import { type LanguageModel, type ModelMessage } from "ai"; import type { StepCatalog } from "#execution/catalog/step-catalog.js"; import type { GenerationSteering } from "#harness/generation-steering.js"; import type { HarnessModelMessage, UserModelMessage } from "#harness/messages.js"; import { type ModelProfile } from "#harness/model-profile.js"; import type { Step } from "#harness/step/context.js"; import { type Prompt } from "#harness/step/prompt.js"; import { type HarnessStepResult } from "#harness/step-hooks.js"; import { type StepResult } from "#harness/types.js"; import type { InstrumentationAttempt } from "#instrumentation/runtime.js"; import { type RequestMessages } from "./request.js"; /** How one attempt differs from the step's first: what recovery and retries change. */ export interface ModelCallOptions { readonly disabledProviderTools?: ReadonlySet; readonly extraSystemNote?: string; readonly retryReason?: "empty-response"; readonly suppressStepStartedEmission?: boolean; readonly trailingUserNote?: string; } /** What a model step's caller needs from the step. */ interface ModelCallerInput { /** The step's catalog: what the model can call, and what each call runs. */ readonly catalog: StepCatalog; readonly model: LanguageModel; readonly generation: GenerationSteering; readonly hidesHeldText: boolean; readonly turnMessages: readonly UserModelMessage[]; readonly approvedTools: ReadonlySet; readonly pendingApprovalsNote: string | undefined; /** The prompt as the step started it, projected for the model. */ readonly projectedMessages: HarnessModelMessage[]; readonly startStep: (messages: readonly ModelMessage[]) => Promise; readonly setAttemptScope: (scope: InstrumentationAttempt | undefined) => void; } /** * Calls the model for one step. Each attempt rebuilds the tools, the request, and the agent, so an * earlier stream can't resolve a retry's one-shot step hooks with stale partial output. An attempt * may first compact the prompt, which rewrites the durable messages the step later commits. */ export declare class ModelCaller { readonly profile: ModelProfile; private readonly attributionHeaders; /** The prompt as the model reads it, projected for its history view. */ private projectedMessages; /** The latest attempt's request; its history is what the step commits. */ request: RequestMessages; /** The messages the latest attempt sent, after attachments were hydrated. */ modelMessages: ModelMessage[]; requestEnvelopeTokens: number; /** Usage of a call steering interrupted, which the steered step still counts. */ private interruptedUsage; private compactionFailure; private attemptIndex; private readonly step; private readonly prompt; private readonly input; constructor(step: Step, prompt: Prompt, input: ModelCallerInput); /** Calls the model, retrying transient failures. */ call(options: ModelCallOptions): Promise; /** * Answers the calls a discarded attempt announced, so none stays open once the replacement * attempt starts. The replacement re-requests whatever the model still wants to run. */ private settleRetriedActions; /** A failed compaction fails the step, whatever recovery the call attempted. */ throwIfCompactionFailed(): void; /** Steering interrupted the call: the step ends with what it committed, and runs again. */ steered(): Promise; /** The step's result counted its usage, so an interrupted call's usage no longer applies. */ clearInterruptedUsage(): void; private buildRequest; private instructions; private prepare; /** Compacts the prompt when it's over the threshold, then rebuilds what depends on it. */ private compact; private attempt; /** Streams the call, publishing its content as it arrives. */ private stream; } export {};