tighten agent execution intent gating
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-03-10 10:02:58 +08:00
parent f1dd0e9da9
commit a458baaca9

View File

@ -35,19 +35,36 @@ function inferDefaultImageEditSubIntent(text: string): AnalysisResult["subIntent
return "enhance";
}
function isVideoGenerationRequest(text: string): boolean {
return /视频|动画|动起来|生成视频|做视频|视频生成|图生视频|文生视频|镜头|分镜|运镜|首帧|尾帧/.test(
text.toLowerCase(),
);
}
function normalizeCompactText(text: string): string {
return text.toLowerCase().replace(/\s+/g, "").trim();
}
function isExplicitImageGenerationRequest(text: string): boolean {
function isLikelyAdvisoryOrPlanningRequest(text: string): boolean {
const normalizedText = text.toLowerCase();
return /重新生成|再来一张|生成新图|新建图片|创作一张|参考.*生成|按这个风格生成|以这张图为灵感生成|仿照.*生成|出一张/.test(
return /怎么|如何|为什么|是否|可不可以|能不能|行不行|建议|思路|方案|流程|步骤|教程|推荐|对比|区别|差别|优缺点|评估|分析|判断|解释|讲讲|科普|适合吗|可行吗|值不值得|要不要|帮我看看|帮我分析|帮我判断/.test(
normalizedText,
);
}
function isExplicitVideoGenerationRequest(text: string): boolean {
const normalizedText = normalizeCompactText(text);
const hasStrongVideoMarkers =
/图生视频|文生视频|首帧|尾帧|分镜|运镜|视频生成/.test(normalizedText);
if (hasStrongVideoMarkers) return true;
if (isLikelyAdvisoryOrPlanningRequest(text)) return false;
return (
/让.+动起来/.test(normalizedText) ||
(/(生成|制作|做|创建|输出|渲染|合成|出|做成|变成|转成)/.test(normalizedText) &&
/(视频|动画|短片|片子|动起来|会动)/.test(normalizedText))
);
}
function isExplicitImageGenerationRequest(text: string): boolean {
const normalizedText = normalizeCompactText(text);
if (isLikelyAdvisoryOrPlanningRequest(text)) return false;
return /重新生成|再来一张|生成新图|新建图片|创作一张|生成一张|画一张|给我画|帮我画|出一张|做一张图|做一张海报|创建一张图片|参考.*生成|按这个风格生成|以这张图为灵感生成|仿照.*生成/.test(
normalizedText,
);
}
@ -83,7 +100,20 @@ function applyDirectExecutionPolicy(
imageFromHistory?: boolean;
}
): AnalysisResult {
if (isVideoGenerationRequest(params.text)) {
const hasUsableImage =
params.hasImage || Boolean(params.imageFromHistory) || (params.imageUrls?.length || 0) > 0;
const compactText = normalizeCompactText(params.text);
const hasAnyRequestText = compactText.length > 0;
const explicitVideoGenerationRequest =
hasAnyRequestText && isExplicitVideoGenerationRequest(params.text);
const explicitImageGenerationRequest =
hasAnyRequestText && isExplicitImageGenerationRequest(params.text);
const likelyAdvisoryRequest =
hasAnyRequestText && isLikelyAdvisoryOrPlanningRequest(params.text);
const likelyVisionRequest = hasAnyRequestText && isLikelyVisionRequest(params.text);
const likelyGeneralChatTurn = hasAnyRequestText && isLikelyGeneralChatTurn(params.text);
if (explicitVideoGenerationRequest) {
return {
...result,
intent: "video_gen",
@ -99,18 +129,50 @@ function applyDirectExecutionPolicy(
};
}
const hasUsableImage =
params.hasImage || Boolean(params.imageFromHistory) || (params.imageUrls?.length || 0) > 0;
if (!hasUsableImage) return result;
if (!hasUsableImage) {
if (!explicitImageGenerationRequest && !explicitVideoGenerationRequest) {
if (likelyAdvisoryRequest || likelyGeneralChatTurn || result.intent === "chat") {
return {
...result,
intent: "chat",
subIntent: undefined,
confidence: Math.max(result.confidence, 0.76),
needsClarification: false,
clarifyingQuestions: [],
conversationalReply:
result.conversationalReply || "收到,我先按你的问题理解需求,再直接回答你。",
};
}
}
if (result.intent === "video_gen" && !explicitVideoGenerationRequest) {
return {
...result,
intent: "chat",
subIntent: undefined,
confidence: Math.max(result.confidence, 0.74),
needsClarification: false,
clarifyingQuestions: [],
};
}
if (result.intent === "image_gen" && !explicitImageGenerationRequest) {
return {
...result,
intent: "chat",
subIntent: undefined,
confidence: Math.max(result.confidence, 0.74),
needsClarification: false,
clarifyingQuestions: [],
};
}
return result;
}
const baseResult = normalizeIntentForImageContext(result, params.text, hasUsableImage);
const compactText = normalizeCompactText(params.text);
const hasAnyRequestText = compactText.length > 0;
const keepClarification = Boolean(result.needsClarification);
const explicitEditRequest = hasAnyRequestText && isLikelyImageEditRequest(params.text);
const explicitImageGenerationRequest = hasAnyRequestText && isExplicitImageGenerationRequest(params.text);
const likelyVisionRequest = hasAnyRequestText && isLikelyVisionRequest(params.text);
const likelyGeneralChatTurn = hasAnyRequestText && isLikelyGeneralChatTurn(params.text);
if (!hasAnyRequestText) {
return {
@ -125,7 +187,7 @@ function applyDirectExecutionPolicy(
};
}
if (!explicitEditRequest && !explicitImageGenerationRequest) {
if (!explicitEditRequest && !explicitImageGenerationRequest && !explicitVideoGenerationRequest) {
if (likelyVisionRequest || baseResult.intent === "vision") {
return {
...baseResult,
@ -139,7 +201,7 @@ function applyDirectExecutionPolicy(
};
}
if (likelyGeneralChatTurn || baseResult.intent === "chat") {
if (likelyAdvisoryRequest || likelyGeneralChatTurn || baseResult.intent === "chat") {
return {
...baseResult,
intent: "chat",
@ -2041,7 +2103,7 @@ export function fallbackKeywordAnalysis(
// === 图片编辑场景(需要有图片) ===
if (hasImage) {
// 视频生成(图生视频/首尾帧等)
if (isVideoGenerationRequest(lowerText)) {
if (isExplicitVideoGenerationRequest(text)) {
return {
intent: "video_gen",
confidence: 0.9,
@ -2186,7 +2248,7 @@ export function fallbackKeywordAnalysis(
// === 无图片场景 ===
// 图片生成
if (/画|绘制|生成图|创建.*图|设计.*图|画一个|生成一张|做一张/.test(lowerText)) {
if (isExplicitImageGenerationRequest(text)) {
return {
intent: "image_gen",
confidence: 0.85,
@ -2195,7 +2257,7 @@ export function fallbackKeywordAnalysis(
}
// 视频生成
if (isVideoGenerationRequest(lowerText)) {
if (isExplicitVideoGenerationRequest(text)) {
return {
intent: "video_gen",
confidence: 0.85,