import { CursorLiveRunAbortError } from "./live-run-coordinator.js"; import { cursorLiveRuns, drainCursorLiveRunTurn, flushPendingCursorLiveRunTraceEventsToStream, settleCursorLiveToolBatch, } from "./provider-live-run-drain.js"; import { buildIncompleteCursorToolRunOutcome, type IncompleteCursorToolRunOutcomeInput, } from "./incomplete-tool-visibility.js"; import type { CursorProviderTurnPrepareResult, CursorProviderTurnRunnerParams, } from "./provider-turn-types.js"; import type { CursorSdkEventDebugSink } from "./sdk-event-debug.js"; export interface EmitCursorLiveTurnParams { params: CursorProviderTurnRunnerParams; prepared: CursorProviderTurnPrepareResult; sdkEventDebug: CursorSdkEventDebugSink | undefined; discardIncompleteTools: (outcome: IncompleteCursorToolRunOutcomeInput) => void; } export async function emitCursorLiveTurn(emitParams: EmitCursorLiveTurnParams): Promise { const { params, prepared, sdkEventDebug, discardIncompleteTools } = emitParams; if (prepared.runtime.kind !== "live") throw new Error("emitCursorLiveTurn requires a live run"); const { liveRun, turnCoordinator } = prepared.runtime; const { options, model } = params; try { await cursorLiveRuns.withRunLease(liveRun, options?.signal, async () => { await cursorLiveRuns.waitForProgress(liveRun, options?.signal); await settleCursorLiveToolBatch(liveRun); turnCoordinator.closeTraceBlock(); await drainCursorLiveRunTurn(params.stream, params.partial, model, params.context, liveRun, 0, { mode: "emit", signal: options?.signal, debugRecorder: sdkEventDebug, }); }); } catch (caught) { if (caught instanceof CursorLiveRunAbortError) { discardIncompleteTools({ status: "cancelled", signalAborted: true }); turnCoordinator.closeTraceBlock(); flushPendingCursorLiveRunTraceEventsToStream(params.stream, params.partial, liveRun, { includeTracesBehindQueuedTools: true, }); } throw caught; } } export function discardIncompleteToolsFromPrepared( prepared: CursorProviderTurnPrepareResult | undefined, outcome: IncompleteCursorToolRunOutcomeInput, ): void { prepared?.runtime.turnCoordinator.discardIncompleteStartedToolCalls(buildIncompleteCursorToolRunOutcome(outcome)); }