Skip to content
Radiant LabsRadiant Labs

Advanced topics

APIs

Register capabilities during setup and expose runtime services to application code.

An API is a typed service registered on the Server. Plugins use APIs to cooperate during setup; application code can also use APIs after startup. For example, SessionsAPI creates sessions and processes turns at runtime. An API is not restricted to the build phase.

Need Use
Read shared configuration in a system Res<T> with a global resource
Mutate session state in a system ResMut<T> with a local resource
Register routes, serializers or agents from a plugin The corresponding API
Execute a turn from a CLI or HTTP handler SessionsAPI

API is a marker trait requiring Send + Sync + 'static. Register one with server.insert_api(value) and look it up with server.api::<T>(). The lookup returns Option<&T>; APIs that support registration through &self use interior mutability internally.

use polaris_ai::system::{api::API, server::Server};
struct FeatureRegistry;
impl API for FeatureRegistry {}
let mut server = Server::new();
server.insert_api(FeatureRegistry);
assert!(server.api::<FeatureRegistry>().is_some());

Current plugins describe their provided and consumed capabilities using PluginAccess and versioned Contract types. Prefer typed Requires<T> or Extends<T> parameters with #[plugin] when writing a consumer. Use dependencies() for ordering that is not expressed by a capability, including relationships used only in ready().

Do not copy the implementation of a core plugin into your app. Register the provided plugin, then contribute through its public API. See Plugins for lifecycle and capability contracts.

  • SessionsAPI: register agents, create contexts and sessions, execute turns, checkpoint and persist state.
  • PersistenceAPI: register serializers for local resource types before session setup captures them.
  • HttpRouter: add routes directly or defer route construction until other APIs are available.
  • HooksAPI: register execution observers and resource-providing hooks.
  • MiddlewareAPI: wrap graph execution units with before-and-after logic.

ToolRegistry and ModelRegistry use a related two-phase pattern: consumers contribute during build, then the registries become global resources for executing systems. They are not interchangeable with server.api::<T>() lookups.

Await server.finish() before creating contexts or serving requests. Clone a cloneable API when a long-lived handler needs ownership rather than borrowing the server.

use polaris_ai::sessions::{AgentTypeId, SessionId, SessionsAPI};
// After server.finish().await? and registration of an agent named "my-agent":
let sessions = server.api::<SessionsAPI>().expect("SessionsPlugin required").clone();
let id = SessionId::new();
let agent_type = AgentTypeId::from_name("my-agent");
sessions.create_session(sessions.create_context(), &id, &agent_type)?;
let result = sessions.process_turn(&id).await?;

These are application fragments inside an async function returning Result; follow Sessions and persistence for the complete setup.