Files
memind/mindspace-image-generation-routes.mjs
T

48 lines
1.8 KiB
JavaScript

const PURPOSES = new Set(['inline_image', 'hero', 'card_cover', 'feed_cover']);
export function attachMindSpaceImageGenerationRoutes(router, { getService } = {}) {
router.post('/mindspace/v1/images/generate', async (req, res) => {
const service = getService?.();
if (!service) {
return res.status(503).json({
ok: false,
fallback: true,
code: 'runtime_unavailable',
message: '图片生成服务未配置',
});
}
const purpose = String(req.body?.purpose ?? '').trim().toLowerCase();
const prompt = String(req.body?.prompt ?? '').trim();
if (!PURPOSES.has(purpose)) {
return res.status(400).json({ message: '不支持的图片生成用途' });
}
if (!prompt || prompt.length > 1600) {
return res.status(400).json({ message: '图片描述不能为空且不能超过 1600 字符' });
}
const headerIdempotencyKey = String(req.get('idempotency-key') ?? '').trim();
const bodyIdempotencyKey = String(req.body?.idempotency_key ?? '').trim();
const idempotencyKey = headerIdempotencyKey || bodyIdempotencyKey || undefined;
if (idempotencyKey && idempotencyKey.length > 128) {
return res.status(400).json({ message: '幂等键不能超过 128 字符' });
}
const result = await service.generate({
userId: req.currentUser.id,
purpose,
prompt,
negativePrompt: req.body?.negative_prompt,
consumerRef: `mindspace:${req.requestId ?? 'request'}:${purpose}`,
idempotencyKey,
});
if (!result.ok) {
const unavailable = new Set([
'runtime_unavailable',
'image_make_unavailable',
'IMAGE_MAKE_HTTP_ERROR',
'IMAGE_MAKE_TIMEOUT',
]).has(result.code);
return res.status(unavailable ? 503 : 409).json(result);
}
return res.status(201).json({ data: result });
});
}