fix(tool-args): coerce JSON-encoded strings on str_replace_editor numeric args#54
Open
sp2935 wants to merge 1 commit intoFSoft-AI4Code:mainfrom
Open
fix(tool-args): coerce JSON-encoded strings on str_replace_editor numeric args#54sp2935 wants to merge 1 commit intoFSoft-AI4Code:mainfrom
sp2935 wants to merge 1 commit intoFSoft-AI4Code:mainfrom
Conversation
…eric args
Some local models routed through OpenAI compatible endpoints (LiteLLM,
vLLM, Ollama, etc.) emit list-typed and int-typed tool arguments as
JSON-encoded strings instead of proper structured values, e.g.
`"view_range": "[1, 50]"` rather than `"view_range": [1, 50]`. Pydantic
strict validation in pydantic-ai then rejects the call with:
ValidationError: 1 validation error for str_replace_editor
view_range
Input should be a valid array
[type=list_type, input_value='[1, 50]', input_type=str]
After the configured `max_retries` the run aborts with
`UnexpectedModelBehavior: Tool 'str_replace_editor' exceeded max retries`.
This patch adds a Pydantic `BeforeValidator` that parses a JSON-encoded
string back into its structured form before strict validation runs, on
the two args observed to fail in practice (`view_range` and
`insert_line`). The validator is a no-op when the value is already typed
correctly, so Anthropic native API users (who emit structured JSON tool
args) are unaffected.
Empirically validated: same model, same prompt, same repo, the only
change is this validator. Before patch: tool exceeds max retries on
every run. After patch: documentation generation completes successfully.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix
str_replace_editortool argument validation when CodeWiki runs against an OpenAI compatible backend (LiteLLM, vLLM, Ollama, etc.) instead of native Anthropic.Problem
Some local models emit list-typed and int-typed tool arguments as JSON-encoded strings rather than proper structured values:
{ "command": "view", "path": "/repo/foo.py", "view_range": "[1, 50]" ← string, not array }Pydantic strict validation in pydantic-ai then rejects the call with:
After the configured
max_retries, the run aborts withUnexpectedModelBehavior: Tool 'str_replace_editor' exceeded max retries. The same model under reasoning enabled mode hits this consistently.This makes CodeWiki effectively unusable on local LLM stacks, even though
--provider openai-compatibleis documented as a supported configuration.Fix
Add a Pydantic
BeforeValidatorthat parses a JSON-encoded string back into its structured form before strict validation runs. Applied to the two args observed to fail in practice:view_range(list) andinsert_line(int).The validator is a no-op when the value is already typed correctly. Anthropic native API users (whose tool calls already arrive as structured JSON) see no behavior change.
Empirical validation
Same model, same prompt, same target repo. The only change between runs is this patch:
Tool 'str_replace_editor' exceeded max retries count of 1. Generation aborted at the documentation phase. Reproduced on two different OpenAI compatible local models.Table of Contentsduplicates.The runtime check inside
EditTool.view(len(view_range) != 2 or not all(isinstance(i, int) for i in view_range)) still rejects malformed values that happen to slip through the JSON parse, so the failure surface is unchanged for genuinely bad input.Test plan
python -c "import ast; ast.parse(open('codewiki/src/be/agent_tools/str_replace_editor.py').read())"parses clean.Related
This addresses a class of issue similar to #50 (fallback-model persistence). Both surface as "configuration says X is supported but X breaks at runtime."