拆分大文件

This commit is contained in:
2026-04-23 23:38:00 +08:00
parent 53a9cdd791
commit 8df502b2a7
506 changed files with 11312 additions and 13069 deletions

View File

@@ -611,7 +611,10 @@ where
empty_json_array()
};
let asset_coverage_json = if should_stay_in_draft_stage {
serialize_json(&request.session.asset_coverage, &empty_agent_asset_coverage_json())
serialize_json(
&request.session.asset_coverage,
&empty_agent_asset_coverage_json(),
)
} else {
empty_agent_asset_coverage_json()
};
@@ -732,7 +735,10 @@ pub(crate) fn build_failed_finalize_record_input(
stage: session.stage.clone(),
progress_percent: session.progress_percent,
focus_card_id: session.focus_card_id.clone(),
anchor_content_json: serialize_json(&session.anchor_content, &empty_agent_anchor_content_json()),
anchor_content_json: serialize_json(
&session.anchor_content,
&empty_agent_anchor_content_json(),
),
creator_intent_json: serialize_optional_json_object(&session.creator_intent),
creator_intent_readiness_json: serialize_json(
&session.creator_intent_readiness,
@@ -753,7 +759,10 @@ pub(crate) fn build_failed_finalize_record_input(
&JsonValue::Array(session.quality_findings.clone()),
&empty_json_array(),
),
asset_coverage_json: serialize_json(&session.asset_coverage, &empty_agent_asset_coverage_json()),
asset_coverage_json: serialize_json(
&session.asset_coverage,
&empty_agent_asset_coverage_json(),
),
error_message: Some(error_message),
updated_at_micros,
}
@@ -771,13 +780,18 @@ async fn stream_single_turn<F>(
where
F: FnMut(&str),
{
let llm_client = llm_client.ok_or_else(|| {
CustomWorldTurnError::new("当前模型不可用,请稍后重试。")
})?;
let llm_client =
llm_client.ok_or_else(|| CustomWorldTurnError::new("当前模型不可用,请稍后重试。"))?;
let chat_history = build_chat_history(messages);
let dynamic_state =
resolve_dynamic_state(llm_client, current_turn, progress_percent, quick_fill_requested, current_anchor_content, &chat_history)
.await;
let dynamic_state = resolve_dynamic_state(
llm_client,
current_turn,
progress_percent,
quick_fill_requested,
current_anchor_content,
&chat_history,
)
.await;
let prompt = build_eight_anchor_single_turn_prompt(
current_turn,
progress_percent,
@@ -806,27 +820,21 @@ where
)
.await;
let response = response.map_err(|_| {
CustomWorldTurnError::new("这一轮设定生成失败,请稍后重试。")
})?;
let response =
response.map_err(|_| CustomWorldTurnError::new("这一轮设定生成失败,请稍后重试。"))?;
let parsed = parse_json_response_text(response.content.as_str()).map_err(|_| {
CustomWorldTurnError::new("模型返回结果解析失败,请稍后重试。")
})?;
let parsed = parse_json_response_text(response.content.as_str())
.map_err(|_| CustomWorldTurnError::new("模型返回结果解析失败,请稍后重试。"))?;
let next_anchor_content = normalize_eight_anchor_content(
parsed
.get("nextAnchorContent")
.unwrap_or(&JsonValue::Null),
);
let next_anchor_content =
normalize_eight_anchor_content(parsed.get("nextAnchorContent").unwrap_or(&JsonValue::Null));
let progress_percent = if quick_fill_requested {
100
} else {
clamp_progress_percent(parsed.get("progressPercent"))
};
let reply_text = to_text(parsed.get("replyText")).ok_or_else(|| {
CustomWorldTurnError::new("模型返回结果缺少有效回复,请稍后重试。")
})?;
let reply_text = to_text(parsed.get("replyText"))
.ok_or_else(|| CustomWorldTurnError::new("模型返回结果缺少有效回复,请稍后重试。"))?;
if reply_text != latest_reply_text {
on_reply_update(reply_text.as_str());
}
@@ -907,13 +915,19 @@ fn build_prompt_dynamic_state(
let Some(inference) = inference else {
return fallback;
};
let user_input_signal = inference.user_input_signal.unwrap_or(fallback.user_input_signal);
let user_input_signal = inference
.user_input_signal
.unwrap_or(fallback.user_input_signal);
let drift_risk = inference.drift_risk.unwrap_or(fallback.drift_risk);
let conversation_mode = inference.conversation_mode.unwrap_or(fallback.conversation_mode);
let conversation_mode = inference
.conversation_mode
.unwrap_or(fallback.conversation_mode);
let judgement_summary = inference
.judgement_summary
.filter(|value| !value.trim().is_empty())
.unwrap_or_else(|| summarize_dynamic_state(user_input_signal, drift_risk, conversation_mode));
.unwrap_or_else(|| {
summarize_dynamic_state(user_input_signal, drift_risk, conversation_mode)
});
PromptDynamicState {
current_turn,
@@ -966,7 +980,11 @@ fn build_prompt_dynamic_state_inference_prompt(
chat_history: &[JsonValue],
) -> (String, String) {
(
[STATE_INFERENCE_SYSTEM_PROMPT, STATE_INFERENCE_OUTPUT_CONTRACT].join("\n\n"),
[
STATE_INFERENCE_SYSTEM_PROMPT,
STATE_INFERENCE_OUTPUT_CONTRACT,
]
.join("\n\n"),
[
format!("当前轮次:{current_turn}"),
format!("当前完成度:{progress_percent}"),
@@ -1010,7 +1028,8 @@ fn build_chat_history(messages: &[CustomWorldAgentMessageRecord]) -> Vec<JsonVal
messages
.iter()
.filter(|message| {
(message.role == "user" || message.role == "assistant") && !message.text.trim().is_empty()
(message.role == "user" || message.role == "assistant")
&& !message.text.trim().is_empty()
})
.map(|message| {
json!({
@@ -1059,8 +1078,7 @@ fn build_creator_intent_from_eight_anchor_content(
.iter()
.cloned()
.chain(
(!value.hidden_crisis.trim().is_empty())
.then_some(value.hidden_crisis.clone()),
(!value.hidden_crisis.trim().is_empty()).then_some(value.hidden_crisis.clone()),
)
.collect::<Vec<_>>()
})
@@ -1205,7 +1223,10 @@ fn evaluate_creator_intent_readiness(intent: &CreatorIntentRecord) -> CreatorInt
}
}
fn resolve_creator_intent_stage(has_user_input: bool, readiness: &CreatorIntentReadiness) -> &'static str {
fn resolve_creator_intent_stage(
has_user_input: bool,
readiness: &CreatorIntentReadiness,
) -> &'static str {
if readiness.is_ready {
"foundation_review"
} else if has_user_input {
@@ -1509,11 +1530,16 @@ fn detect_user_input_signal(chat_history: &[JsonValue]) -> PromptUserInputSignal
if latest_user_text.is_empty() {
return PromptUserInputSignal::Sparse;
}
if contains_any(&latest_user_text, &["不是", "改成", "改为", "换成", "重来", "推翻", "修正"])
{
if contains_any(
&latest_user_text,
&["不是", "改成", "改为", "换成", "重来", "推翻", "修正"],
) {
return PromptUserInputSignal::Correction;
}
if contains_any(&latest_user_text, &["你帮我想", "你来定", "你决定", "你补完"]) {
if contains_any(
&latest_user_text,
&["你帮我想", "你来定", "你决定", "你补完"],
) {
return PromptUserInputSignal::Delegate;
}
let segments = split_sentences(&latest_user_text);
@@ -1535,8 +1561,14 @@ fn detect_drift_risk(
let recent_user_messages = chat_history
.iter()
.filter_map(|entry| {
(entry.get("role").and_then(JsonValue::as_str) == Some("user"))
.then(|| entry.get("content").and_then(JsonValue::as_str).unwrap_or("").trim().to_string())
(entry.get("role").and_then(JsonValue::as_str) == Some("user")).then(|| {
entry
.get("content")
.and_then(JsonValue::as_str)
.unwrap_or("")
.trim()
.to_string()
})
})
.filter(|value| !value.is_empty())
.rev()
@@ -1545,11 +1577,19 @@ fn detect_drift_risk(
let correction_count = recent_user_messages
.iter()
.filter(|entry| contains_any(entry, &["不是", "改成", "改为", "换成", "推翻", "重来", "修正"]))
.filter(|entry| {
contains_any(
entry,
&["不是", "改成", "改为", "换成", "推翻", "重来", "修正"],
)
})
.count();
if correction_count >= 2
|| (progress_percent >= 65
&& contains_any(&latest_user_text, &["不是", "改成", "改为", "换成", "重来", "推翻"]))
&& contains_any(
&latest_user_text,
&["不是", "改成", "改为", "换成", "重来", "推翻"],
))
{
return PromptDriftRisk::High;
}
@@ -1652,7 +1692,8 @@ fn render_dynamic_state_context(dynamic_state: &PromptDynamicState) -> String {
fn render_current_anchor_context(anchor_content: &EightAnchorContent) -> String {
format!(
"当前完整设定结构如下。\n你必须把它视为上一版有效世界底子。\n\n如果用户没有否定其中某部分内容,且该部分仍然成立,可以继续保留。\n如果用户明确修正了某部分内容,新的完整设定结构必须体现修正后的版本。\n\n当前完整设定结构:\n{}",
serde_json::to_string_pretty(anchor_content).unwrap_or_else(|_| empty_agent_anchor_content_json())
serde_json::to_string_pretty(anchor_content)
.unwrap_or_else(|_| empty_agent_anchor_content_json())
)
}
@@ -1757,7 +1798,8 @@ fn parse_conversation_mode(value: Option<&JsonValue>) -> Option<PromptConversati
fn mode_rules(mode: PromptConversationMode) -> &'static str {
match mode {
PromptConversationMode::Bootstrap => r#"当前模式bootstrap
PromptConversationMode::Bootstrap => {
r#"当前模式bootstrap
目标:
1. 先把世界的基本方向抓住
@@ -1777,8 +1819,10 @@ fn mode_rules(mode: PromptConversationMode) -> &'static str {
1. 让用户觉得“现在很容易继续往下说”
2. 不要制造被考试、被拷问、被策划问卷追着跑的感觉
3. replyText 最好短、稳、可接话
4. 如果用户信息很少,也不要显得冷淡或机械"#,
PromptConversationMode::Expand => r#"当前模式expand
4. 如果用户信息很少,也不要显得冷淡或机械"#
}
PromptConversationMode::Expand => {
r#"当前模式expand
目标:
1. 在保持现有方向的前提下,把设定结构逐步补全
@@ -1797,8 +1841,10 @@ fn mode_rules(mode: PromptConversationMode) -> &'static str {
1. 让用户感到“我刚说的内容都被接住了”
2. 回复里可以带一点顺势整理感,但不要太像会议纪要
3. 不要无视用户刚提供的高价值细节
4. 不要让用户觉得系统在自顾自重写世界"#,
PromptConversationMode::Compress => r#"当前模式compress
4. 不要让用户觉得系统在自顾自重写世界"#
}
PromptConversationMode::Compress => {
r#"当前模式compress
目标:
1. 开始收束当前设定
@@ -1818,8 +1864,10 @@ fn mode_rules(mode: PromptConversationMode) -> &'static str {
1. 让用户感觉世界正在变得更稳,而不是越来越散
2. 让推进感更明确,但不要显得催促
3. 回复语气应更笃定一些,减少反复横跳
4. 不要把用户刚补进来的细节又冲淡掉"#,
PromptConversationMode::RepairDirection => r#"当前模式repair_direction
4. 不要把用户刚补进来的细节又冲淡掉"#
}
PromptConversationMode::RepairDirection => {
r#"当前模式repair_direction
目标:
1. 处理用户对既有设定的修正
@@ -1838,8 +1886,10 @@ fn mode_rules(mode: PromptConversationMode) -> &'static str {
1. 让用户感到“我刚刚的纠偏真的生效了”
2. 不要和用户辩论旧方案为什么也行
3. 不要表现出对修正的不情愿
4. 回复要体现重心已经切到新方向,而不是停留在旧世界观惯性里"#,
PromptConversationMode::ForceComplete => r#"当前模式force_complete
4. 回复要体现重心已经切到新方向,而不是停留在旧世界观惯性里"#
}
PromptConversationMode::ForceComplete => {
r#"当前模式force_complete
目标:
1. 基于当前方向直接补齐剩余设定
@@ -1860,8 +1910,10 @@ fn mode_rules(mode: PromptConversationMode) -> &'static str {
1. 让用户感到“系统已经帮我把能补的补好了”
2. 不要在这一步突然冒出很多陌生设定把用户吓出戏
3. 回复要有完成感,但不要太官话
4. 清楚告诉用户下一步可以做什么"#,
PromptConversationMode::Closing => r#"当前模式closing
4. 清楚告诉用户下一步可以做什么"#
}
PromptConversationMode::Closing => {
r#"当前模式closing
目标:
1. 尽量形成一版可用的设定底子
@@ -1880,26 +1932,37 @@ fn mode_rules(mode: PromptConversationMode) -> &'static str {
1. 让用户感觉作品已经快成了,而不是还在无穷试探
2. 回复可以更像确认和轻推,不要继续像前期那样频繁试探
3. 保持留白感,不要把所有东西都一次说死
4. 让用户自然过渡到下一阶段,而不是突然被切断对话"#,
4. 让用户自然过渡到下一阶段,而不是突然被切断对话"#
}
}
}
fn user_signal_rules(signal: PromptUserInputSignal) -> &'static str {
match signal {
PromptUserInputSignal::Rich => r#"本轮用户输入信息密度高。
PromptUserInputSignal::Rich => {
r#"本轮用户输入信息密度高。
请尽量从这一轮里提取多个锚点,不要只更新单一方向。
如果一条输入同时影响世界方向、冲突和关系,请在新的完整设定结构中一起体现。"#,
PromptUserInputSignal::Normal => r#"本轮用户输入为正常补充。
请优先顺着当前方向稳定更新,不要主动扩写太多新设定。"#,
PromptUserInputSignal::Sparse => r#"本轮用户输入较少或较虚
如果一条输入同时影响世界方向、冲突和关系,请在新的完整设定结构中一起体现。"#
}
PromptUserInputSignal::Normal => {
r#"本轮用户输入为正常补充
请优先顺着当前方向稳定更新,不要主动扩写太多新设定。"#
}
PromptUserInputSignal::Sparse => {
r#"本轮用户输入较少或较虚。
请保留上一版中仍然成立的内容,不要为了凑完整度而强行发明过多新设定。
replyText 要让用户容易继续往下说。"#,
PromptUserInputSignal::Correction => r#"本轮用户在修正或推翻旧设定。
replyText 要让用户容易继续往下说。"#
}
PromptUserInputSignal::Correction => {
r#"本轮用户在修正或推翻旧设定。
请优先吸收修正,不要机械复读旧版本。
新的完整设定结构必须以修正后的方向为准。"#,
PromptUserInputSignal::Delegate => r#"本轮用户把部分决定权交给你。
新的完整设定结构必须以修正后的方向为准。"#
}
PromptUserInputSignal::Delegate => {
r#"本轮用户把部分决定权交给你。
你可以在 replyText 中给出有限度的建议,但不要突然补满整套设定。
新的完整设定结构仍应尽量建立在已有世界方向上,而不是完全重做。"#,
新的完整设定结构仍应尽量建立在已有世界方向上,而不是完全重做。"#
}
}
}
@@ -1985,7 +2048,11 @@ fn clamp_text(value: &str, max_length: usize) -> String {
if normalized.chars().count() <= max_length {
return normalized;
}
normalized.chars().take(max_length.saturating_sub(1)).collect::<String>() + ""
normalized
.chars()
.take(max_length.saturating_sub(1))
.collect::<String>()
+ ""
}
fn clamp_progress_percent(value: Option<&JsonValue>) -> u32 {
@@ -1996,7 +2063,8 @@ fn clamp_progress_percent(value: Option<&JsonValue>) -> u32 {
}
fn to_text(value: Option<&JsonValue>) -> Option<String> {
value.and_then(JsonValue::as_str)
value
.and_then(JsonValue::as_str)
.map(str::trim)
.filter(|value| !value.is_empty())
.map(str::to_string)