agents-kit
This crate is in early development. Backwards compatibility is not guaranteed
until 1.0.0; pin exact versions and review the
release notes before upgrading.
agents-kit provides one portable runtime hierarchy over Codex App Server,
OpenCode Server, and Custom provider-backed agents:
Agent -> Workspace -> Conversation
Each supplied opaque handle implements its public backend trait as a closed
Codex/OpenCode/Custom dispatcher. Callers use their concrete AgentBackend
hierarchy directly or compose matching caller-owned exhaustive enums; Workspace
and Conversation remain parent-associated child types.
Construction
Managed runtimes start with required durable storage:
use ;
use StateStoreBackend;
async
Reopen uses AgentBuilder::reopen(config, storage, agent_id) or its typed
native counterpart. Custom callers resupply a direct
P: providers_kit::ProviderBackend implementation; all callers resupply their
already-built T: tools_kit::ToolsetBackend implementations, direct StateStoreBackend
implementation, and optional direct DatabaseBackend implementation.
agents-kit preserves S, D, P, and T statically and never persists lower
credentials or reconstructs integrations through factories.
Examples and real persistence tests use Lance: LanceStateStoreConfig::memory()
for process-local state, LanceStateStoreConfig::directory(path) for durable
state, and LanceConfig::embedded_path(path) for managed knowledge. Alternative
Storage implementations require caller-enabled Storage features; Agent does
not enable them or select a backend on the caller’s behalf.
Concrete Provider, Toolset, and storage implementations are the primary composition
path. A caller may define its own exhaustive Provider/Model/Session, Toolset/Handler, or storage
enum hierarchy when runtime selection is needed; agents-kit does not require a
wrapper or normalize those implementations into supplied Kit handles.
Native Codex/OpenCode construction selects that enum only as a static type
with AgentBuilder::create_for_backends::<FleetProvider, FleetTools>(...) or the matching
reopen method. Custom installs the real value with
AgentBuilder::create_for_backends::<FleetProvider, FleetTools>(...).with_provider(FleetProvider::Custom(...)). Both
paths produce the same Agent<S, D, FleetProvider, FleetTools> type without making native
runtimes own provider lifecycle.
Each with_toolset(T) appends to the fixed inventory; Provider and Database
changes preserve every accepted tool. Neither T nor T::Handler requires
Clone. Caller-built shell tools carry explicit cwd and process policy through
their ordinary tool inputs; Agent has no implicit shell configuration.
Public Modules
config— backend and Custom runtime constructionidentity— typed Agent, Workspace, Conversation, and Notification idsworkspace— context, defaults, revisions, and update requestsconversation— conversation creation and snapshotsprompt— foreground prompt requests, transient output streams, and resultsnotification— durable delivery and interaction resolutionmodel— portable model selection and inventorytool— source-neutral tool selection and inventoryknowledge— source, scope, policy, and ingestion inputserror— closed failure classifications, operation/phase context, and safe evidence
Primary handles, backend traits, AgentBuilder, AgentStorage, and KitError
remain at the crate root.
Boundaries
- Custom retains the caller's
Pand callsP::Model::generatefor unary delivery orgenerate_streamfor incremental delivery through the same multi-turn prompt/tool owner. Session remains the Model-associated provider child and is not used or parameterized by Agent. The Model's associated continuation stays typed inside one active prompt; durable history is provider-neutral and reopen reconstructs messages without it. - Tool execution stays in
tools-kit. - Control-plane state stays in the caller-supplied
storage_kit::StateStoreBackendimplementation. - Managed knowledge is private agent behavior over a caller-supplied
storage_kit::DatabaseBackendimplementation. - Codex/OpenCode protocol values and provider envelopes never become public agent types.
There are no public factories, conformance runners, KnowledgeBase backend, LoopDriver integration, Agent normalization constructors, compatibility API, or runtime trait objects.
Custom accepts final prompt success only from a valid completed model turn. Provider failure, truncation, filtering, paused continuation, and malformed completion remain errors; partial output never becomes a successful durable answer. A caller ToolHandler must return actual content or structured content, including for model-visible failures. Empty results are rejected instead of receiving Kit-authored replacement text.
Documentation
Inspecting failures
KitError is an opaque, cloneable error. Match error.kind() for broad
control flow and inspect detail(), context(), and http_status() for the
reason and detection phase. cause() contains normalized Agent errors;
supplementary() retains cleanup failures without replacing the primary.
These fields do not establish retry safety or durable cancellation.
use ;
let error = integration
.with_context
.with_detail
.with_http_status;
assert_eq!;
assert_eq!;
Caller implementations must supply already-redacted messages. Supplied
implementations never publish native prose through errors. Diagnostic trees
are bounded; check diagnostics_truncated() before treating retained evidence
as complete. See the error contract. Codex prompt records use
version 4; older records are rejected unchanged and are not migrated.
Direct public-trait tests
Run bash scripts/check_mock_contracts.sh --crate agents-kit from the workspace
root for the credential-free mock lane. The workspace primary CI entrypoint is
bash scripts/check_ci.sh. See mock testing for
targets, evidence, runtime qualification, and the separate release/live gates.