A model call whose outcome is unknown

PHP

How the SDK tells you that a provider was called and its answer was lost, what Slen does about the money, and how to repeat the run without paying twice.

3 min read

Sometimes a provider is called and its answer never comes back: the provider did not answer in time, or it took the call to run in the background and could no longer be asked about it. Nobody knows whether the call was made, so it may have been paid for. The SDK tells you so with a type of its own, and an execution says so with the status uncertain. This page says where you meet such an outcome and what to do about it.

Where you meet it

  • A run. operations.execute() raises OperationUncertainError in Node.js and OperationUncertainException in PHP, with the code operation_uncertain. The execution is closed with the status uncertain and the same code.

  • A read later. An execution read by executions.wait(), by a status read or by a repeat of the run under its key comes back as an answer with the status uncertain, not as an error. This is also how a model call that the provider ran in the background, and that could no longer be asked about, ends a run sent in async mode.

ProviderError and ProviderException with a code that says the call failed as a whole — provider_error, provider_unavailable, provider_rate_limit, provider_timeout, provider_not_configured, pool_exhausted — gave the money of the call back. The same type with any other code, or with none, does not say how far the call got: treat it as an unknown outcome too — Handling errors.

What Slen does

  • Slen does not make the call again, and the SDK does not send the run again by itself: it never repeats a 504.

  • The money held for the call is not given back at once, because the provider may have been paid. It stays held until the hold expires — How budget reservations work says when — and counts against the budgets until then.

  • Slen captures nothing for the call: it did not learn what the call used. cost.actual of the execution leaves the call out.

  • The webhook event operation.uncertain announces the call — Webhooks.

Repeat the run under its key

Keep the idempotency key of a run whose outcome is unknown. Under a new key the same run is a new one, and it may pay for the model call a second time.

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

$input = ['messages' => [['role' => 'user', 'content' => 'Write a short follow-up email.']]];
$key = 'order-42:email';

try {
    $execution = $slen->operations()->execute('generate_email', $input, new ExecuteOptions(idempotencyKey: $key));

    echo $execution->status->value, PHP_EOL;
} catch (OperationUncertainException $error) {
    // A provider was called and its answer was lost: the call may have been paid for.
    // Keep the key. Under a new one the same request may pay for the call a second time.
    echo 'outcome unknown: ', $error->errorCode, PHP_EOL;
}

The run sent again under the same key runs nothing: it is answered with the execution the first request opened, as that execution is now.

PHP
use Slen\Sdk\Modules\Operations\Enums\ExecutionStatus;

// The same request under the same key runs nothing: it reads the execution the first one opened.
$again = $slen->operations()->execute('generate_email', $input, new ExecuteOptions(idempotencyKey: $key));

if ($again->status === ExecutionStatus::Uncertain) {
    echo $again->status->value, ': ', $again->errorCode, PHP_EOL;
}

Whether to run the work again under a new key is your decision: the answer you need may then be paid for twice.

Find out what happened

  • The trace of the execution has an uncertain event at the AI Model node that made the call: executions.trace() reads it.

  • The model calls of the project keep their attempts at the providers: which connection, which model, how long it waited. List the operations of the project with the status uncertain to find every such call — Operations.

  • The provider's own account says whether it billed the call.

Where to go next