1use 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 pub fn as_raw(&self) -> &Value {
54 &self.0
55 }
56
57 pub fn into_raw(self) -> Value {
59 self.0
60 }
61
62 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 BetaAssistantTool
73);
74json_payload_wrapper!(
75 BetaThreadToolResources
77);
78json_payload_wrapper!(
79 BetaThreadMessageContent
81);
82json_payload_wrapper!(
83 BetaThreadRunTool
85);
86json_payload_wrapper!(
87 BetaThreadRunStepDetails
89);
90json_payload_wrapper!(
91 ChatKitWorkflow
93);
94json_payload_wrapper!(
95 ChatKitConfiguration
97);
98json_payload_wrapper!(
99 ChatKitRateLimits
101);
102json_payload_wrapper!(
103 ChatKitThreadContent
105);
106
107#[derive(Debug, Clone, Serialize, Deserialize, Default)]
109pub struct BetaThreadRunRequiredActionFunction {
110 #[serde(default)]
112 pub arguments: String,
113 pub name: Option<String>,
115 #[serde(flatten)]
117 pub extra: BTreeMap<String, Value>,
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize, Default)]
122pub struct BetaThreadRunRequiredActionFunctionToolCall {
123 pub id: String,
125 #[serde(rename = "function")]
127 pub function_call: Option<BetaThreadRunRequiredActionFunction>,
128 #[serde(rename = "type")]
130 pub tool_type: Option<String>,
131 #[serde(flatten)]
133 pub extra: BTreeMap<String, Value>,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize, Default)]
138pub struct BetaThreadRunRequiredActionSubmitToolOutputs {
139 #[serde(default)]
141 pub tool_calls: Vec<BetaThreadRunRequiredActionFunctionToolCall>,
142 #[serde(flatten)]
144 pub extra: BTreeMap<String, Value>,
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize, Default)]
149pub struct BetaThreadRunRequiredAction {
150 pub submit_tool_outputs: Option<BetaThreadRunRequiredActionSubmitToolOutputs>,
152 #[serde(rename = "type")]
154 pub action_type: Option<String>,
155 #[serde(flatten)]
157 pub extra: BTreeMap<String, Value>,
158}
159
160#[derive(Debug, Clone, Serialize, Deserialize, Default)]
162pub struct BetaThreadRunLastError {
163 pub code: Option<String>,
165 pub message: Option<String>,
167 #[serde(flatten)]
169 pub extra: BTreeMap<String, Value>,
170}
171
172#[derive(Debug, Clone, Serialize, Deserialize, Default)]
174pub struct BetaThreadRunIncompleteDetails {
175 pub reason: Option<String>,
177 #[serde(flatten)]
179 pub extra: BTreeMap<String, Value>,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize, Default)]
184pub struct BetaThreadRunUsage {
185 pub completion_tokens: Option<u64>,
187 pub prompt_tokens: Option<u64>,
189 pub total_tokens: Option<u64>,
191 #[serde(flatten)]
193 pub extra: BTreeMap<String, Value>,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize, Default)]
198pub struct BetaAssistant {
199 pub id: String,
201 #[serde(default)]
203 pub object: String,
204 pub model: Option<String>,
206 pub name: Option<String>,
208 pub description: Option<String>,
210 pub instructions: Option<String>,
212 #[serde(default)]
214 pub tools: Vec<BetaAssistantTool>,
215 pub metadata: Option<BTreeMap<String, String>>,
217 #[serde(flatten)]
219 pub extra: BTreeMap<String, Value>,
220}
221
222#[derive(Debug, Clone, Serialize, Deserialize, Default)]
224pub struct BetaThread {
225 pub id: String,
227 #[serde(default)]
229 pub object: String,
230 pub metadata: Option<BTreeMap<String, String>>,
232 pub tool_resources: Option<BetaThreadToolResources>,
234 #[serde(flatten)]
236 pub extra: BTreeMap<String, Value>,
237}
238
239#[derive(Debug, Clone, Serialize, Deserialize, Default)]
241pub struct BetaThreadMessage {
242 pub id: String,
244 #[serde(default)]
246 pub object: String,
247 pub thread_id: Option<String>,
249 pub role: Option<String>,
251 pub status: Option<String>,
253 #[serde(default)]
255 pub content: Vec<BetaThreadMessageContent>,
256 pub assistant_id: Option<String>,
258 pub run_id: Option<String>,
260 pub metadata: Option<BTreeMap<String, String>>,
262 #[serde(flatten)]
264 pub extra: BTreeMap<String, Value>,
265}
266
267#[derive(Debug, Clone, Serialize, Deserialize, Default)]
269pub struct BetaThreadRun {
270 pub id: String,
272 #[serde(default)]
274 pub object: String,
275 pub thread_id: Option<String>,
277 pub assistant_id: Option<String>,
279 pub status: Option<String>,
281 pub model: Option<String>,
283 pub instructions: Option<String>,
285 pub required_action: Option<BetaThreadRunRequiredAction>,
287 pub last_error: Option<BetaThreadRunLastError>,
289 pub incomplete_details: Option<BetaThreadRunIncompleteDetails>,
291 #[serde(default)]
293 pub tools: Vec<BetaThreadRunTool>,
294 pub metadata: Option<BTreeMap<String, String>>,
296 pub usage: Option<BetaThreadRunUsage>,
298 #[serde(flatten)]
300 pub extra: BTreeMap<String, Value>,
301}
302
303#[derive(Debug, Clone, Serialize, Deserialize, Default)]
305pub struct BetaThreadRunStep {
306 pub id: String,
308 #[serde(default)]
310 pub object: String,
311 pub run_id: Option<String>,
313 pub assistant_id: Option<String>,
315 pub status: Option<String>,
317 pub step_details: Option<BetaThreadRunStepDetails>,
319 pub usage: Option<BetaThreadRunUsage>,
321 #[serde(flatten)]
323 pub extra: BTreeMap<String, Value>,
324}
325
326#[derive(Debug, Clone, Serialize, Deserialize, Default)]
328pub struct ChatKitSession {
329 pub id: String,
331 #[serde(default)]
333 pub object: String,
334 pub client_secret: Option<String>,
336 pub expires_at: Option<u64>,
338 pub max_requests_per_1_minute: Option<u64>,
340 pub status: Option<String>,
342 pub user: Option<String>,
344 pub workflow: Option<ChatKitWorkflow>,
346 pub chatkit_configuration: Option<ChatKitConfiguration>,
348 pub rate_limits: Option<ChatKitRateLimits>,
350 #[serde(flatten)]
352 pub extra: BTreeMap<String, Value>,
353}
354
355#[derive(Debug, Clone, Serialize, Deserialize, Default)]
357pub struct ChatKitThreadStatus {
358 #[serde(rename = "type")]
360 pub status_type: Option<String>,
361 pub reason: Option<String>,
363 #[serde(flatten)]
365 pub extra: BTreeMap<String, Value>,
366}
367
368#[derive(Debug, Clone, Serialize, Deserialize, Default)]
370pub struct ChatKitThread {
371 pub id: String,
373 pub created_at: Option<u64>,
375 #[serde(default)]
377 pub object: String,
378 pub status: Option<ChatKitThreadStatus>,
380 pub title: Option<String>,
382 pub user: Option<String>,
384 #[serde(flatten)]
386 pub extra: BTreeMap<String, Value>,
387}
388
389#[derive(Debug, Clone, Serialize, Deserialize, Default)]
391pub struct ChatKitThreadItem {
392 pub id: String,
394 #[serde(default)]
396 pub object: String,
397 pub thread_id: Option<String>,
399 pub created_at: Option<u64>,
401 #[serde(rename = "type")]
403 pub item_type: Option<String>,
404 #[serde(default)]
406 pub content: Vec<ChatKitThreadContent>,
407 pub arguments: Option<String>,
409 pub call_id: Option<String>,
411 pub name: Option<String>,
413 #[serde(flatten)]
415 pub extra: BTreeMap<String, Value>,
416}
417
418#[derive(Debug, Clone, Serialize, Deserialize, Default)]
420pub struct BetaRealtimeSession {
421 pub id: Option<String>,
423 #[serde(rename = "type")]
425 pub session_type: Option<String>,
426 pub client_secret: Option<RealtimeSessionClientSecret>,
428 pub model: Option<String>,
430 #[serde(default)]
432 pub modalities: Vec<String>,
433 #[serde(flatten)]
435 pub extra: BTreeMap<String, Value>,
436}
437
438#[derive(Debug, Clone, Serialize, Deserialize, Default)]
440pub struct BetaRealtimeTranscriptionSession {
441 pub client_secret: Option<RealtimeSessionClientSecret>,
443 pub input_audio_format: Option<String>,
445 #[serde(default)]
447 pub modalities: Vec<String>,
448 #[serde(flatten)]
450 pub extra: BTreeMap<String, Value>,
451}
452
453impl BetaResource {
454 pub fn assistants(&self) -> BetaAssistantsResource {
456 BetaAssistantsResource::new(self.client.clone())
457 }
458
459 pub fn threads(&self) -> BetaThreadsResource {
461 BetaThreadsResource::new(self.client.clone())
462 }
463
464 pub fn chatkit(&self) -> BetaChatkitResource {
466 BetaChatkitResource::new(self.client.clone())
467 }
468
469 pub fn realtime(&self) -> BetaRealtimeResource {
471 BetaRealtimeResource::new(self.client.clone())
472 }
473}
474
475impl BetaAssistantsResource {
476 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 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 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 pub fn list(&self) -> ListRequestBuilder<BetaAssistant> {
508 beta_list(self.client.clone(), "beta.assistants.list", "/assistants")
509 }
510
511 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 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 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 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 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 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 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 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 pub fn messages(&self) -> BetaThreadMessagesResource {
609 BetaThreadMessagesResource::new(self.client.clone())
610 }
611
612 pub fn runs(&self) -> BetaThreadRunsResource {
614 BetaThreadRunsResource::new(self.client.clone())
615 }
616}
617
618impl BetaThreadMessagesResource {
619 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 pub fn steps(&self) -> BetaThreadRunStepsResource {
938 BetaThreadRunStepsResource::new(self.client.clone())
939 }
940}
941
942impl BetaThreadRunStepsResource {
943 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 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 pub fn sessions(&self) -> BetaChatkitSessionsResource {
984 BetaChatkitSessionsResource::new(self.client.clone())
985 }
986
987 pub fn threads(&self) -> BetaChatkitThreadsResource {
989 BetaChatkitThreadsResource::new(self.client.clone())
990 }
991}
992
993impl BetaChatkitSessionsResource {
994 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 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 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 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 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 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 #[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 pub fn sessions(&self) -> BetaRealtimeSessionsResource {
1070 BetaRealtimeSessionsResource::new(self.client.clone())
1071 }
1072
1073 pub fn transcription_sessions(&self) -> BetaRealtimeTranscriptionSessionsResource {
1075 BetaRealtimeTranscriptionSessionsResource::new(self.client.clone())
1076 }
1077}
1078
1079impl BetaRealtimeSessionsResource {
1080 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 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}