feat: persist GooseMode per-session via session DB (#7854)

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Adrian Cole
2026-03-16 19:37:21 +08:00
committed by GitHub
parent 2631095f20
commit 94fdcdd07a
42 changed files with 953 additions and 147 deletions
+21 -6
View File
@@ -2,7 +2,7 @@ use anyhow::Result;
use clap::{Args, CommandFactory, Parser, Subcommand};
use clap_complete::{generate, Shell as ClapShell};
use goose::builtin_extension::register_builtin_extensions;
use goose::config::Config;
use goose::config::{Config, GooseMode};
use goose::posthog::get_telemetry_choice;
use goose::recipe::Recipe;
use goose_mcp::mcp_server_runner::{serve, McpCommand};
@@ -356,6 +356,7 @@ async fn get_or_create_session_id(
identifier: Option<Identifier>,
resume: bool,
no_session: bool,
goose_mode: GooseMode,
) -> Result<Option<String>> {
if no_session {
return Ok(None);
@@ -399,6 +400,7 @@ async fn get_or_create_session_id(
std::env::current_dir()?,
"CLI Session".to_string(),
SessionType::User,
goose_mode,
)
.await?;
return Ok(Some(session.id));
@@ -411,7 +413,12 @@ async fn get_or_create_session_id(
let has_user_provided_name = id.name.is_some();
let name = id.name.unwrap_or_else(|| "CLI Session".to_string());
let session = session_manager
.create_session(std::env::current_dir()?, name.clone(), SessionType::User)
.create_session(
std::env::current_dir()?,
name.clone(),
SessionType::User,
goose_mode,
)
.await?;
if has_user_provided_name {
@@ -1129,7 +1136,8 @@ async fn handle_interactive_session(
}
}
let mut session_id = get_or_create_session_id(identifier, resume, false).await?;
let goose_mode = Config::global().get_goose_mode().unwrap_or_default();
let mut session_id = get_or_create_session_id(identifier, resume, false, goose_mode).await?;
if fork {
if let Some(id) = session_id {
@@ -1342,8 +1350,14 @@ async fn handle_run_command(
}
}
let session_id =
get_or_create_session_id(identifier, run_behavior.resume, run_behavior.no_session).await?;
let goose_mode = Config::global().get_goose_mode().unwrap_or_default();
let session_id = get_or_create_session_id(
identifier,
run_behavior.resume,
run_behavior.no_session,
goose_mode,
)
.await?;
let mut session = build_session(SessionBuilderConfig {
session_id,
@@ -1629,7 +1643,8 @@ async fn handle_default_session() -> Result<()> {
configure_telemetry_consent_dialog()?;
}
let session_id = get_or_create_session_id(None, false, false).await?;
let goose_mode = Config::global().get_goose_mode().unwrap_or_default();
let session_id = get_or_create_session_id(None, false, false, goose_mode).await?;
let mut session = build_session(SessionBuilderConfig {
session_id,
@@ -1557,6 +1557,7 @@ pub async fn configure_tool_permissions_dialog() -> anyhow::Result<()> {
std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from(".")),
"Tool Permission Configuration".to_string(),
SessionType::Hidden,
agent.config.goose_mode,
)
.await?;
+2
View File
@@ -1,5 +1,6 @@
use anyhow::{anyhow, Result};
use chrono;
use goose::config::Config;
use goose::conversation::message::{Message, MessageContent, MessageMetadata};
use goose::session::{SessionManager, SessionType};
use rmcp::model::Role;
@@ -138,6 +139,7 @@ pub async fn handle_term_init(
working_dir,
"Goose Term Session".to_string(),
SessionType::Terminal,
Config::global().get_goose_mode().unwrap_or_default(),
)
.await?;
@@ -242,6 +242,7 @@ where
PathBuf::default(),
"scenario-runner".to_string(),
SessionType::Hidden,
GooseMode::default(),
)
.await?;
+19 -3
View File
@@ -5,7 +5,7 @@ use super::CliSession;
use console::style;
use goose::agents::{Agent, Container, ExtensionError};
use goose::config::resolve_extensions_for_new_session;
use goose::config::{get_all_extensions, Config, ExtensionConfig};
use goose::config::{get_all_extensions, Config, ExtensionConfig, GooseMode};
use goose::providers::create;
use goose::recipe::Recipe;
use goose::session::session_manager::SessionType;
@@ -201,6 +201,7 @@ async fn offer_extension_debugging_help(
std::env::current_dir()?,
"CLI Session".to_string(),
SessionType::Hidden,
debug_agent.config.goose_mode,
)
.await?;
@@ -400,11 +401,17 @@ fn resolve_provider_and_model(
async fn resolve_session_id(
session_config: &SessionBuilderConfig,
session_manager: &goose::session::session_manager::SessionManager,
goose_mode: GooseMode,
) -> 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)
.create_session(
working_dir,
"CLI Session".to_string(),
SessionType::Hidden,
goose_mode,
)
.await
.expect("Could not create session");
session.id
@@ -606,7 +613,8 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
.apply_recipe_components(recipe.and_then(|r| r.response.clone()), true)
.await;
let session_id = resolve_session_id(&session_config, &session_manager).await;
let session_id =
resolve_session_id(&session_config, &session_manager, agent.config.goose_mode).await;
if session_config.resume {
handle_resumed_session_workdir(&agent, &session_id, session_config.interactive).await;
@@ -661,6 +669,14 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
process::exit(1);
});
agent
.update_goose_mode(agent.config.goose_mode, &session_id)
.await
.unwrap_or_else(|e| {
output::render_error(&format!("Failed to set session mode: {}", e));
process::exit(1);
});
if let Some(recipe) = session_config.recipe.clone() {
if let Err(e) = session_manager
.update(&session_id)
+1 -1
View File
@@ -886,7 +886,7 @@ impl CliSession {
self.run_mode = RunMode::Normal;
// set goose mode: auto if that isn't already the case
let config = Config::global();
let curr_goose_mode = config.get_goose_mode().unwrap_or(GooseMode::Auto);
let curr_goose_mode = config.get_goose_mode().unwrap_or_default();
if curr_goose_mode != GooseMode::Auto {
config.set_goose_mode(GooseMode::Auto).unwrap();
}