Skip to main content

openai_core/resources/
beta.rs

1//! Beta 命名空间实现。
2
3use std::collections::BTreeMap;
4use std::time::Duration;
5
6use http::Method;
7use serde::{Deserialize, Serialize};
8use serde_json::Value;
9use tokio::time::sleep;
10
11use crate::Client;
12use crate::error::{Error, Result};
13use crate::generated::endpoints;
14
15#[cfg(feature = "realtime")]
16use super::RealtimeSocketRequestBuilder;
17use super::{
18    AssistantStreamRequestBuilder, BetaAssistantsResource, BetaChatkitResource,
19    BetaChatkitSessionsResource, BetaChatkitThreadsResource, BetaRealtimeResource,
20    BetaRealtimeSessionsResource, BetaRealtimeTranscriptionSessionsResource, BetaResource,
21    BetaThreadMessagesResource, BetaThreadRunStepsResource, BetaThreadRunsResource,
22    BetaThreadsResource, DeleteResponse, JsonRequestBuilder, ListRequestBuilder,
23    RealtimeSessionClientSecret, encode_path_segment,
24};
25
26macro_rules! json_payload_wrapper {
27    ($(#[$meta:meta])* $name:ident) => {
28        $(#[$meta])*
29        #[derive(Debug, Clone, Serialize, Deserialize)]
30        #[serde(transparent)]
31        pub struct $name(Value);
32
33        impl Default for $name {
34            fn default() -> Self {
35                Self(Value::Null)
36            }
37        }
38
39        impl From<Value> for $name {
40            fn from(value: Value) -> Self {
41                Self(value)
42            }
43        }
44
45        impl From<$name> for Value {
46            fn from(value: $name) -> Self {
47                value.0
48            }
49        }
50
51        impl $name {
52            /// 返回未经解释的原始 JSON 值。
53            pub fn as_raw(&self) -> &Value {
54                &self.0
55            }
56
57            /// 消费该包装器并返回原始 JSON 值。
58            pub fn into_raw(self) -> Value {
59                self.0
60            }
61
62            /// 返回载荷中的 `type` 字段,若存在且为字符串。
63            pub fn kind(&self) -> Option<&str> {
64                self.0.get("type").and_then(Value::as_str)
65            }
66        }
67    };
68}
69
70json_payload_wrapper!(
71    /// 表示 beta assistant 工具定义。
72    BetaAssistantTool
73);
74json_payload_wrapper!(
75    /// 表示 beta thread 的工具资源。
76    BetaThreadToolResources
77);
78json_payload_wrapper!(
79    /// 表示 beta thread message 内容块。
80    BetaThreadMessageContent
81);
82json_payload_wrapper!(
83    /// 表示 beta thread run 工具定义。
84    BetaThreadRunTool
85);
86json_payload_wrapper!(
87    /// 表示 beta thread run step 详情。
88    BetaThreadRunStepDetails
89);
90json_payload_wrapper!(
91    /// 表示 ChatKit workflow 配置。
92    ChatKitWorkflow
93);
94json_payload_wrapper!(
95    /// 表示 ChatKit 配置。
96    ChatKitConfiguration
97);
98json_payload_wrapper!(
99    /// 表示 ChatKit rate limit 配置。
100    ChatKitRateLimits
101);
102json_payload_wrapper!(
103    /// 表示 ChatKit thread item 内容。
104    ChatKitThreadContent
105);
106
107/// 表示 beta run 所需函数调用。
108#[derive(Debug, Clone, Serialize, Deserialize, Default)]
109pub struct BetaThreadRunRequiredActionFunction {
110    /// 参数 JSON 字符串。
111    #[serde(default)]
112    pub arguments: String,
113    /// 函数名。
114    pub name: Option<String>,
115    /// 额外字段。
116    #[serde(flatten)]
117    pub extra: BTreeMap<String, Value>,
118}
119
120/// 表示 beta run 所需工具调用。
121#[derive(Debug, Clone, Serialize, Deserialize, Default)]
122pub struct BetaThreadRunRequiredActionFunctionToolCall {
123    /// 工具调用 ID。
124    pub id: String,
125    /// 函数定义。
126    #[serde(rename = "function")]
127    pub function_call: Option<BetaThreadRunRequiredActionFunction>,
128    /// 工具类型。
129    #[serde(rename = "type")]
130    pub tool_type: Option<String>,
131    /// 额外字段。
132    #[serde(flatten)]
133    pub extra: BTreeMap<String, Value>,
134}
135
136/// 表示 beta run 所需工具输出。
137#[derive(Debug, Clone, Serialize, Deserialize, Default)]
138pub struct BetaThreadRunRequiredActionSubmitToolOutputs {
139    /// 工具调用列表。
140    #[serde(default)]
141    pub tool_calls: Vec<BetaThreadRunRequiredActionFunctionToolCall>,
142    /// 额外字段。
143    #[serde(flatten)]
144    pub extra: BTreeMap<String, Value>,
145}
146
147/// 表示 beta run 所需动作。
148#[derive(Debug, Clone, Serialize, Deserialize, Default)]
149pub struct BetaThreadRunRequiredAction {
150    /// 工具输出详情。
151    pub submit_tool_outputs: Option<BetaThreadRunRequiredActionSubmitToolOutputs>,
152    /// 动作类型。
153    #[serde(rename = "type")]
154    pub action_type: Option<String>,
155    /// 额外字段。
156    #[serde(flatten)]
157    pub extra: BTreeMap<String, Value>,
158}
159
160/// 表示 beta run 最近错误。
161#[derive(Debug, Clone, Serialize, Deserialize, Default)]
162pub struct BetaThreadRunLastError {
163    /// 错误码。
164    pub code: Option<String>,
165    /// 错误描述。
166    pub message: Option<String>,
167    /// 额外字段。
168    #[serde(flatten)]
169    pub extra: BTreeMap<String, Value>,
170}
171
172/// 表示 beta run 不完整原因。
173#[derive(Debug, Clone, Serialize, Deserialize, Default)]
174pub struct BetaThreadRunIncompleteDetails {
175    /// 不完整原因。
176    pub reason: Option<String>,
177    /// 额外字段。
178    #[serde(flatten)]
179    pub extra: BTreeMap<String, Value>,
180}
181
182/// 表示 beta run / run step token 用量。
183#[derive(Debug, Clone, Serialize, Deserialize, Default)]
184pub struct BetaThreadRunUsage {
185    /// completion token 数。
186    pub completion_tokens: Option<u64>,
187    /// prompt token 数。
188    pub prompt_tokens: Option<u64>,
189    /// 总 token 数。
190    pub total_tokens: Option<u64>,
191    /// 额外字段。
192    #[serde(flatten)]
193    pub extra: BTreeMap<String, Value>,
194}
195
196/// 表示 beta assistant 对象。
197#[derive(Debug, Clone, Serialize, Deserialize, Default)]
198pub struct BetaAssistant {
199    /// 对象 ID。
200    pub id: String,
201    /// 对象类型。
202    #[serde(default)]
203    pub object: String,
204    /// 模型 ID。
205    pub model: Option<String>,
206    /// 名称。
207    pub name: Option<String>,
208    /// 描述。
209    pub description: Option<String>,
210    /// 指令。
211    pub instructions: Option<String>,
212    /// 工具集合。
213    #[serde(default)]
214    pub tools: Vec<BetaAssistantTool>,
215    /// 元数据。
216    pub metadata: Option<BTreeMap<String, String>>,
217    /// 额外字段。
218    #[serde(flatten)]
219    pub extra: BTreeMap<String, Value>,
220}
221
222/// 表示 beta thread 对象。
223#[derive(Debug, Clone, Serialize, Deserialize, Default)]
224pub struct BetaThread {
225    /// 对象 ID。
226    pub id: String,
227    /// 对象类型。
228    #[serde(default)]
229    pub object: String,
230    /// 元数据。
231    pub metadata: Option<BTreeMap<String, String>>,
232    /// 工具资源。
233    pub tool_resources: Option<BetaThreadToolResources>,
234    /// 额外字段。
235    #[serde(flatten)]
236    pub extra: BTreeMap<String, Value>,
237}
238
239/// 表示 beta thread message 对象。
240#[derive(Debug, Clone, Serialize, Deserialize, Default)]
241pub struct BetaThreadMessage {
242    /// 对象 ID。
243    pub id: String,
244    /// 对象类型。
245    #[serde(default)]
246    pub object: String,
247    /// thread ID。
248    pub thread_id: Option<String>,
249    /// 角色。
250    pub role: Option<String>,
251    /// 状态。
252    pub status: Option<String>,
253    /// 内容。
254    #[serde(default)]
255    pub content: Vec<BetaThreadMessageContent>,
256    /// assistant ID。
257    pub assistant_id: Option<String>,
258    /// run ID。
259    pub run_id: Option<String>,
260    /// 元数据。
261    pub metadata: Option<BTreeMap<String, String>>,
262    /// 额外字段。
263    #[serde(flatten)]
264    pub extra: BTreeMap<String, Value>,
265}
266
267/// 表示 beta thread run 对象。
268#[derive(Debug, Clone, Serialize, Deserialize, Default)]
269pub struct BetaThreadRun {
270    /// 对象 ID。
271    pub id: String,
272    /// 对象类型。
273    #[serde(default)]
274    pub object: String,
275    /// thread ID。
276    pub thread_id: Option<String>,
277    /// assistant ID。
278    pub assistant_id: Option<String>,
279    /// 状态。
280    pub status: Option<String>,
281    /// 模型 ID。
282    pub model: Option<String>,
283    /// 指令。
284    pub instructions: Option<String>,
285    /// 需要用户采取的动作。
286    pub required_action: Option<BetaThreadRunRequiredAction>,
287    /// 最近错误。
288    pub last_error: Option<BetaThreadRunLastError>,
289    /// 不完整细节。
290    pub incomplete_details: Option<BetaThreadRunIncompleteDetails>,
291    /// 工具集合。
292    #[serde(default)]
293    pub tools: Vec<BetaThreadRunTool>,
294    /// 元数据。
295    pub metadata: Option<BTreeMap<String, String>>,
296    /// 用量。
297    pub usage: Option<BetaThreadRunUsage>,
298    /// 额外字段。
299    #[serde(flatten)]
300    pub extra: BTreeMap<String, Value>,
301}
302
303/// 表示 beta thread run step 对象。
304#[derive(Debug, Clone, Serialize, Deserialize, Default)]
305pub struct BetaThreadRunStep {
306    /// 对象 ID。
307    pub id: String,
308    /// 对象类型。
309    #[serde(default)]
310    pub object: String,
311    /// run ID。
312    pub run_id: Option<String>,
313    /// assistant ID。
314    pub assistant_id: Option<String>,
315    /// 状态。
316    pub status: Option<String>,
317    /// step 详情。
318    pub step_details: Option<BetaThreadRunStepDetails>,
319    /// 用量。
320    pub usage: Option<BetaThreadRunUsage>,
321    /// 额外字段。
322    #[serde(flatten)]
323    pub extra: BTreeMap<String, Value>,
324}
325
326/// 表示 ChatKit session 对象。
327#[derive(Debug, Clone, Serialize, Deserialize, Default)]
328pub struct ChatKitSession {
329    /// session ID。
330    pub id: String,
331    /// 对象类型。
332    #[serde(default)]
333    pub object: String,
334    /// ChatKit client secret。
335    pub client_secret: Option<String>,
336    /// 过期时间。
337    pub expires_at: Option<u64>,
338    /// 每分钟请求上限。
339    pub max_requests_per_1_minute: Option<u64>,
340    /// 会话状态。
341    pub status: Option<String>,
342    /// 用户标识。
343    pub user: Option<String>,
344    /// workflow 元数据。
345    pub workflow: Option<ChatKitWorkflow>,
346    /// ChatKit 配置。
347    pub chatkit_configuration: Option<ChatKitConfiguration>,
348    /// rate limit 配置。
349    pub rate_limits: Option<ChatKitRateLimits>,
350    /// 额外字段。
351    #[serde(flatten)]
352    pub extra: BTreeMap<String, Value>,
353}
354
355/// 表示 ChatKit thread 状态。
356#[derive(Debug, Clone, Serialize, Deserialize, Default)]
357pub struct ChatKitThreadStatus {
358    /// 状态类型。
359    #[serde(rename = "type")]
360    pub status_type: Option<String>,
361    /// 状态原因。
362    pub reason: Option<String>,
363    /// 额外字段。
364    #[serde(flatten)]
365    pub extra: BTreeMap<String, Value>,
366}
367
368/// 表示 ChatKit thread 对象。
369#[derive(Debug, Clone, Serialize, Deserialize, Default)]
370pub struct ChatKitThread {
371    /// thread ID。
372    pub id: String,
373    /// 创建时间。
374    pub created_at: Option<u64>,
375    /// 对象类型。
376    #[serde(default)]
377    pub object: String,
378    /// thread 状态。
379    pub status: Option<ChatKitThreadStatus>,
380    /// 标题。
381    pub title: Option<String>,
382    /// 用户标识。
383    pub user: Option<String>,
384    /// 额外字段。
385    #[serde(flatten)]
386    pub extra: BTreeMap<String, Value>,
387}
388
389/// 表示 ChatKit thread item。
390#[derive(Debug, Clone, Serialize, Deserialize, Default)]
391pub struct ChatKitThreadItem {
392    /// item ID。
393    pub id: String,
394    /// 对象类型。
395    #[serde(default)]
396    pub object: String,
397    /// 所属 thread ID。
398    pub thread_id: Option<String>,
399    /// 创建时间。
400    pub created_at: Option<u64>,
401    /// item 类型。
402    #[serde(rename = "type")]
403    pub item_type: Option<String>,
404    /// message content。
405    #[serde(default)]
406    pub content: Vec<ChatKitThreadContent>,
407    /// client tool call 的参数。
408    pub arguments: Option<String>,
409    /// client tool call ID。
410    pub call_id: Option<String>,
411    /// client tool call 名称。
412    pub name: Option<String>,
413    /// 额外字段。
414    #[serde(flatten)]
415    pub extra: BTreeMap<String, Value>,
416}
417
418/// 表示 Beta Realtime session 对象。
419#[derive(Debug, Clone, Serialize, Deserialize, Default)]
420pub struct BetaRealtimeSession {
421    /// 会话 ID。
422    pub id: Option<String>,
423    /// 会话类型。
424    #[serde(rename = "type")]
425    pub session_type: Option<String>,
426    /// 临时 client secret。
427    pub client_secret: Option<RealtimeSessionClientSecret>,
428    /// 模型 ID。
429    pub model: Option<String>,
430    /// 模态集合。
431    #[serde(default)]
432    pub modalities: Vec<String>,
433    /// 额外字段。
434    #[serde(flatten)]
435    pub extra: BTreeMap<String, Value>,
436}
437
438/// 表示 Beta Realtime transcription session 对象。
439#[derive(Debug, Clone, Serialize, Deserialize, Default)]
440pub struct BetaRealtimeTranscriptionSession {
441    /// 临时 client secret。
442    pub client_secret: Option<RealtimeSessionClientSecret>,
443    /// 输入音频格式。
444    pub input_audio_format: Option<String>,
445    /// 模态集合。
446    #[serde(default)]
447    pub modalities: Vec<String>,
448    /// 额外字段。
449    #[serde(flatten)]
450    pub extra: BTreeMap<String, Value>,
451}
452
453impl BetaResource {
454    /// 返回 assistants 子资源。
455    pub fn assistants(&self) -> BetaAssistantsResource {
456        BetaAssistantsResource::new(self.client.clone())
457    }
458
459    /// 返回 threads 子资源。
460    pub fn threads(&self) -> BetaThreadsResource {
461        BetaThreadsResource::new(self.client.clone())
462    }
463
464    /// 返回 chatkit 子资源。
465    pub fn chatkit(&self) -> BetaChatkitResource {
466        BetaChatkitResource::new(self.client.clone())
467    }
468
469    /// 返回 realtime 子资源。
470    pub fn realtime(&self) -> BetaRealtimeResource {
471        BetaRealtimeResource::new(self.client.clone())
472    }
473}
474
475impl BetaAssistantsResource {
476    /// 创建 assistant。
477    pub fn create(&self) -> JsonRequestBuilder<BetaAssistant> {
478        beta_json(
479            self.client.clone(),
480            "beta.assistants.create",
481            Method::POST,
482            "/assistants",
483        )
484    }
485
486    /// 获取 assistant。
487    pub fn retrieve(&self, assistant_id: impl Into<String>) -> JsonRequestBuilder<BetaAssistant> {
488        beta_json(
489            self.client.clone(),
490            "beta.assistants.retrieve",
491            Method::GET,
492            format!("/assistants/{}", encode_path_segment(assistant_id.into())),
493        )
494    }
495
496    /// 更新 assistant。
497    pub fn update(&self, assistant_id: impl Into<String>) -> JsonRequestBuilder<BetaAssistant> {
498        beta_json(
499            self.client.clone(),
500            "beta.assistants.update",
501            Method::POST,
502            format!("/assistants/{}", encode_path_segment(assistant_id.into())),
503        )
504    }
505
506    /// 列出 assistants。
507    pub fn list(&self) -> ListRequestBuilder<BetaAssistant> {
508        beta_list(self.client.clone(), "beta.assistants.list", "/assistants")
509    }
510
511    /// 删除 assistant。
512    pub fn delete(&self, assistant_id: impl Into<String>) -> JsonRequestBuilder<DeleteResponse> {
513        beta_json(
514            self.client.clone(),
515            "beta.assistants.delete",
516            Method::DELETE,
517            format!("/assistants/{}", encode_path_segment(assistant_id.into())),
518        )
519    }
520}
521
522impl BetaThreadsResource {
523    /// 创建 thread。
524    pub fn create(&self) -> JsonRequestBuilder<BetaThread> {
525        beta_json(
526            self.client.clone(),
527            "beta.threads.create",
528            Method::POST,
529            "/threads",
530        )
531    }
532
533    /// 获取 thread。
534    pub fn retrieve(&self, thread_id: impl Into<String>) -> JsonRequestBuilder<BetaThread> {
535        beta_json(
536            self.client.clone(),
537            "beta.threads.retrieve",
538            Method::GET,
539            format!("/threads/{}", encode_path_segment(thread_id.into())),
540        )
541    }
542
543    /// 更新 thread。
544    pub fn update(&self, thread_id: impl Into<String>) -> JsonRequestBuilder<BetaThread> {
545        beta_json(
546            self.client.clone(),
547            "beta.threads.update",
548            Method::POST,
549            format!("/threads/{}", encode_path_segment(thread_id.into())),
550        )
551    }
552
553    /// 删除 thread。
554    pub fn delete(&self, thread_id: impl Into<String>) -> JsonRequestBuilder<DeleteResponse> {
555        beta_json(
556            self.client.clone(),
557            "beta.threads.delete",
558            Method::DELETE,
559            format!("/threads/{}", encode_path_segment(thread_id.into())),
560        )
561    }
562
563    /// 创建并运行 thread。
564    pub fn create_and_run(&self) -> JsonRequestBuilder<BetaThreadRun> {
565        beta_json(
566            self.client.clone(),
567            "beta.threads.create_and_run",
568            Method::POST,
569            "/threads/runs",
570        )
571    }
572
573    /// 创建并运行流式 thread。
574    pub fn create_and_run_stream(&self) -> AssistantStreamRequestBuilder {
575        beta_assistant_stream(
576            self.client.clone(),
577            "beta.threads.create_and_run_stream",
578            Method::POST,
579            "/threads/runs",
580        )
581        .extra_body("stream", Value::Bool(true))
582    }
583
584    /// 创建并运行 thread,然后轮询直到 run 进入终态。
585    ///
586    /// # Errors
587    ///
588    /// 当请求失败、响应缺少 `thread_id` 或轮询失败时返回错误。
589    pub async fn create_and_run_poll<T>(
590        &self,
591        body: &T,
592        poll_interval: Option<Duration>,
593    ) -> Result<BetaThreadRun>
594    where
595        T: Serialize,
596    {
597        let run = self.create_and_run().json_body(body)?.send().await?;
598        let thread_id = run
599            .thread_id
600            .clone()
601            .ok_or_else(|| Error::InvalidConfig("run 响应缺少 thread_id,无法继续轮询".into()))?;
602        self.runs()
603            .poll(thread_id, run.id.clone(), poll_interval)
604            .await
605    }
606
607    /// 返回 messages 子资源。
608    pub fn messages(&self) -> BetaThreadMessagesResource {
609        BetaThreadMessagesResource::new(self.client.clone())
610    }
611
612    /// 返回 runs 子资源。
613    pub fn runs(&self) -> BetaThreadRunsResource {
614        BetaThreadRunsResource::new(self.client.clone())
615    }
616}
617
618impl BetaThreadMessagesResource {
619    /// 创建 thread message。
620    pub fn create(&self, thread_id: impl Into<String>) -> JsonRequestBuilder<BetaThreadMessage> {
621        beta_json(
622            self.client.clone(),
623            "beta.threads.messages.create",
624            Method::POST,
625            format!(
626                "/threads/{}/messages",
627                encode_path_segment(thread_id.into())
628            ),
629        )
630    }
631
632    /// 获取 thread message。
633    pub fn retrieve(
634        &self,
635        thread_id: impl Into<String>,
636        message_id: impl Into<String>,
637    ) -> JsonRequestBuilder<BetaThreadMessage> {
638        beta_json(
639            self.client.clone(),
640            "beta.threads.messages.retrieve",
641            Method::GET,
642            format!(
643                "/threads/{}/messages/{}",
644                encode_path_segment(thread_id.into()),
645                encode_path_segment(message_id.into())
646            ),
647        )
648    }
649
650    /// 更新 thread message。
651    pub fn update(
652        &self,
653        thread_id: impl Into<String>,
654        message_id: impl Into<String>,
655    ) -> JsonRequestBuilder<BetaThreadMessage> {
656        beta_json(
657            self.client.clone(),
658            "beta.threads.messages.update",
659            Method::POST,
660            format!(
661                "/threads/{}/messages/{}",
662                encode_path_segment(thread_id.into()),
663                encode_path_segment(message_id.into())
664            ),
665        )
666    }
667
668    /// 列出 thread messages。
669    pub fn list(&self, thread_id: impl Into<String>) -> ListRequestBuilder<BetaThreadMessage> {
670        beta_list(
671            self.client.clone(),
672            "beta.threads.messages.list",
673            format!(
674                "/threads/{}/messages",
675                encode_path_segment(thread_id.into())
676            ),
677        )
678    }
679
680    /// 删除 thread message。
681    pub fn delete(
682        &self,
683        thread_id: impl Into<String>,
684        message_id: impl Into<String>,
685    ) -> JsonRequestBuilder<DeleteResponse> {
686        beta_json(
687            self.client.clone(),
688            "beta.threads.messages.delete",
689            Method::DELETE,
690            format!(
691                "/threads/{}/messages/{}",
692                encode_path_segment(thread_id.into()),
693                encode_path_segment(message_id.into())
694            ),
695        )
696    }
697}
698
699impl BetaThreadRunsResource {
700    /// 创建 run。
701    pub fn create(&self, thread_id: impl Into<String>) -> JsonRequestBuilder<BetaThreadRun> {
702        beta_json(
703            self.client.clone(),
704            "beta.threads.runs.create",
705            Method::POST,
706            format!("/threads/{}/runs", encode_path_segment(thread_id.into())),
707        )
708    }
709
710    /// 获取 run。
711    pub fn retrieve(
712        &self,
713        thread_id: impl Into<String>,
714        run_id: impl Into<String>,
715    ) -> JsonRequestBuilder<BetaThreadRun> {
716        beta_json(
717            self.client.clone(),
718            "beta.threads.runs.retrieve",
719            Method::GET,
720            format!(
721                "/threads/{}/runs/{}",
722                encode_path_segment(thread_id.into()),
723                encode_path_segment(run_id.into())
724            ),
725        )
726    }
727
728    /// 更新 run。
729    pub fn update(
730        &self,
731        thread_id: impl Into<String>,
732        run_id: impl Into<String>,
733    ) -> JsonRequestBuilder<BetaThreadRun> {
734        beta_json(
735            self.client.clone(),
736            "beta.threads.runs.update",
737            Method::POST,
738            format!(
739                "/threads/{}/runs/{}",
740                encode_path_segment(thread_id.into()),
741                encode_path_segment(run_id.into())
742            ),
743        )
744    }
745
746    /// 列出 runs。
747    pub fn list(&self, thread_id: impl Into<String>) -> ListRequestBuilder<BetaThreadRun> {
748        beta_list(
749            self.client.clone(),
750            "beta.threads.runs.list",
751            format!("/threads/{}/runs", encode_path_segment(thread_id.into())),
752        )
753    }
754
755    /// 取消 run。
756    pub fn cancel(
757        &self,
758        thread_id: impl Into<String>,
759        run_id: impl Into<String>,
760    ) -> JsonRequestBuilder<BetaThreadRun> {
761        beta_json(
762            self.client.clone(),
763            "beta.threads.runs.cancel",
764            Method::POST,
765            format!(
766                "/threads/{}/runs/{}/cancel",
767                encode_path_segment(thread_id.into()),
768                encode_path_segment(run_id.into())
769            ),
770        )
771    }
772
773    /// 创建并流式获取 run。
774    pub fn create_and_stream(&self, thread_id: impl Into<String>) -> AssistantStreamRequestBuilder {
775        beta_assistant_stream(
776            self.client.clone(),
777            "beta.threads.runs.create_and_stream",
778            Method::POST,
779            format!("/threads/{}/runs", encode_path_segment(thread_id.into())),
780        )
781        .extra_body("stream", Value::Bool(true))
782    }
783
784    /// 提交工具输出。
785    pub fn submit_tool_outputs(
786        &self,
787        thread_id: impl Into<String>,
788        run_id: impl Into<String>,
789    ) -> JsonRequestBuilder<BetaThreadRun> {
790        beta_json(
791            self.client.clone(),
792            "beta.threads.runs.submit_tool_outputs",
793            Method::POST,
794            format!(
795                "/threads/{}/runs/{}/submit_tool_outputs",
796                encode_path_segment(thread_id.into()),
797                encode_path_segment(run_id.into())
798            ),
799        )
800    }
801
802    /// 流式提交工具输出。
803    pub fn submit_tool_outputs_stream(
804        &self,
805        thread_id: impl Into<String>,
806        run_id: impl Into<String>,
807    ) -> AssistantStreamRequestBuilder {
808        beta_assistant_stream(
809            self.client.clone(),
810            "beta.threads.runs.submit_tool_outputs_stream",
811            Method::POST,
812            format!(
813                "/threads/{}/runs/{}/submit_tool_outputs",
814                encode_path_segment(thread_id.into()),
815                encode_path_segment(run_id.into())
816            ),
817        )
818        .extra_body("stream", Value::Bool(true))
819    }
820
821    /// 流式获取 run。
822    pub fn stream(
823        &self,
824        thread_id: impl Into<String>,
825        run_id: impl Into<String>,
826    ) -> AssistantStreamRequestBuilder {
827        beta_assistant_stream(
828            self.client.clone(),
829            "beta.threads.runs.stream",
830            Method::GET,
831            format!(
832                "/threads/{}/runs/{}",
833                encode_path_segment(thread_id.into()),
834                encode_path_segment(run_id.into())
835            ),
836        )
837        .extra_query("stream", "true")
838    }
839
840    /// 创建 run,然后轮询直到进入终态。
841    ///
842    /// # Errors
843    ///
844    /// 当创建或轮询失败时返回错误。
845    pub async fn create_and_poll<T>(
846        &self,
847        thread_id: impl Into<String>,
848        body: &T,
849        poll_interval: Option<Duration>,
850    ) -> Result<BetaThreadRun>
851    where
852        T: Serialize,
853    {
854        let thread_id = thread_id.into();
855        let run = self
856            .create(thread_id.clone())
857            .json_body(body)?
858            .send()
859            .await?;
860        self.poll(thread_id, run.id.clone(), poll_interval).await
861    }
862
863    /// 轮询 run,直到状态进入终态。
864    ///
865    /// # Errors
866    ///
867    /// 当请求失败时返回错误。
868    pub async fn poll(
869        &self,
870        thread_id: impl Into<String>,
871        run_id: impl Into<String>,
872        poll_interval: Option<Duration>,
873    ) -> Result<BetaThreadRun> {
874        let thread_id = thread_id.into();
875        let run_id = run_id.into();
876
877        loop {
878            let mut request = self
879                .retrieve(thread_id.clone(), run_id.clone())
880                .extra_header("x-stainless-poll-helper", "true");
881            if let Some(interval) = poll_interval {
882                request = request.extra_header(
883                    "x-stainless-custom-poll-interval",
884                    interval.as_millis().to_string(),
885                );
886            }
887
888            let response = request.send_with_meta().await?;
889            let run = response.data;
890            match run.status.as_deref().unwrap_or_default() {
891                "queued" | "in_progress" | "cancelling" => {
892                    let header_delay = response
893                        .meta
894                        .headers
895                        .get("openai-poll-after-ms")
896                        .and_then(|value| value.to_str().ok())
897                        .and_then(|value| value.parse::<u64>().ok())
898                        .map(Duration::from_millis);
899                    sleep(
900                        poll_interval
901                            .or(header_delay)
902                            .unwrap_or(Duration::from_secs(5)),
903                    )
904                    .await;
905                }
906                _ => return Ok(run),
907            }
908        }
909    }
910
911    /// 提交工具输出,然后轮询直到 run 进入终态。
912    ///
913    /// # Errors
914    ///
915    /// 当提交工具输出或轮询失败时返回错误。
916    pub async fn submit_tool_outputs_and_poll<T>(
917        &self,
918        thread_id: impl Into<String>,
919        run_id: impl Into<String>,
920        body: &T,
921        poll_interval: Option<Duration>,
922    ) -> Result<BetaThreadRun>
923    where
924        T: Serialize,
925    {
926        let thread_id = thread_id.into();
927        let run_id = run_id.into();
928        let run = self
929            .submit_tool_outputs(thread_id.clone(), run_id)
930            .json_body(body)?
931            .send()
932            .await?;
933        self.poll(thread_id, run.id.clone(), poll_interval).await
934    }
935
936    /// 返回 steps 子资源。
937    pub fn steps(&self) -> BetaThreadRunStepsResource {
938        BetaThreadRunStepsResource::new(self.client.clone())
939    }
940}
941
942impl BetaThreadRunStepsResource {
943    /// 获取 run step。
944    pub fn retrieve(
945        &self,
946        thread_id: impl Into<String>,
947        run_id: impl Into<String>,
948        step_id: impl Into<String>,
949    ) -> JsonRequestBuilder<BetaThreadRunStep> {
950        beta_json(
951            self.client.clone(),
952            "beta.threads.runs.steps.retrieve",
953            Method::GET,
954            format!(
955                "/threads/{}/runs/{}/steps/{}",
956                encode_path_segment(thread_id.into()),
957                encode_path_segment(run_id.into()),
958                encode_path_segment(step_id.into())
959            ),
960        )
961    }
962
963    /// 列出 run steps。
964    pub fn list(
965        &self,
966        thread_id: impl Into<String>,
967        run_id: impl Into<String>,
968    ) -> ListRequestBuilder<BetaThreadRunStep> {
969        beta_list(
970            self.client.clone(),
971            "beta.threads.runs.steps.list",
972            format!(
973                "/threads/{}/runs/{}/steps",
974                encode_path_segment(thread_id.into()),
975                encode_path_segment(run_id.into())
976            ),
977        )
978    }
979}
980
981impl BetaChatkitResource {
982    /// 返回 sessions 子资源。
983    pub fn sessions(&self) -> BetaChatkitSessionsResource {
984        BetaChatkitSessionsResource::new(self.client.clone())
985    }
986
987    /// 返回 threads 子资源。
988    pub fn threads(&self) -> BetaChatkitThreadsResource {
989        BetaChatkitThreadsResource::new(self.client.clone())
990    }
991}
992
993impl BetaChatkitSessionsResource {
994    /// 创建 chatkit session。
995    pub fn create(&self) -> JsonRequestBuilder<ChatKitSession> {
996        let endpoint = endpoints::beta_chatkit::BETA_CHATKIT_SESSIONS_CREATE;
997        beta_chatkit_json(
998            self.client.clone(),
999            endpoint.id,
1000            Method::POST,
1001            endpoint.template,
1002        )
1003    }
1004
1005    /// 取消 chatkit session。
1006    pub fn cancel(&self, session_id: impl Into<String>) -> JsonRequestBuilder<ChatKitSession> {
1007        let endpoint = endpoints::beta_chatkit::BETA_CHATKIT_SESSIONS_CANCEL;
1008        beta_chatkit_json(
1009            self.client.clone(),
1010            endpoint.id,
1011            Method::POST,
1012            endpoint.render(&[("session_id", &encode_path_segment(session_id.into()))]),
1013        )
1014    }
1015}
1016
1017impl BetaChatkitThreadsResource {
1018    /// 获取 chatkit thread。
1019    pub fn retrieve(&self, thread_id: impl Into<String>) -> JsonRequestBuilder<ChatKitThread> {
1020        let endpoint = endpoints::beta_chatkit::BETA_CHATKIT_THREADS_RETRIEVE;
1021        beta_chatkit_json(
1022            self.client.clone(),
1023            endpoint.id,
1024            Method::GET,
1025            endpoint.render(&[("thread_id", &encode_path_segment(thread_id.into()))]),
1026        )
1027    }
1028
1029    /// 列出 chatkit threads。
1030    pub fn list(&self) -> ListRequestBuilder<ChatKitThread> {
1031        let endpoint = endpoints::beta_chatkit::BETA_CHATKIT_THREADS_LIST;
1032        beta_chatkit_list(self.client.clone(), endpoint.id, endpoint.template)
1033    }
1034
1035    /// 列出 chatkit thread items。
1036    pub fn list_items(
1037        &self,
1038        thread_id: impl Into<String>,
1039    ) -> ListRequestBuilder<ChatKitThreadItem> {
1040        let endpoint = endpoints::beta_chatkit::BETA_CHATKIT_THREADS_LIST_ITEMS;
1041        beta_chatkit_list(
1042            self.client.clone(),
1043            endpoint.id,
1044            endpoint.render(&[("thread_id", &encode_path_segment(thread_id.into()))]),
1045        )
1046    }
1047
1048    /// 删除 chatkit thread。
1049    pub fn delete(&self, thread_id: impl Into<String>) -> JsonRequestBuilder<DeleteResponse> {
1050        let endpoint = endpoints::beta_chatkit::BETA_CHATKIT_THREADS_DELETE;
1051        beta_chatkit_json(
1052            self.client.clone(),
1053            endpoint.id,
1054            Method::DELETE,
1055            endpoint.render(&[("thread_id", &encode_path_segment(thread_id.into()))]),
1056        )
1057    }
1058}
1059
1060impl BetaRealtimeResource {
1061    /// 创建 Realtime WebSocket 连接构建器。
1062    #[cfg(feature = "realtime")]
1063    #[cfg_attr(docsrs, doc(cfg(feature = "realtime")))]
1064    pub fn ws(&self) -> RealtimeSocketRequestBuilder {
1065        RealtimeSocketRequestBuilder::new(self.client.clone())
1066    }
1067
1068    /// 返回 sessions 子资源。
1069    pub fn sessions(&self) -> BetaRealtimeSessionsResource {
1070        BetaRealtimeSessionsResource::new(self.client.clone())
1071    }
1072
1073    /// 返回 transcription_sessions 子资源。
1074    pub fn transcription_sessions(&self) -> BetaRealtimeTranscriptionSessionsResource {
1075        BetaRealtimeTranscriptionSessionsResource::new(self.client.clone())
1076    }
1077}
1078
1079impl BetaRealtimeSessionsResource {
1080    /// 创建 beta realtime session。
1081    pub fn create(&self) -> JsonRequestBuilder<BetaRealtimeSession> {
1082        let endpoint = endpoints::beta_realtime::BETA_REALTIME_SESSIONS_CREATE;
1083        beta_json(
1084            self.client.clone(),
1085            endpoint.id,
1086            Method::POST,
1087            endpoint.template,
1088        )
1089    }
1090}
1091
1092impl BetaRealtimeTranscriptionSessionsResource {
1093    /// 创建 beta realtime transcription session。
1094    pub fn create(&self) -> JsonRequestBuilder<BetaRealtimeTranscriptionSession> {
1095        let endpoint = endpoints::beta_realtime::BETA_REALTIME_TRANSCRIPTION_SESSIONS_CREATE;
1096        beta_json(
1097            self.client.clone(),
1098            endpoint.id,
1099            Method::POST,
1100            endpoint.template,
1101        )
1102    }
1103}
1104
1105fn beta_json<T>(
1106    client: Client,
1107    endpoint_id: &'static str,
1108    method: Method,
1109    path: impl Into<String>,
1110) -> JsonRequestBuilder<T> {
1111    JsonRequestBuilder::new(client, endpoint_id, method, path)
1112        .extra_header("openai-beta", "assistants=v2")
1113}
1114
1115fn beta_list<T>(
1116    client: Client,
1117    endpoint_id: &'static str,
1118    path: impl Into<String>,
1119) -> ListRequestBuilder<T> {
1120    ListRequestBuilder::new(client, endpoint_id, path).extra_header("openai-beta", "assistants=v2")
1121}
1122
1123fn beta_chatkit_json<T>(
1124    client: Client,
1125    endpoint_id: &'static str,
1126    method: Method,
1127    path: impl Into<String>,
1128) -> JsonRequestBuilder<T> {
1129    JsonRequestBuilder::new(client, endpoint_id, method, path)
1130        .extra_header("openai-beta", "chatkit_beta=v1")
1131}
1132
1133fn beta_chatkit_list<T>(
1134    client: Client,
1135    endpoint_id: &'static str,
1136    path: impl Into<String>,
1137) -> ListRequestBuilder<T> {
1138    ListRequestBuilder::new(client, endpoint_id, path)
1139        .extra_header("openai-beta", "chatkit_beta=v1")
1140}
1141
1142fn beta_assistant_stream(
1143    client: Client,
1144    endpoint_id: &'static str,
1145    method: Method,
1146    path: impl Into<String>,
1147) -> AssistantStreamRequestBuilder {
1148    AssistantStreamRequestBuilder::new(client, endpoint_id, method, path)
1149        .extra_header("openai-beta", "assistants=v2")
1150}