Contents

EONYX memory: AGENTS.md, sessions and context compaction

Every turn starts with the model receiving context.
EONYX builds it from three parts.
AGENTS.md carries the project’s standing instructions.
Sessions hold the full history on disk.
Auto-summarization compacts the older turns as the window fills.

AGENTS.md holds the project’s rules and context.
EONYX finds these files while building the system prompt.
It walks up the directory tree from the working directory and collects one at every level.

  • The walk stops at the project root, the directory holding eonyx.json. Or at a directory with .git. Or at the filesystem root.
  • Files attach from the outermost inwards. The nearest one comes last, so local rules refine the general ones.
  • Each file enters the system prompt under # Project context: <relative path>.

Keep general rules at the repository root.
Keep specifics next to the code they describe.

my-project/
├── AGENTS.md            ← stack, conventions, prohibitions
└── services/
    └── billing/
        └── AGENTS.md    ← specifics of a particular service
# 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.
Replacing the prompt entirely
The generated system prompt can be replaced wholesale.
Use the system_prompt field in eonyx.json, or the --system-prompt flag of eonyx run.
The flag beats the field, and the field beats generation.
In that case AGENTS.md files are not attached at all.

Every conversation is a session, fully persisted.
The format is JSONL: one message per line, tool calls and results included.

FileContents
sessions/<id>.jsonlmessages of a single session
sessions.jsonindex: id, title, message counter, dates

The store is shared across projects and sits with the global data.
On Windows that is %LOCALAPPDATA%\eonyx\.
On Linux and macOS it is $XDG_DATA_HOME/eonyx/, which defaults to ~/.local/share/eonyx/.
Session ids sort naturally: 20260705T091500-1a2b3c4d.

Writing is the source of truth.
If a message cannot be saved, the turn aborts rather than running past the disk.
Empty sessions, the ones that never got past the system prompt, are cleaned up on their own.

EONYX resumes the most recent session on startup.
From there:

ActionHow
Session managerCtrl+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
Renamer in the session list or /rename <title>
Forkf in the session list or /fork — a conversation branch
Deleted in the session list
Export to markdown/export.eonyx/exports/eonyx-<id>.md

New sessions get plain sequential titles: 1, 2, 3.
They never change on their own — only an explicit rename touches them.

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 one
A fork as a save point
Fork copies the message file into a new session.
The original stays untouched.
Fork before a risky direction, try it, and fall back if it did not work out.

Set context_window on a model and EONYX starts tracking the history size.
It estimates about 4 characters per token and shows {ctx N%} in the header.
At 80% the indicator lights up, and summarization fires at the same threshold.

How it works:

  • The last 3 user turns stay verbatim. Everything older goes to the model to be compacted into a running summary: decisions, facts, changed files, open tasks.
  • The summary is appended to the system prompt under # Summary of earlier conversation. The next compaction folds in the previous summary.
  • The boundary runs only along user messages, so a tool call is never split from its result.
  • All of this is in memory only. The JSONL on disk keeps the full history, so an export or a reopened session shows the whole conversation.
Without context_window there is no summarization
The context_window field is the switch for this machinery.
Leave it out and the history grows until the API rejects it.
Put the model’s real window size in eonyx.json.
Cheat sheet
  • AGENTS.md
    • project rules; collected up the tree to the project root or .git
    • the closest file comes last
  • 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