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
17 changes: 3 additions & 14 deletions crates/goose/src/agents/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,21 +449,10 @@ impl Agent {
);
}
};
let session = match session.as_ref() {
Some(s) => s,
None => {
return (
request_id,
Err(ErrorData::new(
ErrorCode::INTERNAL_ERROR,
"Session is required".to_string(),
None,
)),
);
}
let (parent_session_id, parent_working_dir) = match session.as_ref() {
Some(s) => (Some(s.id.clone()), s.working_dir.clone()),
None => (None, std::env::current_dir().unwrap_or_default()),
};
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
// This ensures subagents inherit extensions that were dynamically enabled by the parent
Expand Down
66 changes: 45 additions & 21 deletions crates/goose/src/agents/subagent_handler.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
use crate::{
agents::{subagent_task_config::TaskConfig, AgentEvent, SessionConfig},
agents::{
extension::PlatformExtensionContext, subagent_task_config::TaskConfig, Agent, AgentEvent,
SessionConfig,
},
conversation::{message::Message, Conversation},
execution::manager::AgentManager,
session::SessionManager,
};
use anyhow::{anyhow, Result};
use futures::StreamExt;
use rmcp::model::{ErrorCode, ErrorData};
use std::future::Future;
use std::pin::Pin;
use std::{future::Future, sync::Arc};
use tracing::debug;

/// Standalone function to run a complete subagent task with output options
Expand Down Expand Up @@ -101,17 +104,35 @@ fn get_agent_messages(
.map_err(|e| anyhow!("Failed to create AgentManager: {}", e))?;
let parent_session_id = task_config.parent_session_id;
let working_dir = task_config.parent_working_dir;
let session = SessionManager::create_session(
working_dir.clone(),
format!("Subagent task for: {}", parent_session_id),
)
.await
.map_err(|e| anyhow!("Failed to create a session for sub agent: {}", e))?;
let (agent, session_id) = match parent_session_id {
Some(parent_session_id) => {
let session = SessionManager::create_session(
working_dir.clone(),
format!("Subagent task for: {}", parent_session_id),
)
.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
.update_provider(task_config.provider)
.await
Expand All @@ -131,17 +152,20 @@ fn get_agent_messages(
Conversation::new_unvalidated(
vec![Message::user().with_text(text_instruction.clone())],
);
let session_config = SessionConfig {
id: session.id,
working_dir,
schedule_id: None,
execution_mode: None,
max_turns: task_config.max_turns.map(|v| v as u32),
retry_config: None,
let session_config = if let Some(session_id) = session_id {
Some(SessionConfig {
id: session_id,
working_dir,
schedule_id: None,
execution_mode: None,
max_turns: task_config.max_turns.map(|v| v as u32),
retry_config: None,
})
} else {
None
};

let mut stream = agent
.reply(conversation.clone(), Some(session_config), None)
.reply(conversation.clone(), session_config, None)
.await
.map_err(|e| anyhow!("Failed to get reply from agent: {}", e))?;
while let Some(message_result) = stream.next().await {
Expand Down
4 changes: 2 additions & 2 deletions crates/goose/src/agents/subagent_task_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub const GOOSE_SUBAGENT_MAX_TURNS_ENV_VAR: &str = "GOOSE_SUBAGENT_MAX_TURNS";
#[derive(Clone)]
pub struct TaskConfig {
pub provider: Arc<dyn Provider>,
pub parent_session_id: String,
pub parent_session_id: Option<String>,
pub parent_working_dir: PathBuf,
pub extensions: Vec<ExtensionConfig>,
pub max_turns: Option<usize>,
Expand All @@ -37,7 +37,7 @@ impl TaskConfig {
/// Create a new TaskConfig with all required dependencies
pub fn new(
provider: Arc<dyn Provider>,
parent_session_id: String,
parent_session_id: Option<String>,
parent_working_dir: PathBuf,
extensions: Vec<ExtensionConfig>,
) -> Self {
Expand Down
Loading