rename crate again to signal-gateway-code-tool

This commit is contained in:
Chris Beck
2025-12-18 09:56:32 -07:00
parent 63c7974184
commit 2c9d5cfb5e
9 changed files with 81 additions and 78 deletions
Generated
+18 -18
View File
@@ -1935,8 +1935,8 @@ dependencies = [
"serde_json", "serde_json",
"signal-gateway", "signal-gateway",
"signal-gateway-assistant-claude", "signal-gateway-assistant-claude",
"signal-gateway-code-tool",
"signal-gateway-log-ingest", "signal-gateway-log-ingest",
"signal-gateway-repo-code",
"tokio", "tokio",
"tokio-util", "tokio-util",
"toml", "toml",
@@ -1945,6 +1945,23 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "signal-gateway-code-tool"
version = "0.1.0"
dependencies = [
"async-trait",
"flate2",
"globset",
"regex",
"reqwest",
"serde",
"serde_json",
"signal-gateway-assistant",
"tar",
"tokio",
"tracing",
]
[[package]] [[package]]
name = "signal-gateway-log-ingest" name = "signal-gateway-log-ingest"
version = "0.1.0" version = "0.1.0"
@@ -1960,23 +1977,6 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "signal-gateway-repo-code"
version = "0.1.0"
dependencies = [
"async-trait",
"flate2",
"globset",
"regex",
"reqwest",
"serde",
"serde_json",
"signal-gateway-assistant",
"tar",
"tokio",
"tracing",
]
[[package]] [[package]]
name = "signal-hook-registry" name = "signal-hook-registry"
version = "1.4.7" version = "1.4.7"
+1 -1
View File
@@ -3,7 +3,7 @@ resolver = "2"
members = [ members = [
"prometheus-http-client", "prometheus-http-client",
"signal-gateway", "signal-gateway",
"signal-gateway-repo-code", "signal-gateway-code-tool",
"signal-gateway-assistant", "signal-gateway-assistant",
"signal-gateway-assistant/claude", "signal-gateway-assistant/claude",
"signal-gateway-bin", "signal-gateway-bin",
+1 -1
View File
@@ -18,7 +18,7 @@ rustls-tls = ["signal-gateway/rustls-tls"]
[dependencies] [dependencies]
signal-gateway = { workspace = true } signal-gateway = { workspace = true }
signal-gateway-assistant-claude = { workspace = true } signal-gateway-assistant-claude = { workspace = true }
signal-gateway-repo-code = { path = "../signal-gateway-repo-code" } signal-gateway-code-tool = { path = "../signal-gateway-code-tool" }
signal-gateway-log-ingest = { path = "../signal-gateway-log-ingest" } signal-gateway-log-ingest = { path = "../signal-gateway-log-ingest" }
async-trait = { workspace = true } async-trait = { workspace = true }
@@ -1,24 +1,24 @@
//! Extended configuration for application source code browsing. //! Extended configuration for application source code browsing.
use serde::Deserialize; use serde::Deserialize;
use signal_gateway_repo_code::{RepoCode, RepoCodeConfig, ShaCallback}; use signal_gateway_code_tool::{CodeTool, CodeToolConfig, ShaCallback};
use std::sync::Arc; use std::sync::Arc;
use tracing::warn; use tracing::warn;
use url::Url; use url::Url;
/// Extended configuration for RepoCode with HTTP-based SHA fetching. /// Extended configuration for CodeTool with HTTP-based SHA fetching.
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
pub struct RepoCodeConfigExt { pub struct CodeToolConfigExt {
/// The base RepoCode configuration. /// The base CodeTool configuration.
#[serde(flatten)] #[serde(flatten)]
pub config: RepoCodeConfig, pub config: CodeToolConfig,
/// URL to GET the current deployed version SHA. /// URL to GET the current deployed version SHA.
pub version_sha_http_get: Url, pub version_sha_http_get: Url,
} }
impl RepoCodeConfigExt { impl CodeToolConfigExt {
/// Convert to an RepoCode instance with HTTP-based SHA callback. /// Convert to an CodeTool instance with HTTP-based SHA callback.
pub fn into_app_code(self) -> Result<RepoCode, std::io::Error> { pub fn into_app_code(self) -> Result<CodeTool, std::io::Error> {
let url = self.version_sha_http_get.clone(); let url = self.version_sha_http_get.clone();
let client = reqwest::Client::new(); let client = reqwest::Client::new();
@@ -66,6 +66,6 @@ impl RepoCodeConfigExt {
}) })
}); });
RepoCode::new(self.config, sha_callback) CodeTool::new(self.config, sha_callback)
} }
} }
+6 -6
View File
@@ -6,7 +6,7 @@ use conf::Conf;
use metrics_exporter_prometheus::PrometheusBuilder; use metrics_exporter_prometheus::PrometheusBuilder;
use signal_gateway::{CommandRouter, Gateway, GatewayConfig, Handling}; use signal_gateway::{CommandRouter, Gateway, GatewayConfig, Handling};
use signal_gateway_assistant_claude::{ClaudeAssistant, ClaudeConfig}; use signal_gateway_assistant_claude::{ClaudeAssistant, ClaudeConfig};
use signal_gateway_repo_code::RepoCodeTools; use signal_gateway_code_tool::CodeToolTools;
use std::{env, fs, net::SocketAddr, path::PathBuf, sync::Arc}; use std::{env, fs, net::SocketAddr, path::PathBuf, sync::Arc};
use tokio::net::TcpListener; use tokio::net::TcpListener;
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
@@ -16,8 +16,8 @@ use tracing_subscriber::EnvFilter;
mod admin_http; mod admin_http;
use admin_http::AdminHttpConfig; use admin_http::AdminHttpConfig;
mod repo_code; mod code_tool;
use repo_code::RepoCodeConfigExt; use code_tool::CodeToolConfigExt;
mod listen_http; mod listen_http;
use listen_http::start_http_task; use listen_http::start_http_task;
@@ -51,7 +51,7 @@ pub struct Config {
admin_http: Option<AdminHttpConfig>, admin_http: Option<AdminHttpConfig>,
/// Application source code configurations for Claude tools. /// Application source code configurations for Claude tools.
#[conf(long, env, value_parser = serde_json::from_str, default, default_help_str = "[]")] #[conf(long, env, value_parser = serde_json::from_str, default, default_help_str = "[]")]
app_code: Vec<RepoCodeConfigExt>, app_code: Vec<CodeToolConfigExt>,
/// Claude API configuration for AI-powered responses. /// Claude API configuration for AI-powered responses.
#[conf(flatten, prefix)] #[conf(flatten, prefix)]
claude: Option<ClaudeConfig>, claude: Option<ClaudeConfig>,
@@ -150,7 +150,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
router_builder.build() router_builder.build()
}; };
// Build RepoCode tools if configured // Build CodeTool tools if configured
let app_code_tools = if !config.app_code.is_empty() { let app_code_tools = if !config.app_code.is_empty() {
let mut apps = Vec::new(); let mut apps = Vec::new();
for app_config in config.app_code { for app_config in config.app_code {
@@ -163,7 +163,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
} }
} }
Some(Arc::new(RepoCodeTools::new(apps))) Some(Arc::new(CodeToolTools::new(apps)))
} else { } else {
None None
}; };
@@ -1,5 +1,5 @@
[package] [package]
name = "signal-gateway-repo-code" name = "signal-gateway-code-tool"
version = "0.1.0" version = "0.1.0"
edition.workspace = true edition.workspace = true
@@ -61,7 +61,7 @@ pub enum Source {
/// Configuration for an application's source code access. /// Configuration for an application's source code access.
#[derive(Clone, Debug, Deserialize, PartialEq, Eq)] #[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
pub struct RepoCodeConfig { pub struct CodeToolConfig {
/// Name of the application (used to identify it in tool calls). /// Name of the application (used to identify it in tool calls).
pub name: String, pub name: String,
/// Source of the repository code. /// Source of the repository code.
@@ -92,7 +92,7 @@ mod tests {
} }
}"#; }"#;
let config: RepoCodeConfig = serde_json::from_str(json).unwrap(); let config: CodeToolConfig = serde_json::from_str(json).unwrap();
assert_eq!(config.name, "my-app"); assert_eq!(config.name, "my-app");
assert_eq!( assert_eq!(
config.source, config.source,
@@ -117,7 +117,7 @@ mod tests {
} }
}"#; }"#;
let config: RepoCodeConfig = serde_json::from_str(json).unwrap(); let config: CodeToolConfig = serde_json::from_str(json).unwrap();
assert_eq!(config.name, "public-app"); assert_eq!(config.name, "public-app");
assert_eq!( assert_eq!(
config.source, config.source,
@@ -140,7 +140,7 @@ mod tests {
} }
}"#; }"#;
let config: RepoCodeConfig = serde_json::from_str(json).unwrap(); let config: CodeToolConfig = serde_json::from_str(json).unwrap();
assert_eq!(config.name, "local-app"); assert_eq!(config.name, "local-app");
assert_eq!( assert_eq!(
config.source, config.source,
@@ -161,7 +161,7 @@ mod tests {
"include_non_utf8": true "include_non_utf8": true
}"#; }"#;
let config: RepoCodeConfig = serde_json::from_str(json).unwrap(); let config: CodeToolConfig = serde_json::from_str(json).unwrap();
assert_eq!(config.name, "filtered-app"); assert_eq!(config.name, "filtered-app");
assert_eq!(config.glob, vec!["**/*.rs", "Cargo.toml"]); assert_eq!(config.glob, vec!["**/*.rs", "Cargo.toml"]);
assert!(config.include_non_utf8); assert!(config.include_non_utf8);
@@ -5,7 +5,7 @@
mod config; mod config;
pub use config::{GitHubRepo, RepoCodeConfig, Source}; pub use config::{CodeToolConfig, GitHubRepo, Source};
use async_trait::async_trait; use async_trait::async_trait;
use flate2::read::GzDecoder; use flate2::read::GzDecoder;
@@ -13,7 +13,9 @@ use globset::{Glob, GlobSet, GlobSetBuilder};
use regex::Regex; use regex::Regex;
use serde::Deserialize; use serde::Deserialize;
use signal_gateway_assistant::{Tool, ToolExecutor, ToolResult}; use signal_gateway_assistant::{Tool, ToolExecutor, ToolResult};
use std::{collections::HashMap, error::Error, fmt::Write, future::Future, io::Read, pin::Pin, sync::Arc}; use std::{
collections::HashMap, error::Error, fmt::Write, future::Future, io::Read, pin::Pin, sync::Arc,
};
use tar::Archive; use tar::Archive;
use tokio::sync::{Mutex, MutexGuard}; use tokio::sync::{Mutex, MutexGuard};
use tracing::{error, info, warn}; use tracing::{error, info, warn};
@@ -57,7 +59,7 @@ enum ResolvedSource {
/// Application source code browser. /// Application source code browser.
/// ///
/// Downloads and caches GitHub tarballs for browsing application source code. /// Downloads and caches GitHub tarballs for browsing application source code.
pub struct RepoCode { pub struct CodeTool {
name: String, name: String,
source: ResolvedSource, source: ResolvedSource,
glob_filter: Option<GlobSet>, glob_filter: Option<GlobSet>,
@@ -67,13 +69,13 @@ pub struct RepoCode {
cache: Mutex<Option<CachedTarball>>, cache: Mutex<Option<CachedTarball>>,
} }
impl RepoCode { impl CodeTool {
/// Create a new RepoCode instance from configuration. /// Create a new CodeTool instance from configuration.
/// ///
/// The `get_sha` callback is called to determine which git SHA to download/load. /// The `get_sha` callback is called to determine which git SHA to download/load.
/// For GitHub sources, this is the commit SHA. For file sources, this can be /// For GitHub sources, this is the commit SHA. For file sources, this can be
/// used to track file modification (e.g., mtime or a version string). /// used to track file modification (e.g., mtime or a version string).
pub fn new(config: RepoCodeConfig, get_sha: ShaCallback) -> Result<Self, std::io::Error> { pub fn new(config: CodeToolConfig, get_sha: ShaCallback) -> Result<Self, std::io::Error> {
let source = match config.source { let source = match config.source {
Source::GitHub { repo, token_file } => { Source::GitHub { repo, token_file } => {
let token = token_file let token = token_file
@@ -90,7 +92,8 @@ impl RepoCode {
}; };
// Compile glob patterns if any are specified // Compile glob patterns if any are specified
let glob_filter = if config.glob.is_empty() { let glob_filter =
if config.glob.is_empty() {
None None
} else { } else {
let mut builder = GlobSetBuilder::new(); let mut builder = GlobSetBuilder::new();
@@ -187,9 +190,8 @@ impl RepoCode {
self.download_tarball_from_github(owner, repo, token.as_deref(), sha) self.download_tarball_from_github(owner, repo, token.as_deref(), sha)
.await .await
} }
ResolvedSource::File { path } => std::fs::read(path).map_err(|e| { ResolvedSource::File { path } => std::fs::read(path)
format!("Failed to read tarball from {}: {e}", path.display()) .map_err(|e| format!("Failed to read tarball from {}: {e}", path.display())),
}),
} }
} }
@@ -576,18 +578,18 @@ fn looks_binary(content: &str) -> bool {
} }
/// Tool executor for multiple application source code browsers. /// Tool executor for multiple application source code browsers.
pub struct RepoCodeTools { pub struct CodeToolTools {
apps: Vec<RepoCode>, apps: Vec<CodeTool>,
} }
impl RepoCodeTools { impl CodeToolTools {
/// Create a new RepoCodeTools instance. /// Create a new CodeToolTools instance.
pub fn new(apps: Vec<RepoCode>) -> Self { pub fn new(apps: Vec<CodeTool>) -> Self {
Self { apps } Self { apps }
} }
/// Find an app by name. /// Find an app by name.
fn find_app(&self, name: &str) -> Option<&RepoCode> { fn find_app(&self, name: &str) -> Option<&CodeTool> {
self.apps.iter().find(|app| app.name() == name) self.apps.iter().find(|app| app.name() == name)
} }
@@ -631,7 +633,7 @@ struct SearchInput {
} }
#[async_trait] #[async_trait]
impl ToolExecutor for RepoCodeTools { impl ToolExecutor for CodeToolTools {
fn tools(&self) -> Vec<Tool> { fn tools(&self) -> Vec<Tool> {
vec![ vec![
Tool { Tool {
@@ -1,9 +1,9 @@
//! Integration tests for signal-gateway-repo-code. //! Integration tests for signal-gateway-code-tool.
//! //!
//! These tests exercise the GitHub tarball download and file browsing functionality //! These tests exercise the GitHub tarball download and file browsing functionality
//! against a real public repository at a pinned commit. //! against a real public repository at a pinned commit.
use signal_gateway_repo_code::{GitHubRepo, RepoCode, RepoCodeConfig, ShaCallback, Source}; use signal_gateway_code_tool::{CodeTool, CodeToolConfig, GitHubRepo, ShaCallback, Source};
use std::sync::Arc; use std::sync::Arc;
/// Test against cbeck88/ver-stub-rs at a known commit. /// Test against cbeck88/ver-stub-rs at a known commit.
@@ -12,12 +12,12 @@ const TEST_OWNER: &str = "cbeck88";
const TEST_REPO: &str = "ver-stub-rs"; const TEST_REPO: &str = "ver-stub-rs";
const TEST_SHA: &str = "79b98e25f27ae4f5dd73a5a3d8f37dad655a57e8"; const TEST_SHA: &str = "79b98e25f27ae4f5dd73a5a3d8f37dad655a57e8";
fn create_test_repo_code() -> RepoCode { fn create_test_repo_code() -> CodeTool {
create_test_repo_code_with_glob(vec![]) create_test_repo_code_with_glob(vec![])
} }
fn create_test_repo_code_with_glob(glob: Vec<String>) -> RepoCode { fn create_test_repo_code_with_glob(glob: Vec<String>) -> CodeTool {
let config = RepoCodeConfig { let config = CodeToolConfig {
name: "test-app".to_string(), name: "test-app".to_string(),
source: Source::GitHub { source: Source::GitHub {
repo: GitHubRepo { repo: GitHubRepo {
@@ -36,7 +36,7 @@ fn create_test_repo_code_with_glob(glob: Vec<String>) -> RepoCode {
Box::pin(async move { Ok(sha) }) Box::pin(async move { Ok(sha) })
}); });
RepoCode::new(config, sha_callback).expect("Failed to create RepoCode") CodeTool::new(config, sha_callback).expect("Failed to create CodeTool")
} }
#[tokio::test] #[tokio::test]
@@ -276,7 +276,8 @@ async fn test_glob_filter_specific_directory() {
#[tokio::test] #[tokio::test]
async fn test_glob_filter_multiple_patterns() { async fn test_glob_filter_multiple_patterns() {
// Include both Cargo.toml files and shell scripts // Include both Cargo.toml files and shell scripts
let app = create_test_repo_code_with_glob(vec!["**/Cargo.toml".to_string(), "*.sh".to_string()]); let app =
create_test_repo_code_with_glob(vec!["**/Cargo.toml".to_string(), "*.sh".to_string()]);
let result = app.find(Some("*")).await.expect("find failed"); let result = app.find(Some("*")).await.expect("find failed");