@wzyjs/utils 0.3.25 → 0.3.27
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 +205 -8
- package/dist/node.esm.js +203 -6
- package/dist/web.cjs.js +197 -1
- package/dist/web.esm.js +197 -1
- 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, {
|
|
@@ -36130,7 +36321,13 @@ var complete = async (apiUrl, model, token, messages, json = true) => {
|
|
|
36130
36321
|
const errorText = await response.text();
|
|
36131
36322
|
throw new Error(`API request failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
36132
36323
|
}
|
|
36133
|
-
const
|
|
36324
|
+
const responseText = await response.text();
|
|
36325
|
+
let data;
|
|
36326
|
+
try {
|
|
36327
|
+
data = JSON.parse(responseText);
|
|
36328
|
+
} catch (e) {
|
|
36329
|
+
throw new Error(`Failed to parse API response as JSON: ${e.message}. Raw response: ${responseText.slice(0, 500)}`);
|
|
36330
|
+
}
|
|
36134
36331
|
const content = data?.choices?.[0]?.message?.content || data?.output || "";
|
|
36135
36332
|
if (!content) {
|
|
36136
36333
|
throw new Error("No content in response");
|
|
@@ -38875,10 +39072,10 @@ var Enum = {
|
|
|
38875
39072
|
}
|
|
38876
39073
|
};
|
|
38877
39074
|
// src/common/image/index.ts
|
|
38878
|
-
var
|
|
39075
|
+
var import_axios9 = __toESM(require("axios"));
|
|
38879
39076
|
async function imageToBase64(url2) {
|
|
38880
39077
|
try {
|
|
38881
|
-
const response = await
|
|
39078
|
+
const response = await import_axios9.default.get(url2, {
|
|
38882
39079
|
responseType: "arraybuffer"
|
|
38883
39080
|
});
|
|
38884
39081
|
const base64String = Buffer.from(response.data).toString("base64");
|
|
@@ -39121,7 +39318,7 @@ __export(exports_file, {
|
|
|
39121
39318
|
downloadFile: () => downloadFile
|
|
39122
39319
|
});
|
|
39123
39320
|
var import_fs_extra = __toESM(require("fs-extra"));
|
|
39124
|
-
var
|
|
39321
|
+
var import_axios10 = __toESM(require("axios"));
|
|
39125
39322
|
var import_url = __toESM(require("url"));
|
|
39126
39323
|
var path2 = __toESM(require("path"));
|
|
39127
39324
|
var import_crypto = __toESM(require("crypto"));
|
|
@@ -39202,7 +39399,7 @@ var downloadFile = async (httpUrl, outputPath) => {
|
|
|
39202
39399
|
}
|
|
39203
39400
|
outputPath = ".tmp/" + decodeURIComponent(fileName);
|
|
39204
39401
|
}
|
|
39205
|
-
const response = await
|
|
39402
|
+
const response = await import_axios10.default({
|
|
39206
39403
|
url: httpUrl,
|
|
39207
39404
|
method: "get",
|
|
39208
39405
|
responseType: "stream"
|
|
@@ -39239,7 +39436,7 @@ var processFile = async (params) => {
|
|
|
39239
39436
|
throw new Error("当类型为 url 时,file 必须是字符串");
|
|
39240
39437
|
}
|
|
39241
39438
|
try {
|
|
39242
|
-
const response = await
|
|
39439
|
+
const response = await import_axios10.default.get(file, { responseType: "arraybuffer" });
|
|
39243
39440
|
buffer = Buffer.from(response.data);
|
|
39244
39441
|
} catch (error) {
|
|
39245
39442
|
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, {
|
|
@@ -35226,7 +35417,13 @@ var complete = async (apiUrl, model, token, messages, json = true) => {
|
|
|
35226
35417
|
const errorText = await response.text();
|
|
35227
35418
|
throw new Error(`API request failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
35228
35419
|
}
|
|
35229
|
-
const
|
|
35420
|
+
const responseText = await response.text();
|
|
35421
|
+
let data;
|
|
35422
|
+
try {
|
|
35423
|
+
data = JSON.parse(responseText);
|
|
35424
|
+
} catch (e) {
|
|
35425
|
+
throw new Error(`Failed to parse API response as JSON: ${e.message}. Raw response: ${responseText.slice(0, 500)}`);
|
|
35426
|
+
}
|
|
35230
35427
|
const content = data?.choices?.[0]?.message?.content || data?.output || "";
|
|
35231
35428
|
if (!content) {
|
|
35232
35429
|
throw new Error("No content in response");
|
|
@@ -37971,10 +38168,10 @@ var Enum = {
|
|
|
37971
38168
|
}
|
|
37972
38169
|
};
|
|
37973
38170
|
// src/common/image/index.ts
|
|
37974
|
-
import
|
|
38171
|
+
import axios6 from "axios";
|
|
37975
38172
|
async function imageToBase64(url2) {
|
|
37976
38173
|
try {
|
|
37977
|
-
const response = await
|
|
38174
|
+
const response = await axios6.get(url2, {
|
|
37978
38175
|
responseType: "arraybuffer"
|
|
37979
38176
|
});
|
|
37980
38177
|
const base64String = Buffer.from(response.data).toString("base64");
|
|
@@ -38890,7 +39087,7 @@ __export(exports_file, {
|
|
|
38890
39087
|
downloadFile: () => downloadFile
|
|
38891
39088
|
});
|
|
38892
39089
|
import fs from "fs-extra";
|
|
38893
|
-
import
|
|
39090
|
+
import axios7 from "axios";
|
|
38894
39091
|
import url2 from "url";
|
|
38895
39092
|
import * as path2 from "path";
|
|
38896
39093
|
import crypto2 from "crypto";
|
|
@@ -38971,7 +39168,7 @@ var downloadFile = async (httpUrl, outputPath) => {
|
|
|
38971
39168
|
}
|
|
38972
39169
|
outputPath = ".tmp/" + decodeURIComponent(fileName);
|
|
38973
39170
|
}
|
|
38974
|
-
const response = await
|
|
39171
|
+
const response = await axios7({
|
|
38975
39172
|
url: httpUrl,
|
|
38976
39173
|
method: "get",
|
|
38977
39174
|
responseType: "stream"
|
|
@@ -39008,7 +39205,7 @@ var processFile = async (params) => {
|
|
|
39008
39205
|
throw new Error("当类型为 url 时,file 必须是字符串");
|
|
39009
39206
|
}
|
|
39010
39207
|
try {
|
|
39011
|
-
const response = await
|
|
39208
|
+
const response = await axios7.get(file, { responseType: "arraybuffer" });
|
|
39012
39209
|
buffer = Buffer.from(response.data);
|
|
39013
39210
|
} catch (error) {
|
|
39014
39211
|
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, {
|
|
@@ -19455,7 +19645,13 @@ var complete = async (apiUrl, model, token, messages, json = true) => {
|
|
|
19455
19645
|
const errorText = await response.text();
|
|
19456
19646
|
throw new Error(`API request failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
19457
19647
|
}
|
|
19458
|
-
const
|
|
19648
|
+
const responseText = await response.text();
|
|
19649
|
+
let data;
|
|
19650
|
+
try {
|
|
19651
|
+
data = JSON.parse(responseText);
|
|
19652
|
+
} catch (e) {
|
|
19653
|
+
throw new Error(`Failed to parse API response as JSON: ${e.message}. Raw response: ${responseText.slice(0, 500)}`);
|
|
19654
|
+
}
|
|
19459
19655
|
const content = data?.choices?.[0]?.message?.content || data?.output || "";
|
|
19460
19656
|
if (!content) {
|
|
19461
19657
|
throw new Error("No content in response");
|
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, {
|
|
@@ -19264,7 +19454,13 @@ var complete = async (apiUrl, model, token, messages, json = true) => {
|
|
|
19264
19454
|
const errorText = await response.text();
|
|
19265
19455
|
throw new Error(`API request failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
19266
19456
|
}
|
|
19267
|
-
const
|
|
19457
|
+
const responseText = await response.text();
|
|
19458
|
+
let data;
|
|
19459
|
+
try {
|
|
19460
|
+
data = JSON.parse(responseText);
|
|
19461
|
+
} catch (e) {
|
|
19462
|
+
throw new Error(`Failed to parse API response as JSON: ${e.message}. Raw response: ${responseText.slice(0, 500)}`);
|
|
19463
|
+
}
|
|
19268
19464
|
const content = data?.choices?.[0]?.message?.content || data?.output || "";
|
|
19269
19465
|
if (!content) {
|
|
19270
19466
|
throw new Error("No content in response");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wzyjs/utils",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.27",
|
|
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": "f9e5dcf56fea3b93a2614ad468ecb466e5da7945",
|
|
74
74
|
"publishConfig": {
|
|
75
75
|
"access": "public"
|
|
76
76
|
}
|