@optima-chat/gen-cli 1.0.0 → 1.0.1

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.
Files changed (98) hide show
  1. package/dist/index.js +0 -0
  2. package/package.json +1 -1
  3. package/dist/backends/bfl.d.ts +0 -18
  4. package/dist/backends/bfl.d.ts.map +0 -1
  5. package/dist/backends/bfl.js +0 -130
  6. package/dist/backends/bfl.js.map +0 -1
  7. package/dist/backends/comfyui.d.ts +0 -10
  8. package/dist/backends/comfyui.d.ts.map +0 -1
  9. package/dist/backends/comfyui.js +0 -121
  10. package/dist/backends/comfyui.js.map +0 -1
  11. package/dist/backends/index.d.ts +0 -24
  12. package/dist/backends/index.d.ts.map +0 -1
  13. package/dist/backends/index.js +0 -59
  14. package/dist/backends/index.js.map +0 -1
  15. package/dist/backends/types.d.ts +0 -99
  16. package/dist/backends/types.d.ts.map +0 -1
  17. package/dist/backends/types.js +0 -2
  18. package/dist/backends/types.js.map +0 -1
  19. package/dist/backends/video-dashscope.d.ts +0 -10
  20. package/dist/backends/video-dashscope.d.ts.map +0 -1
  21. package/dist/backends/video-dashscope.js +0 -108
  22. package/dist/backends/video-dashscope.js.map +0 -1
  23. package/dist/backends/video-index.d.ts +0 -23
  24. package/dist/backends/video-index.d.ts.map +0 -1
  25. package/dist/backends/video-index.js +0 -57
  26. package/dist/backends/video-index.js.map +0 -1
  27. package/dist/commands/download.d.ts +0 -3
  28. package/dist/commands/download.d.ts.map +0 -1
  29. package/dist/commands/download.js +0 -169
  30. package/dist/commands/download.js.map +0 -1
  31. package/dist/commands/edit.d.ts +0 -3
  32. package/dist/commands/edit.d.ts.map +0 -1
  33. package/dist/commands/edit.js +0 -155
  34. package/dist/commands/edit.js.map +0 -1
  35. package/dist/commands/generate.d.ts +0 -3
  36. package/dist/commands/generate.d.ts.map +0 -1
  37. package/dist/commands/generate.js +0 -135
  38. package/dist/commands/generate.js.map +0 -1
  39. package/dist/commands/init.d.ts +0 -3
  40. package/dist/commands/init.d.ts.map +0 -1
  41. package/dist/commands/init.js +0 -144
  42. package/dist/commands/init.js.map +0 -1
  43. package/dist/commands/interrupt.d.ts +0 -3
  44. package/dist/commands/interrupt.d.ts.map +0 -1
  45. package/dist/commands/interrupt.js +0 -54
  46. package/dist/commands/interrupt.js.map +0 -1
  47. package/dist/commands/model.d.ts +0 -3
  48. package/dist/commands/model.d.ts.map +0 -1
  49. package/dist/commands/model.js +0 -82
  50. package/dist/commands/model.js.map +0 -1
  51. package/dist/commands/node.d.ts +0 -3
  52. package/dist/commands/node.d.ts.map +0 -1
  53. package/dist/commands/node.js +0 -148
  54. package/dist/commands/node.js.map +0 -1
  55. package/dist/commands/queue.d.ts +0 -3
  56. package/dist/commands/queue.d.ts.map +0 -1
  57. package/dist/commands/queue.js +0 -199
  58. package/dist/commands/queue.js.map +0 -1
  59. package/dist/commands/system.d.ts +0 -3
  60. package/dist/commands/system.d.ts.map +0 -1
  61. package/dist/commands/system.js +0 -85
  62. package/dist/commands/system.js.map +0 -1
  63. package/dist/commands/workflow.d.ts +0 -3
  64. package/dist/commands/workflow.d.ts.map +0 -1
  65. package/dist/commands/workflow.js +0 -244
  66. package/dist/commands/workflow.js.map +0 -1
  67. package/dist/services/api.d.ts +0 -23
  68. package/dist/services/api.d.ts.map +0 -1
  69. package/dist/services/api.js +0 -108
  70. package/dist/services/api.js.map +0 -1
  71. package/dist/services/bfl-api.d.ts +0 -67
  72. package/dist/services/bfl-api.d.ts.map +0 -1
  73. package/dist/services/bfl-api.js +0 -108
  74. package/dist/services/bfl-api.js.map +0 -1
  75. package/dist/services/dashscope-api.d.ts +0 -69
  76. package/dist/services/dashscope-api.d.ts.map +0 -1
  77. package/dist/services/dashscope-api.js +0 -134
  78. package/dist/services/dashscope-api.js.map +0 -1
  79. package/dist/services/dashscope-tts-api.d.ts +0 -23
  80. package/dist/services/dashscope-tts-api.d.ts.map +0 -1
  81. package/dist/services/dashscope-tts-api.js +0 -56
  82. package/dist/services/dashscope-tts-api.js.map +0 -1
  83. package/dist/services/fashn-api.d.ts +0 -57
  84. package/dist/services/fashn-api.d.ts.map +0 -1
  85. package/dist/services/fashn-api.js +0 -84
  86. package/dist/services/fashn-api.js.map +0 -1
  87. package/dist/services/groq-api.d.ts +0 -18
  88. package/dist/services/groq-api.d.ts.map +0 -1
  89. package/dist/services/groq-api.js +0 -30
  90. package/dist/services/groq-api.js.map +0 -1
  91. package/dist/services/websocket.d.ts +0 -33
  92. package/dist/services/websocket.d.ts.map +0 -1
  93. package/dist/services/websocket.js +0 -217
  94. package/dist/services/websocket.js.map +0 -1
  95. package/dist/utils/workflow.d.ts +0 -17
  96. package/dist/utils/workflow.d.ts.map +0 -1
  97. package/dist/utils/workflow.js +0 -81
  98. package/dist/utils/workflow.js.map +0 -1
package/dist/index.js CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optima-chat/gen-cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "AI content generation CLI for LLM agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,18 +0,0 @@
1
- import type { ImageBackend, ImageParams, ImageResult } from './types.js';
2
- export declare class BFLBackend implements ImageBackend {
3
- readonly name: "bfl";
4
- private client;
5
- constructor(apiKey: string);
6
- isAvailable(): boolean;
7
- generate(params: ImageParams): Promise<ImageResult>;
8
- getStatus(id: string): Promise<ImageResult>;
9
- /**
10
- * 处理输入图像,转换为 base64
11
- */
12
- private processInputImages;
13
- /**
14
- * 将输入图像映射到 BFL 参数
15
- */
16
- private mapInputImages;
17
- }
18
- //# sourceMappingURL=bfl.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bfl.d.ts","sourceRoot":"","sources":["../../src/backends/bfl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAMzE,qBAAa,UAAW,YAAW,YAAY;IAC7C,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAC/B,OAAO,CAAC,MAAM,CAAY;gBAEd,MAAM,EAAE,MAAM;IAI1B,WAAW,IAAI,OAAO;IAIhB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IA0EnD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAsBjD;;OAEG;YACW,kBAAkB;IAQhC;;OAEG;IACH,OAAO,CAAC,cAAc;CAcvB"}
@@ -1,130 +0,0 @@
1
- import * as path from 'path';
2
- import { BFLClient } from '../services/bfl-api.js';
3
- import { getConfig } from '../services/config.js';
4
- const IMAGE_EXTENSIONS = ['.png', '.jpg', '.jpeg'];
5
- export class BFLBackend {
6
- name = 'bfl';
7
- client;
8
- constructor(apiKey) {
9
- this.client = new BFLClient(apiKey);
10
- }
11
- isAvailable() {
12
- return true;
13
- }
14
- async generate(params) {
15
- const startTime = Date.now();
16
- const cfg = getConfig();
17
- // 1. 处理输入图像(转为 base64)
18
- const inputImageBase64s = await this.processInputImages(params.inputImages);
19
- // 2. 构建 BFL 请求参数
20
- const bflParams = {
21
- prompt: params.prompt,
22
- width: params.width,
23
- height: params.height,
24
- seed: params.seed,
25
- output_format: params.outputFormat || cfg.bfl?.outputFormat || 'png',
26
- safety_tolerance: params.safetyTolerance ?? cfg.bfl?.safetyTolerance ?? 2,
27
- ...this.mapInputImages(inputImageBase64s),
28
- };
29
- // 3. 提交任务
30
- const submitResult = await this.client.submit(bflParams);
31
- const taskId = submitResult.id;
32
- const pollingUrl = submitResult.polling_url;
33
- // 4. 如果不等待,直接返回
34
- if (params.wait === false) {
35
- return {
36
- id: taskId,
37
- backend: 'bfl',
38
- status: 'pending',
39
- };
40
- }
41
- // 5. 轮询等待结果 - 使用服务器返回的 polling_url
42
- const pollResult = await this.client.poll(pollingUrl, {
43
- interval: 1000,
44
- timeout: 300000,
45
- });
46
- // 6. 下载图像到本地
47
- const outputFormat = params.outputFormat || cfg.bfl?.outputFormat || 'png';
48
- const defaultFilename = `bfl_${taskId}.${outputFormat}`;
49
- let outputDir;
50
- let filename;
51
- const outputPath = params.outputDir;
52
- if (outputPath && IMAGE_EXTENSIONS.some(ext => outputPath.toLowerCase().endsWith(ext))) {
53
- // 用户指定了完整文件路径
54
- outputDir = path.dirname(outputPath);
55
- filename = path.basename(outputPath);
56
- }
57
- else {
58
- // 用户指定了目录或使用默认值
59
- outputDir = outputPath || cfg.outputDir || './comfy-output';
60
- filename = defaultFilename;
61
- }
62
- let localPath;
63
- if (pollResult.result?.sample) {
64
- localPath = await this.client.downloadImage(pollResult.result.sample, outputDir, filename);
65
- }
66
- const durationMs = Date.now() - startTime;
67
- return {
68
- id: taskId,
69
- backend: 'bfl',
70
- status: 'completed',
71
- output: localPath,
72
- outputUrl: pollResult.result?.sample,
73
- seed: pollResult.result?.seed,
74
- durationMs,
75
- };
76
- }
77
- async getStatus(id) {
78
- const result = await this.client.getResult(id);
79
- let status = 'pending';
80
- if (result.status === 'Ready') {
81
- status = 'completed';
82
- }
83
- else if (result.status === 'Error' || result.status === 'Request Moderated' || result.status === 'Content Moderated') {
84
- status = 'failed';
85
- }
86
- else if (result.status === 'Pending') {
87
- status = result.progress && result.progress > 0 ? 'processing' : 'pending';
88
- }
89
- return {
90
- id,
91
- backend: 'bfl',
92
- status,
93
- outputUrl: result.result?.sample,
94
- seed: result.result?.seed,
95
- error: status === 'failed' ? result.status : undefined,
96
- };
97
- }
98
- /**
99
- * 处理输入图像,转换为 base64
100
- */
101
- async processInputImages(paths) {
102
- if (!paths || paths.length === 0)
103
- return [];
104
- return Promise.all(paths.map(p => this.client.imageToBase64(p)));
105
- }
106
- /**
107
- * 将输入图像映射到 BFL 参数
108
- */
109
- mapInputImages(base64Images) {
110
- const mapping = {};
111
- if (base64Images[0])
112
- mapping.input_image = base64Images[0];
113
- if (base64Images[1])
114
- mapping.input_image_2 = base64Images[1];
115
- if (base64Images[2])
116
- mapping.input_image_3 = base64Images[2];
117
- if (base64Images[3])
118
- mapping.input_image_4 = base64Images[3];
119
- if (base64Images[4])
120
- mapping.input_image_5 = base64Images[4];
121
- if (base64Images[5])
122
- mapping.input_image_6 = base64Images[5];
123
- if (base64Images[6])
124
- mapping.input_image_7 = base64Images[6];
125
- if (base64Images[7])
126
- mapping.input_image_8 = base64Images[7];
127
- return mapping;
128
- }
129
- }
130
- //# sourceMappingURL=bfl.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bfl.js","sourceRoot":"","sources":["../../src/backends/bfl.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- import type { ImageBackend, ImageParams, ImageResult } from './types.js';
2
- export declare class ComfyUIBackend implements ImageBackend {
3
- readonly name: "comfyui";
4
- private client;
5
- constructor();
6
- isAvailable(): boolean;
7
- generate(params: ImageParams): Promise<ImageResult>;
8
- getStatus(id: string): Promise<ImageResult>;
9
- }
10
- //# sourceMappingURL=comfyui.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"comfyui.d.ts","sourceRoot":"","sources":["../../src/backends/comfyui.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAQzE,qBAAa,cAAe,YAAW,YAAY;IACjD,QAAQ,CAAC,IAAI,EAAG,SAAS,CAAU;IACnC,OAAO,CAAC,MAAM,CAAiB;;IAM/B,WAAW,IAAI,OAAO;IAIhB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IA8GnD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAelD"}
@@ -1,121 +0,0 @@
1
- import * as fs from 'fs/promises';
2
- import * as path from 'path';
3
- import { ComfyAPIClient } from '../services/api.js';
4
- import { loadWorkflow, getBuiltinWorkflowPath, replaceVariables } from '../utils/workflow.js';
5
- import { monitorProgress } from '../services/websocket.js';
6
- import { getConfig } from '../services/config.js';
7
- const IMAGE_EXTENSIONS = ['.png', '.jpg', '.jpeg'];
8
- export class ComfyUIBackend {
9
- name = 'comfyui';
10
- client;
11
- constructor() {
12
- this.client = new ComfyAPIClient();
13
- }
14
- isAvailable() {
15
- return true;
16
- }
17
- async generate(params) {
18
- const startTime = Date.now();
19
- const cfg = getConfig();
20
- // 1. 选择工作流模板
21
- const hasInputImage = params.inputImages && params.inputImages.length > 0;
22
- const workflowName = hasInputImage ? 'flux_image_to_image.json' : 'flux_text_to_image.json';
23
- const workflowPath = getBuiltinWorkflowPath(workflowName);
24
- const workflow = loadWorkflow(workflowPath);
25
- // 2. 处理输入图像(如果有)
26
- let uploadedImageName;
27
- if (hasInputImage && params.inputImages[0]) {
28
- const imagePath = params.inputImages[0];
29
- const imageBuffer = await fs.readFile(imagePath);
30
- const filename = path.basename(imagePath);
31
- const uploadResult = await this.client.uploadImage(imageBuffer, filename);
32
- uploadedImageName = uploadResult.name;
33
- }
34
- // 3. 构建工作流参数
35
- const workflowParams = {
36
- prompt: params.prompt,
37
- width: params.width || 1024,
38
- height: params.height || 1024,
39
- steps: 20,
40
- cfg_scale: 1.0,
41
- seed: params.seed ?? Math.floor(Math.random() * 1000000),
42
- filename_prefix: 'comfy-cli',
43
- model: 'FLUX1/flux1-dev-fp8.safetensors',
44
- sampler: 'euler',
45
- scheduler: 'simple',
46
- negative_prompt: 'Blurry details, distorted shapes, unrealistic reflections, harsh lighting, excessive shadows, overly saturated colors, unnatural composition, poor rendering, low resolution, pixelation, artificial-looking textures, overly exaggerated contrast, cluttered background, unnecessary elements, random objects, plastic-like appearance.',
47
- guidance: 3.5,
48
- };
49
- if (uploadedImageName) {
50
- workflowParams.input_image = uploadedImageName;
51
- workflowParams.denoise = 0.75; // 图生图默认 denoise
52
- }
53
- // 4. 替换变量并提交
54
- const processedWorkflow = replaceVariables(workflow, workflowParams);
55
- const result = await this.client.submitWorkflow(processedWorkflow);
56
- const promptId = result.prompt_id;
57
- // 5. 如果不等待,直接返回
58
- if (params.wait === false) {
59
- return {
60
- id: promptId,
61
- backend: 'comfyui',
62
- status: 'pending',
63
- seed: workflowParams.seed,
64
- };
65
- }
66
- // 6. WebSocket 监控进度
67
- await monitorProgress(promptId);
68
- // 7. 获取输出文件并下载到本地
69
- const outputs = await this.client.getOutputFiles(promptId);
70
- const outputFile = outputs[0];
71
- let localPath;
72
- let outputUrl;
73
- if (outputFile) {
74
- // 构建 URL
75
- const serverUrl = cfg.server;
76
- outputUrl = `${serverUrl}/view?filename=${encodeURIComponent(outputFile.filename)}&subfolder=${encodeURIComponent(outputFile.subfolder)}&type=${encodeURIComponent(outputFile.type)}`;
77
- // 下载到本地
78
- let outputDir;
79
- let filename;
80
- const outputPath = params.outputDir;
81
- if (outputPath && IMAGE_EXTENSIONS.some(ext => outputPath.toLowerCase().endsWith(ext))) {
82
- // 用户指定了完整文件路径
83
- outputDir = path.dirname(outputPath);
84
- filename = path.basename(outputPath);
85
- }
86
- else {
87
- // 用户指定了目录或使用默认值
88
- outputDir = outputPath || cfg.outputDir || './comfy-output';
89
- filename = outputFile.filename;
90
- }
91
- await fs.mkdir(outputDir, { recursive: true });
92
- localPath = path.join(outputDir, filename);
93
- const imageBuffer = await this.client.downloadImage(outputFile.filename, outputFile.subfolder, outputFile.type);
94
- await fs.writeFile(localPath, imageBuffer);
95
- }
96
- const durationMs = Date.now() - startTime;
97
- return {
98
- id: promptId,
99
- backend: 'comfyui',
100
- status: 'completed',
101
- output: localPath,
102
- outputUrl,
103
- seed: workflowParams.seed,
104
- durationMs,
105
- };
106
- }
107
- async getStatus(id) {
108
- const history = await this.client.getHistory(id);
109
- let status = 'pending';
110
- if (history && history[id]) {
111
- const outputs = history[id].outputs;
112
- status = outputs && Object.keys(outputs).length > 0 ? 'completed' : 'processing';
113
- }
114
- return {
115
- id,
116
- backend: 'comfyui',
117
- status,
118
- };
119
- }
120
- }
121
- //# sourceMappingURL=comfyui.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"comfyui.js","sourceRoot":"","sources":["../../src/backends/comfyui.ts"],"names":[],"mappings":"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"}
@@ -1,24 +0,0 @@
1
- import type { ImageBackend } from './types.js';
2
- export type BackendType = 'auto' | 'bfl' | 'comfyui';
3
- export { ImageBackend, ImageParams, ImageResult } from './types.js';
4
- export { BFLBackend } from './bfl.js';
5
- export { ComfyUIBackend } from './comfyui.js';
6
- /**
7
- * 获取 BFL API Key(优先环境变量,其次配置文件)
8
- */
9
- export declare function getBFLApiKey(): string | undefined;
10
- /**
11
- * 获取图像生成后端
12
- *
13
- * - auto: 有 BFL API Key 则用 BFL,否则用 ComfyUI
14
- * - bfl: 强制使用 BFL(需要 API Key)
15
- * - comfyui: 强制使用 ComfyUI
16
- *
17
- * API Key 优先级: 环境变量 BFL_API_KEY > 配置文件 bfl.apiKey
18
- */
19
- export declare function getBackend(type?: BackendType): ImageBackend;
20
- /**
21
- * 获取当前会使用的后端名称
22
- */
23
- export declare function getCurrentBackendName(type?: BackendType): 'bfl' | 'comfyui';
24
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backends/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAEjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,YAAY,CAyB3D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,KAAK,GAAG,SAAS,CAe3E"}
@@ -1,59 +0,0 @@
1
- import { getConfig } from '../services/config.js';
2
- import { BFLBackend } from './bfl.js';
3
- import { ComfyUIBackend } from './comfyui.js';
4
- export { BFLBackend } from './bfl.js';
5
- export { ComfyUIBackend } from './comfyui.js';
6
- /**
7
- * 获取 BFL API Key(优先环境变量,其次配置文件)
8
- */
9
- export function getBFLApiKey() {
10
- return process.env.BFL_API_KEY || getConfig().bfl?.apiKey;
11
- }
12
- /**
13
- * 获取图像生成后端
14
- *
15
- * - auto: 有 BFL API Key 则用 BFL,否则用 ComfyUI
16
- * - bfl: 强制使用 BFL(需要 API Key)
17
- * - comfyui: 强制使用 ComfyUI
18
- *
19
- * API Key 优先级: 环境变量 BFL_API_KEY > 配置文件 bfl.apiKey
20
- */
21
- export function getBackend(type) {
22
- const cfg = getConfig();
23
- const backendType = type || cfg.preferBackend || 'auto';
24
- // 强制使用 BFL
25
- if (backendType === 'bfl') {
26
- const apiKey = getBFLApiKey();
27
- if (!apiKey) {
28
- throw new Error('BFL API key not configured. Set BFL_API_KEY env or run: comfy config set bfl.apiKey <key>');
29
- }
30
- return new BFLBackend(apiKey);
31
- }
32
- // 强制使用 ComfyUI
33
- if (backendType === 'comfyui') {
34
- return new ComfyUIBackend();
35
- }
36
- // 自动选择:优先 BFL
37
- const apiKey = getBFLApiKey();
38
- if (apiKey) {
39
- return new BFLBackend(apiKey);
40
- }
41
- return new ComfyUIBackend();
42
- }
43
- /**
44
- * 获取当前会使用的后端名称
45
- */
46
- export function getCurrentBackendName(type) {
47
- const cfg = getConfig();
48
- const backendType = type || cfg.preferBackend || 'auto';
49
- if (backendType === 'bfl') {
50
- return 'bfl';
51
- }
52
- if (backendType === 'comfyui') {
53
- return 'comfyui';
54
- }
55
- // auto
56
- const apiKey = getBFLApiKey();
57
- return apiKey ? 'bfl' : 'comfyui';
58
- }
59
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backends/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAM9C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC;AAC5D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,IAAkB;IAC3C,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,MAAM,WAAW,GAAG,IAAI,IAAI,GAAG,CAAC,aAAa,IAAI,MAAM,CAAC;IAExD,WAAW;IACX,IAAI,WAAW,KAAK,KAAK,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,2FAA2F,CAAC,CAAC;QAC/G,CAAC;QACD,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAED,eAAe;IACf,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,IAAI,cAAc,EAAE,CAAC;IAC9B,CAAC;IAED,cAAc;IACd,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,IAAI,cAAc,EAAE,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAkB;IACtD,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,MAAM,WAAW,GAAG,IAAI,IAAI,GAAG,CAAC,aAAa,IAAI,MAAM,CAAC;IAExD,IAAI,WAAW,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;IACP,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACpC,CAAC"}
@@ -1,99 +0,0 @@
1
- /**
2
- * 图像生成/编辑参数
3
- */
4
- export interface ImageParams {
5
- prompt: string;
6
- inputImages?: string[];
7
- width?: number;
8
- height?: number;
9
- seed?: number;
10
- outputFormat?: 'jpeg' | 'png';
11
- outputDir?: string;
12
- safetyTolerance?: number;
13
- wait?: boolean;
14
- }
15
- /**
16
- * 图像生成/编辑结果
17
- */
18
- export interface ImageResult {
19
- id: string;
20
- backend: 'bfl' | 'comfyui';
21
- status: 'pending' | 'processing' | 'completed' | 'failed';
22
- output?: string;
23
- outputUrl?: string;
24
- seed?: number;
25
- cost?: number;
26
- megapixels?: number;
27
- durationMs?: number;
28
- error?: string;
29
- }
30
- /**
31
- * 后端接口
32
- */
33
- export interface ImageBackend {
34
- readonly name: 'bfl' | 'comfyui';
35
- /**
36
- * 检查后端是否可用
37
- */
38
- isAvailable(): boolean;
39
- /**
40
- * 生成/编辑图像
41
- */
42
- generate(params: ImageParams): Promise<ImageResult>;
43
- /**
44
- * 获取任务状态
45
- */
46
- getStatus(id: string): Promise<ImageResult>;
47
- }
48
- /**
49
- * 视频生成参数
50
- */
51
- export interface VideoParams {
52
- inputImage: string;
53
- prompt?: string;
54
- negativePrompt?: string;
55
- resolution?: '720P' | '1080P';
56
- duration?: 5 | 10 | 15;
57
- seed?: number;
58
- outputDir?: string;
59
- wait?: boolean;
60
- promptExtend?: boolean;
61
- audio?: boolean;
62
- audioUrl?: string;
63
- shotType?: 'single' | 'multi';
64
- watermark?: boolean;
65
- }
66
- /**
67
- * 视频生成结果
68
- */
69
- export interface VideoResult {
70
- id: string;
71
- backend: 'dashscope' | 'comfyui';
72
- status: 'pending' | 'processing' | 'completed' | 'failed';
73
- output?: string;
74
- outputUrl?: string;
75
- duration?: number;
76
- resolution?: string;
77
- seed?: number;
78
- durationMs?: number;
79
- error?: string;
80
- }
81
- /**
82
- * 视频后端接口
83
- */
84
- export interface VideoBackend {
85
- readonly name: 'dashscope' | 'comfyui';
86
- /**
87
- * 检查后端是否可用
88
- */
89
- isAvailable(): boolean;
90
- /**
91
- * 生成视频
92
- */
93
- generate(params: VideoParams): Promise<VideoResult>;
94
- /**
95
- * 获取任务状态
96
- */
97
- getStatus(id: string): Promise<VideoResult>;
98
- }
99
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/backends/types.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/backends/types.ts"],"names":[],"mappings":""}
@@ -1,10 +0,0 @@
1
- import type { VideoBackend, VideoParams, VideoResult } from './types.js';
2
- export declare class DashScopeVideoBackend implements VideoBackend {
3
- readonly name: "dashscope";
4
- private client;
5
- constructor(apiKey: string);
6
- isAvailable(): boolean;
7
- generate(params: VideoParams): Promise<VideoResult>;
8
- getStatus(id: string): Promise<VideoResult>;
9
- }
10
- //# sourceMappingURL=video-dashscope.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"video-dashscope.d.ts","sourceRoot":"","sources":["../../src/backends/video-dashscope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAMzE,qBAAa,qBAAsB,YAAW,YAAY;IACxD,QAAQ,CAAC,IAAI,EAAG,WAAW,CAAU;IACrC,OAAO,CAAC,MAAM,CAAkB;gBAEpB,MAAM,EAAE,MAAM;IAI1B,WAAW,IAAI,OAAO;IAIhB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAkFnD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAsBlD"}
@@ -1,108 +0,0 @@
1
- import * as path from 'path';
2
- import { DashScopeClient } from '../services/dashscope-api.js';
3
- import { getConfig } from '../services/config.js';
4
- const VIDEO_EXTENSIONS = ['.mp4'];
5
- export class DashScopeVideoBackend {
6
- name = 'dashscope';
7
- client;
8
- constructor(apiKey) {
9
- this.client = new DashScopeClient(apiKey);
10
- }
11
- isAvailable() {
12
- return true;
13
- }
14
- async generate(params) {
15
- const startTime = Date.now();
16
- const cfg = getConfig();
17
- // 1. 处理输入图像(转为 base64 或直接使用 URL)
18
- let imgUrl = params.inputImage;
19
- if (!imgUrl.startsWith('http') && !imgUrl.startsWith('data:')) {
20
- imgUrl = await this.client.imageToBase64(params.inputImage);
21
- }
22
- // 2. 构建请求参数,合并配置默认值
23
- const submitParams = {
24
- prompt: params.prompt,
25
- negativePrompt: params.negativePrompt,
26
- imgUrl,
27
- audioUrl: params.audioUrl,
28
- resolution: params.resolution || cfg.dashscope?.resolution || '1080P',
29
- duration: params.duration || cfg.dashscope?.duration || 5,
30
- promptExtend: params.promptExtend ?? cfg.dashscope?.promptExtend ?? true,
31
- audio: params.audio ?? cfg.dashscope?.audio ?? true,
32
- shotType: params.shotType || cfg.dashscope?.shotType || 'single',
33
- watermark: params.watermark ?? false,
34
- seed: params.seed,
35
- };
36
- // 3. 提交任务
37
- const submitResult = await this.client.submit(submitParams);
38
- const taskId = submitResult.output.task_id;
39
- // 4. 如果不等待,直接返回
40
- if (params.wait === false) {
41
- return {
42
- id: taskId,
43
- backend: 'dashscope',
44
- status: 'pending',
45
- resolution: submitParams.resolution,
46
- duration: submitParams.duration,
47
- };
48
- }
49
- // 5. 轮询等待结果
50
- const pollResult = await this.client.poll(taskId, {
51
- interval: 15000,
52
- timeout: 600000,
53
- });
54
- // 6. 下载视频到本地
55
- const defaultFilename = `dashscope_${taskId}.mp4`;
56
- let outputDir;
57
- let filename;
58
- const outputPath = params.outputDir;
59
- if (outputPath && VIDEO_EXTENSIONS.some(ext => outputPath.toLowerCase().endsWith(ext))) {
60
- // 用户指定了完整文件路径
61
- outputDir = path.dirname(outputPath);
62
- filename = path.basename(outputPath);
63
- }
64
- else {
65
- // 用户指定了目录或使用默认值
66
- outputDir = outputPath || cfg.outputDir || './comfy-output';
67
- filename = defaultFilename;
68
- }
69
- let localPath;
70
- if (pollResult.output.video_url) {
71
- localPath = await this.client.downloadVideo(pollResult.output.video_url, outputDir, filename);
72
- }
73
- const durationMs = Date.now() - startTime;
74
- return {
75
- id: taskId,
76
- backend: 'dashscope',
77
- status: 'completed',
78
- output: localPath,
79
- outputUrl: pollResult.output.video_url,
80
- duration: pollResult.usage?.duration,
81
- resolution: submitParams.resolution,
82
- durationMs,
83
- };
84
- }
85
- async getStatus(id) {
86
- const result = await this.client.getResult(id);
87
- const status = result.output.task_status;
88
- let videoStatus = 'pending';
89
- if (status === 'SUCCEEDED') {
90
- videoStatus = 'completed';
91
- }
92
- else if (status === 'FAILED' || status === 'CANCELED' || status === 'UNKNOWN') {
93
- videoStatus = 'failed';
94
- }
95
- else if (status === 'RUNNING') {
96
- videoStatus = 'processing';
97
- }
98
- return {
99
- id,
100
- backend: 'dashscope',
101
- status: videoStatus,
102
- outputUrl: result.output.video_url,
103
- duration: result.usage?.duration,
104
- error: videoStatus === 'failed' ? status : undefined,
105
- };
106
- }
107
- }
108
- //# sourceMappingURL=video-dashscope.js.map