Skip to content
Closed
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

## [Unreleased]

### Fixed
- Reasoning-effort detection now recognises GLM models (`zai.glm-5`, `zai.glm-4.7`, `glm-5`, etc.) and Claude family-before-version names (`claude-opus-4-8`, `claude-haiku-4-5`, `anthropic.claude-opus-4-8`) as thinking-capable when accessed through named custom providers. Both were missed by PR #3327's family list even though the dot-namespace stripping it introduced correctly surfaces the bare model name.

## [v0.51.210] — 2026-06-02 — Release GD (stage-batch1 — model-picker multi-slash fix + extensionless preview highlighting)

### Fixed
Expand Down
6 changes: 6 additions & 0 deletions api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2140,12 +2140,18 @@ def _candidate_supports_reasoning(candidate: str) -> bool:
return True
if normalized.startswith(("kimi-k2", "kimi-thinking", "claude-3", "claude-4")):
return True
# claude-opus-4-8 / claude-haiku-4-5 style (family-before-version)
if normalized.startswith("claude-") and token_set & {"3", "4"}:
return True
if normalized.startswith("qwen3") or "qwen3" in token_set:
return True
if normalized.startswith(("deepseek-v3", "deepseek-v4", "deepseek-r1", "deepseek-r2")):
return True
if len(tokens) >= 2 and tokens[0] == "deepseek" and tokens[1] in {"v3", "v4", "r1", "r2"}:
return True
# GLM models (ZAI / Zhipu AI) — all modern generations (4.5+) support reasoning
if normalized.startswith("glm-"):
return True
return False


Expand Down
45 changes: 45 additions & 0 deletions tests/test_custom_provider_bare_model_reasoning.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,51 @@ def test_vendor_prefix_keyword_does_not_trigger_reasoning(model_id):
) == []


# ── GLM models (ZAI / Zhipu AI) ──────────────────────────────────────────────

@pytest.mark.parametrize(
"model_id",
[
"zai.glm-5",
"zai.glm-4.7",
"zai.glm-4.6",
"zai.glm-4.7-flash",
"glm-5",
"glm-4.5",
],
)
def test_glm_dot_separated_custom_provider(model_id):
efforts = cfg.resolve_model_reasoning_efforts(
model_id,
provider_id="custom:newapi",
)
assert set(efforts) >= {"low", "medium", "high"}, (
f"{model_id} via custom provider should expose reasoning efforts"
)


# ── Claude family-before-version naming (claude-opus-4-8, claude-haiku-4-5) ──

@pytest.mark.parametrize(
"model_id",
[
"anthropic.claude-opus-4-8",
"anthropic.claude-haiku-4-5",
"anthropic.claude-opus-4-7",
"claude-opus-4-8",
"claude-haiku-4-5",
],
)
def test_claude_family_version_naming_custom_provider(model_id):
efforts = cfg.resolve_model_reasoning_efforts(
model_id,
provider_id="custom:newapi",
)
assert set(efforts) >= {"low", "medium", "high"}, (
f"{model_id} via custom provider should expose reasoning efforts"
)


# ── slash-prefixed names must still work (no regression) ─────────────────────

def test_deepseek_slash_prefix_still_works():
Expand Down
Loading