AgentM SDK Core
This worktree is the reduced AgentM SDK core. It keeps the substrate small: session lifecycle, trajectory persistence, extension loading, provider streams, tool execution, operations ports, and observability hooks. CLI, gateway peers, contrib scenarios, catalog machinery, and product-specific policies are outside this branch until the core abstraction is stable.
Core Abstraction
The SDK is mechanism, not policy. Policy enters through atoms.
| Layer | Responsibility |
|---|---|
AgentSession |
Public session handle: create, run, prompt, interrupt, spawn, fork, resume, shutdown. |
Driver |
Persistent async loop: consume triggers, call the provider, execute tools, commit turns. |
Trigger |
Unified input shape for user input, background completion, monitor fire, subagent result, continuation, and injection. |
TriggerEnvelope |
Queue/routing metadata around a trigger: priority (now/next/later), target identity, origin, mode, and presenter/system flags. |
PromptRun |
Lifecycle of one accepted external trigger. Its receipt stays open across model/tool continuations, while run_id and run_step group the resulting turns. |
MessageMeta |
Control-plane metadata for synthetic messages, hidden attachments, no-response prompts, replay policy, token accounting, origin, mode, and target identity. |
Turn |
Durable transaction unit: exactly one assistant response, all tool results requested by that response, outcome, timing, and usage. |
TrajectoryStore |
The single replaceable persistence boundary for session metadata, incomplete checkpoints, committed turns, message-node indexes, heads, and cache/compaction state. |
TrajectoryNode |
A committed message or compact-boundary index record used for fork, resume, sidechains, compaction, and prompt-cache lookup. Content replacement is state attached atomically to a compact boundary, not another node kind. |
ContextPolicy |
Replaceable context reconstruction policy. Durable compaction and cache decisions use ContentReplacementState and PromptCacheState in the selected TrajectoryStore, so they survive resume/fork without a second policy-owned store. |
EventBus |
Immutable event dispatch surface for observation and policy hooks. |
AtomAPI |
The only surface atoms receive at install time. |
CancelSignal |
Cooperative cancellation boundary shared by provider streams, tools, operations, and optionally foreground child sessions. Its typed reason carries causes such as user cancel, submit interrupt, shutdown, or task stop. |
BackgroundTaskRegistry |
Shared helper for atom-owned detached work: task handles, slot caps, and cooperative cancel. |
StreamFn / ProviderConfig |
Replaceable LLM provider boundary. |
ProviderResolver |
Replaceable active-provider selection policy. |
ToolExecutor |
Replaceable tool execution boundary. Tool requirements declare isolation, filesystem/network access, concurrency, and interrupt behavior; executor capabilities declare what the backend can honor. |
ToolOrchestrator |
Replaceable batch scheduler for tool calls: exclusive vs parallel-safe partitioning, sibling-error cascading, and cooperative cancellation. |
PermissionPolicy |
Replaceable async permission boundary. It returns a final allow or deny; policies that require user interaction await it internally instead of exposing a deferred runtime state. |
BashOperations / ResourceWriter |
Replaceable external-world ports for execution and resource mutation. |
Extension Contract
An atom is a Python module with:
from agentm.extensions import ExtensionManifest
MANIFEST = ExtensionManifest(
name="my_atom",
description="What this atom contributes.",
registers=("tool:my_tool",),
requires=(),
)
def install(api, config):
...
Atoms may depend on agentm.core.abi, agentm.core.lib, and the public
agentm.extensions surface. The load-time validator rejects imports from
agentm.core.runtime and agentm.core._internal; atoms must reach stateful
runtime subsystems through AtomAPI methods and services.
Session Creation
The public path is AgentSession.create(AgentSessionConfig(...)).
from pathlib import Path
from agentm import AgentSession, AgentSessionConfig, LoopConfig, builtin_scenario_loader
from agentm.storage.trajectory import JsonlTrajectoryStore
session = await AgentSession.create(AgentSessionConfig(
cwd=".",
scenario="minimal",
scenario_loader=builtin_scenario_loader,
provider=("agentm.extensions.builtin.llm_openai", {"model": "gpt-4o"}),
trajectory_store=JsonlTrajectoryStore(Path(".agentm/trajectory")),
loop_config=LoopConfig(max_turns=8, max_tool_calls=32),
tool_allowlist=["read", "bash"],
))
messages = await session.run("summarize src/agentm/core/abi")
await session.shutdown()
Use extensions=[...] to bypass scenario lookup entirely. The core runtime has
no built-in scenario registry; pass builtin_scenario_loader to opt into the
packaged scenario names in this reduced worktree:
| Scenario | Meaning |
|---|---|
empty |
No atoms; host code must provide provider/tools directly. |
minimal |
Observability, local bash operations, retry policy, result caps, file tools, bash tool, and system prompt atom. |
Hosts that need named scenarios beyond these should pass
AgentSessionConfig.scenario_loader.
pip install agentm is enough to run any atom this package ships, providers
and observability included. The only extras are storage backends and the Harbor
adapter, which a deployment opts into by naming one: agentm[storage-postgres],
agentm[storage-clickhouse], agentm[harbor].
Persistence
TrajectoryStore owns durable session metadata, the current incomplete Turn
checkpoint, committed turns, message nodes, explicit heads, and cache/compaction
state. Every model/tool continuation commits a separate Turn with its own
resource/effect transaction; all Turns produced by one external trigger share a
run_id and increasing run_step. A committed Turn and its node/head indexes
share one atomic publication boundary. Root metadata is created automatically before the session starts;
child and forked sessions register their own metadata through the session graph
path. SessionMeta.config persists the minimal resumable context
(root_session_id, depth, scenario, and scenario_dir) so a child or fork
can be loaded in a later process without losing its lineage.
AgentSessionConfig(trajectory_store=None) lets the SDK host resolver select
the configured/default backend. Low-level core factories remain explicitly
ephemeral when no store is supplied. Host programs that
need resume or trace queries must select one store. Provider requests that fail
after retries are persisted as non-replayable ProviderRequestFailed turns
before the trigger receipt raises, so failed sessions do not collapse to an
empty session header.
Built-in stores:
| Store | Use |
|---|---|
InMemoryTrajectoryStore |
Tests and ephemeral embedding. |
JsonlTrajectoryStore |
Local append-only persistence, one JSONL file per session. |
PostgresTrajectoryStore |
Durable transactional session, turn, node/head, and policy-state persistence. |
SQL-backed adapters are opened through the shared SQLAlchemy entry point in
agentm.storage.sql; PostgreSQL and ClickHouse still require their optional
driver extras.
The same TrajectoryStore exposes committed message-tree queries with stable
node ids and portable index fields:
| Field group | Fields | Purpose |
|---|---|---|
| Identity | id, session_id, root_session_id, parent_session_id, seq |
Stable lookup, per-session append order, and trace-scope scans. |
| Links | parent_id, logical_parent_id |
Visible chain reconstruction, fork prefix sharing, and compact-boundary lineage. |
| Ownership | agent_id, is_sidechain |
Subagent sidechains and agent-specific resume. |
| Turn join | turn_id, turn_index, run_id, run_step, message_index |
Join message nodes back to committed Turns and group them by PromptRun. |
| Shape | kind, role, timestamp |
Distinguish committed message and compact-boundary nodes, then filter message roles such as user, assistant, and tool result. Incomplete checkpoints are turn-level records outside the committed node graph. |
SQL stores implement these as normal indexed columns. JSONL stores replay the same per-session journal; they do not maintain a separately recoverable sidecar truth. ClickHouse is an optional OTLP observability backend, not a trajectory store. The SDK relies on the Protocol semantics, not on a JSONL layout.
Verification
uv sync
uv run ruff check src/ tests/
uv run mypy src/
uv run pytest --tb=short
Keep project-index.yaml synchronized with every code and test change, then
validate it with:
python3 ${CLAUDE_PLUGIN_ROOT}/scripts/validate_index.py project-index.yaml
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 agentm-0.2.6.tar.gz.
File metadata
- Download URL: agentm-0.2.6.tar.gz
- Upload date:
- Size: 475.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb0292e194303d02a8c026ea8e5c58c9bf42c337f78d82b5279306cf89eb054a
|
|
| MD5 |
7a2fc0fb2995a561dba31a7d10bd547d
|
|
| BLAKE2b-256 |
18525a06103618382fa2d2a0b369ac1db726dfb3421f2d71a9c735c0905073a2
|
File details
Details for the file agentm-0.2.6-py3-none-any.whl.
File metadata
- Download URL: agentm-0.2.6-py3-none-any.whl
- Upload date:
- Size: 564.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13a0146c796e0a408ba5aae70067db02bc76da7dedeac847994334e329f4fc3f
|
|
| MD5 |
c3e34044c48ed12df9d5754f03c11de2
|
|
| BLAKE2b-256 |
4e0acc1909881057f8f19e9cbe1e2444cfa50c82f3fd2e670fbc951100c85b1c
|