/** * OpenCode builds a subagent's `task` result from the last text part of the child session's final * assistant message. A reasoning model that closes its turn with an extra reasoning step can emit a * trailing zero-length text part after the real answer, and that empty part becomes the whole * result. The coordinator then sees an empty handoff and re-dispatches work the worker already did. * * This repair is a read-only reconstruction of what the child actually said. It never invents text, * never touches a non-empty result, and leaves the output untouched whenever the child session * cannot be inspected. */ export declare const TASK_TOOL = "task"; export interface TaskToolExecuteInput { readonly tool: string; readonly sessionID?: string; readonly callID?: string; } export interface TaskToolExecuteOutput { output?: unknown; metadata?: unknown; [key: string]: unknown; } export interface SessionMessagePart { readonly type?: unknown; readonly text?: unknown; readonly synthetic?: unknown; } export interface SessionMessage { readonly info?: { readonly role?: unknown; readonly agent?: unknown; } | undefined; readonly role?: unknown; readonly agent?: unknown; readonly parts?: readonly SessionMessagePart[] | undefined; } /** The subset of the OpenCode SDK client this repair depends on. */ export interface SessionMessageReader { readonly session?: { readonly messages?: (request: { path: { id: string; }; }) => Promise<{ data?: unknown; } | unknown>; }; } export type TaskResultRepairHook = (input: TaskToolExecuteInput, output: TaskToolExecuteOutput) => Promise; export type TaskResultRepairOutcome = { readonly kind: "unchanged"; } | { readonly kind: "recovered"; readonly childSessionID: string; } | { readonly kind: "unrecoverable-empty"; readonly childSessionID: string; }; export declare const CONSULTATION_FALLBACK_RETRY_MARKER = "SORTIE_CONSULTATION_FALLBACK_RETRY"; /** Assistant text the child actually produced, ignoring the empty tail that caused the defect. */ export declare function lastAssistantText(messages: readonly SessionMessage[]): string | undefined; export declare function taskChildSessionID(output: TaskToolExecuteOutput): string | undefined; /** * Repair only the exact defect: a completed `task` call whose result body is empty while the child * session holds real assistant text. Everything else is left byte-identical. */ export declare function createTaskResultRepairHook(client: SessionMessageReader | undefined): TaskResultRepairHook; /** Replace only a still-empty task result with one bounded protocol marker for a proven role. */ export declare function markConsultationFallbackRetry(output: TaskToolExecuteOutput, role: "dog-reviewer" | "dog-advisor"): boolean;