import type { PrepareStepFunction, StepResult, ToolSet, TypedToolCall } from "ai"; import type { HarnessEmissionState } from "#harness/emission.js"; import { type AnthropicCacheMarker, type PromptCachePath } from "#harness/prompt-cache.js"; import type { HarnessEmitFn, HarnessSession, ToolLoopHarnessConfig } from "#harness/types.js"; /** * The subset of `StepResult` that the harness reads after a step completes. * * Used by both the streaming (`onStepFinish` callback) and non-streaming * (`generateText` result) code paths. */ export type HarnessStepResult = Pick, "content" | "finishReason" | "response" | "text" | "toolCalls" | "toolResults" | "usage">; /** * Input for {@link buildStepHooks}. */ interface StepHooksInput { readonly cachePath: PromptCachePath; readonly emit?: HarnessEmitFn; readonly emissionState: HarnessEmissionState; /** * When `false`, `prepareStep` skips the `step.started` emission. * Used by the harness recovery path to avoid emitting `step.started` * twice when retrying the same step with a degraded toolset. * * Defaults to `true`. */ readonly emitStepStarted?: boolean; /** * When set on the `gateway-auto` cache path, merges * `providerOptions.gateway.only = [gatewayPinProvider]` so the AI * Gateway only routes to the given provider. Used to keep * provider-specific tools (e.g. Anthropic's `web_search_20250305`) * on a provider that can serve them, converting a transient outage * into a clean retryable 503 rather than a fallback-to-incompatible * provider 400. * * Ignored when the author already set `gateway.only` or * `gateway.order` on the model reference's provider options. */ readonly gatewayPinProvider?: string; readonly marker: AnthropicCacheMarker | undefined; readonly session: HarnessSession; } /** * Composable hooks returned by {@link buildStepHooks}. */ interface StepHooks { /** * `ToolLoopAgent` `onStepFinish` callback. * * Emits `actions.requested`, `action.result`, and `step.completed` events * from the captured step result. */ readonly onStepFinish: (step: StepResult) => Promise; /** * `ToolLoopAgent` `prepareStep` callback. * * Handles `step.started` emission and cache/provider metadata. Compaction * happens in the tool-loop before `agent.stream()`. */ readonly prepareStep: PrepareStepFunction; /** * Promise that resolves when `onStepFinish` has completed. * * Await this after consuming the stream to ensure all step events * have been emitted before proceeding to post-step handling. * * Resolves once per hooks instance: a retried model call must rebuild * hooks via a fresh `runOneModelCall` attempt. Re-running a call against * hooks whose `stepResult` already resolved reads the previous attempt's * result, not the retry's. * * Never settles when the step does not finish — e.g. the AI SDK's * incomplete-stream rejection (`NoOutputGeneratedError`) skips * `onStepFinish` entirely. Consumers must surface stream errors as * throws before awaiting this promise (`emitStreamContent` does), or * the await hangs. */ readonly stepResult: Promise; } /** * Builds composable `prepareStep` and `onStepFinish` closures that * own all step-internal work: emission, compaction, and prompt caching. * * The harness passes these hooks to `ToolLoopAgent` and reads the * results via `stepResult` after the agent finishes. */ export declare function buildStepHooks(input: StepHooksInput): StepHooks; /** * Emits `actions.requested`, `action.result`, and `step.completed` events * from a captured step result. * * Tool calls and results that match `excludedActionToolNames`, belong to * tool-approval requests, or are marked `invalid` by the AI SDK (e.g. the * model emitted unparsable JSON) are filtered out of the emitted events. * The AI SDK feeds the invalid-call error back to the model on the next * step via `step.response.messages` so it can retry with well-formed * arguments — the runtime event stream only sees successfully parsed * tool calls. * * `handledInlineToolResultCallIds` lists approval-resume tool-result * call ids the stream already handled inline (see `emitStreamContent`). * This skips them to avoid double-emission. */ export declare function emitStepActions(emitFn: HarnessEmitFn, state: HarnessEmissionState, step: HarnessStepResult, options: { readonly excludedActionToolNames: ReadonlySet; readonly handledInlineToolResultCallIds?: ReadonlySet; readonly tools: ToolLoopHarnessConfig["tools"]; }): Promise; /** * Returns true when the AI SDK marked the tool call `invalid` (typically * because the model emitted unparsable JSON or targeted an unknown tool). * * Invalid calls have a raw-string or partial `input` payload that cannot * satisfy the runtime-action contract. The AI SDK synthesizes a tool-error * result for the next model step automatically; callers must skip invalid * calls when projecting to `RuntimeActionRequest` values or the harness * will throw on the JSON-object invariant. */ export declare function isInvalidToolCall(toolCall: TypedToolCall): boolean; export {};