Extend square-hole creation flow with visual asset timeout guard
This commit is contained in:
@@ -20,10 +20,12 @@ pub(crate) const SQUARE_HOLE_AGENT_SYSTEM_PROMPT: &str = r#"你是一个负责
|
||||
2. nextConfig 必须是完整对象,不能只输出 patch
|
||||
3. replyText 必须是自然中文,不能提“字段”“结构”“JSON”“后端”等内部词
|
||||
4. replyText 一次最多推进一个最关键问题
|
||||
5. 如果用户要求自动配置,就直接补齐可发布草稿需要的题材、反差规则、形状数量和难度,不要继续提问
|
||||
5. 如果用户要求自动配置,就直接补齐可发布草稿需要的题材、反差规则、形状数量、难度、形状选项、洞口选项和背景提示,不要继续提问
|
||||
6. 默认核心反差优先使用“方洞万能”或“方洞优先”,但可以根据用户题材包装成更有记忆点的规则
|
||||
7. progressPercent 范围只能是 0 到 100
|
||||
8. shapeCount 只能是 6 到 24 的整数,difficulty 只能是 1 到 10 的整数
|
||||
9. shapeOptions 至少给 6 个,holeOptions 给 3 到 6 个,且至少一个 holeOptions.bonus 为 true
|
||||
10. imagePrompt 和 backgroundPrompt 必须适合直接生成图片,不要包含 UI、文字、水印或解释
|
||||
"#;
|
||||
|
||||
const SQUARE_HOLE_AGENT_OUTPUT_CONTRACT: &str = r#"请严格按以下 JSON 输出,不要输出其他文字:
|
||||
@@ -34,7 +36,24 @@ const SQUARE_HOLE_AGENT_OUTPUT_CONTRACT: &str = r#"请严格按以下 JSON 输
|
||||
"themeText": "",
|
||||
"twistRule": "",
|
||||
"shapeCount": 12,
|
||||
"difficulty": 4
|
||||
"difficulty": 4,
|
||||
"shapeOptions": [
|
||||
{
|
||||
"optionId": "square-block",
|
||||
"shapeKind": "square",
|
||||
"label": "方块",
|
||||
"imagePrompt": "玩具纸箱主题的方块贴纸图,透明背景,明亮可爱,游戏资产"
|
||||
}
|
||||
],
|
||||
"holeOptions": [
|
||||
{
|
||||
"holeId": "square-hole",
|
||||
"holeKind": "square",
|
||||
"label": "方洞",
|
||||
"bonus": true
|
||||
}
|
||||
],
|
||||
"backgroundPrompt": "玩具桌面上的纸箱洞板背景,中央留出操作空间"
|
||||
}
|
||||
}"#;
|
||||
|
||||
@@ -42,8 +61,7 @@ pub(crate) const SQUARE_HOLE_AGENT_JSON_TURN_USER_PROMPT: &str = "请按约定
|
||||
|
||||
/// 方洞挑战草稿生成对话提示词脚本。
|
||||
///
|
||||
/// 方洞首版只需要四个可写回 SpacetimeDB 的配置项,因此提示词直接围绕配置收束,
|
||||
/// 不在模型输出层引入额外锚点,避免和当前持久化 schema 产生漂移。
|
||||
/// 方洞 Agent 负责输出完整玩法配置;后端会继续归一化缺失选项,避免模型偶发漏项导致草稿失败。
|
||||
pub(crate) fn build_square_hole_agent_prompt(
|
||||
session: &SquareHoleAgentSessionRecord,
|
||||
quick_fill_requested: bool,
|
||||
@@ -53,7 +71,7 @@ pub(crate) fn build_square_hole_agent_prompt(
|
||||
"\n\n{}",
|
||||
render_quick_fill_extra_rules(
|
||||
"当前方洞挑战方向里的题材、反差规则、形状数量和难度",
|
||||
"不要要求用户再提供洞口、形状、演出或难度信息",
|
||||
"不要要求用户再提供洞口、形状、背景或难度信息",
|
||||
"输出完整 nextConfig,直接补齐空缺或仍过于泛化的项",
|
||||
"生成结果页",
|
||||
)
|
||||
@@ -62,7 +80,7 @@ pub(crate) fn build_square_hole_agent_prompt(
|
||||
String::new()
|
||||
};
|
||||
format!(
|
||||
"模板目标:收束成可试玩、可发布的方洞挑战玩法草稿。{quick_fill_rules}\n\n当前是第 {turn} 轮,当前进度 {progress}% 。\n\n是否要求自动配置:{quick_fill_requested_text}\n\n当前配置:\n{current_config}\n\n最近聊天记录:\n{chat_history}\n\n收束要求:\n1. themeText 描述本局的玩具、道具或场景题材,保持短句。\n2. twistRule 描述真实判定规则,优先体现方洞优先或类似反直觉逻辑。\n3. shapeCount 决定单局形状数量,移动端短局建议 8 到 16。\n4. difficulty 决定误导强度和节奏,建议 3 到 7。\n5. 用户给出明确方向时优先吸收并推进,不要机械问完四个问题。\n\n{contract}",
|
||||
"模板目标:收束成可试玩、可发布的方洞挑战玩法草稿。{quick_fill_rules}\n\n当前是第 {turn} 轮,当前进度 {progress}% 。\n\n是否要求自动配置:{quick_fill_requested_text}\n\n当前配置:\n{current_config}\n\n最近聊天记录:\n{chat_history}\n\n收束要求:\n1. themeText 描述本局的玩具、道具或场景题材,保持短句。\n2. twistRule 描述真实判定规则,优先体现方洞优先或类似反直觉逻辑。\n3. shapeCount 决定单局形状数量,移动端短局建议 8 到 16。\n4. difficulty 决定误导强度和节奏,建议 3 到 7。\n5. shapeOptions 必须给出至少 6 个可生成贴图的形状候选,每个 imagePrompt 都围绕主题生成。\n6. holeOptions 必须给出 3 到 6 个洞口,创作者可在结果页继续改;至少一个 bonus=true。\n7. backgroundPrompt 用于生成运行态背景,必须描述画面,不要写规则说明。\n8. 用户给出明确方向时优先吸收并推进,不要机械问完所有字段。\n\n{contract}",
|
||||
quick_fill_rules = quick_fill_rules,
|
||||
turn = session.current_turn.saturating_add(1),
|
||||
progress = session.progress_percent,
|
||||
@@ -76,11 +94,42 @@ pub(crate) fn build_square_hole_agent_prompt(
|
||||
}
|
||||
|
||||
fn serialize_square_hole_session_config(session: &SquareHoleAgentSessionRecord) -> String {
|
||||
let shape_options: Vec<JsonValue> = session
|
||||
.config
|
||||
.shape_options
|
||||
.iter()
|
||||
.map(|option| {
|
||||
json!({
|
||||
"optionId": option.option_id,
|
||||
"shapeKind": option.shape_kind,
|
||||
"label": option.label,
|
||||
"imagePrompt": option.image_prompt,
|
||||
"imageSrc": option.image_src,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
let hole_options: Vec<JsonValue> = session
|
||||
.config
|
||||
.hole_options
|
||||
.iter()
|
||||
.map(|option| {
|
||||
json!({
|
||||
"holeId": option.hole_id,
|
||||
"holeKind": option.hole_kind,
|
||||
"label": option.label,
|
||||
"bonus": option.bonus,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
serde_json::to_string_pretty(&json!({
|
||||
"themeText": session.config.theme_text,
|
||||
"twistRule": session.config.twist_rule,
|
||||
"shapeCount": session.config.shape_count,
|
||||
"difficulty": session.config.difficulty,
|
||||
"shapeOptions": shape_options,
|
||||
"holeOptions": hole_options,
|
||||
"backgroundPrompt": session.config.background_prompt,
|
||||
}))
|
||||
.unwrap_or_else(|_| "{}".to_string())
|
||||
}
|
||||
@@ -129,6 +178,11 @@ mod tests {
|
||||
twist_rule: "方洞万能".to_string(),
|
||||
shape_count: 12,
|
||||
difficulty: 4,
|
||||
shape_options: Vec::new(),
|
||||
hole_options: Vec::new(),
|
||||
background_prompt: "积木纸箱桌面背景".to_string(),
|
||||
cover_image_src: None,
|
||||
background_image_src: None,
|
||||
},
|
||||
draft: None,
|
||||
messages: vec![message("user", "做成办公室文具版")],
|
||||
@@ -159,6 +213,9 @@ mod tests {
|
||||
assert!(prompt.contains("用户刚刚主动要求你自动补充剩余关键字"));
|
||||
assert!(prompt.contains("不要再继续提问"));
|
||||
assert!(prompt.contains("nextConfig"));
|
||||
assert!(prompt.contains("shapeOptions"));
|
||||
assert!(prompt.contains("holeOptions"));
|
||||
assert!(prompt.contains("backgroundPrompt"));
|
||||
assert!(prompt.contains("progressPercent 直接输出为 100"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user