@vaultgraph/sdk 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -4
- package/dist/index.d.ts +64 -2
- package/dist/index.js +150 -3
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# VaultGraph SDK
|
|
2
2
|
|
|
3
|
-
[VaultGraph](https://vaultgraph.com) is a platform for building trustworthy AI agent applications.
|
|
3
|
+
[VaultGraph](https://vaultgraph.com) is a platform for building trustworthy AI agent applications.
|
|
4
4
|
|
|
5
5
|
## What this SDK is for
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
## Prerequisites
|
|
13
13
|
|
|
14
|
-
- A VaultGraph vendor organization in the portal (create or join at https://app.vaultgraph.com).
|
|
14
|
+
- A VaultGraph vendor organization in the portal (create or join at https://app.vaultgraph.com).
|
|
15
15
|
- Vendor API key created in the portal (Org Settings → API Keys). Keep this server-side only.
|
|
16
16
|
- At least one agent and consumer defined in the portal so you can reference their IDs when creating receipts.
|
|
17
17
|
|
|
@@ -122,6 +122,31 @@ const { receipt, signature } = createSignedReceipt({
|
|
|
122
122
|
});
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
+
### Manage agents via the API (server-only)
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { createAgentsClient } from "@vaultgraph/sdk";
|
|
129
|
+
|
|
130
|
+
const agents = createAgentsClient({
|
|
131
|
+
apiKey: process.env.VAULTGRAPH_VENDOR_API_KEY!,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const created = await agents.create({
|
|
135
|
+
name: "Support Bot",
|
|
136
|
+
description: "Handles tier-1 support workflows.",
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const list = await agents.list();
|
|
140
|
+
const detail = await agents.get(created.id);
|
|
141
|
+
|
|
142
|
+
const updated = await agents.update(created.id, {
|
|
143
|
+
name: "Support Bot v2",
|
|
144
|
+
description: "Now with escalation scoring.",
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
await agents.delete(updated.id);
|
|
148
|
+
```
|
|
149
|
+
|
|
125
150
|
## API surface
|
|
126
151
|
|
|
127
152
|
- `hashContext(value, options?)` → sha256 hash of canonical JSON/bytes
|
|
@@ -132,9 +157,9 @@ const { receipt, signature } = createSignedReceipt({
|
|
|
132
157
|
- `createSignedReceipt(options)` → `{ receipt, signature }`
|
|
133
158
|
- `submitSignedReceipt(options)` → creates, signs, and submits; defaults `apiUrl` to portal base
|
|
134
159
|
- `submitReceipt(options)` → POSTs to `/api/receipts` (requires `apiKey`)
|
|
135
|
-
- `
|
|
160
|
+
- `createAgentsClient(options)` → CRUD helper for `/api/agents`
|
|
136
161
|
- `generateKeyPair()` → returns PEM-encoded Ed25519 keypair
|
|
137
|
-
- Types: `CreateReceiptInput`, `JobReceipt`, `JobReceiptV0`, `JobResolution`, `ReceiptVersion`, `SubmitReceiptOptions`, `SubmitReceiptResponse`
|
|
162
|
+
- Types: `CreateReceiptInput`, `JobReceipt`, `JobReceiptV0`, `JobResolution`, `ReceiptVersion`, `SubmitReceiptOptions`, `SubmitReceiptResponse`, `AgentRecord`, `AgentCreateInput`, `AgentUpdateInput`, `AgentsClientOptions`, `AgentsClient`
|
|
138
163
|
|
|
139
164
|
## Notes
|
|
140
165
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,80 @@
|
|
|
1
|
-
import { KeyLike, BinaryToTextEncoding } from 'crypto';
|
|
2
1
|
import { CreateReceiptInput, JobReceipt } from '@repo/lib/job-receipt';
|
|
3
2
|
export { CreateReceiptInput, JOB_RESOLUTIONS, JobReceipt, JobReceiptV0, JobResolution, ReceiptVersion, canonicalJSONStringify, createReceipt, hashContext, jobReceiptV0Schema, serializeReceipt, signReceipt, verifyReceipt } from '@repo/lib/job-receipt';
|
|
4
3
|
import { SubmitReceiptResponse } from '@repo/lib/submit-receipt';
|
|
5
4
|
export { SubmitReceiptOptions, SubmitReceiptResponse, submitReceipt } from '@repo/lib/submit-receipt';
|
|
5
|
+
import { KeyLike, BinaryToTextEncoding } from 'crypto';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Agent record returned by the API.
|
|
9
|
+
*/
|
|
10
|
+
interface AgentRecord {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
description: string | null;
|
|
14
|
+
created_at: string;
|
|
15
|
+
updated_at: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Payload for creating agents.
|
|
19
|
+
*/
|
|
20
|
+
interface AgentCreateInput {
|
|
21
|
+
name: string;
|
|
22
|
+
description?: string | null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Payload for updating agents.
|
|
26
|
+
*/
|
|
27
|
+
interface AgentUpdateInput {
|
|
28
|
+
name: string;
|
|
29
|
+
description?: string | null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Configuration for `createAgentsClient`.
|
|
33
|
+
*/
|
|
34
|
+
interface AgentsClientOptions {
|
|
35
|
+
apiKey: string;
|
|
36
|
+
/** API base URL; defaults to the portal URL (app.vaultgraph.com in prod). */
|
|
37
|
+
apiUrl?: string;
|
|
38
|
+
fetchImpl?: typeof fetch;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Client interface for the agent API.
|
|
42
|
+
*/
|
|
43
|
+
interface AgentsClient {
|
|
44
|
+
list: () => Promise<AgentRecord[]>;
|
|
45
|
+
get: (id: string) => Promise<AgentRecord>;
|
|
46
|
+
create: (input: AgentCreateInput) => Promise<AgentRecord>;
|
|
47
|
+
update: (id: string, input: AgentUpdateInput) => Promise<AgentRecord>;
|
|
48
|
+
delete: (id: string) => Promise<{
|
|
49
|
+
id: string;
|
|
50
|
+
}>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Creates a minimal API client for managing agents.
|
|
55
|
+
*/
|
|
56
|
+
declare function createAgentsClient(options: AgentsClientOptions): AgentsClient;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Input for `createSignedReceipt`.
|
|
60
|
+
*/
|
|
7
61
|
interface CreateSignedReceiptOptions extends CreateReceiptInput {
|
|
62
|
+
/** PEM-encoded private key used to sign the receipt. */
|
|
8
63
|
privateKey: KeyLike;
|
|
64
|
+
/** Optional signing algorithm; defaults to Ed25519 when null. */
|
|
9
65
|
algorithm?: string | null;
|
|
66
|
+
/** Encoding for the resulting signature. */
|
|
10
67
|
encoding?: BinaryToTextEncoding;
|
|
11
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Input for `submitSignedReceipt`.
|
|
71
|
+
*/
|
|
12
72
|
interface SubmitSignedReceiptOptions extends CreateSignedReceiptOptions {
|
|
13
73
|
/** API base URL; defaults to the portal URL (app.vaultgraph.com in prod). */
|
|
14
74
|
apiUrl?: string;
|
|
75
|
+
/** Vendor API key for authentication. */
|
|
15
76
|
apiKey: string;
|
|
77
|
+
/** Public key matching the signing private key. */
|
|
16
78
|
publicKey: KeyLike;
|
|
17
79
|
/** Optional fetch implementation for custom transports or tests. */
|
|
18
80
|
fetchImpl?: typeof fetch;
|
|
@@ -40,4 +102,4 @@ declare function generateKeyPair(): {
|
|
|
40
102
|
publicKey: string;
|
|
41
103
|
};
|
|
42
104
|
|
|
43
|
-
export { type CreateSignedReceiptOptions, type SubmitSignedReceiptOptions, createSignedReceipt, generateKeyPair, submitSignedReceipt };
|
|
105
|
+
export { type AgentCreateInput, type AgentRecord, type AgentUpdateInput, type AgentsClient, type AgentsClientOptions, type CreateSignedReceiptOptions, type SubmitSignedReceiptOptions, createAgentsClient, createSignedReceipt, generateKeyPair, submitSignedReceipt };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash, sign, verify, createPrivateKey, createPublicKey, generateKeyPairSync } from 'crypto';
|
|
2
2
|
|
|
3
|
-
// src/
|
|
3
|
+
// ../lib/src/job-receipt.ts
|
|
4
4
|
var JOB_RESOLUTIONS = ["resolved", "partial", "failed"];
|
|
5
5
|
var VALID_JOB_RESOLUTIONS = JOB_RESOLUTIONS;
|
|
6
6
|
var jobReceiptV0Schema = {
|
|
@@ -217,7 +217,154 @@ function getPortalURL() {
|
|
|
217
217
|
return process.env.NEXT_PUBLIC_PORTAL_URL || process.env.NODE_ENV === "development" && "http://localhost:3001" || "https://app.vaultgraph.com";
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
// src/
|
|
220
|
+
// src/shared/api.ts
|
|
221
|
+
function assertNonEmpty(value, name) {
|
|
222
|
+
if (!value || !value.trim()) {
|
|
223
|
+
throw new Error(`${name} is required`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
function extractApiError(payload, fallback) {
|
|
227
|
+
if (!payload || typeof payload !== "object") {
|
|
228
|
+
return fallback || "Request failed";
|
|
229
|
+
}
|
|
230
|
+
const { detail, error } = payload;
|
|
231
|
+
return detail || error || fallback || "Request failed";
|
|
232
|
+
}
|
|
233
|
+
async function requestJson(options) {
|
|
234
|
+
const { apiUrl, apiKey, path, method, body, fetchImpl, headers } = options;
|
|
235
|
+
assertNonEmpty(apiUrl, "apiUrl");
|
|
236
|
+
assertNonEmpty(apiKey, "apiKey");
|
|
237
|
+
assertNonEmpty(path, "path");
|
|
238
|
+
const url = new URL(path, apiUrl).toString();
|
|
239
|
+
const fetcher = fetchImpl ?? fetch;
|
|
240
|
+
const res = await fetcher(url, {
|
|
241
|
+
method,
|
|
242
|
+
headers: {
|
|
243
|
+
"content-type": "application/json",
|
|
244
|
+
"x-api-key": apiKey,
|
|
245
|
+
...headers ?? {}
|
|
246
|
+
},
|
|
247
|
+
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
248
|
+
});
|
|
249
|
+
const payload = await safeParseJson2(res);
|
|
250
|
+
if (!res.ok) {
|
|
251
|
+
throw new Error(extractApiError(payload, res.statusText));
|
|
252
|
+
}
|
|
253
|
+
return payload;
|
|
254
|
+
}
|
|
255
|
+
async function safeParseJson2(response) {
|
|
256
|
+
try {
|
|
257
|
+
return await response.json();
|
|
258
|
+
} catch {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// src/agents/client.ts
|
|
264
|
+
function createAgentsClient(options) {
|
|
265
|
+
const { apiKey, apiUrl, fetchImpl } = options;
|
|
266
|
+
const targetApiUrl = apiUrl ?? getPortalURL();
|
|
267
|
+
assertNonEmpty(apiKey, "apiKey");
|
|
268
|
+
assertNonEmpty(targetApiUrl, "apiUrl");
|
|
269
|
+
return {
|
|
270
|
+
list: async () => {
|
|
271
|
+
const payload = await requestJson({
|
|
272
|
+
apiUrl: targetApiUrl,
|
|
273
|
+
apiKey,
|
|
274
|
+
path: "/api/agents",
|
|
275
|
+
method: "GET",
|
|
276
|
+
fetchImpl
|
|
277
|
+
});
|
|
278
|
+
return extractDataArray(payload, "agents");
|
|
279
|
+
},
|
|
280
|
+
get: async (id) => {
|
|
281
|
+
assertNonEmpty(id, "id");
|
|
282
|
+
const encodedId = encodeURIComponent(id);
|
|
283
|
+
const payload = await requestJson({
|
|
284
|
+
apiUrl: targetApiUrl,
|
|
285
|
+
apiKey,
|
|
286
|
+
path: `/api/agents/${encodedId}`,
|
|
287
|
+
method: "GET",
|
|
288
|
+
fetchImpl
|
|
289
|
+
});
|
|
290
|
+
return extractDataRecord(payload, "agent");
|
|
291
|
+
},
|
|
292
|
+
create: async (input) => {
|
|
293
|
+
assertNonEmpty(input.name, "name");
|
|
294
|
+
const payload = await requestJson({
|
|
295
|
+
apiUrl: targetApiUrl,
|
|
296
|
+
apiKey,
|
|
297
|
+
path: "/api/agents",
|
|
298
|
+
method: "POST",
|
|
299
|
+
body: {
|
|
300
|
+
name: input.name,
|
|
301
|
+
description: input.description ?? null
|
|
302
|
+
},
|
|
303
|
+
fetchImpl
|
|
304
|
+
});
|
|
305
|
+
return extractDataRecord(payload, "agent");
|
|
306
|
+
},
|
|
307
|
+
update: async (id, input) => {
|
|
308
|
+
assertNonEmpty(id, "id");
|
|
309
|
+
assertNonEmpty(input.name, "name");
|
|
310
|
+
const encodedId = encodeURIComponent(id);
|
|
311
|
+
const payload = await requestJson({
|
|
312
|
+
apiUrl: targetApiUrl,
|
|
313
|
+
apiKey,
|
|
314
|
+
path: `/api/agents/${encodedId}`,
|
|
315
|
+
method: "PUT",
|
|
316
|
+
body: {
|
|
317
|
+
name: input.name,
|
|
318
|
+
description: input.description ?? null
|
|
319
|
+
},
|
|
320
|
+
fetchImpl
|
|
321
|
+
});
|
|
322
|
+
return extractDataRecord(payload, "agent");
|
|
323
|
+
},
|
|
324
|
+
delete: async (id) => {
|
|
325
|
+
assertNonEmpty(id, "id");
|
|
326
|
+
const encodedId = encodeURIComponent(id);
|
|
327
|
+
const payload = await requestJson({
|
|
328
|
+
apiUrl: targetApiUrl,
|
|
329
|
+
apiKey,
|
|
330
|
+
path: `/api/agents/${encodedId}`,
|
|
331
|
+
method: "DELETE",
|
|
332
|
+
fetchImpl
|
|
333
|
+
});
|
|
334
|
+
return extractDeleteResponse(payload);
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function extractDataArray(payload, label) {
|
|
339
|
+
if (!payload || typeof payload !== "object") {
|
|
340
|
+
throw new Error(`Invalid ${label} response payload`);
|
|
341
|
+
}
|
|
342
|
+
const data = payload.data;
|
|
343
|
+
if (!Array.isArray(data)) {
|
|
344
|
+
throw new Error(`Invalid ${label} response data`);
|
|
345
|
+
}
|
|
346
|
+
return data;
|
|
347
|
+
}
|
|
348
|
+
function extractDataRecord(payload, label) {
|
|
349
|
+
if (!payload || typeof payload !== "object") {
|
|
350
|
+
throw new Error(`Invalid ${label} response payload`);
|
|
351
|
+
}
|
|
352
|
+
const data = payload.data;
|
|
353
|
+
if (!data || typeof data !== "object") {
|
|
354
|
+
throw new Error(`Invalid ${label} response data`);
|
|
355
|
+
}
|
|
356
|
+
return data;
|
|
357
|
+
}
|
|
358
|
+
function extractDeleteResponse(payload) {
|
|
359
|
+
if (!payload || typeof payload !== "object") {
|
|
360
|
+
throw new Error("Invalid delete response payload");
|
|
361
|
+
}
|
|
362
|
+
const id = payload.id;
|
|
363
|
+
if (!id) {
|
|
364
|
+
throw new Error("Invalid delete response data");
|
|
365
|
+
}
|
|
366
|
+
return { id };
|
|
367
|
+
}
|
|
221
368
|
function createSignedReceipt(options) {
|
|
222
369
|
const { privateKey, algorithm, encoding, ...receiptInput } = options;
|
|
223
370
|
const receipt = createReceipt(receiptInput);
|
|
@@ -251,4 +398,4 @@ function generateKeyPair() {
|
|
|
251
398
|
return { privateKey, publicKey };
|
|
252
399
|
}
|
|
253
400
|
|
|
254
|
-
export { JOB_RESOLUTIONS, canonicalJSONStringify, createReceipt, createSignedReceipt, generateKeyPair, hashContext, jobReceiptV0Schema, serializeReceipt, signReceipt, submitReceipt, submitSignedReceipt, verifyReceipt };
|
|
401
|
+
export { JOB_RESOLUTIONS, canonicalJSONStringify, createAgentsClient, createReceipt, createSignedReceipt, generateKeyPair, hashContext, jobReceiptV0Schema, serializeReceipt, signReceipt, submitReceipt, submitSignedReceipt, verifyReceipt };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaultgraph/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
"test": "vitest run",
|
|
39
39
|
"test:watch": "vitest",
|
|
40
40
|
"check-types": "tsc --noEmit",
|
|
41
|
-
"release": "bash ./scripts/publish.sh"
|
|
41
|
+
"release": "bash ./scripts/publish.sh",
|
|
42
|
+
"docs:sync": "node ./scripts/docs-sync.mjs"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
44
45
|
"@repo/lib": "workspace:*",
|