Remove clippy too_many_lines lint and decompose long functions (#7064)

This commit is contained in:
Bradley Axen
2026-02-06 20:10:24 -08:00
committed by GitHub
parent 948cb91d54
commit b18120bec3
12 changed files with 256 additions and 412 deletions
+238 -170
View File
@@ -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),
);