/** * AgentGuard(TM) Spend: Core SDK entry point * * `withSpendGuard()` wraps provider SDK clients and enforces a SpendPolicy * locally before each call is sent to the provider. * * Design rule: ZERO DATA PLANE INVOLVEMENT. * - Prompts never leave the customer process. * - Provider API keys never leave the customer process. * - The signing key never leaves the customer process. * - All decisions and the entire signed log live in the customer's storage. * * Patent notice: Protected by U.S. patent-pending technology * (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626; * 64/071,781; 64/071,789). */ import type { SpendPolicy, CallContext, SpendDecision, SpendStore, DecisionLogStore, SignedDecisionLogEntry, Provider, CapabilityTier, AttestationChainInput, SpendScope } from './types'; import { type LicenseClientOptions } from './license'; import { type ManagedOpenRouterKeyOptions } from './openrouter/key-fetch'; import { type ComplianceEnforcementConfig, type GovernancePosture } from './posture/enforce'; import type { JurisdictionCountry } from './receipts/schema'; import { type CircuitBreakerConfig, type ToolGateConfig, type ToolGateInput, type ToolGateResult, type WorkflowEnvelopeConfig } from './governance'; type ReviewerCascadeMetric = number | ((response: unknown) => number | null | undefined | Promise); export interface SpendGuardConfig { /** The policy to evaluate every call against. */ policy: SpendPolicy; /** Spend state store. Defaults to in-memory. */ spendStore?: SpendStore; /** Decision log store. Defaults to in-memory. */ logStore?: DecisionLogStore; /** Ed25519 signing keys. If omitted, decisions are not signed. */ signingKeys?: { /** 32-byte Ed25519 secret seed. */ privateKey: Uint8Array; /** 32-byte Ed25519 public key. */ publicKey: Uint8Array; }; /** Optional hook fired on every decision and settlement. */ onDecision?: (decision: SpendDecision, signed: SignedDecisionLogEntry | null) => void | Promise; /** Optional token-count estimator. Defaults to `chars / 4` heuristic. */ tokenEstimator?: (text: string) => number; /** Optional locale for localized block traces. */ locale?: string; /** Optional AgentGuard license key. If omitted, local config or free tier is used. */ licenseKey?: string; /** Optional partner attribution code. Metadata only, included in signed receipts when present. */ builderCode?: string; /** Optional license endpoint base URL for enterprise tests or private mirrors. */ licenseEndpointBaseUrl?: string; /** Optional test hook for license endpoint calls. */ licensePostJson?: LicenseClientOptions['postJson']; /** Optional OpenRouter base URL for managed-key injection host matching. */ openRouterBaseUrl?: string; /** Optional endpoint base URL for managed-key fetch. Defaults to licenseEndpointBaseUrl. */ managedKeyEndpointBaseUrl?: string; /** Optional test hook for managed-key endpoint calls. */ managedKeyGetJson?: ManagedOpenRouterKeyOptions['getJson']; /** Force managed OpenRouter key lookup for tests or Pro runtimes. */ managedOpenRouterKey?: boolean; /** Provenance details for AgentGuard-managed inference receipts. */ inferenceBilling?: 'agentguard_managed' | 'customer_managed'; inferenceBillingDetail?: import('./receipts/schema').ComplianceInferenceBillingDetail | null; /** Governance posture used by provenance enforcement. Defaults to policy.posture or standard. */ posture?: GovernancePosture; /** Optional provider route override, e.g. aws-bedrock or baseten. */ providerRoute?: string; /** Opt-in model router. Disabled by default to preserve BYO behavior. */ modelRouter?: { auto?: boolean; vertical?: string; outcome?: string; posture?: string; budgetTier?: string; imageCapable?: boolean; }; /** Opt-in automatic Reviewer Cascade. Disabled by default. */ reviewerCascade?: { auto?: boolean; enabled?: boolean; outcome?: string; drafterConfidence?: ReviewerCascadeMetric; highRiskClassifierScore?: ReviewerCascadeMetric; keywordWatchlist?: string[]; outputExtractor?: (response: unknown) => string | Promise; reviewerPrompt?: (args: { originalParams: unknown; drafterOutput: string; triggerFired: string[]; }) => unknown[]; reviewerMaxTokens?: number; mode?: 'human' | 'model'; destructivePatterns?: string[]; destructive_patterns?: string[]; escalationModel?: string; escalation_model?: string; escalationEffort?: 'low' | 'medium' | 'high' | 'xhigh'; escalation_effort?: 'low' | 'medium' | 'high' | 'xhigh'; humanApprover?: ToolGateConfig['humanApprover']; modelReviewer?: ToolGateConfig['modelReviewer']; }; /** Opt-in loop and retry-storm circuit breaker. */ circuitBreaker?: CircuitBreakerConfig; /** Opt-in workflow budget envelope aggregated by workflow_id. */ workflowEnvelope?: WorkflowEnvelopeConfig; /** Optional hosting jurisdiction override for provenance receipts. */ jurisdictionCountry?: JurisdictionCountry; jurisdictionRegion?: string; /** Optional BAA and retention attestations supplied by the integrator. */ baaInForce?: boolean; baaVendor?: string | null; dataRetentionDays?: number | null; dataResidencyAttested?: boolean; /** Consent receipt for standard posture calls using foreign origin weights. */ foreignOriginConsentReceiptId?: string; /** Optional consent endpoint base URL for tests or private mirrors. */ consentEndpointBaseUrl?: string; /** Optional test hook for consent receipt verification. */ consentGetJson?: ComplianceEnforcementConfig['consentGetJson']; } export interface StreamSettlementOptions { partial?: boolean; reason?: string; } export interface StreamSettlementResult { decision: SpendDecision; signed: SignedDecisionLogEntry | null; deltaCents: number; } export declare class SpendGuard { private config; private spendStore; private logStore; private nextSequence; private previousHash; private decisionLock; private reservations; private licenseReady; constructor(config: SpendGuardConfig); hydrate(): Promise; decide(call: CallContext): Promise<{ decision: SpendDecision; signed: SignedDecisionLogEntry | null; }>; settleStreamUsage(decisionId: string, actualInputTokens: number, actualOutputTokens: number, options?: StreamSettlementOptions): Promise; guardToolCall(input: ToolGateInput): Promise; dispatchToolCall(input: ToolGateInput, fn: (args: Record) => T | Promise): Promise; private ensureLicenseReady; private signAndAppendDecision; private attachBuilderCode; private rememberReservation; private buildSettlementDecision; recordOutcomeReceipt(outcomeReceipt: Record): Promise<{ decision: SpendDecision; signed: SignedDecisionLogEntry | null; }>; /** * Sign + hash-chain a routing receipt onto the SAME decision log as * enforcement decisions. Reuses the existing Ed25519 + canonical-JSON signing * path (`signAndAppendDecision`); it does NOT introduce a second crypto * scheme. The routing receipt is metadata-only: candidates considered, * chosen provider+model, reason, resolved cost, and fallbacks. Prompt and * completion content and provider keys never enter it. */ recordRoutingReceipt(input: { provider: Provider; modelRequested: string; modelResolved: string; projectedCents: number; reason: string; routingReceipt: Record; }): Promise<{ decision: SpendDecision; signed: SignedDecisionLogEntry | null; }>; private getSignerFingerprint; private refreshChainHead; private withDecisionLock; private defaultTokenEstimator; estimateTokens(text: string): number; managedOpenRouterKeyForClient(): Promise; isOpenRouterClient(client: unknown): boolean; getSpendStore(): SpendStore; getLogStore(): DecisionLogStore; getPolicy(): SpendPolicy; } export interface OpenAIBindingOptions { policy: SpendPolicy; scope: SpendScope; capabilityClaim?: CapabilityTier; /** Optional DAG-TAT chain backing the capability claim (required when policy.attestation lists it). */ attestation?: AttestationChainInput; config?: Omit; licenseKey?: string; } export declare class AgentGuardBlockedError extends Error { decision: SpendDecision; scope?: SpendScope; locale?: string; constructor(decision: SpendDecision, scope?: SpendScope, locale?: string); } export declare function withSpendGuard(client: any, opts: OpenAIBindingOptions): any; export declare function serializeMessages(messages: unknown): string; export declare function serializeMessageContent(message: unknown): string; export declare function extractText(value: unknown): string; export declare function outputTokensFromParams(params: unknown): number; export interface UsageCounts { inputTokens: number; outputTokens: number; } export declare function extractUsage(response: unknown): UsageCounts | null; export declare function usageCountsFromObject(usage: unknown): UsageCounts | null; export declare function wrapUsageStream(stream: AsyncIterable, hooks: { onChunk: (chunk: T) => void; settle: (partial: boolean, reason?: string) => Promise; }): AsyncIterable; export {}; //# sourceMappingURL=spend-guard.d.ts.map