@tonyclaw/llm-inspector 1.7.7 → 1.7.8
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-Drusqil7.js → index-C8o6bEv6.js} +8 -8
- package/.output/public/assets/{main-DYXtPYU8.js → main-Bxc5pKCu.js} +1 -1
- package/.output/server/_ssr/{index-DbpsE3Y4.mjs → index-hNquJMfH.mjs} +53 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-CZSteFqT.mjs → router-MmnX-LYh.mjs} +1 -1
- package/.output/server/{_tanstack-start-manifest_v-DgsS3z4y.mjs → _tanstack-start-manifest_v-CYKtU_9S.mjs} +1 -1
- package/.output/server/index.mjs +20 -20
- package/package.json +1 -1
- package/src/components/providers/ProvidersPanel.tsx +57 -1
|
@@ -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-C8o6bEv6.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-MmnX-LYh.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";
|
|
@@ -2567,6 +2567,7 @@ function ProvidersPanel({
|
|
|
2567
2567
|
} else {
|
|
2568
2568
|
setInternalTestingProviders((prev) => new Set(prev).add(providerId));
|
|
2569
2569
|
}
|
|
2570
|
+
const controller = new AbortController();
|
|
2570
2571
|
let remaining = TEST_TIMEOUT_SECONDS;
|
|
2571
2572
|
setTestingTimeLeft(providerId, remaining);
|
|
2572
2573
|
const intervalId = setInterval(() => {
|
|
@@ -2574,10 +2575,14 @@ function ProvidersPanel({
|
|
|
2574
2575
|
setTestingTimeLeft(providerId, remaining);
|
|
2575
2576
|
if (remaining <= 0) {
|
|
2576
2577
|
clearInterval(intervalId);
|
|
2578
|
+
controller.abort();
|
|
2577
2579
|
}
|
|
2578
2580
|
}, 1e3);
|
|
2579
2581
|
try {
|
|
2580
|
-
const res = await fetch(`/api/providers/${providerId}/test`, {
|
|
2582
|
+
const res = await fetch(`/api/providers/${providerId}/test`, {
|
|
2583
|
+
method: "POST",
|
|
2584
|
+
signal: controller.signal
|
|
2585
|
+
});
|
|
2581
2586
|
if (res.ok) {
|
|
2582
2587
|
const results = await res.json();
|
|
2583
2588
|
if (onTestResultsChange) {
|
|
@@ -2585,6 +2590,52 @@ function ProvidersPanel({
|
|
|
2585
2590
|
} else {
|
|
2586
2591
|
setInternalTestResults((prev) => ({ ...prev, [providerId]: results }));
|
|
2587
2592
|
}
|
|
2593
|
+
} else {
|
|
2594
|
+
const errorResult = {
|
|
2595
|
+
anthropic: {
|
|
2596
|
+
nonStreaming: {
|
|
2597
|
+
success: false,
|
|
2598
|
+
error: { message: `HTTP ${res.status}: ${res.statusText}`, type: "server_error" }
|
|
2599
|
+
},
|
|
2600
|
+
streaming: { notConfigured: true }
|
|
2601
|
+
},
|
|
2602
|
+
openai: {
|
|
2603
|
+
nonStreaming: {
|
|
2604
|
+
success: false,
|
|
2605
|
+
error: { message: `HTTP ${res.status}: ${res.statusText}`, type: "server_error" }
|
|
2606
|
+
},
|
|
2607
|
+
streaming: { notConfigured: true }
|
|
2608
|
+
}
|
|
2609
|
+
};
|
|
2610
|
+
if (onTestResultsChange) {
|
|
2611
|
+
onTestResultsChange(providerId, errorResult);
|
|
2612
|
+
} else {
|
|
2613
|
+
setInternalTestResults((prev) => ({ ...prev, [providerId]: errorResult }));
|
|
2614
|
+
}
|
|
2615
|
+
}
|
|
2616
|
+
} catch (err) {
|
|
2617
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
2618
|
+
const timeoutResult = {
|
|
2619
|
+
anthropic: {
|
|
2620
|
+
nonStreaming: {
|
|
2621
|
+
success: false,
|
|
2622
|
+
error: { message: "Request timed out", type: "timeout" }
|
|
2623
|
+
},
|
|
2624
|
+
streaming: { notConfigured: true }
|
|
2625
|
+
},
|
|
2626
|
+
openai: {
|
|
2627
|
+
nonStreaming: {
|
|
2628
|
+
success: false,
|
|
2629
|
+
error: { message: "Request timed out", type: "timeout" }
|
|
2630
|
+
},
|
|
2631
|
+
streaming: { notConfigured: true }
|
|
2632
|
+
}
|
|
2633
|
+
};
|
|
2634
|
+
if (onTestResultsChange) {
|
|
2635
|
+
onTestResultsChange(providerId, timeoutResult);
|
|
2636
|
+
} else {
|
|
2637
|
+
setInternalTestResults((prev) => ({ ...prev, [providerId]: timeoutResult }));
|
|
2638
|
+
}
|
|
2588
2639
|
}
|
|
2589
2640
|
} finally {
|
|
2590
2641
|
clearInterval(intervalId);
|
|
@@ -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-CYKtU_9S.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-MmnX-LYh.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-hNquJMfH.mjs");
|
|
69
69
|
const Route$d = createFileRoute("/")({
|
|
70
70
|
component: lazyRouteComponent($$splitComponentImporter, "component")
|
|
71
71
|
});
|
|
@@ -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-Bxc5pKCu.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-C8o6bEv6.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-Bxc5pKCu.js" });
|
|
2
2
|
export {
|
|
3
3
|
tsrStartManifest
|
|
4
4
|
};
|
package/.output/server/index.mjs
CHANGED
|
@@ -100,51 +100,51 @@ const assets = {
|
|
|
100
100
|
"/assets/index-B3RwBPLW.css": {
|
|
101
101
|
"type": "text/css; charset=utf-8",
|
|
102
102
|
"etag": '"10c74-aXacU4DRFVsUwcC5jHnjoPRSlTA"',
|
|
103
|
-
"mtime": "2026-06-03T12:
|
|
103
|
+
"mtime": "2026-06-03T12:12:14.334Z",
|
|
104
104
|
"size": 68724,
|
|
105
105
|
"path": "../public/assets/index-B3RwBPLW.css"
|
|
106
106
|
},
|
|
107
107
|
"/assets/alibaba-TTwafVwX.svg": {
|
|
108
108
|
"type": "image/svg+xml",
|
|
109
109
|
"etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
|
|
110
|
-
"mtime": "2026-06-03T12:
|
|
110
|
+
"mtime": "2026-06-03T12:12:14.334Z",
|
|
111
111
|
"size": 5915,
|
|
112
112
|
"path": "../public/assets/alibaba-TTwafVwX.svg"
|
|
113
113
|
},
|
|
114
|
-
"/assets/
|
|
114
|
+
"/assets/minimax-BPMzvuL-.jpeg": {
|
|
115
|
+
"type": "image/jpeg",
|
|
116
|
+
"etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
|
|
117
|
+
"mtime": "2026-06-03T12:12:14.334Z",
|
|
118
|
+
"size": 6918,
|
|
119
|
+
"path": "../public/assets/minimax-BPMzvuL-.jpeg"
|
|
120
|
+
},
|
|
121
|
+
"/assets/main-Bxc5pKCu.js": {
|
|
115
122
|
"type": "text/javascript; charset=utf-8",
|
|
116
|
-
"etag": '"4db57-
|
|
117
|
-
"mtime": "2026-06-03T12:
|
|
123
|
+
"etag": '"4db57-Hyx+4GtcEuVuTT+HldUhPQTOcL8"',
|
|
124
|
+
"mtime": "2026-06-03T12:12:14.334Z",
|
|
118
125
|
"size": 318295,
|
|
119
|
-
"path": "../public/assets/main-
|
|
126
|
+
"path": "../public/assets/main-Bxc5pKCu.js"
|
|
120
127
|
},
|
|
121
128
|
"/assets/qwen-CONDcHqt.png": {
|
|
122
129
|
"type": "image/png",
|
|
123
130
|
"etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
|
|
124
|
-
"mtime": "2026-06-03T12:
|
|
131
|
+
"mtime": "2026-06-03T12:12:14.334Z",
|
|
125
132
|
"size": 357059,
|
|
126
133
|
"path": "../public/assets/qwen-CONDcHqt.png"
|
|
127
134
|
},
|
|
128
|
-
"/assets/minimax-BPMzvuL-.jpeg": {
|
|
129
|
-
"type": "image/jpeg",
|
|
130
|
-
"etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
|
|
131
|
-
"mtime": "2026-06-03T12:05:46.053Z",
|
|
132
|
-
"size": 6918,
|
|
133
|
-
"path": "../public/assets/minimax-BPMzvuL-.jpeg"
|
|
134
|
-
},
|
|
135
135
|
"/assets/zhipuai-BPNAnxo-.svg": {
|
|
136
136
|
"type": "image/svg+xml",
|
|
137
137
|
"etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
|
|
138
|
-
"mtime": "2026-06-03T12:
|
|
138
|
+
"mtime": "2026-06-03T12:12:14.334Z",
|
|
139
139
|
"size": 11256,
|
|
140
140
|
"path": "../public/assets/zhipuai-BPNAnxo-.svg"
|
|
141
141
|
},
|
|
142
|
-
"/assets/index-
|
|
142
|
+
"/assets/index-C8o6bEv6.js": {
|
|
143
143
|
"type": "text/javascript; charset=utf-8",
|
|
144
|
-
"etag": '"
|
|
145
|
-
"mtime": "2026-06-03T12:
|
|
146
|
-
"size":
|
|
147
|
-
"path": "../public/assets/index-
|
|
144
|
+
"etag": '"83962-iIMvsvRc3BmqDsudqDxFOFuC3xg"',
|
|
145
|
+
"mtime": "2026-06-03T12:12:14.334Z",
|
|
146
|
+
"size": 538978,
|
|
147
|
+
"path": "../public/assets/index-C8o6bEv6.js"
|
|
148
148
|
}
|
|
149
149
|
};
|
|
150
150
|
function readAsset(id) {
|
package/package.json
CHANGED
|
@@ -141,6 +141,9 @@ export function ProvidersPanel({
|
|
|
141
141
|
setInternalTestingProviders((prev) => new Set(prev).add(providerId));
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
// Create abort controller for this test request
|
|
145
|
+
const controller = new AbortController();
|
|
146
|
+
|
|
144
147
|
// Start countdown
|
|
145
148
|
let remaining = TEST_TIMEOUT_SECONDS;
|
|
146
149
|
setTestingTimeLeft(providerId, remaining);
|
|
@@ -149,11 +152,16 @@ export function ProvidersPanel({
|
|
|
149
152
|
setTestingTimeLeft(providerId, remaining);
|
|
150
153
|
if (remaining <= 0) {
|
|
151
154
|
clearInterval(intervalId);
|
|
155
|
+
// Abort the fetch request when time runs out
|
|
156
|
+
controller.abort();
|
|
152
157
|
}
|
|
153
158
|
}, 1000);
|
|
154
159
|
|
|
155
160
|
try {
|
|
156
|
-
const res = await fetch(`/api/providers/${providerId}/test`, {
|
|
161
|
+
const res = await fetch(`/api/providers/${providerId}/test`, {
|
|
162
|
+
method: "POST",
|
|
163
|
+
signal: controller.signal,
|
|
164
|
+
});
|
|
157
165
|
if (res.ok) {
|
|
158
166
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
159
167
|
const results = (await res.json()) as TestResults;
|
|
@@ -162,6 +170,54 @@ export function ProvidersPanel({
|
|
|
162
170
|
} else {
|
|
163
171
|
setInternalTestResults((prev) => ({ ...prev, [providerId]: results }));
|
|
164
172
|
}
|
|
173
|
+
} else {
|
|
174
|
+
// Non-ok response, create error result
|
|
175
|
+
const errorResult: TestResults = {
|
|
176
|
+
anthropic: {
|
|
177
|
+
nonStreaming: {
|
|
178
|
+
success: false,
|
|
179
|
+
error: { message: `HTTP ${res.status}: ${res.statusText}`, type: "server_error" },
|
|
180
|
+
},
|
|
181
|
+
streaming: { notConfigured: true },
|
|
182
|
+
},
|
|
183
|
+
openai: {
|
|
184
|
+
nonStreaming: {
|
|
185
|
+
success: false,
|
|
186
|
+
error: { message: `HTTP ${res.status}: ${res.statusText}`, type: "server_error" },
|
|
187
|
+
},
|
|
188
|
+
streaming: { notConfigured: true },
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
if (onTestResultsChange) {
|
|
192
|
+
onTestResultsChange(providerId, errorResult);
|
|
193
|
+
} else {
|
|
194
|
+
setInternalTestResults((prev) => ({ ...prev, [providerId]: errorResult }));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
} catch (err) {
|
|
198
|
+
// Check if this was an abort (timeout)
|
|
199
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
200
|
+
const timeoutResult: TestResults = {
|
|
201
|
+
anthropic: {
|
|
202
|
+
nonStreaming: {
|
|
203
|
+
success: false,
|
|
204
|
+
error: { message: "Request timed out", type: "timeout" },
|
|
205
|
+
},
|
|
206
|
+
streaming: { notConfigured: true },
|
|
207
|
+
},
|
|
208
|
+
openai: {
|
|
209
|
+
nonStreaming: {
|
|
210
|
+
success: false,
|
|
211
|
+
error: { message: "Request timed out", type: "timeout" },
|
|
212
|
+
},
|
|
213
|
+
streaming: { notConfigured: true },
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
if (onTestResultsChange) {
|
|
217
|
+
onTestResultsChange(providerId, timeoutResult);
|
|
218
|
+
} else {
|
|
219
|
+
setInternalTestResults((prev) => ({ ...prev, [providerId]: timeoutResult }));
|
|
220
|
+
}
|
|
165
221
|
}
|
|
166
222
|
} finally {
|
|
167
223
|
clearInterval(intervalId);
|