Files
hermes-agent/plugins/model-providers/commandcode/__init__.py
kshitijk4poor ef754d75ba refactor(commandcode): resolve the native DeepSeek profile through the registry
The delegation imported ``plugins.model_providers.deepseek`` — the only cross-plugin
module import in the tree, and one that resolves solely through the loader's
sys.modules shim (popped again if the deepseek plugin fails to load). Look the
profile up with get_provider_profile("deepseek") instead: already imported from
``providers``, honours a user override of the profile, degrades to the base no-op
without a try/except.

Drop the ``len(m) <= len("deepseek/")`` guard — the native profile returns
({}, {}) for an empty id anyway. Bind the expected value in the parity test and
assert it is non-empty so the equality cannot pass as ({}, {}) == ({}, {}).
2026-09-13 19:46:52 +05:30

100 lines
4.8 KiB
Python

"""CommandCode provider profiles: ``commandcode`` (chat_completions) and
``commandcode-anthropic`` (anthropic_messages, Bearer auth — see
``agent/anthropic_adapter.py``). Same key and base URL for both."""
import json
import logging
import urllib.request
from hermes_cli.urllib_security import open_credentialed_url
from providers import get_provider_profile, register_provider
from providers.base import ProviderProfile, _profile_user_agent
logger = logging.getLogger(__name__)
_COMMANDCODE_BASE = "https://api.commandcode.ai/provider/v1"
_COMMANDCODE_MODELS_URL = f"{_COMMANDCODE_BASE}/models"
class CommandCodeProfile(ProviderProfile):
"""CommandCode — OpenAI-compatible chat completions endpoint."""
def fetch_models(
self, *, api_key: str | None = None, base_url: str | None = None, timeout: float = 8.0
) -> list[str] | None:
"""Public (unauthenticated) /models endpoint. The picker passes base_url
unconditionally, so only a value differing from the default is a custom endpoint."""
caller_base = (base_url or "").strip().rstrip("/")
custom = caller_base and caller_base != _COMMANDCODE_BASE
models_url = caller_base + "/models" if custom else _COMMANDCODE_MODELS_URL
try:
req = urllib.request.Request(models_url)
req.add_header("Accept", "application/json")
req.add_header("User-Agent", _profile_user_agent())
with open_credentialed_url(req, timeout=timeout) as resp:
data = json.loads(resp.read().decode())
return [m["id"] for m in data.get("data", []) if isinstance(m, dict) and "id" in m]
except Exception as exc:
logger.debug("fetch_models(commandcode): %s", exc)
return None
def build_api_kwargs_extras(
self, *, reasoning_config: dict | None = None, model: str | None = None, **context
) -> tuple[dict, dict]:
"""DeepSeek ids (``deepseek/deepseek-v4-flash``) get the native DeepSeek wire
controls: DeepSeek V4+ defaults to thinking when ``thinking`` is omitted, so
without them ``/reasoning`` never reaches the request (#95232). Other model
families stay a no-op — CommandCode declares no reasoning vocabulary for them."""
m = (model or "").strip()
if not m.lower().startswith("deepseek/"):
return {}, {}
# Registry lookup, not a module import: the deepseek shim is only a loader-injected
# sys.modules entry, and the registry honours a user override of the profile.
native = get_provider_profile("deepseek")
if native is None:
return {}, {}
return native.build_api_kwargs_extras(
reasoning_config=reasoning_config, model=m.split("/", 1)[1], **context,
)
class CommandCodeAnthropicProfile(CommandCodeProfile):
"""CommandCode — Anthropic Messages API-compatible endpoint."""
def fetch_models(
self, *, api_key: str | None = None, base_url: str | None = None, timeout: float = 8.0
) -> list[str] | None:
"""Public /models endpoint, filtered to Anthropic-family models."""
all_models = super().fetch_models(api_key=api_key, base_url=base_url, timeout=timeout)
return None if all_models is None else [m for m in all_models if m.startswith("claude-")]
commandcode = CommandCodeProfile(
name="commandcode", aliases=("commandcode-chat",), api_mode="chat_completions",
# Same key as the anthropic profile; distinct base-URL override vars so each
# profile renders its own card on the desktop Keys tab (rows keyed by env var).
env_vars=("COMMANDCODE_API_KEY", "COMMANDCODE_BASE_URL"),
display_name="CommandCode", description="CommandCode — 20+ models via OpenAI-compatible API",
signup_url="https://commandcode.ai/", base_url=_COMMANDCODE_BASE, models_url=_COMMANDCODE_MODELS_URL,
fallback_models=(
"deepseek/deepseek-v4-pro", "deepseek/deepseek-v4-flash", "Qwen/Qwen3.7-Max", "Qwen/Qwen3.6-Plus",
"moonshotai/Kimi-K2.6", "zai-org/GLM-5.1", "MiniMaxAI/MiniMax-M2.7", "stepfun/Step-3.5-Flash",
"xiaomi/mimo-v2.5-pro", "google/gemini-3.5-flash", "gpt-5.5",
),
default_aux_model="deepseek/deepseek-v4-flash",
)
commandcode_anthropic = CommandCodeAnthropicProfile(
name="commandcode-anthropic", aliases=("commandcode-claude",), api_mode="anthropic_messages",
env_vars=("COMMANDCODE_API_KEY", "COMMANDCODE_ANTHROPIC_BASE_URL"),
display_name="CommandCode (Anthropic)",
description="CommandCode — Claude models via Anthropic Messages API",
signup_url="https://commandcode.ai/", base_url=_COMMANDCODE_BASE, models_url=_COMMANDCODE_MODELS_URL,
fallback_models=("claude-sonnet-4-6", "claude-opus-4-7", "claude-haiku-4-5-20251001"),
default_aux_model="claude-haiku-4-5-20251001",
)
register_provider(commandcode)
register_provider(commandcode_anthropic)