diff --git a/docs/openapi/genarrative-external-v1.openapi.json b/docs/openapi/genarrative-external-v1.openapi.json index e4f67a56b..74a73eba0 100644 --- a/docs/openapi/genarrative-external-v1.openapi.json +++ b/docs/openapi/genarrative-external-v1.openapi.json @@ -4945,7 +4945,7 @@ } }, "additionalProperties": true, - "description": "其它生成类型或历史结果的兼容 compact result。该 fallback 明确排除 audioKind=sound-effect,避免吞掉 SFX 专用分支。" + "description": "其它生成类型或历史结果的兼容 compact result。背景音乐(audioKind=background-music)与不带 audioKind 的图片、视频、图标序列帧、角色动作和 UI 拆解结果都落在这里。该 fallback 明确排除 audioKind=sound-effect,避免吞掉 SFX 专用分支。" }, "ExternalEditorGenerationCompletedResult": { "oneOf": [ @@ -4956,13 +4956,7 @@ "$ref": "#/components/schemas/ExternalEditorGenerationGenericCompactResult" } ], - "discriminator": { - "propertyName": "audioKind", - "mapping": { - "sound-effect": "#/components/schemas/ExternalEditorSoundEffectCompactResult" - } - }, - "description": "External v1 轮询 completed 状态的命名 compact result 联合。" + "description": "External v1 轮询 completed 状态的命名 compact result 联合。两个分支已由 audioKind 的 const 与 not 精确互斥,不使用 discriminator:背景音乐返回 audioKind=background-music,图片、视频、图标序列帧、角色动作、UI 拆解与历史结果根本没有 audioKind,它们都无法映射到具名分支,且 fallback 分支不可能把 audioKind 声明为必填,因此任何 discriminator 映射都不可能覆盖全部合法结果。" }, "ExternalEditorGenerationSubmissionResponse": { "type": "object", diff --git a/server-rs/crates/api-server/src/external_editor_api.rs b/server-rs/crates/api-server/src/external_editor_api.rs index 83c43bf39..2deed567d 100644 --- a/server-rs/crates/api-server/src/external_editor_api.rs +++ b/server-rs/crates/api-server/src/external_editor_api.rs @@ -2179,13 +2179,11 @@ mod tests { completed_result["oneOf"][1]["$ref"], "#/components/schemas/ExternalEditorGenerationGenericCompactResult" ); - assert_eq!( - completed_result["discriminator"]["propertyName"], - "audioKind" - ); - assert_eq!( - completed_result["discriminator"]["mapping"]["sound-effect"], - "#/components/schemas/ExternalEditorSoundEffectCompactResult" + assert!( + completed_result.get("discriminator").is_none(), + "completed result 联合不能带 discriminator:BGM 回 audioKind=background-music,图片、\ + 视频与历史结果没有 audioKind,而 fallback 分支不可能把 audioKind 声明为必填,\ + 任何映射都覆盖不全合法结果" ); let sound_effect_result = &parsed["components"]["schemas"]["ExternalEditorSoundEffectCompactResult"]; @@ -2230,6 +2228,19 @@ mod tests { generic_result["not"]["properties"]["audioKind"]["const"], "sound-effect" ); + assert_eq!( + generic_result["not"]["properties"] + .as_object() + .map(serde_json::Map::len), + Some(1), + "fallback 只能排除 SFX 一种 audioKind;再排除别的值会把 BGM 等合法结果挤出联合" + ); + assert!( + generic_result["not"]["properties"]["audioKind"] + .get("enum") + .is_none(), + "排除条件必须是 const sound-effect,换成 enum 会连带排掉 BGM" + ); assert!( parsed["paths"] .get("/api/external/v1/editor/audios/background-music/generations")