@wzyjs/utils 0.3.25 → 0.3.26
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/common/ai/index.d.ts +1 -0
- package/dist/common/ai/xyq/index.d.ts +79 -0
- package/dist/node.cjs.js +198 -7
- package/dist/node.esm.js +196 -5
- package/dist/web.cjs.js +190 -0
- package/dist/web.esm.js +190 -0
- package/package.json +2 -2
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export interface XyqConfig {
|
|
2
|
+
apiKey?: string;
|
|
3
|
+
apiAddress?: string;
|
|
4
|
+
}
|
|
5
|
+
interface XyqEntry {
|
|
6
|
+
type: number;
|
|
7
|
+
message?: {
|
|
8
|
+
message_id: string;
|
|
9
|
+
role: string;
|
|
10
|
+
content: any[];
|
|
11
|
+
};
|
|
12
|
+
artifact?: {
|
|
13
|
+
artifact_id: string;
|
|
14
|
+
content: any[];
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
interface XyqSubmitResult {
|
|
18
|
+
thread_id: string;
|
|
19
|
+
run_id: string;
|
|
20
|
+
web_thread_link: string;
|
|
21
|
+
}
|
|
22
|
+
interface XyqThreadStatus {
|
|
23
|
+
state: number;
|
|
24
|
+
entry_list?: XyqEntry[];
|
|
25
|
+
fail_reason?: string;
|
|
26
|
+
}
|
|
27
|
+
declare const RUN_STATE: {
|
|
28
|
+
readonly Running: 1;
|
|
29
|
+
readonly Waiting: 2;
|
|
30
|
+
readonly Success: 3;
|
|
31
|
+
readonly Failed: 4;
|
|
32
|
+
readonly Canceled: 5;
|
|
33
|
+
};
|
|
34
|
+
export { RUN_STATE };
|
|
35
|
+
export declare const submitRun: (params: {
|
|
36
|
+
message: string;
|
|
37
|
+
threadId?: string;
|
|
38
|
+
assetIds?: string[];
|
|
39
|
+
config?: XyqConfig;
|
|
40
|
+
}) => Promise<XyqSubmitResult>;
|
|
41
|
+
export declare const getThreadStatus: (params: {
|
|
42
|
+
threadId: string;
|
|
43
|
+
runId?: string;
|
|
44
|
+
afterSeq?: number;
|
|
45
|
+
config?: XyqConfig;
|
|
46
|
+
}) => Promise<XyqThreadStatus>;
|
|
47
|
+
export declare const extractMediaFromEntry: (entry: XyqEntry) => {
|
|
48
|
+
url: string;
|
|
49
|
+
width: number;
|
|
50
|
+
height: number;
|
|
51
|
+
type: "image" | "video";
|
|
52
|
+
format?: string;
|
|
53
|
+
} | null;
|
|
54
|
+
export declare const pollUntilComplete: (params: {
|
|
55
|
+
threadId: string;
|
|
56
|
+
runId: string;
|
|
57
|
+
config?: XyqConfig;
|
|
58
|
+
}, options?: {
|
|
59
|
+
onProgress?: (status: string) => void;
|
|
60
|
+
intervalMs?: number;
|
|
61
|
+
maxWaitMs?: number;
|
|
62
|
+
}) => Promise<{
|
|
63
|
+
entry_list: XyqEntry[];
|
|
64
|
+
}>;
|
|
65
|
+
export declare const generateImage: (prompt: string, options?: {
|
|
66
|
+
threadId?: string;
|
|
67
|
+
assetIds?: string[];
|
|
68
|
+
onProgress?: (status: string) => void;
|
|
69
|
+
config?: XyqConfig;
|
|
70
|
+
}) => Promise<{
|
|
71
|
+
threadId: string;
|
|
72
|
+
runId: string;
|
|
73
|
+
webThreadLink: string;
|
|
74
|
+
imageUrl: string;
|
|
75
|
+
width: number;
|
|
76
|
+
height: number;
|
|
77
|
+
type: "image" | "video";
|
|
78
|
+
format?: string;
|
|
79
|
+
}>;
|
package/dist/node.cjs.js
CHANGED
|
@@ -31587,7 +31587,7 @@ __export(exports_node, {
|
|
|
31587
31587
|
calcJsText: () => calcJsText,
|
|
31588
31588
|
boolean: () => booleanType,
|
|
31589
31589
|
bigint: () => bigIntType,
|
|
31590
|
-
axios: () =>
|
|
31590
|
+
axios: () => import_axios11.default,
|
|
31591
31591
|
array: () => arrayType,
|
|
31592
31592
|
any: () => anyType,
|
|
31593
31593
|
amount: () => amount,
|
|
@@ -35625,7 +35625,7 @@ var coerce = {
|
|
|
35625
35625
|
var NEVER = INVALID;
|
|
35626
35626
|
// src/node.ts
|
|
35627
35627
|
var cheerio = __toESM(require("cheerio"));
|
|
35628
|
-
var
|
|
35628
|
+
var import_axios11 = __toESM(require("axios"));
|
|
35629
35629
|
var import_json53 = __toESM(require("json5"));
|
|
35630
35630
|
var import_consola = __toESM(require("consola"));
|
|
35631
35631
|
var import_lodash = __toESM(require_lodash(), 1);
|
|
@@ -35633,6 +35633,7 @@ var import_lodash = __toESM(require_lodash(), 1);
|
|
|
35633
35633
|
// src/common/ai/index.ts
|
|
35634
35634
|
var exports_ai = {};
|
|
35635
35635
|
__export(exports_ai, {
|
|
35636
|
+
xyq: () => exports_xyq,
|
|
35636
35637
|
text: () => exports_text,
|
|
35637
35638
|
keling: () => exports_keling,
|
|
35638
35639
|
doubao: () => exports_doubao,
|
|
@@ -36106,6 +36107,196 @@ var generateVideo = async (imageUrl, prompt) => {
|
|
|
36106
36107
|
console.log(666, "任务 id", taskId);
|
|
36107
36108
|
return taskId;
|
|
36108
36109
|
};
|
|
36110
|
+
// src/common/ai/xyq/index.ts
|
|
36111
|
+
var exports_xyq = {};
|
|
36112
|
+
__export(exports_xyq, {
|
|
36113
|
+
submitRun: () => submitRun,
|
|
36114
|
+
pollUntilComplete: () => pollUntilComplete,
|
|
36115
|
+
getThreadStatus: () => getThreadStatus,
|
|
36116
|
+
generateImage: () => generateImage,
|
|
36117
|
+
extractMediaFromEntry: () => extractMediaFromEntry,
|
|
36118
|
+
RUN_STATE: () => RUN_STATE
|
|
36119
|
+
});
|
|
36120
|
+
var import_axios8 = __toESM(require("axios"));
|
|
36121
|
+
var API_PATHS = {
|
|
36122
|
+
submitRun: "/api/biz/v1/skill/submit_run",
|
|
36123
|
+
getThread: "/api/biz/v1/skill/get_thread",
|
|
36124
|
+
uploadFile: "/api/biz/v1/skill/upload_file"
|
|
36125
|
+
};
|
|
36126
|
+
var getHeaders2 = (config) => ({
|
|
36127
|
+
Authorization: `Bearer ${config?.apiKey}`,
|
|
36128
|
+
"Content-Type": "application/json"
|
|
36129
|
+
});
|
|
36130
|
+
var getBaseUrl = (config) => {
|
|
36131
|
+
return config?.apiAddress.replace(/\/$/, "");
|
|
36132
|
+
};
|
|
36133
|
+
var RUN_STATE = {
|
|
36134
|
+
Running: 1,
|
|
36135
|
+
Waiting: 2,
|
|
36136
|
+
Success: 3,
|
|
36137
|
+
Failed: 4,
|
|
36138
|
+
Canceled: 5
|
|
36139
|
+
};
|
|
36140
|
+
var submitRun = async (params) => {
|
|
36141
|
+
const { config } = params;
|
|
36142
|
+
const apiKey = config?.apiKey;
|
|
36143
|
+
if (!apiKey) {
|
|
36144
|
+
throw new Error("未配置小云雀 API Key");
|
|
36145
|
+
}
|
|
36146
|
+
const body = {};
|
|
36147
|
+
if (params.threadId) {
|
|
36148
|
+
body.thread_id = params.threadId;
|
|
36149
|
+
}
|
|
36150
|
+
if (params.message) {
|
|
36151
|
+
body.message = params.message;
|
|
36152
|
+
}
|
|
36153
|
+
if (params.assetIds?.length) {
|
|
36154
|
+
body.asset_ids = params.assetIds;
|
|
36155
|
+
}
|
|
36156
|
+
const { data } = await import_axios8.default.post(`${getBaseUrl(config)}${API_PATHS.submitRun}`, body, { headers: getHeaders2(config) });
|
|
36157
|
+
if (data.ret !== "0") {
|
|
36158
|
+
throw new Error(`小云雀 API 错误: ${data.errmsg}`);
|
|
36159
|
+
}
|
|
36160
|
+
const run = data.data.run;
|
|
36161
|
+
return {
|
|
36162
|
+
thread_id: run.thread_id,
|
|
36163
|
+
run_id: run.run_id,
|
|
36164
|
+
web_thread_link: data.data.web_thread_link || ""
|
|
36165
|
+
};
|
|
36166
|
+
};
|
|
36167
|
+
var getThreadStatus = async (params) => {
|
|
36168
|
+
const { config } = params;
|
|
36169
|
+
const apiKey = config?.apiKey;
|
|
36170
|
+
if (!apiKey) {
|
|
36171
|
+
throw new Error("未配置小云雀 API Key");
|
|
36172
|
+
}
|
|
36173
|
+
const body = {
|
|
36174
|
+
thread_id: params.threadId,
|
|
36175
|
+
after_seq: params.afterSeq || 0
|
|
36176
|
+
};
|
|
36177
|
+
if (params.runId) {
|
|
36178
|
+
body.run_id = params.runId;
|
|
36179
|
+
}
|
|
36180
|
+
const { data } = await import_axios8.default.post(`${getBaseUrl(config)}${API_PATHS.getThread}`, body, { headers: getHeaders2(config) });
|
|
36181
|
+
if (data.ret !== "0") {
|
|
36182
|
+
throw new Error(`小云雀 API 错误: ${data.errmsg}`);
|
|
36183
|
+
}
|
|
36184
|
+
const runList = data.data.thread.run_list;
|
|
36185
|
+
if (!runList?.length) {
|
|
36186
|
+
throw new Error("未返回 run_list");
|
|
36187
|
+
}
|
|
36188
|
+
return runList[0];
|
|
36189
|
+
};
|
|
36190
|
+
var extractMediaFromEntry = (entry) => {
|
|
36191
|
+
const contents = [...entry.message?.content || [], ...entry.artifact?.content || []];
|
|
36192
|
+
if (!contents.length)
|
|
36193
|
+
return null;
|
|
36194
|
+
for (const item of contents) {
|
|
36195
|
+
let dataObj = item.data;
|
|
36196
|
+
if (typeof dataObj === "string") {
|
|
36197
|
+
try {
|
|
36198
|
+
dataObj = JSON.parse(dataObj);
|
|
36199
|
+
} catch (e) {}
|
|
36200
|
+
}
|
|
36201
|
+
const image = dataObj?.image || (item.sub_type === "biz/x_data_image" ? dataObj : null);
|
|
36202
|
+
if (image?.url) {
|
|
36203
|
+
return {
|
|
36204
|
+
url: image.url,
|
|
36205
|
+
width: image.metadata?.width || 0,
|
|
36206
|
+
height: image.metadata?.height || 0,
|
|
36207
|
+
type: "image",
|
|
36208
|
+
format: image.metadata?.format || "png"
|
|
36209
|
+
};
|
|
36210
|
+
}
|
|
36211
|
+
const video = dataObj?.video || (item.sub_type === "biz/x_data_video" ? dataObj : null);
|
|
36212
|
+
if (video?.url) {
|
|
36213
|
+
return {
|
|
36214
|
+
url: video.url,
|
|
36215
|
+
width: video.metadata?.width || 0,
|
|
36216
|
+
height: video.metadata?.height || 0,
|
|
36217
|
+
type: "video",
|
|
36218
|
+
format: video.metadata?.format || "mp4"
|
|
36219
|
+
};
|
|
36220
|
+
}
|
|
36221
|
+
const deepFindUrl = (obj) => {
|
|
36222
|
+
if (!obj || typeof obj !== "object")
|
|
36223
|
+
return null;
|
|
36224
|
+
if (obj.url && typeof obj.url === "string" && (obj.url.startsWith("http") || obj.url.startsWith("https"))) {
|
|
36225
|
+
return obj.url;
|
|
36226
|
+
}
|
|
36227
|
+
for (const key2 in obj) {
|
|
36228
|
+
const result = deepFindUrl(obj[key2]);
|
|
36229
|
+
if (result)
|
|
36230
|
+
return result;
|
|
36231
|
+
}
|
|
36232
|
+
return null;
|
|
36233
|
+
};
|
|
36234
|
+
const foundUrl = deepFindUrl(dataObj) || deepFindUrl(item);
|
|
36235
|
+
if (foundUrl) {
|
|
36236
|
+
const isVideo = foundUrl.toLowerCase().includes(".mp4") || foundUrl.toLowerCase().includes(".mov");
|
|
36237
|
+
return {
|
|
36238
|
+
url: foundUrl,
|
|
36239
|
+
width: dataObj?.metadata?.width || item.metadata?.width || 0,
|
|
36240
|
+
height: dataObj?.metadata?.height || item.metadata?.height || 0,
|
|
36241
|
+
type: isVideo ? "video" : "image",
|
|
36242
|
+
format: isVideo ? "mp4" : "png"
|
|
36243
|
+
};
|
|
36244
|
+
}
|
|
36245
|
+
}
|
|
36246
|
+
return null;
|
|
36247
|
+
};
|
|
36248
|
+
var pollUntilComplete = async (params, options = {}) => {
|
|
36249
|
+
const { onProgress, intervalMs = 5000, maxWaitMs = 48 * 60 * 60 * 1000 } = options;
|
|
36250
|
+
const startTime = Date.now();
|
|
36251
|
+
while (Date.now() - startTime < maxWaitMs) {
|
|
36252
|
+
const status = await getThreadStatus({
|
|
36253
|
+
threadId: params.threadId,
|
|
36254
|
+
runId: params.runId,
|
|
36255
|
+
config: params.config
|
|
36256
|
+
});
|
|
36257
|
+
if (status.state === RUN_STATE.Success) {
|
|
36258
|
+
return { entry_list: status.entry_list || [] };
|
|
36259
|
+
}
|
|
36260
|
+
if (status.state === RUN_STATE.Failed) {
|
|
36261
|
+
throw new Error(`小云雀任务失败: ${status.fail_reason || "未知原因"}`);
|
|
36262
|
+
}
|
|
36263
|
+
if (status.state === RUN_STATE.Canceled) {
|
|
36264
|
+
throw new Error("小云雀任务已被取消");
|
|
36265
|
+
}
|
|
36266
|
+
onProgress?.(`创作进行中 (state: ${status.state})...`);
|
|
36267
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
36268
|
+
}
|
|
36269
|
+
throw new Error("小云雀任务超时");
|
|
36270
|
+
};
|
|
36271
|
+
var generateImage = async (prompt, options) => {
|
|
36272
|
+
const { threadId: existingThreadId, assetIds, onProgress, config } = options || {};
|
|
36273
|
+
onProgress?.("正在提交创作任务...");
|
|
36274
|
+
const submitResult = await submitRun({
|
|
36275
|
+
message: prompt,
|
|
36276
|
+
threadId: existingThreadId,
|
|
36277
|
+
assetIds,
|
|
36278
|
+
config
|
|
36279
|
+
});
|
|
36280
|
+
onProgress?.("任务已提交,等待创作完成...");
|
|
36281
|
+
const { entry_list } = await pollUntilComplete({ threadId: submitResult.thread_id, runId: submitResult.run_id, config }, { onProgress });
|
|
36282
|
+
console.log("[XYQ DEBUG] All result entries:", JSON.stringify(entry_list, null, 2));
|
|
36283
|
+
for (const entry of entry_list) {
|
|
36284
|
+
const media = extractMediaFromEntry(entry);
|
|
36285
|
+
if (media) {
|
|
36286
|
+
return {
|
|
36287
|
+
threadId: submitResult.thread_id,
|
|
36288
|
+
runId: submitResult.run_id,
|
|
36289
|
+
webThreadLink: submitResult.web_thread_link,
|
|
36290
|
+
imageUrl: media.url,
|
|
36291
|
+
width: media.width,
|
|
36292
|
+
height: media.height,
|
|
36293
|
+
type: media.type,
|
|
36294
|
+
format: media.format
|
|
36295
|
+
};
|
|
36296
|
+
}
|
|
36297
|
+
}
|
|
36298
|
+
throw new Error("未在结果中找到生成的图片");
|
|
36299
|
+
};
|
|
36109
36300
|
// src/common/ai/text/index.ts
|
|
36110
36301
|
var exports_text = {};
|
|
36111
36302
|
__export(exports_text, {
|
|
@@ -38875,10 +39066,10 @@ var Enum = {
|
|
|
38875
39066
|
}
|
|
38876
39067
|
};
|
|
38877
39068
|
// src/common/image/index.ts
|
|
38878
|
-
var
|
|
39069
|
+
var import_axios9 = __toESM(require("axios"));
|
|
38879
39070
|
async function imageToBase64(url2) {
|
|
38880
39071
|
try {
|
|
38881
|
-
const response = await
|
|
39072
|
+
const response = await import_axios9.default.get(url2, {
|
|
38882
39073
|
responseType: "arraybuffer"
|
|
38883
39074
|
});
|
|
38884
39075
|
const base64String = Buffer.from(response.data).toString("base64");
|
|
@@ -39121,7 +39312,7 @@ __export(exports_file, {
|
|
|
39121
39312
|
downloadFile: () => downloadFile
|
|
39122
39313
|
});
|
|
39123
39314
|
var import_fs_extra = __toESM(require("fs-extra"));
|
|
39124
|
-
var
|
|
39315
|
+
var import_axios10 = __toESM(require("axios"));
|
|
39125
39316
|
var import_url = __toESM(require("url"));
|
|
39126
39317
|
var path2 = __toESM(require("path"));
|
|
39127
39318
|
var import_crypto = __toESM(require("crypto"));
|
|
@@ -39202,7 +39393,7 @@ var downloadFile = async (httpUrl, outputPath) => {
|
|
|
39202
39393
|
}
|
|
39203
39394
|
outputPath = ".tmp/" + decodeURIComponent(fileName);
|
|
39204
39395
|
}
|
|
39205
|
-
const response = await
|
|
39396
|
+
const response = await import_axios10.default({
|
|
39206
39397
|
url: httpUrl,
|
|
39207
39398
|
method: "get",
|
|
39208
39399
|
responseType: "stream"
|
|
@@ -39239,7 +39430,7 @@ var processFile = async (params) => {
|
|
|
39239
39430
|
throw new Error("当类型为 url 时,file 必须是字符串");
|
|
39240
39431
|
}
|
|
39241
39432
|
try {
|
|
39242
|
-
const response = await
|
|
39433
|
+
const response = await import_axios10.default.get(file, { responseType: "arraybuffer" });
|
|
39243
39434
|
buffer = Buffer.from(response.data);
|
|
39244
39435
|
} catch (error) {
|
|
39245
39436
|
throw new Error(`无法从 URL 下载文件: ${error}`);
|
package/dist/node.esm.js
CHANGED
|
@@ -34729,6 +34729,7 @@ import { default as default4 } from "consola";
|
|
|
34729
34729
|
// src/common/ai/index.ts
|
|
34730
34730
|
var exports_ai = {};
|
|
34731
34731
|
__export(exports_ai, {
|
|
34732
|
+
xyq: () => exports_xyq,
|
|
34732
34733
|
text: () => exports_text,
|
|
34733
34734
|
keling: () => exports_keling,
|
|
34734
34735
|
doubao: () => exports_doubao,
|
|
@@ -35202,6 +35203,196 @@ var generateVideo = async (imageUrl, prompt) => {
|
|
|
35202
35203
|
console.log(666, "任务 id", taskId);
|
|
35203
35204
|
return taskId;
|
|
35204
35205
|
};
|
|
35206
|
+
// src/common/ai/xyq/index.ts
|
|
35207
|
+
var exports_xyq = {};
|
|
35208
|
+
__export(exports_xyq, {
|
|
35209
|
+
submitRun: () => submitRun,
|
|
35210
|
+
pollUntilComplete: () => pollUntilComplete,
|
|
35211
|
+
getThreadStatus: () => getThreadStatus,
|
|
35212
|
+
generateImage: () => generateImage,
|
|
35213
|
+
extractMediaFromEntry: () => extractMediaFromEntry,
|
|
35214
|
+
RUN_STATE: () => RUN_STATE
|
|
35215
|
+
});
|
|
35216
|
+
import axios5 from "axios";
|
|
35217
|
+
var API_PATHS = {
|
|
35218
|
+
submitRun: "/api/biz/v1/skill/submit_run",
|
|
35219
|
+
getThread: "/api/biz/v1/skill/get_thread",
|
|
35220
|
+
uploadFile: "/api/biz/v1/skill/upload_file"
|
|
35221
|
+
};
|
|
35222
|
+
var getHeaders2 = (config) => ({
|
|
35223
|
+
Authorization: `Bearer ${config?.apiKey}`,
|
|
35224
|
+
"Content-Type": "application/json"
|
|
35225
|
+
});
|
|
35226
|
+
var getBaseUrl = (config) => {
|
|
35227
|
+
return config?.apiAddress.replace(/\/$/, "");
|
|
35228
|
+
};
|
|
35229
|
+
var RUN_STATE = {
|
|
35230
|
+
Running: 1,
|
|
35231
|
+
Waiting: 2,
|
|
35232
|
+
Success: 3,
|
|
35233
|
+
Failed: 4,
|
|
35234
|
+
Canceled: 5
|
|
35235
|
+
};
|
|
35236
|
+
var submitRun = async (params) => {
|
|
35237
|
+
const { config } = params;
|
|
35238
|
+
const apiKey = config?.apiKey;
|
|
35239
|
+
if (!apiKey) {
|
|
35240
|
+
throw new Error("未配置小云雀 API Key");
|
|
35241
|
+
}
|
|
35242
|
+
const body = {};
|
|
35243
|
+
if (params.threadId) {
|
|
35244
|
+
body.thread_id = params.threadId;
|
|
35245
|
+
}
|
|
35246
|
+
if (params.message) {
|
|
35247
|
+
body.message = params.message;
|
|
35248
|
+
}
|
|
35249
|
+
if (params.assetIds?.length) {
|
|
35250
|
+
body.asset_ids = params.assetIds;
|
|
35251
|
+
}
|
|
35252
|
+
const { data } = await axios5.post(`${getBaseUrl(config)}${API_PATHS.submitRun}`, body, { headers: getHeaders2(config) });
|
|
35253
|
+
if (data.ret !== "0") {
|
|
35254
|
+
throw new Error(`小云雀 API 错误: ${data.errmsg}`);
|
|
35255
|
+
}
|
|
35256
|
+
const run = data.data.run;
|
|
35257
|
+
return {
|
|
35258
|
+
thread_id: run.thread_id,
|
|
35259
|
+
run_id: run.run_id,
|
|
35260
|
+
web_thread_link: data.data.web_thread_link || ""
|
|
35261
|
+
};
|
|
35262
|
+
};
|
|
35263
|
+
var getThreadStatus = async (params) => {
|
|
35264
|
+
const { config } = params;
|
|
35265
|
+
const apiKey = config?.apiKey;
|
|
35266
|
+
if (!apiKey) {
|
|
35267
|
+
throw new Error("未配置小云雀 API Key");
|
|
35268
|
+
}
|
|
35269
|
+
const body = {
|
|
35270
|
+
thread_id: params.threadId,
|
|
35271
|
+
after_seq: params.afterSeq || 0
|
|
35272
|
+
};
|
|
35273
|
+
if (params.runId) {
|
|
35274
|
+
body.run_id = params.runId;
|
|
35275
|
+
}
|
|
35276
|
+
const { data } = await axios5.post(`${getBaseUrl(config)}${API_PATHS.getThread}`, body, { headers: getHeaders2(config) });
|
|
35277
|
+
if (data.ret !== "0") {
|
|
35278
|
+
throw new Error(`小云雀 API 错误: ${data.errmsg}`);
|
|
35279
|
+
}
|
|
35280
|
+
const runList = data.data.thread.run_list;
|
|
35281
|
+
if (!runList?.length) {
|
|
35282
|
+
throw new Error("未返回 run_list");
|
|
35283
|
+
}
|
|
35284
|
+
return runList[0];
|
|
35285
|
+
};
|
|
35286
|
+
var extractMediaFromEntry = (entry) => {
|
|
35287
|
+
const contents = [...entry.message?.content || [], ...entry.artifact?.content || []];
|
|
35288
|
+
if (!contents.length)
|
|
35289
|
+
return null;
|
|
35290
|
+
for (const item of contents) {
|
|
35291
|
+
let dataObj = item.data;
|
|
35292
|
+
if (typeof dataObj === "string") {
|
|
35293
|
+
try {
|
|
35294
|
+
dataObj = JSON.parse(dataObj);
|
|
35295
|
+
} catch (e) {}
|
|
35296
|
+
}
|
|
35297
|
+
const image = dataObj?.image || (item.sub_type === "biz/x_data_image" ? dataObj : null);
|
|
35298
|
+
if (image?.url) {
|
|
35299
|
+
return {
|
|
35300
|
+
url: image.url,
|
|
35301
|
+
width: image.metadata?.width || 0,
|
|
35302
|
+
height: image.metadata?.height || 0,
|
|
35303
|
+
type: "image",
|
|
35304
|
+
format: image.metadata?.format || "png"
|
|
35305
|
+
};
|
|
35306
|
+
}
|
|
35307
|
+
const video = dataObj?.video || (item.sub_type === "biz/x_data_video" ? dataObj : null);
|
|
35308
|
+
if (video?.url) {
|
|
35309
|
+
return {
|
|
35310
|
+
url: video.url,
|
|
35311
|
+
width: video.metadata?.width || 0,
|
|
35312
|
+
height: video.metadata?.height || 0,
|
|
35313
|
+
type: "video",
|
|
35314
|
+
format: video.metadata?.format || "mp4"
|
|
35315
|
+
};
|
|
35316
|
+
}
|
|
35317
|
+
const deepFindUrl = (obj) => {
|
|
35318
|
+
if (!obj || typeof obj !== "object")
|
|
35319
|
+
return null;
|
|
35320
|
+
if (obj.url && typeof obj.url === "string" && (obj.url.startsWith("http") || obj.url.startsWith("https"))) {
|
|
35321
|
+
return obj.url;
|
|
35322
|
+
}
|
|
35323
|
+
for (const key2 in obj) {
|
|
35324
|
+
const result = deepFindUrl(obj[key2]);
|
|
35325
|
+
if (result)
|
|
35326
|
+
return result;
|
|
35327
|
+
}
|
|
35328
|
+
return null;
|
|
35329
|
+
};
|
|
35330
|
+
const foundUrl = deepFindUrl(dataObj) || deepFindUrl(item);
|
|
35331
|
+
if (foundUrl) {
|
|
35332
|
+
const isVideo = foundUrl.toLowerCase().includes(".mp4") || foundUrl.toLowerCase().includes(".mov");
|
|
35333
|
+
return {
|
|
35334
|
+
url: foundUrl,
|
|
35335
|
+
width: dataObj?.metadata?.width || item.metadata?.width || 0,
|
|
35336
|
+
height: dataObj?.metadata?.height || item.metadata?.height || 0,
|
|
35337
|
+
type: isVideo ? "video" : "image",
|
|
35338
|
+
format: isVideo ? "mp4" : "png"
|
|
35339
|
+
};
|
|
35340
|
+
}
|
|
35341
|
+
}
|
|
35342
|
+
return null;
|
|
35343
|
+
};
|
|
35344
|
+
var pollUntilComplete = async (params, options = {}) => {
|
|
35345
|
+
const { onProgress, intervalMs = 5000, maxWaitMs = 48 * 60 * 60 * 1000 } = options;
|
|
35346
|
+
const startTime = Date.now();
|
|
35347
|
+
while (Date.now() - startTime < maxWaitMs) {
|
|
35348
|
+
const status = await getThreadStatus({
|
|
35349
|
+
threadId: params.threadId,
|
|
35350
|
+
runId: params.runId,
|
|
35351
|
+
config: params.config
|
|
35352
|
+
});
|
|
35353
|
+
if (status.state === RUN_STATE.Success) {
|
|
35354
|
+
return { entry_list: status.entry_list || [] };
|
|
35355
|
+
}
|
|
35356
|
+
if (status.state === RUN_STATE.Failed) {
|
|
35357
|
+
throw new Error(`小云雀任务失败: ${status.fail_reason || "未知原因"}`);
|
|
35358
|
+
}
|
|
35359
|
+
if (status.state === RUN_STATE.Canceled) {
|
|
35360
|
+
throw new Error("小云雀任务已被取消");
|
|
35361
|
+
}
|
|
35362
|
+
onProgress?.(`创作进行中 (state: ${status.state})...`);
|
|
35363
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
35364
|
+
}
|
|
35365
|
+
throw new Error("小云雀任务超时");
|
|
35366
|
+
};
|
|
35367
|
+
var generateImage = async (prompt, options) => {
|
|
35368
|
+
const { threadId: existingThreadId, assetIds, onProgress, config } = options || {};
|
|
35369
|
+
onProgress?.("正在提交创作任务...");
|
|
35370
|
+
const submitResult = await submitRun({
|
|
35371
|
+
message: prompt,
|
|
35372
|
+
threadId: existingThreadId,
|
|
35373
|
+
assetIds,
|
|
35374
|
+
config
|
|
35375
|
+
});
|
|
35376
|
+
onProgress?.("任务已提交,等待创作完成...");
|
|
35377
|
+
const { entry_list } = await pollUntilComplete({ threadId: submitResult.thread_id, runId: submitResult.run_id, config }, { onProgress });
|
|
35378
|
+
console.log("[XYQ DEBUG] All result entries:", JSON.stringify(entry_list, null, 2));
|
|
35379
|
+
for (const entry of entry_list) {
|
|
35380
|
+
const media = extractMediaFromEntry(entry);
|
|
35381
|
+
if (media) {
|
|
35382
|
+
return {
|
|
35383
|
+
threadId: submitResult.thread_id,
|
|
35384
|
+
runId: submitResult.run_id,
|
|
35385
|
+
webThreadLink: submitResult.web_thread_link,
|
|
35386
|
+
imageUrl: media.url,
|
|
35387
|
+
width: media.width,
|
|
35388
|
+
height: media.height,
|
|
35389
|
+
type: media.type,
|
|
35390
|
+
format: media.format
|
|
35391
|
+
};
|
|
35392
|
+
}
|
|
35393
|
+
}
|
|
35394
|
+
throw new Error("未在结果中找到生成的图片");
|
|
35395
|
+
};
|
|
35205
35396
|
// src/common/ai/text/index.ts
|
|
35206
35397
|
var exports_text = {};
|
|
35207
35398
|
__export(exports_text, {
|
|
@@ -37971,10 +38162,10 @@ var Enum = {
|
|
|
37971
38162
|
}
|
|
37972
38163
|
};
|
|
37973
38164
|
// src/common/image/index.ts
|
|
37974
|
-
import
|
|
38165
|
+
import axios6 from "axios";
|
|
37975
38166
|
async function imageToBase64(url2) {
|
|
37976
38167
|
try {
|
|
37977
|
-
const response = await
|
|
38168
|
+
const response = await axios6.get(url2, {
|
|
37978
38169
|
responseType: "arraybuffer"
|
|
37979
38170
|
});
|
|
37980
38171
|
const base64String = Buffer.from(response.data).toString("base64");
|
|
@@ -38890,7 +39081,7 @@ __export(exports_file, {
|
|
|
38890
39081
|
downloadFile: () => downloadFile
|
|
38891
39082
|
});
|
|
38892
39083
|
import fs from "fs-extra";
|
|
38893
|
-
import
|
|
39084
|
+
import axios7 from "axios";
|
|
38894
39085
|
import url2 from "url";
|
|
38895
39086
|
import * as path2 from "path";
|
|
38896
39087
|
import crypto2 from "crypto";
|
|
@@ -38971,7 +39162,7 @@ var downloadFile = async (httpUrl, outputPath) => {
|
|
|
38971
39162
|
}
|
|
38972
39163
|
outputPath = ".tmp/" + decodeURIComponent(fileName);
|
|
38973
39164
|
}
|
|
38974
|
-
const response = await
|
|
39165
|
+
const response = await axios7({
|
|
38975
39166
|
url: httpUrl,
|
|
38976
39167
|
method: "get",
|
|
38977
39168
|
responseType: "stream"
|
|
@@ -39008,7 +39199,7 @@ var processFile = async (params) => {
|
|
|
39008
39199
|
throw new Error("当类型为 url 时,file 必须是字符串");
|
|
39009
39200
|
}
|
|
39010
39201
|
try {
|
|
39011
|
-
const response = await
|
|
39202
|
+
const response = await axios7.get(file, { responseType: "arraybuffer" });
|
|
39012
39203
|
buffer = Buffer.from(response.data);
|
|
39013
39204
|
} catch (error) {
|
|
39014
39205
|
throw new Error(`无法从 URL 下载文件: ${error}`);
|
package/dist/web.cjs.js
CHANGED
|
@@ -18304,6 +18304,7 @@ var import_lodash2 = __toESM(require_lodash(), 1);
|
|
|
18304
18304
|
// src/common/ai/index.ts
|
|
18305
18305
|
var exports_ai = {};
|
|
18306
18306
|
__export(exports_ai, {
|
|
18307
|
+
xyq: () => exports_xyq,
|
|
18307
18308
|
text: () => exports_text,
|
|
18308
18309
|
keling: () => exports_keling,
|
|
18309
18310
|
doubao: () => exports_doubao,
|
|
@@ -19431,6 +19432,195 @@ var generateVideo = async (imageUrl, prompt) => {
|
|
|
19431
19432
|
console.log(666, "任务 id", taskId);
|
|
19432
19433
|
return taskId;
|
|
19433
19434
|
};
|
|
19435
|
+
// src/common/ai/xyq/index.ts
|
|
19436
|
+
var exports_xyq = {};
|
|
19437
|
+
__export(exports_xyq, {
|
|
19438
|
+
submitRun: () => submitRun,
|
|
19439
|
+
pollUntilComplete: () => pollUntilComplete,
|
|
19440
|
+
getThreadStatus: () => getThreadStatus,
|
|
19441
|
+
generateImage: () => generateImage,
|
|
19442
|
+
extractMediaFromEntry: () => extractMediaFromEntry,
|
|
19443
|
+
RUN_STATE: () => RUN_STATE
|
|
19444
|
+
});
|
|
19445
|
+
var API_PATHS = {
|
|
19446
|
+
submitRun: "/api/biz/v1/skill/submit_run",
|
|
19447
|
+
getThread: "/api/biz/v1/skill/get_thread",
|
|
19448
|
+
uploadFile: "/api/biz/v1/skill/upload_file"
|
|
19449
|
+
};
|
|
19450
|
+
var getHeaders2 = (config) => ({
|
|
19451
|
+
Authorization: `Bearer ${config?.apiKey}`,
|
|
19452
|
+
"Content-Type": "application/json"
|
|
19453
|
+
});
|
|
19454
|
+
var getBaseUrl = (config) => {
|
|
19455
|
+
return config?.apiAddress.replace(/\/$/, "");
|
|
19456
|
+
};
|
|
19457
|
+
var RUN_STATE = {
|
|
19458
|
+
Running: 1,
|
|
19459
|
+
Waiting: 2,
|
|
19460
|
+
Success: 3,
|
|
19461
|
+
Failed: 4,
|
|
19462
|
+
Canceled: 5
|
|
19463
|
+
};
|
|
19464
|
+
var submitRun = async (params) => {
|
|
19465
|
+
const { config } = params;
|
|
19466
|
+
const apiKey = config?.apiKey;
|
|
19467
|
+
if (!apiKey) {
|
|
19468
|
+
throw new Error("未配置小云雀 API Key");
|
|
19469
|
+
}
|
|
19470
|
+
const body = {};
|
|
19471
|
+
if (params.threadId) {
|
|
19472
|
+
body.thread_id = params.threadId;
|
|
19473
|
+
}
|
|
19474
|
+
if (params.message) {
|
|
19475
|
+
body.message = params.message;
|
|
19476
|
+
}
|
|
19477
|
+
if (params.assetIds?.length) {
|
|
19478
|
+
body.asset_ids = params.assetIds;
|
|
19479
|
+
}
|
|
19480
|
+
const { data } = await axios_default.post(`${getBaseUrl(config)}${API_PATHS.submitRun}`, body, { headers: getHeaders2(config) });
|
|
19481
|
+
if (data.ret !== "0") {
|
|
19482
|
+
throw new Error(`小云雀 API 错误: ${data.errmsg}`);
|
|
19483
|
+
}
|
|
19484
|
+
const run = data.data.run;
|
|
19485
|
+
return {
|
|
19486
|
+
thread_id: run.thread_id,
|
|
19487
|
+
run_id: run.run_id,
|
|
19488
|
+
web_thread_link: data.data.web_thread_link || ""
|
|
19489
|
+
};
|
|
19490
|
+
};
|
|
19491
|
+
var getThreadStatus = async (params) => {
|
|
19492
|
+
const { config } = params;
|
|
19493
|
+
const apiKey = config?.apiKey;
|
|
19494
|
+
if (!apiKey) {
|
|
19495
|
+
throw new Error("未配置小云雀 API Key");
|
|
19496
|
+
}
|
|
19497
|
+
const body = {
|
|
19498
|
+
thread_id: params.threadId,
|
|
19499
|
+
after_seq: params.afterSeq || 0
|
|
19500
|
+
};
|
|
19501
|
+
if (params.runId) {
|
|
19502
|
+
body.run_id = params.runId;
|
|
19503
|
+
}
|
|
19504
|
+
const { data } = await axios_default.post(`${getBaseUrl(config)}${API_PATHS.getThread}`, body, { headers: getHeaders2(config) });
|
|
19505
|
+
if (data.ret !== "0") {
|
|
19506
|
+
throw new Error(`小云雀 API 错误: ${data.errmsg}`);
|
|
19507
|
+
}
|
|
19508
|
+
const runList = data.data.thread.run_list;
|
|
19509
|
+
if (!runList?.length) {
|
|
19510
|
+
throw new Error("未返回 run_list");
|
|
19511
|
+
}
|
|
19512
|
+
return runList[0];
|
|
19513
|
+
};
|
|
19514
|
+
var extractMediaFromEntry = (entry) => {
|
|
19515
|
+
const contents = [...entry.message?.content || [], ...entry.artifact?.content || []];
|
|
19516
|
+
if (!contents.length)
|
|
19517
|
+
return null;
|
|
19518
|
+
for (const item of contents) {
|
|
19519
|
+
let dataObj = item.data;
|
|
19520
|
+
if (typeof dataObj === "string") {
|
|
19521
|
+
try {
|
|
19522
|
+
dataObj = JSON.parse(dataObj);
|
|
19523
|
+
} catch (e) {}
|
|
19524
|
+
}
|
|
19525
|
+
const image = dataObj?.image || (item.sub_type === "biz/x_data_image" ? dataObj : null);
|
|
19526
|
+
if (image?.url) {
|
|
19527
|
+
return {
|
|
19528
|
+
url: image.url,
|
|
19529
|
+
width: image.metadata?.width || 0,
|
|
19530
|
+
height: image.metadata?.height || 0,
|
|
19531
|
+
type: "image",
|
|
19532
|
+
format: image.metadata?.format || "png"
|
|
19533
|
+
};
|
|
19534
|
+
}
|
|
19535
|
+
const video = dataObj?.video || (item.sub_type === "biz/x_data_video" ? dataObj : null);
|
|
19536
|
+
if (video?.url) {
|
|
19537
|
+
return {
|
|
19538
|
+
url: video.url,
|
|
19539
|
+
width: video.metadata?.width || 0,
|
|
19540
|
+
height: video.metadata?.height || 0,
|
|
19541
|
+
type: "video",
|
|
19542
|
+
format: video.metadata?.format || "mp4"
|
|
19543
|
+
};
|
|
19544
|
+
}
|
|
19545
|
+
const deepFindUrl = (obj) => {
|
|
19546
|
+
if (!obj || typeof obj !== "object")
|
|
19547
|
+
return null;
|
|
19548
|
+
if (obj.url && typeof obj.url === "string" && (obj.url.startsWith("http") || obj.url.startsWith("https"))) {
|
|
19549
|
+
return obj.url;
|
|
19550
|
+
}
|
|
19551
|
+
for (const key2 in obj) {
|
|
19552
|
+
const result = deepFindUrl(obj[key2]);
|
|
19553
|
+
if (result)
|
|
19554
|
+
return result;
|
|
19555
|
+
}
|
|
19556
|
+
return null;
|
|
19557
|
+
};
|
|
19558
|
+
const foundUrl = deepFindUrl(dataObj) || deepFindUrl(item);
|
|
19559
|
+
if (foundUrl) {
|
|
19560
|
+
const isVideo = foundUrl.toLowerCase().includes(".mp4") || foundUrl.toLowerCase().includes(".mov");
|
|
19561
|
+
return {
|
|
19562
|
+
url: foundUrl,
|
|
19563
|
+
width: dataObj?.metadata?.width || item.metadata?.width || 0,
|
|
19564
|
+
height: dataObj?.metadata?.height || item.metadata?.height || 0,
|
|
19565
|
+
type: isVideo ? "video" : "image",
|
|
19566
|
+
format: isVideo ? "mp4" : "png"
|
|
19567
|
+
};
|
|
19568
|
+
}
|
|
19569
|
+
}
|
|
19570
|
+
return null;
|
|
19571
|
+
};
|
|
19572
|
+
var pollUntilComplete = async (params, options = {}) => {
|
|
19573
|
+
const { onProgress, intervalMs = 5000, maxWaitMs = 48 * 60 * 60 * 1000 } = options;
|
|
19574
|
+
const startTime = Date.now();
|
|
19575
|
+
while (Date.now() - startTime < maxWaitMs) {
|
|
19576
|
+
const status = await getThreadStatus({
|
|
19577
|
+
threadId: params.threadId,
|
|
19578
|
+
runId: params.runId,
|
|
19579
|
+
config: params.config
|
|
19580
|
+
});
|
|
19581
|
+
if (status.state === RUN_STATE.Success) {
|
|
19582
|
+
return { entry_list: status.entry_list || [] };
|
|
19583
|
+
}
|
|
19584
|
+
if (status.state === RUN_STATE.Failed) {
|
|
19585
|
+
throw new Error(`小云雀任务失败: ${status.fail_reason || "未知原因"}`);
|
|
19586
|
+
}
|
|
19587
|
+
if (status.state === RUN_STATE.Canceled) {
|
|
19588
|
+
throw new Error("小云雀任务已被取消");
|
|
19589
|
+
}
|
|
19590
|
+
onProgress?.(`创作进行中 (state: ${status.state})...`);
|
|
19591
|
+
await new Promise((resolve2) => setTimeout(resolve2, intervalMs));
|
|
19592
|
+
}
|
|
19593
|
+
throw new Error("小云雀任务超时");
|
|
19594
|
+
};
|
|
19595
|
+
var generateImage = async (prompt, options) => {
|
|
19596
|
+
const { threadId: existingThreadId, assetIds, onProgress, config } = options || {};
|
|
19597
|
+
onProgress?.("正在提交创作任务...");
|
|
19598
|
+
const submitResult = await submitRun({
|
|
19599
|
+
message: prompt,
|
|
19600
|
+
threadId: existingThreadId,
|
|
19601
|
+
assetIds,
|
|
19602
|
+
config
|
|
19603
|
+
});
|
|
19604
|
+
onProgress?.("任务已提交,等待创作完成...");
|
|
19605
|
+
const { entry_list } = await pollUntilComplete({ threadId: submitResult.thread_id, runId: submitResult.run_id, config }, { onProgress });
|
|
19606
|
+
console.log("[XYQ DEBUG] All result entries:", JSON.stringify(entry_list, null, 2));
|
|
19607
|
+
for (const entry of entry_list) {
|
|
19608
|
+
const media = extractMediaFromEntry(entry);
|
|
19609
|
+
if (media) {
|
|
19610
|
+
return {
|
|
19611
|
+
threadId: submitResult.thread_id,
|
|
19612
|
+
runId: submitResult.run_id,
|
|
19613
|
+
webThreadLink: submitResult.web_thread_link,
|
|
19614
|
+
imageUrl: media.url,
|
|
19615
|
+
width: media.width,
|
|
19616
|
+
height: media.height,
|
|
19617
|
+
type: media.type,
|
|
19618
|
+
format: media.format
|
|
19619
|
+
};
|
|
19620
|
+
}
|
|
19621
|
+
}
|
|
19622
|
+
throw new Error("未在结果中找到生成的图片");
|
|
19623
|
+
};
|
|
19434
19624
|
// src/common/ai/text/index.ts
|
|
19435
19625
|
var exports_text = {};
|
|
19436
19626
|
__export(exports_text, {
|
package/dist/web.esm.js
CHANGED
|
@@ -18113,6 +18113,7 @@ var import_lodash2 = __toESM(require_lodash(), 1);
|
|
|
18113
18113
|
// src/common/ai/index.ts
|
|
18114
18114
|
var exports_ai = {};
|
|
18115
18115
|
__export(exports_ai, {
|
|
18116
|
+
xyq: () => exports_xyq,
|
|
18116
18117
|
text: () => exports_text,
|
|
18117
18118
|
keling: () => exports_keling,
|
|
18118
18119
|
doubao: () => exports_doubao,
|
|
@@ -19240,6 +19241,195 @@ var generateVideo = async (imageUrl, prompt) => {
|
|
|
19240
19241
|
console.log(666, "任务 id", taskId);
|
|
19241
19242
|
return taskId;
|
|
19242
19243
|
};
|
|
19244
|
+
// src/common/ai/xyq/index.ts
|
|
19245
|
+
var exports_xyq = {};
|
|
19246
|
+
__export(exports_xyq, {
|
|
19247
|
+
submitRun: () => submitRun,
|
|
19248
|
+
pollUntilComplete: () => pollUntilComplete,
|
|
19249
|
+
getThreadStatus: () => getThreadStatus,
|
|
19250
|
+
generateImage: () => generateImage,
|
|
19251
|
+
extractMediaFromEntry: () => extractMediaFromEntry,
|
|
19252
|
+
RUN_STATE: () => RUN_STATE
|
|
19253
|
+
});
|
|
19254
|
+
var API_PATHS = {
|
|
19255
|
+
submitRun: "/api/biz/v1/skill/submit_run",
|
|
19256
|
+
getThread: "/api/biz/v1/skill/get_thread",
|
|
19257
|
+
uploadFile: "/api/biz/v1/skill/upload_file"
|
|
19258
|
+
};
|
|
19259
|
+
var getHeaders2 = (config) => ({
|
|
19260
|
+
Authorization: `Bearer ${config?.apiKey}`,
|
|
19261
|
+
"Content-Type": "application/json"
|
|
19262
|
+
});
|
|
19263
|
+
var getBaseUrl = (config) => {
|
|
19264
|
+
return config?.apiAddress.replace(/\/$/, "");
|
|
19265
|
+
};
|
|
19266
|
+
var RUN_STATE = {
|
|
19267
|
+
Running: 1,
|
|
19268
|
+
Waiting: 2,
|
|
19269
|
+
Success: 3,
|
|
19270
|
+
Failed: 4,
|
|
19271
|
+
Canceled: 5
|
|
19272
|
+
};
|
|
19273
|
+
var submitRun = async (params) => {
|
|
19274
|
+
const { config } = params;
|
|
19275
|
+
const apiKey = config?.apiKey;
|
|
19276
|
+
if (!apiKey) {
|
|
19277
|
+
throw new Error("未配置小云雀 API Key");
|
|
19278
|
+
}
|
|
19279
|
+
const body = {};
|
|
19280
|
+
if (params.threadId) {
|
|
19281
|
+
body.thread_id = params.threadId;
|
|
19282
|
+
}
|
|
19283
|
+
if (params.message) {
|
|
19284
|
+
body.message = params.message;
|
|
19285
|
+
}
|
|
19286
|
+
if (params.assetIds?.length) {
|
|
19287
|
+
body.asset_ids = params.assetIds;
|
|
19288
|
+
}
|
|
19289
|
+
const { data } = await axios_default.post(`${getBaseUrl(config)}${API_PATHS.submitRun}`, body, { headers: getHeaders2(config) });
|
|
19290
|
+
if (data.ret !== "0") {
|
|
19291
|
+
throw new Error(`小云雀 API 错误: ${data.errmsg}`);
|
|
19292
|
+
}
|
|
19293
|
+
const run = data.data.run;
|
|
19294
|
+
return {
|
|
19295
|
+
thread_id: run.thread_id,
|
|
19296
|
+
run_id: run.run_id,
|
|
19297
|
+
web_thread_link: data.data.web_thread_link || ""
|
|
19298
|
+
};
|
|
19299
|
+
};
|
|
19300
|
+
var getThreadStatus = async (params) => {
|
|
19301
|
+
const { config } = params;
|
|
19302
|
+
const apiKey = config?.apiKey;
|
|
19303
|
+
if (!apiKey) {
|
|
19304
|
+
throw new Error("未配置小云雀 API Key");
|
|
19305
|
+
}
|
|
19306
|
+
const body = {
|
|
19307
|
+
thread_id: params.threadId,
|
|
19308
|
+
after_seq: params.afterSeq || 0
|
|
19309
|
+
};
|
|
19310
|
+
if (params.runId) {
|
|
19311
|
+
body.run_id = params.runId;
|
|
19312
|
+
}
|
|
19313
|
+
const { data } = await axios_default.post(`${getBaseUrl(config)}${API_PATHS.getThread}`, body, { headers: getHeaders2(config) });
|
|
19314
|
+
if (data.ret !== "0") {
|
|
19315
|
+
throw new Error(`小云雀 API 错误: ${data.errmsg}`);
|
|
19316
|
+
}
|
|
19317
|
+
const runList = data.data.thread.run_list;
|
|
19318
|
+
if (!runList?.length) {
|
|
19319
|
+
throw new Error("未返回 run_list");
|
|
19320
|
+
}
|
|
19321
|
+
return runList[0];
|
|
19322
|
+
};
|
|
19323
|
+
var extractMediaFromEntry = (entry) => {
|
|
19324
|
+
const contents = [...entry.message?.content || [], ...entry.artifact?.content || []];
|
|
19325
|
+
if (!contents.length)
|
|
19326
|
+
return null;
|
|
19327
|
+
for (const item of contents) {
|
|
19328
|
+
let dataObj = item.data;
|
|
19329
|
+
if (typeof dataObj === "string") {
|
|
19330
|
+
try {
|
|
19331
|
+
dataObj = JSON.parse(dataObj);
|
|
19332
|
+
} catch (e) {}
|
|
19333
|
+
}
|
|
19334
|
+
const image = dataObj?.image || (item.sub_type === "biz/x_data_image" ? dataObj : null);
|
|
19335
|
+
if (image?.url) {
|
|
19336
|
+
return {
|
|
19337
|
+
url: image.url,
|
|
19338
|
+
width: image.metadata?.width || 0,
|
|
19339
|
+
height: image.metadata?.height || 0,
|
|
19340
|
+
type: "image",
|
|
19341
|
+
format: image.metadata?.format || "png"
|
|
19342
|
+
};
|
|
19343
|
+
}
|
|
19344
|
+
const video = dataObj?.video || (item.sub_type === "biz/x_data_video" ? dataObj : null);
|
|
19345
|
+
if (video?.url) {
|
|
19346
|
+
return {
|
|
19347
|
+
url: video.url,
|
|
19348
|
+
width: video.metadata?.width || 0,
|
|
19349
|
+
height: video.metadata?.height || 0,
|
|
19350
|
+
type: "video",
|
|
19351
|
+
format: video.metadata?.format || "mp4"
|
|
19352
|
+
};
|
|
19353
|
+
}
|
|
19354
|
+
const deepFindUrl = (obj) => {
|
|
19355
|
+
if (!obj || typeof obj !== "object")
|
|
19356
|
+
return null;
|
|
19357
|
+
if (obj.url && typeof obj.url === "string" && (obj.url.startsWith("http") || obj.url.startsWith("https"))) {
|
|
19358
|
+
return obj.url;
|
|
19359
|
+
}
|
|
19360
|
+
for (const key2 in obj) {
|
|
19361
|
+
const result = deepFindUrl(obj[key2]);
|
|
19362
|
+
if (result)
|
|
19363
|
+
return result;
|
|
19364
|
+
}
|
|
19365
|
+
return null;
|
|
19366
|
+
};
|
|
19367
|
+
const foundUrl = deepFindUrl(dataObj) || deepFindUrl(item);
|
|
19368
|
+
if (foundUrl) {
|
|
19369
|
+
const isVideo = foundUrl.toLowerCase().includes(".mp4") || foundUrl.toLowerCase().includes(".mov");
|
|
19370
|
+
return {
|
|
19371
|
+
url: foundUrl,
|
|
19372
|
+
width: dataObj?.metadata?.width || item.metadata?.width || 0,
|
|
19373
|
+
height: dataObj?.metadata?.height || item.metadata?.height || 0,
|
|
19374
|
+
type: isVideo ? "video" : "image",
|
|
19375
|
+
format: isVideo ? "mp4" : "png"
|
|
19376
|
+
};
|
|
19377
|
+
}
|
|
19378
|
+
}
|
|
19379
|
+
return null;
|
|
19380
|
+
};
|
|
19381
|
+
var pollUntilComplete = async (params, options = {}) => {
|
|
19382
|
+
const { onProgress, intervalMs = 5000, maxWaitMs = 48 * 60 * 60 * 1000 } = options;
|
|
19383
|
+
const startTime = Date.now();
|
|
19384
|
+
while (Date.now() - startTime < maxWaitMs) {
|
|
19385
|
+
const status = await getThreadStatus({
|
|
19386
|
+
threadId: params.threadId,
|
|
19387
|
+
runId: params.runId,
|
|
19388
|
+
config: params.config
|
|
19389
|
+
});
|
|
19390
|
+
if (status.state === RUN_STATE.Success) {
|
|
19391
|
+
return { entry_list: status.entry_list || [] };
|
|
19392
|
+
}
|
|
19393
|
+
if (status.state === RUN_STATE.Failed) {
|
|
19394
|
+
throw new Error(`小云雀任务失败: ${status.fail_reason || "未知原因"}`);
|
|
19395
|
+
}
|
|
19396
|
+
if (status.state === RUN_STATE.Canceled) {
|
|
19397
|
+
throw new Error("小云雀任务已被取消");
|
|
19398
|
+
}
|
|
19399
|
+
onProgress?.(`创作进行中 (state: ${status.state})...`);
|
|
19400
|
+
await new Promise((resolve2) => setTimeout(resolve2, intervalMs));
|
|
19401
|
+
}
|
|
19402
|
+
throw new Error("小云雀任务超时");
|
|
19403
|
+
};
|
|
19404
|
+
var generateImage = async (prompt, options) => {
|
|
19405
|
+
const { threadId: existingThreadId, assetIds, onProgress, config } = options || {};
|
|
19406
|
+
onProgress?.("正在提交创作任务...");
|
|
19407
|
+
const submitResult = await submitRun({
|
|
19408
|
+
message: prompt,
|
|
19409
|
+
threadId: existingThreadId,
|
|
19410
|
+
assetIds,
|
|
19411
|
+
config
|
|
19412
|
+
});
|
|
19413
|
+
onProgress?.("任务已提交,等待创作完成...");
|
|
19414
|
+
const { entry_list } = await pollUntilComplete({ threadId: submitResult.thread_id, runId: submitResult.run_id, config }, { onProgress });
|
|
19415
|
+
console.log("[XYQ DEBUG] All result entries:", JSON.stringify(entry_list, null, 2));
|
|
19416
|
+
for (const entry of entry_list) {
|
|
19417
|
+
const media = extractMediaFromEntry(entry);
|
|
19418
|
+
if (media) {
|
|
19419
|
+
return {
|
|
19420
|
+
threadId: submitResult.thread_id,
|
|
19421
|
+
runId: submitResult.run_id,
|
|
19422
|
+
webThreadLink: submitResult.web_thread_link,
|
|
19423
|
+
imageUrl: media.url,
|
|
19424
|
+
width: media.width,
|
|
19425
|
+
height: media.height,
|
|
19426
|
+
type: media.type,
|
|
19427
|
+
format: media.format
|
|
19428
|
+
};
|
|
19429
|
+
}
|
|
19430
|
+
}
|
|
19431
|
+
throw new Error("未在结果中找到生成的图片");
|
|
19432
|
+
};
|
|
19243
19433
|
// src/common/ai/text/index.ts
|
|
19244
19434
|
var exports_text = {};
|
|
19245
19435
|
__export(exports_text, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wzyjs/utils",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.26",
|
|
4
4
|
"description": "description",
|
|
5
5
|
"author": "wzy",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"@types/nodemailer": "^6.4.7",
|
|
71
71
|
"@types/papaparse": "^5.3.15"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "cf770d4d9e94b1000eab84ce34f91a4e6ee912f6",
|
|
74
74
|
"publishConfig": {
|
|
75
75
|
"access": "public"
|
|
76
76
|
}
|