Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions src/askui/models/shared/thinking.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,17 @@ def make_thinking_settings(
**make_thinking_settings(self._vlm_provider.model_id),
)

Models that support adaptive thinking get ``thinking={"type": "adaptive"}``
(with ``effort`` sent via ``provider_options["output_config"]`` when given);
older models get a fixed token budget of
``thinking={"type": "enabled", "budget_tokens": 2048}`` and ignore ``effort``.
Models that support adaptive thinking get
``thinking={"type": "adaptive", "display": "summarized"}`` (with ``effort``
sent via ``provider_options["output_config"]`` when given); older models
get a fixed token budget of
``thinking={"type": "enabled", "budget_tokens": 2048}`` and ignore
``effort``. ``display`` is set explicitly because the newest adaptive
models (Sonnet 5 generation onward) default it to ``"omitted"``, which
returns thinking blocks whose text is EMPTY while the full thinking
tokens are still billed — reasoning silently disappears from reports and
logs. ``"summarized"`` restores the visible text at no extra cost (billing
is identical for both display modes).

Args:
model_id (str): The model identifier (bare or gateway-prefixed).
Expand All @@ -176,7 +183,9 @@ def make_thinking_settings(
when applicable, ``provider_options``).
"""
if uses_adaptive_thinking(model_id):
settings: dict[str, Any] = {"thinking": {"type": "adaptive"}}
settings: dict[str, Any] = {
Comment thread
philipph-askui marked this conversation as resolved.
"thinking": {"type": "adaptive", "display": "summarized"}
}
if effort is not None:
settings["provider_options"] = {"output_config": {"effort": effort}}
return settings
Expand Down
8 changes: 5 additions & 3 deletions tests/unit/models/test_thinking.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@
@pytest.mark.parametrize("model_id", _ADAPTIVE_MODELS)
def test_adaptive_models_use_adaptive_thinking(model_id: str) -> None:
assert uses_adaptive_thinking(model_id) is True
assert make_thinking_settings(model_id) == {"thinking": {"type": "adaptive"}}
assert make_thinking_settings(model_id) == {
"thinking": {"type": "adaptive", "display": "summarized"}
}


@pytest.mark.parametrize("model_id", _BUDGET_MODELS)
Expand All @@ -63,7 +65,7 @@ def test_other_models_use_budget_tokens(model_id: str) -> None:

def test_effort_is_added_via_provider_options_for_adaptive_models() -> None:
assert make_thinking_settings("claude-sonnet-5", effort="high") == {
"thinking": {"type": "adaptive"},
"thinking": {"type": "adaptive", "display": "summarized"},
"provider_options": {"output_config": {"effort": "high"}},
}

Expand Down Expand Up @@ -139,6 +141,6 @@ def test_non_thinking_settings_omit_thinking_on_always_on_models() -> None:

def test_effort_supports_xhigh() -> None:
assert make_thinking_settings("claude-opus-4-8", effort="xhigh") == {
"thinking": {"type": "adaptive"},
"thinking": {"type": "adaptive", "display": "summarized"},
"provider_options": {"output_config": {"effort": "xhigh"}},
}
Loading