@vinaverse/server 0.1.0-alpha.21 → 0.1.0-alpha.22
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.
- package/README.md +6 -4
- package/dist/api.cjs +42 -0
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.cts +41 -1
- package/dist/api.d.ts +41 -1
- package/dist/api.js +42 -0
- package/dist/api.js.map +1 -1
- package/dist/express.d.cts +2 -2
- package/dist/express.d.ts +2 -2
- package/dist/fastify.d.cts +2 -2
- package/dist/fastify.d.ts +2 -2
- package/dist/hono.d.cts +2 -2
- package/dist/hono.d.ts +2 -2
- package/dist/index.cjs +14 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +14 -2
- package/dist/index.js.map +1 -1
- package/dist/lambda.d.cts +2 -2
- package/dist/lambda.d.ts +2 -2
- package/dist/{provider-1SsRbyN-.d.ts → provider-DsFlhWPu.d.ts} +92 -2
- package/dist/{provider-DhsUFcqq.d.cts → provider-PSwJ554B.d.cts} +92 -2
- package/dist/{vinaverse-v1.d-D-NPpZqW.d.cts → vinaverse-v1.d-C3ZVGBVA.d.cts} +469 -22
- package/dist/{vinaverse-v1.d-D-NPpZqW.d.ts → vinaverse-v1.d-C3ZVGBVA.d.ts} +469 -22
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { T as ToolProvider, W as WebhookHandlerOptions, C as ConversationEvent, a as WebhookError, R as ReadBody } from './provider-
|
|
2
|
-
export { b as ConversationEventType, c as ConversationState, K as KEEP_SECONDS, L as LeaseLostError, M as MAX_REQUEST_BYTES, d as ResultTooLargeError, e as TOOL_OPERATIONS, f as ToolBody, g as ToolCall, h as ToolContractComponents, o as ToolContractOperations, i as ToolHandlers, j as ToolOperationId, k as ToolProviderOptions, l as ToolRequest, m as ToolResponse, n as ToolResult, p as ToolSignatureError, q as ToolSignatureErrorCode, r as WEBHOOK_EVENT_TYPES, s as WebhookEnvelope, t as WebhookErrorCode, u as WebhookEvent, v as WebhookEventOf, w as WebhookEventType, x as WebhookResponse, y as createToolProvider, z as isConversationEvent, A as verifyToolCall } from './provider-
|
|
3
|
-
export { c as ContractComponents, w as ContractWebhooks } from './vinaverse-v1.d-
|
|
1
|
+
import { T as ToolProvider, W as WebhookHandlerOptions, C as ConversationEvent, a as WebhookError, R as ReadBody } from './provider-PSwJ554B.cjs';
|
|
2
|
+
export { b as ConversationEventType, c as ConversationState, K as KEEP_SECONDS, L as LeaseLostError, M as MAX_REQUEST_BYTES, d as ResultTooLargeError, e as TOOL_OPERATIONS, f as ToolBody, g as ToolCall, h as ToolContractComponents, o as ToolContractOperations, i as ToolHandlers, j as ToolOperationId, k as ToolProviderOptions, l as ToolRequest, m as ToolResponse, n as ToolResult, p as ToolSignatureError, q as ToolSignatureErrorCode, r as WEBHOOK_EVENT_TYPES, s as WebhookEnvelope, t as WebhookErrorCode, u as WebhookEvent, v as WebhookEventOf, w as WebhookEventType, x as WebhookResponse, y as createToolProvider, z as isConversationEvent, A as verifyToolCall } from './provider-PSwJ554B.cjs';
|
|
3
|
+
export { c as ContractComponents, w as ContractWebhooks } from './vinaverse-v1.d-C3ZVGBVA.cjs';
|
|
4
4
|
export { I as IdempotencyRecord, a as IdempotencyStore, M as MemoryIdempotencyStore, b as MemoryNonceStore, N as NONCE_KEEP_SECONDS, c as NonceStore, d as canonicalJson, f as fingerprint } from './nonces-scwljZwl.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -22,8 +22,8 @@ declare function createFetchToolHandler(provider: ToolProvider, options?: {
|
|
|
22
22
|
}): (request: Request) => Promise<Response>;
|
|
23
23
|
|
|
24
24
|
declare const CONTRACT: {
|
|
25
|
-
readonly api: "v1-draft.
|
|
26
|
-
readonly commit: "
|
|
25
|
+
readonly api: "v1-draft.48";
|
|
26
|
+
readonly commit: "36c627613e47af01f621bc6ae5fef905e826737a";
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
type ProblemCode = 'not_found' | 'forbidden' | 'invalid_argument' | 'unavailable' | 'token_expired';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { T as ToolProvider, W as WebhookHandlerOptions, C as ConversationEvent, a as WebhookError, R as ReadBody } from './provider-
|
|
2
|
-
export { b as ConversationEventType, c as ConversationState, K as KEEP_SECONDS, L as LeaseLostError, M as MAX_REQUEST_BYTES, d as ResultTooLargeError, e as TOOL_OPERATIONS, f as ToolBody, g as ToolCall, h as ToolContractComponents, o as ToolContractOperations, i as ToolHandlers, j as ToolOperationId, k as ToolProviderOptions, l as ToolRequest, m as ToolResponse, n as ToolResult, p as ToolSignatureError, q as ToolSignatureErrorCode, r as WEBHOOK_EVENT_TYPES, s as WebhookEnvelope, t as WebhookErrorCode, u as WebhookEvent, v as WebhookEventOf, w as WebhookEventType, x as WebhookResponse, y as createToolProvider, z as isConversationEvent, A as verifyToolCall } from './provider-
|
|
3
|
-
export { c as ContractComponents, w as ContractWebhooks } from './vinaverse-v1.d-
|
|
1
|
+
import { T as ToolProvider, W as WebhookHandlerOptions, C as ConversationEvent, a as WebhookError, R as ReadBody } from './provider-DsFlhWPu.js';
|
|
2
|
+
export { b as ConversationEventType, c as ConversationState, K as KEEP_SECONDS, L as LeaseLostError, M as MAX_REQUEST_BYTES, d as ResultTooLargeError, e as TOOL_OPERATIONS, f as ToolBody, g as ToolCall, h as ToolContractComponents, o as ToolContractOperations, i as ToolHandlers, j as ToolOperationId, k as ToolProviderOptions, l as ToolRequest, m as ToolResponse, n as ToolResult, p as ToolSignatureError, q as ToolSignatureErrorCode, r as WEBHOOK_EVENT_TYPES, s as WebhookEnvelope, t as WebhookErrorCode, u as WebhookEvent, v as WebhookEventOf, w as WebhookEventType, x as WebhookResponse, y as createToolProvider, z as isConversationEvent, A as verifyToolCall } from './provider-DsFlhWPu.js';
|
|
3
|
+
export { c as ContractComponents, w as ContractWebhooks } from './vinaverse-v1.d-C3ZVGBVA.js';
|
|
4
4
|
export { I as IdempotencyRecord, a as IdempotencyStore, M as MemoryIdempotencyStore, b as MemoryNonceStore, N as NONCE_KEEP_SECONDS, c as NonceStore, d as canonicalJson, f as fingerprint } from './nonces-scwljZwl.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -22,8 +22,8 @@ declare function createFetchToolHandler(provider: ToolProvider, options?: {
|
|
|
22
22
|
}): (request: Request) => Promise<Response>;
|
|
23
23
|
|
|
24
24
|
declare const CONTRACT: {
|
|
25
|
-
readonly api: "v1-draft.
|
|
26
|
-
readonly commit: "
|
|
25
|
+
readonly api: "v1-draft.48";
|
|
26
|
+
readonly commit: "36c627613e47af01f621bc6ae5fef905e826737a";
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
type ProblemCode = 'not_found' | 'forbidden' | 'invalid_argument' | 'unavailable' | 'token_expired';
|
package/dist/index.js
CHANGED
|
@@ -7,8 +7,8 @@ export { SIGNATURE_HEADER, TOLERANCE_SECONDS, WEBHOOK_EVENT_TYPES, WebCryptoUnav
|
|
|
7
7
|
|
|
8
8
|
// src/contract.ts
|
|
9
9
|
var CONTRACT = {
|
|
10
|
-
api: "v1-draft.
|
|
11
|
-
commit: "
|
|
10
|
+
api: "v1-draft.48",
|
|
11
|
+
commit: "36c627613e47af01f621bc6ae5fef905e826737a"
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
// src/generated/tool-operations.ts
|
|
@@ -239,6 +239,18 @@ var TOOL_OPERATIONS = {
|
|
|
239
239
|
radius_miles: { type: "integer", required: false }
|
|
240
240
|
}
|
|
241
241
|
},
|
|
242
|
+
read_proposal: {
|
|
243
|
+
id: "read_proposal",
|
|
244
|
+
method: "GET",
|
|
245
|
+
path: "/proposals/{id}",
|
|
246
|
+
effect: "read",
|
|
247
|
+
maxResultBytes: 16384,
|
|
248
|
+
successStatus: 200,
|
|
249
|
+
idempotencyKey: false,
|
|
250
|
+
body: false,
|
|
251
|
+
pathParams: { id: { type: "string", required: true } },
|
|
252
|
+
queryParams: {}
|
|
253
|
+
},
|
|
242
254
|
resolve_place: {
|
|
243
255
|
id: "resolve_place",
|
|
244
256
|
method: "GET",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/contract.ts","../src/generated/tool-operations.ts","../src/tools/idempotency.ts","../src/tools/refusals.ts","../src/tools/provider.ts","../src/webhooks/sequence.ts"],"names":["fingerprint","problem"],"mappings":"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","file":"index.js","sourcesContent":["// 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.41',\n commit: '021a15c8373f892fa078ea03fabd86bf7b47348a',\n} as const;\n","// Generated by scripts/gen-tool-operations.mjs from the pinned tool-provider contract (v1-draft.16). 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","// 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","// 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/contract.ts","../src/generated/tool-operations.ts","../src/tools/idempotency.ts","../src/tools/refusals.ts","../src/tools/provider.ts","../src/webhooks/sequence.ts"],"names":["fingerprint","problem"],"mappings":"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","file":"index.js","sourcesContent":["// 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.48',\n commit: '36c627613e47af01f621bc6ae5fef905e826737a',\n} as const;\n","// Generated by scripts/gen-tool-operations.mjs from the pinned tool-provider contract (v1-draft.19). 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 read_proposal: {\n id: 'read_proposal',\n method: 'GET',\n path: '/proposals/{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 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","// 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","// 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"]}
|
package/dist/lambda.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as ToolProvider, W as WebhookHandlerOptions } from './provider-
|
|
2
|
-
import './vinaverse-v1.d-
|
|
1
|
+
import { T as ToolProvider, W as WebhookHandlerOptions } from './provider-PSwJ554B.cjs';
|
|
2
|
+
import './vinaverse-v1.d-C3ZVGBVA.cjs';
|
|
3
3
|
import './nonces-scwljZwl.cjs';
|
|
4
4
|
|
|
5
5
|
/** The fields of an API Gateway (v1 or v2) or function URL event the handler reads. */
|
package/dist/lambda.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as ToolProvider, W as WebhookHandlerOptions } from './provider-
|
|
2
|
-
import './vinaverse-v1.d-
|
|
1
|
+
import { T as ToolProvider, W as WebhookHandlerOptions } from './provider-DsFlhWPu.js';
|
|
2
|
+
import './vinaverse-v1.d-C3ZVGBVA.js';
|
|
3
3
|
import './nonces-scwljZwl.js';
|
|
4
4
|
|
|
5
5
|
/** The fields of an API Gateway (v1 or v2) or function URL event the handler reads. */
|