import type { DispatchManagerConfig } from "../config.ts"; export interface UsageRecord { inputTokens: number; outputTokens: number; cost: number; } export interface BudgetCheckResult { exceeded: boolean; reason?: string; } /** * Tracks token and cost budgets across dispatched sessions within a single * plugin lifecycle. State is persisted to disk via debounced writes so it * survives plugin restarts. * * Tracks two levels: * - **Request-level**: cumulative usage across all dispatched sessions sharing * the same parent session ID (the "root" request). * - **Session-level**: per-session usage for individual dispatched sessions. * * Budget limits come from DispatchManagerConfig and are checked by the * caller (DispatchManager) before launching new tasks and during periodic * sampling. * * Thread-safe for single-process use (no locks needed — in-memory Maps). */ export declare class BudgetTracker { private log; /** Per-parent-session cumulative usage (request-level budgets). */ private requestUsage; /** Per-dispatch-session usage (session-level budgets). */ private sessionUsage; /** The active config used for budget limit checks. */ private config; /** Directory hash for state-file naming. */ private dirHash; /** Workspace directory for state file storage. */ private directory; private _dirty; private _debounceTimer; constructor(config: DispatchManagerConfig, directory: string); /** * Update the config reference (called when config changes at runtime). */ setConfig(config: DispatchManagerConfig): void; /** * Record token/cost usage for a dispatched session. * * @param sessionId The dispatched session ID * @param parentSessionId The parent (request) session ID * @param tokens Input and output token counts * @param cost Estimated or actual cost in USD */ recordUsage(sessionId: string, parentSessionId: string, tokens: { input: number; output: number; }, cost: number): void; /** * Get cumulative usage for a request (parent session). */ getRequestUsage(parentSessionId: string): UsageRecord; /** * Get cumulative usage for a specific dispatched session. */ getSessionUsage(sessionId: string): UsageRecord; /** * Check whether the request-level budget has been exceeded for the given * parent session. Returns { exceeded: true, reason } if any configured * limit is breached. */ isRequestBudgetExceeded(parentSessionId: string): BudgetCheckResult; /** * Check whether the per-session budget has been exceeded for the given * dispatched session. Returns { exceeded: true, reason } if any configured * limit is breached. */ isSessionBudgetExceeded(sessionId: string): BudgetCheckResult; /** * Remove tracking data for a completed/cleaned-up session. */ removeSession(sessionId: string): void; /** * Remove tracking data for a completed request (parent session). */ removeRequest(parentSessionId: string): void; /** * Reset usage for a specific dispatched session, subtracting its recorded * token/cost from the parent request's cumulative usage. Used by task-retry * with reset_budget=true so the retry does not count the old session's usage. * * This is a surgical reset — only the given session is affected; other * concurrent sessions under the same parent are untouched. */ resetSessionUsage(sessionId: string, parentSessionId: string): void; /** * Reset all tracking data. Called on plugin teardown or full reset. */ reset(): void; /** * Dispose the tracker — clears pending debounce timer and resets state. * Called during DispatchManager.dispose(). */ dispose(): void; /** * Path to the budget state file on disk. */ private statePath; /** * Serialize current usage Maps to disk using atomic write pattern * (.tmp + renameSync) to prevent file corruption from partial writes. */ persist(): void; /** * Restore usage Maps from disk. Called from the constructor. * If the file does not exist or is corrupt, starts fresh with empty Maps. */ restore(): void; /** * Debounced persist: sets dirty flag, restarts 200ms timer. * The timer callback flushes to disk when no new calls arrive within * the 200ms window. */ private _debouncedPersist; /** * Get a human-readable budget status summary for a parent session. */ getStatus(parentSessionId: string): string; /** Format a percentage string, or "—" when limit is undefined. */ private _pct; } //# sourceMappingURL=budget-tracker.d.ts.map