EONYX memory: AGENTS.md, sessions and context compaction
Every agent turn starts with the model receiving context. In EONYX it is built from three mechanisms: AGENTS.md — the project’s persistent instructions, sessions — the full conversation history on disk, and auto-summarization — compaction of older turns once the history approaches the limit of the context window.
1 AGENTS.md: project instructions
AGENTS.md is a file with the project’s rules and context. EONYX finds such files automatically while building the system prompt: it walks up the directory tree from the working directory and collects AGENTS.md at every level.
1.1 Traversal rules
- The walk stops at the project root (the directory with
eonyx.json), at a directory with.git, or at the filesystem root. - Files are attached from the outermost to the closest: the one nearest to the working directory comes last, so local instructions refine the general ones.
- Each file goes into the system prompt under the heading
# Project context: <relative path>.
Keep the general rules at the repository root and subdirectory specifics next to the code:
my-project/
├── AGENTS.md ← stack, conventions, prohibitions
└── services/
└── billing/
└── AGENTS.md ← specifics of a particular service1.2 What to write
# Project: My App
## Stack
- Go 1.26, PostgreSQL via pgx.
## Rules
- Run `go test ./...` and `go vet ./...` before committing.
- Do not refactor what you were not asked to.
## Prohibited
- Do not edit .env directly.
- Never run migrations without confirmation.system_prompt field in eonyx.json or the --system-prompt flag of eonyx run (the flag beats the field, the field beats generation — in that case AGENTS.md files are not attached).2 Conversation memory
Everything you discussed with the agent lives in sessions on disk, and once the history approaches the context limit it gets compacted by auto-summarization.
2.1 Sessions on disk
Every conversation is a session, fully persisted to disk. The format is JSONL: one message (including tool calls and their results) per line.
| File | Contents |
|---|---|
sessions/<id>.jsonl | messages of a single session |
sessions.json | index: id, title, message counter, dates |
The storage is shared across all projects and sits next to the global data: on Windows %LOCALAPPDATA%\eonyx\, on Linux/macOS $XDG_DATA_HOME/eonyx/ (~/.local/share/eonyx/ by default). The session id is sortable: 20260705T091500-1a2b3c4d.
Writing is the source of truth: if a message could not be saved, the turn is aborted rather than continuing “past the disk”. Empty sessions (those that never got beyond the system prompt) are cleaned up automatically.
2.2 Working in the TUI
On startup EONYX resumes the most recent session. From there:
| Action | How |
|---|---|
| Session manager | Ctrl+S or /sessions |
| Search across sessions | /sessions <query> — over titles and message text |
| New session | /new |
| Clear the context | /clear — wipes the history, keeping the id and title |
| Rename | r in the session list or /rename <title> |
| Fork | f in the session list or /fork — a conversation branch |
| Delete | d in the session list |
| Export to markdown | /export → .eonyx/exports/eonyx-<id>.md |
New sessions get simple sequential titles — 1, 2, 3… — until you rename them explicitly; the title never changes automatically.
2.3 Working from the console
eonyx sessions # list: id, date, message count, title
eonyx sessions --search parser # search over titles and text
eonyx sessions delete <id> # delete
eonyx run -c "continue" # continue the most recent session
eonyx run -s <id> "and now…" # continue a specific oneFork copies the message file into a new session — the original is left unchanged. Handy before a risky direction: fork the conversation, give it a try, and if it did not work out, go back to the original session.2.4 Auto-summarization
If a model has context_window set in the config, EONYX tracks the size of the history (estimating ~4 characters per token) and shows a {ctx N%} indicator in the header. At 80% the indicator is highlighted — and summarization triggers at that same threshold.
How it works:
- The last 3 user turns are kept verbatim; everything older is sent to the model with a request to compact it into a running summary (decisions, facts, changed files, open tasks).
- The summary is appended to the system prompt under the heading
# Summary of earlier conversation; the next compaction takes the previous summary into account. - The compaction boundary runs only along user messages, so “tool call → result” pairs are never split.
- All of this happens in memory only: the JSONL on disk keeps the full history losslessly — an export or a reopened session sees the whole conversation.
context_window field is the switch for this machinery. If you do not set it, the history grows until the API rejects it. Set the model’s real window size in eonyx.json.3 Summary
- AGENTS.md
- project rules; collected up the tree to the project root or
.git - the closest file comes last
- project rules; collected up the tree to the project root or
- Sessions
- JSONL on disk, shared across all projects
- resuming (
-c/-s), search, fork (f), rename (r), export (/export) - titles are sequential
1,2,3; they change only via an explicit/rename
- Summarization
- at 80% of
context_window: older turns are compacted into a summary in the system prompt - the disk keeps everything; watch
{ctx N%}in the header
- at 80% of