@bpmsoftwaresolutions/ai-engine-client 1.1.16 → 1.1.17
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/package.json +1 -1
- package/src/index.js +62 -0
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
const DEFAULT_TIMEOUT_MS = 30000;
|
|
2
|
+
export const AI_ENGINE_CLIENT_VERSION = '1.1.17';
|
|
3
|
+
export const GOVERNED_MUTATION_REQUIRED_CAPABILITIES = [
|
|
4
|
+
'executeVerifiedMutation',
|
|
5
|
+
'post_mutation_verification',
|
|
6
|
+
'acceptance_check_read',
|
|
7
|
+
'artifact_manifest_read',
|
|
8
|
+
'decision_packet_read',
|
|
9
|
+
'claim_signoff',
|
|
10
|
+
];
|
|
11
|
+
export const AI_ENGINE_CLIENT_CAPABILITIES = [
|
|
12
|
+
...GOVERNED_MUTATION_REQUIRED_CAPABILITIES,
|
|
13
|
+
'execution_eligibility_read',
|
|
14
|
+
'workflow_resume_context_read',
|
|
15
|
+
];
|
|
2
16
|
|
|
3
17
|
export const LOGA_CONTRACT = 'ai-engine-ui/v1';
|
|
4
18
|
export const LOGA_INTERACTION_CONTRACT = 'loga-choreography/v1';
|
|
@@ -124,6 +138,13 @@ function buildVerificationError(message, details = {}) {
|
|
|
124
138
|
return error;
|
|
125
139
|
}
|
|
126
140
|
|
|
141
|
+
function buildEligibilityError(message, details = {}) {
|
|
142
|
+
const error = new Error(message);
|
|
143
|
+
error.code = 'EXECUTION_ELIGIBILITY_FAILED';
|
|
144
|
+
error.details = details;
|
|
145
|
+
return error;
|
|
146
|
+
}
|
|
147
|
+
|
|
127
148
|
export class AIEngineClient {
|
|
128
149
|
constructor({ baseUrl, accessToken, tokenProvider, apiKey, clientId, actorId, fetchImpl, timeoutMs } = {}) {
|
|
129
150
|
if (!baseUrl) throw new Error('baseUrl is required.');
|
|
@@ -135,6 +156,8 @@ export class AIEngineClient {
|
|
|
135
156
|
this.actorId = actorId || 'sdk:npm-ai-engine-client';
|
|
136
157
|
this.fetchImpl = fetchImpl || globalThis.fetch;
|
|
137
158
|
this.timeoutMs = timeoutMs || DEFAULT_TIMEOUT_MS;
|
|
159
|
+
this.clientVersion = AI_ENGINE_CLIENT_VERSION;
|
|
160
|
+
this.clientCapabilities = [...AI_ENGINE_CLIENT_CAPABILITIES];
|
|
138
161
|
if (typeof this.fetchImpl !== 'function') {
|
|
139
162
|
throw new Error('A fetch implementation is required. Use Node 18+ or supply fetchImpl.');
|
|
140
163
|
}
|
|
@@ -399,6 +422,17 @@ export class AIEngineClient {
|
|
|
399
422
|
return this._request('/api/governance/claims/claim-work-item', { method: 'POST', body });
|
|
400
423
|
}
|
|
401
424
|
|
|
425
|
+
async getExecutionEligibility(body = {}) {
|
|
426
|
+
return this._request('/api/governance/execution-eligibility', {
|
|
427
|
+
method: 'POST',
|
|
428
|
+
body: {
|
|
429
|
+
required_capabilities: GOVERNED_MUTATION_REQUIRED_CAPABILITIES,
|
|
430
|
+
verification_required: true,
|
|
431
|
+
...body,
|
|
432
|
+
},
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
|
|
402
436
|
async signoffClaim(claimId, body = {}) {
|
|
403
437
|
if (!claimId) throw new Error('claimId is required.');
|
|
404
438
|
return this._request(`/api/governance/claims/${encodeURIComponent(claimId)}/signoff`, {
|
|
@@ -1164,6 +1198,12 @@ export class AIEngineClient {
|
|
|
1164
1198
|
}
|
|
1165
1199
|
|
|
1166
1200
|
async updateImplementationItemStatus(implementationItemId, body) {
|
|
1201
|
+
await this._assertExecutionEligibility({
|
|
1202
|
+
...(body || {}),
|
|
1203
|
+
claimed_item_id: body?.claimed_item_id || implementationItemId,
|
|
1204
|
+
requested_mutation_surface: body?.requested_mutation_surface || 'implementation_packet_item',
|
|
1205
|
+
verification_required: true,
|
|
1206
|
+
});
|
|
1167
1207
|
const result = await this._request(`/api/governed-implementation/items/${implementationItemId}/status`, {
|
|
1168
1208
|
method: 'PATCH', body,
|
|
1169
1209
|
});
|
|
@@ -1217,6 +1257,12 @@ export class AIEngineClient {
|
|
|
1217
1257
|
}
|
|
1218
1258
|
|
|
1219
1259
|
async updateAcceptanceCheckStatus(implementationItemId, acceptanceCheckId, body) {
|
|
1260
|
+
await this._assertExecutionEligibility({
|
|
1261
|
+
...(body || {}),
|
|
1262
|
+
claimed_item_id: body?.claimed_item_id || implementationItemId,
|
|
1263
|
+
requested_mutation_surface: body?.requested_mutation_surface || 'implementation_acceptance_check',
|
|
1264
|
+
verification_required: true,
|
|
1265
|
+
});
|
|
1220
1266
|
return this._request(
|
|
1221
1267
|
`/api/governed-implementation/items/${implementationItemId}/acceptance-checks/${acceptanceCheckId}/status`,
|
|
1222
1268
|
{ method: 'PATCH', body }
|
|
@@ -2035,6 +2081,8 @@ export class AIEngineClient {
|
|
|
2035
2081
|
const resolvedHeaders = {
|
|
2036
2082
|
accept: accept || 'application/json',
|
|
2037
2083
|
'x-actor-id': this.actorId,
|
|
2084
|
+
'x-ai-engine-client-version': this.clientVersion,
|
|
2085
|
+
'x-ai-engine-client-capabilities': this.clientCapabilities.join(','),
|
|
2038
2086
|
...(isJsonBody(body) ? { 'content-type': 'application/json' } : {}),
|
|
2039
2087
|
...(token ? { authorization: `Bearer ${token}` } : {}),
|
|
2040
2088
|
...(!token && this.clientId ? { 'x-client-id': this.clientId } : {}),
|
|
@@ -2047,6 +2095,20 @@ export class AIEngineClient {
|
|
|
2047
2095
|
return resolvedHeaders;
|
|
2048
2096
|
}
|
|
2049
2097
|
|
|
2098
|
+
async _assertExecutionEligibility(body = {}) {
|
|
2099
|
+
const eligibility = await this.getExecutionEligibility(body);
|
|
2100
|
+
if (eligibility?.execution_eligible && eligibility?.mutation_allowed) {
|
|
2101
|
+
return eligibility;
|
|
2102
|
+
}
|
|
2103
|
+
throw buildEligibilityError(
|
|
2104
|
+
`Execution eligibility gate blocked mutation${cleanText(body?.requested_mutation_surface) ? ` on ${cleanText(body.requested_mutation_surface)}` : ''}.`,
|
|
2105
|
+
{
|
|
2106
|
+
required_gate: eligibility?.required_gate || 'execution_eligibility.required_gate',
|
|
2107
|
+
execution_eligibility: eligibility ?? null,
|
|
2108
|
+
},
|
|
2109
|
+
);
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2050
2112
|
async _request(path, { method = 'GET', query, headers, body } = {}) {
|
|
2051
2113
|
const url = appendQuery(`${this.baseUrl}${path}`, query);
|
|
2052
2114
|
const controller = new AbortController();
|