test: prune low-value tests suite-wide (wave 1) — 46,820 → 28,106 test functions
Systematic prune per AGENTS.md test policy, one pass over every major test tree (gateway, hermes_cli, tools, agent, run_agent, plugins, cli, cron, tui_gateway, honcho/openviking, root-level): - DELETE: source-reading tests (read_text/getsource on prod files), change-detector tests (exact catalog counts, model-name snapshots, config version literals), mock-echo tests (assert a mock returns what it was told), assertion-free/trivial tests, near-duplicate parametrizations (boundaries + one representative kept), async/sync twin duplicates, cosmetic within-file variations. - KEEP (mandatory): security/redaction/approval guards, message-role alternation invariants, prompt-caching/deterministic-call-id invariants, issue-number regression tests (deduped), E2E tests. - 6 test files deleted outright (script-style/no-assert or fully redundant); conftest.py, fakes/, fixtures/ untouched. - tests/acp/conftest.py added: autouse fixture stubs the live models.dev/GitHub/Copilot/Anthropic inventory fetches that ACP server tests performed on every session create — test_server.py 147s → 3.4s, and the tests are now genuinely hermetic. - Sleep-based slowness shrunk where safe (codex_ttfb_watchdog, compression_concurrent_fork, etc.); no wall-clock assertion tightened. Verification: full hermetic suite via scripts/run_tests.sh — 2439 files, 31,130 tests passed, 0 failed, 0 flaky retries, 315s wall (baseline: 583s wall, 13,564s subprocess CPU).
This commit is contained in:
@@ -19,29 +19,7 @@ def _msgs():
|
||||
|
||||
|
||||
class TestNvidiaProfileWiring:
|
||||
def test_nvidia_gets_default_max_tokens(self, transport):
|
||||
profile = get_provider_profile("nvidia")
|
||||
kwargs = transport.build_kwargs(
|
||||
model="nvidia/llama-3.1-nemotron-70b-instruct",
|
||||
messages=_msgs(),
|
||||
tools=None,
|
||||
provider_profile=profile,
|
||||
max_tokens=None,
|
||||
max_tokens_param_fn=lambda x: {"max_tokens": x} if x else {},
|
||||
timeout=300,
|
||||
reasoning_config=None,
|
||||
request_overrides=None,
|
||||
session_id="test",
|
||||
ollama_num_ctx=None,
|
||||
)
|
||||
# NVIDIA profile sets default_max_tokens=16384
|
||||
assert kwargs.get("max_tokens") == 16384
|
||||
|
||||
def test_nvidia_nim_alias(self, transport):
|
||||
profile = get_provider_profile("nvidia-nim")
|
||||
assert profile is not None
|
||||
assert profile.name == "nvidia"
|
||||
assert profile.default_max_tokens == 16384
|
||||
|
||||
def test_nvidia_model_passed(self, transport):
|
||||
profile = get_provider_profile("nvidia")
|
||||
|
||||
@@ -58,42 +58,8 @@ class TestFetchModelsBaseUrlOverride:
|
||||
finally:
|
||||
server.shutdown()
|
||||
|
||||
def test_fallback_to_self_base_url(self):
|
||||
"""When base_url is None, falls back to self.base_url."""
|
||||
server, port = _start_server([{"id": "default-model"}])
|
||||
try:
|
||||
profile = ProviderProfile(
|
||||
name="test",
|
||||
base_url=f"http://127.0.0.1:{port}",
|
||||
)
|
||||
result = profile.fetch_models(api_key="test-key")
|
||||
assert result == ["default-model"]
|
||||
finally:
|
||||
server.shutdown()
|
||||
|
||||
def test_no_base_url_returns_none(self):
|
||||
"""When both base_url and self.base_url are empty, returns None."""
|
||||
profile = ProviderProfile(name="test", base_url="")
|
||||
result = profile.fetch_models(api_key="test-key", base_url="")
|
||||
assert result is None
|
||||
|
||||
def test_base_url_override_with_models_url_set(self):
|
||||
"""When self.models_url is set, base_url override is ignored (models_url wins)."""
|
||||
server, port = _start_server([{"id": "from-models-url"}])
|
||||
try:
|
||||
profile = ProviderProfile(
|
||||
name="test",
|
||||
base_url="http://127.0.0.1:1",
|
||||
models_url=f"http://127.0.0.1:{port}/models",
|
||||
)
|
||||
# base_url override should NOT be used because models_url takes priority
|
||||
result = profile.fetch_models(
|
||||
api_key="test-key",
|
||||
base_url="http://127.0.0.1:1",
|
||||
)
|
||||
assert result == ["from-models-url"]
|
||||
finally:
|
||||
server.shutdown()
|
||||
|
||||
|
||||
class TestCustomProviderBaseUrlPassthrough:
|
||||
@@ -174,14 +140,6 @@ class TestFetchModelsRedirectCredentialStripping:
|
||||
assert "authorization" not in headers
|
||||
assert "x-api-key" not in headers
|
||||
|
||||
def test_same_host_different_port_redirect_strips_credentials(self):
|
||||
"""A different port is a different origin — it can be a different service."""
|
||||
result, headers = self._run(
|
||||
lambda _, second_port: f"http://127.0.0.1:{second_port}/redirected"
|
||||
)
|
||||
assert result == ["redirected-model"]
|
||||
assert "authorization" not in headers
|
||||
assert "x-api-key" not in headers
|
||||
|
||||
def test_same_origin_redirect_keeps_credentials(self):
|
||||
result, headers = self._run(
|
||||
|
||||
@@ -90,21 +90,6 @@ class TestKimiProfileParity:
|
||||
assert "reasoning_effort" not in profile
|
||||
assert "reasoning_effort" not in legacy
|
||||
|
||||
def test_reasoning_effort_default(self, transport):
|
||||
# xor contract: enabled w/o effort → thinking-enabled only, no effort.
|
||||
rc = {"enabled": True}
|
||||
legacy = transport.build_kwargs(
|
||||
model="kimi-k2", messages=_msgs(), tools=None,
|
||||
provider_profile=get_provider_profile("kimi-coding"), reasoning_config=rc,
|
||||
)
|
||||
profile = transport.build_kwargs(
|
||||
model="kimi-k2", messages=_msgs(), tools=None,
|
||||
provider_profile=get_provider_profile("kimi"),
|
||||
reasoning_config=rc,
|
||||
)
|
||||
assert profile["extra_body"]["thinking"] == legacy["extra_body"]["thinking"] == {"type": "enabled"}
|
||||
assert "reasoning_effort" not in profile
|
||||
assert "reasoning_effort" not in legacy
|
||||
|
||||
|
||||
class TestOpenRouterProfileParity:
|
||||
@@ -134,17 +119,6 @@ class TestOpenRouterProfileParity:
|
||||
)
|
||||
assert profile["extra_body"]["reasoning"] == legacy["extra_body"]["reasoning"]
|
||||
|
||||
def test_default_reasoning(self, transport):
|
||||
legacy = transport.build_kwargs(
|
||||
model="deepseek/deepseek-chat", messages=_msgs(), tools=None,
|
||||
provider_profile=get_provider_profile("openrouter"), supports_reasoning=True,
|
||||
)
|
||||
profile = transport.build_kwargs(
|
||||
model="deepseek/deepseek-chat", messages=_msgs(), tools=None,
|
||||
provider_profile=get_provider_profile("openrouter"),
|
||||
supports_reasoning=True,
|
||||
)
|
||||
assert profile["extra_body"]["reasoning"] == legacy["extra_body"]["reasoning"]
|
||||
|
||||
|
||||
class TestNousProfileParity:
|
||||
@@ -210,24 +184,6 @@ class TestQwenProfileParity:
|
||||
assert profile["metadata"] == legacy["metadata"] == meta
|
||||
assert "metadata" not in profile.get("extra_body", {})
|
||||
|
||||
def test_message_preprocessing(self, transport):
|
||||
"""Qwen profile normalizes string content to list-of-parts."""
|
||||
msgs = [
|
||||
{"role": "system", "content": "You are helpful."},
|
||||
{"role": "user", "content": "hello"},
|
||||
]
|
||||
profile = transport.build_kwargs(
|
||||
model="qwen3.5", messages=msgs, tools=None,
|
||||
provider_profile=get_provider_profile("qwen"),
|
||||
)
|
||||
out_msgs = profile["messages"]
|
||||
# System message content normalized + cache_control injected
|
||||
assert isinstance(out_msgs[0]["content"], list)
|
||||
assert out_msgs[0]["content"][0]["type"] == "text"
|
||||
assert "cache_control" in out_msgs[0]["content"][-1]
|
||||
# User message content normalized
|
||||
assert isinstance(out_msgs[1]["content"], list)
|
||||
assert out_msgs[1]["content"][0] == {"type": "text", "text": "hello"}
|
||||
|
||||
|
||||
class TestDeveloperRoleParity:
|
||||
@@ -276,16 +232,6 @@ class TestRequestOverridesParity:
|
||||
)
|
||||
assert kw["extra_body"]["custom_key"] == "custom_val"
|
||||
|
||||
def test_extra_body_override_merges_with_provider_body(self, transport):
|
||||
"""Override extra_body merges WITH provider extra_body, not replaces."""
|
||||
from agent.portal_tags import nous_portal_tags
|
||||
kw = transport.build_kwargs(
|
||||
model="hermes-3", messages=_msgs(), tools=None,
|
||||
provider_profile=get_provider_profile("nous"),
|
||||
request_overrides={"extra_body": {"custom": True}},
|
||||
)
|
||||
assert kw["extra_body"]["tags"] == nous_portal_tags() # from profile
|
||||
assert kw["extra_body"]["custom"] is True # from override
|
||||
|
||||
def test_top_level_override(self, transport):
|
||||
kw = transport.build_kwargs(
|
||||
|
||||
@@ -22,10 +22,6 @@ class TestRegistry:
|
||||
def test_unknown_provider_returns_none(self):
|
||||
assert get_provider_profile("nonexistent-provider") is None
|
||||
|
||||
def test_all_providers_have_name(self):
|
||||
get_provider_profile("nvidia") # trigger discovery
|
||||
for name, profile in _REGISTRY.items():
|
||||
assert profile.name == name
|
||||
|
||||
|
||||
class TestNvidiaProfile:
|
||||
@@ -33,17 +29,11 @@ class TestNvidiaProfile:
|
||||
p = get_provider_profile("nvidia")
|
||||
assert p.default_max_tokens == 16384
|
||||
|
||||
def test_no_special_temperature(self):
|
||||
p = get_provider_profile("nvidia")
|
||||
assert p.fixed_temperature is None
|
||||
|
||||
def test_base_url(self):
|
||||
p = get_provider_profile("nvidia")
|
||||
assert "nvidia.com" in p.base_url
|
||||
|
||||
def test_billing_header_not_profile_wide(self):
|
||||
p = get_provider_profile("nvidia")
|
||||
assert p.default_headers == {}
|
||||
|
||||
|
||||
class TestKimiProfile:
|
||||
@@ -55,17 +45,7 @@ class TestKimiProfile:
|
||||
p = get_provider_profile("kimi")
|
||||
assert p.default_max_tokens == 32000
|
||||
|
||||
def test_cn_separate_profile(self):
|
||||
p = get_provider_profile("kimi-coding-cn")
|
||||
assert p.name == "kimi-coding-cn"
|
||||
assert p.env_vars == ("KIMI_CN_API_KEY",)
|
||||
assert "moonshot.cn" in p.base_url
|
||||
|
||||
def test_cn_not_alias_of_kimi(self):
|
||||
kimi = get_provider_profile("kimi-coding")
|
||||
cn = get_provider_profile("kimi-coding-cn")
|
||||
assert kimi is not cn
|
||||
assert kimi.base_url != cn.base_url
|
||||
|
||||
def test_thinking_enabled(self):
|
||||
# xor contract (fix ce4e74b3): an explicit recognized effort sends
|
||||
@@ -75,11 +55,6 @@ class TestKimiProfile:
|
||||
assert tl["reasoning_effort"] == "high"
|
||||
assert "thinking" not in eb
|
||||
|
||||
def test_thinking_disabled(self):
|
||||
p = get_provider_profile("kimi")
|
||||
eb, tl = p.build_api_kwargs_extras(reasoning_config={"enabled": False})
|
||||
assert eb["thinking"] == {"type": "disabled"}
|
||||
assert "reasoning_effort" not in tl
|
||||
|
||||
def test_reasoning_effort_default(self):
|
||||
# enabled with no effort → thinking toggle only, no top-level effort.
|
||||
@@ -88,12 +63,6 @@ class TestKimiProfile:
|
||||
assert eb["thinking"] == {"type": "enabled"}
|
||||
assert "reasoning_effort" not in tl
|
||||
|
||||
def test_no_config_defaults(self):
|
||||
# No reasoning_config → thinking on, server picks depth; no effort.
|
||||
p = get_provider_profile("kimi")
|
||||
eb, tl = p.build_api_kwargs_extras(reasoning_config=None)
|
||||
assert eb["thinking"] == {"type": "enabled"}
|
||||
assert "reasoning_effort" not in tl
|
||||
|
||||
|
||||
class TestOpenRouterProfile:
|
||||
@@ -107,57 +76,8 @@ class TestOpenRouterProfile:
|
||||
body = p.build_extra_body(session_id="test-session-123")
|
||||
assert body["session_id"] == "test-session-123"
|
||||
|
||||
def test_extra_body_no_prefs(self):
|
||||
p = get_provider_profile("openrouter")
|
||||
body = p.build_extra_body()
|
||||
assert body == {}
|
||||
|
||||
def test_aux_call_inherits_ambient_conversation_as_sticky_key(self):
|
||||
"""Auxiliary calls pass no session_id but must still route stickily.
|
||||
|
||||
Compression, titles, vision, web_extract, session_search and MoA slots
|
||||
funnel through ``agent.auxiliary_client``, which has no session handle.
|
||||
Before the ambient resolution they sent NO sticky key at all and each
|
||||
routed independently of its conversation (#70820).
|
||||
"""
|
||||
from agent.portal_tags import (
|
||||
reset_conversation_context,
|
||||
set_conversation_context,
|
||||
)
|
||||
|
||||
p = get_provider_profile("openrouter")
|
||||
token = set_conversation_context("root-conversation")
|
||||
try:
|
||||
assert p.build_extra_body()["session_id"] == "root-conversation"
|
||||
# An explicitly-passed segment id never beats the lineage root.
|
||||
body = p.build_extra_body(session_id="segment-after-rotation")
|
||||
assert body["session_id"] == "root-conversation"
|
||||
finally:
|
||||
reset_conversation_context(token)
|
||||
|
||||
def test_grok_cache_header_inherits_ambient_conversation(self):
|
||||
"""The xAI cache-affinity header resolves the same way as the body key."""
|
||||
from agent.portal_tags import (
|
||||
reset_conversation_context,
|
||||
set_conversation_context,
|
||||
)
|
||||
|
||||
p = get_provider_profile("openrouter")
|
||||
token = set_conversation_context("root-conversation")
|
||||
try:
|
||||
_, top_level = p.build_api_kwargs_extras(
|
||||
supports_reasoning=False, model="x-ai/grok-4"
|
||||
)
|
||||
headers = top_level.get("extra_headers", {})
|
||||
assert headers["x-grok-conv-id"] == "root-conversation"
|
||||
|
||||
# Still model-gated: non-Grok models get no affinity header.
|
||||
_, other = p.build_api_kwargs_extras(
|
||||
supports_reasoning=False, model="anthropic/claude-sonnet-4.6"
|
||||
)
|
||||
assert "x-grok-conv-id" not in other.get("extra_headers", {})
|
||||
finally:
|
||||
reset_conversation_context(token)
|
||||
|
||||
def test_pareto_min_coding_score_emitted_for_pareto_model(self):
|
||||
"""min_coding_score → plugins block when model is openrouter/pareto-code."""
|
||||
@@ -170,51 +90,10 @@ class TestOpenRouterProfile:
|
||||
{"id": "pareto-router", "min_coding_score": 0.65}
|
||||
]
|
||||
|
||||
def test_pareto_score_ignored_for_other_models(self):
|
||||
"""Score has no effect on any other model — plugins block must not appear."""
|
||||
p = get_provider_profile("openrouter")
|
||||
body = p.build_extra_body(
|
||||
model="anthropic/claude-sonnet-4.6",
|
||||
openrouter_min_coding_score=0.65,
|
||||
)
|
||||
assert "plugins" not in body
|
||||
|
||||
def test_pareto_score_unset_omits_plugins(self):
|
||||
"""Empty/None score → no plugins block (router uses its omission default)."""
|
||||
p = get_provider_profile("openrouter")
|
||||
for unset in (None, ""):
|
||||
body = p.build_extra_body(
|
||||
model="openrouter/pareto-code",
|
||||
openrouter_min_coding_score=unset,
|
||||
)
|
||||
assert "plugins" not in body, f"unset={unset!r}"
|
||||
|
||||
def test_pareto_score_out_of_range_dropped(self):
|
||||
"""Invalid scores are silently dropped — never forwarded to OR."""
|
||||
p = get_provider_profile("openrouter")
|
||||
for bad in (1.5, -0.1, "not-a-number"):
|
||||
body = p.build_extra_body(
|
||||
model="openrouter/pareto-code",
|
||||
openrouter_min_coding_score=bad,
|
||||
)
|
||||
assert "plugins" not in body, f"bad={bad!r}"
|
||||
|
||||
def test_reasoning_full_config(self):
|
||||
p = get_provider_profile("openrouter")
|
||||
eb, _ = p.build_api_kwargs_extras(
|
||||
reasoning_config={"enabled": True, "effort": "high"},
|
||||
supports_reasoning=True,
|
||||
)
|
||||
assert eb["reasoning"] == {"enabled": True, "effort": "high"}
|
||||
|
||||
def test_reasoning_disabled_still_passes(self):
|
||||
"""OpenRouter passes disabled reasoning through (unlike Nous)."""
|
||||
p = get_provider_profile("openrouter")
|
||||
eb, _ = p.build_api_kwargs_extras(
|
||||
reasoning_config={"enabled": False},
|
||||
supports_reasoning=True,
|
||||
)
|
||||
assert eb["reasoning"] == {"enabled": False}
|
||||
|
||||
def test_reasoning_disable_omitted_for_mandatory_anthropic(self):
|
||||
"""Reasoning-mandatory Anthropic models (4.6+/fable) reject any disable
|
||||
@@ -237,60 +116,9 @@ class TestOpenRouterProfile:
|
||||
)
|
||||
assert "reasoning" not in eb, (model, cfg, eb)
|
||||
|
||||
def test_reasoning_disable_kept_for_legacy_anthropic(self):
|
||||
"""Older Anthropic models still accept an explicit disable form, so the
|
||||
profile must keep forwarding it."""
|
||||
p = get_provider_profile("openrouter")
|
||||
for model in (
|
||||
"anthropic/claude-3.7-sonnet",
|
||||
"anthropic/claude-opus-4.5",
|
||||
"anthropic/claude-sonnet-4.5",
|
||||
):
|
||||
eb, _ = p.build_api_kwargs_extras(
|
||||
reasoning_config={"enabled": False},
|
||||
supports_reasoning=True,
|
||||
model=model,
|
||||
)
|
||||
assert eb["reasoning"] == {"enabled": False}, (model, eb)
|
||||
|
||||
def test_reasoning_disable_kept_for_non_anthropic(self):
|
||||
"""Non-Anthropic models (DeepSeek, Qwen, …) disable reasoning fine; the
|
||||
Anthropic-mandatory guard must not touch them."""
|
||||
p = get_provider_profile("openrouter")
|
||||
for model in ("deepseek/deepseek-chat", "qwen/qwen3-max", "openai/gpt-5.4"):
|
||||
eb, _ = p.build_api_kwargs_extras(
|
||||
reasoning_config={"enabled": False},
|
||||
supports_reasoning=True,
|
||||
model=model,
|
||||
)
|
||||
assert eb["reasoning"] == {"enabled": False}, (model, eb)
|
||||
|
||||
def test_reasoning_omitted_for_mandatory_anthropic_even_when_enabled(self):
|
||||
"""Reasoning-mandatory Anthropic models (4.6+/fable) use adaptive
|
||||
thinking — OpenRouter ignores reasoning.effort for them, and sending any
|
||||
reasoning field makes OpenRouter emit thinking.type.disabled on
|
||||
tool-continuation turns (whose assistant tool_calls carry no thinking
|
||||
block), 400ing every turn after the first tool call. The profile must
|
||||
omit reasoning entirely so the model defaults to adaptive.
|
||||
"""
|
||||
p = get_provider_profile("openrouter")
|
||||
for cfg in (
|
||||
{"enabled": True, "effort": "medium"},
|
||||
{"enabled": True, "effort": "xhigh"},
|
||||
{"effort": "high"},
|
||||
{"enabled": True},
|
||||
):
|
||||
eb, _ = p.build_api_kwargs_extras(
|
||||
reasoning_config=cfg,
|
||||
supports_reasoning=True,
|
||||
model="anthropic/claude-fable-5",
|
||||
)
|
||||
assert "reasoning" not in eb, (cfg, eb)
|
||||
|
||||
def test_default_reasoning(self):
|
||||
p = get_provider_profile("openrouter")
|
||||
eb, _ = p.build_api_kwargs_extras(supports_reasoning=True)
|
||||
assert eb["reasoning"] == {"enabled": True, "effort": "medium"}
|
||||
|
||||
def test_grok_session_id_sets_cache_affinity_header(self):
|
||||
"""OpenRouter + Grok model + session_id => x-grok-conv-id header."""
|
||||
@@ -301,42 +129,9 @@ class TestOpenRouterProfile:
|
||||
)
|
||||
assert tl["extra_headers"]["x-grok-conv-id"] == "sess-abc123"
|
||||
|
||||
def test_grok_xai_prefix_also_supported(self):
|
||||
"""xai/ prefix (without dash) should also get the header."""
|
||||
p = get_provider_profile("openrouter")
|
||||
_, tl = p.build_api_kwargs_extras(
|
||||
model="xai/grok-3",
|
||||
session_id="sess-xyz",
|
||||
)
|
||||
assert tl["extra_headers"]["x-grok-conv-id"] == "sess-xyz"
|
||||
|
||||
def test_non_grok_model_no_affinity_header(self):
|
||||
"""OpenRouter + non-Grok model => no x-grok-conv-id header."""
|
||||
p = get_provider_profile("openrouter")
|
||||
_, tl = p.build_api_kwargs_extras(
|
||||
model="anthropic/claude-sonnet-4.6",
|
||||
session_id="sess-abc123",
|
||||
)
|
||||
assert "extra_headers" not in tl
|
||||
assert "x-grok-conv-id" not in tl
|
||||
|
||||
def test_grok_without_session_id_no_header(self):
|
||||
"""Grok model but no session_id => no header (nothing to pin)."""
|
||||
p = get_provider_profile("openrouter")
|
||||
_, tl = p.build_api_kwargs_extras(model="x-ai/grok-4")
|
||||
assert "extra_headers" not in tl
|
||||
|
||||
def test_grok_reasoning_and_header_together(self):
|
||||
"""Reasoning extra_body and Grok header should coexist."""
|
||||
p = get_provider_profile("openrouter")
|
||||
eb, tl = p.build_api_kwargs_extras(
|
||||
model="x-ai/grok-4",
|
||||
session_id="sess-123",
|
||||
supports_reasoning=True,
|
||||
reasoning_config={"enabled": True, "effort": "high"},
|
||||
)
|
||||
assert eb["reasoning"] == {"enabled": True, "effort": "high"}
|
||||
assert tl["extra_headers"]["x-grok-conv-id"] == "sess-123"
|
||||
|
||||
# --- reasoning-mandatory Anthropic effort → top-level verbosity (#43432) ---
|
||||
#
|
||||
@@ -355,88 +150,10 @@ class TestOpenRouterProfile:
|
||||
mod = inspect.getmodule(type(p))
|
||||
return mod._anthropic_reasoning_is_mandatory(model)
|
||||
|
||||
def test_mandatory_anthropic_effort_routes_to_verbosity(self):
|
||||
"""effort set + reasoning enabled → top-level verbosity == effort,
|
||||
and NO reasoning field in extra_body.
|
||||
|
||||
Covers the full real config range produced by
|
||||
``hermes_constants.parse_reasoning_effort`` —
|
||||
``VALID_REASONING_EFFORTS`` (including max and ultra).
|
||||
"""
|
||||
p = get_provider_profile("openrouter")
|
||||
model = "anthropic/claude-fable-5"
|
||||
assert self._is_mandatory(model) # fixture really is mandatory
|
||||
for effort in ("minimal", "low", "medium", "high", "xhigh", "max", "ultra"):
|
||||
eb, tl = p.build_api_kwargs_extras(
|
||||
reasoning_config={"enabled": True, "effort": effort},
|
||||
supports_reasoning=True,
|
||||
model=model,
|
||||
)
|
||||
assert tl["verbosity"] == effort, (effort, tl)
|
||||
assert "reasoning" not in eb, (effort, eb)
|
||||
|
||||
def test_mandatory_anthropic_effort_without_enabled_key_routes(self):
|
||||
"""effort present without an explicit ``enabled`` key still routes to
|
||||
verbosity (enabled defaults to True)."""
|
||||
p = get_provider_profile("openrouter")
|
||||
eb, tl = p.build_api_kwargs_extras(
|
||||
reasoning_config={"effort": "xhigh"},
|
||||
supports_reasoning=True,
|
||||
model="anthropic/claude-fable-5",
|
||||
)
|
||||
assert tl["verbosity"] == "xhigh"
|
||||
assert "reasoning" not in eb
|
||||
|
||||
def test_mandatory_anthropic_verbosity_is_value_agnostic_passthrough(self):
|
||||
"""The mapping passes the effort value through verbatim — it must NOT
|
||||
clamp or whitelist. Extended values must survive
|
||||
rather than be silently dropped. The OpenAI SDK type only literals
|
||||
``low|medium|high`` but it's a TypedDict (no runtime validation), so the
|
||||
extended scale reaches the wire untouched."""
|
||||
p = get_provider_profile("openrouter")
|
||||
for effort in ("xhigh", "max", "ultra"):
|
||||
_, tl = p.build_api_kwargs_extras(
|
||||
reasoning_config={"enabled": True, "effort": effort},
|
||||
supports_reasoning=True,
|
||||
model="anthropic/claude-fable-5",
|
||||
)
|
||||
assert tl["verbosity"] == effort
|
||||
|
||||
def test_mandatory_anthropic_no_verbosity_when_effort_absent(self):
|
||||
"""No effort / none / disabled → no verbosity emitted, so the model
|
||||
keeps its own adaptive default. Still no reasoning field."""
|
||||
p = get_provider_profile("openrouter")
|
||||
model = "anthropic/claude-fable-5"
|
||||
for cfg in (
|
||||
None,
|
||||
{},
|
||||
{"enabled": True},
|
||||
{"effort": "none"},
|
||||
{"enabled": True, "effort": "none"},
|
||||
{"enabled": False, "effort": "high"}, # explicitly disabled wins
|
||||
):
|
||||
eb, tl = p.build_api_kwargs_extras(
|
||||
reasoning_config=cfg,
|
||||
supports_reasoning=True,
|
||||
model=model,
|
||||
)
|
||||
assert "verbosity" not in tl, (cfg, tl)
|
||||
assert "reasoning" not in eb, (cfg, eb)
|
||||
|
||||
def test_non_mandatory_reasoning_model_unchanged_no_verbosity(self):
|
||||
"""Non-mandatory reasoning models (DeepSeek, Qwen, GPT) keep getting
|
||||
``reasoning`` in extra_body and never get a ``verbosity`` field — the
|
||||
new path must not touch them."""
|
||||
p = get_provider_profile("openrouter")
|
||||
for model in ("deepseek/deepseek-chat", "qwen/qwen3-max", "openai/gpt-5.4"):
|
||||
assert not self._is_mandatory(model) # fixture really is non-mandatory
|
||||
eb, tl = p.build_api_kwargs_extras(
|
||||
reasoning_config={"enabled": True, "effort": "high"},
|
||||
supports_reasoning=True,
|
||||
model=model,
|
||||
)
|
||||
assert eb["reasoning"] == {"enabled": True, "effort": "high"}, (model, eb)
|
||||
assert "verbosity" not in tl, (model, tl)
|
||||
|
||||
def test_mandatory_anthropic_verbosity_coexists_with_grok_header(self):
|
||||
"""A reasoning-mandatory Anthropic model is never a Grok model, but the
|
||||
@@ -459,18 +176,6 @@ class TestNousProfile:
|
||||
body = p.build_extra_body()
|
||||
assert body["tags"] == nous_portal_tags()
|
||||
|
||||
def test_extra_body_with_provider_preferences(self):
|
||||
from agent.portal_tags import nous_portal_tags
|
||||
|
||||
p = get_provider_profile("nous")
|
||||
assert p is not None
|
||||
preferences = {"only": ["deepseek"], "ignore": ["deepinfra"]}
|
||||
body = p.build_extra_body(provider_preferences=preferences)
|
||||
|
||||
assert body == {
|
||||
"tags": nous_portal_tags(),
|
||||
"provider": preferences,
|
||||
}
|
||||
|
||||
def test_tags_include_conversation_when_session_id(self):
|
||||
from agent.portal_tags import conversation_tag
|
||||
@@ -478,17 +183,7 @@ class TestNousProfile:
|
||||
body = p.build_extra_body(session_id="sess-99")
|
||||
assert conversation_tag("sess-99") in body["tags"]
|
||||
|
||||
def test_extra_body_session_id(self):
|
||||
"""Top-level session_id is the provider sticky-routing key — keeps
|
||||
Anthropic cache_control breakpoints pinned to one upstream endpoint."""
|
||||
p = get_provider_profile("nous")
|
||||
body = p.build_extra_body(session_id="sess-99")
|
||||
assert body["session_id"] == "sess-99"
|
||||
|
||||
def test_extra_body_no_session_id(self):
|
||||
p = get_provider_profile("nous")
|
||||
body = p.build_extra_body()
|
||||
assert "session_id" not in body
|
||||
|
||||
def test_auth_type(self):
|
||||
p = get_provider_profile("nous")
|
||||
@@ -502,13 +197,6 @@ class TestNousProfile:
|
||||
)
|
||||
assert eb["reasoning"] == {"enabled": True, "effort": "medium"}
|
||||
|
||||
def test_reasoning_omitted_when_disabled(self):
|
||||
p = get_provider_profile("nous")
|
||||
eb, _ = p.build_api_kwargs_extras(
|
||||
reasoning_config={"enabled": False},
|
||||
supports_reasoning=True,
|
||||
)
|
||||
assert "reasoning" not in eb
|
||||
|
||||
|
||||
class TestQwenProfile:
|
||||
@@ -516,64 +204,14 @@ class TestQwenProfile:
|
||||
p = get_provider_profile("qwen-oauth")
|
||||
assert p.default_max_tokens == 65536
|
||||
|
||||
def test_auth_type(self):
|
||||
p = get_provider_profile("qwen-oauth")
|
||||
assert p.auth_type == "oauth_external"
|
||||
|
||||
def test_extra_body_vl(self):
|
||||
p = get_provider_profile("qwen-oauth")
|
||||
body = p.build_extra_body()
|
||||
assert body["vl_high_resolution_images"] is True
|
||||
|
||||
def test_prepare_messages_normalizes_content(self):
|
||||
p = get_provider_profile("qwen-oauth")
|
||||
msgs = [
|
||||
{"role": "system", "content": "Be helpful"},
|
||||
{"role": "user", "content": "hello"},
|
||||
]
|
||||
result = p.prepare_messages(msgs)
|
||||
# System message: content normalized to list, cache_control on last part
|
||||
assert isinstance(result[0]["content"], list)
|
||||
assert result[0]["content"][-1].get("cache_control") == {"type": "ephemeral"}
|
||||
assert result[0]["content"][-1]["text"] == "Be helpful"
|
||||
# User message: content normalized to list
|
||||
assert isinstance(result[1]["content"], list)
|
||||
assert result[1]["content"][0]["text"] == "hello"
|
||||
|
||||
def test_prepare_messages_copy_on_write(self):
|
||||
p = get_provider_profile("qwen-oauth")
|
||||
system_part = {"type": "text", "text": "Be helpful"}
|
||||
msgs = [
|
||||
{"role": "system", "content": [system_part]},
|
||||
{"role": "assistant", "content": [{"type": "text", "text": "unchanged"}]},
|
||||
{"role": "user", "content": ["hello"]},
|
||||
]
|
||||
|
||||
result = p.prepare_messages(msgs)
|
||||
|
||||
assert result is not msgs
|
||||
assert result[0] is not msgs[0]
|
||||
assert result[0]["content"] is not msgs[0]["content"]
|
||||
assert result[0]["content"][0] is not system_part
|
||||
assert result[0]["content"][0]["cache_control"] == {"type": "ephemeral"}
|
||||
assert "cache_control" not in system_part
|
||||
assert result[1] is msgs[1]
|
||||
assert result[2] is not msgs[2]
|
||||
assert result[2]["content"] == [{"type": "text", "text": "hello"}]
|
||||
assert msgs[2]["content"] == ["hello"]
|
||||
|
||||
def test_prepare_messages_does_not_poison_strict_provider_history(self):
|
||||
qwen = get_provider_profile("qwen-oauth")
|
||||
msgs = [
|
||||
{"role": "system", "content": [{"type": "text", "text": "Be helpful"}]},
|
||||
{"role": "user", "content": "hello"},
|
||||
]
|
||||
|
||||
qwen_result = qwen.prepare_messages(msgs)
|
||||
|
||||
assert qwen_result[0]["content"][0]["cache_control"] == {"type": "ephemeral"}
|
||||
assert "cache_control" not in msgs[0]["content"][0]
|
||||
assert msgs[1]["content"] == "hello"
|
||||
|
||||
def test_prepare_messages_protects_nested_image_url_retry_mutation(self):
|
||||
qwen = get_provider_profile("qwen-oauth")
|
||||
@@ -617,12 +255,4 @@ class TestBaseProfile:
|
||||
msgs = [{"role": "user", "content": "hi"}]
|
||||
assert p.prepare_messages(msgs) is msgs
|
||||
|
||||
def test_build_extra_body_empty(self):
|
||||
p = ProviderProfile(name="test")
|
||||
assert p.build_extra_body() == {}
|
||||
|
||||
def test_build_api_kwargs_extras_empty(self):
|
||||
p = ProviderProfile(name="test")
|
||||
eb, tl = p.build_api_kwargs_extras()
|
||||
assert eb == {}
|
||||
assert tl == {}
|
||||
|
||||
@@ -27,19 +27,6 @@ def _max_tokens_fn(n):
|
||||
class TestNvidiaParity:
|
||||
"""NVIDIA NIM: default max_tokens=16384."""
|
||||
|
||||
def test_default_max_tokens(self, transport):
|
||||
"""NVIDIA default max_tokens=16384 comes from profile, not legacy is_nvidia_nim flag."""
|
||||
from providers import get_provider_profile
|
||||
|
||||
profile = get_provider_profile("nvidia")
|
||||
kw = transport.build_kwargs(
|
||||
model="nvidia/llama-3.1-nemotron-70b-instruct",
|
||||
messages=_simple_messages(),
|
||||
tools=None,
|
||||
max_tokens_param_fn=_max_tokens_fn,
|
||||
provider_profile=profile,
|
||||
)
|
||||
assert kw["max_completion_tokens"] == 16384
|
||||
|
||||
def test_user_max_tokens_overrides(self, transport):
|
||||
from providers import get_provider_profile
|
||||
@@ -69,15 +56,6 @@ class TestKimiParity:
|
||||
)
|
||||
assert "temperature" not in kw
|
||||
|
||||
def test_default_max_tokens(self, transport):
|
||||
kw = transport.build_kwargs(
|
||||
model="kimi-k2",
|
||||
messages=_simple_messages(),
|
||||
tools=None,
|
||||
provider_profile=get_provider_profile("kimi-coding"),
|
||||
max_tokens_param_fn=_max_tokens_fn,
|
||||
)
|
||||
assert kw["max_completion_tokens"] == 32000
|
||||
|
||||
def test_thinking_enabled(self, transport):
|
||||
# xor contract (fix ce4e74b3): an explicit recognized effort sends
|
||||
@@ -92,28 +70,7 @@ class TestKimiParity:
|
||||
assert kw.get("reasoning_effort") == "high"
|
||||
assert "thinking" not in kw.get("extra_body", {})
|
||||
|
||||
def test_thinking_enabled_without_effort(self, transport):
|
||||
# enabled but no effort → fall back to the thinking toggle, no effort.
|
||||
kw = transport.build_kwargs(
|
||||
model="kimi-k2",
|
||||
messages=_simple_messages(),
|
||||
tools=None,
|
||||
provider_profile=get_provider_profile("kimi-coding"),
|
||||
reasoning_config={"enabled": True},
|
||||
)
|
||||
assert kw["extra_body"]["thinking"] == {"type": "enabled"}
|
||||
assert "reasoning_effort" not in kw
|
||||
|
||||
def test_thinking_disabled(self, transport):
|
||||
kw = transport.build_kwargs(
|
||||
model="kimi-k2",
|
||||
messages=_simple_messages(),
|
||||
tools=None,
|
||||
provider_profile=get_provider_profile("kimi-coding"),
|
||||
reasoning_config={"enabled": False},
|
||||
)
|
||||
assert kw["extra_body"]["thinking"] == {"type": "disabled"}
|
||||
assert "reasoning_effort" not in kw
|
||||
|
||||
def test_reasoning_effort_top_level(self, transport):
|
||||
"""Kimi reasoning_effort is a TOP-LEVEL api_kwargs key, NOT in extra_body."""
|
||||
@@ -127,19 +84,6 @@ class TestKimiParity:
|
||||
assert kw.get("reasoning_effort") == "high"
|
||||
assert "reasoning_effort" not in kw.get("extra_body", {})
|
||||
|
||||
def test_reasoning_effort_default_no_effort(self, transport):
|
||||
# xor contract: enabled with no effort falls back to thinking-enabled
|
||||
# and emits NO top-level reasoning_effort (previously defaulted to
|
||||
# "medium" alongside thinking — the pairing this fix removes).
|
||||
kw = transport.build_kwargs(
|
||||
model="kimi-k2",
|
||||
messages=_simple_messages(),
|
||||
tools=None,
|
||||
provider_profile=get_provider_profile("kimi-coding"),
|
||||
reasoning_config={"enabled": True},
|
||||
)
|
||||
assert "reasoning_effort" not in kw
|
||||
assert kw["extra_body"]["thinking"] == {"type": "enabled"}
|
||||
|
||||
|
||||
class TestOpenRouterParity:
|
||||
@@ -183,16 +127,6 @@ class TestOpenRouterParity:
|
||||
)
|
||||
assert "reasoning" not in kw.get("extra_body", {})
|
||||
|
||||
def test_default_reasoning_when_no_config(self, transport):
|
||||
"""When supports_reasoning=True but no config, adds default."""
|
||||
kw = transport.build_kwargs(
|
||||
model="deepseek/deepseek-chat",
|
||||
messages=_simple_messages(),
|
||||
tools=None,
|
||||
provider_profile=get_provider_profile("openrouter"),
|
||||
supports_reasoning=True,
|
||||
)
|
||||
assert kw["extra_body"]["reasoning"] == {"enabled": True, "effort": "medium"}
|
||||
|
||||
|
||||
class TestNousParity:
|
||||
@@ -223,17 +157,6 @@ class TestNousParity:
|
||||
)
|
||||
assert kw["extra_body"]["provider"] == preferences
|
||||
|
||||
def test_reasoning_omitted_when_disabled(self, transport):
|
||||
"""Nous special case: reasoning omitted entirely when disabled."""
|
||||
kw = transport.build_kwargs(
|
||||
model="hermes-3-llama-3.1-405b",
|
||||
messages=_simple_messages(),
|
||||
tools=None,
|
||||
provider_profile=get_provider_profile("nous"),
|
||||
supports_reasoning=True,
|
||||
reasoning_config={"enabled": False},
|
||||
)
|
||||
assert "reasoning" not in kw.get("extra_body", {})
|
||||
|
||||
def test_reasoning_enabled(self, transport):
|
||||
rc = {"enabled": True, "effort": "high"}
|
||||
@@ -251,15 +174,6 @@ class TestNousParity:
|
||||
class TestQwenParity:
|
||||
"""Qwen: max_tokens=65536, vl_high_resolution, metadata top-level."""
|
||||
|
||||
def test_default_max_tokens(self, transport):
|
||||
kw = transport.build_kwargs(
|
||||
model="qwen3.5-plus",
|
||||
messages=_simple_messages(),
|
||||
tools=None,
|
||||
provider_profile=get_provider_profile("qwen-oauth"),
|
||||
max_tokens_param_fn=_max_tokens_fn,
|
||||
)
|
||||
assert kw["max_completion_tokens"] == 65536
|
||||
|
||||
def test_vl_high_resolution(self, transport):
|
||||
kw = transport.build_kwargs(
|
||||
|
||||
Reference in New Issue
Block a user