Skip to main content

anamnesis_core/
adapter.rs

1//! The `MemoryAdapter` trait every source connector implements.
2
3use async_trait::async_trait;
4use chrono::{DateTime, Utc};
5use futures::stream::BoxStream;
6use serde::{Deserialize, Serialize};
7
8use crate::error::Result;
9use crate::model::{AnamnesisRecord, SourceDescriptor};
10
11/// Options passed to `MemoryAdapter::scan`.
12#[derive(Debug, Clone, Default)]
13pub struct ScanOpts {
14    /// If set, only records modified since this time are returned.
15    pub since: Option<DateTime<Utc>>,
16    /// If true, skip the dedup hash check and re-emit everything.
17    pub full: bool,
18}
19
20/// Options passed to `MemoryAdapter::watch`.
21#[derive(Debug, Clone, Default)]
22pub struct WatchOpts {
23    /// Polling interval, if the adapter falls back to polling.
24    pub poll_interval: Option<std::time::Duration>,
25}
26
27/// A raw record as produced by an adapter scan, before normalization.
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct RawRecord {
30    /// Source-native id.
31    pub native_id: String,
32    /// Optional path or DB reference.
33    pub native_path: Option<String>,
34    /// Opaque adapter-specific payload.
35    pub payload: serde_json::Value,
36    /// When the record was captured.
37    pub captured_at: DateTime<Utc>,
38}
39
40/// A change event surfaced by `MemoryAdapter::watch`.
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub enum RawDelta {
43    /// A new or updated raw record.
44    Upsert(RawRecord),
45    /// A record was removed from the source.
46    Delete {
47        /// Native id of the removed record.
48        native_id: String,
49    },
50}
51
52/// Adapter health status.
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct HealthStatus {
55    /// Is the adapter usable right now?
56    pub ok: bool,
57    /// Human-readable detail.
58    pub detail: String,
59}
60
61/// The contract every memory source connector implements.
62#[async_trait]
63pub trait MemoryAdapter: Send + Sync {
64    /// Self-describing metadata.
65    fn descriptor(&self) -> SourceDescriptor;
66
67    /// Stream raw records from the source.
68    fn scan<'a>(&'a self, opts: ScanOpts) -> BoxStream<'a, Result<RawRecord>>;
69
70    /// Optional incremental watcher. Default: not supported.
71    fn watch<'a>(&'a self, _opts: WatchOpts) -> Option<BoxStream<'a, Result<RawDelta>>> {
72        None
73    }
74
75    /// Normalize a raw record into one or more canonical records.
76    ///
77    /// Returning multiple records is allowed when one source row maps to
78    /// several memories (e.g. one conversation → multiple extracted facts).
79    fn normalize(&self, raw: RawRecord) -> Result<Vec<AnamnesisRecord>>;
80
81    /// Cheap credential / path / connectivity check.
82    async fn health(&self) -> HealthStatus;
83}