refactor(function): rename agent-tool symbols out of supervisor vocabulary

Since the supervisor registry became kind-generic (agents AND jobs),
'supervisor' naming on the agent__* tool plumbing was misleading:
job__* handlers operate on the same supervisor. Rename
SUPERVISOR_FUNCTION_PREFIX -> AGENT_FUNCTION_PREFIX,
supervisor_function_declarations -> agent_function_declarations,
handle_supervisor_tool -> handle_agent_tool. No behavior change.
This commit is contained in:
2026-08-26 12:53:17 -06:00
parent 4e50b4ff4a
commit c376737bbd
4 changed files with 36 additions and 40 deletions
+2 -2
View File
@@ -22,7 +22,7 @@ use crate::function::{
memory::MEMORY_FUNCTION_PREFIX, memory::MEMORY_FUNCTION_PREFIX,
rag_query::RAG_FUNCTION_PREFIX, rag_query::RAG_FUNCTION_PREFIX,
skill::SKILL_FUNCTION_PREFIX, skill::SKILL_FUNCTION_PREFIX,
supervisor::SUPERVISOR_FUNCTION_PREFIX, supervisor::AGENT_FUNCTION_PREFIX,
todo::TODO_FUNCTION_PREFIX, todo::TODO_FUNCTION_PREFIX,
user_interaction::USER_FUNCTION_PREFIX, user_interaction::USER_FUNCTION_PREFIX,
}; };
@@ -2181,7 +2181,7 @@ impl RequestContext {
&& v.name.starts_with(SKILL_FUNCTION_PREFIX)) && v.name.starts_with(SKILL_FUNCTION_PREFIX))
|| v.name.starts_with(USER_FUNCTION_PREFIX) || v.name.starts_with(USER_FUNCTION_PREFIX)
|| v.name.starts_with(TODO_FUNCTION_PREFIX) || v.name.starts_with(TODO_FUNCTION_PREFIX)
|| v.name.starts_with(SUPERVISOR_FUNCTION_PREFIX) || v.name.starts_with(AGENT_FUNCTION_PREFIX)
|| v.name.starts_with(MEMORY_FUNCTION_PREFIX) || v.name.starts_with(MEMORY_FUNCTION_PREFIX)
|| v.name.starts_with(RAG_FUNCTION_PREFIX) || v.name.starts_with(RAG_FUNCTION_PREFIX)
|| v.name.starts_with(JOB_FUNCTION_PREFIX) || v.name.starts_with(JOB_FUNCTION_PREFIX)
+7 -7
View File
@@ -1,7 +1,7 @@
use super::memory::MEMORY_FUNCTION_PREFIX; use super::memory::MEMORY_FUNCTION_PREFIX;
use super::rag_query::RAG_FUNCTION_PREFIX; use super::rag_query::RAG_FUNCTION_PREFIX;
use super::skill::SKILL_FUNCTION_PREFIX; use super::skill::SKILL_FUNCTION_PREFIX;
use super::supervisor::SUPERVISOR_FUNCTION_PREFIX; use super::supervisor::AGENT_FUNCTION_PREFIX;
use super::todo::TODO_FUNCTION_PREFIX; use super::todo::TODO_FUNCTION_PREFIX;
use super::user_interaction::USER_FUNCTION_PREFIX; use super::user_interaction::USER_FUNCTION_PREFIX;
use super::{FunctionDeclaration, JsonSchema, PATH_SEP, mcp_error_display, render_tool_result}; use super::{FunctionDeclaration, JsonSchema, PATH_SEP, mcp_error_display, render_tool_result};
@@ -303,7 +303,7 @@ fn whitelist_rejection(tool: &str) -> Option<Value> {
MCP_READ_META_FUNCTION_NAME_PREFIX, MCP_READ_META_FUNCTION_NAME_PREFIX,
MCP_PROMPT_META_FUNCTION_NAME_PREFIX, MCP_PROMPT_META_FUNCTION_NAME_PREFIX,
]; ];
let reason = if tool.starts_with(SUPERVISOR_FUNCTION_PREFIX) let reason = if tool.starts_with(AGENT_FUNCTION_PREFIX)
|| tool.starts_with(JOB_FUNCTION_PREFIX) || tool.starts_with(JOB_FUNCTION_PREFIX)
{ {
Some(format!( Some(format!(
@@ -1156,7 +1156,7 @@ mod tests {
use super::*; use super::*;
use crate::config::{AppConfig, AppState, WorkingMode}; use crate::config::{AppConfig, AppState, WorkingMode};
use crate::function::supervisor::{ use crate::function::supervisor::{
GuardrailAction, check_pending_tasks_guardrail, handle_supervisor_tool, GuardrailAction, check_pending_tasks_guardrail, handle_agent_tool,
}; };
use crate::supervisor::mailbox::Inbox; use crate::supervisor::mailbox::Inbox;
use crate::supervisor::{AgentExitStatus, AgentHandle, AgentResult}; use crate::supervisor::{AgentExitStatus, AgentHandle, AgentResult};
@@ -2343,7 +2343,7 @@ mod tests {
fn jobs_only_supervisor_rejects_agent_spawn_at_capacity_zero() { fn jobs_only_supervisor_rejects_agent_spawn_at_capacity_zero() {
let mut ctx = ctx_with_job_supervisor(5); let mut ctx = ctx_with_job_supervisor(5);
let result = run_async(handle_supervisor_tool( let result = run_async(handle_agent_tool(
&mut ctx, &mut ctx,
"agent__spawn", "agent__spawn",
&json!({"agent": "explore", "prompt": "x"}), &json!({"agent": "explore", "prompt": "x"}),
@@ -2389,7 +2389,7 @@ mod tests {
fn jobs_only_supervisor_agent_surfaces_stay_functional() { fn jobs_only_supervisor_agent_surfaces_stay_functional() {
let mut ctx = ctx_with_job_supervisor(5); let mut ctx = ctx_with_job_supervisor(5);
let listed = run_async(handle_supervisor_tool( let listed = run_async(handle_agent_tool(
&mut ctx, &mut ctx,
"agent__list_running", "agent__list_running",
&json!({}), &json!({}),
@@ -2398,7 +2398,7 @@ mod tests {
assert_eq!(listed["active_count"], 0); assert_eq!(listed["active_count"], 0);
assert_eq!(listed["max_concurrent"], 0); assert_eq!(listed["max_concurrent"], 0);
let created = run_async(handle_supervisor_tool( let created = run_async(handle_agent_tool(
&mut ctx, &mut ctx,
"agent__task_create", "agent__task_create",
&json!({"subject": "research"}), &json!({"subject": "research"}),
@@ -2406,7 +2406,7 @@ mod tests {
.unwrap(); .unwrap();
assert_eq!(created["status"], "ok"); assert_eq!(created["status"], "ok");
let tasks = run_async(handle_supervisor_tool( let tasks = run_async(handle_agent_tool(
&mut ctx, &mut ctx,
"agent__task_list", "agent__task_list",
&json!({}), &json!({}),
+5 -5
View File
@@ -48,7 +48,7 @@ use std::{
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use strum_macros::AsRefStr; use strum_macros::AsRefStr;
use supervisor::SUPERVISOR_FUNCTION_PREFIX; use supervisor::AGENT_FUNCTION_PREFIX;
use todo::TODO_FUNCTION_PREFIX; use todo::TODO_FUNCTION_PREFIX;
use user_interaction::USER_FUNCTION_PREFIX; use user_interaction::USER_FUNCTION_PREFIX;
@@ -684,7 +684,7 @@ impl Functions {
pub fn append_supervisor_functions(&mut self) { pub fn append_supervisor_functions(&mut self) {
self.declarations self.declarations
.extend(supervisor::supervisor_function_declarations()); .extend(supervisor::agent_function_declarations());
self.declarations self.declarations
.extend(supervisor::escalation_function_declarations()); .extend(supervisor::escalation_function_declarations());
} }
@@ -1589,8 +1589,8 @@ impl ToolCall {
json!({"tool_call_error": error_msg}) json!({"tool_call_error": error_msg})
}) })
} }
_ if cmd_name.starts_with(SUPERVISOR_FUNCTION_PREFIX) => { _ if cmd_name.starts_with(AGENT_FUNCTION_PREFIX) => {
supervisor::handle_supervisor_tool(ctx, &cmd_name, &json_data) supervisor::handle_agent_tool(ctx, &cmd_name, &json_data)
.await .await
.unwrap_or_else(|e| { .unwrap_or_else(|e| {
let error_msg = format!("Supervisor tool failed: {e}"); let error_msg = format!("Supervisor tool failed: {e}");
@@ -3249,7 +3249,7 @@ mod tests {
#[test] #[test]
fn prefix_constants_are_correct() { fn prefix_constants_are_correct() {
assert_eq!(TODO_FUNCTION_PREFIX, "todo__"); assert_eq!(TODO_FUNCTION_PREFIX, "todo__");
assert_eq!(SUPERVISOR_FUNCTION_PREFIX, "agent__"); assert_eq!(AGENT_FUNCTION_PREFIX, "agent__");
assert_eq!(USER_FUNCTION_PREFIX, "user__"); assert_eq!(USER_FUNCTION_PREFIX, "user__");
assert_eq!(MCP_INVOKE_META_FUNCTION_NAME_PREFIX, "mcp_invoke"); assert_eq!(MCP_INVOKE_META_FUNCTION_NAME_PREFIX, "mcp_invoke");
assert_eq!(MCP_SEARCH_META_FUNCTION_NAME_PREFIX, "mcp_search"); assert_eq!(MCP_SEARCH_META_FUNCTION_NAME_PREFIX, "mcp_search");
+22 -26
View File
@@ -23,7 +23,7 @@ use tokio::time;
use tokio::time::Instant; use tokio::time::Instant;
use uuid::Uuid; use uuid::Uuid;
pub const SUPERVISOR_FUNCTION_PREFIX: &str = "agent__"; pub const AGENT_FUNCTION_PREFIX: &str = "agent__";
pub const PENDING_TASKS_GUARDRAIL_MAX: u32 = 3; pub const PENDING_TASKS_GUARDRAIL_MAX: u32 = 3;
@@ -186,7 +186,7 @@ pub fn check_pending_tasks_guardrail(ctx: &mut RequestContext) -> GuardrailActio
pub fn escalation_function_declarations() -> Vec<FunctionDeclaration> { pub fn escalation_function_declarations() -> Vec<FunctionDeclaration> {
vec![FunctionDeclaration { vec![FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}reply_escalation"), name: format!("{AGENT_FUNCTION_PREFIX}reply_escalation"),
description: "Reply to a pending escalation from a child agent. The child is blocked waiting for this reply. \ description: "Reply to a pending escalation from a child agent. The child is blocked waiting for this reply. \
Use this after seeing pending_escalations notifications.".to_string(), Use this after seeing pending_escalations notifications.".to_string(),
parameters: JsonSchema { parameters: JsonSchema {
@@ -217,10 +217,10 @@ pub fn escalation_function_declarations() -> Vec<FunctionDeclaration> {
}] }]
} }
pub fn supervisor_function_declarations() -> Vec<FunctionDeclaration> { pub fn agent_function_declarations() -> Vec<FunctionDeclaration> {
vec![ vec![
FunctionDeclaration { FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}spawn"), name: format!("{AGENT_FUNCTION_PREFIX}spawn"),
description: "Spawn a subagent to run in the background. Returns an `id` immediately so you can continue \ description: "Spawn a subagent to run in the background. Returns an `id` immediately so you can continue \
working in parallel. CRITICAL: every spawned agent MUST be reclaimed before you end your \ working in parallel. CRITICAL: every spawned agent MUST be reclaimed before you end your \
turn — call `agent__collect` to retrieve its output, or `agent__cancel` if you no longer \ turn — call `agent__collect` to retrieve its output, or `agent__cancel` if you no longer \
@@ -260,7 +260,7 @@ pub fn supervisor_function_declarations() -> Vec<FunctionDeclaration> {
agent: false, agent: false,
}, },
FunctionDeclaration { FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}check"), name: format!("{AGENT_FUNCTION_PREFIX}check"),
description: "Non-blocking status probe: reports whether a spawned agent is still running or finished. \ description: "Non-blocking status probe: reports whether a spawned agent is still running or finished. \
NEVER returns or consumes the result — when finished, call agent__collect to retrieve it.".to_string(), NEVER returns or consumes the result — when finished, call agent__collect to retrieve it.".to_string(),
parameters: JsonSchema { parameters: JsonSchema {
@@ -279,7 +279,7 @@ pub fn supervisor_function_declarations() -> Vec<FunctionDeclaration> {
agent: false, agent: false,
}, },
FunctionDeclaration { FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}collect"), name: format!("{AGENT_FUNCTION_PREFIX}collect"),
description: "Block until the named spawned agent finishes and return its result. This is your primary \ description: "Block until the named spawned agent finishes and return its result. This is your primary \
wait primitive — it pauses your execution until the agent completes (or you are interrupted). \ wait primitive — it pauses your execution until the agent completes (or you are interrupted). \
Call this for every agent you spawned before ending your turn. Do NOT end your turn assuming \ Call this for every agent you spawned before ending your turn. Do NOT end your turn assuming \
@@ -301,7 +301,7 @@ pub fn supervisor_function_declarations() -> Vec<FunctionDeclaration> {
agent: false, agent: false,
}, },
FunctionDeclaration { FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}list_running"), name: format!("{AGENT_FUNCTION_PREFIX}list_running"),
description: "List all subagents YOU have spawned that are still tracked by the supervisor, with their \ description: "List all subagents YOU have spawned that are still tracked by the supervisor, with their \
status. Use this to see which of your background agents are still active. To discover which \ status. Use this to see which of your background agents are still active. To discover which \
agent types you can spawn in the first place, use `agent__list_available` instead.".to_string(), agent types you can spawn in the first place, use `agent__list_available` instead.".to_string(),
@@ -313,7 +313,7 @@ pub fn supervisor_function_declarations() -> Vec<FunctionDeclaration> {
agent: false, agent: false,
}, },
FunctionDeclaration { FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}list_available"), name: format!("{AGENT_FUNCTION_PREFIX}list_available"),
description: "List all agent types installed and available to spawn (name + description). Use this to \ description: "List all agent types installed and available to spawn (name + description). Use this to \
discover what specialists exist before calling `agent__spawn` — especially when you're unsure \ discover what specialists exist before calling `agent__spawn` — especially when you're unsure \
which agent to delegate to. This is the discovery counterpart to `agent__list_running` \ which agent to delegate to. This is the discovery counterpart to `agent__list_running` \
@@ -326,7 +326,7 @@ pub fn supervisor_function_declarations() -> Vec<FunctionDeclaration> {
agent: false, agent: false,
}, },
FunctionDeclaration { FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}cancel"), name: format!("{AGENT_FUNCTION_PREFIX}cancel"),
description: "Cancel a running subagent by its ID. Use this when an agent's output is no longer needed \ description: "Cancel a running subagent by its ID. Use this when an agent's output is no longer needed \
(e.g. you changed direction, or you're about to end your turn and don't want to wait). \ (e.g. you changed direction, or you're about to end your turn and don't want to wait). \
Cancellation cascades: all of the cancelled agent's own descendants are also cancelled. This \ Cancellation cascades: all of the cancelled agent's own descendants are also cancelled. This \
@@ -347,7 +347,7 @@ pub fn supervisor_function_declarations() -> Vec<FunctionDeclaration> {
agent: false, agent: false,
}, },
FunctionDeclaration { FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}task_create"), name: format!("{AGENT_FUNCTION_PREFIX}task_create"),
description: "Create a task in the task queue. Returns the task ID.".to_string(), description: "Create a task in the task queue. Returns the task ID.".to_string(),
parameters: JsonSchema { parameters: JsonSchema {
type_value: Some("object".to_string()), type_value: Some("object".to_string()),
@@ -403,7 +403,7 @@ pub fn supervisor_function_declarations() -> Vec<FunctionDeclaration> {
agent: false, agent: false,
}, },
FunctionDeclaration { FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}task_list"), name: format!("{AGENT_FUNCTION_PREFIX}task_list"),
description: "List all tasks in the task queue with their status and dependencies.".to_string(), description: "List all tasks in the task queue with their status and dependencies.".to_string(),
parameters: JsonSchema { parameters: JsonSchema {
type_value: Some("object".to_string()), type_value: Some("object".to_string()),
@@ -413,7 +413,7 @@ pub fn supervisor_function_declarations() -> Vec<FunctionDeclaration> {
agent: false, agent: false,
}, },
FunctionDeclaration { FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}task_complete"), name: format!("{AGENT_FUNCTION_PREFIX}task_complete"),
description: "Mark a task as completed. Returns any newly unblocked task IDs.".to_string(), description: "Mark a task as completed. Returns any newly unblocked task IDs.".to_string(),
parameters: JsonSchema { parameters: JsonSchema {
type_value: Some("object".to_string()), type_value: Some("object".to_string()),
@@ -431,7 +431,7 @@ pub fn supervisor_function_declarations() -> Vec<FunctionDeclaration> {
agent: false, agent: false,
}, },
FunctionDeclaration { FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}task_fail"), name: format!("{AGENT_FUNCTION_PREFIX}task_fail"),
description: "Mark a task as failed. Dependents will remain blocked.".to_string(), description: "Mark a task as failed. Dependents will remain blocked.".to_string(),
parameters: JsonSchema { parameters: JsonSchema {
type_value: Some("object".to_string()), type_value: Some("object".to_string()),
@@ -454,7 +454,7 @@ pub fn supervisor_function_declarations() -> Vec<FunctionDeclaration> {
pub fn teammate_function_declarations() -> Vec<FunctionDeclaration> { pub fn teammate_function_declarations() -> Vec<FunctionDeclaration> {
vec![ vec![
FunctionDeclaration { FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}send_message"), name: format!("{AGENT_FUNCTION_PREFIX}send_message"),
description: "Send a text message to a sibling or child agent's inbox. Use to share cross-cutting findings or coordinate with teammates.".to_string(), description: "Send a text message to a sibling or child agent's inbox. Use to share cross-cutting findings or coordinate with teammates.".to_string(),
parameters: JsonSchema { parameters: JsonSchema {
type_value: Some("object".to_string()), type_value: Some("object".to_string()),
@@ -482,7 +482,7 @@ pub fn teammate_function_declarations() -> Vec<FunctionDeclaration> {
agent: false, agent: false,
}, },
FunctionDeclaration { FunctionDeclaration {
name: format!("{SUPERVISOR_FUNCTION_PREFIX}check_inbox"), name: format!("{AGENT_FUNCTION_PREFIX}check_inbox"),
description: "Check for and drain all pending messages in your inbox from sibling agents or your parent.".to_string(), description: "Check for and drain all pending messages in your inbox from sibling agents or your parent.".to_string(),
parameters: JsonSchema { parameters: JsonSchema {
type_value: Some("object".to_string()), type_value: Some("object".to_string()),
@@ -494,13 +494,13 @@ pub fn teammate_function_declarations() -> Vec<FunctionDeclaration> {
] ]
} }
pub async fn handle_supervisor_tool( pub async fn handle_agent_tool(
ctx: &mut RequestContext, ctx: &mut RequestContext,
cmd_name: &str, cmd_name: &str,
args: &Value, args: &Value,
) -> Result<Value> { ) -> Result<Value> {
let action = cmd_name let action = cmd_name
.strip_prefix(SUPERVISOR_FUNCTION_PREFIX) .strip_prefix(AGENT_FUNCTION_PREFIX)
.unwrap_or(cmd_name); .unwrap_or(cmd_name);
match action { match action {
@@ -2137,7 +2137,7 @@ mod tests {
#[test] #[test]
fn dispatch_unknown_action_errors() { fn dispatch_unknown_action_errors() {
let mut ctx = ctx_with_supervisor(4, 3); let mut ctx = ctx_with_supervisor(4, 3);
let result = run_async(handle_supervisor_tool(&mut ctx, "agent__bogus", &json!({}))); let result = run_async(handle_agent_tool(&mut ctx, "agent__bogus", &json!({})));
assert!(result.is_err()); assert!(result.is_err());
assert!( assert!(
result result
@@ -2150,7 +2150,7 @@ mod tests {
#[test] #[test]
fn dispatch_routes_list_running() { fn dispatch_routes_list_running() {
let mut ctx = ctx_with_supervisor(4, 3); let mut ctx = ctx_with_supervisor(4, 3);
let result = run_async(handle_supervisor_tool( let result = run_async(handle_agent_tool(
&mut ctx, &mut ctx,
"agent__list_running", "agent__list_running",
&json!({}), &json!({}),
@@ -2162,7 +2162,7 @@ mod tests {
#[test] #[test]
fn dispatch_routes_list_available() { fn dispatch_routes_list_available() {
let mut ctx = ctx_with_supervisor(4, 3); let mut ctx = ctx_with_supervisor(4, 3);
let result = run_async(handle_supervisor_tool( let result = run_async(handle_agent_tool(
&mut ctx, &mut ctx,
"agent__list_available", "agent__list_available",
&json!({}), &json!({}),
@@ -2175,12 +2175,8 @@ mod tests {
#[test] #[test]
fn dispatch_routes_task_list() { fn dispatch_routes_task_list() {
let mut ctx = ctx_with_supervisor(4, 3); let mut ctx = ctx_with_supervisor(4, 3);
let result = run_async(handle_supervisor_tool( let result =
&mut ctx, run_async(handle_agent_tool(&mut ctx, "agent__task_list", &json!({}))).unwrap();
"agent__task_list",
&json!({}),
))
.unwrap();
assert!(result["tasks"].is_array()); assert!(result["tasks"].is_array());
} }