Add support for prompt variables (bot name, date/time, model id)
Fixes https://github.com/etkecc/baibot/issues/10 This also includes them in the default prompts (for newly-created agents), so that people can get a better experience out of the box.
This commit is contained in:
@@ -9,5 +9,7 @@ pub use agent_provider::{AgentProvider, AgentProviderInfo};
|
||||
pub use image_generation::{ImageGenerationParams, ImageGenerationResult};
|
||||
pub use ping::PingResult;
|
||||
pub use speech_to_text::{SpeechToTextParams, SpeechToTextResult};
|
||||
pub use text_generation::{TextGenerationParams, TextGenerationResult};
|
||||
pub use text_generation::{
|
||||
TextGenerationParams, TextGenerationPromptVariables, TextGenerationResult,
|
||||
};
|
||||
pub use text_to_speech::{TextToSpeechParams, TextToSpeechResult};
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
mod prompt_variables;
|
||||
|
||||
pub use prompt_variables::TextGenerationPromptVariables;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct TextGenerationParams {
|
||||
pub context_management_enabled: bool,
|
||||
pub prompt_override: Option<String>,
|
||||
pub temperature_override: Option<f32>,
|
||||
pub prompt_variables: TextGenerationPromptVariables,
|
||||
}
|
||||
|
||||
pub struct TextGenerationResult {
|
||||
@@ -0,0 +1,75 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct TextGenerationPromptVariables {
|
||||
map: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Default for TextGenerationPromptVariables {
|
||||
fn default() -> Self {
|
||||
Self::new("unnamed", "unknown-model", Utc::now())
|
||||
}
|
||||
}
|
||||
|
||||
impl TextGenerationPromptVariables {
|
||||
pub fn new(bot_name: &str, model_id: &str, utc_time: DateTime<Utc>) -> Self {
|
||||
let mut map = HashMap::new();
|
||||
|
||||
map.insert("baibot_name".to_string(), bot_name.to_string());
|
||||
map.insert("baibot_model_id".to_string(), model_id.to_string());
|
||||
map.insert("baibot_now_utc".to_string(), format_utc_time(utc_time));
|
||||
|
||||
Self { map }
|
||||
}
|
||||
|
||||
pub fn format(&self, text: &str) -> String {
|
||||
let mut formatted_text = text.to_string();
|
||||
|
||||
for (key, value) in &self.map {
|
||||
let placeholder = format!("{{{{ {} }}}}", key);
|
||||
formatted_text = formatted_text.replace(&placeholder, value);
|
||||
}
|
||||
|
||||
formatted_text
|
||||
}
|
||||
}
|
||||
|
||||
fn format_utc_time(time: DateTime<Utc>) -> String {
|
||||
time.format("%Y-%m-%d (%A), %H:%M:%S UTC").to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use chrono::{TimeZone, Timelike};
|
||||
|
||||
#[test]
|
||||
fn test_new() {
|
||||
// Intentionally injecting some sub-seconds to ensure formatting would ignore them.
|
||||
let now_utc = Utc
|
||||
.with_ymd_and_hms(2024, 9, 20, 18, 34, 15)
|
||||
.unwrap()
|
||||
.with_nanosecond(250000000)
|
||||
.unwrap();
|
||||
|
||||
let variables = TextGenerationPromptVariables::new("baibot", "gpt-4o", now_utc);
|
||||
|
||||
assert_eq!(
|
||||
variables.map.get("baibot_name"),
|
||||
Some(&"baibot".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
variables.map.get("baibot_model_id"),
|
||||
Some(&"gpt-4o".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
variables.map.get("baibot_now_utc"),
|
||||
Some(&format_utc_time(now_utc))
|
||||
);
|
||||
|
||||
let prompt = "Hello, I'm {{ baibot_name }} using {{ baibot_model_id }}. The date/time now is {{ baibot_now_utc }}.";
|
||||
let expected = "Hello, I'm baibot using gpt-4o. The date/time now is 2024-09-20 (Friday), 18:34:15 UTC.";
|
||||
|
||||
assert_eq!(variables.format(prompt), expected);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user