mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-19 15:18:03 +00:00
fix(upstage): collapse unknown future efforts to high; behavior-contract tests
Review findings from the 4-angle pass: - Unknown-but-enabled effort levels now collapse to Solar's strongest (high) instead of silently downgrading to the medium default — guards against the next #62650-style vocabulary addition. Explicit-empty effort keeps the medium default. - fallback_models test now asserts the behavior contract (non-empty, no denied families) instead of freezing the exact model tuple (change-detector, AGENTS.md reject reason). - Drop unused pytest import in test_upstage_provider.py.
This commit is contained in:
parent
33dfb7e4ec
commit
1f41bdbecd
3 changed files with 24 additions and 10 deletions
|
|
@ -76,18 +76,20 @@ class UpstageProfile(ProviderProfile):
|
|||
return {}, top_level
|
||||
|
||||
# Map Hermes' effort vocabulary onto Solar's accepted set. xhigh/max/
|
||||
# ultra collapse to high (Solar's strongest). minimal → off (omit). An
|
||||
# enabled request with no recognised effort uses the default effort.
|
||||
# ultra collapse to high (Solar's strongest). minimal → off (omit).
|
||||
# Unknown-but-enabled efforts (future vocabulary additions above
|
||||
# "high", per the max/ultra precedent in #62650) also collapse to
|
||||
# high rather than silently downgrading to the medium default.
|
||||
effort = (reasoning_config.get("effort") or "").strip().lower()
|
||||
if not effort:
|
||||
top_level["reasoning_effort"] = _DEFAULT_REASONING_EFFORT
|
||||
return {}, top_level
|
||||
mapped = {
|
||||
"minimal": None,
|
||||
"low": "low",
|
||||
"medium": "medium",
|
||||
"high": "high",
|
||||
"xhigh": "high",
|
||||
"max": "high",
|
||||
"ultra": "high",
|
||||
}.get(effort, _DEFAULT_REASONING_EFFORT)
|
||||
}.get(effort, "high")
|
||||
|
||||
if mapped:
|
||||
top_level["reasoning_effort"] = mapped
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ from __future__ import annotations
|
|||
import sys
|
||||
import types
|
||||
|
||||
import pytest
|
||||
|
||||
if "dotenv" not in sys.modules:
|
||||
fake_dotenv = types.ModuleType("dotenv")
|
||||
|
|
|
|||
|
|
@ -49,9 +49,12 @@ class TestUpstageProfile:
|
|||
# Only the agentic, tool-calling Solar Pro models belong in the offline
|
||||
# catalog — Mini is capable but not agentic, so it's never promoted as a
|
||||
# default. Live /v1/models still surfaces everything when a key is set.
|
||||
assert upstage_profile.fallback_models == (
|
||||
"solar-pro3",
|
||||
)
|
||||
# Behavior contract (not a frozen list): non-empty, no denied families.
|
||||
assert upstage_profile.fallback_models
|
||||
for denied in ("solar-mini", "syn-pro"):
|
||||
assert not any(
|
||||
denied in m for m in upstage_profile.fallback_models
|
||||
), f"non-agentic family {denied!r} must not be a fallback default"
|
||||
|
||||
def test_default_model_is_solar_pro3(self, upstage_profile):
|
||||
# Entry [0] is the setup default (get_default_model_for_provider).
|
||||
|
|
@ -85,6 +88,16 @@ class TestUpstageReasoning:
|
|||
)
|
||||
assert top_level == {"reasoning_effort": "high"}
|
||||
|
||||
def test_unknown_future_effort_collapses_to_high(self, upstage_profile):
|
||||
# Guard against the #62650 recurrence: a future effort level Hermes
|
||||
# adds above "high" must collapse to Solar's strongest, not silently
|
||||
# downgrade to the medium default.
|
||||
_, top_level = upstage_profile.build_api_kwargs_extras(
|
||||
reasoning_config={"enabled": True, "effort": "hyperthink"},
|
||||
model="solar-pro3",
|
||||
)
|
||||
assert top_level == {"reasoning_effort": "high"}
|
||||
|
||||
def test_pro_enabled_without_effort_defaults_on(self, upstage_profile):
|
||||
_, top_level = upstage_profile.build_api_kwargs_extras(
|
||||
reasoning_config={"enabled": True}, model="solar-pro3"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue