Skip to content

Commit 897e5f5

Browse files
Ian Massinghamclaudecollindutter
authored
fix(drivers-prompt-anthropic): omit sampling params for claude-opus-4-7 (#2163)
* fix: omit sampling params for models that deprecate them (claude-opus-4-7) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(anthropic): gate sampling params via supports_* properties Mirrors the OpenAI driver convention by exposing supports_temperature, supports_top_p, and supports_top_k properties that _base_params consults, instead of inlining a model equality check. Uses startswith("claude-opus-4-7") so dated variants are covered. --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Collin Dutter <collin@griptape.ai>
1 parent 98f2d8a commit 897e5f5

2 files changed

Lines changed: 82 additions & 2 deletions

File tree

griptape/drivers/prompt/anthropic_prompt_driver.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,19 @@ def validate_structured_output_strategy(self, _: Attribute, value: str) -> str:
8686

8787
return value
8888

89+
@property
90+
def supports_temperature(self) -> bool:
91+
# claude-opus-4-7 and its dated variants deprecate sampling parameters
92+
return not self.model.startswith("claude-opus-4-7")
93+
94+
@property
95+
def supports_top_p(self) -> bool:
96+
return not self.model.startswith("claude-opus-4-7")
97+
98+
@property
99+
def supports_top_k(self) -> bool:
100+
return not self.model.startswith("claude-opus-4-7")
101+
89102
@observable
90103
def try_run(self, prompt_stack: PromptStack) -> Message:
91104
params = self._base_params(prompt_stack)
@@ -121,13 +134,20 @@ def _base_params(self, prompt_stack: PromptStack) -> dict:
121134
system_messages = prompt_stack.system_messages
122135
system_message = system_messages[0].to_text() if system_messages else None
123136

137+
if self.top_p is not None and self.supports_top_p:
138+
sampling_params = {"top_p": self.top_p}
139+
elif self.supports_temperature:
140+
sampling_params = {"temperature": self.temperature}
141+
else:
142+
sampling_params = {}
143+
124144
params = {
125145
"model": self.model,
126146
"stop_sequences": self.tokenizer.stop_sequences,
127147
"max_tokens": self.max_tokens,
128148
"messages": messages,
129-
**({"top_p": self.top_p} if self.top_p is not None else {"temperature": self.temperature}),
130-
**({"top_k": self.top_k} if self.top_k is not None else {}),
149+
**sampling_params,
150+
**({"top_k": self.top_k} if self.top_k is not None and self.supports_top_k else {}),
131151
**({"system": system_message} if system_message else {}),
132152
**self.extra_params,
133153
}

tests/unit/drivers/prompt/test_anthropic_prompt_driver.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,3 +459,63 @@ def test_verify_structured_output_strategy(self):
459459
ValueError, match="AnthropicPromptDriver does not support `native` structured output strategy."
460460
):
461461
AnthropicPromptDriver(model="foo", structured_output_strategy="native")
462+
463+
@pytest.mark.parametrize(
464+
("model", "expected"),
465+
[
466+
("claude-3-haiku", True),
467+
("claude-3-opus", True),
468+
("claude-sonnet-4-5", True),
469+
("claude-opus-4-7", False),
470+
("claude-opus-4-7-20251101", False),
471+
],
472+
)
473+
def test_supports_temperature(self, model, expected):
474+
driver = AnthropicPromptDriver(model=model, api_key="api-key")
475+
assert driver.supports_temperature == expected
476+
477+
@pytest.mark.parametrize(
478+
("model", "expected"),
479+
[
480+
("claude-3-haiku", True),
481+
("claude-3-opus", True),
482+
("claude-sonnet-4-5", True),
483+
("claude-opus-4-7", False),
484+
("claude-opus-4-7-20251101", False),
485+
],
486+
)
487+
def test_supports_top_p(self, model, expected):
488+
driver = AnthropicPromptDriver(model=model, api_key="api-key")
489+
assert driver.supports_top_p == expected
490+
491+
@pytest.mark.parametrize(
492+
("model", "expected"),
493+
[
494+
("claude-3-haiku", True),
495+
("claude-3-opus", True),
496+
("claude-sonnet-4-5", True),
497+
("claude-opus-4-7", False),
498+
("claude-opus-4-7-20251101", False),
499+
],
500+
)
501+
def test_supports_top_k(self, model, expected):
502+
driver = AnthropicPromptDriver(model=model, api_key="api-key")
503+
assert driver.supports_top_k == expected
504+
505+
def test_try_run_omits_sampling_params_for_opus_4_7(self, mock_client, prompt_stack, messages):
506+
# Given
507+
driver = AnthropicPromptDriver(
508+
model="claude-opus-4-7",
509+
api_key="api-key",
510+
top_p=0.9,
511+
top_k=100,
512+
)
513+
514+
# When
515+
driver.try_run(prompt_stack)
516+
517+
# Then
518+
call_kwargs = mock_client.return_value.messages.create.call_args
519+
assert "temperature" not in call_kwargs.kwargs
520+
assert "top_p" not in call_kwargs.kwargs
521+
assert "top_k" not in call_kwargs.kwargs

0 commit comments

Comments
 (0)