import type { AgentMessage } from "../internal/harness.js"; import type { Model } from "../internal/llm.js"; /** * Fraction of the window at which we start clearing stale tool results (lighter than the guard trim). * Exported as the single source for the compaction-threshold clamp (design/64 §26.4 fix 2): compaction * must trigger AT OR BELOW this point, or every request inside the clearStale band breaks the prefix * cache at the clearing frontier (~0.7W re-prefilled per request — the "death band"). */ export declare const EDIT_FRACTION = 0.7; /** * checklist #54 (CC microCompact.ts:41-50 `COMPACTABLE_TOOLS` parity): the INCLUSION whitelist of * tools whose results may be content-cleared by the stale-result pass. CC's set is exactly * { Read, Bash, PowerShell (SHELL_TOOL_NAMES), Grep, Glob, WebSearch, WebFetch, Edit, Write } — * cheap-to-regenerate I/O. Everything else is PRESERVED: expensive/decision-bearing results * (Agent subagent reports, Task* registry state, TodoWrite acks, Monitor, MCP tools, custom * ToolSpecs) survive to the harder defenses (compaction summarizes them instead of blanking them). * PowerShell is kept for CC fidelity even though sema does not mount it. Overridable per call via * {@link ContextEditOptions.compactableTools} for custom-tool-heavy embedders. */ export declare const COMPACTABLE_TOOLS: ReadonlySet; export interface ContextEditOptions { /** Start clearing once estimated context tokens exceed this. */ budgetTokens: number; /** Always keep the content of this many most-recent tool results. Default 3. */ keepRecentToolResults?: number; /** * roadmap #6② (CC contentReplacementState parity): when set, a result's FULL TEXT is offloaded to * the store before its content is cleared, and the marker carries the ReadToolResult ref — a * cleared result becomes pageable instead of gone-from-view. `persist` must be idempotent per ref * (the store's write-once put) because clearing re-runs on every request build. Absent ⇒ the bare * marker (pre-#6 behavior; the durable session still holds the full result either way). */ offload?: { /** Write-once persist; the returned ref goes into the marker. Sync (in-memory) or async stores both fit. */ persist: (toolCallId: string, fullText: string) => string; }; /** * design/123 D3 (codex-B1 = fable-M5) — ANCHORED accounting start: `estimateContextTokens(messages, * charsPerToken).tokens` for the SAME message array. When set, the trigger gate AND the internal * bookkeeping start from this usage-anchored value instead of the pure structural sum (which * underestimates code by ~25% and CJK by 60–75% — the defense would self-certify and pass * over-window requests). Bookkeeping semantics (pinned): clearing a message AFTER the usage anchor * decrements by its structural delta; clearing a message AT/BEFORE the anchor decrements ZERO — * the anchor usage was billed with that content included and does not shrink on a request-view * edit (the clear only pays off on the NEXT request, after a fresh anchor lands), so the defense * keeps clearing deeper until the anchored total is met or nothing clearable remains. * Absent ⇒ legacy structural gate + accounting (byte-identical behavior). */ anchoredTotalTokens?: number; /** design/123 D2 — structural coefficient (`Model.charsPerToken`); default 4. */ charsPerToken?: number; /** * checklist #54 — which tools' results are clearable. Defaults to {@link COMPACTABLE_TOOLS} * (CC microCompact.ts:41-50). A result whose `toolName` is not in the set is NEVER cleared by * this pass, no matter how far over budget the request is — expensive subagent reports and * registry state are compaction's job, not a blanking marker's. */ compactableTools?: ReadonlySet; } /** * Context-editing (the lightest, safest compaction; Anthropic reports ~29% improvement alone): * when context exceeds the budget, replace the CONTENT of older tool-result messages with a short * marker, keeping the turn structure (tool_call/tool_result pairing) intact. The most recent * `keepRecentToolResults` results are preserved. * * Request-only and non-destructive: returns a new array; the durable session keeps the full results. * Older results are cleared first, stopping as soon as the budget is met. */ /** * audit A-1 (view-level heal for HISTORICAL pollution): drop synthetic EMPTY failure assistants — * stopReason aborted/error with no tool calls and no non-whitespace text/thinking. Sessions persisted * before 1.92.0 may carry one parked between an interrupted tool batch and its reconcile tool_results * (`A(tu×3), TR1, TR2, A(aborted,""), TR3`) — an API-invalid sequence on strict providers, and * append-only sessions cannot be rewritten. Dropping the junk from the REQUEST VIEW restores a legal * transcript (TR3 rejoins its batch). Deterministic ⇒ byte-stable per request ⇒ prefix-cache safe. * New sessions never contain these (the loop exits cleanly on abort; the harness skips persisting them). */ export declare function dropEmptyFailureAssistants(messages: AgentMessage[]): AgentMessage[]; export declare function clearStaleToolResults(messages: AgentMessage[], opts: ContextEditOptions): AgentMessage[]; /** The token budget at which context-editing begins for a model (below the harder guard trim). */ export declare function editBudget(model: Model): number; //# sourceMappingURL=context-edit.d.ts.map