Raxol.Agent.SelfImprove (Raxol Agent v2.6.0)

Copy Markdown View Source

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:

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

writers()

@type writers() :: %{
  optional(:memory) => {module(), keyword()} | nil,
  optional(:skills) => {module(), keyword()} | nil
}

Functions

after_turn(items, writers, config)

@spec after_turn([map()], writers(), map() | nil) :: :spawned | :skipped

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).

qualifies?(items, config)

@spec qualifies?([map()], map()) :: boolean()

Whether a turn qualifies for review: it succeeded (no error item) and did at least min_tool_calls tool calls (default 5).

review(items, writers, config)

@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.