Python-first Coding Agent API and CLI.
Project description
sagent🪄
The self-mutating multi-provider coding-agent CLI and typed Python library.
Tutorial · Concepts · Providers · Tools · CLI · Sessions · Security · Architecture · API · Streaming · Compaction · Slack · Self-hosted · Showcase · Examples
Quick Start
# Mac:
# brew install ripgrep fd uv
# Ubuntu/Debian:
# sudo apt-get install -y curl ripgrep fd-find
# curl -LsSf https://astral.sh/uv/install.sh | sh
uv tool install sagent
sagent
Better CLI
Things Claude Code, Codex CLI, and Gemini CLI don't do:
- Async REPL. Chat with agents about jobs while those jobs run. No ctrl+b, no manual juggling.
- Hot self-mutation. Switch provider, model, or thinking effort mid-session in plain English. No restart.
- One CLI, every provider. Anthropic, OpenAI, Google, Moonshot, DashScope, MiniMax, OpenAI-compatible endpoints, self-hosted HuggingFace models, and a managed
llama.cppserver, all behind one binary. - Unified cost tracking. One USD total across every provider in a session; sub-agent costs roll up to the root.
--max-budget-usd Ncaps the whole tree. - Self-directing agent fleets. Agents retune their own runtime -- provider, model, thinking, context -- mid-task. A coordinator can do it to its workers over
AgentSend: "switch to o1, crank thinking, recompact and drop the file reads." - Recursive agent messaging. Any spawned agent can spawn and
AgentSendto any peer, so coordination is a tree, not a star. Claude Code's experimental Agent Teams is flat (one lead, no nesting); Codex and Gemini have no peer messaging. - Interruptible, detachable tasks. Tell a stuck task to stop, or detach one and let it keep running.
- Richer built-in tools.
PaperSearch/PaperFetchwalk citation graphs and fetch PDFs, multi-backendWebSearch,WebFetchwith markdown extraction, atomic read/write tracking on file tools. - Unix-aligned and pipeable.
stdin,stdout, exit codes, and--output-format jsonare first-class. Pipe throughjq, drop intoipython(sameprompt_toolkitunderneath).
Uniquely also an API
- One runtime, every surface. The same
Agentclass powers the CLI, your application code, and recursive sub-agents. - Typed Python objects.
Agent,Tool,Model,Provider, andMessageare protocols and dataclasses you import, compose, and unit-test. - Peer-to-peer agent messaging. Any spawned agent can
AgentSendto any other named peer -- not just its parent. Like user input, peer messages preempt the receiving agent's tool calls, so no agent blocks waiting on a stuck child.
Use it as a library:
from sagent import tools
from sagent.agent import Agent
from sagent.lib.custom_json import json_freeze
from sagent.providers import Google
agent = Agent(
model=Google.from_env().model("gemini-3.1-pro-preview"),
system="You are a scientist.",
tools=[tools.Read(), tools.Glob(), tools.Grep()],
)
result = await agent.run(json_freeze({"prompt": "analyze the CSV in ./data/"}))
print(result.content)
Install
Sagent requires Python 3.12 or newer. ripgrep and fd-find are
optional -- sagent has Python fallbacks when absent -- but recommended
for faster Grep / Glob. PDF rendering uses the bundled pypdfium2
wheel and needs no system install. The Quick Start
above installs the sagent CLI.
Add sagent to your own project as a library:
uv add sagent
Or run from a source checkout:
git clone --depth 1 https://github.com/rekursiv-ai/sagent.git
cd sagent
uv run sagent --help
Run
Bare sagent uses Anthropic and reads ANTHROPIC_API_KEY:
export ANTHROPIC_API_KEY=...
sagent
Pick a different provider by setting its key (see
Provider setup) and passing --provider:
export OPENAI_API_KEY=...
sagent --provider OpenAI
--provider defaults to the first name in --allow-providers, so
SAGENT_ALLOW_PROVIDERS alone picks the default backend and also caps
which providers spawned sub-agents may use:
SAGENT_ALLOW_PROVIDERS=OpenAI sagent # OpenAI is now the default provider
Pipe a prompt on stdin for non-interactive use:
printf 'Say hi in one sentence.' | \
sagent --provider OpenAI --output-format json
Use --continue to resume the most recent session for this working directory, --session PATH for an explicit session directory, or --ephemeral when prompts and auto-memory should not be written to disk. Use --max-budget-usd N to cap API spend for the current run.
See CLI and Sessions for the full flag set.
Quickstart: Python
import asyncio
from sagent import tools
from sagent.agent import Agent
from sagent.lib.custom_json import json_freeze
from sagent.providers import Anthropic
async def main() -> None:
agent = Agent(
model=Anthropic.from_env().model("claude-sonnet-4-6"),
system="You are a concise coding assistant.",
tools=[tools.Read(), tools.Grep(), tools.Glob()],
)
result = await agent.run(json_freeze({"prompt": "Summarize README.md"}))
print(result.content)
asyncio.run(main())
Agent.run() accepts a JSON directive with a prompt key and returns a Message.
See API, Tutorial, and Concepts for more detail.
Provider setup
Sagent ships API-key providers for Anthropic, OpenAI, OpenAISubscription, Google, Moonshot, DashScope, MiniMax, and generic OpenAI-compatible endpoints, a subscription-backed AnthropicCLI that rides your installed claude login, plus a managed local LlamaCpp provider. Set the key (or run the login) for the provider you plan to use:
export ANTHROPIC_API_KEY=...
export OPENAI_API_KEY=...
export GOOGLE_API_KEY=...
export MOONSHOT_API_KEY=...
export DASHSCOPE_API_KEY=...
export MINIMAX_API_KEY=...
and
export SAGENT_ALLOW_PROVIDERS=...
to set the default value of the --provider flag.
| Provider | Environment variable | Example model |
|---|---|---|
Anthropic |
ANTHROPIC_API_KEY |
claude-sonnet-4-6 |
AnthropicCLI |
none (claude auth login --claudeai) |
claude-sonnet-4-6 |
OpenAI |
OPENAI_API_KEY |
gpt-5.6-sol |
Google |
GOOGLE_API_KEY |
gemini-3.1-pro-preview |
Moonshot |
MOONSHOT_API_KEY |
kimi-k2.6 |
DashScope |
DASHSCOPE_API_KEY |
qwen3.6-plus |
MiniMax |
MINIMAX_API_KEY |
MiniMax-M2.7 |
SelfHosted |
none | Qwen/Qwen3.6-27B |
LlamaCpp |
none (uses LLAMA_CPP_MODEL + LLAMA_CPP_SERVER) |
qwen3.6-27b-12gb |
See Providers for the provider matrix, inference rules, and OpenAI-compatible provider setup.
Self-hosted models
Install the local runtime extra from a checkout:
uv sync --extra selfhosted
Or add it to your project from PyPI:
uv add "sagent[selfhosted]"
Then pass a HuggingFace repo ID or local snapshot path:
sagent --provider SelfHosted --model Qwen/Qwen3.6-27B+bfloat16+cuda
sagent --provider SelfHosted --model Qwen/Qwen3.6-27B+cuda+bfloat16
For a small smoke test:
sagent --provider SelfHosted --model Qwen/Qwen3-0.6B+float16+cuda \
--effort none --max-response-tokens 32 --max-tool-call-rounds 1
SelfHosted options use + suffixes after the model name. Device, dtype, and compile can appear in any order, but each category can appear once.
The LlamaCpp provider is a second local option: it manages a
llama-server subprocess and talks to it over its OpenAI-compatible
endpoint. Point LLAMA_CPP_SERVER at a built llama-server binary and
LLAMA_CPP_MODEL at a .gguf file, then run
sagent --provider LlamaCpp --model qwen3.6-27b-12gb.
See Self-hosted Models for options, local snapshot paths, and runtime requirements.
Examples
The examples/ directory contains small, runnable examples:
offline_custom_tool.py: run an agent/tool/model loop without API keys.decorator_tool.py: wrap a function as a tool.custom_tool.py: implement the fullToolprotocol.multi_agent_reviewer.py: spawn an isolated reviewer child.openai_compatible_provider.py: connect an OpenAI-compatible endpoint.
Start with the tutorial, then use the examples as copyable patterns. See Examples and Tools.
Security and privacy
Sagent is an agent runtime, not a sandbox. Enabled tools run with the current
process permissions: Bash executes local commands, file tools read and write
accessible paths, and provider/network tools send data to their configured
services. Sessions are plaintext local state and may contain prompts, model
responses, tool results, file snippets, and paths.
Use narrow tool sets, pass --ephemeral for one-off sensitive
prompts so sessions and auto-memory are disabled, and run Sagent inside your own
OS/container sandbox when a task needs hard isolation. See
Security.
Comparison
How Sagent compares to aider, LangChain, Claude Code, Codex CLI, Gemini CLI, and other adjacent projects
Not yet in Sagent: MCP, LSP, native sandboxing, desktop UI, tree-sitter repo map, hosted service, browser automation.
This comparison focuses on the runtime shape rather than every feature of each project.
| Sagent | aider | LangChain | OpenClaw | Cline | Claude Code | Codex CLI | Gemini CLI | Flue | Pi | Attractor | npcsh | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Python library | ✅ | 🟡 | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
| Multi-provider | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| Context compaction | ✅ | 🟡 | 🟡 | ❌ | 🟡 | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| User-initiated backend swap | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ |
| Agent-initiated backend swap | ✅ | ❌ | 🟡 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | 🟡 | ❌ |
| Agent self-mutation | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | 🟡 | ❌ | 🟡 |
| Context hot-swap | ✅ | 🟡 | 🟡 | 🟡 | 🟡 | ❌ | ❌ | ❌ | 🟡 | ✅ | ✅ | ❌ |
| Recursive agent spawn | ✅ | ❌ | ✅ | 🟡 | ❌ | 🟡 | 🟡 | ❌ | ✅ | 🟡 | ✅ | ✅ |
| Multi-agent (fully detached) | ✅ | ❌ | ✅ | ✅ | ❌ | 🟡 | 🟡 | ❌ | ✅ | 🟡 | ✅ | 🟡 |
| GitHub stars (May 2026) | -- | 44.4k | 135.8k | 368.6k | 61.4k | -- | 80.1k | 103.2k | 2.5k | 48.6k | 1.1k | 388 |
✅ = yes, 🟡 = partial, ❌ = no. Corrections welcome -- open a PR.
How each project works
- aider -- git-native pair programmer; markdown-diff edits (no structured tool calls), litellm transport, destructive mid-session
/modelswap, tree-sitter repo map, no multi-agent. - LangChain/LangGraph -- broad LLM-app framework; everything is possible but application-defined, not an opinionated agent loop.
- OpenClaw -- TypeScript multi-platform personal assistant; multi-agent but end-user-oriented, no Python library.
- Cline -- VS Code extension; multi-provider, single-agent, truncation-based context, not importable.
- Claude Code (Anthropic) -- Anthropic-only vendor CLI; recursive sub-agents and compaction, but no provider swap and no Python library (JS SDK).
- Codex CLI (OpenAI) -- OpenAI-only Rust CLI; sandboxed local execution, single-agent, no compaction, no API.
- Gemini CLI (Google) -- Google-only TypeScript CLI; summarization compaction, single-agent, no API, no custom tools.
- Flue (Astro) -- headless TypeScript harness; pluggable sandboxes, recursive
session.task()delegation, model chosen per call (no agent-initiated swap), no UI/compaction. - Pi (earendil-works/pi) -- minimal TypeScript harness; branchable session tree,
/reloadsoft self-mutation, sub-agents opt-in only. - npcsh -- Python agentic shell; filesystem-defined NPC personas, many built-in modes, hub-and-spoke sub-agents, rate-limit-fallback "compaction".
- Attractor (StrongDM) -- a spec, not an implementation; DOT-graph pipeline where nodes are AI tasks and the graph is the workflow.
Name
sagent (noun, neologism) /ˈseɪ.dʒənt/
From sage + agent.
An AI assistant that confidently performs a task you didn't ask for while ignoring the one you did.
"I asked the sagent to fix one failing test -- it deleted the test and reported all green."
Contributing
See CONTRIBUTING.md for local validation and public contribution flow.
License
Apache License 2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sagent-0.1.12.tar.gz.
File metadata
- Download URL: sagent-0.1.12.tar.gz
- Upload date:
- Size: 3.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66583b2865c61e56df5fad020f5cdcd22b002c13b44f8dde53e73e8cfab1a42b
|
|
| MD5 |
ac387c29c3557b5f1eadc015723cbdfb
|
|
| BLAKE2b-256 |
2a1349347a1fe024d6cc95923217ba5dc3ccc98702612c2ebfab9f139fdbb2af
|
Provenance
The following attestation bundles were made for sagent-0.1.12.tar.gz:
Publisher:
publish-pypi.yml on rekursiv-ai/sagent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sagent-0.1.12.tar.gz -
Subject digest:
66583b2865c61e56df5fad020f5cdcd22b002c13b44f8dde53e73e8cfab1a42b - Sigstore transparency entry: 2278921927
- Sigstore integration time:
-
Permalink:
rekursiv-ai/sagent@ed443f0bdf3fc32f40e564a533e2ac9640425564 -
Branch / Tag:
refs/tags/v0.1.12 - Owner: https://github.com/rekursiv-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@ed443f0bdf3fc32f40e564a533e2ac9640425564 -
Trigger Event:
release
-
Statement type:
File details
Details for the file sagent-0.1.12-py3-none-any.whl.
File metadata
- Download URL: sagent-0.1.12-py3-none-any.whl
- Upload date:
- Size: 675.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f5648cd73aee5db45568f42ba9c7388794407e414df7adc602bdd69b2d8ae7d
|
|
| MD5 |
81a9d3dedfd42de91adb2c306054938a
|
|
| BLAKE2b-256 |
38d218a3b1891005c7131da931234d26fbfd86dcf18b1badc592c44c997b840b
|
Provenance
The following attestation bundles were made for sagent-0.1.12-py3-none-any.whl:
Publisher:
publish-pypi.yml on rekursiv-ai/sagent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sagent-0.1.12-py3-none-any.whl -
Subject digest:
2f5648cd73aee5db45568f42ba9c7388794407e414df7adc602bdd69b2d8ae7d - Sigstore transparency entry: 2278921944
- Sigstore integration time:
-
Permalink:
rekursiv-ai/sagent@ed443f0bdf3fc32f40e564a533e2ac9640425564 -
Branch / Tag:
refs/tags/v0.1.12 - Owner: https://github.com/rekursiv-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@ed443f0bdf3fc32f40e564a533e2ac9640425564 -
Trigger Event:
release
-
Statement type: