pub mod backend;
pub mod extract;
pub mod inject;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Lesson {
pub content: String,
#[serde(default)]
pub title: String,
#[serde(default = "default_memory_type")]
pub memory_type: String,
#[serde(default = "default_importance")]
pub importance: f64,
#[serde(default = "default_confidence")]
pub confidence: String,
#[serde(default)]
pub tags: Vec<String>,
#[serde(default)]
pub source: String,
#[serde(default)]
pub role: String,
#[serde(default)]
pub project: String,
#[serde(default)]
pub created: String,
}
fn default_memory_type() -> String {
"learning".into()
}
fn default_importance() -> f64 {
0.5
}
fn default_confidence() -> String {
"medium".into()
}
impl Default for Lesson {
fn default() -> Self {
Self {
content: String::new(),
title: String::new(),
memory_type: "learning".into(),
importance: 0.5,
confidence: "medium".into(),
tags: Vec::new(),
source: String::new(),
role: String::new(),
project: String::new(),
created: String::new(),
}
}
}
impl Lesson {
pub fn get_field(&self, name: &str) -> Option<serde_json::Value> {
match name {
"content" => Some(serde_json::Value::String(self.content.clone())),
"title" => Some(serde_json::Value::String(self.title.clone())),
"memory_type" => Some(serde_json::Value::String(self.memory_type.clone())),
"importance" => Some(serde_json::json!(self.importance)),
"confidence" => {
let mapped = match self.confidence.as_str() {
"high" => "user_confirmed",
_ => "agent_inferred",
};
Some(serde_json::Value::String(mapped.to_string()))
}
"tags" => Some(serde_json::json!(self.tags)),
"source" => Some(serde_json::Value::String(self.source.clone())),
"role" => Some(serde_json::Value::String(self.role.clone())),
"project" => Some(serde_json::Value::String(self.project.clone())),
"created" => Some(serde_json::Value::String(self.created.clone())),
_ => None,
}
}
}
pub struct RetrievalContext {
pub query: String,
pub role: String,
pub project: String,
pub limit: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LearningConfig {
#[serde(default)]
pub enabled: bool,
#[serde(default = "default_learning_model")]
pub model: String,
#[serde(default = "default_backend")]
pub backend: String,
#[serde(default = "default_min_messages")]
pub min_messages_for_intermediate: usize,
#[serde(default = "default_max_inject")]
pub max_inject: usize,
#[serde(default)]
pub store: Option<McpEndpointConfig>,
#[serde(default)]
pub retrieve: Option<McpEndpointConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct McpEndpointConfig {
pub tool: String,
#[serde(default)]
pub field_map: HashMap<String, String>,
}
fn default_learning_model() -> String {
"anthropic:claude-haiku-4-5-20251001".into()
}
fn default_backend() -> String {
"file".into()
}
fn default_min_messages() -> usize {
3
}
fn default_max_inject() -> usize {
5
}
impl Default for LearningConfig {
fn default() -> Self {
Self {
enabled: false,
model: default_learning_model(),
backend: default_backend(),
min_messages_for_intermediate: default_min_messages(),
max_inject: default_max_inject(),
store: None,
retrieve: None,
}
}
}