Why it works
Rousseau reads its provider and model from config.yaml once at process start (config.Load in internal/config/config.go). The session state lives in SQLite. Changing the model means editing the config, restarting the daemon, and letting the next inbound message be handled by the new model — while every session the previous model participated in remains intact in sessions.db.
Nothing about the session store is tied to a specific model. The payload column (internal/state/sqlite/schema.sql) is a plain JSON blob of agent.Session; role, content, tool-use blocks. Any model that speaks the Anthropic content-block convention (or is adapted through the SDK adapters in internal/llm/*/client.go) can pick up where the previous one left off.
Swap within the same provider
The easy case. Edit the model field:
# was:
anthropic:
model: claude-sonnet-4-6
# now:
anthropic:
model: claude-opus-4-6
Restart:
systemctl --user restart rousseau-agent
# or, if you're running rousseau chat interactively, quit and relaunch
Send the next message. The reply comes from Opus; the session context is unchanged.
Swap across providers
Slightly more involved because content-block shapes vary. Rousseau's adapters (internal/llm/anthropic/client.go, internal/llm/openai/client.go) round-trip agent.Message values through the SDK's native types on each turn. That means:
claudecli→anthropic— clean swap. Both use the same content-block shape.claudecli→bedrock/vertex— clean swap. Anthropic-on-Bedrock and Anthropic-on-Vertex speak the same messages format.- Anthropic-family →
openai/openrouter/ollama— Tool-use blocks are re-shaped to OpenAI's function-call format. Prior tool_use / tool_result pairs in the session round-trip through the adapter. Should be seamless for text; edge cases (multi-tool-use in a single turn, streaming partials) may render differently.
If the session has heavy tool-use history and you're crossing provider families, test with a fresh session first.
Swap the deployment provider without touching state
Same session store, different daemon config:
cp ~/.config/rousseau/config.yaml ~/.config/rousseau/config.yaml.bak
$EDITOR ~/.config/rousseau/config.yaml # change provider + model
systemctl --user restart rousseau-agent
state.path did not change, so the JID→session mapping (jid_sessions table in internal/state/sqlite/jidmap.go) still points at the same conversation history for every WhatsApp / Slack / Matrix sender.
What is preserved
| State | Survives restart | Notes |
|---|---|---|
| Session transcripts | Yes | sessions table. |
| FTS5 recall index | Yes | sessions_fts virtual table. Re-tokenised on backfill. |
| JID → session mapping | Yes | jid_sessions table. |
| Cron jobs | Yes | cron_jobs table. |
| WhatsApp device pairing | Yes | whatsapp.db (separate file). |
| Anthropic prompt cache hit | No | The cache is per-endpoint. A new model or endpoint starts cold. |
What is lost
The Anthropic prompt-cache markers (applyCacheMarkers in internal/llm/anthropic/client.go) live inside the model's ephemeral cache — they don't persist across restarts of the model or provider. The next few turns after a swap pay full input tokens; subsequent turns rebuild the cache. This is worth knowing for cost budgeting but not for correctness.
When to swap vs. start fresh
Swap in place when:
- The session is worth preserving and the content is text-heavy.
- The models are in the same family (both Anthropic, or via Bedrock/Vertex).
- You accept a one-time cache miss.
Start fresh when:
- The session has stale context you don't want a smarter model chasing.
- You're crossing provider families and want deterministic behaviour.
- The token count is at the compression trigger anyway — compress and swap in one go.
Testing after a swap
rousseau session list | head -3
rousseau session show <id> | tail -20
# in TUI or via a transport:
> what did we just decide about X?
If the reply references the prior conversation coherently, the swap is working. If the model apologises for "not having context" or repeats itself, the adapter round-trip may be losing tool-use metadata — file a bug or fall back to the previous model.
Related
- Providers — every supported provider.
- Configuration — the exact field names.
- Guides: Rate limits — cache-marker discussion.
- Guides: Session management — full lifecycle.