use super::handles::{ResourceHandle, ToolHandle};
use crate::types::Role;
use smallvec::SmallVec;
#[derive(Clone, Debug)]
#[non_exhaustive] pub enum PromptContent {
Text(String),
Image {
data: String,
mime_type: String,
},
ResourceUri(String),
ToolHandle(ToolHandle),
ResourceHandle(ResourceHandle),
Multi(SmallVec<[Box<Self>; 3]>),
}
#[derive(Clone, Debug)]
pub struct InternalPromptMessage {
pub role: Role,
pub content: PromptContent,
}
impl InternalPromptMessage {
pub fn new(role: Role, content: impl Into<PromptContent>) -> Self {
Self {
role,
content: content.into(),
}
}
pub fn text(role: Role, text: impl Into<String>) -> Self {
Self {
role,
content: PromptContent::Text(text.into()),
}
}
pub fn system(text: impl Into<String>) -> Self {
Self::text(Role::System, text)
}
pub fn user(text: impl Into<String>) -> Self {
Self::text(Role::User, text)
}
pub fn assistant(text: impl Into<String>) -> Self {
Self::text(Role::Assistant, text)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_prompt_content_text() {
let content = PromptContent::Text("Hello".to_string());
assert!(matches!(content, PromptContent::Text(_)));
}
#[test]
fn test_prompt_content_image() {
let content = PromptContent::Image {
data: "base64data".to_string(),
mime_type: "image/png".to_string(),
};
assert!(matches!(content, PromptContent::Image { .. }));
}
#[test]
fn test_prompt_content_tool_handle() {
let handle = ToolHandle::new("greet");
let content = PromptContent::ToolHandle(handle);
assert!(matches!(content, PromptContent::ToolHandle(_)));
}
#[test]
fn test_internal_prompt_message_text() {
let msg = InternalPromptMessage::text(Role::User, "Hello");
assert!(matches!(msg.role, Role::User));
assert!(matches!(msg.content, PromptContent::Text(_)));
}
#[test]
fn test_internal_prompt_message_helpers() {
let system_msg = InternalPromptMessage::system("System prompt");
assert!(matches!(system_msg.role, Role::System));
let user_msg = InternalPromptMessage::user("User message");
assert!(matches!(user_msg.role, Role::User));
let assistant_msg = InternalPromptMessage::assistant("Assistant message");
assert!(matches!(assistant_msg.role, Role::Assistant));
}
#[test]
fn test_prompt_content_multi_smallvec() {
let parts = smallvec::smallvec![
Box::new(PromptContent::Text("Part 1".to_string())),
Box::new(PromptContent::Text("Part 2".to_string())),
];
let content = PromptContent::Multi(parts);
if let PromptContent::Multi(parts) = content {
assert_eq!(parts.len(), 2);
} else {
panic!("Expected Multi variant");
}
}
}