show agent scene system lock prompts
This commit is contained in:
parent
bd1dbc4406
commit
a215ec1cbb
@ -58,6 +58,7 @@ import {
|
||||
getAgentRequiredUploadCount,
|
||||
normalizeAgentPresetModeConfig,
|
||||
} from "@/lib/agents/preset-mode-config";
|
||||
import { buildAgentSceneImageRolePrompt } from "@/lib/agents/scene-image-role-prompt";
|
||||
import { getEnabledTools } from "@/lib/ai/tools-registry";
|
||||
import { isProductionEnvironment } from "@/lib/constants";
|
||||
import {
|
||||
@ -3168,85 +3169,6 @@ function buildAgentSceneWorkflowPrompt(params: {
|
||||
return lines.join("\n\n").trim();
|
||||
}
|
||||
|
||||
function buildAgentSceneImageRolePrompt(params: {
|
||||
uploadedImageCount: number;
|
||||
productImageCount: number;
|
||||
includeModelImage: boolean;
|
||||
}) {
|
||||
if (params.uploadedImageCount <= 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const lines = ["【输入图片角色说明】"];
|
||||
const resolvedProductCount = Math.max(
|
||||
1,
|
||||
Math.min(params.productImageCount, params.uploadedImageCount)
|
||||
);
|
||||
const hasModelImage =
|
||||
params.includeModelImage && params.uploadedImageCount > resolvedProductCount;
|
||||
|
||||
for (let index = 0; index < params.uploadedImageCount; index += 1) {
|
||||
if (index < resolvedProductCount) {
|
||||
lines.push(
|
||||
`图片${index + 1}:产品白底参考图,用于锁定产品的外观、比例、材质、颜色、结构和细节。`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hasModelImage && index === resolvedProductCount) {
|
||||
lines.push(
|
||||
`图片${index + 1}:固定模特图。若画面需要人物,必须复用这张图中的同一模特(脸型、发型、体型、肤色、穿搭风格保持一致),不得替换成其他人物。`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
lines.push(
|
||||
`图片${index + 1}:补充参考图,只用于补充产品角度、细节或辅助信息,不可替代主产品外观。`
|
||||
);
|
||||
}
|
||||
|
||||
lines.push(
|
||||
`必须以图片1${resolvedProductCount > 1 ? `到图片${resolvedProductCount}` : ""}中的产品信息为最高优先级,严格保持同一产品。`
|
||||
);
|
||||
lines.push(
|
||||
"【产品锁定约束】生成结果中的产品必须与产品白底参考图保持同一产品身份,禁止改成另一款产品。"
|
||||
);
|
||||
lines.push(
|
||||
"严禁改变产品的主体结构、外轮廓、长宽高比例、层板数量与位置、抽屉数量与位置、柜门/开孔/隔断布局、弧度造型、柜腿样式、把手/五金位置。"
|
||||
);
|
||||
lines.push(
|
||||
"严禁改变产品主色、木纹方向、材质类型、表面纹理、明暗层次和细节做工;不得把深色木纹改成浅色、白色、金属色或其他颜色体系。"
|
||||
);
|
||||
lines.push(
|
||||
"如果场景风格与产品外观产生冲突,必须优先保留产品本体不变,只允许调整周边场景、软装、灯光、背景和道具,不允许为了适配风格而修改产品。"
|
||||
);
|
||||
lines.push(
|
||||
"产品白底图是产品身份锁定图,不是灵感参考图。输出时必须让人一眼看出是同一个产品,只能换场景,不能换产品本体。"
|
||||
);
|
||||
lines.push("不要把多张输入图拼贴成多个主体,也不要把所有输入图元素强行同时融入结果。");
|
||||
lines.push(
|
||||
hasModelImage
|
||||
? `如果当前场景有人物展示需求,只允许使用图片${resolvedProductCount + 1}里的模特;如果不需要人物,则不要强行加入人物。`
|
||||
: "当前没有固定模特图,不要凭空生成强人物主体。"
|
||||
);
|
||||
if (hasModelImage) {
|
||||
lines.push(
|
||||
"【模特锁定约束】固定模特图是人物身份锁定图。结果中出现的人物必须与模特图为同一人,不得换脸、换人、换性别、换年龄段,不得改变五官特征、脸型、发际线、发型主体、肤色、身材和辨识度。"
|
||||
);
|
||||
lines.push(
|
||||
"允许根据场景构图调整模特的站姿、坐姿、手势、视线和轻微表情,但必须让人一眼看出是同一个模特。"
|
||||
);
|
||||
lines.push(
|
||||
"只有当工作流设定或补充要求里明确要求修改模特衣服、穿搭或服装颜色时,才允许更换或调整服饰;如果没有明确要求,默认保持模特原有服装风格和穿搭关系一致。"
|
||||
);
|
||||
lines.push(
|
||||
"如果模特衣服被允许调整,也只能改衣服,不得借机改变模特本人;人物身份稳定性始终高于服装变化。"
|
||||
);
|
||||
}
|
||||
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
type AgentReplacementModePayload = NonNullable<PostRequestBody["agentModePayload"]>;
|
||||
|
||||
type ReplacementReferenceDecision = {
|
||||
|
||||
@ -74,6 +74,7 @@ import {
|
||||
getAgentRequiredUploadCount,
|
||||
normalizeAgentPresetModeConfig,
|
||||
} from "@/lib/agents/preset-mode-config";
|
||||
import { buildAgentSceneImageRolePrompt } from "@/lib/agents/scene-image-role-prompt";
|
||||
import type { Attachment, ChatMessage } from "@/lib/types";
|
||||
import { cn, fetchWithErrorHandlers, fetcher, generateUUID } from "@/lib/utils";
|
||||
import { AgentCanvasTopNavDark } from "@/components/agents/AgentCanvasTopNavDark";
|
||||
@ -931,6 +932,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
)
|
||||
);
|
||||
const [isAttachmentSlotExpanded, setIsAttachmentSlotExpanded] = useState(false);
|
||||
const [isScenePromptExpanded, setIsScenePromptExpanded] = useState(false);
|
||||
const [slotUploading, setSlotUploading] = useState<number | null>(null);
|
||||
const [selectedModelId, setSelectedModelId] = useState<string>(
|
||||
normalizedIncomingWorkspaceState.selectedModelId || "auto"
|
||||
@ -1178,6 +1180,22 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
: null;
|
||||
const attachmentSummaryReady =
|
||||
hasAgentUploadSlots && (requiredUploadCount === 0 || filledAttachmentCount >= requiredUploadCount);
|
||||
const sceneImageRolePromptPreview = useMemo(() => {
|
||||
if (!isSceneGenerationPreset || filledAttachmentCount <= 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return buildAgentSceneImageRolePrompt({
|
||||
uploadedImageCount: filledAttachmentCount,
|
||||
productImageCount: productSlotCount,
|
||||
includeModelImage: modelSlotEnabled,
|
||||
});
|
||||
}, [
|
||||
filledAttachmentCount,
|
||||
isSceneGenerationPreset,
|
||||
modelSlotEnabled,
|
||||
productSlotCount,
|
||||
]);
|
||||
const detailReplacementQueryInput = detailReplacementState.query;
|
||||
const detailReplacementCandidates = detailReplacementState.candidates;
|
||||
const detailReplacementSelectedCandidateId = detailReplacementState.selectedCandidateId;
|
||||
@ -4303,6 +4321,44 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
{slotRequirementMessage}
|
||||
</div>
|
||||
) : null}
|
||||
{sceneImageRolePromptPreview ? (
|
||||
<Collapsible
|
||||
open={isScenePromptExpanded}
|
||||
onOpenChange={setIsScenePromptExpanded}
|
||||
className="rounded-[22px] border border-white/10 bg-black/25"
|
||||
>
|
||||
<div className="flex flex-wrap items-start justify-between gap-3 px-4 py-3">
|
||||
<div>
|
||||
<div className="text-sm font-medium text-white">系统预设约束</div>
|
||||
<div className="mt-1 text-xs leading-6 text-white/55">
|
||||
最终发送给模型时,会自动追加产品锁定约束
|
||||
{modelSlotEnabled ? "和模特锁定约束" : ""}。
|
||||
</div>
|
||||
</div>
|
||||
<CollapsibleTrigger asChild>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
className="h-9 rounded-[18px] border-white/12 bg-black/20 px-3 text-white/80 hover:border-white/22 hover:bg-white/[0.06] hover:text-white"
|
||||
>
|
||||
{isScenePromptExpanded ? "收起约束" : "查看约束"}
|
||||
{isScenePromptExpanded ? (
|
||||
<ChevronUp className="ml-2 h-4 w-4" />
|
||||
) : (
|
||||
<ChevronDown className="ml-2 h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
</CollapsibleTrigger>
|
||||
</div>
|
||||
<CollapsibleContent>
|
||||
<div className="border-t border-white/8 px-4 py-4">
|
||||
<pre className="whitespace-pre-wrap text-xs leading-6 text-white/78">
|
||||
{sceneImageRolePromptPreview}
|
||||
</pre>
|
||||
</div>
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
78
lib/agents/scene-image-role-prompt.ts
Normal file
78
lib/agents/scene-image-role-prompt.ts
Normal file
@ -0,0 +1,78 @@
|
||||
export function buildAgentSceneImageRolePrompt(params: {
|
||||
uploadedImageCount: number;
|
||||
productImageCount: number;
|
||||
includeModelImage: boolean;
|
||||
}) {
|
||||
if (params.uploadedImageCount <= 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const lines = ["【输入图片角色说明】"];
|
||||
const resolvedProductCount = Math.max(
|
||||
1,
|
||||
Math.min(params.productImageCount, params.uploadedImageCount)
|
||||
);
|
||||
const hasModelImage =
|
||||
params.includeModelImage && params.uploadedImageCount > resolvedProductCount;
|
||||
|
||||
for (let index = 0; index < params.uploadedImageCount; index += 1) {
|
||||
if (index < resolvedProductCount) {
|
||||
lines.push(
|
||||
`图片${index + 1}:产品白底参考图,用于锁定产品的外观、比例、材质、颜色、结构和细节。`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hasModelImage && index === resolvedProductCount) {
|
||||
lines.push(
|
||||
`图片${index + 1}:固定模特图。若画面需要人物,必须复用这张图中的同一模特(脸型、发型、体型、肤色、穿搭风格保持一致),不得替换成其他人物。`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
lines.push(
|
||||
`图片${index + 1}:补充参考图,只用于补充产品角度、细节或辅助信息,不可替代主产品外观。`
|
||||
);
|
||||
}
|
||||
|
||||
lines.push(
|
||||
`必须以图片1${resolvedProductCount > 1 ? `到图片${resolvedProductCount}` : ""}中的产品信息为最高优先级,严格保持同一产品。`
|
||||
);
|
||||
lines.push(
|
||||
"【产品锁定约束】生成结果中的产品必须与产品白底参考图保持同一产品身份,禁止改成另一款产品。"
|
||||
);
|
||||
lines.push(
|
||||
"严禁改变产品的主体结构、外轮廓、长宽高比例、层板数量与位置、抽屉数量与位置、柜门/开孔/隔断布局、弧度造型、柜腿样式、把手/五金位置。"
|
||||
);
|
||||
lines.push(
|
||||
"严禁改变产品主色、木纹方向、材质类型、表面纹理、明暗层次和细节做工;不得把深色木纹改成浅色、白色、金属色或其他颜色体系。"
|
||||
);
|
||||
lines.push(
|
||||
"如果场景风格与产品外观产生冲突,必须优先保留产品本体不变,只允许调整周边场景、软装、灯光、背景和道具,不允许为了适配风格而修改产品。"
|
||||
);
|
||||
lines.push(
|
||||
"产品白底图是产品身份锁定图,不是灵感参考图。输出时必须让人一眼看出是同一个产品,只能换场景,不能换产品本体。"
|
||||
);
|
||||
lines.push("不要把多张输入图拼贴成多个主体,也不要把所有输入图元素强行同时融入结果。");
|
||||
lines.push(
|
||||
hasModelImage
|
||||
? `如果当前场景有人物展示需求,只允许使用图片${resolvedProductCount + 1}里的模特;如果不需要人物,则不要强行加入人物。`
|
||||
: "当前没有固定模特图,不要凭空生成强人物主体。"
|
||||
);
|
||||
if (hasModelImage) {
|
||||
lines.push(
|
||||
"【模特锁定约束】固定模特图是人物身份锁定图。结果中出现的人物必须与模特图为同一人,不得换脸、换人、换性别、换年龄段,不得改变五官特征、脸型、发际线、发型主体、肤色、身材和辨识度。"
|
||||
);
|
||||
lines.push(
|
||||
"允许根据场景构图调整模特的站姿、坐姿、手势、视线和轻微表情,但必须让人一眼看出是同一个模特。"
|
||||
);
|
||||
lines.push(
|
||||
"只有当工作流设定或补充要求里明确要求修改模特衣服、穿搭或服装颜色时,才允许更换或调整服饰;如果没有明确要求,默认保持模特原有服装风格和穿搭关系一致。"
|
||||
);
|
||||
lines.push(
|
||||
"如果模特衣服被允许调整,也只能改衣服,不得借机改变模特本人;人物身份稳定性始终高于服装变化。"
|
||||
);
|
||||
}
|
||||
|
||||
return lines.join("\n");
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user