prediction: completely rewrite the prediction engine by moving all the conversation manipulation into that task out of the UI
This commit is contained in:
+73
-35
@@ -1,12 +1,8 @@
|
||||
use async_openai::types::chat::*;
|
||||
use chrono::Duration;
|
||||
use schemars::schema_for;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::GeneratedResponses;
|
||||
|
||||
const SYSTEM_PROMPT: &str = include_str!("system-prompt.txt");
|
||||
use crate::prediction::{GeneratedResponses, PossibleResponse};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum ConversationEntry {
|
||||
@@ -17,6 +13,40 @@ pub enum ConversationEntry {
|
||||
SystemMessage(String)
|
||||
}
|
||||
|
||||
impl TryInto<ChatCompletionRequestMessage> for ConversationEntry {
|
||||
fn try_into(self) -> Result<ChatCompletionRequestMessage, Self::Error> {
|
||||
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() })),
|
||||
ConversationEntry::SystemMessage(_) => Err(())
|
||||
}
|
||||
}
|
||||
|
||||
type Error = ();
|
||||
}
|
||||
|
||||
|
||||
impl TryInto<ConversationEntry> for ChatCompletionRequestMessage {
|
||||
fn try_into(self) -> Result<ConversationEntry, Self::Error> {
|
||||
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 = ();
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||
pub struct StageDirection {
|
||||
pub episode_number: u32,
|
||||
@@ -26,6 +56,22 @@ pub struct StageDirection {
|
||||
pub current_playlist: Vec<PlaylistEntry>
|
||||
}
|
||||
|
||||
/*impl StageDirection {
|
||||
pub fn insert_conversation(&mut self, entry: ConversationEntry) {
|
||||
self.additions.push(entry);
|
||||
}
|
||||
|
||||
pub fn take_actions(&mut self) -> StageActions {
|
||||
StageActions { direction: self.clone(), additions: std::mem::take(&mut self.additions) }
|
||||
}
|
||||
}*/
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct StageActions {
|
||||
pub direction: StageDirection,
|
||||
pub additions: Vec<ConversationEntry>
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||
pub struct PlaylistEntry {
|
||||
pub artist: String,
|
||||
@@ -34,41 +80,33 @@ pub struct PlaylistEntry {
|
||||
pub bpm: f64
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
pub struct Scene {
|
||||
pub conversation: Vec<ConversationEntry>,
|
||||
pub direction: StageDirection
|
||||
reply_options: GeneratedResponses,
|
||||
conversation: Vec<ConversationEntry>,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
pub fn insert_conversation(&mut self, entry: ConversationEntry) {
|
||||
self.conversation.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<CreateChatCompletionRequest> for Scene {
|
||||
fn into(self) -> CreateChatCompletionRequest {
|
||||
let mut messages = vec![
|
||||
ChatCompletionRequestMessage::System(ChatCompletionRequestSystemMessage { content: SYSTEM_PROMPT.into(), ..Default::default()}),
|
||||
ChatCompletionRequestMessage::System(ChatCompletionRequestSystemMessage { content: serde_json::to_string(&self.direction).unwrap().into(), ..Default::default()}),
|
||||
];
|
||||
messages.extend(self.conversation.into_iter().filter(|x| if let ConversationEntry::SystemMessage(_) = x { false } else { true }).map(|entry| {
|
||||
match entry {
|
||||
ConversationEntry::User(text) => ChatCompletionRequestMessage::User(ChatCompletionRequestUserMessage { content: text.into(), ..Default::default()}),
|
||||
ConversationEntry::Eva(text) => ChatCompletionRequestMessage::Assistant(ChatCompletionRequestAssistantMessage { content: Some(text.into()), ..Default::default()}),
|
||||
ConversationEntry::ShipComputer(text) => ChatCompletionRequestMessage::System(ChatCompletionRequestSystemMessage { content: text.into(), name: Some("ship-computer".into()), ..Default::default() }),
|
||||
ConversationEntry::StageDirection(text) => ChatCompletionRequestMessage::System(ChatCompletionRequestSystemMessage { content: text.into(), name: Some("stage-direction".into()), ..Default::default() }),
|
||||
ConversationEntry::SystemMessage(_) => unreachable!()
|
||||
}
|
||||
}));
|
||||
let response_schema: Value = schema_for!(GeneratedResponses).into();
|
||||
CreateChatCompletionRequest {
|
||||
model: "gpt-5.4".into(),
|
||||
messages: messages,
|
||||
max_completion_tokens: Some(350),
|
||||
response_format: Some(ResponseFormat::JsonSchema { json_schema: ResponseFormatJsonSchema { description: None, name: "responses".into(), schema: response_schema, strict: None } }),
|
||||
..Default::default()
|
||||
pub fn new(reply_options: GeneratedResponses, conversation: Vec<ConversationEntry>) -> Self {
|
||||
Self {
|
||||
reply_options,
|
||||
conversation,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn conversation(&self) -> &Vec<ConversationEntry> {
|
||||
&self.conversation
|
||||
}
|
||||
|
||||
pub fn conversation_mut(&mut self) -> &mut Vec<ConversationEntry> {
|
||||
&mut self.conversation
|
||||
}
|
||||
|
||||
pub fn reply_options(&self) -> &Vec<PossibleResponse> {
|
||||
&self.reply_options.responses
|
||||
}
|
||||
|
||||
pub fn reply_options_mut(&mut self) -> &mut Vec<PossibleResponse> {
|
||||
&mut self.reply_options.responses
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user