import type { CompactionConfig } from '../config/runtime.js'; import type { FileAction, PlanSlot, ToolResultSlot, WorkingState } from './types.js'; /** Pins kept at most; the oldest is dropped past this, and the drop is counted. */ export declare const MAX_PINS = 40; /** Characters one pin may carry; a pin is a fact, not a document. */ export declare const MAX_PIN_CHARS = 600; /** @internal Keep the omission visible within the existing character budget. */ export declare function truncateStateText(text: string, max: number): string; export declare class WorkingStateManager { private state; private readonly config; constructor(config: CompactionConfig); setTask(task: string): void; setPlan(plan: PlanSlot[]): void; /** Pin a fact under `key`, replacing what that key held; empty text unpins. */ pin(key: string, text: string, source: string): void; unpin(key: string): void; trackFile(path: string, action: FileAction): void; addDecision(decision: string): void; /** * Failures evict OLDEST-first, unlike every other slot here. * * `keepFirstEntries` exists because early decisions are load-bearing — * the one that set the turn's approach outlives twenty-five incidental * notes. That reasoning is right for decisions and backwards for * failures: the earliest failure is the one the model has most likely * already worked around, and the recent one is the thing it reads to * decide what to do differently. * * It also matters more than a preference. Sinha et al., * "The Illusion of Diminishing Returns" (arXiv:2509.09677), inject * errors into a model's own history at controlled rates and measure * accuracy far later in the turn: conditioning a model on its own * error-prone history raises the likelihood of further errors, and * scaling does not rescue it. So a permanently-protected early failure * is not neutral ballast — it is the input that paper measures. * * Nothing here decided failures should keep their oldest entries; the * behaviour was inherited from a shared helper written for a slot where * it is correct. */ addFailure(failure: string): void; addDiscovery(discovery: string): void; addEnvironment(env: string): void; addToolResult(result: ToolResultSlot): void; addUserRequirement(requirement: string): void; addAssistantNote(note: string): void; slotCount(): number; getState(): WorkingState; /** * Adopt a previously captured state. * * Used on resume: a turn that compacted, checkpointed and came back in a * new process needs the state its earlier summary was built from, or the * next compaction supersedes that summary with one covering only what * happened after the resume. See {@link restoreWorkingState}. */ replaceState(state: WorkingState): void; reset(): void; /** * Append, evicting from the MIDDLE once the list is full. * * This used to `shift()`, dropping the oldest entry — so on a long turn * the 26th assistant note silently deleted the 1st, and "the structured * state that survives compaction" degraded into a rolling window over * recent activity. The early entries are the load-bearing ones: the * original requirement, the decision that set the approach, the failure * that ruled an option out. The recent ones are still in the * un-compacted tail of the conversation. * * So the first `keepFirstEntries` are pinned and eviction happens just * after them — `keep_first` semantics, the same shape OpenHands' * condenser uses. The eviction is counted so the serializer can say * something was dropped rather than presenting a gap as complete. */ private pushWithEviction; } //# sourceMappingURL=manager.d.ts.map