@bpmsoftwaresolutions/ai-engine-client 1.1.92 → 1.1.97

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/src/client.js CHANGED
@@ -56,6 +56,7 @@ import { createWorkflowTurnsDomain } from './domains/workflow-turns.js';
56
56
  import { createChartersDomain } from './domains/charters.js';
57
57
  import { createWorkStartDomain } from './domains/work-start.js';
58
58
  import { createCollaborationDomain } from './domains/collaboration.js';
59
+ import { createAgentCommunicationsDomain } from './domains/agent-communications.js';
59
60
  import { createMessageWatchDomain } from './domains/message-watch.js';
60
61
  import { createPingPongDomain } from './domains/ping-pong.js';
61
62
  import { createPresenceDomain } from './domains/presence.js';
@@ -324,6 +325,7 @@ export class AIEngineClient {
324
325
  this.messageWatch = createMessageWatchDomain(this);
325
326
  this.presence = createPresenceDomain(this);
326
327
  this.pingPong = createPingPongDomain(this);
328
+ this.agentCommunications = createAgentCommunicationsDomain(this);
327
329
  this.collaborationDomain = createCollaborationDomain(this);
328
330
  this.agentComms = createAgentCommunicationsFacade(this);
329
331
  this.collaboration = createCollaborationFacade(this);
@@ -381,131 +383,7 @@ export class AIEngineClient {
381
383
  operator_nudge,
382
384
  metadata = {},
383
385
  } = {}) {
384
- const normalizedFirstMessage = isPlainObject(firstMessage) ? firstMessage : isPlainObject(first_message) ? first_message : {};
385
- const normalizedTransferKind = normalizeTransferKind(cleanText(mode) || 'handoff');
386
- let normalizedWorkflowRunId = cleanText(workflow_run_id) || cleanText(workflowRunId);
387
- if (!normalizedWorkflowRunId) {
388
- try {
389
- const status = await this.currentWorkflowStatus();
390
- normalizedWorkflowRunId =
391
- cleanText(status?.workflow_run_id)
392
- || cleanText(status?.workflowRunId)
393
- || cleanText(status?.current_workflow_run_id)
394
- || cleanText(status?.currentWorkflowRunId)
395
- || cleanText(status?.summary?.workflow_run_id)
396
- || cleanText(status?.summary?.workflowRunId)
397
- || cleanText(status?.summary?.current_workflow_run_id)
398
- || cleanText(status?.summary?.currentWorkflowRunId);
399
- } catch (error) {
400
- void error;
401
- }
402
- }
403
- if (!normalizedWorkflowRunId) {
404
- throw new Error('workflow_run_id is required to start an agent connection.');
405
- }
406
- const normalizedUpstreamAgent = cleanText(upstream_agent) || cleanText(upstreamAgent) || cleanText(upstream_agent_session_id) || cleanText(upstreamAgentSessionId) || cleanText(upstream_agent_id) || cleanText(upstreamAgentId);
407
- const normalizedRecipientMode = cleanText(recipient_mode) || cleanText(recipientMode) || (normalizedUpstreamAgent ? 'agent_session' : 'role');
408
- const normalizedParticipantRole = cleanText(participant_role) || cleanText(participantRole) || 'downstream';
409
- const normalizedParticipantLabel = cleanText(participant_label) || cleanText(participantLabel) || normalizedParticipantRole;
410
- const normalizedSenderAgentSessionId = cleanText(sender_agent_session_id) || cleanText(senderAgentSessionId) || this.agentSessionId;
411
- const normalizedSenderActorSessionId = cleanText(sender_actor_session_id) || cleanText(senderActorSessionId);
412
- const normalizedFirstMessageKind = normalizeConnectionFirstMessageKind(
413
- cleanText(normalizedFirstMessage.kind) || cleanText(normalizedFirstMessage.message_kind) || cleanText(normalizedFirstMessage.messageKind),
414
- normalizedTransferKind,
415
- );
416
- const normalizedExpectedMessageKind = cleanText(expected_message_kind) || cleanText(expectedMessageKind) || 'connection_accepted';
417
- const normalizedObjective = cleanText(objective) || cleanText(purpose) || cleanText(normalizedFirstMessage.body) || cleanText(normalizedFirstMessage.body_markdown) || cleanText(normalizedFirstMessage.bodyMarkdown) || 'Establish governed coordination.';
418
- const transferResult = await this.transferWorkPacket({
419
- workflowRunId: normalizedWorkflowRunId,
420
- transferKind: normalizedTransferKind,
421
- objective: normalizedObjective,
422
- requestedOutcome: cleanText(purpose) || normalizedObjective,
423
- target: {
424
- intent: normalizedTransferKind,
425
- recipient_mode: normalizedRecipientMode,
426
- preferred_agent_session_id: normalizedUpstreamAgent,
427
- preferred_role_key: cleanText(upstream_role) || cleanText(upstreamRole),
428
- },
429
- artifacts: [],
430
- issues: [],
431
- expectedEvidence: [],
432
- preferredModes: ['inline_payload', 'bundle', 'artifact_refs'],
433
- capabilities: {},
434
- senderAgentSessionId: normalizedSenderAgentSessionId,
435
- senderActorSessionId: normalizedSenderActorSessionId,
436
- subject: cleanText(purpose) || normalizedObjective,
437
- bodyMarkdown:
438
- cleanText(normalizedFirstMessage.body_markdown)
439
- || cleanText(normalizedFirstMessage.bodyMarkdown)
440
- || cleanText(normalizedFirstMessage.body)
441
- || `Connection request: ${normalizedObjective}`,
442
- cleanupPolicy: cleanText(cleanup_policy) || cleanText(cleanupPolicy),
443
- messageKind: normalizedFirstMessageKind,
444
- message_kind: normalizedFirstMessageKind,
445
- metadata: isPlainObject(metadata) ? metadata : {},
446
- });
447
- const transferChannel = transferResult.communication_transfer_channel || {};
448
- const connection = await this.connectToTransferChannel({
449
- transferChannelId: transferChannel.transfer_channel_id || transferChannel.channel_id || transferResult.channel_id,
450
- workTransferPacketId: transferResult.work_transfer_packet?.work_transfer_packet_id || transferResult.packet_id || transferResult.transfer_packet_id,
451
- workflowRunId: normalizedWorkflowRunId,
452
- participantRole: normalizedParticipantRole,
453
- expectedPeerRole: cleanText(upstream_role) || cleanText(upstreamRole) || 'upstream',
454
- expectedMessageKind: normalizedExpectedMessageKind,
455
- proposalId: transferResult.transfer_negotiation?.proposal_id,
456
- mode: 'communication_participant',
457
- participantLabel: normalizedParticipantLabel,
458
- senderAgentSessionId: normalizedSenderAgentSessionId,
459
- senderActorSessionId: normalizedSenderActorSessionId,
460
- currentPhase: 'channel_ready',
461
- currentTaskSummary: cleanText(purpose) || normalizedObjective,
462
- expectedPayload: {
463
- purpose: cleanText(purpose) || normalizedObjective,
464
- first_message_kind: normalizedFirstMessageKind,
465
- first_message_body:
466
- cleanText(normalizedFirstMessage.body_markdown)
467
- || cleanText(normalizedFirstMessage.bodyMarkdown)
468
- || cleanText(normalizedFirstMessage.body)
469
- || null,
470
- },
471
- lastSeenMessageId: transferResult.communication_message?.agent_message_id,
472
- staleAfterSeconds: stale_after_seconds ?? staleAfterSeconds,
473
- operatorNudge:
474
- cleanText(operator_nudge)
475
- || cleanText(operatorNudge)
476
- || `upstream, please send ${normalizedExpectedMessageKind}.`,
477
- observedAt: transferResult.communication_message?.created_at || transferResult.transfer_receipt?.created_at,
478
- metadata: {
479
- ...(isPlainObject(metadata) ? metadata : {}),
480
- start_agent_connection: true,
481
- },
482
- });
483
- const handshake = connection.handshake || {};
484
- const status = connection.connected ? 'waiting' : (connection.stop_reason ? 'failed' : 'waiting');
485
- const transferPacketId = transferResult.work_transfer_packet?.work_transfer_packet_id || transferResult.transfer_receipt?.transfer_packet_id || transferResult.packet_id || null;
486
- const channelId = connection.channel_id || transferChannel.transfer_channel_id || transferChannel.channel_id || null;
487
- return {
488
- status,
489
- channel_id: channelId,
490
- transfer_packet_id: transferPacketId,
491
- correlation_id: connection.correlation_id || handshake.correlation_id || null,
492
- handshake_state: connection.handshake_state || handshake.handshake_state || null,
493
- waiting_side: connection.waiting_on || connection.expected_from || handshake.waiting_side || null,
494
- expected_message: connection.expected_message_kind || handshake.expected_message_kind || normalizedExpectedMessageKind,
495
- last_heartbeat_at: handshake.last_heartbeat_at || connection.collaboration_heartbeat?.observed_at || null,
496
- last_receipt_id: handshake.last_receipt_id || transferResult.transfer_receipt?.receipt_id || null,
497
- operator_nudge: connection.operator_nudge || handshake.operator_nudge || null,
498
- handshake,
499
- connection,
500
- transfer: transferResult,
501
- first_message: {
502
- kind: normalizedFirstMessageKind,
503
- body: cleanText(normalizedFirstMessage.body_markdown) || cleanText(normalizedFirstMessage.bodyMarkdown) || cleanText(normalizedFirstMessage.body) || null,
504
- },
505
- transfer_channel: transferChannel,
506
- transfer_receipt: transferResult.transfer_receipt || null,
507
- communication_message: transferResult.communication_message || null,
508
- };
386
+ return this.agentCommunications.startAgentConnection(arguments[0]);
509
387
  }
510
388
 
511
389
  async establishAgentCommunicationChannel({
@@ -563,300 +441,7 @@ export class AIEngineClient {
563
441
  includeOperatorProjectionMetadata = true,
564
442
  metadata = {},
565
443
  } = {}) {
566
- const missingSurfaces = [];
567
- const explicitProjectReference = cleanText(projectIdentifier) || cleanText(projectId);
568
- const actorIdentity = cleanText(actorId) || this.actorId;
569
- const normalizedExecutionIntent = cleanText(executionIntent) || 'establish agent communication channel';
570
- const normalizedParticipantRole = cleanText(participant_role) || cleanText(participantRole) || 'downstream';
571
- const normalizedParticipantLabel = cleanText(participant_label) || cleanText(participantLabel) || normalizedParticipantRole;
572
- const normalizedParticipantKind = cleanText(participant_kind) || cleanText(participantKind) || (
573
- cleanText(agent_session_id)
574
- || cleanText(agentSessionId)
575
- || cleanText(downstream_agent_session_id)
576
- || cleanText(downstreamAgentSessionId)
577
- || cleanText(upstream_agent_session_id)
578
- || cleanText(upstreamAgentSessionId)
579
- ) ? 'agent_session' : 'role';
580
- const normalizedExpectedMessageKind = cleanText(expected_message_kind) || cleanText(expectedMessageKind) || cleanText(expected_next_message) || cleanText(expectedNextMessage) || 'connection_accepted';
581
- const normalizedCurrentPhase = cleanText(current_phase) || cleanText(currentPhase) || 'channel_ready';
582
- const normalizedCurrentTaskSummary = cleanText(current_task_summary) || cleanText(currentTaskSummary) || normalizedExecutionIntent;
583
- const normalizedObjective = cleanText(objective) || cleanText(requestedOutcome) || normalizedExecutionIntent;
584
- const normalizedChannelKind = cleanText(channel_kind) || cleanText(channelKind) || 'bidirectional';
585
- const normalizedMetadata = isPlainObject(metadata) ? metadata : {};
586
- const hasExplicitChannelReference = Boolean(
587
- cleanText(transfer_channel_id)
588
- || cleanText(transferChannelId)
589
- || cleanText(channel_id)
590
- || cleanText(channelId)
591
- );
592
-
593
- let continuation = null;
594
- let startWorkResult = null;
595
- if (explicitProjectReference) {
596
- if (typeof this.resumeProjectWork !== 'function') {
597
- missingSurfaces.push('resumeProjectWork');
598
- } else {
599
- continuation = await this.resumeProjectWork({
600
- projectIdentifier: explicitProjectReference,
601
- projectId: explicitProjectReference,
602
- actorMode,
603
- executionIntent: normalizedExecutionIntent,
604
- requireClaim: false,
605
- workflowRunLimit,
606
- ...normalizedMetadata.resume_project_work_options,
607
- ...resumeProjectWorkOptions,
608
- });
609
- }
610
- } else if (Object.keys(isPlainObject(startWorkRequest) ? startWorkRequest : {}).length > 0 || Object.keys(isPlainObject(startWorkBody) ? startWorkBody : {}).length > 0) {
611
- if (typeof this.startWork !== 'function') {
612
- missingSurfaces.push('startWork');
613
- } else {
614
- startWorkResult = await this.startWork({
615
- ...(isPlainObject(startWorkBody) ? startWorkBody : {}),
616
- ...(isPlainObject(startWorkRequest) ? startWorkRequest : {}),
617
- });
618
- }
619
- } else {
620
- throw new Error('projectIdentifier is required.');
621
- }
622
-
623
- const projectPayload = isPlainObject(continuation?.project)
624
- ? continuation.project
625
- : isPlainObject(startWorkResult?.project)
626
- ? startWorkResult.project
627
- : isPlainObject(continuation?.summary)
628
- ? continuation.summary
629
- : {};
630
- const resolvedProjectId = cleanText(projectPayload.project_id) || cleanText(projectPayload.projectId) || explicitProjectReference;
631
- const resolvedWorkflowId = cleanText(projectPayload.workflow_id) || cleanText(projectPayload.workflowId) || cleanText(continuation?.workflow_id) || cleanText(startWorkResult?.workflow_id);
632
- const resolvedWorkflowRunId = cleanText(projectPayload.workflow_run_id) || cleanText(projectPayload.workflowRunId) || cleanText(continuation?.workflow_run_id) || cleanText(startWorkResult?.workflow_run_id) || cleanText(startWorkResult?.workflowRunId);
633
- if (!resolvedProjectId || !resolvedWorkflowRunId) {
634
- throw new Error('project/work identifiers are ambiguous.');
635
- }
636
-
637
- const transferPacket = await this.transferWorkPacket({
638
- workflowRunId: resolvedWorkflowRunId,
639
- transferKind,
640
- objective: normalizedObjective,
641
- requestedOutcome: normalizedObjective,
642
- target: {
643
- intent: transferKind,
644
- recipient_mode: normalizedParticipantKind === 'agent_session' ? 'agent_session' : 'role',
645
- preferred_agent_session_id: cleanText(downstream_agent_session_id) || cleanText(downstreamAgentSessionId) || cleanText(upstream_agent_session_id) || cleanText(upstreamAgentSessionId) || cleanText(agent_session_id) || cleanText(agentSessionId),
646
- preferred_role_key: normalizedParticipantRole,
647
- },
648
- artifacts: [],
649
- issues: [],
650
- expectedEvidence: [],
651
- preferredModes: ['inline_payload', 'bundle', 'artifact_refs'],
652
- capabilities: {},
653
- senderAgentSessionId: cleanText(agent_session_id) || cleanText(agentSessionId) || this.agentSessionId,
654
- senderActorSessionId: cleanText(actor_session_id) || cleanText(actorSessionId),
655
- subject: normalizedObjective,
656
- bodyMarkdown: normalizedCurrentTaskSummary,
657
- messageKind: normalizedExpectedMessageKind,
658
- metadata: {
659
- ...normalizedMetadata,
660
- source: 'establishAgentCommunicationChannel',
661
- project_id: resolvedProjectId,
662
- workflow_id: resolvedWorkflowId,
663
- workflow_run_id: resolvedWorkflowRunId,
664
- },
665
- });
666
- const normalizedTransferPacket = isPlainObject(transferPacket) ? transferPacket : {};
667
- const transferChannel = isPlainObject(normalizedTransferPacket.communication_transfer_channel)
668
- ? normalizedTransferPacket.communication_transfer_channel
669
- : {};
670
- const resolvedTransferPacketId = cleanText(work_transfer_packet_id)
671
- || cleanText(workTransferPacketId)
672
- || cleanText(packet_id)
673
- || cleanText(packetId)
674
- || cleanText(normalizedTransferPacket.work_transfer_packet?.work_transfer_packet_id)
675
- || cleanText(normalizedTransferPacket.transfer_packet_id)
676
- || cleanText(normalizedTransferPacket.packet_id);
677
- const resolvedTransferChannelId = cleanText(transfer_channel_id)
678
- || cleanText(transferChannelId)
679
- || cleanText(channel_id)
680
- || cleanText(channelId)
681
- || cleanText(transferChannel.transfer_channel_id)
682
- || cleanText(transferChannel.channel_id);
683
-
684
- if (!resolvedTransferPacketId) {
685
- throw new Error('transfer packet could not be established.');
686
- }
687
- if (!resolvedTransferChannelId) {
688
- throw new Error('channel ownership is ambiguous.');
689
- }
690
-
691
- const openChannelSurface = typeof this.openTransferChannel === 'function'
692
- ? this.openTransferChannel.bind(this)
693
- : typeof this.openAgentChannel === 'function'
694
- ? this.openAgentChannel.bind(this)
695
- : typeof this.connectToTransferChannel === 'function'
696
- ? this.connectToTransferChannel.bind(this)
697
- : null;
698
- if (!openChannelSurface) missingSurfaces.push('openTransferChannel');
699
- const openChannel = openChannelSurface
700
- ? await openChannelSurface({
701
- transferChannelId: resolvedTransferChannelId,
702
- workTransferPacketId: resolvedTransferPacketId,
703
- workflowRunId: resolvedWorkflowRunId,
704
- channelKind: normalizedChannelKind,
705
- upstreamAgentSessionId: cleanText(upstream_agent_session_id) || cleanText(upstreamAgentSessionId),
706
- upstreamActorSessionId: cleanText(upstream_actor_session_id) || cleanText(upstreamActorSessionId),
707
- downstreamAgentSessionId: cleanText(downstream_agent_session_id) || cleanText(downstreamAgentSessionId) || cleanText(agent_session_id) || cleanText(agentSessionId) || this.agentSessionId,
708
- downstreamActorSessionId: cleanText(downstream_actor_session_id) || cleanText(downstreamActorSessionId) || cleanText(actor_session_id) || cleanText(actorSessionId),
709
- evidenceRequiredForClosure: true,
710
- metadata: {
711
- ...normalizedMetadata,
712
- source: 'establishAgentCommunicationChannel',
713
- project_id: resolvedProjectId,
714
- workflow_id: resolvedWorkflowId,
715
- workflow_run_id: resolvedWorkflowRunId,
716
- },
717
- })
718
- : null;
719
- const openChannelPayload = isPlainObject(openChannel?.transfer_channel)
720
- ? openChannel.transfer_channel
721
- : isPlainObject(openChannel?.collaboration_participant)
722
- ? openChannel.collaboration_participant
723
- : isPlainObject(openChannel)
724
- ? openChannel
725
- : {};
726
- const openedChannelId = cleanText(openChannelPayload.transfer_channel_id) || cleanText(openChannelPayload.channel_id) || resolvedTransferChannelId;
727
-
728
- const joinSurfaceName = hasExplicitChannelReference ? 'resumeTransferChannel' : 'joinTransferChannel';
729
- const joinSurface = typeof this[joinSurfaceName] === 'function'
730
- ? this[joinSurfaceName].bind(this)
731
- : typeof this.joinTransferChannel === 'function'
732
- ? this.joinTransferChannel.bind(this)
733
- : typeof this.resumeTransferChannel === 'function'
734
- ? this.resumeTransferChannel.bind(this)
735
- : null;
736
- if (!joinSurface) missingSurfaces.push(joinSurfaceName);
737
- const participantRecord = joinSurface
738
- ? await joinSurface({
739
- transferChannelId: openedChannelId,
740
- workTransferPacketId: resolvedTransferPacketId,
741
- workflowRunId: resolvedWorkflowRunId,
742
- participantRole: normalizedParticipantRole,
743
- participantKind: normalizedParticipantKind,
744
- participantLabel: normalizedParticipantLabel,
745
- agentSessionId: cleanText(agent_session_id) || cleanText(agentSessionId) || this.agentSessionId,
746
- actorSessionId: cleanText(actor_session_id) || cleanText(actorSessionId),
747
- currentPhase: normalizedCurrentPhase,
748
- currentTaskSummary: normalizedCurrentTaskSummary,
749
- lastSeenMessageId: cleanText(normalizedTransferPacket.communication_message?.agent_message_id),
750
- lastSeenAt: cleanText(normalizedTransferPacket.communication_message?.created_at) || cleanText(openChannel?.created_at),
751
- lastSeenHeartbeatAt: cleanText(openChannel?.heartbeat?.observed_at) || cleanText(openChannel?.collaboration_heartbeat?.observed_at),
752
- metadata: {
753
- ...normalizedMetadata,
754
- source: 'establishAgentCommunicationChannel',
755
- project_id: resolvedProjectId,
756
- workflow_id: resolvedWorkflowId,
757
- workflow_run_id: resolvedWorkflowRunId,
758
- },
759
- })
760
- : null;
761
-
762
- const heartbeatSurface = typeof this.postCollaborationHeartbeat === 'function'
763
- ? this.postCollaborationHeartbeat.bind(this)
764
- : typeof this.postAgentHeartbeat === 'function'
765
- ? this.postAgentHeartbeat.bind(this)
766
- : null;
767
- if (!heartbeatSurface) missingSurfaces.push('postCollaborationHeartbeat');
768
- const heartbeat = heartbeatSurface
769
- ? await heartbeatSurface({
770
- transferChannelId: openedChannelId,
771
- workTransferPacketId: resolvedTransferPacketId,
772
- workflowRunId: resolvedWorkflowRunId,
773
- participantRole: normalizedParticipantRole,
774
- activityState: 'active',
775
- agentSessionId: cleanText(agent_session_id) || cleanText(agentSessionId) || this.agentSessionId,
776
- actorSessionId: cleanText(actor_session_id) || cleanText(actorSessionId),
777
- currentPhase: normalizedCurrentPhase,
778
- currentTaskSummary: normalizedCurrentTaskSummary,
779
- isActive: true,
780
- observedAt: cleanText(normalizedTransferPacket.communication_message?.created_at) || cleanText(openChannel?.created_at),
781
- metadata: {
782
- ...normalizedMetadata,
783
- source: 'establishAgentCommunicationChannel',
784
- project_id: resolvedProjectId,
785
- workflow_id: resolvedWorkflowId,
786
- workflow_run_id: resolvedWorkflowRunId,
787
- },
788
- })
789
- : null;
790
-
791
- const status = await this.getCommunicationChannelStatus({ transferChannelId: openedChannelId }).catch(() => null);
792
- const participants = await this.getCommunicationChannelParticipants({ transferChannelId: openedChannelId }).catch(() => null);
793
- const transferChannelProjectionSurface = typeof this.getTransferChannelProjection === 'function'
794
- ? this.getTransferChannelProjection.bind(this)
795
- : typeof this.getLogaTransferChannelThreadProjection === 'function'
796
- ? this.getLogaTransferChannelThreadProjection.bind(this)
797
- : null;
798
- if (!transferChannelProjectionSurface) missingSurfaces.push('getTransferChannelProjection');
799
- const transferChannelProjection = includeTransferChannelProjection && transferChannelProjectionSurface
800
- ? await transferChannelProjectionSurface(openedChannelId).catch(() => null)
801
- : null;
802
- const channelPresence = includeChannelPresenceProjection
803
- ? await this.getChannelPresence({ transferChannelId: openedChannelId }).catch(() => null)
804
- : null;
805
-
806
- const statusPayload = isPlainObject(status) ? status : {};
807
- const participantPayload = isPlainObject(participants) ? participants : {};
808
- const participantRows = Array.isArray(participantPayload.participants)
809
- ? participantPayload.participants.filter((row) => isPlainObject(row))
810
- : Array.isArray(participantPayload.collaboration_participants)
811
- ? participantPayload.collaboration_participants.filter((row) => isPlainObject(row))
812
- : [];
813
- const waitingSide = cleanText(statusPayload.waiting_side)
814
- || cleanText(statusPayload.operator_state?.waiting_side)
815
- || cleanText(openChannel?.waiting_side)
816
- || cleanText(heartbeat?.waiting_side)
817
- || null;
818
- const nextMessage = cleanText(statusPayload.next_message_kind)
819
- || cleanText(statusPayload.expected_message_kind)
820
- || cleanText(statusPayload.next_action)
821
- || cleanText(openChannel?.expected_message_kind)
822
- || cleanText(heartbeat?.expected_message_kind)
823
- || normalizedExpectedMessageKind;
824
- const heartbeatStatus = cleanText(heartbeat?.collaboration_heartbeat?.activity_state)
825
- || cleanText(heartbeat?.activity_state)
826
- || cleanText(heartbeat?.status)
827
- || 'active';
828
-
829
- const operatorProjectionMetadata = includeOperatorProjectionMetadata
830
- ? {
831
- transfer_channel_projection: transferChannelProjection,
832
- channel_status: statusPayload,
833
- channel_participants: participantPayload,
834
- channel_presence: channelPresence,
835
- }
836
- : null;
837
-
838
- const established = Boolean(openedChannelId && resolvedTransferPacketId && heartbeat);
839
- return {
840
- status: missingSurfaces.length > 0 ? 'partial' : established ? 'ready' : 'blocked',
841
- project_id: resolvedProjectId,
842
- workflow_id: resolvedWorkflowId,
843
- workflow_run_id: resolvedWorkflowRunId,
844
- transfer_packet_id: resolvedTransferPacketId,
845
- channel_id: openedChannelId,
846
- participants: participantRows.length > 0 ? participantRows : [participantRecord].filter(Boolean),
847
- waiting_side: waitingSide,
848
- expected_next_message: nextMessage,
849
- heartbeat_status: heartbeatStatus,
850
- operator_projection_metadata: operatorProjectionMetadata,
851
- missing_surfaces: [...new Set(missingSurfaces)],
852
- project_continuation: continuation,
853
- start_work: startWorkResult,
854
- transfer_packet: normalizedTransferPacket,
855
- open_channel: openChannel,
856
- channel_participant: participantRecord,
857
- heartbeat,
858
- status_payload: statusPayload,
859
- };
444
+ return this.agentCommunications.establishAgentCommunicationChannel(arguments[0]);
860
445
  }
861
446
 
862
447
  async runInterAgentMessagingLoop({
@@ -920,301 +505,7 @@ export class AIEngineClient {
920
505
  includeOperatorProjectionMetadata = true,
921
506
  metadata = {},
922
507
  } = {}) {
923
- const missingSurfaces = [];
924
- const normalizedTransferChannelId = cleanText(transfer_channel_id) || cleanText(transferChannelId) || cleanText(channel_id) || cleanText(channelId);
925
- if (!normalizedTransferChannelId) throw new Error('transfer_channel_id is required.');
926
- let normalizedPacketId = cleanText(work_transfer_packet_id) || cleanText(workTransferPacketId);
927
- const normalizedMetadata = isPlainObject(metadata) ? metadata : {};
928
- const normalizedReplyRequest = isPlainObject(reply_request) ? reply_request : (isPlainObject(replyRequest) ? replyRequest : {});
929
- const normalizedWatchRequest = isPlainObject(watch_request) ? watch_request : (isPlainObject(watchRequest) ? watchRequest : {});
930
- const normalizedAcknowledgeRequest = isPlainObject(acknowledge_request) ? acknowledge_request : (isPlainObject(acknowledgeRequest) ? acknowledgeRequest : {});
931
- const normalizedHeartbeatRequest = isPlainObject(heartbeat_request) ? heartbeat_request : (isPlainObject(heartbeatRequest) ? heartbeatRequest : {});
932
- const normalizedClosureEvidence = isPlainObject(closure_evidence) ? closure_evidence : (isPlainObject(closureEvidence) ? closureEvidence : {});
933
- const shouldClose = Boolean(close_when_acknowledged || closeWhenAcknowledged || request_closure || requestClosure);
934
-
935
- if (!normalizedPacketId) {
936
- try {
937
- const status = await this.getCommunicationChannelStatus({ transferChannelId: normalizedTransferChannelId });
938
- normalizedPacketId = cleanText(status?.packet_id || status?.packetId || status?.work_transfer_packet_id);
939
- } catch (error) {
940
- void error;
941
- }
942
- }
943
- if (!normalizedPacketId) {
944
- throw new Error('work_transfer_packet_id is required.');
945
- }
946
-
947
- const resumeSurface = typeof this.resumeTransferChannel === 'function'
948
- ? this.resumeTransferChannel.bind(this)
949
- : null;
950
- if (!resumeSurface) missingSurfaces.push('resumeTransferChannel');
951
- const resumedChannel = resumeSurface
952
- ? await resumeSurface({
953
- transferChannelId: normalizedTransferChannelId,
954
- workTransferPacketId: normalizedPacketId,
955
- workflowRunId: cleanText(workflow_run_id) || cleanText(workflowRunId),
956
- participantRole: cleanText(participant_role) || cleanText(participantRole) || cleanText(watching_agent_role) || cleanText(watchingAgentRole) || 'downstream',
957
- participantKind: 'agent_session',
958
- participantLabel: cleanText(participant_role) || cleanText(participantRole) || cleanText(watching_agent_role) || cleanText(watchingAgentRole) || 'downstream',
959
- agentSessionId: this.agentSessionId,
960
- currentPhase: 'message_loop',
961
- currentTaskSummary: cleanText(expected_next_message) || cleanText(expectedNextMessage) || 'Await expected message.',
962
- lastSeenMessageId: cleanText(normalizedReplyRequest.transfer_channel_message_id) || cleanText(normalizedReplyRequest.transferChannelMessageId),
963
- metadata: {
964
- ...normalizedMetadata,
965
- source: 'runInterAgentMessagingLoop',
966
- },
967
- })
968
- : null;
969
-
970
- const replySurface = typeof this.replyToTransferChannel === 'function'
971
- ? this.replyToTransferChannel.bind(this)
972
- : null;
973
- if (!replySurface) missingSurfaces.push('replyToTransferChannel');
974
- const replyBody = normalizedReplyRequest.body_markdown || normalizedReplyRequest.bodyMarkdown || reply_body_markdown || replyBodyMarkdown;
975
- const shouldReply = Boolean(
976
- replyBody
977
- || normalizedReplyRequest.body
978
- || normalizedReplyRequest.message_kind
979
- || normalizedReplyRequest.messageKind
980
- || cleanText(reply_message_kind)
981
- || cleanText(replyMessageKind)
982
- || Object.keys(normalizedReplyRequest).length > 0
983
- );
984
- const replyResult = shouldReply && replySurface
985
- ? await replySurface({
986
- transferChannelId: normalizedTransferChannelId,
987
- senderAgentSessionId: cleanText(normalizedReplyRequest.sender_agent_session_id) || cleanText(normalizedReplyRequest.senderAgentSessionId) || cleanText(reply_sender_agent_session_id) || cleanText(replySenderAgentSessionId) || this.agentSessionId,
988
- senderActorSessionId: cleanText(normalizedReplyRequest.sender_actor_session_id) || cleanText(normalizedReplyRequest.senderActorSessionId) || cleanText(reply_sender_actor_session_id) || cleanText(replySenderActorSessionId),
989
- recipientAgentSessionId: cleanText(normalizedReplyRequest.recipient_agent_session_id) || cleanText(normalizedReplyRequest.recipientAgentSessionId) || cleanText(reply_recipient_agent_session_id) || cleanText(replyRecipientAgentSessionId),
990
- recipientActorSessionId: cleanText(normalizedReplyRequest.recipient_actor_session_id) || cleanText(normalizedReplyRequest.recipientActorSessionId) || cleanText(reply_recipient_actor_session_id) || cleanText(replyRecipientActorSessionId),
991
- messageKind: cleanText(normalizedReplyRequest.message_kind) || cleanText(normalizedReplyRequest.messageKind) || cleanText(reply_message_kind) || cleanText(replyMessageKind) || cleanText(expected_next_message) || cleanText(expectedNextMessage) || 'response',
992
- bodyMarkdown: cleanText(reply_body_markdown) || cleanText(replyBodyMarkdown) || cleanText(normalizedReplyRequest.body_markdown) || cleanText(normalizedReplyRequest.bodyMarkdown) || cleanText(normalizedReplyRequest.body),
993
- transferChannelMessageStatus: cleanText(normalizedReplyRequest.message_status) || cleanText(normalizedReplyRequest.messageStatus),
994
- payload: isPlainObject(normalizedReplyRequest.payload) ? normalizedReplyRequest.payload : (isPlainObject(reply_payload) ? reply_payload : (isPlainObject(replyPayload) ? replyPayload : {})),
995
- scope: isPlainObject(normalizedReplyRequest.scope) ? normalizedReplyRequest.scope : (isPlainObject(reply_scope) ? reply_scope : (isPlainObject(replyScope) ? replyScope : {})),
996
- requiredResponseSchema: isPlainObject(normalizedReplyRequest.required_response_schema) ? normalizedReplyRequest.required_response_schema : (isPlainObject(normalizedReplyRequest.requiredResponseSchema) ? normalizedReplyRequest.requiredResponseSchema : null),
997
- evidenceRefs: Array.isArray(normalizedReplyRequest.evidence_refs) ? normalizedReplyRequest.evidence_refs : (Array.isArray(reply_evidence_refs) ? reply_evidence_refs : replyEvidenceRefs),
998
- metadata: {
999
- ...normalizedMetadata,
1000
- source: 'runInterAgentMessagingLoop',
1001
- },
1002
- closureReason: cleanText(normalizedReplyRequest.closure_reason) || cleanText(normalizedReplyRequest.closureReason) || cleanText(closure_reason) || cleanText(closureReason),
1003
- failureReason: cleanText(normalizedReplyRequest.failure_reason) || cleanText(normalizedReplyRequest.failureReason) || cleanText(failure_reason) || cleanText(failureReason),
1004
- currentWaitingSide: cleanText(normalizedReplyRequest.current_waiting_side) || cleanText(normalizedReplyRequest.currentWaitingSide),
1005
- })
1006
- : null;
1007
-
1008
- const normalizedReplyPayload = isPlainObject(replyResult) ? replyResult : {};
1009
- const messageId = cleanText(normalizedReplyPayload.transfer_channel_message?.transfer_channel_message_id)
1010
- || cleanText(normalizedReplyPayload.communication_message?.transfer_channel_message_id)
1011
- || cleanText(normalizedReplyPayload.communication_message?.agent_message_id)
1012
- || cleanText(normalizedReplyPayload.transfer_channel_message_id)
1013
- || cleanText(normalizedReplyPayload.message_id)
1014
- || cleanText(normalizedReplyPayload.communication_message?.message_id)
1015
- || null;
1016
- const receiptId = cleanText(normalizedReplyPayload.transfer_channel_receipt?.transfer_channel_receipt_id)
1017
- || cleanText(normalizedReplyPayload.transfer_channel_receipt_id)
1018
- || cleanText(normalizedReplyPayload.receipt_id)
1019
- || null;
1020
-
1021
- const watchSurface = typeof this.startMessageWatch === 'function'
1022
- ? this.startMessageWatch.bind(this)
1023
- : null;
1024
- if (!watchSurface) missingSurfaces.push('startMessageWatch');
1025
- const startedWatch = watchSurface
1026
- ? await watchSurface({
1027
- transferChannelId: normalizedTransferChannelId,
1028
- workTransferPacketId: normalizedPacketId,
1029
- workflowRunId: cleanText(workflow_run_id) || cleanText(workflowRunId),
1030
- watchingAgentRole: cleanText(watching_agent_role) || cleanText(watchingAgentRole) || 'upstream',
1031
- expectedFromRole: cleanText(expected_from_role) || cleanText(expectedFromRole) || cleanText(participant_role) || cleanText(participantRole) || 'downstream',
1032
- expectedMessageKind: cleanText(expected_message_kind) || cleanText(expectedMessageKind) || cleanText(expected_next_message) || cleanText(expectedNextMessage) || 'response',
1033
- watchType: cleanText(normalizedWatchRequest.watch_type) || cleanText(normalizedWatchRequest.watchType) || 'expected_peer_message',
1034
- watchingAgentSessionId: cleanText(normalizedWatchRequest.watching_agent_session_id) || cleanText(normalizedWatchRequest.watchingAgentSessionId) || this.agentSessionId,
1035
- watchingActorSessionId: cleanText(normalizedWatchRequest.watching_actor_session_id) || cleanText(normalizedWatchRequest.watchingActorSessionId),
1036
- expectedPayload: isPlainObject(normalizedWatchRequest.expected_payload) ? normalizedWatchRequest.expected_payload : (isPlainObject(normalizedWatchRequest.expectedPayload) ? normalizedWatchRequest.expectedPayload : {}),
1037
- lastSeenMessageId: cleanText(normalizedWatchRequest.last_seen_message_id) || cleanText(normalizedWatchRequest.lastSeenMessageId) || messageId,
1038
- lastCheckedAt: normalizedWatchRequest.last_checked_at || normalizedWatchRequest.lastCheckedAt,
1039
- staleAfterSeconds: normalizedWatchRequest.stale_after_seconds ?? normalizedWatchRequest.staleAfterSeconds,
1040
- currentStatus: cleanText(normalizedWatchRequest.current_status) || cleanText(normalizedWatchRequest.currentStatus) || 'watching',
1041
- operatorNudge: cleanText(normalizedWatchRequest.operator_nudge) || cleanText(normalizedWatchRequest.operatorNudge),
1042
- blockedReason: cleanText(normalizedWatchRequest.blocked_reason) || cleanText(normalizedWatchRequest.blockedReason),
1043
- metadata: {
1044
- ...normalizedMetadata,
1045
- source: 'runInterAgentMessagingLoop',
1046
- },
1047
- })
1048
- : null;
1049
-
1050
- const watchPayload = isPlainObject(startedWatch) ? startedWatch : {};
1051
- const watchRecord = isPlainObject(watchPayload.message_watch)
1052
- ? watchPayload.message_watch
1053
- : (isPlainObject(watchPayload.messageWatch) ? watchPayload.messageWatch : watchPayload);
1054
- const watchId = cleanText(watchRecord.message_watch_id)
1055
- || cleanText(watchRecord.watch_id)
1056
- || null;
1057
- const observedMessageId = messageId || cleanText(normalizedAcknowledgeRequest.observed_message_id) || cleanText(normalizedAcknowledgeRequest.observedMessageId);
1058
- const ackSurface = typeof this.acknowledgeExpectedMessage === 'function'
1059
- ? this.acknowledgeExpectedMessage.bind(this)
1060
- : null;
1061
- if (!ackSurface) missingSurfaces.push('acknowledgeExpectedMessage');
1062
- const acknowledgedResult = ackSurface
1063
- ? await ackSurface({
1064
- transferChannelId: normalizedTransferChannelId,
1065
- messageWatchId: watchId || cleanText(normalizedAcknowledgeRequest.message_watch_id) || cleanText(normalizedAcknowledgeRequest.messageWatchId) || cleanText(normalizedAcknowledgeRequest.watch_id) || cleanText(normalizedAcknowledgeRequest.watchId),
1066
- observedMessageId,
1067
- observedMessageKind: cleanText(normalizedAcknowledgeRequest.observed_message_kind) || cleanText(normalizedAcknowledgeRequest.observedMessageKind) || cleanText(expected_next_message) || cleanText(expectedNextMessage),
1068
- lastCheckedAt: normalizedAcknowledgeRequest.last_checked_at || normalizedAcknowledgeRequest.lastCheckedAt,
1069
- operatorNudge: cleanText(normalizedAcknowledgeRequest.operator_nudge) || cleanText(normalizedAcknowledgeRequest.operatorNudge),
1070
- metadata: {
1071
- ...normalizedMetadata,
1072
- source: 'runInterAgentMessagingLoop',
1073
- },
1074
- })
1075
- : null;
1076
- const acknowledged = Boolean(acknowledgedResult);
1077
-
1078
- const heartbeatSurface = typeof this.postCollaborationHeartbeat === 'function'
1079
- ? this.postCollaborationHeartbeat.bind(this)
1080
- : typeof this.postAgentHeartbeat === 'function'
1081
- ? this.postAgentHeartbeat.bind(this)
1082
- : null;
1083
- if (!heartbeatSurface) missingSurfaces.push('postCollaborationHeartbeat');
1084
- const heartbeatResult = heartbeatSurface
1085
- ? await heartbeatSurface({
1086
- transferChannelId: normalizedTransferChannelId,
1087
- workTransferPacketId: normalizedPacketId,
1088
- workflowRunId: cleanText(workflow_run_id) || cleanText(workflowRunId),
1089
- participantRole: cleanText(participant_role) || cleanText(participantRole) || cleanText(watching_agent_role) || cleanText(watchingAgentRole) || 'downstream',
1090
- activityState: 'active',
1091
- agentSessionId: this.agentSessionId,
1092
- actorSessionId: cleanText(normalizedHeartbeatRequest.actor_session_id) || cleanText(normalizedHeartbeatRequest.actorSessionId),
1093
- currentPhase: cleanText(normalizedHeartbeatRequest.current_phase) || cleanText(normalizedHeartbeatRequest.currentPhase) || 'message_loop',
1094
- currentTaskSummary: cleanText(normalizedHeartbeatRequest.current_task_summary) || cleanText(normalizedHeartbeatRequest.currentTaskSummary) || cleanText(expected_next_message) || cleanText(expectedNextMessage) || 'Await expected message.',
1095
- isActive: normalizedHeartbeatRequest.is_active ?? normalizedHeartbeatRequest.isActive ?? true,
1096
- observedAt: normalizedHeartbeatRequest.observed_at || normalizedHeartbeatRequest.observedAt,
1097
- metadata: {
1098
- ...normalizedMetadata,
1099
- source: 'runInterAgentMessagingLoop',
1100
- },
1101
- })
1102
- : null;
1103
-
1104
- const transferChannelProjectionSurface = typeof this.getTransferChannelProjection === 'function'
1105
- ? this.getTransferChannelProjection.bind(this)
1106
- : typeof this.getLogaTransferChannelThreadProjection === 'function'
1107
- ? this.getLogaTransferChannelThreadProjection.bind(this)
1108
- : null;
1109
- if (!transferChannelProjectionSurface) missingSurfaces.push('getTransferChannelProjection');
1110
- const transferChannelProjection = includeTransferChannelProjection && transferChannelProjectionSurface
1111
- ? await transferChannelProjectionSurface(normalizedTransferChannelId).catch(() => null)
1112
- : null;
1113
-
1114
- const closureRequested = Boolean(shouldClose && acknowledged);
1115
- const closeSurface = typeof this.closeTransferChannel === 'function'
1116
- ? this.closeTransferChannel.bind(this)
1117
- : null;
1118
- if (!closeSurface) missingSurfaces.push('closeTransferChannel');
1119
- const closeResult = closureRequested && closeSurface
1120
- ? await closeSurface({
1121
- transferChannelId: normalizedTransferChannelId,
1122
- closureStatus: 'closed',
1123
- closureReason: cleanText(closure_reason) || cleanText(closureReason) || 'expected message loop completed',
1124
- failureReason: cleanText(failure_reason) || cleanText(failureReason),
1125
- evidence: normalizedClosureEvidence,
1126
- evidenceManifestSha256: cleanText(closure_evidence_manifest_sha256) || cleanText(closureEvidenceManifestSha256),
1127
- closedByAgentSessionId: this.agentSessionId,
1128
- metadata: {
1129
- ...normalizedMetadata,
1130
- source: 'runInterAgentMessagingLoop',
1131
- },
1132
- })
1133
- : null;
1134
-
1135
- const closePayload = isPlainObject(closeResult) ? closeResult : {};
1136
- const channelClosed = Boolean(
1137
- closePayload.closed
1138
- || closePayload.closed_channel
1139
- || closePayload.channel_closed
1140
- || closePayload.closed_at
1141
- || closePayload.transfer_channel?.channel_status === 'closed'
1142
- || closePayload.communication_transfer_channel?.channel_status === 'closed'
1143
- );
1144
- const statusPayload = {
1145
- transfer_channel: resumedChannel || null,
1146
- watch: startedWatch || null,
1147
- reply: replyResult || null,
1148
- acknowledge: acknowledgedResult || null,
1149
- heartbeat: heartbeatResult || null,
1150
- close: closeResult || null,
1151
- transfer_channel_projection: transferChannelProjection,
1152
- };
1153
-
1154
- const waitingSide = cleanText(
1155
- watchRecord.waiting_side
1156
- || watchRecord.expected_from_role
1157
- || watchRecord.expectedFromRole
1158
- || normalizedReplyPayload.current_waiting_side
1159
- || normalizedReplyPayload.currentWaitingSide
1160
- || normalizedReplyPayload.waiting_side
1161
- || normalizedReplyPayload.waitingSide
1162
- || heartbeatResult?.waiting_side
1163
- || resumedChannel?.waiting_side
1164
- ) || null;
1165
- const expectedNext = cleanText(
1166
- watchRecord.expected_message_kind
1167
- || watchRecord.expectedMessageKind
1168
- || normalizedReplyPayload.next_message_kind
1169
- || normalizedReplyPayload.expected_next_message
1170
- || normalizedReplyPayload.expectedNextMessage
1171
- || heartbeatResult?.expected_message_kind
1172
- || expected_message_kind
1173
- || expectedMessageKind
1174
- || expected_next_message
1175
- || expectedNextMessage
1176
- ) || null;
1177
- const heartbeatStatus = cleanText(
1178
- heartbeatResult?.collaboration_heartbeat?.activity_state
1179
- || heartbeatResult?.activity_state
1180
- || heartbeatResult?.status
1181
- || heartbeatResult?.heartbeat_status
1182
- ) || (heartbeatResult ? 'active' : 'missing');
1183
-
1184
- const operatorProjectionMetadata = includeOperatorProjectionMetadata
1185
- ? {
1186
- transfer_channel_projection: transferChannelProjection,
1187
- watch: startedWatch,
1188
- reply: replyResult,
1189
- acknowledge: acknowledgedResult,
1190
- heartbeat: heartbeatResult,
1191
- close: closeResult,
1192
- }
1193
- : null;
1194
-
1195
- const established = Boolean(normalizedTransferChannelId && normalizedPacketId);
1196
- return {
1197
- status: missingSurfaces.length > 0 ? 'partial' : channelClosed ? 'closed' : established ? 'waiting' : 'blocked',
1198
- channel_id: normalizedTransferChannelId,
1199
- message_id: messageId || null,
1200
- receipt_id: receiptId || null,
1201
- watch_id: watchId || null,
1202
- waiting_side: waitingSide,
1203
- expected_next_message: expectedNext,
1204
- acknowledged,
1205
- heartbeat_status: heartbeatStatus,
1206
- closure_requested: closureRequested,
1207
- channel_closed: channelClosed,
1208
- operator_projection_metadata: operatorProjectionMetadata,
1209
- missing_surfaces: [...new Set(missingSurfaces)],
1210
- transfer_channel: resumedChannel,
1211
- message_watch: startedWatch,
1212
- reply: replyResult,
1213
- acknowledge: acknowledgedResult,
1214
- heartbeat: heartbeatResult,
1215
- close: closeResult,
1216
- status_payload: statusPayload,
1217
- };
508
+ return this.agentCommunications.runInterAgentMessagingLoop(arguments[0]);
1218
509
  }
1219
510
 
1220
511
  async createCrossAgentRemediationTicket({
@@ -2691,6 +1982,93 @@ export class AIEngineClient {
2691
1982
  });
2692
1983
  }
2693
1984
 
1985
+ async getPortfolioClosureReadiness(...args) {
1986
+ return this.portfolio.getPortfolioClosureReadiness(...args);
1987
+ }
1988
+
1989
+ async getPortfolioStatus(...args) {
1990
+ return this.portfolio.getPortfolioStatus(...args);
1991
+ }
1992
+
1993
+ async describeDatabaseCatalog({ includeSystemSchemas, limit } = {}) {
1994
+ return this._request('/api/operator/database/schema', {
1995
+ query: {
1996
+ view: 'overview',
1997
+ include_system_schemas: includeSystemSchemas,
1998
+ limit,
1999
+ },
2000
+ });
2001
+ }
2002
+
2003
+ async listDatabaseSchemas({ includeSystemSchemas, limit } = {}) {
2004
+ return this._request('/api/operator/database/schema', {
2005
+ query: {
2006
+ view: 'schemas',
2007
+ include_system_schemas: includeSystemSchemas,
2008
+ limit,
2009
+ },
2010
+ });
2011
+ }
2012
+
2013
+ async listDatabaseTables({ schemaName, includeSystemSchemas, limit } = {}) {
2014
+ return this._request('/api/operator/database/schema', {
2015
+ query: {
2016
+ view: 'tables',
2017
+ schema_name: schemaName,
2018
+ include_system_schemas: includeSystemSchemas,
2019
+ limit,
2020
+ },
2021
+ });
2022
+ }
2023
+
2024
+ async listDatabaseColumns({ schemaName, tableName } = {}) {
2025
+ return this._request('/api/operator/database/schema', {
2026
+ query: {
2027
+ view: 'columns',
2028
+ schema_name: schemaName,
2029
+ table_name: tableName,
2030
+ },
2031
+ });
2032
+ }
2033
+
2034
+ async listDatabaseIndexes({ schemaName, tableName, includeSystemSchemas, limit } = {}) {
2035
+ return this._request('/api/operator/database/schema', {
2036
+ query: {
2037
+ view: 'indexes',
2038
+ schema_name: schemaName,
2039
+ table_name: tableName,
2040
+ include_system_schemas: includeSystemSchemas,
2041
+ limit,
2042
+ },
2043
+ });
2044
+ }
2045
+
2046
+ async describeDatabaseTable({ schemaName, tableName, includeSystemSchemas } = {}) {
2047
+ return this._request('/api/operator/database/schema', {
2048
+ query: {
2049
+ view: 'table',
2050
+ schema_name: schemaName,
2051
+ table_name: tableName,
2052
+ include_system_schemas: includeSystemSchemas,
2053
+ },
2054
+ });
2055
+ }
2056
+
2057
+ async createDatabaseBackup({ databaseName, outputName, noWait } = {}) {
2058
+ return this._request('/api/operator/database/backups', {
2059
+ method: 'POST',
2060
+ body: {
2061
+ database_name: databaseName,
2062
+ output_name: outputName,
2063
+ no_wait: noWait,
2064
+ },
2065
+ });
2066
+ }
2067
+
2068
+ async getPortfolioBundle() {
2069
+ return this.portfolio.getPortfolioBundle();
2070
+ }
2071
+
2694
2072
  async getExternalProjectStatus(projectId) {
2695
2073
  return this._request(`/api/v1/projects/${projectId}/status`);
2696
2074
  }