mirror of
https://github.com/openai/codex.git
synced 2026-11-12 21:20:34 +00:00
core: route view_image through a sandbox-backed fs helper
This commit is contained in:
@@ -14,6 +14,7 @@ use crate::function_tool::FunctionCallError;
|
||||
use crate::original_image_detail::can_request_original_image_detail;
|
||||
use crate::protocol::EventMsg;
|
||||
use crate::protocol::ViewImageToolCallEvent;
|
||||
use crate::sandboxed_fs;
|
||||
use crate::tools::context::ToolInvocation;
|
||||
use crate::tools::context::ToolOutput;
|
||||
use crate::tools::context::ToolPayload;
|
||||
@@ -93,36 +94,6 @@ impl ToolHandler for ViewImageHandler {
|
||||
AbsolutePathBuf::try_from(turn.resolve_path(Some(args.path))).map_err(|error| {
|
||||
FunctionCallError::RespondToModel(format!("unable to resolve image path: {error}"))
|
||||
})?;
|
||||
|
||||
let metadata = turn
|
||||
.environment
|
||||
.get_filesystem()
|
||||
.get_metadata(&abs_path)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
FunctionCallError::RespondToModel(format!(
|
||||
"unable to locate image at `{}`: {error}",
|
||||
abs_path.display()
|
||||
))
|
||||
})?;
|
||||
|
||||
if !metadata.is_file {
|
||||
return Err(FunctionCallError::RespondToModel(format!(
|
||||
"image path `{}` is not a file",
|
||||
abs_path.display()
|
||||
)));
|
||||
}
|
||||
let file_bytes = turn
|
||||
.environment
|
||||
.get_filesystem()
|
||||
.read_file(&abs_path)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
FunctionCallError::RespondToModel(format!(
|
||||
"unable to read image at `{}`: {error}",
|
||||
abs_path.display()
|
||||
))
|
||||
})?;
|
||||
let event_path = abs_path.to_path_buf();
|
||||
|
||||
let can_request_original_detail =
|
||||
@@ -135,14 +106,23 @@ impl ToolHandler for ViewImageHandler {
|
||||
PromptImageMode::ResizeToFit
|
||||
};
|
||||
let image_detail = use_original_detail.then_some(ImageDetail::Original);
|
||||
let image_bytes = sandboxed_fs::read_file(&session, &turn, abs_path.as_path())
|
||||
.await
|
||||
.map_err(|error| {
|
||||
FunctionCallError::RespondToModel(render_view_image_read_error(
|
||||
abs_path.as_path(),
|
||||
&error,
|
||||
))
|
||||
})?;
|
||||
|
||||
let image =
|
||||
load_for_prompt_bytes(abs_path.as_path(), file_bytes, image_mode).map_err(|error| {
|
||||
let image = load_for_prompt_bytes(abs_path.as_path(), image_bytes, image_mode).map_err(
|
||||
|error| {
|
||||
FunctionCallError::RespondToModel(format!(
|
||||
"unable to process image at `{}`: {error}",
|
||||
abs_path.display()
|
||||
))
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
let image_url = image.into_data_url();
|
||||
|
||||
session
|
||||
@@ -201,6 +181,33 @@ impl ToolOutput for ViewImageOutput {
|
||||
}
|
||||
}
|
||||
|
||||
fn render_view_image_read_error(
|
||||
path: &std::path::Path,
|
||||
error: &sandboxed_fs::SandboxedFsError,
|
||||
) -> String {
|
||||
let operation_message = error
|
||||
.operation_error_message()
|
||||
.map(str::to_owned)
|
||||
.unwrap_or_else(|| error.to_string());
|
||||
match error.operation_error_kind() {
|
||||
Some(codex_fs_ops::FsErrorKind::IsADirectory) => {
|
||||
format!("image path `{}` is not a file", path.display())
|
||||
}
|
||||
Some(codex_fs_ops::FsErrorKind::NotFound) => {
|
||||
format!(
|
||||
"unable to locate image at `{}`: {operation_message}",
|
||||
path.display()
|
||||
)
|
||||
}
|
||||
Some(_) | None => {
|
||||
format!(
|
||||
"unable to read image at `{}`: {operation_message}",
|
||||
path.display()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user