import type { ExtensionContext } from "@oh-my-pi/pi-coding-agent"; import { type CompressionCore, type CompressionState, type Config, type CoreMessage, type Prompts } from "acp-kernel"; import { type AdapterConfig } from "./config.js"; import type { BiliMessage } from "acp-kernel/wire"; /** Core-space fold result (provider mode): no originalById — the output * rebuilds straight onto the wire via the kernel codecs. */ export interface CoreFoldResult { state: CompressionState; coreMessages: BiliMessage[]; streamLen: number; } export interface AcpRuntime { core: CompressionCore; adapter: AdapterConfig; setAdapter(adapter: AdapterConfig): void; prompts: Prompts; setPrompts(prompts: Prompts): void; liveContextLimit(ctx: ExtensionContext): number; configFor(ctx: ExtensionContext): Config; /** Core-space fold (provider mode): the wire payload already parsed to * BiliMessage[] by the kernel codec; incremental LCP + replay semantics, * content-hash id space (wire-fold.ts). */ foldStreamCore(ctx: ExtensionContext, stream: BiliMessage[]): CoreFoldResult; stateFor(ctx: ExtensionContext): Promise<{ state: CompressionState; coreMessages: CoreMessage[]; }>; /** Commit the folded state to the core slot — the mirror of stateFor: a * commit must land where the next read goes (issue #90). */ commitFoldState(ctx: ExtensionContext, state: CompressionState, toolCallId?: string): void; /** Track the per-session streak of consecutively REJECTED compress calls. * `ok=false` increments and returns the new streak; `ok=true` resets to 0. * A re-fold (rewritten stream prefix) drops the slot and starts at 0. */ noteCompressOutcome(ctx: ExtensionContext, ok: boolean): number; /** Current consecutive-reject streak in the space the session's CURRENT * mode folds in (issue #104: the nudge must not demand compression while * compress calls are being rejected in a row). */ rejectStreakFor(ctx: ExtensionContext): number; /** Restore the fold slot from the previous process's checkpoint (issue * #130). Returns true when the session already has a live in-memory slot * (in-process switch back — never clobbered) or a valid checkpoint was * loaded. Callers skip the primeFold mirror: a mirror that guesses the * host's view→wire projection lands in a different fingerprint space, * which is exactly the bug the checkpoint exists to fix. */ restoreFold(ctx: ExtensionContext): boolean; /** Debounced checkpoint of the live fold slot. Called from the live fold * path only (wire fold, turn commit, compress commit) — preview/mirror * slots are never persisted. No-op when persistence is disabled. */ scheduleFoldSnapshot(ctx: ExtensionContext): void; /** Synchronously flush the session's checkpoint. For session_shutdown: * the host may exit as soon as the handler returns, so a debounced save * would be dropped with the process. Returns false when the write * failed (the in-memory slot is unaffected either way). */ flushFoldSync(sid: string): boolean; forgetSession(sid: string): void; /** Rebuild blocks from the persisted session at session_start so /acp and * acp_status show them BEFORE the first LLM call of a resumed session. * Provider mode folds the WIRE projection (wire-fold.ts mirrors — the * authoritative fold runs on the wire-synthesized stream, which differs * from the raw session view; issue #64). The slot is marked preview and * always re-folded authoritatively at the first live event (the live * stream is the truth source, not the persisted view). */ primeFold(ctx: ExtensionContext): void; acquireLock(sid: string): Promise<() => void>; } export declare function createRuntime(adapter: AdapterConfig): AcpRuntime;