Current section

Files

Jump to
sagents lib sagents.ex
Raw

lib/sagents.ex

defmodule Sagents do
@moduledoc """
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](docs/observability.md))
## 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.
"""
end