"""提供商凭据/档位路由的请求/响应 schema(C3 / ARCH §4.7, §7.2)。 snake_case;响应一律 **掩码 Key**,绝不含明文。前端经 OpenAPI 生成 TS 类型消费。 """ from __future__ import annotations from pydantic import BaseModel, Field from ww_llm_gateway.types import Tier class ProviderView(BaseModel): """已配置提供商(掩码视图)。""" provider: str masked_key: str # 形如 sk-…1234;明文永不出现 class TierRoutingView(BaseModel): """档位 → provider:model 路由(含回退链)。""" tier: str provider: str model: str fallback: list[str] = Field(default_factory=list) class ProvidersResponse(BaseModel): """GET/PUT 响应:已配置提供商(掩码)+ 当前档位路由。""" providers: list[ProviderView] = Field(default_factory=list) tier_routing: list[TierRoutingView] = Field(default_factory=list) class ProviderCredentialInput(BaseModel): """单条提供商凭据写入。""" provider: str = Field(min_length=1) api_key: str = Field(min_length=1) # 明文入站,加密入库,绝不回显 class TierRoutingInput(BaseModel): """单条档位路由写入。""" # tier 限定已知档位 writer/analyst/light;未知档位 → 422(QA MEDIUM:原接受任意字符串)。 tier: Tier provider: str = Field(min_length=1) model: str = Field(min_length=1) fallback: list[str] = Field(default_factory=list) class ProvidersUpsertRequest(BaseModel): """PUT 请求:可同时 upsert 若干凭据与档位路由(幂等)。""" credentials: list[ProviderCredentialInput] = Field(default_factory=list) tier_routing: list[TierRoutingInput] = Field(default_factory=list) class TestConnectionRequest(BaseModel): """POST /test:最小探测请求。""" provider: str = Field(min_length=1) class CapabilitiesView(BaseModel): """探测得到的能力矩阵(镜像网关 `Capabilities`)。""" structured_output: bool = False prefix_cache: bool = False thinking: bool = False class TestConnectionResponse(BaseModel): """POST /test 响应:连通性 + 能力矩阵。""" provider: str ok: bool capabilities: CapabilitiesView