import type { PiAuthKind, PiProviderGroup, PiProviderInfo, PiThinkingLevel, PiUpstream } from "@umt/contracts"; import { StatusBadge, type StatusTone } from "~/components/console/status-badge.tsx"; import { Input } from "~/components/ui/input.tsx"; // Agent 上游的界面标签(术语见 docs/design/glossary.md:上游配置叫"Agent 上游") export const GROUP_LABEL: Record = { api_key: "API Key", subscription: "订阅登录", cloud: "云凭证", custom: "兼容端点", test: "测试", }; export const GROUP_ORDER: PiProviderGroup[] = ["api_key", "subscription", "cloud", "custom", "test"]; export const AUTH_LABEL: Record = { api_key: "API Key", oauth: "订阅登录", none: "不需要凭证", }; export const THINKING_LABEL: Record = { off: "关闭", minimal: "最低", low: "低", medium: "中", high: "高", xhigh: "很高", max: "最高", }; export const THINKING_OPTIONS = (Object.keys(THINKING_LABEL) as PiThinkingLevel[]).map((v) => ({ value: v, label: `${THINKING_LABEL[v]}(${v})`, })); export const API_OPTIONS = [ { value: "openai-completions", label: "OpenAI Chat Completions" }, { value: "openai-responses", label: "OpenAI Responses" }, { value: "anthropic-messages", label: "Anthropic Messages" }, { value: "google-generative-ai", label: "Google Generative AI" }, ]; export function upstreamStatus(u: Pick): { label: string; tone: StatusTone; } { if (!u.enabled) return { label: "已停用", tone: "neutral" }; switch (u.status) { case "ok": return { label: "可用", tone: "success" }; case "auth_required": return { label: u.authKind === "oauth" ? "待登录" : "缺 API Key", tone: "warning" }; case "expired": return { label: "登录已失效", tone: "destructive" }; case "error": return { label: "出错", tone: "destructive" }; } } export function UpstreamStatusBadge({ u }: { u: Pick }) { const s = upstreamStatus(u); return {s.label}; } export const providerName = (providers: PiProviderInfo[] | undefined, id: string) => providers?.find((p) => p.id === id)?.name ?? id; /** 模型 id:可从列表挑,也可手填(目录滞后于上游时) */ export function ModelInput({ id, value, onChange, models, disabled, invalid, placeholder, }: { id: string; value: string; onChange: (v: string) => void; models: { id: string; name: string }[]; disabled?: boolean; invalid?: boolean; placeholder?: string; }) { const listId = `${id}-models`; return ( <> onChange(e.target.value)} disabled={disabled} aria-invalid={invalid} autoComplete="off" placeholder={placeholder ?? (models.length ? `从 ${models.length} 个模型中选,或手填 id` : "模型 id")} /> {models.map((m) => ( ))} ); }