Прогресс
Для долгосрочных инструментов Neva может отправлять уведомления о прогрессе (notifications/progress), информируя клиентов о ходе выполнения задачи.
Включение уведомлений о прогрессе
Уведомления о прогрессе отправляются через tracing. Настройте слой уведомлений с помощью notification::fmt::layer():
use neva::prelude::*;
use tracing_subscriber::prelude::*;
#[tokio::main]
async fn main() {
tracing_subscriber::registry()
.with(notification::fmt::layer())
.init();
App::new()
.with_options(|opt| opt
.with_tasks(|tasks| tasks.with_all())
.with_default_http())
.run()
.await;
}
with_tasks() включает функциональность Задач, необходимую для того, чтобы клиенты могли передавать progressToken вместе с вызовом инструмента. Подробнее см. в руководстве Задачи.
Отчёт о прогрессе из инструмента
Внедрите Meta<ProgressToken> в обработчик инструмента для доступа к токену прогресса, предоставленному клиентом. Затем отправляйте события прогресса с помощью макроса tracing::info! с целью target: "progress":
use neva::prelude::*;
#[tool]
async fn long_running_task(token: Meta<ProgressToken>, command: String) {
tracing::info!("Starting {command}");
let mut progress = 0;
loop {
if progress == 100 {
break;
}
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
progress += 5;
tracing::info!(
target: "progress",
token = %token, // Токен прогресса от клиента
value = progress, // Текущее значение прогресса
total = 100 // Итого (необязательно)
);
}
tracing::info!("{command} has been successfully completed!");
}
Обязательные поля tracing
| Поле | Описание |
|---|---|
target: "progress" | Направляет событие в обработчик уведомлений прогресса MCP |
token = %token | ProgressToken из запроса клиента |
value = <число> | Текущее значение прогресса |
total = <число> | (Необязательно) Общее количество шагов; помогает клиентам отображать процент |
Если клиент не включил progressToken в запрос, Meta<ProgressToken> всё равно будет присутствовать, но пустым — события прогресса, отправленные с ним, будут просто отброшены.
Обучение на примерах
Полный пример доступен здесь.