|
|
@@ -3,18 +3,24 @@ use serde::Serialize;
|
|
|
use serde_json::{json, Value};
|
|
|
use crate::{
|
|
|
http_error::HttpError,
|
|
|
+ models::{
|
|
|
+ game::Game,
|
|
|
+ character::Character,
|
|
|
+ session::Session,
|
|
|
+ turn::Turn
|
|
|
+ },
|
|
|
DEEPINFRA_TOKEN
|
|
|
};
|
|
|
|
|
|
#[derive(Serialize)]
|
|
|
-pub struct PromptMessage {
|
|
|
+struct PromptMessage {
|
|
|
pub role: PromptRole,
|
|
|
pub content: String
|
|
|
}
|
|
|
|
|
|
#[derive(Serialize)]
|
|
|
#[serde(rename_all = "lowercase")]
|
|
|
-pub enum PromptRole {
|
|
|
+enum PromptRole {
|
|
|
User,
|
|
|
System,
|
|
|
Assistant
|
|
|
@@ -26,7 +32,80 @@ pub struct PromptResponse {
|
|
|
pub output_tokens: i32
|
|
|
}
|
|
|
|
|
|
-pub async fn send_message(prompt: Vec<PromptMessage>) -> Result<PromptResponse, HttpError> {
|
|
|
+pub async fn prompt(
|
|
|
+ game: Game,
|
|
|
+ character: Character,
|
|
|
+ sessions: Vec<Session>,
|
|
|
+ turns: Vec<Turn>,
|
|
|
+ new_input: Option<String>,
|
|
|
+ new_game: bool
|
|
|
+) -> Result<PromptResponse, HttpError> {
|
|
|
+ let system_message = create_system_message(game, character, sessions, new_game);
|
|
|
+ let mut prompt = create_turn_prompts(turns);
|
|
|
+ prompt.insert(0, system_message);
|
|
|
+ if let Some(p) = new_input {
|
|
|
+ prompt.push(PromptMessage {
|
|
|
+ role: PromptRole::User,
|
|
|
+ content: p
|
|
|
+ });
|
|
|
+ }
|
|
|
+ Ok(send_message(prompt).await?)
|
|
|
+}
|
|
|
+
|
|
|
+fn create_system_message(
|
|
|
+ game: Game,
|
|
|
+ character: Character,
|
|
|
+ sessions: Vec<Session>,
|
|
|
+ new_game: bool
|
|
|
+) -> PromptMessage {
|
|
|
+ let mut text = "".to_string();
|
|
|
+ text += "You are acting as a game master for an RPG and running the game.\n";
|
|
|
+ text += &format!("Here is the world context: {}\n", game.game_context);
|
|
|
+ text += &format!(
|
|
|
+ "Character name is {}, here is a description of the character: {}\n",
|
|
|
+ character.name,
|
|
|
+ character.description
|
|
|
+ );
|
|
|
+
|
|
|
+ if sessions.len() == 0 {
|
|
|
+ text += "This is the first session in this game.\n";
|
|
|
+ } else {
|
|
|
+ for(i, session) in sessions.iter().enumerate() {
|
|
|
+ match &session.summary {
|
|
|
+ Some(s) => {text += &format!("Summary of session {}: {}\n", i, s)},
|
|
|
+ None => ()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if new_game {
|
|
|
+ text += "Start off a new session for the player";
|
|
|
+ }
|
|
|
+
|
|
|
+ PromptMessage {
|
|
|
+ role: PromptRole::System,
|
|
|
+ content: text
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+fn create_turn_prompts(turns: Vec<Turn>) -> Vec<PromptMessage> {
|
|
|
+ let mut prompts = Vec::new();
|
|
|
+
|
|
|
+ for turn in turns {
|
|
|
+ prompts.push(PromptMessage {
|
|
|
+ role: PromptRole::User,
|
|
|
+ content: turn.user_text
|
|
|
+ });
|
|
|
+ prompts.push(PromptMessage {
|
|
|
+ role: PromptRole::Assistant,
|
|
|
+ content: turn.llm_text
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ prompts
|
|
|
+}
|
|
|
+
|
|
|
+async fn send_message(prompt: Vec<PromptMessage>) -> Result<PromptResponse, HttpError> {
|
|
|
let client = Client::new();
|
|
|
let key = DEEPINFRA_TOKEN.get().unwrap();
|
|
|
|