Harden PII redaction format conversion

This commit is contained in:
elky
2026-06-14 20:36:57 +08:00
parent 68038c182b
commit 669636d3e4
15 changed files with 813 additions and 285 deletions
@@ -723,15 +723,13 @@ mod tests {
"file": {"file_data": "data:application/pdf;base64,JVBERi0x"}
}),
json!({"type": "text", "text": "[File: https://example.com/report.pdf]"}),
json!({
"type": "text",
"text": "[Claude tool_result document content omitted: text/plain]"
}),
json!({"type": "text", "text": "document body"}),
]
);
let block_content_json = Value::Array(block_content.clone()).to_string();
assert!(!block_content_json.contains("\"source\""));
assert!(!block_content_json.contains("document body"));
assert!(block_content_json.contains("document body"));
assert!(!block_content_json.contains("content omitted"));
}
#[test]
@@ -960,4 +958,90 @@ mod tests {
"data:image/png;base64,AAAA"
);
}
#[test]
fn claude_request_to_responses_rejects_unrepresentable_tool_result_blocks() {
let body = json!({
"model": "claude-sonnet",
"messages": [{
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": "toolu_read",
"content": [{
"type": "image",
"source": {
"type": "unsupported",
"media_type": "image/png",
"data": "AAAA"
}
}]
}]
}],
"max_tokens": 128,
});
let error = registry::convert_request(
"claude:messages",
"openai:responses",
&body,
&FormatContext::default(),
)
.expect_err("unrepresentable Claude tool_result block should fail closed");
assert!(matches!(
error,
registry::FormatError::LossyConversionBlocked {
ref source_format,
ref target_format,
ref field,
..
} if source_format == "claude:messages"
&& target_format == "openai:responses"
&& field == "messages[].content[].tool_result.content"
));
}
#[test]
fn claude_request_to_openai_chat_rejects_unrepresentable_tool_result_blocks() {
let body = json!({
"model": "claude-sonnet",
"messages": [{
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": "toolu_read",
"content": [{
"type": "image",
"source": {
"type": "unsupported",
"media_type": "image/png",
"data": "AAAA"
}
}]
}]
}],
"max_tokens": 128,
});
let error = registry::convert_request(
"claude:messages",
"openai:chat",
&body,
&FormatContext::default(),
)
.expect_err("unrepresentable Claude tool_result block should fail closed for Chat");
assert!(matches!(
error,
registry::FormatError::LossyConversionBlocked {
ref source_format,
ref target_format,
ref field,
..
} if source_format == "claude:messages"
&& target_format == "openai:chat"
&& field == "messages[].content[].tool_result.content"
));
}
}