Catalog PyPI
Back to packageRELEASE DETAILS

0.2.7

PyPI

agentm

AgentM SDK

Published24 Aug 2026
Direct dependencies19
Transitive dependenciesNot calculated

README

Version 0.2.7 documentation

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.

LayerResponsibility
AgentSessionPublic session handle: create, run, prompt, interrupt, spawn, fork, resume, shutdown.
DriverPersistent async loop: consume triggers, call the provider, execute tools, commit turns.
TriggerUnified input shape for user input, background completion, monitor fire, subagent result, continuation, and injection.
TriggerEnvelopeQueue/routing metadata around a trigger: priority (now/next/later), target identity, origin, mode, and presenter/system flags.
PromptRunLifecycle of one accepted external trigger. Its receipt stays open across model/tool continuations, while run_id and run_step group the resulting turns.
MessageMetaControl-plane metadata for synthetic messages, hidden attachments, no-response prompts, replay policy, token accounting, origin, mode, and target identity.
TurnDurable transaction unit: exactly one assistant response, all tool results requested by that response, outcome, timing, and usage.
TrajectoryStoreThe single replaceable persistence boundary for session metadata, incomplete checkpoints, committed turns, message-node indexes, heads, and cache/compaction state.
TrajectoryNodeA 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.
ContextPolicyReplaceable 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.
EventBusImmutable event dispatch surface for observation and policy hooks.
AtomAPIThe only surface atoms receive at install time.
CancelSignalCooperative 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.
BackgroundTaskRegistryShared helper for atom-owned detached work: task handles, slot caps, and cooperative cancel.
StreamFn / ProviderConfigReplaceable LLM provider boundary.
ProviderResolverReplaceable active-provider selection policy.
ToolExecutorReplaceable tool execution boundary. Tool requirements declare isolation, filesystem/network access, concurrency, and interrupt behavior; executor capabilities declare what the backend can honor.
ToolOrchestratorReplaceable batch scheduler for tool calls: exclusive vs parallel-safe partitioning, sibling-error cascading, and cooperative cancellation.
PermissionPolicyReplaceable 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 / ResourceWriterReplaceable 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:

ScenarioMeaning
emptyNo atoms; host code must provide provider/tools directly.
minimalObservability, 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:

StoreUse
InMemoryTrajectoryStoreTests and ephemeral embedding.
JsonlTrajectoryStoreLocal append-only persistence, one JSONL file per session.
PostgresTrajectoryStoreDurable 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 groupFieldsPurpose
Identityid, session_id, root_session_id, parent_session_id, seqStable lookup, per-session append order, and trace-scope scans.
Linksparent_id, logical_parent_idVisible chain reconstruction, fork prefix sharing, and compact-boundary lineage.
Ownershipagent_id, is_sidechainSubagent sidechains and agent-specific resume.
Turn jointurn_id, turn_index, run_id, run_step, message_indexJoin message nodes back to committed Turns and group them by PromptRun.
Shapekind, role, timestampDistinguish 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

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 19

Native requirements
19 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
pydantic
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
pydantic>=2.0runtime
loguru
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
loguru>=0.7runtime
pyyaml
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
pyyaml>=6.0runtime
typer
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
typer>=0.12runtime
rich
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
rich>=13.0runtime
python-frontmatter
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
python-frontmatter>=1.3.0runtime
textual
Environment
{
  "extras": "syntax",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
textual[syntax]>=2.0runtime
sqlalchemy
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
sqlalchemy>=2.0runtime
ast-grep-cli
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
ast-grep-cli>=0.44.1runtime
httpx
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
httpx>=0.28.0runtime
openai
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
openai>=1.50.0runtime
anthropic
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
anthropic>=0.86.0runtime
tiktoken
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
tiktoken>=0.12.0runtime
jsonschema
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
jsonschema>=4.0runtime
opentelemetry-api
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
opentelemetry-api>=1.30.0runtime
opentelemetry-sdk
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
opentelemetry-sdk>=1.30.0runtime
opentelemetry-exporter-otlp
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
opentelemetry-exporter-otlp>=1.30.0runtime
clickhouse-connect
Environment
{
  "extras": "",
  "marker": "extra == \"storage-clickhouse\"",
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
clickhouse-connect>=0.7.0; extra == "storage-clickhouse"runtime
psycopg
Environment
{
  "extras": "binary",
  "marker": "extra == \"storage-postgres\"",
  "requires_python": ">=3.12",
  "evaluation": "NOT_EVALUATED"
}
psycopg[binary]>=3.2.0; extra == "storage-postgres"runtime

Distribution files

2 collected
agentm-0.2.7-py3-none-any.whl

bdist_wheel · 554.86 KB · Python py3

Source file
agentm-0.2.7.tar.gz

sdist · 468.03 KB · Python source

Source file

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 22:38 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:a99980df1217ff50e3fc27dd65407bc2c1dc97dff0e3f312fa1895cfaf527dd7

Other collected versions

View all collected versions →