After-turn background curation: review a completed agent turn and persist durable knowledge without touching the live conversation.
When a react/2 turn finishes and the runtime has drained it into the
Conversation.Log (via Raxol.Agent.Conversation.Recorder.record_stream/4),
the runtime calls after_turn/3 with the turn's items, the configured write
targets, and the agent's self_improve/0 config. If the turn qualifies (it
succeeded and did at least min_tool_calls tool calls), an unlinked Task
reviews it on an auxiliary model and writes what is worth keeping:
- facts ->
Raxol.Agent.Memory(semantic memory) - reusable procedures ->
Raxol.Agent.Skills.Store, taggedcreated_by: :agentso the Curator may later age or consolidate them.
The reviewer runs in its own process with its own model call. It can only
append to memory and the skill store; it never calls update/2, never mutates
the live conversation, and a crash in it is logged, not propagated.
Config (the self_improve/0 map)
%{
enabled: true,
backend: Raxol.Agent.Backend.HTTP, # an AIBackend; defaults to Mock
model: "claude-haiku-4-5", # auxiliary (cheap) model
backend_opts: [], # extra opts passed to complete/2
min_tool_calls: 5 # complexity gate (default 5)
}Writers
writers mirrors the agent's tool context:
%{memory: {mod, opts} | nil, skills: {mod, opts} | nil} (the same tuples
Raxol.Agent.Memory.provider_context/3 and
Raxol.Agent.Skills.provider_context/2 build). Either may be absent; the
reviewer simply skips that write target.
Summary
Functions
Entry point the runtime calls after recording a turn.
Whether a turn qualifies for review: it succeeded (no error item) and did at
least min_tool_calls tool calls (default 5).
Run the review synchronously: format the turn, ask the auxiliary model what to
keep, and apply the writes. Returns {:ok, %{memories: n, skills: n}} with the
counts written, or {:error, reason}. Public so it can be driven directly in
tests; production goes through after_turn/3.
Types
Functions
Entry point the runtime calls after recording a turn.
Returns :spawned when a background review was started, :skipped
otherwise (disabled, or the turn did not qualify).
Whether a turn qualifies for review: it succeeded (no error item) and did at
least min_tool_calls tool calls (default 5).
@spec review([map()], writers(), map()) :: {:ok, %{memories: non_neg_integer(), skills: non_neg_integer()}} | {:error, term()}
Run the review synchronously: format the turn, ask the auxiliary model what to
keep, and apply the writes. Returns {:ok, %{memories: n, skills: n}} with the
counts written, or {:error, reason}. Public so it can be driven directly in
tests; production goes through after_turn/3.