CODE · 3.1 KB
api/generate-banners.js
Workspace snapshot · 09/04 13:35
import { buildBannerPrompts, buildRuntimePrompt, callRuntimeRpc, IMAGE_ENGINE, loadPromptSettings, RUNTIME_SERVICE_ID, runtimeEnvironment } from "./banner-core.js";
export const config = { maxDuration: 30 };
export function publicRuntimeGenerationEnabled(environment = process.env) {
return environment.PUBLIC_RUNTIME_GENERATION_ENABLED === "true";
}
export default async function handler(req, res) {
if (!publicRuntimeGenerationEnabled()) {
return res.status(503).json({
error: "公開画像生成は利用ポリシー確認中のため停止しています",
code: "PUBLIC_IMAGE_RUNTIME_DISABLED",
});
}
const runtime = runtimeEnvironment();
if (req.method === "GET" && !req.query?.jobIds) {
if (!runtime.connected) return res.status(200).json({ connected: false, engine: IMAGE_ENGINE });
try {
const status = await callRuntimeRpc({
rpc: "avs_llm_public_image_service_status",
payload: { p_service_id: RUNTIME_SERVICE_ID, p_token: runtime.token },
});
return res.status(200).json(status);
} catch {
return res.status(200).json({ connected: false, engine: IMAGE_ENGINE });
}
}
if (!runtime.connected) return res.status(503).json({ error: "VPS画像生成基盤が未接続です", code: "IMAGE_RUNTIME_NOT_CONFIGURED" });
if (req.method === "GET") {
const jobIds = String(req.query.jobIds).split(",").filter(Boolean).slice(0, 3);
if (!jobIds.length) return res.status(400).json({ error: "jobIdsが必要です" });
try {
const jobs = await Promise.all(jobIds.map(jobId => callRuntimeRpc({
rpc: "avs_llm_public_get_image_job",
payload: { p_service_id: RUNTIME_SERVICE_ID, p_token: runtime.token, p_job_id: jobId },
})));
return res.status(200).json({ engine: IMAGE_ENGINE, jobs });
} catch (error) {
return res.status(error.status || 502).json({ error: error.message, code: error.code });
}
}
if (req.method !== "POST") return res.status(405).json({ error: "GETまたはPOSTのみ利用できます" });
let prompts;
try {
const promptSettings = await loadPromptSettings();
prompts = buildBannerPrompts(req.body, promptSettings);
} catch (error) {
return res.status(400).json({ error: error.message });
}
const requestId = crypto.randomUUID();
const settled = await Promise.allSettled(prompts.map(async item => ({
direction: item.direction,
jobId: await callRuntimeRpc({
rpc: "avs_llm_public_enqueue_image_job",
payload: {
p_service_id: RUNTIME_SERVICE_ID,
p_token: runtime.token,
p_request_id: requestId,
p_direction: item.direction,
p_prompt: buildRuntimePrompt(item),
p_width: item.width,
p_height: item.height,
},
}),
})));
const jobs = settled.map((result, index) => result.status === "fulfilled"
? { ...result.value, status: "QUEUED" }
: { direction: prompts[index].direction, status: "FAILED", error: result.reason?.message || "画像生成を開始できませんでした" });
return res.status(jobs.some(item => item.jobId) ? 202 : 502).json({ engine: IMAGE_ENGINE, requestId, jobs });
}