非字符串入参的回显截断到 120 字符,不再把整个对象原样带进诊断
- arguments::optional_text 里的 not_text 改为传截断后的序列化值:类型错只需要看出「传了什么」 - got 同时出现在 to_user_msg 与序列化 error 里,限长后工具结果与诊断 sidecar 都不会被超大数组/对象灌爆 - 复用 runtime_state::truncate_agent_runtime_text,不新增第二套截断实现 - 测试补一条:超大数组回显必须带截断标记且长度可控 验证:cargo test --bin genarrative-ai-game-creator-shell -- non_text_field_values 通过;cargo fmt --check 通过
This commit is contained in:
@@ -4965,6 +4965,29 @@ mod tests {
|
||||
);
|
||||
assert!(!prompt_not_text.contains("不能为空"), "{prompt_not_text}");
|
||||
|
||||
let oversized_not_text = match resource_generation_input(&json!({
|
||||
"kind": "video",
|
||||
"mode": "create",
|
||||
"prompt": vec!["需要回显但必须截断的字段内容"; 40],
|
||||
"assetName": "开场"
|
||||
})) {
|
||||
Ok(_) => panic!("prompt 不是字符串时必须被拒绝"),
|
||||
Err(error) => error.to_user_msg(),
|
||||
};
|
||||
assert!(
|
||||
oversized_not_text.contains("prompt 必须是字符串"),
|
||||
"{oversized_not_text}"
|
||||
);
|
||||
assert!(
|
||||
oversized_not_text.contains('…'),
|
||||
"超长回显必须带截断标记:{oversized_not_text}"
|
||||
);
|
||||
assert!(
|
||||
oversized_not_text.chars().count() < 200,
|
||||
"超长回显必须被截断:{}",
|
||||
oversized_not_text.chars().count()
|
||||
);
|
||||
|
||||
let brief_not_text = required_text(&json!({ "brief": 5 }), PrepareGameArtTextField::Brief)
|
||||
.expect_err("brief 不是字符串时必须被拒绝")
|
||||
.to_user_msg();
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
use serde_json::Value;
|
||||
|
||||
use super::error::ToolPageRejection;
|
||||
use crate::agent::runtime_state::truncate_agent_runtime_text;
|
||||
|
||||
/// 字段给了非字符串值时,回显进诊断的那个值最多保留多少字符。
|
||||
///
|
||||
/// 类型错只需要让模型看出「传进来的是什么」,不必把整个对象或数组原样带进工具结果与
|
||||
/// 诊断 sidecar;`got` 会同时出现在 `to_user_msg` 和序列化后的 `error` 里。
|
||||
const NOT_TEXT_GOT_MAX_CHARS: usize = 120;
|
||||
|
||||
/// 一个会被边界校验的文本字段。
|
||||
pub(crate) trait ToolTextField<E>: Copy {
|
||||
@@ -35,7 +42,10 @@ pub(crate) fn optional_text<F: ToolTextField<E>, E>(
|
||||
return Ok(None);
|
||||
};
|
||||
let Some(value) = value.as_str() else {
|
||||
return Err(field.not_text(value.to_string()));
|
||||
return Err(field.not_text(truncate_agent_runtime_text(
|
||||
&value.to_string(),
|
||||
NOT_TEXT_GOT_MAX_CHARS,
|
||||
)));
|
||||
};
|
||||
let value = value.trim();
|
||||
if value.is_empty() {
|
||||
|
||||
Reference in New Issue
Block a user