{-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeOperators #-} module Main where import Conduit import Data.Conduit.Lazy import qualified Data.Text.IO as T import Options.Generic import System.Exit import System.IO import Llama import Llama.Streaming as LS data Options w = Options { systemPrompt :: w ::: Text "The system prompt to use" "You are a helpful assistant." , url :: w ::: String "llama-server URL" "http://localhost:8080" , streaming :: w ::: Bool "use to stream output from the LLM" } deriving (Generic) instance ParseRecord (Options Wrapped) where parseRecord = parseRecordWithModifiers lispCaseModifiers deriving instance Show (Options Unwrapped) main :: IO () main = do opts <- unwrapRecord "A command line interface for llama-server" input <- T.getContents let request = [ LlamaMessage System $ systemPrompt opts , LlamaMessage User input ] case streaming opts of False -> do response <- llamaTemplated (url opts) (LlamaApplyTemplateRequest request) case response of Nothing -> T.hPutStrLn stderr "Got no response from the server." >> exitFailure Just r -> T.putStrLn r True -> do hSetBuffering stdout NoBuffering conduit <- llamaTemplatedStreaming (url opts) (LlamaApplyTemplateRequest request) runResourceT $ do list <- lazyConsume conduit liftIO $ mapM_ (T.putStr . LS.content) $ list T.putStrLn ""