Skip to main content

openai_core/resources/
mod.rs

1//! 资源命名空间、公开类型与请求构建器。
2
3mod audio;
4mod batches;
5mod beta;
6mod chat;
7mod common;
8mod containers;
9mod conversations;
10mod core;
11mod evals;
12mod files;
13mod fine_tuning;
14mod images;
15mod longtail;
16mod responses;
17mod skills;
18mod uploads;
19mod vector_stores;
20mod videos;
21mod webhooks;
22
23use std::collections::BTreeMap;
24
25use serde::{Deserialize, Serialize};
26use serde_json::Value;
27
28use crate::Client;
29use crate::error::{Error, Result};
30#[cfg(feature = "tool-runner")]
31use crate::helpers::ToolDefinition;
32use crate::json_payload::JsonPayload;
33
34pub use beta::{
35    BetaAssistant, BetaAssistantTool, BetaRealtimeSession, BetaRealtimeTranscriptionSession,
36    BetaThread, BetaThreadMessage, BetaThreadMessageContent, BetaThreadRun,
37    BetaThreadRunIncompleteDetails, BetaThreadRunLastError, BetaThreadRunRequiredAction,
38    BetaThreadRunRequiredActionFunction, BetaThreadRunRequiredActionFunctionToolCall,
39    BetaThreadRunRequiredActionSubmitToolOutputs, BetaThreadRunStep, BetaThreadRunStepDetails,
40    BetaThreadRunTool, BetaThreadRunUsage, BetaThreadToolResources, ChatKitConfiguration,
41    ChatKitRateLimits, ChatKitSession, ChatKitThread, ChatKitThreadContent, ChatKitThreadItem,
42    ChatKitThreadStatus, ChatKitWorkflow,
43};
44#[cfg(feature = "structured-output")]
45pub use chat::ChatCompletionParseRequestBuilder;
46pub use chat::{
47    AssistantStreamRequestBuilder, ChatCompletionCreateRequestBuilder, ChatCompletionStoreMessage,
48    ChatCompletionStreamRequestBuilder,
49};
50#[cfg(feature = "tool-runner")]
51pub use chat::{
52    ChatCompletionRunToolsRequestBuilder, ChatCompletionRunner, ChatCompletionStreamingRunner,
53    ChatCompletionToolResult,
54};
55pub use common::{
56    BytesRequestBuilder, JsonRequestBuilder, ListRequestBuilder, NoContentRequestBuilder,
57};
58pub(crate) use common::{
59    TypedJsonRequestState, encode_path_segment, metadata_is_empty, value_from,
60};
61pub use core::{
62    Completion, CompletionChoice, CompletionLogProbs, CompletionUsage,
63    CompletionUsageCompletionTokensDetails, CompletionUsagePromptTokensDetails,
64    ModerationCreateResponse, ModerationResult,
65};
66pub use fine_tuning::{
67    GraderModel, GraderModelCatalog, GraderRunErrors, GraderRunMetadata, GraderRunResponse,
68    GraderValidateResponse,
69};
70pub use longtail::{
71    AudioSpeechCreateParams, AudioSpeechRequestBuilder, AudioTranscription,
72    AudioTranscriptionRequestBuilder, AudioTranscriptionSegment, AudioTranscriptionSegmentId,
73    AudioTranscriptionWord, AudioTranslation, AudioTranslationRequestBuilder, Batch,
74    BatchCreateParams, BatchCreateRequestBuilder, BatchError, BatchErrors, BatchRequestCounts,
75    BatchUsage, BatchUsageInputTokensDetails, BatchUsageOutputTokensDetails, Container,
76    ContainerCreateParams, ContainerExpiresAfter, ContainerFile, ContainerFileCreateParams,
77    Conversation, ConversationContentPart, ConversationCreateParams, ConversationInputItem,
78    ConversationItem, ConversationItemCreateParams, ConversationUpdateParams, Eval,
79    EvalCreateParams, EvalDataSourceConfig, EvalOutput, EvalOutputItem, EvalRun,
80    EvalRunCreateParams, EvalRunInput, EvalTestingCriterion, EvalUpdateParams,
81    FineTuningCheckpoint, FineTuningCheckpointPermission, FineTuningHyperparameterValue,
82    FineTuningJob, FineTuningJobCreateParams, FineTuningJobCreateRequestBuilder,
83    FineTuningJobError, FineTuningJobEvent, FineTuningJobHyperparameters, FineTuningJobIntegration,
84    FineTuningMetrics, FineTuningWandbIntegration, ImageData, ImageGenerateParams,
85    ImageGenerateRequestBuilder, ImageGenerationResponse, Skill, SkillCreateParams,
86    SkillUpdateParams, SkillVersion, SkillVersionContent, SkillVersionCreateParams, Video,
87    VideoCharacter, VideoCharacterCreateParams, VideoCreateParams,
88};
89#[cfg(feature = "realtime")]
90pub use responses::RealtimeSocketRequestBuilder;
91#[cfg(feature = "structured-output")]
92pub use responses::ResponseParseRequestBuilder;
93#[cfg(feature = "responses-ws")]
94pub use responses::ResponsesSocketRequestBuilder;
95pub use responses::{
96    RealtimeClientSecretCreateResponse, RealtimeSessionClientSecret, ResponseCreateRequestBuilder,
97    ResponseStreamRequestBuilder,
98};
99pub use uploads::UploadPart;
100pub use vector_stores::{
101    VectorStore, VectorStoreAttributeValue, VectorStoreAttributes, VectorStoreExpiresAfter,
102    VectorStoreFile, VectorStoreFileBatch, VectorStoreFileChunkingStrategy, VectorStoreFileContent,
103    VectorStoreFileCounts, VectorStoreFileLastError, VectorStoreMetadata, VectorStoreSearchContent,
104    VectorStoreSearchResponse, VectorStoreSearchResult, VectorStoreStaticFileChunkingStrategy,
105};
106
107macro_rules! json_payload_wrapper {
108    ($(#[$meta:meta])* $name:ident) => {
109        $(#[$meta])*
110        #[derive(Debug, Clone, Serialize, Deserialize)]
111        #[serde(transparent)]
112        pub struct $name(Value);
113
114        impl Default for $name {
115            fn default() -> Self {
116                Self(Value::Null)
117            }
118        }
119
120        impl From<Value> for $name {
121            fn from(value: Value) -> Self {
122                Self(value)
123            }
124        }
125
126        impl From<$name> for Value {
127            fn from(value: $name) -> Self {
128                value.0
129            }
130        }
131
132        impl $name {
133            /// 返回未经解释的原始 JSON 值。
134            pub fn as_raw(&self) -> &Value {
135                &self.0
136            }
137
138            /// 消费该包装器并返回原始 JSON 值。
139            pub fn into_raw(self) -> Value {
140                self.0
141            }
142
143            /// 返回载荷中的 `type` 字段,若存在且为字符串。
144            pub fn kind(&self) -> Option<&str> {
145                self.0.get("type").and_then(Value::as_str)
146            }
147        }
148    };
149}
150
151macro_rules! handle {
152    ($(#[$meta:meta])* $name:ident) => {
153        $(#[$meta])*
154        #[derive(Debug, Clone)]
155        pub struct $name {
156            client: Client,
157        }
158
159        impl $name {
160            pub(crate) fn new(client: Client) -> Self {
161                Self { client }
162            }
163        }
164    };
165}
166
167/// 表示常见的删除结果。
168#[derive(Debug, Clone, Serialize, Deserialize, Default)]
169pub struct DeleteResponse {
170    /// 被删除对象的 ID。
171    pub id: Option<String>,
172    /// 是否删除成功。
173    #[serde(default)]
174    pub deleted: bool,
175    /// 对象类型。
176    pub object: Option<String>,
177    /// 额外字段。
178    #[serde(flatten)]
179    pub extra: BTreeMap<String, Value>,
180}
181
182/// 表示模型对象。
183#[derive(Debug, Clone, Serialize, Deserialize, Default)]
184pub struct Model {
185    /// 模型 ID。
186    pub id: String,
187    /// 对象类型。
188    #[serde(default)]
189    pub object: String,
190    /// 模型所有者。
191    pub owned_by: Option<String>,
192    /// 额外字段。
193    #[serde(flatten)]
194    pub extra: BTreeMap<String, Value>,
195}
196
197/// 表示文件对象。
198#[derive(Debug, Clone, Serialize, Deserialize, Default)]
199pub struct FileObject {
200    /// 文件 ID。
201    pub id: String,
202    /// 对象类型。
203    #[serde(default)]
204    pub object: String,
205    /// 文件名。
206    pub filename: Option<String>,
207    /// 文件用途。
208    pub purpose: Option<String>,
209    /// 文件大小。
210    pub bytes: Option<u64>,
211    /// 额外字段。
212    #[serde(flatten)]
213    pub extra: BTreeMap<String, Value>,
214}
215
216/// 表示上传对象。
217#[derive(Debug, Clone, Serialize, Deserialize, Default)]
218pub struct UploadObject {
219    /// 上传 ID。
220    pub id: String,
221    /// 对象类型。
222    #[serde(default)]
223    pub object: String,
224    /// 上传状态。
225    pub status: Option<String>,
226    /// 额外字段。
227    #[serde(flatten)]
228    pub extra: BTreeMap<String, Value>,
229}
230
231/// 表示 Embeddings 接口的返回值。
232#[derive(Debug, Clone, Serialize, Deserialize, Default)]
233pub struct EmbeddingResponse {
234    /// 对象类型。
235    #[serde(default)]
236    pub object: String,
237    /// 向量数据。
238    #[serde(default)]
239    pub data: Vec<EmbeddingData>,
240    /// 使用统计。
241    pub usage: Option<EmbeddingUsage>,
242    /// 额外字段。
243    #[serde(flatten)]
244    pub extra: BTreeMap<String, Value>,
245}
246
247/// 表示单个 embedding 向量项。
248#[derive(Debug, Clone, Serialize, Deserialize, Default)]
249pub struct EmbeddingData {
250    /// embedding 向量。
251    #[serde(default)]
252    pub embedding: Vec<f64>,
253    /// 向量索引。
254    pub index: Option<u32>,
255    /// 对象类型。
256    #[serde(default)]
257    pub object: String,
258    /// 额外字段。
259    #[serde(flatten)]
260    pub extra: BTreeMap<String, Value>,
261}
262
263/// 表示 embeddings 的用量统计。
264#[derive(Debug, Clone, Serialize, Deserialize, Default)]
265pub struct EmbeddingUsage {
266    /// prompt token 数。
267    #[serde(default)]
268    pub prompt_tokens: u64,
269    /// 总 token 数。
270    #[serde(default)]
271    pub total_tokens: u64,
272    /// 额外字段。
273    #[serde(flatten)]
274    pub extra: BTreeMap<String, Value>,
275}
276
277/// 表示模型计数结果。
278#[derive(Debug, Clone, Serialize, Deserialize, Default)]
279pub struct InputTokenCount {
280    /// 总 token 数量。
281    pub total_tokens: u64,
282    /// 额外字段。
283    #[serde(flatten)]
284    pub extra: BTreeMap<String, Value>,
285}
286
287json_payload_wrapper!(
288    /// 表示已存储 chat completion 的 content part。
289    ChatCompletionStoreContentPart
290);
291json_payload_wrapper!(
292    /// 表示聊天消息中的 reasoning detail。
293    ChatReasoningDetail
294);
295json_payload_wrapper!(
296    /// 表示 chat 请求中的多模态 content part。
297    ChatMessageContentPart
298);
299json_payload_wrapper!(
300    /// 表示 chat 请求中的 tool_choice 载荷。
301    ChatToolChoice
302);
303json_payload_wrapper!(
304    /// 表示 responses 请求的输入载荷。
305    ResponseInputPayload
306);
307json_payload_wrapper!(
308    /// 表示 responses 请求中的单个输入项。
309    ResponseInputItemPayload
310);
311json_payload_wrapper!(
312    /// 表示 realtime client secret 返回中的 session 配置。
313    RealtimeSessionPayload
314);
315json_payload_wrapper!(
316    /// 表示 responses 输出中的未知原始输出项。
317    ResponseOutputItemRaw
318);
319json_payload_wrapper!(
320    /// 表示 responses message 中的未知原始内容片段。
321    ResponseOutputContentPartRaw
322);
323
324/// 表示 chat tool_choice 的字符串模式。
325#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
326#[serde(rename_all = "snake_case")]
327pub enum ChatToolChoiceMode {
328    /// 不允许工具调用。
329    None,
330    /// 允许模型自动选择。
331    Auto,
332    /// 要求模型必须调用工具。
333    Required,
334}
335
336impl From<ChatToolChoiceMode> for ChatToolChoice {
337    fn from(mode: ChatToolChoiceMode) -> Self {
338        let value = match mode {
339            ChatToolChoiceMode::None => Value::String("none".into()),
340            ChatToolChoiceMode::Auto => Value::String("auto".into()),
341            ChatToolChoiceMode::Required => Value::String("required".into()),
342        };
343        Self::from(value)
344    }
345}
346
347impl From<String> for ResponseInputPayload {
348    fn from(value: String) -> Self {
349        Self::from(Value::String(value))
350    }
351}
352
353impl From<&str> for ResponseInputPayload {
354    fn from(value: &str) -> Self {
355        Self::from(Value::String(value.into()))
356    }
357}
358
359impl From<Vec<ResponseInputItemPayload>> for ResponseInputPayload {
360    fn from(items: Vec<ResponseInputItemPayload>) -> Self {
361        Self::from(Value::Array(items.into_iter().map(Value::from).collect()))
362    }
363}
364
365impl ChatToolChoice {
366    /// 生成 `none` 模式。
367    pub fn none() -> Self {
368        ChatToolChoiceMode::None.into()
369    }
370
371    /// 生成 `auto` 模式。
372    pub fn auto() -> Self {
373        ChatToolChoiceMode::Auto.into()
374    }
375
376    /// 生成 `required` 模式。
377    pub fn required() -> Self {
378        ChatToolChoiceMode::Required.into()
379    }
380
381    /// 强制调用指定函数工具。
382    pub fn function(name: impl Into<String>) -> Self {
383        serde_json::json!({
384            "type": "function",
385            "function": {
386                "name": name.into(),
387            },
388        })
389        .into()
390    }
391
392    /// 强制调用指定自定义工具。
393    pub fn custom(name: impl Into<String>) -> Self {
394        serde_json::json!({
395            "type": "custom",
396            "custom": {
397                "name": name.into(),
398            },
399        })
400        .into()
401    }
402
403    /// 当 tool_choice 为字符串模式时返回该模式。
404    pub fn mode_name(&self) -> Option<&str> {
405        self.0.as_str()
406    }
407}
408
409/// 表示一个工具函数调用。
410#[derive(Debug, Clone, Serialize, Deserialize, Default)]
411pub struct ChatCompletionFunctionCall {
412    /// 工具名称。
413    pub name: String,
414    /// 参数 JSON 字符串。
415    #[serde(default)]
416    pub arguments: String,
417}
418
419/// 表示工具调用项。
420#[derive(Debug, Clone, Serialize, Deserialize, Default)]
421pub struct ChatCompletionToolCall {
422    /// 工具调用 ID。
423    pub id: String,
424    /// 调用类型。
425    #[serde(rename = "type", default = "default_function_type")]
426    pub call_type: String,
427    /// 函数调用内容。
428    pub function: ChatCompletionFunctionCall,
429    /// 额外字段。
430    #[serde(flatten)]
431    pub extra: BTreeMap<String, Value>,
432}
433
434/// 表示 token 的 top logprob。
435#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
436pub struct ChatCompletionTokenTopLogprob {
437    /// token 内容。
438    #[serde(default)]
439    pub token: String,
440    /// UTF-8 bytes。
441    pub bytes: Option<Vec<u8>>,
442    /// token 对应的 logprob。
443    #[serde(default)]
444    pub logprob: f64,
445    /// 额外字段。
446    #[serde(flatten)]
447    pub extra: BTreeMap<String, Value>,
448}
449
450/// 表示单个 token 的 logprob 信息。
451#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
452pub struct ChatCompletionTokenLogprob {
453    /// token 内容。
454    #[serde(default)]
455    pub token: String,
456    /// UTF-8 bytes。
457    pub bytes: Option<Vec<u8>>,
458    /// token 对应的 logprob。
459    #[serde(default)]
460    pub logprob: f64,
461    /// top logprobs。
462    #[serde(default)]
463    pub top_logprobs: Vec<ChatCompletionTokenTopLogprob>,
464    /// 额外字段。
465    #[serde(flatten)]
466    pub extra: BTreeMap<String, Value>,
467}
468
469/// 表示 chat completion choice 的 token logprobs。
470#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
471pub struct ChatCompletionChoiceLogprobs {
472    /// 内容 token 的 logprobs。
473    #[serde(default, skip_serializing_if = "Vec::is_empty")]
474    pub content: Vec<ChatCompletionTokenLogprob>,
475    /// refusal token 的 logprobs。
476    #[serde(default, skip_serializing_if = "Vec::is_empty")]
477    pub refusal: Vec<ChatCompletionTokenLogprob>,
478    /// 额外字段。
479    #[serde(flatten)]
480    pub extra: BTreeMap<String, Value>,
481}
482
483impl ChatCompletionChoiceLogprobs {
484    /// 按字段名返回对应的 token logprobs 列表。
485    pub fn values(&self, field_name: &str) -> Option<&[ChatCompletionTokenLogprob]> {
486        match field_name {
487            "content" if !self.content.is_empty() => Some(&self.content),
488            "refusal" if !self.refusal.is_empty() => Some(&self.refusal),
489            _ => None,
490        }
491    }
492}
493
494/// 表示流式函数调用增量。
495#[derive(Debug, Clone, Serialize, Deserialize, Default)]
496pub struct ChatCompletionFunctionCallDelta {
497    /// 函数名称增量。
498    pub name: Option<String>,
499    /// 参数增量。
500    pub arguments: Option<String>,
501}
502
503/// 表示流式工具调用增量。
504#[derive(Debug, Clone, Serialize, Deserialize, Default)]
505pub struct ChatCompletionToolCallDelta {
506    /// 增量对应索引。
507    pub index: Option<u32>,
508    /// 工具调用 ID。
509    pub id: Option<String>,
510    /// 调用类型。
511    #[serde(rename = "type")]
512    pub call_type: Option<String>,
513    /// 函数调用增量。
514    pub function: Option<ChatCompletionFunctionCallDelta>,
515}
516
517/// 表示聊天消息。
518#[derive(Debug, Clone, Serialize, Deserialize, Default)]
519pub struct ChatCompletionMessage {
520    /// 角色。
521    pub role: String,
522    /// 文本内容。
523    #[serde(skip_serializing_if = "Option::is_none")]
524    pub content: Option<String>,
525    /// 可选名称。
526    #[serde(skip_serializing_if = "Option::is_none")]
527    pub name: Option<String>,
528    /// 工具调用关联 ID。
529    #[serde(skip_serializing_if = "Option::is_none")]
530    pub tool_call_id: Option<String>,
531    /// 工具调用集合。
532    #[serde(default, skip_serializing_if = "Vec::is_empty")]
533    pub tool_calls: Vec<ChatCompletionToolCall>,
534    /// 拒绝回答文本。
535    #[serde(skip_serializing_if = "Option::is_none")]
536    pub refusal: Option<String>,
537    /// 推理内容。
538    #[serde(skip_serializing_if = "Option::is_none")]
539    pub reasoning_content: Option<String>,
540    /// 推理细节。
541    #[serde(default, skip_serializing_if = "Vec::is_empty")]
542    pub reasoning_details: Vec<ChatReasoningDetail>,
543    /// 额外字段。
544    #[serde(flatten)]
545    pub extra: BTreeMap<String, Value>,
546}
547
548impl ChatCompletionMessage {
549    /// 创建 system 消息。
550    pub fn system(content: impl Into<String>) -> Self {
551        Self {
552            role: "system".into(),
553            content: Some(content.into()),
554            ..Self::default()
555        }
556    }
557
558    /// 创建 user 消息。
559    pub fn user(content: impl Into<String>) -> Self {
560        Self {
561            role: "user".into(),
562            content: Some(content.into()),
563            ..Self::default()
564        }
565    }
566
567    /// 创建包含多模态 content parts 的 user 消息。
568    pub fn user_content_parts(parts: Vec<ChatMessageContentPart>) -> Self {
569        Self::with_content_parts("user", parts)
570    }
571
572    /// 创建包含多模态 content parts 的任意角色消息。
573    pub fn with_content_parts(role: impl Into<String>, parts: Vec<ChatMessageContentPart>) -> Self {
574        let mut extra = BTreeMap::new();
575        extra.insert(
576            "content".into(),
577            Value::Array(parts.into_iter().map(Value::from).collect()),
578        );
579        Self {
580            role: role.into(),
581            content: None,
582            extra,
583            ..Self::default()
584        }
585    }
586
587    /// 创建 text content part。
588    pub fn content_text(text: impl Into<String>) -> ChatMessageContentPart {
589        serde_json::json!({
590            "type": "text",
591            "text": text.into(),
592        })
593        .into()
594    }
595
596    /// 创建 image_url content part。
597    pub fn content_image_url(url: impl Into<String>) -> ChatMessageContentPart {
598        serde_json::json!({
599            "type": "image_url",
600            "image_url": {
601                "url": url.into(),
602            },
603        })
604        .into()
605    }
606
607    /// 创建 video_url content part 预留结构。
608    pub fn content_video_url(url: impl Into<String>) -> ChatMessageContentPart {
609        serde_json::json!({
610            "type": "video_url",
611            "video_url": {
612                "url": url.into(),
613            },
614        })
615        .into()
616    }
617
618    /// 创建 file 引用 content part 预留结构。
619    pub fn content_file(file_id: impl Into<String>) -> ChatMessageContentPart {
620        serde_json::json!({
621            "type": "file",
622            "file": {
623                "file_id": file_id.into(),
624            },
625        })
626        .into()
627    }
628
629    /// 创建 assistant 消息。
630    pub fn assistant(content: impl Into<String>) -> Self {
631        Self {
632            role: "assistant".into(),
633            content: Some(content.into()),
634            ..Self::default()
635        }
636    }
637
638    /// 创建 tool 消息。
639    pub fn tool(tool_call_id: impl Into<String>, content: impl Into<String>) -> Self {
640        Self {
641            role: "tool".into(),
642            content: Some(content.into()),
643            tool_call_id: Some(tool_call_id.into()),
644            ..Self::default()
645        }
646    }
647
648    /// 尝试把消息文本解析为结构化对象。
649    ///
650    /// # Errors
651    ///
652    /// 当文本存在但 JSON 解析失败时返回错误。
653    pub fn parse_content<T>(&self) -> Result<Option<T>>
654    where
655        T: serde::de::DeserializeOwned,
656    {
657        self.content
658            .as_deref()
659            .map(parse_jsonish_payload)
660            .transpose()
661    }
662
663    /// 尝试解析首个工具调用的参数。
664    ///
665    /// # Errors
666    ///
667    /// 当工具参数不是合法 JSON 时返回错误。
668    pub fn parse_tool_arguments<T>(&self) -> Result<Option<T>>
669    where
670        T: serde::de::DeserializeOwned,
671    {
672        self.tool_calls
673            .first()
674            .map(|tool_call| parse_json_arguments(&tool_call.function.arguments))
675            .transpose()
676    }
677
678    /// 尝试解析指定工具调用的参数。
679    ///
680    /// # Errors
681    ///
682    /// 当工具参数不是合法 JSON 时返回错误。
683    pub fn parse_tool_arguments_by_id<T>(&self, tool_call_id: &str) -> Result<Option<T>>
684    where
685        T: serde::de::DeserializeOwned,
686    {
687        self.tool_calls
688            .iter()
689            .find(|tool_call| tool_call.id == tool_call_id)
690            .map(|tool_call| parse_json_arguments(&tool_call.function.arguments))
691            .transpose()
692    }
693}
694
695/// 表示聊天补全中的单个候选项。
696#[derive(Debug, Clone, Serialize, Deserialize, Default)]
697pub struct ChatCompletionChoice {
698    /// 候选项索引。
699    pub index: u32,
700    /// 结束原因。
701    pub finish_reason: Option<String>,
702    /// 返回消息。
703    pub message: ChatCompletionMessage,
704    /// token 级 logprobs。
705    pub logprobs: Option<ChatCompletionChoiceLogprobs>,
706    /// 额外字段。
707    #[serde(flatten)]
708    pub extra: BTreeMap<String, Value>,
709}
710
711/// 表示聊天补全结果。
712#[derive(Debug, Clone, Serialize, Deserialize, Default)]
713pub struct ChatCompletion {
714    /// 补全 ID。
715    pub id: String,
716    /// 对象类型。
717    #[serde(default)]
718    pub object: String,
719    /// 创建时间。
720    pub created: Option<i64>,
721    /// 模型 ID。
722    #[serde(default)]
723    pub model: String,
724    /// 候选项集合。
725    #[serde(default)]
726    pub choices: Vec<ChatCompletionChoice>,
727    /// 使用统计。
728    pub usage: Option<CompletionUsage>,
729    /// 额外字段。
730    #[serde(flatten)]
731    pub extra: BTreeMap<String, Value>,
732}
733
734impl ChatCompletion {
735    /// 校验返回结果没有因为长度或内容过滤而失去可解析语义。
736    ///
737    /// # Errors
738    ///
739    /// 当任一 choice 的 `finish_reason` 为 `length` 或 `content_filter` 时返回错误。
740    pub fn ensure_not_truncated(&self) -> Result<&Self> {
741        for choice in &self.choices {
742            match choice.finish_reason.as_deref() {
743                Some("length") => return Err(crate::LengthFinishReasonError.into()),
744                Some("content_filter") => return Err(crate::ContentFilterFinishReasonError.into()),
745                _ => {}
746            }
747        }
748        Ok(self)
749    }
750}
751
752/// 表示流式增量。
753#[derive(Debug, Clone, Serialize, Deserialize, Default)]
754pub struct ChatCompletionChunkDelta {
755    /// 角色增量。
756    pub role: Option<String>,
757    /// 文本内容增量。
758    pub content: Option<String>,
759    /// 拒绝回答文本增量。
760    pub refusal: Option<String>,
761    /// 推理内容增量。
762    pub reasoning_content: Option<String>,
763    /// 推理细节增量。
764    #[serde(default)]
765    pub reasoning_details: Vec<ChatReasoningDetail>,
766    /// 工具调用增量。
767    #[serde(default)]
768    pub tool_calls: Vec<ChatCompletionToolCallDelta>,
769    /// 额外字段。
770    #[serde(flatten)]
771    pub extra: BTreeMap<String, Value>,
772}
773
774/// 表示流式候选项。
775#[derive(Debug, Clone, Serialize, Deserialize, Default)]
776pub struct ChatCompletionChunkChoice {
777    /// 候选索引。
778    pub index: u32,
779    /// 增量载荷。
780    pub delta: ChatCompletionChunkDelta,
781    /// 结束原因。
782    pub finish_reason: Option<String>,
783    /// token 级 logprobs 增量。
784    pub logprobs: Option<ChatCompletionChoiceLogprobs>,
785    /// 额外字段。
786    #[serde(flatten)]
787    pub extra: BTreeMap<String, Value>,
788}
789
790/// 表示聊天文本增量事件。
791#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
792pub struct ChatContentDeltaEvent {
793    /// 候选索引。
794    pub choice_index: u32,
795    /// 文本增量。
796    pub delta: String,
797}
798
799/// 表示聊天拒绝回答增量事件。
800#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
801pub struct ChatRefusalDeltaEvent {
802    /// 候选索引。
803    pub choice_index: u32,
804    /// 拒绝文本增量。
805    pub delta: String,
806}
807
808/// 表示工具参数增量事件。
809#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
810pub struct ChatToolArgumentsDeltaEvent {
811    /// 候选索引。
812    pub choice_index: u32,
813    /// 工具调用索引。
814    pub tool_call_index: u32,
815    /// 工具名称增量。
816    pub name: Option<String>,
817    /// 参数增量。
818    pub delta: String,
819}
820
821/// 表示 token logprobs 增量事件。
822#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
823pub struct ChatLogProbsDeltaEvent {
824    /// 候选索引。
825    pub choice_index: u32,
826    /// logprobs 明细。
827    pub values: Vec<ChatCompletionTokenLogprob>,
828}
829
830/// 表示聊天补全 SSE 分片。
831#[derive(Debug, Clone, Serialize, Deserialize, Default)]
832pub struct ChatCompletionChunk {
833    /// 分片所属补全 ID。
834    pub id: String,
835    /// 对象类型。
836    #[serde(default)]
837    pub object: String,
838    /// 创建时间。
839    pub created: Option<i64>,
840    /// 模型 ID。
841    #[serde(default)]
842    pub model: String,
843    /// 候选项集合。
844    #[serde(default)]
845    pub choices: Vec<ChatCompletionChunkChoice>,
846    /// 额外字段。
847    #[serde(flatten)]
848    pub extra: BTreeMap<String, Value>,
849}
850
851impl ChatCompletionChunk {
852    /// 提取所有文本内容增量。
853    pub fn content_deltas(&self) -> Vec<ChatContentDeltaEvent> {
854        self.choices
855            .iter()
856            .filter_map(|choice| {
857                choice
858                    .delta
859                    .content
860                    .as_ref()
861                    .map(|delta| ChatContentDeltaEvent {
862                        choice_index: choice.index,
863                        delta: delta.clone(),
864                    })
865            })
866            .collect()
867    }
868
869    /// 提取所有拒绝回答增量。
870    pub fn refusal_deltas(&self) -> Vec<ChatRefusalDeltaEvent> {
871        self.choices
872            .iter()
873            .filter_map(|choice| {
874                choice
875                    .delta
876                    .refusal
877                    .as_ref()
878                    .map(|delta| ChatRefusalDeltaEvent {
879                        choice_index: choice.index,
880                        delta: delta.clone(),
881                    })
882            })
883            .collect()
884    }
885
886    /// 提取所有工具参数增量。
887    pub fn tool_argument_deltas(&self) -> Vec<ChatToolArgumentsDeltaEvent> {
888        self.choices
889            .iter()
890            .flat_map(|choice| {
891                choice.delta.tool_calls.iter().filter_map(|tool_call| {
892                    let delta = tool_call.function.as_ref()?.arguments.clone()?;
893                    Some(ChatToolArgumentsDeltaEvent {
894                        choice_index: choice.index,
895                        tool_call_index: tool_call.index.unwrap_or_default(),
896                        name: tool_call
897                            .function
898                            .as_ref()
899                            .and_then(|function| function.name.clone()),
900                        delta,
901                    })
902                })
903            })
904            .collect()
905    }
906
907    /// 提取内容 token 的 logprobs 增量。
908    pub fn logprobs_content_deltas(&self) -> Vec<ChatLogProbsDeltaEvent> {
909        extract_logprobs(self, "content")
910    }
911
912    /// 提取拒绝回答 token 的 logprobs 增量。
913    pub fn logprobs_refusal_deltas(&self) -> Vec<ChatLogProbsDeltaEvent> {
914        extract_logprobs(self, "refusal")
915    }
916}
917
918fn extract_logprobs(chunk: &ChatCompletionChunk, field_name: &str) -> Vec<ChatLogProbsDeltaEvent> {
919    chunk
920        .choices
921        .iter()
922        .filter_map(|choice| {
923            let values = choice
924                .logprobs
925                .as_ref()
926                .and_then(|logprobs| logprobs.values(field_name))?
927                .to_vec();
928            Some(ChatLogProbsDeltaEvent {
929                choice_index: choice.index,
930                values,
931            })
932        })
933        .collect()
934}
935
936/// 表示聊天工具定义。
937#[derive(Debug, Clone, Serialize, Deserialize)]
938pub struct ChatToolDefinition {
939    /// 工具类型,当前固定为 `function`。
940    #[serde(rename = "type")]
941    pub tool_type: String,
942    /// 函数定义。
943    pub function: ChatToolFunction,
944}
945
946impl ChatToolDefinition {
947    #[cfg(feature = "tool-runner")]
948    fn from_tool(tool: &ToolDefinition) -> Self {
949        Self {
950            tool_type: "function".into(),
951            function: ChatToolFunction {
952                name: tool.name.clone(),
953                description: tool.description.clone(),
954                parameters: tool.parameters.clone(),
955            },
956        }
957    }
958
959    /// 转换为 Responses API 所需的扁平工具定义格式。
960    fn as_response_tool_value(&self) -> Value {
961        serde_json::json!({
962            "type": self.tool_type,
963            "name": self.function.name,
964            "description": self.function.description,
965            "parameters": self.function.parameters,
966        })
967    }
968}
969
970/// 表示聊天工具函数定义。
971#[derive(Debug, Clone, Serialize, Deserialize)]
972pub struct ChatToolFunction {
973    /// 函数名。
974    pub name: String,
975    /// 函数描述。
976    pub description: Option<String>,
977    /// 参数 Schema。
978    pub parameters: JsonPayload,
979}
980
981/// 表示聊天补全请求参数。
982#[derive(Debug, Clone, Serialize, Deserialize, Default)]
983pub struct ChatCompletionCreateParams {
984    /// 模型 ID。
985    #[serde(skip_serializing_if = "Option::is_none")]
986    pub model: Option<String>,
987    /// 历史消息。
988    #[serde(default, skip_serializing_if = "Vec::is_empty")]
989    pub messages: Vec<ChatCompletionMessage>,
990    /// 温度。
991    #[serde(skip_serializing_if = "Option::is_none")]
992    pub temperature: Option<f32>,
993    /// 候选数量。
994    #[serde(skip_serializing_if = "Option::is_none")]
995    pub n: Option<u32>,
996    /// 最大 token 数。
997    #[serde(skip_serializing_if = "Option::is_none")]
998    pub max_tokens: Option<u32>,
999    /// 工具定义。
1000    #[serde(default, skip_serializing_if = "Vec::is_empty")]
1001    pub tools: Vec<ChatToolDefinition>,
1002    /// 工具选择策略。
1003    #[serde(skip_serializing_if = "Option::is_none")]
1004    pub tool_choice: Option<ChatToolChoice>,
1005    /// 流式开关。
1006    #[serde(skip_serializing_if = "Option::is_none")]
1007    pub stream: Option<bool>,
1008}
1009
1010/// 表示 Responses 对象。
1011#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1012pub struct Response {
1013    /// 响应 ID。
1014    pub id: String,
1015    /// 创建时间。
1016    pub created_at: Option<u64>,
1017    /// 对象类型。
1018    #[serde(default)]
1019    pub object: String,
1020    /// 模型 ID。
1021    pub model: Option<String>,
1022    /// 状态。
1023    pub status: Option<String>,
1024    /// 错误信息。
1025    pub error: Option<ResponseError>,
1026    /// 不完整原因。
1027    pub incomplete_details: Option<ResponseIncompleteDetails>,
1028    /// 元数据。
1029    pub metadata: Option<BTreeMap<String, String>>,
1030    /// 输出项。
1031    #[serde(default)]
1032    pub output: Vec<ResponseOutputItem>,
1033    /// 用量统计。
1034    pub usage: Option<ResponseUsage>,
1035    /// 额外字段。
1036    #[serde(flatten)]
1037    pub extra: BTreeMap<String, Value>,
1038}
1039
1040impl Response {
1041    /// 尝试提取最终文本输出。
1042    pub fn output_text(&self) -> Option<String> {
1043        for item in &self.output {
1044            if let Some(text) = item.output_text() {
1045                return Some(text.to_owned());
1046            }
1047        }
1048
1049        self.extra
1050            .get("output_text")
1051            .and_then(Value::as_str)
1052            .map(str::to_owned)
1053    }
1054}
1055
1056/// 表示 responses 顶层错误。
1057#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1058pub struct ResponseError {
1059    /// 错误码。
1060    pub code: Option<String>,
1061    /// 错误消息。
1062    pub message: Option<String>,
1063    /// 额外字段。
1064    #[serde(flatten)]
1065    pub extra: BTreeMap<String, Value>,
1066}
1067
1068/// 表示 responses 不完整原因。
1069#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1070pub struct ResponseIncompleteDetails {
1071    /// 不完整原因。
1072    pub reason: Option<String>,
1073    /// 额外字段。
1074    #[serde(flatten)]
1075    pub extra: BTreeMap<String, Value>,
1076}
1077
1078/// 表示 responses 用量明细。
1079#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1080pub struct ResponseUsage {
1081    /// 输入 token 数。
1082    #[serde(default)]
1083    pub input_tokens: u64,
1084    /// 输入 token 明细。
1085    pub input_tokens_details: Option<ResponseInputTokensDetails>,
1086    /// 输出 token 数。
1087    #[serde(default)]
1088    pub output_tokens: u64,
1089    /// 输出 token 明细。
1090    pub output_tokens_details: Option<ResponseOutputTokensDetails>,
1091    /// 总 token 数。
1092    #[serde(default)]
1093    pub total_tokens: u64,
1094    /// 额外字段。
1095    #[serde(flatten)]
1096    pub extra: BTreeMap<String, Value>,
1097}
1098
1099/// 表示 responses 输入 token 明细。
1100#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1101pub struct ResponseInputTokensDetails {
1102    /// cache 命中 token 数。
1103    pub cached_tokens: Option<u64>,
1104    /// 额外字段。
1105    #[serde(flatten)]
1106    pub extra: BTreeMap<String, Value>,
1107}
1108
1109/// 表示 responses 输出 token 明细。
1110#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1111pub struct ResponseOutputTokensDetails {
1112    /// reasoning token 数。
1113    pub reasoning_tokens: Option<u64>,
1114    /// 额外字段。
1115    #[serde(flatten)]
1116    pub extra: BTreeMap<String, Value>,
1117}
1118
1119/// 表示响应输出项。
1120#[derive(Debug, Clone, Serialize, Deserialize)]
1121#[serde(untagged)]
1122pub enum ResponseOutputItem {
1123    /// 已知输出项。
1124    Known(KnownResponseOutputItem),
1125    /// 向前兼容保留的原始项。
1126    Raw(ResponseOutputItemRaw),
1127}
1128
1129impl Default for ResponseOutputItem {
1130    fn default() -> Self {
1131        Self::Raw(ResponseOutputItemRaw::default())
1132    }
1133}
1134
1135impl ResponseOutputItem {
1136    /// 返回消息输出项。
1137    pub fn as_message(&self) -> Option<&ResponseOutputMessage> {
1138        match self {
1139            Self::Known(KnownResponseOutputItem::Message(message)) => Some(message),
1140            _ => None,
1141        }
1142    }
1143
1144    /// 返回函数调用输出项。
1145    pub fn as_function_call(&self) -> Option<&ResponseFunctionToolCall> {
1146        match self {
1147            Self::Known(KnownResponseOutputItem::FunctionCall(call)) => Some(call),
1148            _ => None,
1149        }
1150    }
1151
1152    /// 返回原始 JSON 项。
1153    pub fn as_raw(&self) -> Option<&Value> {
1154        match self {
1155            Self::Raw(value) => Some(value.as_raw()),
1156            _ => None,
1157        }
1158    }
1159
1160    /// 提取输出文本。
1161    pub fn output_text(&self) -> Option<&str> {
1162        match self {
1163            Self::Known(KnownResponseOutputItem::OutputText(text)) => Some(text.text.as_str()),
1164            Self::Known(KnownResponseOutputItem::Message(message)) => message
1165                .content
1166                .iter()
1167                .find_map(ResponseOutputContentPart::text),
1168            Self::Raw(value) => {
1169                let value = value.as_raw();
1170                if let Some(text) = value.get("text").and_then(Value::as_str) {
1171                    return Some(text);
1172                }
1173                value
1174                    .get("content")
1175                    .and_then(Value::as_array)
1176                    .and_then(|content| {
1177                        content
1178                            .iter()
1179                            .find_map(|item| item.get("text").and_then(Value::as_str))
1180                    })
1181            }
1182            _ => None,
1183        }
1184    }
1185}
1186
1187/// 已知的响应输出项类型。
1188#[derive(Debug, Clone, Serialize, Deserialize)]
1189#[serde(tag = "type", rename_all = "snake_case")]
1190pub enum KnownResponseOutputItem {
1191    /// assistant message。
1192    Message(ResponseOutputMessage),
1193    /// function call。
1194    FunctionCall(ResponseFunctionToolCall),
1195    /// 某些兼容 Provider 直接把 `output_text` 作为顶层输出项返回。
1196    OutputText(ResponseOutputText),
1197    /// 某些兼容 Provider 直接把 `refusal` 作为顶层输出项返回。
1198    Refusal(ResponseOutputRefusal),
1199}
1200
1201/// 表示 assistant message 输出。
1202#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1203pub struct ResponseOutputMessage {
1204    /// message ID。
1205    pub id: String,
1206    /// 内容片段。
1207    #[serde(default)]
1208    pub content: Vec<ResponseOutputContentPart>,
1209    /// 角色。
1210    pub role: Option<String>,
1211    /// 状态。
1212    pub status: Option<String>,
1213    /// assistant phase。
1214    pub phase: Option<String>,
1215    /// 额外字段。
1216    #[serde(flatten)]
1217    pub extra: BTreeMap<String, Value>,
1218}
1219
1220/// 表示函数工具调用输出项。
1221#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1222pub struct ResponseFunctionToolCall {
1223    /// 输出项 ID。
1224    pub id: String,
1225    /// tool call ID。
1226    pub call_id: Option<String>,
1227    /// 工具名称。
1228    pub name: Option<String>,
1229    /// 参数 JSON 字符串。
1230    #[serde(default)]
1231    pub arguments: String,
1232    /// 状态。
1233    pub status: Option<String>,
1234    /// 额外字段。
1235    #[serde(flatten)]
1236    pub extra: BTreeMap<String, Value>,
1237}
1238
1239/// 表示 message 中的内容片段。
1240#[derive(Debug, Clone, Serialize, Deserialize)]
1241#[serde(untagged)]
1242pub enum ResponseOutputContentPart {
1243    /// 已知内容片段。
1244    Known(KnownResponseOutputContentPart),
1245    /// 向前兼容保留的原始片段。
1246    Raw(ResponseOutputContentPartRaw),
1247}
1248
1249impl Default for ResponseOutputContentPart {
1250    fn default() -> Self {
1251        Self::Raw(ResponseOutputContentPartRaw::default())
1252    }
1253}
1254
1255impl ResponseOutputContentPart {
1256    /// 返回 output_text 内容片段。
1257    pub fn as_output_text(&self) -> Option<&ResponseOutputText> {
1258        match self {
1259            Self::Known(KnownResponseOutputContentPart::OutputText(text)) => Some(text),
1260            _ => None,
1261        }
1262    }
1263
1264    /// 提取文本内容。
1265    pub fn text(&self) -> Option<&str> {
1266        match self {
1267            Self::Known(KnownResponseOutputContentPart::OutputText(text)) => {
1268                Some(text.text.as_str())
1269            }
1270            Self::Raw(value) => value.as_raw().get("text").and_then(Value::as_str),
1271            _ => None,
1272        }
1273    }
1274}
1275
1276/// 已知的 message 内容片段。
1277#[derive(Debug, Clone, Serialize, Deserialize)]
1278#[serde(tag = "type", rename_all = "snake_case")]
1279pub enum KnownResponseOutputContentPart {
1280    /// 输出文本。
1281    OutputText(ResponseOutputText),
1282    /// 拒绝回答。
1283    Refusal(ResponseOutputRefusal),
1284}
1285
1286/// 表示 output_text 注解中的文件引用。
1287#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1288pub struct ResponseOutputTextFileCitation {
1289    /// 文件 ID。
1290    pub file_id: String,
1291    /// 文件名。
1292    pub filename: String,
1293    /// 文件索引。
1294    pub index: u64,
1295    /// 额外字段。
1296    #[serde(flatten)]
1297    pub extra: BTreeMap<String, Value>,
1298}
1299
1300/// 表示 output_text 注解中的 URL 引用。
1301#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1302pub struct ResponseOutputTextUrlCitation {
1303    /// 引用结束位置。
1304    pub end_index: u64,
1305    /// 引用起始位置。
1306    pub start_index: u64,
1307    /// 标题。
1308    pub title: String,
1309    /// URL。
1310    pub url: String,
1311    /// 额外字段。
1312    #[serde(flatten)]
1313    pub extra: BTreeMap<String, Value>,
1314}
1315
1316/// 表示 output_text 注解中的容器文件引用。
1317#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1318pub struct ResponseOutputTextContainerFileCitation {
1319    /// 容器 ID。
1320    pub container_id: String,
1321    /// 引用结束位置。
1322    pub end_index: u64,
1323    /// 文件 ID。
1324    pub file_id: String,
1325    /// 文件名。
1326    pub filename: String,
1327    /// 引用起始位置。
1328    pub start_index: u64,
1329    /// 额外字段。
1330    #[serde(flatten)]
1331    pub extra: BTreeMap<String, Value>,
1332}
1333
1334/// 表示 output_text 注解中的文件路径。
1335#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
1336pub struct ResponseOutputTextFilePath {
1337    /// 文件 ID。
1338    pub file_id: String,
1339    /// 文件索引。
1340    pub index: u64,
1341    /// 额外字段。
1342    #[serde(flatten)]
1343    pub extra: BTreeMap<String, Value>,
1344}
1345
1346/// 已知的 output_text 注解类型。
1347#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1348#[serde(tag = "type", rename_all = "snake_case")]
1349pub enum KnownResponseOutputTextAnnotation {
1350    /// 文件引用。
1351    FileCitation(ResponseOutputTextFileCitation),
1352    /// URL 引用。
1353    UrlCitation(ResponseOutputTextUrlCitation),
1354    /// 容器文件引用。
1355    ContainerFileCitation(ResponseOutputTextContainerFileCitation),
1356    /// 文件路径。
1357    FilePath(ResponseOutputTextFilePath),
1358}
1359
1360/// 向前兼容保留的未知 output_text 注解。
1361#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
1362pub struct ResponseOutputTextAnnotationUnknown {
1363    /// 注解类型。
1364    #[serde(rename = "type")]
1365    pub annotation_type: Option<String>,
1366    /// 额外字段。
1367    #[serde(flatten)]
1368    pub extra: BTreeMap<String, Value>,
1369}
1370
1371/// 表示 output_text 注解。
1372#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1373#[serde(untagged)]
1374pub enum ResponseOutputTextAnnotation {
1375    /// 已知注解。
1376    Known(KnownResponseOutputTextAnnotation),
1377    /// 未知注解。
1378    Unknown(ResponseOutputTextAnnotationUnknown),
1379}
1380
1381impl Default for ResponseOutputTextAnnotation {
1382    fn default() -> Self {
1383        Self::Unknown(ResponseOutputTextAnnotationUnknown::default())
1384    }
1385}
1386
1387impl ResponseOutputTextAnnotation {
1388    /// 返回注解类型。
1389    pub fn kind(&self) -> Option<&str> {
1390        match self {
1391            Self::Known(KnownResponseOutputTextAnnotation::FileCitation(_)) => {
1392                Some("file_citation")
1393            }
1394            Self::Known(KnownResponseOutputTextAnnotation::UrlCitation(_)) => Some("url_citation"),
1395            Self::Known(KnownResponseOutputTextAnnotation::ContainerFileCitation(_)) => {
1396                Some("container_file_citation")
1397            }
1398            Self::Known(KnownResponseOutputTextAnnotation::FilePath(_)) => Some("file_path"),
1399            Self::Unknown(annotation) => annotation.annotation_type.as_deref(),
1400        }
1401    }
1402}
1403
1404/// 表示 output_text 的 top logprob。
1405#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
1406pub struct ResponseOutputTextTopLogprob {
1407    /// token 内容。
1408    #[serde(default)]
1409    pub token: String,
1410    /// UTF-8 bytes。
1411    #[serde(default)]
1412    pub bytes: Vec<u8>,
1413    /// token 对应的 logprob。
1414    #[serde(default)]
1415    pub logprob: f64,
1416    /// 额外字段。
1417    #[serde(flatten)]
1418    pub extra: BTreeMap<String, Value>,
1419}
1420
1421/// 表示 output_text 的单个 token logprob。
1422#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
1423pub struct ResponseOutputTextLogprob {
1424    /// token 内容。
1425    #[serde(default)]
1426    pub token: String,
1427    /// UTF-8 bytes。
1428    #[serde(default)]
1429    pub bytes: Vec<u8>,
1430    /// token 对应的 logprob。
1431    #[serde(default)]
1432    pub logprob: f64,
1433    /// top logprobs。
1434    #[serde(default)]
1435    pub top_logprobs: Vec<ResponseOutputTextTopLogprob>,
1436    /// 额外字段。
1437    #[serde(flatten)]
1438    pub extra: BTreeMap<String, Value>,
1439}
1440
1441/// 表示输出文本片段。
1442#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1443pub struct ResponseOutputText {
1444    /// 注解。
1445    #[serde(default)]
1446    pub annotations: Vec<ResponseOutputTextAnnotation>,
1447    /// 文本。
1448    #[serde(default)]
1449    pub text: String,
1450    /// token 级 logprobs。
1451    pub logprobs: Option<Vec<ResponseOutputTextLogprob>>,
1452    /// 额外字段。
1453    #[serde(flatten)]
1454    pub extra: BTreeMap<String, Value>,
1455}
1456
1457/// 表示拒绝回答片段。
1458#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1459pub struct ResponseOutputRefusal {
1460    /// 拒绝原因。
1461    #[serde(default)]
1462    pub refusal: String,
1463    /// 额外字段。
1464    #[serde(flatten)]
1465    pub extra: BTreeMap<String, Value>,
1466}
1467
1468/// 表示 Responses 创建参数。
1469#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1470pub struct ResponseCreateParams {
1471    /// 模型 ID。
1472    #[serde(skip_serializing_if = "Option::is_none")]
1473    pub model: Option<String>,
1474    /// 输入载荷。
1475    #[serde(skip_serializing_if = "Option::is_none")]
1476    pub input: Option<ResponseInputPayload>,
1477    /// 温度。
1478    #[serde(skip_serializing_if = "Option::is_none")]
1479    pub temperature: Option<f32>,
1480    /// 工具定义。
1481    #[serde(default, skip_serializing_if = "Vec::is_empty")]
1482    pub tools: Vec<ChatToolDefinition>,
1483    /// 是否启用流式。
1484    #[serde(skip_serializing_if = "Option::is_none")]
1485    pub stream: Option<bool>,
1486}
1487
1488fn default_function_type() -> String {
1489    "function".into()
1490}
1491
1492fn parse_jsonish_payload<T>(payload: &str) -> Result<T>
1493where
1494    T: serde::de::DeserializeOwned,
1495{
1496    let trimmed = payload.trim();
1497    let normalized = trimmed
1498        .strip_prefix("```json")
1499        .or_else(|| trimmed.strip_prefix("```"))
1500        .map(|value| value.trim())
1501        .and_then(|value| value.strip_suffix("```"))
1502        .map_or(trimmed, str::trim);
1503    serde_json::from_str(normalized).map_err(|error| {
1504        Error::Serialization(crate::SerializationError::new(format!(
1505            "结构化 JSON 解析失败: {error}"
1506        )))
1507    })
1508}
1509
1510fn parse_json_arguments<T>(arguments: &str) -> Result<T>
1511where
1512    T: serde::de::DeserializeOwned,
1513{
1514    serde_json::from_str(arguments).map_err(|error| {
1515        Error::Serialization(crate::SerializationError::new(format!(
1516            "工具参数 JSON 解析失败: {error}"
1517        )))
1518    })
1519}
1520
1521handle!(
1522    /// 顶层 completions 资源。
1523    CompletionsResource
1524);
1525handle!(
1526    /// 聊天资源命名空间。
1527    ChatResource
1528);
1529handle!(
1530    /// 聊天补全资源。
1531    ChatCompletionsResource
1532);
1533handle!(
1534    /// 聊天补全消息子资源。
1535    ChatCompletionMessagesResource
1536);
1537handle!(
1538    /// Embeddings 资源。
1539    EmbeddingsResource
1540);
1541handle!(
1542    /// Files 资源。
1543    FilesResource
1544);
1545handle!(
1546    /// Images 资源。
1547    ImagesResource
1548);
1549handle!(
1550    /// Audio 资源命名空间。
1551    AudioResource
1552);
1553handle!(
1554    /// Audio Speech 资源。
1555    AudioSpeechResource
1556);
1557handle!(
1558    /// Audio Transcriptions 资源。
1559    AudioTranscriptionsResource
1560);
1561handle!(
1562    /// Audio Translations 资源。
1563    AudioTranslationsResource
1564);
1565handle!(
1566    /// Moderations 资源。
1567    ModerationsResource
1568);
1569handle!(
1570    /// Models 资源。
1571    ModelsResource
1572);
1573handle!(
1574    /// Fine-tuning 资源命名空间。
1575    FineTuningResource
1576);
1577handle!(
1578    /// Fine-tuning Jobs 资源。
1579    FineTuningJobsResource
1580);
1581handle!(
1582    /// Fine-tuning Checkpoints 资源。
1583    FineTuningJobCheckpointsResource
1584);
1585handle!(
1586    /// Fine-tuning 权限资源。
1587    FineTuningCheckpointPermissionsResource
1588);
1589handle!(
1590    /// Fine-tuning Alpha 命名空间。
1591    FineTuningAlphaResource
1592);
1593handle!(
1594    /// Fine-tuning Alpha Graders 资源。
1595    FineTuningAlphaGradersResource
1596);
1597handle!(
1598    /// Graders 资源命名空间。
1599    GradersResource
1600);
1601handle!(
1602    /// Vector Stores 资源。
1603    VectorStoresResource
1604);
1605handle!(
1606    /// Vector Store Files 资源。
1607    VectorStoreFilesResource
1608);
1609handle!(
1610    /// Vector Store File Batches 资源。
1611    VectorStoreFileBatchesResource
1612);
1613handle!(
1614    /// Batches 资源。
1615    BatchesResource
1616);
1617handle!(
1618    /// Uploads 资源。
1619    UploadsResource
1620);
1621handle!(
1622    /// Uploads Parts 资源。
1623    UploadPartsResource
1624);
1625handle!(
1626    /// Responses 资源。
1627    ResponsesResource
1628);
1629handle!(
1630    /// Responses Input Items 资源。
1631    ResponseInputItemsResource
1632);
1633handle!(
1634    /// Responses Input Tokens 资源。
1635    ResponseInputTokensResource
1636);
1637handle!(
1638    /// Realtime 资源命名空间。
1639    RealtimeResource
1640);
1641handle!(
1642    /// Realtime Client Secrets 资源。
1643    RealtimeClientSecretsResource
1644);
1645handle!(
1646    /// Realtime Calls 资源。
1647    RealtimeCallsResource
1648);
1649handle!(
1650    /// Conversations 资源。
1651    ConversationsResource
1652);
1653handle!(
1654    /// Conversation Items 资源。
1655    ConversationItemsResource
1656);
1657handle!(
1658    /// Evals 资源。
1659    EvalsResource
1660);
1661handle!(
1662    /// Eval Runs 资源。
1663    EvalRunsResource
1664);
1665handle!(
1666    /// Eval Run Output Items 资源。
1667    EvalRunOutputItemsResource
1668);
1669handle!(
1670    /// Containers 资源。
1671    ContainersResource
1672);
1673handle!(
1674    /// Container Files 资源。
1675    ContainerFilesResource
1676);
1677handle!(
1678    /// Container File Content 资源。
1679    ContainerFilesContentResource
1680);
1681handle!(
1682    /// Skills 资源。
1683    SkillsResource
1684);
1685handle!(
1686    /// Skills Content 资源。
1687    SkillsContentResource
1688);
1689handle!(
1690    /// Skills Versions 资源。
1691    SkillVersionsResource
1692);
1693handle!(
1694    /// Skills Versions Content 资源。
1695    SkillVersionsContentResource
1696);
1697handle!(
1698    /// Videos 资源。
1699    VideosResource
1700);
1701handle!(
1702    /// Webhooks 资源。
1703    WebhooksResource
1704);
1705handle!(
1706    /// Beta 资源命名空间。
1707    BetaResource
1708);
1709handle!(
1710    /// Beta Assistants 资源。
1711    BetaAssistantsResource
1712);
1713handle!(
1714    /// Beta Threads 资源。
1715    BetaThreadsResource
1716);
1717handle!(
1718    /// Beta Thread Messages 资源。
1719    BetaThreadMessagesResource
1720);
1721handle!(
1722    /// Beta Thread Runs 资源。
1723    BetaThreadRunsResource
1724);
1725handle!(
1726    /// Beta Thread Run Steps 资源。
1727    BetaThreadRunStepsResource
1728);
1729handle!(
1730    /// Beta ChatKit 命名空间。
1731    BetaChatkitResource
1732);
1733handle!(
1734    /// Beta ChatKit Sessions 资源。
1735    BetaChatkitSessionsResource
1736);
1737handle!(
1738    /// Beta ChatKit Threads 资源。
1739    BetaChatkitThreadsResource
1740);
1741handle!(
1742    /// Beta Realtime 命名空间。
1743    BetaRealtimeResource
1744);
1745handle!(
1746    /// Beta Realtime Sessions 资源。
1747    BetaRealtimeSessionsResource
1748);
1749handle!(
1750    /// Beta Realtime Transcription Sessions 资源。
1751    BetaRealtimeTranscriptionSessionsResource
1752);