限制 DirectProject inline 附件数量

为 canonical 附件增加独立的八个条目上限。

补充超限附件拒绝测试,避免绕过素材引用数量门禁。
This commit is contained in:
2026-09-18 14:03:30 +08:00
parent 6b13d1d613
commit 37d45d2de8
@@ -4,6 +4,7 @@ use super::model::{
};
use crate::agent::{
read_manifest_for_project, sanitize_attachment_local_path, GameCreationAppManifest,
MAX_DIRECT_CODEX_ATTACHMENTS,
};
use std::path::Path;
@@ -27,6 +28,7 @@ pub(crate) fn validate_direct_codex_user_item(
}
let manifest = read_manifest_for_project(root)?;
let mut reference_count = 0usize;
let mut attachment_count = 0usize;
for part in &message.content {
match part {
DirectCodexUserContentPart::InputText { .. } => {}
@@ -39,6 +41,12 @@ pub(crate) fn validate_direct_codex_user_item(
validate_runtime_region_reference(&manifest, reference)?;
}
DirectCodexUserContentPart::AgcAttachmentReference(reference) => {
attachment_count = attachment_count.saturating_add(1);
if attachment_count > MAX_DIRECT_CODEX_ATTACHMENTS {
return Err(format!(
"一次最多携带 {MAX_DIRECT_CODEX_ATTACHMENTS} 个附件"
));
}
if reference.name.trim().is_empty() {
return Err("附件缺少文件名".to_string());
}
@@ -107,8 +115,9 @@ fn validate_runtime_region_reference(
#[cfg(test)]
mod tests {
use super::content_has_meaningful_input;
use super::{content_has_meaningful_input, validate_direct_codex_user_item};
use crate::agent::direct_codex_user_item::model::DirectCodexUserContentPart;
use serde_json::json;
fn input_text(text: &str) -> DirectCodexUserContentPart {
DirectCodexUserContentPart::InputText {
@@ -148,4 +157,33 @@ mod tests {
},
]));
}
#[test]
fn inline_attachment_count_is_bounded_independently() {
let root = tempfile::tempdir().expect("temp project");
crate::init_local_game_project_at(root.path(), "validation-test", "校验测试")
.expect("init project");
let content = (0..=crate::agent::MAX_DIRECT_CODEX_ATTACHMENTS)
.map(|index| {
json!({
"type": "agc_attachment_reference",
"name": format!("attachment-{index}.txt"),
"mediaType": "text/plain",
"size": 1,
"localPath": "",
"status": "failed"
})
})
.collect::<Vec<_>>();
let item = serde_json::from_value(json!({
"type": "message",
"role": "user",
"content": content,
"id": "turn-1:user"
}))
.expect("deserialize user item");
let error = validate_direct_codex_user_item(root.path(), &item)
.expect_err("too many inline attachments must be rejected");
assert!(error.contains("最多携带"), "{error}");
}
}