UNPKG

@kya-os/mcp-i

Version:

The TypeScript MCP framework with identity features built-in

175 lines (174 loc) 6.2 kB
/** * Proof Batch Queue * * Collects proofs in memory and submits them in batches to KTA and AgentShield. * This prevents blocking tool execution while ensuring proofs are eventually submitted. * * Performance: * - Batch size: 10 proofs (configurable) * - Flush interval: 5 seconds (configurable) * - Fire-and-forget submission (doesn't block tool execution) * * Retry Strategy: * - Exponential backoff: 1s, 2s, 4s, 8s, 16s * - Max retries: 5 * - Failed proofs logged and dropped after max retries * * Related: PHASE_1_XMCP_I_SERVER.md Epic 3 (Proof Batching) */ import type { DetachedProof } from "@kya-os/mcp/types" with { "resolution-mode": "import" }; /** * A proof plus the tool-call context KTA's submission API requires * alongside it. DetachedProof (proof.meta) carries did/kid/ts/nonce/ * audience/etc, but not which tool was called or how it turned out — * that context only exists at the call site, so it has to be threaded * through explicitly rather than derived from the proof. */ export interface ProofSubmission { proof: DetachedProof; toolName: string; outcome: "success" | "failure" | "denied"; } /** * Proof submission destination */ export interface ProofDestination { /** Destination name (for logging) */ name: string; /** Submit a batch of proof submissions */ submit(submissions: ProofSubmission[]): Promise<void>; } /** * Thrown by a ProofDestination whose submit() made independent per-item * requests (rather than one atomic request for the whole array) when only * some of them failed. Callers that retry on failure MUST retry only * `failed`, not the original full array — retrying everything would * resubmit proofs the destination already accepted. */ export declare class PartialProofSubmissionError extends Error { readonly failed: ProofSubmission[]; readonly succeededCount: number; /** The per-item rejection reason for each entry in `failed`, same order. */ readonly causes?: unknown[] | undefined; constructor(message: string, failed: ProofSubmission[], succeededCount: number, /** The per-item rejection reason for each entry in `failed`, same order. */ causes?: unknown[] | undefined); } /** * KTA proof submission destination * * The live KTA API (POST /api/v1/proofs) accepts exactly one proof per * request — there is no /batch endpoint — so a "batch" here means firing * one request per submission, not one request for the whole array. Since * each request is independent, submit() reports PARTIAL failure via * PartialProofSubmissionError rather than treating the whole array as * atomic — a caller that blindly retried everything on any rejection * would resubmit proofs that already succeeded. */ export declare class KTAProofDestination implements ProofDestination { name: string; private apiUrl; private apiKey?; constructor(apiUrl: string, apiKey?: string); submit(submissions: ProofSubmission[]): Promise<void>; private submitOne; } /** * AgentShield proof submission destination * * Submits proofs to AgentShield's /api/v1/bouncer/proofs endpoint * with proper authentication and session grouping. */ export declare class AgentShieldProofDestination implements ProofDestination { name: string; private apiUrl; private apiKey; constructor(apiUrl: string, apiKey: string); submit(submissions: ProofSubmission[]): Promise<void>; } /** * Proof batch queue configuration */ export interface ProofBatchQueueConfig { /** Destinations to submit proofs to */ destinations: ProofDestination[]; /** Maximum batch size (default: 10) */ maxBatchSize?: number; /** Flush interval in milliseconds (default: 5000 = 5 seconds) */ flushIntervalMs?: number; /** Maximum retries per batch (default: 5) */ maxRetries?: number; /** Enable debug logging */ debug?: boolean; } /** * Proof Batch Queue * * Collects proofs and submits them in batches to multiple destinations */ export declare class ProofBatchQueue { private queue; private pendingBatches; private config; private flushTimer?; private retryTimer?; private closed; private stats; constructor(config: ProofBatchQueueConfig); /** * Add a proof submission to the queue. * * Accepts a bare DetachedProof for backward compatibility with the * pre-#650 API: a plain-JS (or un-upgraded TS) consumer built against * the old `enqueue(proof: DetachedProof)` signature would otherwise have * `toolName`/`outcome` silently come through as `undefined`. */ enqueue(item: ProofSubmission | DetachedProof): void; /** * Normalize a bare DetachedProof (the pre-#650 enqueue() shape) into a * ProofSubmission. Derives toolName/outcome from the proof's own signed * meta when present, rather than a hardcoded literal -- a destination's * server-side check compares the submitted toolName/outcome against what * was actually signed into the JWS payload, so a literal that disagrees * with the real signed value is guaranteed to fail verification. When the * proof was never signed with these fields at all (a genuinely pre-#651 * proof), no fallback can make the submission succeed, so this warns * rather than silently queueing a doomed submission. */ private submissionFromBareProof; /** * Flush queue immediately (submit all queued proofs) */ flush(): Promise<void>; /** * Submit batch to destination (with retries) */ private submitBatch; /** * Start flush timer */ private startFlushTimer; /** * Start retry timer */ private startRetryTimer; /** * Close queue and flush remaining proofs */ close(): Promise<void>; /** * Get queue statistics */ getStats(): { queueSize: number; pendingBatches: number; queued: number; submitted: number; failed: number; batchesSubmitted: number; }; } /** * Create proof batch queue from config */ export declare function createProofBatchQueue(config: ProofBatchQueueConfig): ProofBatchQueue;