llama-cpp-haskell 0.3 → 0.3.0.1
raw patch · 3 files changed
+46/−26 lines, 3 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ Llama: LlamaError :: Word -> Text -> LlamaError
+ Llama: LlamaResponseError :: LlamaError -> LlamaResponseError
+ Llama: [code] :: LlamaError -> Word
+ Llama: [error] :: LlamaResponseError -> LlamaError
+ Llama: [message] :: LlamaError -> Text
+ Llama: data LlamaError
+ Llama: instance Data.Aeson.Types.FromJSON.FromJSON Llama.LlamaError
+ Llama: instance Data.Aeson.Types.FromJSON.FromJSON Llama.LlamaResponseError
+ Llama: instance GHC.Generics.Generic Llama.LlamaError
+ Llama: instance GHC.Generics.Generic Llama.LlamaResponseError
+ Llama: instance GHC.Show.Show Llama.LlamaError
+ Llama: instance GHC.Show.Show Llama.LlamaResponseError
+ Llama: llamaDecode :: FromJSON a => ByteString -> IO (Maybe a)
+ Llama: newtype LlamaResponseError
Files
- Llama.hs +37/−20
- Llama/Streaming.hs +6/−3
- llama-cpp-haskell.cabal +3/−3
Llama.hs view
@@ -88,9 +88,32 @@ } deriving (Show, Generic) instance FromJSON LlamaResponse +data LlamaError = LlamaError+ { code :: Word+ , message :: Text+ } deriving (Show, Generic)+instance FromJSON LlamaError++newtype LlamaResponseError = LlamaResponseError+ { error :: LlamaError+ } deriving (Show, Generic)+instance FromJSON LlamaResponseError+ type Token = Word32 type URL = String +llamaDecode :: (FromJSON a) => ByteString -> IO (Maybe a)+llamaDecode x =+ case decode x of+ Just v -> return v+ Nothing -> do+ case decode x of+ Just (LlamaResponseError err) -> do+ liftIO $ hPutStrLn stderr $ "llama-server returned an error: " ++ show err+ Nothing -> do+ liftIO $ hPutStrLn stderr $ "Failed to decode Llama response, got: " ++ show x+ return Nothing+ -- |Apply the LLM tempate to produce a raw LLM prompt from the role-content pairs applyTemplateSimple :: URL -> LlamaApplyTemplateRequest -> IO (Maybe Text) applyTemplateSimple = applyTemplateGeneral httpLBS@@ -109,11 +132,8 @@ , requestHeaders = [("Content-Type", "application/json")] } response <- fetch req- case decode (responseBody response) of- Just (LlamaApplyTemplateResponse text) -> return (Just text)- Nothing -> do- liftIO $ hPutStrLn stderr $ "Failed to decode Llama response, got: " ++ (show $ responseBody response)- return Nothing+ decoded <- llamaDecode (responseBody response)+ return $ decoded >>= (\(LlamaApplyTemplateResponse text) -> Just text) -- |Simple completion API sendToLlama :: URL -> Manager -> Text -> IO (Maybe Text)@@ -130,11 +150,8 @@ , responseTimeout = responseTimeoutMicro 1800000000 } response <- httpLbs req manager- case decode (responseBody response) of- Just (LlamaResponse text) -> return (Just text)- Nothing -> do- liftIO $ hPutStrLn stderr $ "Failed to decode Llama response, got: " ++ (show $ responseBody response)- return Nothing+ decoded <- llamaDecode (responseBody response)+ return $ decoded >>= (\(LlamaResponse text) -> Just text) -- |Returns a token-by-token stream sendToLlamaStreaming :: (MonadThrow m, MonadResource m) => URL -> Manager -> Text -> IO (ConduitT () LlamaStreamingResponse m ())@@ -150,6 +167,12 @@ , requestHeaders = [("Content-Type", "application/json")] } pure $ httpSource req getResponseBody .| eventConduit+-- pure $ httpSource req getResponseBody .| debugConduit "stream" .| eventConduit+--+--debugConduit :: (MonadIO m, Show a) => String -> ConduitT a a m ()+--debugConduit prefix = awaitForever $ \x -> do+-- liftIO $ hPutStrLn stderr (prefix ++ ": " ++ show x)+-- yield x tokenize :: URL -> LlamaTokenizeRequest -> IO (Maybe [Token]) tokenize url input = do@@ -159,11 +182,8 @@ , requestHeaders = [("Content-Type", "application/json")] } response <- httpLBS req- case decode (responseBody response) of- Just (LlamaTokenizeResponse result) -> return (Just result)- Nothing -> do- liftIO $ hPutStrLn stderr $ "Failed to decode Llama response, got: " ++ (show $ responseBody response)- return Nothing+ decoded <- llamaDecode (responseBody response)+ return $ decoded >>= (\(LlamaTokenizeResponse result) -> Just result) detokenize :: URL -> [Token] -> IO (Maybe Text) detokenize url input = do@@ -174,11 +194,8 @@ , requestHeaders = [("Content-Type", "application/json")] } response <- httpLBS req- case decode (responseBody response) of- Just (LlamaDetokenizeResponse text) -> return (Just text)- Nothing -> do- liftIO $ hPutStrLn stderr $ "Failed to decode Llama response, got: " ++ (show $ responseBody response)- return Nothing+ decoded <- llamaDecode (responseBody response)+ return $ decoded >>= (\(LlamaDetokenizeResponse result) -> Just result) -- |Extremely basic interface llama :: URL -> Text -> IO (Maybe Text)
Llama/Streaming.hs view
@@ -58,7 +58,7 @@ { eventComment :: ByteString } | RetryEvent { eventRetry :: Int- } | CloseEvent+ } | DispatchEvent deriving (Show) data LlamaStreamingResponse = LlamaStreamingResponse@@ -79,19 +79,22 @@ -- |text/event-stream parser event :: Parser ServerEvent-event = (sevent <|> comment <|> retry) <* eol+event = (sevent <|> comment <|> retry <|> dispatch) <* eol sevent :: Parser ServerEvent sevent = ServerEvent <$> optional (string "event" *> char ':' *> chars <* eol) <*> optional (string "id" *> char ':' *> chars <* eol)- <*> many (string "data" *> char ':' *> chars <* eol)+ <*> many1 (string "data" *> char ':' *> chars <* eol) -- technically SSE can have no data, but it is not the case for llama-server comment :: Parser ServerEvent comment = CommentEvent <$> (char ':' *> chars <* eol) retry :: Parser ServerEvent retry = RetryEvent <$> (string "retry:" *> decimal <* eol)++dispatch :: Parser ServerEvent+dispatch = pure DispatchEvent chars :: Parser ByteString chars = AC8.takeTill (== '\n')
llama-cpp-haskell.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: llama-cpp-haskell-version: 0.3+version: 0.3.0.1 synopsis: Haskell bindings for the llama.cpp llama-server and a simple CLI description: This is the interface that allows one to interface with llama-server RPC API using Haskell concepts. It also includes a `llamacall` binary to do it from your favorite command line shell and use it in scripting. license: AGPL-3.0-only@@ -10,7 +10,7 @@ -- copyright: category: Text, LLM, Llama, Machine Learning, AI, Network, CLI build-type: Simple-tested-with: GHC == 9.12.2+tested-with: GHC == 9.12.3 -- extra-source-files: Source-repository head@@ -20,7 +20,7 @@ Source-repository this type: git location: https://github.com/l29ah/llama-cpp-haskell.git- tag: 0.3+ tag: 0.3.0.1 common stuff ghc-options: -Wall