Part of the agents epic #421. The centerpiece of the module.
Rationale
An agent session is an append-only conversation log — exactly what PersistentActor models. Event sourcing gives audit (tokens/cost per call), replayable tests, and mid-turn crash recovery: the intent (tool-call-requested) is persisted before tools execute, so a restarted agent resumes deterministically instead of losing the turn or silently re-running side effects.
Scope
AgentActor extends PersistentActor<AgentCommand, AgentEvent, AgentState>; persisted event union with kind literals (user-message, assistant-message, tool-call-requested, tool-result, turn-completed, turn-failed, context-compacted, approval-requested, approval-resolved, handed-off) + codecs with EventAdapter versioning from day one.
- Turn loop: guardrails check → context strategy → model call (streamed via self-tell pump with delta coalescing, mailbox-safe) → persist assistant message + tool intents → invoke tools via ToolRegistry → loop until finish (
maxIterationsPerTurn bound).
- Recovery policies:
interruptedTurn: 'retry-model' | 'fail-turn'; only idempotent: true tools are re-invoked; others fail or park the turn.
TruncateStrategy as the first ContextStrategy (summarization is a follow-up; compaction results are persisted as events so replay stays stable).
- Snapshots via
everyNEvents + opt-in destructive compaction through the existing Journal.delete (documented trade-off: storage vs. audit/replay).
AgentsExtension (model registry, default ToolRegistry) via the Extension pattern; AgentOptions.ts per the AGENTS.md options family (AgentOptionsType / AgentOptionsBuilder / AgentOptions / AgentOptionsValidator; resolution explicit > HOCON actor-ts.agents.* > defaults). Engine match arms delegate to private onXxx handlers.
const agentOptions = AgentOptions.create()
.withAgentId('support-42')
.withModel('default')
.withSystemPrompt('You are a helpful support agent.')
.withTools(['get_weather'])
.withGuardrails({ maxIterationsPerTurn: 6, tokenBudget: { perSession: 200_000 } });
const support = system.spawn(Props.create(() => new AgentActor(agentOptions)), 'support-42');
support.tell({ kind: 'user-turn', turnId: 'T1', content: 'Weather in Kiel?', streamTo: uiRef });
const result = await support.ask<TurnResult>({ kind: 'user-turn', turnId: 'T2', content: 'Thanks!' });
Documentation
Docs-chapter core pages (quickstart, event model, recovery semantics, config reference — EN + DE); JSDoc; CHANGELOG; feeds the examples/agents/ app (tracked in the epic).
Acceptance
- Full-turn tests incl. streaming + tool loop under ScriptedChatModel/ManualScheduler; kill-mid-turn recovery tests for both policies; guardrail stop conditions; snapshot/recovery round-trip.
Non-goals
Summarize strategy, typed-facade polish, approval gate, orchestration helpers (separate issues).
Relates
Epic #421; depends on the ChatModel and ToolRegistry issues.
Part of the agents epic #421. The centerpiece of the module.
Rationale
An agent session is an append-only conversation log — exactly what
PersistentActormodels. Event sourcing gives audit (tokens/cost per call), replayable tests, and mid-turn crash recovery: the intent (tool-call-requested) is persisted before tools execute, so a restarted agent resumes deterministically instead of losing the turn or silently re-running side effects.Scope
AgentActor extends PersistentActor<AgentCommand, AgentEvent, AgentState>; persisted event union withkindliterals (user-message,assistant-message,tool-call-requested,tool-result,turn-completed,turn-failed,context-compacted,approval-requested,approval-resolved,handed-off) + codecs with EventAdapter versioning from day one.maxIterationsPerTurnbound).interruptedTurn: 'retry-model' | 'fail-turn'; onlyidempotent: truetools are re-invoked; others fail or park the turn.TruncateStrategyas the firstContextStrategy(summarization is a follow-up; compaction results are persisted as events so replay stays stable).everyNEvents+ opt-in destructive compaction through the existingJournal.delete(documented trade-off: storage vs. audit/replay).AgentsExtension(model registry, default ToolRegistry) via the Extension pattern;AgentOptions.tsper the AGENTS.md options family (AgentOptionsType/AgentOptionsBuilder/AgentOptions/AgentOptionsValidator; resolution explicit > HOCONactor-ts.agents.*> defaults). Engine match arms delegate to privateonXxxhandlers.Documentation
Docs-chapter core pages (quickstart, event model, recovery semantics, config reference — EN + DE); JSDoc; CHANGELOG; feeds the
examples/agents/app (tracked in the epic).Acceptance
Non-goals
Summarize strategy, typed-facade polish, approval gate, orchestration helpers (separate issues).
Relates
Epic #421; depends on the ChatModel and ToolRegistry issues.