@decidio/sdk 0.6.4 → 0.8.0
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 +167 -0
- package/README.md +104 -24
- package/dist/adapters/_gate.d.ts +47 -2
- package/dist/adapters/_gate.js +49 -3
- package/dist/adapters/langgraph.d.ts +5 -11
- package/dist/adapters/langgraph.js +57 -6
- package/dist/adapters/openai.d.ts +40 -10
- package/dist/adapters/openai.js +19 -11
- package/dist/adapters/temporal.d.ts +21 -2
- package/dist/adapters/temporal.js +18 -5
- package/dist/cli.d.ts +59 -0
- package/dist/cli.js +2095 -194
- package/dist/demo-gate.js +6 -4
- package/dist/index.d.ts +36 -4
- package/dist/index.js +50 -5
- package/dist/inngest.d.ts +5 -2
- package/dist/inngest.js +23 -15
- package/dist/resume.d.ts +108 -5
- package/dist/resume.js +215 -109
- package/dist/signing.d.ts +40 -0
- package/dist/signing.js +43 -1
- package/openapi.yaml +65 -6
- package/package.json +2 -2
package/openapi.yaml
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
openapi: 3.1.0
|
|
6
6
|
info:
|
|
7
7
|
title: Decidio Agent Gate
|
|
8
|
-
version: 0.
|
|
8
|
+
version: 0.8.0 # tracks the SDK release - checked by packages/conformance/manifests.mjs
|
|
9
9
|
description: >
|
|
10
10
|
Authorize an AI-agent action (proceed | route | block), confirm the captured outcome, and
|
|
11
11
|
receive the signed resume webhook when a routed action is decided. Every outcome seals a
|
|
@@ -65,7 +65,28 @@ components:
|
|
|
65
65
|
resumeUrl:
|
|
66
66
|
type: string
|
|
67
67
|
format: uri
|
|
68
|
-
description: where Decidio POSTs the signed
|
|
68
|
+
description: where Decidio POSTs the signed wake-up when a routed decision resolves
|
|
69
|
+
requestCommitment:
|
|
70
|
+
type: string
|
|
71
|
+
pattern: "^[0-9a-f]{64}$"
|
|
72
|
+
description: >
|
|
73
|
+
REQUEST BINDING (SDK 0.7.0). An OPAQUE commitment to the exact request the agent will run:
|
|
74
|
+
lowercase-hex HMAC-SHA256 under a key only the agent holds (its Ed25519 signing key, else its
|
|
75
|
+
API token) over the canonical request. Stored with the decision and returned by
|
|
76
|
+
GET /agent/status; the SDK recomputes it over the request it is about to run and refuses a
|
|
77
|
+
mismatch. Carries no authority - the verdict is computed exactly as without it. Anything that
|
|
78
|
+
is not 64 lowercase hex is a 400.
|
|
79
|
+
idempotencyKey:
|
|
80
|
+
type: string
|
|
81
|
+
pattern: "^[A-Za-z0-9._:-]{16,128}$"
|
|
82
|
+
description: >
|
|
83
|
+
SDK 0.7.0. The same key from the same requester returns the SAME decision (idempotentReplay:
|
|
84
|
+
true) instead of a new one - an engine that re-runs its authorizing code on resume (LangGraph)
|
|
85
|
+
must not mint a phantom second decision. Accepted ONLY beside a requestCommitment (a key alone is
|
|
86
|
+
400). Stored only as a requester-scoped HMAC. A replay must be the same request twice over - the
|
|
87
|
+
same requestCommitment AND the same requester, action, amount and scope (the server binds that
|
|
88
|
+
tuple itself) - otherwise 409 IDEMPOTENCY_CONFLICT; an earlier decision is never handed back for a
|
|
89
|
+
changed request.
|
|
69
90
|
AuthorizeResponse:
|
|
70
91
|
type: object
|
|
71
92
|
required: [decision, decisionId, receiptId]
|
|
@@ -79,6 +100,17 @@ components:
|
|
|
79
100
|
decisionId: { type: string }
|
|
80
101
|
receiptId: { type: string }
|
|
81
102
|
reason: { type: string }
|
|
103
|
+
requestCommitment:
|
|
104
|
+
type: [string, "null"]
|
|
105
|
+
description: the commitment stored with the decision (SDK 0.7.0), null when none was sent
|
|
106
|
+
idempotentReplay:
|
|
107
|
+
type: boolean
|
|
108
|
+
description: >
|
|
109
|
+
present (true) when this answer is an idempotent replay of an existing decision: nothing was
|
|
110
|
+
evaluated, created, sealed or summoned again (one `agent.authorize.replayed` audit row is written),
|
|
111
|
+
and `receipt` carries only the fields fixed at create. A sealed auto-approval replays as `proceed`
|
|
112
|
+
only when THIS call could itself auto-approve (a verified, replay-protected identity or a trusted
|
|
113
|
+
transport); anything else answers `route` or `block` - ask GET /agent/status for the real state.
|
|
82
114
|
StatusResponse:
|
|
83
115
|
type: object
|
|
84
116
|
required: [state]
|
|
@@ -87,6 +119,13 @@ components:
|
|
|
87
119
|
type: string
|
|
88
120
|
enum: [pending, approved, auto_approved, rejected, blocked]
|
|
89
121
|
reason: { type: string }
|
|
122
|
+
requestCommitment:
|
|
123
|
+
type: [string, "null"]
|
|
124
|
+
description: >
|
|
125
|
+
SDK 0.7.0: the request commitment the decision was authorized with (null when none was
|
|
126
|
+
sent). The SDK treats an approval as covering the request it is about to run only when this
|
|
127
|
+
equals its own recompute; a gate that returns no commitment for a request the SDK bound is
|
|
128
|
+
refused (commitment_missing), never trusted.
|
|
90
129
|
ConfirmRequest:
|
|
91
130
|
type: object
|
|
92
131
|
required: [decisionId, capturedResponse, source]
|
|
@@ -163,10 +202,13 @@ components:
|
|
|
163
202
|
properties:
|
|
164
203
|
status:
|
|
165
204
|
type: string
|
|
166
|
-
enum: [executed, indeterminate, rejected, blocked, no_handler, unknown]
|
|
205
|
+
enum: [executed, indeterminate, rejected, blocked, no_handler, unknown, not_approved, request_unverified]
|
|
167
206
|
description: >
|
|
168
207
|
the LOCAL run. `indeterminate` means the handler was invoked and its outcome is
|
|
169
|
-
unknown — it will NOT be retried automatically and needs reconcile().
|
|
208
|
+
unknown — it will NOT be retried automatically and needs reconcile(). Since SDK 0.7.0 the
|
|
209
|
+
webhook is a wake-up: `not_approved` = Decidio does not (yet) record an approval, so nothing
|
|
210
|
+
ran and the entry stays parked; `request_unverified` = the approval could not be tied to the
|
|
211
|
+
parked request (a different request, or no commitment from the gate), so nothing ran.
|
|
170
212
|
decisionId: { type: string }
|
|
171
213
|
reportRecorded: { type: boolean, description: "Decidio accepted the execution report." }
|
|
172
214
|
executionConfirmed: { type: boolean, description: "the recorded tier attests a COMMITTED execution — a different question from reportRecorded." }
|
|
@@ -214,7 +256,11 @@ components:
|
|
|
214
256
|
description: >
|
|
215
257
|
OUTBOUND — Decidio → your resumeUrl when a routed decision is decided. The raw body is
|
|
216
258
|
HMAC-signed; verify `x-decidio-signature: sha256=<hex>` with your DECIDIO_WEBHOOK_SECRET
|
|
217
|
-
BEFORE acting (the SDK resume controllers fail closed
|
|
259
|
+
BEFORE acting (the SDK resume controllers fail closed; since SDK 0.7.0 there is no fallback to
|
|
260
|
+
the API token - no secret means 401). The server signs with DECIDIO_WEBHOOK_SECRET only and sends
|
|
261
|
+
no webhook without it; it is a dedicated secret - never the server's API_AUTH_TOKEN. It is a WAKE-UP, never the authority: since SDK 0.7.0 the
|
|
262
|
+
SDK reads only `decisionId`, then asks GET /agent/status and runs the parked action only when
|
|
263
|
+
Decidio records it approved for THIS request (the request commitment). A duplicate delivery cannot cause a
|
|
218
264
|
second execution: the SDK writes a durable invoking marker before calling the handler,
|
|
219
265
|
so once invocation may have begun it is never invoked again automatically.
|
|
220
266
|
OPERATOR DEPLOYMENTS ONLY: signing uses a shared secret configured on both the Decidio
|
|
@@ -245,7 +291,20 @@ paths:
|
|
|
245
291
|
content:
|
|
246
292
|
application/json:
|
|
247
293
|
schema: { $ref: "#/components/schemas/AuthorizeResponse" }
|
|
294
|
+
"400": { description: "a malformed field, including a requestCommitment or idempotencyKey outside its grammar, or an idempotencyKey without a requestCommitment" }
|
|
248
295
|
"401": { description: missing/invalid agent token }
|
|
296
|
+
"409":
|
|
297
|
+
description: >
|
|
298
|
+
IDEMPOTENCY_CONFLICT (SDK 0.7.0) - this idempotencyKey already names a decision for a
|
|
299
|
+
DIFFERENT request (its requestCommitment, or its requester, action, amount or scope, differs).
|
|
300
|
+
Send a new key for the new request.
|
|
301
|
+
content:
|
|
302
|
+
application/json:
|
|
303
|
+
schema:
|
|
304
|
+
type: object
|
|
305
|
+
properties:
|
|
306
|
+
code: { type: string, enum: [IDEMPOTENCY_CONFLICT] }
|
|
307
|
+
message: { type: string }
|
|
249
308
|
/agent/status/{decisionId}:
|
|
250
309
|
get:
|
|
251
310
|
summary: Poll a routed decision (blocking mode / durable worker)
|
|
@@ -328,7 +387,7 @@ paths:
|
|
|
328
387
|
x-webhooks:
|
|
329
388
|
resume:
|
|
330
389
|
post:
|
|
331
|
-
summary: Signed
|
|
390
|
+
summary: Signed wake-up delivery (Decidio → agent resumeUrl); the SDK confirms the approval with GET /agent/status before acting
|
|
332
391
|
requestBody:
|
|
333
392
|
content:
|
|
334
393
|
application/json:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decidio/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "One-line approval gate for AI-agent actions. Wrap a risky tool call with guard.protect(); Decidio's policy engine decides proceed | route | block, a human approves routed actions, and every outcome is sealed as a verifiable Authority Receipt.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"prepublishOnly": "npm run typecheck && npm run build && node ../publish-boundary/check.mjs --only @decidio/sdk"
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@decidio/verify": "0.
|
|
87
|
+
"@decidio/verify": "0.8.0"
|
|
88
88
|
},
|
|
89
89
|
"author": "OmniTwin Technologies Inc.",
|
|
90
90
|
"bugs": {
|