#![allow(missing_docs)]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum MemoryImportance {
Low = 1,
Normal = 2,
High = 3,
Critical = 4,
}
impl std::fmt::Display for MemoryImportance {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MemoryImportance::Low => write!(f, "low"),
MemoryImportance::Normal => write!(f, "normal"),
MemoryImportance::High => write!(f, "high"),
MemoryImportance::Critical => write!(f, "critical"),
}
}
}
impl Default for MemoryImportance {
fn default() -> Self {
Self::Normal
}
}
impl TryFrom<u8> for MemoryImportance {
type Error = String;
fn try_from(value: u8) -> std::result::Result<Self, Self::Error> {
match value {
1 => Ok(MemoryImportance::Low),
2 => Ok(MemoryImportance::Normal),
3 => Ok(MemoryImportance::High),
4 => Ok(MemoryImportance::Critical),
_ => Err(format!("Invalid importance level: {}", value)),
}
}
}
#[derive(Debug, Clone, Default)]
pub struct RememberInput {
pub content: String,
pub tags: Vec<String>,
pub importance: MemoryImportance,
pub metadata: serde_json::Value,
}
#[derive(Debug, Clone, Default)]
pub struct RecallInput {
pub query: String,
pub tags: Vec<String>,
pub limit: Option<usize>,
pub min_importance: Option<MemoryImportance>,
}
#[derive(Debug, Clone)]
pub struct ForgetInput {
pub memory_id: Option<String>,
pub content_match: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemorySearchResult {
pub id: String,
pub content: String,
pub tags: Vec<String>,
pub importance: MemoryImportance,
pub created_at: String,
pub score: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct EncodedMetadata {
#[serde(rename = "t")]
tags: Vec<String>,
#[serde(rename = "i")]
importance: u8,
}
#[derive(Debug, Clone)]
pub struct ParsedMemory {
pub content: String,
pub tags: Vec<String>,
pub importance: MemoryImportance,
}
pub const MEMORY_SEPARATOR: &str = "\n---\n";
pub const MEMORY_SOURCE: &str = "plugin-memory";
pub fn encode_memory_text(content: &str, tags: &[String], importance: MemoryImportance) -> String {
let metadata = EncodedMetadata {
tags: tags.to_vec(),
importance: importance as u8,
};
let metadata_str = serde_json::to_string(&metadata).unwrap_or_default();
format!("{}{}{}", metadata_str, MEMORY_SEPARATOR, content)
}
pub fn decode_memory_text(text: &str) -> ParsedMemory {
if let Some(sep_pos) = text.find(MEMORY_SEPARATOR) {
let metadata_str = &text[..sep_pos];
let content = &text[sep_pos + MEMORY_SEPARATOR.len()..];
if let Ok(metadata) = serde_json::from_str::<EncodedMetadata>(metadata_str) {
return ParsedMemory {
content: content.to_string(),
tags: metadata.tags,
importance: MemoryImportance::try_from(metadata.importance)
.unwrap_or(MemoryImportance::Normal),
};
}
}
ParsedMemory {
content: text.to_string(),
tags: Vec::new(),
importance: MemoryImportance::Normal,
}
}
pub fn memory_source() -> &'static str {
MEMORY_SOURCE
}
#[derive(Debug, Clone, Serialize)]
pub struct ActionResult {
pub text: String,
pub success: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<serde_json::Value>,
}
impl ActionResult {
pub fn success(text: impl Into<String>) -> Self {
Self {
text: text.into(),
success: true,
data: None,
}
}
pub fn success_with_data(text: impl Into<String>, data: serde_json::Value) -> Self {
Self {
text: text.into(),
success: true,
data: Some(data),
}
}
pub fn error(text: impl Into<String>) -> Self {
Self {
text: text.into(),
success: false,
data: None,
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct ProviderResult {
pub text: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<serde_json::Value>,
}
impl ProviderResult {
pub fn new(text: impl Into<String>) -> Self {
Self {
text: text.into(),
data: None,
}
}
pub fn with_data(text: impl Into<String>, data: serde_json::Value) -> Self {
Self {
text: text.into(),
data: Some(data),
}
}
}