feat(goose-acp): enable parallel sessions with isolated agent state (#6392)

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Adrian Cole
2026-01-15 06:19:17 +08:00
committed by GitHub
parent fb0eca2c36
commit 7d4a6bd8ff
86 changed files with 2594 additions and 1938 deletions
+28 -30
View File
@@ -10,9 +10,7 @@ use goose::config::{
use goose::providers::create;
use goose::recipe::{Response, SubRecipe};
use goose::agents::extension::PlatformExtensionContext;
use goose::session::session_manager::SessionType;
use goose::session::SessionManager;
use goose::session::{EnabledExtensionsState, ExtensionState};
use rustyline::EditMode;
use std::collections::HashSet;
@@ -147,12 +145,15 @@ async fn offer_extension_debugging_help(
// Create a minimal agent for debugging
let debug_agent = Agent::new();
let session = SessionManager::create_session(
std::env::current_dir()?,
"CLI Session".to_string(),
SessionType::Hidden,
)
.await?;
let session = debug_agent
.config
.session_manager
.create_session(
std::env::current_dir()?,
"CLI Session".to_string(),
SessionType::Hidden,
)
.await?;
debug_agent.update_provider(provider, &session.id).await?;
@@ -252,10 +253,12 @@ 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();
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 SessionManager::get_session(session_id, false).await {
match session_manager.get_session(session_id, false).await {
Ok(session_data) => (session_data.provider_name, session_data.model_config),
Err(_) => (None, None),
}
@@ -310,8 +313,6 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
.with_temperature(temperature)
};
let agent: Agent = Agent::new();
agent
.apply_recipe_components(
session_config.sub_recipes,
@@ -348,17 +349,14 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
let session_id: String = if session_config.no_session {
let working_dir = std::env::current_dir().expect("Could not get working directory");
let session = SessionManager::create_session(
working_dir,
"CLI Session".to_string(),
SessionType::Hidden,
)
.await
.expect("Could not create session");
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 SessionManager::get_session(&session_id, false).await {
match session_manager.get_session(&session_id, false).await {
Ok(_) => session_id,
Err(_) => {
output::render_error(&format!(
@@ -369,7 +367,7 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
}
}
} else {
match SessionManager::list_sessions().await {
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");
@@ -389,16 +387,11 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
process::exit(1);
});
agent
.extension_manager
.set_context(PlatformExtensionContext {
session_id: Some(session_id.clone()),
extension_manager: Some(Arc::downgrade(&agent.extension_manager)),
})
.await;
if session_config.resume {
let session = SessionManager::get_session(&session_id, false)
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));
@@ -451,7 +444,12 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
let extensions_to_run: Vec<_> = if let Some(extensions) = session_config.extensions_override {
extensions.into_iter().collect()
} else if session_config.resume {
match SessionManager::get_session(&session_id, false).await {
match agent
.config
.session_manager
.get_session(&session_id, false)
.await
{
Ok(session_data) => {
if let Some(saved_state) =
EnabledExtensionsState::from_extension_data(&session_data.extension_data)