rename crate again to signal-gateway-code-tool
This commit is contained in:
Generated
+18
-18
@@ -1935,8 +1935,8 @@ dependencies = [
|
||||
"serde_json",
|
||||
"signal-gateway",
|
||||
"signal-gateway-assistant-claude",
|
||||
"signal-gateway-code-tool",
|
||||
"signal-gateway-log-ingest",
|
||||
"signal-gateway-repo-code",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"toml",
|
||||
@@ -1945,6 +1945,23 @@ dependencies = [
|
||||
"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]]
|
||||
name = "signal-gateway-log-ingest"
|
||||
version = "0.1.0"
|
||||
@@ -1960,23 +1977,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.7"
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ resolver = "2"
|
||||
members = [
|
||||
"prometheus-http-client",
|
||||
"signal-gateway",
|
||||
"signal-gateway-repo-code",
|
||||
"signal-gateway-code-tool",
|
||||
"signal-gateway-assistant",
|
||||
"signal-gateway-assistant/claude",
|
||||
"signal-gateway-bin",
|
||||
|
||||
@@ -18,7 +18,7 @@ rustls-tls = ["signal-gateway/rustls-tls"]
|
||||
[dependencies]
|
||||
signal-gateway = { 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" }
|
||||
|
||||
async-trait = { workspace = true }
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
//! Extended configuration for application source code browsing.
|
||||
|
||||
use serde::Deserialize;
|
||||
use signal_gateway_repo_code::{RepoCode, RepoCodeConfig, ShaCallback};
|
||||
use signal_gateway_code_tool::{CodeTool, CodeToolConfig, ShaCallback};
|
||||
use std::sync::Arc;
|
||||
use tracing::warn;
|
||||
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)]
|
||||
pub struct RepoCodeConfigExt {
|
||||
/// The base RepoCode configuration.
|
||||
pub struct CodeToolConfigExt {
|
||||
/// The base CodeTool configuration.
|
||||
#[serde(flatten)]
|
||||
pub config: RepoCodeConfig,
|
||||
pub config: CodeToolConfig,
|
||||
/// URL to GET the current deployed version SHA.
|
||||
pub version_sha_http_get: Url,
|
||||
}
|
||||
|
||||
impl RepoCodeConfigExt {
|
||||
/// Convert to an RepoCode instance with HTTP-based SHA callback.
|
||||
pub fn into_app_code(self) -> Result<RepoCode, std::io::Error> {
|
||||
impl CodeToolConfigExt {
|
||||
/// Convert to an CodeTool instance with HTTP-based SHA callback.
|
||||
pub fn into_app_code(self) -> Result<CodeTool, std::io::Error> {
|
||||
let url = self.version_sha_http_get.clone();
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
@@ -66,6 +66,6 @@ impl RepoCodeConfigExt {
|
||||
})
|
||||
});
|
||||
|
||||
RepoCode::new(self.config, sha_callback)
|
||||
CodeTool::new(self.config, sha_callback)
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ use conf::Conf;
|
||||
use metrics_exporter_prometheus::PrometheusBuilder;
|
||||
use signal_gateway::{CommandRouter, Gateway, GatewayConfig, Handling};
|
||||
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 tokio::net::TcpListener;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
@@ -16,8 +16,8 @@ use tracing_subscriber::EnvFilter;
|
||||
mod admin_http;
|
||||
use admin_http::AdminHttpConfig;
|
||||
|
||||
mod repo_code;
|
||||
use repo_code::RepoCodeConfigExt;
|
||||
mod code_tool;
|
||||
use code_tool::CodeToolConfigExt;
|
||||
|
||||
mod listen_http;
|
||||
use listen_http::start_http_task;
|
||||
@@ -51,7 +51,7 @@ pub struct Config {
|
||||
admin_http: Option<AdminHttpConfig>,
|
||||
/// Application source code configurations for Claude tools.
|
||||
#[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.
|
||||
#[conf(flatten, prefix)]
|
||||
claude: Option<ClaudeConfig>,
|
||||
@@ -150,7 +150,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
router_builder.build()
|
||||
};
|
||||
|
||||
// Build RepoCode tools if configured
|
||||
// Build CodeTool tools if configured
|
||||
let app_code_tools = if !config.app_code.is_empty() {
|
||||
let mut apps = Vec::new();
|
||||
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 {
|
||||
None
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "signal-gateway-repo-code"
|
||||
name = "signal-gateway-code-tool"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
|
||||
@@ -61,7 +61,7 @@ pub enum Source {
|
||||
|
||||
/// Configuration for an application's source code access.
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
|
||||
pub struct RepoCodeConfig {
|
||||
pub struct CodeToolConfig {
|
||||
/// Name of the application (used to identify it in tool calls).
|
||||
pub name: String,
|
||||
/// 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.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.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.source,
|
||||
@@ -161,7 +161,7 @@ mod tests {
|
||||
"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.glob, vec!["**/*.rs", "Cargo.toml"]);
|
||||
assert!(config.include_non_utf8);
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
mod config;
|
||||
|
||||
pub use config::{GitHubRepo, RepoCodeConfig, Source};
|
||||
pub use config::{CodeToolConfig, GitHubRepo, Source};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use flate2::read::GzDecoder;
|
||||
@@ -13,7 +13,9 @@ use globset::{Glob, GlobSet, GlobSetBuilder};
|
||||
use regex::Regex;
|
||||
use serde::Deserialize;
|
||||
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 tokio::sync::{Mutex, MutexGuard};
|
||||
use tracing::{error, info, warn};
|
||||
@@ -57,7 +59,7 @@ enum ResolvedSource {
|
||||
/// Application source code browser.
|
||||
///
|
||||
/// Downloads and caches GitHub tarballs for browsing application source code.
|
||||
pub struct RepoCode {
|
||||
pub struct CodeTool {
|
||||
name: String,
|
||||
source: ResolvedSource,
|
||||
glob_filter: Option<GlobSet>,
|
||||
@@ -67,13 +69,13 @@ pub struct RepoCode {
|
||||
cache: Mutex<Option<CachedTarball>>,
|
||||
}
|
||||
|
||||
impl RepoCode {
|
||||
/// Create a new RepoCode instance from configuration.
|
||||
impl CodeTool {
|
||||
/// Create a new CodeTool instance from configuration.
|
||||
///
|
||||
/// 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
|
||||
/// 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 {
|
||||
Source::GitHub { repo, token_file } => {
|
||||
let token = token_file
|
||||
@@ -90,20 +92,21 @@ impl RepoCode {
|
||||
};
|
||||
|
||||
// Compile glob patterns if any are specified
|
||||
let glob_filter = if config.glob.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let mut builder = GlobSetBuilder::new();
|
||||
for pattern in &config.glob {
|
||||
let glob = Glob::new(pattern).map_err(|e| {
|
||||
std::io::Error::other(format!("invalid glob pattern '{}': {}", pattern, e))
|
||||
})?;
|
||||
builder.add(glob);
|
||||
}
|
||||
Some(builder.build().map_err(|e| {
|
||||
std::io::Error::other(format!("failed to build glob set: {}", e))
|
||||
})?)
|
||||
};
|
||||
let glob_filter =
|
||||
if config.glob.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let mut builder = GlobSetBuilder::new();
|
||||
for pattern in &config.glob {
|
||||
let glob = Glob::new(pattern).map_err(|e| {
|
||||
std::io::Error::other(format!("invalid glob pattern '{}': {}", pattern, e))
|
||||
})?;
|
||||
builder.add(glob);
|
||||
}
|
||||
Some(builder.build().map_err(|e| {
|
||||
std::io::Error::other(format!("failed to build glob set: {}", e))
|
||||
})?)
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
name: config.name,
|
||||
@@ -187,9 +190,8 @@ impl RepoCode {
|
||||
self.download_tarball_from_github(owner, repo, token.as_deref(), sha)
|
||||
.await
|
||||
}
|
||||
ResolvedSource::File { path } => std::fs::read(path).map_err(|e| {
|
||||
format!("Failed to read tarball from {}: {e}", path.display())
|
||||
}),
|
||||
ResolvedSource::File { path } => std::fs::read(path)
|
||||
.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.
|
||||
pub struct RepoCodeTools {
|
||||
apps: Vec<RepoCode>,
|
||||
pub struct CodeToolTools {
|
||||
apps: Vec<CodeTool>,
|
||||
}
|
||||
|
||||
impl RepoCodeTools {
|
||||
/// Create a new RepoCodeTools instance.
|
||||
pub fn new(apps: Vec<RepoCode>) -> Self {
|
||||
impl CodeToolTools {
|
||||
/// Create a new CodeToolTools instance.
|
||||
pub fn new(apps: Vec<CodeTool>) -> Self {
|
||||
Self { apps }
|
||||
}
|
||||
|
||||
/// 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)
|
||||
}
|
||||
|
||||
@@ -631,7 +633,7 @@ struct SearchInput {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ToolExecutor for RepoCodeTools {
|
||||
impl ToolExecutor for CodeToolTools {
|
||||
fn tools(&self) -> Vec<Tool> {
|
||||
vec![
|
||||
Tool {
|
||||
+8
-7
@@ -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
|
||||
//! 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;
|
||||
|
||||
/// 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_SHA: &str = "79b98e25f27ae4f5dd73a5a3d8f37dad655a57e8";
|
||||
|
||||
fn create_test_repo_code() -> RepoCode {
|
||||
fn create_test_repo_code() -> CodeTool {
|
||||
create_test_repo_code_with_glob(vec![])
|
||||
}
|
||||
|
||||
fn create_test_repo_code_with_glob(glob: Vec<String>) -> RepoCode {
|
||||
let config = RepoCodeConfig {
|
||||
fn create_test_repo_code_with_glob(glob: Vec<String>) -> CodeTool {
|
||||
let config = CodeToolConfig {
|
||||
name: "test-app".to_string(),
|
||||
source: Source::GitHub {
|
||||
repo: GitHubRepo {
|
||||
@@ -36,7 +36,7 @@ fn create_test_repo_code_with_glob(glob: Vec<String>) -> RepoCode {
|
||||
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]
|
||||
@@ -276,7 +276,8 @@ async fn test_glob_filter_specific_directory() {
|
||||
#[tokio::test]
|
||||
async fn test_glob_filter_multiple_patterns() {
|
||||
// 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");
|
||||
|
||||
Reference in New Issue
Block a user