@vinaverse/server 0.1.0-alpha.10 → 0.1.0-alpha.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/webhooks/crypto.ts","../src/internal/bytes.ts","../src/webhooks/errors.ts","../src/webhooks/events.ts","../src/webhooks/signature.ts","../src/webhooks/verify.ts","../src/adapters/handler.ts","../src/adapters/fetch.ts","../src/contract.ts","../src/generated/tool-operations.ts","../src/tools/idempotency.ts","../src/tools/nonces.ts","../src/tools/refusals.ts","../src/tools/signature.ts","../src/tools/provider.ts","../src/webhooks/sequence.ts"],"names":["fingerprint","until","problem"],"mappings":"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","file":"index.cjs","sourcesContent":["// Web Crypto wherever the package runs. Node 20+, AWS Lambda, edge runtimes\n// and React Native expose it as `globalThis.crypto`; Node 18 has the same API\n// but only as `webcrypto` in its crypto module, so on Node 18 it is loaded\n// from there, once.\n\n/** No Web Crypto in this runtime: the package cannot verify anything here. */\nexport class WebCryptoUnavailableError extends Error {\n constructor() {\n super(\n 'Web Crypto (crypto.subtle) is not available in this runtime; @vinaverse/server needs Node 18+, an edge runtime or another runtime with Web Crypto',\n );\n this.name = 'WebCryptoUnavailableError';\n }\n}\n\ntype MaybeNode = { process?: { versions?: { node?: unknown } } };\n\nlet fromNode: Promise<Crypto> | undefined;\n\n/** The runtime's Web Crypto: `crypto.subtle` and `crypto.getRandomValues`. */\nexport function webCrypto(): Promise<Crypto> {\n const global = (globalThis as { crypto?: Crypto }).crypto;\n if (global?.subtle) return Promise.resolve(global);\n fromNode ??= nodeWebCrypto();\n return fromNode;\n}\n\nexport async function subtleCrypto(): Promise<SubtleCrypto> {\n return (await webCrypto()).subtle;\n}\n\nasync function nodeWebCrypto(): Promise<Crypto> {\n if (typeof (globalThis as MaybeNode).process?.versions?.node !== 'string') {\n throw new WebCryptoUnavailableError();\n }\n // Built at run time on purpose: bundlers for edge runtimes and React Native,\n // where this line never runs, must not try to resolve a Node module.\n const specifier = ['node', 'crypto'].join(':');\n const mod = (await import(\n /* webpackIgnore: true */ /* @vite-ignore */ specifier\n )) as { webcrypto?: Crypto };\n if (!mod.webcrypto?.subtle) throw new WebCryptoUnavailableError();\n return mod.webcrypto;\n}\n","// Byte helpers on Web APIs only (no Buffer), shared by the signature checks.\nimport { subtleCrypto } from '../webhooks/crypto.js';\n\nconst encoder = new TextEncoder();\n\nexport function utf8(text: string): Uint8Array<ArrayBuffer> {\n return encoder.encode(text);\n}\n\nexport function toBytes(body: string | Uint8Array | ArrayBuffer): Uint8Array {\n if (typeof body === 'string') return utf8(body);\n if (body instanceof Uint8Array) return body;\n return new Uint8Array(body);\n}\n\nexport function hexToBytes(hex: string): Uint8Array<ArrayBuffer> {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n\nexport async function sha256Hex(data: Uint8Array): Promise<string> {\n const subtle = await subtleCrypto();\n return bytesToHex(new Uint8Array(await subtle.digest('SHA-256', copy(data))));\n}\n\nexport async function hmacKey(\n secret: string,\n usage: 'sign' | 'verify',\n): Promise<CryptoKey> {\n const subtle = await subtleCrypto();\n return subtle.importKey(\n 'raw',\n utf8(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n [usage],\n );\n}\n\n// Web Crypto takes an ArrayBuffer-backed view; a Node Buffer may sit on a\n// shared pool, so a view is copied when it does not own its whole buffer.\nexport function copy(data: Uint8Array): Uint8Array<ArrayBuffer> {\n const out = new Uint8Array(data.length);\n out.set(data);\n return out;\n}\n\nexport function concat(...parts: Uint8Array[]): Uint8Array<ArrayBuffer> {\n const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));\n let at = 0;\n for (const p of parts) {\n out.set(p, at);\n at += p.length;\n }\n return out;\n}\n","/**\n * Why a delivery was refused, in the conformance vectors' words\n * (vinaverse-contracts `conformance/webhooks.json`). Every one is answered with\n * `400`, so Vinaverse retries it; none of them is ever a valid delivery.\n *\n * - `missing`: no `Vinaverse-Signature` header.\n * - `malformed`: the header is not `t=<unix seconds>,v1=<hex>[,v1=<hex>]`\n * (no single timestamp, or no `v1` signature).\n * - `stale`: signed more than the tolerance (300 seconds) before or after now:\n * a replay, or a clock far off.\n * - `mismatch`: no `v1` signature matches the body with any secret: a wrong\n * secret (or the secret without its `vv_whsec_` prefix), a changed body, or a\n * body parsed and serialized again.\n * - `invalid_body`: signed by Vinaverse, but not a webhook envelope this\n * package can read.\n */\nexport type WebhookErrorCode =\n | 'missing'\n | 'malformed'\n | 'stale'\n | 'mismatch'\n | 'invalid_body';\n\nexport interface WebhookError {\n readonly code: WebhookErrorCode;\n readonly message: string;\n}\n\nexport function webhookError(\n code: WebhookErrorCode,\n message: string,\n): WebhookError {\n return { code, message };\n}\n","// The webhook events, typed from the pinned contract (vinaverse-v1.yaml,\n// `webhooks`), and the reading of a verified body into one of them.\nimport type { components, webhooks } from '../generated/vinaverse-v1.js';\nimport { type WebhookError, webhookError } from './errors.js';\n\ntype Schemas = components['schemas'];\n\n/** The envelope every webhook body has. `data` depends on `type`. */\nexport type WebhookEnvelope = Schemas['WebhookEnvelope'];\n\n/** Every event type the targeted contract defines. */\nexport type WebhookEventType = WebhookEnvelope['type'] & keyof webhooks;\n\ntype BodyOf<T extends WebhookEventType> = NonNullable<\n webhooks[T]['post']['requestBody']\n>['content']['application/json'];\n\n/** One event of type `T`: the envelope, with `data` as the contract says. */\nexport type WebhookEventOf<T extends WebhookEventType> = Omit<\n WebhookEnvelope,\n 'type' | 'data'\n> & {\n type: T;\n data: NonNullable<BodyOf<T>['data']>;\n};\n\n/** Any event this package version knows; narrow it on `type`. */\nexport type WebhookEvent = {\n [T in WebhookEventType]: WebhookEventOf<T>;\n}[WebhookEventType];\n\nexport type ConversationEventType =\n | 'conversation.updated'\n | 'conversation.completed'\n | 'conversation.failed'\n | 'conversation.expired';\n\n/** A guided-flow conversation's state changed: `data` is its `ConversationState`. */\nexport type ConversationEvent = {\n [T in ConversationEventType]: WebhookEventOf<T>;\n}[ConversationEventType];\n\nexport type ConversationState = Schemas['ConversationState'];\n\n// Kept in step with the contract by a test that reads the pinned YAML.\nexport const WEBHOOK_EVENT_TYPES: readonly WebhookEventType[] = [\n 'moderation.item.completed',\n 'moderation.job.completed',\n 'document_check.completed',\n 'session.completed',\n 'subject.erased',\n 'usage.threshold_reached',\n 'feature.state_changed',\n 'media.job.queued',\n 'media.job.progress',\n 'media.job.step.completed',\n 'media.job.completed',\n 'media.job.failed',\n 'media.job.cancelled',\n 'conversation.updated',\n 'conversation.completed',\n 'conversation.failed',\n 'conversation.expired',\n];\n\nconst KNOWN = new Set<string>(WEBHOOK_EVENT_TYPES);\n\n// The statuses each conversation event may carry (vinaverse-v1.yaml, webhooks).\nconst CONVERSATION_STATUSES: Readonly<Record<string, readonly string[]>> = {\n 'conversation.updated': ['in_progress', 'failed'],\n 'conversation.completed': ['completed'],\n 'conversation.failed': ['failed'],\n 'conversation.expired': ['expired'],\n};\nconst ENVIRONMENTS = new Set(['mock', 'development', 'production']);\n\nexport function isConversationEvent(\n event: WebhookEvent,\n): event is ConversationEvent {\n return event.type.startsWith('conversation.');\n}\n\n/** What a verified body is: a known event, a test delivery, or a type newer than this package. */\nexport type ReadBody =\n | { kind: 'event'; event: WebhookEvent }\n | { kind: 'test'; envelope: WebhookEnvelope }\n | { kind: 'unrecognized'; envelope: WebhookEnvelope };\n\ntype Json = Record<string, unknown>;\n\nfunction isObject(value: unknown): value is Json {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Reads a verified body: it must be the webhook envelope (`id`, `type`,\n * `created_at`, `environment`, `data`). A test delivery from Studio carries\n * `data: { test: true }` and no payload. A conversation event must carry a\n * guided flow's state with the status its type allows and the fields its\n * ordering depends on (`conversation_id`, `sequence`); other payloads are as\n * Vinaverse signed them. A type newer than this package is `unrecognized`,\n * never an error: answer it 2xx and upgrade.\n */\nexport function readBody(text: string): ReadBody | WebhookError {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return webhookError('invalid_body', 'the body is not JSON');\n }\n if (\n !isObject(parsed) ||\n typeof parsed.id !== 'string' ||\n typeof parsed.type !== 'string' ||\n typeof parsed.created_at !== 'string' ||\n typeof parsed.environment !== 'string' ||\n !ENVIRONMENTS.has(parsed.environment) ||\n !isObject(parsed.data)\n ) {\n return webhookError(\n 'invalid_body',\n 'the body is not a webhook envelope (id, type, created_at, environment, data)',\n );\n }\n const envelope = parsed as WebhookEnvelope;\n if (parsed.data.test === true) return { kind: 'test', envelope };\n if (!KNOWN.has(parsed.type)) return { kind: 'unrecognized', envelope };\n const statuses = CONVERSATION_STATUSES[parsed.type];\n if (statuses) {\n const { conversation_id, sequence, status, flow } = parsed.data;\n if (\n typeof conversation_id !== 'string' ||\n !Number.isSafeInteger(sequence) ||\n (sequence as number) < 1 ||\n typeof status !== 'string' ||\n !statuses.includes(status) ||\n typeof flow !== 'string'\n ) {\n return webhookError(\n 'invalid_body',\n `a ${parsed.type} event carries a guided flow's state: conversation_id, a positive integer sequence, a flow, and status ${statuses.join(' or ')}`,\n );\n }\n }\n return { kind: 'event', event: parsed as WebhookEvent };\n}\n","// The webhook signature, exactly as the Vinaverse API signs and checks it\n// (contract: docs/conversation-state.md §1, \"Delivery\"):\n// Vinaverse-Signature: t=<unix seconds>,v1=<hex>[,v1=<hex>]\n// `v1` is the lowercase hex HMAC-SHA256, keyed with the endpoint's whole\n// signing secret as UTF-8 (the `vv_whsec_` prefix included, never decoded),\n// over `<t>.` followed by the raw request body. During a secret rotation the\n// header carries one `v1` per valid secret. A signature more than 300 seconds\n// from now, either way, is refused.\nimport { concat, hexToBytes, hmacKey, utf8 } from '../internal/bytes.js';\nimport { subtleCrypto } from './crypto.js';\nimport { type WebhookError, webhookError } from './errors.js';\n\nexport const SIGNATURE_HEADER = 'Vinaverse-Signature';\nexport const TOLERANCE_SECONDS = 300;\n\nconst DIGITS = /^[0-9]+$/;\nconst V1 = /^[0-9a-f]{64}$/;\n\nexport interface ParsedSignature {\n /** The signed timestamp, in Unix seconds. */\n readonly timestamp: bigint;\n /** Each `v1` signature, decoded. */\n readonly signatures: readonly Uint8Array[];\n}\n\n/**\n * Reads the header the way the API's own verifier does: comma-separated\n * `key=value` parts (a space around a part changes nothing), exactly one `t`\n * of digits, and the `v1` values. A `v1`\n * that is not 64 lowercase hex digits can never match, so it is left out; a\n * header left with no `v1` is malformed.\n */\nexport function parseSignatureHeader(\n header: string,\n): ParsedSignature | WebhookError {\n const parts = header\n .split(',')\n .map((p) => p.trim())\n .filter((p) => p.includes('='))\n .map((p) => {\n const at = p.indexOf('=');\n return [p.slice(0, at), p.slice(at + 1)] as const;\n });\n const timestamps = parts.filter(([k]) => k === 't').map(([, v]) => v);\n const [t] = timestamps;\n if (timestamps.length !== 1 || t === undefined || !DIGITS.test(t)) {\n return webhookError(\n 'malformed',\n 'the signature header needs exactly one timestamp, t=<unix seconds>',\n );\n }\n const signatures = parts\n .filter(([k, v]) => k === 'v1' && V1.test(v))\n .map(([, v]) => hexToBytes(v));\n if (signatures.length === 0) {\n return webhookError(\n 'malformed',\n 'the signature header has no v1 signature',\n );\n }\n return { timestamp: BigInt(t), signatures };\n}\n\n/**\n * Checks a delivery's signature: the header's form, its timestamp against\n * `now`, then each `v1` against each secret, in constant time (Web Crypto's\n * `verify`). `secrets` is more than one while the receiver rolls a new secret\n * out. Returns null when the signature is valid.\n */\nexport async function checkSignature(options: {\n body: Uint8Array;\n header: string;\n secrets: readonly string[];\n now: Date;\n toleranceSeconds: number;\n}): Promise<WebhookError | null> {\n const parsed = parseSignatureHeader(options.header);\n if ('code' in parsed) return parsed;\n const now = BigInt(Math.floor(options.now.getTime() / 1000));\n const skew =\n now > parsed.timestamp ? now - parsed.timestamp : parsed.timestamp - now;\n if (skew > BigInt(options.toleranceSeconds)) {\n return webhookError(\n 'stale',\n `the signature is ${skew} seconds from now; at most ${options.toleranceSeconds} are accepted`,\n );\n }\n const message = concat(utf8(`${parsed.timestamp}.`), options.body);\n const subtle = await subtleCrypto();\n for (const secret of options.secrets) {\n const key = await hmacKey(secret, 'verify');\n for (const signature of parsed.signatures) {\n // Every signature is decoded into its own ArrayBuffer (hexToBytes).\n if (\n await subtle.verify(\n 'HMAC',\n key,\n signature as Uint8Array<ArrayBuffer>,\n message,\n )\n )\n return null;\n }\n }\n return webhookError(\n 'mismatch',\n 'no signature matches the body with the signing secret: check the secret, and verify the raw body exactly as received',\n );\n}\n","import { toBytes } from '../internal/bytes.js';\nimport { type WebhookError, webhookError } from './errors.js';\nimport { type ReadBody, readBody } from './events.js';\nimport { checkSignature, TOLERANCE_SECONDS } from './signature.js';\n\nexport interface VerifyWebhookOptions {\n /**\n * The request body exactly as received, before any JSON parsing: a string,\n * or bytes (`Uint8Array`, which a Node `Buffer` is, or `ArrayBuffer`). A\n * body parsed and serialized again never verifies.\n */\n rawBody: string | Uint8Array | ArrayBuffer;\n /** The `Vinaverse-Signature` header (a framework's string array is accepted). */\n header: string | readonly string[] | null | undefined;\n /**\n * The endpoint's signing secret (`vv_whsec_…`), whole. Pass two while you\n * roll a new one out: a delivery verifies if either matches.\n */\n secret: string | readonly string[];\n /** The time to check the signature's timestamp against; default now. */\n now?: Date;\n /** How far from `now` a signature may be: whole seconds, 0 to 300 (the contract's window, the default). */\n toleranceSeconds?: number;\n}\n\nexport type VerifyWebhookResult =\n | ({ ok: true } & ReadBody)\n | { ok: false; error: WebhookError };\n\n/**\n * Verifies a Vinaverse webhook delivery and reads it, in one call:\n *\n * - `{ ok: true, kind: 'event', event }`: a verified event; narrow it on `event.type`.\n * - `{ ok: true, kind: 'test', envelope }`: a test delivery from Studio; answer 2xx, do nothing.\n * - `{ ok: true, kind: 'unrecognized', envelope }`: verified, but a type newer than this\n * package; answer 2xx, and upgrade to handle it.\n * - `{ ok: false, error }`: refused (`error.code` says why); answer 400.\n *\n * Deliveries are at least once: deduplicate on `event.id`, and order a\n * conversation's states with `sequenceVerdict` or `applyConversationState`.\n * It never throws for a bad delivery; it throws a `TypeError` for a missing\n * secret or a tolerance that is not a whole number of seconds from 0 to 300,\n * and `WebCryptoUnavailableError` in a runtime without Web Crypto.\n */\nexport async function verifyWebhook(\n options: VerifyWebhookOptions,\n): Promise<VerifyWebhookResult> {\n const secrets = signingSecrets(options.secret);\n const toleranceSeconds = checkTolerance(options.toleranceSeconds);\n const header = singleHeader(options.header);\n if (header === undefined) {\n return {\n ok: false,\n error: webhookError('missing', 'no Vinaverse-Signature header'),\n };\n }\n if (header === null) {\n return {\n ok: false,\n error: webhookError(\n 'malformed',\n 'more than one Vinaverse-Signature header',\n ),\n };\n }\n const body = toBytes(options.rawBody);\n const refused = await checkSignature({\n body,\n header,\n secrets,\n now: options.now ?? new Date(),\n toleranceSeconds,\n });\n if (refused) return { ok: false, error: refused };\n let text: string;\n try {\n text = new TextDecoder('utf-8', { fatal: true }).decode(body);\n } catch {\n return {\n ok: false,\n error: webhookError('invalid_body', 'the body is not UTF-8'),\n };\n }\n const read = readBody(text);\n return 'code' in read ? { ok: false, error: read } : { ok: true, ...read };\n}\n\n// undefined: absent; null: more than one; otherwise the header.\nfunction singleHeader(\n header: string | readonly string[] | null | undefined,\n): string | null | undefined {\n if (header === null || header === undefined) return undefined;\n if (typeof header === 'string') return header === '' ? undefined : header;\n if (header.length === 0) return undefined;\n return header.length === 1 ? header[0] : null;\n}\n\n/** The signing secrets, checked: a TypeError for none, an empty one, or an unset variable. */\nexport function signingSecrets(secret: unknown): string[] {\n const list =\n typeof secret === 'string'\n ? [secret]\n : Array.isArray(secret)\n ? [...secret]\n : [];\n if (\n list.length === 0 ||\n list.some((s) => typeof s !== 'string' || s === '')\n ) {\n throw new TypeError(\n 'the webhook signing secret is required (vv_whsec_…), and none was given',\n );\n }\n return list as string[];\n}\n\n/**\n * The tolerance, checked once: whole seconds from 0 to 300. A wider window is\n * a longer replay window than the contract allows.\n */\nexport function checkTolerance(seconds: number | undefined): number {\n if (seconds === undefined) return TOLERANCE_SECONDS;\n if (\n !Number.isSafeInteger(seconds) ||\n seconds < 0 ||\n seconds > TOLERANCE_SECONDS\n ) {\n throw new TypeError(\n `toleranceSeconds must be a whole number of seconds from 0 to ${TOLERANCE_SECONDS}, not ${seconds}`,\n );\n }\n return seconds;\n}\n","// What every adapter does with a delivery once it has the raw body and the\n// signature header: verify, call the tenant's handler for the result, and\n// answer. A refused delivery is answered 400 (Vinaverse retries, then gives\n// up); a handled one 200. A handler that throws is the adapter's to surface,\n// so the delivery fails and Vinaverse retries it.\nimport type { WebhookError } from '../webhooks/errors.js';\nimport type { WebhookEnvelope, WebhookEvent } from '../webhooks/events.js';\nimport {\n checkTolerance,\n signingSecrets,\n verifyWebhook,\n} from '../webhooks/verify.js';\n\nexport interface WebhookHandlerOptions {\n /** The endpoint's signing secret, or two while rolling a new one out. */\n secret: string | readonly string[];\n /**\n * Called once per verified delivery of a known event. Answer quickly (the\n * contract allows 5 seconds) and do the work afterwards; deliveries are at\n * least once, so deduplicate on `event.id`.\n */\n onEvent(event: WebhookEvent): void | Promise<void>;\n /** A test delivery from Studio; by default it is acknowledged and ignored. */\n onTest?(envelope: WebhookEnvelope): void | Promise<void>;\n /** A verified type newer than this package; by default acknowledged and ignored. */\n onUnrecognized?(envelope: WebhookEnvelope): void | Promise<void>;\n /** A refused delivery, for logging; it is answered 400 either way. */\n onRejected?(error: WebhookError): void | Promise<void>;\n /** How far from now a signature may be, in seconds; default 300. */\n toleranceSeconds?: number;\n /**\n * The largest body accepted, in bytes; default 1 MiB (a conversation\n * webhook is at most 64 KB). A larger one is answered 413 unread.\n */\n maxBodyBytes?: number;\n /** The clock; default the system clock. */\n now?: () => Date;\n}\n\nexport interface WebhookResponse {\n readonly status: 200 | 400 | 413;\n readonly body: string;\n}\n\nexport const MAX_BODY_BYTES = 1024 * 1024;\nconst RECEIVED = JSON.stringify({ received: true });\n\nexport function tooLarge(): WebhookResponse {\n return {\n status: 413,\n body: JSON.stringify({ error: { code: 'body_too_large' } }),\n };\n}\n\nexport function byteLength(body: string | Uint8Array | ArrayBuffer): number {\n return typeof body === 'string'\n ? new TextEncoder().encode(body).length\n : body.byteLength;\n}\n\nexport async function handleWebhook(\n options: WebhookHandlerOptions,\n rawBody: string | Uint8Array | ArrayBuffer,\n header: string | readonly string[] | null | undefined,\n): Promise<WebhookResponse> {\n if (byteLength(rawBody) > (options.maxBodyBytes ?? MAX_BODY_BYTES)) {\n return tooLarge();\n }\n const result = await verifyWebhook({\n rawBody,\n header,\n secret: options.secret,\n ...(options.now ? { now: options.now() } : {}),\n ...(options.toleranceSeconds === undefined\n ? {}\n : { toleranceSeconds: options.toleranceSeconds }),\n });\n if (!result.ok) {\n await options.onRejected?.(result.error);\n return {\n status: 400,\n body: JSON.stringify({ error: { code: result.error.code } }),\n };\n }\n if (result.kind === 'event') await options.onEvent(result.event);\n else if (result.kind === 'test') await options.onTest?.(result.envelope);\n else await options.onUnrecognized?.(result.envelope);\n return { status: 200, body: RECEIVED };\n}\n\n/** A header's value from a record whose names may have any case. */\nexport function headerValue(\n headers:\n | Readonly<Record<string, string | readonly string[] | undefined>>\n | null\n | undefined,\n name: string,\n): string | readonly string[] | undefined {\n if (!headers) return undefined;\n const wanted = name.toLowerCase();\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === wanted && value !== undefined) return value;\n }\n return undefined;\n}\n\n/**\n * Checks a handler's options once, when the adapter is made, so a wrong value\n * fails at start-up instead of answering every delivery with an error.\n */\nexport function checkHandlerOptions(options: WebhookHandlerOptions): void {\n signingSecrets(options.secret);\n checkTolerance(options.toleranceSeconds);\n if (typeof options.onEvent !== 'function') {\n throw new TypeError(\n 'onEvent is required: it receives every verified event',\n );\n }\n const max = options.maxBodyBytes;\n if (max !== undefined && (!Number.isSafeInteger(max) || max <= 0)) {\n throw new TypeError(\n `maxBodyBytes must be a positive whole number of bytes, not ${max}`,\n );\n }\n}\n","// Web-standard handlers: anything that hands over a `Request` and takes a\n// `Response` (Hono, Next.js route handlers, Cloudflare Workers, Deno, Bun).\nimport {\n checkHandlerOptions,\n handleWebhook,\n MAX_BODY_BYTES,\n tooLarge,\n type WebhookHandlerOptions,\n type WebhookResponse,\n} from './handler.js';\n\nexport type { WebhookHandlerOptions } from './handler.js';\n\nimport type { ToolProvider } from '../tools/provider.js';\n\n/**\n * `(request) => Promise<Response>` for a Vinaverse webhook endpoint. It reads\n * the raw body itself, so mount it where nothing has parsed the body:\n *\n * export const POST = createFetchWebhookHandler({ secret, onEvent });\n */\nexport function createFetchWebhookHandler(\n options: WebhookHandlerOptions,\n): (request: Request) => Promise<Response> {\n checkHandlerOptions(options);\n const max = options.maxBodyBytes ?? MAX_BODY_BYTES;\n return async (request) => {\n const body = await readCapped(request, max);\n if (body === undefined) return toResponse(tooLarge());\n return toResponse(\n await handleWebhook(\n options,\n body,\n request.headers.get('vinaverse-signature'),\n ),\n );\n };\n}\n\n/**\n * The body, read as a stream and stopped past `max` bytes (undefined then),\n * so neither a declared nor a chunked oversized body is held in memory.\n */\nexport async function readCapped(\n request: Request,\n max: number,\n): Promise<Uint8Array | undefined> {\n const declared = Number(request.headers.get('content-length') ?? '0');\n if (declared > max) return undefined;\n if (!request.body) return new Uint8Array(0);\n const reader = request.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.length;\n if (size > max) {\n await reader.cancel();\n return undefined;\n }\n chunks.push(value);\n }\n const body = new Uint8Array(size);\n let at = 0;\n for (const chunk of chunks) {\n body.set(chunk, at);\n at += chunk.length;\n }\n return body;\n}\n\nexport function toResponse(response: WebhookResponse): Response {\n return new Response(response.body, {\n status: response.status,\n headers: { 'content-type': 'application/json' },\n });\n}\n\n/**\n * `(request) => Promise<Response>` serving a tenant's tools: every tool route\n * under the provider's `basePath`, with the contract enforced. The target is\n * the request URL's path and query as received.\n *\n * const handle = createFetchToolHandler(createToolProvider({ … }));\n */\nexport function createFetchToolHandler(\n provider: ToolProvider,\n options: { maxBodyBytes?: number } = {},\n): (request: Request) => Promise<Response> {\n const max = options.maxBodyBytes ?? MAX_BODY_BYTES;\n return async (request) => {\n const url = new URL(request.url);\n const reads = request.method !== 'GET' && request.method !== 'HEAD';\n const body = reads ? await readCapped(request, max) : null;\n if (body === undefined) {\n return new Response(\n JSON.stringify({\n status: 413,\n code: 'invalid_argument',\n detail: 'the request body is too large',\n }),\n {\n status: 413,\n headers: { 'content-type': 'application/problem+json' },\n },\n );\n }\n const response = await provider.handle({\n method: request.method,\n target: `${url.pathname}${url.search}`,\n header: (name) => request.headers.get(name) ?? undefined,\n body,\n });\n return new Response(response.body, {\n status: response.status,\n headers: response.headers,\n });\n };\n}\n","// The contract this package version targets: the public API's version and the\n// vinaverse-contracts commit its types were generated from (contracts.lock).\n// A test holds both to the pinned contracts, so they cannot drift.\nexport const CONTRACT = {\n api: 'v1-draft.22',\n commit: '4695e3dc042e6e0cf1936aae24fcb093eacd27c8',\n} as const;\n","// Generated by scripts/gen-tool-operations.mjs from the pinned tool-provider contract (v1-draft.15). Do not edit.\nexport const TOOL_OPERATIONS = {\n create_handoff: {\n id: 'create_handoff',\n method: 'POST',\n path: '/handoffs',\n effect: 'write',\n maxResultBytes: 16384,\n successStatus: 201,\n idempotencyKey: true,\n body: true,\n pathParams: {},\n queryParams: {},\n },\n create_proposal: {\n id: 'create_proposal',\n method: 'POST',\n path: '/proposals',\n effect: 'propose',\n maxResultBytes: 16384,\n successStatus: 201,\n idempotencyKey: true,\n body: true,\n pathParams: {},\n queryParams: {},\n },\n get_availability: {\n id: 'get_availability',\n method: 'GET',\n path: '/availability',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n professional_id: { type: 'string', required: true },\n service_id: { type: 'string', required: true },\n from: { type: 'string', required: true },\n to: { type: 'string', required: true },\n limit: { type: 'integer', required: false },\n },\n },\n get_flow_definition: {\n id: 'get_flow_definition',\n method: 'GET',\n path: '/flows/{flow}/definition',\n effect: 'read',\n maxResultBytes: 131072,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { flow: { type: 'string', required: true } },\n queryParams: { version: { type: 'integer', required: false } },\n },\n get_my_booking: {\n id: 'get_my_booking',\n method: 'GET',\n path: '/me/bookings/{id}',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { id: { type: 'string', required: true } },\n queryParams: {},\n },\n get_my_kit: {\n id: 'get_my_kit',\n method: 'GET',\n path: '/me/kits/{id}',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { id: { type: 'string', required: true } },\n queryParams: {},\n },\n get_my_order: {\n id: 'get_my_order',\n method: 'GET',\n path: '/me/orders/{id}',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { id: { type: 'string', required: true } },\n queryParams: {},\n },\n get_policy: {\n id: 'get_policy',\n method: 'GET',\n path: '/policies/{topic}',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { topic: { type: 'string', required: true } },\n queryParams: {},\n },\n get_professional: {\n id: 'get_professional',\n method: 'GET',\n path: '/professionals/{id}',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { id: { type: 'string', required: true } },\n queryParams: {},\n },\n get_quote: {\n id: 'get_quote',\n method: 'POST',\n path: '/quotes',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: true,\n body: true,\n pathParams: {},\n queryParams: {},\n },\n get_setup_state: {\n id: 'get_setup_state',\n method: 'GET',\n path: '/business/setup',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {},\n },\n get_workspace: {\n id: 'get_workspace',\n method: 'GET',\n path: '/workspaces/{id}',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { id: { type: 'string', required: true } },\n queryParams: {},\n },\n list_my_bookings: {\n id: 'list_my_bookings',\n method: 'GET',\n path: '/me/bookings',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n scope: { type: 'string', required: false },\n limit: { type: 'integer', required: false },\n },\n },\n list_my_kits: {\n id: 'list_my_kits',\n method: 'GET',\n path: '/me/kits',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n scope: { type: 'string', required: false },\n limit: { type: 'integer', required: false },\n },\n },\n list_my_orders: {\n id: 'list_my_orders',\n method: 'GET',\n path: '/me/orders',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n kit_id: { type: 'string', required: false },\n limit: { type: 'integer', required: false },\n },\n },\n list_services: {\n id: 'list_services',\n method: 'GET',\n path: '/catalog/services',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n q: { type: 'string', required: true },\n limit: { type: 'integer', required: false },\n },\n },\n list_services_in_area: {\n id: 'list_services_in_area',\n method: 'GET',\n path: '/areas/services',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n lat: { type: 'number', required: false },\n lng: { type: 'number', required: false },\n radius_miles: { type: 'integer', required: false },\n },\n },\n resolve_place: {\n id: 'resolve_place',\n method: 'GET',\n path: '/places/resolve',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n text: { type: 'string', required: true },\n near_lat: { type: 'number', required: false },\n near_lng: { type: 'number', required: false },\n },\n },\n search_professionals: {\n id: 'search_professionals',\n method: 'GET',\n path: '/search/professionals',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n q: { type: 'string', required: false },\n category_id: { type: 'string', required: false },\n service_type_id: { type: 'string', required: false },\n lat: { type: 'number', required: false },\n lng: { type: 'number', required: false },\n radius_miles: { type: 'integer', required: false },\n date: { type: 'string', required: false },\n time_from: { type: 'string', required: false },\n time_to: { type: 'string', required: false },\n max_price: { type: 'integer', required: false },\n min_rating_ppm: { type: 'integer', required: false },\n sort: { type: 'string', required: false },\n limit: { type: 'integer', required: false },\n cursor: { type: 'string', required: false },\n },\n },\n search_workspaces: {\n id: 'search_workspaces',\n method: 'GET',\n path: '/search/workspaces',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n q: { type: 'string', required: false },\n space_category: { type: 'string', required: false },\n lat: { type: 'number', required: false },\n lng: { type: 'number', required: false },\n radius_miles: { type: 'integer', required: false },\n max_price: { type: 'integer', required: false },\n min_rating_ppm: { type: 'integer', required: false },\n sort: { type: 'string', required: false },\n limit: { type: 'integer', required: false },\n cursor: { type: 'string', required: false },\n },\n },\n submit_flow: {\n id: 'submit_flow',\n method: 'POST',\n path: '/flows/{flow}/submissions',\n effect: 'write',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: true,\n pathParams: { flow: { type: 'string', required: true } },\n queryParams: {},\n },\n} as const;\n\nexport type ToolOperationId = keyof typeof TOOL_OPERATIONS;\n","// Idempotency for the tool calls that change something (contract:\n// tool-provider-v1.yaml, `submit_flow`, `create_proposal`, and every call\n// with a required `Idempotency-Key`). A call is recorded under a key with a\n// fingerprint of what it asked; the same key and fingerprint gets the stored\n// answer again, and the same key with another fingerprint is a conflict.\n\nimport { sha256Hex, utf8 } from '../internal/bytes.js';\n\n/** What a store holds for a key. `pending` while the first call runs. */\nexport interface IdempotencyRecord {\n /** The hex SHA-256 of what the call asked (never the request itself). */\n readonly fingerprint: string;\n readonly state: 'pending' | 'done';\n /** The stored answer, once done. */\n readonly status?: number;\n readonly body?: string;\n}\n\n/**\n * Every write is tied to the call that started the key (`owner`, random per\n * call): a call whose pending lease lapsed and was taken by another can\n * neither store its answer over that call's nor release that call's lease.\n */\nexport interface IdempotencyStore {\n /**\n * Creates a pending record for `key`, held by `owner`, and returns null, or,\n * when one exists, returns it unchanged. Must be atomic across every\n * instance sharing the store. A pending record lapses after\n * `pendingSeconds`, so a call that crashed does not hold its key forever.\n */\n start(\n key: string,\n fingerprint: string,\n pendingSeconds: number,\n owner: string,\n ): Promise<IdempotencyRecord | null>;\n /**\n * Stores the answer for `key`, kept for `keepSeconds`, when `owner` still\n * holds the pending record (or nobody holds the key); returns false and\n * stores nothing when another call holds it or has answered.\n */\n finish(\n key: string,\n record: { fingerprint: string; status: number; body: string },\n keepSeconds: number,\n owner: string,\n ): Promise<boolean>;\n /** Drops the record if `owner` still holds it pending (the call failed without an answer to keep). */\n release(key: string, owner: string): Promise<void>;\n}\n\ninterface Held {\n record: IdempotencyRecord;\n owner?: string;\n until: number;\n}\n\n/**\n * An in-process store: right for one instance and for tests. Expired records\n * are dropped on one `start` in `sweepEvery` (default 256).\n */\nexport class MemoryIdempotencyStore implements IdempotencyStore {\n readonly #held = new Map<string, Held>();\n readonly #now: () => number;\n readonly #sweepEvery: number;\n #starts = 0;\n\n constructor(options: { now?: () => number; sweepEvery?: number } = {}) {\n this.#now = options.now ?? (() => Date.now() / 1000);\n this.#sweepEvery = Math.max(1, options.sweepEvery ?? 256);\n }\n\n async start(\n key: string,\n fingerprint: string,\n pendingSeconds: number,\n owner: string,\n ): Promise<IdempotencyRecord | null> {\n const now = this.#now();\n if (++this.#starts % this.#sweepEvery === 0) {\n for (const [k, h] of this.#held) if (h.until < now) this.#held.delete(k);\n }\n const held = this.#live(key);\n if (held) return held.record;\n this.#held.set(key, {\n record: { fingerprint, state: 'pending' },\n owner,\n until: now + pendingSeconds,\n });\n return null;\n }\n\n async finish(\n key: string,\n record: { fingerprint: string; status: number; body: string },\n keepSeconds: number,\n owner: string,\n ): Promise<boolean> {\n const held = this.#live(key);\n if (held && (held.record.state !== 'pending' || held.owner !== owner)) {\n return false;\n }\n this.#held.set(key, {\n record: { ...record, state: 'done' },\n until: this.#now() + keepSeconds,\n });\n return true;\n }\n\n async release(key: string, owner: string): Promise<void> {\n const held = this.#live(key);\n if (held?.record.state === 'pending' && held.owner === owner) {\n this.#held.delete(key);\n }\n }\n\n /** Records held, expired ones included until a sweep drops them. */\n get size(): number {\n return this.#held.size;\n }\n\n #live(key: string): Held | undefined {\n const held = this.#held.get(key);\n return held && held.until >= this.#now() ? held : undefined;\n }\n}\n\n/** The fingerprint of a request: the hex SHA-256 of its canonical JSON. */\nexport function fingerprint(value: unknown): Promise<string> {\n return sha256Hex(utf8(canonicalJson(value)));\n}\n\n/**\n * JSON with keys sorted at every level and no insignificant whitespace, so\n * two bodies equal as JSON (key order aside, numbers by value: `1` and `1.0`)\n * have one fingerprint.\n */\nexport function canonicalJson(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`;\n if (value !== null && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`).join(',')}}`;\n }\n return JSON.stringify(value) ?? 'null';\n}\n","// Single-use nonces for tool calls (contract: tool-provider-v1.yaml,\n// `vinaverseSignature`, \"Nonces\"). A nonce is taken once; a second call with\n// it is a replay. Each one is kept until at least `t + 300` seconds, counted\n// from the call's `t`; 6 minutes after `t` is kept here. Every instance that\n// receives calls must share one store, or calls must be pinned to one\n// instance: otherwise a replay sent to another instance passes.\n\n/** Keep each nonce this long after the call's `t` (the contract's minimum is the 300-second window). */\nexport const NONCE_KEEP_SECONDS = 360;\n\nexport interface NonceStore {\n /**\n * Takes `nonce` until `keepUntil` (Unix seconds): true the first time it is\n * seen, false for a replay. Must be atomic across every instance that\n * shares the store.\n */\n claim(nonce: string, keepUntil: number): Promise<boolean>;\n}\n\n/**\n * An in-process store: right for one instance (a single server, tests, one\n * Lambda with reserved concurrency of 1). Behind several instances, use a\n * shared store (`@vinaverse/server/stores`: Redis, DynamoDB, Postgres).\n * Expired nonces are dropped on one claim in `sweepEvery` (default 256).\n */\nexport class MemoryNonceStore implements NonceStore {\n readonly #seen = new Map<string, number>();\n readonly #now: () => number;\n readonly #sweepEvery: number;\n #claims = 0;\n\n constructor(options: { now?: () => number; sweepEvery?: number } = {}) {\n this.#now = options.now ?? (() => Math.floor(Date.now() / 1000));\n this.#sweepEvery = Math.max(1, options.sweepEvery ?? 256);\n }\n\n async claim(nonce: string, keepUntil: number): Promise<boolean> {\n const now = this.#now();\n if (++this.#claims % this.#sweepEvery === 0) {\n for (const [n, until] of this.#seen) {\n if (until < now) this.#seen.delete(n);\n }\n }\n const until = this.#seen.get(nonce);\n if (until !== undefined && until >= now) return false;\n this.#seen.set(nonce, keepUntil);\n return true;\n }\n\n /** Nonces held, expired ones included until a sweep drops them. */\n get size(): number {\n return this.#seen.size;\n }\n}\n","// Typed refusals a tool handler throws; the toolkit answers each with the\n// status and problem body the contract defines (tool-provider-v1.yaml,\n// `Problem`, `FlowSubmissionRefusal`, the `410` of `get_flow_definition`).\n// The runtime maps a problem's `code` to what the agent does: ask again\n// (`invalid_argument`, with `field` and `example`), say the record is not\n// there (`not_found`), stop (`forbidden`), try later (`unavailable`), or end\n// the session's tool access (`token_expired`, always a 401).\n\nexport type ProblemCode =\n | 'not_found'\n | 'forbidden'\n | 'invalid_argument'\n | 'unavailable'\n | 'token_expired';\n\n/** The codes a refused flow submission carries (`FlowSubmissionRefusal`). */\nexport type FlowRefusalCode =\n | 'REQUIRED_MISSING'\n | 'UNKNOWN_VALUE'\n | 'TOO_LONG'\n | 'VERSION_NOT_ACCEPTED'\n | 'TOO_MANY'\n | 'TOO_FEW'\n | 'BAD_DATE'\n | 'UPLOAD_NOT_FOUND'\n | 'OUT_OF_RANGE';\n\nconst FLOW_REFUSAL_CODES: Record<FlowRefusalCode, true> = {\n REQUIRED_MISSING: true,\n UNKNOWN_VALUE: true,\n TOO_LONG: true,\n VERSION_NOT_ACCEPTED: true,\n TOO_MANY: true,\n TOO_FEW: true,\n BAD_DATE: true,\n UPLOAD_NOT_FOUND: true,\n OUT_OF_RANGE: true,\n};\n\n/**\n * Whether a problem is a `FlowSubmissionRefusal`: a 422 with a flow code and\n * the question to ask again (none only for `VERSION_NOT_ACCEPTED`).\n */\nexport function isFlowRefusal(problem: ProblemBody): boolean {\n return (\n problem.status === 422 &&\n Object.hasOwn(FLOW_REFUSAL_CODES, problem.code) &&\n (problem.code === 'VERSION_NOT_ACCEPTED' || !!problem.question_id)\n );\n}\n\nexport interface ProblemBody {\n readonly status: number;\n readonly code: string;\n readonly detail?: string;\n readonly field?: string;\n readonly example?: string;\n readonly question_id?: string;\n}\n\nconst STATUS: Record<ProblemCode, number> = {\n not_found: 404,\n forbidden: 403,\n invalid_argument: 422,\n unavailable: 503,\n token_expired: 401,\n};\n\n/** A refusal the toolkit sends as the contract's problem details. */\nexport class ToolRefusal extends Error {\n readonly problem: ProblemBody;\n\n constructor(problem: ProblemBody) {\n super(problem.detail ?? problem.code);\n this.name = 'ToolRefusal';\n this.problem = problem;\n }\n\n get status(): number {\n return this.problem.status;\n }\n\n /** The record does not exist, or the person may not see it (both are the same 404). */\n static notFound(detail?: string): ToolRefusal {\n return ToolRefusal.#coded('not_found', detail);\n }\n\n static forbidden(detail?: string): ToolRefusal {\n return ToolRefusal.#coded('forbidden', detail);\n }\n\n /**\n * A value the tenant does not accept. `field` is a JSON Pointer into the\n * body (`/changes/address/postal_code`); `example` is a valid value the\n * agent offers when it asks again.\n */\n static invalidArgument(\n options: { field?: string; example?: string; detail?: string } = {},\n ): ToolRefusal {\n return new ToolRefusal({\n status: 422,\n code: 'invalid_argument',\n ...clip('detail', options.detail, 300),\n ...clip('field', options.field, 200),\n ...clip('example', options.example, 200),\n });\n }\n\n /** A temporary failure; a read is retried. */\n static unavailable(detail?: string): ToolRefusal {\n return ToolRefusal.#coded('unavailable', detail);\n }\n\n /** The delegated token is not valid (expired, revoked, unknown): a 401, which ends the session's tool access. */\n static tokenExpired(detail?: string): ToolRefusal {\n return ToolRefusal.#coded('token_expired', detail);\n }\n\n /** `get_flow_definition` with a `version` the tenant no longer accepts: `410 VERSION_GONE`. */\n static versionGone(detail?: string): ToolRefusal {\n return new ToolRefusal({\n status: 410,\n code: 'VERSION_GONE',\n ...clip('detail', detail, 300),\n });\n }\n\n /**\n * `submit_flow` refused: `422` with a flow code and the question to ask\n * again (none only for `VERSION_NOT_ACCEPTED`). Stored like an acceptance,\n * so the same submission gets the same refusal again.\n */\n static flowRefused(\n code: FlowRefusalCode,\n questionId?: string,\n detail?: string,\n ): ToolRefusal {\n if (code !== 'VERSION_NOT_ACCEPTED' && !questionId) {\n throw new TypeError(`a ${code} refusal names the question to ask again`);\n }\n return new ToolRefusal({\n status: 422,\n code,\n ...(questionId ? { question_id: questionId } : {}),\n ...clip('detail', detail, 300),\n });\n }\n\n static #coded(code: ProblemCode, detail?: string): ToolRefusal {\n return new ToolRefusal({\n status: STATUS[code],\n code,\n ...clip('detail', detail, 300),\n });\n }\n}\n\nfunction clip<K extends string>(\n key: K,\n value: string | undefined,\n max: number,\n): Partial<Record<K, string>> {\n if (value === undefined) return {};\n return { [key]: [...value].slice(0, max).join('') } as Partial<\n Record<K, string>\n >;\n}\n","// Tool-call signature v2, exactly as the Vinaverse API signs it and as its\n// reference verifier checks it in strict mode (contract: tool-provider-v1.yaml,\n// `vinaverseSignature`; API: vvcore.connectors.signature):\n// Vinaverse-Signature: t=<unix seconds>,n=<nonce>,v2=<hex>[,v2=<hex>][,v1=<hex>]\n// `v2` is the lowercase hex HMAC-SHA256, keyed with the tool signing secret as\n// UTF-8, over seven lines joined by \"\\n\" with no trailing line feed:\n// v2, t, n, the METHOD, the request target exactly as sent (path and query,\n// still percent-escaped), the hex SHA-256 of the whole delegated token, and\n// the hex SHA-256 of the body, or an empty line when there is no body.\n// A signature more than 300 seconds from now is refused, and so is a nonce\n// already taken. `v1` (sent during the transition) is ignored: it binds\n// neither the token nor a nonce.\nimport { hexToBytes, hmacKey, sha256Hex, utf8 } from '../internal/bytes.js';\nimport { subtleCrypto } from '../webhooks/crypto.js';\nimport { checkTolerance } from '../webhooks/verify.js';\nimport { NONCE_KEEP_SECONDS, type NonceStore } from './nonces.js';\n\nexport const TOOL_TOLERANCE_SECONDS = 300;\n\nconst T = /^[0-9]{1,12}$/;\nconst NONCE = /^[A-Za-z0-9_-]{16,64}$/;\nconst MAC = /^[0-9a-f]{64}$/;\n\n/**\n * Why a tool call's signature was refused, in the conformance vectors' words\n * (vinaverse-contracts `conformance/tool-calls.json`), checked in their order:\n * - `missing`: no `Vinaverse-Signature` header.\n * - `malformed`: no valid `t`, or no valid nonce (16 to 64 of `A-Z a-z 0-9 - _`).\n * - `stale`: signed more than 300 seconds from now, either way.\n * - `v2_required`: no `v2` (a v1-only header binds neither the token nor a nonce).\n * - `mismatch`: no `v2` matches with any secret: a wrong secret, or a method,\n * target, delegated token or body other than the ones signed.\n * - `replayed`: a valid signature whose nonce was already taken.\n */\nexport type ToolSignatureErrorCode =\n | 'missing'\n | 'malformed'\n | 'stale'\n | 'v2_required'\n | 'mismatch'\n | 'replayed';\n\nexport interface ToolSignatureError {\n readonly code: ToolSignatureErrorCode;\n readonly message: string;\n}\n\nexport interface ToolCallToVerify {\n /** The HTTP method. */\n method: string;\n /** The request target exactly as received: path and query, still percent-escaped. */\n target: string;\n /** The delegated token from the `Authorization: Bearer` header. */\n token: string;\n /** The body as received; `undefined`, `null` or empty for none. */\n body?: Uint8Array | null | undefined;\n /** The `Vinaverse-Signature` header. */\n header: string | null | undefined;\n}\n\nexport interface VerifyToolCallOptions {\n /** The tool signing secret, or two during a rotation. */\n secrets: readonly string[];\n nonces: NonceStore;\n now: Date;\n toleranceSeconds?: number;\n}\n\n/**\n * The fields the header carries. A repeated `t` or `n` makes the header\n * ambiguous, so it is refused (`repeated`), never resolved by order (VIN-154).\n */\nexport function parseToolSignature(header: string): {\n t: number | undefined;\n n: string | undefined;\n v2: string[];\n repeated: boolean;\n} {\n let t: number | undefined;\n let n: string | undefined;\n let seenT = 0;\n let seenN = 0;\n const v2: string[] = [];\n for (const part of header.split(',')) {\n const trimmed = part.trim();\n const at = trimmed.indexOf('=');\n const key = at < 0 ? trimmed : trimmed.slice(0, at);\n const value = at < 0 ? '' : trimmed.slice(at + 1);\n if (key === 't') {\n seenT++;\n if (T.test(value)) t = Number(value);\n } else if (key === 'n') {\n seenN++;\n n = value;\n } else if (key === 'v2' && MAC.test(value)) {\n v2.push(value);\n }\n }\n return { t, n, v2, repeated: seenT > 1 || seenN > 1 };\n}\n\n/** The string v2 signs. */\nexport async function toolSigningString(call: {\n t: number;\n n: string;\n method: string;\n target: string;\n token: string;\n body?: Uint8Array | null | undefined;\n}): Promise<Uint8Array<ArrayBuffer>> {\n const bodyHash =\n call.body && call.body.length > 0 ? await sha256Hex(call.body) : '';\n return utf8(\n [\n 'v2',\n String(call.t),\n call.n,\n call.method.toUpperCase(),\n call.target,\n await sha256Hex(utf8(call.token)),\n bodyHash,\n ].join('\\n'),\n );\n}\n\n/**\n * Checks a tool call's v2 signature and takes its nonce. Returns null when the\n * call is authentic and fresh. The nonce is claimed only after a signature\n * matched, so a forged header cannot burn a real call's nonce.\n */\nexport async function verifyToolCall(\n call: ToolCallToVerify,\n options: VerifyToolCallOptions,\n): Promise<ToolSignatureError | null> {\n if (!call.header) {\n return refusal('missing', 'no Vinaverse-Signature header');\n }\n const { t, n, v2, repeated } = parseToolSignature(call.header);\n if (repeated) {\n return refusal(\n 'malformed',\n 'the signature repeats t or n: an ambiguous header',\n );\n }\n if (t === undefined) {\n return refusal(\n 'malformed',\n 'the signature has no timestamp t=<unix seconds>',\n );\n }\n const now = Math.floor(options.now.getTime() / 1000);\n const tolerance =\n options.toleranceSeconds === undefined\n ? TOOL_TOLERANCE_SECONDS\n : checkTolerance(options.toleranceSeconds);\n if (Math.abs(now - t) > tolerance) {\n return refusal(\n 'stale',\n `the signature is ${Math.abs(now - t)} seconds from now; at most ${tolerance} are accepted`,\n );\n }\n if (v2.length === 0) {\n return refusal(\n 'v2_required',\n 'the signature has no v2 (a v1-only header binds neither the token nor a nonce)',\n );\n }\n if (n === undefined || !NONCE.test(n)) {\n return refusal(\n 'malformed',\n 'the signature has no valid nonce n (16 to 64 of A-Z a-z 0-9 - _)',\n );\n }\n const message = await toolSigningString({ ...call, t, n });\n const subtle = await subtleCrypto();\n let matched = false;\n for (const secret of options.secrets) {\n const key = await hmacKey(secret, 'verify');\n for (const mac of v2) {\n if (await subtle.verify('HMAC', key, hexToBytes(mac), message)) {\n matched = true;\n break;\n }\n }\n if (matched) break;\n }\n if (!matched) {\n return refusal(\n 'mismatch',\n 'no v2 signature matches: check the tool signing secret, and verify the method, target, token and body exactly as received',\n );\n }\n if (!(await options.nonces.claim(n, Math.max(t, now) + NONCE_KEEP_SECONDS))) {\n return refusal('replayed', 'this nonce was already used: a replayed call');\n }\n return null;\n}\n\nfunction refusal(\n code: ToolSignatureErrorCode,\n message: string,\n): ToolSignatureError {\n return { code, message };\n}\n","// The tool provider: a tenant's tool endpoints with the contract enforced\n// around its handlers (contract: tool-provider-v1.yaml). For each call, in\n// order:\n// 1. the body is at most `maxRequestBytes`;\n// 2. a bearer token is present (else 401 token_expired);\n// 3. the signature v2 is valid and its nonce unused (else 403 forbidden);\n// 4. the route is one the contract defines and the tenant serves (else 404);\n// 5. the tenant's `authenticate` resolves the token to its principal;\n// 6. path and query parameters are read and typed, the JSON body parsed;\n// 7. calls that change something are made idempotent: `submit_flow` by its\n// `submission_id`, `create_proposal` by its key and canonical\n// `{topic, changes}`, the others with a required `Idempotency-Key` by the\n// key and the canonical body (stored as a SHA-256 fingerprint, never the\n// body); each run holds its key with a lease only it can store over or\n// release;\n// 8. the handler runs; a `ToolRefusal` becomes the contract's problem; any\n// other error is a 500 `unavailable` reported to `onError`;\n// 9. the result is at most the operation's limit (16 KB, the flow definition\n// 128 KB), else a 500 reported to `onError`, since the runtime would\n// refuse it anyway.\n\nimport {\n TOOL_OPERATIONS,\n type ToolOperationId,\n} from '../generated/tool-operations.js';\nimport type { operations } from '../generated/tool-provider-v1.js';\nimport { toBytes } from '../internal/bytes.js';\nimport { webCrypto } from '../webhooks/crypto.js';\nimport { checkTolerance } from '../webhooks/verify.js';\nimport {\n fingerprint,\n type IdempotencyRecord,\n type IdempotencyStore,\n} from './idempotency.js';\nimport type { NonceStore } from './nonces.js';\nimport { isFlowRefusal, type ProblemBody, ToolRefusal } from './refusals.js';\nimport { type ToolSignatureErrorCode, verifyToolCall } from './signature.js';\n\nexport type { ToolOperationId } from '../generated/tool-operations.js';\n\ntype Op<K extends ToolOperationId> = operations[K];\n\ntype ParamsOf<K extends ToolOperationId, Where extends string> =\n Op<K>['parameters'] extends Record<Where, infer P>\n ? [P] extends [never | undefined]\n ? Record<string, never>\n : NonNullable<P>\n : Record<string, never>;\n\n/** A tool's request body, as the contract types it. */\nexport type ToolBody<K extends ToolOperationId> =\n Op<K> extends {\n requestBody: { content: { 'application/json': infer B } };\n }\n ? B\n : Op<K> extends {\n requestBody?: { content: { 'application/json': infer B } };\n }\n ? B | undefined\n : undefined;\n\ntype SuccessOf<R> = R extends { 200: infer S }\n ? S\n : R extends { 201: infer S }\n ? S\n : never;\n\n/** A tool's success result, as the contract types it. */\nexport type ToolResult<K extends ToolOperationId> =\n SuccessOf<Op<K>['responses']> extends {\n content: { 'application/json': infer B };\n }\n ? B\n : never;\n\n/** What a handler receives. */\nexport interface ToolCall<K extends ToolOperationId, P> {\n readonly operation: K;\n /** What `authenticate` returned for the delegated token. */\n readonly principal: P;\n /** The session's delegated token (verified as signed; its meaning is the tenant's). */\n readonly token: string;\n readonly params: ParamsOf<K, 'path'>;\n readonly query: ParamsOf<K, 'query'>;\n readonly body: ToolBody<K>;\n /** The informational headers Vinaverse sends (not signed). */\n readonly session: {\n readonly id?: string;\n readonly conversationId?: string;\n readonly toolCallId?: string;\n readonly requestId?: string;\n };\n readonly idempotencyKey?: string;\n}\n\n/**\n * A handler per served operation; one the tenant does not serve answers 404.\n * Handlers validate what they act on: the toolkit checks the call's origin and\n * shape, not the meaning of its values. A `submit_flow` handler refuses only\n * with `ToolRefusal.flowRefused` (the contract's `FlowSubmissionRefusal`); any\n * other 422 from it is answered as a 500 and reported to `onError`.\n */\nexport type ToolHandlers<P> = {\n [K in ToolOperationId]?: (\n call: ToolCall<K, P>,\n ) => K extends 'submit_flow'\n ? Accepting\n : Promise<ToolResult<K>> | ToolResult<K>;\n};\n\n// A submission handler that accepts may return nothing: `{ ok: true }` is sent.\ntype Accepted = ToolResult<'submit_flow'>;\n// biome-ignore lint/suspicious/noConfusingVoidType: an accepting handler returns nothing\ntype Accepting = Promise<void | Accepted> | void | Accepted;\n\nexport interface ToolProviderOptions<P> {\n /** The tool signing secret, or two during a rotation. */\n secret: string | readonly string[];\n /** Where nonces are taken: shared by every instance (`@vinaverse/server/stores`). */\n nonces: NonceStore;\n /** Where idempotent answers are kept: shared by every instance. */\n idempotency: IdempotencyStore;\n /**\n * The path of the tool base URL registered in Studio (`/api/v2/ai` for\n * `https://tenant.example.com/api/v2/ai`); routes are matched below it.\n */\n basePath?: string;\n /**\n * Resolves the delegated token to the tenant's principal (the person and\n * what the token lets them do). Throw `ToolRefusal.tokenExpired()` for a\n * token that is not valid.\n */\n authenticate(token: string, operation: ToolOperationId): Promise<P> | P;\n handlers: ToolHandlers<P>;\n /**\n * For `create_proposal`: the stored proposal's current state, read again on\n * a replay (the contract returns its current `status`). Default: as stored.\n */\n currentProposal?(\n stored: ToolResult<'create_proposal'>,\n principal: P,\n ): Promise<ToolResult<'create_proposal'>> | ToolResult<'create_proposal'>;\n /**\n * An error the toolkit answered with a 500 (a handler's, a result over its\n * limit, a refusal the contract does not allow), or one it worked around (an\n * answer it could not store).\n */\n onError?(error: unknown, operation: ToolOperationId | undefined): void;\n /**\n * A call whose signature was refused, with the reason (`stale`, `mismatch`,\n * `replayed`, …): the 403 itself says only that the signature was refused.\n */\n onRefused?(reason: ToolSignatureErrorCode, message: string): void;\n /**\n * Scopes idempotent answers, for example to the tenant or environment of the\n * principal: a stored answer is replayed only to a call with the same scope.\n */\n scope?(principal: P, operation: ToolOperationId): string;\n /**\n * How long a running call holds its idempotency key, in seconds; default 60.\n * Set it above the longest your handlers can run: a resend after it lapses\n * runs the handler again.\n */\n leaseSeconds?: number;\n /** The largest request body accepted, in bytes; default 1 MiB. */\n maxRequestBytes?: number;\n toleranceSeconds?: number;\n now?: () => Date;\n}\n\nexport interface ToolRequest {\n method: string;\n /** The request target exactly as received: path and query, percent-escaped. */\n target: string;\n /** Header lookup by name, any case. */\n header(name: string): string | undefined;\n body: string | Uint8Array | ArrayBuffer | null | undefined;\n}\n\nexport interface ToolResponse {\n readonly status: number;\n readonly headers: Readonly<Record<string, string>>;\n readonly body: string;\n}\n\n/** The result of a submission that a handler accepted. */\nconst ACCEPTED = { ok: true } as const;\n\n/** How long idempotent answers are kept (seconds), and a pending call holds its key. */\nexport const KEEP_SECONDS = {\n submit_flow: 31 * 86_400, // a conversation lives up to 30 days, and a submission is resent in later sessions\n create_proposal: 8 * 86_400, // at least until the proposal expires (at most 7 days)\n default: 86_400,\n pending: 60,\n} as const;\n\n/** The longest `Idempotency-Key` the contract allows. */\nconst MAX_IDEMPOTENCY_KEY = 255;\n\nexport const MAX_REQUEST_BYTES = 1024 * 1024;\n\n/** A run's idempotency lease lapsed and another run took the key: its answer was sent but not stored. */\nexport class LeaseLostError extends Error {\n constructor(operation: ToolOperationId, leaseSeconds: number) {\n super(\n `${operation} ran longer than its ${leaseSeconds}-second idempotency lease and another call took the key: the answer was sent but not stored (raise leaseSeconds)`,\n );\n this.name = 'LeaseLostError';\n }\n}\n\nexport class ResultTooLargeError extends Error {\n constructor(operation: ToolOperationId, bytes: number, limit: number) {\n super(\n `${operation} returned ${bytes} bytes; the contract allows ${limit}: the runtime would refuse it`,\n );\n this.name = 'ResultTooLargeError';\n }\n}\n\ninterface Route {\n id: ToolOperationId;\n segments: readonly string[];\n}\n\nexport interface ToolProvider {\n handle(request: ToolRequest): Promise<ToolResponse>;\n}\n\nexport function createToolProvider<P>(\n options: ToolProviderOptions<P>,\n): ToolProvider {\n const secrets =\n typeof options.secret === 'string' ? [options.secret] : [...options.secret];\n if (\n secrets.length === 0 ||\n secrets.some((s) => typeof s !== 'string' || !s)\n ) {\n throw new TypeError('createToolProvider needs the tool signing secret');\n }\n checkTolerance(options.toleranceSeconds);\n const maxRequest = options.maxRequestBytes;\n if (\n maxRequest !== undefined &&\n (!Number.isSafeInteger(maxRequest) || maxRequest <= 0)\n ) {\n throw new TypeError(\n `maxRequestBytes must be a positive whole number of bytes, not ${maxRequest}`,\n );\n }\n const lease = options.leaseSeconds ?? KEEP_SECONDS.pending;\n if (!Number.isFinite(lease) || lease <= 0) {\n throw new TypeError(\n `leaseSeconds must be a positive number of seconds, not ${options.leaseSeconds}`,\n );\n }\n if (typeof options.authenticate !== 'function') {\n throw new TypeError(\n 'createToolProvider needs authenticate: it resolves the delegated token',\n );\n }\n const base = (options.basePath ?? '').replace(/\\/+$/, '');\n const routes: Route[] = Object.values(TOOL_OPERATIONS).map((o) => ({\n id: o.id,\n segments: o.path.split('/').filter(Boolean),\n }));\n\n async function handle(request: ToolRequest): Promise<ToolResponse> {\n const raw = request.body ?? new Uint8Array(0);\n const body = toBytes(raw);\n if (body.length > (options.maxRequestBytes ?? MAX_REQUEST_BYTES)) {\n return problem({\n status: 413,\n code: 'invalid_argument',\n detail: 'the request body is too large',\n });\n }\n const token = bearer(request.header('authorization'));\n if (!token) {\n return problem({\n status: 401,\n code: 'token_expired',\n detail: 'no delegated token (Authorization: Bearer)',\n });\n }\n const refused = await verifyToolCall(\n {\n method: request.method,\n target: request.target,\n token,\n body,\n header: request.header('vinaverse-signature'),\n },\n {\n secrets,\n nonces: options.nonces,\n now: options.now?.() ?? new Date(),\n ...(options.toleranceSeconds === undefined\n ? {}\n : { toleranceSeconds: options.toleranceSeconds }),\n },\n );\n if (refused) {\n options.onRefused?.(refused.code, refused.message);\n return problem({\n status: 403,\n code: 'forbidden',\n detail: 'the signature was refused',\n });\n }\n const matched = match(request.method, request.target);\n if (!matched)\n return problem({\n status: 404,\n code: 'not_found',\n detail: 'no such tool',\n });\n const { id, params, query } = matched;\n const operation = TOOL_OPERATIONS[id];\n const handler = options.handlers[id] as\n | ((call: ToolCall<ToolOperationId, P>) => unknown)\n | undefined;\n if (!handler)\n return problem({\n status: 404,\n code: 'not_found',\n detail: `${id} is not served here`,\n });\n try {\n const principal = await options.authenticate(token, id);\n const typedQuery = readQuery(id, query);\n const parsed = operation.body ? parseBody(body) : undefined;\n const key = request.header('idempotency-key');\n if (operation.idempotencyKey && !key) {\n throw ToolRefusal.invalidArgument({\n detail: 'the Idempotency-Key header is required',\n });\n }\n if (key && key.length > MAX_IDEMPOTENCY_KEY) {\n throw ToolRefusal.invalidArgument({\n detail: `the Idempotency-Key is longer than ${MAX_IDEMPOTENCY_KEY} characters`,\n });\n }\n const call: ToolCall<ToolOperationId, P> = {\n operation: id,\n principal,\n token,\n params: params as never,\n query: typedQuery as never,\n body: parsed as never,\n session: session(request),\n ...(key ? { idempotencyKey: key } : {}),\n };\n const run = () => runHandler(id, handler, call);\n const scope = options.scope?.(principal, id);\n const keyOf = (...parts: string[]) =>\n (scope === undefined ? parts : [scope, ...parts])\n .map(encodeURIComponent)\n .join(':');\n if (id === 'submit_flow')\n return await submission(keyOf, params, parsed, run);\n if (id === 'create_proposal' && key)\n return await proposal(keyOf(id, key), parsed, principal, run);\n if (operation.idempotencyKey && key) {\n return await keyed(\n id,\n keyOf(id, key),\n await fingerprint(parsed),\n KEEP_SECONDS.default,\n run,\n () =>\n problem({\n status: 409,\n code: 'IDEMPOTENCY_KEY_REUSED',\n detail: 'this Idempotency-Key was used with another body',\n }),\n );\n }\n return await run();\n } catch (error) {\n return failure(error, id);\n }\n }\n\n async function runHandler(\n id: ToolOperationId,\n handler: (call: ToolCall<ToolOperationId, P>) => unknown,\n call: ToolCall<ToolOperationId, P>,\n ): Promise<ToolResponse> {\n const result =\n (await handler(call)) ?? (id === 'submit_flow' ? ACCEPTED : undefined);\n if (result === undefined) {\n throw new TypeError(`the ${id} handler returned nothing`);\n }\n const text = JSON.stringify(result);\n const limit = TOOL_OPERATIONS[id].maxResultBytes;\n const bytes = toBytes(text).length;\n if (bytes > limit) throw new ResultTooLargeError(id, bytes, limit);\n return json(TOOL_OPERATIONS[id].successStatus, text);\n }\n\n // The answer for an idempotent call: run once per key, then the stored\n // answer for the same fingerprint, a conflict for another. A success and the\n // refusals `keeps` accepts (by default a 422: an invalid argument, the call's\n // outcome) are kept; any other failure releases the key so a retry runs\n // again. The run holds the key with a lease tied to it (`owner`): it can\n // neither store over nor release a lease another run took after it lapsed.\n async function keyed(\n id: ToolOperationId,\n key: string,\n print: string,\n keepSeconds: number,\n run: () => Promise<ToolResponse>,\n conflict: (held: IdempotencyRecord) => ToolResponse | Promise<ToolResponse>,\n replay?: (held: IdempotencyRecord) => ToolResponse | Promise<ToolResponse>,\n keeps: (refusal: ToolRefusal) => boolean = (r) => r.status === 422,\n ): Promise<ToolResponse> {\n const store = options.idempotency;\n const owner = await ownerToken();\n const held = await store.start(key, print, lease, owner);\n if (held) {\n if (held.state === 'pending') {\n return problem({\n status: 503,\n code: 'unavailable',\n detail: 'the same call is still running',\n });\n }\n if (held.fingerprint !== print) return conflict(held);\n return replay ? replay(held) : stored(held);\n }\n let response: ToolResponse;\n try {\n response = await run();\n } catch (error) {\n if (!(error instanceof ToolRefusal && keeps(error))) {\n await store.release(key, owner);\n throw error;\n }\n response = problem(error.problem);\n }\n // The answer stands whether or not it is stored: the work is done.\n try {\n const kept = await store.finish(\n key,\n { fingerprint: print, status: response.status, body: response.body },\n keepSeconds,\n owner,\n );\n if (!kept) options.onError?.(new LeaseLostError(id, lease), id);\n } catch (error) {\n options.onError?.(error, id);\n }\n return response;\n }\n\n async function submission(\n keyOf: (...parts: string[]) => string,\n params: Record<string, string>,\n body: unknown,\n run: () => Promise<ToolResponse>,\n ): Promise<ToolResponse> {\n const submissionId = (body as { submission_id?: unknown } | undefined)\n ?.submission_id;\n if (typeof submissionId !== 'string' || submissionId === '') {\n throw ToolRefusal.invalidArgument({\n field: '/submission_id',\n detail: 'a submission needs its submission_id',\n });\n }\n // Only a FlowSubmissionRefusal is a submission's outcome to keep; any other\n // 422 is a handler's mistake the contract has no shape for.\n const refused = async () => {\n try {\n return await run();\n } catch (error) {\n if (\n error instanceof ToolRefusal &&\n error.status === 422 &&\n !isFlowRefusal(error.problem)\n ) {\n throw new TypeError(\n `submit_flow refused with ${error.problem.code}: a submission is refused only with ToolRefusal.flowRefused (a flow code and the question to ask again)`,\n );\n }\n throw error;\n }\n };\n return keyed(\n 'submit_flow',\n keyOf('submit_flow', params.flow ?? '', submissionId),\n await fingerprint(body),\n KEEP_SECONDS.submit_flow,\n refused,\n (held) => {\n const was = held.body\n ? (JSON.parse(held.body) as Partial<ProblemBody>)\n : {};\n const storedResult =\n held.status === 200\n ? { result: 'accepted' }\n : {\n result: 'refused',\n ...(was.code ? { code: was.code } : {}),\n ...(was.question_id ? { question_id: was.question_id } : {}),\n };\n return json(\n 409,\n JSON.stringify({\n status: 409,\n code: 'SUBMISSION_ID_REUSED',\n stored: storedResult,\n }),\n 'application/problem+json',\n );\n },\n undefined,\n (r) => isFlowRefusal(r.problem),\n );\n }\n\n async function proposal(\n key: string,\n body: unknown,\n principal: P,\n run: () => Promise<ToolResponse>,\n ): Promise<ToolResponse> {\n const { topic, changes } = (body ?? {}) as {\n topic?: unknown;\n changes?: unknown;\n };\n const current = async (held: IdempotencyRecord) => {\n const storedProposal = JSON.parse(\n held.body ?? 'null',\n ) as ToolResult<'create_proposal'>;\n return options.currentProposal\n ? await options.currentProposal(storedProposal, principal)\n : storedProposal;\n };\n return keyed(\n 'create_proposal',\n key,\n await fingerprint({ topic, changes }),\n KEEP_SECONDS.create_proposal,\n run,\n async (held) =>\n held.status === 201\n ? json(\n 409,\n JSON.stringify({\n status: 409,\n code: 'IDEMPOTENCY_KEY_REUSED',\n proposal: await current(held),\n }),\n 'application/problem+json',\n )\n : stored(held),\n async (held) =>\n held.status === 201\n ? json(201, JSON.stringify(await current(held)))\n : stored(held),\n );\n }\n\n function match(\n method: string,\n target: string,\n ):\n | {\n id: ToolOperationId;\n params: Record<string, string>;\n query: URLSearchParams;\n }\n | undefined {\n const at = target.indexOf('?');\n const path = at < 0 ? target : target.slice(0, at);\n const query = new URLSearchParams(at < 0 ? '' : target.slice(at + 1));\n if (base && path !== base && !path.startsWith(`${base}/`)) return undefined;\n const segments = path.slice(base.length).split('/').filter(Boolean);\n for (const route of routes) {\n if (TOOL_OPERATIONS[route.id].method !== method.toUpperCase()) continue;\n if (route.segments.length !== segments.length) continue;\n const params: Record<string, string> = {};\n let ok = true;\n for (const [i, part] of route.segments.entries()) {\n const actual = segments[i] as string;\n if (part.startsWith('{') && part.endsWith('}')) {\n try {\n params[part.slice(1, -1)] = decodeURIComponent(actual);\n } catch {\n ok = false;\n }\n } else if (part !== actual) {\n ok = false;\n }\n if (!ok) break;\n }\n if (ok) return { id: route.id, params, query };\n }\n return undefined;\n }\n\n function failure(\n error: unknown,\n id: ToolOperationId | undefined,\n ): ToolResponse {\n if (error instanceof ToolRefusal) return problem(error.problem);\n options.onError?.(error, id);\n return problem({\n status: 500,\n code: 'unavailable',\n detail: 'the tool failed',\n });\n }\n\n return { handle };\n}\n\nfunction readQuery(\n id: ToolOperationId,\n query: URLSearchParams,\n): Record<string, unknown> {\n const declared = TOOL_OPERATIONS[id].queryParams as Record<\n string,\n { type: string; required: boolean }\n >;\n const out: Record<string, unknown> = {};\n for (const [name, spec] of Object.entries(declared)) {\n const value = query.get(name);\n if (value === null) {\n if (spec.required)\n throw ToolRefusal.invalidArgument({\n detail: `the query parameter ${name} is required`,\n });\n continue;\n }\n if (spec.type === 'integer' || spec.type === 'number') {\n const n = Number(value);\n if (\n value.trim() === '' ||\n !Number.isFinite(n) ||\n (spec.type === 'integer' && !Number.isInteger(n))\n ) {\n throw ToolRefusal.invalidArgument({\n detail: `the query parameter ${name} must be ${spec.type === 'integer' ? 'an integer' : 'a number'}`,\n });\n }\n out[name] = n;\n } else {\n out[name] = value;\n }\n }\n return out;\n}\n\nfunction parseBody(body: Uint8Array): unknown {\n if (body.length === 0)\n throw ToolRefusal.invalidArgument({\n detail: 'the request needs a JSON body',\n });\n try {\n return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(body));\n } catch {\n throw ToolRefusal.invalidArgument({\n detail: 'the request body is not JSON',\n });\n }\n}\n\nfunction bearer(value: string | undefined): string | undefined {\n const m = /^Bearer\\s+(\\S+)\\s*$/i.exec(value ?? '');\n return m?.[1];\n}\n\nfunction session(\n request: ToolRequest,\n): ToolCall<ToolOperationId, unknown>['session'] {\n const pick = (name: string) => request.header(name);\n const entries = {\n id: pick('vinaverse-session') ?? pick('vinaverse-session-id'),\n conversationId: pick('vinaverse-conversation'),\n toolCallId: pick('vinaverse-tool-call-id'),\n requestId: pick('vinaverse-request-id'),\n };\n return Object.fromEntries(\n Object.entries(entries).filter(([, v]) => v !== undefined),\n );\n}\n\n/** A random token tying an idempotency lease to the run that holds it. */\nasync function ownerToken(): Promise<string> {\n const bytes = (await webCrypto()).getRandomValues(new Uint8Array(16));\n return [...bytes].map((b) => b.toString(16).padStart(2, '0')).join('');\n}\n\nfunction json(\n status: number,\n body: string,\n type = 'application/json',\n): ToolResponse {\n return { status, headers: { 'content-type': type }, body };\n}\n\nfunction problem(body: ProblemBody): ToolResponse {\n return json(body.status, JSON.stringify(body), 'application/problem+json');\n}\n\nfunction stored(held: IdempotencyRecord): ToolResponse {\n const status = held.status ?? 200;\n return json(\n status,\n held.body ?? '',\n status >= 400 ? 'application/problem+json' : 'application/json',\n );\n}\n","// The ordering rule for conversation states (contract:\n// docs/conversation-state.md §3 and §4; vectors: vinaverse-contracts\n// conformance/webhook-sequence.json, whose words these are). Deliveries are at\n// least once and in no set order:\n// - deduplicate on the envelope's `id` (`duplicate`);\n// - keep, per conversation, the state with the highest `sequence`; one with an\n// equal or lower `sequence` is old news (`stale`), even under a new envelope id;\n// - a gap means deliveries still to come: apply the higher state anyway, the\n// missing ones then arrive stale;\n// - a state with `answers_omitted: true` updates every other field and keeps\n// the `answers` and `remarks` held; read the full state afterwards\n// (`GET /v1/conversations/{conversation_id}`);\n// - a Studio test delivery (`data.test: true`) carries no state (`skip_test`).\n//\n// The pure functions work on a record the tenant stores per conversation;\n// `ConversationReceiver` keeps the records and the ids in memory, for one\n// process and for tests.\nimport type { ConversationEvent } from './events.js';\n\n/** The fields of a conversation state the rule reads. */\nexport interface SequencedState {\n readonly conversation_id: string;\n readonly sequence: number;\n readonly answers_omitted?: boolean;\n readonly answers?: unknown;\n readonly remarks?: unknown;\n}\n\n/** What a tenant keeps per conversation: the state held, and what it knows about the deliveries. */\nexport interface ConversationRecord<S extends SequencedState = SequencedState> {\n /** The newest state, with the answers and remarks merged in when a delivery left them out. */\n readonly state: S;\n /** Every `sequence` a delivery carried for this conversation, ascending. */\n readonly seen: readonly number[];\n /** The last applied state left out its answers: read the full state. */\n readonly fullReadNeeded: boolean;\n}\n\nexport type SequenceAction = 'apply' | 'stale';\nexport type DeliveryAction = SequenceAction | 'duplicate' | 'skip_test';\n\n/** Apply a state only above the one held: an equal or lower `sequence` is stale. */\nexport function sequenceVerdict(\n held: Pick<SequencedState, 'conversation_id' | 'sequence'> | null | undefined,\n incoming: Pick<SequencedState, 'conversation_id' | 'sequence'>,\n): SequenceAction {\n if (held && held.conversation_id !== incoming.conversation_id) {\n throw new TypeError(\n `the states belong to different conversations (${held.conversation_id}, ${incoming.conversation_id})`,\n );\n }\n return held && incoming.sequence <= held.sequence ? 'stale' : 'apply';\n}\n\n/**\n * Applies one conversation state to the record held for its conversation (or\n * none) and returns the record to keep and what happened. A stale state\n * changes nothing but `seen`. An applied state with `answers_omitted: true` is\n * kept without that flag, with the `answers` and `remarks` held (or none), and\n * `fullReadNeeded` set.\n */\nexport function applyConversationState<S extends SequencedState>(\n record: ConversationRecord<S> | null | undefined,\n incoming: S,\n): { record: ConversationRecord<S>; action: SequenceAction } {\n const action = sequenceVerdict(record?.state, incoming);\n const seen = record?.seen.includes(incoming.sequence)\n ? record.seen\n : [...(record?.seen ?? []), incoming.sequence].sort((a, b) => a - b);\n if (action === 'stale' && record)\n return { record: { ...record, seen }, action };\n if (incoming.answers_omitted === true) {\n const { answers_omitted: _omitted, ...rest } = incoming;\n const state = {\n ...rest,\n answers: record?.state.answers ?? [],\n remarks: record?.state.remarks ?? {},\n } as unknown as S;\n return { record: { state, seen, fullReadNeeded: true }, action };\n }\n return { record: { state: incoming, seen, fullReadNeeded: false }, action };\n}\n\n/**\n * The sequences still to come for a conversation: above the lowest one a\n * delivery carried and below the one held, that no delivery has carried yet.\n * Wait for them, or read the full state.\n */\nexport function missingSequences(record: ConversationRecord): number[] {\n const [lowest] = record.seen;\n if (lowest === undefined) return [];\n const missing: number[] = [];\n for (let s = lowest + 1; s < record.state.sequence; s++) {\n if (!record.seen.includes(s)) missing.push(s);\n }\n return missing;\n}\n\ntype ConversationData = ConversationEvent['data'];\n\n/**\n * The rule over a stream of verified deliveries, in memory: envelope ids seen,\n * and a record per conversation. For one process and for tests; a tenant\n * behind several instances keeps the ids and the records in its database and\n * calls `applyConversationState` itself.\n */\nexport class ConversationReceiver {\n readonly #ids = new Set<string>();\n readonly #records = new Map<string, ConversationRecord<ConversationData>>();\n\n /**\n * One verified delivery (an event, or a Studio test delivery's envelope):\n * what to do with it. The record for its conversation is then `record(id)`.\n */\n receive(delivery: {\n readonly id: string;\n readonly data: unknown;\n }): DeliveryAction {\n if (this.#ids.has(delivery.id)) return 'duplicate';\n this.#ids.add(delivery.id);\n const data = delivery.data as {\n test?: unknown;\n conversation_id?: unknown;\n } | null;\n if (data?.test === true) return 'skip_test';\n if (typeof data?.conversation_id !== 'string') {\n throw new TypeError(`${delivery.id} carries no conversation state`);\n }\n const state = data as ConversationData;\n const { record, action } = applyConversationState(\n this.#records.get(state.conversation_id),\n state,\n );\n this.#records.set(state.conversation_id, record);\n return action;\n }\n\n record(\n conversationId: string,\n ): ConversationRecord<ConversationData> | undefined {\n return this.#records.get(conversationId);\n }\n\n conversations(): string[] {\n return [...this.#records.keys()].sort();\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/webhooks/crypto.ts","../src/internal/bytes.ts","../src/webhooks/errors.ts","../src/webhooks/events.ts","../src/webhooks/signature.ts","../src/webhooks/verify.ts","../src/adapters/handler.ts","../src/adapters/fetch.ts","../src/contract.ts","../src/generated/tool-operations.ts","../src/tools/idempotency.ts","../src/tools/nonces.ts","../src/tools/refusals.ts","../src/tools/signature.ts","../src/tools/provider.ts","../src/webhooks/sequence.ts"],"names":["fingerprint","until","problem"],"mappings":"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","file":"index.cjs","sourcesContent":["// Web Crypto wherever the package runs. Node 20+, AWS Lambda, edge runtimes\n// and React Native expose it as `globalThis.crypto`; Node 18 has the same API\n// but only as `webcrypto` in its crypto module, so on Node 18 it is loaded\n// from there, once.\n\n/** No Web Crypto in this runtime: the package cannot verify anything here. */\nexport class WebCryptoUnavailableError extends Error {\n constructor() {\n super(\n 'Web Crypto (crypto.subtle) is not available in this runtime; @vinaverse/server needs Node 18+, an edge runtime or another runtime with Web Crypto',\n );\n this.name = 'WebCryptoUnavailableError';\n }\n}\n\ntype MaybeNode = { process?: { versions?: { node?: unknown } } };\n\nlet fromNode: Promise<Crypto> | undefined;\n\n/** The runtime's Web Crypto: `crypto.subtle` and `crypto.getRandomValues`. */\nexport function webCrypto(): Promise<Crypto> {\n const global = (globalThis as { crypto?: Crypto }).crypto;\n if (global?.subtle) return Promise.resolve(global);\n fromNode ??= nodeWebCrypto();\n return fromNode;\n}\n\nexport async function subtleCrypto(): Promise<SubtleCrypto> {\n return (await webCrypto()).subtle;\n}\n\nasync function nodeWebCrypto(): Promise<Crypto> {\n if (typeof (globalThis as MaybeNode).process?.versions?.node !== 'string') {\n throw new WebCryptoUnavailableError();\n }\n // Built at run time on purpose: bundlers for edge runtimes and React Native,\n // where this line never runs, must not try to resolve a Node module.\n const specifier = ['node', 'crypto'].join(':');\n const mod = (await import(\n /* webpackIgnore: true */ /* @vite-ignore */ specifier\n )) as { webcrypto?: Crypto };\n if (!mod.webcrypto?.subtle) throw new WebCryptoUnavailableError();\n return mod.webcrypto;\n}\n","// Byte helpers on Web APIs only (no Buffer), shared by the signature checks.\nimport { subtleCrypto } from '../webhooks/crypto.js';\n\nconst encoder = new TextEncoder();\n\nexport function utf8(text: string): Uint8Array<ArrayBuffer> {\n return encoder.encode(text);\n}\n\nexport function toBytes(body: string | Uint8Array | ArrayBuffer): Uint8Array {\n if (typeof body === 'string') return utf8(body);\n if (body instanceof Uint8Array) return body;\n return new Uint8Array(body);\n}\n\nexport function hexToBytes(hex: string): Uint8Array<ArrayBuffer> {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n\nexport async function sha256Hex(data: Uint8Array): Promise<string> {\n const subtle = await subtleCrypto();\n return bytesToHex(new Uint8Array(await subtle.digest('SHA-256', copy(data))));\n}\n\nexport async function hmacKey(\n secret: string,\n usage: 'sign' | 'verify',\n): Promise<CryptoKey> {\n const subtle = await subtleCrypto();\n return subtle.importKey(\n 'raw',\n utf8(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n [usage],\n );\n}\n\n// Web Crypto takes an ArrayBuffer-backed view; a Node Buffer may sit on a\n// shared pool, so a view is copied when it does not own its whole buffer.\nexport function copy(data: Uint8Array): Uint8Array<ArrayBuffer> {\n const out = new Uint8Array(data.length);\n out.set(data);\n return out;\n}\n\nexport function concat(...parts: Uint8Array[]): Uint8Array<ArrayBuffer> {\n const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));\n let at = 0;\n for (const p of parts) {\n out.set(p, at);\n at += p.length;\n }\n return out;\n}\n","/**\n * Why a delivery was refused, in the conformance vectors' words\n * (vinaverse-contracts `conformance/webhooks.json`). Every one is answered with\n * `400`, so Vinaverse retries it; none of them is ever a valid delivery.\n *\n * - `missing`: no `Vinaverse-Signature` header.\n * - `malformed`: the header is not `t=<unix seconds>,v1=<hex>[,v1=<hex>]`\n * (no single timestamp, or no `v1` signature).\n * - `stale`: signed more than the tolerance (300 seconds) before or after now:\n * a replay, or a clock far off.\n * - `mismatch`: no `v1` signature matches the body with any secret: a wrong\n * secret (or the secret without its `vv_whsec_` prefix), a changed body, or a\n * body parsed and serialized again.\n * - `invalid_body`: signed by Vinaverse, but not a webhook envelope this\n * package can read.\n */\nexport type WebhookErrorCode =\n | 'missing'\n | 'malformed'\n | 'stale'\n | 'mismatch'\n | 'invalid_body';\n\nexport interface WebhookError {\n readonly code: WebhookErrorCode;\n readonly message: string;\n}\n\nexport function webhookError(\n code: WebhookErrorCode,\n message: string,\n): WebhookError {\n return { code, message };\n}\n","// The webhook events, typed from the pinned contract (vinaverse-v1.yaml,\n// `webhooks`), and the reading of a verified body into one of them.\nimport type { components, webhooks } from '../generated/vinaverse-v1.js';\nimport { type WebhookError, webhookError } from './errors.js';\n\ntype Schemas = components['schemas'];\n\n/** The envelope every webhook body has. `data` depends on `type`. */\nexport type WebhookEnvelope = Schemas['WebhookEnvelope'];\n\n/** Every event type the targeted contract defines. */\nexport type WebhookEventType = WebhookEnvelope['type'] & keyof webhooks;\n\ntype BodyOf<T extends WebhookEventType> = NonNullable<\n webhooks[T]['post']['requestBody']\n>['content']['application/json'];\n\n/** One event of type `T`: the envelope, with `data` as the contract says. */\nexport type WebhookEventOf<T extends WebhookEventType> = Omit<\n WebhookEnvelope,\n 'type' | 'data'\n> & {\n type: T;\n data: NonNullable<BodyOf<T>['data']>;\n};\n\n/** Any event this package version knows; narrow it on `type`. */\nexport type WebhookEvent = {\n [T in WebhookEventType]: WebhookEventOf<T>;\n}[WebhookEventType];\n\nexport type ConversationEventType =\n | 'conversation.updated'\n | 'conversation.completed'\n | 'conversation.failed'\n | 'conversation.expired';\n\n/** A guided-flow conversation's state changed: `data` is its `ConversationState`. */\nexport type ConversationEvent = {\n [T in ConversationEventType]: WebhookEventOf<T>;\n}[ConversationEventType];\n\nexport type ConversationState = Schemas['ConversationState'];\n\n// Kept in step with the contract by a test that reads the pinned YAML.\nexport const WEBHOOK_EVENT_TYPES: readonly WebhookEventType[] = [\n 'moderation.item.completed',\n 'moderation.job.completed',\n 'document_check.completed',\n 'session.completed',\n 'subject.erased',\n 'usage.threshold_reached',\n 'feature.state_changed',\n 'media.job.queued',\n 'media.job.progress',\n 'media.job.step.completed',\n 'media.job.completed',\n 'media.job.failed',\n 'media.job.cancelled',\n 'conversation.updated',\n 'conversation.completed',\n 'conversation.failed',\n 'conversation.expired',\n];\n\nconst KNOWN = new Set<string>(WEBHOOK_EVENT_TYPES);\n\n// The statuses each conversation event may carry (vinaverse-v1.yaml, webhooks).\nconst CONVERSATION_STATUSES: Readonly<Record<string, readonly string[]>> = {\n 'conversation.updated': ['in_progress', 'failed'],\n 'conversation.completed': ['completed'],\n 'conversation.failed': ['failed'],\n 'conversation.expired': ['expired'],\n};\nconst ENVIRONMENTS = new Set(['mock', 'development', 'production']);\n\nexport function isConversationEvent(\n event: WebhookEvent,\n): event is ConversationEvent {\n return event.type.startsWith('conversation.');\n}\n\n/** What a verified body is: a known event, a test delivery, or a type newer than this package. */\nexport type ReadBody =\n | { kind: 'event'; event: WebhookEvent }\n | { kind: 'test'; envelope: WebhookEnvelope }\n | { kind: 'unrecognized'; envelope: WebhookEnvelope };\n\ntype Json = Record<string, unknown>;\n\nfunction isObject(value: unknown): value is Json {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Reads a verified body: it must be the webhook envelope (`id`, `type`,\n * `created_at`, `environment`, `data`). A test delivery from Studio carries\n * `data: { test: true }` and no payload. A conversation event must carry a\n * guided flow's state with the status its type allows and the fields its\n * ordering depends on (`conversation_id`, `sequence`); other payloads are as\n * Vinaverse signed them. A type newer than this package is `unrecognized`,\n * never an error: answer it 2xx and upgrade.\n */\nexport function readBody(text: string): ReadBody | WebhookError {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return webhookError('invalid_body', 'the body is not JSON');\n }\n if (\n !isObject(parsed) ||\n typeof parsed.id !== 'string' ||\n typeof parsed.type !== 'string' ||\n typeof parsed.created_at !== 'string' ||\n typeof parsed.environment !== 'string' ||\n !ENVIRONMENTS.has(parsed.environment) ||\n !isObject(parsed.data)\n ) {\n return webhookError(\n 'invalid_body',\n 'the body is not a webhook envelope (id, type, created_at, environment, data)',\n );\n }\n const envelope = parsed as WebhookEnvelope;\n if (parsed.data.test === true) return { kind: 'test', envelope };\n if (!KNOWN.has(parsed.type)) return { kind: 'unrecognized', envelope };\n const statuses = CONVERSATION_STATUSES[parsed.type];\n if (statuses) {\n const { conversation_id, sequence, status, flow } = parsed.data;\n if (\n typeof conversation_id !== 'string' ||\n !Number.isSafeInteger(sequence) ||\n (sequence as number) < 1 ||\n typeof status !== 'string' ||\n !statuses.includes(status) ||\n typeof flow !== 'string'\n ) {\n return webhookError(\n 'invalid_body',\n `a ${parsed.type} event carries a guided flow's state: conversation_id, a positive integer sequence, a flow, and status ${statuses.join(' or ')}`,\n );\n }\n }\n return { kind: 'event', event: parsed as WebhookEvent };\n}\n","// The webhook signature, exactly as the Vinaverse API signs and checks it\n// (contract: docs/conversation-state.md §1, \"Delivery\"):\n// Vinaverse-Signature: t=<unix seconds>,v1=<hex>[,v1=<hex>]\n// `v1` is the lowercase hex HMAC-SHA256, keyed with the endpoint's whole\n// signing secret as UTF-8 (the `vv_whsec_` prefix included, never decoded),\n// over `<t>.` followed by the raw request body. During a secret rotation the\n// header carries one `v1` per valid secret. A signature more than 300 seconds\n// from now, either way, is refused.\nimport { concat, hexToBytes, hmacKey, utf8 } from '../internal/bytes.js';\nimport { subtleCrypto } from './crypto.js';\nimport { type WebhookError, webhookError } from './errors.js';\n\nexport const SIGNATURE_HEADER = 'Vinaverse-Signature';\nexport const TOLERANCE_SECONDS = 300;\n\nconst DIGITS = /^[0-9]+$/;\nconst V1 = /^[0-9a-f]{64}$/;\n\nexport interface ParsedSignature {\n /** The signed timestamp, in Unix seconds. */\n readonly timestamp: bigint;\n /** Each `v1` signature, decoded. */\n readonly signatures: readonly Uint8Array[];\n}\n\n/**\n * Reads the header the way the API's own verifier does: comma-separated\n * `key=value` parts (a space around a part changes nothing), exactly one `t`\n * of digits, and the `v1` values. A `v1`\n * that is not 64 lowercase hex digits can never match, so it is left out; a\n * header left with no `v1` is malformed.\n */\nexport function parseSignatureHeader(\n header: string,\n): ParsedSignature | WebhookError {\n const parts = header\n .split(',')\n .map((p) => p.trim())\n .filter((p) => p.includes('='))\n .map((p) => {\n const at = p.indexOf('=');\n return [p.slice(0, at), p.slice(at + 1)] as const;\n });\n const timestamps = parts.filter(([k]) => k === 't').map(([, v]) => v);\n const [t] = timestamps;\n if (timestamps.length !== 1 || t === undefined || !DIGITS.test(t)) {\n return webhookError(\n 'malformed',\n 'the signature header needs exactly one timestamp, t=<unix seconds>',\n );\n }\n const signatures = parts\n .filter(([k, v]) => k === 'v1' && V1.test(v))\n .map(([, v]) => hexToBytes(v));\n if (signatures.length === 0) {\n return webhookError(\n 'malformed',\n 'the signature header has no v1 signature',\n );\n }\n return { timestamp: BigInt(t), signatures };\n}\n\n/**\n * Checks a delivery's signature: the header's form, its timestamp against\n * `now`, then each `v1` against each secret, in constant time (Web Crypto's\n * `verify`). `secrets` is more than one while the receiver rolls a new secret\n * out. Returns null when the signature is valid.\n */\nexport async function checkSignature(options: {\n body: Uint8Array;\n header: string;\n secrets: readonly string[];\n now: Date;\n toleranceSeconds: number;\n}): Promise<WebhookError | null> {\n const parsed = parseSignatureHeader(options.header);\n if ('code' in parsed) return parsed;\n const now = BigInt(Math.floor(options.now.getTime() / 1000));\n const skew =\n now > parsed.timestamp ? now - parsed.timestamp : parsed.timestamp - now;\n if (skew > BigInt(options.toleranceSeconds)) {\n return webhookError(\n 'stale',\n `the signature is ${skew} seconds from now; at most ${options.toleranceSeconds} are accepted`,\n );\n }\n const message = concat(utf8(`${parsed.timestamp}.`), options.body);\n const subtle = await subtleCrypto();\n for (const secret of options.secrets) {\n const key = await hmacKey(secret, 'verify');\n for (const signature of parsed.signatures) {\n // Every signature is decoded into its own ArrayBuffer (hexToBytes).\n if (\n await subtle.verify(\n 'HMAC',\n key,\n signature as Uint8Array<ArrayBuffer>,\n message,\n )\n )\n return null;\n }\n }\n return webhookError(\n 'mismatch',\n 'no signature matches the body with the signing secret: check the secret, and verify the raw body exactly as received',\n );\n}\n","import { toBytes } from '../internal/bytes.js';\nimport { type WebhookError, webhookError } from './errors.js';\nimport { type ReadBody, readBody } from './events.js';\nimport { checkSignature, TOLERANCE_SECONDS } from './signature.js';\n\nexport interface VerifyWebhookOptions {\n /**\n * The request body exactly as received, before any JSON parsing: a string,\n * or bytes (`Uint8Array`, which a Node `Buffer` is, or `ArrayBuffer`). A\n * body parsed and serialized again never verifies.\n */\n rawBody: string | Uint8Array | ArrayBuffer;\n /** The `Vinaverse-Signature` header (a framework's string array is accepted). */\n header: string | readonly string[] | null | undefined;\n /**\n * The endpoint's signing secret (`vv_whsec_…`), whole. Pass two while you\n * roll a new one out: a delivery verifies if either matches.\n */\n secret: string | readonly string[];\n /** The time to check the signature's timestamp against; default now. */\n now?: Date;\n /** How far from `now` a signature may be: whole seconds, 0 to 300 (the contract's window, the default). */\n toleranceSeconds?: number;\n}\n\nexport type VerifyWebhookResult =\n | ({ ok: true } & ReadBody)\n | { ok: false; error: WebhookError };\n\n/**\n * Verifies a Vinaverse webhook delivery and reads it, in one call:\n *\n * - `{ ok: true, kind: 'event', event }`: a verified event; narrow it on `event.type`.\n * - `{ ok: true, kind: 'test', envelope }`: a test delivery from Studio; answer 2xx, do nothing.\n * - `{ ok: true, kind: 'unrecognized', envelope }`: verified, but a type newer than this\n * package; answer 2xx, and upgrade to handle it.\n * - `{ ok: false, error }`: refused (`error.code` says why); answer 400.\n *\n * Deliveries are at least once: deduplicate on `event.id`, and order a\n * conversation's states with `sequenceVerdict` or `applyConversationState`.\n * It never throws for a bad delivery; it throws a `TypeError` for a missing\n * secret or a tolerance that is not a whole number of seconds from 0 to 300,\n * and `WebCryptoUnavailableError` in a runtime without Web Crypto.\n */\nexport async function verifyWebhook(\n options: VerifyWebhookOptions,\n): Promise<VerifyWebhookResult> {\n const secrets = signingSecrets(options.secret);\n const toleranceSeconds = checkTolerance(options.toleranceSeconds);\n const header = singleHeader(options.header);\n if (header === undefined) {\n return {\n ok: false,\n error: webhookError('missing', 'no Vinaverse-Signature header'),\n };\n }\n if (header === null) {\n return {\n ok: false,\n error: webhookError(\n 'malformed',\n 'more than one Vinaverse-Signature header',\n ),\n };\n }\n const body = toBytes(options.rawBody);\n const refused = await checkSignature({\n body,\n header,\n secrets,\n now: options.now ?? new Date(),\n toleranceSeconds,\n });\n if (refused) return { ok: false, error: refused };\n let text: string;\n try {\n text = new TextDecoder('utf-8', { fatal: true }).decode(body);\n } catch {\n return {\n ok: false,\n error: webhookError('invalid_body', 'the body is not UTF-8'),\n };\n }\n const read = readBody(text);\n return 'code' in read ? { ok: false, error: read } : { ok: true, ...read };\n}\n\n// undefined: absent; null: more than one; otherwise the header.\nfunction singleHeader(\n header: string | readonly string[] | null | undefined,\n): string | null | undefined {\n if (header === null || header === undefined) return undefined;\n if (typeof header === 'string') return header === '' ? undefined : header;\n if (header.length === 0) return undefined;\n return header.length === 1 ? header[0] : null;\n}\n\n/** The signing secrets, checked: a TypeError for none, an empty one, or an unset variable. */\nexport function signingSecrets(secret: unknown): string[] {\n const list =\n typeof secret === 'string'\n ? [secret]\n : Array.isArray(secret)\n ? [...secret]\n : [];\n if (\n list.length === 0 ||\n list.some((s) => typeof s !== 'string' || s === '')\n ) {\n throw new TypeError(\n 'the webhook signing secret is required (vv_whsec_…), and none was given',\n );\n }\n return list as string[];\n}\n\n/**\n * The tolerance, checked once: whole seconds from 0 to 300. A wider window is\n * a longer replay window than the contract allows.\n */\nexport function checkTolerance(seconds: number | undefined): number {\n if (seconds === undefined) return TOLERANCE_SECONDS;\n if (\n !Number.isSafeInteger(seconds) ||\n seconds < 0 ||\n seconds > TOLERANCE_SECONDS\n ) {\n throw new TypeError(\n `toleranceSeconds must be a whole number of seconds from 0 to ${TOLERANCE_SECONDS}, not ${seconds}`,\n );\n }\n return seconds;\n}\n","// What every adapter does with a delivery once it has the raw body and the\n// signature header: verify, call the tenant's handler for the result, and\n// answer. A refused delivery is answered 400 (Vinaverse retries, then gives\n// up); a handled one 200. A handler that throws is the adapter's to surface,\n// so the delivery fails and Vinaverse retries it.\nimport type { WebhookError } from '../webhooks/errors.js';\nimport type { WebhookEnvelope, WebhookEvent } from '../webhooks/events.js';\nimport {\n checkTolerance,\n signingSecrets,\n verifyWebhook,\n} from '../webhooks/verify.js';\n\nexport interface WebhookHandlerOptions {\n /** The endpoint's signing secret, or two while rolling a new one out. */\n secret: string | readonly string[];\n /**\n * Called once per verified delivery of a known event. Answer quickly (the\n * contract allows 5 seconds) and do the work afterwards; deliveries are at\n * least once, so deduplicate on `event.id`.\n */\n onEvent(event: WebhookEvent): void | Promise<void>;\n /** A test delivery from Studio; by default it is acknowledged and ignored. */\n onTest?(envelope: WebhookEnvelope): void | Promise<void>;\n /** A verified type newer than this package; by default acknowledged and ignored. */\n onUnrecognized?(envelope: WebhookEnvelope): void | Promise<void>;\n /** A refused delivery, for logging; it is answered 400 either way. */\n onRejected?(error: WebhookError): void | Promise<void>;\n /** How far from now a signature may be, in seconds; default 300. */\n toleranceSeconds?: number;\n /**\n * The largest body accepted, in bytes; default 1 MiB (a conversation\n * webhook is at most 64 KB). A larger one is answered 413 unread.\n */\n maxBodyBytes?: number;\n /** The clock; default the system clock. */\n now?: () => Date;\n}\n\nexport interface WebhookResponse {\n readonly status: 200 | 400 | 413;\n readonly body: string;\n}\n\nexport const MAX_BODY_BYTES = 1024 * 1024;\nconst RECEIVED = JSON.stringify({ received: true });\n\nexport function tooLarge(): WebhookResponse {\n return {\n status: 413,\n body: JSON.stringify({ error: { code: 'body_too_large' } }),\n };\n}\n\nexport function byteLength(body: string | Uint8Array | ArrayBuffer): number {\n return typeof body === 'string'\n ? new TextEncoder().encode(body).length\n : body.byteLength;\n}\n\nexport async function handleWebhook(\n options: WebhookHandlerOptions,\n rawBody: string | Uint8Array | ArrayBuffer,\n header: string | readonly string[] | null | undefined,\n): Promise<WebhookResponse> {\n if (byteLength(rawBody) > (options.maxBodyBytes ?? MAX_BODY_BYTES)) {\n return tooLarge();\n }\n const result = await verifyWebhook({\n rawBody,\n header,\n secret: options.secret,\n ...(options.now ? { now: options.now() } : {}),\n ...(options.toleranceSeconds === undefined\n ? {}\n : { toleranceSeconds: options.toleranceSeconds }),\n });\n if (!result.ok) {\n await options.onRejected?.(result.error);\n return {\n status: 400,\n body: JSON.stringify({ error: { code: result.error.code } }),\n };\n }\n if (result.kind === 'event') await options.onEvent(result.event);\n else if (result.kind === 'test') await options.onTest?.(result.envelope);\n else await options.onUnrecognized?.(result.envelope);\n return { status: 200, body: RECEIVED };\n}\n\n/** A header's value from a record whose names may have any case. */\nexport function headerValue(\n headers:\n | Readonly<Record<string, string | readonly string[] | undefined>>\n | null\n | undefined,\n name: string,\n): string | readonly string[] | undefined {\n if (!headers) return undefined;\n const wanted = name.toLowerCase();\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === wanted && value !== undefined) return value;\n }\n return undefined;\n}\n\n/**\n * Checks a handler's options once, when the adapter is made, so a wrong value\n * fails at start-up instead of answering every delivery with an error.\n */\nexport function checkHandlerOptions(options: WebhookHandlerOptions): void {\n signingSecrets(options.secret);\n checkTolerance(options.toleranceSeconds);\n if (typeof options.onEvent !== 'function') {\n throw new TypeError(\n 'onEvent is required: it receives every verified event',\n );\n }\n const max = options.maxBodyBytes;\n if (max !== undefined && (!Number.isSafeInteger(max) || max <= 0)) {\n throw new TypeError(\n `maxBodyBytes must be a positive whole number of bytes, not ${max}`,\n );\n }\n}\n","// Web-standard handlers: anything that hands over a `Request` and takes a\n// `Response` (Hono, Next.js route handlers, Cloudflare Workers, Deno, Bun).\nimport {\n checkHandlerOptions,\n handleWebhook,\n MAX_BODY_BYTES,\n tooLarge,\n type WebhookHandlerOptions,\n type WebhookResponse,\n} from './handler.js';\n\nexport type { WebhookHandlerOptions } from './handler.js';\n\nimport type { ToolProvider } from '../tools/provider.js';\n\n/**\n * `(request) => Promise<Response>` for a Vinaverse webhook endpoint. It reads\n * the raw body itself, so mount it where nothing has parsed the body:\n *\n * export const POST = createFetchWebhookHandler({ secret, onEvent });\n */\nexport function createFetchWebhookHandler(\n options: WebhookHandlerOptions,\n): (request: Request) => Promise<Response> {\n checkHandlerOptions(options);\n const max = options.maxBodyBytes ?? MAX_BODY_BYTES;\n return async (request) => {\n const body = await readCapped(request, max);\n if (body === undefined) return toResponse(tooLarge());\n return toResponse(\n await handleWebhook(\n options,\n body,\n request.headers.get('vinaverse-signature'),\n ),\n );\n };\n}\n\n/**\n * The body, read as a stream and stopped past `max` bytes (undefined then),\n * so neither a declared nor a chunked oversized body is held in memory.\n */\nexport async function readCapped(\n request: Request,\n max: number,\n): Promise<Uint8Array | undefined> {\n const declared = Number(request.headers.get('content-length') ?? '0');\n if (declared > max) return undefined;\n if (!request.body) return new Uint8Array(0);\n const reader = request.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.length;\n if (size > max) {\n await reader.cancel();\n return undefined;\n }\n chunks.push(value);\n }\n const body = new Uint8Array(size);\n let at = 0;\n for (const chunk of chunks) {\n body.set(chunk, at);\n at += chunk.length;\n }\n return body;\n}\n\nexport function toResponse(response: WebhookResponse): Response {\n return new Response(response.body, {\n status: response.status,\n headers: { 'content-type': 'application/json' },\n });\n}\n\n/**\n * `(request) => Promise<Response>` serving a tenant's tools: every tool route\n * under the provider's `basePath`, with the contract enforced. The target is\n * the request URL's path and query as received.\n *\n * const handle = createFetchToolHandler(createToolProvider({ … }));\n */\nexport function createFetchToolHandler(\n provider: ToolProvider,\n options: { maxBodyBytes?: number } = {},\n): (request: Request) => Promise<Response> {\n const max = options.maxBodyBytes ?? MAX_BODY_BYTES;\n return async (request) => {\n const url = new URL(request.url);\n const reads = request.method !== 'GET' && request.method !== 'HEAD';\n const body = reads ? await readCapped(request, max) : null;\n if (body === undefined) {\n return new Response(\n JSON.stringify({\n status: 413,\n code: 'invalid_argument',\n detail: 'the request body is too large',\n }),\n {\n status: 413,\n headers: { 'content-type': 'application/problem+json' },\n },\n );\n }\n const response = await provider.handle({\n method: request.method,\n target: `${url.pathname}${url.search}`,\n header: (name) => request.headers.get(name) ?? undefined,\n body,\n });\n return new Response(response.body, {\n status: response.status,\n headers: response.headers,\n });\n };\n}\n","// The contract this package version targets: the public API's version and the\n// vinaverse-contracts commit its types were generated from (contracts.lock).\n// A test holds both to the pinned contracts, so they cannot drift.\nexport const CONTRACT = {\n api: 'v1-draft.24',\n commit: 'a7fd1e0f13093b50c1ebdb5d5d0fe8b724daae39',\n} as const;\n","// Generated by scripts/gen-tool-operations.mjs from the pinned tool-provider contract (v1-draft.15). Do not edit.\nexport const TOOL_OPERATIONS = {\n create_handoff: {\n id: 'create_handoff',\n method: 'POST',\n path: '/handoffs',\n effect: 'write',\n maxResultBytes: 16384,\n successStatus: 201,\n idempotencyKey: true,\n body: true,\n pathParams: {},\n queryParams: {},\n },\n create_proposal: {\n id: 'create_proposal',\n method: 'POST',\n path: '/proposals',\n effect: 'propose',\n maxResultBytes: 16384,\n successStatus: 201,\n idempotencyKey: true,\n body: true,\n pathParams: {},\n queryParams: {},\n },\n get_availability: {\n id: 'get_availability',\n method: 'GET',\n path: '/availability',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n professional_id: { type: 'string', required: true },\n service_id: { type: 'string', required: true },\n from: { type: 'string', required: true },\n to: { type: 'string', required: true },\n limit: { type: 'integer', required: false },\n },\n },\n get_flow_definition: {\n id: 'get_flow_definition',\n method: 'GET',\n path: '/flows/{flow}/definition',\n effect: 'read',\n maxResultBytes: 131072,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { flow: { type: 'string', required: true } },\n queryParams: { version: { type: 'integer', required: false } },\n },\n get_my_booking: {\n id: 'get_my_booking',\n method: 'GET',\n path: '/me/bookings/{id}',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { id: { type: 'string', required: true } },\n queryParams: {},\n },\n get_my_kit: {\n id: 'get_my_kit',\n method: 'GET',\n path: '/me/kits/{id}',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { id: { type: 'string', required: true } },\n queryParams: {},\n },\n get_my_order: {\n id: 'get_my_order',\n method: 'GET',\n path: '/me/orders/{id}',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { id: { type: 'string', required: true } },\n queryParams: {},\n },\n get_policy: {\n id: 'get_policy',\n method: 'GET',\n path: '/policies/{topic}',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { topic: { type: 'string', required: true } },\n queryParams: {},\n },\n get_professional: {\n id: 'get_professional',\n method: 'GET',\n path: '/professionals/{id}',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { id: { type: 'string', required: true } },\n queryParams: {},\n },\n get_quote: {\n id: 'get_quote',\n method: 'POST',\n path: '/quotes',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: true,\n body: true,\n pathParams: {},\n queryParams: {},\n },\n get_setup_state: {\n id: 'get_setup_state',\n method: 'GET',\n path: '/business/setup',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {},\n },\n get_workspace: {\n id: 'get_workspace',\n method: 'GET',\n path: '/workspaces/{id}',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: { id: { type: 'string', required: true } },\n queryParams: {},\n },\n list_my_bookings: {\n id: 'list_my_bookings',\n method: 'GET',\n path: '/me/bookings',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n scope: { type: 'string', required: false },\n limit: { type: 'integer', required: false },\n },\n },\n list_my_kits: {\n id: 'list_my_kits',\n method: 'GET',\n path: '/me/kits',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n scope: { type: 'string', required: false },\n limit: { type: 'integer', required: false },\n },\n },\n list_my_orders: {\n id: 'list_my_orders',\n method: 'GET',\n path: '/me/orders',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n kit_id: { type: 'string', required: false },\n limit: { type: 'integer', required: false },\n },\n },\n list_services: {\n id: 'list_services',\n method: 'GET',\n path: '/catalog/services',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n q: { type: 'string', required: true },\n limit: { type: 'integer', required: false },\n },\n },\n list_services_in_area: {\n id: 'list_services_in_area',\n method: 'GET',\n path: '/areas/services',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n lat: { type: 'number', required: false },\n lng: { type: 'number', required: false },\n radius_miles: { type: 'integer', required: false },\n },\n },\n resolve_place: {\n id: 'resolve_place',\n method: 'GET',\n path: '/places/resolve',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n text: { type: 'string', required: true },\n near_lat: { type: 'number', required: false },\n near_lng: { type: 'number', required: false },\n },\n },\n search_professionals: {\n id: 'search_professionals',\n method: 'GET',\n path: '/search/professionals',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n q: { type: 'string', required: false },\n category_id: { type: 'string', required: false },\n service_type_id: { type: 'string', required: false },\n lat: { type: 'number', required: false },\n lng: { type: 'number', required: false },\n radius_miles: { type: 'integer', required: false },\n date: { type: 'string', required: false },\n time_from: { type: 'string', required: false },\n time_to: { type: 'string', required: false },\n max_price: { type: 'integer', required: false },\n min_rating_ppm: { type: 'integer', required: false },\n sort: { type: 'string', required: false },\n limit: { type: 'integer', required: false },\n cursor: { type: 'string', required: false },\n },\n },\n search_workspaces: {\n id: 'search_workspaces',\n method: 'GET',\n path: '/search/workspaces',\n effect: 'read',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: false,\n pathParams: {},\n queryParams: {\n q: { type: 'string', required: false },\n space_category: { type: 'string', required: false },\n lat: { type: 'number', required: false },\n lng: { type: 'number', required: false },\n radius_miles: { type: 'integer', required: false },\n max_price: { type: 'integer', required: false },\n min_rating_ppm: { type: 'integer', required: false },\n sort: { type: 'string', required: false },\n limit: { type: 'integer', required: false },\n cursor: { type: 'string', required: false },\n },\n },\n submit_flow: {\n id: 'submit_flow',\n method: 'POST',\n path: '/flows/{flow}/submissions',\n effect: 'write',\n maxResultBytes: 16384,\n successStatus: 200,\n idempotencyKey: false,\n body: true,\n pathParams: { flow: { type: 'string', required: true } },\n queryParams: {},\n },\n} as const;\n\nexport type ToolOperationId = keyof typeof TOOL_OPERATIONS;\n","// Idempotency for the tool calls that change something (contract:\n// tool-provider-v1.yaml, `submit_flow`, `create_proposal`, and every call\n// with a required `Idempotency-Key`). A call is recorded under a key with a\n// fingerprint of what it asked; the same key and fingerprint gets the stored\n// answer again, and the same key with another fingerprint is a conflict.\n\nimport { sha256Hex, utf8 } from '../internal/bytes.js';\n\n/** What a store holds for a key. `pending` while the first call runs. */\nexport interface IdempotencyRecord {\n /** The hex SHA-256 of what the call asked (never the request itself). */\n readonly fingerprint: string;\n readonly state: 'pending' | 'done';\n /** The stored answer, once done. */\n readonly status?: number;\n readonly body?: string;\n}\n\n/**\n * Every write is tied to the call that started the key (`owner`, random per\n * call): a call whose pending lease lapsed and was taken by another can\n * neither store its answer over that call's nor release that call's lease.\n */\nexport interface IdempotencyStore {\n /**\n * Creates a pending record for `key`, held by `owner`, and returns null, or,\n * when one exists, returns it unchanged. Must be atomic across every\n * instance sharing the store. A pending record lapses after\n * `pendingSeconds`, so a call that crashed does not hold its key forever.\n */\n start(\n key: string,\n fingerprint: string,\n pendingSeconds: number,\n owner: string,\n ): Promise<IdempotencyRecord | null>;\n /**\n * Stores the answer for `key`, kept for `keepSeconds`, when `owner` still\n * holds the pending record (or nobody holds the key); returns false and\n * stores nothing when another call holds it or has answered.\n */\n finish(\n key: string,\n record: { fingerprint: string; status: number; body: string },\n keepSeconds: number,\n owner: string,\n ): Promise<boolean>;\n /** Drops the record if `owner` still holds it pending (the call failed without an answer to keep). */\n release(key: string, owner: string): Promise<void>;\n}\n\ninterface Held {\n record: IdempotencyRecord;\n owner?: string;\n until: number;\n}\n\n/**\n * An in-process store: right for one instance and for tests. Expired records\n * are dropped on one `start` in `sweepEvery` (default 256).\n */\nexport class MemoryIdempotencyStore implements IdempotencyStore {\n readonly #held = new Map<string, Held>();\n readonly #now: () => number;\n readonly #sweepEvery: number;\n #starts = 0;\n\n constructor(options: { now?: () => number; sweepEvery?: number } = {}) {\n this.#now = options.now ?? (() => Date.now() / 1000);\n this.#sweepEvery = Math.max(1, options.sweepEvery ?? 256);\n }\n\n async start(\n key: string,\n fingerprint: string,\n pendingSeconds: number,\n owner: string,\n ): Promise<IdempotencyRecord | null> {\n const now = this.#now();\n if (++this.#starts % this.#sweepEvery === 0) {\n for (const [k, h] of this.#held) if (h.until < now) this.#held.delete(k);\n }\n const held = this.#live(key);\n if (held) return held.record;\n this.#held.set(key, {\n record: { fingerprint, state: 'pending' },\n owner,\n until: now + pendingSeconds,\n });\n return null;\n }\n\n async finish(\n key: string,\n record: { fingerprint: string; status: number; body: string },\n keepSeconds: number,\n owner: string,\n ): Promise<boolean> {\n const held = this.#live(key);\n if (held && (held.record.state !== 'pending' || held.owner !== owner)) {\n return false;\n }\n this.#held.set(key, {\n record: { ...record, state: 'done' },\n until: this.#now() + keepSeconds,\n });\n return true;\n }\n\n async release(key: string, owner: string): Promise<void> {\n const held = this.#live(key);\n if (held?.record.state === 'pending' && held.owner === owner) {\n this.#held.delete(key);\n }\n }\n\n /** Records held, expired ones included until a sweep drops them. */\n get size(): number {\n return this.#held.size;\n }\n\n #live(key: string): Held | undefined {\n const held = this.#held.get(key);\n return held && held.until >= this.#now() ? held : undefined;\n }\n}\n\n/** The fingerprint of a request: the hex SHA-256 of its canonical JSON. */\nexport function fingerprint(value: unknown): Promise<string> {\n return sha256Hex(utf8(canonicalJson(value)));\n}\n\n/**\n * JSON with keys sorted at every level and no insignificant whitespace, so\n * two bodies equal as JSON (key order aside, numbers by value: `1` and `1.0`)\n * have one fingerprint.\n */\nexport function canonicalJson(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`;\n if (value !== null && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`).join(',')}}`;\n }\n return JSON.stringify(value) ?? 'null';\n}\n","// Single-use nonces for tool calls (contract: tool-provider-v1.yaml,\n// `vinaverseSignature`, \"Nonces\"). A nonce is taken once; a second call with\n// it is a replay. Each one is kept until at least `t + 300` seconds, counted\n// from the call's `t`; 6 minutes after `t` is kept here. Every instance that\n// receives calls must share one store, or calls must be pinned to one\n// instance: otherwise a replay sent to another instance passes.\n\n/** Keep each nonce this long after the call's `t` (the contract's minimum is the 300-second window). */\nexport const NONCE_KEEP_SECONDS = 360;\n\nexport interface NonceStore {\n /**\n * Takes `nonce` until `keepUntil` (Unix seconds): true the first time it is\n * seen, false for a replay. Must be atomic across every instance that\n * shares the store.\n */\n claim(nonce: string, keepUntil: number): Promise<boolean>;\n}\n\n/**\n * An in-process store: right for one instance (a single server, tests, one\n * Lambda with reserved concurrency of 1). Behind several instances, use a\n * shared store (`@vinaverse/server/stores`: Redis, DynamoDB, Postgres).\n * Expired nonces are dropped on one claim in `sweepEvery` (default 256).\n */\nexport class MemoryNonceStore implements NonceStore {\n readonly #seen = new Map<string, number>();\n readonly #now: () => number;\n readonly #sweepEvery: number;\n #claims = 0;\n\n constructor(options: { now?: () => number; sweepEvery?: number } = {}) {\n this.#now = options.now ?? (() => Math.floor(Date.now() / 1000));\n this.#sweepEvery = Math.max(1, options.sweepEvery ?? 256);\n }\n\n async claim(nonce: string, keepUntil: number): Promise<boolean> {\n const now = this.#now();\n if (++this.#claims % this.#sweepEvery === 0) {\n for (const [n, until] of this.#seen) {\n if (until < now) this.#seen.delete(n);\n }\n }\n const until = this.#seen.get(nonce);\n if (until !== undefined && until >= now) return false;\n this.#seen.set(nonce, keepUntil);\n return true;\n }\n\n /** Nonces held, expired ones included until a sweep drops them. */\n get size(): number {\n return this.#seen.size;\n }\n}\n","// Typed refusals a tool handler throws; the toolkit answers each with the\n// status and problem body the contract defines (tool-provider-v1.yaml,\n// `Problem`, `FlowSubmissionRefusal`, the `410` of `get_flow_definition`).\n// The runtime maps a problem's `code` to what the agent does: ask again\n// (`invalid_argument`, with `field` and `example`), say the record is not\n// there (`not_found`), stop (`forbidden`), try later (`unavailable`), or end\n// the session's tool access (`token_expired`, always a 401).\n\nexport type ProblemCode =\n | 'not_found'\n | 'forbidden'\n | 'invalid_argument'\n | 'unavailable'\n | 'token_expired';\n\n/** The codes a refused flow submission carries (`FlowSubmissionRefusal`). */\nexport type FlowRefusalCode =\n | 'REQUIRED_MISSING'\n | 'UNKNOWN_VALUE'\n | 'TOO_LONG'\n | 'VERSION_NOT_ACCEPTED'\n | 'TOO_MANY'\n | 'TOO_FEW'\n | 'BAD_DATE'\n | 'UPLOAD_NOT_FOUND'\n | 'OUT_OF_RANGE';\n\nconst FLOW_REFUSAL_CODES: Record<FlowRefusalCode, true> = {\n REQUIRED_MISSING: true,\n UNKNOWN_VALUE: true,\n TOO_LONG: true,\n VERSION_NOT_ACCEPTED: true,\n TOO_MANY: true,\n TOO_FEW: true,\n BAD_DATE: true,\n UPLOAD_NOT_FOUND: true,\n OUT_OF_RANGE: true,\n};\n\n/**\n * Whether a problem is a `FlowSubmissionRefusal`: a 422 with a flow code and\n * the question to ask again (none only for `VERSION_NOT_ACCEPTED`).\n */\nexport function isFlowRefusal(problem: ProblemBody): boolean {\n return (\n problem.status === 422 &&\n Object.hasOwn(FLOW_REFUSAL_CODES, problem.code) &&\n (problem.code === 'VERSION_NOT_ACCEPTED' || !!problem.question_id)\n );\n}\n\nexport interface ProblemBody {\n readonly status: number;\n readonly code: string;\n readonly detail?: string;\n readonly field?: string;\n readonly example?: string;\n readonly question_id?: string;\n}\n\nconst STATUS: Record<ProblemCode, number> = {\n not_found: 404,\n forbidden: 403,\n invalid_argument: 422,\n unavailable: 503,\n token_expired: 401,\n};\n\n/** A refusal the toolkit sends as the contract's problem details. */\nexport class ToolRefusal extends Error {\n readonly problem: ProblemBody;\n\n constructor(problem: ProblemBody) {\n super(problem.detail ?? problem.code);\n this.name = 'ToolRefusal';\n this.problem = problem;\n }\n\n get status(): number {\n return this.problem.status;\n }\n\n /** The record does not exist, or the person may not see it (both are the same 404). */\n static notFound(detail?: string): ToolRefusal {\n return ToolRefusal.#coded('not_found', detail);\n }\n\n static forbidden(detail?: string): ToolRefusal {\n return ToolRefusal.#coded('forbidden', detail);\n }\n\n /**\n * A value the tenant does not accept. `field` is a JSON Pointer into the\n * body (`/changes/address/postal_code`); `example` is a valid value the\n * agent offers when it asks again.\n */\n static invalidArgument(\n options: { field?: string; example?: string; detail?: string } = {},\n ): ToolRefusal {\n return new ToolRefusal({\n status: 422,\n code: 'invalid_argument',\n ...clip('detail', options.detail, 300),\n ...clip('field', options.field, 200),\n ...clip('example', options.example, 200),\n });\n }\n\n /** A temporary failure; a read is retried. */\n static unavailable(detail?: string): ToolRefusal {\n return ToolRefusal.#coded('unavailable', detail);\n }\n\n /** The delegated token is not valid (expired, revoked, unknown): a 401, which ends the session's tool access. */\n static tokenExpired(detail?: string): ToolRefusal {\n return ToolRefusal.#coded('token_expired', detail);\n }\n\n /** `get_flow_definition` with a `version` the tenant no longer accepts: `410 VERSION_GONE`. */\n static versionGone(detail?: string): ToolRefusal {\n return new ToolRefusal({\n status: 410,\n code: 'VERSION_GONE',\n ...clip('detail', detail, 300),\n });\n }\n\n /**\n * `submit_flow` refused: `422` with a flow code and the question to ask\n * again (none only for `VERSION_NOT_ACCEPTED`). Stored like an acceptance,\n * so the same submission gets the same refusal again.\n */\n static flowRefused(\n code: FlowRefusalCode,\n questionId?: string,\n detail?: string,\n ): ToolRefusal {\n if (code !== 'VERSION_NOT_ACCEPTED' && !questionId) {\n throw new TypeError(`a ${code} refusal names the question to ask again`);\n }\n return new ToolRefusal({\n status: 422,\n code,\n ...(questionId ? { question_id: questionId } : {}),\n ...clip('detail', detail, 300),\n });\n }\n\n static #coded(code: ProblemCode, detail?: string): ToolRefusal {\n return new ToolRefusal({\n status: STATUS[code],\n code,\n ...clip('detail', detail, 300),\n });\n }\n}\n\nfunction clip<K extends string>(\n key: K,\n value: string | undefined,\n max: number,\n): Partial<Record<K, string>> {\n if (value === undefined) return {};\n return { [key]: [...value].slice(0, max).join('') } as Partial<\n Record<K, string>\n >;\n}\n","// Tool-call signature v2, exactly as the Vinaverse API signs it and as its\n// reference verifier checks it in strict mode (contract: tool-provider-v1.yaml,\n// `vinaverseSignature`; API: vvcore.connectors.signature):\n// Vinaverse-Signature: t=<unix seconds>,n=<nonce>,v2=<hex>[,v2=<hex>][,v1=<hex>]\n// `v2` is the lowercase hex HMAC-SHA256, keyed with the tool signing secret as\n// UTF-8, over seven lines joined by \"\\n\" with no trailing line feed:\n// v2, t, n, the METHOD, the request target exactly as sent (path and query,\n// still percent-escaped), the hex SHA-256 of the whole delegated token, and\n// the hex SHA-256 of the body, or an empty line when there is no body.\n// A signature more than 300 seconds from now is refused, and so is a nonce\n// already taken. `v1` (sent during the transition) is ignored: it binds\n// neither the token nor a nonce.\nimport { hexToBytes, hmacKey, sha256Hex, utf8 } from '../internal/bytes.js';\nimport { subtleCrypto } from '../webhooks/crypto.js';\nimport { checkTolerance } from '../webhooks/verify.js';\nimport { NONCE_KEEP_SECONDS, type NonceStore } from './nonces.js';\n\nexport const TOOL_TOLERANCE_SECONDS = 300;\n\nconst T = /^[0-9]{1,12}$/;\nconst NONCE = /^[A-Za-z0-9_-]{16,64}$/;\nconst MAC = /^[0-9a-f]{64}$/;\n\n/**\n * Why a tool call's signature was refused, in the conformance vectors' words\n * (vinaverse-contracts `conformance/tool-calls.json`), checked in their order:\n * - `missing`: no `Vinaverse-Signature` header.\n * - `malformed`: no valid `t`, or no valid nonce (16 to 64 of `A-Z a-z 0-9 - _`).\n * - `stale`: signed more than 300 seconds from now, either way.\n * - `v2_required`: no `v2` (a v1-only header binds neither the token nor a nonce).\n * - `mismatch`: no `v2` matches with any secret: a wrong secret, or a method,\n * target, delegated token or body other than the ones signed.\n * - `replayed`: a valid signature whose nonce was already taken.\n */\nexport type ToolSignatureErrorCode =\n | 'missing'\n | 'malformed'\n | 'stale'\n | 'v2_required'\n | 'mismatch'\n | 'replayed';\n\nexport interface ToolSignatureError {\n readonly code: ToolSignatureErrorCode;\n readonly message: string;\n}\n\nexport interface ToolCallToVerify {\n /** The HTTP method. */\n method: string;\n /** The request target exactly as received: path and query, still percent-escaped. */\n target: string;\n /** The delegated token from the `Authorization: Bearer` header. */\n token: string;\n /** The body as received; `undefined`, `null` or empty for none. */\n body?: Uint8Array | null | undefined;\n /** The `Vinaverse-Signature` header. */\n header: string | null | undefined;\n}\n\nexport interface VerifyToolCallOptions {\n /** The tool signing secret, or two during a rotation. */\n secrets: readonly string[];\n nonces: NonceStore;\n now: Date;\n toleranceSeconds?: number;\n}\n\n/**\n * The fields the header carries. A repeated `t` or `n` makes the header\n * ambiguous, so it is refused (`repeated`), never resolved by order (VIN-154).\n */\nexport function parseToolSignature(header: string): {\n t: number | undefined;\n n: string | undefined;\n v2: string[];\n repeated: boolean;\n} {\n let t: number | undefined;\n let n: string | undefined;\n let seenT = 0;\n let seenN = 0;\n const v2: string[] = [];\n for (const part of header.split(',')) {\n const trimmed = part.trim();\n const at = trimmed.indexOf('=');\n const key = at < 0 ? trimmed : trimmed.slice(0, at);\n const value = at < 0 ? '' : trimmed.slice(at + 1);\n if (key === 't') {\n seenT++;\n if (T.test(value)) t = Number(value);\n } else if (key === 'n') {\n seenN++;\n n = value;\n } else if (key === 'v2' && MAC.test(value)) {\n v2.push(value);\n }\n }\n return { t, n, v2, repeated: seenT > 1 || seenN > 1 };\n}\n\n/** The string v2 signs. */\nexport async function toolSigningString(call: {\n t: number;\n n: string;\n method: string;\n target: string;\n token: string;\n body?: Uint8Array | null | undefined;\n}): Promise<Uint8Array<ArrayBuffer>> {\n const bodyHash =\n call.body && call.body.length > 0 ? await sha256Hex(call.body) : '';\n return utf8(\n [\n 'v2',\n String(call.t),\n call.n,\n call.method.toUpperCase(),\n call.target,\n await sha256Hex(utf8(call.token)),\n bodyHash,\n ].join('\\n'),\n );\n}\n\n/**\n * Checks a tool call's v2 signature and takes its nonce. Returns null when the\n * call is authentic and fresh. The nonce is claimed only after a signature\n * matched, so a forged header cannot burn a real call's nonce.\n */\nexport async function verifyToolCall(\n call: ToolCallToVerify,\n options: VerifyToolCallOptions,\n): Promise<ToolSignatureError | null> {\n if (!call.header) {\n return refusal('missing', 'no Vinaverse-Signature header');\n }\n const { t, n, v2, repeated } = parseToolSignature(call.header);\n if (repeated) {\n return refusal(\n 'malformed',\n 'the signature repeats t or n: an ambiguous header',\n );\n }\n if (t === undefined) {\n return refusal(\n 'malformed',\n 'the signature has no timestamp t=<unix seconds>',\n );\n }\n const now = Math.floor(options.now.getTime() / 1000);\n const tolerance =\n options.toleranceSeconds === undefined\n ? TOOL_TOLERANCE_SECONDS\n : checkTolerance(options.toleranceSeconds);\n if (Math.abs(now - t) > tolerance) {\n return refusal(\n 'stale',\n `the signature is ${Math.abs(now - t)} seconds from now; at most ${tolerance} are accepted`,\n );\n }\n if (v2.length === 0) {\n return refusal(\n 'v2_required',\n 'the signature has no v2 (a v1-only header binds neither the token nor a nonce)',\n );\n }\n if (n === undefined || !NONCE.test(n)) {\n return refusal(\n 'malformed',\n 'the signature has no valid nonce n (16 to 64 of A-Z a-z 0-9 - _)',\n );\n }\n const message = await toolSigningString({ ...call, t, n });\n const subtle = await subtleCrypto();\n let matched = false;\n for (const secret of options.secrets) {\n const key = await hmacKey(secret, 'verify');\n for (const mac of v2) {\n if (await subtle.verify('HMAC', key, hexToBytes(mac), message)) {\n matched = true;\n break;\n }\n }\n if (matched) break;\n }\n if (!matched) {\n return refusal(\n 'mismatch',\n 'no v2 signature matches: check the tool signing secret, and verify the method, target, token and body exactly as received',\n );\n }\n if (!(await options.nonces.claim(n, Math.max(t, now) + NONCE_KEEP_SECONDS))) {\n return refusal('replayed', 'this nonce was already used: a replayed call');\n }\n return null;\n}\n\nfunction refusal(\n code: ToolSignatureErrorCode,\n message: string,\n): ToolSignatureError {\n return { code, message };\n}\n","// The tool provider: a tenant's tool endpoints with the contract enforced\n// around its handlers (contract: tool-provider-v1.yaml). For each call, in\n// order:\n// 1. the body is at most `maxRequestBytes`;\n// 2. a bearer token is present (else 401 token_expired);\n// 3. the signature v2 is valid and its nonce unused (else 403 forbidden);\n// 4. the route is one the contract defines and the tenant serves (else 404);\n// 5. the tenant's `authenticate` resolves the token to its principal;\n// 6. path and query parameters are read and typed, the JSON body parsed;\n// 7. calls that change something are made idempotent: `submit_flow` by its\n// `submission_id`, `create_proposal` by its key and canonical\n// `{topic, changes}`, the others with a required `Idempotency-Key` by the\n// key and the canonical body (stored as a SHA-256 fingerprint, never the\n// body); each run holds its key with a lease only it can store over or\n// release;\n// 8. the handler runs; a `ToolRefusal` becomes the contract's problem; any\n// other error is a 500 `unavailable` reported to `onError`;\n// 9. the result is at most the operation's limit (16 KB, the flow definition\n// 128 KB), else a 500 reported to `onError`, since the runtime would\n// refuse it anyway.\n\nimport {\n TOOL_OPERATIONS,\n type ToolOperationId,\n} from '../generated/tool-operations.js';\nimport type { operations } from '../generated/tool-provider-v1.js';\nimport { toBytes } from '../internal/bytes.js';\nimport { webCrypto } from '../webhooks/crypto.js';\nimport { checkTolerance } from '../webhooks/verify.js';\nimport {\n fingerprint,\n type IdempotencyRecord,\n type IdempotencyStore,\n} from './idempotency.js';\nimport type { NonceStore } from './nonces.js';\nimport { isFlowRefusal, type ProblemBody, ToolRefusal } from './refusals.js';\nimport { type ToolSignatureErrorCode, verifyToolCall } from './signature.js';\n\nexport type { ToolOperationId } from '../generated/tool-operations.js';\n\ntype Op<K extends ToolOperationId> = operations[K];\n\ntype ParamsOf<K extends ToolOperationId, Where extends string> =\n Op<K>['parameters'] extends Record<Where, infer P>\n ? [P] extends [never | undefined]\n ? Record<string, never>\n : NonNullable<P>\n : Record<string, never>;\n\n/** A tool's request body, as the contract types it. */\nexport type ToolBody<K extends ToolOperationId> =\n Op<K> extends {\n requestBody: { content: { 'application/json': infer B } };\n }\n ? B\n : Op<K> extends {\n requestBody?: { content: { 'application/json': infer B } };\n }\n ? B | undefined\n : undefined;\n\ntype SuccessOf<R> = R extends { 200: infer S }\n ? S\n : R extends { 201: infer S }\n ? S\n : never;\n\n/** A tool's success result, as the contract types it. */\nexport type ToolResult<K extends ToolOperationId> =\n SuccessOf<Op<K>['responses']> extends {\n content: { 'application/json': infer B };\n }\n ? B\n : never;\n\n/** What a handler receives. */\nexport interface ToolCall<K extends ToolOperationId, P> {\n readonly operation: K;\n /** What `authenticate` returned for the delegated token. */\n readonly principal: P;\n /** The session's delegated token (verified as signed; its meaning is the tenant's). */\n readonly token: string;\n readonly params: ParamsOf<K, 'path'>;\n readonly query: ParamsOf<K, 'query'>;\n readonly body: ToolBody<K>;\n /** The informational headers Vinaverse sends (not signed). */\n readonly session: {\n readonly id?: string;\n readonly conversationId?: string;\n readonly toolCallId?: string;\n readonly requestId?: string;\n };\n readonly idempotencyKey?: string;\n}\n\n/**\n * A handler per served operation; one the tenant does not serve answers 404.\n * Handlers validate what they act on: the toolkit checks the call's origin and\n * shape, not the meaning of its values. A `submit_flow` handler refuses only\n * with `ToolRefusal.flowRefused` (the contract's `FlowSubmissionRefusal`); any\n * other 422 from it is answered as a 500 and reported to `onError`.\n */\nexport type ToolHandlers<P> = {\n [K in ToolOperationId]?: (\n call: ToolCall<K, P>,\n ) => K extends 'submit_flow'\n ? Accepting\n : Promise<ToolResult<K>> | ToolResult<K>;\n};\n\n// A submission handler that accepts may return nothing: `{ ok: true }` is sent.\ntype Accepted = ToolResult<'submit_flow'>;\n// biome-ignore lint/suspicious/noConfusingVoidType: an accepting handler returns nothing\ntype Accepting = Promise<void | Accepted> | void | Accepted;\n\nexport interface ToolProviderOptions<P> {\n /** The tool signing secret, or two during a rotation. */\n secret: string | readonly string[];\n /** Where nonces are taken: shared by every instance (`@vinaverse/server/stores`). */\n nonces: NonceStore;\n /** Where idempotent answers are kept: shared by every instance. */\n idempotency: IdempotencyStore;\n /**\n * The path of the tool base URL registered in Studio (`/api/v2/ai` for\n * `https://tenant.example.com/api/v2/ai`); routes are matched below it.\n */\n basePath?: string;\n /**\n * Resolves the delegated token to the tenant's principal (the person and\n * what the token lets them do). Throw `ToolRefusal.tokenExpired()` for a\n * token that is not valid.\n */\n authenticate(token: string, operation: ToolOperationId): Promise<P> | P;\n handlers: ToolHandlers<P>;\n /**\n * For `create_proposal`: the stored proposal's current state, read again on\n * a replay (the contract returns its current `status`). Default: as stored.\n */\n currentProposal?(\n stored: ToolResult<'create_proposal'>,\n principal: P,\n ): Promise<ToolResult<'create_proposal'>> | ToolResult<'create_proposal'>;\n /**\n * An error the toolkit answered with a 500 (a handler's, a result over its\n * limit, a refusal the contract does not allow), or one it worked around (an\n * answer it could not store).\n */\n onError?(error: unknown, operation: ToolOperationId | undefined): void;\n /**\n * A call whose signature was refused, with the reason (`stale`, `mismatch`,\n * `replayed`, …): the 403 itself says only that the signature was refused.\n */\n onRefused?(reason: ToolSignatureErrorCode, message: string): void;\n /**\n * Scopes idempotent answers, for example to the tenant or environment of the\n * principal: a stored answer is replayed only to a call with the same scope.\n */\n scope?(principal: P, operation: ToolOperationId): string;\n /**\n * How long a running call holds its idempotency key, in seconds; default 60.\n * Set it above the longest your handlers can run: a resend after it lapses\n * runs the handler again.\n */\n leaseSeconds?: number;\n /** The largest request body accepted, in bytes; default 1 MiB. */\n maxRequestBytes?: number;\n toleranceSeconds?: number;\n now?: () => Date;\n}\n\nexport interface ToolRequest {\n method: string;\n /** The request target exactly as received: path and query, percent-escaped. */\n target: string;\n /** Header lookup by name, any case. */\n header(name: string): string | undefined;\n body: string | Uint8Array | ArrayBuffer | null | undefined;\n}\n\nexport interface ToolResponse {\n readonly status: number;\n readonly headers: Readonly<Record<string, string>>;\n readonly body: string;\n}\n\n/** The result of a submission that a handler accepted. */\nconst ACCEPTED = { ok: true } as const;\n\n/** How long idempotent answers are kept (seconds), and a pending call holds its key. */\nexport const KEEP_SECONDS = {\n submit_flow: 31 * 86_400, // a conversation lives up to 30 days, and a submission is resent in later sessions\n create_proposal: 8 * 86_400, // at least until the proposal expires (at most 7 days)\n default: 86_400,\n pending: 60,\n} as const;\n\n/** The longest `Idempotency-Key` the contract allows. */\nconst MAX_IDEMPOTENCY_KEY = 255;\n\nexport const MAX_REQUEST_BYTES = 1024 * 1024;\n\n/** A run's idempotency lease lapsed and another run took the key: its answer was sent but not stored. */\nexport class LeaseLostError extends Error {\n constructor(operation: ToolOperationId, leaseSeconds: number) {\n super(\n `${operation} ran longer than its ${leaseSeconds}-second idempotency lease and another call took the key: the answer was sent but not stored (raise leaseSeconds)`,\n );\n this.name = 'LeaseLostError';\n }\n}\n\nexport class ResultTooLargeError extends Error {\n constructor(operation: ToolOperationId, bytes: number, limit: number) {\n super(\n `${operation} returned ${bytes} bytes; the contract allows ${limit}: the runtime would refuse it`,\n );\n this.name = 'ResultTooLargeError';\n }\n}\n\ninterface Route {\n id: ToolOperationId;\n segments: readonly string[];\n}\n\nexport interface ToolProvider {\n handle(request: ToolRequest): Promise<ToolResponse>;\n}\n\nexport function createToolProvider<P>(\n options: ToolProviderOptions<P>,\n): ToolProvider {\n const secrets =\n typeof options.secret === 'string' ? [options.secret] : [...options.secret];\n if (\n secrets.length === 0 ||\n secrets.some((s) => typeof s !== 'string' || !s)\n ) {\n throw new TypeError('createToolProvider needs the tool signing secret');\n }\n checkTolerance(options.toleranceSeconds);\n const maxRequest = options.maxRequestBytes;\n if (\n maxRequest !== undefined &&\n (!Number.isSafeInteger(maxRequest) || maxRequest <= 0)\n ) {\n throw new TypeError(\n `maxRequestBytes must be a positive whole number of bytes, not ${maxRequest}`,\n );\n }\n const lease = options.leaseSeconds ?? KEEP_SECONDS.pending;\n if (!Number.isFinite(lease) || lease <= 0) {\n throw new TypeError(\n `leaseSeconds must be a positive number of seconds, not ${options.leaseSeconds}`,\n );\n }\n if (typeof options.authenticate !== 'function') {\n throw new TypeError(\n 'createToolProvider needs authenticate: it resolves the delegated token',\n );\n }\n const base = (options.basePath ?? '').replace(/\\/+$/, '');\n const routes: Route[] = Object.values(TOOL_OPERATIONS).map((o) => ({\n id: o.id,\n segments: o.path.split('/').filter(Boolean),\n }));\n\n async function handle(request: ToolRequest): Promise<ToolResponse> {\n const raw = request.body ?? new Uint8Array(0);\n const body = toBytes(raw);\n if (body.length > (options.maxRequestBytes ?? MAX_REQUEST_BYTES)) {\n return problem({\n status: 413,\n code: 'invalid_argument',\n detail: 'the request body is too large',\n });\n }\n const token = bearer(request.header('authorization'));\n if (!token) {\n return problem({\n status: 401,\n code: 'token_expired',\n detail: 'no delegated token (Authorization: Bearer)',\n });\n }\n const refused = await verifyToolCall(\n {\n method: request.method,\n target: request.target,\n token,\n body,\n header: request.header('vinaverse-signature'),\n },\n {\n secrets,\n nonces: options.nonces,\n now: options.now?.() ?? new Date(),\n ...(options.toleranceSeconds === undefined\n ? {}\n : { toleranceSeconds: options.toleranceSeconds }),\n },\n );\n if (refused) {\n options.onRefused?.(refused.code, refused.message);\n return problem({\n status: 403,\n code: 'forbidden',\n detail: 'the signature was refused',\n });\n }\n const matched = match(request.method, request.target);\n if (!matched)\n return problem({\n status: 404,\n code: 'not_found',\n detail: 'no such tool',\n });\n const { id, params, query } = matched;\n const operation = TOOL_OPERATIONS[id];\n const handler = options.handlers[id] as\n | ((call: ToolCall<ToolOperationId, P>) => unknown)\n | undefined;\n if (!handler)\n return problem({\n status: 404,\n code: 'not_found',\n detail: `${id} is not served here`,\n });\n try {\n const principal = await options.authenticate(token, id);\n const typedQuery = readQuery(id, query);\n const parsed = operation.body ? parseBody(body) : undefined;\n const key = request.header('idempotency-key');\n if (operation.idempotencyKey && !key) {\n throw ToolRefusal.invalidArgument({\n detail: 'the Idempotency-Key header is required',\n });\n }\n if (key && key.length > MAX_IDEMPOTENCY_KEY) {\n throw ToolRefusal.invalidArgument({\n detail: `the Idempotency-Key is longer than ${MAX_IDEMPOTENCY_KEY} characters`,\n });\n }\n const call: ToolCall<ToolOperationId, P> = {\n operation: id,\n principal,\n token,\n params: params as never,\n query: typedQuery as never,\n body: parsed as never,\n session: session(request),\n ...(key ? { idempotencyKey: key } : {}),\n };\n const run = () => runHandler(id, handler, call);\n const scope = options.scope?.(principal, id);\n const keyOf = (...parts: string[]) =>\n (scope === undefined ? parts : [scope, ...parts])\n .map(encodeURIComponent)\n .join(':');\n if (id === 'submit_flow')\n return await submission(keyOf, params, parsed, run);\n if (id === 'create_proposal' && key)\n return await proposal(keyOf(id, key), parsed, principal, run);\n if (operation.idempotencyKey && key) {\n return await keyed(\n id,\n keyOf(id, key),\n await fingerprint(parsed),\n KEEP_SECONDS.default,\n run,\n () =>\n problem({\n status: 409,\n code: 'IDEMPOTENCY_KEY_REUSED',\n detail: 'this Idempotency-Key was used with another body',\n }),\n );\n }\n return await run();\n } catch (error) {\n return failure(error, id);\n }\n }\n\n async function runHandler(\n id: ToolOperationId,\n handler: (call: ToolCall<ToolOperationId, P>) => unknown,\n call: ToolCall<ToolOperationId, P>,\n ): Promise<ToolResponse> {\n const result =\n (await handler(call)) ?? (id === 'submit_flow' ? ACCEPTED : undefined);\n if (result === undefined) {\n throw new TypeError(`the ${id} handler returned nothing`);\n }\n const text = JSON.stringify(result);\n const limit = TOOL_OPERATIONS[id].maxResultBytes;\n const bytes = toBytes(text).length;\n if (bytes > limit) throw new ResultTooLargeError(id, bytes, limit);\n return json(TOOL_OPERATIONS[id].successStatus, text);\n }\n\n // The answer for an idempotent call: run once per key, then the stored\n // answer for the same fingerprint, a conflict for another. A success and the\n // refusals `keeps` accepts (by default a 422: an invalid argument, the call's\n // outcome) are kept; any other failure releases the key so a retry runs\n // again. The run holds the key with a lease tied to it (`owner`): it can\n // neither store over nor release a lease another run took after it lapsed.\n async function keyed(\n id: ToolOperationId,\n key: string,\n print: string,\n keepSeconds: number,\n run: () => Promise<ToolResponse>,\n conflict: (held: IdempotencyRecord) => ToolResponse | Promise<ToolResponse>,\n replay?: (held: IdempotencyRecord) => ToolResponse | Promise<ToolResponse>,\n keeps: (refusal: ToolRefusal) => boolean = (r) => r.status === 422,\n ): Promise<ToolResponse> {\n const store = options.idempotency;\n const owner = await ownerToken();\n const held = await store.start(key, print, lease, owner);\n if (held) {\n if (held.state === 'pending') {\n return problem({\n status: 503,\n code: 'unavailable',\n detail: 'the same call is still running',\n });\n }\n if (held.fingerprint !== print) return conflict(held);\n return replay ? replay(held) : stored(held);\n }\n let response: ToolResponse;\n try {\n response = await run();\n } catch (error) {\n if (!(error instanceof ToolRefusal && keeps(error))) {\n await store.release(key, owner);\n throw error;\n }\n response = problem(error.problem);\n }\n // The answer stands whether or not it is stored: the work is done.\n try {\n const kept = await store.finish(\n key,\n { fingerprint: print, status: response.status, body: response.body },\n keepSeconds,\n owner,\n );\n if (!kept) options.onError?.(new LeaseLostError(id, lease), id);\n } catch (error) {\n options.onError?.(error, id);\n }\n return response;\n }\n\n async function submission(\n keyOf: (...parts: string[]) => string,\n params: Record<string, string>,\n body: unknown,\n run: () => Promise<ToolResponse>,\n ): Promise<ToolResponse> {\n const submissionId = (body as { submission_id?: unknown } | undefined)\n ?.submission_id;\n if (typeof submissionId !== 'string' || submissionId === '') {\n throw ToolRefusal.invalidArgument({\n field: '/submission_id',\n detail: 'a submission needs its submission_id',\n });\n }\n // Only a FlowSubmissionRefusal is a submission's outcome to keep; any other\n // 422 is a handler's mistake the contract has no shape for.\n const refused = async () => {\n try {\n return await run();\n } catch (error) {\n if (\n error instanceof ToolRefusal &&\n error.status === 422 &&\n !isFlowRefusal(error.problem)\n ) {\n throw new TypeError(\n `submit_flow refused with ${error.problem.code}: a submission is refused only with ToolRefusal.flowRefused (a flow code and the question to ask again)`,\n );\n }\n throw error;\n }\n };\n return keyed(\n 'submit_flow',\n keyOf('submit_flow', params.flow ?? '', submissionId),\n await fingerprint(body),\n KEEP_SECONDS.submit_flow,\n refused,\n (held) => {\n const was = held.body\n ? (JSON.parse(held.body) as Partial<ProblemBody>)\n : {};\n const storedResult =\n held.status === 200\n ? { result: 'accepted' }\n : {\n result: 'refused',\n ...(was.code ? { code: was.code } : {}),\n ...(was.question_id ? { question_id: was.question_id } : {}),\n };\n return json(\n 409,\n JSON.stringify({\n status: 409,\n code: 'SUBMISSION_ID_REUSED',\n stored: storedResult,\n }),\n 'application/problem+json',\n );\n },\n undefined,\n (r) => isFlowRefusal(r.problem),\n );\n }\n\n async function proposal(\n key: string,\n body: unknown,\n principal: P,\n run: () => Promise<ToolResponse>,\n ): Promise<ToolResponse> {\n const { topic, changes } = (body ?? {}) as {\n topic?: unknown;\n changes?: unknown;\n };\n const current = async (held: IdempotencyRecord) => {\n const storedProposal = JSON.parse(\n held.body ?? 'null',\n ) as ToolResult<'create_proposal'>;\n return options.currentProposal\n ? await options.currentProposal(storedProposal, principal)\n : storedProposal;\n };\n return keyed(\n 'create_proposal',\n key,\n await fingerprint({ topic, changes }),\n KEEP_SECONDS.create_proposal,\n run,\n async (held) =>\n held.status === 201\n ? json(\n 409,\n JSON.stringify({\n status: 409,\n code: 'IDEMPOTENCY_KEY_REUSED',\n proposal: await current(held),\n }),\n 'application/problem+json',\n )\n : stored(held),\n async (held) =>\n held.status === 201\n ? json(201, JSON.stringify(await current(held)))\n : stored(held),\n );\n }\n\n function match(\n method: string,\n target: string,\n ):\n | {\n id: ToolOperationId;\n params: Record<string, string>;\n query: URLSearchParams;\n }\n | undefined {\n const at = target.indexOf('?');\n const path = at < 0 ? target : target.slice(0, at);\n const query = new URLSearchParams(at < 0 ? '' : target.slice(at + 1));\n if (base && path !== base && !path.startsWith(`${base}/`)) return undefined;\n const segments = path.slice(base.length).split('/').filter(Boolean);\n for (const route of routes) {\n if (TOOL_OPERATIONS[route.id].method !== method.toUpperCase()) continue;\n if (route.segments.length !== segments.length) continue;\n const params: Record<string, string> = {};\n let ok = true;\n for (const [i, part] of route.segments.entries()) {\n const actual = segments[i] as string;\n if (part.startsWith('{') && part.endsWith('}')) {\n try {\n params[part.slice(1, -1)] = decodeURIComponent(actual);\n } catch {\n ok = false;\n }\n } else if (part !== actual) {\n ok = false;\n }\n if (!ok) break;\n }\n if (ok) return { id: route.id, params, query };\n }\n return undefined;\n }\n\n function failure(\n error: unknown,\n id: ToolOperationId | undefined,\n ): ToolResponse {\n if (error instanceof ToolRefusal) return problem(error.problem);\n options.onError?.(error, id);\n return problem({\n status: 500,\n code: 'unavailable',\n detail: 'the tool failed',\n });\n }\n\n return { handle };\n}\n\nfunction readQuery(\n id: ToolOperationId,\n query: URLSearchParams,\n): Record<string, unknown> {\n const declared = TOOL_OPERATIONS[id].queryParams as Record<\n string,\n { type: string; required: boolean }\n >;\n const out: Record<string, unknown> = {};\n for (const [name, spec] of Object.entries(declared)) {\n const value = query.get(name);\n if (value === null) {\n if (spec.required)\n throw ToolRefusal.invalidArgument({\n detail: `the query parameter ${name} is required`,\n });\n continue;\n }\n if (spec.type === 'integer' || spec.type === 'number') {\n const n = Number(value);\n if (\n value.trim() === '' ||\n !Number.isFinite(n) ||\n (spec.type === 'integer' && !Number.isInteger(n))\n ) {\n throw ToolRefusal.invalidArgument({\n detail: `the query parameter ${name} must be ${spec.type === 'integer' ? 'an integer' : 'a number'}`,\n });\n }\n out[name] = n;\n } else {\n out[name] = value;\n }\n }\n return out;\n}\n\nfunction parseBody(body: Uint8Array): unknown {\n if (body.length === 0)\n throw ToolRefusal.invalidArgument({\n detail: 'the request needs a JSON body',\n });\n try {\n return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(body));\n } catch {\n throw ToolRefusal.invalidArgument({\n detail: 'the request body is not JSON',\n });\n }\n}\n\nfunction bearer(value: string | undefined): string | undefined {\n const m = /^Bearer\\s+(\\S+)\\s*$/i.exec(value ?? '');\n return m?.[1];\n}\n\nfunction session(\n request: ToolRequest,\n): ToolCall<ToolOperationId, unknown>['session'] {\n const pick = (name: string) => request.header(name);\n const entries = {\n id: pick('vinaverse-session') ?? pick('vinaverse-session-id'),\n conversationId: pick('vinaverse-conversation'),\n toolCallId: pick('vinaverse-tool-call-id'),\n requestId: pick('vinaverse-request-id'),\n };\n return Object.fromEntries(\n Object.entries(entries).filter(([, v]) => v !== undefined),\n );\n}\n\n/** A random token tying an idempotency lease to the run that holds it. */\nasync function ownerToken(): Promise<string> {\n const bytes = (await webCrypto()).getRandomValues(new Uint8Array(16));\n return [...bytes].map((b) => b.toString(16).padStart(2, '0')).join('');\n}\n\nfunction json(\n status: number,\n body: string,\n type = 'application/json',\n): ToolResponse {\n return { status, headers: { 'content-type': type }, body };\n}\n\nfunction problem(body: ProblemBody): ToolResponse {\n return json(body.status, JSON.stringify(body), 'application/problem+json');\n}\n\nfunction stored(held: IdempotencyRecord): ToolResponse {\n const status = held.status ?? 200;\n return json(\n status,\n held.body ?? '',\n status >= 400 ? 'application/problem+json' : 'application/json',\n );\n}\n","// The ordering rule for conversation states (contract:\n// docs/conversation-state.md §3 and §4; vectors: vinaverse-contracts\n// conformance/webhook-sequence.json, whose words these are). Deliveries are at\n// least once and in no set order:\n// - deduplicate on the envelope's `id` (`duplicate`);\n// - keep, per conversation, the state with the highest `sequence`; one with an\n// equal or lower `sequence` is old news (`stale`), even under a new envelope id;\n// - a gap means deliveries still to come: apply the higher state anyway, the\n// missing ones then arrive stale;\n// - a state with `answers_omitted: true` updates every other field and keeps\n// the `answers` and `remarks` held; read the full state afterwards\n// (`GET /v1/conversations/{conversation_id}`);\n// - a Studio test delivery (`data.test: true`) carries no state (`skip_test`).\n//\n// The pure functions work on a record the tenant stores per conversation;\n// `ConversationReceiver` keeps the records and the ids in memory, for one\n// process and for tests.\nimport type { ConversationEvent } from './events.js';\n\n/** The fields of a conversation state the rule reads. */\nexport interface SequencedState {\n readonly conversation_id: string;\n readonly sequence: number;\n readonly answers_omitted?: boolean;\n readonly answers?: unknown;\n readonly remarks?: unknown;\n}\n\n/** What a tenant keeps per conversation: the state held, and what it knows about the deliveries. */\nexport interface ConversationRecord<S extends SequencedState = SequencedState> {\n /** The newest state, with the answers and remarks merged in when a delivery left them out. */\n readonly state: S;\n /** Every `sequence` a delivery carried for this conversation, ascending. */\n readonly seen: readonly number[];\n /** The last applied state left out its answers: read the full state. */\n readonly fullReadNeeded: boolean;\n}\n\nexport type SequenceAction = 'apply' | 'stale';\nexport type DeliveryAction = SequenceAction | 'duplicate' | 'skip_test';\n\n/** Apply a state only above the one held: an equal or lower `sequence` is stale. */\nexport function sequenceVerdict(\n held: Pick<SequencedState, 'conversation_id' | 'sequence'> | null | undefined,\n incoming: Pick<SequencedState, 'conversation_id' | 'sequence'>,\n): SequenceAction {\n if (held && held.conversation_id !== incoming.conversation_id) {\n throw new TypeError(\n `the states belong to different conversations (${held.conversation_id}, ${incoming.conversation_id})`,\n );\n }\n return held && incoming.sequence <= held.sequence ? 'stale' : 'apply';\n}\n\n/**\n * Applies one conversation state to the record held for its conversation (or\n * none) and returns the record to keep and what happened. A stale state\n * changes nothing but `seen`. An applied state with `answers_omitted: true` is\n * kept without that flag, with the `answers` and `remarks` held (or none), and\n * `fullReadNeeded` set.\n */\nexport function applyConversationState<S extends SequencedState>(\n record: ConversationRecord<S> | null | undefined,\n incoming: S,\n): { record: ConversationRecord<S>; action: SequenceAction } {\n const action = sequenceVerdict(record?.state, incoming);\n const seen = record?.seen.includes(incoming.sequence)\n ? record.seen\n : [...(record?.seen ?? []), incoming.sequence].sort((a, b) => a - b);\n if (action === 'stale' && record)\n return { record: { ...record, seen }, action };\n if (incoming.answers_omitted === true) {\n const { answers_omitted: _omitted, ...rest } = incoming;\n const state = {\n ...rest,\n answers: record?.state.answers ?? [],\n remarks: record?.state.remarks ?? {},\n } as unknown as S;\n return { record: { state, seen, fullReadNeeded: true }, action };\n }\n return { record: { state: incoming, seen, fullReadNeeded: false }, action };\n}\n\n/**\n * The sequences still to come for a conversation: above the lowest one a\n * delivery carried and below the one held, that no delivery has carried yet.\n * Wait for them, or read the full state.\n */\nexport function missingSequences(record: ConversationRecord): number[] {\n const [lowest] = record.seen;\n if (lowest === undefined) return [];\n const missing: number[] = [];\n for (let s = lowest + 1; s < record.state.sequence; s++) {\n if (!record.seen.includes(s)) missing.push(s);\n }\n return missing;\n}\n\ntype ConversationData = ConversationEvent['data'];\n\n/**\n * The rule over a stream of verified deliveries, in memory: envelope ids seen,\n * and a record per conversation. For one process and for tests; a tenant\n * behind several instances keeps the ids and the records in its database and\n * calls `applyConversationState` itself.\n */\nexport class ConversationReceiver {\n readonly #ids = new Set<string>();\n readonly #records = new Map<string, ConversationRecord<ConversationData>>();\n\n /**\n * One verified delivery (an event, or a Studio test delivery's envelope):\n * what to do with it. The record for its conversation is then `record(id)`.\n */\n receive(delivery: {\n readonly id: string;\n readonly data: unknown;\n }): DeliveryAction {\n if (this.#ids.has(delivery.id)) return 'duplicate';\n this.#ids.add(delivery.id);\n const data = delivery.data as {\n test?: unknown;\n conversation_id?: unknown;\n } | null;\n if (data?.test === true) return 'skip_test';\n if (typeof data?.conversation_id !== 'string') {\n throw new TypeError(`${delivery.id} carries no conversation state`);\n }\n const state = data as ConversationData;\n const { record, action } = applyConversationState(\n this.#records.get(state.conversation_id),\n state,\n );\n this.#records.set(state.conversation_id, record);\n return action;\n }\n\n record(\n conversationId: string,\n ): ConversationRecord<ConversationData> | undefined {\n return this.#records.get(conversationId);\n }\n\n conversations(): string[] {\n return [...this.#records.keys()].sort();\n }\n}\n"]}