@pliuz/sdk 0.1.0 → 0.2.1
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 +51 -0
- package/README.md +38 -21
- package/dist/adapters/ai.cjs +56 -10
- package/dist/adapters/ai.cjs.map +1 -1
- package/dist/adapters/ai.d.cts +1 -1
- package/dist/adapters/ai.d.ts +1 -1
- package/dist/adapters/ai.js +56 -10
- package/dist/adapters/ai.js.map +1 -1
- package/dist/{client-BABvN_88.d.cts → client-4jk23X41.d.cts} +2 -2
- package/dist/{client-BABvN_88.d.ts → client-4jk23X41.d.ts} +2 -2
- package/dist/index.cjs +57 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -4
- package/dist/index.d.ts +25 -4
- package/dist/index.js +57 -11
- package/dist/index.js.map +1 -1
- package/package.json +4 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,57 @@ 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.1] — 2026-06-12
|
|
9
|
+
|
|
10
|
+
Identical in content to 0.2.0 (below), which never reached npm — its release
|
|
11
|
+
CI run failed on a monorepo PostCSS config leak into the SDK's vitest, fixed
|
|
12
|
+
here. First published version of the 0.2 line.
|
|
13
|
+
|
|
14
|
+
## [0.2.0] — 2026-06-12 (not published to npm)
|
|
15
|
+
|
|
16
|
+
Correctness release from an internal security/architecture review. Three of
|
|
17
|
+
these are behavior changes you should read before upgrading.
|
|
18
|
+
|
|
19
|
+
### Fixed (behavior changes)
|
|
20
|
+
|
|
21
|
+
- **Human edits are now executed.** When an approver decides with
|
|
22
|
+
*Edit & Approve*, the wrapper now runs the edited `final_args` — previously
|
|
23
|
+
it silently ran the ORIGINAL args the agent sent. With the default
|
|
24
|
+
`toolArgs` mapper this is automatic; custom mappers need the new
|
|
25
|
+
`applyFinalArgs` option or the call throws the new
|
|
26
|
+
`PliuzEditNotApplicableError` (the SDK refuses to execute args a human did
|
|
27
|
+
not approve). Redaction placeholders echoed back by the approver are
|
|
28
|
+
restored to the original values.
|
|
29
|
+
- **Idempotency keys are now hashed over PRE-redaction args.** Previously two
|
|
30
|
+
calls differing only in a redacted field (e.g. two transfers to different
|
|
31
|
+
IBANs) produced the SAME key, so the second silently replayed the first's
|
|
32
|
+
approval. Keys change across this upgrade: in-flight dedupe windows reset
|
|
33
|
+
(worst case: one extra approval request, never a skipped approval).
|
|
34
|
+
- **Execution reports are awaited** before the wrapped call returns.
|
|
35
|
+
Previously they were fire-and-forget, which on serverless (Vercel/Lambda)
|
|
36
|
+
routinely froze before the report was sent — silently losing the audit
|
|
37
|
+
loop's execution record.
|
|
38
|
+
- **The execution excerpt is redacted** with the same `redact` paths as
|
|
39
|
+
`tool_args`. Previously a tool that returned the sensitive field it
|
|
40
|
+
received re-leaked it through `target_response_excerpt`.
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- Default `baseUrl` is now `https://pliuz.com` (was a dev deployment URL).
|
|
45
|
+
- README idempotency section rewritten to match real backend semantics
|
|
46
|
+
(24h dedupe window, per-agent, payload-conflict → 409) and to recommend a
|
|
47
|
+
per-run `sessionId` for legitimately repeating calls.
|
|
48
|
+
- README no longer claims AbortSignal cancellation or Vercel Edge support
|
|
49
|
+
(neither shipped yet — both on the roadmap).
|
|
50
|
+
- Contract tests now FAIL (instead of silently skipping) when the OpenAPI
|
|
51
|
+
spec is missing, and resolve a vendored `api-spec/openapi.yaml` in the
|
|
52
|
+
public mirror.
|
|
53
|
+
|
|
54
|
+
### Added
|
|
55
|
+
|
|
56
|
+
- `applyFinalArgs?: (finalArgs, originalArgs) => TArgs` in `GatedOptions`.
|
|
57
|
+
- `PliuzEditNotApplicableError` (exported).
|
|
58
|
+
|
|
8
59
|
## [0.1.0] — 2026-05-21
|
|
9
60
|
|
|
10
61
|
### Added
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@pliuz/sdk)
|
|
4
4
|
[](https://www.npmjs.com/package/@pliuz/sdk)
|
|
5
|
-
[](https://github.com/
|
|
5
|
+
[](https://github.com/pliuz/pliuz-ts/blob/main/sdk-typescript/LICENSE)
|
|
6
6
|
|
|
7
7
|
> **Human-in-the-loop approval gates for AI agents.** Wrap any function in `gated()` to pause execution, route the call to a human approver via Pliuz, then resume — or abort — based on the decision. Every call is audited.
|
|
8
8
|
|
|
@@ -44,7 +44,7 @@ Requires Node ≥ 18.17 (uses native `fetch` + `AbortController`).
|
|
|
44
44
|
|
|
45
45
|
### 1. Get an API key
|
|
46
46
|
|
|
47
|
-
Sign up at [pliuz.
|
|
47
|
+
Sign up at [pliuz.com](https://pliuz.com/signup), create an agent in the dashboard, copy the key.
|
|
48
48
|
|
|
49
49
|
### 2. Set the env var
|
|
50
50
|
|
|
@@ -99,9 +99,10 @@ yourFn(...args) yourFn(...args)
|
|
|
99
99
|
- **Dual ESM/CJS** — works in any modern Node project
|
|
100
100
|
- **First-class TypeScript** — fully typed, including narrow error subclasses
|
|
101
101
|
- **Idempotency** via deterministic key hashing — safe to retry from anywhere
|
|
102
|
-
- **Client-side redaction** — sensitive fields never leave your process plaintext
|
|
103
|
-
- **
|
|
104
|
-
- **
|
|
102
|
+
- **Client-side redaction** — sensitive fields never leave your process plaintext (applied to tool args AND the execution excerpt)
|
|
103
|
+
- **Bounded waiting** via `timeoutMs` (first-class `AbortSignal` cancellation is on the roadmap — not shipped yet)
|
|
104
|
+
- **Human edits honored** — if an approver edits the args, the edited args execute (or a typed error is thrown), never the original ones
|
|
105
|
+
- **Single-shot execution reporting** — awaited before your call returns, closing the audit loop reliably on serverless
|
|
105
106
|
- **Typed errors** — `PliuzRejectedError`, `PliuzApprovalExpiredError`, `PliuzPolicyError`, etc.
|
|
106
107
|
- **Vercel AI SDK adapter** — `gatedTool()` wraps `tool({...})` from `ai` so existing AI SDK agents gate transparently
|
|
107
108
|
|
|
@@ -249,7 +250,7 @@ The wrapped tool preserves `description` and `parameters` — the LLM sees it id
|
|
|
249
250
|
| Env var | Default | Purpose |
|
|
250
251
|
|---|---|---|
|
|
251
252
|
| `PLIUZ_API_KEY` | _(required)_ | Per-agent API key. `pli_live_...` format. |
|
|
252
|
-
| `PLIUZ_BASE_URL` | `https://pliuz
|
|
253
|
+
| `PLIUZ_BASE_URL` | `https://pliuz.com` | Override for self-hosted or staging. |
|
|
253
254
|
|
|
254
255
|
All env vars can be passed as `PliuzClient` constructor options:
|
|
255
256
|
|
|
@@ -261,24 +262,40 @@ new PliuzClient({ apiKey: 'pli_live_...', baseUrl: 'https://pliuz.mycompany.com'
|
|
|
261
262
|
|
|
262
263
|
## Production tips
|
|
263
264
|
|
|
264
|
-
### Idempotency
|
|
265
|
+
### Idempotency — read this before relying on it
|
|
265
266
|
|
|
266
|
-
`gated()` automatically generates a deterministic `idempotency_key` per call
|
|
267
|
+
`gated()` automatically generates a deterministic `idempotency_key` per call from `(tool_name, args, sessionId)`. The key is hashed over the **pre-redaction** args (only the truncated SHA-256 leaves your process), so two calls that differ only in a redacted field get **different** keys — each needs its own approval.
|
|
267
268
|
|
|
268
|
-
|
|
269
|
-
const refund = gated({ policy: 'refund' }, async (id: string, cents: number) => {
|
|
270
|
-
// ...
|
|
271
|
-
})
|
|
269
|
+
**Important:** the backend currently dedupes on this key with **no time window** — a `(tool_name, args, sessionId)` combination that was approved once is replayed as approved on every identical future call (and a rejected one stays rejected). The dedupe exists for HTTP-retry safety, but with the default `sessionId: undefined` it also applies across runs and days. **If your agent legitimately repeats identical calls (crons, recurring jobs), set a per-run `sessionId`** so each run gets its own approval:
|
|
272
270
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
271
|
+
```typescript
|
|
272
|
+
const refund = gated(
|
|
273
|
+
{ policy: 'refund', sessionId: runId }, // scope approvals to this run
|
|
274
|
+
async (id: string, cents: number) => { /* ... */ },
|
|
275
|
+
)
|
|
277
276
|
```
|
|
278
277
|
|
|
278
|
+
Within one run, retries are then safe: same args → one approval request, one human decision.
|
|
279
|
+
|
|
280
|
+
> A bounded server-side dedupe window is planned; until then treat the replay semantics above as the contract.
|
|
281
|
+
|
|
279
282
|
### Cross-language idempotency
|
|
280
283
|
|
|
281
|
-
The
|
|
284
|
+
The hash algorithm matches the [Python SDK](https://pypi.org/project/pliuz/) for ASCII string/integer payloads. Known divergence: non-ASCII strings and float-typed numbers serialize differently between `JSON.stringify` and Python's `json.dumps`, producing different keys — don't rely on cross-language dedupe for those payloads yet.
|
|
285
|
+
|
|
286
|
+
### When the approver edits the args
|
|
287
|
+
|
|
288
|
+
If a human decides with **Edit & Approve**, `gated()` executes the **edited** `final_args`, never the original call. With the default `toolArgs` mapper this is automatic. With a custom `toolArgs` mapper, provide `applyFinalArgs` to map the edited object back onto your function's arguments — otherwise the SDK throws `PliuzEditNotApplicableError` (it refuses to run args the human did not approve):
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
const refund = gated(
|
|
292
|
+
{
|
|
293
|
+
toolArgs: (id: string, cents: number) => ({ customer_id: id, amount_cents: cents }),
|
|
294
|
+
applyFinalArgs: (fa, [id]) => [id, fa.amount_cents as number] as const,
|
|
295
|
+
},
|
|
296
|
+
async (id: string, cents: number) => { /* ... */ },
|
|
297
|
+
)
|
|
298
|
+
```
|
|
282
299
|
|
|
283
300
|
### Custom timeouts per call
|
|
284
301
|
|
|
@@ -292,7 +309,7 @@ If polling exceeds `timeoutMs`, you get `PliuzApprovalTimeoutError`. **Your wrap
|
|
|
292
309
|
|
|
293
310
|
### Edge / Bun / Deno
|
|
294
311
|
|
|
295
|
-
The
|
|
312
|
+
The HTTP layer uses native `fetch` + `AbortController`, but `gated()` imports `node:crypto` at module load — so today the SDK requires a Node-compatible runtime: **Node ≥ 18.17, Bun, Deno (via `npm:`), and Cloudflare Workers with `nodejs_compat`**. **Vercel Edge runtime is NOT supported yet** (no `node:crypto` there); use the Node.js runtime for routes that import this SDK. A Web-Crypto build is on the roadmap.
|
|
296
313
|
|
|
297
314
|
---
|
|
298
315
|
|
|
@@ -320,9 +337,9 @@ See [`examples/`](./examples) for runnable scripts:
|
|
|
320
337
|
|
|
321
338
|
## Links
|
|
322
339
|
|
|
323
|
-
- **Docs**: https://pliuz.
|
|
324
|
-
- **GitHub**: https://github.com/
|
|
325
|
-
- **Issues**: https://github.com/
|
|
340
|
+
- **Docs**: https://pliuz.com/docs
|
|
341
|
+
- **GitHub**: https://github.com/pliuz/pliuz-ts
|
|
342
|
+
- **Issues**: https://github.com/pliuz/pliuz-ts/issues
|
|
326
343
|
- **Python SDK**: [`pliuz`](https://pypi.org/project/pliuz/)
|
|
327
344
|
|
|
328
345
|
---
|
package/dist/adapters/ai.cjs
CHANGED
|
@@ -5,7 +5,7 @@ var crypto = require('crypto');
|
|
|
5
5
|
// src/gated.ts
|
|
6
6
|
|
|
7
7
|
// src/version.ts
|
|
8
|
-
var VERSION = "0.1
|
|
8
|
+
var VERSION = "0.2.1";
|
|
9
9
|
|
|
10
10
|
// src/errors.ts
|
|
11
11
|
var PliuzError = class extends Error {
|
|
@@ -134,6 +134,19 @@ var PliuzApprovalTimeoutError = class extends PliuzError {
|
|
|
134
134
|
approvalId;
|
|
135
135
|
timeoutMs;
|
|
136
136
|
};
|
|
137
|
+
var PliuzEditNotApplicableError = class extends PliuzError {
|
|
138
|
+
constructor(approvalId, finalArgs) {
|
|
139
|
+
super(
|
|
140
|
+
`approval ${approvalId} was approved with edited args, but they cannot be mapped back to the wrapped function (custom toolArgs mapper without applyFinalArgs, or incompatible shape) \u2014 refusing to execute the original (unapproved) args. Apply e.finalArgs manually.`
|
|
141
|
+
);
|
|
142
|
+
this.approvalId = approvalId;
|
|
143
|
+
this.finalArgs = finalArgs;
|
|
144
|
+
this.name = "PliuzEditNotApplicableError";
|
|
145
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
146
|
+
}
|
|
147
|
+
approvalId;
|
|
148
|
+
finalArgs;
|
|
149
|
+
};
|
|
137
150
|
var STATUS_TO_ERROR = {
|
|
138
151
|
400: PliuzValidationError,
|
|
139
152
|
401: PliuzAuthError,
|
|
@@ -240,7 +253,7 @@ async function request(opts) {
|
|
|
240
253
|
}
|
|
241
254
|
|
|
242
255
|
// src/client.ts
|
|
243
|
-
var DEFAULT_BASE_URL = "https://pliuz
|
|
256
|
+
var DEFAULT_BASE_URL = "https://pliuz.com";
|
|
244
257
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
245
258
|
var DEFAULT_MAX_RETRIES = 3;
|
|
246
259
|
var ENV_API_KEY = "PLIUZ_API_KEY";
|
|
@@ -437,7 +450,7 @@ function gated(options, fn) {
|
|
|
437
450
|
const activeClient = options.client ?? new PliuzClient();
|
|
438
451
|
const rawArgs = toolArgsMapper(...args);
|
|
439
452
|
const sendArgs = redactPaths && redactPaths.length > 0 ? applyRedaction(rawArgs, redactPaths) : rawArgs;
|
|
440
|
-
const idempotencyKey = idempotencyKeyFor(toolName,
|
|
453
|
+
const idempotencyKey = idempotencyKeyFor(toolName, rawArgs, options.sessionId);
|
|
441
454
|
const metadata = {};
|
|
442
455
|
if (options.policy) metadata.policy = options.policy;
|
|
443
456
|
const response = await activeClient.createApproval({
|
|
@@ -456,6 +469,7 @@ function gated(options, fn) {
|
|
|
456
469
|
if (TERMINAL_EXPIRED.has(response.status)) {
|
|
457
470
|
throw new PliuzApprovalExpiredError(approvalId);
|
|
458
471
|
}
|
|
472
|
+
let approval = null;
|
|
459
473
|
if (!TERMINAL_OK.has(response.status)) {
|
|
460
474
|
const deadline = Date.now() + timeoutMs;
|
|
461
475
|
while (true) {
|
|
@@ -463,20 +477,27 @@ function gated(options, fn) {
|
|
|
463
477
|
throw new PliuzApprovalTimeoutError(approvalId, timeoutMs);
|
|
464
478
|
}
|
|
465
479
|
await sleep2(pollIntervalMs);
|
|
466
|
-
|
|
480
|
+
approval = await activeClient.getApproval(approvalId);
|
|
467
481
|
if (terminalOrThrow(approval)) break;
|
|
468
482
|
}
|
|
483
|
+
} else if (response.is_replay) {
|
|
484
|
+
approval = await activeClient.getApproval(approvalId);
|
|
485
|
+
}
|
|
486
|
+
let callArgs = args;
|
|
487
|
+
const finalArgs = approval?.final_args ?? null;
|
|
488
|
+
if (finalArgs) {
|
|
489
|
+
callArgs = resolveEditedArgs(approvalId, rawArgs, finalArgs, args, options);
|
|
469
490
|
}
|
|
470
491
|
const started = Date.now();
|
|
471
492
|
try {
|
|
472
|
-
const result = await fn(...
|
|
493
|
+
const result = await fn(...callArgs);
|
|
473
494
|
const latencyMs = Date.now() - started;
|
|
474
|
-
|
|
495
|
+
await safeReport(activeClient, approvalId, "success", null, latencyMs, result, redactPaths);
|
|
475
496
|
return result;
|
|
476
497
|
} catch (e) {
|
|
477
498
|
const latencyMs = Date.now() - started;
|
|
478
499
|
const errMsg = e instanceof Error ? e.message : String(e);
|
|
479
|
-
|
|
500
|
+
await safeReport(activeClient, approvalId, "error", errMsg.slice(0, 2e3), latencyMs, null, redactPaths);
|
|
480
501
|
throw e;
|
|
481
502
|
}
|
|
482
503
|
};
|
|
@@ -500,6 +521,30 @@ function canonicalJSON(value) {
|
|
|
500
521
|
const keys = Object.keys(obj).sort();
|
|
501
522
|
return "{" + keys.map((k) => JSON.stringify(k) + ":" + canonicalJSON(obj[k])).join(",") + "}";
|
|
502
523
|
}
|
|
524
|
+
function mergeFinalArgs(raw, final) {
|
|
525
|
+
if (isPlainRecord(raw) && isPlainRecord(final)) {
|
|
526
|
+
const out = {};
|
|
527
|
+
for (const [k, v] of Object.entries(final)) {
|
|
528
|
+
out[k] = k in raw ? mergeFinalArgs(raw[k], v) : v;
|
|
529
|
+
}
|
|
530
|
+
return out;
|
|
531
|
+
}
|
|
532
|
+
if (final === REDACTED_PLACEHOLDER) return raw;
|
|
533
|
+
return final;
|
|
534
|
+
}
|
|
535
|
+
function isPlainRecord(v) {
|
|
536
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
537
|
+
}
|
|
538
|
+
function resolveEditedArgs(approvalId, rawArgs, finalArgs, originalArgs, options) {
|
|
539
|
+
const merged = mergeFinalArgs(rawArgs, finalArgs);
|
|
540
|
+
if (options.applyFinalArgs) {
|
|
541
|
+
return options.applyFinalArgs(merged, originalArgs);
|
|
542
|
+
}
|
|
543
|
+
if (options.toolArgs === void 0 && Array.isArray(merged.args)) {
|
|
544
|
+
return merged.args;
|
|
545
|
+
}
|
|
546
|
+
throw new PliuzEditNotApplicableError(approvalId, merged);
|
|
547
|
+
}
|
|
503
548
|
function terminalOrThrow(approval) {
|
|
504
549
|
if (TERMINAL_OK.has(approval.status)) return true;
|
|
505
550
|
if (TERMINAL_REJECT.has(approval.status)) {
|
|
@@ -510,13 +555,14 @@ function terminalOrThrow(approval) {
|
|
|
510
555
|
}
|
|
511
556
|
return false;
|
|
512
557
|
}
|
|
513
|
-
async function safeReport(client, approvalId, status, errorMessage, latencyMs, result) {
|
|
558
|
+
async function safeReport(client, approvalId, status, errorMessage, latencyMs, result, redactPaths) {
|
|
514
559
|
let excerpt = null;
|
|
515
560
|
if (result != null) {
|
|
561
|
+
const toDump = redactPaths && redactPaths.length > 0 && isPlainRecord(result) ? applyRedaction(result, redactPaths) : result;
|
|
516
562
|
try {
|
|
517
|
-
excerpt = JSON.stringify(
|
|
563
|
+
excerpt = JSON.stringify(toDump).slice(0, 2e3);
|
|
518
564
|
} catch {
|
|
519
|
-
excerpt = String(
|
|
565
|
+
excerpt = String(toDump).slice(0, 2e3);
|
|
520
566
|
}
|
|
521
567
|
}
|
|
522
568
|
try {
|
package/dist/adapters/ai.cjs.map
CHANGED
|
@@ -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":"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","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.1.0' 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\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-dev.vercel.app'\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-dev.vercel.app`.\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 PliuzRejectedError,\n} from './errors.js'\nimport { applyRedaction } 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\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 const idempotencyKey = idempotencyKeyFor(toolName, sendArgs, 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 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 const approval = await activeClient.getApproval(approvalId)\n if (terminalOrThrow(approval)) break\n }\n }\n\n // Execute + report\n const started = Date.now()\n try {\n const result = await fn(...args)\n const latencyMs = Date.now() - started\n void safeReport(activeClient, approvalId, 'success', null, latencyMs, result)\n return result\n } catch (e) {\n const latencyMs = Date.now() - started\n const errMsg = e instanceof Error ? e.message : String(e)\n void safeReport(activeClient, approvalId, 'error', errMsg.slice(0, 2000), latencyMs, null)\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\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): Promise<void> {\n let excerpt: string | null = null\n if (result != null) {\n try {\n excerpt = JSON.stringify(result).slice(0, 2000)\n } catch {\n excerpt = String(result).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;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"]}
|
package/dist/adapters/ai.d.cts
CHANGED
package/dist/adapters/ai.d.ts
CHANGED