1
This commit is contained in:
@@ -1,18 +1,15 @@
|
||||
use module_big_fish::{BigFishAnchorPack, BigFishAnchorStatus, BigFishCreationStage};
|
||||
use platform_llm::LlmClient;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{Value as JsonValue, json};
|
||||
use spacetime_client::{
|
||||
BigFishAgentMessageRecord, BigFishMessageFinalizeRecordInput, BigFishSessionRecord,
|
||||
};
|
||||
use serde_json::Value as JsonValue;
|
||||
use spacetime_client::{BigFishMessageFinalizeRecordInput, BigFishSessionRecord};
|
||||
|
||||
use crate::creation_agent_anchor_templates::{
|
||||
get_creation_agent_anchor_template, render_anchor_question_block,
|
||||
};
|
||||
use crate::creation_agent_chat::render_quick_fill_extra_rules;
|
||||
use crate::creation_agent_llm_turn::{
|
||||
CreationAgentLlmTurnErrorMessages, stream_creation_agent_json_turn,
|
||||
};
|
||||
use crate::prompt::big_fish::{
|
||||
BIG_FISH_AGENT_SYSTEM_PROMPT, build_big_fish_agent_prompt, serialize_record_anchor_pack,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct BigFishAgentTurnRequest<'a> {
|
||||
@@ -60,57 +57,6 @@ struct BigFishAgentModelOutput {
|
||||
next_anchor_pack: BigFishAnchorPack,
|
||||
}
|
||||
|
||||
const BIG_FISH_AGENT_SYSTEM_PROMPT: &str = r#"你是一个负责和创作者共创“大鱼吃小鱼”竖屏玩法的中文创意策划。
|
||||
|
||||
你必须把用户灵感收束成可以编译为可玩草稿的玩法、生态视觉、成长阶梯和风险节奏。
|
||||
|
||||
你必须同时输出:
|
||||
1. 一段直接发给用户的中文回复 replyText
|
||||
2. 当前进度 progressPercent
|
||||
3. 下一轮完整可用的 nextAnchorPack
|
||||
|
||||
硬约束:
|
||||
1. 只能输出 JSON,不能输出代码块或解释
|
||||
2. nextAnchorPack 必须是完整对象,不能只输出 patch
|
||||
3. replyText 必须是自然中文,不能提“字段”“锚点”“结构”“JSON”等内部词
|
||||
4. replyText 一次最多推进一个最关键问题
|
||||
5. 必须对齐 RPG 共创的体验:先理解玩家幻想,再收束成能进入运行时的可玩效果
|
||||
6. progressPercent 范围只能是 0 到 100
|
||||
7. status 只能使用 missing / inferred / confirmed / locked
|
||||
"#;
|
||||
|
||||
const BIG_FISH_AGENT_OUTPUT_CONTRACT: &str = r#"请严格按以下 JSON 输出,不要输出其他文字:
|
||||
{
|
||||
"replyText": "",
|
||||
"progressPercent": 0,
|
||||
"nextAnchorPack": {
|
||||
"gameplayPromise": {
|
||||
"key": "gameplayPromise",
|
||||
"label": "玩法承诺",
|
||||
"value": "",
|
||||
"status": "missing"
|
||||
},
|
||||
"ecologyVisualTheme": {
|
||||
"key": "ecologyVisualTheme",
|
||||
"label": "生态视觉主题",
|
||||
"value": "",
|
||||
"status": "missing"
|
||||
},
|
||||
"growthLadder": {
|
||||
"key": "growthLadder",
|
||||
"label": "成长阶梯",
|
||||
"value": "",
|
||||
"status": "missing"
|
||||
},
|
||||
"riskTempo": {
|
||||
"key": "riskTempo",
|
||||
"label": "风险节奏",
|
||||
"value": "",
|
||||
"status": "missing"
|
||||
}
|
||||
}
|
||||
}"#;
|
||||
|
||||
pub(crate) async fn run_big_fish_agent_turn<F>(
|
||||
request: BigFishAgentTurnRequest<'_>,
|
||||
on_reply_update: F,
|
||||
@@ -189,54 +135,6 @@ pub(crate) fn build_failed_finalize_record_input(
|
||||
}
|
||||
}
|
||||
|
||||
fn build_big_fish_agent_prompt(
|
||||
session: &BigFishSessionRecord,
|
||||
quick_fill_requested: bool,
|
||||
) -> String {
|
||||
let anchor_question_block = get_creation_agent_anchor_template("big_fish")
|
||||
.map(render_anchor_question_block)
|
||||
.unwrap_or_else(|| "模板目标:收束成可玩的竖屏大鱼吃小鱼玩法草稿。".to_string());
|
||||
let quick_fill_rules = if quick_fill_requested {
|
||||
format!(
|
||||
"\n\n{}",
|
||||
render_quick_fill_extra_rules(
|
||||
"当前玩法方向里的成长、生态、风险节奏等缺失关键词",
|
||||
"不要要求用户再提供等级、鱼群、场景或节奏信息",
|
||||
"输出完整 nextAnchorPack,直接补齐 value 为空或 status 为 missing 的项",
|
||||
"生成结果页",
|
||||
)
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
format!(
|
||||
"{anchor_question_block}{quick_fill_rules}\n\n当前是第 {turn} 轮,当前进度 {progress}% 。\n\n是否要求自动补充剩余关键字:{quick_fill_requested_text}\n\n当前 anchor pack:\n{anchor_pack}\n\n最近聊天记录:\n{chat_history}\n\n{contract}",
|
||||
anchor_question_block = anchor_question_block,
|
||||
quick_fill_rules = quick_fill_rules,
|
||||
turn = session.current_turn.saturating_add(1),
|
||||
progress = session.progress_percent,
|
||||
quick_fill_requested_text = if quick_fill_requested { "是" } else { "否" },
|
||||
anchor_pack = serialize_record_anchor_pack(&session.anchor_pack),
|
||||
chat_history =
|
||||
serde_json::to_string_pretty(&build_chat_history(session.messages.as_slice()))
|
||||
.unwrap_or_else(|_| "[]".to_string()),
|
||||
contract = BIG_FISH_AGENT_OUTPUT_CONTRACT,
|
||||
)
|
||||
}
|
||||
|
||||
fn build_chat_history(messages: &[BigFishAgentMessageRecord]) -> Vec<JsonValue> {
|
||||
messages
|
||||
.iter()
|
||||
.map(|message| {
|
||||
json!({
|
||||
"role": message.role,
|
||||
"kind": message.kind,
|
||||
"content": message.text,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn parse_big_fish_model_output(
|
||||
parsed: &JsonValue,
|
||||
) -> Result<BigFishAgentModelOutput, BigFishAgentTurnError> {
|
||||
@@ -327,33 +225,6 @@ fn default_big_fish_anchor_label(field_name: &str) -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_record_anchor_pack(anchor_pack: &spacetime_client::BigFishAnchorPackRecord) -> String {
|
||||
serde_json::to_string_pretty(&map_big_fish_record_anchor_pack(anchor_pack))
|
||||
.unwrap_or_else(|_| "{}".to_string())
|
||||
}
|
||||
|
||||
fn map_big_fish_record_anchor_pack(
|
||||
record: &spacetime_client::BigFishAnchorPackRecord,
|
||||
) -> BigFishAnchorPack {
|
||||
BigFishAnchorPack {
|
||||
gameplay_promise: map_big_fish_record_anchor_item(&record.gameplay_promise),
|
||||
ecology_visual_theme: map_big_fish_record_anchor_item(&record.ecology_visual_theme),
|
||||
growth_ladder: map_big_fish_record_anchor_item(&record.growth_ladder),
|
||||
risk_tempo: map_big_fish_record_anchor_item(&record.risk_tempo),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_big_fish_record_anchor_item(
|
||||
record: &spacetime_client::BigFishAnchorItemRecord,
|
||||
) -> module_big_fish::BigFishAnchorItem {
|
||||
module_big_fish::BigFishAnchorItem {
|
||||
key: record.key.clone(),
|
||||
label: record.label.clone(),
|
||||
value: record.value.clone(),
|
||||
status: parse_big_fish_anchor_status(record.status.as_str()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_big_fish_anchor_status(value: &str) -> BigFishAnchorStatus {
|
||||
match value {
|
||||
"confirmed" => BigFishAnchorStatus::Confirmed,
|
||||
|
||||
Reference in New Issue
Block a user