{
  "name": "forge-embed",
  "language": "rust",
  "version": "0.2.0",
  "description": "Embedding, reranking, vector store, and RAG primitives for the Forge SDK",
  "manifest": "forge-rs/crates/forge-embed/Cargo.toml",
  "manifestSha256": "fdaf0df7c5bf1f097cadc779ff1e169f6392277cf545d9c910f28f9f9fb2ec79",
  "status": "source-reference",
  "registryPublicationVerified": false,
  "route": "/libraries/rust/forge-embed",
  "features": {},
  "files": [
    {
      "path": "forge-rs/crates/forge-embed/src/chunking.rs",
      "sha256": "fbdc79c82f2cf6ea447a067b584a94d6489119f7999c45f048ac7fbea8662a58",
      "artifactSha256": "dcea115a9aa07696852560b2ee7cfe1ab4554b8438fa6a458686d32404963f32",
      "url": "/reference/source/forge-rs/crates/forge-embed/src/chunking.rs.txt",
      "declarations": [
        {
          "name": "::TextSplitter",
          "line": 48,
          "signature": "pub trait TextSplitter: Send + Sync {\n    /// Splits the input text into chunks.\n    ///\n    /// # Arguments\n    ///\n    /// * `text` - The text to split.\n    ///\n    /// # Returns\n    ///\n    /// A vector of non-empty string chunks. Returns an empty vector if the\n    /// input is empty.\n    fn split(&self, text: &str) -> Vec<String>;\n}",
          "documentation": "Trait for text splitting strategies.\n\nImplementors break a text into smaller chunks suitable for embedding.\nEach chunk should be a meaningful unit of text (not split mid-word when\npossible).\n\n# Examples\n\n```\nuse forge_embed::chunking::TextSplitter;\n\nstruct FixedSplitter { size: usize }\n\nimpl TextSplitter for FixedSplitter {\n    fn split(&self, text: &str) -> Vec<String> {\n        text.chars()\n            .collect::<Vec<_>>()\n            .chunks(self.size)\n            .map(|c| c.iter().collect())\n            .collect()\n    }\n}\n\nlet splitter = FixedSplitter { size: 5 };\nlet chunks = splitter.split(\"HelloWorld\");\nassert_eq!(chunks, vec![\"Hello\", \"World\"]);\n```"
        },
        {
          "name": "::RecursiveCharacterSplitter",
          "line": 84,
          "signature": "#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct RecursiveCharacterSplitter {\n\n}",
          "documentation": "Splits text recursively using a hierarchy of separators.\n\nTries to split on paragraph boundaries first (`\\n\\n`), then sentence\nboundaries (`. `), then word boundaries (` `), and finally by individual\ncharacters. This preserves semantic coherence as much as possible.\n\n# Configuration\n\n- `chunk_size` -- Target maximum chunk size in characters.\n- `overlap` -- Number of characters to overlap between consecutive chunks.\n\n# Examples\n\n```\nuse forge_embed::chunking::{TextSplitter, RecursiveCharacterSplitter};\n\nlet splitter = RecursiveCharacterSplitter::new(100, 20);\nlet text = \"First paragraph with some content.\\n\\nSecond paragraph with more content.\";\nlet chunks = splitter.split(text);\nassert!(chunks.len() >= 1);\n```"
        },
        {
          "name": "::RecursiveCharacterSplitter::new",
          "line": 112,
          "signature": "pub fn new(chunk_size: usize, overlap: usize) -> Self;",
          "documentation": "Creates a new `RecursiveCharacterSplitter` with the given chunk size and overlap.\n\nUses the default separator hierarchy: `[\"\\n\\n\", \"\\n\", \". \", \" \"]`.\n\n# Arguments\n\n* `chunk_size` - Target maximum chunk size in characters. Must be > 0.\n  If 0 is passed, it is clamped to 1.\n* `overlap` - Number of characters to overlap between chunks. If larger\n  than `chunk_size`, it is clamped to `chunk_size - 1`.\n\n# Examples\n\n```\nuse forge_embed::chunking::RecursiveCharacterSplitter;\n\nlet splitter = RecursiveCharacterSplitter::new(500, 50);\n```"
        },
        {
          "name": "::RecursiveCharacterSplitter::with_separators",
          "line": 149,
          "signature": "pub fn with_separators(chunk_size: usize, overlap: usize, separators: Vec<String>) -> Self;",
          "documentation": "Creates a splitter with custom separators.\n\n# Arguments\n\n* `chunk_size` - Target maximum chunk size in characters. Clamped to 1 if 0.\n* `overlap` - Number of overlap characters. Clamped to `chunk_size - 1`.\n* `separators` - Custom separator hierarchy, tried in order.\n\n# Examples\n\n```\nuse forge_embed::chunking::RecursiveCharacterSplitter;\n\nlet splitter = RecursiveCharacterSplitter::with_separators(\n    200, 20,\n    vec![\"---\".to_string(), \"\\n\".to_string(), \" \".to_string()],\n);\n```"
        },
        {
          "name": "::RecursiveCharacterSplitter::chunk_size",
          "line": 164,
          "signature": "pub fn chunk_size(&self) -> usize;",
          "documentation": "Returns the configured chunk size."
        },
        {
          "name": "::RecursiveCharacterSplitter::overlap",
          "line": 169,
          "signature": "pub fn overlap(&self) -> usize;",
          "documentation": "Returns the configured overlap."
        },
        {
          "name": "::TokenSplitter",
          "line": 295,
          "signature": "#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct TokenSplitter {\n\n}",
          "documentation": "Splits text by approximate token count using whitespace boundaries.\n\nUses word-level splitting as an approximation of tokenization. Each\nchunk contains at most `tokens_per_chunk` whitespace-delimited words.\n\n# Configuration\n\n- `tokens_per_chunk` -- Maximum number of words per chunk.\n- `overlap_tokens` -- Number of words to overlap between consecutive chunks.\n\n# Examples\n\n```\nuse forge_embed::chunking::{TextSplitter, TokenSplitter};\n\nlet splitter = TokenSplitter::new(3, 1);\nlet chunks = splitter.split(\"one two three four five\");\nassert_eq!(chunks.len(), 2); // [\"one two three\", \"three four five\"]\n```"
        },
        {
          "name": "::TokenSplitter::new",
          "line": 317,
          "signature": "pub fn new(tokens_per_chunk: usize, overlap_tokens: usize) -> Self;",
          "documentation": "Creates a new `TokenSplitter` with the given tokens per chunk and overlap.\n\n# Arguments\n\n* `tokens_per_chunk` - Maximum words per chunk. Must be > 0; clamped to 1 if 0.\n* `overlap_tokens` - Words to overlap. Clamped to `tokens_per_chunk - 1`.\n\n# Examples\n\n```\nuse forge_embed::chunking::TokenSplitter;\n\nlet splitter = TokenSplitter::new(100, 10);\n```"
        },
        {
          "name": "::TokenSplitter::tokens_per_chunk",
          "line": 335,
          "signature": "pub fn tokens_per_chunk(&self) -> usize;",
          "documentation": "Returns the configured tokens per chunk."
        },
        {
          "name": "::TokenSplitter::overlap_tokens",
          "line": 340,
          "signature": "pub fn overlap_tokens(&self) -> usize;",
          "documentation": "Returns the configured overlap tokens."
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-embed/src/document.rs",
      "sha256": "8d95d8e9d6be575f5d12050c9c17c1c9a27e67c436bd5fff569099e9a0c4aa3e",
      "artifactSha256": "c1cc60d291ed83b32af9e2be1fb7b7c45c8abe75b355dc13ec9b4c99d2c800bd",
      "url": "/reference/source/forge-rs/crates/forge-embed/src/document.rs.txt",
      "declarations": [
        {
          "name": "::Document",
          "line": 38,
          "signature": "#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Document {\n/// The text content of the document.\n\npub content: String,\n/// Arbitrary metadata associated with this document.\n\npub metadata: serde_json::Value\n}",
          "documentation": "A loaded document with its text content and metadata.\n\nRepresents a single document or text fragment in a RAG pipeline.\nMetadata is stored as a JSON value for maximum flexibility.\n\n# Examples\n\n```\nuse forge_embed::document::Document;\nuse serde_json::json;\n\nlet doc = Document {\n    content: \"The quick brown fox.\".to_string(),\n    metadata: json!({\"source\": \"example.txt\", \"page\": 1}),\n};\nassert!(!doc.content.is_empty());\n```"
        },
        {
          "name": "::Document::new",
          "line": 61,
          "signature": "pub fn new(content: impl Into<String>) -> Self;",
          "documentation": "Creates a new document with the given content and empty metadata.\n\n# Arguments\n\n* `content` - The text content.\n\n# Examples\n\n```\nuse forge_embed::document::Document;\n\nlet doc = Document::new(\"Some text.\");\nassert_eq!(doc.content, \"Some text.\");\nassert_eq!(doc.metadata, serde_json::Value::Null);\n```"
        },
        {
          "name": "::Document::with_metadata",
          "line": 84,
          "signature": "pub fn with_metadata(content: impl Into<String>, metadata: serde_json::Value) -> Self;",
          "documentation": "Creates a new document with content and metadata.\n\n# Arguments\n\n* `content` - The text content.\n* `metadata` - Metadata to associate with the document.\n\n# Examples\n\n```\nuse forge_embed::document::Document;\nuse serde_json::json;\n\nlet doc = Document::with_metadata(\"content\", json!({\"key\": \"value\"}));\nassert_eq!(doc.metadata[\"key\"], \"value\");\n```"
        },
        {
          "name": "::Document::is_empty",
          "line": 92,
          "signature": "pub fn is_empty(&self) -> bool;",
          "documentation": "Returns `true` if the document content is empty."
        },
        {
          "name": "::Document::len",
          "line": 97,
          "signature": "pub fn len(&self) -> usize;",
          "documentation": "Returns the character length of the document content."
        },
        {
          "name": "::DocumentLoader",
          "line": 125,
          "signature": "pub trait DocumentLoader: Send + Sync {\n    /// Loads documents from the given source string.\n    ///\n    /// # Arguments\n    ///\n    /// * `source` - The source to load from. Interpretation depends on the\n    ///   implementation (raw text, JSON string, file path, etc.).\n    ///\n    /// # Returns\n    ///\n    /// A vector of loaded documents.\n    ///\n    /// # Errors\n    ///\n    /// Returns [`ForgeEmbedError`] if loading fails (e.g., invalid format,\n    /// empty input).\n    fn load(&self, source: &str) -> EmbedResult<Vec<Document>>;\n}",
          "documentation": "Trait for loading documents from a source.\n\nImplementors convert a source (text, JSON, file path, URL, etc.) into\na vector of [`Document`] instances.\n\n# Examples\n\n```\nuse forge_embed::document::{DocumentLoader, Document};\nuse forge_embed::error::ForgeEmbedError;\n\nstruct UpperLoader;\n\nimpl DocumentLoader for UpperLoader {\n    fn load(&self, source: &str) -> Result<Vec<Document>, ForgeEmbedError> {\n        Ok(vec![Document::new(source.to_uppercase())])\n    }\n}\n\nlet loader = UpperLoader;\nlet docs = loader.load(\"hello\").unwrap();\nassert_eq!(docs[0].content, \"HELLO\");\n```"
        },
        {
          "name": "::TextLoader",
          "line": 160,
          "signature": "#[derive(Debug, Clone, Copy, Default)]\npub struct TextLoader;",
          "documentation": "Loads plain text as a single document.\n\nThe entire source string becomes the content of one document. Metadata\nincludes the character length.\n\n# Examples\n\n```\nuse forge_embed::document::{DocumentLoader, TextLoader};\n\nlet loader = TextLoader;\nlet docs = loader.load(\"Hello, world!\").unwrap();\nassert_eq!(docs.len(), 1);\nassert_eq!(docs[0].content, \"Hello, world!\");\n```"
        },
        {
          "name": "::JsonLoader",
          "line": 204,
          "signature": "#[derive(Debug, Clone, Default)]\npub struct JsonLoader {\n\n}",
          "documentation": "Loads a JSON string and extracts text content from specified fields.\n\nIf the JSON is an object, each string-valued field becomes a separate\ndocument. If the JSON is an array of objects, each object's string fields\nare extracted as documents. Non-string fields are skipped.\n\n# Configuration\n\n- `content_field` -- If set, only extract text from this field name.\n  If `None`, all string fields are extracted.\n\n# Examples\n\n```\nuse forge_embed::document::{DocumentLoader, JsonLoader};\n\nlet loader = JsonLoader::new(Some(\"text\".to_string()));\nlet json = r#\"[{\"text\": \"Hello\"}, {\"text\": \"World\"}]\"#;\nlet docs = loader.load(json).unwrap();\nassert_eq!(docs.len(), 2);\nassert_eq!(docs[0].content, \"Hello\");\nassert_eq!(docs[1].content, \"World\");\n```"
        },
        {
          "name": "::JsonLoader::new",
          "line": 228,
          "signature": "pub fn new(content_field: Option<String>) -> Self;",
          "documentation": "Creates a new `JsonLoader` with an optional content field filter.\n\n# Arguments\n\n* `content_field` - If `Some`, only extract text from fields with\n  this name. If `None`, extract all string fields.\n\n# Examples\n\n```\nuse forge_embed::document::JsonLoader;\n\n// Extract only the \"body\" field from JSON objects\nlet loader = JsonLoader::new(Some(\"body\".to_string()));\n\n// Extract all string fields\nlet loader = JsonLoader::new(None);\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-embed/src/embed.rs",
      "sha256": "eb51d8b701081c2e2939e1ba0778ec1685017b467a99a88204016a610365e324",
      "artifactSha256": "abf7b5a316d4e5351ee7faee6a58e0910be220a43dfc384ff3463de75781e9d2",
      "url": "/reference/source/forge-rs/crates/forge-embed/src/embed.rs.txt",
      "declarations": [
        {
          "name": "::EmbeddingResult",
          "line": 42,
          "signature": "#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct EmbeddingResult {\n/// The embedding vector.\n\npub vector: Vec<f64>,\n/// The model that produced this embedding.\n\npub model: String,\n/// The number of dimensions in the embedding vector.\n\npub dimensions: usize\n}",
          "documentation": "The result of embedding a single text input.\n\nContains the embedding vector, the model that produced it, and the\nvector dimensionality.\n\n# Examples\n\n```\nuse forge_embed::embed::EmbeddingResult;\n\nlet result = EmbeddingResult {\n    vector: vec![0.1, 0.2, 0.3],\n    model: \"text-embedding-3-small\".to_string(),\n    dimensions: 3,\n};\nassert_eq!(result.dimensions, result.vector.len());\n```"
        },
        {
          "name": "::EmbeddingProvider",
          "line": 83,
          "signature": "#[async_trait]\npub trait EmbeddingProvider: Send + Sync {\n    /// Returns the model identifier for this provider (e.g., \"text-embedding-3-small\").\n    fn model_id(&self) -> &str;\n\n    /// Generates embedding vectors for one or more text inputs.\n    ///\n    /// # Arguments\n    ///\n    /// * `input` - A slice of strings to embed. Must contain at least one item.\n    ///\n    /// # Returns\n    ///\n    /// A vector of embedding vectors, one per input string, in the same order.\n    ///\n    /// # Errors\n    ///\n    /// Returns [`ForgeEmbedError::ModelError`] if the provider call fails,\n    /// or [`ForgeEmbedError::EmptyInput`] if the input slice is empty.\n    async fn embed(&self, input: &[String]) -> Result<Vec<Vec<f64>>, ForgeEmbedError>;\n}",
          "documentation": "Trait for pluggable embedding backends.\n\nImplementors provide the actual embedding logic (e.g., calling an API\nlike OpenAI, running a local model, etc.). The trait is object-safe\nand supports async execution.\n\n# ANVIL Spec SS6.3\n\nEvery ANVIL-compliant runtime must support at least one embedding provider.\nProvider implementations must be `Send + Sync` for use in async contexts.\n\n# Examples\n\n```\nuse forge_embed::embed::EmbeddingProvider;\nuse forge_embed::error::ForgeEmbedError;\nuse async_trait::async_trait;\n\nstruct MockProvider;\n\n#[async_trait]\nimpl EmbeddingProvider for MockProvider {\n    fn model_id(&self) -> &str {\n        \"mock-embed-v1\"\n    }\n\n    async fn embed(&self, input: &[String]) -> Result<Vec<Vec<f64>>, ForgeEmbedError> {\n        Ok(input.iter().map(|_| vec![0.1, 0.2, 0.3]).collect())\n    }\n}\n```"
        },
        {
          "name": "::embed",
          "line": 131,
          "signature": "pub async fn embed(provider: &dyn EmbeddingProvider, text: &str) -> EmbedResult<EmbeddingResult>;",
          "documentation": "Embeds a single text string using the given provider.\n\nThis is a convenience wrapper around [`EmbeddingProvider::embed`] for the\ncommon case of embedding one document or query at a time.\n\n# Arguments\n\n* `provider` - The embedding provider to use.\n* `text` - The text to embed.\n\n# Returns\n\nAn [`EmbeddingResult`] containing the vector, model name, and dimensions.\n\n# Errors\n\nReturns [`ForgeEmbedError::EmptyInput`] if `text` is empty.\nReturns [`ForgeEmbedError::ModelError`] if the provider call fails.\n\n# Examples\n\n```no_run\n# use forge_embed::embed::{embed, EmbeddingProvider};\n# async fn example(provider: &dyn EmbeddingProvider) {\nlet result = embed(provider, \"What is machine learning?\").await;\n# }\n```"
        },
        {
          "name": "::embed_many",
          "line": 194,
          "signature": "pub async fn embed_many(\n    provider: &dyn EmbeddingProvider,\n    texts: &[String],\n) -> EmbedResult<Vec<EmbeddingResult>>;",
          "documentation": "Embeds multiple text strings using the given provider.\n\nSends all inputs in a single batch call to the provider. The returned\nresults are in the same order as the input strings.\n\n# Arguments\n\n* `provider` - The embedding provider to use.\n* `texts` - The texts to embed. Must contain at least one item.\n\n# Returns\n\nA vector of [`EmbeddingResult`] values, one per input text.\n\n# Errors\n\nReturns [`ForgeEmbedError::EmptyInput`] if `texts` is empty.\nReturns [`ForgeEmbedError::ModelError`] if the provider call fails or\nreturns a different number of vectors than inputs.\n\n# Examples\n\n```no_run\n# use forge_embed::embed::{embed_many, EmbeddingProvider};\n# async fn example(provider: &dyn EmbeddingProvider) {\nlet texts = vec![\"Hello\".to_string(), \"World\".to_string()];\nlet results = embed_many(provider, &texts).await;\n# }\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-embed/src/error.rs",
      "sha256": "6d3240e5e78a7afd1719ace97c96e290fccda5e395648a43aef69d4377744ac5",
      "artifactSha256": "2456b4c49d9599d4b84a626b4529f5a4c7da240db8ac12e70329e18466681bb4",
      "url": "/reference/source/forge-rs/crates/forge-embed/src/error.rs.txt",
      "declarations": [
        {
          "name": "::ForgeEmbedError",
          "line": 31,
          "signature": "#[derive(Debug, Error)]\npub enum ForgeEmbedError {\n    /// The embedding model returned an error.\n    #[error(\"embedding model '{model}' failed: {reason}\")]\n    ModelError {\n        /// The model identifier that was used.\n        model: String,\n        /// A description of what went wrong.\n        reason: String,\n    },\n\n    /// Vector dimensions do not match for the requested operation.\n    #[error(\"dimension mismatch: vector A has {a} dimensions but vector B has {b} dimensions; both must be equal for {operation}\")]\n    DimensionMismatch {\n        /// Dimensions of the first vector.\n        a: usize,\n        /// Dimensions of the second vector.\n        b: usize,\n        /// The operation that required matching dimensions.\n        operation: String,\n    },\n\n    /// An empty input was provided where at least one item is required.\n    #[error(\"empty input for '{operation}': at least one item is required\")]\n    EmptyInput {\n        /// The operation that received empty input.\n        operation: String,\n    },\n\n    /// A vector store operation failed.\n    #[error(\"vector store error during '{operation}': {reason}\")]\n    StoreError {\n        /// The store operation that failed (e.g., \"insert\", \"search\", \"delete\").\n        operation: String,\n        /// A description of what went wrong.\n        reason: String,\n    },\n\n    /// A text chunking operation failed.\n    #[error(\"chunking error: {reason}\")]\n    ChunkingError {\n        /// A description of what went wrong during chunking.\n        reason: String,\n    },\n\n    /// An error propagated from the `forge-core` crate.\n    #[error(transparent)]\n    Core(#[from] ForgeError),\n}",
          "documentation": "Errors that can occur during embedding, reranking, vector store, or\nchunking operations.\n\nEach variant includes enough context to identify what failed and why,\nfollowing the Forge SDK convention of actionable error messages.\n\n# Examples\n\n```\nuse forge_embed::error::ForgeEmbedError;\n\nlet err = ForgeEmbedError::EmptyInput {\n    operation: \"embed\".to_string(),\n};\nassert!(err.to_string().contains(\"embed\"));\n```"
        },
        {
          "name": "::EmbedResult",
          "line": 81,
          "signature": "pub type EmbedResult<T> = Result<T, ForgeEmbedError>;",
          "documentation": "A specialized `Result` type for `forge-embed` operations."
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-embed/src/lib.rs",
      "sha256": "d25665ffabb2954fc39de77029df8b435d6469f044ebf48bd2863f15f9c86cab",
      "artifactSha256": "0c011e62e9bb35e4fd690a383fe4acc5e1c88be19b420ac9c9a8ca563b2f8974",
      "url": "/reference/source/forge-rs/crates/forge-embed/src/lib.rs.txt",
      "declarations": [
        {
          "name": "chunking",
          "line": 59,
          "signature": "pub mod chunking;",
          "documentation": "# forge-embed\n\nEmbedding, reranking, vector store, and RAG primitives for the Forge SDK.\n\nThis crate provides everything needed to build retrieval-augmented generation\n(RAG) pipelines with the Forge SDK:\n\n- **Embedding** \u2014 [`embed::embed`] and [`embed::embed_many`] for generating\n  vector representations of text via pluggable [`embed::EmbeddingProvider`]\n  implementations.\n- **Similarity** \u2014 [`similarity::cosine_similarity`], [`similarity::euclidean_distance`],\n  and [`similarity::dot_product`] for comparing embedding vectors.\n- **Reranking** \u2014 [`rerank::rerank`] to reorder documents by relevance, with\n  the pluggable [`rerank::Reranker`] trait for custom strategies.\n- **Vector Store** \u2014 [`vector_store::VectorStore`] trait with an\n  [`vector_store::InMemoryVectorStore`] reference implementation for\n  nearest-neighbor search.\n- **Chunking** \u2014 [`chunking::RecursiveCharacterSplitter`] and\n  [`chunking::TokenSplitter`] for breaking text into embeddable chunks.\n- **Document Loading** \u2014 [`document::TextLoader`] and [`document::JsonLoader`]\n  for loading text from various sources.\n\n# ANVIL Spec Reference\n\nThis crate implements types from the following ANVIL specification sections:\n- SS6.3 \u2014 Embedding Interface\n- SS6.4 \u2014 Reranking Interface\n- SS6.5 \u2014 Vector Store Interface\n\n# Design Principles\n\n- **Pluggable providers** \u2014 Every operation is defined by a trait so\n  implementations can be swapped without changing application code.\n- **Zero unsafe code** \u2014 All operations use safe Rust with iterators.\n- **Typed errors** \u2014 Every fallible function returns a typed [`error::ForgeEmbedError`].\n- **Serialization** \u2014 All data types implement `Serialize` and `Deserialize`.\n\n# Examples\n\n```no_run\nuse forge_embed::prelude::*;\nuse forge_embed::embed::EmbeddingProvider;\nuse forge_embed::error::ForgeEmbedError;\nuse async_trait::async_trait;\n\nstruct MyProvider;\n\n#[async_trait]\nimpl EmbeddingProvider for MyProvider {\n    fn model_id(&self) -> &str { \"my-model\" }\n    async fn embed(&self, input: &[String]) -> Result<Vec<Vec<f64>>, ForgeEmbedError> {\n        Ok(input.iter().map(|_| vec![0.1, 0.2, 0.3]).collect())\n    }\n}\n```"
        },
        {
          "name": "document",
          "line": 60,
          "signature": "pub mod document;",
          "documentation": ""
        },
        {
          "name": "embed",
          "line": 61,
          "signature": "pub mod embed;",
          "documentation": ""
        },
        {
          "name": "error",
          "line": 62,
          "signature": "pub mod error;",
          "documentation": ""
        },
        {
          "name": "rerank",
          "line": 63,
          "signature": "pub mod rerank;",
          "documentation": ""
        },
        {
          "name": "similarity",
          "line": 64,
          "signature": "pub mod similarity;",
          "documentation": ""
        },
        {
          "name": "vector_store",
          "line": 65,
          "signature": "pub mod vector_store;",
          "documentation": ""
        },
        {
          "name": "prelude",
          "line": 68,
          "signature": "pub mod prelude;",
          "documentation": "Re-exports of the most commonly used types."
        },
        {
          "name": "pub use crate::chunking::{RecursiveCharacterSplitter, TextSplitter, TokenSplitter};",
          "line": 69,
          "signature": "pub use crate::chunking::{RecursiveCharacterSplitter, TextSplitter, TokenSplitter};",
          "documentation": ""
        },
        {
          "name": "pub use crate::document::{Document, DocumentLoader, JsonLoader, TextLoader};",
          "line": 70,
          "signature": "pub use crate::document::{Document, DocumentLoader, JsonLoader, TextLoader};",
          "documentation": ""
        },
        {
          "name": "pub use crate::embed::{EmbeddingProvider, EmbeddingResult};",
          "line": 71,
          "signature": "pub use crate::embed::{EmbeddingProvider, EmbeddingResult};",
          "documentation": ""
        },
        {
          "name": "pub use crate::error::{EmbedResult, ForgeEmbedError};",
          "line": 72,
          "signature": "pub use crate::error::{EmbedResult, ForgeEmbedError};",
          "documentation": ""
        },
        {
          "name": "pub use crate::rerank::{RerankResult, Reranker};",
          "line": 73,
          "signature": "pub use crate::rerank::{RerankResult, Reranker};",
          "documentation": ""
        },
        {
          "name": "pub use crate::similarity::{cosine_similarity, dot_product, euclidean_distance};",
          "line": 74,
          "signature": "pub use crate::similarity::{cosine_similarity, dot_product, euclidean_distance};",
          "documentation": ""
        },
        {
          "name": "pub use crate::vector_store::{InMemoryVectorStore, SearchResult, VectorEntry, VectorStore};",
          "line": 75,
          "signature": "pub use crate::vector_store::{InMemoryVectorStore, SearchResult, VectorEntry, VectorStore};",
          "documentation": ""
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-embed/src/rerank.rs",
      "sha256": "3492bef99c4c6a876008cb685249e39965975554ce65570ab40f90228a49437d",
      "artifactSha256": "84e9a0af67215359d383c137e0232cc80ffbb5dede230d48ac2079ef10975971",
      "url": "/reference/source/forge-rs/crates/forge-embed/src/rerank.rs.txt",
      "declarations": [
        {
          "name": "::RerankResult",
          "line": 42,
          "signature": "#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct RerankResult {\n/// The original index of this document in the input slice.\n\npub index: usize,\n/// The relevance score (higher is more relevant).\n\npub score: f64,\n/// The document text.\n\npub document: String\n}",
          "documentation": "A single reranked document with its relevance score and original index.\n\n# Examples\n\n```\nuse forge_embed::rerank::RerankResult;\n\nlet result = RerankResult {\n    index: 2,\n    score: 0.95,\n    document: \"Machine learning is a subset of AI.\".to_string(),\n};\nassert_eq!(result.index, 2);\n```"
        },
        {
          "name": "::Reranker",
          "line": 92,
          "signature": "#[async_trait]\npub trait Reranker: Send + Sync {\n    /// Reranks documents by relevance to a query.\n    ///\n    /// # Arguments\n    ///\n    /// * `query` - The query string to rank documents against.\n    /// * `documents` - The documents to rerank.\n    /// * `top_k` - If provided, return only the top K most relevant results.\n    ///\n    /// # Returns\n    ///\n    /// A vector of [`RerankResult`] sorted by descending relevance score.\n    ///\n    /// # Errors\n    ///\n    /// Returns [`ForgeEmbedError`] if the reranking operation fails.\n    async fn rerank(\n        &self,\n        query: &str,\n        documents: &[String],\n        top_k: Option<usize>,\n    ) -> Result<Vec<RerankResult>, ForgeEmbedError>;\n}",
          "documentation": "Trait for pluggable reranking strategies.\n\nImplementors can provide custom reranking logic such as cross-encoder\nmodels, BM25 scoring, or hybrid approaches.\n\n# Examples\n\n```\nuse forge_embed::rerank::{Reranker, RerankResult};\nuse forge_embed::error::ForgeEmbedError;\nuse async_trait::async_trait;\n\nstruct SimpleReranker;\n\n#[async_trait]\nimpl Reranker for SimpleReranker {\n    async fn rerank(\n        &self,\n        query: &str,\n        documents: &[String],\n        top_k: Option<usize>,\n    ) -> Result<Vec<RerankResult>, ForgeEmbedError> {\n        // Simple length-based scoring for demonstration\n        let mut results: Vec<RerankResult> = documents\n            .iter()\n            .enumerate()\n            .map(|(i, doc)| RerankResult {\n                index: i,\n                score: 1.0 / (1.0 + (doc.len() as f64 - query.len() as f64).abs()),\n                document: doc.clone(),\n            })\n            .collect();\n        results.sort_by(|a, b| b.score.partial_cmp(&a.score).unwrap_or(std::cmp::Ordering::Equal));\n        if let Some(k) = top_k {\n            results.truncate(k);\n        }\n        Ok(results)\n    }\n}\n```"
        },
        {
          "name": "::rerank",
          "line": 151,
          "signature": "pub async fn rerank(\n    provider: &dyn EmbeddingProvider,\n    query: &str,\n    documents: &[String],\n    top_k: Option<usize>,\n) -> EmbedResult<Vec<RerankResult>>;",
          "documentation": "Reranks documents by cosine similarity to a query using an embedding provider.\n\nThis is the default reranking strategy: embed the query and all documents,\nthen sort by cosine similarity (highest first).\n\n# Arguments\n\n* `provider` - The embedding provider to use for vectorizing query and documents.\n* `query` - The query string.\n* `documents` - The documents to rerank.\n* `top_k` - If provided, return only the top K most relevant results.\n\n# Returns\n\nA vector of [`RerankResult`] sorted by descending cosine similarity.\n\n# Errors\n\nReturns [`ForgeEmbedError::EmptyInput`] if `query` is empty or `documents` is empty.\nReturns [`ForgeEmbedError::ModelError`] if the embedding provider fails.\n\n# Examples\n\n```no_run\n# use forge_embed::rerank::rerank;\n# use forge_embed::embed::EmbeddingProvider;\n# async fn example(provider: &dyn EmbeddingProvider) {\nlet documents = vec![\n    \"Rust is a systems programming language.\".to_string(),\n    \"Python is popular for data science.\".to_string(),\n    \"Machine learning uses neural networks.\".to_string(),\n];\nlet results = rerank(provider, \"programming language\", &documents, Some(2)).await;\n# }\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-embed/src/similarity.rs",
      "sha256": "619ea0af9aaf0b22c34c0b9d7094f60d95f13c36d9d48234127111a3af680e8f",
      "artifactSha256": "16339ec55838f03e0f9a71ec12fabc4688921a88d9fb6f2dbe62fb0e9e93c800",
      "url": "/reference/source/forge-rs/crates/forge-embed/src/similarity.rs.txt",
      "declarations": [
        {
          "name": "::cosine_similarity",
          "line": 97,
          "signature": "pub fn cosine_similarity(a: &[f64], b: &[f64]) -> EmbedResult<f64>;",
          "documentation": "Computes the cosine similarity between two vectors.\n\nCosine similarity measures the cosine of the angle between two vectors,\nproducing a value between -1.0 (opposite) and 1.0 (identical direction).\nA value of 0.0 indicates orthogonal (unrelated) vectors.\n\n# Formula\n\n`cos(a, b) = (a . b) / (|a| * |b|)`\n\n# Arguments\n\n* `a` - The first vector.\n* `b` - The second vector. Must have the same length as `a`.\n\n# Returns\n\nThe cosine similarity as a value in `[-1.0, 1.0]`. Returns `0.0` if\neither vector has zero magnitude (to avoid division by zero).\n\n# Errors\n\nReturns [`ForgeEmbedError::DimensionMismatch`] if the vectors have\ndifferent lengths.\nReturns [`ForgeEmbedError::EmptyInput`] if the vectors are empty.\n\n# Examples\n\n```\nuse forge_embed::similarity::cosine_similarity;\n\n// Identical direction\nlet sim = cosine_similarity(&[1.0, 0.0], &[2.0, 0.0]).unwrap();\nassert!((sim - 1.0).abs() < 1e-10);\n\n// Opposite direction\nlet sim = cosine_similarity(&[1.0, 0.0], &[-1.0, 0.0]).unwrap();\nassert!((sim - (-1.0)).abs() < 1e-10);\n\n// Orthogonal\nlet sim = cosine_similarity(&[1.0, 0.0], &[0.0, 1.0]).unwrap();\nassert!((sim - 0.0).abs() < 1e-10);\n```"
        },
        {
          "name": "::euclidean_distance",
          "line": 150,
          "signature": "pub fn euclidean_distance(a: &[f64], b: &[f64]) -> EmbedResult<f64>;",
          "documentation": "Computes the Euclidean distance between two vectors.\n\nEuclidean distance (L2 norm of the difference) measures the straight-line\ndistance between two points in N-dimensional space. Returns a non-negative\nvalue where 0.0 indicates identical vectors.\n\n# Formula\n\n`dist(a, b) = sqrt(sum((a_i - b_i)^2))`\n\n# Arguments\n\n* `a` - The first vector.\n* `b` - The second vector. Must have the same length as `a`.\n\n# Returns\n\nThe Euclidean distance, a non-negative `f64` value.\n\n# Errors\n\nReturns [`ForgeEmbedError::DimensionMismatch`] if the vectors have\ndifferent lengths.\nReturns [`ForgeEmbedError::EmptyInput`] if the vectors are empty.\n\n# Examples\n\n```\nuse forge_embed::similarity::euclidean_distance;\n\n// Identical vectors have distance 0\nlet dist = euclidean_distance(&[1.0, 2.0], &[1.0, 2.0]).unwrap();\nassert!((dist - 0.0).abs() < 1e-10);\n\n// Distance between (0,0) and (3,4) is 5\nlet dist = euclidean_distance(&[0.0, 0.0], &[3.0, 4.0]).unwrap();\nassert!((dist - 5.0).abs() < 1e-10);\n```"
        },
        {
          "name": "::dot_product",
          "line": 201,
          "signature": "pub fn dot_product(a: &[f64], b: &[f64]) -> EmbedResult<f64>;",
          "documentation": "Computes the dot product of two vectors.\n\nThe dot product (inner product) combines magnitude and direction alignment.\nIt is used in many similarity computations and as a raw building block.\n\n# Formula\n\n`dot(a, b) = sum(a_i * b_i)`\n\n# Arguments\n\n* `a` - The first vector.\n* `b` - The second vector. Must have the same length as `a`.\n\n# Returns\n\nThe scalar dot product.\n\n# Errors\n\nReturns [`ForgeEmbedError::DimensionMismatch`] if the vectors have\ndifferent lengths.\nReturns [`ForgeEmbedError::EmptyInput`] if the vectors are empty.\n\n# Examples\n\n```\nuse forge_embed::similarity::dot_product;\n\nlet result = dot_product(&[1.0, 2.0, 3.0], &[4.0, 5.0, 6.0]).unwrap();\nassert!((result - 32.0).abs() < 1e-10);\n\n// Orthogonal vectors\nlet result = dot_product(&[1.0, 0.0], &[0.0, 1.0]).unwrap();\nassert!((result - 0.0).abs() < 1e-10);\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-embed/src/vector_store.rs",
      "sha256": "2857ad400d7305d797a88518d5cfba5c391b4c48d9923175963de90541055b8d",
      "artifactSha256": "2c5481f681b3c316c068bfcd6a7625044aa03ba1d1b00982ca2240d7a051f692",
      "url": "/reference/source/forge-rs/crates/forge-embed/src/vector_store.rs.txt",
      "declarations": [
        {
          "name": "::VectorEntry",
          "line": 56,
          "signature": "#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct VectorEntry {\n/// Unique identifier for this entry.\n\npub id: String,\n/// The embedding vector.\n\npub vector: Vec<f64>,\n/// Arbitrary metadata associated with this entry.\n\npub metadata: serde_json::Value\n}",
          "documentation": "A single entry in a vector store.\n\nAssociates an embedding vector with an identifier and arbitrary metadata.\n\n# Examples\n\n```\nuse forge_embed::vector_store::VectorEntry;\nuse serde_json::json;\n\nlet entry = VectorEntry {\n    id: \"doc-42\".to_string(),\n    vector: vec![0.1, 0.2, 0.3],\n    metadata: json!({\"source\": \"wikipedia\", \"title\": \"Rust\"}),\n};\nassert_eq!(entry.id, \"doc-42\");\n```"
        },
        {
          "name": "::SearchResult",
          "line": 86,
          "signature": "#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct SearchResult {\n/// The matched vector entry.\n\npub entry: VectorEntry,\n/// The similarity score (higher is more similar).\n\npub score: f64\n}",
          "documentation": "A search result from a vector store query.\n\nContains the matched entry and its similarity score relative to the query.\n\n# Examples\n\n```\nuse forge_embed::vector_store::{SearchResult, VectorEntry};\nuse serde_json::json;\n\nlet result = SearchResult {\n    entry: VectorEntry {\n        id: \"doc-1\".to_string(),\n        vector: vec![1.0, 0.0],\n        metadata: json!({}),\n    },\n    score: 0.95,\n};\nassert!(result.score > 0.9);\n```"
        },
        {
          "name": "::VectorStore",
          "line": 131,
          "signature": "#[async_trait]\npub trait VectorStore: Send + Sync {\n    /// Inserts or updates a vector entry in the store.\n    ///\n    /// If an entry with the same `id` already exists, it is replaced.\n    ///\n    /// # Arguments\n    ///\n    /// * `entry` - The vector entry to insert.\n    ///\n    /// # Errors\n    ///\n    /// Returns [`ForgeEmbedError::StoreError`] if the insertion fails.\n    async fn insert(&mut self, entry: VectorEntry) -> EmbedResult<()>;\n\n    /// Searches for the nearest vectors to the query.\n    ///\n    /// Returns up to `top_k` results sorted by descending similarity score.\n    ///\n    /// # Arguments\n    ///\n    /// * `query` - The query embedding vector.\n    /// * `top_k` - Maximum number of results to return.\n    ///\n    /// # Returns\n    ///\n    /// A vector of [`SearchResult`] sorted by descending similarity score.\n    ///\n    /// # Errors\n    ///\n    /// Returns [`ForgeEmbedError::StoreError`] if the search fails.\n    /// Returns [`ForgeEmbedError::EmptyInput`] if the query vector is empty.\n    async fn search(&self, query: &[f64], top_k: usize) -> EmbedResult<Vec<SearchResult>>;\n\n    /// Deletes a vector entry by ID.\n    ///\n    /// # Arguments\n    ///\n    /// * `id` - The identifier of the entry to delete.\n    ///\n    /// # Returns\n    ///\n    /// `true` if the entry was found and deleted, `false` if it did not exist.\n    ///\n    /// # Errors\n    ///\n    /// Returns [`ForgeEmbedError::StoreError`] if the deletion fails.\n    async fn delete(&mut self, id: &str) -> EmbedResult<bool>;\n}",
          "documentation": "Trait for pluggable vector storage backends.\n\nImplementors provide persistent (or ephemeral) storage for embedding\nvectors with nearest-neighbor search capabilities.\n\n# ANVIL Spec SS6.5\n\nEvery ANVIL-compliant runtime that supports RAG must implement this\ninterface. The trait is object-safe and supports async operations.\n\n# Examples\n\n```no_run\nuse forge_embed::vector_store::{VectorStore, VectorEntry, SearchResult};\nuse forge_embed::error::ForgeEmbedError;\nuse async_trait::async_trait;\n\nstruct MyStore;\n\n#[async_trait]\nimpl VectorStore for MyStore {\n    async fn insert(&mut self, entry: VectorEntry) -> Result<(), ForgeEmbedError> {\n        // Store the entry in your backend\n        Ok(())\n    }\n\n    async fn search(&self, query: &[f64], top_k: usize) -> Result<Vec<SearchResult>, ForgeEmbedError> {\n        // Find nearest neighbors\n        Ok(vec![])\n    }\n\n    async fn delete(&mut self, id: &str) -> Result<bool, ForgeEmbedError> {\n        // Remove the entry\n        Ok(false)\n    }\n}\n```"
        },
        {
          "name": "::InMemoryVectorStore",
          "line": 212,
          "signature": "#[derive(Debug, Default)]\npub struct InMemoryVectorStore {\n\n}",
          "documentation": "A simple in-memory vector store backed by a `HashMap`.\n\nUses brute-force cosine similarity search. Suitable for testing,\nprototyping, and small datasets. For production use with large\ncollections, use a dedicated vector database backend.\n\n# Examples\n\n```no_run\nuse forge_embed::vector_store::{InMemoryVectorStore, VectorStore, VectorEntry};\nuse serde_json::json;\n\n# async fn example() {\nlet mut store = InMemoryVectorStore::new();\n\nstore.insert(VectorEntry {\n    id: \"a\".to_string(),\n    vector: vec![1.0, 0.0, 0.0],\n    metadata: json!({}),\n}).await.unwrap();\n\nstore.insert(VectorEntry {\n    id: \"b\".to_string(),\n    vector: vec![0.0, 1.0, 0.0],\n    metadata: json!({}),\n}).await.unwrap();\n\nlet results = store.search(&[1.0, 0.0, 0.0], 1).await.unwrap();\nassert_eq!(results[0].entry.id, \"a\");\n# }\n```"
        },
        {
          "name": "::InMemoryVectorStore::new",
          "line": 227,
          "signature": "pub fn new() -> Self;",
          "documentation": "Creates an empty in-memory vector store.\n\n# Examples\n\n```\nuse forge_embed::vector_store::InMemoryVectorStore;\n\nlet store = InMemoryVectorStore::new();\nassert_eq!(store.len(), 0);\n```"
        },
        {
          "name": "::InMemoryVectorStore::len",
          "line": 234,
          "signature": "pub fn len(&self) -> usize;",
          "documentation": "Returns the number of entries in the store."
        },
        {
          "name": "::InMemoryVectorStore::is_empty",
          "line": 239,
          "signature": "pub fn is_empty(&self) -> bool;",
          "documentation": "Returns `true` if the store is empty."
        },
        {
          "name": "::InMemoryVectorStore::contains",
          "line": 244,
          "signature": "pub fn contains(&self, id: &str) -> bool;",
          "documentation": "Returns `true` if the store contains an entry with the given ID."
        },
        {
          "name": "::InMemoryVectorStore::get",
          "line": 249,
          "signature": "pub fn get(&self, id: &str) -> Option<&VectorEntry>;",
          "documentation": "Returns a reference to an entry by ID, if it exists."
        }
      ]
    }
  ]
}
