use async_openai::types::chat::{ChatCompletionRequestAssistantMessage, ChatCompletionRequestAssistantMessageContent, ChatCompletionRequestMessage, ChatCompletionRequestSystemMessage, ChatCompletionRequestSystemMessageContent, ChatCompletionRequestUserMessage, ChatCompletionRequestUserMessageContent}; use ratatui::style::{self, Style}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum ConversationEntry { User(String), Eva(String), ShipComputer(String), StageDirection(String), #[serde(skip)] SystemMessage(String) } impl ConversationEntry { pub fn prefix(&self) -> Option<&str> { match self { ConversationEntry::Eva(_) => Some("Eva: "), ConversationEntry::User(_) => Some("Argee: "), ConversationEntry::ShipComputer(_) => Some("Ship Computer: "), _ => None, } } pub fn prefix_style(&self) -> Style { match self { ConversationEntry::Eva(_) => Style::new().fg(style::Color::Cyan), ConversationEntry::User(_) => Style::new().fg(style::Color::Magenta), ConversationEntry::ShipComputer(_) => Style::new().fg(style::Color::Red), ConversationEntry::StageDirection(_) => Style::new().fg(style::Color::Yellow), ConversationEntry::SystemMessage(_) => Style::new().fg(style::Color::DarkGray), } } pub fn text_style(&self) -> Style { match self { ConversationEntry::StageDirection(_) => Style::new().fg(style::Color::Yellow), ConversationEntry::SystemMessage(_) => Style::new().fg(style::Color::DarkGray), _ => Style::new() } } } impl ToString for ConversationEntry { fn to_string(&self) -> String { match self { ConversationEntry::Eva(text) => text, ConversationEntry::ShipComputer(text) => text, ConversationEntry::StageDirection(text) => text, ConversationEntry::SystemMessage(text) => text, ConversationEntry::User(text) => text }.clone() } } impl TryInto for ConversationEntry { fn try_into(self) -> Result { match self { ConversationEntry::User(text) => Ok(ChatCompletionRequestMessage::User(ChatCompletionRequestUserMessage { content: text.into(), ..Default::default()})), ConversationEntry::Eva(text) => Ok(ChatCompletionRequestMessage::Assistant(ChatCompletionRequestAssistantMessage { content: Some(text.into()), ..Default::default()})), ConversationEntry::ShipComputer(text) => Ok(ChatCompletionRequestMessage::System(ChatCompletionRequestSystemMessage { content: text.into(), name: Some("ship-computer".into()), ..Default::default() })), ConversationEntry::StageDirection(text) => Ok(ChatCompletionRequestMessage::System(ChatCompletionRequestSystemMessage { content: text.into(), name: Some("stage-direction".into()), ..Default::default() })), _ => Err(()) } } type Error = (); } impl TryInto for ChatCompletionRequestMessage { fn try_into(self) -> Result { match self { ChatCompletionRequestMessage::User(ChatCompletionRequestUserMessage { content: ChatCompletionRequestUserMessageContent::Text(msg), ..}) => Ok(ConversationEntry::User(msg)), ChatCompletionRequestMessage::Assistant(ChatCompletionRequestAssistantMessage { content: Some(ChatCompletionRequestAssistantMessageContent::Text(msg)), ..}) => Ok(ConversationEntry::Eva(msg)), ChatCompletionRequestMessage::System(ChatCompletionRequestSystemMessage { content: ChatCompletionRequestSystemMessageContent::Text(msg), name: Some(name), ..}) => { match name.as_str() { "ship-computer" => Ok(ConversationEntry::ShipComputer(msg)), "stage-direction" => Ok(ConversationEntry::StageDirection(msg)), _ => Err(()) } }, _ => Err(()) } } type Error = (); }