@tonyclaw/llm-inspector 1.15.0 → 1.16.0

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 (54) hide show
  1. package/.output/cli.js +1 -0
  2. package/.output/nitro.json +1 -1
  3. package/.output/public/assets/index-BmkN9DxE.js +107 -0
  4. package/.output/public/assets/index-DPe3eOih.css +1 -0
  5. package/.output/public/assets/{main-BLYgekFx.js → main-BjnjXVBU.js} +1 -1
  6. package/.output/server/_libs/diff.mjs +2 -2
  7. package/.output/server/_ssr/{index-P66uoVEU.mjs → index-BIOEVAzU.mjs} +783 -588
  8. package/.output/server/_ssr/index.mjs +2 -2
  9. package/.output/server/_ssr/{router-DpLCKk51.mjs → router-THS9ptvu.mjs} +439 -177
  10. package/.output/server/{_tanstack-start-manifest_v-C9Wq6YdJ.mjs → _tanstack-start-manifest_v-BYhN7q_z.mjs} +1 -1
  11. package/.output/server/index.mjs +31 -31
  12. package/README.md +200 -113
  13. package/package.json +1 -1
  14. package/src/cli.ts +1 -0
  15. package/src/components/ProxyViewer.tsx +77 -85
  16. package/src/components/ProxyViewerContainer.tsx +148 -76
  17. package/src/components/providers/ImportWizardDialog.tsx +27 -3
  18. package/src/components/proxy-viewer/CompareDrawer.tsx +17 -4
  19. package/src/components/proxy-viewer/ConversationGroup.tsx +15 -47
  20. package/src/components/proxy-viewer/ConversationHeader.tsx +58 -5
  21. package/src/components/proxy-viewer/LogEntry.tsx +297 -329
  22. package/src/components/proxy-viewer/LogEntryHeader.tsx +126 -137
  23. package/src/components/proxy-viewer/ResponseView.tsx +14 -34
  24. package/src/components/proxy-viewer/StreamingChunkSequence.tsx +3 -3
  25. package/src/components/proxy-viewer/TurnGroup.tsx +25 -21
  26. package/src/components/proxy-viewer/diff/DiffView.tsx +5 -3
  27. package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +13 -9
  28. package/src/components/proxy-viewer/formats/anthropic/ResponseView.tsx +3 -3
  29. package/src/components/proxy-viewer/formats/index.tsx +19 -10
  30. package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +7 -3
  31. package/src/components/proxy-viewer/log-formats/anthropic.ts +48 -0
  32. package/src/components/proxy-viewer/log-formats/index.ts +23 -0
  33. package/src/components/proxy-viewer/log-formats/openai.ts +40 -0
  34. package/src/components/proxy-viewer/log-formats/types.ts +33 -0
  35. package/src/components/proxy-viewer/log-formats/unknown.ts +14 -0
  36. package/src/components/proxy-viewer/viewerState.ts +58 -0
  37. package/src/components/ui/json-viewer.tsx +3 -3
  38. package/src/lib/objectUtils.ts +22 -0
  39. package/src/proxy/claudeCodeStrip.ts +5 -8
  40. package/src/proxy/formats/index.ts +1 -1
  41. package/src/proxy/formats/registry.ts +9 -0
  42. package/src/proxy/handler.ts +2 -8
  43. package/src/proxy/logIndex.ts +58 -43
  44. package/src/proxy/logger.ts +51 -27
  45. package/src/proxy/openaiOrphanToolStrip.ts +11 -17
  46. package/src/proxy/providerImporters.ts +245 -19
  47. package/src/proxy/providers.ts +20 -7
  48. package/src/proxy/schemas.ts +5 -9
  49. package/src/proxy/socketTracker.ts +109 -78
  50. package/src/proxy/store.ts +68 -83
  51. package/src/routes/api/logs.ts +31 -2
  52. package/styles/globals.css +22 -0
  53. package/.output/public/assets/index-CMuJQyt1.js +0 -105
  54. package/.output/public/assets/index-DciyfYBk.css +0 -1
@@ -2,15 +2,16 @@ import { c as createRouter, a as createRootRoute, b as createFileRoute, l as laz
2
2
  import { j as jsxRuntimeExports } from "../_libs/react.mjs";
3
3
  import { S as SWRConfig } from "../_libs/swr.mjs";
4
4
  import { existsSync, mkdirSync, writeFileSync, renameSync, copyFileSync, unlinkSync, readFileSync } from "node:fs";
5
+ import { mkdir, appendFile, readFile, open, readdir, stat, unlink, writeFile } from "node:fs/promises";
6
+ import { Buffer } from "node:buffer";
5
7
  import path, { join, isAbsolute, dirname } from "node:path";
6
- import { mkdir, appendFile, readFile, readdir, stat, unlink, writeFile } from "node:fs/promises";
7
8
  import { C as Conf } from "../_libs/conf.mjs";
8
9
  import { randomUUID } from "crypto";
9
10
  import { exec } from "node:child_process";
10
11
  import { promisify } from "node:util";
11
12
  import { M as McpServer, W as WebStandardStreamableHTTPServerTransport } from "../_libs/modelcontextprotocol__server.mjs";
12
13
  import { homedir } from "node:os";
13
- import { d as object, _ as _enum, b as string, a as array, u as union, c as boolean, r as record, n as number, g as discriminatedUnion, l as literal, h as _null, k as lazy, e as unknown } from "../_libs/zod.mjs";
14
+ import { d as object, _ as _enum, b as string, a as array, u as union, n as number, c as boolean, r as record, g as discriminatedUnion, l as literal, h as _null, k as lazy, e as unknown } from "../_libs/zod.mjs";
14
15
  import "../_libs/tiny-warning.mjs";
15
16
  import "../_libs/tanstack__router-core.mjs";
16
17
  import "../_libs/cookie-es.mjs";
@@ -45,7 +46,7 @@ import "../_libs/debounce-fn.mjs";
45
46
  import "../_libs/mimic-function.mjs";
46
47
  import "../_libs/semver.mjs";
47
48
  import "../_libs/uint8array-extras.mjs";
48
- const appCss = "/assets/index-DciyfYBk.css";
49
+ const appCss = "/assets/index-DPe3eOih.css";
49
50
  const Route$k = createRootRoute({
50
51
  head: () => ({
51
52
  meta: [
@@ -69,7 +70,7 @@ function RootDocument({ children }) {
69
70
  ] })
70
71
  ] });
71
72
  }
72
- const $$splitComponentImporter = () => import("./index-P66uoVEU.mjs");
73
+ const $$splitComponentImporter = () => import("./index-BIOEVAzU.mjs");
73
74
  const Route$j = createFileRoute("/")({
74
75
  component: lazyRouteComponent($$splitComponentImporter, "component")
75
76
  });
@@ -165,40 +166,57 @@ const logger = {
165
166
  };
166
167
  const MAX_BUFFER_SIZE = 1e3;
167
168
  let writeBuffer = [];
168
- let writeScheduled = false;
169
- let isFlushing = false;
170
- async function flushWriteBuffer() {
171
- if (writeBuffer.length === 0) return;
172
- if (isFlushing) return;
173
- isFlushing = true;
169
+ let writeQueue = Promise.resolve();
170
+ function drainBuffer() {
174
171
  const toWrite = writeBuffer.join("");
175
172
  writeBuffer = [];
173
+ return toWrite;
174
+ }
175
+ async function flushWriteBuffer() {
176
+ let toWrite;
177
+ {
178
+ toWrite = drainBuffer();
179
+ }
180
+ if (toWrite.length === 0) return;
176
181
  try {
177
182
  const filePath = getLogFilePath();
178
183
  await mkdir(path.dirname(filePath), { recursive: true });
179
184
  await appendFile(filePath, toWrite, "utf-8");
180
185
  } catch (err) {
181
- console.error("[logger] Failed to flush write buffer:", err);
182
- } finally {
183
- isFlushing = false;
186
+ writeBuffer.unshift(toWrite);
187
+ console.error("[logger] Failed to flush write buffer, re-queued:", err);
184
188
  }
185
189
  }
186
- function scheduleFlush() {
187
- if (writeScheduled) return;
188
- writeScheduled = true;
189
- void Promise.resolve().then(() => {
190
- writeScheduled = false;
191
- void flushWriteBuffer();
192
- });
193
- }
194
190
  function appendLogEntry(entry) {
195
191
  const line = JSON.stringify(entry) + "\n";
196
192
  writeBuffer.push(line);
197
193
  if (writeBuffer.length >= MAX_BUFFER_SIZE) {
198
- void flushWriteBuffer();
199
- } else {
200
- scheduleFlush();
194
+ writeQueue = writeQueue.then(() => flushWriteBuffer());
195
+ } else if (writeBuffer.length === 1) {
196
+ writeQueue = writeQueue.then(() => flushWriteBuffer());
197
+ }
198
+ }
199
+ async function flushLogBuffer() {
200
+ await writeQueue;
201
+ if (writeBuffer.length > 0) {
202
+ await flushWriteBuffer();
203
+ }
204
+ }
205
+ process.on("exit", () => {
206
+ if (writeBuffer.length > 0) {
207
+ const toWrite = drainBuffer();
208
+ try {
209
+ const filePath = getLogFilePath();
210
+ mkdirSync(path.dirname(filePath), { recursive: true });
211
+ writeFileSync(filePath, toWrite, "utf-8");
212
+ } catch {
213
+ }
201
214
  }
215
+ });
216
+ for (const signal of ["SIGINT", "SIGTERM"]) {
217
+ process.on(signal, () => {
218
+ void flushLogBuffer().then(() => process.exit(0));
219
+ });
202
220
  }
203
221
  const INDEX_VERSION = 1;
204
222
  const INDEX_FILE = "logs.idx";
@@ -255,9 +273,9 @@ async function saveIndex(index) {
255
273
  logger.error("[logIndex] Failed to save index:", String(err));
256
274
  }
257
275
  }
258
- async function addToIndex(id, file, lineStart, lineEnd) {
276
+ async function addToIndex(id, file, byteOffset, byteLength) {
259
277
  const index = await loadIndex();
260
- index.entries[id] = { id, file, lineStart, lineEnd };
278
+ index.entries[id] = { id, file, byteOffset, byteLength };
261
279
  if (id > index.maxId) {
262
280
  index.maxId = id;
263
281
  }
@@ -334,6 +352,14 @@ const JsonValueSchema = lazy(
334
352
  function trustAsJsonValue(value) {
335
353
  return value;
336
354
  }
355
+ function isPlainRecord(val) {
356
+ return typeof val === "object" && val !== null && !Array.isArray(val);
357
+ }
358
+ function safeGetOwnProperty(obj, key) {
359
+ if (obj === null || typeof obj !== "object" || Array.isArray(obj)) return void 0;
360
+ const desc = Object.getOwnPropertyDescriptor(obj, key);
361
+ return desc?.value;
362
+ }
337
363
  const CacheControl = object({
338
364
  type: string(),
339
365
  ttl: string().optional(),
@@ -519,8 +545,6 @@ const SseEventSchema = discriminatedUnion("type", [
519
545
  SsePingEvent,
520
546
  SseErrorEvent
521
547
  ]);
522
- const InspectorRequestSchema = AnthropicRequestSchema;
523
- const InspectorResponseSchema = AnthropicResponseSchema$1;
524
548
  const OpenAIMessageContent = union([
525
549
  string(),
526
550
  array(
@@ -741,17 +765,6 @@ function extractRequestMetadata(body, headers) {
741
765
  }
742
766
  return { model: null, sessionId: null };
743
767
  }
744
- function parseRequest(rawBody) {
745
- if (rawBody === null) return null;
746
- try {
747
- const json = JSON.parse(rawBody);
748
- const result = InspectorRequestSchema.safeParse(json);
749
- if (result.success) return result.data;
750
- return null;
751
- } catch {
752
- return null;
753
- }
754
- }
755
768
  const StreamingChunkSchema = object({
756
769
  index: number(),
757
770
  timestamp: number(),
@@ -822,38 +835,22 @@ function readChunks(path2) {
822
835
  }
823
836
  const MAX_MEMORY_CACHE = 100;
824
837
  const memoryCache = /* @__PURE__ */ new Map();
825
- let headId = null;
826
- let tailId = null;
827
- const prevMap = /* @__PURE__ */ new Map();
828
- const nextMap = /* @__PURE__ */ new Map();
829
838
  function evictOldestIfNeeded() {
830
- while (memoryCache.size >= MAX_MEMORY_CACHE && headId !== null) {
831
- const oldest = headId;
832
- const next = nextMap.get(oldest) ?? null;
833
- memoryCache.delete(oldest);
834
- prevMap.delete(oldest);
835
- nextMap.delete(oldest);
836
- if (next !== null) {
837
- prevMap.set(next, null);
838
- headId = next;
839
- } else {
840
- headId = null;
841
- tailId = null;
842
- }
839
+ while (memoryCache.size > MAX_MEMORY_CACHE) {
840
+ const oldestKey = memoryCache.keys().next().value;
841
+ if (oldestKey === void 0) break;
842
+ memoryCache.delete(oldestKey);
843
843
  }
844
844
  }
845
845
  function addToCache(log) {
846
- evictOldestIfNeeded();
847
- if (tailId !== null) {
848
- nextMap.set(tailId, log.id);
849
- prevMap.set(log.id, tailId);
850
- } else {
851
- headId = log.id;
852
- prevMap.set(log.id, null);
846
+ if (memoryCache.has(log.id)) {
847
+ memoryCache.delete(log.id);
853
848
  }
854
- nextMap.set(log.id, null);
855
- tailId = log.id;
856
849
  memoryCache.set(log.id, log);
850
+ evictOldestIfNeeded();
851
+ }
852
+ function removeFromCache(id) {
853
+ memoryCache.delete(id);
857
854
  }
858
855
  async function addTestLogEntry(entry) {
859
856
  const id = await getNextLogId();
@@ -933,6 +930,22 @@ async function getLogById(id) {
933
930
  if (!existsSync(filePath)) {
934
931
  return null;
935
932
  }
933
+ if (entry.byteOffset >= 0 && entry.byteLength > 0) {
934
+ const fh = await open(filePath, "r");
935
+ try {
936
+ const buffer = Buffer.alloc(entry.byteLength);
937
+ const { bytesRead } = await fh.read(buffer, 0, entry.byteLength, entry.byteOffset);
938
+ if (bytesRead === 0) return null;
939
+ const line = buffer.toString("utf-8", 0, bytesRead).trimEnd();
940
+ if (line === "") return null;
941
+ const parsed = JSON.parse(line);
942
+ const result = CapturedLogSchema.safeParse(parsed);
943
+ if (result.success) return result.data;
944
+ } finally {
945
+ await fh.close();
946
+ }
947
+ return null;
948
+ }
936
949
  const content = readFileSync(filePath, "utf-8");
937
950
  const lines = content.split("\n");
938
951
  let lastMatch = null;
@@ -985,12 +998,18 @@ function getModels() {
985
998
  function clearAllLogs() {
986
999
  const count = memoryCache.size;
987
1000
  memoryCache.clear();
988
- headId = null;
989
- tailId = null;
990
- prevMap.clear();
991
- nextMap.clear();
992
1001
  return { cleared: count };
993
1002
  }
1003
+ function clearLogsByIds(ids) {
1004
+ const unique = /* @__PURE__ */ new Set();
1005
+ for (const id of ids) {
1006
+ if (memoryCache.has(id)) unique.add(id);
1007
+ }
1008
+ for (const id of unique) {
1009
+ removeFromCache(id);
1010
+ }
1011
+ return { cleared: unique.size };
1012
+ }
994
1013
  const sseHandlers = /* @__PURE__ */ new Set();
995
1014
  function onLogUpdate(handler) {
996
1015
  sseHandlers.add(handler);
@@ -1062,6 +1081,9 @@ const formatRegistry = new FormatRegistryImpl();
1062
1081
  function formatForPath(path2) {
1063
1082
  return formatRegistry.getByPath(path2) ?? null;
1064
1083
  }
1084
+ function requestFormatForPath(path2) {
1085
+ return formatForPath(path2)?.format ?? "unknown";
1086
+ }
1065
1087
  formatRegistry.registerPath(PATH_V1_MESSAGES, "anthropic");
1066
1088
  formatRegistry.registerPath(PATH_V1_CHAT_COMPLETIONS, "openai");
1067
1089
  formatRegistry.registerPath(PATH_CHAT_COMPLETIONS, "openai");
@@ -1882,6 +1904,12 @@ function importProviders(json) {
1882
1904
  };
1883
1905
  }
1884
1906
  const providerArray = Array.isArray(parseResult.data) ? parseResult.data : parseResult.data.providers;
1907
+ const existingProviders = getProviders();
1908
+ const existingKeys = /* @__PURE__ */ new Set();
1909
+ for (const p of existingProviders) {
1910
+ existingKeys.add(`${p.name}::${p.anthropicBaseUrl ?? ""}`);
1911
+ }
1912
+ const newProviders = [];
1885
1913
  for (let i = 0; i < providerArray.length; i++) {
1886
1914
  const item = providerArray[i];
1887
1915
  const result = ProviderConfigSchema.safeParse(item);
@@ -1890,10 +1918,8 @@ function importProviders(json) {
1890
1918
  continue;
1891
1919
  }
1892
1920
  const provider = result.data;
1893
- const existing = getProviders().find(
1894
- (p) => p.name === provider.name && p.anthropicBaseUrl === provider.anthropicBaseUrl
1895
- );
1896
- if (existing) {
1921
+ const key = `${provider.name}::${provider.anthropicBaseUrl ?? ""}`;
1922
+ if (existingKeys.has(key)) {
1897
1923
  errors.push(`Provider "${provider.name}" already exists, skipping`);
1898
1924
  continue;
1899
1925
  }
@@ -1903,11 +1929,13 @@ function importProviders(json) {
1903
1929
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1904
1930
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1905
1931
  };
1906
- const providers = getProviders();
1907
- providers.push(newProvider);
1908
- store.set("providers", providers);
1932
+ newProviders.push(newProvider);
1933
+ existingKeys.add(key);
1909
1934
  imported++;
1910
1935
  }
1936
+ if (newProviders.length > 0) {
1937
+ store.set("providers", [...existingProviders, ...newProviders]);
1938
+ }
1911
1939
  } catch (err) {
1912
1940
  return {
1913
1941
  imported: 0,
@@ -1959,6 +1987,15 @@ function findProviderByModel(model) {
1959
1987
  const execAsync = promisify(exec);
1960
1988
  const cache = /* @__PURE__ */ new Map();
1961
1989
  const CACHE_TTL_MS = 5 * 60 * 1e3;
1990
+ const MAX_CACHE_SIZE = 200;
1991
+ const inflight = /* @__PURE__ */ new Map();
1992
+ function evictCacheIfNeeded() {
1993
+ while (cache.size > MAX_CACHE_SIZE) {
1994
+ const oldestKey = cache.keys().next().value;
1995
+ if (oldestKey === void 0) break;
1996
+ cache.delete(oldestKey);
1997
+ }
1998
+ }
1962
1999
  function getFromCache(port) {
1963
2000
  const entry = cache.get(port);
1964
2001
  if (entry && Date.now() < entry.expiresAt) {
@@ -1969,6 +2006,7 @@ function getFromCache(port) {
1969
2006
  }
1970
2007
  function setCache(port, info) {
1971
2008
  cache.set(port, { ...info, expiresAt: Date.now() + CACHE_TTL_MS });
2009
+ evictCacheIfNeeded();
1972
2010
  }
1973
2011
  function extractRemotePort(request) {
1974
2012
  const socket = request.socket;
@@ -1976,43 +2014,83 @@ function extractRemotePort(request) {
1976
2014
  if (remotePort !== void 0 && remotePort !== null) return remotePort;
1977
2015
  return null;
1978
2016
  }
1979
- async function lookupPidByPort(port) {
2017
+ async function lookupClientInfo(port) {
1980
2018
  const platform = process.platform;
1981
2019
  try {
1982
2020
  if (platform === "win32") {
1983
- const { stdout } = await execAsync(
1984
- `powershell -NoProfile -Command "Get-NetTCPConnection -LocalPort ${port} -State Established | Select-Object -ExpandProperty OwningProcess"`,
1985
- { windowsHide: true }
1986
- );
1987
- const pid = parseInt(stdout.trim(), 10);
1988
- return !isNaN(pid) && pid > 0 ? pid : null;
1989
- } else if (platform === "darwin") {
2021
+ const psScript = [
2022
+ `$conn = Get-NetTCPConnection -LocalPort ${port} -State Established -ErrorAction SilentlyContinue | Select-Object -First 1`,
2023
+ `if ($conn) {`,
2024
+ ` $pid = $conn.OwningProcess`,
2025
+ ` $proc = Get-CimInstance Win32_Process -Filter "ProcessId=$pid" -ErrorAction SilentlyContinue`,
2026
+ ` $cmd = if ($proc) { $proc.CommandLine } else { "" }`,
2027
+ ` Write-Output "$pid|$cmd"`,
2028
+ `}`
2029
+ ].join("; ");
2030
+ const { stdout } = await execAsync(`powershell -NoProfile -Command "${psScript}"`, {
2031
+ windowsHide: true
2032
+ });
2033
+ const trimmed = stdout.trim();
2034
+ if (trimmed === "") {
2035
+ return { port, pid: null, cwd: null, projectFolder: null };
2036
+ }
2037
+ const [pidStr, ...cmdParts] = trimmed.split("|");
2038
+ const pid2 = parseInt(pidStr ?? "", 10);
2039
+ if (isNaN(pid2) || pid2 <= 0) {
2040
+ return { port, pid: null, cwd: null, projectFolder: null };
2041
+ }
2042
+ const commandLine = cmdParts.join("|").trim();
2043
+ const { cwd: cwd2, projectFolder: projectFolder2 } = parseCommandLine(commandLine, "\\");
2044
+ return { port, pid: pid2, cwd: cwd2, projectFolder: projectFolder2 };
2045
+ }
2046
+ let pid = null;
2047
+ if (platform === "darwin") {
1990
2048
  const { stdout } = await execAsync(`lsof -i :${port} -sTCP:ESTABLISHED -t 2>/dev/null`, {
1991
2049
  shell: "/bin/sh"
1992
2050
  });
1993
- const pid = parseInt(stdout.trim(), 10);
1994
- return !isNaN(pid) && pid > 0 ? pid : null;
2051
+ const parsed = parseInt(stdout.trim(), 10);
2052
+ if (!isNaN(parsed) && parsed > 0) pid = parsed;
1995
2053
  } else {
1996
2054
  try {
1997
- const { stdout: stdout2 } = await execAsync(
2055
+ const { stdout } = await execAsync(
1998
2056
  `ss -tlnp 'sport = :${port}' 2>/dev/null | grep ESTAB | awk '{print $6}' | grep -o 'pid=[0-9]*' | cut -d= -f2`,
1999
2057
  { shell: "/bin/sh" }
2000
2058
  );
2001
- const pid2 = parseInt(stdout2.trim(), 10);
2002
- if (!isNaN(pid2) && pid2 > 0) return pid2;
2059
+ const parsed = parseInt(stdout.trim(), 10);
2060
+ if (!isNaN(parsed) && parsed > 0) pid = parsed;
2003
2061
  } catch {
2004
2062
  }
2005
- const { stdout } = await execAsync(
2006
- `netstat -tan 2>/dev/null | grep ':${port}' | grep ESTABLISHED | awk '{print $7}' | cut -d/ -f1`,
2007
- { shell: "/bin/sh" }
2008
- );
2009
- const pid = parseInt(stdout.trim(), 10);
2010
- return !isNaN(pid) && pid > 0 ? pid : null;
2063
+ if (pid === null) {
2064
+ const { stdout } = await execAsync(
2065
+ `netstat -tan 2>/dev/null | grep ':${port}' | grep ESTABLISHED | awk '{print $7}' | cut -d/ -f1`,
2066
+ { shell: "/bin/sh" }
2067
+ );
2068
+ const parsed = parseInt(stdout.trim(), 10);
2069
+ if (!isNaN(parsed) && parsed > 0) pid = parsed;
2070
+ }
2011
2071
  }
2072
+ if (pid === null) {
2073
+ return { port, pid: null, cwd: null, projectFolder: null };
2074
+ }
2075
+ const { cwd, projectFolder } = await lookupProcessInfo(pid);
2076
+ return { port, pid, cwd, projectFolder };
2012
2077
  } catch (err) {
2013
- logger.debug(`[socketTracker] Failed to lookup PID for port ${port}:`, String(err));
2014
- return null;
2078
+ logger.debug(`[socketTracker] Failed to lookup info for port ${port}:`, String(err));
2079
+ return { port, pid: null, cwd: null, projectFolder: null };
2080
+ }
2081
+ }
2082
+ function parseCommandLine(commandLine, sep) {
2083
+ if (!commandLine) return { cwd: null, projectFolder: null };
2084
+ const exeMatch = commandLine.match(/^"([^"]+)"/) || commandLine.match(/^([^\s]+)/);
2085
+ if (exeMatch?.[1] !== void 0) {
2086
+ const exePath = exeMatch[1];
2087
+ const lastSep = exePath.lastIndexOf(sep);
2088
+ if (lastSep > 0) {
2089
+ const exeDir = exePath.substring(0, lastSep);
2090
+ return { cwd: exeDir, projectFolder: exeDir.split(sep).pop() ?? null };
2091
+ }
2015
2092
  }
2093
+ return { cwd: null, projectFolder: null };
2016
2094
  }
2017
2095
  async function lookupProcessInfo(pid) {
2018
2096
  const platform = process.platform;
@@ -2027,15 +2105,7 @@ async function lookupProcessInfo(pid) {
2027
2105
  if (line.includes("=")) {
2028
2106
  const commandLine = (line.split("=")[1] ?? "").trim();
2029
2107
  if (commandLine) {
2030
- const exeMatch = commandLine.match(/^"([^"]+)"/) || commandLine.match(/^([^\s]+)/);
2031
- if (exeMatch && exeMatch[1] !== void 0) {
2032
- const exePath = exeMatch[1];
2033
- const exeDir = exePath.substring(0, exePath.lastIndexOf("\\"));
2034
- return {
2035
- cwd: exeDir,
2036
- projectFolder: exeDir.split("\\").pop() ?? null
2037
- };
2038
- }
2108
+ return parseCommandLine(commandLine, "\\");
2039
2109
  }
2040
2110
  }
2041
2111
  }
@@ -2046,15 +2116,7 @@ async function lookupProcessInfo(pid) {
2046
2116
  });
2047
2117
  const commandLine = stdout.trim();
2048
2118
  if (commandLine) {
2049
- const exeMatch = commandLine.match(/^"([^"]+)"/) || commandLine.match(/^([^\s]+)/);
2050
- if (exeMatch && exeMatch[1] !== void 0) {
2051
- const exePath = exeMatch[1];
2052
- const exeDir = exePath.substring(0, exePath.lastIndexOf("/"));
2053
- return {
2054
- cwd: exeDir,
2055
- projectFolder: exeDir.split("/").pop() ?? null
2056
- };
2057
- }
2119
+ return parseCommandLine(commandLine, "/");
2058
2120
  }
2059
2121
  } catch {
2060
2122
  }
@@ -2064,11 +2126,7 @@ async function lookupProcessInfo(pid) {
2064
2126
  });
2065
2127
  const exePath = stdout.trim();
2066
2128
  if (exePath) {
2067
- const exeDir = exePath.substring(0, exePath.lastIndexOf("/"));
2068
- return {
2069
- cwd: exeDir,
2070
- projectFolder: exePath.split("/").pop() ?? null
2071
- };
2129
+ return parseCommandLine(exePath, "/");
2072
2130
  }
2073
2131
  }
2074
2132
  }
@@ -2084,16 +2142,21 @@ async function getClientInfo(request) {
2084
2142
  }
2085
2143
  const cached = getFromCache(port);
2086
2144
  if (cached) return cached;
2087
- const pid = await lookupPidByPort(port);
2088
- if (pid === null) {
2089
- const info2 = { port, pid: null, cwd: null, projectFolder: null };
2090
- setCache(port, info2);
2091
- return info2;
2092
- }
2093
- const { cwd, projectFolder } = await lookupProcessInfo(pid);
2094
- const info = { port, pid, cwd, projectFolder };
2095
- setCache(port, info);
2096
- return info;
2145
+ const existing = inflight.get(port);
2146
+ if (existing) return existing;
2147
+ const promise = lookupClientInfo(port).then((info) => {
2148
+ setCache(port, info);
2149
+ inflight.delete(port);
2150
+ return info;
2151
+ }).catch((err) => {
2152
+ inflight.delete(port);
2153
+ logger.debug(`[socketTracker] Lookup failed for port ${port}:`, String(err));
2154
+ const fallback = { port, pid: null, cwd: null, projectFolder: null };
2155
+ setCache(port, fallback);
2156
+ return fallback;
2157
+ });
2158
+ inflight.set(port, promise);
2159
+ return promise;
2097
2160
  }
2098
2161
  const RuntimeConfigSchema = object({
2099
2162
  stripClaudeCodeBillingHeader: boolean()
@@ -2178,18 +2241,14 @@ function isClaudeCodeBillingHeaderBlock(text) {
2178
2241
  const trimmed = text.trimStart();
2179
2242
  return trimmed.toLowerCase().startsWith(BILLING_HEADER_PREFIX);
2180
2243
  }
2181
- function getOwnProperty$1(obj, key) {
2182
- const desc = Object.getOwnPropertyDescriptor(obj, key);
2183
- return desc?.value;
2184
- }
2185
2244
  function isObjectWithSystem(value) {
2186
- if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
2245
+ if (!isPlainRecord(value)) return false;
2187
2246
  return Object.prototype.hasOwnProperty.call(value, "system");
2188
2247
  }
2189
2248
  function isBillingHeaderTextBlock(block) {
2190
- if (block === null || typeof block !== "object" || Array.isArray(block)) return false;
2191
- const typeVal = getOwnProperty$1(block, "type");
2192
- const textVal = getOwnProperty$1(block, "text");
2249
+ if (!isPlainRecord(block)) return false;
2250
+ const typeVal = safeGetOwnProperty(block, "type");
2251
+ const textVal = safeGetOwnProperty(block, "text");
2193
2252
  if (typeof typeVal !== "string" || typeVal !== "text") return false;
2194
2253
  if (typeof textVal !== "string") return false;
2195
2254
  return isClaudeCodeBillingHeaderBlock(textVal);
@@ -2229,25 +2288,19 @@ function stripClaudeCodeBillingHeader(rawBody) {
2229
2288
  }
2230
2289
  const ROLE_ASSISTANT = "assistant";
2231
2290
  const ROLE_TOOL = "tool";
2232
- function getOwnProperty(obj, key) {
2233
- const desc = Object.getOwnPropertyDescriptor(obj, key);
2234
- return desc?.value;
2235
- }
2236
- function isPlainObject(value) {
2237
- return typeof value === "object" && value !== null && !Array.isArray(value);
2238
- }
2239
2291
  function isObjectWithMessages(value) {
2240
- if (!isPlainObject(value)) return false;
2292
+ if (!isPlainRecord(value)) return false;
2241
2293
  if (!Object.prototype.hasOwnProperty.call(value, "messages")) return false;
2242
- const messages = getOwnProperty(value, "messages");
2294
+ const messages = safeGetOwnProperty(value, "messages");
2243
2295
  return Array.isArray(messages);
2244
2296
  }
2245
2297
  function collectAssistantToolCallIds(message, into) {
2246
- const toolCalls = getOwnProperty(message, "tool_calls");
2298
+ if (!isPlainRecord(message)) return;
2299
+ const toolCalls = safeGetOwnProperty(message, "tool_calls");
2247
2300
  if (!Array.isArray(toolCalls)) return;
2248
2301
  for (const tc of toolCalls) {
2249
- if (!isPlainObject(tc)) continue;
2250
- const id = getOwnProperty(tc, "id");
2302
+ if (!isPlainRecord(tc)) continue;
2303
+ const id = safeGetOwnProperty(tc, "id");
2251
2304
  if (typeof id === "string" && id.length > 0) {
2252
2305
  into.add(id);
2253
2306
  }
@@ -2259,14 +2312,14 @@ function findOrphanToolMessageIndices(messages) {
2259
2312
  const orphanIds = [];
2260
2313
  for (let i = 0; i < messages.length; i++) {
2261
2314
  const msg = messages[i];
2262
- if (!isPlainObject(msg)) continue;
2263
- const role = getOwnProperty(msg, "role");
2315
+ if (!isPlainRecord(msg)) continue;
2316
+ const role = safeGetOwnProperty(msg, "role");
2264
2317
  if (role === ROLE_ASSISTANT) {
2265
2318
  collectAssistantToolCallIds(msg, knownToolCallIds);
2266
2319
  continue;
2267
2320
  }
2268
2321
  if (role === ROLE_TOOL) {
2269
- const id = getOwnProperty(msg, "tool_call_id");
2322
+ const id = safeGetOwnProperty(msg, "tool_call_id");
2270
2323
  if (typeof id !== "string" || id.length === 0) {
2271
2324
  indices.push(i);
2272
2325
  orphanIds.push(null);
@@ -2532,8 +2585,6 @@ async function handleProxy(req) {
2532
2585
  upstreamHeaders.forEach((value, key) => {
2533
2586
  upstreamHeadersObj[key.toLowerCase()] = value;
2534
2587
  });
2535
- const bodyFormat = formatRegistry.detectFormat(requestBody);
2536
- const displayApiFormat = bodyFormat !== "unknown" ? bodyFormat : formatHandler.format;
2537
2588
  const log = await createLog(
2538
2589
  req.method,
2539
2590
  parsed.apiPath,
@@ -2542,7 +2593,7 @@ async function handleProxy(req) {
2542
2593
  clientInfo,
2543
2594
  rawHeaders,
2544
2595
  upstreamHeadersObj,
2545
- displayApiFormat,
2596
+ formatHandler.format,
2546
2597
  model,
2547
2598
  sessionId,
2548
2599
  preAcquiredId
@@ -3166,6 +3217,9 @@ const Route$e = createFileRoute("/api/mcp")({
3166
3217
  }
3167
3218
  }
3168
3219
  });
3220
+ const DeleteBodySchema = object({
3221
+ ids: array(number().int().positive()).optional()
3222
+ }).optional();
3169
3223
  const Route$d = createFileRoute("/api/logs")({
3170
3224
  server: {
3171
3225
  handlers: {
@@ -3184,7 +3238,28 @@ const Route$d = createFileRoute("/api/logs")({
3184
3238
  limit
3185
3239
  });
3186
3240
  },
3187
- DELETE: () => {
3241
+ DELETE: async ({ request }) => {
3242
+ let body = void 0;
3243
+ try {
3244
+ const raw = await request.text();
3245
+ if (raw !== "") {
3246
+ const parsed = JSON.parse(raw);
3247
+ const result2 = DeleteBodySchema.safeParse(parsed);
3248
+ if (!result2.success) {
3249
+ return Response.json(
3250
+ { error: "Invalid request body", details: result2.error.format() },
3251
+ { status: 400 }
3252
+ );
3253
+ }
3254
+ body = result2.data;
3255
+ }
3256
+ } catch {
3257
+ return Response.json({ error: "Invalid JSON body" }, { status: 400 });
3258
+ }
3259
+ if (body?.ids !== void 0 && body.ids.length > 0) {
3260
+ const result2 = clearLogsByIds(body.ids);
3261
+ return Response.json({ success: true, cleared: result2.cleared });
3262
+ }
3188
3263
  const result = clearAllLogs();
3189
3264
  return Response.json({ success: true, cleared: result.cleared });
3190
3265
  }
@@ -3235,21 +3310,18 @@ const Route$b = createFileRoute("/api/config")({
3235
3310
  }
3236
3311
  }
3237
3312
  });
3238
- function isRecord(val) {
3239
- return val !== null && typeof val === "object" && !Array.isArray(val);
3240
- }
3241
3313
  function readJsonSafe(filePath) {
3242
3314
  try {
3243
3315
  if (!existsSync(filePath)) return null;
3244
3316
  const raw = readFileSync(filePath, "utf-8");
3245
3317
  const parsed = JSON.parse(raw);
3246
- return isRecord(parsed) ? parsed : null;
3318
+ return isPlainRecord(parsed) ? parsed : null;
3247
3319
  } catch {
3248
3320
  return null;
3249
3321
  }
3250
3322
  }
3251
3323
  function getEnvValue(envObj, key) {
3252
- if (!isRecord(envObj)) return void 0;
3324
+ if (!isPlainRecord(envObj)) return void 0;
3253
3325
  const val = envObj[key];
3254
3326
  return typeof val === "string" ? val.trim() : void 0;
3255
3327
  }
@@ -3294,15 +3366,15 @@ function detectClaudeCodeProviders() {
3294
3366
  const globalConfig = readJsonSafe(join(home, ".claude", "settings.json"));
3295
3367
  const localConfig = readJsonSafe(join(home, ".claude", "settings.local.json"));
3296
3368
  const mergedEnv = {};
3297
- if (isRecord(globalConfig)) {
3369
+ if (isPlainRecord(globalConfig)) {
3298
3370
  const env = globalConfig["env"];
3299
- if (isRecord(env)) {
3371
+ if (isPlainRecord(env)) {
3300
3372
  Object.assign(mergedEnv, env);
3301
3373
  }
3302
3374
  }
3303
- if (isRecord(localConfig)) {
3375
+ if (isPlainRecord(localConfig)) {
3304
3376
  const env = localConfig["env"];
3305
- if (isRecord(env)) {
3377
+ if (isPlainRecord(env)) {
3306
3378
  Object.assign(mergedEnv, env);
3307
3379
  }
3308
3380
  }
@@ -3343,25 +3415,25 @@ function detectOpenCodeProviders() {
3343
3415
  if (config === null) return results;
3344
3416
  const auth = readJsonSafe(join(home, ".local", "share", "opencode", "auth.json"));
3345
3417
  const providersVal = config["provider"];
3346
- if (!isRecord(providersVal)) {
3418
+ if (!isPlainRecord(providersVal)) {
3347
3419
  return results;
3348
3420
  }
3349
3421
  const providers = providersVal;
3350
3422
  for (const [providerId, providerObj] of Object.entries(providers)) {
3351
- if (!isRecord(providerObj)) continue;
3423
+ if (!isPlainRecord(providerObj)) continue;
3352
3424
  const options = providerObj["options"];
3353
3425
  const npm = providerObj["npm"];
3354
3426
  const npmStr = typeof npm === "string" ? npm : "";
3355
3427
  const format = npmStr === "@ai-sdk/anthropic" ? "anthropic" : "openai";
3356
3428
  let baseURL = "";
3357
3429
  let apiKey = "";
3358
- if (isRecord(options)) {
3430
+ if (isPlainRecord(options)) {
3359
3431
  baseURL = typeof options["baseURL"] === "string" ? options["baseURL"].trim() : "";
3360
3432
  apiKey = typeof options["apiKey"] === "string" ? options["apiKey"].trim() : "";
3361
3433
  }
3362
- if (apiKey === "" && isRecord(auth)) {
3434
+ if (apiKey === "" && isPlainRecord(auth)) {
3363
3435
  const cred = auth[providerId];
3364
- if (isRecord(cred)) {
3436
+ if (isPlainRecord(cred)) {
3365
3437
  const key = cred["key"];
3366
3438
  if (typeof key === "string" && key !== "") apiKey = key;
3367
3439
  }
@@ -3369,11 +3441,11 @@ function detectOpenCodeProviders() {
3369
3441
  if (baseURL === "" || apiKey === "") continue;
3370
3442
  const modelSet = /* @__PURE__ */ new Set();
3371
3443
  const modelsObj = providerObj["models"];
3372
- if (isRecord(modelsObj)) {
3444
+ if (isPlainRecord(modelsObj)) {
3373
3445
  for (const [modelId, modelDef] of Object.entries(modelsObj)) {
3374
3446
  if (typeof modelDef === "string") {
3375
3447
  modelSet.add(modelDef);
3376
- } else if (isRecord(modelDef)) {
3448
+ } else if (isPlainRecord(modelDef)) {
3377
3449
  modelSet.add(modelId);
3378
3450
  } else {
3379
3451
  modelSet.add(modelId);
@@ -3394,6 +3466,189 @@ function detectOpenCodeProviders() {
3394
3466
  }
3395
3467
  return results;
3396
3468
  }
3469
+ function stripJsoncComments(raw) {
3470
+ let result = "";
3471
+ let i = 0;
3472
+ let inString = false;
3473
+ let stringChar = "";
3474
+ while (i < raw.length) {
3475
+ const ch = raw[i];
3476
+ const next = raw[i + 1];
3477
+ if (inString) {
3478
+ if (ch === "\\" && next !== void 0) {
3479
+ result += ch + next;
3480
+ i += 2;
3481
+ continue;
3482
+ }
3483
+ if (ch === stringChar) {
3484
+ inString = false;
3485
+ stringChar = "";
3486
+ }
3487
+ result += ch;
3488
+ i += 1;
3489
+ continue;
3490
+ }
3491
+ if (ch === '"' || ch === "'") {
3492
+ inString = true;
3493
+ stringChar = ch;
3494
+ result += ch;
3495
+ i += 1;
3496
+ continue;
3497
+ }
3498
+ if (ch === "/" && next === "/") {
3499
+ while (i < raw.length && raw[i] !== "\n") {
3500
+ i += 1;
3501
+ }
3502
+ continue;
3503
+ }
3504
+ if (ch === "/" && next === "*") {
3505
+ i += 2;
3506
+ while (i < raw.length - 1 && !(raw[i] === "*" && raw[i + 1] === "/")) {
3507
+ i += 1;
3508
+ }
3509
+ i += 2;
3510
+ continue;
3511
+ }
3512
+ result += ch;
3513
+ i += 1;
3514
+ }
3515
+ return result;
3516
+ }
3517
+ function readJsonCSafe(filePath) {
3518
+ try {
3519
+ if (!existsSync(filePath)) return null;
3520
+ const raw = readFileSync(filePath, "utf-8");
3521
+ const stripped = stripJsoncComments(raw);
3522
+ const parsed = JSON.parse(stripped);
3523
+ return isPlainRecord(parsed) ? parsed : null;
3524
+ } catch {
3525
+ return null;
3526
+ }
3527
+ }
3528
+ function detectMiMoCodeProviders() {
3529
+ const home = homedir();
3530
+ const results = [];
3531
+ const config = readJsonCSafe(join(home, ".config", "mimocode", "mimocode.jsonc")) ?? readJsonCSafe(join(home, ".config", "mimocode", "mimocode.json")) ?? readJsonCSafe(join(home, ".config", "mimocode", "config.jsonc")) ?? readJsonCSafe(join(home, ".config", "mimocode", "config.json")) ?? readJsonCSafe(join(home, ".mimocode", "config.jsonc")) ?? readJsonCSafe(join(home, ".mimocode", "config.json"));
3532
+ const auth = readJsonSafe(join(home, ".local", "share", "mimocode", "auth.json"));
3533
+ const providersVal = config?.["provider"];
3534
+ const configProviders = isPlainRecord(providersVal) ? providersVal : {};
3535
+ for (const [providerId, providerObj] of Object.entries(configProviders)) {
3536
+ if (!isPlainRecord(providerObj)) continue;
3537
+ const options = providerObj["options"];
3538
+ const npm = providerObj["npm"];
3539
+ const npmStr = typeof npm === "string" ? npm : "";
3540
+ const format = npmStr === "@ai-sdk/anthropic" ? "anthropic" : "openai";
3541
+ let baseURL = "";
3542
+ let apiKey = "";
3543
+ if (isPlainRecord(options)) {
3544
+ baseURL = typeof options["baseURL"] === "string" ? options["baseURL"].trim() : "";
3545
+ apiKey = typeof options["apiKey"] === "string" ? options["apiKey"].trim() : "";
3546
+ }
3547
+ if (apiKey === "" && isPlainRecord(auth)) {
3548
+ const cred = auth[providerId];
3549
+ if (isPlainRecord(cred)) {
3550
+ const key = cred["key"];
3551
+ if (typeof key === "string" && key !== "") apiKey = key;
3552
+ }
3553
+ }
3554
+ if (baseURL === "" || apiKey === "") continue;
3555
+ const modelSet = /* @__PURE__ */ new Set();
3556
+ const modelsObj = providerObj["models"];
3557
+ if (isPlainRecord(modelsObj)) {
3558
+ for (const [modelId, modelDef] of Object.entries(modelsObj)) {
3559
+ if (typeof modelDef === "string") {
3560
+ modelSet.add(modelDef);
3561
+ } else if (isPlainRecord(modelDef)) {
3562
+ modelSet.add(modelId);
3563
+ } else {
3564
+ modelSet.add(modelId);
3565
+ }
3566
+ }
3567
+ }
3568
+ const models = modelSet.size > 0 ? [...modelSet] : ["default"];
3569
+ results.push({
3570
+ name: providerId,
3571
+ apiKey: normalizeApiKey(apiKey),
3572
+ format,
3573
+ anthropicBaseUrl: format === "anthropic" ? baseURL : "",
3574
+ openaiBaseUrl: format === "openai" ? baseURL : "",
3575
+ models,
3576
+ sourceTool: "mimo-code",
3577
+ alreadyExists: false
3578
+ });
3579
+ }
3580
+ if (isPlainRecord(auth)) {
3581
+ const knownDefaults = {
3582
+ deepseek: {
3583
+ anthropicBaseUrl: "https://api.deepseek.com/anthropic",
3584
+ openaiBaseUrl: "https://api.deepseek.com",
3585
+ format: "anthropic"
3586
+ },
3587
+ minimax: {
3588
+ anthropicBaseUrl: "https://api.minimaxi.com/anthropic",
3589
+ openaiBaseUrl: "https://api.minimaxi.com",
3590
+ format: "anthropic"
3591
+ },
3592
+ "minimax-coding-plan": {
3593
+ anthropicBaseUrl: "https://api.minimaxi.com/anthropic",
3594
+ openaiBaseUrl: "https://api.minimaxi.com",
3595
+ format: "anthropic"
3596
+ },
3597
+ openai: {
3598
+ anthropicBaseUrl: "",
3599
+ openaiBaseUrl: "https://api.openai.com",
3600
+ format: "openai"
3601
+ },
3602
+ anthropic: {
3603
+ anthropicBaseUrl: "https://api.anthropic.com",
3604
+ openaiBaseUrl: "",
3605
+ format: "anthropic"
3606
+ },
3607
+ groq: {
3608
+ anthropicBaseUrl: "",
3609
+ openaiBaseUrl: "https://api.groq.com/openai",
3610
+ format: "openai"
3611
+ },
3612
+ openrouter: {
3613
+ anthropicBaseUrl: "",
3614
+ openaiBaseUrl: "https://openrouter.ai/api",
3615
+ format: "openai"
3616
+ },
3617
+ together: {
3618
+ anthropicBaseUrl: "",
3619
+ openaiBaseUrl: "https://api.together.xyz",
3620
+ format: "openai"
3621
+ }
3622
+ };
3623
+ for (const [key, cred] of Object.entries(auth)) {
3624
+ if (configProviders[key] !== void 0) continue;
3625
+ if (!isPlainRecord(cred)) continue;
3626
+ const apiKey = cred["key"];
3627
+ if (typeof apiKey !== "string" || apiKey === "") continue;
3628
+ let defaults = knownDefaults[key.toLowerCase()];
3629
+ if (defaults === void 0) {
3630
+ for (const [knownKey, cfg] of Object.entries(knownDefaults)) {
3631
+ if (key.toLowerCase().startsWith(knownKey)) {
3632
+ defaults = cfg;
3633
+ break;
3634
+ }
3635
+ }
3636
+ }
3637
+ if (defaults === void 0) continue;
3638
+ results.push({
3639
+ name: key,
3640
+ apiKey: normalizeApiKey(apiKey),
3641
+ format: defaults.format,
3642
+ anthropicBaseUrl: defaults.anthropicBaseUrl,
3643
+ openaiBaseUrl: defaults.openaiBaseUrl,
3644
+ models: ["default"],
3645
+ sourceTool: "mimo-code",
3646
+ alreadyExists: false
3647
+ });
3648
+ }
3649
+ }
3650
+ return results;
3651
+ }
3397
3652
  function scanExternalProviders() {
3398
3653
  const warnings = [];
3399
3654
  let claudeProviders = [];
@@ -3408,7 +3663,13 @@ function scanExternalProviders() {
3408
3663
  } catch (err) {
3409
3664
  warnings.push(`OpenCode: ${err instanceof Error ? err.message : String(err)}`);
3410
3665
  }
3411
- const allProviders = [...claudeProviders, ...opencodeProviders];
3666
+ let mimoProviders = [];
3667
+ try {
3668
+ mimoProviders = detectMiMoCodeProviders();
3669
+ } catch (err) {
3670
+ warnings.push(`MiMo Code: ${err instanceof Error ? err.message : String(err)}`);
3671
+ }
3672
+ const allProviders = [...claudeProviders, ...opencodeProviders, ...mimoProviders];
3412
3673
  const filteredProviders = allProviders.filter((p) => {
3413
3674
  const url = p.anthropicBaseUrl || p.openaiBaseUrl;
3414
3675
  return !/(?:localhost|127\.0\.0\.1)/.test(url);
@@ -4741,16 +5002,17 @@ const router = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
4741
5002
  getRouter
4742
5003
  }, Symbol.toStringTag, { value: "Module" }));
4743
5004
  export {
5005
+ AnthropicResponseSchema$1 as A,
4744
5006
  CapturedLogSchema as C,
4745
- InspectorResponseSchema as I,
4746
5007
  OpenAIRequestSchema as O,
4747
5008
  ProviderTestResultsSchema as P,
4748
5009
  RuntimeConfigSchema as R,
4749
- parseRequest as a,
5010
+ AnthropicRequestSchema as a,
4750
5011
  createFailedProviderTestResults as b,
4751
5012
  createPendingProviderTestResults as c,
4752
5013
  ProviderConfigSchema as d,
5014
+ router as e,
4753
5015
  parseOpenAIResponse as p,
4754
- router as r,
5016
+ requestFormatForPath as r,
4755
5017
  stripClaudeCodeBillingHeader as s
4756
5018
  };