Skip to main content

subcog/models/
memory.rs

1//! Memory types and identifiers.
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use std::fmt;
6
7/// Unique identifier for a memory.
8#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
9#[serde(transparent)]
10pub struct MemoryId(String);
11
12impl MemoryId {
13    /// Creates a new memory ID.
14    #[must_use]
15    pub fn new(id: impl Into<String>) -> Self {
16        Self(id.into())
17    }
18
19    /// Returns the ID as a string slice.
20    #[must_use]
21    pub fn as_str(&self) -> &str {
22        &self.0
23    }
24}
25
26impl fmt::Display for MemoryId {
27    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28        write!(f, "{}", self.0)
29    }
30}
31
32impl From<String> for MemoryId {
33    fn from(s: String) -> Self {
34        Self(s)
35    }
36}
37
38impl From<&str> for MemoryId {
39    fn from(s: &str) -> Self {
40        Self(s.to_string())
41    }
42}
43
44/// A captured memory entry.
45#[derive(Debug, Clone)]
46pub struct Memory {
47    /// Unique identifier.
48    pub id: MemoryId,
49    /// The memory content.
50    pub content: String,
51    /// The namespace this memory belongs to.
52    pub namespace: super::Namespace,
53    /// The domain this memory is associated with.
54    pub domain: super::Domain,
55    /// Optional project identifier (normalized git remote URL).
56    pub project_id: Option<String>,
57    /// Optional branch name for project-scoped memories.
58    pub branch: Option<String>,
59    /// Optional file path relative to repository root.
60    pub file_path: Option<String>,
61    /// Current status of the memory.
62    pub status: super::MemoryStatus,
63    /// Creation timestamp (Unix epoch seconds).
64    pub created_at: u64,
65    /// Last update timestamp (Unix epoch seconds).
66    pub updated_at: u64,
67    /// Tombstone timestamp (UTC) when soft-deleted.
68    ///
69    /// Compatibility is handled in storage adapters, so explicit versioning
70    /// of the Memory struct is not required at this time.
71    pub tombstoned_at: Option<DateTime<Utc>>,
72    /// Expiration timestamp (Unix epoch seconds).
73    ///
74    /// Memory is eligible for automatic cleanup after this timestamp.
75    /// Set at capture time as `created_at + ttl_seconds`. Preserved on updates.
76    /// `None` means no expiration (memory lives until manually deleted).
77    pub expires_at: Option<u64>,
78    /// Optional embedding vector.
79    pub embedding: Option<Vec<f32>>,
80    /// Optional tags for categorization.
81    pub tags: Vec<String>,
82    /// Optional group identifier for group-scoped memories.
83    ///
84    /// When set, this memory belongs to a specific group within an organization.
85    /// Group members with sufficient permissions can access these memories.
86    #[cfg(feature = "group-scope")]
87    pub group_id: Option<String>,
88    /// Optional source reference (file path, URL, etc.).
89    pub source: Option<String>,
90    /// Whether this memory is a consolidation summary.
91    ///
92    /// When `true`, this memory represents a consolidated summary of multiple
93    /// related memories. The original memories are preserved and linked via
94    /// `source_memory_ids`.
95    pub is_summary: bool,
96    /// IDs of memories that were consolidated into this summary.
97    ///
98    /// Only populated when `is_summary` is `true`. These represent the original
99    /// memories that were analyzed and combined to create this summary.
100    pub source_memory_ids: Option<Vec<MemoryId>>,
101    /// Timestamp when this memory was consolidated (Unix epoch seconds).
102    ///
103    /// Only populated for consolidated memories (both summaries and source memories
104    /// that have been included in a consolidation).
105    pub consolidation_timestamp: Option<u64>,
106}
107
108/// Result of a memory operation with optional metadata.
109#[derive(Debug, Clone)]
110pub struct MemoryResult {
111    /// The memory data.
112    pub memory: Memory,
113    /// Similarity score (0.0 to 1.0) if from a search.
114    pub score: Option<f32>,
115    /// BM25 score if text search was used.
116    pub bm25_score: Option<f32>,
117}