@tonyclaw/llm-inspector 1.7.4 → 1.7.5
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-Bf_WGooQ.js → index-BkNsdDqV.js} +2 -2
- package/.output/public/assets/{main-CpIX1ZHy.js → main-CC-HN8LQ.js} +1 -1
- package/.output/server/_ssr/{index-BauwiGgk.mjs → index-DosJndBx.mjs} +3 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-DPnnefGg.mjs → router-4NfH7bm_.mjs} +41 -22
- package/.output/server/{_tanstack-start-manifest_v-b6u6g-Cr.mjs → _tanstack-start-manifest_v-CdS0WV2N.mjs} +1 -1
- package/.output/server/index.mjs +26 -26
- package/package.json +1 -1
- package/src/components/providers/ProviderLogo.tsx +2 -1
- package/src/proxy/providers.ts +8 -1
- package/src/routes/api/providers.$providerId.ts +2 -0
|
@@ -14,4 +14,4 @@ Error generating stack: `+l.message+`
|
|
|
14
14
|
`)}else{const p=o.indexOf(`
|
|
15
15
|
`);if(p>=0){const S=o.slice(0,p).trim();o=o.slice(p+1),S.length>0&&(m=JSON.parse(S),f=!0)}}}return(async()=>{try{for(;;){const{value:y,done:h}=await r.read();y&&(o+=y);const p=o.lastIndexOf(`
|
|
16
16
|
`);if(p>=0){const S=o.slice(0,p);o=o.slice(p+1);const b=S.split(`
|
|
17
|
-
`).filter(Boolean);for(const _ of b)try{u(JSON.parse(_))}catch(R){i?.(`Invalid JSON line: ${_}`,R)}}if(h)break}}catch(y){i?.("Stream processing error:",y)}})(),u(m)}async function _E({jsonStream:a,onMessage:u,onError:i}){const r=a.getReader(),{value:o,done:f}=await r.read();if(f||!o)throw new Error("Stream ended before first object");const m=JSON.parse(o);return(async()=>{try{for(;;){const{value:y,done:h}=await r.read();if(h)break;if(y)try{u(JSON.parse(y))}catch(p){i?.(`Invalid JSON: ${y}`,p)}}}catch(y){i?.("Stream processing error:",y)}})(),u(m)}function EE(a){const u="/_serverFn/"+a;return Object.assign((...o)=>{const f=Lp()?.serverFns?.fetch;return gE(u,o,f??fetch)},{url:u,serverFnMeta:{id:a},[Ao]:!0})}const RE={key:"$TSS/serverfn",test:a=>typeof a!="function"||!(Ao in a)?!1:!!a[Ao],toSerializable:({serverFnMeta:a})=>({functionId:a.id}),fromSerializable:({functionId:a})=>EE(a)},TE="/assets/index-B3RwBPLW.css",Hp=G_({head:()=>({meta:[{charSet:"utf-8"},{name:"viewport",content:"width=device-width, initial-scale=1"},{title:"llm-inspector"}],links:[{rel:"stylesheet",href:TE}]}),component:AE});function AE(){return k.jsx(OE,{children:k.jsx(Cp,{})})}function OE({children:a}){return k.jsxs("html",{lang:"en",className:"dark",children:[k.jsx("head",{children:k.jsx(aE,{})}),k.jsxs("body",{children:[a,k.jsx(lE,{})]})]})}const ME="modulepreload",zE=function(a){return"/"+a},zy={},xE=function(u,i,r){let o=Promise.resolve();if(i&&i.length>0){let h=function(p){return Promise.all(p.map(S=>Promise.resolve(S).then(b=>({status:"fulfilled",value:b}),b=>({status:"rejected",reason:b}))))};document.getElementsByTagName("link");const m=document.querySelector("meta[property=csp-nonce]"),y=m?.nonce||m?.getAttribute("nonce");o=h(i.map(p=>{if(p=zE(p),p in zy)return;zy[p]=!0;const S=p.endsWith(".css"),b=S?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${p}"]${b}`))return;const _=document.createElement("link");if(_.rel=S?"stylesheet":ME,S||(_.as="script"),_.crossOrigin="",_.href=p,y&&_.setAttribute("nonce",y),document.head.appendChild(_),S)return new Promise((R,D)=>{_.addEventListener("load",R),_.addEventListener("error",()=>D(new Error(`Unable to preload CSS for ${p}`)))})}))}function f(m){const y=new Event("vite:preloadError",{cancelable:!0});if(y.payload=m,window.dispatchEvent(y),!y.defaultPrevented)throw m}return o.then(m=>{for(const y of m||[])y.status==="rejected"&&f(y.reason);return u().catch(f)})},wE=()=>xE(()=>import("./index-
|
|
17
|
+
`).filter(Boolean);for(const _ of b)try{u(JSON.parse(_))}catch(R){i?.(`Invalid JSON line: ${_}`,R)}}if(h)break}}catch(y){i?.("Stream processing error:",y)}})(),u(m)}async function _E({jsonStream:a,onMessage:u,onError:i}){const r=a.getReader(),{value:o,done:f}=await r.read();if(f||!o)throw new Error("Stream ended before first object");const m=JSON.parse(o);return(async()=>{try{for(;;){const{value:y,done:h}=await r.read();if(h)break;if(y)try{u(JSON.parse(y))}catch(p){i?.(`Invalid JSON: ${y}`,p)}}}catch(y){i?.("Stream processing error:",y)}})(),u(m)}function EE(a){const u="/_serverFn/"+a;return Object.assign((...o)=>{const f=Lp()?.serverFns?.fetch;return gE(u,o,f??fetch)},{url:u,serverFnMeta:{id:a},[Ao]:!0})}const RE={key:"$TSS/serverfn",test:a=>typeof a!="function"||!(Ao in a)?!1:!!a[Ao],toSerializable:({serverFnMeta:a})=>({functionId:a.id}),fromSerializable:({functionId:a})=>EE(a)},TE="/assets/index-B3RwBPLW.css",Hp=G_({head:()=>({meta:[{charSet:"utf-8"},{name:"viewport",content:"width=device-width, initial-scale=1"},{title:"llm-inspector"}],links:[{rel:"stylesheet",href:TE}]}),component:AE});function AE(){return k.jsx(OE,{children:k.jsx(Cp,{})})}function OE({children:a}){return k.jsxs("html",{lang:"en",className:"dark",children:[k.jsx("head",{children:k.jsx(aE,{})}),k.jsxs("body",{children:[a,k.jsx(lE,{})]})]})}const ME="modulepreload",zE=function(a){return"/"+a},zy={},xE=function(u,i,r){let o=Promise.resolve();if(i&&i.length>0){let h=function(p){return Promise.all(p.map(S=>Promise.resolve(S).then(b=>({status:"fulfilled",value:b}),b=>({status:"rejected",reason:b}))))};document.getElementsByTagName("link");const m=document.querySelector("meta[property=csp-nonce]"),y=m?.nonce||m?.getAttribute("nonce");o=h(i.map(p=>{if(p=zE(p),p in zy)return;zy[p]=!0;const S=p.endsWith(".css"),b=S?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${p}"]${b}`))return;const _=document.createElement("link");if(_.rel=S?"stylesheet":ME,S||(_.as="script"),_.crossOrigin="",_.href=p,y&&_.setAttribute("nonce",y),document.head.appendChild(_),S)return new Promise((R,D)=>{_.addEventListener("load",R),_.addEventListener("error",()=>D(new Error(`Unable to preload CSS for ${p}`)))})}))}function f(m){const y=new Event("vite:preloadError",{cancelable:!0});if(y.payload=m,window.dispatchEvent(y),!y.defaultPrevented)throw m}return o.then(m=>{for(const y of m||[])y.status==="rejected"&&f(y.reason);return u().catch(f)})},wE=()=>xE(()=>import("./index-BkNsdDqV.js"),[]),CE=To("/")({component:V_(wE,"component")}),DE=CE.update({id:"/",path:"/",getParentRoute:()=>Hp}),UE={IndexRoute:DE},LE=Hp._addFileChildren(UE);function NE(){return P_({routeTree:LE,scrollRestoration:!1})}async function BE(){const a=await NE();let u;return u=[],window.__TSS_START_OPTIONS__={serializationAdapters:u},u.push(RE),a.options.serializationAdapters&&u.push(...a.options.serializationAdapters),a.update({basepath:"",serializationAdapters:u}),a.state.matches.length||await uE(a),a}async function jE(){const a=await BE();return window.$_TSR?.h(),a}let So;function HE(){return So||(So=jE()),k.jsx(p_,{promise:So,children:a=>k.jsx(I_,{router:a})})}nt.startTransition(()=>{h0.hydrateRoot(document,k.jsx(nt.StrictMode,{children:k.jsx(HE,{})}))});export{Ul as R,Mp as a,s0 as b,qE as c,XE as d,xy as g,k as j,nt as r};
|
|
@@ -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, p as parseOpenAIResponse, I as InspectorResponseSchema } from "./router-
|
|
2
|
+
import { C as CapturedLogSchema, a as parseRequest, p as parseOpenAIResponse, I as InspectorResponseSchema } from "./router-4NfH7bm_.mjs";
|
|
3
3
|
import { u as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
|
|
4
4
|
import { J as JSZip } from "../_libs/jszip.mjs";
|
|
5
5
|
import { c as clsx } from "../_libs/clsx.mjs";
|
|
@@ -878,8 +878,9 @@ const PROVIDER_MAP = {
|
|
|
878
878
|
};
|
|
879
879
|
function detectProvider(model) {
|
|
880
880
|
if (model === null) return "unknown";
|
|
881
|
+
const modelLower = model.toLowerCase();
|
|
881
882
|
for (const [prefix, provider] of Object.entries(PROVIDER_MAP)) {
|
|
882
|
-
if (
|
|
883
|
+
if (modelLower.startsWith(prefix.toLowerCase())) {
|
|
883
884
|
return provider;
|
|
884
885
|
}
|
|
885
886
|
}
|
|
@@ -197,7 +197,7 @@ function getResponse() {
|
|
|
197
197
|
return event.res;
|
|
198
198
|
}
|
|
199
199
|
async function getStartManifest(matchedRoutes) {
|
|
200
|
-
const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-
|
|
200
|
+
const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-CdS0WV2N.mjs");
|
|
201
201
|
const startManifest = tsrStartManifest();
|
|
202
202
|
const rootRoute = startManifest.routes[rootRouteId] = startManifest.routes[rootRouteId] || {};
|
|
203
203
|
rootRoute.assets = rootRoute.assets || [];
|
|
@@ -766,7 +766,7 @@ let entriesPromise;
|
|
|
766
766
|
let baseManifestPromise;
|
|
767
767
|
let cachedFinalManifestPromise;
|
|
768
768
|
async function loadEntries() {
|
|
769
|
-
const routerEntry = await import("./router-
|
|
769
|
+
const routerEntry = await import("./router-4NfH7bm_.mjs").then((n) => n.r);
|
|
770
770
|
const startEntry = await import("./start-HYkvq4Ni.mjs");
|
|
771
771
|
return { startEntry, routerEntry };
|
|
772
772
|
}
|
|
@@ -65,7 +65,7 @@ function RootDocument({ children }) {
|
|
|
65
65
|
] })
|
|
66
66
|
] });
|
|
67
67
|
}
|
|
68
|
-
const $$splitComponentImporter = () => import("./index-
|
|
68
|
+
const $$splitComponentImporter = () => import("./index-DosJndBx.mjs");
|
|
69
69
|
const Route$d = createFileRoute("/")({
|
|
70
70
|
component: lazyRouteComponent($$splitComponentImporter, "component")
|
|
71
71
|
});
|
|
@@ -1480,7 +1480,9 @@ function addProvider(name, apiKey, format, baseUrl, model, authHeader) {
|
|
|
1480
1480
|
model,
|
|
1481
1481
|
authHeader: authHeader ?? "bearer",
|
|
1482
1482
|
createdAt: now,
|
|
1483
|
-
updatedAt: now
|
|
1483
|
+
updatedAt: now,
|
|
1484
|
+
anthropicBaseUrl: format === "anthropic" && baseUrl !== void 0 ? baseUrl : "",
|
|
1485
|
+
openaiBaseUrl: format === "openai" && baseUrl !== void 0 ? baseUrl : ""
|
|
1484
1486
|
};
|
|
1485
1487
|
providers.push(newProvider);
|
|
1486
1488
|
store.set("providers", providers);
|
|
@@ -1499,7 +1501,10 @@ function updateProvider(id, updates) {
|
|
|
1499
1501
|
baseUrl: updates.baseUrl !== void 0 ? updates.baseUrl : existing.baseUrl,
|
|
1500
1502
|
authHeader: updates.authHeader ?? existing.authHeader,
|
|
1501
1503
|
createdAt: existing.createdAt,
|
|
1502
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1504
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1505
|
+
// Handle format-specific URLs
|
|
1506
|
+
anthropicBaseUrl: updates.anthropicBaseUrl !== void 0 ? updates.anthropicBaseUrl : existing.anthropicBaseUrl,
|
|
1507
|
+
openaiBaseUrl: updates.openaiBaseUrl !== void 0 ? updates.openaiBaseUrl : existing.openaiBaseUrl
|
|
1503
1508
|
};
|
|
1504
1509
|
const index = providers.findIndex((p) => p.id === id);
|
|
1505
1510
|
providers[index] = updated;
|
|
@@ -1968,7 +1973,9 @@ const ProviderUpdateSchema = object({
|
|
|
1968
1973
|
format: _enum(["anthropic", "openai"]).optional(),
|
|
1969
1974
|
baseUrl: string().min(1, "Base URL is required").optional(),
|
|
1970
1975
|
model: string().min(1, "Model is required").optional(),
|
|
1971
|
-
authHeader: _enum(["bearer", "x-api-key"]).optional()
|
|
1976
|
+
authHeader: _enum(["bearer", "x-api-key"]).optional(),
|
|
1977
|
+
anthropicBaseUrl: string().optional(),
|
|
1978
|
+
openaiBaseUrl: string().optional()
|
|
1972
1979
|
});
|
|
1973
1980
|
const Route$6 = createFileRoute("/api/providers/$providerId")({
|
|
1974
1981
|
server: {
|
|
@@ -2195,16 +2202,17 @@ async function testEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2195
2202
|
messages: [{ role: "user", content: "say hello and briefly introduce yourself" }],
|
|
2196
2203
|
max_tokens: 1024
|
|
2197
2204
|
});
|
|
2205
|
+
const requestHeaders = {
|
|
2206
|
+
"Content-Type": "application/json",
|
|
2207
|
+
Authorization: `Bearer ${apiKey}`
|
|
2208
|
+
};
|
|
2198
2209
|
const controller = new AbortController();
|
|
2199
2210
|
const timeoutId = setTimeout(() => controller.abort(), TEST_TIMEOUT_MS);
|
|
2200
2211
|
try {
|
|
2201
2212
|
const url = `${baseUrl}${path2}`;
|
|
2202
2213
|
const response = await fetch(url, {
|
|
2203
2214
|
method: "POST",
|
|
2204
|
-
headers:
|
|
2205
|
-
"Content-Type": "application/json",
|
|
2206
|
-
Authorization: `Bearer ${apiKey}`
|
|
2207
|
-
},
|
|
2215
|
+
headers: requestHeaders,
|
|
2208
2216
|
body,
|
|
2209
2217
|
signal: controller.signal
|
|
2210
2218
|
});
|
|
@@ -2233,7 +2241,8 @@ async function testEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2233
2241
|
outputTokens,
|
|
2234
2242
|
latencyMs,
|
|
2235
2243
|
content: content !== null && content !== "" ? [{ type: "text", text: content }] : void 0,
|
|
2236
|
-
rawResponse: responseText
|
|
2244
|
+
rawResponse: responseText,
|
|
2245
|
+
requestHeaders
|
|
2237
2246
|
};
|
|
2238
2247
|
} else {
|
|
2239
2248
|
const json = AnthropicResponseSchema.parse(JSON.parse(responseText));
|
|
@@ -2255,7 +2264,8 @@ async function testEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2255
2264
|
outputTokens,
|
|
2256
2265
|
latencyMs,
|
|
2257
2266
|
content: content.length > 0 ? content : void 0,
|
|
2258
|
-
rawResponse: responseText
|
|
2267
|
+
rawResponse: responseText,
|
|
2268
|
+
requestHeaders
|
|
2259
2269
|
};
|
|
2260
2270
|
}
|
|
2261
2271
|
} catch (parseErr) {
|
|
@@ -2264,7 +2274,8 @@ async function testEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2264
2274
|
model,
|
|
2265
2275
|
latencyMs,
|
|
2266
2276
|
content: [{ type: "text", text: responseText.slice(0, 2e3) }],
|
|
2267
|
-
rawResponse: responseText
|
|
2277
|
+
rawResponse: responseText,
|
|
2278
|
+
requestHeaders
|
|
2268
2279
|
};
|
|
2269
2280
|
}
|
|
2270
2281
|
} catch (err) {
|
|
@@ -2280,16 +2291,17 @@ async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2280
2291
|
max_tokens: 256,
|
|
2281
2292
|
stream: true
|
|
2282
2293
|
});
|
|
2294
|
+
const requestHeaders = {
|
|
2295
|
+
"Content-Type": "application/json",
|
|
2296
|
+
Authorization: `Bearer ${apiKey}`
|
|
2297
|
+
};
|
|
2283
2298
|
const controller = new AbortController();
|
|
2284
2299
|
const timeoutId = setTimeout(() => controller.abort(), TEST_TIMEOUT_MS);
|
|
2285
2300
|
try {
|
|
2286
2301
|
const url = `${baseUrl}${path2}`;
|
|
2287
2302
|
const response = await fetch(url, {
|
|
2288
2303
|
method: "POST",
|
|
2289
|
-
headers:
|
|
2290
|
-
"Content-Type": "application/json",
|
|
2291
|
-
Authorization: `Bearer ${apiKey}`
|
|
2292
|
-
},
|
|
2304
|
+
headers: requestHeaders,
|
|
2293
2305
|
body,
|
|
2294
2306
|
signal: controller.signal
|
|
2295
2307
|
});
|
|
@@ -2392,7 +2404,8 @@ async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2392
2404
|
content: content.length > 0 ? content : void 0,
|
|
2393
2405
|
rawResponse: reconstructedJson,
|
|
2394
2406
|
streaming: true,
|
|
2395
|
-
streamingChunks
|
|
2407
|
+
streamingChunks,
|
|
2408
|
+
requestHeaders
|
|
2396
2409
|
};
|
|
2397
2410
|
} catch {
|
|
2398
2411
|
return {
|
|
@@ -2402,7 +2415,8 @@ async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2402
2415
|
content: [{ type: "text", text: reconstructedJson.slice(0, 2e3) }],
|
|
2403
2416
|
rawResponse: reconstructedJson,
|
|
2404
2417
|
streaming: true,
|
|
2405
|
-
streamingChunks
|
|
2418
|
+
streamingChunks,
|
|
2419
|
+
requestHeaders
|
|
2406
2420
|
};
|
|
2407
2421
|
}
|
|
2408
2422
|
} catch (err) {
|
|
@@ -2430,7 +2444,8 @@ function createTestLogEntry(providerName, path2, body, upstreamUrl, result, isTe
|
|
|
2430
2444
|
upstreamUrl,
|
|
2431
2445
|
error: result.success ? null : result.error?.message ?? String(result.error),
|
|
2432
2446
|
isTest: true,
|
|
2433
|
-
providerName
|
|
2447
|
+
providerName,
|
|
2448
|
+
headers: result.requestHeaders ?? {}
|
|
2434
2449
|
};
|
|
2435
2450
|
}
|
|
2436
2451
|
const Route$2 = createFileRoute("/api/providers/$providerId/test")({
|
|
@@ -2487,7 +2502,8 @@ const Route$2 = createFileRoute("/api/providers/$providerId/test")({
|
|
|
2487
2502
|
origin: null,
|
|
2488
2503
|
apiFormat: "anthropic",
|
|
2489
2504
|
isTest: true,
|
|
2490
|
-
providerName: provider.name
|
|
2505
|
+
providerName: provider.name,
|
|
2506
|
+
headers: nonStreamingResult.requestHeaders ?? {}
|
|
2491
2507
|
});
|
|
2492
2508
|
appendLogEntry(
|
|
2493
2509
|
createTestLogEntry(
|
|
@@ -2533,7 +2549,8 @@ const Route$2 = createFileRoute("/api/providers/$providerId/test")({
|
|
|
2533
2549
|
origin: null,
|
|
2534
2550
|
apiFormat: "anthropic",
|
|
2535
2551
|
isTest: true,
|
|
2536
|
-
providerName: provider.name
|
|
2552
|
+
providerName: provider.name,
|
|
2553
|
+
headers: streamingResult.requestHeaders ?? {}
|
|
2537
2554
|
});
|
|
2538
2555
|
appendLogEntry(
|
|
2539
2556
|
createTestLogEntry(
|
|
@@ -2580,7 +2597,8 @@ const Route$2 = createFileRoute("/api/providers/$providerId/test")({
|
|
|
2580
2597
|
origin: null,
|
|
2581
2598
|
apiFormat: "openai",
|
|
2582
2599
|
isTest: true,
|
|
2583
|
-
providerName: provider.name
|
|
2600
|
+
providerName: provider.name,
|
|
2601
|
+
headers: nonStreamingResult.requestHeaders ?? {}
|
|
2584
2602
|
});
|
|
2585
2603
|
appendLogEntry(
|
|
2586
2604
|
createTestLogEntry(
|
|
@@ -2626,7 +2644,8 @@ const Route$2 = createFileRoute("/api/providers/$providerId/test")({
|
|
|
2626
2644
|
origin: null,
|
|
2627
2645
|
apiFormat: "openai",
|
|
2628
2646
|
isTest: true,
|
|
2629
|
-
providerName: provider.name
|
|
2647
|
+
providerName: provider.name,
|
|
2648
|
+
headers: streamingResult.requestHeaders ?? {}
|
|
2630
2649
|
});
|
|
2631
2650
|
appendLogEntry(
|
|
2632
2651
|
createTestLogEntry(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", "children": ["/", "/api/health", "/api/logs", "/api/models", "/api/providers", "/api/sessions", "/proxy/$", "/api/config/paths"], "preloads": ["/assets/main-
|
|
1
|
+
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", "children": ["/", "/api/health", "/api/logs", "/api/models", "/api/providers", "/api/sessions", "/proxy/$", "/api/config/paths"], "preloads": ["/assets/main-CC-HN8LQ.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-BkNsdDqV.js"] }, "/api/health": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/health.ts" }, "/api/logs": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.ts", "children": ["/api/logs/$id", "/api/logs/stream"] }, "/api/models": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/models.ts" }, "/api/providers": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.ts", "children": ["/api/providers/$providerId"] }, "/api/sessions": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/sessions.ts" }, "/proxy/$": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/proxy/$.ts" }, "/api/config/paths": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/config.paths.ts" }, "/api/logs/$id": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.ts", "children": ["/api/logs/$id/chunks", "/api/logs/$id/replay"] }, "/api/logs/stream": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.stream.ts" }, "/api/providers/$providerId": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.ts", "children": ["/api/providers/$providerId/test"] }, "/api/logs/$id/chunks": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.chunks.ts" }, "/api/logs/$id/replay": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.replay.ts" }, "/api/providers/$providerId/test": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.test.ts" } }, "clientEntry": "/assets/main-CC-HN8LQ.js" });
|
|
2
2
|
export {
|
|
3
3
|
tsrStartManifest
|
|
4
4
|
};
|
package/.output/server/index.mjs
CHANGED
|
@@ -100,51 +100,51 @@ const assets = {
|
|
|
100
100
|
"/assets/alibaba-TTwafVwX.svg": {
|
|
101
101
|
"type": "image/svg+xml",
|
|
102
102
|
"etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
|
|
103
|
-
"mtime": "2026-06-
|
|
103
|
+
"mtime": "2026-06-03T11:03:37.187Z",
|
|
104
104
|
"size": 5915,
|
|
105
105
|
"path": "../public/assets/alibaba-TTwafVwX.svg"
|
|
106
106
|
},
|
|
107
|
-
"/assets/minimax-BPMzvuL-.jpeg": {
|
|
108
|
-
"type": "image/jpeg",
|
|
109
|
-
"etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
|
|
110
|
-
"mtime": "2026-06-03T10:13:16.267Z",
|
|
111
|
-
"size": 6918,
|
|
112
|
-
"path": "../public/assets/minimax-BPMzvuL-.jpeg"
|
|
113
|
-
},
|
|
114
107
|
"/assets/zhipuai-BPNAnxo-.svg": {
|
|
115
108
|
"type": "image/svg+xml",
|
|
116
109
|
"etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
|
|
117
|
-
"mtime": "2026-06-
|
|
110
|
+
"mtime": "2026-06-03T11:03:37.189Z",
|
|
118
111
|
"size": 11256,
|
|
119
112
|
"path": "../public/assets/zhipuai-BPNAnxo-.svg"
|
|
120
113
|
},
|
|
121
|
-
"/assets/
|
|
114
|
+
"/assets/minimax-BPMzvuL-.jpeg": {
|
|
115
|
+
"type": "image/jpeg",
|
|
116
|
+
"etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
|
|
117
|
+
"mtime": "2026-06-03T11:03:37.187Z",
|
|
118
|
+
"size": 6918,
|
|
119
|
+
"path": "../public/assets/minimax-BPMzvuL-.jpeg"
|
|
120
|
+
},
|
|
121
|
+
"/assets/main-CC-HN8LQ.js": {
|
|
122
122
|
"type": "text/javascript; charset=utf-8",
|
|
123
|
-
"etag": '"4db57-
|
|
124
|
-
"mtime": "2026-06-
|
|
123
|
+
"etag": '"4db57-dDRKN7pAYlQliYE7orCiiIlfW1M"',
|
|
124
|
+
"mtime": "2026-06-03T11:03:37.189Z",
|
|
125
125
|
"size": 318295,
|
|
126
|
-
"path": "../public/assets/main-
|
|
127
|
-
},
|
|
128
|
-
"/assets/qwen-CONDcHqt.png": {
|
|
129
|
-
"type": "image/png",
|
|
130
|
-
"etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
|
|
131
|
-
"mtime": "2026-06-03T10:13:16.269Z",
|
|
132
|
-
"size": 357059,
|
|
133
|
-
"path": "../public/assets/qwen-CONDcHqt.png"
|
|
126
|
+
"path": "../public/assets/main-CC-HN8LQ.js"
|
|
134
127
|
},
|
|
135
128
|
"/assets/index-B3RwBPLW.css": {
|
|
136
129
|
"type": "text/css; charset=utf-8",
|
|
137
130
|
"etag": '"10c74-aXacU4DRFVsUwcC5jHnjoPRSlTA"',
|
|
138
|
-
"mtime": "2026-06-
|
|
131
|
+
"mtime": "2026-06-03T11:03:37.189Z",
|
|
139
132
|
"size": 68724,
|
|
140
133
|
"path": "../public/assets/index-B3RwBPLW.css"
|
|
141
134
|
},
|
|
142
|
-
"/assets/
|
|
135
|
+
"/assets/qwen-CONDcHqt.png": {
|
|
136
|
+
"type": "image/png",
|
|
137
|
+
"etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
|
|
138
|
+
"mtime": "2026-06-03T11:03:37.189Z",
|
|
139
|
+
"size": 357059,
|
|
140
|
+
"path": "../public/assets/qwen-CONDcHqt.png"
|
|
141
|
+
},
|
|
142
|
+
"/assets/index-BkNsdDqV.js": {
|
|
143
143
|
"type": "text/javascript; charset=utf-8",
|
|
144
|
-
"etag": '"
|
|
145
|
-
"mtime": "2026-06-
|
|
146
|
-
"size":
|
|
147
|
-
"path": "../public/assets/index-
|
|
144
|
+
"etag": '"83205-a3v/UM6yJRUCSO9lDIeVoj7vJXg"',
|
|
145
|
+
"mtime": "2026-06-03T11:03:37.189Z",
|
|
146
|
+
"size": 537093,
|
|
147
|
+
"path": "../public/assets/index-BkNsdDqV.js"
|
|
148
148
|
}
|
|
149
149
|
};
|
|
150
150
|
function readAsset(id) {
|
package/package.json
CHANGED
|
@@ -31,8 +31,9 @@ const PROVIDER_MAP: Record<string, Provider> = {
|
|
|
31
31
|
|
|
32
32
|
export function detectProvider(model: string | null): Provider {
|
|
33
33
|
if (model === null) return "unknown";
|
|
34
|
+
const modelLower = model.toLowerCase();
|
|
34
35
|
for (const [prefix, provider] of Object.entries(PROVIDER_MAP)) {
|
|
35
|
-
if (
|
|
36
|
+
if (modelLower.startsWith(prefix.toLowerCase())) {
|
|
36
37
|
return provider;
|
|
37
38
|
}
|
|
38
39
|
}
|
package/src/proxy/providers.ts
CHANGED
|
@@ -131,7 +131,7 @@ export function getProvider(id: string): ProviderConfig | undefined {
|
|
|
131
131
|
/**
|
|
132
132
|
* Normalizes an API key by stripping "Bearer " prefix if present.
|
|
133
133
|
*/
|
|
134
|
-
function normalizeApiKey(apiKey: string): string {
|
|
134
|
+
export function normalizeApiKey(apiKey: string): string {
|
|
135
135
|
return apiKey.replace(/^Bearer\s+/i, "").trim();
|
|
136
136
|
}
|
|
137
137
|
|
|
@@ -155,6 +155,8 @@ export function addProvider(
|
|
|
155
155
|
authHeader: authHeader ?? "bearer",
|
|
156
156
|
createdAt: now,
|
|
157
157
|
updatedAt: now,
|
|
158
|
+
anthropicBaseUrl: format === "anthropic" && baseUrl !== undefined ? baseUrl : "",
|
|
159
|
+
openaiBaseUrl: format === "openai" && baseUrl !== undefined ? baseUrl : "",
|
|
158
160
|
};
|
|
159
161
|
providers.push(newProvider);
|
|
160
162
|
store.set("providers", providers);
|
|
@@ -179,6 +181,11 @@ export function updateProvider(
|
|
|
179
181
|
authHeader: updates.authHeader ?? existing.authHeader,
|
|
180
182
|
createdAt: existing.createdAt,
|
|
181
183
|
updatedAt: new Date().toISOString(),
|
|
184
|
+
// Handle format-specific URLs
|
|
185
|
+
anthropicBaseUrl:
|
|
186
|
+
updates.anthropicBaseUrl !== undefined ? updates.anthropicBaseUrl : existing.anthropicBaseUrl,
|
|
187
|
+
openaiBaseUrl:
|
|
188
|
+
updates.openaiBaseUrl !== undefined ? updates.openaiBaseUrl : existing.openaiBaseUrl,
|
|
182
189
|
};
|
|
183
190
|
const index = providers.findIndex((p) => p.id === id);
|
|
184
191
|
providers[index] = updated;
|
|
@@ -9,6 +9,8 @@ const ProviderUpdateSchema = z.object({
|
|
|
9
9
|
baseUrl: z.string().min(1, "Base URL is required").optional(),
|
|
10
10
|
model: z.string().min(1, "Model is required").optional(),
|
|
11
11
|
authHeader: z.enum(["bearer", "x-api-key"]).optional(),
|
|
12
|
+
anthropicBaseUrl: z.string().optional(),
|
|
13
|
+
openaiBaseUrl: z.string().optional(),
|
|
12
14
|
});
|
|
13
15
|
|
|
14
16
|
export const Route = createFileRoute("/api/providers/$providerId")({
|