use crate::Hook;
use std::path::{Path, PathBuf};
use tokio::sync::broadcast;
use wcore::{AgentEvent, ToolDispatch, ToolFuture, protocol::message};
pub trait Env: Send + Sync + 'static {
type Hook: Hook;
fn hook(&self) -> &Self::Hook;
fn on_agent_event(&self, _agent: &str, _conversation_id: u64, _event: &AgentEvent) {}
fn subscribe_events(&self) -> Option<broadcast::Receiver<message::AgentEventMsg>> {
None
}
fn discover_instructions(&self, _cwd: &Path) -> Option<String> {
None
}
fn effective_cwd(&self, _conversation_id: u64) -> PathBuf {
std::env::current_dir().unwrap_or_default()
}
}
pub fn dispatch_tool<'a, E: Env>(
env: &'a E,
name: &'a str,
args: &'a str,
agent: &'a str,
sender: &'a str,
conversation_id: Option<u64>,
) -> ToolFuture<'a> {
let call = ToolDispatch {
args: args.to_owned(),
agent: agent.to_owned(),
sender: sender.to_owned(),
conversation_id,
};
match env.hook().dispatch(name, call) {
Some(fut) => fut,
None => Box::pin(async move { Err(format!("tool not registered: {name}")) }),
}
}
impl Env for () {
type Hook = ();
fn hook(&self) -> &() {
&()
}
}