import type { HarnessStepResult } from "#harness/step-hooks.js"; /** How a recovery reissues the call. */ type RecoveryCall = (options: { readonly disabledProviderTools?: ReadonlySet; readonly extraSystemNote?: string; readonly retryReason?: "empty-response"; readonly suppressStepStartedEmission?: boolean; readonly trailingUserNote?: string; }) => Promise; /** * Recovers a failed model call, each recovery at most once and within the current step, so the * reissue suppresses a second `step.started`: * * 1. The host rejected a provider-specific tool it can't serve (an AI Gateway fallback provider, * or an OpenAI-compatible endpoint without OpenAI web search): the call is reissued without * it, and a system note tells the model which capability went away. Only known provider tools * are dropped, never an authored one. * 2. The response was empty (see {@link EmptyModelResponseError}), including the first * recovery's: the call is reissued with {@link EMPTY_RESPONSE_NUDGE}, repeating what the first * recovery removed. * * Each reissue goes through `call` so it gets fresh step hooks: the failed attempt's one-shot * `stepResult` already resolved. Returns the error that remains when nothing recovered. */ export declare function recoverModelCall(input: { readonly error: unknown; readonly call: RecoveryCall; readonly sessionId: string; readonly turnId: string; }): Promise<{ readonly result: HarnessStepResult; } | { readonly error: unknown; }>; /** * True when a step produced no assistant text and no tool calls. A blank * response is ambiguous and must be retried instead of silently dropping a * HITL reply. */ export declare function isEmptyModelResponse(step: HarnessStepResult): boolean; /** * Rethrows the AI SDK's `NoOutputGeneratedError` as * {@link EmptyModelResponseError}. Since `ai@7.0.0-canary.169` * (vercel/ai#15938) a stream that closes after metadata without output or * a finish chunk rejects — the SDK enqueues the error onto `fullStream` * (so `emitStreamContent` throws it) and never emits `finish-step`, so * `onStepEnd` does not fire and the step hooks' `stepResult` promise * would never settle. The same condition previously completed as an empty * step caught by {@link isEmptyModelResponse}; normalizing here funnels * both shapes into the one-shot empty-response reissue. */ export declare function rethrowNoOutputAsEmptyResponse(error: unknown): never; export {};