Add -with-remote-extension (#2062)

This commit is contained in:
Jim Bennett
2025-04-07 13:42:38 -07:00
committed by GitHub
parent 63623733dc
commit 050a8f2f42
21 changed files with 121 additions and 4 deletions

View File

@@ -77,6 +77,7 @@ impl Evaluation for ComputerControllerScript {
ExtensionRequirements {
builtin: vec!["computercontroller".to_string()],
external: Vec::new(),
remote: Vec::new(),
}
}
}

View File

@@ -80,6 +80,7 @@ impl Evaluation for ComputerControllerWebScrape {
ExtensionRequirements {
builtin: vec!["computercontroller".to_string()],
external: Vec::new(),
remote: Vec::new(),
}
}
}

View File

@@ -120,6 +120,7 @@ impl Evaluation for DeveloperCreateFile {
ExtensionRequirements {
builtin: vec!["developer".to_string()],
external: Vec::new(),
remote: Vec::new(),
}
}
}

View File

@@ -81,6 +81,7 @@ impl Evaluation for DeveloperListFiles {
ExtensionRequirements {
builtin: vec!["developer".to_string()],
external: Vec::new(),
remote: Vec::new(),
}
}
}

View File

@@ -207,6 +207,7 @@ impl Evaluation for SimpleRepoCloneTest {
ExtensionRequirements {
builtin: vec!["developer".to_string()],
external: Vec::new(),
remote: Vec::new(),
}
}
}

View File

@@ -98,6 +98,7 @@ impl Evaluation for DeveloperImage {
ExtensionRequirements {
builtin: vec!["developer".to_string()],
external: Vec::new(),
remote: Vec::new(),
}
}
}

View File

@@ -102,6 +102,7 @@ impl Evaluation for DeveloperSearchReplace {
ExtensionRequirements {
builtin: vec!["developer".to_string()],
external: Vec::new(),
remote: Vec::new(),
}
}
}

View File

@@ -82,6 +82,7 @@ impl Evaluation for MemoryRememberMemory {
ExtensionRequirements {
builtin: vec!["memory".to_string()],
external: Vec::new(),
remote: Vec::new(),
}
}
}

View File

@@ -27,6 +27,7 @@ pub enum EvaluationMetric {
pub struct ExtensionRequirements {
pub builtin: Vec<String>,
pub external: Vec<String>,
pub remote: Vec<String>,
}
#[async_trait]
@@ -54,6 +55,7 @@ pub trait Evaluation: Send + Sync {
ExtensionRequirements {
builtin: Vec::new(),
external: Vec::new(),
remote: Vec::new(),
}
}
}

View File

@@ -82,6 +82,7 @@ impl Evaluation for BlogSummary {
ExtensionRequirements {
builtin: vec!["developer".to_string()],
external: vec!["uvx mcp-server-fetch".to_string()],
remote: Vec::new(),
}
}
}

View File

@@ -114,6 +114,7 @@ impl Evaluation for FlappyBird {
ExtensionRequirements {
builtin: vec!["developer".to_string()],
external: Vec::new(),
remote: Vec::new(),
}
}
}

View File

@@ -92,6 +92,7 @@ impl Evaluation for GooseWiki {
ExtensionRequirements {
builtin: vec!["developer".to_string()],
external: Vec::new(),
remote: Vec::new(),
}
}
}

View File

@@ -102,6 +102,7 @@ Present the information in order of significance or quality. Focus specifically
ExtensionRequirements {
builtin: vec!["developer".to_string()],
external: vec!["uvx mcp-server-fetch".to_string()],
remote: Vec::new(),
}
}
}

View File

@@ -170,6 +170,7 @@ After writing the script, run it using python3 and show the results. Do not ask
ExtensionRequirements {
builtin: vec!["developer".to_string()],
external: Vec::new(),
remote: Vec::new(),
}
}
}

View File

@@ -128,6 +128,16 @@ enum Command {
)]
extension: Vec<String>,
/// Add remote extensions with a URL
#[arg(
long = "with-remote-extension",
value_name = "URL",
help = "Add remote extensions (can be specified multiple times)",
long_help = "Add remote extensions from a URL. Can be specified multiple times. Format: 'url...'",
action = clap::ArgAction::Append
)]
remote_extension: Vec<String>,
/// Add builtin extensions by name
#[arg(
long = "with-builtin",
@@ -203,6 +213,16 @@ enum Command {
)]
extension: Vec<String>,
/// Add remote extensions
#[arg(
long = "with-remote-extension",
value_name = "URL",
help = "Add remote extensions (can be specified multiple times)",
long_help = "Add remote extensions. Can be specified multiple times. Format: 'url...'",
action = clap::ArgAction::Append
)]
remote_extension: Vec<String>,
/// Add builtin extensions by name
#[arg(
long = "with-builtin",
@@ -323,6 +343,7 @@ pub async fn cli() -> Result<()> {
resume,
debug,
extension,
remote_extension,
builtin,
}) => {
match command {
@@ -336,6 +357,7 @@ pub async fn cli() -> Result<()> {
identifier.map(extract_identifier),
resume,
extension,
remote_extension,
builtin,
debug,
)
@@ -357,6 +379,7 @@ pub async fn cli() -> Result<()> {
resume,
debug,
extension,
remote_extension,
builtin,
}) => {
let contents = match (instructions, input_text) {
@@ -385,6 +408,7 @@ pub async fn cli() -> Result<()> {
identifier.map(extract_identifier),
resume,
extension,
remote_extension,
builtin,
debug,
)
@@ -468,7 +492,7 @@ pub async fn cli() -> Result<()> {
return Ok(());
} else {
// Run session command by default
let mut session = build_session(None, false, vec![], vec![], false).await;
let mut session = build_session(None, false, vec![], vec![], vec![], false).await;
setup_logging(
session.session_file().file_stem().and_then(|s| s.to_str()),
None,

View File

@@ -85,6 +85,7 @@ async fn run_eval(
None,
false,
requirements.external,
requirements.remote,
requirements.builtin,
false,
)

View File

@@ -14,6 +14,7 @@ pub async fn build_session(
identifier: Option<Identifier>,
resume: bool,
extensions: Vec<String>,
remote_extensions: Vec<String>,
builtins: Vec<String>,
debug: bool,
) -> Session {
@@ -126,6 +127,14 @@ pub async fn build_session(
}
}
// Add remote extensions if provided
for extension_str in remote_extensions {
if let Err(e) = session.add_remote_extension(extension_str).await {
eprintln!("Failed to start extension: {}", e);
process::exit(1);
}
}
// Add builtin extensions
for builtin in builtins {
if let Err(e) = session.add_builtin(builtin).await {

View File

@@ -172,6 +172,37 @@ impl Session {
Ok(())
}
/// Add a remote extension to the session
///
/// # Arguments
/// * `extension_url` - URL of the server
pub async fn add_remote_extension(&mut self, extension_url: String) -> Result<()> {
let name: String = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(8)
.map(char::from)
.collect();
let config = ExtensionConfig::Sse {
name,
uri: extension_url,
envs: Envs::new(HashMap::new()),
description: Some(goose::config::DEFAULT_EXTENSION_DESCRIPTION.to_string()),
// TODO: should set timeout
timeout: Some(goose::config::DEFAULT_EXTENSION_TIMEOUT),
};
self.agent
.add_extension(config)
.await
.map_err(|e| anyhow::anyhow!("Failed to start extension: {}", e))?;
// Invalidate the completion cache when a new extension is added
self.invalidate_completion_cache().await;
Ok(())
}
/// Add a builtin extension to the session
///
/// # Arguments