Skip to main content

oneiros_client/
client.rs

1use oneiros_model::*;
2use std::net::SocketAddr;
3
4use crate::*;
5
6pub struct Client {
7    client: SocketClient,
8}
9
10impl Client {
11    pub fn new(addr: SocketAddr) -> Self {
12        Self {
13            client: SocketClient::new(addr),
14        }
15    }
16
17    async fn send(
18        &self,
19        method: &str,
20        uri: &str,
21        token: &Token,
22        body: Option<Vec<u8>>,
23    ) -> Result<Vec<u8>, Error> {
24        let (status, response_body) = self
25            .client
26            .authenticated_request(method, uri, token, body)
27            .await?;
28
29        if status >= 400 {
30            let body_str = String::from_utf8_lossy(&response_body).to_string();
31            return Err(ResponseError {
32                status,
33                body: body_str,
34            })?;
35        }
36
37        Ok(response_body)
38    }
39
40    /// Parse a JSON response as a full Response envelope.
41    fn parse(&self, bytes: &[u8]) -> Result<Response, Error> {
42        Ok(serde_json::from_slice(bytes)?)
43    }
44
45    pub async fn get_event(&self, token: &Token, name: &EventId) -> Result<Response, Error> {
46        let uri = format!("/events/{name}");
47        let bytes = self.send("GET", &uri, token, None).await?;
48        self.parse(&bytes)
49    }
50
51    pub async fn list_events(&self, token: &Token) -> Result<Response, Error> {
52        let bytes = self.send("GET", "/events", token, None).await?;
53        self.parse(&bytes)
54    }
55
56    pub async fn create_brain(&self, request: CreateBrainRequest) -> Result<Response, Error> {
57        let body = serde_json::to_vec(&request)?;
58        let (status, response_body) = self.client.request("POST", "/brains", body).await?;
59
60        if status >= 400 {
61            let body_str = String::from_utf8_lossy(&response_body).to_string();
62            return Err(ResponseError {
63                status,
64                body: body_str,
65            })?;
66        }
67
68        self.parse(&response_body)
69    }
70
71    pub async fn export_brain(&self, token: &Token) -> Result<Response, Error> {
72        self.list_events(token).await
73    }
74
75    pub async fn import_events(
76        &self,
77        token: &Token,
78        events: Vec<ImportEvent>,
79    ) -> Result<Response, Error> {
80        let body = serde_json::to_vec(&events)?;
81        let bytes = self
82            .send("POST", "/events/import", token, Some(body))
83            .await?;
84        self.parse(&bytes)
85    }
86
87    pub async fn replay_brain(&self, token: &Token) -> Result<Response, Error> {
88        let bytes = self.send("POST", "/events/replay", token, None).await?;
89        self.parse(&bytes)
90    }
91
92    pub async fn create_agent(
93        &self,
94        token: &Token,
95        request: CreateAgentRequest,
96    ) -> Result<Response, Error> {
97        let body = serde_json::to_vec(&request)?;
98        let bytes = self.send("POST", "/agents", token, Some(body)).await?;
99        self.parse(&bytes)
100    }
101
102    pub async fn update_agent(
103        &self,
104        token: &Token,
105        name: &AgentName,
106        request: UpdateAgentRequest,
107    ) -> Result<Response, Error> {
108        let uri = format!("/agents/{name}");
109        let body = serde_json::to_vec(&request)?;
110        let bytes = self.send("PUT", &uri, token, Some(body)).await?;
111        self.parse(&bytes)
112    }
113
114    pub async fn remove_agent(&self, token: &Token, name: &AgentName) -> Result<(), Error> {
115        let uri = format!("/agents/{name}");
116        self.send("DELETE", &uri, token, None).await?;
117        Ok(())
118    }
119
120    pub async fn get_agent(&self, token: &Token, name: &AgentName) -> Result<Response, Error> {
121        let uri = format!("/agents/{name}");
122        let bytes = self.send("GET", &uri, token, None).await?;
123        self.parse(&bytes)
124    }
125
126    pub async fn list_agents(&self, token: &Token) -> Result<Response, Error> {
127        let bytes = self.send("GET", "/agents", token, None).await?;
128        self.parse(&bytes)
129    }
130
131    pub async fn add_cognition(
132        &self,
133        token: &Token,
134        request: AddCognitionRequest,
135    ) -> Result<Response, Error> {
136        let body = serde_json::to_vec(&request)?;
137        let bytes = self.send("POST", "/cognitions", token, Some(body)).await?;
138        self.parse(&bytes)
139    }
140
141    pub async fn get_cognition(&self, token: &Token, id: &CognitionId) -> Result<Response, Error> {
142        let uri = format!("/cognitions/{id}");
143        let bytes = self.send("GET", &uri, token, None).await?;
144        self.parse(&bytes)
145    }
146
147    pub async fn list_cognitions(
148        &self,
149        token: &Token,
150        agent: Option<&AgentName>,
151        texture: Option<&TextureName>,
152    ) -> Result<Response, Error> {
153        let mut params = Vec::new();
154        if let Some(agent) = agent {
155            params.push(format!("agent={}", urlencoding::encode(agent.as_str())));
156        }
157        if let Some(texture) = texture {
158            params.push(format!("texture={}", urlencoding::encode(texture.as_str())));
159        }
160
161        let uri = if params.is_empty() {
162            "/cognitions".to_string()
163        } else {
164            format!("/cognitions?{}", params.join("&"))
165        };
166
167        let bytes = self.send("GET", &uri, token, None).await?;
168        self.parse(&bytes)
169    }
170
171    pub async fn add_memory(
172        &self,
173        token: &Token,
174        request: AddMemoryRequest,
175    ) -> Result<Response, Error> {
176        let body = serde_json::to_vec(&request)?;
177        let bytes = self.send("POST", "/memories", token, Some(body)).await?;
178        self.parse(&bytes)
179    }
180
181    pub async fn get_memory(&self, token: &Token, id: &MemoryId) -> Result<Response, Error> {
182        let uri = format!("/memories/{id}");
183        let bytes = self.send("GET", &uri, token, None).await?;
184        self.parse(&bytes)
185    }
186
187    pub async fn list_memories(
188        &self,
189        token: &Token,
190        agent: Option<&AgentName>,
191        level: Option<&LevelName>,
192    ) -> Result<Response, Error> {
193        let mut params = Vec::new();
194        if let Some(agent) = agent {
195            params.push(format!("agent={}", urlencoding::encode(agent.as_str())));
196        }
197        if let Some(level) = level {
198            params.push(format!("level={}", urlencoding::encode(level.as_str())));
199        }
200
201        let uri = if params.is_empty() {
202            "/memories".to_string()
203        } else {
204            format!("/memories?{}", params.join("&"))
205        };
206
207        let bytes = self.send("GET", &uri, token, None).await?;
208        self.parse(&bytes)
209    }
210
211    pub async fn set_persona(&self, token: &Token, request: Persona) -> Result<Response, Error> {
212        let body = serde_json::to_vec(&request)?;
213        let bytes = self.send("PUT", "/personas", token, Some(body)).await?;
214        self.parse(&bytes)
215    }
216
217    pub async fn remove_persona(&self, token: &Token, name: &PersonaName) -> Result<(), Error> {
218        let uri = format!("/personas/{name}");
219        self.send("DELETE", &uri, token, None).await?;
220        Ok(())
221    }
222
223    pub async fn get_persona(&self, token: &Token, name: &PersonaName) -> Result<Response, Error> {
224        let uri = format!("/personas/{name}");
225        let bytes = self.send("GET", &uri, token, None).await?;
226        self.parse(&bytes)
227    }
228
229    pub async fn list_personas(&self, token: &Token) -> Result<Response, Error> {
230        let bytes = self.send("GET", "/personas", token, None).await?;
231        self.parse(&bytes)
232    }
233
234    pub async fn set_texture(&self, token: &Token, request: Texture) -> Result<Response, Error> {
235        let body = serde_json::to_vec(&request)?;
236        let bytes = self.send("PUT", "/textures", token, Some(body)).await?;
237        self.parse(&bytes)
238    }
239
240    pub async fn remove_texture(&self, token: &Token, name: &TextureName) -> Result<(), Error> {
241        let uri = format!("/textures/{name}");
242        self.send("DELETE", &uri, token, None).await?;
243        Ok(())
244    }
245
246    pub async fn get_texture(&self, token: &Token, name: &TextureName) -> Result<Response, Error> {
247        let uri = format!("/textures/{name}");
248        let bytes = self.send("GET", &uri, token, None).await?;
249        self.parse(&bytes)
250    }
251
252    pub async fn list_textures(&self, token: &Token) -> Result<Response, Error> {
253        let bytes = self.send("GET", "/textures", token, None).await?;
254        self.parse(&bytes)
255    }
256
257    pub async fn set_urge(&self, token: &Token, request: Urge) -> Result<Response, Error> {
258        let body = serde_json::to_vec(&request)?;
259        let bytes = self.send("PUT", "/urges", token, Some(body)).await?;
260        self.parse(&bytes)
261    }
262
263    pub async fn remove_urge(&self, token: &Token, name: &UrgeName) -> Result<(), Error> {
264        let uri = format!("/urges/{name}");
265        self.send("DELETE", &uri, token, None).await?;
266        Ok(())
267    }
268
269    pub async fn get_urge(&self, token: &Token, name: &UrgeName) -> Result<Response, Error> {
270        let uri = format!("/urges/{name}");
271        let bytes = self.send("GET", &uri, token, None).await?;
272        self.parse(&bytes)
273    }
274
275    pub async fn list_urges(&self, token: &Token) -> Result<Response, Error> {
276        let bytes = self.send("GET", "/urges", token, None).await?;
277        self.parse(&bytes)
278    }
279
280    pub async fn get_pressure(&self, token: &Token, agent: &AgentName) -> Result<Response, Error> {
281        self.parse(
282            &self
283                .send("GET", &format!("/pressures/{agent}"), token, None)
284                .await?,
285        )
286    }
287
288    pub async fn list_pressures(&self, token: &Token) -> Result<Response, Error> {
289        self.parse(&self.send("GET", "/pressures", token, None).await?)
290    }
291
292    pub async fn set_level(&self, token: &Token, request: Level) -> Result<Response, Error> {
293        self.parse(
294            &self
295                .send("PUT", "/levels", token, Some(serde_json::to_vec(&request)?))
296                .await?,
297        )
298    }
299
300    pub async fn remove_level(&self, token: &Token, name: &LevelName) -> Result<(), Error> {
301        let uri = format!("/levels/{name}");
302        self.send("DELETE", &uri, token, None).await?;
303        Ok(())
304    }
305
306    pub async fn get_level(&self, token: &Token, name: &LevelName) -> Result<Response, Error> {
307        let uri = format!("/levels/{name}");
308        let bytes = self.send("GET", &uri, token, None).await?;
309        self.parse(&bytes)
310    }
311
312    pub async fn list_levels(&self, token: &Token) -> Result<Response, Error> {
313        let bytes = self.send("GET", "/levels", token, None).await?;
314        self.parse(&bytes)
315    }
316
317    pub async fn set_storage(
318        &self,
319        token: &Token,
320        key: &StorageKey,
321        data: Vec<u8>,
322        description: &str,
323    ) -> Result<Response, Error> {
324        let storage_ref = StorageRef::encode(key);
325        let uri = format!("/storage/{storage_ref}");
326        let headers = vec![("x-storage-description", description)];
327        let (status, response_body) = self
328            .client
329            .authenticated_binary_request("PUT", &uri, token, data, &headers)
330            .await?;
331
332        if status >= 400 {
333            let body_str = String::from_utf8_lossy(&response_body).to_string();
334            return Err(ResponseError {
335                status,
336                body: body_str,
337            })?;
338        }
339
340        self.parse(&response_body)
341    }
342
343    pub async fn get_storage(&self, token: &Token, key: &StorageKey) -> Result<Response, Error> {
344        let storage_ref = StorageRef::encode(key);
345        let uri = format!("/storage/{storage_ref}");
346        let bytes = self.send("GET", &uri, token, None).await?;
347        self.parse(&bytes)
348    }
349
350    pub async fn get_storage_content(
351        &self,
352        token: &Token,
353        key: &StorageKey,
354    ) -> Result<Vec<u8>, Error> {
355        let storage_ref = StorageRef::encode(key);
356        let uri = format!("/storage/{storage_ref}/content");
357        self.send("GET", &uri, token, None).await
358    }
359
360    pub async fn list_storage(&self, token: &Token) -> Result<Response, Error> {
361        let bytes = self.send("GET", "/storage", token, None).await?;
362        self.parse(&bytes)
363    }
364
365    pub async fn remove_storage(&self, token: &Token, key: &StorageKey) -> Result<(), Error> {
366        let storage_ref = StorageRef::encode(key);
367        let uri = format!("/storage/{storage_ref}");
368        self.send("DELETE", &uri, token, None).await?;
369        Ok(())
370    }
371
372    pub async fn dream(&self, token: &Token, agent_name: &AgentName) -> Result<Response, Error> {
373        let uri = format!("/dream/{agent_name}");
374        let bytes = self.send("POST", &uri, token, None).await?;
375        self.parse(&bytes)
376    }
377
378    pub async fn introspect(
379        &self,
380        token: &Token,
381        agent_name: &AgentName,
382    ) -> Result<Response, Error> {
383        let uri = format!("/introspect/{agent_name}");
384        let bytes = self.send("POST", &uri, token, None).await?;
385        self.parse(&bytes)
386    }
387
388    // -- Sensation methods --
389
390    pub async fn set_sensation(
391        &self,
392        token: &Token,
393        request: Sensation,
394    ) -> Result<Response, Error> {
395        let body = serde_json::to_vec(&request)?;
396        let bytes = self.send("PUT", "/sensations", token, Some(body)).await?;
397        self.parse(&bytes)
398    }
399
400    pub async fn remove_sensation(&self, token: &Token, name: &SensationName) -> Result<(), Error> {
401        let uri = format!("/sensations/{name}");
402        self.send("DELETE", &uri, token, None).await?;
403        Ok(())
404    }
405
406    pub async fn get_sensation(
407        &self,
408        token: &Token,
409        name: &SensationName,
410    ) -> Result<Response, Error> {
411        let uri = format!("/sensations/{name}");
412        let bytes = self.send("GET", &uri, token, None).await?;
413        self.parse(&bytes)
414    }
415
416    pub async fn list_sensations(&self, token: &Token) -> Result<Response, Error> {
417        let bytes = self.send("GET", "/sensations", token, None).await?;
418        self.parse(&bytes)
419    }
420
421    // -- Nature methods --
422
423    pub async fn set_nature(&self, token: &Token, request: Nature) -> Result<Response, Error> {
424        let body = serde_json::to_vec(&request)?;
425        let bytes = self.send("PUT", "/natures", token, Some(body)).await?;
426        self.parse(&bytes)
427    }
428
429    pub async fn remove_nature(&self, token: &Token, name: &NatureName) -> Result<(), Error> {
430        let uri = format!("/natures/{name}");
431        self.send("DELETE", &uri, token, None).await?;
432        Ok(())
433    }
434
435    pub async fn get_nature(&self, token: &Token, name: &NatureName) -> Result<Response, Error> {
436        let uri = format!("/natures/{name}");
437        let bytes = self.send("GET", &uri, token, None).await?;
438        self.parse(&bytes)
439    }
440
441    pub async fn list_natures(&self, token: &Token) -> Result<Response, Error> {
442        let bytes = self.send("GET", "/natures", token, None).await?;
443        self.parse(&bytes)
444    }
445
446    // -- Connection methods --
447
448    pub async fn create_connection(
449        &self,
450        token: &Token,
451        request: CreateConnectionRequest,
452    ) -> Result<Response, Error> {
453        let body = serde_json::to_vec(&request)?;
454        let bytes = self.send("POST", "/connections", token, Some(body)).await?;
455        self.parse(&bytes)
456    }
457
458    pub async fn get_connection(
459        &self,
460        token: &Token,
461        id: &ConnectionId,
462    ) -> Result<Response, Error> {
463        let uri = format!("/connections/{id}");
464        let bytes = self.send("GET", &uri, token, None).await?;
465        self.parse(&bytes)
466    }
467
468    pub async fn list_connections(
469        &self,
470        token: &Token,
471        nature: Option<&NatureName>,
472        entity_ref: Option<&RefToken>,
473    ) -> Result<Response, Error> {
474        let mut params = Vec::new();
475        if let Some(nature) = nature {
476            params.push(format!("nature={}", urlencoding::encode(nature.as_str())));
477        }
478        if let Some(entity_ref) = entity_ref {
479            params.push(format!(
480                "entity_ref={}",
481                urlencoding::encode(&entity_ref.to_string())
482            ));
483        }
484
485        let uri = if params.is_empty() {
486            "/connections".to_string()
487        } else {
488            format!("/connections?{}", params.join("&"))
489        };
490
491        let bytes = self.send("GET", &uri, token, None).await?;
492        self.parse(&bytes)
493    }
494
495    pub async fn remove_connection(&self, token: &Token, id: &ConnectionId) -> Result<(), Error> {
496        let uri = format!("/connections/{id}");
497        self.send("DELETE", &uri, token, None).await?;
498        Ok(())
499    }
500
501    // -- Experience methods --
502
503    pub async fn create_experience(
504        &self,
505        token: &Token,
506        request: CreateExperienceRequest,
507    ) -> Result<Response, Error> {
508        let body = serde_json::to_vec(&request)?;
509        let bytes = self.send("POST", "/experiences", token, Some(body)).await?;
510        self.parse(&bytes)
511    }
512
513    pub async fn get_experience(
514        &self,
515        token: &Token,
516        id: &ExperienceId,
517    ) -> Result<Response, Error> {
518        let uri = format!("/experiences/{id}");
519        let bytes = self.send("GET", &uri, token, None).await?;
520        self.parse(&bytes)
521    }
522
523    pub async fn list_experiences(
524        &self,
525        token: &Token,
526        agent: Option<&AgentName>,
527        sensation: Option<&SensationName>,
528    ) -> Result<Response, Error> {
529        let mut params = Vec::new();
530        if let Some(agent) = agent {
531            params.push(format!("agent={}", urlencoding::encode(agent.as_str())));
532        }
533        if let Some(sensation) = sensation {
534            params.push(format!(
535                "sensation={}",
536                urlencoding::encode(sensation.as_str())
537            ));
538        }
539
540        let uri = if params.is_empty() {
541            "/experiences".to_string()
542        } else {
543            format!("/experiences?{}", params.join("&"))
544        };
545
546        let bytes = self.send("GET", &uri, token, None).await?;
547        self.parse(&bytes)
548    }
549
550    pub async fn update_experience_description(
551        &self,
552        token: &Token,
553        experience_id: &ExperienceId,
554        request: UpdateExperienceDescriptionRequest,
555    ) -> Result<Response, Error> {
556        let uri = format!("/experiences/{experience_id}/description");
557        let body = serde_json::to_vec(&request)?;
558        let bytes = self.send("PUT", &uri, token, Some(body)).await?;
559        self.parse(&bytes)
560    }
561
562    pub async fn update_experience_sensation(
563        &self,
564        token: &Token,
565        experience_id: &ExperienceId,
566        request: UpdateExperienceSensationRequest,
567    ) -> Result<Response, Error> {
568        let uri = format!("/experiences/{experience_id}/sensation");
569        let body = serde_json::to_vec(&request)?;
570        let bytes = self.send("PUT", &uri, token, Some(body)).await?;
571        self.parse(&bytes)
572    }
573
574    // -- Lifecycle methods --
575
576    pub async fn wake(&self, token: &Token, agent_name: &AgentName) -> Result<Response, Error> {
577        let uri = format!("/lifecycle/wake/{agent_name}");
578        let bytes = self.send("POST", &uri, token, None).await?;
579        self.parse(&bytes)
580    }
581
582    pub async fn sleep(&self, token: &Token, agent_name: &AgentName) -> Result<Response, Error> {
583        let uri = format!("/lifecycle/sleep/{agent_name}");
584        let bytes = self.send("POST", &uri, token, None).await?;
585        self.parse(&bytes)
586    }
587
588    pub async fn emerge(
589        &self,
590        token: &Token,
591        request: CreateAgentRequest,
592    ) -> Result<Response, Error> {
593        let body = serde_json::to_vec(&request)?;
594        let bytes = self
595            .send("POST", "/lifecycle/emerge", token, Some(body))
596            .await?;
597        self.parse(&bytes)
598    }
599
600    pub async fn recede(&self, token: &Token, agent_name: &AgentName) -> Result<(), Error> {
601        let uri = format!("/lifecycle/recede/{agent_name}");
602        self.send("POST", &uri, token, None).await?;
603        Ok(())
604    }
605
606    pub async fn reflect(&self, token: &Token, agent_name: &AgentName) -> Result<Response, Error> {
607        let uri = format!("/reflect/{agent_name}");
608        let bytes = self.send("POST", &uri, token, None).await?;
609        self.parse(&bytes)
610    }
611
612    pub async fn sense(&self, token: &Token, agent_name: &AgentName) -> Result<Response, Error> {
613        let uri = format!("/sense/{agent_name}");
614        let bytes = self.send("POST", &uri, token, None).await?;
615        self.parse(&bytes)
616    }
617
618    pub async fn search(
619        &self,
620        token: &Token,
621        query: &str,
622        agent: Option<&AgentName>,
623    ) -> Result<Response, Error> {
624        let mut uri = format!("/search?query={}", urlencoding::encode(query));
625        if let Some(agent) = agent {
626            uri.push_str(&format!("&agent={}", urlencoding::encode(agent.as_str())));
627        }
628        let bytes = self.send("GET", &uri, token, None).await?;
629        self.parse(&bytes)
630    }
631
632    pub async fn health(&self) -> Result<(), Error> {
633        let (status, response_body) = self.client.request("GET", "/health", vec![]).await?;
634
635        if status >= 400 {
636            let body_str = String::from_utf8_lossy(&response_body).to_string();
637            return Err(ResponseError {
638                status,
639                body: body_str,
640            })?;
641        }
642
643        Ok(())
644    }
645}