{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
module Data.Ollama.Common.Utils
(
encodeImage
, withOllamaRequest
, commonNonStreamingHandler
, commonStreamHandler
, nonJsonHandler
, defaultModelOptions
, withRetry
, getVersion
) where
import Control.Concurrent (threadDelay)
import Control.Exception (IOException, try)
import Data.Aeson
import Data.ByteString qualified as BS
import Data.ByteString.Base64 qualified as Base64
import Data.ByteString.Lazy qualified as BSL
import Data.Char (toLower)
import Data.Maybe (fromMaybe)
import Data.Ollama.Common.Config
import Data.Ollama.Common.Error
import Data.Ollama.Common.Error qualified as Error
import Data.Ollama.Common.Types
import Data.Text (Text)
import Data.Text qualified as T
import Data.Text.Encoding qualified as TE
import Network.HTTP.Client
import Network.HTTP.Client.TLS
import Network.HTTP.Types (Status (statusCode))
import System.Directory
import System.FilePath
supportedExtensions :: [String]
supportedExtensions :: [[Char]]
supportedExtensions = [[Char]
".jpg", [Char]
".jpeg", [Char]
".png"]
safeReadFile :: FilePath -> IO (Either IOException BS.ByteString)
safeReadFile :: [Char] -> IO (Either IOException ByteString)
safeReadFile = IO ByteString -> IO (Either IOException ByteString)
forall e a. Exception e => IO a -> IO (Either e a)
try (IO ByteString -> IO (Either IOException ByteString))
-> ([Char] -> IO ByteString)
-> [Char]
-> IO (Either IOException ByteString)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> IO ByteString
BS.readFile
asPath :: FilePath -> IO (Maybe BS.ByteString)
asPath :: [Char] -> IO (Maybe ByteString)
asPath [Char]
filePath = do
Bool
exists <- [Char] -> IO Bool
doesFileExist [Char]
filePath
if Bool
exists
then (IOException -> Maybe ByteString)
-> (ByteString -> Maybe ByteString)
-> Either IOException ByteString
-> Maybe ByteString
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe ByteString -> IOException -> Maybe ByteString
forall a b. a -> b -> a
const Maybe ByteString
forall a. Maybe a
Nothing) ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Either IOException ByteString -> Maybe ByteString)
-> IO (Either IOException ByteString) -> IO (Maybe ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> IO (Either IOException ByteString)
safeReadFile [Char]
filePath
else Maybe ByteString -> IO (Maybe ByteString)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ByteString
forall a. Maybe a
Nothing
isSupportedExtension :: FilePath -> Bool
isSupportedExtension :: [Char] -> Bool
isSupportedExtension [Char]
p = (Char -> Char) -> [Char] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower ([Char] -> [Char]
takeExtension [Char]
p) [Char] -> [[Char]] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [[Char]]
supportedExtensions
encodeImage :: FilePath -> IO (Maybe Text)
encodeImage :: [Char] -> IO (Maybe Text)
encodeImage [Char]
filePath = do
if Bool -> Bool
not ([Char] -> Bool
isSupportedExtension [Char]
filePath)
then Maybe Text -> IO (Maybe Text)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Text
forall a. Maybe a
Nothing
else do
Maybe ByteString
maybeContent <- [Char] -> IO (Maybe ByteString)
asPath [Char]
filePath
Maybe Text -> IO (Maybe Text)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Text -> IO (Maybe Text)) -> Maybe Text -> IO (Maybe Text)
forall a b. (a -> b) -> a -> b
$ (ByteString -> Text) -> Maybe ByteString -> Maybe Text
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ByteString -> Text
TE.decodeUtf8 (ByteString -> Text)
-> (ByteString -> ByteString) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
Base64.encode) Maybe ByteString
maybeContent
withRetry ::
Int ->
Int ->
IO (Either OllamaError a) ->
IO (Either OllamaError a)
withRetry :: forall a.
Int
-> Int -> IO (Either OllamaError a) -> IO (Either OllamaError a)
withRetry Int
0 Int
_ IO (Either OllamaError a)
action = IO (Either OllamaError a)
action
withRetry Int
retries Int
delaySeconds IO (Either OllamaError a)
action = do
Either OllamaError a
result <- IO (Either OllamaError a)
action
case Either OllamaError a
result of
Left OllamaError
err | OllamaError -> Bool
isRetryableError OllamaError
err -> do
Int -> IO ()
threadDelay (Int
delaySeconds Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
1000000)
Int
-> Int -> IO (Either OllamaError a) -> IO (Either OllamaError a)
forall a.
Int
-> Int -> IO (Either OllamaError a) -> IO (Either OllamaError a)
withRetry (Int
retries Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int
delaySeconds IO (Either OllamaError a)
action
Either OllamaError a
_ -> Either OllamaError a -> IO (Either OllamaError a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Either OllamaError a
result
where
isRetryableError :: OllamaError -> Bool
isRetryableError (HttpError HttpException
_) = Bool
True
isRetryableError (TimeoutError [Char]
_) = Bool
True
isRetryableError (JsonSchemaError [Char]
_) = Bool
True
isRetryableError (DecodeError [Char]
_ [Char]
_) = Bool
True
isRetryableError OllamaError
_ = Bool
False
withOllamaRequest ::
forall payload response.
(ToJSON payload) =>
Text ->
BS.ByteString ->
Maybe payload ->
Maybe OllamaConfig ->
(Response BodyReader -> IO (Either OllamaError response)) ->
IO (Either OllamaError response)
withOllamaRequest :: forall payload response.
ToJSON payload =>
Text
-> ByteString
-> Maybe payload
-> Maybe OllamaConfig
-> (Response (IO ByteString) -> IO (Either OllamaError response))
-> IO (Either OllamaError response)
withOllamaRequest Text
endpoint ByteString
reqMethod Maybe payload
mbPayload Maybe OllamaConfig
mbOllamaConfig Response (IO ByteString) -> IO (Either OllamaError response)
handler = do
let OllamaConfig {Int
Maybe Int
Maybe (IO ())
Maybe Manager
Text
hostUrl :: Text
timeout :: Int
onModelStart :: Maybe (IO ())
onModelError :: Maybe (IO ())
onModelFinish :: Maybe (IO ())
retryCount :: Maybe Int
retryDelay :: Maybe Int
commonManager :: Maybe Manager
commonManager :: OllamaConfig -> Maybe Manager
retryDelay :: OllamaConfig -> Maybe Int
retryCount :: OllamaConfig -> Maybe Int
onModelFinish :: OllamaConfig -> Maybe (IO ())
onModelError :: OllamaConfig -> Maybe (IO ())
onModelStart :: OllamaConfig -> Maybe (IO ())
timeout :: OllamaConfig -> Int
hostUrl :: OllamaConfig -> Text
..} = OllamaConfig -> Maybe OllamaConfig -> OllamaConfig
forall a. a -> Maybe a -> a
fromMaybe OllamaConfig
defaultOllamaConfig Maybe OllamaConfig
mbOllamaConfig
fullUrl :: [Char]
fullUrl = Text -> [Char]
T.unpack (Text -> [Char]) -> Text -> [Char]
forall a b. (a -> b) -> a -> b
$ Text
hostUrl Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
endpoint
timeoutMicros :: Int
timeoutMicros = Int
timeout Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
1000000
Manager
manager <- case Maybe Manager
commonManager of
Maybe Manager
Nothing ->
ManagerSettings -> IO Manager
forall (m :: * -> *). MonadIO m => ManagerSettings -> m Manager
newTlsManagerWith
ManagerSettings
tlsManagerSettings {managerResponseTimeout = responseTimeoutMicro timeoutMicros}
Just Manager
m -> Manager -> IO Manager
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Manager
m
Either HttpException Request
eRequest <- IO Request -> IO (Either HttpException Request)
forall e a. Exception e => IO a -> IO (Either e a)
try (IO Request -> IO (Either HttpException Request))
-> IO Request -> IO (Either HttpException Request)
forall a b. (a -> b) -> a -> b
$ [Char] -> IO Request
forall (m :: * -> *). MonadThrow m => [Char] -> m Request
parseRequest [Char]
fullUrl
case Either HttpException Request
eRequest of
Left HttpException
ex -> Either OllamaError response -> IO (Either OllamaError response)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either OllamaError response -> IO (Either OllamaError response))
-> Either OllamaError response -> IO (Either OllamaError response)
forall a b. (a -> b) -> a -> b
$ OllamaError -> Either OllamaError response
forall a b. a -> Either a b
Left (OllamaError -> Either OllamaError response)
-> OllamaError -> Either OllamaError response
forall a b. (a -> b) -> a -> b
$ HttpException -> OllamaError
Error.HttpError HttpException
ex
Right Request
req -> do
let request :: Request
request =
Request
req
{ method = reqMethod
, requestBody =
maybe mempty (\payload
x -> ByteString -> RequestBody
RequestBodyLBS (ByteString -> RequestBody) -> ByteString -> RequestBody
forall a b. (a -> b) -> a -> b
$ payload -> ByteString
forall a. ToJSON a => a -> ByteString
encode payload
x) mbPayload
}
retryCnt :: Int
retryCnt = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
0 Maybe Int
retryCount
retryDelay_ :: Int
retryDelay_ = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
1 Maybe Int
retryDelay
Int
-> Int
-> IO (Either OllamaError response)
-> IO (Either OllamaError response)
forall a.
Int
-> Int -> IO (Either OllamaError a) -> IO (Either OllamaError a)
withRetry Int
retryCnt Int
retryDelay_ (IO (Either OllamaError response)
-> IO (Either OllamaError response))
-> IO (Either OllamaError response)
-> IO (Either OllamaError response)
forall a b. (a -> b) -> a -> b
$ do
IO () -> Maybe (IO ()) -> IO ()
forall a. a -> Maybe a -> a
fromMaybe (() -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) Maybe (IO ())
onModelStart
Either HttpException (Either OllamaError response)
eResponse <- IO (Either OllamaError response)
-> IO (Either HttpException (Either OllamaError response))
forall e a. Exception e => IO a -> IO (Either e a)
try (IO (Either OllamaError response)
-> IO (Either HttpException (Either OllamaError response)))
-> IO (Either OllamaError response)
-> IO (Either HttpException (Either OllamaError response))
forall a b. (a -> b) -> a -> b
$ Request
-> Manager
-> (Response (IO ByteString) -> IO (Either OllamaError response))
-> IO (Either OllamaError response)
forall a.
Request -> Manager -> (Response (IO ByteString) -> IO a) -> IO a
withResponse Request
request Manager
manager Response (IO ByteString) -> IO (Either OllamaError response)
handler
case Either HttpException (Either OllamaError response)
eResponse of
Left HttpException
ex -> do
IO () -> Maybe (IO ()) -> IO ()
forall a. a -> Maybe a -> a
fromMaybe (() -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) Maybe (IO ())
onModelError
case HttpException
ex of
(HttpExceptionRequest Request
_ HttpExceptionContent
ResponseTimeout) ->
Either OllamaError response -> IO (Either OllamaError response)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either OllamaError response -> IO (Either OllamaError response))
-> Either OllamaError response -> IO (Either OllamaError response)
forall a b. (a -> b) -> a -> b
$ OllamaError -> Either OllamaError response
forall a b. a -> Either a b
Left (OllamaError -> Either OllamaError response)
-> OllamaError -> Either OllamaError response
forall a b. (a -> b) -> a -> b
$ [Char] -> OllamaError
Error.TimeoutError [Char]
"No response from LLM yet"
HttpException
_ -> Either OllamaError response -> IO (Either OllamaError response)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either OllamaError response -> IO (Either OllamaError response))
-> Either OllamaError response -> IO (Either OllamaError response)
forall a b. (a -> b) -> a -> b
$ OllamaError -> Either OllamaError response
forall a b. a -> Either a b
Left (OllamaError -> Either OllamaError response)
-> OllamaError -> Either OllamaError response
forall a b. (a -> b) -> a -> b
$ HttpException -> OllamaError
Error.HttpError HttpException
ex
Right Either OllamaError response
result -> do
IO () -> Maybe (IO ()) -> IO ()
forall a. a -> Maybe a -> a
fromMaybe (() -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) Maybe (IO ())
onModelFinish
Either OllamaError response -> IO (Either OllamaError response)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Either OllamaError response
result
commonNonStreamingHandler ::
FromJSON a =>
Response BodyReader ->
IO (Either OllamaError a)
commonNonStreamingHandler :: forall a.
FromJSON a =>
Response (IO ByteString) -> IO (Either OllamaError a)
commonNonStreamingHandler Response (IO ByteString)
resp = do
let bodyReader :: IO ByteString
bodyReader = Response (IO ByteString) -> IO ByteString
forall body. Response body -> body
responseBody Response (IO ByteString)
resp
respStatus :: Int
respStatus = Status -> Int
statusCode (Status -> Int) -> Status -> Int
forall a b. (a -> b) -> a -> b
$ Response (IO ByteString) -> Status
forall body. Response body -> Status
responseStatus Response (IO ByteString)
resp
if Int
respStatus Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
200 Bool -> Bool -> Bool
&& Int
respStatus Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
300
then do
ByteString
finalBs <- ByteString -> IO ByteString -> IO ByteString
readFullBuff ByteString
BS.empty IO ByteString
bodyReader
case ByteString -> Either [Char] a
forall a. FromJSON a => ByteString -> Either [Char] a
eitherDecode (ByteString -> ByteString
BSL.fromStrict ByteString
finalBs) of
Left [Char]
err -> Either OllamaError a -> IO (Either OllamaError a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either OllamaError a -> IO (Either OllamaError a))
-> (OllamaError -> Either OllamaError a)
-> OllamaError
-> IO (Either OllamaError a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OllamaError -> Either OllamaError a
forall a b. a -> Either a b
Left (OllamaError -> IO (Either OllamaError a))
-> OllamaError -> IO (Either OllamaError a)
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> OllamaError
Error.DecodeError [Char]
err (ByteString -> [Char]
forall a. Show a => a -> [Char]
show ByteString
finalBs)
Right a
decoded -> Either OllamaError a -> IO (Either OllamaError a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either OllamaError a -> IO (Either OllamaError a))
-> (a -> Either OllamaError a) -> a -> IO (Either OllamaError a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Either OllamaError a
forall a b. b -> Either a b
Right (a -> IO (Either OllamaError a)) -> a -> IO (Either OllamaError a)
forall a b. (a -> b) -> a -> b
$ a
decoded
else OllamaError -> Either OllamaError a
forall a b. a -> Either a b
Left (OllamaError -> Either OllamaError a)
-> (ByteString -> OllamaError)
-> ByteString
-> Either OllamaError a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> OllamaError
ApiError (Text -> OllamaError)
-> (ByteString -> Text) -> ByteString -> OllamaError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
TE.decodeUtf8 (ByteString -> Either OllamaError a)
-> IO ByteString -> IO (Either OllamaError a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO ByteString -> IO ByteString
brRead IO ByteString
bodyReader
readFullBuff :: BS.ByteString -> BodyReader -> IO BS.ByteString
readFullBuff :: ByteString -> IO ByteString -> IO ByteString
readFullBuff ByteString
acc IO ByteString
reader = do
ByteString
chunk <- IO ByteString -> IO ByteString
brRead IO ByteString
reader
if ByteString -> Bool
BS.null ByteString
chunk
then ByteString -> IO ByteString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ByteString
acc
else ByteString -> IO ByteString -> IO ByteString
readFullBuff (ByteString
acc ByteString -> ByteString -> ByteString
`BS.append` ByteString
chunk) IO ByteString
reader
commonStreamHandler ::
(HasDone a, FromJSON a) =>
(a -> IO ()) ->
IO () ->
Response BodyReader ->
IO (Either OllamaError a)
commonStreamHandler :: forall a.
(HasDone a, FromJSON a) =>
(a -> IO ())
-> IO () -> Response (IO ByteString) -> IO (Either OllamaError a)
commonStreamHandler a -> IO ()
sendChunk IO ()
flush Response (IO ByteString)
resp = ByteString -> IO (Either OllamaError a)
go ByteString
forall a. Monoid a => a
mempty
where
go :: ByteString -> IO (Either OllamaError a)
go ByteString
acc = do
ByteString
bs <- IO ByteString -> IO ByteString
brRead (IO ByteString -> IO ByteString) -> IO ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$ Response (IO ByteString) -> IO ByteString
forall body. Response body -> body
responseBody Response (IO ByteString)
resp
if ByteString -> Bool
BS.null ByteString
bs
then do
case ByteString -> Either [Char] a
forall a. FromJSON a => ByteString -> Either [Char] a
eitherDecode (ByteString -> ByteString
BSL.fromStrict ByteString
acc) of
Left [Char]
err -> Either OllamaError a -> IO (Either OllamaError a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either OllamaError a -> IO (Either OllamaError a))
-> Either OllamaError a -> IO (Either OllamaError a)
forall a b. (a -> b) -> a -> b
$ OllamaError -> Either OllamaError a
forall a b. a -> Either a b
Left (OllamaError -> Either OllamaError a)
-> OllamaError -> Either OllamaError a
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> OllamaError
Error.DecodeError [Char]
err (ByteString -> [Char]
forall a. Show a => a -> [Char]
show ByteString
acc)
Right a
decoded -> Either OllamaError a -> IO (Either OllamaError a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either OllamaError a -> IO (Either OllamaError a))
-> Either OllamaError a -> IO (Either OllamaError a)
forall a b. (a -> b) -> a -> b
$ a -> Either OllamaError a
forall a b. b -> Either a b
Right a
decoded
else do
let chunk :: ByteString
chunk = ByteString -> ByteString
BSL.fromStrict ByteString
bs
case ByteString -> Either [Char] a
forall a. FromJSON a => ByteString -> Either [Char] a
eitherDecode ByteString
chunk of
Left [Char]
err -> Either OllamaError a -> IO (Either OllamaError a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either OllamaError a -> IO (Either OllamaError a))
-> Either OllamaError a -> IO (Either OllamaError a)
forall a b. (a -> b) -> a -> b
$ OllamaError -> Either OllamaError a
forall a b. a -> Either a b
Left (OllamaError -> Either OllamaError a)
-> OllamaError -> Either OllamaError a
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> OllamaError
Error.DecodeError [Char]
err (ByteString -> [Char]
forall a. Show a => a -> [Char]
show ByteString
acc)
Right a
res -> do
a -> IO ()
sendChunk a
res
IO ()
flush
if a -> Bool
forall a. HasDone a => a -> Bool
getDone a
res then Either OllamaError a -> IO (Either OllamaError a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Either OllamaError a
forall a b. b -> Either a b
Right a
res) else ByteString -> IO (Either OllamaError a)
go (ByteString
acc ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
bs)
nonJsonHandler :: Response BodyReader -> IO (Either OllamaError BS.ByteString)
nonJsonHandler :: Response (IO ByteString) -> IO (Either OllamaError ByteString)
nonJsonHandler Response (IO ByteString)
resp = do
let bodyReader :: IO ByteString
bodyReader = Response (IO ByteString) -> IO ByteString
forall body. Response body -> body
responseBody Response (IO ByteString)
resp
respStatus :: Int
respStatus = Status -> Int
statusCode (Status -> Int) -> Status -> Int
forall a b. (a -> b) -> a -> b
$ Response (IO ByteString) -> Status
forall body. Response body -> Status
responseStatus Response (IO ByteString)
resp
if Int
respStatus Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
200 Bool -> Bool -> Bool
&& Int
respStatus Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
300
then ByteString -> Either OllamaError ByteString
forall a b. b -> Either a b
Right (ByteString -> Either OllamaError ByteString)
-> IO ByteString -> IO (Either OllamaError ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> IO ByteString -> IO ByteString
readFullBuff ByteString
BS.empty IO ByteString
bodyReader
else OllamaError -> Either OllamaError ByteString
forall a b. a -> Either a b
Left (OllamaError -> Either OllamaError ByteString)
-> (ByteString -> OllamaError)
-> ByteString
-> Either OllamaError ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> OllamaError
ApiError (Text -> OllamaError)
-> (ByteString -> Text) -> ByteString -> OllamaError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
TE.decodeUtf8 (ByteString -> Either OllamaError ByteString)
-> IO ByteString -> IO (Either OllamaError ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO ByteString -> IO ByteString
brRead IO ByteString
bodyReader
defaultModelOptions :: ModelOptions
defaultModelOptions :: ModelOptions
defaultModelOptions =
ModelOptions
{ numKeep :: Maybe Int
numKeep = Maybe Int
forall a. Maybe a
Nothing
, seed :: Maybe Int
seed = Maybe Int
forall a. Maybe a
Nothing
, numPredict :: Maybe Int
numPredict = Maybe Int
forall a. Maybe a
Nothing
, topK :: Maybe Int
topK = Maybe Int
forall a. Maybe a
Nothing
, topP :: Maybe Double
topP = Maybe Double
forall a. Maybe a
Nothing
, minP :: Maybe Double
minP = Maybe Double
forall a. Maybe a
Nothing
, typicalP :: Maybe Double
typicalP = Maybe Double
forall a. Maybe a
Nothing
, repeatLastN :: Maybe Int
repeatLastN = Maybe Int
forall a. Maybe a
Nothing
, temperature :: Maybe Double
temperature = Maybe Double
forall a. Maybe a
Nothing
, repeatPenalty :: Maybe Double
repeatPenalty = Maybe Double
forall a. Maybe a
Nothing
, presencePenalty :: Maybe Double
presencePenalty = Maybe Double
forall a. Maybe a
Nothing
, frequencyPenalty :: Maybe Double
frequencyPenalty = Maybe Double
forall a. Maybe a
Nothing
, penalizeNewline :: Maybe Bool
penalizeNewline = Maybe Bool
forall a. Maybe a
Nothing
, stop :: Maybe [Text]
stop = Maybe [Text]
forall a. Maybe a
Nothing
, numa :: Maybe Bool
numa = Maybe Bool
forall a. Maybe a
Nothing
, numCtx :: Maybe Int
numCtx = Maybe Int
forall a. Maybe a
Nothing
, numBatch :: Maybe Int
numBatch = Maybe Int
forall a. Maybe a
Nothing
, numGpu :: Maybe Int
numGpu = Maybe Int
forall a. Maybe a
Nothing
, mainGpu :: Maybe Int
mainGpu = Maybe Int
forall a. Maybe a
Nothing
, useMmap :: Maybe Bool
useMmap = Maybe Bool
forall a. Maybe a
Nothing
, numThread :: Maybe Int
numThread = Maybe Int
forall a. Maybe a
Nothing
}
getVersion :: IO (Either OllamaError Version)
getVersion :: IO (Either OllamaError Version)
getVersion = do
Text
-> ByteString
-> Maybe Value
-> Maybe OllamaConfig
-> (Response (IO ByteString) -> IO (Either OllamaError Version))
-> IO (Either OllamaError Version)
forall payload response.
ToJSON payload =>
Text
-> ByteString
-> Maybe payload
-> Maybe OllamaConfig
-> (Response (IO ByteString) -> IO (Either OllamaError response))
-> IO (Either OllamaError response)
withOllamaRequest
Text
"/api//version"
ByteString
"GET"
(Maybe Value
forall a. Maybe a
Nothing :: Maybe Value)
Maybe OllamaConfig
forall a. Maybe a
Nothing
Response (IO ByteString) -> IO (Either OllamaError Version)
forall a.
FromJSON a =>
Response (IO ByteString) -> IO (Either OllamaError a)
commonNonStreamingHandler