xai: drop unsupported 'stop' parameter for grok-3 models

The grok-3 model family rejects the legacy 'stop' parameter with a 400
BadRequestError rather than ignoring it. Override _get_request_payload
on ChatXAI to silently strip 'stop' from the outbound payload when the
model name starts with 'grok-3', so shared configurations across xAI
models don't hard-fail on grok-3.

Other models (e.g. grok-4) continue to forward 'stop' unchanged.
This commit is contained in:
LangSmith Issues Agent
2026-05-26 18:58:50 +00:00
parent 7bb4130c7d
commit 518ed3360d
2 changed files with 34 additions and 0 deletions

View File

@@ -535,6 +535,21 @@ class ChatXAI(BaseChatOpenAI): # type: ignore[override]
def _resolve_model_profile(self) -> ModelProfile | None:
return _get_default_model_profile(self.model_name) or None
def _get_request_payload(
self,
input_: LanguageModelInput,
*,
stop: list[str] | None = None,
**kwargs: Any,
) -> dict:
payload = super()._get_request_payload(input_, stop=stop, **kwargs)
# The grok-3 family rejects the `stop` parameter with a 400 error
# rather than ignoring it. Drop it silently so calls that set `stop`
# for other models in a shared code path don't hard-fail on grok-3.
if self.model_name and self.model_name.startswith("grok-3"):
payload.pop("stop", None)
return payload
def _stream(self, *args: Any, **kwargs: Any) -> Iterator[ChatGenerationChunk]:
"""Route to Chat Completions or Responses API."""
if self._use_responses_api({**kwargs, **self.model_kwargs}):

View File

@@ -159,3 +159,22 @@ def test_stream_usage_metadata() -> None:
model = ChatXAI(model=MODEL_NAME, stream_usage=False)
assert model.stream_usage is False
def test_chat_xai_grok_3_strips_stop_from_payload() -> None:
"""grok-3 family rejects the `stop` param; ensure it's stripped from payload."""
llm = ChatXAI(model="grok-3", api_key=SecretStr("test-api-key"), stop=["END"])
payload = llm._get_request_payload([HumanMessage(content="hi")])
assert "stop" not in payload
# Also covers forward-compat variants like `grok-3-mini`, `grok-3-fast`, etc.
llm_variant = ChatXAI(
model="grok-3-mini", api_key=SecretStr("test-api-key"), stop=["END"]
)
payload_variant = llm_variant._get_request_payload([HumanMessage(content="hi")])
assert "stop" not in payload_variant
# Sanity check: other models still forward `stop`.
llm_other = ChatXAI(model="grok-4", api_key=SecretStr("test-api-key"), stop=["END"])
payload_other = llm_other._get_request_payload([HumanMessage(content="hi")])
assert payload_other.get("stop") == ["END"]