Files
tracer-cloud--opensre/config/llm_auth/provider_catalog.py
T
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

267 lines
8.3 KiB
Python

"""Canonical LLM provider auth and model-selection metadata."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Literal
CredentialKind = Literal["api_key", "cli", "ambient", "local"]
@dataclass(frozen=True)
class ProviderSpec:
"""Provider facts shared by config, auth, wizard, and runtime checks."""
value: str
label: str
credential_kind: CredentialKind
api_key_env: str = ""
model_env: str = ""
legacy_model_env: str | None = None
toolcall_model_env: str | None = None
classification_model_env: str | None = None
cli_model_env: str | None = None
endpoint_env: str = ""
api_version_env: str = ""
allow_custom_models: bool = False
@property
def uses_open_sre_api_key(self) -> bool:
return self.credential_kind == "api_key" and bool(self.api_key_env)
PROVIDER_SPECS: tuple[ProviderSpec, ...] = (
ProviderSpec(
value="anthropic",
label="Anthropic API key",
credential_kind="api_key",
api_key_env="ANTHROPIC_API_KEY",
model_env="ANTHROPIC_REASONING_MODEL",
legacy_model_env="ANTHROPIC_MODEL",
toolcall_model_env="ANTHROPIC_TOOLCALL_MODEL",
classification_model_env="ANTHROPIC_CLASSIFICATION_MODEL",
),
ProviderSpec(
value="openai",
label="OpenAI API key",
credential_kind="api_key",
api_key_env="OPENAI_API_KEY",
model_env="OPENAI_REASONING_MODEL",
legacy_model_env="OPENAI_MODEL",
toolcall_model_env="OPENAI_TOOLCALL_MODEL",
classification_model_env="OPENAI_CLASSIFICATION_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="openrouter",
label="OpenRouter",
credential_kind="api_key",
api_key_env="OPENROUTER_API_KEY",
model_env="OPENROUTER_REASONING_MODEL",
legacy_model_env="OPENROUTER_MODEL",
toolcall_model_env="OPENROUTER_TOOLCALL_MODEL",
classification_model_env="OPENROUTER_CLASSIFICATION_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="deepseek",
label="DeepSeek",
credential_kind="api_key",
api_key_env="DEEPSEEK_API_KEY",
model_env="DEEPSEEK_REASONING_MODEL",
legacy_model_env="DEEPSEEK_MODEL",
toolcall_model_env="DEEPSEEK_TOOLCALL_MODEL",
classification_model_env="DEEPSEEK_CLASSIFICATION_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="gemini",
label="Google Gemini API key",
credential_kind="api_key",
api_key_env="GEMINI_API_KEY",
model_env="GEMINI_REASONING_MODEL",
legacy_model_env="GEMINI_MODEL",
toolcall_model_env="GEMINI_TOOLCALL_MODEL",
classification_model_env="GEMINI_CLASSIFICATION_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="nvidia",
label="NVIDIA NIM",
credential_kind="api_key",
api_key_env="NVIDIA_API_KEY",
model_env="NVIDIA_REASONING_MODEL",
legacy_model_env="NVIDIA_MODEL",
toolcall_model_env="NVIDIA_TOOLCALL_MODEL",
classification_model_env="NVIDIA_CLASSIFICATION_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="minimax",
label="MiniMax",
credential_kind="api_key",
api_key_env="MINIMAX_API_KEY",
model_env="MINIMAX_REASONING_MODEL",
legacy_model_env="MINIMAX_MODEL",
toolcall_model_env="MINIMAX_TOOLCALL_MODEL",
classification_model_env="MINIMAX_CLASSIFICATION_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="groq",
label="Groq API key",
credential_kind="api_key",
api_key_env="GROQ_API_KEY",
model_env="GROQ_REASONING_MODEL",
legacy_model_env="GROQ_MODEL",
toolcall_model_env="GROQ_TOOLCALL_MODEL",
classification_model_env="GROQ_CLASSIFICATION_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="azure-openai",
label="Azure OpenAI",
credential_kind="api_key",
api_key_env="AZURE_OPENAI_API_KEY",
model_env="AZURE_OPENAI_REASONING_MODEL",
legacy_model_env="AZURE_OPENAI_MODEL",
toolcall_model_env="AZURE_OPENAI_TOOLCALL_MODEL",
classification_model_env="AZURE_OPENAI_CLASSIFICATION_MODEL",
endpoint_env="AZURE_OPENAI_BASE_URL",
api_version_env="AZURE_OPENAI_API_VERSION",
allow_custom_models=True,
),
ProviderSpec(
value="bedrock",
label="Amazon Bedrock (IAM auth)",
credential_kind="ambient",
model_env="BEDROCK_REASONING_MODEL",
toolcall_model_env="BEDROCK_TOOLCALL_MODEL",
classification_model_env="BEDROCK_CLASSIFICATION_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="ollama",
label="Ollama (local)",
credential_kind="local",
api_key_env="OLLAMA_HOST",
model_env="OLLAMA_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="codex",
label="OpenAI Codex CLI",
credential_kind="cli",
model_env="CODEX_MODEL",
cli_model_env="CODEX_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="cursor",
label="Cursor Agent CLI",
credential_kind="cli",
model_env="CURSOR_MODEL",
cli_model_env="CURSOR_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="claude-code",
label="Anthropic Claude Code CLI",
credential_kind="cli",
model_env="CLAUDE_CODE_MODEL",
cli_model_env="CLAUDE_CODE_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="gemini-cli",
label="Google Gemini CLI",
credential_kind="cli",
model_env="GEMINI_CLI_MODEL",
cli_model_env="GEMINI_CLI_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="antigravity-cli",
label="Google Antigravity CLI",
credential_kind="cli",
model_env="ANTIGRAVITY_CLI_MODEL",
cli_model_env="ANTIGRAVITY_CLI_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="opencode",
label="OpenCode CLI",
credential_kind="cli",
model_env="OPENCODE_MODEL",
cli_model_env="OPENCODE_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="kimi",
label="Kimi Code CLI",
credential_kind="cli",
model_env="KIMI_MODEL",
cli_model_env="KIMI_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="copilot",
label="GitHub Copilot CLI",
credential_kind="cli",
model_env="COPILOT_MODEL",
cli_model_env="COPILOT_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="grok-cli",
label="xAI Grok Build CLI",
credential_kind="cli",
model_env="GROK_CLI_MODEL",
cli_model_env="GROK_CLI_MODEL",
allow_custom_models=True,
),
ProviderSpec(
value="pi",
label="Pi CLI (pi.dev, BYOK multi-provider)",
credential_kind="cli",
model_env="PI_MODEL",
cli_model_env="PI_MODEL",
allow_custom_models=True,
),
)
PROVIDER_BY_VALUE: dict[str, ProviderSpec] = {spec.value: spec for spec in PROVIDER_SPECS}
SUPPORTED_PROVIDER_VALUES: tuple[str, ...] = tuple(spec.value for spec in PROVIDER_SPECS)
API_KEY_PROVIDER_ENVS: dict[str, str] = {
spec.value: spec.api_key_env for spec in PROVIDER_SPECS if spec.uses_open_sre_api_key
}
KEYLESS_PROVIDER_VALUES: frozenset[str] = frozenset(
spec.value for spec in PROVIDER_SPECS if not spec.uses_open_sre_api_key
)
def provider_spec(provider: str) -> ProviderSpec | None:
"""Return the provider spec for *provider*, if supported."""
return PROVIDER_BY_VALUE.get(provider.strip().lower())
def require_provider_spec(provider: str) -> ProviderSpec:
"""Return the provider spec or raise ``KeyError`` for unsupported providers."""
spec = provider_spec(provider)
if spec is None:
raise KeyError(provider)
return spec
__all__ = [
"API_KEY_PROVIDER_ENVS",
"CredentialKind",
"KEYLESS_PROVIDER_VALUES",
"PROVIDER_BY_VALUE",
"PROVIDER_SPECS",
"ProviderSpec",
"SUPPORTED_PROVIDER_VALUES",
"provider_spec",
"require_provider_spec",
]