mirror of
https://github.com/aljazceru/goose.git
synced 2025-12-17 22:24:21 +01:00
Add -with-remote-extension (#2062)
This commit is contained in:
@@ -77,6 +77,7 @@ impl Evaluation for ComputerControllerScript {
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["computercontroller".to_string()],
|
builtin: vec!["computercontroller".to_string()],
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ impl Evaluation for ComputerControllerWebScrape {
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["computercontroller".to_string()],
|
builtin: vec!["computercontroller".to_string()],
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ impl Evaluation for DeveloperCreateFile {
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["developer".to_string()],
|
builtin: vec!["developer".to_string()],
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ impl Evaluation for DeveloperListFiles {
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["developer".to_string()],
|
builtin: vec!["developer".to_string()],
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ impl Evaluation for SimpleRepoCloneTest {
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["developer".to_string()],
|
builtin: vec!["developer".to_string()],
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ impl Evaluation for DeveloperImage {
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["developer".to_string()],
|
builtin: vec!["developer".to_string()],
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ impl Evaluation for DeveloperSearchReplace {
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["developer".to_string()],
|
builtin: vec!["developer".to_string()],
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ impl Evaluation for MemoryRememberMemory {
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["memory".to_string()],
|
builtin: vec!["memory".to_string()],
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ pub enum EvaluationMetric {
|
|||||||
pub struct ExtensionRequirements {
|
pub struct ExtensionRequirements {
|
||||||
pub builtin: Vec<String>,
|
pub builtin: Vec<String>,
|
||||||
pub external: Vec<String>,
|
pub external: Vec<String>,
|
||||||
|
pub remote: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
@@ -54,6 +55,7 @@ pub trait Evaluation: Send + Sync {
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: Vec::new(),
|
builtin: Vec::new(),
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ impl Evaluation for BlogSummary {
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["developer".to_string()],
|
builtin: vec!["developer".to_string()],
|
||||||
external: vec!["uvx mcp-server-fetch".to_string()],
|
external: vec!["uvx mcp-server-fetch".to_string()],
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ impl Evaluation for FlappyBird {
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["developer".to_string()],
|
builtin: vec!["developer".to_string()],
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ impl Evaluation for GooseWiki {
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["developer".to_string()],
|
builtin: vec!["developer".to_string()],
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ Present the information in order of significance or quality. Focus specifically
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["developer".to_string()],
|
builtin: vec!["developer".to_string()],
|
||||||
external: vec!["uvx mcp-server-fetch".to_string()],
|
external: vec!["uvx mcp-server-fetch".to_string()],
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ After writing the script, run it using python3 and show the results. Do not ask
|
|||||||
ExtensionRequirements {
|
ExtensionRequirements {
|
||||||
builtin: vec!["developer".to_string()],
|
builtin: vec!["developer".to_string()],
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
|
remote: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,16 @@ enum Command {
|
|||||||
)]
|
)]
|
||||||
extension: Vec<String>,
|
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
|
/// Add builtin extensions by name
|
||||||
#[arg(
|
#[arg(
|
||||||
long = "with-builtin",
|
long = "with-builtin",
|
||||||
@@ -203,6 +213,16 @@ enum Command {
|
|||||||
)]
|
)]
|
||||||
extension: Vec<String>,
|
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
|
/// Add builtin extensions by name
|
||||||
#[arg(
|
#[arg(
|
||||||
long = "with-builtin",
|
long = "with-builtin",
|
||||||
@@ -323,6 +343,7 @@ pub async fn cli() -> Result<()> {
|
|||||||
resume,
|
resume,
|
||||||
debug,
|
debug,
|
||||||
extension,
|
extension,
|
||||||
|
remote_extension,
|
||||||
builtin,
|
builtin,
|
||||||
}) => {
|
}) => {
|
||||||
match command {
|
match command {
|
||||||
@@ -336,6 +357,7 @@ pub async fn cli() -> Result<()> {
|
|||||||
identifier.map(extract_identifier),
|
identifier.map(extract_identifier),
|
||||||
resume,
|
resume,
|
||||||
extension,
|
extension,
|
||||||
|
remote_extension,
|
||||||
builtin,
|
builtin,
|
||||||
debug,
|
debug,
|
||||||
)
|
)
|
||||||
@@ -357,6 +379,7 @@ pub async fn cli() -> Result<()> {
|
|||||||
resume,
|
resume,
|
||||||
debug,
|
debug,
|
||||||
extension,
|
extension,
|
||||||
|
remote_extension,
|
||||||
builtin,
|
builtin,
|
||||||
}) => {
|
}) => {
|
||||||
let contents = match (instructions, input_text) {
|
let contents = match (instructions, input_text) {
|
||||||
@@ -385,6 +408,7 @@ pub async fn cli() -> Result<()> {
|
|||||||
identifier.map(extract_identifier),
|
identifier.map(extract_identifier),
|
||||||
resume,
|
resume,
|
||||||
extension,
|
extension,
|
||||||
|
remote_extension,
|
||||||
builtin,
|
builtin,
|
||||||
debug,
|
debug,
|
||||||
)
|
)
|
||||||
@@ -468,7 +492,7 @@ pub async fn cli() -> Result<()> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
} else {
|
||||||
// Run session command by default
|
// 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(
|
setup_logging(
|
||||||
session.session_file().file_stem().and_then(|s| s.to_str()),
|
session.session_file().file_stem().and_then(|s| s.to_str()),
|
||||||
None,
|
None,
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ async fn run_eval(
|
|||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
requirements.external,
|
requirements.external,
|
||||||
|
requirements.remote,
|
||||||
requirements.builtin,
|
requirements.builtin,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ pub async fn build_session(
|
|||||||
identifier: Option<Identifier>,
|
identifier: Option<Identifier>,
|
||||||
resume: bool,
|
resume: bool,
|
||||||
extensions: Vec<String>,
|
extensions: Vec<String>,
|
||||||
|
remote_extensions: Vec<String>,
|
||||||
builtins: Vec<String>,
|
builtins: Vec<String>,
|
||||||
debug: bool,
|
debug: bool,
|
||||||
) -> Session {
|
) -> 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
|
// Add builtin extensions
|
||||||
for builtin in builtins {
|
for builtin in builtins {
|
||||||
if let Err(e) = session.add_builtin(builtin).await {
|
if let Err(e) = session.add_builtin(builtin).await {
|
||||||
|
|||||||
@@ -172,6 +172,37 @@ impl Session {
|
|||||||
Ok(())
|
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
|
/// Add a builtin extension to the session
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
|||||||
@@ -376,7 +376,7 @@ goose session --with-builtin developer --with-builtin computercontroller
|
|||||||
To enable an extension while starting a session, run the following command:
|
To enable an extension while starting a session, run the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
goose session --with-extension "{extension command}" --with-extension "{antoher extension command}"
|
goose session --with-extension "{extension command}" --with-extension "{another extension command}"
|
||||||
```
|
```
|
||||||
|
|
||||||
For example, to start a session with the [Fetch extension](https://github.com/modelcontextprotocol/servers/tree/main/src/fetch), you'd run:
|
For example, to start a session with the [Fetch extension](https://github.com/modelcontextprotocol/servers/tree/main/src/fetch), you'd run:
|
||||||
@@ -404,9 +404,22 @@ goose session --with-extension "GITHUB_PERSONAL_ACCESS_TOKEN=<YOUR_TOKEN> npx -y
|
|||||||
Note that you'll need [Node.js](https://nodejs.org/) installed on your system to run this command, as it uses `npx`.
|
Note that you'll need [Node.js](https://nodejs.org/) installed on your system to run this command, as it uses `npx`.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
### Remote Extensions over SSE
|
||||||
|
|
||||||
|
To enable a remote extension over SSE while starting a session, run the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
goose session --with-remote-extension "{extension URL}" --with-remote-extension "{another extension URL}"
|
||||||
|
```
|
||||||
|
|
||||||
|
For example, to start a session with a remote extension running on localhost on port 8080, you'd run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
goose session --with-remote-extension "http://localhost:8080/sse"
|
||||||
|
```
|
||||||
|
|
||||||
## Developing Extensions
|
## Developing Extensions
|
||||||
|
|
||||||
Goose extensions are implemented with MCP, a standard protocol that allows AI models and agents to securely connect with local or remote resources. Learn how to build your own [extension as an MCP server](https://modelcontextprotocol.io/quickstart/server).
|
Goose extensions are implemented with MCP, a standard protocol that allows AI models and agents to securely connect with local or remote resources. Learn how to build your own [extension as an MCP server](https://modelcontextprotocol.io/quickstart/server).
|
||||||
|
|
||||||
|
|
||||||
[extensions-directory]: https://block.github.io/goose/v1/extensions
|
[extensions-directory]: https://block.github.io/goose/v1/extensions
|
||||||
|
|||||||
@@ -79,6 +79,24 @@ goose configure
|
|||||||
goose session --with-extension "GITHUB_PERSONAL_ACCESS_TOKEN=<YOUR_TOKEN> npx -y @modelcontextprotocol/server-github"
|
goose session --with-extension "GITHUB_PERSONAL_ACCESS_TOKEN=<YOUR_TOKEN> npx -y @modelcontextprotocol/server-github"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- Start a session with the specified remote extension over SSE
|
||||||
|
|
||||||
|
**Options:**
|
||||||
|
|
||||||
|
**`--with-remote-extension <url>`**
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
goose session --with-remote-extension <url>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
goose session --with-remote-extension "http://localhost:8080/sse"
|
||||||
|
```
|
||||||
|
|
||||||
- Start a session with the specified [built-in extension](/docs/getting-started/using-extensions#built-in-extensions) enabled (e.g. 'developer')
|
- Start a session with the specified [built-in extension](/docs/getting-started/using-extensions#built-in-extensions) enabled (e.g. 'developer')
|
||||||
|
|
||||||
**Options:**
|
**Options:**
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ goose run -n my-project -r
|
|||||||
|
|
||||||
### Working with Extensions
|
### Working with Extensions
|
||||||
|
|
||||||
If you want to ensure specific extensions are available when running your task, you can indicate this with arguments. This can be done using the `--with-extension` or `--with-builtin` flags:
|
If you want to ensure specific extensions are available when running your task, you can indicate this with arguments. This can be done using the `--with-extension`, `--with-remote-extension`, or `--with-builtin` flags:
|
||||||
|
|
||||||
- Using built-in extensions e.g developer and computercontroller extensions
|
- Using built-in extensions e.g developer and computercontroller extensions
|
||||||
|
|
||||||
@@ -106,6 +106,12 @@ goose run --with-builtin "developer,computercontroller" -t "your instructions"
|
|||||||
goose run --with-extension "ENV1=value1 custom-extension-args" -t "your instructions"
|
goose run --with-extension "ENV1=value1 custom-extension-args" -t "your instructions"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- Using remote extensions
|
||||||
|
|
||||||
|
```bash
|
||||||
|
goose run --with-remote-extension "url" -t "your instructions"
|
||||||
|
```
|
||||||
|
|
||||||
## Common Use Cases
|
## Common Use Cases
|
||||||
|
|
||||||
### Running Script Files
|
### Running Script Files
|
||||||
|
|||||||
Reference in New Issue
Block a user