Spaces:
Configuration error
Configuration error
File size: 6,173 Bytes
a37e1b9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | """CommandCode provider profile.
CommandCode provides a unified API that fronts 20+ models from DeepSeek, Qwen,
Kimi, GLM, MiniMax, StepFun, Xiaomi Mimo, Google Gemini, and OpenAI GPT β all
accessible through either OpenAI-compatible chat completions or Anthropic
Messages endpoints from a single base URL and API key.
Two provider profiles are registered:
``commandcode``
``api_mode=chat_completions`` β standard OpenAI-compatible endpoint.
Model prefix: ``deepseek/deepseek-v4-pro``, ``Qwen/Qwen3.7-Max``, etc.
``commandcode-anthropic``
``api_mode=anthropic_messages`` β Anthropic Messages API-compatible.
Model names: ``claude-sonnet-4-6``, ``claude-opus-4-7``,
``claude-haiku-4-5-20251001``.
Both use the same ``COMMANDCODE_API_KEY`` env var and
``https://api.commandcode.ai/provider/v1`` base URL. The
``commandcode-anthropic`` profile relies on ``agent/anthropic_adapter.py``
recognizing the ``api.commandcode.ai`` hostname for Bearer auth (the
CommandCode /anthropic endpoint uses ``Authorization: Bearer``, not
Anthropic's native ``x-api-key`` header).
"""
from __future__ import annotations
import json
import logging
import urllib.request
from providers import register_provider
from providers.base import ProviderProfile, _profile_user_agent
logger = logging.getLogger(__name__)
# ββ Shared constants ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
_COMMANDCODE_BASE = "https://api.commandcode.ai/provider/v1"
_COMMANDCODE_MODELS_URL = f"{_COMMANDCODE_BASE}/models"
# Both profiles authenticate with the same key; each carries its own base-URL
# override var so each renders its own card on the desktop Keys tab (rows are
# keyed by env var, and the shared API key attributes to the first profile).
_COMMANDCODE_ENV = ("COMMANDCODE_API_KEY", "COMMANDCODE_BASE_URL")
_COMMANDCODE_ANTHROPIC_ENV = ("COMMANDCODE_API_KEY", "COMMANDCODE_ANTHROPIC_BASE_URL")
def _fetch_commandcode_models(
timeout: float = 10.0,
) -> list[str] | None:
"""Fetch the live model list from the CommandCode /models endpoint.
Returns a flat list of model IDs or None on failure.
No auth required β the public models endpoint is open.
"""
try:
req = urllib.request.Request(_COMMANDCODE_MODELS_URL)
req.add_header("Accept", "application/json")
req.add_header("User-Agent", _profile_user_agent())
with urllib.request.urlopen(req, timeout=timeout) as resp:
data = json.loads(resp.read().decode())
# Response shape: {"object": "list", "data": [{"id": "..."}, ...]}
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
# ββ Chat Completions profile ββββββββββββββββββββββββββββββββββββββββββββββββββ
class CommandCodeProfile(ProviderProfile):
"""CommandCode β OpenAI-compatible chat completions endpoint."""
def fetch_models(
self,
*,
api_key: str | None = None,
timeout: float = 8.0,
) -> list[str] | None:
"""Fetch from the public CommandCode /models endpoint."""
return _fetch_commandcode_models(timeout=timeout)
commandcode = CommandCodeProfile(
name="commandcode",
aliases=("commandcode-chat",),
api_mode="chat_completions",
env_vars=_COMMANDCODE_ENV,
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",
)
# ββ Anthropic Messages profile ββββββββββββββββββββββββββββββββββββββββββββββββ
class CommandCodeAnthropicProfile(ProviderProfile):
"""CommandCode β Anthropic Messages API-compatible endpoint.
Uses Bearer auth (same API key), not Anthropic's native x-api-key header.
``agent/anthropic_adapter.py`` must recognize ``api.commandcode.ai``
as a Bearer-auth domain for this to work.
"""
def fetch_models(
self,
*,
api_key: str | None = None,
timeout: float = 8.0,
) -> list[str] | None:
"""Fetch from the public CommandCode /models endpoint.
Filter to Anthropic-family models only (claude-*).
"""
all_models = _fetch_commandcode_models(timeout=timeout)
if all_models is None:
return None
return [m for m in all_models if m.startswith("claude-")]
commandcode_anthropic = CommandCodeAnthropicProfile(
name="commandcode-anthropic",
aliases=("commandcode-claude",),
api_mode="anthropic_messages",
env_vars=_COMMANDCODE_ANTHROPIC_ENV,
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",
)
# ββ Registration ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
register_provider(commandcode)
register_provider(commandcode_anthropic)
|