State And Memory
ProtoAgent has two separate memory layers:
- Rust UI session summaries in
sessions.json. - ProtoLink model-facing conversation state in
conversations.sqlite.
The second one is the real agent memory.
Storage
Conversation state uses ProtoLink SQLiteStorage:
~/.protoagent/conversations.sqlite
Each agent has its own namespace:
| Agent | Namespace |
|---|---|
| Architect | protoagent-architect |
| Explorer | protoagent-explorer |
| Coder | protoagent-coder |
The session id is usually derived from the active project path:
protoagent-project-<hash>
If /context off is active, the Rust CLI passes no stable session id and runs
use task-local state.
Run-Boundary Compaction
Before a session resumes, compact_agent_histories_for_run() checks each
running agent's LLMModelProfile.context_window. It compacts history when the
budget is exceeded.
Default ratio:
PROTOAGENT_HISTORY_BUDGET_RATIO=0.7
The code clamps the ratio between 0.2 and 0.9.
Explicit Commands
| CLI command | Python function | ProtoLink operation |
|---|---|---|
/context history | describe_saved_histories() | describe_state() |
/context compact | compact_saved_histories() | compact_state() |
/context reset | reset_saved_histories() | reset_state() |
State control facades are regular ProtoLink Agent instances with no LLM. Their
policy allows history/state operations and denies everything else.
Compaction Strategies
| Strategy | Options |
|---|---|
recent | max_messages |
tokens | max_tokens, preserve_recent=6 |
summary | preserve_recent |
When no token limit is passed, tokens uses the agent model profile and the
history budget ratio. If no context window exists, it falls back to 4000 tokens.
Top-Level Turn Persistence
persist_architect_turn() makes sure the top-level Architect user/assistant
turn exists in ProtoLink conversation state. This guards against gaps when the
streaming runtime does not persist the final current turn.
It avoids duplicates by checking whether the latest saved messages already match either:
- The raw user prompt.
- A runtime prompt that ends with
Current user request: <prompt>.
Rust Session Ledger Is Different
cli/src/sessions.rs records UI summaries:
| Field | Purpose |
|---|---|
id | Stable project-derived id. |
name | Display name. |
workspace | Project path. |
turns | UI turn count. |
history | Recent UI turn previews. |
timeline | Structured timeline derived from run events. |
Limits:
| Limit | Value |
|---|---|
| Max saved sessions | 40 |
| Max turns per session | 60 |
| Answer preview chars | 420 |
This ledger is useful for the UI but should not be described as the model's conversation memory.