Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 35 additions & 8 deletions crates/goose/src/providers/formats/openai.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,14 @@ pub fn format_messages(messages: &[Message], image_format: &ImageFormat) -> Vec<
match content {
MessageContent::Text(text) => {
if !text.text.is_empty() {
if let Some(image_path) = detect_image_path(&text.text) {
if let Ok(image) = load_image_file(image_path) {
content_array.push(json!({"type": "text", "text": text.text}));
content_array.push(convert_image(&image, image_format));
if message.role == Role::User {
if let Some(image_path) = detect_image_path(&text.text) {
if let Ok(image) = load_image_file(image_path) {
content_array.push(json!({"type": "text", "text": text.text}));
content_array.push(convert_image(&image, image_format));
} else {
text_array.push(text.text.clone());
}
} else {
text_array.push(text.text.clone());
}
Expand Down Expand Up @@ -204,7 +208,14 @@ pub fn format_messages(messages: &[Message], image_format: &ImageFormat) -> Vec<
MessageContent::ToolConfirmationRequest(_) => {}
MessageContent::ActionRequired(_) => {}
MessageContent::Image(image) => {
content_array.push(convert_image(image, image_format));
if message.role == Role::User {
content_array.push(convert_image(image, image_format));
} else {
content_array.push(json!({
"type": "text",
"text": "[Image content removed - not supported in assistant messages]"
}));
}
}
MessageContent::FrontendToolRequest(request) => match &request.tool_call {
Ok(tool_call) => {
Expand Down Expand Up @@ -1031,9 +1042,9 @@ mod tests {
std::fs::write(&png_path, png_data)?;
let png_path_str = png_path.to_str().unwrap();

// Create message with image path
let message = Message::user().with_text(format!("Here is an image: {}", png_path_str));
let spec = format_messages(&[message], &ImageFormat::OpenAi);
// Create user message with image path - should load the image
let user_message = Message::user().with_text(format!("Here is an image: {}", png_path_str));
let spec = format_messages(&[user_message], &ImageFormat::OpenAi);

assert_eq!(spec.len(), 1);
assert_eq!(spec[0]["role"], "user");
Expand All @@ -1049,6 +1060,22 @@ mod tests {
.unwrap()
.starts_with("data:image/png;base64,"));

// Create assistant message with same text - should NOT load the image
let assistant_message =
Message::assistant().with_text(format!("I saved the output to {}", png_path_str));
let spec = format_messages(&[assistant_message], &ImageFormat::OpenAi);

assert_eq!(spec.len(), 1);
assert_eq!(spec[0]["role"], "assistant");

// Content should be plain text, NOT an array with image
let content = spec[0]["content"].as_str();
assert!(
content.is_some(),
"Assistant message content should be a string, not an array with image"
);
assert!(content.unwrap().contains(png_path_str));

Ok(())
}

Expand Down
Loading