move repo-code config objects to their own submodule

This commit is contained in:
Chris Beck
2025-12-17 23:48:50 -07:00
parent 1a67da9e3d
commit 6f1af0d01f
2 changed files with 66 additions and 61 deletions
+61
View File
@@ -0,0 +1,61 @@
//! Configuration types for repository code browsing.
use serde::Deserialize;
use std::{path::PathBuf, str::FromStr};
/// A GitHub repository identifier (owner/repo).
#[derive(Clone, Debug, Deserialize)]
#[serde(try_from = "String")]
pub struct GitHubRepo {
/// The repository owner (user or organization).
pub owner: String,
/// The repository name.
pub repo: String,
}
impl FromStr for GitHubRepo {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts: Vec<&str> = s.split('/').collect();
if parts.len() != 2 || parts[0].is_empty() || parts[1].is_empty() {
return Err(format!(
"invalid GitHub repo '{}': expected 'owner/repo' format",
s
));
}
Ok(Self {
owner: parts[0].to_string(),
repo: parts[1].to_string(),
})
}
}
impl TryFrom<String> for GitHubRepo {
type Error = String;
fn try_from(s: String) -> Result<Self, Self::Error> {
s.parse()
}
}
/// Configuration for an application's source code access.
#[derive(Clone, Debug, Deserialize)]
pub struct RepoCodeConfig {
/// Name of the application (used to identify it in tool calls).
pub name: String,
/// GitHub repository in "owner/repo" format.
pub github: GitHubRepo,
/// Path to file containing the GitHub personal access token.
/// Optional for public repositories (unauthenticated access has lower rate limits).
pub token_file: Option<PathBuf>,
/// Glob patterns to filter which files are included from the tarball.
/// If non-empty, only files matching at least one pattern are kept.
/// Uses gitignore-style glob syntax (e.g., "*.rs", "src/**/*.rs").
#[serde(default)]
pub glob: Vec<String>,
/// Include files that aren't valid UTF-8 (using lossy conversion).
/// By default (false), non-UTF-8 files are skipped entirely.
#[serde(default)]
pub include_non_utf8: bool,
}
+5 -61
View File
@@ -3,77 +3,21 @@
//! This crate provides tools for browsing application source code by downloading
//! tarballs from GitHub and caching them in memory.
mod config;
pub use config::{GitHubRepo, RepoCodeConfig};
use async_trait::async_trait;
use flate2::read::GzDecoder;
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, path::PathBuf,
pin::Pin, str::FromStr, 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};
/// A GitHub repository identifier (owner/repo).
#[derive(Clone, Debug, Deserialize)]
#[serde(try_from = "String")]
pub struct GitHubRepo {
/// The repository owner (user or organization).
pub owner: String,
/// The repository name.
pub repo: String,
}
impl FromStr for GitHubRepo {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts: Vec<&str> = s.split('/').collect();
if parts.len() != 2 || parts[0].is_empty() || parts[1].is_empty() {
return Err(format!(
"invalid GitHub repo '{}': expected 'owner/repo' format",
s
));
}
Ok(Self {
owner: parts[0].to_string(),
repo: parts[1].to_string(),
})
}
}
impl TryFrom<String> for GitHubRepo {
type Error = String;
fn try_from(s: String) -> Result<Self, Self::Error> {
s.parse()
}
}
/// Configuration for an application's source code access.
#[derive(Clone, Debug, Deserialize)]
pub struct RepoCodeConfig {
/// Name of the application (used to identify it in tool calls).
pub name: String,
/// GitHub repository in "owner/repo" format.
pub github: GitHubRepo,
/// Path to file containing the GitHub personal access token.
/// Optional for public repositories (unauthenticated access has lower rate limits).
pub token_file: Option<PathBuf>,
/// Glob patterns to filter which files are included from the tarball.
/// If non-empty, only files matching at least one pattern are kept.
/// Uses gitignore-style glob syntax (e.g., "*.rs", "src/**/*.rs").
#[serde(default)]
pub glob: Vec<String>,
/// Include files that aren't valid UTF-8 (using lossy conversion).
/// By default (false), non-UTF-8 files are skipped entirely.
#[serde(default)]
pub include_non_utf8: bool,
}
/// A file stored in memory from the tarball.
#[derive(Debug, Clone)]
struct CachedFile {