Build profiles
| Profile | Cargo Features | Use Case |
|---|---|---|
| Minimal | --no-default-features | Ephemeral agent, no persistence, no compaction |
| Persistent | session-store | Sessions survive restart with the realm-pinned backend (sqlite by default when compiled) |
| Compacting | session-compaction | Auto-compact long conversations |
| Full | session-store,session-compaction | Persistent + compacting |
Capability behavior
| Operation | Minimal | Persistent | Compacting | Full |
|---|---|---|---|---|
create_session | Works | Works | Works | Works |
start_turn | Works | Works + snapshot saved | Works | Works + snapshot saved |
interrupt | Works | Works | Works | Works |
read (live session) | Works | Works | Works | Works |
read (archived) | SESSION_NOT_FOUND | Falls back to store | SESSION_NOT_FOUND | Falls back to store |
list | Live sessions only | Live + stored sessions | Live sessions only | Live + stored sessions |
archive | Removes from memory | Removes from memory, snapshot kept | Removes from memory | Removes + snapshot kept |
| Auto-compaction | No-op | No-op | Triggers at threshold | Triggers at threshold |
Error codes
Deterministic error codes across all surfaces. The canonical mapping is defined inmeerkat-contracts (ErrorCode). Every SessionError variant maps to a stable
string code and a transport-specific representation:
SessionError | Code | JSON-RPC | REST | MCP | CLI |
|---|---|---|---|---|---|
NotFound | SESSION_NOT_FOUND | -32001 | 404 | tool error | exit 10 |
Busy | SESSION_BUSY | -32002 | 409 | tool error | exit 11 |
NotRunning | SESSION_NOT_RUNNING | -32003 | 409 | tool error | exit 12 |
PersistenceDisabled | CAPABILITY_UNAVAILABLE | -32020 | 501 | tool error | exit 40 |
CompactionDisabled | CAPABILITY_UNAVAILABLE | -32020 | 501 | tool error | exit 40 |
Store | INTERNAL_ERROR | -32603 | 500 | tool error | exit 1 |
Agent | AGENT_ERROR | -32013 | 500 | tool error | exit 30 |
Transport error mapping summary
- JSON-RPC: Custom error codes in the -32000..-32099 range. The
codefield of the JSON-RPC error object carries the string code (e.g.SESSION_NOT_FOUND). - REST: HTTP status codes (404, 409, 500, 501). Error body includes
{ "code": "...", "message": "..." }. - MCP Server: Tool calls return
is_error: truewith the error message and code in the content. - CLI: Non-zero exit codes. Each
ErrorCodemaps to a stable exit code (see CLI exit codes). Error details printed to stderr.
Pick only what you need
Model capabilities
ModelProfile describes per-model capabilities used for feature gating and tool visibility. Two fields are relevant to multimodal content support:
| Capability | Description | Anthropic | OpenAI | Gemini |
|---|---|---|---|---|
vision | Model can process image content in user messages | Yes | Yes | Yes |
image_tool_results | Model can process image content in tool results | Yes | No | Yes |
meerkat-models) and exposed via ModelProfile. They control:
view_imagetool visibility — hidden viaToolScopewhen eithervisionorimage_tool_resultsisfalse.ContentBlock::Imagein tool results — providers that do not supportimage_tool_resultswill receive image content blocks converted to text descriptions.ContentBlock::Imagein user messages — providers that do not supportvisionwill not receive image content blocks in user messages.
MCP server loading
MCP server connections are non-blocking across all surfaces. Servers connect in parallel in the background afterapply_staged(). The agent loop polls poll_external_updates() at each CallingLlm boundary and injects a [MCP_PENDING] system notice while servers are still connecting. Tools become visible as each server completes its handshake.
- Per-server timeout:
connect_timeout_secsin MCP config (default: 10s) - CLI:
--wait-for-mcpblocks before the first turn until all servers finish connecting - SDK:
McpRouterAdapter::wait_until_ready(timeout)provides the same blocking behavior programmatically
Compaction behavior
Whensession-compaction is enabled:
- Trigger:
last_input_tokens >= thresholdORestimated_history_tokens >= threshold - Guards: Never on first turn. Minimum 3 turns between compactions.
- Failure: Non-fatal.
CompactionFailedevent emitted, agent continues with uncompacted history. - Budget: Compaction LLM call draws from the same token budget as regular turns.
CompactionStarted, CompactionCompleted, CompactionFailed.
Concurrency
- At most one turn runs per session at a time.
- Second
start_turnwhile one is in-flight returnsSESSION_BUSY. interrupt()cancels the in-flight turn.read()andlist()are non-blocking.- No queueing: callers retry on
Busy.
Durability
- Ephemeral: Process death loses all state.
- Persistent: Snapshot saved after turn completion according to the pinned realm backend.
- Backends are pinned per realm (
realm_manifest.json) and shared across surfaces only whenrealm_idmatches. - SQLite-backed realms are the standard same-realm multi-process mode.
See also
- Session contracts — concurrency, durability, and compaction semantics
- Architecture — crate structure and agent loop details
