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 }; }