1pub mod permissions;
2
3use agent_client_protocol as acp;
4use tokio::sync::{mpsc, oneshot};
5
6use crate::bridge::events::{
7 BridgeEvent, PermissionKind, PermissionOption, PermissionOutcome, ToolCallInfo,
8};
9
10pub struct BridgedAcpClient {
17 pub evt_tx: mpsc::UnboundedSender<BridgeEvent>,
18}
19
20#[async_trait::async_trait(?Send)]
21impl acp::Client for BridgedAcpClient {
22 async fn request_permission(
23 &self,
24 args: acp::RequestPermissionRequest,
25 ) -> acp::Result<acp::RequestPermissionResponse> {
26 let tool = ToolCallInfo {
28 name: args.tool_call.fields.title.clone().unwrap_or_default(),
29 description: None,
30 };
31
32 let options: Vec<PermissionOption> = args
34 .options
35 .iter()
36 .map(|o| PermissionOption {
37 option_id: o.option_id.0.to_string(),
38 name: o.name.clone(),
39 kind: match o.kind {
40 acp::PermissionOptionKind::AllowOnce
41 | acp::PermissionOptionKind::AllowAlways => PermissionKind::Allow,
42 _ => PermissionKind::Deny,
43 },
44 })
45 .collect();
46
47 let (reply_tx, reply_rx) = oneshot::channel();
49
50 let _ = self.evt_tx.send(BridgeEvent::PermissionRequest {
52 tool,
53 options,
54 reply: reply_tx,
55 });
56
57 let outcome = reply_rx.await.unwrap_or(PermissionOutcome::Cancelled);
59
60 let acp_outcome = match outcome {
62 PermissionOutcome::Selected { option_id } => acp::RequestPermissionOutcome::Selected(
63 acp::SelectedPermissionOutcome::new(option_id),
64 ),
65 PermissionOutcome::Cancelled => acp::RequestPermissionOutcome::Cancelled,
66 };
67
68 Ok(acp::RequestPermissionResponse::new(acp_outcome))
69 }
70
71 async fn session_notification(&self, args: acp::SessionNotification) -> acp::Result<()> {
72 match args.update {
73 acp::SessionUpdate::AgentMessageChunk(chunk) => {
74 if let acp::ContentBlock::Text(text_content) = chunk.content {
75 let _ = self.evt_tx.send(BridgeEvent::TextChunk {
76 text: text_content.text,
77 });
78 }
79 }
80 acp::SessionUpdate::ToolCall(tool_call) => {
81 let _ = self.evt_tx.send(BridgeEvent::ToolUse {
82 name: tool_call.title.clone(),
83 });
84 }
85 _ => {
86 }
88 }
89 Ok(())
90 }
91}