ai-world-sdk 1.1.1 → 1.1.3
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 +285 -5
- package/dist/__tests__/example.test.js +397 -4
- package/dist/base.d.ts +1 -1
- package/dist/base.js +60 -8
- package/dist/config.d.ts +3 -3
- package/dist/config.js +2 -2
- package/dist/gemini-image-generation.d.ts +2 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +17 -16
- package/dist/log.js +1 -1
- package/dist/openai_video_generation.d.ts +188 -0
- package/dist/openai_video_generation.js +287 -0
- package/dist/provider_config.d.ts +8 -0
- package/dist/provider_config.js +14 -0
- package/package.json +1 -1
|
@@ -44,7 +44,7 @@ const fs_1 = require("fs");
|
|
|
44
44
|
dotenv.config();
|
|
45
45
|
index_1.sdkConfig.setBaseUrl("http://localhost:8000");
|
|
46
46
|
index_1.sdkConfig.setToken(process.env.AUTH_TOKEN || process.env.TOKEN || "");
|
|
47
|
-
|
|
47
|
+
index_1.sdkConfig.setDebug(true);
|
|
48
48
|
function extractTextFromChunk(chunk) {
|
|
49
49
|
if (typeof chunk.content === "string") {
|
|
50
50
|
return chunk.content;
|
|
@@ -882,7 +882,7 @@ describe("Langchain SDK Tests", () => {
|
|
|
882
882
|
const openai = new index_1.ChatOpenAI({
|
|
883
883
|
modelName: "gpt-4",
|
|
884
884
|
temperature: 0.7,
|
|
885
|
-
provider: "
|
|
885
|
+
provider: "api2img",
|
|
886
886
|
});
|
|
887
887
|
let fullText = "";
|
|
888
888
|
for await (const chunk of openai.stream([
|
|
@@ -891,14 +891,14 @@ describe("Langchain SDK Tests", () => {
|
|
|
891
891
|
fullText += extractTextFromChunk(chunk);
|
|
892
892
|
}
|
|
893
893
|
expect(fullText.length).toBeGreaterThan(0);
|
|
894
|
-
console.log("✅ ChatOpenAI 流式测试成功");
|
|
894
|
+
console.log("✅ ChatOpenAI 流式测试成功 " + fullText);
|
|
895
895
|
console.log(`完整回复长度: ${fullText.length} 字符`);
|
|
896
896
|
}, 30000);
|
|
897
897
|
test("ChatOpenAI - batch 方法", async () => {
|
|
898
898
|
const openai = new index_1.ChatOpenAI({
|
|
899
899
|
modelName: "gpt-4",
|
|
900
900
|
temperature: 0.7,
|
|
901
|
-
provider: "
|
|
901
|
+
provider: "api2img",
|
|
902
902
|
});
|
|
903
903
|
const responses = await openai.batch([
|
|
904
904
|
[new index_1.HumanMessage("什么是人工智能?")],
|
|
@@ -1148,4 +1148,397 @@ describe("Langchain SDK Tests", () => {
|
|
|
1148
1148
|
console.log("响应内容:", content);
|
|
1149
1149
|
}
|
|
1150
1150
|
}, 30000);
|
|
1151
|
+
// ========== OpenAI 视频生成测试 ==========
|
|
1152
|
+
test("OpenAIVideoGenerationClient - 创建视频生成任务(文本)", async () => {
|
|
1153
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1154
|
+
const task = await openaiVideoClient.generate({
|
|
1155
|
+
prompt: "A beautiful sunset over the ocean with waves crashing on the shore",
|
|
1156
|
+
model: "sora-2",
|
|
1157
|
+
provider: "aihubmix",
|
|
1158
|
+
seconds: "4",
|
|
1159
|
+
size: "1280x720",
|
|
1160
|
+
});
|
|
1161
|
+
expect(task).toBeDefined();
|
|
1162
|
+
expect(task.id).toBeDefined();
|
|
1163
|
+
expect(typeof task.id).toBe("string");
|
|
1164
|
+
expect(task.status).toBeDefined();
|
|
1165
|
+
expect(["queued", "in_progress", "completed", "failed"]).toContain(task.status);
|
|
1166
|
+
console.log("✅ OpenAI 视频生成任务创建成功(文本)");
|
|
1167
|
+
console.log("任务 ID:", task.id);
|
|
1168
|
+
console.log("任务状态:", task.status);
|
|
1169
|
+
}, 60000);
|
|
1170
|
+
test("OpenAIVideoGenerationClient - 创建视频生成任务(图像)", async () => {
|
|
1171
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1172
|
+
// 使用一个小的 base64 图像
|
|
1173
|
+
const base64Image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAJCAIAAACAMfp5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAFgmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgOS4xLWMwMDIgNzkuZGJhM2RhM2I1LCAyMDIzLzEyLzE1LTEwOjQyOjM3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB0aWZmOk9yaWVudGF0aW9uPSIxIiBleGlmOkNvbG9yU3BhY2U9IjEiIGV4aWY6UGl4ZWxYRGltZW5zaW9uPSI4IiBleGlmOlBpeGVsWURpbWVuc2lvbj0iOSIgeG1wOkNyZWF0ZURhdGU9IjIwMjUtMTItMTlUMTI6MDY6MDMrMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDI1LTEyLTE5VDEyOjA2OjM1KzA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDI1LTEyLTE5VDEyOjA2OjM1KzA4OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo5Y2IwNmRjYi04MmI0LTQ3ODctYmQ1Ny1lYWI5MzE5MzkyYzUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OWNiMDZkY2ItODJiNC00Nzg3LWJkNTctZWFiOTMxOTM5MmM1IiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6OWNiMDZkY2ItODJiNC00Nzg3LWJkNTctZWFiOTMxOTM5MmM1Ij4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6OWNiMDZkY2ItODJiNC00Nzg3LWJkNTctZWFiOTMxOTM5MmM1IiBzdEV2dDp3aGVuPSIyMDI1LTEyLTE5VDEyOjA2OjM1KzA4OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgMjUuNiAoTWFjaW50b3NoKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6KNh+8AAAAEElEQVQIHWNgYPiPAw0PCQA/Vke5jW7wRQAAAABJRU5ErkJggg==";
|
|
1174
|
+
const task = await openaiVideoClient.generate({
|
|
1175
|
+
prompt: "Animate this scene with gentle movements",
|
|
1176
|
+
input_reference: base64Image,
|
|
1177
|
+
model: "sora-2",
|
|
1178
|
+
provider: "aihubmix",
|
|
1179
|
+
seconds: "4",
|
|
1180
|
+
});
|
|
1181
|
+
console.log("task:", task);
|
|
1182
|
+
expect(task).toBeDefined();
|
|
1183
|
+
expect(task.id).toBeDefined();
|
|
1184
|
+
expect(typeof task.id).toBe("string");
|
|
1185
|
+
console.log("✅ OpenAI 视频生成任务创建成功(图像)");
|
|
1186
|
+
console.log("任务 ID:", task.id);
|
|
1187
|
+
}, 60000);
|
|
1188
|
+
test("OpenAIVideoGenerationClient - 查询任务状态", async () => {
|
|
1189
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1190
|
+
// // 先创建一个任务
|
|
1191
|
+
// const createTask = await openaiVideoClient.generate({
|
|
1192
|
+
// prompt: "A serene mountain landscape",
|
|
1193
|
+
// model: "sora-2",
|
|
1194
|
+
// provider: "aihubmix",
|
|
1195
|
+
// seconds: "4",
|
|
1196
|
+
// });
|
|
1197
|
+
// console.log("createTask:", createTask);
|
|
1198
|
+
// expect(createTask.id).toBeDefined();
|
|
1199
|
+
// 查询任务状态
|
|
1200
|
+
let taskId = "eyJtb2RlbCI6InNvcmEtMiIsImlkIjoidmlkZW9fNjk0YmYxYzZjNTEwODE5MDliZjBlNDc5ZDI3OGU5ODYifQchannel2361";
|
|
1201
|
+
// 轮询任务(使用较短的超时时间用于测试)
|
|
1202
|
+
try {
|
|
1203
|
+
const result = await openaiVideoClient.waitForCompletion(taskId, "aihubmix", {
|
|
1204
|
+
maxAttempts: 30, // 最多轮询 30 次
|
|
1205
|
+
interval: 5000, // 每 5 秒轮询一次
|
|
1206
|
+
onProgress: (status) => {
|
|
1207
|
+
console.log(`进度更新: ${status.status}`);
|
|
1208
|
+
}
|
|
1209
|
+
});
|
|
1210
|
+
console.log("--------------------------------");
|
|
1211
|
+
console.log("result:", JSON.stringify(result, null, 2));
|
|
1212
|
+
console.log("--------------------------------");
|
|
1213
|
+
expect(result).toBeDefined();
|
|
1214
|
+
expect(["completed", "failed"]).toContain(result.status);
|
|
1215
|
+
console.log("✅ OpenAI 视频任务轮询完成");
|
|
1216
|
+
console.log("最终状态:", result.status);
|
|
1217
|
+
if (result.status === "completed") {
|
|
1218
|
+
console.log("视频 ID:", result.id);
|
|
1219
|
+
}
|
|
1220
|
+
else if (result.error) {
|
|
1221
|
+
console.log("错误信息:", result.error);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
catch (error) {
|
|
1225
|
+
// 如果超时,这是正常的(视频生成需要时间)
|
|
1226
|
+
if (error.message?.includes("已轮询") || error.message?.includes("仍未完成")) {
|
|
1227
|
+
console.log("⏭️ 轮询超时(正常,视频生成需要较长时间)");
|
|
1228
|
+
}
|
|
1229
|
+
else {
|
|
1230
|
+
throw error;
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
}, 60000);
|
|
1234
|
+
test("OpenAIVideoGenerationClient - 轮询等待完成", async () => {
|
|
1235
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1236
|
+
// 创建任务
|
|
1237
|
+
const createTask = await openaiVideoClient.generate({
|
|
1238
|
+
prompt: "A short video of clouds moving across the sky",
|
|
1239
|
+
model: "sora-2",
|
|
1240
|
+
provider: "aihubmix",
|
|
1241
|
+
seconds: "4",
|
|
1242
|
+
});
|
|
1243
|
+
expect(createTask.id).toBeDefined();
|
|
1244
|
+
console.log("任务创建:", createTask.id);
|
|
1245
|
+
// 轮询任务(使用较短的超时时间用于测试)
|
|
1246
|
+
try {
|
|
1247
|
+
const result = await openaiVideoClient.waitForCompletion(createTask.id, "aihubmix", {
|
|
1248
|
+
maxAttempts: 30, // 最多轮询 30 次
|
|
1249
|
+
interval: 5000, // 每 5 秒轮询一次
|
|
1250
|
+
onProgress: (status) => {
|
|
1251
|
+
console.log(`进度更新: ${status.status}`);
|
|
1252
|
+
}
|
|
1253
|
+
});
|
|
1254
|
+
expect(result).toBeDefined();
|
|
1255
|
+
expect(["completed", "failed"]).toContain(result.status);
|
|
1256
|
+
console.log("✅ OpenAI 视频任务轮询完成");
|
|
1257
|
+
console.log("最终状态:", result.status);
|
|
1258
|
+
if (result.status === "completed") {
|
|
1259
|
+
console.log("视频 ID:", result.id);
|
|
1260
|
+
}
|
|
1261
|
+
else if (result.error) {
|
|
1262
|
+
console.log("错误信息:", result.error);
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
catch (error) {
|
|
1266
|
+
// 如果超时,这是正常的(视频生成需要时间)
|
|
1267
|
+
if (error.message?.includes("已轮询") || error.message?.includes("仍未完成")) {
|
|
1268
|
+
console.log("⏭️ 轮询超时(正常,视频生成需要较长时间)");
|
|
1269
|
+
}
|
|
1270
|
+
else {
|
|
1271
|
+
throw error;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
}, 180000);
|
|
1275
|
+
test("OpenAIVideoGenerationClient - 一键生成并等待", async () => {
|
|
1276
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1277
|
+
try {
|
|
1278
|
+
const result = await openaiVideoClient.generateAndWait({
|
|
1279
|
+
prompt: "A futuristic city skyline",
|
|
1280
|
+
model: "sora-2",
|
|
1281
|
+
provider: "aihubmix",
|
|
1282
|
+
seconds: "4",
|
|
1283
|
+
size: "1280x720"
|
|
1284
|
+
}, {
|
|
1285
|
+
maxAttempts: 30,
|
|
1286
|
+
interval: 5000,
|
|
1287
|
+
onProgress: (status) => {
|
|
1288
|
+
console.log("状态:", status.status);
|
|
1289
|
+
}
|
|
1290
|
+
});
|
|
1291
|
+
expect(result).toBeDefined();
|
|
1292
|
+
expect(result.id).toBeDefined();
|
|
1293
|
+
expect(["completed", "failed"]).toContain(result.status);
|
|
1294
|
+
console.log("✅ OpenAI 一键生成并等待测试完成");
|
|
1295
|
+
console.log("最终状态:", result.status);
|
|
1296
|
+
}
|
|
1297
|
+
catch (error) {
|
|
1298
|
+
if (error.message?.includes("已轮询") || error.message?.includes("仍未完成")) {
|
|
1299
|
+
console.log("⏭️ 轮询超时(正常)");
|
|
1300
|
+
}
|
|
1301
|
+
else {
|
|
1302
|
+
throw error;
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
}, 180000);
|
|
1306
|
+
test("OpenAIVideoGenerationClient - 不同 provider 测试", async () => {
|
|
1307
|
+
const providers = ["api2img"];
|
|
1308
|
+
for (const provider of providers) {
|
|
1309
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1310
|
+
const task = await openaiVideoClient.generate({
|
|
1311
|
+
prompt: "A simple animation",
|
|
1312
|
+
model: "sora-2",
|
|
1313
|
+
provider: provider,
|
|
1314
|
+
seconds: "4",
|
|
1315
|
+
});
|
|
1316
|
+
expect(task).toBeDefined();
|
|
1317
|
+
expect(task.id).toBeDefined();
|
|
1318
|
+
console.log(`✅ provider ${provider} 测试成功,任务 ID: ${task.id}`);
|
|
1319
|
+
}
|
|
1320
|
+
}, 120000);
|
|
1321
|
+
test("OpenAIVideoGenerationClient - 不同 seconds 参数测试", async () => {
|
|
1322
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1323
|
+
const secondsOptions = ["4", "8"];
|
|
1324
|
+
for (const seconds of secondsOptions) {
|
|
1325
|
+
const task = await openaiVideoClient.generate({
|
|
1326
|
+
prompt: "A video clip",
|
|
1327
|
+
model: "sora-2",
|
|
1328
|
+
provider: "aihubmix",
|
|
1329
|
+
seconds: seconds,
|
|
1330
|
+
});
|
|
1331
|
+
expect(task).toBeDefined();
|
|
1332
|
+
expect(task.id).toBeDefined();
|
|
1333
|
+
console.log(`✅ seconds ${seconds} 测试成功,任务 ID: ${task.id}`);
|
|
1334
|
+
}
|
|
1335
|
+
}, 120000);
|
|
1336
|
+
test("OpenAIVideoGenerationClient - 不同 size 参数测试", async () => {
|
|
1337
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1338
|
+
const sizeOptions = [
|
|
1339
|
+
"1280x720",
|
|
1340
|
+
"720x1280",
|
|
1341
|
+
];
|
|
1342
|
+
for (const size of sizeOptions) {
|
|
1343
|
+
const task = await openaiVideoClient.generate({
|
|
1344
|
+
prompt: "A landscape video",
|
|
1345
|
+
model: "sora-2",
|
|
1346
|
+
provider: "aihubmix",
|
|
1347
|
+
seconds: "4",
|
|
1348
|
+
size: size,
|
|
1349
|
+
});
|
|
1350
|
+
expect(task).toBeDefined();
|
|
1351
|
+
expect(task.id).toBeDefined();
|
|
1352
|
+
console.log(`✅ size ${size} 测试成功,任务 ID: ${task.id}`);
|
|
1353
|
+
}
|
|
1354
|
+
}, 120000);
|
|
1355
|
+
test("OpenAIVideoGenerationClient - 下载视频测试", async () => {
|
|
1356
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1357
|
+
let taskId = "eyJtb2RlbCI6InNvcmEtMiIsImlkIjoidmlkZW9fNjk0YmYxYzZjNTEwODE5MDliZjBlNDc5ZDI3OGU5ODYifQchannel2361";
|
|
1358
|
+
// 等待任务完成
|
|
1359
|
+
try {
|
|
1360
|
+
const result = await openaiVideoClient.waitForCompletion(taskId, "aihubmix", {
|
|
1361
|
+
maxAttempts: 30,
|
|
1362
|
+
interval: 5000,
|
|
1363
|
+
});
|
|
1364
|
+
console.log("result:", result);
|
|
1365
|
+
if (result.status === "completed") {
|
|
1366
|
+
// 下载视频
|
|
1367
|
+
const videoBlob = await openaiVideoClient.downloadVideo(result.id, "aihubmix", "video");
|
|
1368
|
+
expect(videoBlob).toBeDefined();
|
|
1369
|
+
expect(videoBlob instanceof Blob).toBe(true);
|
|
1370
|
+
expect(videoBlob.size).toBeGreaterThan(0);
|
|
1371
|
+
console.log("✅ OpenAI 视频下载测试成功");
|
|
1372
|
+
console.log(`视频大小: ${(videoBlob.size / 1024 / 1024).toFixed(2)} MB`);
|
|
1373
|
+
}
|
|
1374
|
+
else {
|
|
1375
|
+
console.log("⏭️ 任务未完成,跳过下载测试");
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
catch (error) {
|
|
1379
|
+
if (error.message?.includes("已轮询") || error.message?.includes("仍未完成")) {
|
|
1380
|
+
console.log("⏭️ 轮询超时,跳过下载测试");
|
|
1381
|
+
}
|
|
1382
|
+
else {
|
|
1383
|
+
throw error;
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
}, 180000);
|
|
1387
|
+
test("OpenAIVideoGenerationClient - 下载缩略图测试", async () => {
|
|
1388
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1389
|
+
// 创建任务
|
|
1390
|
+
const createTask = await openaiVideoClient.generate({
|
|
1391
|
+
prompt: "A simple scene for thumbnail test",
|
|
1392
|
+
model: "sora-2",
|
|
1393
|
+
provider: "aihubmix",
|
|
1394
|
+
seconds: "4",
|
|
1395
|
+
});
|
|
1396
|
+
expect(createTask.id).toBeDefined();
|
|
1397
|
+
console.log("创建任务:", createTask.id);
|
|
1398
|
+
// 等待任务完成
|
|
1399
|
+
try {
|
|
1400
|
+
const result = await openaiVideoClient.waitForCompletion(createTask.id, "aihubmix", {
|
|
1401
|
+
maxAttempts: 30,
|
|
1402
|
+
interval: 5000,
|
|
1403
|
+
});
|
|
1404
|
+
if (result.status === "completed") {
|
|
1405
|
+
// 下载缩略图
|
|
1406
|
+
const thumbnailBlob = await openaiVideoClient.downloadVideo(result.id, "aihubmix", "thumbnail");
|
|
1407
|
+
expect(thumbnailBlob).toBeDefined();
|
|
1408
|
+
expect(thumbnailBlob instanceof Blob).toBe(true);
|
|
1409
|
+
expect(thumbnailBlob.size).toBeGreaterThan(0);
|
|
1410
|
+
console.log("✅ OpenAI 缩略图下载测试成功");
|
|
1411
|
+
console.log(`缩略图大小: ${(thumbnailBlob.size / 1024).toFixed(2)} KB`);
|
|
1412
|
+
}
|
|
1413
|
+
else {
|
|
1414
|
+
console.log("⏭️ 任务未完成,跳过缩略图下载测试");
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
catch (error) {
|
|
1418
|
+
if (error.message?.includes("已轮询") || error.message?.includes("仍未完成")) {
|
|
1419
|
+
console.log("⏭️ 轮询超时,跳过缩略图下载测试");
|
|
1420
|
+
}
|
|
1421
|
+
else {
|
|
1422
|
+
throw error;
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
}, 180000);
|
|
1426
|
+
test("OpenAIVideoGenerationClient - 不同 provider 下载测试", async () => {
|
|
1427
|
+
const providers = ["api2img"];
|
|
1428
|
+
for (const provider of providers) {
|
|
1429
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1430
|
+
// 创建任务
|
|
1431
|
+
const createTask = await openaiVideoClient.generate({
|
|
1432
|
+
prompt: "A test video for download",
|
|
1433
|
+
model: "sora-2",
|
|
1434
|
+
provider: provider,
|
|
1435
|
+
seconds: "4",
|
|
1436
|
+
});
|
|
1437
|
+
expect(createTask.id).toBeDefined();
|
|
1438
|
+
console.log(`${provider} 创建任务:`, createTask.id);
|
|
1439
|
+
try {
|
|
1440
|
+
const result = await openaiVideoClient.waitForCompletion(createTask.id, provider, {
|
|
1441
|
+
maxAttempts: 30,
|
|
1442
|
+
interval: 5000,
|
|
1443
|
+
});
|
|
1444
|
+
if (result.status === "completed") {
|
|
1445
|
+
// 下载视频
|
|
1446
|
+
const videoBlob = await openaiVideoClient.downloadVideo(result.id, provider, "video");
|
|
1447
|
+
expect(videoBlob).toBeDefined();
|
|
1448
|
+
expect(videoBlob instanceof Blob).toBe(true);
|
|
1449
|
+
expect(videoBlob.size).toBeGreaterThan(0);
|
|
1450
|
+
console.log(`✅ provider ${provider} 下载测试成功`);
|
|
1451
|
+
console.log(`视频大小: ${(videoBlob.size / 1024 / 1024).toFixed(2)} MB`);
|
|
1452
|
+
}
|
|
1453
|
+
else {
|
|
1454
|
+
console.log(`⏭️ ${provider} 任务未完成,跳过下载测试`);
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
catch (error) {
|
|
1458
|
+
if (error.message?.includes("已轮询") || error.message?.includes("仍未完成")) {
|
|
1459
|
+
console.log(`⏭️ ${provider} 轮询超时,跳过下载测试`);
|
|
1460
|
+
}
|
|
1461
|
+
else {
|
|
1462
|
+
throw error;
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
}, 360000);
|
|
1467
|
+
test("OpenAIVideoGenerationClient - 直接下载已完成的视频", async () => {
|
|
1468
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1469
|
+
// 使用一个已知完成的视频 ID(从前面测试中获取)
|
|
1470
|
+
// 注意:这需要一个真实的已完成视频 ID,此处仅作示例
|
|
1471
|
+
const knownVideoId = "eyJtb2RlbCI6InNvcmEtMiIsImlkIjoidmlkZW9fNjk0YmYxYzZjNTEwODE5MDliZjBlNDc5ZDI3OGU5ODYifQchannel2361";
|
|
1472
|
+
try {
|
|
1473
|
+
// 先查询状态
|
|
1474
|
+
const status = await openaiVideoClient.getTask(knownVideoId, "aihubmix");
|
|
1475
|
+
if (status.status === "completed") {
|
|
1476
|
+
// 下载视频
|
|
1477
|
+
const videoBlob = await openaiVideoClient.downloadVideo(knownVideoId, "aihubmix", "video");
|
|
1478
|
+
expect(videoBlob).toBeDefined();
|
|
1479
|
+
expect(videoBlob instanceof Blob).toBe(true);
|
|
1480
|
+
expect(videoBlob.size).toBeGreaterThan(0);
|
|
1481
|
+
console.log("✅ 直接下载已完成视频测试成功");
|
|
1482
|
+
console.log(`视频大小: ${(videoBlob.size / 1024 / 1024).toFixed(2)} MB`);
|
|
1483
|
+
}
|
|
1484
|
+
else {
|
|
1485
|
+
console.log(`⏭️ 视频状态: ${status.status},跳过下载测试`);
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
catch (error) {
|
|
1489
|
+
// 视频可能已过期或不存在
|
|
1490
|
+
console.log("⏭️ 视频不存在或已过期,跳过测试");
|
|
1491
|
+
}
|
|
1492
|
+
}, 60000);
|
|
1493
|
+
test("OpenAIVideoGenerationClient - 完整流程:生成、等待、下载", async () => {
|
|
1494
|
+
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
|
1495
|
+
try {
|
|
1496
|
+
console.log("1️⃣ 开始生成视频...");
|
|
1497
|
+
const task = await openaiVideoClient.generate({
|
|
1498
|
+
prompt: "A complete workflow test video",
|
|
1499
|
+
model: "sora-2",
|
|
1500
|
+
provider: "aihubmix",
|
|
1501
|
+
seconds: "4",
|
|
1502
|
+
});
|
|
1503
|
+
expect(task.id).toBeDefined();
|
|
1504
|
+
console.log(`任务创建成功: ${task.id}`);
|
|
1505
|
+
console.log("2️⃣ 等待视频生成完成...");
|
|
1506
|
+
const result = await openaiVideoClient.waitForCompletion(task.id, "aihubmix", {
|
|
1507
|
+
maxAttempts: 30,
|
|
1508
|
+
interval: 5000,
|
|
1509
|
+
onProgress: (status) => {
|
|
1510
|
+
console.log(` 进度: ${status.status}`);
|
|
1511
|
+
},
|
|
1512
|
+
});
|
|
1513
|
+
expect(result.status).toBeDefined();
|
|
1514
|
+
console.log(`视频生成完成: ${result.status}`);
|
|
1515
|
+
if (result.status === "completed") {
|
|
1516
|
+
console.log("3️⃣ 下载视频...");
|
|
1517
|
+
const videoBlob = await openaiVideoClient.downloadVideo(result.id, "aihubmix", "video");
|
|
1518
|
+
expect(videoBlob).toBeDefined();
|
|
1519
|
+
expect(videoBlob instanceof Blob).toBe(true);
|
|
1520
|
+
expect(videoBlob.size).toBeGreaterThan(0);
|
|
1521
|
+
console.log("✅ 完整流程测试成功");
|
|
1522
|
+
console.log(` - 任务 ID: ${result.id}`);
|
|
1523
|
+
console.log(` - 视频大小: ${(videoBlob.size / 1024 / 1024).toFixed(2)} MB`);
|
|
1524
|
+
// 也下载缩略图
|
|
1525
|
+
console.log("4️⃣ 下载缩略图...");
|
|
1526
|
+
const thumbnailBlob = await openaiVideoClient.downloadVideo(result.id, "aihubmix", "thumbnail");
|
|
1527
|
+
expect(thumbnailBlob).toBeDefined();
|
|
1528
|
+
expect(thumbnailBlob instanceof Blob).toBe(true);
|
|
1529
|
+
console.log(` - 缩略图大小: ${(thumbnailBlob.size / 1024).toFixed(2)} KB`);
|
|
1530
|
+
}
|
|
1531
|
+
else {
|
|
1532
|
+
console.log("⏭️ 视频生成失败或未完成");
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
catch (error) {
|
|
1536
|
+
if (error.message?.includes("已轮询") || error.message?.includes("仍未完成")) {
|
|
1537
|
+
console.log("⏭️ 轮询超时(正常,视频生成需要较长时间)");
|
|
1538
|
+
}
|
|
1539
|
+
else {
|
|
1540
|
+
throw error;
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
}, 240000);
|
|
1151
1544
|
});
|
package/dist/base.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Similar to LangChain.js BaseChatModel
|
|
4
4
|
*/
|
|
5
5
|
import { BaseMessage, AIMessage, AIMessageChunk } from "./messages";
|
|
6
|
-
|
|
6
|
+
import type { AIModelProvider } from "./provider_config";
|
|
7
7
|
export interface BaseChatModelParams {
|
|
8
8
|
provider: AIModelProvider;
|
|
9
9
|
baseUrl?: string;
|
package/dist/base.js
CHANGED
|
@@ -130,21 +130,73 @@ class BaseChatModel {
|
|
|
130
130
|
}
|
|
131
131
|
const reader = response.body.getReader();
|
|
132
132
|
const decoder = new TextDecoder();
|
|
133
|
+
let buffer = "";
|
|
133
134
|
try {
|
|
134
135
|
while (true) {
|
|
135
136
|
const { done, value } = await reader.read();
|
|
136
137
|
if (done)
|
|
137
138
|
break;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
buffer += decoder.decode(value, { stream: true });
|
|
140
|
+
console.log('buffer', buffer);
|
|
141
|
+
// 按行分割处理 SSE 格式数据
|
|
142
|
+
const lines = buffer.split("\n");
|
|
143
|
+
// 保留最后一个可能不完整的行
|
|
144
|
+
buffer = lines.pop() || "";
|
|
145
|
+
for (const line of lines) {
|
|
146
|
+
const trimmedLine = line.trim();
|
|
147
|
+
// 跳过空行
|
|
148
|
+
if (!trimmedLine)
|
|
149
|
+
continue;
|
|
150
|
+
// 检查结束标志
|
|
151
|
+
if (trimmedLine === "data: [DONE]") {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
// 处理 SSE 格式 "data: {...}"
|
|
155
|
+
if (trimmedLine.startsWith("data: ")) {
|
|
156
|
+
const jsonStr = trimmedLine.slice(6); // 去掉 "data: " 前缀
|
|
157
|
+
try {
|
|
158
|
+
const parsed = JSON.parse(jsonStr);
|
|
159
|
+
if (config_1.sdkConfig.getDebug()) {
|
|
160
|
+
(0, log_1.debugLog)("📦 Stream Chunk:", parsed);
|
|
161
|
+
}
|
|
162
|
+
yield new messages_1.AIMessageChunk(parsed);
|
|
163
|
+
}
|
|
164
|
+
catch (e) {
|
|
165
|
+
if (config_1.sdkConfig.getDebug()) {
|
|
166
|
+
(0, log_1.debugLog)("⚠️ Failed to parse SSE data:", jsonStr, e);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
// 尝试直接解析(兼容非 SSE 格式)
|
|
172
|
+
try {
|
|
173
|
+
const parsed = JSON.parse(trimmedLine);
|
|
174
|
+
if (config_1.sdkConfig.getDebug()) {
|
|
175
|
+
(0, log_1.debugLog)("📦 Stream Chunk (non-SSE):", parsed);
|
|
176
|
+
}
|
|
177
|
+
yield new messages_1.AIMessageChunk(parsed);
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
// 忽略无法解析的行
|
|
181
|
+
}
|
|
143
182
|
}
|
|
144
|
-
yield new messages_1.AIMessageChunk(parsed);
|
|
145
183
|
}
|
|
146
|
-
|
|
147
|
-
|
|
184
|
+
}
|
|
185
|
+
// 处理缓冲区中剩余的数据
|
|
186
|
+
if (buffer.trim()) {
|
|
187
|
+
const trimmedBuffer = buffer.trim();
|
|
188
|
+
if (trimmedBuffer.startsWith("data: ") && trimmedBuffer !== "data: [DONE]") {
|
|
189
|
+
const jsonStr = trimmedBuffer.slice(6);
|
|
190
|
+
try {
|
|
191
|
+
const parsed = JSON.parse(jsonStr);
|
|
192
|
+
if (config_1.sdkConfig.getDebug()) {
|
|
193
|
+
(0, log_1.debugLog)("📦 Stream Chunk (final):", parsed);
|
|
194
|
+
}
|
|
195
|
+
yield new messages_1.AIMessageChunk(parsed);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// 忽略解析错误
|
|
199
|
+
}
|
|
148
200
|
}
|
|
149
201
|
}
|
|
150
202
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* 注意: {VERSION} 占位符会在构建时被替换为实际版本号
|
|
11
11
|
*/
|
|
12
|
-
export declare const SDK_SIGNATURE = "AI_WORLD_SDK_V:1.1.
|
|
12
|
+
export declare const SDK_SIGNATURE = "AI_WORLD_SDK_V:1.1.3";
|
|
13
13
|
/**
|
|
14
14
|
* 版本兼容性错误
|
|
15
15
|
*/
|
|
@@ -24,8 +24,8 @@ declare class SDKConfig {
|
|
|
24
24
|
private _pluginId;
|
|
25
25
|
private _versionCompatible;
|
|
26
26
|
private _versionCheckPromise;
|
|
27
|
-
readonly sdkSignature = "AI_WORLD_SDK_V:1.1.
|
|
28
|
-
readonly sdkVersion = "1.1.
|
|
27
|
+
readonly sdkSignature = "AI_WORLD_SDK_V:1.1.3";
|
|
28
|
+
readonly sdkVersion = "1.1.3";
|
|
29
29
|
constructor();
|
|
30
30
|
/**
|
|
31
31
|
* Set global base URL
|
package/dist/config.js
CHANGED
|
@@ -7,7 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.sdkConfig = exports.VersionCompatibilityError = exports.SDK_SIGNATURE = void 0;
|
|
8
8
|
// SDK 版本号(构建时自动从 package.json 更新)
|
|
9
9
|
// 此版本号会在运行 npm run build 时自动从 package.json 读取并更新
|
|
10
|
-
const SDK_VERSION = "1.1.
|
|
10
|
+
const SDK_VERSION = "1.1.3";
|
|
11
11
|
/**
|
|
12
12
|
* SDK 特征码 - 用于在构建后的 JS 文件中识别 SDK 版本
|
|
13
13
|
* 格式: AI_WORLD_SDK_V:版本号
|
|
@@ -15,7 +15,7 @@ const SDK_VERSION = "1.1.1";
|
|
|
15
15
|
*
|
|
16
16
|
* 注意: {VERSION} 占位符会在构建时被替换为实际版本号
|
|
17
17
|
*/
|
|
18
|
-
exports.SDK_SIGNATURE = "AI_WORLD_SDK_V:1.1.
|
|
18
|
+
exports.SDK_SIGNATURE = "AI_WORLD_SDK_V:1.1.3";
|
|
19
19
|
/**
|
|
20
20
|
* 版本兼容性错误
|
|
21
21
|
*/
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Gemini Image Generation Client
|
|
3
3
|
* Google Gemini 图像生成客户端
|
|
4
4
|
*/
|
|
5
|
-
|
|
5
|
+
import type { AIModelProvider } from "./provider_config";
|
|
6
|
+
export type GeminiImageGenerationProvider = Extract<AIModelProvider, "aihubmix" | "shubiaobiao" | "api2img" | "gemini">;
|
|
6
7
|
export interface GeminiImageGenerationConfig {
|
|
7
8
|
provider?: GeminiImageGenerationProvider;
|
|
8
9
|
baseUrl?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -8,10 +8,12 @@ import { BaseChatModel, BaseChatModelParams } from "./base";
|
|
|
8
8
|
import { DoubaoImageGenerationClient, DoubaoImageSize, type DoubaoImageGenerationConfig, type DoubaoImageGenerationRequest, type DoubaoImageGenerationResponse } from "./doubao-image-generation";
|
|
9
9
|
import { GeminiImageGenerationClient, type GeminiImageGenerationConfig, type GeminiImageGenerationRequest, type GeminiImageGenerationResponse } from "./gemini-image-generation";
|
|
10
10
|
import { VideoGenerationClient, type VideoGenerationConfig, type VideoGenerationRequest, type ContentGenerationTaskID, type ContentGenerationTask } from "./video_generation";
|
|
11
|
+
import { OpenAIVideoGenerationClient, type OpenAIVideoGenerationConfig, type OpenAIVideoGenerationRequest, type OpenAIVideoTaskResponse } from "./openai_video_generation";
|
|
11
12
|
import { DownloadClient, type DownloadConfig, type DownloadOptions, type StreamDownloadOptions } from "./download";
|
|
12
13
|
import { AuthClient, getCurrentUserInfo, type AuthConfig, type UserInfo } from "./auth";
|
|
13
14
|
export { BaseMessage, HumanMessage, AIMessage, SystemMessage, AIMessageChunk, type MessageContent, type AIMessageChunkData, } from "./messages";
|
|
14
|
-
export { BaseChatModel, type BaseChatModelParams, type
|
|
15
|
+
export { BaseChatModel, type BaseChatModelParams, type ToolDefinition, type BindOptions, } from "./base";
|
|
16
|
+
export type { AIModelProvider } from "./provider_config";
|
|
15
17
|
export { ChatOpenAI } from "./chat_models/openai";
|
|
16
18
|
export { ChatGoogleGenerativeAI } from "./chat_models/google";
|
|
17
19
|
export { ChatAnthropic } from "./chat_models/anthropic";
|
|
@@ -23,6 +25,7 @@ export interface LangchainClientConfig {
|
|
|
23
25
|
export { DoubaoImageGenerationClient, type DoubaoImageGenerationConfig, type DoubaoImageGenerationRequest, type DoubaoImageGenerationResponse, type DoubaoImageSize, };
|
|
24
26
|
export { GeminiImageGenerationClient, type GeminiImageGenerationConfig, type GeminiImageGenerationRequest, type GeminiImageGenerationResponse, };
|
|
25
27
|
export { VideoGenerationClient, type VideoGenerationConfig, type VideoGenerationRequest, type ContentGenerationTaskID, type ContentGenerationTask, };
|
|
28
|
+
export { OpenAIVideoGenerationClient, type OpenAIVideoGenerationConfig, type OpenAIVideoGenerationRequest, type OpenAIVideoTaskResponse, };
|
|
26
29
|
export { DownloadClient, type DownloadConfig, type DownloadOptions, type StreamDownloadOptions, };
|
|
27
30
|
export { AuthClient, getCurrentUserInfo, type AuthConfig, type UserInfo, };
|
|
28
31
|
export { sdkConfig, VersionCompatibilityError, SDK_SIGNATURE } from "./config";
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @see https://github.com/langchain-ai/langchainjs
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.SDK_SIGNATURE = exports.VersionCompatibilityError = exports.sdkConfig = exports.getCurrentUserInfo = exports.AuthClient = exports.DownloadClient = exports.VideoGenerationClient = exports.GeminiImageGenerationClient = exports.DoubaoImageGenerationClient = exports.ChatAnthropic = exports.ChatGoogleGenerativeAI = exports.ChatOpenAI = exports.BaseChatModel = exports.AIMessageChunk = exports.SystemMessage = exports.AIMessage = exports.HumanMessage = void 0;
|
|
9
|
+
exports.SDK_SIGNATURE = exports.VersionCompatibilityError = exports.sdkConfig = exports.getCurrentUserInfo = exports.AuthClient = exports.DownloadClient = exports.OpenAIVideoGenerationClient = exports.VideoGenerationClient = exports.GeminiImageGenerationClient = exports.DoubaoImageGenerationClient = exports.ChatAnthropic = exports.ChatGoogleGenerativeAI = exports.ChatOpenAI = exports.BaseChatModel = exports.AIMessageChunk = exports.SystemMessage = exports.AIMessage = exports.HumanMessage = void 0;
|
|
10
10
|
exports.createChatModel = createChatModel;
|
|
11
11
|
const openai_1 = require("./chat_models/openai");
|
|
12
12
|
const google_1 = require("./chat_models/google");
|
|
@@ -16,12 +16,15 @@ const gemini_image_generation_1 = require("./gemini-image-generation");
|
|
|
16
16
|
Object.defineProperty(exports, "GeminiImageGenerationClient", { enumerable: true, get: function () { return gemini_image_generation_1.GeminiImageGenerationClient; } });
|
|
17
17
|
const video_generation_1 = require("./video_generation");
|
|
18
18
|
Object.defineProperty(exports, "VideoGenerationClient", { enumerable: true, get: function () { return video_generation_1.VideoGenerationClient; } });
|
|
19
|
+
const openai_video_generation_1 = require("./openai_video_generation");
|
|
20
|
+
Object.defineProperty(exports, "OpenAIVideoGenerationClient", { enumerable: true, get: function () { return openai_video_generation_1.OpenAIVideoGenerationClient; } });
|
|
19
21
|
const download_1 = require("./download");
|
|
20
22
|
Object.defineProperty(exports, "DownloadClient", { enumerable: true, get: function () { return download_1.DownloadClient; } });
|
|
21
23
|
const auth_1 = require("./auth");
|
|
22
24
|
Object.defineProperty(exports, "AuthClient", { enumerable: true, get: function () { return auth_1.AuthClient; } });
|
|
23
25
|
Object.defineProperty(exports, "getCurrentUserInfo", { enumerable: true, get: function () { return auth_1.getCurrentUserInfo; } });
|
|
24
26
|
const config_1 = require("./config");
|
|
27
|
+
const provider_config_1 = require("./provider_config");
|
|
25
28
|
// Re-export types and classes
|
|
26
29
|
var messages_1 = require("./messages");
|
|
27
30
|
Object.defineProperty(exports, "HumanMessage", { enumerable: true, get: function () { return messages_1.HumanMessage; } });
|
|
@@ -56,20 +59,18 @@ function createChatModel(model, config) {
|
|
|
56
59
|
...config.headers,
|
|
57
60
|
},
|
|
58
61
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
case "api2img":
|
|
63
|
-
return new openai_1.ChatOpenAI({
|
|
64
|
-
modelName: model,
|
|
65
|
-
...finalConfig,
|
|
66
|
-
});
|
|
67
|
-
case "gemini":
|
|
68
|
-
return new google_1.ChatGoogleGenerativeAI({
|
|
69
|
-
modelName: model,
|
|
70
|
-
...finalConfig,
|
|
71
|
-
});
|
|
72
|
-
default:
|
|
73
|
-
throw new Error(`Unsupported provider: ${config.provider}`);
|
|
62
|
+
const providerConfig = (0, provider_config_1.getProviderConfig)(config.provider);
|
|
63
|
+
if (!providerConfig) {
|
|
64
|
+
throw new Error(`Unsupported provider: ${config.provider}`);
|
|
74
65
|
}
|
|
66
|
+
if (providerConfig.modelType === "gemini") {
|
|
67
|
+
return new google_1.ChatGoogleGenerativeAI({
|
|
68
|
+
modelName: model,
|
|
69
|
+
...finalConfig,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return new openai_1.ChatOpenAI({
|
|
73
|
+
modelName: model,
|
|
74
|
+
...finalConfig,
|
|
75
|
+
});
|
|
75
76
|
}
|