抠图背景色只作内部 screenColorHex 元数据,不再暴露进用户可见 fields

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 <noreply@anthropic.com>
This commit is contained in:
2026-07-09 03:52:43 +00:00
parent 578313050e
commit b8c2efaf24
2 changed files with 11 additions and 38 deletions
@@ -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"));
}
@@ -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\"}。不要解释,不要返回候选列表外的颜色。"
}