101 lines · 3.2 KB · Rust
RawDownload
use std::sync::Arc; use anyhow::{anyhow, bail};use assistant_tool::Tool;use gpui::{App, Entity, Task, Window}; use crate::manager::ContextServerManager;use crate::types; pub struct ContextServerTool {    server_manager: Entity<ContextServerManager>,    server_id: Arc<str>,    tool: types::Tool,} impl ContextServerTool {    pub fn new(        server_manager: Entity<ContextServerManager>,        server_id: impl Into<Arc<str>>,        tool: types::Tool,    ) -> Self {        Self {            server_manager,            server_id: server_id.into(),            tool,        }    }} impl Tool for ContextServerTool {    fn name(&self) -> String {        self.tool.name.clone()    }     fn description(&self) -> String {        self.tool.description.clone().unwrap_or_default()    }     fn input_schema(&self) -> serde_json::Value {        match &self.tool.input_schema {            serde_json::Value::Null => {                serde_json::json!({ "type": "object", "properties": [] })            }            serde_json::Value::Object(map) if map.is_empty() => {                serde_json::json!({ "type": "object", "properties": [] })            }            _ => self.tool.input_schema.clone(),        }    }     fn run(        self: std::sync::Arc<Self>,        input: serde_json::Value,        _thread_id: Arc<str>,        _workspace: gpui::WeakEntity<workspace::Workspace>,        _: &mut Window,        cx: &mut App,    ) -> gpui::Task<gpui::Result<String>> {        if let Some(server) = self.server_manager.read(cx).get_server(&self.server_id) {            cx.foreground_executor().spawn({                let tool_name = self.tool.name.clone();                async move {                    let Some(protocol) = server.client() else {                        bail!("Context server not initialized");                    };                     let arguments = if let serde_json::Value::Object(map) = input {                        Some(map.into_iter().collect())                    } else {                        None                    };                     log::trace!(                        "Running tool: {} with arguments: {:?}",                        tool_name,                        arguments                    );                    let response = protocol.run_tool(tool_name, arguments).await?;                     let mut result = String::new();                    for content in response.content {                        match content {                            types::ToolResponseContent::Text { text } => {                                result.push_str(&text);                            }                            types::ToolResponseContent::Image { .. } => {                                log::warn!("Ignoring image content from tool response");                            }                            types::ToolResponseContent::Resource { .. } => {                                log::warn!("Ignoring resource content from tool response");                            }                        }                    }                    Ok(result)                }            })        } else {            Task::ready(Err(anyhow!("Context server not found")))        }    }}