import type { AuthorizationGate } from '../../../../authorization/index.js'; import type { ChatCompletionResponse } from '../../../../types/provider/index.js'; import type { SessionEvent } from '../../../../types/session/index.js'; import { type IterationContext } from './context.js'; interface VerificationAwareContext extends IterationContext { readonly verificationGate?: AuthorizationGate; } export type ToolReviewDecision = 'executed' | 'rejected' | 'stop'; /** * What the review produced. The tool outcomes travel with the decision so * the loop can build a `StepResult` without re-deriving them from the * messages it just pushed. */ export interface ToolReviewOutcome { decision: ToolReviewDecision; results: readonly import('../../executor.js').ToolCallOutcome[]; /** Wall-clock spent executing tools in this review. */ durationMs: number; } /** * Run every tool call in `response` through the gate and (when the gate is * inconclusive) a human, then hand the whole batch — approved and refused * alike — to the executor. * * Two invariants this function is responsible for: * * 1. **Every `tool_use` is answered.** No branch may return without the * executor having produced a `tool_result` for each call, because an * unanswered `tool_use` makes the next provider request malformed. The * refusal reason rides inside the `tool_result`, which is also what * lets a rejection steer the model instead of just stopping it. * 2. **A gate denial is never overridable by an approval.** A human * approving a batch approves the calls the gate left undecided — not * the ones it refused. Gate denials are threaded into every downstream * execution so no path can widen them. */ export declare function runToolReview(ctx: VerificationAwareContext, response: ChatCompletionResponse, iterationNum: number): AsyncGenerator; export {}; //# sourceMappingURL=tool-review.d.ts.map