import type { AgentMessage } from "../internal/harness.js"; import { type ToolResultStore } from "./tool-result-store.js"; /** * Per-message aggregate tool-result budget (design/64 §17.2 / §24 — CC `MAX_TOOL_RESULTS_PER_MESSAGE_CHARS`, * `constants/toolLimits.ts:49`). A single turn's batch of N parallel tool results can each be under the * per-tool offload threshold yet SUM past the model/API limit (10×40K = 400K). This caps the aggregate of * one turn's tool_result batch: while over budget, the LARGEST fresh non-exempt result is offloaded to a * preview (largest-first), repeating until the batch fits. * * **Simpler than CC by construction (§24.2):** a request-only, non-destructive transform (returns a new * array; the durable session keeps full results) applied in the existing `harness.on("context")` hook — * the same per-query point as `clearStaleToolResults` (the mirror of CC's query.ts:379). It is DETERMINISTIC * (stable `ref = tr__` + deterministic {@link buildPreview}), so re-running it every * query yields byte-identical previews → prompt-cache safe **without** CC's ContentReplacementState freeze * machine (the determinism IS the freeze), and resume-free (the transcript holds originals; this re-applies * on replay). Reuses design/30's offload store + preview format; with no store it falls back to a * self-contained head+tail truncation preview that still bounds the request. */ /** CC's per-message cap (chars, not tokens — the "100K token" figure in old notes was unsourced). */ export declare const AGGREGATE_TOOL_RESULT_BUDGET_CHARS = 200000; export interface AggregateBudgetOptions { /** Per-batch char budget. Default {@link AGGREGATE_TOOL_RESULT_BUDGET_CHARS}. */ budgetChars?: number; /** Tool names exempt from the budget (their own caps bound them) — e.g. read_file, read_tool_result. */ exemptTools?: ReadonlySet; /** design/30 store for offload+read-back. Absent ⇒ self-contained truncation preview. */ store?: ToolResultStore; /** Namespaces the stable ref so an offloaded result is globally addressable. */ sessionId: string; /** service [398] C8: fired once per result actually capped (offloaded OR degraded to a truncation * preview). `storeFallback` = the model LOST read-back for this result (store.put failed / no store) * — the silent-degradation face this callback exists for. Must not throw (caller-side contract). */ onCapped?: (info: { tool?: string; sizeChars: number; storeFallback: boolean; }) => void; } /** Default exemptions: tools whose result is self-bounded (read_file errors at its own token cap; the * offload reader pages small slices). grep/bash/glob/web_fetch/MCP are the risk sources, NOT exempt. */ export declare const DEFAULT_BUDGET_EXEMPT_TOOLS: ReadonlySet; /** Cap each over-budget turn-batch (run of consecutive tool_result messages). Request-only; see file docs. */ export declare function capAggregateToolResults(messages: AgentMessage[], opts: AggregateBudgetOptions): Promise; //# sourceMappingURL=tool-result-budget.d.ts.map