Add simplex-bot.hs

This commit is contained in:
first 2025-01-09 07:55:09 +00:00
parent 74bda361cd
commit 68efaf3279

96
simplex-bot.hs Normal file
View file

@ -0,0 +1,96 @@
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
module Main where
import Simplex.Chat.Bot
import Simplex.Chat.Controller (versionNumber)
import Simplex.Chat.Core
import Simplex.Chat.Options
import Simplex.Chat.Terminal (terminalChatConfig)
import System.Directory (getAppUserDataDirectory)
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import Network.HTTP.Simple
import Data.Aeson
import GHC.Generics
import qualified Data.ByteString.Lazy as BL
import System.Environment (getEnv)
import Control.Monad.IO.Class (liftIO)
-- Data types for Venice.ai API
data ChatMessage = ChatMessage
{ role :: String
, content :: String
} deriving (Show, Generic)
data ChatRequest = ChatRequest
{ model :: String
, messages :: [ChatMessage]
, temperature :: Float
} deriving (Show, Generic)
data ChatResponse = ChatResponse
{ choices :: [Choice]
} deriving (Show, Generic)
data Choice = Choice
{ message :: ChatMessage
} deriving (Show, Generic)
instance ToJSON ChatMessage
instance ToJSON ChatRequest
instance FromJSON ChatMessage
instance FromJSON ChatResponse
instance FromJSON Choice
-- Venice API client function
callVeniceAPI :: String -> String -> IO (Maybe String)
callVeniceAPI apiKey userMessage = do
let request = ChatRequest
{ model = "venice-model" -- Replace with actual Venice model name
, messages = [ChatMessage "user" userMessage]
, temperature = 0.7
}
let jsonRequest = encode request
initReq <- parseRequest "POST https://api.venice.ai/api/v1/chat/completions"
let req = setRequestMethod "POST"
. setRequestHeader "Content-Type" ["application/json"]
. setRequestHeader "Authorization" ["Bearer " <> TE.encodeUtf8 (T.pack apiKey)]
. setRequestBodyLBS jsonRequest
$ initReq
response <- httpLBS req
let decoded = decode (getResponseBody response) :: Maybe ChatResponse
return $ case decoded of
Just chatResponse -> case choices chatResponse of
(choice:_) -> Just $ content (message choice)
_ -> Nothing
Nothing -> Nothing
main :: IO ()
main = do
opts <- welcomeGetOpts
apiKey <- getEnv "VENICE_API_KEY"
simplexChatCore terminalChatConfig opts $
chatBotRepl welcomeMessage $ \_contact msg -> do
case words msg of
("/bot":rest) -> do
response <- liftIO $ callVeniceAPI apiKey (unwords rest)
pure $ case response of
Just reply -> reply
Nothing -> "Sorry, I couldn't process that request."
_ -> pure "" -- Don't respond to messages without the /bot prefix
welcomeMessage :: String
welcomeMessage = "Hello! I'm a Venice.ai powered chat bot.\nUse /bot followed by your message to talk to me."
welcomeGetOpts :: IO ChatOpts
welcomeGetOpts = do
appDir <- getAppUserDataDirectory "simplex"
opts@ChatOpts {coreOptions = CoreChatOpts {dbFilePrefix}} <- getChatOpts appDir "simplex_bot"
putStrLn $ "SimpleX Chat Bot v" ++ versionNumber
putStrLn $ "db: " <> dbFilePrefix <> "_chat.db, " <> dbFilePrefix <> "_agent.db"
pure opts