@bpmsoftwaresolutions/ai-engine-client 1.1.88 → 1.1.89
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/client.js +70 -535
- package/src/domains/charters.js +5 -0
- package/src/domains/claims.js +58 -0
- package/src/domains/commit-governance.js +68 -0
- package/src/domains/context-orientation.js +48 -0
- package/src/domains/context-sessions.js +46 -0
- package/src/domains/execution-eligibility.js +44 -0
- package/src/domains/governed-implementation.js +7 -0
- package/src/domains/session-governance.js +64 -0
- package/src/domains/tool-binding-approvals.js +102 -0
- package/src/domains/verified-mutations.js +7 -0
- package/src/domains/work-start.js +192 -0
- package/src/domains/workflow-turns.js +6 -0
- package/src/index.js +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { cleanText } from '../utils/text.js';
|
|
2
|
+
|
|
3
|
+
export function createClaimsDomain(client) {
|
|
4
|
+
return {
|
|
5
|
+
getClaim: (claimId) => {
|
|
6
|
+
if (!claimId) throw new Error('claimId is required.');
|
|
7
|
+
return client._request(`/api/governance/claims/${encodeURIComponent(claimId)}`);
|
|
8
|
+
},
|
|
9
|
+
claimIsValid: async (claimId) => {
|
|
10
|
+
const claim = await client.getClaim(claimId);
|
|
11
|
+
return cleanText(claim?.status) === 'active';
|
|
12
|
+
},
|
|
13
|
+
signoffClaim: (claimId, body = {}) => {
|
|
14
|
+
if (!claimId) throw new Error('claimId is required.');
|
|
15
|
+
return client._request(`/api/governance/claims/${encodeURIComponent(claimId)}/signoff`, {
|
|
16
|
+
method: 'POST',
|
|
17
|
+
body,
|
|
18
|
+
});
|
|
19
|
+
},
|
|
20
|
+
promoteClaimSurface: ({
|
|
21
|
+
claimId,
|
|
22
|
+
workflowId,
|
|
23
|
+
contextSessionId,
|
|
24
|
+
actorId,
|
|
25
|
+
requiredToolKeys,
|
|
26
|
+
intentId,
|
|
27
|
+
bindingScope,
|
|
28
|
+
usageMode,
|
|
29
|
+
operatorScope,
|
|
30
|
+
allowedArgumentPolicy,
|
|
31
|
+
...rest
|
|
32
|
+
} = {}) => {
|
|
33
|
+
if (!claimId) throw new Error('claimId is required.');
|
|
34
|
+
if (!workflowId) throw new Error('workflowId is required.');
|
|
35
|
+
if (!contextSessionId) throw new Error('contextSessionId is required.');
|
|
36
|
+
if (!actorId) throw new Error('actorId is required.');
|
|
37
|
+
if (!Array.isArray(requiredToolKeys) || requiredToolKeys.length === 0) {
|
|
38
|
+
throw new Error('requiredToolKeys must be a non-empty array.');
|
|
39
|
+
}
|
|
40
|
+
return client._request('/api/governance/claims/promote-surface', {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
body: {
|
|
43
|
+
...rest,
|
|
44
|
+
claim_id: claimId,
|
|
45
|
+
workflow_id: workflowId,
|
|
46
|
+
context_session_id: contextSessionId,
|
|
47
|
+
actor_id: actorId,
|
|
48
|
+
required_tool_keys: requiredToolKeys,
|
|
49
|
+
intent_id: intentId,
|
|
50
|
+
binding_scope: bindingScope,
|
|
51
|
+
usage_mode: usageMode,
|
|
52
|
+
operator_scope: operatorScope,
|
|
53
|
+
allowed_argument_policy: allowedArgumentPolicy,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export function createCommitGovernanceDomain(client) {
|
|
2
|
+
return {
|
|
3
|
+
evaluateCommitGovernance: ({
|
|
4
|
+
claimId,
|
|
5
|
+
contextSessionId,
|
|
6
|
+
agentId,
|
|
7
|
+
intentId,
|
|
8
|
+
changedFiles,
|
|
9
|
+
declaredScopeFiles,
|
|
10
|
+
diffSummary,
|
|
11
|
+
branch,
|
|
12
|
+
headSha,
|
|
13
|
+
} = {}) => client._request('/api/commit-governance/evaluate', {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
body: {
|
|
16
|
+
claim_id: claimId,
|
|
17
|
+
context_session_id: contextSessionId,
|
|
18
|
+
agent_id: agentId,
|
|
19
|
+
intent_id: intentId,
|
|
20
|
+
changed_files: changedFiles,
|
|
21
|
+
declared_scope_files: declaredScopeFiles,
|
|
22
|
+
diff_summary: diffSummary,
|
|
23
|
+
branch,
|
|
24
|
+
head_sha: headSha,
|
|
25
|
+
},
|
|
26
|
+
}),
|
|
27
|
+
checkGitShipReadiness: ({
|
|
28
|
+
claimId,
|
|
29
|
+
actorId,
|
|
30
|
+
targetBranch,
|
|
31
|
+
shipCommand,
|
|
32
|
+
packageName,
|
|
33
|
+
declaredScopeFiles,
|
|
34
|
+
stagedFiles,
|
|
35
|
+
dirtyFiles,
|
|
36
|
+
branch,
|
|
37
|
+
headSha,
|
|
38
|
+
packageJsonVersion,
|
|
39
|
+
facadeMinClientVersion,
|
|
40
|
+
packageRelease,
|
|
41
|
+
packageJsonHash,
|
|
42
|
+
sdkVersionHash,
|
|
43
|
+
} = {}) => client._request('/api/commit-governance/ship-readiness', {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
body: {
|
|
46
|
+
claim_id: claimId,
|
|
47
|
+
actor_id: actorId,
|
|
48
|
+
target_branch: targetBranch,
|
|
49
|
+
ship_command: shipCommand,
|
|
50
|
+
package_name: packageName,
|
|
51
|
+
declared_scope_files: declaredScopeFiles,
|
|
52
|
+
staged_files: stagedFiles,
|
|
53
|
+
dirty_files: dirtyFiles,
|
|
54
|
+
branch,
|
|
55
|
+
head_sha: headSha,
|
|
56
|
+
package_json_version: packageJsonVersion,
|
|
57
|
+
facade_min_client_version: facadeMinClientVersion,
|
|
58
|
+
package_release: packageRelease,
|
|
59
|
+
package_json_hash: packageJsonHash,
|
|
60
|
+
sdk_version_hash: sdkVersionHash,
|
|
61
|
+
},
|
|
62
|
+
}),
|
|
63
|
+
getCommitGovernanceEvaluation: (evaluationId) => client._request(`/api/commit-governance/evaluations/${encodeURIComponent(evaluationId)}`),
|
|
64
|
+
listCommitGovernanceEvaluationsByClaim: (claimId, { limit } = {}) => client._request(`/api/commit-governance/claims/${encodeURIComponent(claimId)}/evaluations`, {
|
|
65
|
+
query: { limit },
|
|
66
|
+
}),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export function createContextOrientationDomain(client) {
|
|
2
|
+
return {
|
|
3
|
+
conductOrientation: async ({
|
|
4
|
+
agentId,
|
|
5
|
+
runtimeSessionId,
|
|
6
|
+
intentId,
|
|
7
|
+
executionPurpose,
|
|
8
|
+
agentSignature,
|
|
9
|
+
understandingSummary,
|
|
10
|
+
lockClaim = true,
|
|
11
|
+
} = {}) => {
|
|
12
|
+
const { context_session, reminders } = await client.contextSessions.openContextSession({
|
|
13
|
+
agentId,
|
|
14
|
+
runtimeSessionId,
|
|
15
|
+
intentId,
|
|
16
|
+
executionPurpose,
|
|
17
|
+
});
|
|
18
|
+
const sessionId = context_session.context_session_id;
|
|
19
|
+
|
|
20
|
+
const required = (reminders || []).filter((reminder) => reminder.severity === 'required');
|
|
21
|
+
let acknowledgedCount = 0;
|
|
22
|
+
for (const reminder of required) {
|
|
23
|
+
await client.contextSessions.acknowledgeReminder(sessionId, {
|
|
24
|
+
reminderId: reminder.reminder_id,
|
|
25
|
+
agentSignature,
|
|
26
|
+
understandingSummary,
|
|
27
|
+
});
|
|
28
|
+
acknowledgedCount++;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const completion = await client.contextSessions.completeOrientation(sessionId);
|
|
32
|
+
|
|
33
|
+
let claimLockResult = null;
|
|
34
|
+
if (lockClaim) {
|
|
35
|
+
claimLockResult = await client.contextSessions.lockContextSessionClaim(sessionId);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
context_session_id: sessionId,
|
|
40
|
+
intent_id: intentId,
|
|
41
|
+
context_session: claimLockResult?.context_session || completion.context_session,
|
|
42
|
+
gate_result: claimLockResult?.gate_result || completion.gate_result,
|
|
43
|
+
acknowledged_count: acknowledgedCount,
|
|
44
|
+
claim_locked: lockClaim && !!claimLockResult,
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { cleanText } from '../utils/text.js';
|
|
2
|
+
|
|
3
|
+
export function contextSessionIdFromInput(input) {
|
|
4
|
+
if (input !== null && typeof input === 'object' && !Array.isArray(input)) {
|
|
5
|
+
return cleanText(input.contextSessionId)
|
|
6
|
+
|| cleanText(input.context_session_id)
|
|
7
|
+
|| cleanText(input.context_session?.context_session_id)
|
|
8
|
+
|| cleanText(input.claim?.context_session_id);
|
|
9
|
+
}
|
|
10
|
+
return cleanText(input);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function createContextSessionsDomain(client) {
|
|
14
|
+
return {
|
|
15
|
+
openContextSession: ({ agentId, runtimeSessionId, intentId, executionPurpose, notes } = {}) => client._request('/api/context-session/open', {
|
|
16
|
+
method: 'POST',
|
|
17
|
+
body: {
|
|
18
|
+
agent_id: agentId,
|
|
19
|
+
runtime_session_id: runtimeSessionId,
|
|
20
|
+
intent_id: intentId,
|
|
21
|
+
execution_purpose: executionPurpose,
|
|
22
|
+
notes,
|
|
23
|
+
},
|
|
24
|
+
}),
|
|
25
|
+
getOrientationWindow: (contextSessionId) => client._request(`/api/context-session/${encodeURIComponent(contextSessionId)}/window`),
|
|
26
|
+
acknowledgeReminder: (contextSessionId, { reminderId, agentSignature, understandingSummary } = {}) => client._request(`/api/context-session/${encodeURIComponent(contextSessionId)}/acknowledge`, {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
body: {
|
|
29
|
+
reminder_id: reminderId,
|
|
30
|
+
agent_signature: agentSignature,
|
|
31
|
+
understanding_summary: understandingSummary,
|
|
32
|
+
},
|
|
33
|
+
}),
|
|
34
|
+
completeOrientation: (contextSessionId) => client._request(`/api/context-session/${encodeURIComponent(contextSessionId)}/complete`, {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
}),
|
|
37
|
+
lockContextSessionClaim: (input) => {
|
|
38
|
+
const contextSessionId = contextSessionIdFromInput(input);
|
|
39
|
+
if (!contextSessionId) throw new Error('contextSessionId is required.');
|
|
40
|
+
return client._request(`/api/context-session/${encodeURIComponent(contextSessionId)}/lock-claim`, {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
getContextSessionGateStatus: (contextSessionId) => client._request(`/api/context-session/${encodeURIComponent(contextSessionId)}/gate-status`),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { cleanText } from '../utils/text.js';
|
|
2
|
+
import { GOVERNED_MUTATION_REQUIRED_CAPABILITIES } from '../constants/governance.js';
|
|
3
|
+
|
|
4
|
+
export function buildEligibilityError(message, details = {}) {
|
|
5
|
+
const error = new Error(message);
|
|
6
|
+
error.code = 'EXECUTION_ELIGIBILITY_FAILED';
|
|
7
|
+
error.details = details;
|
|
8
|
+
return error;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function createExecutionEligibilityDomain(client) {
|
|
12
|
+
return {
|
|
13
|
+
getExecutionEligibility: (body = {}) => client._request('/api/governance/execution-eligibility', {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
body: {
|
|
16
|
+
required_capabilities: GOVERNED_MUTATION_REQUIRED_CAPABILITIES,
|
|
17
|
+
verification_required: true,
|
|
18
|
+
...body,
|
|
19
|
+
},
|
|
20
|
+
}),
|
|
21
|
+
_assertExecutionEligibility: async (body = {}) => {
|
|
22
|
+
const eligibility = await client.getExecutionEligibility(body);
|
|
23
|
+
if (eligibility?.execution_eligible && eligibility?.mutation_allowed) {
|
|
24
|
+
return eligibility;
|
|
25
|
+
}
|
|
26
|
+
const remediation = cleanText(eligibility?.remediation_command);
|
|
27
|
+
const verification = cleanText(eligibility?.verification_command);
|
|
28
|
+
throw buildEligibilityError(
|
|
29
|
+
[
|
|
30
|
+
`Execution eligibility gate blocked mutation${cleanText(body?.requested_mutation_surface) ? ` on ${cleanText(body.requested_mutation_surface)}` : ''}.`,
|
|
31
|
+
remediation ? `Fix: ${remediation}` : null,
|
|
32
|
+
verification ? `Then verify: ${verification}` : null,
|
|
33
|
+
].filter(Boolean).join(' '),
|
|
34
|
+
{
|
|
35
|
+
required_gate: eligibility?.required_gate || 'execution_eligibility.required_gate',
|
|
36
|
+
execution_eligibility: eligibility ?? null,
|
|
37
|
+
requested_mutation_surface: cleanText(body?.requested_mutation_surface) || null,
|
|
38
|
+
remediation_command: remediation || null,
|
|
39
|
+
verification_command: verification || null,
|
|
40
|
+
},
|
|
41
|
+
);
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export function createGovernedImplementationDomain(client) {
|
|
2
|
+
return {
|
|
3
|
+
getExecutionEligibility: (body = {}) => client.executionEligibility.getExecutionEligibility(body),
|
|
4
|
+
_assertExecutionEligibility: (body = {}) => client.executionEligibility._assertExecutionEligibility(body),
|
|
5
|
+
executeVerifiedMutation: (request = {}) => client.verifiedMutations.executeVerifiedMutation(request),
|
|
6
|
+
};
|
|
7
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export function createSessionGovernanceDomain(client) {
|
|
2
|
+
return {
|
|
3
|
+
startSessionGovernance: ({
|
|
4
|
+
intent,
|
|
5
|
+
objective,
|
|
6
|
+
allowedScopes,
|
|
7
|
+
allowedMutationSurfaces,
|
|
8
|
+
requiredToolKeys,
|
|
9
|
+
sessionKey,
|
|
10
|
+
workflowRunId,
|
|
11
|
+
workflowId,
|
|
12
|
+
workflowSlug,
|
|
13
|
+
governedScope,
|
|
14
|
+
successCriteria,
|
|
15
|
+
disallowedSurfaces,
|
|
16
|
+
...rest
|
|
17
|
+
} = {}) => client._request('/api/v1/session-governance/startup', {
|
|
18
|
+
method: 'POST',
|
|
19
|
+
body: {
|
|
20
|
+
...rest,
|
|
21
|
+
objective: objective ?? intent,
|
|
22
|
+
allowed_mutation_surfaces: allowedMutationSurfaces ?? allowedScopes,
|
|
23
|
+
required_tool_keys: requiredToolKeys,
|
|
24
|
+
session_key: sessionKey,
|
|
25
|
+
workflow_run_id: workflowRunId,
|
|
26
|
+
workflow_id: workflowId,
|
|
27
|
+
workflow_slug: workflowSlug,
|
|
28
|
+
governed_scope: governedScope,
|
|
29
|
+
success_criteria: successCriteria,
|
|
30
|
+
disallowed_surfaces: disallowedSurfaces,
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
33
|
+
startReviewGovernance: ({
|
|
34
|
+
intent,
|
|
35
|
+
objective,
|
|
36
|
+
readScope,
|
|
37
|
+
requiredToolKeys,
|
|
38
|
+
sessionKey,
|
|
39
|
+
workflowRunId,
|
|
40
|
+
workflowId,
|
|
41
|
+
workflowSlug,
|
|
42
|
+
turnPersisted,
|
|
43
|
+
...rest
|
|
44
|
+
} = {}) => client._request('/api/v1/session-governance/review/startup', {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
body: {
|
|
47
|
+
...rest,
|
|
48
|
+
intent: intent ?? 'review code',
|
|
49
|
+
objective: objective ?? intent,
|
|
50
|
+
read_scope: readScope,
|
|
51
|
+
required_tool_keys: requiredToolKeys,
|
|
52
|
+
session_key: sessionKey,
|
|
53
|
+
workflow_run_id: workflowRunId,
|
|
54
|
+
workflow_id: workflowId,
|
|
55
|
+
workflow_slug: workflowSlug ?? 'code-review/read-only',
|
|
56
|
+
turn_persisted: turnPersisted,
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
evaluateTurnCompliance: (sessionId) => client._request(`/api/v1/session-governance/${encodeURIComponent(sessionId)}/compliance`),
|
|
60
|
+
blockIfNonCompliant: (sessionId) => client._request(`/api/v1/session-governance/${encodeURIComponent(sessionId)}/block-if-non-compliant`, {
|
|
61
|
+
method: 'POST',
|
|
62
|
+
}),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
export function createToolBindingApprovalsDomain(client) {
|
|
2
|
+
return {
|
|
3
|
+
createWorkflowToolBindingApprovalLane: ({
|
|
4
|
+
operatorActorType,
|
|
5
|
+
requesterActor,
|
|
6
|
+
requestedToolKeys,
|
|
7
|
+
blockedReason,
|
|
8
|
+
rollbackPlan,
|
|
9
|
+
requesterActorType,
|
|
10
|
+
operatorActorId,
|
|
11
|
+
targetWorkflowId,
|
|
12
|
+
targetWorkflowRunId,
|
|
13
|
+
relatedGapRecordIds,
|
|
14
|
+
requestedBindingScope,
|
|
15
|
+
riskClassification,
|
|
16
|
+
metadata,
|
|
17
|
+
...rest
|
|
18
|
+
} = {}) => {
|
|
19
|
+
if (!operatorActorType) throw new Error('operatorActorType is required.');
|
|
20
|
+
if (!requesterActor) throw new Error('requesterActor is required.');
|
|
21
|
+
if (!Array.isArray(requestedToolKeys) || requestedToolKeys.length === 0) {
|
|
22
|
+
throw new Error('requestedToolKeys must be a non-empty array.');
|
|
23
|
+
}
|
|
24
|
+
if (!blockedReason) throw new Error('blockedReason is required.');
|
|
25
|
+
if (!rollbackPlan) throw new Error('rollbackPlan is required.');
|
|
26
|
+
return client._request('/api/governance/bootstrap/workflow-tool-binding-approval/create', {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
body: {
|
|
29
|
+
...rest,
|
|
30
|
+
operator_actor_type: operatorActorType,
|
|
31
|
+
requester_actor: requesterActor,
|
|
32
|
+
requested_tool_keys: requestedToolKeys,
|
|
33
|
+
blocked_reason: blockedReason,
|
|
34
|
+
rollback_plan: rollbackPlan,
|
|
35
|
+
requester_actor_type: requesterActorType,
|
|
36
|
+
operator_actor_id: operatorActorId,
|
|
37
|
+
target_workflow_id: targetWorkflowId,
|
|
38
|
+
target_workflow_run_id: targetWorkflowRunId,
|
|
39
|
+
related_gap_record_ids: relatedGapRecordIds,
|
|
40
|
+
requested_binding_scope: requestedBindingScope,
|
|
41
|
+
risk_classification: riskClassification,
|
|
42
|
+
metadata,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
recordWorkflowToolBindingApprovalDecision: (approvalRequestId, {
|
|
47
|
+
operatorActorType,
|
|
48
|
+
decision,
|
|
49
|
+
operatorActorId,
|
|
50
|
+
decisionNotes,
|
|
51
|
+
decisionConditions,
|
|
52
|
+
...rest
|
|
53
|
+
} = {}) => {
|
|
54
|
+
if (!approvalRequestId) throw new Error('approvalRequestId is required.');
|
|
55
|
+
if (!operatorActorType) throw new Error('operatorActorType is required.');
|
|
56
|
+
if (!decision) throw new Error('decision is required.');
|
|
57
|
+
return client._request(`/api/governance/bootstrap/workflow-tool-binding-approval/${encodeURIComponent(approvalRequestId)}/approval-decision`, {
|
|
58
|
+
method: 'POST',
|
|
59
|
+
body: {
|
|
60
|
+
...rest,
|
|
61
|
+
operator_actor_type: operatorActorType,
|
|
62
|
+
operator_actor_id: operatorActorId,
|
|
63
|
+
decision,
|
|
64
|
+
decision_notes: decisionNotes,
|
|
65
|
+
decision_conditions: decisionConditions,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
executeWorkflowToolBindingApprovalBinding: (approvalRequestId, {
|
|
70
|
+
operatorActorType,
|
|
71
|
+
operatorActorId,
|
|
72
|
+
...rest
|
|
73
|
+
} = {}) => {
|
|
74
|
+
if (!approvalRequestId) throw new Error('approvalRequestId is required.');
|
|
75
|
+
if (!operatorActorType) throw new Error('operatorActorType is required.');
|
|
76
|
+
return client._request(`/api/governance/bootstrap/workflow-tool-binding-approval/${encodeURIComponent(approvalRequestId)}/binding-execution`, {
|
|
77
|
+
method: 'POST',
|
|
78
|
+
body: {
|
|
79
|
+
...rest,
|
|
80
|
+
operator_actor_type: operatorActorType,
|
|
81
|
+
operator_actor_id: operatorActorId,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
revalidateWorkflowToolBindingStartup: (approvalRequestId, {
|
|
86
|
+
operatorActorType,
|
|
87
|
+
operatorActorId,
|
|
88
|
+
...rest
|
|
89
|
+
} = {}) => {
|
|
90
|
+
if (!approvalRequestId) throw new Error('approvalRequestId is required.');
|
|
91
|
+
if (!operatorActorType) throw new Error('operatorActorType is required.');
|
|
92
|
+
return client._request(`/api/governance/bootstrap/workflow-tool-binding-approval/${encodeURIComponent(approvalRequestId)}/startup-revalidation`, {
|
|
93
|
+
method: 'POST',
|
|
94
|
+
body: {
|
|
95
|
+
...rest,
|
|
96
|
+
operator_actor_type: operatorActorType,
|
|
97
|
+
operator_actor_id: operatorActorId,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { executeVerifiedMutation as executeVerifiedMutationHelper } from '../utils/verified-mutations.js';
|
|
2
|
+
|
|
3
|
+
export function createVerifiedMutationsDomain(client) {
|
|
4
|
+
return {
|
|
5
|
+
executeVerifiedMutation: (request = {}) => executeVerifiedMutationHelper(request),
|
|
6
|
+
};
|
|
7
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { cleanList, cleanText, isPlainObject } from '../utils/text.js';
|
|
2
|
+
import { normalizeMetadataTaskBinding, normalizeTaskBindingPolicy } from '../utils/task-binding.js';
|
|
3
|
+
import { contextSessionIdFromInput } from './context-sessions.js';
|
|
4
|
+
|
|
5
|
+
function isActiveBinding(binding) {
|
|
6
|
+
return binding !== null && typeof binding === 'object' && !Array.isArray(binding) && (
|
|
7
|
+
binding.is_active === true ||
|
|
8
|
+
binding.is_active === 1 ||
|
|
9
|
+
binding.is_active === 'true' ||
|
|
10
|
+
binding.is_active === 'True'
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function activeToolKeysFromRegistry(registry) {
|
|
15
|
+
const bindings = Array.isArray(registry?.bindings) ? registry.bindings : [];
|
|
16
|
+
const seen = new Set();
|
|
17
|
+
const keys = [];
|
|
18
|
+
for (const binding of bindings) {
|
|
19
|
+
if (!isActiveBinding(binding)) continue;
|
|
20
|
+
const key = cleanText(binding.tool_key);
|
|
21
|
+
if (!key || seen.has(key)) continue;
|
|
22
|
+
seen.add(key);
|
|
23
|
+
keys.push(key);
|
|
24
|
+
}
|
|
25
|
+
return keys;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function reminderTokens(reminders) {
|
|
29
|
+
const tokens = [];
|
|
30
|
+
for (const reminder of Array.isArray(reminders) ? reminders : []) {
|
|
31
|
+
if (reminder === null || typeof reminder !== 'object' || Array.isArray(reminder)) continue;
|
|
32
|
+
for (const value of [reminder.reminder_key, reminder.reminder_id]) {
|
|
33
|
+
const token = cleanText(value);
|
|
34
|
+
if (token && !tokens.includes(token)) tokens.push(token);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return tokens;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function createWorkStartDomain(client) {
|
|
41
|
+
return {
|
|
42
|
+
startWork: (body = {}) => client._request('/api/work/start', { method: 'POST', body }),
|
|
43
|
+
startClaimedWork: ({
|
|
44
|
+
claimName,
|
|
45
|
+
actorId,
|
|
46
|
+
intentId,
|
|
47
|
+
declaredScopeFiles,
|
|
48
|
+
allowedMutationSurfaces,
|
|
49
|
+
runtimeSessionId,
|
|
50
|
+
executionPurpose,
|
|
51
|
+
successCriteria,
|
|
52
|
+
mutationAllowed,
|
|
53
|
+
metadata,
|
|
54
|
+
...rest
|
|
55
|
+
} = {}) => client._request('/api/governance/claims/start-claimed-work', {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
body: {
|
|
58
|
+
...rest,
|
|
59
|
+
claim_name: claimName,
|
|
60
|
+
actor_id: actorId,
|
|
61
|
+
intent_id: intentId,
|
|
62
|
+
declared_scope_files: declaredScopeFiles,
|
|
63
|
+
allowed_mutation_surfaces: allowedMutationSurfaces,
|
|
64
|
+
runtime_session_id: runtimeSessionId,
|
|
65
|
+
execution_purpose: executionPurpose,
|
|
66
|
+
success_criteria: successCriteria,
|
|
67
|
+
mutation_allowed: mutationAllowed,
|
|
68
|
+
metadata: normalizeMetadataTaskBinding(metadata),
|
|
69
|
+
},
|
|
70
|
+
}),
|
|
71
|
+
claimWorkItem: (body = {}) => {
|
|
72
|
+
const normalizedBody = body !== null && typeof body === 'object' && !Array.isArray(body)
|
|
73
|
+
? {
|
|
74
|
+
...body,
|
|
75
|
+
...(body.task_binding !== null && typeof body.task_binding === 'object' && !Array.isArray(body.task_binding)
|
|
76
|
+
? { task_binding: normalizeTaskBindingPolicy(body.task_binding) }
|
|
77
|
+
: {}),
|
|
78
|
+
metadata: normalizeMetadataTaskBinding(body.metadata),
|
|
79
|
+
}
|
|
80
|
+
: body;
|
|
81
|
+
return client._request('/api/governance/claims/claim-work-item', { method: 'POST', body: normalizedBody });
|
|
82
|
+
},
|
|
83
|
+
bindClaimedWorkItem: async ({
|
|
84
|
+
claimId,
|
|
85
|
+
contextSessionId,
|
|
86
|
+
workflowRunId,
|
|
87
|
+
agentSessionId,
|
|
88
|
+
claimedItemId,
|
|
89
|
+
claimedItemKey,
|
|
90
|
+
claimName,
|
|
91
|
+
actorId,
|
|
92
|
+
workflowId,
|
|
93
|
+
workflowSlug,
|
|
94
|
+
requiredToolKeys,
|
|
95
|
+
declaredScopeFiles,
|
|
96
|
+
allowedMutationSurfaces,
|
|
97
|
+
successCriteria,
|
|
98
|
+
acknowledgedReminders,
|
|
99
|
+
intentConfirmation,
|
|
100
|
+
actorSignature,
|
|
101
|
+
autoSignoff = true,
|
|
102
|
+
metadata,
|
|
103
|
+
} = {}) => {
|
|
104
|
+
const normalizedContextSessionId = contextSessionIdFromInput({
|
|
105
|
+
contextSessionId,
|
|
106
|
+
context_session_id: contextSessionId,
|
|
107
|
+
claim: { context_session_id: contextSessionId },
|
|
108
|
+
});
|
|
109
|
+
const normalizedClaimId = cleanText(claimId);
|
|
110
|
+
const normalizedWorkflowRunId = cleanText(workflowRunId);
|
|
111
|
+
const normalizedAgentSessionId = cleanText(agentSessionId);
|
|
112
|
+
const normalizedClaimedItemId = cleanText(claimedItemId);
|
|
113
|
+
const normalizedClaimedItemKey = cleanText(claimedItemKey);
|
|
114
|
+
const normalizedClaimedItemRef = normalizedClaimedItemId || normalizedClaimedItemKey;
|
|
115
|
+
if (!normalizedContextSessionId) throw new Error('contextSessionId is required.');
|
|
116
|
+
if (!normalizedWorkflowRunId) throw new Error('workflowRunId is required.');
|
|
117
|
+
if (!normalizedAgentSessionId) throw new Error('agentSessionId is required.');
|
|
118
|
+
if (!normalizedClaimedItemRef) throw new Error('claimedItemId or claimedItemKey is required.');
|
|
119
|
+
|
|
120
|
+
const normalizedWorkflowId = cleanText(workflowId);
|
|
121
|
+
const normalizedWorkflowSlug = cleanText(workflowSlug);
|
|
122
|
+
let normalizedRequiredToolKeys = cleanList(requiredToolKeys);
|
|
123
|
+
let workflowRegistry = null;
|
|
124
|
+
if (normalizedRequiredToolKeys.length === 0 && (normalizedWorkflowId || normalizedWorkflowSlug)) {
|
|
125
|
+
workflowRegistry = await client.getWorkflowToolRegistry({
|
|
126
|
+
workflowId: normalizedWorkflowId,
|
|
127
|
+
workflowSlug: normalizedWorkflowSlug,
|
|
128
|
+
});
|
|
129
|
+
normalizedRequiredToolKeys = activeToolKeysFromRegistry(workflowRegistry);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const lockClaimResult = await client.contextSessions.lockContextSessionClaim(normalizedContextSessionId);
|
|
133
|
+
const lockedContextSession = lockClaimResult?.context_session || lockClaimResult;
|
|
134
|
+
const lockedContextSessionId = contextSessionIdFromInput(lockedContextSession) || normalizedContextSessionId;
|
|
135
|
+
|
|
136
|
+
const claimWorkItemResult = await client.claimWorkItem({
|
|
137
|
+
context_session_id: lockedContextSessionId,
|
|
138
|
+
workflow_run_id: normalizedWorkflowRunId,
|
|
139
|
+
agent_session_id: normalizedAgentSessionId,
|
|
140
|
+
claimed_item_id: normalizedClaimedItemId,
|
|
141
|
+
claimed_item_key: normalizedClaimedItemKey,
|
|
142
|
+
claim_name: claimName,
|
|
143
|
+
actor_id: actorId,
|
|
144
|
+
workflow_id: normalizedWorkflowId,
|
|
145
|
+
workflow_slug: normalizedWorkflowSlug,
|
|
146
|
+
required_tool_keys: normalizedRequiredToolKeys,
|
|
147
|
+
declared_scope_files: cleanList(declaredScopeFiles).length > 0
|
|
148
|
+
? cleanList(declaredScopeFiles)
|
|
149
|
+
: [normalizedClaimedItemRef],
|
|
150
|
+
allowed_mutation_surfaces: cleanList(allowedMutationSurfaces).length > 0
|
|
151
|
+
? cleanList(allowedMutationSurfaces)
|
|
152
|
+
: ['project_roadmap_task'],
|
|
153
|
+
success_criteria: successCriteria,
|
|
154
|
+
metadata,
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
let signedClaim = null;
|
|
158
|
+
const resolvedClaimId = cleanText(claimWorkItemResult?.claim_id) || normalizedClaimId;
|
|
159
|
+
if (autoSignoff && resolvedClaimId) {
|
|
160
|
+
const claimEnvelope = isPlainObject(claimWorkItemResult?.claim) ? claimWorkItemResult.claim : claimWorkItemResult;
|
|
161
|
+
const reminders = cleanList(acknowledgedReminders).length > 0
|
|
162
|
+
? cleanList(acknowledgedReminders)
|
|
163
|
+
: reminderTokens(claimEnvelope?.required_reminders);
|
|
164
|
+
if (reminders.length > 0) {
|
|
165
|
+
signedClaim = await client.signoffClaim(resolvedClaimId, {
|
|
166
|
+
acknowledged_reminders: reminders,
|
|
167
|
+
intent_confirmation: cleanText(intentConfirmation) || 'I confirm this governed execution intent and scope.',
|
|
168
|
+
actor_signature: cleanText(actorSignature) || cleanText(actorId) || client.actorId,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
claim_id: resolvedClaimId,
|
|
175
|
+
context_session_id: lockedContextSessionId,
|
|
176
|
+
workflow_run_id: normalizedWorkflowRunId,
|
|
177
|
+
agent_session_id: normalizedAgentSessionId,
|
|
178
|
+
required_tool_keys: normalizedRequiredToolKeys,
|
|
179
|
+
workflow_registry: workflowRegistry,
|
|
180
|
+
lock_claim_result: lockClaimResult,
|
|
181
|
+
claim_work_item_result: claimWorkItemResult,
|
|
182
|
+
signed_claim: signedClaim,
|
|
183
|
+
approved_tool_keys: cleanList(
|
|
184
|
+
signedClaim?.approved_tool_keys ||
|
|
185
|
+
signedClaim?.claim?.approved_tool_keys ||
|
|
186
|
+
claimWorkItemResult?.approved_tool_keys ||
|
|
187
|
+
claimWorkItemResult?.claim?.approved_tool_keys
|
|
188
|
+
),
|
|
189
|
+
};
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export function createWorkflowTurnsDomain(client) {
|
|
2
|
+
return {
|
|
3
|
+
completeTurn: (body = {}) => client._request('/api/turns/complete', { method: 'POST', body }),
|
|
4
|
+
persistAssistantTurn: (body) => client._request('/api/v1/assistant-turns', { method: 'POST', body }),
|
|
5
|
+
};
|
|
6
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { AIEngineClient, createAIEngineClient } from './client.js';
|
|
2
|
-
export const AI_ENGINE_CLIENT_VERSION = '1.1.
|
|
2
|
+
export const AI_ENGINE_CLIENT_VERSION = '1.1.89';
|
|
3
3
|
export { GOVERNED_MUTATION_REQUIRED_CAPABILITIES, AI_ENGINE_CLIENT_CAPABILITIES, TASK_BOUND_SUBSTRATE_EXECUTION_POLICY } from './constants/governance.js';
|
|
4
4
|
export { LOGA_CONTRACT, LOGA_INTERACTION_CONTRACT, LOGA_NAVIGATION_CONTRACT, LOGA_PROJECTION_WORKFLOW } from './constants/loga.js';
|
|
5
5
|
export {
|