@tonyclaw/llm-inspector 1.14.1 → 1.14.3
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/.output/nitro.json +1 -1
- package/.output/public/assets/index-6F6Tf88s.js +105 -0
- package/.output/public/assets/index-CzrT_ZB_.css +1 -0
- package/.output/public/assets/{main-BzK2SzIB.js → main-BcEfx6FM.js} +3 -3
- package/.output/server/_ssr/{index-Cso39vJc.mjs → index-BbJkYeb-.mjs} +212 -116
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-B8X3GXM2.mjs → router-Cz7UcQ5N.mjs} +539 -286
- package/.output/server/{_tanstack-start-manifest_v-vO4aM6jK.mjs → _tanstack-start-manifest_v-DxqMZv-B.mjs} +1 -1
- package/.output/server/index.mjs +20 -20
- package/package.json +1 -1
- package/src/components/providers/ProviderCard.tsx +111 -6
- package/src/components/providers/ProviderForm.tsx +125 -39
- package/src/components/providers/ProvidersPanel.tsx +16 -7
- package/src/components/providers/SettingsDialog.tsx +1 -1
- package/src/lib/providerContract.ts +1 -0
- package/src/lib/providerTestContract.ts +8 -0
- package/src/proxy/providers.ts +119 -21
- package/src/routes/api/providers.$providerId.test.log.ts +293 -0
- package/src/routes/api/providers.$providerId.ts +2 -1
- package/src/routes/api/providers.ts +3 -2
- package/styles/globals.css +121 -121
- package/.output/public/assets/index-DEUddp_2.css +0 -1
- package/.output/public/assets/index-ax85pt2A.js +0 -105
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports, a as React } from "../_libs/react.mjs";
|
|
2
|
-
import { C as CapturedLogSchema, a as parseRequest, s as stripClaudeCodeBillingHeader, R as RuntimeConfigSchema, P as ProviderConfigSchema, p as parseOpenAIResponse, I as InspectorResponseSchema
|
|
2
|
+
import { C as CapturedLogSchema, a as parseRequest, s as stripClaudeCodeBillingHeader, R as RuntimeConfigSchema, c as createPendingProviderTestResults, P as ProviderTestResultsSchema, b as createFailedProviderTestResults, d as ProviderConfigSchema, p as parseOpenAIResponse, I as InspectorResponseSchema } from "./router-Cz7UcQ5N.mjs";
|
|
3
3
|
import { u as useSWR, a as useSWRConfig } from "../_libs/swr.mjs";
|
|
4
4
|
import { u as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
|
|
5
5
|
import { J as JSZip } from "../_libs/jszip.mjs";
|
|
@@ -12,7 +12,7 @@ import { R as Root2, T as Trigger, I as Icon, V as Value, P as Portal, C as Cont
|
|
|
12
12
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
13
13
|
import { D as Download, L as LayoutGrid, a as List, G as GitCompareArrows, X, S as Settings, C as ChevronDown, b as Check, R as RotateCcw, U as Upload, P as Plus, c as Copy, d as CircleAlert, e as ChevronUp, f as ChevronRight, g as Clock, M as MessageSquare, Z as Zap, h as LoaderCircle, W as Wrench, i as Globe, j as User, F as FileTerminal, k as Radio, l as Rows3, m as Columns2, n as Minus, o as Pencil, E as Equal, p as EyeOff, q as Eye, r as ExternalLink, s as RotateCw, T as Trash2, A as ArrowUp, t as ArrowDown, u as TriangleAlert, v as CircleCheckBig, w as CircleStop, x as CircleQuestionMark, y as Server, z as Gauge, B as Lock, H as Wifi, I as WifiOff, J as ChevronsUp, K as ChevronsDown, N as Brain, O as Terminal } from "../_libs/lucide-react.mjs";
|
|
14
14
|
import { M as Markdown } from "../_libs/react-markdown.mjs";
|
|
15
|
-
import { a as array, b as string, u as union, d as object, l as literal, n as number, c as boolean
|
|
15
|
+
import { a as array, b as string, u as union, d as object, l as literal, n as number, c as boolean } from "../_libs/zod.mjs";
|
|
16
16
|
import { R as Root2$1, L as List$1, T as Trigger$2, C as Content$1 } from "../_libs/radix-ui__react-tabs.mjs";
|
|
17
17
|
import { S as Slot } from "../_libs/radix-ui__react-slot.mjs";
|
|
18
18
|
import { P as Provider, R as Root3, T as Trigger$3, a as Portal$2, C as Content2$1, A as Arrow2 } from "../_libs/radix-ui__react-tooltip.mjs";
|
|
@@ -276,7 +276,7 @@ async function exportLogsAsZip(logs) {
|
|
|
276
276
|
document.body.removeChild(anchor);
|
|
277
277
|
URL.revokeObjectURL(url);
|
|
278
278
|
}
|
|
279
|
-
const version = "1.14.
|
|
279
|
+
const version = "1.14.3";
|
|
280
280
|
const packageJson = {
|
|
281
281
|
version
|
|
282
282
|
};
|
|
@@ -2984,6 +2984,19 @@ function TestStatus({ result }) {
|
|
|
2984
2984
|
] })
|
|
2985
2985
|
] });
|
|
2986
2986
|
}
|
|
2987
|
+
function formatTimeAgo(isoString) {
|
|
2988
|
+
const now = Date.now();
|
|
2989
|
+
const then = new Date(isoString).getTime();
|
|
2990
|
+
const diffMs = now - then;
|
|
2991
|
+
const diffSec = Math.floor(diffMs / 1e3);
|
|
2992
|
+
if (diffSec < 60) return "just now";
|
|
2993
|
+
const diffMin = Math.floor(diffSec / 60);
|
|
2994
|
+
if (diffMin < 60) return `${diffMin}m ago`;
|
|
2995
|
+
const diffHr = Math.floor(diffMin / 60);
|
|
2996
|
+
if (diffHr < 24) return `${diffHr}h ago`;
|
|
2997
|
+
const diffDay = Math.floor(diffHr / 24);
|
|
2998
|
+
return `${diffDay}d ago`;
|
|
2999
|
+
}
|
|
2987
3000
|
function ProviderCard({
|
|
2988
3001
|
provider,
|
|
2989
3002
|
testResults,
|
|
@@ -2996,6 +3009,27 @@ function ProviderCard({
|
|
|
2996
3009
|
}) {
|
|
2997
3010
|
const [showApiKey, setShowApiKey] = reactExports.useState(false);
|
|
2998
3011
|
const [copied, setCopied] = reactExports.useState(false);
|
|
3012
|
+
const [showModelResults, setShowModelResults] = reactExports.useState(false);
|
|
3013
|
+
const hasLoggedRef = reactExports.useRef(null);
|
|
3014
|
+
const lastTestedAtRef = reactExports.useRef(void 0);
|
|
3015
|
+
if (testResults?.testedAt !== void 0 && testResults.testedAt !== lastTestedAtRef.current) {
|
|
3016
|
+
lastTestedAtRef.current = testResults.testedAt;
|
|
3017
|
+
hasLoggedRef.current = null;
|
|
3018
|
+
}
|
|
3019
|
+
const handleToggleModelResults = reactExports.useCallback(() => {
|
|
3020
|
+
setShowModelResults((v) => {
|
|
3021
|
+
const next = !v;
|
|
3022
|
+
if (next && hasLoggedRef.current === null && testResults?.models !== void 0) {
|
|
3023
|
+
hasLoggedRef.current = testResults.testedAt ?? "";
|
|
3024
|
+
void fetch(`/api/providers/${provider.id}/test/log`, {
|
|
3025
|
+
method: "POST",
|
|
3026
|
+
headers: { "Content-Type": "application/json" },
|
|
3027
|
+
body: JSON.stringify(testResults)
|
|
3028
|
+
});
|
|
3029
|
+
}
|
|
3030
|
+
return next;
|
|
3031
|
+
});
|
|
3032
|
+
}, [provider.id, testResults]);
|
|
2999
3033
|
function handleCopy() {
|
|
3000
3034
|
navigator.clipboard.writeText(provider.apiKey).catch(() => {
|
|
3001
3035
|
});
|
|
@@ -3012,7 +3046,7 @@ function ProviderCard({
|
|
|
3012
3046
|
children: [
|
|
3013
3047
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
3014
3048
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
3015
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium truncate", children: provider.
|
|
3049
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium truncate", children: provider.name }),
|
|
3016
3050
|
provider.source === "company" && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs px-1.5 py-0.5 rounded bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400 shrink-0", children: "公司" }),
|
|
3017
3051
|
provider.source === "personal" && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs px-1.5 py-0.5 rounded bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400 shrink-0", children: "个人" })
|
|
3018
3052
|
] }),
|
|
@@ -3031,6 +3065,7 @@ function ProviderCard({
|
|
|
3031
3065
|
}
|
|
3032
3066
|
)
|
|
3033
3067
|
] }),
|
|
3068
|
+
provider.models !== void 0 && provider.models.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1", children: provider.models.map((m) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs px-1.5 py-0.5 rounded bg-muted text-muted-foreground", children: m }, m)) }),
|
|
3034
3069
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3035
3070
|
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "text-xs text-muted-foreground bg-muted px-2 py-1 rounded flex-1 truncate", children: showApiKey ? provider.apiKey : maskApiKey(provider.apiKey) }),
|
|
3036
3071
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -3070,6 +3105,41 @@ function ProviderCard({
|
|
|
3070
3105
|
] }),
|
|
3071
3106
|
testResults && /* @__PURE__ */ jsxRuntimeExports.jsx(TestStatus, { result: testResults.openai.nonStreaming })
|
|
3072
3107
|
] }),
|
|
3108
|
+
testResults?.testedAt !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-muted-foreground flex items-center gap-1", children: [
|
|
3109
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
3110
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
3111
|
+
"Tested ",
|
|
3112
|
+
formatTimeAgo(testResults.testedAt)
|
|
3113
|
+
] })
|
|
3114
|
+
] }),
|
|
3115
|
+
testResults?.models !== void 0 && Object.keys(testResults.models).length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t pt-2", children: [
|
|
3116
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3117
|
+
"button",
|
|
3118
|
+
{
|
|
3119
|
+
type: "button",
|
|
3120
|
+
onClick: handleToggleModelResults,
|
|
3121
|
+
className: "text-xs text-muted-foreground hover:text-foreground transition-colors flex items-center gap-1",
|
|
3122
|
+
children: [
|
|
3123
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: showModelResults ? "▾" : "▸" }),
|
|
3124
|
+
"Model Test Results (",
|
|
3125
|
+
Object.keys(testResults.models).length,
|
|
3126
|
+
")"
|
|
3127
|
+
]
|
|
3128
|
+
}
|
|
3129
|
+
),
|
|
3130
|
+
showModelResults && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 overflow-x-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-xs border-collapse", children: [
|
|
3131
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-border", children: [
|
|
3132
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left py-1 px-2 font-medium text-muted-foreground", children: "Model" }),
|
|
3133
|
+
provider.anthropicBaseUrl !== void 0 && provider.anthropicBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left py-1 px-2 font-medium text-muted-foreground", children: "Anthropic" }),
|
|
3134
|
+
provider.openaiBaseUrl !== void 0 && provider.openaiBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left py-1 px-2 font-medium text-muted-foreground", children: "OpenAI" })
|
|
3135
|
+
] }) }),
|
|
3136
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: Object.entries(testResults.models).map(([modelName, modelResult]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-border/50 last:border-0", children: [
|
|
3137
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-1 px-2 font-medium", children: modelName }),
|
|
3138
|
+
provider.anthropicBaseUrl !== void 0 && provider.anthropicBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-1 px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(TestStatus, { result: modelResult.anthropic.nonStreaming }) }),
|
|
3139
|
+
provider.openaiBaseUrl !== void 0 && provider.openaiBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-1 px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(TestStatus, { result: modelResult.openai.nonStreaming }) })
|
|
3140
|
+
] }, modelName)) })
|
|
3141
|
+
] }) })
|
|
3142
|
+
] }),
|
|
3073
3143
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 pt-1 border-t", children: [
|
|
3074
3144
|
onTest !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3075
3145
|
Button,
|
|
@@ -3143,11 +3213,14 @@ const MINIMAX_MODELS = [
|
|
|
3143
3213
|
];
|
|
3144
3214
|
const ALIBABA_MODELS = ["glm-5", "glm-5.1", "qwen3.6-plus", "qwen3.7-max"];
|
|
3145
3215
|
function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
3146
|
-
const [name, setName] = reactExports.useState(provider?.name ?? "
|
|
3216
|
+
const [name, setName] = reactExports.useState(provider?.name ?? "");
|
|
3147
3217
|
const [apiKey, setApiKey] = reactExports.useState(provider?.apiKey ?? "");
|
|
3148
3218
|
const [showApiKey, setShowApiKey] = reactExports.useState(false);
|
|
3149
3219
|
const [copied, setCopied] = reactExports.useState(false);
|
|
3150
|
-
const
|
|
3220
|
+
const initialModels = provider?.models;
|
|
3221
|
+
const [models, setModels] = reactExports.useState(
|
|
3222
|
+
initialModels !== void 0 && initialModels.length > 0 ? initialModels : [""]
|
|
3223
|
+
);
|
|
3151
3224
|
const [activeTab, setActiveTab] = reactExports.useState("anthropic");
|
|
3152
3225
|
const [anthropicBaseUrl, setAnthropicBaseUrl] = reactExports.useState(provider?.anthropicBaseUrl ?? "");
|
|
3153
3226
|
const [openaiBaseUrl, setOpenaiBaseUrl] = reactExports.useState(provider?.openaiBaseUrl ?? "");
|
|
@@ -3155,6 +3228,21 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
3155
3228
|
const [source, setSource] = reactExports.useState(provider?.source);
|
|
3156
3229
|
const [errors, setErrors] = reactExports.useState({});
|
|
3157
3230
|
const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
|
|
3231
|
+
const [openModelDropdown, setOpenModelDropdown] = reactExports.useState(null);
|
|
3232
|
+
const modelRowRefs = reactExports.useRef([]);
|
|
3233
|
+
reactExports.useEffect(() => {
|
|
3234
|
+
if (openModelDropdown === null) return;
|
|
3235
|
+
const index = openModelDropdown;
|
|
3236
|
+
function handleClick(e) {
|
|
3237
|
+
if (!(e.target instanceof Node)) return;
|
|
3238
|
+
const ref = modelRowRefs.current[index];
|
|
3239
|
+
if (ref !== null && ref !== void 0 && !ref.contains(e.target)) {
|
|
3240
|
+
setOpenModelDropdown(null);
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
document.addEventListener("mousedown", handleClick);
|
|
3244
|
+
return () => document.removeEventListener("mousedown", handleClick);
|
|
3245
|
+
}, [openModelDropdown]);
|
|
3158
3246
|
const [manualAnthropicUrlOverride, setManualAnthropicUrlOverride] = reactExports.useState(false);
|
|
3159
3247
|
const [manualOpenaiUrlOverride, setManualOpenaiUrlOverride] = reactExports.useState(false);
|
|
3160
3248
|
const isMiniMax = name.toLowerCase().includes("minimax");
|
|
@@ -3169,7 +3257,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
3169
3257
|
if (provider) {
|
|
3170
3258
|
setName(provider.name);
|
|
3171
3259
|
setApiKey(provider.apiKey);
|
|
3172
|
-
|
|
3260
|
+
setModels((provider.models?.length ?? 0) > 0 ? provider.models : [""]);
|
|
3173
3261
|
setAnthropicBaseUrl(provider.anthropicBaseUrl ?? "");
|
|
3174
3262
|
setOpenaiBaseUrl(provider.openaiBaseUrl ?? "");
|
|
3175
3263
|
setApiDocsUrl(provider.apiDocsUrl ?? "");
|
|
@@ -3190,11 +3278,11 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
3190
3278
|
if (preset.apiDocsUrl !== void 0 && !apiDocsUrl) {
|
|
3191
3279
|
setApiDocsUrl(preset.apiDocsUrl);
|
|
3192
3280
|
}
|
|
3193
|
-
if (keyword === "minimax" &&
|
|
3194
|
-
|
|
3281
|
+
if (keyword === "minimax" && models.length === 1 && models[0] === "") {
|
|
3282
|
+
setModels([MINIMAX_MODELS[0] ?? ""]);
|
|
3195
3283
|
}
|
|
3196
|
-
if (keyword === "alibaba" &&
|
|
3197
|
-
|
|
3284
|
+
if (keyword === "alibaba" && models.length === 1 && models[0] === "") {
|
|
3285
|
+
setModels([ALIBABA_MODELS[0] ?? ""]);
|
|
3198
3286
|
}
|
|
3199
3287
|
break;
|
|
3200
3288
|
}
|
|
@@ -3208,8 +3296,8 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
3208
3296
|
if (!apiKey.trim()) {
|
|
3209
3297
|
newErrors.apiKey = "API key is required";
|
|
3210
3298
|
}
|
|
3211
|
-
if (!
|
|
3212
|
-
newErrors.
|
|
3299
|
+
if (models.length === 0 || models.every((m) => !m.trim())) {
|
|
3300
|
+
newErrors.models = "At least one model is required";
|
|
3213
3301
|
}
|
|
3214
3302
|
if (anthropicBaseUrl.trim() && !isValidUrl(anthropicBaseUrl.trim())) {
|
|
3215
3303
|
newErrors.anthropicBaseUrl = "Invalid URL format";
|
|
@@ -3239,7 +3327,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
3239
3327
|
onSubmit({
|
|
3240
3328
|
name: name.trim(),
|
|
3241
3329
|
apiKey: apiKey.trim(),
|
|
3242
|
-
|
|
3330
|
+
models: models.map((m) => m.trim()).filter((m) => m !== ""),
|
|
3243
3331
|
anthropicBaseUrl: anthropicBaseUrl.trim() || void 0,
|
|
3244
3332
|
openaiBaseUrl: openaiBaseUrl.trim() || void 0,
|
|
3245
3333
|
apiDocsUrl: apiDocsUrl.trim() || void 0,
|
|
@@ -3262,7 +3350,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
3262
3350
|
type: "text",
|
|
3263
3351
|
value: name,
|
|
3264
3352
|
onChange: (e) => setName(e.target.value),
|
|
3265
|
-
placeholder: "
|
|
3353
|
+
placeholder: "Provider Name",
|
|
3266
3354
|
className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:border-ring focus-visible:outline-ring focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50"
|
|
3267
3355
|
}
|
|
3268
3356
|
),
|
|
@@ -3333,31 +3421,107 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
3333
3421
|
errors.apiKey !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.apiKey })
|
|
3334
3422
|
] }),
|
|
3335
3423
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
3336
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", {
|
|
3337
|
-
"
|
|
3424
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-sm font-medium", children: [
|
|
3425
|
+
"Models ",
|
|
3338
3426
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
|
|
3339
3427
|
] }),
|
|
3340
|
-
|
|
3341
|
-
"
|
|
3428
|
+
models.map((m, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3429
|
+
"div",
|
|
3342
3430
|
{
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
className: "
|
|
3347
|
-
children:
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3431
|
+
ref: (el) => {
|
|
3432
|
+
modelRowRefs.current[i] = el;
|
|
3433
|
+
},
|
|
3434
|
+
className: "flex items-center gap-2",
|
|
3435
|
+
children: [
|
|
3436
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex-1", children: [
|
|
3437
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3438
|
+
"input",
|
|
3439
|
+
{
|
|
3440
|
+
type: "text",
|
|
3441
|
+
value: m,
|
|
3442
|
+
onChange: (e) => {
|
|
3443
|
+
setModels((prev) => {
|
|
3444
|
+
const next = [...prev];
|
|
3445
|
+
next[i] = e.target.value;
|
|
3446
|
+
return next;
|
|
3447
|
+
});
|
|
3448
|
+
},
|
|
3449
|
+
placeholder: isMiniMax || isAlibaba ? "Type or select a model..." : "Model name",
|
|
3450
|
+
className: "w-full rounded-md border border-input bg-background px-4 py-3 pr-8 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:border-ring focus-visible:outline-ring focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50"
|
|
3451
|
+
}
|
|
3452
|
+
),
|
|
3453
|
+
(isMiniMax || isAlibaba) && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3454
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3455
|
+
"button",
|
|
3456
|
+
{
|
|
3457
|
+
type: "button",
|
|
3458
|
+
onClick: () => setOpenModelDropdown(openModelDropdown === i ? null : i),
|
|
3459
|
+
className: "absolute right-1 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors p-1 z-10",
|
|
3460
|
+
"aria-label": "Show model suggestions",
|
|
3461
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" })
|
|
3462
|
+
}
|
|
3463
|
+
),
|
|
3464
|
+
openModelDropdown === i && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute left-0 right-0 top-full mt-1 z-50 bg-popover border border-border rounded-md shadow-md max-h-48 overflow-y-auto", children: (isMiniMax ? MINIMAX_MODELS : ALIBABA_MODELS).map((opt) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3465
|
+
"button",
|
|
3466
|
+
{
|
|
3467
|
+
type: "button",
|
|
3468
|
+
onClick: () => {
|
|
3469
|
+
setModels((prev) => {
|
|
3470
|
+
const next = [...prev];
|
|
3471
|
+
next[i] = opt;
|
|
3472
|
+
return next;
|
|
3473
|
+
});
|
|
3474
|
+
setOpenModelDropdown(null);
|
|
3475
|
+
},
|
|
3476
|
+
className: "w-full text-left px-3 py-2 text-sm hover:bg-muted transition-colors",
|
|
3477
|
+
children: opt
|
|
3478
|
+
},
|
|
3479
|
+
opt
|
|
3480
|
+
)) })
|
|
3481
|
+
] })
|
|
3482
|
+
] }),
|
|
3483
|
+
models.length > 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3484
|
+
"button",
|
|
3485
|
+
{
|
|
3486
|
+
type: "button",
|
|
3487
|
+
onClick: () => setModels((prev) => prev.filter((_, idx) => idx !== i)),
|
|
3488
|
+
className: "text-muted-foreground hover:text-destructive transition-colors p-1 shrink-0",
|
|
3489
|
+
"aria-label": "Remove model",
|
|
3490
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3491
|
+
"svg",
|
|
3492
|
+
{
|
|
3493
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3494
|
+
width: "16",
|
|
3495
|
+
height: "16",
|
|
3496
|
+
viewBox: "0 0 24 24",
|
|
3497
|
+
fill: "none",
|
|
3498
|
+
stroke: "currentColor",
|
|
3499
|
+
strokeWidth: "2",
|
|
3500
|
+
strokeLinecap: "round",
|
|
3501
|
+
strokeLinejoin: "round",
|
|
3502
|
+
children: [
|
|
3503
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M3 6h18" }),
|
|
3504
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" }),
|
|
3505
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" })
|
|
3506
|
+
]
|
|
3507
|
+
}
|
|
3508
|
+
)
|
|
3509
|
+
}
|
|
3510
|
+
)
|
|
3511
|
+
]
|
|
3512
|
+
},
|
|
3513
|
+
i
|
|
3514
|
+
)),
|
|
3515
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3516
|
+
"button",
|
|
3351
3517
|
{
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
placeholder: "",
|
|
3357
|
-
className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:border-ring focus-visible:outline-ring focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50"
|
|
3518
|
+
type: "button",
|
|
3519
|
+
onClick: () => setModels((prev) => [...prev, ""]),
|
|
3520
|
+
className: "text-xs text-primary hover:underline flex items-center gap-1",
|
|
3521
|
+
children: "+ Add Model"
|
|
3358
3522
|
}
|
|
3359
3523
|
),
|
|
3360
|
-
errors.
|
|
3524
|
+
errors.models !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.models })
|
|
3361
3525
|
] }),
|
|
3362
3526
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
3363
3527
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1 border-b border-border", children: [
|
|
@@ -3441,83 +3605,6 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
3441
3605
|
] })
|
|
3442
3606
|
] });
|
|
3443
3607
|
}
|
|
3444
|
-
const ProviderTestErrorTypeSchema = _enum([
|
|
3445
|
-
"timeout",
|
|
3446
|
-
"network_unreachable",
|
|
3447
|
-
"connection_refused",
|
|
3448
|
-
"auth_failed",
|
|
3449
|
-
"rate_limited",
|
|
3450
|
-
"server_error",
|
|
3451
|
-
"invalid_response",
|
|
3452
|
-
"unknown"
|
|
3453
|
-
]);
|
|
3454
|
-
const ProviderTestErrorSchema = object({
|
|
3455
|
-
message: string(),
|
|
3456
|
-
type: ProviderTestErrorTypeSchema,
|
|
3457
|
-
details: string().optional(),
|
|
3458
|
-
hint: string().optional()
|
|
3459
|
-
});
|
|
3460
|
-
const ProviderTestContentSchema = object({
|
|
3461
|
-
type: _enum(["text", "thinking"]),
|
|
3462
|
-
text: string().optional(),
|
|
3463
|
-
thinking: string().optional()
|
|
3464
|
-
});
|
|
3465
|
-
const ProviderTestResultSchema = object({
|
|
3466
|
-
success: boolean(),
|
|
3467
|
-
error: ProviderTestErrorSchema.optional(),
|
|
3468
|
-
model: string().optional(),
|
|
3469
|
-
inputTokens: number().optional(),
|
|
3470
|
-
outputTokens: number().optional(),
|
|
3471
|
-
cacheCreationInputTokens: number().optional(),
|
|
3472
|
-
cacheReadInputTokens: number().optional(),
|
|
3473
|
-
latencyMs: number().optional(),
|
|
3474
|
-
content: array(ProviderTestContentSchema).optional(),
|
|
3475
|
-
rawResponse: string().optional(),
|
|
3476
|
-
streaming: boolean().optional(),
|
|
3477
|
-
streamingChunks: object({
|
|
3478
|
-
chunks: array(StreamingChunkSchema$1),
|
|
3479
|
-
truncated: boolean().default(false)
|
|
3480
|
-
}).optional(),
|
|
3481
|
-
requestHeaders: record(string(), string()).optional()
|
|
3482
|
-
});
|
|
3483
|
-
const ProviderTestStateSchema = union([
|
|
3484
|
-
ProviderTestResultSchema,
|
|
3485
|
-
object({ notConfigured: literal(true) }),
|
|
3486
|
-
object({ testing: literal(true) })
|
|
3487
|
-
]);
|
|
3488
|
-
const ProviderFormatTestResultsSchema = object({
|
|
3489
|
-
nonStreaming: ProviderTestStateSchema,
|
|
3490
|
-
streaming: ProviderTestStateSchema
|
|
3491
|
-
});
|
|
3492
|
-
const ProviderTestResultsSchema = object({
|
|
3493
|
-
anthropic: ProviderFormatTestResultsSchema,
|
|
3494
|
-
openai: ProviderFormatTestResultsSchema
|
|
3495
|
-
});
|
|
3496
|
-
function createPendingProviderTestResults() {
|
|
3497
|
-
return {
|
|
3498
|
-
anthropic: {
|
|
3499
|
-
nonStreaming: { testing: true },
|
|
3500
|
-
streaming: { testing: true }
|
|
3501
|
-
},
|
|
3502
|
-
openai: {
|
|
3503
|
-
nonStreaming: { testing: true },
|
|
3504
|
-
streaming: { testing: true }
|
|
3505
|
-
}
|
|
3506
|
-
};
|
|
3507
|
-
}
|
|
3508
|
-
function createFailedProviderTestResults(message, type) {
|
|
3509
|
-
const createFormatResult = () => ({
|
|
3510
|
-
nonStreaming: {
|
|
3511
|
-
success: false,
|
|
3512
|
-
error: { message, type }
|
|
3513
|
-
},
|
|
3514
|
-
streaming: { notConfigured: true }
|
|
3515
|
-
});
|
|
3516
|
-
return {
|
|
3517
|
-
anthropic: createFormatResult(),
|
|
3518
|
-
openai: createFormatResult()
|
|
3519
|
-
};
|
|
3520
|
-
}
|
|
3521
3608
|
const ConfigPathsResponseSchema = object({
|
|
3522
3609
|
providerConfig: string()
|
|
3523
3610
|
});
|
|
@@ -3533,7 +3620,7 @@ function createProviderPayload(data) {
|
|
|
3533
3620
|
return {
|
|
3534
3621
|
name: data.name,
|
|
3535
3622
|
apiKey: data.apiKey,
|
|
3536
|
-
|
|
3623
|
+
models: data.models,
|
|
3537
3624
|
anthropicBaseUrl: (data.anthropicBaseUrl?.length ?? 0) > 0 ? data.anthropicBaseUrl : void 0,
|
|
3538
3625
|
openaiBaseUrl: (data.openaiBaseUrl?.length ?? 0) > 0 ? data.openaiBaseUrl : void 0,
|
|
3539
3626
|
apiDocsUrl: (data.apiDocsUrl?.length ?? 0) > 0 ? data.apiDocsUrl : void 0,
|
|
@@ -3566,7 +3653,16 @@ function ProvidersPanel({
|
|
|
3566
3653
|
const listScrollRef = reactExports.useRef(null);
|
|
3567
3654
|
const highlightTimeoutRef = reactExports.useRef(null);
|
|
3568
3655
|
const providers = externalProviders ?? [];
|
|
3569
|
-
const filteredProviders =
|
|
3656
|
+
const filteredProviders = reactExports.useMemo(() => {
|
|
3657
|
+
const filtered = sourceFilter === "all" ? providers : providers.filter((p) => p.source === sourceFilter);
|
|
3658
|
+
if (sourceFilter === "all") {
|
|
3659
|
+
return [...filtered].sort((a, b) => {
|
|
3660
|
+
const order = { personal: 0, company: 1 };
|
|
3661
|
+
return (order[a.source ?? ""] ?? 2) - (order[b.source ?? ""] ?? 2);
|
|
3662
|
+
});
|
|
3663
|
+
}
|
|
3664
|
+
return filtered;
|
|
3665
|
+
}, [providers, sourceFilter]);
|
|
3570
3666
|
const testResults = externalTestResults ?? internalTestResults;
|
|
3571
3667
|
const testingProviders = externalTestingProviders ?? internalTestingProviders;
|
|
3572
3668
|
const testingTimeLeft = externalTestingTimeLeft ?? internalTestingTimeLeft;
|
|
@@ -3731,7 +3827,7 @@ function ProvidersPanel({
|
|
|
3731
3827
|
setEditingProvider(void 0);
|
|
3732
3828
|
triggerHighlight(updated.id);
|
|
3733
3829
|
refreshProviders();
|
|
3734
|
-
const criticalFieldsChanged = (data.apiKey ?? "") !== (editingProvider.apiKey ?? "") || (data.
|
|
3830
|
+
const criticalFieldsChanged = (data.apiKey ?? "") !== (editingProvider.apiKey ?? "") || JSON.stringify(data.models) !== JSON.stringify(editingProvider.models) || (data.anthropicBaseUrl ?? "") !== (editingProvider.anthropicBaseUrl ?? "") || (data.openaiBaseUrl ?? "") !== (editingProvider.openaiBaseUrl ?? "");
|
|
3735
3831
|
if (criticalFieldsChanged) {
|
|
3736
3832
|
await runTest(updated.id);
|
|
3737
3833
|
}
|
|
@@ -3817,7 +3913,7 @@ function ProvidersPanel({
|
|
|
3817
3913
|
}
|
|
3818
3914
|
if (showForm || editingProvider) {
|
|
3819
3915
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
3820
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium", children: editingProvider ? "Edit Provider" : "Add New Provider" }) }),
|
|
3916
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between sticky top-0 bg-background z-10 pb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium", children: editingProvider ? "Edit Provider" : "Add New Provider" }) }),
|
|
3821
3917
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3822
3918
|
ProviderForm,
|
|
3823
3919
|
{
|
|
@@ -4009,7 +4105,7 @@ function SettingsDialog() {
|
|
|
4009
4105
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "providers", children: "Providers" }),
|
|
4010
4106
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "proxy", children: "Proxy" })
|
|
4011
4107
|
] }),
|
|
4012
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 overflow-y-auto flex-1", children: [
|
|
4108
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 overflow-y-auto flex-1 pr-3", children: [
|
|
4013
4109
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "providers", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4014
4110
|
ProvidersPanel,
|
|
4015
4111
|
{
|
|
@@ -198,7 +198,7 @@ function getResponse() {
|
|
|
198
198
|
return event.res;
|
|
199
199
|
}
|
|
200
200
|
async function getStartManifest(matchedRoutes) {
|
|
201
|
-
const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-
|
|
201
|
+
const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-DxqMZv-B.mjs");
|
|
202
202
|
const startManifest = tsrStartManifest();
|
|
203
203
|
const rootRoute = startManifest.routes[rootRouteId] = startManifest.routes[rootRouteId] || {};
|
|
204
204
|
rootRoute.assets = rootRoute.assets || [];
|
|
@@ -767,7 +767,7 @@ let entriesPromise;
|
|
|
767
767
|
let baseManifestPromise;
|
|
768
768
|
let cachedFinalManifestPromise;
|
|
769
769
|
async function loadEntries() {
|
|
770
|
-
const routerEntry = await import("./router-
|
|
770
|
+
const routerEntry = await import("./router-Cz7UcQ5N.mjs").then((n) => n.r);
|
|
771
771
|
const startEntry = await import("./start-HYkvq4Ni.mjs");
|
|
772
772
|
return { startEntry, routerEntry };
|
|
773
773
|
}
|