Skip to main content

subcog/models/
capture.rs

1//! Capture request and result types.
2
3use super::{Domain, MemoryId, Namespace};
4use crate::storage::index::DomainScope;
5
6/// Request to capture a new memory.
7#[derive(Debug, Clone, Default)]
8pub struct CaptureRequest {
9    /// The content to capture.
10    pub content: String,
11    /// Target namespace for the memory.
12    pub namespace: Namespace,
13    /// Target domain for the memory.
14    pub domain: Domain,
15    /// Optional tags for categorization.
16    pub tags: Vec<String>,
17    /// Optional source reference.
18    pub source: Option<String>,
19    /// Whether to skip security filtering.
20    pub skip_security_check: bool,
21    /// Optional time-to-live in seconds.
22    ///
23    /// When set, `expires_at` is calculated as `created_at + ttl_seconds`.
24    /// `None` means no expiration (memory lives until manually deleted).
25    pub ttl_seconds: Option<u64>,
26    /// Target storage scope for the memory.
27    ///
28    /// - `Project`/`User`: Stored in user-local index (default)
29    /// - `Org`: Stored in organization-shared index (requires org feature enabled)
30    ///
31    /// Default: `None` (uses context-appropriate scope based on git status)
32    pub scope: Option<DomainScope>,
33    /// Optional group identifier for group-scoped memories.
34    ///
35    /// When set, the memory is associated with a specific group and requires
36    /// write permission to that group. Group-scoped memories are visible to
37    /// all group members during recall.
38    #[cfg(feature = "group-scope")]
39    pub group_id: Option<String>,
40}
41
42impl CaptureRequest {
43    /// Creates a new capture request with the given content.
44    #[must_use]
45    pub fn new(content: impl Into<String>) -> Self {
46        Self {
47            content: content.into(),
48            ..Default::default()
49        }
50    }
51
52    /// Sets the namespace.
53    #[must_use]
54    pub const fn with_namespace(mut self, namespace: Namespace) -> Self {
55        self.namespace = namespace;
56        self
57    }
58
59    /// Sets the domain.
60    #[must_use]
61    pub fn with_domain(mut self, domain: Domain) -> Self {
62        self.domain = domain;
63        self
64    }
65
66    /// Adds a tag.
67    #[must_use]
68    pub fn with_tag(mut self, tag: impl Into<String>) -> Self {
69        self.tags.push(tag.into());
70        self
71    }
72
73    /// Sets the source reference.
74    #[must_use]
75    pub fn with_source(mut self, source: impl Into<String>) -> Self {
76        self.source = Some(source.into());
77        self
78    }
79
80    /// Sets the time-to-live in seconds.
81    ///
82    /// The memory will expire after this duration from creation time.
83    /// `None` means no expiration.
84    #[must_use]
85    pub const fn with_ttl(mut self, ttl_seconds: u64) -> Self {
86        self.ttl_seconds = Some(ttl_seconds);
87        self
88    }
89
90    /// Sets the storage scope for the memory.
91    ///
92    /// - `Project`/`User`: Stored in user-local index
93    /// - `Org`: Stored in organization-shared index
94    #[must_use]
95    pub const fn with_scope(mut self, scope: DomainScope) -> Self {
96        self.scope = Some(scope);
97        self
98    }
99
100    /// Sets the group identifier for group-scoped memories.
101    ///
102    /// When set, the memory is associated with a specific group and requires
103    /// write permission to that group.
104    #[cfg(feature = "group-scope")]
105    #[must_use]
106    pub fn with_group_id(mut self, group_id: impl Into<String>) -> Self {
107        self.group_id = Some(group_id.into());
108        self
109    }
110}
111
112/// Result of a capture operation.
113#[derive(Debug, Clone)]
114pub struct CaptureResult {
115    /// The ID of the captured memory.
116    pub memory_id: MemoryId,
117    /// The URN of the captured memory.
118    pub urn: String,
119    /// Whether the content was modified (e.g., redacted).
120    pub content_modified: bool,
121    /// Any warnings generated during capture.
122    pub warnings: Vec<String>,
123}
124
125impl CaptureResult {
126    /// Creates a new capture result.
127    #[must_use]
128    pub const fn new(memory_id: MemoryId, urn: String) -> Self {
129        Self {
130            memory_id,
131            urn,
132            content_modified: false,
133            warnings: Vec::new(),
134        }
135    }
136}