feat(imageProcessor): add image editing functionality and improve response structure for better processing.

This commit is contained in:
Jerry 2025-12-07 00:39:52 +08:00
parent f1215fc32e
commit 20eaf117f1

View File

@ -89,7 +89,6 @@ class ImageProcessor {
quality: config.quality || 'standard', quality: config.quality || 'standard',
style: config.style || 'vivid', style: config.style || 'vivid',
response_format: config.responseFormat || 'url', response_format: config.responseFormat || 'url',
user: config.user || undefined
}; };
const response = await axios.post( const response = await axios.post(
@ -145,21 +144,22 @@ class ImageProcessor {
const messages = [ const messages = [
{ {
role: 'system', role: 'system',
content: '请你根据用户的描述生成高质量且准确的图像,条件允许的情况下,请先思考用户的意图再生成图像,请直接返回图像url,不要任何其他内容' content: [
{type: 'text', text: '请你根据用户的描述生成高质量且准确的图像,条件允许的情况下,请先思考用户的意图再生成图像,请直接返回图像url,不要任何其他内容'}
]
}, },
{ {
role: 'user', role: 'user',
content: prompt content: [
{type: 'text', text: prompt}
]
} }
]; ];
const requestBody = { const requestBody = {
model: config.model || 'google/gemini-3-pro-image-preview', model: config.model || 'google/gemini-3-pro-image-preview',
messages: messages, messages: messages,
max_tokens: config.maxTokens || 4000,
temperature: config.temperature || 0.7, temperature: config.temperature || 0.7,
modalities: config.modalities || ['text', 'image'], modalities: config.modalities || ['text', 'image'],
size: config.size || '1024x1024',
response_format: config.responseFormat || 'url'
}; };
const response = await axios.post( const response = await axios.post(
@ -229,6 +229,117 @@ class ImageProcessor {
} }
} }
async editImage(prompt, sourceImageArr, config){
if(config.imageMode==='openai'){
return await this.editImageByOpenAI(prompt, sourceImageArr, config);
} else if(config.imageMode==='chat'){
return await this.editImageByChat(prompt, sourceImageArr, config);
} else {
return await this.editImageByChat(prompt, sourceImageArr, config);
}
}
/**
* 使用对话式接口编辑图像如gemini-3-pro-image-preview
* @param {string} prompt - 编辑描述
* @param {string} sourceImageArr - 源图像URL数组
* @param {Object} config - 配置对象
* @returns {Promise<Object>} 编辑结果
*/
async editImageByChat(prompt, sourceImageArr, config) {
try{
logger.info(`[crystelf-ai] 开始编辑图像: ${prompt}, 源图像数量: ${sourceImageArr.length}`);
if(!sourceImageArr||sourceImageArr.length===0){
return {
success: false,
error: '编辑图像需要提供源图像'
};
}
let messages = [];
messages.push({
role: 'system',
content: [
{type: 'text', text: '请你根据用户的描述编辑图像,条件允许的情况下,请先思考用户的意图再编辑图像,请直接返回图像url,不要任何其他内容'}
]
});
let userContent = [];
userContent.push({type: 'text', text: prompt});
sourceImageArr.forEach((img) => {
userContent.push({type: 'image_url', image_url: {url: img}});
});
messages.push({
role: 'user',
content: userContent
});
const requestBody = {
model: config.model || 'google/gemini-3-pro-image-preview',
messages: messages,
temperature: config.temperature || 0.7,
modalities: config.modalities || ['text', 'image'],
};
const response = await axios.post(
`${config.baseApi}/v1/chat/completions`,
requestBody,
{
headers: {
'Authorization': `Bearer ${config.apiKey}`,
'Content-Type': 'application/json'
},
timeout: config.timeout || 60000
}
);
if (response.data && response.data.choices && response.data.choices.length > 0) {
const choice = response.data.choices[0];
if (choice.message && choice.message.images && choice.message.images.length > 0) {
const imageData = choice.message.images[0];
const imageUrl = imageData.image_url ? imageData.image_url.url : null;
if (imageUrl) {
logger.info(`[crystelf-ai] 对话接口图像生成成功: ${imageUrl.substring(0, 50)}...`);
return {
success: true,
imageUrl: imageUrl,
description: prompt,
model: config.model || 'google/gemini-3-pro-image-preview',
rawResponse: response.data
};
}
}
if (choice.message && choice.message.content) {
const imageUrl = this.extractImageUrl(choice.message.content);
if (imageUrl) {
logger.info(`[crystelf-ai] 从响应内容中提取到图像URL: ${imageUrl}`);
return {
success: true,
imageUrl: imageUrl,
description: prompt,
model: config.model || 'google/gemini-3-pro-image-preview',
rawResponse: response.data
};
} else {
logger.info(`[crystelf-ai] 收到文本响应: ${choice.message.content}`);
return {
success: true,
response: choice.message.content,
description: prompt,
model: config.model || 'google/gemini-3-pro-image-preview',
rawResponse: response.data
};
}
}
}
} catch (err){
logger.error(`[crystelf-ai] 图像编辑失败: ${error.message}`);
return {
success: false,
error: `图像编辑失败: ${error.message}`
};
}
}
/** /**
* 编辑图像 - 使用OpenAI标准接口 * 编辑图像 - 使用OpenAI标准接口
* @param {string} prompt - 编辑描述 * @param {string} prompt - 编辑描述
@ -236,7 +347,7 @@ class ImageProcessor {
* @param {Object} config - 配置对象 * @param {Object} config - 配置对象
* @returns {Promise<Object>} 编辑结果 * @returns {Promise<Object>} 编辑结果
*/ */
async editImage(prompt, sourceImageArr, config) { async editImageByOpenAI(prompt, sourceImageArr, config) {
try { try {
logger.info(`[crystelf-ai] 开始编辑图像: ${prompt}, 源图像数量: ${sourceImageArr.length}`); logger.info(`[crystelf-ai] 开始编辑图像: ${prompt}, 源图像数量: ${sourceImageArr.length}`);