fix(xai): honor nested web_search filters on the xAI Responses API

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Devin AI 2026-08-25 22:27:34 +00:00 committed by yassin
parent 79d4d4d8f5
commit 3cb5ceb98c
2 changed files with 51 additions and 12 deletions

View file

@ -81,30 +81,24 @@ class XAIResponsesAPIConfig(OpenAIResponsesAPIConfig):
- enable_image_understanding
XAI does NOT support search_context_size (OpenAI-specific).
Domains may come nested under 'filters' (the OpenAI/XAI documented shape) or flat on the tool.
"""
xai_tool: Final[dict[str, object]] = {"type": "web_search"}
# Remove search_context_size if present (not supported by XAI)
if "search_context_size" in tool:
verbose_logger.info(
"XAI does not support 'search_context_size' parameter. Removing it from web_search tool."
)
# Handle filters (XAI-specific structure)
filters: Final = {}
if "allowed_domains" in tool:
allowed_domains: Final = tool["allowed_domains"]
filters["allowed_domains"] = allowed_domains
domains: Final = tool.get("filters") or tool
filters: Final = {
key: domains[key] for key in ("allowed_domains", "excluded_domains") if key in domains
}
if "excluded_domains" in tool:
excluded_domains: Final = tool["excluded_domains"]
filters["excluded_domains"] = excluded_domains
# Add filters if any were specified
if filters:
xai_tool["filters"] = filters
# Handle enable_image_understanding (top-level in XAI format)
if "enable_image_understanding" in tool:
xai_tool["enable_image_understanding"] = tool["enable_image_understanding"]

View file

@ -119,6 +119,51 @@ class TestXAIResponsesAPITransformation:
assert tool["filters"]["allowed_domains"] == ["wikipedia.org", "x.ai"]
assert tool["enable_image_understanding"] is True
def test_web_search_nested_filters_preserved(self):
"""The documented nested 'filters' shape must reach xAI instead of being dropped"""
config = XAIResponsesAPIConfig()
params = ResponsesAPIOptionalRequestParams(
tools=[
{
"type": "web_search",
"filters": {"allowed_domains": ["grokipedia.com"], "excluded_domains": ["example.com"]},
}
]
)
result = config.map_openai_params(
response_api_optional_params=params,
model="grok-4-1-fast",
drop_params=False,
)
tool = result["tools"][0]
assert tool["filters"]["allowed_domains"] == ["grokipedia.com"]
assert tool["filters"]["excluded_domains"] == ["example.com"]
def test_web_search_nested_filters_win_over_flat(self):
"""Nested filters take precedence when both shapes are sent"""
config = XAIResponsesAPIConfig()
params = ResponsesAPIOptionalRequestParams(
tools=[
{
"type": "web_search",
"allowed_domains": ["flat.com"],
"filters": {"allowed_domains": ["nested.com"]},
}
]
)
result = config.map_openai_params(
response_api_optional_params=params,
model="grok-4-1-fast",
drop_params=False,
)
assert result["tools"][0]["filters"] == {"allowed_domains": ["nested.com"]}
def test_web_search_search_context_size_removed(self):
"""Test that search_context_size is removed from web_search tools"""
config = XAIResponsesAPIConfig()