@tonyclaw/llm-inspector 1.11.3 → 1.11.4

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.
@@ -1,5 +1,5 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports, R as React } from "../_libs/react.mjs";
2
- import { C as CapturedLogSchema, R as RuntimeConfigSchema, a as parseRequest, s as stripClaudeCodeBillingHeader, p as parseOpenAIResponse, I as InspectorResponseSchema } from "./router-CChl8Zb8.mjs";
2
+ import { C as CapturedLogSchema, R as RuntimeConfigSchema, a as parseRequest, s as stripClaudeCodeBillingHeader, p as parseOpenAIResponse, I as InspectorResponseSchema } from "./router-DRA0j7Zv.mjs";
3
3
  import { u as useSWR, a as useSWRConfig } from "../_libs/swr.mjs";
4
4
  import { u as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
5
5
  import { J as JSZip } from "../_libs/jszip.mjs";
@@ -255,7 +255,7 @@ async function exportLogsAsZip(logs) {
255
255
  document.body.removeChild(anchor);
256
256
  URL.revokeObjectURL(url);
257
257
  }
258
- const version = "1.11.3";
258
+ const version = "1.11.4";
259
259
  const packageJson = {
260
260
  version
261
261
  };
@@ -1778,6 +1778,7 @@ function ResponseContentBlockRenderer({
1778
1778
  case "text":
1779
1779
  return /* @__PURE__ */ jsxRuntimeExports.jsx(TextBlock, { text: block.text });
1780
1780
  case "thinking":
1781
+ case "think":
1781
1782
  return /* @__PURE__ */ jsxRuntimeExports.jsx(ThinkingBlock, { thinking: block.thinking });
1782
1783
  case "tool_use":
1783
1784
  return /* @__PURE__ */ jsxRuntimeExports.jsx(ToolUseBlock, { name: block.name, input: block.input });
@@ -1907,7 +1908,10 @@ function getStatusClasses(category) {
1907
1908
  }
1908
1909
  function parseResponse(text, apiFormat) {
1909
1910
  try {
1910
- const json = JSON.parse(text);
1911
+ let json = JSON.parse(text);
1912
+ if (typeof json === "string") {
1913
+ json = JSON.parse(json);
1914
+ }
1911
1915
  if (apiFormat === "openai") {
1912
1916
  const result2 = parseOpenAIResponse(text);
1913
1917
  if (result2) return result2;
@@ -85,7 +85,7 @@ function getResponse() {
85
85
  }
86
86
  var HEADERS = { TSS_SHELL: "X-TSS_SHELL" };
87
87
  async function getStartManifest(matchedRoutes) {
88
- const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-Crwqisvn.mjs");
88
+ const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-DKfW4gRz.mjs");
89
89
  const startManifest = tsrStartManifest();
90
90
  let routes = startManifest.routes;
91
91
  routes[rootRouteId];
@@ -1157,7 +1157,7 @@ var getBaseManifest = getProdBaseManifest;
1157
1157
  var createEarlyHintsForRequest = createEarlyHintsCollector;
1158
1158
  async function loadEntries() {
1159
1159
  const [routerEntry, startEntry, pluginAdapters] = await Promise.all([
1160
- import("./router-CChl8Zb8.mjs").then((n) => n.r),
1160
+ import("./router-DRA0j7Zv.mjs").then((n) => n.r),
1161
1161
  import("./start-HYkvq4Ni.mjs"),
1162
1162
  import("./empty-plugin-adapters-BFgPZ6_d.mjs")
1163
1163
  ]);
@@ -66,7 +66,7 @@ function RootDocument({ children }) {
66
66
  ] })
67
67
  ] });
68
68
  }
69
- const $$splitComponentImporter = () => import("./index-ByYDXUrF.mjs");
69
+ const $$splitComponentImporter = () => import("./index-BWMVJy33.mjs");
70
70
  const Route$g = createFileRoute("/")({
71
71
  component: lazyRouteComponent($$splitComponentImporter, "component")
72
72
  });
@@ -346,6 +346,11 @@ const ThinkingContentBlock = object({
346
346
  thinking: string(),
347
347
  signature: string().optional()
348
348
  });
349
+ const ThinkContentBlock = object({
350
+ type: literal("think"),
351
+ thinking: string(),
352
+ signature: string().optional()
353
+ });
349
354
  const ImageSourceBlock = object({
350
355
  type: literal("base64"),
351
356
  media_type: string(),
@@ -419,6 +424,7 @@ const AnthropicRequestSchema = object({
419
424
  const ResponseContentBlock = discriminatedUnion("type", [
420
425
  TextContentBlock,
421
426
  ThinkingContentBlock,
427
+ ThinkContentBlock,
422
428
  ToolUseContentBlock
423
429
  ]);
424
430
  const ResponseUsageSchema = object({
@@ -434,7 +440,7 @@ const AnthropicResponseSchema$1 = object({
434
440
  role: literal("assistant"),
435
441
  content: array(ResponseContentBlock),
436
442
  stop_reason: string().nullable(),
437
- stop_sequence: string().nullable(),
443
+ stop_sequence: string().nullable().optional(),
438
444
  usage: ResponseUsageSchema
439
445
  }).passthrough();
440
446
  const SseMessageStartEvent = object({
@@ -1068,6 +1074,11 @@ function finalizeBlock(block) {
1068
1074
  if (block.signature !== "") out.signature = block.signature;
1069
1075
  return out;
1070
1076
  }
1077
+ case "think": {
1078
+ const out = { type: "think", thinking: block.thinking };
1079
+ if (block.signature !== "") out.signature = block.signature;
1080
+ return out;
1081
+ }
1071
1082
  case "tool_use":
1072
1083
  return {
1073
1084
  type: "tool_use",
@@ -1122,21 +1133,32 @@ function extractAnthropicStream(raw, log, fallbackModel, collectChunks) {
1122
1133
  break;
1123
1134
  case "content_block_start": {
1124
1135
  const cb = data.content_block;
1125
- if (cb.type === "text") {
1126
- blocks.set(data.index, { type: "text", text: cb.text ?? "" });
1127
- } else if (cb.type === "thinking") {
1128
- blocks.set(data.index, {
1129
- type: "thinking",
1130
- thinking: cb.thinking ?? "",
1131
- signature: cb.signature ?? ""
1132
- });
1133
- } else {
1134
- blocks.set(data.index, {
1135
- type: "tool_use",
1136
- id: cb.id,
1137
- name: cb.name,
1138
- inputJson: ""
1139
- });
1136
+ switch (cb.type) {
1137
+ case "text":
1138
+ blocks.set(data.index, { type: "text", text: cb.text ?? "" });
1139
+ break;
1140
+ case "thinking":
1141
+ blocks.set(data.index, {
1142
+ type: "thinking",
1143
+ thinking: cb.thinking ?? "",
1144
+ signature: cb.signature ?? ""
1145
+ });
1146
+ break;
1147
+ case "think":
1148
+ blocks.set(data.index, {
1149
+ type: "think",
1150
+ thinking: cb.thinking ?? "",
1151
+ signature: cb.signature ?? ""
1152
+ });
1153
+ break;
1154
+ case "tool_use":
1155
+ blocks.set(data.index, {
1156
+ type: "tool_use",
1157
+ id: cb.id,
1158
+ name: cb.name,
1159
+ inputJson: ""
1160
+ });
1161
+ break;
1140
1162
  }
1141
1163
  break;
1142
1164
  }
@@ -1146,9 +1168,9 @@ function extractAnthropicStream(raw, log, fallbackModel, collectChunks) {
1146
1168
  const delta = data.delta;
1147
1169
  if (delta.type === "text_delta" && block.type === "text") {
1148
1170
  block.text += delta.text;
1149
- } else if (delta.type === "thinking_delta" && block.type === "thinking") {
1171
+ } else if (delta.type === "thinking_delta" && (block.type === "thinking" || block.type === "think")) {
1150
1172
  block.thinking += delta.thinking;
1151
- } else if (delta.type === "signature_delta" && block.type === "thinking") {
1173
+ } else if (delta.type === "signature_delta" && (block.type === "thinking" || block.type === "think")) {
1152
1174
  block.signature += delta.signature;
1153
1175
  } else if (delta.type === "input_json_delta" && block.type === "tool_use") {
1154
1176
  block.inputJson += delta.partial_json;
@@ -1,4 +1,4 @@
1
- const tsrStartManifest = () => ({ routes: { __root__: { filePath: "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", children: ["/", "/api/config", "/api/health", "/api/logs", "/api/models", "/api/providers", "/api/sessions", "/proxy/$"], preloads: ["/assets/index-CKy7R8oW.js"], scripts: [{ attrs: { type: "module", async: true, src: "/assets/index-CKy7R8oW.js" } }] }, "/": { filePath: "C:/Users/claw/workspace/llm-inspector/src/routes/index.tsx", children: void 0, preloads: ["/assets/index-CSRjLK1k.js"] } } });
1
+ const tsrStartManifest = () => ({ routes: { __root__: { filePath: "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", children: ["/", "/api/config", "/api/health", "/api/logs", "/api/models", "/api/providers", "/api/sessions", "/proxy/$"], preloads: ["/assets/index-Do7wdaYZ.js"], scripts: [{ attrs: { type: "module", async: true, src: "/assets/index-Do7wdaYZ.js" } }] }, "/": { filePath: "C:/Users/claw/workspace/llm-inspector/src/routes/index.tsx", children: void 0, preloads: ["/assets/index-CjjXIYIt.js"] } } });
2
2
  export {
3
3
  tsrStartManifest
4
4
  };
@@ -38,51 +38,51 @@ const assets = {
38
38
  "/assets/alibaba-TTwafVwX.svg": {
39
39
  "type": "image/svg+xml",
40
40
  "etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
41
- "mtime": "2026-06-06T09:31:31.372Z",
41
+ "mtime": "2026-06-08T00:49:07.051Z",
42
42
  "size": 5915,
43
43
  "path": "../public/assets/alibaba-TTwafVwX.svg"
44
44
  },
45
- "/assets/index-BpKPXEcb.css": {
46
- "type": "text/css; charset=utf-8",
47
- "etag": '"11628-5GjLelHqc7BEfGB/7qUFPt5/gyM"',
48
- "mtime": "2026-06-06T09:31:31.372Z",
49
- "size": 71208,
50
- "path": "../public/assets/index-BpKPXEcb.css"
51
- },
52
45
  "/assets/minimax-BPMzvuL-.jpeg": {
53
46
  "type": "image/jpeg",
54
47
  "etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
55
- "mtime": "2026-06-06T09:31:31.372Z",
48
+ "mtime": "2026-06-08T00:49:07.048Z",
56
49
  "size": 6918,
57
50
  "path": "../public/assets/minimax-BPMzvuL-.jpeg"
58
51
  },
59
- "/assets/index-CKy7R8oW.js": {
60
- "type": "text/javascript; charset=utf-8",
61
- "etag": '"5103c-DuZfMWELeZa9mIZKPKG6FD5Y+uE"',
62
- "mtime": "2026-06-06T09:31:31.372Z",
63
- "size": 331836,
64
- "path": "../public/assets/index-CKy7R8oW.js"
52
+ "/assets/index-BpKPXEcb.css": {
53
+ "type": "text/css; charset=utf-8",
54
+ "etag": '"11628-5GjLelHqc7BEfGB/7qUFPt5/gyM"',
55
+ "mtime": "2026-06-08T00:49:07.051Z",
56
+ "size": 71208,
57
+ "path": "../public/assets/index-BpKPXEcb.css"
65
58
  },
66
59
  "/assets/zhipuai-BPNAnxo-.svg": {
67
60
  "type": "image/svg+xml",
68
61
  "etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
69
- "mtime": "2026-06-06T09:31:31.370Z",
62
+ "mtime": "2026-06-08T00:49:07.051Z",
70
63
  "size": 11256,
71
64
  "path": "../public/assets/zhipuai-BPNAnxo-.svg"
72
65
  },
66
+ "/assets/index-Do7wdaYZ.js": {
67
+ "type": "text/javascript; charset=utf-8",
68
+ "etag": '"5103c-aaFcAP7Accy+WRst7gdyeAfO198"',
69
+ "mtime": "2026-06-08T00:49:07.051Z",
70
+ "size": 331836,
71
+ "path": "../public/assets/index-Do7wdaYZ.js"
72
+ },
73
73
  "/assets/qwen-CONDcHqt.png": {
74
74
  "type": "image/png",
75
75
  "etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
76
- "mtime": "2026-06-06T09:31:31.372Z",
76
+ "mtime": "2026-06-08T00:49:07.051Z",
77
77
  "size": 357059,
78
78
  "path": "../public/assets/qwen-CONDcHqt.png"
79
79
  },
80
- "/assets/index-CSRjLK1k.js": {
80
+ "/assets/index-CjjXIYIt.js": {
81
81
  "type": "text/javascript; charset=utf-8",
82
- "etag": '"8b887-aEaYFR9Qp5UrFg7NUdOU4Zrq+D4"',
83
- "mtime": "2026-06-06T09:31:31.373Z",
84
- "size": 571527,
85
- "path": "../public/assets/index-CSRjLK1k.js"
82
+ "etag": '"8b905-rdaof1vYelA3ENck4MON8W7NPww"',
83
+ "mtime": "2026-06-08T00:49:07.051Z",
84
+ "size": 571653,
85
+ "path": "../public/assets/index-CjjXIYIt.js"
86
86
  }
87
87
  };
88
88
  function readAsset(id) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonyclaw/llm-inspector",
3
- "version": "1.11.3",
3
+ "version": "1.11.4",
4
4
  "type": "module",
5
5
  "description": "LLM API proxy inspector — captures and displays requests/responses from AI coding tools in a web UI",
6
6
  "license": "MIT",
@@ -41,7 +41,11 @@ function parseResponse(
41
41
  apiFormat: "anthropic" | "openai" | "unknown" | undefined,
42
42
  ): InspectorResponse | OpenAIResponse | null {
43
43
  try {
44
- const json: unknown = JSON.parse(text);
44
+ let json: unknown = JSON.parse(text);
45
+ // Handle double-encoded JSON (some providers send response body as JSON-encoded string)
46
+ if (typeof json === "string") {
47
+ json = JSON.parse(json);
48
+ }
45
49
  if (apiFormat === "openai") {
46
50
  const result = parseOpenAIResponse(text);
47
51
  if (result) return result;
@@ -163,6 +163,7 @@ export function ResponseContentBlockRenderer({
163
163
  case "text":
164
164
  return <TextBlock text={block.text} />;
165
165
  case "thinking":
166
+ case "think":
166
167
  return <ThinkingBlock thinking={block.thinking} />;
167
168
  case "tool_use":
168
169
  return <ToolUseBlock name={block.name} input={block.input} />;
@@ -19,6 +19,12 @@ const ThinkingContentBlock = z.object({
19
19
  signature: z.string().optional(),
20
20
  });
21
21
 
22
+ const ThinkContentBlock = z.object({
23
+ type: z.literal("think"),
24
+ thinking: z.string(),
25
+ signature: z.string().optional(),
26
+ });
27
+
22
28
  const ImageSourceBlock = z.object({
23
29
  type: z.literal("base64"),
24
30
  media_type: z.string(),
@@ -107,6 +113,7 @@ export const AnthropicRequestSchema = z.object({
107
113
  const ResponseContentBlock = z.discriminatedUnion("type", [
108
114
  TextContentBlock,
109
115
  ThinkingContentBlock,
116
+ ThinkContentBlock,
110
117
  ToolUseContentBlock,
111
118
  ]);
112
119
 
@@ -127,7 +134,7 @@ export const AnthropicResponseSchema = z
127
134
  role: z.literal("assistant"),
128
135
  content: z.array(ResponseContentBlock),
129
136
  stop_reason: z.string().nullable(),
130
- stop_sequence: z.string().nullable(),
137
+ stop_sequence: z.string().nullable().optional(),
131
138
  usage: ResponseUsageSchema,
132
139
  })
133
140
  .passthrough(); // Allow extra unknown fields
@@ -4,8 +4,9 @@ import { SseEventSchema } from "./schemas";
4
4
 
5
5
  type StreamTextBlock = { type: "text"; text: string };
6
6
  type StreamThinkingBlock = { type: "thinking"; thinking: string; signature: string };
7
+ type StreamThinkBlock = { type: "think"; thinking: string; signature: string };
7
8
  type StreamToolUseBlock = { type: "tool_use"; id: string; name: string; inputJson: string };
8
- type StreamBlock = StreamTextBlock | StreamThinkingBlock | StreamToolUseBlock;
9
+ type StreamBlock = StreamTextBlock | StreamThinkingBlock | StreamThinkBlock | StreamToolUseBlock;
9
10
 
10
11
  function parseInputJson(json: string): Record<string, unknown> {
11
12
  if (json === "") return {};
@@ -29,6 +30,11 @@ function finalizeBlock(block: StreamBlock): Record<string, unknown> {
29
30
  if (block.signature !== "") out.signature = block.signature;
30
31
  return out;
31
32
  }
33
+ case "think": {
34
+ const out: Record<string, unknown> = { type: "think", thinking: block.thinking };
35
+ if (block.signature !== "") out.signature = block.signature;
36
+ return out;
37
+ }
32
38
  case "tool_use":
33
39
  return {
34
40
  type: "tool_use",
@@ -98,21 +104,32 @@ export function extractAnthropicStream(
98
104
  break;
99
105
  case "content_block_start": {
100
106
  const cb = data.content_block;
101
- if (cb.type === "text") {
102
- blocks.set(data.index, { type: "text", text: cb.text ?? "" });
103
- } else if (cb.type === "thinking") {
104
- blocks.set(data.index, {
105
- type: "thinking",
106
- thinking: cb.thinking ?? "",
107
- signature: cb.signature ?? "",
108
- });
109
- } else {
110
- blocks.set(data.index, {
111
- type: "tool_use",
112
- id: cb.id,
113
- name: cb.name,
114
- inputJson: "",
115
- });
107
+ switch (cb.type) {
108
+ case "text":
109
+ blocks.set(data.index, { type: "text", text: cb.text ?? "" });
110
+ break;
111
+ case "thinking":
112
+ blocks.set(data.index, {
113
+ type: "thinking",
114
+ thinking: cb.thinking ?? "",
115
+ signature: cb.signature ?? "",
116
+ });
117
+ break;
118
+ case "think":
119
+ blocks.set(data.index, {
120
+ type: "think",
121
+ thinking: cb.thinking ?? "",
122
+ signature: cb.signature ?? "",
123
+ });
124
+ break;
125
+ case "tool_use":
126
+ blocks.set(data.index, {
127
+ type: "tool_use",
128
+ id: cb.id,
129
+ name: cb.name,
130
+ inputJson: "",
131
+ });
132
+ break;
116
133
  }
117
134
  break;
118
135
  }
@@ -122,9 +139,15 @@ export function extractAnthropicStream(
122
139
  const delta = data.delta;
123
140
  if (delta.type === "text_delta" && block.type === "text") {
124
141
  block.text += delta.text;
125
- } else if (delta.type === "thinking_delta" && block.type === "thinking") {
142
+ } else if (
143
+ delta.type === "thinking_delta" &&
144
+ (block.type === "thinking" || block.type === "think")
145
+ ) {
126
146
  block.thinking += delta.thinking;
127
- } else if (delta.type === "signature_delta" && block.type === "thinking") {
147
+ } else if (
148
+ delta.type === "signature_delta" &&
149
+ (block.type === "thinking" || block.type === "think")
150
+ ) {
128
151
  block.signature += delta.signature;
129
152
  } else if (delta.type === "input_json_delta" && block.type === "tool_use") {
130
153
  block.inputJson += delta.partial_json;