1pub use hook::Hook;
8pub use memory::{InMemory, Memory, NoEmbedder};
9pub use wcore::AgentConfig;
10pub use wcore::model::{Message, Request, Response, Role, StreamChunk, Tool};
11
12use anyhow::Result;
13use compact_str::CompactString;
14use std::{collections::BTreeMap, future::Future, sync::Arc};
15use tokio::sync::RwLock;
16
17pub mod hook;
18
19pub mod prelude {
21 pub use crate::{
22 AgentConfig, Hook, InMemory, Message, Request, Response, Role, Runtime, StreamChunk, Tool,
23 };
24}
25
26pub type Handler =
28 Arc<dyn Fn(String) -> std::pin::Pin<Box<dyn Future<Output = String> + Send>> + Send + Sync>;
29
30pub struct AgentDispatcher<'a, H: Hook> {
32 pub hook: &'a H,
34 pub agent: &'a str,
36}
37
38impl<H: Hook> wcore::Dispatcher for AgentDispatcher<'_, H> {
39 fn dispatch(&self, calls: &[(&str, &str)]) -> impl Future<Output = Vec<Result<String>>> + Send {
40 self.hook.dispatch(self.agent, calls)
41 }
42
43 fn tools(&self) -> Vec<Tool> {
44 self.hook.tools(self.agent)
45 }
46}
47
48pub struct Runtime<H: Hook> {
54 hook: Arc<H>,
55 agents: RwLock<BTreeMap<CompactString, wcore::Agent<H::Model>>>,
56}
57
58impl<H: Hook + 'static> Runtime<H> {
59 pub fn new(hook: Arc<H>) -> Self {
61 Self {
62 hook,
63 agents: RwLock::new(BTreeMap::new()),
64 }
65 }
66
67 pub fn hook(&self) -> &H {
69 &self.hook
70 }
71
72 pub async fn add_agent(&self, config: AgentConfig) {
76 let name = config.name.clone();
77 let agent = wcore::AgentBuilder::new(self.hook.model().clone())
78 .config(config)
79 .build();
80 self.agents.write().await.insert(name, agent);
81 }
82
83 pub async fn agent(&self, name: &str) -> Option<AgentConfig> {
85 self.agents.read().await.get(name).map(|a| a.config.clone())
86 }
87
88 pub async fn agents(&self) -> Vec<AgentConfig> {
90 self.agents
91 .read()
92 .await
93 .values()
94 .map(|a| a.config.clone())
95 .collect()
96 }
97
98 pub async fn take_agent(&self, name: &str) -> Option<wcore::Agent<H::Model>> {
103 self.agents.write().await.remove(name)
104 }
105
106 pub async fn put_agent(&self, agent: wcore::Agent<H::Model>) {
108 let name = agent.config.name.clone();
109 self.agents.write().await.insert(name, agent);
110 }
111
112 pub async fn clear_session(&self, agent: &str) {
114 if let Some(a) = self.agents.write().await.get_mut(agent) {
115 a.clear_history();
116 }
117 }
118}