Direct mode still batch-aborts on raw malformed tool argument JSON #304
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
nsaspy/prolog-rlm#304
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Reproducer
Auto-Dig live run
33433989280on Prolog-RLM6957c30c88f9548137a8ff9c3a0720f9bdadb210reached a real OpenRouter native-direct turn with six parallel read-onlymcp.brave.brave_web_searchcalls.Five calls contained valid JSON argument objects. One provider call emitted this raw argument string with duplicate keys:
normalize_arguments/2correctly classifies that call asmalformed_arguments, butnormalize_response_calls/2still invokesnative_tool_calls_normalize/2over the whole provider batch. The batch normalizer usesmaplist(normalize_native_call, Inputs, Calls), so this parse-level per-call fault becomesafter_call_normalization(error(...))and aborts every valid sibling beforeclassify_calls/4from #313 can isolate it.Observed top-level error:
Expected
The #313 recoverability rule should cover malformed raw provider argument JSON too, not only malformed arguments that survive native-call normalization and fail later schema/context validation.
A malformed call with a recoverable
malformed_argumentsfault should produce a structurednative_call_rejectedobservation for that original call ID/name while valid read-only siblings continue. Batch-fatal invariants must remain fail-closed: malformed/duplicate call envelope or IDs, duplicate IDs, unsupported call type, effect isolation, and budget violations must still abort before execution.Regression test
Add a direct partial-batch test whose provider response contains two calls:
id,type=function,function.name) whosefunction.argumentsis a JSON string containing duplicate keysAssert the valid sibling executes exactly once, the malformed sibling gets a bounded
malformed_argumentsobservation, and the loop can repair/finish on the next model turn.Also add the reverse ordering case so isolation is order-independent.