@onesi/genesis 0.1.13 → 0.2.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/README.md +1 -1
- package/dist/auto.d.ts +1010 -0
- package/dist/auto.js +125 -0
- package/dist/beacons.d.ts +42 -0
- package/dist/beacons.js +71 -0
- package/dist/blinds-owner-enrollment.d.ts +109 -0
- package/dist/blinds-owner-enrollment.js +21 -2
- package/dist/client.d.ts +3 -19947
- package/dist/client.js +124 -17
- package/dist/errors.js +1 -1
- package/dist/flares.d.ts +32 -0
- package/dist/flares.js +5 -0
- package/dist/fleets.d.ts +32 -0
- package/dist/fleets.js +59 -6
- package/dist/flocks.d.ts +285 -1
- package/dist/flocks.js +59 -0
- package/dist/foundry.d.ts +424 -0
- package/dist/foundry.js +133 -0
- package/dist/garden.d.ts +754 -0
- package/dist/garden.js +76 -0
- package/dist/gateway.d.ts +365 -0
- package/dist/gateway.js +82 -0
- package/dist/gears.d.ts +121 -2
- package/dist/gears.js +24 -2
- package/dist/generated/operations.d.ts +3 -19948
- package/dist/generated/operations.js +54590 -13302
- package/dist/generated/schema.d.ts +69793 -17548
- package/dist/genesis.d.ts +7908 -1260
- package/dist/genesis.js +90 -25
- package/dist/genesis.openapi.json +109121 -29920
- package/dist/henry.d.ts +202 -1
- package/dist/henry.js +223 -0
- package/dist/hives-environment.d.ts +9 -0
- package/dist/hives-environment.js +22 -0
- package/dist/hives-node.js +3 -0
- package/dist/hives-operations.d.ts +114 -0
- package/dist/hives-operations.js +2 -0
- package/dist/hives-platform.d.ts +149 -0
- package/dist/hives-platform.js +183 -0
- package/dist/hives-sse.d.ts +24 -0
- package/dist/hives-sse.js +111 -0
- package/dist/iam-directory.d.ts +8 -0
- package/dist/iam-directory.js +23 -0
- package/dist/iam.d.ts +391 -0
- package/dist/iam.js +92 -0
- package/dist/idempotency.d.ts +3 -0
- package/dist/idempotency.js +22 -0
- package/dist/index.d.ts +18 -4
- package/dist/index.js +16 -4
- package/dist/instances.d.ts +177 -2
- package/dist/instances.js +37 -5
- package/dist/minds-agent.d.ts +28 -0
- package/dist/minds-agent.js +53 -10
- package/dist/minds-engine.d.ts +394 -0
- package/dist/minds-engine.js +555 -0
- package/dist/minds.d.ts +109 -1
- package/dist/minds.js +49 -14
- package/dist/orgs.d.ts +405 -0
- package/dist/orgs.js +63 -0
- package/dist/runner.d.ts +4 -0
- package/dist/runner.js +1 -0
- package/dist/scopes.d.ts +310 -0
- package/dist/scopes.js +40 -0
- package/dist/taps.d.ts +118 -0
- package/dist/taps.js +45 -0
- package/dist/traces.d.ts +574 -0
- package/dist/traces.js +97 -0
- package/dist/types.d.ts +12 -1
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -9,12 +9,18 @@ import { isHivesObjectUpload, hivesObjectBody, hivesContentType, isHivesResource
|
|
|
9
9
|
import { operationTable, services } from './generated/operations.js';
|
|
10
10
|
import { GenesisError } from './errors.js';
|
|
11
11
|
import { requireSecureUrl } from './urls.js';
|
|
12
|
+
import { iamDirectoryFailure, isIamDirectoryOperation } from './iam-directory.js';
|
|
12
13
|
import { validateHivesInvocation, hivesFunctionResponseHeaders, hivesFunctionMetadata, hivesOperationError } from './hives-functions.js';
|
|
13
|
-
import { validateHivesEnvironment, hivesEnvironmentMetadata, hivesEnvironmentReveal } from './hives-environment.js';
|
|
14
|
+
import { validateHivesEnvironment, validateHivesEnvironmentNames, hivesEnvironmentSetNames, hivesEnvironmentMetadata, hivesEnvironmentReveal } from './hives-environment.js';
|
|
14
15
|
import { RUNNER_SELF_GRANT_OPERATION, snapshotRunnerSelfGrant, runnerGrantResponse, runnerGrantTransportError } from './runner-grant.js';
|
|
15
16
|
/** The Genesis API gateway. `https://console.life.one/api` remains an alias for the same gateway. */
|
|
16
17
|
export const DEFAULT_BASE_URL = 'https://os.one.ml/api';
|
|
17
18
|
const env = globalThis.process?.env ?? {};
|
|
19
|
+
/** Endless Server-Sent Events streams and the bounded reader for each; request() refuses these and any operation generated with `stream: true`. */
|
|
20
|
+
const ENDLESS_STREAMS = {
|
|
21
|
+
hives_stream_logs: 'genesis.hives.logs.stream() or genesis.hives.logs.window()',
|
|
22
|
+
hives_stream_deployment_logs: 'hivesSseWindow(await genesis.raw(...))',
|
|
23
|
+
};
|
|
18
24
|
export class GenesisClient {
|
|
19
25
|
baseUrl;
|
|
20
26
|
routing;
|
|
@@ -45,11 +51,19 @@ export class GenesisClient {
|
|
|
45
51
|
const v = input[k];
|
|
46
52
|
if (v === undefined || v === null || v === '')
|
|
47
53
|
throw new GenesisError({ status: 0, type: 'invalid_request', message: `Missing required path parameter "${k}" for ${operationId}`, operationId });
|
|
48
|
-
|
|
54
|
+
if (!op.tailParams?.includes(k))
|
|
55
|
+
return encodeURIComponent(String(v));
|
|
56
|
+
const segments = String(v).split('/');
|
|
57
|
+
if (segments.some(s => s === '' || s === '.' || s === '..' || s.includes('\\')))
|
|
58
|
+
throw new GenesisError({ status: 0, type: 'invalid_request', operationId,
|
|
59
|
+
message: `Path parameter "${k}" for ${operationId} must be "/"-separated segments with no empty, "." or ".." segment and no backslash` });
|
|
60
|
+
return segments.map(encodeURIComponent).join('/');
|
|
49
61
|
});
|
|
50
62
|
let base;
|
|
51
63
|
let p;
|
|
52
64
|
if (this.routing === 'direct') {
|
|
65
|
+
if (op.service === 'gateway')
|
|
66
|
+
throw new GenesisError({ status: 0, type: 'invalid_request', operationId, message: 'Gateway operations are answered by the Genesis gateway itself and have no direct upstream.' });
|
|
53
67
|
base = (this.opts.upstreams?.[op.service] ?? op.upstream.base).replace(/\/+$/, '');
|
|
54
68
|
p = fill(op.upstream.path);
|
|
55
69
|
}
|
|
@@ -72,9 +86,21 @@ export class GenesisClient {
|
|
|
72
86
|
}
|
|
73
87
|
/** Call any Genesis operation by id, fully typed from the merged spec. */
|
|
74
88
|
async request(operationId, input, init = {}) {
|
|
89
|
+
// An endless SSE body never completes, so buffering it would hang: refuse before any request is sent.
|
|
90
|
+
// Finite SSE reads (for example traces_streamRun) are not marked and still use request().
|
|
91
|
+
const endless = ENDLESS_STREAMS[operationId]
|
|
92
|
+
?? (operationTable[operationId]?.stream === true ? 'hivesSseWindow(await genesis.raw(...))' : undefined);
|
|
93
|
+
if (endless)
|
|
94
|
+
throw new GenesisError({ status: 0, type: 'invalid_request', operationId,
|
|
95
|
+
message: `${String(operationId)} is an endless Server-Sent Events stream. Read a bounded window with ${endless} instead of request().` });
|
|
75
96
|
const res = await this.raw(operationId, (input ?? {}), init);
|
|
76
97
|
if (operationTable[operationId].rawResponse)
|
|
77
98
|
return res;
|
|
99
|
+
// DELETE /env answers 200 with an empty body.
|
|
100
|
+
if (operationId === 'hives_delete_project_env') {
|
|
101
|
+
void res.body?.cancel().catch(() => { });
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
78
104
|
if (operationId === 'hives_stop_deployment' && res.status !== 200) {
|
|
79
105
|
void res.body?.cancel().catch(() => { });
|
|
80
106
|
throw new GenesisError({ status: 0, type: 'invalid_response', operationId, message: 'Hives did not confirm this deployment stopped. Read its current state before explicitly reconciling stop.' });
|
|
@@ -87,7 +113,7 @@ export class GenesisClient {
|
|
|
87
113
|
value = ct.includes('json') ? await res.json() : await res.text();
|
|
88
114
|
}
|
|
89
115
|
catch (error) {
|
|
90
|
-
if (String(operationId).startsWith('hives_') &&
|
|
116
|
+
if (String(operationId).startsWith('hives_') && /_project_env(?:ironment)?$/.test(operationId))
|
|
91
117
|
throw new Error('Hives returned invalid environment data.');
|
|
92
118
|
if (String(operationId).startsWith('hives_') && /_functions?$/.test(operationId))
|
|
93
119
|
throw new Error('Hives returned invalid function metadata.');
|
|
@@ -111,6 +137,9 @@ export class GenesisClient {
|
|
|
111
137
|
if (operationId === 'hives_list_project_environment' || operationId === 'hives_update_project_environment') {
|
|
112
138
|
return hivesEnvironmentMetadata(value, input?.project_id, operationId === 'hives_update_project_environment');
|
|
113
139
|
}
|
|
140
|
+
if (operationId === 'hives_set_project_env') {
|
|
141
|
+
return hivesEnvironmentSetNames(value, input?.project_id, input?.body);
|
|
142
|
+
}
|
|
114
143
|
if (operationId === 'hives_reveal_project_environment') {
|
|
115
144
|
return hivesEnvironmentReveal(value, input?.key);
|
|
116
145
|
}
|
|
@@ -118,6 +147,17 @@ export class GenesisClient {
|
|
|
118
147
|
}
|
|
119
148
|
/** Raw Response. Completed Hives guest responses retain their actual status, including non-2xx. */
|
|
120
149
|
async raw(operationId, input = {}, init = {}) {
|
|
150
|
+
if (!isIamDirectoryOperation(operationId))
|
|
151
|
+
return this.dispatch(operationId, input, init);
|
|
152
|
+
// The gateway binds the organization context itself. A refusal is only explained here; the client never changes a session or its context.
|
|
153
|
+
try {
|
|
154
|
+
return await this.dispatch(operationId, input, init);
|
|
155
|
+
}
|
|
156
|
+
catch (e) {
|
|
157
|
+
throw iamDirectoryFailure(e, typeof input.org_id === 'string' ? input.org_id : '', operationId);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
async dispatch(operationId, input, init) {
|
|
121
161
|
if (isMindsOwnerOperation(operationId))
|
|
122
162
|
return mindsOwnerTransport({ operationId, input, headers: init.headers, routing: this.routing, url: this.url(operationId, input), credential: () => this.credential(), fetch: this.fetchImpl, signal: init.signal });
|
|
123
163
|
if (isMindsAgentOperation(operationId))
|
|
@@ -139,13 +179,15 @@ export class GenesisClient {
|
|
|
139
179
|
const flocksNative = ['flocks_exchangeJoinToken', 'flocks_activateNode', 'flocks_rotateNodeCredential'].includes(operationId);
|
|
140
180
|
if (flocksNative && this.routing === 'direct')
|
|
141
181
|
throw new GenesisError({ status: 0, type: 'invalid_request', message: 'Native Flocks credentials are brokered only through the Genesis gateway.', operationId });
|
|
142
|
-
if (operationId === 'hives_update_project_environment')
|
|
182
|
+
if (operationId === 'hives_update_project_environment' || operationId === 'hives_set_project_env')
|
|
143
183
|
input = { ...input, body: validateHivesEnvironment(input.body) };
|
|
184
|
+
if (operationId === 'hives_delete_project_env')
|
|
185
|
+
input = { ...input, body: validateHivesEnvironmentNames(input.body) };
|
|
144
186
|
const objectBody = isHivesObjectUpload(operationId) ? await hivesObjectBody(input.body) : undefined;
|
|
145
187
|
const url = this.url(operationId, input);
|
|
146
188
|
const headers = {
|
|
147
189
|
accept: 'application/json',
|
|
148
|
-
'user-agent': this.opts.userAgent ?? '@onesi/genesis/0.
|
|
190
|
+
'user-agent': this.opts.userAgent ?? '@onesi/genesis/0.2.0',
|
|
149
191
|
...this.opts.headers, ...init.headers,
|
|
150
192
|
};
|
|
151
193
|
if (op.service === 'blinds' && !['GET', 'HEAD', 'OPTIONS'].includes(op.method))
|
|
@@ -203,7 +245,7 @@ export class GenesisClient {
|
|
|
203
245
|
body = JSON.stringify(input.body);
|
|
204
246
|
}
|
|
205
247
|
}
|
|
206
|
-
const environmentOperation = op.service === 'hives' &&
|
|
248
|
+
const environmentOperation = op.service === 'hives' && /_project_env(?:ironment)?$/.test(operationId);
|
|
207
249
|
const secretOperation = op.service === 'hives' && (/_secrets?$/.test(operationId) || environmentOperation);
|
|
208
250
|
const functionOperation = op.service === 'hives' && (op.rawResponse || /_function(?:s|_async)?$/.test(operationId));
|
|
209
251
|
let res;
|
|
@@ -224,13 +266,28 @@ export class GenesisClient {
|
|
|
224
266
|
}
|
|
225
267
|
if (runnerGrant)
|
|
226
268
|
return runnerGrantResponse(res, runnerGrant);
|
|
269
|
+
// A raw (binary) answer outside Hives, e.g. a Panes screenshot: a success is the bytes; a
|
|
270
|
+
// failure takes the ordinary error path below.
|
|
271
|
+
if (op.rawResponse && op.service !== 'hives' && res.ok)
|
|
272
|
+
return res;
|
|
227
273
|
if (op.rawResponse && /^exec_[a-f0-9]{32}$/.test(res.headers.get('x-execution-id') ?? '')) {
|
|
228
274
|
return new Response(res.body, { status: res.status, statusText: res.statusText, headers: hivesFunctionResponseHeaders(res.headers) });
|
|
229
275
|
}
|
|
230
276
|
if (op.rawResponse && op.service === 'hives' && res.headers.has('x-hives-operation-id')) {
|
|
277
|
+
// 5xx stays invalid_response below: its outcome is uncertain, so keep the key and reconcile.
|
|
278
|
+
const copy = res.status >= 400 && res.status < 500 ? res.clone() : undefined;
|
|
231
279
|
const error = await hivesOperationError(res);
|
|
232
|
-
if (error)
|
|
280
|
+
if (error) {
|
|
281
|
+
void copy?.body?.cancel().catch(() => { });
|
|
233
282
|
throw error;
|
|
283
|
+
}
|
|
284
|
+
// A refusal envelope that is not an operation receipt keeps its own status, code and request id (finding G2).
|
|
285
|
+
const detail = copy ? await hivesErrorDetail(copy) : {};
|
|
286
|
+
if (detail.code !== undefined) {
|
|
287
|
+
throw new GenesisError({ status: res.status, type: `http_${res.status}`, operationId, code: detail.code,
|
|
288
|
+
message: detail.message ?? `Hives refused this invocation (${res.status}). Keep the original idempotency key and read its operation status before retrying.`,
|
|
289
|
+
requestId: res.headers.get('x-request-id') ?? detail.requestId });
|
|
290
|
+
}
|
|
234
291
|
throw new GenesisError({ status: res.status, type: 'invalid_response', operationId,
|
|
235
292
|
message: 'Hives operation status was not confirmed. Keep the original idempotency key and reconcile its operation.' });
|
|
236
293
|
}
|
|
@@ -238,16 +295,21 @@ export class GenesisClient {
|
|
|
238
295
|
throw new GenesisError({ status: res.status, type: 'invalid_response', operationId,
|
|
239
296
|
message: 'Hives did not confirm a completed guest execution. Keep the original invocation key and reconcile its operation.' });
|
|
240
297
|
if (functionOperation && !res.ok) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
298
|
+
// Keep the service's own refusal code and text (findings G3, G4); the fixed texts are fallbacks only.
|
|
299
|
+
const detail = await hivesErrorDetail(res);
|
|
300
|
+
const invocation = op.rawResponse === true;
|
|
301
|
+
const scope = detail.code === undefined || /scope/i.test(detail.code);
|
|
302
|
+
const message = detail.code !== undefined && detail.message !== undefined && !(res.status === 403 && scope) ? detail.message
|
|
303
|
+
: res.status === 401 ? 'Genesis credential rejected. Sign in again.'
|
|
304
|
+
: res.status === 403 ? (scope ? 'Missing the authorized Hives scope for this function action.' : `Hives refused this ${invocation ? 'invocation' : 'function action'} (${detail.code}).`)
|
|
305
|
+
: res.status === 404 ? 'Function/deployment, project or artifact not found in the authenticated organization and project.'
|
|
306
|
+
: res.status === 409 ? (invocation ? `Hives refused this invocation as a conflict${detail.code ? ` (${detail.code})` : ''}. Read the target's current state before retrying.` : 'Function mutation conflicted. Refresh its metadata before retrying.')
|
|
307
|
+
: res.status === 400 || res.status === 422 ? 'Invalid function request. Check artifact, resource bounds and guest request syntax.'
|
|
308
|
+
: res.status === 413 ? 'Function request exceeds a body or serialized guest envelope limit.'
|
|
309
|
+
: res.status >= 300 && res.status < 400 ? 'Unexpected function service redirect. No redirect was followed.'
|
|
310
|
+
: `Hives function operation failed (${res.status}). Refresh and retry.`;
|
|
311
|
+
throw new GenesisError({ status: res.status, type: `http_${res.status}`, operationId, message, code: detail.code,
|
|
312
|
+
requestId: res.headers.get('x-request-id') ?? detail.requestId });
|
|
251
313
|
}
|
|
252
314
|
if (!res.ok && secretOperation) {
|
|
253
315
|
const message = res.status === 401 ? 'Genesis credential rejected. Sign in again.'
|
|
@@ -275,3 +337,48 @@ export class GenesisClient {
|
|
|
275
337
|
return res;
|
|
276
338
|
}
|
|
277
339
|
}
|
|
340
|
+
/**
|
|
341
|
+
* The refusal code, short message and request id of a Hives function/invocation error body. Reads at most
|
|
342
|
+
* 8 KiB and keeps nothing else: a body without a platform code may reflect guest request data.
|
|
343
|
+
*/
|
|
344
|
+
async function hivesErrorDetail(res) {
|
|
345
|
+
if (!res.body)
|
|
346
|
+
return {};
|
|
347
|
+
const reader = res.body.getReader();
|
|
348
|
+
const chunks = [];
|
|
349
|
+
let size = 0;
|
|
350
|
+
try {
|
|
351
|
+
for (;;) {
|
|
352
|
+
const { value, done } = await reader.read();
|
|
353
|
+
if (done)
|
|
354
|
+
break;
|
|
355
|
+
size += value.length;
|
|
356
|
+
if (size > 8192) {
|
|
357
|
+
await reader.cancel().catch(() => { });
|
|
358
|
+
return {};
|
|
359
|
+
}
|
|
360
|
+
chunks.push(value);
|
|
361
|
+
}
|
|
362
|
+
const bytes = new Uint8Array(size);
|
|
363
|
+
let offset = 0;
|
|
364
|
+
for (const chunk of chunks) {
|
|
365
|
+
bytes.set(chunk, offset);
|
|
366
|
+
offset += chunk.length;
|
|
367
|
+
}
|
|
368
|
+
const body = JSON.parse(new TextDecoder().decode(bytes));
|
|
369
|
+
const e = body && typeof body === 'object' ? body.error : undefined;
|
|
370
|
+
// Only an error envelope: a top-level `code` belongs to an operation receipt, never to a refusal.
|
|
371
|
+
const raw = e && typeof e === 'object' ? e.code : typeof e === 'string' ? e : undefined;
|
|
372
|
+
const code = typeof raw === 'string' && /^[A-Za-z][A-Za-z0-9_.:-]{0,63}$/.test(raw) ? raw : undefined;
|
|
373
|
+
const text = e && typeof e === 'object' ? e.message : undefined;
|
|
374
|
+
const message = code && typeof text === 'string' && text.length <= 300 && !/[\u0000-\u001f\u007f]/.test(text) ? text : undefined;
|
|
375
|
+
const id = (e && typeof e === 'object' ? e.request_id : undefined) ?? body?.request_id;
|
|
376
|
+
return { code, message, requestId: typeof id === 'string' && /^[A-Za-z0-9_.:-]{1,128}$/.test(id) ? id : undefined };
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
return {};
|
|
380
|
+
}
|
|
381
|
+
finally {
|
|
382
|
+
reader.releaseLock();
|
|
383
|
+
}
|
|
384
|
+
}
|
package/dist/errors.js
CHANGED
|
@@ -29,7 +29,7 @@ export class GenesisError extends Error {
|
|
|
29
29
|
(typeof e === 'string' && e) || (typeof body === 'string' && body) || `${res.status} ${res.statusText}`;
|
|
30
30
|
return new GenesisError({
|
|
31
31
|
status: res.status, type, message, code: typeof e === 'object' ? e?.code : undefined,
|
|
32
|
-
requestId: res.headers.get('x-request-id')
|
|
32
|
+
requestId: [typeof e === 'object' ? e?.request_id : undefined, body?.request_id, res.headers.get('x-request-id')].find((v) => typeof v === 'string' && v !== ''),
|
|
33
33
|
operationId, body,
|
|
34
34
|
});
|
|
35
35
|
}
|
package/dist/flares.d.ts
CHANGED
|
@@ -92,6 +92,15 @@ export declare function flaresModule(client: GenesisClient): {
|
|
|
92
92
|
}>;
|
|
93
93
|
};
|
|
94
94
|
presence: {
|
|
95
|
+
list: () => Promise<({
|
|
96
|
+
did?: string;
|
|
97
|
+
status?: string;
|
|
98
|
+
sessionId?: string;
|
|
99
|
+
sessionCount?: number;
|
|
100
|
+
lastSeenAt?: string;
|
|
101
|
+
} & {
|
|
102
|
+
[key: string]: unknown;
|
|
103
|
+
})[]>;
|
|
95
104
|
heartbeat: (body: In<"flares_presenceHeartbeat">["body"], key: string) => Promise<{
|
|
96
105
|
did?: string;
|
|
97
106
|
status?: string;
|
|
@@ -112,6 +121,18 @@ export declare function flaresModule(client: GenesisClient): {
|
|
|
112
121
|
}>;
|
|
113
122
|
};
|
|
114
123
|
trust: {
|
|
124
|
+
list: () => Promise<({
|
|
125
|
+
did?: string;
|
|
126
|
+
score?: number;
|
|
127
|
+
confidence?: number;
|
|
128
|
+
dataPoints?: number;
|
|
129
|
+
computedAt?: string;
|
|
130
|
+
expiresAt?: string;
|
|
131
|
+
trustLevel?: string;
|
|
132
|
+
endorsementCount?: number;
|
|
133
|
+
} & {
|
|
134
|
+
[key: string]: unknown;
|
|
135
|
+
})[]>;
|
|
115
136
|
score: (did: string) => Promise<{
|
|
116
137
|
did?: string;
|
|
117
138
|
score?: number;
|
|
@@ -137,6 +158,17 @@ export declare function flaresModule(client: GenesisClient): {
|
|
|
137
158
|
[key: string]: unknown;
|
|
138
159
|
}>;
|
|
139
160
|
};
|
|
161
|
+
activity: {
|
|
162
|
+
list: (q?: In<"flares_listActivity">) => Promise<({
|
|
163
|
+
id?: string;
|
|
164
|
+
at?: string;
|
|
165
|
+
action?: string;
|
|
166
|
+
resourceId?: string | null;
|
|
167
|
+
actor?: string;
|
|
168
|
+
} & {
|
|
169
|
+
[key: string]: unknown;
|
|
170
|
+
})[]>;
|
|
171
|
+
};
|
|
140
172
|
choreography: {
|
|
141
173
|
workflows: {
|
|
142
174
|
list: () => Promise<{
|
package/dist/flares.js
CHANGED
|
@@ -28,16 +28,21 @@ export function flaresModule(client) {
|
|
|
28
28
|
fail: (id, body, key) => write('flares_failCommitment', { id, body }, key),
|
|
29
29
|
},
|
|
30
30
|
presence: {
|
|
31
|
+
list: () => client.request('flares_listPresence'),
|
|
31
32
|
heartbeat: (body, key) => write('flares_presenceHeartbeat', { body }, key),
|
|
32
33
|
get: (did) => client.request('flares_getPresence', { did }),
|
|
33
34
|
},
|
|
34
35
|
trust: {
|
|
36
|
+
list: () => client.request('flares_listTrust'),
|
|
35
37
|
score: (did) => client.request('flares_getTrustScore', { did }),
|
|
36
38
|
check: (body, key) => write('flares_checkTrust', { body }, key),
|
|
37
39
|
endorsements: (did) => client.request('flares_listEndorsements', { did }),
|
|
38
40
|
endorse: (body, key) => write('flares_createEndorsement', { body }, key),
|
|
39
41
|
revoke: (id, key) => write('flares_revokeEndorsement', { id }, key),
|
|
40
42
|
},
|
|
43
|
+
activity: {
|
|
44
|
+
list: (q = {}) => client.request('flares_listActivity', q),
|
|
45
|
+
},
|
|
41
46
|
choreography: {
|
|
42
47
|
workflows: {
|
|
43
48
|
list: () => client.request('flares_listChoreographyWorkflows'),
|
package/dist/fleets.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ import type { OperationInput } from './types.js';
|
|
|
3
3
|
type TaskInput = NonNullable<OperationInput<'fleets_submitTask'>['body']>;
|
|
4
4
|
type AgentLaunchInput = NonNullable<OperationInput<'fleets_launchAgent'>['body']>;
|
|
5
5
|
type AgentCommandInput = NonNullable<OperationInput<'fleets_commandAgent'>['body']>;
|
|
6
|
+
type AgentUpdateInput = NonNullable<OperationInput<'fleets_updateAgent'>['body']>;
|
|
7
|
+
type AgentLogsQuery = Omit<OperationInput<'fleets_getAgentLogs'>, 'agent_id'>;
|
|
8
|
+
type TaskLogsQuery = Omit<OperationInput<'fleets_getTaskLogs'>, 'task_id'>;
|
|
6
9
|
export interface FleetsInstanceOptions {
|
|
7
10
|
idempotencyKey?: string;
|
|
8
11
|
signal?: AbortSignal;
|
|
@@ -62,6 +65,27 @@ export declare function fleetsModule(client: GenesisClient): {
|
|
|
62
65
|
[key: string]: unknown;
|
|
63
66
|
};
|
|
64
67
|
}>;
|
|
68
|
+
/** Change name, model, instructions or memory. A memory change needs a stopped agent. */
|
|
69
|
+
update: (agent_id: string, body: AgentUpdateInput) => Promise<{
|
|
70
|
+
agent: import("./index.js").components["schemas"]["Fleets.Agent"];
|
|
71
|
+
operation_id: string;
|
|
72
|
+
result?: {
|
|
73
|
+
[key: string]: unknown;
|
|
74
|
+
};
|
|
75
|
+
}>;
|
|
76
|
+
/** Delete a stopped (or recovery_required) idle agent and its log. */
|
|
77
|
+
delete: (agent_id: string) => Promise<{
|
|
78
|
+
id: string;
|
|
79
|
+
deleted: true;
|
|
80
|
+
operation_id: string;
|
|
81
|
+
}>;
|
|
82
|
+
/** Operation log, oldest first; page with after = next_after. */
|
|
83
|
+
logs: (agent_id: string, query?: AgentLogsQuery) => Promise<{
|
|
84
|
+
agent_id: string;
|
|
85
|
+
state: "launching" | "running" | "stopping" | "stopped" | "recovering" | "recovery_required";
|
|
86
|
+
entries: import("./index.js").components["schemas"]["Fleets.AgentLogEntry"][];
|
|
87
|
+
next_after: number | null;
|
|
88
|
+
}>;
|
|
65
89
|
};
|
|
66
90
|
instances: {
|
|
67
91
|
list: (query?: OperationInput<"fleets_listInstances">) => Promise<{
|
|
@@ -181,6 +205,14 @@ export declare function fleetsModule(client: GenesisClient): {
|
|
|
181
205
|
[key: string]: unknown;
|
|
182
206
|
};
|
|
183
207
|
}>;
|
|
208
|
+
/** Lifecycle and output log; poll with after = next_after until complete. */
|
|
209
|
+
logs: (task_id: string, query?: TaskLogsQuery) => Promise<{
|
|
210
|
+
task_id: string;
|
|
211
|
+
state: "pending" | "running" | "cancelling" | "completed" | "failed" | "cancelled" | "timed_out";
|
|
212
|
+
complete: boolean;
|
|
213
|
+
entries: import("./index.js").components["schemas"]["Fleets.TaskLogEntry"][];
|
|
214
|
+
next_after: number | null;
|
|
215
|
+
}>;
|
|
184
216
|
};
|
|
185
217
|
};
|
|
186
218
|
export {};
|
package/dist/fleets.js
CHANGED
|
@@ -46,12 +46,7 @@ function validateAgentLaunch(body) {
|
|
|
46
46
|
if (body.model !== undefined && (!body.model || byteLength(body.model) > 128)) {
|
|
47
47
|
throw invalid('fleets_launchAgent', 'Agent model must contain 1–128 UTF-8 bytes.');
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
if (!['minds', 'files', 'custom'].includes(body.memory.provider))
|
|
51
|
-
throw invalid('fleets_launchAgent', 'Memory provider must be minds, files, or custom.');
|
|
52
|
-
if (body.memory.provider === 'custom' && !body.memory.endpoint)
|
|
53
|
-
throw invalid('fleets_launchAgent', 'Custom memory requires an endpoint.');
|
|
54
|
-
}
|
|
49
|
+
validateMemory('fleets_launchAgent', body.memory);
|
|
55
50
|
if (body.idempotency_key !== undefined && (typeof body.idempotency_key !== 'string' || !/^[!-~]{1,128}$/.test(body.idempotency_key))) {
|
|
56
51
|
throw invalid('fleets_launchAgent', 'Idempotency key must contain 1–128 visible ASCII characters.');
|
|
57
52
|
}
|
|
@@ -61,6 +56,39 @@ function validateAgentCommand(body) {
|
|
|
61
56
|
throw invalid('fleets_commandAgent', 'Agent input must contain 1–65536 UTF-8 bytes without NUL.');
|
|
62
57
|
}
|
|
63
58
|
}
|
|
59
|
+
function validateMemory(operation, memory) {
|
|
60
|
+
if (memory === undefined)
|
|
61
|
+
return;
|
|
62
|
+
if (!memory || !['minds', 'files', 'custom'].includes(memory.provider))
|
|
63
|
+
throw invalid(operation, 'Memory provider must be minds, files, or custom.');
|
|
64
|
+
if (memory.provider === 'custom' && !memory.endpoint)
|
|
65
|
+
throw invalid(operation, 'Custom memory requires an endpoint.');
|
|
66
|
+
}
|
|
67
|
+
function validateAgentUpdate(body) {
|
|
68
|
+
const op = 'fleets_updateAgent';
|
|
69
|
+
if (!body || typeof body !== 'object' || Array.isArray(body))
|
|
70
|
+
throw invalid(op, 'Provide at least one of name, model, instructions or memory.');
|
|
71
|
+
const keys = Object.keys(body);
|
|
72
|
+
if (!keys.length || keys.some(key => !['name', 'model', 'instructions', 'memory'].includes(key))) {
|
|
73
|
+
throw invalid(op, 'Provide at least one of name, model, instructions or memory.');
|
|
74
|
+
}
|
|
75
|
+
if (body.name !== undefined && (typeof body.name !== 'string' || !body.name.trim() || byteLength(body.name) > 128)) {
|
|
76
|
+
throw invalid(op, 'Agent name must contain 1–128 UTF-8 bytes.');
|
|
77
|
+
}
|
|
78
|
+
if (body.model !== undefined && body.model !== null && (typeof body.model !== 'string' || !body.model || byteLength(body.model) > 128)) {
|
|
79
|
+
throw invalid(op, 'Agent model must contain 1–128 UTF-8 bytes, or be null to clear it.');
|
|
80
|
+
}
|
|
81
|
+
if (body.instructions !== undefined && body.instructions !== null
|
|
82
|
+
&& (typeof body.instructions !== 'string' || byteLength(body.instructions) > 65536 || body.instructions.includes('\0'))) {
|
|
83
|
+
throw invalid(op, 'Agent instructions must contain at most 65536 UTF-8 bytes without NUL, or be null to clear them.');
|
|
84
|
+
}
|
|
85
|
+
validateMemory(op, body.memory);
|
|
86
|
+
}
|
|
87
|
+
const cursor = (value, operation, max) => {
|
|
88
|
+
if (value !== undefined && (!Number.isSafeInteger(value) || value < 0 || value > max)) {
|
|
89
|
+
throw invalid(operation, 'after must be a non-negative integer cursor (next_after).');
|
|
90
|
+
}
|
|
91
|
+
};
|
|
64
92
|
/** Managed Henry instances and tasks scoped to the credential's verified org. */
|
|
65
93
|
export function fleetsModule(client) {
|
|
66
94
|
return {
|
|
@@ -87,6 +115,26 @@ export function fleetsModule(client) {
|
|
|
87
115
|
agentId(agent_id, 'fleets_recoverAgent');
|
|
88
116
|
return client.request('fleets_recoverAgent', { agent_id });
|
|
89
117
|
},
|
|
118
|
+
/** Change name, model, instructions or memory. A memory change needs a stopped agent. */
|
|
119
|
+
update: async (agent_id, body) => {
|
|
120
|
+
agentId(agent_id, 'fleets_updateAgent');
|
|
121
|
+
validateAgentUpdate(body);
|
|
122
|
+
return client.request('fleets_updateAgent', { agent_id, body });
|
|
123
|
+
},
|
|
124
|
+
/** Delete a stopped (or recovery_required) idle agent and its log. */
|
|
125
|
+
delete: async (agent_id) => {
|
|
126
|
+
agentId(agent_id, 'fleets_deleteAgent');
|
|
127
|
+
return client.request('fleets_deleteAgent', { agent_id });
|
|
128
|
+
},
|
|
129
|
+
/** Operation log, oldest first; page with after = next_after. */
|
|
130
|
+
logs: async (agent_id, query = {}) => {
|
|
131
|
+
agentId(agent_id, 'fleets_getAgentLogs');
|
|
132
|
+
cursor(query.after, 'fleets_getAgentLogs', Number.MAX_SAFE_INTEGER);
|
|
133
|
+
if (query.limit !== undefined && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200)) {
|
|
134
|
+
throw invalid('fleets_getAgentLogs', 'Limit must be 1–200.');
|
|
135
|
+
}
|
|
136
|
+
return client.request('fleets_getAgentLogs', { agent_id, ...query });
|
|
137
|
+
},
|
|
90
138
|
},
|
|
91
139
|
instances: {
|
|
92
140
|
list: async (query = {}) => {
|
|
@@ -131,6 +179,11 @@ export function fleetsModule(client) {
|
|
|
131
179
|
get: (task_id) => client.request('fleets_getTask', { task_id }),
|
|
132
180
|
cancel: (task_id) => client.request('fleets_cancelTask', { task_id }),
|
|
133
181
|
receipt: (task_id) => client.request('fleets_getTaskReceipt', { task_id }),
|
|
182
|
+
/** Lifecycle and output log; poll with after = next_after until complete. */
|
|
183
|
+
logs: async (task_id, query = {}) => {
|
|
184
|
+
cursor(query.after, 'fleets_getTaskLogs', 4294967295);
|
|
185
|
+
return client.request('fleets_getTaskLogs', { task_id, ...query });
|
|
186
|
+
},
|
|
134
187
|
},
|
|
135
188
|
};
|
|
136
189
|
}
|