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"))) } }}
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")))
}
}
}