fix(xai-responses): strip enum values containing '/' from tool schemas#28122
Merged
Conversation
xAI's /v1/responses and /v1/chat/completions endpoints reject tool schemas
whose enum values contain a forward slash with a generic HTTP 400 'Invalid
arguments passed to the model.' before any token is emitted — the schema
compiler trips on the '/' character regardless of where it appears.
Most commonly hit by MCP-derived tools whose enum lists HuggingFace model
IDs ('Qwen/Qwen3.5-0.8B', 'openai/gpt-oss-20b') or owner/name environment
identifiers.
Mirrors the existing strip_pattern_and_format sanitizer (PR for #27197).
The new strip_slash_enum walks tool parameters and drops the entire enum
keyword when any value contains '/' — keeping it partial would still 400
since xAI's failure is all-or-nothing on the enum. The field description
still reaches the model so the prompting hint is preserved.
Wired in at both code paths for parity:
- agent/chat_completion_helpers.py (main agent xAI Responses path)
- agent/auxiliary_client.py (aux client xAI Responses path, matching
the same parity guarantee 2fae8fb established for pattern/format)
Salvaged from #28021 by @Slimydog21 — contributor's branch was severely
stale (would have reverted ~5000 LOC across azure/kanban/i18n); fix
re-applied surgically on current main with their sanitizer + 9 tests
preserved verbatim. Author noreply email used (original was a Mac
hostname leak).
Contributor
🔎 Lint report:
|
| Rule | Count |
|---|---|
invalid-argument-type |
1 |
First entries
tests/tools/test_schema_sanitizer.py:618: [invalid-argument-type] invalid-argument-type: Argument to function `strip_slash_enum` is incorrect: Expected `list[dict[Unknown, Unknown]]`, found `None`
✅ Fixed issues: none
Unchanged: 4622 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
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.
Salvage of #28021 by @Slimydog21. Contributor's branch was severely stale (would have reverted ~5000 LOC across azure/kanban/i18n). Fix re-applied surgically on current main with their sanitizer + 9 tests preserved.
Summary
xAI's grammar compiler rejects
enumvalues containing/(HuggingFace IDs from MCP-derived tools) with the same opaque HTTP 400 'Invalid arguments passed to the model' it raises forpattern/format. Addsstrip_slash_enum()that drops the entire enum keyword (all-or-nothing — partial would still 400) but keeps the field description so the model still gets the prompting hint.Changes
tools/schema_sanitizer.py: newstrip_slash_enum()mirroringstrip_pattern_and_format()structureagent/chat_completion_helpers.py: wire into main-agent xAI Responses sanitization stepagent/auxiliary_client.py: same wire into aux-client xAI Responses path (parity with 2fae8fb for pattern/format)tests/tools/test_schema_sanitizer.py: 9 new testsscripts/release.py: AUTHOR_MAP noreply entryValidation
scripts/run_tests.sh tests/tools/test_schema_sanitizer.py→ 40/40 passing.Closes #28021 (salvage merge — contributor authorship preserved via noreply email).