Skip to content

apomesh-substrate

apomesh-substrate is the substrate runtime: the domain library whose functions take domain types and return domain types, so a transport handler (gRPC, REST) is a thin adapter around them. It combines the type-vocabulary foundation (apomesh-substrate-types — the closed enums, boundary types, and port traits) with the sibling implementation planes (catalog, state, LLM, sandbox, tools, net, and an optional MCP plane) and re-exports them module-for-module, so a consumer always reaches apomesh_substrate::<module>::<Type> rather than the plane crates directly. Touch it when substrate behaviour changes — routing, supervision, the session-strategy seam, the tenant boundary.

  • Layer: substrate core (the runtime facade). See Control & execution planes.
  • Depends on: apomesh-protocol (it owns the wire↔domain conversions), the apomesh-substrate-types vocabulary, and the implementation planes (apomesh-substrate-catalog, -state, -llm, -sandbox, -tools, -net, and -mcp behind the optional mcp feature).
  • Consumed by: the orchestrator, the worker, the REST API, SmartChat, the state-store adapters, the tool-runner, the auth-providers and config crates, and both verticals.
  • The wire↔domain conversions — the *::wire modules that map protocol’s prost types to and from the domain types (the orphan rule puts them here, not in the wire crate).
  • The VMAO coordinator and the SessionStrategy seam (vmao, coordinator) — the one-coordinator-per-session loop and the trait a vertical implements to specialize it.
  • Fleet routing and supervisionrouting (provider routing, placement, affinity) and supervisor (the cascade + SupervisorStrategy).
  • The runtime facade over the impl planes — curated pub use re-exports for tool, state_store, llm_provider, agent, agent_catalog, prompt, and skill; the implementation submodules stay private behind the facade.
  • The tenant boundary and credential resolutiontenant::TenantContext and auth, the entry every workflow authenticates against.

The vocabulary items below live in apomesh-substrate-types and are re-exported through this facade; the runtime items (routing, vmao, supervisor) are owned here.

  • tenant::TenantContext — the per-tenant boundary every workflow takes as its first input.
  • agent::AgentRef — the opaque, tenant-scoped agent identity; the substrate is its only constructor.
  • budget::Budget — the concentric-ring token/time/cost budget carried down the hierarchy.
  • LoopDefinition — how a vertical states its loop shape. This replaced the SessionStrategy trait, whose hook positions a vertical used to plug into: a shape is now a composition of a closed primitive set rather than an implementation of a fixed loop’s hooks, and it lives in apomesh-loops rather than here.
  • routing::ProviderRouter — provider routing (one route per dispatch, not per iteration).
  • state_store::StateStore — the persistence port; the sole path to durable state.
  • tool::Tool — the sandboxed tool port; every dispatch goes through ToolSandbox.
  • llm_provider::LLMProvider — the provider port; concrete impls live in the LLM plane.
  • supervisor — the parent-chain supervisor cascade and SupervisorStrategy.
  • apomesh-loops engine — the one-coordinator-per-session contract. It moved out of this crate into apomesh-loops, where one engine carries the contract’s provisions structurally for every definition it runs.

The facade is the contract: a consumer imports a plane type through apomesh_substrate::<module>, never from the plane crate directly.

// The runtime re-exports the -types vocabulary and the impl planes
// module-for-module — imports come from `apomesh_substrate`, not from the
// `apomesh-substrate-state` / `-types` crates behind it.
use apomesh_substrate::state_store::{InMemoryStateStore, SessionId, StateStore};
use apomesh_substrate::tenant::TenantContext;
fn store() -> impl StateStore {
InMemoryStateStore::default()
}