@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.
@@ -1,4 +1,5 @@
1
1
  export * as ai302 from './302';
2
2
  export * as doubao from './doubao';
3
3
  export * as keling from './keling';
4
+ export * as xyq from './xyq';
4
5
  export * as text from './text';
@@ -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: () => import_axios10.default,
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 import_axios10 = __toESM(require("axios"));
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 data = await response.json();
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 import_axios8 = __toESM(require("axios"));
39075
+ var import_axios9 = __toESM(require("axios"));
38879
39076
  async function imageToBase64(url2) {
38880
39077
  try {
38881
- const response = await import_axios8.default.get(url2, {
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 import_axios9 = __toESM(require("axios"));
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 import_axios9.default({
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 import_axios9.default.get(file, { responseType: "arraybuffer" });
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 data = await response.json();
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 axios5 from "axios";
38171
+ import axios6 from "axios";
37975
38172
  async function imageToBase64(url2) {
37976
38173
  try {
37977
- const response = await axios5.get(url2, {
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 axios6 from "axios";
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 axios6({
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 axios6.get(file, { responseType: "arraybuffer" });
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 data = await response.json();
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 data = await response.json();
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.25",
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": "ccab22c313d0a8023b98f9711f65c5ed59d886a8",
73
+ "gitHead": "f9e5dcf56fea3b93a2614ad468ecb466e5da7945",
74
74
  "publishConfig": {
75
75
  "access": "public"
76
76
  }