import type { Span } from '@opentelemetry/api'; import type { WorkingStateManager } from '../../compaction/manager.js'; import type { SessionEvent, StepResult } from '../../types/session/index.js'; import type { TurnContext } from './context.js'; import type { EventTranslator } from './events.js'; import type { QueryParams } from './index.js'; import type { ResultAssembler } from './result.js'; /** * What a turn does on its way out, once the loop has stopped. * * The loop returns for any of a dozen reasons — an answer, a budget, a stop * condition, a cancelled signal — and this is the one place all of them pass * through: the `run_end`/`subagent_stop` hooks, the step record, the output * guardrails, consolidation into a memory store, and the terminal events. * * It is a generator because it emits, and it is reached with `yield*` so * every one of those emits suspends the caller at exactly the point it did * when the code lived inline. * * Two positions here are load-bearing, and they are stated where they happen. * `markCancelled` runs before the assembler, because `completeTurn` marks a * `running` turn `completed` — the reverse order would overwrite the * cancellation the abort signal had already declared. And * `memory_consolidated` precedes `turn_completed`, so a host folding the * stream in order has the memory before the turn that produced it. * * `setSteps` keeps its position too, but on the move's terms rather than on * its own. This file used to claim the assembler needed it first "or the * returned `Turn` loses the final turn's steps" — that is not true, and a * mutation proves it: `completeTurn` reads `result`, `stopReason` and the * budget and never `steps`, the returned `Turn` is built by `finalize()` * (which runs after the whole `try`/`catch`/`finally`), and moving * `setSteps` below the assembler leaves the suite green, including the test * that asserts `turn.steps` on a returned turn. What holds `setSteps` where it * is, is the byte-identity of this move: every position was preserved, not * just the consequential ones. Its read is still deferred to the same * moment — after the `run_end` hooks, immediately before the record is * written — which is why the caller passes `takeSteps` rather than an array. */ export interface TurnFinalization { readonly ctx: TurnContext; readonly params: QueryParams; readonly eventTranslator: EventTranslator; /** * The steps the loop recorded, read HERE rather than handed over as an * array: it is read where it always was, after the `run_end` hooks and * immediately before the record is written. */ readonly takeSteps: () => readonly StepResult[]; readonly workingStateManager: WorkingStateManager | undefined; readonly resultAssembler: ResultAssembler; readonly rootSpan: Span; } export declare function finalizeTurn(finalization: TurnFinalization): AsyncGenerator; //# sourceMappingURL=finalize-turn.d.ts.map