use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::memory::tree::bucket_seal::{LabelStrategy, LeafRef};
use crate::memory::tree::store::{Tree, TreeKind};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct TreeLeafPayload {
pub chunk_id: String,
pub token_count: u32,
pub timestamp: DateTime<Utc>,
pub content: String,
#[serde(default)]
pub entities: Vec<String>,
#[serde(default)]
pub topics: Vec<String>,
#[serde(default)]
pub score: f32,
}
impl From<&TreeLeafPayload> for LeafRef {
fn from(p: &TreeLeafPayload) -> Self {
LeafRef {
chunk_id: p.chunk_id.clone(),
token_count: p.token_count,
timestamp: p.timestamp,
content: p.content.clone(),
entities: p.entities.clone(),
topics: p.topics.clone(),
score: p.score,
}
}
}
impl From<LeafRef> for TreeLeafPayload {
fn from(l: LeafRef) -> Self {
Self {
chunk_id: l.chunk_id,
token_count: l.token_count,
timestamp: l.timestamp,
content: l.content,
entities: l.entities,
topics: l.topics,
score: l.score,
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TreeLabelStrategy {
#[default]
Inherit,
Extract,
Empty,
}
impl TreeLabelStrategy {
pub fn resolve(
self,
extractor: Option<std::sync::Arc<dyn crate::memory::score::extract::EntityExtractor>>,
) -> LabelStrategy {
match self {
TreeLabelStrategy::Inherit => LabelStrategy::UnionFromChildren,
TreeLabelStrategy::Empty => LabelStrategy::Empty,
TreeLabelStrategy::Extract => match extractor {
Some(ex) => LabelStrategy::ExtractFromContent(ex),
None => LabelStrategy::UnionFromChildren,
},
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct TreeWriteRequest {
pub tree_id: String,
pub tree_kind: TreeKind,
pub leaf: TreeLeafPayload,
#[serde(default)]
pub label_strategy: TreeLabelStrategy,
#[serde(default)]
pub deferred: bool,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct TreeWriteOutcome {
pub new_summary_ids: Vec<String>,
pub seal_pending: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct TreeReadRequest {
pub tree_id: String,
#[serde(default)]
pub start_node_id: Option<String>,
pub max_depth: u32,
#[serde(default)]
pub query: Option<String>,
#[serde(default)]
pub limit: Option<usize>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct TreeReadHit {
pub node_id: String,
pub node_kind: String,
pub level: u32,
pub content: String,
#[serde(default)]
pub score: f32,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct TreeReadResult {
pub hits: Vec<TreeReadHit>,
pub total: usize,
pub tree_id: String,
}
impl TreeReadResult {
pub fn empty(tree: &Tree) -> Self {
Self {
hits: Vec::new(),
total: 0,
tree_id: tree.id.clone(),
}
}
}
#[cfg(test)]
#[path = "io_tests.rs"]
mod tests;