@tonyclaw/agent-inspector 2.1.15 → 2.1.17

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