openai-servant 0.2.1.0 → 0.2.2.0
raw patch · 6 files changed
+273/−154 lines, 6 filessetup-changedPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- OpenAI.Resources: FileHunk :: Text -> Maybe Text -> FileHunk
- OpenAI.Resources: [fhContent] :: FileHunk -> Text
- OpenAI.Resources: [fhMetadata] :: FileHunk -> Maybe Text
+ OpenAI.Api: type FineTuneApi = OpenAIAuth :> "fine-tunes" :> ReqBody '[JSON] FineTuneCreate :> Post '[JSON] FineTune :<|> OpenAIAuth :> "fine-tunes" :> Get '[JSON] (OpenAIList FineTune) :<|> OpenAIAuth :> "fine-tunes" :> Capture "fine_tune_id" FineTuneId :> Get '[JSON] FineTune :<|> OpenAIAuth :> "fine-tunes" :> Capture "fine_tune_id" FineTuneId :> "cancel" :> Post '[JSON] FineTune :<|> OpenAIAuth :> "fine-tunes" :> Capture "fine_tune_id" FineTuneId :> "events" :> Get '[JSON] (OpenAIList FineTuneEvent)
+ OpenAI.Resources: ClassificationHunk :: Text -> Text -> ClassificationHunk
+ OpenAI.Resources: Embedding :: Vector Double -> Int -> Embedding
+ OpenAI.Resources: EmbeddingCreate :: Text -> EmbeddingCreate
+ OpenAI.Resources: FhClassifications :: ClassificationHunk -> FileHunk
+ OpenAI.Resources: FhFineTune :: FineTuneHunk -> FileHunk
+ OpenAI.Resources: FhSearch :: SearchHunk -> FileHunk
+ OpenAI.Resources: FineTune :: FineTuneId -> Text -> Int -> Vector FineTuneEvent -> Maybe Text -> Text -> FineTune
+ OpenAI.Resources: FineTuneCreate :: FileId -> Maybe FileId -> Maybe Text -> Maybe Int -> Maybe Text -> Maybe Double -> Maybe Double -> Maybe Bool -> Maybe Int -> Maybe Text -> FineTuneCreate
+ OpenAI.Resources: FineTuneEvent :: Int -> Text -> Text -> FineTuneEvent
+ OpenAI.Resources: FineTuneHunk :: Text -> Text -> FineTuneHunk
+ OpenAI.Resources: FineTuneId :: Text -> FineTuneId
+ OpenAI.Resources: SearchHunk :: Text -> Maybe Text -> SearchHunk
+ OpenAI.Resources: [chLabel] :: ClassificationHunk -> Text
+ OpenAI.Resources: [chText] :: ClassificationHunk -> Text
+ OpenAI.Resources: [eEmbedding] :: Embedding -> Vector Double
+ OpenAI.Resources: [eIndex] :: Embedding -> Int
+ OpenAI.Resources: [ecInput] :: EmbeddingCreate -> Text
+ OpenAI.Resources: [ftCreatedAt] :: FineTune -> Int
+ OpenAI.Resources: [ftEvents] :: FineTune -> Vector FineTuneEvent
+ OpenAI.Resources: [ftId] :: FineTune -> FineTuneId
+ OpenAI.Resources: [ftModel] :: FineTune -> Text
+ OpenAI.Resources: [ftStatus] :: FineTune -> Text
+ OpenAI.Resources: [ftTunedModel] :: FineTune -> Maybe Text
+ OpenAI.Resources: [ftcBatchSize] :: FineTuneCreate -> Maybe Int
+ OpenAI.Resources: [ftcClassificationNClasses] :: FineTuneCreate -> Maybe Int
+ OpenAI.Resources: [ftcClassificationPositiveClass] :: FineTuneCreate -> Maybe Text
+ OpenAI.Resources: [ftcComputeClassificationMetrics] :: FineTuneCreate -> Maybe Bool
+ OpenAI.Resources: [ftcLearningRateMultiplier] :: FineTuneCreate -> Maybe Double
+ OpenAI.Resources: [ftcModel] :: FineTuneCreate -> Maybe Text
+ OpenAI.Resources: [ftcNEpochs] :: FineTuneCreate -> Maybe Text
+ OpenAI.Resources: [ftcPromptLossWeight] :: FineTuneCreate -> Maybe Double
+ OpenAI.Resources: [ftcTrainingFile] :: FineTuneCreate -> FileId
+ OpenAI.Resources: [ftcValidationFile] :: FineTuneCreate -> Maybe FileId
+ OpenAI.Resources: [fteCreatedAt] :: FineTuneEvent -> Int
+ OpenAI.Resources: [fteLevel] :: FineTuneEvent -> Text
+ OpenAI.Resources: [fteMessage] :: FineTuneEvent -> Text
+ OpenAI.Resources: [fthCompletion] :: FineTuneHunk -> Text
+ OpenAI.Resources: [fthPrompt] :: FineTuneHunk -> Text
+ OpenAI.Resources: [shMetadata] :: SearchHunk -> Maybe Text
+ OpenAI.Resources: [shText] :: SearchHunk -> Text
+ OpenAI.Resources: [unFineTuneId] :: FineTuneId -> Text
+ OpenAI.Resources: data ClassificationHunk
+ OpenAI.Resources: data Embedding
+ OpenAI.Resources: data EmbeddingCreate
+ OpenAI.Resources: data FineTune
+ OpenAI.Resources: data FineTuneCreate
+ OpenAI.Resources: data FineTuneEvent
+ OpenAI.Resources: data FineTuneHunk
+ OpenAI.Resources: data SearchHunk
+ OpenAI.Resources: defaultFineTuneCreate :: FileId -> FineTuneCreate
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.ClassificationHunk
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.Embedding
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.EmbeddingCreate
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.FineTune
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.FineTuneCreate
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.FineTuneEvent
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.FineTuneHunk
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.FineTuneId
+ OpenAI.Resources: instance Data.Aeson.Types.FromJSON.FromJSON OpenAI.Resources.SearchHunk
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.ClassificationHunk
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.Embedding
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.EmbeddingCreate
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.FineTune
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.FineTuneCreate
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.FineTuneEvent
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.FineTuneHunk
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.FineTuneId
+ OpenAI.Resources: instance Data.Aeson.Types.ToJSON.ToJSON OpenAI.Resources.SearchHunk
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.ClassificationHunk
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.Embedding
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.EmbeddingCreate
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.FineTune
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.FineTuneCreate
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.FineTuneEvent
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.FineTuneHunk
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.FineTuneId
+ OpenAI.Resources: instance GHC.Classes.Eq OpenAI.Resources.SearchHunk
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.ClassificationHunk
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.Embedding
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.EmbeddingCreate
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.FineTune
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.FineTuneCreate
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.FineTuneEvent
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.FineTuneHunk
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.FineTuneId
+ OpenAI.Resources: instance GHC.Show.Show OpenAI.Resources.SearchHunk
+ OpenAI.Resources: instance Web.Internal.HttpApiData.ToHttpApiData OpenAI.Resources.FineTuneId
+ OpenAI.Resources: newtype FineTuneId
- OpenAI.Api: type EnginesApi = OpenAIAuth :> Get '[JSON] (OpenAIList Engine) :<|> OpenAIAuth :> Capture "engine_id" EngineId :> Get '[JSON] Engine :<|> OpenAIAuth :> Capture "engine_id" EngineId :> "completions" :> ReqBody '[JSON] TextCompletionCreate :> Post '[JSON] TextCompletion :<|> OpenAIAuth :> Capture "engine_id" EngineId :> "search" :> ReqBody '[JSON] SearchResultCreate :> Post '[JSON] (OpenAIList SearchResult)
+ OpenAI.Api: type EnginesApi = OpenAIAuth :> Get '[JSON] (OpenAIList Engine) :<|> OpenAIAuth :> Capture "engine_id" EngineId :> Get '[JSON] Engine :<|> OpenAIAuth :> Capture "engine_id" EngineId :> "completions" :> ReqBody '[JSON] TextCompletionCreate :> Post '[JSON] TextCompletion :<|> OpenAIAuth :> Capture "engine_id" EngineId :> "search" :> ReqBody '[JSON] SearchResultCreate :> Post '[JSON] (OpenAIList SearchResult) :<|> OpenAIAuth :> Capture "engine_id" EngineId :> "embeddings" :> ReqBody '[JSON] EmbeddingCreate :> Post '[JSON] (OpenAIList Embedding)
- OpenAI.Api: type OpenAIApiInternal = "engines" :> EnginesApi :<|> "files" :> FilesApi :<|> AnswerApi
+ OpenAI.Api: type OpenAIApiInternal = "engines" :> EnginesApi :<|> "files" :> FilesApi :<|> AnswerApi :<|> FineTuneApi
Files
- LICENSE +1/−1
- Setup.hs +1/−0
- openai-servant.cabal +3/−3
- src/OpenAI/Api.hs +25/−18
- src/OpenAI/Internal/Aeson.hs +5/−8
- src/OpenAI/Resources.hs +238/−124
LICENSE view
@@ -1,4 +1,4 @@-Copyright Alexander Thiemann <mail@thiemann.at> (c) 2020+Copyright Alexander Thiemann <mail@thiemann.at> (c) 2021-2022 All rights reserved.
Setup.hs view
@@ -1,2 +1,3 @@ import Distribution.Simple+ main = defaultMain
openai-servant.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: d66854fa4f05fdb20cfe30829902f9bdd793c39e6b314aabbcb6568b637db03e+-- hash: fa6a579e19b730c3c7362a8966f384ff312aaceb6cf8cdceff036ed2ec48f90b name: openai-servant-version: 0.2.1.0+version: 0.2.2.0 synopsis: Unofficial OpenAI servant types description: Unofficial description of the OpenAI API using servant types category: Web@@ -15,7 +15,7 @@ bug-reports: https://github.com/agrafix/openai-hs/issues author: Alexander Thiemann <mail@thiemann.at> maintainer: Alexander Thiemann <mail@thiemann.at>-copyright: 2021 Alexander Thiemann <mail@thiemann.at>+copyright: 2021-2022 Alexander Thiemann <mail@thiemann.at> license: BSD3 license-file: LICENSE build-type: Simple
src/OpenAI/Api.hs view
@@ -1,31 +1,38 @@ -- | The API- module OpenAI.Api where import OpenAI.Resources- import Servant.API import Servant.Multipart.API type OpenAIAuth = BasicAuth "OpenAI API" () -type OpenAIApi- = "v1" :> OpenAIApiInternal+type OpenAIApi =+ "v1" :> OpenAIApiInternal -type OpenAIApiInternal- = "engines" :> EnginesApi- :<|> "files" :> FilesApi- :<|> AnswerApi+type OpenAIApiInternal =+ "engines" :> EnginesApi+ :<|> "files" :> FilesApi+ :<|> AnswerApi+ :<|> FineTuneApi -type FilesApi- = OpenAIAuth :> MultipartForm Mem FileCreate :> Post '[JSON] File- :<|> OpenAIAuth :> Capture "file_id" FileId :> Delete '[JSON] FileDeleteConfirmation+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 AnswerApi =+ "answers" :> OpenAIAuth :> ReqBody '[JSON] AnswerReq :> Post '[JSON] AnswerResp -type EnginesApi- = OpenAIAuth :> Get '[JSON] (OpenAIList Engine)- :<|> OpenAIAuth :> Capture "engine_id" EngineId :> Get '[JSON] Engine- :<|> OpenAIAuth :> Capture "engine_id" EngineId :> "completions" :> ReqBody '[JSON] TextCompletionCreate :> Post '[JSON] TextCompletion- :<|> OpenAIAuth :> Capture "engine_id" EngineId :> "search" :> ReqBody '[JSON] SearchResultCreate :> Post '[JSON] (OpenAIList SearchResult)+type FineTuneApi =+ OpenAIAuth :> "fine-tunes" :> ReqBody '[JSON] FineTuneCreate :> Post '[JSON] FineTune+ :<|> OpenAIAuth :> "fine-tunes" :> Get '[JSON] (OpenAIList FineTune)+ :<|> OpenAIAuth :> "fine-tunes" :> Capture "fine_tune_id" FineTuneId :> Get '[JSON] FineTune+ :<|> OpenAIAuth :> "fine-tunes" :> Capture "fine_tune_id" FineTuneId :> "cancel" :> Post '[JSON] FineTune+ :<|> OpenAIAuth :> "fine-tunes" :> Capture "fine_tune_id" FineTuneId :> "events" :> Get '[JSON] (OpenAIList FineTuneEvent)++type EnginesApi =+ OpenAIAuth :> Get '[JSON] (OpenAIList Engine)+ :<|> OpenAIAuth :> Capture "engine_id" EngineId :> Get '[JSON] Engine+ :<|> OpenAIAuth :> Capture "engine_id" EngineId :> "completions" :> ReqBody '[JSON] TextCompletionCreate :> Post '[JSON] TextCompletion+ :<|> OpenAIAuth :> Capture "engine_id" EngineId :> "search" :> ReqBody '[JSON] SearchResultCreate :> Post '[JSON] (OpenAIList SearchResult)+ :<|> OpenAIAuth :> Capture "engine_id" EngineId :> "embeddings" :> ReqBody '[JSON] EmbeddingCreate :> Post '[JSON] (OpenAIList Embedding)
src/OpenAI/Internal/Aeson.hs view
@@ -1,8 +1,5 @@ -- |--module OpenAI.Internal.Aeson- ( jsonOpts, deriveJSON, ToJSON, FromJSON )-where+module OpenAI.Internal.Aeson (jsonOpts, deriveJSON, ToJSON, FromJSON) where import Data.Aeson import Data.Aeson.TH@@ -11,7 +8,7 @@ jsonOpts :: Int -> Options jsonOpts x = defaultOptions- { fieldLabelModifier = quietSnake . drop x- , constructorTagModifier = quietSnake- , omitNothingFields = True- }+ { fieldLabelModifier = quietSnake . drop x,+ constructorTagModifier = quietSnake,+ omitNothingFields = True+ }
src/OpenAI/Resources.hs view
@@ -1,37 +1,65 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TemplateHaskell #-}+ module OpenAI.Resources ( -- * Core Types- TimeStamp(..), OpenAIList(..)+ TimeStamp (..),+ OpenAIList (..),+ -- * Engine- , EngineId(..), Engine(..)+ EngineId (..),+ Engine (..),+ -- * Text completion- , TextCompletionId(..), TextCompletionChoice(..), TextCompletion(..), TextCompletionCreate(..)- , defaultTextCompletionCreate+ TextCompletionId (..),+ TextCompletionChoice (..),+ TextCompletion (..),+ TextCompletionCreate (..),+ defaultTextCompletionCreate,++ -- * Embeddings+ EmbeddingCreate (..),+ Embedding (..),++ -- * Fine tuning+ FineTuneId (..),+ FineTuneCreate (..),+ defaultFineTuneCreate,+ FineTune (..),+ FineTuneEvent (..),+ -- * Searching- , SearchResult(..), SearchResultCreate(..)+ SearchResult (..),+ SearchResultCreate (..),+ -- * File API- , FileCreate(..), FileId(..), File(..), FileHunk(..)- , FileDeleteConfirmation(..)+ FileCreate (..),+ FileId (..),+ File (..),+ FileHunk (..),+ SearchHunk (..),+ ClassificationHunk (..),+ FineTuneHunk (..),+ FileDeleteConfirmation (..),+ -- * Answers API- , AnswerReq(..), AnswerResp(..)+ AnswerReq (..),+ AnswerResp (..), ) where -import OpenAI.Internal.Aeson--import Data.Time-import Data.Time.Clock.POSIX-import Servant.API-import Servant.Multipart.API import qualified Data.Aeson as A import qualified Data.ByteString.Lazy as BSL import qualified Data.Text as T+import Data.Time+import Data.Time.Clock.POSIX import qualified Data.Vector as V+import OpenAI.Internal.Aeson+import Servant.API+import Servant.Multipart.API -- | A 'UTCTime' wrapper that has unix timestamp JSON representation-newtype TimeStamp- = TimeStamp { unTimeStamp :: UTCTime }+newtype TimeStamp = TimeStamp {unTimeStamp :: UTCTime} deriving (Show, Eq) instance A.ToJSON TimeStamp where@@ -40,22 +68,22 @@ instance A.FromJSON TimeStamp where parseJSON = A.withScientific "unix timestamp" $ \sci ->- pure $ TimeStamp $ posixSecondsToUTCTime (fromRational $ toRational sci)+ pure $ TimeStamp $ posixSecondsToUTCTime (fromRational $ toRational sci) instance ToHttpApiData TimeStamp where toUrlPiece x = let unix :: Int unix = round . utcTimeToPOSIXSeconds . unTimeStamp $ x- in T.pack (show unix)+ in T.pack (show unix) -- | A 'V.Vector' wrapper.-newtype OpenAIList a- = OpenAIList+newtype OpenAIList a = OpenAIList { olData :: V.Vector a- } deriving (Show, Eq, Functor)+ }+ deriving (Show, Eq, Functor) instance Semigroup (OpenAIList a) where- (<>) a b = OpenAIList (olData a <> olData b)+ (<>) a b = OpenAIList (olData a <> olData b) instance Monoid (OpenAIList a) where mempty = OpenAIList mempty@@ -64,142 +92,220 @@ pure = OpenAIList . pure (<*>) go x = OpenAIList (olData go <*> olData x) -newtype EngineId- = EngineId { unEngineId :: T.Text }+newtype EngineId = EngineId {unEngineId :: T.Text} deriving (Show, Eq, ToJSON, FromJSON, ToHttpApiData) -data Engine- = Engine- { eId :: EngineId- , eOwner :: T.Text- , eReady :: Bool- } deriving (Show, Eq)-+data Engine = Engine+ { eId :: EngineId,+ eOwner :: T.Text,+ eReady :: Bool+ }+ deriving (Show, Eq) -newtype TextCompletionId- = TextCompletionId { unTextCompletionId :: T.Text }+newtype TextCompletionId = TextCompletionId {unTextCompletionId :: T.Text} deriving (Show, Eq, ToJSON, FromJSON, ToHttpApiData) -data TextCompletionChoice- = TextCompletionChoice- { tccText :: T.Text- , tccIndex :: Int- , tccLogProps :: Maybe Int- , tccFinishReason :: T.Text- } deriving (Show, Eq)+data TextCompletionChoice = TextCompletionChoice+ { tccText :: T.Text,+ tccIndex :: Int,+ tccLogProps :: Maybe Int,+ tccFinishReason :: T.Text+ }+ deriving (Show, Eq) -data TextCompletion- = TextCompletion- { tcId :: TextCompletionId- , tcCreated :: TimeStamp- , tcModel :: T.Text- , tcChoices :: V.Vector TextCompletionChoice- } deriving (Show, Eq)+data TextCompletion = TextCompletion+ { tcId :: TextCompletionId,+ tcCreated :: TimeStamp,+ tcModel :: T.Text,+ tcChoices :: V.Vector TextCompletionChoice+ }+ deriving (Show, Eq) -data TextCompletionCreate- = TextCompletionCreate- { tccrPrompt :: T.Text -- TODO: support lists of strings- , tccrMaxTokens :: Maybe Int- , tccrTemperature :: Maybe Double- , tccrTopP :: Maybe Double- , tccrN :: Maybe Int- , tccrLogprobs :: Maybe Int- , tccrEcho :: Maybe Bool- , tccrStop :: Maybe (V.Vector T.Text)- , tccrPresencePenalty :: Maybe Double- , tccrFrequencyPenalty :: Maybe Double- , tccrBestOf :: Maybe Int- } deriving (Show, Eq)+data TextCompletionCreate = TextCompletionCreate+ { tccrPrompt :: T.Text, -- TODO: support lists of strings+ tccrMaxTokens :: Maybe Int,+ tccrTemperature :: Maybe Double,+ tccrTopP :: Maybe Double,+ tccrN :: Maybe Int,+ tccrLogprobs :: Maybe Int,+ tccrEcho :: Maybe Bool,+ tccrStop :: Maybe (V.Vector T.Text),+ tccrPresencePenalty :: Maybe Double,+ tccrFrequencyPenalty :: Maybe Double,+ tccrBestOf :: Maybe Int+ }+ deriving (Show, Eq) -- | Applies API defaults, only passing a prompt. defaultTextCompletionCreate :: T.Text -> TextCompletionCreate defaultTextCompletionCreate prompt = TextCompletionCreate- { tccrPrompt = prompt- , tccrMaxTokens = Nothing- , tccrTemperature = Nothing- , tccrTopP = Nothing- , tccrN = Nothing- , tccrLogprobs = Nothing- , tccrEcho = Nothing- , tccrStop = Nothing- , tccrPresencePenalty = Nothing- , tccrFrequencyPenalty = Nothing- , tccrBestOf = Nothing+ { tccrPrompt = prompt,+ tccrMaxTokens = Nothing,+ tccrTemperature = Nothing,+ tccrTopP = Nothing,+ tccrN = Nothing,+ tccrLogprobs = Nothing,+ tccrEcho = Nothing,+ tccrStop = Nothing,+ tccrPresencePenalty = Nothing,+ tccrFrequencyPenalty = Nothing,+ tccrBestOf = Nothing+ }++data EmbeddingCreate = EmbeddingCreate+ {ecInput :: T.Text}+ deriving (Show, Eq)++data Embedding = Embedding+ {eEmbedding :: V.Vector Double, eIndex :: Int}+ deriving (Show, Eq)++newtype FineTuneId = FineTuneId {unFineTuneId :: T.Text}+ deriving (Show, Eq, ToJSON, FromJSON, ToHttpApiData)++data FineTuneCreate = FineTuneCreate+ { ftcTrainingFile :: FileId,+ ftcValidationFile :: Maybe FileId,+ ftcModel :: Maybe T.Text,+ ftcBatchSize :: Maybe Int,+ ftcNEpochs :: Maybe T.Text,+ ftcLearningRateMultiplier :: Maybe Double,+ ftcPromptLossWeight :: Maybe Double,+ ftcComputeClassificationMetrics :: Maybe Bool,+ ftcClassificationNClasses :: Maybe Int,+ ftcClassificationPositiveClass :: Maybe T.Text }+ deriving (Show, Eq) -data SearchResult- = SearchResult- { srDocument :: Int- , srScore :: Double- , srMetadata :: Maybe T.Text- } deriving (Show, Eq)+defaultFineTuneCreate :: FileId -> FineTuneCreate+defaultFineTuneCreate file =+ FineTuneCreate+ { ftcTrainingFile = file,+ ftcValidationFile = Nothing,+ ftcModel = Nothing,+ ftcBatchSize = Nothing,+ ftcNEpochs = Nothing,+ ftcLearningRateMultiplier = Nothing,+ ftcPromptLossWeight = Nothing,+ ftcComputeClassificationMetrics = Nothing,+ ftcClassificationNClasses = Nothing,+ ftcClassificationPositiveClass = Nothing+ } -data SearchResultCreate- = SearchResultCreate- { sccrFile :: Maybe FileId- , sccrDocuments :: Maybe (V.Vector T.Text)- , sccrQuery :: T.Text- , sccrReturnMetadata :: Bool- } deriving (Show, Eq)+data FineTuneEvent = FineTuneEvent+ { fteCreatedAt :: Int,+ fteLevel :: T.Text,+ fteMessage :: T.Text+ }+ deriving (Show, Eq) +data FineTune = FineTune+ { ftId :: FineTuneId,+ ftModel :: T.Text,+ ftCreatedAt :: Int,+ ftEvents :: V.Vector FineTuneEvent,+ ftTunedModel :: Maybe T.Text,+ ftStatus :: T.Text+ }+ deriving (Show, Eq)++data SearchResult = SearchResult+ { srDocument :: Int,+ srScore :: Double,+ srMetadata :: Maybe T.Text+ }+ deriving (Show, Eq)++data SearchResultCreate = SearchResultCreate+ { sccrFile :: Maybe FileId,+ sccrDocuments :: Maybe (V.Vector T.Text),+ sccrQuery :: T.Text,+ sccrReturnMetadata :: Bool+ }+ deriving (Show, Eq)++data SearchHunk = SearchHunk+ { shText :: T.Text,+ shMetadata :: Maybe T.Text+ }+ deriving (Show, Eq)++data ClassificationHunk = ClassificationHunk+ { chText :: T.Text,+ chLabel :: T.Text+ }+ deriving (Show, Eq)++data FineTuneHunk = FineTuneHunk+ { fthPrompt :: T.Text,+ fthCompletion :: T.Text+ }+ deriving (Show, Eq)+ data FileHunk- = FileHunk- { fhContent :: T.Text- , fhMetadata :: Maybe T.Text- } deriving (Show, Eq)+ = FhSearch SearchHunk+ | FhClassifications ClassificationHunk+ | FhFineTune FineTuneHunk+ deriving (Show, Eq) -data FileCreate- = FileCreate- { fcPurpose :: T.Text- , fcDocuments :: [FileHunk]- } 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+ map+ ( \t -> A.encode $+ case t of+ FhSearch x -> A.toJSON x+ FhClassifications x -> A.toJSON x+ FhFineTune x -> A.toJSON x+ )+ docs instance ToMultipart Mem FileCreate where toMultipart rfc = MultipartData- [ Input "purpose" (fcPurpose rfc)- ]- [ FileData "file" "data.jsonl" "application/json" (packDocuments $ fcDocuments rfc)- ]+ [ Input "purpose" (fcPurpose rfc)+ ]+ [ FileData "file" "data.jsonl" "application/json" (packDocuments $ fcDocuments rfc)+ ] -newtype FileId- = FileId { unFileId :: T.Text }+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 File = File+ { fId :: FileId,+ fCreatedAt :: TimeStamp,+ fPurpose :: T.Text+ }+ deriving (Show, Eq) -data FileDeleteConfirmation- = FileDeleteConfirmation+data FileDeleteConfirmation = FileDeleteConfirmation { fdcId :: FileId- } deriving (Show, Eq)+ }+ 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 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+data AnswerResp = AnswerResp { arsAnswers :: [T.Text]- } deriving (Show, Eq)+ }+ deriving (Show, Eq) $(deriveJSON (jsonOpts 2) ''OpenAIList) $(deriveJSON (jsonOpts 1) ''Engine)@@ -212,3 +318,11 @@ $(deriveJSON (jsonOpts 3) ''FileDeleteConfirmation) $(deriveJSON (jsonOpts 2) ''AnswerReq) $(deriveJSON (jsonOpts 3) ''AnswerResp)+$(deriveJSON (jsonOpts 2) ''EmbeddingCreate)+$(deriveJSON (jsonOpts 1) ''Embedding)+$(deriveJSON (jsonOpts 3) ''FineTuneCreate)+$(deriveJSON (jsonOpts 3) ''FineTuneEvent)+$(deriveJSON (jsonOpts 2) ''FineTune)+$(deriveJSON (jsonOpts 2) ''SearchHunk)+$(deriveJSON (jsonOpts 2) ''ClassificationHunk)+$(deriveJSON (jsonOpts 3) ''FineTuneHunk)