fix: allow subagent to run in parent --no-session mode (#5384)

This commit is contained in:
Lifei Zhou
2025-10-29 08:59:01 +11:00
committed by GitHub
parent 9cf24fa88a
commit 6b6b71f3b4
3 changed files with 50 additions and 37 deletions
+3 -14
View File
@@ -449,21 +449,10 @@ impl Agent {
); );
} }
}; };
let session = match session.as_ref() { let (parent_session_id, parent_working_dir) = match session.as_ref() {
Some(s) => s, Some(s) => (Some(s.id.clone()), s.working_dir.clone()),
None => { None => (None, std::env::current_dir().unwrap_or_default()),
return (
request_id,
Err(ErrorData::new(
ErrorCode::INTERNAL_ERROR,
"Session is required".to_string(),
None,
)),
);
}
}; };
let parent_session_id = session.id.to_string();
let parent_working_dir = session.working_dir.clone();
// Get extensions from the agent's runtime state rather than global config // Get extensions from the agent's runtime state rather than global config
// This ensures subagents inherit extensions that were dynamically enabled by the parent // This ensures subagents inherit extensions that were dynamically enabled by the parent
+45 -21
View File
@@ -1,5 +1,8 @@
use crate::{ use crate::{
agents::{subagent_task_config::TaskConfig, AgentEvent, SessionConfig}, agents::{
extension::PlatformExtensionContext, subagent_task_config::TaskConfig, Agent, AgentEvent,
SessionConfig,
},
conversation::{message::Message, Conversation}, conversation::{message::Message, Conversation},
execution::manager::AgentManager, execution::manager::AgentManager,
session::SessionManager, session::SessionManager,
@@ -7,8 +10,8 @@ use crate::{
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use futures::StreamExt; use futures::StreamExt;
use rmcp::model::{ErrorCode, ErrorData}; use rmcp::model::{ErrorCode, ErrorData};
use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
use std::{future::Future, sync::Arc};
use tracing::debug; use tracing::debug;
/// Standalone function to run a complete subagent task with output options /// Standalone function to run a complete subagent task with output options
@@ -101,17 +104,35 @@ fn get_agent_messages(
.map_err(|e| anyhow!("Failed to create AgentManager: {}", e))?; .map_err(|e| anyhow!("Failed to create AgentManager: {}", e))?;
let parent_session_id = task_config.parent_session_id; let parent_session_id = task_config.parent_session_id;
let working_dir = task_config.parent_working_dir; let working_dir = task_config.parent_working_dir;
let session = SessionManager::create_session( let (agent, session_id) = match parent_session_id {
working_dir.clone(), Some(parent_session_id) => {
format!("Subagent task for: {}", parent_session_id), let session = SessionManager::create_session(
) working_dir.clone(),
.await format!("Subagent task for: {}", parent_session_id),
.map_err(|e| anyhow!("Failed to create a session for sub agent: {}", e))?; )
.await
.map_err(|e| anyhow!("Failed to create a session for sub agent: {}", e))?;
let agent = agent_manager
.get_or_create_agent(session.id.clone())
.await
.map_err(|e| anyhow!("Failed to get sub agent session file path: {}", e))?;
(agent, Some(session.id))
}
None => {
let agent = Arc::new(Agent::new());
agent
.extension_manager
.set_context(PlatformExtensionContext {
session_id: None,
extension_manager: Some(Arc::downgrade(&agent.extension_manager)),
tool_route_manager: Some(Arc::downgrade(&agent.tool_route_manager)),
})
.await;
(agent, None)
}
};
let agent = agent_manager
.get_or_create_agent(session.id.clone())
.await
.map_err(|e| anyhow!("Failed to get sub agent session file path: {}", e))?;
agent agent
.update_provider(task_config.provider) .update_provider(task_config.provider)
.await .await
@@ -131,17 +152,20 @@ fn get_agent_messages(
Conversation::new_unvalidated( Conversation::new_unvalidated(
vec![Message::user().with_text(text_instruction.clone())], vec![Message::user().with_text(text_instruction.clone())],
); );
let session_config = SessionConfig { let session_config = if let Some(session_id) = session_id {
id: session.id, Some(SessionConfig {
working_dir, id: session_id,
schedule_id: None, working_dir,
execution_mode: None, schedule_id: None,
max_turns: task_config.max_turns.map(|v| v as u32), execution_mode: None,
retry_config: None, max_turns: task_config.max_turns.map(|v| v as u32),
retry_config: None,
})
} else {
None
}; };
let mut stream = agent let mut stream = agent
.reply(conversation.clone(), Some(session_config), None) .reply(conversation.clone(), session_config, None)
.await .await
.map_err(|e| anyhow!("Failed to get reply from agent: {}", e))?; .map_err(|e| anyhow!("Failed to get reply from agent: {}", e))?;
while let Some(message_result) = stream.next().await { while let Some(message_result) = stream.next().await {
@@ -15,7 +15,7 @@ pub const GOOSE_SUBAGENT_MAX_TURNS_ENV_VAR: &str = "GOOSE_SUBAGENT_MAX_TURNS";
#[derive(Clone)] #[derive(Clone)]
pub struct TaskConfig { pub struct TaskConfig {
pub provider: Arc<dyn Provider>, pub provider: Arc<dyn Provider>,
pub parent_session_id: String, pub parent_session_id: Option<String>,
pub parent_working_dir: PathBuf, pub parent_working_dir: PathBuf,
pub extensions: Vec<ExtensionConfig>, pub extensions: Vec<ExtensionConfig>,
pub max_turns: Option<usize>, pub max_turns: Option<usize>,
@@ -37,7 +37,7 @@ impl TaskConfig {
/// Create a new TaskConfig with all required dependencies /// Create a new TaskConfig with all required dependencies
pub fn new( pub fn new(
provider: Arc<dyn Provider>, provider: Arc<dyn Provider>,
parent_session_id: String, parent_session_id: Option<String>,
parent_working_dir: PathBuf, parent_working_dir: PathBuf,
extensions: Vec<ExtensionConfig>, extensions: Vec<ExtensionConfig>,
) -> Self { ) -> Self {