luma-mcp 1.3.0 → 1.3.2
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/README.md +142 -17
- package/build/config.d.ts +3 -3
- package/build/config.d.ts.map +1 -1
- package/build/config.js +11 -4
- package/build/config.js.map +1 -1
- package/build/hunyuan-client.d.ts +28 -0
- package/build/hunyuan-client.d.ts.map +1 -0
- package/build/hunyuan-client.js +96 -0
- package/build/hunyuan-client.js.map +1 -0
- package/build/image-processor.d.ts +6 -3
- package/build/image-processor.d.ts.map +1 -1
- package/build/image-processor.js +85 -31
- package/build/image-processor.js.map +1 -1
- package/build/index.d.ts +2 -2
- package/build/index.js +109 -40
- package/build/index.js.map +1 -1
- package/build/qwen-client.d.ts +3 -3
- package/build/qwen-client.js +8 -8
- package/build/qwen-client.js.map +1 -1
- package/build/siliconflow-client.d.ts +1 -1
- package/build/siliconflow-client.js +2 -2
- package/build/siliconflow-client.js.map +1 -1
- package/build/vision-client.d.ts +2 -2
- package/build/vision-client.js +1 -1
- package/build/volcengine-client.d.ts +2 -2
- package/build/volcengine-client.js +4 -4
- package/build/volcengine-client.js.map +1 -1
- package/build/zhipu-client.js +2 -2
- package/build/zhipu-client.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
## 特性
|
|
8
8
|
|
|
9
|
-
- **多模型支持**:
|
|
9
|
+
- **多模型支持**: 支持五个视觉模型
|
|
10
10
|
- GLM-4.6V(智谱清言)- 付费,中文理解优秀
|
|
11
11
|
- DeepSeek-OCR(硅基流动)- **免费使用**,OCR 能力强
|
|
12
12
|
- Qwen3-VL-Flash(阿里云通义千问)- 付费,速度快成本低,支持思考模式
|
|
13
13
|
- Doubao-Seed-1.6(火山方舟)- 付费,性价比高,支持多种版本
|
|
14
|
+
- Hunyuan-Vision-1.5(腾讯混元)- 付费,图文推理强,多语言表现优秀
|
|
14
15
|
- **简单设计**: 单一 `analyze_image` 工具处理所有图片分析任务
|
|
15
16
|
- **智能理解**: 自动识别代码、UI、错误等不同场景
|
|
16
17
|
- **全面支持**: 代码截图、界面设计、错误诊断、OCR 文字识别
|
|
@@ -28,6 +29,7 @@
|
|
|
28
29
|
- **方案 B**: 硅基流动 API Key ([获取地址](https://cloud.siliconflow.cn/)) - **免费使用**,OCR 能力强
|
|
29
30
|
- **方案 C**: 阿里云百炼 API Key ([获取地址](https://bailian.console.aliyun.com/)) - 速度快成本低,支持思考模式
|
|
30
31
|
- **方案 D**: 火山方舟 API Key ([获取地址](https://console.volcengine.com/ark)) - 性价比高,支持多种版本
|
|
32
|
+
- **方案 E**: 腾讯混元 API Key ([获取地址](https://cloud.tencent.com/product/hunyuan)) - 图文推理强,多语言表现优秀
|
|
31
33
|
|
|
32
34
|
### 安装
|
|
33
35
|
|
|
@@ -118,6 +120,26 @@ npx luma-mcp
|
|
|
118
120
|
}
|
|
119
121
|
```
|
|
120
122
|
|
|
123
|
+
**方案 E: 使用腾讯混元 Hunyuan-Vision-1.5**:
|
|
124
|
+
|
|
125
|
+
MODEL_NAME 可选:`hunyuan-t1-vision-20250916`(默认)或 `HY-vision-1.5-instruct`
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"mcpServers": {
|
|
130
|
+
"luma": {
|
|
131
|
+
"command": "npx",
|
|
132
|
+
"args": ["-y", "luma-mcp"],
|
|
133
|
+
"env": {
|
|
134
|
+
"MODEL_PROVIDER": "hunyuan",
|
|
135
|
+
"HUNYUAN_API_KEY": "your-hunyuan-api-key",
|
|
136
|
+
"MODEL_NAME": "hunyuan-t1-vision-20250916"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
121
143
|
**本地开发(智谱)**:
|
|
122
144
|
|
|
123
145
|
```json
|
|
@@ -151,6 +173,24 @@ npx luma-mcp
|
|
|
151
173
|
}
|
|
152
174
|
```
|
|
153
175
|
|
|
176
|
+
**本地开发(腾讯混元)**:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"mcpServers": {
|
|
181
|
+
"luma": {
|
|
182
|
+
"command": "node",
|
|
183
|
+
"args": ["D:\\codes\\luma-mcp\\build\\index.js"],
|
|
184
|
+
"env": {
|
|
185
|
+
"MODEL_PROVIDER": "hunyuan",
|
|
186
|
+
"HUNYUAN_API_KEY": "your-hunyuan-api-key",
|
|
187
|
+
"MODEL_NAME": "hunyuan-t1-vision-20250916"
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
154
194
|
配置完成后重启 Claude Desktop。
|
|
155
195
|
|
|
156
196
|
#### Cline (VSCode)
|
|
@@ -207,6 +247,44 @@ npx luma-mcp
|
|
|
207
247
|
}
|
|
208
248
|
```
|
|
209
249
|
|
|
250
|
+
**方案 D: 使用火山方舟 Doubao-Seed-1.6**:
|
|
251
|
+
|
|
252
|
+
```json
|
|
253
|
+
{
|
|
254
|
+
"mcpServers": {
|
|
255
|
+
"luma": {
|
|
256
|
+
"command": "npx",
|
|
257
|
+
"args": ["-y", "luma-mcp"],
|
|
258
|
+
"env": {
|
|
259
|
+
"MODEL_PROVIDER": "volcengine",
|
|
260
|
+
"VOLCENGINE_API_KEY": "your-volcengine-api-key",
|
|
261
|
+
"MODEL_NAME": "doubao-seed-1-6-flash-250828"
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**方案 E: 使用腾讯混元 Hunyuan-Vision-1.5**:
|
|
269
|
+
|
|
270
|
+
MODEL_NAME 可选:`hunyuan-t1-vision-20250916`(默认)或 `HY-vision-1.5-instruct`
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"mcpServers": {
|
|
275
|
+
"luma": {
|
|
276
|
+
"command": "npx",
|
|
277
|
+
"args": ["-y", "luma-mcp"],
|
|
278
|
+
"env": {
|
|
279
|
+
"MODEL_PROVIDER": "hunyuan",
|
|
280
|
+
"HUNYUAN_API_KEY": "your-hunyuan-api-key",
|
|
281
|
+
"MODEL_NAME": "hunyuan-t1-vision-20250916"
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
210
288
|
#### Claude Code (命令行)
|
|
211
289
|
|
|
212
290
|
**使用智谱 GLM-4.6V**:
|
|
@@ -227,6 +305,18 @@ claude mcp add -s user luma-mcp --env MODEL_PROVIDER=siliconflow --env SILICONFL
|
|
|
227
305
|
claude mcp add -s user luma-mcp --env MODEL_PROVIDER=qwen --env DASHSCOPE_API_KEY=your-api-key -- npx -y luma-mcp
|
|
228
306
|
```
|
|
229
307
|
|
|
308
|
+
**使用火山方舟 Doubao-Seed-1.6**:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
claude mcp add -s user luma-mcp --env MODEL_PROVIDER=volcengine --env VOLCENGINE_API_KEY=your-api-key --env MODEL_NAME=doubao-seed-1-6-flash-250828 -- npx -y luma-mcp
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**使用腾讯混元 Hunyuan-Vision-1.5**:
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
claude mcp add -s user luma-mcp --env MODEL_PROVIDER=hunyuan --env HUNYUAN_API_KEY=your-api-key --env MODEL_NAME=hunyuan-t1-vision-20250916 -- npx -y luma-mcp
|
|
318
|
+
```
|
|
319
|
+
|
|
230
320
|
#### 其他工具
|
|
231
321
|
|
|
232
322
|
更多 MCP 客户端配置方法请参考[智谱官方文档](https://docs.bigmodel.cn/cn/coding-plan/mcp/vision-mcp-server#claude-code)
|
|
@@ -311,6 +401,20 @@ $env:DASHSCOPE_API_KEY="your-api-key" # Windows PowerShell
|
|
|
311
401
|
npm run test:local ./test.png
|
|
312
402
|
```
|
|
313
403
|
|
|
404
|
+
**测试腾讯混元 Hunyuan-Vision-1.5**:
|
|
405
|
+
|
|
406
|
+
```bash
|
|
407
|
+
# 设置 API Key 和提供商
|
|
408
|
+
export MODEL_PROVIDER=hunyuan
|
|
409
|
+
export HUNYUAN_API_KEY="your-api-key" # macOS/Linux
|
|
410
|
+
|
|
411
|
+
$env:MODEL_PROVIDER="hunyuan"
|
|
412
|
+
$env:HUNYUAN_API_KEY="your-api-key" # Windows PowerShell
|
|
413
|
+
|
|
414
|
+
# 测试本地图片
|
|
415
|
+
npm run test:local ./test.png
|
|
416
|
+
```
|
|
417
|
+
|
|
314
418
|
**其他测试命令**:
|
|
315
419
|
|
|
316
420
|
```bash
|
|
@@ -368,14 +472,14 @@ analyze_image({
|
|
|
368
472
|
|
|
369
473
|
### 通用配置
|
|
370
474
|
|
|
371
|
-
| 变量名 | 必需 | 默认值 | 说明
|
|
372
|
-
|
|
373
|
-
| `MODEL_PROVIDER` | 否 | `zhipu` | 模型提供商:`zhipu`、`siliconflow`
|
|
374
|
-
| `MODEL_NAME` | 否 | 见下文 | 模型名称(自动根据提供商选择)
|
|
375
|
-
| `MAX_TOKENS` | 否 | `16384` | 最大生成 tokens
|
|
376
|
-
| `TEMPERATURE` | 否 | `0.7` | 温度参数 (0-1)
|
|
377
|
-
| `TOP_P` | 否 | `0.7` | Top-p 参数 (0-1)
|
|
378
|
-
| `ENABLE_THINKING` | 否 | `true` | 是否启用思考模式(GLM-4.6V
|
|
475
|
+
| 变量名 | 必需 | 默认值 | 说明 |
|
|
476
|
+
|-------------------|------|---------|----------------------------------------------------------------|
|
|
477
|
+
| `MODEL_PROVIDER` | 否 | `zhipu` | 模型提供商:`zhipu`、`siliconflow`、`qwen`、`volcengine`、`hunyuan` |
|
|
478
|
+
| `MODEL_NAME` | 否 | 见下文 | 模型名称(自动根据提供商选择) |
|
|
479
|
+
| `MAX_TOKENS` | 否 | `16384` | 最大生成 tokens |
|
|
480
|
+
| `TEMPERATURE` | 否 | `0.7` | 温度参数 (0-1) |
|
|
481
|
+
| `TOP_P` | 否 | `0.7` | Top-p 参数 (0-1) |
|
|
482
|
+
| `ENABLE_THINKING` | 否 | `true` | 是否启用思考模式(GLM-4.6V、Qwen3-VL-Flash、Doubao-Seed-1.6) |
|
|
379
483
|
|
|
380
484
|
### 智谱 GLM-4.6V 专用
|
|
381
485
|
|
|
@@ -401,6 +505,16 @@ analyze_image({
|
|
|
401
505
|
|
|
402
506
|
默认模型:`qwen3-vl-flash`
|
|
403
507
|
|
|
508
|
+
### 腾讯混元 Hunyuan-Vision-1.5 专用
|
|
509
|
+
|
|
510
|
+
| 变量名 | 必需 | 默认值 | 说明 |
|
|
511
|
+
|-------------------|----------------|--------|-------------------|
|
|
512
|
+
| `HUNYUAN_API_KEY` | 是(使用混元时) | - | 腾讯混元 API 密钥 |
|
|
513
|
+
|
|
514
|
+
默认模型:`hunyuan-t1-vision-20250916`
|
|
515
|
+
|
|
516
|
+
可选模型:`HY-vision-1.5-instruct`
|
|
517
|
+
|
|
404
518
|
**思考模式说明**:
|
|
405
519
|
|
|
406
520
|
- 默认开启,提高图片分析的准确性和详细程度
|
|
@@ -446,6 +560,7 @@ luma-mcp/
|
|
|
446
560
|
│ ├── siliconflow-client.ts # DeepSeek-OCR API 客户端
|
|
447
561
|
│ ├── qwen-client.ts # Qwen3-VL API 客户端
|
|
448
562
|
│ ├── volcengine-client.ts # Doubao-Seed-1.6 API 客户端
|
|
563
|
+
│ ├── hunyuan-client.ts # Hunyuan-Vision-1.5 API 客户端
|
|
449
564
|
│ ├── image-processor.ts # 图片处理
|
|
450
565
|
│ └── utils/
|
|
451
566
|
│ ├── logger.ts # 日志工具
|
|
@@ -488,6 +603,13 @@ luma-mcp/
|
|
|
488
603
|
3. 进入 API-KEY 管理创建 API Key
|
|
489
604
|
4. 复制 API Key 到配置文件
|
|
490
605
|
|
|
606
|
+
**腾讯混元 Hunyuan-Vision-1.5**:
|
|
607
|
+
|
|
608
|
+
1. 访问 [腾讯混元控制台](https://cloud.tencent.com/product/hunyuan)
|
|
609
|
+
2. 注册/登录账号
|
|
610
|
+
3. 进入 API Key 管理创建 API Key
|
|
611
|
+
4. 复制 API Key 到配置文件
|
|
612
|
+
|
|
491
613
|
### 支持哪些图片格式?
|
|
492
614
|
|
|
493
615
|
支持 JPG、PNG、WebP、GIF 格式。建议使用 JPG 格式以获得更好的压缩率。
|
|
@@ -541,20 +663,22 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...
|
|
|
541
663
|
|
|
542
664
|
### 如何选择模型?
|
|
543
665
|
|
|
544
|
-
| 特性 | GLM-4.6V(智谱) | DeepSeek-OCR(硅基流动) | Qwen3-VL-Flash(阿里云) |
|
|
545
|
-
|
|
546
|
-
| **费用** | 收费 | **完全免费** | 收费 |
|
|
547
|
-
| **中文理解** | 优秀 | 良好 | **优秀** |
|
|
548
|
-
| **OCR 能力** | 良好 | **优秀** | 优秀 |
|
|
549
|
-
| **思考模式** | 支持 | 不支持 | 支持 |
|
|
550
|
-
| **速度/成本** | 中等 | 免费 | **快速/低成本** |
|
|
551
|
-
| **适用场景** | 通用图片分析 | OCR、文字识别 | 快速分析、3D 定位 |
|
|
666
|
+
| 特性 | GLM-4.6V(智谱) | DeepSeek-OCR(硅基流动) | Qwen3-VL-Flash(阿里云) | Doubao-Seed-1.6(火山方舟) | Hunyuan-Vision-1.5(腾讯混元) |
|
|
667
|
+
|---------------|----------------|------------------------|------------------------|---------------------------|------------------------------|
|
|
668
|
+
| **费用** | 收费 | **完全免费** | 收费 | 收费 | 收费 |
|
|
669
|
+
| **中文理解** | 优秀 | 良好 | **优秀** | 优秀 | **优秀** |
|
|
670
|
+
| **OCR 能力** | 良好 | **优秀** | 优秀 | 良好 | 优秀 |
|
|
671
|
+
| **思考模式** | 支持 | 不支持 | 支持 | 支持 | 默认思考版模型 |
|
|
672
|
+
| **速度/成本** | 中等 | 免费 | **快速/低成本** | 高性价比 | 中等 |
|
|
673
|
+
| **适用场景** | 通用图片分析 | OCR、文字识别 | 快速分析、3D 定位 | 高性价比通用分析 | 复杂图文推理、多语言理解 |
|
|
552
674
|
|
|
553
675
|
**推荐**:
|
|
554
676
|
|
|
555
677
|
- 需要 OCR 或文字识别:选择 **DeepSeek-OCR**(免费)
|
|
556
678
|
- 需要快速低成本分析:选择 **Qwen3-VL-Flash**
|
|
679
|
+
- 需要高性价比通用分析:选择 **Doubao-Seed-1.6**
|
|
557
680
|
- 需要深度图片理解:选择 **GLM-4.6V**
|
|
681
|
+
- 需要复杂图文推理或多语言理解:选择 **Hunyuan-Vision-1.5**
|
|
558
682
|
|
|
559
683
|
## 贡献
|
|
560
684
|
|
|
@@ -572,6 +696,7 @@ MIT License
|
|
|
572
696
|
- [DeepSeek-OCR 文档](https://docs.siliconflow.cn/cn/api-reference/chat-completions/chat-completions)
|
|
573
697
|
- [阿里云百炼平台](https://bailian.console.aliyun.com/)
|
|
574
698
|
- [Qwen3-VL 文档](https://help.aliyun.com/zh/model-studio/getting-started/models)
|
|
699
|
+
- [腾讯混元平台](https://cloud.tencent.com/product/hunyuan)
|
|
575
700
|
- [MCP 协议文档](https://modelcontextprotocol.io/)
|
|
576
701
|
|
|
577
702
|
## 更新日志
|
package/build/config.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* 配置模块
|
|
3
|
+
* 从环境变量加载配置
|
|
4
4
|
*/
|
|
5
|
-
export type ModelProvider = 'zhipu' | 'siliconflow' | 'qwen' | 'volcengine';
|
|
5
|
+
export type ModelProvider = 'zhipu' | 'siliconflow' | 'qwen' | 'volcengine' | 'hunyuan';
|
|
6
6
|
export interface LumaConfig {
|
|
7
7
|
provider: ModelProvider;
|
|
8
8
|
apiKey: string;
|
package/build/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;AAExF,MAAM,WAAW,UAAU;IAC1B,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,UAAU,CAuDvC"}
|
package/build/config.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* 配置模块
|
|
3
|
+
* 从环境变量加载配置
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
6
|
* 从环境变量加载配置
|
|
7
7
|
*/
|
|
8
8
|
export function loadConfig() {
|
|
9
|
-
//
|
|
9
|
+
// 确定模型提供商
|
|
10
10
|
const provider = (process.env.MODEL_PROVIDER?.toLowerCase() || 'zhipu');
|
|
11
|
-
//
|
|
11
|
+
// 根据提供商读取 API Key
|
|
12
12
|
let apiKey;
|
|
13
13
|
let defaultModel;
|
|
14
14
|
if (provider === 'siliconflow') {
|
|
@@ -32,6 +32,13 @@ export function loadConfig() {
|
|
|
32
32
|
throw new Error('VOLCENGINE_API_KEY environment variable is required. Please configure it in your MCP settings.');
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
else if (provider === 'hunyuan') {
|
|
36
|
+
apiKey = process.env.HUNYUAN_API_KEY;
|
|
37
|
+
defaultModel = 'hunyuan-t1-vision-20250916';
|
|
38
|
+
if (!apiKey) {
|
|
39
|
+
throw new Error('HUNYUAN_API_KEY environment variable is required. Please configure it in your MCP settings.');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
35
42
|
else {
|
|
36
43
|
apiKey = process.env.ZHIPU_API_KEY;
|
|
37
44
|
defaultModel = 'glm-4.6v';
|
package/build/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,UAAU;IACV,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,EAAE,IAAI,OAAO,CAAkB,CAAC;IAEzF,kBAAkB;IAClB,IAAI,MAA0B,CAAC;IAC/B,IAAI,YAAoB,CAAC;IAEzB,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;QAC/B,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACzC,YAAY,GAAG,0BAA0B,CAAC;QAE1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,iGAAiG,CAAC,CAAC;QACrH,CAAC;IACH,CAAC;SAAM,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC/B,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QACvC,YAAY,GAAG,gBAAgB,CAAC;QAEhC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAC;QACnH,CAAC;IACH,CAAC;SAAM,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QACrC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QACxC,YAAY,GAAG,8BAA8B,CAAC;QAE9C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,gGAAgG,CAAC,CAAC;QACpH,CAAC;IACH,CAAC;SAAM,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QACrC,YAAY,GAAG,4BAA4B,CAAC;QAE5C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,6FAA6F,CAAC,CAAC;QACjH,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QACnC,YAAY,GAAG,UAAU,CAAC;QAE1B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,2FAA2F,CAAC,CAAC;QAC/G,CAAC;IACH,CAAC;IAED,OAAO;QACL,QAAQ;QACR,MAAM;QACN,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,YAAY;QAC7C,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,EAAE,EAAE,CAAC;QAC1D,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,KAAK,CAAC;QACzD,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC;QAC9C,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,OAAO;QACvD,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;KAC/C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 腾讯混元视觉 API 客户端
|
|
3
|
+
* api文档:https://cloud.tencent.com/document/product/1729/101848
|
|
4
|
+
* OpenAI 兼容接口
|
|
5
|
+
*/
|
|
6
|
+
import type { VisionClient } from "./vision-client.js";
|
|
7
|
+
import type { LumaConfig } from "./config.js";
|
|
8
|
+
/**
|
|
9
|
+
* 混元视觉客户端
|
|
10
|
+
*/
|
|
11
|
+
export declare class HunyuanClient implements VisionClient {
|
|
12
|
+
private client;
|
|
13
|
+
private apiKey;
|
|
14
|
+
private model;
|
|
15
|
+
private maxTokens;
|
|
16
|
+
private temperature;
|
|
17
|
+
private topP;
|
|
18
|
+
constructor(config: LumaConfig);
|
|
19
|
+
/**
|
|
20
|
+
* 分析图片
|
|
21
|
+
*/
|
|
22
|
+
analyzeImage(imageDataUrl: string, prompt: string, enableThinking?: boolean): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* 获取模型名称
|
|
25
|
+
*/
|
|
26
|
+
getModelName(): string;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=hunyuan-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hunyuan-client.d.ts","sourceRoot":"","sources":["../src/hunyuan-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAyC9C;;GAEG;AACH,qBAAa,aAAc,YAAW,YAAY;IAChD,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,IAAI,CAAS;gBAET,MAAM,EAAE,UAAU;IAiB9B;;OAEG;IACG,YAAY,CAChB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,OAAO,GACvB,OAAO,CAAC,MAAM,CAAC;IAmElB;;OAEG;IACH,YAAY,IAAI,MAAM;CAGvB"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 腾讯混元视觉 API 客户端
|
|
3
|
+
* api文档:https://cloud.tencent.com/document/product/1729/101848
|
|
4
|
+
* OpenAI 兼容接口
|
|
5
|
+
*/
|
|
6
|
+
import axios from "axios";
|
|
7
|
+
import { logger } from "./utils/logger.js";
|
|
8
|
+
/**
|
|
9
|
+
* 混元视觉客户端
|
|
10
|
+
*/
|
|
11
|
+
export class HunyuanClient {
|
|
12
|
+
client;
|
|
13
|
+
apiKey;
|
|
14
|
+
model;
|
|
15
|
+
maxTokens;
|
|
16
|
+
temperature;
|
|
17
|
+
topP;
|
|
18
|
+
constructor(config) {
|
|
19
|
+
this.apiKey = config.apiKey;
|
|
20
|
+
this.model = config.model;
|
|
21
|
+
this.maxTokens = config.maxTokens;
|
|
22
|
+
this.temperature = config.temperature;
|
|
23
|
+
this.topP = config.topP;
|
|
24
|
+
this.client = axios.create({
|
|
25
|
+
baseURL: "https://api.hunyuan.cloud.tencent.com/v1",
|
|
26
|
+
headers: {
|
|
27
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
},
|
|
30
|
+
timeout: 180000,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 分析图片
|
|
35
|
+
*/
|
|
36
|
+
async analyzeImage(imageDataUrl, prompt, enableThinking) {
|
|
37
|
+
try {
|
|
38
|
+
const requestBody = {
|
|
39
|
+
model: this.model,
|
|
40
|
+
messages: [
|
|
41
|
+
{
|
|
42
|
+
role: "user",
|
|
43
|
+
content: [
|
|
44
|
+
{
|
|
45
|
+
type: "image_url",
|
|
46
|
+
image_url: {
|
|
47
|
+
url: imageDataUrl,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
type: "text",
|
|
52
|
+
text: prompt,
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
temperature: this.temperature,
|
|
58
|
+
max_tokens: this.maxTokens,
|
|
59
|
+
top_p: this.topP,
|
|
60
|
+
};
|
|
61
|
+
logger.info("Calling Hunyuan Vision API", {
|
|
62
|
+
model: this.model,
|
|
63
|
+
thinking: enableThinking !== false,
|
|
64
|
+
});
|
|
65
|
+
const response = await this.client.post("/chat/completions", requestBody);
|
|
66
|
+
if (!response.data?.choices?.[0]?.message?.content) {
|
|
67
|
+
throw new Error("Invalid response format from Hunyuan API");
|
|
68
|
+
}
|
|
69
|
+
const result = response.data.choices[0].message.content;
|
|
70
|
+
const usage = response.data.usage;
|
|
71
|
+
logger.info("Hunyuan Vision API call successful", {
|
|
72
|
+
tokens: usage?.total_tokens || 0,
|
|
73
|
+
model: response.data.model,
|
|
74
|
+
});
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
logger.error("Hunyuan Vision API call failed", {
|
|
79
|
+
error: error instanceof Error ? error.message : String(error),
|
|
80
|
+
});
|
|
81
|
+
if (axios.isAxiosError(error)) {
|
|
82
|
+
const errorMessage = error.response?.data?.error?.message || error.message;
|
|
83
|
+
const status = error.response?.status;
|
|
84
|
+
throw new Error(`Hunyuan API error (${status || "unknown"}): ${errorMessage}`);
|
|
85
|
+
}
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 获取模型名称
|
|
91
|
+
*/
|
|
92
|
+
getModelName() {
|
|
93
|
+
return `Hunyuan (${this.model})`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=hunyuan-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hunyuan-client.js","sourceRoot":"","sources":["../src/hunyuan-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 图片处理工具
|
|
3
|
-
*
|
|
3
|
+
* 读取、压缩并编码图片(本地文件与远程 URL)
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* 校验图片来源(文件或 URL)
|
|
7
7
|
*/
|
|
8
8
|
export declare function validateImageSource(imageSource: string, maxSizeMB?: number): Promise<void>;
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* 将图片转为 base64 Data URL 或直接返回 URL
|
|
11
11
|
*/
|
|
12
12
|
export declare function imageToBase64(imagePath: string): Promise<string>;
|
|
13
|
+
export declare function imageToBase64WithOptions(imagePath: string, options?: {
|
|
14
|
+
preferText?: boolean;
|
|
15
|
+
}): Promise<string>;
|
|
13
16
|
//# sourceMappingURL=image-processor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-processor.d.ts","sourceRoot":"","sources":["../src/image-processor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiDH;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,MAAW,GACrB,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"image-processor.d.ts","sourceRoot":"","sources":["../src/image-processor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiDH;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,MAAW,GACrB,OAAO,CAAC,IAAI,CAAC,CAoEf;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBtE;AAED,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,OAAO,CAAC,MAAM,CAAC,CAuBjB"}
|
package/build/image-processor.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 图片处理工具
|
|
3
|
-
*
|
|
3
|
+
* 读取、压缩并编码图片(本地文件与远程 URL)
|
|
4
4
|
*/
|
|
5
5
|
import { readFile, stat } from "fs/promises";
|
|
6
6
|
import sharp from "sharp";
|
|
7
7
|
import { isUrl } from "./utils/helpers.js";
|
|
8
8
|
import { logger } from "./utils/logger.js";
|
|
9
|
-
//
|
|
9
|
+
// 判断输入是否为 Data URI(data:image/png;base64,...)
|
|
10
10
|
function isDataUri(input) {
|
|
11
11
|
return (typeof input === "string" &&
|
|
12
12
|
input.startsWith("data:") &&
|
|
13
13
|
/;base64,/.test(input));
|
|
14
14
|
}
|
|
15
|
-
// 从 Data URI
|
|
15
|
+
// 从 Data URI 提取 mimeType
|
|
16
16
|
function getMimeFromDataUri(input) {
|
|
17
17
|
const match = input.match(/^data:([^;]+);base64,/i);
|
|
18
18
|
return match ? match[1].toLowerCase() : null;
|
|
@@ -21,7 +21,7 @@ function getMimeFromDataUri(input) {
|
|
|
21
21
|
function estimateBytesFromDataUri(input) {
|
|
22
22
|
try {
|
|
23
23
|
const base64 = input.split(",")[1] || "";
|
|
24
|
-
// base64 长度 * 3/4,忽略 padding
|
|
24
|
+
// base64 长度 * 3/4,忽略 padding 进行近似计算
|
|
25
25
|
return Math.floor((base64.length * 3) / 4);
|
|
26
26
|
}
|
|
27
27
|
catch {
|
|
@@ -29,8 +29,8 @@ function estimateBytesFromDataUri(input) {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
32
|
+
* 规范化本地图片路径(例如移除前缀符号)
|
|
33
|
+
* 部分客户端使用 "@path/to/file" 引用,需要转为真实路径
|
|
34
34
|
*/
|
|
35
35
|
function normalizeImageSourcePath(source) {
|
|
36
36
|
if (typeof source === "string" && source.startsWith("@")) {
|
|
@@ -44,24 +44,42 @@ function normalizeImageSourcePath(source) {
|
|
|
44
44
|
return source;
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
47
|
+
* 校验图片来源(文件或 URL)
|
|
48
48
|
*/
|
|
49
49
|
export async function validateImageSource(imageSource, maxSizeMB = 10) {
|
|
50
|
-
//
|
|
50
|
+
// 规范化本地路径(处理可能的前缀符号,如 "@image.png")
|
|
51
51
|
const normalizedSource = normalizeImageSourcePath(imageSource);
|
|
52
|
-
|
|
52
|
+
if (isDataUri(normalizedSource)) {
|
|
53
|
+
const mimeType = getMimeFromDataUri(normalizedSource);
|
|
54
|
+
const supportedMimeTypes = [
|
|
55
|
+
"image/jpeg",
|
|
56
|
+
"image/png",
|
|
57
|
+
"image/webp",
|
|
58
|
+
"image/gif",
|
|
59
|
+
];
|
|
60
|
+
if (!mimeType || !supportedMimeTypes.includes(mimeType)) {
|
|
61
|
+
throw new Error(`Unsupported image format: ${mimeType || "unknown"}. Supported: ${supportedMimeTypes.join(", ")}`);
|
|
62
|
+
}
|
|
63
|
+
const bytes = estimateBytesFromDataUri(normalizedSource);
|
|
64
|
+
const maxBytes = maxSizeMB * 1024 * 1024;
|
|
65
|
+
if (bytes > maxBytes) {
|
|
66
|
+
throw new Error(`Image file too large: ${(bytes / (1024 * 1024)).toFixed(2)}MB (max: ${maxSizeMB}MB)`);
|
|
67
|
+
}
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// URL 直接跳过校验
|
|
53
71
|
if (isUrl(normalizedSource)) {
|
|
54
72
|
logger.debug("Image source is URL, skipping validation");
|
|
55
73
|
return;
|
|
56
74
|
}
|
|
57
|
-
//
|
|
75
|
+
// 校验本地文件
|
|
58
76
|
try {
|
|
59
77
|
const stats = await stat(normalizedSource);
|
|
60
78
|
const fileSizeMB = stats.size / (1024 * 1024);
|
|
61
79
|
if (fileSizeMB > maxSizeMB) {
|
|
62
80
|
throw new Error(`Image file too large: ${fileSizeMB.toFixed(2)}MB (max: ${maxSizeMB}MB)`);
|
|
63
81
|
}
|
|
64
|
-
//
|
|
82
|
+
// 校验文件格式
|
|
65
83
|
const ext = normalizedSource.toLowerCase().split(".").pop();
|
|
66
84
|
const supportedFormats = ["jpg", "jpeg", "png", "webp", "gif"];
|
|
67
85
|
if (!ext || !supportedFormats.includes(ext)) {
|
|
@@ -76,46 +94,82 @@ export async function validateImageSource(imageSource, maxSizeMB = 10) {
|
|
|
76
94
|
}
|
|
77
95
|
}
|
|
78
96
|
/**
|
|
79
|
-
*
|
|
97
|
+
* 将图片转为 base64 Data URL 或直接返回 URL
|
|
80
98
|
*/
|
|
81
99
|
export async function imageToBase64(imagePath) {
|
|
82
100
|
try {
|
|
83
101
|
// 规范化本地路径(处理可能的前缀符号)
|
|
84
102
|
const normalizedPath = normalizeImageSourcePath(imagePath);
|
|
85
|
-
|
|
103
|
+
if (isDataUri(normalizedPath)) {
|
|
104
|
+
return normalizedPath;
|
|
105
|
+
}
|
|
106
|
+
// 直接返回 URL
|
|
86
107
|
if (isUrl(normalizedPath)) {
|
|
87
108
|
logger.info("Using remote image URL", { url: normalizedPath });
|
|
88
109
|
return normalizedPath;
|
|
89
110
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
111
|
+
const result = await encodeLocalImage(normalizedPath);
|
|
112
|
+
return `data:${result.mimeType};base64,${result.base64}`;
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
throw new Error(`Failed to process image: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
export async function imageToBase64WithOptions(imagePath, options) {
|
|
119
|
+
try {
|
|
120
|
+
const normalizedPath = normalizeImageSourcePath(imagePath);
|
|
121
|
+
if (isDataUri(normalizedPath)) {
|
|
122
|
+
return normalizedPath;
|
|
123
|
+
}
|
|
124
|
+
if (isUrl(normalizedPath)) {
|
|
125
|
+
logger.info("Using remote image URL", { url: normalizedPath });
|
|
126
|
+
return normalizedPath;
|
|
98
127
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const mimeType = getMimeType(normalizedPath);
|
|
102
|
-
return `data:${mimeType};base64,${base64}`;
|
|
128
|
+
const result = await encodeLocalImage(normalizedPath, options);
|
|
129
|
+
return `data:${result.mimeType};base64,${result.base64}`;
|
|
103
130
|
}
|
|
104
131
|
catch (error) {
|
|
105
132
|
throw new Error(`Failed to process image: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
106
133
|
}
|
|
107
134
|
}
|
|
135
|
+
async function encodeLocalImage(normalizedPath, options) {
|
|
136
|
+
let imageBuffer = await readFile(normalizedPath);
|
|
137
|
+
let mimeType = getMimeType(normalizedPath);
|
|
138
|
+
if (imageBuffer.length > 2 * 1024 * 1024) {
|
|
139
|
+
logger.info("Compressing large image", {
|
|
140
|
+
originalSize: `${(imageBuffer.length / (1024 * 1024)).toFixed(2)}MB`,
|
|
141
|
+
});
|
|
142
|
+
const compressed = await compressImage(imageBuffer, mimeType, options?.preferText);
|
|
143
|
+
imageBuffer = compressed.buffer;
|
|
144
|
+
mimeType = compressed.mimeType;
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
base64: imageBuffer.toString("base64"),
|
|
148
|
+
mimeType,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
108
151
|
/**
|
|
109
152
|
* 压缩图片
|
|
110
153
|
*/
|
|
111
|
-
async function compressImage(imageBuffer) {
|
|
112
|
-
|
|
113
|
-
|
|
154
|
+
async function compressImage(imageBuffer, inputMimeType, preferText) {
|
|
155
|
+
if (inputMimeType === "image/gif") {
|
|
156
|
+
return { buffer: imageBuffer, mimeType: inputMimeType };
|
|
157
|
+
}
|
|
158
|
+
const maxSize = preferText ? 3072 : 2048;
|
|
159
|
+
const pipeline = sharp(imageBuffer).resize(maxSize, maxSize, {
|
|
114
160
|
fit: "inside",
|
|
115
161
|
withoutEnlargement: true,
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
.toBuffer();
|
|
162
|
+
});
|
|
163
|
+
if (inputMimeType === "image/png") {
|
|
164
|
+
const buffer = await pipeline.png({ compressionLevel: preferText ? 3 : 6 }).toBuffer();
|
|
165
|
+
return { buffer, mimeType: "image/png" };
|
|
166
|
+
}
|
|
167
|
+
if (inputMimeType === "image/webp") {
|
|
168
|
+
const buffer = await pipeline.webp({ quality: preferText ? 90 : 85 }).toBuffer();
|
|
169
|
+
return { buffer, mimeType: "image/webp" };
|
|
170
|
+
}
|
|
171
|
+
const buffer = await pipeline.jpeg({ quality: preferText ? 90 : 85 }).toBuffer();
|
|
172
|
+
return { buffer, mimeType: "image/jpeg" };
|
|
119
173
|
}
|
|
120
174
|
/**
|
|
121
175
|
* 根据文件扩展名获取 MIME 类型
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-processor.js","sourceRoot":"","sources":["../src/image-processor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,
|
|
1
|
+
{"version":3,"file":"image-processor.js","sourceRoot":"","sources":["../src/image-processor.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
CHANGED
package/build/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Luma MCP
|
|
4
|
-
*
|
|
3
|
+
* Luma MCP 服务器
|
|
4
|
+
* 支持多提供商的通用视觉理解 MCP 服务器
|
|
5
5
|
*/
|
|
6
|
-
//
|
|
6
|
+
// 将 console 输出重定向到 stderr,避免污染 MCP stdout
|
|
7
7
|
import { setupConsoleRedirection, logger } from "./utils/logger.js";
|
|
8
8
|
setupConsoleRedirection();
|
|
9
9
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -14,27 +14,26 @@ import { ZhipuClient } from "./zhipu-client.js";
|
|
|
14
14
|
import { SiliconFlowClient } from "./siliconflow-client.js";
|
|
15
15
|
import { QwenClient } from "./qwen-client.js";
|
|
16
16
|
import { VolcengineClient } from "./volcengine-client.js";
|
|
17
|
-
import {
|
|
17
|
+
import { HunyuanClient } from "./hunyuan-client.js";
|
|
18
|
+
import { imageToBase64WithOptions, validateImageSource, } from "./image-processor.js";
|
|
18
19
|
import { withRetry, createSuccessResponse, createErrorResponse, } from "./utils/helpers.js";
|
|
19
20
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
21
|
+
* 当未设置 BASE_VISION_PROMPT 时使用的默认视觉提示词
|
|
22
|
+
* 作为轻量级系统提示词引导图像理解
|
|
22
23
|
*
|
|
23
24
|
* 设计目标:
|
|
24
|
-
* -
|
|
25
|
-
* -
|
|
25
|
+
* - 基于截图可见事实优先输出结构/布局
|
|
26
|
+
* - 避免猜测不可见细节(实现、性能等)
|
|
26
27
|
*/
|
|
27
28
|
const DEFAULT_BASE_VISION_PROMPT = [
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"3. 如用户没有明确要求“设计点评/优化建议”,可以完全不写或只给最多 1~2 条简短、标明为“通用建议”的内容,且要明确说明这些建议无法仅凭截图确认当前是否已经做到。",
|
|
34
|
-
"4. 任何基于猜测的内容,都要使用“从截图中无法确认,但一般建议……”这样的表述,避免把猜测说成事实。",
|
|
29
|
+
"你是一个专门帮助开发者理解截图内容的视觉理解助手。",
|
|
30
|
+
"目标:基于截图中可见信息进行高保真理解与回答。",
|
|
31
|
+
"当用户明确要求诊断、排错或推断时,可以基于可见证据做推断,并清晰标注不确定性与依据。",
|
|
32
|
+
"优先顺序:事实描述 → 文字/代码/数据提取 → 结构/布局 → 回答用户问题。",
|
|
33
|
+
"当用户描述过于简短时,自动执行全面提取并结构化输出。",
|
|
35
34
|
].join("\n");
|
|
36
35
|
/**
|
|
37
|
-
*
|
|
36
|
+
* 拼接基础提示词与用户提示词
|
|
38
37
|
*/
|
|
39
38
|
function buildFullPrompt(userPrompt, basePrompt) {
|
|
40
39
|
if (!basePrompt) {
|
|
@@ -47,6 +46,64 @@ function buildFullPrompt(userPrompt, basePrompt) {
|
|
|
47
46
|
}
|
|
48
47
|
return `${trimmedBase}\n\n用户任务描述:\n${trimmedUser}`;
|
|
49
48
|
}
|
|
49
|
+
function getPromptProfile(userPrompt) {
|
|
50
|
+
const normalized = userPrompt.trim();
|
|
51
|
+
const isGenericShort = /^(分析|查看|识别|描述|理解|看一下|看看|分析一下|请分析|analyze|describe|view|check)/i.test(normalized) && normalized.length < 30;
|
|
52
|
+
const wantsText = /(ocr|文字|文本|代码|日志|报错|堆栈|stack|trace|error|exception|表格|文档|识别)/i.test(normalized);
|
|
53
|
+
const wantsLayout = /(布局|结构|组件|页面|界面|架构|ui|layout|component|wireframe)/i.test(normalized);
|
|
54
|
+
const wantsDiagnosis = /(报错|错误|异常|崩溃|失败|error|exception|crash)/i.test(normalized);
|
|
55
|
+
const extractionOnly = /(只|仅).*(文字|文本|ocr|识别)/i.test(normalized) &&
|
|
56
|
+
!wantsLayout;
|
|
57
|
+
const preferText = wantsText || wantsDiagnosis || isGenericShort;
|
|
58
|
+
const needsTwoPass = isGenericShort || wantsDiagnosis || (wantsText && wantsLayout);
|
|
59
|
+
return {
|
|
60
|
+
isGenericShort,
|
|
61
|
+
wantsText,
|
|
62
|
+
wantsLayout,
|
|
63
|
+
wantsDiagnosis,
|
|
64
|
+
preferText,
|
|
65
|
+
needsTwoPass,
|
|
66
|
+
extractionOnly,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function buildStagePrompt(stage, userPrompt, basePrompt, extracted) {
|
|
70
|
+
const parts = [];
|
|
71
|
+
const trimmedBase = basePrompt?.trim();
|
|
72
|
+
if (trimmedBase) {
|
|
73
|
+
parts.push(trimmedBase);
|
|
74
|
+
}
|
|
75
|
+
if (stage === "extract") {
|
|
76
|
+
parts.push([
|
|
77
|
+
"请进行高密度可见信息提取:",
|
|
78
|
+
"1) 逐行完整提取所有可见文字、代码、日志、表格内容,保持原始顺序;",
|
|
79
|
+
"2) 描述主要区域与布局层次(上/下/左/右/主次区域);",
|
|
80
|
+
"3) 列出关键UI元素/图表/按钮/状态标识;",
|
|
81
|
+
"只基于可见内容,不做无依据推测。",
|
|
82
|
+
"输出要求:使用清晰标题和列表,便于后续复用。",
|
|
83
|
+
].join("\n"));
|
|
84
|
+
}
|
|
85
|
+
if (stage === "answer") {
|
|
86
|
+
parts.push([
|
|
87
|
+
"请基于可见信息与已提取信息回答用户问题。",
|
|
88
|
+
"如果需要推断,请明确标注推断并给出依据。",
|
|
89
|
+
"输出结构:先简要结论,再给要点。",
|
|
90
|
+
].join("\n"));
|
|
91
|
+
}
|
|
92
|
+
if (stage === "single") {
|
|
93
|
+
parts.push([
|
|
94
|
+
"请基于可见信息回答用户问题。",
|
|
95
|
+
"若用户描述模糊,先进行完整提取再回答。",
|
|
96
|
+
"输出结构化。",
|
|
97
|
+
].join("\n"));
|
|
98
|
+
}
|
|
99
|
+
if (extracted?.trim()) {
|
|
100
|
+
parts.push(`已提取信息:\n${extracted.trim()}`);
|
|
101
|
+
}
|
|
102
|
+
if (userPrompt.trim()) {
|
|
103
|
+
parts.push(`用户任务描述:\n${userPrompt.trim()}`);
|
|
104
|
+
}
|
|
105
|
+
return parts.join("\n\n");
|
|
106
|
+
}
|
|
50
107
|
/**
|
|
51
108
|
* 创建 MCP 服务器
|
|
52
109
|
*/
|
|
@@ -55,7 +112,7 @@ async function createServer() {
|
|
|
55
112
|
// 加载配置
|
|
56
113
|
const config = loadConfig();
|
|
57
114
|
const baseVisionPrompt = config.baseVisionPrompt ?? DEFAULT_BASE_VISION_PROMPT;
|
|
58
|
-
//
|
|
115
|
+
// 按配置选择模型客户端
|
|
59
116
|
let visionClient;
|
|
60
117
|
if (config.provider === "siliconflow") {
|
|
61
118
|
visionClient = new SiliconFlowClient(config);
|
|
@@ -66,6 +123,9 @@ async function createServer() {
|
|
|
66
123
|
else if (config.provider === "volcengine") {
|
|
67
124
|
visionClient = new VolcengineClient(config);
|
|
68
125
|
}
|
|
126
|
+
else if (config.provider === "hunyuan") {
|
|
127
|
+
visionClient = new HunyuanClient(config);
|
|
128
|
+
}
|
|
69
129
|
else {
|
|
70
130
|
visionClient = new ZhipuClient(config);
|
|
71
131
|
}
|
|
@@ -73,7 +133,7 @@ async function createServer() {
|
|
|
73
133
|
provider: config.provider,
|
|
74
134
|
model: visionClient.getModelName(),
|
|
75
135
|
});
|
|
76
|
-
//
|
|
136
|
+
// 使用 McpServer 创建服务器
|
|
77
137
|
const server = new McpServer({
|
|
78
138
|
name: "luma-mcp",
|
|
79
139
|
version: "1.0.0",
|
|
@@ -84,27 +144,36 @@ async function createServer() {
|
|
|
84
144
|
});
|
|
85
145
|
// 创建带重试的分析函数
|
|
86
146
|
const analyzeWithRetry = withRetry(async (imageSource, prompt) => {
|
|
87
|
-
// 1.
|
|
147
|
+
// 1. 校验图片来源
|
|
88
148
|
await validateImageSource(imageSource);
|
|
89
|
-
|
|
90
|
-
const imageDataUrl = await
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
149
|
+
const profile = getPromptProfile(prompt);
|
|
150
|
+
const imageDataUrl = await imageToBase64WithOptions(imageSource, {
|
|
151
|
+
preferText: profile.preferText,
|
|
152
|
+
});
|
|
153
|
+
if (profile.needsTwoPass) {
|
|
154
|
+
const extractPrompt = buildStagePrompt("extract", profile.extractionOnly ? prompt : "", baseVisionPrompt);
|
|
155
|
+
const extracted = await visionClient.analyzeImage(imageDataUrl, extractPrompt, config.enableThinking);
|
|
156
|
+
if (profile.extractionOnly) {
|
|
157
|
+
return extracted;
|
|
158
|
+
}
|
|
159
|
+
const answerPrompt = buildStagePrompt("answer", prompt, baseVisionPrompt, extracted);
|
|
160
|
+
return await visionClient.analyzeImage(imageDataUrl, answerPrompt, config.enableThinking);
|
|
161
|
+
}
|
|
162
|
+
const singlePrompt = buildStagePrompt("single", prompt, baseVisionPrompt);
|
|
163
|
+
return await visionClient.analyzeImage(imageDataUrl, singlePrompt, config.enableThinking);
|
|
164
|
+
}, 2, // 最大重试次数: 2
|
|
165
|
+
1000 // 初始退避: 1s
|
|
97
166
|
);
|
|
98
|
-
//
|
|
99
|
-
server.tool("analyze_image", `图像分析工具:
|
|
100
|
-
- 何时调用:当用户提到“看图、看截图、看看这张图片/界面/页面/报错/架构/布局/组件结构/页面结构”等需求,或者在对话中出现图片附件并询问与图片内容相关的问题(包括 UI/前端界面结构、代码截图、日志/报错截图、文档截图、表单、表格等),都应优先调用本工具,而不是只用文本推理。
|
|
101
|
-
- 图片来源:1) 用户粘贴图片时直接调用,无需手动指定路径 2) 指定本地图片路径,如 ./screenshot.png 3) 指定图片 URL,如 https://example.com/image.png。
|
|
102
|
-
- 提示词(prompt)约定:
|
|
103
|
-
- **不要**在调用本工具前自己构造一大段复杂分析提示词;
|
|
104
|
-
- 直接把“用户关于图片的原始问题/指令”作为 prompt 传入即可,例如:
|
|
105
|
-
- “这张图是什么界面?整体结构是什么样的?”
|
|
106
|
-
- “帮我从前端实现角度拆解这个页面的布局和组件结构”;
|
|
107
|
-
- Luma 会在服务器内部自动拼接系统级视觉说明和分析模板,调用底层视觉模型完成完整理解;
|
|
167
|
+
// 使用 McpServer.tool() 注册工具
|
|
168
|
+
server.tool("analyze_image", `图像分析工具:
|
|
169
|
+
- 何时调用:当用户提到“看图、看截图、看看这张图片/界面/页面/报错/架构/布局/组件结构/页面结构”等需求,或者在对话中出现图片附件并询问与图片内容相关的问题(包括 UI/前端界面结构、代码截图、日志/报错截图、文档截图、表单、表格等),都应优先调用本工具,而不是只用文本推理。
|
|
170
|
+
- 图片来源:1) 用户粘贴图片时直接调用,无需手动指定路径 2) 指定本地图片路径,如 ./screenshot.png 3) 指定图片 URL,如 https://example.com/image.png。
|
|
171
|
+
- 提示词(prompt)约定:
|
|
172
|
+
- **不要**在调用本工具前自己构造一大段复杂分析提示词;
|
|
173
|
+
- 直接把“用户关于图片的原始问题/指令”作为 prompt 传入即可,例如:
|
|
174
|
+
- “这张图是什么界面?整体结构是什么样的?”
|
|
175
|
+
- “帮我从前端实现角度拆解这个页面的布局和组件结构”;
|
|
176
|
+
- Luma 会在服务器内部自动拼接系统级视觉说明和分析模板,调用底层视觉模型完成完整理解;
|
|
108
177
|
- 你只需要确保 prompt 准确表达用户对这张图想了解的内容,无需重复描述图片细节或编写长篇提示词。`, {
|
|
109
178
|
image_source: z
|
|
110
179
|
.string()
|
|
@@ -114,13 +183,13 @@ async function createServer() {
|
|
|
114
183
|
.describe("用户关于图片的原始问题或简短指令,例如“这张图是什么界面?”、“帮我分析这个页面的结构和布局”。服务器会在内部补充系统级视觉提示词并构造完整分析指令。"),
|
|
115
184
|
}, async (params) => {
|
|
116
185
|
try {
|
|
117
|
-
//
|
|
186
|
+
// Prompt 已根据用户请求准备
|
|
118
187
|
const prompt = params.prompt;
|
|
119
188
|
logger.info("Analyzing image", {
|
|
120
189
|
source: params.image_source,
|
|
121
190
|
prompt,
|
|
122
191
|
});
|
|
123
|
-
//
|
|
192
|
+
// 使用重试执行分析
|
|
124
193
|
const result = await analyzeWithRetry(params.image_source, prompt);
|
|
125
194
|
logger.info("Image analysis completed successfully");
|
|
126
195
|
return createSuccessResponse(result);
|
|
@@ -135,7 +204,7 @@ async function createServer() {
|
|
|
135
204
|
return server;
|
|
136
205
|
}
|
|
137
206
|
/**
|
|
138
|
-
*
|
|
207
|
+
* 主入口
|
|
139
208
|
*/
|
|
140
209
|
async function main() {
|
|
141
210
|
try {
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAEH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/build/qwen-client.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* 阿里云 Qwen VL 客户端
|
|
3
|
+
* OpenAI 兼容接口
|
|
4
|
+
* 文档: https://help.aliyun.com/zh/model-studio/vision
|
|
5
5
|
*/
|
|
6
6
|
import { VisionClient } from "./vision-client.js";
|
|
7
7
|
import type { LumaConfig } from "./config.js";
|
package/build/qwen-client.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* 阿里云 Qwen VL 客户端
|
|
3
|
+
* OpenAI 兼容接口
|
|
4
|
+
* 文档: https://help.aliyun.com/zh/model-studio/vision
|
|
5
5
|
*/
|
|
6
6
|
import axios from "axios";
|
|
7
7
|
import { logger } from "./utils/logger.js";
|
|
@@ -16,19 +16,19 @@ export class QwenClient {
|
|
|
16
16
|
this.model = config.model;
|
|
17
17
|
this.maxTokens = config.maxTokens;
|
|
18
18
|
this.temperature = config.temperature;
|
|
19
|
-
//
|
|
19
|
+
// 使用阿里云百炼 OpenAI 兼容接口
|
|
20
20
|
this.client = axios.create({
|
|
21
21
|
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
22
22
|
headers: {
|
|
23
23
|
Authorization: `Bearer ${config.apiKey}`,
|
|
24
24
|
"Content-Type": "application/json",
|
|
25
25
|
},
|
|
26
|
-
timeout: 180000, //
|
|
26
|
+
timeout: 180000, // 180s timeout
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
async analyzeImage(imageDataUrl, prompt, enableThinking) {
|
|
30
30
|
try {
|
|
31
|
-
// Qwen3-VL
|
|
31
|
+
// Qwen3-VL 通过 extra_body 启用思考模式
|
|
32
32
|
const requestBody = {
|
|
33
33
|
model: this.model,
|
|
34
34
|
messages: [
|
|
@@ -52,11 +52,11 @@ export class QwenClient {
|
|
|
52
52
|
temperature: this.temperature,
|
|
53
53
|
stream: false,
|
|
54
54
|
};
|
|
55
|
-
//
|
|
55
|
+
// 根据参数启用思考模式
|
|
56
56
|
if (enableThinking !== false) {
|
|
57
57
|
requestBody.extra_body = {
|
|
58
58
|
enable_thinking: true,
|
|
59
|
-
thinking_budget: 81920, // 最大思考
|
|
59
|
+
thinking_budget: 81920, // 最大思考 token 预算
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
logger.info("Calling Qwen3-VL API", {
|
package/build/qwen-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qwen-client.js","sourceRoot":"","sources":["../src/qwen-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAwB,MAAM,OAAO,CAAC;AAG7C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,OAAO,UAAU;IACb,MAAM,CAAgB;IACtB,MAAM,CAAS;IACf,KAAK,CAAS;IACd,SAAS,CAAS;IAClB,WAAW,CAAS;IAE5B,YAAY,MAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QAEtC,
|
|
1
|
+
{"version":3,"file":"qwen-client.js","sourceRoot":"","sources":["../src/qwen-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAwB,MAAM,OAAO,CAAC;AAG7C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,OAAO,UAAU;IACb,MAAM,CAAgB;IACtB,MAAM,CAAS;IACf,KAAK,CAAS;IACd,SAAS,CAAS;IAClB,WAAW,CAAS;IAE5B,YAAY,MAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QAEtC,sBAAsB;QACtB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YACzB,OAAO,EAAE,mDAAmD;YAC5D,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE;gBACxC,cAAc,EAAE,kBAAkB;aACnC;YACD,OAAO,EAAE,MAAM,EAAE,eAAe;SACjC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,YAAoB,EACpB,MAAc,EACd,cAAwB;QAExB,IAAI,CAAC;YACH,gCAAgC;YAChC,MAAM,WAAW,GAAQ;gBACvB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,WAAW;gCACjB,SAAS,EAAE;oCACT,GAAG,EAAE,YAAY;iCAClB;6BACF;4BACD;gCACE,IAAI,EAAE,MAAM;gCACZ,IAAI,EAAE,MAAM;6BACb;yBACF;qBACF;iBACF;gBACD,UAAU,EAAE,IAAI,CAAC,SAAS;gBAC1B,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,MAAM,EAAE,KAAK;aACd,CAAC;YAEF,aAAa;YACb,IAAI,cAAc,KAAK,KAAK,EAAE,CAAC;gBAC7B,WAAW,CAAC,UAAU,GAAG;oBACvB,eAAe,EAAE,IAAI;oBACrB,eAAe,EAAE,KAAK,EAAE,gBAAgB;iBACzC,CAAC;YACJ,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE;gBAClC,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,UAAU;aACnC,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;YAE1E,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;gBACnD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;YAC3D,CAAC;YAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;YACxD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;YAElC,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE;gBAC1C,MAAM,EAAE,KAAK,EAAE,YAAY,IAAI,CAAC;gBAChC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK;aAC3B,CAAC,CAAC;YAEH,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE;gBACvC,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;YAEH,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,MAAM,YAAY,GAChB,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC;gBACxD,MAAM,IAAI,KAAK,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,YAAY;QACV,OAAO,SAAS,IAAI,CAAC,KAAK,GAAG,CAAC;IAChC,CAAC;CACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 硅基流动 DeepSeek-OCR API 客户端
|
|
3
|
-
*
|
|
3
|
+
* OpenAI 兼容接口
|
|
4
4
|
*/
|
|
5
5
|
import axios from 'axios';
|
|
6
6
|
import { logger } from './utils/logger.js';
|
|
@@ -55,7 +55,7 @@ export class SiliconFlowClient {
|
|
|
55
55
|
'Authorization': `Bearer ${this.apiKey}`,
|
|
56
56
|
'Content-Type': 'application/json',
|
|
57
57
|
},
|
|
58
|
-
timeout: 60000, //
|
|
58
|
+
timeout: 60000, // 60s 超时
|
|
59
59
|
});
|
|
60
60
|
if (!response.data.choices || response.data.choices.length === 0) {
|
|
61
61
|
throw new Error('No response from DeepSeek-OCR');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"siliconflow-client.js","sourceRoot":"","sources":["../src/siliconflow-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AA0C3C;;GAEG;AACH,MAAM,OAAO,iBAAiB;IACpB,MAAM,CAAS;IACf,KAAK,CAAS;IACd,SAAS,CAAS;IAClB,WAAW,CAAS;IACpB,WAAW,GAAG,gDAAgD,CAAC;IAEvE,YAAY,MAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,YAAoB,EAAE,MAAc,EAAE,cAAwB;QAC/E,MAAM,WAAW,GAAuB;YACtC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,WAAW;4BACjB,SAAS,EAAE;gCACT,GAAG,EAAE,YAAY;6BAClB;yBACF;wBACD;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,MAAM;yBACb;qBACF;iBACF;aACF;YACD,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,IAAI,CAAC,SAAS;YAC1B,MAAM,EAAE,KAAK;SACd,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE;YAClD,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAC/B,IAAI,CAAC,WAAW,EAChB,WAAW,EACX;gBACE,OAAO,EAAE;oBACP,eAAe,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;oBACxC,cAAc,EAAE,kBAAkB;iBACnC;gBACD,OAAO,EAAE,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"siliconflow-client.js","sourceRoot":"","sources":["../src/siliconflow-client.ts"],"names":[],"mappings":"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"}
|
package/build/vision-client.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 统一的视觉模型客户端接口
|
|
3
3
|
*/
|
|
4
4
|
export interface VisionClient {
|
|
5
5
|
/**
|
|
6
6
|
* 分析图片
|
|
7
7
|
* @param imageDataUrl 图片 Data URL 或 URL
|
|
8
8
|
* @param prompt 分析提示词
|
|
9
|
-
* @param enableThinking
|
|
9
|
+
* @param enableThinking 是否启用思考模式(如支持)
|
|
10
10
|
* @returns 分析结果文本
|
|
11
11
|
*/
|
|
12
12
|
analyzeImage(imageDataUrl: string, prompt: string, enableThinking?: boolean): Promise<string>;
|
package/build/vision-client.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 火山方舟
|
|
3
|
-
* 支持 Doubao-Seed-1.6
|
|
2
|
+
* 火山方舟 Doubao 视觉模型客户端
|
|
3
|
+
* 支持 Doubao-Seed-1.6 系列(flash、vision、lite)
|
|
4
4
|
* 使用 Chat Completions API 格式
|
|
5
5
|
*/
|
|
6
6
|
import axios from "axios";
|
|
@@ -47,7 +47,7 @@ export class VolcengineClient {
|
|
|
47
47
|
max_tokens: this.maxTokens,
|
|
48
48
|
stream: false,
|
|
49
49
|
};
|
|
50
|
-
//
|
|
50
|
+
// 根据参数启用思考模式
|
|
51
51
|
if (enableThinking !== false) {
|
|
52
52
|
requestBody.thinking = { type: "enabled" };
|
|
53
53
|
}
|
|
@@ -61,7 +61,7 @@ export class VolcengineClient {
|
|
|
61
61
|
Authorization: `Bearer ${this.apiKey}`,
|
|
62
62
|
"Content-Type": "application/json",
|
|
63
63
|
},
|
|
64
|
-
timeout: 120000, //
|
|
64
|
+
timeout: 120000, // 120s 超时
|
|
65
65
|
});
|
|
66
66
|
if (!response.data.choices || response.data.choices.length === 0) {
|
|
67
67
|
throw new Error("No response from Volcengine Doubao");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"volcengine-client.js","sourceRoot":"","sources":["../src/volcengine-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AA6C3C;;GAEG;AACH,MAAM,OAAO,gBAAgB;IACnB,MAAM,CAAS;IACf,KAAK,CAAS;IACd,SAAS,CAAS;IAClB,WAAW,CAAS;IACpB,WAAW,GACjB,2DAA2D,CAAC;IAE9D,YAAY,MAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAChB,YAAoB,EACpB,MAAc,EACd,cAAwB;QAExB,MAAM,WAAW,GAAsB;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,WAAW;4BACjB,SAAS,EAAE;gCACT,GAAG,EAAE,YAAY;6BAClB;yBACF;wBACD;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,MAAM;yBACb;qBACF;iBACF;aACF;YACD,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,IAAI,CAAC,SAAS;YAC1B,MAAM,EAAE,KAAK;SACd,CAAC;QAEF,
|
|
1
|
+
{"version":3,"file":"volcengine-client.js","sourceRoot":"","sources":["../src/volcengine-client.ts"],"names":[],"mappings":"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"}
|
package/build/zhipu-client.js
CHANGED
|
@@ -47,7 +47,7 @@ export class ZhipuClient {
|
|
|
47
47
|
max_tokens: this.maxTokens,
|
|
48
48
|
top_p: this.topP,
|
|
49
49
|
};
|
|
50
|
-
//
|
|
50
|
+
// 根据参数启用思考模式
|
|
51
51
|
if (enableThinking !== false) {
|
|
52
52
|
requestBody.thinking = { type: "enabled" };
|
|
53
53
|
}
|
|
@@ -61,7 +61,7 @@ export class ZhipuClient {
|
|
|
61
61
|
Authorization: `Bearer ${this.apiKey}`,
|
|
62
62
|
"Content-Type": "application/json",
|
|
63
63
|
},
|
|
64
|
-
timeout: 60000, //
|
|
64
|
+
timeout: 60000, // 60s 超时
|
|
65
65
|
});
|
|
66
66
|
if (!response.data.choices || response.data.choices.length === 0) {
|
|
67
67
|
throw new Error("No response from GLM-4.6V");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zhipu-client.js","sourceRoot":"","sources":["../src/zhipu-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AA2C3C;;GAEG;AACH,MAAM,OAAO,WAAW;IACd,MAAM,CAAS;IACf,KAAK,CAAS;IACd,SAAS,CAAS;IAClB,WAAW,CAAS;IACpB,IAAI,CAAS;IACb,WAAW,GAAG,uDAAuD,CAAC;IAE9E,YAAY,MAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAChB,YAAoB,EACpB,MAAc,EACd,cAAwB;QAExB,MAAM,WAAW,GAAiB;YAChC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,WAAW;4BACjB,SAAS,EAAE;gCACT,GAAG,EAAE,YAAY;6BAClB;yBACF;wBACD;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,MAAM;yBACb;qBACF;iBACF;aACF;YACD,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,IAAI,CAAC,SAAS;YAC1B,KAAK,EAAE,IAAI,CAAC,IAAI;SACjB,CAAC;QAEF,
|
|
1
|
+
{"version":3,"file":"zhipu-client.js","sourceRoot":"","sources":["../src/zhipu-client.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "luma-mcp",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Multi-model vision understanding MCP server. Supports GLM-4.6V (Zhipu), DeepSeek-OCR (SiliconFlow - Free), Qwen3-VL-Flash (Aliyun), and Doubao-Seed-1.6 (Volcengine)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|