Merge branch 'dev'

This commit is contained in:
jonathang4 2025-12-13 14:35:29 +08:00
commit 640e098714
6 changed files with 587 additions and 171 deletions

View File

@ -256,6 +256,7 @@ export async function uploadFile(
*/ */
export function checkResult(result: AxiosResponse) { export function checkResult(result: AxiosResponse) {
const { ret, errmsg, data } = result.data; const { ret, errmsg, data } = result.data;
console.log("检查请求结果", { ret, errmsg } );
if (!_.isFinite(Number(ret))) return result.data; if (!_.isFinite(Number(ret))) return result.data;
if (ret !== '0') { if (ret !== '0') {
logger.error(`[Jimeng API Error] ret=${ret}, errmsg=${errmsg}, data=${JSON.stringify(data)}`); logger.error(`[Jimeng API Error] ret=${ret}, errmsg=${errmsg}, data=${JSON.stringify(data)}`);
@ -296,3 +297,339 @@ export async function getTokenLiveStatus(refreshToken: string) {
return false; return false;
} }
} }
export function image3Options(
model,
componentId,
prompt,
sampleStrength,
height,
width,
negativePrompt = '',
resolutionType = "1k",
generateCount = 4
){
const min_version = "3.0.2"
const version = "3.0.2"
return {
params: {
babi_param: encodeURIComponent(
JSON.stringify({
scenario: "image_video_generation",
feature_key: "aigc_to_image",
feature_entrance: "to_image",
feature_entrance_detail: "to_image-" + model,
})
),
},
data: {
extend: {
root_model: model,
template_id: "",
},
submit_id: util.uuid(),
metrics_extra: JSON.stringify({
templateId: "",
generateCount: generateCount,
promptSource: "custom",
templateSource: "",
lastRequestId: "",
originRequestId: "",
}),
draft_content: JSON.stringify({
type: "draft",
id: util.uuid(),
min_version: min_version,
is_from_tsn: true,
version: version,
main_component_id: componentId,
component_list: [
{
type: "image_base_component",
id: componentId,
min_version: min_version,
generate_type: "generate",
aigc_mode: "workbench",
abilities: {
type: "",
id: util.uuid(),
generate: {
type: "",
id: util.uuid(),
core_param: {
type: "",
id: util.uuid(),
model,
prompt:prompt,
negative_prompt: negativePrompt,
seed: Math.floor(Math.random() * 100000000) + 2500000000,
sample_strength: sampleStrength,
image_ratio: 1,
large_image_info: {
type: "",
id: util.uuid(),
height,
width,
resolution_type: resolutionType,
},
},
history_option: {
type: "",
id: util.uuid(),
},
},
},
},
],
}),
http_common_info: {
aid: Number(DEFAULT_ASSISTANT_ID),
},
},
}
}
export function image4Options_0302(
model,
componentId,
prompt,
sampleStrength,
height,
width,
negativePrompt = '',
resolutionType = "2k",
generateCount = 4
){
const min_version = "3.0.2"
const version = "3.0.2"
const submit_id = util.uuid()
return {
params: {
babi_param: encodeURIComponent(
JSON.stringify({
scenario: "image_video_generation",
feature_key: "aigc_to_image",
feature_entrance: "to_image",
feature_entrance_detail: "to_image-" + model,
})
),
},
data: {
extend: {
root_model: model,
},
submit_id: submit_id,
metrics_extra: JSON.stringify({
promptSource: "custom",
generateCount: generateCount,
enterFrom: "click",
sceneOptions:JSON.stringify([
{
"type": "image",
"scene": "ImageBasicGenerate",
"modelReqKey": model,
"resolutionType": resolutionType,
"abilityList": [],
"benefitCount": 4,
"reportParams": {
"enterSource": "generate",
"vipSource": "generate",
"extraVipFunctionKey": model+"-"+resolutionType,
"useVipFunctionDetailsReporterHoc": true
}
}
]),
isBoxSelect: false,
isCutout: false,
generateId: submit_id,
isRegenerate: false
}),
draft_content: JSON.stringify({
type: "draft",
id: util.uuid(),
min_version: min_version,
is_from_tsn: true,
version: version,
main_component_id: componentId,
component_list: [
{
type: "image_base_component",
id: componentId,
min_version: min_version,
generate_type: "generate",
aigc_mode: "workbench",
metadata: {
"type": "",
"id": util.uuid(),
"created_platform": 3,
"created_platform_version": "",
"created_time_in_ms": Math.floor(Date.now()/1000),
"created_did": ""
},
abilities: {
type: "",
id: util.uuid(),
generate: {
type: "",
id: util.uuid(),
core_param: {
type: "",
id: util.uuid(),
model,
prompt,
negative_prompt: negativePrompt,
seed: Math.floor(Math.random() * 100000000) + 2500000000,
sample_strength: sampleStrength,
image_ratio: 5,
large_image_info: {
type: "",
id: util.uuid(),
height,
width,
resolution_type: resolutionType,
},
intelligent_ratio: false
},
},
gen_option: {
"type": "",
"id": util.uuid(),
"gen_count": generateCount,
"generate_all": false
}
},
},
],
}),
http_common_info: {
aid: Number(DEFAULT_ASSISTANT_ID),
},
},
}
}
export function image4Options_0337(
model,
componentId,
prompt,
sampleStrength,
height,
width,
negativePrompt = '',
resolutionType = "2k",
generateCount = 4
){
const min_version = "3.0.2"
const version = "3.3.7"
const submit_id = util.uuid()
return {
params: {
da_version: version,
web_component_open_flag:1,
web_version:'7.5.0',
aigc_features:'app_lip_sync',
babi_param: encodeURIComponent(
JSON.stringify({
scenario: "image_video_generation",
feature_key: "aigc_to_image",
feature_entrance: "to_image",
feature_entrance_detail: "to_image-" + model,
})
),
},
data: {
extend: {
root_model: model,
},
submit_id: submit_id,
metrics_extra: JSON.stringify({
promptSource: "custom",
generateCount: generateCount,
enterFrom: "click",
sceneOptions:JSON.stringify([
{
"type": "image",
"scene": "ImageBasicGenerate",
"modelReqKey": model,
"resolutionType": resolutionType,
"abilityList": [],
"benefitCount": 4,
"reportParams": {
"enterSource": "generate",
"vipSource": "generate",
"extraVipFunctionKey": model+"-"+resolutionType,
"useVipFunctionDetailsReporterHoc": true
}
}
]),
isBoxSelect: false,
isCutout: false,
generateId: submit_id,
isRegenerate: false
}),
draft_content: JSON.stringify({
type: "draft",
id: util.uuid(),
min_version: min_version,
is_from_tsn: true,
version: version,
main_component_id: componentId,
component_list: [
{
type: "image_base_component",
id: componentId,
min_version: min_version,
generate_type: "generate",
aigc_mode: "workbench",
metadata: {
"type": "",
"id": util.uuid(),
"created_platform": 3,
"created_platform_version": "",
"created_time_in_ms": Math.floor(Date.now()/1000),
"created_did": ""
},
abilities: {
type: "",
id: util.uuid(),
generate: {
type: "",
id: util.uuid(),
core_param: {
type: "",
id: util.uuid(),
model,
prompt,
negative_prompt: negativePrompt,
seed: Math.floor(Math.random() * 100000000) + 2500000000,
sample_strength: sampleStrength,
image_ratio: 5,
large_image_info: {
type: "",
id: util.uuid(),
height,
width,
resolution_type: resolutionType,
},
intelligent_ratio: false
},
},
gen_option: {
"type": "",
"id": util.uuid(),
"gen_count": generateCount,
"generate_all": false
}
},
},
],
}),
http_common_info: {
aid: Number(DEFAULT_ASSISTANT_ID),
},
},
}
}

View File

@ -3,7 +3,7 @@ import _ from "lodash";
import APIException from "@/lib/exceptions/APIException.ts"; import APIException from "@/lib/exceptions/APIException.ts";
import EX from "@/api/consts/exceptions.ts"; import EX from "@/api/consts/exceptions.ts";
import util from "@/lib/util.ts"; import util from "@/lib/util.ts";
import { getCredit, receiveCredit, request } from "./core.ts"; import { getCredit, receiveCredit, request, image3Options, image4Options_0302 } from "./core.ts";
import logger from "@/lib/logger.ts"; import logger from "@/lib/logger.ts";
import { ImagesTaskCache } from '@/api/ImagesTaskCache.ts'; import { ImagesTaskCache } from '@/api/ImagesTaskCache.ts';
@ -36,11 +36,13 @@ export async function generateImages(
height = 1024, height = 1024,
sampleStrength = 0.5, sampleStrength = 0.5,
negativePrompt = "", negativePrompt = "",
generateCount = 4,
}: { }: {
width?: number; width?: number;
height?: number; height?: number;
sampleStrength?: number; sampleStrength?: number;
negativePrompt?: string; negativePrompt?: string;
generateCount?: number;
}, },
refreshToken: string refreshToken: string
) { ) {
@ -60,86 +62,114 @@ export async function generateImages(
await receiveCredit(refreshToken); await receiveCredit(refreshToken);
const componentId = util.uuid(); const componentId = util.uuid();
let isModel4 = model.startsWith("jimeng-4");
let options = {};
if(isModel4){
options = image4Options_0302(
model,
componentId,
prompt,
sampleStrength,
height,
width,
negativePrompt,
'2k',
generateCount,
);
}else{
options = image3Options(
model,
componentId,
prompt,
sampleStrength,
height,
width,
negativePrompt,
'1k',
generateCount,
);
}
const { aigc_data } = await request( const { aigc_data } = await request(
"post", "post",
"/mweb/v1/aigc_draft/generate", "/mweb/v1/aigc_draft/generate",
refreshToken, refreshToken,
{ options,
params: { // {
babi_param: encodeURIComponent( // params: {
JSON.stringify({ // babi_param: encodeURIComponent(
scenario: "image_video_generation", // JSON.stringify({
feature_key: "aigc_to_image", // scenario: "image_video_generation",
feature_entrance: "to_image", // feature_key: "aigc_to_image",
feature_entrance_detail: "to_image-" + model, // feature_entrance: "to_image",
}) // feature_entrance_detail: "to_image-" + model,
), // })
}, // ),
data: { // },
extend: { // data: {
root_model: model, // extend: {
template_id: "", // root_model: model,
}, // template_id: "",
submit_id: util.uuid(), // },
metrics_extra: JSON.stringify({ // submit_id: util.uuid(),
templateId: "", // metrics_extra: JSON.stringify({
generateCount: 1, // templateId: "",
promptSource: "custom", // generateCount: 1,
templateSource: "", // promptSource: "custom",
lastRequestId: "", // templateSource: "",
originRequestId: "", // lastRequestId: "",
}), // originRequestId: "",
draft_content: JSON.stringify({ // }),
type: "draft", // draft_content: JSON.stringify({
id: util.uuid(), // type: "draft",
min_version: DRAFT_VERSION, // id: util.uuid(),
is_from_tsn: true, // min_version: DRAFT_VERSION,
version: currentVersion, // is_from_tsn: true,
main_component_id: componentId, // version: DRAFT_VERSION,
component_list: [ // main_component_id: componentId,
{ // component_list: [
type: "image_base_component", // {
id: componentId, // type: "image_base_component",
min_version: DRAFT_VERSION, // id: componentId,
generate_type: "generate", // min_version: DRAFT_VERSION,
aigc_mode: "workbench", // generate_type: "generate",
abilities: { // aigc_mode: "workbench",
type: "", // abilities: {
id: util.uuid(), // type: "",
generate: { // id: util.uuid(),
type: "", // generate: {
id: util.uuid(), // type: "",
core_param: { // id: util.uuid(),
type: "", // core_param: {
id: util.uuid(), // type: "",
model, // id: util.uuid(),
prompt, // model,
negative_prompt: negativePrompt, // prompt,
seed: Math.floor(Math.random() * 100000000) + 2500000000, // negative_prompt: negativePrompt,
sample_strength: sampleStrength, // seed: Math.floor(Math.random() * 100000000) + 2500000000,
image_ratio: 1, // sample_strength: sampleStrength,
large_image_info: { // image_ratio: 1,
type: "", // large_image_info: {
id: util.uuid(), // type: "",
height, // id: util.uuid(),
width, // height,
resolution_type: resolutionType, // width,
}, // resolution_type: "1k",
}, // },
history_option: { // },
type: "", // history_option: {
id: util.uuid(), // type: "",
}, // id: util.uuid(),
}, // },
}, // },
}, // },
], // },
}), // ],
http_common_info: { // }),
aid: Number(DEFAULT_ASSISTANT_ID), // http_common_info: {
}, // aid: Number(DEFAULT_ASSISTANT_ID),
}, // },
} // },
// }
); );
const historyId = aigc_data.history_record_id; const historyId = aigc_data.history_record_id;
if (!historyId) if (!historyId)

View File

@ -4,6 +4,7 @@ import Request from "@/lib/request/Request.ts";
import { generateImages } from "@/api/controllers/images.ts"; import { generateImages } from "@/api/controllers/images.ts";
import { tokenSplit } from "@/api/controllers/core.ts"; import { tokenSplit } from "@/api/controllers/core.ts";
import util from "@/lib/util.ts"; import util from "@/lib/util.ts";
import logger from "@/lib/logger.ts";
import { ImagesTaskCache } from '@/api/ImagesTaskCache.ts'; import { ImagesTaskCache } from '@/api/ImagesTaskCache.ts';
import DatabaseGenerationService from '@/lib/services/DatabaseGenerationService.js'; import DatabaseGenerationService from '@/lib/services/DatabaseGenerationService.js';
@ -65,9 +66,10 @@ export default {
.validate("body.task_id", _.isString) .validate("body.task_id", _.isString)
.validate("body.prompt", _.isString) .validate("body.prompt", _.isString)
// .validate("body.negative_prompt", v => _.isUndefined(v) || _.isString(v)) // .validate("body.negative_prompt", v => _.isUndefined(v) || _.isString(v))
.validate("body.width", v => _.isUndefined(v) || _.isFinite(v) || _.isString(v)) .validate("body.width", v => _.isUndefined(v) || _.isFinite(v))
.validate("body.height", v => _.isUndefined(v) || _.isFinite(v) || _.isString(v)) .validate("body.height", v => _.isUndefined(v) || _.isFinite(v))
// .validate("body.sample_strength", v => _.isUndefined(v) || _.isFinite(v)) .validate("body.sample_strength", v => _.isUndefined(v) || _.isFinite(v))
.validate("body.generate_count", v => _.isUndefined(v) || _.isFinite(v))
.validate("body.response_format", v => _.isUndefined(v) || _.isString(v)) .validate("body.response_format", v => _.isUndefined(v) || _.isString(v))
.validate("headers.authorization", _.isString); .validate("headers.authorization", _.isString);
// refresh_token切分 // refresh_token切分
@ -81,27 +83,31 @@ export default {
// negative_prompt: negativePrompt, // negative_prompt: negativePrompt,
width, width,
height, height,
// sample_strength: sampleStrength, sample_strength,
generate_count,
response_format, response_format,
} = request.body; } = request.body;
const responseFormat = _.defaultTo(response_format, "url"); const responseFormat = _.defaultTo(response_format, "url");
logger.info(`\n发起图片生成: model: ${model}, task_id: ${task_id}, width: ${width}, height: ${height}, responseFormat: ${responseFormat}, sample_strength: ${sample_strength}, generate_count: ${generate_count}`);
if (USE_DATABASE_MODE) { if (USE_DATABASE_MODE) {
// 使用新的数据库方法 // 使用新的数据库方法
await DatabaseGenerationService.generateImagesV2(model||'jimeng-3.0', task_id, prompt, { await DatabaseGenerationService.generateImagesV2(model||'jimeng-3.0', task_id, prompt, {
width, width,
height, height,
sampleStrength: 0.5, sampleStrength: sample_strength || 0.5,
negativePrompt: "", negativePrompt: "",
response_format: responseFormat response_format: responseFormat,
generateCount: generate_count || 4,
}, token); }, token);
} else { } else {
// 使用原有方法(不等待结果) // 使用原有方法(不等待结果)
generateImages(model||'jimeng-3.0', task_id, prompt, { generateImages(model||'jimeng-3.0', task_id, prompt, {
width, width,
height, height,
sampleStrength: 0.5, sampleStrength: sample_strength || 0.5,
negativePrompt: "", negativePrompt: "",
generateCount: generate_count || 4,
}, token); }, token);
} }

View File

@ -23,6 +23,7 @@ export interface IGenerationTask {
duration?: number; // 时长(毫秒) duration?: number; // 时长(毫秒)
ratio?: string; // 比例 ratio?: string; // 比例
response_format?: string; // 响应格式 response_format?: string; // 响应格式
generate_count?: number; // 生成数量
}; };
// 生成过程中的内部参数 // 生成过程中的内部参数

View File

@ -45,6 +45,7 @@ export class DatabaseGenerationService {
sampleStrength?: number; sampleStrength?: number;
negativePrompt?: string; negativePrompt?: string;
response_format?: string; response_format?: string;
generateCount?: number;
}, },
refreshToken: string refreshToken: string
): Promise<void> { ): Promise<void> {
@ -74,7 +75,8 @@ export class DatabaseGenerationService {
height: params.height || 1024, height: params.height || 1024,
sample_strength: params.sampleStrength || 0.5, sample_strength: params.sampleStrength || 0.5,
negative_prompt: params.negativePrompt || "", negative_prompt: params.negativePrompt || "",
response_format: params.response_format response_format: params.response_format,
generate_count: params.generateCount || 4,
}, },
internal_params: { internal_params: {
refresh_token: refreshToken refresh_token: refreshToken

View File

@ -8,7 +8,7 @@ import logger from '@/lib/logger.js';
import TOSService from '@/lib/tos/tos-service.js'; import TOSService from '@/lib/tos/tos-service.js';
import { generateImages as originalGenerateImages } from '@/api/controllers/images.js'; import { generateImages as originalGenerateImages } from '@/api/controllers/images.js';
import { generateVideo as originalGenerateVideo } from '@/api/controllers/video.js'; import { generateVideo as originalGenerateVideo } from '@/api/controllers/video.js';
import { request } from '@/api/controllers/core.js'; import { request, image4Options_0302, image4Options_0337, image3Options } from '@/api/controllers/core.js';
import EX from "@/api/consts/exceptions.ts"; import EX from "@/api/consts/exceptions.ts";
const timeZone = 'Asia/Shanghai'; const timeZone = 'Asia/Shanghai';
@ -327,6 +327,7 @@ export class TaskPollingService {
} }
taskLog(`Starting task: ${task.task_id} (${task.task_type})`); taskLog(`Starting task: ${task.task_id} (${task.task_type})`);
// taskLog(`original_params: ${JSON.stringify(task.original_params)}`);
// 调用原有生成方法获取historyId // 调用原有生成方法获取historyId
let historyId: string; let historyId: string;
@ -397,7 +398,8 @@ export class TaskPollingService {
const { status, fail_code: failCode, item_list } = result[historyId]; const { status, fail_code: failCode, item_list } = result[historyId];
if (status === 20) { taskLog(`调用即梦API检查结果 ${task.task_id} [status${status} fail_code: ${failCode}]`);
if (status === 20 || status === 45) {
// 仍在生成中,更新下次轮询时间 // 仍在生成中,更新下次轮询时间
await GenerationTask.updateOne( await GenerationTask.updateOne(
{ task_id: task.task_id }, { task_id: task.task_id },
@ -766,7 +768,8 @@ export class TaskPollingService {
* API * API
*/ */
private async callImageGeneration(task: IGenerationTask): Promise<string> { private async callImageGeneration(task: IGenerationTask): Promise<string> {
const { model, prompt, width = 1024, height = 1024, sample_strength = 0.5, negative_prompt = "" } = task.original_params; const { model, prompt, width = 1024, height = 1024, sample_strength = 0.5,
negative_prompt = "", generate_count = 4 } = task.original_params;
const refreshToken = task.internal_params.refresh_token; const refreshToken = task.internal_params.refresh_token;
// 映射模型 // 映射模型
@ -792,89 +795,126 @@ export class TaskPollingService {
const componentId = this.generateUUID(); const componentId = this.generateUUID();
const submitId = this.generateUUID(); const submitId = this.generateUUID();
let isModel4 = model.startsWith("jimeng-4");
const { aigc_data } = await request( let options:any = image3Options(
mappedModel,
componentId,
prompt,
sample_strength,
height,
width,
negative_prompt,
'1k',
generate_count,
);
if(isModel4){
options = image4Options_0337(
mappedModel,
componentId,
prompt,
sample_strength,
height,
width,
negative_prompt,
'2k',
generate_count,
);
// options = image4Options_0302(
// mappedModel,
// componentId,
// prompt,
// sample_strength,
// height,
// width,
// negative_prompt,
// '2k',
// generate_count,
// );
}
taskLog(`生成图片 发起请求 isModel4 ${isModel4}`);
const res = await request(
"post", "post",
"/mweb/v1/aigc_draft/generate", "/mweb/v1/aigc_draft/generate",
refreshToken, refreshToken,
{ options,
params: { // {
babi_param: encodeURIComponent( // params: {
JSON.stringify({ // babi_param: encodeURIComponent(
scenario: "image_video_generation", // JSON.stringify({
feature_key: "aigc_to_image", // scenario: "image_video_generation",
feature_entrance: "to_image", // feature_key: "aigc_to_image",
feature_entrance_detail: "to_image-" + mappedModel, // feature_entrance: "to_image",
}) // feature_entrance_detail: "to_image-" + mappedModel,
), // })
}, // ),
data: { // },
extend: { // data: {
root_model: mappedModel, // extend: {
template_id: "", // root_model: mappedModel,
}, // template_id: "",
submit_id: submitId, // },
metrics_extra: JSON.stringify({ // submit_id: submitId,
templateId: "", // metrics_extra: JSON.stringify({
generateCount: 1, // templateId: "",
promptSource: "custom", // generateCount: 1,
templateSource: "", // promptSource: "custom",
lastRequestId: "", // templateSource: "",
originRequestId: "", // lastRequestId: "",
}), // originRequestId: "",
draft_content: JSON.stringify({ // }),
type: "draft", // draft_content: JSON.stringify({
id: this.generateUUID(), // type: "draft",
min_version: "3.0.2", // id: this.generateUUID(),
is_from_tsn: true, // min_version: "3.0.2",
version: currentVersion, // is_from_tsn: true,
main_component_id: componentId, // version: "3.0.2",
component_list: [ // main_component_id: componentId,
{ // component_list: [
type: "image_base_component", // {
id: componentId, // type: "image_base_component",
min_version: "3.0.2", // id: componentId,
generate_type: "generate", // min_version: "3.0.2",
aigc_mode: "workbench", // generate_type: "generate",
abilities: { // aigc_mode: "workbench",
type: "", // abilities: {
id: this.generateUUID(), // type: "",
generate: { // id: this.generateUUID(),
type: "", // generate: {
id: this.generateUUID(), // type: "",
core_param: { // id: this.generateUUID(),
type: "", // core_param: {
id: this.generateUUID(), // type: "",
model: mappedModel, // id: this.generateUUID(),
prompt, // model: mappedModel,
negative_prompt, // prompt,
seed: Math.floor(Math.random() * 100000000) + 2500000000, // negative_prompt,
sample_strength, // seed: Math.floor(Math.random() * 100000000) + 2500000000,
image_ratio: 1, // sample_strength,
large_image_info: { // image_ratio: 1,
type: "", // large_image_info: {
id: this.generateUUID(), // type: "",
height, // id: this.generateUUID(),
width, // height,
resolution_type: resolutionType, // width,
}, // resolution_type: "1k",
}, // },
history_option: { // },
type: "", // history_option: {
id: this.generateUUID(), // type: "",
}, // id: this.generateUUID(),
}, // },
}, // },
}, // },
], // },
}), // ],
http_common_info: { // }),
aid: Number(process.env.DEFAULT_ASSISTANT_ID || "513695"), // http_common_info: {
}, // aid: Number(process.env.DEFAULT_ASSISTANT_ID || "513695"),
}, // },
} // },
// }
); );
const { aigc_data } = res;
const historyId = aigc_data.history_record_id; const historyId = aigc_data.history_record_id;
if (!historyId) { if (!historyId) {
throw new Error('Failed to get history_record_id from image generation API'); throw new Error('Failed to get history_record_id from image generation API');