mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-19 21:32:20 +03:00
Google validates every `functionDeclarations[].name` against one grammar and rejects the WHOLE GenerateContentRequest when any single one is invalid, so six `1c_*` tools in a 109-tool MCP catalog made every request 400, including requests that would never call them (#13715). `normalizeGeminiToolName` removed invalid characters, collapsed underscores and stripped leading and trailing ones, none of which touches a leading digit. The strip is also why a leading underscore was not a workaround: the client's `_1c_probe` was normalized back to `1c_probe` and rejected for the same reason. The prefix goes inside the normalizer rather than at the call site, because that keeps the guarantee on the one value every path reads. `buildHashedGemini ToolName` builds its name from the normalized string and inherits its first character, so a fix applied later would hold for short names and fail silently for the long ones a 109-tool catalog is full of. It also runs before the collision check, so two names that newly collide are still separated by the existing hashed path. The reverse direction needs nothing: the sanitized name now differs from the client's, so `buildChangedToolNameMap` carries the original and the response translator restores the client's spelling on the model's functionCall. Six cells: no declared name starts with a digit, a leading underscore reaches Google letter-first, the reverse map returns the client's spelling, a letter-first name is untouched, an over-long digit-first name keeps the guarantee through the hash path, and two colliding digit-first names stay distinct. Four mutations, all killed.