Skip to main content

openai_core/resources/
mod.rs

1//! 资源命名空间、公开类型与请求构建器。
2
3mod 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            /// 返回未经解释的原始 JSON 值。
135            pub fn as_raw(&self) -> &Value {
136                &self.0
137            }
138
139            /// 消费该包装器并返回原始 JSON 值。
140            pub fn into_raw(self) -> Value {
141                self.0
142            }
143
144            /// 返回载荷中的 `type` 字段,若存在且为字符串。
145            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/// 表示常见的删除结果。
169#[derive(Debug, Clone, Serialize, Deserialize, Default)]
170pub struct DeleteResponse {
171    /// 被删除对象的 ID。
172    pub id: Option<String>,
173    /// 是否删除成功。
174    #[serde(default)]
175    pub deleted: bool,
176    /// 对象类型。
177    pub object: Option<String>,
178    /// 额外字段。
179    #[serde(flatten)]
180    pub extra: BTreeMap<String, Value>,
181}
182
183/// 表示模型对象。
184#[derive(Debug, Clone, Serialize, Deserialize, Default)]
185pub struct Model {
186    /// 模型 ID。
187    pub id: String,
188    /// 对象类型。
189    #[serde(default)]
190    pub object: String,
191    /// 模型所有者。
192    pub owned_by: Option<String>,
193    /// 额外字段。
194    #[serde(flatten)]
195    pub extra: BTreeMap<String, Value>,
196}
197
198/// 表示文件对象。
199#[derive(Debug, Clone, Serialize, Deserialize, Default)]
200pub struct FileObject {
201    /// 文件 ID。
202    pub id: String,
203    /// 对象类型。
204    #[serde(default)]
205    pub object: String,
206    /// 文件名。
207    pub filename: Option<String>,
208    /// 文件用途。
209    pub purpose: Option<String>,
210    /// 文件大小。
211    pub bytes: Option<u64>,
212    /// 额外字段。
213    #[serde(flatten)]
214    pub extra: BTreeMap<String, Value>,
215}
216
217/// 表示上传对象。
218#[derive(Debug, Clone, Serialize, Deserialize, Default)]
219pub struct UploadObject {
220    /// 上传 ID。
221    pub id: String,
222    /// 对象类型。
223    #[serde(default)]
224    pub object: String,
225    /// 上传状态。
226    pub status: Option<String>,
227    /// 额外字段。
228    #[serde(flatten)]
229    pub extra: BTreeMap<String, Value>,
230}
231
232/// 表示 Embeddings 接口的返回值。
233#[derive(Debug, Clone, Serialize, Deserialize, Default)]
234pub struct EmbeddingResponse {
235    /// 对象类型。
236    #[serde(default)]
237    pub object: String,
238    /// 向量数据。
239    #[serde(default)]
240    pub data: Vec<EmbeddingData>,
241    /// 使用统计。
242    pub usage: Option<EmbeddingUsage>,
243    /// 额外字段。
244    #[serde(flatten)]
245    pub extra: BTreeMap<String, Value>,
246}
247
248/// 表示单个 embedding 向量项。
249#[derive(Debug, Clone, Serialize, Deserialize, Default)]
250pub struct EmbeddingData {
251    /// embedding 向量。
252    #[serde(default)]
253    pub embedding: Vec<f64>,
254    /// 向量索引。
255    pub index: Option<u32>,
256    /// 对象类型。
257    #[serde(default)]
258    pub object: String,
259    /// 额外字段。
260    #[serde(flatten)]
261    pub extra: BTreeMap<String, Value>,
262}
263
264/// 表示 embeddings 的用量统计。
265#[derive(Debug, Clone, Serialize, Deserialize, Default)]
266pub struct EmbeddingUsage {
267    /// prompt token 数。
268    #[serde(default)]
269    pub prompt_tokens: u64,
270    /// 总 token 数。
271    #[serde(default)]
272    pub total_tokens: u64,
273    /// 额外字段。
274    #[serde(flatten)]
275    pub extra: BTreeMap<String, Value>,
276}
277
278/// 表示模型计数结果。
279#[derive(Debug, Clone, Serialize, Deserialize, Default)]
280pub struct InputTokenCount {
281    /// 总 token 数量。
282    pub total_tokens: u64,
283    /// 额外字段。
284    #[serde(flatten)]
285    pub extra: BTreeMap<String, Value>,
286}
287
288json_payload_wrapper!(
289    /// 表示已存储 chat completion 的 content part。
290    ChatCompletionStoreContentPart
291);
292json_payload_wrapper!(
293    /// 表示聊天消息中的 reasoning detail。
294    ChatReasoningDetail
295);
296json_payload_wrapper!(
297    /// 表示 chat 请求中的多模态 content part。
298    ChatMessageContentPart
299);
300json_payload_wrapper!(
301    /// 表示 chat 请求中的 tool_choice 载荷。
302    ChatToolChoice
303);
304json_payload_wrapper!(
305    /// 表示 responses 请求的输入载荷。
306    ResponseInputPayload
307);
308json_payload_wrapper!(
309    /// 表示 responses 请求中的单个输入项。
310    ResponseInputItemPayload
311);
312json_payload_wrapper!(
313    /// 表示 realtime client secret 返回中的 session 配置。
314    RealtimeSessionPayload
315);
316json_payload_wrapper!(
317    /// 表示 responses 输出中的未知原始输出项。
318    ResponseOutputItemRaw
319);
320json_payload_wrapper!(
321    /// 表示 responses message 中的未知原始内容片段。
322    ResponseOutputContentPartRaw
323);
324
325/// 表示 chat tool_choice 的字符串模式。
326#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
327#[serde(rename_all = "snake_case")]
328pub enum ChatToolChoiceMode {
329    /// 不允许工具调用。
330    None,
331    /// 允许模型自动选择。
332    Auto,
333    /// 要求模型必须调用工具。
334    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    /// 生成 `none` 模式。
368    pub fn none() -> Self {
369        ChatToolChoiceMode::None.into()
370    }
371
372    /// 生成 `auto` 模式。
373    pub fn auto() -> Self {
374        ChatToolChoiceMode::Auto.into()
375    }
376
377    /// 生成 `required` 模式。
378    pub fn required() -> Self {
379        ChatToolChoiceMode::Required.into()
380    }
381
382    /// 强制调用指定函数工具。
383    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    /// 强制调用指定自定义工具。
394    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    /// 当 tool_choice 为字符串模式时返回该模式。
405    pub fn mode_name(&self) -> Option<&str> {
406        self.0.as_str()
407    }
408}
409
410/// 表示一个工具函数调用。
411#[derive(Debug, Clone, Serialize, Deserialize, Default)]
412pub struct ChatCompletionFunctionCall {
413    /// 工具名称。
414    pub name: String,
415    /// 参数 JSON 字符串。
416    #[serde(default)]
417    pub arguments: String,
418}
419
420/// 表示工具调用项。
421#[derive(Debug, Clone, Serialize, Deserialize, Default)]
422pub struct ChatCompletionToolCall {
423    /// 工具调用 ID。
424    pub id: String,
425    /// 调用类型。
426    #[serde(rename = "type", default = "default_function_type")]
427    pub call_type: String,
428    /// 函数调用内容。
429    pub function: ChatCompletionFunctionCall,
430    /// 额外字段。
431    #[serde(flatten)]
432    pub extra: BTreeMap<String, Value>,
433}
434
435/// 表示 token 的 top logprob。
436#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
437pub struct ChatCompletionTokenTopLogprob {
438    /// token 内容。
439    #[serde(default)]
440    pub token: String,
441    /// UTF-8 bytes。
442    pub bytes: Option<Vec<u8>>,
443    /// token 对应的 logprob。
444    #[serde(default)]
445    pub logprob: f64,
446    /// 额外字段。
447    #[serde(flatten)]
448    pub extra: BTreeMap<String, Value>,
449}
450
451/// 表示单个 token 的 logprob 信息。
452#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
453pub struct ChatCompletionTokenLogprob {
454    /// token 内容。
455    #[serde(default)]
456    pub token: String,
457    /// UTF-8 bytes。
458    pub bytes: Option<Vec<u8>>,
459    /// token 对应的 logprob。
460    #[serde(default)]
461    pub logprob: f64,
462    /// top logprobs。
463    #[serde(default)]
464    pub top_logprobs: Vec<ChatCompletionTokenTopLogprob>,
465    /// 额外字段。
466    #[serde(flatten)]
467    pub extra: BTreeMap<String, Value>,
468}
469
470/// 表示 chat completion choice 的 token logprobs。
471#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
472pub struct ChatCompletionChoiceLogprobs {
473    /// 内容 token 的 logprobs。
474    #[serde(default, skip_serializing_if = "Vec::is_empty")]
475    pub content: Vec<ChatCompletionTokenLogprob>,
476    /// refusal token 的 logprobs。
477    #[serde(default, skip_serializing_if = "Vec::is_empty")]
478    pub refusal: Vec<ChatCompletionTokenLogprob>,
479    /// 额外字段。
480    #[serde(flatten)]
481    pub extra: BTreeMap<String, Value>,
482}
483
484impl ChatCompletionChoiceLogprobs {
485    /// 按字段名返回对应的 token logprobs 列表。
486    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/// 表示流式函数调用增量。
496#[derive(Debug, Clone, Serialize, Deserialize, Default)]
497pub struct ChatCompletionFunctionCallDelta {
498    /// 函数名称增量。
499    pub name: Option<String>,
500    /// 参数增量。
501    pub arguments: Option<String>,
502}
503
504/// 表示流式工具调用增量。
505#[derive(Debug, Clone, Serialize, Deserialize, Default)]
506pub struct ChatCompletionToolCallDelta {
507    /// 增量对应索引。
508    pub index: Option<u32>,
509    /// 工具调用 ID。
510    pub id: Option<String>,
511    /// 调用类型。
512    #[serde(rename = "type")]
513    pub call_type: Option<String>,
514    /// 函数调用增量。
515    pub function: Option<ChatCompletionFunctionCallDelta>,
516}
517
518/// 表示聊天消息。
519#[derive(Debug, Clone, Serialize, Deserialize, Default)]
520pub struct ChatCompletionMessage {
521    /// 角色。
522    pub role: String,
523    /// 文本内容。
524    #[serde(skip_serializing_if = "Option::is_none")]
525    pub content: Option<String>,
526    /// 可选名称。
527    #[serde(skip_serializing_if = "Option::is_none")]
528    pub name: Option<String>,
529    /// 工具调用关联 ID。
530    #[serde(skip_serializing_if = "Option::is_none")]
531    pub tool_call_id: Option<String>,
532    /// 工具调用集合。
533    #[serde(default, skip_serializing_if = "Vec::is_empty")]
534    pub tool_calls: Vec<ChatCompletionToolCall>,
535    /// 拒绝回答文本。
536    #[serde(skip_serializing_if = "Option::is_none")]
537    pub refusal: Option<String>,
538    /// 推理内容。
539    #[serde(skip_serializing_if = "Option::is_none")]
540    pub reasoning_content: Option<String>,
541    /// 推理细节。
542    #[serde(default, skip_serializing_if = "Vec::is_empty")]
543    pub reasoning_details: Vec<ChatReasoningDetail>,
544    /// 额外字段。
545    #[serde(flatten)]
546    pub extra: BTreeMap<String, Value>,
547}
548
549impl ChatCompletionMessage {
550    /// 创建 system 消息。
551    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    /// 创建 user 消息。
560    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    /// 创建包含多模态 content parts 的 user 消息。
569    pub fn user_content_parts(parts: Vec<ChatMessageContentPart>) -> Self {
570        Self::with_content_parts("user", parts)
571    }
572
573    /// 创建包含多模态 content parts 的任意角色消息。
574    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    /// 创建 text content part。
589    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    /// 创建 image_url content part。
598    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    /// 创建 video_url content part 预留结构。
609    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    /// 创建 file 引用 content part 预留结构。
620    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    /// 创建 assistant 消息。
631    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    /// 创建 tool 消息。
640    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    /// 尝试把消息文本解析为结构化对象。
650    ///
651    /// # Errors
652    ///
653    /// 当文本存在但 JSON 解析失败时返回错误。
654    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    /// 尝试解析首个工具调用的参数。
665    ///
666    /// # Errors
667    ///
668    /// 当工具参数不是合法 JSON 时返回错误。
669    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    /// 尝试解析指定工具调用的参数。
680    ///
681    /// # Errors
682    ///
683    /// 当工具参数不是合法 JSON 时返回错误。
684    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/// 表示聊天补全中的单个候选项。
697#[derive(Debug, Clone, Serialize, Deserialize, Default)]
698pub struct ChatCompletionChoice {
699    /// 候选项索引。
700    pub index: u32,
701    /// 结束原因。
702    pub finish_reason: Option<String>,
703    /// 返回消息。
704    pub message: ChatCompletionMessage,
705    /// token 级 logprobs。
706    pub logprobs: Option<ChatCompletionChoiceLogprobs>,
707    /// 额外字段。
708    #[serde(flatten)]
709    pub extra: BTreeMap<String, Value>,
710}
711
712/// 表示聊天补全结果。
713#[derive(Debug, Clone, Serialize, Deserialize, Default)]
714pub struct ChatCompletion {
715    /// 补全 ID。
716    pub id: String,
717    /// 对象类型。
718    #[serde(default)]
719    pub object: String,
720    /// 创建时间。
721    pub created: Option<i64>,
722    /// 模型 ID。
723    #[serde(default)]
724    pub model: String,
725    /// 候选项集合。
726    #[serde(default)]
727    pub choices: Vec<ChatCompletionChoice>,
728    /// 使用统计。
729    pub usage: Option<CompletionUsage>,
730    /// 额外字段。
731    #[serde(flatten)]
732    pub extra: BTreeMap<String, Value>,
733}
734
735impl ChatCompletion {
736    /// 校验返回结果没有因为长度或内容过滤而失去可解析语义。
737    ///
738    /// # Errors
739    ///
740    /// 当任一 choice 的 `finish_reason` 为 `length` 或 `content_filter` 时返回错误。
741    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/// 表示流式增量。
754#[derive(Debug, Clone, Serialize, Deserialize, Default)]
755pub struct ChatCompletionChunkDelta {
756    /// 角色增量。
757    pub role: Option<String>,
758    /// 文本内容增量。
759    pub content: Option<String>,
760    /// 拒绝回答文本增量。
761    pub refusal: Option<String>,
762    /// 推理内容增量。
763    pub reasoning_content: Option<String>,
764    /// 推理细节增量。
765    #[serde(default)]
766    pub reasoning_details: Vec<ChatReasoningDetail>,
767    /// 工具调用增量。
768    #[serde(default)]
769    pub tool_calls: Vec<ChatCompletionToolCallDelta>,
770    /// 额外字段。
771    #[serde(flatten)]
772    pub extra: BTreeMap<String, Value>,
773}
774
775/// 表示流式候选项。
776#[derive(Debug, Clone, Serialize, Deserialize, Default)]
777pub struct ChatCompletionChunkChoice {
778    /// 候选索引。
779    pub index: u32,
780    /// 增量载荷。
781    pub delta: ChatCompletionChunkDelta,
782    /// 结束原因。
783    pub finish_reason: Option<String>,
784    /// token 级 logprobs 增量。
785    pub logprobs: Option<ChatCompletionChoiceLogprobs>,
786    /// 额外字段。
787    #[serde(flatten)]
788    pub extra: BTreeMap<String, Value>,
789}
790
791/// 表示聊天文本增量事件。
792#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
793pub struct ChatContentDeltaEvent {
794    /// 候选索引。
795    pub choice_index: u32,
796    /// 文本增量。
797    pub delta: String,
798}
799
800/// 表示聊天拒绝回答增量事件。
801#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
802pub struct ChatRefusalDeltaEvent {
803    /// 候选索引。
804    pub choice_index: u32,
805    /// 拒绝文本增量。
806    pub delta: String,
807}
808
809/// 表示工具参数增量事件。
810#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
811pub struct ChatToolArgumentsDeltaEvent {
812    /// 候选索引。
813    pub choice_index: u32,
814    /// 工具调用索引。
815    pub tool_call_index: u32,
816    /// 工具名称增量。
817    pub name: Option<String>,
818    /// 参数增量。
819    pub delta: String,
820}
821
822/// 表示 token logprobs 增量事件。
823#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
824pub struct ChatLogProbsDeltaEvent {
825    /// 候选索引。
826    pub choice_index: u32,
827    /// logprobs 明细。
828    pub values: Vec<ChatCompletionTokenLogprob>,
829}
830
831/// 表示聊天补全 SSE 分片。
832#[derive(Debug, Clone, Serialize, Deserialize, Default)]
833pub struct ChatCompletionChunk {
834    /// 分片所属补全 ID。
835    pub id: String,
836    /// 对象类型。
837    #[serde(default)]
838    pub object: String,
839    /// 创建时间。
840    pub created: Option<i64>,
841    /// 模型 ID。
842    #[serde(default)]
843    pub model: String,
844    /// 候选项集合。
845    #[serde(default)]
846    pub choices: Vec<ChatCompletionChunkChoice>,
847    /// 额外字段。
848    #[serde(flatten)]
849    pub extra: BTreeMap<String, Value>,
850}
851
852impl ChatCompletionChunk {
853    /// 提取所有文本内容增量。
854    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    /// 提取所有拒绝回答增量。
871    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    /// 提取所有工具参数增量。
888    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    /// 提取内容 token 的 logprobs 增量。
909    pub fn logprobs_content_deltas(&self) -> Vec<ChatLogProbsDeltaEvent> {
910        extract_logprobs(self, "content")
911    }
912
913    /// 提取拒绝回答 token 的 logprobs 增量。
914    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/// 表示聊天工具定义。
938#[derive(Debug, Clone, Serialize, Deserialize)]
939pub struct ChatToolDefinition {
940    /// 工具类型,当前固定为 `function`。
941    #[serde(rename = "type")]
942    pub tool_type: String,
943    /// 函数定义。
944    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    /// 转换为 Responses API 所需的扁平工具定义格式。
961    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/// 表示聊天工具函数定义。
972#[derive(Debug, Clone, Serialize, Deserialize)]
973pub struct ChatToolFunction {
974    /// 函数名。
975    pub name: String,
976    /// 函数描述。
977    pub description: Option<String>,
978    /// 参数 Schema。
979    pub parameters: JsonPayload,
980}
981
982/// 表示聊天补全请求参数。
983#[derive(Debug, Clone, Serialize, Deserialize, Default)]
984pub struct ChatCompletionCreateParams {
985    /// 模型 ID。
986    #[serde(skip_serializing_if = "Option::is_none")]
987    pub model: Option<String>,
988    /// 历史消息。
989    #[serde(default, skip_serializing_if = "Vec::is_empty")]
990    pub messages: Vec<ChatCompletionMessage>,
991    /// 温度。
992    #[serde(skip_serializing_if = "Option::is_none")]
993    pub temperature: Option<f32>,
994    /// 候选数量。
995    #[serde(skip_serializing_if = "Option::is_none")]
996    pub n: Option<u32>,
997    /// 最大 token 数。
998    #[serde(skip_serializing_if = "Option::is_none")]
999    pub max_tokens: Option<u32>,
1000    /// 工具定义。
1001    #[serde(default, skip_serializing_if = "Vec::is_empty")]
1002    pub tools: Vec<ChatToolDefinition>,
1003    /// 工具选择策略。
1004    #[serde(skip_serializing_if = "Option::is_none")]
1005    pub tool_choice: Option<ChatToolChoice>,
1006    /// 流式开关。
1007    #[serde(skip_serializing_if = "Option::is_none")]
1008    pub stream: Option<bool>,
1009}
1010
1011/// 表示 Responses 对象。
1012#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1013pub struct Response {
1014    /// 响应 ID。
1015    pub id: String,
1016    /// 创建时间。
1017    pub created_at: Option<u64>,
1018    /// 对象类型。
1019    #[serde(default)]
1020    pub object: String,
1021    /// 模型 ID。
1022    pub model: Option<String>,
1023    /// 状态。
1024    pub status: Option<String>,
1025    /// 错误信息。
1026    pub error: Option<ResponseError>,
1027    /// 不完整原因。
1028    pub incomplete_details: Option<ResponseIncompleteDetails>,
1029    /// 元数据。
1030    pub metadata: Option<BTreeMap<String, String>>,
1031    /// 输出项。
1032    #[serde(default)]
1033    pub output: Vec<ResponseOutputItem>,
1034    /// 用量统计。
1035    pub usage: Option<ResponseUsage>,
1036    /// 额外字段。
1037    #[serde(flatten)]
1038    pub extra: BTreeMap<String, Value>,
1039}
1040
1041impl Response {
1042    /// 尝试提取最终文本输出。
1043    pub fn output_text(&self) -> Option<String> {
1044        for item in &self.output {
1045            if let Some(text) = item.output_text() {
1046                return Some(text.to_owned());
1047            }
1048        }
1049
1050        self.extra
1051            .get("output_text")
1052            .and_then(Value::as_str)
1053            .map(str::to_owned)
1054    }
1055}
1056
1057/// 表示 responses 顶层错误。
1058#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1059pub struct ResponseError {
1060    /// 错误码。
1061    pub code: Option<String>,
1062    /// 错误消息。
1063    pub message: Option<String>,
1064    /// 额外字段。
1065    #[serde(flatten)]
1066    pub extra: BTreeMap<String, Value>,
1067}
1068
1069/// 表示 responses 不完整原因。
1070#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1071pub struct ResponseIncompleteDetails {
1072    /// 不完整原因。
1073    pub reason: Option<String>,
1074    /// 额外字段。
1075    #[serde(flatten)]
1076    pub extra: BTreeMap<String, Value>,
1077}
1078
1079/// 表示 responses 用量明细。
1080#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1081pub struct ResponseUsage {
1082    /// 输入 token 数。
1083    #[serde(default)]
1084    pub input_tokens: u64,
1085    /// 输入 token 明细。
1086    pub input_tokens_details: Option<ResponseInputTokensDetails>,
1087    /// 输出 token 数。
1088    #[serde(default)]
1089    pub output_tokens: u64,
1090    /// 输出 token 明细。
1091    pub output_tokens_details: Option<ResponseOutputTokensDetails>,
1092    /// 总 token 数。
1093    #[serde(default)]
1094    pub total_tokens: u64,
1095    /// 额外字段。
1096    #[serde(flatten)]
1097    pub extra: BTreeMap<String, Value>,
1098}
1099
1100/// 表示 responses 输入 token 明细。
1101#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1102pub struct ResponseInputTokensDetails {
1103    /// cache 命中 token 数。
1104    pub cached_tokens: Option<u64>,
1105    /// 额外字段。
1106    #[serde(flatten)]
1107    pub extra: BTreeMap<String, Value>,
1108}
1109
1110/// 表示 responses 输出 token 明细。
1111#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1112pub struct ResponseOutputTokensDetails {
1113    /// reasoning token 数。
1114    pub reasoning_tokens: Option<u64>,
1115    /// 额外字段。
1116    #[serde(flatten)]
1117    pub extra: BTreeMap<String, Value>,
1118}
1119
1120/// 表示响应输出项。
1121#[derive(Debug, Clone, Serialize, Deserialize)]
1122#[serde(untagged)]
1123pub enum ResponseOutputItem {
1124    /// 已知输出项。
1125    Known(KnownResponseOutputItem),
1126    /// 向前兼容保留的原始项。
1127    Raw(ResponseOutputItemRaw),
1128}
1129
1130impl Default for ResponseOutputItem {
1131    fn default() -> Self {
1132        Self::Raw(ResponseOutputItemRaw::default())
1133    }
1134}
1135
1136impl ResponseOutputItem {
1137    /// 返回消息输出项。
1138    pub fn as_message(&self) -> Option<&ResponseOutputMessage> {
1139        match self {
1140            Self::Known(KnownResponseOutputItem::Message(message)) => Some(message),
1141            _ => None,
1142        }
1143    }
1144
1145    /// 返回函数调用输出项。
1146    pub fn as_function_call(&self) -> Option<&ResponseFunctionToolCall> {
1147        match self {
1148            Self::Known(KnownResponseOutputItem::FunctionCall(call)) => Some(call),
1149            _ => None,
1150        }
1151    }
1152
1153    /// 返回原始 JSON 项。
1154    pub fn as_raw(&self) -> Option<&Value> {
1155        match self {
1156            Self::Raw(value) => Some(value.as_raw()),
1157            _ => None,
1158        }
1159    }
1160
1161    /// 提取输出文本。
1162    pub fn output_text(&self) -> Option<&str> {
1163        match self {
1164            Self::Known(KnownResponseOutputItem::OutputText(text)) => Some(text.text.as_str()),
1165            Self::Known(KnownResponseOutputItem::Message(message)) => message
1166                .content
1167                .iter()
1168                .find_map(ResponseOutputContentPart::text),
1169            Self::Raw(value) => {
1170                let value = value.as_raw();
1171                if let Some(text) = value.get("text").and_then(Value::as_str) {
1172                    return Some(text);
1173                }
1174                value
1175                    .get("content")
1176                    .and_then(Value::as_array)
1177                    .and_then(|content| {
1178                        content
1179                            .iter()
1180                            .find_map(|item| item.get("text").and_then(Value::as_str))
1181                    })
1182            }
1183            _ => None,
1184        }
1185    }
1186}
1187
1188/// 已知的响应输出项类型。
1189#[derive(Debug, Clone, Serialize, Deserialize)]
1190#[serde(tag = "type", rename_all = "snake_case")]
1191pub enum KnownResponseOutputItem {
1192    /// assistant message。
1193    Message(ResponseOutputMessage),
1194    /// function call。
1195    FunctionCall(ResponseFunctionToolCall),
1196    /// 某些兼容 Provider 直接把 `output_text` 作为顶层输出项返回。
1197    OutputText(ResponseOutputText),
1198    /// 某些兼容 Provider 直接把 `refusal` 作为顶层输出项返回。
1199    Refusal(ResponseOutputRefusal),
1200}
1201
1202/// 表示 assistant message 输出。
1203#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1204pub struct ResponseOutputMessage {
1205    /// message ID。
1206    pub id: String,
1207    /// 内容片段。
1208    #[serde(default)]
1209    pub content: Vec<ResponseOutputContentPart>,
1210    /// 角色。
1211    pub role: Option<String>,
1212    /// 状态。
1213    pub status: Option<String>,
1214    /// assistant phase。
1215    pub phase: Option<String>,
1216    /// 额外字段。
1217    #[serde(flatten)]
1218    pub extra: BTreeMap<String, Value>,
1219}
1220
1221/// 表示函数工具调用输出项。
1222#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1223pub struct ResponseFunctionToolCall {
1224    /// 输出项 ID。
1225    pub id: String,
1226    /// tool call ID。
1227    pub call_id: Option<String>,
1228    /// 工具名称。
1229    pub name: Option<String>,
1230    /// 参数 JSON 字符串。
1231    #[serde(default)]
1232    pub arguments: String,
1233    /// 状态。
1234    pub status: Option<String>,
1235    /// 额外字段。
1236    #[serde(flatten)]
1237    pub extra: BTreeMap<String, Value>,
1238}
1239
1240/// 表示 message 中的内容片段。
1241#[derive(Debug, Clone, Serialize, Deserialize)]
1242#[serde(untagged)]
1243pub enum ResponseOutputContentPart {
1244    /// 已知内容片段。
1245    Known(KnownResponseOutputContentPart),
1246    /// 向前兼容保留的原始片段。
1247    Raw(ResponseOutputContentPartRaw),
1248}
1249
1250impl Default for ResponseOutputContentPart {
1251    fn default() -> Self {
1252        Self::Raw(ResponseOutputContentPartRaw::default())
1253    }
1254}
1255
1256impl ResponseOutputContentPart {
1257    /// 返回 output_text 内容片段。
1258    pub fn as_output_text(&self) -> Option<&ResponseOutputText> {
1259        match self {
1260            Self::Known(KnownResponseOutputContentPart::OutputText(text)) => Some(text),
1261            _ => None,
1262        }
1263    }
1264
1265    /// 提取文本内容。
1266    pub fn text(&self) -> Option<&str> {
1267        match self {
1268            Self::Known(KnownResponseOutputContentPart::OutputText(text)) => {
1269                Some(text.text.as_str())
1270            }
1271            Self::Raw(value) => value.as_raw().get("text").and_then(Value::as_str),
1272            _ => None,
1273        }
1274    }
1275}
1276
1277/// 已知的 message 内容片段。
1278#[derive(Debug, Clone, Serialize, Deserialize)]
1279#[serde(tag = "type", rename_all = "snake_case")]
1280pub enum KnownResponseOutputContentPart {
1281    /// 输出文本。
1282    OutputText(ResponseOutputText),
1283    /// 拒绝回答。
1284    Refusal(ResponseOutputRefusal),
1285}
1286
1287/// 表示 output_text 注解中的文件引用。
1288#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1289pub struct ResponseOutputTextFileCitation {
1290    /// 文件 ID。
1291    pub file_id: String,
1292    /// 文件名。
1293    pub filename: String,
1294    /// 文件索引。
1295    pub index: u64,
1296    /// 额外字段。
1297    #[serde(flatten)]
1298    pub extra: BTreeMap<String, Value>,
1299}
1300
1301/// 表示 output_text 注解中的 URL 引用。
1302#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1303pub struct ResponseOutputTextUrlCitation {
1304    /// 引用结束位置。
1305    pub end_index: u64,
1306    /// 引用起始位置。
1307    pub start_index: u64,
1308    /// 标题。
1309    pub title: String,
1310    /// URL。
1311    pub url: String,
1312    /// 额外字段。
1313    #[serde(flatten)]
1314    pub extra: BTreeMap<String, Value>,
1315}
1316
1317/// 表示 output_text 注解中的容器文件引用。
1318#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1319pub struct ResponseOutputTextContainerFileCitation {
1320    /// 容器 ID。
1321    pub container_id: String,
1322    /// 引用结束位置。
1323    pub end_index: u64,
1324    /// 文件 ID。
1325    pub file_id: String,
1326    /// 文件名。
1327    pub filename: String,
1328    /// 引用起始位置。
1329    pub start_index: u64,
1330    /// 额外字段。
1331    #[serde(flatten)]
1332    pub extra: BTreeMap<String, Value>,
1333}
1334
1335/// 表示 output_text 注解中的文件路径。
1336#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1337pub struct ResponseOutputTextFilePath {
1338    /// 文件 ID。
1339    pub file_id: String,
1340    /// 文件索引。
1341    pub index: u64,
1342    /// 额外字段。
1343    #[serde(flatten)]
1344    pub extra: BTreeMap<String, Value>,
1345}
1346
1347/// 已知的 output_text 注解类型。
1348#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1349#[serde(tag = "type", rename_all = "snake_case")]
1350pub enum KnownResponseOutputTextAnnotation {
1351    /// 文件引用。
1352    FileCitation(ResponseOutputTextFileCitation),
1353    /// URL 引用。
1354    UrlCitation(ResponseOutputTextUrlCitation),
1355    /// 容器文件引用。
1356    ContainerFileCitation(ResponseOutputTextContainerFileCitation),
1357    /// 文件路径。
1358    FilePath(ResponseOutputTextFilePath),
1359}
1360
1361/// 向前兼容保留的未知 output_text 注解。
1362#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
1363pub struct ResponseOutputTextAnnotationUnknown {
1364    /// 注解类型。
1365    #[serde(rename = "type")]
1366    pub annotation_type: Option<String>,
1367    /// 额外字段。
1368    #[serde(flatten)]
1369    pub extra: BTreeMap<String, Value>,
1370}
1371
1372/// 表示 output_text 注解。
1373#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1374#[serde(untagged)]
1375pub enum ResponseOutputTextAnnotation {
1376    /// 已知注解。
1377    Known(KnownResponseOutputTextAnnotation),
1378    /// 未知注解。
1379    Unknown(ResponseOutputTextAnnotationUnknown),
1380}
1381
1382impl Default for ResponseOutputTextAnnotation {
1383    fn default() -> Self {
1384        Self::Unknown(ResponseOutputTextAnnotationUnknown::default())
1385    }
1386}
1387
1388impl ResponseOutputTextAnnotation {
1389    /// 返回注解类型。
1390    pub fn kind(&self) -> Option<&str> {
1391        match self {
1392            Self::Known(KnownResponseOutputTextAnnotation::FileCitation(_)) => {
1393                Some("file_citation")
1394            }
1395            Self::Known(KnownResponseOutputTextAnnotation::UrlCitation(_)) => Some("url_citation"),
1396            Self::Known(KnownResponseOutputTextAnnotation::ContainerFileCitation(_)) => {
1397                Some("container_file_citation")
1398            }
1399            Self::Known(KnownResponseOutputTextAnnotation::FilePath(_)) => Some("file_path"),
1400            Self::Unknown(annotation) => annotation.annotation_type.as_deref(),
1401        }
1402    }
1403}
1404
1405/// 表示 output_text 的 top logprob。
1406#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
1407pub struct ResponseOutputTextTopLogprob {
1408    /// token 内容。
1409    #[serde(default)]
1410    pub token: String,
1411    /// UTF-8 bytes。
1412    #[serde(default)]
1413    pub bytes: Vec<u8>,
1414    /// token 对应的 logprob。
1415    #[serde(default)]
1416    pub logprob: f64,
1417    /// 额外字段。
1418    #[serde(flatten)]
1419    pub extra: BTreeMap<String, Value>,
1420}
1421
1422/// 表示 output_text 的单个 token logprob。
1423#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
1424pub struct ResponseOutputTextLogprob {
1425    /// token 内容。
1426    #[serde(default)]
1427    pub token: String,
1428    /// UTF-8 bytes。
1429    #[serde(default)]
1430    pub bytes: Vec<u8>,
1431    /// token 对应的 logprob。
1432    #[serde(default)]
1433    pub logprob: f64,
1434    /// top logprobs。
1435    #[serde(default)]
1436    pub top_logprobs: Vec<ResponseOutputTextTopLogprob>,
1437    /// 额外字段。
1438    #[serde(flatten)]
1439    pub extra: BTreeMap<String, Value>,
1440}
1441
1442/// 表示输出文本片段。
1443#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1444pub struct ResponseOutputText {
1445    /// 注解。
1446    #[serde(default)]
1447    pub annotations: Vec<ResponseOutputTextAnnotation>,
1448    /// 文本。
1449    #[serde(default)]
1450    pub text: String,
1451    /// token 级 logprobs。
1452    pub logprobs: Option<Vec<ResponseOutputTextLogprob>>,
1453    /// 额外字段。
1454    #[serde(flatten)]
1455    pub extra: BTreeMap<String, Value>,
1456}
1457
1458/// 表示拒绝回答片段。
1459#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1460pub struct ResponseOutputRefusal {
1461    /// 拒绝原因。
1462    #[serde(default)]
1463    pub refusal: String,
1464    /// 额外字段。
1465    #[serde(flatten)]
1466    pub extra: BTreeMap<String, Value>,
1467}
1468
1469/// 表示 Responses 创建参数。
1470#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1471pub struct ResponseCreateParams {
1472    /// 模型 ID。
1473    #[serde(skip_serializing_if = "Option::is_none")]
1474    pub model: Option<String>,
1475    /// 输入载荷。
1476    #[serde(skip_serializing_if = "Option::is_none")]
1477    pub input: Option<ResponseInputPayload>,
1478    /// 温度。
1479    #[serde(skip_serializing_if = "Option::is_none")]
1480    pub temperature: Option<f32>,
1481    /// 工具定义。
1482    #[serde(default, skip_serializing_if = "Vec::is_empty")]
1483    pub tools: Vec<ChatToolDefinition>,
1484    /// 是否启用流式。
1485    #[serde(skip_serializing_if = "Option::is_none")]
1486    pub stream: Option<bool>,
1487}
1488
1489fn default_function_type() -> String {
1490    "function".into()
1491}
1492
1493fn parse_jsonish_payload<T>(payload: &str) -> Result<T>
1494where
1495    T: serde::de::DeserializeOwned,
1496{
1497    let trimmed = payload.trim();
1498    let normalized = trimmed
1499        .strip_prefix("```json")
1500        .or_else(|| trimmed.strip_prefix("```"))
1501        .map(|value| value.trim())
1502        .and_then(|value| value.strip_suffix("```"))
1503        .map_or(trimmed, str::trim);
1504    serde_json::from_str(normalized).map_err(|error| {
1505        Error::Serialization(crate::SerializationError::new(format!(
1506            "结构化 JSON 解析失败: {error}"
1507        )))
1508    })
1509}
1510
1511fn parse_json_arguments<T>(arguments: &str) -> Result<T>
1512where
1513    T: serde::de::DeserializeOwned,
1514{
1515    serde_json::from_str(arguments).map_err(|error| {
1516        Error::Serialization(crate::SerializationError::new(format!(
1517            "工具参数 JSON 解析失败: {error}"
1518        )))
1519    })
1520}
1521
1522handle!(
1523    /// Admin 资源命名空间。
1524    AdminResource
1525);
1526handle!(
1527    /// Admin Organization 资源命名空间。
1528    AdminOrganizationResource
1529);
1530handle!(
1531    /// Admin Organization Audit Logs 资源。
1532    AdminOrganizationAuditLogsResource
1533);
1534handle!(
1535    /// Admin Organization Admin API Keys 资源。
1536    AdminOrganizationAdminApiKeysResource
1537);
1538handle!(
1539    /// Admin Organization Usage 资源。
1540    AdminOrganizationUsageResource
1541);
1542handle!(
1543    /// Admin Organization Invites 资源。
1544    AdminOrganizationInvitesResource
1545);
1546handle!(
1547    /// Admin Organization Users 资源。
1548    AdminOrganizationUsersResource
1549);
1550handle!(
1551    /// Admin Organization User Roles 资源。
1552    AdminOrganizationUserRolesResource
1553);
1554handle!(
1555    /// Admin Organization Groups 资源。
1556    AdminOrganizationGroupsResource
1557);
1558handle!(
1559    /// Admin Organization Group Users 资源。
1560    AdminOrganizationGroupUsersResource
1561);
1562handle!(
1563    /// Admin Organization Group Roles 资源。
1564    AdminOrganizationGroupRolesResource
1565);
1566handle!(
1567    /// Admin Organization Roles 资源。
1568    AdminOrganizationRolesResource
1569);
1570handle!(
1571    /// Admin Organization Data Retention 资源。
1572    AdminOrganizationDataRetentionResource
1573);
1574handle!(
1575    /// Admin Organization Spend Alerts 资源。
1576    AdminOrganizationSpendAlertsResource
1577);
1578handle!(
1579    /// Admin Organization Certificates 资源。
1580    AdminOrganizationCertificatesResource
1581);
1582handle!(
1583    /// Admin Organization Projects 资源。
1584    AdminOrganizationProjectsResource
1585);
1586handle!(
1587    /// Admin Project Users 资源。
1588    AdminProjectUsersResource
1589);
1590handle!(
1591    /// Admin Project User Roles 资源。
1592    AdminProjectUserRolesResource
1593);
1594handle!(
1595    /// Admin Project Service Accounts 资源。
1596    AdminProjectServiceAccountsResource
1597);
1598handle!(
1599    /// Admin Project API Keys 资源。
1600    AdminProjectApiKeysResource
1601);
1602handle!(
1603    /// Admin Project Rate Limits 资源。
1604    AdminProjectRateLimitsResource
1605);
1606handle!(
1607    /// Admin Project Model Permissions 资源。
1608    AdminProjectModelPermissionsResource
1609);
1610handle!(
1611    /// Admin Project Hosted Tool Permissions 资源。
1612    AdminProjectHostedToolPermissionsResource
1613);
1614handle!(
1615    /// Admin Project Groups 资源。
1616    AdminProjectGroupsResource
1617);
1618handle!(
1619    /// Admin Project Group Roles 资源。
1620    AdminProjectGroupRolesResource
1621);
1622handle!(
1623    /// Admin Project Roles 资源。
1624    AdminProjectRolesResource
1625);
1626handle!(
1627    /// Admin Project Data Retention 资源。
1628    AdminProjectDataRetentionResource
1629);
1630handle!(
1631    /// Admin Project Spend Alerts 资源。
1632    AdminProjectSpendAlertsResource
1633);
1634handle!(
1635    /// Admin Project Certificates 资源。
1636    AdminProjectCertificatesResource
1637);
1638handle!(
1639    /// 顶层 completions 资源。
1640    CompletionsResource
1641);
1642handle!(
1643    /// 聊天资源命名空间。
1644    ChatResource
1645);
1646handle!(
1647    /// 聊天补全资源。
1648    ChatCompletionsResource
1649);
1650handle!(
1651    /// 聊天补全消息子资源。
1652    ChatCompletionMessagesResource
1653);
1654handle!(
1655    /// Embeddings 资源。
1656    EmbeddingsResource
1657);
1658handle!(
1659    /// Files 资源。
1660    FilesResource
1661);
1662handle!(
1663    /// Images 资源。
1664    ImagesResource
1665);
1666handle!(
1667    /// Audio 资源命名空间。
1668    AudioResource
1669);
1670handle!(
1671    /// Audio Speech 资源。
1672    AudioSpeechResource
1673);
1674handle!(
1675    /// Audio Transcriptions 资源。
1676    AudioTranscriptionsResource
1677);
1678handle!(
1679    /// Audio Translations 资源。
1680    AudioTranslationsResource
1681);
1682handle!(
1683    /// Moderations 资源。
1684    ModerationsResource
1685);
1686handle!(
1687    /// Models 资源。
1688    ModelsResource
1689);
1690handle!(
1691    /// Fine-tuning 资源命名空间。
1692    FineTuningResource
1693);
1694handle!(
1695    /// Fine-tuning Jobs 资源。
1696    FineTuningJobsResource
1697);
1698handle!(
1699    /// Fine-tuning Checkpoints 资源。
1700    FineTuningJobCheckpointsResource
1701);
1702handle!(
1703    /// Fine-tuning 权限资源。
1704    FineTuningCheckpointPermissionsResource
1705);
1706handle!(
1707    /// Fine-tuning Alpha 命名空间。
1708    FineTuningAlphaResource
1709);
1710handle!(
1711    /// Fine-tuning Alpha Graders 资源。
1712    FineTuningAlphaGradersResource
1713);
1714handle!(
1715    /// Graders 资源命名空间。
1716    GradersResource
1717);
1718handle!(
1719    /// Vector Stores 资源。
1720    VectorStoresResource
1721);
1722handle!(
1723    /// Vector Store Files 资源。
1724    VectorStoreFilesResource
1725);
1726handle!(
1727    /// Vector Store File Batches 资源。
1728    VectorStoreFileBatchesResource
1729);
1730handle!(
1731    /// Batches 资源。
1732    BatchesResource
1733);
1734handle!(
1735    /// Uploads 资源。
1736    UploadsResource
1737);
1738handle!(
1739    /// Uploads Parts 资源。
1740    UploadPartsResource
1741);
1742handle!(
1743    /// Responses 资源。
1744    ResponsesResource
1745);
1746handle!(
1747    /// Responses Input Items 资源。
1748    ResponseInputItemsResource
1749);
1750handle!(
1751    /// Responses Input Tokens 资源。
1752    ResponseInputTokensResource
1753);
1754handle!(
1755    /// Realtime 资源命名空间。
1756    RealtimeResource
1757);
1758handle!(
1759    /// Realtime Client Secrets 资源。
1760    RealtimeClientSecretsResource
1761);
1762handle!(
1763    /// Realtime Calls 资源。
1764    RealtimeCallsResource
1765);
1766handle!(
1767    /// Conversations 资源。
1768    ConversationsResource
1769);
1770handle!(
1771    /// Conversation Items 资源。
1772    ConversationItemsResource
1773);
1774handle!(
1775    /// Evals 资源。
1776    EvalsResource
1777);
1778handle!(
1779    /// Eval Runs 资源。
1780    EvalRunsResource
1781);
1782handle!(
1783    /// Eval Run Output Items 资源。
1784    EvalRunOutputItemsResource
1785);
1786handle!(
1787    /// Containers 资源。
1788    ContainersResource
1789);
1790handle!(
1791    /// Container Files 资源。
1792    ContainerFilesResource
1793);
1794handle!(
1795    /// Container File Content 资源。
1796    ContainerFilesContentResource
1797);
1798handle!(
1799    /// Skills 资源。
1800    SkillsResource
1801);
1802handle!(
1803    /// Skills Content 资源。
1804    SkillsContentResource
1805);
1806handle!(
1807    /// Skills Versions 资源。
1808    SkillVersionsResource
1809);
1810handle!(
1811    /// Skills Versions Content 资源。
1812    SkillVersionsContentResource
1813);
1814handle!(
1815    /// Videos 资源。
1816    VideosResource
1817);
1818handle!(
1819    /// Webhooks 资源。
1820    WebhooksResource
1821);
1822handle!(
1823    /// Beta 资源命名空间。
1824    BetaResource
1825);
1826handle!(
1827    /// Beta Assistants 资源。
1828    BetaAssistantsResource
1829);
1830handle!(
1831    /// Beta Threads 资源。
1832    BetaThreadsResource
1833);
1834handle!(
1835    /// Beta Thread Messages 资源。
1836    BetaThreadMessagesResource
1837);
1838handle!(
1839    /// Beta Thread Runs 资源。
1840    BetaThreadRunsResource
1841);
1842handle!(
1843    /// Beta Thread Run Steps 资源。
1844    BetaThreadRunStepsResource
1845);
1846handle!(
1847    /// Beta ChatKit 命名空间。
1848    BetaChatkitResource
1849);
1850handle!(
1851    /// Beta ChatKit Sessions 资源。
1852    BetaChatkitSessionsResource
1853);
1854handle!(
1855    /// Beta ChatKit Threads 资源。
1856    BetaChatkitThreadsResource
1857);
1858handle!(
1859    /// Beta Realtime 命名空间。
1860    BetaRealtimeResource
1861);
1862handle!(
1863    /// Beta Realtime Sessions 资源。
1864    BetaRealtimeSessionsResource
1865);
1866handle!(
1867    /// Beta Realtime Transcription Sessions 资源。
1868    BetaRealtimeTranscriptionSessionsResource
1869);