校验联合结果素材引用

拒绝不存在的图片素材组件引用

拒绝不存在的字体绑定引用
This commit is contained in:
2026-09-05 12:58:49 +08:00
parent 7ccc0b8def
commit ebe1aed349
@@ -4,6 +4,7 @@ use crate::ui_editor::commands::utils::{
parse_limited_llm_tool_arguments, read_ui_reference_image_data_url, request_ui_editor_llm,
strict_json_schema,
};
use crate::ui_editor::component::text::FontSource;
use crate::ui_editor::component::Component;
use crate::ui_editor::layout::children_display_mode::ChildrenDisplayMode;
use crate::ui_editor::layout::control_layout::ControlLayout;
@@ -348,6 +349,37 @@ fn validate_confidence(nodes: &[RecognitionNode]) -> Result<(), String> {
Ok(())
}
fn validate_component_references(
nodes: &[RecognitionNode],
known_sprite_ids: &HashSet<crate::ui_editor::utils::SpriteAssetId>,
known_font_ids: &HashSet<crate::ui_editor::utils::FontAssetId>,
) -> Result<(), String> {
for node in nodes {
for component in node.components.as_deref().unwrap_or_default() {
match component {
Component::Image(image) => {
if image
.target_graphic
.as_ref()
.is_some_and(|id| !known_sprite_ids.contains(id))
{
return Err("联合识别绑定引用了不存在的独立素材".to_string());
}
}
Component::Text(text) => {
if let FontSource::Bound(id) = &text.font {
if !known_font_ids.contains(id) {
return Err("联合识别绑定引用了不存在的字体素材".to_string());
}
}
}
}
}
validate_component_references(&node.children, known_sprite_ids, known_font_ids)?;
}
Ok(())
}
fn validate_tree_image_ids(
trees: &[RecognitionTree],
allowed_ids: &[UIDesignImageId],
@@ -694,6 +726,11 @@ pub(crate) async fn recognition_and_binding_impl_with_provider(
let parsed = serde_json::from_value::<RecognitionResponse>(arguments)
.map_err(|error| format!("联合结果参数无效:{error}"))?;
validate_tree_image_ids(&parsed.trees, &context_ids)?;
let known_sprite_ids = state.sprite_assets.keys().cloned().collect::<HashSet<_>>();
let known_font_ids = state.font_assets.keys().cloned().collect::<HashSet<_>>();
for tree in &parsed.trees {
validate_component_references(&tree.children, &known_sprite_ids, &known_font_ids)?;
}
let mut ui_trees = Vec::with_capacity(parsed.trees.len());
for tree in parsed.trees {
let image = state