Files
zesdex/src/app/subagent/context.rs
T

59 lines
2.5 KiB
Rust

//! 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, atomic::AtomicBool};
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<String>,
pub max_steps: usize,
pub session_dir: PathBuf,
pub workspaces: Vec<PathBuf>,
/// 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<Arc<Mutex<Vec<String>>>>,
/// Atomic abort flag: when set to `true`, the subagent loop will exit
/// at the earliest opportunity (before the next LLM call). Mirrors the
/// main agent's `abort_flag` mechanism so that long-running or stuck
/// subagents can be cancelled from the parent.
pub abort_flag: Option<Arc<AtomicBool>>,
}
/// 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(std::string::ToString::to_string).collect()
} else {
Vec::new()
}
});
let max_steps = def.max_steps.unwrap_or(usize::MAX);
SubagentContext {
system_prompt: String::new(),
allowed_tools,
max_steps,
session_dir: PathBuf::new(),
workspaces: Vec::new(),
workflow_findings: None,
abort_flag: None,
}
}