Sagents.Factory behaviour (Sagents v0.8.0-rc.8)
Copy MarkdownBehaviour for modules that build %Sagents.Agent{} instances from
validated configuration.
Contract
A factory implements one callback:
@callback create_agent(agent_id :: String.t(), config :: term()) ::
{:ok, Sagents.Agent.t(), session_opts :: keyword()}
| {:error, term()}agent_idis generated bySagents.Sessionfrom the conversation ID via the configuredagent_id_fun. It is system-supplied, opaque to the factory's domain logic.configis whatever the configuredSagents.FactoryRouterreturned as the third element of{:ok, factory_module, config}. The library treats it as opaque and forwards it verbatim. By convention,configis a typed struct (commonly anEcto.Schema embedded_schema) defined by a paired*Configmodule — see the host's generatedFactoryConfigfor the canonical shape.
Returns
{:ok, agent, session_opts}— successful build.session_optsis a keyword list with library-recognized keys::fresh_state_attrs— map seeded intoSagents.State.new!/1only on fresh state (ignored on resume).:supervisor_opts— keyword list merged into the supervisor child config (e.g.:message_preprocessor).- All other keys are app-internal; the library forwards but does not inspect them.
{:error, reason}— propagated up the session-start path.
Example
defmodule MyApp.Agents.Factory do
@behaviour Sagents.Factory
alias Sagents.Agent
alias MyApp.Agents.FactoryConfig
@impl true
def create_agent(agent_id, %FactoryConfig{} = c) do
agent =
Agent.new!(%{
agent_id: agent_id,
scope: c.scope,
model: build_model(c),
base_system_prompt: base_system_prompt(c),
middleware: build_middleware(c),
tools: build_tools(c),
tool_context: c.tool_context
})
{:ok, agent, []}
end
end
Summary
Callbacks
@callback create_agent(agent_id :: String.t(), config :: term()) :: {:ok, Sagents.Agent.t(), session_opts :: keyword()} | {:error, term()}