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
|
||||
|
||||
Reference in New Issue
Block a user