Config-as-code agent SDK
Project description
OpenAgents SDK
Config-as-code, async-first, pluggable SDK for building protocol-rich single-agent systems.
English | 中文
Overview
OpenAgents gives you a small, explicit runtime kernel for single-agent execution. It is designed for developers who want real control over agent behavior — not a black-box framework that hides everything inside one monolithic execute() call.
Designed for:
- Teams that want a clear, auditable agent runtime instead of a magic framework
- Developers building coding agents, research agents, and workflow agents
- Products that need custom middle protocols, safety rules, and context logic
- Applications that want a stable kernel now and product infrastructure on top
Deliberately not:
- A multi-agent control plane (one
run= oneagent_id) - A job scheduler or queue system
- A durable product control plane
- A UI framework
Team orchestration, mailboxes, schedulers, approvals, and product UX belong above this layer.
Why OpenAgents
Most agent frameworks collapse three very different concerns into one abstraction:
- Kernel protocol — what a run is (inputs, outputs, state)
- Runtime seams — how a run behaves (memory, tools, context assembly)
- Product middle protocols — what only your application understands (task envelopes, review contracts, permission models)
OpenAgents keeps them separate:
┌─────────────────────────────────────────────────┐
│ App / Product Protocols │
│ task envelopes · coding plans · approvals │
│ review contracts · artifact taxonomies │
└──────────────────────┬──────────────────────────┘
│
┌──────────────────────▼──────────────────────────┐
│ SDK Runtime Seams (8) │
│ memory · pattern · tool · tool_executor │
│ context_assembler · runtime · session │
│ events · skills │
└──────────────────────┬──────────────────────────┘
│
┌──────────────────────▼──────────────────────────┐
│ Kernel Protocols │
│ RunRequest · RunResult · RunContext │
│ ToolExecutionRequest · SessionArtifact │
└─────────────────────────────────────────────────┘
This separation gives you a small kernel with explicit behavior, stable extension seams instead of ad-hoc monkeypatching, and room to invent app-specific protocols without forking the SDK.
Installation
Core (zero optional deps):
pip install io-openagent-sdk
# or
uv add io-openagent-sdk
Optional extras:
| Extra | Installs | Use when |
|---|---|---|
cli |
rich, questionary, watchdog, pyyaml |
Interactive CLI, hot reload, colour output |
openai |
openai, httpx |
OpenAI-compatible LLM providers |
litellm |
litellm |
Non-OpenAI backends via LiteLLM (Bedrock, Vertex, Gemini, Azure, …) |
mem0 |
mem0ai |
Persistent cross-session memory |
mcp |
mcp |
MCP tool bridge |
otel |
opentelemetry-api |
OpenTelemetry event bridge |
sqlite |
aiosqlite |
SQLite-backed session persistence |
tokenizers |
tiktoken |
Accurate token counting for OpenAI |
yaml |
pyyaml |
YAML config files |
all |
Everything above | Development / full-featured deployments |
uv add "io-openagent-sdk[cli]"
uv add "io-openagent-sdk[openai,mcp]"
uv add "io-openagent-sdk[all]"
Requires Python ≥ 3.11.
Quick Start
1. Define your agent in JSON
{
"version": "1.0",
"agents": [
{
"id": "assistant",
"name": "demo-agent",
"memory": {"type": "window_buffer", "on_error": "continue"},
"pattern": {"type": "react"},
"llm": {"provider": "anthropic", "model": "claude-sonnet-4-6"},
"tools": [
{"id": "search", "type": "builtin_search"},
{"id": "files", "type": "read_file"}
]
}
]
}
2. Run via CLI
# Single-shot turn
openagents run agent.json --input "hello"
# Interactive multi-turn REPL
openagents chat agent.json
# Hot-reload on config change (dev mode)
openagents dev agent.json
3. Run via Python (async)
import asyncio
from openagents import Runtime
async def main() -> None:
runtime = Runtime.from_config("agent.json")
result = await runtime.run(
agent_id="assistant",
session_id="demo",
input_text="What files are in the current directory?",
)
print(result.output)
asyncio.run(main())
4. Run via Python (sync helpers)
from openagents import run_agent, run_agent_detailed, run_agent_with_dict
# Simple sync wrapper
result = run_agent("agent.json", agent_id="assistant", session_id="s1", input_text="hello")
# Detailed result (usage, artifacts, stop reason)
result = run_agent_detailed("agent.json", agent_id="assistant", session_id="s1", input_text="hello")
print(result.usage.cost_usd, result.stop_reason)
# Inline config (no file needed)
result = run_agent_with_dict(
{
"version": "1.0",
"agents": [
{
"id": "assistant",
"name": "demo",
"memory": {"type": "buffer"},
"pattern": {"type": "react"},
"llm": {"provider": "mock"},
"tools": []
}
]
},
agent_id="assistant",
session_id="demo",
input_text="hello",
)
5. Streaming
from openagents import Runtime, RunRequest
async def stream_example() -> None:
runtime = Runtime.from_config("agent.json")
request = RunRequest(agent_id="assistant", session_id="s1", input_text="hello")
async for chunk in runtime.run_stream(request):
print(chunk.kind, chunk.data)
Core Concepts
Runtime Flow
Caller
→ Runtime facade (Runtime.run / run_stream)
→ Runtime plugin (DefaultRuntime)
→ Session manager + Event bus
→ Context assembler (what enters this run?)
→ Pattern.setup() → Memory.inject()
→ Pattern.execute() ↔ Tool calls (policy + executor)
→ Memory.writeback() → Context assembler.finalize()
→ RunResult
Key Objects
| Object | Role |
|---|---|
RunRequest |
Inputs to a single run (agent_id, session_id, input_text, context_hints, budget) |
RunResult[OutputT] |
Output of a run (output, usage, artifacts, stop_reason, error) |
RunContext[DepsT] |
Per-run state carrier available to tools and patterns |
RunUsage |
Token counts + cost_usd + cache stats |
RunBudget |
Limits: max_cost_usd, max_tokens, max_turns, max_validation_retries |
RunArtifact |
Named artifact emitted during a run (carries metadata) |
StopReason |
Typed termination state (end_turn, budget_exhausted, error, …) |
Plugin Selectors
Every plugin is loaded by either:
{"type": "react"} // builtin or decorator-registered name
{"impl": "myapp.patterns.custom.MyPattern"} // Python dotted path
If both are set, impl wins. Top-level runtime, session, and events each take exactly one selector; agent-level plugins require at least one.
Builtin Components
Memory
| Name | Description |
|---|---|
buffer |
Full in-memory conversation history |
window_buffer |
Sliding window over recent turns |
markdown_memory |
File-backed long-term memory (MEMORY.md index) |
mem0 |
Persistent semantic memory via mem0ai ([mem0] extra) |
chain |
Compose multiple memory plugins in sequence |
Pattern (Reasoning Loop)
| Name | Description |
|---|---|
react |
ReAct: think → act → observe loop |
plan_execute |
Plan first, then execute steps |
reflexion |
Self-reflection and iterative refinement |
Context Assembler
| Name | Description |
|---|---|
truncating |
Simple head truncation to fit token budget |
head_tail |
Keep head + tail, drop middle |
sliding_window |
Rolling window over recent messages |
importance_weighted |
Score-based retention |
Builtin Tools
| Category | Tools |
|---|---|
| Search | builtin_search, tavily_search |
| Files | read_file, write_file, list_files, delete_file |
| Text | grep_files, ripgrep, json_parse, text_transform |
| HTTP | http_request, url_parse, url_build, query_param, host_lookup |
| System | shell_exec, execute_command, get_env, set_env |
| Time | current_time, date_parse, date_diff |
| Random | random_int, random_choice, random_string, uuid |
| Math | calc, percentage, min_max |
| Memory | remember_preference |
| MCP | mcp (bridge to any MCP server, [mcp] extra) |
App Infrastructure
| Seam | Builtin | Description |
|---|---|---|
runtime |
default |
DefaultRuntime orchestrator |
session |
in_memory |
In-process session storage |
events |
async |
Async event bus |
CLI Reference
Install the cli extra for the full CLI experience:
uv add "io-openagent-sdk[cli]"
| Command | Description |
|---|---|
openagents run <path> |
Execute a single-shot turn |
openagents chat <path> |
Interactive multi-turn REPL |
openagents dev <path> |
Hot-reload runtime on config change |
openagents validate <path> |
Validate an agent.json without running |
openagents schema |
Dump the full AppConfig JSON Schema |
openagents list-plugins |
List all registered plugins by seam |
openagents config show <path> |
Print the fully-resolved AppConfig |
openagents init <name> |
Scaffold a new project from a template |
openagents new plugin <seam> <name> |
Scaffold a plugin skeleton + test stub |
openagents replay <path> |
Re-render a persisted transcript |
openagents doctor |
Environment health check |
openagents version |
Print SDK / Python / extras / plugin counts |
openagents completion <shell> |
Emit a shell-completion script |
Exit codes: 0 success · 1 usage error · 2 validation error · 3 runtime error
Writing a Custom Plugin
Any seam can be extended by implementing the plugin interface and pointing to it via impl:
# myapp/patterns/my_pattern.py
from openagents.interfaces import PatternPlugin, RunContext
class MyPattern(PatternPlugin):
async def execute(self, context: RunContext) -> str:
# your reasoning loop here
return "done"
{
"pattern": {"impl": "myapp.patterns.my_pattern.MyPattern"}
}
Or use the decorator registry for named plugins:
from openagents.decorators import pattern
@pattern("my_react")
class MyReact(PatternPlugin):
...
{"pattern": {"type": "my_react"}}
See Plugin Development for the full guide.
App-Defined Middle Protocols
The SDK provides carriers for product-specific state — no need to fork the kernel:
| Carrier | Use for |
|---|---|
RunRequest.context_hints |
Pass structured hints into context assembly |
RunRequest.metadata |
Caller metadata (task IDs, trace IDs, …) |
RunContext.state |
Mutable per-run app state shared across tools/pattern |
RunContext.scratch |
Ephemeral scratchpad within a run |
RunContext.assembly_metadata |
Signals from context assembler to pattern |
RunArtifact.metadata |
Structured metadata on emitted artifacts |
Examples
| Example | Description |
|---|---|
examples/quickstart/ |
Minimal builtin-only setup — first contact with the kernel |
examples/production_coding_agent/ |
Production coding agent: task packets, persistent memory, follow-up recovery, delivery artifacts |
examples/pptx_generator/ |
Interactive 7-stage PPT generator CLI (pptx-agent) with MCP + multi-pattern pipeline |
Full example guide: docs/examples.md
Documentation
Developer docs live in the docs directory.
| Document | Description |
|---|---|
| Developer Guide | Architecture boundaries, runtime lifecycle, state carriers |
| Repository Layout | Directory structure, doc topology, test conventions |
| Seams & Extension Points | Decision tree: which seam for which problem |
| Configuration Reference | JSON schema, selector rules, builtin names |
| Plugin Development | Loader mechanics, plugin contracts, testing patterns |
| API Reference | Package exports, runtime methods, protocol objects |
| CLI Reference | Full CLI surface and exit codes |
| Examples Guide | What each example demonstrates |
| Migration 0.2 → 0.3 | Upgrade guide |
Recommended reading order for new users:
Development
This project uses uv for dependency management.
# Clone and install all dev deps
git clone https://github.com/your-org/openagent-python-sdk
cd openagent-python-sdk
uv sync
# Run the full test suite
uv run pytest -q
# Run a single test
uv run pytest -q tests/unit/test_runtime_core.py::MyTest::test_case
# Coverage (floor: 92%)
uv run coverage run -m pytest && uv run coverage report
# Lint
uv run ruff check .
uv run ruff format --check .
Rule: When adding, removing, or changing code under the openagents package, you must add/update/remove the corresponding tests in the same change. The test suite and source are co-evolved.
What's New in 0.4.0
shell_exec— allowlist-aware subprocess tool with cwd/env/timeout controlstavily_search— REST-based Tavily search tool (readsTAVILY_API_KEY)markdown_memory— file-backed long-term memory (MEMORY.md index + per-section files)remember_preference— companion tool for agent-side preference captureopenagents.utils.env_doctor— reusable environment health check frameworkopenagents.cli.wizard— Rich + questionary wizard component for interactive CLIsexamples/pptx_generator/— production-grade 7-stage PPT generator (pptx-agent)
Full changelog: CHANGELOG.md | Migration guide: 0.2 → 0.3
License
Apache License 2.0 — see LICENSE.
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 io_openagent_sdk-0.4.0.tar.gz.
File metadata
- Download URL: io_openagent_sdk-0.4.0.tar.gz
- Upload date:
- Size: 236.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
521974af1a1996e114bd26feaa165df898309c008741c62eac08d34b7c623a01
|
|
| MD5 |
12f3da23fa4b547f0e7416eadfd8da72
|
|
| BLAKE2b-256 |
ac8d9fde6f8381e0004b0480a56b99e754d15c49c4669a9fed3c7324fef5b811
|
Provenance
The following attestation bundles were made for io_openagent_sdk-0.4.0.tar.gz:
Publisher:
publish.yml on io-wy/openagent-python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
io_openagent_sdk-0.4.0.tar.gz -
Subject digest:
521974af1a1996e114bd26feaa165df898309c008741c62eac08d34b7c623a01 - Sigstore transparency entry: 1670564812
- Sigstore integration time:
-
Permalink:
io-wy/openagent-python-sdk@26313485ae9be8e358a4e355e639923ab8823b86 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/io-wy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@26313485ae9be8e358a4e355e639923ab8823b86 -
Trigger Event:
push
-
Statement type:
File details
Details for the file io_openagent_sdk-0.4.0-py3-none-any.whl.
File metadata
- Download URL: io_openagent_sdk-0.4.0-py3-none-any.whl
- Upload date:
- Size: 311.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31cc25e8de9815ade5a658cdad26524712f5aa5da5c3cd4b4a4c8dfd45cb7778
|
|
| MD5 |
4fc291084d26a368d1a3bd8a7975a62a
|
|
| BLAKE2b-256 |
bf085122e5afea0535f79a4a68052f80deb06da34023bf6896bc69ceb665cbc2
|
Provenance
The following attestation bundles were made for io_openagent_sdk-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on io-wy/openagent-python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
io_openagent_sdk-0.4.0-py3-none-any.whl -
Subject digest:
31cc25e8de9815ade5a658cdad26524712f5aa5da5c3cd4b4a4c8dfd45cb7778 - Sigstore transparency entry: 1670564906
- Sigstore integration time:
-
Permalink:
io-wy/openagent-python-sdk@26313485ae9be8e358a4e355e639923ab8823b86 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/io-wy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@26313485ae9be8e358a4e355e639923ab8823b86 -
Trigger Event:
push
-
Statement type: