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/// 表示 MCP 工具定义。
972#[derive(Debug, Clone, Serialize, Deserialize)]
973pub struct McpToolDefinition {
974    /// 工具类型,固定为 `mcp`。
975    #[serde(rename = "type", default = "default_mcp_tool_type")]
976    pub tool_type: String,
977    /// MCP server 标签,用于工具调用中标识该 server。
978    pub server_label: String,
979    /// 允许调用的工具名列表或过滤对象。
980    #[serde(skip_serializing_if = "Option::is_none")]
981    pub allowed_tools: Option<JsonPayload>,
982    /// 远程 MCP server 或 service connector 的 OAuth access token。
983    #[serde(skip_serializing_if = "Option::is_none")]
984    pub authorization: Option<String>,
985    /// ChatGPT service connector ID。
986    #[serde(skip_serializing_if = "Option::is_none")]
987    pub connector_id: Option<String>,
988    /// 是否延迟发现工具。
989    #[serde(skip_serializing_if = "Option::is_none")]
990    pub defer_loading: Option<bool>,
991    /// 发往 MCP server 的可选 HTTP 头。
992    #[serde(skip_serializing_if = "Option::is_none")]
993    pub headers: Option<BTreeMap<String, String>>,
994    /// 需要审批的工具过滤规则,或 `always` / `never`。
995    #[serde(skip_serializing_if = "Option::is_none")]
996    pub require_approval: Option<JsonPayload>,
997    /// MCP server 描述。
998    #[serde(skip_serializing_if = "Option::is_none")]
999    pub server_description: Option<String>,
1000    /// MCP server URL。
1001    #[serde(skip_serializing_if = "Option::is_none")]
1002    pub server_url: Option<String>,
1003    /// Secure MCP Tunnel ID。可替代 `server_url` 或 `connector_id`。
1004    #[serde(skip_serializing_if = "Option::is_none")]
1005    pub tunnel_id: Option<String>,
1006    /// 额外字段。
1007    #[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    /// 创建 MCP 工具定义。
1032    pub fn new(server_label: impl Into<String>) -> Self {
1033        Self {
1034            server_label: server_label.into(),
1035            ..Self::default()
1036        }
1037    }
1038
1039    /// 设置允许调用的工具名列表或过滤对象。
1040    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    /// 设置允许调用的工具名列表。
1046    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    /// 设置 OAuth access token。
1064    pub fn authorization(mut self, authorization: impl Into<String>) -> Self {
1065        self.authorization = Some(authorization.into());
1066        self
1067    }
1068
1069    /// 设置 service connector ID。
1070    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    /// 设置是否延迟发现工具。
1076    pub fn defer_loading(mut self, defer_loading: bool) -> Self {
1077        self.defer_loading = Some(defer_loading);
1078        self
1079    }
1080
1081    /// 设置 HTTP header。
1082    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    /// 设置需要审批的工具过滤规则,或 `always` / `never`。
1090    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    /// 设置需要审批的模式,常用值为 `always` 或 `never`。
1096    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    /// 设置 MCP server 描述。
1102    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    /// 设置 MCP server URL。
1108    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    /// 设置 Secure MCP Tunnel ID。
1114    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    /// 添加额外字段。
1120    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/// 表示聊天工具函数定义。
1127#[derive(Debug, Clone, Serialize, Deserialize)]
1128pub struct ChatToolFunction {
1129    /// 函数名。
1130    pub name: String,
1131    /// 函数描述。
1132    pub description: Option<String>,
1133    /// 参数 Schema。
1134    pub parameters: JsonPayload,
1135}
1136
1137/// 表示聊天补全请求参数。
1138#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1139pub struct ChatCompletionCreateParams {
1140    /// 模型 ID。
1141    #[serde(skip_serializing_if = "Option::is_none")]
1142    pub model: Option<String>,
1143    /// 历史消息。
1144    #[serde(default, skip_serializing_if = "Vec::is_empty")]
1145    pub messages: Vec<ChatCompletionMessage>,
1146    /// 温度。
1147    #[serde(skip_serializing_if = "Option::is_none")]
1148    pub temperature: Option<f32>,
1149    /// 候选数量。
1150    #[serde(skip_serializing_if = "Option::is_none")]
1151    pub n: Option<u32>,
1152    /// 最大 token 数。
1153    #[serde(skip_serializing_if = "Option::is_none")]
1154    pub max_tokens: Option<u32>,
1155    /// 工具定义。
1156    #[serde(default, skip_serializing_if = "Vec::is_empty")]
1157    pub tools: Vec<ChatToolDefinition>,
1158    /// 工具选择策略。
1159    #[serde(skip_serializing_if = "Option::is_none")]
1160    pub tool_choice: Option<ChatToolChoice>,
1161    /// 流式开关。
1162    #[serde(skip_serializing_if = "Option::is_none")]
1163    pub stream: Option<bool>,
1164}
1165
1166/// 表示 Responses 对象。
1167#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1168pub struct Response {
1169    /// 响应 ID。
1170    pub id: String,
1171    /// 创建时间。
1172    pub created_at: Option<u64>,
1173    /// 对象类型。
1174    #[serde(default)]
1175    pub object: String,
1176    /// 模型 ID。
1177    pub model: Option<String>,
1178    /// 状态。
1179    pub status: Option<String>,
1180    /// 错误信息。
1181    pub error: Option<ResponseError>,
1182    /// 不完整原因。
1183    pub incomplete_details: Option<ResponseIncompleteDetails>,
1184    /// 元数据。
1185    pub metadata: Option<BTreeMap<String, String>>,
1186    /// 输出项。
1187    #[serde(default)]
1188    pub output: Vec<ResponseOutputItem>,
1189    /// 用量统计。
1190    pub usage: Option<ResponseUsage>,
1191    /// 额外字段。
1192    #[serde(flatten)]
1193    pub extra: BTreeMap<String, Value>,
1194}
1195
1196impl Response {
1197    /// 尝试提取最终文本输出。
1198    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/// 表示 responses 顶层错误。
1213#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1214pub struct ResponseError {
1215    /// 错误码。
1216    pub code: Option<String>,
1217    /// 错误消息。
1218    pub message: Option<String>,
1219    /// 额外字段。
1220    #[serde(flatten)]
1221    pub extra: BTreeMap<String, Value>,
1222}
1223
1224/// 表示 responses 不完整原因。
1225#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1226pub struct ResponseIncompleteDetails {
1227    /// 不完整原因。
1228    pub reason: Option<String>,
1229    /// 额外字段。
1230    #[serde(flatten)]
1231    pub extra: BTreeMap<String, Value>,
1232}
1233
1234/// 表示 responses 用量明细。
1235#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1236pub struct ResponseUsage {
1237    /// 输入 token 数。
1238    #[serde(default)]
1239    pub input_tokens: u64,
1240    /// 输入 token 明细。
1241    pub input_tokens_details: Option<ResponseInputTokensDetails>,
1242    /// 输出 token 数。
1243    #[serde(default)]
1244    pub output_tokens: u64,
1245    /// 输出 token 明细。
1246    pub output_tokens_details: Option<ResponseOutputTokensDetails>,
1247    /// 总 token 数。
1248    #[serde(default)]
1249    pub total_tokens: u64,
1250    /// 额外字段。
1251    #[serde(flatten)]
1252    pub extra: BTreeMap<String, Value>,
1253}
1254
1255/// 表示 responses 输入 token 明细。
1256#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1257pub struct ResponseInputTokensDetails {
1258    /// cache 命中 token 数。
1259    pub cached_tokens: Option<u64>,
1260    /// 额外字段。
1261    #[serde(flatten)]
1262    pub extra: BTreeMap<String, Value>,
1263}
1264
1265/// 表示 responses 输出 token 明细。
1266#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1267pub struct ResponseOutputTokensDetails {
1268    /// reasoning token 数。
1269    pub reasoning_tokens: Option<u64>,
1270    /// 额外字段。
1271    #[serde(flatten)]
1272    pub extra: BTreeMap<String, Value>,
1273}
1274
1275/// 表示响应输出项。
1276#[derive(Debug, Clone, Serialize, Deserialize)]
1277#[serde(untagged)]
1278pub enum ResponseOutputItem {
1279    /// 已知输出项。
1280    Known(KnownResponseOutputItem),
1281    /// 向前兼容保留的原始项。
1282    Raw(ResponseOutputItemRaw),
1283}
1284
1285impl Default for ResponseOutputItem {
1286    fn default() -> Self {
1287        Self::Raw(ResponseOutputItemRaw::default())
1288    }
1289}
1290
1291impl ResponseOutputItem {
1292    /// 返回消息输出项。
1293    pub fn as_message(&self) -> Option<&ResponseOutputMessage> {
1294        match self {
1295            Self::Known(KnownResponseOutputItem::Message(message)) => Some(message),
1296            _ => None,
1297        }
1298    }
1299
1300    /// 返回函数调用输出项。
1301    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    /// 返回原始 JSON 项。
1309    pub fn as_raw(&self) -> Option<&Value> {
1310        match self {
1311            Self::Raw(value) => Some(value.as_raw()),
1312            _ => None,
1313        }
1314    }
1315
1316    /// 提取输出文本。
1317    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/// 已知的响应输出项类型。
1344#[derive(Debug, Clone, Serialize, Deserialize)]
1345#[serde(tag = "type", rename_all = "snake_case")]
1346pub enum KnownResponseOutputItem {
1347    /// assistant message。
1348    Message(ResponseOutputMessage),
1349    /// function call。
1350    FunctionCall(ResponseFunctionToolCall),
1351    /// 某些兼容 Provider 直接把 `output_text` 作为顶层输出项返回。
1352    OutputText(ResponseOutputText),
1353    /// 某些兼容 Provider 直接把 `refusal` 作为顶层输出项返回。
1354    Refusal(ResponseOutputRefusal),
1355}
1356
1357/// 表示 assistant message 输出。
1358#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1359pub struct ResponseOutputMessage {
1360    /// message ID。
1361    pub id: String,
1362    /// 内容片段。
1363    #[serde(default)]
1364    pub content: Vec<ResponseOutputContentPart>,
1365    /// 角色。
1366    pub role: Option<String>,
1367    /// 状态。
1368    pub status: Option<String>,
1369    /// assistant phase。
1370    pub phase: Option<String>,
1371    /// 额外字段。
1372    #[serde(flatten)]
1373    pub extra: BTreeMap<String, Value>,
1374}
1375
1376/// 表示函数工具调用输出项。
1377#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1378pub struct ResponseFunctionToolCall {
1379    /// 输出项 ID。
1380    pub id: String,
1381    /// tool call ID。
1382    pub call_id: Option<String>,
1383    /// 工具名称。
1384    pub name: Option<String>,
1385    /// 参数 JSON 字符串。
1386    #[serde(default)]
1387    pub arguments: String,
1388    /// 状态。
1389    pub status: Option<String>,
1390    /// 额外字段。
1391    #[serde(flatten)]
1392    pub extra: BTreeMap<String, Value>,
1393}
1394
1395/// 表示 message 中的内容片段。
1396#[derive(Debug, Clone, Serialize, Deserialize)]
1397#[serde(untagged)]
1398pub enum ResponseOutputContentPart {
1399    /// 已知内容片段。
1400    Known(KnownResponseOutputContentPart),
1401    /// 向前兼容保留的原始片段。
1402    Raw(ResponseOutputContentPartRaw),
1403}
1404
1405impl Default for ResponseOutputContentPart {
1406    fn default() -> Self {
1407        Self::Raw(ResponseOutputContentPartRaw::default())
1408    }
1409}
1410
1411impl ResponseOutputContentPart {
1412    /// 返回 output_text 内容片段。
1413    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    /// 提取文本内容。
1421    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/// 已知的 message 内容片段。
1433#[derive(Debug, Clone, Serialize, Deserialize)]
1434#[serde(tag = "type", rename_all = "snake_case")]
1435pub enum KnownResponseOutputContentPart {
1436    /// 输出文本。
1437    OutputText(ResponseOutputText),
1438    /// 拒绝回答。
1439    Refusal(ResponseOutputRefusal),
1440}
1441
1442/// 表示 output_text 注解中的文件引用。
1443#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1444pub struct ResponseOutputTextFileCitation {
1445    /// 文件 ID。
1446    pub file_id: String,
1447    /// 文件名。
1448    pub filename: String,
1449    /// 文件索引。
1450    pub index: u64,
1451    /// 额外字段。
1452    #[serde(flatten)]
1453    pub extra: BTreeMap<String, Value>,
1454}
1455
1456/// 表示 output_text 注解中的 URL 引用。
1457#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1458pub struct ResponseOutputTextUrlCitation {
1459    /// 引用结束位置。
1460    pub end_index: u64,
1461    /// 引用起始位置。
1462    pub start_index: u64,
1463    /// 标题。
1464    pub title: String,
1465    /// URL。
1466    pub url: String,
1467    /// 额外字段。
1468    #[serde(flatten)]
1469    pub extra: BTreeMap<String, Value>,
1470}
1471
1472/// 表示 output_text 注解中的容器文件引用。
1473#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1474pub struct ResponseOutputTextContainerFileCitation {
1475    /// 容器 ID。
1476    pub container_id: String,
1477    /// 引用结束位置。
1478    pub end_index: u64,
1479    /// 文件 ID。
1480    pub file_id: String,
1481    /// 文件名。
1482    pub filename: String,
1483    /// 引用起始位置。
1484    pub start_index: u64,
1485    /// 额外字段。
1486    #[serde(flatten)]
1487    pub extra: BTreeMap<String, Value>,
1488}
1489
1490/// 表示 output_text 注解中的文件路径。
1491#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1492pub struct ResponseOutputTextFilePath {
1493    /// 文件 ID。
1494    pub file_id: String,
1495    /// 文件索引。
1496    pub index: u64,
1497    /// 额外字段。
1498    #[serde(flatten)]
1499    pub extra: BTreeMap<String, Value>,
1500}
1501
1502/// 已知的 output_text 注解类型。
1503#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1504#[serde(tag = "type", rename_all = "snake_case")]
1505pub enum KnownResponseOutputTextAnnotation {
1506    /// 文件引用。
1507    FileCitation(ResponseOutputTextFileCitation),
1508    /// URL 引用。
1509    UrlCitation(ResponseOutputTextUrlCitation),
1510    /// 容器文件引用。
1511    ContainerFileCitation(ResponseOutputTextContainerFileCitation),
1512    /// 文件路径。
1513    FilePath(ResponseOutputTextFilePath),
1514}
1515
1516/// 向前兼容保留的未知 output_text 注解。
1517#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
1518pub struct ResponseOutputTextAnnotationUnknown {
1519    /// 注解类型。
1520    #[serde(rename = "type")]
1521    pub annotation_type: Option<String>,
1522    /// 额外字段。
1523    #[serde(flatten)]
1524    pub extra: BTreeMap<String, Value>,
1525}
1526
1527/// 表示 output_text 注解。
1528#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1529#[serde(untagged)]
1530pub enum ResponseOutputTextAnnotation {
1531    /// 已知注解。
1532    Known(KnownResponseOutputTextAnnotation),
1533    /// 未知注解。
1534    Unknown(ResponseOutputTextAnnotationUnknown),
1535}
1536
1537impl Default for ResponseOutputTextAnnotation {
1538    fn default() -> Self {
1539        Self::Unknown(ResponseOutputTextAnnotationUnknown::default())
1540    }
1541}
1542
1543impl ResponseOutputTextAnnotation {
1544    /// 返回注解类型。
1545    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/// 表示 output_text 的 top logprob。
1561#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
1562pub struct ResponseOutputTextTopLogprob {
1563    /// token 内容。
1564    #[serde(default)]
1565    pub token: String,
1566    /// UTF-8 bytes。
1567    #[serde(default)]
1568    pub bytes: Vec<u8>,
1569    /// token 对应的 logprob。
1570    #[serde(default)]
1571    pub logprob: f64,
1572    /// 额外字段。
1573    #[serde(flatten)]
1574    pub extra: BTreeMap<String, Value>,
1575}
1576
1577/// 表示 output_text 的单个 token logprob。
1578#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
1579pub struct ResponseOutputTextLogprob {
1580    /// token 内容。
1581    #[serde(default)]
1582    pub token: String,
1583    /// UTF-8 bytes。
1584    #[serde(default)]
1585    pub bytes: Vec<u8>,
1586    /// token 对应的 logprob。
1587    #[serde(default)]
1588    pub logprob: f64,
1589    /// top logprobs。
1590    #[serde(default)]
1591    pub top_logprobs: Vec<ResponseOutputTextTopLogprob>,
1592    /// 额外字段。
1593    #[serde(flatten)]
1594    pub extra: BTreeMap<String, Value>,
1595}
1596
1597/// 表示输出文本片段。
1598#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1599pub struct ResponseOutputText {
1600    /// 注解。
1601    #[serde(default)]
1602    pub annotations: Vec<ResponseOutputTextAnnotation>,
1603    /// 文本。
1604    #[serde(default)]
1605    pub text: String,
1606    /// token 级 logprobs。
1607    pub logprobs: Option<Vec<ResponseOutputTextLogprob>>,
1608    /// 额外字段。
1609    #[serde(flatten)]
1610    pub extra: BTreeMap<String, Value>,
1611}
1612
1613/// 表示拒绝回答片段。
1614#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1615pub struct ResponseOutputRefusal {
1616    /// 拒绝原因。
1617    #[serde(default)]
1618    pub refusal: String,
1619    /// 额外字段。
1620    #[serde(flatten)]
1621    pub extra: BTreeMap<String, Value>,
1622}
1623
1624/// 表示 Responses 创建参数。
1625#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1626pub struct ResponseCreateParams {
1627    /// 模型 ID。
1628    #[serde(skip_serializing_if = "Option::is_none")]
1629    pub model: Option<String>,
1630    /// 输入载荷。
1631    #[serde(skip_serializing_if = "Option::is_none")]
1632    pub input: Option<ResponseInputPayload>,
1633    /// 温度。
1634    #[serde(skip_serializing_if = "Option::is_none")]
1635    pub temperature: Option<f32>,
1636    /// 工具定义。
1637    #[serde(default, skip_serializing_if = "Vec::is_empty")]
1638    pub tools: Vec<ChatToolDefinition>,
1639    /// 是否启用流式。
1640    #[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    /// Admin 资源命名空间。
1683    AdminResource
1684);
1685handle!(
1686    /// Admin Organization 资源命名空间。
1687    AdminOrganizationResource
1688);
1689handle!(
1690    /// Admin Organization Audit Logs 资源。
1691    AdminOrganizationAuditLogsResource
1692);
1693handle!(
1694    /// Admin Organization Admin API Keys 资源。
1695    AdminOrganizationAdminApiKeysResource
1696);
1697handle!(
1698    /// Admin Organization Usage 资源。
1699    AdminOrganizationUsageResource
1700);
1701handle!(
1702    /// Admin Organization Invites 资源。
1703    AdminOrganizationInvitesResource
1704);
1705handle!(
1706    /// Admin Organization Users 资源。
1707    AdminOrganizationUsersResource
1708);
1709handle!(
1710    /// Admin Organization User Roles 资源。
1711    AdminOrganizationUserRolesResource
1712);
1713handle!(
1714    /// Admin Organization Groups 资源。
1715    AdminOrganizationGroupsResource
1716);
1717handle!(
1718    /// Admin Organization Group Users 资源。
1719    AdminOrganizationGroupUsersResource
1720);
1721handle!(
1722    /// Admin Organization Group Roles 资源。
1723    AdminOrganizationGroupRolesResource
1724);
1725handle!(
1726    /// Admin Organization Roles 资源。
1727    AdminOrganizationRolesResource
1728);
1729handle!(
1730    /// Admin Organization Data Retention 资源。
1731    AdminOrganizationDataRetentionResource
1732);
1733handle!(
1734    /// Admin Organization Spend Alerts 资源。
1735    AdminOrganizationSpendAlertsResource
1736);
1737handle!(
1738    /// Admin Organization Certificates 资源。
1739    AdminOrganizationCertificatesResource
1740);
1741handle!(
1742    /// Admin Organization Projects 资源。
1743    AdminOrganizationProjectsResource
1744);
1745handle!(
1746    /// Admin Project Users 资源。
1747    AdminProjectUsersResource
1748);
1749handle!(
1750    /// Admin Project User Roles 资源。
1751    AdminProjectUserRolesResource
1752);
1753handle!(
1754    /// Admin Project Service Accounts 资源。
1755    AdminProjectServiceAccountsResource
1756);
1757handle!(
1758    /// Admin Project API Keys 资源。
1759    AdminProjectApiKeysResource
1760);
1761handle!(
1762    /// Admin Project Rate Limits 资源。
1763    AdminProjectRateLimitsResource
1764);
1765handle!(
1766    /// Admin Project Model Permissions 资源。
1767    AdminProjectModelPermissionsResource
1768);
1769handle!(
1770    /// Admin Project Hosted Tool Permissions 资源。
1771    AdminProjectHostedToolPermissionsResource
1772);
1773handle!(
1774    /// Admin Project Groups 资源。
1775    AdminProjectGroupsResource
1776);
1777handle!(
1778    /// Admin Project Group Roles 资源。
1779    AdminProjectGroupRolesResource
1780);
1781handle!(
1782    /// Admin Project Roles 资源。
1783    AdminProjectRolesResource
1784);
1785handle!(
1786    /// Admin Project Data Retention 资源。
1787    AdminProjectDataRetentionResource
1788);
1789handle!(
1790    /// Admin Project Spend Alerts 资源。
1791    AdminProjectSpendAlertsResource
1792);
1793handle!(
1794    /// Admin Project Certificates 资源。
1795    AdminProjectCertificatesResource
1796);
1797handle!(
1798    /// 顶层 completions 资源。
1799    CompletionsResource
1800);
1801handle!(
1802    /// 聊天资源命名空间。
1803    ChatResource
1804);
1805handle!(
1806    /// 聊天补全资源。
1807    ChatCompletionsResource
1808);
1809handle!(
1810    /// 聊天补全消息子资源。
1811    ChatCompletionMessagesResource
1812);
1813handle!(
1814    /// Embeddings 资源。
1815    EmbeddingsResource
1816);
1817handle!(
1818    /// Files 资源。
1819    FilesResource
1820);
1821handle!(
1822    /// Images 资源。
1823    ImagesResource
1824);
1825handle!(
1826    /// Audio 资源命名空间。
1827    AudioResource
1828);
1829handle!(
1830    /// Audio Speech 资源。
1831    AudioSpeechResource
1832);
1833handle!(
1834    /// Audio Transcriptions 资源。
1835    AudioTranscriptionsResource
1836);
1837handle!(
1838    /// Audio Translations 资源。
1839    AudioTranslationsResource
1840);
1841handle!(
1842    /// Moderations 资源。
1843    ModerationsResource
1844);
1845handle!(
1846    /// Models 资源。
1847    ModelsResource
1848);
1849handle!(
1850    /// Fine-tuning 资源命名空间。
1851    FineTuningResource
1852);
1853handle!(
1854    /// Fine-tuning Jobs 资源。
1855    FineTuningJobsResource
1856);
1857handle!(
1858    /// Fine-tuning Checkpoints 资源。
1859    FineTuningJobCheckpointsResource
1860);
1861handle!(
1862    /// Fine-tuning 权限资源。
1863    FineTuningCheckpointPermissionsResource
1864);
1865handle!(
1866    /// Fine-tuning Alpha 命名空间。
1867    FineTuningAlphaResource
1868);
1869handle!(
1870    /// Fine-tuning Alpha Graders 资源。
1871    FineTuningAlphaGradersResource
1872);
1873handle!(
1874    /// Graders 资源命名空间。
1875    GradersResource
1876);
1877handle!(
1878    /// Vector Stores 资源。
1879    VectorStoresResource
1880);
1881handle!(
1882    /// Vector Store Files 资源。
1883    VectorStoreFilesResource
1884);
1885handle!(
1886    /// Vector Store File Batches 资源。
1887    VectorStoreFileBatchesResource
1888);
1889handle!(
1890    /// Batches 资源。
1891    BatchesResource
1892);
1893handle!(
1894    /// Uploads 资源。
1895    UploadsResource
1896);
1897handle!(
1898    /// Uploads Parts 资源。
1899    UploadPartsResource
1900);
1901handle!(
1902    /// Responses 资源。
1903    ResponsesResource
1904);
1905handle!(
1906    /// Responses Input Items 资源。
1907    ResponseInputItemsResource
1908);
1909handle!(
1910    /// Responses Input Tokens 资源。
1911    ResponseInputTokensResource
1912);
1913handle!(
1914    /// Realtime 资源命名空间。
1915    RealtimeResource
1916);
1917handle!(
1918    /// Realtime Client Secrets 资源。
1919    RealtimeClientSecretsResource
1920);
1921handle!(
1922    /// Realtime Calls 资源。
1923    RealtimeCallsResource
1924);
1925handle!(
1926    /// Conversations 资源。
1927    ConversationsResource
1928);
1929handle!(
1930    /// Conversation Items 资源。
1931    ConversationItemsResource
1932);
1933handle!(
1934    /// Evals 资源。
1935    EvalsResource
1936);
1937handle!(
1938    /// Eval Runs 资源。
1939    EvalRunsResource
1940);
1941handle!(
1942    /// Eval Run Output Items 资源。
1943    EvalRunOutputItemsResource
1944);
1945handle!(
1946    /// Containers 资源。
1947    ContainersResource
1948);
1949handle!(
1950    /// Container Files 资源。
1951    ContainerFilesResource
1952);
1953handle!(
1954    /// Container File Content 资源。
1955    ContainerFilesContentResource
1956);
1957handle!(
1958    /// Skills 资源。
1959    SkillsResource
1960);
1961handle!(
1962    /// Skills Content 资源。
1963    SkillsContentResource
1964);
1965handle!(
1966    /// Skills Versions 资源。
1967    SkillVersionsResource
1968);
1969handle!(
1970    /// Skills Versions Content 资源。
1971    SkillVersionsContentResource
1972);
1973handle!(
1974    /// Videos 资源。
1975    VideosResource
1976);
1977handle!(
1978    /// Webhooks 资源。
1979    WebhooksResource
1980);
1981handle!(
1982    /// Beta 资源命名空间。
1983    BetaResource
1984);
1985handle!(
1986    /// Beta Assistants 资源。
1987    BetaAssistantsResource
1988);
1989handle!(
1990    /// Beta Threads 资源。
1991    BetaThreadsResource
1992);
1993handle!(
1994    /// Beta Thread Messages 资源。
1995    BetaThreadMessagesResource
1996);
1997handle!(
1998    /// Beta Thread Runs 资源。
1999    BetaThreadRunsResource
2000);
2001handle!(
2002    /// Beta Thread Run Steps 资源。
2003    BetaThreadRunStepsResource
2004);
2005handle!(
2006    /// Beta ChatKit 命名空间。
2007    BetaChatkitResource
2008);
2009handle!(
2010    /// Beta ChatKit Sessions 资源。
2011    BetaChatkitSessionsResource
2012);
2013handle!(
2014    /// Beta ChatKit Threads 资源。
2015    BetaChatkitThreadsResource
2016);
2017handle!(
2018    /// Beta Realtime 命名空间。
2019    BetaRealtimeResource
2020);
2021handle!(
2022    /// Beta Realtime Sessions 资源。
2023    BetaRealtimeSessionsResource
2024);
2025handle!(
2026    /// Beta Realtime Transcription Sessions 资源。
2027    BetaRealtimeTranscriptionSessionsResource
2028);