1mod admin;
4mod audio;
5mod batches;
6mod beta;
7mod chat;
8mod common;
9mod containers;
10mod conversations;
11mod core;
12mod evals;
13mod files;
14mod fine_tuning;
15mod images;
16mod longtail;
17mod responses;
18mod skills;
19mod uploads;
20mod vector_stores;
21mod videos;
22mod webhooks;
23
24use std::collections::BTreeMap;
25
26use serde::{Deserialize, Serialize};
27use serde_json::Value;
28
29use crate::Client;
30use crate::error::{Error, Result};
31#[cfg(feature = "tool-runner")]
32use crate::helpers::ToolDefinition;
33use crate::json_payload::JsonPayload;
34
35pub use beta::{
36 BetaAssistant, BetaAssistantTool, BetaRealtimeSession, BetaRealtimeTranscriptionSession,
37 BetaThread, BetaThreadMessage, BetaThreadMessageContent, BetaThreadRun,
38 BetaThreadRunIncompleteDetails, BetaThreadRunLastError, BetaThreadRunRequiredAction,
39 BetaThreadRunRequiredActionFunction, BetaThreadRunRequiredActionFunctionToolCall,
40 BetaThreadRunRequiredActionSubmitToolOutputs, BetaThreadRunStep, BetaThreadRunStepDetails,
41 BetaThreadRunTool, BetaThreadRunUsage, BetaThreadToolResources, ChatKitConfiguration,
42 ChatKitRateLimits, ChatKitSession, ChatKitThread, ChatKitThreadContent, ChatKitThreadItem,
43 ChatKitThreadStatus, ChatKitWorkflow,
44};
45#[cfg(feature = "structured-output")]
46pub use chat::ChatCompletionParseRequestBuilder;
47pub use chat::{
48 AssistantStreamRequestBuilder, ChatCompletionCreateRequestBuilder, ChatCompletionStoreMessage,
49 ChatCompletionStreamRequestBuilder,
50};
51#[cfg(feature = "tool-runner")]
52pub use chat::{
53 ChatCompletionRunToolsRequestBuilder, ChatCompletionRunner, ChatCompletionStreamingRunner,
54 ChatCompletionToolResult,
55};
56pub use common::{
57 BytesRequestBuilder, JsonRequestBuilder, ListRequestBuilder, NoContentRequestBuilder,
58};
59pub(crate) use common::{
60 TypedJsonRequestState, encode_path_segment, metadata_is_empty, value_from,
61};
62pub use core::{
63 Completion, CompletionChoice, CompletionLogProbs, CompletionUsage,
64 CompletionUsageCompletionTokensDetails, CompletionUsagePromptTokensDetails,
65 ModerationCreateResponse, ModerationResult,
66};
67pub use fine_tuning::{
68 GraderModel, GraderModelCatalog, GraderRunErrors, GraderRunMetadata, GraderRunResponse,
69 GraderValidateResponse,
70};
71pub use longtail::{
72 AudioSpeechCreateParams, AudioSpeechRequestBuilder, AudioTranscription,
73 AudioTranscriptionRequestBuilder, AudioTranscriptionSegment, AudioTranscriptionSegmentId,
74 AudioTranscriptionWord, AudioTranslation, AudioTranslationRequestBuilder, Batch,
75 BatchCreateParams, BatchCreateRequestBuilder, BatchError, BatchErrors, BatchRequestCounts,
76 BatchUsage, BatchUsageInputTokensDetails, BatchUsageOutputTokensDetails, Container,
77 ContainerCreateParams, ContainerExpiresAfter, ContainerFile, ContainerFileCreateParams,
78 Conversation, ConversationContentPart, ConversationCreateParams, ConversationInputItem,
79 ConversationItem, ConversationItemCreateParams, ConversationUpdateParams, Eval,
80 EvalCreateParams, EvalDataSourceConfig, EvalOutput, EvalOutputItem, EvalRun,
81 EvalRunCreateParams, EvalRunInput, EvalTestingCriterion, EvalUpdateParams,
82 FineTuningCheckpoint, FineTuningCheckpointPermission, FineTuningHyperparameterValue,
83 FineTuningJob, FineTuningJobCreateParams, FineTuningJobCreateRequestBuilder,
84 FineTuningJobError, FineTuningJobEvent, FineTuningJobHyperparameters, FineTuningJobIntegration,
85 FineTuningMetrics, FineTuningWandbIntegration, ImageData, ImageGenerateParams,
86 ImageGenerateRequestBuilder, ImageGenerationResponse, Skill, SkillCreateParams,
87 SkillUpdateParams, SkillVersion, SkillVersionContent, SkillVersionCreateParams, Video,
88 VideoCharacter, VideoCharacterCreateParams, VideoCreateParams,
89};
90#[cfg(feature = "realtime")]
91pub use responses::RealtimeSocketRequestBuilder;
92#[cfg(feature = "structured-output")]
93pub use responses::ResponseParseRequestBuilder;
94#[cfg(feature = "responses-ws")]
95pub use responses::ResponsesSocketRequestBuilder;
96pub use responses::{
97 RealtimeClientSecretCreateResponse, RealtimeSessionClientSecret, ResponseCreateRequestBuilder,
98 ResponseStreamRequestBuilder,
99};
100pub use uploads::UploadPart;
101pub use vector_stores::{
102 VectorStore, VectorStoreAttributeValue, VectorStoreAttributes, VectorStoreExpiresAfter,
103 VectorStoreFile, VectorStoreFileBatch, VectorStoreFileChunkingStrategy, VectorStoreFileContent,
104 VectorStoreFileCounts, VectorStoreFileLastError, VectorStoreMetadata, VectorStoreSearchContent,
105 VectorStoreSearchResponse, VectorStoreSearchResult, VectorStoreStaticFileChunkingStrategy,
106};
107
108macro_rules! json_payload_wrapper {
109 ($(#[$meta:meta])* $name:ident) => {
110 $(#[$meta])*
111 #[derive(Debug, Clone, Serialize, Deserialize)]
112 #[serde(transparent)]
113 pub struct $name(Value);
114
115 impl Default for $name {
116 fn default() -> Self {
117 Self(Value::Null)
118 }
119 }
120
121 impl From<Value> for $name {
122 fn from(value: Value) -> Self {
123 Self(value)
124 }
125 }
126
127 impl From<$name> for Value {
128 fn from(value: $name) -> Self {
129 value.0
130 }
131 }
132
133 impl $name {
134 pub fn as_raw(&self) -> &Value {
136 &self.0
137 }
138
139 pub fn into_raw(self) -> Value {
141 self.0
142 }
143
144 pub fn kind(&self) -> Option<&str> {
146 self.0.get("type").and_then(Value::as_str)
147 }
148 }
149 };
150}
151
152macro_rules! handle {
153 ($(#[$meta:meta])* $name:ident) => {
154 $(#[$meta])*
155 #[derive(Debug, Clone)]
156 pub struct $name {
157 client: Client,
158 }
159
160 impl $name {
161 pub(crate) fn new(client: Client) -> Self {
162 Self { client }
163 }
164 }
165 };
166}
167
168#[derive(Debug, Clone, Serialize, Deserialize, Default)]
170pub struct DeleteResponse {
171 pub id: Option<String>,
173 #[serde(default)]
175 pub deleted: bool,
176 pub object: Option<String>,
178 #[serde(flatten)]
180 pub extra: BTreeMap<String, Value>,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize, Default)]
185pub struct Model {
186 pub id: String,
188 #[serde(default)]
190 pub object: String,
191 pub owned_by: Option<String>,
193 #[serde(flatten)]
195 pub extra: BTreeMap<String, Value>,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize, Default)]
200pub struct FileObject {
201 pub id: String,
203 #[serde(default)]
205 pub object: String,
206 pub filename: Option<String>,
208 pub purpose: Option<String>,
210 pub bytes: Option<u64>,
212 #[serde(flatten)]
214 pub extra: BTreeMap<String, Value>,
215}
216
217#[derive(Debug, Clone, Serialize, Deserialize, Default)]
219pub struct UploadObject {
220 pub id: String,
222 #[serde(default)]
224 pub object: String,
225 pub status: Option<String>,
227 #[serde(flatten)]
229 pub extra: BTreeMap<String, Value>,
230}
231
232#[derive(Debug, Clone, Serialize, Deserialize, Default)]
234pub struct EmbeddingResponse {
235 #[serde(default)]
237 pub object: String,
238 #[serde(default)]
240 pub data: Vec<EmbeddingData>,
241 pub usage: Option<EmbeddingUsage>,
243 #[serde(flatten)]
245 pub extra: BTreeMap<String, Value>,
246}
247
248#[derive(Debug, Clone, Serialize, Deserialize, Default)]
250pub struct EmbeddingData {
251 #[serde(default)]
253 pub embedding: Vec<f64>,
254 pub index: Option<u32>,
256 #[serde(default)]
258 pub object: String,
259 #[serde(flatten)]
261 pub extra: BTreeMap<String, Value>,
262}
263
264#[derive(Debug, Clone, Serialize, Deserialize, Default)]
266pub struct EmbeddingUsage {
267 #[serde(default)]
269 pub prompt_tokens: u64,
270 #[serde(default)]
272 pub total_tokens: u64,
273 #[serde(flatten)]
275 pub extra: BTreeMap<String, Value>,
276}
277
278#[derive(Debug, Clone, Serialize, Deserialize, Default)]
280pub struct InputTokenCount {
281 pub total_tokens: u64,
283 #[serde(flatten)]
285 pub extra: BTreeMap<String, Value>,
286}
287
288json_payload_wrapper!(
289 ChatCompletionStoreContentPart
291);
292json_payload_wrapper!(
293 ChatReasoningDetail
295);
296json_payload_wrapper!(
297 ChatMessageContentPart
299);
300json_payload_wrapper!(
301 ChatToolChoice
303);
304json_payload_wrapper!(
305 ResponseInputPayload
307);
308json_payload_wrapper!(
309 ResponseInputItemPayload
311);
312json_payload_wrapper!(
313 RealtimeSessionPayload
315);
316json_payload_wrapper!(
317 ResponseOutputItemRaw
319);
320json_payload_wrapper!(
321 ResponseOutputContentPartRaw
323);
324
325#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
327#[serde(rename_all = "snake_case")]
328pub enum ChatToolChoiceMode {
329 None,
331 Auto,
333 Required,
335}
336
337impl From<ChatToolChoiceMode> for ChatToolChoice {
338 fn from(mode: ChatToolChoiceMode) -> Self {
339 let value = match mode {
340 ChatToolChoiceMode::None => Value::String("none".into()),
341 ChatToolChoiceMode::Auto => Value::String("auto".into()),
342 ChatToolChoiceMode::Required => Value::String("required".into()),
343 };
344 Self::from(value)
345 }
346}
347
348impl From<String> for ResponseInputPayload {
349 fn from(value: String) -> Self {
350 Self::from(Value::String(value))
351 }
352}
353
354impl From<&str> for ResponseInputPayload {
355 fn from(value: &str) -> Self {
356 Self::from(Value::String(value.into()))
357 }
358}
359
360impl From<Vec<ResponseInputItemPayload>> for ResponseInputPayload {
361 fn from(items: Vec<ResponseInputItemPayload>) -> Self {
362 Self::from(Value::Array(items.into_iter().map(Value::from).collect()))
363 }
364}
365
366impl ChatToolChoice {
367 pub fn none() -> Self {
369 ChatToolChoiceMode::None.into()
370 }
371
372 pub fn auto() -> Self {
374 ChatToolChoiceMode::Auto.into()
375 }
376
377 pub fn required() -> Self {
379 ChatToolChoiceMode::Required.into()
380 }
381
382 pub fn function(name: impl Into<String>) -> Self {
384 serde_json::json!({
385 "type": "function",
386 "function": {
387 "name": name.into(),
388 },
389 })
390 .into()
391 }
392
393 pub fn custom(name: impl Into<String>) -> Self {
395 serde_json::json!({
396 "type": "custom",
397 "custom": {
398 "name": name.into(),
399 },
400 })
401 .into()
402 }
403
404 pub fn mode_name(&self) -> Option<&str> {
406 self.0.as_str()
407 }
408}
409
410#[derive(Debug, Clone, Serialize, Deserialize, Default)]
412pub struct ChatCompletionFunctionCall {
413 pub name: String,
415 #[serde(default)]
417 pub arguments: String,
418}
419
420#[derive(Debug, Clone, Serialize, Deserialize, Default)]
422pub struct ChatCompletionToolCall {
423 pub id: String,
425 #[serde(rename = "type", default = "default_function_type")]
427 pub call_type: String,
428 pub function: ChatCompletionFunctionCall,
430 #[serde(flatten)]
432 pub extra: BTreeMap<String, Value>,
433}
434
435#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
437pub struct ChatCompletionTokenTopLogprob {
438 #[serde(default)]
440 pub token: String,
441 pub bytes: Option<Vec<u8>>,
443 #[serde(default)]
445 pub logprob: f64,
446 #[serde(flatten)]
448 pub extra: BTreeMap<String, Value>,
449}
450
451#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
453pub struct ChatCompletionTokenLogprob {
454 #[serde(default)]
456 pub token: String,
457 pub bytes: Option<Vec<u8>>,
459 #[serde(default)]
461 pub logprob: f64,
462 #[serde(default)]
464 pub top_logprobs: Vec<ChatCompletionTokenTopLogprob>,
465 #[serde(flatten)]
467 pub extra: BTreeMap<String, Value>,
468}
469
470#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
472pub struct ChatCompletionChoiceLogprobs {
473 #[serde(default, skip_serializing_if = "Vec::is_empty")]
475 pub content: Vec<ChatCompletionTokenLogprob>,
476 #[serde(default, skip_serializing_if = "Vec::is_empty")]
478 pub refusal: Vec<ChatCompletionTokenLogprob>,
479 #[serde(flatten)]
481 pub extra: BTreeMap<String, Value>,
482}
483
484impl ChatCompletionChoiceLogprobs {
485 pub fn values(&self, field_name: &str) -> Option<&[ChatCompletionTokenLogprob]> {
487 match field_name {
488 "content" if !self.content.is_empty() => Some(&self.content),
489 "refusal" if !self.refusal.is_empty() => Some(&self.refusal),
490 _ => None,
491 }
492 }
493}
494
495#[derive(Debug, Clone, Serialize, Deserialize, Default)]
497pub struct ChatCompletionFunctionCallDelta {
498 pub name: Option<String>,
500 pub arguments: Option<String>,
502}
503
504#[derive(Debug, Clone, Serialize, Deserialize, Default)]
506pub struct ChatCompletionToolCallDelta {
507 pub index: Option<u32>,
509 pub id: Option<String>,
511 #[serde(rename = "type")]
513 pub call_type: Option<String>,
514 pub function: Option<ChatCompletionFunctionCallDelta>,
516}
517
518#[derive(Debug, Clone, Serialize, Deserialize, Default)]
520pub struct ChatCompletionMessage {
521 pub role: String,
523 #[serde(skip_serializing_if = "Option::is_none")]
525 pub content: Option<String>,
526 #[serde(skip_serializing_if = "Option::is_none")]
528 pub name: Option<String>,
529 #[serde(skip_serializing_if = "Option::is_none")]
531 pub tool_call_id: Option<String>,
532 #[serde(default, skip_serializing_if = "Vec::is_empty")]
534 pub tool_calls: Vec<ChatCompletionToolCall>,
535 #[serde(skip_serializing_if = "Option::is_none")]
537 pub refusal: Option<String>,
538 #[serde(skip_serializing_if = "Option::is_none")]
540 pub reasoning_content: Option<String>,
541 #[serde(default, skip_serializing_if = "Vec::is_empty")]
543 pub reasoning_details: Vec<ChatReasoningDetail>,
544 #[serde(flatten)]
546 pub extra: BTreeMap<String, Value>,
547}
548
549impl ChatCompletionMessage {
550 pub fn system(content: impl Into<String>) -> Self {
552 Self {
553 role: "system".into(),
554 content: Some(content.into()),
555 ..Self::default()
556 }
557 }
558
559 pub fn user(content: impl Into<String>) -> Self {
561 Self {
562 role: "user".into(),
563 content: Some(content.into()),
564 ..Self::default()
565 }
566 }
567
568 pub fn user_content_parts(parts: Vec<ChatMessageContentPart>) -> Self {
570 Self::with_content_parts("user", parts)
571 }
572
573 pub fn with_content_parts(role: impl Into<String>, parts: Vec<ChatMessageContentPart>) -> Self {
575 let mut extra = BTreeMap::new();
576 extra.insert(
577 "content".into(),
578 Value::Array(parts.into_iter().map(Value::from).collect()),
579 );
580 Self {
581 role: role.into(),
582 content: None,
583 extra,
584 ..Self::default()
585 }
586 }
587
588 pub fn content_text(text: impl Into<String>) -> ChatMessageContentPart {
590 serde_json::json!({
591 "type": "text",
592 "text": text.into(),
593 })
594 .into()
595 }
596
597 pub fn content_image_url(url: impl Into<String>) -> ChatMessageContentPart {
599 serde_json::json!({
600 "type": "image_url",
601 "image_url": {
602 "url": url.into(),
603 },
604 })
605 .into()
606 }
607
608 pub fn content_video_url(url: impl Into<String>) -> ChatMessageContentPart {
610 serde_json::json!({
611 "type": "video_url",
612 "video_url": {
613 "url": url.into(),
614 },
615 })
616 .into()
617 }
618
619 pub fn content_file(file_id: impl Into<String>) -> ChatMessageContentPart {
621 serde_json::json!({
622 "type": "file",
623 "file": {
624 "file_id": file_id.into(),
625 },
626 })
627 .into()
628 }
629
630 pub fn assistant(content: impl Into<String>) -> Self {
632 Self {
633 role: "assistant".into(),
634 content: Some(content.into()),
635 ..Self::default()
636 }
637 }
638
639 pub fn tool(tool_call_id: impl Into<String>, content: impl Into<String>) -> Self {
641 Self {
642 role: "tool".into(),
643 content: Some(content.into()),
644 tool_call_id: Some(tool_call_id.into()),
645 ..Self::default()
646 }
647 }
648
649 pub fn parse_content<T>(&self) -> Result<Option<T>>
655 where
656 T: serde::de::DeserializeOwned,
657 {
658 self.content
659 .as_deref()
660 .map(parse_jsonish_payload)
661 .transpose()
662 }
663
664 pub fn parse_tool_arguments<T>(&self) -> Result<Option<T>>
670 where
671 T: serde::de::DeserializeOwned,
672 {
673 self.tool_calls
674 .first()
675 .map(|tool_call| parse_json_arguments(&tool_call.function.arguments))
676 .transpose()
677 }
678
679 pub fn parse_tool_arguments_by_id<T>(&self, tool_call_id: &str) -> Result<Option<T>>
685 where
686 T: serde::de::DeserializeOwned,
687 {
688 self.tool_calls
689 .iter()
690 .find(|tool_call| tool_call.id == tool_call_id)
691 .map(|tool_call| parse_json_arguments(&tool_call.function.arguments))
692 .transpose()
693 }
694}
695
696#[derive(Debug, Clone, Serialize, Deserialize, Default)]
698pub struct ChatCompletionChoice {
699 pub index: u32,
701 pub finish_reason: Option<String>,
703 pub message: ChatCompletionMessage,
705 pub logprobs: Option<ChatCompletionChoiceLogprobs>,
707 #[serde(flatten)]
709 pub extra: BTreeMap<String, Value>,
710}
711
712#[derive(Debug, Clone, Serialize, Deserialize, Default)]
714pub struct ChatCompletion {
715 pub id: String,
717 #[serde(default)]
719 pub object: String,
720 pub created: Option<i64>,
722 #[serde(default)]
724 pub model: String,
725 #[serde(default)]
727 pub choices: Vec<ChatCompletionChoice>,
728 pub usage: Option<CompletionUsage>,
730 #[serde(flatten)]
732 pub extra: BTreeMap<String, Value>,
733}
734
735impl ChatCompletion {
736 pub fn ensure_not_truncated(&self) -> Result<&Self> {
742 for choice in &self.choices {
743 match choice.finish_reason.as_deref() {
744 Some("length") => return Err(crate::LengthFinishReasonError.into()),
745 Some("content_filter") => return Err(crate::ContentFilterFinishReasonError.into()),
746 _ => {}
747 }
748 }
749 Ok(self)
750 }
751}
752
753#[derive(Debug, Clone, Serialize, Deserialize, Default)]
755pub struct ChatCompletionChunkDelta {
756 pub role: Option<String>,
758 pub content: Option<String>,
760 pub refusal: Option<String>,
762 pub reasoning_content: Option<String>,
764 #[serde(default)]
766 pub reasoning_details: Vec<ChatReasoningDetail>,
767 #[serde(default)]
769 pub tool_calls: Vec<ChatCompletionToolCallDelta>,
770 #[serde(flatten)]
772 pub extra: BTreeMap<String, Value>,
773}
774
775#[derive(Debug, Clone, Serialize, Deserialize, Default)]
777pub struct ChatCompletionChunkChoice {
778 pub index: u32,
780 pub delta: ChatCompletionChunkDelta,
782 pub finish_reason: Option<String>,
784 pub logprobs: Option<ChatCompletionChoiceLogprobs>,
786 #[serde(flatten)]
788 pub extra: BTreeMap<String, Value>,
789}
790
791#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
793pub struct ChatContentDeltaEvent {
794 pub choice_index: u32,
796 pub delta: String,
798}
799
800#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
802pub struct ChatRefusalDeltaEvent {
803 pub choice_index: u32,
805 pub delta: String,
807}
808
809#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
811pub struct ChatToolArgumentsDeltaEvent {
812 pub choice_index: u32,
814 pub tool_call_index: u32,
816 pub name: Option<String>,
818 pub delta: String,
820}
821
822#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
824pub struct ChatLogProbsDeltaEvent {
825 pub choice_index: u32,
827 pub values: Vec<ChatCompletionTokenLogprob>,
829}
830
831#[derive(Debug, Clone, Serialize, Deserialize, Default)]
833pub struct ChatCompletionChunk {
834 pub id: String,
836 #[serde(default)]
838 pub object: String,
839 pub created: Option<i64>,
841 #[serde(default)]
843 pub model: String,
844 #[serde(default)]
846 pub choices: Vec<ChatCompletionChunkChoice>,
847 #[serde(flatten)]
849 pub extra: BTreeMap<String, Value>,
850}
851
852impl ChatCompletionChunk {
853 pub fn content_deltas(&self) -> Vec<ChatContentDeltaEvent> {
855 self.choices
856 .iter()
857 .filter_map(|choice| {
858 choice
859 .delta
860 .content
861 .as_ref()
862 .map(|delta| ChatContentDeltaEvent {
863 choice_index: choice.index,
864 delta: delta.clone(),
865 })
866 })
867 .collect()
868 }
869
870 pub fn refusal_deltas(&self) -> Vec<ChatRefusalDeltaEvent> {
872 self.choices
873 .iter()
874 .filter_map(|choice| {
875 choice
876 .delta
877 .refusal
878 .as_ref()
879 .map(|delta| ChatRefusalDeltaEvent {
880 choice_index: choice.index,
881 delta: delta.clone(),
882 })
883 })
884 .collect()
885 }
886
887 pub fn tool_argument_deltas(&self) -> Vec<ChatToolArgumentsDeltaEvent> {
889 self.choices
890 .iter()
891 .flat_map(|choice| {
892 choice.delta.tool_calls.iter().filter_map(|tool_call| {
893 let delta = tool_call.function.as_ref()?.arguments.clone()?;
894 Some(ChatToolArgumentsDeltaEvent {
895 choice_index: choice.index,
896 tool_call_index: tool_call.index.unwrap_or_default(),
897 name: tool_call
898 .function
899 .as_ref()
900 .and_then(|function| function.name.clone()),
901 delta,
902 })
903 })
904 })
905 .collect()
906 }
907
908 pub fn logprobs_content_deltas(&self) -> Vec<ChatLogProbsDeltaEvent> {
910 extract_logprobs(self, "content")
911 }
912
913 pub fn logprobs_refusal_deltas(&self) -> Vec<ChatLogProbsDeltaEvent> {
915 extract_logprobs(self, "refusal")
916 }
917}
918
919fn extract_logprobs(chunk: &ChatCompletionChunk, field_name: &str) -> Vec<ChatLogProbsDeltaEvent> {
920 chunk
921 .choices
922 .iter()
923 .filter_map(|choice| {
924 let values = choice
925 .logprobs
926 .as_ref()
927 .and_then(|logprobs| logprobs.values(field_name))?
928 .to_vec();
929 Some(ChatLogProbsDeltaEvent {
930 choice_index: choice.index,
931 values,
932 })
933 })
934 .collect()
935}
936
937#[derive(Debug, Clone, Serialize, Deserialize)]
939pub struct ChatToolDefinition {
940 #[serde(rename = "type")]
942 pub tool_type: String,
943 pub function: ChatToolFunction,
945}
946
947impl ChatToolDefinition {
948 #[cfg(feature = "tool-runner")]
949 fn from_tool(tool: &ToolDefinition) -> Self {
950 Self {
951 tool_type: "function".into(),
952 function: ChatToolFunction {
953 name: tool.name.clone(),
954 description: tool.description.clone(),
955 parameters: tool.parameters.clone(),
956 },
957 }
958 }
959
960 fn as_response_tool_value(&self) -> Value {
962 serde_json::json!({
963 "type": self.tool_type,
964 "name": self.function.name,
965 "description": self.function.description,
966 "parameters": self.function.parameters,
967 })
968 }
969}
970
971#[derive(Debug, Clone, Serialize, Deserialize)]
973pub struct McpToolDefinition {
974 #[serde(rename = "type", default = "default_mcp_tool_type")]
976 pub tool_type: String,
977 pub server_label: String,
979 #[serde(skip_serializing_if = "Option::is_none")]
981 pub allowed_tools: Option<JsonPayload>,
982 #[serde(skip_serializing_if = "Option::is_none")]
984 pub authorization: Option<String>,
985 #[serde(skip_serializing_if = "Option::is_none")]
987 pub connector_id: Option<String>,
988 #[serde(skip_serializing_if = "Option::is_none")]
990 pub defer_loading: Option<bool>,
991 #[serde(skip_serializing_if = "Option::is_none")]
993 pub headers: Option<BTreeMap<String, String>>,
994 #[serde(skip_serializing_if = "Option::is_none")]
996 pub require_approval: Option<JsonPayload>,
997 #[serde(skip_serializing_if = "Option::is_none")]
999 pub server_description: Option<String>,
1000 #[serde(skip_serializing_if = "Option::is_none")]
1002 pub server_url: Option<String>,
1003 #[serde(skip_serializing_if = "Option::is_none")]
1005 pub tunnel_id: Option<String>,
1006 #[serde(flatten)]
1008 pub extra: BTreeMap<String, Value>,
1009}
1010
1011impl Default for McpToolDefinition {
1012 fn default() -> Self {
1013 Self {
1014 tool_type: default_mcp_tool_type(),
1015 server_label: String::new(),
1016 allowed_tools: None,
1017 authorization: None,
1018 connector_id: None,
1019 defer_loading: None,
1020 headers: None,
1021 require_approval: None,
1022 server_description: None,
1023 server_url: None,
1024 tunnel_id: None,
1025 extra: BTreeMap::new(),
1026 }
1027 }
1028}
1029
1030impl McpToolDefinition {
1031 pub fn new(server_label: impl Into<String>) -> Self {
1033 Self {
1034 server_label: server_label.into(),
1035 ..Self::default()
1036 }
1037 }
1038
1039 pub fn allowed_tools(mut self, allowed_tools: impl Into<JsonPayload>) -> Self {
1041 self.allowed_tools = Some(allowed_tools.into());
1042 self
1043 }
1044
1045 pub fn allowed_tool_names<I, S>(mut self, names: I) -> Self
1047 where
1048 I: IntoIterator<Item = S>,
1049 S: Into<String>,
1050 {
1051 self.allowed_tools = Some(
1052 Value::Array(
1053 names
1054 .into_iter()
1055 .map(|name| Value::String(name.into()))
1056 .collect(),
1057 )
1058 .into(),
1059 );
1060 self
1061 }
1062
1063 pub fn authorization(mut self, authorization: impl Into<String>) -> Self {
1065 self.authorization = Some(authorization.into());
1066 self
1067 }
1068
1069 pub fn connector_id(mut self, connector_id: impl Into<String>) -> Self {
1071 self.connector_id = Some(connector_id.into());
1072 self
1073 }
1074
1075 pub fn defer_loading(mut self, defer_loading: bool) -> Self {
1077 self.defer_loading = Some(defer_loading);
1078 self
1079 }
1080
1081 pub fn header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
1083 self.headers
1084 .get_or_insert_with(BTreeMap::new)
1085 .insert(key.into(), value.into());
1086 self
1087 }
1088
1089 pub fn require_approval(mut self, require_approval: impl Into<JsonPayload>) -> Self {
1091 self.require_approval = Some(require_approval.into());
1092 self
1093 }
1094
1095 pub fn require_approval_mode(mut self, mode: impl Into<String>) -> Self {
1097 self.require_approval = Some(Value::String(mode.into()).into());
1098 self
1099 }
1100
1101 pub fn server_description(mut self, server_description: impl Into<String>) -> Self {
1103 self.server_description = Some(server_description.into());
1104 self
1105 }
1106
1107 pub fn server_url(mut self, server_url: impl Into<String>) -> Self {
1109 self.server_url = Some(server_url.into());
1110 self
1111 }
1112
1113 pub fn tunnel_id(mut self, tunnel_id: impl Into<String>) -> Self {
1115 self.tunnel_id = Some(tunnel_id.into());
1116 self
1117 }
1118
1119 pub fn extra(mut self, key: impl Into<String>, value: impl Into<JsonPayload>) -> Self {
1121 self.extra.insert(key.into(), value.into().into_raw());
1122 self
1123 }
1124}
1125
1126#[derive(Debug, Clone, Serialize, Deserialize)]
1128pub struct ChatToolFunction {
1129 pub name: String,
1131 pub description: Option<String>,
1133 pub parameters: JsonPayload,
1135}
1136
1137#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1139pub struct ChatCompletionCreateParams {
1140 #[serde(skip_serializing_if = "Option::is_none")]
1142 pub model: Option<String>,
1143 #[serde(default, skip_serializing_if = "Vec::is_empty")]
1145 pub messages: Vec<ChatCompletionMessage>,
1146 #[serde(skip_serializing_if = "Option::is_none")]
1148 pub temperature: Option<f32>,
1149 #[serde(skip_serializing_if = "Option::is_none")]
1151 pub n: Option<u32>,
1152 #[serde(skip_serializing_if = "Option::is_none")]
1154 pub max_tokens: Option<u32>,
1155 #[serde(default, skip_serializing_if = "Vec::is_empty")]
1157 pub tools: Vec<ChatToolDefinition>,
1158 #[serde(skip_serializing_if = "Option::is_none")]
1160 pub tool_choice: Option<ChatToolChoice>,
1161 #[serde(skip_serializing_if = "Option::is_none")]
1163 pub stream: Option<bool>,
1164}
1165
1166#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1168pub struct Response {
1169 pub id: String,
1171 pub created_at: Option<u64>,
1173 #[serde(default)]
1175 pub object: String,
1176 pub model: Option<String>,
1178 pub status: Option<String>,
1180 pub error: Option<ResponseError>,
1182 pub incomplete_details: Option<ResponseIncompleteDetails>,
1184 pub metadata: Option<BTreeMap<String, String>>,
1186 #[serde(default)]
1188 pub output: Vec<ResponseOutputItem>,
1189 pub usage: Option<ResponseUsage>,
1191 #[serde(flatten)]
1193 pub extra: BTreeMap<String, Value>,
1194}
1195
1196impl Response {
1197 pub fn output_text(&self) -> Option<String> {
1199 for item in &self.output {
1200 if let Some(text) = item.output_text() {
1201 return Some(text.to_owned());
1202 }
1203 }
1204
1205 self.extra
1206 .get("output_text")
1207 .and_then(Value::as_str)
1208 .map(str::to_owned)
1209 }
1210}
1211
1212#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1214pub struct ResponseError {
1215 pub code: Option<String>,
1217 pub message: Option<String>,
1219 #[serde(flatten)]
1221 pub extra: BTreeMap<String, Value>,
1222}
1223
1224#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1226pub struct ResponseIncompleteDetails {
1227 pub reason: Option<String>,
1229 #[serde(flatten)]
1231 pub extra: BTreeMap<String, Value>,
1232}
1233
1234#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1236pub struct ResponseUsage {
1237 #[serde(default)]
1239 pub input_tokens: u64,
1240 pub input_tokens_details: Option<ResponseInputTokensDetails>,
1242 #[serde(default)]
1244 pub output_tokens: u64,
1245 pub output_tokens_details: Option<ResponseOutputTokensDetails>,
1247 #[serde(default)]
1249 pub total_tokens: u64,
1250 #[serde(flatten)]
1252 pub extra: BTreeMap<String, Value>,
1253}
1254
1255#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1257pub struct ResponseInputTokensDetails {
1258 pub cached_tokens: Option<u64>,
1260 #[serde(flatten)]
1262 pub extra: BTreeMap<String, Value>,
1263}
1264
1265#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1267pub struct ResponseOutputTokensDetails {
1268 pub reasoning_tokens: Option<u64>,
1270 #[serde(flatten)]
1272 pub extra: BTreeMap<String, Value>,
1273}
1274
1275#[derive(Debug, Clone, Serialize, Deserialize)]
1277#[serde(untagged)]
1278pub enum ResponseOutputItem {
1279 Known(KnownResponseOutputItem),
1281 Raw(ResponseOutputItemRaw),
1283}
1284
1285impl Default for ResponseOutputItem {
1286 fn default() -> Self {
1287 Self::Raw(ResponseOutputItemRaw::default())
1288 }
1289}
1290
1291impl ResponseOutputItem {
1292 pub fn as_message(&self) -> Option<&ResponseOutputMessage> {
1294 match self {
1295 Self::Known(KnownResponseOutputItem::Message(message)) => Some(message),
1296 _ => None,
1297 }
1298 }
1299
1300 pub fn as_function_call(&self) -> Option<&ResponseFunctionToolCall> {
1302 match self {
1303 Self::Known(KnownResponseOutputItem::FunctionCall(call)) => Some(call),
1304 _ => None,
1305 }
1306 }
1307
1308 pub fn as_raw(&self) -> Option<&Value> {
1310 match self {
1311 Self::Raw(value) => Some(value.as_raw()),
1312 _ => None,
1313 }
1314 }
1315
1316 pub fn output_text(&self) -> Option<&str> {
1318 match self {
1319 Self::Known(KnownResponseOutputItem::OutputText(text)) => Some(text.text.as_str()),
1320 Self::Known(KnownResponseOutputItem::Message(message)) => message
1321 .content
1322 .iter()
1323 .find_map(ResponseOutputContentPart::text),
1324 Self::Raw(value) => {
1325 let value = value.as_raw();
1326 if let Some(text) = value.get("text").and_then(Value::as_str) {
1327 return Some(text);
1328 }
1329 value
1330 .get("content")
1331 .and_then(Value::as_array)
1332 .and_then(|content| {
1333 content
1334 .iter()
1335 .find_map(|item| item.get("text").and_then(Value::as_str))
1336 })
1337 }
1338 _ => None,
1339 }
1340 }
1341}
1342
1343#[derive(Debug, Clone, Serialize, Deserialize)]
1345#[serde(tag = "type", rename_all = "snake_case")]
1346pub enum KnownResponseOutputItem {
1347 Message(ResponseOutputMessage),
1349 FunctionCall(ResponseFunctionToolCall),
1351 OutputText(ResponseOutputText),
1353 Refusal(ResponseOutputRefusal),
1355}
1356
1357#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1359pub struct ResponseOutputMessage {
1360 pub id: String,
1362 #[serde(default)]
1364 pub content: Vec<ResponseOutputContentPart>,
1365 pub role: Option<String>,
1367 pub status: Option<String>,
1369 pub phase: Option<String>,
1371 #[serde(flatten)]
1373 pub extra: BTreeMap<String, Value>,
1374}
1375
1376#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1378pub struct ResponseFunctionToolCall {
1379 pub id: String,
1381 pub call_id: Option<String>,
1383 pub name: Option<String>,
1385 #[serde(default)]
1387 pub arguments: String,
1388 pub status: Option<String>,
1390 #[serde(flatten)]
1392 pub extra: BTreeMap<String, Value>,
1393}
1394
1395#[derive(Debug, Clone, Serialize, Deserialize)]
1397#[serde(untagged)]
1398pub enum ResponseOutputContentPart {
1399 Known(KnownResponseOutputContentPart),
1401 Raw(ResponseOutputContentPartRaw),
1403}
1404
1405impl Default for ResponseOutputContentPart {
1406 fn default() -> Self {
1407 Self::Raw(ResponseOutputContentPartRaw::default())
1408 }
1409}
1410
1411impl ResponseOutputContentPart {
1412 pub fn as_output_text(&self) -> Option<&ResponseOutputText> {
1414 match self {
1415 Self::Known(KnownResponseOutputContentPart::OutputText(text)) => Some(text),
1416 _ => None,
1417 }
1418 }
1419
1420 pub fn text(&self) -> Option<&str> {
1422 match self {
1423 Self::Known(KnownResponseOutputContentPart::OutputText(text)) => {
1424 Some(text.text.as_str())
1425 }
1426 Self::Raw(value) => value.as_raw().get("text").and_then(Value::as_str),
1427 _ => None,
1428 }
1429 }
1430}
1431
1432#[derive(Debug, Clone, Serialize, Deserialize)]
1434#[serde(tag = "type", rename_all = "snake_case")]
1435pub enum KnownResponseOutputContentPart {
1436 OutputText(ResponseOutputText),
1438 Refusal(ResponseOutputRefusal),
1440}
1441
1442#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1444pub struct ResponseOutputTextFileCitation {
1445 pub file_id: String,
1447 pub filename: String,
1449 pub index: u64,
1451 #[serde(flatten)]
1453 pub extra: BTreeMap<String, Value>,
1454}
1455
1456#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1458pub struct ResponseOutputTextUrlCitation {
1459 pub end_index: u64,
1461 pub start_index: u64,
1463 pub title: String,
1465 pub url: String,
1467 #[serde(flatten)]
1469 pub extra: BTreeMap<String, Value>,
1470}
1471
1472#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1474pub struct ResponseOutputTextContainerFileCitation {
1475 pub container_id: String,
1477 pub end_index: u64,
1479 pub file_id: String,
1481 pub filename: String,
1483 pub start_index: u64,
1485 #[serde(flatten)]
1487 pub extra: BTreeMap<String, Value>,
1488}
1489
1490#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1492pub struct ResponseOutputTextFilePath {
1493 pub file_id: String,
1495 pub index: u64,
1497 #[serde(flatten)]
1499 pub extra: BTreeMap<String, Value>,
1500}
1501
1502#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1504#[serde(tag = "type", rename_all = "snake_case")]
1505pub enum KnownResponseOutputTextAnnotation {
1506 FileCitation(ResponseOutputTextFileCitation),
1508 UrlCitation(ResponseOutputTextUrlCitation),
1510 ContainerFileCitation(ResponseOutputTextContainerFileCitation),
1512 FilePath(ResponseOutputTextFilePath),
1514}
1515
1516#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
1518pub struct ResponseOutputTextAnnotationUnknown {
1519 #[serde(rename = "type")]
1521 pub annotation_type: Option<String>,
1522 #[serde(flatten)]
1524 pub extra: BTreeMap<String, Value>,
1525}
1526
1527#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1529#[serde(untagged)]
1530pub enum ResponseOutputTextAnnotation {
1531 Known(KnownResponseOutputTextAnnotation),
1533 Unknown(ResponseOutputTextAnnotationUnknown),
1535}
1536
1537impl Default for ResponseOutputTextAnnotation {
1538 fn default() -> Self {
1539 Self::Unknown(ResponseOutputTextAnnotationUnknown::default())
1540 }
1541}
1542
1543impl ResponseOutputTextAnnotation {
1544 pub fn kind(&self) -> Option<&str> {
1546 match self {
1547 Self::Known(KnownResponseOutputTextAnnotation::FileCitation(_)) => {
1548 Some("file_citation")
1549 }
1550 Self::Known(KnownResponseOutputTextAnnotation::UrlCitation(_)) => Some("url_citation"),
1551 Self::Known(KnownResponseOutputTextAnnotation::ContainerFileCitation(_)) => {
1552 Some("container_file_citation")
1553 }
1554 Self::Known(KnownResponseOutputTextAnnotation::FilePath(_)) => Some("file_path"),
1555 Self::Unknown(annotation) => annotation.annotation_type.as_deref(),
1556 }
1557 }
1558}
1559
1560#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
1562pub struct ResponseOutputTextTopLogprob {
1563 #[serde(default)]
1565 pub token: String,
1566 #[serde(default)]
1568 pub bytes: Vec<u8>,
1569 #[serde(default)]
1571 pub logprob: f64,
1572 #[serde(flatten)]
1574 pub extra: BTreeMap<String, Value>,
1575}
1576
1577#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
1579pub struct ResponseOutputTextLogprob {
1580 #[serde(default)]
1582 pub token: String,
1583 #[serde(default)]
1585 pub bytes: Vec<u8>,
1586 #[serde(default)]
1588 pub logprob: f64,
1589 #[serde(default)]
1591 pub top_logprobs: Vec<ResponseOutputTextTopLogprob>,
1592 #[serde(flatten)]
1594 pub extra: BTreeMap<String, Value>,
1595}
1596
1597#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1599pub struct ResponseOutputText {
1600 #[serde(default)]
1602 pub annotations: Vec<ResponseOutputTextAnnotation>,
1603 #[serde(default)]
1605 pub text: String,
1606 pub logprobs: Option<Vec<ResponseOutputTextLogprob>>,
1608 #[serde(flatten)]
1610 pub extra: BTreeMap<String, Value>,
1611}
1612
1613#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1615pub struct ResponseOutputRefusal {
1616 #[serde(default)]
1618 pub refusal: String,
1619 #[serde(flatten)]
1621 pub extra: BTreeMap<String, Value>,
1622}
1623
1624#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1626pub struct ResponseCreateParams {
1627 #[serde(skip_serializing_if = "Option::is_none")]
1629 pub model: Option<String>,
1630 #[serde(skip_serializing_if = "Option::is_none")]
1632 pub input: Option<ResponseInputPayload>,
1633 #[serde(skip_serializing_if = "Option::is_none")]
1635 pub temperature: Option<f32>,
1636 #[serde(default, skip_serializing_if = "Vec::is_empty")]
1638 pub tools: Vec<ChatToolDefinition>,
1639 #[serde(skip_serializing_if = "Option::is_none")]
1641 pub stream: Option<bool>,
1642}
1643
1644fn default_function_type() -> String {
1645 "function".into()
1646}
1647
1648fn default_mcp_tool_type() -> String {
1649 "mcp".into()
1650}
1651
1652fn parse_jsonish_payload<T>(payload: &str) -> Result<T>
1653where
1654 T: serde::de::DeserializeOwned,
1655{
1656 let trimmed = payload.trim();
1657 let normalized = trimmed
1658 .strip_prefix("```json")
1659 .or_else(|| trimmed.strip_prefix("```"))
1660 .map(|value| value.trim())
1661 .and_then(|value| value.strip_suffix("```"))
1662 .map_or(trimmed, str::trim);
1663 serde_json::from_str(normalized).map_err(|error| {
1664 Error::Serialization(crate::SerializationError::new(format!(
1665 "结构化 JSON 解析失败: {error}"
1666 )))
1667 })
1668}
1669
1670fn parse_json_arguments<T>(arguments: &str) -> Result<T>
1671where
1672 T: serde::de::DeserializeOwned,
1673{
1674 serde_json::from_str(arguments).map_err(|error| {
1675 Error::Serialization(crate::SerializationError::new(format!(
1676 "工具参数 JSON 解析失败: {error}"
1677 )))
1678 })
1679}
1680
1681handle!(
1682 AdminResource
1684);
1685handle!(
1686 AdminOrganizationResource
1688);
1689handle!(
1690 AdminOrganizationAuditLogsResource
1692);
1693handle!(
1694 AdminOrganizationAdminApiKeysResource
1696);
1697handle!(
1698 AdminOrganizationUsageResource
1700);
1701handle!(
1702 AdminOrganizationInvitesResource
1704);
1705handle!(
1706 AdminOrganizationUsersResource
1708);
1709handle!(
1710 AdminOrganizationUserRolesResource
1712);
1713handle!(
1714 AdminOrganizationGroupsResource
1716);
1717handle!(
1718 AdminOrganizationGroupUsersResource
1720);
1721handle!(
1722 AdminOrganizationGroupRolesResource
1724);
1725handle!(
1726 AdminOrganizationRolesResource
1728);
1729handle!(
1730 AdminOrganizationDataRetentionResource
1732);
1733handle!(
1734 AdminOrganizationSpendAlertsResource
1736);
1737handle!(
1738 AdminOrganizationCertificatesResource
1740);
1741handle!(
1742 AdminOrganizationProjectsResource
1744);
1745handle!(
1746 AdminProjectUsersResource
1748);
1749handle!(
1750 AdminProjectUserRolesResource
1752);
1753handle!(
1754 AdminProjectServiceAccountsResource
1756);
1757handle!(
1758 AdminProjectApiKeysResource
1760);
1761handle!(
1762 AdminProjectRateLimitsResource
1764);
1765handle!(
1766 AdminProjectModelPermissionsResource
1768);
1769handle!(
1770 AdminProjectHostedToolPermissionsResource
1772);
1773handle!(
1774 AdminProjectGroupsResource
1776);
1777handle!(
1778 AdminProjectGroupRolesResource
1780);
1781handle!(
1782 AdminProjectRolesResource
1784);
1785handle!(
1786 AdminProjectDataRetentionResource
1788);
1789handle!(
1790 AdminProjectSpendAlertsResource
1792);
1793handle!(
1794 AdminProjectCertificatesResource
1796);
1797handle!(
1798 CompletionsResource
1800);
1801handle!(
1802 ChatResource
1804);
1805handle!(
1806 ChatCompletionsResource
1808);
1809handle!(
1810 ChatCompletionMessagesResource
1812);
1813handle!(
1814 EmbeddingsResource
1816);
1817handle!(
1818 FilesResource
1820);
1821handle!(
1822 ImagesResource
1824);
1825handle!(
1826 AudioResource
1828);
1829handle!(
1830 AudioSpeechResource
1832);
1833handle!(
1834 AudioTranscriptionsResource
1836);
1837handle!(
1838 AudioTranslationsResource
1840);
1841handle!(
1842 ModerationsResource
1844);
1845handle!(
1846 ModelsResource
1848);
1849handle!(
1850 FineTuningResource
1852);
1853handle!(
1854 FineTuningJobsResource
1856);
1857handle!(
1858 FineTuningJobCheckpointsResource
1860);
1861handle!(
1862 FineTuningCheckpointPermissionsResource
1864);
1865handle!(
1866 FineTuningAlphaResource
1868);
1869handle!(
1870 FineTuningAlphaGradersResource
1872);
1873handle!(
1874 GradersResource
1876);
1877handle!(
1878 VectorStoresResource
1880);
1881handle!(
1882 VectorStoreFilesResource
1884);
1885handle!(
1886 VectorStoreFileBatchesResource
1888);
1889handle!(
1890 BatchesResource
1892);
1893handle!(
1894 UploadsResource
1896);
1897handle!(
1898 UploadPartsResource
1900);
1901handle!(
1902 ResponsesResource
1904);
1905handle!(
1906 ResponseInputItemsResource
1908);
1909handle!(
1910 ResponseInputTokensResource
1912);
1913handle!(
1914 RealtimeResource
1916);
1917handle!(
1918 RealtimeClientSecretsResource
1920);
1921handle!(
1922 RealtimeCallsResource
1924);
1925handle!(
1926 ConversationsResource
1928);
1929handle!(
1930 ConversationItemsResource
1932);
1933handle!(
1934 EvalsResource
1936);
1937handle!(
1938 EvalRunsResource
1940);
1941handle!(
1942 EvalRunOutputItemsResource
1944);
1945handle!(
1946 ContainersResource
1948);
1949handle!(
1950 ContainerFilesResource
1952);
1953handle!(
1954 ContainerFilesContentResource
1956);
1957handle!(
1958 SkillsResource
1960);
1961handle!(
1962 SkillsContentResource
1964);
1965handle!(
1966 SkillVersionsResource
1968);
1969handle!(
1970 SkillVersionsContentResource
1972);
1973handle!(
1974 VideosResource
1976);
1977handle!(
1978 WebhooksResource
1980);
1981handle!(
1982 BetaResource
1984);
1985handle!(
1986 BetaAssistantsResource
1988);
1989handle!(
1990 BetaThreadsResource
1992);
1993handle!(
1994 BetaThreadMessagesResource
1996);
1997handle!(
1998 BetaThreadRunsResource
2000);
2001handle!(
2002 BetaThreadRunStepsResource
2004);
2005handle!(
2006 BetaChatkitResource
2008);
2009handle!(
2010 BetaChatkitSessionsResource
2012);
2013handle!(
2014 BetaChatkitThreadsResource
2016);
2017handle!(
2018 BetaRealtimeResource
2020);
2021handle!(
2022 BetaRealtimeSessionsResource
2024);
2025handle!(
2026 BetaRealtimeTranscriptionSessionsResource
2028);