Skip to main content

Agent State

One AgentState dict is the app-owned turn snapshot. Runtime stages read from it and return partial deltas. Explicit runtime merge helpers preserve the long-lived dict channels that need cross-turn continuity, while ordinary fields are last-write-wins.

Mental model

LifecycleWhat it meansExamples
inputSet once by the caller at turn startmessage, user_id, channel
persisted/mergedSaved in the app-owned state snapshot and shallow-merged when a stage returns a partial nested updatetranscript, session_progress, exercise_state, diagnostics
loadedRe-fetched each turn from the memory storeworking_memory, procedural_profile.*
turn-scopedFresh each turn, last-write-winscrisis, route, response_text

That's the whole story. The interactive table below splits the schema into nine groups and tags every field with one of these four labels — click a section to expand it.

Field reference

inputSet once by the caller at turn start.persisted/mergedSaved in app-owned state snapshots; dict channels are shallow-merged by runtime helpers.turn-scopedFresh each turn. Last-write-wins.loadedRe-fetched each turn from the memory store.
messagestr

Current user message being processed.

inputset by caller
channelChannel

Transport surface: TEST, WEB, VOICE.

inputset by caller
user_idstr | None

Persistent owner. resolve_owner_id() namespaces memory by this; mandatory if session_id is absent.

inputset by caller
session_idstr | None

Thread identifier used by persistence and as a fallback memory owner.

inputset by caller
installed_skillslist[str]

Caller-provided capability keys used for capability-aware routing and catalog filtering.

inputset by caller
transcriptlist[dict]

Full app-owned conversation record for API/CLI/audit fallback. The current user turn is appended before the SDK run; the assistant turn is appended during finalization.

persisted/mergedappend in runtime stateset by build_initial_state + finalize_openai_turn
working_memorylist[WorkingMemoryEntry]

SemanticWorkingMemoryEntry (category/subject/predicate/object + evidence_quote) and EpisodicWorkingMemoryEntry (summary, themes, is_catch_up, approach_used). Formatted on demand at prompt-build time.

loadedset by turn memory context
session_memorySessionMemoryState

Prompt-visible session continuity: summary, active_concerns, open_loops, current_goal.

persisted/mergedshallow dict mergeset by turn memory context
procedural_profile.procedural_ruleslist[str]

Style directives that shape every reply. Always applied — the recall toggle is content-recall only.

loadedset by turn memory context
procedural_profile.proactive_recall_enabledbool

Whether the agent may proactively reference recalled content. Procedural rules apply regardless.

loadedset by turn memory context
session_progressSessionProgressState

Turn-count continuity. Runtime merge helpers preserve sibling flags while updating counters.

persisted/mergedshallow dict mergeset by build_initial_state
session_progress.turn_countint

Persistent callers derive from the prior runtime state snapshot; one-shot callers count from input history.

persisted/mergedset by build_initial_state
exercise_stateExerciseState

Active guided-exercise continuity. Cleared by runtime logic when the user exits or the exercise completes.

persisted/mergedshallow dict mergeset by guided exercise flow + triage
exercise_state.exercise_typestr | None

Active exercise identifier (e.g., "grounding_5_4_3_2_1").

persisted/mergedset by guided exercise flow
exercise_state.exercise_stepint | None

Current step index. Cleared when the exercise completes or the user exits.

persisted/mergedset by guided exercise flow
exercise_state.exercise_therapeutic_approachstr | None

Approach pinned at exercise start. Reused when guidance resumes and for narrow clarifying side-turns; psychoeducation side-turns keep the exercise active but may use a fresh top-level approach.

persisted/mergedset by guided exercise flow + triage
memory_control.pending_actiondict | None

Carries a destructive memory action across turns so the next reply can confirm or cancel without LLM inference.

persisted/mergedshallow dict mergeset by memory-control service
crisisCrisisAssessment

level (0–3), confidence, reason, needs_crisis_response, needs_clarification.

turn-scopedset by crisis gate
crisis_auditCrisisAuditState

Classifier provenance: override_kind, classifier_path (llm_primary), llm_failure_occurred. Read by crisis logging.

turn-scopedset by crisis gate
routestr

"crisis" / "therapeutic" / "memory_control" / "grounded_lookup". Drives extractor skip logic.

turn-scopedset by crisis_gate + turn_dispatch
response_textstr

Generated reply for the turn.

turn-scopedset by reply node (response style / crisis_response / memory_control / grounded_answer)
response_stylestr

supportive · reflective · clarifying · psychoeducation · technique · guided_exercise · closing · safety_check · crisis_response · memory_control · grounded_lookup

turn-scopedset by reply node + gates
therapeutic_approachstr | None

motivational_interviewing · cbt · act · dbt_skills · grief_support · interpersonal_therapy · pfa · none

turn-scopedset by TherapeuticAgent
should_persist_memorybool

Set on exercise completion as a hint that the turn is worth summarizing.

turn-scopedset by guided exercise flow
memory_control.actiondict

Detected memory command (kind, args). Consumed by the memory-control service.

turn-scopedset by turn triage
grounded_lookup.querystr

Factual query extracted by triage. Consumed by the grounded lookup tool.

turn-scopedset by turn triage
grounded_lookup.statusstr

answered · no_verified_answer · not_attempted

turn-scopedset by grounded lookup tool
inferred_locationstr

Region extracted from recent context for hotline lookup.

turn-scopedset by crisis resource lookup
found_resourceslist[dict]

Verified hotlines (name / phone / website / region). Empty on failure or missing location.

turn-scopedset by crisis resource lookup
resource_lookup_statusstr

found · no_location · location_refused · no_verified_results · not_attempted

turn-scopedset by crisis resource lookup
diagnosticsdict[str, Any]

Timing, routing, and retrieval metadata.

persisted/mergedshallow dict mergeset by runtime stages + services
diagnostics.crisis_gate_ms · crisis_classifier_pathfloat · str

Time spent classifying + which path decided it.

persisted/mergedset by crisis gate
diagnostics.load_memory_ms · retrieval_pathfloat · str

Retrieval time + which path ran (hybrid_rrf / token_recall / token_recall_after_embed_error).

persisted/mergedset by turn memory context
diagnostics.turn_total_msfloat

Total turn wall-clock, stamped outside the route flow.

persisted/mergedset by runtime

Working memory

working_memory is a list of structured dicts, not pre-formatted strings. Two entry types:

TypeKey fieldsRenders as
SemanticWorkingMemoryEntryevidence_quote, category, subject, predicate, object[relationship] User WORRIES_ABOUT work — "my boss is terrible"
EpisodicWorkingMemoryEntrysummary, primary_themes, is_catch_up, approach_used, approach_contextLast session (grief): talked about loss after my dog died.

Formatting via format_working_memory_entries() happens at three surfaces only: the therapeutic prompt builder, the dispatcher prompt, and the CLI's context panel. Legacy str entries from older state snapshots pass through unchanged.

Public contract

The external API only sees AgentInput and AgentOutput — the state itself is internal to the runtime.

ModelPublic fields
AgentInputmessage, channel, user_id, session_id, history, working_memory, installed_skills
AgentOutputresponse_text, response_type, crisis, response_style, response_style_type, response_style_source, therapeutic_approach, should_persist_memory, diagnostics
CrisisAssessmentlevel (0–3), confidence, reason, needs_crisis_response, needs_clarification
Messagerole, content, response_style (optional — stamped onto assistant turns by turn finalization)

installed_skills is retained as the external field name for compatibility. The runtime treats these strings as capability keys for capability-aware routing and guided-exercise catalog filtering.

Runtime context

Runtime dependencies live on WorkflowContext, not on the state. It's a frozen dataclass injected via runtime.context — attribute access only.

FieldTypeDefault
llm_clientBaseLLMClient | Nonerequired
memory_storeMemoryStorerequired
crisis_log_backendCrisisLogBackendrequired
memory_modeMemoryModerequired
response_llmBaseLLMClient | NoneNone
embedding_providerEmbeddingProvider | NoneNone
session_memory_bufferSessionMemoryBuffer | NoneNone

session_memory_buffer is set by PersistentAgentRuntime so that session-end candidates can be carried in a per-thread buffer that persists across restarts.

Schema implementation detail

The schema is built from TypedDict fragments — AgentIdentityState, AgentConversationState, AgentPersistentState, AgentCrisisState, AgentTurnOutputState, and AgentPrivateState. The runtime declares two main views over them:

SchemaUsed as
AgentTurnInputStateInput — what build_initial_state() emits
AgentStateInternal — the full state used by runtime stages, prompt builders, tests, and evals

state_to_output() reads the relevant output fields from AgentState and normalizes them into the public AgentOutput contract.

You don't need to think about the fragments to use the agent — they exist so the runtime can keep input, internal state, and public output boundaries explicit.

Key files

FileDefines
agent/state.pyAll TypedDict fragments plus AgentTurnInputState and AgentState schemas
agent/memory/entries.pyWorkingMemoryEntry types and format_working_memory_entry/entries()
agent/models.pyAgentInput, AgentOutput, Message, CrisisAssessment, Channel, MessageRole, ResponseCategory, ResponseStyleType, stream events, STAGE_LABELS
agent/audit/models.pyCrisisOverrideOutcome and CrisisClassifierPath (used inside CrisisAuditState), plus CrisisLogRecord and feedback types
agent/runtime/turn.pybuild_initial_state() (input → state) and state_to_output() (state → output)
agent/runtime/workflow_context.pyWorkflowContext frozen dataclass — runtime dependencies via runtime.context