@tonyclaw/agent-inspector 2.1.16 → 2.1.18
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-Ccrrcx1j.js → CompareDrawer-Fqqw5Lci.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-CP_RzwW9.js +106 -0
- package/.output/public/assets/{ReplayDialog-C7axhr-l.js → ReplayDialog-hYhz_i6W.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-WOptg8j_.js → RequestAnatomy-CTuWbtwC.js} +1 -1
- package/.output/public/assets/{ResponseView-CSAcxh_M.js → ResponseView-CsZ7S5Gv.js} +2 -2
- package/.output/public/assets/{StreamingChunkSequence-DJS5KhPx.js → StreamingChunkSequence-PIbJMotU.js} +1 -1
- package/.output/public/assets/_sessionId-CUGA9qU3.js +1 -0
- package/.output/public/assets/{index-DMPNh46t.js → index-F7mynwuH.js} +1 -1
- package/.output/public/assets/index-G4dTUobw.js +1 -0
- package/.output/public/assets/index-gvYkgMPF.css +1 -0
- package/.output/public/assets/{json-viewer-inX5QSa3.js → json-viewer-DCXtNmmD.js} +1 -1
- package/.output/public/assets/{main-aCAKYGSD.js → main-BJZf7_Ib.js} +2 -2
- package/.output/server/_libs/lucide-react.mjs +220 -202
- package/.output/server/{_sessionId-C0fhvQnn.mjs → _sessionId-DjSHDNh8.mjs} +2 -2
- package/.output/server/_ssr/{CompareDrawer-CO-Ti5sg.mjs → CompareDrawer-Dal52IFo.mjs} +3 -3
- package/.output/server/_ssr/{ProxyViewerContainer-N4J7uBCX.mjs → ProxyViewerContainer-CVqFZGff.mjs} +1833 -1366
- package/.output/server/_ssr/{ReplayDialog-J1VxC0In.mjs → ReplayDialog-BOEgdMes.mjs} +4 -4
- package/.output/server/_ssr/{RequestAnatomy-DBH-F3rq.mjs → RequestAnatomy-gch7_vCV.mjs} +2 -2
- package/.output/server/_ssr/{ResponseView-DLFwV7Hd.mjs → ResponseView-lEWPy-H4.mjs} +3 -3
- package/.output/server/_ssr/{StreamingChunkSequence-BywmuND0.mjs → StreamingChunkSequence-DnudbJ1O.mjs} +2 -2
- package/.output/server/_ssr/{index-CStymIc0.mjs → index-Cza8zDrW.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-DlQu0N1x.mjs → json-viewer-C2lIVEX3.mjs} +3 -3
- package/.output/server/_ssr/{router-CQ4Zxhmr.mjs → router-bF9uzd1k.mjs} +939 -113
- package/.output/server/{_tanstack-start-manifest_v-BHeJBGfo.mjs → _tanstack-start-manifest_v-ErvW-mtr.mjs} +1 -1
- package/.output/server/index.mjs +74 -74
- 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 +395 -64
- package/src/components/providers/ProviderCard.tsx +132 -31
- package/src/components/providers/ProviderForm.tsx +43 -11
- package/src/components/providers/ProvidersPanel.tsx +1 -1
- package/src/components/proxy-viewer/ConversationHeader.tsx +133 -112
- package/src/components/proxy-viewer/LogEntry.tsx +109 -26
- package/src/components/proxy-viewer/LogEntryHeader.tsx +339 -329
- package/src/components/proxy-viewer/ThreadConnector.tsx +49 -46
- package/src/components/proxy-viewer/TurnGroup.tsx +22 -62
- package/src/components/proxy-viewer/bodyHydration.ts +56 -0
- package/src/lib/providerTestContract.ts +56 -10
- package/src/lib/providerTestPrompt.ts +23 -1
- package/src/lib/upstreamUrl.ts +105 -1
- package/src/mcp/server.ts +275 -0
- package/src/mcp/toolHandlers.ts +381 -4
- package/src/proxy/logSearch.ts +3 -0
- package/src/proxy/store.ts +40 -15
- package/src/routes/api/logs.ts +8 -2
- package/src/routes/api/providers.$providerId.test.log.ts +85 -10
- package/.output/public/assets/ProxyViewerContainer-DLqClc9A.js +0 -106
- package/.output/public/assets/_sessionId-DUSalzKH.js +0 -1
- package/.output/public/assets/index-BPpA21dY.css +0 -1
- package/.output/public/assets/index-Bt0Az2I2.js +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-gvYkgMPF.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-Cza8zDrW.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-DjSHDNh8.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) {
|
|
@@ -2019,9 +2019,9 @@ const DEFAULT_OPENAI_UPSTREAM$1 = "https://api.openai.com/v1";
|
|
|
2019
2019
|
const PROXY_IDENTITY = process.env["PROXY_IDENTITY"] ?? "inspector9527@Tony";
|
|
2020
2020
|
const PATH_V1_CHAT_COMPLETIONS$1 = "/v1/chat/completions";
|
|
2021
2021
|
const PATH_CHAT_COMPLETIONS = "/chat/completions";
|
|
2022
|
-
const PATH_V1_RESPONSES = "/v1/responses";
|
|
2022
|
+
const PATH_V1_RESPONSES$1 = "/v1/responses";
|
|
2023
2023
|
const PATH_RESPONSES = "/responses";
|
|
2024
|
-
const PATH_V1_MESSAGES = "/v1/messages";
|
|
2024
|
+
const PATH_V1_MESSAGES$1 = "/v1/messages";
|
|
2025
2025
|
const HEADER_CONTENT_TYPE = "content-type";
|
|
2026
2026
|
const HEADER_USER_AGENT = "user-agent";
|
|
2027
2027
|
const HEADER_X_PROXY_IDENTITY = "x-proxy-identity";
|
|
@@ -2075,10 +2075,10 @@ function formatForPath(path2) {
|
|
|
2075
2075
|
function apiFormatForPath(path2) {
|
|
2076
2076
|
return formatRegistry.getApiFormatByPath(path2) ?? "unknown";
|
|
2077
2077
|
}
|
|
2078
|
-
formatRegistry.registerPath(PATH_V1_MESSAGES, "anthropic");
|
|
2078
|
+
formatRegistry.registerPath(PATH_V1_MESSAGES$1, "anthropic");
|
|
2079
2079
|
formatRegistry.registerPath(PATH_V1_CHAT_COMPLETIONS$1, "openai");
|
|
2080
2080
|
formatRegistry.registerPath(PATH_CHAT_COMPLETIONS, "openai");
|
|
2081
|
-
formatRegistry.registerPath(PATH_V1_RESPONSES, "openai");
|
|
2081
|
+
formatRegistry.registerPath(PATH_V1_RESPONSES$1, "openai");
|
|
2082
2082
|
formatRegistry.registerPath(PATH_RESPONSES, "openai");
|
|
2083
2083
|
const SESSION_ARCHIVE_DIR = "sessions";
|
|
2084
2084
|
const SESSION_ARCHIVE_FILE = "session.sqlite";
|
|
@@ -2130,7 +2130,7 @@ function objectFromUnknown(value) {
|
|
|
2130
2130
|
if (typeof value === "object" || typeof value === "function") return value;
|
|
2131
2131
|
return null;
|
|
2132
2132
|
}
|
|
2133
|
-
function readProperty$
|
|
2133
|
+
function readProperty$3(value, name) {
|
|
2134
2134
|
let current = objectFromUnknown(value);
|
|
2135
2135
|
while (current !== null) {
|
|
2136
2136
|
const desc = Object.getOwnPropertyDescriptor(current, name);
|
|
@@ -2144,7 +2144,7 @@ function readProperty$2(value, name) {
|
|
|
2144
2144
|
return void 0;
|
|
2145
2145
|
}
|
|
2146
2146
|
function readFunction(value, name) {
|
|
2147
|
-
const property = readProperty$
|
|
2147
|
+
const property = readProperty$3(value, name);
|
|
2148
2148
|
return typeof property === "function" ? property : null;
|
|
2149
2149
|
}
|
|
2150
2150
|
function callMethod(target, methodName, args) {
|
|
@@ -2182,7 +2182,7 @@ function closeDatabase(db) {
|
|
|
2182
2182
|
callMethod(db, "close", []);
|
|
2183
2183
|
}
|
|
2184
2184
|
function sqliteConstructorFromModule(moduleValue, exportName) {
|
|
2185
|
-
const exportedValue = readProperty$
|
|
2185
|
+
const exportedValue = readProperty$3(moduleValue, exportName);
|
|
2186
2186
|
if (typeof exportedValue === "function") {
|
|
2187
2187
|
return (path2) => Reflect.construct(exportedValue, [path2]);
|
|
2188
2188
|
}
|
|
@@ -2273,11 +2273,11 @@ async function archiveSessionLog(log) {
|
|
|
2273
2273
|
}
|
|
2274
2274
|
}
|
|
2275
2275
|
function readString$1(row, name) {
|
|
2276
|
-
const value = readProperty$
|
|
2276
|
+
const value = readProperty$3(row, name);
|
|
2277
2277
|
return typeof value === "string" ? value : null;
|
|
2278
2278
|
}
|
|
2279
2279
|
function readNumber(row, name) {
|
|
2280
|
-
const value = readProperty$
|
|
2280
|
+
const value = readProperty$3(row, name);
|
|
2281
2281
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
2282
2282
|
}
|
|
2283
2283
|
function logFromJson(value) {
|
|
@@ -2734,12 +2734,14 @@ let sessionArchiveQueue = Promise.resolve();
|
|
|
2734
2734
|
function cursorPageIndexKey(options) {
|
|
2735
2735
|
return JSON.stringify({
|
|
2736
2736
|
sessionId: options.sessionId ?? null,
|
|
2737
|
-
model: options.model ?? null
|
|
2737
|
+
model: options.model ?? null,
|
|
2738
|
+
clientPid: options.clientPid ?? null
|
|
2738
2739
|
});
|
|
2739
2740
|
}
|
|
2740
2741
|
function matchesCursorIndexFilters(log, index) {
|
|
2741
2742
|
if (index.sessionId !== void 0 && getLogSessionId(log) !== index.sessionId) return false;
|
|
2742
2743
|
if (index.model !== void 0 && log.model !== index.model) return false;
|
|
2744
|
+
if (index.clientPid !== void 0 && log.clientPid !== index.clientPid) return false;
|
|
2743
2745
|
return true;
|
|
2744
2746
|
}
|
|
2745
2747
|
function insertSortedLogId(ids, id) {
|
|
@@ -3056,14 +3058,15 @@ async function scanLogFileForId(filePath, id) {
|
|
|
3056
3058
|
}
|
|
3057
3059
|
return lastMatch;
|
|
3058
3060
|
}
|
|
3059
|
-
function getFilteredLogs(sessionId, model) {
|
|
3061
|
+
function getFilteredLogs(sessionId, model, clientPid) {
|
|
3060
3062
|
return [...memoryCache.values()].filter((l) => {
|
|
3061
|
-
return matchesLogFilters(l, sessionId, model);
|
|
3063
|
+
return matchesLogFilters(l, sessionId, model, clientPid);
|
|
3062
3064
|
});
|
|
3063
3065
|
}
|
|
3064
|
-
function matchesLogFilters(log, sessionId, model) {
|
|
3066
|
+
function matchesLogFilters(log, sessionId, model, clientPid) {
|
|
3065
3067
|
if (sessionId !== void 0 && getLogSessionId(log) !== sessionId) return false;
|
|
3066
3068
|
if (model !== void 0 && log.model !== model) return false;
|
|
3069
|
+
if (clientPid !== void 0 && log.clientPid !== clientPid) return false;
|
|
3067
3070
|
return true;
|
|
3068
3071
|
}
|
|
3069
3072
|
async function visitPersistedLogs(visitor) {
|
|
@@ -3113,7 +3116,7 @@ async function visitArchivedSessionLogs(sessionId, visitor) {
|
|
|
3113
3116
|
}
|
|
3114
3117
|
}
|
|
3115
3118
|
function canUseIndexedListPage(options) {
|
|
3116
|
-
return options.sessionId === void 0 && options.model === void 0;
|
|
3119
|
+
return options.sessionId === void 0 && options.model === void 0 && options.clientPid === void 0;
|
|
3117
3120
|
}
|
|
3118
3121
|
function hasUsableIndexOffset(entry) {
|
|
3119
3122
|
return entry.byteOffset >= 0 && entry.byteLength > 0;
|
|
@@ -3158,7 +3161,7 @@ async function listLogsPage(options) {
|
|
|
3158
3161
|
const includeBodies = options.includeBodies !== false;
|
|
3159
3162
|
let total = 0;
|
|
3160
3163
|
const visitLog = (log) => {
|
|
3161
|
-
if (!matchesLogFilters(log, options.sessionId, options.model)) return;
|
|
3164
|
+
if (!matchesLogFilters(log, options.sessionId, options.model, options.clientPid)) return;
|
|
3162
3165
|
if (!seenIds.has(log.id)) {
|
|
3163
3166
|
seenIds.add(log.id);
|
|
3164
3167
|
const position = total;
|
|
@@ -3223,12 +3226,14 @@ function hasLogIndexFilterMetadata(entry) {
|
|
|
3223
3226
|
function hasLogIndexSummary(entry) {
|
|
3224
3227
|
return entry.summary !== void 0;
|
|
3225
3228
|
}
|
|
3226
|
-
function matchesLogIndexEntryFilters(entry, sessionId, model) {
|
|
3229
|
+
function matchesLogIndexEntryFilters(entry, sessionId, model, clientPid) {
|
|
3227
3230
|
if (sessionId !== void 0 && entry.sessionId !== sessionId) return false;
|
|
3228
3231
|
if (model !== void 0 && entry.model !== model) return false;
|
|
3232
|
+
if (clientPid !== void 0 && entry.summary?.clientPid !== clientPid) return false;
|
|
3229
3233
|
return true;
|
|
3230
3234
|
}
|
|
3231
3235
|
async function buildLogCursorPageIndexFromLogIndex(options, allowRebuild) {
|
|
3236
|
+
if (options.clientPid !== void 0) return null;
|
|
3232
3237
|
let entries = await listFilteredIndexEntries(options);
|
|
3233
3238
|
if (entries.length === 0 && allowRebuild) {
|
|
3234
3239
|
await rebuildIndex();
|
|
@@ -3240,7 +3245,7 @@ async function buildLogCursorPageIndexFromLogIndex(options, allowRebuild) {
|
|
|
3240
3245
|
return await buildLogCursorPageIndexFromLogIndex(options, false);
|
|
3241
3246
|
}
|
|
3242
3247
|
const matchingEntries = entries.filter(
|
|
3243
|
-
(entry) => matchesLogIndexEntryFilters(entry, options.sessionId, options.model)
|
|
3248
|
+
(entry) => matchesLogIndexEntryFilters(entry, options.sessionId, options.model, options.clientPid)
|
|
3244
3249
|
);
|
|
3245
3250
|
if (matchingEntries.some((entry) => !hasLogIndexSummary(entry))) {
|
|
3246
3251
|
if (!allowRebuild) return null;
|
|
@@ -3260,7 +3265,7 @@ async function buildLogCursorPageIndexFromLogIndex(options, allowRebuild) {
|
|
|
3260
3265
|
}
|
|
3261
3266
|
const logsById = /* @__PURE__ */ new Map();
|
|
3262
3267
|
for (const log of memoryCache.values()) {
|
|
3263
|
-
if (!matchesLogFilters(log, options.sessionId, options.model)) continue;
|
|
3268
|
+
if (!matchesLogFilters(log, options.sessionId, options.model, options.clientPid)) continue;
|
|
3264
3269
|
idsById.add(log.id);
|
|
3265
3270
|
logsById.set(log.id, log);
|
|
3266
3271
|
}
|
|
@@ -3269,7 +3274,7 @@ async function buildLogCursorPageIndexFromLogIndex(options, allowRebuild) {
|
|
|
3269
3274
|
const archivedLogs = await listArchivedSessionLogs(options.sessionId);
|
|
3270
3275
|
for (const archivedLog of archivedLogs) {
|
|
3271
3276
|
const log = normalizeLog(archivedLog);
|
|
3272
|
-
if (!matchesLogFilters(log, options.sessionId, options.model)) continue;
|
|
3277
|
+
if (!matchesLogFilters(log, options.sessionId, options.model, options.clientPid)) continue;
|
|
3273
3278
|
observeSessionLog(log);
|
|
3274
3279
|
idsById.add(log.id);
|
|
3275
3280
|
logsById.set(log.id, log);
|
|
@@ -3279,6 +3284,7 @@ async function buildLogCursorPageIndexFromLogIndex(options, allowRebuild) {
|
|
|
3279
3284
|
key: cursorPageIndexKey(options),
|
|
3280
3285
|
sessionId: options.sessionId,
|
|
3281
3286
|
model: options.model,
|
|
3287
|
+
clientPid: options.clientPid,
|
|
3282
3288
|
ids: [...idsById].sort((left, right) => left - right),
|
|
3283
3289
|
logsById,
|
|
3284
3290
|
entriesById
|
|
@@ -3290,7 +3296,7 @@ async function buildLogCursorPageIndex(options) {
|
|
|
3290
3296
|
const key = cursorPageIndexKey(options);
|
|
3291
3297
|
const logsById = /* @__PURE__ */ new Map();
|
|
3292
3298
|
const visitLog = (log) => {
|
|
3293
|
-
if (!matchesLogFilters(log, options.sessionId, options.model)) return;
|
|
3299
|
+
if (!matchesLogFilters(log, options.sessionId, options.model, options.clientPid)) return;
|
|
3294
3300
|
logsById.set(log.id, log);
|
|
3295
3301
|
};
|
|
3296
3302
|
await visitPersistedLogs((log) => {
|
|
@@ -3305,6 +3311,7 @@ async function buildLogCursorPageIndex(options) {
|
|
|
3305
3311
|
key,
|
|
3306
3312
|
sessionId: options.sessionId,
|
|
3307
3313
|
model: options.model,
|
|
3314
|
+
clientPid: options.clientPid,
|
|
3308
3315
|
ids: [...logsById.keys()].sort((left, right) => left - right),
|
|
3309
3316
|
logsById,
|
|
3310
3317
|
entriesById: /* @__PURE__ */ new Map()
|
|
@@ -3415,7 +3422,7 @@ async function collectIndexedSessionLogSummaries(sessionId) {
|
|
|
3415
3422
|
if (entries.length === 0) return [];
|
|
3416
3423
|
const needsMetadataRebuild = entries.some((entry) => !hasLogIndexFilterMetadata(entry));
|
|
3417
3424
|
const needsSummaryRebuild = entries.some((entry) => {
|
|
3418
|
-
if (!matchesLogIndexEntryFilters(entry, sessionId, void 0)) return false;
|
|
3425
|
+
if (!matchesLogIndexEntryFilters(entry, sessionId, void 0, void 0)) return false;
|
|
3419
3426
|
return !hasLogIndexSummary(entry);
|
|
3420
3427
|
});
|
|
3421
3428
|
if (needsMetadataRebuild || needsSummaryRebuild) {
|
|
@@ -3424,7 +3431,7 @@ async function collectIndexedSessionLogSummaries(sessionId) {
|
|
|
3424
3431
|
}
|
|
3425
3432
|
const summaries = [];
|
|
3426
3433
|
for (const entry of entries) {
|
|
3427
|
-
if (!matchesLogIndexEntryFilters(entry, sessionId, void 0)) continue;
|
|
3434
|
+
if (!matchesLogIndexEntryFilters(entry, sessionId, void 0, void 0)) continue;
|
|
3428
3435
|
if (entry.summary === void 0) continue;
|
|
3429
3436
|
summaries.push(buildSessionLogSummary(compactLogFromIndexSummary(entry.summary)));
|
|
3430
3437
|
}
|
|
@@ -4090,24 +4097,24 @@ const anthropicProvider = {
|
|
|
4090
4097
|
};
|
|
4091
4098
|
registry.register(anthropicProvider);
|
|
4092
4099
|
const MAX_CHUNKS = 1e3;
|
|
4093
|
-
function readProperty$
|
|
4100
|
+
function readProperty$2(value, key) {
|
|
4094
4101
|
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
4095
4102
|
return Object.getOwnPropertyDescriptor(value, key)?.value;
|
|
4096
4103
|
}
|
|
4097
|
-
function readStringProperty$
|
|
4098
|
-
const property = readProperty$
|
|
4104
|
+
function readStringProperty$2(value, key) {
|
|
4105
|
+
const property = readProperty$2(value, key);
|
|
4099
4106
|
return typeof property === "string" ? property : null;
|
|
4100
4107
|
}
|
|
4101
4108
|
function readNumberProperty(value, key) {
|
|
4102
|
-
const property = readProperty$
|
|
4109
|
+
const property = readProperty$2(value, key);
|
|
4103
4110
|
return typeof property === "number" && Number.isFinite(property) ? property : null;
|
|
4104
4111
|
}
|
|
4105
4112
|
function readObjectProperty(value, key) {
|
|
4106
|
-
const property = readProperty$
|
|
4113
|
+
const property = readProperty$2(value, key);
|
|
4107
4114
|
return property !== null && typeof property === "object" && !Array.isArray(property) ? property : null;
|
|
4108
4115
|
}
|
|
4109
|
-
function readArrayProperty(value, key) {
|
|
4110
|
-
const property = readProperty$
|
|
4116
|
+
function readArrayProperty$1(value, key) {
|
|
4117
|
+
const property = readProperty$2(value, key);
|
|
4111
4118
|
return Array.isArray(property) ? property : [];
|
|
4112
4119
|
}
|
|
4113
4120
|
function parseSseEvents(raw) {
|
|
@@ -4175,7 +4182,7 @@ function collectChunk(chunks, chunkIndex, streamStartMs, type, parsed) {
|
|
|
4175
4182
|
}
|
|
4176
4183
|
function setErrorFromPayload(log, payload) {
|
|
4177
4184
|
const errorObject = readObjectProperty(payload, "error");
|
|
4178
|
-
const message = readStringProperty$
|
|
4185
|
+
const message = readStringProperty$2(errorObject, "message") ?? readStringProperty$2(payload, "message") ?? readStringProperty$2(payload, "error");
|
|
4179
4186
|
if (message !== null && message.length > 0) {
|
|
4180
4187
|
log.error = message;
|
|
4181
4188
|
}
|
|
@@ -4299,7 +4306,7 @@ function extractChatCompletionsStream(events, log, fallbackModel, collectChunks)
|
|
|
4299
4306
|
}
|
|
4300
4307
|
function parseResponsesResponse(value) {
|
|
4301
4308
|
const fromResponseProperty = OpenAIResponsesResponseSchema.safeParse(
|
|
4302
|
-
readProperty$
|
|
4309
|
+
readProperty$2(value, "response")
|
|
4303
4310
|
);
|
|
4304
4311
|
if (fromResponseProperty.success) return fromResponseProperty.data;
|
|
4305
4312
|
const direct = OpenAIResponsesResponseSchema.safeParse(value);
|
|
@@ -4311,10 +4318,10 @@ function responseTextFromOutput(response) {
|
|
|
4311
4318
|
}
|
|
4312
4319
|
const parts = [];
|
|
4313
4320
|
for (const outputItem of response.output ?? []) {
|
|
4314
|
-
const content = readArrayProperty(outputItem, "content");
|
|
4321
|
+
const content = readArrayProperty$1(outputItem, "content");
|
|
4315
4322
|
for (const contentPart of content) {
|
|
4316
|
-
const type = readStringProperty$
|
|
4317
|
-
const text = readStringProperty$
|
|
4323
|
+
const type = readStringProperty$2(contentPart, "type");
|
|
4324
|
+
const text = readStringProperty$2(contentPart, "text");
|
|
4318
4325
|
if ((type === "output_text" || type === "text") && text !== null && text.length > 0) {
|
|
4319
4326
|
parts.push(text);
|
|
4320
4327
|
}
|
|
@@ -4333,7 +4340,7 @@ function updateUsageFromResponse(response, log) {
|
|
|
4333
4340
|
return { inputTokens, outputTokens };
|
|
4334
4341
|
}
|
|
4335
4342
|
function functionCallKey(payload, fallbackIndex) {
|
|
4336
|
-
const itemId = readStringProperty$
|
|
4343
|
+
const itemId = readStringProperty$2(payload, "item_id");
|
|
4337
4344
|
if (itemId !== null && itemId.length > 0) return itemId;
|
|
4338
4345
|
const outputIndex = readNumberProperty(payload, "output_index");
|
|
4339
4346
|
if (outputIndex !== null) return String(outputIndex);
|
|
@@ -4350,13 +4357,13 @@ function ensureFunctionCall(calls, key) {
|
|
|
4350
4357
|
return created;
|
|
4351
4358
|
}
|
|
4352
4359
|
function updateFunctionCallFromItem(calls, key, item) {
|
|
4353
|
-
if (readStringProperty$
|
|
4360
|
+
if (readStringProperty$2(item, "type") !== "function_call") return;
|
|
4354
4361
|
const call = ensureFunctionCall(calls, key);
|
|
4355
|
-
const id = readStringProperty$
|
|
4356
|
-
const callId = readStringProperty$
|
|
4357
|
-
const name = readStringProperty$
|
|
4358
|
-
const args = readStringProperty$
|
|
4359
|
-
const status = readStringProperty$
|
|
4362
|
+
const id = readStringProperty$2(item, "id");
|
|
4363
|
+
const callId = readStringProperty$2(item, "call_id");
|
|
4364
|
+
const name = readStringProperty$2(item, "name");
|
|
4365
|
+
const args = readStringProperty$2(item, "arguments");
|
|
4366
|
+
const status = readStringProperty$2(item, "status");
|
|
4360
4367
|
if (id !== null) call.id = id;
|
|
4361
4368
|
if (callId !== null) call.call_id = callId;
|
|
4362
4369
|
if (name !== null) call.name = name;
|
|
@@ -4444,13 +4451,13 @@ function extractResponsesStream(events, log, fallbackModel, collectChunks) {
|
|
|
4444
4451
|
outputTokens = usage.outputTokens ?? outputTokens;
|
|
4445
4452
|
setErrorFromPayload(log, response);
|
|
4446
4453
|
}
|
|
4447
|
-
const delta = readStringProperty$
|
|
4454
|
+
const delta = readStringProperty$2(parsed, "delta");
|
|
4448
4455
|
switch (type) {
|
|
4449
4456
|
case "response.output_text.delta":
|
|
4450
4457
|
if (delta !== null) outputText += delta;
|
|
4451
4458
|
break;
|
|
4452
4459
|
case "response.output_text.done": {
|
|
4453
|
-
const text = readStringProperty$
|
|
4460
|
+
const text = readStringProperty$2(parsed, "text");
|
|
4454
4461
|
if (outputText.length === 0 && text !== null) outputText = text;
|
|
4455
4462
|
break;
|
|
4456
4463
|
}
|
|
@@ -4462,7 +4469,7 @@ function extractResponsesStream(events, log, fallbackModel, collectChunks) {
|
|
|
4462
4469
|
break;
|
|
4463
4470
|
}
|
|
4464
4471
|
case "response.function_call_arguments.done": {
|
|
4465
|
-
const args = readStringProperty$
|
|
4472
|
+
const args = readStringProperty$2(parsed, "arguments");
|
|
4466
4473
|
if (args !== null) {
|
|
4467
4474
|
const call = ensureFunctionCall(calls, functionCallKey(parsed, calls.size));
|
|
4468
4475
|
call.arguments = args;
|
|
@@ -4511,7 +4518,7 @@ function extractResponsesStream(events, log, fallbackModel, collectChunks) {
|
|
|
4511
4518
|
return JSON.stringify(normalizedResponse.data);
|
|
4512
4519
|
}
|
|
4513
4520
|
if (log.outputTokens === null) {
|
|
4514
|
-
const finalText = readStringProperty$
|
|
4521
|
+
const finalText = readStringProperty$2(normalized, "output_text") ?? outputText;
|
|
4515
4522
|
const estimatedOutputTokens = Math.ceil(finalText.length / 4);
|
|
4516
4523
|
log.outputTokens = estimatedOutputTokens;
|
|
4517
4524
|
}
|
|
@@ -6251,7 +6258,7 @@ function parseJson$1(raw) {
|
|
|
6251
6258
|
function isRecord$1(value) {
|
|
6252
6259
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6253
6260
|
}
|
|
6254
|
-
function readProperty(value, key) {
|
|
6261
|
+
function readProperty$1(value, key) {
|
|
6255
6262
|
if (!isRecord$1(value)) return void 0;
|
|
6256
6263
|
return Object.getOwnPropertyDescriptor(value, key)?.value;
|
|
6257
6264
|
}
|
|
@@ -6259,18 +6266,18 @@ function hasOwnProperty(value, key) {
|
|
|
6259
6266
|
return Object.getOwnPropertyDescriptor(value, key) !== void 0;
|
|
6260
6267
|
}
|
|
6261
6268
|
function readString(value, key) {
|
|
6262
|
-
const property = readProperty(value, key);
|
|
6269
|
+
const property = readProperty$1(value, key);
|
|
6263
6270
|
return typeof property === "string" ? property : null;
|
|
6264
6271
|
}
|
|
6265
6272
|
function readArray(value, key) {
|
|
6266
|
-
const property = readProperty(value, key);
|
|
6273
|
+
const property = readProperty$1(value, key);
|
|
6267
6274
|
return Array.isArray(property) ? property : [];
|
|
6268
6275
|
}
|
|
6269
6276
|
function readStringArray(value, key) {
|
|
6270
6277
|
return readArray(value, key).filter((item) => typeof item === "string");
|
|
6271
6278
|
}
|
|
6272
6279
|
function readObject(value, key) {
|
|
6273
|
-
const property = readProperty(value, key);
|
|
6280
|
+
const property = readProperty$1(value, key);
|
|
6274
6281
|
return isRecord$1(property) ? property : null;
|
|
6275
6282
|
}
|
|
6276
6283
|
function normalizeExpectedType(typeName) {
|
|
@@ -6288,7 +6295,7 @@ function normalizeExpectedType(typeName) {
|
|
|
6288
6295
|
}
|
|
6289
6296
|
}
|
|
6290
6297
|
function schemaTypes(schema) {
|
|
6291
|
-
const typeValue = readProperty(schema, "type");
|
|
6298
|
+
const typeValue = readProperty$1(schema, "type");
|
|
6292
6299
|
const rawTypes = Array.isArray(typeValue) ? typeValue : [typeValue];
|
|
6293
6300
|
const types = [];
|
|
6294
6301
|
for (const rawType of rawTypes) {
|
|
@@ -6378,7 +6385,7 @@ function schemaAllowsObjectValidation(schema, expectedTypes) {
|
|
|
6378
6385
|
return expectedTypes.includes("object");
|
|
6379
6386
|
}
|
|
6380
6387
|
function schemaAllowsArrayValidation(schema, expectedTypes) {
|
|
6381
|
-
if (expectedTypes.length === 0) return readProperty(schema, "items") !== void 0;
|
|
6388
|
+
if (expectedTypes.length === 0) return readProperty$1(schema, "items") !== void 0;
|
|
6382
6389
|
return expectedTypes.includes("array");
|
|
6383
6390
|
}
|
|
6384
6391
|
function addTypeWarning(warnings, toolName, path2, expectedTypes, value) {
|
|
@@ -6411,7 +6418,7 @@ function validateObjectSchema(schema, value, toolName, path2, warnings) {
|
|
|
6411
6418
|
}
|
|
6412
6419
|
}
|
|
6413
6420
|
function validateArraySchema(schema, value, toolName, path2, warnings) {
|
|
6414
|
-
const itemsSchema = readProperty(schema, "items");
|
|
6421
|
+
const itemsSchema = readProperty$1(schema, "items");
|
|
6415
6422
|
if (itemsSchema === void 0) return;
|
|
6416
6423
|
let index = 0;
|
|
6417
6424
|
for (const item of value) {
|
|
@@ -6420,7 +6427,7 @@ function validateArraySchema(schema, value, toolName, path2, warnings) {
|
|
|
6420
6427
|
}
|
|
6421
6428
|
}
|
|
6422
6429
|
function validateEnum(schema, value, toolName, path2, warnings) {
|
|
6423
|
-
const enumValue = readProperty(schema, "enum");
|
|
6430
|
+
const enumValue = readProperty$1(schema, "enum");
|
|
6424
6431
|
if (Array.isArray(enumValue) && enumValue.length > 0 && !enumMatches(value, enumValue)) {
|
|
6425
6432
|
warnings.push(
|
|
6426
6433
|
`Tool call "${toolName}" ${pathLabel(path2)} expected one of ${formatJsonValue(
|
|
@@ -6537,7 +6544,7 @@ function extractOpenAIToolCalls(response) {
|
|
|
6537
6544
|
for (const call of readArray(message, "tool_calls")) {
|
|
6538
6545
|
const functionCall = readObject(call, "function");
|
|
6539
6546
|
const name = functionCall === null ? null : readString(functionCall, "name");
|
|
6540
|
-
const parsedArguments = functionCall === null ? { value: {}, issue: "function block is missing" } : parseOpenAIArguments(readProperty(functionCall, "arguments"));
|
|
6547
|
+
const parsedArguments = functionCall === null ? { value: {}, issue: "function block is missing" } : parseOpenAIArguments(readProperty$1(functionCall, "arguments"));
|
|
6541
6548
|
calls.push({
|
|
6542
6549
|
name,
|
|
6543
6550
|
arguments: parsedArguments.value,
|
|
@@ -6548,7 +6555,7 @@ function extractOpenAIToolCalls(response) {
|
|
|
6548
6555
|
}
|
|
6549
6556
|
const legacyFunctionCall = readObject(message, "function_call");
|
|
6550
6557
|
if (legacyFunctionCall !== null) {
|
|
6551
|
-
const parsedArguments = parseOpenAIArguments(readProperty(legacyFunctionCall, "arguments"));
|
|
6558
|
+
const parsedArguments = parseOpenAIArguments(readProperty$1(legacyFunctionCall, "arguments"));
|
|
6552
6559
|
calls.push({
|
|
6553
6560
|
name: readString(legacyFunctionCall, "name"),
|
|
6554
6561
|
arguments: parsedArguments.value,
|
|
@@ -6564,7 +6571,7 @@ function extractOpenAIToolCalls(response) {
|
|
|
6564
6571
|
outputIndex++;
|
|
6565
6572
|
continue;
|
|
6566
6573
|
}
|
|
6567
|
-
const parsedArguments = parseOpenAIArguments(readProperty(item, "arguments"));
|
|
6574
|
+
const parsedArguments = parseOpenAIArguments(readProperty$1(item, "arguments"));
|
|
6568
6575
|
calls.push({
|
|
6569
6576
|
name: readString(item, "name"),
|
|
6570
6577
|
arguments: parsedArguments.value,
|
|
@@ -6585,7 +6592,7 @@ function extractAnthropicToolCalls(response) {
|
|
|
6585
6592
|
}
|
|
6586
6593
|
calls.push({
|
|
6587
6594
|
name: readString(block, "name"),
|
|
6588
|
-
arguments: readProperty(block, "input") ?? {},
|
|
6595
|
+
arguments: readProperty$1(block, "input") ?? {},
|
|
6589
6596
|
argumentIssue: null,
|
|
6590
6597
|
location: `content[${contentIndex}]`
|
|
6591
6598
|
});
|
|
@@ -7154,9 +7161,11 @@ class RawStreamCapture {
|
|
|
7154
7161
|
}
|
|
7155
7162
|
}
|
|
7156
7163
|
const PATH_V1_CHAT_COMPLETIONS = "/v1/chat/completions";
|
|
7164
|
+
const PATH_V1_RESPONSES = "/v1/responses";
|
|
7165
|
+
const PATH_V1_MESSAGES = "/v1/messages";
|
|
7157
7166
|
function buildUpstreamUrl(upstreamBase, normalizedPath) {
|
|
7158
7167
|
const base = upstreamBase.endsWith("/") ? upstreamBase.slice(0, -1) : upstreamBase;
|
|
7159
|
-
const endpointPath = normalizedPath
|
|
7168
|
+
const endpointPath = endpointPathFor(normalizedPath);
|
|
7160
7169
|
const queryIndex = normalizedPath.indexOf("?");
|
|
7161
7170
|
const search = queryIndex >= 0 ? normalizedPath.slice(queryIndex) : "";
|
|
7162
7171
|
if (endpointPath !== "" && base.endsWith(endpointPath)) {
|
|
@@ -7170,9 +7179,78 @@ function buildUpstreamUrl(upstreamBase, normalizedPath) {
|
|
|
7170
7179
|
}
|
|
7171
7180
|
return base + normalizedPath;
|
|
7172
7181
|
}
|
|
7182
|
+
function previewUpstreamUrl(upstreamBase, normalizedPath, options = {}) {
|
|
7183
|
+
const base = upstreamBase.trim().replace(/\/+$/, "");
|
|
7184
|
+
const endpointPath = endpointPathFor(normalizedPath);
|
|
7185
|
+
const finalUrl = buildUpstreamUrl(base, normalizedPath);
|
|
7186
|
+
const diagnostics = [];
|
|
7187
|
+
const exactEndpoint = endpointPath !== "" && base.endsWith(endpointPath);
|
|
7188
|
+
if (exactEndpoint) {
|
|
7189
|
+
diagnostics.push({
|
|
7190
|
+
severity: "info",
|
|
7191
|
+
message: "This already includes the exact endpoint; no duplicate suffix will be appended."
|
|
7192
|
+
});
|
|
7193
|
+
} else if (isZhipuVersionedOpenAIBase(base) && isVersionedChatCompletionsPath(normalizedPath)) {
|
|
7194
|
+
diagnostics.push({
|
|
7195
|
+
severity: "info",
|
|
7196
|
+
message: "Zhipu bases already include the API version; only /chat/completions is appended."
|
|
7197
|
+
});
|
|
7198
|
+
} else if (base.endsWith("/v1") && normalizedPath.startsWith("/v1/")) {
|
|
7199
|
+
diagnostics.push({
|
|
7200
|
+
severity: "info",
|
|
7201
|
+
message: "Base URL already ends with /v1; the suffix will not repeat /v1."
|
|
7202
|
+
});
|
|
7203
|
+
}
|
|
7204
|
+
if (isResponsesPath(endpointPath) && baseEndsWithChatEndpoint(base)) {
|
|
7205
|
+
diagnostics.push({
|
|
7206
|
+
severity: "warning",
|
|
7207
|
+
message: "This looks like a Chat Completions endpoint, so Responses would append after it."
|
|
7208
|
+
});
|
|
7209
|
+
}
|
|
7210
|
+
if (isChatCompletionsPath(endpointPath) && baseEndsWithResponsesEndpoint(base)) {
|
|
7211
|
+
diagnostics.push({
|
|
7212
|
+
severity: "warning",
|
|
7213
|
+
message: "This looks like a Responses endpoint, so Chat Completions would append after it."
|
|
7214
|
+
});
|
|
7215
|
+
}
|
|
7216
|
+
if (isResponsesPath(endpointPath) && isLikelyDeepSeekBase(base, options.providerName)) {
|
|
7217
|
+
diagnostics.push({
|
|
7218
|
+
severity: "warning",
|
|
7219
|
+
message: "DeepSeek's official API does not currently expose OpenAI Responses."
|
|
7220
|
+
});
|
|
7221
|
+
}
|
|
7222
|
+
return { finalUrl, diagnostics };
|
|
7223
|
+
}
|
|
7224
|
+
function endpointPathFor(normalizedPath) {
|
|
7225
|
+
return normalizedPath.split("?")[0] ?? normalizedPath;
|
|
7226
|
+
}
|
|
7173
7227
|
function isVersionedChatCompletionsPath(normalizedPath) {
|
|
7174
7228
|
return normalizedPath === PATH_V1_CHAT_COMPLETIONS || normalizedPath.startsWith(`${PATH_V1_CHAT_COMPLETIONS}?`) || normalizedPath.startsWith(`${PATH_V1_CHAT_COMPLETIONS}/`);
|
|
7175
7229
|
}
|
|
7230
|
+
function isChatCompletionsPath(endpointPath) {
|
|
7231
|
+
return endpointPath === PATH_V1_CHAT_COMPLETIONS || endpointPath.startsWith(`${PATH_V1_CHAT_COMPLETIONS}/`);
|
|
7232
|
+
}
|
|
7233
|
+
function isResponsesPath(endpointPath) {
|
|
7234
|
+
return endpointPath === PATH_V1_RESPONSES || endpointPath.startsWith(`${PATH_V1_RESPONSES}/`);
|
|
7235
|
+
}
|
|
7236
|
+
function baseEndsWithChatEndpoint(base) {
|
|
7237
|
+
const normalized = base.toLowerCase();
|
|
7238
|
+
return normalized.endsWith("/chat/completions");
|
|
7239
|
+
}
|
|
7240
|
+
function baseEndsWithResponsesEndpoint(base) {
|
|
7241
|
+
const normalized = base.toLowerCase();
|
|
7242
|
+
return normalized.endsWith("/responses");
|
|
7243
|
+
}
|
|
7244
|
+
function isLikelyDeepSeekBase(base, providerName) {
|
|
7245
|
+
const provider = providerName?.toLowerCase();
|
|
7246
|
+
if (provider !== void 0 && provider.includes("deepseek")) return true;
|
|
7247
|
+
try {
|
|
7248
|
+
const parsed = new URL(base);
|
|
7249
|
+
return parsed.hostname.toLowerCase().includes("deepseek");
|
|
7250
|
+
} catch {
|
|
7251
|
+
return base.toLowerCase().includes("deepseek");
|
|
7252
|
+
}
|
|
7253
|
+
}
|
|
7176
7254
|
function isZhipuVersionedOpenAIBase(base) {
|
|
7177
7255
|
try {
|
|
7178
7256
|
const parsed = new URL(base);
|
|
@@ -7185,7 +7263,7 @@ function isZhipuVersionedOpenAIBase(base) {
|
|
|
7185
7263
|
function describeApiRoute(apiPath) {
|
|
7186
7264
|
const endpointPath = apiPath.split("?")[0] ?? "";
|
|
7187
7265
|
const isChatCompletions = endpointPath === PATH_CHAT_COMPLETIONS || endpointPath === PATH_V1_CHAT_COMPLETIONS$1;
|
|
7188
|
-
const isResponses = endpointPath === PATH_RESPONSES || endpointPath === PATH_V1_RESPONSES;
|
|
7266
|
+
const isResponses = endpointPath === PATH_RESPONSES || endpointPath === PATH_V1_RESPONSES$1;
|
|
7189
7267
|
const isOpenAI = isChatCompletions || isResponses;
|
|
7190
7268
|
const normalizedPath = isOpenAI && !apiPath.startsWith("/v1/") ? `/v1${apiPath}` : apiPath;
|
|
7191
7269
|
return { apiPath, endpointPath, isChatCompletions, isResponses, isOpenAI, normalizedPath };
|
|
@@ -7255,7 +7333,7 @@ function parseRequestPath(req, url) {
|
|
|
7255
7333
|
const route = describeApiRoute(getProxyApiPath(url));
|
|
7256
7334
|
const isPost = req.method === "POST";
|
|
7257
7335
|
const isChatCompletions = isPost && route.isChatCompletions;
|
|
7258
|
-
const isMessages = isPost && (route.endpointPath === PATH_V1_MESSAGES || route.isChatCompletions);
|
|
7336
|
+
const isMessages = isPost && (route.endpointPath === PATH_V1_MESSAGES$1 || route.isChatCompletions);
|
|
7259
7337
|
return {
|
|
7260
7338
|
apiPath: route.apiPath,
|
|
7261
7339
|
isMessages,
|
|
@@ -9016,7 +9094,7 @@ const Route$w = createFileRoute("/api/models")({
|
|
|
9016
9094
|
}
|
|
9017
9095
|
}
|
|
9018
9096
|
});
|
|
9019
|
-
const version = "2.1.
|
|
9097
|
+
const version = "2.1.18";
|
|
9020
9098
|
const packageJson = {
|
|
9021
9099
|
version
|
|
9022
9100
|
};
|
|
@@ -9650,11 +9728,18 @@ const SearchLogsResponseSchema = object({
|
|
|
9650
9728
|
const PAGINATION_DEFAULTS = { offset: 0, limit: 3 };
|
|
9651
9729
|
const LIMIT_HARD_CAP = 5;
|
|
9652
9730
|
const LOG_DETAIL_TEXT_LIMIT = 2e5;
|
|
9731
|
+
const PROCESS_LOG_LIMIT_DEFAULT = 50;
|
|
9732
|
+
const PROCESS_LOG_LIMIT_MAX = 200;
|
|
9653
9733
|
function clampLimit(input) {
|
|
9654
9734
|
if (input === void 0) return PAGINATION_DEFAULTS.limit;
|
|
9655
9735
|
if (!Number.isFinite(input) || input < 1) return 1;
|
|
9656
9736
|
return Math.min(Math.floor(input), LIMIT_HARD_CAP);
|
|
9657
9737
|
}
|
|
9738
|
+
function clampProcessLogLimit(input) {
|
|
9739
|
+
if (input === void 0) return PROCESS_LOG_LIMIT_DEFAULT;
|
|
9740
|
+
if (!Number.isFinite(input) || input < 1) return 1;
|
|
9741
|
+
return Math.min(Math.floor(input), PROCESS_LOG_LIMIT_MAX);
|
|
9742
|
+
}
|
|
9658
9743
|
function textJson(data) {
|
|
9659
9744
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
9660
9745
|
}
|
|
@@ -9700,8 +9785,11 @@ function buildBoundedLogDetail(log) {
|
|
|
9700
9785
|
responseTextTruncated: boundedResponse.truncated
|
|
9701
9786
|
};
|
|
9702
9787
|
}
|
|
9788
|
+
function logHasError(log) {
|
|
9789
|
+
return log.error !== null && log.error !== void 0 && log.error.length > 0 || log.responseStatus !== null && log.responseStatus !== void 0 && log.responseStatus >= 400;
|
|
9790
|
+
}
|
|
9703
9791
|
function buildLogSummary(log) {
|
|
9704
|
-
const hasError = log
|
|
9792
|
+
const hasError = logHasError(log);
|
|
9705
9793
|
const rawRequestBodyBytes = log.rawRequestBodyBytes ?? textByteLength(log.rawRequestBody);
|
|
9706
9794
|
const responseTextBytes = log.responseTextBytes ?? textByteLength(log.responseText);
|
|
9707
9795
|
return {
|
|
@@ -9738,6 +9826,74 @@ function buildLogSummary(log) {
|
|
|
9738
9826
|
responseTextBytes
|
|
9739
9827
|
};
|
|
9740
9828
|
}
|
|
9829
|
+
function sortedUniqueStrings(values) {
|
|
9830
|
+
return [
|
|
9831
|
+
...new Set(
|
|
9832
|
+
values.filter(
|
|
9833
|
+
(value) => value !== null && value !== void 0 && value !== ""
|
|
9834
|
+
)
|
|
9835
|
+
)
|
|
9836
|
+
].sort((left, right) => left.localeCompare(right));
|
|
9837
|
+
}
|
|
9838
|
+
function sortedUniqueNumbers(values) {
|
|
9839
|
+
return [
|
|
9840
|
+
...new Set(
|
|
9841
|
+
values.filter(
|
|
9842
|
+
(value) => value !== null && value !== void 0 && Number.isFinite(value)
|
|
9843
|
+
)
|
|
9844
|
+
)
|
|
9845
|
+
].sort((left, right) => left - right);
|
|
9846
|
+
}
|
|
9847
|
+
function inferAgentFromUserAgent(userAgent) {
|
|
9848
|
+
if (userAgent === null || userAgent === void 0) return null;
|
|
9849
|
+
const lower2 = userAgent.toLowerCase();
|
|
9850
|
+
if (lower2.includes("codex")) return "Codex";
|
|
9851
|
+
if (lower2.includes("opencode")) return "OpenCode";
|
|
9852
|
+
if (lower2.includes("claude")) return "Claude Code";
|
|
9853
|
+
if (lower2.includes("mimocode")) return "MiMoCode";
|
|
9854
|
+
if (lower2.includes("ai-sdk")) return "AI SDK";
|
|
9855
|
+
return null;
|
|
9856
|
+
}
|
|
9857
|
+
function processSummary(clientPid, logs, total, limit) {
|
|
9858
|
+
const sortedLogs = [...logs].sort((left, right) => left.id - right.id);
|
|
9859
|
+
const first = sortedLogs[0];
|
|
9860
|
+
const last = sortedLogs[sortedLogs.length - 1];
|
|
9861
|
+
const userAgents = sortedUniqueStrings(sortedLogs.map((log) => log.userAgent));
|
|
9862
|
+
const agents = sortedUniqueStrings(userAgents.map(inferAgentFromUserAgent));
|
|
9863
|
+
const sessions2 = sortedUniqueStrings(sortedLogs.map((log) => log.sessionId));
|
|
9864
|
+
return {
|
|
9865
|
+
clientPid,
|
|
9866
|
+
total,
|
|
9867
|
+
limit,
|
|
9868
|
+
logCount: sortedLogs.length,
|
|
9869
|
+
sessionCount: sessions2.length,
|
|
9870
|
+
sessions: sessions2,
|
|
9871
|
+
agents,
|
|
9872
|
+
userAgents,
|
|
9873
|
+
clientPorts: sortedUniqueNumbers(sortedLogs.map((log) => log.clientPort)),
|
|
9874
|
+
clientCwds: sortedUniqueStrings(sortedLogs.map((log) => log.clientCwd)),
|
|
9875
|
+
clientProjectFolders: sortedUniqueStrings(sortedLogs.map((log) => log.clientProjectFolder)),
|
|
9876
|
+
models: sortedUniqueStrings(sortedLogs.map((log) => log.model)),
|
|
9877
|
+
providers: sortedUniqueStrings(sortedLogs.map((log) => log.providerName)),
|
|
9878
|
+
errorCount: sortedLogs.filter(logHasError).length,
|
|
9879
|
+
startedAt: first?.timestamp ?? null,
|
|
9880
|
+
updatedAt: last?.timestamp ?? null,
|
|
9881
|
+
latestLogs: sortedLogs.slice(-Math.min(10, sortedLogs.length)).reverse().map(buildLogSummary)
|
|
9882
|
+
};
|
|
9883
|
+
}
|
|
9884
|
+
async function readCompactLogsPage(callApi2, params) {
|
|
9885
|
+
const path2 = `/api/logs?${params.toString()}`;
|
|
9886
|
+
const res = await callApi2(path2);
|
|
9887
|
+
if (!res.ok) return toolError(`GET ${path2} returned ${res.status}`);
|
|
9888
|
+
const rawBody = await res.json();
|
|
9889
|
+
const parsed = LogsListResponseSchema.safeParse(rawBody);
|
|
9890
|
+
if (!parsed.success) return toolError("GET /api/logs returned an unparseable logs shape");
|
|
9891
|
+
const logs = parsed.data.logs ?? [];
|
|
9892
|
+
return { logs, total: parsed.data.total ?? logs.length };
|
|
9893
|
+
}
|
|
9894
|
+
function isToolResult(value) {
|
|
9895
|
+
return typeof value === "object" && value !== null && Object.getOwnPropertyDescriptor(value, "content") !== void 0;
|
|
9896
|
+
}
|
|
9741
9897
|
async function listLogsImpl(callApi2, args) {
|
|
9742
9898
|
const offset = args.offset ?? PAGINATION_DEFAULTS.offset;
|
|
9743
9899
|
const limit = clampLimit(args.limit);
|
|
@@ -9752,6 +9908,9 @@ async function listLogsImpl(callApi2, args) {
|
|
|
9752
9908
|
if (args.model !== void 0 && args.model.length > 0) {
|
|
9753
9909
|
params.set("model", args.model);
|
|
9754
9910
|
}
|
|
9911
|
+
if (args.clientPid !== void 0) {
|
|
9912
|
+
params.set("clientPid", String(args.clientPid));
|
|
9913
|
+
}
|
|
9755
9914
|
const res = await callApi2(`/api/logs?${params.toString()}`);
|
|
9756
9915
|
if (!res.ok) return toolError(`GET /api/logs returned ${res.status}`);
|
|
9757
9916
|
const rawBody = await res.json();
|
|
@@ -9777,6 +9936,9 @@ async function searchLogsImpl(callApi2, args) {
|
|
|
9777
9936
|
if (args.model !== void 0 && args.model.length > 0) {
|
|
9778
9937
|
params.set("model", args.model);
|
|
9779
9938
|
}
|
|
9939
|
+
if (args.clientPid !== void 0) {
|
|
9940
|
+
params.set("clientPid", String(args.clientPid));
|
|
9941
|
+
}
|
|
9780
9942
|
const res = await callApi2(`/api/logs?${params.toString()}`);
|
|
9781
9943
|
if (!res.ok) return toolError(`GET /api/logs search returned ${res.status}`);
|
|
9782
9944
|
const rawBody = await res.json();
|
|
@@ -9952,6 +10114,225 @@ async function getSessionTimelineImpl(callApi2, args) {
|
|
|
9952
10114
|
buildSessionTimeline(args.sessionId, logs, parsed.data.total ?? logs.length, limit)
|
|
9953
10115
|
);
|
|
9954
10116
|
}
|
|
10117
|
+
async function listProcessesImpl(callApi2, args = {}) {
|
|
10118
|
+
const scanLimit = clampProcessLogLimit(args.scanLimit ?? args.limit);
|
|
10119
|
+
const params = new URLSearchParams({
|
|
10120
|
+
q: "",
|
|
10121
|
+
offset: "0",
|
|
10122
|
+
limit: String(Math.min(scanLimit, 50)),
|
|
10123
|
+
scanLimit: String(scanLimit)
|
|
10124
|
+
});
|
|
10125
|
+
const res = await callApi2(`/api/logs?${params.toString()}`);
|
|
10126
|
+
if (!res.ok) return toolError(`GET /api/logs process scan returned ${res.status}`);
|
|
10127
|
+
const rawBody = await res.json();
|
|
10128
|
+
const parsed = SearchLogsResponseSchema.safeParse(rawBody);
|
|
10129
|
+
if (!parsed.success) return toolError("GET /api/logs returned an unparseable process scan shape");
|
|
10130
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
10131
|
+
for (const log of parsed.data.logs) {
|
|
10132
|
+
if (log.clientPid === null || log.clientPid === void 0) continue;
|
|
10133
|
+
const existing = grouped.get(log.clientPid) ?? [];
|
|
10134
|
+
existing.push(log);
|
|
10135
|
+
grouped.set(log.clientPid, existing);
|
|
10136
|
+
}
|
|
10137
|
+
const processes = [...grouped.entries()].map(([clientPid, logs]) => processSummary(clientPid, logs, logs.length, logs.length)).sort((left, right) => {
|
|
10138
|
+
const leftUpdated = typeof left["updatedAt"] === "string" ? left["updatedAt"] : "";
|
|
10139
|
+
const rightUpdated = typeof right["updatedAt"] === "string" ? right["updatedAt"] : "";
|
|
10140
|
+
return rightUpdated.localeCompare(leftUpdated);
|
|
10141
|
+
});
|
|
10142
|
+
return textJson({
|
|
10143
|
+
scanned: parsed.data.scanned ?? parsed.data.logs.length,
|
|
10144
|
+
processCount: processes.length,
|
|
10145
|
+
processes
|
|
10146
|
+
});
|
|
10147
|
+
}
|
|
10148
|
+
async function getProcessImpl(callApi2, args) {
|
|
10149
|
+
const limit = clampProcessLogLimit(args.limit);
|
|
10150
|
+
const offset = args.offset ?? 0;
|
|
10151
|
+
const params = new URLSearchParams({
|
|
10152
|
+
clientPid: String(args.clientPid),
|
|
10153
|
+
offset: String(offset),
|
|
10154
|
+
limit: String(limit),
|
|
10155
|
+
compact: "1"
|
|
10156
|
+
});
|
|
10157
|
+
const result = await readCompactLogsPage(callApi2, params);
|
|
10158
|
+
if (isToolResult(result)) return result;
|
|
10159
|
+
return textJson(processSummary(args.clientPid, result.logs, result.total, limit));
|
|
10160
|
+
}
|
|
10161
|
+
async function getProcessTimelineImpl(callApi2, args) {
|
|
10162
|
+
const limit = clampTimelineLimit(args.limit);
|
|
10163
|
+
const offset = args.offset ?? 0;
|
|
10164
|
+
const params = new URLSearchParams({
|
|
10165
|
+
clientPid: String(args.clientPid),
|
|
10166
|
+
offset: String(offset),
|
|
10167
|
+
limit: String(limit),
|
|
10168
|
+
compact: "1"
|
|
10169
|
+
});
|
|
10170
|
+
const result = await readCompactLogsPage(callApi2, params);
|
|
10171
|
+
if (isToolResult(result)) return result;
|
|
10172
|
+
const sortedLogs = [...result.logs].sort((left, right) => left.id - right.id);
|
|
10173
|
+
return textJson({
|
|
10174
|
+
clientPid: args.clientPid,
|
|
10175
|
+
logCoverage: "bounded",
|
|
10176
|
+
total: result.total,
|
|
10177
|
+
limit,
|
|
10178
|
+
eventCount: sortedLogs.length,
|
|
10179
|
+
requestCount: sortedLogs.length,
|
|
10180
|
+
errorCount: sortedLogs.filter(logHasError).length,
|
|
10181
|
+
startedAt: sortedLogs[0]?.timestamp ?? null,
|
|
10182
|
+
updatedAt: sortedLogs.at(-1)?.timestamp ?? null,
|
|
10183
|
+
sessions: sortedUniqueStrings(sortedLogs.map((log) => log.sessionId)),
|
|
10184
|
+
models: sortedUniqueStrings(sortedLogs.map((log) => log.model)),
|
|
10185
|
+
providers: sortedUniqueStrings(sortedLogs.map((log) => log.providerName)),
|
|
10186
|
+
events: sortedLogs.map((log, index) => ({
|
|
10187
|
+
sequence: index + 1,
|
|
10188
|
+
kind: "request",
|
|
10189
|
+
logId: log.id,
|
|
10190
|
+
...buildLogSummary(log)
|
|
10191
|
+
}))
|
|
10192
|
+
});
|
|
10193
|
+
}
|
|
10194
|
+
async function getLogHeadersImpl(callApi2, id) {
|
|
10195
|
+
const res = await callApi2(`/api/logs/${id}`);
|
|
10196
|
+
if (!res.ok) return toolError(`GET /api/logs/${id} returned ${res.status}`);
|
|
10197
|
+
const rawBody = await res.json();
|
|
10198
|
+
const parsed = CapturedLogSchema.safeParse(rawBody);
|
|
10199
|
+
if (!parsed.success) {
|
|
10200
|
+
return toolError(`GET /api/logs/${id} returned an unparseable CapturedLog`);
|
|
10201
|
+
}
|
|
10202
|
+
const log = parsed.data;
|
|
10203
|
+
return textJson({
|
|
10204
|
+
id: log.id,
|
|
10205
|
+
sessionId: log.sessionId,
|
|
10206
|
+
userAgent: log.userAgent,
|
|
10207
|
+
origin: log.origin,
|
|
10208
|
+
clientPid: log.clientPid ?? null,
|
|
10209
|
+
clientPort: log.clientPort ?? null,
|
|
10210
|
+
clientCwd: log.clientCwd ?? null,
|
|
10211
|
+
clientProjectFolder: log.clientProjectFolder ?? null,
|
|
10212
|
+
apiFormat: log.apiFormat,
|
|
10213
|
+
method: log.method,
|
|
10214
|
+
path: log.path,
|
|
10215
|
+
model: log.model,
|
|
10216
|
+
rawHeaders: log.rawHeaders ?? null,
|
|
10217
|
+
headers: log.headers ?? null,
|
|
10218
|
+
hasRawHeaders: log.rawHeaders !== void 0 && Object.keys(log.rawHeaders).length > 0,
|
|
10219
|
+
hasHeaders: log.headers !== void 0 && Object.keys(log.headers).length > 0,
|
|
10220
|
+
bodyContentMode: log.bodyContentMode ?? null
|
|
10221
|
+
});
|
|
10222
|
+
}
|
|
10223
|
+
async function getRuntimeConfigImpl(callApi2) {
|
|
10224
|
+
const configRes = await callApi2("/api/config");
|
|
10225
|
+
if (!configRes.ok) return toolError(`GET /api/config returned ${configRes.status}`);
|
|
10226
|
+
const statsRes = await callApi2("/api/logs?stats=1");
|
|
10227
|
+
if (!statsRes.ok) return toolError(`GET /api/logs?stats=1 returned ${statsRes.status}`);
|
|
10228
|
+
const config = await configRes.json();
|
|
10229
|
+
const storage = await statsRes.json();
|
|
10230
|
+
return textJson({
|
|
10231
|
+
config,
|
|
10232
|
+
storage
|
|
10233
|
+
});
|
|
10234
|
+
}
|
|
10235
|
+
async function diagnoseCaptureImpl(callApi2, args = {}) {
|
|
10236
|
+
const runtime = await getRuntimeConfigImpl(callApi2);
|
|
10237
|
+
if (runtime.isError === true) return runtime;
|
|
10238
|
+
const runtimeText = runtime.content[0]?.text ?? "{}";
|
|
10239
|
+
const runtimePayload = JSON.parse(runtimeText);
|
|
10240
|
+
const runtimeRecord = isRecord(runtimePayload) ? runtimePayload : {};
|
|
10241
|
+
const configRecord = isRecord(runtimeRecord["config"]) ? runtimeRecord["config"] : {};
|
|
10242
|
+
const captureMode = stringField(configRecord, "captureMode");
|
|
10243
|
+
let log = null;
|
|
10244
|
+
if (args.id !== void 0) {
|
|
10245
|
+
const logRes = await callApi2(`/api/logs/${args.id}`);
|
|
10246
|
+
if (!logRes.ok) return toolError(`GET /api/logs/${args.id} returned ${logRes.status}`);
|
|
10247
|
+
const rawLog = await logRes.json();
|
|
10248
|
+
const parsed = CapturedLogSchema.safeParse(rawLog);
|
|
10249
|
+
if (!parsed.success) return toolError(`GET /api/logs/${args.id} returned an unparseable log`);
|
|
10250
|
+
log = parsed.data;
|
|
10251
|
+
}
|
|
10252
|
+
const findings = [];
|
|
10253
|
+
const recommendations = [];
|
|
10254
|
+
if (captureMode !== "full") {
|
|
10255
|
+
findings.push(
|
|
10256
|
+
"Runtime captureMode is not full, so request/response bodies and headers may be compacted."
|
|
10257
|
+
);
|
|
10258
|
+
recommendations.push(
|
|
10259
|
+
"Restart or launch Agent Inspector with full capture mode when header/body evidence is required."
|
|
10260
|
+
);
|
|
10261
|
+
}
|
|
10262
|
+
if (log !== null) {
|
|
10263
|
+
if (log.rawHeaders === void 0 || Object.keys(log.rawHeaders).length === 0) {
|
|
10264
|
+
findings.push(`Log ${String(log.id)} has no rawHeaders stored.`);
|
|
10265
|
+
}
|
|
10266
|
+
if (log.headers === void 0 || Object.keys(log.headers).length === 0) {
|
|
10267
|
+
findings.push(`Log ${String(log.id)} has no upstream headers stored.`);
|
|
10268
|
+
}
|
|
10269
|
+
if (log.rawRequestBody === null) {
|
|
10270
|
+
findings.push(`Log ${String(log.id)} does not include rawRequestBody in this response.`);
|
|
10271
|
+
}
|
|
10272
|
+
if (log.bodyContentMode === "compact") {
|
|
10273
|
+
findings.push(`Log ${String(log.id)} is in compact body mode.`);
|
|
10274
|
+
recommendations.push(
|
|
10275
|
+
"Use inspector_get_log_headers for header-only checks and enable full capture for future body inspection."
|
|
10276
|
+
);
|
|
10277
|
+
}
|
|
10278
|
+
}
|
|
10279
|
+
return textJson({
|
|
10280
|
+
captureMode,
|
|
10281
|
+
logId: log?.id ?? null,
|
|
10282
|
+
hasLog: log !== null,
|
|
10283
|
+
findings,
|
|
10284
|
+
recommendations,
|
|
10285
|
+
runtime: runtimeRecord
|
|
10286
|
+
});
|
|
10287
|
+
}
|
|
10288
|
+
async function addGroupProcessImpl(callApi2, args) {
|
|
10289
|
+
const params = new URLSearchParams({
|
|
10290
|
+
clientPid: String(args.clientPid),
|
|
10291
|
+
offset: "0",
|
|
10292
|
+
limit: String(PROCESS_LOG_LIMIT_MAX),
|
|
10293
|
+
compact: "1"
|
|
10294
|
+
});
|
|
10295
|
+
const result = await readCompactLogsPage(callApi2, params);
|
|
10296
|
+
if (isToolResult(result)) return result;
|
|
10297
|
+
const bySession = /* @__PURE__ */ new Map();
|
|
10298
|
+
for (const log of result.logs) {
|
|
10299
|
+
if (log.sessionId === null || log.sessionId === "") continue;
|
|
10300
|
+
const existing = bySession.get(log.sessionId) ?? [];
|
|
10301
|
+
existing.push(log);
|
|
10302
|
+
bySession.set(log.sessionId, existing);
|
|
10303
|
+
}
|
|
10304
|
+
if (bySession.size === 0) {
|
|
10305
|
+
return toolError(`No sessions found for clientPid ${String(args.clientPid)}`);
|
|
10306
|
+
}
|
|
10307
|
+
let groupResult = null;
|
|
10308
|
+
const attached = [];
|
|
10309
|
+
for (const [sessionId, logs] of bySession.entries()) {
|
|
10310
|
+
const first = logs[0];
|
|
10311
|
+
const last = logs.at(-1);
|
|
10312
|
+
const userAgent = last?.userAgent ?? first?.userAgent ?? null;
|
|
10313
|
+
const agent = inferAgentFromUserAgent(userAgent);
|
|
10314
|
+
groupResult = addInspectorGroupSession(args.groupId, {
|
|
10315
|
+
sessionId,
|
|
10316
|
+
label: `${args.labelPrefix ?? `PID ${String(args.clientPid)}`} - ${sessionId}`,
|
|
10317
|
+
agent,
|
|
10318
|
+
provider: last?.providerName ?? first?.providerName ?? null,
|
|
10319
|
+
model: last?.model ?? first?.model ?? null,
|
|
10320
|
+
metadata: {
|
|
10321
|
+
clientPid: args.clientPid,
|
|
10322
|
+
processLogCount: logs.length,
|
|
10323
|
+
userAgent: userAgent ?? ""
|
|
10324
|
+
}
|
|
10325
|
+
});
|
|
10326
|
+
if (!groupResult.ok) return toolError(groupResult.message);
|
|
10327
|
+
attached.push({ sessionId, logCount: logs.length, agent, userAgent });
|
|
10328
|
+
}
|
|
10329
|
+
if (groupResult === null || !groupResult.ok) return toolError("Group process attach failed");
|
|
10330
|
+
return textJson({
|
|
10331
|
+
group: groupResult.value,
|
|
10332
|
+
clientPid: args.clientPid,
|
|
10333
|
+
attached
|
|
10334
|
+
});
|
|
10335
|
+
}
|
|
9955
10336
|
function fileBytes(path2) {
|
|
9956
10337
|
if (!existsSync(path2)) return null;
|
|
9957
10338
|
try {
|
|
@@ -10224,7 +10605,7 @@ function providerDiagnosticHints(result) {
|
|
|
10224
10605
|
}
|
|
10225
10606
|
if (text.includes("nonstream") || text.includes("non-stream")) {
|
|
10226
10607
|
hints.push(
|
|
10227
|
-
"The failure mentions non-streaming. Compare the
|
|
10608
|
+
"The failure mentions non-streaming. Compare the Anthropic, OpenAI Chat, and OpenAI Responses non-streaming path and payload with the streaming request."
|
|
10228
10609
|
);
|
|
10229
10610
|
}
|
|
10230
10611
|
return [...new Set(hints)];
|
|
@@ -10398,6 +10779,9 @@ const UpdateProviderInputSchema = object({
|
|
|
10398
10779
|
const LogResourceListResponseSchema = object({
|
|
10399
10780
|
logs: array(object({ id: number().int().positive() }))
|
|
10400
10781
|
});
|
|
10782
|
+
const ProcessResourceListResponseSchema = object({
|
|
10783
|
+
logs: array(object({ clientPid: number().int().positive().nullable().optional() }))
|
|
10784
|
+
});
|
|
10401
10785
|
function textResource(uri, mimeType, text) {
|
|
10402
10786
|
return {
|
|
10403
10787
|
contents: [{ uri: uri.href, mimeType, text }]
|
|
@@ -10438,6 +10822,7 @@ const WRITE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
10438
10822
|
"inspector_update_group",
|
|
10439
10823
|
"inspector_delete_group",
|
|
10440
10824
|
"inspector_add_group_session",
|
|
10825
|
+
"inspector_add_group_process",
|
|
10441
10826
|
"inspector_export_group_evidence",
|
|
10442
10827
|
"inspector_export_group_evidence_bundle",
|
|
10443
10828
|
"inspector_set_current_context",
|
|
@@ -10616,6 +11001,40 @@ async function listLogResources() {
|
|
|
10616
11001
|
return listResult([]);
|
|
10617
11002
|
}
|
|
10618
11003
|
}
|
|
11004
|
+
async function listProcessResources() {
|
|
11005
|
+
try {
|
|
11006
|
+
const response = await callApi("/api/logs?q=&offset=0&limit=50&scanLimit=200");
|
|
11007
|
+
if (!response.ok) return listResult([]);
|
|
11008
|
+
const parsed = ProcessResourceListResponseSchema.safeParse(await response.json());
|
|
11009
|
+
if (!parsed.success) return listResult([]);
|
|
11010
|
+
const pids = [
|
|
11011
|
+
...new Set(
|
|
11012
|
+
parsed.data.logs.map((log) => log.clientPid ?? null).filter((pid) => pid !== null)
|
|
11013
|
+
)
|
|
11014
|
+
].sort((left, right) => left - right);
|
|
11015
|
+
return listResult(
|
|
11016
|
+
pids.map((pid) => ({
|
|
11017
|
+
uri: `inspector://processes/${String(pid)}`,
|
|
11018
|
+
name: `process:${String(pid)}`,
|
|
11019
|
+
title: `Inspector process ${String(pid)}`,
|
|
11020
|
+
mimeType: "application/json"
|
|
11021
|
+
}))
|
|
11022
|
+
);
|
|
11023
|
+
} catch {
|
|
11024
|
+
return listResult([]);
|
|
11025
|
+
}
|
|
11026
|
+
}
|
|
11027
|
+
async function listProcessTimelineResources() {
|
|
11028
|
+
const processResources = await listProcessResources();
|
|
11029
|
+
return listResult(
|
|
11030
|
+
processResources.resources.map((resource) => ({
|
|
11031
|
+
uri: `${resource.uri}/timeline`,
|
|
11032
|
+
name: `${resource.name}:timeline`,
|
|
11033
|
+
title: `${resource.title ?? resource.name} timeline`,
|
|
11034
|
+
mimeType: "application/json"
|
|
11035
|
+
}))
|
|
11036
|
+
);
|
|
11037
|
+
}
|
|
10619
11038
|
function listRunResources() {
|
|
10620
11039
|
return listResult(
|
|
10621
11040
|
listInspectorRuns().runs.map((run) => ({
|
|
@@ -10713,7 +11132,8 @@ function registerTools(server) {
|
|
|
10713
11132
|
offset: number().int().nonnegative().optional().describe("Skip this many entries."),
|
|
10714
11133
|
limit: number().int().positive().optional().describe("How many summaries to return. Hard-capped at 5."),
|
|
10715
11134
|
sessionId: string().optional().describe("Filter by session/affinity id."),
|
|
10716
|
-
model: string().optional().describe("Filter by model name.")
|
|
11135
|
+
model: string().optional().describe("Filter by model name."),
|
|
11136
|
+
clientPid: number().int().positive().optional().describe("Filter by originating client process PID.")
|
|
10717
11137
|
})
|
|
10718
11138
|
},
|
|
10719
11139
|
(args) => safeCall(() => listLogsImpl(callApi, args))
|
|
@@ -10729,7 +11149,8 @@ function registerTools(server) {
|
|
|
10729
11149
|
limit: number().int().positive().optional().describe("How many summaries to return. Hard-capped at 5 by the MCP handler."),
|
|
10730
11150
|
scanLimit: number().int().positive().max(1e3).optional().describe("How many recent compact logs to scan before filtering. Default 200."),
|
|
10731
11151
|
sessionId: string().optional().describe("Optional session/affinity id filter."),
|
|
10732
|
-
model: string().optional().describe("Optional model name filter.")
|
|
11152
|
+
model: string().optional().describe("Optional model name filter."),
|
|
11153
|
+
clientPid: number().int().positive().optional().describe("Optional originating client process PID filter.")
|
|
10733
11154
|
})
|
|
10734
11155
|
},
|
|
10735
11156
|
(args) => safeCall(() => searchLogsImpl(callApi, args))
|
|
@@ -10756,6 +11177,55 @@ function registerTools(server) {
|
|
|
10756
11177
|
},
|
|
10757
11178
|
({ id }) => safeCall(() => getLogChunksImpl(callApi, id))
|
|
10758
11179
|
);
|
|
11180
|
+
server.registerTool(
|
|
11181
|
+
"inspector_get_log_headers",
|
|
11182
|
+
{
|
|
11183
|
+
title: "Get captured log headers",
|
|
11184
|
+
description: "Returns header-focused evidence for one log without large request/response bodies: raw headers, upstream headers, user-agent, origin, client PID/port, session id, model, and API path.",
|
|
11185
|
+
inputSchema: object({
|
|
11186
|
+
id: number().int().positive().describe("The log id.")
|
|
11187
|
+
})
|
|
11188
|
+
},
|
|
11189
|
+
({ id }) => safeCall(() => getLogHeadersImpl(callApi, id))
|
|
11190
|
+
);
|
|
11191
|
+
server.registerTool(
|
|
11192
|
+
"inspector_list_processes",
|
|
11193
|
+
{
|
|
11194
|
+
title: "List observed client processes",
|
|
11195
|
+
description: "Groups recent compact logs by originating client PID and returns sessions, agents, user-agents, models, providers, ports, error counts, and latest logs. Useful for IDE -> process -> session navigation.",
|
|
11196
|
+
inputSchema: object({
|
|
11197
|
+
scanLimit: number().int().positive().max(200).optional().describe("How many recent logs to scan. Default 50, max 200."),
|
|
11198
|
+
limit: number().int().positive().max(200).optional().describe("Alias for scanLimit for simpler MCP clients.")
|
|
11199
|
+
})
|
|
11200
|
+
},
|
|
11201
|
+
(args) => safeCall(() => listProcessesImpl(callApi, args))
|
|
11202
|
+
);
|
|
11203
|
+
server.registerTool(
|
|
11204
|
+
"inspector_get_process",
|
|
11205
|
+
{
|
|
11206
|
+
title: "Get process summary",
|
|
11207
|
+
description: "Returns a bounded summary for one originating client PID across sessions, including user-agents, ports, models, providers, errors, and latest compact logs.",
|
|
11208
|
+
inputSchema: object({
|
|
11209
|
+
clientPid: number().int().positive().describe("Originating client process PID."),
|
|
11210
|
+
offset: number().int().nonnegative().optional().describe("Skip this many matching logs."),
|
|
11211
|
+
limit: number().int().positive().max(200).optional().describe("Maximum logs to summarize. Default 50, max 200.")
|
|
11212
|
+
})
|
|
11213
|
+
},
|
|
11214
|
+
(args) => safeCall(() => getProcessImpl(callApi, args))
|
|
11215
|
+
);
|
|
11216
|
+
server.registerTool(
|
|
11217
|
+
"inspector_get_process_timeline",
|
|
11218
|
+
{
|
|
11219
|
+
title: "Get process timeline",
|
|
11220
|
+
description: "Returns a bounded chronological timeline for one originating client PID, spanning all sessions observed for that process.",
|
|
11221
|
+
inputSchema: object({
|
|
11222
|
+
clientPid: number().int().positive().describe("Originating client process PID."),
|
|
11223
|
+
offset: number().int().nonnegative().optional().describe("Skip this many matching logs."),
|
|
11224
|
+
limit: number().int().positive().max(50).optional().describe("Maximum timeline events to return. Default 20, max 50.")
|
|
11225
|
+
})
|
|
11226
|
+
},
|
|
11227
|
+
(args) => safeCall(() => getProcessTimelineImpl(callApi, args))
|
|
11228
|
+
);
|
|
10759
11229
|
server.registerTool(
|
|
10760
11230
|
"inspector_list_sessions",
|
|
10761
11231
|
{
|
|
@@ -10819,6 +11289,26 @@ function registerTools(server) {
|
|
|
10819
11289
|
},
|
|
10820
11290
|
(args) => safeWriteCall("inspector_set_current_context", () => setCurrentContextImpl(args))
|
|
10821
11291
|
);
|
|
11292
|
+
server.registerTool(
|
|
11293
|
+
"inspector_get_runtime_config",
|
|
11294
|
+
{
|
|
11295
|
+
title: "Get Inspector runtime config",
|
|
11296
|
+
description: "Read-only runtime diagnostics: current proxy config plus log storage stats, including captureMode and log/chunk directories. Does not expose provider secrets.",
|
|
11297
|
+
inputSchema: object({})
|
|
11298
|
+
},
|
|
11299
|
+
() => safeCall(() => getRuntimeConfigImpl(callApi))
|
|
11300
|
+
);
|
|
11301
|
+
server.registerTool(
|
|
11302
|
+
"inspector_diagnose_capture",
|
|
11303
|
+
{
|
|
11304
|
+
title: "Diagnose capture detail availability",
|
|
11305
|
+
description: "Explains why headers or bodies may be missing for the current runtime or a specific log, including captureMode, compact body mode, rawHeaders presence, and next-step recommendations.",
|
|
11306
|
+
inputSchema: object({
|
|
11307
|
+
id: number().int().positive().optional().describe("Optional log id to inspect.")
|
|
11308
|
+
})
|
|
11309
|
+
},
|
|
11310
|
+
(args) => safeCall(() => diagnoseCaptureImpl(callApi, args))
|
|
11311
|
+
);
|
|
10822
11312
|
server.registerTool(
|
|
10823
11313
|
"inspector_create_run",
|
|
10824
11314
|
{
|
|
@@ -10980,6 +11470,19 @@ function registerTools(server) {
|
|
|
10980
11470
|
},
|
|
10981
11471
|
(args) => safeWriteCall("inspector_add_group_session", () => addGroupSessionImpl(args))
|
|
10982
11472
|
);
|
|
11473
|
+
server.registerTool(
|
|
11474
|
+
"inspector_add_group_process",
|
|
11475
|
+
{
|
|
11476
|
+
title: "Attach a process to an Inspector group",
|
|
11477
|
+
description: "Finds sessions observed for one client PID and attaches each session to a group with inferred agent/model/provider metadata. Useful when a process has both process fallback and explicit sessions.",
|
|
11478
|
+
inputSchema: object({
|
|
11479
|
+
groupId: string().min(1).describe("The Inspector group id."),
|
|
11480
|
+
clientPid: number().int().positive().describe("Originating client process PID."),
|
|
11481
|
+
labelPrefix: string().min(1).optional().describe("Optional label prefix. Defaults to PID <clientPid>.")
|
|
11482
|
+
})
|
|
11483
|
+
},
|
|
11484
|
+
(args) => safeWriteCall("inspector_add_group_process", () => addGroupProcessImpl(callApi, args))
|
|
11485
|
+
);
|
|
10983
11486
|
server.registerTool(
|
|
10984
11487
|
"inspector_export_group_evidence",
|
|
10985
11488
|
{
|
|
@@ -11208,6 +11711,21 @@ function registerResources(server) {
|
|
|
11208
11711
|
},
|
|
11209
11712
|
(uri) => jsonResource(uri, getCurrentContext())
|
|
11210
11713
|
);
|
|
11714
|
+
server.registerResource(
|
|
11715
|
+
"inspector_runtime_config",
|
|
11716
|
+
"inspector://runtime/config",
|
|
11717
|
+
{
|
|
11718
|
+
title: "Inspector runtime config",
|
|
11719
|
+
description: "Read-only runtime config and log storage stats.",
|
|
11720
|
+
mimeType: "application/json"
|
|
11721
|
+
},
|
|
11722
|
+
async (uri) => {
|
|
11723
|
+
const result = await getRuntimeConfigImpl(callApi);
|
|
11724
|
+
const first = result.content[0];
|
|
11725
|
+
const text = first?.text ?? "";
|
|
11726
|
+
return textResource(uri, result.isError === true ? "text/plain" : "application/json", text);
|
|
11727
|
+
}
|
|
11728
|
+
);
|
|
11211
11729
|
server.registerResource(
|
|
11212
11730
|
"inspector_sessions",
|
|
11213
11731
|
"inspector://sessions",
|
|
@@ -11272,6 +11790,63 @@ function registerResources(server) {
|
|
|
11272
11790
|
return textResource(uri, result.isError === true ? "text/plain" : "application/json", text);
|
|
11273
11791
|
}
|
|
11274
11792
|
);
|
|
11793
|
+
server.registerResource(
|
|
11794
|
+
"inspector_processes",
|
|
11795
|
+
"inspector://processes",
|
|
11796
|
+
{
|
|
11797
|
+
title: "Inspector client processes",
|
|
11798
|
+
description: "Observed originating client process PIDs grouped from recent logs.",
|
|
11799
|
+
mimeType: "application/json"
|
|
11800
|
+
},
|
|
11801
|
+
async (uri) => {
|
|
11802
|
+
const result = await listProcessesImpl(callApi, { scanLimit: 200 });
|
|
11803
|
+
const first = result.content[0];
|
|
11804
|
+
const text = first?.text ?? "";
|
|
11805
|
+
return textResource(uri, result.isError === true ? "text/plain" : "application/json", text);
|
|
11806
|
+
}
|
|
11807
|
+
);
|
|
11808
|
+
server.registerResource(
|
|
11809
|
+
"inspector_process",
|
|
11810
|
+
new ResourceTemplate("inspector://processes/{clientPid}", { list: listProcessResources }),
|
|
11811
|
+
{
|
|
11812
|
+
title: "Inspector process",
|
|
11813
|
+
description: "One originating client process summary with sessions, agents, user-agents, ports, models, providers, errors, and latest logs.",
|
|
11814
|
+
mimeType: "application/json"
|
|
11815
|
+
},
|
|
11816
|
+
async (uri, variables) => {
|
|
11817
|
+
const clientPid = variableString(variables, "clientPid");
|
|
11818
|
+
const parsed = clientPid === null ? Number.NaN : Number(clientPid);
|
|
11819
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
11820
|
+
return textResource(uri, "text/plain", "Invalid clientPid");
|
|
11821
|
+
}
|
|
11822
|
+
const result = await getProcessImpl(callApi, { clientPid: parsed });
|
|
11823
|
+
const first = result.content[0];
|
|
11824
|
+
const text = first?.text ?? "";
|
|
11825
|
+
return textResource(uri, result.isError === true ? "text/plain" : "application/json", text);
|
|
11826
|
+
}
|
|
11827
|
+
);
|
|
11828
|
+
server.registerResource(
|
|
11829
|
+
"inspector_process_timeline",
|
|
11830
|
+
new ResourceTemplate("inspector://processes/{clientPid}/timeline", {
|
|
11831
|
+
list: listProcessTimelineResources
|
|
11832
|
+
}),
|
|
11833
|
+
{
|
|
11834
|
+
title: "Inspector process timeline",
|
|
11835
|
+
description: "Bounded chronological timeline for one originating client process PID.",
|
|
11836
|
+
mimeType: "application/json"
|
|
11837
|
+
},
|
|
11838
|
+
async (uri, variables) => {
|
|
11839
|
+
const clientPid = variableString(variables, "clientPid");
|
|
11840
|
+
const parsed = clientPid === null ? Number.NaN : Number(clientPid);
|
|
11841
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
11842
|
+
return textResource(uri, "text/plain", "Invalid clientPid");
|
|
11843
|
+
}
|
|
11844
|
+
const result = await getProcessTimelineImpl(callApi, { clientPid: parsed, limit: 50 });
|
|
11845
|
+
const first = result.content[0];
|
|
11846
|
+
const text = first?.text ?? "";
|
|
11847
|
+
return textResource(uri, result.isError === true ? "text/plain" : "application/json", text);
|
|
11848
|
+
}
|
|
11849
|
+
);
|
|
11275
11850
|
server.registerResource(
|
|
11276
11851
|
"inspector_runs",
|
|
11277
11852
|
"inspector://runs",
|
|
@@ -11544,11 +12119,17 @@ const TOOL_NAMES = [
|
|
|
11544
12119
|
"inspector_search_logs",
|
|
11545
12120
|
"inspector_get_log",
|
|
11546
12121
|
"inspector_get_log_chunks",
|
|
12122
|
+
"inspector_get_log_headers",
|
|
12123
|
+
"inspector_list_processes",
|
|
12124
|
+
"inspector_get_process",
|
|
12125
|
+
"inspector_get_process_timeline",
|
|
11547
12126
|
"inspector_list_sessions",
|
|
11548
12127
|
"inspector_get_session",
|
|
11549
12128
|
"inspector_get_session_timeline",
|
|
11550
12129
|
"inspector_get_current_context",
|
|
11551
12130
|
"inspector_set_current_context",
|
|
12131
|
+
"inspector_get_runtime_config",
|
|
12132
|
+
"inspector_diagnose_capture",
|
|
11552
12133
|
"inspector_create_run",
|
|
11553
12134
|
"inspector_get_run",
|
|
11554
12135
|
"inspector_update_run",
|
|
@@ -11562,6 +12143,7 @@ const TOOL_NAMES = [
|
|
|
11562
12143
|
"inspector_update_group",
|
|
11563
12144
|
"inspector_delete_group",
|
|
11564
12145
|
"inspector_add_group_session",
|
|
12146
|
+
"inspector_add_group_process",
|
|
11565
12147
|
"inspector_export_group_evidence",
|
|
11566
12148
|
"inspector_get_group_evidence_files",
|
|
11567
12149
|
"inspector_export_group_evidence_bundle",
|
|
@@ -11584,10 +12166,14 @@ const RESOURCE_NAMES = [
|
|
|
11584
12166
|
"inspector_mcp_capabilities",
|
|
11585
12167
|
"inspector_mcp_config",
|
|
11586
12168
|
"inspector_current_context",
|
|
12169
|
+
"inspector_runtime_config",
|
|
11587
12170
|
"inspector_sessions",
|
|
11588
12171
|
"inspector_session",
|
|
11589
12172
|
"inspector_session_timeline",
|
|
11590
12173
|
"inspector_log",
|
|
12174
|
+
"inspector_processes",
|
|
12175
|
+
"inspector_process",
|
|
12176
|
+
"inspector_process_timeline",
|
|
11591
12177
|
"inspector_runs",
|
|
11592
12178
|
"inspector_recent_failures",
|
|
11593
12179
|
"inspector_run",
|
|
@@ -11679,6 +12265,7 @@ async function searchLogsPage(options) {
|
|
|
11679
12265
|
const firstPage = await listLogsPage({
|
|
11680
12266
|
sessionId: options.sessionId,
|
|
11681
12267
|
model: options.model,
|
|
12268
|
+
clientPid: options.clientPid,
|
|
11682
12269
|
offset: 0,
|
|
11683
12270
|
limit: 1,
|
|
11684
12271
|
includeBodies: false
|
|
@@ -11687,6 +12274,7 @@ async function searchLogsPage(options) {
|
|
|
11687
12274
|
const scanPage = await listLogsPage({
|
|
11688
12275
|
sessionId: options.sessionId,
|
|
11689
12276
|
model: options.model,
|
|
12277
|
+
clientPid: options.clientPid,
|
|
11690
12278
|
offset: scanOffset,
|
|
11691
12279
|
limit: scanLimit,
|
|
11692
12280
|
includeBodies: false
|
|
@@ -11742,6 +12330,11 @@ const Route$u = createFileRoute("/api/logs")({
|
|
|
11742
12330
|
}
|
|
11743
12331
|
const sessionId = url.searchParams.get("sessionId") ?? void 0;
|
|
11744
12332
|
const model = url.searchParams.get("model") ?? void 0;
|
|
12333
|
+
const clientPidResult = parseOptionalPositiveInt(url.searchParams.get("clientPid"));
|
|
12334
|
+
if (!clientPidResult.ok) {
|
|
12335
|
+
return Response.json({ error: "Invalid clientPid" }, { status: 400 });
|
|
12336
|
+
}
|
|
12337
|
+
const clientPid = clientPidResult.value ?? void 0;
|
|
11745
12338
|
const query = url.searchParams.get("q") ?? url.searchParams.get("search");
|
|
11746
12339
|
const offset = parseNonNegativeInt(url.searchParams.get("offset"), 0);
|
|
11747
12340
|
if (query !== null) {
|
|
@@ -11751,7 +12344,7 @@ const Route$u = createFileRoute("/api/logs")({
|
|
|
11751
12344
|
LOG_SEARCH_DEFAULT_SCAN_LIMIT
|
|
11752
12345
|
);
|
|
11753
12346
|
return Response.json(
|
|
11754
|
-
await searchLogsPage({ query, sessionId, model, offset, limit: limit2, scanLimit })
|
|
12347
|
+
await searchLogsPage({ query, sessionId, model, clientPid, offset, limit: limit2, scanLimit })
|
|
11755
12348
|
);
|
|
11756
12349
|
}
|
|
11757
12350
|
const limit = parsePositiveInt$2(url.searchParams.get("limit"), 50);
|
|
@@ -11773,6 +12366,7 @@ const Route$u = createFileRoute("/api/logs")({
|
|
|
11773
12366
|
await listLogsCursorPage({
|
|
11774
12367
|
sessionId,
|
|
11775
12368
|
model,
|
|
12369
|
+
clientPid,
|
|
11776
12370
|
limit,
|
|
11777
12371
|
includeBodies,
|
|
11778
12372
|
beforeLogId: beforeLogId.value ?? void 0,
|
|
@@ -11782,7 +12376,7 @@ const Route$u = createFileRoute("/api/logs")({
|
|
|
11782
12376
|
);
|
|
11783
12377
|
}
|
|
11784
12378
|
return Response.json(
|
|
11785
|
-
await listLogsPage({ sessionId, model, offset, limit, includeBodies })
|
|
12379
|
+
await listLogsPage({ sessionId, model, clientPid, offset, limit, includeBodies })
|
|
11786
12380
|
);
|
|
11787
12381
|
},
|
|
11788
12382
|
DELETE: async ({ request }) => {
|
|
@@ -13229,7 +13823,7 @@ function parseJsonlLogs(text) {
|
|
|
13229
13823
|
}
|
|
13230
13824
|
return { logs, skipped };
|
|
13231
13825
|
}
|
|
13232
|
-
function readStringProperty(value, name) {
|
|
13826
|
+
function readStringProperty$1(value, name) {
|
|
13233
13827
|
const property = readRecordProperty(value, name);
|
|
13234
13828
|
return typeof property === "string" ? property : null;
|
|
13235
13829
|
}
|
|
@@ -13238,7 +13832,7 @@ function hasProperty(value, name) {
|
|
|
13238
13832
|
return Object.getOwnPropertyDescriptor(value, name) !== void 0;
|
|
13239
13833
|
}
|
|
13240
13834
|
function modelFromRequestText(requestText) {
|
|
13241
|
-
return readStringProperty(parseJson(requestText), "model");
|
|
13835
|
+
return readStringProperty$1(parseJson(requestText), "model");
|
|
13242
13836
|
}
|
|
13243
13837
|
function inferApiFormatFromBody(path2, model, requestText) {
|
|
13244
13838
|
const pathFormat = apiFormatForPath(path2);
|
|
@@ -14424,7 +15018,15 @@ function buildProviderTestUserPrompt(mode) {
|
|
|
14424
15018
|
function buildProviderTestMessages(mode) {
|
|
14425
15019
|
return [{ role: "user", content: buildProviderTestUserPrompt(mode) }];
|
|
14426
15020
|
}
|
|
14427
|
-
function buildProviderTestRequestBody(model, mode) {
|
|
15021
|
+
function buildProviderTestRequestBody(model, mode, apiShape = "chat") {
|
|
15022
|
+
if (apiShape === "responses") {
|
|
15023
|
+
return {
|
|
15024
|
+
model,
|
|
15025
|
+
input: buildProviderTestUserPrompt(mode),
|
|
15026
|
+
max_output_tokens: maxTokensForMode(mode),
|
|
15027
|
+
stream: mode === "streaming"
|
|
15028
|
+
};
|
|
15029
|
+
}
|
|
14428
15030
|
const base = {
|
|
14429
15031
|
model,
|
|
14430
15032
|
messages: buildProviderTestMessages(mode),
|
|
@@ -14671,6 +15273,50 @@ const OpenAIResponseSchema = object({
|
|
|
14671
15273
|
})
|
|
14672
15274
|
)
|
|
14673
15275
|
});
|
|
15276
|
+
function isOpenAIProtocol(protocol) {
|
|
15277
|
+
return protocol === "openaiChat" || protocol === "openaiResponses";
|
|
15278
|
+
}
|
|
15279
|
+
function providerTestApiShape(protocol) {
|
|
15280
|
+
switch (protocol) {
|
|
15281
|
+
case "anthropic":
|
|
15282
|
+
case "openaiChat":
|
|
15283
|
+
return "chat";
|
|
15284
|
+
case "openaiResponses":
|
|
15285
|
+
return "responses";
|
|
15286
|
+
}
|
|
15287
|
+
}
|
|
15288
|
+
function buildProviderTestBodyText(model, mode, protocol) {
|
|
15289
|
+
return JSON.stringify(buildProviderTestRequestBody(model, mode, providerTestApiShape(protocol)));
|
|
15290
|
+
}
|
|
15291
|
+
function readProperty(value, key) {
|
|
15292
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
15293
|
+
return Object.getOwnPropertyDescriptor(value, key)?.value;
|
|
15294
|
+
}
|
|
15295
|
+
function readStringProperty(value, key) {
|
|
15296
|
+
const property = readProperty(value, key);
|
|
15297
|
+
return typeof property === "string" ? property : null;
|
|
15298
|
+
}
|
|
15299
|
+
function readArrayProperty(value, key) {
|
|
15300
|
+
const property = readProperty(value, key);
|
|
15301
|
+
return Array.isArray(property) ? property : [];
|
|
15302
|
+
}
|
|
15303
|
+
function responseTextFromOpenAIResponses(response) {
|
|
15304
|
+
if (response.output_text !== void 0 && response.output_text.length > 0) {
|
|
15305
|
+
return response.output_text;
|
|
15306
|
+
}
|
|
15307
|
+
const parts = [];
|
|
15308
|
+
for (const outputItem of response.output ?? []) {
|
|
15309
|
+
const content = readArrayProperty(outputItem, "content");
|
|
15310
|
+
for (const contentPart of content) {
|
|
15311
|
+
const type = readStringProperty(contentPart, "type");
|
|
15312
|
+
const text = readStringProperty(contentPart, "text");
|
|
15313
|
+
if ((type === "output_text" || type === "text") && text !== null && text.length > 0) {
|
|
15314
|
+
parts.push(text);
|
|
15315
|
+
}
|
|
15316
|
+
}
|
|
15317
|
+
}
|
|
15318
|
+
return parts.length > 0 ? parts.join("\n") : null;
|
|
15319
|
+
}
|
|
14674
15320
|
function getProviderTestTimeoutMs() {
|
|
14675
15321
|
return getConfig().providerTestTimeoutSeconds * 1e3;
|
|
14676
15322
|
}
|
|
@@ -14684,9 +15330,9 @@ function buildTestRequestHeaders(provider) {
|
|
|
14684
15330
|
});
|
|
14685
15331
|
return result;
|
|
14686
15332
|
}
|
|
14687
|
-
async function testEndpoint(baseUrl, provider, path2, model,
|
|
15333
|
+
async function testEndpoint(baseUrl, provider, path2, model, protocol) {
|
|
14688
15334
|
const startTime = Date.now();
|
|
14689
|
-
const body =
|
|
15335
|
+
const body = buildProviderTestBodyText(model, "non-streaming", protocol);
|
|
14690
15336
|
const requestHeaders = buildTestRequestHeaders(provider);
|
|
14691
15337
|
let requestUrl = baseUrl;
|
|
14692
15338
|
const controller = new AbortController();
|
|
@@ -14719,7 +15365,7 @@ async function testEndpoint(baseUrl, provider, path2, model, isOpenAI) {
|
|
|
14719
15365
|
const responseText = await response.text();
|
|
14720
15366
|
const safeRequestHeaders = redactHeaders(requestHeaders);
|
|
14721
15367
|
try {
|
|
14722
|
-
if (
|
|
15368
|
+
if (protocol === "openaiChat") {
|
|
14723
15369
|
const json = OpenAIResponseSchema.parse(JSON.parse(responseText));
|
|
14724
15370
|
const responseModel = json.model ?? model;
|
|
14725
15371
|
const inputTokens = json.usage?.prompt_tokens;
|
|
@@ -14735,7 +15381,25 @@ async function testEndpoint(baseUrl, provider, path2, model, isOpenAI) {
|
|
|
14735
15381
|
rawResponse: responseText,
|
|
14736
15382
|
requestHeaders: safeRequestHeaders
|
|
14737
15383
|
};
|
|
14738
|
-
}
|
|
15384
|
+
}
|
|
15385
|
+
if (protocol === "openaiResponses") {
|
|
15386
|
+
const json = OpenAIResponsesResponseSchema.parse(JSON.parse(responseText));
|
|
15387
|
+
const responseModel = json.model ?? model;
|
|
15388
|
+
const inputTokens = json.usage?.input_tokens ?? void 0;
|
|
15389
|
+
const outputTokens = json.usage?.output_tokens ?? void 0;
|
|
15390
|
+
const content = responseTextFromOpenAIResponses(json);
|
|
15391
|
+
return {
|
|
15392
|
+
success: true,
|
|
15393
|
+
model: responseModel,
|
|
15394
|
+
inputTokens,
|
|
15395
|
+
outputTokens,
|
|
15396
|
+
latencyMs,
|
|
15397
|
+
content: content !== null && content !== "" ? [{ type: "text", text: content }] : void 0,
|
|
15398
|
+
rawResponse: responseText,
|
|
15399
|
+
requestHeaders: safeRequestHeaders
|
|
15400
|
+
};
|
|
15401
|
+
}
|
|
15402
|
+
{
|
|
14739
15403
|
const json = AnthropicResponseSchema.parse(JSON.parse(responseText));
|
|
14740
15404
|
const responseModel = json.model ?? model;
|
|
14741
15405
|
const inputTokens = json.usage?.input_tokens;
|
|
@@ -14790,9 +15454,9 @@ async function testEndpoint(baseUrl, provider, path2, model, isOpenAI) {
|
|
|
14790
15454
|
clearTimeout(timeoutId);
|
|
14791
15455
|
}
|
|
14792
15456
|
}
|
|
14793
|
-
async function testStreamingEndpoint(baseUrl, provider, path2, model,
|
|
15457
|
+
async function testStreamingEndpoint(baseUrl, provider, path2, model, protocol) {
|
|
14794
15458
|
const startTime = Date.now();
|
|
14795
|
-
const body =
|
|
15459
|
+
const body = buildProviderTestBodyText(model, "streaming", protocol);
|
|
14796
15460
|
const requestHeaders = buildTestRequestHeaders(provider);
|
|
14797
15461
|
let requestUrl = baseUrl;
|
|
14798
15462
|
const controller = new AbortController();
|
|
@@ -14906,11 +15570,11 @@ async function testStreamingEndpoint(baseUrl, provider, path2, model, isOpenAI)
|
|
|
14906
15570
|
streaming: true,
|
|
14907
15571
|
userAgent: null,
|
|
14908
15572
|
origin: null,
|
|
14909
|
-
apiFormat: "anthropic",
|
|
15573
|
+
apiFormat: isOpenAIProtocol(protocol) ? "openai" : "anthropic",
|
|
14910
15574
|
isTest: true
|
|
14911
15575
|
};
|
|
14912
15576
|
let reconstructedJson;
|
|
14913
|
-
if (
|
|
15577
|
+
if (isOpenAIProtocol(protocol)) {
|
|
14914
15578
|
reconstructedJson = extractOpenAIStream(fullResponse, mockLog, model, true);
|
|
14915
15579
|
} else {
|
|
14916
15580
|
reconstructedJson = extractAnthropicStream(fullResponse, mockLog, model, true);
|
|
@@ -14923,7 +15587,7 @@ async function testStreamingEndpoint(baseUrl, provider, path2, model, isOpenAI)
|
|
|
14923
15587
|
let cacheCreationInputTokens;
|
|
14924
15588
|
let cacheReadInputTokens;
|
|
14925
15589
|
let responseModel;
|
|
14926
|
-
if (
|
|
15590
|
+
if (protocol === "openaiChat") {
|
|
14927
15591
|
const parsed = OpenAIResponseSchema.parse(JSON.parse(reconstructedJson));
|
|
14928
15592
|
responseModel = typeof parsed.model === "string" && parsed.model !== "" ? parsed.model : void 0;
|
|
14929
15593
|
inputTokens = parsed.usage?.prompt_tokens;
|
|
@@ -14932,6 +15596,15 @@ async function testStreamingEndpoint(baseUrl, provider, path2, model, isOpenAI)
|
|
|
14932
15596
|
if (textContent !== null && textContent !== "") {
|
|
14933
15597
|
content = [{ type: "text", text: textContent }];
|
|
14934
15598
|
}
|
|
15599
|
+
} else if (protocol === "openaiResponses") {
|
|
15600
|
+
const parsed = OpenAIResponsesResponseSchema.parse(JSON.parse(reconstructedJson));
|
|
15601
|
+
responseModel = typeof parsed.model === "string" && parsed.model !== "" ? parsed.model : void 0;
|
|
15602
|
+
inputTokens = parsed.usage?.input_tokens ?? void 0;
|
|
15603
|
+
outputTokens = parsed.usage?.output_tokens ?? void 0;
|
|
15604
|
+
const textContent = responseTextFromOpenAIResponses(parsed);
|
|
15605
|
+
if (textContent !== null && textContent !== "") {
|
|
15606
|
+
content = [{ type: "text", text: textContent }];
|
|
15607
|
+
}
|
|
14935
15608
|
} else {
|
|
14936
15609
|
const parsed = AnthropicResponseSchema.parse(JSON.parse(reconstructedJson));
|
|
14937
15610
|
responseModel = typeof parsed.model === "string" && parsed.model !== "" ? parsed.model : void 0;
|
|
@@ -15016,24 +15689,39 @@ const Route$a = createFileRoute("/api/providers/$providerId/test")({
|
|
|
15016
15689
|
const results = {
|
|
15017
15690
|
anthropic: { nonStreaming: { notConfigured: true }, streaming: { notConfigured: true } },
|
|
15018
15691
|
openai: { nonStreaming: { notConfigured: true }, streaming: { notConfigured: true } },
|
|
15692
|
+
openaiChat: {
|
|
15693
|
+
nonStreaming: { notConfigured: true },
|
|
15694
|
+
streaming: { notConfigured: true }
|
|
15695
|
+
},
|
|
15696
|
+
openaiResponses: {
|
|
15697
|
+
nonStreaming: { notConfigured: true },
|
|
15698
|
+
streaming: { notConfigured: true }
|
|
15699
|
+
},
|
|
15019
15700
|
models: {}
|
|
15020
15701
|
};
|
|
15021
15702
|
const anthropicUrl = provider.anthropicBaseUrl !== void 0 && provider.anthropicBaseUrl.length > 0 ? provider.anthropicBaseUrl : void 0;
|
|
15022
15703
|
const openaiUrl = provider.openaiBaseUrl !== void 0 && provider.openaiBaseUrl.length > 0 ? provider.openaiBaseUrl : void 0;
|
|
15704
|
+
const openaiResponsesUrl = provider.openaiResponsesBaseUrl !== void 0 && provider.openaiResponsesBaseUrl.length > 0 ? provider.openaiResponsesBaseUrl : void 0;
|
|
15023
15705
|
async function testOneModel(displayName) {
|
|
15024
15706
|
const usageModel = getModelUsageName(displayName, p.name);
|
|
15025
15707
|
const notConfigured = { notConfigured: true };
|
|
15708
|
+
const notConfiguredFormat = {
|
|
15709
|
+
nonStreaming: notConfigured,
|
|
15710
|
+
streaming: notConfigured
|
|
15711
|
+
};
|
|
15026
15712
|
const modelResults = {
|
|
15027
15713
|
anthropic: { nonStreaming: notConfigured, streaming: notConfigured },
|
|
15028
|
-
openai:
|
|
15714
|
+
openai: notConfiguredFormat,
|
|
15715
|
+
openaiChat: { nonStreaming: notConfigured, streaming: notConfigured },
|
|
15716
|
+
openaiResponses: { nonStreaming: notConfigured, streaming: notConfigured }
|
|
15029
15717
|
};
|
|
15030
15718
|
const tasks = [];
|
|
15031
15719
|
if (anthropicUrl !== void 0) {
|
|
15032
15720
|
tasks.push(
|
|
15033
|
-
testEndpoint(anthropicUrl, p, "/v1/messages", usageModel,
|
|
15721
|
+
testEndpoint(anthropicUrl, p, "/v1/messages", usageModel, "anthropic").then((r) => {
|
|
15034
15722
|
modelResults.anthropic.nonStreaming = r;
|
|
15035
15723
|
}),
|
|
15036
|
-
testStreamingEndpoint(anthropicUrl, p, "/v1/messages", usageModel,
|
|
15724
|
+
testStreamingEndpoint(anthropicUrl, p, "/v1/messages", usageModel, "anthropic").then(
|
|
15037
15725
|
(r) => {
|
|
15038
15726
|
modelResults.anthropic.streaming = r;
|
|
15039
15727
|
}
|
|
@@ -15042,14 +15730,44 @@ const Route$a = createFileRoute("/api/providers/$providerId/test")({
|
|
|
15042
15730
|
}
|
|
15043
15731
|
if (openaiUrl !== void 0) {
|
|
15044
15732
|
tasks.push(
|
|
15045
|
-
testEndpoint(openaiUrl, p, "/v1/chat/completions", usageModel,
|
|
15046
|
-
modelResults.openai.nonStreaming = r;
|
|
15047
|
-
}),
|
|
15048
|
-
testStreamingEndpoint(openaiUrl, p, "/v1/chat/completions", usageModel, true).then(
|
|
15733
|
+
testEndpoint(openaiUrl, p, "/v1/chat/completions", usageModel, "openaiChat").then(
|
|
15049
15734
|
(r) => {
|
|
15050
|
-
modelResults.openai.
|
|
15735
|
+
modelResults.openai.nonStreaming = r;
|
|
15736
|
+
modelResults.openaiChat.nonStreaming = r;
|
|
15051
15737
|
}
|
|
15052
|
-
)
|
|
15738
|
+
),
|
|
15739
|
+
testStreamingEndpoint(
|
|
15740
|
+
openaiUrl,
|
|
15741
|
+
p,
|
|
15742
|
+
"/v1/chat/completions",
|
|
15743
|
+
usageModel,
|
|
15744
|
+
"openaiChat"
|
|
15745
|
+
).then((r) => {
|
|
15746
|
+
modelResults.openai.streaming = r;
|
|
15747
|
+
modelResults.openaiChat.streaming = r;
|
|
15748
|
+
})
|
|
15749
|
+
);
|
|
15750
|
+
}
|
|
15751
|
+
if (openaiResponsesUrl !== void 0) {
|
|
15752
|
+
tasks.push(
|
|
15753
|
+
testEndpoint(
|
|
15754
|
+
openaiResponsesUrl,
|
|
15755
|
+
p,
|
|
15756
|
+
"/v1/responses",
|
|
15757
|
+
usageModel,
|
|
15758
|
+
"openaiResponses"
|
|
15759
|
+
).then((r) => {
|
|
15760
|
+
modelResults.openaiResponses.nonStreaming = r;
|
|
15761
|
+
}),
|
|
15762
|
+
testStreamingEndpoint(
|
|
15763
|
+
openaiResponsesUrl,
|
|
15764
|
+
p,
|
|
15765
|
+
"/v1/responses",
|
|
15766
|
+
usageModel,
|
|
15767
|
+
"openaiResponses"
|
|
15768
|
+
).then((r) => {
|
|
15769
|
+
modelResults.openaiResponses.streaming = r;
|
|
15770
|
+
})
|
|
15053
15771
|
);
|
|
15054
15772
|
}
|
|
15055
15773
|
await Promise.all(tasks);
|
|
@@ -15061,6 +15779,8 @@ const Route$a = createFileRoute("/api/providers/$providerId/test")({
|
|
|
15061
15779
|
if (firstResults !== void 0) {
|
|
15062
15780
|
results.anthropic = firstResults.anthropic;
|
|
15063
15781
|
results.openai = firstResults.openai;
|
|
15782
|
+
results.openaiChat = firstResults.openaiChat;
|
|
15783
|
+
results.openaiResponses = firstResults.openaiResponses;
|
|
15064
15784
|
}
|
|
15065
15785
|
results.testedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
15066
15786
|
return Response.json(results);
|
|
@@ -15701,15 +16421,41 @@ const ProviderFormatTestResultsSchema = object({
|
|
|
15701
16421
|
nonStreaming: ProviderTestStateSchema,
|
|
15702
16422
|
streaming: ProviderTestStateSchema
|
|
15703
16423
|
});
|
|
16424
|
+
function createNotConfiguredProviderFormatTestResults() {
|
|
16425
|
+
return {
|
|
16426
|
+
nonStreaming: { notConfigured: true },
|
|
16427
|
+
streaming: { notConfigured: true }
|
|
16428
|
+
};
|
|
16429
|
+
}
|
|
15704
16430
|
const ModelTestResultsSchema = object({
|
|
15705
16431
|
anthropic: ProviderFormatTestResultsSchema,
|
|
15706
|
-
openai: ProviderFormatTestResultsSchema
|
|
16432
|
+
openai: ProviderFormatTestResultsSchema.optional(),
|
|
16433
|
+
openaiChat: ProviderFormatTestResultsSchema.optional(),
|
|
16434
|
+
openaiResponses: ProviderFormatTestResultsSchema.optional()
|
|
16435
|
+
}).transform((value) => {
|
|
16436
|
+
const openaiChat = value.openaiChat ?? value.openai ?? createNotConfiguredProviderFormatTestResults();
|
|
16437
|
+
return {
|
|
16438
|
+
...value,
|
|
16439
|
+
openai: value.openai ?? openaiChat,
|
|
16440
|
+
openaiChat,
|
|
16441
|
+
openaiResponses: value.openaiResponses ?? createNotConfiguredProviderFormatTestResults()
|
|
16442
|
+
};
|
|
15707
16443
|
});
|
|
15708
16444
|
const ProviderTestResultsSchema = object({
|
|
15709
16445
|
anthropic: ProviderFormatTestResultsSchema,
|
|
15710
|
-
openai: ProviderFormatTestResultsSchema,
|
|
16446
|
+
openai: ProviderFormatTestResultsSchema.optional(),
|
|
16447
|
+
openaiChat: ProviderFormatTestResultsSchema.optional(),
|
|
16448
|
+
openaiResponses: ProviderFormatTestResultsSchema.optional(),
|
|
15711
16449
|
models: record(string(), ModelTestResultsSchema).optional(),
|
|
15712
16450
|
testedAt: string().optional()
|
|
16451
|
+
}).transform((value) => {
|
|
16452
|
+
const openaiChat = value.openaiChat ?? value.openai ?? createNotConfiguredProviderFormatTestResults();
|
|
16453
|
+
return {
|
|
16454
|
+
...value,
|
|
16455
|
+
openai: value.openai ?? openaiChat,
|
|
16456
|
+
openaiChat,
|
|
16457
|
+
openaiResponses: value.openaiResponses ?? createNotConfiguredProviderFormatTestResults()
|
|
16458
|
+
};
|
|
15713
16459
|
});
|
|
15714
16460
|
function createPendingProviderTestResults() {
|
|
15715
16461
|
return {
|
|
@@ -15720,6 +16466,14 @@ function createPendingProviderTestResults() {
|
|
|
15720
16466
|
openai: {
|
|
15721
16467
|
nonStreaming: { testing: true },
|
|
15722
16468
|
streaming: { testing: true }
|
|
16469
|
+
},
|
|
16470
|
+
openaiChat: {
|
|
16471
|
+
nonStreaming: { testing: true },
|
|
16472
|
+
streaming: { testing: true }
|
|
16473
|
+
},
|
|
16474
|
+
openaiResponses: {
|
|
16475
|
+
nonStreaming: { testing: true },
|
|
16476
|
+
streaming: { testing: true }
|
|
15723
16477
|
}
|
|
15724
16478
|
};
|
|
15725
16479
|
}
|
|
@@ -15733,7 +16487,9 @@ function createFailedProviderTestResults(message, type) {
|
|
|
15733
16487
|
});
|
|
15734
16488
|
return {
|
|
15735
16489
|
anthropic: createFormatResult(),
|
|
15736
|
-
openai: createFormatResult()
|
|
16490
|
+
openai: createFormatResult(),
|
|
16491
|
+
openaiChat: createFormatResult(),
|
|
16492
|
+
openaiResponses: createFormatResult()
|
|
15737
16493
|
};
|
|
15738
16494
|
}
|
|
15739
16495
|
function hasSuccessField(result) {
|
|
@@ -15764,7 +16520,7 @@ function getResultTokensPerSecond(result) {
|
|
|
15764
16520
|
totalStreamMs: getResultTotalStreamMs(result)
|
|
15765
16521
|
});
|
|
15766
16522
|
}
|
|
15767
|
-
async function logModelResults(displayName, providerName, providerSessionId, anthropicUrl,
|
|
16523
|
+
async function logModelResults(displayName, providerName, providerSessionId, anthropicUrl, openaiChatUrl, openaiResponsesUrl, modelResults, captureFullDetails) {
|
|
15768
16524
|
const usageModel = getModelUsageName(displayName, providerName);
|
|
15769
16525
|
if (anthropicUrl !== void 0) {
|
|
15770
16526
|
const nsResult = modelResults.anthropic.nonStreaming;
|
|
@@ -15829,9 +16585,9 @@ async function logModelResults(displayName, providerName, providerSessionId, ant
|
|
|
15829
16585
|
});
|
|
15830
16586
|
}
|
|
15831
16587
|
}
|
|
15832
|
-
if (
|
|
15833
|
-
const nsResult = modelResults.
|
|
15834
|
-
const sResult = modelResults.
|
|
16588
|
+
if (openaiChatUrl !== void 0) {
|
|
16589
|
+
const nsResult = modelResults.openaiChat.nonStreaming;
|
|
16590
|
+
const sResult = modelResults.openaiChat.streaming;
|
|
15835
16591
|
if (hasSuccessField(nsResult) && hasSuccessField(sResult)) {
|
|
15836
16592
|
const nonStreamingResult = nsResult;
|
|
15837
16593
|
const streamingResult = sResult;
|
|
@@ -15892,6 +16648,71 @@ async function logModelResults(displayName, providerName, providerSessionId, ant
|
|
|
15892
16648
|
});
|
|
15893
16649
|
}
|
|
15894
16650
|
}
|
|
16651
|
+
if (openaiResponsesUrl !== void 0) {
|
|
16652
|
+
const nsResult = modelResults.openaiResponses.nonStreaming;
|
|
16653
|
+
const sResult = modelResults.openaiResponses.streaming;
|
|
16654
|
+
if (hasSuccessField(nsResult) && hasSuccessField(sResult)) {
|
|
16655
|
+
const nonStreamingResult = nsResult;
|
|
16656
|
+
const streamingResult = sResult;
|
|
16657
|
+
const requestBody = JSON.stringify(
|
|
16658
|
+
buildProviderTestRequestBody(usageModel, "non-streaming", "responses")
|
|
16659
|
+
);
|
|
16660
|
+
await addTestLogEntry({
|
|
16661
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
16662
|
+
method: "POST",
|
|
16663
|
+
path: "/v1/responses",
|
|
16664
|
+
model: nonStreamingResult.model ?? displayName,
|
|
16665
|
+
sessionId: providerSessionId,
|
|
16666
|
+
rawRequestBody: requestBody,
|
|
16667
|
+
responseStatus: getResultResponseStatus(nonStreamingResult),
|
|
16668
|
+
responseText: getResultResponseText(nonStreamingResult),
|
|
16669
|
+
inputTokens: nonStreamingResult.inputTokens ?? null,
|
|
16670
|
+
outputTokens: nonStreamingResult.outputTokens ?? null,
|
|
16671
|
+
cacheCreationInputTokens: null,
|
|
16672
|
+
cacheReadInputTokens: nonStreamingResult.cacheReadInputTokens ?? null,
|
|
16673
|
+
elapsedMs: nonStreamingResult.latencyMs ?? 0,
|
|
16674
|
+
firstChunkMs: null,
|
|
16675
|
+
totalStreamMs: null,
|
|
16676
|
+
tokensPerSecond: null,
|
|
16677
|
+
streaming: false,
|
|
16678
|
+
userAgent: "provider-test",
|
|
16679
|
+
origin: null,
|
|
16680
|
+
apiFormat: "openai",
|
|
16681
|
+
isTest: true,
|
|
16682
|
+
providerName,
|
|
16683
|
+
headers: captureFullDetails ? getResultHeaders(nonStreamingResult) : void 0
|
|
16684
|
+
});
|
|
16685
|
+
const streamingRequestBody = JSON.stringify(
|
|
16686
|
+
buildProviderTestRequestBody(usageModel, "streaming", "responses")
|
|
16687
|
+
);
|
|
16688
|
+
await addTestLogEntry({
|
|
16689
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
16690
|
+
method: "POST",
|
|
16691
|
+
path: "/v1/responses",
|
|
16692
|
+
model: streamingResult.model ?? displayName,
|
|
16693
|
+
sessionId: providerSessionId,
|
|
16694
|
+
rawRequestBody: streamingRequestBody,
|
|
16695
|
+
responseStatus: getResultResponseStatus(streamingResult),
|
|
16696
|
+
responseText: getResultResponseText(streamingResult),
|
|
16697
|
+
inputTokens: streamingResult.inputTokens ?? null,
|
|
16698
|
+
outputTokens: streamingResult.outputTokens ?? null,
|
|
16699
|
+
cacheCreationInputTokens: null,
|
|
16700
|
+
cacheReadInputTokens: streamingResult.cacheReadInputTokens ?? null,
|
|
16701
|
+
elapsedMs: getResultTotalStreamMs(streamingResult) ?? 0,
|
|
16702
|
+
firstChunkMs: getResultFirstChunkMs(streamingResult),
|
|
16703
|
+
totalStreamMs: getResultTotalStreamMs(streamingResult),
|
|
16704
|
+
tokensPerSecond: getResultTokensPerSecond(streamingResult),
|
|
16705
|
+
streaming: true,
|
|
16706
|
+
streamingChunks: captureFullDetails ? streamingResult.streamingChunks : void 0,
|
|
16707
|
+
userAgent: "provider-test",
|
|
16708
|
+
origin: null,
|
|
16709
|
+
apiFormat: "openai",
|
|
16710
|
+
isTest: true,
|
|
16711
|
+
providerName,
|
|
16712
|
+
headers: captureFullDetails ? getResultHeaders(streamingResult) : void 0
|
|
16713
|
+
});
|
|
16714
|
+
}
|
|
16715
|
+
}
|
|
15895
16716
|
}
|
|
15896
16717
|
const Route$2 = createFileRoute("/api/providers/$providerId/test/log")({
|
|
15897
16718
|
server: {
|
|
@@ -15918,7 +16739,8 @@ const Route$2 = createFileRoute("/api/providers/$providerId/test/log")({
|
|
|
15918
16739
|
const providerSessionId = buildProviderTestSessionId(params.providerId);
|
|
15919
16740
|
const captureFullDetails = getConfig().captureMode === "full";
|
|
15920
16741
|
const anthropicUrl = provider.anthropicBaseUrl !== void 0 && provider.anthropicBaseUrl.length > 0 ? provider.anthropicBaseUrl : void 0;
|
|
15921
|
-
const
|
|
16742
|
+
const openaiChatUrl = provider.openaiBaseUrl !== void 0 && provider.openaiBaseUrl.length > 0 ? provider.openaiBaseUrl : void 0;
|
|
16743
|
+
const openaiResponsesUrl = provider.openaiResponsesBaseUrl !== void 0 && provider.openaiResponsesBaseUrl.length > 0 ? provider.openaiResponsesBaseUrl : void 0;
|
|
15922
16744
|
const entries = [];
|
|
15923
16745
|
if (results.models !== void 0) {
|
|
15924
16746
|
for (const [modelName, modelResult] of Object.entries(results.models)) {
|
|
@@ -15928,7 +16750,8 @@ const Route$2 = createFileRoute("/api/providers/$providerId/test/log")({
|
|
|
15928
16750
|
provider.name,
|
|
15929
16751
|
providerSessionId,
|
|
15930
16752
|
anthropicUrl,
|
|
15931
|
-
|
|
16753
|
+
openaiChatUrl,
|
|
16754
|
+
openaiResponsesUrl,
|
|
15932
16755
|
modelResult,
|
|
15933
16756
|
captureFullDetails
|
|
15934
16757
|
)
|
|
@@ -16386,12 +17209,15 @@ const router = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
|
|
|
16386
17209
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
16387
17210
|
export {
|
|
16388
17211
|
AnthropicResponseSchema$1 as A,
|
|
16389
|
-
|
|
17212
|
+
createFailedProviderTestResults as B,
|
|
16390
17213
|
CapturedLogSchema as C,
|
|
16391
17214
|
DEFAULT_CAPTURE_MODE as D,
|
|
16392
|
-
|
|
17215
|
+
MAX_PROVIDER_TEST_TIMEOUT_SECONDS as E,
|
|
17216
|
+
resolveProviderContextWindow as F,
|
|
16393
17217
|
GroupEvidenceReadResponseSchema as G,
|
|
17218
|
+
isPlainRecord as H,
|
|
16394
17219
|
InspectorGroupsListResponseSchema as I,
|
|
17220
|
+
router as J,
|
|
16395
17221
|
KnowledgeCandidateSchema as K,
|
|
16396
17222
|
LogBodyChunkSchema as L,
|
|
16397
17223
|
MAX_SLOW_RESPONSE_THRESHOLD_SECONDS as M,
|
|
@@ -16419,10 +17245,10 @@ export {
|
|
|
16419
17245
|
findProviderModelMetadata as r,
|
|
16420
17246
|
safeGetOwnProperty as s,
|
|
16421
17247
|
maskApiKey as t,
|
|
16422
|
-
|
|
16423
|
-
|
|
16424
|
-
|
|
16425
|
-
|
|
16426
|
-
|
|
16427
|
-
|
|
17248
|
+
PATH_V1_MESSAGES as u,
|
|
17249
|
+
PATH_V1_CHAT_COMPLETIONS as v,
|
|
17250
|
+
PATH_V1_RESPONSES as w,
|
|
17251
|
+
previewUpstreamUrl as x,
|
|
17252
|
+
createPendingProviderTestResults as y,
|
|
17253
|
+
ProviderTestResultsSchema as z
|
|
16428
17254
|
};
|