过滤 DirectProject 上下文用户消息

识别 Codex 环境与上下文标签形式的 user item

补充无 passthrough 元数据的回归测试
This commit is contained in:
2026-09-07 10:51:34 +08:00
parent 86d74033c0
commit 0b0d48d9b4
@@ -15,6 +15,16 @@ const DIRECT_PROJECT_INTERNAL_CONTEXT_KINDS: &[&str] = &[
"environments.environment_context",
];
const DIRECT_PROJECT_CONTEXTUAL_USER_TEXT_MARKERS: &[(&str, &str)] = &[
("<environment_context>", "</environment_context>"),
("<skill>", "</skill>"),
("<user_shell_command>", "</user_shell_command>"),
("<turn_aborted>", "</turn_aborted>"),
("<subagent_notification>", "</subagent_notification>"),
("<recommended_plugins>", "</recommended_plugins>"),
("<goal_context>", "</goal_context>"),
];
pub(crate) fn is_direct_project_internal_context_item(item: &Value) -> bool {
if matches!(
item.get("role").and_then(Value::as_str),
@@ -22,7 +32,8 @@ pub(crate) fn is_direct_project_internal_context_item(item: &Value) -> bool {
) {
return true;
}
item.pointer("/internal_chat_message_metadata_passthrough/content_item_kinds")
if item
.pointer("/internal_chat_message_metadata_passthrough/content_item_kinds")
.and_then(Value::as_array)
.is_some_and(|kinds| {
kinds
@@ -30,6 +41,22 @@ pub(crate) fn is_direct_project_internal_context_item(item: &Value) -> bool {
.filter_map(Value::as_str)
.any(|kind| DIRECT_PROJECT_INTERNAL_CONTEXT_KINDS.contains(&kind))
})
{
return true;
}
item.get("content")
.and_then(Value::as_array)
.is_some_and(|parts| {
parts.iter().any(|part| {
let Some(text) = part.get("text").and_then(Value::as_str) else {
return false;
};
let text = text.trim();
DIRECT_PROJECT_CONTEXTUAL_USER_TEXT_MARKERS
.iter()
.any(|(start, end)| text.starts_with(start) && text.ends_with(end))
})
})
}
fn history_path(root: &Path) -> PathBuf {
@@ -96,7 +123,9 @@ fn find_direct_project_history_item_by_id_at(
}
if !pending.is_empty() {
if let Some(item) = direct_project_history_item_from_line(path, &pending)? {
// The append path repairs an unterminated final JSONL record before
// writing. A duplicate scan must not reject that repairable tail.
if let Ok(Some(item)) = direct_project_history_item_from_line(path, &pending) {
if item.get("id").and_then(Value::as_str) == Some(item_id) {
return Ok(Some(item));
}
@@ -302,4 +331,24 @@ mod tests {
}
})));
}
#[test]
fn filters_codex_contextual_user_item_without_passthrough_metadata() {
assert!(is_direct_project_internal_context_item(&json!({
"type": "message",
"role": "user",
"content": [{
"type": "input_text",
"text": "<environment_context>\n<cwd>/tmp/project</cwd>\n</environment_context>"
}]
})));
assert!(!is_direct_project_internal_context_item(&json!({
"type": "message",
"role": "user",
"content": [{
"type": "input_text",
"text": "请读取 <environment_context> 中的说明"
}]
})));
}
}