@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.
- package/.output/cli.js +1 -0
- package/.output/nitro.json +1 -1
- package/.output/public/assets/index-BmkN9DxE.js +107 -0
- package/.output/public/assets/index-DPe3eOih.css +1 -0
- package/.output/public/assets/{main-BLYgekFx.js → main-BjnjXVBU.js} +1 -1
- package/.output/server/_libs/diff.mjs +2 -2
- package/.output/server/_ssr/{index-P66uoVEU.mjs → index-BIOEVAzU.mjs} +783 -588
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-DpLCKk51.mjs → router-THS9ptvu.mjs} +439 -177
- package/.output/server/{_tanstack-start-manifest_v-C9Wq6YdJ.mjs → _tanstack-start-manifest_v-BYhN7q_z.mjs} +1 -1
- package/.output/server/index.mjs +31 -31
- package/README.md +200 -113
- package/package.json +1 -1
- package/src/cli.ts +1 -0
- package/src/components/ProxyViewer.tsx +77 -85
- package/src/components/ProxyViewerContainer.tsx +148 -76
- package/src/components/providers/ImportWizardDialog.tsx +27 -3
- package/src/components/proxy-viewer/CompareDrawer.tsx +17 -4
- package/src/components/proxy-viewer/ConversationGroup.tsx +15 -47
- package/src/components/proxy-viewer/ConversationHeader.tsx +58 -5
- package/src/components/proxy-viewer/LogEntry.tsx +297 -329
- package/src/components/proxy-viewer/LogEntryHeader.tsx +126 -137
- package/src/components/proxy-viewer/ResponseView.tsx +14 -34
- package/src/components/proxy-viewer/StreamingChunkSequence.tsx +3 -3
- package/src/components/proxy-viewer/TurnGroup.tsx +25 -21
- package/src/components/proxy-viewer/diff/DiffView.tsx +5 -3
- package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +13 -9
- package/src/components/proxy-viewer/formats/anthropic/ResponseView.tsx +3 -3
- package/src/components/proxy-viewer/formats/index.tsx +19 -10
- package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +7 -3
- package/src/components/proxy-viewer/log-formats/anthropic.ts +48 -0
- package/src/components/proxy-viewer/log-formats/index.ts +23 -0
- package/src/components/proxy-viewer/log-formats/openai.ts +40 -0
- package/src/components/proxy-viewer/log-formats/types.ts +33 -0
- package/src/components/proxy-viewer/log-formats/unknown.ts +14 -0
- package/src/components/proxy-viewer/viewerState.ts +58 -0
- package/src/components/ui/json-viewer.tsx +3 -3
- package/src/lib/objectUtils.ts +22 -0
- package/src/proxy/claudeCodeStrip.ts +5 -8
- package/src/proxy/formats/index.ts +1 -1
- package/src/proxy/formats/registry.ts +9 -0
- package/src/proxy/handler.ts +2 -8
- package/src/proxy/logIndex.ts +58 -43
- package/src/proxy/logger.ts +51 -27
- package/src/proxy/openaiOrphanToolStrip.ts +11 -17
- package/src/proxy/providerImporters.ts +245 -19
- package/src/proxy/providers.ts +20 -7
- package/src/proxy/schemas.ts +5 -9
- package/src/proxy/socketTracker.ts +109 -78
- package/src/proxy/store.ts +68 -83
- package/src/routes/api/logs.ts +31 -2
- package/styles/globals.css +22 -0
- package/.output/public/assets/index-CMuJQyt1.js +0 -105
- package/.output/public/assets/index-DciyfYBk.css +0 -1
|
@@ -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/mcp", "/api/models", "/api/providers", "/api/sessions", "/proxy/$"], "preloads": ["/assets/main-
|
|
1
|
+
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", "children": ["/", "/api/config", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/providers", "/api/sessions", "/proxy/$"], "preloads": ["/assets/main-BjnjXVBU.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-BmkN9DxE.js"] }, "/api/config": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/config.ts", "children": ["/api/config/paths"] }, "/api/health": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/health.ts" }, "/api/logs": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.ts", "children": ["/api/logs/$id", "/api/logs/stream"] }, "/api/mcp": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/mcp.ts" }, "/api/models": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/models.ts" }, "/api/providers": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.ts", "children": ["/api/providers/$providerId", "/api/providers/export", "/api/providers/import", "/api/providers/scan"] }, "/api/sessions": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/sessions.ts" }, "/proxy/$": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/proxy/$.ts" }, "/api/config/paths": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/config.paths.ts" }, "/api/logs/$id": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.ts", "children": ["/api/logs/$id/chunks", "/api/logs/$id/replay"] }, "/api/logs/stream": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.stream.ts" }, "/api/providers/$providerId": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.ts", "children": ["/api/providers/$providerId/test"] }, "/api/providers/export": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.export.ts" }, "/api/providers/import": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.import.ts" }, "/api/providers/scan": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.scan.ts" }, "/api/logs/$id/chunks": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.chunks.ts" }, "/api/logs/$id/replay": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.replay.ts" }, "/api/providers/$providerId/test": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.test.ts", "children": ["/api/providers/$providerId/test/log"] }, "/api/providers/$providerId/test/log": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.test.log.ts" } }, "clientEntry": "/assets/main-BjnjXVBU.js" });
|
|
2
2
|
export {
|
|
3
3
|
tsrStartManifest
|
|
4
4
|
};
|
package/.output/server/index.mjs
CHANGED
|
@@ -35,54 +35,54 @@ const headers = ((m) => function headersRouteRule(event) {
|
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
37
|
const assets = {
|
|
38
|
-
"/assets/index-DciyfYBk.css": {
|
|
39
|
-
"type": "text/css; charset=utf-8",
|
|
40
|
-
"etag": '"15867-TOX1Gddns0p3jKt+7co1NuZS+d8"',
|
|
41
|
-
"mtime": "2026-06-12T07:17:56.431Z",
|
|
42
|
-
"size": 88167,
|
|
43
|
-
"path": "../public/assets/index-DciyfYBk.css"
|
|
44
|
-
},
|
|
45
38
|
"/assets/alibaba-TTwafVwX.svg": {
|
|
46
39
|
"type": "image/svg+xml",
|
|
47
40
|
"etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
|
|
48
|
-
"mtime": "2026-06-
|
|
41
|
+
"mtime": "2026-06-13T05:45:10.081Z",
|
|
49
42
|
"size": 5915,
|
|
50
43
|
"path": "../public/assets/alibaba-TTwafVwX.svg"
|
|
51
44
|
},
|
|
52
|
-
"/assets/
|
|
45
|
+
"/assets/index-DPe3eOih.css": {
|
|
46
|
+
"type": "text/css; charset=utf-8",
|
|
47
|
+
"etag": '"15a32-YUlUFJPXe5WrOzMkLVz9gOyERE4"',
|
|
48
|
+
"mtime": "2026-06-13T05:45:10.081Z",
|
|
49
|
+
"size": 88626,
|
|
50
|
+
"path": "../public/assets/index-DPe3eOih.css"
|
|
51
|
+
},
|
|
52
|
+
"/assets/qwen-CONDcHqt.png": {
|
|
53
|
+
"type": "image/png",
|
|
54
|
+
"etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
|
|
55
|
+
"mtime": "2026-06-13T05:45:10.081Z",
|
|
56
|
+
"size": 357059,
|
|
57
|
+
"path": "../public/assets/qwen-CONDcHqt.png"
|
|
58
|
+
},
|
|
59
|
+
"/assets/main-BjnjXVBU.js": {
|
|
53
60
|
"type": "text/javascript; charset=utf-8",
|
|
54
|
-
"etag": '"50599-
|
|
55
|
-
"mtime": "2026-06-
|
|
61
|
+
"etag": '"50599-TBFFt8m3KX+84o0h5FGqLcw9zvM"',
|
|
62
|
+
"mtime": "2026-06-13T05:45:10.081Z",
|
|
56
63
|
"size": 329113,
|
|
57
|
-
"path": "../public/assets/main-
|
|
58
|
-
},
|
|
59
|
-
"/assets/zhipuai-BPNAnxo-.svg": {
|
|
60
|
-
"type": "image/svg+xml",
|
|
61
|
-
"etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
|
|
62
|
-
"mtime": "2026-06-12T07:17:56.431Z",
|
|
63
|
-
"size": 11256,
|
|
64
|
-
"path": "../public/assets/zhipuai-BPNAnxo-.svg"
|
|
64
|
+
"path": "../public/assets/main-BjnjXVBU.js"
|
|
65
65
|
},
|
|
66
66
|
"/assets/minimax-BPMzvuL-.jpeg": {
|
|
67
67
|
"type": "image/jpeg",
|
|
68
68
|
"etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
|
|
69
|
-
"mtime": "2026-06-
|
|
69
|
+
"mtime": "2026-06-13T05:45:10.078Z",
|
|
70
70
|
"size": 6918,
|
|
71
71
|
"path": "../public/assets/minimax-BPMzvuL-.jpeg"
|
|
72
72
|
},
|
|
73
|
-
"/assets/
|
|
74
|
-
"type": "image/
|
|
75
|
-
"etag": '"
|
|
76
|
-
"mtime": "2026-06-
|
|
77
|
-
"size":
|
|
78
|
-
"path": "../public/assets/
|
|
73
|
+
"/assets/zhipuai-BPNAnxo-.svg": {
|
|
74
|
+
"type": "image/svg+xml",
|
|
75
|
+
"etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
|
|
76
|
+
"mtime": "2026-06-13T05:45:10.081Z",
|
|
77
|
+
"size": 11256,
|
|
78
|
+
"path": "../public/assets/zhipuai-BPNAnxo-.svg"
|
|
79
79
|
},
|
|
80
|
-
"/assets/index-
|
|
80
|
+
"/assets/index-BmkN9DxE.js": {
|
|
81
81
|
"type": "text/javascript; charset=utf-8",
|
|
82
|
-
"etag": '"
|
|
83
|
-
"mtime": "2026-06-
|
|
84
|
-
"size":
|
|
85
|
-
"path": "../public/assets/index-
|
|
82
|
+
"etag": '"9ae0c-h7IO5tRUMmZre12bMt7hEiFWLhQ"',
|
|
83
|
+
"mtime": "2026-06-13T05:45:10.081Z",
|
|
84
|
+
"size": 634380,
|
|
85
|
+
"path": "../public/assets/index-BmkN9DxE.js"
|
|
86
86
|
}
|
|
87
87
|
};
|
|
88
88
|
function readAsset(id) {
|
package/README.md
CHANGED
|
@@ -1,34 +1,36 @@
|
|
|
1
1
|
# llm-inspector
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
透明捕获、解析和重放 AI 编码工具的 LLM API 流量。
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
`llm-inspector` 是一个运行在本机的 HTTP 代理和 Web 调试器。将 Claude Code、OpenCode、Cursor、Cody 或其他兼容客户端的 API Base URL 指向它,即可实时查看请求、响应、工具调用、Thinking、SSE chunks 和 Token 用量。
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
默认地址:
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
- SSE 流式数据块 (Streaming Chunks)
|
|
15
|
-
- Token 用量 (Token Usage)
|
|
11
|
+
- Web UI:`http://localhost:25947`
|
|
12
|
+
- 代理入口:`http://localhost:25947/proxy`
|
|
13
|
+
- MCP Server:`http://localhost:25947/api/mcp`
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
## 功能
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
- 同时支持 Anthropic Messages API 和 OpenAI Chat Completions API
|
|
18
|
+
- 分开解析两种协议的请求、响应、Thinking、Answer 和 Tool Call
|
|
19
|
+
- 按请求路径识别协议:
|
|
20
|
+
- `/proxy/v1/messages` -> Anthropic
|
|
21
|
+
- `/proxy/v1/chat/completions` -> OpenAI
|
|
22
|
+
- 实时捕获普通响应和 SSE 流式响应
|
|
23
|
+
- 查看原始/处理后的 Headers 和 Request Diff
|
|
24
|
+
- 比较同一会话、同一协议的相邻请求
|
|
25
|
+
- 请求 Replay、日志 ZIP 导出和按会话/模型筛选
|
|
26
|
+
- 会话分组、Turn 边界、缓存 Token 趋势和 Token 汇总
|
|
27
|
+
- 提供商管理、双协议 URL、连接测试、导入与导出
|
|
28
|
+
- 记录客户端 PID、工作目录和项目目录,便于定位请求来源
|
|
29
|
+
- 内置 MCP Server,让 Coding Agent 直接查询日志和管理提供商
|
|
20
30
|
|
|
21
|
-
|
|
22
|
-
|------|------|
|
|
23
|
-
| **透明代理、零侵入** | 只需设置环境变量即可拦截所有流量,无需修改 AI 编程工具本身 |
|
|
24
|
-
| **结构化 API 可视化** | 交互式 JSON 树查看器,自动解析并渲染 Markdown 文本、思考块、工具调用块 |
|
|
25
|
-
| **完整的 SSE 流式解析** | 捕获并重建每个流式事件,原始事件时间线一目了然 |
|
|
26
|
-
| **Token 用量实时追踪** | 单请求 + 会话级 + 全局级 Token 统计 |
|
|
27
|
-
| **多提供商自动路由** | 支持 Anthropic、OpenAI、DeepSeek、MiniMax、Qwen、ZhipuAI,自动识别格式和认证 |
|
|
28
|
-
| **客户端进程追踪** | 自动关联 PID、工作目录、项目文件夹,区分请求来源 |
|
|
29
|
-
| **持久化存储 + 导出** | 磁盘日志存储 + ZIP 导出,支持离线分析 |
|
|
31
|
+

|
|
30
32
|
|
|
31
|
-
##
|
|
33
|
+
## 快速开始
|
|
32
34
|
|
|
33
35
|
### npm 安装
|
|
34
36
|
|
|
@@ -37,93 +39,145 @@ npm install -g @tonyclaw/llm-inspector
|
|
|
37
39
|
llm-inspector
|
|
38
40
|
```
|
|
39
41
|
|
|
42
|
+
启动后会自动打开浏览器。也可以使用:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
llm-inspector --no-open
|
|
46
|
+
llm-inspector --port 3000
|
|
47
|
+
llm-inspector --config-dir ./local-config
|
|
48
|
+
```
|
|
49
|
+
|
|
40
50
|
### Docker
|
|
41
51
|
|
|
42
52
|
```bash
|
|
43
|
-
cd docker
|
|
53
|
+
cd docker
|
|
54
|
+
docker compose up -d
|
|
44
55
|
```
|
|
45
56
|
|
|
46
57
|
### 源码运行
|
|
47
58
|
|
|
59
|
+
需要安装 [Bun](https://bun.sh/)。
|
|
60
|
+
|
|
48
61
|
```bash
|
|
49
62
|
bun install
|
|
50
63
|
bun run dev
|
|
51
64
|
```
|
|
52
65
|
|
|
53
|
-
|
|
66
|
+
## 配置提供商
|
|
67
|
+
|
|
68
|
+
打开 Web UI,进入 **Settings** 添加提供商:
|
|
54
69
|
|
|
55
|
-
|
|
70
|
+
1. 填写提供商名称和 API Key。
|
|
71
|
+
2. 添加一个或多个模型名称。代理使用模型名称匹配提供商。
|
|
72
|
+
3. 按实际能力填写协议 URL:
|
|
73
|
+
- **Anthropic Base URL**:例如 `https://api.anthropic.com`
|
|
74
|
+
- **OpenAI Base URL**:例如 `https://api.openai.com`
|
|
75
|
+
4. 选择认证方式:`Bearer` 或 `x-api-key`。
|
|
76
|
+
5. 使用 Provider Test 分别验证流式和非流式请求。
|
|
56
77
|
|
|
57
|
-
|
|
78
|
+
同一个提供商可以同时配置 Anthropic 和 OpenAI URL。代理会根据客户端请求路径选择协议与上游地址,而不是根据请求 body 猜测格式。
|
|
79
|
+
|
|
80
|
+
## 接入 AI 编码工具
|
|
81
|
+
|
|
82
|
+
### Claude Code
|
|
83
|
+
|
|
84
|
+
macOS / Linux:
|
|
58
85
|
|
|
59
86
|
```bash
|
|
60
|
-
# Claude Code
|
|
61
87
|
ANTHROPIC_BASE_URL=http://localhost:25947/proxy claude
|
|
88
|
+
```
|
|
62
89
|
|
|
63
|
-
|
|
64
|
-
LLM_BASE_URL=http://localhost:25947/proxy opencode
|
|
90
|
+
Windows PowerShell:
|
|
65
91
|
|
|
66
|
-
|
|
67
|
-
ANTHROPIC_BASE_URL=http://localhost:25947/proxy
|
|
92
|
+
```powershell
|
|
93
|
+
$env:ANTHROPIC_BASE_URL = "http://localhost:25947/proxy"
|
|
94
|
+
claude
|
|
68
95
|
```
|
|
69
96
|
|
|
70
|
-
|
|
97
|
+
如果 API Key 已保存在 llm-inspector 的提供商配置中,客户端令牌可以留空:
|
|
71
98
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
99
|
+
```powershell
|
|
100
|
+
$env:ANTHROPIC_AUTH_TOKEN = ""
|
|
101
|
+
```
|
|
75
102
|
|
|
76
|
-
|
|
103
|
+
### OpenCode 和其他客户端
|
|
77
104
|
|
|
78
|
-
|
|
105
|
+
不同客户端使用的环境变量名称不同。将其 Anthropic 或 OpenAI Base URL 设置为:
|
|
79
106
|
|
|
80
|
-
|
|
107
|
+
```text
|
|
108
|
+
http://localhost:25947/proxy
|
|
109
|
+
```
|
|
81
110
|
|
|
82
|
-
|
|
83
|
-
(MCP) server, mounted at `POST http://localhost:25947/api/mcp` on the same port as
|
|
84
|
-
the Web UI. Any MCP-aware Coding Agent running on the same machine can
|
|
85
|
-
discover and invoke 11 `inspector_*` tools to read captured traffic and
|
|
86
|
-
manage provider configuration without a human round-trip.
|
|
111
|
+
例如:
|
|
87
112
|
|
|
88
|
-
|
|
113
|
+
```bash
|
|
114
|
+
LLM_BASE_URL=http://localhost:25947/proxy opencode
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
对于 Cursor、Cody 等工具,请在其设置中修改 API Base URL。
|
|
118
|
+
|
|
119
|
+
## 直接发送请求
|
|
89
120
|
|
|
90
|
-
|
|
121
|
+
请先在 Settings 中配置与 `model` 匹配的提供商。
|
|
91
122
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
123
|
+
### Anthropic 格式
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
curl http://localhost:25947/proxy/v1/messages \
|
|
127
|
+
-H "content-type: application/json" \
|
|
128
|
+
-H "x-api-key: resolved-by-llm-inspector" \
|
|
129
|
+
-d '{
|
|
130
|
+
"model": "claude-sonnet-4-6",
|
|
131
|
+
"max_tokens": 128,
|
|
132
|
+
"messages": [{"role": "user", "content": "Hello"}]
|
|
133
|
+
}'
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### OpenAI 格式
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
curl http://localhost:25947/proxy/v1/chat/completions \
|
|
140
|
+
-H "content-type: application/json" \
|
|
141
|
+
-H "authorization: Bearer resolved-by-llm-inspector" \
|
|
142
|
+
-d '{
|
|
143
|
+
"model": "gpt-4o-mini",
|
|
144
|
+
"max_tokens": 128,
|
|
145
|
+
"messages": [{"role": "user", "content": "Hello"}]
|
|
146
|
+
}'
|
|
147
|
+
```
|
|
100
148
|
|
|
101
|
-
|
|
149
|
+
## 使用查看器
|
|
102
150
|
|
|
103
|
-
|
|
104
|
-
|------|---------|
|
|
105
|
-
| `inspector_get_provider` | Full `ProviderConfig` for a single id, `apiKey` in plaintext. |
|
|
106
|
-
| `inspector_replay_log` | Re-send a captured request body to its upstream and return the response summary. |
|
|
151
|
+
### Simple / Full
|
|
107
152
|
|
|
108
|
-
**
|
|
153
|
+
- **Simple**:聚焦 Request 和解析后的 Response。
|
|
154
|
+
- **Full**:额外显示 Raw Headers、Headers、Raw Request、Raw Response 和 SSE chunks。
|
|
109
155
|
|
|
110
|
-
|
|
111
|
-
|------|---------|
|
|
112
|
-
| `inspector_add_provider` | Persist a new provider to `<dataDir>/providers.json`. |
|
|
113
|
-
| `inspector_update_provider` | Patch-style update of an existing provider. |
|
|
114
|
-
| `inspector_test_provider` | Run the UI's connectivity test against a provider. |
|
|
156
|
+
### Thinking 与 Answer
|
|
115
157
|
|
|
116
|
-
|
|
158
|
+
查看器按协议分别解析响应:
|
|
117
159
|
|
|
118
|
-
- `
|
|
119
|
-
- `
|
|
120
|
-
- `get_runtime_config` / `set_runtime_config` — runtime policy surface; UI is the source of truth.
|
|
160
|
+
- Anthropic:`content[].type === "thinking"` 与 `content[].type === "text"`
|
|
161
|
+
- OpenAI:`reasoning_content`、`thinking`、`think` 与 `message.content`
|
|
121
162
|
|
|
122
|
-
|
|
163
|
+
Thinking 和最终 Answer 会分区显示。如果响应因 `max_tokens` 提前结束且只返回 Thinking,界面只展示真实存在的 Thinking,不会生成不存在的 Answer。
|
|
123
164
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
165
|
+
### Diff 与 Replay
|
|
166
|
+
|
|
167
|
+
- **Diff with Raw**:比较代理处理前后的 Request 或 Headers。
|
|
168
|
+
- **Diff with Previous**:比较同一会话、同一协议中的相邻请求。
|
|
169
|
+
- **Replay**:使用当前提供商配置重新发送历史请求。
|
|
170
|
+
- **Export**:将捕获日志导出为 ZIP,供离线分析。
|
|
171
|
+
|
|
172
|
+
## MCP Server
|
|
173
|
+
|
|
174
|
+
内置 MCP Server 使用 HTTP Streamable transport:
|
|
175
|
+
|
|
176
|
+
```text
|
|
177
|
+
POST http://localhost:25947/api/mcp
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Claude Code `.mcp.json` 示例:
|
|
127
181
|
|
|
128
182
|
```json
|
|
129
183
|
{
|
|
@@ -136,49 +190,82 @@ example, in Claude Code's `.mcp.json`:
|
|
|
136
190
|
}
|
|
137
191
|
```
|
|
138
192
|
|
|
139
|
-
|
|
193
|
+
提供 11 个 `inspector_*` 工具:
|
|
194
|
+
|
|
195
|
+
| 类型 | 工具 |
|
|
196
|
+
| --- | --- |
|
|
197
|
+
| 日志查询 | `inspector_list_logs`, `inspector_get_log`, `inspector_get_log_chunks` |
|
|
198
|
+
| 索引查询 | `inspector_list_sessions`, `inspector_list_models` |
|
|
199
|
+
| 提供商查询 | `inspector_list_providers`, `inspector_get_provider` |
|
|
200
|
+
| 操作 | `inspector_replay_log`, `inspector_test_provider` |
|
|
201
|
+
| 提供商写入 | `inspector_add_provider`, `inspector_update_provider` |
|
|
202
|
+
|
|
203
|
+
完整说明见 [MCP Server 文档](docs/MCP-Server.md)。
|
|
204
|
+
|
|
205
|
+
> MCP 接口仅应在可信本机环境使用。提供商查询工具会返回明文 API Key,请勿将服务暴露到不可信网络。
|
|
206
|
+
|
|
207
|
+
## 数据目录与环境变量
|
|
208
|
+
|
|
209
|
+
默认数据目录:
|
|
210
|
+
|
|
211
|
+
- Windows:`%USERPROFILE%\.llm-inspector`
|
|
212
|
+
- macOS / Linux:`$HOME/.llm-inspector`
|
|
213
|
+
|
|
214
|
+
常用环境变量:
|
|
215
|
+
|
|
216
|
+
| 变量 | 默认值 | 说明 |
|
|
217
|
+
| --- | --- | --- |
|
|
218
|
+
| `PORT` | `25947` | Web UI 和代理端口 |
|
|
219
|
+
| `LLM_INSPECTOR_DATA_DIR` | 系统默认目录 | providers、runtime config 等数据目录 |
|
|
220
|
+
| `LOG_DIR` | `<dataDir>/logs` | 捕获日志和运行日志目录 |
|
|
221
|
+
| `LOG_RETENTION_DAYS` | `7` | 日志保留天数 |
|
|
222
|
+
| `CHUNKS_DIR` | `<dataDir>/chunks` | SSE chunks 存储目录 |
|
|
223
|
+
|
|
224
|
+
提供商 API Key 以明文 JSON 保存在本机数据目录中。请保护该目录,并避免在共享或不可信主机上运行服务。
|
|
225
|
+
|
|
226
|
+
## HTTP API
|
|
227
|
+
|
|
228
|
+
| Endpoint | Method | 说明 |
|
|
229
|
+
| --- | --- | --- |
|
|
230
|
+
| `/api/health` | GET | 健康检查 |
|
|
231
|
+
| `/api/logs` | GET / DELETE | 查询或清空日志 |
|
|
232
|
+
| `/api/logs/:id` | GET | 获取完整日志 |
|
|
233
|
+
| `/api/logs/:id/chunks` | GET | 获取 SSE chunks |
|
|
234
|
+
| `/api/logs/:id/replay` | POST | 重放请求 |
|
|
235
|
+
| `/api/logs/stream` | GET | 实时日志更新 |
|
|
236
|
+
| `/api/sessions` | GET | 会话列表 |
|
|
237
|
+
| `/api/models` | GET | 模型列表 |
|
|
238
|
+
| `/api/providers` | GET / POST | 查询或添加提供商 |
|
|
239
|
+
| `/api/providers/:id` | GET / PUT / DELETE | 管理单个提供商 |
|
|
240
|
+
| `/api/providers/:id/test` | POST | 测试提供商连接 |
|
|
241
|
+
| `/api/mcp` | POST | MCP HTTP Streamable endpoint |
|
|
242
|
+
|
|
243
|
+
## 开发与验证
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
bun test
|
|
247
|
+
npm run typecheck
|
|
248
|
+
npm run lint
|
|
249
|
+
npm run format:check
|
|
250
|
+
npm run build
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
涉及代理或 UI 的改动还应启动开发服务器,并使用真实 AI 编码工具通过代理完成端到端验证:
|
|
140
254
|
|
|
141
255
|
```bash
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
-H 'accept: application/json, text/event-stream' \
|
|
145
|
-
-d '{
|
|
146
|
-
"jsonrpc": "2.0",
|
|
147
|
-
"id": 1,
|
|
148
|
-
"method": "initialize",
|
|
149
|
-
"params": {
|
|
150
|
-
"protocolVersion": "2025-06-18",
|
|
151
|
-
"capabilities": {},
|
|
152
|
-
"clientInfo": { "name": "my-client", "version": "0.0.0" }
|
|
153
|
-
}
|
|
154
|
-
}'
|
|
256
|
+
bun run dev
|
|
257
|
+
ANTHROPIC_BASE_URL=http://localhost:25947/proxy claude
|
|
155
258
|
```
|
|
156
259
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
- **List limits are hardcoded** at default 3, max 5. Not user-configurable.
|
|
170
|
-
- **Deferred to v1.1** (not in this change): MCP Resources for logs
|
|
171
|
-
(`mcp://llm-inspector/log/{id}`), notifications/subscriptions for live
|
|
172
|
-
log push, filtering out reflexive-loop entries server-side, full-text
|
|
173
|
-
or time-range search, MCP-level auth.
|
|
174
|
-
|
|
175
|
-
---
|
|
176
|
-
|
|
177
|
-
## Documentation / 文档目录
|
|
178
|
-
|
|
179
|
-
- [特性 (Features)](docs/Features.md) - 核心功能介绍
|
|
180
|
-
- [安装 (Installation)](docs/Installation.md) - 安装指南
|
|
181
|
-
- [使用 (Usage)](docs/Usage.md) - 详细使用说明
|
|
182
|
-
- [架构 (Architecture)](docs/Architecture.md) - 系统架构
|
|
183
|
-
- [开发 (Development)](docs/Development.md) - 开发指南
|
|
184
|
-
- [MCP Server](docs/MCP-Server.md) - 把 llm-inspector 当作 MCP 工具接入 Coding Agent
|
|
260
|
+
## 更多文档
|
|
261
|
+
|
|
262
|
+
- [功能介绍](docs/Features.md)
|
|
263
|
+
- [安装指南](docs/Installation.md)
|
|
264
|
+
- [使用说明](docs/Usage.md)
|
|
265
|
+
- [架构说明](docs/Architecture.md)
|
|
266
|
+
- [开发指南](docs/Development.md)
|
|
267
|
+
- [MCP Server](docs/MCP-Server.md)
|
|
268
|
+
|
|
269
|
+
## License
|
|
270
|
+
|
|
271
|
+
MIT
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -126,6 +126,7 @@ console.log(``);
|
|
|
126
126
|
console.log(`Route AI coding tools through the proxy:`);
|
|
127
127
|
console.log(` Claude Code: ANTHROPIC_BASE_URL=${url}/proxy claude`);
|
|
128
128
|
console.log(` OpenCode: LLM_BASE_URL=${url}/proxy opencode`);
|
|
129
|
+
console.log(` MiMo Code: OPENAI_BASE_URL=${url}/proxy mimo`);
|
|
129
130
|
console.log(` Direct HTTP: curl ${url}/proxy/v1/messages -d '{"model":"...","messages":[...]}'`);
|
|
130
131
|
console.log(``);
|
|
131
132
|
console.log(`Routing environment variables:`);
|