Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license

This commit is contained in:
2026-09-05 13:26:46 +03:00
commit 03634b1ca3
11340 changed files with 3442369 additions and 0 deletions
View File
+107
View File
@@ -0,0 +1,107 @@
"""E2E tests: verify _build_kwargs_from_profile produces correct output.
These tests call _build_kwargs_from_profile on the transport directly,
without importing run_agent (which would cause xdist worker contamination).
"""
import pytest
from agent.transports.chat_completions import ChatCompletionsTransport
from providers import get_provider_profile
@pytest.fixture
def transport():
return ChatCompletionsTransport()
def _msgs():
return [{"role": "user", "content": "hi"}]
class TestNvidiaProfileWiring:
def test_nvidia_model_passed(self, transport):
profile = get_provider_profile("nvidia")
kwargs = transport.build_kwargs(
model="nvidia/test-model",
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,
)
assert kwargs["model"] == "nvidia/test-model"
def test_nvidia_tool_messages_drop_name_fields(self, transport):
profile = get_provider_profile("nvidia")
msgs = [
{"role": "user", "content": "run a command"},
{
"role": "assistant",
"content": None,
"tool_calls": [
{
"id": "call_1",
"type": "function",
"function": {"name": "terminal", "arguments": "{}"},
}
],
},
{
"role": "tool",
"name": "terminal",
"tool_name": "terminal",
"tool_call_id": "call_1",
"content": "ok",
},
]
kwargs = transport.build_kwargs(
model="mistralai/mistral-large-3-675b-instruct-2512",
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,
)
assert kwargs["messages"][2] == {
"role": "tool",
"tool_call_id": "call_1",
"content": "ok",
}
assert msgs[2]["name"] == "terminal"
assert msgs[2]["tool_name"] == "terminal"
class TestDeepSeekProfileWiring:
def test_deepseek_no_forced_max_tokens(self, transport):
profile = get_provider_profile("deepseek")
kwargs = transport.build_kwargs(
model="deepseek-chat",
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,
)
# DeepSeek has no default_max_tokens
assert kwargs["model"] == "deepseek-chat"
assert kwargs.get("max_tokens") is None or "max_tokens" not in kwargs
@@ -0,0 +1,225 @@
"""Tests for pip entry-point provider discovery (hermes_agent.plugins group).
Verifies that ``providers/__init__.py`` imports provider plugins exposed via a
distribution's ``hermes_agent.plugins`` entry point, supporting both a
``module:func`` callable target and a bare self-registering ``module`` target.
"""
from __future__ import annotations
import sys
from pathlib import Path
import pytest
import providers
REPO_ROOT = Path(__file__).resolve().parents[2]
def _clear_provider_caches():
providers._REGISTRY.clear()
providers._ALIASES.clear()
providers._PROVIDER_LIST_CACHE = None
providers._discovered = False
for mod in list(sys.modules.keys()):
if mod.startswith("plugins.model_providers") or mod.startswith(
"_hermes_user_provider"
):
del sys.modules[mod]
@pytest.fixture(autouse=True)
def _restore_real_discovery():
"""Snapshot registry state; on teardown re-run REAL discovery.
These tests monkeypatch ``importlib.metadata.entry_points`` and evict the
``plugins.model_providers`` submodules to force re-discovery. Without an
explicit restore, the emptied registry / ``sys.modules`` would leak into
later tests (e.g. ``from plugins.model_providers.custom import ...``).
This fixture is autouse and declared before ``monkeypatch`` is requested,
so it tears down LAST — after ``entry_points`` is restored to the real
implementation — letting the final ``_discover_providers()`` repopulate
both the registry and ``sys.modules`` from the real filesystem plugins.
"""
yield
_clear_provider_caches()
providers._discover_providers()
class _FakeEP:
def __init__(self, name, loader):
self.name = name
self.group = "hermes_agent.plugins"
self._loader = loader
def load(self):
return self._loader()
def _enable(monkeypatch, *names, disabled=()):
"""Gate helper: mark entry-point names enabled/disabled in config.
``_discover_entry_point_providers`` enforces the PluginManager's
``plugins.enabled`` opt-in allow-list, so tests must enable their fake
entry points explicitly.
"""
import hermes_cli.plugins as hp
monkeypatch.setattr(hp, "_get_enabled_plugins", lambda: set(names))
monkeypatch.setattr(hp, "_get_disabled_plugins", lambda: set(disabled))
class _FakeEntryPoints:
def __init__(self, eps):
self._eps = eps
def select(self, group):
return [e for e in self._eps if e.group == group]
def _register_via_callable():
from providers.base import ProviderProfile
def register():
providers.register_provider(
ProviderProfile(name="ep-callable", aliases=("epc",), base_url="https://a.test/v1")
)
return register # ep.load() returns the callable; discovery invokes it
def _register_via_module():
# ep.load() returns a non-callable object; the import side effect already
# registered the profile (mirrors a bare ``module`` target).
from providers.base import ProviderProfile
providers.register_provider(
ProviderProfile(name="ep-module", base_url="https://b.test/v1")
)
return object() # non-callable → discovery must NOT try to call it
def test_entry_point_callable_and_module_targets(monkeypatch):
fake_eps = _FakeEntryPoints(
[
_FakeEP("ep-callable", _register_via_callable),
_FakeEP("ep-module", _register_via_module),
]
)
import importlib.metadata as md
monkeypatch.setattr(md, "entry_points", lambda: fake_eps)
_enable(monkeypatch, "ep-callable", "ep-module")
_clear_provider_caches()
try:
assert providers.get_provider_profile("ep-callable") is not None
assert providers.get_provider_profile("epc") is not None # alias
assert providers.get_provider_profile("ep-module") is not None
finally:
_clear_provider_caches()
def test_entry_point_not_enabled_is_skipped(monkeypatch):
"""Entry points honor the plugins.enabled opt-in gate — installed ≠ loaded."""
fake_eps = _FakeEntryPoints([_FakeEP("ep-callable", _register_via_callable)])
import importlib.metadata as md
monkeypatch.setattr(md, "entry_points", lambda: fake_eps)
_enable(monkeypatch, "some-other-plugin") # ep-callable NOT enabled
_clear_provider_caches()
try:
assert providers.get_provider_profile("ep-callable") is None
finally:
_clear_provider_caches()
def test_entry_point_disabled_wins_over_enabled(monkeypatch):
"""plugins.disabled is a deny-list that beats plugins.enabled."""
fake_eps = _FakeEntryPoints([_FakeEP("ep-callable", _register_via_callable)])
import importlib.metadata as md
monkeypatch.setattr(md, "entry_points", lambda: fake_eps)
_enable(monkeypatch, "ep-callable", disabled=("ep-callable",))
_clear_provider_caches()
try:
assert providers.get_provider_profile("ep-callable") is None
finally:
_clear_provider_caches()
def test_general_plugin_register_ctx_not_invoked(monkeypatch):
"""A register(ctx)-style general plugin sharing the group is never called."""
calls = []
def _general_plugin_target():
def register(ctx): # requires an argument — PluginManager contract
calls.append(ctx)
return register
fake_eps = _FakeEntryPoints([_FakeEP("general-plugin", _general_plugin_target)])
import importlib.metadata as md
monkeypatch.setattr(md, "entry_points", lambda: fake_eps)
_enable(monkeypatch, "general-plugin")
_clear_provider_caches()
try:
providers._discover_providers()
assert calls == [] # never invoked (would have been a TypeError anyway)
finally:
_clear_provider_caches()
def test_entry_point_failure_is_isolated(monkeypatch):
def _boom():
raise RuntimeError("broken plugin")
fake_eps = _FakeEntryPoints(
[
_FakeEP("broken", _boom),
_FakeEP("ep-callable", _register_via_callable),
]
)
import importlib.metadata as md
monkeypatch.setattr(md, "entry_points", lambda: fake_eps)
_enable(monkeypatch, "broken", "ep-callable")
_clear_provider_caches()
try:
# A broken entry point must not prevent the good one from registering.
assert providers.get_provider_profile("ep-callable") is not None
finally:
_clear_provider_caches()
def test_filesystem_plugins_win_over_entry_points(monkeypatch):
"""Entry points are discovered FIRST (lowest precedence): last-writer-wins
in register_provider() means a bundled/user profile of the same name
overrides a pip impostor."""
from providers.base import ProviderProfile
def _register_ep_openrouter():
def register():
providers.register_provider(
ProviderProfile(name="openrouter", base_url="https://impostor.test/v1")
)
return register
fake_eps = _FakeEntryPoints([_FakeEP("openrouter", _register_ep_openrouter)])
import importlib.metadata as md
monkeypatch.setattr(md, "entry_points", lambda: fake_eps)
_enable(monkeypatch, "openrouter") # enabled, so precedence is what's tested
_clear_provider_caches()
try:
p = providers.get_provider_profile("openrouter")
assert p is not None
# The bundled OpenRouter profile (real base_url) must win, not the impostor.
assert "impostor.test" not in (p.base_url or "")
finally:
_clear_provider_caches()
@@ -0,0 +1,212 @@
"""Tests for ProviderProfile.fetch_models base_url override (issue #47009)."""
import json
from http.server import HTTPServer, BaseHTTPRequestHandler
from threading import Thread
from unittest.mock import patch, MagicMock
from providers.base import ProviderProfile
class _FakeModelHandler(BaseHTTPRequestHandler):
"""Serves /models with a configurable model list."""
models = [{"id": "custom-model-1"}, {"id": "custom-model-2"}]
def do_GET(self):
if self.path.rstrip("/") == "/models":
body = json.dumps({"data": self.models}).encode()
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(body)
else:
self.send_response(404)
self.end_headers()
def log_message(self, format, *args):
pass # suppress noise
def _start_server(models=None):
"""Start a local HTTP server returning given models. Returns (server, port)."""
if models is not None:
_FakeModelHandler.models = models
server = HTTPServer(("127.0.0.1", 0), _FakeModelHandler)
port = server.server_address[1]
thread = Thread(target=server.serve_forever, daemon=True)
thread.start()
return server, port
class TestFetchModelsBaseUrlOverride:
"""fetch_models() should use caller-provided base_url when given."""
def test_base_url_override_used(self):
"""When base_url is passed, it overrides self.base_url."""
server, port = _start_server([{"id": "proxy-model-a"}])
try:
profile = ProviderProfile(
name="test",
base_url="http://127.0.0.1:1", # wrong port — should not be used
)
result = profile.fetch_models(
api_key="test-key",
base_url=f"http://127.0.0.1:{port}",
)
assert result == ["proxy-model-a"]
finally:
server.shutdown()
def test_custom_base_url_beats_models_url(self):
"""A caller base_url differing from the profile default overrides
models_url — a user-configured proxy must win over the profile's
hardcoded catalog endpoint (Discord report: CommandCode picker)."""
server, port = _start_server([{"id": "proxy-model-b"}])
try:
profile = ProviderProfile(
name="test",
base_url="http://127.0.0.1:1",
models_url="http://127.0.0.1:1/models", # unreachable
)
result = profile.fetch_models(
api_key="test-key",
base_url=f"http://127.0.0.1:{port}",
)
assert result == ["proxy-model-b"]
finally:
server.shutdown()
def test_default_base_url_does_not_shadow_models_url(self):
"""Callers pass base_url unconditionally (profile default when the
user configured nothing). Equality with self.base_url means "not
customised" and must keep models_url as the endpoint."""
server, port = _start_server([{"id": "catalog-model"}])
try:
profile = ProviderProfile(
name="test",
base_url="http://127.0.0.1:1", # inference URL, unreachable
models_url=f"http://127.0.0.1:{port}/models",
)
# Caller echoes the profile default back — models_url must win.
result = profile.fetch_models(
api_key="test-key",
base_url="http://127.0.0.1:1/", # same default, trailing slash
)
assert result == ["catalog-model"]
finally:
server.shutdown()
class TestCustomProviderBaseUrlPassthrough:
"""Custom provider (ollama/local) should pass base_url through to super."""
def test_custom_passes_base_url(self):
"""CustomProfile.fetch_models passes base_url to super()."""
server, port = _start_server([{"id": "ollama-model"}])
try:
from plugins.model_providers.custom import CustomProfile
profile = CustomProfile(
name="custom",
base_url="http://127.0.0.1:1", # wrong port
)
result = profile.fetch_models(
api_key="",
base_url=f"http://127.0.0.1:{port}",
)
assert result == ["ollama-model"]
finally:
server.shutdown()
class _RedirectingHandler(BaseHTTPRequestHandler):
"""Redirects /models to a configurable target and records received headers."""
redirect_to = "" # full URL to redirect /models to (set per test)
received_headers: dict = {}
def do_GET(self):
if self.path.rstrip("/") == "/models":
self.send_response(302)
self.send_header("Location", type(self).redirect_to)
self.end_headers()
else:
_RedirectingHandler.received_headers = dict(self.headers)
body = json.dumps({"data": [{"id": "redirected-model"}]}).encode()
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(body)
def log_message(self, format, *args):
pass
class TestFetchModelsRedirectCredentialStripping:
"""Credential headers must not follow a redirect outside the original origin."""
def _run(self, redirect_to):
"""redirect_to is a callable (first_port, second_port) -> Location URL."""
_RedirectingHandler.received_headers = {}
server = HTTPServer(("127.0.0.1", 0), _RedirectingHandler)
second_server = HTTPServer(("127.0.0.1", 0), _RedirectingHandler)
port = server.server_address[1]
second_port = second_server.server_address[1]
_RedirectingHandler.redirect_to = redirect_to(port, second_port)
Thread(target=server.serve_forever, daemon=True).start()
Thread(target=second_server.serve_forever, daemon=True).start()
try:
profile = ProviderProfile(
name="test",
base_url=f"http://127.0.0.1:{port}",
default_headers={"x-api-key": "default-header-secret"},
)
result = profile.fetch_models(api_key="bearer-secret")
finally:
server.shutdown()
second_server.shutdown()
headers = {k.lower(): v for k, v in _RedirectingHandler.received_headers.items()}
return result, headers
def test_cross_host_redirect_strips_credentials(self):
result, headers = self._run(
lambda port, _: f"http://localhost:{port}/redirected"
)
assert result == ["redirected-model"] # fetch itself still works
assert "authorization" not in headers
assert "x-api-key" not in headers
def test_same_origin_redirect_keeps_credentials(self):
result, headers = self._run(
lambda port, _: f"http://127.0.0.1:{port}/redirected"
)
assert result == ["redirected-model"]
assert headers.get("authorization") == "Bearer bearer-secret"
assert headers.get("x-api-key") == "default-header-secret"
class TestModelPickerBaseUrlIntegration:
"""The /model picker path should pass model.base_url to fetch_models."""
def test_picker_passes_base_url(self):
"""Verify models.py caller passes base_url to fetch_models."""
mock_profile = MagicMock()
mock_profile.auth_type = "api_key"
mock_profile.base_url = "https://default.api.com"
mock_profile.fetch_models.return_value = ["model-a"]
with (
patch("providers.get_provider_profile", return_value=mock_profile),
patch("hermes_cli.auth.resolve_api_key_provider_credentials",
return_value={"api_key": "sk-test", "base_url": "https://custom.proxy.com"}),
):
from hermes_cli.models import provider_model_ids
result = provider_model_ids("test-provider")
# Verify fetch_models was called with base_url
mock_profile.fetch_models.assert_called_once()
call_kwargs = mock_profile.fetch_models.call_args
assert call_kwargs.kwargs.get("base_url") == "https://custom.proxy.com"
@@ -0,0 +1,78 @@
"""A provider installed by ``hermes plugins install`` must actually be found.
The installer clones into ``$HERMES_HOME/plugins/<name>/`` (flat), provider
discovery only scanned ``plugins/model-providers/<name>/``, and PluginManager
skips ``kind: model-provider`` on purpose — so the documented install path
reported success and registered nothing. These tests pin the join, and that
discovery keeps its hands off every other plugin in that directory.
"""
from __future__ import annotations
import sys
import textwrap
from pathlib import Path
import pytest
_PROFILE_SOURCE = textwrap.dedent(
"""
from providers import register_provider
from providers.base import ProviderProfile
register_provider(ProviderProfile(name="{name}", aliases=("{name}-alias",),
base_url="acp://{name}", auth_type="external_process"))
"""
)
def _clear_provider_caches():
import providers as _pkg
_pkg._REGISTRY.clear()
_pkg._ALIASES.clear()
_pkg._PROVIDER_LIST_CACHE = None
_pkg._discovered = False
for mod in list(sys.modules):
if mod.startswith(("plugins.model_providers", "_hermes_user_provider")):
del sys.modules[mod]
def _write_plugin(directory: Path, *, name: str, manifest: str | None):
directory.mkdir(parents=True, exist_ok=True)
if manifest is not None:
(directory / "plugin.yaml").write_text(manifest, encoding="utf-8")
# Registers a provider on import, so an unwanted import is *visible*.
(directory / "__init__.py").write_text(_PROFILE_SOURCE.format(name=name), encoding="utf-8")
@pytest.fixture
def hermes_home(tmp_path, monkeypatch):
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
_clear_provider_caches()
yield tmp_path
_clear_provider_caches()
def test_flat_installed_model_provider_plugins_are_discovered_alongside_nested_ones(hermes_home):
_write_plugin(hermes_home / "plugins" / "installed-acp", name="installed-acp",
manifest='name: installed-acp\nkind: "model-provider"\n')
_write_plugin(hermes_home / "plugins" / "model-providers" / "nested-acp", name="nested-acp",
manifest="name: nested-acp\nkind: model-provider\n")
from providers import get_provider_profile
assert get_provider_profile("installed-acp").base_url == "acp://installed-acp"
assert get_provider_profile("installed-acp-alias") is not None
assert get_provider_profile("nested-acp") is not None
def test_other_plugins_in_the_flat_directory_are_left_to_the_plugin_manager(hermes_home):
_write_plugin(hermes_home / "plugins" / "other-standalone", name="other-standalone",
manifest="name: other-standalone\nkind: standalone\n")
_write_plugin(hermes_home / "plugins" / "manifestless", name="manifestless", manifest=None)
_write_plugin(hermes_home / "plugins" / "broken-manifest", name="broken-manifest",
manifest="kind: [this is: not valid\n")
from providers import get_provider_profile, list_providers
assert not [p for p in list_providers() if p.name in ("other-standalone", "manifestless", "broken-manifest")]
assert get_provider_profile("copilot-acp") is not None # bundled set still intact
+81
View File
@@ -0,0 +1,81 @@
"""Tests for the bundled Meta Model API (Muse Spark) provider plugin.
Adapted from the plugin's original suite at
https://github.com/albertodepaola/hermes-meta-provider — the plugin is now
bundled, so profiles resolve through normal registry discovery.
"""
import pytest
from providers import get_provider_profile
from providers.base import ProviderProfile
def _profile():
p = get_provider_profile("meta-ai")
assert p is not None
return p
class TestMetaAIProfile:
def test_profile_registered(self):
p = _profile()
assert p.name == "meta-ai"
assert p.base_url == "https://api.meta.ai/v1"
assert p.auth_type == "api_key"
# Responses API engages Muse prompt caching (0% on chat/completions
# vs 93-99% on /v1/responses with prompt_cache_retention).
assert p.api_mode == "codex_responses"
assert "MODEL_API_KEY" in p.env_vars
assert p.supports_vision is True
# Images are accepted on user turns only; tool-result envelopes 400 (#101668).
assert p.supports_vision_tool_messages is False
assert p.default_aux_model == "muse-spark-1.2-contributor"
assert p.default_max_tokens == 16384
assert p.fallback_models == ("muse-spark-1.2",)
def test_live_catalog_filters_non_chat_models(self, monkeypatch):
p = _profile()
seen = []
def fake_fetch_models(_self, **_kwargs):
seen.append(True)
return [
"muse-voice-transcribe-1.0",
"muse-spark-latest",
"muse-image-1.0-eval",
"muse-nova-test",
]
monkeypatch.setattr(ProviderProfile, "fetch_models", fake_fetch_models)
assert p.fetch_models() == ["muse-spark-latest", "muse-nova-test"]
assert seen
@pytest.mark.parametrize("alias", ["meta", "muse", "muse-spark", "model-api", "msl"])
def test_aliases_resolve(self, alias):
assert get_provider_profile(alias) is _profile()
def _effort(cfg):
_eb, top = _profile().build_api_kwargs_extras(reasoning_config=cfg)
return top.get("reasoning_effort")
class TestReasoningEffort:
def test_mapping(self):
assert _effort(None) == "medium" # unset -> medium
assert _effort({"enabled": True, "effort": "high"}) == "high"
assert _effort({"enabled": True, "effort": "low"}) == "low"
assert _effort({"enabled": True, "effort": "max"}) == "xhigh"
assert _effort({"enabled": False}) == "minimal" # disabled -> minimal
# Meta 400s on "none" — must map to "minimal"
assert _effort({"effort": "none"}) == "minimal"
def test_never_uses_extra_body(self):
"""The dial must be top-level, not extra_body.reasoning (core-gated path)."""
eb, top = _profile().build_api_kwargs_extras(
reasoning_config={"enabled": True, "effort": "high"}
)
assert eb == {}
assert "reasoning_effort" in top
+126
View File
@@ -0,0 +1,126 @@
"""Tests for the model-providers plugin discovery system.
Verifies that:
1. All bundled providers at plugins/model-providers/<name>/ are discovered
2. User plugins at $HERMES_HOME/plugins/model-providers/<name>/ override bundled
3. plugin.yaml manifests with kind=model-provider are correctly categorized
"""
from __future__ import annotations
import sys
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[2]
def _clear_provider_caches():
"""Force providers/__init__.py to re-discover on next list_providers()."""
import providers as _pkg
_pkg._REGISTRY.clear()
_pkg._ALIASES.clear()
_pkg._PROVIDER_LIST_CACHE = None
_pkg._discovered = False
# Evict any cached plugin modules so the next import re-executes.
for mod in list(sys.modules.keys()):
if (
mod.startswith("plugins.model_providers")
or mod.startswith("_hermes_user_provider")
):
del sys.modules[mod]
def test_bundled_plugins_discovered():
"""Every plugins/model-providers/<name>/ should contain a plugin.yaml + __init__.py."""
plugins_dir = REPO_ROOT / "plugins" / "model-providers"
assert plugins_dir.is_dir(), f"Missing {plugins_dir}"
child_dirs = [c for c in plugins_dir.iterdir() if c.is_dir()]
assert len(child_dirs) >= 28, f"Expected at least 28 provider plugins, found {len(child_dirs)}"
for child in child_dirs:
assert (child / "__init__.py").exists(), f"{child.name} missing __init__.py"
assert (child / "plugin.yaml").exists(), f"{child.name} missing plugin.yaml"
def test_all_profiles_register():
"""After discovery, the registry must contain every bundled provider directory.
This is an invariant — the number of profiles matches the number of plugin
directories, not a hardcoded count. Counts shift when providers are
added/removed; that's expected and shouldn't break CI.
"""
_clear_provider_caches()
from providers import list_providers
plugins_dir = REPO_ROOT / "plugins" / "model-providers"
plugin_dir_count = sum(1 for c in plugins_dir.iterdir() if c.is_dir())
profiles = list_providers()
names = sorted(p.name for p in profiles)
# Some plugin __init__.py files register multiple profiles, so the registry
# count is >= the directory count (never less).
assert len(names) >= plugin_dir_count, (
f"Expected at least {plugin_dir_count} profiles (one per plugin dir), got {len(names)}: {names}"
)
# Spot-check representative providers from different categories
for required in (
"openrouter", "anthropic", "custom", "bedrock", "openai-codex",
"minimax-oauth", "gmi", "xiaomi", "alibaba-coding-plan", "fireworks",
"nebius-token-factory",
):
assert required in names, f"Missing profile: {required}"
def test_user_plugin_overrides_bundled(tmp_path, monkeypatch):
"""A user plugin with the same name must override the bundled profile."""
# Point HERMES_HOME at a fresh temp dir
hermes_home = tmp_path / ".hermes"
hermes_home.mkdir()
monkeypatch.setenv("HERMES_HOME", str(hermes_home))
# get_hermes_home() may be module-cached depending on codebase; ensure the
# env var is the source of truth. Most code paths re-read it each call.
# Drop a user plugin that replaces 'gmi'
user_gmi = hermes_home / "plugins" / "model-providers" / "gmi"
user_gmi.mkdir(parents=True)
(user_gmi / "__init__.py").write_text(
"from providers import register_provider\n"
"from providers.base import ProviderProfile\n"
"\n"
"custom_gmi = ProviderProfile(\n"
' name="gmi",\n'
' aliases=("gmi-user-override-test",),\n'
' env_vars=("GMI_API_KEY",),\n'
' base_url="https://user-override.example.com/v1",\n'
' auth_type="api_key",\n'
")\n"
"register_provider(custom_gmi)\n"
)
(user_gmi / "plugin.yaml").write_text(
"name: gmi-user-override\n"
"kind: model-provider\n"
"version: 0.0.1\n"
"description: Test user override\n"
)
_clear_provider_caches()
from providers import get_provider_profile
gmi = get_provider_profile("gmi")
assert gmi is not None
assert gmi.base_url == "https://user-override.example.com/v1", (
f"User override not applied; got base_url={gmi.base_url!r}"
)
assert "gmi-user-override-test" in gmi.aliases
# Clean up: reset discovery state so other tests see the bundled version
_clear_provider_caches()
# No import means the module must NOT be in the plugins list as a loaded one.
# We check that the general loader didn't crash and didn't raise from the
# broken __init__.py.
+178
View File
@@ -0,0 +1,178 @@
"""Profile-path parity tests: verify profile path produces identical output to legacy flags.
Each test calls build_kwargs twice — once with legacy flags, once with provider_profile —
and asserts the output is identical. This catches any behavioral drift between the two paths.
"""
import pytest
from agent.transports.chat_completions import ChatCompletionsTransport
from providers import get_provider_profile
@pytest.fixture
def transport():
return ChatCompletionsTransport()
def _msgs():
return [{"role": "user", "content": "hello"}]
def _max_tokens_fn(n):
return {"max_completion_tokens": n}
class TestNvidiaProfileParity:
def test_max_tokens_match(self, transport):
"""NVIDIA profile sets max_tokens=16384; legacy flag is removed."""
profile = transport.build_kwargs(
model="nvidia/nemotron", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("nvidia"),
max_tokens_param_fn=_max_tokens_fn,
)
assert profile["max_completion_tokens"] == 16384
class TestKimiProfileParity:
def test_temperature_omitted(self, transport):
legacy = transport.build_kwargs(
model="kimi-k2", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("kimi-coding"), omit_temperature=True,
)
profile = transport.build_kwargs(
model="kimi-k2", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("kimi"),
)
assert "temperature" not in legacy
assert "temperature" not in profile
def test_thinking_enabled(self, transport):
# xor contract: explicit effort → reasoning_effort only, no thinking.
rc = {"enabled": True, "effort": "high"}
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["reasoning_effort"] == legacy["reasoning_effort"] == "high"
assert "thinking" not in profile.get("extra_body", {})
assert "thinking" not in legacy.get("extra_body", {})
class TestOpenRouterProfileParity:
def test_provider_preferences(self, transport):
prefs = {"allow": ["anthropic"]}
legacy = transport.build_kwargs(
model="anthropic/claude-sonnet-4.6", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("openrouter"), provider_preferences=prefs,
)
profile = transport.build_kwargs(
model="anthropic/claude-sonnet-4.6", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("openrouter"),
provider_preferences=prefs,
)
assert profile["extra_body"]["provider"] == legacy["extra_body"]["provider"]
def test_reasoning_full_config(self, transport):
rc = {"enabled": True, "effort": "high"}
legacy = transport.build_kwargs(
model="deepseek/deepseek-chat", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("openrouter"), supports_reasoning=True, reasoning_config=rc,
)
profile = transport.build_kwargs(
model="deepseek/deepseek-chat", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("openrouter"),
supports_reasoning=True, reasoning_config=rc,
)
assert profile["extra_body"]["reasoning"] == legacy["extra_body"]["reasoning"]
class TestNousProfileParity:
def test_tags(self, transport):
legacy = transport.build_kwargs(
model="hermes-3", messages=_msgs(), tools=None, provider_profile=get_provider_profile("nous"),
)
profile = transport.build_kwargs(
model="hermes-3", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("nous"),
)
assert profile["extra_body"]["tags"] == legacy["extra_body"]["tags"]
class TestQwenProfileParity:
def test_vl_high_resolution(self, transport):
legacy = transport.build_kwargs(
model="qwen3.5", messages=_msgs(), tools=None, provider_profile=get_provider_profile("qwen-oauth"),
)
profile = transport.build_kwargs(
model="qwen3.5", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("qwen"),
)
assert profile["extra_body"]["vl_high_resolution_images"] == legacy["extra_body"]["vl_high_resolution_images"]
def test_metadata_top_level(self, transport):
meta = {"sessionId": "s123", "promptId": "p456"}
legacy = transport.build_kwargs(
model="qwen3.5", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("qwen-oauth"), qwen_session_metadata=meta,
)
profile = transport.build_kwargs(
model="qwen3.5", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("qwen"),
qwen_session_metadata=meta,
)
assert profile["metadata"] == legacy["metadata"] == meta
assert "metadata" not in profile.get("extra_body", {})
class TestDeveloperRoleParity:
"""Developer role swap must work on BOTH legacy and profile paths."""
def test_legacy_path_swaps_for_gpt5(self, transport):
msgs = [{"role": "system", "content": "Be helpful"}, {"role": "user", "content": "hi"}]
kw = transport.build_kwargs(
model="gpt-5.4", messages=msgs, tools=None,
)
assert kw["messages"][0]["role"] == "developer"
def test_profile_path_swaps_for_gpt5(self, transport):
msgs = [{"role": "system", "content": "Be helpful"}, {"role": "user", "content": "hi"}]
kw = transport.build_kwargs(
model="gpt-5.4", messages=msgs, tools=None,
provider_profile=get_provider_profile("openrouter"),
)
assert kw["messages"][0]["role"] == "developer"
class TestRequestOverridesParity:
"""request_overrides with extra_body must merge identically on both paths."""
def test_extra_body_override_legacy(self, transport):
kw = transport.build_kwargs(
model="gpt-5.4", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("openrouter"),
request_overrides={"extra_body": {"custom_key": "custom_val"}},
)
assert kw["extra_body"]["custom_key"] == "custom_val"
def test_top_level_override(self, transport):
kw = transport.build_kwargs(
model="gpt-5.4", messages=_msgs(), tools=None,
provider_profile=get_provider_profile("openrouter"),
request_overrides={"top_p": 0.9},
)
assert kw["top_p"] == 0.9
+313
View File
@@ -0,0 +1,313 @@
"""Tests for the provider module registry and profiles."""
from providers import get_provider_profile, _REGISTRY
from providers.base import ProviderProfile, OMIT_TEMPERATURE
class TestRegistry:
def test_discovery_populates_registry(self):
p = get_provider_profile("nvidia")
assert p is not None
assert p.name == "nvidia"
class TestNvidiaProfile:
def test_max_tokens(self):
p = get_provider_profile("nvidia")
assert p.default_max_tokens == 16384
def test_base_url(self):
p = get_provider_profile("nvidia")
assert "nvidia.com" in p.base_url
def test_prepare_messages_strips_tool_result_names(self):
p = get_provider_profile("nvidia")
msgs = [
{"role": "user", "content": "run a command"},
{
"role": "assistant",
"content": None,
"tool_calls": [
{
"id": "call_1",
"type": "function",
"function": {"name": "terminal", "arguments": "{}"},
}
],
},
{
"role": "tool",
"name": "terminal",
"tool_name": "terminal",
"tool_call_id": "call_1",
"content": "ok",
},
]
result = p.prepare_messages(msgs)
assert "name" not in result[2]
assert "tool_name" not in result[2]
assert result[2] == {
"role": "tool",
"tool_call_id": "call_1",
"content": "ok",
}
assert msgs[2]["name"] == "terminal"
assert msgs[2]["tool_name"] == "terminal"
def test_prepare_messages_passthrough_without_tool_result_names(self):
p = get_provider_profile("nvidia")
msgs = [{"role": "tool", "tool_call_id": "call_1", "content": "ok"}]
assert p.prepare_messages(msgs) is msgs
class TestKimiProfile:
def test_temperature_omit(self):
p = get_provider_profile("kimi")
assert p.fixed_temperature is OMIT_TEMPERATURE
def test_thinking_enabled(self):
# xor contract (fix ce4e74b3): an explicit recognized effort sends
# reasoning_effort ONLY — never paired with extra_body.thinking.
p = get_provider_profile("kimi")
eb, tl = p.build_api_kwargs_extras(reasoning_config={"enabled": True, "effort": "high"})
assert tl["reasoning_effort"] == "high"
assert "thinking" not in eb
class TestOpenRouterProfile:
def test_extra_body_with_prefs(self):
p = get_provider_profile("openrouter")
body = p.build_extra_body(provider_preferences={"allow": ["anthropic"]})
assert body["provider"] == {"allow": ["anthropic"]}
def test_sticky_session_id_normalizes_cron_timestamp(self):
"""Cron re-fires of the same job keep the same sticky routing key."""
p = get_provider_profile("openrouter")
first = p.build_extra_body(session_id="cron_job42_20260801_090000")
second = p.build_extra_body(session_id="cron_job42_20260802_090000")
assert first["session_id"] == "cron_job42"
assert first["session_id"] == second["session_id"]
def test_pareto_min_coding_score_emitted_for_pareto_model(self):
"""min_coding_score → plugins block when model is openrouter/pareto-code."""
p = get_provider_profile("openrouter")
body = p.build_extra_body(
model="openrouter/pareto-code",
openrouter_min_coding_score=0.65,
)
assert body["plugins"] == [
{"id": "pareto-router", "min_coding_score": 0.65}
]
def test_grok_session_id_sets_cache_affinity_header(self):
"""OpenRouter + Grok model + session_id => x-grok-conv-id header."""
p = get_provider_profile("openrouter")
_, tl = p.build_api_kwargs_extras(
model="x-ai/grok-4",
session_id="sess-abc123",
)
assert tl["extra_headers"]["x-grok-conv-id"] == "sess-abc123"
def test_grok_conv_id_normalizes_cron_timestamp(self):
"""Cron re-fires of the same job must pin to the same xAI backend,
same as the body.session_id sticky key (#78941)."""
p = get_provider_profile("openrouter")
_, first = p.build_api_kwargs_extras(
model="x-ai/grok-4", session_id="cron_job42_20260801_090000",
)
_, second = p.build_api_kwargs_extras(
model="x-ai/grok-4", session_id="cron_job42_20260802_090000",
)
assert first["extra_headers"]["x-grok-conv-id"] == "cron_job42"
assert (
first["extra_headers"]["x-grok-conv-id"]
== second["extra_headers"]["x-grok-conv-id"]
)
# --- reasoning-mandatory Anthropic effort → top-level verbosity (#43432) ---
#
# These models (Claude 4.6+ / fable / mythos-class) ignore
# ``reasoning.effort`` and use adaptive thinking. OpenRouter honors the
# requested effort on the top-level ``verbosity`` field instead (maps to
# Anthropic ``output_config.effort``). The profile must route the existing
# ``reasoning_config["effort"]`` there while still NEVER emitting a
# ``reasoning`` field (which would 400 — see #42991). Gate every fixture on
# the real predicate so this stays a behavior contract, not a name snapshot.
@staticmethod
def _is_mandatory(model):
import inspect
p = get_provider_profile("openrouter")
mod = inspect.getmodule(type(p))
return mod._anthropic_reasoning_is_mandatory(model)
def test_mandatory_anthropic_verbosity_coexists_with_grok_header(self):
"""A reasoning-mandatory Anthropic model is never a Grok model, but the
top-level dict must remain a single merged dict — verify the verbosity
path doesn't clobber the extra_headers slot used by Grok affinity."""
p = get_provider_profile("openrouter")
# mandatory anthropic + effort → verbosity, no extra_headers
_, tl = p.build_api_kwargs_extras(
reasoning_config={"enabled": True, "effort": "high"},
supports_reasoning=True,
model="anthropic/claude-fable-5",
)
assert tl == {"verbosity": "high"}
class TestNousProfile:
def test_tags(self):
from agent.portal_tags import nous_portal_tags
p = get_provider_profile("nous")
body = p.build_extra_body()
assert body["tags"] == nous_portal_tags()
def test_sticky_session_id_normalizes_cron_timestamp(self):
"""Cron re-fires of the same job keep the same sticky routing key."""
p = get_provider_profile("nous")
first = p.build_extra_body(session_id="cron_job42_20260801_090000")
second = p.build_extra_body(session_id="cron_job42_20260802_090000")
assert first["session_id"] == "cron_job42"
assert first["session_id"] == second["session_id"]
def test_auth_type(self):
p = get_provider_profile("nous")
assert p.auth_type == "oauth_device_code"
class TestQwenProfile:
def test_prepare_messages_protects_nested_image_url_retry_mutation(self):
qwen = get_provider_profile("qwen-oauth")
image_url = {"url": "data:image/png;base64,original"}
msgs = [
{"role": "system", "content": "Be helpful"},
{
"role": "user",
"content": [
{"type": "text", "text": "see image"},
{"type": "image_url", "image_url": image_url},
],
},
]
qwen_result = qwen.prepare_messages(msgs)
assert qwen_result[1] is not msgs[1]
assert qwen_result[1]["content"] is not msgs[1]["content"]
assert qwen_result[1]["content"][1] is not msgs[1]["content"][1]
assert qwen_result[1]["content"][1]["image_url"] is not image_url
qwen_result[1]["content"][1]["image_url"]["url"] = (
"data:image/png;base64,shrunk"
)
assert msgs[1]["content"][1]["image_url"]["url"] == (
"data:image/png;base64,original"
)
def test_metadata_top_level(self):
p = get_provider_profile("qwen-oauth")
meta = {"sessionId": "s123", "promptId": "p456"}
eb, tl = p.build_api_kwargs_extras(qwen_session_metadata=meta)
assert tl["metadata"] == meta
assert "metadata" not in eb
class TestAlibabaRegionalAndTokenPlanProfiles:
"""#73265: the models.dev catalog advertises alibaba-cn /
alibaba-token-plan(-cn) / alibaba-coding-plan-cn, but none were registered
at runtime — `model.provider: alibaba-coding-plan-cn` failed with
"Unknown provider" and users were forced onto the `custom` escape hatch.
Profile names intentionally match the catalog keys exactly so model
metadata lines up."""
def test_alibaba_cn_registered(self):
p = get_provider_profile("alibaba-cn")
assert p is not None and p.name == "alibaba-cn"
assert p.base_url == "https://dashscope.aliyuncs.com/compatible-mode/v1"
assert "DASHSCOPE_API_KEY" in p.env_vars
assert "DASHSCOPE_CN_BASE_URL" in p.env_vars
def test_alibaba_coding_plan_cn_registered(self):
p = get_provider_profile("alibaba-coding-plan-cn")
assert p is not None and p.name == "alibaba-coding-plan-cn"
assert p.base_url == "https://coding.dashscope.aliyuncs.com/v1"
assert "ALIBABA_CODING_PLAN_API_KEY" in p.env_vars
def test_alibaba_token_plan_registered(self):
p = get_provider_profile("alibaba-token-plan")
assert p is not None and p.name == "alibaba-token-plan"
assert p.base_url == "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
assert "ALIBABA_TOKEN_PLAN_API_KEY" in p.env_vars
def test_alibaba_token_plan_cn_registered(self):
p = get_provider_profile("alibaba-token-plan-cn")
assert p is not None and p.name == "alibaba-token-plan-cn"
assert p.base_url == "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1"
assert "ALIBABA_TOKEN_PLAN_API_KEY" in p.env_vars
def test_cn_variants_resolve_in_auth_registry(self, monkeypatch):
"""The reporter's exact failure site: ``auth.resolve_provider()`` only
consults PROVIDER_REGISTRY (auto-extended from provider profiles,
hermes_cli/auth.py:461-490) and raised
"Unknown provider 'alibaba-coding-plan-cn'" (hermes_cli/auth.py:1937)
even though the models.dev catalog advertised the id — the
resolve_provider_full() catalog chain covers only the CLI --provider
path, not the credential/runtime path."""
from hermes_cli.auth import PROVIDER_REGISTRY, resolve_provider
monkeypatch.setenv("DASHSCOPE_API_KEY", "sk-test")
monkeypatch.setenv("ALIBABA_CODING_PLAN_API_KEY", "sk-test")
monkeypatch.setenv("ALIBABA_TOKEN_PLAN_API_KEY", "sk-test")
for pid in ("alibaba-cn", "alibaba-coding-plan-cn",
"alibaba-token-plan", "alibaba-token-plan-cn"):
assert pid in PROVIDER_REGISTRY, f"{pid} missing from PROVIDER_REGISTRY"
assert resolve_provider(pid) == pid
assert (PROVIDER_REGISTRY["alibaba-token-plan-cn"].inference_base_url
== "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1")
+66
View File
@@ -0,0 +1,66 @@
import pytest
from providers import ProviderProfile
import providers
@pytest.fixture(autouse=True)
def isolate_provider_registry():
registry = providers._REGISTRY.copy()
aliases = providers._ALIASES.copy()
provider_list_cache = (
None
if providers._PROVIDER_LIST_CACHE is None
else list(providers._PROVIDER_LIST_CACHE)
)
discovered = providers._discovered
yield
providers._REGISTRY.clear()
providers._REGISTRY.update(registry)
providers._ALIASES.clear()
providers._ALIASES.update(aliases)
providers._PROVIDER_LIST_CACHE = provider_list_cache
providers._discovered = discovered
def _profile(name: str, *aliases: str) -> ProviderProfile:
return ProviderProfile(name=name, aliases=aliases)
def _reset_registry() -> None:
providers._REGISTRY.clear()
providers._ALIASES.clear()
providers._PROVIDER_LIST_CACHE = None
providers._discovered = True
def test_list_providers_reuses_cached_snapshot_until_registration_changes():
_reset_registry()
first = _profile("alpha")
providers.register_provider(first)
listed = providers.list_providers()
listed.clear()
assert providers.list_providers() == [first]
# Hit-path copy guard: mutating a CACHED return must not corrupt the
# module-level snapshot for later callers (aliasing bug class).
providers.list_providers().clear()
assert providers.list_providers() == [first]
second = _profile("beta")
providers.register_provider(second)
assert providers.list_providers() == [first, second]
def test_list_providers_dedupes_aliases_in_cached_snapshot():
_reset_registry()
profile = _profile("kimi", "moonshot", "kimi-k2")
providers.register_provider(profile)
assert providers.get_provider_profile("moonshot") is profile
assert providers.list_providers() == [profile]
+185
View File
@@ -0,0 +1,185 @@
"""Parity tests: pin the exact current transport behavior per provider.
These tests document the flag-based contract between run_agent.py and
ChatCompletionsTransport.build_kwargs(). When the next PR wires profiles
to replace flags, every assertion here must still pass — any failure is
a behavioral regression.
"""
import pytest
from agent.transports.chat_completions import ChatCompletionsTransport
from providers import get_provider_profile
@pytest.fixture
def transport():
return ChatCompletionsTransport()
def _simple_messages():
return [{"role": "user", "content": "hello"}]
def _max_tokens_fn(n):
return {"max_completion_tokens": n}
class TestNvidiaParity:
"""NVIDIA NIM: default max_tokens=16384."""
def test_user_max_tokens_overrides(self, transport):
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=4096,
max_tokens_param_fn=_max_tokens_fn,
provider_profile=profile,
)
assert kw["max_completion_tokens"] == 4096 # user overrides default
class TestKimiParity:
"""Kimi: OMIT temperature, max_tokens=32000, thinking + reasoning_effort."""
def test_temperature_omitted(self, transport):
kw = transport.build_kwargs(
model="kimi-k2",
messages=_simple_messages(),
tools=None,
provider_profile=get_provider_profile("kimi-coding"),
omit_temperature=True,
)
assert "temperature" not in kw
def test_thinking_enabled(self, transport):
# xor contract (fix ce4e74b3): an explicit recognized effort sends
# reasoning_effort ONLY — never paired with extra_body.thinking.
kw = transport.build_kwargs(
model="kimi-k2",
messages=_simple_messages(),
tools=None,
provider_profile=get_provider_profile("kimi-coding"),
reasoning_config={"enabled": True, "effort": "high"},
)
assert kw.get("reasoning_effort") == "high"
assert "thinking" not in kw.get("extra_body", {})
def test_reasoning_effort_top_level(self, transport):
"""Kimi reasoning_effort is a TOP-LEVEL api_kwargs key, NOT in extra_body."""
kw = transport.build_kwargs(
model="kimi-k2",
messages=_simple_messages(),
tools=None,
provider_profile=get_provider_profile("kimi-coding"),
reasoning_config={"enabled": True, "effort": "high"},
)
assert kw.get("reasoning_effort") == "high"
assert "reasoning_effort" not in kw.get("extra_body", {})
class TestOpenRouterParity:
"""OpenRouter: provider preferences, reasoning in extra_body."""
def test_provider_preferences(self, transport):
prefs = {"allow": ["anthropic"], "sort": "price"}
kw = transport.build_kwargs(
model="anthropic/claude-sonnet-4.6",
messages=_simple_messages(),
tools=None,
provider_profile=get_provider_profile("openrouter"),
provider_preferences=prefs,
)
assert kw["extra_body"]["provider"] == prefs
class TestNousParity:
"""Nous: product tags, reasoning passthrough (disable included)."""
def test_tags(self, transport):
from agent.portal_tags import nous_portal_tags
kw = transport.build_kwargs(
model="hermes-3-llama-3.1-405b",
messages=_simple_messages(),
tools=None,
provider_profile=get_provider_profile("nous"),
)
assert kw["extra_body"]["tags"] == nous_portal_tags()
class TestQwenParity:
"""Qwen: max_tokens=65536, vl_high_resolution, metadata top-level."""
def test_vl_high_resolution(self, transport):
kw = transport.build_kwargs(
model="qwen3.5-plus",
messages=_simple_messages(),
tools=None,
provider_profile=get_provider_profile("qwen-oauth"),
)
assert kw["extra_body"]["vl_high_resolution_images"] is True
def test_metadata_top_level(self, transport):
"""Qwen metadata goes to top-level api_kwargs, NOT extra_body."""
meta = {"sessionId": "s123", "promptId": "p456"}
kw = transport.build_kwargs(
model="qwen3.5-plus",
messages=_simple_messages(),
tools=None,
provider_profile=get_provider_profile("qwen-oauth"),
qwen_session_metadata=meta,
)
assert kw["metadata"] == meta
assert "metadata" not in kw.get("extra_body", {})
class TestCustomOllamaParity:
"""Custom/Ollama: num_ctx, thinking controls — now tested via profile."""
def test_ollama_num_ctx(self, transport):
kw = transport.build_kwargs(
model="llama3.1",
messages=_simple_messages(),
tools=None,
provider_profile=get_provider_profile("custom"),
ollama_num_ctx=131072,
)
assert kw["extra_body"]["options"]["num_ctx"] == 131072
def test_think_false_when_disabled(self, transport):
kw = transport.build_kwargs(
model="qwen3:72b",
messages=_simple_messages(),
tools=None,
provider_profile=get_provider_profile("custom"),
reasoning_config={"enabled": False, "effort": "none"},
base_url="http://127.0.0.1:11434/v1",
)
assert kw["extra_body"]["think"] is False
def test_think_omitted_for_mistral_custom(self, transport):
kw = transport.build_kwargs(
model="mistral-small-latest",
messages=_simple_messages(),
tools=None,
provider_profile=get_provider_profile("custom"),
reasoning_config={"enabled": False, "effort": "none"},
base_url="https://api.mistral.ai/v1",
)
assert kw.get("extra_body", {}).get("think") is None
assert kw.get("reasoning_effort") == "none"