From b8c2efaf2496293d1ef04f4432833a14acebad09 Mon Sep 17 00:00:00 2001 From: Linghong Date: Thu, 9 Jul 2026 03:52:43 +0000 Subject: [PATCH] =?UTF-8?q?=E6=8A=A0=E5=9B=BE=E8=83=8C=E6=99=AF=E8=89=B2?= =?UTF-8?q?=E5=8F=AA=E4=BD=9C=E5=86=85=E9=83=A8=20screenColorHex=20?= =?UTF-8?q?=E5=85=83=E6=95=B0=E6=8D=AE=EF=BC=8C=E4=B8=8D=E5=86=8D=E6=9A=B4?= =?UTF-8?q?=E9=9C=B2=E8=BF=9B=E7=94=A8=E6=88=B7=E5=8F=AF=E8=A7=81=20fields?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit apply_editor_screen_background_decision_to_generation_inputs 之前会往 generationInputs.fields 追加「抠图背景色」条目,把内部自动决策/兜底细节 暴露给用户,违反「用户可见输入快照不记录抠图背景色/抠图模型」的产品契约(P2)。 - 去掉 fields 注入,只保留顶层内部可追踪元数据 screenColorHex(不进用户快照)。 - 删除因此变成死代码的 format_editor_screen_background_decision_input 及其 import。 - 重写两个单测:断言 fields 不被注入/不被修改,只写 screenColorHex。 Co-Authored-By: Claude Opus 4.8 --- .../crates/api-server/src/editor_project.rs | 33 +++++++------------ .../src/editor_screen_background_decision.rs | 16 --------- 2 files changed, 11 insertions(+), 38 deletions(-) diff --git a/server-rs/crates/api-server/src/editor_project.rs b/server-rs/crates/api-server/src/editor_project.rs index eea999ee6..029e9ff85 100644 --- a/server-rs/crates/api-server/src/editor_project.rs +++ b/server-rs/crates/api-server/src/editor_project.rs @@ -64,8 +64,7 @@ use crate::{ }, editor_screen_background_decision::{ EditorScreenBackgroundDecision, EditorScreenBackgroundDecisionInput, - EditorScreenBackgroundDecisionKind, format_editor_screen_background_decision_input, - resolve_editor_screen_background_color, + EditorScreenBackgroundDecisionKind, resolve_editor_screen_background_color, }, generated_image_assets::{ GeneratedImageAssetAdapter, GeneratedImageAssetDataUrl, @@ -1673,18 +1672,8 @@ pub(crate) fn apply_editor_screen_background_decision_to_generation_inputs( Some(other) => return Some(other), None => json!({ "fields": [], "references": [] }), }; - let resolved_value = format_editor_screen_background_decision_input(decision); - if let Some(fields) = value.get_mut("fields").and_then(Value::as_array_mut) { - if let Some(field) = fields - .iter_mut() - .find(|field| field.get("title").and_then(Value::as_str) == Some("抠图背景色")) - { - field["value"] = Value::String(resolved_value); - } else { - fields.push(json!({ "title": "抠图背景色", "value": resolved_value })); - } - } - // 结构化背景色,供旧背景色先验等程序化消费;展示字段的中文格式不可作解析依据。 + // 抠图背景色是内部自动决策 / 兜底细节,产品契约要求不进用户可见的 generationInputs.fields; + // 只写顶层内部可追踪元数据 screenColorHex(不属于用户输入快照,前端展示不读取)。 value["screenColorHex"] = Value::String(decision.color.hex.to_string()); Some(value) } @@ -5680,9 +5669,10 @@ mod tests { } #[test] - fn screen_background_decision_generation_inputs_record_structured_hex() { + fn screen_background_decision_records_hex_without_touching_visible_fields() { let decision = manual_screen_background_decision("#B0C2E0"); + // 用户可见的 fields 不被注入抠图背景色,只写内部 screenColorHex。 let updated = apply_editor_screen_background_decision_to_generation_inputs( Some(json!({ "fields": [{ "title": "角色设定", "value": "红发骑士" }], @@ -5694,19 +5684,17 @@ mod tests { assert_eq!(updated["screenColorHex"], json!("#B0C2E0")); assert_eq!( updated["fields"], - json!([ - { "title": "角色设定", "value": "红发骑士" }, - { "title": "抠图背景色", "value": "浅钢蓝 #B0C2E0" }, - ]), + json!([{ "title": "角色设定", "value": "红发骑士" }]), ); + // 无 generation_inputs 时创建骨架并写入内部元数据,fields 保持为空。 let created = apply_editor_screen_background_decision_to_generation_inputs(None, Some(&decision)) .expect("missing generation inputs should still record the decision"); assert_eq!( created, json!({ - "fields": [{ "title": "抠图背景色", "value": "浅钢蓝 #B0C2E0" }], + "fields": [], "references": [], "screenColorHex": "#B0C2E0", }), @@ -5714,9 +5702,10 @@ mod tests { } #[test] - fn screen_background_decision_generation_inputs_overwrite_existing_display_field() { + fn screen_background_decision_leaves_existing_visible_fields_untouched() { let decision = manual_screen_background_decision("#CFEFFF"); + // 即使旧数据的 fields 里残留了抠图背景色,后端也不修改用户可见字段。 let updated = apply_editor_screen_background_decision_to_generation_inputs( Some(json!({ "fields": [{ "title": "抠图背景色", "value": "旧值" }], @@ -5727,7 +5716,7 @@ mod tests { .expect("generation inputs should be preserved"); assert_eq!( updated["fields"], - json!([{ "title": "抠图背景色", "value": "浅雾蓝 #CFEFFF" }]), + json!([{ "title": "抠图背景色", "value": "旧值" }]), ); assert_eq!(updated["screenColorHex"], json!("#CFEFFF")); } diff --git a/server-rs/crates/api-server/src/editor_screen_background_decision.rs b/server-rs/crates/api-server/src/editor_screen_background_decision.rs index 48c47c27f..12f2bb8a1 100644 --- a/server-rs/crates/api-server/src/editor_screen_background_decision.rs +++ b/server-rs/crates/api-server/src/editor_screen_background_decision.rs @@ -278,22 +278,6 @@ pub(crate) fn is_auto_screen_background_color(value: Option<&str>) -> bool { .unwrap_or(true) } -pub(crate) fn format_editor_screen_background_decision_input( - decision: &EditorScreenBackgroundDecision, -) -> String { - let resolved = format!("{} {}", decision.color.label, decision.color.hex); - match decision.mode { - EditorScreenBackgroundDecisionMode::Manual => resolved, - EditorScreenBackgroundDecisionMode::Auto => { - if decision.fallback { - format!("自动 -> {resolved}(兜底)") - } else { - format!("自动 -> {resolved}") - } - } - } -} - fn editor_screen_background_decision_system_prompt() -> &'static str { "你是游戏素材生图的抠图背景色决策器。根据任务和用户输入,从候选列表中选择一个最不容易与主体混淆、最适合后续扣除的纯色背景。如果附带了主体参考图,必须以图中主体(含服饰、道具、光效)的实际配色为准,选择色相距离最远的候选色,忽略图中已有的背景或透明区域。只能返回 JSON:{\"hex\":\"#RRGGBB\"}。不要解释,不要返回候选列表外的颜色。" }