Refactor server-rs runtime and update related docs

This commit is contained in:
2026-04-25 14:29:44 +08:00
parent 019dd9efba
commit 6be3afe45a
56 changed files with 1561 additions and 1158 deletions

View File

@@ -63,6 +63,9 @@ use crate::{
generate_custom_world_foundation_draft,
},
http_error::AppError,
prompt::scene_background::{
SceneActBackgroundPromptParams, build_scene_act_background_image_prompt,
},
request_context::RequestContext,
state::AppState,
};
@@ -1598,7 +1601,7 @@ async fn generate_draft_foundation_act_backgrounds(
act_ref.scene_id.as_str(),
act_ref.scene_name.as_str(),
act_ref.scene_description.as_str(),
act_ref.prompt.as_str(),
act_ref.scene_image_prompt.as_str(),
)
.await
};
@@ -1772,9 +1775,13 @@ struct SceneActGenerationRef {
scene_name: String,
scene_description: String,
prompt: String,
scene_image_prompt: String,
}
fn collect_scene_act_refs(draft_profile: &Value) -> Vec<SceneActGenerationRef> {
let world_name =
json_text_from_value(draft_profile, "name").unwrap_or_else(|| "未命名世界".to_string());
let world_tone = json_text_from_value(draft_profile, "tone").unwrap_or_default();
let scene_context_by_id = collect_scene_context_by_id(draft_profile);
draft_profile
.get("sceneChapterBlueprints")
@@ -1800,9 +1807,10 @@ fn collect_scene_act_refs(draft_profile: &Value) -> Vec<SceneActGenerationRef> {
description: json_text_from_value(chapter, "description")
.or_else(|| json_text_from_value(chapter, "summary"))
.unwrap_or_default(),
danger_level: json_text_from_value(chapter, "dangerLevel").unwrap_or_default(),
});
let scene_contexts = scene_context_by_id.clone();
let world_name = world_name.clone();
let world_tone = world_tone.clone();
chapter
.get("acts")
.and_then(Value::as_array)
@@ -1838,8 +1846,31 @@ fn collect_scene_act_refs(draft_profile: &Value) -> Vec<SceneActGenerationRef> {
id: act_scene_id.clone(),
name: scene_name,
description: chapter_scene_context.description.clone(),
danger_level: chapter_scene_context.danger_level.clone(),
});
let title = json_text_from_value(act, "title")
.unwrap_or_else(|| format!("{}", act_index + 1));
let summary = json_text_from_value(act, "summary").unwrap_or_default();
let act_goal = json_text_from_value(act, "actGoal").unwrap_or_default();
let transition_hook =
json_text_from_value(act, "transitionHook").unwrap_or_default();
let primary_role_name = json_first_text_from_value(
act,
&["primaryRoleName", "primaryRole", "mainRoleName"],
)
.unwrap_or_default();
let scene_image_prompt =
build_scene_act_background_image_prompt(SceneActBackgroundPromptParams {
world_name: world_name.as_str(),
world_tone: world_tone.as_str(),
scene_name: scene_context.name.as_str(),
title: title.as_str(),
summary: summary.as_str(),
act_goal: act_goal.as_str(),
transition_hook: transition_hook.as_str(),
primary_role_name: primary_role_name.as_str(),
support_role_names: collect_scene_act_support_role_names(act),
prompt_text: prompt.as_str(),
});
SceneActGenerationRef {
chapter_index,
@@ -1847,19 +1878,18 @@ fn collect_scene_act_refs(draft_profile: &Value) -> Vec<SceneActGenerationRef> {
scene_id: act_scene_id,
scene_name: scene_context.name,
scene_description: scene_context.description,
prompt: prompt.clone(),
prompt,
scene_image_prompt,
}
})
})
.collect()
}
#[derive(Clone, Debug)]
struct SceneImageContext {
id: String,
name: String,
description: String,
danger_level: String,
}
fn collect_scene_context_by_id(draft_profile: &Value) -> BTreeMap<String, SceneImageContext> {
@@ -1895,10 +1925,26 @@ fn scene_context_from_object(
description: read_string_field(object, "description")
.or_else(|| read_string_field(object, "visualDescription"))
.unwrap_or_default(),
danger_level: read_string_field(object, "dangerLevel").unwrap_or_default(),
})
}
fn collect_scene_act_support_role_names(act: &Value) -> Vec<String> {
// 兼容旧 Node 自动资产链路可能写入的 supportRoleNames也兼容单字段字符串避免迁移后丢上下文。
let mut names = act
.get("supportRoleNames")
.and_then(Value::as_array)
.into_iter()
.flatten()
.filter_map(Value::as_str)
.map(str::trim)
.filter(|value| !value.is_empty())
.map(ToOwned::to_owned)
.collect::<Vec<_>>();
names.extend(json_text_from_value(act, "supportRoleName"));
names.extend(json_text_from_value(act, "supportRoles"));
names
}
fn validate_scene_act_background_prompts(act_refs: &[SceneActGenerationRef]) -> Result<(), String> {
if let Some(act_ref) = act_refs.iter().find(|act_ref| act_ref.prompt.is_empty()) {
return Err(format!(
@@ -2664,8 +2710,7 @@ mod tests {
{
"id": "scene-office",
"name": "旧港办公室",
"description": "旧港边缘的玻璃办公室,窗外能看到潮湿码头。",
"dangerLevel": "low"
"description": "旧港边缘的玻璃办公室,窗外能看到潮湿码头。"
}
],
"sceneChapterBlueprints": [