Separate display history from LLM context; formalize worker system
Architecture change:
- session.messages: full display history, never modified by compression
- session.context: what the LLM sees, may be compressed by workers
- System messages go only into context (not display history)
- Image injections (synthetic) go only into context
- User/assistant/tool messages go into both

SQLite: add context column with backward-compat migration
(empty context → initialized from messages on load)

Workers (navi/workers/):
- Worker ABC + WorkerContext + WorkerResult (base.py)
- CompressionWorker: compresses session.context when above threshold
- build_default_workers() returns [CompressionWorker()]
- Agent accepts workers list, runs them after StreamEnd
- Workers injected via deps.py get_workers() (lru_cached singleton)
- WebSocket agent construction also receives workers

Compressor: compress_context() now takes context[], not messages[]
Config: context_keep_recent 6 → 10
Agent: _run_workers() collects events from all workers and yields them

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 802c186 commit 261459a6856b1dbe99fbc16a464d94f00fdb11ed
@Eugene Sukhodolskiy Eugene Sukhodolskiy authored on 8 Apr
Showing 10 changed files
View
navi/api/deps.py
View
navi/api/websocket.py
View
navi/config.py
View
navi/core/agent.py
View
navi/core/compressor.py
View
navi/core/session.py
View
navi/core/sqlite_session_store.py
View
navi/workers/__init__.py 0 → 100644
View
navi/workers/base.py 0 → 100644
View
navi/workers/compressor.py 0 → 100644