Support catalog descriptions for all multi-agent V2 tools (#46297)

## Why

Model catalog description overrides only covered `spawn_agent`, leaving the other multi-agent V2 tools with fixed descriptions.

## What changed

Extend `model_messages.tools.multi_agent` description overrides to `send_message`, `followup_task`, `wait_agent`, `interrupt_agent`, and `list_agents`. Resolve each override by tool name across namespaced, plain, and Code Mode exposure.

Missing or null descriptions retain bundled text; empty strings suppress static text without disabling tools. Preserve `spawn_agent` runtime guidance, tool schemas, and execution behavior. Descriptions follow mid-turn model changes.

## Testing

Expand integration coverage to all six tools, including missing, null, empty, and sparse overrides; plain, namespaced, and Code Mode exposure; unchanged V1 behavior; and mid-turn model changes.

GitOrigin-RevId: a2c47eb8efb28c3eeebcc6482e36c188c38a6dd1
This commit is contained in:
rhan-oai
2026-09-17 20:05:47 +00:00
committed by copyberry
parent 17baabd01b
commit 3e581ebca8
10 changed files with 401 additions and 191 deletions
+13 -2
View File
@@ -583,8 +583,8 @@ pub struct ToolMessages {
/// Model-owned messages for a built-in tool.
#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq, Eq, TS, JsonSchema)]
pub struct ToolMessage {
/// Missing or null uses the built-in description; an empty string leaves the description
/// empty without disabling the tool.
/// Missing or null uses the built-in description; an empty string suppresses its static
/// text without disabling the tool. Tool-owned runtime guidance is retained.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
@@ -596,6 +596,16 @@ pub struct MultiAgentToolMessages {
/// suppresses it. Generated model information and local usage hints are retained.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub spawn_agent: Option<ToolMessage>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub send_message: Option<ToolMessage>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub followup_task: Option<ToolMessage>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub wait_agent: Option<ToolMessage>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub interrupt_agent: Option<ToolMessage>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub list_agents: Option<ToolMessage>,
}
/// Model-owned defaults for the context-window token-budget feature.
@@ -1387,6 +1397,7 @@ mod tests {
spawn_agent: Some(ToolMessage {
description: Some("Catalog spawn description".to_string()),
}),
..Default::default()
}),
}),
instructions_template: None,