Skip to content
Open
Show file tree
Hide file tree
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
48 changes: 48 additions & 0 deletions crates/goose-providers/src/image.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};

#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ImageFormat {
OpenAi,
Anthropic,
}

pub fn convert_image(data: &str, mime_type: &str, image_format: &ImageFormat) -> Value {
match image_format {
ImageFormat::OpenAi => json!({
"type": "image_url",
"image_url": {
"url": format!("data:{};base64,{}", mime_type, data)
}
}),
ImageFormat::Anthropic => json!({
"type": "image",
"source": {
"type": "base64",
"media_type": mime_type,
"data": data,
}
}),
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -17,4 +37,32 @@ mod tests {
let decoded: ImageFormat = serde_json::from_str(&encoded).unwrap();
assert_eq!(decoded, ImageFormat::OpenAi);
}

#[test]
fn converts_image_to_openai_payload() {
assert_eq!(
convert_image("abc123", "image/png", &ImageFormat::OpenAi),
serde_json::json!({
"type": "image_url",
"image_url": {
"url": "data:image/png;base64,abc123"
}
})
);
}

#[test]
fn converts_image_to_anthropic_payload() {
assert_eq!(
convert_image("abc123", "image/png", &ImageFormat::Anthropic),
serde_json::json!({
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "abc123",
}
})
);
}
}
19 changes: 2 additions & 17 deletions crates/goose/src/providers/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,13 @@ pub use goose_types::{
};
use rmcp::model::{AnnotateAble, ImageContent, RawImageContent};
use serde::Serialize;
use serde_json::{json, Value};
use serde_json::Value;
use std::io::Read;
use std::path::Path;

/// Convert an image content into an image json based on format
pub fn convert_image(image: &ImageContent, image_format: &ImageFormat) -> Value {
match image_format {
ImageFormat::OpenAi => json!({
"type": "image_url",
"image_url": {
"url": format!("data:{};base64,{}", image.mime_type, image.data)
}
}),
ImageFormat::Anthropic => json!({
"type": "image",
"source": {
"type": "base64",
"media_type": image.mime_type,
"data": image.data,
}
}),
}
goose_providers::image::convert_image(&image.data, &image.mime_type, image_format)
}

/// Check if a file is actually an image by examining its magic bytes
Expand Down