/** * src/engine/context.ts — C2 `--main` context projection for delegated children. * * Benchmark reference (reports/pi-subagents/benchmark/deep/pi-small-dense.md * §2.4, ryan session.ts:67,170): projecting the MAIN conversation to a child is * a condensed TEXT projection — the most recent compaction summary plus the * last N messages (texts + toolCalls, skipping toolResults; subagent results * truncated harder) — plus a FILE POINTER to the main session JSONL (path * only, read on demand; the content is NEVER copied into the projection). * * The projected text is wrapped in a strict authority hierarchy: * * [GENERAL INSTRUCTION — AUTHORITATIVE] anti-persona rules (see below) * [HISTORY — REFERENCE ONLY] condensed projection * [HISTORY SOURCE — REFERENCE ONLY] main-session JSONL path (optional) * [REQUEST — AUTHORITATIVE] the actual task * * Anti-persona-bleed: the child NEVER adopts the persona, role, or * instructions found inside the HISTORY blocks — those are transcripts of the * parent conversation, reference material only. * * The engine NEVER reads the pi session directly: all parent-side data is * supplied through the injectable `ContextProvider` (the extension fills it * from the live pi session). Zero @earendil-works/* imports; pure functions. */ /** Most recent messages projected to the child (benchmark: last 20). */ export declare const MAIN_CONTEXT_RECENT_MESSAGE_COUNT = 20; /** Per-message projection bound (chars) for ordinary messages. */ export declare const MAIN_CONTEXT_MESSAGE_MAX_CHARS = 2000; /** Harder bound (chars) for embedded subagent results (benchmark: 500). */ export declare const SUBAGENT_RESULT_MAX_CHARS = 500; /** Authority-hierarchy block headers (exact order enforced by wrap). */ export declare const GENERAL_INSTRUCTION_HEADER = "[GENERAL INSTRUCTION \u2014 AUTHORITATIVE]"; export declare const HISTORY_HEADER = "[HISTORY \u2014 REFERENCE ONLY]"; export declare const HISTORY_SOURCE_HEADER = "[HISTORY SOURCE \u2014 REFERENCE ONLY]"; export declare const REQUEST_HEADER = "[REQUEST \u2014 AUTHORITATIVE]"; /** Anti-persona rules placed in the GENERAL INSTRUCTION block. */ export declare const GENERAL_INSTRUCTION_RULES: string; /** * A parent-conversation message handed to the projection. `kind` lets the * provider mark tool traffic so the projection can skip toolResults * (benchmark: texts + toolCalls only); `subagentResult` marks embedded * subagent results, which are truncated harder. */ export interface MainContextMessage { role: string; text: string; kind?: "text" | "toolCall" | "toolResult"; subagentResult?: boolean; } /** Parent-side main-context data supplied by the injectable provider. */ export interface MainContextData { /** Most recent compaction summary, if any (projected first). */ compactionSummary?: string; /** Recent messages (provider may pre-filter; toolResults are skipped here too). */ recentMessages: MainContextMessage[]; /** Main-session JSONL path — POINTER ONLY, content is never copied. */ sessionFilePath?: string; } /** * Injectable main-context source. The engine never reads the pi session; the * extension supplies an implementation built from the live session. */ export interface ContextProvider { getMainContext(): MainContextData; } /** Context projection mode for a dispatch. `isolated` (default) = no projection. */ export type ContextMode = "isolated" | "main"; /** * Remove the immediate task echo from projected history: any message whose * whitespace-normalized text equals the (normalized) task is dropped, so the * child does not see the triggering request twice (benchmark: * `stripTaskEchoFromMainContext`). */ export declare function stripTaskEcho(task: string, messages: readonly T[]): T[]; /** * Condensed projection of the main context (compaction summary + last-20 * messages, echo-stripped, toolResults skipped, per-message truncation). This * is the text placed inside the [HISTORY — REFERENCE ONLY] block. Excludes the * file pointer, which lives in its own [HISTORY SOURCE] block. */ export declare function projectMainContext(data: MainContextData, task?: string): string; /** * Standalone condensed main-context text from a provider: projection + the * file-pointer footer (path only, never the file content). */ export declare function buildMainContextText(provider: ContextProvider, task?: string): string; /** * Wrap a task with the authority hierarchy: * GENERAL INSTRUCTION (anti-persona rules) -> HISTORY (projected context) -> * HISTORY SOURCE (session JSONL path, when known) -> REQUEST (the task). * * Empty `contextText` omits the HISTORY block; a missing `sessionFilePath` * omits the HISTORY SOURCE block. The task is always the LAST block so the * child treats it as the sole authoritative request. */ export declare function wrapTaskWithContext(task: string, contextText: string, sessionFilePath?: string): string;