chore(llm): Hardening Fallback Tool Call#8325
Conversation
Greptile OverviewGreptile SummaryHardens the fallback tool-call parser to correctly handle nested argument objects. The previous implementation used simple deduplication that would collapse any consecutive identical tool calls, including intentional duplicates. This PR refines the logic to only skip nested argument objects (e.g., when Key Changes:
Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant LLM as LLM Response
participant Parser as extract_tool_calls_from_response_text
participant JSONFinder as find_all_json_objects
participant Matcher as _try_match_json_to_tool
participant DupCheck as _is_nested_arguments_duplicate
participant Extractor as _extract_nested_arguments_obj
LLM->>Parser: response_text with tool calls
Parser->>JSONFinder: Extract all JSON objects
JSONFinder-->>Parser: [json_obj1, json_obj2, ...]
loop For each json_obj
Parser->>Matcher: Try to match to tool
Matcher-->>Parser: (tool_name, tool_args) or None
alt Has previous tool call
Parser->>Parser: Check if matched_tool_call == prev_tool_call
alt Tool calls match
Parser->>DupCheck: Is current_json_obj nested duplicate?
DupCheck->>Extractor: Extract args from prev_json_obj
Extractor-->>DupCheck: nested_args or None
DupCheck->>DupCheck: Compare current_json_obj == nested_args
DupCheck-->>Parser: True (skip) or False (keep)
end
end
alt Not a nested duplicate
Parser->>Parser: Add to matched_tool_calls
Parser->>Parser: Update prev_json_obj & prev_tool_call
end
end
Parser-->>LLM: List of ToolCallKickoff objects
|
There was a problem hiding this comment.
1 issue found across 2 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="backend/onyx/chat/llm_step.py">
<violation number="1" location="backend/onyx/chat/llm_step.py:350">
P2: The strict equality check `matched_tool_call == prev_tool_call` prevents deduplication when `_try_match_json_to_tool` produces different results for the outer tool call versus the inner arguments object.
This happens because Format 1 (direct tool call) returns arguments as-is (including extra keys), while Format 4 (parameter schema match) filters arguments to only known properties. If an extra argument is present, the equality check fails, and the nested argument object is incorrectly added as a duplicate tool call. Since `_is_nested_arguments_duplicate` already verifies that the current object is structurally identical to the previous tool's arguments, the equality check is unnecessary and harmful.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| if ( | ||
| prev_json_obj is not None | ||
| and prev_tool_call is not None | ||
| and matched_tool_call == prev_tool_call |
There was a problem hiding this comment.
P2: The strict equality check matched_tool_call == prev_tool_call prevents deduplication when _try_match_json_to_tool produces different results for the outer tool call versus the inner arguments object.
This happens because Format 1 (direct tool call) returns arguments as-is (including extra keys), while Format 4 (parameter schema match) filters arguments to only known properties. If an extra argument is present, the equality check fails, and the nested argument object is incorrectly added as a duplicate tool call. Since _is_nested_arguments_duplicate already verifies that the current object is structurally identical to the previous tool's arguments, the equality check is unnecessary and harmful.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At backend/onyx/chat/llm_step.py, line 350:
<comment>The strict equality check `matched_tool_call == prev_tool_call` prevents deduplication when `_try_match_json_to_tool` produces different results for the outer tool call versus the inner arguments object.
This happens because Format 1 (direct tool call) returns arguments as-is (including extra keys), while Format 4 (parameter schema match) filters arguments to only known properties. If an extra argument is present, the equality check fails, and the nested argument object is incorrectly added as a duplicate tool call. Since `_is_nested_arguments_duplicate` already verifies that the current object is structurally identical to the previous tool's arguments, the equality check is unnecessary and harmful.</comment>
<file context>
@@ -333,20 +333,32 @@ def extract_tool_calls_from_response_text(
+ if (
+ prev_json_obj is not None
+ and prev_tool_call is not None
+ and matched_tool_call == prev_tool_call
+ and _is_nested_arguments_duplicate(
+ previous_json_obj=prev_json_obj,
</file context>
Description
Building upon on the previous PR that was merged in here: #8290
There was an issue with nested tool calls which was addressed. This PR aims to harden this so we don't cause more issues in the future around how we are parsing the individual tool calls.
Previously
extract_tool_calls_from_response_textwould treat the nested objects as separate tool calls.How Has This Been Tested?
Added more tests and ran against existing tests.
Additional Options
Summary by cubic
Hardens tool-call parsing to stop nested argument objects from being treated as separate calls. Prevents duplicate invocations while keeping intentional repeats.
Written for commit 0769fd5. Summary will update on new commits.