[Platform] Keep forward slashes unescaped in tool call arguments - #2504
Conversation
|
Hi @solverat, thanks for checking in, how did you discover the issue? never had a problem with that? is it reproducible? |
|
Hi, I ran into it while debugging a chat turn that kept failing on a path filter. The model sent The encoding side is fully reproducible, and that is the snippet in the PR. Call Whether the model then sends the backslash back varies from run to run. It needs a tool call that goes back into the history, an argument containing a slash, and a retry after a failed call. We saw it in three of five runs of the same prompt. With a single call it never happens, because the arguments never reach the model again. |
|
Just super curious here because this change has impact horizontally across ... well, almost everywhere :D that's actually why i closed the mentioned #2087 @symfony/ai any opinion? never had that issue myself |
|
The encoding difference is 100% reproducible without a provider, and tests stay green. Different footing than #2087. That one's root cause was never confirmed and touched the whole body for one bridge. This touches one field but reaches most bridges through the shared normalizer. Narrower change, proven mechanism. I'd land it. |
|
Thank you @solverat. |
…n tool call arguments (chr-hertel) This PR was merged into the main branch. Discussion ---------- [Examples] Update replay cassettes for unescaped slashes in tool call arguments | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | Docs? | no | Issues | - | License | MIT #2504 encodes tool call `arguments` with `JSON_UNESCAPED_SLASHES`, but the replay cassettes still hold `https:\/\/…`, so `Integration / Examples (replay)` fails on every PR since. * Unescape slashes in the recorded tool call `arguments` of `toolbox/{tavily,brave,firecrawl-map,firecrawl-scrape}` and `openai/agent-stream-sources` * Recompute the request signatures of the touched interactions, no re-recording needed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Commits ------- 499d0d5 [Examples] Update replay cassettes for unescaped slashes in tool call arguments
ToolCallNormalizerencodes a tool call's arguments withjson_encode()and no flags. PHP escapes forward slashes by default, so/de/shopis written as\/de\/shop. That is valid JSON, and any decoder returns the original string.The problem is that these arguments are not only sent to the provider. They also come back to the model as the text of its own previous call, and the model reads that text instead of decoding it. It sees a backslash, assumes the value contains one, and escapes it on the next attempt. The next call then arrives with a real backslash in the path.
This only happens after a failed call, because that is when the previous call is part of the history.
#2087 asked how much impact this has: For model names the answer depends on the backend, because a router compares the string. For tool call arguments the reader is the model itself, so every provider is affected.
The fix is the same line in the two normalizers that encode arguments. The Ollama normalizer passes the array through and needs no change. Neither class had tests, so I added them.