Skip to main content

leviathan/
lib.rs

1//! Leviathan: deep memory for agents over large datasets.
2//!
3//! Index JSONL, JSON, CSV or SQLite records into a single SQLite/FTS5 file,
4//! then answer questions with a few ranked, cited cards instead of the raw
5//! data. A small field mapping (`leviathan.toml`, CLI flags, or inference)
6//! says which fields are the id, title, searchable text, group, date and
7//! filters. Use it from the CLI, as an MCP server, or as a library:
8//!
9//! ```no_run
10//! use leviathan::{card::CardOptions, query::{SearchRequest, Store}};
11//!
12//! let store = Store::open("leviathan.db".as_ref(), CardOptions::default())?;
13//! let hits = store.search(&SearchRequest {
14//!     group: Some("acme".into()),
15//!     query: "login loops after password reset".into(),
16//!     filters: vec![("status".into(), "closed".into())],
17//!     limit: 5,
18//!     fallback: true,
19//!     ..Default::default()
20//! })?;
21//! println!("{}", leviathan::render::search(&hits));
22//! # anyhow::Ok(())
23//! ```
24
25pub mod card;
26pub mod config;
27pub mod fields;
28pub mod index;
29pub mod infer;
30pub mod mcp;
31pub mod query;
32pub mod render;
33pub mod source;
34pub mod text;
35pub mod wrap;
36
37/// Current UTC time as RFC 3339, without a date-time dependency.
38pub fn now_rfc3339() -> String {
39    let secs = std::time::SystemTime::now()
40        .duration_since(std::time::UNIX_EPOCH)
41        .map(|d| d.as_secs() as i64)
42        .unwrap_or(0);
43    text::format_unix(secs)
44}