/** * Unified turn-end decision pipeline (integration subtask of the copilot * strategy). * * Orchestrates the three policy sources evaluated at `session.idle`, in * STRICT precedence order, with at most ONE injection per idle: * * a. BUILTIN function-continuation source (src/copilot/sources/builtin.ts) * — always evaluated first, semantics untouched. If it injects, STOP. * b. USER heuristic rules (src/copilot/rules.ts) over the last assistant * text — a match with action `skip` consumes the turn (no injection, no * LLM fallthrough); a match with continue/blocked/done injects its reply * text and STOPS. * c. LLM role (transcript → prompt → verdict) — advance verdict injects * replyText; hand_to_user (advance:false) or null (any failure) injects * nothing. * * When the session's role has no copilot config, or `copilot.enabled` is * false, ONLY the builtin source runs — byte-identical legacy behavior. * * INVARIANT: at most ONE injection per session.idle. Each source returns as * soon as it injects; the next source only runs when the previous declined. * Copilot-sourced injections (b/c) are wrapped via `buildReminder` and MUST * carry COPILOT_MARKER (src/copilot/constants.ts) so they are classified as * synthetic on re-entry through `chat.message` (src/hooks/chat-message.ts). * The builtin source keeps its own existing `[auto-continue` marker. */ import type { ISessionClient } from "../platform/ports/session-client.ts"; import type { ResolvedFunction } from "../types.ts"; import type { ArtifactStore } from "../function/artifact-store.ts"; import type { CopilotConfig } from "./types.ts"; /** Pipeline-level dependencies (a subset of HookDeps). */ export interface TurnEndPipelineDeps { /** Platform session client — source of last-text/transcript reads and the * injection channel for copilot-sourced replies. */ session: ISessionClient; /** Workspace directory (feeds the builtin CondEnv + verdict child session). */ dir: string; /** * Copilot config per role id, parsed at construction. Absent (or a role * missing from the map) → the pipeline runs ONLY the builtin source. */ copilotConfigs?: Map; /** * Resolved subagent registry for the LLM-role verdict source * (src/copilot/llm.ts). Absent → the LLM source cannot resolve its role * and is skipped (treated as a null verdict). */ resolvedSubagents?: Map; } /** Per-idle context precomputed by the session.idle handler. */ export interface TurnEndPipelineContext { /** Active function names in insertion order (builtin iteration order). */ activeSet: Set; /** All resolved functions for the session's roles. */ allFns: ResolvedFunction[]; /** Whether any active fn declares Tier-2 handlers. */ hasHandlers: boolean; /** Last assistant text (may be null when no capture/handler needed it). */ lastText: string | null; /** Function artifact store (builtin source). */ artifacts: ArtifactStore; /** Hook-owned session→agent registry (sessionAgentRegistry). */ sessionAgentRegistry: Map; } /** * Run the unified turn-end decision pipeline for one `session.idle`. * * @returns true when an injection was successfully sent; false otherwise * (no source decided to inject, or the only source that decided * failed to deliver). The return value is informational — the * at-most-one-injection invariant is structural. */ export declare function runTurnEndPipeline(deps: TurnEndPipelineDeps, sid: string, ctx: TurnEndPipelineContext): Promise; //# sourceMappingURL=pipeline.d.ts.map