//! Construction of a `SubagentContext` from an `AgentDefinition`, //! including the default read-only tool set for reviewer agents. use std::path::PathBuf; use std::sync::{Arc, Mutex}; use super::spawn::AgentDefinition; /// Default read-only tool names granted to `role == "reviewer"` agents. pub const REVIEWER_ALLOWED: &[&str] = &["read", "grep", "glob", "recall", "remember"]; /// Per-invocation configuration for a subagent: prompt, allowed tools, /// step budget, session directory, and optional workflow-findings Arc /// for cross-agent communication within a workflow run. pub struct SubagentContext { pub system_prompt: String, pub allowed_tools: Vec, pub max_steps: usize, pub session_dir: PathBuf, pub workspaces: Vec, /// Ephemeral findings shared between sibling subagents in the same /// workflow run. Set by the workflow engine; `note_finding` writes /// into this from tool code via `ToolCtx.workflow_findings`. pub workflow_findings: Option>>>, } /// Build a `SubagentContext` from an `AgentDefinition`. /// /// Flow: copy optional `allowed_tools` from the def → fall back to the /// reviewer-allowlist when the def has none and the role is "reviewer" → /// fall back to an empty list (i.e. "all tools allowed") for other roles. /// `max_steps` is read from the definition, defaulting to 25 if absent. /// /// Return: a context with empty `system_prompt`, empty `workspaces`, /// empty `session_dir`, resolved `max_steps`, and the resolved allowed-tool list. pub fn build_subagent_context(def: AgentDefinition) -> SubagentContext { let allowed_tools = def.allowed_tools.clone().unwrap_or_else(|| { if def.role == "reviewer" { REVIEWER_ALLOWED.iter().map(|s| s.to_string()).collect() } else { Vec::new() } }); let max_steps = def.max_steps.unwrap_or(25); SubagentContext { system_prompt: String::new(), allowed_tools, max_steps, session_dir: PathBuf::new(), workspaces: Vec::new(), workflow_findings: None, } }