diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Revision history for ollama-haskell
 
+## 0.1.3.0 -- 2025-03-25
+
+* Added options, tools and tool_calls fields in chat and generate.
+* Exported EmbeddingResponse.
+* Added Format argument in chat and generate function for structured output.
+
 ## 0.1.2.0 -- 2024-11-20
 
 * Added hostUrl and responseTimeOut options in generate function.
diff --git a/ollama-haskell.cabal b/ollama-haskell.cabal
--- a/ollama-haskell.cabal
+++ b/ollama-haskell.cabal
@@ -5,9 +5,9 @@
 -- see: https://github.com/sol/hpack
 
 name:           ollama-haskell
-version:        0.1.2.0
+version:        0.1.3.0
 synopsis:       Haskell bindings for ollama.
-description:    Please see the README on GitHub at <https://github.com/tusharad/ollama-haskell#readme>
+description:    Ollama client for Haskell
 category:       Web
 homepage:       https://github.com/tusharad/ollama-haskell#readme
 bug-reports:    https://github.com/tusharad/ollama-haskell/issues
@@ -53,6 +53,7 @@
     , base >=4.7 && <5
     , base64-bytestring
     , bytestring
+    , containers
     , directory
     , filepath
     , http-client
@@ -76,6 +77,7 @@
     , base >=4.7 && <5
     , base64-bytestring
     , bytestring
+    , containers
     , directory
     , filepath
     , http-client
diff --git a/src/Data/Ollama/Chat.hs b/src/Data/Ollama/Chat.hs
--- a/src/Data/Ollama/Chat.hs
+++ b/src/Data/Ollama/Chat.hs
@@ -12,22 +12,26 @@
   , defaultChatOps
   , ChatOps (..)
   , ChatResponse (..)
+  , Format (..)
+  , schemaFromType 
   ) where
 
 import Control.Exception (try)
 import Data.Aeson
-import Data.ByteString.Char8 qualified as BS
-import Data.ByteString.Lazy.Char8 qualified as BSL
+import qualified Data.ByteString.Char8 as BS
+import qualified Data.ByteString.Lazy.Char8 as BSL
 import Data.List.NonEmpty as NonEmpty
 import Data.Maybe (fromMaybe, isNothing)
 import Data.Ollama.Common.Utils as CU
+import Data.Ollama.Common.Types (Format(..))
 import Data.Text (Text)
-import Data.Text qualified as T
-import Data.Text.Encoding qualified as T
+import qualified Data.Text as T
+import qualified Data.Text.Encoding as T
 import Data.Time (UTCTime)
 import GHC.Generics
 import GHC.Int (Int64)
 import Network.HTTP.Client
+import qualified Data.Aeson.KeyMap as HM
 
 -- | Enumerated roles that can participate in a chat.
 data Role = System | User | Assistant | Tool
@@ -56,6 +60,9 @@
   -- ^ The textual content of the message.
   , images :: Maybe [Text]
   -- ^ Optional list of base64 encoded images that accompany the message.
+  , tool_calls :: Maybe [Value]
+  -- ^ a list of tools in JSON that the model wants to use
+  -- ^ Since 0.1.3.0
   }
   deriving (Show, Eq, Generic, ToJSON, FromJSON)
 
@@ -65,10 +72,11 @@
   -- ^ The name of the chat model to be used.
   , messages :: NonEmpty Message
   -- ^ A non-empty list of messages forming the conversation context.
-  , tools :: Maybe Text
+  , tools :: Maybe [Value]
   -- ^ Optional tools that may be used in the chat.
-  , format :: Maybe Text
-  -- ^ An optional format for the chat response.
+  , format :: Maybe Format
+  -- ^ An optional format for the chat response (json or JSON schema).
+  -- ^ Since 0.1.3.0
   , stream :: Maybe (ChatResponse -> IO (), IO ())
   -- ^ Optional streaming functions where the first handles each chunk of the response, and the second flushes the stream.
   , keepAlive :: Maybe Text
@@ -77,6 +85,9 @@
   -- ^ Override default Ollama host url. Default url = "http://127.0.0.1:11434"
   , responseTimeOut :: Maybe Int
   -- ^ Override default response timeout in minutes. Default = 15 minutes
+  , options :: Maybe Value
+  -- ^ additional model parameters listed in the documentation for the Modelfile such as temperature
+  -- ^ Since 0.1.3.0
   }
 
 instance Show ChatOps where
@@ -128,7 +139,7 @@
   deriving (Show, Eq)
 
 instance ToJSON ChatOps where
-  toJSON (ChatOps model_ messages_ tools_ format_ stream_ keepAlive_ _ _) =
+  toJSON (ChatOps model_ messages_ tools_ format_ stream_ keepAlive_ _ _ options) =
     object
       [ "model" .= model_
       , "messages" .= messages_
@@ -136,6 +147,7 @@
       , "format" .= format_
       , "stream" .= if isNothing stream_ then Just False else Just True
       , "keep_alive" .= keepAlive_
+      , "options" .= options
       ]
 
 instance FromJSON ChatResponse where
@@ -165,13 +177,14 @@
 defaultChatOps =
   ChatOps
     { chatModelName = "llama3.2"
-    , messages = Message User "What is 2+2?" Nothing :| []
+    , messages = Message User "What is 2+2?" Nothing Nothing :| []
     , tools = Nothing
     , format = Nothing
     , stream = Nothing
     , keepAlive = Nothing
     , hostUrl = Nothing
     , responseTimeOut = Nothing
+    , options = Nothing
     }
 
 {- |
@@ -187,6 +200,17 @@
 > case result of
 >   Left errorMsg -> putStrLn ("Error: " ++ errorMsg)
 >   Right response -> print response
+
+To request a JSON format response:
+
+> let ops = defaultChatOps { format = Just JsonFormat }
+> result <- chat ops
+
+To request a structured output with a JSON schema:
+
+> import Data.Aeson (object, (.=))
+> let ops = defaultChatOps { format = Just (SchemaFormat schema) }
+> result <- chat ops
 -}
 chat :: ChatOps -> IO (Either String ChatResponse)
 chat cOps = do
@@ -212,7 +236,8 @@
           IO (Either HttpException (Either String ChatResponse))
       case eRes of
         Left e -> return $ Left $ "HTTP error occured: " <> show e
-        Right r -> return r
+        Right r -> do 
+            return r
 
 handleRequest :: ChatOps -> Response BodyReader -> IO (Either String ChatResponse)
 handleRequest cOps response = do
@@ -249,6 +274,10 @@
  response in certain JSON format and serializes the response. This function will be helpful when you
  want to use the LLM to do something programmatic.
 
+ Note: This function predates the format parameter in the API. For new code, consider using
+ the `format` parameter with a SchemaFormat instead, which leverages the model's native
+ JSON output capabilities.
+
  For Example:
   > let expectedJsonStrucutre = Example {
   >   sortedList = ["sorted List here"]
@@ -283,34 +312,90 @@
   Maybe Int ->
   IO (Either String jsonResult)
 chatJson cOps@ChatOps {..} jsonStructure mMaxRetries = do
-  let lastMessage = NonEmpty.last messages
-      jsonHelperPrompt =
-        "You are an AI that returns only JSON object. \n"
-          <> "* Your output should be a JSON object that matches the following schema: \n"
-          <> T.decodeUtf8 (BSL.toStrict $ encode jsonStructure)
-          <> content lastMessage
-          <> "\n"
-          <> "# How to treat the task:\n"
-          <> "* Stricly follow the schema for the output.\n"
-          <> "* Never return anything other than a JSON object.\n"
-          <> "* Do not talk to the user.\n"
-  chatResponse <-
-    chat
-      cOps
-        { messages =
-            NonEmpty.fromList $
-              lastMessage {content = jsonHelperPrompt} : NonEmpty.init messages
-        }
-  case chatResponse of
-    Left err -> return $ Left err
-    Right r -> do
-      let mMessage = message r
-      case mMessage of
-        Nothing -> return $ Left "Something went wrong"
-        Just res -> do
-          case decode (BSL.fromStrict . T.encodeUtf8 $ content res) of
-            Nothing -> do
-              case mMaxRetries of
-                Nothing -> return $ Left "Decoding Failed :("
-                Just n -> if n < 1 then return $ Left "Decoding Failed :(" else chatJson cOps jsonStructure (Just (n - 1))
-            Just resultInType -> return $ Right resultInType
+  -- For models that support the format parameter, use that directly
+  --let jsonSchema = encode jsonStructure
+  let useNativeFormat = False  -- Set to True to use the native format parameter when appropriate
+  
+  if useNativeFormat
+    then do
+      let formattedOps = cOps { format = Just (SchemaFormat (Object $ HM.fromList [("schema", Object $ HM.fromList [("type", String "object")])])) }
+      chatResponse <- chat formattedOps
+      case chatResponse of
+        Left err -> return $ Left err
+        Right r -> do
+          let mMessage = message r
+          case mMessage of
+            Nothing -> return $ Left "Something went wrong"
+            Just res -> case decode (BSL.fromStrict . T.encodeUtf8 $ content res) of
+              Nothing -> return $ Left "Decoding Failed :("
+              Just resultInType -> return $ Right resultInType
+    else do
+      -- Fall back to the original implementation using prompts
+      let lastMessage = NonEmpty.last messages
+          jsonHelperPrompt =
+            "You are an AI that returns only JSON object. \n"
+              <> "* Your output should be a JSON object that matches the following schema: \n"
+              <> T.decodeUtf8 (BSL.toStrict $ encode jsonStructure)
+              <> content lastMessage
+              <> "\n"
+              <> "# How to treat the task:\n"
+              <> "* Stricly follow the schema for the output.\n"
+              <> "* Never return anything other than a JSON object.\n"
+              <> "* Do not talk to the user.\n"
+      chatResponse <-
+        chat
+          cOps
+            { messages =
+                NonEmpty.fromList $
+                  lastMessage {content = jsonHelperPrompt} : NonEmpty.init messages
+            }
+      case chatResponse of
+        Left err -> return $ Left err
+        Right r -> do
+          let mMessage = message r
+          case mMessage of
+            Nothing -> return $ Left "Something went wrong"
+            Just res -> do
+              case decode (BSL.fromStrict . T.encodeUtf8 $ content res) of
+                Nothing -> do
+                  case mMaxRetries of
+                    Nothing -> return $ Left "Decoding Failed :("
+                    Just n -> if n < 1 then return $ Left "Decoding Failed :(" else chatJson cOps jsonStructure (Just (n - 1))
+                Just resultInType -> return $ Right resultInType
+
+-- | Helper function to create a JSON schema from a Haskell type
+schemaFromType :: ToJSON a => a -> BSL.ByteString
+schemaFromType = encode  -- This is a simplified version; a real implementation would generate a JSON Schema
+
+{- |
+   Example usage of 'Ollama.chat' with a JSON schema format and options field.
+
+   The first example sends a message requesting a JSON response conforming to a given schema.
+   The second example uses an alternative JSON format (here, @JsonFormat@).
+
+   >>> import Data.Aeson (Value, object, (.=))
+   >>> import Data.List.NonEmpty (NonEmpty(..))
+   >>> import Ollama (defaultChatOps, Message(..), SchemaFormat, JsonFormat)
+   >>> let x :: Value
+   ...     x = object [ "type" .= ("object" :: String)
+   ...                , "properties" .= object [ "age" .= object ["type" .= ("integer" :: String)] ]
+   ...                ]
+   >>> let msg = Message User "Ollama is 22 years old and is busy saving the world. Respond using JSON" Nothing
+   >>> let opts = object ["option" .= ("some value" :: String)]
+   >>> res <- chat defaultChatOps
+   ...   { chatModelName = "llama3.2"
+   ...   , messages = msg :| []
+   ...   , format = Just (SchemaFormat x)
+   ...   , options = opts
+   ...   }
+   >>> print (message res)
+   Just (Message {role = Assistant, content = "{\n    \"age\": 22\n}", images = Nothing})
+   >>> res2 <- chat defaultChatOps
+   ...   { chatModelName = "llama3.2"
+   ...   , messages = msg :| []
+   ...   , format = Just JsonFormat
+   ...   , options = object ["option" .= ("other value" :: String)]
+   ...   }
+   >>> print (message res2)
+   Just (Message {role = Assistant, content = "{ \"Name\": \"Ollama\", \"Age\": 22, \"Occupation\": \"World Savior\", \"Goals\": [\"Save humanity from alien invasion\", \"Unite warring nations\", \"Protect the environment\"] }", images = Nothing})
+-}
diff --git a/src/Data/Ollama/Common/Types.hs b/src/Data/Ollama/Common/Types.hs
--- a/src/Data/Ollama/Common/Types.hs
+++ b/src/Data/Ollama/Common/Types.hs
@@ -4,6 +4,7 @@
 module Data.Ollama.Common.Types
   ( ModelDetails (..)
   , OllamaClient (..)
+  , Format (..)
   ) where
 
 import Data.Aeson
@@ -33,3 +34,31 @@
   { host :: Text
   }
   deriving (Eq, Show)
+
+
+{-|
+E.g SchemaFormat
+{
+    "type": "object",
+    "properties": {
+      "age": {
+        "type": "integer"
+      },
+      "available": {
+        "type": "boolean"
+      }
+    },
+    "required": [
+      "age",
+      "available"
+    ]
+  }
+|-}
+-- | Format specification for the chat output
+-- | Since 0.1.3.0
+data Format = JsonFormat | SchemaFormat Value
+  deriving (Show, Eq)
+
+instance ToJSON Format where
+  toJSON JsonFormat = String "json"
+  toJSON (SchemaFormat schema) = schema
diff --git a/src/Data/Ollama/Embeddings.hs b/src/Data/Ollama/Embeddings.hs
--- a/src/Data/Ollama/Embeddings.hs
+++ b/src/Data/Ollama/Embeddings.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE DeriveAnyClass #-}
-{-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE DuplicateRecordFields #-}
 {-# LANGUAGE OverloadedStrings #-}
 
@@ -7,14 +5,17 @@
   ( -- * Embedding API
     embedding
   , embeddingOps
+  , EmbeddingOps (..)
+  , EmbeddingResp (..)
   ) where
 
 import Data.Aeson
 import Data.Ollama.Common.Utils as CU
 import Data.Text (Text)
 import Data.Text qualified as T
-import GHC.Generics
 import Network.HTTP.Client
+import Control.Exception (try)
+import Data.ByteString.Lazy.Char8 (ByteString)
 
 -- TODO: Add Options parameter
 data EmbeddingOps = EmbeddingOps
@@ -27,10 +28,15 @@
 
 data EmbeddingResp = EmbeddingResp
   { model :: Text
-  , embedding' :: [[Float]]
+  , embedding_ :: [[Float]]
   }
-  deriving (Show, Eq, Generic, FromJSON)
+  deriving (Show, Eq)
 
+instance FromJSON EmbeddingResp where
+  parseJSON = withObject "EmbeddingResp" $ \v -> EmbeddingResp
+        <$> v .: "model"
+        <*> v .: "embeddings"
+
 instance ToJSON EmbeddingOps where
   toJSON (EmbeddingOps model_ input_ truncate' keepAlive_) =
     object
@@ -52,28 +58,36 @@
   Maybe Bool ->
   -- | Keep Alive
   Maybe Text ->
-  IO (Maybe EmbeddingResp)
+  IO (Either String EmbeddingResp)
 embeddingOps modelName input_ mTruncate mKeepAlive = do
   let url = defaultOllamaUrl
   manager <- newManager defaultManagerSettings
-  initialRequest <- parseRequest $ T.unpack (url <> "/api/embed")
-  let reqBody =
-        EmbeddingOps
-          { model = modelName
-          , input = input_
-          , truncate = mTruncate
-          , keepAlive = mKeepAlive
-          }
-      request =
-        initialRequest
-          { method = "POST"
-          , requestBody = RequestBodyLBS $ encode reqBody
-          }
-  resp <- httpLbs request manager
-  let mRes = decode (responseBody resp) :: Maybe EmbeddingResp
-  case mRes of
-    Nothing -> pure Nothing
-    Just r -> pure $ Just r
+  --einitialRequest <- parseRequest $ T.unpack (url <> "/api/embed")
+  eInitialRequest <-
+    try $ parseRequest $ T.unpack (url <> "/api/embed") :: IO (Either HttpException Request)
+  case eInitialRequest of
+    Left e -> do
+      return $ Left $ show e
+    Right initialRequest -> do
+      let reqBody =
+            EmbeddingOps
+              { model = modelName
+              , input = input_
+              , truncate = mTruncate
+              , keepAlive = mKeepAlive
+              }
+          request =
+            initialRequest
+              { method = "POST"
+              , requestBody = RequestBodyLBS $ encode reqBody
+              }
+      eResp <- try $ httpLbs request manager :: IO (Either HttpException (Response ByteString))
+      case eResp of
+        Left err -> return $ Left (show err)
+        Right resp -> 
+          case decode (responseBody resp) of
+            Nothing -> return $ Left $ "Couldn't decode response: " <> show (responseBody resp)
+            Just r -> return $ Right r
 
 -- Higher level binding that only takes important params
 
@@ -83,6 +97,6 @@
   Text ->
   -- | Input
   Text ->
-  IO (Maybe EmbeddingResp)
+  IO (Either String EmbeddingResp)
 embedding modelName input_ =
   embeddingOps modelName input_ Nothing Nothing
diff --git a/src/Data/Ollama/Generate.hs b/src/Data/Ollama/Generate.hs
--- a/src/Data/Ollama/Generate.hs
+++ b/src/Data/Ollama/Generate.hs
@@ -17,6 +17,7 @@
 import Data.ByteString.Lazy.Char8 qualified as BSL
 import Data.Maybe
 import Data.Ollama.Common.Utils as CU
+import Data.Ollama.Common.Types (Format(..))
 import Data.Text (Text)
 import Data.Text qualified as T
 import Data.Text.Encoding qualified as T
@@ -55,8 +56,9 @@
   -- ^ An optional suffix to append to the generated text.
   , images :: Maybe [Text]
   -- ^ Optional list of base64 encoded images to include with the request.
-  , format :: Maybe Text
+  , format :: Maybe Format
   -- ^ An optional format specifier for the response.
+  -- ^ Since 0.1.3.0
   , system :: Maybe Text
   -- ^ Optional system text that can be included in the generation context.
   , template :: Maybe Text
@@ -71,6 +73,9 @@
   -- ^ Override default Ollama host url. Default url = "http://127.0.0.1:11434"
   , responseTimeOut :: Maybe Int
   -- ^ Override default response timeout in minutes. Default = 15 minutes
+  , options :: Maybe Value
+  -- ^ additional model parameters listed in the documentation for the Modelfile such as temperature
+  -- ^ Since 0.1.3.0
   }
 
 instance Show GenerateOps where
@@ -96,6 +101,8 @@
       <> show raw
       <> ", keepAlive : "
       <> show keepAlive
+      <> ", options : "
+      <> show options
 
 instance Eq GenerateOps where
   (==) a b =
@@ -108,6 +115,7 @@
       && template a == template b
       && raw a == raw b
       && keepAlive a == keepAlive b
+      && options a == options b
 
 -- TODO: Add Context Param
 
@@ -153,6 +161,7 @@
         keepAlive
         _ -- Host url
         _ -- Response timeout
+        options 
       ) =
       object
         [ "model" .= model
@@ -165,6 +174,7 @@
         , "stream" .= if isNothing stream then Just False else Just True
         , "raw" .= raw
         , "keep_alive" .= keepAlive
+        , "options" .= options
         ]
 
 instance FromJSON GenerateResponse where
@@ -206,6 +216,7 @@
     , keepAlive = Nothing
     , hostUrl = Nothing
     , responseTimeOut = Nothing
+    , options = Nothing
     }
 
 {- |
@@ -288,7 +299,7 @@
               Right r -> do
                 _ <- sendChunk r
                 _ <- flush
-                if done r then pure (Left "") else streamResponse sendChunk flush
+                if done r then pure (Right r) else streamResponse sendChunk flush
   let genResponse op = do
         bs <- brRead $ responseBody response
         if bs == ""
@@ -368,3 +379,32 @@
                 then return $ Left "Decoding failed :("
                 else generateJson genOps jsonStructure (Just (n - 1))
         Just resultInType -> return $ Right resultInType
+
+
+{- |
+   Example usage of 'Ollama.generate' with a JSON schema format and options field.
+
+   In this example we pass a JSON schema that expects an object with an integer field @age@.
+   The options field is supplied as a JSON value.
+
+   >>> import Data.Aeson (Value, object, (.=))
+   >>> import Ollama (GenerateOps, defaultGenerateOps, SchemaFormat)
+   >>> let x :: Value
+   ...     x = object [ "type" .= ("object" :: String)
+   ...                , "properties" .= object [ "age" .= object ["type" .= ("integer" :: String)] ]
+   ...                ]
+   >>> let opts :: Value
+   ...     opts = object ["option" .= ("some value" :: String)]
+   >>> generate defaultGenerateOps
+   ...   { modelName = "llama3.2"
+   ...   , prompt = "Ollama is 22 years old and is busy saving the world. Respond using JSON"
+   ...   , format = Just (SchemaFormat x)
+   ...   , options = opts
+   ...   }
+   Right (GenerateResponse {model = "llama3.2", createdAt = 2025-03-25 09:34:15.853417157 UTC,
+                            response_ = "{\n    \"age\": 22\n}", done = True,
+                            totalDuration = Just 6625631744, loadDuration = Just 2578791966,
+                            promptEvalCount = Just 43, promptEvalDuration = Just 2983000000,
+                            evalCount = Just 10, evalDuration = Just 1061000000})
+-}
+
diff --git a/src/Ollama.hs b/src/Ollama.hs
--- a/src/Ollama.hs
+++ b/src/Ollama.hs
@@ -24,6 +24,8 @@
     -- ** Embeddings
   , embedding
   , embeddingOps
+  , EmbeddingOps (..)
+  , EmbeddingResp (..)
 
     -- * Ollama operations
 
@@ -60,6 +62,7 @@
   , RunningModels (..)
   , RunningModel (..)
   , Message (..)
+  , Format(..)
   )
 where
 
@@ -75,7 +78,7 @@
 import Data.Ollama.Copy (copyModel)
 import Data.Ollama.Create (createModel, createModelOps)
 import Data.Ollama.Delete (deleteModel)
-import Data.Ollama.Embeddings (embedding, embeddingOps)
+import Data.Ollama.Embeddings (embedding, embeddingOps, EmbeddingOps (..), EmbeddingResp (..))
 import Data.Ollama.Generate
   ( GenerateOps (..)
   , GenerateResponse (..)
@@ -88,3 +91,4 @@
 import Data.Ollama.Pull (pull, pullOps)
 import Data.Ollama.Push (push, pushOps)
 import Data.Ollama.Show (ShowModelResponse (..), showModel, showModelOps)
+import Data.Ollama.Common.Types (Format (..))
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -12,6 +12,8 @@
 import System.IO.Silently (capture)
 import Test.Tasty
 import Test.Tasty.HUnit
+import qualified Data.Text as T 
+import Data.Aeson 
 
 tests :: TestTree
 tests =
@@ -21,6 +23,9 @@
     , chatTest
     , psTest
     , showTest
+    , embeddingTest
+    , generateFormatTest
+    , chatFormatTest
     ]
 
 generateTest :: TestTree
@@ -59,13 +64,48 @@
         assertBool "Expecting generation to fail with invalid model" (isLeft eRes)
     ]
 
+generateFormatTest :: TestTree
+generateFormatTest =
+  testGroup "Generate tests with format and options"
+    [ testCase "Generate with SchemaFormat and options" $ do
+        let schema = object
+              [ "type" .= ("object" :: String)
+              , "properties" .= object [ "age" .= object ["type" .= ("integer" :: String)] ]
+              ]
+        eRes <-
+          Ollama.generate
+            defaultGenerateOps
+              { modelName = "llama3.2"
+              , prompt = "Ollama is 22 years old and is busy saving the world. Respond using JSON"
+              , format = Just (Ollama.SchemaFormat schema)
+              }
+        case eRes of
+          Right res ->
+            assertBool "Response should contain JSON with key \"age\"" ( "age" `T.isInfixOf` Ollama.response_ res )
+          Left err ->
+            assertFailure $ "Generation failed with error: " ++ show err
+    , testCase "Generate with JsonFormat and options" $ do
+        eRes <-
+          Ollama.generate
+            defaultGenerateOps
+              { modelName = "llama3.2"
+              , prompt = "Provide a simple JSON response describing Ollama."
+              , format = Just Ollama.JsonFormat
+              }
+        case eRes of
+          Right res ->
+            assertBool "Response should start with '{'" ( "{" `T.isPrefixOf` Ollama.response_ res )
+          Left err ->
+            assertFailure $ "Generation failed with error: " ++ show err
+    ]
+
 chatTest :: TestTree
 chatTest =
   testGroup
     "Chat tests"
     [ testCase "chat stream" $ do
-        let msg = Ollama.Message User "What is 29 + 3?" Nothing
-            defaultMsg = Ollama.Message User "" Nothing
+        let msg = Ollama.Message User "What is 29 + 3?" Nothing Nothing
+            defaultMsg = Ollama.Message User "" Nothing Nothing
         output <-
           capture $
             Ollama.chat
@@ -76,7 +116,7 @@
                 }
         assertBool "Checking if chat function is printing anything" (length output > 0)
     , testCase "Chat non-stream" $ do
-        let msg = Ollama.Message User "What is 29 + 3?" Nothing
+        let msg = Ollama.Message User "What is 29 + 3?" Nothing Nothing
         eRes <-
           Ollama.chat
             defaultChatOps
@@ -85,7 +125,7 @@
               }
         assertBool "Checking if chat function returns a valid value" (isRight eRes)
     , testCase "Chat invalid host url" $ do
-        let msg = Ollama.Message User "What is 29 + 3?" Nothing
+        let msg = Ollama.Message User "What is 29 + 3?" Nothing Nothing
         eRes <-
           Ollama.chat
             defaultChatOps
@@ -97,6 +137,46 @@
         assertBool "It should return Left" (isLeft eRes)
     ]
 
+chatFormatTest :: TestTree
+chatFormatTest =
+  testGroup "Chat tests with format and options"
+    [ testCase "Chat with SchemaFormat and options" $ do
+        let schema = object
+              [ "type" .= ("object" :: String)
+              , "properties" .= object [ "age" .= object ["type" .= ("integer" :: String)] ]
+              ]
+            msg = Ollama.Message User "Ollama is 22 years old and is busy saving the world. Respond using JSON" Nothing Nothing
+        eRes <-
+          Ollama.chat
+            defaultChatOps
+              { Chat.chatModelName = "llama3.2"
+              , Chat.messages = msg :| []
+              , Chat.format = Just (Ollama.SchemaFormat schema)
+              , Chat.options = Just $ object ["penalize_newline" .= Bool True]
+              }
+        case eRes of
+          Right res ->
+            assertBool "Chat response should contain key \"age\"" $
+              maybe False (\m -> "age" `T.isInfixOf` Chat.content m) (Chat.message res)
+          Left err ->
+            assertFailure $ "Chat failed with error: " ++ show err
+    , testCase "Chat with JsonFormat and options" $ do
+        let msg = Ollama.Message User "Tell me about Ollama in JSON format." Nothing Nothing
+        eRes <-
+          Ollama.chat
+            defaultChatOps
+              { Chat.chatModelName = "llama3.2"
+              , Chat.messages = msg :| []
+              , Chat.format = Just Ollama.JsonFormat
+              }
+        case eRes of
+          Right res ->
+            assertBool "Chat response should start with '{'" $
+              maybe False (\m -> "{" `T.isPrefixOf` Chat.content m) (Chat.message res)
+          Left err ->
+            assertFailure $ "Chat failed with error: " ++ show err
+    ]
+
 psTest :: TestTree
 psTest =
   testGroup
@@ -113,6 +193,15 @@
     [ testCase "check show" $ do
         mRes <- Ollama.showModel "llama3.2"
         assertBool "Check if model exists or not" (isJust mRes)
+    ]
+
+embeddingTest :: TestTree
+embeddingTest =
+  testGroup
+    "Embedding test"
+    [ testCase "check embedding" $ do
+        eRes <- Ollama.embedding "llama3.2" "Why is sky blue?"
+        assertBool "Check if embedding returns anything" (isRight eRes)
     ]
 
 main :: IO ()
