pub struct CCCCClient { /* private fields */ }Expand description
Blocking CCCC Daemon IPC v1 client.
Implementations§
Source§impl CCCCClient
impl CCCCClient
Sourcepub fn discover() -> Result<Self>
pub fn discover() -> Result<Self>
Discover the currently running daemon.
Examples found in repository?
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let client = CCCCClient::discover()?;
5 let requirements = CompatibilityRequirements {
6 minimum_ipc_version: 1,
7 operations: vec![
8 "groups",
9 "group_show",
10 "send",
11 "tracked_send",
12 "reply",
13 "inbox_read",
14 "message_history",
15 "context_get",
16 "context_sync",
17 "group_preamble_get",
18 "send_files",
19 "terminal_history",
20 "term_resize",
21 "web_model_delivery_preferences_get",
22 "web_model_delivery_preferences_update",
23 "web_model_runtime_recover_turn",
24 "assistant_voice_document_library",
25 "assistant_voice_document_library_update",
26 "assistant_voice_document_delete",
27 ],
28 ..Default::default()
29 };
30 let daemon = client.assert_compatible(&requirements)?;
31 println!(
32 "CCCC {} ({}) is compatible with IPC v{}",
33 daemon.version, daemon.implementation, daemon.ipc_v
34 );
35 Ok(())
36}More examples
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 let path = "notes/sdk.md";
18 call(
19 "assistant_voice_document_save",
20 json!({"group_id":group_id,"document_path":path,"content":"# SDK fixture"}),
21 )?;
22 let library = client.assistant_voice_document_library_update(
23 group_id,
24 &Action::CreateFolder {
25 name: "Meetings".into(),
26 },
27 None,
28 )?;
29 let folder_id = library.folders[0].folder_id.clone();
30 for action in [
31 Action::RenameFolder {
32 folder_id: folder_id.clone(),
33 name: "Notes".into(),
34 },
35 Action::Rename {
36 document_path: path.into(),
37 name: "Summary".into(),
38 },
39 Action::Move {
40 document_path: path.into(),
41 folder_id: folder_id.clone(),
42 },
43 ] {
44 client.assistant_voice_document_library_update(group_id, &action, None)?;
45 }
46 call(
47 "assistant_voice_document_archive",
48 json!({"group_id":group_id,"document_path":path}),
49 )?;
50 let library = client.assistant_voice_document_library(group_id)?;
51 assert_eq!(library.documents[0]["status"], "archived");
52 let file = home
53 .join("voice-secretary")
54 .join(group_id)
55 .join("documents")
56 .join(path);
57 assert_eq!(std::fs::read_to_string(&file)?, "# SDK fixture");
58 let library = client.assistant_voice_document_library_update(
59 group_id,
60 &Action::Restore {
61 document_path: path.into(),
62 },
63 None,
64 )?;
65 assert_eq!(library.documents[0]["status"], "active");
66 assert_eq!(library.documents[0]["folder_id"], folder_id);
67 client.assistant_voice_document_library_update(
68 group_id,
69 &Action::Move {
70 document_path: path.into(),
71 folder_id: "".into(),
72 },
73 None,
74 )?;
75 let order = vec![format!("folder:{folder_id}"), format!("document:{path}")];
76 let library = client.assistant_voice_document_library_update(
77 group_id,
78 &Action::ReorderRoot {
79 root_order: order.clone(),
80 },
81 None,
82 )?;
83 assert_eq!(library.root_order, order);
84 let library = client.assistant_voice_document_library_update(
85 group_id,
86 &Action::ReorderRoot { root_order: vec![] },
87 None,
88 )?;
89 assert!(library.root_order.is_empty());
90 client.assistant_voice_document_library_update(
91 group_id,
92 &Action::RemoveFolder { folder_id },
93 None,
94 )?;
95 let deleted = client.assistant_voice_document_delete(group_id, path, None)?;
96 assert_eq!(deleted["event"]["data"]["action"], "deleted");
97 assert!(!file.exists());
98 assert!(client
99 .assistant_voice_document_library(group_id)?
100 .documents
101 .is_empty());
102 assert!(client
103 .assistant_voice_document_library_update(
104 group_id,
105 &Action::Restore {
106 document_path: path.into()
107 },
108 None
109 )
110 .is_err());
111
112 // Persist configuration only. No browser/provider starts in this paused Group.
113 for (id, runtime) in [
114 ("chat1", "web_model"),
115 ("chat2", "web_model"),
116 ("bot", "grok_web_model"),
117 ] {
118 let actor = call(
119 "actor_add",
120 json!({"group_id":group_id,"actor_id":id,"runtime":runtime}),
121 )?;
122 assert_eq!(actor["actor"]["runtime"], runtime);
123 assert_eq!(actor["actor"]["runner"], "headless");
124 }
125 let group: Map<String, Value> = client.group_show(group_id)?;
126 assert_eq!(group["group"]["state"], "paused");
127 println!("Installed Rust artifact: Voice library lifecycle and Web Model configuration passed");
128 Ok(())
129}Sourcepub fn discover_in(cccc_home: Option<&Path>) -> Result<Self>
pub fn discover_in(cccc_home: Option<&Path>) -> Result<Self>
Discover a daemon under an explicit CCCC_HOME.
pub fn new(endpoint: DaemonEndpoint) -> Self
pub fn with_timeout(self, timeout: Duration) -> Self
Sourcepub fn endpoint(&self) -> &DaemonEndpoint
pub fn endpoint(&self) -> &DaemonEndpoint
The endpoint supplied to new or found during initial discovery.
Sourcepub fn current_endpoint(&self) -> DaemonEndpoint
pub fn current_endpoint(&self) -> DaemonEndpoint
The endpoint currently used for calls, including a successful rediscovery after daemon restart.
Sourcepub fn call(
&self,
op: &str,
args: Map<String, Value>,
) -> Result<Map<String, Value>>
pub fn call( &self, op: &str, args: Map<String, Value>, ) -> Result<Map<String, Value>>
Call any non-streaming daemon operation and return its result object.
Examples found in repository?
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 let path = "notes/sdk.md";
18 call(
19 "assistant_voice_document_save",
20 json!({"group_id":group_id,"document_path":path,"content":"# SDK fixture"}),
21 )?;
22 let library = client.assistant_voice_document_library_update(
23 group_id,
24 &Action::CreateFolder {
25 name: "Meetings".into(),
26 },
27 None,
28 )?;
29 let folder_id = library.folders[0].folder_id.clone();
30 for action in [
31 Action::RenameFolder {
32 folder_id: folder_id.clone(),
33 name: "Notes".into(),
34 },
35 Action::Rename {
36 document_path: path.into(),
37 name: "Summary".into(),
38 },
39 Action::Move {
40 document_path: path.into(),
41 folder_id: folder_id.clone(),
42 },
43 ] {
44 client.assistant_voice_document_library_update(group_id, &action, None)?;
45 }
46 call(
47 "assistant_voice_document_archive",
48 json!({"group_id":group_id,"document_path":path}),
49 )?;
50 let library = client.assistant_voice_document_library(group_id)?;
51 assert_eq!(library.documents[0]["status"], "archived");
52 let file = home
53 .join("voice-secretary")
54 .join(group_id)
55 .join("documents")
56 .join(path);
57 assert_eq!(std::fs::read_to_string(&file)?, "# SDK fixture");
58 let library = client.assistant_voice_document_library_update(
59 group_id,
60 &Action::Restore {
61 document_path: path.into(),
62 },
63 None,
64 )?;
65 assert_eq!(library.documents[0]["status"], "active");
66 assert_eq!(library.documents[0]["folder_id"], folder_id);
67 client.assistant_voice_document_library_update(
68 group_id,
69 &Action::Move {
70 document_path: path.into(),
71 folder_id: "".into(),
72 },
73 None,
74 )?;
75 let order = vec![format!("folder:{folder_id}"), format!("document:{path}")];
76 let library = client.assistant_voice_document_library_update(
77 group_id,
78 &Action::ReorderRoot {
79 root_order: order.clone(),
80 },
81 None,
82 )?;
83 assert_eq!(library.root_order, order);
84 let library = client.assistant_voice_document_library_update(
85 group_id,
86 &Action::ReorderRoot { root_order: vec![] },
87 None,
88 )?;
89 assert!(library.root_order.is_empty());
90 client.assistant_voice_document_library_update(
91 group_id,
92 &Action::RemoveFolder { folder_id },
93 None,
94 )?;
95 let deleted = client.assistant_voice_document_delete(group_id, path, None)?;
96 assert_eq!(deleted["event"]["data"]["action"], "deleted");
97 assert!(!file.exists());
98 assert!(client
99 .assistant_voice_document_library(group_id)?
100 .documents
101 .is_empty());
102 assert!(client
103 .assistant_voice_document_library_update(
104 group_id,
105 &Action::Restore {
106 document_path: path.into()
107 },
108 None
109 )
110 .is_err());
111
112 // Persist configuration only. No browser/provider starts in this paused Group.
113 for (id, runtime) in [
114 ("chat1", "web_model"),
115 ("chat2", "web_model"),
116 ("bot", "grok_web_model"),
117 ] {
118 let actor = call(
119 "actor_add",
120 json!({"group_id":group_id,"actor_id":id,"runtime":runtime}),
121 )?;
122 assert_eq!(actor["actor"]["runtime"], runtime);
123 assert_eq!(actor["actor"]["runner"], "headless");
124 }
125 let group: Map<String, Value> = client.group_show(group_id)?;
126 assert_eq!(group["group"]["state"], "paused");
127 println!("Installed Rust artifact: Voice library lifecycle and Web Model configuration passed");
128 Ok(())
129}Sourcepub fn call_raw(
&self,
op: &str,
args: Map<String, Value>,
) -> Result<DaemonResponse>
pub fn call_raw( &self, op: &str, args: Map<String, Value>, ) -> Result<DaemonResponse>
Call an operation and retain the full response envelope.
pub fn ping(&self) -> Result<PingResult>
pub fn groups(&self) -> Result<Map<String, Value>>
Sourcepub fn group_show(&self, group_id: &str) -> Result<Map<String, Value>>
pub fn group_show(&self, group_id: &str) -> Result<Map<String, Value>>
Examples found in repository?
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 let path = "notes/sdk.md";
18 call(
19 "assistant_voice_document_save",
20 json!({"group_id":group_id,"document_path":path,"content":"# SDK fixture"}),
21 )?;
22 let library = client.assistant_voice_document_library_update(
23 group_id,
24 &Action::CreateFolder {
25 name: "Meetings".into(),
26 },
27 None,
28 )?;
29 let folder_id = library.folders[0].folder_id.clone();
30 for action in [
31 Action::RenameFolder {
32 folder_id: folder_id.clone(),
33 name: "Notes".into(),
34 },
35 Action::Rename {
36 document_path: path.into(),
37 name: "Summary".into(),
38 },
39 Action::Move {
40 document_path: path.into(),
41 folder_id: folder_id.clone(),
42 },
43 ] {
44 client.assistant_voice_document_library_update(group_id, &action, None)?;
45 }
46 call(
47 "assistant_voice_document_archive",
48 json!({"group_id":group_id,"document_path":path}),
49 )?;
50 let library = client.assistant_voice_document_library(group_id)?;
51 assert_eq!(library.documents[0]["status"], "archived");
52 let file = home
53 .join("voice-secretary")
54 .join(group_id)
55 .join("documents")
56 .join(path);
57 assert_eq!(std::fs::read_to_string(&file)?, "# SDK fixture");
58 let library = client.assistant_voice_document_library_update(
59 group_id,
60 &Action::Restore {
61 document_path: path.into(),
62 },
63 None,
64 )?;
65 assert_eq!(library.documents[0]["status"], "active");
66 assert_eq!(library.documents[0]["folder_id"], folder_id);
67 client.assistant_voice_document_library_update(
68 group_id,
69 &Action::Move {
70 document_path: path.into(),
71 folder_id: "".into(),
72 },
73 None,
74 )?;
75 let order = vec![format!("folder:{folder_id}"), format!("document:{path}")];
76 let library = client.assistant_voice_document_library_update(
77 group_id,
78 &Action::ReorderRoot {
79 root_order: order.clone(),
80 },
81 None,
82 )?;
83 assert_eq!(library.root_order, order);
84 let library = client.assistant_voice_document_library_update(
85 group_id,
86 &Action::ReorderRoot { root_order: vec![] },
87 None,
88 )?;
89 assert!(library.root_order.is_empty());
90 client.assistant_voice_document_library_update(
91 group_id,
92 &Action::RemoveFolder { folder_id },
93 None,
94 )?;
95 let deleted = client.assistant_voice_document_delete(group_id, path, None)?;
96 assert_eq!(deleted["event"]["data"]["action"], "deleted");
97 assert!(!file.exists());
98 assert!(client
99 .assistant_voice_document_library(group_id)?
100 .documents
101 .is_empty());
102 assert!(client
103 .assistant_voice_document_library_update(
104 group_id,
105 &Action::Restore {
106 document_path: path.into()
107 },
108 None
109 )
110 .is_err());
111
112 // Persist configuration only. No browser/provider starts in this paused Group.
113 for (id, runtime) in [
114 ("chat1", "web_model"),
115 ("chat2", "web_model"),
116 ("bot", "grok_web_model"),
117 ] {
118 let actor = call(
119 "actor_add",
120 json!({"group_id":group_id,"actor_id":id,"runtime":runtime}),
121 )?;
122 assert_eq!(actor["actor"]["runtime"], runtime);
123 assert_eq!(actor["actor"]["runner"], "headless");
124 }
125 let group: Map<String, Value> = client.group_show(group_id)?;
126 assert_eq!(group["group"]["state"], "paused");
127 println!("Installed Rust artifact: Voice library lifecycle and Web Model configuration passed");
128 Ok(())
129}pub fn send( &self, group_id: &str, text: &str, message_mode: MessageMode, by: &str, ) -> Result<Map<String, Value>>
pub fn reply( &self, group_id: &str, reply_to: &str, text: &str, by: &str, ) -> Result<Map<String, Value>>
pub fn reply_with_mode( &self, group_id: &str, reply_to: &str, text: &str, message_mode: ReplyMessageMode, by: &str, ) -> Result<Map<String, Value>>
pub fn reply_request_cancel( &self, group_id: &str, source_event_id: &str, by: &str, ) -> Result<Map<String, Value>>
pub fn message_deliver( &self, group_id: &str, source_event_id: &str, actor_ids: &[&str], by: &str, force_ambiguous: bool, ) -> Result<Map<String, Value>>
pub fn inbox_peek( &self, group_id: &str, actor_id: &str, by: &str, limit: Option<u32>, ) -> Result<Map<String, Value>>
pub fn inbox_read( &self, group_id: &str, actor_id: &str, by: &str, limit: Option<u32>, ) -> Result<Map<String, Value>>
Sourcepub fn message_history(
&self,
group_id: &str,
actor_id: &str,
by: &str,
mode: MessageHistoryMode,
query: Option<&str>,
before_event_id: Option<&str>,
limit: Option<u32>,
) -> Result<Map<String, Value>>
pub fn message_history( &self, group_id: &str, actor_id: &str, by: &str, mode: MessageHistoryMode, query: Option<&str>, before_event_id: Option<&str>, limit: Option<u32>, ) -> Result<Map<String, Value>>
Inspect actor-visible chat history without consuming Mail.
pub fn context_get(&self, group_id: &str) -> Result<Map<String, Value>>
pub fn context_get_with_detail( &self, group_id: &str, detail: ContextDetail, ) -> Result<Map<String, Value>>
pub fn context_sync( &self, group_id: &str, by: &str, operations: Vec<Value>, ) -> Result<Map<String, Value>>
pub fn context_sync_checked( &self, group_id: &str, by: &str, operations: Vec<Value>, if_version: Option<&str>, dry_run: bool, ) -> Result<Map<String, Value>>
pub fn terminal_history( &self, group_id: &str, actor_id: &str, options: &TerminalHistoryOptions, ) -> Result<TerminalHistoryResult>
pub fn terminal_since( &self, group_id: &str, actor_id: &str, after: u64, options: &TerminalSinceOptions, ) -> Result<TerminalSinceResult>
pub fn terminal_snapshot( &self, group_id: &str, actor_id: &str, options: &TerminalSnapshotOptions, ) -> Result<TerminalSnapshotResult>
Sourcepub fn term_resize(
&self,
group_id: &str,
actor_id: &str,
cols: u32,
rows: u32,
) -> Result<TerminalResizeResult>
pub fn term_resize( &self, group_id: &str, actor_id: &str, cols: u32, rows: u32, ) -> Result<TerminalResizeResult>
Resize a PTY using the normative op, with a compatibility fallback for
Rust daemon builds that temporarily exposed terminal_resize instead.
pub fn web_model_delivery_preferences_get( &self, group_id: &str, actor_id: &str, ) -> Result<WebModelDeliveryPreferencesResult>
pub fn web_model_delivery_preferences_update( &self, group_id: &str, actor_id: &str, mode: WebModelDeliveryMode, by: &str, ) -> Result<WebModelDeliveryPreferencesResult>
pub fn web_model_runtime_recover_turn( &self, group_id: &str, actor_id: &str, event_ids: &[String], ) -> Result<WebModelRuntimeRecoverTurnResult>
Sourcepub fn assert_compatible(
&self,
requirements: &CompatibilityRequirements<'_>,
) -> Result<PingResult>
pub fn assert_compatible( &self, requirements: &CompatibilityRequirements<'_>, ) -> Result<PingResult>
Validate protocol, advertised capabilities, and actual op recognition.
Examples found in repository?
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let client = CCCCClient::discover()?;
5 let requirements = CompatibilityRequirements {
6 minimum_ipc_version: 1,
7 operations: vec![
8 "groups",
9 "group_show",
10 "send",
11 "tracked_send",
12 "reply",
13 "inbox_read",
14 "message_history",
15 "context_get",
16 "context_sync",
17 "group_preamble_get",
18 "send_files",
19 "terminal_history",
20 "term_resize",
21 "web_model_delivery_preferences_get",
22 "web_model_delivery_preferences_update",
23 "web_model_runtime_recover_turn",
24 "assistant_voice_document_library",
25 "assistant_voice_document_library_update",
26 "assistant_voice_document_delete",
27 ],
28 ..Default::default()
29 };
30 let daemon = client.assert_compatible(&requirements)?;
31 println!(
32 "CCCC {} ({}) is compatible with IPC v{}",
33 daemon.version, daemon.implementation, daemon.ipc_v
34 );
35 Ok(())
36}Source§impl CCCCClient
impl CCCCClient
pub fn connect_catalog( &self, options: &ConnectCatalogOptions, ) -> Result<Map<String, Value>>
pub fn connect_send( &self, options: &ConnectSendOptions, ) -> Result<Map<String, Value>>
Sourcepub fn connect_send_files(
&self,
options: &ConnectSendOptions,
paths: &[String],
) -> Result<Map<String, Value>>
pub fn connect_send_files( &self, options: &ConnectSendOptions, paths: &[String], ) -> Result<Map<String, Value>>
Paths are read by the daemon within the source Group’s active scope.
Source§impl CCCCClient
impl CCCCClient
Sourcepub fn assistant_voice_document_library(
&self,
group_id: &str,
) -> Result<VoiceDocumentLibrary>
pub fn assistant_voice_document_library( &self, group_id: &str, ) -> Result<VoiceDocumentLibrary>
Read the stored library without workspace discovery or content reconciliation.
Examples found in repository?
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 let path = "notes/sdk.md";
18 call(
19 "assistant_voice_document_save",
20 json!({"group_id":group_id,"document_path":path,"content":"# SDK fixture"}),
21 )?;
22 let library = client.assistant_voice_document_library_update(
23 group_id,
24 &Action::CreateFolder {
25 name: "Meetings".into(),
26 },
27 None,
28 )?;
29 let folder_id = library.folders[0].folder_id.clone();
30 for action in [
31 Action::RenameFolder {
32 folder_id: folder_id.clone(),
33 name: "Notes".into(),
34 },
35 Action::Rename {
36 document_path: path.into(),
37 name: "Summary".into(),
38 },
39 Action::Move {
40 document_path: path.into(),
41 folder_id: folder_id.clone(),
42 },
43 ] {
44 client.assistant_voice_document_library_update(group_id, &action, None)?;
45 }
46 call(
47 "assistant_voice_document_archive",
48 json!({"group_id":group_id,"document_path":path}),
49 )?;
50 let library = client.assistant_voice_document_library(group_id)?;
51 assert_eq!(library.documents[0]["status"], "archived");
52 let file = home
53 .join("voice-secretary")
54 .join(group_id)
55 .join("documents")
56 .join(path);
57 assert_eq!(std::fs::read_to_string(&file)?, "# SDK fixture");
58 let library = client.assistant_voice_document_library_update(
59 group_id,
60 &Action::Restore {
61 document_path: path.into(),
62 },
63 None,
64 )?;
65 assert_eq!(library.documents[0]["status"], "active");
66 assert_eq!(library.documents[0]["folder_id"], folder_id);
67 client.assistant_voice_document_library_update(
68 group_id,
69 &Action::Move {
70 document_path: path.into(),
71 folder_id: "".into(),
72 },
73 None,
74 )?;
75 let order = vec![format!("folder:{folder_id}"), format!("document:{path}")];
76 let library = client.assistant_voice_document_library_update(
77 group_id,
78 &Action::ReorderRoot {
79 root_order: order.clone(),
80 },
81 None,
82 )?;
83 assert_eq!(library.root_order, order);
84 let library = client.assistant_voice_document_library_update(
85 group_id,
86 &Action::ReorderRoot { root_order: vec![] },
87 None,
88 )?;
89 assert!(library.root_order.is_empty());
90 client.assistant_voice_document_library_update(
91 group_id,
92 &Action::RemoveFolder { folder_id },
93 None,
94 )?;
95 let deleted = client.assistant_voice_document_delete(group_id, path, None)?;
96 assert_eq!(deleted["event"]["data"]["action"], "deleted");
97 assert!(!file.exists());
98 assert!(client
99 .assistant_voice_document_library(group_id)?
100 .documents
101 .is_empty());
102 assert!(client
103 .assistant_voice_document_library_update(
104 group_id,
105 &Action::Restore {
106 document_path: path.into()
107 },
108 None
109 )
110 .is_err());
111
112 // Persist configuration only. No browser/provider starts in this paused Group.
113 for (id, runtime) in [
114 ("chat1", "web_model"),
115 ("chat2", "web_model"),
116 ("bot", "grok_web_model"),
117 ] {
118 let actor = call(
119 "actor_add",
120 json!({"group_id":group_id,"actor_id":id,"runtime":runtime}),
121 )?;
122 assert_eq!(actor["actor"]["runtime"], runtime);
123 assert_eq!(actor["actor"]["runner"], "headless");
124 }
125 let group: Map<String, Value> = client.group_show(group_id)?;
126 assert_eq!(group["group"]["state"], "paused");
127 println!("Installed Rust artifact: Voice library lifecycle and Web Model configuration passed");
128 Ok(())
129}Sourcepub fn assistant_voice_document_library_update(
&self,
group_id: &str,
action: &VoiceDocumentLibraryAction,
by: Option<&str>,
) -> Result<VoiceDocumentLibrary>
pub fn assistant_voice_document_library_update( &self, group_id: &str, action: &VoiceDocumentLibraryAction, by: Option<&str>, ) -> Result<VoiceDocumentLibrary>
The daemon enforces writer permission; omitted by means the local user.
Examples found in repository?
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 let path = "notes/sdk.md";
18 call(
19 "assistant_voice_document_save",
20 json!({"group_id":group_id,"document_path":path,"content":"# SDK fixture"}),
21 )?;
22 let library = client.assistant_voice_document_library_update(
23 group_id,
24 &Action::CreateFolder {
25 name: "Meetings".into(),
26 },
27 None,
28 )?;
29 let folder_id = library.folders[0].folder_id.clone();
30 for action in [
31 Action::RenameFolder {
32 folder_id: folder_id.clone(),
33 name: "Notes".into(),
34 },
35 Action::Rename {
36 document_path: path.into(),
37 name: "Summary".into(),
38 },
39 Action::Move {
40 document_path: path.into(),
41 folder_id: folder_id.clone(),
42 },
43 ] {
44 client.assistant_voice_document_library_update(group_id, &action, None)?;
45 }
46 call(
47 "assistant_voice_document_archive",
48 json!({"group_id":group_id,"document_path":path}),
49 )?;
50 let library = client.assistant_voice_document_library(group_id)?;
51 assert_eq!(library.documents[0]["status"], "archived");
52 let file = home
53 .join("voice-secretary")
54 .join(group_id)
55 .join("documents")
56 .join(path);
57 assert_eq!(std::fs::read_to_string(&file)?, "# SDK fixture");
58 let library = client.assistant_voice_document_library_update(
59 group_id,
60 &Action::Restore {
61 document_path: path.into(),
62 },
63 None,
64 )?;
65 assert_eq!(library.documents[0]["status"], "active");
66 assert_eq!(library.documents[0]["folder_id"], folder_id);
67 client.assistant_voice_document_library_update(
68 group_id,
69 &Action::Move {
70 document_path: path.into(),
71 folder_id: "".into(),
72 },
73 None,
74 )?;
75 let order = vec![format!("folder:{folder_id}"), format!("document:{path}")];
76 let library = client.assistant_voice_document_library_update(
77 group_id,
78 &Action::ReorderRoot {
79 root_order: order.clone(),
80 },
81 None,
82 )?;
83 assert_eq!(library.root_order, order);
84 let library = client.assistant_voice_document_library_update(
85 group_id,
86 &Action::ReorderRoot { root_order: vec![] },
87 None,
88 )?;
89 assert!(library.root_order.is_empty());
90 client.assistant_voice_document_library_update(
91 group_id,
92 &Action::RemoveFolder { folder_id },
93 None,
94 )?;
95 let deleted = client.assistant_voice_document_delete(group_id, path, None)?;
96 assert_eq!(deleted["event"]["data"]["action"], "deleted");
97 assert!(!file.exists());
98 assert!(client
99 .assistant_voice_document_library(group_id)?
100 .documents
101 .is_empty());
102 assert!(client
103 .assistant_voice_document_library_update(
104 group_id,
105 &Action::Restore {
106 document_path: path.into()
107 },
108 None
109 )
110 .is_err());
111
112 // Persist configuration only. No browser/provider starts in this paused Group.
113 for (id, runtime) in [
114 ("chat1", "web_model"),
115 ("chat2", "web_model"),
116 ("bot", "grok_web_model"),
117 ] {
118 let actor = call(
119 "actor_add",
120 json!({"group_id":group_id,"actor_id":id,"runtime":runtime}),
121 )?;
122 assert_eq!(actor["actor"]["runtime"], runtime);
123 assert_eq!(actor["actor"]["runner"], "headless");
124 }
125 let group: Map<String, Value> = client.group_show(group_id)?;
126 assert_eq!(group["group"]["state"], "paused");
127 println!("Installed Rust artifact: Voice library lifecycle and Web Model configuration passed");
128 Ok(())
129}Sourcepub fn assistant_voice_document_delete(
&self,
group_id: &str,
document_path: &str,
by: Option<&str>,
) -> Result<Map<String, Value>>
pub fn assistant_voice_document_delete( &self, group_id: &str, document_path: &str, by: Option<&str>, ) -> Result<Map<String, Value>>
Permanently delete the Markdown file. Archive instead to retain the file.
Examples found in repository?
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 let path = "notes/sdk.md";
18 call(
19 "assistant_voice_document_save",
20 json!({"group_id":group_id,"document_path":path,"content":"# SDK fixture"}),
21 )?;
22 let library = client.assistant_voice_document_library_update(
23 group_id,
24 &Action::CreateFolder {
25 name: "Meetings".into(),
26 },
27 None,
28 )?;
29 let folder_id = library.folders[0].folder_id.clone();
30 for action in [
31 Action::RenameFolder {
32 folder_id: folder_id.clone(),
33 name: "Notes".into(),
34 },
35 Action::Rename {
36 document_path: path.into(),
37 name: "Summary".into(),
38 },
39 Action::Move {
40 document_path: path.into(),
41 folder_id: folder_id.clone(),
42 },
43 ] {
44 client.assistant_voice_document_library_update(group_id, &action, None)?;
45 }
46 call(
47 "assistant_voice_document_archive",
48 json!({"group_id":group_id,"document_path":path}),
49 )?;
50 let library = client.assistant_voice_document_library(group_id)?;
51 assert_eq!(library.documents[0]["status"], "archived");
52 let file = home
53 .join("voice-secretary")
54 .join(group_id)
55 .join("documents")
56 .join(path);
57 assert_eq!(std::fs::read_to_string(&file)?, "# SDK fixture");
58 let library = client.assistant_voice_document_library_update(
59 group_id,
60 &Action::Restore {
61 document_path: path.into(),
62 },
63 None,
64 )?;
65 assert_eq!(library.documents[0]["status"], "active");
66 assert_eq!(library.documents[0]["folder_id"], folder_id);
67 client.assistant_voice_document_library_update(
68 group_id,
69 &Action::Move {
70 document_path: path.into(),
71 folder_id: "".into(),
72 },
73 None,
74 )?;
75 let order = vec![format!("folder:{folder_id}"), format!("document:{path}")];
76 let library = client.assistant_voice_document_library_update(
77 group_id,
78 &Action::ReorderRoot {
79 root_order: order.clone(),
80 },
81 None,
82 )?;
83 assert_eq!(library.root_order, order);
84 let library = client.assistant_voice_document_library_update(
85 group_id,
86 &Action::ReorderRoot { root_order: vec![] },
87 None,
88 )?;
89 assert!(library.root_order.is_empty());
90 client.assistant_voice_document_library_update(
91 group_id,
92 &Action::RemoveFolder { folder_id },
93 None,
94 )?;
95 let deleted = client.assistant_voice_document_delete(group_id, path, None)?;
96 assert_eq!(deleted["event"]["data"]["action"], "deleted");
97 assert!(!file.exists());
98 assert!(client
99 .assistant_voice_document_library(group_id)?
100 .documents
101 .is_empty());
102 assert!(client
103 .assistant_voice_document_library_update(
104 group_id,
105 &Action::Restore {
106 document_path: path.into()
107 },
108 None
109 )
110 .is_err());
111
112 // Persist configuration only. No browser/provider starts in this paused Group.
113 for (id, runtime) in [
114 ("chat1", "web_model"),
115 ("chat2", "web_model"),
116 ("bot", "grok_web_model"),
117 ] {
118 let actor = call(
119 "actor_add",
120 json!({"group_id":group_id,"actor_id":id,"runtime":runtime}),
121 )?;
122 assert_eq!(actor["actor"]["runtime"], runtime);
123 assert_eq!(actor["actor"]["runner"], "headless");
124 }
125 let group: Map<String, Value> = client.group_show(group_id)?;
126 assert_eq!(group["group"]["state"], "paused");
127 println!("Installed Rust artifact: Voice library lifecycle and Web Model configuration passed");
128 Ok(())
129}