From 943141c0f699b240419e2cdf92392f887020297c Mon Sep 17 00:00:00 2001 From: Chris Beck Date: Thu, 18 Dec 2025 11:45:16 -0700 Subject: [PATCH] add support for code-tool summary --- signal-gateway-code-tool/src/config.rs | 4 +- signal-gateway-code-tool/src/lib.rs | 154 ++++++++++++------------- 2 files changed, 79 insertions(+), 79 deletions(-) diff --git a/signal-gateway-code-tool/src/config.rs b/signal-gateway-code-tool/src/config.rs index 81d3c5c..3f66f02 100644 --- a/signal-gateway-code-tool/src/config.rs +++ b/signal-gateway-code-tool/src/config.rs @@ -59,10 +59,10 @@ pub enum Source { }, } -/// Configuration for an application's source code access. +/// Configuration for a repository's source code access. #[derive(Clone, Debug, Deserialize, PartialEq, Eq)] pub struct CodeToolConfig { - /// Name of the application (used to identify it in tool calls). + /// Name of the repository (used to identify it in tool calls). pub name: String, /// Source of the repository code. #[serde(flatten)] diff --git a/signal-gateway-code-tool/src/lib.rs b/signal-gateway-code-tool/src/lib.rs index 3360972..267fd90 100644 --- a/signal-gateway-code-tool/src/lib.rs +++ b/signal-gateway-code-tool/src/lib.rs @@ -1,6 +1,6 @@ -//! Application source code browsing via GitHub tarball downloads. +//! Repository source code browsing via GitHub tarball downloads. //! -//! This crate provides tools for browsing application source code by downloading +//! This crate provides tools for browsing repository source code by downloading //! tarballs from GitHub and caching them in memory. mod cached; @@ -40,9 +40,9 @@ enum ResolvedSource { }, } -/// Application source code browser. +/// Repository source code browser. /// -/// Downloads and caches GitHub tarballs for browsing application source code. +/// Downloads and caches GitHub tarballs for browsing repository source code. pub struct CodeTool { config: CodeToolConfig, source: ResolvedSource, @@ -110,7 +110,7 @@ impl CodeTool { }) } - /// Get the application name. + /// Get the repository name. pub fn name(&self) -> &str { &self.config.name } @@ -477,56 +477,56 @@ impl CodeTool { } } -/// Tool executor for multiple application source code browsers. +/// Tool executor for multiple repository code browsers. pub struct CodeToolTools { - apps: Vec, + repos: Vec, } impl CodeToolTools { /// Create a new CodeToolTools instance. - pub fn new(apps: Vec) -> Self { - Self { apps } + pub fn new(repos: Vec) -> Self { + Self { repos } } - /// Find an app by name. - fn find_app(&self, name: &str) -> Option<&CodeTool> { - self.apps.iter().find(|app| app.name() == name) + /// Find a repo by name. + fn find_repo(&self, name: &str) -> Option<&CodeTool> { + self.repos.iter().find(|repo| repo.name() == name) } - /// Get list of app names for error messages. - fn app_names(&self) -> String { - self.apps + /// Get list of repo names for error messages. + fn repo_names(&self) -> String { + self.repos .iter() - .map(|a| a.name()) + .map(|r| r.name()) .collect::>() .join(", ") } - /// Get list of app names that have summaries available. - fn apps_with_summaries(&self) -> Vec<&str> { - self.apps + /// Get list of repo names that have summaries available. + fn repos_with_summaries(&self) -> Vec<&str> { + self.repos .iter() - .filter(|a| a.has_summary()) - .map(|a| a.name()) + .filter(|r| r.has_summary()) + .map(|r| r.name()) .collect() } } #[derive(Deserialize)] struct LsInput { - app: String, + repo: String, path: Option, } #[derive(Deserialize)] struct FindInput { - app: String, + repo: String, pattern: Option, } #[derive(Deserialize)] struct ReadInput { - app: String, + repo: String, path: String, line_start: Option, line_end: Option, @@ -534,7 +534,7 @@ struct ReadInput { #[derive(Deserialize)] struct SearchInput { - app: String, + repo: String, pattern: String, #[serde(default)] context: u32, @@ -543,7 +543,7 @@ struct SearchInput { #[derive(Deserialize)] struct SummaryInput { - app: String, + repo: String, } #[async_trait] @@ -552,49 +552,49 @@ impl ToolExecutor for CodeToolTools { let mut tools = vec![ Tool { name: "code_ls", - description: "List files in a directory of an application's source code.", + description: "List files in a directory of a repository's source code.", input_schema: serde_json::json!({ "type": "object", "properties": { - "app": { + "repo": { "type": "string", - "description": "Name of the application" + "description": "Name of the repository" }, "path": { "type": "string", "description": "Directory path to list (optional, defaults to root)" } }, - "required": ["app"] + "required": ["repo"] }), }, Tool { name: "code_find", - description: "Find files matching a glob pattern in an application's source code.", + description: "Find files matching a glob pattern in a repository's source code.", input_schema: serde_json::json!({ "type": "object", "properties": { - "app": { + "repo": { "type": "string", - "description": "Name of the application" + "description": "Name of the repository" }, "pattern": { "type": "string", "description": "Glob pattern to match (e.g., '*.rs', 'src/*.py')" } }, - "required": ["app"] + "required": ["repo"] }), }, Tool { name: "code_read", - description: "Read a file from an application's source code.", + description: "Read a file from a repository's source code.", input_schema: serde_json::json!({ "type": "object", "properties": { - "app": { + "repo": { "type": "string", - "description": "Name of the application" + "description": "Name of the repository" }, "path": { "type": "string", @@ -609,18 +609,18 @@ impl ToolExecutor for CodeToolTools { "description": "Ending line number (inclusive, optional)" } }, - "required": ["app", "path"] + "required": ["repo", "path"] }), }, Tool { name: "code_search", - description: "Search for a regex pattern in an application's source code (like grep).", + description: "Search for a regex pattern in a repository's source code (like grep).", input_schema: serde_json::json!({ "type": "object", "properties": { - "app": { + "repo": { "type": "string", - "description": "Name of the application" + "description": "Name of the repository" }, "pattern": { "type": "string", @@ -635,26 +635,26 @@ impl ToolExecutor for CodeToolTools { "description": "Optional path prefix to limit search scope" } }, - "required": ["app", "pattern"] + "required": ["repo", "pattern"] }), }, ]; - // Only include summary tool if at least one app has a summary - let apps_with_summaries = self.apps_with_summaries(); - if !apps_with_summaries.is_empty() { + // Only include summary tool if at least one repo has a summary + let repos_with_summaries = self.repos_with_summaries(); + if !repos_with_summaries.is_empty() { tools.push(Tool { name: "code_summary", - description: "Get a summary/overview of an application's codebase.", + description: "Get a summary/overview of a repository's codebase.", input_schema: serde_json::json!({ "type": "object", "properties": { - "app": { + "repo": { "type": "string", - "description": format!("Name of the application. Apps with summaries: {}", apps_with_summaries.join(", ")) + "description": format!("Name of the repository. Repos with summaries: {}", repos_with_summaries.join(", ")) } }, - "required": ["app"] + "required": ["repo"] }), }); } @@ -674,40 +674,40 @@ impl ToolExecutor for CodeToolTools { "code_ls" => { let input: LsInput = serde_json::from_value(input.clone()) .map_err(|e| format!("Invalid input: {e}"))?; - let app = self.find_app(&input.app).ok_or_else(|| { + let repo = self.find_repo(&input.repo).ok_or_else(|| { format!( - "Unknown app '{}'. Available: {}", - input.app, - self.app_names() + "Unknown repo '{}'. Available: {}", + input.repo, + self.repo_names() ) })?; - let result = app.ls(input.path.as_deref()).await?; + let result = repo.ls(input.path.as_deref()).await?; Ok(ToolResult::new(result)) } "code_find" => { let input: FindInput = serde_json::from_value(input.clone()) .map_err(|e| format!("Invalid input: {e}"))?; - let app = self.find_app(&input.app).ok_or_else(|| { + let repo = self.find_repo(&input.repo).ok_or_else(|| { format!( - "Unknown app '{}'. Available: {}", - input.app, - self.app_names() + "Unknown repo '{}'. Available: {}", + input.repo, + self.repo_names() ) })?; - let result = app.find(input.pattern.as_deref()).await?; + let result = repo.find(input.pattern.as_deref()).await?; Ok(ToolResult::new(result)) } "code_read" => { let input: ReadInput = serde_json::from_value(input.clone()) .map_err(|e| format!("Invalid input: {e}"))?; - let app = self.find_app(&input.app).ok_or_else(|| { + let repo = self.find_repo(&input.repo).ok_or_else(|| { format!( - "Unknown app '{}'. Available: {}", - input.app, - self.app_names() + "Unknown repo '{}'. Available: {}", + input.repo, + self.repo_names() ) })?; - let result = app + let result = repo .read(&input.path, input.line_start, input.line_end) .await?; Ok(ToolResult::new(result)) @@ -715,14 +715,14 @@ impl ToolExecutor for CodeToolTools { "code_search" => { let input: SearchInput = serde_json::from_value(input.clone()) .map_err(|e| format!("Invalid input: {e}"))?; - let app = self.find_app(&input.app).ok_or_else(|| { + let repo = self.find_repo(&input.repo).ok_or_else(|| { format!( - "Unknown app '{}'. Available: {}", - input.app, - self.app_names() + "Unknown repo '{}'. Available: {}", + input.repo, + self.repo_names() ) })?; - let result = app + let result = repo .search(&input.pattern, input.context, input.path_prefix.as_deref()) .await?; Ok(ToolResult::new(result)) @@ -730,18 +730,18 @@ impl ToolExecutor for CodeToolTools { "code_summary" => { let input: SummaryInput = serde_json::from_value(input.clone()) .map_err(|e| format!("Invalid input: {e}"))?; - let app = self.find_app(&input.app).ok_or_else(|| { + let repo = self.find_repo(&input.repo).ok_or_else(|| { format!( - "Unknown app '{}'. Available: {}", - input.app, - self.app_names() + "Unknown repo '{}'. Available: {}", + input.repo, + self.repo_names() ) })?; - let summary = app.summary().ok_or_else(|| { + let summary = repo.summary().ok_or_else(|| { format!( - "No summary available for '{}'. Apps with summaries: {}", - input.app, - self.apps_with_summaries().join(", ") + "No summary available for '{}'. Repos with summaries: {}", + input.repo, + self.repos_with_summaries().join(", ") ) })?; Ok(ToolResult::new(summary.to_string()))