Governed Agent Runtime for A3S
Build auditable coding agents with bounded tools, resumable sessions, and deterministic coordination
Overview • Features • Quick Start • Application Model • TUI and SDKs • Architecture • Development
A3S Code is an async Rust runtime for building governed coding agents. It
owns the agent loop, workspace tools, model adapters, context assembly,
permissions, human approval, memory, delegation, persistence, verification,
and replay. Hosts can use the same runtime from Rust, Node.js, Python, or the
a3s code terminal application.
A3S Code is not a hosted agent service or a terminal widget library. The
a3s-code-core crate provides the execution contracts. The interactive TUI is
shipped by the separate A3S CLI, and its
account integrations and presentation policy remain host concerns.
use a3s_code_core::{Agent, AgentEvent};
#[tokio::main]
async fn main() -> a3s_code_core::Result<()> {
let agent = Agent::new("agent.acl").await?;
let session = agent.session_builder(".").build().await?;
let (mut events, lifecycle) = session
.stream("Find the authentication entry points.", None)
.await?;
while let Some(event) = events.recv().await {
match event {
AgentEvent::TextDelta { text } => print!("{text}"),
AgentEvent::End { .. } => break,
_ => {}
}
}
let _ = lifecycle.await;
Ok(())
}An Agent owns resolved configuration and shared capabilities. An
AgentSession binds them to one workspace and conversation; a configured
SessionStore makes that state durable. Awaiting the stream lifecycle releases
the session for its next transcript operation.
- Async Agent Sessions: Create, resume, atomically replace, cancel, close, send, stream, attach images, dispatch slash commands, and replay runs
- Governed Tool Runtime: Validate arguments, enforce permissions and human approval, apply budgets and hooks, sanitize events, and propagate cancellation
- Bounded Workspace Tools: Read, search, edit, patch, execute, fetch, batch, and paginate without placing unbounded observations into model context
- Native Code Intelligence: Query saved-file symbols, definitions, declarations, references, implementations, and diagnostics through one workspace-scoped semantic runtime
- Managed Context and Memory: Assemble ranked context, compact repeatedly, preserve tool evidence, recall durable memory, and extract significant facts
- Model and MCP Adapters: Use OpenAI-compatible, Anthropic, Zhipu, custom
LlmClient, and session-isolated MCP capabilities through one event model - Structured Generation: Request schema-constrained objects through native provider formats or validated prompt-and-repair fallbacks
- Agent Orchestration: Plan, track goals, delegate foreground or background tasks, run bounded parallel work, and resume deterministic workflows
- Programmable Workflows: Execute sandboxed QuickJS tool programs and explicitly registered A3S Flow-backed dynamic workflows
- Durable Evidence: Persist atomic snapshots, versioned events, traces, artifacts, verification reports, checkpoints, and optional RL trajectories
- Immutable Release Admission: Validate bounded
.a3s/asset.aclmanifests, derive schema-aware identities, and reject incompatible runtime capabilities before activation - Event-Sourced State Graph: Coordinate typed objects and relations through hash-linked records, optimistic patches, strict replay, forks, and diffs
The core crate has no default Cargo features. Baseline capabilities are compiled without optional cloud or daemon dependencies; session policy remains explicit even when the supporting types are available.
| Area | Availability | Included capability |
|---|---|---|
| Agent runtime | Baseline | Async Agent, SessionBuilder, and workspace-bound AgentSession |
| Conversation | Baseline | Send, stream, history, image attachments, slash commands, continuation, and cancellation |
| Providers | Baseline | OpenAI-compatible, Anthropic, Zhipu, and custom LlmClient implementations |
| Structured output | Baseline | Native or prompted JSON generation, JSON Schema validation, partial parsing, and repair |
| Workspace tools | Baseline | Capability-gated file, search, shell, Git, web, batch, program, skill, and delegation tools |
| Code Intelligence | Host-selected local workspace | Saved-file symbols, semantic navigation, diagnostics, typed status, and bounded result evidence |
| Context | Baseline and host-selected | Ranked filesystem, recent-file, ripgrep, memory, prompt-slot, skill, project, and custom sources |
| Memory | Baseline and configurable | Three-tier memory, a default workspace file store, typed overrides, recall, extraction, relations, and pruning |
| Persistence | Configured store | Atomic SessionSnapshotV1, file or memory stores, run replay, traces, tasks, and checkpoints |
| Planning | Baseline session policy | Automatic by default, forced or disabled modes, pre/post hooks, task events, and optional goals |
| Delegation | Manual by default, automatic opt-in | Agent definitions, worker specs, task, parallel_task, tracking, cancellation, and source anchors |
| Session queue | Config or session opt-in | Priority lanes, bounded concurrency, internal/external/hybrid handlers, retry, DLQ, metrics, alerts, rate limits, and timeouts |
| Dynamic workflow | Explicit registration | QuickJS-authored commands executed by an A3S Flow-backed runtime |
| State graph | Explicit application use | Event-sourced objects, relations, behaviors, patches, replay, forks, diffs, and Flow projection |
| MCP | Config or session registration | stdio, SSE, streamable HTTP, OAuth, refresh, and live add/remove management |
| Skills | Filesystem, registry, or live session registration | Search/execute tools, model-visible catalog, live add/remove with shadow restoration, and child-run inheritance |
| Search runtime | Explicit host operation | Browser status, install, update, and repair APIs for managed search runtimes |
| Agent release contract | Baseline admission API | Closed, bounded manifest validation, immutable OCI/provenance binding, canonical identity, typed storage and secret slots, and pre-activation compatibility checks |
| S3 workspace | Cargo feature s3 |
S3-compatible object storage backend with capability-aware tool visibility |
| Agent daemon | Cargo feature serve |
Filesystem-first agent serving and cron schedules |
| OpenTelemetry | Cargo feature telemetry |
OTLP trace export; normal tracing remains available without it |
| Native SDKs | Separate packages | N-API Node.js and PyO3 Python bindings over the Core runtime |
| Terminal product | Separate A3S CLI | Streaming TUI, editors, account models, effort profiles, research, assets, and optional A3S OS views |
Feature availability does not bypass policy. Auto-save, automatic compaction,
goals, automatic delegation, security providers, human approval, trajectory
recording, and graph integration run only when a host configures them. The
dynamic_workflow tool is not registered in a plain Core session.
brew install A3S-Lab/tap/a3s
# or install from crates.io
cargo install a3s
a3s codeRun the TUI from the workspace the agent should inspect. Resume a saved session
with a3s code resume or a3s code resume <session-id>.
cargo add a3s-code-core
cargo add tokio --features macros,rt-multi-threadUse ACL configuration and keep credentials in environment variables:
default_model = "anthropic/claude-sonnet-4-20250514"
providers "anthropic" {
api_key = env("ANTHROPIC_API_KEY")
models "claude-sonnet-4-20250514" {
name = "Claude Sonnet"
tool_call = true
limit = {
context = 200000
output = 8192
}
}
}
storage_backend = "file"
sessions_dir = ".a3s/sessions"
memory_dir = ".a3s/memory"
skill_dirs = [".a3s/skills"]
agent_dirs = [".a3s/agents"]
Agent::new accepts either an ACL file path or inline ACL. Do not commit real
API keys, access tokens, private endpoints, or tenant identifiers.
use a3s_code_core::{Agent, PlanningMode, SessionOptions};
# async fn run() -> a3s_code_core::Result<()> {
let agent = Agent::new("agent.acl").await?;
let options = SessionOptions::new()
.with_planning_mode(PlanningMode::Auto)
.with_tool_timeout(120_000)
.with_auto_compact(true)
.with_max_context_tokens(200_000)
.with_auto_compact_threshold(0.8);
let session = agent
.session_builder("/path/to/workspace")
.options(options)
.build()
.await?;
let result = session.send("Explain the test strategy.", None).await?;
println!("{}", result.text);
# Ok(())
# }SessionBuilder::build is the primary construction path. It resolves merged
configuration and initializes filesystem stores, queues, trajectories, and MCP
sources asynchronously. Synchronous constructors remain compatibility APIs for
already initialized resources and never start or block a Tokio runtime.
AgentReleaseManifest admits the versioned .a3s/asset.acl contract, returns
schema-aware canonical ACL and its SHA-256 identity, and verifies an
AgentReleaseCompatibility before activation. Secret declarations are typed
injection slots only; values and external secret identifiers remain outside
the release document.
This API does not build or run the declared OCI artifact and does not implement its readiness, liveness, or shutdown behavior. See the Agent Release Contract for the complete v1 schema, compatibility policy, security boundary, and fixture status.
A session owns conversation history, workspace services, tool registrations, context providers, policies, stores, and active child work. The runtime can:
- create sessions with generated or host-supplied identities;
- resume complete snapshots from a
SessionStore; - atomically replace an idle persisted session with new runtime options;
- list and close live sessions owned by an
Agent; - cancel and settle an active operation before safely reusing its session;
- add, replace, list, and remove lifecycle-owned Skills while restoring an exactly shadowed registration on removal;
- add and remove session-local MCP servers without disturbing inherited or later host-owned tools;
- save, cancel, or close without abandoning active child work; and
- inspect runs, paginated run events, active tools, tasks, and verification.
Only one transcript-affecting operation may run at a time. Send, stream,
attachment requests, slash commands, and run resumption fail fast with
CodeError::SessionBusy when another such operation is active. Direct trusted
host tool calls use a separate control-plane path.
Core streams AgentEvent values. SDK live streams and persisted-run replay
project them through EventEnvelopeV1: a stable version, event type, complete
payload, and optional metadata. The protocol covers text and reasoning, tools,
planning, tasks, memory, compaction, budgets, verification, and terminal state.
SDKs preserve future event names and payloads for older clients.
CodeConfig is the typed source of truth for providers, models, stores, memory,
queues, search, agents, skills, MCP, and execution limits. Hosts that provide a
config editor can call rewrite_acl_sections to replace selected top-level ACL
sections while preserving unrelated blocks, unknown fields, external comments,
and raw expressions such as env("TOKEN").
Tools are registered only when the selected workspace exposes the capability
they require. A model never receives a local bash or git definition from an
object-only backend that cannot execute it.
| Concern | Tools | Behavior |
|---|---|---|
| Files and directories | read, write, edit, patch, ls |
Ranged reads, resumable writes, compare-and-swap edits, strict unified patches, and bounded listings |
| Workspace search | glob, grep |
Bounded matching with explicit result metadata and continuation |
| Code Intelligence | code_symbols, code_navigation, code_diagnostics |
Saved-file semantic metadata and locations with bounded results; source retrieval and mutation stay in the existing file tools |
| Commands and source control | bash, git |
Bounded output, cancellation, process-group termination on Unix, and typed Git operations |
| Web evidence | web_search, web_fetch |
Ranked multi-engine search with structured engine failures, policy-driven fallback, optional native AnySearch and Tavily providers, normalized sources, semantic <main> extraction with <body> fallback, SSRF protections, and bounded pages |
| Structured output | generate_object |
Schema-constrained model generation with validation and repair |
| Composition | batch, program |
Safe batch scheduling and sandboxed JavaScript programmatic tool calling |
| Delegation | task, parallel_task |
Foreground/background workers, bounded parallelism, partial results, and task tracking |
| Skills | Skill, search_skills |
Filesystem or inline skill discovery and execution with optional tool restrictions |
| MCP | mcp__<server>__<tool> |
Namespaced tools owned by their source manager |
| Dynamic workflows | dynamic_workflow |
Explicitly registered A3S Flow-backed, replayable per-turn workflows |
Without an explicit request or SearchConfig engine selection, web_search
uses DuckDuckGo and Wikipedia; AnySearch is not enabled by default. Configure
the search.engine block in config.acl to replace that default selection,
including an explicit anysearch { enabled = true } entry when desired. Set
ANYSEARCH_API_KEY to authenticate it. When selected engines fail or return no
usable result, the tool uses untried HTTP engines within the original timeout
budget and reports the degradation through structured metadata and a visible
notice.
Standalone greetings are conversational turns: the model receives no tool definitions and a friendly response is not converted into a synthetic continuation. A greeting that also asks for work keeps the normal tool surface.
The built-in skill registry starts empty; skills come from configured
directories, AgentDir, inline host input, or live registration. The
model-visible program tool executes JavaScript in QuickJS, not arbitrary
Python or a shell-script catalog.
Hosts can attach a BashSandbox through SessionOptions::with_sandbox_handle.
The extended execution request preserves the command, guest workspace, timeout,
stream observer, and explicit command environment; existing implementations
remain compatible through exec_command.
SrtBashSandbox is the fail-closed local adapter. It denies command network
egress, local binding, and Unix sockets; limits writes to the active workspace
and a private per-run scratch directory; protects repository and agent-control
metadata; blocks common credential reads; and scrubs ambient secrets and
language/bootstrap injection variables. It keeps stdout and stderr distinct
under one global capture limit. Its deadline covers output draining and the
child's complete lifetime, including a process that closes both streams before
it exits; timeout or cancellation terminates the Unix process group. It never
searches PATH for a sandbox runtime and never falls back to the host runner
when its explicitly provisioned runtime is missing or fails. Write-deny paths
already covered by a protected ancestor are collapsed before SRT startup,
while more-specific credential read denies remain intact. Workspace policy
scans treat an entry removed concurrently after enumeration as absent, but
permission and other I/O failures remain fatal. Unix wrapper temporary files
are pinned to the same private per-run scratch directory so a lifecycle host
can pass large native sandbox policies by file. The embedding host remains
responsible for choosing whether an unavailable sandbox causes an interactive
escalation or a deterministic denial.
Shell isolation does not automatically govern in-process workspace tools.
Interactive hosts should construct LocalWorkspaceBackend or
ManifestWorkspaceBackend with
LocalWorkspaceAccessPolicy::CredentialBoundary. That opt-in applies the
credential boundary to direct reads, range reads, writes, and both indexed and
fallback grep. Directory grep omits denied candidates, explicit sensitive
targets fail closed, source-tree multi-link files are rejected, and ordinary
package-store hardlinks remain usable unless they alias a discovered
credential inode. Guarded local Git diff enumerates changed paths with Git's
NUL-delimited format and regenerates output only for allowed paths; option-like
revision input cannot become a Git flag, and displayed remote URLs omit
embedded HTTP credentials and query tokens.
Hosts use from_verified_npm_with_node when a lifecycle owner supplies exact
SRT and Node paths. The verified constructor requires the expected npm package
identity and a tested SRT version; new likewise requires an explicit path for
an intentionally supplied custom adapter. The A3S CLI uses the verified
exact-path form after validating and, when policy allows, preparing its
user-wide managed installation; Core does not install host software.
This adapter is a low-latency local enforcement provider, not the stack-wide
workload contract. Code owns agent permission and escalation policy, A3S
Runtime owns provider-neutral Task and Service lifecycle and placement, and A3S
Box owns OCI and stronger-isolation workloads. Replacing the CLI's transitional
npm bootstrap with an A3S-signed sandbox artifact does not change the
BashSandbox contract.
Long-running hosts can call AgentSession::add_skill, remove_skill, and
skill_names without rebuilding the session. The model-visible Skill catalog
reads the same live registry, so a successful mutation is visible on the next
turn. Live registrations use pointer identity as their ownership token: an
upgrade preserves the original shadow chain, and removal never deletes a Skill
installed later by another host.
Local hosts can attach native Code Intelligence with
WorkspaceServices::local_with_code_intelligence or the shared-backend
variant. The provider reuses the existing workspace manifest, filesystem,
path resolver, cancellation, and tool policy. It does not create a competing
file index, search implementation, editing path, memory store, or MCP server.
The initial profiles require rust-analyzer for Rust and
typescript-language-server --stdio for TypeScript and JavaScript. Install the
executables before launching the host:
rustup component add rust-analyzer
npm install --global typescript typescript-language-serverQueries use saved files only. Public lines and characters are zero-based, and
characters count UTF-16 code units. Document results include the saved-content
revision and hash plus a stale flag when the file changes while a query is in
flight. The first navigation request for a saved revision includes a bounded,
cancellable stabilization pass so a protocol-ready but still-indexing server
does not leak a cold partial result. The semantic tools return metadata and
workspace-relative locations; agents continue to use read, grep, edit,
and patch for source text and mutations.
See the Code Intelligence design for the capability boundary, shared runtime architecture, lifecycle, and verification plan.
Every invocation carries declared ToolCapabilities, including read-only,
idempotent, resumable, cancellation-safe, paginated, output kind, and parallel
limits. Model, nested-program, and session calls validate JSON arguments before
permission prompts or side effects.
batch runs children concurrently only when every call declares safe
read-only parallel behavior; mutations and unknown tools are serialized.
Segmented writes require the expected UTF-8 byte offset, so retries are
idempotent and stale appends fail. Patch hunks validate positions, counts,
context, removals, whitespace, and line endings before one compare-and-swap
write; fuzzy application is intentionally rejected.
An optional session queue routes agent tool work through the Query and Execute lanes with bounded concurrency, handler modes, retry, DLQ, metrics, alerts, rate limits, and per-lane timeouts. Control and Generate remain reserved lane types; conversation runs use a separate single-flight admission guard, so lane priority orders pending work but does not interrupt an active model future.
Observations are bounded at their source. Reads, listings, globs, Git results, and fetched pages expose offsets or cursors. Large tool output and file changes move into bounded artifacts with previews, exact sizes, and hashes. Tool and model deadlines propagate cancellation; on Unix, shell cancellation terminates the process group rather than only its parent.
Optional permission policies resolve deny, allow, ask, and default behavior.
Interactive Code hosts can additionally share InteractiveToolGuardrail, a
conservative argument-aware classifier that quietly permits a narrow read-only
subset, asks for ordinary side effects, denies workspace escapes and catastrophic
shell operations, and keeps a non-bypassable safety floor in streamlined modes.
Its explainable assessment API classifies each invocation as routine, bounded,
high, or critical; records capability, target, impact, reversibility, environment,
and stable reason codes; and routes the result to allow, human confirmation,
constrained review, or deterministic denial. Nested batches inherit their
highest child risk, while the legacy allow/ask/deny projection remains available
to existing HITL integrations.
Confirmation managers, hooks, budget guards, security providers, stream
sanitization, retention limits, circuit breakers, duplicate-call guards, and
no-progress detection compose around the same invocation path. Trusted direct
host calls skip model-facing permission prompts, so an embedding application
must authorize its callers. Only built-in control-plane orchestrators may carry
that authority into host-selected nested calls. A public custom tool's
InvocationRuntime, and every model sub-run created from a direct host context,
produce ordinary governed invocations instead of inheriting ambient trust.
Delegated tasks, workflow steps, and Skill child runs retain the parent sandbox
and intersect their local permission policy with the parent checker. A
child-local Ask follows that worker's auto_approve, deny_on_ask, or
inherit_parent policy, while an Ask introduced by the parent remains under
the parent confirmation provider. If both scopes ask, both remain effective and
the same provider is de-duplicated. Tool-owned confirmation after both policies
allow is also governed by the parent, so a child-local auto-approver cannot
waive a host escalation boundary. Cancellation and timeout settle only the
matching confirmation ID; unrelated concurrent prompts remain pending.
The default LocalWorkspaceBackend provides filesystem, search, command, and
Git services beneath a workspace root. ManifestWorkspaceBackend adds live
file status and recent-file tracking. RemoteGitBackend exposes remote Git
operations, and the s3 Cargo feature provides an S3-compatible object backend
for file tools.
Applications can implement typed WorkspaceFileSystem, WorkspaceSearch,
WorkspaceCommandRunner, WorkspaceGit, path resolution, stash, and worktree
contracts. WorkspaceServicesBuilder combines only the services a backend can
actually support.
ContextAssembler ranks and budgets items from static, filesystem, recent-file,
ripgrep, memory, and host-defined ContextProvider implementations. Project
instructions and skill catalogs join them during session prompt assembly.
SystemPromptSlots keeps role, rules, workspace instructions, and host guidance
separate. Filesystem and recent-file providers are installed only when selected.
Automatic compaction is opt-in. It monitors estimated or provider-reported usage against the configured model window, bounds oversized tool results, summarizes older history, and targets a safe post-compaction watermark after subtracting the fixed system-prompt and tool-schema cost. Recent raw messages are retained only within that token budget, while the latest user instruction and unresolved tool calls remain intact. The policy re-arms after success so a long session can compact repeatedly. The summary is treated as untrusted transcript data, not as a new source of executable instructions.
The memory layer separates working, short-term, and durable long-term state. It supports relevance and recency scoring, typed memories, relations, successful and failed pattern capture, file or custom stores, optional pruning, and context injection. By default, every completed non-empty session turn is sent to the active model for a semantic value judgment; the model returns an empty set when nothing is reusable. Automatic extraction writes only validated semantic or procedural memories and never mechanically persists tool results or turn history. Streaming turns register extraction before publishing their final event, run through a FIFO background queue, and graceful session close drains already-accepted work for a bounded period. Stored extractor metadata records source, confidence, scope, reason, workspace, session, and schema version. Hosts can disable extraction or tune its input and output bounds.
Core includes clients for Anthropic, Zhipu, and OpenAI-compatible APIs, plus the
LlmClient trait for host adapters. The common model contract normalizes text,
reasoning, tool calls, usage, images, retries, cancellation, and streaming where
the provider supports them. Structured generation uses native response formats
when available and a schema-validated prompt fallback otherwise.
Anthropic and OpenAI-compatible SSE transports decode UTF-8 incrementally across raw network chunks before splitting events. A multibyte character may therefore cross any transport boundary without being replaced or corrupting the event payload.
LlmClient::model_generation_concurrency is the typed admission contract for
structured model transactions. The default is conservative single-flight;
providers may explicitly report a larger finite bound.
Each AgentSession owns one cancellation-safe gate and reuses it across
conversation loops, host-direct calls, and rebuilt direct-tool runtimes.
generate_object waits on that gate before starting its active deadline,
retains the permit through schema repairs, and reports the queue wait
separately in metadata. DynamicWorkflowRuntime recognizes the exact
generate_object Flow step identity and acquires the same capacity before
starting its bounded program VM. The nested generation reuses that one-shot
identity-checked permit, so neither the generation deadline nor the Program
deadline includes admission queue time, parallel nested calls cannot reuse one
reservation, and concurrent host-direct workflows cannot create independent
provider gates.
If an established response stream closes before its final response, Core
restarts the same LLM turn with the same message snapshot up to ten times. The
delay grows exponentially from one second and is capped at thirty seconds, with
jitter. Core re-emits TurnStart with the same turn number before each wait so
stream consumers can roll back provisional deltas and tool drafts in place;
only the successful assistant response is committed. Cancellation interrupts
the wait immediately, and setup/status retries remain owned by the provider
transport rather than nesting another turn-level retry loop.
MCP connections support stdio, HTTP SSE, streamable HTTP, and OAuth client credentials. Global managers can seed new sessions and refresh cached tools; session managers can connect, disconnect, and live-add or remove isolated servers. Tools remain source qualified so separate servers do not silently share ownership. A local stdio server leads a dedicated Unix process group. Transport close or drop stops its pipe tasks, fails pending requests, reaps the direct child, and terminates descendants; stderr is drained independently so a diagnostic-heavy server cannot block the protocol pipe. This lifecycle containment does not make the configured server an untrusted sandbox.
Hosts can add or replace a Skill in a running session with
AgentSession::add_skill, inspect the effective names with skill_names, and
remove host-owned entries with remove_skill. The search tools and
model-visible Skill catalog observe the live registry on the next query or
turn. Removing a live Skill restores the session definition it shadowed;
closing the session removes all host-owned entries. Delegated child runs share
that same effective registry, so a capability attached after session creation
does not disappear at the worker boundary.
The browser search runtime exposes read-only status separately from explicit install, update, and repair operations. Inspecting runtime status never performs an installation as a side effect.
Planning has three states: automatic, forced, and disabled. PrePlanning can
block or modify planner input, while PostPlanning reports the outcome. Streams
expose planning, task-snapshot, step, and optional goal-progress events so a
host can render and replay the same lifecycle it supervises.
Goal tracking and automatic delegation are opt-in. Bounded continuation is
enabled by default and can be tuned or disabled. Manual task and
parallel_task tools remain independently configurable, allowing a host to
expose deliberate delegation without enabling heuristic fan-out.
AgentDefinition loads reusable roles from Markdown or YAML. Explicit
WorkerAgentSpec values describe reproducible disposable workers. Delegated
tasks inherit bounded parent policy, can run foreground or background, can
request structured output, record source anchors, expose progress snapshots,
and accept targeted cancellation.
The orchestration module provides sequential pipelines, bounded parallel steps, resumable parallel execution, loops, workflow events, token and step budgets, and checkpoints. Completed steps can be restored from a checkpoint instead of repeating successful model work after a restart.
program runs a bounded JavaScript module in QuickJS with a host-provided
ctx surface. Time, nested tool calls, output bytes, recursion, and allowed
tools are limited. Auditable workflow source is capped at 192 KiB. Recursive
program, dynamic_workflow, and
parallel_task calls are excluded from its normal allow-list.
DynamicWorkflowRuntime is a separate, explicit capability. A sandboxed
program returns commands such as complete, fail, schedule_step, or
schedule_steps; A3S Flow records workflow and step history, while the host
executes allowed steps. A plain Core session must call
session.register_dynamic_workflow_runtime() before invoking the
dynamic_workflow tool.
AgentDir keeps an agent's instructions, ACL, skills, tool specifications, and
schedules in reviewable files:
agent-dir/
├── instructions.md
├── agent.acl
├── skills/
├── tools/
└── schedules/
Tool specifications can connect MCP servers or bounded PTC scripts. With the
serve feature, a host can serve an agent directory and run cron schedules.
Files do not bypass workspace, permission, confirmation, or verification policy.
SessionSnapshotV1 commits the session, artifacts, trace events, run records,
verification reports, and subagent tasks as one generation when the selected
store advertises atomic snapshots. The built-in memory and file stores provide
that guarantee; custom stores declare their own capabilities. Loop and workflow
checkpoints use dedicated store APIs.
Runs expose status, active tools, ordered event replay, exclusive pagination cursors, and retention-gap detection. File persistence uses temporary files and atomic replacement. Artifact stores bound both item count and bytes, while verification reports keep claims and evidence separate from final prose.
tracing works in the baseline build. Enable telemetry for OpenTelemetry OTLP
trace export. Training-oriented hosts can opt into JSONL RL trajectories
covering prompts, model turns, tools, observations, usage, and termination
reasons, and can request token log probabilities from compatible providers.
The state graph is a complementary coordination runtime, not hidden mutable state inside every session. Applications opt into it when several agents, behaviors, or workflow decisions need a shared auditable model.
external or agent event
│
▼
hash-linked GraphEventRecord log
│ strict projection
▼
typed objects + typed relations
│ matching behaviors
▼
optimistic GraphPatch values
│ version checks
▼
new graph version or explicit rejection
GraphRuntime supports typed objects and relations, event filters, behaviors,
per-event limits, optimistic object and relation versions,
correlation and causation metadata, and custom external-event projection.
Records carry previous-record and resulting-state hashes, making semantic or
ordering changes detectable during strict replay.
A runtime can fork at an event point and produce a structural diff without
mutating its parent. MemoryGraphEventStore and FileGraphEventStore persist
branches; capable stores publish extending generations with compare-and-swap
head checks. The A3S Flow bridge projects workflow state into the graph and
uses memory or file decision ledgers to claim, renew, complete, and recover
durable decisions with at-least-once dispatch. Sinks must be idempotent by
decision ID.
Node.js and Python expose StateGraphRuntime operations for event emission,
patching, restore through strict replay, fork, and JSON diff exchange.
The A3S CLI builds the a3s code product on
Core and the shared A3S TUI framework.
| Area | TUI capability |
|---|---|
| Coding workspace | Streaming text, reasoning, tool cards, approvals, task progress, image/file input, session resume/fork, and bounded Markdown/diff rendering |
| Workspace UI | Full-screen /ide file browser/editor with saved-file symbols, semantic navigation, and diagnostics, plus a /config ACL editor with shared workspace and permission boundaries |
| Models and effort | ACL providers, signed-in Claude Code, Codex, and WorkBuddy accounts, host-provided models, and effort profiles from low through ultracode |
| Long sessions | A single footer context meter, repeated model-aware compaction, past-session search, durable memory, daily consolidation, and local knowledge |
| Orchestration | Planning, goals, tracked child tasks, parallel work, Ultracode workflows, bounded DeepResearch, and persistent maker/checker loops |
| Local assets | Filesystem-first agents, MCP servers, skills, workflows, and knowledge packages with optional publishing and deployment |
| Optional host integration | A3S OS login, runtime tools, activity, progressive responses, and trusted RemoteUI view links when configured |
Account-backed Claude Code, Codex, and WorkBuddy clients are CLI adapters, not Core provider defaults. Local chat, tools, skills, MCP, memory, delegation, and dynamic workflows remain usable without an A3S OS account.
| Language | Package | Runtime surface |
|---|---|---|
| Rust | a3s-code-core |
Complete Core API and extension traits |
| Node.js | @a3s-lab/code |
N-API bindings with async lifecycle, streaming, tools, orchestration, stores, MCP, and state graph |
| Python | a3s-code |
PyO3/bootstrap package with sync and async APIs, streaming, tools, orchestration, stores, MCP, and state graph |
Both native SDK crates enable the Core s3 and serve features. Typed option
objects carry memory, session, workspace, and security extensions, while the
alignment check documents intentional language-specific omissions.
Rust host / Node SDK / Python SDK / a3s code TUI
│
Agent
│
AgentSession
┌────────────────┼────────────────┐
│ │ │
context + memory model adapters governed tools
│ │ │
└────────────────┼────────────────┘
│
events + runs + traces + artifacts + snapshots
│
optional StateGraph / Flow bridge
The public extension boundaries are LlmClient, ContextProvider,
MemoryStore, SessionStore, workspace service traits, permissions,
confirmation, hooks, security, budget guards, tools, MCP transports, and graph
stores. Core owns lifecycle and ordering; hosts own product UI, identity,
credential access, and deployment policy.
Source is split by concern under agent_api/, tools/, workspace/,
context/, llm/, mcp/, orchestration/, store/, and state_graph/.
Node and Python bindings remain separate crates over the same Rust core.
Run checks from the A3S Code repository directory:
cargo fmt --all -- --check
cargo test -p a3s-code-core
cargo test -p a3s-code-core --all-features
cargo clippy -p a3s-code-core --all-targets --all-features -- -D warnings
node scripts/sdk_api_alignment_check.mjsReal-provider, browser-runtime, and S3 tests are intentionally ignored unless their credentials or external services are configured. Run only the focused ignored test whose prerequisites are available; the normal suite is hermetic.
See the Node SDK, Python SDK, and Changelog for surface-specific details and release history.
MIT