langchain-hs-gemini
Google Gemini Interactions v1 API client and LangChain provider for langchain-hs.
Built using type-safe Servant bindings over the official Google GenAI OpenAPI specification (Interactions v1 API), following the design patterns of MercuryTechnologies/openai.
Features
- Type-Safe Servant Bindings (
Gemini.Client):
createInteraction (POST /v1/interactions)
getInteraction (GET /v1/interactions/{id})
cancelInteraction (POST /v1/interactions/{id}/cancel)
deleteInteraction (DELETE /v1/interactions/{id})
embedContent (POST /v1/models/{model}:embedContent)
batchEmbedContents (POST /v1/models/{model}:batchEmbedContents)
- SSE Streaming (
streamGeminiInteraction)
- LangChain ChatModel Provider (
Langchain.Provider.Gemini):
- Full
ChatModel instance supporting synchronous invoke and streaming stream.
- Multi-turn conversation mapping and system instructions.
- Multi-modal content support (Base64 images, audio, documents).
- Function calling & tool binding via
ToolBinder.
- Built-in tools: Code Execution, Google Search, Google Maps, File Search, URL Context.
- LangChain Embeddings (
Langchain.Embeddings.Gemini):
- Effect-polymorphic
Embeddings instance (embedQuery and embedDocuments).
Installation
# package.yaml / .cabal
dependencies:
- langchain-hs-gemini
- langchain-hs-core
Quick Start
1. ChatModel Provider
{-# LANGUAGE OverloadedStrings #-}
import Control.Monad.Except (runExceptT)
import Langchain.Model
import Langchain.Provider.Gemini
main :: IO ()
main = do
let provider = newGemini "AIzaSy..." "gemini-3.6-flash" Nothing
res <- runExceptT $ invoke provider [userMessage "Why is the sky blue?"] Nothing
case res of
Left err -> putStrLn $ "Error: " ++ show err
Right msg -> putStrLn $ extractMessageText msg
2. Streaming with Conduit
import Control.Monad.Trans.Resource (runResourceT)
import Control.Monad.Except (runExceptT)
import Langchain.Model
import Langchain.Provider.Gemini
import Langchain.Stream (collectEvents)
main :: IO ()
main = do
let provider = newGemini "AIzaSy..." "gemini-3.6-flash" Nothing
eEvents <- runResourceT $ runExceptT $ collectEvents $ stream provider [userMessage "Tell me a short story"] Nothing
case eEvents of
Left err -> print err
Right events -> mapM_ print events
3. Embeddings
import Control.Monad.Except (runExceptT)
import Langchain.Embeddings.Core (Embeddings (..))
import Langchain.Embeddings.Gemini (defaultGeminiEmbeddings)
main :: IO ()
main = do
let embeddings = defaultGeminiEmbeddings "AIzaSy..."
res <- runExceptT $ embedQuery embeddings "Functional programming in Haskell"
case res of
Left err -> print err
Right vec -> putStrLn $ "Generated vector with dimension: " ++ show (length vec)
4. Direct Servant Client
import Gemini.Client
main :: IO ()
main = do
env <- newGeminiClientEnv "AIzaSy..."
let req = createModelInteraction "gemini-3.6-flash" (TextInput "Explain quantum computing in one sentence")
res <- runGeminiClient env (createInteraction "AIzaSy..." req)
case res of
Left clientErr -> print clientErr
Right interaction -> print (interactionSteps interaction)