首尾换行回到按空白裁剪,不再当控制字符报错
- 回退 3f70c6911 的收紧:optional_text 恢复成先 trim、再查 is_control
- prompt 末尾带 \n(\r\n 等)视为普通首尾空白裁掉,与首尾空格同口径;中间的控制字符仍然报 has_control_characters
- 测试改为断言行尾换行被接受且裁成 "生成过场",另加一条中间换行仍被拒的断言
验证:cargo test --bin genarrative-ai-game-creator-shell -- agent::direct_tool_bridge:: 41 passed / 0 failed
This commit is contained in:
@@ -4898,18 +4898,30 @@ mod tests {
|
||||
GameCreationAppAssetKind::Image
|
||||
);
|
||||
|
||||
let trailing_newline = match resource_generation_input(&json!({
|
||||
assert_eq!(
|
||||
resource_generation_input(&json!({
|
||||
"kind": "video",
|
||||
"mode": "create",
|
||||
"prompt": "生成过场\n",
|
||||
"assetName": "开场"
|
||||
}))
|
||||
.expect("首尾换行按普通空白裁掉,不能报控制字符")
|
||||
.prompt,
|
||||
"生成过场"
|
||||
);
|
||||
|
||||
let interior_newline = match resource_generation_input(&json!({
|
||||
"kind": "video",
|
||||
"mode": "create",
|
||||
"prompt": "生成过场\n",
|
||||
"prompt": "生成\n过场",
|
||||
"assetName": "开场"
|
||||
})) {
|
||||
Ok(_) => panic!("落在首尾的控制字符不能被 trim 静默吞掉"),
|
||||
Ok(_) => panic!("中间的控制字符仍必须被拒绝"),
|
||||
Err(error) => error.to_user_msg(),
|
||||
};
|
||||
assert!(
|
||||
trailing_newline.contains("prompt 含有控制字符"),
|
||||
"{trailing_newline}"
|
||||
interior_newline.contains("prompt 含有控制字符"),
|
||||
"{interior_newline}"
|
||||
);
|
||||
|
||||
let whitespace_only =
|
||||
|
||||
@@ -37,19 +37,17 @@ pub(crate) fn optional_text<F: ToolTextField<E>, E>(
|
||||
let Some(value) = value.as_str() else {
|
||||
return Err(field.not_text(value.to_string()));
|
||||
};
|
||||
let trimmed = value.trim();
|
||||
if trimmed.is_empty() {
|
||||
let value = value.trim();
|
||||
if value.is_empty() {
|
||||
return Err(field.empty());
|
||||
}
|
||||
// 控制字符必须按原串判定:否则落在首尾的 `\n`/`\t` 会被 trim 静默吞掉,
|
||||
// 同一个字符在中间报错、在边上通过。
|
||||
if value.chars().count() > field.max_chars() {
|
||||
return Err(field.too_long(value.chars().count(), field.max_chars()));
|
||||
}
|
||||
if value.chars().any(char::is_control) {
|
||||
return Err(field.has_control_characters());
|
||||
}
|
||||
if trimmed.chars().count() > field.max_chars() {
|
||||
return Err(field.too_long(trimmed.chars().count(), field.max_chars()));
|
||||
}
|
||||
Ok(Some(trimmed.to_string()))
|
||||
Ok(Some(value.to_string()))
|
||||
}
|
||||
|
||||
/// 一页列表结果:`offset` 是起始下标,`limit` 是这一次最多返回多少项。
|
||||
|
||||
Reference in New Issue
Block a user