@bpmsoftwaresolutions/ai-engine-client 1.1.29 → 1.1.31
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 +171 -2
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const DEFAULT_TIMEOUT_MS = 30000;
|
|
2
|
-
export const AI_ENGINE_CLIENT_VERSION = '1.1.
|
|
2
|
+
export const AI_ENGINE_CLIENT_VERSION = '1.1.31';
|
|
3
3
|
export const GOVERNED_MUTATION_REQUIRED_CAPABILITIES = [
|
|
4
4
|
'executeVerifiedMutation',
|
|
5
5
|
'post_mutation_verification',
|
|
@@ -113,10 +113,60 @@ function cleanText(value) {
|
|
|
113
113
|
return text || null;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
function cleanList(value) {
|
|
117
|
+
if (!Array.isArray(value)) return [];
|
|
118
|
+
return value.map((item) => cleanText(item)).filter(Boolean);
|
|
119
|
+
}
|
|
120
|
+
|
|
116
121
|
function isPlainObject(value) {
|
|
117
122
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
118
123
|
}
|
|
119
124
|
|
|
125
|
+
function isActiveBinding(binding) {
|
|
126
|
+
return isPlainObject(binding) && (
|
|
127
|
+
binding.is_active === true ||
|
|
128
|
+
binding.is_active === 1 ||
|
|
129
|
+
binding.is_active === 'true' ||
|
|
130
|
+
binding.is_active === 'True'
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function activeToolKeysFromRegistry(registry) {
|
|
135
|
+
const bindings = Array.isArray(registry?.bindings) ? registry.bindings : [];
|
|
136
|
+
const seen = new Set();
|
|
137
|
+
const keys = [];
|
|
138
|
+
for (const binding of bindings) {
|
|
139
|
+
if (!isActiveBinding(binding)) continue;
|
|
140
|
+
const key = cleanText(binding.tool_key);
|
|
141
|
+
if (!key || seen.has(key)) continue;
|
|
142
|
+
seen.add(key);
|
|
143
|
+
keys.push(key);
|
|
144
|
+
}
|
|
145
|
+
return keys;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function reminderTokens(reminders) {
|
|
149
|
+
const tokens = [];
|
|
150
|
+
for (const reminder of Array.isArray(reminders) ? reminders : []) {
|
|
151
|
+
if (!isPlainObject(reminder)) continue;
|
|
152
|
+
for (const value of [reminder.reminder_key, reminder.reminder_id]) {
|
|
153
|
+
const token = cleanText(value);
|
|
154
|
+
if (token && !tokens.includes(token)) tokens.push(token);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return tokens;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function contextSessionIdFromInput(input) {
|
|
161
|
+
if (isPlainObject(input)) {
|
|
162
|
+
return cleanText(input.contextSessionId)
|
|
163
|
+
|| cleanText(input.context_session_id)
|
|
164
|
+
|| cleanText(input.context_session?.context_session_id)
|
|
165
|
+
|| cleanText(input.claim?.context_session_id);
|
|
166
|
+
}
|
|
167
|
+
return cleanText(input);
|
|
168
|
+
}
|
|
169
|
+
|
|
120
170
|
function matchesExpectedState(actual, expected) {
|
|
121
171
|
if (typeof expected === 'function') {
|
|
122
172
|
throw new Error('matchesExpectedState does not support function expectations.');
|
|
@@ -456,6 +506,115 @@ export class AIEngineClient {
|
|
|
456
506
|
return this._request('/api/governance/claims/claim-work-item', { method: 'POST', body });
|
|
457
507
|
}
|
|
458
508
|
|
|
509
|
+
async bindClaimedWorkItem({
|
|
510
|
+
claimId,
|
|
511
|
+
contextSessionId,
|
|
512
|
+
workflowRunId,
|
|
513
|
+
agentSessionId,
|
|
514
|
+
claimedItemId,
|
|
515
|
+
claimedItemKey,
|
|
516
|
+
claimName,
|
|
517
|
+
actorId,
|
|
518
|
+
workflowId,
|
|
519
|
+
workflowSlug,
|
|
520
|
+
requiredToolKeys,
|
|
521
|
+
declaredScopeFiles,
|
|
522
|
+
allowedMutationSurfaces,
|
|
523
|
+
successCriteria,
|
|
524
|
+
acknowledgedReminders,
|
|
525
|
+
intentConfirmation,
|
|
526
|
+
actorSignature,
|
|
527
|
+
autoSignoff = true,
|
|
528
|
+
metadata,
|
|
529
|
+
} = {}) {
|
|
530
|
+
const normalizedContextSessionId = contextSessionIdFromInput({
|
|
531
|
+
contextSessionId,
|
|
532
|
+
context_session_id: contextSessionId,
|
|
533
|
+
claim: { context_session_id: contextSessionId },
|
|
534
|
+
});
|
|
535
|
+
const normalizedClaimId = cleanText(claimId);
|
|
536
|
+
const normalizedWorkflowRunId = cleanText(workflowRunId);
|
|
537
|
+
const normalizedAgentSessionId = cleanText(agentSessionId);
|
|
538
|
+
const normalizedClaimedItemId = cleanText(claimedItemId);
|
|
539
|
+
const normalizedClaimedItemKey = cleanText(claimedItemKey);
|
|
540
|
+
const normalizedClaimedItemRef = normalizedClaimedItemId || normalizedClaimedItemKey;
|
|
541
|
+
if (!normalizedContextSessionId) throw new Error('contextSessionId is required.');
|
|
542
|
+
if (!normalizedWorkflowRunId) throw new Error('workflowRunId is required.');
|
|
543
|
+
if (!normalizedAgentSessionId) throw new Error('agentSessionId is required.');
|
|
544
|
+
if (!normalizedClaimedItemRef) throw new Error('claimedItemId or claimedItemKey is required.');
|
|
545
|
+
|
|
546
|
+
const normalizedWorkflowId = cleanText(workflowId);
|
|
547
|
+
const normalizedWorkflowSlug = cleanText(workflowSlug);
|
|
548
|
+
let normalizedRequiredToolKeys = cleanList(requiredToolKeys);
|
|
549
|
+
let workflowRegistry = null;
|
|
550
|
+
if (normalizedRequiredToolKeys.length === 0 && (normalizedWorkflowId || normalizedWorkflowSlug)) {
|
|
551
|
+
workflowRegistry = await this.getWorkflowToolRegistry({
|
|
552
|
+
workflowId: normalizedWorkflowId,
|
|
553
|
+
workflowSlug: normalizedWorkflowSlug,
|
|
554
|
+
});
|
|
555
|
+
normalizedRequiredToolKeys = activeToolKeysFromRegistry(workflowRegistry);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
const lockClaimResult = await this.lockContextSessionClaim(normalizedContextSessionId);
|
|
559
|
+
const lockedContextSession = lockClaimResult?.context_session || lockClaimResult;
|
|
560
|
+
const lockedContextSessionId = contextSessionIdFromInput(lockedContextSession) || normalizedContextSessionId;
|
|
561
|
+
|
|
562
|
+
const claimWorkItemResult = await this.claimWorkItem({
|
|
563
|
+
context_session_id: lockedContextSessionId,
|
|
564
|
+
workflow_run_id: normalizedWorkflowRunId,
|
|
565
|
+
agent_session_id: normalizedAgentSessionId,
|
|
566
|
+
claimed_item_id: normalizedClaimedItemId,
|
|
567
|
+
claimed_item_key: normalizedClaimedItemKey,
|
|
568
|
+
claim_name: claimName,
|
|
569
|
+
actor_id: actorId,
|
|
570
|
+
workflow_id: normalizedWorkflowId,
|
|
571
|
+
workflow_slug: normalizedWorkflowSlug,
|
|
572
|
+
required_tool_keys: normalizedRequiredToolKeys,
|
|
573
|
+
declared_scope_files: cleanList(declaredScopeFiles).length > 0
|
|
574
|
+
? cleanList(declaredScopeFiles)
|
|
575
|
+
: [normalizedClaimedItemRef],
|
|
576
|
+
allowed_mutation_surfaces: cleanList(allowedMutationSurfaces).length > 0
|
|
577
|
+
? cleanList(allowedMutationSurfaces)
|
|
578
|
+
: ['project_roadmap_task'],
|
|
579
|
+
success_criteria: successCriteria,
|
|
580
|
+
metadata,
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
let signedClaim = null;
|
|
584
|
+
const resolvedClaimId = cleanText(claimWorkItemResult?.claim_id) || normalizedClaimId;
|
|
585
|
+
if (autoSignoff && resolvedClaimId) {
|
|
586
|
+
const claimEnvelope = isPlainObject(claimWorkItemResult?.claim) ? claimWorkItemResult.claim : claimWorkItemResult;
|
|
587
|
+
const reminders = cleanList(acknowledgedReminders).length > 0
|
|
588
|
+
? cleanList(acknowledgedReminders)
|
|
589
|
+
: reminderTokens(claimEnvelope?.required_reminders);
|
|
590
|
+
if (reminders.length > 0) {
|
|
591
|
+
signedClaim = await this.signoffClaim(resolvedClaimId, {
|
|
592
|
+
acknowledged_reminders: reminders,
|
|
593
|
+
intent_confirmation: cleanText(intentConfirmation) || 'I confirm this governed execution intent and scope.',
|
|
594
|
+
actor_signature: cleanText(actorSignature) || cleanText(actorId) || this.actorId,
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
return {
|
|
600
|
+
claim_id: resolvedClaimId,
|
|
601
|
+
context_session_id: lockedContextSessionId,
|
|
602
|
+
workflow_run_id: normalizedWorkflowRunId,
|
|
603
|
+
agent_session_id: normalizedAgentSessionId,
|
|
604
|
+
required_tool_keys: normalizedRequiredToolKeys,
|
|
605
|
+
workflow_registry: workflowRegistry,
|
|
606
|
+
lock_claim_result: lockClaimResult,
|
|
607
|
+
claim_work_item_result: claimWorkItemResult,
|
|
608
|
+
signed_claim: signedClaim,
|
|
609
|
+
approved_tool_keys: cleanList(
|
|
610
|
+
signedClaim?.approved_tool_keys ||
|
|
611
|
+
signedClaim?.claim?.approved_tool_keys ||
|
|
612
|
+
claimWorkItemResult?.approved_tool_keys ||
|
|
613
|
+
claimWorkItemResult?.claim?.approved_tool_keys
|
|
614
|
+
),
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
|
|
459
618
|
async getClaim(claimId) {
|
|
460
619
|
if (!claimId) throw new Error('claimId is required.');
|
|
461
620
|
return this._request(`/api/governance/claims/${encodeURIComponent(claimId)}`);
|
|
@@ -712,6 +871,14 @@ export class AIEngineClient {
|
|
|
712
871
|
});
|
|
713
872
|
}
|
|
714
873
|
|
|
874
|
+
async routeImplementationItem(implementationItemId, body = {}) {
|
|
875
|
+
if (!implementationItemId) throw new Error('implementationItemId is required.');
|
|
876
|
+
return this._request(`/api/governed-implementation/items/${encodeURIComponent(implementationItemId)}/routing`, {
|
|
877
|
+
method: 'PATCH',
|
|
878
|
+
body,
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
|
|
715
882
|
async persistAssistantTurn(body) {
|
|
716
883
|
return this._request('/api/v1/assistant-turns', { method: 'POST', body });
|
|
717
884
|
}
|
|
@@ -2348,7 +2515,9 @@ export class AIEngineClient {
|
|
|
2348
2515
|
});
|
|
2349
2516
|
}
|
|
2350
2517
|
|
|
2351
|
-
async lockContextSessionClaim(
|
|
2518
|
+
async lockContextSessionClaim(input) {
|
|
2519
|
+
const contextSessionId = contextSessionIdFromInput(input);
|
|
2520
|
+
if (!contextSessionId) throw new Error('contextSessionId is required.');
|
|
2352
2521
|
return this._request(`/api/context-session/${encodeURIComponent(contextSessionId)}/lock-claim`, {
|
|
2353
2522
|
method: 'POST',
|
|
2354
2523
|
});
|