Sagents (Sagents v0.8.0-rc.8)

Copy Markdown

Sagents provides hierarchical agent capabilities with composable middleware.

Sagents extends LangChain with powerful features:

  • Middleware System: Composable components for agent capabilities
  • TODO Management: Task planning and progress tracking
  • Virtual Filesystem: File operations for agent workflows
  • Task Delegation: Hierarchical sub-agents for complex tasks
  • Context Management: Automatic summarization and optimization
  • Observability: Custom telemetry and tracing via middleware callbacks (see Observability Guide)

Quick Start

alias Sagents.{Agent, State}
alias LangChain.ChatModels.ChatAnthropic

# Create an agent
{:ok, agent} = Agent.new(%{
  model: ChatAnthropic.new!(%{model: "claude-sonnet-4-6"}),
  system_prompt: "You are a helpful assistant."
})

# Execute with a State
state = State.new!(%{messages: [%{role: "user", content: "Hello!"}]})
{:ok, result} = Agent.execute(agent, state)

Middleware Composition

Sagents uses a middleware pattern for extensibility:

# Use default middleware (TODO, Filesystem, SubAgent, etc.)
{:ok, agent} = Agent.new(%{
  model: model,
  middleware: [MyCustomMiddleware]
})

# Customize default middleware
{:ok, agent} = Agent.new(%{
  model: model,
  filesystem_opts: [long_term_memory: true]
})

# Provide complete middleware stack
{:ok, agent} = Agent.new(%{
  model: model,
  replace_default_middleware: true,
  middleware: [MyMiddleware1, MyMiddleware2]
})

Creating Custom Middleware

defmodule MyMiddleware do
  @behaviour Sagents.Middleware

  @impl true
  def init(opts) do
    {:ok, %{enabled: Keyword.get(opts, :enabled, true)}}
  end

  @impl true
  def system_prompt(_config) do
    "Custom instructions for the agent."
  end

  @impl true
  def tools(_config) do
    [my_custom_tool()]
  end

  @impl true
  def before_model(state, _config) do
    # Preprocess state before LLM
    {:ok, state}
  end

  @impl true
  def after_model(state, _config) do
    # Postprocess after LLM response
    {:ok, state}
  end
end

State Management

Agent state flows through middleware and execution:

state = Sagents.State.new!(%{
  messages: [%{role: "user", content: "Hello"}],
  files: %{"/notes.txt" => "content"},
  metadata: %{session_id: "123"}
})

{:ok, result_state} = Sagents.Agent.execute(agent, state)

See Sagents.Agent for agent creation and execution, and Sagents.State for state management functions.