mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Support original-detail metadata on MCP image outputs (#17714)
## Summary - honor `_meta["codex/imageDetail"] == "original"` on MCP image content and map it to `detail: "original"` where supported - strip that detail back out when the active model does not support original-detail image inputs - update code-mode `image(...)` to accept individual MCP image blocks - teach `js_repl` / `codex.emitImage(...)` to preserve the same hint from raw MCP image outputs - document the new `_meta` contract and add generic RMCP-backed coverage across protocol, core, code-mode, and js_repl paths
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use codex_protocol::models::FunctionCallOutputContentItem;
|
||||
use codex_protocol::models::ImageDetail;
|
||||
use codex_protocol::openai_models::ModelInfo;
|
||||
|
||||
@@ -17,6 +18,23 @@ pub fn normalize_output_image_detail(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sanitize_original_image_detail(
|
||||
can_request_original_image_detail: bool,
|
||||
items: &mut [FunctionCallOutputContentItem],
|
||||
) {
|
||||
if can_request_original_image_detail {
|
||||
return;
|
||||
}
|
||||
|
||||
for item in items {
|
||||
if let FunctionCallOutputContentItem::InputImage { detail, .. } = item
|
||||
&& matches!(detail, Some(ImageDetail::Original))
|
||||
{
|
||||
*detail = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "image_detail_tests.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use super::*;
|
||||
use codex_protocol::models::FunctionCallOutputContentItem;
|
||||
use codex_protocol::models::ImageDetail;
|
||||
use codex_protocol::openai_models::ModelInfo;
|
||||
use pretty_assertions::assert_eq;
|
||||
@@ -73,3 +74,39 @@ fn unsupported_non_original_detail_is_dropped() {
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sanitize_original_drops_original_without_support() {
|
||||
let mut items = vec![
|
||||
FunctionCallOutputContentItem::InputText {
|
||||
text: "header".to_string(),
|
||||
},
|
||||
FunctionCallOutputContentItem::InputImage {
|
||||
image_url: "data:image/png;base64,AAA".to_string(),
|
||||
detail: Some(ImageDetail::Original),
|
||||
},
|
||||
FunctionCallOutputContentItem::InputImage {
|
||||
image_url: "data:image/png;base64,BBB".to_string(),
|
||||
detail: Some(ImageDetail::Low),
|
||||
},
|
||||
];
|
||||
|
||||
sanitize_original_image_detail(/*can_request_original_image_detail*/ false, &mut items);
|
||||
|
||||
assert_eq!(
|
||||
items,
|
||||
vec![
|
||||
FunctionCallOutputContentItem::InputText {
|
||||
text: "header".to_string(),
|
||||
},
|
||||
FunctionCallOutputContentItem::InputImage {
|
||||
image_url: "data:image/png;base64,AAA".to_string(),
|
||||
detail: None,
|
||||
},
|
||||
FunctionCallOutputContentItem::InputImage {
|
||||
image_url: "data:image/png;base64,BBB".to_string(),
|
||||
detail: Some(ImageDetail::Low),
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ pub use codex_protocol::ToolName;
|
||||
pub use dynamic_tool::parse_dynamic_tool;
|
||||
pub use image_detail::can_request_original_image_detail;
|
||||
pub use image_detail::normalize_output_image_detail;
|
||||
pub use image_detail::sanitize_original_image_detail;
|
||||
pub use js_repl_tool::create_js_repl_reset_tool;
|
||||
pub use js_repl_tool::create_js_repl_tool;
|
||||
pub use json_schema::AdditionalProperties;
|
||||
|
||||
Reference in New Issue
Block a user