feat: integrate image_make with MindSpace assets
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import crypto from 'node:crypto';
|
||||
|
||||
const PURPOSES = {
|
||||
inline_image: { presetId: 'memind_square_illustration', filename: 'inline-image.webp' },
|
||||
hero: { presetId: 'memind_dark_hero', filename: 'hero.webp' },
|
||||
card_cover: { presetId: 'memind_card_cover', filename: 'card-cover.webp' },
|
||||
feed_cover: { presetId: 'memind_feed_cover_source', filename: 'feed-cover.webp' },
|
||||
};
|
||||
|
||||
export function createMindSpaceImageGenerationService({
|
||||
configService,
|
||||
assetService,
|
||||
imageMakeClient,
|
||||
logger = console,
|
||||
} = {}) {
|
||||
async function generate({
|
||||
userId,
|
||||
purpose,
|
||||
prompt,
|
||||
negativePrompt = '',
|
||||
consumerRef = '',
|
||||
idempotencyKey,
|
||||
} = {}) {
|
||||
const spec = PURPOSES[purpose];
|
||||
if (!spec) {
|
||||
return { ok: false, fallback: true, code: 'unsupported_purpose', message: '不支持的图片生成用途' };
|
||||
}
|
||||
if (!configService?.resolveImageGenerationPurpose) {
|
||||
return { ok: false, fallback: true, code: 'gateway_unavailable', message: '图片生成能力未启用' };
|
||||
}
|
||||
const gate = await configService.resolveImageGenerationPurpose(purpose);
|
||||
if (!gate.ok) return { ...gate, fallback: true };
|
||||
if (!imageMakeClient || !assetService?.createChatAsset) {
|
||||
return { ok: false, fallback: true, code: 'runtime_unavailable', message: '图片生成服务未配置' };
|
||||
}
|
||||
|
||||
try {
|
||||
const generated = await imageMakeClient.generateImage({
|
||||
prompt,
|
||||
negativePrompt,
|
||||
presetId: gate.presetId ?? spec.presetId,
|
||||
consumerRef,
|
||||
idempotencyKey: idempotencyKey || `imgreq_${crypto.randomUUID()}`,
|
||||
});
|
||||
const asset = await assetService.createChatAsset(userId, {
|
||||
categoryCode: 'public',
|
||||
buffer: generated.buffer,
|
||||
filename: spec.filename,
|
||||
displayName: spec.filename,
|
||||
sourceType: 'image_make',
|
||||
});
|
||||
await imageMakeClient.acknowledge(generated.jobId, asset.id).catch((error) => {
|
||||
logger.warn?.('[image_make] acknowledge failed; TTL cleanup will apply:', error?.message ?? error);
|
||||
});
|
||||
return {
|
||||
ok: true,
|
||||
purpose,
|
||||
jobId: generated.jobId,
|
||||
asset,
|
||||
source: {
|
||||
mimeType: generated.mimeType,
|
||||
width: generated.width,
|
||||
height: generated.height,
|
||||
sha256: generated.sha256,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
logger.warn?.('[image_make] generation failed; existing flow remains active:', error?.message ?? error);
|
||||
return {
|
||||
ok: false,
|
||||
fallback: true,
|
||||
code: error?.code ?? 'image_make_unavailable',
|
||||
message: '图片生成暂不可用,已保留原有流程',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return { purposes: Object.keys(PURPOSES), generate };
|
||||
}
|
||||
Reference in New Issue
Block a user