@bpmsoftwaresolutions/ai-engine-client 1.1.98 → 1.1.99

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.
@@ -0,0 +1,405 @@
1
+ import { cleanText, isPlainObject } from '../utils/communication.js';
2
+
3
+ export function createRefactoringTransfersDomain(client) {
4
+ return {
5
+ transferRefactoringBundle: (request) => transferRefactoringBundle(client, request),
6
+ };
7
+ }
8
+
9
+ export async function transferRefactoringBundle(client, {
10
+ projectIdentifier,
11
+ projectId,
12
+ startWorkBody = {},
13
+ startWorkRequest = {},
14
+ resumeProjectWorkOptions = {},
15
+ transferChannelId,
16
+ transfer_channel_id,
17
+ channelId,
18
+ channel_id,
19
+ workTransferPacketId,
20
+ work_transfer_packet_id,
21
+ workflowRunId,
22
+ workflow_run_id,
23
+ sourceAgent,
24
+ source_agent,
25
+ sourceAgentSessionId,
26
+ source_agent_session_id,
27
+ targetAgent,
28
+ target_agent,
29
+ targetAgentSessionId,
30
+ target_agent_session_id,
31
+ targetAgentLabel,
32
+ target_agent_label,
33
+ sourceRef,
34
+ source_ref,
35
+ problemStatement,
36
+ problem_statement,
37
+ affectedFilesOrSymbols,
38
+ affected_files_or_symbols,
39
+ recommendedAction,
40
+ recommended_action,
41
+ acceptanceCriteria,
42
+ acceptance_criteria,
43
+ evidenceRefs = [],
44
+ evidence_refs = [],
45
+ riskLevel,
46
+ risk_level,
47
+ handoffNotes,
48
+ handoff_notes,
49
+ ownershipAssignment = {},
50
+ ownership_assignment = {},
51
+ proposal = {},
52
+ refactoringBundle = {},
53
+ refactoring_bundle = {},
54
+ participantRole,
55
+ participant_role,
56
+ includeTransferChannelProjection = true,
57
+ includeOperatorProjectionMetadata = true,
58
+ metadata = {},
59
+ } = {}) {
60
+ const missingSurfaces = [];
61
+ const normalizedMetadata = isPlainObject(metadata) ? metadata : {};
62
+ const normalizedBundle = isPlainObject(refactoring_bundle)
63
+ ? refactoring_bundle
64
+ : (isPlainObject(refactoringBundle) ? refactoringBundle : {});
65
+ const normalizedOwnershipAssignment = isPlainObject(ownership_assignment)
66
+ ? ownership_assignment
67
+ : (isPlainObject(ownershipAssignment) ? ownershipAssignment : {});
68
+ const normalizedProposal = isPlainObject(proposal) ? proposal : {};
69
+ const normalizedProjectReference = cleanText(projectIdentifier) || cleanText(projectId);
70
+ const normalizedSourceAgent = cleanText(source_agent) || cleanText(sourceAgent) || client.agentSessionId || client.actorId;
71
+ const normalizedTargetAgent = cleanText(target_agent) || cleanText(targetAgent) || cleanText(target_agent_session_id) || cleanText(targetAgentSessionId);
72
+ const normalizedTargetLabel = cleanText(target_agent_label) || cleanText(targetAgentLabel) || normalizedTargetAgent;
73
+ const normalizedParticipantRole = cleanText(participant_role) || cleanText(participantRole) || 'requester';
74
+ const normalizedSourceRef = cleanText(source_ref) || cleanText(sourceRef) || cleanText(normalizedBundle.source_ref);
75
+ const normalizedProblemStatement = cleanText(problem_statement) || cleanText(problemStatement) || cleanText(normalizedBundle.problem_statement);
76
+ const normalizedAffectedFiles = Array.isArray(affected_files_or_symbols)
77
+ ? affected_files_or_symbols
78
+ : (Array.isArray(affectedFilesOrSymbols) ? affectedFilesOrSymbols : normalizedBundle.affected_files_or_symbols || []);
79
+ const normalizedRecommendedAction = cleanText(recommended_action) || cleanText(recommendedAction) || cleanText(normalizedBundle.recommended_action);
80
+ const normalizedAcceptanceCriteria = Array.isArray(acceptance_criteria)
81
+ ? acceptance_criteria
82
+ : (Array.isArray(acceptanceCriteria) ? acceptanceCriteria : normalizedBundle.acceptance_criteria || []);
83
+ const normalizedEvidenceRefs = Array.isArray(evidence_refs) ? evidence_refs : (Array.isArray(evidenceRefs) ? evidenceRefs : normalizedBundle.evidence_refs || []);
84
+ const normalizedRiskLevel = cleanText(risk_level) || cleanText(riskLevel) || cleanText(normalizedBundle.risk_level) || 'medium';
85
+ const normalizedHandoffNotes = cleanText(handoff_notes) || cleanText(handoffNotes) || cleanText(normalizedBundle.handoff_notes);
86
+ const shouldMoveOwnership = Boolean(normalizedTargetAgent || normalizedOwnershipAssignment.owner_agent_session_id);
87
+ if (!normalizedTargetAgent) {
88
+ throw new Error('target_agent is required.');
89
+ }
90
+
91
+ let continuation = null;
92
+ let startWorkResult = null;
93
+ if (normalizedProjectReference) {
94
+ if (typeof client.resumeProjectWork === 'function') {
95
+ continuation = await client.resumeProjectWork({
96
+ projectIdentifier: normalizedProjectReference,
97
+ projectId: normalizedProjectReference,
98
+ requireClaim: false,
99
+ ...resumeProjectWorkOptions,
100
+ ...normalizedMetadata.resume_project_work_options,
101
+ });
102
+ } else {
103
+ missingSurfaces.push('resumeProjectWork');
104
+ }
105
+ } else if (Object.keys(isPlainObject(startWorkRequest) ? startWorkRequest : {}).length > 0 || Object.keys(isPlainObject(startWorkBody) ? startWorkBody : {}).length > 0) {
106
+ if (typeof client.startWork === 'function') {
107
+ startWorkResult = await client.startWork({
108
+ ...(isPlainObject(startWorkBody) ? startWorkBody : {}),
109
+ ...(isPlainObject(startWorkRequest) ? startWorkRequest : {}),
110
+ });
111
+ } else {
112
+ missingSurfaces.push('startWork');
113
+ }
114
+ } else {
115
+ throw new Error('projectIdentifier is required.');
116
+ }
117
+
118
+ const projectPayload = isPlainObject(continuation?.project)
119
+ ? continuation.project
120
+ : isPlainObject(startWorkResult?.project)
121
+ ? startWorkResult.project
122
+ : isPlainObject(continuation?.summary)
123
+ ? continuation.summary
124
+ : {};
125
+ const resolvedProjectId = cleanText(projectPayload.project_id) || cleanText(projectPayload.projectId) || normalizedProjectReference;
126
+ const resolvedWorkflowId = cleanText(projectPayload.workflow_id) || cleanText(projectPayload.workflowId) || cleanText(continuation?.workflow_id) || cleanText(startWorkResult?.workflow_id);
127
+ const resolvedWorkflowRunId = cleanText(projectPayload.workflow_run_id) || cleanText(projectPayload.workflowRunId) || cleanText(continuation?.workflow_run_id) || cleanText(startWorkResult?.workflow_run_id) || cleanText(startWorkResult?.workflowRunId) || cleanText(workflow_run_id) || cleanText(workflowRunId);
128
+ if (!resolvedProjectId || !resolvedWorkflowRunId) {
129
+ throw new Error('project/work identifiers are ambiguous.');
130
+ }
131
+
132
+ const transferSurface = typeof client.transferWorkPacket === 'function'
133
+ ? client.transferWorkPacket.bind(client)
134
+ : null;
135
+ if (!transferSurface) missingSurfaces.push('transferWorkPacket');
136
+ const transferResult = transferSurface
137
+ ? await transferSurface({
138
+ workflowRunId: resolvedWorkflowRunId,
139
+ transferKind: 'upstream_remediation',
140
+ objective: normalizedProblemStatement || normalizedRecommendedAction || 'Refactoring bundle transfer',
141
+ requestedOutcome: normalizedRecommendedAction || normalizedProblemStatement || 'Receive refactoring bundle acknowledgement.',
142
+ target: {
143
+ intent: 'upstream_remediation',
144
+ recipient_mode: 'agent_session',
145
+ preferred_agent_session_id: normalizedTargetAgent,
146
+ preferred_role_key: normalizedTargetLabel,
147
+ },
148
+ artifacts: normalizedAffectedFiles,
149
+ issues: [],
150
+ expectedEvidence: normalizedAcceptanceCriteria,
151
+ preferredModes: ['bundle', 'artifact_refs', 'inline_payload'],
152
+ capabilities: {},
153
+ senderAgentSessionId: normalizedSourceAgent,
154
+ senderActorSessionId: null,
155
+ subject: normalizedProblemStatement || normalizedRecommendedAction || 'Refactoring bundle transfer',
156
+ bodyMarkdown: normalizedHandoffNotes || normalizedRecommendedAction || normalizedProblemStatement,
157
+ messageKind: 'handoff',
158
+ metadata: {
159
+ ...normalizedMetadata,
160
+ source: 'transferRefactoringBundle',
161
+ source_ref: normalizedSourceRef,
162
+ risk_level: normalizedRiskLevel,
163
+ },
164
+ })
165
+ : null;
166
+ const transferPayload = isPlainObject(transferResult) ? transferResult : {};
167
+ let resolvedWorkTransferPacketId = cleanText(work_transfer_packet_id)
168
+ || cleanText(workTransferPacketId)
169
+ || cleanText(transferPayload.work_transfer_packet?.work_transfer_packet_id)
170
+ || cleanText(transferPayload.work_transfer_packet_id)
171
+ || cleanText(transferPayload.transfer_packet_id)
172
+ || cleanText(transferPayload.packet_id)
173
+ || null;
174
+ const transferChannel = isPlainObject(transferPayload.communication_transfer_channel) ? transferPayload.communication_transfer_channel : {};
175
+ let resolvedTransferChannelId = cleanText(transfer_channel_id)
176
+ || cleanText(transferChannelId)
177
+ || cleanText(channel_id)
178
+ || cleanText(channelId)
179
+ || cleanText(transferChannel.transfer_channel_id)
180
+ || cleanText(transferChannel.channel_id)
181
+ || null;
182
+
183
+ const shouldResumeChannel = Boolean(cleanText(transfer_channel_id) || cleanText(transferChannelId) || cleanText(channel_id) || cleanText(channelId));
184
+ const channelSurface = shouldResumeChannel
185
+ ? (typeof client.resumeTransferChannel === 'function'
186
+ ? client.resumeTransferChannel.bind(client)
187
+ : null)
188
+ : (typeof client.openTransferChannel === 'function'
189
+ ? client.openTransferChannel.bind(client)
190
+ : null);
191
+ if (!channelSurface) missingSurfaces.push(shouldResumeChannel ? 'resumeTransferChannel' : 'openTransferChannel');
192
+ const channelResult = channelSurface && resolvedWorkTransferPacketId
193
+ ? await channelSurface({
194
+ transferChannelId: resolvedTransferChannelId,
195
+ workTransferPacketId: resolvedWorkTransferPacketId,
196
+ workflowRunId: resolvedWorkflowRunId,
197
+ channelKind: 'bidirectional',
198
+ downstreamAgentSessionId: normalizedTargetAgent,
199
+ downstreamActorSessionId: null,
200
+ upstreamAgentSessionId: normalizedSourceAgent,
201
+ upstreamActorSessionId: null,
202
+ evidenceRequiredForClosure: true,
203
+ metadata: {
204
+ ...normalizedMetadata,
205
+ source: 'transferRefactoringBundle',
206
+ },
207
+ })
208
+ : null;
209
+ const channelPayload = isPlainObject(channelResult) ? channelResult : {};
210
+ resolvedTransferChannelId = cleanText(channelPayload.transfer_channel_id)
211
+ || cleanText(channelPayload.channel_id)
212
+ || cleanText(channelPayload.transfer_channel?.transfer_channel_id)
213
+ || cleanText(channelPayload.communication_transfer_channel?.transfer_channel_id)
214
+ || resolvedTransferChannelId;
215
+
216
+ const ownershipSurface = typeof client.assignCollaborationOwnership === 'function'
217
+ ? client.assignCollaborationOwnership.bind(client)
218
+ : null;
219
+ if (!ownershipSurface) missingSurfaces.push('assignCollaborationOwnership');
220
+ const ownershipResult = ownershipSurface && resolvedTransferChannelId && normalizedTargetAgent
221
+ ? await ownershipSurface({
222
+ transferChannelId: resolvedTransferChannelId,
223
+ workTransferPacketId: resolvedWorkTransferPacketId,
224
+ workflowRunId: resolvedWorkflowRunId,
225
+ participantRole: normalizedParticipantRole,
226
+ ownerAgentSessionId: normalizedTargetAgent,
227
+ ownerActorSessionId: null,
228
+ ownerLabel: normalizedTargetLabel,
229
+ assignmentState: 'assigned',
230
+ assignmentReason: normalizedProblemStatement || normalizedRecommendedAction,
231
+ currentPhase: 'refactoring_bundle_transfer',
232
+ assignedByAgentSessionId: normalizedSourceAgent,
233
+ assignedByActorSessionId: null,
234
+ metadata: {
235
+ ...normalizedMetadata,
236
+ source: 'transferRefactoringBundle',
237
+ source_ref: normalizedSourceRef,
238
+ },
239
+ })
240
+ : null;
241
+ const ownershipPayload = isPlainObject(ownershipResult) ? ownershipResult : {};
242
+
243
+ const proposalSurface = typeof client.postCollaborationProposal === 'function'
244
+ ? client.postCollaborationProposal.bind(client)
245
+ : null;
246
+ if (!proposalSurface) missingSurfaces.push('postCollaborationProposal');
247
+ const proposalResult = proposalSurface && resolvedTransferChannelId && resolvedWorkTransferPacketId
248
+ ? await proposalSurface({
249
+ transferChannelId: resolvedTransferChannelId,
250
+ workTransferPacketId: resolvedWorkTransferPacketId,
251
+ workflowRunId: resolvedWorkflowRunId,
252
+ proposalKind: 'refactoring_bundle',
253
+ proposalState: 'proposed',
254
+ participantRole: normalizedParticipantRole,
255
+ proposalSummary: normalizedProblemStatement || normalizedRecommendedAction || 'Refactoring bundle transfer',
256
+ currentPhase: 'refactoring_bundle_transfer',
257
+ expectedNextUpdate: normalizedAcceptanceCriteria.join('; ') || normalizedRecommendedAction,
258
+ requiredEvidence: normalizedAcceptanceCriteria,
259
+ responseSchema: {
260
+ source_ref: normalizedSourceRef,
261
+ risk_level: normalizedRiskLevel,
262
+ target_agent: normalizedTargetAgent,
263
+ },
264
+ blockerSummary: normalizedProblemStatement || normalizedRecommendedAction,
265
+ revisionNumber: 1,
266
+ proposerAgentSessionId: normalizedSourceAgent,
267
+ proposerActorSessionId: null,
268
+ metadata: {
269
+ ...normalizedMetadata,
270
+ source: 'transferRefactoringBundle',
271
+ affected_files_or_symbols: normalizedAffectedFiles,
272
+ },
273
+ })
274
+ : null;
275
+ const proposalPayload = isPlainObject(proposalResult) ? proposalResult : {};
276
+
277
+ const watchSurface = typeof client.startMessageWatch === 'function'
278
+ ? client.startMessageWatch.bind(client)
279
+ : null;
280
+ if (!watchSurface) missingSurfaces.push('startMessageWatch');
281
+ const watchResult = watchSurface && resolvedTransferChannelId && resolvedWorkTransferPacketId
282
+ ? await watchSurface({
283
+ transferChannelId: resolvedTransferChannelId,
284
+ workTransferPacketId: resolvedWorkTransferPacketId,
285
+ workflowRunId: resolvedWorkflowRunId,
286
+ watchingAgentRole: normalizedSourceAgent,
287
+ expectedFromRole: normalizedTargetAgent,
288
+ expectedMessageKind: 'response',
289
+ watchType: 'expected_peer_message',
290
+ watchingAgentSessionId: normalizedSourceAgent,
291
+ expectedPayload: {
292
+ source_ref: normalizedSourceRef,
293
+ expected_acknowledgement: 'refactoring bundle received',
294
+ target_agent: normalizedTargetAgent,
295
+ },
296
+ currentStatus: 'watching',
297
+ operatorNudge: normalizedHandoffNotes || normalizedRecommendedAction || normalizedProblemStatement,
298
+ metadata: {
299
+ ...normalizedMetadata,
300
+ source: 'transferRefactoringBundle',
301
+ },
302
+ })
303
+ : null;
304
+ const watchPayload = isPlainObject(watchResult) ? watchResult : {};
305
+
306
+ const heartbeatSurface = typeof client.postCollaborationHeartbeat === 'function'
307
+ ? client.postCollaborationHeartbeat.bind(client)
308
+ : typeof client.postAgentHeartbeat === 'function'
309
+ ? client.postAgentHeartbeat.bind(client)
310
+ : null;
311
+ if (!heartbeatSurface) missingSurfaces.push('postCollaborationHeartbeat');
312
+ const heartbeatResult = heartbeatSurface && resolvedTransferChannelId && resolvedWorkTransferPacketId
313
+ ? await heartbeatSurface({
314
+ transferChannelId: resolvedTransferChannelId,
315
+ workTransferPacketId: resolvedWorkTransferPacketId,
316
+ workflowRunId: resolvedWorkflowRunId,
317
+ participantRole: normalizedParticipantRole,
318
+ activityState: 'active',
319
+ agentSessionId: normalizedSourceAgent,
320
+ currentPhase: 'refactoring_bundle_transfer',
321
+ currentTaskSummary: normalizedProblemStatement || normalizedRecommendedAction || 'Refactoring bundle transfer',
322
+ isActive: true,
323
+ metadata: {
324
+ ...normalizedMetadata,
325
+ source: 'transferRefactoringBundle',
326
+ },
327
+ })
328
+ : null;
329
+ const heartbeatPayload = isPlainObject(heartbeatResult) ? heartbeatResult : {};
330
+
331
+ const transferChannelProjectionSurface = typeof client.getTransferChannelProjection === 'function'
332
+ ? client.getTransferChannelProjection.bind(client)
333
+ : typeof client.getLogaTransferChannelThreadProjection === 'function'
334
+ ? client.getLogaTransferChannelThreadProjection.bind(client)
335
+ : null;
336
+ if (!transferChannelProjectionSurface) missingSurfaces.push('getTransferChannelProjection');
337
+ const transferChannelProjection = includeTransferChannelProjection && transferChannelProjectionSurface && resolvedTransferChannelId
338
+ ? await transferChannelProjectionSurface(resolvedTransferChannelId).catch(() => null)
339
+ : null;
340
+
341
+ const transferPacketId = cleanText(transferPayload.work_transfer_packet?.work_transfer_packet_id)
342
+ || cleanText(transferPayload.work_transfer_packet_id)
343
+ || cleanText(transferPayload.transfer_packet_id)
344
+ || cleanText(transferPayload.packet_id)
345
+ || resolvedWorkTransferPacketId
346
+ || null;
347
+ const channelIdResolved = resolvedTransferChannelId || cleanText(channelPayload.transfer_channel_id) || cleanText(channelPayload.channel_id) || null;
348
+ const ownershipAssignmentId = cleanText(ownershipPayload.collaboration_ownership_assignment_id)
349
+ || cleanText(ownershipPayload.ownership_assignment_id)
350
+ || cleanText(ownershipPayload.collaboration_ownership_assignment?.collaboration_ownership_assignment_id)
351
+ || cleanText(ownershipPayload.collaboration_ownership_assignment?.ownership_assignment_id)
352
+ || null;
353
+ const proposalId = cleanText(proposalPayload.collaboration_proposal_id)
354
+ || cleanText(proposalPayload.proposal_id)
355
+ || cleanText(proposalPayload.collaboration_proposal?.collaboration_proposal_id)
356
+ || cleanText(proposalPayload.collaboration_proposal?.proposal_id)
357
+ || null;
358
+ const watchId = cleanText(watchPayload.message_watch_id)
359
+ || cleanText(watchPayload.watch_id)
360
+ || cleanText(watchPayload.message_watch?.message_watch_id)
361
+ || cleanText(watchPayload.message_watch?.watch_id)
362
+ || null;
363
+ const heartbeatStatus = cleanText(heartbeatPayload.collaboration_heartbeat?.activity_state)
364
+ || cleanText(heartbeatPayload.activity_state)
365
+ || cleanText(heartbeatPayload.status)
366
+ || cleanText(heartbeatPayload.collaboration_heartbeat?.status)
367
+ || 'active';
368
+ const expectedAcknowledgement = cleanText(watchPayload.expected_message_kind)
369
+ || cleanText(watchPayload.message_watch?.expected_message_kind)
370
+ || cleanText(watchPayload.message_watch?.expected_acknowledgement)
371
+ || 'response';
372
+ const operatorProjectionMetadata = includeOperatorProjectionMetadata
373
+ ? {
374
+ transfer_channel_projection: transferChannelProjection,
375
+ transfer: transferPayload,
376
+ channel: channelPayload,
377
+ ownership_assignment: ownershipPayload,
378
+ proposal: proposalPayload,
379
+ message_watch: watchPayload,
380
+ heartbeat: heartbeatPayload,
381
+ }
382
+ : null;
383
+
384
+ return {
385
+ status: missingSurfaces.length > 0 ? 'partial' : 'ready',
386
+ project_id: resolvedProjectId,
387
+ source_agent: normalizedSourceAgent,
388
+ target_agent: normalizedTargetAgent,
389
+ transfer_packet_id: transferPacketId,
390
+ channel_id: channelIdResolved,
391
+ ownership_assignment_id: ownershipAssignmentId,
392
+ proposal_id: proposalId,
393
+ watch_id: watchId,
394
+ expected_acknowledgement: expectedAcknowledgement,
395
+ heartbeat_status: heartbeatStatus,
396
+ operator_projection_metadata: operatorProjectionMetadata,
397
+ missing_surfaces: [...new Set(missingSurfaces)],
398
+ transfer: transferPayload,
399
+ channel: channelPayload,
400
+ ownership_assignment: ownershipPayload,
401
+ proposal: proposalPayload,
402
+ message_watch: watchPayload,
403
+ heartbeat: heartbeatPayload,
404
+ };
405
+ }
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.98';
2
+ export const AI_ENGINE_CLIENT_VERSION = '1.1.99';
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 {