7.1 KiB
adr_number, title, status_history, tier, authors, superseded_by, related_adrs, acceptance
| adr_number | title | status_history | tier | authors | superseded_by | related_adrs | acceptance | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 20 | Session Model |
|
3 |
|
null |
|
|
Context
Users interact with CleverAgents through conversations — asking questions, giving instructions, reviewing plan outputs, and providing corrections. These conversations need persistent state: the current orchestrator actor, the conversation history, the active plan context, and accumulated knowledge. The system needs a session abstraction that binds a conversation to an orchestrator actor and provides session-scoped context, budgets, and lifecycle management.
Decision Drivers
- Conversations must persist across CLI restarts so users can resume multi-turn interactions
- Each session needs a bound orchestrator actor that provides a consistent conversational personality
- Session-scoped cost budgets must aggregate across all plans within a session to prevent cost overruns
- Accumulated knowledge and conversation history must be available across plan boundaries within a session
- Session lifecycle (create, resume, archive) must be explicitly manageable by users
Decision
A session is a persistent conversation thread that binds a user to an orchestrator actor and provides session-scoped context, cost budgets, and conversation history. Sessions are the top-level interactive abstraction — plans are executed within the context of a session.
Design
Session Identity
Each session has:
session_id: ULID, unique identifier.name: Optional human-readable label for the session.created_at/updated_at: Timestamps.created_by: User identity.
Orchestrator Binding
Every session is bound to an orchestrator actor — the actor that drives the conversation. The orchestrator:
- Receives user messages and routes them to appropriate actions.
- Can invoke
plan use,plan execute,plan apply, and other commands on behalf of the user. - Maintains conversational context across turns.
- May delegate to specialized actors via actor composition.
The default orchestrator is configured via actor.default.orchestrator. Sessions created without an explicit --actor flag use this default.
Session Lifecycle
Sessions are created via agents session new (or implicitly when the user starts a conversation). Sessions persist across CLI invocations — the user can resume a session by ID or name. Sessions can be listed, shown, and archived.
Session-Scoped Context
Sessions maintain their own context:
- Conversation history: The sequence of user messages and actor responses.
- Active plans: Plans currently being worked on within this session.
- Session knowledge: Accumulated facts and preferences learned during the conversation.
- Session budget: Maximum estimated API cost per session (
plan.budget.per-session). When cumulative session cost exceeds this budget, all plan operations pause.
Session and Plan Relationship
Plans are executed within sessions. A session may have multiple active plans (sequential or concurrent). The session provides:
- The orchestrator actor for interactive plan management.
- Session-level budget tracking across all plans.
- Conversation context that persists across plan boundaries.
Session Commands
| Command | Description |
|---|---|
agents session new [--actor <NAME>] |
Create a new session |
agents session list |
List sessions |
agents session show <ID> |
Show session details |
agents session resume <ID> |
Resume a session |
agents session archive <ID> |
Archive a session |
Constraints
- Every interactive conversation must have a session. There is no "sessionless" interaction mode.
- Sessions are bound to exactly one orchestrator actor at creation time. The binding cannot be changed after creation.
- Session budget (
plan.budget.per-session) is an aggregate across all plans within the session. - Session conversation history must be persisted to the database, not held only in memory.
- Session IDs are ULIDs, consistent with all other entity identifiers.
Consequences
Positive
- Persistent sessions enable long-running conversations that survive CLI restarts.
- Session-scoped budgets prevent cost overruns across multiple plans.
- Orchestrator binding provides a consistent conversational personality and capability set.
- Conversation history enables context-aware interactions across plan boundaries.
Negative
- Session management adds another entity type to the system with its own lifecycle and storage requirements.
- The orchestrator binding is immutable after creation, which may be limiting if the user wants to switch interaction styles mid-session.
- Session-scoped context accumulates over time and may need periodic cleanup or summarization to remain useful.
Risks
- Long-running sessions could accumulate excessive conversation history, consuming storage and degrading context retrieval quality.
- Session budget tracking requires accurate cost estimation, which depends on LLM provider pricing accuracy.
- Orphaned sessions (created but never used or resumed) could accumulate in the database without cleanup.
Alternatives Considered
Stateless interactions (no session persistence) — Every CLI invocation would start fresh with no conversation context. This prevents multi-turn interactions, accumulated knowledge, and session-scoped budgets.
Implicit sessions (auto-created, auto-destroyed) — Simpler but prevents intentional session management (naming, archiving, resuming). The explicit session model gives users control over their conversation state.
Compliance
- Session lifecycle tests: Tests verify creation, resumption, archival, and listing of sessions.
- Budget enforcement tests: Tests verify that session-scoped budgets correctly aggregate across plans and pause operations when exceeded.
- Persistence tests: Tests verify that conversation history survives CLI restarts and is correctly loaded on session resumption.
- Orchestrator binding tests: Tests verify that the orchestrator actor is correctly bound at creation and that all session interactions route through it.
- Cleanup tests: Tests verify that session archival correctly marks sessions as inactive without data loss.