-
Stefy Lanza (nextime / spora ) authored
The gemma-4 native call:NAME{…} heuristic could eat legitimate text: the content stripper removed ANY call:/response:{…} span with no tool-name restriction, so a coding reply containing e.g. call:foo{…} in prose or a snippet got silently deleted; and with no tools declared the parser matched any call:word{. Add a 3-way mode, resolved per-model (models.json "gemma_tool_parser") over the global models.gemma_tool_parser (default "restricted"): * full - parse & strip every call:/response: span (old behavior) * restricted - only when NAME is a declared tool; legit call:foo{…} prose/code is preserved, real declared-tool calls still parse & strip * off - disable the gemma heuristic entirely (bigger models that emit standard structured tool calls) resolve_gemma_tool_mode() + a centralized strip_gemma_native() now gate both the parse (GemmaParser, via the dispatcher) and the strip (ModelParserAdapter and the streaming ToolCallParser, which now stashes the declared tool names from extract_tool_calls so 'restricted' works on the streaming finalizer too). Co-Authored-By:Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RdMufYvtTbtGDWsiZVoXce
c7105023