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}