agc_generate_image 的 kind 传了非字符串不再静默当成 image
- bridge_image_generation_kind 原来用 and_then(Value::as_str)…unwrap_or("image"):{"kind":true}、{"kind":5}、{"kind":[]} 都会被当成 image 继续生成;空串也会被静默当默认值
- 改成按 schema 语义区分:缺省与显式 null 用默认 image;字符串按原值走 canonical 校验(空串/未知值走 KindUnsupported);其它类型返回新的 GenerateImageError::KindNotText { got }
- 测试补四条断言:kind=true 报「kind 必须是字符串」、kind="" 报「不是受支持的素材类型」、缺省与 null 仍解析为 image
验证:cargo test --bin genarrative-ai-game-creator-shell -- agent::direct_tool_bridge:: 41 passed;agent:: tests::project:: 1078 passed(两条失败为既有 flaky:art_director_request_exposes_canvas_only_for_the_keyed_owner_route / background_agent_runtime_can_generate_platform_art_asset,单独重跑通过)
This commit is contained in:
@@ -2900,12 +2900,16 @@ fn generate_image_grid_axis(
|
||||
fn bridge_image_generation_kind(
|
||||
arguments: &Value,
|
||||
) -> Result<GameCreationAppAssetKind, GenerateImageError> {
|
||||
let kind = arguments
|
||||
.get("kind")
|
||||
.and_then(Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.unwrap_or("image");
|
||||
// 缺省与显式 null 用 schema 声明的默认值;给了别的类型不许静默当 image。
|
||||
let kind = match arguments.get("kind") {
|
||||
None | Some(Value::Null) => "image",
|
||||
Some(Value::String(value)) => value.trim(),
|
||||
Some(value) => {
|
||||
return Err(GenerateImageError::KindNotText {
|
||||
got: value.to_string(),
|
||||
})
|
||||
}
|
||||
};
|
||||
normalize_platform_art_asset_generation_kind(kind).ok_or_else(|| {
|
||||
GenerateImageError::KindUnsupported {
|
||||
got: kind.to_string(),
|
||||
@@ -4860,6 +4864,40 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn non_text_field_values_report_a_type_error_instead_of_an_empty_value() {
|
||||
let kind_not_text = match generate_image_input(&json!({
|
||||
"prompt": "像素风主角",
|
||||
"kind": true
|
||||
})) {
|
||||
Ok(_) => panic!("kind 不是字符串时必须被拒绝"),
|
||||
Err(error) => error.to_user_msg(),
|
||||
};
|
||||
assert!(
|
||||
kind_not_text.contains("kind 必须是字符串"),
|
||||
"{kind_not_text}"
|
||||
);
|
||||
|
||||
let kind_empty = match generate_image_input(&json!({
|
||||
"prompt": "像素风主角",
|
||||
"kind": ""
|
||||
})) {
|
||||
Ok(_) => panic!("空 kind 必须被拒绝,不能再静默当 image"),
|
||||
Err(error) => error.to_user_msg(),
|
||||
};
|
||||
assert!(kind_empty.contains("不是受支持的素材类型"), "{kind_empty}");
|
||||
|
||||
assert_eq!(
|
||||
generate_image_input(&json!({ "prompt": "像素风主角" }))
|
||||
.map(|input| input.kind)
|
||||
.expect("缺省 kind 仍默认 image"),
|
||||
GameCreationAppAssetKind::Image
|
||||
);
|
||||
assert_eq!(
|
||||
generate_image_input(&json!({ "prompt": "像素风主角", "kind": null }))
|
||||
.map(|input| input.kind)
|
||||
.expect("显式 null 仍按默认 image"),
|
||||
GameCreationAppAssetKind::Image
|
||||
);
|
||||
|
||||
let trailing_newline = match resource_generation_input(&json!({
|
||||
"kind": "video",
|
||||
"mode": "create",
|
||||
|
||||
@@ -20,6 +20,7 @@ pub(crate) enum GenerateImageError {
|
||||
PromptTooLong { got_chars: usize, max_chars: usize },
|
||||
PromptHasControlCharacters,
|
||||
PromptNotText { got: String },
|
||||
KindNotText { got: String },
|
||||
KindUnsupported { got: String },
|
||||
AspectRatioEmpty,
|
||||
AspectRatioTooLong { got_chars: usize, max_chars: usize },
|
||||
@@ -83,6 +84,9 @@ impl ToolFailure for GenerateImageError {
|
||||
Self::PromptNotText { got } => format!(
|
||||
"生成图片失败:prompt 必须是字符串,当前是「{got}」。"
|
||||
),
|
||||
Self::KindNotText { got } => {
|
||||
format!("生成图片失败:kind 必须是字符串,当前是「{got}」。")
|
||||
}
|
||||
Self::KindUnsupported { got } => format!(
|
||||
"生成图片失败:kind「{got}」不是受支持的素材类型,只允许 {}。",
|
||||
platform_art_asset_generation_kind_list()
|
||||
|
||||
Reference in New Issue
Block a user