Skip to content

Commit 20eea6b

Browse files
committed
feat(acp-nats): add terminal_create client handler
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
1 parent c5832c8 commit 20eea6b

5 files changed

Lines changed: 614 additions & 3 deletions

File tree

rsworkspace/crates/acp-nats/src/client/mod.rs

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ pub(crate) mod fs_read_text_file;
22
pub(crate) mod request_permission;
33
pub(crate) mod rpc_reply;
44
pub(crate) mod session_update;
5+
pub(crate) mod terminal_create;
56

67
use crate::agent::Bridge;
78
use crate::error::AGENT_UNAVAILABLE;
@@ -201,6 +202,17 @@ async fn dispatch_client_method<
201202
ClientMethod::SessionUpdate => {
202203
session_update::handle(&payload, ctx.client, &parsed.session_id).await;
203204
}
205+
ClientMethod::TerminalCreate => {
206+
terminal_create::handle(
207+
&payload,
208+
ctx.client,
209+
reply.as_deref(),
210+
ctx.nats,
211+
parsed.session_id.as_str(),
212+
ctx.serializer,
213+
)
214+
.await;
215+
}
204216
}
205217
}
206218

@@ -209,9 +221,9 @@ mod tests {
209221
use super::*;
210222
use crate::session_id::AcpSessionId;
211223
use agent_client_protocol::{
212-
ContentBlock, ContentChunk, ReadTextFileRequest, ReadTextFileResponse, Request, RequestId,
213-
RequestPermissionOutcome, RequestPermissionRequest, RequestPermissionResponse,
214-
SessionNotification, SessionUpdate,
224+
ContentBlock, ContentChunk, CreateTerminalRequest, CreateTerminalResponse,
225+
ReadTextFileRequest, ReadTextFileResponse, Request, RequestId, RequestPermissionOutcome,
226+
RequestPermissionRequest, RequestPermissionResponse, SessionNotification, SessionUpdate,
215227
};
216228
use async_trait::async_trait;
217229
use std::cell::RefCell;
@@ -257,6 +269,13 @@ mod tests {
257269
) -> agent_client_protocol::Result<ReadTextFileResponse> {
258270
Ok(ReadTextFileResponse::new("mock file content".to_string()))
259271
}
272+
273+
async fn create_terminal(
274+
&self,
275+
_: CreateTerminalRequest,
276+
) -> agent_client_protocol::Result<CreateTerminalResponse> {
277+
Ok(CreateTerminalResponse::new("term-001"))
278+
}
260279
}
261280

262281
fn make_msg(subject: &str, payload: &[u8], reply: Option<&str>) -> async_nats::Message {
@@ -415,6 +434,77 @@ mod tests {
415434
assert_eq!(nats.published_messages(), vec!["_INBOX.reply"]);
416435
}
417436

437+
#[tokio::test]
438+
async fn dispatch_client_method_dispatches_terminal_create() {
439+
let nats = MockNatsClient::new();
440+
let client = MockClient::new();
441+
let session_id = AcpSessionId::new("sess-1").unwrap();
442+
443+
let envelope = Request {
444+
id: RequestId::Number(1),
445+
method: std::sync::Arc::from("terminal/create"),
446+
params: Some(CreateTerminalRequest::new("sess-1", "echo hello")),
447+
};
448+
let payload = bytes::Bytes::from(serde_json::to_vec(&envelope).unwrap());
449+
450+
let parsed = crate::nats::ParsedClientSubject {
451+
session_id,
452+
method: ClientMethod::TerminalCreate,
453+
};
454+
455+
let ctx = DispatchContext {
456+
nats: &nats,
457+
client: &client,
458+
serializer: &StdJsonSerialize,
459+
};
460+
dispatch_client_method(
461+
"acp.sess-1.client.terminal.create",
462+
parsed,
463+
payload,
464+
Some("_INBOX.reply".to_string()),
465+
&ctx,
466+
)
467+
.await;
468+
469+
assert_eq!(nats.published_messages(), vec!["_INBOX.reply"]);
470+
}
471+
472+
#[tokio::test]
473+
async fn dispatch_client_method_dispatches_terminal_create_session_id_mismatch_publishes_error_reply()
474+
{
475+
let nats = MockNatsClient::new();
476+
let client = MockClient::new();
477+
let session_id = AcpSessionId::new("sess-a").unwrap();
478+
479+
let envelope = Request {
480+
id: RequestId::Number(1),
481+
method: std::sync::Arc::from("terminal/create"),
482+
params: Some(CreateTerminalRequest::new("sess-b", "echo hello")),
483+
};
484+
let payload = bytes::Bytes::from(serde_json::to_vec(&envelope).unwrap());
485+
486+
let parsed = crate::nats::ParsedClientSubject {
487+
session_id,
488+
method: ClientMethod::TerminalCreate,
489+
};
490+
491+
let ctx = DispatchContext {
492+
nats: &nats,
493+
client: &client,
494+
serializer: &StdJsonSerialize,
495+
};
496+
dispatch_client_method(
497+
"acp.sess-a.client.terminal.create",
498+
parsed,
499+
payload,
500+
Some("_INBOX.reply".to_string()),
501+
&ctx,
502+
)
503+
.await;
504+
505+
assert_eq!(nats.published_messages(), vec!["_INBOX.reply"]);
506+
}
507+
418508
#[tokio::test]
419509
async fn dispatch_client_method_dispatches_fs_read_text_file_with_advanced_mock() {
420510
let nats = AdvancedMockNatsClient::new();

0 commit comments

Comments
 (0)