use crate::handler::{decode, encode};
use proto::method::agent as method;
use std::future::Future;
pub trait Agent: Send + Sync + 'static {
fn initialize(
&self,
request: proto::InitializeRequest,
) -> impl Future<Output = proto::Result<proto::InitializeResponse>> + Send;
fn new_session(
&self,
request: proto::NewSessionRequest,
) -> impl Future<Output = proto::Result<proto::NewSessionResponse>> + Send;
fn prompt(
&self,
request: proto::PromptRequest,
) -> impl Future<Output = proto::Result<proto::PromptResponse>> + Send;
fn cancel(&self, notification: proto::CancelNotification) -> impl Future<Output = ()> + Send {
let _ = notification;
async {}
}
fn authenticate(
&self,
request: proto::AuthenticateRequest,
) -> impl Future<Output = proto::Result<proto::AuthenticateResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn logout(
&self,
request: proto::LogoutRequest,
) -> impl Future<Output = proto::Result<proto::LogoutResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn load_session(
&self,
request: proto::LoadSessionRequest,
) -> impl Future<Output = proto::Result<proto::LoadSessionResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn resume_session(
&self,
request: proto::ResumeSessionRequest,
) -> impl Future<Output = proto::Result<proto::ResumeSessionResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn fork_session(
&self,
request: proto::ForkSessionRequest,
) -> impl Future<Output = proto::Result<proto::ForkSessionResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn close_session(
&self,
request: proto::CloseSessionRequest,
) -> impl Future<Output = proto::Result<proto::CloseSessionResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn list_sessions(
&self,
request: proto::ListSessionsRequest,
) -> impl Future<Output = proto::Result<proto::ListSessionsResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn delete_session(
&self,
request: proto::DeleteSessionRequest,
) -> impl Future<Output = proto::Result<proto::DeleteSessionResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn set_session_mode(
&self,
request: proto::SetSessionModeRequest,
) -> impl Future<Output = proto::Result<proto::SetSessionModeResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn set_session_config_option(
&self,
request: proto::SetSessionConfigOptionRequest,
) -> impl Future<Output = proto::Result<proto::SetSessionConfigOptionResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn list_providers(
&self,
request: proto::ListProvidersRequest,
) -> impl Future<Output = proto::Result<proto::ListProvidersResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn set_provider(
&self,
request: proto::SetProviderRequest,
) -> impl Future<Output = proto::Result<proto::SetProviderResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn disable_provider(
&self,
request: proto::DisableProviderRequest,
) -> impl Future<Output = proto::Result<proto::DisableProviderResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn start_nes(
&self,
request: proto::StartNesRequest,
) -> impl Future<Output = proto::Result<proto::StartNesResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn suggest_nes(
&self,
request: proto::SuggestNesRequest,
) -> impl Future<Output = proto::Result<proto::SuggestNesResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn close_nes(
&self,
request: proto::CloseNesRequest,
) -> impl Future<Output = proto::Result<proto::CloseNesResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn accept_nes(
&self,
notification: proto::AcceptNesNotification,
) -> impl Future<Output = ()> + Send {
let _ = notification;
async {}
}
fn reject_nes(
&self,
notification: proto::RejectNesNotification,
) -> impl Future<Output = ()> + Send {
let _ = notification;
async {}
}
fn did_open_document(
&self,
notification: proto::DidOpenDocumentNotification,
) -> impl Future<Output = ()> + Send {
let _ = notification;
async {}
}
fn did_change_document(
&self,
notification: proto::DidChangeDocumentNotification,
) -> impl Future<Output = ()> + Send {
let _ = notification;
async {}
}
fn did_close_document(
&self,
notification: proto::DidCloseDocumentNotification,
) -> impl Future<Output = ()> + Send {
let _ = notification;
async {}
}
fn did_save_document(
&self,
notification: proto::DidSaveDocumentNotification,
) -> impl Future<Output = ()> + Send {
let _ = notification;
async {}
}
fn did_focus_document(
&self,
notification: proto::DidFocusDocumentNotification,
) -> impl Future<Output = ()> + Send {
let _ = notification;
async {}
}
fn message_mcp(
&self,
request: proto::MessageMcpRequest,
) -> impl Future<Output = proto::Result<proto::MessageMcpResponse>> + Send {
let _ = request;
async { Err(proto::Error::method_not_found()) }
}
fn notify_mcp(
&self,
notification: proto::MessageMcpNotification,
) -> impl Future<Output = ()> + Send {
let _ = notification;
async {}
}
fn ext_request(
&self,
method: String,
params: serde_json::Value,
) -> impl Future<Output = proto::Result<serde_json::Value>> + Send {
let _ = params;
async move { Err(proto::Error::method_not_found().data(method)) }
}
fn ext_notification(
&self,
method: String,
params: serde_json::Value,
) -> impl Future<Output = ()> + Send {
let _ = (method, params);
async {}
}
fn dispatch(
&self,
method: String,
params: serde_json::Value,
) -> impl Future<Output = proto::Result<serde_json::Value>> + Send {
async move {
match method.as_str() {
method::INITIALIZE => encode(self.initialize(decode(params)?).await?),
method::AUTHENTICATE => encode(self.authenticate(decode(params)?).await?),
method::LOGOUT => encode(self.logout(decode(params)?).await?),
method::SESSION_NEW => encode(self.new_session(decode(params)?).await?),
method::SESSION_LOAD => encode(self.load_session(decode(params)?).await?),
method::SESSION_RESUME => encode(self.resume_session(decode(params)?).await?),
method::SESSION_FORK => encode(self.fork_session(decode(params)?).await?),
method::SESSION_CLOSE => encode(self.close_session(decode(params)?).await?),
method::SESSION_LIST => encode(self.list_sessions(decode(params)?).await?),
method::SESSION_DELETE => encode(self.delete_session(decode(params)?).await?),
method::SESSION_SET_MODE => encode(self.set_session_mode(decode(params)?).await?),
method::SESSION_SET_CONFIG_OPTION => {
encode(self.set_session_config_option(decode(params)?).await?)
}
method::SESSION_PROMPT => encode(self.prompt(decode(params)?).await?),
method::PROVIDERS_LIST => encode(self.list_providers(decode(params)?).await?),
method::PROVIDERS_SET => encode(self.set_provider(decode(params)?).await?),
method::PROVIDERS_DISABLE => encode(self.disable_provider(decode(params)?).await?),
method::NES_START => encode(self.start_nes(decode(params)?).await?),
method::NES_SUGGEST => encode(self.suggest_nes(decode(params)?).await?),
method::NES_CLOSE => encode(self.close_nes(decode(params)?).await?),
method::MCP_MESSAGE => encode(self.message_mcp(decode(params)?).await?),
_ => self.ext_request(method, params).await,
}
}
}
fn dispatch_notification(
&self,
method: String,
params: serde_json::Value,
) -> impl Future<Output = ()> + Send {
async move {
match method.as_str() {
method::SESSION_CANCEL => {
if let Ok(notification) = decode(params) {
self.cancel(notification).await;
}
}
method::NES_ACCEPT => {
if let Ok(notification) = decode(params) {
self.accept_nes(notification).await;
}
}
method::NES_REJECT => {
if let Ok(notification) = decode(params) {
self.reject_nes(notification).await;
}
}
method::DOCUMENT_DID_OPEN => {
if let Ok(notification) = decode(params) {
self.did_open_document(notification).await;
}
}
method::DOCUMENT_DID_CHANGE => {
if let Ok(notification) = decode(params) {
self.did_change_document(notification).await;
}
}
method::DOCUMENT_DID_CLOSE => {
if let Ok(notification) = decode(params) {
self.did_close_document(notification).await;
}
}
method::DOCUMENT_DID_SAVE => {
if let Ok(notification) = decode(params) {
self.did_save_document(notification).await;
}
}
method::DOCUMENT_DID_FOCUS => {
if let Ok(notification) = decode(params) {
self.did_focus_document(notification).await;
}
}
method::MCP_MESSAGE => {
if let Ok(notification) = decode(params) {
self.notify_mcp(notification).await;
}
}
_ => self.ext_notification(method, params).await,
}
}
}
}