xt8 commited on
Commit
278e9a6
·
verified ·
1 Parent(s): 2d57059

Upload 52 files

Browse files
jimeng-api/Skill.md CHANGED
@@ -107,12 +107,12 @@ python scripts/generate_image.py text \
107
  - `prompt` (required): Text description of the desired image
108
  - `--session-id`: Jimeng session ID (required)
109
  - `--model`: Model to use (default: `jimeng-4.0`)
110
- - Options: `jimeng-4.0`, `jimeng-3.1`, `jimeng-3.0`, `jimeng-2.1`, `jimeng-xl-pro`, `nanobanana` (international only)
111
  - `--ratio`: Aspect ratio (default: `1:1`)
112
  - Options: `1:1`, `4:3`, `3:4`, `16:9`, `9:16`, `3:2`, `2:3`, `21:9`
113
  - `--resolution`: Resolution level (default: `2k`)
114
  - Options: `1k`, `2k`, `4k`
115
- - `--intelligent-ratio`: Enable smart ratio detection based on prompt keywords **⚠️ Only works for jimeng-4.0 model; other models will ignore this parameter**
116
  - `--negative-prompt`: Negative prompt (elements to avoid)
117
  - `--sample-strength`: Sampling strength (0.0-1.0)
118
  - `--api-url`: Custom API URL (default: `http://localhost:5100`)
@@ -155,7 +155,7 @@ python scripts/generate_image.py image \
155
 
156
  ### Intelligent Ratio Detection
157
 
158
- **⚠️ IMPORTANT**: This feature only works with the `jimeng-4.0` model. Other models (jimeng-3.0, nanobanana, etc.) will ignore the `--intelligent-ratio` flag.
159
 
160
  Use `--intelligent-ratio` to automatically select the best aspect ratio based on prompt keywords.
161
 
@@ -276,9 +276,9 @@ Script executes:
276
  - If you need full control over resolution and ratio, use `jimeng-4.0` model instead
277
 
278
  **"intelligent_ratio not working"**
279
- - The `--intelligent-ratio` flag only works with `jimeng-4.0` model
280
  - Other models (jimeng-3.0, nanobanana, etc.) will ignore this parameter
281
- - Solution: Use `jimeng-4.0` if you need intelligent ratio detection
282
 
283
  ## Best Practices
284
 
 
107
  - `prompt` (required): Text description of the desired image
108
  - `--session-id`: Jimeng session ID (required)
109
  - `--model`: Model to use (default: `jimeng-4.0`)
110
+ - Options: `jimeng-4.5`, `jimeng-4.0`, `jimeng-3.1`, `jimeng-3.0`, `jimeng-2.1`, `jimeng-xl-pro`, `nanobanana` (international only)
111
  - `--ratio`: Aspect ratio (default: `1:1`)
112
  - Options: `1:1`, `4:3`, `3:4`, `16:9`, `9:16`, `3:2`, `2:3`, `21:9`
113
  - `--resolution`: Resolution level (default: `2k`)
114
  - Options: `1k`, `2k`, `4k`
115
+ - `--intelligent-ratio`: Enable smart ratio detection based on prompt keywords **⚠️ Only works for jimeng-4.0/jimeng-4.1/jimeng-4.5 models; other models will ignore this parameter**
116
  - `--negative-prompt`: Negative prompt (elements to avoid)
117
  - `--sample-strength`: Sampling strength (0.0-1.0)
118
  - `--api-url`: Custom API URL (default: `http://localhost:5100`)
 
155
 
156
  ### Intelligent Ratio Detection
157
 
158
+ **⚠️ IMPORTANT**: This feature only works with the `jimeng-4.0`, `jimeng-4.1`, and `jimeng-4.5` models. Other models (jimeng-3.0, nanobanana, etc.) will ignore the `--intelligent-ratio` flag.
159
 
160
  Use `--intelligent-ratio` to automatically select the best aspect ratio based on prompt keywords.
161
 
 
276
  - If you need full control over resolution and ratio, use `jimeng-4.0` model instead
277
 
278
  **"intelligent_ratio not working"**
279
+ - The `--intelligent-ratio` flag only works with `jimeng-4.0`, `jimeng-4.1`, and `jimeng-4.5` models
280
  - Other models (jimeng-3.0, nanobanana, etc.) will ignore this parameter
281
+ - Solution: Use `jimeng-4.0`, `jimeng-4.1`, or `jimeng-4.5` if you need intelligent ratio detection
282
 
283
  ## Best Practices
284
 
jimeng-api/scripts/generate_image.py CHANGED
@@ -352,8 +352,8 @@ def main():
352
  "--model",
353
  type=str,
354
  default="jimeng-4.0",
355
- choices=["jimeng-4.0", "jimeng-3.1", "jimeng-3.0", "jimeng-2.1", "jimeng-xl-pro", "nanobanana"],
356
- help="Model to use (default: jimeng-4.0)"
357
  )
358
  subparser.add_argument(
359
  "--ratio",
 
352
  "--model",
353
  type=str,
354
  default="jimeng-4.0",
355
+ choices=["jimeng-4.5", "jimeng-4.0", "jimeng-3.1", "jimeng-3.0", "jimeng-2.1", "jimeng-xl-pro", "nanobanana"],
356
+ help="Model to use (default: jimeng-4.0; jimeng-4.5 is domestic only and supports intelligent ratio)"
357
  )
358
  subparser.add_argument(
359
  "--ratio",
src/api/builders/payload-builder.ts CHANGED
@@ -144,7 +144,7 @@ export interface BuildCoreParamOptions {
144
  * 构建 core_param
145
  * - 图生图: image_ratio 始终保留,prompt 前缀为 ## * imageCount
146
  * - 文生图: intelligent_ratio=true 时移除 image_ratio
147
- * - intelligent_ratio 仅对 jimeng-4.0/jimeng-4.1 模型有效,其他模型忽略此参数
148
  */
149
  export function buildCoreParam(options: BuildCoreParamOptions) {
150
  const {
@@ -160,8 +160,8 @@ export function buildCoreParam(options: BuildCoreParamOptions) {
160
  mode = "text2img",
161
  } = options;
162
 
163
- // ⚠️ intelligent_ratio 仅对 jimeng-4.0/jimeng-4.1 模型有效
164
- const effectiveIntelligentRatio = ['jimeng-4.0', 'jimeng-4.1'].includes(userModel) ? intelligentRatio : false;
165
 
166
  // 图生图时,prompt 前缀规则: 每张图片对应 2 个 #
167
  // 1张图 → ##, 2张图 → ####, 3张图 → ######
@@ -176,6 +176,7 @@ export function buildCoreParam(options: BuildCoreParamOptions) {
176
  large_image_info: {
177
  type: "",
178
  id: util.uuid(),
 
179
  height: resolution.height,
180
  width: resolution.width,
181
  resolution_type: resolution.resolutionType,
 
144
  * 构建 core_param
145
  * - 图生图: image_ratio 始终保留,prompt 前缀为 ## * imageCount
146
  * - 文生图: intelligent_ratio=true 时移除 image_ratio
147
+ * - intelligent_ratio 仅对 jimeng-4.0/jimeng-4.1/jimeng-4.5 模型有效,其他模型忽略此参数
148
  */
149
  export function buildCoreParam(options: BuildCoreParamOptions) {
150
  const {
 
160
  mode = "text2img",
161
  } = options;
162
 
163
+ // ⚠️ intelligent_ratio 仅对 jimeng-4.0/jimeng-4.1/jimeng-4.5 模型有效
164
+ const effectiveIntelligentRatio = ['jimeng-4.0', 'jimeng-4.1', 'jimeng-4.5'].includes(userModel) ? intelligentRatio : false;
165
 
166
  // 图生图时,prompt 前缀规则: 每张图片对应 2 个 #
167
  // 1张图 → ##, 2张图 → ####, 3张图 → ######
 
176
  large_image_info: {
177
  type: "",
178
  id: util.uuid(),
179
+ min_version: DRAFT_MIN_VERSION,
180
  height: resolution.height,
181
  width: resolution.width,
182
  resolution_type: resolution.resolutionType,
src/api/consts/common.ts CHANGED
@@ -30,7 +30,8 @@ export const PLATFORM_CODE = "7";
30
  export const VERSION_CODE = "5.8.0";
31
 
32
  // 默认模型
33
- export const DEFAULT_IMAGE_MODEL = "jimeng-4.1";
 
34
  export const DEFAULT_VIDEO_MODEL = "jimeng-video-3.0";
35
 
36
  // 草稿版本
@@ -39,6 +40,7 @@ export const DRAFT_MIN_VERSION = "3.0.2";
39
 
40
  // 图像模型映射
41
  export const IMAGE_MODEL_MAP = {
 
42
  "jimeng-4.1": "high_aes_general_v41",
43
  "jimeng-4.0": "high_aes_general_v40",
44
  "jimeng-3.1": "high_aes_general_v30l_art_fangzhou:general_v3.0_18b",
 
30
  export const VERSION_CODE = "5.8.0";
31
 
32
  // 默认模型
33
+ export const DEFAULT_IMAGE_MODEL = "jimeng-4.5";
34
+ export const DEFAULT_IMAGE_MODEL_US = "jimeng-4.0";
35
  export const DEFAULT_VIDEO_MODEL = "jimeng-video-3.0";
36
 
37
  // 草稿版本
 
40
 
41
  // 图像模型映射
42
  export const IMAGE_MODEL_MAP = {
43
+ "jimeng-4.5": "high_aes_general_v40l",
44
  "jimeng-4.1": "high_aes_general_v41",
45
  "jimeng-4.0": "high_aes_general_v40",
46
  "jimeng-3.1": "high_aes_general_v30l_art_fangzhou:general_v3.0_18b",
src/api/controllers/images.ts CHANGED
@@ -6,7 +6,7 @@ import util from "@/lib/util.ts";
6
  import { getCredit, receiveCredit, request, parseRegionFromToken, getAssistantId, RegionInfo } from "./core.ts";
7
  import logger from "@/lib/logger.ts";
8
  import { SmartPoller, PollingStatus } from "@/lib/smart-poller.ts";
9
- import { DEFAULT_IMAGE_MODEL, IMAGE_MODEL_MAP, IMAGE_MODEL_MAP_US } from "@/api/consts/common.ts";
10
  import { uploadImageFromUrl, uploadImageBuffer } from "@/lib/image-uploader.ts";
11
  import { extractImageUrls } from "@/lib/image-utils.ts";
12
  import {
@@ -22,26 +22,43 @@ import {
22
  } from "@/api/builders/payload-builder.ts";
23
 
24
  export const DEFAULT_MODEL = DEFAULT_IMAGE_MODEL;
 
 
 
 
 
 
25
 
26
  /**
27
  * 获取模型映射
 
 
28
  */
29
- export function getModel(model: string, isInternational: boolean) {
30
  const modelMap = isInternational ? IMAGE_MODEL_MAP_US : IMAGE_MODEL_MAP;
 
 
31
  if (isInternational && !modelMap[model]) {
 
 
 
 
 
32
  const supportedModels = Object.keys(modelMap).join(', ');
33
  throw new Error(`国际版不支持模型 "${model}"。支持的模型: ${supportedModels}`);
34
  }
35
- return modelMap[model] || modelMap[DEFAULT_MODEL];
 
 
36
  }
37
 
38
  /**
39
  * 记录分辨率信息
40
  */
41
- function logResolutionInfo(_model: string, resolution: ResolutionResult, regionInfo: RegionInfo) {
42
  if (!resolution.isForced) return;
43
 
44
- if (_model === 'nanobanana') {
45
  if (regionInfo.isUS) {
46
  logger.warn('美区 nanobanana 模型固定使用1024x1024分辨率和2k的清晰度,比例固定为1:1。');
47
  } else if (regionInfo.isHK || regionInfo.isJP || regionInfo.isSG) {
@@ -74,14 +91,14 @@ export async function generateImageComposition(
74
  refreshToken: string
75
  ) {
76
  const regionInfo = parseRegionFromToken(refreshToken);
77
- const model = getModel(_model, regionInfo.isInternational);
78
 
79
  // 使用 payload-builder 处理分辨率
80
- const resolutionResult = resolveResolution(_model, regionInfo, resolution, ratio);
81
- logResolutionInfo(_model, resolutionResult, regionInfo);
82
 
83
  const imageCount = images.length;
84
- logger.info(`使用模型: ${_model} 映射模型: ${model} 图生图功能 ${imageCount}张图片 ${resolutionResult.width}x${resolutionResult.height} 精细度: ${sampleStrength}`);
85
 
86
  // 获取积分
87
  try {
@@ -120,7 +137,7 @@ export async function generateImageComposition(
120
 
121
  // 使用 payload-builder 构建 core_param
122
  const coreParam = buildCoreParam({
123
- userModel: _model,
124
  model,
125
  prompt,
126
  imageCount,
@@ -141,7 +158,7 @@ export async function generateImageComposition(
141
 
142
  // 使用 payload-builder 构建 metrics_extra
143
  const metricsExtra = buildMetricsExtra({
144
- userModel: _model,
145
  regionInfo,
146
  submitId,
147
  scene: "ImageBasicGenerate",
@@ -272,10 +289,10 @@ export async function generateImages(
272
  refreshToken: string
273
  ) {
274
  const regionInfo = parseRegionFromToken(refreshToken);
275
- const model = getModel(_model, regionInfo.isInternational);
276
- logger.info(`使用模型: ${_model} 映射模型: ${model} 分辨率: ${resolution} 比例: ${ratio} 精细度: ${sampleStrength} 智能比例: ${intelligentRatio}`);
277
 
278
- return await generateImagesInternal(_model, prompt, { ratio, resolution, sampleStrength, negativePrompt, intelligentRatio }, refreshToken);
279
  }
280
 
281
  /**
@@ -300,11 +317,11 @@ async function generateImagesInternal(
300
  refreshToken: string
301
  ) {
302
  const regionInfo = parseRegionFromToken(refreshToken);
303
- const model = getModel(_model, regionInfo.isInternational);
304
 
305
  // 使用 payload-builder 处理分辨率
306
- const resolutionResult = resolveResolution(_model, regionInfo, resolution, ratio);
307
- logResolutionInfo(_model, resolutionResult, regionInfo);
308
 
309
  // 获取积分
310
  const { totalCredit, giftCredit, purchaseCredit, vipCredit } = await getCredit(refreshToken);
@@ -313,8 +330,8 @@ async function generateImagesInternal(
313
 
314
  logger.info(`当前积分状态: 总计=${totalCredit}, 赠送=${giftCredit}, 购买=${purchaseCredit}, VIP=${vipCredit}`);
315
 
316
- // 检查是否为多图生成模式 (jimeng-4.0/jimeng-4.1 支持)
317
- const isJimeng4xMultiImage = ['jimeng-4.0', 'jimeng-4.1'].includes(_model) && (
318
  prompt.includes("连续") ||
319
  prompt.includes("绘本") ||
320
  prompt.includes("故事") ||
@@ -322,7 +339,7 @@ async function generateImagesInternal(
322
  );
323
 
324
  if (isJimeng4xMultiImage) {
325
- return await generateJimeng4xMultiImages(_model, prompt, { ratio, resolution, sampleStrength, negativePrompt, intelligentRatio }, refreshToken);
326
  }
327
 
328
  const componentId = util.uuid();
@@ -330,7 +347,7 @@ async function generateImagesInternal(
330
 
331
  // 使用 payload-builder 构建 core_param
332
  const coreParam = buildCoreParam({
333
- userModel: _model,
334
  model,
335
  prompt,
336
  negativePrompt,
@@ -343,7 +360,7 @@ async function generateImagesInternal(
343
 
344
  // 使用 payload-builder 构建 metrics_extra
345
  const metricsExtra = buildMetricsExtra({
346
- userModel: _model,
347
  regionInfo,
348
  submitId,
349
  scene: "ImageBasicGenerate",
@@ -442,7 +459,7 @@ async function generateImagesInternal(
442
  }
443
 
444
  /**
445
- * jimeng-4.0/jimeng-4.1 多图生成
446
  */
447
  async function generateJimeng4xMultiImages(
448
  _model: string,
@@ -463,10 +480,10 @@ async function generateJimeng4xMultiImages(
463
  refreshToken: string
464
  ) {
465
  const regionInfo = parseRegionFromToken(refreshToken);
466
- const model = getModel(_model, regionInfo.isInternational);
467
 
468
  // 使用 payload-builder 处理分辨率
469
- const resolutionResult = resolveResolution(_model, regionInfo, resolution, ratio);
470
 
471
  const targetImageCount = prompt.match(/(\d+)张/) ? parseInt(prompt.match(/(\d+)张/)[1]) : 4;
472
 
@@ -477,7 +494,7 @@ async function generateJimeng4xMultiImages(
477
 
478
  // 使用 payload-builder 构建 core_param
479
  const coreParam = buildCoreParam({
480
- userModel: _model,
481
  model,
482
  prompt,
483
  negativePrompt,
@@ -490,7 +507,7 @@ async function generateJimeng4xMultiImages(
490
 
491
  // 使用 payload-builder 构建 metrics_extra (多图模式)
492
  const metricsExtra = buildMetricsExtra({
493
- userModel: _model,
494
  regionInfo,
495
  submitId,
496
  scene: "ImageMultiGenerate",
 
6
  import { getCredit, receiveCredit, request, parseRegionFromToken, getAssistantId, RegionInfo } from "./core.ts";
7
  import logger from "@/lib/logger.ts";
8
  import { SmartPoller, PollingStatus } from "@/lib/smart-poller.ts";
9
+ import { DEFAULT_IMAGE_MODEL, DEFAULT_IMAGE_MODEL_US, IMAGE_MODEL_MAP, IMAGE_MODEL_MAP_US } from "@/api/consts/common.ts";
10
  import { uploadImageFromUrl, uploadImageBuffer } from "@/lib/image-uploader.ts";
11
  import { extractImageUrls } from "@/lib/image-utils.ts";
12
  import {
 
22
  } from "@/api/builders/payload-builder.ts";
23
 
24
  export const DEFAULT_MODEL = DEFAULT_IMAGE_MODEL;
25
+ export const DEFAULT_MODEL_US = DEFAULT_IMAGE_MODEL_US;
26
+
27
+ export interface ModelResult {
28
+ model: string;
29
+ userModel: string;
30
+ }
31
 
32
  /**
33
  * 获取模型映射
34
+ * - 国际站不支持的模型会抛出错误
35
+ * - 但如果传入的是国内站默认模型,国际站会自动回退到国际站默认模型
36
  */
37
+ export function getModel(model: string, isInternational: boolean): ModelResult {
38
  const modelMap = isInternational ? IMAGE_MODEL_MAP_US : IMAGE_MODEL_MAP;
39
+ const defaultModel = isInternational ? DEFAULT_MODEL_US : DEFAULT_MODEL;
40
+
41
  if (isInternational && !modelMap[model]) {
42
+ // 如果传入的是国内站默认模型,回退到国际站默认模型
43
+ if (model === DEFAULT_MODEL) {
44
+ logger.info(`国际站不支持默认模型 "${model}",回退到 "${defaultModel}"`);
45
+ return { model: modelMap[defaultModel], userModel: defaultModel };
46
+ }
47
  const supportedModels = Object.keys(modelMap).join(', ');
48
  throw new Error(`国际版不支持模型 "${model}"。支持的模型: ${supportedModels}`);
49
  }
50
+
51
+ const effectiveUserModel = modelMap[model] ? model : defaultModel;
52
+ return { model: modelMap[effectiveUserModel], userModel: effectiveUserModel };
53
  }
54
 
55
  /**
56
  * 记录分辨率信息
57
  */
58
+ function logResolutionInfo(userModel: string, resolution: ResolutionResult, regionInfo: RegionInfo) {
59
  if (!resolution.isForced) return;
60
 
61
+ if (userModel === 'nanobanana') {
62
  if (regionInfo.isUS) {
63
  logger.warn('美区 nanobanana 模型固定使用1024x1024分辨率和2k的清晰度,比例固定为1:1。');
64
  } else if (regionInfo.isHK || regionInfo.isJP || regionInfo.isSG) {
 
91
  refreshToken: string
92
  ) {
93
  const regionInfo = parseRegionFromToken(refreshToken);
94
+ const { model, userModel } = getModel(_model, regionInfo.isInternational);
95
 
96
  // 使用 payload-builder 处理分辨率
97
+ const resolutionResult = resolveResolution(userModel, regionInfo, resolution, ratio);
98
+ logResolutionInfo(userModel, resolutionResult, regionInfo);
99
 
100
  const imageCount = images.length;
101
+ logger.info(`使用模型: ${userModel} 映射模型: ${model} 图生图功能 ${imageCount}张图片 ${resolutionResult.width}x${resolutionResult.height} 精细度: ${sampleStrength}`);
102
 
103
  // 获取积分
104
  try {
 
137
 
138
  // 使用 payload-builder 构建 core_param
139
  const coreParam = buildCoreParam({
140
+ userModel,
141
  model,
142
  prompt,
143
  imageCount,
 
158
 
159
  // 使用 payload-builder 构建 metrics_extra
160
  const metricsExtra = buildMetricsExtra({
161
+ userModel,
162
  regionInfo,
163
  submitId,
164
  scene: "ImageBasicGenerate",
 
289
  refreshToken: string
290
  ) {
291
  const regionInfo = parseRegionFromToken(refreshToken);
292
+ const { model, userModel } = getModel(_model, regionInfo.isInternational);
293
+ logger.info(`使用模型: ${userModel} 映射模型: ${model} 分辨率: ${resolution} 比例: ${ratio} 精细度: ${sampleStrength} 智能比例: ${intelligentRatio}`);
294
 
295
+ return await generateImagesInternal(userModel, prompt, { ratio, resolution, sampleStrength, negativePrompt, intelligentRatio }, refreshToken);
296
  }
297
 
298
  /**
 
317
  refreshToken: string
318
  ) {
319
  const regionInfo = parseRegionFromToken(refreshToken);
320
+ const { model, userModel } = getModel(_model, regionInfo.isInternational);
321
 
322
  // 使用 payload-builder 处理分辨率
323
+ const resolutionResult = resolveResolution(userModel, regionInfo, resolution, ratio);
324
+ logResolutionInfo(userModel, resolutionResult, regionInfo);
325
 
326
  // 获取积分
327
  const { totalCredit, giftCredit, purchaseCredit, vipCredit } = await getCredit(refreshToken);
 
330
 
331
  logger.info(`当前积分状态: 总计=${totalCredit}, 赠送=${giftCredit}, 购买=${purchaseCredit}, VIP=${vipCredit}`);
332
 
333
+ // 检查是否为多图生成模式 (jimeng-4.0/jimeng-4.1/jimeng-4.5 支持)
334
+ const isJimeng4xMultiImage = ['jimeng-4.0', 'jimeng-4.1', 'jimeng-4.5'].includes(userModel) && (
335
  prompt.includes("连续") ||
336
  prompt.includes("绘本") ||
337
  prompt.includes("故事") ||
 
339
  );
340
 
341
  if (isJimeng4xMultiImage) {
342
+ return await generateJimeng4xMultiImages(userModel, prompt, { ratio, resolution, sampleStrength, negativePrompt, intelligentRatio }, refreshToken);
343
  }
344
 
345
  const componentId = util.uuid();
 
347
 
348
  // 使用 payload-builder 构建 core_param
349
  const coreParam = buildCoreParam({
350
+ userModel,
351
  model,
352
  prompt,
353
  negativePrompt,
 
360
 
361
  // 使用 payload-builder 构建 metrics_extra
362
  const metricsExtra = buildMetricsExtra({
363
+ userModel,
364
  regionInfo,
365
  submitId,
366
  scene: "ImageBasicGenerate",
 
459
  }
460
 
461
  /**
462
+ * jimeng-4.0/jimeng-4.1/jimeng-4.5 多图生成
463
  */
464
  async function generateJimeng4xMultiImages(
465
  _model: string,
 
480
  refreshToken: string
481
  ) {
482
  const regionInfo = parseRegionFromToken(refreshToken);
483
+ const { model, userModel } = getModel(_model, regionInfo.isInternational);
484
 
485
  // 使用 payload-builder 处理分辨率
486
+ const resolutionResult = resolveResolution(userModel, regionInfo, resolution, ratio);
487
 
488
  const targetImageCount = prompt.match(/(\d+)张/) ? parseInt(prompt.match(/(\d+)张/)[1]) : 4;
489
 
 
494
 
495
  // 使用 payload-builder 构建 core_param
496
  const coreParam = buildCoreParam({
497
+ userModel,
498
  model,
499
  prompt,
500
  negativePrompt,
 
507
 
508
  // 使用 payload-builder 构建 metrics_extra (多图模式)
509
  const metricsExtra = buildMetricsExtra({
510
+ userModel,
511
  regionInfo,
512
  submitId,
513
  scene: "ImageMultiGenerate",