This commit is contained in:
2026-04-25 22:19:04 +08:00
parent 2ebfd1cf55
commit 8404081d7b
149 changed files with 10508 additions and 2732 deletions

View File

@@ -2,15 +2,18 @@ use module_custom_world::{
empty_agent_anchor_content_json, empty_agent_asset_coverage_json,
empty_agent_creator_intent_readiness_json, empty_json_array, empty_json_object,
};
use platform_llm::{LlmClient, LlmMessage, LlmStreamDelta, LlmTextRequest};
use platform_llm::LlmClient;
use serde::{Deserialize, Serialize};
use serde_json::{Value as JsonValue, json};
use crate::creation_agent_llm_turn::{
CreationAgentLlmTurnErrorMessages, request_creation_agent_json_turn,
stream_creation_agent_json_turn,
};
use crate::custom_world_rpg_draft_prompts::{
BASE_SYSTEM_PROMPT, GLOBAL_HARD_RULES, OUTPUT_CONTRACT_REMINDER,
STATE_INFERENCE_OUTPUT_CONTRACT, STATE_INFERENCE_SYSTEM_PROMPT,
extract_reply_text_from_partial_json, mode_rules, parse_conversation_mode, parse_drift_risk,
parse_json_response_text, parse_user_input_signal, quick_fill_extra_rules,
STATE_INFERENCE_OUTPUT_CONTRACT, STATE_INFERENCE_SYSTEM_PROMPT, mode_rules,
parse_conversation_mode, parse_drift_risk, parse_user_input_signal, quick_fill_extra_rules,
render_chat_history_context, render_current_anchor_context, render_dynamic_state_context,
user_signal_rules,
};
@@ -561,7 +564,7 @@ async fn stream_single_turn<F>(
progress_percent: u32,
quick_fill_requested: bool,
current_anchor_content: &EightAnchorContent,
mut on_reply_update: F,
on_reply_update: F,
) -> Result<SingleTurnModelOutput, CustomWorldTurnError>
where
F: FnMut(&str),
@@ -586,31 +589,20 @@ where
&chat_history,
&dynamic_state,
);
let mut latest_reply_text = String::new();
let response = llm_client
.stream_text(
LlmTextRequest::new(vec![
LlmMessage::system(prompt),
LlmMessage::user("请按约定输出这一轮的 JSON"),
]),
|delta: &LlmStreamDelta| {
if let Some(reply_progress) =
extract_reply_text_from_partial_json(delta.accumulated_text.as_str())
&& reply_progress != latest_reply_text
{
latest_reply_text = reply_progress.clone();
on_reply_update(reply_progress.as_str());
}
},
)
.await;
let response =
response.map_err(|_| CustomWorldTurnError::new("这一轮设定生成失败,请稍后重试。"))?;
let parsed = parse_json_response_text(response.content.as_str())
.map_err(|_| CustomWorldTurnError::new("模型返回结果解析失败,请稍后重试。"))?;
let turn_output = stream_creation_agent_json_turn(
Some(llm_client),
prompt,
"请按约定输出这一轮的 JSON。",
CreationAgentLlmTurnErrorMessages {
model_unavailable: "当前模型不可用,请稍后重试。",
generation_failed: "这一轮设定生成失败,请稍后重试",
parse_failed: "模型返回结果解析失败,请稍后重试。",
},
on_reply_update,
CustomWorldTurnError::new,
)
.await?;
let parsed = turn_output.parsed;
let next_anchor_content =
normalize_eight_anchor_content(parsed.get("nextAnchorContent").unwrap_or(&JsonValue::Null));
@@ -621,9 +613,6 @@ where
};
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());
}
Ok(SingleTurnModelOutput {
next_anchor_content,
@@ -656,16 +645,14 @@ async fn resolve_dynamic_state(
chat_history,
);
let response = llm_client
.request_text(LlmTextRequest::new(vec![
LlmMessage::system(system_prompt),
LlmMessage::user(user_prompt),
]))
.await;
let Ok(response) = response else {
return fallback;
};
let Ok(parsed) = parse_json_response_text(response.content.as_str()) else {
let Ok(parsed) = request_creation_agent_json_turn(
llm_client,
system_prompt,
user_prompt,
CustomWorldTurnError::new,
)
.await
else {
return fallback;
};
build_prompt_dynamic_state(
@@ -1610,7 +1597,7 @@ impl PromptConversationMode {
#[cfg(test)]
mod tests {
use crate::custom_world_rpg_draft_prompts::extract_reply_text_from_partial_json;
use crate::creation_agent_llm_turn::extract_reply_text_from_partial_json;
#[test]
fn extract_reply_text_from_partial_json_preserves_chinese_characters() {