chore: use typed notifications from rmcp (#3653)
This commit is contained in:
@@ -45,8 +45,7 @@ use crate::tool_monitor::{ToolCall, ToolMonitor};
|
||||
use crate::utils::is_token_cancelled;
|
||||
use mcp_core::{ToolError, ToolResult};
|
||||
use regex::Regex;
|
||||
use rmcp::model::Tool;
|
||||
use rmcp::model::{Content, GetPromptResult, JsonRpcMessage, Prompt};
|
||||
use rmcp::model::{Content, GetPromptResult, Prompt, ServerNotification, Tool};
|
||||
use serde_json::Value;
|
||||
use tokio::sync::{mpsc, Mutex, RwLock};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
@@ -83,7 +82,7 @@ pub struct Agent {
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum AgentEvent {
|
||||
Message(Message),
|
||||
McpNotification((String, JsonRpcMessage)),
|
||||
McpNotification((String, ServerNotification)),
|
||||
ModelChange { model: String, mode: String },
|
||||
}
|
||||
|
||||
@@ -94,19 +93,19 @@ impl Default for Agent {
|
||||
}
|
||||
|
||||
pub enum ToolStreamItem<T> {
|
||||
Message(JsonRpcMessage),
|
||||
Message(ServerNotification),
|
||||
Result(T),
|
||||
}
|
||||
|
||||
pub type ToolStream = Pin<Box<dyn Stream<Item = ToolStreamItem<ToolResult<Vec<Content>>>> + Send>>;
|
||||
|
||||
// tool_stream combines a stream of JsonRpcMessages with a future representing the
|
||||
// tool_stream combines a stream of ServerNotifications with a future representing the
|
||||
// final result of the tool call. MCP notifications are not request-scoped, but
|
||||
// this lets us capture all notifications emitted during the tool call for
|
||||
// simpler consumption
|
||||
pub fn tool_stream<S, F>(rx: S, done: F) -> ToolStream
|
||||
where
|
||||
S: Stream<Item = JsonRpcMessage> + Send + Unpin + 'static,
|
||||
S: Stream<Item = ServerNotification> + Send + Unpin + 'static,
|
||||
F: Future<Output = ToolResult<Vec<Content>>> + Send + 'static,
|
||||
{
|
||||
Box::pin(async_stream::stream! {
|
||||
|
||||
@@ -835,7 +835,7 @@ mod tests {
|
||||
CallToolResult, InitializeResult, ListPromptsResult, ListResourcesResult, ListToolsResult,
|
||||
ReadResourceResult,
|
||||
};
|
||||
use rmcp::model::{GetPromptResult, JsonRpcMessage};
|
||||
use rmcp::model::{GetPromptResult, ServerNotification};
|
||||
use serde_json::json;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
@@ -891,7 +891,7 @@ mod tests {
|
||||
Err(Error::NotInitialized)
|
||||
}
|
||||
|
||||
async fn subscribe(&self) -> mpsc::Receiver<JsonRpcMessage> {
|
||||
async fn subscribe(&self) -> mpsc::Receiver<ServerNotification> {
|
||||
mpsc::channel(1).1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::agents::subagent_execution_tool::task_execution_tracker::{
|
||||
use crate::agents::subagent_execution_tool::tasks::process_task;
|
||||
use crate::agents::subagent_execution_tool::workers::spawn_worker;
|
||||
use crate::agents::subagent_task_config::TaskConfig;
|
||||
use rmcp::model::JsonRpcMessage;
|
||||
use rmcp::model::ServerNotification;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc;
|
||||
@@ -20,7 +20,7 @@ const DEFAULT_MAX_WORKERS: usize = 10;
|
||||
|
||||
pub async fn execute_single_task(
|
||||
task: &Task,
|
||||
notifier: mpsc::Sender<JsonRpcMessage>,
|
||||
notifier: mpsc::Sender<ServerNotification>,
|
||||
task_config: TaskConfig,
|
||||
cancellation_token: Option<CancellationToken>,
|
||||
) -> ExecutionResponse {
|
||||
@@ -56,7 +56,7 @@ pub async fn execute_single_task(
|
||||
|
||||
pub async fn execute_tasks_in_parallel(
|
||||
tasks: Vec<Task>,
|
||||
notifier: Sender<JsonRpcMessage>,
|
||||
notifier: Sender<ServerNotification>,
|
||||
task_config: TaskConfig,
|
||||
cancellation_token: Option<CancellationToken>,
|
||||
) -> ExecutionResponse {
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::agents::subagent_execution_tool::{
|
||||
tasks_manager::TasksManager,
|
||||
};
|
||||
use crate::agents::subagent_task_config::TaskConfig;
|
||||
use rmcp::model::JsonRpcMessage;
|
||||
use rmcp::model::ServerNotification;
|
||||
use serde_json::{json, Value};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
@@ -14,7 +14,7 @@ use tokio_util::sync::CancellationToken;
|
||||
pub async fn execute_tasks(
|
||||
input: Value,
|
||||
execution_mode: ExecutionMode,
|
||||
notifier: Sender<JsonRpcMessage>,
|
||||
notifier: Sender<ServerNotification>,
|
||||
task_config: TaskConfig,
|
||||
tasks_manager: &TasksManager,
|
||||
cancellation_token: Option<CancellationToken>,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use mcp_core::ToolError;
|
||||
use rmcp::model::{Content, Tool, ToolAnnotations};
|
||||
use rmcp::model::{Content, ServerNotification, Tool, ToolAnnotations};
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::agents::subagent_task_config::TaskConfig;
|
||||
@@ -8,7 +8,6 @@ use crate::agents::{
|
||||
subagent_execution_tool::task_types::ExecutionMode,
|
||||
subagent_execution_tool::tasks_manager::TasksManager, tool_execution::ToolCallResult,
|
||||
};
|
||||
use rmcp::model::JsonRpcMessage;
|
||||
use rmcp::object;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio_stream;
|
||||
@@ -67,7 +66,7 @@ pub async fn run_tasks(
|
||||
tasks_manager: &TasksManager,
|
||||
cancellation_token: Option<CancellationToken>,
|
||||
) -> ToolCallResult {
|
||||
let (notification_tx, notification_rx) = mpsc::channel::<JsonRpcMessage>(100);
|
||||
let (notification_tx, notification_rx) = mpsc::channel::<ServerNotification>(100);
|
||||
|
||||
let tasks_manager_clone = tasks_manager.clone();
|
||||
let result_future = async move {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use rmcp::model::{JsonRpcMessage, JsonRpcNotification, JsonRpcVersion2_0, Notification};
|
||||
use rmcp::object;
|
||||
use rmcp::model::{
|
||||
LoggingLevel, LoggingMessageNotification, LoggingMessageNotificationMethod,
|
||||
LoggingMessageNotificationParam, ServerNotification,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{mpsc, RwLock};
|
||||
@@ -52,7 +54,7 @@ fn format_task_metadata(task_info: &TaskInfo) -> String {
|
||||
pub struct TaskExecutionTracker {
|
||||
tasks: Arc<RwLock<HashMap<String, TaskInfo>>>,
|
||||
last_refresh: Arc<RwLock<Instant>>,
|
||||
notifier: mpsc::Sender<JsonRpcMessage>,
|
||||
notifier: mpsc::Sender<ServerNotification>,
|
||||
display_mode: DisplayMode,
|
||||
cancellation_token: Option<CancellationToken>,
|
||||
}
|
||||
@@ -61,7 +63,7 @@ impl TaskExecutionTracker {
|
||||
pub fn new(
|
||||
tasks: Vec<Task>,
|
||||
display_mode: DisplayMode,
|
||||
notifier: Sender<JsonRpcMessage>,
|
||||
notifier: Sender<ServerNotification>,
|
||||
cancellation_token: Option<CancellationToken>,
|
||||
) -> Self {
|
||||
let task_map = tasks
|
||||
@@ -97,7 +99,7 @@ impl TaskExecutionTracker {
|
||||
|
||||
fn log_notification_error(
|
||||
&self,
|
||||
error: &mpsc::error::TrySendError<JsonRpcMessage>,
|
||||
error: &mpsc::error::TrySendError<ServerNotification>,
|
||||
context: &str,
|
||||
) {
|
||||
if !self.is_cancelled() {
|
||||
@@ -108,16 +110,17 @@ impl TaskExecutionTracker {
|
||||
fn try_send_notification(&self, event: TaskExecutionNotificationEvent, context: &str) {
|
||||
if let Err(e) = self
|
||||
.notifier
|
||||
.try_send(JsonRpcMessage::Notification(JsonRpcNotification {
|
||||
jsonrpc: JsonRpcVersion2_0,
|
||||
notification: Notification {
|
||||
method: "notifications/message".to_string(),
|
||||
params: object!({
|
||||
"data": event.to_notification_data()
|
||||
}),
|
||||
.try_send(ServerNotification::LoggingMessageNotification(
|
||||
LoggingMessageNotification {
|
||||
method: LoggingMessageNotificationMethod,
|
||||
params: LoggingMessageNotificationParam {
|
||||
data: event.to_notification_data(),
|
||||
level: LoggingLevel::Info,
|
||||
logger: None,
|
||||
},
|
||||
extensions: Default::default(),
|
||||
},
|
||||
}))
|
||||
))
|
||||
{
|
||||
self.log_notification_error(&e, context);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::sync::Arc;
|
||||
use async_stream::try_stream;
|
||||
use futures::stream::{self, BoxStream};
|
||||
use futures::{Stream, StreamExt};
|
||||
use rmcp::model::JsonRpcMessage;
|
||||
use rmcp::model::ServerNotification;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
@@ -19,7 +19,7 @@ use rmcp::model::Content;
|
||||
// can be used to receive notifications from the tool.
|
||||
pub struct ToolCallResult {
|
||||
pub result: Box<dyn Future<Output = ToolResult<Vec<Content>>> + Send + Unpin>,
|
||||
pub notification_stream: Option<Box<dyn Stream<Item = JsonRpcMessage> + Send + Unpin>>,
|
||||
pub notification_stream: Option<Box<dyn Stream<Item = ServerNotification> + Send + Unpin>>,
|
||||
}
|
||||
|
||||
impl From<ToolResult<Vec<Content>>> for ToolCallResult {
|
||||
|
||||
Reference in New Issue
Block a user