Skip to main content

State And Memory

ProtoAgent has two separate memory layers:

  1. Rust UI session summaries in sessions.json.
  2. 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

Only the stateful Architect uses durable model-facing conversation storage:

RoleState modelNamespace
Architectdurable conversation memoryprotoagent-architect
Explorertask-local stateless workernone
Codertask-local stateless workernone
Scoutoptional tool-only worker; no LLM statenone

ProtoLink may allocate in-memory state for Explorer/Coder execution, but that state is discarded with the task and is not part of conversations.sqlite. Scout is created with no LLM, no storage, and empty state.

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 durable agent storage and the active LLMModelProfile.context_window. In the current architecture this applies to Architect memory only; stateless workers are skipped.

Default ratio:

PROTOAGENT_HISTORY_BUDGET_RATIO=0.7

The code clamps the ratio between 0.2 and 0.9.

Explicit Commands

CLI commandPython functionProtoLink operation
/context historydescribe_saved_histories()describe_state() for Architect memory
/context compactcompact_saved_histories()compact_state() for Architect memory
/context resetreset_saved_histories()reset_state() for Architect memory

State control facades are regular ProtoLink Agent instances with no LLM. Their policy allows history/state operations and denies everything else.

Compaction Strategies

StrategyOptions
recentmax_messages
tokensmax_tokens, preserve_recent=6
summarypreserve_recent

When no token limit is passed, tokens uses the Architect 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:

  1. The raw user prompt.
  2. A runtime prompt that ends with Current user request: <prompt>.

Rust Session Ledger Is Different

cli/src/sessions.rs records UI summaries:

FieldPurpose
idStable project-derived id.
nameDisplay name.
workspaceProject path.
turnsUI turn count.
historyRecent UI turn previews.
timelineStructured timeline derived from run events.

Limits:

LimitValue
Max saved sessions40
Max turns per session60
Answer preview chars420

This ledger is useful for the UI but should not be described as the model's conversation memory.