1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// OpenAI, Ollama proper-noun identifiers appear throughout the
// provider docs; backticking them adds no signal.
//! # mnem-embed-providers
//!
//! Embedding-provider adapters for mnem. Ships OpenAI and Ollama out
//! of the box; both behind opt-in (on-by-default) cargo features.
//!
//! ## Scope
//!
//! This crate turns a user-configured provider into a concrete
//! [`Embedder`] that the mnem CLI, MCP server, and Python bindings use
//! to (a) auto-embed node summaries on write and (b) auto-embed query
//! strings on retrieve. That is the piece that makes `mnem retrieve
//! --text ...` semantic-hybrid by default once a provider is
//! configured.
//!
//! ## Invariants
//!
//! - **No tokio / no async.** All adapters are sync, built on top of
//! [`ureq`] (rustls-backed). Mnem cannot afford to drag an async
//! runtime into the CLI or the MCP server.
//! - **No API keys in config / on disk.** The config stores the *name*
//! of the env var holding the key (`api_key_env`). The key itself is
//! read from the environment at adapter-construction time and is
//! never persisted by this crate.
//! - **Deterministic outputs.** Adapters only wrap providers whose
//! `embed(text)` is a pure function of `(provider, model, text)`.
//! Randomised projections would break mnem's agent-replay guarantee.
//! - **`mnem-core` is not a dependency of the HTTP layer.** `mnem-core`
//! still has zero network / HTTP / tokio in its dep tree, preserving
//! the WASM-embeddability promises.
//!
//! ## Usage
//!
//! ```no_run
//! # use mnem_embed_providers::{open, Embedder, ProviderConfig, OpenAiConfig};
//! # fn demo() -> Result<(), Box<dyn std::error::Error>> {
//! let cfg = ProviderConfig::Openai(OpenAiConfig {
//! model: "text-embedding-3-small".into(),
//! ..Default::default()
//! });
//! let embedder = open(&cfg)?;
//! let v = embedder.embed("Alice lives in Berlin")?;
//! assert_eq!(v.len(), embedder.dim() as usize);
//! # Ok(()) }
//! ```
pub
// `onnx` and `onnx-bundled` differ only in the ort runtime source
// (load-dynamic vs download-binaries). The Rust-level adapter is
// identical, so the module compiles on either feature. The
// `compile_error!` at the top of `onnx.rs` rejects the
// both-enabled combination at compile time.
pub use ;
pub use ;
pub use EmbedError;
pub use ;
pub use MockEmbedder;
pub use ;