d5b122d4a3
CI / lint (push) Successful in 14s
CI / quality (push) Successful in 21s
CI / security (push) Successful in 36s
CI / build (push) Successful in 36s
CI / typecheck (push) Successful in 39s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 2m57s
CI / integration_tests (push) Successful in 3m23s
CI / docker (push) Successful in 53s
CI / coverage (push) Successful in 5m58s
CI / benchmark-publish (push) Successful in 19m27s
143 lines
7.1 KiB
Markdown
143 lines
7.1 KiB
Markdown
---
|
|
adr_number: 20
|
|
title: Session Model
|
|
status_history:
|
|
- - '2026-02-16'
|
|
- Proposed
|
|
- Jeffrey Phillips Freeman
|
|
- - '2026-02-16'
|
|
- Accepted
|
|
- Jeffrey Phillips Freeman
|
|
tier: 3
|
|
authors:
|
|
- Jeffrey Phillips Freeman
|
|
superseded_by: null
|
|
related_adrs:
|
|
- number: 6
|
|
title: Plan Lifecycle
|
|
relationship: Plans execute within sessions and inherit session-scoped context
|
|
- number: 10
|
|
title: Actor and Agent Architecture
|
|
relationship: Sessions bind a user to an orchestrator actor for conversation
|
|
- number: 14
|
|
title: Context Management (ACMS)
|
|
relationship: Sessions maintain session-scoped context tiers and conversation history
|
|
- number: 26
|
|
title: Agent-to-Agent Protocol (A2A)
|
|
relationship: A2A exposes session lifecycle operations to all clients
|
|
acceptance:
|
|
votes_for:
|
|
- voter: Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com>
|
|
comment: Sessions as persistent conversation threads with cost budgets and context scoping tie the user experience together
|
|
votes_against: []
|
|
abstentions: []
|
|
---
|
|
## 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.
|