Remove clippy too_many_lines lint and decompose long functions (#7064)
This commit is contained in:
@@ -337,36 +337,26 @@ async fn load_extensions(
|
||||
agent_ptr
|
||||
}
|
||||
|
||||
pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
|
||||
goose::posthog::set_session_context("cli", session_config.resume);
|
||||
struct ResolvedProviderConfig {
|
||||
provider_name: String,
|
||||
model_name: String,
|
||||
model_config: goose::model::ModelConfig,
|
||||
}
|
||||
|
||||
let config = Config::global();
|
||||
let agent: Agent = Agent::new();
|
||||
|
||||
if session_config.container.is_some() {
|
||||
agent.set_container(session_config.container.clone()).await;
|
||||
}
|
||||
|
||||
let session_manager = agent.config.session_manager.clone();
|
||||
|
||||
let (saved_provider, saved_model_config) = if session_config.resume {
|
||||
if let Some(ref session_id) = session_config.session_id {
|
||||
match session_manager.get_session(session_id, false).await {
|
||||
Ok(session_data) => (session_data.provider_name, session_data.model_config),
|
||||
Err(_) => (None, None),
|
||||
}
|
||||
} else {
|
||||
(None, None)
|
||||
}
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
|
||||
let recipe = session_config.recipe.as_ref();
|
||||
let recipe_settings = recipe.and_then(|r| r.settings.as_ref());
|
||||
fn resolve_provider_and_model(
|
||||
session_config: &SessionBuilderConfig,
|
||||
config: &Config,
|
||||
saved_provider: Option<String>,
|
||||
saved_model_config: Option<goose::model::ModelConfig>,
|
||||
) -> ResolvedProviderConfig {
|
||||
let recipe_settings = session_config
|
||||
.recipe
|
||||
.as_ref()
|
||||
.and_then(|r| r.settings.as_ref());
|
||||
|
||||
let provider_name = session_config
|
||||
.provider
|
||||
.clone()
|
||||
.or(saved_provider)
|
||||
.or_else(|| recipe_settings.and_then(|s| s.goose_provider.clone()))
|
||||
.or_else(|| config.get_goose_provider().ok())
|
||||
@@ -374,6 +364,7 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
|
||||
|
||||
let model_name = session_config
|
||||
.model
|
||||
.clone()
|
||||
.or_else(|| saved_model_config.as_ref().map(|mc| mc.model_name.clone()))
|
||||
.or_else(|| recipe_settings.and_then(|s| s.goose_model.clone()))
|
||||
.or_else(|| config.get_goose_model().ok())
|
||||
@@ -399,6 +390,215 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
|
||||
.with_temperature(temperature)
|
||||
};
|
||||
|
||||
ResolvedProviderConfig {
|
||||
provider_name,
|
||||
model_name,
|
||||
model_config,
|
||||
}
|
||||
}
|
||||
|
||||
async fn resolve_session_id(
|
||||
session_config: &SessionBuilderConfig,
|
||||
session_manager: &goose::session::session_manager::SessionManager,
|
||||
) -> String {
|
||||
if session_config.no_session {
|
||||
let working_dir = std::env::current_dir().expect("Could not get working directory");
|
||||
let session = session_manager
|
||||
.create_session(working_dir, "CLI Session".to_string(), SessionType::Hidden)
|
||||
.await
|
||||
.expect("Could not create session");
|
||||
session.id
|
||||
} else if session_config.resume {
|
||||
if let Some(ref session_id) = session_config.session_id {
|
||||
match session_manager.get_session(session_id, false).await {
|
||||
Ok(_) => session_id.clone(),
|
||||
Err(_) => {
|
||||
output::render_error(&format!(
|
||||
"Cannot resume session {} - no such session exists",
|
||||
style(session_id).cyan()
|
||||
));
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match session_manager.list_sessions().await {
|
||||
Ok(sessions) if !sessions.is_empty() => sessions[0].id.clone(),
|
||||
_ => {
|
||||
output::render_error("Cannot resume - no previous sessions found");
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
session_config.session_id.clone().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_resumed_session_workdir(agent: &Agent, session_id: &str, interactive: bool) {
|
||||
let session = agent
|
||||
.config
|
||||
.session_manager
|
||||
.get_session(session_id, false)
|
||||
.await
|
||||
.unwrap_or_else(|e| {
|
||||
output::render_error(&format!("Failed to read session metadata: {}", e));
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
let current_workdir = std::env::current_dir().expect("Failed to get current working directory");
|
||||
if current_workdir == session.working_dir {
|
||||
return;
|
||||
}
|
||||
|
||||
if interactive {
|
||||
let change_workdir = cliclack::confirm(format!(
|
||||
"{} The original working directory of this session was set to {}. \
|
||||
Your current directory is {}. \
|
||||
Do you want to switch back to the original working directory?",
|
||||
style("WARNING:").yellow(),
|
||||
style(session.working_dir.display()).cyan(),
|
||||
style(current_workdir.display()).cyan(),
|
||||
))
|
||||
.initial_value(true)
|
||||
.interact()
|
||||
.expect("Failed to get user input");
|
||||
|
||||
if change_workdir {
|
||||
if !session.working_dir.exists() {
|
||||
output::render_error(&format!(
|
||||
"Cannot switch to original working directory - {} no longer exists",
|
||||
style(session.working_dir.display()).cyan()
|
||||
));
|
||||
} else if let Err(e) = std::env::set_current_dir(&session.working_dir) {
|
||||
output::render_error(&format!(
|
||||
"Failed to switch to original working directory: {}",
|
||||
e
|
||||
));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
eprintln!(
|
||||
"{}",
|
||||
style(format!(
|
||||
"Warning: Working directory differs from session (current: {}, session: {}). \
|
||||
Staying in current directory.",
|
||||
current_workdir.display(),
|
||||
session.working_dir.display()
|
||||
))
|
||||
.yellow()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async fn resolve_and_load_extensions(
|
||||
agent: Agent,
|
||||
session_config: &SessionBuilderConfig,
|
||||
recipe: Option<&Recipe>,
|
||||
session_id: &str,
|
||||
provider_for_debug: Arc<dyn goose::providers::base::Provider>,
|
||||
) -> Arc<Agent> {
|
||||
for warning in goose::config::get_warnings() {
|
||||
eprintln!("{}", style(format!("Warning: {}", warning)).yellow());
|
||||
}
|
||||
|
||||
let configured_extensions: Vec<ExtensionConfig> = if session_config.resume {
|
||||
agent
|
||||
.config
|
||||
.session_manager
|
||||
.get_session(session_id, false)
|
||||
.await
|
||||
.ok()
|
||||
.and_then(|s| EnabledExtensionsState::from_extension_data(&s.extension_data))
|
||||
.map(|state| state.extensions)
|
||||
.unwrap_or_else(get_enabled_extensions)
|
||||
} else if session_config.no_profile {
|
||||
Vec::new()
|
||||
} else {
|
||||
resolve_extensions_for_new_session(recipe.and_then(|r| r.extensions.as_deref()), None)
|
||||
};
|
||||
|
||||
let cli_flag_extensions = parse_cli_flag_extensions(
|
||||
&session_config.extensions,
|
||||
&session_config.streamable_http_extensions,
|
||||
&session_config.builtins,
|
||||
);
|
||||
|
||||
let mut extensions_to_load: Vec<(String, ExtensionConfig)> = configured_extensions
|
||||
.iter()
|
||||
.map(|cfg| (cfg.name(), cfg.clone()))
|
||||
.collect();
|
||||
extensions_to_load.extend(cli_flag_extensions);
|
||||
|
||||
load_extensions(
|
||||
agent,
|
||||
extensions_to_load,
|
||||
provider_for_debug,
|
||||
session_config.interactive,
|
||||
session_id,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn configure_session_prompts(
|
||||
session: &CliSession,
|
||||
config: &Config,
|
||||
session_config: &SessionBuilderConfig,
|
||||
session_id: &str,
|
||||
) {
|
||||
if let Err(e) = session.agent.persist_extension_state(session_id).await {
|
||||
tracing::warn!("Failed to save extension state: {}", e);
|
||||
}
|
||||
|
||||
session
|
||||
.agent
|
||||
.extend_system_prompt(super::prompt::get_cli_prompt())
|
||||
.await;
|
||||
|
||||
if let Some(ref additional_prompt) = session_config.additional_system_prompt {
|
||||
session
|
||||
.agent
|
||||
.extend_system_prompt(additional_prompt.clone())
|
||||
.await;
|
||||
}
|
||||
|
||||
let system_prompt_file: Option<String> = config.get_param("GOOSE_SYSTEM_PROMPT_FILE_PATH").ok();
|
||||
if let Some(ref path) = system_prompt_file {
|
||||
let override_prompt =
|
||||
std::fs::read_to_string(path).expect("Failed to read system prompt file");
|
||||
session.agent.override_system_prompt(override_prompt).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
|
||||
goose::posthog::set_session_context("cli", session_config.resume);
|
||||
|
||||
let config = Config::global();
|
||||
let agent: Agent = Agent::new();
|
||||
|
||||
if session_config.container.is_some() {
|
||||
agent.set_container(session_config.container.clone()).await;
|
||||
}
|
||||
|
||||
let session_manager = agent.config.session_manager.clone();
|
||||
|
||||
let (saved_provider, saved_model_config) = if session_config.resume {
|
||||
if let Some(ref session_id) = session_config.session_id {
|
||||
match session_manager.get_session(session_id, false).await {
|
||||
Ok(session_data) => (session_data.provider_name, session_data.model_config),
|
||||
Err(_) => (None, None),
|
||||
}
|
||||
} else {
|
||||
(None, None)
|
||||
}
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
|
||||
let resolved =
|
||||
resolve_provider_and_model(&session_config, config, saved_provider, saved_model_config);
|
||||
|
||||
let recipe = session_config.recipe.as_ref();
|
||||
|
||||
agent
|
||||
.apply_recipe_components(
|
||||
recipe.and_then(|r| r.sub_recipes.clone()),
|
||||
@@ -407,7 +607,7 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
|
||||
)
|
||||
.await;
|
||||
|
||||
let new_provider = match create(&provider_name, model_config).await {
|
||||
let new_provider = match create(&resolved.provider_name, resolved.model_config).await {
|
||||
Ok(provider) => provider,
|
||||
Err(e) => {
|
||||
output::render_error(&format!(
|
||||
@@ -430,40 +630,10 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
|
||||
worker_model
|
||||
);
|
||||
} else {
|
||||
tracing::info!("🤖 Using model: {}", model_name);
|
||||
tracing::info!("🤖 Using model: {}", resolved.model_name);
|
||||
}
|
||||
|
||||
let session_id: String = if session_config.no_session {
|
||||
let working_dir = std::env::current_dir().expect("Could not get working directory");
|
||||
let session = session_manager
|
||||
.create_session(working_dir, "CLI Session".to_string(), SessionType::Hidden)
|
||||
.await
|
||||
.expect("Could not create session");
|
||||
session.id
|
||||
} else if session_config.resume {
|
||||
if let Some(session_id) = session_config.session_id {
|
||||
match session_manager.get_session(&session_id, false).await {
|
||||
Ok(_) => session_id,
|
||||
Err(_) => {
|
||||
output::render_error(&format!(
|
||||
"Cannot resume session {} - no such session exists",
|
||||
style(&session_id).cyan()
|
||||
));
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match session_manager.list_sessions().await {
|
||||
Ok(sessions) if !sessions.is_empty() => sessions[0].id.clone(),
|
||||
_ => {
|
||||
output::render_error("Cannot resume - no previous sessions found");
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
session_config.session_id.unwrap()
|
||||
};
|
||||
let session_id = resolve_session_id(&session_config, &session_manager).await;
|
||||
|
||||
agent
|
||||
.update_provider(new_provider, &session_id)
|
||||
@@ -474,96 +644,19 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
|
||||
});
|
||||
|
||||
if session_config.resume {
|
||||
let session = agent
|
||||
.config
|
||||
.session_manager
|
||||
.get_session(&session_id, false)
|
||||
.await
|
||||
.unwrap_or_else(|e| {
|
||||
output::render_error(&format!("Failed to read session metadata: {}", e));
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
let current_workdir =
|
||||
std::env::current_dir().expect("Failed to get current working directory");
|
||||
if current_workdir != session.working_dir {
|
||||
if session_config.interactive {
|
||||
let change_workdir = cliclack::confirm(format!("{} The original working directory of this session was set to {}. Your current directory is {}. Do you want to switch back to the original working directory?", style("WARNING:").yellow(), style(session.working_dir.display()).cyan(), style(current_workdir.display()).cyan()))
|
||||
.initial_value(true)
|
||||
.interact().expect("Failed to get user input");
|
||||
|
||||
if change_workdir {
|
||||
if !session.working_dir.exists() {
|
||||
output::render_error(&format!(
|
||||
"Cannot switch to original working directory - {} no longer exists",
|
||||
style(session.working_dir.display()).cyan()
|
||||
));
|
||||
} else if let Err(e) = std::env::set_current_dir(&session.working_dir) {
|
||||
output::render_error(&format!(
|
||||
"Failed to switch to original working directory: {}",
|
||||
e
|
||||
));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
eprintln!(
|
||||
"{}",
|
||||
style(format!(
|
||||
"Warning: Working directory differs from session (current: {}, session: {}). Staying in current directory.",
|
||||
current_workdir.display(),
|
||||
session.working_dir.display()
|
||||
))
|
||||
.yellow()
|
||||
);
|
||||
}
|
||||
}
|
||||
handle_resumed_session_workdir(&agent, &session_id, session_config.interactive).await;
|
||||
}
|
||||
|
||||
// Setup extensions for the agent
|
||||
// Extensions need to be added after the session is created because we change directory when resuming a session
|
||||
|
||||
for warning in goose::config::get_warnings() {
|
||||
eprintln!("{}", style(format!("Warning: {}", warning)).yellow());
|
||||
}
|
||||
|
||||
let configured_extensions: Vec<ExtensionConfig> = if session_config.resume {
|
||||
agent
|
||||
.config
|
||||
.session_manager
|
||||
.get_session(&session_id, false)
|
||||
.await
|
||||
.ok()
|
||||
.and_then(|s| EnabledExtensionsState::from_extension_data(&s.extension_data))
|
||||
.map(|state| state.extensions)
|
||||
.unwrap_or_else(get_enabled_extensions)
|
||||
} else if session_config.no_profile {
|
||||
Vec::new()
|
||||
} else {
|
||||
resolve_extensions_for_new_session(recipe.and_then(|r| r.extensions.as_deref()), None)
|
||||
};
|
||||
|
||||
let cli_flag_extensions_to_load = parse_cli_flag_extensions(
|
||||
&session_config.extensions,
|
||||
&session_config.streamable_http_extensions,
|
||||
&session_config.builtins,
|
||||
);
|
||||
|
||||
let mut extensions_to_load: Vec<(String, ExtensionConfig)> = configured_extensions
|
||||
.iter()
|
||||
.map(|cfg| (cfg.name(), cfg.clone()))
|
||||
.collect();
|
||||
extensions_to_load.extend(cli_flag_extensions_to_load);
|
||||
|
||||
let agent_ptr = load_extensions(
|
||||
// Extensions are loaded after session creation because we may change directory when resuming
|
||||
let agent_ptr = resolve_and_load_extensions(
|
||||
agent,
|
||||
extensions_to_load,
|
||||
Arc::clone(&provider_for_display),
|
||||
session_config.interactive,
|
||||
&session_config,
|
||||
recipe,
|
||||
&session_id,
|
||||
Arc::clone(&provider_for_display),
|
||||
)
|
||||
.await;
|
||||
|
||||
// Determine editor mode
|
||||
let edit_mode = config
|
||||
.get_param::<String>("EDIT_MODE")
|
||||
.ok()
|
||||
@@ -590,38 +683,13 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
|
||||
)
|
||||
.await;
|
||||
|
||||
if let Err(e) = session
|
||||
.agent
|
||||
.persist_extension_state(&session_id.clone())
|
||||
.await
|
||||
{
|
||||
tracing::warn!("Failed to save extension state: {}", e);
|
||||
}
|
||||
configure_session_prompts(&session, config, &session_config, &session_id).await;
|
||||
|
||||
// Add CLI-specific system prompt extension
|
||||
session
|
||||
.agent
|
||||
.extend_system_prompt(super::prompt::get_cli_prompt())
|
||||
.await;
|
||||
|
||||
if let Some(additional_prompt) = session_config.additional_system_prompt {
|
||||
session.agent.extend_system_prompt(additional_prompt).await;
|
||||
}
|
||||
|
||||
// Only override system prompt if a system override exists
|
||||
let system_prompt_file: Option<String> = config.get_param("GOOSE_SYSTEM_PROMPT_FILE_PATH").ok();
|
||||
if let Some(ref path) = system_prompt_file {
|
||||
let override_prompt =
|
||||
std::fs::read_to_string(path).expect("Failed to read system prompt file");
|
||||
session.agent.override_system_prompt(override_prompt).await;
|
||||
}
|
||||
|
||||
// Display session information unless in quiet mode
|
||||
if !session_config.quiet {
|
||||
output::display_session_info(
|
||||
session_config.resume,
|
||||
&provider_name,
|
||||
&model_name,
|
||||
&resolved.provider_name,
|
||||
&resolved.model_name,
|
||||
&Some(session_id),
|
||||
Some(&provider_for_display),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user