import { BoundedCompletionFailureError } from "../autonomy/bounded-completion.ts"; import type { AttemptUsageSnapshot, ExecutionGrant, ToolCapabilityManifest } from "./contracts.ts"; export type GatewayDecisionCode = "allowed" | "grant_expired" | "tool_not_granted" | "manifest_name_mismatch" | "capability_not_granted" | "path_argument_required" | "path_outside_scope" | "scope_denied" | "tool_call_budget_exhausted" | "token_budget_exhausted" | "cost_budget_exhausted" | "wall_clock_budget_exhausted"; export interface GatewayAuditRecord { grantId: string; attemptId: string; toolName: string; outcome: "allow" | "deny"; reasonCode: GatewayDecisionCode; at: string; } export interface CapabilityGatewayOptions { grant: ExecutionGrant; cwd: string; /** Durable active usage carried forward when an attempt resumes in a new process. */ initialUsage?: GatewayInitialUsage; now?: () => number; onAudit?: (record: GatewayAuditRecord) => void; /** Session-tree cumulative budget owner. Per-attempt grants remain independently enforced. */ sharedBudget?: SharedCapabilityBudget; } export interface GatewayUsageDelta { inputTokens?: number; outputTokens?: number; cacheReadTokens?: number; cacheWriteTokens?: number; /** Provider-authoritative total. Defaults to the supplied detail sum when omitted. */ totalTokens?: number; costUsd?: number; } export interface GatewayUsageSnapshot { toolCalls: number; inputTokens: number; outputTokens: number; cacheReadTokens: number; cacheWriteTokens: number; totalTokens: number; costUsd: number; wallClockMs: number; } export interface ProviderBudgetReservation { maxTokens: number; release(): void; } export interface SharedCapabilityBudget { assertBudgetAvailable(subject: string): void; recordAttemptUsage(usage: GatewayUsageSnapshot): void; remainingTokens(): number | undefined; reserveProviderBudget(requestedMaxTokens: number, subject: string, signal?: AbortSignal): Promise; } /** Persistable cumulative usage from a prior active segment; excludes restart downtime. */ export type GatewayInitialUsage = AttemptUsageSnapshot; /** * Weight applied to prompt-cache reads when charging token budgets. Cache reads re-bill the * same context on every request (a worker's fixed system prompt alone is thousands of tokens), * so charging them at face value turns `maxTokens` into a request counter: a 9k grant died in * 2-3 responses while doing ~500 tokens of real work per response (field session 019fd4dc). * The weight mirrors the typical cache-read price ratio; money stays bounded by `maxCostUsd`. */ export declare const CACHE_READ_BUDGET_WEIGHT = 0.1; /** * Tokens charged against `maxTokens` budgets: real work at face value, cache reads discounted. * A provider-authoritative total above the detail sum is unattributed usage and charges fully. */ export declare function budgetedTokens(usage: { inputTokens: number; outputTokens: number; cacheReadTokens: number; cacheWriteTokens: number; totalTokens: number; }): number; export declare class CapabilityGatewayDeniedError extends BoundedCompletionFailureError { readonly reasonCode: GatewayDecisionCode; constructor(reasonCode: GatewayDecisionCode, message: string); } /** * Per-invocation enforcement for an already-compiled grant. The compiler controls what may be * loaded; this gateway independently rechecks authority, path scope, expiry, and cumulative budget * immediately before execution. */ export declare class CapabilityGateway { private readonly grant; private readonly cwd; private readonly now; private readonly onAudit?; private readonly sharedBudget?; private readonly startedAt; private readonly initialWallClockMs; private toolCalls; private inputTokens; private outputTokens; private cacheReadTokens; private cacheWriteTokens; private totalTokens; private costUsd; constructor(options: CapabilityGatewayOptions); execute(manifest: ToolCapabilityManifest, toolName: string, params: unknown, invoke: () => Promise | T): Promise; /** Immediate pre-execution authorization for runtimes that expose a before-tool-call hook. */ authorizeToolCall(manifest: ToolCapabilityManifest, toolName: string, params: unknown): void; recordUsage(delta: GatewayUsageDelta): void; /** Enforce resumed cumulative budgets before a provider request that has no tool-call boundary. */ assertBudgetAvailable(subject?: string): void; reserveProviderBudget(requestedMaxTokens: number, subject?: string, signal?: AbortSignal): Promise; remainingAttemptTokenBudget(): number | undefined; remainingTokenBudget(): number | undefined; getUsage(): GatewayUsageSnapshot; private authorize; private enforceBudget; private currentTime; private wallClockMsAt; private pathAllowed; private deny; private audit; } //# sourceMappingURL=capability-gateway.d.ts.map