1use cccc_sdk::{CCCCClient, VoiceDocumentLibraryAction as Action};
3use serde_json::{json, Map, Value};
4
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let home = std::path::PathBuf::from(
7 std::env::var_os("CCCC_HOME").expect("isolated CCCC_HOME required"),
8 );
9 let client = CCCCClient::discover()?;
10 let call = |op: &str, args: Value| client.call(op, args.as_object().expect("object").clone());
11 let group = call("group_create", json!({"title":"Rust SDK release fixture"}))?;
12 let group_id = group["group"]["group_id"].as_str().expect("group id");
13 call(
14 "group_set_state",
15 json!({"group_id":group_id,"state":"paused"}),
16 )?;
17 call(
18 "actor_add",
19 json!({"group_id":group_id,"actor_id":"fixture","runtime":"custom",
20 "command":[std::env::current_exe()?.to_string_lossy()]}),
21 )?;
22 let event = call(
23 "send",
24 json!({"group_id":group_id,"text":"release mail","message_mode":"mail",
25 "to":["fixture"],"by":"user"}),
26 )?;
27 let event_id = event["event"]["id"].as_str().expect("event id");
28 let exact = client.message_history_exact(group_id, "fixture", event_id, "user")?;
29 assert_eq!(exact["messages"][0]["id"], event_id);
30 let summary = client.inbox_summary(group_id, "2020-01-01T00:00:00Z", "user")?;
31 assert_eq!(
32 summary
33 .actors
34 .iter()
35 .find(|row| row.actor_id == "fixture")
36 .unwrap()
37 .awaiting_count,
38 1
39 );
40 let path = "notes/sdk.md";
41 call(
42 "assistant_voice_document_save",
43 json!({"group_id":group_id,"document_path":path,"content":"# SDK fixture"}),
44 )?;
45 let library = client.assistant_voice_document_library_update(
46 group_id,
47 &Action::CreateFolder {
48 name: "Meetings".into(),
49 },
50 None,
51 )?;
52 let folder_id = library.folders[0].folder_id.clone();
53 for action in [
54 Action::RenameFolder {
55 folder_id: folder_id.clone(),
56 name: "Notes".into(),
57 },
58 Action::Rename {
59 document_path: path.into(),
60 name: "Summary".into(),
61 },
62 Action::Move {
63 document_path: path.into(),
64 folder_id: folder_id.clone(),
65 },
66 ] {
67 client.assistant_voice_document_library_update(group_id, &action, None)?;
68 }
69 call(
70 "assistant_voice_document_archive",
71 json!({"group_id":group_id,"document_path":path}),
72 )?;
73 let library = client.assistant_voice_document_library(group_id)?;
74 assert_eq!(library.documents[0]["status"], "archived");
75 let file = home
76 .join("voice-secretary")
77 .join(group_id)
78 .join("documents")
79 .join(path);
80 assert_eq!(std::fs::read_to_string(&file)?, "# SDK fixture");
81 let library = client.assistant_voice_document_library_update(
82 group_id,
83 &Action::Restore {
84 document_path: path.into(),
85 },
86 None,
87 )?;
88 assert_eq!(library.documents[0]["status"], "active");
89 assert_eq!(library.documents[0]["folder_id"], folder_id);
90 client.assistant_voice_document_library_update(
91 group_id,
92 &Action::Move {
93 document_path: path.into(),
94 folder_id: "".into(),
95 },
96 None,
97 )?;
98 let order = vec![format!("folder:{folder_id}"), format!("document:{path}")];
99 let library = client.assistant_voice_document_library_update(
100 group_id,
101 &Action::ReorderRoot {
102 root_order: order.clone(),
103 },
104 None,
105 )?;
106 assert_eq!(library.root_order, order);
107 let library = client.assistant_voice_document_library_update(
108 group_id,
109 &Action::ReorderRoot { root_order: vec![] },
110 None,
111 )?;
112 assert!(library.root_order.is_empty());
113 client.assistant_voice_document_library_update(
114 group_id,
115 &Action::RemoveFolder { folder_id },
116 None,
117 )?;
118 let deleted = client.assistant_voice_document_delete(group_id, path, None)?;
119 assert_eq!(deleted["event"]["data"]["action"], "deleted");
120 assert!(!file.exists());
121 assert!(client
122 .assistant_voice_document_library(group_id)?
123 .documents
124 .is_empty());
125 assert!(client
126 .assistant_voice_document_library_update(
127 group_id,
128 &Action::Restore {
129 document_path: path.into()
130 },
131 None
132 )
133 .is_err());
134
135 for (id, runtime) in [
137 ("chat1", "web_model"),
138 ("chat2", "web_model"),
139 ("bot", "grok_web_model"),
140 ] {
141 let actor = call(
142 "actor_add",
143 json!({"group_id":group_id,"actor_id":id,"runtime":runtime}),
144 )?;
145 assert_eq!(actor["actor"]["runtime"], runtime);
146 assert_eq!(actor["actor"]["runner"], "headless");
147 }
148 let group: Map<String, Value> = client.group_show(group_id)?;
149 assert_eq!(group["group"]["state"], "paused");
150 println!("Installed Rust artifact: Voice library lifecycle and Web Model configuration passed");
151 Ok(())
152}