livekit_api/services/
agent_dispatch.rs1use super::{twirp_client::TwirpClient, ServiceBase, ServiceResult, LIVEKIT_PACKAGE};
16use http::header::HeaderMap;
17use livekit_protocol as proto;
18use livekit_token::{get_env_keys, AccessTokenError, VideoGrants};
19
20const SVC: &str = "AgentDispatchService";
21
22#[derive(Debug)]
23pub struct AgentDispatchClient {
24 base: ServiceBase,
25 client: TwirpClient,
26}
27
28impl AgentDispatchClient {
29 pub fn with_api_key(host: &str, api_key: &str, api_secret: &str) -> Self {
31 Self::build(
32 host,
33 ServiceBase::with_api_key(api_key, api_secret),
34 crate::http_client::Client::new(),
35 )
36 }
37
38 pub fn with_token(host: &str, token: &str) -> Self {
40 Self::build(host, ServiceBase::with_token(token), crate::http_client::Client::new())
41 }
42
43 pub(crate) fn build(host: &str, base: ServiceBase, client: crate::http_client::Client) -> Self {
46 Self { base, client: TwirpClient::with_client(host, LIVEKIT_PACKAGE, None, client) }
47 }
48
49 #[cfg(test)]
50 pub(crate) fn with_default_headers(mut self, headers: http::HeaderMap) -> Self {
51 self.client = self.client.with_default_headers(headers);
52 self
53 }
54
55 pub fn new(host: &str) -> ServiceResult<Self> {
58 let (api_key, api_secret) = get_env_keys()?;
59 Ok(Self::with_api_key(host, &api_key, &api_secret))
60 }
61
62 pub fn with_failover(mut self, enabled: bool) -> Self {
65 self.client = self.client.with_failover(enabled);
66 self
67 }
68
69 pub fn with_request_timeout(mut self, timeout: std::time::Duration) -> Self {
71 self.client = self.client.with_request_timeout(timeout);
72 self
73 }
74
75 pub async fn create_dispatch(
88 &self,
89 req: proto::CreateAgentDispatchRequest,
90 ) -> ServiceResult<proto::AgentDispatch> {
91 const METHOD: &str = "CreateDispatch";
92 let headers = self.auth_headers(req.room.to_string())?;
93 Ok(self.client.request(SVC, METHOD, req, headers).await?)
94 }
95
96 pub async fn delete_dispatch(
106 &self,
107 dispatch_id: impl Into<String>,
108 room_name: impl Into<String>,
109 ) -> ServiceResult<proto::AgentDispatch> {
110 const METHOD: &str = "DeleteDispatch";
111 let req = proto::DeleteAgentDispatchRequest {
112 dispatch_id: dispatch_id.into(),
113 room: room_name.into(),
114 };
115 let headers = self.auth_headers(req.room.to_string())?;
116 Ok(self.client.request(SVC, METHOD, req, headers).await?)
117 }
118
119 pub async fn list_dispatch(
128 &self,
129 room_name: impl Into<String>,
130 ) -> ServiceResult<Vec<proto::AgentDispatch>> {
131 const METHOD: &str = "ListDispatch";
132 let req = proto::ListAgentDispatchRequest { room: room_name.into(), ..Default::default() };
133 let headers = self.auth_headers(req.room.to_string())?;
134 let res: proto::ListAgentDispatchResponse =
135 self.client.request(SVC, METHOD, req, headers).await?;
136 Ok(res.agent_dispatches)
137 }
138
139 pub async fn get_dispatch(
149 &self,
150 dispatch_id: impl Into<String>,
151 room_name: impl Into<String>,
152 ) -> ServiceResult<Option<proto::AgentDispatch>> {
153 const METHOD: &str = "ListDispatch";
154 let req = proto::ListAgentDispatchRequest {
155 room: room_name.into(),
156 dispatch_id: dispatch_id.into(),
157 };
158 let headers = self.auth_headers(req.room.to_string())?;
159 let mut res: proto::ListAgentDispatchResponse =
160 self.client.request(SVC, METHOD, req, headers).await?;
161 Ok(res.agent_dispatches.pop())
162 }
163}
164
165impl AgentDispatchClient {
166 fn auth_headers(&self, room: String) -> Result<HeaderMap, AccessTokenError> {
168 self.base.auth_header(VideoGrants { room, room_admin: true, ..Default::default() }, None)
169 }
170}