Перейти к основному содержимому

Получение данных

В этом руководстве описывается, как использовать получение данных (elicitation) на стороне сервера для запроса дополнительного ввода от пользователя или выполнения внешних действий в процессе работы инструмента.

Что такое получение данных?

Получение данных позволяет серверному инструменту:

  • Запрашивать структурированный ввод от пользователя (формы с валидацией по схеме)
  • Просить клиент выполнить внешнее действие (например, открыть URL для оплаты)
  • Приостанавливать выполнение до тех пор, пока запрос не будет принят, отклонён или выполнен

Типичные сценарии применения:

  • Сбор контактных данных или параметров конфигурации
  • Шаги подтверждения от пользователя
  • Платежи или OAuth-перенаправления

Для использования получения данных внедрите Context в обработчик инструмента и вызовите метод elicit() с нужными параметрами запроса.

Определение формы для получения данных

Формы используют JSON-схему для определения и валидации структурированного ввода.

#[json_schema(de)]
struct Contact {
name: String,
email: String,
age: u32,
}

С помощью атрибутного макроса #[json_schema] можно управлять сериализацией/десериализацией через serde:

  • all — добавляет derive(serde::Serialize, serde::Deserialize).
  • serde — добавляет derive(serde::Serialize, serde::Deserialize).
  • ser — добавляет derive(serde::Serialize).
  • de — добавляет derive(serde::Deserialize).

Создание и отправка запроса формы

Для создания параметров запроса формы используйте метод ElicitRequestParams::form() с последующим вызовом with_contract(), который задаёт ожидаемую JSON-схему.

#[tool]
async fn generate_business_card(mut ctx: Context) -> Result<String, Error> {
let params = ElicitRequestParams::form(
"Please provide your contact information"
)
.with_schema::<Contact>();

ctx.elicit(params.into())
.await?
.map(format_contact)
}

fn format_contact(c: Contact) -> String {
format!("Name: {}, Age: {}, email: {}", c.name, c.age, c.email)
}

Порядок выполнения:

  1. Сервер отправляет запрос формы
  2. Клиент получает данные и проводит их валидацию
  3. Инструмент возобновляет выполнение с валидированными данными
  4. Результат преобразуется в выходные данные инструмента

Определение URL-запроса

URL-запросы используются, когда пользователь должен выполнить внешнее действие. Для создания ElicitRequestUrlParams используйте метод ElicitRequestParams::url().

#[tool]
async fn pay_a_bill(mut ctx: Context) -> Result<&'static str, Error> {
let params = ElicitRequestParams::url(
"https://www.paypal.com/us/webapps/mpp/paypal-payment",
"Please pay your bill using PayPal"
);

let elicitation_id = params.id.clone();

ctx.elicit(params.into()).await?;

// Отправляем `notifications/elicitation/complete`
ctx.complete_elicitation(elicitation_id).await?;

Ok("Payment successful")
}

После завершения внеполосного взаимодействия можно отправить уведомление notifications/elicitation/complete. Это позволяет клиентам программно реагировать при необходимости.

примечание
  • Сервер контролирует момент завершения запроса
  • Клиент только подтверждает принятие
  • Полезно для платежей, SSO, внешних подтверждений

Обучение на примерах

Полный рабочий пример доступен здесь.