openai-2.2.0: src/OpenAI/V1/Responses.hs
-- | \/v1/responses
--
-- Streaming is not implemented here; this covers JSON responses only.
module OpenAI.V1.Responses
( -- * Main types
CreateResponse(..)
, _CreateResponse
, Input(..)
, InputItem(..)
, InputRole(..)
, InputContent(..)
, OutputItem(..)
, OutputMessage(..)
, OutputContent(..)
, FunctionToolCall(..)
, FunctionToolCallOutput(..)
, WebSearchToolCall(..)
, FileSearchToolCall(..)
, FileSearchResult(..)
, CodeInterpreterToolCall(..)
, CodeInterpreterOutput(..)
, WebSearchAction(..)
, WebSearchSource(..)
, Annotation(..)
, ReasoningSummary(..)
, Reasoning(..)
, _Reasoning
, ReasoningItem(..)
, SummaryPart(..)
, ReasoningText(..)
, ReasoningEffort(..)
, ServiceTier
, ResponseStreamEvent(..)
, ResponseObject(..)
, ResponseUsage(..)
, InputTokensDetails(..)
, OutputTokensDetails(..)
-- * Constants
, statusIncomplete
, statusCompleted
-- * Servant
, API
) where
import Data.Aeson (Object)
import qualified Data.Aeson as Aeson
import OpenAI.Prelude hiding (Input(..))
-- no TH; inline JSON instances for payloads
import OpenAI.V1.AutoOr (AutoOr(..))
import OpenAI.V1.ListOf (ListOf)
import OpenAI.V1.Models (Model)
import qualified Data.Aeson.Key as Key
import qualified Data.Aeson.KeyMap as KeyMap
import qualified Data.Vector as Vector
import OpenAI.V1.Tool
( Tool
, ToolChoice
, toolChoiceAutoText
, toolChoiceNoneText
, toolChoiceRequiredText
, toolChoiceToResponsesValue
, toolToResponsesValue
, unflattenToolValue
)
-- | Status constants for function call outputs
statusIncomplete, statusCompleted :: Text
statusIncomplete = "incomplete"
statusCompleted = "completed"
-- | Specifies the processing tier used for the request
type ServiceTier = Text
-- | Constrains effort on reasoning for reasoning models.
--
-- Defaults to @ReasoningEffort_Medium@ when omitted. Reducing the effort can
-- result in faster responses with fewer reasoning tokens. The `gpt-5-pro`
-- model currently only supports @ReasoningEffort_High@.
data ReasoningEffort
= ReasoningEffort_Minimal
| ReasoningEffort_Low
| ReasoningEffort_Medium
| ReasoningEffort_High
deriving stock (Eq, Generic, Show)
reasoningEffortOptions :: Options
reasoningEffortOptions =
aesonOptions
{ constructorTagModifier = stripPrefix "ReasoningEffort_" }
instance FromJSON ReasoningEffort where
parseJSON = genericParseJSON reasoningEffortOptions
instance ToJSON ReasoningEffort where
toJSON = genericToJSON reasoningEffortOptions
-- | Reasoning summary verbosity options.
--
-- Note: the @ReasoningSummary_Concise@ option is only supported for
-- `computer-use-preview` models.
data ReasoningSummary
= ReasoningSummary_Auto
| ReasoningSummary_Concise
| ReasoningSummary_Detailed
deriving stock (Eq, Generic, Show)
reasoningSummaryOptions :: Options
reasoningSummaryOptions =
aesonOptions
{ constructorTagModifier = stripPrefix "ReasoningSummary_" }
instance FromJSON ReasoningSummary where
parseJSON = genericParseJSON reasoningSummaryOptions
instance ToJSON ReasoningSummary where
toJSON = genericToJSON reasoningSummaryOptions
-- | Configuration options for reasoning models (`gpt-5` and o-series only).
data Reasoning = Reasoning
{ effort :: Maybe ReasoningEffort
-- ^ Constrains the amount of effort spent by the model on reasoning.
, summary :: Maybe ReasoningSummary
-- ^ Controls whether the model should produce a reasoning summary (one of
-- @auto@, @concise@, or @detailed@). The @concise@ option is currently
-- limited to `computer-use-preview` models.
, generate_summary :: Maybe ReasoningSummary
-- ^ **Deprecated:** use 'summary' instead. When present, behaves like
-- 'summary' and accepts @auto@, @concise@, or @detailed@.
} deriving stock (Eq, Generic, Show)
instance FromJSON Reasoning where
parseJSON = genericParseJSON aesonOptions
instance ToJSON Reasoning where
toJSON = genericToJSON aesonOptions
-- | Default reasoning configuration
_Reasoning :: Reasoning
_Reasoning =
Reasoning
{ effort = Nothing
, summary = Nothing
, generate_summary = Nothing
}
-- | Input for the Responses API: a list of input items
newtype Input = Input (Vector InputItem)
deriving stock (Generic, Show)
instance ToJSON Input where
toJSON (Input xs) = toJSON xs
instance FromJSON Input where
parseJSON v = Input <$> parseJSON v
-- | Role of an input message
data InputRole = User | System | Developer
deriving stock (Eq, Generic, Show)
instance FromJSON InputRole where
parseJSON = genericParseJSON aesonOptions
instance ToJSON InputRole where
toJSON = genericToJSON aesonOptions
-- | Content parts for input messages
data InputContent
= Input_Text { text :: Text }
| Input_Image { image_url :: Maybe Text, file_id :: Maybe Text, detail :: Maybe Text }
| Input_File { file_id :: Maybe Text, filename :: Maybe Text, file_url :: Maybe Text, file_data :: Maybe Text }
| Input_Audio { input_audio :: Object }
deriving stock (Eq, Generic, Show)
inputContentOptions :: Options
inputContentOptions =
aesonOptions
{ sumEncoding = TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
, tagSingleConstructors = True
-- Keep constructor names like "Input_Text" -> "input_text"
, constructorTagModifier = labelModifier
}
instance FromJSON InputContent where
parseJSON = genericParseJSON inputContentOptions
instance ToJSON InputContent where
toJSON = genericToJSON inputContentOptions
-- | An input item
data InputItem
= Item_Input_Message
{ role :: InputRole
, content :: Vector InputContent
, status :: Maybe Text
}
| Item_Input_Function_Call
{ id :: Maybe Text
, call_id :: Text
, name :: Text
, arguments :: Text
, status :: Maybe Text
}
| Item_Input_Function_Call_Output
{ id :: Maybe Text
, call_id :: Text
, output :: Text
, status :: Maybe Text
}
| Item_Input_Reasoning
{ reasoning_id :: Text
, reasoning_encrypted_content :: Maybe Text
, reasoning_summary :: Maybe (Vector SummaryPart)
, reasoning_content :: Maybe (Vector ReasoningText)
, reasoning_status :: Maybe Text
}
| Item_Input_Item_Reference
{ id :: Maybe Text
}
deriving stock (Eq, Generic, Show)
inputItemOptions :: Options
inputItemOptions =
aesonOptions
{ sumEncoding = TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
, tagSingleConstructors = True
, constructorTagModifier = stripPrefix "Item_Input_"
, fieldLabelModifier = stripPrefix "reasoning_"
}
instance FromJSON InputItem where
parseJSON = genericParseJSON inputItemOptions
instance ToJSON InputItem where
toJSON = genericToJSON inputItemOptions
keyTools :: Key.Key
keyTools = Key.fromText "tools"
keyToolChoice :: Key.Key
keyToolChoice = Key.fromText "tool_choice"
flattenResponseToolFields
:: Maybe (Vector Tool)
-> Maybe ToolChoice
-> KeyMap.KeyMap Value
-> KeyMap.KeyMap Value
flattenResponseToolFields mTools mChoice o =
let oWithTools = case mTools of
Nothing -> o
Just ts -> KeyMap.insert keyTools (Aeson.Array (Vector.map toolToResponsesValue ts)) o
oWithChoice = case mChoice of
Nothing -> oWithTools
Just choice -> KeyMap.insert keyToolChoice (toolChoiceToResponsesValue choice) oWithTools
in oWithChoice
unflattenResponseToolFields :: KeyMap.KeyMap Value -> KeyMap.KeyMap Value
unflattenResponseToolFields = adjustChoice . adjustTools
where
adjustTools = adjustKey keyTools (mapArrayValues unflattenToolValue)
adjustChoice = adjustKey keyToolChoice unflattenChoice
unflattenChoice (String s)
| s `elem` ([toolChoiceNoneText, toolChoiceAutoText, toolChoiceRequiredText] :: [Text]) = String s
unflattenChoice other = unflattenToolValue other
mapArrayValues :: (Value -> Value) -> Value -> Value
mapArrayValues f (Aeson.Array arr) = Aeson.Array (Vector.map f arr)
mapArrayValues _ other = other
adjustKey
:: Key.Key
-> (Value -> Value)
-> KeyMap.KeyMap Value
-> KeyMap.KeyMap Value
adjustKey key f obj =
case KeyMap.lookup key obj of
Nothing -> obj
Just v -> KeyMap.insert key (f v) obj
-- | Output content from the model
data OutputContent
= Output_Text
{ text :: Text
, annotations :: Vector Value
, logprobs :: Maybe (Vector Value)
}
| Refusal
{ refusal :: Text }
deriving stock (Generic, Show)
outputContentOptions :: Options
outputContentOptions =
aesonOptions
{ sumEncoding = TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
, tagSingleConstructors = True
}
instance FromJSON OutputContent where
parseJSON = genericParseJSON outputContentOptions
instance ToJSON OutputContent where
toJSON = genericToJSON outputContentOptions
-- | An output message item
data OutputMessage = OutputMessage
{ id :: Text
, role :: Text
, content :: Vector OutputContent
, status :: Text
} deriving stock (Generic, Show)
instance FromJSON OutputMessage where
parseJSON = genericParseJSON aesonOptions
instance ToJSON OutputMessage where
toJSON = genericToJSON aesonOptions
-- | A generated output item.
data OutputItem
= Item_OutputMessage
{ message_id :: Text
, message_role :: Text
, message_content :: Vector OutputContent
, message_status :: Text
}
| Item_FunctionToolCall
{ function_id :: Maybe Text
, function_call_id :: Text
, function_name :: Text
, function_arguments :: Text
, function_status :: Maybe Text
}
| Item_WebSearchToolCall
{ web_search_id :: Text
, web_search_status :: Text
, web_search_action :: Maybe WebSearchAction
}
| Item_FunctionToolCallOutput
{ function_output_id :: Maybe Text
, function_output_call_id :: Text
, function_output_output :: Text
, function_output_status :: Maybe Text
}
| Item_FileSearchToolCall
{ file_search_id :: Text
, file_search_status :: Text
, file_search_queries :: Vector Text
, file_search_results :: Maybe (Vector FileSearchResult)
}
| Item_CodeInterpreterToolCall
{ code_interpreter_id :: Text
, code_interpreter_status :: Text
, code_interpreter_container_id :: Maybe Text
, code_interpreter_code :: Maybe Text
, code_interpreter_outputs :: Maybe (Vector CodeInterpreterOutput)
}
| Item_Reasoning
{ reasoning_id :: Text
, reasoning_encrypted_content :: Maybe Text
, reasoning_summary :: Maybe (Vector SummaryPart)
, reasoning_content :: Maybe (Vector ReasoningText)
, reasoning_status :: Maybe Text
}
deriving stock (Generic, Show)
outputItemOptions :: Options
outputItemOptions = aesonOptions
{ sumEncoding = TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
, tagSingleConstructors = True
, fieldLabelModifier = \s -> case s of
"message_id" -> "id"
"message_role" -> "role"
"message_content" -> "content"
"message_status" -> "status"
"function_id" -> "id"
"function_call_id" -> "call_id"
"function_name" -> "name"
"function_arguments" -> "arguments"
"function_status" -> "status"
"web_search_id" -> "id"
"web_search_status" -> "status"
"web_search_action" -> "action"
"function_output_id" -> "id"
"function_output_call_id" -> "call_id"
"function_output_output" -> "output"
"function_output_status" -> "status"
"file_search_id" -> "id"
"file_search_status" -> "status"
"file_search_queries" -> "queries"
"file_search_results" -> "results"
"code_interpreter_id" -> "id"
"code_interpreter_status" -> "status"
"code_interpreter_container_id" -> "container_id"
"code_interpreter_code" -> "code"
"code_interpreter_outputs" -> "outputs"
"reasoning_id" -> "id"
"reasoning_encrypted_content" -> "encrypted_content"
"reasoning_summary" -> "summary"
"reasoning_content" -> "content"
"reasoning_status" -> "status"
other -> other
, constructorTagModifier = \s -> case s of
"Item_OutputMessage" -> "message"
"Item_FunctionToolCall" -> "function_call"
"Item_WebSearchToolCall" -> "web_search_call"
"Item_FunctionToolCallOutput" -> "function_call_output"
"Item_FileSearchToolCall" -> "file_search_call"
"Item_CodeInterpreterToolCall" -> "code_interpreter_call"
"Item_Reasoning" -> "reasoning"
_ -> Prelude.error "Unknown OutputItem constructor"
}
instance FromJSON OutputItem where
parseJSON = genericParseJSON outputItemOptions
instance ToJSON OutputItem where
toJSON = genericToJSON outputItemOptions
-- | Function tool call output item
data FunctionToolCall = FunctionToolCall
{ id :: Maybe Text
, call_id :: Text
, name :: Text
, arguments :: Text
, status :: Maybe Text
} deriving stock (Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Function tool call output item
data FunctionToolCallOutput = FunctionToolCallOutput
{ id :: Maybe Text
, call_id :: Text
, output :: Text
, status :: Maybe Text
} deriving stock (Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Web search tool call output item (action is left generic for now)
data WebSearchToolCall = WebSearchToolCall
{ id :: Text
, status :: Text
, action :: Maybe WebSearchAction
} deriving stock (Generic, Show)
instance FromJSON WebSearchToolCall where
parseJSON = genericParseJSON aesonOptions
instance ToJSON WebSearchToolCall where
toJSON = genericToJSON aesonOptions
-- | File search result entry
data FileSearchResult = FileSearchResult
{ file_id :: Text
, text :: Text
, filename :: Text
, score :: Maybe Double
} deriving stock (Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | File search tool call output item
data FileSearchToolCall = FileSearchToolCall
{ id :: Text
, status :: Text
, queries :: Vector Text
, results :: Maybe (Vector FileSearchResult)
} deriving stock (Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Code interpreter tool call outputs
data CodeInterpreterOutput
= CodeInterpreterOutput_Logs{ logs :: Text }
| CodeInterpreterOutput_Image{ url :: Text }
deriving stock (Generic, Show)
codeInterpreterOutputOptions :: Options
codeInterpreterOutputOptions = aesonOptions
{ sumEncoding = TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
, tagSingleConstructors = True
, constructorTagModifier = stripPrefix "CodeInterpreterOutput_"
}
instance FromJSON CodeInterpreterOutput where
parseJSON = genericParseJSON codeInterpreterOutputOptions
instance ToJSON CodeInterpreterOutput where
toJSON = genericToJSON codeInterpreterOutputOptions
-- | Code interpreter tool call output item
data CodeInterpreterToolCall = CodeInterpreterToolCall
{ id :: Text
, status :: Text
, container_id :: Maybe Text
, code :: Maybe Text
, outputs :: Maybe (Vector CodeInterpreterOutput)
} deriving stock (Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Web search action sources
data WebSearchSource = WebSearchSource_URL{ url :: Text }
deriving stock (Generic, Show)
webSearchSourceOptions :: Options
webSearchSourceOptions = aesonOptions
{ sumEncoding = TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
, tagSingleConstructors = True
, constructorTagModifier = stripPrefix "WebSearchSource_"
}
instance FromJSON WebSearchSource where
parseJSON = genericParseJSON webSearchSourceOptions
instance ToJSON WebSearchSource where
toJSON = genericToJSON webSearchSourceOptions
-- | Web search action
data WebSearchAction
= WebSearchAction_Search
{ query :: Maybe Text
, sources :: Maybe (Vector WebSearchSource)
}
| WebSearchAction_Open_Page
{ url :: Maybe Text }
| WebSearchAction_Find
{ url :: Maybe Text
, pattern :: Maybe Text
}
deriving stock (Generic, Show)
webSearchActionOptions :: Options
webSearchActionOptions = aesonOptions
{ sumEncoding = TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
, tagSingleConstructors = True
, constructorTagModifier = stripPrefix "WebSearchAction_"
}
instance FromJSON WebSearchAction where
parseJSON = genericParseJSON webSearchActionOptions
instance ToJSON WebSearchAction where
toJSON = genericToJSON webSearchActionOptions
-- | Output text annotation
data Annotation
= Annotation_File_Citation
{ file_id :: Text
, index :: Natural
, filename :: Text
}
| Annotation_Url_Citation
{ url :: Text
, start_index :: Natural
, end_index :: Natural
, title :: Text
}
| Annotation_Container_File_Citation
{ container_id :: Text
, file_id :: Text
, start_index :: Natural
, end_index :: Natural
, filename :: Text
}
| Annotation_File_Path
{ file_id :: Text
, index :: Natural
}
deriving stock (Generic, Show)
annotationOptions :: Options
annotationOptions = aesonOptions
{ sumEncoding = TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
, tagSingleConstructors = True
, constructorTagModifier = stripPrefix "Annotation_"
}
instance FromJSON Annotation where
parseJSON = genericParseJSON annotationOptions
instance ToJSON Annotation where
toJSON = genericToJSON annotationOptions
-- | Reasoning summary part
data SummaryPart = Summary_Text{ text :: Text }
deriving stock (Eq, Generic, Show)
summaryPartOptions :: Options
summaryPartOptions = aesonOptions
{ sumEncoding = TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
, tagSingleConstructors = True
}
instance FromJSON SummaryPart where
parseJSON = genericParseJSON summaryPartOptions
instance ToJSON SummaryPart where
toJSON = genericToJSON summaryPartOptions
-- | Reasoning text part
data ReasoningText = Reasoning_Text{ text :: Text }
deriving stock (Eq, Generic, Show)
reasoningTextOptions :: Options
reasoningTextOptions = aesonOptions
{ sumEncoding = TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
, tagSingleConstructors = True
}
instance FromJSON ReasoningText where
parseJSON = genericParseJSON reasoningTextOptions
instance ToJSON ReasoningText where
toJSON = genericToJSON reasoningTextOptions
-- | Reasoning item produced by reasoning models
data ReasoningItem = ReasoningItem
{ id :: Text
, encrypted_content :: Maybe Text
, summary :: Maybe (Vector SummaryPart)
, content :: Maybe (Vector ReasoningText)
, status :: Maybe Text
} deriving stock (Eq, Generic, Show)
instance FromJSON ReasoningItem where
parseJSON = genericParseJSON aesonOptions
instance ToJSON ReasoningItem where
toJSON = genericToJSON aesonOptions
-- | Streaming events for \/v1/responses
data ResponseStreamEvent
= ResponseCreatedEvent
{ response :: ResponseObject
, sequence_number :: Natural
}
| ResponseInProgressEvent
{ response :: ResponseObject
, sequence_number :: Natural
}
| ResponseCompletedEvent
{ response :: ResponseObject
, sequence_number :: Natural
}
| ResponseFailedEvent
{ response :: ResponseObject
, sequence_number :: Natural
}
| ResponseOutputItemAddedEvent
{ output_index :: Natural
, item :: OutputItem
, sequence_number :: Natural
}
| ResponseOutputItemDoneEvent
{ output_index :: Natural
, sequence_number :: Natural
}
| ResponseContentPartAddedEvent
{ item_id :: Text
, output_index :: Natural
, content_index :: Natural
, part :: OutputContent
, sequence_number :: Natural
}
| ResponseContentPartDoneEvent
{ item_id :: Text
, output_index :: Natural
, content_index :: Natural
, part :: OutputContent
, sequence_number :: Natural
}
| ResponseTextDeltaEvent
{ item_id :: Text
, output_index :: Natural
, content_index :: Natural
, delta :: Text
, sequence_number :: Natural
}
| ResponseTextDoneEvent
{ item_id :: Text
, output_index :: Natural
, content_index :: Natural
, text :: Text
, sequence_number :: Natural
}
| ResponseOutputTextAnnotationAddedEvent
{ item_id :: Text
, output_index :: Natural
, content_index :: Natural
, annotation_index :: Natural
, annotation :: Annotation
, sequence_number :: Natural
}
| ResponseWebSearchCallInProgressEvent
{ output_index :: Natural
, item_id :: Text
, sequence_number :: Natural
}
| ResponseWebSearchCallSearchingEvent
{ output_index :: Natural
, item_id :: Text
, sequence_number :: Natural
}
| ResponseWebSearchCallCompletedEvent
{ output_index :: Natural
, item_id :: Text
, sequence_number :: Natural
}
| ResponseFileSearchCallInProgressEvent
{ output_index :: Natural
, item_id :: Text
, sequence_number :: Natural
}
| ResponseFileSearchCallSearchingEvent
{ output_index :: Natural
, item_id :: Text
, sequence_number :: Natural
}
| ResponseFileSearchCallCompletedEvent
{ output_index :: Natural
, item_id :: Text
, sequence_number :: Natural
}
| ResponseCodeInterpreterCallInProgressEvent
{ output_index :: Natural
, item_id :: Text
, sequence_number :: Natural
}
| ResponseCodeInterpreterCallInterpretingEvent
{ output_index :: Natural
, item_id :: Text
, sequence_number :: Natural
}
| ResponseCodeInterpreterCallCompletedEvent
{ output_index :: Natural
, item_id :: Text
, sequence_number :: Natural
}
| ResponseCodeInterpreterCallCodeDeltaEvent
{ output_index :: Natural
, item_id :: Text
, delta :: Text
, sequence_number :: Natural
}
| ResponseCodeInterpreterCallCodeDoneEvent
{ output_index :: Natural
, item_id :: Text
, code :: Text
, sequence_number :: Natural
}
| ErrorEvent
{ error_code :: Maybe Text
, error_message :: Text
, error_param :: Maybe Text
, error_sequence_number :: Natural
}
deriving stock (Generic, Show)
responseStreamEventOptions :: Options
responseStreamEventOptions = aesonOptions
{ sumEncoding = TaggedObject{ tagFieldName = "type", contentsFieldName = "" }
, tagSingleConstructors = True
, fieldLabelModifier = \s -> case s of
-- Strip "error_" prefix from ErrorEvent fields
"error_code" -> "code"
"error_message" -> "message"
"error_param" -> "param"
"error_sequence_number" -> "sequence_number"
-- Keep all other fields as-is
other -> other
, constructorTagModifier = \s -> case s of
"ResponseCreatedEvent" -> "response.created"
"ResponseInProgressEvent" -> "response.in_progress"
"ResponseCompletedEvent" -> "response.completed"
"ResponseFailedEvent" -> "response.failed"
"ResponseOutputItemAddedEvent" -> "response.output_item.added"
"ResponseOutputItemDoneEvent" -> "response.output_item.done"
"ResponseContentPartAddedEvent" -> "response.content_part.added"
"ResponseContentPartDoneEvent" -> "response.content_part.done"
"ResponseTextDeltaEvent" -> "response.output_text.delta"
"ResponseTextDoneEvent" -> "response.output_text.done"
"ResponseOutputTextAnnotationAddedEvent" -> "response.output_text.annotation.added"
"ResponseWebSearchCallInProgressEvent" -> "response.web_search_call.in_progress"
"ResponseWebSearchCallSearchingEvent" -> "response.web_search_call.searching"
"ResponseWebSearchCallCompletedEvent" -> "response.web_search_call.completed"
"ResponseFileSearchCallInProgressEvent" -> "response.file_search_call.in_progress"
"ResponseFileSearchCallSearchingEvent" -> "response.file_search_call.searching"
"ResponseFileSearchCallCompletedEvent" -> "response.file_search_call.completed"
"ResponseCodeInterpreterCallInProgressEvent" -> "response.code_interpreter_call.in_progress"
"ResponseCodeInterpreterCallInterpretingEvent" -> "response.code_interpreter_call.interpreting"
"ResponseCodeInterpreterCallCompletedEvent" -> "response.code_interpreter_call.completed"
"ResponseCodeInterpreterCallCodeDeltaEvent" -> "response.code_interpreter_call_code.delta"
"ResponseCodeInterpreterCallCodeDoneEvent" -> "response.code_interpreter_call_code.done"
"ErrorEvent" -> "error"
_ -> Prelude.error "Unknown ResponseStreamEvent constructor"
}
instance FromJSON ResponseStreamEvent where
parseJSON = genericParseJSON responseStreamEventOptions
instance ToJSON ResponseStreamEvent where
toJSON = genericToJSON responseStreamEventOptions
-- | Usage statistics for the response request
data ResponseUsage = ResponseUsage
{ input_tokens :: Natural
, input_tokens_details :: InputTokensDetails
, output_tokens :: Natural
, output_tokens_details :: OutputTokensDetails
, total_tokens :: Natural
} deriving stock (Generic, Show)
deriving anyclass (FromJSON, ToJSON)
data InputTokensDetails = InputTokensDetails
{ cached_tokens :: Natural
} deriving stock (Generic, Show)
deriving anyclass (FromJSON, ToJSON)
data OutputTokensDetails = OutputTokensDetails
{ reasoning_tokens :: Natural
} deriving stock (Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Response object
data ResponseObject = ResponseObject
{ id :: Text
, object :: Text
, created_at :: POSIXTime
, status :: Text
, error :: Maybe Value
, incomplete_details :: Maybe Value
, instructions :: Maybe Value
, model :: Model
, output :: Vector OutputItem
, parallel_tool_calls :: Bool
, previous_response_id :: Maybe Text
, reasoning :: Maybe Reasoning
, service_tier :: Maybe ServiceTier
, store :: Maybe Bool
, temperature :: Maybe Double
, tool_choice :: Maybe ToolChoice
, tools :: Maybe (Vector Tool)
, top_p :: Maybe Double
, truncation :: Maybe Text
, usage :: Maybe ResponseUsage
, user :: Maybe Text
, metadata :: Maybe (Map Text Text)
} deriving stock (Generic, Show)
instance FromJSON ResponseObject where
parseJSON (Aeson.Object o) =
genericParseJSON aesonOptions (Aeson.Object (unflattenResponseToolFields o))
parseJSON other = genericParseJSON aesonOptions other
instance ToJSON ResponseObject where
toJSON response@ResponseObject{ tools = mTools, tool_choice = mChoice } =
case genericToJSON aesonOptions response of
Aeson.Object o ->
Aeson.Object
(flattenResponseToolFields mTools mChoice o)
other -> other
-- | Request body for \/v1/responses
data CreateResponse = CreateResponse
{ model :: Model
, input :: Maybe Input
, include :: Maybe (Vector Text)
, reasoning :: Maybe Reasoning
, service_tier :: Maybe (AutoOr ServiceTier)
, parallel_tool_calls :: Maybe Bool
, store :: Maybe Bool
, instructions :: Maybe Text
, stream :: Maybe Bool
, stream_options :: Maybe Value
, metadata :: Maybe (Map Text Text)
, temperature :: Maybe Double
, top_p :: Maybe Double
, tools :: Maybe (Vector Tool)
, tool_choice :: Maybe ToolChoice
} deriving stock (Generic, Show)
instance FromJSON CreateResponse where
parseJSON (Aeson.Object o) =
genericParseJSON aesonOptions (Aeson.Object (unflattenResponseToolFields o))
parseJSON other = genericParseJSON aesonOptions other
instance ToJSON CreateResponse where
toJSON request@CreateResponse{ tools = mTools, tool_choice = mChoice } =
case genericToJSON aesonOptions request of
Aeson.Object o ->
Aeson.Object
(flattenResponseToolFields mTools mChoice o)
other -> other
-- | Default CreateResponse
_CreateResponse :: CreateResponse
_CreateResponse = CreateResponse
{ input = Nothing
, include = Nothing
, reasoning = Nothing
, service_tier = Nothing
, parallel_tool_calls = Nothing
, store = Nothing
, instructions = Nothing
, stream = Nothing
, stream_options = Nothing
, metadata = Nothing
, temperature = Nothing
, top_p = Nothing
, tools = Nothing
, tool_choice = Nothing
}
-- | Servant API for \/v1/responses
type API =
"responses"
:> ( ReqBody '[JSON] CreateResponse
:> Post '[JSON] ResponseObject
:<|> Capture "response_id" Text
:> Get '[JSON] ResponseObject
:<|> Capture "response_id" Text
:> "cancel"
:> Post '[JSON] ResponseObject
:<|> Capture "response_id" Text
:> "input_items"
:> Get '[JSON] (ListOf InputItem)
)