fix: infer canvas agent image counts
This commit is contained in:
parent
c15a68385a
commit
0f74cbd6ff
@ -38,6 +38,7 @@ import {
|
|||||||
executeDirectVideoGeneration,
|
executeDirectVideoGeneration,
|
||||||
generateVideo,
|
generateVideo,
|
||||||
} from "@/lib/ai/tools/generate-video";
|
} from "@/lib/ai/tools/generate-video";
|
||||||
|
import { inferAgentImageCountFromText } from "@/lib/ai/runtime/image-count-intent";
|
||||||
import {
|
import {
|
||||||
getAgentRequiredUploadCount,
|
getAgentRequiredUploadCount,
|
||||||
normalizeAgentPresetModeConfig,
|
normalizeAgentPresetModeConfig,
|
||||||
@ -2241,7 +2242,7 @@ export async function POST(request: Request) {
|
|||||||
!smartAutoNeedsClarification &&
|
!smartAutoNeedsClarification &&
|
||||||
allowAgentVideoGeneration &&
|
allowAgentVideoGeneration &&
|
||||||
Boolean(smartAutoExecution?.shouldApplyVideoPipeline);
|
Boolean(smartAutoExecution?.shouldApplyVideoPipeline);
|
||||||
const effectiveImageParams = shouldApplyAgentImageParams
|
const mergedEffectiveImageParams = shouldApplyAgentImageParams
|
||||||
? mergeImageParamsWithAgentRecommendation({
|
? mergeImageParamsWithAgentRecommendation({
|
||||||
incoming: requestBody.imageParams,
|
incoming: requestBody.imageParams,
|
||||||
recommended: smartAutoRecommendedImageParams,
|
recommended: smartAutoRecommendedImageParams,
|
||||||
@ -2249,6 +2250,17 @@ export async function POST(request: Request) {
|
|||||||
hasUserCustomSettings: hasUserCustomImageParams,
|
hasUserCustomSettings: hasUserCustomImageParams,
|
||||||
})
|
})
|
||||||
: requestBody.imageParams;
|
: requestBody.imageParams;
|
||||||
|
const inferredAgentImageCount =
|
||||||
|
shouldApplyAgentImageParams && smartAutoDetectedIntent === "image_gen"
|
||||||
|
? inferAgentImageCountFromText(requestTextContent)
|
||||||
|
: null;
|
||||||
|
const effectiveImageParams =
|
||||||
|
inferredAgentImageCount !== null
|
||||||
|
? {
|
||||||
|
...(mergedEffectiveImageParams || {}),
|
||||||
|
imageCount: inferredAgentImageCount,
|
||||||
|
}
|
||||||
|
: mergedEffectiveImageParams;
|
||||||
const effectiveVideoParams = shouldApplyAgentVideoParams
|
const effectiveVideoParams = shouldApplyAgentVideoParams
|
||||||
? mergeVideoParamsWithAgentRecommendation({
|
? mergeVideoParamsWithAgentRecommendation({
|
||||||
incoming: requestBody.videoParams,
|
incoming: requestBody.videoParams,
|
||||||
@ -2273,6 +2285,7 @@ export async function POST(request: Request) {
|
|||||||
chatApiLogger.info("[Smart Auto Mode] 🎯 Effective image params:", {
|
chatApiLogger.info("[Smart Auto Mode] 🎯 Effective image params:", {
|
||||||
incoming: requestBody.imageParams,
|
incoming: requestBody.imageParams,
|
||||||
recommended: smartAutoRecommendedImageParams,
|
recommended: smartAutoRecommendedImageParams,
|
||||||
|
inferredImageCount: inferredAgentImageCount,
|
||||||
merged: effectiveImageGenerationParams,
|
merged: effectiveImageGenerationParams,
|
||||||
hasUserCustomImageParams,
|
hasUserCustomImageParams,
|
||||||
});
|
});
|
||||||
|
|||||||
60
lib/ai/runtime/image-count-intent.ts
Normal file
60
lib/ai/runtime/image-count-intent.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
const CHINESE_NUMBER_VALUES: Record<string, number> = {
|
||||||
|
一: 1,
|
||||||
|
两: 2,
|
||||||
|
二: 2,
|
||||||
|
三: 3,
|
||||||
|
四: 4,
|
||||||
|
五: 5,
|
||||||
|
六: 6,
|
||||||
|
七: 7,
|
||||||
|
八: 8,
|
||||||
|
九: 9,
|
||||||
|
十: 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
const COUNT_TOKEN = "([一两二三四五六七八九十]|[1-9]\\d?)";
|
||||||
|
const COUNT_UNIT = "(?:张|幅|版|个|组)";
|
||||||
|
|
||||||
|
function normalizeCountText(text: string) {
|
||||||
|
return String(text || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/\s+/g, "")
|
||||||
|
.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseCountToken(token?: string | null) {
|
||||||
|
const value = String(token || "").trim();
|
||||||
|
if (!value) return null;
|
||||||
|
if (/^\d+$/.test(value)) {
|
||||||
|
const numericValue = Number(value);
|
||||||
|
return Number.isFinite(numericValue) ? numericValue : null;
|
||||||
|
}
|
||||||
|
return CHINESE_NUMBER_VALUES[value] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clampImageCount(value: number, maxCount: number) {
|
||||||
|
return Math.min(Math.max(Math.round(value), 1), Math.max(1, maxCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function inferAgentImageCountFromText(text: string, maxCount = 12) {
|
||||||
|
const normalizedText = normalizeCountText(text);
|
||||||
|
if (!normalizedText) return null;
|
||||||
|
|
||||||
|
const explicitCountPatterns = [
|
||||||
|
new RegExp(
|
||||||
|
`(?:再来|再出|再做|再给我|补|多来|继续生成|继续出|继续做)${COUNT_TOKEN}${COUNT_UNIT}?`
|
||||||
|
),
|
||||||
|
new RegExp(
|
||||||
|
`(?:生成|创作|创建|制作|设计|做|出|画|绘制)${COUNT_TOKEN}${COUNT_UNIT}(?:图|图片|海报|头像|插画|场景|主图|产品图|商品图|电商图|壁纸|封面|logo|图标)?`
|
||||||
|
),
|
||||||
|
new RegExp(`(?:来|出|做)${COUNT_TOKEN}${COUNT_UNIT}`),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const pattern of explicitCountPatterns) {
|
||||||
|
const match = normalizedText.match(pattern);
|
||||||
|
const count = parseCountToken(match?.[1]);
|
||||||
|
if (count !== null && count > 0) return clampImageCount(count, maxCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
@ -40,6 +40,7 @@ import {
|
|||||||
} from "@/lib/canvas-toolbar-config";
|
} from "@/lib/canvas-toolbar-config";
|
||||||
import { shouldBypassCanvasAgentMissingTargetClarification } from "@/lib/ai/runtime/canvas-agent-clarification";
|
import { shouldBypassCanvasAgentMissingTargetClarification } from "@/lib/ai/runtime/canvas-agent-clarification";
|
||||||
import { hasCanvasAgentRoutingContext } from "@/lib/ai/canvas-agent-routing";
|
import { hasCanvasAgentRoutingContext } from "@/lib/ai/canvas-agent-routing";
|
||||||
|
import { inferAgentImageCountFromText } from "@/lib/ai/runtime/image-count-intent";
|
||||||
import {
|
import {
|
||||||
isAgentModeScopedChatId,
|
isAgentModeScopedChatId,
|
||||||
isScopedEmptyHistoryRequest,
|
isScopedEmptyHistoryRequest,
|
||||||
@ -158,6 +159,16 @@ import type { CanvasAgentContext } from "@/types/canvas/agent-protocol";
|
|||||||
import type { ChatMessage } from "@/lib/types";
|
import type { ChatMessage } from "@/lib/types";
|
||||||
|
|
||||||
test.describe("canvas chat pure helpers", () => {
|
test.describe("canvas chat pure helpers", () => {
|
||||||
|
test("infers explicit agent image counts from user text", () => {
|
||||||
|
expect(inferAgentImageCountFromText("再出三版")).toBe(3);
|
||||||
|
expect(inferAgentImageCountFromText("基于这张图再来 3 张")).toBe(3);
|
||||||
|
expect(inferAgentImageCountFromText("生成四张主图")).toBe(4);
|
||||||
|
expect(inferAgentImageCountFromText("多来两张")).toBe(2);
|
||||||
|
expect(inferAgentImageCountFromText("生成16:9横版海报")).toBeNull();
|
||||||
|
expect(inferAgentImageCountFromText("提升到2K清晰度")).toBeNull();
|
||||||
|
expect(inferAgentImageCountFromText("再出30张", 12)).toBe(12);
|
||||||
|
});
|
||||||
|
|
||||||
test("keeps canvas message empty-history access scoped and explicit", () => {
|
test("keeps canvas message empty-history access scoped and explicit", () => {
|
||||||
const canvasChatId = "11111111-1111-4111-8111-111111111111";
|
const canvasChatId = "11111111-1111-4111-8111-111111111111";
|
||||||
const agentScopedChatId = "11111111-1111-4111-8111-a93e17a60001";
|
const agentScopedChatId = "11111111-1111-4111-8111-a93e17a60001";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user