Skip to content

Commit c604b90

Browse files
authored
fix: use semantic JSON comparison for MCP approval argument matching (#5080)
## Summary MCP tool approval matching fails intermittently because LLMs may serialize tool call arguments differently between the first turn (where the approval request is created) and the second turn (where the approval is looked up). For example, the first call may include `{"liquid_name":"x","celsius":true}` while the re-invocation omits the defaulted field: `{"liquid_name":"x"}`. The current code compares argument strings with `==`, so these are treated as different tool calls and a new approval request is emitted instead of honoring the one the user already approved. This change parses the JSON before comparing so that semantically identical arguments match regardless of serialization differences. ## Test plan Existing `test_response_mcp_tool_approval` integration test covers this path. Made with [Cursor](https://cursor.com)
1 parent 424ff0c commit c604b90

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

  • src/llama_stack/providers/inline/agents/meta_reference/responses

src/llama_stack/providers/inline/agents/meta_reference/responses/types.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# This source code is licensed under the terms described in the LICENSE file in
55
# the root directory of this source tree.
66

7+
import json
78
from dataclasses import dataclass
89
from typing import cast
910

@@ -34,6 +35,14 @@
3435
)
3536

3637

38+
def _json_equal(a: str, b: str) -> bool:
39+
"""Compare two JSON strings by value, falling back to string comparison."""
40+
try:
41+
return json.loads(a) == json.loads(b)
42+
except (json.JSONDecodeError, TypeError):
43+
return a == b
44+
45+
3746
class ToolExecutionResult(BaseModel):
3847
"""Result of streaming tool execution."""
3948

@@ -210,7 +219,7 @@ def approval_response(self, tool_name: str, arguments: str) -> OpenAIResponseMCP
210219

211220
def _approval_request(self, tool_name: str, arguments: str) -> OpenAIResponseMCPApprovalRequest | None:
212221
for request in self.approval_requests:
213-
if request.name == tool_name and request.arguments == arguments:
222+
if request.name == tool_name and _json_equal(request.arguments, arguments):
214223
return request
215224
return None
216225

0 commit comments

Comments
 (0)