-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathOpenAI.hs
89 lines (72 loc) · 2.32 KB
/
OpenAI.hs
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
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE TypeOperators #-}
module OpenAI where
import Data.Aeson (FromJSON(..), ToJSON, Options(..))
import Data.Text (Text)
import Data.Vector (Vector)
import GHC.Generics (Generic)
import Numeric.Natural (Natural)
import Servant.API
(Header', JSON, Post, ReqBody, Required, Strict, (:>), (:<|>))
import qualified Data.Aeson as Aeson
dropTrailingUnderscore :: String -> String
dropTrailingUnderscore "_" = ""
dropTrailingUnderscore "" = ""
dropTrailingUnderscore (c : cs) = c : dropTrailingUnderscore cs
aesonOptions :: Options
aesonOptions = Aeson.defaultOptions
{ fieldLabelModifier = dropTrailingUnderscore
}
data EmbeddingRequest = EmbeddingRequest
{ input :: Vector Text
, model :: Text
} deriving stock (Generic, Show)
deriving anyclass (ToJSON)
data EmbeddingResponse = EmbeddingResponse
{ data_ :: Vector Embedding
} deriving stock (Generic, Show)
instance FromJSON EmbeddingResponse where
parseJSON = Aeson.genericParseJSON aesonOptions
data Embedding = Embedding
{ index :: Natural
, embedding :: Vector Double
} deriving stock (Generic, Show)
deriving anyclass (FromJSON)
type Embeddings =
"embeddings"
:> ReqBody '[JSON] EmbeddingRequest
:> Post '[JSON] EmbeddingResponse
data CompletionRequest = CompletionRequest
{ messages :: Vector Message
, model :: Text
, max_tokens :: Maybe Natural
} deriving stock (Generic, Show)
deriving anyclass (ToJSON)
data Message = Message
{ content :: Text
, role :: Text
} deriving stock (Generic, Show)
deriving anyclass (FromJSON, ToJSON)
data CompletionResponse = CompletionResponse
{ choices :: Vector Choice
} deriving stock (Generic, Show)
deriving anyclass (FromJSON)
data Choice = Choice
{ message :: Message
} deriving stock (Generic, Show)
deriving anyclass (FromJSON)
type Completions =
"chat"
:> "completions"
:> ReqBody '[JSON] CompletionRequest
:> Post '[JSON] CompletionResponse
type API =
Header' [Required, Strict] "Authorization" Text
:> "v1"
:> ( Embeddings
:<|> Completions
)