gemini_memory_rs/lib.rs
1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![warn(unreachable_pub)]
3#![forbid(unsafe_code)]
4#![warn(missing_docs)]
5//! # gemini-memory-rs
6//!
7//! A contextual memory engine for Gemini Live voice sessions.
8//!
9//! The engine's organising principle is that **context is prepared
10//! asynchronously and consumed synchronously**. Nothing expensive — model
11//! calls, search, repository writes — ever happens on the path between the
12//! model asking for memory and the memory arriving. By the time a
13//! `recall_context` tool call lands, the answer is already sitting in state.
14//!
15//! ```text
16//! user speech ─► input transcription ─► retrieval-state extraction
17//! │
18//! ▼
19//! local BM25 search
20//! │
21//! ▼
22//! immutable prepared snapshot ─► Gemini
23//!
24//! final transcript ─► observation extraction ─► session ledger
25//! │
26//! ┌───────────────────────────┤
27//! ▼ ▼
28//! session overlay post-session reconciliation
29//! (usable now) │
30//! ▼
31//! canonical OKF markdown
32//! ```
33//!
34//! ## Layout
35//!
36//! Each module is the design's correspondingly-named component:
37//!
38//! | Module | Responsibility |
39//! |--------|----------------|
40//! | [`core`] | Domain vocabulary, deterministic policy, event log |
41//! | [`okf`] | Canonical Markdown memory records and the repository |
42//! | [`bm25`] | Fielded lexical index, ranking, and search explanation |
43//! | [`transcript`] | Partial/final transcript accumulation and debouncing |
44//! | [`retrieval`] | Retrieval plans, fusion, budgeted context assembly |
45//! | [`ingestion`] | Observation extraction, candidate ledger, session overlay |
46//! | [`reconcile`] | Consolidation, conflict resolution, promotion, commit |
47//! | [`runtime`] | Live-session wiring: state keys, control loop, tools |
48//! | [`evals`] | Fixture-driven quality harness |
49//!
50//! ## Getting started
51//!
52//! ```no_run
53//! use gemini_memory_rs::prelude::*;
54//!
55//! # async fn demo() -> Result<(), MemoryError> {
56//! let engine = MemoryEngine::in_memory(UserId::new("usr_72ab"));
57//!
58//! // A finalized user turn: evidence in, context out.
59//! let session = engine.begin_session(SessionId::new("ses_01"));
60//! session.observe_final_transcript(TurnId(1), "I am pescatarian").await?;
61//!
62//! let snapshot = session.prepare(TurnId(2), "what should we eat tonight").await?;
63//! for fact in snapshot.facts.iter() {
64//! println!("{}", fact.statement);
65//! }
66//! # Ok(())
67//! # }
68//! ```
69
70pub mod bm25;
71pub mod core;
72pub mod engine;
73pub mod evals;
74pub mod ingestion;
75#[cfg(feature = "gemini-llm")]
76pub mod llm;
77pub mod okf;
78pub mod reconcile;
79pub mod retrieval;
80pub mod runtime;
81pub mod transcript;
82
83/// The types a typical application touches.
84pub mod prelude {
85 pub use crate::bm25::{MemoryIndex, SearchExplanation, SearchHit};
86 pub use crate::core::{
87 CanonicalMemory, CanonicalPredicate, EntityRef, Explicitness, MemoryError, MemoryEvent,
88 MemoryKind, MemoryObservation, MemoryRuntimeConfig, MemoryStatus, MemoryValue,
89 MutationIntent, ProposedPersistence, SensitivityClass, SessionId, SpeakerAttribution,
90 TemporalScope, TurnId, UserId,
91 };
92 pub use crate::engine::{MemoryEngine, MemorySession};
93 pub use crate::ingestion::{SessionCandidate, SessionCandidateStatus, SessionMemoryOverlay};
94 pub use crate::okf::{MemoryRepository, OkfDocument};
95 pub use crate::reconcile::{ProposedMemory, ResolutionKind, ResolvedMutation};
96 pub use crate::retrieval::{
97 MemoryRetriever, PreparedMemorySnapshot, RetrievalPlan, RetrievedMemory,
98 };
99 pub use crate::runtime::{MemorySlot, MemoryTurnExtractor};
100}