@pliuz/sdk 0.2.1 → 0.2.2

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/CHANGELOG.md CHANGED
@@ -5,6 +5,30 @@ All notable changes to `@pliuz/sdk` (TypeScript SDK) are documented in this file
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.2] — 2026-06-13
9
+
10
+ Ships the F2 long-poll that landed in the repo *after* the 0.2.1 tag, plus Vercel AI
11
+ adapter and redaction hardening from the architecture-closure pass.
12
+
13
+ ### Added
14
+
15
+ - **Long-poll decision delivery (F2).** `gated()` now waits on
16
+ `GET /approvals/:id?wait=` (up to 25s server-side), cutting polling volume ~12x. The
17
+ code existed in the repo but was committed after the 0.2.1 tag, so
18
+ `npm install @pliuz/sdk` did not include it until now.
19
+ - **Strict redaction mode (D13).** `gated({ ..., redactStrict: true })` and
20
+ `applyRedaction(payload, paths, true)` throw `PliuzRedactionPathError` when a path
21
+ matches no field, instead of silently leaving it unredacted. The default stays lenient.
22
+
23
+ ### Fixed / Changed (behavior changes)
24
+
25
+ - **Vercel AI adapter `toolName` is now required (D14).** `gatedTool` no longer derives
26
+ the Pliuz tool name from the tool's prose `description` — a copy edit silently
27
+ re-routed approvals. Pass `toolName` explicitly; a missing/blank value throws.
28
+ - **Vercel AI adapter concurrency fix (D14).** Execution `options` are now captured
29
+ per-call instead of via a shared mutable holder that cross-talked between concurrent
30
+ tool invocations.
31
+
8
32
  ## [0.2.1] — 2026-06-12
9
33
 
10
34
  Identical in content to 0.2.0 (below), which never reached npm — its release
package/README.md CHANGED
@@ -222,7 +222,7 @@ import { z } from 'zod'
222
222
  import { gatedTool } from '@pliuz/sdk/adapters/ai'
223
223
 
224
224
  const issueRefund = gatedTool(
225
- { policy: 'refund', redact: ['customer.ssn'] },
225
+ { toolName: 'issue_refund', policy: 'refund', redact: ['customer.ssn'] },
226
226
  tool({
227
227
  description: 'Issue a refund to a customer',
228
228
  parameters: z.object({
@@ -297,6 +297,18 @@ const refund = gated(
297
297
  )
298
298
  ```
299
299
 
300
+ ### Decision latency (long-poll)
301
+
302
+ `gated()` waits for the human decision via **server long-poll**: each wait call
303
+ holds the connection open up to ~25s and returns the instant the approval is
304
+ decided. You get near-zero decision-delivery latency and ~12x fewer requests
305
+ than fixed-interval polling — no configuration needed. `pollIntervalMs` now
306
+ just caps the per-call wait window. The low-level client exposes it directly:
307
+
308
+ ```typescript
309
+ const a = await pliuz.getApproval(id, 25) // long-poll up to 25s
310
+ ```
311
+
300
312
  ### Custom timeouts per call
301
313
 
302
314
  - **Live user-facing**: `timeoutMs: 30_000`
@@ -5,7 +5,7 @@ var crypto = require('crypto');
5
5
  // src/gated.ts
6
6
 
7
7
  // src/version.ts
8
- var VERSION = "0.2.1";
8
+ var VERSION = "0.2.2";
9
9
 
10
10
  // src/errors.ts
11
11
  var PliuzError = class extends Error {
@@ -24,6 +24,17 @@ var PliuzNetworkError = class extends PliuzError {
24
24
  }
25
25
  cause;
26
26
  };
27
+ var PliuzRedactionPathError = class extends PliuzError {
28
+ constructor(path) {
29
+ super(
30
+ `redaction path '${path}' did not match any field in the payload (strict mode). Fix the path or set redactStrict=false to ignore misses.`
31
+ );
32
+ this.path = path;
33
+ this.name = "PliuzRedactionPathError";
34
+ Object.setPrototypeOf(this, new.target.prototype);
35
+ }
36
+ path;
37
+ };
27
38
  var PliuzTimeoutError = class extends PliuzError {
28
39
  constructor(message) {
29
40
  super(message);
@@ -278,6 +289,7 @@ function approvalUrl(baseUrl, approvalId, suffix) {
278
289
  if (suffix) path += `/${suffix}`;
279
290
  return baseUrl + path;
280
291
  }
292
+ var MAX_WAIT_SECONDS = 25;
281
293
  var PliuzClient = class {
282
294
  apiKey;
283
295
  baseUrl;
@@ -327,13 +339,22 @@ var PliuzClient = class {
327
339
  /**
328
340
  * Fetch the current state of an approval request.
329
341
  * Used by polling in `gated()` to detect status transitions.
342
+ *
343
+ * Pass `waitSeconds` (1..25) to long-poll: the server holds the request
344
+ * open and returns the instant the approval stops being `pending`, or after
345
+ * `waitSeconds` (still pending). Cuts polling volume and decision latency
346
+ * ~12x vs fixed-interval polling. The per-request HTTP timeout is bumped to
347
+ * cover the wait window.
330
348
  */
331
- async getApproval(approvalId) {
349
+ async getApproval(approvalId, waitSeconds) {
350
+ const wait = waitSeconds && waitSeconds > 0 ? Math.min(Math.floor(waitSeconds), MAX_WAIT_SECONDS) : 0;
351
+ const url = wait > 0 ? `${approvalUrl(this.baseUrl, approvalId)}?wait=${wait}` : approvalUrl(this.baseUrl, approvalId);
332
352
  return request({
333
353
  method: "GET",
334
- url: approvalUrl(this.baseUrl, approvalId),
354
+ url,
335
355
  apiKey: this.apiKey,
336
- timeoutMs: this.timeoutMs,
356
+ // Give the socket head-room over the server-side wait window.
357
+ timeoutMs: wait > 0 ? Math.max(this.timeoutMs, wait * 1e3 + 5e3) : this.timeoutMs,
337
358
  maxRetries: this.maxRetries,
338
359
  fetchImpl: this.fetchImpl
339
360
  });
@@ -366,13 +387,16 @@ var PliuzClient = class {
366
387
 
367
388
  // src/redaction.ts
368
389
  var REDACTED_PLACEHOLDER = "<redacted>";
369
- function applyRedaction(payload, paths) {
390
+ function applyRedaction(payload, paths, strict = false) {
370
391
  if (!paths || paths.length === 0) {
371
392
  return deepClone(payload);
372
393
  }
373
394
  const result = deepClone(payload);
374
395
  for (const path of paths) {
375
- redactPath(result, parsePath(path));
396
+ const matched = redactPath(result, parsePath(path));
397
+ if (strict && !matched) {
398
+ throw new PliuzRedactionPathError(path);
399
+ }
376
400
  }
377
401
  return result;
378
402
  }
@@ -400,28 +424,30 @@ function parsePath(path) {
400
424
  return segments;
401
425
  }
402
426
  function redactPath(node, segments) {
403
- if (segments.length === 0) return;
404
- if (!isPlainObject(node)) return;
427
+ if (segments.length === 0) return true;
428
+ if (!isPlainObject(node)) return false;
405
429
  const [head, ...rest] = segments;
406
- if (!head) return;
430
+ if (!head) return false;
407
431
  const { key, isArrayWildcard } = head;
408
- if (!(key in node)) return;
432
+ if (!(key in node)) return false;
409
433
  if (isArrayWildcard) {
410
434
  const target = node[key];
411
- if (!Array.isArray(target)) return;
435
+ if (!Array.isArray(target)) return false;
412
436
  if (rest.length === 0) {
413
437
  node[key] = target.map(() => REDACTED_PLACEHOLDER);
414
- return;
438
+ return true;
415
439
  }
440
+ let matched = target.length > 0;
416
441
  for (const item of target) {
417
- redactPath(item, rest);
442
+ if (!redactPath(item, rest)) matched = false;
418
443
  }
444
+ return matched;
419
445
  } else {
420
446
  if (rest.length === 0) {
421
447
  node[key] = REDACTED_PLACEHOLDER;
422
- } else {
423
- redactPath(node[key], rest);
448
+ return true;
424
449
  }
450
+ return redactPath(node[key], rest);
425
451
  }
426
452
  }
427
453
  function isPlainObject(v) {
@@ -449,7 +475,7 @@ function gated(options, fn) {
449
475
  return async (...args) => {
450
476
  const activeClient = options.client ?? new PliuzClient();
451
477
  const rawArgs = toolArgsMapper(...args);
452
- const sendArgs = redactPaths && redactPaths.length > 0 ? applyRedaction(rawArgs, redactPaths) : rawArgs;
478
+ const sendArgs = redactPaths && redactPaths.length > 0 ? applyRedaction(rawArgs, redactPaths, options.redactStrict ?? false) : rawArgs;
453
479
  const idempotencyKey = idempotencyKeyFor(toolName, rawArgs, options.sessionId);
454
480
  const metadata = {};
455
481
  if (options.policy) metadata.policy = options.policy;
@@ -473,12 +499,15 @@ function gated(options, fn) {
473
499
  if (!TERMINAL_OK.has(response.status)) {
474
500
  const deadline = Date.now() + timeoutMs;
475
501
  while (true) {
476
- if (Date.now() >= deadline) {
502
+ const remainingMs = deadline - Date.now();
503
+ if (remainingMs <= 0) {
477
504
  throw new PliuzApprovalTimeoutError(approvalId, timeoutMs);
478
505
  }
479
- await sleep2(pollIntervalMs);
480
- approval = await activeClient.getApproval(approvalId);
506
+ const waitSeconds = Math.max(1, Math.ceil(Math.min(remainingMs, pollIntervalMs * 1e3) / 1e3));
507
+ const callStart = Date.now();
508
+ approval = await activeClient.getApproval(approvalId, waitSeconds);
481
509
  if (terminalOrThrow(approval)) break;
510
+ if (Date.now() - callStart < 250) await sleep2(pollIntervalMs);
482
511
  }
483
512
  } else if (response.is_replay) {
484
513
  approval = await activeClient.getApproval(approvalId);
@@ -585,28 +614,31 @@ function gatedTool(options, tool) {
585
614
  if (typeof tool.execute !== "function") {
586
615
  return tool;
587
616
  }
588
- const toolName = options.toolName ?? (typeof tool.description === "string" ? tool.description.slice(0, 64) : "ai_tool");
617
+ const toolName = options.toolName;
618
+ if (typeof toolName !== "string" || toolName.trim() === "") {
619
+ throw new Error(
620
+ "gatedTool: `toolName` is required and must be a non-empty string. It drives Pliuz policy matching, so it must be explicit and stable \u2014 never derived from the tool description (a copy edit would silently re-route approvals)."
621
+ );
622
+ }
589
623
  const originalExecute = tool.execute;
590
- let pendingOptions = void 0;
591
- const gatedExecute1Arg = gated(
592
- {
593
- policy: options.policy,
594
- redact: options.redact,
595
- timeoutMs: options.timeoutMs,
596
- pollIntervalMs: options.pollIntervalMs,
597
- client: options.client,
598
- contextMessages: options.contextMessages,
599
- sessionId: options.sessionId,
600
- originator: options.originator,
601
- toolName,
602
- // Surface the Vercel-AI input dict directly as Pliuz tool_args
603
- // instead of wrapping in `{ args: [input] }` for cleaner audit logs.
604
- toolArgs: (input) => isPlainObject2(input) ? input : { input }
605
- },
606
- async (input) => originalExecute(input, pendingOptions)
607
- );
608
624
  const wrappedExecute = async (input, opts) => {
609
- pendingOptions = opts;
625
+ const gatedExecute1Arg = gated(
626
+ {
627
+ policy: options.policy,
628
+ redact: options.redact,
629
+ timeoutMs: options.timeoutMs,
630
+ pollIntervalMs: options.pollIntervalMs,
631
+ client: options.client,
632
+ contextMessages: options.contextMessages,
633
+ sessionId: options.sessionId,
634
+ originator: options.originator,
635
+ toolName,
636
+ // Surface the Vercel-AI input dict directly as Pliuz tool_args
637
+ // instead of wrapping in `{ args: [input] }` for cleaner audit logs.
638
+ toolArgs: (inp) => isPlainObject2(inp) ? inp : { input: inp }
639
+ },
640
+ async (inp) => originalExecute(inp, opts)
641
+ );
610
642
  return gatedExecute1Arg(input);
611
643
  };
612
644
  return {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/version.ts","../../src/errors.ts","../../src/_http.ts","../../src/client.ts","../../src/redaction.ts","../../src/gated.ts","../../src/adapters/ai.ts"],"names":["sleep","createHash","isPlainObject"],"mappings":";;;;;;;AAIO,IAAM,OAAA,GAAU,OAAA;;;ACkBhB,IAAM,UAAA,GAAN,cAAyB,KAAA,CAAM;AAAA,EACpC,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,YAAA;AAEZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,iBAAA,GAAN,cAAgC,UAAA,CAAW;AAAA,EAChD,WAAA,CAAY,SAA0C,KAAA,EAAiB;AACrE,IAAA,KAAA,CAAM,OAAO,CAAA;AADuC,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAEpD,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAJsD,KAAA;AAKxD,CAAA;AAEO,IAAM,iBAAA,GAAN,cAAgC,UAAA,CAAW;AAAA,EAChD,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,aAAA,GAAN,cAA4B,UAAA,CAAW;AAAA,EAC5C,WAAA,CACkB,UAAA,EACA,SAAA,EAChB,OAAA,EACgB,OAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AALG,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAEA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EARkB,UAAA;AAAA,EACA,SAAA;AAAA,EAEA,OAAA;AAMpB,CAAA;AAEO,IAAM,oBAAA,GAAN,cAAmC,aAAA,CAAc;AAAA,EACtD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,cAAA,GAAN,cAA6B,aAAA,CAAc;AAAA,EAChD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,mBAAA,GAAN,cAAkC,aAAA,CAAc;AAAA,EACrD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,kBAAA,GAAN,cAAiC,aAAA,CAAc;AAAA,EACpD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,kBAAA,GAAN,cAAiC,aAAA,CAAc;AAAA,EACpD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,gBAAA,GAAN,cAA+B,aAAA,CAAc;AAAA,EAClD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,mBAAA,GAAN,cAAkC,aAAA,CAAc;AAAA,EACrD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,gBAAA,GAAN,cAA+B,aAAA,CAAc;AAAA,EAClD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAMO,IAAM,kBAAA,GAAN,cAAiC,UAAA,CAAW;AAAA,EACjD,WAAA,CAA4B,YAAoC,MAAA,EAAuB;AACrF,IAAA,MAAM,GAAA,GAAM,SACR,CAAA,SAAA,EAAY,UAAU,kBAAkB,MAAM,CAAA,CAAA,GAC9C,YAAY,UAAU,CAAA,aAAA,CAAA;AAC1B,IAAA,KAAA,CAAM,GAAG,CAAA;AAJiB,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAAoC,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAK9D,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAP4B,UAAA;AAAA,EAAoC,MAAA;AAQlE,CAAA;AAEO,IAAM,yBAAA,GAAN,cAAwC,UAAA,CAAW;AAAA,EACxD,YAA4B,UAAA,EAAoB;AAC9C,IAAA,KAAA,CAAM,CAAA,SAAA,EAAY,UAAU,CAAA,+BAAA,CAAiC,CAAA;AADnC,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAE1B,IAAA,IAAA,CAAK,IAAA,GAAO,2BAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAJ4B,UAAA;AAK9B,CAAA;AAEO,IAAM,yBAAA,GAAN,cAAwC,UAAA,CAAW;AAAA,EACxD,WAAA,CAA4B,YAAoC,SAAA,EAAmB;AACjF,IAAA,KAAA;AAAA,MACE,CAAA,SAAA,EAAY,UAAU,CAAA,wBAAA,EAA2B,SAAS,CAAA,yEAAA;AAAA,KAE5D;AAJ0B,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAAoC,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAK9D,IAAA,IAAA,CAAK,IAAA,GAAO,2BAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAP4B,UAAA;AAAA,EAAoC,SAAA;AAQlE,CAAA;AAUO,IAAM,2BAAA,GAAN,cAA0C,UAAA,CAAW;AAAA,EAC1D,WAAA,CACkB,YACA,SAAA,EAChB;AACA,IAAA,KAAA;AAAA,MACE,YAAY,UAAU,CAAA,oPAAA;AAAA,KAIxB;AARgB,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAQhB,IAAA,IAAA,CAAK,IAAA,GAAO,6BAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAXkB,UAAA;AAAA,EACA,SAAA;AAWpB,CAAA;AAEA,IAAM,eAAA,GAAuH;AAAA,EAC3H,GAAA,EAAK,oBAAA;AAAA,EACL,GAAA,EAAK,cAAA;AAAA,EACL,GAAA,EAAK,mBAAA;AAAA,EACL,GAAA,EAAK,kBAAA;AAAA,EACL,GAAA,EAAK,kBAAA;AAAA,EACL,GAAA,EAAK,gBAAA;AAAA,EACL,GAAA,EAAK;AACP,CAAA;AAEO,SAAS,cAAA,CACd,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACe;AACf,EAAA,IAAI,UAAA,IAAc,GAAA,IAAO,UAAA,GAAa,GAAA,EAAK;AACzC,IAAA,OAAO,IAAI,gBAAA,CAAiB,UAAA,EAAY,SAAA,EAAW,SAAS,OAAO,CAAA;AAAA,EACrE;AACA,EAAA,MAAM,GAAA,GAAM,eAAA,CAAgB,UAAU,CAAA,IAAK,aAAA;AAC3C,EAAA,OAAO,IAAI,GAAA,CAAI,UAAA,EAAY,SAAA,EAAW,SAAS,OAAO,CAAA;AACxD;;;AChOA,IAAM,kBAAA,uBAAyB,GAAA,CAAI,CAAC,OAAO,MAAA,EAAQ,SAAA,EAAW,KAAA,EAAO,QAAQ,CAAC,CAAA;AAG9E,IAAM,gBAAA,mBAAmB,IAAI,GAAA,CAAI,CAAC,GAAA,EAAK,KAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAC,CAAA;AAa/D,SAAS,SAAA,GAAoB;AAC3B,EAAA,OAAO,oBAAoB,OAAO,CAAA,CAAA;AACpC;AAEA,SAAS,aAAa,MAAA,EAAwC;AAC5D,EAAA,OAAO;AAAA,IACL,iBAAA,EAAmB,MAAA;AAAA,IACnB,cAAc,SAAA,EAAU;AAAA,IACxB,MAAA,EAAQ,kBAAA;AAAA,IACR,cAAA,EAAgB;AAAA,GAClB;AACF;AAEA,SAAS,SAAA,CAAU,OAAA,EAAiB,MAAA,GAAS,GAAA,EAAK,QAAQ,GAAA,EAAc;AAEtE,EAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,OAAO,MAAA,GAAS,CAAA,KAAM,UAAU,CAAA,CAAE,CAAA;AACxD,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,IAAI,CAAA;AACxC;AAEA,SAAS,WAAA,CAAY,MAAA,EAAgB,MAAA,EAAgB,WAAA,EAA+B;AAClF,EAAA,IAAI,CAAC,gBAAA,CAAiB,GAAA,CAAI,MAAM,GAAG,OAAO,KAAA;AAC1C,EAAA,IAAI,kBAAA,CAAmB,GAAA,CAAI,MAAM,CAAA,EAAG,OAAO,IAAA;AAC3C,EAAA,IAAI,MAAA,KAAW,MAAA,IAAU,WAAA,EAAa,OAAO,IAAA;AAC7C,EAAA,OAAO,KAAA;AACT;AAEA,eAAe,WAAW,QAAA,EAA4C;AACpE,EAAA,IAAI,OAA8B,EAAC;AACnC,EAAA,IAAI;AACF,IAAA,IAAA,GAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,EAC9B,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,MAAM,SAAA,GAAY,KAAK,KAAA,IAAS,eAAA;AAChC,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,QAAA,CAAS,UAAA,IAAc,iBAAA;AACvD,EAAA,MAAM,UAAU,IAAA,CAAK,OAAA;AACrB,EAAA,OAAO,cAAA,CAAe,QAAA,CAAS,MAAA,EAAQ,SAAA,EAAW,SAAS,OAAO,CAAA;AACpE;AAEA,SAAS,MAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;AAEA,eAAsB,QAAW,IAAA,EAAkC;AACjE,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAA,EAAK,MAAA,EAAQ,IAAA,EAAM,WAAW,UAAA,EAAY,WAAA,GAAc,KAAA,EAAO,SAAA,EAAU,GAAI,IAAA;AAC7F,EAAA,MAAM,OAAA,GAAU,aAAa,MAAM,CAAA;AAEnC,EAAA,IAAI,SAAA,GAA0B,IAAA;AAE9B,EAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,UAAA,GAAa,GAAG,OAAA,EAAA,EAAW;AAC1D,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,SAAS,CAAA;AAE5D,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,UAAU,GAAA,EAAK;AAAA,QAC9B,MAAA;AAAA,QACA,OAAA;AAAA,QACA,MAAM,IAAA,IAAQ,IAAA,GAAO,KAAA,CAAA,GAAY,IAAA,CAAK,UAAU,IAAI,CAAA;AAAA,QACpD,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AAAA,IACH,SAAS,CAAA,EAAG;AACV,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,MAAM,SAAA,GACJ,aAAa,KAAA,KACZ,CAAA,CAAE,SAAS,YAAA,IAAgB,gBAAA,CAAiB,IAAA,CAAK,CAAA,CAAE,OAAO,CAAA,CAAA;AAC7D,MAAA,SAAA,GAAY,YACR,IAAI,iBAAA,CAAkB,iCAAiC,SAAS,CAAA,EAAA,CAAI,IACpE,IAAI,iBAAA;AAAA,QACF,wBAAwB,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA,CAAA;AAAA,QAClE;AAAA,OACF;AACJ,MAAA,IAAI,OAAA,GAAU,YAAY,MAAM,SAAA;AAChC,MAAA,MAAM,KAAA,CAAM,SAAA,CAAU,OAAO,CAAC,CAAA;AAC9B,MAAA;AAAA,IACF;AACA,IAAA,YAAA,CAAa,KAAK,CAAA;AAElB,IAAA,IAAI,QAAA,CAAS,MAAA,IAAU,GAAA,IAAO,QAAA,CAAS,SAAS,GAAA,EAAK;AACnD,MAAA,IAAI;AACF,QAAA,OAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,MAC9B,SAAS,CAAA,EAAG;AACV,QAAA,MAAM,IAAI,aAAA;AAAA,UACR,QAAA,CAAS,MAAA;AAAA,UACT,cAAA;AAAA,UACA,qCAAqC,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,SACjF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,WAAA,CAAY,MAAA,EAAQ,QAAA,CAAS,MAAA,EAAQ,WAAW,CAAA,EAAG;AACrD,MAAA,IAAI,UAAU,UAAA,EAAY;AACxB,QAAA,MAAM,MAAM,WAAW,QAAQ,CAAA;AAAA,MACjC;AACA,MAAA,MAAM,KAAA,CAAM,SAAA,CAAU,OAAO,CAAC,CAAA;AAC9B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAM,WAAW,QAAQ,CAAA;AAAA,EACjC;AAGA,EAAA,MAAM,SAAA,IAAa,IAAI,aAAA,CAAc,CAAA,EAAG,aAAa,mCAAmC,CAAA;AAC1F;;;AC1GO,IAAM,gBAAA,GAAmB,mBAAA;AACzB,IAAM,kBAAA,GAAqB,GAAA;AAC3B,IAAM,mBAAA,GAAsB,CAAA;AAC5B,IAAM,WAAA,GAAc,eAAA;AACpB,IAAM,YAAA,GAAe,gBAAA;AA4B5B,SAAS,cAAc,QAAA,EAAsC;AAC3D,EAAA,IAAI,UAAU,OAAO,QAAA;AACrB,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,GAAM,WAAW,CAAA,EAAG;AAChE,IAAA,OAAO,OAAA,CAAQ,IAAI,WAAW,CAAA;AAAA,EAChC;AACA,EAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gDAAA,EAAmD,WAAW,CAAA,CAAA,CAAG,CAAA;AACnF;AAEA,SAAS,eAAe,QAAA,EAAsC;AAC5D,EAAA,IAAI,QAAA,EAAU,OAAO,QAAA,CAAS,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAChD,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,GAAM,YAAY,CAAA,EAAG;AACjE,IAAA,OAAO,QAAQ,GAAA,CAAI,YAAY,CAAA,CAAE,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAAA,EACrD;AACA,EAAA,OAAO,gBAAA;AACT;AAEA,SAAS,WAAA,CAAY,OAAA,EAAiB,UAAA,EAAqB,MAAA,EAAyB;AAClF,EAAA,IAAI,IAAA,GAAO,mBAAA;AACX,EAAA,IAAI,UAAA,EAAY,IAAA,IAAQ,CAAA,CAAA,EAAI,kBAAA,CAAmB,UAAU,CAAC,CAAA,CAAA;AAC1D,EAAA,IAAI,MAAA,EAAQ,IAAA,IAAQ,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AAC9B,EAAA,OAAO,OAAA,GAAU,IAAA;AACnB;AAEO,IAAM,cAAN,MAAkB;AAAA,EACN,MAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EAEjB,WAAA,CAAY,OAAA,GAA8B,EAAC,EAAG;AAC5C,IAAA,IAAA,CAAK,MAAA,GAAS,aAAA,CAAc,OAAA,CAAQ,MAAM,CAAA;AAC1C,IAAA,IAAA,CAAK,OAAA,GAAU,cAAA,CAAe,OAAA,CAAQ,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,kBAAA;AACtC,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,IAAc,mBAAA;AAExC,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA;AAC9C,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAe,KAAA,EAA6D;AAChF,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,gBAAA,EAAkB,MAAM,gBAAA,IAAoB,IAAA;AAAA,MAC5C,UAAA,EAAY,KAAA,CAAM,UAAA,IAAc,EAAE,MAAM,QAAA,EAAS;AAAA,MACjD,UAAA,EAAY,MAAM,UAAA,IAAc,IAAA;AAAA,MAChC,eAAA,EAAiB,MAAM,eAAA,IAAmB,IAAA;AAAA,MAC1C,eAAA,EAAiB,MAAM,eAAA,IAAmB;AAAA,KAC5C;AACA,IAAA,OAAO,OAAA,CAAgC;AAAA,MACrC,MAAA,EAAQ,MAAA;AAAA,MACR,GAAA,EAAK,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AAAA,MAC7B,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,IAAA;AAAA,MACA,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,WAAA,EAAa,OAAA,CAAQ,KAAA,CAAM,eAAe,CAAA;AAAA,MAC1C,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,UAAA,EAA8C;AAC9D,IAAA,OAAO,OAAA,CAAyB;AAAA,MAC9B,MAAA,EAAQ,KAAA;AAAA,MACR,GAAA,EAAK,WAAA,CAAY,IAAA,CAAK,OAAA,EAAS,UAAU,CAAA;AAAA,MACzC,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAA,CACJ,UAAA,EACA,KAAA,EAC0B;AAC1B,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,KAAA,EAAO,MAAM,KAAA,IAAS,IAAA;AAAA,MACtB,UAAA,EAAY,MAAM,UAAA,IAAc,IAAA;AAAA,MAChC,uBAAA,EAAyB,MAAM,uBAAA,IAA2B;AAAA,KAC5D;AACA,IAAA,OAAO,OAAA,CAAyB;AAAA,MAC9B,MAAA,EAAQ,MAAA;AAAA,MACR,GAAA,EAAK,WAAA,CAAY,IAAA,CAAK,OAAA,EAAS,YAAY,WAAW,CAAA;AAAA,MACtD,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,IAAA;AAAA,MACA,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,WAAA,EAAa,KAAA;AAAA,MACb,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AAAA,EACH;AACF,CAAA;;;AC/JO,IAAM,oBAAA,GAAuB,YAAA;AAY7B,SAAS,cAAA,CACd,SACA,KAAA,EACG;AACH,EAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAChC,IAAA,OAAO,UAAU,OAAO,CAAA;AAAA,EAC1B;AACA,EAAA,MAAM,MAAA,GAAS,UAAU,OAAO,CAAA;AAChC,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,UAAA,CAAW,MAAA,EAAmC,SAAA,CAAU,IAAI,CAAC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,MAAA;AACT;AAMA,SAAS,UAAU,IAAA,EAA6B;AAC9C,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,MAAM,IAAI,MAAM,gCAAgC,CAAA;AAAA,EAClD;AAEA,EAAA,MAAM,WAA0B,EAAC;AACjC,EAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,EAAG;AACjC,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,KAAK,CAAA,EAAG;AACvB,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAC3B,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mDAAA,EAAsD,IAAI,CAAA,CAAE,CAAA;AAAA,MAC9E;AACA,MAAA,QAAA,CAAS,IAAA,CAAK,EAAE,GAAA,EAAK,eAAA,EAAiB,MAAM,CAAA;AAAA,IAC9C,CAAA,MAAA,IAAW,IAAI,QAAA,CAAS,GAAG,KAAK,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,EAAG;AACjD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoC,IAAI,CAAA,4BAAA,CAAyB,CAAA;AAAA,IACnF,CAAA,MAAO;AACL,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,IAAI,CAAA,CAAE,CAAA;AAAA,MAC7D;AACA,MAAA,QAAA,CAAS,KAAK,EAAE,GAAA,EAAK,GAAA,EAAK,eAAA,EAAiB,OAAO,CAAA;AAAA,IACpD;AAAA,EACF;AACA,EAAA,OAAO,QAAA;AACT;AAEA,SAAS,UAAA,CAAW,MAAe,QAAA,EAA+B;AAChE,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AAC3B,EAAA,IAAI,CAAC,aAAA,CAAc,IAAI,CAAA,EAAG;AAE1B,EAAA,MAAM,CAAC,IAAA,EAAM,GAAG,IAAI,CAAA,GAAI,QAAA;AACxB,EAAA,IAAI,CAAC,IAAA,EAAM;AACX,EAAA,MAAM,EAAE,GAAA,EAAK,eAAA,EAAgB,GAAI,IAAA;AACjC,EAAA,IAAI,EAAE,OAAO,IAAA,CAAA,EAAO;AAEpB,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,MAAM,MAAA,GAAS,KAAK,GAAG,CAAA;AACvB,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC5B,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,MAAM,oBAAoB,CAAA;AACjD,MAAA;AAAA,IACF;AACA,IAAA,KAAA,MAAW,QAAQ,MAAA,EAAQ;AACzB,MAAA,UAAA,CAAW,MAAM,IAAI,CAAA;AAAA,IACvB;AAAA,EACF,CAAA,MAAO;AACL,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,oBAAA;AAAA,IACd,CAAA,MAAO;AACL,MAAA,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA,EAAG,IAAI,CAAA;AAAA,IAC5B;AAAA,EACF;AACF;AAEA,SAAS,cAAc,CAAA,EAA0C;AAC/D,EAAA,OAAO,OAAO,MAAM,QAAA,IAAY,CAAA,KAAM,QAAQ,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE;AAEA,SAAS,UAAa,CAAA,EAAS;AAG7B,EAAA,IAAI,OAAO,oBAAoB,UAAA,EAAY;AACzC,IAAA,OAAO,gBAAgB,CAAC,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA;AACrC;;;ACxEO,IAAM,wBAAA,GAA2B,GAAA;AACjC,IAAM,8BAAA,GAAiC,GAAA;AA+C9C,IAAM,WAAA,mBAAc,IAAI,GAAA,CAAY,CAAC,UAAU,CAAC,CAAA;AAChD,IAAM,eAAA,mBAAkB,IAAI,GAAA,CAAY,CAAC,UAAU,CAAC,CAAA;AACpD,IAAM,gBAAA,mBAAmB,IAAI,GAAA,CAAY,CAAC,SAAS,CAAC,CAAA;AAQ7C,SAAS,KAAA,CACd,SACA,EAAA,EACsC;AACtC,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,QAAA,KAAa,EAAA,CAAG,IAAA,IAAQ,WAAA,CAAA;AACjD,EAAA,MAAM,iBACJ,OAAA,CAAQ,QAAA,KACP,CAAA,GAAI,IAAA,MAA0C,EAAE,IAAA,EAAmC,CAAA,CAAA;AACtF,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,wBAAA;AACvC,EAAA,MAAM,cAAA,GAAiB,QAAQ,cAAA,IAAkB,8BAAA;AACjD,EAAA,MAAM,cAAc,OAAA,CAAQ,MAAA;AAE5B,EAAA,OAAO,UAAU,IAAA,KAAkC;AACjD,IAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,MAAA,IAAU,IAAI,WAAA,EAAY;AACvD,IAAA,MAAM,OAAA,GAAU,cAAA,CAAe,GAAG,IAAI,CAAA;AACtC,IAAA,MAAM,QAAA,GAAW,eAAe,WAAA,CAAY,MAAA,GAAS,IACjD,cAAA,CAAe,OAAA,EAAS,WAAW,CAAA,GACnC,OAAA;AAKJ,IAAA,MAAM,cAAA,GAAiB,iBAAA,CAAkB,QAAA,EAAU,OAAA,EAAS,QAAQ,SAAS,CAAA;AAC7E,IAAA,MAAM,WAAoC,EAAC;AAC3C,IAAA,IAAI,OAAA,CAAQ,MAAA,EAAQ,QAAA,CAAS,MAAA,GAAS,OAAA,CAAQ,MAAA;AAE9C,IAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,cAAA,CAAe;AAAA,MACjD,SAAA,EAAW,QAAA;AAAA,MACX,SAAA,EAAW,QAAA;AAAA,MACX,gBAAA,EAAkB,QAAQ,eAAA,IAAmB,IAAA;AAAA,MAC7C,YAAY,OAAA,CAAQ,UAAA;AAAA,MACpB,UAAA,EAAY,QAAQ,SAAA,IAAa,IAAA;AAAA,MACjC,iBAAiB,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,CAAE,MAAA,GAAS,IAAI,QAAA,GAAW,IAAA;AAAA,MAC/D,eAAA,EAAiB;AAAA,KAClB,CAAA;AAED,IAAA,MAAM,aAAa,QAAA,CAAS,EAAA;AAE5B,IAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACxC,MAAA,MAAM,IAAI,kBAAA,CAAmB,UAAA,EAAY,QAAA,CAAS,WAAW,IAAI,CAAA;AAAA,IACnE;AACA,IAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACzC,MAAA,MAAM,IAAI,0BAA0B,UAAU,CAAA;AAAA,IAChD;AAEA,IAAA,IAAI,QAAA,GAAmC,IAAA;AACvC,IAAA,IAAI,CAAC,WAAA,CAAY,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AAErC,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAC9B,MAAA,OAAO,IAAA,EAAM;AACX,QAAA,IAAI,IAAA,CAAK,GAAA,EAAI,IAAK,QAAA,EAAU;AAC1B,UAAA,MAAM,IAAI,yBAAA,CAA0B,UAAA,EAAY,SAAS,CAAA;AAAA,QAC3D;AACA,QAAA,MAAMA,OAAM,cAAc,CAAA;AAC1B,QAAA,QAAA,GAAW,MAAM,YAAA,CAAa,WAAA,CAAY,UAAU,CAAA;AACpD,QAAA,IAAI,eAAA,CAAgB,QAAQ,CAAA,EAAG;AAAA,MACjC;AAAA,IACF,CAAA,MAAA,IAAW,SAAS,SAAA,EAAW;AAG7B,MAAA,QAAA,GAAW,MAAM,YAAA,CAAa,WAAA,CAAY,UAAU,CAAA;AAAA,IACtD;AAIA,IAAA,IAAI,QAAA,GAAW,IAAA;AACf,IAAA,MAAM,SAAA,GAAY,UAAU,UAAA,IAAc,IAAA;AAC1C,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,QAAA,GAAW,iBAAA,CAAkB,UAAA,EAAY,OAAA,EAAS,SAAA,EAAW,MAAM,OAAO,CAAA;AAAA,IAC5E;AAKA,IAAA,MAAM,OAAA,GAAU,KAAK,GAAA,EAAI;AACzB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,GAAG,QAAQ,CAAA;AACnC,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,EAAI,GAAI,OAAA;AAC/B,MAAA,MAAM,WAAW,YAAA,EAAc,UAAA,EAAY,WAAW,IAAA,EAAM,SAAA,EAAW,QAAQ,WAAW,CAAA;AAC1F,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,CAAA,EAAG;AACV,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,EAAI,GAAI,OAAA;AAC/B,MAAA,MAAM,SAAS,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AACxD,MAAA,MAAM,UAAA,CAAW,YAAA,EAAc,UAAA,EAAY,OAAA,EAAS,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,GAAI,CAAA,EAAG,SAAA,EAAW,IAAA,EAAM,WAAW,CAAA;AACvG,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAMA,SAAS,iBAAA,CACP,QAAA,EACA,QAAA,EACA,SAAA,EACQ;AACR,EAAgB,IAAA,CAAK,SAAA;AAAA,IACnB,EAAE,IAAA,EAAM,QAAA,EAAU,MAAM,QAAA,EAAU,OAAA,EAAS,aAAa,IAAA,EAAK;AAAA,IAC7D,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,OAAA,EAAS,CAAA,EAAG,CAAA,CAAE,IAAA;AAAK;AAGrD,EAAA,MAAM,SAAA,GAAY,aAAA,CAAc,EAAE,IAAA,EAAM,QAAA,EAAU,MAAM,QAAA,EAAU,OAAA,EAAS,SAAA,IAAa,IAAA,EAAM,CAAA;AAE9F,EAAA,OAAO,IAAA,GAAOC,iBAAA,CAAW,QAAQ,CAAA,CAAE,MAAA,CAAO,SAAS,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAChF;AAEA,SAAS,cAAc,KAAA,EAAwB;AAC7C,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,EAAU;AAC/C,IAAA,OAAO,IAAA,CAAK,UAAU,KAAK,CAAA;AAAA,EAC7B;AACA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,IAAA,OAAO,MAAM,KAAA,CAAM,GAAA,CAAI,aAAa,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,GAAI,GAAA;AAAA,EACpD;AACA,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,GAAG,EAAE,IAAA,EAAK;AACnC,EAAA,OACE,MACA,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,UAAU,CAAC,CAAA,GAAI,GAAA,GAAM,aAAA,CAAc,IAAI,CAAC,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,GACzE,GAAA;AAEJ;AAQA,SAAS,cAAA,CAAe,KAAc,KAAA,EAAyB;AAC7D,EAAA,IAAI,aAAA,CAAc,GAAG,CAAA,IAAK,aAAA,CAAc,KAAK,CAAA,EAAG;AAC9C,IAAA,MAAM,MAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC1C,MAAA,GAAA,CAAI,CAAC,IAAI,CAAA,IAAK,GAAA,GAAM,eAAe,GAAA,CAAI,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,CAAA;AAAA,IAClD;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,IAAI,KAAA,KAAU,sBAAsB,OAAO,GAAA;AAC3C,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,cAAc,CAAA,EAA0C;AAC/D,EAAA,OAAO,OAAO,MAAM,QAAA,IAAY,CAAA,KAAM,QAAQ,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE;AAWA,SAAS,iBAAA,CACP,UAAA,EACA,OAAA,EACA,SAAA,EACA,cACA,OAAA,EACO;AACP,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,OAAA,EAAS,SAAS,CAAA;AAChD,EAAA,IAAI,QAAQ,cAAA,EAAgB;AAC1B,IAAA,OAAO,OAAA,CAAQ,cAAA,CAAe,MAAA,EAAQ,YAAY,CAAA;AAAA,EACpD;AACA,EAAA,IAAI,QAAQ,QAAA,KAAa,MAAA,IAAa,MAAM,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA,EAAG;AAChE,IAAA,OAAO,MAAA,CAAO,IAAA;AAAA,EAChB;AACA,EAAA,MAAM,IAAI,2BAAA,CAA4B,UAAA,EAAY,MAAM,CAAA;AAC1D;AAEA,SAAS,gBAAgB,QAAA,EAAoC;AAC3D,EAAA,IAAI,WAAA,CAAY,GAAA,CAAI,QAAA,CAAS,MAAM,GAAG,OAAO,IAAA;AAC7C,EAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACxC,IAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,EAAA,EAAI,SAAS,eAAe,CAAA;AAAA,EACpE;AACA,EAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACzC,IAAA,MAAM,IAAI,yBAAA,CAA0B,QAAA,CAAS,EAAE,CAAA;AAAA,EACjD;AACA,EAAA,OAAO,KAAA;AACT;AAEA,eAAe,WACb,MAAA,EACA,UAAA,EACA,QACA,YAAA,EACA,SAAA,EACA,QACA,WAAA,EACe;AACf,EAAA,IAAI,OAAA,GAAyB,IAAA;AAC7B,EAAA,IAAI,UAAU,IAAA,EAAM;AAIlB,IAAA,MAAM,MAAA,GAAS,WAAA,IAAe,WAAA,CAAY,MAAA,GAAS,CAAA,IAAK,aAAA,CAAc,MAAM,CAAA,GACxE,cAAA,CAAe,MAAA,EAAQ,WAAW,CAAA,GAClC,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,KAAK,SAAA,CAAU,MAAM,CAAA,CAAE,KAAA,CAAM,GAAG,GAAI,CAAA;AAAA,IAChD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAA,GAAU,MAAA,CAAO,MAAM,CAAA,CAAE,KAAA,CAAM,GAAG,GAAI,CAAA;AAAA,IACxC;AAAA,EACF;AACA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,CAAO,gBAAgB,UAAA,EAAY;AAAA,MACvC,MAAA;AAAA,MACA,KAAA,EAAO,YAAA;AAAA,MACP,UAAA,EAAY,SAAA;AAAA,MACZ,uBAAA,EAAyB;AAAA,KAC1B,CAAA;AAAA,EACH,CAAA,CAAA,MAAQ;AAAA,EAGR;AACF;AAEA,SAASD,OAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;;;AC7PO,IAAM,YAAA,GAAe;AAQrB,SAAS,SAAA,CACd,SACA,IAAA,EACyB;AACzB,EAAA,IAAI,OAAO,IAAA,CAAK,OAAA,KAAY,UAAA,EAAY;AAEtC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,QAAA,GACJ,OAAA,CAAQ,QAAA,KACP,OAAO,IAAA,CAAK,WAAA,KAAgB,QAAA,GAAW,IAAA,CAAK,WAAA,CAAY,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,SAAA,CAAA;AAE1E,EAAA,MAAM,kBAAkB,IAAA,CAAK,OAAA;AAI7B,EAAA,IAAI,cAAA,GAA0B,MAAA;AAE9B,EAAA,MAAM,gBAAA,GAAmB,KAAA;AAAA,IACvB;AAAA,MACE,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,WAAW,OAAA,CAAQ,SAAA;AAAA,MACnB,gBAAgB,OAAA,CAAQ,cAAA;AAAA,MACxB,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,iBAAiB,OAAA,CAAQ,eAAA;AAAA,MACzB,WAAW,OAAA,CAAQ,SAAA;AAAA,MACnB,YAAY,OAAA,CAAQ,UAAA;AAAA,MACpB,QAAA;AAAA;AAAA;AAAA,MAGA,QAAA,EAAU,CAAC,KAAA,KACTE,cAAAA,CAAc,KAAK,CAAA,GAAI,KAAA,GAAS,EAAE,KAAA;AAAM,KAC5C;AAAA,IACA,OAAO,KAAA,KAAkB,eAAA,CAAgB,KAAA,EAAO,cAAc;AAAA,GAChE;AAEA,EAAA,MAAM,cAAA,GAAqD,OAAO,KAAA,EAAO,IAAA,KAAS;AAChF,IAAA,cAAA,GAAiB,IAAA;AACjB,IAAA,OAAO,iBAAiB,KAAK,CAAA;AAAA,EAC/B,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,OAAA,EAAS;AAAA,GACX;AACF;AAEA,SAASA,eAAc,CAAA,EAA0C;AAC/D,EAAA,OAAO,OAAO,MAAM,QAAA,IAAY,CAAA,KAAM,QAAQ,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE","file":"ai.cjs","sourcesContent":["/**\n * Single source of truth for the package version.\n * Kept in sync with `package.json` by release tooling at publish time.\n */\nexport const VERSION = '0.2.1' as const\n","/**\n * Error hierarchy for the Pliuz SDK.\n *\n * All exceptions extend `PliuzError`. HTTP-level failures use `PliuzApiError`\n * subclasses keyed by status code, so callers can do narrow `instanceof` checks:\n *\n * ```ts\n * try {\n * await pliuz.createApproval(...)\n * } catch (e) {\n * if (e instanceof PliuzAuthError) {\n * // refresh API key\n * } else if (e instanceof PliuzPolicyError) {\n * // no policy matched — define a catch-all\n * } else if (e instanceof PliuzApiError) {\n * // other 4xx/5xx\n * }\n * throw e\n * }\n * ```\n */\n\nexport class PliuzError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PliuzError'\n // Maintain proper prototype chain for `instanceof` after transpile (CJS target)\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzNetworkError extends PliuzError {\n constructor(message: string, public override readonly cause?: unknown) {\n super(message)\n this.name = 'PliuzNetworkError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzTimeoutError extends PliuzError {\n constructor(message: string) {\n super(message)\n this.name = 'PliuzTimeoutError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzApiError extends PliuzError {\n constructor(\n public readonly statusCode: number,\n public readonly errorCode: string,\n message: string,\n public readonly details?: Record<string, unknown>,\n ) {\n super(message)\n this.name = 'PliuzApiError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzValidationError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzValidationError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzAuthError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzAuthError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzForbiddenError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzForbiddenError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzNotFoundError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzNotFoundError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzConflictError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzConflictError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzPolicyError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzPolicyError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzRateLimitError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzRateLimitError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzServerError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzServerError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\n// ---------------------------------------------------------------------------\n// gated() lifecycle errors — raised by the wrapper, NOT by direct client calls.\n// ---------------------------------------------------------------------------\n\nexport class PliuzRejectedError extends PliuzError {\n constructor(public readonly approvalId: string, public readonly reason: string | null) {\n const msg = reason\n ? `approval ${approvalId} was rejected: ${reason}`\n : `approval ${approvalId} was rejected`\n super(msg)\n this.name = 'PliuzRejectedError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzApprovalExpiredError extends PliuzError {\n constructor(public readonly approvalId: string) {\n super(`approval ${approvalId} expired before a human decided`)\n this.name = 'PliuzApprovalExpiredError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzApprovalTimeoutError extends PliuzError {\n constructor(public readonly approvalId: string, public readonly timeoutMs: number) {\n super(\n `approval ${approvalId} did not resolve within ${timeoutMs}ms ` +\n '(SDK polling timeout — approval may still be pending server-side)',\n )\n this.name = 'PliuzApprovalTimeoutError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\n/**\n * A human approved with EDITED args (action='edit') but the SDK cannot map\n * `final_args` back onto the wrapped function's parameters. The SDK refuses\n * to execute the ORIGINAL (unapproved) args — that would make the audit\n * trail lie about what was approved vs executed. Carries `finalArgs` so the\n * caller can apply the edit manually, or pass an `applyFinalArgs` mapper in\n * GatedOptions to handle edits automatically.\n */\nexport class PliuzEditNotApplicableError extends PliuzError {\n constructor(\n public readonly approvalId: string,\n public readonly finalArgs: Record<string, unknown>,\n ) {\n super(\n `approval ${approvalId} was approved with edited args, but they cannot be ` +\n 'mapped back to the wrapped function (custom toolArgs mapper without ' +\n 'applyFinalArgs, or incompatible shape) — refusing to execute the ' +\n 'original (unapproved) args. Apply e.finalArgs manually.',\n )\n this.name = 'PliuzEditNotApplicableError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nconst STATUS_TO_ERROR: Record<number, new (s: number, c: string, m: string, d?: Record<string, unknown>) => PliuzApiError> = {\n 400: PliuzValidationError,\n 401: PliuzAuthError,\n 403: PliuzForbiddenError,\n 404: PliuzNotFoundError,\n 409: PliuzConflictError,\n 422: PliuzPolicyError,\n 429: PliuzRateLimitError,\n}\n\nexport function errorForStatus(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n): PliuzApiError {\n if (statusCode >= 500 && statusCode < 600) {\n return new PliuzServerError(statusCode, errorCode, message, details)\n }\n const Cls = STATUS_TO_ERROR[statusCode] ?? PliuzApiError\n return new Cls(statusCode, errorCode, message, details)\n}\n","/**\n * Internal HTTP layer — shared by PliuzClient.\n *\n * Centralizes: header injection, error mapping, exponential-backoff retries\n * for idempotent operations, and JSON parsing.\n *\n * NOT public API — only `PliuzClient` should import from here.\n */\n\nimport { VERSION } from './version.js'\nimport type { ApiErrorBody } from './types.js'\nimport {\n PliuzApiError,\n PliuzNetworkError,\n PliuzTimeoutError,\n errorForStatus,\n} from './errors.js'\n\n// HTTP methods safe to retry without risking duplicate side-effects.\nconst IDEMPOTENT_METHODS = new Set(['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'])\n\n// Retry-able status codes — server hiccups, NOT client errors.\nconst RETRYABLE_STATUS = new Set([408, 429, 500, 502, 503, 504])\n\nexport interface RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE'\n url: string\n apiKey: string\n body?: Record<string, unknown> | null\n timeoutMs: number\n maxRetries: number\n retryOnPost?: boolean\n fetchImpl: typeof fetch\n}\n\nfunction userAgent(): string {\n return `pliuz-typescript/${VERSION}`\n}\n\nfunction buildHeaders(apiKey: string): Record<string, string> {\n return {\n 'X-Pliuz-Api-Key': apiKey,\n 'User-Agent': userAgent(),\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n }\n}\n\nfunction backoffMs(attempt: number, baseMs = 500, capMs = 8000): number {\n // Exponential with full jitter (AWS architecture blog formula).\n const expo = Math.min(capMs, baseMs * 2 ** (attempt - 1))\n return Math.floor(Math.random() * expo)\n}\n\nfunction isRetryable(method: string, status: number, retryOnPost: boolean): boolean {\n if (!RETRYABLE_STATUS.has(status)) return false\n if (IDEMPOTENT_METHODS.has(method)) return true\n if (method === 'POST' && retryOnPost) return true\n return false\n}\n\nasync function parseError(response: Response): Promise<PliuzApiError> {\n let body: Partial<ApiErrorBody> = {}\n try {\n body = (await response.json()) as Partial<ApiErrorBody>\n } catch {\n /* non-JSON body — fall through with empty */\n }\n const errorCode = body.error ?? 'unknown_error'\n const message = body.message ?? response.statusText ?? 'Pliuz API error'\n const details = body.details\n return errorForStatus(response.status, errorCode, message, details)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport async function request<T>(opts: RequestOptions): Promise<T> {\n const { method, url, apiKey, body, timeoutMs, maxRetries, retryOnPost = false, fetchImpl } = opts\n const headers = buildHeaders(apiKey)\n\n let lastError: Error | null = null\n\n for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n\n let response: Response\n try {\n response = await fetchImpl(url, {\n method,\n headers,\n body: body == null ? undefined : JSON.stringify(body),\n signal: controller.signal,\n })\n } catch (e) {\n clearTimeout(timer)\n const isTimeout =\n e instanceof Error &&\n (e.name === 'AbortError' || /abort|timeout/i.test(e.message))\n lastError = isTimeout\n ? new PliuzTimeoutError(`Pliuz request timed out after ${timeoutMs}ms`)\n : new PliuzNetworkError(\n `Pliuz network error: ${e instanceof Error ? e.message : String(e)}`,\n e,\n )\n if (attempt > maxRetries) throw lastError\n await sleep(backoffMs(attempt))\n continue\n }\n clearTimeout(timer)\n\n if (response.status >= 200 && response.status < 300) {\n try {\n return (await response.json()) as T\n } catch (e) {\n throw new PliuzApiError(\n response.status,\n 'invalid_json',\n `Pliuz returned non-JSON 2xx body: ${e instanceof Error ? e.message : String(e)}`,\n )\n }\n }\n\n if (isRetryable(method, response.status, retryOnPost)) {\n if (attempt > maxRetries) {\n throw await parseError(response)\n }\n await sleep(backoffMs(attempt))\n continue\n }\n\n throw await parseError(response)\n }\n\n // Unreachable — the loop always returns or throws.\n throw lastError ?? new PliuzApiError(0, 'exhausted', 'retry loop exhausted unexpectedly')\n}\n","/**\n * PliuzClient — the SDK entry point.\n *\n * Reads PLIUZ_API_KEY env var by default (Node only). Apply redaction\n * client-side via `applyRedaction` before passing tool_args; the client\n * does NOT redact for you (separation of concerns — the `gated()` wrapper\n * in Fase 7 will wire them together).\n *\n * @example\n * import { PliuzClient, applyRedaction } from '@pliuz/sdk'\n *\n * const pliuz = new PliuzClient() // reads PLIUZ_API_KEY\n *\n * const response = await pliuz.createApproval({\n * tool_name: 'issue_refund',\n * tool_args: applyRedaction(\n * { customer: { ssn: '...', id: 'cus_123' }, amount_cents: 5000 },\n * ['customer.ssn'],\n * ),\n * idempotency_key: 'refund-cus_123-2026-05-21-001',\n * })\n */\n\nimport { request } from './_http.js'\nimport type {\n ApprovalRequest,\n CreateApprovalInput,\n CreateApprovalResponse,\n ExecutionInput,\n ExecutionResult,\n} from './types.js'\n\nexport const DEFAULT_BASE_URL = 'https://pliuz.com'\nexport const DEFAULT_TIMEOUT_MS = 30_000\nexport const DEFAULT_MAX_RETRIES = 3\nexport const ENV_API_KEY = 'PLIUZ_API_KEY'\nexport const ENV_BASE_URL = 'PLIUZ_BASE_URL'\n\nexport interface PliuzClientOptions {\n /**\n * Pliuz API key (per-agent). Defaults to `process.env.PLIUZ_API_KEY`.\n * NEVER hardcode in source — read from env or a secrets manager.\n */\n apiKey?: string\n\n /**\n * Base URL (no trailing slash). Defaults to `process.env.PLIUZ_BASE_URL`\n * or `https://pliuz.com`.\n */\n baseUrl?: string\n\n /** Per-request timeout in milliseconds. Default: 30 000. */\n timeoutMs?: number\n\n /** Max retries for transient failures (network / 5xx / 429). Default: 3. */\n maxRetries?: number\n\n /**\n * Custom fetch implementation. Defaults to global `fetch` (Node ≥18).\n * Use for testing (MSW, vitest-fetch-mock) or to inject proxy/keepalive.\n */\n fetch?: typeof fetch\n}\n\nfunction resolveApiKey(explicit: string | undefined): string {\n if (explicit) return explicit\n if (typeof process !== 'undefined' && process.env?.[ENV_API_KEY]) {\n return process.env[ENV_API_KEY]\n }\n throw new Error(`Pliuz API key not provided. Pass apiKey or set $${ENV_API_KEY}.`)\n}\n\nfunction resolveBaseUrl(explicit: string | undefined): string {\n if (explicit) return explicit.replace(/\\/+$/, '')\n if (typeof process !== 'undefined' && process.env?.[ENV_BASE_URL]) {\n return process.env[ENV_BASE_URL].replace(/\\/+$/, '')\n }\n return DEFAULT_BASE_URL\n}\n\nfunction approvalUrl(baseUrl: string, approvalId?: string, suffix?: string): string {\n let path = '/api/v1/approvals'\n if (approvalId) path += `/${encodeURIComponent(approvalId)}`\n if (suffix) path += `/${suffix}`\n return baseUrl + path\n}\n\nexport class PliuzClient {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly timeoutMs: number\n private readonly maxRetries: number\n private readonly fetchImpl: typeof fetch\n\n constructor(options: PliuzClientOptions = {}) {\n this.apiKey = resolveApiKey(options.apiKey)\n this.baseUrl = resolveBaseUrl(options.baseUrl)\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES\n\n const fetchImpl = options.fetch ?? globalThis.fetch\n if (!fetchImpl) {\n throw new Error(\n 'No fetch implementation available. Pliuz requires Node ≥18 or a polyfill.',\n )\n }\n this.fetchImpl = fetchImpl\n }\n\n /**\n * Create (or idempotently replay) an approval request.\n *\n * With `idempotency_key`, the call retries on network failure without\n * risk of duplicates (backend dedupes within 24h).\n */\n async createApproval(input: CreateApprovalInput): Promise<CreateApprovalResponse> {\n const body = {\n tool_name: input.tool_name,\n tool_args: input.tool_args,\n context_messages: input.context_messages ?? null,\n originator: input.originator ?? { type: 'system' },\n session_id: input.session_id ?? null,\n client_metadata: input.client_metadata ?? null,\n idempotency_key: input.idempotency_key ?? null,\n }\n return request<CreateApprovalResponse>({\n method: 'POST',\n url: approvalUrl(this.baseUrl),\n apiKey: this.apiKey,\n body,\n timeoutMs: this.timeoutMs,\n maxRetries: this.maxRetries,\n retryOnPost: Boolean(input.idempotency_key),\n fetchImpl: this.fetchImpl,\n })\n }\n\n /**\n * Fetch the current state of an approval request.\n * Used by polling in `gated()` to detect status transitions.\n */\n async getApproval(approvalId: string): Promise<ApprovalRequest> {\n return request<ApprovalRequest>({\n method: 'GET',\n url: approvalUrl(this.baseUrl, approvalId),\n apiKey: this.apiKey,\n timeoutMs: this.timeoutMs,\n maxRetries: this.maxRetries,\n fetchImpl: this.fetchImpl,\n })\n }\n\n /**\n * Close the audit loop by reporting the outcome of the gated action.\n *\n * Single-shot: a second call returns 409 (PliuzConflictError).\n * Only the originating agent can report — others get 403 (PliuzForbiddenError).\n */\n async reportExecution(\n approvalId: string,\n input: ExecutionInput,\n ): Promise<ExecutionResult> {\n const body = {\n status: input.status,\n error: input.error ?? null,\n latency_ms: input.latency_ms ?? null,\n target_response_excerpt: input.target_response_excerpt ?? null,\n }\n return request<ExecutionResult>({\n method: 'POST',\n url: approvalUrl(this.baseUrl, approvalId, 'execution'),\n apiKey: this.apiKey,\n body,\n timeoutMs: this.timeoutMs,\n maxRetries: this.maxRetries,\n retryOnPost: false,\n fetchImpl: this.fetchImpl,\n })\n }\n}\n","/**\n * Field-level redaction applied client-side BEFORE sending to Pliuz.\n *\n * Non-negotiable architectural decision: sensitive fields (PII, secrets, PHI)\n * must never leave the caller's process in plaintext. The SDK applies\n * redaction on the client side, transmits the redacted payload, and the\n * backend never sees the raw values.\n *\n * ## Path syntax\n *\n * \"customer.ssn\" → payload.customer.ssn\n * \"items[*].card_number\" → every item's card_number\n * \"headers.authorization\" → payload.headers.authorization\n *\n * Limitations (intentional — keep the surface tiny):\n * - No JSONPath wildcards beyond `[*]`\n * - No filter expressions\n * - Missing keys are silently ignored\n */\n\nexport const REDACTED_PLACEHOLDER = '<redacted>' as const\n\ntype PathSegment = { key: string; isArrayWildcard: boolean }\n\n/**\n * Returns a deep copy of `payload` with values at `paths` replaced by\n * `REDACTED_PLACEHOLDER`. Does not mutate the input.\n *\n * @example\n * applyRedaction({ customer: { ssn: '123-45-6789' } }, ['customer.ssn'])\n * // → { customer: { ssn: '<redacted>' } }\n */\nexport function applyRedaction<T extends Record<string, unknown>>(\n payload: T,\n paths: readonly string[] | null | undefined,\n): T {\n if (!paths || paths.length === 0) {\n return deepClone(payload)\n }\n const result = deepClone(payload)\n for (const path of paths) {\n redactPath(result as Record<string, unknown>, parsePath(path))\n }\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Internal\n// ---------------------------------------------------------------------------\n\nfunction parsePath(path: string): PathSegment[] {\n if (!path) {\n throw new Error('redaction path cannot be empty')\n }\n\n const segments: PathSegment[] = []\n for (const raw of path.split('.')) {\n if (raw.endsWith('[*]')) {\n const key = raw.slice(0, -3)\n if (!key) {\n throw new Error(`redaction path segment before [*] cannot be empty: ${path}`)\n }\n segments.push({ key, isArrayWildcard: true })\n } else if (raw.includes('[') || raw.includes(']')) {\n throw new Error(`unsupported redaction syntax in '${path}' — only [*] is allowed`)\n } else {\n if (!raw) {\n throw new Error(`redaction path has empty segment: ${path}`)\n }\n segments.push({ key: raw, isArrayWildcard: false })\n }\n }\n return segments\n}\n\nfunction redactPath(node: unknown, segments: PathSegment[]): void {\n if (segments.length === 0) return\n if (!isPlainObject(node)) return\n\n const [head, ...rest] = segments\n if (!head) return\n const { key, isArrayWildcard } = head\n if (!(key in node)) return\n\n if (isArrayWildcard) {\n const target = node[key]\n if (!Array.isArray(target)) return\n if (rest.length === 0) {\n node[key] = target.map(() => REDACTED_PLACEHOLDER)\n return\n }\n for (const item of target) {\n redactPath(item, rest)\n }\n } else {\n if (rest.length === 0) {\n node[key] = REDACTED_PLACEHOLDER\n } else {\n redactPath(node[key], rest)\n }\n }\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\nfunction deepClone<T>(v: T): T {\n // Prefer structuredClone when available (Node 17+). Falls back to JSON\n // for environments without it (e.g. some bundler test setups).\n if (typeof structuredClone === 'function') {\n return structuredClone(v)\n }\n return JSON.parse(JSON.stringify(v)) as T\n}\n","/**\n * The `gated()` wrapper — the headline API of the Pliuz TypeScript SDK.\n *\n * Wraps any function (sync or async) so every call is gated by a Pliuz\n * approval request. The wrapped function always returns `Promise<TResult>`\n * even if the original is synchronous — gating is inherently async because\n * it involves an HTTP call.\n *\n * @example\n * import { gated } from '@pliuz/sdk'\n *\n * const issueRefund = gated(\n * {\n * policy: 'refund',\n * redact: ['customer.ssn'],\n * toolArgs: (customerId: string, amountCents: number) => ({\n * customer_id: customerId,\n * amount_cents: amountCents,\n * }),\n * },\n * async (customerId, amountCents) => stripe.refund(customerId, amountCents),\n * )\n *\n * const result = await issueRefund('cus_123', 5000)\n */\n\nimport { createHash } from 'node:crypto'\n\nimport { PliuzClient } from './client.js'\nimport {\n PliuzApprovalExpiredError,\n PliuzApprovalTimeoutError,\n PliuzEditNotApplicableError,\n PliuzRejectedError,\n} from './errors.js'\nimport { applyRedaction, REDACTED_PLACEHOLDER } from './redaction.js'\nimport type {\n ApprovalRequest,\n ExecutionStatus,\n Originator,\n} from './types.js'\n\nexport const DEFAULT_GATED_TIMEOUT_MS = 300_000 // 5 min — matches Pliuz default SLA\nexport const DEFAULT_GATED_POLL_INTERVAL_MS = 2000\n\nexport interface GatedOptions<TArgs extends readonly unknown[]> {\n /** Policy slug to bind this gate to. Default: backend resolves by toolName. */\n policy?: string\n\n /** Redaction paths applied to tool_args BEFORE sending. */\n redact?: readonly string[]\n\n /** Override the tool name. Default: `fn.name` (may be empty for anonymous). */\n toolName?: string\n\n /**\n * Map the wrapped function's args into a tool_args object.\n * Default: `(...args) => ({ args })` — wraps all positional args under\n * a single `args` key. Provide a custom mapper for cleaner audit trails.\n */\n toolArgs?: (...args: TArgs) => Record<string, unknown>\n\n /** Max ms to poll for the approval to resolve. Throws on timeout. */\n timeoutMs?: number\n\n /** Ms between GET /approvals/:id polls. */\n pollIntervalMs?: number\n\n /** Reuse an existing PliuzClient. Default: `new PliuzClient()`. */\n client?: PliuzClient\n\n /** Optional context for the human approver. */\n contextMessages?: readonly string[]\n\n /** Optional session id (groups related approvals in the UI). */\n sessionId?: string\n\n /** Optional originator (default: { type: 'system' }). */\n originator?: Originator\n\n /**\n * Map human-EDITED args (approval decided with action='edit') back onto\n * the wrapped function's argument tuple. Required to honor edits when a\n * custom `toolArgs` mapper is used (the SDK cannot invert an arbitrary\n * mapper). Without it, an edited approval throws\n * PliuzEditNotApplicableError instead of executing the original args.\n */\n applyFinalArgs?: (finalArgs: Record<string, unknown>, originalArgs: TArgs) => TArgs\n}\n\nconst TERMINAL_OK = new Set<string>(['approved'])\nconst TERMINAL_REJECT = new Set<string>(['rejected'])\nconst TERMINAL_EXPIRED = new Set<string>(['expired'])\n\n/**\n * Wrap a function so every call is gated by Pliuz.\n *\n * The returned function ALWAYS returns a Promise, even if the input is sync.\n * This is intentional — gating necessarily involves async HTTP calls.\n */\nexport function gated<TArgs extends readonly unknown[], TResult>(\n options: GatedOptions<TArgs>,\n fn: (...args: TArgs) => Promise<TResult> | TResult,\n): (...args: TArgs) => Promise<TResult> {\n const toolName = options.toolName ?? (fn.name || 'anonymous')\n const toolArgsMapper =\n options.toolArgs ??\n ((...args: TArgs): Record<string, unknown> => ({ args: args as unknown as unknown[] }))\n const timeoutMs = options.timeoutMs ?? DEFAULT_GATED_TIMEOUT_MS\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_GATED_POLL_INTERVAL_MS\n const redactPaths = options.redact\n\n return async (...args: TArgs): Promise<TResult> => {\n const activeClient = options.client ?? new PliuzClient()\n const rawArgs = toolArgsMapper(...args)\n const sendArgs = redactPaths && redactPaths.length > 0\n ? applyRedaction(rawArgs, redactPaths)\n : rawArgs\n // Key over PRE-redaction args: hashing the redacted payload collapses\n // calls that differ only in a redacted field (two transfers to different\n // IBANs) into one key — the second would replay the first's approval.\n // Only the truncated SHA-256 leaves the process, never the raw values.\n const idempotencyKey = idempotencyKeyFor(toolName, rawArgs, options.sessionId)\n const metadata: Record<string, unknown> = {}\n if (options.policy) metadata.policy = options.policy\n\n const response = await activeClient.createApproval({\n tool_name: toolName,\n tool_args: sendArgs,\n context_messages: options.contextMessages ?? null,\n originator: options.originator,\n session_id: options.sessionId ?? null,\n client_metadata: Object.keys(metadata).length > 0 ? metadata : null,\n idempotency_key: idempotencyKey,\n })\n\n const approvalId = response.id\n\n if (TERMINAL_REJECT.has(response.status)) {\n throw new PliuzRejectedError(approvalId, response.message ?? null)\n }\n if (TERMINAL_EXPIRED.has(response.status)) {\n throw new PliuzApprovalExpiredError(approvalId)\n }\n\n let approval: ApprovalRequest | null = null\n if (!TERMINAL_OK.has(response.status)) {\n // Poll\n const deadline = Date.now() + timeoutMs\n while (true) {\n if (Date.now() >= deadline) {\n throw new PliuzApprovalTimeoutError(approvalId, timeoutMs)\n }\n await sleep(pollIntervalMs)\n approval = await activeClient.getApproval(approvalId)\n if (terminalOrThrow(approval)) break\n }\n } else if (response.is_replay) {\n // Replayed already-approved request: a human may have EDITED the args\n // (final_args). Fresh auto-approvals can't carry edits — skip the fetch.\n approval = await activeClient.getApproval(approvalId)\n }\n\n // Honor human edits: execute final_args, NEVER the original args when\n // the approver changed them.\n let callArgs = args\n const finalArgs = approval?.final_args ?? null\n if (finalArgs) {\n callArgs = resolveEditedArgs(approvalId, rawArgs, finalArgs, args, options)\n }\n\n // Execute + report. The report is AWAITED: on serverless (Vercel/Lambda)\n // the runtime freezes once the handler resolves, so a fire-and-forget\n // report is routinely never sent — silently losing the audit loop.\n const started = Date.now()\n try {\n const result = await fn(...callArgs)\n const latencyMs = Date.now() - started\n await safeReport(activeClient, approvalId, 'success', null, latencyMs, result, redactPaths)\n return result\n } catch (e) {\n const latencyMs = Date.now() - started\n const errMsg = e instanceof Error ? e.message : String(e)\n await safeReport(activeClient, approvalId, 'error', errMsg.slice(0, 2000), latencyMs, null, redactPaths)\n throw e\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction idempotencyKeyFor(\n toolName: string,\n toolArgs: Record<string, unknown>,\n sessionId: string | undefined,\n): string {\n const payload = JSON.stringify(\n { tool: toolName, args: toolArgs, session: sessionId ?? null },\n Object.keys({ tool: 0, args: 0, session: 0 }).sort(),\n )\n // Canonicalize via sorted-key JSON stringify for deterministic hash\n const canonical = canonicalJSON({ tool: toolName, args: toolArgs, session: sessionId ?? null })\n void payload // silence unused\n return 'g_' + createHash('sha256').update(canonical).digest('hex').slice(0, 30)\n}\n\nfunction canonicalJSON(value: unknown): string {\n if (value === null || typeof value !== 'object') {\n return JSON.stringify(value)\n }\n if (Array.isArray(value)) {\n return '[' + value.map(canonicalJSON).join(',') + ']'\n }\n const obj = value as Record<string, unknown>\n const keys = Object.keys(obj).sort()\n return (\n '{' +\n keys.map((k) => JSON.stringify(k) + ':' + canonicalJSON(obj[k])).join(',') +\n '}'\n )\n}\n\n/**\n * Merge human-edited final_args over the original raw args. final_args is\n * authoritative (the edit modal pre-fills the FULL tool_args JSON), except\n * values left as the redaction placeholder — those are echoes of what we\n * sent; restore the original raw value rather than executing '<redacted>'.\n */\nfunction mergeFinalArgs(raw: unknown, final: unknown): unknown {\n if (isPlainRecord(raw) && isPlainRecord(final)) {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(final)) {\n out[k] = k in raw ? mergeFinalArgs(raw[k], v) : v\n }\n return out\n }\n if (final === REDACTED_PLACEHOLDER) return raw\n return final\n}\n\nfunction isPlainRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\n/**\n * Map human-edited args back onto the wrapped function's argument tuple.\n *\n * - custom `applyFinalArgs` mapper → caller decides.\n * - default toolArgs mapper ({ args: [...] }) → use the edited array.\n * - custom toolArgs mapper without applyFinalArgs → PliuzEditNotApplicableError:\n * executing the ORIGINAL args after a human approved something ELSE would\n * make the audit trail misrepresent what was approved vs executed.\n */\nfunction resolveEditedArgs<TArgs extends readonly unknown[]>(\n approvalId: string,\n rawArgs: Record<string, unknown>,\n finalArgs: Record<string, unknown>,\n originalArgs: TArgs,\n options: GatedOptions<TArgs>,\n): TArgs {\n const merged = mergeFinalArgs(rawArgs, finalArgs) as Record<string, unknown>\n if (options.applyFinalArgs) {\n return options.applyFinalArgs(merged, originalArgs)\n }\n if (options.toolArgs === undefined && Array.isArray(merged.args)) {\n return merged.args as unknown as TArgs\n }\n throw new PliuzEditNotApplicableError(approvalId, merged)\n}\n\nfunction terminalOrThrow(approval: ApprovalRequest): boolean {\n if (TERMINAL_OK.has(approval.status)) return true\n if (TERMINAL_REJECT.has(approval.status)) {\n throw new PliuzRejectedError(approval.id, approval.decision_reason)\n }\n if (TERMINAL_EXPIRED.has(approval.status)) {\n throw new PliuzApprovalExpiredError(approval.id)\n }\n return false\n}\n\nasync function safeReport(\n client: PliuzClient,\n approvalId: string,\n status: ExecutionStatus,\n errorMessage: string | null,\n latencyMs: number,\n result: unknown,\n redactPaths: readonly string[] | undefined,\n): Promise<void> {\n let excerpt: string | null = null\n if (result != null) {\n // The caller's redact paths apply to the RESULT too: a tool that\n // receives a redacted SSN often returns it. Without this the excerpt\n // re-leaked exactly the fields marked as never-leave-process.\n const toDump = redactPaths && redactPaths.length > 0 && isPlainRecord(result)\n ? applyRedaction(result, redactPaths)\n : result\n try {\n excerpt = JSON.stringify(toDump).slice(0, 2000)\n } catch {\n excerpt = String(toDump).slice(0, 2000)\n }\n }\n try {\n await client.reportExecution(approvalId, {\n status,\n error: errorMessage,\n latency_ms: latencyMs,\n target_response_excerpt: excerpt,\n })\n } catch {\n // Intentionally swallow — if reporting fails the audit log surfaces\n // 'execution unreported' but we don't want to crash the caller's flow.\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","/**\n * Vercel AI SDK adapter for Pliuz.\n *\n * Wraps any Vercel AI SDK `Tool` so its `execute` is gated by a Pliuz\n * approval request. The wrapped tool preserves `description` and\n * `parameters` so the LLM sees the tool identically — only the\n * execution path is gated.\n *\n * Install requires `ai >= 4.0` as a peer dependency.\n *\n * @example\n * import { tool } from 'ai'\n * import { z } from 'zod'\n * import { gatedTool } from '@pliuz/sdk/adapters/ai'\n *\n * const issueRefund = gatedTool(\n * { policy: 'refund', redact: ['customer.ssn'] },\n * tool({\n * description: 'Issue a refund to a customer',\n * parameters: z.object({\n * customer_id: z.string(),\n * amount_cents: z.number().int().positive(),\n * }),\n * execute: async ({ customer_id, amount_cents }) => {\n * return stripe.refund(customer_id, amount_cents)\n * },\n * }),\n * )\n */\n\nimport { gated } from '../gated.js'\nimport type { PliuzClient } from '../client.js'\nimport type { Originator } from '../types.js'\n\n/**\n * Minimal structural type that matches Vercel AI SDK's `Tool<TParams, TResult>`\n * without importing `ai` (it's a peer dep — adapter must work even if absent\n * from a consumer's tsconfig). The shape mirrors the v4 contract.\n */\nexport interface AITool<TInput, TResult> {\n description?: string\n parameters: unknown\n execute?: (input: TInput, options: unknown) => Promise<TResult> | TResult\n [key: string]: unknown\n}\n\n/**\n * Options for `gatedTool`. Mirrors the relevant fields of GatedOptions\n * without the `toolArgs` / `toolName` generic-parametric pieces (the\n * adapter sets toolArgs internally to surface the Vercel-AI input dict\n * directly as the Pliuz tool_args).\n */\nexport interface GatedToolOptions {\n policy?: string\n redact?: readonly string[]\n /**\n * Override the tool name reported to Pliuz. Defaults to the tool's\n * `description` (first 64 chars) or `'ai_tool'` if neither is set.\n */\n toolName?: string\n timeoutMs?: number\n pollIntervalMs?: number\n client?: PliuzClient\n contextMessages?: readonly string[]\n sessionId?: string\n originator?: Originator\n}\n\nexport const ADAPTER_NAME = 'vercel-ai' as const\n\n/**\n * Wrap a Vercel AI SDK tool so its `execute` is gated by Pliuz.\n *\n * If the tool has no `execute` (e.g. client-side tools), this is a\n * no-op — gating only makes sense on the server side.\n */\nexport function gatedTool<TInput, TResult>(\n options: GatedToolOptions,\n tool: AITool<TInput, TResult>,\n): AITool<TInput, TResult> {\n if (typeof tool.execute !== 'function') {\n // Client-side tool — nothing to gate.\n return tool\n }\n\n const toolName =\n options.toolName ??\n (typeof tool.description === 'string' ? tool.description.slice(0, 64) : 'ai_tool')\n\n const originalExecute = tool.execute\n // We bind the Vercel AI 2-arg `(input, options)` execute into a 1-arg\n // closure for `gated()`, which infers TArgs from the wrapped fn. The\n // closure captures `options` per-call via a mutable holder.\n let pendingOptions: unknown = undefined\n\n const gatedExecute1Arg = gated(\n {\n policy: options.policy,\n redact: options.redact,\n timeoutMs: options.timeoutMs,\n pollIntervalMs: options.pollIntervalMs,\n client: options.client,\n contextMessages: options.contextMessages,\n sessionId: options.sessionId,\n originator: options.originator,\n toolName,\n // Surface the Vercel-AI input dict directly as Pliuz tool_args\n // instead of wrapping in `{ args: [input] }` for cleaner audit logs.\n toolArgs: (input: TInput) =>\n isPlainObject(input) ? input : ({ input } as Record<string, unknown>),\n },\n async (input: TInput) => originalExecute(input, pendingOptions),\n )\n\n const wrappedExecute: AITool<TInput, TResult>['execute'] = async (input, opts) => {\n pendingOptions = opts\n return gatedExecute1Arg(input)\n }\n\n return {\n ...tool,\n execute: wrappedExecute,\n }\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n"]}
1
+ {"version":3,"sources":["../../src/version.ts","../../src/errors.ts","../../src/_http.ts","../../src/client.ts","../../src/redaction.ts","../../src/gated.ts","../../src/adapters/ai.ts"],"names":["sleep","createHash","isPlainObject"],"mappings":";;;;;;;AAIO,IAAM,OAAA,GAAU,OAAA;;;ACkBhB,IAAM,UAAA,GAAN,cAAyB,KAAA,CAAM;AAAA,EACpC,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,YAAA;AAEZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,iBAAA,GAAN,cAAgC,UAAA,CAAW;AAAA,EAChD,WAAA,CAAY,SAA0C,KAAA,EAAiB;AACrE,IAAA,KAAA,CAAM,OAAO,CAAA;AADuC,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAEpD,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAJsD,KAAA;AAKxD,CAAA;AAQO,IAAM,uBAAA,GAAN,cAAsC,UAAA,CAAW;AAAA,EACtD,YAA4B,IAAA,EAAc;AACxC,IAAA,KAAA;AAAA,MACE,mBAAmB,IAAI,CAAA,gHAAA;AAAA,KAEzB;AAJ0B,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAK1B,IAAA,IAAA,CAAK,IAAA,GAAO,yBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAP4B,IAAA;AAQ9B,CAAA;AAEO,IAAM,iBAAA,GAAN,cAAgC,UAAA,CAAW;AAAA,EAChD,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,aAAA,GAAN,cAA4B,UAAA,CAAW;AAAA,EAC5C,WAAA,CACkB,UAAA,EACA,SAAA,EAChB,OAAA,EACgB,OAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AALG,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAEA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EARkB,UAAA;AAAA,EACA,SAAA;AAAA,EAEA,OAAA;AAMpB,CAAA;AAEO,IAAM,oBAAA,GAAN,cAAmC,aAAA,CAAc;AAAA,EACtD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,cAAA,GAAN,cAA6B,aAAA,CAAc;AAAA,EAChD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,mBAAA,GAAN,cAAkC,aAAA,CAAc;AAAA,EACrD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,kBAAA,GAAN,cAAiC,aAAA,CAAc;AAAA,EACpD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,kBAAA,GAAN,cAAiC,aAAA,CAAc;AAAA,EACpD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,gBAAA,GAAN,cAA+B,aAAA,CAAc;AAAA,EAClD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,mBAAA,GAAN,cAAkC,aAAA,CAAc;AAAA,EACrD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEO,IAAM,gBAAA,GAAN,cAA+B,aAAA,CAAc;AAAA,EAClD,WAAA,CACE,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAMO,IAAM,kBAAA,GAAN,cAAiC,UAAA,CAAW;AAAA,EACjD,WAAA,CAA4B,YAAoC,MAAA,EAAuB;AACrF,IAAA,MAAM,GAAA,GAAM,SACR,CAAA,SAAA,EAAY,UAAU,kBAAkB,MAAM,CAAA,CAAA,GAC9C,YAAY,UAAU,CAAA,aAAA,CAAA;AAC1B,IAAA,KAAA,CAAM,GAAG,CAAA;AAJiB,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAAoC,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAK9D,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAP4B,UAAA;AAAA,EAAoC,MAAA;AAQlE,CAAA;AAEO,IAAM,yBAAA,GAAN,cAAwC,UAAA,CAAW;AAAA,EACxD,YAA4B,UAAA,EAAoB;AAC9C,IAAA,KAAA,CAAM,CAAA,SAAA,EAAY,UAAU,CAAA,+BAAA,CAAiC,CAAA;AADnC,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAE1B,IAAA,IAAA,CAAK,IAAA,GAAO,2BAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAJ4B,UAAA;AAK9B,CAAA;AAEO,IAAM,yBAAA,GAAN,cAAwC,UAAA,CAAW;AAAA,EACxD,WAAA,CAA4B,YAAoC,SAAA,EAAmB;AACjF,IAAA,KAAA;AAAA,MACE,CAAA,SAAA,EAAY,UAAU,CAAA,wBAAA,EAA2B,SAAS,CAAA,yEAAA;AAAA,KAE5D;AAJ0B,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAAoC,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAK9D,IAAA,IAAA,CAAK,IAAA,GAAO,2BAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAP4B,UAAA;AAAA,EAAoC,SAAA;AAQlE,CAAA;AAUO,IAAM,2BAAA,GAAN,cAA0C,UAAA,CAAW;AAAA,EAC1D,WAAA,CACkB,YACA,SAAA,EAChB;AACA,IAAA,KAAA;AAAA,MACE,YAAY,UAAU,CAAA,oPAAA;AAAA,KAIxB;AARgB,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAQhB,IAAA,IAAA,CAAK,IAAA,GAAO,6BAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAXkB,UAAA;AAAA,EACA,SAAA;AAWpB,CAAA;AAEA,IAAM,eAAA,GAAuH;AAAA,EAC3H,GAAA,EAAK,oBAAA;AAAA,EACL,GAAA,EAAK,cAAA;AAAA,EACL,GAAA,EAAK,mBAAA;AAAA,EACL,GAAA,EAAK,kBAAA;AAAA,EACL,GAAA,EAAK,kBAAA;AAAA,EACL,GAAA,EAAK,gBAAA;AAAA,EACL,GAAA,EAAK;AACP,CAAA;AAEO,SAAS,cAAA,CACd,UAAA,EACA,SAAA,EACA,OAAA,EACA,OAAA,EACe;AACf,EAAA,IAAI,UAAA,IAAc,GAAA,IAAO,UAAA,GAAa,GAAA,EAAK;AACzC,IAAA,OAAO,IAAI,gBAAA,CAAiB,UAAA,EAAY,SAAA,EAAW,SAAS,OAAO,CAAA;AAAA,EACrE;AACA,EAAA,MAAM,GAAA,GAAM,eAAA,CAAgB,UAAU,CAAA,IAAK,aAAA;AAC3C,EAAA,OAAO,IAAI,GAAA,CAAI,UAAA,EAAY,SAAA,EAAW,SAAS,OAAO,CAAA;AACxD;;;ACjPA,IAAM,kBAAA,uBAAyB,GAAA,CAAI,CAAC,OAAO,MAAA,EAAQ,SAAA,EAAW,KAAA,EAAO,QAAQ,CAAC,CAAA;AAG9E,IAAM,gBAAA,mBAAmB,IAAI,GAAA,CAAI,CAAC,GAAA,EAAK,KAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAC,CAAA;AAa/D,SAAS,SAAA,GAAoB;AAC3B,EAAA,OAAO,oBAAoB,OAAO,CAAA,CAAA;AACpC;AAEA,SAAS,aAAa,MAAA,EAAwC;AAC5D,EAAA,OAAO;AAAA,IACL,iBAAA,EAAmB,MAAA;AAAA,IACnB,cAAc,SAAA,EAAU;AAAA,IACxB,MAAA,EAAQ,kBAAA;AAAA,IACR,cAAA,EAAgB;AAAA,GAClB;AACF;AAEA,SAAS,SAAA,CAAU,OAAA,EAAiB,MAAA,GAAS,GAAA,EAAK,QAAQ,GAAA,EAAc;AAEtE,EAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,OAAO,MAAA,GAAS,CAAA,KAAM,UAAU,CAAA,CAAE,CAAA;AACxD,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,IAAI,CAAA;AACxC;AAEA,SAAS,WAAA,CAAY,MAAA,EAAgB,MAAA,EAAgB,WAAA,EAA+B;AAClF,EAAA,IAAI,CAAC,gBAAA,CAAiB,GAAA,CAAI,MAAM,GAAG,OAAO,KAAA;AAC1C,EAAA,IAAI,kBAAA,CAAmB,GAAA,CAAI,MAAM,CAAA,EAAG,OAAO,IAAA;AAC3C,EAAA,IAAI,MAAA,KAAW,MAAA,IAAU,WAAA,EAAa,OAAO,IAAA;AAC7C,EAAA,OAAO,KAAA;AACT;AAEA,eAAe,WAAW,QAAA,EAA4C;AACpE,EAAA,IAAI,OAA8B,EAAC;AACnC,EAAA,IAAI;AACF,IAAA,IAAA,GAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,EAC9B,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,MAAM,SAAA,GAAY,KAAK,KAAA,IAAS,eAAA;AAChC,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,QAAA,CAAS,UAAA,IAAc,iBAAA;AACvD,EAAA,MAAM,UAAU,IAAA,CAAK,OAAA;AACrB,EAAA,OAAO,cAAA,CAAe,QAAA,CAAS,MAAA,EAAQ,SAAA,EAAW,SAAS,OAAO,CAAA;AACpE;AAEA,SAAS,MAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;AAEA,eAAsB,QAAW,IAAA,EAAkC;AACjE,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAA,EAAK,MAAA,EAAQ,IAAA,EAAM,WAAW,UAAA,EAAY,WAAA,GAAc,KAAA,EAAO,SAAA,EAAU,GAAI,IAAA;AAC7F,EAAA,MAAM,OAAA,GAAU,aAAa,MAAM,CAAA;AAEnC,EAAA,IAAI,SAAA,GAA0B,IAAA;AAE9B,EAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,UAAA,GAAa,GAAG,OAAA,EAAA,EAAW;AAC1D,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,SAAS,CAAA;AAE5D,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,UAAU,GAAA,EAAK;AAAA,QAC9B,MAAA;AAAA,QACA,OAAA;AAAA,QACA,MAAM,IAAA,IAAQ,IAAA,GAAO,KAAA,CAAA,GAAY,IAAA,CAAK,UAAU,IAAI,CAAA;AAAA,QACpD,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AAAA,IACH,SAAS,CAAA,EAAG;AACV,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,MAAM,SAAA,GACJ,aAAa,KAAA,KACZ,CAAA,CAAE,SAAS,YAAA,IAAgB,gBAAA,CAAiB,IAAA,CAAK,CAAA,CAAE,OAAO,CAAA,CAAA;AAC7D,MAAA,SAAA,GAAY,YACR,IAAI,iBAAA,CAAkB,iCAAiC,SAAS,CAAA,EAAA,CAAI,IACpE,IAAI,iBAAA;AAAA,QACF,wBAAwB,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA,CAAA;AAAA,QAClE;AAAA,OACF;AACJ,MAAA,IAAI,OAAA,GAAU,YAAY,MAAM,SAAA;AAChC,MAAA,MAAM,KAAA,CAAM,SAAA,CAAU,OAAO,CAAC,CAAA;AAC9B,MAAA;AAAA,IACF;AACA,IAAA,YAAA,CAAa,KAAK,CAAA;AAElB,IAAA,IAAI,QAAA,CAAS,MAAA,IAAU,GAAA,IAAO,QAAA,CAAS,SAAS,GAAA,EAAK;AACnD,MAAA,IAAI;AACF,QAAA,OAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,MAC9B,SAAS,CAAA,EAAG;AACV,QAAA,MAAM,IAAI,aAAA;AAAA,UACR,QAAA,CAAS,MAAA;AAAA,UACT,cAAA;AAAA,UACA,qCAAqC,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,SACjF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,WAAA,CAAY,MAAA,EAAQ,QAAA,CAAS,MAAA,EAAQ,WAAW,CAAA,EAAG;AACrD,MAAA,IAAI,UAAU,UAAA,EAAY;AACxB,QAAA,MAAM,MAAM,WAAW,QAAQ,CAAA;AAAA,MACjC;AACA,MAAA,MAAM,KAAA,CAAM,SAAA,CAAU,OAAO,CAAC,CAAA;AAC9B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAM,WAAW,QAAQ,CAAA;AAAA,EACjC;AAGA,EAAA,MAAM,SAAA,IAAa,IAAI,aAAA,CAAc,CAAA,EAAG,aAAa,mCAAmC,CAAA;AAC1F;;;AC1GO,IAAM,gBAAA,GAAmB,mBAAA;AACzB,IAAM,kBAAA,GAAqB,GAAA;AAC3B,IAAM,mBAAA,GAAsB,CAAA;AAC5B,IAAM,WAAA,GAAc,eAAA;AACpB,IAAM,YAAA,GAAe,gBAAA;AA4B5B,SAAS,cAAc,QAAA,EAAsC;AAC3D,EAAA,IAAI,UAAU,OAAO,QAAA;AACrB,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,GAAM,WAAW,CAAA,EAAG;AAChE,IAAA,OAAO,OAAA,CAAQ,IAAI,WAAW,CAAA;AAAA,EAChC;AACA,EAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gDAAA,EAAmD,WAAW,CAAA,CAAA,CAAG,CAAA;AACnF;AAEA,SAAS,eAAe,QAAA,EAAsC;AAC5D,EAAA,IAAI,QAAA,EAAU,OAAO,QAAA,CAAS,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAChD,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,GAAM,YAAY,CAAA,EAAG;AACjE,IAAA,OAAO,QAAQ,GAAA,CAAI,YAAY,CAAA,CAAE,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAAA,EACrD;AACA,EAAA,OAAO,gBAAA;AACT;AAEA,SAAS,WAAA,CAAY,OAAA,EAAiB,UAAA,EAAqB,MAAA,EAAyB;AAClF,EAAA,IAAI,IAAA,GAAO,mBAAA;AACX,EAAA,IAAI,UAAA,EAAY,IAAA,IAAQ,CAAA,CAAA,EAAI,kBAAA,CAAmB,UAAU,CAAC,CAAA,CAAA;AAC1D,EAAA,IAAI,MAAA,EAAQ,IAAA,IAAQ,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AAC9B,EAAA,OAAO,OAAA,GAAU,IAAA;AACnB;AAGO,IAAM,gBAAA,GAAmB,EAAA;AAEzB,IAAM,cAAN,MAAkB;AAAA,EACN,MAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EAEjB,WAAA,CAAY,OAAA,GAA8B,EAAC,EAAG;AAC5C,IAAA,IAAA,CAAK,MAAA,GAAS,aAAA,CAAc,OAAA,CAAQ,MAAM,CAAA;AAC1C,IAAA,IAAA,CAAK,OAAA,GAAU,cAAA,CAAe,OAAA,CAAQ,OAAO,CAAA;AAC7C,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,kBAAA;AACtC,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,IAAc,mBAAA;AAExC,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA;AAC9C,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAe,KAAA,EAA6D;AAChF,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,gBAAA,EAAkB,MAAM,gBAAA,IAAoB,IAAA;AAAA,MAC5C,UAAA,EAAY,KAAA,CAAM,UAAA,IAAc,EAAE,MAAM,QAAA,EAAS;AAAA,MACjD,UAAA,EAAY,MAAM,UAAA,IAAc,IAAA;AAAA,MAChC,eAAA,EAAiB,MAAM,eAAA,IAAmB,IAAA;AAAA,MAC1C,eAAA,EAAiB,MAAM,eAAA,IAAmB;AAAA,KAC5C;AACA,IAAA,OAAO,OAAA,CAAgC;AAAA,MACrC,MAAA,EAAQ,MAAA;AAAA,MACR,GAAA,EAAK,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AAAA,MAC7B,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,IAAA;AAAA,MACA,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,WAAA,EAAa,OAAA,CAAQ,KAAA,CAAM,eAAe,CAAA;AAAA,MAC1C,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,WAAA,CAAY,UAAA,EAAoB,WAAA,EAAgD;AACpF,IAAA,MAAM,IAAA,GACJ,WAAA,IAAe,WAAA,GAAc,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA,EAAG,gBAAgB,CAAA,GAAI,CAAA;AACzF,IAAA,MAAM,GAAA,GAAM,IAAA,GAAO,CAAA,GACf,CAAA,EAAG,YAAY,IAAA,CAAK,OAAA,EAAS,UAAU,CAAC,SAAS,IAAI,CAAA,CAAA,GACrD,WAAA,CAAY,IAAA,CAAK,SAAS,UAAU,CAAA;AACxC,IAAA,OAAO,OAAA,CAAyB;AAAA,MAC9B,MAAA,EAAQ,KAAA;AAAA,MACR,GAAA;AAAA,MACA,QAAQ,IAAA,CAAK,MAAA;AAAA;AAAA,MAEb,SAAA,EAAW,IAAA,GAAO,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,SAAA,EAAW,IAAA,GAAO,GAAA,GAAO,GAAI,CAAA,GAAI,IAAA,CAAK,SAAA;AAAA,MAC1E,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAA,CACJ,UAAA,EACA,KAAA,EAC0B;AAC1B,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,KAAA,EAAO,MAAM,KAAA,IAAS,IAAA;AAAA,MACtB,UAAA,EAAY,MAAM,UAAA,IAAc,IAAA;AAAA,MAChC,uBAAA,EAAyB,MAAM,uBAAA,IAA2B;AAAA,KAC5D;AACA,IAAA,OAAO,OAAA,CAAyB;AAAA,MAC9B,MAAA,EAAQ,MAAA;AAAA,MACR,GAAA,EAAK,WAAA,CAAY,IAAA,CAAK,OAAA,EAAS,YAAY,WAAW,CAAA;AAAA,MACtD,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,IAAA;AAAA,MACA,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,WAAA,EAAa,KAAA;AAAA,MACb,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AAAA,EACH;AACF,CAAA;;;AC5KO,IAAM,oBAAA,GAAuB,YAAA;AAiB7B,SAAS,cAAA,CACd,OAAA,EACA,KAAA,EACA,MAAA,GAAS,KAAA,EACN;AACH,EAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAChC,IAAA,OAAO,UAAU,OAAO,CAAA;AAAA,EAC1B;AACA,EAAA,MAAM,MAAA,GAAS,UAAU,OAAO,CAAA;AAChC,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,OAAA,GAAU,UAAA,CAAW,MAAA,EAAmC,SAAA,CAAU,IAAI,CAAC,CAAA;AAC7E,IAAA,IAAI,MAAA,IAAU,CAAC,OAAA,EAAS;AACtB,MAAA,MAAM,IAAI,wBAAwB,IAAI,CAAA;AAAA,IACxC;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAMA,SAAS,UAAU,IAAA,EAA6B;AAC9C,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,MAAM,IAAI,MAAM,gCAAgC,CAAA;AAAA,EAClD;AAEA,EAAA,MAAM,WAA0B,EAAC;AACjC,EAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,EAAG;AACjC,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,KAAK,CAAA,EAAG;AACvB,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAC3B,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mDAAA,EAAsD,IAAI,CAAA,CAAE,CAAA;AAAA,MAC9E;AACA,MAAA,QAAA,CAAS,IAAA,CAAK,EAAE,GAAA,EAAK,eAAA,EAAiB,MAAM,CAAA;AAAA,IAC9C,CAAA,MAAA,IAAW,IAAI,QAAA,CAAS,GAAG,KAAK,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,EAAG;AACjD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoC,IAAI,CAAA,4BAAA,CAAyB,CAAA;AAAA,IACnF,CAAA,MAAO;AACL,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,IAAI,CAAA,CAAE,CAAA;AAAA,MAC7D;AACA,MAAA,QAAA,CAAS,KAAK,EAAE,GAAA,EAAK,GAAA,EAAK,eAAA,EAAiB,OAAO,CAAA;AAAA,IACpD;AAAA,EACF;AACA,EAAA,OAAO,QAAA;AACT;AAQA,SAAS,UAAA,CAAW,MAAe,QAAA,EAAkC;AACnE,EAAA,IAAI,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAClC,EAAA,IAAI,CAAC,aAAA,CAAc,IAAI,CAAA,EAAG,OAAO,KAAA;AAEjC,EAAA,MAAM,CAAC,IAAA,EAAM,GAAG,IAAI,CAAA,GAAI,QAAA;AACxB,EAAA,IAAI,CAAC,MAAM,OAAO,KAAA;AAClB,EAAA,MAAM,EAAE,GAAA,EAAK,eAAA,EAAgB,GAAI,IAAA;AACjC,EAAA,IAAI,EAAE,GAAA,IAAO,IAAA,CAAA,EAAO,OAAO,KAAA;AAE3B,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,MAAM,MAAA,GAAS,KAAK,GAAG,CAAA;AACvB,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,GAAG,OAAO,KAAA;AACnC,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,MAAM,oBAAoB,CAAA;AACjD,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,IAAI,OAAA,GAAU,OAAO,MAAA,GAAS,CAAA;AAC9B,IAAA,KAAA,MAAW,QAAQ,MAAA,EAAQ;AACzB,MAAA,IAAI,CAAC,UAAA,CAAW,IAAA,EAAM,IAAI,GAAG,OAAA,GAAU,KAAA;AAAA,IACzC;AACA,IAAA,OAAO,OAAA;AAAA,EACT,CAAA,MAAO;AACL,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,oBAAA;AACZ,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA,EAAG,IAAI,CAAA;AAAA,EACnC;AACF;AAEA,SAAS,cAAc,CAAA,EAA0C;AAC/D,EAAA,OAAO,OAAO,MAAM,QAAA,IAAY,CAAA,KAAM,QAAQ,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE;AAEA,SAAS,UAAa,CAAA,EAAS;AAG7B,EAAA,IAAI,OAAO,oBAAoB,UAAA,EAAY;AACzC,IAAA,OAAO,gBAAgB,CAAC,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA;AACrC;;;AC7FO,IAAM,wBAAA,GAA2B,GAAA;AACjC,IAAM,8BAAA,GAAiC,GAAA;AAsD9C,IAAM,WAAA,mBAAc,IAAI,GAAA,CAAY,CAAC,UAAU,CAAC,CAAA;AAChD,IAAM,eAAA,mBAAkB,IAAI,GAAA,CAAY,CAAC,UAAU,CAAC,CAAA;AACpD,IAAM,gBAAA,mBAAmB,IAAI,GAAA,CAAY,CAAC,SAAS,CAAC,CAAA;AAQ7C,SAAS,KAAA,CACd,SACA,EAAA,EACsC;AACtC,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,QAAA,KAAa,EAAA,CAAG,IAAA,IAAQ,WAAA,CAAA;AACjD,EAAA,MAAM,iBACJ,OAAA,CAAQ,QAAA,KACP,CAAA,GAAI,IAAA,MAA0C,EAAE,IAAA,EAAmC,CAAA,CAAA;AACtF,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,wBAAA;AACvC,EAAA,MAAM,cAAA,GAAiB,QAAQ,cAAA,IAAkB,8BAAA;AACjD,EAAA,MAAM,cAAc,OAAA,CAAQ,MAAA;AAE5B,EAAA,OAAO,UAAU,IAAA,KAAkC;AACjD,IAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,MAAA,IAAU,IAAI,WAAA,EAAY;AACvD,IAAA,MAAM,OAAA,GAAU,cAAA,CAAe,GAAG,IAAI,CAAA;AACtC,IAAA,MAAM,QAAA,GAAW,WAAA,IAAe,WAAA,CAAY,MAAA,GAAS,CAAA,GACjD,cAAA,CAAe,OAAA,EAAS,WAAA,EAAa,OAAA,CAAQ,YAAA,IAAgB,KAAK,CAAA,GAClE,OAAA;AAKJ,IAAA,MAAM,cAAA,GAAiB,iBAAA,CAAkB,QAAA,EAAU,OAAA,EAAS,QAAQ,SAAS,CAAA;AAC7E,IAAA,MAAM,WAAoC,EAAC;AAC3C,IAAA,IAAI,OAAA,CAAQ,MAAA,EAAQ,QAAA,CAAS,MAAA,GAAS,OAAA,CAAQ,MAAA;AAE9C,IAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,cAAA,CAAe;AAAA,MACjD,SAAA,EAAW,QAAA;AAAA,MACX,SAAA,EAAW,QAAA;AAAA,MACX,gBAAA,EAAkB,QAAQ,eAAA,IAAmB,IAAA;AAAA,MAC7C,YAAY,OAAA,CAAQ,UAAA;AAAA,MACpB,UAAA,EAAY,QAAQ,SAAA,IAAa,IAAA;AAAA,MACjC,iBAAiB,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,CAAE,MAAA,GAAS,IAAI,QAAA,GAAW,IAAA;AAAA,MAC/D,eAAA,EAAiB;AAAA,KAClB,CAAA;AAED,IAAA,MAAM,aAAa,QAAA,CAAS,EAAA;AAE5B,IAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACxC,MAAA,MAAM,IAAI,kBAAA,CAAmB,UAAA,EAAY,QAAA,CAAS,WAAW,IAAI,CAAA;AAAA,IACnE;AACA,IAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACzC,MAAA,MAAM,IAAI,0BAA0B,UAAU,CAAA;AAAA,IAChD;AAEA,IAAA,IAAI,QAAA,GAAmC,IAAA;AACvC,IAAA,IAAI,CAAC,WAAA,CAAY,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AAKrC,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAC9B,MAAA,OAAO,IAAA,EAAM;AACX,QAAA,MAAM,WAAA,GAAc,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI;AACxC,QAAA,IAAI,eAAe,CAAA,EAAG;AACpB,UAAA,MAAM,IAAI,yBAAA,CAA0B,UAAA,EAAY,SAAS,CAAA;AAAA,QAC3D;AACA,QAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,WAAA,EAAa,cAAA,GAAiB,GAAI,CAAA,GAAI,GAAI,CAAC,CAAA;AAC9F,QAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,QAAA,QAAA,GAAW,MAAM,YAAA,CAAa,WAAA,CAAY,UAAA,EAAY,WAAW,CAAA;AACjE,QAAA,IAAI,eAAA,CAAgB,QAAQ,CAAA,EAAG;AAG/B,QAAA,IAAI,KAAK,GAAA,EAAI,GAAI,YAAY,GAAA,EAAK,MAAMA,OAAM,cAAc,CAAA;AAAA,MAC9D;AAAA,IACF,CAAA,MAAA,IAAW,SAAS,SAAA,EAAW;AAG7B,MAAA,QAAA,GAAW,MAAM,YAAA,CAAa,WAAA,CAAY,UAAU,CAAA;AAAA,IACtD;AAIA,IAAA,IAAI,QAAA,GAAW,IAAA;AACf,IAAA,MAAM,SAAA,GAAY,UAAU,UAAA,IAAc,IAAA;AAC1C,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,QAAA,GAAW,iBAAA,CAAkB,UAAA,EAAY,OAAA,EAAS,SAAA,EAAW,MAAM,OAAO,CAAA;AAAA,IAC5E;AAKA,IAAA,MAAM,OAAA,GAAU,KAAK,GAAA,EAAI;AACzB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,GAAG,QAAQ,CAAA;AACnC,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,EAAI,GAAI,OAAA;AAC/B,MAAA,MAAM,WAAW,YAAA,EAAc,UAAA,EAAY,WAAW,IAAA,EAAM,SAAA,EAAW,QAAQ,WAAW,CAAA;AAC1F,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,CAAA,EAAG;AACV,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,EAAI,GAAI,OAAA;AAC/B,MAAA,MAAM,SAAS,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AACxD,MAAA,MAAM,UAAA,CAAW,YAAA,EAAc,UAAA,EAAY,OAAA,EAAS,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,GAAI,CAAA,EAAG,SAAA,EAAW,IAAA,EAAM,WAAW,CAAA;AACvG,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAMA,SAAS,iBAAA,CACP,QAAA,EACA,QAAA,EACA,SAAA,EACQ;AACR,EAAgB,IAAA,CAAK,SAAA;AAAA,IACnB,EAAE,IAAA,EAAM,QAAA,EAAU,MAAM,QAAA,EAAU,OAAA,EAAS,aAAa,IAAA,EAAK;AAAA,IAC7D,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,OAAA,EAAS,CAAA,EAAG,CAAA,CAAE,IAAA;AAAK;AAGrD,EAAA,MAAM,SAAA,GAAY,aAAA,CAAc,EAAE,IAAA,EAAM,QAAA,EAAU,MAAM,QAAA,EAAU,OAAA,EAAS,SAAA,IAAa,IAAA,EAAM,CAAA;AAE9F,EAAA,OAAO,IAAA,GAAOC,iBAAA,CAAW,QAAQ,CAAA,CAAE,MAAA,CAAO,SAAS,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAChF;AAEA,SAAS,cAAc,KAAA,EAAwB;AAC7C,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,EAAU;AAC/C,IAAA,OAAO,IAAA,CAAK,UAAU,KAAK,CAAA;AAAA,EAC7B;AACA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,IAAA,OAAO,MAAM,KAAA,CAAM,GAAA,CAAI,aAAa,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,GAAI,GAAA;AAAA,EACpD;AACA,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,GAAG,EAAE,IAAA,EAAK;AACnC,EAAA,OACE,MACA,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,UAAU,CAAC,CAAA,GAAI,GAAA,GAAM,aAAA,CAAc,IAAI,CAAC,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,GACzE,GAAA;AAEJ;AAQA,SAAS,cAAA,CAAe,KAAc,KAAA,EAAyB;AAC7D,EAAA,IAAI,aAAA,CAAc,GAAG,CAAA,IAAK,aAAA,CAAc,KAAK,CAAA,EAAG;AAC9C,IAAA,MAAM,MAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC1C,MAAA,GAAA,CAAI,CAAC,IAAI,CAAA,IAAK,GAAA,GAAM,eAAe,GAAA,CAAI,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,CAAA;AAAA,IAClD;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,IAAI,KAAA,KAAU,sBAAsB,OAAO,GAAA;AAC3C,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,cAAc,CAAA,EAA0C;AAC/D,EAAA,OAAO,OAAO,MAAM,QAAA,IAAY,CAAA,KAAM,QAAQ,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE;AAWA,SAAS,iBAAA,CACP,UAAA,EACA,OAAA,EACA,SAAA,EACA,cACA,OAAA,EACO;AACP,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,OAAA,EAAS,SAAS,CAAA;AAChD,EAAA,IAAI,QAAQ,cAAA,EAAgB;AAC1B,IAAA,OAAO,OAAA,CAAQ,cAAA,CAAe,MAAA,EAAQ,YAAY,CAAA;AAAA,EACpD;AACA,EAAA,IAAI,QAAQ,QAAA,KAAa,MAAA,IAAa,MAAM,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA,EAAG;AAChE,IAAA,OAAO,MAAA,CAAO,IAAA;AAAA,EAChB;AACA,EAAA,MAAM,IAAI,2BAAA,CAA4B,UAAA,EAAY,MAAM,CAAA;AAC1D;AAEA,SAAS,gBAAgB,QAAA,EAAoC;AAC3D,EAAA,IAAI,WAAA,CAAY,GAAA,CAAI,QAAA,CAAS,MAAM,GAAG,OAAO,IAAA;AAC7C,EAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACxC,IAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,EAAA,EAAI,SAAS,eAAe,CAAA;AAAA,EACpE;AACA,EAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACzC,IAAA,MAAM,IAAI,yBAAA,CAA0B,QAAA,CAAS,EAAE,CAAA;AAAA,EACjD;AACA,EAAA,OAAO,KAAA;AACT;AAEA,eAAe,WACb,MAAA,EACA,UAAA,EACA,QACA,YAAA,EACA,SAAA,EACA,QACA,WAAA,EACe;AACf,EAAA,IAAI,OAAA,GAAyB,IAAA;AAC7B,EAAA,IAAI,UAAU,IAAA,EAAM;AAIlB,IAAA,MAAM,MAAA,GAAS,WAAA,IAAe,WAAA,CAAY,MAAA,GAAS,CAAA,IAAK,aAAA,CAAc,MAAM,CAAA,GACxE,cAAA,CAAe,MAAA,EAAQ,WAAW,CAAA,GAClC,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,KAAK,SAAA,CAAU,MAAM,CAAA,CAAE,KAAA,CAAM,GAAG,GAAI,CAAA;AAAA,IAChD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAA,GAAU,MAAA,CAAO,MAAM,CAAA,CAAE,KAAA,CAAM,GAAG,GAAI,CAAA;AAAA,IACxC;AAAA,EACF;AACA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,CAAO,gBAAgB,UAAA,EAAY;AAAA,MACvC,MAAA;AAAA,MACA,KAAA,EAAO,YAAA;AAAA,MACP,UAAA,EAAY,SAAA;AAAA,MACZ,uBAAA,EAAyB;AAAA,KAC1B,CAAA;AAAA,EACH,CAAA,CAAA,MAAQ;AAAA,EAGR;AACF;AAEA,SAASD,OAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;;;ACzQO,IAAM,YAAA,GAAe;AAQrB,SAAS,SAAA,CACd,SACA,IAAA,EACyB;AACzB,EAAA,IAAI,OAAO,IAAA,CAAK,OAAA,KAAY,UAAA,EAAY;AAEtC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAW,OAAA,CAAQ,QAAA;AACzB,EAAA,IAAI,OAAO,QAAA,KAAa,QAAA,IAAY,QAAA,CAAS,IAAA,OAAW,EAAA,EAAI;AAC1D,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KAGF;AAAA,EACF;AAEA,EAAA,MAAM,kBAAkB,IAAA,CAAK,OAAA;AAE7B,EAAA,MAAM,cAAA,GAAqD,OAAO,KAAA,EAAO,IAAA,KAAS;AAKhF,IAAA,MAAM,gBAAA,GAAmB,KAAA;AAAA,MACvB;AAAA,QACE,QAAQ,OAAA,CAAQ,MAAA;AAAA,QAChB,QAAQ,OAAA,CAAQ,MAAA;AAAA,QAChB,WAAW,OAAA,CAAQ,SAAA;AAAA,QACnB,gBAAgB,OAAA,CAAQ,cAAA;AAAA,QACxB,QAAQ,OAAA,CAAQ,MAAA;AAAA,QAChB,iBAAiB,OAAA,CAAQ,eAAA;AAAA,QACzB,WAAW,OAAA,CAAQ,SAAA;AAAA,QACnB,YAAY,OAAA,CAAQ,UAAA;AAAA,QACpB,QAAA;AAAA;AAAA;AAAA,QAGA,QAAA,EAAU,CAAC,GAAA,KACTE,cAAAA,CAAc,GAAG,CAAA,GAAI,GAAA,GAAO,EAAE,KAAA,EAAO,GAAA;AAAI,OAC7C;AAAA,MACA,OAAO,GAAA,KAAgB,eAAA,CAAgB,GAAA,EAAK,IAAI;AAAA,KAClD;AACA,IAAA,OAAO,iBAAiB,KAAK,CAAA;AAAA,EAC/B,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,OAAA,EAAS;AAAA,GACX;AACF;AAEA,SAASA,eAAc,CAAA,EAA0C;AAC/D,EAAA,OAAO,OAAO,MAAM,QAAA,IAAY,CAAA,KAAM,QAAQ,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AAChE","file":"ai.cjs","sourcesContent":["/**\n * Single source of truth for the package version.\n * Kept in sync with `package.json` by release tooling at publish time.\n */\nexport const VERSION = '0.2.2' as const\n","/**\n * Error hierarchy for the Pliuz SDK.\n *\n * All exceptions extend `PliuzError`. HTTP-level failures use `PliuzApiError`\n * subclasses keyed by status code, so callers can do narrow `instanceof` checks:\n *\n * ```ts\n * try {\n * await pliuz.createApproval(...)\n * } catch (e) {\n * if (e instanceof PliuzAuthError) {\n * // refresh API key\n * } else if (e instanceof PliuzPolicyError) {\n * // no policy matched — define a catch-all\n * } else if (e instanceof PliuzApiError) {\n * // other 4xx/5xx\n * }\n * throw e\n * }\n * ```\n */\n\nexport class PliuzError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PliuzError'\n // Maintain proper prototype chain for `instanceof` after transpile (CJS target)\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzNetworkError extends PliuzError {\n constructor(message: string, public override readonly cause?: unknown) {\n super(message)\n this.name = 'PliuzNetworkError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\n/**\n * A redaction path was syntactically valid but matched no field. Thrown only\n * in strict mode (`redactStrict: true`) to catch the silent-leak footgun where\n * a typo like `'customer.ssnn'` would otherwise be a no-op, leaving the real\n * `customer.ssn` unredacted in the payload sent to Pliuz.\n */\nexport class PliuzRedactionPathError extends PliuzError {\n constructor(public readonly path: string) {\n super(\n `redaction path '${path}' did not match any field in the payload (strict mode). ` +\n 'Fix the path or set redactStrict=false to ignore misses.',\n )\n this.name = 'PliuzRedactionPathError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzTimeoutError extends PliuzError {\n constructor(message: string) {\n super(message)\n this.name = 'PliuzTimeoutError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzApiError extends PliuzError {\n constructor(\n public readonly statusCode: number,\n public readonly errorCode: string,\n message: string,\n public readonly details?: Record<string, unknown>,\n ) {\n super(message)\n this.name = 'PliuzApiError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzValidationError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzValidationError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzAuthError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzAuthError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzForbiddenError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzForbiddenError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzNotFoundError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzNotFoundError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzConflictError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzConflictError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzPolicyError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzPolicyError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzRateLimitError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzRateLimitError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzServerError extends PliuzApiError {\n constructor(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(statusCode, errorCode, message, details)\n this.name = 'PliuzServerError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\n// ---------------------------------------------------------------------------\n// gated() lifecycle errors — raised by the wrapper, NOT by direct client calls.\n// ---------------------------------------------------------------------------\n\nexport class PliuzRejectedError extends PliuzError {\n constructor(public readonly approvalId: string, public readonly reason: string | null) {\n const msg = reason\n ? `approval ${approvalId} was rejected: ${reason}`\n : `approval ${approvalId} was rejected`\n super(msg)\n this.name = 'PliuzRejectedError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzApprovalExpiredError extends PliuzError {\n constructor(public readonly approvalId: string) {\n super(`approval ${approvalId} expired before a human decided`)\n this.name = 'PliuzApprovalExpiredError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class PliuzApprovalTimeoutError extends PliuzError {\n constructor(public readonly approvalId: string, public readonly timeoutMs: number) {\n super(\n `approval ${approvalId} did not resolve within ${timeoutMs}ms ` +\n '(SDK polling timeout — approval may still be pending server-side)',\n )\n this.name = 'PliuzApprovalTimeoutError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\n/**\n * A human approved with EDITED args (action='edit') but the SDK cannot map\n * `final_args` back onto the wrapped function's parameters. The SDK refuses\n * to execute the ORIGINAL (unapproved) args — that would make the audit\n * trail lie about what was approved vs executed. Carries `finalArgs` so the\n * caller can apply the edit manually, or pass an `applyFinalArgs` mapper in\n * GatedOptions to handle edits automatically.\n */\nexport class PliuzEditNotApplicableError extends PliuzError {\n constructor(\n public readonly approvalId: string,\n public readonly finalArgs: Record<string, unknown>,\n ) {\n super(\n `approval ${approvalId} was approved with edited args, but they cannot be ` +\n 'mapped back to the wrapped function (custom toolArgs mapper without ' +\n 'applyFinalArgs, or incompatible shape) — refusing to execute the ' +\n 'original (unapproved) args. Apply e.finalArgs manually.',\n )\n this.name = 'PliuzEditNotApplicableError'\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nconst STATUS_TO_ERROR: Record<number, new (s: number, c: string, m: string, d?: Record<string, unknown>) => PliuzApiError> = {\n 400: PliuzValidationError,\n 401: PliuzAuthError,\n 403: PliuzForbiddenError,\n 404: PliuzNotFoundError,\n 409: PliuzConflictError,\n 422: PliuzPolicyError,\n 429: PliuzRateLimitError,\n}\n\nexport function errorForStatus(\n statusCode: number,\n errorCode: string,\n message: string,\n details?: Record<string, unknown>,\n): PliuzApiError {\n if (statusCode >= 500 && statusCode < 600) {\n return new PliuzServerError(statusCode, errorCode, message, details)\n }\n const Cls = STATUS_TO_ERROR[statusCode] ?? PliuzApiError\n return new Cls(statusCode, errorCode, message, details)\n}\n","/**\n * Internal HTTP layer — shared by PliuzClient.\n *\n * Centralizes: header injection, error mapping, exponential-backoff retries\n * for idempotent operations, and JSON parsing.\n *\n * NOT public API — only `PliuzClient` should import from here.\n */\n\nimport { VERSION } from './version.js'\nimport type { ApiErrorBody } from './types.js'\nimport {\n PliuzApiError,\n PliuzNetworkError,\n PliuzTimeoutError,\n errorForStatus,\n} from './errors.js'\n\n// HTTP methods safe to retry without risking duplicate side-effects.\nconst IDEMPOTENT_METHODS = new Set(['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'])\n\n// Retry-able status codes — server hiccups, NOT client errors.\nconst RETRYABLE_STATUS = new Set([408, 429, 500, 502, 503, 504])\n\nexport interface RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE'\n url: string\n apiKey: string\n body?: Record<string, unknown> | null\n timeoutMs: number\n maxRetries: number\n retryOnPost?: boolean\n fetchImpl: typeof fetch\n}\n\nfunction userAgent(): string {\n return `pliuz-typescript/${VERSION}`\n}\n\nfunction buildHeaders(apiKey: string): Record<string, string> {\n return {\n 'X-Pliuz-Api-Key': apiKey,\n 'User-Agent': userAgent(),\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n }\n}\n\nfunction backoffMs(attempt: number, baseMs = 500, capMs = 8000): number {\n // Exponential with full jitter (AWS architecture blog formula).\n const expo = Math.min(capMs, baseMs * 2 ** (attempt - 1))\n return Math.floor(Math.random() * expo)\n}\n\nfunction isRetryable(method: string, status: number, retryOnPost: boolean): boolean {\n if (!RETRYABLE_STATUS.has(status)) return false\n if (IDEMPOTENT_METHODS.has(method)) return true\n if (method === 'POST' && retryOnPost) return true\n return false\n}\n\nasync function parseError(response: Response): Promise<PliuzApiError> {\n let body: Partial<ApiErrorBody> = {}\n try {\n body = (await response.json()) as Partial<ApiErrorBody>\n } catch {\n /* non-JSON body — fall through with empty */\n }\n const errorCode = body.error ?? 'unknown_error'\n const message = body.message ?? response.statusText ?? 'Pliuz API error'\n const details = body.details\n return errorForStatus(response.status, errorCode, message, details)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport async function request<T>(opts: RequestOptions): Promise<T> {\n const { method, url, apiKey, body, timeoutMs, maxRetries, retryOnPost = false, fetchImpl } = opts\n const headers = buildHeaders(apiKey)\n\n let lastError: Error | null = null\n\n for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n\n let response: Response\n try {\n response = await fetchImpl(url, {\n method,\n headers,\n body: body == null ? undefined : JSON.stringify(body),\n signal: controller.signal,\n })\n } catch (e) {\n clearTimeout(timer)\n const isTimeout =\n e instanceof Error &&\n (e.name === 'AbortError' || /abort|timeout/i.test(e.message))\n lastError = isTimeout\n ? new PliuzTimeoutError(`Pliuz request timed out after ${timeoutMs}ms`)\n : new PliuzNetworkError(\n `Pliuz network error: ${e instanceof Error ? e.message : String(e)}`,\n e,\n )\n if (attempt > maxRetries) throw lastError\n await sleep(backoffMs(attempt))\n continue\n }\n clearTimeout(timer)\n\n if (response.status >= 200 && response.status < 300) {\n try {\n return (await response.json()) as T\n } catch (e) {\n throw new PliuzApiError(\n response.status,\n 'invalid_json',\n `Pliuz returned non-JSON 2xx body: ${e instanceof Error ? e.message : String(e)}`,\n )\n }\n }\n\n if (isRetryable(method, response.status, retryOnPost)) {\n if (attempt > maxRetries) {\n throw await parseError(response)\n }\n await sleep(backoffMs(attempt))\n continue\n }\n\n throw await parseError(response)\n }\n\n // Unreachable — the loop always returns or throws.\n throw lastError ?? new PliuzApiError(0, 'exhausted', 'retry loop exhausted unexpectedly')\n}\n","/**\n * PliuzClient — the SDK entry point.\n *\n * Reads PLIUZ_API_KEY env var by default (Node only). Apply redaction\n * client-side via `applyRedaction` before passing tool_args; the client\n * does NOT redact for you (separation of concerns — the `gated()` wrapper\n * in Fase 7 will wire them together).\n *\n * @example\n * import { PliuzClient, applyRedaction } from '@pliuz/sdk'\n *\n * const pliuz = new PliuzClient() // reads PLIUZ_API_KEY\n *\n * const response = await pliuz.createApproval({\n * tool_name: 'issue_refund',\n * tool_args: applyRedaction(\n * { customer: { ssn: '...', id: 'cus_123' }, amount_cents: 5000 },\n * ['customer.ssn'],\n * ),\n * idempotency_key: 'refund-cus_123-2026-05-21-001',\n * })\n */\n\nimport { request } from './_http.js'\nimport type {\n ApprovalRequest,\n CreateApprovalInput,\n CreateApprovalResponse,\n ExecutionInput,\n ExecutionResult,\n} from './types.js'\n\nexport const DEFAULT_BASE_URL = 'https://pliuz.com'\nexport const DEFAULT_TIMEOUT_MS = 30_000\nexport const DEFAULT_MAX_RETRIES = 3\nexport const ENV_API_KEY = 'PLIUZ_API_KEY'\nexport const ENV_BASE_URL = 'PLIUZ_BASE_URL'\n\nexport interface PliuzClientOptions {\n /**\n * Pliuz API key (per-agent). Defaults to `process.env.PLIUZ_API_KEY`.\n * NEVER hardcode in source — read from env or a secrets manager.\n */\n apiKey?: string\n\n /**\n * Base URL (no trailing slash). Defaults to `process.env.PLIUZ_BASE_URL`\n * or `https://pliuz.com`.\n */\n baseUrl?: string\n\n /** Per-request timeout in milliseconds. Default: 30 000. */\n timeoutMs?: number\n\n /** Max retries for transient failures (network / 5xx / 429). Default: 3. */\n maxRetries?: number\n\n /**\n * Custom fetch implementation. Defaults to global `fetch` (Node ≥18).\n * Use for testing (MSW, vitest-fetch-mock) or to inject proxy/keepalive.\n */\n fetch?: typeof fetch\n}\n\nfunction resolveApiKey(explicit: string | undefined): string {\n if (explicit) return explicit\n if (typeof process !== 'undefined' && process.env?.[ENV_API_KEY]) {\n return process.env[ENV_API_KEY]\n }\n throw new Error(`Pliuz API key not provided. Pass apiKey or set $${ENV_API_KEY}.`)\n}\n\nfunction resolveBaseUrl(explicit: string | undefined): string {\n if (explicit) return explicit.replace(/\\/+$/, '')\n if (typeof process !== 'undefined' && process.env?.[ENV_BASE_URL]) {\n return process.env[ENV_BASE_URL].replace(/\\/+$/, '')\n }\n return DEFAULT_BASE_URL\n}\n\nfunction approvalUrl(baseUrl: string, approvalId?: string, suffix?: string): string {\n let path = '/api/v1/approvals'\n if (approvalId) path += `/${encodeURIComponent(approvalId)}`\n if (suffix) path += `/${suffix}`\n return baseUrl + path\n}\n\n/** Max server-side long-poll window (matches backend cap). */\nexport const MAX_WAIT_SECONDS = 25\n\nexport class PliuzClient {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly timeoutMs: number\n private readonly maxRetries: number\n private readonly fetchImpl: typeof fetch\n\n constructor(options: PliuzClientOptions = {}) {\n this.apiKey = resolveApiKey(options.apiKey)\n this.baseUrl = resolveBaseUrl(options.baseUrl)\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES\n\n const fetchImpl = options.fetch ?? globalThis.fetch\n if (!fetchImpl) {\n throw new Error(\n 'No fetch implementation available. Pliuz requires Node ≥18 or a polyfill.',\n )\n }\n this.fetchImpl = fetchImpl\n }\n\n /**\n * Create (or idempotently replay) an approval request.\n *\n * With `idempotency_key`, the call retries on network failure without\n * risk of duplicates (backend dedupes within 24h).\n */\n async createApproval(input: CreateApprovalInput): Promise<CreateApprovalResponse> {\n const body = {\n tool_name: input.tool_name,\n tool_args: input.tool_args,\n context_messages: input.context_messages ?? null,\n originator: input.originator ?? { type: 'system' },\n session_id: input.session_id ?? null,\n client_metadata: input.client_metadata ?? null,\n idempotency_key: input.idempotency_key ?? null,\n }\n return request<CreateApprovalResponse>({\n method: 'POST',\n url: approvalUrl(this.baseUrl),\n apiKey: this.apiKey,\n body,\n timeoutMs: this.timeoutMs,\n maxRetries: this.maxRetries,\n retryOnPost: Boolean(input.idempotency_key),\n fetchImpl: this.fetchImpl,\n })\n }\n\n /**\n * Fetch the current state of an approval request.\n * Used by polling in `gated()` to detect status transitions.\n *\n * Pass `waitSeconds` (1..25) to long-poll: the server holds the request\n * open and returns the instant the approval stops being `pending`, or after\n * `waitSeconds` (still pending). Cuts polling volume and decision latency\n * ~12x vs fixed-interval polling. The per-request HTTP timeout is bumped to\n * cover the wait window.\n */\n async getApproval(approvalId: string, waitSeconds?: number): Promise<ApprovalRequest> {\n const wait =\n waitSeconds && waitSeconds > 0 ? Math.min(Math.floor(waitSeconds), MAX_WAIT_SECONDS) : 0\n const url = wait > 0\n ? `${approvalUrl(this.baseUrl, approvalId)}?wait=${wait}`\n : approvalUrl(this.baseUrl, approvalId)\n return request<ApprovalRequest>({\n method: 'GET',\n url,\n apiKey: this.apiKey,\n // Give the socket head-room over the server-side wait window.\n timeoutMs: wait > 0 ? Math.max(this.timeoutMs, wait * 1000 + 5000) : this.timeoutMs,\n maxRetries: this.maxRetries,\n fetchImpl: this.fetchImpl,\n })\n }\n\n /**\n * Close the audit loop by reporting the outcome of the gated action.\n *\n * Single-shot: a second call returns 409 (PliuzConflictError).\n * Only the originating agent can report — others get 403 (PliuzForbiddenError).\n */\n async reportExecution(\n approvalId: string,\n input: ExecutionInput,\n ): Promise<ExecutionResult> {\n const body = {\n status: input.status,\n error: input.error ?? null,\n latency_ms: input.latency_ms ?? null,\n target_response_excerpt: input.target_response_excerpt ?? null,\n }\n return request<ExecutionResult>({\n method: 'POST',\n url: approvalUrl(this.baseUrl, approvalId, 'execution'),\n apiKey: this.apiKey,\n body,\n timeoutMs: this.timeoutMs,\n maxRetries: this.maxRetries,\n retryOnPost: false,\n fetchImpl: this.fetchImpl,\n })\n }\n}\n","/**\n * Field-level redaction applied client-side BEFORE sending to Pliuz.\n *\n * Non-negotiable architectural decision: sensitive fields (PII, secrets, PHI)\n * must never leave the caller's process in plaintext. The SDK applies\n * redaction on the client side, transmits the redacted payload, and the\n * backend never sees the raw values.\n *\n * ## Path syntax\n *\n * \"customer.ssn\" → payload.customer.ssn\n * \"items[*].card_number\" → every item's card_number\n * \"headers.authorization\" → payload.headers.authorization\n *\n * Limitations (intentional — keep the surface tiny):\n * - No JSONPath wildcards beyond `[*]`\n * - No filter expressions\n * - Missing keys are silently ignored\n */\n\nimport { PliuzRedactionPathError } from './errors.js'\n\nexport const REDACTED_PLACEHOLDER = '<redacted>' as const\n\ntype PathSegment = { key: string; isArrayWildcard: boolean }\n\n/**\n * Returns a deep copy of `payload` with values at `paths` replaced by\n * `REDACTED_PLACEHOLDER`. Does not mutate the input.\n *\n * When `strict` is true, a syntactically valid path that resolves to no\n * existing field throws {@link PliuzRedactionPathError} instead of being a\n * silent no-op — turn it on to fail loud and avoid leaking a field you meant\n * to redact. Defaults to false (lenient: a typo'd path is ignored).\n *\n * @example\n * applyRedaction({ customer: { ssn: '123-45-6789' } }, ['customer.ssn'])\n * // → { customer: { ssn: '<redacted>' } }\n */\nexport function applyRedaction<T extends Record<string, unknown>>(\n payload: T,\n paths: readonly string[] | null | undefined,\n strict = false,\n): T {\n if (!paths || paths.length === 0) {\n return deepClone(payload)\n }\n const result = deepClone(payload)\n for (const path of paths) {\n const matched = redactPath(result as Record<string, unknown>, parsePath(path))\n if (strict && !matched) {\n throw new PliuzRedactionPathError(path)\n }\n }\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Internal\n// ---------------------------------------------------------------------------\n\nfunction parsePath(path: string): PathSegment[] {\n if (!path) {\n throw new Error('redaction path cannot be empty')\n }\n\n const segments: PathSegment[] = []\n for (const raw of path.split('.')) {\n if (raw.endsWith('[*]')) {\n const key = raw.slice(0, -3)\n if (!key) {\n throw new Error(`redaction path segment before [*] cannot be empty: ${path}`)\n }\n segments.push({ key, isArrayWildcard: true })\n } else if (raw.includes('[') || raw.includes(']')) {\n throw new Error(`unsupported redaction syntax in '${path}' — only [*] is allowed`)\n } else {\n if (!raw) {\n throw new Error(`redaction path has empty segment: ${path}`)\n }\n segments.push({ key: raw, isArrayWildcard: false })\n }\n }\n return segments\n}\n\n/**\n * Walk `segments` into `node`, mutating in place. Returns true if the path\n * matched the payload's shape and redacted at least one terminal field, false\n * if it was a no-op (missing key / shape mismatch) — the caller uses this to\n * fail loud under strict mode.\n */\nfunction redactPath(node: unknown, segments: PathSegment[]): boolean {\n if (segments.length === 0) return true\n if (!isPlainObject(node)) return false\n\n const [head, ...rest] = segments\n if (!head) return false\n const { key, isArrayWildcard } = head\n if (!(key in node)) return false\n\n if (isArrayWildcard) {\n const target = node[key]\n if (!Array.isArray(target)) return false\n if (rest.length === 0) {\n node[key] = target.map(() => REDACTED_PLACEHOLDER)\n return true\n }\n // Match only if EVERY item resolves the remaining path — a single item\n // missing the field is the leak strict mode must catch. Empty list = miss.\n let matched = target.length > 0\n for (const item of target) {\n if (!redactPath(item, rest)) matched = false\n }\n return matched\n } else {\n if (rest.length === 0) {\n node[key] = REDACTED_PLACEHOLDER\n return true\n }\n return redactPath(node[key], rest)\n }\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\nfunction deepClone<T>(v: T): T {\n // Prefer structuredClone when available (Node 17+). Falls back to JSON\n // for environments without it (e.g. some bundler test setups).\n if (typeof structuredClone === 'function') {\n return structuredClone(v)\n }\n return JSON.parse(JSON.stringify(v)) as T\n}\n","/**\n * The `gated()` wrapper — the headline API of the Pliuz TypeScript SDK.\n *\n * Wraps any function (sync or async) so every call is gated by a Pliuz\n * approval request. The wrapped function always returns `Promise<TResult>`\n * even if the original is synchronous — gating is inherently async because\n * it involves an HTTP call.\n *\n * @example\n * import { gated } from '@pliuz/sdk'\n *\n * const issueRefund = gated(\n * {\n * policy: 'refund',\n * redact: ['customer.ssn'],\n * toolArgs: (customerId: string, amountCents: number) => ({\n * customer_id: customerId,\n * amount_cents: amountCents,\n * }),\n * },\n * async (customerId, amountCents) => stripe.refund(customerId, amountCents),\n * )\n *\n * const result = await issueRefund('cus_123', 5000)\n */\n\nimport { createHash } from 'node:crypto'\n\nimport { PliuzClient } from './client.js'\nimport {\n PliuzApprovalExpiredError,\n PliuzApprovalTimeoutError,\n PliuzEditNotApplicableError,\n PliuzRejectedError,\n} from './errors.js'\nimport { applyRedaction, REDACTED_PLACEHOLDER } from './redaction.js'\nimport type {\n ApprovalRequest,\n ExecutionStatus,\n Originator,\n} from './types.js'\n\nexport const DEFAULT_GATED_TIMEOUT_MS = 300_000 // 5 min — matches Pliuz default SLA\nexport const DEFAULT_GATED_POLL_INTERVAL_MS = 2000\n\nexport interface GatedOptions<TArgs extends readonly unknown[]> {\n /** Policy slug to bind this gate to. Default: backend resolves by toolName. */\n policy?: string\n\n /** Redaction paths applied to tool_args BEFORE sending. */\n redact?: readonly string[]\n\n /**\n * When true, a `redact` path that matches no field throws\n * PliuzRedactionPathError instead of being a silent no-op — fail loud so a\n * typo'd path never leaks the field you meant to redact. Default: false.\n */\n redactStrict?: boolean\n\n /** Override the tool name. Default: `fn.name` (may be empty for anonymous). */\n toolName?: string\n\n /**\n * Map the wrapped function's args into a tool_args object.\n * Default: `(...args) => ({ args })` — wraps all positional args under\n * a single `args` key. Provide a custom mapper for cleaner audit trails.\n */\n toolArgs?: (...args: TArgs) => Record<string, unknown>\n\n /** Max ms to poll for the approval to resolve. Throws on timeout. */\n timeoutMs?: number\n\n /** Ms between GET /approvals/:id polls. */\n pollIntervalMs?: number\n\n /** Reuse an existing PliuzClient. Default: `new PliuzClient()`. */\n client?: PliuzClient\n\n /** Optional context for the human approver. */\n contextMessages?: readonly string[]\n\n /** Optional session id (groups related approvals in the UI). */\n sessionId?: string\n\n /** Optional originator (default: { type: 'system' }). */\n originator?: Originator\n\n /**\n * Map human-EDITED args (approval decided with action='edit') back onto\n * the wrapped function's argument tuple. Required to honor edits when a\n * custom `toolArgs` mapper is used (the SDK cannot invert an arbitrary\n * mapper). Without it, an edited approval throws\n * PliuzEditNotApplicableError instead of executing the original args.\n */\n applyFinalArgs?: (finalArgs: Record<string, unknown>, originalArgs: TArgs) => TArgs\n}\n\nconst TERMINAL_OK = new Set<string>(['approved'])\nconst TERMINAL_REJECT = new Set<string>(['rejected'])\nconst TERMINAL_EXPIRED = new Set<string>(['expired'])\n\n/**\n * Wrap a function so every call is gated by Pliuz.\n *\n * The returned function ALWAYS returns a Promise, even if the input is sync.\n * This is intentional — gating necessarily involves async HTTP calls.\n */\nexport function gated<TArgs extends readonly unknown[], TResult>(\n options: GatedOptions<TArgs>,\n fn: (...args: TArgs) => Promise<TResult> | TResult,\n): (...args: TArgs) => Promise<TResult> {\n const toolName = options.toolName ?? (fn.name || 'anonymous')\n const toolArgsMapper =\n options.toolArgs ??\n ((...args: TArgs): Record<string, unknown> => ({ args: args as unknown as unknown[] }))\n const timeoutMs = options.timeoutMs ?? DEFAULT_GATED_TIMEOUT_MS\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_GATED_POLL_INTERVAL_MS\n const redactPaths = options.redact\n\n return async (...args: TArgs): Promise<TResult> => {\n const activeClient = options.client ?? new PliuzClient()\n const rawArgs = toolArgsMapper(...args)\n const sendArgs = redactPaths && redactPaths.length > 0\n ? applyRedaction(rawArgs, redactPaths, options.redactStrict ?? false)\n : rawArgs\n // Key over PRE-redaction args: hashing the redacted payload collapses\n // calls that differ only in a redacted field (two transfers to different\n // IBANs) into one key — the second would replay the first's approval.\n // Only the truncated SHA-256 leaves the process, never the raw values.\n const idempotencyKey = idempotencyKeyFor(toolName, rawArgs, options.sessionId)\n const metadata: Record<string, unknown> = {}\n if (options.policy) metadata.policy = options.policy\n\n const response = await activeClient.createApproval({\n tool_name: toolName,\n tool_args: sendArgs,\n context_messages: options.contextMessages ?? null,\n originator: options.originator,\n session_id: options.sessionId ?? null,\n client_metadata: Object.keys(metadata).length > 0 ? metadata : null,\n idempotency_key: idempotencyKey,\n })\n\n const approvalId = response.id\n\n if (TERMINAL_REJECT.has(response.status)) {\n throw new PliuzRejectedError(approvalId, response.message ?? null)\n }\n if (TERMINAL_EXPIRED.has(response.status)) {\n throw new PliuzApprovalExpiredError(approvalId)\n }\n\n let approval: ApprovalRequest | null = null\n if (!TERMINAL_OK.has(response.status)) {\n // Long-poll: the server returns the instant the decision lands (or after\n // its wait window). We pass the lesser of the remaining budget and the\n // server cap, so latency is near-zero and we make ~1 request per ~25s\n // instead of one every pollIntervalMs.\n const deadline = Date.now() + timeoutMs\n while (true) {\n const remainingMs = deadline - Date.now()\n if (remainingMs <= 0) {\n throw new PliuzApprovalTimeoutError(approvalId, timeoutMs)\n }\n const waitSeconds = Math.max(1, Math.ceil(Math.min(remainingMs, pollIntervalMs * 1000) / 1000))\n const callStart = Date.now()\n approval = await activeClient.getApproval(approvalId, waitSeconds)\n if (terminalOrThrow(approval)) break\n // Safety floor: if the server ignored `wait` and returned instantly\n // while still pending, back off so we don't hot-spin.\n if (Date.now() - callStart < 250) await sleep(pollIntervalMs)\n }\n } else if (response.is_replay) {\n // Replayed already-approved request: a human may have EDITED the args\n // (final_args). Fresh auto-approvals can't carry edits — skip the fetch.\n approval = await activeClient.getApproval(approvalId)\n }\n\n // Honor human edits: execute final_args, NEVER the original args when\n // the approver changed them.\n let callArgs = args\n const finalArgs = approval?.final_args ?? null\n if (finalArgs) {\n callArgs = resolveEditedArgs(approvalId, rawArgs, finalArgs, args, options)\n }\n\n // Execute + report. The report is AWAITED: on serverless (Vercel/Lambda)\n // the runtime freezes once the handler resolves, so a fire-and-forget\n // report is routinely never sent — silently losing the audit loop.\n const started = Date.now()\n try {\n const result = await fn(...callArgs)\n const latencyMs = Date.now() - started\n await safeReport(activeClient, approvalId, 'success', null, latencyMs, result, redactPaths)\n return result\n } catch (e) {\n const latencyMs = Date.now() - started\n const errMsg = e instanceof Error ? e.message : String(e)\n await safeReport(activeClient, approvalId, 'error', errMsg.slice(0, 2000), latencyMs, null, redactPaths)\n throw e\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction idempotencyKeyFor(\n toolName: string,\n toolArgs: Record<string, unknown>,\n sessionId: string | undefined,\n): string {\n const payload = JSON.stringify(\n { tool: toolName, args: toolArgs, session: sessionId ?? null },\n Object.keys({ tool: 0, args: 0, session: 0 }).sort(),\n )\n // Canonicalize via sorted-key JSON stringify for deterministic hash\n const canonical = canonicalJSON({ tool: toolName, args: toolArgs, session: sessionId ?? null })\n void payload // silence unused\n return 'g_' + createHash('sha256').update(canonical).digest('hex').slice(0, 30)\n}\n\nfunction canonicalJSON(value: unknown): string {\n if (value === null || typeof value !== 'object') {\n return JSON.stringify(value)\n }\n if (Array.isArray(value)) {\n return '[' + value.map(canonicalJSON).join(',') + ']'\n }\n const obj = value as Record<string, unknown>\n const keys = Object.keys(obj).sort()\n return (\n '{' +\n keys.map((k) => JSON.stringify(k) + ':' + canonicalJSON(obj[k])).join(',') +\n '}'\n )\n}\n\n/**\n * Merge human-edited final_args over the original raw args. final_args is\n * authoritative (the edit modal pre-fills the FULL tool_args JSON), except\n * values left as the redaction placeholder — those are echoes of what we\n * sent; restore the original raw value rather than executing '<redacted>'.\n */\nfunction mergeFinalArgs(raw: unknown, final: unknown): unknown {\n if (isPlainRecord(raw) && isPlainRecord(final)) {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(final)) {\n out[k] = k in raw ? mergeFinalArgs(raw[k], v) : v\n }\n return out\n }\n if (final === REDACTED_PLACEHOLDER) return raw\n return final\n}\n\nfunction isPlainRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\n/**\n * Map human-edited args back onto the wrapped function's argument tuple.\n *\n * - custom `applyFinalArgs` mapper → caller decides.\n * - default toolArgs mapper ({ args: [...] }) → use the edited array.\n * - custom toolArgs mapper without applyFinalArgs → PliuzEditNotApplicableError:\n * executing the ORIGINAL args after a human approved something ELSE would\n * make the audit trail misrepresent what was approved vs executed.\n */\nfunction resolveEditedArgs<TArgs extends readonly unknown[]>(\n approvalId: string,\n rawArgs: Record<string, unknown>,\n finalArgs: Record<string, unknown>,\n originalArgs: TArgs,\n options: GatedOptions<TArgs>,\n): TArgs {\n const merged = mergeFinalArgs(rawArgs, finalArgs) as Record<string, unknown>\n if (options.applyFinalArgs) {\n return options.applyFinalArgs(merged, originalArgs)\n }\n if (options.toolArgs === undefined && Array.isArray(merged.args)) {\n return merged.args as unknown as TArgs\n }\n throw new PliuzEditNotApplicableError(approvalId, merged)\n}\n\nfunction terminalOrThrow(approval: ApprovalRequest): boolean {\n if (TERMINAL_OK.has(approval.status)) return true\n if (TERMINAL_REJECT.has(approval.status)) {\n throw new PliuzRejectedError(approval.id, approval.decision_reason)\n }\n if (TERMINAL_EXPIRED.has(approval.status)) {\n throw new PliuzApprovalExpiredError(approval.id)\n }\n return false\n}\n\nasync function safeReport(\n client: PliuzClient,\n approvalId: string,\n status: ExecutionStatus,\n errorMessage: string | null,\n latencyMs: number,\n result: unknown,\n redactPaths: readonly string[] | undefined,\n): Promise<void> {\n let excerpt: string | null = null\n if (result != null) {\n // The caller's redact paths apply to the RESULT too: a tool that\n // receives a redacted SSN often returns it. Without this the excerpt\n // re-leaked exactly the fields marked as never-leave-process.\n const toDump = redactPaths && redactPaths.length > 0 && isPlainRecord(result)\n ? applyRedaction(result, redactPaths)\n : result\n try {\n excerpt = JSON.stringify(toDump).slice(0, 2000)\n } catch {\n excerpt = String(toDump).slice(0, 2000)\n }\n }\n try {\n await client.reportExecution(approvalId, {\n status,\n error: errorMessage,\n latency_ms: latencyMs,\n target_response_excerpt: excerpt,\n })\n } catch {\n // Intentionally swallow — if reporting fails the audit log surfaces\n // 'execution unreported' but we don't want to crash the caller's flow.\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","/**\n * Vercel AI SDK adapter for Pliuz.\n *\n * Wraps any Vercel AI SDK `Tool` so its `execute` is gated by a Pliuz\n * approval request. The wrapped tool preserves `description` and\n * `parameters` so the LLM sees the tool identically — only the\n * execution path is gated.\n *\n * Install requires `ai >= 4.0` as a peer dependency.\n *\n * @example\n * import { tool } from 'ai'\n * import { z } from 'zod'\n * import { gatedTool } from '@pliuz/sdk/adapters/ai'\n *\n * const issueRefund = gatedTool(\n * { toolName: 'issue_refund', policy: 'refund', redact: ['customer.ssn'] },\n * tool({\n * description: 'Issue a refund to a customer',\n * parameters: z.object({\n * customer_id: z.string(),\n * amount_cents: z.number().int().positive(),\n * }),\n * execute: async ({ customer_id, amount_cents }) => {\n * return stripe.refund(customer_id, amount_cents)\n * },\n * }),\n * )\n */\n\nimport { gated } from '../gated.js'\nimport type { PliuzClient } from '../client.js'\nimport type { Originator } from '../types.js'\n\n/**\n * Minimal structural type that matches Vercel AI SDK's `Tool<TParams, TResult>`\n * without importing `ai` (it's a peer dep — adapter must work even if absent\n * from a consumer's tsconfig). The shape mirrors the v4 contract.\n */\nexport interface AITool<TInput, TResult> {\n description?: string\n parameters: unknown\n execute?: (input: TInput, options: unknown) => Promise<TResult> | TResult\n [key: string]: unknown\n}\n\n/**\n * Options for `gatedTool`. Mirrors the relevant fields of GatedOptions\n * without the `toolArgs` / `toolName` generic-parametric pieces (the\n * adapter sets toolArgs internally to surface the Vercel-AI input dict\n * directly as the Pliuz tool_args).\n */\nexport interface GatedToolOptions {\n policy?: string\n redact?: readonly string[]\n /**\n * Tool name reported to Pliuz — drives policy matching, so it MUST be explicit\n * and stable. Required: the old behavior derived it from the prose\n * `description`, so a copy edit silently re-routed approvals. The Vercel AI SDK\n * gives a tool no intrinsic name (it lives in the `tools` map key), so the\n * adapter cannot infer it safely — you pass it.\n */\n toolName: string\n timeoutMs?: number\n pollIntervalMs?: number\n client?: PliuzClient\n contextMessages?: readonly string[]\n sessionId?: string\n originator?: Originator\n}\n\nexport const ADAPTER_NAME = 'vercel-ai' as const\n\n/**\n * Wrap a Vercel AI SDK tool so its `execute` is gated by Pliuz.\n *\n * If the tool has no `execute` (e.g. client-side tools), this is a\n * no-op — gating only makes sense on the server side.\n */\nexport function gatedTool<TInput, TResult>(\n options: GatedToolOptions,\n tool: AITool<TInput, TResult>,\n): AITool<TInput, TResult> {\n if (typeof tool.execute !== 'function') {\n // Client-side tool — nothing to gate.\n return tool\n }\n\n const toolName = options.toolName\n if (typeof toolName !== 'string' || toolName.trim() === '') {\n throw new Error(\n 'gatedTool: `toolName` is required and must be a non-empty string. It drives ' +\n 'Pliuz policy matching, so it must be explicit and stable — never derived ' +\n 'from the tool description (a copy edit would silently re-route approvals).',\n )\n }\n\n const originalExecute = tool.execute\n\n const wrappedExecute: AITool<TInput, TResult>['execute'] = async (input, opts) => {\n // Build the gated wrapper PER CALL so the Vercel AI `options` (`opts`) is\n // captured in THIS closure. A shared mutable holder cross-talked between\n // concurrent invocations: a second call overwrote the first call's options\n // before its execute ran.\n const gatedExecute1Arg = gated(\n {\n policy: options.policy,\n redact: options.redact,\n timeoutMs: options.timeoutMs,\n pollIntervalMs: options.pollIntervalMs,\n client: options.client,\n contextMessages: options.contextMessages,\n sessionId: options.sessionId,\n originator: options.originator,\n toolName,\n // Surface the Vercel-AI input dict directly as Pliuz tool_args\n // instead of wrapping in `{ args: [input] }` for cleaner audit logs.\n toolArgs: (inp: TInput) =>\n isPlainObject(inp) ? inp : ({ input: inp } as Record<string, unknown>),\n },\n async (inp: TInput) => originalExecute(inp, opts),\n )\n return gatedExecute1Arg(input)\n }\n\n return {\n ...tool,\n execute: wrappedExecute,\n }\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { P as PliuzClient, O as Originator } from '../client-4jk23X41.cjs';
1
+ import { P as PliuzClient, O as Originator } from '../client-K9c9HsAc.cjs';
2
2
 
3
3
  /**
4
4
  * Vercel AI SDK adapter for Pliuz.
@@ -16,7 +16,7 @@ import { P as PliuzClient, O as Originator } from '../client-4jk23X41.cjs';
16
16
  * import { gatedTool } from '@pliuz/sdk/adapters/ai'
17
17
  *
18
18
  * const issueRefund = gatedTool(
19
- * { policy: 'refund', redact: ['customer.ssn'] },
19
+ * { toolName: 'issue_refund', policy: 'refund', redact: ['customer.ssn'] },
20
20
  * tool({
21
21
  * description: 'Issue a refund to a customer',
22
22
  * parameters: z.object({
@@ -51,10 +51,13 @@ interface GatedToolOptions {
51
51
  policy?: string;
52
52
  redact?: readonly string[];
53
53
  /**
54
- * Override the tool name reported to Pliuz. Defaults to the tool's
55
- * `description` (first 64 chars) or `'ai_tool'` if neither is set.
54
+ * Tool name reported to Pliuz drives policy matching, so it MUST be explicit
55
+ * and stable. Required: the old behavior derived it from the prose
56
+ * `description`, so a copy edit silently re-routed approvals. The Vercel AI SDK
57
+ * gives a tool no intrinsic name (it lives in the `tools` map key), so the
58
+ * adapter cannot infer it safely — you pass it.
56
59
  */
57
- toolName?: string;
60
+ toolName: string;
58
61
  timeoutMs?: number;
59
62
  pollIntervalMs?: number;
60
63
  client?: PliuzClient;
@@ -1,4 +1,4 @@
1
- import { P as PliuzClient, O as Originator } from '../client-4jk23X41.js';
1
+ import { P as PliuzClient, O as Originator } from '../client-K9c9HsAc.js';
2
2
 
3
3
  /**
4
4
  * Vercel AI SDK adapter for Pliuz.
@@ -16,7 +16,7 @@ import { P as PliuzClient, O as Originator } from '../client-4jk23X41.js';
16
16
  * import { gatedTool } from '@pliuz/sdk/adapters/ai'
17
17
  *
18
18
  * const issueRefund = gatedTool(
19
- * { policy: 'refund', redact: ['customer.ssn'] },
19
+ * { toolName: 'issue_refund', policy: 'refund', redact: ['customer.ssn'] },
20
20
  * tool({
21
21
  * description: 'Issue a refund to a customer',
22
22
  * parameters: z.object({
@@ -51,10 +51,13 @@ interface GatedToolOptions {
51
51
  policy?: string;
52
52
  redact?: readonly string[];
53
53
  /**
54
- * Override the tool name reported to Pliuz. Defaults to the tool's
55
- * `description` (first 64 chars) or `'ai_tool'` if neither is set.
54
+ * Tool name reported to Pliuz drives policy matching, so it MUST be explicit
55
+ * and stable. Required: the old behavior derived it from the prose
56
+ * `description`, so a copy edit silently re-routed approvals. The Vercel AI SDK
57
+ * gives a tool no intrinsic name (it lives in the `tools` map key), so the
58
+ * adapter cannot infer it safely — you pass it.
56
59
  */
57
- toolName?: string;
60
+ toolName: string;
58
61
  timeoutMs?: number;
59
62
  pollIntervalMs?: number;
60
63
  client?: PliuzClient;