@tonyclaw/agent-inspector 2.1.15 → 2.1.17
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/cli.js +57 -13
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-BcEd6V-V.js → CompareDrawer-B9sLBHw5.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-DbWjc_BE.js +106 -0
- package/.output/public/assets/{ReplayDialog-BNpC0548.js → ReplayDialog-D9I9W9n3.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-Ds1uRLVB.js → RequestAnatomy-DGXK_Rii.js} +1 -1
- package/.output/public/assets/{ResponseView-7KPVqKl5.js → ResponseView-df_JzwsS.js} +2 -2
- package/.output/public/assets/{StreamingChunkSequence-BHQT261s.js → StreamingChunkSequence-i3DM5IKL.js} +1 -1
- package/.output/public/assets/_sessionId-CTpCHdFh.js +1 -0
- package/.output/public/assets/index-Blqvndcn.js +1 -0
- package/.output/public/assets/index-Cs79WRQj.css +1 -0
- package/.output/public/assets/{index-DjKt8XKe.js → index-Dqc2r1ea.js} +1 -1
- package/.output/public/assets/{json-viewer-CkCu-rka.js → json-viewer-D3QWQlSB.js} +1 -1
- package/.output/public/assets/{main-DpD1N0S8.js → main-ZhxhOCmF.js} +2 -2
- package/.output/server/_libs/lucide-react.mjs +255 -201
- package/.output/server/{_sessionId-DF9Sy8cP.mjs → _sessionId-YFrP0lZP.mjs} +2 -2
- package/.output/server/_ssr/{CompareDrawer-BoxztaO7.mjs → CompareDrawer-qC3adEeq.mjs} +3 -3
- package/.output/server/_ssr/{ProxyViewerContainer-CRBkqFlJ.mjs → ProxyViewerContainer-DCZIJC2b.mjs} +2732 -1849
- package/.output/server/_ssr/{ReplayDialog-Cc1dyDuK.mjs → ReplayDialog-CvX4XYCi.mjs} +4 -4
- package/.output/server/_ssr/{RequestAnatomy-CMGSsz5Z.mjs → RequestAnatomy-HQfrxjO1.mjs} +3 -3
- package/.output/server/_ssr/{ResponseView-Cp10DM1D.mjs → ResponseView-QSlSD11e.mjs} +3 -3
- package/.output/server/_ssr/{StreamingChunkSequence-B1VGxy3A.mjs → StreamingChunkSequence-DTAiwlnI.mjs} +3 -3
- package/.output/server/_ssr/{index-47XVPghS.mjs → index-D_EzfXaN.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-zDE2rrmJ.mjs → json-viewer-CrIX0e0Q.mjs} +3 -3
- package/.output/server/_ssr/{router-DVeuZFqI.mjs → router-__o2wrfO.mjs} +505 -136
- package/.output/server/{_tanstack-start-manifest_v-Bp8JxtPW.mjs → _tanstack-start-manifest_v-DbqyLpsI.mjs} +1 -1
- package/.output/server/index.mjs +63 -63
- package/README.md +57 -2
- package/package.json +1 -1
- package/src/cli/startupOutput.ts +16 -0
- package/src/cli.ts +61 -15
- package/src/components/ProxyViewer.tsx +535 -163
- package/src/components/ProxyViewerContainer.tsx +77 -67
- package/src/components/alerts/AlertsDialog.tsx +2 -1
- package/src/components/clients/ClientLogo.tsx +1 -1
- package/src/components/groups/GroupsDialog.tsx +19 -1
- package/src/components/providers/ProviderCard.tsx +133 -32
- package/src/components/providers/ProviderForm.tsx +61 -29
- package/src/components/providers/ProviderLogo.tsx +6 -1
- package/src/components/providers/ProvidersPanel.tsx +7 -7
- package/src/components/providers/SettingsDialog.tsx +13 -6
- package/src/components/proxy-viewer/AgentTraceSummary.tsx +6 -6
- package/src/components/proxy-viewer/ConversationGroup.tsx +43 -32
- package/src/components/proxy-viewer/ConversationGroupList.tsx +452 -89
- package/src/components/proxy-viewer/ConversationHeader.tsx +153 -120
- package/src/components/proxy-viewer/LogEntry.tsx +130 -43
- package/src/components/proxy-viewer/LogEntryHeader.tsx +357 -354
- package/src/components/proxy-viewer/ProviderLogoStack.tsx +2 -2
- package/src/components/proxy-viewer/RequestToolsPanel.tsx +9 -9
- package/src/components/proxy-viewer/ThreadConnector.tsx +102 -83
- package/src/components/proxy-viewer/TurnGroup.tsx +33 -69
- package/src/components/proxy-viewer/TurnGroupList.tsx +3 -0
- package/src/components/proxy-viewer/bodyHydration.ts +56 -0
- package/src/components/proxy-viewer/viewerState.ts +0 -4
- package/src/components/ui/icon-trigger.ts +2 -0
- package/src/components/ui/transient-toast.tsx +104 -0
- package/src/lib/providerTestContract.ts +56 -10
- package/src/lib/providerTestPrompt.ts +23 -1
- package/src/lib/sessionInfoContract.ts +4 -0
- package/src/lib/upstreamUrl.ts +105 -1
- package/src/mcp/server.ts +71 -27
- package/src/mcp/toolHandlers.ts +24 -5
- package/src/proxy/formats/openai/alibabaProvider.ts +0 -4
- package/src/proxy/sessionInfo.ts +31 -2
- package/src/proxy/sessionSupervisor.ts +20 -1
- package/src/proxy/store.ts +1 -1
- package/src/routes/api/providers.$providerId.test.log.ts +93 -14
- package/styles/globals.css +180 -180
- package/.output/public/assets/ProxyViewerContainer-h851qWNp.js +0 -106
- package/.output/public/assets/_sessionId-DWePGjnS.js +0 -1
- package/.output/public/assets/index-CI1-G8ua.js +0 -1
- package/.output/public/assets/index-DdhFqPsI.css +0 -1
|
@@ -65,7 +65,7 @@ import "../_libs/immediate.mjs";
|
|
|
65
65
|
import "../_libs/setimmediate.mjs";
|
|
66
66
|
import "../_libs/pako.mjs";
|
|
67
67
|
const faviconSvg = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20role='img'%20aria-label='Agent%20Inspector'%3e%3cg%20fill='none'%20stroke='%23f59e0b'%20stroke-width='1.5'%20stroke-linecap='round'%20stroke-linejoin='round'%20%3e%3cpath%20d='M5%2013%20C5%209%208%207%2012%207%20C16%207%2019%209%2019%2013%20C19%2016%2016%2018%2012%2018%20C8%2018%205%2016%205%2013%20Z'%20/%3e%3cpath%20d='M5%2011%20C3.5%209.5%201.5%2010%202%2012.5%20C2.5%2014%204%2013.5%205%2012.5'%20/%3e%3cpath%20d='M19%2011%20C20.5%209.5%2022.5%2010%2022%2012.5%20C21.5%2014%2020%2013.5%2019%2012.5'%20/%3e%3cline%20x1='10'%20y1='7'%20x2='9.5'%20y2='5'%20/%3e%3cline%20x1='14'%20y1='7'%20x2='14.5'%20y2='5'%20/%3e%3cline%20x1='6.5'%20y1='16'%20x2='4.5'%20y2='19.5'%20/%3e%3cline%20x1='9'%20y1='17.5'%20x2='8'%20y2='20.5'%20/%3e%3cline%20x1='15'%20y1='17.5'%20x2='16'%20y2='20.5'%20/%3e%3cline%20x1='17.5'%20y1='16'%20x2='19.5'%20y2='19.5'%20/%3e%3c/g%3e%3ccircle%20cx='9.5'%20cy='4.5'%20r='0.9'%20fill='%23f59e0b'%20/%3e%3ccircle%20cx='14.5'%20cy='4.5'%20r='0.9'%20fill='%23f59e0b'%20/%3e%3c/svg%3e";
|
|
68
|
-
const appCss = "/assets/index-
|
|
68
|
+
const appCss = "/assets/index-Cs79WRQj.css";
|
|
69
69
|
const Route$D = createRootRoute({
|
|
70
70
|
head: () => ({
|
|
71
71
|
meta: [
|
|
@@ -108,7 +108,7 @@ function RootDocument({ children }) {
|
|
|
108
108
|
] })
|
|
109
109
|
] });
|
|
110
110
|
}
|
|
111
|
-
const $$splitComponentImporter$1 = () => import("./index-
|
|
111
|
+
const $$splitComponentImporter$1 = () => import("./index-D_EzfXaN.mjs");
|
|
112
112
|
const Route$C = createFileRoute("/")({
|
|
113
113
|
component: lazyRouteComponent($$splitComponentImporter$1, "component")
|
|
114
114
|
});
|
|
@@ -151,7 +151,7 @@ function decodeSessionIdFromPath(encoded) {
|
|
|
151
151
|
function getSessionPath(sessionId) {
|
|
152
152
|
return `/session/${encodeSessionIdForPath(sessionId)}`;
|
|
153
153
|
}
|
|
154
|
-
const $$splitComponentImporter = () => import("../_sessionId-
|
|
154
|
+
const $$splitComponentImporter = () => import("../_sessionId-YFrP0lZP.mjs");
|
|
155
155
|
const Route$B = createFileRoute("/session/$sessionId")({
|
|
156
156
|
component: lazyRouteComponent($$splitComponentImporter, "component"),
|
|
157
157
|
parseParams: (params) => ({
|
|
@@ -1061,7 +1061,7 @@ function objectFromUnknown$1(value) {
|
|
|
1061
1061
|
if (typeof value === "object" || typeof value === "function") return value;
|
|
1062
1062
|
return null;
|
|
1063
1063
|
}
|
|
1064
|
-
function readProperty$
|
|
1064
|
+
function readProperty$4(value, name) {
|
|
1065
1065
|
let current = objectFromUnknown$1(value);
|
|
1066
1066
|
while (current !== null) {
|
|
1067
1067
|
const desc = Object.getOwnPropertyDescriptor(current, name);
|
|
@@ -1075,7 +1075,7 @@ function readProperty$3(value, name) {
|
|
|
1075
1075
|
return void 0;
|
|
1076
1076
|
}
|
|
1077
1077
|
function readFunction$1(value, name) {
|
|
1078
|
-
const property = readProperty$
|
|
1078
|
+
const property = readProperty$4(value, name);
|
|
1079
1079
|
return typeof property === "function" ? property : null;
|
|
1080
1080
|
}
|
|
1081
1081
|
function callMethod$1(target, methodName, args) {
|
|
@@ -1117,7 +1117,7 @@ function execSql$1(db, sql) {
|
|
|
1117
1117
|
return result !== void 0;
|
|
1118
1118
|
}
|
|
1119
1119
|
function sqliteConstructorFromModule$1(moduleValue, exportName) {
|
|
1120
|
-
const exportedValue = readProperty$
|
|
1120
|
+
const exportedValue = readProperty$4(moduleValue, exportName);
|
|
1121
1121
|
if (typeof exportedValue === "function") {
|
|
1122
1122
|
return (path2) => Reflect.construct(exportedValue, [path2]);
|
|
1123
1123
|
}
|
|
@@ -1260,11 +1260,11 @@ function entryParams(entry) {
|
|
|
1260
1260
|
];
|
|
1261
1261
|
}
|
|
1262
1262
|
function readNumber$1(row, name) {
|
|
1263
|
-
const value = readProperty$
|
|
1263
|
+
const value = readProperty$4(row, name);
|
|
1264
1264
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
1265
1265
|
}
|
|
1266
1266
|
function readString$2(row, name) {
|
|
1267
|
-
const value = readProperty$
|
|
1267
|
+
const value = readProperty$4(row, name);
|
|
1268
1268
|
return typeof value === "string" ? value : null;
|
|
1269
1269
|
}
|
|
1270
1270
|
function readBoolean(row, name) {
|
|
@@ -1849,7 +1849,10 @@ function buildSessionLogSummary(log) {
|
|
|
1849
1849
|
cacheCreate: log.cacheCreationInputTokens,
|
|
1850
1850
|
cacheRead: log.cacheReadInputTokens
|
|
1851
1851
|
},
|
|
1852
|
-
sessionId: normalizeString(log.sessionId)
|
|
1852
|
+
sessionId: normalizeString(log.sessionId),
|
|
1853
|
+
userAgent: normalizeString(log.userAgent),
|
|
1854
|
+
clientPid: log.clientPid ?? null,
|
|
1855
|
+
clientProjectFolder: normalizeString(log.clientProjectFolder)
|
|
1853
1856
|
};
|
|
1854
1857
|
}
|
|
1855
1858
|
function nonNegativeInteger(value) {
|
|
@@ -1895,6 +1898,27 @@ function collectSortedValues$1(values) {
|
|
|
1895
1898
|
}
|
|
1896
1899
|
return [...set].sort();
|
|
1897
1900
|
}
|
|
1901
|
+
function firstSummaryUserAgent(summaries) {
|
|
1902
|
+
for (const summary of summaries) {
|
|
1903
|
+
const value = normalizeString(summary.userAgent);
|
|
1904
|
+
if (value !== null) return value;
|
|
1905
|
+
}
|
|
1906
|
+
return null;
|
|
1907
|
+
}
|
|
1908
|
+
function firstSummaryClientPid(summaries) {
|
|
1909
|
+
for (const summary of summaries) {
|
|
1910
|
+
const value = summary.clientPid;
|
|
1911
|
+
if (value !== null && value !== void 0) return value;
|
|
1912
|
+
}
|
|
1913
|
+
return null;
|
|
1914
|
+
}
|
|
1915
|
+
function firstSummaryProjectFolder(summaries) {
|
|
1916
|
+
for (const summary of summaries) {
|
|
1917
|
+
const value = normalizeString(summary.clientProjectFolder);
|
|
1918
|
+
if (value !== null) return value;
|
|
1919
|
+
}
|
|
1920
|
+
return null;
|
|
1921
|
+
}
|
|
1898
1922
|
function countCompletedLogs(summaries) {
|
|
1899
1923
|
let count = 0;
|
|
1900
1924
|
for (const summary of summaries) {
|
|
@@ -1977,8 +2001,9 @@ function buildSessionInfo(input) {
|
|
|
1977
2001
|
tokenUsage,
|
|
1978
2002
|
lastLogId: input.snapshot?.lastLogId ?? latestLog?.id ?? null,
|
|
1979
2003
|
lastModel: normalizeString(input.snapshot?.lastModel) ?? latestLog?.model ?? null,
|
|
1980
|
-
|
|
1981
|
-
|
|
2004
|
+
clientUserAgent: firstSummaryUserAgent(summaries),
|
|
2005
|
+
clientPid: input.snapshot?.clientPid ?? firstSummaryClientPid(summaries),
|
|
2006
|
+
clientProjectFolder: normalizeString(input.snapshot?.clientProjectFolder) ?? firstSummaryProjectFolder(summaries),
|
|
1982
2007
|
inspectorPath,
|
|
1983
2008
|
inspectorUrl: buildAbsoluteUrl(input.baseUrl, inspectorPath),
|
|
1984
2009
|
apiPath,
|
|
@@ -1994,9 +2019,9 @@ const DEFAULT_OPENAI_UPSTREAM$1 = "https://api.openai.com/v1";
|
|
|
1994
2019
|
const PROXY_IDENTITY = process.env["PROXY_IDENTITY"] ?? "inspector9527@Tony";
|
|
1995
2020
|
const PATH_V1_CHAT_COMPLETIONS$1 = "/v1/chat/completions";
|
|
1996
2021
|
const PATH_CHAT_COMPLETIONS = "/chat/completions";
|
|
1997
|
-
const PATH_V1_RESPONSES = "/v1/responses";
|
|
2022
|
+
const PATH_V1_RESPONSES$1 = "/v1/responses";
|
|
1998
2023
|
const PATH_RESPONSES = "/responses";
|
|
1999
|
-
const PATH_V1_MESSAGES = "/v1/messages";
|
|
2024
|
+
const PATH_V1_MESSAGES$1 = "/v1/messages";
|
|
2000
2025
|
const HEADER_CONTENT_TYPE = "content-type";
|
|
2001
2026
|
const HEADER_USER_AGENT = "user-agent";
|
|
2002
2027
|
const HEADER_X_PROXY_IDENTITY = "x-proxy-identity";
|
|
@@ -2050,10 +2075,10 @@ function formatForPath(path2) {
|
|
|
2050
2075
|
function apiFormatForPath(path2) {
|
|
2051
2076
|
return formatRegistry.getApiFormatByPath(path2) ?? "unknown";
|
|
2052
2077
|
}
|
|
2053
|
-
formatRegistry.registerPath(PATH_V1_MESSAGES, "anthropic");
|
|
2078
|
+
formatRegistry.registerPath(PATH_V1_MESSAGES$1, "anthropic");
|
|
2054
2079
|
formatRegistry.registerPath(PATH_V1_CHAT_COMPLETIONS$1, "openai");
|
|
2055
2080
|
formatRegistry.registerPath(PATH_CHAT_COMPLETIONS, "openai");
|
|
2056
|
-
formatRegistry.registerPath(PATH_V1_RESPONSES, "openai");
|
|
2081
|
+
formatRegistry.registerPath(PATH_V1_RESPONSES$1, "openai");
|
|
2057
2082
|
formatRegistry.registerPath(PATH_RESPONSES, "openai");
|
|
2058
2083
|
const SESSION_ARCHIVE_DIR = "sessions";
|
|
2059
2084
|
const SESSION_ARCHIVE_FILE = "session.sqlite";
|
|
@@ -2105,7 +2130,7 @@ function objectFromUnknown(value) {
|
|
|
2105
2130
|
if (typeof value === "object" || typeof value === "function") return value;
|
|
2106
2131
|
return null;
|
|
2107
2132
|
}
|
|
2108
|
-
function readProperty$
|
|
2133
|
+
function readProperty$3(value, name) {
|
|
2109
2134
|
let current = objectFromUnknown(value);
|
|
2110
2135
|
while (current !== null) {
|
|
2111
2136
|
const desc = Object.getOwnPropertyDescriptor(current, name);
|
|
@@ -2119,7 +2144,7 @@ function readProperty$2(value, name) {
|
|
|
2119
2144
|
return void 0;
|
|
2120
2145
|
}
|
|
2121
2146
|
function readFunction(value, name) {
|
|
2122
|
-
const property = readProperty$
|
|
2147
|
+
const property = readProperty$3(value, name);
|
|
2123
2148
|
return typeof property === "function" ? property : null;
|
|
2124
2149
|
}
|
|
2125
2150
|
function callMethod(target, methodName, args) {
|
|
@@ -2157,7 +2182,7 @@ function closeDatabase(db) {
|
|
|
2157
2182
|
callMethod(db, "close", []);
|
|
2158
2183
|
}
|
|
2159
2184
|
function sqliteConstructorFromModule(moduleValue, exportName) {
|
|
2160
|
-
const exportedValue = readProperty$
|
|
2185
|
+
const exportedValue = readProperty$3(moduleValue, exportName);
|
|
2161
2186
|
if (typeof exportedValue === "function") {
|
|
2162
2187
|
return (path2) => Reflect.construct(exportedValue, [path2]);
|
|
2163
2188
|
}
|
|
@@ -2248,11 +2273,11 @@ async function archiveSessionLog(log) {
|
|
|
2248
2273
|
}
|
|
2249
2274
|
}
|
|
2250
2275
|
function readString$1(row, name) {
|
|
2251
|
-
const value = readProperty$
|
|
2276
|
+
const value = readProperty$3(row, name);
|
|
2252
2277
|
return typeof value === "string" ? value : null;
|
|
2253
2278
|
}
|
|
2254
2279
|
function readNumber(row, name) {
|
|
2255
|
-
const value = readProperty$
|
|
2280
|
+
const value = readProperty$3(row, name);
|
|
2256
2281
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
2257
2282
|
}
|
|
2258
2283
|
function logFromJson(value) {
|
|
@@ -2508,6 +2533,14 @@ function normalizeExplicitSessionId(sessionId) {
|
|
|
2508
2533
|
const trimmed = sessionId.trim();
|
|
2509
2534
|
return trimmed.length > 0 ? trimmed : null;
|
|
2510
2535
|
}
|
|
2536
|
+
function buildProviderTestSessionId(providerId) {
|
|
2537
|
+
const normalizedProviderId = normalizeExplicitSessionId(providerId);
|
|
2538
|
+
if (normalizedProviderId === null) return PROVIDER_TEST_SESSION_ID;
|
|
2539
|
+
return `${PROVIDER_TEST_SESSION_ID}:${normalizedProviderId}`;
|
|
2540
|
+
}
|
|
2541
|
+
function isProviderTestSessionId(sessionId) {
|
|
2542
|
+
return sessionId === PROVIDER_TEST_SESSION_ID || sessionId.startsWith(`${PROVIDER_TEST_SESSION_ID}:`);
|
|
2543
|
+
}
|
|
2511
2544
|
function buildClientSessionId(clientInfo) {
|
|
2512
2545
|
const projectFolder = normalizeExplicitSessionId(clientInfo.projectFolder);
|
|
2513
2546
|
if (clientInfo.pid !== null) {
|
|
@@ -2525,10 +2558,16 @@ function buildClientSessionId(clientInfo) {
|
|
|
2525
2558
|
return { id: null, source: null };
|
|
2526
2559
|
}
|
|
2527
2560
|
function resolveSessionIdentity(input) {
|
|
2561
|
+
const explicit = normalizeExplicitSessionId(input.explicitSessionId);
|
|
2528
2562
|
if (input.isTest === true) {
|
|
2563
|
+
if (explicit !== null) {
|
|
2564
|
+
return {
|
|
2565
|
+
id: explicit,
|
|
2566
|
+
source: isProviderTestSessionId(explicit) ? "provider-test" : "explicit"
|
|
2567
|
+
};
|
|
2568
|
+
}
|
|
2529
2569
|
return { id: PROVIDER_TEST_SESSION_ID, source: "provider-test" };
|
|
2530
2570
|
}
|
|
2531
|
-
const explicit = normalizeExplicitSessionId(input.explicitSessionId);
|
|
2532
2571
|
if (explicit !== null) {
|
|
2533
2572
|
return { id: explicit, source: "explicit" };
|
|
2534
2573
|
}
|
|
@@ -4051,24 +4090,24 @@ const anthropicProvider = {
|
|
|
4051
4090
|
};
|
|
4052
4091
|
registry.register(anthropicProvider);
|
|
4053
4092
|
const MAX_CHUNKS = 1e3;
|
|
4054
|
-
function readProperty$
|
|
4093
|
+
function readProperty$2(value, key) {
|
|
4055
4094
|
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
4056
4095
|
return Object.getOwnPropertyDescriptor(value, key)?.value;
|
|
4057
4096
|
}
|
|
4058
|
-
function readStringProperty$
|
|
4059
|
-
const property = readProperty$
|
|
4097
|
+
function readStringProperty$2(value, key) {
|
|
4098
|
+
const property = readProperty$2(value, key);
|
|
4060
4099
|
return typeof property === "string" ? property : null;
|
|
4061
4100
|
}
|
|
4062
4101
|
function readNumberProperty(value, key) {
|
|
4063
|
-
const property = readProperty$
|
|
4102
|
+
const property = readProperty$2(value, key);
|
|
4064
4103
|
return typeof property === "number" && Number.isFinite(property) ? property : null;
|
|
4065
4104
|
}
|
|
4066
4105
|
function readObjectProperty(value, key) {
|
|
4067
|
-
const property = readProperty$
|
|
4106
|
+
const property = readProperty$2(value, key);
|
|
4068
4107
|
return property !== null && typeof property === "object" && !Array.isArray(property) ? property : null;
|
|
4069
4108
|
}
|
|
4070
|
-
function readArrayProperty(value, key) {
|
|
4071
|
-
const property = readProperty$
|
|
4109
|
+
function readArrayProperty$1(value, key) {
|
|
4110
|
+
const property = readProperty$2(value, key);
|
|
4072
4111
|
return Array.isArray(property) ? property : [];
|
|
4073
4112
|
}
|
|
4074
4113
|
function parseSseEvents(raw) {
|
|
@@ -4136,7 +4175,7 @@ function collectChunk(chunks, chunkIndex, streamStartMs, type, parsed) {
|
|
|
4136
4175
|
}
|
|
4137
4176
|
function setErrorFromPayload(log, payload) {
|
|
4138
4177
|
const errorObject = readObjectProperty(payload, "error");
|
|
4139
|
-
const message = readStringProperty$
|
|
4178
|
+
const message = readStringProperty$2(errorObject, "message") ?? readStringProperty$2(payload, "message") ?? readStringProperty$2(payload, "error");
|
|
4140
4179
|
if (message !== null && message.length > 0) {
|
|
4141
4180
|
log.error = message;
|
|
4142
4181
|
}
|
|
@@ -4260,7 +4299,7 @@ function extractChatCompletionsStream(events, log, fallbackModel, collectChunks)
|
|
|
4260
4299
|
}
|
|
4261
4300
|
function parseResponsesResponse(value) {
|
|
4262
4301
|
const fromResponseProperty = OpenAIResponsesResponseSchema.safeParse(
|
|
4263
|
-
readProperty$
|
|
4302
|
+
readProperty$2(value, "response")
|
|
4264
4303
|
);
|
|
4265
4304
|
if (fromResponseProperty.success) return fromResponseProperty.data;
|
|
4266
4305
|
const direct = OpenAIResponsesResponseSchema.safeParse(value);
|
|
@@ -4272,10 +4311,10 @@ function responseTextFromOutput(response) {
|
|
|
4272
4311
|
}
|
|
4273
4312
|
const parts = [];
|
|
4274
4313
|
for (const outputItem of response.output ?? []) {
|
|
4275
|
-
const content = readArrayProperty(outputItem, "content");
|
|
4314
|
+
const content = readArrayProperty$1(outputItem, "content");
|
|
4276
4315
|
for (const contentPart of content) {
|
|
4277
|
-
const type = readStringProperty$
|
|
4278
|
-
const text = readStringProperty$
|
|
4316
|
+
const type = readStringProperty$2(contentPart, "type");
|
|
4317
|
+
const text = readStringProperty$2(contentPart, "text");
|
|
4279
4318
|
if ((type === "output_text" || type === "text") && text !== null && text.length > 0) {
|
|
4280
4319
|
parts.push(text);
|
|
4281
4320
|
}
|
|
@@ -4294,7 +4333,7 @@ function updateUsageFromResponse(response, log) {
|
|
|
4294
4333
|
return { inputTokens, outputTokens };
|
|
4295
4334
|
}
|
|
4296
4335
|
function functionCallKey(payload, fallbackIndex) {
|
|
4297
|
-
const itemId = readStringProperty$
|
|
4336
|
+
const itemId = readStringProperty$2(payload, "item_id");
|
|
4298
4337
|
if (itemId !== null && itemId.length > 0) return itemId;
|
|
4299
4338
|
const outputIndex = readNumberProperty(payload, "output_index");
|
|
4300
4339
|
if (outputIndex !== null) return String(outputIndex);
|
|
@@ -4311,13 +4350,13 @@ function ensureFunctionCall(calls, key) {
|
|
|
4311
4350
|
return created;
|
|
4312
4351
|
}
|
|
4313
4352
|
function updateFunctionCallFromItem(calls, key, item) {
|
|
4314
|
-
if (readStringProperty$
|
|
4353
|
+
if (readStringProperty$2(item, "type") !== "function_call") return;
|
|
4315
4354
|
const call = ensureFunctionCall(calls, key);
|
|
4316
|
-
const id = readStringProperty$
|
|
4317
|
-
const callId = readStringProperty$
|
|
4318
|
-
const name = readStringProperty$
|
|
4319
|
-
const args = readStringProperty$
|
|
4320
|
-
const status = readStringProperty$
|
|
4355
|
+
const id = readStringProperty$2(item, "id");
|
|
4356
|
+
const callId = readStringProperty$2(item, "call_id");
|
|
4357
|
+
const name = readStringProperty$2(item, "name");
|
|
4358
|
+
const args = readStringProperty$2(item, "arguments");
|
|
4359
|
+
const status = readStringProperty$2(item, "status");
|
|
4321
4360
|
if (id !== null) call.id = id;
|
|
4322
4361
|
if (callId !== null) call.call_id = callId;
|
|
4323
4362
|
if (name !== null) call.name = name;
|
|
@@ -4405,13 +4444,13 @@ function extractResponsesStream(events, log, fallbackModel, collectChunks) {
|
|
|
4405
4444
|
outputTokens = usage.outputTokens ?? outputTokens;
|
|
4406
4445
|
setErrorFromPayload(log, response);
|
|
4407
4446
|
}
|
|
4408
|
-
const delta = readStringProperty$
|
|
4447
|
+
const delta = readStringProperty$2(parsed, "delta");
|
|
4409
4448
|
switch (type) {
|
|
4410
4449
|
case "response.output_text.delta":
|
|
4411
4450
|
if (delta !== null) outputText += delta;
|
|
4412
4451
|
break;
|
|
4413
4452
|
case "response.output_text.done": {
|
|
4414
|
-
const text = readStringProperty$
|
|
4453
|
+
const text = readStringProperty$2(parsed, "text");
|
|
4415
4454
|
if (outputText.length === 0 && text !== null) outputText = text;
|
|
4416
4455
|
break;
|
|
4417
4456
|
}
|
|
@@ -4423,7 +4462,7 @@ function extractResponsesStream(events, log, fallbackModel, collectChunks) {
|
|
|
4423
4462
|
break;
|
|
4424
4463
|
}
|
|
4425
4464
|
case "response.function_call_arguments.done": {
|
|
4426
|
-
const args = readStringProperty$
|
|
4465
|
+
const args = readStringProperty$2(parsed, "arguments");
|
|
4427
4466
|
if (args !== null) {
|
|
4428
4467
|
const call = ensureFunctionCall(calls, functionCallKey(parsed, calls.size));
|
|
4429
4468
|
call.arguments = args;
|
|
@@ -4472,7 +4511,7 @@ function extractResponsesStream(events, log, fallbackModel, collectChunks) {
|
|
|
4472
4511
|
return JSON.stringify(normalizedResponse.data);
|
|
4473
4512
|
}
|
|
4474
4513
|
if (log.outputTokens === null) {
|
|
4475
|
-
const finalText = readStringProperty$
|
|
4514
|
+
const finalText = readStringProperty$2(normalized, "output_text") ?? outputText;
|
|
4476
4515
|
const estimatedOutputTokens = Math.ceil(finalText.length / 4);
|
|
4477
4516
|
log.outputTokens = estimatedOutputTokens;
|
|
4478
4517
|
}
|
|
@@ -4622,9 +4661,6 @@ const alibabaProvider = {
|
|
|
4622
4661
|
name: "alibaba",
|
|
4623
4662
|
matches(model) {
|
|
4624
4663
|
const m = model.toLowerCase().replace(/\s+/g, "-");
|
|
4625
|
-
if (m.startsWith("glm-5")) {
|
|
4626
|
-
return true;
|
|
4627
|
-
}
|
|
4628
4664
|
if (m.startsWith("qwen")) {
|
|
4629
4665
|
return true;
|
|
4630
4666
|
}
|
|
@@ -6215,7 +6251,7 @@ function parseJson$1(raw) {
|
|
|
6215
6251
|
function isRecord$1(value) {
|
|
6216
6252
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6217
6253
|
}
|
|
6218
|
-
function readProperty(value, key) {
|
|
6254
|
+
function readProperty$1(value, key) {
|
|
6219
6255
|
if (!isRecord$1(value)) return void 0;
|
|
6220
6256
|
return Object.getOwnPropertyDescriptor(value, key)?.value;
|
|
6221
6257
|
}
|
|
@@ -6223,18 +6259,18 @@ function hasOwnProperty(value, key) {
|
|
|
6223
6259
|
return Object.getOwnPropertyDescriptor(value, key) !== void 0;
|
|
6224
6260
|
}
|
|
6225
6261
|
function readString(value, key) {
|
|
6226
|
-
const property = readProperty(value, key);
|
|
6262
|
+
const property = readProperty$1(value, key);
|
|
6227
6263
|
return typeof property === "string" ? property : null;
|
|
6228
6264
|
}
|
|
6229
6265
|
function readArray(value, key) {
|
|
6230
|
-
const property = readProperty(value, key);
|
|
6266
|
+
const property = readProperty$1(value, key);
|
|
6231
6267
|
return Array.isArray(property) ? property : [];
|
|
6232
6268
|
}
|
|
6233
6269
|
function readStringArray(value, key) {
|
|
6234
6270
|
return readArray(value, key).filter((item) => typeof item === "string");
|
|
6235
6271
|
}
|
|
6236
6272
|
function readObject(value, key) {
|
|
6237
|
-
const property = readProperty(value, key);
|
|
6273
|
+
const property = readProperty$1(value, key);
|
|
6238
6274
|
return isRecord$1(property) ? property : null;
|
|
6239
6275
|
}
|
|
6240
6276
|
function normalizeExpectedType(typeName) {
|
|
@@ -6252,7 +6288,7 @@ function normalizeExpectedType(typeName) {
|
|
|
6252
6288
|
}
|
|
6253
6289
|
}
|
|
6254
6290
|
function schemaTypes(schema) {
|
|
6255
|
-
const typeValue = readProperty(schema, "type");
|
|
6291
|
+
const typeValue = readProperty$1(schema, "type");
|
|
6256
6292
|
const rawTypes = Array.isArray(typeValue) ? typeValue : [typeValue];
|
|
6257
6293
|
const types = [];
|
|
6258
6294
|
for (const rawType of rawTypes) {
|
|
@@ -6342,7 +6378,7 @@ function schemaAllowsObjectValidation(schema, expectedTypes) {
|
|
|
6342
6378
|
return expectedTypes.includes("object");
|
|
6343
6379
|
}
|
|
6344
6380
|
function schemaAllowsArrayValidation(schema, expectedTypes) {
|
|
6345
|
-
if (expectedTypes.length === 0) return readProperty(schema, "items") !== void 0;
|
|
6381
|
+
if (expectedTypes.length === 0) return readProperty$1(schema, "items") !== void 0;
|
|
6346
6382
|
return expectedTypes.includes("array");
|
|
6347
6383
|
}
|
|
6348
6384
|
function addTypeWarning(warnings, toolName, path2, expectedTypes, value) {
|
|
@@ -6375,7 +6411,7 @@ function validateObjectSchema(schema, value, toolName, path2, warnings) {
|
|
|
6375
6411
|
}
|
|
6376
6412
|
}
|
|
6377
6413
|
function validateArraySchema(schema, value, toolName, path2, warnings) {
|
|
6378
|
-
const itemsSchema = readProperty(schema, "items");
|
|
6414
|
+
const itemsSchema = readProperty$1(schema, "items");
|
|
6379
6415
|
if (itemsSchema === void 0) return;
|
|
6380
6416
|
let index = 0;
|
|
6381
6417
|
for (const item of value) {
|
|
@@ -6384,7 +6420,7 @@ function validateArraySchema(schema, value, toolName, path2, warnings) {
|
|
|
6384
6420
|
}
|
|
6385
6421
|
}
|
|
6386
6422
|
function validateEnum(schema, value, toolName, path2, warnings) {
|
|
6387
|
-
const enumValue = readProperty(schema, "enum");
|
|
6423
|
+
const enumValue = readProperty$1(schema, "enum");
|
|
6388
6424
|
if (Array.isArray(enumValue) && enumValue.length > 0 && !enumMatches(value, enumValue)) {
|
|
6389
6425
|
warnings.push(
|
|
6390
6426
|
`Tool call "${toolName}" ${pathLabel(path2)} expected one of ${formatJsonValue(
|
|
@@ -6501,7 +6537,7 @@ function extractOpenAIToolCalls(response) {
|
|
|
6501
6537
|
for (const call of readArray(message, "tool_calls")) {
|
|
6502
6538
|
const functionCall = readObject(call, "function");
|
|
6503
6539
|
const name = functionCall === null ? null : readString(functionCall, "name");
|
|
6504
|
-
const parsedArguments = functionCall === null ? { value: {}, issue: "function block is missing" } : parseOpenAIArguments(readProperty(functionCall, "arguments"));
|
|
6540
|
+
const parsedArguments = functionCall === null ? { value: {}, issue: "function block is missing" } : parseOpenAIArguments(readProperty$1(functionCall, "arguments"));
|
|
6505
6541
|
calls.push({
|
|
6506
6542
|
name,
|
|
6507
6543
|
arguments: parsedArguments.value,
|
|
@@ -6512,7 +6548,7 @@ function extractOpenAIToolCalls(response) {
|
|
|
6512
6548
|
}
|
|
6513
6549
|
const legacyFunctionCall = readObject(message, "function_call");
|
|
6514
6550
|
if (legacyFunctionCall !== null) {
|
|
6515
|
-
const parsedArguments = parseOpenAIArguments(readProperty(legacyFunctionCall, "arguments"));
|
|
6551
|
+
const parsedArguments = parseOpenAIArguments(readProperty$1(legacyFunctionCall, "arguments"));
|
|
6516
6552
|
calls.push({
|
|
6517
6553
|
name: readString(legacyFunctionCall, "name"),
|
|
6518
6554
|
arguments: parsedArguments.value,
|
|
@@ -6528,7 +6564,7 @@ function extractOpenAIToolCalls(response) {
|
|
|
6528
6564
|
outputIndex++;
|
|
6529
6565
|
continue;
|
|
6530
6566
|
}
|
|
6531
|
-
const parsedArguments = parseOpenAIArguments(readProperty(item, "arguments"));
|
|
6567
|
+
const parsedArguments = parseOpenAIArguments(readProperty$1(item, "arguments"));
|
|
6532
6568
|
calls.push({
|
|
6533
6569
|
name: readString(item, "name"),
|
|
6534
6570
|
arguments: parsedArguments.value,
|
|
@@ -6549,7 +6585,7 @@ function extractAnthropicToolCalls(response) {
|
|
|
6549
6585
|
}
|
|
6550
6586
|
calls.push({
|
|
6551
6587
|
name: readString(block, "name"),
|
|
6552
|
-
arguments: readProperty(block, "input") ?? {},
|
|
6588
|
+
arguments: readProperty$1(block, "input") ?? {},
|
|
6553
6589
|
argumentIssue: null,
|
|
6554
6590
|
location: `content[${contentIndex}]`
|
|
6555
6591
|
});
|
|
@@ -7118,9 +7154,11 @@ class RawStreamCapture {
|
|
|
7118
7154
|
}
|
|
7119
7155
|
}
|
|
7120
7156
|
const PATH_V1_CHAT_COMPLETIONS = "/v1/chat/completions";
|
|
7157
|
+
const PATH_V1_RESPONSES = "/v1/responses";
|
|
7158
|
+
const PATH_V1_MESSAGES = "/v1/messages";
|
|
7121
7159
|
function buildUpstreamUrl(upstreamBase, normalizedPath) {
|
|
7122
7160
|
const base = upstreamBase.endsWith("/") ? upstreamBase.slice(0, -1) : upstreamBase;
|
|
7123
|
-
const endpointPath = normalizedPath
|
|
7161
|
+
const endpointPath = endpointPathFor(normalizedPath);
|
|
7124
7162
|
const queryIndex = normalizedPath.indexOf("?");
|
|
7125
7163
|
const search = queryIndex >= 0 ? normalizedPath.slice(queryIndex) : "";
|
|
7126
7164
|
if (endpointPath !== "" && base.endsWith(endpointPath)) {
|
|
@@ -7134,9 +7172,78 @@ function buildUpstreamUrl(upstreamBase, normalizedPath) {
|
|
|
7134
7172
|
}
|
|
7135
7173
|
return base + normalizedPath;
|
|
7136
7174
|
}
|
|
7175
|
+
function previewUpstreamUrl(upstreamBase, normalizedPath, options = {}) {
|
|
7176
|
+
const base = upstreamBase.trim().replace(/\/+$/, "");
|
|
7177
|
+
const endpointPath = endpointPathFor(normalizedPath);
|
|
7178
|
+
const finalUrl = buildUpstreamUrl(base, normalizedPath);
|
|
7179
|
+
const diagnostics = [];
|
|
7180
|
+
const exactEndpoint = endpointPath !== "" && base.endsWith(endpointPath);
|
|
7181
|
+
if (exactEndpoint) {
|
|
7182
|
+
diagnostics.push({
|
|
7183
|
+
severity: "info",
|
|
7184
|
+
message: "This already includes the exact endpoint; no duplicate suffix will be appended."
|
|
7185
|
+
});
|
|
7186
|
+
} else if (isZhipuVersionedOpenAIBase(base) && isVersionedChatCompletionsPath(normalizedPath)) {
|
|
7187
|
+
diagnostics.push({
|
|
7188
|
+
severity: "info",
|
|
7189
|
+
message: "Zhipu bases already include the API version; only /chat/completions is appended."
|
|
7190
|
+
});
|
|
7191
|
+
} else if (base.endsWith("/v1") && normalizedPath.startsWith("/v1/")) {
|
|
7192
|
+
diagnostics.push({
|
|
7193
|
+
severity: "info",
|
|
7194
|
+
message: "Base URL already ends with /v1; the suffix will not repeat /v1."
|
|
7195
|
+
});
|
|
7196
|
+
}
|
|
7197
|
+
if (isResponsesPath(endpointPath) && baseEndsWithChatEndpoint(base)) {
|
|
7198
|
+
diagnostics.push({
|
|
7199
|
+
severity: "warning",
|
|
7200
|
+
message: "This looks like a Chat Completions endpoint, so Responses would append after it."
|
|
7201
|
+
});
|
|
7202
|
+
}
|
|
7203
|
+
if (isChatCompletionsPath(endpointPath) && baseEndsWithResponsesEndpoint(base)) {
|
|
7204
|
+
diagnostics.push({
|
|
7205
|
+
severity: "warning",
|
|
7206
|
+
message: "This looks like a Responses endpoint, so Chat Completions would append after it."
|
|
7207
|
+
});
|
|
7208
|
+
}
|
|
7209
|
+
if (isResponsesPath(endpointPath) && isLikelyDeepSeekBase(base, options.providerName)) {
|
|
7210
|
+
diagnostics.push({
|
|
7211
|
+
severity: "warning",
|
|
7212
|
+
message: "DeepSeek's official API does not currently expose OpenAI Responses."
|
|
7213
|
+
});
|
|
7214
|
+
}
|
|
7215
|
+
return { finalUrl, diagnostics };
|
|
7216
|
+
}
|
|
7217
|
+
function endpointPathFor(normalizedPath) {
|
|
7218
|
+
return normalizedPath.split("?")[0] ?? normalizedPath;
|
|
7219
|
+
}
|
|
7137
7220
|
function isVersionedChatCompletionsPath(normalizedPath) {
|
|
7138
7221
|
return normalizedPath === PATH_V1_CHAT_COMPLETIONS || normalizedPath.startsWith(`${PATH_V1_CHAT_COMPLETIONS}?`) || normalizedPath.startsWith(`${PATH_V1_CHAT_COMPLETIONS}/`);
|
|
7139
7222
|
}
|
|
7223
|
+
function isChatCompletionsPath(endpointPath) {
|
|
7224
|
+
return endpointPath === PATH_V1_CHAT_COMPLETIONS || endpointPath.startsWith(`${PATH_V1_CHAT_COMPLETIONS}/`);
|
|
7225
|
+
}
|
|
7226
|
+
function isResponsesPath(endpointPath) {
|
|
7227
|
+
return endpointPath === PATH_V1_RESPONSES || endpointPath.startsWith(`${PATH_V1_RESPONSES}/`);
|
|
7228
|
+
}
|
|
7229
|
+
function baseEndsWithChatEndpoint(base) {
|
|
7230
|
+
const normalized = base.toLowerCase();
|
|
7231
|
+
return normalized.endsWith("/chat/completions");
|
|
7232
|
+
}
|
|
7233
|
+
function baseEndsWithResponsesEndpoint(base) {
|
|
7234
|
+
const normalized = base.toLowerCase();
|
|
7235
|
+
return normalized.endsWith("/responses");
|
|
7236
|
+
}
|
|
7237
|
+
function isLikelyDeepSeekBase(base, providerName) {
|
|
7238
|
+
const provider = providerName?.toLowerCase();
|
|
7239
|
+
if (provider !== void 0 && provider.includes("deepseek")) return true;
|
|
7240
|
+
try {
|
|
7241
|
+
const parsed = new URL(base);
|
|
7242
|
+
return parsed.hostname.toLowerCase().includes("deepseek");
|
|
7243
|
+
} catch {
|
|
7244
|
+
return base.toLowerCase().includes("deepseek");
|
|
7245
|
+
}
|
|
7246
|
+
}
|
|
7140
7247
|
function isZhipuVersionedOpenAIBase(base) {
|
|
7141
7248
|
try {
|
|
7142
7249
|
const parsed = new URL(base);
|
|
@@ -7149,7 +7256,7 @@ function isZhipuVersionedOpenAIBase(base) {
|
|
|
7149
7256
|
function describeApiRoute(apiPath) {
|
|
7150
7257
|
const endpointPath = apiPath.split("?")[0] ?? "";
|
|
7151
7258
|
const isChatCompletions = endpointPath === PATH_CHAT_COMPLETIONS || endpointPath === PATH_V1_CHAT_COMPLETIONS$1;
|
|
7152
|
-
const isResponses = endpointPath === PATH_RESPONSES || endpointPath === PATH_V1_RESPONSES;
|
|
7259
|
+
const isResponses = endpointPath === PATH_RESPONSES || endpointPath === PATH_V1_RESPONSES$1;
|
|
7153
7260
|
const isOpenAI = isChatCompletions || isResponses;
|
|
7154
7261
|
const normalizedPath = isOpenAI && !apiPath.startsWith("/v1/") ? `/v1${apiPath}` : apiPath;
|
|
7155
7262
|
return { apiPath, endpointPath, isChatCompletions, isResponses, isOpenAI, normalizedPath };
|
|
@@ -7219,7 +7326,7 @@ function parseRequestPath(req, url) {
|
|
|
7219
7326
|
const route = describeApiRoute(getProxyApiPath(url));
|
|
7220
7327
|
const isPost = req.method === "POST";
|
|
7221
7328
|
const isChatCompletions = isPost && route.isChatCompletions;
|
|
7222
|
-
const isMessages = isPost && (route.endpointPath === PATH_V1_MESSAGES || route.isChatCompletions);
|
|
7329
|
+
const isMessages = isPost && (route.endpointPath === PATH_V1_MESSAGES$1 || route.isChatCompletions);
|
|
7223
7330
|
return {
|
|
7224
7331
|
apiPath: route.apiPath,
|
|
7225
7332
|
isMessages,
|
|
@@ -7508,7 +7615,10 @@ const SessionLogSummarySchema = object({
|
|
|
7508
7615
|
cacheCreate: number().nullable(),
|
|
7509
7616
|
cacheRead: number().nullable()
|
|
7510
7617
|
}),
|
|
7511
|
-
sessionId: string().nullable()
|
|
7618
|
+
sessionId: string().nullable(),
|
|
7619
|
+
userAgent: string().nullable().optional(),
|
|
7620
|
+
clientPid: number().nullable().optional(),
|
|
7621
|
+
clientProjectFolder: string().nullable().optional()
|
|
7512
7622
|
});
|
|
7513
7623
|
const SessionInfoSchema = object({
|
|
7514
7624
|
id: string(),
|
|
@@ -7532,6 +7642,7 @@ const SessionInfoSchema = object({
|
|
|
7532
7642
|
tokenUsage: SessionTokenUsageSchema,
|
|
7533
7643
|
lastLogId: number().nullable(),
|
|
7534
7644
|
lastModel: string().nullable(),
|
|
7645
|
+
clientUserAgent: string().nullable().optional(),
|
|
7535
7646
|
clientPid: number().nullable(),
|
|
7536
7647
|
clientProjectFolder: string().nullable(),
|
|
7537
7648
|
inspectorPath: string(),
|
|
@@ -8976,7 +9087,7 @@ const Route$w = createFileRoute("/api/models")({
|
|
|
8976
9087
|
}
|
|
8977
9088
|
}
|
|
8978
9089
|
});
|
|
8979
|
-
const version = "2.1.
|
|
9090
|
+
const version = "2.1.17";
|
|
8980
9091
|
const packageJson = {
|
|
8981
9092
|
version
|
|
8982
9093
|
};
|
|
@@ -9686,7 +9797,10 @@ function buildLogSummary(log) {
|
|
|
9686
9797
|
cacheRead: log.cacheReadInputTokens
|
|
9687
9798
|
},
|
|
9688
9799
|
sessionId: log.sessionId,
|
|
9800
|
+
userAgent: log.userAgent ?? null,
|
|
9689
9801
|
clientPid: log.clientPid ?? null,
|
|
9802
|
+
clientCwd: log.clientCwd ?? null,
|
|
9803
|
+
clientProjectFolder: log.clientProjectFolder ?? null,
|
|
9690
9804
|
lastUserMessagePreview: extractLastUserMessagePreview(log),
|
|
9691
9805
|
responsePreview: extractResponsePreview(log),
|
|
9692
9806
|
hasChunks: log.streamingChunks !== void 0 && log.streamingChunks !== null || log.streamingChunksPath !== null && log.streamingChunksPath !== void 0,
|
|
@@ -10056,21 +10170,31 @@ async function replayLogImpl(callApi2, args) {
|
|
|
10056
10170
|
}
|
|
10057
10171
|
return textJson(await replayRes.json());
|
|
10058
10172
|
}
|
|
10173
|
+
function normalizedProviderModels(input) {
|
|
10174
|
+
const modelList = input.models ?? [];
|
|
10175
|
+
const models = modelList.map((model2) => model2.trim()).filter((model2) => model2 !== "");
|
|
10176
|
+
if (models.length > 0) return models;
|
|
10177
|
+
const model = input.model?.trim();
|
|
10178
|
+
return model !== void 0 && model !== "" ? [model] : [];
|
|
10179
|
+
}
|
|
10059
10180
|
async function addProviderImpl(callApi2, provider) {
|
|
10181
|
+
const models = normalizedProviderModels(provider);
|
|
10060
10182
|
const res = await callApi2("/api/providers", {
|
|
10061
10183
|
method: "POST",
|
|
10062
10184
|
headers: { "content-type": "application/json" },
|
|
10063
|
-
body: JSON.stringify(provider)
|
|
10185
|
+
body: JSON.stringify({ ...provider, models })
|
|
10064
10186
|
});
|
|
10065
10187
|
if (!res.ok) return toolError(`POST /api/providers returned ${res.status}`);
|
|
10066
10188
|
return textJson(await res.json());
|
|
10067
10189
|
}
|
|
10068
10190
|
async function updateProviderImpl(callApi2, input) {
|
|
10069
10191
|
const { id, ...patch } = input;
|
|
10192
|
+
const models = patch.models !== void 0 || patch.model !== void 0 ? normalizedProviderModels(patch) : void 0;
|
|
10193
|
+
const body = models === void 0 ? patch : { ...patch, models };
|
|
10070
10194
|
const res = await callApi2(`/api/providers/${encodeURIComponent(id)}`, {
|
|
10071
10195
|
method: "PUT",
|
|
10072
10196
|
headers: { "content-type": "application/json" },
|
|
10073
|
-
body: JSON.stringify(
|
|
10197
|
+
body: JSON.stringify(body)
|
|
10074
10198
|
});
|
|
10075
10199
|
if (!res.ok) return toolError(`PUT /api/providers/${id} returned ${res.status}`);
|
|
10076
10200
|
return textJson(await res.json());
|
|
@@ -10171,7 +10295,7 @@ function providerDiagnosticHints(result) {
|
|
|
10171
10295
|
}
|
|
10172
10296
|
if (text.includes("nonstream") || text.includes("non-stream")) {
|
|
10173
10297
|
hints.push(
|
|
10174
|
-
"The failure mentions non-streaming. Compare the
|
|
10298
|
+
"The failure mentions non-streaming. Compare the Anthropic, OpenAI Chat, and OpenAI Responses non-streaming path and payload with the streaming request."
|
|
10175
10299
|
);
|
|
10176
10300
|
}
|
|
10177
10301
|
return [...new Set(hints)];
|
|
@@ -10302,13 +10426,46 @@ Parameters:
|
|
|
10302
10426
|
Returns: array of "thick summary" objects, each containing:
|
|
10303
10427
|
- id, timestamp, provider, model, apiFormat, method, path, status, isStreaming,
|
|
10304
10428
|
hasError, latencyMs, tokens { input, output, cacheCreate, cacheRead },
|
|
10305
|
-
sessionId, clientPid,
|
|
10429
|
+
sessionId, userAgent, clientPid, clientCwd, clientProjectFolder,
|
|
10306
10430
|
- lastUserMessagePreview (string|null, ≤500 chars) — first text block of the last user message, parsed via the format-specific schema (NOT a raw body slice)
|
|
10307
10431
|
- responsePreview (string|null, ≤500 chars) — first text block of the assistant response
|
|
10308
10432
|
- hasChunks, hasRawRequestBody (booleans)
|
|
10309
10433
|
|
|
10310
10434
|
Either preview field is null when the body is unknown format, unparseable, or the relevant content is non-text (e.g., image-only).`;
|
|
10311
10435
|
const PROVIDER_WRITE_WARNING = "⚠ This tool mutates provider configuration. Confirm with the user before invoking.";
|
|
10436
|
+
const AddProviderInputSchema = object({
|
|
10437
|
+
name: string().min(1).describe("Provider display name."),
|
|
10438
|
+
apiKey: string().min(1).describe("Plaintext provider API key."),
|
|
10439
|
+
format: _enum(["anthropic", "openai"]).optional().describe("Primary API family. Use openai for Chat Completions or Responses providers."),
|
|
10440
|
+
model: string().min(1).optional().describe("Legacy single-model input. Prefer models for new clients."),
|
|
10441
|
+
models: array(string().min(1)).min(1).optional().describe("Provider model names."),
|
|
10442
|
+
anthropicBaseUrl: string().optional().describe("Anthropic-compatible base or exact /v1/messages endpoint."),
|
|
10443
|
+
openaiBaseUrl: string().optional().describe("OpenAI Chat Completions base or exact /v1/chat/completions endpoint."),
|
|
10444
|
+
openaiResponsesBaseUrl: string().optional().describe(
|
|
10445
|
+
"OpenAI Responses base or exact /v1/responses endpoint. MiniMax default endpoint is https://api.minimaxi.com/v1/responses."
|
|
10446
|
+
),
|
|
10447
|
+
authHeader: _enum(["bearer", "x-api-key"]).optional(),
|
|
10448
|
+
apiDocsUrl: string().optional()
|
|
10449
|
+
}).refine(
|
|
10450
|
+
(input) => input.model !== void 0 || input.models !== void 0 && input.models.length > 0,
|
|
10451
|
+
{ message: "Provide models or legacy model." }
|
|
10452
|
+
);
|
|
10453
|
+
const UpdateProviderInputSchema = object({
|
|
10454
|
+
id: string().describe("The provider id to update."),
|
|
10455
|
+
name: string().min(1).optional(),
|
|
10456
|
+
apiKey: string().min(1).optional(),
|
|
10457
|
+
format: _enum(["anthropic", "openai"]).optional(),
|
|
10458
|
+
model: string().min(1).optional().describe("Legacy single-model input. Prefer models."),
|
|
10459
|
+
models: array(string().min(1)).optional().describe("Replace provider model names."),
|
|
10460
|
+
baseUrl: string().min(1).optional().describe("Legacy route URL retained for old configs; prefer format-specific URL fields."),
|
|
10461
|
+
authHeader: _enum(["bearer", "x-api-key"]).optional(),
|
|
10462
|
+
anthropicBaseUrl: string().optional().describe("Anthropic-compatible base or exact /v1/messages endpoint."),
|
|
10463
|
+
openaiBaseUrl: string().optional().describe("OpenAI Chat Completions base or exact /v1/chat/completions endpoint."),
|
|
10464
|
+
openaiResponsesBaseUrl: string().optional().describe(
|
|
10465
|
+
"OpenAI Responses base or exact /v1/responses endpoint. MiniMax default endpoint is https://api.minimaxi.com/v1/responses."
|
|
10466
|
+
),
|
|
10467
|
+
apiDocsUrl: string().optional()
|
|
10468
|
+
});
|
|
10312
10469
|
const LogResourceListResponseSchema = object({
|
|
10313
10470
|
logs: array(object({ id: number().int().positive() }))
|
|
10314
10471
|
});
|
|
@@ -10979,18 +11136,8 @@ function registerTools(server) {
|
|
|
10979
11136
|
title: "Add a new LLM provider",
|
|
10980
11137
|
description: `${PROVIDER_WRITE_WARNING}
|
|
10981
11138
|
|
|
10982
|
-
Persists a new provider to <dataDir>/providers.json. Required fields: name, apiKey,
|
|
10983
|
-
inputSchema:
|
|
10984
|
-
name: string().min(1),
|
|
10985
|
-
apiKey: string().min(1),
|
|
10986
|
-
format: _enum(["anthropic", "openai"]),
|
|
10987
|
-
model: string().min(1),
|
|
10988
|
-
anthropicBaseUrl: string().optional(),
|
|
10989
|
-
openaiBaseUrl: string().optional(),
|
|
10990
|
-
openaiResponsesBaseUrl: string().optional(),
|
|
10991
|
-
authHeader: _enum(["bearer", "x-api-key"]).optional(),
|
|
10992
|
-
apiDocsUrl: string().optional()
|
|
10993
|
-
})
|
|
11139
|
+
Persists a new provider to <dataDir>/providers.json. Required fields: name, apiKey, and models (or legacy model). Chat Completions and Responses can use different upstream URLs: set openaiBaseUrl for /v1/chat/completions and openaiResponsesBaseUrl for /v1/responses. The URL builder accepts either a base URL such as https://api.minimaxi.com or an exact endpoint such as https://api.minimaxi.com/v1/responses.`,
|
|
11140
|
+
inputSchema: AddProviderInputSchema
|
|
10994
11141
|
},
|
|
10995
11142
|
(provider) => safeWriteCall("inspector_add_provider", () => addProviderImpl(callApi, provider))
|
|
10996
11143
|
);
|
|
@@ -11000,20 +11147,8 @@ Persists a new provider to <dataDir>/providers.json. Required fields: name, apiK
|
|
|
11000
11147
|
title: "Update an existing provider",
|
|
11001
11148
|
description: `${PROVIDER_WRITE_WARNING} Updating with nonsense values effectively soft-deletes a provider. Confirm with the user before invoking.
|
|
11002
11149
|
|
|
11003
|
-
PATCH-style update: only the fields you supply are changed.
|
|
11004
|
-
inputSchema:
|
|
11005
|
-
id: string().describe("The provider id to update."),
|
|
11006
|
-
name: string().min(1).optional(),
|
|
11007
|
-
apiKey: string().min(1).optional(),
|
|
11008
|
-
format: _enum(["anthropic", "openai"]).optional(),
|
|
11009
|
-
model: string().min(1).optional(),
|
|
11010
|
-
baseUrl: string().min(1).optional(),
|
|
11011
|
-
authHeader: _enum(["bearer", "x-api-key"]).optional(),
|
|
11012
|
-
anthropicBaseUrl: string().optional(),
|
|
11013
|
-
openaiBaseUrl: string().optional(),
|
|
11014
|
-
openaiResponsesBaseUrl: string().optional(),
|
|
11015
|
-
apiDocsUrl: string().optional()
|
|
11016
|
-
})
|
|
11150
|
+
PATCH-style update: only the fields you supply are changed. Use models to update the configured model list. For OpenAI-compatible providers, openaiBaseUrl targets /v1/chat/completions and openaiResponsesBaseUrl targets /v1/responses, and those endpoints may be different.`,
|
|
11151
|
+
inputSchema: UpdateProviderInputSchema
|
|
11017
11152
|
},
|
|
11018
11153
|
(input) => safeWriteCall("inspector_update_provider", () => updateProviderImpl(callApi, input))
|
|
11019
11154
|
);
|
|
@@ -13165,7 +13300,7 @@ function parseJsonlLogs(text) {
|
|
|
13165
13300
|
}
|
|
13166
13301
|
return { logs, skipped };
|
|
13167
13302
|
}
|
|
13168
|
-
function readStringProperty(value, name) {
|
|
13303
|
+
function readStringProperty$1(value, name) {
|
|
13169
13304
|
const property = readRecordProperty(value, name);
|
|
13170
13305
|
return typeof property === "string" ? property : null;
|
|
13171
13306
|
}
|
|
@@ -13174,7 +13309,7 @@ function hasProperty(value, name) {
|
|
|
13174
13309
|
return Object.getOwnPropertyDescriptor(value, name) !== void 0;
|
|
13175
13310
|
}
|
|
13176
13311
|
function modelFromRequestText(requestText) {
|
|
13177
|
-
return readStringProperty(parseJson(requestText), "model");
|
|
13312
|
+
return readStringProperty$1(parseJson(requestText), "model");
|
|
13178
13313
|
}
|
|
13179
13314
|
function inferApiFormatFromBody(path2, model, requestText) {
|
|
13180
13315
|
const pathFormat = apiFormatForPath(path2);
|
|
@@ -14360,7 +14495,15 @@ function buildProviderTestUserPrompt(mode) {
|
|
|
14360
14495
|
function buildProviderTestMessages(mode) {
|
|
14361
14496
|
return [{ role: "user", content: buildProviderTestUserPrompt(mode) }];
|
|
14362
14497
|
}
|
|
14363
|
-
function buildProviderTestRequestBody(model, mode) {
|
|
14498
|
+
function buildProviderTestRequestBody(model, mode, apiShape = "chat") {
|
|
14499
|
+
if (apiShape === "responses") {
|
|
14500
|
+
return {
|
|
14501
|
+
model,
|
|
14502
|
+
input: buildProviderTestUserPrompt(mode),
|
|
14503
|
+
max_output_tokens: maxTokensForMode(mode),
|
|
14504
|
+
stream: mode === "streaming"
|
|
14505
|
+
};
|
|
14506
|
+
}
|
|
14364
14507
|
const base = {
|
|
14365
14508
|
model,
|
|
14366
14509
|
messages: buildProviderTestMessages(mode),
|
|
@@ -14607,6 +14750,50 @@ const OpenAIResponseSchema = object({
|
|
|
14607
14750
|
})
|
|
14608
14751
|
)
|
|
14609
14752
|
});
|
|
14753
|
+
function isOpenAIProtocol(protocol) {
|
|
14754
|
+
return protocol === "openaiChat" || protocol === "openaiResponses";
|
|
14755
|
+
}
|
|
14756
|
+
function providerTestApiShape(protocol) {
|
|
14757
|
+
switch (protocol) {
|
|
14758
|
+
case "anthropic":
|
|
14759
|
+
case "openaiChat":
|
|
14760
|
+
return "chat";
|
|
14761
|
+
case "openaiResponses":
|
|
14762
|
+
return "responses";
|
|
14763
|
+
}
|
|
14764
|
+
}
|
|
14765
|
+
function buildProviderTestBodyText(model, mode, protocol) {
|
|
14766
|
+
return JSON.stringify(buildProviderTestRequestBody(model, mode, providerTestApiShape(protocol)));
|
|
14767
|
+
}
|
|
14768
|
+
function readProperty(value, key) {
|
|
14769
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
14770
|
+
return Object.getOwnPropertyDescriptor(value, key)?.value;
|
|
14771
|
+
}
|
|
14772
|
+
function readStringProperty(value, key) {
|
|
14773
|
+
const property = readProperty(value, key);
|
|
14774
|
+
return typeof property === "string" ? property : null;
|
|
14775
|
+
}
|
|
14776
|
+
function readArrayProperty(value, key) {
|
|
14777
|
+
const property = readProperty(value, key);
|
|
14778
|
+
return Array.isArray(property) ? property : [];
|
|
14779
|
+
}
|
|
14780
|
+
function responseTextFromOpenAIResponses(response) {
|
|
14781
|
+
if (response.output_text !== void 0 && response.output_text.length > 0) {
|
|
14782
|
+
return response.output_text;
|
|
14783
|
+
}
|
|
14784
|
+
const parts = [];
|
|
14785
|
+
for (const outputItem of response.output ?? []) {
|
|
14786
|
+
const content = readArrayProperty(outputItem, "content");
|
|
14787
|
+
for (const contentPart of content) {
|
|
14788
|
+
const type = readStringProperty(contentPart, "type");
|
|
14789
|
+
const text = readStringProperty(contentPart, "text");
|
|
14790
|
+
if ((type === "output_text" || type === "text") && text !== null && text.length > 0) {
|
|
14791
|
+
parts.push(text);
|
|
14792
|
+
}
|
|
14793
|
+
}
|
|
14794
|
+
}
|
|
14795
|
+
return parts.length > 0 ? parts.join("\n") : null;
|
|
14796
|
+
}
|
|
14610
14797
|
function getProviderTestTimeoutMs() {
|
|
14611
14798
|
return getConfig().providerTestTimeoutSeconds * 1e3;
|
|
14612
14799
|
}
|
|
@@ -14620,9 +14807,9 @@ function buildTestRequestHeaders(provider) {
|
|
|
14620
14807
|
});
|
|
14621
14808
|
return result;
|
|
14622
14809
|
}
|
|
14623
|
-
async function testEndpoint(baseUrl, provider, path2, model,
|
|
14810
|
+
async function testEndpoint(baseUrl, provider, path2, model, protocol) {
|
|
14624
14811
|
const startTime = Date.now();
|
|
14625
|
-
const body =
|
|
14812
|
+
const body = buildProviderTestBodyText(model, "non-streaming", protocol);
|
|
14626
14813
|
const requestHeaders = buildTestRequestHeaders(provider);
|
|
14627
14814
|
let requestUrl = baseUrl;
|
|
14628
14815
|
const controller = new AbortController();
|
|
@@ -14655,7 +14842,7 @@ async function testEndpoint(baseUrl, provider, path2, model, isOpenAI) {
|
|
|
14655
14842
|
const responseText = await response.text();
|
|
14656
14843
|
const safeRequestHeaders = redactHeaders(requestHeaders);
|
|
14657
14844
|
try {
|
|
14658
|
-
if (
|
|
14845
|
+
if (protocol === "openaiChat") {
|
|
14659
14846
|
const json = OpenAIResponseSchema.parse(JSON.parse(responseText));
|
|
14660
14847
|
const responseModel = json.model ?? model;
|
|
14661
14848
|
const inputTokens = json.usage?.prompt_tokens;
|
|
@@ -14671,7 +14858,25 @@ async function testEndpoint(baseUrl, provider, path2, model, isOpenAI) {
|
|
|
14671
14858
|
rawResponse: responseText,
|
|
14672
14859
|
requestHeaders: safeRequestHeaders
|
|
14673
14860
|
};
|
|
14674
|
-
}
|
|
14861
|
+
}
|
|
14862
|
+
if (protocol === "openaiResponses") {
|
|
14863
|
+
const json = OpenAIResponsesResponseSchema.parse(JSON.parse(responseText));
|
|
14864
|
+
const responseModel = json.model ?? model;
|
|
14865
|
+
const inputTokens = json.usage?.input_tokens ?? void 0;
|
|
14866
|
+
const outputTokens = json.usage?.output_tokens ?? void 0;
|
|
14867
|
+
const content = responseTextFromOpenAIResponses(json);
|
|
14868
|
+
return {
|
|
14869
|
+
success: true,
|
|
14870
|
+
model: responseModel,
|
|
14871
|
+
inputTokens,
|
|
14872
|
+
outputTokens,
|
|
14873
|
+
latencyMs,
|
|
14874
|
+
content: content !== null && content !== "" ? [{ type: "text", text: content }] : void 0,
|
|
14875
|
+
rawResponse: responseText,
|
|
14876
|
+
requestHeaders: safeRequestHeaders
|
|
14877
|
+
};
|
|
14878
|
+
}
|
|
14879
|
+
{
|
|
14675
14880
|
const json = AnthropicResponseSchema.parse(JSON.parse(responseText));
|
|
14676
14881
|
const responseModel = json.model ?? model;
|
|
14677
14882
|
const inputTokens = json.usage?.input_tokens;
|
|
@@ -14726,9 +14931,9 @@ async function testEndpoint(baseUrl, provider, path2, model, isOpenAI) {
|
|
|
14726
14931
|
clearTimeout(timeoutId);
|
|
14727
14932
|
}
|
|
14728
14933
|
}
|
|
14729
|
-
async function testStreamingEndpoint(baseUrl, provider, path2, model,
|
|
14934
|
+
async function testStreamingEndpoint(baseUrl, provider, path2, model, protocol) {
|
|
14730
14935
|
const startTime = Date.now();
|
|
14731
|
-
const body =
|
|
14936
|
+
const body = buildProviderTestBodyText(model, "streaming", protocol);
|
|
14732
14937
|
const requestHeaders = buildTestRequestHeaders(provider);
|
|
14733
14938
|
let requestUrl = baseUrl;
|
|
14734
14939
|
const controller = new AbortController();
|
|
@@ -14842,11 +15047,11 @@ async function testStreamingEndpoint(baseUrl, provider, path2, model, isOpenAI)
|
|
|
14842
15047
|
streaming: true,
|
|
14843
15048
|
userAgent: null,
|
|
14844
15049
|
origin: null,
|
|
14845
|
-
apiFormat: "anthropic",
|
|
15050
|
+
apiFormat: isOpenAIProtocol(protocol) ? "openai" : "anthropic",
|
|
14846
15051
|
isTest: true
|
|
14847
15052
|
};
|
|
14848
15053
|
let reconstructedJson;
|
|
14849
|
-
if (
|
|
15054
|
+
if (isOpenAIProtocol(protocol)) {
|
|
14850
15055
|
reconstructedJson = extractOpenAIStream(fullResponse, mockLog, model, true);
|
|
14851
15056
|
} else {
|
|
14852
15057
|
reconstructedJson = extractAnthropicStream(fullResponse, mockLog, model, true);
|
|
@@ -14859,7 +15064,7 @@ async function testStreamingEndpoint(baseUrl, provider, path2, model, isOpenAI)
|
|
|
14859
15064
|
let cacheCreationInputTokens;
|
|
14860
15065
|
let cacheReadInputTokens;
|
|
14861
15066
|
let responseModel;
|
|
14862
|
-
if (
|
|
15067
|
+
if (protocol === "openaiChat") {
|
|
14863
15068
|
const parsed = OpenAIResponseSchema.parse(JSON.parse(reconstructedJson));
|
|
14864
15069
|
responseModel = typeof parsed.model === "string" && parsed.model !== "" ? parsed.model : void 0;
|
|
14865
15070
|
inputTokens = parsed.usage?.prompt_tokens;
|
|
@@ -14868,6 +15073,15 @@ async function testStreamingEndpoint(baseUrl, provider, path2, model, isOpenAI)
|
|
|
14868
15073
|
if (textContent !== null && textContent !== "") {
|
|
14869
15074
|
content = [{ type: "text", text: textContent }];
|
|
14870
15075
|
}
|
|
15076
|
+
} else if (protocol === "openaiResponses") {
|
|
15077
|
+
const parsed = OpenAIResponsesResponseSchema.parse(JSON.parse(reconstructedJson));
|
|
15078
|
+
responseModel = typeof parsed.model === "string" && parsed.model !== "" ? parsed.model : void 0;
|
|
15079
|
+
inputTokens = parsed.usage?.input_tokens ?? void 0;
|
|
15080
|
+
outputTokens = parsed.usage?.output_tokens ?? void 0;
|
|
15081
|
+
const textContent = responseTextFromOpenAIResponses(parsed);
|
|
15082
|
+
if (textContent !== null && textContent !== "") {
|
|
15083
|
+
content = [{ type: "text", text: textContent }];
|
|
15084
|
+
}
|
|
14871
15085
|
} else {
|
|
14872
15086
|
const parsed = AnthropicResponseSchema.parse(JSON.parse(reconstructedJson));
|
|
14873
15087
|
responseModel = typeof parsed.model === "string" && parsed.model !== "" ? parsed.model : void 0;
|
|
@@ -14952,24 +15166,39 @@ const Route$a = createFileRoute("/api/providers/$providerId/test")({
|
|
|
14952
15166
|
const results = {
|
|
14953
15167
|
anthropic: { nonStreaming: { notConfigured: true }, streaming: { notConfigured: true } },
|
|
14954
15168
|
openai: { nonStreaming: { notConfigured: true }, streaming: { notConfigured: true } },
|
|
15169
|
+
openaiChat: {
|
|
15170
|
+
nonStreaming: { notConfigured: true },
|
|
15171
|
+
streaming: { notConfigured: true }
|
|
15172
|
+
},
|
|
15173
|
+
openaiResponses: {
|
|
15174
|
+
nonStreaming: { notConfigured: true },
|
|
15175
|
+
streaming: { notConfigured: true }
|
|
15176
|
+
},
|
|
14955
15177
|
models: {}
|
|
14956
15178
|
};
|
|
14957
15179
|
const anthropicUrl = provider.anthropicBaseUrl !== void 0 && provider.anthropicBaseUrl.length > 0 ? provider.anthropicBaseUrl : void 0;
|
|
14958
15180
|
const openaiUrl = provider.openaiBaseUrl !== void 0 && provider.openaiBaseUrl.length > 0 ? provider.openaiBaseUrl : void 0;
|
|
15181
|
+
const openaiResponsesUrl = provider.openaiResponsesBaseUrl !== void 0 && provider.openaiResponsesBaseUrl.length > 0 ? provider.openaiResponsesBaseUrl : void 0;
|
|
14959
15182
|
async function testOneModel(displayName) {
|
|
14960
15183
|
const usageModel = getModelUsageName(displayName, p.name);
|
|
14961
15184
|
const notConfigured = { notConfigured: true };
|
|
15185
|
+
const notConfiguredFormat = {
|
|
15186
|
+
nonStreaming: notConfigured,
|
|
15187
|
+
streaming: notConfigured
|
|
15188
|
+
};
|
|
14962
15189
|
const modelResults = {
|
|
14963
15190
|
anthropic: { nonStreaming: notConfigured, streaming: notConfigured },
|
|
14964
|
-
openai:
|
|
15191
|
+
openai: notConfiguredFormat,
|
|
15192
|
+
openaiChat: { nonStreaming: notConfigured, streaming: notConfigured },
|
|
15193
|
+
openaiResponses: { nonStreaming: notConfigured, streaming: notConfigured }
|
|
14965
15194
|
};
|
|
14966
15195
|
const tasks = [];
|
|
14967
15196
|
if (anthropicUrl !== void 0) {
|
|
14968
15197
|
tasks.push(
|
|
14969
|
-
testEndpoint(anthropicUrl, p, "/v1/messages", usageModel,
|
|
15198
|
+
testEndpoint(anthropicUrl, p, "/v1/messages", usageModel, "anthropic").then((r) => {
|
|
14970
15199
|
modelResults.anthropic.nonStreaming = r;
|
|
14971
15200
|
}),
|
|
14972
|
-
testStreamingEndpoint(anthropicUrl, p, "/v1/messages", usageModel,
|
|
15201
|
+
testStreamingEndpoint(anthropicUrl, p, "/v1/messages", usageModel, "anthropic").then(
|
|
14973
15202
|
(r) => {
|
|
14974
15203
|
modelResults.anthropic.streaming = r;
|
|
14975
15204
|
}
|
|
@@ -14978,14 +15207,44 @@ const Route$a = createFileRoute("/api/providers/$providerId/test")({
|
|
|
14978
15207
|
}
|
|
14979
15208
|
if (openaiUrl !== void 0) {
|
|
14980
15209
|
tasks.push(
|
|
14981
|
-
testEndpoint(openaiUrl, p, "/v1/chat/completions", usageModel,
|
|
14982
|
-
modelResults.openai.nonStreaming = r;
|
|
14983
|
-
}),
|
|
14984
|
-
testStreamingEndpoint(openaiUrl, p, "/v1/chat/completions", usageModel, true).then(
|
|
15210
|
+
testEndpoint(openaiUrl, p, "/v1/chat/completions", usageModel, "openaiChat").then(
|
|
14985
15211
|
(r) => {
|
|
14986
|
-
modelResults.openai.
|
|
15212
|
+
modelResults.openai.nonStreaming = r;
|
|
15213
|
+
modelResults.openaiChat.nonStreaming = r;
|
|
14987
15214
|
}
|
|
14988
|
-
)
|
|
15215
|
+
),
|
|
15216
|
+
testStreamingEndpoint(
|
|
15217
|
+
openaiUrl,
|
|
15218
|
+
p,
|
|
15219
|
+
"/v1/chat/completions",
|
|
15220
|
+
usageModel,
|
|
15221
|
+
"openaiChat"
|
|
15222
|
+
).then((r) => {
|
|
15223
|
+
modelResults.openai.streaming = r;
|
|
15224
|
+
modelResults.openaiChat.streaming = r;
|
|
15225
|
+
})
|
|
15226
|
+
);
|
|
15227
|
+
}
|
|
15228
|
+
if (openaiResponsesUrl !== void 0) {
|
|
15229
|
+
tasks.push(
|
|
15230
|
+
testEndpoint(
|
|
15231
|
+
openaiResponsesUrl,
|
|
15232
|
+
p,
|
|
15233
|
+
"/v1/responses",
|
|
15234
|
+
usageModel,
|
|
15235
|
+
"openaiResponses"
|
|
15236
|
+
).then((r) => {
|
|
15237
|
+
modelResults.openaiResponses.nonStreaming = r;
|
|
15238
|
+
}),
|
|
15239
|
+
testStreamingEndpoint(
|
|
15240
|
+
openaiResponsesUrl,
|
|
15241
|
+
p,
|
|
15242
|
+
"/v1/responses",
|
|
15243
|
+
usageModel,
|
|
15244
|
+
"openaiResponses"
|
|
15245
|
+
).then((r) => {
|
|
15246
|
+
modelResults.openaiResponses.streaming = r;
|
|
15247
|
+
})
|
|
14989
15248
|
);
|
|
14990
15249
|
}
|
|
14991
15250
|
await Promise.all(tasks);
|
|
@@ -14997,6 +15256,8 @@ const Route$a = createFileRoute("/api/providers/$providerId/test")({
|
|
|
14997
15256
|
if (firstResults !== void 0) {
|
|
14998
15257
|
results.anthropic = firstResults.anthropic;
|
|
14999
15258
|
results.openai = firstResults.openai;
|
|
15259
|
+
results.openaiChat = firstResults.openaiChat;
|
|
15260
|
+
results.openaiResponses = firstResults.openaiResponses;
|
|
15000
15261
|
}
|
|
15001
15262
|
results.testedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
15002
15263
|
return Response.json(results);
|
|
@@ -15637,15 +15898,41 @@ const ProviderFormatTestResultsSchema = object({
|
|
|
15637
15898
|
nonStreaming: ProviderTestStateSchema,
|
|
15638
15899
|
streaming: ProviderTestStateSchema
|
|
15639
15900
|
});
|
|
15901
|
+
function createNotConfiguredProviderFormatTestResults() {
|
|
15902
|
+
return {
|
|
15903
|
+
nonStreaming: { notConfigured: true },
|
|
15904
|
+
streaming: { notConfigured: true }
|
|
15905
|
+
};
|
|
15906
|
+
}
|
|
15640
15907
|
const ModelTestResultsSchema = object({
|
|
15641
15908
|
anthropic: ProviderFormatTestResultsSchema,
|
|
15642
|
-
openai: ProviderFormatTestResultsSchema
|
|
15909
|
+
openai: ProviderFormatTestResultsSchema.optional(),
|
|
15910
|
+
openaiChat: ProviderFormatTestResultsSchema.optional(),
|
|
15911
|
+
openaiResponses: ProviderFormatTestResultsSchema.optional()
|
|
15912
|
+
}).transform((value) => {
|
|
15913
|
+
const openaiChat = value.openaiChat ?? value.openai ?? createNotConfiguredProviderFormatTestResults();
|
|
15914
|
+
return {
|
|
15915
|
+
...value,
|
|
15916
|
+
openai: value.openai ?? openaiChat,
|
|
15917
|
+
openaiChat,
|
|
15918
|
+
openaiResponses: value.openaiResponses ?? createNotConfiguredProviderFormatTestResults()
|
|
15919
|
+
};
|
|
15643
15920
|
});
|
|
15644
15921
|
const ProviderTestResultsSchema = object({
|
|
15645
15922
|
anthropic: ProviderFormatTestResultsSchema,
|
|
15646
|
-
openai: ProviderFormatTestResultsSchema,
|
|
15923
|
+
openai: ProviderFormatTestResultsSchema.optional(),
|
|
15924
|
+
openaiChat: ProviderFormatTestResultsSchema.optional(),
|
|
15925
|
+
openaiResponses: ProviderFormatTestResultsSchema.optional(),
|
|
15647
15926
|
models: record(string(), ModelTestResultsSchema).optional(),
|
|
15648
15927
|
testedAt: string().optional()
|
|
15928
|
+
}).transform((value) => {
|
|
15929
|
+
const openaiChat = value.openaiChat ?? value.openai ?? createNotConfiguredProviderFormatTestResults();
|
|
15930
|
+
return {
|
|
15931
|
+
...value,
|
|
15932
|
+
openai: value.openai ?? openaiChat,
|
|
15933
|
+
openaiChat,
|
|
15934
|
+
openaiResponses: value.openaiResponses ?? createNotConfiguredProviderFormatTestResults()
|
|
15935
|
+
};
|
|
15649
15936
|
});
|
|
15650
15937
|
function createPendingProviderTestResults() {
|
|
15651
15938
|
return {
|
|
@@ -15656,6 +15943,14 @@ function createPendingProviderTestResults() {
|
|
|
15656
15943
|
openai: {
|
|
15657
15944
|
nonStreaming: { testing: true },
|
|
15658
15945
|
streaming: { testing: true }
|
|
15946
|
+
},
|
|
15947
|
+
openaiChat: {
|
|
15948
|
+
nonStreaming: { testing: true },
|
|
15949
|
+
streaming: { testing: true }
|
|
15950
|
+
},
|
|
15951
|
+
openaiResponses: {
|
|
15952
|
+
nonStreaming: { testing: true },
|
|
15953
|
+
streaming: { testing: true }
|
|
15659
15954
|
}
|
|
15660
15955
|
};
|
|
15661
15956
|
}
|
|
@@ -15669,7 +15964,9 @@ function createFailedProviderTestResults(message, type) {
|
|
|
15669
15964
|
});
|
|
15670
15965
|
return {
|
|
15671
15966
|
anthropic: createFormatResult(),
|
|
15672
|
-
openai: createFormatResult()
|
|
15967
|
+
openai: createFormatResult(),
|
|
15968
|
+
openaiChat: createFormatResult(),
|
|
15969
|
+
openaiResponses: createFormatResult()
|
|
15673
15970
|
};
|
|
15674
15971
|
}
|
|
15675
15972
|
function hasSuccessField(result) {
|
|
@@ -15700,7 +15997,7 @@ function getResultTokensPerSecond(result) {
|
|
|
15700
15997
|
totalStreamMs: getResultTotalStreamMs(result)
|
|
15701
15998
|
});
|
|
15702
15999
|
}
|
|
15703
|
-
async function logModelResults(displayName, providerName, anthropicUrl,
|
|
16000
|
+
async function logModelResults(displayName, providerName, providerSessionId, anthropicUrl, openaiChatUrl, openaiResponsesUrl, modelResults, captureFullDetails) {
|
|
15704
16001
|
const usageModel = getModelUsageName(displayName, providerName);
|
|
15705
16002
|
if (anthropicUrl !== void 0) {
|
|
15706
16003
|
const nsResult = modelResults.anthropic.nonStreaming;
|
|
@@ -15714,7 +16011,7 @@ async function logModelResults(displayName, providerName, anthropicUrl, openaiUr
|
|
|
15714
16011
|
method: "POST",
|
|
15715
16012
|
path: "/v1/messages",
|
|
15716
16013
|
model: nonStreamingResult.model ?? displayName,
|
|
15717
|
-
sessionId:
|
|
16014
|
+
sessionId: providerSessionId,
|
|
15718
16015
|
rawRequestBody: requestBody,
|
|
15719
16016
|
responseStatus: getResultResponseStatus(nonStreamingResult),
|
|
15720
16017
|
responseText: getResultResponseText(nonStreamingResult),
|
|
@@ -15742,7 +16039,7 @@ async function logModelResults(displayName, providerName, anthropicUrl, openaiUr
|
|
|
15742
16039
|
method: "POST",
|
|
15743
16040
|
path: "/v1/messages",
|
|
15744
16041
|
model: streamingResult.model ?? displayName,
|
|
15745
|
-
sessionId:
|
|
16042
|
+
sessionId: providerSessionId,
|
|
15746
16043
|
rawRequestBody: streamingRequestBody,
|
|
15747
16044
|
responseStatus: getResultResponseStatus(streamingResult),
|
|
15748
16045
|
responseText: getResultResponseText(streamingResult),
|
|
@@ -15765,9 +16062,9 @@ async function logModelResults(displayName, providerName, anthropicUrl, openaiUr
|
|
|
15765
16062
|
});
|
|
15766
16063
|
}
|
|
15767
16064
|
}
|
|
15768
|
-
if (
|
|
15769
|
-
const nsResult = modelResults.
|
|
15770
|
-
const sResult = modelResults.
|
|
16065
|
+
if (openaiChatUrl !== void 0) {
|
|
16066
|
+
const nsResult = modelResults.openaiChat.nonStreaming;
|
|
16067
|
+
const sResult = modelResults.openaiChat.streaming;
|
|
15771
16068
|
if (hasSuccessField(nsResult) && hasSuccessField(sResult)) {
|
|
15772
16069
|
const nonStreamingResult = nsResult;
|
|
15773
16070
|
const streamingResult = sResult;
|
|
@@ -15777,7 +16074,7 @@ async function logModelResults(displayName, providerName, anthropicUrl, openaiUr
|
|
|
15777
16074
|
method: "POST",
|
|
15778
16075
|
path: "/v1/chat/completions",
|
|
15779
16076
|
model: nonStreamingResult.model ?? displayName,
|
|
15780
|
-
sessionId:
|
|
16077
|
+
sessionId: providerSessionId,
|
|
15781
16078
|
rawRequestBody: requestBody,
|
|
15782
16079
|
responseStatus: getResultResponseStatus(nonStreamingResult),
|
|
15783
16080
|
responseText: getResultResponseText(nonStreamingResult),
|
|
@@ -15805,7 +16102,7 @@ async function logModelResults(displayName, providerName, anthropicUrl, openaiUr
|
|
|
15805
16102
|
method: "POST",
|
|
15806
16103
|
path: "/v1/chat/completions",
|
|
15807
16104
|
model: streamingResult.model ?? displayName,
|
|
15808
|
-
sessionId:
|
|
16105
|
+
sessionId: providerSessionId,
|
|
15809
16106
|
rawRequestBody: streamingRequestBody,
|
|
15810
16107
|
responseStatus: getResultResponseStatus(streamingResult),
|
|
15811
16108
|
responseText: getResultResponseText(streamingResult),
|
|
@@ -15828,6 +16125,71 @@ async function logModelResults(displayName, providerName, anthropicUrl, openaiUr
|
|
|
15828
16125
|
});
|
|
15829
16126
|
}
|
|
15830
16127
|
}
|
|
16128
|
+
if (openaiResponsesUrl !== void 0) {
|
|
16129
|
+
const nsResult = modelResults.openaiResponses.nonStreaming;
|
|
16130
|
+
const sResult = modelResults.openaiResponses.streaming;
|
|
16131
|
+
if (hasSuccessField(nsResult) && hasSuccessField(sResult)) {
|
|
16132
|
+
const nonStreamingResult = nsResult;
|
|
16133
|
+
const streamingResult = sResult;
|
|
16134
|
+
const requestBody = JSON.stringify(
|
|
16135
|
+
buildProviderTestRequestBody(usageModel, "non-streaming", "responses")
|
|
16136
|
+
);
|
|
16137
|
+
await addTestLogEntry({
|
|
16138
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
16139
|
+
method: "POST",
|
|
16140
|
+
path: "/v1/responses",
|
|
16141
|
+
model: nonStreamingResult.model ?? displayName,
|
|
16142
|
+
sessionId: providerSessionId,
|
|
16143
|
+
rawRequestBody: requestBody,
|
|
16144
|
+
responseStatus: getResultResponseStatus(nonStreamingResult),
|
|
16145
|
+
responseText: getResultResponseText(nonStreamingResult),
|
|
16146
|
+
inputTokens: nonStreamingResult.inputTokens ?? null,
|
|
16147
|
+
outputTokens: nonStreamingResult.outputTokens ?? null,
|
|
16148
|
+
cacheCreationInputTokens: null,
|
|
16149
|
+
cacheReadInputTokens: nonStreamingResult.cacheReadInputTokens ?? null,
|
|
16150
|
+
elapsedMs: nonStreamingResult.latencyMs ?? 0,
|
|
16151
|
+
firstChunkMs: null,
|
|
16152
|
+
totalStreamMs: null,
|
|
16153
|
+
tokensPerSecond: null,
|
|
16154
|
+
streaming: false,
|
|
16155
|
+
userAgent: "provider-test",
|
|
16156
|
+
origin: null,
|
|
16157
|
+
apiFormat: "openai",
|
|
16158
|
+
isTest: true,
|
|
16159
|
+
providerName,
|
|
16160
|
+
headers: captureFullDetails ? getResultHeaders(nonStreamingResult) : void 0
|
|
16161
|
+
});
|
|
16162
|
+
const streamingRequestBody = JSON.stringify(
|
|
16163
|
+
buildProviderTestRequestBody(usageModel, "streaming", "responses")
|
|
16164
|
+
);
|
|
16165
|
+
await addTestLogEntry({
|
|
16166
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
16167
|
+
method: "POST",
|
|
16168
|
+
path: "/v1/responses",
|
|
16169
|
+
model: streamingResult.model ?? displayName,
|
|
16170
|
+
sessionId: providerSessionId,
|
|
16171
|
+
rawRequestBody: streamingRequestBody,
|
|
16172
|
+
responseStatus: getResultResponseStatus(streamingResult),
|
|
16173
|
+
responseText: getResultResponseText(streamingResult),
|
|
16174
|
+
inputTokens: streamingResult.inputTokens ?? null,
|
|
16175
|
+
outputTokens: streamingResult.outputTokens ?? null,
|
|
16176
|
+
cacheCreationInputTokens: null,
|
|
16177
|
+
cacheReadInputTokens: streamingResult.cacheReadInputTokens ?? null,
|
|
16178
|
+
elapsedMs: getResultTotalStreamMs(streamingResult) ?? 0,
|
|
16179
|
+
firstChunkMs: getResultFirstChunkMs(streamingResult),
|
|
16180
|
+
totalStreamMs: getResultTotalStreamMs(streamingResult),
|
|
16181
|
+
tokensPerSecond: getResultTokensPerSecond(streamingResult),
|
|
16182
|
+
streaming: true,
|
|
16183
|
+
streamingChunks: captureFullDetails ? streamingResult.streamingChunks : void 0,
|
|
16184
|
+
userAgent: "provider-test",
|
|
16185
|
+
origin: null,
|
|
16186
|
+
apiFormat: "openai",
|
|
16187
|
+
isTest: true,
|
|
16188
|
+
providerName,
|
|
16189
|
+
headers: captureFullDetails ? getResultHeaders(streamingResult) : void 0
|
|
16190
|
+
});
|
|
16191
|
+
}
|
|
16192
|
+
}
|
|
15831
16193
|
}
|
|
15832
16194
|
const Route$2 = createFileRoute("/api/providers/$providerId/test/log")({
|
|
15833
16195
|
server: {
|
|
@@ -15851,9 +16213,11 @@ const Route$2 = createFileRoute("/api/providers/$providerId/test/log")({
|
|
|
15851
16213
|
);
|
|
15852
16214
|
}
|
|
15853
16215
|
const results = parsed.data;
|
|
16216
|
+
const providerSessionId = buildProviderTestSessionId(params.providerId);
|
|
15854
16217
|
const captureFullDetails = getConfig().captureMode === "full";
|
|
15855
16218
|
const anthropicUrl = provider.anthropicBaseUrl !== void 0 && provider.anthropicBaseUrl.length > 0 ? provider.anthropicBaseUrl : void 0;
|
|
15856
|
-
const
|
|
16219
|
+
const openaiChatUrl = provider.openaiBaseUrl !== void 0 && provider.openaiBaseUrl.length > 0 ? provider.openaiBaseUrl : void 0;
|
|
16220
|
+
const openaiResponsesUrl = provider.openaiResponsesBaseUrl !== void 0 && provider.openaiResponsesBaseUrl.length > 0 ? provider.openaiResponsesBaseUrl : void 0;
|
|
15857
16221
|
const entries = [];
|
|
15858
16222
|
if (results.models !== void 0) {
|
|
15859
16223
|
for (const [modelName, modelResult] of Object.entries(results.models)) {
|
|
@@ -15861,8 +16225,10 @@ const Route$2 = createFileRoute("/api/providers/$providerId/test/log")({
|
|
|
15861
16225
|
logModelResults(
|
|
15862
16226
|
modelName,
|
|
15863
16227
|
provider.name,
|
|
16228
|
+
providerSessionId,
|
|
15864
16229
|
anthropicUrl,
|
|
15865
|
-
|
|
16230
|
+
openaiChatUrl,
|
|
16231
|
+
openaiResponsesUrl,
|
|
15866
16232
|
modelResult,
|
|
15867
16233
|
captureFullDetails
|
|
15868
16234
|
)
|
|
@@ -16320,12 +16686,15 @@ const router = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
|
|
|
16320
16686
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
16321
16687
|
export {
|
|
16322
16688
|
AnthropicResponseSchema$1 as A,
|
|
16323
|
-
|
|
16689
|
+
createFailedProviderTestResults as B,
|
|
16324
16690
|
CapturedLogSchema as C,
|
|
16325
16691
|
DEFAULT_CAPTURE_MODE as D,
|
|
16326
|
-
|
|
16692
|
+
MAX_PROVIDER_TEST_TIMEOUT_SECONDS as E,
|
|
16693
|
+
resolveProviderContextWindow as F,
|
|
16327
16694
|
GroupEvidenceReadResponseSchema as G,
|
|
16695
|
+
isPlainRecord as H,
|
|
16328
16696
|
InspectorGroupsListResponseSchema as I,
|
|
16697
|
+
router as J,
|
|
16329
16698
|
KnowledgeCandidateSchema as K,
|
|
16330
16699
|
LogBodyChunkSchema as L,
|
|
16331
16700
|
MAX_SLOW_RESPONSE_THRESHOLD_SECONDS as M,
|
|
@@ -16353,10 +16722,10 @@ export {
|
|
|
16353
16722
|
findProviderModelMetadata as r,
|
|
16354
16723
|
safeGetOwnProperty as s,
|
|
16355
16724
|
maskApiKey as t,
|
|
16356
|
-
|
|
16357
|
-
|
|
16358
|
-
|
|
16359
|
-
|
|
16360
|
-
|
|
16361
|
-
|
|
16725
|
+
PATH_V1_MESSAGES as u,
|
|
16726
|
+
PATH_V1_CHAT_COMPLETIONS as v,
|
|
16727
|
+
PATH_V1_RESPONSES as w,
|
|
16728
|
+
previewUpstreamUrl as x,
|
|
16729
|
+
createPendingProviderTestResults as y,
|
|
16730
|
+
ProviderTestResultsSchema as z
|
|
16362
16731
|
};
|