ZaiProvider replaces the zai stub. It reaches z.ai's Anthropic-compatible endpoint (default https://api.z.ai/api/anthropic) exactly like Claude Code with ANTHROPIC_BASE_URL pointed at z.ai: a /v1/messages POST with a Bearer key. The key + base URL come from the config the control panel's z.ai field writes (providers.zai.base_url/.api_key) — no OAuth, no local files. Two z.ai-specific cares: (1) static API key, no self-refresh; (2) the GLM Coding Plan meters by prompts, so a 60s poll would drain quota — the provider self-throttles to one network call per poll_interval_s (default 15 min) and serves a cached status in between. Rate-limit parsing assumes z.ai proxies Anthropic's unified headers (5h->s/sr, 7d->w/wr); if a real response lacks them it still reports connected and logs the limit-ish headers it did return, so the mapping can be finalized against a live key. tools/probe_zai.py dumps a real z.ai response's headers (key via env, never printed) to pin the exact header names. Graceful without a key: selecting z.ai shows the blue theme + "no key", never crashes the loop. Registry: all three providers now real; unknown ids fall back to StubProvider. +7 z.ai tests (mocked transport: header mapping, auth, throttle, fallback); 120 passed, 2 Linux-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
31 lines
923 B
Python
31 lines
923 B
Python
"""Provider registry (v3).
|
|
|
|
get_provider(id) returns a Provider instance for the daemon to poll. Anthropic
|
|
is real; OpenAI and z.ai return a StubProvider until M2/M3 land, so selecting
|
|
them never crashes the loop.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from .base import Provider, ProviderStatus, StubProvider
|
|
from .anthropic import AnthropicProvider
|
|
from .openai_codex import OpenAICodexProvider
|
|
from .zai import ZaiProvider
|
|
|
|
|
|
def get_provider(pid: str) -> Provider:
|
|
if pid == "anthropic":
|
|
return AnthropicProvider()
|
|
if pid == "openai":
|
|
return OpenAICodexProvider()
|
|
if pid == "zai":
|
|
return ZaiProvider()
|
|
# Unknown id (a config from a newer version, say) — a safe placeholder.
|
|
return StubProvider(pid, label=pid, accent="d97757")
|
|
|
|
|
|
__all__ = [
|
|
"Provider", "ProviderStatus", "StubProvider",
|
|
"AnthropicProvider", "OpenAICodexProvider", "ZaiProvider", "get_provider",
|
|
]
|