| POST | /v1/chat/completions |
|---|
# frozen_string_literal: true
# encoding: utf-8
require 'json'
require 'servicestack'
module ResponseFormat
TEXT = 'Text'
JSON_OBJECT = 'JsonObject'
end
module ToolType
FUNCTION = 'Function'
end
# @DataContract
class AiContent
include ServiceStack::DTO
# @DataMember(Name="type")
# @return [String]
attr_accessor :type
def self.properties
{
type: { name: 'type' },
}
end
end
#
# Annotations for the message, when applicable, as when using the web search tool.
#
# @DataContract
class UrlCitation
include ServiceStack::DTO
# @DataMember(Name="end_index")
# @return [Integer]
attr_accessor :end_index
# @DataMember(Name="start_index")
# @return [Integer]
attr_accessor :start_index
# @DataMember(Name="title")
# @return [String]
attr_accessor :title
# @DataMember(Name="url")
# @return [String]
attr_accessor :url
def self.properties
{
end_index: { name: 'end_index' },
start_index: { name: 'start_index' },
title: { name: 'title' },
url: { name: 'url' },
}
end
end
#
# Annotations for the message, when applicable, as when using the web search tool.
#
# @DataContract
class ChoiceAnnotation
include ServiceStack::DTO
# @DataMember(Name="type")
# @return [String]
attr_accessor :type
# @DataMember(Name="url_citation")
# @return [UrlCitation]
attr_accessor :url_citation
def self.properties
{
type: { name: 'type' },
url_citation: { name: 'url_citation', type: UrlCitation },
}
end
end
#
# If the audio output modality is requested, this object contains data about the audio response from the model.
#
# @DataContract
class ChoiceAudio
include ServiceStack::DTO
# @DataMember(Name="data")
# @return [String]
attr_accessor :data
# @DataMember(Name="expires_at")
# @return [Integer]
attr_accessor :expires_at
# @DataMember(Name="id")
# @return [String]
attr_accessor :id
# @DataMember(Name="transcript")
# @return [String]
attr_accessor :transcript
def self.properties
{
data: { name: 'data' },
expires_at: { name: 'expires_at' },
id: { name: 'id' },
transcript: { name: 'transcript' },
}
end
end
#
# The function that the model called.
#
# @DataContract
class ToolFunction
include ServiceStack::DTO
# @DataMember(Name="name")
# @return [String]
attr_accessor :name
# @DataMember(Name="arguments")
# @return [String]
attr_accessor :arguments
def self.properties
{
name: { name: 'name' },
arguments: { name: 'arguments' },
}
end
end
#
# The tool calls generated by the model, such as function calls.
#
# @DataContract
class ToolCall
include ServiceStack::DTO
# @DataMember(Name="id")
# @return [String]
attr_accessor :id
# @DataMember(Name="type")
# @return [String]
attr_accessor :type
# @DataMember(Name="function")
# @return [ToolFunction]
attr_accessor :function
def self.properties
{
id: { name: 'id' },
type: { name: 'type' },
function: { name: 'function', type: ToolFunction },
}
end
end
# @DataContract
class ChoiceMessage
include ServiceStack::DTO
# @DataMember(Name="content")
# @return [String]
attr_accessor :content
# @DataMember(Name="refusal")
# @return [String]
attr_accessor :refusal
# @DataMember(Name="reasoning")
# @return [String]
attr_accessor :reasoning
# @DataMember(Name="reasoning_content")
# @return [String]
attr_accessor :reasoning_content
# @DataMember(Name="thinking")
# @return [String]
attr_accessor :thinking
# @DataMember(Name="role")
# @return [String]
attr_accessor :role
# @DataMember(Name="timestamp")
# @return [Integer]
attr_accessor :timestamp
# @DataMember(Name="tool_call_id")
# @return [String]
attr_accessor :tool_call_id
# @DataMember(Name="images")
# @return [List]
attr_accessor :images
# @DataMember(Name="audios")
# @return [List]
attr_accessor :audios
# @DataMember(Name="files")
# @return [List]
attr_accessor :files
# @DataMember(Name="annotations")
# @return [List]
attr_accessor :annotations
# @DataMember(Name="audio")
# @return [ChoiceAudio]
attr_accessor :audio
# @DataMember(Name="tool_calls")
# @return [List]
attr_accessor :tool_calls
def self.properties
{
content: { name: 'content' },
refusal: { name: 'refusal' },
reasoning: { name: 'reasoning' },
reasoning_content: { name: 'reasoning_content' },
thinking: { name: 'thinking' },
role: { name: 'role' },
timestamp: { name: 'timestamp' },
tool_call_id: { name: 'tool_call_id' },
images: { name: 'images', type: [AiContent] },
audios: { name: 'audios', type: [AiContent] },
files: { name: 'files', type: [AiContent] },
annotations: { name: 'annotations', type: [ChoiceAnnotation] },
audio: { name: 'audio', type: ChoiceAudio },
tool_calls: { name: 'tool_calls', type: [ToolCall] },
}
end
end
#
# A list of message content tokens with log probability information.
#
# @DataContract
class LogprobItem
include ServiceStack::DTO
# @DataMember(Name="token")
# @return [String]
attr_accessor :token
# @DataMember(Name="logprob")
# @return [Float]
attr_accessor :logprob
# @DataMember(Name="bytes")
# @return [String]
attr_accessor :bytes
# @DataMember(Name="top_logprobs")
# @return [List]
attr_accessor :top_logprobs
def self.properties
{
token: { name: 'token' },
logprob: { name: 'logprob' },
bytes: { name: 'bytes' },
top_logprobs: { name: 'top_logprobs', type: [LogprobItem] },
}
end
end
#
# Log probability information for the choice.
#
# @DataContract
class Logprobs
include ServiceStack::DTO
# @DataMember(Name="content")
# @return [List]
attr_accessor :content
def self.properties
{
content: { name: 'content', type: [LogprobItem] },
}
end
end
# @DataContract
class Choice
include ServiceStack::DTO
# @DataMember(Name="finish_reason")
# @return [String]
attr_accessor :finish_reason
# @DataMember(Name="index")
# @return [Integer]
attr_accessor :index
# @DataMember(Name="message")
# @return [ChoiceMessage]
attr_accessor :message
# @DataMember(Name="logprobs")
# @return [Logprobs]
attr_accessor :logprobs
def self.properties
{
finish_reason: { name: 'finish_reason' },
index: { name: 'index' },
message: { name: 'message', type: ChoiceMessage },
logprobs: { name: 'logprobs', type: Logprobs },
}
end
end
#
# Usage statistics for the completion request.
#
# @DataContract
class AiCompletionUsage
include ServiceStack::DTO
# @DataMember(Name="accepted_prediction_tokens")
# @return [Integer]
attr_accessor :accepted_prediction_tokens
# @DataMember(Name="audio_tokens")
# @return [Integer]
attr_accessor :audio_tokens
# @DataMember(Name="reasoning_tokens")
# @return [Integer]
attr_accessor :reasoning_tokens
# @DataMember(Name="rejected_prediction_tokens")
# @return [Integer]
attr_accessor :rejected_prediction_tokens
def self.properties
{
accepted_prediction_tokens: { name: 'accepted_prediction_tokens' },
audio_tokens: { name: 'audio_tokens' },
reasoning_tokens: { name: 'reasoning_tokens' },
rejected_prediction_tokens: { name: 'rejected_prediction_tokens' },
}
end
end
#
# Breakdown of tokens used in the prompt.
#
# @DataContract
class AiPromptUsage
include ServiceStack::DTO
# @DataMember(Name="accepted_prediction_tokens")
# @return [Integer]
attr_accessor :accepted_prediction_tokens
# @DataMember(Name="audio_tokens")
# @return [Integer]
attr_accessor :audio_tokens
# @DataMember(Name="cached_tokens")
# @return [Integer]
attr_accessor :cached_tokens
def self.properties
{
accepted_prediction_tokens: { name: 'accepted_prediction_tokens' },
audio_tokens: { name: 'audio_tokens' },
cached_tokens: { name: 'cached_tokens' },
}
end
end
#
# Usage statistics for the completion request.
#
# @DataContract
class AiUsage
include ServiceStack::DTO
# @DataMember(Name="completion_tokens")
# @return [Integer]
attr_accessor :completion_tokens
# @DataMember(Name="prompt_tokens")
# @return [Integer]
attr_accessor :prompt_tokens
# @DataMember(Name="total_tokens")
# @return [Integer]
attr_accessor :total_tokens
# @DataMember(Name="completion_tokens_details")
# @return [AiCompletionUsage]
attr_accessor :completion_tokens_details
# @DataMember(Name="prompt_tokens_details")
# @return [AiPromptUsage]
attr_accessor :prompt_tokens_details
# @DataMember(Name="duration")
# @return [Integer]
attr_accessor :duration
def self.properties
{
completion_tokens: { name: 'completion_tokens' },
prompt_tokens: { name: 'prompt_tokens' },
total_tokens: { name: 'total_tokens' },
completion_tokens_details: { name: 'completion_tokens_details', type: AiCompletionUsage },
prompt_tokens_details: { name: 'prompt_tokens_details', type: AiPromptUsage },
duration: { name: 'duration' },
}
end
end
# @DataContract
class ChatResponse
include ServiceStack::DTO
# @DataMember(Name="id")
# @return [String]
attr_accessor :id
# @DataMember(Name="choices")
# @return [List]
attr_accessor :choices
# @DataMember(Name="created")
# @return [Integer]
attr_accessor :created
# @DataMember(Name="model")
# @return [String]
attr_accessor :model
# @DataMember(Name="system_fingerprint")
# @return [String]
attr_accessor :system_fingerprint
# @DataMember(Name="object")
# @return [String]
attr_accessor :object
# @DataMember(Name="service_tier")
# @return [String]
attr_accessor :service_tier
# @DataMember(Name="usage")
# @return [AiUsage]
attr_accessor :usage
# @DataMember(Name="provider")
# @return [String]
attr_accessor :provider
# @DataMember(Name="cost")
# @return [Float]
attr_accessor :cost
# @DataMember(Name="tool_history")
# @return [List]
attr_accessor :tool_history
# @DataMember(Name="metadata")
# @return [Dictionary]
attr_accessor :metadata
# @DataMember(Name="responseStatus")
# @return [ServiceStack::ResponseStatus]
attr_accessor :response_status
def self.properties
{
id: { name: 'id' },
choices: { name: 'choices', type: [Choice] },
created: { name: 'created' },
model: { name: 'model' },
system_fingerprint: { name: 'system_fingerprint' },
object: { name: 'object' },
service_tier: { name: 'service_tier' },
usage: { name: 'usage', type: AiUsage },
provider: { name: 'provider' },
cost: { name: 'cost' },
tool_history: { name: 'tool_history', type: [ChoiceMessage] },
metadata: { name: 'metadata' },
response_status: { name: 'responseStatus', type: ServiceStack::ResponseStatus },
}
end
end
#
# A list of messages comprising the conversation so far.
#
# @DataContract
class AiMessage
include ServiceStack::DTO
# @DataMember(Name="content")
# @return [List]
attr_accessor :content
# @DataMember(Name="role")
# @return [String]
attr_accessor :role
# @DataMember(Name="name")
# @return [String]
attr_accessor :name
# @DataMember(Name="tool_calls")
# @return [List]
attr_accessor :tool_calls
# @DataMember(Name="tool_call_id")
# @return [String]
attr_accessor :tool_call_id
# @DataMember(Name="reasoning")
# @return [String]
attr_accessor :reasoning
# @DataMember(Name="reasoning_content")
# @return [String]
attr_accessor :reasoning_content
# @DataMember(Name="timestamp")
# @return [Integer]
attr_accessor :timestamp
# @DataMember(Name="images")
# @return [List]
attr_accessor :images
def self.properties
{
content: { name: 'content', type: [AiContent] },
role: { name: 'role' },
name: { name: 'name' },
tool_calls: { name: 'tool_calls', type: [ToolCall] },
tool_call_id: { name: 'tool_call_id' },
reasoning: { name: 'reasoning' },
reasoning_content: { name: 'reasoning_content' },
timestamp: { name: 'timestamp' },
images: { name: 'images', type: [AiContent] },
}
end
end
#
# Parameters for audio output. Required when audio output is requested with modalities: [audio]
#
# @DataContract
class AiChatAudio
include ServiceStack::DTO
# @DataMember(Name="format")
# @return [String]
attr_accessor :format
# @DataMember(Name="voice")
# @return [String]
attr_accessor :voice
def self.properties
{
format: { name: 'format' },
voice: { name: 'voice' },
}
end
end
# @DataContract
class AiResponseFormat
include ServiceStack::DTO
# @DataMember(Name="type")
# @return [ResponseFormat]
attr_accessor :type
def self.properties
{
type: { name: 'type' },
}
end
end
# @DataContract
class AiToolFunction
include ServiceStack::DTO
# @DataMember(Name="name")
# @return [String]
attr_accessor :name
# @DataMember(Name="description")
# @return [String]
attr_accessor :description
# @DataMember(Name="parameters")
# @return [Dictionary]
attr_accessor :parameters
def self.properties
{
name: { name: 'name' },
description: { name: 'description' },
parameters: { name: 'parameters' },
}
end
end
# @DataContract
class Tool
include ServiceStack::DTO
# @DataMember(Name="type")
# @return [ToolType]
attr_accessor :type
# @DataMember(Name="function")
# @return [AiToolFunction]
attr_accessor :function
def self.properties
{
type: { name: 'type' },
function: { name: 'function', type: AiToolFunction },
}
end
end
#
# Chat Completions API (OpenAI-Compatible)
#
# @DataContract
class ChatCompletion
include ServiceStack::DTO
# @DataMember(Name="messages")
# @return [List]
attr_accessor :messages
# @DataMember(Name="model")
# @return [String]
attr_accessor :model
# @DataMember(Name="audio")
# @return [AiChatAudio]
attr_accessor :audio
# @DataMember(Name="logit_bias")
# @return [Dictionary]
attr_accessor :logit_bias
# @DataMember(Name="metadata")
# @return [Dictionary]
attr_accessor :metadata
# @DataMember(Name="reasoning_effort")
# @return [String]
attr_accessor :reasoning_effort
# @DataMember(Name="response_format")
# @return [AiResponseFormat]
attr_accessor :response_format
# @DataMember(Name="service_tier")
# @return [String]
attr_accessor :service_tier
# @DataMember(Name="safety_identifier")
# @return [String]
attr_accessor :safety_identifier
# @DataMember(Name="stop")
# @return [List]
attr_accessor :stop
# @DataMember(Name="modalities")
# @return [List]
attr_accessor :modalities
# @DataMember(Name="prompt_cache_key")
# @return [String]
attr_accessor :prompt_cache_key
# @DataMember(Name="tools")
# @return [List]
attr_accessor :tools
# @DataMember(Name="verbosity")
# @return [String]
attr_accessor :verbosity
# @DataMember(Name="temperature")
# @return [Float]
attr_accessor :temperature
# @DataMember(Name="max_completion_tokens")
# @return [Integer]
attr_accessor :max_completion_tokens
# @DataMember(Name="top_logprobs")
# @return [Integer]
attr_accessor :top_logprobs
# @DataMember(Name="top_p")
# @return [Float]
attr_accessor :top_p
# @DataMember(Name="frequency_penalty")
# @return [Float]
attr_accessor :frequency_penalty
# @DataMember(Name="presence_penalty")
# @return [Float]
attr_accessor :presence_penalty
# @DataMember(Name="seed")
# @return [Integer]
attr_accessor :seed
# @DataMember(Name="n")
# @return [Integer]
attr_accessor :n
# @DataMember(Name="store")
# @return [TrueClass]
attr_accessor :store
# @DataMember(Name="logprobs")
# @return [TrueClass]
attr_accessor :logprobs
# @DataMember(Name="parallel_tool_calls")
# @return [TrueClass]
attr_accessor :parallel_tool_calls
# @DataMember(Name="enable_thinking")
# @return [TrueClass]
attr_accessor :enable_thinking
# @DataMember(Name="stream")
# @return [TrueClass]
attr_accessor :stream
def self.properties
{
messages: { name: 'messages', type: [AiMessage] },
model: { name: 'model' },
audio: { name: 'audio', type: AiChatAudio },
logit_bias: { name: 'logit_bias' },
metadata: { name: 'metadata' },
reasoning_effort: { name: 'reasoning_effort' },
response_format: { name: 'response_format', type: AiResponseFormat },
service_tier: { name: 'service_tier' },
safety_identifier: { name: 'safety_identifier' },
stop: { name: 'stop' },
modalities: { name: 'modalities' },
prompt_cache_key: { name: 'prompt_cache_key' },
tools: { name: 'tools', type: [Tool] },
verbosity: { name: 'verbosity' },
temperature: { name: 'temperature' },
max_completion_tokens: { name: 'max_completion_tokens' },
top_logprobs: { name: 'top_logprobs' },
top_p: { name: 'top_p' },
frequency_penalty: { name: 'frequency_penalty' },
presence_penalty: { name: 'presence_penalty' },
seed: { name: 'seed' },
n: { name: 'n' },
store: { name: 'store' },
logprobs: { name: 'logprobs' },
parallel_tool_calls: { name: 'parallel_tool_calls' },
enable_thinking: { name: 'enable_thinking' },
stream: { name: 'stream' },
}
end
def response_type() = ChatResponse
def get_type_name() = 'ChatCompletion'
end
To override the Content-type in your clients, use the HTTP Accept Header, append the .xml suffix or ?format=xml
The following are sample HTTP requests and responses. The placeholders shown need to be replaced with actual values.
POST /v1/chat/completions HTTP/1.1
Host: blazor-vue.web-templates.io
Accept: application/xml
Content-Type: application/xml
Content-Length: length
<ChatCompletion xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ServiceStack.AI">
<audio>
<format>String</format>
<voice>String</voice>
</audio>
<enable_thinking>false</enable_thinking>
<frequency_penalty>0</frequency_penalty>
<logit_bias xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:KeyValueOfintint>
<d2p1:Key>0</d2p1:Key>
<d2p1:Value>0</d2p1:Value>
</d2p1:KeyValueOfintint>
</logit_bias>
<logprobs>false</logprobs>
<max_completion_tokens>0</max_completion_tokens>
<messages>
<AiMessage>
<content>
<AiContent i:nil="true" />
</content>
<images>
<AiContent i:nil="true" />
</images>
<name>String</name>
<reasoning>String</reasoning>
<reasoning_content>String</reasoning_content>
<role>String</role>
<timestamp>0</timestamp>
<tool_call_id>String</tool_call_id>
<tool_calls>
<ToolCall>
<function>
<arguments>String</arguments>
<name>String</name>
</function>
<id>String</id>
<type>String</type>
</ToolCall>
</tool_calls>
</AiMessage>
</messages>
<metadata xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:KeyValueOfstringstring>
<d2p1:Key>String</d2p1:Key>
<d2p1:Value>String</d2p1:Value>
</d2p1:KeyValueOfstringstring>
</metadata>
<modalities xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:string>String</d2p1:string>
</modalities>
<model>String</model>
<n>0</n>
<parallel_tool_calls>false</parallel_tool_calls>
<presence_penalty>0</presence_penalty>
<prompt_cache_key>String</prompt_cache_key>
<reasoning_effort>String</reasoning_effort>
<response_format>
<type>Text</type>
</response_format>
<safety_identifier>String</safety_identifier>
<seed>0</seed>
<service_tier>String</service_tier>
<stop xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:string>String</d2p1:string>
</stop>
<store>false</store>
<stream>false</stream>
<temperature>0</temperature>
<tools>
<Tool>
<function>
<description>String</description>
<name>String</name>
<parameters xmlns:d5p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d5p1:KeyValueOfstringanyType>
<d5p1:Key>String</d5p1:Key>
<d5p1:Value />
</d5p1:KeyValueOfstringanyType>
</parameters>
</function>
<type>Function</type>
</Tool>
</tools>
<top_logprobs>0</top_logprobs>
<top_p>0</top_p>
<verbosity>String</verbosity>
</ChatCompletion>
HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: length
<ChatResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ServiceStack.AI">
<choices>
<Choice>
<finish_reason>String</finish_reason>
<index>0</index>
<logprobs>
<content>
<LogprobItem>
<bytes>AA==</bytes>
<logprob>0</logprob>
<token>String</token>
<top_logprobs>
<LogprobItem>
<bytes>AA==</bytes>
<logprob>0</logprob>
<token>String</token>
<top_logprobs>
<LogprobItem>
<bytes>AA==</bytes>
<logprob>0</logprob>
<token>String</token>
<top_logprobs i:nil="true" />
</LogprobItem>
</top_logprobs>
</LogprobItem>
</top_logprobs>
</LogprobItem>
</content>
</logprobs>
<message>
<annotations>
<ChoiceAnnotation>
<type>String</type>
<url_citation>
<end_index>0</end_index>
<start_index>0</start_index>
<title>String</title>
<url>String</url>
</url_citation>
</ChoiceAnnotation>
</annotations>
<audio>
<data>String</data>
<expires_at>0</expires_at>
<id>String</id>
<transcript>String</transcript>
</audio>
<audios>
<AiContent i:nil="true" />
</audios>
<content>String</content>
<files>
<AiContent i:nil="true" />
</files>
<images>
<AiContent i:nil="true" />
</images>
<reasoning>String</reasoning>
<reasoning_content>String</reasoning_content>
<refusal>String</refusal>
<role>String</role>
<thinking>String</thinking>
<timestamp>0</timestamp>
<tool_call_id>String</tool_call_id>
<tool_calls>
<ToolCall>
<function>
<arguments>String</arguments>
<name>String</name>
</function>
<id>String</id>
<type>String</type>
</ToolCall>
</tool_calls>
</message>
</Choice>
</choices>
<cost>0</cost>
<created>0</created>
<id>String</id>
<metadata xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:KeyValueOfstringstring>
<d2p1:Key>String</d2p1:Key>
<d2p1:Value>String</d2p1:Value>
</d2p1:KeyValueOfstringstring>
</metadata>
<model>String</model>
<object>String</object>
<provider>String</provider>
<responseStatus xmlns:d2p1="http://schemas.servicestack.net/types">
<d2p1:ErrorCode>String</d2p1:ErrorCode>
<d2p1:Message>String</d2p1:Message>
<d2p1:StackTrace>String</d2p1:StackTrace>
<d2p1:Errors>
<d2p1:ResponseError>
<d2p1:ErrorCode>String</d2p1:ErrorCode>
<d2p1:FieldName>String</d2p1:FieldName>
<d2p1:Message>String</d2p1:Message>
<d2p1:Meta xmlns:d5p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d5p1:KeyValueOfstringstring>
<d5p1:Key>String</d5p1:Key>
<d5p1:Value>String</d5p1:Value>
</d5p1:KeyValueOfstringstring>
</d2p1:Meta>
</d2p1:ResponseError>
</d2p1:Errors>
<d2p1:Meta xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d3p1:KeyValueOfstringstring>
<d3p1:Key>String</d3p1:Key>
<d3p1:Value>String</d3p1:Value>
</d3p1:KeyValueOfstringstring>
</d2p1:Meta>
</responseStatus>
<service_tier>String</service_tier>
<system_fingerprint>String</system_fingerprint>
<tool_history>
<ChoiceMessage>
<annotations>
<ChoiceAnnotation>
<type>String</type>
<url_citation>
<end_index>0</end_index>
<start_index>0</start_index>
<title>String</title>
<url>String</url>
</url_citation>
</ChoiceAnnotation>
</annotations>
<audio>
<data>String</data>
<expires_at>0</expires_at>
<id>String</id>
<transcript>String</transcript>
</audio>
<audios>
<AiContent i:nil="true" />
</audios>
<content>String</content>
<files>
<AiContent i:nil="true" />
</files>
<images>
<AiContent i:nil="true" />
</images>
<reasoning>String</reasoning>
<reasoning_content>String</reasoning_content>
<refusal>String</refusal>
<role>String</role>
<thinking>String</thinking>
<timestamp>0</timestamp>
<tool_call_id>String</tool_call_id>
<tool_calls>
<ToolCall>
<function>
<arguments>String</arguments>
<name>String</name>
</function>
<id>String</id>
<type>String</type>
</ToolCall>
</tool_calls>
</ChoiceMessage>
</tool_history>
<usage>
<completion_tokens>0</completion_tokens>
<completion_tokens_details>
<accepted_prediction_tokens>0</accepted_prediction_tokens>
<audio_tokens>0</audio_tokens>
<reasoning_tokens>0</reasoning_tokens>
<rejected_prediction_tokens>0</rejected_prediction_tokens>
</completion_tokens_details>
<duration>0</duration>
<prompt_tokens>0</prompt_tokens>
<prompt_tokens_details>
<accepted_prediction_tokens>0</accepted_prediction_tokens>
<audio_tokens>0</audio_tokens>
<cached_tokens>0</cached_tokens>
</prompt_tokens_details>
<total_tokens>0</total_tokens>
</usage>
</ChatResponse>