@tonyclaw/llm-inspector 1.14.2 → 1.14.4
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-5yrjXc3u.js +105 -0
- package/.output/public/assets/index-o0Ui96SM.css +1 -0
- package/.output/public/assets/{main-BElVT2p3.js → main-CC0TDCAo.js} +1 -1
- package/.output/server/_libs/lucide-react.mjs +113 -105
- package/.output/server/_ssr/{index-DmLit8Ad.mjs → index-Cz6oxzsy.mjs} +350 -55
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-BoeSXWHG.mjs → router-Bl3OCdGC.mjs} +229 -33
- package/.output/server/_tanstack-start-manifest_v-Oekf1osO.mjs +4 -0
- package/.output/server/index.mjs +22 -22
- package/package.json +1 -1
- package/src/components/providers/ImportWizardDialog.tsx +281 -0
- package/src/components/providers/ProviderCard.tsx +2 -0
- package/src/components/providers/ProviderForm.tsx +76 -26
- package/src/components/providers/ProvidersPanel.tsx +35 -5
- package/src/components/providers/SettingsDialog.tsx +1 -1
- package/src/proxy/providerImporters.ts +235 -0
- package/src/routes/api/providers.scan.ts +23 -0
- package/styles/globals.css +121 -121
- package/.output/public/assets/index-DDrUlr6L.js +0 -105
- package/.output/public/assets/index-DOG5AdQ9.css +0 -1
- package/.output/server/_tanstack-start-manifest_v-B6idtbmL.mjs +0 -4
|
@@ -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, c as createPendingProviderTestResults, P as ProviderTestResultsSchema, b as createFailedProviderTestResults, d as ProviderConfigSchema, p as parseOpenAIResponse, I as InspectorResponseSchema } from "./router-
|
|
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-Bl3OCdGC.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";
|
|
@@ -10,9 +10,9 @@ import { d as diffLines, a as diffJson } from "../_libs/diff.mjs";
|
|
|
10
10
|
import { R as Root, T as Trigger$1, C as Content, a as Close, b as Title, P as Portal$1, O as Overlay } from "../_libs/radix-ui__react-dialog.mjs";
|
|
11
11
|
import { R as Root2, T as Trigger, I as Icon, V as Value, P as Portal, C as Content2, a as Viewport, b as Item, c as ItemIndicator, d as ItemText, S as ScrollUpButton, e as ScrollDownButton } from "../_libs/radix-ui__react-select.mjs";
|
|
12
12
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
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,
|
|
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, c as Scan, P as Plus, d as Copy, e as CircleAlert, f as ChevronUp, g as ChevronRight, h as Clock, M as MessageSquare, Z as Zap, i as LoaderCircle, W as Wrench, j as Globe, k as User, F as FileTerminal, l as Radio, m as Rows3, n as Columns2, o as Minus, p as Pencil, E as Equal, q as EyeOff, r as Eye, s as ExternalLink, t as RotateCw, T as Trash2, A as ArrowUp, u as ArrowDown, v as TriangleAlert, w as CircleCheckBig, x as CircleStop, y as CircleQuestionMark, z as Server, B as Gauge, H as Lock, I as Wifi, J as WifiOff, K as ChevronsUp, N as ChevronsDown, O as Brain, Q 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 } from "../_libs/zod.mjs";
|
|
15
|
+
import { a as array, b as string, u as union, d as object, l as literal, n as number, c as boolean, _ as _enum } 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.4";
|
|
280
280
|
const packageJson = {
|
|
281
281
|
version
|
|
282
282
|
};
|
|
@@ -2861,6 +2861,210 @@ function SelectScrollDownButton({
|
|
|
2861
2861
|
}
|
|
2862
2862
|
);
|
|
2863
2863
|
}
|
|
2864
|
+
const ExternalProviderSchema = object({
|
|
2865
|
+
name: string(),
|
|
2866
|
+
apiKey: string(),
|
|
2867
|
+
format: _enum(["anthropic", "openai"]),
|
|
2868
|
+
anthropicBaseUrl: string(),
|
|
2869
|
+
openaiBaseUrl: string(),
|
|
2870
|
+
models: array(string()),
|
|
2871
|
+
sourceTool: _enum(["claude-code", "opencode"]),
|
|
2872
|
+
alreadyExists: boolean()
|
|
2873
|
+
});
|
|
2874
|
+
const ScanResponseSchema = object({
|
|
2875
|
+
providers: array(ExternalProviderSchema),
|
|
2876
|
+
warnings: array(string()).optional()
|
|
2877
|
+
});
|
|
2878
|
+
const ImportResponseSchema$1 = object({
|
|
2879
|
+
success: boolean().optional(),
|
|
2880
|
+
imported: number().optional(),
|
|
2881
|
+
message: string().optional(),
|
|
2882
|
+
errors: array(string()).optional()
|
|
2883
|
+
});
|
|
2884
|
+
function ImportWizardDialog({
|
|
2885
|
+
open,
|
|
2886
|
+
onOpenChange,
|
|
2887
|
+
onImportComplete
|
|
2888
|
+
}) {
|
|
2889
|
+
const [scanning, setScanning] = reactExports.useState(false);
|
|
2890
|
+
const [scanError, setScanError] = reactExports.useState(null);
|
|
2891
|
+
const [providers, setProviders] = reactExports.useState([]);
|
|
2892
|
+
const [warnings, setWarnings] = reactExports.useState([]);
|
|
2893
|
+
const [selected, setSelected] = reactExports.useState(/* @__PURE__ */ new Set());
|
|
2894
|
+
const [importing, setImporting] = reactExports.useState(false);
|
|
2895
|
+
const [importResult, setImportResult] = reactExports.useState(null);
|
|
2896
|
+
const [importError, setImportError] = reactExports.useState(null);
|
|
2897
|
+
const scan = reactExports.useCallback(() => {
|
|
2898
|
+
setScanning(true);
|
|
2899
|
+
setScanError(null);
|
|
2900
|
+
setWarnings([]);
|
|
2901
|
+
setProviders([]);
|
|
2902
|
+
setSelected(/* @__PURE__ */ new Set());
|
|
2903
|
+
setImportResult(null);
|
|
2904
|
+
setImportError(null);
|
|
2905
|
+
fetch("/api/providers/scan").then((res) => {
|
|
2906
|
+
if (!res.ok) {
|
|
2907
|
+
return res.text().then((text) => {
|
|
2908
|
+
setScanError(`Scan failed (${res.status}): ${text}`);
|
|
2909
|
+
});
|
|
2910
|
+
}
|
|
2911
|
+
return res.json().then((data) => {
|
|
2912
|
+
const parsed = ScanResponseSchema.safeParse(data);
|
|
2913
|
+
if (!parsed.success) {
|
|
2914
|
+
setScanError(`Invalid response: ${parsed.error.message}`);
|
|
2915
|
+
return;
|
|
2916
|
+
}
|
|
2917
|
+
setProviders(parsed.data.providers);
|
|
2918
|
+
setWarnings(parsed.data.warnings ?? []);
|
|
2919
|
+
const indices = /* @__PURE__ */ new Set();
|
|
2920
|
+
parsed.data.providers.forEach((p, i) => {
|
|
2921
|
+
if (!p.alreadyExists) indices.add(i);
|
|
2922
|
+
});
|
|
2923
|
+
setSelected(indices);
|
|
2924
|
+
});
|
|
2925
|
+
}).catch((err) => {
|
|
2926
|
+
setScanError(err instanceof Error ? err.message : String(err));
|
|
2927
|
+
}).finally(() => {
|
|
2928
|
+
setScanning(false);
|
|
2929
|
+
});
|
|
2930
|
+
}, []);
|
|
2931
|
+
reactExports.useEffect(() => {
|
|
2932
|
+
if (open) {
|
|
2933
|
+
scan();
|
|
2934
|
+
}
|
|
2935
|
+
}, [open, scan]);
|
|
2936
|
+
const toggleProvider = reactExports.useCallback((index) => {
|
|
2937
|
+
setSelected((prev) => {
|
|
2938
|
+
const next = new Set(prev);
|
|
2939
|
+
if (next.has(index)) {
|
|
2940
|
+
next.delete(index);
|
|
2941
|
+
} else {
|
|
2942
|
+
next.add(index);
|
|
2943
|
+
}
|
|
2944
|
+
return next;
|
|
2945
|
+
});
|
|
2946
|
+
}, []);
|
|
2947
|
+
const importSelected = reactExports.useCallback(() => {
|
|
2948
|
+
const toImport = providers.filter((_, i) => selected.has(i));
|
|
2949
|
+
if (toImport.length === 0) return;
|
|
2950
|
+
setImporting(true);
|
|
2951
|
+
setImportError(null);
|
|
2952
|
+
setImportResult(null);
|
|
2953
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2954
|
+
const providersPayload = toImport.map((p) => ({
|
|
2955
|
+
id: window.crypto.randomUUID(),
|
|
2956
|
+
name: p.name,
|
|
2957
|
+
apiKey: p.apiKey,
|
|
2958
|
+
format: p.format,
|
|
2959
|
+
anthropicBaseUrl: p.anthropicBaseUrl,
|
|
2960
|
+
openaiBaseUrl: p.openaiBaseUrl,
|
|
2961
|
+
models: p.models,
|
|
2962
|
+
createdAt: now,
|
|
2963
|
+
updatedAt: now
|
|
2964
|
+
}));
|
|
2965
|
+
fetch("/api/providers/import", {
|
|
2966
|
+
method: "POST",
|
|
2967
|
+
headers: { "Content-Type": "application/json" },
|
|
2968
|
+
body: JSON.stringify({ providers: providersPayload })
|
|
2969
|
+
}).then((res) => res.json()).then((data) => {
|
|
2970
|
+
const parsed = ImportResponseSchema$1.safeParse(data);
|
|
2971
|
+
if (!parsed.success) {
|
|
2972
|
+
setImportError(`Invalid response: ${parsed.error.message}`);
|
|
2973
|
+
return;
|
|
2974
|
+
}
|
|
2975
|
+
const result = parsed.data;
|
|
2976
|
+
if (result.errors !== void 0 && result.errors.length > 0 && result.message !== void 0) {
|
|
2977
|
+
setImportResult(result.message);
|
|
2978
|
+
} else {
|
|
2979
|
+
setImportResult(`Imported ${result.imported ?? toImport.length} provider(s)`);
|
|
2980
|
+
}
|
|
2981
|
+
onImportComplete();
|
|
2982
|
+
}).catch((err) => {
|
|
2983
|
+
setImportError(err instanceof Error ? err.message : String(err));
|
|
2984
|
+
}).finally(() => {
|
|
2985
|
+
setImporting(false);
|
|
2986
|
+
});
|
|
2987
|
+
}, [providers, selected, onImportComplete]);
|
|
2988
|
+
const hasSelectable = providers.some((p) => !p.alreadyExists);
|
|
2989
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-xl max-h-[80vh] overflow-hidden flex flex-col", children: [
|
|
2990
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [
|
|
2991
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Import from External Tools" }),
|
|
2992
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Detect provider configurations from Claude Code and OpenCode." })
|
|
2993
|
+
] }),
|
|
2994
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto space-y-3", children: [
|
|
2995
|
+
scanning && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-center py-8 gap-2 text-muted-foreground", children: [
|
|
2996
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin" }),
|
|
2997
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: "Scanning for external providers..." })
|
|
2998
|
+
] }),
|
|
2999
|
+
scanError !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-destructive text-sm py-4", children: [
|
|
3000
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "size-4" }),
|
|
3001
|
+
scanError
|
|
3002
|
+
] }),
|
|
3003
|
+
!scanning && scanError === null && providers.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-muted-foreground py-8 text-center", children: [
|
|
3004
|
+
"No external provider configurations found.",
|
|
3005
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
3006
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs", children: "Supported tools: Claude Code (~/.claude/settings.json), OpenCode (~/.config/opencode/opencode.json)" })
|
|
3007
|
+
] }),
|
|
3008
|
+
!scanning && providers.map((p, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3009
|
+
"label",
|
|
3010
|
+
{
|
|
3011
|
+
className: "flex items-start gap-3 p-3 border rounded-md cursor-pointer hover:bg-muted/50 has-[:disabled]:opacity-50 has-[:disabled]:cursor-not-allowed",
|
|
3012
|
+
children: [
|
|
3013
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3014
|
+
"input",
|
|
3015
|
+
{
|
|
3016
|
+
type: "checkbox",
|
|
3017
|
+
checked: selected.has(i),
|
|
3018
|
+
disabled: p.alreadyExists || importing,
|
|
3019
|
+
onChange: () => toggleProvider(i),
|
|
3020
|
+
className: "mt-0.5 size-4"
|
|
3021
|
+
}
|
|
3022
|
+
),
|
|
3023
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
3024
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3025
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium truncate", children: p.name }),
|
|
3026
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "secondary", className: "text-[10px] px-1.5 py-0", children: p.format }),
|
|
3027
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "text-[10px] px-1.5 py-0", children: p.sourceTool }),
|
|
3028
|
+
p.alreadyExists && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground", children: "Already added" })
|
|
3029
|
+
] }),
|
|
3030
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-muted-foreground mt-1 truncate", children: [
|
|
3031
|
+
p.models.slice(0, 4).join(", "),
|
|
3032
|
+
p.models.length > 4 ? ` +${p.models.length - 4} more` : ""
|
|
3033
|
+
] }),
|
|
3034
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground mt-0.5 truncate", children: p.format === "anthropic" ? p.anthropicBaseUrl : p.openaiBaseUrl }),
|
|
3035
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground mt-0.5 font-mono", children: p.apiKey.length > 8 ? `${p.apiKey.slice(0, 4)}••••${p.apiKey.slice(-4)}` : "••••" })
|
|
3036
|
+
] })
|
|
3037
|
+
]
|
|
3038
|
+
},
|
|
3039
|
+
`${p.sourceTool}-${p.name}`
|
|
3040
|
+
)),
|
|
3041
|
+
warnings.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground space-y-1 border-t pt-2", children: warnings.map((w, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
3042
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "size-3" }),
|
|
3043
|
+
w
|
|
3044
|
+
] }, i)) }),
|
|
3045
|
+
importResult !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-green-500 border-t pt-2", children: importResult }),
|
|
3046
|
+
importError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-destructive border-t pt-2", children: importError })
|
|
3047
|
+
] }),
|
|
3048
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between pt-3 border-t", children: [
|
|
3049
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "outline", size: "sm", onClick: scan, disabled: scanning, children: [
|
|
3050
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: `size-3 mr-1 ${scanning ? "animate-spin" : ""}` }),
|
|
3051
|
+
"Rescan"
|
|
3052
|
+
] }),
|
|
3053
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3054
|
+
Button,
|
|
3055
|
+
{
|
|
3056
|
+
size: "sm",
|
|
3057
|
+
onClick: importSelected,
|
|
3058
|
+
disabled: !hasSelectable || selected.size === 0 || importing,
|
|
3059
|
+
children: [
|
|
3060
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "size-3 mr-1" }),
|
|
3061
|
+
importing ? "Importing..." : `Import Selected (${selected.size})`
|
|
3062
|
+
]
|
|
3063
|
+
}
|
|
3064
|
+
)
|
|
3065
|
+
] })
|
|
3066
|
+
] }) });
|
|
3067
|
+
}
|
|
2864
3068
|
function maskApiKey(apiKey) {
|
|
2865
3069
|
if (apiKey.length <= 8) return "••••••••";
|
|
2866
3070
|
return apiKey.slice(0, 4) + "••••••••" + apiKey.slice(-4);
|
|
@@ -3162,6 +3366,7 @@ function ProviderCard({
|
|
|
3162
3366
|
size: "sm",
|
|
3163
3367
|
onClick: () => onEdit(provider),
|
|
3164
3368
|
className: "text-xs h-7 gap-1",
|
|
3369
|
+
disabled: isTesting ?? false,
|
|
3165
3370
|
children: [
|
|
3166
3371
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "size-3" }),
|
|
3167
3372
|
"Edit"
|
|
@@ -3175,6 +3380,7 @@ function ProviderCard({
|
|
|
3175
3380
|
size: "sm",
|
|
3176
3381
|
onClick: () => onDelete(provider.id),
|
|
3177
3382
|
className: "text-xs h-7 gap-1 text-destructive hover:text-destructive",
|
|
3383
|
+
disabled: isTesting ?? false,
|
|
3178
3384
|
children: [
|
|
3179
3385
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-3" }),
|
|
3180
3386
|
"Delete"
|
|
@@ -3213,7 +3419,7 @@ const MINIMAX_MODELS = [
|
|
|
3213
3419
|
];
|
|
3214
3420
|
const ALIBABA_MODELS = ["glm-5", "glm-5.1", "qwen3.6-plus", "qwen3.7-max"];
|
|
3215
3421
|
function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
3216
|
-
const [name, setName] = reactExports.useState(provider?.name ?? "
|
|
3422
|
+
const [name, setName] = reactExports.useState(provider?.name ?? "");
|
|
3217
3423
|
const [apiKey, setApiKey] = reactExports.useState(provider?.apiKey ?? "");
|
|
3218
3424
|
const [showApiKey, setShowApiKey] = reactExports.useState(false);
|
|
3219
3425
|
const [copied, setCopied] = reactExports.useState(false);
|
|
@@ -3228,6 +3434,21 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
3228
3434
|
const [source, setSource] = reactExports.useState(provider?.source);
|
|
3229
3435
|
const [errors, setErrors] = reactExports.useState({});
|
|
3230
3436
|
const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
|
|
3437
|
+
const [openModelDropdown, setOpenModelDropdown] = reactExports.useState(null);
|
|
3438
|
+
const modelRowRefs = reactExports.useRef([]);
|
|
3439
|
+
reactExports.useEffect(() => {
|
|
3440
|
+
if (openModelDropdown === null) return;
|
|
3441
|
+
const index = openModelDropdown;
|
|
3442
|
+
function handleClick(e) {
|
|
3443
|
+
if (!(e.target instanceof Node)) return;
|
|
3444
|
+
const ref = modelRowRefs.current[index];
|
|
3445
|
+
if (ref !== null && ref !== void 0 && !ref.contains(e.target)) {
|
|
3446
|
+
setOpenModelDropdown(null);
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
document.addEventListener("mousedown", handleClick);
|
|
3450
|
+
return () => document.removeEventListener("mousedown", handleClick);
|
|
3451
|
+
}, [openModelDropdown]);
|
|
3231
3452
|
const [manualAnthropicUrlOverride, setManualAnthropicUrlOverride] = reactExports.useState(false);
|
|
3232
3453
|
const [manualOpenaiUrlOverride, setManualOpenaiUrlOverride] = reactExports.useState(false);
|
|
3233
3454
|
const isMiniMax = name.toLowerCase().includes("minimax");
|
|
@@ -3335,7 +3556,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
3335
3556
|
type: "text",
|
|
3336
3557
|
value: name,
|
|
3337
3558
|
onChange: (e) => setName(e.target.value),
|
|
3338
|
-
placeholder: "
|
|
3559
|
+
placeholder: "Provider Name",
|
|
3339
3560
|
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"
|
|
3340
3561
|
}
|
|
3341
3562
|
),
|
|
@@ -3410,54 +3631,93 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
3410
3631
|
"Models ",
|
|
3411
3632
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
|
|
3412
3633
|
] }),
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3634
|
+
models.map((m, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3635
|
+
"div",
|
|
3636
|
+
{
|
|
3637
|
+
ref: (el) => {
|
|
3638
|
+
modelRowRefs.current[i] = el;
|
|
3639
|
+
},
|
|
3640
|
+
className: "flex items-center gap-2",
|
|
3641
|
+
children: [
|
|
3642
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex-1", children: [
|
|
3643
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3644
|
+
"input",
|
|
3645
|
+
{
|
|
3646
|
+
type: "text",
|
|
3647
|
+
value: m,
|
|
3648
|
+
onChange: (e) => {
|
|
3649
|
+
setModels((prev) => {
|
|
3650
|
+
const next = [...prev];
|
|
3651
|
+
next[i] = e.target.value;
|
|
3652
|
+
return next;
|
|
3653
|
+
});
|
|
3654
|
+
},
|
|
3655
|
+
placeholder: isMiniMax || isAlibaba ? "Type or select a model..." : "Model name",
|
|
3656
|
+
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"
|
|
3657
|
+
}
|
|
3658
|
+
),
|
|
3659
|
+
(isMiniMax || isAlibaba) && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3660
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3661
|
+
"button",
|
|
3662
|
+
{
|
|
3663
|
+
type: "button",
|
|
3664
|
+
onClick: () => setOpenModelDropdown(openModelDropdown === i ? null : i),
|
|
3665
|
+
className: "absolute right-1 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors p-1 z-10",
|
|
3666
|
+
"aria-label": "Show model suggestions",
|
|
3667
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" })
|
|
3668
|
+
}
|
|
3669
|
+
),
|
|
3670
|
+
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(
|
|
3671
|
+
"button",
|
|
3672
|
+
{
|
|
3673
|
+
type: "button",
|
|
3674
|
+
onClick: () => {
|
|
3675
|
+
setModels((prev) => {
|
|
3676
|
+
const next = [...prev];
|
|
3677
|
+
next[i] = opt;
|
|
3678
|
+
return next;
|
|
3679
|
+
});
|
|
3680
|
+
setOpenModelDropdown(null);
|
|
3681
|
+
},
|
|
3682
|
+
className: "w-full text-left px-3 py-2 text-sm hover:bg-muted transition-colors",
|
|
3683
|
+
children: opt
|
|
3684
|
+
},
|
|
3685
|
+
opt
|
|
3686
|
+
)) })
|
|
3687
|
+
] })
|
|
3688
|
+
] }),
|
|
3689
|
+
models.length > 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3690
|
+
"button",
|
|
3441
3691
|
{
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3692
|
+
type: "button",
|
|
3693
|
+
onClick: () => setModels((prev) => prev.filter((_, idx) => idx !== i)),
|
|
3694
|
+
className: "text-muted-foreground hover:text-destructive transition-colors p-1 shrink-0",
|
|
3695
|
+
"aria-label": "Remove model",
|
|
3696
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3697
|
+
"svg",
|
|
3698
|
+
{
|
|
3699
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3700
|
+
width: "16",
|
|
3701
|
+
height: "16",
|
|
3702
|
+
viewBox: "0 0 24 24",
|
|
3703
|
+
fill: "none",
|
|
3704
|
+
stroke: "currentColor",
|
|
3705
|
+
strokeWidth: "2",
|
|
3706
|
+
strokeLinecap: "round",
|
|
3707
|
+
strokeLinejoin: "round",
|
|
3708
|
+
children: [
|
|
3709
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M3 6h18" }),
|
|
3710
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" }),
|
|
3711
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" })
|
|
3712
|
+
]
|
|
3713
|
+
}
|
|
3714
|
+
)
|
|
3456
3715
|
}
|
|
3457
3716
|
)
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3717
|
+
]
|
|
3718
|
+
},
|
|
3719
|
+
i
|
|
3720
|
+
)),
|
|
3461
3721
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3462
3722
|
"button",
|
|
3463
3723
|
{
|
|
@@ -3595,11 +3855,21 @@ function ProvidersPanel({
|
|
|
3595
3855
|
const [configPath, setConfigPath] = reactExports.useState(null);
|
|
3596
3856
|
const [configPathCopied, setConfigPathCopied] = reactExports.useState(false);
|
|
3597
3857
|
const [highlightedProviderId, setHighlightedProviderId] = reactExports.useState(null);
|
|
3858
|
+
const [showImportWizard, setShowImportWizard] = reactExports.useState(false);
|
|
3598
3859
|
const [sourceFilter, setSourceFilter] = reactExports.useState("all");
|
|
3599
3860
|
const listScrollRef = reactExports.useRef(null);
|
|
3600
3861
|
const highlightTimeoutRef = reactExports.useRef(null);
|
|
3601
3862
|
const providers = externalProviders ?? [];
|
|
3602
|
-
const filteredProviders =
|
|
3863
|
+
const filteredProviders = reactExports.useMemo(() => {
|
|
3864
|
+
const filtered = sourceFilter === "all" ? providers : providers.filter((p) => p.source === sourceFilter);
|
|
3865
|
+
if (sourceFilter === "all") {
|
|
3866
|
+
return [...filtered].sort((a, b) => {
|
|
3867
|
+
const order = { personal: 0, company: 1 };
|
|
3868
|
+
return (order[a.source ?? ""] ?? 2) - (order[b.source ?? ""] ?? 2);
|
|
3869
|
+
});
|
|
3870
|
+
}
|
|
3871
|
+
return filtered;
|
|
3872
|
+
}, [providers, sourceFilter]);
|
|
3603
3873
|
const testResults = externalTestResults ?? internalTestResults;
|
|
3604
3874
|
const testingProviders = externalTestingProviders ?? internalTestingProviders;
|
|
3605
3875
|
const testingTimeLeft = externalTestingTimeLeft ?? internalTestingTimeLeft;
|
|
@@ -3850,7 +4120,7 @@ function ProvidersPanel({
|
|
|
3850
4120
|
}
|
|
3851
4121
|
if (showForm || editingProvider) {
|
|
3852
4122
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
3853
|
-
/* @__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" }) }),
|
|
4123
|
+
/* @__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" }) }),
|
|
3854
4124
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3855
4125
|
ProviderForm,
|
|
3856
4126
|
{
|
|
@@ -3904,6 +4174,19 @@ function ProvidersPanel({
|
|
|
3904
4174
|
style: { display: "none" }
|
|
3905
4175
|
}
|
|
3906
4176
|
),
|
|
4177
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4178
|
+
Button,
|
|
4179
|
+
{
|
|
4180
|
+
variant: "outline",
|
|
4181
|
+
size: "sm",
|
|
4182
|
+
onClick: () => setShowImportWizard(true),
|
|
4183
|
+
className: "gap-1",
|
|
4184
|
+
children: [
|
|
4185
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Scan, { className: "size-3" }),
|
|
4186
|
+
"Scan"
|
|
4187
|
+
]
|
|
4188
|
+
}
|
|
4189
|
+
),
|
|
3907
4190
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: () => setShowForm(true), size: "sm", className: "gap-1", children: [
|
|
3908
4191
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4" }),
|
|
3909
4192
|
"Add Provider"
|
|
@@ -3966,7 +4249,19 @@ function ProvidersPanel({
|
|
|
3966
4249
|
},
|
|
3967
4250
|
provider.id
|
|
3968
4251
|
)) })
|
|
3969
|
-
] })
|
|
4252
|
+
] }),
|
|
4253
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4254
|
+
ImportWizardDialog,
|
|
4255
|
+
{
|
|
4256
|
+
open: showImportWizard,
|
|
4257
|
+
onOpenChange: setShowImportWizard,
|
|
4258
|
+
onImportComplete: () => {
|
|
4259
|
+
if (onProvidersMutate !== void 0) {
|
|
4260
|
+
void onProvidersMutate();
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
)
|
|
3970
4265
|
] });
|
|
3971
4266
|
}
|
|
3972
4267
|
async function fetcher(url) {
|
|
@@ -4042,7 +4337,7 @@ function SettingsDialog() {
|
|
|
4042
4337
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "providers", children: "Providers" }),
|
|
4043
4338
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "proxy", children: "Proxy" })
|
|
4044
4339
|
] }),
|
|
4045
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 overflow-y-auto flex-1", children: [
|
|
4340
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 overflow-y-auto flex-1 pr-3", children: [
|
|
4046
4341
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "providers", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4047
4342
|
ProvidersPanel,
|
|
4048
4343
|
{
|
|
@@ -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-Oekf1osO.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-Bl3OCdGC.mjs").then((n) => n.r);
|
|
771
771
|
const startEntry = await import("./start-HYkvq4Ni.mjs");
|
|
772
772
|
return { startEntry, routerEntry };
|
|
773
773
|
}
|