@lutery/vision-mcp 1.0.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/README.md +428 -0
- package/dist/adapters/base-adapter.d.ts +69 -0
- package/dist/adapters/base-adapter.d.ts.map +1 -0
- package/dist/adapters/base-adapter.js +143 -0
- package/dist/adapters/base-adapter.js.map +1 -0
- package/dist/adapters/claude-adapter.d.ts +38 -0
- package/dist/adapters/claude-adapter.d.ts.map +1 -0
- package/dist/adapters/claude-adapter.js +251 -0
- package/dist/adapters/claude-adapter.js.map +1 -0
- package/dist/adapters/glm-adapter.d.ts +15 -0
- package/dist/adapters/glm-adapter.d.ts.map +1 -0
- package/dist/adapters/glm-adapter.js +131 -0
- package/dist/adapters/glm-adapter.js.map +1 -0
- package/dist/adapters/modelscope-adapter.d.ts +20 -0
- package/dist/adapters/modelscope-adapter.d.ts.map +1 -0
- package/dist/adapters/modelscope-adapter.js +142 -0
- package/dist/adapters/modelscope-adapter.js.map +1 -0
- package/dist/adapters/openai-adapter.d.ts +20 -0
- package/dist/adapters/openai-adapter.d.ts.map +1 -0
- package/dist/adapters/openai-adapter.js +194 -0
- package/dist/adapters/openai-adapter.js.map +1 -0
- package/dist/adapters/siliconflow-adapter.d.ts +21 -0
- package/dist/adapters/siliconflow-adapter.d.ts.map +1 -0
- package/dist/adapters/siliconflow-adapter.js +145 -0
- package/dist/adapters/siliconflow-adapter.js.map +1 -0
- package/dist/config/model-config.d.ts +39 -0
- package/dist/config/model-config.d.ts.map +1 -0
- package/dist/config/model-config.js +115 -0
- package/dist/config/model-config.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +186 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/system.d.ts +75 -0
- package/dist/prompts/system.d.ts.map +1 -0
- package/dist/prompts/system.js +272 -0
- package/dist/prompts/system.js.map +1 -0
- package/dist/providers/provider-registry.d.ts +58 -0
- package/dist/providers/provider-registry.d.ts.map +1 -0
- package/dist/providers/provider-registry.js +173 -0
- package/dist/providers/provider-registry.js.map +1 -0
- package/dist/src/adapters/base-adapter.d.ts +59 -0
- package/dist/src/adapters/base-adapter.d.ts.map +1 -0
- package/dist/src/adapters/base-adapter.js +83 -0
- package/dist/src/adapters/base-adapter.js.map +1 -0
- package/dist/src/adapters/glm-adapter.d.ts +15 -0
- package/dist/src/adapters/glm-adapter.d.ts.map +1 -0
- package/dist/src/adapters/glm-adapter.js +116 -0
- package/dist/src/adapters/glm-adapter.js.map +1 -0
- package/dist/src/adapters/siliconflow-adapter.d.ts +21 -0
- package/dist/src/adapters/siliconflow-adapter.d.ts.map +1 -0
- package/dist/src/adapters/siliconflow-adapter.js +130 -0
- package/dist/src/adapters/siliconflow-adapter.js.map +1 -0
- package/dist/src/config/model-config.d.ts +40 -0
- package/dist/src/config/model-config.d.ts.map +1 -0
- package/dist/src/config/model-config.js +126 -0
- package/dist/src/config/model-config.js.map +1 -0
- package/dist/src/index.d.ts +17 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +188 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/prompts/system.d.ts +75 -0
- package/dist/src/prompts/system.d.ts.map +1 -0
- package/dist/src/prompts/system.js +272 -0
- package/dist/src/prompts/system.js.map +1 -0
- package/dist/src/tools/vision-tool.d.ts +91 -0
- package/dist/src/tools/vision-tool.d.ts.map +1 -0
- package/dist/src/tools/vision-tool.js +171 -0
- package/dist/src/tools/vision-tool.js.map +1 -0
- package/dist/src/utils/errors.d.ts +65 -0
- package/dist/src/utils/errors.d.ts.map +1 -0
- package/dist/src/utils/errors.js +146 -0
- package/dist/src/utils/errors.js.map +1 -0
- package/dist/src/utils/image-input.d.ts +45 -0
- package/dist/src/utils/image-input.d.ts.map +1 -0
- package/dist/src/utils/image-input.js +226 -0
- package/dist/src/utils/image-input.js.map +1 -0
- package/dist/src/utils/logger.d.ts +63 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +157 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/test/integration.test.d.ts +10 -0
- package/dist/test/integration.test.d.ts.map +1 -0
- package/dist/test/integration.test.js +270 -0
- package/dist/test/integration.test.js.map +1 -0
- package/dist/test/test-utils.d.ts +45 -0
- package/dist/test/test-utils.d.ts.map +1 -0
- package/dist/test/test-utils.js +107 -0
- package/dist/test/test-utils.js.map +1 -0
- package/dist/test/vision-tool.test.d.ts +9 -0
- package/dist/test/vision-tool.test.d.ts.map +1 -0
- package/dist/test/vision-tool.test.js +167 -0
- package/dist/test/vision-tool.test.js.map +1 -0
- package/dist/tools/vision-tool.d.ts +91 -0
- package/dist/tools/vision-tool.d.ts.map +1 -0
- package/dist/tools/vision-tool.js +167 -0
- package/dist/tools/vision-tool.js.map +1 -0
- package/dist/utils/data-url-parser.d.ts +27 -0
- package/dist/utils/data-url-parser.d.ts.map +1 -0
- package/dist/utils/data-url-parser.js +53 -0
- package/dist/utils/data-url-parser.js.map +1 -0
- package/dist/utils/errors.d.ts +65 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +146 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/image-input.d.ts +45 -0
- package/dist/utils/image-input.d.ts.map +1 -0
- package/dist/utils/image-input.js +238 -0
- package/dist/utils/image-input.js.map +1 -0
- package/dist/utils/logger.d.ts +63 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +157 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/thinking-extractors.d.ts +34 -0
- package/dist/utils/thinking-extractors.d.ts.map +1 -0
- package/dist/utils/thinking-extractors.js +83 -0
- package/dist/utils/thinking-extractors.js.map +1 -0
- package/dist/utils/thinking-filter.d.ts +32 -0
- package/dist/utils/thinking-filter.d.ts.map +1 -0
- package/dist/utils/thinking-filter.js +147 -0
- package/dist/utils/thinking-filter.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude (Anthropic Messages API) Adapter
|
|
3
|
+
*
|
|
4
|
+
* @description Claude Messages API 适配器实现,支持 Claude 多模态视觉模型
|
|
5
|
+
* @see https://docs.anthropic.com/claude/reference/messages-post
|
|
6
|
+
*/
|
|
7
|
+
import { BaseVisionModelAdapter } from './base-adapter.js';
|
|
8
|
+
import { ModelAPIError, ModelConfigError } from '../utils/errors.js';
|
|
9
|
+
import { logger } from '../utils/logger.js';
|
|
10
|
+
import { parseDataUrl } from '../utils/data-url-parser.js';
|
|
11
|
+
export class ClaudeAdapter extends BaseVisionModelAdapter {
|
|
12
|
+
options;
|
|
13
|
+
constructor(config, options = {}) {
|
|
14
|
+
super(config);
|
|
15
|
+
if (config.type !== 'claude') {
|
|
16
|
+
throw new ModelConfigError('Invalid model type. Expected: claude', { expected: 'claude', received: config.type });
|
|
17
|
+
}
|
|
18
|
+
this.options = {
|
|
19
|
+
maxTokens: options.maxTokens || 2048,
|
|
20
|
+
apiVersion: options.apiVersion ||
|
|
21
|
+
process.env.VISION_CLAUDE_API_VERSION ||
|
|
22
|
+
'2023-06-01'
|
|
23
|
+
};
|
|
24
|
+
logger.info('Initialized Claude adapter', {
|
|
25
|
+
model: config.name,
|
|
26
|
+
baseUrl: config.baseUrl,
|
|
27
|
+
apiVersion: this.options.apiVersion,
|
|
28
|
+
options: this.options
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async analyze(imageData, prompt) {
|
|
32
|
+
logger.logRequest('Analyzing image with Claude', {
|
|
33
|
+
modelType: 'claude',
|
|
34
|
+
model: this.config.name,
|
|
35
|
+
imageLength: imageData.length
|
|
36
|
+
});
|
|
37
|
+
try {
|
|
38
|
+
return await this.withRetry(async (signal) => {
|
|
39
|
+
const response = await this.callClaudeAPI(imageData, prompt, signal);
|
|
40
|
+
logger.logRequest('Claude analysis completed', {
|
|
41
|
+
modelType: 'claude',
|
|
42
|
+
model: this.config.name,
|
|
43
|
+
responseLength: response.content.length
|
|
44
|
+
});
|
|
45
|
+
return response.content;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
logger.error('Claude analysis failed', error);
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async analyzeWithResponse(imageData, prompt) {
|
|
54
|
+
logger.logRequest('Analyzing image with Claude (full response)', {
|
|
55
|
+
modelType: 'claude',
|
|
56
|
+
model: this.config.name,
|
|
57
|
+
imageLength: imageData.length
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
return await this.withRetry(async (signal) => {
|
|
61
|
+
const response = await this.callClaudeAPI(imageData, prompt, signal);
|
|
62
|
+
logger.logRequest('Claude analysis completed', {
|
|
63
|
+
modelType: 'claude',
|
|
64
|
+
model: this.config.name,
|
|
65
|
+
responseLength: response.content.length,
|
|
66
|
+
usage: response.usage
|
|
67
|
+
});
|
|
68
|
+
return response;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
logger.error('Claude analysis failed', error);
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async callClaudeAPI(imageData, prompt, signal) {
|
|
77
|
+
// 构建请求 URL:{baseUrl}/v1/messages
|
|
78
|
+
// 移除 baseUrl 末尾的 /v1(如果有),避免重复路径
|
|
79
|
+
let baseUrl = this.config.baseUrl.replace(/\/$/, '');
|
|
80
|
+
if (baseUrl.endsWith('/v1')) {
|
|
81
|
+
baseUrl = baseUrl.slice(0, -3);
|
|
82
|
+
logger.warn('Removed duplicate /v1 from baseUrl', {
|
|
83
|
+
original: this.config.baseUrl,
|
|
84
|
+
normalized: baseUrl
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
const apiUrl = `${baseUrl}/v1/messages`;
|
|
88
|
+
// 构建图片 content block
|
|
89
|
+
const imageBlock = this.buildImageBlock(imageData);
|
|
90
|
+
// 构建请求体(Claude Messages API 格式)
|
|
91
|
+
const requestBody = {
|
|
92
|
+
model: this.config.name,
|
|
93
|
+
max_tokens: this.options.maxTokens,
|
|
94
|
+
messages: [{
|
|
95
|
+
role: 'user',
|
|
96
|
+
content: [
|
|
97
|
+
imageBlock,
|
|
98
|
+
{ type: 'text', text: prompt }
|
|
99
|
+
]
|
|
100
|
+
}]
|
|
101
|
+
};
|
|
102
|
+
logger.debug('Calling Claude Messages API', {
|
|
103
|
+
endpoint: apiUrl,
|
|
104
|
+
model: this.config.name,
|
|
105
|
+
hasImage: !!imageData
|
|
106
|
+
});
|
|
107
|
+
// 发起请求
|
|
108
|
+
const response = await fetch(apiUrl, {
|
|
109
|
+
method: 'POST',
|
|
110
|
+
headers: {
|
|
111
|
+
'Content-Type': 'application/json',
|
|
112
|
+
'x-api-key': this.config.apiKey,
|
|
113
|
+
'anthropic-version': this.options.apiVersion
|
|
114
|
+
},
|
|
115
|
+
body: JSON.stringify(requestBody),
|
|
116
|
+
signal
|
|
117
|
+
});
|
|
118
|
+
// 处理错误响应
|
|
119
|
+
if (!response.ok) {
|
|
120
|
+
await this.handleErrorResponse(response);
|
|
121
|
+
}
|
|
122
|
+
// 解析响应
|
|
123
|
+
const responseData = await this.parseResponseData(response);
|
|
124
|
+
// 归一化响应
|
|
125
|
+
return this.normalizeResponse(responseData);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 构建图片 content block
|
|
129
|
+
* 支持 URL 和 base64 data URL 两种格式
|
|
130
|
+
*/
|
|
131
|
+
buildImageBlock(imageData) {
|
|
132
|
+
// 判断是 URL 还是 data URL
|
|
133
|
+
if (imageData.startsWith('http://') || imageData.startsWith('https://')) {
|
|
134
|
+
return {
|
|
135
|
+
type: 'image',
|
|
136
|
+
source: {
|
|
137
|
+
type: 'url',
|
|
138
|
+
url: imageData
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
// 解析 data URL
|
|
143
|
+
const parsed = parseDataUrl(imageData);
|
|
144
|
+
return {
|
|
145
|
+
type: 'image',
|
|
146
|
+
source: {
|
|
147
|
+
type: 'base64',
|
|
148
|
+
media_type: parsed.mimeType,
|
|
149
|
+
data: parsed.data
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* 处理错误响应
|
|
155
|
+
*/
|
|
156
|
+
async handleErrorResponse(response) {
|
|
157
|
+
const status = response.status;
|
|
158
|
+
const requestId = response.headers.get('request-id') || response.headers.get('x-request-id');
|
|
159
|
+
let errorDetails = { status, requestId };
|
|
160
|
+
try {
|
|
161
|
+
const errorText = await response.text();
|
|
162
|
+
// 尝试解析为 JSON
|
|
163
|
+
try {
|
|
164
|
+
const errorJson = JSON.parse(errorText);
|
|
165
|
+
if (errorJson.error) {
|
|
166
|
+
errorDetails.error = {
|
|
167
|
+
type: errorJson.error?.type,
|
|
168
|
+
message: errorJson.error?.message
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
// 非 JSON 响应,截断存储
|
|
174
|
+
errorDetails.errorText = errorText.slice(0, 500);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// 无法读取响应体
|
|
179
|
+
}
|
|
180
|
+
// 特殊处理 429
|
|
181
|
+
if (status === 429) {
|
|
182
|
+
const retryAfter = response.headers.get('retry-after');
|
|
183
|
+
throw new ModelAPIError(`Rate limit exceeded (429).${retryAfter ? ` Retry after ${retryAfter}s` : ''}`, errorDetails);
|
|
184
|
+
}
|
|
185
|
+
throw new ModelAPIError(`Claude API request failed: ${status}`, errorDetails);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* 解析响应数据
|
|
189
|
+
*/
|
|
190
|
+
async parseResponseData(response) {
|
|
191
|
+
const contentType = response.headers.get('content-type');
|
|
192
|
+
try {
|
|
193
|
+
const rawText = await response.text();
|
|
194
|
+
try {
|
|
195
|
+
return JSON.parse(rawText);
|
|
196
|
+
}
|
|
197
|
+
catch (parseError) {
|
|
198
|
+
const bodyPreview = rawText.length > 500
|
|
199
|
+
? `${rawText.slice(0, 500)}... (truncated, total length: ${rawText.length})`
|
|
200
|
+
: rawText;
|
|
201
|
+
logger.error('Failed to parse Claude response as JSON', parseError, {
|
|
202
|
+
contentType,
|
|
203
|
+
bodyLength: rawText.length,
|
|
204
|
+
bodyPreview
|
|
205
|
+
});
|
|
206
|
+
throw new ModelAPIError('Failed to parse Claude response as JSON', {
|
|
207
|
+
contentType,
|
|
208
|
+
bodyLength: rawText.length,
|
|
209
|
+
bodyPreview
|
|
210
|
+
}, parseError);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
if (error instanceof ModelAPIError) {
|
|
215
|
+
throw error;
|
|
216
|
+
}
|
|
217
|
+
throw new ModelAPIError('Failed to read Claude response', { contentType }, error);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* 归一化 Claude 响应为 VisionModelResponse
|
|
222
|
+
* Claude 响应格式:{ content: [{type: "text", text: "..."}], usage: {...} }
|
|
223
|
+
*/
|
|
224
|
+
normalizeResponse(claudeResponse) {
|
|
225
|
+
const contentBlocks = claudeResponse?.content || [];
|
|
226
|
+
// 提取所有 text blocks 并拼接
|
|
227
|
+
const textParts = contentBlocks
|
|
228
|
+
.filter((block) => block?.type === 'text')
|
|
229
|
+
.map((block) => block?.text || '')
|
|
230
|
+
.filter(Boolean);
|
|
231
|
+
const content = textParts.join('\n\n');
|
|
232
|
+
if (!content) {
|
|
233
|
+
throw new ModelAPIError('Empty content in Claude response', {
|
|
234
|
+
response: claudeResponse
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
// 映射 usage 字段(Claude 使用 input_tokens/output_tokens)
|
|
238
|
+
const claudeUsage = claudeResponse?.usage;
|
|
239
|
+
const usage = claudeUsage ? {
|
|
240
|
+
promptTokens: claudeUsage.input_tokens,
|
|
241
|
+
completionTokens: claudeUsage.output_tokens,
|
|
242
|
+
totalTokens: (claudeUsage.input_tokens || 0) + (claudeUsage.output_tokens || 0)
|
|
243
|
+
} : undefined;
|
|
244
|
+
return {
|
|
245
|
+
content,
|
|
246
|
+
usage,
|
|
247
|
+
model: claudeResponse?.model
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=claude-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-adapter.js","sourceRoot":"","sources":["../../src/adapters/claude-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GLM-4.6V Adapter
|
|
3
|
+
*
|
|
4
|
+
* @description GLM-4.6V 模型适配器实现,支持智谱 AI 开放平台的视觉模型
|
|
5
|
+
*/
|
|
6
|
+
import { BaseVisionModelAdapter } from './base-adapter.js';
|
|
7
|
+
import { ModelConfig } from '../config/model-config.js';
|
|
8
|
+
import { VisionModelResponse } from './base-adapter.js';
|
|
9
|
+
export declare class GLM4VisionAdapter extends BaseVisionModelAdapter {
|
|
10
|
+
constructor(config: ModelConfig);
|
|
11
|
+
analyze(imageData: string, prompt: string): Promise<string>;
|
|
12
|
+
analyzeWithResponse(imageData: string, prompt: string): Promise<VisionModelResponse>;
|
|
13
|
+
private callGLMAPI;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=glm-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glm-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/glm-adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,qBAAa,iBAAkB,SAAQ,sBAAsB;gBAC/C,MAAM,EAAE,WAAW;IAazB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuB3D,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAwB5E,UAAU;CAoFzB"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GLM-4.6V Adapter
|
|
3
|
+
*
|
|
4
|
+
* @description GLM-4.6V 模型适配器实现,支持智谱 AI 开放平台的视觉模型
|
|
5
|
+
*/
|
|
6
|
+
import { BaseVisionModelAdapter } from './base-adapter.js';
|
|
7
|
+
import { ModelAPIError } from '../utils/errors.js';
|
|
8
|
+
import { logger } from '../utils/logger.js';
|
|
9
|
+
export class GLM4VisionAdapter extends BaseVisionModelAdapter {
|
|
10
|
+
constructor(config) {
|
|
11
|
+
super(config);
|
|
12
|
+
if (config.type !== 'glm-4.6v') {
|
|
13
|
+
throw new Error('Invalid model type. Expected: glm-4.6v');
|
|
14
|
+
}
|
|
15
|
+
logger.info('Initialized GLM-4.6V adapter', {
|
|
16
|
+
model: config.name,
|
|
17
|
+
baseUrl: config.baseUrl
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
async analyze(imageData, prompt) {
|
|
21
|
+
logger.logRequest('Analyzing image with GLM-4.6V', {
|
|
22
|
+
modelType: 'glm-4.6v',
|
|
23
|
+
imageLength: imageData.length
|
|
24
|
+
});
|
|
25
|
+
try {
|
|
26
|
+
return await this.withRetry(async (signal) => {
|
|
27
|
+
const response = await this.callGLMAPI(imageData, prompt, signal);
|
|
28
|
+
logger.logRequest('GLM-4.6V analysis completed', {
|
|
29
|
+
modelType: 'glm-4.6v',
|
|
30
|
+
responseLength: response.content.length
|
|
31
|
+
});
|
|
32
|
+
return response.content;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
logger.error('GLM-4.6V analysis failed', error);
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async analyzeWithResponse(imageData, prompt) {
|
|
41
|
+
logger.logRequest('Analyzing image with GLM-4.6V (full response)', {
|
|
42
|
+
modelType: 'glm-4.6v',
|
|
43
|
+
imageLength: imageData.length
|
|
44
|
+
});
|
|
45
|
+
try {
|
|
46
|
+
return await this.withRetry(async (signal) => {
|
|
47
|
+
const response = await this.callGLMAPI(imageData, prompt, signal);
|
|
48
|
+
logger.logRequest('GLM-4.6V analysis completed', {
|
|
49
|
+
modelType: 'glm-4.6v',
|
|
50
|
+
responseLength: response.content.length,
|
|
51
|
+
usage: response.usage
|
|
52
|
+
});
|
|
53
|
+
return response;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
logger.error('GLM-4.6V analysis failed', error);
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async callGLMAPI(imageData, prompt, signal) {
|
|
62
|
+
// 构建请求 URL
|
|
63
|
+
const apiUrl = `${this.config.baseUrl}/chat/completions`;
|
|
64
|
+
// 构建请求体
|
|
65
|
+
const requestBody = {
|
|
66
|
+
model: this.config.name,
|
|
67
|
+
messages: [
|
|
68
|
+
{
|
|
69
|
+
role: 'user',
|
|
70
|
+
content: [
|
|
71
|
+
{
|
|
72
|
+
type: 'text',
|
|
73
|
+
text: prompt
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: 'image_url',
|
|
77
|
+
image_url: {
|
|
78
|
+
url: imageData
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
],
|
|
84
|
+
stream: false, // 显式禁用流式响应
|
|
85
|
+
...(this.config.thinking && {
|
|
86
|
+
thinking: this.config.thinking
|
|
87
|
+
})
|
|
88
|
+
};
|
|
89
|
+
logger.debug('Calling GLM-4.6V API', {
|
|
90
|
+
apiUrl,
|
|
91
|
+
model: this.config.name,
|
|
92
|
+
hasThinking: !!this.config.thinking
|
|
93
|
+
});
|
|
94
|
+
const response = await fetch(apiUrl, {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
headers: {
|
|
97
|
+
'Authorization': `Bearer ${this.config.apiKey}`,
|
|
98
|
+
'Content-Type': 'application/json',
|
|
99
|
+
'Accept': 'application/json'
|
|
100
|
+
},
|
|
101
|
+
body: JSON.stringify(requestBody),
|
|
102
|
+
signal
|
|
103
|
+
});
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
const errorText = await response.text().catch(() => 'Failed to get error details');
|
|
106
|
+
// Special handling for rate limiting
|
|
107
|
+
if (response.status === 429) {
|
|
108
|
+
const retryAfter = response.headers.get('retry-after');
|
|
109
|
+
const retryAfterText = retryAfter ? `Retry after ${retryAfter}s. ` : '';
|
|
110
|
+
throw new ModelAPIError(`Rate limit exceeded (429). ${retryAfterText}Please check your API quota or wait before retrying.`, {
|
|
111
|
+
status: response.status,
|
|
112
|
+
statusText: response.statusText,
|
|
113
|
+
errorDetails: errorText,
|
|
114
|
+
endpoint: apiUrl,
|
|
115
|
+
retryAfter: retryAfter,
|
|
116
|
+
guidance: 'Check your API quota or wait before retrying'
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
// Handle other errors normally
|
|
120
|
+
throw new ModelAPIError(`GLM API request failed: ${response.status} ${response.statusText}`, {
|
|
121
|
+
status: response.status,
|
|
122
|
+
statusText: response.statusText,
|
|
123
|
+
errorDetails: errorText,
|
|
124
|
+
endpoint: apiUrl
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
const responseData = await response.json();
|
|
128
|
+
return this.parseResponse(responseData, 'glm-4.6v');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=glm-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glm-adapter.js","sourceRoot":"","sources":["../../src/adapters/glm-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModelScope Adapter
|
|
3
|
+
*
|
|
4
|
+
* @description ModelScope API-Inference 适配器实现,支持 OpenAI 兼容接口的视觉模型
|
|
5
|
+
*/
|
|
6
|
+
import { BaseVisionModelAdapter } from './base-adapter.js';
|
|
7
|
+
import { ModelConfig } from '../config/model-config.js';
|
|
8
|
+
import { VisionModelResponse } from './base-adapter.js';
|
|
9
|
+
export interface ModelScopeAdapterOptions {
|
|
10
|
+
maxTokens?: number;
|
|
11
|
+
temperature?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class ModelScopeAdapter extends BaseVisionModelAdapter {
|
|
14
|
+
private options;
|
|
15
|
+
constructor(config: ModelConfig, options?: ModelScopeAdapterOptions);
|
|
16
|
+
analyze(imageData: string, prompt: string): Promise<string>;
|
|
17
|
+
analyzeWithResponse(imageData: string, prompt: string): Promise<VisionModelResponse>;
|
|
18
|
+
private callModelScopeAPI;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=modelscope-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modelscope-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/modelscope-adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,iBAAkB,SAAQ,sBAAsB;IAC3D,OAAO,CAAC,OAAO,CAA2B;gBAE9B,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,wBAA6B;IAoBjE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyB3D,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YA0B5E,iBAAiB;CAoFhC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModelScope Adapter
|
|
3
|
+
*
|
|
4
|
+
* @description ModelScope API-Inference 适配器实现,支持 OpenAI 兼容接口的视觉模型
|
|
5
|
+
*/
|
|
6
|
+
import { BaseVisionModelAdapter } from './base-adapter.js';
|
|
7
|
+
import { ModelAPIError } from '../utils/errors.js';
|
|
8
|
+
import { logger } from '../utils/logger.js';
|
|
9
|
+
export class ModelScopeAdapter extends BaseVisionModelAdapter {
|
|
10
|
+
options;
|
|
11
|
+
constructor(config, options = {}) {
|
|
12
|
+
super(config);
|
|
13
|
+
if (config.type !== 'modelscope') {
|
|
14
|
+
throw new Error('Invalid model type. Expected: modelscope');
|
|
15
|
+
}
|
|
16
|
+
this.options = {
|
|
17
|
+
maxTokens: 2048,
|
|
18
|
+
temperature: 0.7,
|
|
19
|
+
...options
|
|
20
|
+
};
|
|
21
|
+
logger.info('Initialized ModelScope adapter', {
|
|
22
|
+
model: config.name,
|
|
23
|
+
baseUrl: config.baseUrl,
|
|
24
|
+
options: this.options
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
async analyze(imageData, prompt) {
|
|
28
|
+
logger.logRequest('Analyzing image with ModelScope', {
|
|
29
|
+
modelType: 'modelscope',
|
|
30
|
+
model: this.config.name,
|
|
31
|
+
imageLength: imageData.length
|
|
32
|
+
});
|
|
33
|
+
try {
|
|
34
|
+
return await this.withRetry(async (signal) => {
|
|
35
|
+
const response = await this.callModelScopeAPI(imageData, prompt, signal);
|
|
36
|
+
logger.logRequest('ModelScope analysis completed', {
|
|
37
|
+
modelType: 'modelscope',
|
|
38
|
+
model: this.config.name,
|
|
39
|
+
responseLength: response.content.length
|
|
40
|
+
});
|
|
41
|
+
return response.content;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
logger.error('ModelScope analysis failed', error);
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async analyzeWithResponse(imageData, prompt) {
|
|
50
|
+
logger.logRequest('Analyzing image with ModelScope (full response)', {
|
|
51
|
+
modelType: 'modelscope',
|
|
52
|
+
model: this.config.name,
|
|
53
|
+
imageLength: imageData.length
|
|
54
|
+
});
|
|
55
|
+
try {
|
|
56
|
+
return await this.withRetry(async (signal) => {
|
|
57
|
+
const response = await this.callModelScopeAPI(imageData, prompt, signal);
|
|
58
|
+
logger.logRequest('ModelScope analysis completed', {
|
|
59
|
+
modelType: 'modelscope',
|
|
60
|
+
model: this.config.name,
|
|
61
|
+
responseLength: response.content.length,
|
|
62
|
+
usage: response.usage
|
|
63
|
+
});
|
|
64
|
+
return response;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
logger.error('ModelScope analysis failed', error);
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async callModelScopeAPI(imageData, prompt, signal) {
|
|
73
|
+
// 构建请求 URL
|
|
74
|
+
const apiUrl = `${this.config.baseUrl}/chat/completions`;
|
|
75
|
+
// 构建请求体(OpenAI 兼容格式)
|
|
76
|
+
const requestBody = {
|
|
77
|
+
model: this.config.name,
|
|
78
|
+
messages: [
|
|
79
|
+
{
|
|
80
|
+
role: 'user',
|
|
81
|
+
content: [
|
|
82
|
+
{
|
|
83
|
+
type: 'text',
|
|
84
|
+
text: prompt
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
type: 'image_url',
|
|
88
|
+
image_url: {
|
|
89
|
+
url: imageData
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
stream: false, // 显式禁用流式响应
|
|
96
|
+
max_tokens: this.options.maxTokens,
|
|
97
|
+
temperature: this.options.temperature
|
|
98
|
+
};
|
|
99
|
+
logger.debug('Calling ModelScope API', {
|
|
100
|
+
apiUrl,
|
|
101
|
+
model: this.config.name,
|
|
102
|
+
maxTokens: this.options.maxTokens,
|
|
103
|
+
temperature: this.options.temperature
|
|
104
|
+
});
|
|
105
|
+
const response = await fetch(apiUrl, {
|
|
106
|
+
method: 'POST',
|
|
107
|
+
headers: {
|
|
108
|
+
'Authorization': `Bearer ${this.config.apiKey}`,
|
|
109
|
+
'Content-Type': 'application/json',
|
|
110
|
+
'Accept': 'application/json'
|
|
111
|
+
},
|
|
112
|
+
body: JSON.stringify(requestBody),
|
|
113
|
+
signal
|
|
114
|
+
});
|
|
115
|
+
if (!response.ok) {
|
|
116
|
+
const errorText = await response.text().catch(() => 'Failed to get error details');
|
|
117
|
+
// Special handling for rate limiting
|
|
118
|
+
if (response.status === 429) {
|
|
119
|
+
const retryAfter = response.headers.get('retry-after');
|
|
120
|
+
const retryAfterText = retryAfter ? `Retry after ${retryAfter}s. ` : '';
|
|
121
|
+
throw new ModelAPIError(`Rate limit exceeded (429). ${retryAfterText}Please check your API quota or wait before retrying.`, {
|
|
122
|
+
status: response.status,
|
|
123
|
+
statusText: response.statusText,
|
|
124
|
+
errorDetails: errorText,
|
|
125
|
+
endpoint: apiUrl,
|
|
126
|
+
retryAfter: retryAfter,
|
|
127
|
+
guidance: 'Check your API quota or wait before retrying'
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// Handle other errors normally
|
|
131
|
+
throw new ModelAPIError(`ModelScope API request failed: ${response.status} ${response.statusText}`, {
|
|
132
|
+
status: response.status,
|
|
133
|
+
statusText: response.statusText,
|
|
134
|
+
errorDetails: errorText,
|
|
135
|
+
endpoint: apiUrl
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
const responseData = await response.json();
|
|
139
|
+
return this.parseResponse(responseData, 'modelscope');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=modelscope-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modelscope-adapter.js","sourceRoot":"","sources":["../../src/adapters/modelscope-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Adapter
|
|
3
|
+
*
|
|
4
|
+
* @description OpenAI API 适配器实现,支持 GPT-4o、GPT-4 Vision 等视觉模型
|
|
5
|
+
*/
|
|
6
|
+
import { BaseVisionModelAdapter } from './base-adapter.js';
|
|
7
|
+
import { ModelConfig } from '../config/model-config.js';
|
|
8
|
+
import { VisionModelResponse } from './base-adapter.js';
|
|
9
|
+
export interface OpenAIAdapterOptions {
|
|
10
|
+
maxTokens?: number;
|
|
11
|
+
temperature?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class OpenAIAdapter extends BaseVisionModelAdapter {
|
|
14
|
+
private options;
|
|
15
|
+
constructor(config: ModelConfig, options?: OpenAIAdapterOptions);
|
|
16
|
+
analyze(imageData: string, prompt: string): Promise<string>;
|
|
17
|
+
analyzeWithResponse(imageData: string, prompt: string): Promise<VisionModelResponse>;
|
|
18
|
+
private callOpenAIAPI;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=openai-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/openai-adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,aAAc,SAAQ,sBAAsB;IACvD,OAAO,CAAC,OAAO,CAAuB;gBAE1B,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,oBAAyB;IAuB7D,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyB3D,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YA0B5E,aAAa;CA6I5B"}
|