@bpmsoftwaresolutions/ai-engine-client 1.1.98 → 1.1.101

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,379 @@
1
+ import { cleanText, isPlainObject } from '../utils/communication.js';
2
+
3
+ export function createCommunicationTicketsDomain(client) {
4
+ return {
5
+ createCrossAgentRemediationTicket: (request) => createCrossAgentRemediationTicket(client, request),
6
+ };
7
+ }
8
+
9
+ export async function createCrossAgentRemediationTicket(client, {
10
+ transferChannelId,
11
+ transfer_channel_id,
12
+ channelId,
13
+ channel_id,
14
+ workTransferPacketId,
15
+ work_transfer_packet_id,
16
+ packetId,
17
+ packet_id,
18
+ workflowRunId,
19
+ workflow_run_id,
20
+ ownershipMove,
21
+ ownership_move,
22
+ transferOwnership,
23
+ transfer_ownership,
24
+ assignedTo,
25
+ assigned_to,
26
+ requestedBy,
27
+ requested_by,
28
+ severity,
29
+ sourceRef,
30
+ source_ref,
31
+ findingId,
32
+ finding_id,
33
+ blockerId,
34
+ blocker_id,
35
+ failedCheckId,
36
+ failed_check_id,
37
+ workflowGap,
38
+ workflow_gap,
39
+ blockerKind,
40
+ blocker_kind,
41
+ blockerSummary,
42
+ blocker_summary,
43
+ blockerDetails,
44
+ blocker_details,
45
+ expectedResponse,
46
+ expected_response,
47
+ participantRole,
48
+ participant_role,
49
+ watcherRole,
50
+ watcher_role,
51
+ proposalId,
52
+ proposal_id,
53
+ collaborationProposalId,
54
+ collaboration_proposal_id,
55
+ expectedMessageKind,
56
+ expected_message_kind,
57
+ messageWatchId,
58
+ message_watch_id,
59
+ replyBodyMarkdown,
60
+ reply_body_markdown,
61
+ replyPayload = {},
62
+ reply_payload = {},
63
+ replyScope = {},
64
+ reply_scope = {},
65
+ replyEvidenceRefs = [],
66
+ reply_evidence_refs = [],
67
+ metadata = {},
68
+ includeTransferChannelProjection = true,
69
+ includeOperatorProjectionMetadata = true,
70
+ } = {}) {
71
+ const missingSurfaces = [];
72
+ const normalizedMetadata = isPlainObject(metadata) ? metadata : {};
73
+ const normalizedTransferChannelId = cleanText(transfer_channel_id) || cleanText(transferChannelId) || cleanText(channel_id) || cleanText(channelId);
74
+ const normalizedWorkTransferPacketId = cleanText(work_transfer_packet_id) || cleanText(workTransferPacketId) || cleanText(packet_id) || cleanText(packetId);
75
+ const normalizedWorkflowRunId = cleanText(workflow_run_id) || cleanText(workflowRunId);
76
+ const normalizedRequestedBy = cleanText(requested_by) || cleanText(requestedBy) || client.agentSessionId || client.actorId;
77
+ const normalizedAssignedTo = cleanText(assigned_to) || cleanText(assignedTo);
78
+ const normalizedSeverity = cleanText(severity) || 'medium';
79
+ const normalizedSourceRef = cleanText(source_ref) || cleanText(sourceRef) || cleanText(finding_id) || cleanText(findingId) || cleanText(blocker_id) || cleanText(blockerId) || cleanText(failed_check_id) || cleanText(failedCheckId) || cleanText(workflow_gap) || cleanText(workflowGap);
80
+ const normalizedExpectedResponse = cleanText(expected_response) || cleanText(expectedResponse) || 'assignee acknowledgement';
81
+ const normalizedParticipantRole = cleanText(participant_role) || cleanText(participantRole) || 'requester';
82
+ const normalizedWatcherRole = cleanText(watcher_role) || cleanText(watcherRole) || 'watcher';
83
+ const normalizedBlockerKind = cleanText(blocker_kind) || cleanText(blockerKind) || 'remediation';
84
+ const normalizedBlockerSummary = cleanText(blocker_summary) || cleanText(blockerSummary) || normalizedSourceRef || normalizedExpectedResponse;
85
+ const normalizedBlockerDetails = cleanText(blocker_details) || cleanText(blockerDetails) || normalizedExpectedResponse;
86
+ const normalizedExpectedMessageKind = cleanText(expected_message_kind) || cleanText(expectedMessageKind) || 'response';
87
+ const normalizedReplyPayload = isPlainObject(reply_payload) ? reply_payload : (isPlainObject(replyPayload) ? replyPayload : {});
88
+ const normalizedReplyScope = isPlainObject(reply_scope) ? reply_scope : (isPlainObject(replyScope) ? replyScope : {});
89
+ const normalizedReplyEvidenceRefs = Array.isArray(reply_evidence_refs) ? reply_evidence_refs : (Array.isArray(replyEvidenceRefs) ? replyEvidenceRefs : []);
90
+ const shouldMoveOwnership = Boolean(ownership_move ?? ownershipMove ?? transfer_ownership ?? transferOwnership);
91
+ const hasExplicitChannel = Boolean(normalizedTransferChannelId);
92
+
93
+ if (!hasExplicitChannel && !shouldMoveOwnership) {
94
+ throw new Error('channel_id is required unless ownershipMove is true.');
95
+ }
96
+
97
+ let resumedChannel = null;
98
+ let resolvedTransferChannelId = normalizedTransferChannelId;
99
+ let resolvedWorkTransferPacketId = normalizedWorkTransferPacketId;
100
+
101
+ if (hasExplicitChannel) {
102
+ const resumeSurface = typeof client.resumeTransferChannel === 'function'
103
+ ? client.resumeTransferChannel.bind(client)
104
+ : null;
105
+ if (!resumeSurface) missingSurfaces.push('resumeTransferChannel');
106
+ if (resumeSurface) {
107
+ resumedChannel = await resumeSurface({
108
+ transferChannelId: normalizedTransferChannelId,
109
+ workTransferPacketId: normalizedWorkTransferPacketId,
110
+ workflowRunId: normalizedWorkflowRunId,
111
+ participantRole: normalizedParticipantRole,
112
+ participantKind: 'agent_session',
113
+ participantLabel: normalizedParticipantRole,
114
+ agentSessionId: client.agentSessionId,
115
+ currentPhase: 'remediation',
116
+ currentTaskSummary: normalizedBlockerSummary,
117
+ lastSeenMessageId: cleanText(message_watch_id) || cleanText(messageWatchId),
118
+ metadata: {
119
+ ...normalizedMetadata,
120
+ source: 'createCrossAgentRemediationTicket',
121
+ },
122
+ });
123
+ const resumedPayload = isPlainObject(resumedChannel) ? resumedChannel : {};
124
+ resolvedTransferChannelId = cleanText(resumedPayload.transfer_channel_id)
125
+ || cleanText(resumedPayload.channel_id)
126
+ || cleanText(resumedPayload.transfer_channel?.transfer_channel_id)
127
+ || cleanText(resumedPayload.communication_transfer_channel?.transfer_channel_id)
128
+ || resolvedTransferChannelId;
129
+ resolvedWorkTransferPacketId = cleanText(resumedPayload.work_transfer_packet_id)
130
+ || cleanText(resumedPayload.work_transfer_packet?.work_transfer_packet_id)
131
+ || cleanText(resumedPayload.communication_transfer_channel?.work_transfer_packet_id)
132
+ || resolvedWorkTransferPacketId;
133
+ }
134
+ }
135
+
136
+ if (shouldMoveOwnership) {
137
+ const transferSurface = typeof client.transferWorkPacket === 'function'
138
+ ? client.transferWorkPacket.bind(client)
139
+ : null;
140
+ if (!transferSurface) missingSurfaces.push('transferWorkPacket');
141
+ if (transferSurface) {
142
+ const transferResult = await transferSurface({
143
+ workflowRunId: normalizedWorkflowRunId,
144
+ transferKind: 'upstream_remediation',
145
+ objective: normalizedBlockerSummary,
146
+ requestedOutcome: normalizedExpectedResponse,
147
+ target: {
148
+ intent: 'upstream_remediation',
149
+ recipient_mode: normalizedAssignedTo ? 'agent_session' : 'role',
150
+ preferred_agent_session_id: normalizedAssignedTo,
151
+ preferred_role_key: normalizedAssignedTo || normalizedWatcherRole,
152
+ },
153
+ artifacts: [],
154
+ issues: [],
155
+ expectedEvidence: [],
156
+ preferredModes: ['bundle', 'artifact_refs', 'inline_payload'],
157
+ capabilities: {},
158
+ senderAgentSessionId: client.agentSessionId,
159
+ senderActorSessionId: null,
160
+ subject: normalizedBlockerSummary,
161
+ bodyMarkdown: cleanText(reply_body_markdown) || cleanText(replyBodyMarkdown) || normalizedBlockerDetails,
162
+ messageKind: normalizedExpectedMessageKind,
163
+ metadata: {
164
+ ...normalizedMetadata,
165
+ source: 'createCrossAgentRemediationTicket',
166
+ source_ref: normalizedSourceRef,
167
+ assigned_to: normalizedAssignedTo,
168
+ requested_by: normalizedRequestedBy,
169
+ },
170
+ });
171
+ const transferPayload = isPlainObject(transferResult) ? transferResult : {};
172
+ resolvedWorkTransferPacketId = cleanText(transferPayload.work_transfer_packet?.work_transfer_packet_id)
173
+ || cleanText(transferPayload.work_transfer_packet_id)
174
+ || cleanText(transferPayload.transfer_packet_id)
175
+ || cleanText(transferPayload.packet_id)
176
+ || resolvedWorkTransferPacketId;
177
+ resolvedTransferChannelId = cleanText(transferPayload.communication_transfer_channel?.transfer_channel_id)
178
+ || cleanText(transferPayload.communication_transfer_channel?.channel_id)
179
+ || cleanText(transferPayload.channel_id)
180
+ || resolvedTransferChannelId;
181
+ }
182
+ }
183
+
184
+ if (!resolvedTransferChannelId) {
185
+ throw new Error('channel ownership is ambiguous.');
186
+ }
187
+ if (!resolvedWorkTransferPacketId) {
188
+ throw new Error('work_transfer_packet_id is required.');
189
+ }
190
+
191
+ const blockerSurface = typeof client.raiseCollaborationBlocker === 'function'
192
+ ? client.raiseCollaborationBlocker.bind(client)
193
+ : null;
194
+ if (!blockerSurface) missingSurfaces.push('raiseCollaborationBlocker');
195
+ const blockerResult = blockerSurface && resolvedTransferChannelId
196
+ ? await blockerSurface({
197
+ transferChannelId: resolvedTransferChannelId,
198
+ workTransferPacketId: resolvedWorkTransferPacketId,
199
+ workflowRunId: normalizedWorkflowRunId,
200
+ participantRole: normalizedParticipantRole,
201
+ blockerKind: normalizedBlockerKind,
202
+ blockerState: 'open',
203
+ blockedSide: normalizedWatcherRole,
204
+ blockerSummary: normalizedBlockerSummary,
205
+ blockerDetails: normalizedBlockerDetails,
206
+ expectedNextUpdate: normalizedExpectedResponse,
207
+ nextOwner: normalizedAssignedTo,
208
+ reviewerAgentSessionId: client.agentSessionId,
209
+ reviewerActorSessionId: null,
210
+ metadata: {
211
+ ...normalizedMetadata,
212
+ source: 'createCrossAgentRemediationTicket',
213
+ source_ref: normalizedSourceRef,
214
+ assigned_to: normalizedAssignedTo,
215
+ requested_by: normalizedRequestedBy,
216
+ },
217
+ })
218
+ : null;
219
+
220
+ const proposalIdCandidate = cleanText(collaboration_proposal_id) || cleanText(collaborationProposalId) || cleanText(proposal_id) || cleanText(proposalId);
221
+ const proposalSurface = proposalIdCandidate && typeof client.reviewCollaborationProposal === 'function'
222
+ ? client.reviewCollaborationProposal.bind(client)
223
+ : null;
224
+ if (proposalIdCandidate && !proposalSurface) missingSurfaces.push('reviewCollaborationProposal');
225
+ const proposalResult = proposalSurface && resolvedTransferChannelId
226
+ ? await proposalSurface({
227
+ transferChannelId: resolvedTransferChannelId,
228
+ collaborationProposalId: proposalIdCandidate,
229
+ decision: 'accept',
230
+ nextOwner: normalizedAssignedTo,
231
+ phase: 'remediation',
232
+ decisionReason: normalizedBlockerSummary,
233
+ evidenceRefs: normalizedReplyEvidenceRefs,
234
+ reviewerRole: normalizedParticipantRole,
235
+ reviewerAgentSessionId: client.agentSessionId,
236
+ reviewerActorSessionId: null,
237
+ reviewedByClaimId: null,
238
+ metadata: {
239
+ ...normalizedMetadata,
240
+ source: 'createCrossAgentRemediationTicket',
241
+ source_ref: normalizedSourceRef,
242
+ },
243
+ })
244
+ : null;
245
+
246
+ const watchSurface = typeof client.startMessageWatch === 'function'
247
+ ? client.startMessageWatch.bind(client)
248
+ : null;
249
+ if (!watchSurface) missingSurfaces.push('startMessageWatch');
250
+ const watchResult = watchSurface && resolvedTransferChannelId && resolvedWorkTransferPacketId
251
+ ? await watchSurface({
252
+ transferChannelId: resolvedTransferChannelId,
253
+ workTransferPacketId: resolvedWorkTransferPacketId,
254
+ workflowRunId: normalizedWorkflowRunId,
255
+ watchingAgentRole: normalizedWatcherRole,
256
+ expectedFromRole: normalizedAssignedTo || normalizedParticipantRole,
257
+ expectedMessageKind: normalizedExpectedMessageKind,
258
+ watchType: 'expected_peer_message',
259
+ watchingAgentSessionId: client.agentSessionId,
260
+ expectedPayload: {
261
+ source_ref: normalizedSourceRef,
262
+ severity: normalizedSeverity,
263
+ assigned_to: normalizedAssignedTo,
264
+ requested_by: normalizedRequestedBy,
265
+ },
266
+ currentStatus: 'watching',
267
+ operatorNudge: normalizedExpectedResponse,
268
+ metadata: {
269
+ ...normalizedMetadata,
270
+ source: 'createCrossAgentRemediationTicket',
271
+ },
272
+ })
273
+ : null;
274
+
275
+ const heartbeatSurface = typeof client.postCollaborationHeartbeat === 'function'
276
+ ? client.postCollaborationHeartbeat.bind(client)
277
+ : typeof client.postAgentHeartbeat === 'function'
278
+ ? client.postAgentHeartbeat.bind(client)
279
+ : null;
280
+ if (!heartbeatSurface) missingSurfaces.push('postCollaborationHeartbeat');
281
+ const heartbeatResult = heartbeatSurface && resolvedTransferChannelId && resolvedWorkTransferPacketId
282
+ ? await heartbeatSurface({
283
+ transferChannelId: resolvedTransferChannelId,
284
+ workTransferPacketId: resolvedWorkTransferPacketId,
285
+ workflowRunId: normalizedWorkflowRunId,
286
+ participantRole: normalizedParticipantRole,
287
+ activityState: 'active',
288
+ agentSessionId: client.agentSessionId,
289
+ currentPhase: 'remediation',
290
+ currentTaskSummary: normalizedBlockerSummary,
291
+ isActive: true,
292
+ metadata: {
293
+ ...normalizedMetadata,
294
+ source: 'createCrossAgentRemediationTicket',
295
+ },
296
+ })
297
+ : null;
298
+
299
+ const transferChannelProjectionSurface = typeof client.getTransferChannelProjection === 'function'
300
+ ? client.getTransferChannelProjection.bind(client)
301
+ : typeof client.getLogaTransferChannelThreadProjection === 'function'
302
+ ? client.getLogaTransferChannelThreadProjection.bind(client)
303
+ : null;
304
+ if (!transferChannelProjectionSurface) missingSurfaces.push('getTransferChannelProjection');
305
+ const transferChannelProjection = includeTransferChannelProjection && transferChannelProjectionSurface && resolvedTransferChannelId
306
+ ? await transferChannelProjectionSurface(resolvedTransferChannelId).catch(() => null)
307
+ : null;
308
+
309
+ const blockerPayload = isPlainObject(blockerResult) ? blockerResult : {};
310
+ const proposalPayload = isPlainObject(proposalResult) ? proposalResult : {};
311
+ const watchPayload = isPlainObject(watchResult) ? watchResult : {};
312
+ const heartbeatPayload = isPlainObject(heartbeatResult) ? heartbeatResult : {};
313
+ const blockerRecord = isPlainObject(blockerPayload.collaboration_blocker)
314
+ ? blockerPayload.collaboration_blocker
315
+ : blockerPayload;
316
+ const watchRecord = isPlainObject(watchPayload.message_watch)
317
+ ? watchPayload.message_watch
318
+ : watchPayload;
319
+ const heartbeatRecord = isPlainObject(heartbeatPayload.collaboration_heartbeat)
320
+ ? heartbeatPayload.collaboration_heartbeat
321
+ : heartbeatPayload;
322
+
323
+ const blockerRecordId = cleanText(blockerRecord.collaboration_blocker_id)
324
+ || cleanText(blockerRecord.blocker_id)
325
+ || cleanText(blockerPayload.collaboration_blocker_id)
326
+ || cleanText(blockerPayload.blocker_id)
327
+ || null;
328
+ const remediationTicketId = cleanText(transferChannelProjection?.remediation_ticket_id)
329
+ || cleanText(transferChannelProjection?.work_transfer_packet_id)
330
+ || cleanText(transferChannelProjection?.transfer_packet_id)
331
+ || resolvedWorkTransferPacketId
332
+ || null;
333
+ const watchId = cleanText(watchRecord.message_watch_id)
334
+ || cleanText(watchRecord.watch_id)
335
+ || null;
336
+ const heartbeatStatus = cleanText(heartbeatRecord.activity_state)
337
+ || cleanText(heartbeatRecord.status)
338
+ || 'active';
339
+ const waitingSide = cleanText(watchRecord.waiting_side)
340
+ || cleanText(blockerRecord.blocked_side)
341
+ || cleanText(proposalPayload.next_owner)
342
+ || normalizedWatcherRole;
343
+ const expectedResponseText = cleanText(blockerRecord.expected_next_update)
344
+ || cleanText(watchRecord.expected_message_kind)
345
+ || cleanText(heartbeatRecord.expected_message_kind)
346
+ || normalizedExpectedResponse;
347
+ const status = missingSurfaces.length > 0 ? 'partial' : 'ready';
348
+ const operatorProjectionMetadata = includeOperatorProjectionMetadata
349
+ ? {
350
+ transfer_channel_projection: transferChannelProjection,
351
+ blocker: blockerPayload,
352
+ proposal: proposalPayload,
353
+ message_watch: watchPayload,
354
+ heartbeat: heartbeatPayload,
355
+ }
356
+ : null;
357
+
358
+ return {
359
+ status,
360
+ remediation_ticket_id: remediationTicketId,
361
+ blocker_id: blockerRecordId,
362
+ channel_id: resolvedTransferChannelId || null,
363
+ transfer_packet_id: resolvedWorkTransferPacketId || null,
364
+ assigned_to: normalizedAssignedTo,
365
+ requested_by: normalizedRequestedBy,
366
+ severity: normalizedSeverity,
367
+ source_ref: normalizedSourceRef,
368
+ expected_response: expectedResponseText,
369
+ watch_id: watchId,
370
+ heartbeat_status: heartbeatStatus,
371
+ operator_projection_metadata: operatorProjectionMetadata,
372
+ missing_surfaces: [...new Set(missingSurfaces)],
373
+ resume_channel: resumedChannel,
374
+ blocker: blockerPayload,
375
+ proposal: proposalPayload,
376
+ watch: watchPayload,
377
+ heartbeat: heartbeatPayload,
378
+ };
379
+ }
@@ -139,6 +139,12 @@ export function createDatabaseDomain(client) {
139
139
  limit,
140
140
  },
141
141
  }),
142
+ describeDatabaseCatalog: ({ includeSystemSchemas, limit } = {}) => client.database.schema.getOverview({ includeSystemSchemas, limit }),
143
+ listDatabaseSchemas: ({ includeSystemSchemas, limit } = {}) => client.database.schema.listSchemas({ includeSystemSchemas, limit }),
144
+ listDatabaseTables: ({ schemaName, includeSystemSchemas, limit } = {}) => client.database.schema.listTables({ schemaName, includeSystemSchemas, limit }),
145
+ listDatabaseColumns: ({ schemaName, tableName } = {}) => client.database.schema.listColumns({ schemaName, tableName }),
146
+ listDatabaseIndexes: ({ schemaName, tableName, includeSystemSchemas, limit } = {}) => client.database.schema.listIndexes({ schemaName, tableName, includeSystemSchemas, limit }),
147
+ describeDatabaseTable: ({ schemaName, tableName, includeSystemSchemas } = {}) => client.database.schema.describeTable({ schemaName, tableName, includeSystemSchemas }),
142
148
  backups: createDatabaseBackupsDomain(client),
143
149
  schema: createDatabaseSchemaDomain(client),
144
150
  };
@@ -0,0 +1,30 @@
1
+ export function createExternalAudioDomain(client) {
2
+ return {
3
+ createExternalAudioRender: (request) => createExternalAudioRender(client, request),
4
+ getExternalAudioRender: (audioRenderRunId) => getExternalAudioRender(client, audioRenderRunId),
5
+ downloadExternalAudioRender: (audioRenderRunId) => downloadExternalAudioRender(client, audioRenderRunId),
6
+ };
7
+ }
8
+
9
+ export async function createExternalAudioRender(client, { text, voice, model, speed, file } = {}) {
10
+ if (file) {
11
+ const form = new FormData();
12
+ form.append('file', file);
13
+ if (voice !== undefined) form.append('voice', String(voice));
14
+ if (model !== undefined) form.append('model', String(model));
15
+ if (speed !== undefined) form.append('speed', String(speed));
16
+ return client._request('/api/v1/audio-renders', { method: 'POST', body: form });
17
+ }
18
+ return client._request('/api/v1/audio-renders', {
19
+ method: 'POST',
20
+ body: { text, voice, model, speed },
21
+ });
22
+ }
23
+
24
+ export async function getExternalAudioRender(client, audioRenderRunId) {
25
+ return client._request(`/api/v1/audio-renders/${audioRenderRunId}`);
26
+ }
27
+
28
+ export async function downloadExternalAudioRender(client, audioRenderRunId) {
29
+ return client._requestBinary(`/api/v1/audio-renders/${audioRenderRunId}/download`);
30
+ }
@@ -0,0 +1,29 @@
1
+ export function createExternalProjectsDomain(client) {
2
+ return {
3
+ getExternalProjectStatus: (projectId) => getExternalProjectStatus(client, projectId),
4
+ getExternalProjectRoadmapSummary: (projectId) => getExternalProjectRoadmapSummary(client, projectId),
5
+ getExternalProjectRoadmapActiveItem: (projectId) => getExternalProjectRoadmapActiveItem(client, projectId),
6
+ listExternalProjectOpenTasks: (projectId) => listExternalProjectOpenTasks(client, projectId),
7
+ getExternalProjectStatusBundle: (projectId) => getExternalProjectStatusBundle(client, projectId),
8
+ };
9
+ }
10
+
11
+ export async function getExternalProjectStatus(client, projectId) {
12
+ return client._request(`/api/v1/projects/${projectId}/status`);
13
+ }
14
+
15
+ export async function getExternalProjectRoadmapSummary(client, projectId) {
16
+ return client._request(`/api/v1/projects/${projectId}/implementation-roadmap/summary`);
17
+ }
18
+
19
+ export async function getExternalProjectRoadmapActiveItem(client, projectId) {
20
+ return client._request(`/api/v1/projects/${projectId}/implementation-roadmap/active-item`);
21
+ }
22
+
23
+ export async function listExternalProjectOpenTasks(client, projectId) {
24
+ return client._request(`/api/v1/projects/${projectId}/open-tasks`);
25
+ }
26
+
27
+ export async function getExternalProjectStatusBundle(client, projectId) {
28
+ return client._request(`/api/v1/projects/${projectId}/status-bundle`);
29
+ }
@@ -0,0 +1,14 @@
1
+ export function createExternalWorkflowArtifactsDomain(client) {
2
+ return {
3
+ listExternalWorkflowRunArtifacts: (workflowRunId) => listExternalWorkflowRunArtifacts(client, workflowRunId),
4
+ downloadExternalWorkflowRunArtifact: (workflowRunId, artifactType) => downloadExternalWorkflowRunArtifact(client, workflowRunId, artifactType),
5
+ };
6
+ }
7
+
8
+ export async function listExternalWorkflowRunArtifacts(client, workflowRunId) {
9
+ return client._request(`/api/v1/runs/${workflowRunId}/artifacts`);
10
+ }
11
+
12
+ export async function downloadExternalWorkflowRunArtifact(client, workflowRunId, artifactType) {
13
+ return client._requestBinary(`/api/v1/runs/${workflowRunId}/artifacts/${artifactType}/download`);
14
+ }
@@ -4,6 +4,7 @@ export function createMessageWatchDomain(client) {
4
4
  return {
5
5
  startMessageWatch: (request) => startMessageWatch(client, request),
6
6
  acknowledgeExpectedMessage: (request) => acknowledgeExpectedMessage(client, request),
7
+ acknowledgeAgentMessage: (request) => acknowledgeAgentMessage(client, request),
7
8
  expireMessageWatch: (request) => expireMessageWatch(client, request),
8
9
  respondToMessageWatch: (request) => respondToMessageWatch(client, request),
9
10
  acceptAgentChannel: (request) => acceptAgentChannel(client, request),
@@ -151,6 +152,40 @@ export async function acknowledgeExpectedMessage(client, {
151
152
  });
152
153
  }
153
154
 
155
+ export async function acknowledgeAgentMessage(client, {
156
+ transferChannelId,
157
+ transfer_channel_id,
158
+ channelId,
159
+ channel_id,
160
+ messageWatchId,
161
+ message_watch_id,
162
+ watchId,
163
+ watch_id,
164
+ messageId,
165
+ message_id,
166
+ messageKind,
167
+ message_kind,
168
+ observedMessageId,
169
+ observed_message_id,
170
+ observedMessageKind,
171
+ observed_message_kind,
172
+ operatorNudge,
173
+ operator_nudge,
174
+ metadata = {},
175
+ } = {}) {
176
+ const normalizedWatchId = cleanText(message_watch_id) || cleanText(messageWatchId) || cleanText(watch_id) || cleanText(watchId) || await resolveMessageWatchId(client, { transfer_channel_id, transferChannelId, channel_id, channelId });
177
+ if (!normalizedWatchId) throw new Error('message_watch_id is required.');
178
+ return client._request(`/api/agent-communications/message-watches/${encodeURIComponent(normalizedWatchId)}/acknowledge-message`, {
179
+ method: 'POST',
180
+ body: {
181
+ observed_message_id: cleanText(observed_message_id) || cleanText(observedMessageId) || cleanText(message_id) || cleanText(messageId),
182
+ observed_message_kind: cleanText(observed_message_kind) || cleanText(observedMessageKind) || cleanText(message_kind) || cleanText(messageKind),
183
+ operator_nudge: cleanText(operator_nudge) || cleanText(operatorNudge),
184
+ metadata: isPlainObject(metadata) ? metadata : {},
185
+ },
186
+ });
187
+ }
188
+
154
189
  export async function expireMessageWatch(client, {
155
190
  messageWatchId,
156
191
  message_watch_id,
@@ -1,18 +1,6 @@
1
1
  import { AI_ENGINE_CLIENT_VERSION } from '../constants/client.js';
2
2
  import { cleanText, isPlainObject } from '../utils/communication.js';
3
-
4
- function compareSemanticVersions(left, right) {
5
- const leftParts = String(left || '').split('.').map((part) => Number.parseInt(part, 10) || 0);
6
- const rightParts = String(right || '').split('.').map((part) => Number.parseInt(part, 10) || 0);
7
- const width = Math.max(leftParts.length, rightParts.length);
8
- for (let index = 0; index < width; index += 1) {
9
- const a = leftParts[index] || 0;
10
- const b = rightParts[index] || 0;
11
- if (a > b) return 1;
12
- if (a < b) return -1;
13
- }
14
- return 0;
15
- }
3
+ import { compareSemanticVersions } from '../utils/version.js';
16
4
 
17
5
  function buildEligibilityError(message, details = {}) {
18
6
  const error = new Error(message);