Chatoyant_provider.XaiSourceStandalone xAI API mirror.
xAI shares OpenAI-compatible wire formats for some endpoints, but this module owns xAI semantics directly: model capability quirks, web search, cost ticks, Imagine image/video endpoints, and xAI-specific errors.
type message = {message_role : role;message_content : string option;message_name : string option;message_tool_call_id : string option;message_tool_calls : Provider.tool_call list;}type tool = | Function of Openai.function_tool| Web_search| Raw_tool of Chatoyant_runtime.Json.ttype tool_choice = | Auto| None_| Required| Tool of string| Raw_tool_choice of Chatoyant_runtime.Json.ttype response_format = | Text| Json_object| Json_schema of {schema_name : string;schema_description : string option;schema_value : Chatoyant_runtime.Json.t;schema_strict : bool;}type chat_request = {chat_model : string;chat_messages : message list;chat_stream : bool;chat_temperature : float option;chat_max_tokens : int option;chat_top_p : float option;chat_stop : string list;chat_user : string option;chat_seed : int option;chat_logprobs : bool option;chat_top_logprobs : int option;chat_n : int option;chat_response_format : response_format option;chat_tools : tool list;chat_tool_choice : tool_choice option;chat_parallel_tool_calls : bool option;chat_extra : (string * Chatoyant_runtime.Json.t) list;}Chat Completions request body for xAI's /v1/chat/completions endpoint. Optional fields intentionally stay explicit instead of being inherited from OpenAI, because xAI evolves capabilities and unsupported parameters on its own schedule. chat_extra is the forward-compatible escape hatch for freshly shipped provider fields.
type chat_response = {response_id : string option;response_model : string option;response_content : string;response_reasoning_content : string;response_usage : Chatoyant_tokens.Cost.usage;response_raw : Chatoyant_runtime.Json.t;}Decoded chat response. response_raw preserves the complete provider JSON so parity tests can inspect unknown fields without weakening the typed normalized surface.
type responses_input = | Responses_text of string| Responses_items of Chatoyant_runtime.Json.t listtype responses_request = {responses_model : string;responses_input : responses_input;responses_instructions : string option;responses_previous_response_id : string option;responses_store : bool option;responses_stream : bool;responses_temperature : float option;responses_top_p : float option;responses_max_output_tokens : int option;responses_tools : tool list;responses_tool_choice : tool_choice option;responses_text_format : response_format option;responses_parallel_tool_calls : bool option;responses_top_logprobs : int option;responses_truncation : string option;responses_extra : (string * Chatoyant_runtime.Json.t) list;}Preferred xAI Responses API request body for /v1/responses.
type responses_response = {responses_id : string option;responses_model : string option;responses_status : response_status;responses_output_text : string;responses_reasoning_text : string;responses_usage : Chatoyant_tokens.Cost.usage;responses_raw : Chatoyant_runtime.Json.t;}Decoded Responses API object, including message output text and reasoning summary text when xAI returns it.
type delete_response = {deleted_id : string option;deleted : bool;deleted_raw : Chatoyant_runtime.Json.t;}type model = {model_id : string option;model_object : string option;model_owned_by : string option;model_created : int option;model_raw : Chatoyant_runtime.Json.t;}type form_part = {form_name : string;form_filename : string option;form_content_type : string option;form_body : string;}type file_upload = {file_filename : string;file_content_type : string option;file_body : string;file_purpose : string;file_expires_after : int option;}type file_object = {file_id : string option;file_object : string option;file_bytes : int option;file_filename : string option;file_purpose : string option;file_created_at : int option;file_expires_at : string option;file_raw : Chatoyant_runtime.Json.t;}type file_list = {files : file_object list;pagination_token : string option;raw : Chatoyant_runtime.Json.t;}type file_delete = {deleted_file_id : string option;deleted : bool;raw : Chatoyant_runtime.Json.t;}type batch = {batch_id : string option;batch_create_api_key_id : string option;batch_create_time : string option;batch_name : string option;batch_state : Chatoyant_runtime.Json.t option;batch_raw : Chatoyant_runtime.Json.t;}type batch_list = {batches : batch list;pagination_token : string option;raw : Chatoyant_runtime.Json.t;}type batch_request_metadata_list = {batch_request_metadata : Chatoyant_runtime.Json.t list;pagination_token : string option;raw : Chatoyant_runtime.Json.t;}type api_error = {error_type : string option;error_message : string;error_raw : Chatoyant_runtime.Json.t option;}type tts_request = {tts_text : string;tts_voice_id : string option;tts_language : string;tts_output_format : tts_output_format option;tts_speed : float option;tts_optimize_streaming_latency : int option;tts_text_normalization : bool option;tts_with_timestamps : bool option;tts_extra : (string * Chatoyant_runtime.Json.t) list;}REST text-to-speech request for /v1/tts. The normal response body is raw audio bytes; when tts_with_timestamps is true, xAI returns a JSON envelope as the body.
type stt_request = {stt_file : upload_part option;stt_url : string option;stt_audio_format : string option;stt_sample_rate : int option;stt_language : string option;stt_format : bool option;stt_multichannel : bool option;stt_channels : int option;stt_diarize : bool option;stt_keyterms : string list;stt_filler_words : bool option;stt_extra : (string * string) list;}REST speech-to-text request for /v1/stt. Either stt_file or stt_url must be supplied. When stt_file is present it is encoded last, matching xAI's multipart requirement.
type stt_word = {word_text : string option;word_start : float option;word_end : float option;word_speaker : int option;word_raw : Chatoyant_runtime.Json.t;}type stt_channel = {channel_index : int option;channel_text : string option;channel_words : stt_word list;channel_raw : Chatoyant_runtime.Json.t;}type stt_response = {stt_text : string option;stt_language : string option;stt_duration : float option;stt_words : stt_word list;stt_channels : stt_channel list;stt_raw : Chatoyant_runtime.Json.t;}type voice = {voice_id : string option;voice_name : string option;voice_description : string option;voice_gender : string option;voice_accent : string option;voice_age : string option;voice_language : string option;voice_use_case : string option;voice_tone : string option;voice_created_at : string option;voice_raw : Chatoyant_runtime.Json.t;}type voice_list = {voices : voice list;voices_pagination_token : string option;voices_raw : Chatoyant_runtime.Json.t;}type custom_voice_request = {custom_voice_file : upload_part;custom_voice_name : string option;custom_voice_description : string option;custom_voice_gender : string option;custom_voice_accent : string option;custom_voice_age : string option;custom_voice_language : string option;custom_voice_use_case : string option;custom_voice_tone : string option;custom_voice_extra : (string * string) list;}type custom_voice_update = {custom_voice_update_name : string option;custom_voice_update_description : string option;custom_voice_update_gender : string option;custom_voice_update_accent : string option;custom_voice_update_age : string option;custom_voice_update_language : string option;custom_voice_update_use_case : string option;custom_voice_update_tone : string option;custom_voice_update_extra : (string * Chatoyant_runtime.Json.t) list;}type voice_delete = {deleted_voice_id : string option;voice_deleted : bool;voice_delete_raw : Chatoyant_runtime.Json.t;}type realtime_client_secret_request = {realtime_client_secret_expires_after_seconds : int option;realtime_client_secret_extra : (string * Chatoyant_runtime.Json.t) list;}Ephemeral token request for browser/mobile WebSocket clients.
type realtime_client_secret = {realtime_client_secret_value : string option;realtime_client_secret_expires_at : int option;realtime_client_secret_raw : Chatoyant_runtime.Json.t;}Ephemeral Realtime client secret returned by xAI.
type websocket_config = {websocket_api_key : string;websocket_url : string;websocket_timeout_ms : int option;websocket_headers : (string * string) list;websocket_protocols : string list;}xAI WebSocket config for voice-agent realtime and streaming TTS.
type responses_stream_event = | Response_created of responses_response| Response_in_progress of responses_response| Response_completed of responses_response| Response_failed of responses_response| Response_incomplete of responses_response| Response_output_text_delta of {}| Response_output_text_done of {}| Response_reasoning_summary_text_delta of {}| Response_function_call_arguments_delta of {}| Response_function_call_arguments_done of {}| Response_refusal_delta of string| Response_error of api_error| Response_raw_event of {event_type : string option;raw : Chatoyant_runtime.Json.t;}xAI Responses SSE events. The provider currently follows OpenAI's event names for /v1/responses, while this type remains owned by the xAI module so downstream explicit-provider code never depends on OpenAI internals.
type image_request = {image_model : string option;image_prompt : string;image_n : int option;image_response_format : image_response_format option;image_aspect_ratio : string option;image_resolution : string option;image_user : string option;image_extra : (string * Chatoyant_runtime.Json.t) list;}Image generation request for Grok Imagine image models.
type image_edit_request = {edit_model : string option;edit_prompt : string;edit_images : image_edit_source list;edit_n : int option;edit_response_format : image_response_format option;edit_aspect_ratio : string option;edit_resolution : string option;edit_extra : (string * Chatoyant_runtime.Json.t) list;}Image edit request. The source list is encoded as the singular xAI image field, either as one object or an array of reference images.
type image_response = {image_created : int option;image_model : string option;image_data : image_data list;image_raw : Chatoyant_runtime.Json.t;}type video_request = {video_model : string option;video_prompt : string;video_duration : int option;video_aspect_ratio : string option;video_resolution : string option;video_image_url : string option;video_url : string option;video_extra : (string * Chatoyant_runtime.Json.t) list;}Async Imagine video generation/edit request. Poll the returned request id with Make_client.get_video_status.
type video_status_response = {status : video_status;video_url : string option;video_duration : int option;video_model : string option;raw : Chatoyant_runtime.Json.t;}type collection_request = {collection_name : string;collection_description : string option;collection_index_configuration : Chatoyant_runtime.Json.t option;collection_field_definitions : Chatoyant_runtime.Json.t list;collection_extra : (string * Chatoyant_runtime.Json.t) list;}type collection_update = {collection_update_name : string option;collection_update_description : string option;collection_update_index_configuration : Chatoyant_runtime.Json.t option;collection_update_field_definitions : Chatoyant_runtime.Json.t list;collection_update_extra : (string * Chatoyant_runtime.Json.t) list;}type collection = {collection_id : string option;collection_name : string option;collection_description : string option;collection_created_at : string option;collection_documents_count : int option;collection_index_configuration : Chatoyant_runtime.Json.t option;collection_field_definitions : Chatoyant_runtime.Json.t option;collection_raw : Chatoyant_runtime.Json.t;}type collection_list = {collections : collection list;collections_pagination_token : string option;collections_raw : Chatoyant_runtime.Json.t;}type collection_document = {document_file_metadata : Chatoyant_runtime.Json.t option;document_status : string option;document_error_message : string option;document_last_indexed_at : string option;document_fields : Chatoyant_runtime.Json.t option;document_raw : Chatoyant_runtime.Json.t;}type collection_document_list = {collection_documents : collection_document list;collection_documents_pagination_token : string option;collection_documents_raw : Chatoyant_runtime.Json.t;}type collection_delete = {collection_delete_id : string option;collection_deleted : bool;collection_delete_raw : Chatoyant_runtime.Json.t;}type collection_search_request = {collection_search_query : string;collection_search_limit : int option;collection_search_filter : string option;collection_search_extra : (string * Chatoyant_runtime.Json.t) list;}type collection_search_response = {collection_search_results : Chatoyant_runtime.Json.t list;collection_search_raw : Chatoyant_runtime.Json.t;}val realtime_client_secret_request_json :
realtime_client_secret_request ->
Chatoyant_runtime.Json.tBearer auth headers for xAI REST calls.
val streaming_tts_url :
?base_url:string ->
?language:string ->
?voice:string ->
?codec:string ->
?sample_rate:int ->
?bit_rate:int ->
?speed:float ->
?optimize_streaming_latency:int ->
?text_normalization:bool ->
?with_timestamps:bool ->
unit ->
stringval streaming_stt_url :
?base_url:string ->
?sample_rate:int ->
?encoding:string ->
?interim_results:bool ->
?endpointing:int ->
?language:string ->
?diarize:bool ->
?filler_words:bool ->
?multichannel:bool ->
?channels:int ->
?keyterms:string list ->
?smart_turn:float ->
?smart_turn_timeout:int ->
unit ->
stringval responses_stream_events_of_chunks :
string list ->
(responses_stream_event list, string) resultval batch_request_metadata_list_of_json :
Chatoyant_runtime.Json.t ->
batch_request_metadata_listDecode OpenAI-compatible SSE chunks while preserving xAI reasoning deltas and cost-tick usage when present.
val collection_search_response_of_json :
Chatoyant_runtime.Json.t ->
collection_search_responseRuntime-independent xAI client. Native OCaml, Node/Melange, browser, and tests supply the HTTP effect implementation; the provider logic never performs ambient IO.
xAI WebSocket helper for Voice Agent and streaming TTS endpoints.
module Make_provider
(Http : Chatoyant_runtime.Effect.HTTP)
(Config : sig ... end) :
Provider.CHATUnified chat adapter used by higher-level Chatoyant core flows.