mirror of
https://github.com/openai/codex.git
synced 2026-10-30 19:18:49 +00:00
Expose MCP read-only hints in tool call items (#36055)
## What changed - Propagate MCP tool `readOnlyHint` annotations through tool-call start and completion events. - Include the optional hint in persisted thread history and app-server `mcpToolCall` items, preserving compatibility when the annotation is absent. - Document that the hint describes tool capability, not the outcome of a particular invocation. ## Testing - Cover read-only and write-capable tools in live events and persisted rollout data. - Verify the hint survives thread reads and resumes for both in-progress and completed MCP calls. GitOrigin-RevId: dddfe905146075e5137a1094da485b86b99807f0
This commit is contained in:
@@ -787,6 +787,7 @@ impl ThreadHistoryBuilder {
|
||||
}),
|
||||
mcp_app_resource_uri: payload.mcp_app_resource_uri.clone(),
|
||||
plugin_id: payload.plugin_id.clone(),
|
||||
read_only_hint: payload.read_only_hint,
|
||||
result: None,
|
||||
error: None,
|
||||
duration_ms: None,
|
||||
@@ -839,6 +840,7 @@ impl ThreadHistoryBuilder {
|
||||
}),
|
||||
mcp_app_resource_uri: payload.mcp_app_resource_uri.clone(),
|
||||
plugin_id: payload.plugin_id.clone(),
|
||||
read_only_hint: payload.read_only_hint,
|
||||
result,
|
||||
error,
|
||||
duration_ms,
|
||||
@@ -2782,6 +2784,7 @@ mod tests {
|
||||
app_name: None,
|
||||
action_name: None,
|
||||
plugin_id: None,
|
||||
read_only_hint: None,
|
||||
duration: Duration::from_millis(8),
|
||||
result: Err("boom".into()),
|
||||
}),
|
||||
@@ -2840,6 +2843,7 @@ mod tests {
|
||||
app_context: None,
|
||||
mcp_app_resource_uri: None,
|
||||
plugin_id: None,
|
||||
read_only_hint: None,
|
||||
result: None,
|
||||
error: Some(McpToolCallError {
|
||||
message: "boom".into(),
|
||||
@@ -2872,6 +2876,7 @@ mod tests {
|
||||
app_name: Some("Calendar".into()),
|
||||
action_name: Some("lookup".into()),
|
||||
plugin_id: Some("sample@test".into()),
|
||||
read_only_hint: Some(false),
|
||||
duration: Duration::from_millis(8),
|
||||
result: Ok(CallToolResult {
|
||||
content: vec![serde_json::json!({
|
||||
@@ -2910,6 +2915,7 @@ mod tests {
|
||||
}),
|
||||
mcp_app_resource_uri: Some("ui://widget/lookup.html".into()),
|
||||
plugin_id: Some("sample@test".into()),
|
||||
read_only_hint: Some(false),
|
||||
result: Some(Box::new(McpToolCallResult {
|
||||
content: vec![serde_json::json!({
|
||||
"type": "text",
|
||||
|
||||
@@ -317,6 +317,7 @@ pub enum ThreadItem {
|
||||
/// Deprecated: use `appContext.resourceUri` instead.
|
||||
mcp_app_resource_uri: Option<String>,
|
||||
plugin_id: Option<String>,
|
||||
read_only_hint: Option<bool>,
|
||||
result: Option<Box<McpToolCallResult>>,
|
||||
error: Option<McpToolCallError>,
|
||||
/// The duration of the MCP tool call in milliseconds.
|
||||
@@ -961,6 +962,7 @@ impl From<CoreTurnItem> for ThreadItem {
|
||||
}),
|
||||
mcp_app_resource_uri: mcp.mcp_app_resource_uri,
|
||||
plugin_id: mcp.plugin_id,
|
||||
read_only_hint: mcp.read_only_hint,
|
||||
result: mcp.result.map(McpToolCallResult::from).map(Box::new),
|
||||
error: mcp.error.map(McpToolCallError::from),
|
||||
duration_ms,
|
||||
|
||||
@@ -3144,6 +3144,7 @@ fn core_turn_item_into_thread_item_converts_supported_variants() {
|
||||
app_name: Some("Calendar".to_string()),
|
||||
action_name: Some("create_event".to_string()),
|
||||
plugin_id: Some("sample@test".to_string()),
|
||||
read_only_hint: Some(true),
|
||||
status: CoreMcpToolCallStatus::InProgress,
|
||||
result: None,
|
||||
error: None,
|
||||
@@ -3167,6 +3168,7 @@ fn core_turn_item_into_thread_item_converts_supported_variants() {
|
||||
}),
|
||||
mcp_app_resource_uri: Some("app://connector".to_string()),
|
||||
plugin_id: Some("sample@test".to_string()),
|
||||
read_only_hint: Some(true),
|
||||
result: None,
|
||||
error: None,
|
||||
duration_ms: None,
|
||||
@@ -3184,6 +3186,7 @@ fn core_turn_item_into_thread_item_converts_supported_variants() {
|
||||
app_name: None,
|
||||
action_name: None,
|
||||
plugin_id: None,
|
||||
read_only_hint: Some(false),
|
||||
status: CoreMcpToolCallStatus::Completed,
|
||||
result: Some(CallToolResult {
|
||||
content: vec![json!({"type": "text", "text": "ok"})],
|
||||
@@ -3206,6 +3209,7 @@ fn core_turn_item_into_thread_item_converts_supported_variants() {
|
||||
app_context: None,
|
||||
mcp_app_resource_uri: None,
|
||||
plugin_id: None,
|
||||
read_only_hint: Some(false),
|
||||
result: Some(Box::new(McpToolCallResult {
|
||||
content: vec![json!({"type": "text", "text": "ok"})],
|
||||
structured_content: Some(json!({"ok": true})),
|
||||
@@ -3234,6 +3238,7 @@ fn mcp_tool_call_app_context_serializes_connector_id() {
|
||||
}),
|
||||
mcp_app_resource_uri: Some("app://connector".to_string()),
|
||||
plugin_id: None,
|
||||
read_only_hint: Some(false),
|
||||
result: None,
|
||||
error: None,
|
||||
duration_ms: None,
|
||||
@@ -3257,6 +3262,7 @@ fn mcp_tool_call_app_context_serializes_connector_id() {
|
||||
},
|
||||
"mcpAppResourceUri": "app://connector",
|
||||
"pluginId": null,
|
||||
"readOnlyHint": false,
|
||||
"result": null,
|
||||
"error": null,
|
||||
"durationMs": null,
|
||||
|
||||
Reference in New Issue
Block a user