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