/** * otel-budget.ts — OpenTelemetry Budget Circuit-Breaker for AWS AgentCore * * Reads OTel span data from AgentCore-instrumented agents, applies per-agent * and per-task budget policies against accumulated spend, emits budget * enforcement decisions as OTel events, and supports circuit-breaker patterns * (auto-kill agent runs exceeding budget thresholds). * * Why this exists: AWS AgentCore Policy Controls (GA March 2026) provide * observability and guardrails but NO native per-agent/per-session spend cap * APIs. This module fills that gap by sitting between the OTel telemetry * pipeline and agentpay-mcp's existing budget enforcement. * * @module otel-budget * @since 4.2.0 */ import { z } from 'zod'; export interface AgentBudgetPolicy { /** Unique agent or session identifier */ agentId: string; /** Optional task-level identifier for fine-grained budgets */ taskId?: string; /** Maximum spend in USD for this agent/task */ maxSpendUsd: number; /** Rolling window in milliseconds (0 = lifetime budget) */ windowMs: number; /** Action when budget exceeded: 'warn' | 'block' | 'kill' */ breachAction: 'warn' | 'block' | 'kill'; /** Optional callback URL for circuit-breaker kill signal */ killCallbackUrl?: string; } export interface SpendRecord { agentId: string; taskId?: string; amountUsd: number; timestamp: number; spanId: string; traceId: string; } export interface BudgetDecision { agentId: string; taskId?: string; action: 'allow' | 'warn' | 'block' | 'kill'; accumulatedSpendUsd: number; budgetLimitUsd: number; remainingUsd: number; utilizationPct: number; reason: string; timestamp: number; } export interface OTelSpanCostAttributes { /** OTel span attribute: agentcore.agent.id */ 'agentcore.agent.id'?: string; /** OTel span attribute: agentcore.task.id */ 'agentcore.task.id'?: string; /** OTel span attribute: agentcore.cost.usd — cost incurred in this span */ 'agentcore.cost.usd'?: number; /** OTel span attribute: gen_ai.usage.input_tokens */ 'gen_ai.usage.input_tokens'?: number; /** OTel span attribute: gen_ai.usage.output_tokens */ 'gen_ai.usage.output_tokens'?: number; /** OTel span attribute: gen_ai.usage.cost */ 'gen_ai.usage.cost'?: number; /** Standard OTel trace/span IDs */ traceId?: string; spanId?: string; } /** Reset all state — useful for testing */ export declare function _resetOTelBudgetState(): void; /** * Register a budget policy for an agent or agent+task combination. */ export declare function registerPolicy(policy: AgentBudgetPolicy): void; /** * Process an OTel span and evaluate budget. Returns a BudgetDecision. * * This is the main entry point: feed it span attributes from an * AgentCore-instrumented agent, and it returns an enforcement decision. */ export declare function evaluateSpan(attrs: OTelSpanCostAttributes): BudgetDecision | null; export declare function invokeKillCallback(policy: AgentBudgetPolicy, decision: BudgetDecision): Promise<{ attempted: boolean; ok: boolean; status?: number; error?: string; } | null>; /** * Convert a BudgetDecision to OTel-compatible event attributes. * These can be emitted as span events for AgentCore dashboard visibility. */ export declare function decisionToOTelEvent(decision: BudgetDecision): Record; /** * Get recent decisions for an agent (for dashboard/audit). */ export declare function getDecisionHistory(agentId: string, limit?: number): BudgetDecision[]; /** * Get all registered policies (for introspection). */ export declare function listPolicies(): AgentBudgetPolicy[]; export declare const OTelRegisterPolicySchema: z.ZodObject<{ agentId: z.ZodString; taskId: z.ZodOptional; maxSpendUsd: z.ZodNumber; windowMs: z.ZodDefault; breachAction: z.ZodDefault>; killCallbackUrl: z.ZodOptional; }, "strip", z.ZodTypeAny, { agentId: string; maxSpendUsd: number; windowMs: number; breachAction: "block" | "warn" | "kill"; taskId?: string | undefined; killCallbackUrl?: string | undefined; }, { agentId: string; maxSpendUsd: number; taskId?: string | undefined; windowMs?: number | undefined; breachAction?: "block" | "warn" | "kill" | undefined; killCallbackUrl?: string | undefined; }>; export type OTelRegisterPolicyInput = z.infer; export declare const otelRegisterPolicyTool: { name: string; description: string; inputSchema: { type: "object"; properties: { agentId: { type: string; description: string; }; taskId: { type: string; description: string; }; maxSpendUsd: { type: string; description: string; }; windowMs: { type: string; description: string; }; breachAction: { type: string; enum: string[]; description: string; }; killCallbackUrl: { type: string; description: string; }; }; required: string[]; }; }; export declare function handleOTelRegisterPolicy(input: OTelRegisterPolicyInput): Promise<{ content: Array<{ type: 'text'; text: string; }>; isError?: boolean; }>; export declare const OTelEvaluateSpendSchema: z.ZodObject<{ agentId: z.ZodString; taskId: z.ZodOptional; costUsd: z.ZodNumber; spanId: z.ZodOptional; traceId: z.ZodOptional; }, "strip", z.ZodTypeAny, { agentId: string; costUsd: number; taskId?: string | undefined; spanId?: string | undefined; traceId?: string | undefined; }, { agentId: string; costUsd: number; taskId?: string | undefined; spanId?: string | undefined; traceId?: string | undefined; }>; export type OTelEvaluateSpendInput = z.infer; export declare const otelEvaluateSpendTool: { name: string; description: string; inputSchema: { type: "object"; properties: { agentId: { type: string; description: string; }; taskId: { type: string; description: string; }; costUsd: { type: string; description: string; }; spanId: { type: string; description: string; }; traceId: { type: string; description: string; }; }; required: string[]; }; }; export declare function handleOTelEvaluateSpend(input: OTelEvaluateSpendInput): Promise<{ content: Array<{ type: 'text'; text: string; }>; isError?: boolean; }>; export declare const OTelBudgetStatusSchema: z.ZodObject<{ agentId: z.ZodString; includeHistory: z.ZodDefault; historyLimit: z.ZodDefault; }, "strip", z.ZodTypeAny, { agentId: string; includeHistory: boolean; historyLimit: number; }, { agentId: string; includeHistory?: boolean | undefined; historyLimit?: number | undefined; }>; export type OTelBudgetStatusInput = z.infer; export declare const otelBudgetStatusTool: { name: string; description: string; inputSchema: { type: "object"; properties: { agentId: { type: string; description: string; }; includeHistory: { type: string; description: string; }; historyLimit: { type: string; description: string; }; }; required: string[]; }; }; export declare function handleOTelBudgetStatus(input: OTelBudgetStatusInput): Promise<{ content: Array<{ type: 'text'; text: string; }>; isError?: boolean; }>; //# sourceMappingURL=otel-budget.d.ts.map