Skip to main content

bamboo_engine/runtime/
agent.rs

1//! Stable public API for the agent runtime.
2//!
3//! [`Agent`] wraps an [`AgentRuntime`] with method-based access and serves as
4//! the primary entry point for SDK consumers.
5
6use std::sync::Arc;
7
8use bamboo_agent_core::Session;
9
10use crate::runtime::{AgentRuntime, AgentRuntimeBuilder, ExecuteRequest};
11use bamboo_domain::RuntimeSessionPersistence;
12
13// ---------------------------------------------------------------------------
14// Agent — stable public object
15// ---------------------------------------------------------------------------
16
17/// Stable public entry point for agent execution.
18///
19/// Wraps an [`AgentRuntime`] and provides:
20/// - [`Agent::execute()`] — run the agent loop on a session
21/// - [`Agent::storage()`] — access the shared storage backend
22///
23/// Clone is cheap (inner is `Arc`).
24#[derive(Clone)]
25pub struct Agent {
26    runtime: Arc<AgentRuntime>,
27}
28
29impl Agent {
30    /// Wrap an existing [`AgentRuntime`] in an `Agent`.
31    pub fn from_runtime(runtime: Arc<AgentRuntime>) -> Self {
32        Agent { runtime }
33    }
34
35    /// Return a new builder.
36    pub fn builder() -> AgentBuilder {
37        AgentBuilder::new()
38    }
39
40    /// Execute the agent loop with the given request.
41    pub async fn execute(
42        &self,
43        session: &mut Session,
44        req: ExecuteRequest,
45    ) -> crate::runtime::runner::Result<()> {
46        self.runtime.execute(session, req).await
47    }
48
49    /// Access the shared storage backend.
50    pub fn storage(&self) -> &Arc<dyn bamboo_agent_core::storage::Storage> {
51        &self.runtime.storage
52    }
53
54    /// Access the runtime persistence adapter for non-authoritative saves.
55    pub fn persistence(&self) -> &Arc<dyn RuntimeSessionPersistence> {
56        &self.runtime.persistence
57    }
58
59    /// Access the runtime's default tool executor (the root/full tool surface
60    /// assembled at build time).
61    ///
62    /// Exposed so callers can compose additional one-off dispatches against the
63    /// SAME executor the loop itself uses — e.g. re-executing a single
64    /// previously-gated tool call after a permission approval — without forking
65    /// or reaching into `AgentLoopConfig` (which stays unconstructible outside
66    /// the engine). This is a read-only accessor alongside `storage()` /
67    /// `persistence()`; it does not touch the sealed loop config.
68    pub fn default_tools(&self) -> &Arc<dyn bamboo_agent_core::tools::ToolExecutor> {
69        &self.runtime.default_tools
70    }
71}
72
73// ---------------------------------------------------------------------------
74// AgentBuilder
75// ---------------------------------------------------------------------------
76
77/// Builder for [`Agent`].
78///
79/// Delegates to [`AgentRuntimeBuilder`] internally.
80pub struct AgentBuilder {
81    inner: AgentRuntimeBuilder,
82}
83
84impl AgentBuilder {
85    pub fn new() -> Self {
86        Self {
87            inner: AgentRuntimeBuilder::new(),
88        }
89    }
90
91    pub fn storage(mut self, v: Arc<dyn bamboo_agent_core::storage::Storage>) -> Self {
92        self.inner = self.inner.storage(v);
93        self
94    }
95
96    pub fn persistence(mut self, v: Arc<dyn RuntimeSessionPersistence>) -> Self {
97        self.inner = self.inner.persistence(v);
98        self
99    }
100
101    pub fn attachment_reader(
102        mut self,
103        v: Arc<dyn bamboo_agent_core::storage::AttachmentReader>,
104    ) -> Self {
105        self.inner = self.inner.attachment_reader(v);
106        self
107    }
108
109    pub fn skill_manager(mut self, v: Arc<bamboo_skills::SkillManager>) -> Self {
110        self.inner = self.inner.skill_manager(v);
111        self
112    }
113
114    pub fn metrics_collector(mut self, v: bamboo_metrics::MetricsCollector) -> Self {
115        self.inner = self.inner.metrics_collector(v);
116        self
117    }
118
119    pub fn config(mut self, v: Arc<tokio::sync::RwLock<bamboo_llm::Config>>) -> Self {
120        self.inner = self.inner.config(v);
121        self
122    }
123
124    pub fn provider(mut self, v: Arc<dyn bamboo_llm::LLMProvider>) -> Self {
125        self.inner = self.inner.provider(v);
126        self
127    }
128
129    pub fn default_tools(mut self, v: Arc<dyn bamboo_agent_core::tools::ToolExecutor>) -> Self {
130        self.inner = self.inner.default_tools(v);
131        self
132    }
133
134    pub fn build(self) -> Result<Agent, &'static str> {
135        let runtime = self.inner.build()?;
136        Ok(Agent {
137            runtime: Arc::new(runtime),
138        })
139    }
140}
141
142impl Default for AgentBuilder {
143    fn default() -> Self {
144        Self::new()
145    }
146}