leviath_runtime/lib.rs
1//! # Leviath Runtime
2//!
3//! ECS-based agent execution engine using bevy_ecs.
4//!
5//! The runtime manages agent lifecycle, context window management, task scheduling,
6//! and inference execution through a game-loop-inspired architecture where agents
7//! are entities and their behaviors are systems.
8//!
9//! ## Embedding
10//!
11//! [`AgentWorld`] is the front door for running agents inside your own
12//! application - no `lev` CLI, daemon, or config file. Build a world from
13//! plain values, spawn an agent, and drive the event stream:
14//!
15//! ```no_run
16//! use leviath_runtime::{AgentWorld, BlueprintSource, ProviderCreds, SpawnSpec, WorldEvent};
17//!
18//! # async fn embed() -> Result<(), Box<dyn std::error::Error>> {
19//! let world = AgentWorld::builder()
20//! .provider(ProviderCreds {
21//! name: "anthropic".to_string(),
22//! api_key: std::env::var("ANTHROPIC_API_KEY").ok(),
23//! ..ProviderCreds::simple("anthropic")
24//! })
25//! .build()?;
26//!
27//! let mut events = world.events();
28//! let run = world
29//! .spawn(SpawnSpec::new(
30//! BlueprintSource::Path("coder.leviath".into()),
31//! "Build a CSV parser",
32//! std::env::current_dir()?,
33//! ))
34//! .await?;
35//!
36//! while let Some(event) = events.next().await {
37//! match event {
38//! WorldEvent::StageTransition { from, to, .. } => println!("{from} -> {to}"),
39//! WorldEvent::ToolCallStarted { tool, .. } => println!("running {tool}"),
40//! WorldEvent::Interaction { request, .. } => {
41//! // The agent asked a question: answer via world.answer(...).
42//! }
43//! WorldEvent::Completed { run_id, status, .. } if run_id == run.as_ref() => break,
44//! _ => {}
45//! }
46//! }
47//! world.shutdown().await;
48//! # Ok(())
49//! # }
50//! ```
51//!
52//! ## Stability layers
53//!
54//! - [`AgentWorld`] and the other [`embed`] types are the stable embedding
55//! surface.
56//! - [`WorldHost`] and [`PipelineWorld`] are the semi-stable machinery both
57//! the daemon and `AgentWorld` are built on; use them when you need your
58//! own assembly (custom spawners, hooks, tick control).
59//! - The raw ECS underneath ([`PipelineWorld::world_mut`]) is the unstable
60//! escape hatch: it tracks this crate's `bevy_ecs` version (re-exported as
61//! [`ecs`]) and carries no compatibility promise.
62
63// Public because [`tool_bridge::ToolJob`] carries a `CancelToken`, so anything
64// handing work to the tool lane needs to name the type.
65pub mod cancel;
66pub(crate) mod compaction_bridge;
67pub mod components;
68pub mod context_setup;
69pub(crate) mod context_tools;
70pub(crate) mod context_transform;
71#[cfg(feature = "control-socket")]
72pub mod control_socket;
73pub mod custom_region;
74pub mod dynamic_interaction;
75pub mod embed;
76pub mod fanout;
77pub(crate) mod gate_prompt;
78pub mod host;
79pub(crate) mod inference_bridge;
80pub mod inference_pool;
81pub mod inference_usage;
82pub mod interaction_hub;
83pub mod interaction_points;
84pub(crate) mod lane_supervisor;
85pub mod output_tool;
86pub mod persistence;
87pub(crate) mod persistence_bridge;
88pub mod pipeline;
89pub mod provider_creds;
90pub(crate) mod providers;
91pub(crate) mod repetition;
92pub mod restore;
93pub mod script_provider;
94pub mod taint;
95pub mod telemetry;
96pub(crate) mod tick_scope;
97pub mod title;
98pub(crate) mod title_bridge;
99pub mod tool_bridge;
100pub mod world;
101// test_support.rs gates itself with an inner `#![cfg(test)]` attribute, so no
102// `#[cfg(test)]` is needed here (adding one would trigger clippy's
103// `duplicated_attributes` lint under `-D warnings`).
104mod test_support;
105
106pub use components::{AgentState, AgentStatus, ContextWindow, ParentRef, SubAgentChildren};
107pub use embed::{
108 AgentWorld, AgentWorldBuilder, BasicToolService, BlueprintSource, EmbedError, EventStream,
109 RunId, SpawnSpec,
110};
111pub use fanout::{FanOutSpawner, FanOutSpawnerRes};
112pub use host::{ControlOp, SpawnArgs, WorldEvent, WorldHost};
113pub use inference_bridge::{
114 CAPACITY_BASE_DELAY_SECS, CAPACITY_MAX_DELAY_SECS, DEFAULT_RETRY_ATTEMPTS,
115 DEFAULT_RETRY_BASE_DELAY_MS, MAX_TOTAL_BACKOFF_SECS, RetryPolicy,
116};
117pub use inference_pool::{InferencePoolConfig, InferencePools};
118pub use interaction_hub::InteractionHub;
119pub use pipeline::{ModelDefaults, ResolvedStage, ToolService, is_stage_specific};
120pub use provider_creds::{ProviderCreds, build_provider_registry};
121pub use providers::ProviderRegistry;
122pub use taint::TaintGate;
123pub use tool_bridge::BoxedToolExec;
124pub use world::{PipelineWorld, TickOutcome};
125
126/// The name issue-facing docs use for the world's event enum; the same type
127/// as [`WorldEvent`].
128pub type AgentEvent = WorldEvent;
129
130/// The `bevy_ecs` version this runtime is built against, for code that
131/// reaches through [`PipelineWorld::world_mut`] into the raw ECS. Depending
132/// on this re-export (instead of your own `bevy_ecs`) keeps the versions
133/// aligned.
134pub use bevy_ecs as ecs;