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
29 changes: 15 additions & 14 deletions crates/goose-acp/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,12 +375,14 @@ impl GooseAcpAgent {
&self,
cx: Option<&JrConnectionCx<AgentToClient>>,
session_id: Option<&SessionId>,
goose_mode: Option<GooseMode>,
) -> Result<Arc<Agent>> {
let mode = goose_mode.unwrap_or(self.goose_mode);
let agent = Agent::with_config(AgentConfig::new(
Arc::clone(&self.session_manager),
Arc::clone(&self.permission_manager),
None,
self.goose_mode,
mode,
self.disable_session_naming,
GoosePlatform::GooseCli,
));
Expand Down Expand Up @@ -805,6 +807,7 @@ impl GooseAcpAgent {
args.cwd.clone(),
"ACP Session".to_string(),
SessionType::User,
self.goose_mode,
)
.await
.map_err(|e| {
Expand All @@ -814,7 +817,7 @@ impl GooseAcpAgent {
let session_id = SessionId::new(goose_session.id.clone());

let agent = self
.create_agent_for_session(Some(cx), Some(&session_id))
.create_agent_for_session(Some(cx), Some(&session_id), None)
.await
.map_err(|e| {
sacp::Error::internal_error().data(format!("Failed to create agent: {}", e))
Expand Down Expand Up @@ -924,10 +927,11 @@ impl GooseAcpAgent {
.data(format!("Failed to load session {}: {}", session_id, e))
})?;

let loaded_mode = goose_session.goose_mode;
let acp_session_id = SessionId::new(session_id.clone());

let agent = self
.create_agent_for_session(Some(cx), Some(&acp_session_id))
.create_agent_for_session(Some(cx), Some(&acp_session_id), Some(loaded_mode))
.await
.map_err(|e| {
sacp::Error::internal_error().data(format!("Failed to create agent: {}", e))
Expand Down Expand Up @@ -1013,8 +1017,7 @@ impl GooseAcpAgent {
let mut sessions = self.sessions.lock().await;
sessions.insert(session_id.clone(), session);

// TODO: read from goose_session.goose_mode after #7603
let goose_mode = self.goose_mode;
let goose_mode = loaded_mode;

info!(
session_id = %session_id,
Expand Down Expand Up @@ -1167,15 +1170,13 @@ impl GooseAcpAgent {
sacp::Error::invalid_params().data(format!("Invalid mode: {}", mode_id))
})?;

self.get_session_agent(session_id, None).await?;

// Reject mode changes until per-session persistence lands (#7603)
if mode != self.goose_mode {
return Err(sacp::Error::invalid_params().data(format!(
"Mode change not supported: session is {}, requested {}",
self.goose_mode, mode_id
)));
}
let agent = self.get_session_agent(session_id, None).await?;
agent
.update_goose_mode(mode, session_id)
.await
.map_err(|e| {
sacp::Error::internal_error().data(format!("Failed to update mode: {}", e))
})?;

Ok(SetSessionModeResponse::new())
}
Expand Down
1 change: 0 additions & 1 deletion crates/goose-acp/tests/common_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,6 @@ macro_rules! tests_mode_set_error {
($conn:ty) => {
#[test_case::test_case("not_a_mode", None, sacp::Error::invalid_params().data("Invalid mode: not_a_mode") ; "invalid mode")]
#[test_case::test_case("auto", Some("nonexistent-session-id"), sacp::Error::invalid_params().data("Session not found: nonexistent-session-id") ; "session not found")]
#[test_case::test_case("approve", None, sacp::Error::invalid_params().data("Mode change not supported: session is auto, requested approve") ; "mode change rejected")]
fn test_mode_set_error(
mode_id: &'static str,
session_id: Option<&'static str>,
Expand Down
1 change: 0 additions & 1 deletion crates/goose-acp/tests/provider_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ fn test_load_session_mcp() {
}

#[test]
#[ignore = "TODO: on_set_mode is a no-op until mode is threaded per-session (#7603)"]
fn test_mode_set() {
run_test(async { run_mode_set::<ClientToProviderConnection>().await });
}
Expand Down
2 changes: 0 additions & 2 deletions crates/goose-acp/tests/server_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ fn test_initialize_doesnt_hit_provider() {
}

#[test]
#[ignore = "TODO: on_set_mode is a no-op until mode is threaded per-session (#7603)"]
fn test_load_mode() {
run_test(async { run_load_mode::<ClientToAgentConnection>().await });
}
Expand All @@ -53,7 +52,6 @@ fn test_load_session_mcp() {
}

#[test]
#[ignore = "TODO: on_set_mode is a no-op until mode is threaded per-session (#7603)"]
fn test_mode_set() {
run_test(async { run_mode_set::<ClientToAgentConnection>().await });
}
Expand Down
27 changes: 21 additions & 6 deletions crates/goose-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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));
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions crates/goose-cli/src/commands/configure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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?;

Expand Down
2 changes: 2 additions & 0 deletions crates/goose-cli/src/commands/term.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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?;

Expand Down
1 change: 1 addition & 0 deletions crates/goose-cli/src/scenario_tests/scenario_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ where
PathBuf::default(),
"scenario-runner".to_string(),
SessionType::Hidden,
GooseMode::default(),
)
.await?;

Expand Down
22 changes: 19 additions & 3 deletions crates/goose-cli/src/session/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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?;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion crates/goose-cli/src/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
3 changes: 3 additions & 0 deletions crates/goose-server/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ derive_utoipa!(Icon as IconSchema);
super::routes::agent::agent_add_extension,
super::routes::agent::agent_remove_extension,
super::routes::agent::update_agent_provider,
super::routes::agent::update_session,
super::routes::action_required::confirm_tool_action,
super::routes::reply::reply,
super::routes::session::list_sessions,
Expand Down Expand Up @@ -579,6 +580,7 @@ derive_utoipa!(Icon as IconSchema);
ModelInfo,
ModelConfig,
Session,
goose::config::goose_mode::GooseMode,
SessionInsights,
SessionType,
SystemInfo,
Expand Down Expand Up @@ -625,6 +627,7 @@ derive_utoipa!(Icon as IconSchema);
goose::agents::types::RetryConfig,
goose::agents::types::SuccessCheck,
super::routes::agent::UpdateProviderRequest,
super::routes::agent::UpdateSessionRequest,
super::routes::agent::GetToolsQuery,
super::routes::agent::ReadResourceRequest,
super::routes::agent::ReadResourceResponse,
Expand Down
Loading
Loading