ai-world-sdk 1.0.1 → 1.0.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/dist/__tests__/example.test.js +2 -85
- package/dist/base.d.ts +0 -3
- package/dist/base.js +74 -59
- package/dist/config.d.ts +13 -1
- package/dist/config.js +33 -1
- package/dist/image_generation.d.ts +0 -2
- package/dist/image_generation.js +8 -12
- package/dist/index.js +3 -2
- package/dist/log.d.ts +19 -0
- package/dist/log.js +65 -0
- package/dist/messages.d.ts +0 -12
- package/dist/messages.js +0 -12
- package/dist/video_generation.d.ts +0 -1
- package/dist/video_generation.js +13 -13
- package/package.json +2 -1
|
@@ -61,10 +61,6 @@ describe("Langchain SDK Tests", () => {
|
|
|
61
61
|
}
|
|
62
62
|
});
|
|
63
63
|
test("ChatGoogleGenerativeAI - 非流式调用", async () => {
|
|
64
|
-
if (!token) {
|
|
65
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
64
|
const gemini = new index_1.ChatGoogleGenerativeAI({
|
|
69
65
|
modelName: "gemini-2.0-flash-exp-image-generation",
|
|
70
66
|
temperature: 0.7,
|
|
@@ -79,10 +75,6 @@ describe("Langchain SDK Tests", () => {
|
|
|
79
75
|
console.log("AI:", response.content);
|
|
80
76
|
}, 30000);
|
|
81
77
|
test("ChatGoogleGenerativeAI - 流式调用", async () => {
|
|
82
|
-
if (!token) {
|
|
83
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
78
|
const gemini = new index_1.ChatGoogleGenerativeAI({
|
|
87
79
|
modelName: "gemini-2.0-flash-exp-image-generation",
|
|
88
80
|
temperature: 0.7,
|
|
@@ -101,10 +93,6 @@ describe("Langchain SDK Tests", () => {
|
|
|
101
93
|
console.log(`完整回复长度: ${fullText.length} 字符`);
|
|
102
94
|
}, 30000);
|
|
103
95
|
test("createChatModel 工厂函数", async () => {
|
|
104
|
-
if (!token) {
|
|
105
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
96
|
const model = (0, index_1.createChatModel)("gemini-2.0-flash-exp-image-generation", {
|
|
109
97
|
temperature: 0.7,
|
|
110
98
|
});
|
|
@@ -119,10 +107,6 @@ describe("Langchain SDK Tests", () => {
|
|
|
119
107
|
console.log("AI:", response.content);
|
|
120
108
|
}, 30000);
|
|
121
109
|
test("BaseChatModel - bind 方法", async () => {
|
|
122
|
-
if (!token) {
|
|
123
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
110
|
const gemini = new index_1.ChatGoogleGenerativeAI({
|
|
127
111
|
modelName: "gemini-2.0-flash-exp-image-generation",
|
|
128
112
|
temperature: 0.5,
|
|
@@ -138,10 +122,6 @@ describe("Langchain SDK Tests", () => {
|
|
|
138
122
|
console.log("AI:", response.content);
|
|
139
123
|
}, 30000);
|
|
140
124
|
test("BaseChatModel - batch 方法", async () => {
|
|
141
|
-
if (!token) {
|
|
142
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
125
|
const gemini = new index_1.ChatGoogleGenerativeAI({
|
|
146
126
|
modelName: "gemini-2.0-flash-exp-image-generation",
|
|
147
127
|
temperature: 0.7,
|
|
@@ -163,13 +143,7 @@ describe("Langchain SDK Tests", () => {
|
|
|
163
143
|
console.log(`批量响应数量: ${responses.length}`);
|
|
164
144
|
}, 30000);
|
|
165
145
|
test("ChatGoogleGenerativeAI - aihubmix.com no stream", async () => {
|
|
166
|
-
if (!token) {
|
|
167
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
146
|
const gemini = new index_1.ChatGoogleGenerativeAI({
|
|
171
|
-
baseUrl: "http://localhost:8000",
|
|
172
|
-
token: token || "",
|
|
173
147
|
modelName: "gemini-2.0-flash-exp-image-generation",
|
|
174
148
|
temperature: 0.7,
|
|
175
149
|
headers: {
|
|
@@ -186,13 +160,7 @@ describe("Langchain SDK Tests", () => {
|
|
|
186
160
|
console.log("AI:", response.content);
|
|
187
161
|
}, 30000);
|
|
188
162
|
test("ChatGoogleGenerativeAI - aihubmix.com stream", async () => {
|
|
189
|
-
if (!token) {
|
|
190
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
163
|
const gemini = new index_1.ChatGoogleGenerativeAI({
|
|
194
|
-
baseUrl: "http://localhost:8000",
|
|
195
|
-
token: token || "",
|
|
196
164
|
modelName: "gemini-2.0-flash-exp-image-generation",
|
|
197
165
|
temperature: 0.7,
|
|
198
166
|
headers: {
|
|
@@ -213,12 +181,8 @@ describe("Langchain SDK Tests", () => {
|
|
|
213
181
|
console.log(`完整回复长度: ${fullText.length} 字符`);
|
|
214
182
|
}, 30000);
|
|
215
183
|
test("ChatGoogleGenerativeAI - Google 图像生成", async () => {
|
|
216
|
-
if (!token) {
|
|
217
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
184
|
const gemini = new index_1.ChatGoogleGenerativeAI({
|
|
221
|
-
modelName: "gemini-
|
|
185
|
+
modelName: "gemini-3-pro-image-preview",
|
|
222
186
|
temperature: 0.7,
|
|
223
187
|
});
|
|
224
188
|
const response = await gemini.invoke([
|
|
@@ -248,13 +212,7 @@ describe("Langchain SDK Tests", () => {
|
|
|
248
212
|
}
|
|
249
213
|
}, 60000);
|
|
250
214
|
test("ChatGoogleGenerativeAI - aihubmix.com 图像生成", async () => {
|
|
251
|
-
if (!token) {
|
|
252
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
215
|
const gemini = new index_1.ChatGoogleGenerativeAI({
|
|
256
|
-
baseUrl: "http://localhost:8000",
|
|
257
|
-
token: token || "",
|
|
258
216
|
modelName: "gemini-3-pro-image-preview",
|
|
259
217
|
temperature: 0.7,
|
|
260
218
|
headers: {
|
|
@@ -288,13 +246,7 @@ describe("Langchain SDK Tests", () => {
|
|
|
288
246
|
}
|
|
289
247
|
}, 60000);
|
|
290
248
|
test("ChatGoogleGenerativeAI - seedream 图像生成", async () => {
|
|
291
|
-
if (!token) {
|
|
292
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
249
|
const gemini = new index_1.ChatGoogleGenerativeAI({
|
|
296
|
-
baseUrl: "http://localhost:8000",
|
|
297
|
-
token: token || "",
|
|
298
250
|
modelName: "doubao-seedream-4-5-251128",
|
|
299
251
|
temperature: 0.7,
|
|
300
252
|
headers: {
|
|
@@ -328,10 +280,6 @@ describe("Langchain SDK Tests", () => {
|
|
|
328
280
|
}
|
|
329
281
|
}, 60000);
|
|
330
282
|
test("ImageGenerationClient - 基础图像生成", async () => {
|
|
331
|
-
if (!token) {
|
|
332
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
283
|
const imageClient = new index_1.ImageGenerationClient({});
|
|
336
284
|
const result = await imageClient.generate({
|
|
337
285
|
prompt: "充满活力的特写编辑肖像,模特眼神犀利,头戴雕塑感帽子,色彩拼接丰富,眼部焦点锐利,景深较浅,具有Vogue杂志封面的美学风格,采用中画幅拍摄,工作室灯光效果强烈。",
|
|
@@ -359,10 +307,6 @@ describe("Langchain SDK Tests", () => {
|
|
|
359
307
|
console.log("创建时间:", new Date(result.created * 1000).toISOString());
|
|
360
308
|
}, 120000);
|
|
361
309
|
test("ImageGenerationClient - 多图像生成 (n=2)", async () => {
|
|
362
|
-
if (!token) {
|
|
363
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
310
|
const imageClient = new index_1.ImageGenerationClient({});
|
|
367
311
|
const result = await imageClient.generate({
|
|
368
312
|
prompt: "A beautiful sunset over the ocean with vibrant colors",
|
|
@@ -381,10 +325,6 @@ describe("Langchain SDK Tests", () => {
|
|
|
381
325
|
});
|
|
382
326
|
}, 120000);
|
|
383
327
|
test("ImageGenerationClient - 不同尺寸测试", async () => {
|
|
384
|
-
if (!token) {
|
|
385
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
328
|
const imageClient = new index_1.ImageGenerationClient({});
|
|
389
329
|
const sizes = ["1K", "2K", "4K"];
|
|
390
330
|
for (const size of sizes) {
|
|
@@ -401,10 +341,6 @@ describe("Langchain SDK Tests", () => {
|
|
|
401
341
|
}
|
|
402
342
|
}, 180000);
|
|
403
343
|
test("VideoGenerationClient - 创建视频生成任务(文本)", async () => {
|
|
404
|
-
if (!token) {
|
|
405
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
344
|
const videoClient = new index_1.VideoGenerationClient({});
|
|
409
345
|
const task = await videoClient.create({
|
|
410
346
|
prompt: "A beautiful sunset over the ocean with waves crashing on the shore",
|
|
@@ -420,10 +356,6 @@ describe("Langchain SDK Tests", () => {
|
|
|
420
356
|
console.log("任务 ID:", task.id);
|
|
421
357
|
}, 30000);
|
|
422
358
|
test("VideoGenerationClient - 创建视频生成任务(图像)", async () => {
|
|
423
|
-
if (!token) {
|
|
424
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
425
|
-
return;
|
|
426
|
-
}
|
|
427
359
|
const videoClient = new index_1.VideoGenerationClient({});
|
|
428
360
|
const task = await videoClient.create({
|
|
429
361
|
image_url: "https://example.com/image.jpg",
|
|
@@ -437,14 +369,7 @@ describe("Langchain SDK Tests", () => {
|
|
|
437
369
|
console.log("任务 ID:", task.id);
|
|
438
370
|
}, 30000);
|
|
439
371
|
test("VideoGenerationClient - 查询视频生成任务", async () => {
|
|
440
|
-
|
|
441
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
444
|
-
const videoClient = new index_1.VideoGenerationClient({
|
|
445
|
-
baseUrl: "http://localhost:8000",
|
|
446
|
-
token: token || "",
|
|
447
|
-
});
|
|
372
|
+
const videoClient = new index_1.VideoGenerationClient({});
|
|
448
373
|
// 先创建一个任务
|
|
449
374
|
const createTask = await videoClient.create({
|
|
450
375
|
prompt: "A serene mountain landscape with a lake",
|
|
@@ -469,10 +394,6 @@ describe("Langchain SDK Tests", () => {
|
|
|
469
394
|
}
|
|
470
395
|
}, 30000);
|
|
471
396
|
test("VideoGenerationClient - 轮询视频生成任务", async () => {
|
|
472
|
-
if (!token) {
|
|
473
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
397
|
const videoClient = new index_1.VideoGenerationClient({});
|
|
477
398
|
// 创建任务
|
|
478
399
|
const createTask = await videoClient.create({
|
|
@@ -510,10 +431,6 @@ describe("Langchain SDK Tests", () => {
|
|
|
510
431
|
}
|
|
511
432
|
}, 120000);
|
|
512
433
|
test("VideoGenerationClient - 直接提供 content", async () => {
|
|
513
|
-
if (!token) {
|
|
514
|
-
console.log("⏭️ 跳过测试: 未设置 AUTH_TOKEN");
|
|
515
|
-
return;
|
|
516
|
-
}
|
|
517
434
|
const videoClient = new index_1.VideoGenerationClient({});
|
|
518
435
|
const task = await videoClient.create({
|
|
519
436
|
model: "doubao-seedance-1-0-pro-fast-251015",
|
package/dist/base.d.ts
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import { BaseMessage, AIMessage, AIMessageChunk } from "./messages";
|
|
6
6
|
export interface BaseChatModelParams {
|
|
7
7
|
baseUrl?: string;
|
|
8
|
-
token?: string;
|
|
9
8
|
headers?: Record<string, string>;
|
|
10
9
|
temperature?: number;
|
|
11
10
|
maxTokens?: number;
|
|
@@ -39,7 +38,6 @@ export interface BindOptions {
|
|
|
39
38
|
};
|
|
40
39
|
}
|
|
41
40
|
export declare abstract class BaseChatModel {
|
|
42
|
-
protected baseUrl: string;
|
|
43
41
|
protected headers: Record<string, string>;
|
|
44
42
|
protected temperature: number;
|
|
45
43
|
protected maxTokens?: number;
|
|
@@ -50,7 +48,6 @@ export declare abstract class BaseChatModel {
|
|
|
50
48
|
protected apiKey?: string;
|
|
51
49
|
constructor(config: {
|
|
52
50
|
baseUrl?: string;
|
|
53
|
-
token?: string;
|
|
54
51
|
headers?: Record<string, string>;
|
|
55
52
|
temperature?: number;
|
|
56
53
|
maxTokens?: number;
|
package/dist/base.js
CHANGED
|
@@ -7,36 +7,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.BaseChatModel = void 0;
|
|
8
8
|
const messages_1 = require("./messages");
|
|
9
9
|
const config_1 = require("./config");
|
|
10
|
+
const log_1 = require("./log");
|
|
10
11
|
class BaseChatModel {
|
|
11
12
|
constructor(config) {
|
|
12
|
-
// 使用提供的 baseUrl,否则使用全局配置
|
|
13
|
-
const baseUrl = config.baseUrl || config_1.sdkConfig.getBaseUrl();
|
|
14
|
-
if (!baseUrl) {
|
|
15
|
-
throw new Error("baseUrl is required. Either provide it in config or set it globally using sdkConfig.setBaseUrl()");
|
|
16
|
-
}
|
|
17
|
-
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
18
13
|
// 合并全局 headers 和配置 headers
|
|
19
14
|
const globalHeaders = config_1.sdkConfig.getHeaders();
|
|
20
15
|
this.headers = {
|
|
21
16
|
"Content-Type": "application/json",
|
|
17
|
+
"Authorization": `Bearer ${config_1.sdkConfig.getToken()}`,
|
|
18
|
+
"X-Base-Url": config.baseUrl || "",
|
|
22
19
|
...globalHeaders,
|
|
23
20
|
...config.headers,
|
|
24
21
|
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (token) {
|
|
28
|
-
this.headers["Authorization"] = `Bearer ${token}`;
|
|
29
|
-
}
|
|
30
|
-
// 如果提供了 provider,添加到请求头
|
|
31
|
-
if (config.provider) {
|
|
32
|
-
this.headers["X-Provider"] = config.provider;
|
|
33
|
-
this.provider = config.provider;
|
|
34
|
-
}
|
|
35
|
-
// 如果提供了 apiKey,添加到请求头(用于指定后端使用的环境变量名)
|
|
36
|
-
if (config.apiKey) {
|
|
37
|
-
this.headers["X-Api-Key-Env"] = config.apiKey;
|
|
38
|
-
this.apiKey = config.apiKey;
|
|
39
|
-
}
|
|
22
|
+
this.provider = config.provider;
|
|
23
|
+
this.apiKey = config.apiKey;
|
|
40
24
|
this.temperature = config.temperature ?? 0.7;
|
|
41
25
|
this.maxTokens = config.maxTokens;
|
|
42
26
|
this.topP = config.topP;
|
|
@@ -48,29 +32,34 @@ class BaseChatModel {
|
|
|
48
32
|
*/
|
|
49
33
|
async invoke(messages) {
|
|
50
34
|
const options = this._mergeOptions({});
|
|
51
|
-
const
|
|
35
|
+
const requestBody = {
|
|
36
|
+
messages,
|
|
37
|
+
config: {
|
|
38
|
+
temperature: options.temperature ?? this.temperature,
|
|
39
|
+
max_tokens: options.maxTokens ?? this.maxTokens,
|
|
40
|
+
top_p: options.topP ?? this.topP,
|
|
41
|
+
tools: options.tools,
|
|
42
|
+
tool_choice: options.toolChoice,
|
|
43
|
+
},
|
|
44
|
+
model: this.modelName,
|
|
45
|
+
provider: this.provider,
|
|
46
|
+
api_key_env: this.apiKey,
|
|
47
|
+
};
|
|
48
|
+
const url = `${config_1.sdkConfig.getServerUrl()}/api/langchain-proxy/invoke`;
|
|
49
|
+
(0, log_1.logRequest)("POST", url, this.headers, requestBody);
|
|
50
|
+
const response = await fetch(url, {
|
|
52
51
|
method: "POST",
|
|
53
52
|
headers: this.headers,
|
|
54
|
-
body: JSON.stringify(
|
|
55
|
-
messages: messages.map((msg) => msg.toJSON()),
|
|
56
|
-
config: {
|
|
57
|
-
temperature: options.temperature ?? this.temperature,
|
|
58
|
-
max_tokens: options.maxTokens ?? this.maxTokens,
|
|
59
|
-
top_p: options.topP ?? this.topP,
|
|
60
|
-
tools: options.tools,
|
|
61
|
-
tool_choice: options.toolChoice,
|
|
62
|
-
},
|
|
63
|
-
model: this.modelName,
|
|
64
|
-
provider: this.provider,
|
|
65
|
-
api_key_env: this.apiKey,
|
|
66
|
-
}),
|
|
53
|
+
body: JSON.stringify(requestBody),
|
|
67
54
|
});
|
|
68
55
|
if (!response.ok) {
|
|
69
56
|
const errorText = await response.text();
|
|
57
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, errorText);
|
|
70
58
|
throw new Error(`Langchain API error: ${response.status} ${errorText}`);
|
|
71
59
|
}
|
|
72
60
|
// 返回标准 AIMessage 格式(从 message_to_dict 序列化)
|
|
73
61
|
const data = (await response.json());
|
|
62
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, data);
|
|
74
63
|
// 从标准 AIMessage 格式创建 AIMessage 对象
|
|
75
64
|
const content = data.content || "";
|
|
76
65
|
return new messages_1.AIMessage(content);
|
|
@@ -82,7 +71,7 @@ class BaseChatModel {
|
|
|
82
71
|
async *stream(messages) {
|
|
83
72
|
const options = this._mergeOptions({});
|
|
84
73
|
const requestBody = {
|
|
85
|
-
messages
|
|
74
|
+
messages,
|
|
86
75
|
config: {
|
|
87
76
|
temperature: options.temperature ?? this.temperature,
|
|
88
77
|
max_tokens: options.maxTokens ?? this.maxTokens,
|
|
@@ -94,50 +83,76 @@ class BaseChatModel {
|
|
|
94
83
|
provider: this.provider,
|
|
95
84
|
api_key_env: this.apiKey,
|
|
96
85
|
};
|
|
97
|
-
const
|
|
86
|
+
const url = `${config_1.sdkConfig.getServerUrl()}/api/langchain-proxy/stream`;
|
|
87
|
+
const streamHeaders = {
|
|
88
|
+
...this.headers,
|
|
89
|
+
Accept: "text/event-stream",
|
|
90
|
+
};
|
|
91
|
+
(0, log_1.logRequest)("POST", url, streamHeaders, requestBody);
|
|
92
|
+
const response = await fetch(url, {
|
|
98
93
|
method: "POST",
|
|
99
|
-
headers:
|
|
100
|
-
...this.headers,
|
|
101
|
-
Accept: "text/event-stream",
|
|
102
|
-
},
|
|
94
|
+
headers: streamHeaders,
|
|
103
95
|
body: JSON.stringify(requestBody),
|
|
104
96
|
});
|
|
105
97
|
if (!response.ok) {
|
|
106
98
|
const errorText = await response.text();
|
|
99
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, errorText);
|
|
107
100
|
throw new Error(`Langchain API error: ${response.status} ${errorText}`);
|
|
108
101
|
}
|
|
102
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, "[Streaming Response]");
|
|
103
|
+
if (!response.body) {
|
|
104
|
+
throw new Error("Response body is not readable");
|
|
105
|
+
}
|
|
106
|
+
const reader = response.body.getReader();
|
|
109
107
|
const decoder = new TextDecoder();
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
108
|
+
try {
|
|
109
|
+
while (true) {
|
|
110
|
+
const { done, value } = await reader.read();
|
|
111
|
+
if (done)
|
|
112
|
+
break;
|
|
113
|
+
let data = decoder.decode(value, { stream: true });
|
|
114
|
+
try {
|
|
115
|
+
const parsed = JSON.parse(data);
|
|
116
|
+
if (config_1.sdkConfig.getDebug()) {
|
|
117
|
+
(0, log_1.debugLog)("📦 Stream Chunk:", parsed);
|
|
118
|
+
}
|
|
119
|
+
yield new messages_1.AIMessageChunk(parsed);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// 忽略解析错误
|
|
123
|
+
}
|
|
116
124
|
}
|
|
117
125
|
}
|
|
126
|
+
finally {
|
|
127
|
+
reader.releaseLock();
|
|
128
|
+
}
|
|
118
129
|
}
|
|
119
130
|
/**
|
|
120
131
|
* Batch invoke multiple message sets
|
|
121
132
|
* 遵循标准 LangChain API
|
|
122
133
|
*/
|
|
123
134
|
async batch(messagesList) {
|
|
124
|
-
const
|
|
135
|
+
const requestBody = {
|
|
136
|
+
messages_list: messagesList,
|
|
137
|
+
config: {
|
|
138
|
+
temperature: this.temperature,
|
|
139
|
+
max_tokens: this.maxTokens,
|
|
140
|
+
top_p: this.topP,
|
|
141
|
+
},
|
|
142
|
+
model: this.modelName,
|
|
143
|
+
provider: this.provider,
|
|
144
|
+
api_key_env: this.apiKey,
|
|
145
|
+
};
|
|
146
|
+
const url = `${config_1.sdkConfig.getServerUrl()}/api/langchain-proxy/batch`;
|
|
147
|
+
(0, log_1.logRequest)("POST", url, this.headers, requestBody);
|
|
148
|
+
const response = await fetch(url, {
|
|
125
149
|
method: "POST",
|
|
126
150
|
headers: this.headers,
|
|
127
|
-
body: JSON.stringify(
|
|
128
|
-
messages_list: messagesList.map((msgs) => msgs.map((msg) => msg.toJSON())),
|
|
129
|
-
config: {
|
|
130
|
-
temperature: this.temperature,
|
|
131
|
-
max_tokens: this.maxTokens,
|
|
132
|
-
top_p: this.topP,
|
|
133
|
-
},
|
|
134
|
-
model: this.modelName,
|
|
135
|
-
provider: this.provider,
|
|
136
|
-
api_key_env: this.apiKey,
|
|
137
|
-
}),
|
|
151
|
+
body: JSON.stringify(requestBody),
|
|
138
152
|
});
|
|
139
153
|
if (!response.ok) {
|
|
140
154
|
const errorText = await response.text();
|
|
155
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, errorText);
|
|
141
156
|
throw new Error(`Langchain API error: ${response.status} ${errorText}`);
|
|
142
157
|
}
|
|
143
158
|
// 返回标准 AIMessage 格式列表(从 message_to_dict 序列化)
|
package/dist/config.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ declare class SDKConfig {
|
|
|
6
6
|
private _baseUrl;
|
|
7
7
|
private _token;
|
|
8
8
|
private _headers;
|
|
9
|
+
private _debug;
|
|
10
|
+
constructor();
|
|
9
11
|
/**
|
|
10
12
|
* Set global base URL
|
|
11
13
|
* 设置全局 base URL
|
|
@@ -15,7 +17,7 @@ declare class SDKConfig {
|
|
|
15
17
|
* Get global base URL
|
|
16
18
|
* 获取全局 base URL
|
|
17
19
|
*/
|
|
18
|
-
|
|
20
|
+
getServerUrl(): string | null;
|
|
19
21
|
/**
|
|
20
22
|
* Set global token
|
|
21
23
|
* 设置全局 token
|
|
@@ -36,6 +38,16 @@ declare class SDKConfig {
|
|
|
36
38
|
* 获取全局 headers
|
|
37
39
|
*/
|
|
38
40
|
getHeaders(): Record<string, string>;
|
|
41
|
+
/**
|
|
42
|
+
* Set debug mode
|
|
43
|
+
* 设置调试模式
|
|
44
|
+
*/
|
|
45
|
+
setDebug(enabled: boolean): void;
|
|
46
|
+
/**
|
|
47
|
+
* Get debug mode
|
|
48
|
+
* 获取调试模式状态
|
|
49
|
+
*/
|
|
50
|
+
getDebug(): boolean;
|
|
39
51
|
/**
|
|
40
52
|
* Reset all global configuration
|
|
41
53
|
* 重置所有全局配置
|
package/dist/config.js
CHANGED
|
@@ -10,6 +10,23 @@ class SDKConfig {
|
|
|
10
10
|
this._baseUrl = null;
|
|
11
11
|
this._token = null;
|
|
12
12
|
this._headers = {};
|
|
13
|
+
this._debug = false;
|
|
14
|
+
// 通过cookie获取token
|
|
15
|
+
try {
|
|
16
|
+
const cookieString = typeof document !== 'undefined' ? document.cookie : '';
|
|
17
|
+
const tokenRow = cookieString.split('; ').find(row => row.startsWith('auth_token='));
|
|
18
|
+
if (tokenRow) {
|
|
19
|
+
const tokenValue = tokenRow.split('=')[1];
|
|
20
|
+
// 处理 URL 编码的 token(如果有)
|
|
21
|
+
this._token = decodeURIComponent(tokenValue);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
console.warn('Failed to read token from cookie:', error);
|
|
26
|
+
}
|
|
27
|
+
// 通过cookie获取baseUrl
|
|
28
|
+
const baseUrl = typeof window !== 'undefined' ? window.location.origin : '';
|
|
29
|
+
this._baseUrl = baseUrl;
|
|
13
30
|
}
|
|
14
31
|
/**
|
|
15
32
|
* Set global base URL
|
|
@@ -22,7 +39,7 @@ class SDKConfig {
|
|
|
22
39
|
* Get global base URL
|
|
23
40
|
* 获取全局 base URL
|
|
24
41
|
*/
|
|
25
|
-
|
|
42
|
+
getServerUrl() {
|
|
26
43
|
return this._baseUrl;
|
|
27
44
|
}
|
|
28
45
|
/**
|
|
@@ -53,6 +70,20 @@ class SDKConfig {
|
|
|
53
70
|
getHeaders() {
|
|
54
71
|
return { ...this._headers };
|
|
55
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Set debug mode
|
|
75
|
+
* 设置调试模式
|
|
76
|
+
*/
|
|
77
|
+
setDebug(enabled) {
|
|
78
|
+
this._debug = enabled;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get debug mode
|
|
82
|
+
* 获取调试模式状态
|
|
83
|
+
*/
|
|
84
|
+
getDebug() {
|
|
85
|
+
return this._debug;
|
|
86
|
+
}
|
|
56
87
|
/**
|
|
57
88
|
* Reset all global configuration
|
|
58
89
|
* 重置所有全局配置
|
|
@@ -61,6 +92,7 @@ class SDKConfig {
|
|
|
61
92
|
this._baseUrl = null;
|
|
62
93
|
this._token = null;
|
|
63
94
|
this._headers = {};
|
|
95
|
+
this._debug = false;
|
|
64
96
|
}
|
|
65
97
|
}
|
|
66
98
|
// 导出单例实例
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export interface ImageGenerationConfig {
|
|
6
6
|
baseUrl?: string;
|
|
7
|
-
token?: string;
|
|
8
7
|
headers?: Record<string, string>;
|
|
9
8
|
}
|
|
10
9
|
export interface ImageGenerationRequest {
|
|
@@ -27,7 +26,6 @@ export interface ImageGenerationResponse {
|
|
|
27
26
|
data: ImageData[];
|
|
28
27
|
}
|
|
29
28
|
export declare class ImageGenerationClient {
|
|
30
|
-
private baseUrl;
|
|
31
29
|
private headers;
|
|
32
30
|
constructor(config?: ImageGenerationConfig);
|
|
33
31
|
/**
|
package/dist/image_generation.js
CHANGED
|
@@ -6,26 +6,18 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.ImageGenerationClient = void 0;
|
|
8
8
|
const config_1 = require("./config");
|
|
9
|
+
const log_1 = require("./log");
|
|
9
10
|
class ImageGenerationClient {
|
|
10
11
|
constructor(config) {
|
|
11
|
-
// 使用提供的 baseUrl,否则使用全局配置
|
|
12
|
-
const baseUrl = config?.baseUrl || config_1.sdkConfig.getBaseUrl();
|
|
13
|
-
if (!baseUrl) {
|
|
14
|
-
throw new Error("baseUrl is required. Either provide it in config or set it globally using sdkConfig.setBaseUrl()");
|
|
15
|
-
}
|
|
16
|
-
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
17
12
|
// 合并全局 headers 和配置 headers
|
|
18
13
|
const globalHeaders = config_1.sdkConfig.getHeaders();
|
|
19
14
|
this.headers = {
|
|
20
15
|
"Content-Type": "application/json",
|
|
16
|
+
"Authorization": `Bearer ${config_1.sdkConfig.getToken()}`,
|
|
17
|
+
"X-Base-Url": config?.baseUrl || "",
|
|
21
18
|
...globalHeaders,
|
|
22
19
|
...config?.headers,
|
|
23
20
|
};
|
|
24
|
-
// 使用提供的 token,否则使用全局 token
|
|
25
|
-
const token = config?.token || config_1.sdkConfig.getToken();
|
|
26
|
-
if (token) {
|
|
27
|
-
this.headers["Authorization"] = `Bearer ${token}`;
|
|
28
|
-
}
|
|
29
21
|
}
|
|
30
22
|
/**
|
|
31
23
|
* Generate images
|
|
@@ -54,16 +46,20 @@ class ImageGenerationClient {
|
|
|
54
46
|
if (request.user) {
|
|
55
47
|
requestBody.user = request.user;
|
|
56
48
|
}
|
|
57
|
-
const
|
|
49
|
+
const url = `${config_1.sdkConfig.getServerUrl()}/api/image-proxy/generate`;
|
|
50
|
+
(0, log_1.logRequest)("POST", url, this.headers, requestBody);
|
|
51
|
+
const response = await fetch(url, {
|
|
58
52
|
method: "POST",
|
|
59
53
|
headers: this.headers,
|
|
60
54
|
body: JSON.stringify(requestBody),
|
|
61
55
|
});
|
|
62
56
|
if (!response.ok) {
|
|
63
57
|
const errorText = await response.text();
|
|
58
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, errorText);
|
|
64
59
|
throw new Error(`Image generation API error: ${response.status} ${errorText}`);
|
|
65
60
|
}
|
|
66
61
|
const data = (await response.json());
|
|
62
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, data);
|
|
67
63
|
return data;
|
|
68
64
|
}
|
|
69
65
|
}
|
package/dist/index.js
CHANGED
|
@@ -38,9 +38,10 @@ function createChatModel(model, config) {
|
|
|
38
38
|
// 如果没有提供 baseUrl,使用全局配置
|
|
39
39
|
const finalConfig = {
|
|
40
40
|
...config,
|
|
41
|
-
baseUrl:
|
|
42
|
-
token:
|
|
41
|
+
baseUrl: config_1.sdkConfig.getServerUrl() || undefined,
|
|
42
|
+
token: config_1.sdkConfig.getToken() || undefined,
|
|
43
43
|
headers: {
|
|
44
|
+
"X-Base-Url": config.baseUrl || "",
|
|
44
45
|
...config_1.sdkConfig.getHeaders(),
|
|
45
46
|
...config.headers,
|
|
46
47
|
},
|
package/dist/log.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug logging utilities
|
|
3
|
+
* 调试日志工具
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Debug logger utility
|
|
7
|
+
* 调试日志工具
|
|
8
|
+
*/
|
|
9
|
+
export declare function debugLog(...args: any[]): void;
|
|
10
|
+
/**
|
|
11
|
+
* Log HTTP request
|
|
12
|
+
* 记录 HTTP 请求
|
|
13
|
+
*/
|
|
14
|
+
export declare function logRequest(method: string, url: string, headers: Record<string, string>, body?: any): void;
|
|
15
|
+
/**
|
|
16
|
+
* Log HTTP response
|
|
17
|
+
* 记录 HTTP 响应
|
|
18
|
+
*/
|
|
19
|
+
export declare function logResponse(status: number, statusText: string, headers: Headers, body?: any): void;
|
package/dist/log.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Debug logging utilities
|
|
4
|
+
* 调试日志工具
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.debugLog = debugLog;
|
|
8
|
+
exports.logRequest = logRequest;
|
|
9
|
+
exports.logResponse = logResponse;
|
|
10
|
+
const config_1 = require("./config");
|
|
11
|
+
/**
|
|
12
|
+
* Debug logger utility
|
|
13
|
+
* 调试日志工具
|
|
14
|
+
*/
|
|
15
|
+
function debugLog(...args) {
|
|
16
|
+
if (config_1.sdkConfig.getDebug()) {
|
|
17
|
+
console.log("[AI-World-SDK]", ...args);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Log HTTP request
|
|
22
|
+
* 记录 HTTP 请求
|
|
23
|
+
*/
|
|
24
|
+
function logRequest(method, url, headers, body) {
|
|
25
|
+
if (!config_1.sdkConfig.getDebug())
|
|
26
|
+
return;
|
|
27
|
+
debugLog("📤 HTTP Request");
|
|
28
|
+
debugLog(" Method:", method);
|
|
29
|
+
debugLog(" URL:", url);
|
|
30
|
+
debugLog(" Headers:", { ...headers, Authorization: headers.Authorization ? "Bearer ***" : undefined });
|
|
31
|
+
if (body) {
|
|
32
|
+
try {
|
|
33
|
+
const bodyStr = typeof body === "string" ? body : JSON.stringify(body, null, 2);
|
|
34
|
+
debugLog(" Body:", bodyStr);
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
debugLog(" Body:", "[无法序列化]");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Log HTTP response
|
|
43
|
+
* 记录 HTTP 响应
|
|
44
|
+
*/
|
|
45
|
+
function logResponse(status, statusText, headers, body) {
|
|
46
|
+
if (!config_1.sdkConfig.getDebug())
|
|
47
|
+
return;
|
|
48
|
+
debugLog("📥 HTTP Response");
|
|
49
|
+
debugLog(" Status:", `${status} ${statusText}`);
|
|
50
|
+
debugLog(" Headers:", headers);
|
|
51
|
+
if (body !== undefined) {
|
|
52
|
+
try {
|
|
53
|
+
const bodyStr = typeof body === "string" ? body : JSON.stringify(body, null, 2);
|
|
54
|
+
// 限制响应体长度,避免日志过长
|
|
55
|
+
const maxLength = 1000;
|
|
56
|
+
const displayBody = bodyStr.length > maxLength
|
|
57
|
+
? bodyStr.substring(0, maxLength) + `... (${bodyStr.length - maxLength} more characters)`
|
|
58
|
+
: bodyStr;
|
|
59
|
+
debugLog(" Body:", displayBody);
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
debugLog(" Body:", "[无法序列化]");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
package/dist/messages.d.ts
CHANGED
|
@@ -10,28 +10,16 @@ export interface MessageContent {
|
|
|
10
10
|
export interface BaseMessage {
|
|
11
11
|
content: string | MessageContent[];
|
|
12
12
|
role?: "user" | "assistant" | "system";
|
|
13
|
-
toJSON(): {
|
|
14
|
-
role: string;
|
|
15
|
-
content: string | MessageContent[];
|
|
16
|
-
};
|
|
17
13
|
}
|
|
18
14
|
export declare class HumanMessage implements BaseMessage {
|
|
19
15
|
content: string | MessageContent[];
|
|
20
16
|
role: "user";
|
|
21
17
|
constructor(content: string | MessageContent[]);
|
|
22
|
-
toJSON(): {
|
|
23
|
-
role: string;
|
|
24
|
-
content: string | MessageContent[];
|
|
25
|
-
};
|
|
26
18
|
}
|
|
27
19
|
export declare class AIMessage implements BaseMessage {
|
|
28
20
|
content: string | MessageContent[];
|
|
29
21
|
role: "assistant";
|
|
30
22
|
constructor(content: string | MessageContent[]);
|
|
31
|
-
toJSON(): {
|
|
32
|
-
role: string;
|
|
33
|
-
content: string | MessageContent[];
|
|
34
|
-
};
|
|
35
23
|
}
|
|
36
24
|
export declare class SystemMessage implements BaseMessage {
|
|
37
25
|
content: string | MessageContent[];
|
package/dist/messages.js
CHANGED
|
@@ -10,12 +10,6 @@ class HumanMessage {
|
|
|
10
10
|
this.role = "user";
|
|
11
11
|
this.content = content;
|
|
12
12
|
}
|
|
13
|
-
toJSON() {
|
|
14
|
-
return {
|
|
15
|
-
role: this.role,
|
|
16
|
-
content: this.content,
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
13
|
}
|
|
20
14
|
exports.HumanMessage = HumanMessage;
|
|
21
15
|
class AIMessage {
|
|
@@ -23,12 +17,6 @@ class AIMessage {
|
|
|
23
17
|
this.role = "assistant";
|
|
24
18
|
this.content = content;
|
|
25
19
|
}
|
|
26
|
-
toJSON() {
|
|
27
|
-
return {
|
|
28
|
-
role: this.role,
|
|
29
|
-
content: this.content,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
20
|
}
|
|
33
21
|
exports.AIMessage = AIMessage;
|
|
34
22
|
class SystemMessage {
|
package/dist/video_generation.js
CHANGED
|
@@ -6,42 +6,38 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.VideoGenerationClient = void 0;
|
|
8
8
|
const config_1 = require("./config");
|
|
9
|
+
const log_1 = require("./log");
|
|
9
10
|
class VideoGenerationClient {
|
|
10
11
|
constructor(config) {
|
|
11
|
-
// 使用提供的 baseUrl,否则使用全局配置
|
|
12
|
-
const baseUrl = config?.baseUrl || config_1.sdkConfig.getBaseUrl();
|
|
13
|
-
if (!baseUrl) {
|
|
14
|
-
throw new Error("baseUrl is required. Either provide it in config or set it globally using sdkConfig.setBaseUrl()");
|
|
15
|
-
}
|
|
16
|
-
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
17
12
|
// 合并全局 headers 和配置 headers
|
|
18
13
|
const globalHeaders = config_1.sdkConfig.getHeaders();
|
|
19
14
|
this.headers = {
|
|
20
15
|
"Content-Type": "application/json",
|
|
16
|
+
"Authorization": `Bearer ${config_1.sdkConfig.getToken()}`,
|
|
17
|
+
"X-Base-Url": config?.baseUrl || "",
|
|
21
18
|
...globalHeaders,
|
|
22
19
|
...config?.headers,
|
|
23
20
|
};
|
|
24
|
-
// 使用提供的 token,否则使用全局 token
|
|
25
|
-
const token = config?.token || config_1.sdkConfig.getToken();
|
|
26
|
-
if (token) {
|
|
27
|
-
this.headers["Authorization"] = `Bearer ${token}`;
|
|
28
|
-
}
|
|
29
21
|
}
|
|
30
22
|
/**
|
|
31
23
|
* Create a video generation task
|
|
32
24
|
* 创建视频生成任务
|
|
33
25
|
*/
|
|
34
26
|
async create(request) {
|
|
35
|
-
const
|
|
27
|
+
const url = `${config_1.sdkConfig.getServerUrl()}/api/video-proxy/generate`;
|
|
28
|
+
(0, log_1.logRequest)("POST", url, this.headers, request);
|
|
29
|
+
const response = await fetch(url, {
|
|
36
30
|
method: "POST",
|
|
37
31
|
headers: this.headers,
|
|
38
32
|
body: JSON.stringify(request),
|
|
39
33
|
});
|
|
40
34
|
if (!response.ok) {
|
|
41
35
|
const errorText = await response.text();
|
|
36
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, errorText);
|
|
42
37
|
throw new Error(`Video generation API error: ${response.status} ${errorText}`);
|
|
43
38
|
}
|
|
44
39
|
const data = (await response.json());
|
|
40
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, data);
|
|
45
41
|
return data;
|
|
46
42
|
}
|
|
47
43
|
/**
|
|
@@ -49,15 +45,19 @@ class VideoGenerationClient {
|
|
|
49
45
|
* 查询视频生成任务状态
|
|
50
46
|
*/
|
|
51
47
|
async get(taskId) {
|
|
52
|
-
const
|
|
48
|
+
const url = `${config_1.sdkConfig.getServerUrl()}/api/video-proxy/${taskId}`;
|
|
49
|
+
(0, log_1.logRequest)("GET", url, this.headers);
|
|
50
|
+
const response = await fetch(url, {
|
|
53
51
|
method: "GET",
|
|
54
52
|
headers: this.headers,
|
|
55
53
|
});
|
|
56
54
|
if (!response.ok) {
|
|
57
55
|
const errorText = await response.text();
|
|
56
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, errorText);
|
|
58
57
|
throw new Error(`Get video task API error: ${response.status} ${errorText}`);
|
|
59
58
|
}
|
|
60
59
|
const data = (await response.json());
|
|
60
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, data);
|
|
61
61
|
return data;
|
|
62
62
|
}
|
|
63
63
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-world-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "TypeScript SDK for AI World Platform - Chat Models, Image Generation, and Video Generation",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"test:aihubmix-no-stream": "jest -t 'aihubmix.com no stream'",
|
|
18
18
|
"test:aihubmix-stream": "jest -t 'aihubmix.com stream'",
|
|
19
19
|
"test:aihubmix-image": "jest -t 'aihubmix.com 图像生成'",
|
|
20
|
+
"test:google-image": "jest -t 'ChatGoogleGenerativeAI - Google 图像生成'",
|
|
20
21
|
"test:seedream-image": "jest -t 'seedream 图像生成'",
|
|
21
22
|
"test:image-generation": "jest -t 'ImageGenerationClient - 基础图像生成'",
|
|
22
23
|
"test:video-generation": "jest -t 'VideoGenerationClient - 轮询视频生成任务'"
|