130 lines
4.1 KiB
Rust
130 lines
4.1 KiB
Rust
|
|
use std::sync::atomic::AtomicI64;
|
||
|
|
use std::sync::atomic::Ordering;
|
||
|
|
|
||
|
|
use codex_core::protocol::Event;
|
||
|
|
use mcp_types::JSONRPC_VERSION;
|
||
|
|
use mcp_types::JSONRPCError;
|
||
|
|
use mcp_types::JSONRPCErrorError;
|
||
|
|
use mcp_types::JSONRPCMessage;
|
||
|
|
use mcp_types::JSONRPCNotification;
|
||
|
|
use mcp_types::JSONRPCRequest;
|
||
|
|
use mcp_types::JSONRPCResponse;
|
||
|
|
use mcp_types::RequestId;
|
||
|
|
use mcp_types::Result;
|
||
|
|
use serde::Serialize;
|
||
|
|
use tokio::sync::mpsc;
|
||
|
|
|
||
|
|
pub(crate) struct OutgoingMessageSender {
|
||
|
|
next_request_id: AtomicI64,
|
||
|
|
sender: mpsc::Sender<OutgoingMessage>,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl OutgoingMessageSender {
|
||
|
|
pub(crate) fn new(sender: mpsc::Sender<OutgoingMessage>) -> Self {
|
||
|
|
Self {
|
||
|
|
next_request_id: AtomicI64::new(0),
|
||
|
|
sender,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[allow(dead_code)]
|
||
|
|
pub(crate) async fn send_request(&self, method: &str, params: Option<serde_json::Value>) {
|
||
|
|
let outgoing_message = OutgoingMessage::Request(OutgoingRequest {
|
||
|
|
id: RequestId::Integer(self.next_request_id.fetch_add(1, Ordering::Relaxed)),
|
||
|
|
method: method.to_string(),
|
||
|
|
params,
|
||
|
|
});
|
||
|
|
let _ = self.sender.send(outgoing_message).await;
|
||
|
|
}
|
||
|
|
|
||
|
|
pub(crate) async fn send_response(&self, id: RequestId, result: Result) {
|
||
|
|
let outgoing_message = OutgoingMessage::Response(OutgoingResponse { id, result });
|
||
|
|
let _ = self.sender.send(outgoing_message).await;
|
||
|
|
}
|
||
|
|
|
||
|
|
pub(crate) async fn send_event_as_notification(&self, event: &Event) {
|
||
|
|
#[expect(clippy::expect_used)]
|
||
|
|
let params = Some(serde_json::to_value(event).expect("Event must serialize"));
|
||
|
|
let outgoing_message = OutgoingMessage::Notification(OutgoingNotification {
|
||
|
|
method: "codex/event".to_string(),
|
||
|
|
params,
|
||
|
|
});
|
||
|
|
let _ = self.sender.send(outgoing_message).await;
|
||
|
|
}
|
||
|
|
|
||
|
|
pub(crate) async fn send_error(&self, id: RequestId, error: JSONRPCErrorError) {
|
||
|
|
let outgoing_message = OutgoingMessage::Error(OutgoingError { id, error });
|
||
|
|
let _ = self.sender.send(outgoing_message).await;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Outgoing message from the server to the client.
|
||
|
|
pub(crate) enum OutgoingMessage {
|
||
|
|
Request(OutgoingRequest),
|
||
|
|
Notification(OutgoingNotification),
|
||
|
|
Response(OutgoingResponse),
|
||
|
|
Error(OutgoingError),
|
||
|
|
}
|
||
|
|
|
||
|
|
impl From<OutgoingMessage> for JSONRPCMessage {
|
||
|
|
fn from(val: OutgoingMessage) -> Self {
|
||
|
|
use OutgoingMessage::*;
|
||
|
|
match val {
|
||
|
|
Request(OutgoingRequest { id, method, params }) => {
|
||
|
|
JSONRPCMessage::Request(JSONRPCRequest {
|
||
|
|
jsonrpc: JSONRPC_VERSION.into(),
|
||
|
|
id,
|
||
|
|
method,
|
||
|
|
params,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
Notification(OutgoingNotification { method, params }) => {
|
||
|
|
JSONRPCMessage::Notification(JSONRPCNotification {
|
||
|
|
jsonrpc: JSONRPC_VERSION.into(),
|
||
|
|
method,
|
||
|
|
params,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
Response(OutgoingResponse { id, result }) => {
|
||
|
|
JSONRPCMessage::Response(JSONRPCResponse {
|
||
|
|
jsonrpc: JSONRPC_VERSION.into(),
|
||
|
|
id,
|
||
|
|
result,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
Error(OutgoingError { id, error }) => JSONRPCMessage::Error(JSONRPCError {
|
||
|
|
jsonrpc: JSONRPC_VERSION.into(),
|
||
|
|
id,
|
||
|
|
error,
|
||
|
|
}),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||
|
|
pub(crate) struct OutgoingRequest {
|
||
|
|
pub id: RequestId,
|
||
|
|
pub method: String,
|
||
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||
|
|
pub params: Option<serde_json::Value>,
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||
|
|
pub(crate) struct OutgoingNotification {
|
||
|
|
pub method: String,
|
||
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||
|
|
pub params: Option<serde_json::Value>,
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||
|
|
pub(crate) struct OutgoingResponse {
|
||
|
|
pub id: RequestId,
|
||
|
|
pub result: Result,
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||
|
|
pub(crate) struct OutgoingError {
|
||
|
|
pub error: JSONRPCErrorError,
|
||
|
|
pub id: RequestId,
|
||
|
|
}
|