From 59b28e455f416ca0de484215d15549742e207ccd Mon Sep 17 00:00:00 2001 From: Lifei Zhou Date: Fri, 26 Jun 2026 09:13:57 +1000 Subject: [PATCH] Apply ACP recipe state during session load and fork (#9998) --- crates/goose-server/src/routes/session.rs | 2 +- crates/goose/src/acp/server/fork_session.rs | 9 ++++--- crates/goose/src/acp/server/load_session.rs | 1 + crates/goose/src/acp/server/recipe/mod.rs | 27 +++++++++++++++++++++ ui/desktop/src/hooks/useAcpChatSession.ts | 13 +--------- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/crates/goose-server/src/routes/session.rs b/crates/goose-server/src/routes/session.rs index efe9f509d..534f21f03 100644 --- a/crates/goose-server/src/routes/session.rs +++ b/crates/goose-server/src/routes/session.rs @@ -183,7 +183,7 @@ async fn update_session_user_recipe_values( message: format!("Failed to get agent: {}", status), status, })?; - if let Some(prompt) = apply_recipe_to_agent(&agent, &recipe, false).await { + if let Some(prompt) = apply_recipe_to_agent(&agent, &recipe, true).await { agent .extend_system_prompt("recipe".to_string(), prompt) .await; diff --git a/crates/goose/src/acp/server/fork_session.rs b/crates/goose/src/acp/server/fork_session.rs index cb2b399f5..e9d9553c3 100644 --- a/crates/goose/src/acp/server/fork_session.rs +++ b/crates/goose/src/acp/server/fork_session.rs @@ -51,12 +51,13 @@ impl GooseAcpAgent { ) .await?; - let (_agent, extension_results) = self - .activate_acp_session(cx, &goose_session, HashMap::new()) - .await?; + let (agent, extension_results) = self.prepare_acp_session_agent(cx, &goose_session).await?; + self.apply_session_recipe(&agent, &goose_session).await?; + self.register_acp_session(goose_session.id.clone(), agent, HashMap::new()) + .await; let acp_session_id = SessionId::new(new_session_id.clone()); - let mut meta = session_meta(&new_session); + let mut meta = session_meta(&goose_session); if let Ok(v) = serde_json::to_value(&extension_results) { meta.insert("extensionResults".to_string(), v); } diff --git a/crates/goose/src/acp/server/load_session.rs b/crates/goose/src/acp/server/load_session.rs index ad5b1b84e..d28d9101f 100644 --- a/crates/goose/src/acp/server/load_session.rs +++ b/crates/goose/src/acp/server/load_session.rs @@ -191,6 +191,7 @@ impl GooseAcpAgent { let replay_tool_requests = replay_conversation_to_client(cx, &session)?; let (agent, extension_results) = self.prepare_acp_session_agent(cx, &session).await?; + self.apply_session_recipe(&agent, &session).await?; self.register_acp_session(session_id_str.clone(), agent.clone(), replay_tool_requests) .await; diff --git a/crates/goose/src/acp/server/recipe/mod.rs b/crates/goose/src/acp/server/recipe/mod.rs index 9b493004f..f4ebf5f13 100644 --- a/crates/goose/src/acp/server/recipe/mod.rs +++ b/crates/goose/src/acp/server/recipe/mod.rs @@ -29,6 +29,7 @@ use crate::recipe::manifest::{ use crate::recipe::validate_recipe::validate_recipe_template_from_content; use crate::recipe::{strip_error_location, Recipe, RecipeParameter}; use crate::recipe_deeplink; +use crate::session::{Session, SessionType}; use crate::slash_commands::recipe_slash_command; use self::conversions::recipe_manifest_to_list_entry_dto; @@ -321,6 +322,32 @@ impl GooseAcpAgent { } } + pub(super) async fn apply_session_recipe( + &self, + agent: &Arc, + session: &Session, + ) -> Result<(), agent_client_protocol::Error> { + let Some(recipe) = session.recipe.as_ref() else { + return Ok(()); + }; + + if session.session_type == SessionType::Scheduled { + self.apply_recipe(agent, recipe).await; + return Ok(()); + } + + let recipe_dir = get_recipe_library_dir(true); + if let Some(rendered) = self.render_recipe( + recipe, + &recipe_dir, + session.user_recipe_values.clone().unwrap_or_default(), + )? { + self.apply_recipe(agent, &rendered).await; + } + + Ok(()) + } + pub(super) async fn render_recipe_for_session( &self, cx: &ConnectionTo, diff --git a/ui/desktop/src/hooks/useAcpChatSession.ts b/ui/desktop/src/hooks/useAcpChatSession.ts index 6940f15dc..ebc646151 100644 --- a/ui/desktop/src/hooks/useAcpChatSession.ts +++ b/ui/desktop/src/hooks/useAcpChatSession.ts @@ -3,7 +3,7 @@ import { defineMessages, useIntl } from '../i18n'; import { AppEvents } from '../constants/events'; import { ChatState } from '../types/chatState'; -import { Message, Session, TokenState, updateFromSession } from '../api'; +import { Message, Session, TokenState } from '../api'; import { createUserMessage, NotificationEvent, UserInput } from '../types/message'; import { errorMessage } from '../utils/conversionUtils'; @@ -267,17 +267,6 @@ export function useAcpChatSession({ return Promise.reject(new Error('ACP recipe parameters are handled during session creation')); }, []); - useEffect(() => { - if (session) { - updateFromSession({ - body: { - session_id: session.id, - }, - throwOnError: true, - }); - } - }, [session]); - const stopStreaming = useCallback(() => { acpChatSessionController.stop(sessionId); }, [sessionId]);