aigetwey 1.3.6 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/build-manifest.json +3 -3
- package/dashboard/.next/diagnostics/route-bundle-stats.json +10 -10
- package/dashboard/.next/fallback-build-manifest.json +3 -3
- package/dashboard/.next/server/app/(console)/combos/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/config/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/console/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/endpoint/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/providers/[id]/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/providers/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/quota/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/tools/[id]/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/tools/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/usage/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/_global-error.html +1 -1
- package/dashboard/.next/server/app/_global-error.rsc +1 -1
- package/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/_not-found.html +1 -1
- package/dashboard/.next/server/app/_not-found.rsc +2 -2
- package/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/combos.html +1 -1
- package/dashboard/.next/server/app/combos.rsc +2 -2
- package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp/combos/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp/combos.segment.rsc +1 -1
- package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp.segment.rsc +1 -1
- package/dashboard/.next/server/app/combos.segments/_full.segment.rsc +2 -2
- package/dashboard/.next/server/app/combos.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/combos.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/combos.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/config.html +1 -1
- package/dashboard/.next/server/app/config.rsc +2 -2
- package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp/config/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp/config.segment.rsc +1 -1
- package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp.segment.rsc +1 -1
- package/dashboard/.next/server/app/config.segments/_full.segment.rsc +2 -2
- package/dashboard/.next/server/app/config.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/config.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/config.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/console.html +1 -1
- package/dashboard/.next/server/app/console.rsc +2 -2
- package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp/console/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp/console.segment.rsc +1 -1
- package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp.segment.rsc +1 -1
- package/dashboard/.next/server/app/console.segments/_full.segment.rsc +2 -2
- package/dashboard/.next/server/app/console.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/console.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/console.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/endpoint.html +1 -1
- package/dashboard/.next/server/app/endpoint.rsc +3 -3
- package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp/endpoint/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp/endpoint.segment.rsc +1 -1
- package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp.segment.rsc +1 -1
- package/dashboard/.next/server/app/endpoint.segments/_full.segment.rsc +3 -3
- package/dashboard/.next/server/app/endpoint.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/endpoint.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/endpoint.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/index.html +1 -1
- package/dashboard/.next/server/app/index.rsc +3 -3
- package/dashboard/.next/server/app/index.segments/!KGNvbnNvbGUp/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/server/app/index.segments/!KGNvbnNvbGUp.segment.rsc +1 -1
- package/dashboard/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/login.html +1 -1
- package/dashboard/.next/server/app/login.rsc +2 -2
- package/dashboard/.next/server/app/login.segments/_full.segment.rsc +2 -2
- package/dashboard/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/login.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/dashboard/.next/server/app/providers.html +1 -1
- package/dashboard/.next/server/app/providers.rsc +3 -3
- package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp/providers/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp/providers.segment.rsc +1 -1
- package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp.segment.rsc +1 -1
- package/dashboard/.next/server/app/providers.segments/_full.segment.rsc +3 -3
- package/dashboard/.next/server/app/providers.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/providers.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/providers.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/quota.html +1 -1
- package/dashboard/.next/server/app/quota.rsc +2 -2
- package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp/quota/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp/quota.segment.rsc +1 -1
- package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp.segment.rsc +1 -1
- package/dashboard/.next/server/app/quota.segments/_full.segment.rsc +2 -2
- package/dashboard/.next/server/app/quota.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/quota.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/quota.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/tools.html +1 -1
- package/dashboard/.next/server/app/tools.rsc +2 -2
- package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp/tools/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp/tools.segment.rsc +1 -1
- package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp.segment.rsc +1 -1
- package/dashboard/.next/server/app/tools.segments/_full.segment.rsc +2 -2
- package/dashboard/.next/server/app/tools.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/tools.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/tools.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/chunks/[root-of-the-server]__043un18._.js +1 -1
- package/dashboard/.next/server/chunks/[root-of-the-server]__043un18._.js.map +1 -1
- package/dashboard/.next/server/chunks/_0digmky._.js +1 -1
- package/dashboard/.next/server/chunks/_0digmky._.js.map +1 -1
- package/dashboard/.next/server/chunks/ssr/_1mumvwn._.js +1 -1
- package/dashboard/.next/server/chunks/ssr/_1mumvwn._.js.map +1 -1
- package/dashboard/.next/server/chunks/ssr/src_components_0nuo5yx._.js +1 -1
- package/dashboard/.next/server/chunks/ssr/src_components_0nuo5yx._.js.map +1 -1
- package/dashboard/.next/server/chunks/ssr/src_components_EndpointView_tsx_0awdzb5._.js +1 -1
- package/dashboard/.next/server/chunks/ssr/src_components_EndpointView_tsx_0awdzb5._.js.map +1 -1
- package/dashboard/.next/server/chunks/ssr/src_components_ProviderDetail_tsx_06sxu0r._.js +1 -1
- package/dashboard/.next/server/chunks/ssr/src_components_ProviderDetail_tsx_06sxu0r._.js.map +1 -1
- package/dashboard/.next/server/chunks/ssr/src_components_ToolDetail_tsx_0qperd-._.js +1 -1
- package/dashboard/.next/server/chunks/ssr/src_components_ToolDetail_tsx_0qperd-._.js.map +1 -1
- package/dashboard/.next/server/middleware-build-manifest.js +3 -3
- package/dashboard/.next/server/pages/404.html +1 -1
- package/dashboard/.next/server/pages/500.html +1 -1
- package/dashboard/.next/static/chunks/03o9w8fy3awov.css +3 -0
- package/dashboard/.next/static/chunks/{0_fo_1xhw25rd.js → 063d_vdu_m-g_.js} +1 -1
- package/dashboard/.next/static/chunks/{3i6nr2y3h_7s2.js → 0tq5u12liycmg.js} +1 -1
- package/dashboard/.next/static/chunks/{00415cmd3ji2s.js → 16vbdc0g5xea0.js} +1 -1
- package/dashboard/.next/static/chunks/{05i93ivai9obr.js → 3mhsmb2ks1vev.js} +1 -1
- package/dashboard/.next/trace +1 -1
- package/dashboard/.next/trace-build +1 -1
- package/dashboard/src/components/EndpointView.tsx +13 -7
- package/dashboard/src/components/ProviderDetail.tsx +1 -1
- package/dashboard/src/components/ProviderManager.tsx +1 -1
- package/dashboard/src/components/ToolDetail.tsx +160 -20
- package/dashboard/src/lib/session.ts +6 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/src/cli.ts +1 -1
- package/dashboard/.next/static/chunks/2284qz1hy9776.css +0 -3
- /package/dashboard/.next/static/{kpgVHg6Rdnh2YUO8-xGjX → BHVoneq9_CCAAPwET7GfO}/_buildManifest.js +0 -0
- /package/dashboard/.next/static/{kpgVHg6Rdnh2YUO8-xGjX → BHVoneq9_CCAAPwET7GfO}/_clientMiddlewareManifest.js +0 -0
- /package/dashboard/.next/static/{kpgVHg6Rdnh2YUO8-xGjX → BHVoneq9_CCAAPwET7GfO}/_ssgManifest.js +0 -0
package/dashboard/.next/server/chunks/ssr/src_components_ProviderDetail_tsx_06sxu0r._.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/ProviderDetail.tsx","../../../../src/components/Checkbox.tsx","../../../../src/components/ModelSelectModal.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, useCallback, useRef } from \"react\";\nimport { useRouter } from \"next/navigation\";\nimport { adminApi } from \"@/lib/client\";\nimport { Lamp } from \"@/components/Lamp\";\nimport { Badge, FormatBadge } from \"@/components/Badge\";\nimport { CooldownTimer } from \"@/components/CooldownTimer\";\nimport { RichCard, CardTitle } from \"@/components/RichCard\";\nimport { Button, Input, Field } from \"@/components/Button\";\nimport { Icon } from \"@/components/Icon\";\nimport { fmt, Empty } from \"@/components/ui\";\nimport { ModelSelectModal, type DiscoveredModel } from \"@/components/ModelSelectModal\";\nimport { CapacityBadges } from \"@/components/CapacityBadges\";\nimport { ConfirmModal } from \"@/components/ConfirmModal\";\nimport type { MaskedConfig, MaskedProvider, ProviderSnapshot, PingResult } from \"@/lib/gateway\";\n\nexport function ProviderDetail({ id }: { id: string }) {\n const router = useRouter();\n const [provider, setProvider] = useState<MaskedProvider | null>(null);\n const [health, setHealth] = useState<ProviderSnapshot | null>(null);\n const [error, setError] = useState(\"\");\n const [ping, setPing] = useState<PingResult | null>(null);\n const [busy, setBusy] = useState(\"\");\n const [newKey, setNewKey] = useState(\"\");\n const [newKeyName, setNewKeyName] = useState(\"\");\n const [editIdx, setEditIdx] = useState<number | null>(null);\n const [editName, setEditName] = useState(\"\");\n const [editVal, setEditVal] = useState(\"\");\n const [newModel, setNewModel] = useState(\"\");\n const [modelFilter, setModelFilter] = useState(\"\");\n const [discovered, setDiscovered] = useState<DiscoveredModel[] | null>(null);\n const [modelTest, setModelTest] = useState<Record<string, \"testing\" | \"ok\" | \"fail\">>({});\n const [keyTest, setKeyTest] = useState<Record<number, \"testing\" | PingResult>>({});\n const [testingAll, setTestingAll] = useState(false);\n const [testAllSummary, setTestAllSummary] = useState<{ total: number; passed: number; failed: number } | null>(null);\n const stopTestAll = useRef(false);\n const [editingConn, setEditingConn] = useState(false);\n const [connUrl, setConnUrl] = useState(\"\");\n const [connPrefix, setConnPrefix] = useState(\"\");\n const [revealedKeys, setRevealedKeys] = useState<Record<number, string>>({});\n const [confirmDelete, setConfirmDelete] = useState(false);\n\n async function testModel(mid: string) {\n setModelTest((t) => ({ ...t, [mid]: \"testing\" }));\n const r = await adminApi.testModel(id, mid);\n setModelTest((t) => ({ ...t, [mid]: r.ok && r.data?.ok ? \"ok\" : \"fail\" }));\n }\n\n async function testKey(i: number) {\n setKeyTest((t) => ({ ...t, [i]: \"testing\" }));\n const r = await adminApi.testKey(id, i);\n setKeyTest((t) => ({ ...t, [i]: r.data ?? { ok: false, reachable: false, status: 0, error: r.error } }));\n }\n\n async function testAllKeys(count: number) {\n stopTestAll.current = false;\n setTestingAll(true);\n setTestAllSummary(null);\n setKeyTest({});\n let passed = 0;\n let failed = 0;\n for (let i = 0; i < count; i++) {\n if (stopTestAll.current) break;\n setKeyTest((t) => ({ ...t, [i]: \"testing\" }));\n const r = await adminApi.testKey(id, i);\n const result = r.data ?? { ok: false, reachable: false, status: 0, error: r.error };\n setKeyTest((t) => ({ ...t, [i]: result }));\n if (result.ok) passed++;\n else failed++;\n if (i < count - 1 && !stopTestAll.current) await new Promise((resolve) => setTimeout(resolve, 500));\n }\n setTestingAll(false);\n setTestAllSummary({ total: count, passed, failed });\n }\n\n const reload = useCallback(async () => {\n const [cfgRes, provRes] = await Promise.all([fetch(\"/api/gw/admin/config\"), adminApi.providers()]);\n if (!cfgRes.ok) {\n setError(\"could not reach the gateway\");\n return;\n }\n const cfg = (await cfgRes.json()) as MaskedConfig;\n const p = cfg.providers.find((x) => x.id === id) ?? null;\n if (!p) {\n setError(`provider \"${id}\" not found`);\n return;\n }\n setError(\"\");\n setProvider(p);\n setHealth(provRes.data?.providers.find((x) => x.id === id) ?? null);\n }, [id]);\n\n useEffect(() => {\n void reload();\n }, [reload]);\n\n if (error) return <Empty>{error}</Empty>;\n if (!provider) return <Empty>Loading…</Empty>;\n\n const keys = provider.api_keys ?? (provider.api_key ? [provider.api_key] : []);\n const q = modelFilter.trim().toLowerCase();\n const shownModels = q ? provider.models.filter((m) => m.id.toLowerCase().includes(q)) : provider.models;\n\n async function run(label: string, fn: () => Promise<{ ok: boolean; error?: string }>) {\n setBusy(label);\n const res = await fn();\n setBusy(\"\");\n if (!res.ok) setError(res.error ?? \"action failed\");\n else {\n setError(\"\");\n await reload();\n }\n }\n\n return (\n <div>\n <button onClick={() => router.push(\"/providers\")} className=\"mb-4 inline-flex items-center gap-1 text-[12px] text-text-muted hover:text-text\">\n <Icon name=\"arrow_back\" size={15} /> Providers\n </button>\n\n <div className=\"mb-6 flex items-center gap-3\">\n <Lamp state={provider.disabled ? \"idle\" : (health?.keys.some((k) => k.healthy) ?? true) ? \"live\" : \"down\"} />\n <div>\n <h1 className=\"text-[22px] font-semibold tracking-tight text-text\">{provider.name || provider.id}</h1>\n {provider.name && <span className=\"text-[12px] text-text-subtle\">{provider.id}/</span>}\n </div>\n <FormatBadge format={provider.format} />\n {provider.free && <Badge tone=\"info\">free</Badge>}\n {provider.service_account && <Badge tone=\"info\">service-account</Badge>}\n {/* enable/disable lives on the Providers list (one place); here we just\n flag the state. Disabled = red badge + the content below fades. */}\n {provider.disabled && <Badge tone=\"down\">disabled</Badge>}\n </div>\n\n <div className={`grid gap-4 lg:grid-cols-2 transition-opacity ${provider.disabled ? \"opacity-50\" : \"\"}`}>\n <RichCard header={<CardTitle title=\"Connection\" />}>\n {editingConn ? (\n <div className=\"space-y-3\">\n <Field label=\"Name\" hint=\"the id — also the call prefix (name/model) & combos\">\n <Input value={connPrefix} onChange={(e) => setConnPrefix(e.target.value)} placeholder=\"e.g. huki\" className=\"font-mono text-[12.5px]\" />\n </Field>\n {connPrefix.trim() && connPrefix.trim() !== id && (\n <p className=\"flex items-start gap-1.5 rounded-brand border border-warning/40 bg-warning/8 px-2.5 py-2 text-[11.5px] text-warning\">\n <Icon name=\"warning\" size={14} className=\"mt-0.5 flex-none\" />\n <span>\n Renaming rewrites the call string. CLI tools pointing at{\" \"}\n <code className=\"tnum\">{id}/…</code> will break until repointed; combos that target it are\n updated automatically.\n </span>\n </p>\n )}\n <Field label=\"Base URL\">\n <Input value={connUrl} onChange={(e) => setConnUrl(e.target.value)} placeholder=\"https://...\" className=\"font-mono text-[12.5px]\" />\n </Field>\n <div className=\"flex justify-end gap-2\">\n <Button variant=\"ghost\" onClick={() => setEditingConn(false)}>Cancel</Button>\n <Button disabled={busy === \"editconn\"} onClick={() => run(\"editconn\", async () => {\n // One identifier: Name == id == call prefix. Rename it (cascades to\n // combos, moves this page to the new id) then apply base_url.\n const newId = connPrefix.trim();\n let activeId = id;\n if (newId && newId !== id) {\n const rr = await adminApi.renameProvider(id, newId);\n if (!rr.ok) return rr;\n activeId = newId;\n }\n const r = await adminApi.editProvider(activeId, { base_url: connUrl.trim() || undefined });\n if (r.ok) {\n setEditingConn(false);\n if (activeId !== id) { router.push(`/providers/${encodeURIComponent(activeId)}`); return r; }\n }\n return r;\n })}>Save</Button>\n </div>\n </div>\n ) : (\n <>\n <div className=\"space-y-2 text-[13px]\">\n <Row k=\"Base URL\" v={provider.base_url} />\n <Row k=\"Format\" v={provider.format} />\n <Row k=\"Cooldown base\" v={`${provider.cooldown_base_ms}ms`} />\n <Row k=\"Max retries\" v={String(provider.max_retries)} />\n </div>\n <div className=\"mt-4 flex items-center gap-2\">\n <Button variant=\"ghost\" onClick={() => { setEditingConn(true); setConnUrl(provider.base_url); setConnPrefix(provider.id); }}>\n <Icon name=\"edit\" size={15} /> Edit\n </Button>\n <Button variant=\"ghost\" disabled={busy === \"test\"} onClick={() => run(\"test\", async () => {\n const r = await adminApi.testProvider(id);\n if (r.ok) setPing(r.data);\n return r;\n })}>\n <Icon name=\"wifi_tethering\" size={16} /> {busy === \"test\" ? \"Testing…\" : \"Test connection\"}\n </Button>\n <Button variant=\"ghost\" disabled={busy === \"discover\"} onClick={() => run(\"discover\", async () => {\n const r = await adminApi.discoverModels(id);\n if (r.ok) setDiscovered(r.data?.models ?? []);\n return r;\n })}>\n <Icon name=\"sync\" size={16} /> {busy === \"discover\" ? \"Fetching…\" : \"Fetch models\"}\n </Button>\n </div>\n {ping && (\n <div className=\"mt-3 text-[12px]\">\n <Badge tone={ping.ok ? \"live\" : ping.reachable ? \"warn\" : \"down\"}>\n {ping.ok ? `ok (${ping.status})` : ping.reachable ? `reachable (${ping.status})` : \"unreachable\"}\n </Badge>\n {ping.error && <span className=\"ml-2 text-text-subtle\">{ping.error}</span>}\n </div>\n )}\n </>\n )}\n </RichCard>\n\n <RichCard\n header={\n <>\n <CardTitle title=\"Keys\" sub={`${keys.length} configured`} />\n <div className=\"flex flex-wrap items-center gap-3\">\n {keys.length > 1 && (\n <Button variant=\"ghost\" disabled={testingAll} onClick={() => testAllKeys(keys.length)}>\n <Icon name={testingAll ? \"progress_activity\" : \"sync\"} size={15} />\n {testingAll ? \"Testing…\" : \"Test All\"}\n </Button>\n )}\n {testingAll && (\n <Button variant=\"ghost\" onClick={() => { stopTestAll.current = true; }}>\n <Icon name=\"stop\" size={15} /> Stop\n </Button>\n )}\n <span className=\"text-[11px] text-text-subtle\">Round Robin</span>\n <button\n onClick={() => {\n const next = provider.strategy === \"round-robin\" ? null : \"round-robin\";\n void adminApi.setProviderStrategy(id, next as \"round-robin\" | null, provider.sticky ?? 1).then(() => reload());\n }}\n className={`relative h-5 w-9 rounded-full transition-colors ${provider.strategy === \"round-robin\" ? \"bg-accent\" : \"bg-border-subtle\"}`}\n aria-label=\"Toggle round-robin\"\n >\n <span className={`absolute left-0.5 top-0.5 h-4 w-4 rounded-full bg-white transition-transform ${provider.strategy === \"round-robin\" ? \"translate-x-[18px]\" : \"translate-x-0\"}`} />\n </button>\n {provider.strategy === \"round-robin\" && (\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-[11px] text-text-subtle\">Sticky:</span>\n <div className=\"flex items-center rounded-brand border border-border-subtle\">\n <button\n type=\"button\"\n disabled={(provider.sticky ?? 1) <= 1}\n onClick={() => void adminApi.setProviderStrategy(id, \"round-robin\", Math.max(1, (provider.sticky ?? 1) - 1)).then(() => reload())}\n className=\"px-1.5 py-0.5 text-text-subtle transition-colors hover:text-text disabled:opacity-30\"\n aria-label=\"Decrease sticky\"\n >\n <Icon name=\"remove\" size={13} />\n </button>\n <span className=\"tnum w-6 text-center text-[11px] text-text\">{provider.sticky ?? 1}</span>\n <button\n type=\"button\"\n onClick={() => void adminApi.setProviderStrategy(id, \"round-robin\", (provider.sticky ?? 1) + 1).then(() => reload())}\n className=\"px-1.5 py-0.5 text-text-subtle transition-colors hover:text-text\"\n aria-label=\"Increase sticky\"\n >\n <Icon name=\"add\" size={13} />\n </button>\n </div>\n </div>\n )}\n </div>\n </>\n }\n >\n {testAllSummary && (\n <div className=\"mb-3 flex items-center gap-2 text-[11.5px]\">\n <Badge tone={testAllSummary.failed === 0 ? \"live\" : \"warn\"}>\n {testAllSummary.total} tested: {testAllSummary.passed} valid, {testAllSummary.failed} failed\n </Badge>\n </div>\n )}\n {keys.length === 0 ? (\n <Empty>No keys (free / service-account provider).</Empty>\n ) : (\n <div className=\"space-y-1.5\">\n {keys.map((k, i) => {\n const ks = health?.keys[i];\n const test = keyTest[i];\n const tested = test && test !== \"testing\" ? test : null;\n const lamp = tested ? (tested.ok ? \"live\" : tested.reachable ? \"idle\" : \"down\") : ks ? (ks.healthy ? \"live\" : \"down\") : \"idle\";\n const name = provider.key_names?.[k];\n const disabled = provider.disabled_keys?.includes(i) ?? false;\n if (editIdx === i) {\n return (\n <div key={i} className=\"space-y-2 rounded-brand border border-accent bg-accent-soft/40 px-3 py-2.5\">\n <Input value={editName} onChange={(e) => setEditName(e.target.value)} placeholder=\"key name (optional)\" />\n <Input value={editVal} onChange={(e) => setEditVal(e.target.value)} placeholder=\"new key value (leave blank to keep)\" className=\"font-mono text-[12.5px]\" />\n <div className=\"flex justify-end gap-2\">\n <Button variant=\"ghost\" onClick={() => setEditIdx(null)}>Cancel</Button>\n <Button disabled={busy === `editkey${i}`} onClick={() => run(`editkey${i}`, async () => {\n const r = await adminApi.editKey(id, i, { name: editName, key: editVal.trim() || undefined });\n if (r.ok) setEditIdx(null);\n return r;\n })}>Save</Button>\n </div>\n </div>\n );\n }\n return (\n <div key={i} className={`rounded-brand border border-border-subtle px-3 py-2${disabled ? \" opacity-60\" : \"\"}`}>\n <div className=\"flex items-center gap-2\">\n {/* reorder */}\n <div className=\"flex flex-col\">\n <button\n onClick={() => run(`reorder${i}up`, () => adminApi.reorderKey(id, i, i - 1))}\n disabled={i === 0}\n className=\"p-0.5 text-text-subtle hover:text-text disabled:opacity-30\"\n aria-label=\"Move up\"\n >\n <Icon name=\"keyboard_arrow_up\" size={14} />\n </button>\n <button\n onClick={() => run(`reorder${i}dn`, () => adminApi.reorderKey(id, i, i + 1))}\n disabled={i === keys.length - 1}\n className=\"p-0.5 text-text-subtle hover:text-text disabled:opacity-30\"\n aria-label=\"Move down\"\n >\n <Icon name=\"keyboard_arrow_down\" size={14} />\n </button>\n </div>\n <Lamp state={lamp} />\n <div className=\"min-w-0 flex-1\">\n {name && <div className=\"text-[12px] font-semibold text-text-muted\">{name}</div>}\n <span className=\"block truncate font-mono text-[12.5px] text-text\">{revealedKeys[i] ?? k}</span>\n </div>\n {revealedKeys[i] && (\n <button\n onClick={() => { void navigator.clipboard.writeText(revealedKeys[i]!); }}\n className=\"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text\"\n aria-label=\"Copy key\"\n title=\"Copy to clipboard\"\n >\n <Icon name=\"content_copy\" size={14} />\n </button>\n )}\n {ks && ks.cooldown_ms > 0 && <CooldownTimer ms={ks.cooldown_ms} />}\n {/* actions: reveal > toggle > test > edit > delete */}\n <button\n onClick={async () => {\n if (revealedKeys[i]) { setRevealedKeys((r) => { const n = { ...r }; delete n[i]; return n; }); return; }\n const r = await adminApi.revealKey(id, i);\n if (r.ok && r.data?.key) setRevealedKeys((prev) => ({ ...prev, [i]: r.data!.key }));\n }}\n className=\"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text\"\n aria-label={revealedKeys[i] ? \"Hide key\" : \"Show key\"}\n title={revealedKeys[i] ? \"Hide key\" : \"Show key\"}\n >\n <Icon name={revealedKeys[i] ? \"visibility_off\" : \"visibility\"} size={15} />\n </button>\n <button\n onClick={() => run(`toggle${i}`, () => adminApi.toggleKey(id, i, disabled))}\n className=\"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text\"\n aria-label={disabled ? \"Enable key\" : \"Disable key\"}\n title={disabled ? \"Enable this key\" : \"Disable this key\"}\n >\n <Icon name={disabled ? \"toggle_off\" : \"toggle_on\"} size={20} className={disabled ? \"text-text-subtle\" : \"text-success\"} />\n </button>\n <button\n onClick={() => testKey(i)}\n disabled={test === \"testing\"}\n className=\"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text disabled:opacity-60\"\n aria-label={`Check key ${i + 1}`}\n title=\"Check this key against the base URL\"\n >\n <Icon name={test === \"testing\" ? \"progress_activity\" : \"wifi_tethering\"} size={15} />\n </button>\n <button\n onClick={() => { setEditIdx(i); setEditName(name ?? \"\"); setEditVal(\"\"); }}\n className=\"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text\"\n aria-label={`Edit key ${i + 1}`}\n title=\"Rename or replace this key\"\n >\n <Icon name=\"edit\" size={15} />\n </button>\n <button\n onClick={() => run(`rmkey${i}`, () => adminApi.removeKey(id, i))}\n className=\"flex-none rounded p-1 text-text-subtle transition-colors hover:text-danger\"\n aria-label=\"Remove key\"\n >\n <Icon name=\"delete\" size={15} />\n </button>\n </div>\n {tested && (\n <div className=\"mt-1.5 flex items-center gap-2 pl-8 text-[11.5px]\">\n <Badge tone={tested.ok ? \"live\" : tested.reachable ? \"warn\" : \"down\"}>\n {tested.ok ? \"valid\" : tested.reachable ? `reachable (${tested.status})` : \"invalid\"}\n </Badge>\n {tested.error && <span className=\"truncate text-danger\">{tested.error}</span>}\n </div>\n )}\n {!tested && ks?.last_error && (\n <div className=\"mt-1.5 flex items-center gap-2 pl-8 text-[11.5px]\">\n <span className=\"text-danger\">{ks.last_error.status ? `${ks.last_error.status}: ` : \"\"}{ks.last_error.message}</span>\n <span className=\"text-text-subtle\">{new Date(ks.last_error.at).toLocaleTimeString()}</span>\n </div>\n )}\n </div>\n );\n })}\n </div>\n )}\n <div className=\"mt-3 space-y-2\">\n <Input value={newKeyName} onChange={(e) => setNewKeyName(e.target.value)} placeholder=\"key name (optional, e.g. primary)\" />\n <div className=\"flex gap-2\">\n <Input value={newKey} onChange={(e) => setNewKey(e.target.value)} placeholder=\"add a key…\" className=\"font-mono text-[12.5px]\" />\n <Button disabled={!newKey || busy === \"addkey\"} onClick={() => run(\"addkey\", async () => {\n const r = await adminApi.addKey(id, newKey, newKeyName.trim() || undefined);\n if (r.ok) { setNewKey(\"\"); setNewKeyName(\"\"); }\n return r;\n })}>Add</Button>\n </div>\n </div>\n </RichCard>\n\n <RichCard\n className=\"lg:col-span-2\"\n header={\n <>\n <CardTitle title=\"Models served\" sub={`${provider.models.length} in catalog`} />\n {provider.models.length > 0 && (\n <button\n onClick={() => run(\"clear\", () => adminApi.clearModels(id))}\n disabled={busy === \"clear\"}\n className=\"text-[12px] text-text-subtle hover:text-danger\"\n >\n Clear all\n </button>\n )}\n </>\n }\n >\n {provider.models.length === 0 ? (\n <Empty>No models. Add one below, or fetch them for a free/auto provider.</Empty>\n ) : (\n <>\n <p className=\"mb-2.5 text-[12px] text-text-subtle\">\n Call any of these as <span className=\"tnum text-text-muted\">{provider.id}/<model></span>, as a combo alias, or by the bare id.\n </p>\n {/* filter only earns its space once the catalog is long enough to scroll */}\n {provider.models.length > 8 && (\n <div className=\"mb-2.5 flex items-center gap-2\">\n <div className=\"relative flex-1\">\n <Icon name=\"search\" size={15} className=\"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-text-subtle\" />\n <Input value={modelFilter} onChange={(e) => setModelFilter(e.target.value)} placeholder=\"filter models…\" className=\"pl-8\" />\n </div>\n <span className=\"tnum whitespace-nowrap text-[12px] text-text-subtle\">\n {q ? `${shownModels.length} of ${provider.models.length}` : `${provider.models.length}`}\n </span>\n </div>\n )}\n {shownModels.length === 0 ? (\n <Empty>No model matches “{modelFilter}”.</Empty>\n ) : (\n <div className=\"max-h-[360px] divide-y divide-border-subtle overflow-y-auto rounded-brand border border-border-subtle\">\n {shownModels.map((m) => {\n const st = modelTest[m.id];\n const statusIcon = st === \"ok\" ? \"check_circle\" : st === \"fail\" ? \"cancel\" : \"smart_toy\";\n const statusColor = st === \"ok\" ? \"text-success\" : st === \"fail\" ? \"text-danger\" : \"text-text-subtle\";\n return (\n <div key={m.id} className=\"group flex items-center justify-between gap-3 px-3 py-2 hover:bg-bg\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <Icon name={statusIcon} size={15} className={`flex-none ${statusColor}`} />\n {/* the prefix (= provider id) is what makes the call string; show it aigetwey-style */}\n <span className=\"tnum truncate text-[12.5px]\">\n <span className=\"text-text-subtle\">{provider.id}/</span>\n <span className=\"text-text\">{m.id}</span>\n </span>\n <CapacityBadges model={m.id} provider={provider.id} />\n {(m.price_in !== undefined || m.price_out !== undefined) && (\n <span className=\"tnum whitespace-nowrap text-[11px] text-text-subtle\">\n {fmt.cost(m.price_in ?? 0)}/{fmt.cost(m.price_out ?? 0)} per 1M\n </span>\n )}\n </div>\n <div className=\"flex flex-none items-center gap-0.5\">\n <button\n onClick={() => testModel(m.id)}\n disabled={st === \"testing\"}\n className=\"rounded p-1 text-text-subtle transition-colors hover:bg-surface hover:text-accent disabled:opacity-60\"\n aria-label={`Test ${m.id}`}\n title={st === \"fail\" ? \"Test failed — click to retry\" : \"Test this model\"}\n >\n <Icon name={st === \"testing\" ? \"progress_activity\" : \"science\"} size={15} />\n </button>\n <button\n onClick={() => run(`rmmodel${m.id}`, () => adminApi.removeModel(id, m.id))}\n disabled={busy === `rmmodel${m.id}`}\n className=\"rounded p-1 text-text-subtle transition-colors hover:bg-surface hover:text-danger disabled:opacity-40\"\n aria-label={`Remove ${m.id}`}\n >\n <Icon name=\"delete\" size={16} />\n </button>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </>\n )}\n <div className=\"mt-3 flex gap-2\">\n <Input value={newModel} onChange={(e) => setNewModel(e.target.value)} placeholder=\"add a model id…\" />\n <Button disabled={!newModel || busy === \"addmodel\"} onClick={() => run(\"addmodel\", async () => {\n const r = await adminApi.addModel(id, newModel);\n if (r.ok) setNewModel(\"\");\n return r;\n })}>Add</Button>\n </div>\n </RichCard>\n </div>\n\n {discovered && (\n <ModelSelectModal\n models={discovered}\n busy={busy === \"addmodels\"}\n onClose={() => setDiscovered(null)}\n onAdd={(ids) => run(\"addmodels\", async () => {\n const r = await adminApi.addModels(id, ids);\n if (r.ok) setDiscovered(null);\n return r;\n })}\n />\n )}\n\n <div className=\"mt-6\">\n <Button variant=\"danger\" onClick={() => setConfirmDelete(true)}>\n <Icon name=\"delete\" size={16} /> Remove provider\n </Button>\n </div>\n\n {confirmDelete && (\n <ConfirmModal\n title=\"Remove provider\"\n message={`Delete \"${provider.name ?? id}\"? All keys and model associations will be lost.`}\n confirmLabel=\"Remove\"\n busy={busy === \"rmprov\"}\n onCancel={() => setConfirmDelete(false)}\n onConfirm={() => run(\"rmprov\", async () => {\n const r = await adminApi.removeProvider(id);\n if (r.ok) router.push(\"/providers\");\n else setConfirmDelete(false);\n return r;\n })}\n />\n )}\n </div>\n );\n}\n\nfunction Row({ k, v }: { k: string; v: string }) {\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-text-subtle\">{k}</span>\n <span className=\"truncate text-text\">{v}</span>\n </div>\n );\n}\n","import { Icon } from \"./Icon\";\n\n/**\n * Themed checkbox. Native checkboxes look out of place on the dark Haulix\n * surface, so this is a button styled to match: filled with the accent + a\n * check glyph when on, a bordered box when off. `indeterminate` renders a dash\n * for \"some selected\" (drives the select-all row).\n */\nexport function Checkbox({\n checked,\n indeterminate,\n onChange,\n className,\n ariaLabel,\n}: {\n checked: boolean;\n indeterminate?: boolean;\n onChange: () => void;\n className?: string;\n ariaLabel?: string;\n}) {\n const on = checked || indeterminate;\n return (\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={indeterminate ? \"mixed\" : checked}\n aria-label={ariaLabel}\n onClick={(e) => {\n e.stopPropagation();\n onChange();\n }}\n className={`flex h-[18px] w-[18px] flex-none items-center justify-center rounded-[5px] border transition-colors ${\n on ? \"border-accent bg-accent text-accent-ink\" : \"border-border bg-bg text-transparent hover:border-text-subtle\"\n }${className ? ` ${className}` : \"\"}`}\n >\n <Icon name={indeterminate ? \"remove\" : \"check\"} size={13} />\n </button>\n );\n}\n","\"use client\";\n\nimport { useState, useMemo } from \"react\";\nimport { Button, Input } from \"@/components/Button\";\nimport { Checkbox } from \"@/components/Checkbox\";\nimport { Icon } from \"@/components/Icon\";\n\nexport interface DiscoveredModel {\n id: string;\n added: boolean; // already in the provider catalog\n}\n\n/**\n * Pick which discovered models to add. Free providers can return hundreds of\n * ids, so this is a filterable checklist (defaulting to only the not-yet-added\n * ones selected) rather than dumping everything into the catalog.\n */\nexport function ModelSelectModal({\n models,\n busy,\n onAdd,\n onClose,\n}: {\n models: DiscoveredModel[];\n busy: boolean;\n onAdd: (ids: string[]) => void;\n onClose: () => void;\n}) {\n const [filter, setFilter] = useState(\"\");\n const [picked, setPicked] = useState<Set<string>>(() => new Set(models.filter((m) => !m.added).map((m) => m.id)));\n\n const shown = useMemo(() => {\n const q = filter.trim().toLowerCase();\n return q ? models.filter((m) => m.id.toLowerCase().includes(q)) : models;\n }, [models, filter]);\n\n function toggle(id: string) {\n setPicked((s) => {\n const next = new Set(s);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }\n\n const shownPickedCount = shown.filter((m) => picked.has(m.id)).length;\n const allShownPicked = shown.length > 0 && shownPickedCount === shown.length;\n const someShownPicked = shownPickedCount > 0 && !allShownPicked;\n function toggleAllShown() {\n setPicked((s) => {\n const next = new Set(s);\n if (allShownPicked) shown.forEach((m) => next.delete(m.id));\n else shown.forEach((m) => next.add(m.id));\n return next;\n });\n }\n\n return (\n <div className=\"fixed inset-0 z-50 grid place-items-center bg-black/50 p-6\" onClick={onClose}>\n <div\n className=\"flex max-h-[80vh] w-full max-w-[480px] flex-col overflow-hidden rounded-brand-lg border border-border bg-surface shadow-elevated\"\n onClick={(e) => e.stopPropagation()}\n >\n <header className=\"flex items-center justify-between border-b border-border-subtle px-4 py-3\">\n <span className=\"text-[14px] font-semibold text-text\">{models.length} models found</span>\n <button onClick={onClose} className=\"text-text-subtle hover:text-text\" aria-label=\"Close\">\n <Icon name=\"close\" size={18} />\n </button>\n </header>\n\n <div className=\"border-b border-border-subtle px-4 py-2.5\">\n <Input value={filter} onChange={(e) => setFilter(e.target.value)} placeholder=\"filter…\" autoFocus />\n </div>\n\n {/* select-all row: an obvious clickable control, not an ambiguous button */}\n {shown.length > 0 && (\n <button\n onClick={toggleAllShown}\n className=\"flex items-center gap-2.5 border-b border-border-subtle px-4 py-2 text-left hover:bg-surface-2\"\n >\n <Checkbox checked={allShownPicked} indeterminate={someShownPicked} onChange={toggleAllShown} ariaLabel=\"Select all\" />\n <span className=\"text-[12.5px] font-medium text-text\">Select all{filter ? \" (filtered)\" : \"\"}</span>\n <span className=\"ml-auto tnum text-[11px] text-text-subtle\">\n {shownPickedCount}/{shown.length}\n </span>\n </button>\n )}\n\n <div className=\"flex-1 overflow-y-auto px-2 py-2\">\n {shown.length === 0 ? (\n <div className=\"px-2 py-6 text-center text-[13px] text-text-muted\">No matches.</div>\n ) : (\n shown.map((m) => {\n const sel = picked.has(m.id);\n return (\n <button\n key={m.id}\n onClick={() => toggle(m.id)}\n className={`flex w-full items-center gap-2.5 rounded-brand border px-2.5 py-2 text-left transition-colors ${\n sel ? \"border-accent/40 bg-accent-soft\" : \"border-transparent hover:bg-surface-2\"\n }`}\n >\n <Checkbox checked={sel} onChange={() => toggle(m.id)} ariaLabel={m.id} />\n <span className=\"flex-1 truncate text-[12.5px] text-text\">{m.id}</span>\n {m.added && <span className=\"text-[11px] text-text-subtle\">in catalog</span>}\n </button>\n );\n })\n )}\n </div>\n\n <footer className=\"flex items-center justify-between gap-3 border-t border-border-subtle bg-bg-alt px-4 py-2.5\">\n <span className=\"tnum text-[12px] text-text-muted\">{picked.size} selected</span>\n <div className=\"flex gap-2\">\n <Button variant=\"ghost\" onClick={onClose}>\n Cancel\n </Button>\n <Button disabled={picked.size === 0 || busy} onClick={() => onAdd([...picked])}>\n {busy ? \"Adding…\" : `Add ${picked.size}`}\n </Button>\n </div>\n </footer>\n </div>\n </div>\n );\n}\n"],"names":["Checkbox","checked","indeterminate","onChange","className","ariaLabel","on","type","role","onClick","e","stopPropagation","name","size"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/ProviderDetail.tsx","../../../../src/components/Checkbox.tsx","../../../../src/components/ModelSelectModal.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, useCallback, useRef } from \"react\";\nimport { useRouter } from \"next/navigation\";\nimport { adminApi } from \"@/lib/client\";\nimport { Lamp } from \"@/components/Lamp\";\nimport { Badge, FormatBadge } from \"@/components/Badge\";\nimport { CooldownTimer } from \"@/components/CooldownTimer\";\nimport { RichCard, CardTitle } from \"@/components/RichCard\";\nimport { Button, Input, Field } from \"@/components/Button\";\nimport { Icon } from \"@/components/Icon\";\nimport { fmt, Empty } from \"@/components/ui\";\nimport { ModelSelectModal, type DiscoveredModel } from \"@/components/ModelSelectModal\";\nimport { CapacityBadges } from \"@/components/CapacityBadges\";\nimport { ConfirmModal } from \"@/components/ConfirmModal\";\nimport type { MaskedConfig, MaskedProvider, ProviderSnapshot, PingResult } from \"@/lib/gateway\";\n\nexport function ProviderDetail({ id }: { id: string }) {\n const router = useRouter();\n const [provider, setProvider] = useState<MaskedProvider | null>(null);\n const [health, setHealth] = useState<ProviderSnapshot | null>(null);\n const [error, setError] = useState(\"\");\n const [ping, setPing] = useState<PingResult | null>(null);\n const [busy, setBusy] = useState(\"\");\n const [newKey, setNewKey] = useState(\"\");\n const [newKeyName, setNewKeyName] = useState(\"\");\n const [editIdx, setEditIdx] = useState<number | null>(null);\n const [editName, setEditName] = useState(\"\");\n const [editVal, setEditVal] = useState(\"\");\n const [newModel, setNewModel] = useState(\"\");\n const [modelFilter, setModelFilter] = useState(\"\");\n const [discovered, setDiscovered] = useState<DiscoveredModel[] | null>(null);\n const [modelTest, setModelTest] = useState<Record<string, \"testing\" | \"ok\" | \"fail\">>({});\n const [keyTest, setKeyTest] = useState<Record<number, \"testing\" | PingResult>>({});\n const [testingAll, setTestingAll] = useState(false);\n const [testAllSummary, setTestAllSummary] = useState<{ total: number; passed: number; failed: number } | null>(null);\n const stopTestAll = useRef(false);\n const [editingConn, setEditingConn] = useState(false);\n const [connUrl, setConnUrl] = useState(\"\");\n const [connPrefix, setConnPrefix] = useState(\"\");\n const [revealedKeys, setRevealedKeys] = useState<Record<number, string>>({});\n const [confirmDelete, setConfirmDelete] = useState(false);\n\n async function testModel(mid: string) {\n setModelTest((t) => ({ ...t, [mid]: \"testing\" }));\n const r = await adminApi.testModel(id, mid);\n setModelTest((t) => ({ ...t, [mid]: r.ok && r.data?.ok ? \"ok\" : \"fail\" }));\n }\n\n async function testKey(i: number) {\n setKeyTest((t) => ({ ...t, [i]: \"testing\" }));\n const r = await adminApi.testKey(id, i);\n setKeyTest((t) => ({ ...t, [i]: r.data ?? { ok: false, reachable: false, status: 0, error: r.error } }));\n }\n\n async function testAllKeys(count: number) {\n stopTestAll.current = false;\n setTestingAll(true);\n setTestAllSummary(null);\n setKeyTest({});\n let passed = 0;\n let failed = 0;\n for (let i = 0; i < count; i++) {\n if (stopTestAll.current) break;\n setKeyTest((t) => ({ ...t, [i]: \"testing\" }));\n const r = await adminApi.testKey(id, i);\n const result = r.data ?? { ok: false, reachable: false, status: 0, error: r.error };\n setKeyTest((t) => ({ ...t, [i]: result }));\n if (result.ok) passed++;\n else failed++;\n if (i < count - 1 && !stopTestAll.current) await new Promise((resolve) => setTimeout(resolve, 500));\n }\n setTestingAll(false);\n setTestAllSummary({ total: count, passed, failed });\n }\n\n const reload = useCallback(async () => {\n const [cfgRes, provRes] = await Promise.all([fetch(\"/api/gw/admin/config\"), adminApi.providers()]);\n if (!cfgRes.ok) {\n setError(\"could not reach the gateway\");\n return;\n }\n const cfg = (await cfgRes.json()) as MaskedConfig;\n const p = cfg.providers.find((x) => x.id === id) ?? null;\n if (!p) {\n setError(`provider \"${id}\" not found`);\n return;\n }\n setError(\"\");\n setProvider(p);\n setHealth(provRes.data?.providers.find((x) => x.id === id) ?? null);\n }, [id]);\n\n useEffect(() => {\n void reload();\n }, [reload]);\n\n if (error) return <Empty>{error}</Empty>;\n if (!provider) return <Empty>Loading…</Empty>;\n\n const keys = provider.api_keys ?? (provider.api_key ? [provider.api_key] : []);\n const q = modelFilter.trim().toLowerCase();\n const shownModels = q ? provider.models.filter((m) => m.id.toLowerCase().includes(q)) : provider.models;\n\n async function run(label: string, fn: () => Promise<{ ok: boolean; error?: string }>) {\n setBusy(label);\n const res = await fn();\n setBusy(\"\");\n if (!res.ok) setError(res.error ?? \"action failed\");\n else {\n setError(\"\");\n await reload();\n }\n }\n\n return (\n <div>\n <button onClick={() => router.push(\"/providers\")} className=\"mb-4 inline-flex items-center gap-1 text-[12px] text-text-muted hover:text-text\">\n <Icon name=\"arrow_back\" size={15} /> Providers\n </button>\n\n <div className=\"mb-6 flex items-center gap-3\">\n <Lamp state={provider.disabled ? \"idle\" : (health?.keys.some((k) => k.healthy) ?? true) ? \"live\" : \"down\"} />\n <div>\n <h1 className=\"text-[22px] font-semibold tracking-tight text-text\">{provider.name || provider.id}</h1>\n {provider.name && <span className=\"text-[12px] text-text-subtle\">{provider.id}/</span>}\n </div>\n <FormatBadge format={provider.format} />\n {provider.free && <Badge tone=\"info\">free</Badge>}\n {provider.service_account && <Badge tone=\"info\">service-account</Badge>}\n {/* enable/disable lives on the Providers list (one place); here we just\n flag the state. Disabled = red badge + the content below fades. */}\n {provider.disabled && <Badge tone=\"down\">disabled</Badge>}\n </div>\n\n <div className={`grid gap-4 lg:grid-cols-2 transition-opacity ${provider.disabled ? \"opacity-50\" : \"\"}`}>\n <RichCard header={<CardTitle title=\"Connection\" />}>\n {editingConn ? (\n <div className=\"space-y-3\">\n <Field label=\"Name\" hint=\"the id — also the call prefix (name/model) & combos\">\n <Input value={connPrefix} onChange={(e) => setConnPrefix(e.target.value)} placeholder=\"e.g. openai\" className=\"font-mono text-[12.5px]\" />\n </Field>\n {connPrefix.trim() && connPrefix.trim() !== id && (\n <p className=\"flex items-start gap-1.5 rounded-brand border border-warning/40 bg-warning/8 px-2.5 py-2 text-[11.5px] text-warning\">\n <Icon name=\"warning\" size={14} className=\"mt-0.5 flex-none\" />\n <span>\n Renaming rewrites the call string. CLI tools pointing at{\" \"}\n <code className=\"tnum\">{id}/…</code> will break until repointed; combos that target it are\n updated automatically.\n </span>\n </p>\n )}\n <Field label=\"Base URL\">\n <Input value={connUrl} onChange={(e) => setConnUrl(e.target.value)} placeholder=\"https://...\" className=\"font-mono text-[12.5px]\" />\n </Field>\n <div className=\"flex justify-end gap-2\">\n <Button variant=\"ghost\" onClick={() => setEditingConn(false)}>Cancel</Button>\n <Button disabled={busy === \"editconn\"} onClick={() => run(\"editconn\", async () => {\n // One identifier: Name == id == call prefix. Rename it (cascades to\n // combos, moves this page to the new id) then apply base_url.\n const newId = connPrefix.trim();\n let activeId = id;\n if (newId && newId !== id) {\n const rr = await adminApi.renameProvider(id, newId);\n if (!rr.ok) return rr;\n activeId = newId;\n }\n const r = await adminApi.editProvider(activeId, { base_url: connUrl.trim() || undefined });\n if (r.ok) {\n setEditingConn(false);\n if (activeId !== id) { router.push(`/providers/${encodeURIComponent(activeId)}`); return r; }\n }\n return r;\n })}>Save</Button>\n </div>\n </div>\n ) : (\n <>\n <div className=\"space-y-2 text-[13px]\">\n <Row k=\"Base URL\" v={provider.base_url} />\n <Row k=\"Format\" v={provider.format} />\n <Row k=\"Cooldown base\" v={`${provider.cooldown_base_ms}ms`} />\n <Row k=\"Max retries\" v={String(provider.max_retries)} />\n </div>\n <div className=\"mt-4 flex items-center gap-2\">\n <Button variant=\"ghost\" onClick={() => { setEditingConn(true); setConnUrl(provider.base_url); setConnPrefix(provider.id); }}>\n <Icon name=\"edit\" size={15} /> Edit\n </Button>\n <Button variant=\"ghost\" disabled={busy === \"test\"} onClick={() => run(\"test\", async () => {\n const r = await adminApi.testProvider(id);\n if (r.ok) setPing(r.data);\n return r;\n })}>\n <Icon name=\"wifi_tethering\" size={16} /> {busy === \"test\" ? \"Testing…\" : \"Test connection\"}\n </Button>\n <Button variant=\"ghost\" disabled={busy === \"discover\"} onClick={() => run(\"discover\", async () => {\n const r = await adminApi.discoverModels(id);\n if (r.ok) setDiscovered(r.data?.models ?? []);\n return r;\n })}>\n <Icon name=\"sync\" size={16} /> {busy === \"discover\" ? \"Fetching…\" : \"Fetch models\"}\n </Button>\n </div>\n {ping && (\n <div className=\"mt-3 text-[12px]\">\n <Badge tone={ping.ok ? \"live\" : ping.reachable ? \"warn\" : \"down\"}>\n {ping.ok ? `ok (${ping.status})` : ping.reachable ? `reachable (${ping.status})` : \"unreachable\"}\n </Badge>\n {ping.error && <span className=\"ml-2 text-text-subtle\">{ping.error}</span>}\n </div>\n )}\n </>\n )}\n </RichCard>\n\n <RichCard\n header={\n <>\n <CardTitle title=\"Keys\" sub={`${keys.length} configured`} />\n <div className=\"flex flex-wrap items-center gap-3\">\n {keys.length > 1 && (\n <Button variant=\"ghost\" disabled={testingAll} onClick={() => testAllKeys(keys.length)}>\n <Icon name={testingAll ? \"progress_activity\" : \"sync\"} size={15} />\n {testingAll ? \"Testing…\" : \"Test All\"}\n </Button>\n )}\n {testingAll && (\n <Button variant=\"ghost\" onClick={() => { stopTestAll.current = true; }}>\n <Icon name=\"stop\" size={15} /> Stop\n </Button>\n )}\n <span className=\"text-[11px] text-text-subtle\">Round Robin</span>\n <button\n onClick={() => {\n const next = provider.strategy === \"round-robin\" ? null : \"round-robin\";\n void adminApi.setProviderStrategy(id, next as \"round-robin\" | null, provider.sticky ?? 1).then(() => reload());\n }}\n className={`relative h-5 w-9 rounded-full transition-colors ${provider.strategy === \"round-robin\" ? \"bg-accent\" : \"bg-border-subtle\"}`}\n aria-label=\"Toggle round-robin\"\n >\n <span className={`absolute left-0.5 top-0.5 h-4 w-4 rounded-full bg-white transition-transform ${provider.strategy === \"round-robin\" ? \"translate-x-[18px]\" : \"translate-x-0\"}`} />\n </button>\n {provider.strategy === \"round-robin\" && (\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-[11px] text-text-subtle\">Sticky:</span>\n <div className=\"flex items-center rounded-brand border border-border-subtle\">\n <button\n type=\"button\"\n disabled={(provider.sticky ?? 1) <= 1}\n onClick={() => void adminApi.setProviderStrategy(id, \"round-robin\", Math.max(1, (provider.sticky ?? 1) - 1)).then(() => reload())}\n className=\"px-1.5 py-0.5 text-text-subtle transition-colors hover:text-text disabled:opacity-30\"\n aria-label=\"Decrease sticky\"\n >\n <Icon name=\"remove\" size={13} />\n </button>\n <span className=\"tnum w-6 text-center text-[11px] text-text\">{provider.sticky ?? 1}</span>\n <button\n type=\"button\"\n onClick={() => void adminApi.setProviderStrategy(id, \"round-robin\", (provider.sticky ?? 1) + 1).then(() => reload())}\n className=\"px-1.5 py-0.5 text-text-subtle transition-colors hover:text-text\"\n aria-label=\"Increase sticky\"\n >\n <Icon name=\"add\" size={13} />\n </button>\n </div>\n </div>\n )}\n </div>\n </>\n }\n >\n {testAllSummary && (\n <div className=\"mb-3 flex items-center gap-2 text-[11.5px]\">\n <Badge tone={testAllSummary.failed === 0 ? \"live\" : \"warn\"}>\n {testAllSummary.total} tested: {testAllSummary.passed} valid, {testAllSummary.failed} failed\n </Badge>\n </div>\n )}\n {keys.length === 0 ? (\n <Empty>No keys (free / service-account provider).</Empty>\n ) : (\n <div className=\"space-y-1.5\">\n {keys.map((k, i) => {\n const ks = health?.keys[i];\n const test = keyTest[i];\n const tested = test && test !== \"testing\" ? test : null;\n const lamp = tested ? (tested.ok ? \"live\" : tested.reachable ? \"idle\" : \"down\") : ks ? (ks.healthy ? \"live\" : \"down\") : \"idle\";\n const name = provider.key_names?.[k];\n const disabled = provider.disabled_keys?.includes(i) ?? false;\n if (editIdx === i) {\n return (\n <div key={i} className=\"space-y-2 rounded-brand border border-accent bg-accent-soft/40 px-3 py-2.5\">\n <Input value={editName} onChange={(e) => setEditName(e.target.value)} placeholder=\"key name (optional)\" />\n <Input value={editVal} onChange={(e) => setEditVal(e.target.value)} placeholder=\"new key value (leave blank to keep)\" className=\"font-mono text-[12.5px]\" />\n <div className=\"flex justify-end gap-2\">\n <Button variant=\"ghost\" onClick={() => setEditIdx(null)}>Cancel</Button>\n <Button disabled={busy === `editkey${i}`} onClick={() => run(`editkey${i}`, async () => {\n const r = await adminApi.editKey(id, i, { name: editName, key: editVal.trim() || undefined });\n if (r.ok) setEditIdx(null);\n return r;\n })}>Save</Button>\n </div>\n </div>\n );\n }\n return (\n <div key={i} className={`rounded-brand border border-border-subtle px-3 py-2${disabled ? \" opacity-60\" : \"\"}`}>\n <div className=\"flex items-center gap-2\">\n {/* reorder */}\n <div className=\"flex flex-col\">\n <button\n onClick={() => run(`reorder${i}up`, () => adminApi.reorderKey(id, i, i - 1))}\n disabled={i === 0}\n className=\"p-0.5 text-text-subtle hover:text-text disabled:opacity-30\"\n aria-label=\"Move up\"\n >\n <Icon name=\"keyboard_arrow_up\" size={14} />\n </button>\n <button\n onClick={() => run(`reorder${i}dn`, () => adminApi.reorderKey(id, i, i + 1))}\n disabled={i === keys.length - 1}\n className=\"p-0.5 text-text-subtle hover:text-text disabled:opacity-30\"\n aria-label=\"Move down\"\n >\n <Icon name=\"keyboard_arrow_down\" size={14} />\n </button>\n </div>\n <Lamp state={lamp} />\n <div className=\"min-w-0 flex-1\">\n {name && <div className=\"text-[12px] font-semibold text-text-muted\">{name}</div>}\n <span className=\"block truncate font-mono text-[12.5px] text-text\">{revealedKeys[i] ?? k}</span>\n </div>\n {revealedKeys[i] && (\n <button\n onClick={() => { void navigator.clipboard.writeText(revealedKeys[i]!); }}\n className=\"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text\"\n aria-label=\"Copy key\"\n title=\"Copy to clipboard\"\n >\n <Icon name=\"content_copy\" size={14} />\n </button>\n )}\n {ks && ks.cooldown_ms > 0 && <CooldownTimer ms={ks.cooldown_ms} />}\n {/* actions: reveal > toggle > test > edit > delete */}\n <button\n onClick={async () => {\n if (revealedKeys[i]) { setRevealedKeys((r) => { const n = { ...r }; delete n[i]; return n; }); return; }\n const r = await adminApi.revealKey(id, i);\n if (r.ok && r.data?.key) setRevealedKeys((prev) => ({ ...prev, [i]: r.data!.key }));\n }}\n className=\"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text\"\n aria-label={revealedKeys[i] ? \"Hide key\" : \"Show key\"}\n title={revealedKeys[i] ? \"Hide key\" : \"Show key\"}\n >\n <Icon name={revealedKeys[i] ? \"visibility_off\" : \"visibility\"} size={15} />\n </button>\n <button\n onClick={() => run(`toggle${i}`, () => adminApi.toggleKey(id, i, disabled))}\n className=\"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text\"\n aria-label={disabled ? \"Enable key\" : \"Disable key\"}\n title={disabled ? \"Enable this key\" : \"Disable this key\"}\n >\n <Icon name={disabled ? \"toggle_off\" : \"toggle_on\"} size={20} className={disabled ? \"text-text-subtle\" : \"text-success\"} />\n </button>\n <button\n onClick={() => testKey(i)}\n disabled={test === \"testing\"}\n className=\"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text disabled:opacity-60\"\n aria-label={`Check key ${i + 1}`}\n title=\"Check this key against the base URL\"\n >\n <Icon name={test === \"testing\" ? \"progress_activity\" : \"wifi_tethering\"} size={15} />\n </button>\n <button\n onClick={() => { setEditIdx(i); setEditName(name ?? \"\"); setEditVal(\"\"); }}\n className=\"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text\"\n aria-label={`Edit key ${i + 1}`}\n title=\"Rename or replace this key\"\n >\n <Icon name=\"edit\" size={15} />\n </button>\n <button\n onClick={() => run(`rmkey${i}`, () => adminApi.removeKey(id, i))}\n className=\"flex-none rounded p-1 text-text-subtle transition-colors hover:text-danger\"\n aria-label=\"Remove key\"\n >\n <Icon name=\"delete\" size={15} />\n </button>\n </div>\n {tested && (\n <div className=\"mt-1.5 flex items-center gap-2 pl-8 text-[11.5px]\">\n <Badge tone={tested.ok ? \"live\" : tested.reachable ? \"warn\" : \"down\"}>\n {tested.ok ? \"valid\" : tested.reachable ? `reachable (${tested.status})` : \"invalid\"}\n </Badge>\n {tested.error && <span className=\"truncate text-danger\">{tested.error}</span>}\n </div>\n )}\n {!tested && ks?.last_error && (\n <div className=\"mt-1.5 flex items-center gap-2 pl-8 text-[11.5px]\">\n <span className=\"text-danger\">{ks.last_error.status ? `${ks.last_error.status}: ` : \"\"}{ks.last_error.message}</span>\n <span className=\"text-text-subtle\">{new Date(ks.last_error.at).toLocaleTimeString()}</span>\n </div>\n )}\n </div>\n );\n })}\n </div>\n )}\n <div className=\"mt-3 space-y-2\">\n <Input value={newKeyName} onChange={(e) => setNewKeyName(e.target.value)} placeholder=\"key name (optional, e.g. primary)\" />\n <div className=\"flex gap-2\">\n <Input value={newKey} onChange={(e) => setNewKey(e.target.value)} placeholder=\"add a key…\" className=\"font-mono text-[12.5px]\" />\n <Button disabled={!newKey || busy === \"addkey\"} onClick={() => run(\"addkey\", async () => {\n const r = await adminApi.addKey(id, newKey, newKeyName.trim() || undefined);\n if (r.ok) { setNewKey(\"\"); setNewKeyName(\"\"); }\n return r;\n })}>Add</Button>\n </div>\n </div>\n </RichCard>\n\n <RichCard\n className=\"lg:col-span-2\"\n header={\n <>\n <CardTitle title=\"Models served\" sub={`${provider.models.length} in catalog`} />\n {provider.models.length > 0 && (\n <button\n onClick={() => run(\"clear\", () => adminApi.clearModels(id))}\n disabled={busy === \"clear\"}\n className=\"text-[12px] text-text-subtle hover:text-danger\"\n >\n Clear all\n </button>\n )}\n </>\n }\n >\n {provider.models.length === 0 ? (\n <Empty>No models. Add one below, or fetch them for a free/auto provider.</Empty>\n ) : (\n <>\n <p className=\"mb-2.5 text-[12px] text-text-subtle\">\n Call any of these as <span className=\"tnum text-text-muted\">{provider.id}/<model></span>, as a combo alias, or by the bare id.\n </p>\n {/* filter only earns its space once the catalog is long enough to scroll */}\n {provider.models.length > 8 && (\n <div className=\"mb-2.5 flex items-center gap-2\">\n <div className=\"relative flex-1\">\n <Icon name=\"search\" size={15} className=\"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-text-subtle\" />\n <Input value={modelFilter} onChange={(e) => setModelFilter(e.target.value)} placeholder=\"filter models…\" className=\"pl-8\" />\n </div>\n <span className=\"tnum whitespace-nowrap text-[12px] text-text-subtle\">\n {q ? `${shownModels.length} of ${provider.models.length}` : `${provider.models.length}`}\n </span>\n </div>\n )}\n {shownModels.length === 0 ? (\n <Empty>No model matches “{modelFilter}”.</Empty>\n ) : (\n <div className=\"max-h-[360px] divide-y divide-border-subtle overflow-y-auto rounded-brand border border-border-subtle\">\n {shownModels.map((m) => {\n const st = modelTest[m.id];\n const statusIcon = st === \"ok\" ? \"check_circle\" : st === \"fail\" ? \"cancel\" : \"smart_toy\";\n const statusColor = st === \"ok\" ? \"text-success\" : st === \"fail\" ? \"text-danger\" : \"text-text-subtle\";\n return (\n <div key={m.id} className=\"group flex items-center justify-between gap-3 px-3 py-2 hover:bg-bg\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <Icon name={statusIcon} size={15} className={`flex-none ${statusColor}`} />\n {/* the prefix (= provider id) is what makes the call string; show it aigetwey-style */}\n <span className=\"tnum truncate text-[12.5px]\">\n <span className=\"text-text-subtle\">{provider.id}/</span>\n <span className=\"text-text\">{m.id}</span>\n </span>\n <CapacityBadges model={m.id} provider={provider.id} />\n {(m.price_in !== undefined || m.price_out !== undefined) && (\n <span className=\"tnum whitespace-nowrap text-[11px] text-text-subtle\">\n {fmt.cost(m.price_in ?? 0)}/{fmt.cost(m.price_out ?? 0)} per 1M\n </span>\n )}\n </div>\n <div className=\"flex flex-none items-center gap-0.5\">\n <button\n onClick={() => testModel(m.id)}\n disabled={st === \"testing\"}\n className=\"rounded p-1 text-text-subtle transition-colors hover:bg-surface hover:text-accent disabled:opacity-60\"\n aria-label={`Test ${m.id}`}\n title={st === \"fail\" ? \"Test failed — click to retry\" : \"Test this model\"}\n >\n <Icon name={st === \"testing\" ? \"progress_activity\" : \"science\"} size={15} />\n </button>\n <button\n onClick={() => run(`rmmodel${m.id}`, () => adminApi.removeModel(id, m.id))}\n disabled={busy === `rmmodel${m.id}`}\n className=\"rounded p-1 text-text-subtle transition-colors hover:bg-surface hover:text-danger disabled:opacity-40\"\n aria-label={`Remove ${m.id}`}\n >\n <Icon name=\"delete\" size={16} />\n </button>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </>\n )}\n <div className=\"mt-3 flex gap-2\">\n <Input value={newModel} onChange={(e) => setNewModel(e.target.value)} placeholder=\"add a model id…\" />\n <Button disabled={!newModel || busy === \"addmodel\"} onClick={() => run(\"addmodel\", async () => {\n const r = await adminApi.addModel(id, newModel);\n if (r.ok) setNewModel(\"\");\n return r;\n })}>Add</Button>\n </div>\n </RichCard>\n </div>\n\n {discovered && (\n <ModelSelectModal\n models={discovered}\n busy={busy === \"addmodels\"}\n onClose={() => setDiscovered(null)}\n onAdd={(ids) => run(\"addmodels\", async () => {\n const r = await adminApi.addModels(id, ids);\n if (r.ok) setDiscovered(null);\n return r;\n })}\n />\n )}\n\n <div className=\"mt-6\">\n <Button variant=\"danger\" onClick={() => setConfirmDelete(true)}>\n <Icon name=\"delete\" size={16} /> Remove provider\n </Button>\n </div>\n\n {confirmDelete && (\n <ConfirmModal\n title=\"Remove provider\"\n message={`Delete \"${provider.name ?? id}\"? All keys and model associations will be lost.`}\n confirmLabel=\"Remove\"\n busy={busy === \"rmprov\"}\n onCancel={() => setConfirmDelete(false)}\n onConfirm={() => run(\"rmprov\", async () => {\n const r = await adminApi.removeProvider(id);\n if (r.ok) router.push(\"/providers\");\n else setConfirmDelete(false);\n return r;\n })}\n />\n )}\n </div>\n );\n}\n\nfunction Row({ k, v }: { k: string; v: string }) {\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-text-subtle\">{k}</span>\n <span className=\"truncate text-text\">{v}</span>\n </div>\n );\n}\n","import { Icon } from \"./Icon\";\n\n/**\n * Themed checkbox. Native checkboxes look out of place on the dark Haulix\n * surface, so this is a button styled to match: filled with the accent + a\n * check glyph when on, a bordered box when off. `indeterminate` renders a dash\n * for \"some selected\" (drives the select-all row).\n */\nexport function Checkbox({\n checked,\n indeterminate,\n onChange,\n className,\n ariaLabel,\n}: {\n checked: boolean;\n indeterminate?: boolean;\n onChange: () => void;\n className?: string;\n ariaLabel?: string;\n}) {\n const on = checked || indeterminate;\n return (\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={indeterminate ? \"mixed\" : checked}\n aria-label={ariaLabel}\n onClick={(e) => {\n e.stopPropagation();\n onChange();\n }}\n className={`flex h-[18px] w-[18px] flex-none items-center justify-center rounded-[5px] border transition-colors ${\n on ? \"border-accent bg-accent text-accent-ink\" : \"border-border bg-bg text-transparent hover:border-text-subtle\"\n }${className ? ` ${className}` : \"\"}`}\n >\n <Icon name={indeterminate ? \"remove\" : \"check\"} size={13} />\n </button>\n );\n}\n","\"use client\";\n\nimport { useState, useMemo } from \"react\";\nimport { Button, Input } from \"@/components/Button\";\nimport { Checkbox } from \"@/components/Checkbox\";\nimport { Icon } from \"@/components/Icon\";\n\nexport interface DiscoveredModel {\n id: string;\n added: boolean; // already in the provider catalog\n}\n\n/**\n * Pick which discovered models to add. Free providers can return hundreds of\n * ids, so this is a filterable checklist (defaulting to only the not-yet-added\n * ones selected) rather than dumping everything into the catalog.\n */\nexport function ModelSelectModal({\n models,\n busy,\n onAdd,\n onClose,\n}: {\n models: DiscoveredModel[];\n busy: boolean;\n onAdd: (ids: string[]) => void;\n onClose: () => void;\n}) {\n const [filter, setFilter] = useState(\"\");\n const [picked, setPicked] = useState<Set<string>>(() => new Set(models.filter((m) => !m.added).map((m) => m.id)));\n\n const shown = useMemo(() => {\n const q = filter.trim().toLowerCase();\n return q ? models.filter((m) => m.id.toLowerCase().includes(q)) : models;\n }, [models, filter]);\n\n function toggle(id: string) {\n setPicked((s) => {\n const next = new Set(s);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }\n\n const shownPickedCount = shown.filter((m) => picked.has(m.id)).length;\n const allShownPicked = shown.length > 0 && shownPickedCount === shown.length;\n const someShownPicked = shownPickedCount > 0 && !allShownPicked;\n function toggleAllShown() {\n setPicked((s) => {\n const next = new Set(s);\n if (allShownPicked) shown.forEach((m) => next.delete(m.id));\n else shown.forEach((m) => next.add(m.id));\n return next;\n });\n }\n\n return (\n <div className=\"fixed inset-0 z-50 grid place-items-center bg-black/50 p-6\" onClick={onClose}>\n <div\n className=\"flex max-h-[80vh] w-full max-w-[480px] flex-col overflow-hidden rounded-brand-lg border border-border bg-surface shadow-elevated\"\n onClick={(e) => e.stopPropagation()}\n >\n <header className=\"flex items-center justify-between border-b border-border-subtle px-4 py-3\">\n <span className=\"text-[14px] font-semibold text-text\">{models.length} models found</span>\n <button onClick={onClose} className=\"text-text-subtle hover:text-text\" aria-label=\"Close\">\n <Icon name=\"close\" size={18} />\n </button>\n </header>\n\n <div className=\"border-b border-border-subtle px-4 py-2.5\">\n <Input value={filter} onChange={(e) => setFilter(e.target.value)} placeholder=\"filter…\" autoFocus />\n </div>\n\n {/* select-all row: an obvious clickable control, not an ambiguous button */}\n {shown.length > 0 && (\n <button\n onClick={toggleAllShown}\n className=\"flex items-center gap-2.5 border-b border-border-subtle px-4 py-2 text-left hover:bg-surface-2\"\n >\n <Checkbox checked={allShownPicked} indeterminate={someShownPicked} onChange={toggleAllShown} ariaLabel=\"Select all\" />\n <span className=\"text-[12.5px] font-medium text-text\">Select all{filter ? \" (filtered)\" : \"\"}</span>\n <span className=\"ml-auto tnum text-[11px] text-text-subtle\">\n {shownPickedCount}/{shown.length}\n </span>\n </button>\n )}\n\n <div className=\"flex-1 overflow-y-auto px-2 py-2\">\n {shown.length === 0 ? (\n <div className=\"px-2 py-6 text-center text-[13px] text-text-muted\">No matches.</div>\n ) : (\n shown.map((m) => {\n const sel = picked.has(m.id);\n return (\n <button\n key={m.id}\n onClick={() => toggle(m.id)}\n className={`flex w-full items-center gap-2.5 rounded-brand border px-2.5 py-2 text-left transition-colors ${\n sel ? \"border-accent/40 bg-accent-soft\" : \"border-transparent hover:bg-surface-2\"\n }`}\n >\n <Checkbox checked={sel} onChange={() => toggle(m.id)} ariaLabel={m.id} />\n <span className=\"flex-1 truncate text-[12.5px] text-text\">{m.id}</span>\n {m.added && <span className=\"text-[11px] text-text-subtle\">in catalog</span>}\n </button>\n );\n })\n )}\n </div>\n\n <footer className=\"flex items-center justify-between gap-3 border-t border-border-subtle bg-bg-alt px-4 py-2.5\">\n <span className=\"tnum text-[12px] text-text-muted\">{picked.size} selected</span>\n <div className=\"flex gap-2\">\n <Button variant=\"ghost\" onClick={onClose}>\n Cancel\n </Button>\n <Button disabled={picked.size === 0 || busy} onClick={() => onAdd([...picked])}>\n {busy ? \"Adding…\" : `Add ${picked.size}`}\n </Button>\n </div>\n </footer>\n </div>\n </div>\n );\n}\n"],"names":["Checkbox","checked","indeterminate","onChange","className","ariaLabel","on","type","role","onClick","e","stopPropagation","name","size"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
module.exports=[95600,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(50944),e=a.i(85732),f=a.i(2693),g=a.i(7078),h=a.i(47444),i=a.i(93026),j=a.i(58918),k=a.i(56173),l=a.i(70200),m=a.i(55690);function n({label:a,children:c,top:d}){return(0,b.jsxs)("div",{className:`grid grid-cols-[7rem_1fr] gap-3 ${d?"items-start":"items-center"}`,children:[(0,b.jsx)("span",{className:`text-[12px] font-medium text-text-subtle ${d?"pt-1.5":""}`,children:a}),(0,b.jsx)("div",{className:"min-w-0",children:c})]})}function o({text:a}){let[d,e]=(0,c.useState)(!1);return(0,b.jsxs)("div",{className:"relative",children:[(0,b.jsx)("pre",{className:"overflow-x-auto rounded-brand border border-border-subtle bg-bg px-3 py-2.5 font-mono text-[12.5px] leading-relaxed text-text",children:a}),(0,b.jsxs)("button",{onClick:()=>{navigator.clipboard.writeText(a),e(!0),setTimeout(()=>e(!1),1200)},className:"absolute right-2 top-2 flex items-center gap-1 rounded-brand border border-border bg-surface px-2 py-1 text-[11px] text-text-muted hover:text-text",children:[(0,b.jsx)(i.Icon,{name:d?"check":"content_copy",size:13})," ",d?"copied":"copy"]})]})}a.s(["ToolDetail",0,function({id:a}){let p=(0,d.useRouter)(),q=(0,l.toolById)(a),[r,s]=(0,c.useState)(null),[t,u]=(0,c.useState)([]),[v,w]=(0,c.useState)(0),[x,y]=(0,c.useState)(""),[z,A]=(0,c.useState)(""),[B,C]=(0,c.useState)(null),[D,E]=(0,c.useState)(""),[F,G]=(0,c.useState)(""),[H,I]=(0,c.useState)([]),[J,K]=(0,c.useState)([]),[L,M]=(0,c.useState)(!1),[N,O]=(0,c.useState)([]),[P,Q]=(0,c.useState)(""),[R,S]=(0,c.useState)({opus:"",sonnet:"",haiku:""}),T=q?.format==="anthropic",U=(0,c.useCallback)(async()=>{q?.autoConfig&&C((await k.cliConfig.status(q.id)).data)},[q]);async function V(){if(!q||!r)return;G("");let a=`http://127.0.0.1:${r.port}`,b=r.keys.length&&x||void 0;if(T){let c={};R.opus&&(c.opus=R.opus),R.sonnet&&(c.sonnet=R.sonnet),R.haiku&&(c.haiku=R.haiku),E("apply");let d=await k.cliConfig.apply(q.id,{base:a,key:b,models:c});E(""),G(d.ok?"Wrote config ✓":d.error??"failed"),d.ok&&U();return}if(0===N.length)return void G("add at least one model");E("apply");let c=await k.cliConfig.apply(q.id,{base:a,key:b,models:N,active:P});E(""),G(c.ok?"Wrote config ✓":c.error??"failed"),c.ok&&U()}async function W(){if(!q)return;E("reset"),G("");let a=await k.cliConfig.reset(q.id);E(""),a.ok?(G("Removed gateway config ✓"),U()):G(a.error??"failed")}if((0,c.useEffect)(()=>{U()},[U]),(0,c.useEffect)(()=>{B?.installed&&(T&&B.modelSlots?S({opus:B.modelSlots.opus??"",sonnet:B.modelSlots.sonnet??"",haiku:B.modelSlots.haiku??""}):!T&&B.models&&B.models.length>0&&(O(B.models),Q(B.activeModel??B.models[0]??"")))},[B,T]),(0,c.useEffect)(()=>{(async()=>{let[a,b]=await Promise.all([fetch("/api/gw/admin/endpoint"),fetch("/api/gw/admin/config")]);if(!a.ok)return A("could not reach the gateway");if(s(await a.json()),b.ok){let a=await b.json(),c=a.models.map(a=>a.alias);u(c);let d=a.providers.filter(a=>!a.disabled);I([...c,...d.flatMap(a=>a.models.map(b=>`${a.id}/${b.id}`))]);let e=[];for(let a of(c.length&&e.push({label:"Combos",items:c.map(a=>({value:a,label:a}))}),d))a.models.length&&e.push({label:a.id,items:a.models.map(b=>({value:`${a.id}/${b.id}`,label:`${a.id}/${b.id}`}))});K(e)}})()},[]),(0,c.useEffect)(()=>{r&&0!==r.keys.length&&k.adminApi.revealServerKey(v).then(a=>y(a.ok?a.data?.key??"":""))},[r,v]),!q)return(0,b.jsx)(j.Empty,{children:"Unknown tool."});if(z)return(0,b.jsx)(j.Empty,{children:z});if(!r)return(0,b.jsx)(j.Empty,{children:"Loading…"});let X=`http://127.0.0.1:${r.port}`,Y=q.env(X,x).map(a=>`export ${a.name}="${a.value}"`).join("\n"),Z=N.length?N:B?.models??[],$="opencode"===q.id?JSON.stringify({provider:{aigetwey:{npm:"@ai-sdk/openai-compatible",options:{baseURL:`${X}/v1`,apiKey:x||"aigetwey"},models:Object.fromEntries(Z.map(a=>[a,{name:a,modalities:(0,m.modalitiesForModel)(a)}]))}},model:`aigetwey/${P||Z[0]||""}`},null,2):null,_="claude-code"===q.id?JSON.stringify({hasCompletedOnboarding:!0,env:{ANTHROPIC_BASE_URL:X,API_TIMEOUT_MS:"600000",...x?{ANTHROPIC_AUTH_TOKEN:x}:{},...R.opus?{ANTHROPIC_DEFAULT_OPUS_MODEL:R.opus}:{},...R.sonnet?{ANTHROPIC_DEFAULT_SONNET_MODEL:R.sonnet}:{},...R.haiku?{ANTHROPIC_DEFAULT_HAIKU_MODEL:R.haiku}:{}}},null,2):null;return(0,b.jsxs)("div",{children:[(0,b.jsxs)("button",{onClick:()=>p.push("/tools"),className:"mb-4 inline-flex items-center gap-1 text-[12px] text-text-muted hover:text-text",children:[(0,b.jsx)(i.Icon,{name:"arrow_back",size:15})," CLI Tools"]}),(0,b.jsxs)("div",{className:"mb-6 flex items-center gap-3",children:[(0,b.jsx)("span",{className:"flex h-9 w-9 items-center justify-center rounded-brand bg-surface-2 text-text-muted",children:(0,b.jsx)(i.Icon,{name:q.icon,size:20})}),(0,b.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:q.name}),(0,b.jsx)(f.Badge,{tone:"info",children:q.format})]}),(0,b.jsxs)("div",{className:"grid gap-4 lg:grid-cols-2",children:[q.autoConfig&&(0,b.jsx)(e.RichCard,{className:"lg:col-span-2",header:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(e.CardTitle,{title:"Local setup",sub:"detect this tool on your machine and write its config for you"}),B&&(0,b.jsx)(f.Badge,{tone:B.installed?B.configured?"live":"warn":"neutral",children:B.installed?B.configured?"configured":"detected":"not detected"})]}),children:B?B.installed?(0,b.jsxs)("div",{className:"space-y-3",children:[(0,b.jsx)(n,{label:"Endpoint",children:(0,b.jsx)("span",{className:"tnum text-[12.5px] text-text",children:T?X:`${X}/v1`})}),r.keys.length>0&&(0,b.jsx)(n,{label:"API Key",children:(0,b.jsx)(g.Select,{value:String(v),onChange:a=>w(Number(a.target.value)),className:"max-w-[260px]",children:r.keys.map((a,c)=>(0,b.jsx)("option",{value:c,children:a.name||`key ${c+1}`},c))})}),T?(0,b.jsx)(n,{label:"Models",top:!0,children:(0,b.jsx)("div",{className:"flex flex-col gap-2",children:["opus","sonnet","haiku"].map(a=>(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[(0,b.jsx)("span",{className:"w-16 text-[12px] capitalize text-text-subtle",children:a}),(0,b.jsxs)(g.Select,{value:R[a],onChange:b=>S(c=>({...c,[a]:b.target.value})),className:"flex-1",children:[(0,b.jsx)("option",{value:"",children:"— none —"}),H.map(a=>(0,b.jsx)("option",{value:a,children:a},a))]})]},a))})}):(0,b.jsx)(n,{label:"Models",top:!0,children:(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"flex min-h-[34px] flex-wrap gap-1.5 rounded-brand border border-border-subtle bg-bg px-2 py-1.5",children:0===N.length?(0,b.jsx)("span",{className:"text-[12px] text-text-subtle",children:"No models — add one below."}):N.map(a=>(0,b.jsxs)("span",{onClick:()=>Q(b=>b===a?"":a),title:a===P?"active model — click to clear":"click to set active",className:`inline-flex cursor-pointer items-center gap-1 rounded px-2 py-0.5 text-[12px] transition-colors ${a===P?"border border-accent bg-accent-soft text-accent":"border border-transparent bg-surface-2 text-text-muted hover:border-border"}`,children:[a===P&&(0,b.jsx)(i.Icon,{name:"star",size:11}),(0,b.jsx)("span",{className:"tnum",children:a}),(0,b.jsx)("button",{onClick:b=>{b.stopPropagation(),O(b=>b.filter(b=>b!==a)),Q(b=>b===a?"":b)},className:"hover:text-danger","aria-label":`Remove ${a}`,children:(0,b.jsx)(i.Icon,{name:"close",size:12})})]},a))}),(0,b.jsxs)("div",{className:"mt-1.5 flex items-center gap-2",children:[(0,b.jsxs)(g.Button,{type:"button",variant:"ghost",onClick:()=>M(!0),children:[(0,b.jsx)(i.Icon,{name:"add",size:15})," Add models"]}),(0,b.jsx)("span",{className:"text-[11.5px] text-text-subtle",children:P?(0,b.jsxs)(b.Fragment,{children:["active: ",(0,b.jsx)("span",{className:"tnum text-accent",children:P})]}):N.length?"click a chip to set active":""})]})]})}),B.configured&&B.baseUrl&&(0,b.jsx)(n,{label:"Current",children:(0,b.jsx)("span",{className:"tnum text-[11.5px] text-text-subtle",children:B.baseUrl})}),(0,b.jsxs)("div",{className:"flex items-center gap-2 border-t border-border-subtle pt-3",children:[(0,b.jsxs)(g.Button,{onClick:V,disabled:"apply"===D,children:[(0,b.jsx)(i.Icon,{name:"apply"===D?"progress_activity":"bolt",size:15}),"apply"===D?"Applying…":B.configured?"Re-apply":"Apply config"]}),B.configured&&(0,b.jsx)(g.Button,{variant:"ghost",onClick:W,disabled:"reset"===D,children:"reset"===D?"Removing…":"Reset"}),F&&(0,b.jsx)("span",{className:"text-[12px] text-text-subtle",children:F}),B.path&&(0,b.jsx)("span",{className:"ml-auto truncate tnum text-[11px] text-text-subtle",children:B.path})]})]}):(0,b.jsx)("p",{className:"text-[12.5px] text-text-muted",children:"Not found on this machine. Install it (above) or paste the manual env below — then re-open this page."}):(0,b.jsx)("p",{className:"text-[12.5px] text-text-subtle",children:"Checking your machine…"})}),q.install&&(0,b.jsx)(e.RichCard,{header:(0,b.jsx)(e.CardTitle,{title:"Install"}),children:(0,b.jsx)(o,{text:q.install})}),(0,b.jsxs)(e.RichCard,{className:q.install?"":"lg:col-span-2",header:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(e.CardTitle,{title:"Environment",sub:"copy into your shell"}),r.keys.length>1&&(0,b.jsx)(g.Select,{value:String(v),onChange:a=>w(Number(a.target.value)),className:"max-w-[180px]",children:r.keys.map((a,c)=>(0,b.jsx)("option",{value:c,children:a.name||`key ${c+1}`},c))})]}),children:[(0,b.jsx)(o,{text:Y}),0===r.keys.length?(0,b.jsx)("p",{className:"mt-3 text-[12px] text-warning",children:"No gateway key set — auth is disabled. Add one under Endpoint, then it appears here."}):(0,b.jsxs)("p",{className:"mt-3 text-[12px] text-text-subtle",children:["Using key ",(0,b.jsx)("span",{className:"text-text-muted",children:r.keys[v]?.name||`#${v+1}`}),". The real value is filled in above."]})]}),$&&(0,b.jsxs)(e.RichCard,{className:"lg:col-span-2",header:(0,b.jsx)(e.CardTitle,{title:"Manual config",sub:"merge into ~/.config/opencode/opencode.json — every model listed"}),children:[0===Z.length?(0,b.jsx)("p",{className:"text-[12.5px] text-text-muted",children:"Add models above to see them listed here."}):(0,b.jsx)(o,{text:$}),(0,b.jsx)("p",{className:"mt-3 text-[12px] text-text-subtle",children:"Apply does the same merge for you — it keeps any other providers and existing models, only adding these."})]}),_&&(0,b.jsxs)(e.RichCard,{className:"lg:col-span-2",header:(0,b.jsx)(e.CardTitle,{title:"Manual config",sub:"merge the env block into ~/.claude/settings.json"}),children:[(0,b.jsx)(o,{text:_}),(0,b.jsx)("p",{className:"mt-3 text-[12px] text-text-subtle",children:"Apply does the same merge for you — it keeps the rest of your settings, only writing these env keys."})]}),!q.autoConfig&&(0,b.jsxs)(e.RichCard,{className:"lg:col-span-2",header:(0,b.jsx)(e.CardTitle,{title:"Models to call",sub:"name a combo exactly this — the tool will hit it"}),children:[(0,b.jsx)("div",{className:"space-y-1.5",children:q.slots.map(a=>{let c=t.includes(a.alias);return(0,b.jsxs)("div",{className:"flex items-center gap-3 rounded-brand border border-border-subtle px-3 py-2",children:[(0,b.jsx)("span",{className:"w-32 flex-none text-[12px] text-text-subtle",children:a.label}),(0,b.jsx)(i.Icon,{name:"arrow_forward",size:14,className:"flex-none text-text-subtle"}),(0,b.jsx)("span",{className:"tnum truncate text-[13px] text-text",children:a.alias}),(0,b.jsx)("span",{className:"ml-auto flex flex-none items-center gap-2",children:c?(0,b.jsx)(f.Badge,{tone:"live",children:"ready"}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(f.Badge,{tone:"warn",children:"missing"}),(0,b.jsxs)("button",{type:"button",onClick:()=>p.push("/combos"),className:"inline-flex items-center gap-1 text-[12px] text-accent hover:underline",children:[(0,b.jsx)(i.Icon,{name:"add",size:13})," create"]})]})})]},a.alias)})}),t.length>0&&(0,b.jsxs)("p",{className:"mt-2.5 text-[11px] text-text-subtle",children:["Your combos: ",(0,b.jsx)("span",{className:"tnum text-text-muted",children:t.join(", ")})]})]}),(0,b.jsx)(e.RichCard,{className:"lg:col-span-2",header:(0,b.jsx)(e.CardTitle,{title:"Steps"}),children:(0,b.jsx)("ol",{className:"space-y-2.5",children:q.steps.map((a,c)=>(0,b.jsxs)("li",{className:"flex gap-2.5 text-[13px] text-text-muted",children:[(0,b.jsx)("span",{className:"flex h-5 w-5 flex-none items-center justify-center rounded-full bg-surface-2 tnum text-[11px] text-text",children:c+1}),a]},c))})})]}),L&&(0,b.jsx)(h.ModelPicker,{title:"Add models",note:"Click a model to add it, click again to remove. Then hit Apply.",groups:J,selected:N,onToggle:function(a){N.includes(a)?(O(b=>b.filter(b=>b!==a)),P===a&&Q("")):(O(b=>[...b,a]),P||Q(a))},onClose:()=>M(!1)})]})}])}];
|
|
1
|
+
module.exports=[95600,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(50944),e=a.i(85732),f=a.i(2693),g=a.i(7078),h=a.i(47444),i=a.i(93026),j=a.i(58918),k=a.i(56173),l=a.i(70200),m=a.i(55690);function n({label:a,children:c,top:d}){return(0,b.jsxs)("div",{className:`grid grid-cols-[7rem_1fr] gap-3 ${d?"items-start":"items-center"}`,children:[(0,b.jsx)("span",{className:`text-[12px] font-medium text-text-subtle ${d?"pt-1.5":""}`,children:a}),(0,b.jsx)("div",{className:"min-w-0",children:c})]})}function o({text:a}){let[d,e]=(0,c.useState)(!1);return(0,b.jsxs)("div",{className:"relative",children:[(0,b.jsx)("pre",{className:"overflow-x-auto rounded-brand border border-border-subtle bg-bg px-3 py-2.5 font-mono text-[12.5px] leading-relaxed text-text",children:a}),(0,b.jsxs)("button",{onClick:()=>{navigator.clipboard.writeText(a),e(!0),setTimeout(()=>e(!1),1200)},className:"absolute right-2 top-2 flex items-center gap-1 rounded-brand border border-border bg-surface px-2 py-1 text-[11px] text-text-muted hover:text-text",children:[(0,b.jsx)(i.Icon,{name:d?"check":"content_copy",size:13})," ",d?"copied":"copy"]})]})}a.s(["ToolDetail",0,function({id:a}){let p=(0,d.useRouter)(),q=(0,l.toolById)(a),[r,s]=(0,c.useState)(null),[t,u]=(0,c.useState)([]),[v,w]=(0,c.useState)(0),[x,y]=(0,c.useState)(""),[z,A]=(0,c.useState)([]),[B,C]=(0,c.useState)(""),[D,E]=(0,c.useState)(""),[F,G]=(0,c.useState)(!1),[H,I]=(0,c.useState)(""),[J,K]=(0,c.useState)(!1),[L,M]=(0,c.useState)("");(0,c.useEffect)(()=>{A(JSON.parse(localStorage.getItem(`cli-saved-bases-${a}`)??"[]")),C(localStorage.getItem(`cli-selected-base-${a}`)??""),I(localStorage.getItem(`cli-custom-key-${a}`)??"")},[a]);let[N,O]=(0,c.useState)(""),[P,Q]=(0,c.useState)(null),[R,S]=(0,c.useState)(""),[T,U]=(0,c.useState)(""),[V,W]=(0,c.useState)([]),[X,Y]=(0,c.useState)([]),[Z,$]=(0,c.useState)(!1),[_,aa]=(0,c.useState)(null),[ab,ac]=(0,c.useState)([]),[ad,ae]=(0,c.useState)(""),[af,ag]=(0,c.useState)({opus:"",sonnet:"",haiku:""}),ah=q?.format==="anthropic",ai=(0,c.useCallback)(async()=>{q?.autoConfig&&Q((await k.cliConfig.status(q.id)).data)},[q]);function aj(b){let c=b.trim();if(!c)return;let d=[c,...z.filter(a=>a!==c)];A(d),C(c),localStorage.setItem(`cli-saved-bases-${a}`,JSON.stringify(d)),localStorage.setItem(`cli-selected-base-${a}`,c),E(""),G(!1)}async function ak(){if(!q||!r)return;U(""),localStorage.setItem(`cli-selected-base-${a}`,B),H.trim()?localStorage.setItem(`cli-custom-key-${a}`,H.trim()):localStorage.removeItem(`cli-custom-key-${a}`);let b=`http://127.0.0.1:${r.port}`,c=B||b,d=H.trim()||r.keys.length&&x||void 0;if(ah){let a={};af.opus&&(a.opus=af.opus),af.sonnet&&(a.sonnet=af.sonnet),af.haiku&&(a.haiku=af.haiku),S("apply");let b=await k.cliConfig.apply(q.id,{base:c,key:d,models:a});S(""),U(b.ok?"Wrote config ✓":b.error??"failed"),b.ok&&ai();return}if(0===ab.length)return void U("add at least one model");S("apply");let e=await k.cliConfig.apply(q.id,{base:c,key:d,models:ab,active:ad});S(""),U(e.ok?"Wrote config ✓":e.error??"failed"),e.ok&&ai()}async function al(){if(!q)return;S("reset"),U("");let a=await k.cliConfig.reset(q.id);S(""),a.ok?(U("Removed gateway config ✓"),ai()):U(a.error??"failed")}if((0,c.useEffect)(()=>{ai()},[ai]),(0,c.useEffect)(()=>{P?.installed&&(ah&&P.modelSlots?ag({opus:P.modelSlots.opus??"",sonnet:P.modelSlots.sonnet??"",haiku:P.modelSlots.haiku??""}):!ah&&P.models&&P.models.length>0&&(ac(P.models),ae(P.activeModel??P.models[0]??"")))},[P,ah]),(0,c.useEffect)(()=>{(async()=>{let[a,b]=await Promise.all([fetch("/api/gw/admin/endpoint"),fetch("/api/gw/admin/config")]);if(!a.ok)return O("could not reach the gateway");if(s(await a.json()),b.ok){let a=await b.json(),c=a.models.map(a=>a.alias);u(c);let d=a.providers.filter(a=>!a.disabled);W([...c,...d.flatMap(a=>a.models.map(b=>`${a.id}/${b.id}`))]);let e=[];for(let a of(c.length&&e.push({label:"Combos",items:c.map(a=>({value:a,label:a}))}),d))a.models.length&&e.push({label:a.id,items:a.models.map(b=>({value:`${a.id}/${b.id}`,label:`${a.id}/${b.id}`}))});Y(e)}})()},[]),(0,c.useEffect)(()=>{r&&0!==r.keys.length&&k.adminApi.revealServerKey(v).then(a=>y(a.ok?a.data?.key??"":""))},[r,v]),!q)return(0,b.jsx)(j.Empty,{children:"Unknown tool."});if(N)return(0,b.jsx)(j.Empty,{children:N});if(!r)return(0,b.jsx)(j.Empty,{children:"Loading…"});let am=`http://127.0.0.1:${r.port}`,an=B||am,ao=H.trim()||x,ap=q.env(an,ao).map(a=>`export ${a.name}="${a.value}"`).join("\n"),aq=ab.length?ab:P?.models??[],ar="opencode"===q.id?JSON.stringify({provider:{aigetwey:{npm:"@ai-sdk/openai-compatible",options:{baseURL:`${an}/v1`,apiKey:x||"aigetwey"},models:Object.fromEntries(aq.map(a=>[a,{name:a,modalities:(0,m.modalitiesForModel)(a)}]))}},model:`aigetwey/${ad||aq[0]||""}`},null,2):null,as="claude-code"===q.id?JSON.stringify({hasCompletedOnboarding:!0,env:{ANTHROPIC_BASE_URL:an,API_TIMEOUT_MS:"600000",...x?{ANTHROPIC_AUTH_TOKEN:x}:{},...af.opus?{ANTHROPIC_DEFAULT_OPUS_MODEL:af.opus}:{},...af.sonnet?{ANTHROPIC_DEFAULT_SONNET_MODEL:af.sonnet}:{},...af.haiku?{ANTHROPIC_DEFAULT_HAIKU_MODEL:af.haiku}:{}}},null,2):null;return(0,b.jsxs)("div",{children:[(0,b.jsxs)("button",{onClick:()=>p.push("/tools"),className:"mb-4 inline-flex items-center gap-1 text-[12px] text-text-muted hover:text-text",children:[(0,b.jsx)(i.Icon,{name:"arrow_back",size:15})," CLI Tools"]}),(0,b.jsxs)("div",{className:"mb-6 flex items-center gap-3",children:[(0,b.jsx)("span",{className:"flex h-9 w-9 items-center justify-center rounded-brand bg-surface-2 text-text-muted",children:(0,b.jsx)(i.Icon,{name:q.icon,size:20})}),(0,b.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:q.name}),(0,b.jsx)(f.Badge,{tone:"info",children:q.format})]}),(0,b.jsxs)("div",{className:"grid gap-4 lg:grid-cols-2",children:[q.autoConfig&&(0,b.jsx)(e.RichCard,{className:"lg:col-span-2",header:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(e.CardTitle,{title:"Local setup",sub:"detect this tool on your machine and write its config for you"}),P&&(0,b.jsx)(f.Badge,{tone:P.installed?P.configured?"live":"warn":"neutral",children:P.installed?P.configured?"configured":"detected":"not detected"})]}),children:P?P.installed?(0,b.jsxs)("div",{className:"space-y-3",children:[(0,b.jsx)(n,{label:"Endpoint",children:(0,b.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[(0,b.jsxs)(g.Select,{value:B||"__auto__",onChange:b=>{let c=b.target.value;if("__custom__"===c)return void G(!0);let d="__auto__"===c?"":c;C(d),localStorage.setItem(`cli-selected-base-${a}`,d)},className:"flex-1",children:[(0,b.jsxs)("option",{value:"__auto__",children:[am," (auto)"]}),z.map(a=>(0,b.jsx)("option",{value:a,children:a},a)),(0,b.jsx)("option",{value:"__custom__",children:"Custom URL…"})]}),B&&(0,b.jsx)(g.Button,{variant:"ghost",className:"px-2 py-1 flex-none",title:"remove this URL",onClick:()=>{let b=z.filter(a=>a!==B);A(b),localStorage.setItem(`cli-saved-bases-${a}`,JSON.stringify(b)),C(""),localStorage.setItem(`cli-selected-base-${a}`,"")},children:(0,b.jsx)(i.Icon,{name:"delete",size:15})})]}),F&&(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[(0,b.jsx)("input",{autoFocus:!0,value:D,onChange:a=>E(a.target.value),onKeyDown:a=>"Enter"===a.key&&aj(D),placeholder:"https://your-gateway.example.com",className:"flex-1 rounded-brand border border-accent bg-bg px-2.5 py-1.5 font-mono text-[12px] text-text outline-none placeholder:text-text-subtle"}),(0,b.jsx)(g.Button,{variant:"ghost",onClick:()=>aj(D),children:"Add"}),(0,b.jsx)(g.Button,{variant:"ghost",onClick:()=>{G(!1),E("")},children:"Cancel"})]})]})}),(0,b.jsx)(n,{label:"API Key",children:(0,b.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[(0,b.jsxs)(g.Select,{value:H?"__custom__":String(v),onChange:b=>{let c=b.target.value;"__custom__"===c?K(!0):(I(""),w(Number(c)),localStorage.removeItem(`cli-custom-key-${a}`))},className:"flex-1",children:[r.keys.map((a,c)=>(0,b.jsx)("option",{value:c,children:a.name||`key ${c+1}`},c)),H&&(0,b.jsxs)("option",{value:"__custom__",children:[H.slice(0,12),"… (custom)"]}),!H&&(0,b.jsx)("option",{value:"__custom__",children:"Custom key…"})]}),H&&(0,b.jsx)(g.Button,{variant:"ghost",className:"px-2 py-1 flex-none",title:"remove custom key",onClick:()=>{I(""),localStorage.removeItem(`cli-custom-key-${a}`)},children:(0,b.jsx)(i.Icon,{name:"delete",size:15})})]}),J&&(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[(0,b.jsx)("input",{autoFocus:!0,value:L,onChange:a=>M(a.target.value),onKeyDown:b=>{"Enter"===b.key&&(I(L.trim()),localStorage.setItem(`cli-custom-key-${a}`,L.trim()),K(!1),M(""))},placeholder:"paste API key…",className:"flex-1 rounded-brand border border-accent bg-bg px-2.5 py-1.5 font-mono text-[12px] text-text outline-none placeholder:text-text-subtle"}),(0,b.jsx)(g.Button,{variant:"ghost",onClick:()=>{I(L.trim()),localStorage.setItem(`cli-custom-key-${a}`,L.trim()),K(!1),M("")},children:"Add"}),(0,b.jsx)(g.Button,{variant:"ghost",onClick:()=>{K(!1),M("")},children:"Cancel"})]})]})}),ah?(0,b.jsx)(n,{label:"Models",top:!0,children:(0,b.jsx)("div",{className:"flex flex-col gap-2",children:["opus","sonnet","haiku"].map(a=>(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[(0,b.jsx)("span",{className:"w-16 flex-none text-[12px] capitalize text-text-subtle",children:a}),af[a]?(0,b.jsxs)("span",{className:"flex flex-1 items-center gap-1.5 rounded border border-accent bg-accent-soft px-2 py-1 font-mono text-[12px] text-accent",children:[(0,b.jsx)("span",{className:"flex-1 truncate",children:af[a]}),(0,b.jsx)("button",{onClick:()=>ag(b=>({...b,[a]:""})),className:"flex-none hover:text-danger","aria-label":"clear",children:(0,b.jsx)(i.Icon,{name:"close",size:12})})]}):(0,b.jsxs)("button",{onClick:()=>{aa(a),$(!0)},className:"flex items-center gap-1 rounded border border-dashed border-border px-2.5 py-1 text-[12px] text-text-subtle hover:border-accent hover:text-accent",children:[(0,b.jsx)(i.Icon,{name:"add",size:13})," Add model"]})]},a))})}):(0,b.jsx)(n,{label:"Models",top:!0,children:(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"flex min-h-[34px] flex-wrap gap-1.5 rounded-brand border border-border-subtle bg-bg px-2 py-1.5",children:0===ab.length?(0,b.jsx)("span",{className:"text-[12px] text-text-subtle",children:"No models — add one below."}):ab.map(a=>(0,b.jsxs)("span",{onClick:()=>ae(b=>b===a?"":a),title:a===ad?"active model — click to clear":"click to set active",className:`inline-flex cursor-pointer items-center gap-1 rounded px-2 py-0.5 text-[12px] transition-colors ${a===ad?"border border-accent bg-accent-soft text-accent":"border border-transparent bg-surface-2 text-text-muted hover:border-border"}`,children:[a===ad&&(0,b.jsx)(i.Icon,{name:"star",size:11}),(0,b.jsx)("span",{className:"tnum",children:a}),(0,b.jsx)("button",{onClick:b=>{b.stopPropagation(),ac(b=>b.filter(b=>b!==a)),ae(b=>b===a?"":b)},className:"hover:text-danger","aria-label":`Remove ${a}`,children:(0,b.jsx)(i.Icon,{name:"close",size:12})})]},a))}),(0,b.jsxs)("div",{className:"mt-1.5 flex items-center gap-2",children:[(0,b.jsxs)(g.Button,{type:"button",variant:"ghost",onClick:()=>$(!0),children:[(0,b.jsx)(i.Icon,{name:"add",size:15})," Add models"]}),(0,b.jsx)("span",{className:"text-[11.5px] text-text-subtle",children:ad?(0,b.jsxs)(b.Fragment,{children:["active: ",(0,b.jsx)("span",{className:"tnum text-accent",children:ad})]}):ab.length?"click a chip to set active":""})]})]})}),P.configured&&P.baseUrl&&(0,b.jsx)(n,{label:"Current",children:(0,b.jsx)("span",{className:"tnum text-[11.5px] text-text-subtle",children:P.baseUrl})}),(0,b.jsxs)("div",{className:"flex items-center gap-2 border-t border-border-subtle pt-3",children:[(0,b.jsxs)(g.Button,{onClick:ak,disabled:"apply"===R,children:[(0,b.jsx)(i.Icon,{name:"apply"===R?"progress_activity":"bolt",size:15}),"apply"===R?"Applying…":P.configured?"Re-apply":"Apply config"]}),P.configured&&(0,b.jsx)(g.Button,{variant:"ghost",onClick:al,disabled:"reset"===R,children:"reset"===R?"Removing…":"Reset"}),T&&(0,b.jsx)("span",{className:"text-[12px] text-text-subtle",children:T}),P.path&&(0,b.jsx)("span",{className:"ml-auto truncate tnum text-[11px] text-text-subtle",children:P.path})]})]}):(0,b.jsx)("p",{className:"text-[12.5px] text-text-muted",children:"Not found on this machine. Install it (above) or paste the manual env below — then re-open this page."}):(0,b.jsx)("p",{className:"text-[12.5px] text-text-subtle",children:"Checking your machine…"})}),q.install&&(0,b.jsx)(e.RichCard,{header:(0,b.jsx)(e.CardTitle,{title:"Install"}),children:(0,b.jsx)(o,{text:q.install})}),(0,b.jsxs)(e.RichCard,{className:q.install?"":"lg:col-span-2",header:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(e.CardTitle,{title:"Environment",sub:"copy into your shell"}),r.keys.length>1&&(0,b.jsx)(g.Select,{value:String(v),onChange:a=>w(Number(a.target.value)),className:"max-w-[180px]",children:r.keys.map((a,c)=>(0,b.jsx)("option",{value:c,children:a.name||`key ${c+1}`},c))})]}),children:[(0,b.jsx)(o,{text:ap}),0===r.keys.length?(0,b.jsx)("p",{className:"mt-3 text-[12px] text-warning",children:"No gateway key set — auth is disabled. Add one under Endpoint, then it appears here."}):(0,b.jsxs)("p",{className:"mt-3 text-[12px] text-text-subtle",children:["Using key ",(0,b.jsx)("span",{className:"text-text-muted",children:r.keys[v]?.name||`#${v+1}`}),". The real value is filled in above."]})]}),ar&&(0,b.jsxs)(e.RichCard,{className:"lg:col-span-2",header:(0,b.jsx)(e.CardTitle,{title:"Manual config",sub:"merge into ~/.config/opencode/opencode.json — every model listed"}),children:[0===aq.length?(0,b.jsx)("p",{className:"text-[12.5px] text-text-muted",children:"Add models above to see them listed here."}):(0,b.jsx)(o,{text:ar}),(0,b.jsx)("p",{className:"mt-3 text-[12px] text-text-subtle",children:"Apply does the same merge for you — it keeps any other providers and existing models, only adding these."})]}),as&&(0,b.jsxs)(e.RichCard,{className:"lg:col-span-2",header:(0,b.jsx)(e.CardTitle,{title:"Manual config",sub:"merge the env block into ~/.claude/settings.json"}),children:[(0,b.jsx)(o,{text:as}),(0,b.jsx)("p",{className:"mt-3 text-[12px] text-text-subtle",children:"Apply does the same merge for you — it keeps the rest of your settings, only writing these env keys."})]}),!q.autoConfig&&(0,b.jsxs)(e.RichCard,{className:"lg:col-span-2",header:(0,b.jsx)(e.CardTitle,{title:"Models to call",sub:"name a combo exactly this — the tool will hit it"}),children:[(0,b.jsx)("div",{className:"space-y-1.5",children:q.slots.map(a=>{let c=t.includes(a.alias);return(0,b.jsxs)("div",{className:"flex items-center gap-3 rounded-brand border border-border-subtle px-3 py-2",children:[(0,b.jsx)("span",{className:"w-32 flex-none text-[12px] text-text-subtle",children:a.label}),(0,b.jsx)(i.Icon,{name:"arrow_forward",size:14,className:"flex-none text-text-subtle"}),(0,b.jsx)("span",{className:"tnum truncate text-[13px] text-text",children:a.alias}),(0,b.jsx)("span",{className:"ml-auto flex flex-none items-center gap-2",children:c?(0,b.jsx)(f.Badge,{tone:"live",children:"ready"}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(f.Badge,{tone:"warn",children:"missing"}),(0,b.jsxs)("button",{type:"button",onClick:()=>p.push("/combos"),className:"inline-flex items-center gap-1 text-[12px] text-accent hover:underline",children:[(0,b.jsx)(i.Icon,{name:"add",size:13})," create"]})]})})]},a.alias)})}),t.length>0&&(0,b.jsxs)("p",{className:"mt-2.5 text-[11px] text-text-subtle",children:["Your combos: ",(0,b.jsx)("span",{className:"tnum text-text-muted",children:t.join(", ")})]})]}),(0,b.jsx)(e.RichCard,{className:"lg:col-span-2",header:(0,b.jsx)(e.CardTitle,{title:"Steps"}),children:(0,b.jsx)("ol",{className:"space-y-2.5",children:q.steps.map((a,c)=>(0,b.jsxs)("li",{className:"flex gap-2.5 text-[13px] text-text-muted",children:[(0,b.jsx)("span",{className:"flex h-5 w-5 flex-none items-center justify-center rounded-full bg-surface-2 tnum text-[11px] text-text",children:c+1}),a]},c))})})]}),Z&&_&&(0,b.jsx)(h.ModelPicker,{title:`Pick model — ${_}`,note:"Click a model to select it for this slot.",groups:X,selected:af[_]?[af[_]]:[],onToggle:a=>{ag(b=>({...b,[_]:b[_]===a?"":a})),$(!1),aa(null)},onClose:()=>{$(!1),aa(null)}}),Z&&!_&&(0,b.jsx)(h.ModelPicker,{title:"Add models",note:"Click a model to add it, click again to remove. Then hit Apply.",groups:X,selected:ab,onToggle:function(a){ab.includes(a)?(ac(b=>b.filter(b=>b!==a)),ad===a&&ae("")):(ac(b=>[...b,a]),ad||ae(a))},onClose:()=>$(!1)})]})}])}];
|
|
2
2
|
|
|
3
3
|
//# sourceMappingURL=src_components_ToolDetail_tsx_0qperd-._.js.map
|