Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 39 additions & 36 deletions crates/goose-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,14 @@ pub struct InputConfig {
pub additional_system_prompt: Option<String>,
}

#[derive(Debug)]
pub struct RecipeInfo {
pub session_settings: Option<SessionSettings>,
pub sub_recipes: Option<Vec<goose::recipe::SubRecipe>>,
pub final_output_response: Option<goose::recipe::Response>,
pub retry_config: Option<goose::agents::types::RetryConfig>,
}

pub async fn cli() -> Result<()> {
let cli = Cli::parse();

Expand Down Expand Up @@ -771,6 +779,7 @@ pub async fn cli() -> Result<()> {
quiet: false,
sub_recipes: None,
final_output_response: None,
retry_config: None,
})
.await;
setup_logging(
Expand Down Expand Up @@ -828,27 +837,19 @@ pub async fn cli() -> Result<()> {
provider,
model,
}) => {
let (input_config, session_settings, sub_recipes, final_output_response) = match (
instructions,
input_text,
recipe,
) {
let (input_config, recipe_info) = match (instructions, input_text, recipe) {
(Some(file), _, _) if file == "-" => {
let mut input = String::new();
std::io::stdin()
.read_to_string(&mut input)
.expect("Failed to read from stdin");

(
InputConfig {
contents: Some(input),
extensions_override: None,
additional_system_prompt: system,
},
None,
None,
None,
)
let input_config = InputConfig {
contents: Some(input),
extensions_override: None,
additional_system_prompt: system,
};
(input_config, None)
}
(Some(file), _, _) => {
let contents = std::fs::read_to_string(&file).unwrap_or_else(|err| {
Expand All @@ -858,27 +859,21 @@ pub async fn cli() -> Result<()> {
);
std::process::exit(1);
});
(
InputConfig {
contents: Some(contents),
extensions_override: None,
additional_system_prompt: None,
},
None,
None,
None,
)
let input_config = InputConfig {
contents: Some(contents),
extensions_override: None,
additional_system_prompt: None,
};
(input_config, None)
}
(_, Some(text), _) => (
InputConfig {
(_, Some(text), _) => {
let input_config = InputConfig {
contents: Some(text),
extensions_override: None,
additional_system_prompt: system,
},
None,
None,
None,
),
};
(input_config, None)
}
(_, _, Some(recipe_name)) => {
if explain {
explain_recipe(&recipe_name, params)?;
Expand All @@ -891,7 +886,9 @@ pub async fn cli() -> Result<()> {
}
return Ok(());
}
extract_recipe_info_from_cli(recipe_name, params, additional_sub_recipes)?
let (input_config, recipe_info) =
extract_recipe_info_from_cli(recipe_name, params, additional_sub_recipes)?;
(input_config, Some(recipe_info))
}
(None, None, None) => {
eprintln!("Error: Must provide either --instructions (-i), --text (-t), or --recipe. Use -i - for stdin.");
Expand All @@ -909,7 +906,9 @@ pub async fn cli() -> Result<()> {
builtins,
extensions_override: input_config.extensions_override,
additional_system_prompt: input_config.additional_system_prompt,
settings: session_settings,
settings: recipe_info
.as_ref()
.and_then(|r| r.session_settings.clone()),
provider,
model,
debug,
Expand All @@ -918,8 +917,11 @@ pub async fn cli() -> Result<()> {
scheduled_job_id,
interactive, // Use the interactive flag from the Run command
quiet,
sub_recipes,
final_output_response,
sub_recipes: recipe_info.as_ref().and_then(|r| r.sub_recipes.clone()),
final_output_response: recipe_info
.as_ref()
.and_then(|r| r.final_output_response.clone()),
retry_config: recipe_info.as_ref().and_then(|r| r.retry_config.clone()),
})
.await;

Expand Down Expand Up @@ -1051,6 +1053,7 @@ pub async fn cli() -> Result<()> {
quiet: false,
sub_recipes: None,
final_output_response: None,
retry_config: None,
})
.await;
setup_logging(
Expand Down
1 change: 1 addition & 0 deletions crates/goose-cli/src/commands/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub async fn agent_generator(
quiet: false,
sub_recipes: None,
final_output_response: None,
retry_config: None,
})
.await;

Expand Down
1 change: 1 addition & 0 deletions crates/goose-cli/src/commands/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ async fn process_message_streaming(
schedule_id: None,
execution_mode: None,
max_turns: None,
retry_config: None,
};

// Get response from agent
Expand Down
49 changes: 28 additions & 21 deletions crates/goose-cli/src/recipes/extract_from_cli.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
use std::path::PathBuf;

use anyhow::{anyhow, Result};
use goose::recipe::{Response, SubRecipe};
use goose::recipe::SubRecipe;

use crate::recipes::print_recipe::print_recipe_info;
use crate::recipes::recipe::load_recipe;
use crate::recipes::search_recipe::retrieve_recipe_file;
use crate::{cli::InputConfig, session::SessionSettings};
use crate::{
cli::{InputConfig, RecipeInfo},
session::SessionSettings,
};

#[allow(clippy::type_complexity)]
pub fn extract_recipe_info_from_cli(
recipe_name: String,
params: Vec<(String, String)>,
additional_sub_recipes: Vec<String>,
) -> Result<(
InputConfig,
Option<SessionSettings>,
Option<Vec<SubRecipe>>,
Option<Response>,
)> {
) -> Result<(InputConfig, RecipeInfo)> {
let recipe = load_recipe(&recipe_name, params.clone()).unwrap_or_else(|err| {
eprintln!("{}: {}", console::style("Error").red().bold(), err);
std::process::exit(1);
Expand Down Expand Up @@ -49,20 +46,24 @@ pub fn extract_recipe_info_from_cli(
}
}
}
Ok((
InputConfig {
contents: recipe.prompt.filter(|s| !s.trim().is_empty()),
extensions_override: recipe.extensions,
additional_system_prompt: recipe.instructions,
},
recipe.settings.map(|s| SessionSettings {
let input_config = InputConfig {
contents: recipe.prompt.filter(|s| !s.trim().is_empty()),
extensions_override: recipe.extensions,
additional_system_prompt: recipe.instructions,
};

let recipe_info = RecipeInfo {
session_settings: recipe.settings.map(|s| SessionSettings {
goose_provider: s.goose_provider,
goose_model: s.goose_model,
temperature: s.temperature,
}),
Some(all_sub_recipes),
recipe.response,
))
sub_recipes: Some(all_sub_recipes),
final_output_response: recipe.response,
retry_config: recipe.retry,
};

Ok((input_config, recipe_info))
}

fn extract_recipe_name(recipe_identifier: &str) -> String {
Expand Down Expand Up @@ -93,8 +94,11 @@ mod tests {
let params = vec![("name".to_string(), "my_value".to_string())];
let recipe_name = recipe_path.to_str().unwrap().to_string();

let (input_config, settings, sub_recipes, response) =
let (input_config, recipe_info) =
extract_recipe_info_from_cli(recipe_name, params, Vec::new()).unwrap();
let settings = recipe_info.session_settings;
let sub_recipes = recipe_info.sub_recipes;
let response = recipe_info.final_output_response;

assert_eq!(input_config.contents, Some("test_prompt".to_string()));
assert_eq!(
Expand Down Expand Up @@ -149,8 +153,11 @@ mod tests {
sub_recipe2_path.to_string_lossy().to_string(),
];

let (input_config, settings, sub_recipes, response) =
let (input_config, recipe_info) =
extract_recipe_info_from_cli(recipe_name, params, additional_sub_recipes).unwrap();
let settings = recipe_info.session_settings;
let sub_recipes = recipe_info.sub_recipes;
let response = recipe_info.final_output_response;

assert_eq!(input_config.contents, Some("test_prompt".to_string()));
assert_eq!(
Expand Down
6 changes: 6 additions & 0 deletions crates/goose-cli/src/session/builder.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use console::style;
use goose::agents::extension::ExtensionError;
use goose::agents::types::RetryConfig;
use goose::agents::Agent;
use goose::config::{Config, ExtensionConfig, ExtensionConfigManager};
use goose::providers::create;
Expand Down Expand Up @@ -60,6 +61,8 @@ pub struct SessionBuilderConfig {
pub sub_recipes: Option<Vec<SubRecipe>>,
/// Final output expected response
pub final_output_response: Option<Response>,
/// Retry configuration for automated validation and recovery
pub retry_config: Option<RetryConfig>,
}

/// Offers to help debug an extension failure by creating a minimal debugging session
Expand Down Expand Up @@ -138,6 +141,7 @@ async fn offer_extension_debugging_help(
None,
None,
None,
None,
);

// Process the debugging request
Expand Down Expand Up @@ -407,6 +411,7 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> Session {
session_config.scheduled_job_id.clone(),
session_config.max_turns,
edit_mode,
session_config.retry_config.clone(),
);

// Add extensions if provided
Expand Down Expand Up @@ -602,6 +607,7 @@ mod tests {
quiet: false,
sub_recipes: None,
final_output_response: None,
retry_config: None,
};

assert_eq!(config.extensions.len(), 1);
Expand Down
5 changes: 5 additions & 0 deletions crates/goose-cli/src/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use anyhow::{Context, Result};
use completion::GooseCompleter;
use etcetera::{choose_app_strategy, AppStrategy};
use goose::agents::extension::{Envs, ExtensionConfig};
use goose::agents::types::RetryConfig;
use goose::agents::{Agent, SessionConfig};
use goose::config::Config;
use goose::message::{Message, MessageContent};
Expand Down Expand Up @@ -64,6 +65,7 @@ pub struct Session {
scheduled_job_id: Option<String>, // ID of the scheduled job that triggered this session
max_turns: Option<u32>,
edit_mode: Option<EditMode>,
retry_config: Option<RetryConfig>,
}

// Cache structure for completion data
Expand Down Expand Up @@ -127,6 +129,7 @@ impl Session {
scheduled_job_id: Option<String>,
max_turns: Option<u32>,
edit_mode: Option<EditMode>,
retry_config: Option<RetryConfig>,
) -> Self {
let messages = if let Some(session_file) = &session_file {
match session::read_messages(session_file) {
Expand All @@ -151,6 +154,7 @@ impl Session {
scheduled_job_id,
max_turns,
edit_mode,
retry_config,
}
}

Expand Down Expand Up @@ -879,6 +883,7 @@ impl Session {
schedule_id: self.scheduled_job_id.clone(),
execution_mode: None,
max_turns: self.max_turns,
retry_config: self.retry_config.clone(),
}
});
let mut stream = self
Expand Down
2 changes: 2 additions & 0 deletions crates/goose-server/src/routes/reply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ async fn handler(
schedule_id: request.scheduled_job_id.clone(),
execution_mode: None,
max_turns: None,
retry_config: None,
}),
)
.await
Expand Down Expand Up @@ -368,6 +369,7 @@ async fn ask_handler(
schedule_id: request.scheduled_job_id.clone(),
execution_mode: None,
max_turns: None,
retry_config: None,
}),
)
.await
Expand Down
Loading
Loading