Запустите флоу и прочитайте ответ

PHP

Запустите флоу с его входом, клиентом, для которого он выполняется, и контекстом вызова и прочитайте каждое поле выполнения, которое вернётся.

6 мин чтения

Запуск называет код операции, передаёт флоу его вход и, когда это нужно, клиента, для которого он выполняется, и контекст вызова. Slen выполняет флоу, привязанный к коду, и отвечает выполнением. Эта страница показывает, что входит в вызов и что возвращается; самый короткий путь к первому ответу — статья Быстрый старт.

Отправить запрос

PHP
use Slen\Sdk\Modules\Operations\Options\ExecuteOptions;

$execution = $slen->operations()->execute(
    'generate_email',
    ['messages' => [['role' => 'user', 'content' => 'Write a short follow-up email to Ada.']]],
    new ExecuteOptions(customer: 'user_8421', context: ['plan' => 'pro'], idempotencyKey: 'order-57:email'),
);
  • Первый аргумент — код операции. Его привязывают к флоу в настройках флоу — как, говорит статья AI-флоу.

  • Второй аргумент — вход флоу, который его узлы читают под input. Это объект, и пустой объект допустим. Флоу с узлом AI-модель нужен непустой input.messages, когда он доходит до этого узла. Без них выполнение заканчивается с кодом invalid_flow_input.

  • Клиент называет вашего пользователя, для которого выполняется запуск, — ниже.

  • Ключ идемпотентности называет единицу работы. Чем отвечают на повтор под ним, говорит статья Ключи идемпотентности.

Клиент, тип кредитов, контекст и ключ — именованные аргументы ExecuteOptions, последнего аргумента вызова, рядом с timeout и retries — Повторы и таймауты.

Клиент и контекст

  • Клиент — ваш пользователь, для которого выполняется запуск: внешний идентификатор, с которым вы создали клиента. SDK отправляет его как context.user_id. Тогда вызовы моделей во флоу делаются для этого клиента: действуют бюджет, заданный для клиента, и политика с условием на клиента, а платит клиент своими кредитами, когда у проекта есть цена в кредитах для операции, — Клиенты и кредиты.

  • Тип кредитов называет счёт клиента, который платит. SDK отправляет его как context.credit_type; без него это счёт default.

  • Контекст несёт всё остальное, что флоу должен знать и не получает во входе: тариф вашего клиента, регион запроса. Это плоский объект до 64 значений. Значение — строка, число, булево значение или null, а весь контекст — не больше 16 384 байт в JSON.

  • Узлы флоу читают значение контекста по его пути, context.<name>. Узел Условие может ветвиться по context.plan.

  • Slen обрезает пробелы по краям строкового значения контекста, а строка, которая осталась пустой, становится null. Вход не меняется: он доходит до флоу таким, каким вы его отправили.

Контекст, чей user_id называет не того клиента, которого вы передаёте, пустой клиент и пустой тип кредитов отклоняются до отправки запроса, с кодом invalid_request. Запрос для заблокированного клиента отклоняется с customer_blocked, и ничего не выполняется.

Прочитать ответ

PHP
echo match (true) {
    $execution->isCompleted() => $execution->output['content'],
    $execution->isRejected() => "Refused: {$execution->errorCode} — {$execution->errorMessage}",
    $execution->isPending() => "Not over yet: {$execution->status->value}. Read it again in {$execution->retryAfterSeconds} s.",
    default => "Did not complete: {$execution->status->value}, {$execution->errorCode}",
}, PHP_EOL;

Вызов возвращает выполнение. Его status говорит, чем закончился запрос или что он ещё не закончился, — каждый статус перечисляет раздел Что говорит ответ.

ПолеЧто в нём
execution_idИдентификатор выполнения. Его принимают чтение статуса и трассировка
statusЧем закончился запрос или что он ещё не закончился
operationКод операции, который назвал запрос
outputТо, что вернул флоу, когда статус — completed. Иначе null
error_codeПочему закончилось выполнение, которое не завершилось
error_messageТа же причина фразой для человека. Показывайте или пишите её в лог; ветвитесь по error_code
errorerror_code и error_message одним объектом, когда у выполнения есть сообщение
costestimated — сколько, как ожидалось, будут стоить вызовы моделей, в сумме. actual — сколько они стоили
cachehit равно true, когда output взят из кеша, а cached_at говорит, когда этот ответ сохранён
replayedtrue, когда ответ принадлежит выполнению, которое начал более ранний запрос под тем же ключом
waiting_onЧего ждёт выполнение со статусом waiting
retry_after_secondsСколько подождать, прежде чем снова читать статус. Только пока выполнение не закончилось
trace_urlПуть трассировки выполнения в API

У ExecutionDTO эти поля — свойства в camel case: executionId, status — это ExecutionStatus, — operationCode, output, errorCode, errorMessage, error, cost, cache, replayed, waitingOn, retryAfterSeconds и traceUrl. isCompleted(), isRejected(), isPending() и isFinished() читают статус — Объекты ответа.

  • cost.actual приходит после ответа. Расчёт за вызовы моделей выполнения идёт в фоне, когда оно заканчивается, поэтому синхронный ответ несёт null, а более позднее чтение — чтение статуса, повтор ключа — несёт сумму.

  • За ответ из кеша заплатил вызов, который его получил. cost.actual остаётся null, если флоу не вызвал модель помимо этого.

  • После отказа cost.estimated — не трата. Выполнение со статусом rejected несёт оценку отклонённого вызова — трату, которую отказ предотвратил, — или null, когда отказ не назвал оценки.

Отказ и сбой

  • Флоу, который отказывает, отвечает как любой другой: узел Отклонить запрос заканчивает выполнение со статусом rejected, с кодом и сообщением, которые дал ему автор. Вызов возвращает выполнение и ничего не выбрасывает. isRejected() отличает такой ответ от завершённого.

  • Отказ платформы по пути — бюджет, политика, кредиты клиента, заблокированный клиент — выбрасывается как ошибка, когда флоу его не направляет. Выполнение закрывается с тем же кодом. Узел модели со связью на порту Отказ вместо этого направляет отказ во флоу, и флоу решает, что услышит вызывающий.

  • Ошибка, которая не является отказом, — во входе нет messages, провайдер упал, а флоу это не направляет, — тоже выбрасывается. Выполнение закрывается со статусом failed или uncertain, когда ответ провайдера потерян.

Если прочитать такое выполнение позже — чтением статуса, ожиданием, повтором ключа, — оно вернётся ответом, со своим статусом и error_code, а не ошибкой.

Как поймать отказ платформы в обеих его формах, показывает статья Когда трата отклонена, а любую другую ошибку SDK — статья Обработка ошибок.

Когда ответ не окончательный

  • На флоу, который остановился на ждущем узле, отвечают 202 и статусом waiting. Вызов возвращается без ошибки, а результат читают позже — Асинхронные запуски и ожидание.

  • Флоу, который выполняется дольше таймаута клиента, не выполняется дважды. SDK отправляет запрос ещё раз под тем же ключом, и ответ — выполнение как есть: running, пока оно идёт, и его исход, когда оно закончилось.

Что читать дальше