@wzyjs/utils 0.3.24 → 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.
@@ -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,
@@ -35647,7 +35648,7 @@ __export(exports_302, {
35647
35648
 
35648
35649
  // src/common/ai/302/axios.ts
35649
35650
  var import_axios = __toESM(require("axios"));
35650
- var key = process.env.AI_302_KEY || process.env.NEXT_PUBLIC_AI_302_KEY;
35651
+ var key = process.env.AI_302_KEY;
35651
35652
  var axios = import_axios.default.create({
35652
35653
  baseURL: "https://api.302.ai",
35653
35654
  headers: {
@@ -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 import_axios8 = __toESM(require("axios"));
39069
+ var import_axios9 = __toESM(require("axios"));
38879
39070
  async function imageToBase64(url2) {
38880
39071
  try {
38881
- const response = await import_axios8.default.get(url2, {
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 import_axios9 = __toESM(require("axios"));
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 import_axios9.default({
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 import_axios9.default.get(file, { responseType: "arraybuffer" });
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,
@@ -34743,7 +34744,7 @@ __export(exports_302, {
34743
34744
 
34744
34745
  // src/common/ai/302/axios.ts
34745
34746
  import axios_ from "axios";
34746
- var key = process.env.AI_302_KEY || process.env.NEXT_PUBLIC_AI_302_KEY;
34747
+ var key = process.env.AI_302_KEY;
34747
34748
  var axios = axios_.create({
34748
34749
  baseURL: "https://api.302.ai",
34749
34750
  headers: {
@@ -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 axios5 from "axios";
38165
+ import axios6 from "axios";
37975
38166
  async function imageToBase64(url2) {
37976
38167
  try {
37977
- const response = await axios5.get(url2, {
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 axios6 from "axios";
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 axios6({
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 axios6.get(file, { responseType: "arraybuffer" });
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,
@@ -18317,7 +18318,7 @@ __export(exports_302, {
18317
18318
  });
18318
18319
 
18319
18320
  // src/common/ai/302/axios.ts
18320
- var key = process.env.AI_302_KEY || process.env.NEXT_PUBLIC_AI_302_KEY;
18321
+ var key = process.env.AI_302_KEY;
18321
18322
  var axios2 = axios_default.create({
18322
18323
  baseURL: "https://api.302.ai",
18323
18324
  headers: {
@@ -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,
@@ -18126,7 +18127,7 @@ __export(exports_302, {
18126
18127
  });
18127
18128
 
18128
18129
  // src/common/ai/302/axios.ts
18129
- var key = process.env.AI_302_KEY || process.env.NEXT_PUBLIC_AI_302_KEY;
18130
+ var key = process.env.AI_302_KEY;
18130
18131
  var axios2 = axios_default.create({
18131
18132
  baseURL: "https://api.302.ai",
18132
18133
  headers: {
@@ -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.24",
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": "82ce1f2a13a92943ae2618039c78148ff9637d52",
73
+ "gitHead": "cf770d4d9e94b1000eab84ce34f91a4e6ee912f6",
74
74
  "publishConfig": {
75
75
  "access": "public"
76
76
  }