packages feed

langchain-hs-0.0.3.0: src/Langchain/Embeddings/Core.hs

{- |
Module      : Langchain.Embeddings.Core
Description : Embedding model interface for LangChain Haskell
Copyright   : (c) 2025 Tushar Adhatrao
License     : MIT
Maintainer  : Tushar Adhatrao <tusharadhatrao@gmail.com>
Stability   : experimental

Haskell implementation of LangChain's embedding model abstraction, providing:

- Document vectorization for semantic search
- Query embedding for similarity comparisons
- Integration with document loading pipelines

Example usage:

@
  let oEmbed = defaultOpenAIEmbeddings { apiKey = "api-key" }
  let p = PdfLoader "/home/user/Documents/TS/langchain/SOP.pdf"
  eDocs <- load p
  case eDocs of
    Left err -> error err
    Right docs -> do
      eRes <- embedQuery oEmbed "Hello"
      print eRes
@
-}
module Langchain.Embeddings.Core
  ( -- * Embedding Interface
    Embeddings (..)
  ) where

import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Text (Text)
import Langchain.DocumentLoader.Core
import Langchain.Error (LangchainResult)

{- | Typeclass for embedding models following LangChain's pattern.
Converts text/documents into numerical vectors for machine learning tasks.

Implementations should handle:

- Text preprocessing
- API calls to embedding services
- Error handling for failed requests
- Consistent vector dimensionality

Example instance for a test model:

@
data TestEmbeddings = TestEmbeddings

instance Embeddings TestEmbeddings where
  embedDocuments _ _ = return $ Right [[0.1, 0.2, 0.3]]
  embedQuery _ _ = return $ Right [0.4, 0.5, 0.6]
@
-}
class Embeddings embed where
  {- | Convert documents to embedding vectors

  Example:

  >>> let doc = Document "Hello world" mempty
  >>> embedDocuments TestEmbeddings [doc]
  Right [[0.1, 0.2, 0.3]]
  -}
  embedDocuments :: embed -> [Document] -> IO (LangchainResult [[Float]])

  embedDocumentsM :: MonadIO m => embed -> [Document] -> m (LangchainResult [[Float]])
  embedDocumentsM embeddings docs = liftIO $ embedDocuments embeddings docs

  {- | Convert query text to embedding vector

  Example:

  >>> embedQuery TestEmbeddings "Search query"
  Right [0.4, 0.5, 0.6]
  -}
  embedQuery :: embed -> Text -> IO (LangchainResult [Float])

  embedQueryM :: MonadIO m => embed -> Text -> m (LangchainResult [Float])
  embedQueryM embeddings query = liftIO $ embedQuery embeddings query

{- $examples
Test case patterns:

1. Document embedding
   >>> let docs = [Document "Test content" mempty]
   >>> embedDocuments TestEmbeddings docs
   Right [[0.1, 0.2, 0.3]]

2. Query embedding
   >>> embedQuery TestEmbeddings "Test query"
   Right [0.4, 0.5, 0.6]

3. Error handling
   >>> -- Simulate failed API call
   >>> embedQuery FaultyEmbeddings "Bad request"
   Left "API request failed"
-}