MyApp

<back to all web services

ChatCompletion

AI

Chat Completions API (OpenAI-Compatible)

The following routes are available for this service:
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

Ruby ChatCompletion DTOs

To override the Content-type in your clients, use the HTTP Accept Header, append the .xml suffix or ?format=xml

HTTP + 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>