ai-chatbot/lib/ai/canvas-agent-runtime/cutout-completion.ts

25 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { AgentRunSnapshot } from "./protocol";
import { finalResultNodeIds } from "./results";
/** Only a complete, single-purpose cutout may finish on file evidence alone. */
export function isCompletedSimpleCutout(snapshot: AgentRunSnapshot): boolean {
if (snapshot.workspace === "video") return false;
if (snapshot.inputs.length) return false; // Supplements can introduce a new action.
const request = [snapshot.objective, ...snapshot.inputs.map(input => input.text)].join("\n");
const intent = /抠图|抠出(?:来)?|扣出(?:来)?|去背|去(?:掉|除)?背景|移除背景|删除背景|remove\s+(?:the\s+)?background/i.exec(request);
if (!intent) return false;
// An unknown follow-up instruction is never silently treated as just cutout.
const tail = request.slice(intent.index + intent[0].length).replace(/[\s,。!!、;;,.::]/g, "")
.replace(/(?:保持透明背景|保持背景透明|透明背景|背景透明|保持透明|透明|保留原图|原图保留|放在原图旁边|结果放在原图旁边|放到画布上|PNG格式|PNG|一下|谢谢)/gi, "");
if (tail) return false;
if (/生成|换背景|更换背景|改.{0,8}(?:颜色|色彩|蓝|绿|红)|变.{0,5}色|排版|拼图|增强|修复|裁剪|尺寸|比例|下载|导出|检查|分析|对比|边缘|白边|毛边|光晕|发丝|锯齿|精细|移动|旋转|翻转|改名|重命名|删除原图|generate|resize|export|inspect|enhance|recolor|change|replace|crop|download/i.test(request)) return false;
if (!snapshot.calls.length || snapshot.calls.some(call => call.status !== "succeeded" || call.uncertain || call.rejected)) return false;
if (snapshot.calls.some(call => !["planCanvasTask", "readCanvas", "removeBackground", "analyzeCanvasImages", "listCanvasCapabilities"].includes(call.name))) return false;
const writes = snapshot.calls.filter(call => call.name === "removeBackground");
if (!writes.length || writes.some(call => call.output?.status !== "succeeded" || !Array.isArray(call.output.createdNodeIds) || !call.output.createdNodeIds.length)) return false;
const plan = snapshot.calls.filter(call => call.name === "planCanvasTask").at(-1)?.output;
const count = snapshot.requirements?.expectedImageCount ?? plan?.expectedImageCount;
const ids = finalResultNodeIds(snapshot);
return typeof count === "number" && count > 0 && ids.length === count && ids.every(id => writes.some(call => (call.output!.createdNodeIds as unknown[]).includes(id)));
}