@auctra/sdk 0.2.0 → 0.3.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 +20 -0
- package/LICENSE +21 -0
- package/README.md +41 -4
- package/dist/cjs/index.js +247 -0
- package/dist/cjs/package.json +3 -0
- package/dist/esm/index.d.ts +355 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +242 -0
- package/package.json +18 -8
- package/src/index.ts +569 -0
- package/dist/index.d.ts +0 -129
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -143
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
- Extend `evaluateAction` with trust infrastructure fields: `claimedIntentId`, `parentActionId`, `actor`, and `action` (target, description, riskLevel, metadata).
|
|
6
|
+
- Return intelligence metadata on evaluation: authority validity, root intent validity, intent status, trust summary.
|
|
7
|
+
- Add `listIntents`, `createIntent`, `getIntent`, `getAuthorityGraph`, `getActionEvaluation`, and `getRootIntentChain`.
|
|
8
|
+
|
|
9
|
+
## 0.2.1
|
|
10
|
+
|
|
11
|
+
- Add complete response types for agents, delegations, action requests, policies, audit events, and API keys.
|
|
12
|
+
- Add `getDelegation`, `createPolicy`, and `listApiKeys`.
|
|
13
|
+
- Honor `Retry-After`, preserve caller cancellation, and validate client options.
|
|
14
|
+
- Correct the REST example to use the API's snake_case contract.
|
|
15
|
+
- Add package-level integration tests and npm provenance metadata.
|
|
16
|
+
- Ship tested ESM and CommonJS entry points.
|
|
17
|
+
|
|
18
|
+
## 0.2.0
|
|
19
|
+
|
|
20
|
+
- Add bounded retries, request deadlines, idempotent evaluation, and structured API errors.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Auctra
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -16,6 +16,8 @@ Evaluate every agent action against delegated authority and org policies before
|
|
|
16
16
|
npm install @auctra/sdk
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
Both ESM (`import`) and CommonJS (`require`) entry points are included.
|
|
20
|
+
|
|
19
21
|
## Quick start
|
|
20
22
|
|
|
21
23
|
```typescript
|
|
@@ -46,6 +48,31 @@ if (decision.decision === "allowed") {
|
|
|
46
48
|
}
|
|
47
49
|
```
|
|
48
50
|
|
|
51
|
+
### Trust infrastructure (0.3.0+)
|
|
52
|
+
|
|
53
|
+
Declare why an action is happening and trace it back to human-approved intent:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const intent = await auctra.createIntent({
|
|
57
|
+
title: "Renew SaaS contracts under $500/month for Q3",
|
|
58
|
+
description: "Procurement agent may renew eligible vendor subscriptions.",
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const decision = await auctra.evaluateAction({
|
|
62
|
+
agentId: "your-agent-uuid",
|
|
63
|
+
actionType: "send_payment",
|
|
64
|
+
claimedIntentId: intent.intent.id,
|
|
65
|
+
action: {
|
|
66
|
+
target: "vendor:slack",
|
|
67
|
+
description: "Renew Slack Team plan",
|
|
68
|
+
riskLevel: "medium",
|
|
69
|
+
},
|
|
70
|
+
payload: { amount: 420, currency: "USD" },
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
console.log(decision.intelligence?.trust_summary);
|
|
74
|
+
```
|
|
75
|
+
|
|
49
76
|
## Get an API key
|
|
50
77
|
|
|
51
78
|
1. [Sign up](https://console.auctra.tech/auth/signup) and create an organization
|
|
@@ -57,10 +84,18 @@ if (decision.decision === "allowed") {
|
|
|
57
84
|
|
|
58
85
|
| Method | Description |
|
|
59
86
|
| ------------------------------------------- | ------------------------------------------------- |
|
|
60
|
-
| `evaluateAction(input, options)` | Idempotently check authority before an agent acts |
|
|
61
|
-
| `
|
|
87
|
+
| `evaluateAction(input, options)` | Idempotently check authority + trust trace before an agent acts |
|
|
88
|
+
| `listIntents()` | List human-approved intents |
|
|
89
|
+
| `createIntent(input)` | Declare a new intent |
|
|
90
|
+
| `getIntent(id)` | Get intent detail and linked actions |
|
|
91
|
+
| `getAuthorityGraph()` | Fetch authority graph nodes and edges |
|
|
92
|
+
| `getActionEvaluation(actionRequestId)` | Get decision record for an action |
|
|
93
|
+
| `getRootIntentChain(actionRequestId)` | Get root human intent chain (trust trace) |
|
|
94
|
+
| `listAgents()` | List registered agents |
|
|
62
95
|
| `createAgent(input)` | Register a new agent |
|
|
96
|
+
| `getAgent(id)` | Get one registered agent |
|
|
63
97
|
| `listDelegations()` | List authority delegations |
|
|
98
|
+
| `getDelegation(id)` | Get one authority delegation |
|
|
64
99
|
| `createDelegation(input)` | Grant bounded authority |
|
|
65
100
|
| `revokeDelegation(id)` | Revoke a delegation |
|
|
66
101
|
| `listActionRequests()` | List recent evaluations |
|
|
@@ -68,7 +103,9 @@ if (decision.decision === "allowed") {
|
|
|
68
103
|
| `rejectActionRequest(id, approverUserId)` | Reject as an accountable reviewer |
|
|
69
104
|
| `escalateActionRequest(id, approverUserId)` | Escalate as an accountable reviewer |
|
|
70
105
|
| `listPolicies()` | List org policies |
|
|
106
|
+
| `createPolicy(input)` | Create an org policy |
|
|
71
107
|
| `listAuditEvents()` | List audit ledger events |
|
|
108
|
+
| `listApiKeys()` | List API key metadata |
|
|
72
109
|
|
|
73
110
|
## REST API (curl)
|
|
74
111
|
|
|
@@ -78,8 +115,8 @@ curl -X POST https://console.auctra.tech/v1/action-requests/evaluate \
|
|
|
78
115
|
-H "Idempotency-Key: $(uuidgen)" \
|
|
79
116
|
-H "Content-Type: application/json" \
|
|
80
117
|
-d '{
|
|
81
|
-
"
|
|
82
|
-
"
|
|
118
|
+
"agent_id": "your-agent-uuid",
|
|
119
|
+
"action_type": "send_payment",
|
|
83
120
|
"payload": { "amount": 100, "currency": "USD" }
|
|
84
121
|
}'
|
|
85
122
|
```
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Auctra = exports.AuctraApiError = exports.AUCTRA_SDK_VERSION = void 0;
|
|
4
|
+
exports.AUCTRA_SDK_VERSION = "0.3.0";
|
|
5
|
+
class AuctraApiError extends Error {
|
|
6
|
+
status;
|
|
7
|
+
code;
|
|
8
|
+
details;
|
|
9
|
+
requestId;
|
|
10
|
+
constructor(message, options) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = "AuctraApiError";
|
|
13
|
+
this.status = options.status;
|
|
14
|
+
this.code = options.code;
|
|
15
|
+
this.details = options.details;
|
|
16
|
+
this.requestId = options.requestId;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.AuctraApiError = AuctraApiError;
|
|
20
|
+
function retryDelay(response, attempt) {
|
|
21
|
+
const retryAfter = response?.headers.get("retry-after");
|
|
22
|
+
if (retryAfter) {
|
|
23
|
+
const seconds = Number(retryAfter);
|
|
24
|
+
if (Number.isFinite(seconds))
|
|
25
|
+
return Math.min(30_000, Math.max(0, seconds * 1_000));
|
|
26
|
+
const dateDelay = Date.parse(retryAfter) - Date.now();
|
|
27
|
+
if (Number.isFinite(dateDelay))
|
|
28
|
+
return Math.min(30_000, Math.max(0, dateDelay));
|
|
29
|
+
}
|
|
30
|
+
return Math.min(5_000, 150 * 2 ** attempt);
|
|
31
|
+
}
|
|
32
|
+
function wait(ms, signal) {
|
|
33
|
+
if (signal?.aborted)
|
|
34
|
+
return Promise.reject(signal.reason);
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
const timeout = setTimeout(resolve, ms);
|
|
37
|
+
signal?.addEventListener("abort", () => {
|
|
38
|
+
clearTimeout(timeout);
|
|
39
|
+
reject(signal.reason);
|
|
40
|
+
}, { once: true });
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
class Auctra {
|
|
44
|
+
apiKey;
|
|
45
|
+
baseUrl;
|
|
46
|
+
timeoutMs;
|
|
47
|
+
maxRetries;
|
|
48
|
+
fetchImpl;
|
|
49
|
+
constructor(options) {
|
|
50
|
+
if (!options.apiKey.trim())
|
|
51
|
+
throw new Error("apiKey is required");
|
|
52
|
+
if (options.timeoutMs !== undefined && options.timeoutMs <= 0) {
|
|
53
|
+
throw new Error("timeoutMs must be greater than zero");
|
|
54
|
+
}
|
|
55
|
+
if (options.maxRetries !== undefined &&
|
|
56
|
+
(!Number.isInteger(options.maxRetries) || options.maxRetries < 0)) {
|
|
57
|
+
throw new Error("maxRetries must be a non-negative integer");
|
|
58
|
+
}
|
|
59
|
+
this.apiKey = options.apiKey;
|
|
60
|
+
this.baseUrl = (options.baseUrl ?? "https://console.auctra.tech").replace(/\/$/, "");
|
|
61
|
+
this.timeoutMs = options.timeoutMs ?? 10_000;
|
|
62
|
+
this.maxRetries = options.maxRetries ?? 2;
|
|
63
|
+
this.fetchImpl = options.fetch ?? globalThis.fetch;
|
|
64
|
+
if (!this.fetchImpl)
|
|
65
|
+
throw new Error("A fetch implementation is required");
|
|
66
|
+
}
|
|
67
|
+
async request(method, path, body, options = {}) {
|
|
68
|
+
const retryableRequest = method === "GET" || Boolean(options.idempotencyKey);
|
|
69
|
+
let lastError;
|
|
70
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt += 1) {
|
|
71
|
+
if (options.signal?.aborted)
|
|
72
|
+
throw options.signal.reason;
|
|
73
|
+
const timeoutSignal = AbortSignal.timeout(this.timeoutMs);
|
|
74
|
+
const signal = options.signal
|
|
75
|
+
? AbortSignal.any([options.signal, timeoutSignal])
|
|
76
|
+
: timeoutSignal;
|
|
77
|
+
let response;
|
|
78
|
+
try {
|
|
79
|
+
response = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
80
|
+
method,
|
|
81
|
+
signal,
|
|
82
|
+
headers: {
|
|
83
|
+
...(body !== undefined ? { "content-type": "application/json" } : {}),
|
|
84
|
+
...(options.idempotencyKey ? { "idempotency-key": options.idempotencyKey } : {}),
|
|
85
|
+
authorization: `Bearer ${this.apiKey}`,
|
|
86
|
+
"x-auctra-sdk-version": exports.AUCTRA_SDK_VERSION,
|
|
87
|
+
},
|
|
88
|
+
...(body !== undefined ? { body: JSON.stringify(body) } : {}),
|
|
89
|
+
});
|
|
90
|
+
const data = (await response.json().catch(() => ({})));
|
|
91
|
+
if (response.ok)
|
|
92
|
+
return data;
|
|
93
|
+
if (retryableRequest &&
|
|
94
|
+
(response.status === 429 || response.status >= 500) &&
|
|
95
|
+
attempt < this.maxRetries) {
|
|
96
|
+
await wait(retryDelay(response, attempt), options.signal);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
throw new AuctraApiError(typeof data.error === "string" ? data.error : `Auctra API error (${response.status})`, {
|
|
100
|
+
status: response.status,
|
|
101
|
+
code: typeof data.code === "string" ? data.code : undefined,
|
|
102
|
+
details: data.details,
|
|
103
|
+
requestId: response.headers.get("x-request-id") ?? undefined,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
lastError = error;
|
|
108
|
+
if (options.signal?.aborted)
|
|
109
|
+
throw options.signal.reason;
|
|
110
|
+
if (error instanceof AuctraApiError || !retryableRequest || attempt >= this.maxRetries) {
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
await wait(retryDelay(response, attempt), options.signal);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
throw lastError;
|
|
117
|
+
}
|
|
118
|
+
async evaluateAction(input, options = {}) {
|
|
119
|
+
const idempotencyKey = options.idempotencyKey ?? crypto.randomUUID();
|
|
120
|
+
return this.request("POST", "/v1/action-requests/evaluate", {
|
|
121
|
+
agent_id: input.agentId,
|
|
122
|
+
action_type: input.actionType,
|
|
123
|
+
payload: input.payload ?? {},
|
|
124
|
+
claimed_intent_id: input.claimedIntentId,
|
|
125
|
+
parent_action_id: input.parentActionId,
|
|
126
|
+
actor: input.actor
|
|
127
|
+
? {
|
|
128
|
+
id: input.actor.id,
|
|
129
|
+
type: input.actor.type,
|
|
130
|
+
name: input.actor.name,
|
|
131
|
+
}
|
|
132
|
+
: undefined,
|
|
133
|
+
action: input.action
|
|
134
|
+
? {
|
|
135
|
+
target: input.action.target,
|
|
136
|
+
description: input.action.description,
|
|
137
|
+
risk_level: input.action.riskLevel,
|
|
138
|
+
metadata: input.action.metadata,
|
|
139
|
+
}
|
|
140
|
+
: undefined,
|
|
141
|
+
}, { ...options, idempotencyKey });
|
|
142
|
+
}
|
|
143
|
+
async listIntents() {
|
|
144
|
+
return this.request("GET", "/v1/intents");
|
|
145
|
+
}
|
|
146
|
+
async createIntent(input) {
|
|
147
|
+
return this.request("POST", "/v1/intents", {
|
|
148
|
+
title: input.title,
|
|
149
|
+
description: input.description,
|
|
150
|
+
intent_type: input.intentType,
|
|
151
|
+
risk_level: input.riskLevel,
|
|
152
|
+
max_risk_level: input.maxRiskLevel,
|
|
153
|
+
expires_at: input.expiresAt,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
async getIntent(intentId) {
|
|
157
|
+
return this.request("GET", `/v1/intents/${encodeURIComponent(intentId)}`);
|
|
158
|
+
}
|
|
159
|
+
async getAuthorityGraph() {
|
|
160
|
+
return this.request("GET", "/v1/authority/graph");
|
|
161
|
+
}
|
|
162
|
+
async getActionEvaluation(actionRequestId) {
|
|
163
|
+
return this.request("GET", `/v1/action-requests/${encodeURIComponent(actionRequestId)}/evaluation`);
|
|
164
|
+
}
|
|
165
|
+
async getRootIntentChain(actionRequestId) {
|
|
166
|
+
return this.request("GET", `/v1/action-requests/${encodeURIComponent(actionRequestId)}/root-intent`);
|
|
167
|
+
}
|
|
168
|
+
async listAgents() {
|
|
169
|
+
return this.request("GET", "/v1/agents");
|
|
170
|
+
}
|
|
171
|
+
async getAgent(agentId) {
|
|
172
|
+
return this.request("GET", `/v1/agents/${encodeURIComponent(agentId)}`);
|
|
173
|
+
}
|
|
174
|
+
async createAgent(input) {
|
|
175
|
+
return this.request("POST", "/v1/agents", {
|
|
176
|
+
name: input.name,
|
|
177
|
+
model_provider: input.modelProvider,
|
|
178
|
+
model_name: input.modelName,
|
|
179
|
+
description: input.description,
|
|
180
|
+
environment: input.environment,
|
|
181
|
+
authority_level: input.authorityLevel,
|
|
182
|
+
sponsor_user_id: input.sponsorUserId,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
async listDelegations() {
|
|
186
|
+
return this.request("GET", "/v1/delegations");
|
|
187
|
+
}
|
|
188
|
+
async getDelegation(delegationId) {
|
|
189
|
+
return this.request("GET", `/v1/delegations/${encodeURIComponent(delegationId)}`);
|
|
190
|
+
}
|
|
191
|
+
async createDelegation(input) {
|
|
192
|
+
return this.request("POST", "/v1/delegations", {
|
|
193
|
+
agent_id: input.agentId,
|
|
194
|
+
action_types: input.actionTypes,
|
|
195
|
+
valid_until: input.validUntil,
|
|
196
|
+
max_amount: input.maxAmount,
|
|
197
|
+
max_count: input.maxCount,
|
|
198
|
+
environment: input.environment,
|
|
199
|
+
currency: input.currency,
|
|
200
|
+
delegator_user_id: input.delegatorUserId,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
async revokeDelegation(delegationId) {
|
|
204
|
+
return this.request("POST", `/v1/delegations/${encodeURIComponent(delegationId)}/revoke`, {});
|
|
205
|
+
}
|
|
206
|
+
async listActionRequests() {
|
|
207
|
+
return this.request("GET", "/v1/action-requests");
|
|
208
|
+
}
|
|
209
|
+
async approveActionRequest(actionRequestId, approverUserId, reason) {
|
|
210
|
+
return this.resolveActionRequest(actionRequestId, "approve", approverUserId, reason);
|
|
211
|
+
}
|
|
212
|
+
async rejectActionRequest(actionRequestId, approverUserId, reason) {
|
|
213
|
+
return this.resolveActionRequest(actionRequestId, "reject", approverUserId, reason);
|
|
214
|
+
}
|
|
215
|
+
async escalateActionRequest(actionRequestId, approverUserId, reason) {
|
|
216
|
+
return this.resolveActionRequest(actionRequestId, "escalate", approverUserId, reason);
|
|
217
|
+
}
|
|
218
|
+
async resolveActionRequest(actionRequestId, action, approverUserId, reason) {
|
|
219
|
+
return this.request("POST", `/v1/action-requests/${encodeURIComponent(actionRequestId)}/${action}`, { reason, approver_user_id: approverUserId });
|
|
220
|
+
}
|
|
221
|
+
async listPolicies() {
|
|
222
|
+
return this.request("GET", "/v1/policies");
|
|
223
|
+
}
|
|
224
|
+
async createPolicy(input) {
|
|
225
|
+
return this.request("POST", "/v1/policies", {
|
|
226
|
+
name: input.name,
|
|
227
|
+
description: input.description,
|
|
228
|
+
policy_type: input.policyType,
|
|
229
|
+
status: input.status,
|
|
230
|
+
priority: input.priority,
|
|
231
|
+
action_type: input.actionType,
|
|
232
|
+
amount_greater_than: input.amountGreaterThan,
|
|
233
|
+
resource_sensitivity: input.resourceSensitivity,
|
|
234
|
+
external_recipient: input.externalRecipient,
|
|
235
|
+
environment: input.environment,
|
|
236
|
+
decision: input.decision,
|
|
237
|
+
approver_role: input.approverRole,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
async listAuditEvents() {
|
|
241
|
+
return this.request("GET", "/v1/audit-events");
|
|
242
|
+
}
|
|
243
|
+
async listApiKeys() {
|
|
244
|
+
return this.request("GET", "/v1/api-keys");
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
exports.Auctra = Auctra;
|