Add approved dynamic tool arguments steering

This commit is contained in:
Qiyao Qin
2026-03-15 18:28:02 -07:00
parent d692b74007
commit 2aef39aac9
15 changed files with 1344 additions and 9 deletions

View File

@@ -5634,6 +5634,9 @@ pub struct PermissionsRequestApprovalResponse {
pub struct DynamicToolCallResponse {
pub content_items: Vec<DynamicToolCallOutputContentItem>,
pub success: bool,
/// Optional client-approved replacement arguments. When present, this must
/// fully match the existing registered schema for the same dynamic tool.
pub approved_arguments: Option<JsonValue>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
@@ -7640,6 +7643,7 @@ mod tests {
text: "dynamic-ok".to_string(),
}],
success: true,
approved_arguments: None,
})
.unwrap();
@@ -7652,6 +7656,7 @@ mod tests {
"text": "dynamic-ok"
}
],
"approvedArguments": null,
"success": true,
})
);
@@ -7669,6 +7674,7 @@ mod tests {
},
],
success: true,
approved_arguments: None,
})
.unwrap();
@@ -7685,11 +7691,51 @@ mod tests {
"imageUrl": "data:image/png;base64,AAA"
}
],
"approvedArguments": null,
"success": true,
})
);
}
#[test]
fn dynamic_tool_response_round_trips_non_null_approved_arguments() {
let value = serde_json::to_value(DynamicToolCallResponse {
content_items: vec![DynamicToolCallOutputContentItem::InputText {
text: "dynamic-ok".to_string(),
}],
success: true,
approved_arguments: Some(json!({ "city": "Tokyo" })),
})
.unwrap();
assert_eq!(
value,
json!({
"contentItems": [
{
"type": "inputText",
"text": "dynamic-ok"
}
],
"approvedArguments": {
"city": "Tokyo"
},
"success": true,
})
);
assert_eq!(
serde_json::from_value::<DynamicToolCallResponse>(value).unwrap(),
DynamicToolCallResponse {
content_items: vec![DynamicToolCallOutputContentItem::InputText {
text: "dynamic-ok".to_string(),
}],
success: true,
approved_arguments: Some(json!({ "city": "Tokyo" })),
}
);
}
#[test]
fn dynamic_tool_spec_deserializes_defer_loading() {
let value = json!({