async_openai_alt/
runs.rs

1use serde::Serialize;
2
3use crate::{
4    config::Config,
5    error::OpenAIError,
6    steps::Steps,
7    types::{
8        AssistantEventStream, AssistantStreamEvent, CreateRunRequest, ListRunsResponse,
9        ModifyRunRequest, RunObject, SubmitToolOutputsRunRequest,
10    },
11    Client,
12};
13
14/// Represents an execution run on a thread.
15///
16/// Related guide: [Assistants](https://platform.openai.com/docs/assistants/overview)
17pub struct Runs<'c, C: Config> {
18    pub thread_id: String,
19    client: &'c Client<C>,
20}
21
22impl<'c, C: Config> Runs<'c, C> {
23    pub fn new(client: &'c Client<C>, thread_id: &str) -> Self {
24        Self {
25            client,
26            thread_id: thread_id.into(),
27        }
28    }
29
30    ///  [Steps] API group
31    pub fn steps(&self, run_id: &str) -> Steps<C> {
32        Steps::new(self.client, &self.thread_id, run_id)
33    }
34
35    /// Create a run.
36    pub async fn create(&self, request: CreateRunRequest) -> Result<RunObject, OpenAIError> {
37        self.client
38            .post(&format!("/threads/{}/runs", self.thread_id), request)
39            .await
40    }
41
42    /// Create a run.
43    pub async fn create_stream(
44        &self,
45        mut request: CreateRunRequest,
46    ) -> Result<AssistantEventStream, OpenAIError> {
47        if request.stream.is_some() && !request.stream.unwrap() {
48            return Err(OpenAIError::InvalidArgument(
49                "When stream is false, use Runs::create".into(),
50            ));
51        }
52
53        request.stream = Some(true);
54
55        Ok(self
56            .client
57            .post_stream_mapped_raw_events(
58                &format!("/threads/{}/runs", self.thread_id),
59                request,
60                AssistantStreamEvent::try_from,
61            )
62            .await)
63    }
64
65    /// Retrieves a run.
66    pub async fn retrieve(&self, run_id: &str) -> Result<RunObject, OpenAIError> {
67        self.client
68            .get(&format!("/threads/{}/runs/{run_id}", self.thread_id))
69            .await
70    }
71
72    /// Modifies a run.
73    pub async fn update(
74        &self,
75        run_id: &str,
76        request: ModifyRunRequest,
77    ) -> Result<RunObject, OpenAIError> {
78        self.client
79            .post(
80                &format!("/threads/{}/runs/{run_id}", self.thread_id),
81                request,
82            )
83            .await
84    }
85
86    /// Returns a list of runs belonging to a thread.
87    pub async fn list<Q>(&self, query: &Q) -> Result<ListRunsResponse, OpenAIError>
88    where
89        Q: Serialize + ?Sized,
90    {
91        self.client
92            .get_with_query(&format!("/threads/{}/runs", self.thread_id), query)
93            .await
94    }
95
96    /// When a run has the status: "requires_action" and required_action.type is submit_tool_outputs, this endpoint can be used to submit the outputs from the tool calls once they're all completed. All outputs must be submitted in a single request.
97    pub async fn submit_tool_outputs(
98        &self,
99        run_id: &str,
100        request: SubmitToolOutputsRunRequest,
101    ) -> Result<RunObject, OpenAIError> {
102        self.client
103            .post(
104                &format!(
105                    "/threads/{}/runs/{run_id}/submit_tool_outputs",
106                    self.thread_id
107                ),
108                request,
109            )
110            .await
111    }
112
113    pub async fn submit_tool_outputs_stream(
114        &self,
115        run_id: &str,
116        mut request: SubmitToolOutputsRunRequest,
117    ) -> Result<AssistantEventStream, OpenAIError> {
118        if request.stream.is_some() && !request.stream.unwrap() {
119            return Err(OpenAIError::InvalidArgument(
120                "When stream is false, use Runs::submit_tool_outputs".into(),
121            ));
122        }
123
124        request.stream = Some(true);
125
126        Ok(self
127            .client
128            .post_stream_mapped_raw_events(
129                &format!(
130                    "/threads/{}/runs/{run_id}/submit_tool_outputs",
131                    self.thread_id
132                ),
133                request,
134                AssistantStreamEvent::try_from,
135            )
136            .await)
137    }
138
139    /// Cancels a run that is `in_progress`
140    pub async fn cancel(&self, run_id: &str) -> Result<RunObject, OpenAIError> {
141        self.client
142            .post(
143                &format!("/threads/{}/runs/{run_id}/cancel", self.thread_id),
144                (),
145            )
146            .await
147    }
148}