git.mcksp
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
{-# LANGUAGE DeriveGeneric #-}

module Openai
    ( chatCall
    , ChatResponse(..)
    , Choice(..)
    , Message(..)
    ) where

import Data.Text
import Network.HTTP.Simple
import Data.Aeson
import GHC.Generics (Generic)
import Env

data ChatReq = ChatReq
    { model :: Text
    , response_format :: RespForm
    , messages :: [Message]
    } deriving (Generic)
instance ToJSON ChatReq where

data RespForm = RespForm
    { typeX :: Text
    } deriving (Generic)
instance ToJSON RespForm where
    toJSON (RespForm t) =
        object [ "type" .= t ]

data Message = Message
    { role :: Text
    , content :: Text
    } deriving (Generic)
instance ToJSON Message where
instance FromJSON Message where

data ChatResponse = ChatResponse
    { choices :: [Choice]
    , model :: Text
    , usage :: Usage
    } deriving (Generic)
instance FromJSON ChatResponse where
instance ToJSON ChatResponse where

data Usage = Usage
    { completion_tokens :: Int
    , prompt_tokens :: Int
    , total_tokens :: Int
    } deriving (Generic)
instance FromJSON Usage where
instance ToJSON Usage where

data Choice = Choice
    { finishReason :: Maybe Text
    , index :: Int
    , message :: Message
    , logprobs :: Maybe Text
    } deriving (Generic)
instance FromJSON Choice where
instance ToJSON Choice where

chatCall :: Text -> IO ChatResponse
chatCall prompt = do
    let request = setRequestMethod "POST"
            $ setRequestSecure True
            $ setRequestPort 443
            $ setRequestHost "api.openai.com"
            $ setRequestPath "/v1/chat/completions"
            $ setRequestBodyJSON (chatReq prompt)
            $ setRequestBearerAuth openaiEnv.apikey
            $ defaultRequest

    response <- httpJSON request
    let body = getResponseBody response :: ChatResponse
    print $ encode body
    return body

chatReq :: Text -> ChatReq
chatReq prompt = ChatReq
    { model = "gpt-4o"
    , response_format = RespForm "json_object"
    , messages =
        [ Message
            { role = "system"
            , content = "You are a helpful assistant. Your main job is creating short stories for kids designated to output JSON"
            }
        , Message
            { role = "user"
            , content = prompt <> ". Your response should be a JSON with fields: title - title of a story, summary - two sentcence summary of a story, story - whole story."
            }
        ]
    }