@lifesi/genesis 0.1.1 → 0.1.3
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/dist/beacons.d.ts +46 -0
- package/dist/beacons.js +20 -0
- package/dist/client.d.ts +7669 -1635
- package/dist/client.js +54 -5
- package/dist/dials.d.ts +171 -1
- package/dist/dials.js +40 -0
- package/dist/fleets.d.ts +109 -1
- package/dist/fleets.js +89 -1
- package/dist/flocks.d.ts +73 -0
- package/dist/flocks.js +22 -0
- package/dist/generated/operations.d.ts +7669 -1635
- package/dist/generated/operations.js +9193 -1691
- package/dist/generated/schema.d.ts +16979 -5698
- package/dist/genesis.d.ts +795 -13
- package/dist/genesis.js +21 -0
- package/dist/genesis.openapi.json +23483 -7599
- package/dist/henry.d.ts +7 -0
- package/dist/henry.js +23 -0
- package/dist/hives-cells.d.ts +127 -0
- package/dist/hives-cells.js +151 -0
- package/dist/hives-environment.d.ts +28 -0
- package/dist/hives-environment.js +58 -0
- package/dist/hives-functions.d.ts +1 -1
- package/dist/hives-functions.js +3 -1
- package/dist/hives-marketplace.d.ts +128 -0
- package/dist/hives-marketplace.js +187 -0
- package/dist/hives-node.js +2 -0
- package/dist/hives-operations.d.ts +304 -0
- package/dist/hives-operations.js +39 -0
- package/dist/hives-queues.d.ts +121 -0
- package/dist/hives-queues.js +106 -0
- package/dist/hives-resources-transport.d.ts +18 -0
- package/dist/hives-resources-transport.js +165 -0
- package/dist/hives-runtimes.d.ts +34 -0
- package/dist/hives-runtimes.js +32 -0
- package/dist/hives-volumes.d.ts +64 -0
- package/dist/hives-volumes.js +117 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +3 -0
- package/dist/runner-grant.d.ts +10 -0
- package/dist/runner-grant.js +133 -0
- package/dist/runner.d.ts +16 -0
- package/dist/runner.js +4 -0
- package/package.json +6 -1
package/dist/client.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { isHivesObjectUpload, hivesObjectBody, hivesContentType, isHivesResourceOperation, resourceError } from './hives-resources-transport.js';
|
|
1
2
|
import { operationTable, services } from './generated/operations.js';
|
|
2
3
|
import { GenesisError } from './errors.js';
|
|
3
4
|
import { validateHivesInvocation, hivesFunctionResponseHeaders, hivesFunctionMetadata } from './hives-functions.js';
|
|
5
|
+
import { validateHivesEnvironment, hivesEnvironmentMetadata, hivesEnvironmentReveal } from './hives-environment.js';
|
|
6
|
+
import { RUNNER_SELF_GRANT_OPERATION, snapshotRunnerSelfGrant, runnerGrantResponse, runnerGrantTransportError } from './runner-grant.js';
|
|
4
7
|
export const DEFAULT_BASE_URL = 'https://console.life.one/api';
|
|
5
8
|
const env = globalThis.process?.env ?? {};
|
|
6
9
|
export class GenesisClient {
|
|
@@ -70,6 +73,8 @@ export class GenesisClient {
|
|
|
70
73
|
value = ct.includes('json') ? await res.json() : await res.text();
|
|
71
74
|
}
|
|
72
75
|
catch (error) {
|
|
76
|
+
if (String(operationId).startsWith('hives_') && String(operationId).endsWith('_project_environment'))
|
|
77
|
+
throw new Error('Hives returned invalid environment data.');
|
|
73
78
|
if (String(operationId).startsWith('hives_') && /_functions?$/.test(operationId))
|
|
74
79
|
throw new Error('Hives returned invalid function metadata.');
|
|
75
80
|
throw error;
|
|
@@ -81,21 +86,48 @@ export class GenesisClient {
|
|
|
81
86
|
return { data: value.data.map((row) => hivesFunctionMetadata(row, input?.project_id)), pagination };
|
|
82
87
|
}
|
|
83
88
|
if (['hives_get_function', 'hives_create_function', 'hives_update_function'].includes(operationId)) {
|
|
84
|
-
return hivesFunctionMetadata(value, input?.project_id);
|
|
89
|
+
return hivesFunctionMetadata(value, input?.project_id, operationId === 'hives_create_function' ? undefined : input?.function_id);
|
|
90
|
+
}
|
|
91
|
+
if (operationId === 'hives_list_project_environment' || operationId === 'hives_update_project_environment') {
|
|
92
|
+
return hivesEnvironmentMetadata(value, input?.project_id, operationId === 'hives_update_project_environment');
|
|
93
|
+
}
|
|
94
|
+
if (operationId === 'hives_reveal_project_environment') {
|
|
95
|
+
return hivesEnvironmentReveal(value, input?.key);
|
|
85
96
|
}
|
|
86
97
|
return value;
|
|
87
98
|
}
|
|
88
99
|
/** Raw Response. Completed Hives guest responses retain their actual status, including non-2xx. */
|
|
89
100
|
async raw(operationId, input = {}, init = {}) {
|
|
101
|
+
const runnerGrant = operationId === RUNNER_SELF_GRANT_OPERATION ? snapshotRunnerSelfGrant(input, this.routing) : undefined;
|
|
102
|
+
if (runnerGrant)
|
|
103
|
+
input = { body: runnerGrant };
|
|
90
104
|
const op = operationTable[operationId];
|
|
91
105
|
if (op.rawResponse && op.service === 'hives')
|
|
92
106
|
validateHivesInvocation(input.body);
|
|
107
|
+
const flocksNative = ['flocks_exchangeJoinToken', 'flocks_activateNode', 'flocks_rotateNodeCredential'].includes(operationId);
|
|
108
|
+
if (flocksNative && this.routing === 'direct')
|
|
109
|
+
throw new GenesisError({ status: 0, type: 'invalid_request', message: 'Native Flocks credentials are brokered only through the Genesis gateway.', operationId });
|
|
110
|
+
if (operationId === 'hives_update_project_environment')
|
|
111
|
+
input = { ...input, body: validateHivesEnvironment(input.body) };
|
|
112
|
+
const objectBody = isHivesObjectUpload(operationId) ? await hivesObjectBody(input.body) : undefined;
|
|
93
113
|
const url = this.url(operationId, input);
|
|
94
114
|
const headers = {
|
|
95
115
|
accept: 'application/json',
|
|
96
116
|
'user-agent': this.opts.userAgent ?? '@lifesi/genesis/0.1.0',
|
|
97
117
|
...this.opts.headers, ...init.headers,
|
|
98
118
|
};
|
|
119
|
+
if (runnerGrant) {
|
|
120
|
+
for (const key of Object.keys(headers))
|
|
121
|
+
if (!['accept', 'user-agent'].includes(key.toLowerCase()))
|
|
122
|
+
delete headers[key];
|
|
123
|
+
headers['x-request-id'] = runnerGrant.requestId;
|
|
124
|
+
headers['idempotency-key'] = runnerGrant.operationId;
|
|
125
|
+
}
|
|
126
|
+
if (operationId === 'flocks_exchangeJoinToken') {
|
|
127
|
+
for (const key of Object.keys(headers))
|
|
128
|
+
if (!['accept', 'user-agent'].includes(key.toLowerCase()))
|
|
129
|
+
delete headers[key];
|
|
130
|
+
}
|
|
99
131
|
if (!op.public) {
|
|
100
132
|
const cred = await this.credential();
|
|
101
133
|
// Direct mode: let the upstream decide (some, like Foundry's model list, are public).
|
|
@@ -104,13 +136,21 @@ export class GenesisClient {
|
|
|
104
136
|
if (cred)
|
|
105
137
|
headers.authorization = `Bearer ${cred}`;
|
|
106
138
|
}
|
|
139
|
+
// A timed-out credential provider must not dispatch a later resource mutation.
|
|
140
|
+
if (init.signal?.aborted && isHivesResourceOperation(operationId))
|
|
141
|
+
throw resourceError(0, operationId);
|
|
107
142
|
let body;
|
|
108
143
|
if (op.hasBody && input.body !== undefined) {
|
|
109
144
|
// Fetch owns multipart boundary generation. Never serialize a File/Blob as JSON.
|
|
110
145
|
for (const key of Object.keys(headers))
|
|
111
146
|
if (key.toLowerCase() === 'content-type')
|
|
112
147
|
delete headers[key];
|
|
113
|
-
if (op.requestContentType === '
|
|
148
|
+
if (objectBody !== undefined && op.requestContentType === 'application/octet-stream') {
|
|
149
|
+
headers['content-type'] = hivesContentType(input.content_type);
|
|
150
|
+
headers['content-length'] = String(objectBody.byteLength);
|
|
151
|
+
body = objectBody;
|
|
152
|
+
}
|
|
153
|
+
else if (op.requestContentType === 'multipart/form-data') {
|
|
114
154
|
if (!(input.body instanceof FormData))
|
|
115
155
|
throw new GenesisError({ status: 0, type: 'invalid_request', operationId,
|
|
116
156
|
message: 'This operation requires a FormData body containing a real binary file.' });
|
|
@@ -124,14 +164,17 @@ export class GenesisClient {
|
|
|
124
164
|
body = JSON.stringify(input.body);
|
|
125
165
|
}
|
|
126
166
|
}
|
|
127
|
-
const
|
|
167
|
+
const environmentOperation = op.service === 'hives' && operationId.endsWith('_project_environment');
|
|
168
|
+
const secretOperation = op.service === 'hives' && (/_secrets?$/.test(operationId) || environmentOperation);
|
|
128
169
|
const functionOperation = op.service === 'hives' && (op.rawResponse || /_function(?:s|_async)?$/.test(operationId));
|
|
129
170
|
let res;
|
|
130
171
|
try {
|
|
131
172
|
res = await this.fetchImpl(url, { method: op.method, headers, body, signal: init.signal,
|
|
132
|
-
...(op.service === 'hives' ? { cache: 'no-store', redirect: op.rawResponse ? 'manual' : 'error' } : {}) });
|
|
173
|
+
...(op.service === 'hives' || op.service === 'flocks' || runnerGrant ? { cache: 'no-store', redirect: op.rawResponse && !runnerGrant ? 'manual' : 'error' } : {}) });
|
|
133
174
|
}
|
|
134
175
|
catch (error) {
|
|
176
|
+
if (runnerGrant)
|
|
177
|
+
throw runnerGrantTransportError();
|
|
135
178
|
if (functionOperation)
|
|
136
179
|
throw new GenesisError({ status: 0, type: 'transport_error', operationId,
|
|
137
180
|
message: 'Hives function transport failed. No redirects are followed; check the service address and retry.' });
|
|
@@ -140,6 +183,8 @@ export class GenesisClient {
|
|
|
140
183
|
throw new GenesisError({ status: 0, type: 'transport_error', operationId,
|
|
141
184
|
message: 'Hives secret transport failed. Redirects are refused; check the service address and retry.' });
|
|
142
185
|
}
|
|
186
|
+
if (runnerGrant)
|
|
187
|
+
return runnerGrantResponse(res, runnerGrant);
|
|
143
188
|
if (op.rawResponse && /^exec_[a-f0-9]{32}$/.test(res.headers.get('x-execution-id') ?? '')) {
|
|
144
189
|
return new Response(res.body, { status: res.status, statusText: res.statusText, headers: hivesFunctionResponseHeaders(res.headers) });
|
|
145
190
|
}
|
|
@@ -170,7 +215,11 @@ export class GenesisClient {
|
|
|
170
215
|
: `Hives secret operation failed (${res.status}). Refresh metadata and retry.`;
|
|
171
216
|
// Validation/provider bodies may reflect submitted plaintext. Never retain or log them.
|
|
172
217
|
throw new GenesisError({ status: res.status, type: `http_${res.status}`, message, operationId,
|
|
173
|
-
requestId: res.headers.get('x-request-id') ?? undefined });
|
|
218
|
+
requestId: environmentOperation ? undefined : res.headers.get('x-request-id') ?? undefined });
|
|
219
|
+
}
|
|
220
|
+
if (!res.ok && isHivesResourceOperation(operationId)) {
|
|
221
|
+
await res.body?.cancel().catch(() => { });
|
|
222
|
+
throw resourceError(res.status, operationId);
|
|
174
223
|
}
|
|
175
224
|
if (!res.ok)
|
|
176
225
|
throw await GenesisError.fromResponse(res, operationId);
|
package/dist/dials.d.ts
CHANGED
|
@@ -5,9 +5,151 @@ export type DialsScope = components['schemas']['Dials.Scope'];
|
|
|
5
5
|
export type DialsCallControl = components['schemas']['Dials.CallControl'];
|
|
6
6
|
/** The public call contract requires customer-selected behavior for every caller. */
|
|
7
7
|
export type DialsOutboundCall = components['schemas']['Dials.OutboundCall'];
|
|
8
|
+
export type DialsOutboundCallReceipt = components['schemas']['Dials.OutboundCallReceipt'];
|
|
9
|
+
export type DialsRecoveredOutboundCallReceipt = components['schemas']['Dials.RecoveredOutboundCallReceipt'];
|
|
8
10
|
export type DialsEmergencyAddress = components['schemas']['Dials.RegisterEmergencyAddress'];
|
|
11
|
+
export type DialsCallListItem = components['schemas']['Dials.CallListItem'];
|
|
12
|
+
export type DialsCallDispatchState = components['schemas']['Dials.CallDispatchState'];
|
|
13
|
+
export type DialsMessage = components['schemas']['Dials.MessageEvent'];
|
|
14
|
+
export type DialsMessageTemplate = components['schemas']['Dials.MessageTemplate'];
|
|
15
|
+
export type DialsMessagingBrand = components['schemas']['Dials.MessagingBrand'];
|
|
16
|
+
export type DialsMessagingCampaign = components['schemas']['Dials.MessagingCampaign'];
|
|
17
|
+
export type DialsWorkflowDocument = components['schemas']['Dials.WorkflowDocument'];
|
|
18
|
+
export type DialsRoutingAction = components['schemas']['Dials.RoutingAction'];
|
|
19
|
+
export type DialsRoutingRule = components['schemas']['Dials.RoutingRule'];
|
|
20
|
+
export type DialsRoutingRuleReceipt = components['schemas']['Dials.RoutingRuleReceipt'];
|
|
9
21
|
/** Scope is selection only; the Dials backend verifies its org against signed identity. */
|
|
10
22
|
export declare function dialsModule(client: GenesisClient): {
|
|
23
|
+
routing: {
|
|
24
|
+
list: (scope: DialsScope) => Promise<{
|
|
25
|
+
ok: true;
|
|
26
|
+
scope: components["schemas"]["Dials.Scope"];
|
|
27
|
+
rules: components["schemas"]["Dials.RoutingRule"][];
|
|
28
|
+
}>;
|
|
29
|
+
create: (body: OperationInput<"dials_createRoutingRule">["body"]) => Promise<{
|
|
30
|
+
ok: true;
|
|
31
|
+
rule: components["schemas"]["Dials.RoutingRule"];
|
|
32
|
+
auditId: string;
|
|
33
|
+
idempotentReplay: boolean;
|
|
34
|
+
}>;
|
|
35
|
+
disable: (ruleId: string, body: OperationInput<"dials_disableRoutingRule">["body"]) => Promise<{
|
|
36
|
+
ok: true;
|
|
37
|
+
rule: components["schemas"]["Dials.RoutingRule"];
|
|
38
|
+
auditId: string | null;
|
|
39
|
+
idempotentReplay: boolean;
|
|
40
|
+
}>;
|
|
41
|
+
};
|
|
42
|
+
people: {
|
|
43
|
+
list: (scope: DialsScope) => Promise<{
|
|
44
|
+
ok: boolean;
|
|
45
|
+
humans: components["schemas"]["Dials.HumanProfile"][];
|
|
46
|
+
}>;
|
|
47
|
+
create: (body: OperationInput<"dials_createHumanProfile">["body"]) => Promise<{
|
|
48
|
+
ok: boolean;
|
|
49
|
+
human: components["schemas"]["Dials.HumanProfile"];
|
|
50
|
+
auditId: string;
|
|
51
|
+
usageEventId: string;
|
|
52
|
+
next: string;
|
|
53
|
+
}>;
|
|
54
|
+
};
|
|
55
|
+
agents: {
|
|
56
|
+
list: (scope: DialsScope) => Promise<{
|
|
57
|
+
ok: boolean;
|
|
58
|
+
agents: components["schemas"]["Dials.AgentProfile"][];
|
|
59
|
+
}>;
|
|
60
|
+
create: (body: OperationInput<"dials_createAgent">["body"]) => Promise<{
|
|
61
|
+
ok: boolean;
|
|
62
|
+
agent: components["schemas"]["Dials.AgentProfile"];
|
|
63
|
+
auditId: string;
|
|
64
|
+
usageEventId: string;
|
|
65
|
+
next: string;
|
|
66
|
+
}>;
|
|
67
|
+
};
|
|
68
|
+
voice: {
|
|
69
|
+
list: (scope: DialsScope) => Promise<{
|
|
70
|
+
ok: boolean;
|
|
71
|
+
voiceProfiles: components["schemas"]["Dials.VoiceProfile"][];
|
|
72
|
+
}>;
|
|
73
|
+
create: (body: OperationInput<"dials_createVoiceProfile">["body"]) => Promise<{
|
|
74
|
+
ok: boolean;
|
|
75
|
+
voiceProfile: components["schemas"]["Dials.VoiceProfile"];
|
|
76
|
+
auditId: string;
|
|
77
|
+
usageEventId: string;
|
|
78
|
+
next: string;
|
|
79
|
+
}>;
|
|
80
|
+
};
|
|
81
|
+
messages: {
|
|
82
|
+
list: (scope: DialsScope) => Promise<{
|
|
83
|
+
ok: boolean;
|
|
84
|
+
messages: components["schemas"]["Dials.MessageEvent"][];
|
|
85
|
+
}>;
|
|
86
|
+
send: (body: OperationInput<"dials_createOutboundMessage">["body"]) => Promise<{
|
|
87
|
+
ok: boolean;
|
|
88
|
+
message: components["schemas"]["Dials.MessageEvent"];
|
|
89
|
+
auditId: string;
|
|
90
|
+
usageEventId: string;
|
|
91
|
+
next: string;
|
|
92
|
+
idempotentReplay: boolean;
|
|
93
|
+
}>;
|
|
94
|
+
templates: {
|
|
95
|
+
list: (scope: DialsScope) => Promise<{
|
|
96
|
+
ok: boolean;
|
|
97
|
+
templates: components["schemas"]["Dials.MessageTemplate"][];
|
|
98
|
+
}>;
|
|
99
|
+
create: (body: OperationInput<"dials_createMessageTemplate">["body"]) => Promise<{
|
|
100
|
+
ok: boolean;
|
|
101
|
+
template: components["schemas"]["Dials.MessageTemplate"];
|
|
102
|
+
auditId: string;
|
|
103
|
+
usageEventId: string;
|
|
104
|
+
next: string;
|
|
105
|
+
}>;
|
|
106
|
+
};
|
|
107
|
+
brands: {
|
|
108
|
+
list: (scope: DialsScope) => Promise<{
|
|
109
|
+
ok: boolean;
|
|
110
|
+
brands: components["schemas"]["Dials.MessagingBrand"][];
|
|
111
|
+
}>;
|
|
112
|
+
create: (body: OperationInput<"dials_createMessagingBrand">["body"]) => Promise<{
|
|
113
|
+
ok: boolean;
|
|
114
|
+
brand: components["schemas"]["Dials.MessagingBrand"];
|
|
115
|
+
auditId: string;
|
|
116
|
+
next: string;
|
|
117
|
+
}>;
|
|
118
|
+
};
|
|
119
|
+
campaigns: {
|
|
120
|
+
list: (scope: DialsScope) => Promise<{
|
|
121
|
+
ok: boolean;
|
|
122
|
+
campaigns: components["schemas"]["Dials.MessagingCampaign"][];
|
|
123
|
+
}>;
|
|
124
|
+
create: (body: OperationInput<"dials_createMessagingCampaign">["body"]) => Promise<{
|
|
125
|
+
ok: boolean;
|
|
126
|
+
campaign: components["schemas"]["Dials.MessagingCampaign"];
|
|
127
|
+
auditId: string;
|
|
128
|
+
next: string;
|
|
129
|
+
}>;
|
|
130
|
+
assignNumber: (campaignId: string, body: OperationInput<"dials_assignCampaignNumber">["body"]) => Promise<{
|
|
131
|
+
ok: boolean;
|
|
132
|
+
campaignId: string;
|
|
133
|
+
phoneNumberId: string;
|
|
134
|
+
auditId: string;
|
|
135
|
+
next: string;
|
|
136
|
+
}>;
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
workflows: {
|
|
140
|
+
list: (scope: DialsScope) => Promise<{
|
|
141
|
+
ok: boolean;
|
|
142
|
+
workflows: components["schemas"]["Dials.WorkflowDocument"][];
|
|
143
|
+
}>;
|
|
144
|
+
deploy: (body: OperationInput<"dials_deployWorkflow">["body"]) => Promise<{
|
|
145
|
+
ok: boolean;
|
|
146
|
+
workflow: components["schemas"]["Dials.WorkflowDocument"];
|
|
147
|
+
auditId: string;
|
|
148
|
+
usageEventId: string;
|
|
149
|
+
next: string;
|
|
150
|
+
route: components["schemas"]["Dials.RoutingRule"];
|
|
151
|
+
}>;
|
|
152
|
+
};
|
|
11
153
|
overview: {
|
|
12
154
|
summary: (scope: DialsScope) => Promise<{
|
|
13
155
|
ok: boolean;
|
|
@@ -100,6 +242,13 @@ export declare function dialsModule(client: GenesisClient): {
|
|
|
100
242
|
assign: (body: OperationInput<"dials_assignNumber">["body"]) => Promise<{
|
|
101
243
|
[key: string]: unknown;
|
|
102
244
|
}>;
|
|
245
|
+
delete: (input: OperationInput<"dials_deleteNumber">) => Promise<{
|
|
246
|
+
ok: boolean;
|
|
247
|
+
number: components["schemas"]["Dials.Number"];
|
|
248
|
+
auditId: string;
|
|
249
|
+
usageEventId: string;
|
|
250
|
+
next: string;
|
|
251
|
+
}>;
|
|
103
252
|
release: (body: OperationInput<"dials_releaseNumber">["body"]) => Promise<{
|
|
104
253
|
[key: string]: unknown;
|
|
105
254
|
}>;
|
|
@@ -114,14 +263,35 @@ export declare function dialsModule(client: GenesisClient): {
|
|
|
114
263
|
calls: {
|
|
115
264
|
list: (scope: DialsScope) => Promise<{
|
|
116
265
|
ok: boolean;
|
|
117
|
-
calls: components["schemas"]["Dials.
|
|
266
|
+
calls: components["schemas"]["Dials.CallListItem"][];
|
|
118
267
|
}>;
|
|
119
268
|
validate: (body: DialsOutboundCall) => Promise<{
|
|
120
269
|
[key: string]: unknown;
|
|
121
270
|
}>;
|
|
122
271
|
create: (body: DialsOutboundCall) => Promise<{
|
|
272
|
+
ok: boolean;
|
|
273
|
+
call: components["schemas"]["Dials.CallSession"];
|
|
274
|
+
auditId: string;
|
|
275
|
+
dispatchJobId: string;
|
|
276
|
+
usageEventId: string;
|
|
277
|
+
next: string;
|
|
278
|
+
idempotentReplay: boolean;
|
|
279
|
+
} & {
|
|
123
280
|
[key: string]: unknown;
|
|
124
281
|
}>;
|
|
282
|
+
recover: (body: DialsOutboundCall) => Promise<{
|
|
283
|
+
ok: boolean;
|
|
284
|
+
call: components["schemas"]["Dials.CallSession"];
|
|
285
|
+
auditId: string;
|
|
286
|
+
dispatchJobId: string;
|
|
287
|
+
usageEventId: string;
|
|
288
|
+
next: string;
|
|
289
|
+
idempotentReplay: boolean;
|
|
290
|
+
} & {
|
|
291
|
+
[key: string]: unknown;
|
|
292
|
+
} & {
|
|
293
|
+
idempotentReplay: true;
|
|
294
|
+
}>;
|
|
125
295
|
};
|
|
126
296
|
};
|
|
127
297
|
export type DialsEmergencyAddressFeedback = components['schemas']['Dials.EmergencyAddressFeedback'];
|
package/dist/dials.js
CHANGED
|
@@ -2,6 +2,44 @@ import { GenesisError } from './errors.js';
|
|
|
2
2
|
/** Scope is selection only; the Dials backend verifies its org against signed identity. */
|
|
3
3
|
export function dialsModule(client) {
|
|
4
4
|
return {
|
|
5
|
+
routing: {
|
|
6
|
+
list: (scope) => client.request('dials_listRoutingRules', scope),
|
|
7
|
+
create: (body) => client.request('dials_createRoutingRule', { body }),
|
|
8
|
+
disable: (ruleId, body) => client.request('dials_disableRoutingRule', { rule_id: ruleId, body }),
|
|
9
|
+
},
|
|
10
|
+
people: {
|
|
11
|
+
list: (scope) => client.request('dials_listHumanProfiles', scope),
|
|
12
|
+
create: (body) => client.request('dials_createHumanProfile', { body }),
|
|
13
|
+
},
|
|
14
|
+
agents: {
|
|
15
|
+
list: (scope) => client.request('dials_listAgents', scope),
|
|
16
|
+
create: (body) => client.request('dials_createAgent', { body }),
|
|
17
|
+
},
|
|
18
|
+
voice: {
|
|
19
|
+
list: (scope) => client.request('dials_listVoiceProfiles', scope),
|
|
20
|
+
create: (body) => client.request('dials_createVoiceProfile', { body }),
|
|
21
|
+
},
|
|
22
|
+
messages: {
|
|
23
|
+
list: (scope) => client.request('dials_listMessages', scope),
|
|
24
|
+
send: (body) => client.request('dials_createOutboundMessage', { body }),
|
|
25
|
+
templates: {
|
|
26
|
+
list: (scope) => client.request('dials_listMessageTemplates', scope),
|
|
27
|
+
create: (body) => client.request('dials_createMessageTemplate', { body }),
|
|
28
|
+
},
|
|
29
|
+
brands: {
|
|
30
|
+
list: (scope) => client.request('dials_listMessagingBrands', scope),
|
|
31
|
+
create: (body) => client.request('dials_createMessagingBrand', { body }),
|
|
32
|
+
},
|
|
33
|
+
campaigns: {
|
|
34
|
+
list: (scope) => client.request('dials_listMessagingCampaigns', scope),
|
|
35
|
+
create: (body) => client.request('dials_createMessagingCampaign', { body }),
|
|
36
|
+
assignNumber: (campaignId, body) => client.request('dials_assignCampaignNumber', { campaign_id: campaignId, body }),
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
workflows: {
|
|
40
|
+
list: (scope) => client.request('dials_listWorkflows', scope),
|
|
41
|
+
deploy: (body) => client.request('dials_deployWorkflow', { body }),
|
|
42
|
+
},
|
|
5
43
|
overview: {
|
|
6
44
|
summary: (scope) => client.request('dials_getConsoleSummary', scope),
|
|
7
45
|
operatingSurface: (scope) => client.request('dials_getOperatingSurface', scope),
|
|
@@ -15,6 +53,7 @@ export function dialsModule(client) {
|
|
|
15
53
|
search: (scope, query = {}) => client.request('dials_searchNumbers', { ...query, ...scope }),
|
|
16
54
|
provision: (body) => client.request('dials_provisionNumber', { body }),
|
|
17
55
|
assign: (body) => client.request('dials_assignNumber', { body }),
|
|
56
|
+
delete: (input) => client.request('dials_deleteNumber', input),
|
|
18
57
|
release: (body) => client.request('dials_releaseNumber', { body }),
|
|
19
58
|
registerEmergencyAddress: (body) => client.request('dials_registerEmergencyAddress', { body }),
|
|
20
59
|
},
|
|
@@ -22,6 +61,7 @@ export function dialsModule(client) {
|
|
|
22
61
|
list: (scope) => client.request('dials_listCalls', scope),
|
|
23
62
|
validate: (body) => client.request('dials_validateOutboundCall', { body }),
|
|
24
63
|
create: (body) => client.request('dials_createOutboundCall', { body }),
|
|
64
|
+
recover: (body) => client.request('dials_recoverOutboundCall', { body }),
|
|
25
65
|
},
|
|
26
66
|
};
|
|
27
67
|
}
|
package/dist/fleets.d.ts
CHANGED
|
@@ -1,8 +1,116 @@
|
|
|
1
1
|
import type { GenesisClient } from './client.js';
|
|
2
2
|
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
|
+
type AgentCommandInput = NonNullable<OperationInput<'fleets_commandAgent'>['body']>;
|
|
6
|
+
export interface FleetsInstanceOptions {
|
|
7
|
+
idempotencyKey?: string;
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
}
|
|
10
|
+
/** Managed Henry instances and tasks scoped to the credential's verified org. */
|
|
5
11
|
export declare function fleetsModule(client: GenesisClient): {
|
|
12
|
+
agents: {
|
|
13
|
+
list: () => Promise<{
|
|
14
|
+
agents: import("./index.js").components["schemas"]["Fleets.Agent"][];
|
|
15
|
+
}>;
|
|
16
|
+
launch: (body: AgentLaunchInput) => Promise<{
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
state: "launching" | "running" | "stopping" | "stopped" | "recovering" | "recovery_required";
|
|
20
|
+
memory: import("./index.js").components["schemas"]["Fleets.Memory"];
|
|
21
|
+
model?: string | null;
|
|
22
|
+
inference: {
|
|
23
|
+
provider: "foundry";
|
|
24
|
+
mode: "managed";
|
|
25
|
+
};
|
|
26
|
+
created_at_ms: number;
|
|
27
|
+
updated_at_ms: number;
|
|
28
|
+
last_operation_id?: string | null;
|
|
29
|
+
}>;
|
|
30
|
+
get: (agent_id: string) => Promise<{
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
state: "launching" | "running" | "stopping" | "stopped" | "recovering" | "recovery_required";
|
|
34
|
+
memory: import("./index.js").components["schemas"]["Fleets.Memory"];
|
|
35
|
+
model?: string | null;
|
|
36
|
+
inference: {
|
|
37
|
+
provider: "foundry";
|
|
38
|
+
mode: "managed";
|
|
39
|
+
};
|
|
40
|
+
created_at_ms: number;
|
|
41
|
+
updated_at_ms: number;
|
|
42
|
+
last_operation_id?: string | null;
|
|
43
|
+
}>;
|
|
44
|
+
command: (agent_id: string, body: AgentCommandInput) => Promise<{
|
|
45
|
+
agent: import("./index.js").components["schemas"]["Fleets.Agent"];
|
|
46
|
+
operation_id: string;
|
|
47
|
+
result?: {
|
|
48
|
+
[key: string]: unknown;
|
|
49
|
+
};
|
|
50
|
+
}>;
|
|
51
|
+
stop: (agent_id: string) => Promise<{
|
|
52
|
+
agent: import("./index.js").components["schemas"]["Fleets.Agent"];
|
|
53
|
+
operation_id: string;
|
|
54
|
+
result?: {
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
};
|
|
57
|
+
}>;
|
|
58
|
+
recover: (agent_id: string) => Promise<{
|
|
59
|
+
agent: import("./index.js").components["schemas"]["Fleets.Agent"];
|
|
60
|
+
operation_id: string;
|
|
61
|
+
result?: {
|
|
62
|
+
[key: string]: unknown;
|
|
63
|
+
};
|
|
64
|
+
}>;
|
|
65
|
+
};
|
|
66
|
+
instances: {
|
|
67
|
+
list: (query?: OperationInput<"fleets_listInstances">) => Promise<{
|
|
68
|
+
instances: import("./index.js").components["schemas"]["Fleets.Instance"][];
|
|
69
|
+
next_cursor: string | null;
|
|
70
|
+
}>;
|
|
71
|
+
get: (instance_id: string) => Promise<{
|
|
72
|
+
id: string;
|
|
73
|
+
name: string;
|
|
74
|
+
organization_id: string;
|
|
75
|
+
workspace_id: string;
|
|
76
|
+
project_id: string;
|
|
77
|
+
admission_held: boolean | null;
|
|
78
|
+
physical_state: "created" | "running" | "held" | "stopped" | "recovery_required" | "released";
|
|
79
|
+
status_evidence: "live_controller" | "confirmed_release_receipt";
|
|
80
|
+
release_acknowledged_at_ms: number | null;
|
|
81
|
+
harness_ready: boolean;
|
|
82
|
+
observed_at_ms: number | null;
|
|
83
|
+
lease_expires: {
|
|
84
|
+
wall_ms: number;
|
|
85
|
+
logical: number;
|
|
86
|
+
} | null;
|
|
87
|
+
}>;
|
|
88
|
+
stop: (instance_id: string, options?: FleetsInstanceOptions) => Promise<{
|
|
89
|
+
id: string;
|
|
90
|
+
state: "released";
|
|
91
|
+
reaped: true;
|
|
92
|
+
data_retained: true;
|
|
93
|
+
status_evidence: "confirmed_release_receipt";
|
|
94
|
+
release_acknowledged_at_ms: number;
|
|
95
|
+
}>;
|
|
96
|
+
start: (instance_id: string, options?: FleetsInstanceOptions) => Promise<{
|
|
97
|
+
id: string;
|
|
98
|
+
name: string;
|
|
99
|
+
organization_id: string;
|
|
100
|
+
workspace_id: string;
|
|
101
|
+
project_id: string;
|
|
102
|
+
admission_held: boolean | null;
|
|
103
|
+
physical_state: "created" | "running" | "held" | "stopped" | "recovery_required" | "released";
|
|
104
|
+
status_evidence: "live_controller" | "confirmed_release_receipt";
|
|
105
|
+
release_acknowledged_at_ms: number | null;
|
|
106
|
+
harness_ready: boolean;
|
|
107
|
+
observed_at_ms: number | null;
|
|
108
|
+
lease_expires: {
|
|
109
|
+
wall_ms: number;
|
|
110
|
+
logical: number;
|
|
111
|
+
} | null;
|
|
112
|
+
}>;
|
|
113
|
+
};
|
|
6
114
|
connection: {
|
|
7
115
|
get: () => Promise<{
|
|
8
116
|
connected: boolean;
|
package/dist/fleets.js
CHANGED
|
@@ -3,6 +3,13 @@ const byteLength = (value) => new TextEncoder().encode(value).byteLength;
|
|
|
3
3
|
const invalid = (operationId, message) => new GenesisError({
|
|
4
4
|
status: 0, type: 'invalid_request', operationId, message,
|
|
5
5
|
});
|
|
6
|
+
function instanceOptions(operation, options) {
|
|
7
|
+
const key = options.idempotencyKey;
|
|
8
|
+
if (key !== undefined && (typeof key !== 'string' || !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(key))) {
|
|
9
|
+
throw invalid(operation, 'Idempotency-Key must be one canonical UUID4.');
|
|
10
|
+
}
|
|
11
|
+
return { signal: options.signal, ...(key === undefined ? {} : { headers: { 'idempotency-key': key } }) };
|
|
12
|
+
}
|
|
6
13
|
function validateTask(body) {
|
|
7
14
|
if (typeof body?.input !== 'string' || !body.input || byteLength(body.input) > 65536 || body.input.includes('\0')) {
|
|
8
15
|
throw invalid('fleets_submitTask', 'Task input must contain 1–65536 UTF-8 bytes without NUL.');
|
|
@@ -19,9 +26,90 @@ function validateKey(apiKey) {
|
|
|
19
26
|
throw invalid('fleets_setConnection', 'Foundry key must contain 1–4096 UTF-8 bytes without CR, LF or NUL.');
|
|
20
27
|
}
|
|
21
28
|
}
|
|
22
|
-
|
|
29
|
+
const instanceId = (value, operation) => {
|
|
30
|
+
if (typeof value !== 'string' || !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value)) {
|
|
31
|
+
throw invalid(operation, 'Invalid Fleets instance ID.');
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const agentId = (value, operation) => {
|
|
35
|
+
if (typeof value !== 'string' || !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value)) {
|
|
36
|
+
throw invalid(operation, 'Invalid Fleets agent ID.');
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
function validateAgentLaunch(body) {
|
|
40
|
+
if (!body || typeof body.name !== 'string' || !body.name.trim() || byteLength(body.name) > 128) {
|
|
41
|
+
throw invalid('fleets_launchAgent', 'Agent name must contain 1–128 UTF-8 bytes.');
|
|
42
|
+
}
|
|
43
|
+
if (body.instructions !== undefined && (byteLength(body.instructions) > 65536 || body.instructions.includes('\0'))) {
|
|
44
|
+
throw invalid('fleets_launchAgent', 'Agent instructions must contain at most 65536 UTF-8 bytes without NUL.');
|
|
45
|
+
}
|
|
46
|
+
if (body.model !== undefined && (!body.model || byteLength(body.model) > 128)) {
|
|
47
|
+
throw invalid('fleets_launchAgent', 'Agent model must contain 1–128 UTF-8 bytes.');
|
|
48
|
+
}
|
|
49
|
+
if (body.memory !== undefined) {
|
|
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
|
+
}
|
|
55
|
+
if (body.idempotency_key !== undefined && (typeof body.idempotency_key !== 'string' || !/^[!-~]{1,128}$/.test(body.idempotency_key))) {
|
|
56
|
+
throw invalid('fleets_launchAgent', 'Idempotency key must contain 1–128 visible ASCII characters.');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function validateAgentCommand(body) {
|
|
60
|
+
if (!body || typeof body.input !== 'string' || !body.input.trim() || byteLength(body.input) > 65536 || body.input.includes('\0')) {
|
|
61
|
+
throw invalid('fleets_commandAgent', 'Agent input must contain 1–65536 UTF-8 bytes without NUL.');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Managed Henry instances and tasks scoped to the credential's verified org. */
|
|
23
65
|
export function fleetsModule(client) {
|
|
24
66
|
return {
|
|
67
|
+
agents: {
|
|
68
|
+
list: () => client.request('fleets_listAgents'),
|
|
69
|
+
launch: async (body) => {
|
|
70
|
+
validateAgentLaunch(body);
|
|
71
|
+
return client.request('fleets_launchAgent', { body });
|
|
72
|
+
},
|
|
73
|
+
get: async (agent_id) => {
|
|
74
|
+
agentId(agent_id, 'fleets_getAgent');
|
|
75
|
+
return client.request('fleets_getAgent', { agent_id });
|
|
76
|
+
},
|
|
77
|
+
command: async (agent_id, body) => {
|
|
78
|
+
agentId(agent_id, 'fleets_commandAgent');
|
|
79
|
+
validateAgentCommand(body);
|
|
80
|
+
return client.request('fleets_commandAgent', { agent_id, body });
|
|
81
|
+
},
|
|
82
|
+
stop: async (agent_id) => {
|
|
83
|
+
agentId(agent_id, 'fleets_stopAgent');
|
|
84
|
+
return client.request('fleets_stopAgent', { agent_id });
|
|
85
|
+
},
|
|
86
|
+
recover: async (agent_id) => {
|
|
87
|
+
agentId(agent_id, 'fleets_recoverAgent');
|
|
88
|
+
return client.request('fleets_recoverAgent', { agent_id });
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
instances: {
|
|
92
|
+
list: async (query = {}) => {
|
|
93
|
+
if (query.limit !== undefined && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 50)) {
|
|
94
|
+
throw invalid('fleets_listInstances', 'Limit must be 1–50.');
|
|
95
|
+
}
|
|
96
|
+
if (query.after !== undefined)
|
|
97
|
+
instanceId(query.after, 'fleets_listInstances');
|
|
98
|
+
return client.request('fleets_listInstances', query);
|
|
99
|
+
},
|
|
100
|
+
get: async (instance_id) => {
|
|
101
|
+
instanceId(instance_id, 'fleets_getInstance');
|
|
102
|
+
return client.request('fleets_getInstance', { instance_id });
|
|
103
|
+
},
|
|
104
|
+
stop: async (instance_id, options = {}) => {
|
|
105
|
+
instanceId(instance_id, 'fleets_stopInstance');
|
|
106
|
+
return client.request('fleets_stopInstance', { instance_id }, instanceOptions('fleets_stopInstance', options));
|
|
107
|
+
},
|
|
108
|
+
start: async (instance_id, options = {}) => {
|
|
109
|
+
instanceId(instance_id, 'fleets_startInstance');
|
|
110
|
+
return client.request('fleets_startInstance', { instance_id }, instanceOptions('fleets_startInstance', options));
|
|
111
|
+
},
|
|
112
|
+
},
|
|
25
113
|
connection: {
|
|
26
114
|
get: () => client.request('fleets_getConnection', {}),
|
|
27
115
|
set: async (api_key) => {
|