openai-servant 0.1.0.0 → 0.2.0.0
raw patch · 3 files changed
+87/−3 lines, 3 filesdep +bytestringdep +servant-multipartPVP ok
version bump matches the API change (PVP)
Dependencies added: bytestring, servant-multipart
API changes (from Hackage documentation)
+ OpenAI.Api: type AnswerApi = "answers" :> OpenAIAuth :> ReqBody '[JSON] AnswerReq :> Post '[JSON] AnswerResp
+ OpenAI.Api: type FilesApi = OpenAIAuth :> MultipartForm Mem FileCreate :> Post '[JSON] File :<|> OpenAIAuth :> Capture "file_id" FileId :> Delete '[JSON] FileDeleteConfirmation
+ OpenAI.Resources: AnswerReq :: Maybe FileId -> Maybe (Vector Text) -> Text -> EngineId -> EngineId -> Text -> [[Text]] -> Bool -> AnswerReq
+ OpenAI.Resources: AnswerResp :: [Text] -> AnswerResp
+ OpenAI.Resources: File :: FileId -> TimeStamp -> Text -> File
+ OpenAI.Resources: FileCreate :: Text -> [FileHunk] -> FileCreate
+ OpenAI.Resources: FileDeleteConfirmation :: FileId -> FileDeleteConfirmation
+ OpenAI.Resources: FileHunk :: Text -> Maybe Text -> FileHunk
+ OpenAI.Resources: FileId :: Text -> FileId
+ OpenAI.Resources: [arDocuments] :: AnswerReq -> Maybe (Vector Text)
+ OpenAI.Resources: [arExamplesContext] :: AnswerReq -> Text
+ OpenAI.Resources: [arExamples] :: AnswerReq -> [[Text]]
+ OpenAI.Resources: [arFile] :: AnswerReq -> Maybe FileId
+ OpenAI.Resources: [arModel] :: AnswerReq -> EngineId
+ OpenAI.Resources: [arQuestion] :: AnswerReq -> Text
+ OpenAI.Resources: [arReturnMetadata] :: AnswerReq -> Bool
+ OpenAI.Resources: [arSearchModel] :: AnswerReq -> EngineId
+ OpenAI.Resources: [arsAnswers] :: AnswerResp -> [Text]
+ OpenAI.Resources: [fCreatedAt] :: File -> TimeStamp
+ OpenAI.Resources: [fId] :: File -> FileId
+ OpenAI.Resources: [fPurpose] :: File -> Text
+ OpenAI.Resources: [fcDocuments] :: FileCreate -> [FileHunk]
+ OpenAI.Resources: [fcPurpose] :: FileCreate -> Text
+ OpenAI.Resources: [fdcId] :: FileDeleteConfirmation -> FileId
+ OpenAI.Resources: [fhContent] :: FileHunk -> Text
+ OpenAI.Resources: [fhMetadata] :: FileHunk -> Maybe Text
+ OpenAI.Resources: [sccrFile] :: SearchResultCreate -> Maybe FileId
+ OpenAI.Resources: [sccrReturnMetadata] :: SearchResultCreate -> Bool
+ OpenAI.Resources: [srMetadata] :: SearchResult -> Maybe Text
+ OpenAI.Resources: [unFileId] :: FileId -> Text
+ OpenAI.Resources: data AnswerReq
+ OpenAI.Resources: data AnswerResp
+ OpenAI.Resources: data File
+ OpenAI.Resources: data FileCreate
+ OpenAI.Resources: data FileDeleteConfirmation
+ OpenAI.Resources: data FileHunk
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.AnswerReq
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.AnswerResp
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.File
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.FileDeleteConfirmation
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.FileId
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.AnswerReq
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.AnswerResp
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.File
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.FileDeleteConfirmation
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.FileId
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.AnswerReq
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.AnswerResp
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.File
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.FileCreate
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.FileDeleteConfirmation
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.FileHunk
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.FileId
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.AnswerReq
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.AnswerResp
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.File
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.FileCreate
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.FileDeleteConfirmation
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.FileHunk
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.FileId
+ OpenAI.Resources: instance Servant.Multipart.ToMultipart Servant.Multipart.Mem OpenAI.Resources.FileCreate
+ OpenAI.Resources: instance Web.Internal.HttpApiData.ToHttpApiData OpenAI.Resources.FileId
+ OpenAI.Resources: newtype FileId
- OpenAI.Api: type OpenAIApiInternal = "engines" :> EnginesApi
+ OpenAI.Api: type OpenAIApiInternal = "engines" :> EnginesApi :<|> "files" :> FilesApi :<|> AnswerApi
- OpenAI.Resources: SearchResult :: Int -> Double -> SearchResult
+ OpenAI.Resources: SearchResult :: Int -> Double -> Maybe Text -> SearchResult
- OpenAI.Resources: SearchResultCreate :: Vector Text -> Text -> SearchResultCreate
+ OpenAI.Resources: SearchResultCreate :: Maybe FileId -> Maybe (Vector Text) -> Text -> Bool -> SearchResultCreate
- OpenAI.Resources: [sccrDocuments] :: SearchResultCreate -> Vector Text
+ OpenAI.Resources: [sccrDocuments] :: SearchResultCreate -> Maybe (Vector Text)
Files
- openai-servant.cabal +4/−2
- src/OpenAI/Api.hs +10/−0
- src/OpenAI/Resources.hs +73/−1
openai-servant.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 7d9611438da3fd219c80f23301bed8d6b0ed55b71c59d82b976a6e0704630db3+-- hash: 0f47df90d0a45b723d7b0b77c3679bccd709f8c989a14ca39f9c4f7abb0f4f08 name: openai-servant-version: 0.1.0.0+version: 0.2.0.0 synopsis: Unofficial OpenAI servant types description: Unofficial description of the OpenAI API using servant types category: Web@@ -40,8 +40,10 @@ build-depends: aeson , base >=4.7 && <5+ , bytestring , casing , servant+ , servant-multipart , text , time , vector
src/OpenAI/Api.hs view
@@ -5,6 +5,7 @@ import OpenAI.Resources import Servant.API+import Servant.Multipart type OpenAIAuth = BasicAuth "OpenAI API" () @@ -13,6 +14,15 @@ type OpenAIApiInternal = "engines" :> EnginesApi+ :<|> "files" :> FilesApi+ :<|> AnswerApi++type FilesApi+ = OpenAIAuth :> MultipartForm Mem FileCreate :> Post '[JSON] File+ :<|> OpenAIAuth :> Capture "file_id" FileId :> Delete '[JSON] FileDeleteConfirmation++type AnswerApi+ = "answers" :> OpenAIAuth :> ReqBody '[JSON] AnswerReq :> Post '[JSON] AnswerResp type EnginesApi = OpenAIAuth :> Get '[JSON] (OpenAIList Engine)
src/OpenAI/Resources.hs view
@@ -10,6 +10,11 @@ , defaultTextCompletionCreate -- * Searching , SearchResult(..), SearchResultCreate(..)+ -- * File API+ , FileCreate(..), FileId(..), File(..), FileHunk(..)+ , FileDeleteConfirmation(..)+ -- * Answers API+ , AnswerReq(..), AnswerResp(..) ) where @@ -18,7 +23,9 @@ import Data.Time import Data.Time.Clock.POSIX import Servant.API+import Servant.Multipart import qualified Data.Aeson as A+import qualified Data.ByteString.Lazy as BSL import qualified Data.Text as T import qualified Data.Vector as V @@ -125,14 +132,75 @@ = SearchResult { srDocument :: Int , srScore :: Double+ , srMetadata :: Maybe T.Text } deriving (Show, Eq) data SearchResultCreate = SearchResultCreate- { sccrDocuments :: V.Vector T.Text+ { sccrFile :: Maybe FileId+ , sccrDocuments :: Maybe (V.Vector T.Text) , sccrQuery :: T.Text+ , sccrReturnMetadata :: Bool } deriving (Show, Eq) +data FileHunk+ = FileHunk+ { fhContent :: T.Text+ , fhMetadata :: Maybe T.Text+ } deriving (Show, Eq)++data FileCreate+ = FileCreate+ { fcPurpose :: T.Text+ , fcDocuments :: [FileHunk]+ } deriving (Show, Eq)++packDocuments :: [FileHunk] -> BSL.ByteString+packDocuments docs =+ BSL.intercalate "\n" $+ map (\t -> A.encode $ A.object ["text" A..= fhContent t, "metadata" A..= fhMetadata t]) docs++instance ToMultipart Mem FileCreate where+ toMultipart rfc =+ MultipartData+ [ Input "purpose" (fcPurpose rfc)+ ]+ [ FileData "file" "data.jsonl" "application/json" (packDocuments $ fcDocuments rfc)+ ]++newtype FileId+ = FileId { unFileId :: T.Text }+ deriving (Show, Eq, ToJSON, FromJSON, ToHttpApiData)++data File+ = File+ { fId :: FileId+ , fCreatedAt :: TimeStamp+ , fPurpose :: T.Text+ } deriving (Show, Eq)++data FileDeleteConfirmation+ = FileDeleteConfirmation+ { fdcId :: FileId+ } deriving (Show, Eq)++data AnswerReq+ = AnswerReq+ { arFile :: Maybe FileId+ , arDocuments :: Maybe (V.Vector T.Text)+ , arQuestion :: T.Text+ , arSearchModel :: EngineId+ , arModel :: EngineId+ , arExamplesContext :: T.Text+ , arExamples :: [[T.Text]]+ , arReturnMetadata :: Bool+ } deriving (Show, Eq)++data AnswerResp+ = AnswerResp+ { arsAnswers :: [T.Text]+ } deriving (Show, Eq)+ $(deriveJSON (jsonOpts 2) ''OpenAIList) $(deriveJSON (jsonOpts 1) ''Engine) $(deriveJSON (jsonOpts 2) ''TextCompletion)@@ -140,3 +208,7 @@ $(deriveJSON (jsonOpts 4) ''TextCompletionCreate) $(deriveJSON (jsonOpts 2) ''SearchResult) $(deriveJSON (jsonOpts 4) ''SearchResultCreate)+$(deriveJSON (jsonOpts 1) ''File)+$(deriveJSON (jsonOpts 3) ''FileDeleteConfirmation)+$(deriveJSON (jsonOpts 2) ''AnswerReq)+$(deriveJSON (jsonOpts 3) ''AnswerResp)