mirror of
https://github.com/aljazceru/goose.git
synced 2025-12-18 06:34:26 +01:00
Streamable HTTP CLI flag (#3394)
This commit is contained in:
@@ -341,6 +341,16 @@ enum Command {
|
||||
)]
|
||||
remote_extensions: Vec<String>,
|
||||
|
||||
/// Add streamable HTTP extensions with a URL
|
||||
#[arg(
|
||||
long = "with-streamable-http-extension",
|
||||
value_name = "URL",
|
||||
help = "Add streamable HTTP extensions (can be specified multiple times)",
|
||||
long_help = "Add streamable HTTP extensions from a URL. Can be specified multiple times. Format: 'url...'",
|
||||
action = clap::ArgAction::Append
|
||||
)]
|
||||
streamable_http_extensions: Vec<String>,
|
||||
|
||||
/// Add builtin extensions by name
|
||||
#[arg(
|
||||
long = "with-builtin",
|
||||
@@ -509,6 +519,16 @@ enum Command {
|
||||
)]
|
||||
remote_extensions: Vec<String>,
|
||||
|
||||
/// Add streamable HTTP extensions
|
||||
#[arg(
|
||||
long = "with-streamable-http-extension",
|
||||
value_name = "URL",
|
||||
help = "Add streamable HTTP extensions (can be specified multiple times)",
|
||||
long_help = "Add streamable HTTP extensions. Can be specified multiple times. Format: 'url...'",
|
||||
action = clap::ArgAction::Append
|
||||
)]
|
||||
streamable_http_extensions: Vec<String>,
|
||||
|
||||
/// Add builtin extensions by name
|
||||
#[arg(
|
||||
long = "with-builtin",
|
||||
@@ -674,6 +694,7 @@ pub async fn cli() -> Result<()> {
|
||||
max_turns,
|
||||
extensions,
|
||||
remote_extensions,
|
||||
streamable_http_extensions,
|
||||
builtins,
|
||||
}) => {
|
||||
return match command {
|
||||
@@ -714,6 +735,7 @@ pub async fn cli() -> Result<()> {
|
||||
no_session: false,
|
||||
extensions,
|
||||
remote_extensions,
|
||||
streamable_http_extensions,
|
||||
builtins,
|
||||
extensions_override: None,
|
||||
additional_system_prompt: None,
|
||||
@@ -774,6 +796,7 @@ pub async fn cli() -> Result<()> {
|
||||
max_turns,
|
||||
extensions,
|
||||
remote_extensions,
|
||||
streamable_http_extensions,
|
||||
builtins,
|
||||
params,
|
||||
explain,
|
||||
@@ -863,6 +886,7 @@ pub async fn cli() -> Result<()> {
|
||||
no_session,
|
||||
extensions,
|
||||
remote_extensions,
|
||||
streamable_http_extensions,
|
||||
builtins,
|
||||
extensions_override: input_config.extensions_override,
|
||||
additional_system_prompt: input_config.additional_system_prompt,
|
||||
@@ -990,6 +1014,7 @@ pub async fn cli() -> Result<()> {
|
||||
no_session: false,
|
||||
extensions: Vec::new(),
|
||||
remote_extensions: Vec::new(),
|
||||
streamable_http_extensions: Vec::new(),
|
||||
builtins: Vec::new(),
|
||||
extensions_override: None,
|
||||
additional_system_prompt: None,
|
||||
|
||||
@@ -37,6 +37,7 @@ pub async fn agent_generator(
|
||||
no_session: false,
|
||||
extensions: requirements.external,
|
||||
remote_extensions: requirements.remote,
|
||||
streamable_http_extensions: Vec::new(),
|
||||
builtins: requirements.builtin,
|
||||
extensions_override: None,
|
||||
additional_system_prompt: None,
|
||||
|
||||
@@ -29,6 +29,8 @@ pub struct SessionBuilderConfig {
|
||||
pub extensions: Vec<String>,
|
||||
/// List of remote extension commands to add
|
||||
pub remote_extensions: Vec<String>,
|
||||
/// List of streamable HTTP extension commands to add
|
||||
pub streamable_http_extensions: Vec<String>,
|
||||
/// List of builtin extension commands to add
|
||||
pub builtins: Vec<String>,
|
||||
/// List of extensions to enable, enable only this set and ignore configured ones
|
||||
@@ -454,6 +456,43 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> Session {
|
||||
}
|
||||
}
|
||||
|
||||
// Add streamable HTTP extensions if provided
|
||||
for extension_str in session_config.streamable_http_extensions {
|
||||
if let Err(e) = session
|
||||
.add_streamable_http_extension(extension_str.clone())
|
||||
.await
|
||||
{
|
||||
eprintln!(
|
||||
"{}",
|
||||
style(format!(
|
||||
"Warning: Failed to start streamable HTTP extension '{}': {}",
|
||||
extension_str, e
|
||||
))
|
||||
.yellow()
|
||||
);
|
||||
eprintln!(
|
||||
"{}",
|
||||
style(format!(
|
||||
"Continuing without streamable HTTP extension '{}'",
|
||||
extension_str
|
||||
))
|
||||
.yellow()
|
||||
);
|
||||
|
||||
// Offer debugging help
|
||||
if let Err(debug_err) = offer_extension_debugging_help(
|
||||
&extension_str,
|
||||
&e.to_string(),
|
||||
Arc::clone(&provider_for_display),
|
||||
session_config.interactive,
|
||||
)
|
||||
.await
|
||||
{
|
||||
eprintln!("Note: Could not start debugging session: {}", debug_err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add builtin extensions
|
||||
for builtin in session_config.builtins {
|
||||
if let Err(e) = session.add_builtin(builtin.clone()).await {
|
||||
@@ -531,6 +570,7 @@ mod tests {
|
||||
no_session: false,
|
||||
extensions: vec!["echo test".to_string()],
|
||||
remote_extensions: vec!["http://example.com".to_string()],
|
||||
streamable_http_extensions: vec!["http://example.com/streamable".to_string()],
|
||||
builtins: vec!["developer".to_string()],
|
||||
extensions_override: None,
|
||||
additional_system_prompt: Some("Test prompt".to_string()),
|
||||
@@ -549,6 +589,7 @@ mod tests {
|
||||
|
||||
assert_eq!(config.extensions.len(), 1);
|
||||
assert_eq!(config.remote_extensions.len(), 1);
|
||||
assert_eq!(config.streamable_http_extensions.len(), 1);
|
||||
assert_eq!(config.builtins.len(), 1);
|
||||
assert!(config.debug);
|
||||
assert_eq!(config.max_tool_repetitions, Some(5));
|
||||
@@ -567,6 +608,7 @@ mod tests {
|
||||
assert!(!config.no_session);
|
||||
assert!(config.extensions.is_empty());
|
||||
assert!(config.remote_extensions.is_empty());
|
||||
assert!(config.streamable_http_extensions.is_empty());
|
||||
assert!(config.builtins.is_empty());
|
||||
assert!(config.extensions_override.is_none());
|
||||
assert!(config.additional_system_prompt.is_none());
|
||||
|
||||
@@ -244,6 +244,40 @@ impl Session {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add a streamable HTTP extension to the session
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `extension_url` - URL of the server
|
||||
pub async fn add_streamable_http_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::StreamableHttp {
|
||||
name,
|
||||
uri: extension_url,
|
||||
envs: Envs::new(HashMap::new()),
|
||||
env_keys: Vec::new(),
|
||||
headers: HashMap::new(),
|
||||
description: Some(goose::config::DEFAULT_EXTENSION_DESCRIPTION.to_string()),
|
||||
// TODO: should set timeout
|
||||
timeout: Some(goose::config::DEFAULT_EXTENSION_TIMEOUT),
|
||||
bundled: None,
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
@@ -291,6 +291,26 @@ For example, a deeplink for a URL like `http://localhost:8080/sse` would look li
|
||||
|
||||
```
|
||||
goose://extension?url=http%3A%2F%2Flocalhost%3A8080%2Fsse&timeout=<timeout>&id=<id>&name=<name>&description=<description>>
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="streamable_http" label="Streaming HTTP">
|
||||
```
|
||||
goose://extension?url=<remote-streamable-http-url>&type=streamable_http&id=<id>&name=<n>&description=<description>
|
||||
```
|
||||
|
||||
Parameters:
|
||||
- `url`: The URL of the remote Streaming HTTP server
|
||||
- `type`: Must be set to `streamable_http` to specify the protocol type
|
||||
- `timeout`: Maximum time (in seconds) to wait for extension responses
|
||||
- `id`: Unique identifier for the extension
|
||||
- `name`: Display name for the extension
|
||||
- `description`: Brief description of the extension's functionality
|
||||
|
||||
For example, a deeplink for a URL like `https://example.com/streamable` would look like this when URL-encoded:
|
||||
|
||||
```
|
||||
goose://extension?url=https%3A%2F%2Fexample.com%2Fstreamable&type=streamable_http&timeout=<timeout>&id=<id>&name=<n>&description=<description>
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@@ -598,8 +618,22 @@ For example, to start a session with a remote extension over SSE running on loca
|
||||
goose session --with-remote-extension "http://localhost:8080/sse"
|
||||
```
|
||||
|
||||
### Remote Extensions over Streaming HTTP
|
||||
|
||||
To enable a remote extension over Streaming HTTP while starting a session, run the following command:
|
||||
|
||||
```bash
|
||||
goose session --with-streamable-http-extension "{extension URL}" --with-streamable-http-extension "{another extension URL}"
|
||||
```
|
||||
|
||||
For example, to start a session with a Streaming HTTP extension, you'd run:
|
||||
|
||||
```bash
|
||||
goose session --with-streamable-http-extension "https://example.com/streamable"
|
||||
```
|
||||
|
||||
## 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).
|
||||
|
||||
[extensions-directory]: https://block.github.io/goose/v1/extensions
|
||||
[extensions-directory]: https://block.github.io/goose/v1/extensions
|
||||
|
||||
@@ -32,7 +32,7 @@ goose configure
|
||||
|
||||
### session [options]
|
||||
|
||||
- Start a session and give it a name
|
||||
#### Start a session and give it a name
|
||||
|
||||
**Options:**
|
||||
|
||||
@@ -43,8 +43,9 @@ goose configure
|
||||
```bash
|
||||
goose session --name <n>
|
||||
```
|
||||
---
|
||||
|
||||
- Resume a previous session
|
||||
#### Resume a previous session
|
||||
|
||||
**Options:**
|
||||
|
||||
@@ -59,8 +60,9 @@ goose configure
|
||||
```bash
|
||||
goose session --resume --id <id>
|
||||
```
|
||||
---
|
||||
|
||||
- Start a session with the specified extension
|
||||
#### Start a session with the specified extension
|
||||
|
||||
**Options:**
|
||||
|
||||
@@ -83,8 +85,9 @@ goose configure
|
||||
```bash
|
||||
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
|
||||
#### Start a session with the specified remote extension over SSE
|
||||
|
||||
**Options:**
|
||||
|
||||
@@ -102,7 +105,48 @@ goose configure
|
||||
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 remote extension over Streaming HTTP
|
||||
|
||||
**Options:**
|
||||
|
||||
**`--with-streamable-http-extension <url>`**
|
||||
|
||||
**Usage:**
|
||||
|
||||
```bash
|
||||
goose session --with-streamable-http-extension <url>
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
goose session --with-streamable-http-extension "https://example.com/streamable"
|
||||
```
|
||||
|
||||
**Advanced Examples:**
|
||||
|
||||
```bash
|
||||
# Start a session with a streamable HTTP extension
|
||||
goose session --with-streamable-http-extension "http://api.example.com"
|
||||
|
||||
# Use multiple streamable HTTP extensions
|
||||
goose session \
|
||||
--with-streamable-http-extension "http://api1.example.com" \
|
||||
--with-streamable-http-extension "http://api2.example.com"
|
||||
|
||||
# Mix different extension types
|
||||
goose session \
|
||||
--with-extension "echo hello" \
|
||||
--with-remote-extension "http://sse.example.com/sse" \
|
||||
--with-streamable-http-extension "http://http.example.com" \
|
||||
--with-builtin "developer"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Start a session with the specified [built-in extension](/docs/getting-started/using-extensions#built-in-extensions) enabled (e.g. 'developer')
|
||||
|
||||
**Options:**
|
||||
|
||||
@@ -119,8 +163,9 @@ goose configure
|
||||
```bash
|
||||
goose session --with-builtin computercontroller
|
||||
```
|
||||
---
|
||||
|
||||
- Enable debug mode to output complete tool responses, detailed parameter values, and full file paths
|
||||
#### Enable debug mode to output complete tool responses, detailed parameter values, and full file paths
|
||||
|
||||
**Options:**
|
||||
|
||||
@@ -131,8 +176,9 @@ goose configure
|
||||
```bash
|
||||
goose session --name my-session --debug
|
||||
```
|
||||
---
|
||||
|
||||
- Limit the maximum number of turns the agent can take before asking for user input to continue
|
||||
#### Limit the maximum number of turns the agent can take before asking for user input to continue
|
||||
|
||||
**Options:**
|
||||
|
||||
@@ -144,7 +190,9 @@ goose configure
|
||||
goose session --max-turns 50
|
||||
```
|
||||
|
||||
- Set the [maximum number of turns](/docs/guides/smart-context-management#maximum-turns) allowed without user input (default: 1000)
|
||||
---
|
||||
|
||||
#### Set the [maximum number of turns](/docs/guides/smart-context-management#maximum-turns) allowed without user input (default: 1000)
|
||||
|
||||
**Options:**
|
||||
|
||||
@@ -170,6 +218,7 @@ goose configure
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### session list [options]
|
||||
|
||||
List all saved sessions.
|
||||
@@ -326,6 +375,8 @@ Execute commands from an instruction file or stdin. Check out the [full guide](/
|
||||
- **`--recipe <RECIPE_FILE_NAME> <OPTIONS>`**: Load a custom recipe in current session
|
||||
- **`-p, --path <PATH>`**: Path for this run session (e.g. `./playground.jsonl`)
|
||||
- **`--with-extension <COMMAND>`**: Add stdio extensions (can be used multiple times in the same command)
|
||||
- **`--with-remote-extension <URL>`**: Add remote extensions over SSE (can be used multiple times in the same command)
|
||||
- **`--with-streamable-http-extension <URL>`**: Add remote extensions over Streaming HTTP (can be used multiple times in the same command)
|
||||
- **`--with-builtin <n>`**: Add builtin extensions by name (e.g., 'developer' or multiple: 'developer,github')
|
||||
- **`--debug`**: Output complete tool responses, detailed parameter values, and full file paths
|
||||
- **`--max-turns <NUMBER>`**: [Maximum number of turns](/docs/guides/smart-context-management#maximum-turns) allowed without user input (default: 1000)
|
||||
|
||||
@@ -100,7 +100,7 @@ goose run --no-session -t "your command here"
|
||||
|
||||
### 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`, `--with-remote-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`, `--with-streamable-http-extension`, or `--with-builtin` flags:
|
||||
|
||||
- Using built-in extensions e.g developer and computercontroller extensions
|
||||
|
||||
@@ -120,6 +120,12 @@ goose run --with-extension "ENV1=value1 custom-extension-args" -t "your instruct
|
||||
goose run --with-remote-extension "url" -t "your instructions"
|
||||
```
|
||||
|
||||
- Using streamable HTTP extensions
|
||||
|
||||
```bash
|
||||
goose run --with-streamable-http-extension "https://example.com/streamable" -t "your instructions"
|
||||
```
|
||||
|
||||
### Debug Mode
|
||||
|
||||
When troubleshooting or developing complex workflows, you can enable debug mode to get more detailed information about tool execution. The `--debug` flag provides:
|
||||
|
||||
Reference in New Issue
Block a user