@memberjunction/ng-conversations 5.43.0 → 5.45.0
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/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts +0 -1
- package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts.map +1 -1
- package/dist/lib/components/active-tasks/active-tasks-panel.component.js +56 -52
- package/dist/lib/components/active-tasks/active-tasks-panel.component.js.map +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.d.ts +3 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.js +52 -52
- package/dist/lib/components/artifact/artifact-share-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.js +10 -14
- package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.d.ts +3 -1
- package/dist/lib/components/collection/collection-share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.js +56 -56
- package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.d.ts +3 -1
- package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.js +10 -7
- package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
- package/dist/lib/components/collection/collection-view.component.d.ts +3 -1
- package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +29 -41
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.d.ts +4 -0
- package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +134 -166
- package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
- package/dist/lib/components/composer/ai-composer.component.d.ts +103 -0
- package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -0
- package/dist/lib/components/composer/ai-composer.component.js +263 -0
- package/dist/lib/components/composer/ai-composer.component.js.map +1 -0
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +76 -12
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +522 -158
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
- package/dist/lib/components/conversation/pinned-messages-panel.component.js +6 -9
- package/dist/lib/components/conversation/pinned-messages-panel.component.js.map +1 -1
- package/dist/lib/components/library/library-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/library/library-full-view.component.js +20 -24
- package/dist/lib/components/library/library-full-view.component.js.map +1 -1
- package/dist/lib/components/members/members-modal.component.d.ts.map +1 -1
- package/dist/lib/components/members/members-modal.component.js +10 -11
- package/dist/lib/components/members/members-modal.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +87 -23
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +245 -158
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +11 -3
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +73 -21
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.js +6 -9
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts +4 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.js +9 -4
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +45 -0
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +10 -0
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.d.ts +46 -0
- package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -0
- package/dist/lib/components/realtime/channels/client-context-channel.js +174 -0
- package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -0
- package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.d.ts +123 -0
- package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js +397 -0
- package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js.map +1 -0
- package/dist/lib/components/realtime/media/media-channel-state.d.ts +103 -0
- package/dist/lib/components/realtime/media/media-channel-state.d.ts.map +1 -0
- package/dist/lib/components/realtime/media/media-channel-state.js +143 -0
- package/dist/lib/components/realtime/media/media-channel-state.js.map +1 -0
- package/dist/lib/components/realtime/media/media-channel-tools.d.ts +24 -0
- package/dist/lib/components/realtime/media/media-channel-tools.d.ts.map +1 -0
- package/dist/lib/components/realtime/media/media-channel-tools.js +107 -0
- package/dist/lib/components/realtime/media/media-channel-tools.js.map +1 -0
- package/dist/lib/components/realtime/media/media-channel.d.ts +89 -0
- package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -0
- package/dist/lib/components/realtime/media/media-channel.js +253 -0
- package/dist/lib/components/realtime/media/media-channel.js.map +1 -0
- package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts +141 -0
- package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/media/realtime-media-surface.component.js +574 -0
- package/dist/lib/components/realtime/media/realtime-media-surface.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +59 -14
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.js +277 -74
- package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +28 -27
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.js +144 -143
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +12 -0
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-picker.component.js +105 -43
- package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +2 -2
- package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.d.ts +41 -7
- package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.js +216 -102
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +0 -2
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.js +67 -71
- package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +364 -44
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +839 -153
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.d.ts +5 -5
- package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tab-style.d.ts +70 -0
- package/dist/lib/components/realtime/realtime-surface-tab-style.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tab-style.js +115 -0
- package/dist/lib/components/realtime/realtime-surface-tab-style.js.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +55 -57
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js +165 -143
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +80 -71
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js +83 -113
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
- package/dist/lib/components/realtime/realtime-ui-config.d.ts +270 -0
- package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-ui-config.js +212 -0
- package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -0
- package/dist/lib/components/search/search-panel.component.d.ts +2 -0
- package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
- package/dist/lib/components/search/search-panel.component.js +92 -101
- package/dist/lib/components/search/search-panel.component.js.map +1 -1
- package/dist/lib/components/share/share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/share/share-modal.component.js +10 -11
- package/dist/lib/components/share/share-modal.component.js.map +1 -1
- package/dist/lib/components/shared/user-picker.component.d.ts.map +1 -1
- package/dist/lib/components/shared/user-picker.component.js +12 -15
- package/dist/lib/components/shared/user-picker.component.js.map +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts +11 -3
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts.map +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.js +34 -10
- package/dist/lib/components/sidebar/conversation-sidebar.component.js.map +1 -1
- package/dist/lib/components/sidebar/routines-section.component.d.ts +73 -0
- package/dist/lib/components/sidebar/routines-section.component.d.ts.map +1 -0
- package/dist/lib/components/sidebar/routines-section.component.js +211 -0
- package/dist/lib/components/sidebar/routines-section.component.js.map +1 -0
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +12 -0
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +37 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +16 -5
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +51 -31
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/composer-plugins/agent-mention.provider.d.ts +16 -0
- package/dist/lib/composer-plugins/agent-mention.provider.d.ts.map +1 -0
- package/dist/lib/composer-plugins/agent-mention.provider.js +28 -0
- package/dist/lib/composer-plugins/agent-mention.provider.js.map +1 -0
- package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts +20 -0
- package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts.map +1 -0
- package/dist/lib/composer-plugins/base-conversation-mention.provider.js +32 -0
- package/dist/lib/composer-plugins/base-conversation-mention.provider.js.map +1 -0
- package/dist/lib/composer-plugins/load-composer-plugins.d.ts +9 -0
- package/dist/lib/composer-plugins/load-composer-plugins.d.ts.map +1 -0
- package/dist/lib/composer-plugins/load-composer-plugins.js +17 -0
- package/dist/lib/composer-plugins/load-composer-plugins.js.map +1 -0
- package/dist/lib/composer-plugins/record-mention.provider.d.ts +14 -0
- package/dist/lib/composer-plugins/record-mention.provider.d.ts.map +1 -0
- package/dist/lib/composer-plugins/record-mention.provider.js +26 -0
- package/dist/lib/composer-plugins/record-mention.provider.js.map +1 -0
- package/dist/lib/composer-plugins/skill-command.provider.d.ts +15 -0
- package/dist/lib/composer-plugins/skill-command.provider.d.ts.map +1 -0
- package/dist/lib/composer-plugins/skill-command.provider.js +27 -0
- package/dist/lib/composer-plugins/skill-command.provider.js.map +1 -0
- package/dist/lib/conversations.module.d.ts +68 -64
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js +69 -18
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/models/conversation-state.model.d.ts +6 -3
- package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
- package/dist/lib/models/conversation-state.model.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +9 -2
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +26 -2
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-attachment.service.d.ts +1 -1
- package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-attachment.service.js.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.d.ts +42 -19
- package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.js +113 -18
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
- package/dist/lib/services/realtime-audio-recorder.d.ts +143 -0
- package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -0
- package/dist/lib/services/realtime-audio-recorder.js +379 -0
- package/dist/lib/services/realtime-audio-recorder.js.map +1 -0
- package/dist/lib/services/realtime-pcm-wav.d.ts +75 -0
- package/dist/lib/services/realtime-pcm-wav.d.ts.map +1 -0
- package/dist/lib/services/realtime-pcm-wav.js +205 -0
- package/dist/lib/services/realtime-pcm-wav.js.map +1 -0
- package/dist/lib/services/realtime-session-review.service.d.ts +28 -1
- package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session-review.service.js +12 -3
- package/dist/lib/services/realtime-session-review.service.js.map +1 -1
- package/dist/lib/services/realtime-session.service.d.ts +210 -20
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +452 -21
- package/dist/lib/services/realtime-session.service.js.map +1 -1
- package/dist/lib/services/realtime-sessions-adapter.js +1 -1
- package/dist/lib/services/realtime-sessions-adapter.js.map +1 -1
- package/dist/lib/services/ui-command-handler.service.d.ts +7 -2
- package/dist/lib/services/ui-command-handler.service.d.ts.map +1 -1
- package/dist/lib/services/ui-command-handler.service.js +6 -2
- package/dist/lib/services/ui-command-handler.service.js.map +1 -1
- package/dist/lib/utils/plan-mode-preference.d.ts +62 -0
- package/dist/lib/utils/plan-mode-preference.d.ts.map +1 -0
- package/dist/lib/utils/plan-mode-preference.js +130 -0
- package/dist/lib/utils/plan-mode-preference.js.map +1 -0
- package/dist/public-api.d.ts +29 -3
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +46 -3
- package/dist/public-api.js.map +1 -1
- package/package.json +30 -26
- package/dist/__tests__/attachment-badge.test.d.ts +0 -2
- package/dist/__tests__/attachment-badge.test.d.ts.map +0 -1
- package/dist/__tests__/attachment-badge.test.js +0 -66
- package/dist/__tests__/attachment-badge.test.js.map +0 -1
- package/dist/__tests__/channel-optional-surface.test.d.ts +0 -2
- package/dist/__tests__/channel-optional-surface.test.d.ts.map +0 -1
- package/dist/__tests__/channel-optional-surface.test.js +0 -53
- package/dist/__tests__/channel-optional-surface.test.js.map +0 -1
- package/dist/__tests__/chat-events.test.d.ts +0 -14
- package/dist/__tests__/chat-events.test.d.ts.map +0 -1
- package/dist/__tests__/chat-events.test.js +0 -109
- package/dist/__tests__/chat-events.test.js.map +0 -1
- package/dist/__tests__/collections-full-view.test.d.ts +0 -2
- package/dist/__tests__/collections-full-view.test.d.ts.map +0 -1
- package/dist/__tests__/collections-full-view.test.js +0 -225
- package/dist/__tests__/collections-full-view.test.js.map +0 -1
- package/dist/__tests__/conversation-cache.test.d.ts +0 -2
- package/dist/__tests__/conversation-cache.test.d.ts.map +0 -1
- package/dist/__tests__/conversation-cache.test.js +0 -233
- package/dist/__tests__/conversation-cache.test.js.map +0 -1
- package/dist/__tests__/conversation-naming.test.d.ts +0 -2
- package/dist/__tests__/conversation-naming.test.d.ts.map +0 -1
- package/dist/__tests__/conversation-naming.test.js +0 -110
- package/dist/__tests__/conversation-naming.test.js.map +0 -1
- package/dist/__tests__/delegation-result-parser.test.d.ts +0 -2
- package/dist/__tests__/delegation-result-parser.test.d.ts.map +0 -1
- package/dist/__tests__/delegation-result-parser.test.js +0 -107
- package/dist/__tests__/delegation-result-parser.test.js.map +0 -1
- package/dist/__tests__/distinct-artifacts.test.d.ts +0 -2
- package/dist/__tests__/distinct-artifacts.test.d.ts.map +0 -1
- package/dist/__tests__/distinct-artifacts.test.js +0 -56
- package/dist/__tests__/distinct-artifacts.test.js.map +0 -1
- package/dist/__tests__/event-wiring.test.d.ts +0 -15
- package/dist/__tests__/event-wiring.test.d.ts.map +0 -1
- package/dist/__tests__/event-wiring.test.js +0 -100
- package/dist/__tests__/event-wiring.test.js.map +0 -1
- package/dist/__tests__/index.test.d.ts +0 -2
- package/dist/__tests__/index.test.d.ts.map +0 -1
- package/dist/__tests__/index.test.js +0 -7
- package/dist/__tests__/index.test.js.map +0 -1
- package/dist/__tests__/narration-template.test.d.ts +0 -2
- package/dist/__tests__/narration-template.test.d.ts.map +0 -1
- package/dist/__tests__/narration-template.test.js +0 -76
- package/dist/__tests__/narration-template.test.js.map +0 -1
- package/dist/__tests__/notification-model.test.d.ts +0 -2
- package/dist/__tests__/notification-model.test.d.ts.map +0 -1
- package/dist/__tests__/notification-model.test.js +0 -68
- package/dist/__tests__/notification-model.test.js.map +0 -1
- package/dist/__tests__/realtime-agent-picker-models.test.d.ts +0 -2
- package/dist/__tests__/realtime-agent-picker-models.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-agent-picker-models.test.js +0 -49
- package/dist/__tests__/realtime-agent-picker-models.test.js.map +0 -1
- package/dist/__tests__/realtime-audio-visuals.test.d.ts +0 -2
- package/dist/__tests__/realtime-audio-visuals.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-audio-visuals.test.js +0 -123
- package/dist/__tests__/realtime-audio-visuals.test.js.map +0 -1
- package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts +0 -2
- package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-delegation-card-cancel.test.js +0 -48
- package/dist/__tests__/realtime-delegation-card-cancel.test.js.map +0 -1
- package/dist/__tests__/realtime-disclosure.test.d.ts +0 -2
- package/dist/__tests__/realtime-disclosure.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-disclosure.test.js +0 -164
- package/dist/__tests__/realtime-disclosure.test.js.map +0 -1
- package/dist/__tests__/realtime-pairing.test.d.ts +0 -2
- package/dist/__tests__/realtime-pairing.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-pairing.test.js +0 -207
- package/dist/__tests__/realtime-pairing.test.js.map +0 -1
- package/dist/__tests__/realtime-review-lifecycle.test.d.ts +0 -2
- package/dist/__tests__/realtime-review-lifecycle.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-review-lifecycle.test.js +0 -154
- package/dist/__tests__/realtime-review-lifecycle.test.js.map +0 -1
- package/dist/__tests__/realtime-session-cancel-usage.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-cancel-usage.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-cancel-usage.test.js +0 -230
- package/dist/__tests__/realtime-session-cancel-usage.test.js.map +0 -1
- package/dist/__tests__/realtime-session-channels.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-channels.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-channels.test.js +0 -252
- package/dist/__tests__/realtime-session-channels.test.js.map +0 -1
- package/dist/__tests__/realtime-session-client-tools.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-client-tools.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-client-tools.test.js +0 -103
- package/dist/__tests__/realtime-session-client-tools.test.js.map +0 -1
- package/dist/__tests__/realtime-session-minimized.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-minimized.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-minimized.test.js +0 -32
- package/dist/__tests__/realtime-session-minimized.test.js.map +0 -1
- package/dist/__tests__/realtime-session-mint.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-mint.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-mint.test.js +0 -69
- package/dist/__tests__/realtime-session-mint.test.js.map +0 -1
- package/dist/__tests__/realtime-session-policy.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-policy.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-policy.test.js +0 -303
- package/dist/__tests__/realtime-session-policy.test.js.map +0 -1
- package/dist/__tests__/realtime-session-review.service.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-review.service.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-review.service.test.js +0 -743
- package/dist/__tests__/realtime-session-review.service.test.js.map +0 -1
- package/dist/__tests__/realtime-session-state.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-state.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-state.test.js +0 -83
- package/dist/__tests__/realtime-session-state.test.js.map +0 -1
- package/dist/__tests__/realtime-session-timeline-card.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-timeline-card.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-timeline-card.test.js +0 -106
- package/dist/__tests__/realtime-session-timeline-card.test.js.map +0 -1
- package/dist/__tests__/realtime-session-timeline.test.d.ts +0 -2
- package/dist/__tests__/realtime-session-timeline.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-session-timeline.test.js +0 -142
- package/dist/__tests__/realtime-session-timeline.test.js.map +0 -1
- package/dist/__tests__/realtime-sessions-adapter.test.d.ts +0 -19
- package/dist/__tests__/realtime-sessions-adapter.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-sessions-adapter.test.js +0 -188
- package/dist/__tests__/realtime-sessions-adapter.test.js.map +0 -1
- package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts +0 -2
- package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-surface-panel-prefs.test.js +0 -100
- package/dist/__tests__/realtime-surface-panel-prefs.test.js.map +0 -1
- package/dist/__tests__/realtime-surface-tabs-model.test.d.ts +0 -2
- package/dist/__tests__/realtime-surface-tabs-model.test.d.ts.map +0 -1
- package/dist/__tests__/realtime-surface-tabs-model.test.js +0 -193
- package/dist/__tests__/realtime-surface-tabs-model.test.js.map +0 -1
- package/dist/__tests__/remote-browser-audio-player.test.d.ts +0 -2
- package/dist/__tests__/remote-browser-audio-player.test.d.ts.map +0 -1
- package/dist/__tests__/remote-browser-audio-player.test.js +0 -137
- package/dist/__tests__/remote-browser-audio-player.test.js.map +0 -1
- package/dist/__tests__/remote-browser-channel.test.d.ts +0 -2
- package/dist/__tests__/remote-browser-channel.test.d.ts.map +0 -1
- package/dist/__tests__/remote-browser-channel.test.js +0 -585
- package/dist/__tests__/remote-browser-channel.test.js.map +0 -1
- package/dist/__tests__/search-service.test.d.ts +0 -2
- package/dist/__tests__/search-service.test.d.ts.map +0 -1
- package/dist/__tests__/search-service.test.js +0 -114
- package/dist/__tests__/search-service.test.js.map +0 -1
- package/dist/__tests__/slot-defaults.test.d.ts +0 -24
- package/dist/__tests__/slot-defaults.test.d.ts.map +0 -1
- package/dist/__tests__/slot-defaults.test.js +0 -63
- package/dist/__tests__/slot-defaults.test.js.map +0 -1
- package/dist/__tests__/toast-service.test.d.ts +0 -2
- package/dist/__tests__/toast-service.test.d.ts.map +0 -1
- package/dist/__tests__/toast-service.test.js +0 -143
- package/dist/__tests__/toast-service.test.js.map +0 -1
- package/dist/__tests__/user-authorization.test.d.ts +0 -2
- package/dist/__tests__/user-authorization.test.d.ts.map +0 -1
- package/dist/__tests__/user-authorization.test.js +0 -97
- package/dist/__tests__/user-authorization.test.js.map +0 -1
- package/dist/__tests__/voice-session-narration.test.d.ts +0 -2
- package/dist/__tests__/voice-session-narration.test.d.ts.map +0 -1
- package/dist/__tests__/voice-session-narration.test.js +0 -609
- package/dist/__tests__/voice-session-narration.test.js.map +0 -1
- package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts +0 -2
- package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts.map +0 -1
- package/dist/__tests__/whiteboard-artifact-viewer.test.js +0 -101
- package/dist/__tests__/whiteboard-artifact-viewer.test.js.map +0 -1
- package/dist/__tests__/whiteboard-channel.test.d.ts +0 -2
- package/dist/__tests__/whiteboard-channel.test.d.ts.map +0 -1
- package/dist/__tests__/whiteboard-channel.test.js +0 -260
- package/dist/__tests__/whiteboard-channel.test.js.map +0 -1
- package/dist/__tests__/whiteboard-restore-state.test.d.ts +0 -2
- package/dist/__tests__/whiteboard-restore-state.test.d.ts.map +0 -1
- package/dist/__tests__/whiteboard-restore-state.test.js +0 -108
- package/dist/__tests__/whiteboard-restore-state.test.js.map +0 -1
- package/dist/lib/components/mention/mention-dropdown.component.d.ts +0 -53
- package/dist/lib/components/mention/mention-dropdown.component.d.ts.map +0 -1
- package/dist/lib/components/mention/mention-dropdown.component.js +0 -276
- package/dist/lib/components/mention/mention-dropdown.component.js.map +0 -1
- package/dist/lib/components/mention/mention-editor.component.d.ts +0 -256
- package/dist/lib/components/mention/mention-editor.component.d.ts.map +0 -1
- package/dist/lib/components/mention/mention-editor.component.js +0 -1233
- package/dist/lib/components/mention/mention-editor.component.js.map +0 -1
- package/dist/lib/components/message/message-input-box.component.d.ts +0 -137
- package/dist/lib/components/message/message-input-box.component.d.ts.map +0 -1
- package/dist/lib/components/message/message-input-box.component.js +0 -321
- package/dist/lib/components/message/message-input-box.component.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realtime-session-review.service.js","sourceRoot":"","sources":["../../../src/lib/services/realtime-session-review.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { IMetadataProvider, Metadata, RunView, RunViewParams } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { RealtimeDelegationCardVM, RealtimeThreadItem } from '../components/realtime/realtime-session-state';\nimport { ParsedDelegationArtifact } from './delegation-result-parser';\n\n/**\n * Why a reviewed session was closed, as stamped server-side by `SessionManager.CloseSession`\n * (mirrors `MJAIAgentSessionEntity.CloseReason`). `null` means the session is still open OR a\n * legacy row was closed before the column existed.\n */\nexport type RealtimeReviewCloseReason = 'Error' | 'Explicit' | 'Janitor' | 'Shutdown';\n\n/** One historical caption turn of a reviewed session (a persisted `MJ: Conversation Details` row). */\nexport interface RealtimeSessionReviewTurn {\n /** Who spoke the turn. Persisted `AI` rows map to `Assistant`. */\n Role: 'User' | 'Assistant';\n /** The transcript text. */\n Text: string;\n /** When the turn was persisted (`__mj_CreatedAt`), or null when unknown. */\n At: Date | null;\n}\n\n/**\n * A compact preview of one DELEGATED agent run the reviewed session spawned (an\n * `MJ: AI Agent Runs` row linked via `AgentSessionID`, EXCLUDING the co-agent's own\n * observability run). Carries just enough to render a done delegation card.\n */\nexport interface RealtimeSessionReviewRun {\n /** `MJ: AI Agent Runs.ID`. */\n RunID: string;\n /** The delegated agent's id. */\n AgentID: string;\n /** Denormalized agent display name from the run view, when available. */\n AgentName: string | null;\n /** Terminal (or last-known) run status (`Completed` | `Failed` | `Running` | …). */\n Status: string;\n /** Whether the run reported success. */\n Success: boolean;\n /** The run's user-facing result message, when one was recorded. */\n Message: string | null;\n /** The run's error message, when it failed. */\n ErrorMessage: string | null;\n /** The final step the run reported (`Success` | `Failed` | `Retry` | …), when known. */\n FinalStep: string | null;\n StartedAt: Date | null;\n CompletedAt: Date | null;\n}\n\n/** The persisted state of one interactive channel of the reviewed session. */\nexport interface RealtimeSessionReviewChannelState {\n /** Channel display name (e.g. `Whiteboard`), denormalized on the session-channel row. */\n ChannelName: string;\n /** The channel's serialized state of record (`AIAgentSessionChannel.Config`), or null when none was saved. */\n StateJson: string | null;\n}\n\n/**\n * MULTI-LEG channel-state merge: folds every leg's channel rows into one state set,\n * NEWEST leg wins per channel name — but only a leg that actually SAVED state counts.\n * A resumed session whose final leg never touched the whiteboard therefore still\n * reviews with the board an EARLIER leg drew (previously only the primary/newest leg's\n * rows were consulted, so that board silently vanished from review).\n *\n * @param legChannelStates Per-leg channel states, ordered OLDEST → NEWEST (the chain order).\n * @returns One entry per channel name (case-insensitive), each from the newest leg that\n * saved a non-empty state; channels no leg ever saved keep a null-state entry so the\n * review still knows the channel existed.\n */\nexport function MergeChainChannelStates(\n legChannelStates: ReadonlyArray<ReadonlyArray<RealtimeSessionReviewChannelState>>\n): RealtimeSessionReviewChannelState[] {\n const byName = new Map<string, RealtimeSessionReviewChannelState>();\n for (const leg of legChannelStates) {\n for (const state of leg) {\n const key = state.ChannelName.trim().toLowerCase();\n if (key.length === 0) {\n continue;\n }\n const existing = byName.get(key);\n const hasState = typeof state.StateJson === 'string' && state.StateJson.trim().length > 0;\n // Later legs are newer: a saved state always supersedes; a null/empty state only\n // registers the channel's existence and never clobbers an earlier saved board.\n if (!existing || hasState) {\n byName.set(key, hasState ? state : (existing ?? state));\n }\n }\n }\n return [...byName.values()];\n}\n\n/**\n * One LEG of a reviewed session chain: a single `MJ: AI Agent Sessions` row plus its own\n * caption turns and delegated-run previews. A session resumed via `lastSessionId` chains\n * legs together (newest leg's `LastSessionID` → prior leg); the review loader walks that\n * chain BACKWARDS (capped — see the loader docs) so review mode can render the FULL\n * conversation arc chronologically, with a divider between legs.\n */\nexport interface RealtimeSessionReviewLeg {\n /** `MJ: AI Agent Sessions.ID` of this leg. */\n SessionID: string;\n /** When this leg started (`__mj_CreatedAt`). */\n StartedAt: Date | null;\n /** When this leg closed (null while still open). */\n ClosedAt: Date | null;\n /** Why this leg closed (null while open / legacy rows). */\n CloseReason: RealtimeReviewCloseReason | null;\n /** This leg's chronological caption turns (oldest first). */\n Turns: RealtimeSessionReviewTurn[];\n /** This leg's delegated-run previews (oldest first, minus its co-agent observability run). */\n DelegatedRuns: RealtimeSessionReviewRun[];\n}\n\n/**\n * Everything the call overlay's SESSION REVIEW mode renders for one past realtime session:\n * the session identity/lifecycle row, the chronological caption turns, previews of the\n * delegated runs, and the saved per-channel states (e.g. the whiteboard board).\n */\nexport interface RealtimeSessionReview {\n /** `MJ: AI Agent Sessions.ID` of the reviewed session. */\n SessionID: string;\n /** The session's fronting agent id (`AIAgentSession.AgentID` — usually the Realtime Co-Agent). */\n AgentID: string;\n /** Display name shown in the review banner (target agent when resolvable, else the session agent). */\n AgentName: string;\n /**\n * The agent a RESUMED live session should front: the session Config's `targetAgentID`,\n * falling back to the session's own `AgentID` when the config doesn't carry one.\n */\n TargetAgentID: string;\n /** Conversation the session was bound to, when any. */\n ConversationID: string | null;\n Status: 'Active' | 'Closed' | 'Idle';\n CloseReason: RealtimeReviewCloseReason | null;\n /** When the session started (`__mj_CreatedAt`). */\n StartedAt: Date | null;\n LastActiveAt: Date | null;\n ClosedAt: Date | null;\n /** Chronological caption turns (oldest first) — ALL legs of the chain, flattened. */\n Turns: RealtimeSessionReviewTurn[];\n /** Delegated run previews (oldest first, all legs), minus each leg's co-agent observability run. */\n DelegatedRuns: RealtimeSessionReviewRun[];\n /**\n * Saved channel states, one per session-channel row that carried a name. Channel state\n * (e.g. the whiteboard board) is the LATEST leg's only — earlier legs' states were\n * superseded when the chain resumed.\n */\n ChannelStates: RealtimeSessionReviewChannelState[];\n /**\n * The session-chain LEGS, chronological (oldest first; the LAST leg is the reviewed\n * session itself). Single-session reviews carry exactly one leg. Drives the per-leg\n * dividers `BuildReviewThreadItems` renders.\n */\n Legs: RealtimeSessionReviewLeg[];\n /**\n * ARTIFACTS attached to the chain's conversation history: every `MJ: Conversation\n * Detail Artifacts` junction (Direction `Output`) hanging off the chain's\n * session-stamped `Conversation Details`, resolved to `{ArtifactID, ArtifactVersionID,\n * Name}`. Review mode registers each as an (unfocused) artifact tab on the surface\n * panel, and they carry into a resumed live session. Empty when none / on any\n * tolerated load failure.\n */\n Artifacts: ParsedDelegationArtifact[];\n}\n\n// ── Raw row shapes (ResultType: 'simple', narrowed Fields) ──────────────────\n\ninterface SessionRow {\n ID: string;\n AgentID: string;\n Agent: string | null;\n Status: 'Active' | 'Closed' | 'Idle';\n ConversationID: string | null;\n Config: string | null;\n LastSessionID: string | null;\n LastActiveAt: string | null;\n ClosedAt: string | null;\n CloseReason: RealtimeReviewCloseReason | null;\n __mj_CreatedAt: string | null;\n}\n\ninterface DetailRow {\n ID: string;\n Role: 'AI' | 'Error' | 'User';\n Message: string | null;\n HiddenToUser: boolean;\n __mj_CreatedAt: string | null;\n}\n\ninterface RunRow {\n ID: string;\n AgentID: string;\n Agent: string | null;\n Status: string;\n Success: boolean | null;\n Message: string | null;\n ErrorMessage: string | null;\n FinalStep: string | null;\n StartedAt: string | null;\n CompletedAt: string | null;\n}\n\ninterface ChannelRow {\n ID: string;\n Channel: string | null;\n Config: string | null;\n}\n\ninterface DetailArtifactJunctionRow {\n ID: string;\n ConversationDetailID: string;\n ArtifactVersionID: string | null;\n}\n\ninterface ArtifactVersionRow {\n ID: string;\n ArtifactID: string;\n /** Version display name (nullable on the row). */\n Name: string | null;\n /** Denormalized parent-artifact name from the version view. */\n Artifact: string | null;\n}\n\n/** The raw rows of ONE chain leg, before mapping to the public review shapes. */\ninterface LegRows {\n session: SessionRow;\n details: DetailRow[];\n runs: RunRow[];\n channels: ChannelRow[];\n}\n\n/** The Config-JSON keys the realtime voice stack persists on `AIAgentSession.Config`. */\ninterface SessionConfigJson {\n targetAgentID?: string;\n coAgentRunID?: string;\n}\n\nconst SESSION_FIELDS = ['ID', 'AgentID', 'Agent', 'Status', 'ConversationID', 'Config', 'LastSessionID', 'LastActiveAt', 'ClosedAt', 'CloseReason', '__mj_CreatedAt'];\nconst DETAIL_FIELDS = ['ID', 'Role', 'Message', 'HiddenToUser', '__mj_CreatedAt'];\nconst RUN_FIELDS = ['ID', 'AgentID', 'Agent', 'Status', 'Success', 'Message', 'ErrorMessage', 'FinalStep', 'StartedAt', 'CompletedAt'];\nconst CHANNEL_FIELDS = ['ID', 'Channel', 'Config'];\nconst JUNCTION_FIELDS = ['ID', 'ConversationDetailID', 'ArtifactVersionID'];\nconst VERSION_FIELDS = ['ID', 'ArtifactID', 'Name', 'Artifact'];\n\n/** Maximum number of chain legs the review loader walks (the reviewed session included). */\nexport const MAX_REVIEW_LEGS = 5;\n/** Maximum total caption-detail rows loaded across the whole chain (oldest legs trimmed first). */\nexport const MAX_REVIEW_DETAILS = 500;\n\n// ── Review → thread-item mapping (pure, unit-testable) ──────────────────────\n\n/** Maps one delegated-run preview to the done delegation-card VM the thread/rail render. */\nexport function BuildReviewDelegationCard(run: RealtimeSessionReviewRun, fallbackAgentName: string): RealtimeDelegationCardVM {\n const startedAt = run.StartedAt?.getTime() ?? 0;\n return {\n CallID: run.RunID,\n AgentName: run.AgentName || fallbackAgentName,\n LatestMessage: run.Message ?? run.ErrorMessage ?? run.Status,\n LatestStep: run.FinalStep ?? '',\n Done: true,\n Success: run.Success,\n RunRef: shortRunRef(run.RunID),\n RunID: run.RunID,\n Result: run.Message ?? run.ErrorMessage ?? null,\n StartedAt: startedAt,\n FinishedAt: run.CompletedAt?.getTime() ?? startedAt\n };\n}\n\n/**\n * Builds the chronological thread (caption turns + done delegation cards, oldest first)\n * for a reviewed session — the items `RealtimeSessionState.LoadHistoricalItems` takes.\n *\n * CHAIN-AWARE: when the review carries multiple {@link RealtimeSessionReview.Legs}, each\n * leg's items render in leg order with a `divider` item between legs (\"Session leg\n * started · <time>\", carrying the PREVIOUS leg's CloseReason as a chip). A single-leg\n * review (or a legless legacy shape) renders the flat thread with no divider —\n * byte-identical to the pre-chain behavior.\n */\nexport function BuildReviewThreadItems(review: RealtimeSessionReview): RealtimeThreadItem[] {\n const legs = review.Legs ?? [];\n if (legs.length <= 1) {\n const only = legs[0];\n return buildLegThreadItems(only?.Turns ?? review.Turns, only?.DelegatedRuns ?? review.DelegatedRuns, review.AgentName);\n }\n const items: RealtimeThreadItem[] = [];\n legs.forEach((leg, i) => {\n if (i > 0) {\n items.push({\n Kind: 'divider',\n Label: 'Session leg started',\n At: leg.StartedAt,\n Icon: 'fa-solid fa-arrows-rotate',\n CloseReason: legs[i - 1].CloseReason ?? null\n });\n }\n items.push(...buildLegThreadItems(leg.Turns, leg.DelegatedRuns, review.AgentName));\n });\n return items;\n}\n\n/**\n * Builds ONE leg's chronological items (caption turns + done delegation cards, oldest\n * first). Entries without a timestamp sort to the front, preserving their relative order.\n */\nfunction buildLegThreadItems(\n turns: RealtimeSessionReviewTurn[],\n runs: RealtimeSessionReviewRun[],\n fallbackAgentName: string\n): RealtimeThreadItem[] {\n const stamped: Array<{ At: number; Item: RealtimeThreadItem }> = [];\n for (const turn of turns) {\n stamped.push({ At: turn.At?.getTime() ?? 0, Item: { Kind: 'caption', Role: turn.Role, Text: turn.Text } });\n }\n for (const run of runs) {\n stamped.push({ At: run.StartedAt?.getTime() ?? 0, Item: { Kind: 'delegation', Card: BuildReviewDelegationCard(run, fallbackAgentName) } });\n }\n // Array.prototype.sort is stable — equal timestamps keep their build order.\n stamped.sort((a, b) => a.At - b.At);\n return stamped.map(s => s.Item);\n}\n\n/** Derives a short run reference (e.g. \"#a3f1\") from the run id — mirrors the live cards. */\nfunction shortRunRef(runId: string): string {\n const compact = runId.replace(/[^a-z0-9]/gi, '');\n return compact.length >= 4 ? `#${compact.slice(-4).toLowerCase()}` : `#${compact.toLowerCase()}`;\n}\n\n/**\n * STATELESS loader for the call overlay's SESSION REVIEW mode: given a past\n * `MJ: AI Agent Sessions` id, batch-loads the session row, its persisted caption turns\n * (`MJ: Conversation Details` linked by `AgentSessionID`), its delegated agent runs\n * (minus the co-agent observability run named in the session Config's `coAgentRunID`),\n * and its saved channel states — and folds them into one {@link RealtimeSessionReview}.\n *\n * CHAIN-AWARE: when the reviewed session carries a `LastSessionID` (it RESUMED an earlier\n * session), the loader walks the chain BACKWARDS — capped at {@link MAX_REVIEW_LEGS} legs\n * and {@link MAX_REVIEW_DETAILS} caption rows total (oldest legs trimmed first), with a\n * cycle guard so a corrupt A→B→A chain can never loop — and surfaces ALL legs\n * chronologically on {@link RealtimeSessionReview.Legs}. Channel state stays the\n * reviewed (latest) leg's only. The chain's conversation-history ARTIFACTS (junction\n * rows on the session-stamped details) are collected onto\n * {@link RealtimeSessionReview.Artifacts}.\n *\n * TOLERANT by design: any missing piece degrades to an empty collection; the loader\n * returns `null` only when the reviewed session row itself can't be found.\n */\n@Injectable({ providedIn: 'root' })\nexport class RealtimeSessionReviewService {\n /**\n * Loads everything review mode renders for one past session (and its prior-leg chain).\n *\n * @param agentSessionId The `MJ: AI Agent Sessions.ID` to review.\n * @param provider Optional metadata provider (multi-server apps); falls back to the global default.\n * @returns The assembled review, or `null` when the session doesn't exist / can't be read.\n */\n public async LoadSessionReview(agentSessionId: string, provider?: IMetadataProvider): Promise<RealtimeSessionReview | null> {\n const trimmed = agentSessionId?.trim() ?? '';\n if (trimmed.length === 0) {\n return null;\n }\n try {\n const md = provider ?? Metadata.Provider;\n const primary = await this.loadLegRows(trimmed, md, true);\n if (!primary) {\n return null;\n }\n const chain = await this.collectChainLegs(primary, md);\n const artifacts = await this.loadChainArtifacts(chain, md);\n return this.assembleReview(chain, artifacts);\n } catch (error) {\n console.error('[RealtimeSessionReview] Failed to load session review:', error);\n return null;\n }\n }\n\n /**\n * One batched RunViews pass for one chain leg: session row + caption turns + linked\n * runs (+ channel rows for the PRIMARY leg only — channel state is latest-leg-only).\n * Returns `null` when the session row can't be found.\n */\n private async loadLegRows(\n agentSessionId: string,\n provider: IMetadataProvider,\n includeChannels: boolean\n ): Promise<LegRows | null> {\n const safeID = agentSessionId.replace(/'/g, \"''\");\n const rv = RunView.FromMetadataProvider(provider);\n const queries: RunViewParams[] = [\n { EntityName: 'MJ: AI Agent Sessions', ExtraFilter: `ID='${safeID}'`, Fields: SESSION_FIELDS, ResultType: 'simple' as const },\n {\n EntityName: 'MJ: Conversation Details', ExtraFilter: `AgentSessionID='${safeID}'`, Fields: DETAIL_FIELDS,\n OrderBy: '__mj_CreatedAt ASC', MaxRows: MAX_REVIEW_DETAILS, ResultType: 'simple' as const\n },\n { EntityName: 'MJ: AI Agent Runs', ExtraFilter: `AgentSessionID='${safeID}'`, Fields: RUN_FIELDS, OrderBy: 'StartedAt ASC', ResultType: 'simple' as const }\n ];\n if (includeChannels) {\n queries.push({ EntityName: 'MJ: AI Agent Session Channels', ExtraFilter: `AgentSessionID='${safeID}'`, Fields: CHANNEL_FIELDS, ResultType: 'simple' as const });\n }\n const [sessionResult, detailResult, runResult, channelResult] = await rv.RunViews(queries);\n const sessions = (sessionResult?.Success ? sessionResult.Results : []) as SessionRow[];\n const session = sessions[0] ?? null;\n if (!session) {\n return null;\n }\n return {\n session,\n details: (detailResult?.Success ? detailResult.Results : []) as DetailRow[],\n runs: (runResult?.Success ? runResult.Results : []) as RunRow[],\n channels: (channelResult?.Success ? channelResult.Results : []) as ChannelRow[]\n };\n }\n\n /**\n * Walks the `LastSessionID` chain BACKWARDS from the reviewed (primary) leg, collecting\n * raw leg rows OLDEST-FIRST (primary last). Safety rails:\n * - at most {@link MAX_REVIEW_LEGS} legs total;\n * - at most {@link MAX_REVIEW_DETAILS} caption rows across the chain — an older leg\n * whose details would overflow the budget is trimmed to its NEWEST rows and ends\n * the walk;\n * - a visited-set cycle guard (case-insensitive ids) so A→B→A can never loop;\n * - a leg that fails to load simply ends the walk (the collected legs still render).\n */\n private async collectChainLegs(primary: LegRows, provider: IMetadataProvider): Promise<LegRows[]> {\n const chain: LegRows[] = [primary];\n const visited = new Set<string>([this.normalizeID(primary.session.ID)]);\n let cursor = primary.session.LastSessionID ?? null;\n let detailBudget = MAX_REVIEW_DETAILS - primary.details.length;\n\n while (cursor && chain.length < MAX_REVIEW_LEGS && detailBudget > 0) {\n const key = this.normalizeID(cursor);\n if (visited.has(key)) {\n console.warn(`[RealtimeSessionReview] Session chain cycle detected at ${cursor} — stopping the walk.`);\n break;\n }\n visited.add(key);\n const leg = await this.loadLegRows(cursor, provider, false);\n if (!leg) {\n break;\n }\n if (leg.details.length > detailBudget) {\n // Keep this leg's NEWEST rows (details arrive oldest-first) and end the walk.\n leg.details = leg.details.slice(leg.details.length - detailBudget);\n detailBudget = 0;\n } else {\n detailBudget -= leg.details.length;\n }\n chain.unshift(leg);\n cursor = leg.session.LastSessionID ?? null;\n }\n return chain;\n }\n\n /**\n * Collects the chain's conversation-history ARTIFACTS: `MJ: Conversation Detail\n * Artifacts` junction rows (Direction `Output`) hanging off the chain's session-stamped\n * details, resolved through `MJ: Artifact Versions` to `{ArtifactID, ArtifactVersionID,\n * Name}` (version name, falling back to the artifact name). Order follows junction\n * creation; duplicate versions are deduped. TOLERANT: any failure returns `[]`.\n */\n private async loadChainArtifacts(chain: LegRows[], provider: IMetadataProvider): Promise<ParsedDelegationArtifact[]> {\n const detailIDs = chain.flatMap(leg => leg.details.map(d => d.ID)).filter(id => typeof id === 'string' && id.length > 0);\n if (detailIDs.length === 0) {\n return [];\n }\n try {\n const rv = RunView.FromMetadataProvider(provider);\n const detailList = detailIDs.map(id => `'${id.replace(/'/g, \"''\")}'`).join(',');\n const [junctionResult] = await rv.RunViews([{\n EntityName: 'MJ: Conversation Detail Artifacts',\n ExtraFilter: `ConversationDetailID IN (${detailList}) AND Direction='Output'`,\n Fields: JUNCTION_FIELDS,\n OrderBy: '__mj_CreatedAt ASC',\n ResultType: 'simple'\n }]);\n const junctions = (junctionResult?.Success ? junctionResult.Results : []) as DetailArtifactJunctionRow[];\n const versionIDs = this.uniqueVersionIDs(junctions);\n if (versionIDs.length === 0) {\n return [];\n }\n\n const versionList = versionIDs.map(id => `'${id.replace(/'/g, \"''\")}'`).join(',');\n const [versionResult] = await rv.RunViews([{\n EntityName: 'MJ: Artifact Versions',\n ExtraFilter: `ID IN (${versionList})`,\n Fields: VERSION_FIELDS,\n ResultType: 'simple'\n }]);\n const versions = (versionResult?.Success ? versionResult.Results : []) as ArtifactVersionRow[];\n const byID = new Map<string, ArtifactVersionRow>(versions.map(v => [this.normalizeID(v.ID), v]));\n\n const artifacts: ParsedDelegationArtifact[] = [];\n for (const versionID of versionIDs) {\n const row = byID.get(this.normalizeID(versionID));\n if (!row?.ArtifactID) {\n continue; // junction points at an unreadable / deleted version — skip\n }\n artifacts.push({\n ArtifactID: row.ArtifactID,\n ArtifactVersionID: row.ID,\n Name: row.Name?.trim() || row.Artifact?.trim() || 'Artifact'\n });\n }\n return artifacts;\n } catch (error) {\n console.warn('[RealtimeSessionReview] Artifact collection failed — review renders without artifact tabs.', error);\n return [];\n }\n }\n\n /** Unique, non-empty `ArtifactVersionID`s from junction rows, in arrival order (case-insensitive dedupe). */\n private uniqueVersionIDs(junctions: DetailArtifactJunctionRow[]): string[] {\n const seen = new Set<string>();\n const ids: string[] = [];\n for (const j of junctions) {\n const id = typeof j.ArtifactVersionID === 'string' ? j.ArtifactVersionID.trim() : '';\n if (id.length === 0 || seen.has(this.normalizeID(id))) {\n continue;\n }\n seen.add(this.normalizeID(id));\n ids.push(id);\n }\n return ids;\n }\n\n /** Case-insensitive UUID key for Set/Map membership (SQL Server uppercase vs PostgreSQL lowercase). */\n private normalizeID(id: string): string {\n return (id ?? '').trim().toLowerCase();\n }\n\n /**\n * Folds the chain's raw leg rows into the typed review. The PRIMARY (reviewed) leg —\n * the chain's LAST entry — supplies identity/lifecycle/channel state; turns and runs\n * are surfaced both per-leg (`Legs`) and flattened chronologically (`Turns` /\n * `DelegatedRuns`). Each leg excludes ITS OWN config's co-agent observability run.\n */\n private assembleReview(chain: LegRows[], artifacts: ParsedDelegationArtifact[]): RealtimeSessionReview {\n const primary = chain[chain.length - 1];\n const session = primary.session;\n const config = this.parseSessionConfig(session.Config);\n const legs = chain.map(leg => this.mapLeg(leg));\n return {\n SessionID: session.ID,\n AgentID: session.AgentID,\n AgentName: session.Agent || 'the agent',\n TargetAgentID: config.targetAgentID ?? session.AgentID,\n ConversationID: session.ConversationID ?? null,\n Status: session.Status,\n CloseReason: session.CloseReason ?? null,\n StartedAt: this.toDate(session.__mj_CreatedAt),\n LastActiveAt: this.toDate(session.LastActiveAt),\n ClosedAt: this.toDate(session.ClosedAt),\n Turns: legs.flatMap(l => l.Turns),\n DelegatedRuns: legs.flatMap(l => l.DelegatedRuns),\n // Multi-leg: newest leg with a SAVED state wins per channel — a final leg that\n // never touched the board no longer hides an earlier leg's drawing from review.\n ChannelStates: MergeChainChannelStates(chain.map(leg => this.mapChannels(leg.channels))),\n Legs: legs,\n Artifacts: artifacts\n };\n }\n\n /** Maps one leg's raw rows to the public leg shape (per-leg co-agent-run exclusion). */\n private mapLeg(leg: LegRows): RealtimeSessionReviewLeg {\n const config = this.parseSessionConfig(leg.session.Config);\n return {\n SessionID: leg.session.ID,\n StartedAt: this.toDate(leg.session.__mj_CreatedAt),\n ClosedAt: this.toDate(leg.session.ClosedAt),\n CloseReason: leg.session.CloseReason ?? null,\n Turns: this.mapTurns(leg.details),\n DelegatedRuns: this.mapRuns(leg.runs, config.coAgentRunID ?? null)\n };\n }\n\n /** Persisted detail rows → caption turns: visible `User`/`AI` rows with text (AI → Assistant). */\n private mapTurns(details: DetailRow[]): RealtimeSessionReviewTurn[] {\n const turns: RealtimeSessionReviewTurn[] = [];\n for (const row of details) {\n const text = row.Message?.trim() ?? '';\n if (row.HiddenToUser || text.length === 0 || (row.Role !== 'User' && row.Role !== 'AI')) {\n continue;\n }\n turns.push({\n Role: row.Role === 'AI' ? 'Assistant' : 'User',\n Text: text,\n At: this.toDate(row.__mj_CreatedAt)\n });\n }\n return turns;\n }\n\n /** Linked run rows → delegated-run previews, EXCLUDING the co-agent's observability run. */\n private mapRuns(runs: RunRow[], coAgentRunId: string | null): RealtimeSessionReviewRun[] {\n return runs\n .filter(r => !coAgentRunId || !UUIDsEqual(r.ID, coAgentRunId))\n .map(r => ({\n RunID: r.ID,\n AgentID: r.AgentID,\n AgentName: r.Agent ?? null,\n Status: r.Status ?? '',\n Success: r.Success === true,\n Message: r.Message ?? null,\n ErrorMessage: r.ErrorMessage ?? null,\n FinalStep: r.FinalStep ?? null,\n StartedAt: this.toDate(r.StartedAt),\n CompletedAt: this.toDate(r.CompletedAt)\n }));\n }\n\n /** Session-channel rows → named channel states (rows without a channel name are skipped). */\n private mapChannels(channels: ChannelRow[]): RealtimeSessionReviewChannelState[] {\n return channels\n .filter(c => !!c.Channel)\n .map(c => ({ ChannelName: c.Channel as string, StateJson: c.Config ?? null }));\n }\n\n /** Tolerant Config JSON parse — malformed/missing payloads degrade to `{}`. */\n private parseSessionConfig(raw: string | null): SessionConfigJson {\n if (!raw) {\n return {};\n }\n try {\n const parsed = JSON.parse(raw) as SessionConfigJson;\n return parsed && typeof parsed === 'object' ? parsed : {};\n } catch {\n return {};\n }\n }\n\n /** Tolerant date conversion — view rows arrive as ISO strings (or Dates from some providers). */\n private toDate(value: string | Date | null | undefined): Date | null {\n if (value == null) {\n return null;\n }\n const date = value instanceof Date ? value : new Date(value);\n return isNaN(date.getTime()) ? null : date;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"realtime-session-review.service.js","sourceRoot":"","sources":["../../../src/lib/services/realtime-session-review.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { IMetadataProvider, Metadata, RunView, RunViewParams } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { RealtimeDelegationCardVM, RealtimeThreadItem } from '../components/realtime/realtime-session-state';\nimport { ParsedDelegationArtifact } from './delegation-result-parser';\n\n/**\n * Why a reviewed session was closed, as stamped server-side by `SessionManager.CloseSession`\n * (mirrors `MJAIAgentSessionEntity.CloseReason`). `null` means the session is still open OR a\n * legacy row was closed before the column existed.\n */\nexport type RealtimeReviewCloseReason = 'Error' | 'Explicit' | 'Janitor' | 'Shutdown';\n\n/**\n * One historical caption turn of a reviewed session (a persisted `MJ: Conversation Details` row).\n *\n * Carries BOTH the thread-rendering fields (`Role`/`Text`/`At`) AND the raw fields the time-aligned\n * evidence player reads (`ID`, `Message`, `__mj_CreatedAt`, `UtteranceStartMs`, `UtteranceEndMs`) so\n * a review's turns can be handed straight to {@link RealtimeEvidencePlaybackComponent} for the\n * Recording tab — this shape structurally satisfies that player's `EvidencePlaybackTurn` input.\n */\nexport interface RealtimeSessionReviewTurn {\n /** `MJ: Conversation Details.ID` — the player's `@for` track key. */\n ID: string;\n /** Who spoke the turn. Persisted `AI` rows map to `Assistant`. */\n Role: 'User' | 'Assistant';\n /** The transcript text. */\n Text: string;\n /** The raw transcript text (mirrors {@link Text}) — the player reads `Message`. */\n Message: string | null;\n /** When the turn was persisted (`__mj_CreatedAt`), or null when unknown. Aliases {@link At}. */\n __mj_CreatedAt: Date | null;\n /** When the turn was persisted (`__mj_CreatedAt`), or null when unknown. */\n At: Date | null;\n /** Precise media-relative start (ms from recording t0), or null when the driver supplied no timing. */\n UtteranceStartMs: number | null;\n /** Precise media-relative end (ms from recording t0), or null. */\n UtteranceEndMs: number | null;\n}\n\n/**\n * A compact preview of one DELEGATED agent run the reviewed session spawned (an\n * `MJ: AI Agent Runs` row linked via `AgentSessionID`, EXCLUDING the co-agent's own\n * observability run). Carries just enough to render a done delegation card.\n */\nexport interface RealtimeSessionReviewRun {\n /** `MJ: AI Agent Runs.ID`. */\n RunID: string;\n /** The delegated agent's id. */\n AgentID: string;\n /** Denormalized agent display name from the run view, when available. */\n AgentName: string | null;\n /** Terminal (or last-known) run status (`Completed` | `Failed` | `Running` | …). */\n Status: string;\n /** Whether the run reported success. */\n Success: boolean;\n /** The run's user-facing result message, when one was recorded. */\n Message: string | null;\n /** The run's error message, when it failed. */\n ErrorMessage: string | null;\n /** The final step the run reported (`Success` | `Failed` | `Retry` | …), when known. */\n FinalStep: string | null;\n StartedAt: Date | null;\n CompletedAt: Date | null;\n}\n\n/** The persisted state of one interactive channel of the reviewed session. */\nexport interface RealtimeSessionReviewChannelState {\n /** Channel display name (e.g. `Whiteboard`), denormalized on the session-channel row. */\n ChannelName: string;\n /** The channel's serialized state of record (`AIAgentSessionChannel.Config`), or null when none was saved. */\n StateJson: string | null;\n}\n\n/**\n * MULTI-LEG channel-state merge: folds every leg's channel rows into one state set,\n * NEWEST leg wins per channel name — but only a leg that actually SAVED state counts.\n * A resumed session whose final leg never touched the whiteboard therefore still\n * reviews with the board an EARLIER leg drew (previously only the primary/newest leg's\n * rows were consulted, so that board silently vanished from review).\n *\n * @param legChannelStates Per-leg channel states, ordered OLDEST → NEWEST (the chain order).\n * @returns One entry per channel name (case-insensitive), each from the newest leg that\n * saved a non-empty state; channels no leg ever saved keep a null-state entry so the\n * review still knows the channel existed.\n */\nexport function MergeChainChannelStates(\n legChannelStates: ReadonlyArray<ReadonlyArray<RealtimeSessionReviewChannelState>>\n): RealtimeSessionReviewChannelState[] {\n const byName = new Map<string, RealtimeSessionReviewChannelState>();\n for (const leg of legChannelStates) {\n for (const state of leg) {\n const key = state.ChannelName.trim().toLowerCase();\n if (key.length === 0) {\n continue;\n }\n const existing = byName.get(key);\n const hasState = typeof state.StateJson === 'string' && state.StateJson.trim().length > 0;\n // Later legs are newer: a saved state always supersedes; a null/empty state only\n // registers the channel's existence and never clobbers an earlier saved board.\n if (!existing || hasState) {\n byName.set(key, hasState ? state : (existing ?? state));\n }\n }\n }\n return [...byName.values()];\n}\n\n/**\n * One LEG of a reviewed session chain: a single `MJ: AI Agent Sessions` row plus its own\n * caption turns and delegated-run previews. A session resumed via `lastSessionId` chains\n * legs together (newest leg's `LastSessionID` → prior leg); the review loader walks that\n * chain BACKWARDS (capped — see the loader docs) so review mode can render the FULL\n * conversation arc chronologically, with a divider between legs.\n */\nexport interface RealtimeSessionReviewLeg {\n /** `MJ: AI Agent Sessions.ID` of this leg. */\n SessionID: string;\n /** When this leg started (`__mj_CreatedAt`). */\n StartedAt: Date | null;\n /** When this leg closed (null while still open). */\n ClosedAt: Date | null;\n /** Why this leg closed (null while open / legacy rows). */\n CloseReason: RealtimeReviewCloseReason | null;\n /** This leg's chronological caption turns (oldest first). */\n Turns: RealtimeSessionReviewTurn[];\n /** This leg's delegated-run previews (oldest first, minus its co-agent observability run). */\n DelegatedRuns: RealtimeSessionReviewRun[];\n}\n\n/**\n * Everything the call overlay's SESSION REVIEW mode renders for one past realtime session:\n * the session identity/lifecycle row, the chronological caption turns, previews of the\n * delegated runs, and the saved per-channel states (e.g. the whiteboard board).\n */\nexport interface RealtimeSessionReview {\n /** `MJ: AI Agent Sessions.ID` of the reviewed session. */\n SessionID: string;\n /** The session's fronting agent id (`AIAgentSession.AgentID` — usually the Realtime Co-Agent). */\n AgentID: string;\n /** Display name shown in the review banner (target agent when resolvable, else the session agent). */\n AgentName: string;\n /**\n * The agent a RESUMED live session should front: the session Config's `targetAgentID`,\n * falling back to the session's own `AgentID` when the config doesn't carry one.\n */\n TargetAgentID: string;\n /** Conversation the session was bound to, when any. */\n ConversationID: string | null;\n Status: 'Active' | 'Closed' | 'Idle';\n CloseReason: RealtimeReviewCloseReason | null;\n /** When the session started (`__mj_CreatedAt`). */\n StartedAt: Date | null;\n LastActiveAt: Date | null;\n ClosedAt: Date | null;\n /**\n * The `MJ: Files` id of the reviewed session's recorded audio, or null when nothing was recorded.\n * When set, review mode resolves a signed download URL and shows a Recording tab with the\n * time-aligned evidence player. From the PRIMARY (reviewed) leg only.\n */\n RecordingFileID: string | null;\n /** Recording alignment origin (t0), used by the playback transcript sync. From the primary leg. */\n RecordingStartedAt: Date | null;\n /** What was captured (`Audio` / `AudioVideo`), or null. From the primary leg. */\n RecordingMedia: string | null;\n /** Chronological caption turns (oldest first) — ALL legs of the chain, flattened. */\n Turns: RealtimeSessionReviewTurn[];\n /** Delegated run previews (oldest first, all legs), minus each leg's co-agent observability run. */\n DelegatedRuns: RealtimeSessionReviewRun[];\n /**\n * Saved channel states, one per session-channel row that carried a name. Channel state\n * (e.g. the whiteboard board) is the LATEST leg's only — earlier legs' states were\n * superseded when the chain resumed.\n */\n ChannelStates: RealtimeSessionReviewChannelState[];\n /**\n * The session-chain LEGS, chronological (oldest first; the LAST leg is the reviewed\n * session itself). Single-session reviews carry exactly one leg. Drives the per-leg\n * dividers `BuildReviewThreadItems` renders.\n */\n Legs: RealtimeSessionReviewLeg[];\n /**\n * ARTIFACTS attached to the chain's conversation history: every `MJ: Conversation\n * Detail Artifacts` junction (Direction `Output`) hanging off the chain's\n * session-stamped `Conversation Details`, resolved to `{ArtifactID, ArtifactVersionID,\n * Name}`. Review mode registers each as an (unfocused) artifact tab on the surface\n * panel, and they carry into a resumed live session. Empty when none / on any\n * tolerated load failure.\n */\n Artifacts: ParsedDelegationArtifact[];\n}\n\n// ── Raw row shapes (ResultType: 'simple', narrowed Fields) ──────────────────\n\ninterface SessionRow {\n ID: string;\n AgentID: string;\n Agent: string | null;\n Status: 'Active' | 'Closed' | 'Idle';\n ConversationID: string | null;\n Config: string | null;\n LastSessionID: string | null;\n LastActiveAt: string | null;\n ClosedAt: string | null;\n CloseReason: RealtimeReviewCloseReason | null;\n RecordingFileID: string | null;\n RecordingStartedAt: string | null;\n RecordingMedia: string | null;\n __mj_CreatedAt: string | null;\n}\n\ninterface DetailRow {\n ID: string;\n Role: 'AI' | 'Error' | 'User';\n Message: string | null;\n HiddenToUser: boolean;\n UserID: string | null;\n Status: string | null;\n UtteranceStartMs: number | null;\n UtteranceEndMs: number | null;\n __mj_CreatedAt: string | null;\n}\n\ninterface RunRow {\n ID: string;\n AgentID: string;\n Agent: string | null;\n Status: string;\n Success: boolean | null;\n Message: string | null;\n ErrorMessage: string | null;\n FinalStep: string | null;\n StartedAt: string | null;\n CompletedAt: string | null;\n}\n\ninterface ChannelRow {\n ID: string;\n Channel: string | null;\n Config: string | null;\n}\n\ninterface DetailArtifactJunctionRow {\n ID: string;\n ConversationDetailID: string;\n ArtifactVersionID: string | null;\n}\n\ninterface ArtifactVersionRow {\n ID: string;\n ArtifactID: string;\n /** Version display name (nullable on the row). */\n Name: string | null;\n /** Denormalized parent-artifact name from the version view. */\n Artifact: string | null;\n}\n\n/** The raw rows of ONE chain leg, before mapping to the public review shapes. */\ninterface LegRows {\n session: SessionRow;\n details: DetailRow[];\n runs: RunRow[];\n channels: ChannelRow[];\n}\n\n/** The Config-JSON keys the realtime voice stack persists on `AIAgentSession.Config`. */\ninterface SessionConfigJson {\n targetAgentID?: string;\n coAgentRunID?: string;\n}\n\nconst SESSION_FIELDS = ['ID', 'AgentID', 'Agent', 'Status', 'ConversationID', 'Config', 'LastSessionID', 'LastActiveAt', 'ClosedAt', 'CloseReason', 'RecordingFileID', 'RecordingStartedAt', 'RecordingMedia', '__mj_CreatedAt'];\nconst DETAIL_FIELDS = ['ID', 'Role', 'Message', 'HiddenToUser', 'UserID', 'Status', 'UtteranceStartMs', 'UtteranceEndMs', '__mj_CreatedAt'];\nconst RUN_FIELDS = ['ID', 'AgentID', 'Agent', 'Status', 'Success', 'Message', 'ErrorMessage', 'FinalStep', 'StartedAt', 'CompletedAt'];\nconst CHANNEL_FIELDS = ['ID', 'Channel', 'Config'];\nconst JUNCTION_FIELDS = ['ID', 'ConversationDetailID', 'ArtifactVersionID'];\nconst VERSION_FIELDS = ['ID', 'ArtifactID', 'Name', 'Artifact'];\n\n/** Maximum number of chain legs the review loader walks (the reviewed session included). */\nexport const MAX_REVIEW_LEGS = 5;\n/** Maximum total caption-detail rows loaded across the whole chain (oldest legs trimmed first). */\nexport const MAX_REVIEW_DETAILS = 500;\n\n// ── Review → thread-item mapping (pure, unit-testable) ──────────────────────\n\n/** Maps one delegated-run preview to the done delegation-card VM the thread/rail render. */\nexport function BuildReviewDelegationCard(run: RealtimeSessionReviewRun, fallbackAgentName: string): RealtimeDelegationCardVM {\n const startedAt = run.StartedAt?.getTime() ?? 0;\n return {\n CallID: run.RunID,\n AgentName: run.AgentName || fallbackAgentName,\n LatestMessage: run.Message ?? run.ErrorMessage ?? run.Status,\n LatestStep: run.FinalStep ?? '',\n Done: true,\n Success: run.Success,\n RunRef: shortRunRef(run.RunID),\n RunID: run.RunID,\n Result: run.Message ?? run.ErrorMessage ?? null,\n StartedAt: startedAt,\n FinishedAt: run.CompletedAt?.getTime() ?? startedAt\n };\n}\n\n/**\n * Builds the chronological thread (caption turns + done delegation cards, oldest first)\n * for a reviewed session — the items `RealtimeSessionState.LoadHistoricalItems` takes.\n *\n * CHAIN-AWARE: when the review carries multiple {@link RealtimeSessionReview.Legs}, each\n * leg's items render in leg order with a `divider` item between legs (\"Session leg\n * started · <time>\", carrying the PREVIOUS leg's CloseReason as a chip). A single-leg\n * review (or a legless legacy shape) renders the flat thread with no divider —\n * byte-identical to the pre-chain behavior.\n */\nexport function BuildReviewThreadItems(review: RealtimeSessionReview): RealtimeThreadItem[] {\n const legs = review.Legs ?? [];\n if (legs.length <= 1) {\n const only = legs[0];\n return buildLegThreadItems(only?.Turns ?? review.Turns, only?.DelegatedRuns ?? review.DelegatedRuns, review.AgentName);\n }\n const items: RealtimeThreadItem[] = [];\n legs.forEach((leg, i) => {\n if (i > 0) {\n items.push({\n Kind: 'divider',\n Label: 'Session leg started',\n At: leg.StartedAt,\n Icon: 'fa-solid fa-arrows-rotate',\n CloseReason: legs[i - 1].CloseReason ?? null\n });\n }\n items.push(...buildLegThreadItems(leg.Turns, leg.DelegatedRuns, review.AgentName));\n });\n return items;\n}\n\n/**\n * Builds ONE leg's chronological items (caption turns + done delegation cards, oldest\n * first). Entries without a timestamp sort to the front, preserving their relative order.\n */\nfunction buildLegThreadItems(\n turns: RealtimeSessionReviewTurn[],\n runs: RealtimeSessionReviewRun[],\n fallbackAgentName: string\n): RealtimeThreadItem[] {\n const stamped: Array<{ At: number; Item: RealtimeThreadItem }> = [];\n for (const turn of turns) {\n stamped.push({ At: turn.At?.getTime() ?? 0, Item: { Kind: 'caption', Role: turn.Role, Text: turn.Text } });\n }\n for (const run of runs) {\n stamped.push({ At: run.StartedAt?.getTime() ?? 0, Item: { Kind: 'delegation', Card: BuildReviewDelegationCard(run, fallbackAgentName) } });\n }\n // Array.prototype.sort is stable — equal timestamps keep their build order.\n stamped.sort((a, b) => a.At - b.At);\n return stamped.map(s => s.Item);\n}\n\n/** Derives a short run reference (e.g. \"#a3f1\") from the run id — mirrors the live cards. */\nfunction shortRunRef(runId: string): string {\n const compact = runId.replace(/[^a-z0-9]/gi, '');\n return compact.length >= 4 ? `#${compact.slice(-4).toLowerCase()}` : `#${compact.toLowerCase()}`;\n}\n\n/**\n * STATELESS loader for the call overlay's SESSION REVIEW mode: given a past\n * `MJ: AI Agent Sessions` id, batch-loads the session row, its persisted caption turns\n * (`MJ: Conversation Details` linked by `AgentSessionID`), its delegated agent runs\n * (minus the co-agent observability run named in the session Config's `coAgentRunID`),\n * and its saved channel states — and folds them into one {@link RealtimeSessionReview}.\n *\n * CHAIN-AWARE: when the reviewed session carries a `LastSessionID` (it RESUMED an earlier\n * session), the loader walks the chain BACKWARDS — capped at {@link MAX_REVIEW_LEGS} legs\n * and {@link MAX_REVIEW_DETAILS} caption rows total (oldest legs trimmed first), with a\n * cycle guard so a corrupt A→B→A chain can never loop — and surfaces ALL legs\n * chronologically on {@link RealtimeSessionReview.Legs}. Channel state stays the\n * reviewed (latest) leg's only. The chain's conversation-history ARTIFACTS (junction\n * rows on the session-stamped details) are collected onto\n * {@link RealtimeSessionReview.Artifacts}.\n *\n * TOLERANT by design: any missing piece degrades to an empty collection; the loader\n * returns `null` only when the reviewed session row itself can't be found.\n */\n@Injectable({ providedIn: 'root' })\nexport class RealtimeSessionReviewService {\n /**\n * Loads everything review mode renders for one past session (and its prior-leg chain).\n *\n * @param agentSessionId The `MJ: AI Agent Sessions.ID` to review.\n * @param provider Optional metadata provider (multi-server apps); falls back to the global default.\n * @returns The assembled review, or `null` when the session doesn't exist / can't be read.\n */\n public async LoadSessionReview(agentSessionId: string, provider?: IMetadataProvider): Promise<RealtimeSessionReview | null> {\n const trimmed = agentSessionId?.trim() ?? '';\n if (trimmed.length === 0) {\n return null;\n }\n try {\n const md = provider ?? Metadata.Provider;\n const primary = await this.loadLegRows(trimmed, md, true);\n if (!primary) {\n return null;\n }\n const chain = await this.collectChainLegs(primary, md);\n const artifacts = await this.loadChainArtifacts(chain, md);\n return this.assembleReview(chain, artifacts);\n } catch (error) {\n console.error('[RealtimeSessionReview] Failed to load session review:', error);\n return null;\n }\n }\n\n /**\n * One batched RunViews pass for one chain leg: session row + caption turns + linked\n * runs (+ channel rows for the PRIMARY leg only — channel state is latest-leg-only).\n * Returns `null` when the session row can't be found.\n */\n private async loadLegRows(\n agentSessionId: string,\n provider: IMetadataProvider,\n includeChannels: boolean\n ): Promise<LegRows | null> {\n const safeID = agentSessionId.replace(/'/g, \"''\");\n const rv = RunView.FromMetadataProvider(provider);\n const queries: RunViewParams[] = [\n { EntityName: 'MJ: AI Agent Sessions', ExtraFilter: `ID='${safeID}'`, Fields: SESSION_FIELDS, ResultType: 'simple' as const },\n {\n EntityName: 'MJ: Conversation Details', ExtraFilter: `AgentSessionID='${safeID}'`, Fields: DETAIL_FIELDS,\n OrderBy: '__mj_CreatedAt ASC', MaxRows: MAX_REVIEW_DETAILS, ResultType: 'simple' as const\n },\n { EntityName: 'MJ: AI Agent Runs', ExtraFilter: `AgentSessionID='${safeID}'`, Fields: RUN_FIELDS, OrderBy: 'StartedAt ASC', ResultType: 'simple' as const }\n ];\n if (includeChannels) {\n queries.push({ EntityName: 'MJ: AI Agent Session Channels', ExtraFilter: `AgentSessionID='${safeID}'`, Fields: CHANNEL_FIELDS, ResultType: 'simple' as const });\n }\n const [sessionResult, detailResult, runResult, channelResult] = await rv.RunViews(queries);\n const sessions = (sessionResult?.Success ? sessionResult.Results : []) as SessionRow[];\n const session = sessions[0] ?? null;\n if (!session) {\n return null;\n }\n return {\n session,\n details: (detailResult?.Success ? detailResult.Results : []) as DetailRow[],\n runs: (runResult?.Success ? runResult.Results : []) as RunRow[],\n channels: (channelResult?.Success ? channelResult.Results : []) as ChannelRow[]\n };\n }\n\n /**\n * Walks the `LastSessionID` chain BACKWARDS from the reviewed (primary) leg, collecting\n * raw leg rows OLDEST-FIRST (primary last). Safety rails:\n * - at most {@link MAX_REVIEW_LEGS} legs total;\n * - at most {@link MAX_REVIEW_DETAILS} caption rows across the chain — an older leg\n * whose details would overflow the budget is trimmed to its NEWEST rows and ends\n * the walk;\n * - a visited-set cycle guard (case-insensitive ids) so A→B→A can never loop;\n * - a leg that fails to load simply ends the walk (the collected legs still render).\n */\n private async collectChainLegs(primary: LegRows, provider: IMetadataProvider): Promise<LegRows[]> {\n const chain: LegRows[] = [primary];\n const visited = new Set<string>([this.normalizeID(primary.session.ID)]);\n let cursor = primary.session.LastSessionID ?? null;\n let detailBudget = MAX_REVIEW_DETAILS - primary.details.length;\n\n while (cursor && chain.length < MAX_REVIEW_LEGS && detailBudget > 0) {\n const key = this.normalizeID(cursor);\n if (visited.has(key)) {\n console.warn(`[RealtimeSessionReview] Session chain cycle detected at ${cursor} — stopping the walk.`);\n break;\n }\n visited.add(key);\n const leg = await this.loadLegRows(cursor, provider, false);\n if (!leg) {\n break;\n }\n if (leg.details.length > detailBudget) {\n // Keep this leg's NEWEST rows (details arrive oldest-first) and end the walk.\n leg.details = leg.details.slice(leg.details.length - detailBudget);\n detailBudget = 0;\n } else {\n detailBudget -= leg.details.length;\n }\n chain.unshift(leg);\n cursor = leg.session.LastSessionID ?? null;\n }\n return chain;\n }\n\n /**\n * Collects the chain's conversation-history ARTIFACTS: `MJ: Conversation Detail\n * Artifacts` junction rows (Direction `Output`) hanging off the chain's session-stamped\n * details, resolved through `MJ: Artifact Versions` to `{ArtifactID, ArtifactVersionID,\n * Name}` (version name, falling back to the artifact name). Order follows junction\n * creation; duplicate versions are deduped. TOLERANT: any failure returns `[]`.\n */\n private async loadChainArtifacts(chain: LegRows[], provider: IMetadataProvider): Promise<ParsedDelegationArtifact[]> {\n const detailIDs = chain.flatMap(leg => leg.details.map(d => d.ID)).filter(id => typeof id === 'string' && id.length > 0);\n if (detailIDs.length === 0) {\n return [];\n }\n try {\n const rv = RunView.FromMetadataProvider(provider);\n const detailList = detailIDs.map(id => `'${id.replace(/'/g, \"''\")}'`).join(',');\n const [junctionResult] = await rv.RunViews([{\n EntityName: 'MJ: Conversation Detail Artifacts',\n ExtraFilter: `ConversationDetailID IN (${detailList}) AND Direction='Output'`,\n Fields: JUNCTION_FIELDS,\n OrderBy: '__mj_CreatedAt ASC',\n ResultType: 'simple'\n }]);\n const junctions = (junctionResult?.Success ? junctionResult.Results : []) as DetailArtifactJunctionRow[];\n const versionIDs = this.uniqueVersionIDs(junctions);\n if (versionIDs.length === 0) {\n return [];\n }\n\n const versionList = versionIDs.map(id => `'${id.replace(/'/g, \"''\")}'`).join(',');\n const [versionResult] = await rv.RunViews([{\n EntityName: 'MJ: Artifact Versions',\n ExtraFilter: `ID IN (${versionList})`,\n Fields: VERSION_FIELDS,\n ResultType: 'simple'\n }]);\n const versions = (versionResult?.Success ? versionResult.Results : []) as ArtifactVersionRow[];\n const byID = new Map<string, ArtifactVersionRow>(versions.map(v => [this.normalizeID(v.ID), v]));\n\n const artifacts: ParsedDelegationArtifact[] = [];\n for (const versionID of versionIDs) {\n const row = byID.get(this.normalizeID(versionID));\n if (!row?.ArtifactID) {\n continue; // junction points at an unreadable / deleted version — skip\n }\n artifacts.push({\n ArtifactID: row.ArtifactID,\n ArtifactVersionID: row.ID,\n Name: row.Name?.trim() || row.Artifact?.trim() || 'Artifact'\n });\n }\n return artifacts;\n } catch (error) {\n console.warn('[RealtimeSessionReview] Artifact collection failed — review renders without artifact tabs.', error);\n return [];\n }\n }\n\n /** Unique, non-empty `ArtifactVersionID`s from junction rows, in arrival order (case-insensitive dedupe). */\n private uniqueVersionIDs(junctions: DetailArtifactJunctionRow[]): string[] {\n const seen = new Set<string>();\n const ids: string[] = [];\n for (const j of junctions) {\n const id = typeof j.ArtifactVersionID === 'string' ? j.ArtifactVersionID.trim() : '';\n if (id.length === 0 || seen.has(this.normalizeID(id))) {\n continue;\n }\n seen.add(this.normalizeID(id));\n ids.push(id);\n }\n return ids;\n }\n\n /** Case-insensitive UUID key for Set/Map membership (SQL Server uppercase vs PostgreSQL lowercase). */\n private normalizeID(id: string): string {\n return (id ?? '').trim().toLowerCase();\n }\n\n /**\n * Folds the chain's raw leg rows into the typed review. The PRIMARY (reviewed) leg —\n * the chain's LAST entry — supplies identity/lifecycle/channel state; turns and runs\n * are surfaced both per-leg (`Legs`) and flattened chronologically (`Turns` /\n * `DelegatedRuns`). Each leg excludes ITS OWN config's co-agent observability run.\n */\n private assembleReview(chain: LegRows[], artifacts: ParsedDelegationArtifact[]): RealtimeSessionReview {\n const primary = chain[chain.length - 1];\n const session = primary.session;\n const config = this.parseSessionConfig(session.Config);\n const legs = chain.map(leg => this.mapLeg(leg));\n return {\n SessionID: session.ID,\n AgentID: session.AgentID,\n AgentName: session.Agent || 'the agent',\n TargetAgentID: config.targetAgentID ?? session.AgentID,\n ConversationID: session.ConversationID ?? null,\n Status: session.Status,\n CloseReason: session.CloseReason ?? null,\n StartedAt: this.toDate(session.__mj_CreatedAt),\n LastActiveAt: this.toDate(session.LastActiveAt),\n ClosedAt: this.toDate(session.ClosedAt),\n RecordingFileID: session.RecordingFileID ?? null,\n RecordingStartedAt: this.toDate(session.RecordingStartedAt),\n RecordingMedia: session.RecordingMedia ?? null,\n Turns: legs.flatMap(l => l.Turns),\n DelegatedRuns: legs.flatMap(l => l.DelegatedRuns),\n // Multi-leg: newest leg with a SAVED state wins per channel — a final leg that\n // never touched the board no longer hides an earlier leg's drawing from review.\n ChannelStates: MergeChainChannelStates(chain.map(leg => this.mapChannels(leg.channels))),\n Legs: legs,\n Artifacts: artifacts\n };\n }\n\n /** Maps one leg's raw rows to the public leg shape (per-leg co-agent-run exclusion). */\n private mapLeg(leg: LegRows): RealtimeSessionReviewLeg {\n const config = this.parseSessionConfig(leg.session.Config);\n return {\n SessionID: leg.session.ID,\n StartedAt: this.toDate(leg.session.__mj_CreatedAt),\n ClosedAt: this.toDate(leg.session.ClosedAt),\n CloseReason: leg.session.CloseReason ?? null,\n Turns: this.mapTurns(leg.details),\n DelegatedRuns: this.mapRuns(leg.runs, config.coAgentRunID ?? null)\n };\n }\n\n /** Persisted detail rows → caption turns: visible `User`/`AI` rows with text (AI → Assistant). */\n private mapTurns(details: DetailRow[]): RealtimeSessionReviewTurn[] {\n const turns: RealtimeSessionReviewTurn[] = [];\n for (const row of details) {\n const text = row.Message?.trim() ?? '';\n if (row.HiddenToUser || text.length === 0 || (row.Role !== 'User' && row.Role !== 'AI')) {\n continue;\n }\n const createdAt = this.toDate(row.__mj_CreatedAt);\n turns.push({\n ID: row.ID,\n Role: row.Role === 'AI' ? 'Assistant' : 'User',\n Text: text,\n Message: text,\n __mj_CreatedAt: createdAt,\n At: createdAt,\n UtteranceStartMs: row.UtteranceStartMs ?? null,\n UtteranceEndMs: row.UtteranceEndMs ?? null\n });\n }\n return turns;\n }\n\n /** Linked run rows → delegated-run previews, EXCLUDING the co-agent's observability run. */\n private mapRuns(runs: RunRow[], coAgentRunId: string | null): RealtimeSessionReviewRun[] {\n return runs\n .filter(r => !coAgentRunId || !UUIDsEqual(r.ID, coAgentRunId))\n .map(r => ({\n RunID: r.ID,\n AgentID: r.AgentID,\n AgentName: r.Agent ?? null,\n Status: r.Status ?? '',\n Success: r.Success === true,\n Message: r.Message ?? null,\n ErrorMessage: r.ErrorMessage ?? null,\n FinalStep: r.FinalStep ?? null,\n StartedAt: this.toDate(r.StartedAt),\n CompletedAt: this.toDate(r.CompletedAt)\n }));\n }\n\n /** Session-channel rows → named channel states (rows without a channel name are skipped). */\n private mapChannels(channels: ChannelRow[]): RealtimeSessionReviewChannelState[] {\n return channels\n .filter(c => !!c.Channel)\n .map(c => ({ ChannelName: c.Channel as string, StateJson: c.Config ?? null }));\n }\n\n /** Tolerant Config JSON parse — malformed/missing payloads degrade to `{}`. */\n private parseSessionConfig(raw: string | null): SessionConfigJson {\n if (!raw) {\n return {};\n }\n try {\n const parsed = JSON.parse(raw) as SessionConfigJson;\n return parsed && typeof parsed === 'object' ? parsed : {};\n } catch {\n return {};\n }\n }\n\n /** Tolerant date conversion — view rows arrive as ISO strings (or Dates from some providers). */\n private toDate(value: string | Date | null | undefined): Date | null {\n if (value == null) {\n return null;\n }\n const date = value instanceof Date ? value : new Date(value);\n return isNaN(date.getTime()) ? null : date;\n }\n}\n"]}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { Observable } from 'rxjs';
|
|
2
2
|
import { IMetadataProvider } from '@memberjunction/core';
|
|
3
3
|
import { RealtimeToolDefinition } from '@memberjunction/ai';
|
|
4
|
+
import { AppContextSnapshot } from '@memberjunction/ai-core-plus';
|
|
4
5
|
import { RealtimeAudioActivity } from '@memberjunction/ai-realtime-client';
|
|
5
6
|
import { ParsedDelegationArtifact } from './delegation-result-parser';
|
|
6
7
|
import { BaseRealtimeChannelClient } from '../components/realtime/channels/base-realtime-channel-client';
|
|
7
8
|
import * as i0 from "@angular/core";
|
|
9
|
+
/**
|
|
10
|
+
* `MJ: User Settings` key for the per-user "record this voice call" consent toggle. Stored as
|
|
11
|
+
* the literal string `'true'`/`'false'` (read with `=== 'true'`), cross-device via
|
|
12
|
+
* {@link UserInfoEngine}. The pre-call picker writes it; the session service reads it as the
|
|
13
|
+
* default when the caller doesn't pass an explicit consent value.
|
|
14
|
+
*/
|
|
15
|
+
export declare const REALTIME_RECORDING_CONSENT_KEY = "mj.realtimeVoice.recordingConsent.v1";
|
|
8
16
|
/**
|
|
9
17
|
* Connection / turn state for a real-time voice session, surfaced to the UI overlay.
|
|
10
18
|
* - `connecting` — negotiating the session + provider handshake
|
|
@@ -14,9 +22,9 @@ import * as i0 from "@angular/core";
|
|
|
14
22
|
* - `error` — a fatal error occurred; the session is no longer usable
|
|
15
23
|
* - `closed` — the session has been torn down
|
|
16
24
|
*/
|
|
17
|
-
export type
|
|
25
|
+
export type RealtimeConnectionState = 'connecting' | 'listening' | 'speaking' | 'thinking' | 'error' | 'closed';
|
|
18
26
|
/** A single caption line (one side of the conversation) shown in the live-captions list. */
|
|
19
|
-
export interface
|
|
27
|
+
export interface RealtimeCaption {
|
|
20
28
|
Role: 'User' | 'Assistant';
|
|
21
29
|
Text: string;
|
|
22
30
|
}
|
|
@@ -25,7 +33,7 @@ export interface VoiceCaption {
|
|
|
25
33
|
* These originate server-side during an `invoke-target-agent` delegation (e.g. while Sage works) and let a
|
|
26
34
|
* future overlay render a "working" card while the realtime model narrates the same progress aloud.
|
|
27
35
|
*/
|
|
28
|
-
export interface
|
|
36
|
+
export interface RealtimeDelegationProgress {
|
|
29
37
|
/** The `invoke-target-agent` call this progress belongs to. */
|
|
30
38
|
CallID: string;
|
|
31
39
|
/** The delegation phase: `prompt_execution` | `action_execution` | `subagent_execution` | `decision_processing`. */
|
|
@@ -40,7 +48,7 @@ export interface VoiceDelegationProgress {
|
|
|
40
48
|
* when the delegation finishes so the overlay can flip the "working" card into a result card with real
|
|
41
49
|
* content + provenance.
|
|
42
50
|
*/
|
|
43
|
-
export interface
|
|
51
|
+
export interface RealtimeDelegationResult {
|
|
44
52
|
/** The `invoke-target-agent` call this result belongs to. */
|
|
45
53
|
CallID: string;
|
|
46
54
|
/** Whether the delegated work succeeded. */
|
|
@@ -87,7 +95,7 @@ export interface RealtimeChannelFocusEvent {
|
|
|
87
95
|
* decision they are NOT captions and NOT persisted as ConversationDetails — they exist
|
|
88
96
|
* only as a live note in the overlay, replaced by each newer narration.
|
|
89
97
|
*/
|
|
90
|
-
export interface
|
|
98
|
+
export interface RealtimeDelegationNarration {
|
|
91
99
|
/** The narration transcript text. */
|
|
92
100
|
Text: string;
|
|
93
101
|
}
|
|
@@ -108,7 +116,7 @@ export interface VoiceDelegationNarration {
|
|
|
108
116
|
* bakes the companion instructions + tool set into `SessionConfigJson`, which the client
|
|
109
117
|
* driver applies verbatim.
|
|
110
118
|
*
|
|
111
|
-
* Lifecycle: {@link
|
|
119
|
+
* Lifecycle: {@link StartRealtimeSession} → live duplex → {@link EndRealtimeSession}.
|
|
112
120
|
*/
|
|
113
121
|
export declare class RealtimeSessionService {
|
|
114
122
|
private _connectionState$;
|
|
@@ -126,24 +134,24 @@ export declare class RealtimeSessionService {
|
|
|
126
134
|
private _sessionEnded$;
|
|
127
135
|
private _channelActivity$;
|
|
128
136
|
/** Current connection / turn state. */
|
|
129
|
-
readonly ConnectionState$: Observable<
|
|
137
|
+
readonly ConnectionState$: Observable<RealtimeConnectionState>;
|
|
130
138
|
/** Live captions for both sides of the conversation. */
|
|
131
|
-
readonly Captions$: Observable<
|
|
139
|
+
readonly Captions$: Observable<RealtimeCaption[]>;
|
|
132
140
|
/** True while a session is open (mic button active, overlay shown). */
|
|
133
141
|
readonly Active$: Observable<boolean>;
|
|
134
142
|
/**
|
|
135
143
|
* Progress updates from a delegated agent run (e.g. Sage) while the realtime model waits on it.
|
|
136
144
|
* The future overlay subscribes to render a "working" card; the model also narrates these aloud.
|
|
137
145
|
*/
|
|
138
|
-
readonly DelegationProgress$: Observable<
|
|
146
|
+
readonly DelegationProgress$: Observable<RealtimeDelegationProgress>;
|
|
139
147
|
/** Terminal result of a delegation, so the overlay can complete the working card with real content. */
|
|
140
|
-
readonly DelegationResult$: Observable<
|
|
148
|
+
readonly DelegationResult$: Observable<RealtimeDelegationResult>;
|
|
141
149
|
/**
|
|
142
|
-
* EPHEMERAL spoken progress narrations (see {@link
|
|
150
|
+
* EPHEMERAL spoken progress narrations (see {@link RealtimeDelegationNarration}). These are
|
|
143
151
|
* deliberately kept OUT of {@link Captions$} and never relayed/persisted — the overlay
|
|
144
152
|
* renders them as a transient "live note" near the active working card.
|
|
145
153
|
*/
|
|
146
|
-
readonly DelegationNarration$: Observable<
|
|
154
|
+
readonly DelegationNarration$: Observable<RealtimeDelegationNarration>;
|
|
147
155
|
/** Display name of the agent the active session fronts (set at session start). */
|
|
148
156
|
readonly AgentName$: Observable<string>;
|
|
149
157
|
/**
|
|
@@ -191,7 +199,7 @@ export declare class RealtimeSessionService {
|
|
|
191
199
|
* Fired EXACTLY ONCE per session as teardown begins, with the prior
|
|
192
200
|
* `agentSessionId` (so subscribers can correlate against `SessionStarted$`'s
|
|
193
201
|
* sessionId) and the client-distinguishable reason — `'explicit'` when the
|
|
194
|
-
* user called `
|
|
202
|
+
* user called `EndRealtimeSession`, `'error'` when teardown ran from a catch
|
|
195
203
|
* block. Server-side close paths (janitor, shutdown) do NOT propagate here —
|
|
196
204
|
* they happen out-of-process and have no client push channel today.
|
|
197
205
|
*/
|
|
@@ -209,6 +217,14 @@ export declare class RealtimeSessionService {
|
|
|
209
217
|
readonly ChannelActivity$: Observable<BaseRealtimeChannelClient>;
|
|
210
218
|
/** Synchronous access to the session's active interactive-channel plugins. */
|
|
211
219
|
get ActiveChannels(): readonly BaseRealtimeChannelClient[];
|
|
220
|
+
/**
|
|
221
|
+
* The `ChannelName`s the agent has used (acted on) at least once this session. The overlay
|
|
222
|
+
* uses this to register a channel's surface tab only after it has come into play. A fresh
|
|
223
|
+
* Set snapshot so callers can't mutate the service's tracking.
|
|
224
|
+
*/
|
|
225
|
+
get UsedChannelNames(): ReadonlySet<string>;
|
|
226
|
+
/** Whether the agent has used (acted on) the named channel at least once this session. */
|
|
227
|
+
HasChannelBeenUsed(channelName: string): boolean;
|
|
212
228
|
/** Synchronous access to the display name of the agent the active session fronts. */
|
|
213
229
|
get CurrentAgentName(): string;
|
|
214
230
|
/**
|
|
@@ -243,12 +259,66 @@ export declare class RealtimeSessionService {
|
|
|
243
259
|
/** The mic capture stream — acquired here (permission UX) and handed to the client. */
|
|
244
260
|
private localStream;
|
|
245
261
|
private agentSessionId;
|
|
262
|
+
/**
|
|
263
|
+
* The application the active session runs in (sources the server-side app config cascade +
|
|
264
|
+
* RelevantAgents → allowed-agent union, and the default-agent chain). `null` when no app context
|
|
265
|
+
* was supplied. Set at {@link StartRealtimeSession}; sent to the mint mutation.
|
|
266
|
+
*/
|
|
267
|
+
private applicationId;
|
|
268
|
+
/**
|
|
269
|
+
* The live app-context snapshot (where the user is, what they see, the capability manifest),
|
|
270
|
+
* pushed by the host (Explorer) at session start and on subsequent changes via
|
|
271
|
+
* {@link UpdateAppContext}. The headless {@link import('../components/realtime/channels/client-context-channel').ClientContextChannel}
|
|
272
|
+
* subscribes to {@link AppContext$} and streams deltas to the model via `SendContextNote`.
|
|
273
|
+
*/
|
|
274
|
+
private readonly _appContext$;
|
|
275
|
+
/** Observable of the live app-context snapshot (see {@link _appContext$}). */
|
|
276
|
+
readonly AppContext$: Observable<AppContextSnapshot | null>;
|
|
277
|
+
/**
|
|
278
|
+
* Push an updated app-context snapshot mid-session (the continuous-streaming half of client-context
|
|
279
|
+
* delivery). The host (Explorer) calls this when the user navigates / the active surface's state or
|
|
280
|
+
* capability manifest changes; the ClientContextChannel turns the delta into a `SendContextNote`.
|
|
281
|
+
* No-op semantics when no session is live — the channel simply re-reads on next start.
|
|
282
|
+
*
|
|
283
|
+
* @param snapshot The latest app-context snapshot (or null to clear).
|
|
284
|
+
*/
|
|
285
|
+
UpdateAppContext(snapshot: AppContextSnapshot | null): void;
|
|
246
286
|
/**
|
|
247
287
|
* The DB-driven narration instruction template (server-resolved at session start, containing a
|
|
248
288
|
* `{{ progressMessage }}` placeholder). `null` when the deployment hasn't synced the narration
|
|
249
289
|
* prompt — {@link buildNarrationInstructions} then falls back to the built-in wording.
|
|
250
290
|
*/
|
|
251
291
|
private narrationTemplate;
|
|
292
|
+
/**
|
|
293
|
+
* The active session's audio recorder (mic + agent mix), or `null` when the user didn't
|
|
294
|
+
* consent or the browser can't record. Created after the client connects; stopped + uploaded
|
|
295
|
+
* at teardown.
|
|
296
|
+
*/
|
|
297
|
+
private recorder;
|
|
298
|
+
/** ISO timestamp of when recording started — sent to the server on session start. */
|
|
299
|
+
private recordingStartedAtIso;
|
|
300
|
+
/** Interval that flushes ~15s crash-recovery shards to the server during a recording. */
|
|
301
|
+
private segmentTimer;
|
|
302
|
+
/** 0-based index of the next recording shard to upload. */
|
|
303
|
+
private segmentIndex;
|
|
304
|
+
/** How often crash-recovery shards are flushed during a recording. */
|
|
305
|
+
private static readonly SegmentFlushMs;
|
|
306
|
+
/**
|
|
307
|
+
* Recording-relative ms offset at which the IN-FLIGHT (not-yet-finalized) turn's audio
|
|
308
|
+
* actually BEGAN — captured the moment that turn's audio/text starts flowing (its first
|
|
309
|
+
* interim transcript), NOT inherited from the previous turn's end. `null` before the first
|
|
310
|
+
* turn / between turns (until the next turn's audio starts). Sent as `utteranceStartMs` on
|
|
311
|
+
* the turn's final transcript so per-turn timing lines up with the recording even when a
|
|
312
|
+
* tool-call / silence gap sits between turns (the inherit-previous-end model mis-stamped
|
|
313
|
+
* the post-gap turn at the pre-gap offset). See {@link markTurnAudioStart}.
|
|
314
|
+
*/
|
|
315
|
+
private currentTurnStartMs;
|
|
316
|
+
/**
|
|
317
|
+
* Per-turn guard for {@link markTurnAudioStart}: `true` once the in-flight turn's audio-start
|
|
318
|
+
* offset has been captured, so mid-turn interim deltas don't overwrite it. Reset to `false`
|
|
319
|
+
* at each finalization so the NEXT turn re-stamps from where ITS audio begins.
|
|
320
|
+
*/
|
|
321
|
+
private turnAudioStartCaptured;
|
|
252
322
|
/** First spoken update fires no earlier than this long after delegated work starts. */
|
|
253
323
|
private static readonly FirstNarrationDelayMs;
|
|
254
324
|
/** Minimum gap between SUBSEQUENT spoken updates (the 7–10s band; floods aggregate). */
|
|
@@ -318,6 +388,14 @@ export declare class RealtimeSessionService {
|
|
|
318
388
|
* the final save still lands on the just-closed session.
|
|
319
389
|
*/
|
|
320
390
|
private pendingChannelSaves;
|
|
391
|
+
/**
|
|
392
|
+
* `ChannelName`s the agent has ACTED ON at least once this session (the channel's first
|
|
393
|
+
* tool call routed to its local executor). The overlay reads this to decide which channel
|
|
394
|
+
* surface tabs to register: a channel earns its tab only once it's been used (the
|
|
395
|
+
* whiteboard is the sole exception — it tabs immediately, since a user may draw first).
|
|
396
|
+
* Reset at session start via {@link resetState}.
|
|
397
|
+
*/
|
|
398
|
+
private usedChannelNames;
|
|
321
399
|
private _provider;
|
|
322
400
|
/**
|
|
323
401
|
* Metadata provider used for the GraphQL relay mutations. Falls back to the
|
|
@@ -356,13 +434,21 @@ export declare class RealtimeSessionService {
|
|
|
356
434
|
* authorization on any overrides — hosts only populate this from authorization-gated
|
|
357
435
|
* pickers, and never synthesize overrides beyond what the user explicitly chose.
|
|
358
436
|
* Omit/`null` for the server's defaults (today's behavior).
|
|
437
|
+
* @param recordingConsent Optional EXPLICIT "record this call" consent for THIS session. When
|
|
438
|
+
* `true`, the browser records a mic + agent-audio mix and uploads it at session end. When
|
|
439
|
+
* omitted/`null`, the per-user persisted preference (`mj.realtimeVoice.recordingConsent.v1`
|
|
440
|
+
* via {@link UserInfoEngine}) is read as the default. `false` never records.
|
|
441
|
+
* @param mediaCollectionId Optional per-session media-kit override (`MJ: Collections.ID`). When set,
|
|
442
|
+
* the server-side Media channel resolves THIS collection as the agent's media kit for the session,
|
|
443
|
+
* taking precedence over the agent's `DefaultMediaCollectionID`. The server UUID-validates it
|
|
444
|
+
* (malformed ⇒ ignored, the agent default applies). Omit/`null` to use the agent default kit.
|
|
359
445
|
*/
|
|
360
|
-
|
|
446
|
+
StartRealtimeSession(targetAgentId: string, conversationId?: string | null, lastSessionId?: string | null, agentName?: string | null, preferredModelId?: string | null, clientTools?: RealtimeToolDefinition[] | null, coAgentId?: string | null, configOverridesJson?: string | null, recordingConsent?: boolean | null, mediaCollectionId?: string | null, applicationId?: string | null, appContext?: AppContextSnapshot | null): Promise<void>;
|
|
361
447
|
/**
|
|
362
448
|
* End the active session: stop the mic, tear down the provider connection, and close
|
|
363
449
|
* the server-side agent session. Safe to call when no session is active.
|
|
364
450
|
*/
|
|
365
|
-
|
|
451
|
+
EndRealtimeSession(): Promise<void>;
|
|
366
452
|
/**
|
|
367
453
|
* Inject a typed message into the live session as a user turn.
|
|
368
454
|
*
|
|
@@ -402,6 +488,44 @@ export declare class RealtimeSessionService {
|
|
|
402
488
|
* a cheap analyser read, never provider traffic.
|
|
403
489
|
*/
|
|
404
490
|
GetAudioActivity(): RealtimeAudioActivity | null;
|
|
491
|
+
/**
|
|
492
|
+
* Reads the per-user recording-consent preference from `MJ: User Settings` (via
|
|
493
|
+
* {@link UserInfoEngine}'s synchronous cache). Defensive: any failure resolves to `false`
|
|
494
|
+
* (don't record) so a settings hiccup can never opt a user into recording.
|
|
495
|
+
*/
|
|
496
|
+
private readPersistedRecordingConsent;
|
|
497
|
+
/**
|
|
498
|
+
* Starts the browser-side recorder (mic + agent-audio mix). Best-effort — any failure is
|
|
499
|
+
* contained so it never disturbs the live call; an unsupported browser simply records
|
|
500
|
+
* nothing (the recorder disables itself).
|
|
501
|
+
*/
|
|
502
|
+
private startRecording;
|
|
503
|
+
/** Begins flushing ~15s crash-recovery shards to the server for the duration of the recording. */
|
|
504
|
+
private startSegmentFlushing;
|
|
505
|
+
/** Stops the periodic crash-recovery shard flush. */
|
|
506
|
+
private stopSegmentFlushing;
|
|
507
|
+
/**
|
|
508
|
+
* Uploads the chunks captured since the last flush as one crash-recovery shard (durability only;
|
|
509
|
+
* the canonical file is still the full upload at teardown). Best-effort — never disturbs the call.
|
|
510
|
+
*/
|
|
511
|
+
private flushRecordingSegment;
|
|
512
|
+
/**
|
|
513
|
+
* Stops the active recorder and uploads the captured audio via `UploadRealtimeRecording`.
|
|
514
|
+
* Fully best-effort and wrapped in try/catch — recording upload must NEVER block teardown.
|
|
515
|
+
* No-op when nothing was recorded or there's no session id to attach the file to.
|
|
516
|
+
*/
|
|
517
|
+
private stopAndUploadRecording;
|
|
518
|
+
/**
|
|
519
|
+
* Runs the `UploadRealtimeRecording` mutation; failures are logged, never thrown. Sends the
|
|
520
|
+
* capture-time waveform `peaks` (max-abs per bucket, normalized 0..1) so the server can persist a
|
|
521
|
+
* `peaks.json` sidecar for fast waveform rendering without re-decoding the audio.
|
|
522
|
+
*/
|
|
523
|
+
private uploadRecording;
|
|
524
|
+
/**
|
|
525
|
+
* Encodes a {@link Blob} as a base64 string (the data: prefix stripped) via {@link FileReader}.
|
|
526
|
+
* Resolves `''` on any read failure so the upload path can bail cleanly.
|
|
527
|
+
*/
|
|
528
|
+
private blobToBase64;
|
|
405
529
|
/**
|
|
406
530
|
* Resolves, instantiates and initializes the session's interactive-channel plugins from
|
|
407
531
|
* the `MJ: AI Agent Channels` registry, publishes them on {@link ActiveChannels$}, and
|
|
@@ -441,6 +565,35 @@ export declare class RealtimeSessionService {
|
|
|
441
565
|
private initializeChannel;
|
|
442
566
|
/** Builds the host-services context one channel plugin sees (its only line to the session). */
|
|
443
567
|
private buildChannelContext;
|
|
568
|
+
/**
|
|
569
|
+
* Host registry of surface CLIENT TOOLS (Name → handler), fed by the host (Explorer) from the
|
|
570
|
+
* active surface's `SetAgentClientTools`. The headless ClientContextChannel's `ContextTool` proxy
|
|
571
|
+
* executes against this via {@link executeAppClientTool}. Keys are lower-cased for case-insensitive
|
|
572
|
+
* model-supplied action names.
|
|
573
|
+
*/
|
|
574
|
+
private readonly appClientToolHandlers;
|
|
575
|
+
/**
|
|
576
|
+
* Replaces the set of host-registered surface client tools the realtime ContextTool can execute.
|
|
577
|
+
* The host calls this at session start and whenever the active surface's tool set changes (the
|
|
578
|
+
* continuous-capability half of client-context delivery). Passing `[]` clears them.
|
|
579
|
+
*
|
|
580
|
+
* @param tools The current surface client tools (name + handler). Descriptions/schemas ride the
|
|
581
|
+
* app-context manifest separately; only the executable handler is needed here.
|
|
582
|
+
*/
|
|
583
|
+
RegisterAppClientTools(tools: ReadonlyArray<{
|
|
584
|
+
Name: string;
|
|
585
|
+
Handler: (params: Record<string, unknown>) => Promise<unknown> | unknown;
|
|
586
|
+
}>): void;
|
|
587
|
+
/**
|
|
588
|
+
* Executes a host-registered surface client tool by name (the {@link RealtimeChannelContext.ExecuteClientTool}
|
|
589
|
+
* implementation). Tolerant: an unknown tool or a thrown handler resolves to a structured
|
|
590
|
+
* `Success: false` result the channel narrates — never throws.
|
|
591
|
+
*
|
|
592
|
+
* @param name The tool name (the model's `action`).
|
|
593
|
+
* @param params The tool parameters.
|
|
594
|
+
* @returns A structured result for the channel to serialize back to the model.
|
|
595
|
+
*/
|
|
596
|
+
private executeAppClientTool;
|
|
444
597
|
/**
|
|
445
598
|
* Runs a channel-specific GraphQL operation through the live session's provider (the
|
|
446
599
|
* {@link RealtimeChannelContext.ExecuteServerAction} implementation). Best-effort: any
|
|
@@ -504,7 +657,7 @@ export declare class RealtimeSessionService {
|
|
|
504
657
|
/** Maps a client state event onto the UI connection state. */
|
|
505
658
|
private onClientStateChange;
|
|
506
659
|
/**
|
|
507
|
-
* Translates {@link RealtimeClientState} into {@link
|
|
660
|
+
* Translates {@link RealtimeClientState} into {@link RealtimeConnectionState}. `'connected'`
|
|
508
661
|
* is suppressed (the UI stays 'connecting' until the control channel opens → 'listening'),
|
|
509
662
|
* and `'closed'` never overwrites a terminal 'error' the service itself recorded.
|
|
510
663
|
*/
|
|
@@ -512,13 +665,37 @@ export declare class RealtimeSessionService {
|
|
|
512
665
|
/** True when the live control channel is usable (open and not torn down / failed). */
|
|
513
666
|
private isSessionLive;
|
|
514
667
|
/**
|
|
515
|
-
* Applies transcript policy to client transcript events. Interim deltas
|
|
516
|
-
* (the client already drives the speaking state)
|
|
668
|
+
* Applies transcript policy to client transcript events. Interim deltas don't become
|
|
669
|
+
* captions/turns (the client already drives the speaking state) but DO mark this turn's
|
|
670
|
+
* audio-start offset against the recording (the first interim fires as the audio/text
|
|
671
|
+
* starts flowing — see {@link markTurnAudioStart}). Final NORMAL assistant turns become
|
|
517
672
|
* captions + persisted transcripts; final NARRATION turns are EPHEMERAL by product
|
|
518
673
|
* decision — emitted on {@link DelegationNarration$} only, never a caption, never
|
|
519
674
|
* relayed/persisted. User turns ride the caption + relay path.
|
|
520
675
|
*/
|
|
521
676
|
private onClientTranscript;
|
|
677
|
+
/**
|
|
678
|
+
* Stamps the recording-relative offset at which the IN-FLIGHT turn's audio actually began,
|
|
679
|
+
* the moment that turn's audio/text first starts flowing (its FIRST interim transcript).
|
|
680
|
+
*
|
|
681
|
+
* This is the fix for transcript cues drifting out of sync with the audio when a tool-call /
|
|
682
|
+
* silence gap sits between turns: the old model inherited the next turn's start from the
|
|
683
|
+
* PREVIOUS turn's end (assumes contiguous turns), so a post-gap turn's cue pointed ~gap-length
|
|
684
|
+
* too early. Capturing the start where the audio truly begins keeps the cue aligned.
|
|
685
|
+
*
|
|
686
|
+
* Guards:
|
|
687
|
+
* - only when recording ({@link recorder} present),
|
|
688
|
+
* - only ONCE per turn ({@link turnAudioStartCaptured}) so mid-turn interim deltas don't move it,
|
|
689
|
+
* - NORMAL turns only — NARRATION interims are ephemeral and never persisted, so they must not
|
|
690
|
+
* claim the next real turn's start slot.
|
|
691
|
+
*
|
|
692
|
+
* Works for any role whose driver surfaces interim deltas (all drivers for the assistant; the
|
|
693
|
+
* relevant case here — the post-tool-gap assistant answer — and user-interim drivers like
|
|
694
|
+
* Gemini/AssemblyAI). For final-only user turns (OpenAI/xAI/ElevenLabs) no interim arrives, so
|
|
695
|
+
* {@link relayTranscript} falls back to the seeded/prior start — the gap case that drifts is the
|
|
696
|
+
* assistant answer, which always has interims.
|
|
697
|
+
*/
|
|
698
|
+
private markTurnAudioStart;
|
|
522
699
|
/**
|
|
523
700
|
* Replaces the LAST caption of `role` in place (correction semantics); falls back to a
|
|
524
701
|
* plain append when no such caption exists yet (e.g. the superseded turn predates this
|
|
@@ -548,8 +725,8 @@ export declare class RealtimeSessionService {
|
|
|
548
725
|
* {@link ParseDelegationResultJson}; if it isn't JSON, surfaces the raw string. Only delegation
|
|
549
726
|
* cards (created from progress events) react — non-delegation tool results have no card and are
|
|
550
727
|
* harmlessly ignored downstream. The `runId` (the delegated `MJ: AI Agent Runs` record) rides
|
|
551
|
-
* along as {@link
|
|
552
|
-
* ride along as {@link
|
|
728
|
+
* along as {@link RealtimeDelegationResult.RunID} for the overlay's dev links, and any `artifacts`
|
|
729
|
+
* ride along as {@link RealtimeDelegationResult.Artifacts} for the surface panel's artifact tabs.
|
|
553
730
|
*/
|
|
554
731
|
private emitDelegationResult;
|
|
555
732
|
/**
|
|
@@ -605,6 +782,19 @@ export declare class RealtimeSessionService {
|
|
|
605
782
|
SaveChannelState(channelName: string, stateJson: string, agentSessionId?: string | null): Promise<boolean>;
|
|
606
783
|
/**
|
|
607
784
|
* Relays a final transcript turn to MJ via `RelayRealtimeTranscript`.
|
|
785
|
+
*
|
|
786
|
+
* When the session is being recorded, per-turn timing rides along: `utteranceEndMs` is the
|
|
787
|
+
* recording-relative offset at finalization, and `utteranceStartMs` is the offset captured by
|
|
788
|
+
* {@link markTurnAudioStart} when THIS turn's audio actually began (its first interim) — NOT
|
|
789
|
+
* inherited from the previous turn's end. That distinction is the timing fix: when a tool-call
|
|
790
|
+
* / silence gap sits between turns, the post-gap turn's audio starts much later, so inheriting
|
|
791
|
+
* the prior turn's end stamped the cue ~gap-length too early. Both are omitted (left `null`)
|
|
792
|
+
* when the session isn't being recorded.
|
|
793
|
+
*
|
|
794
|
+
* A correction (`replacesPrevious`) doesn't open a new turn, so it carries no start and doesn't
|
|
795
|
+
* reset the per-turn start guard. After a normal finalization the guard is cleared so the NEXT
|
|
796
|
+
* turn re-stamps its start from where ITS audio begins.
|
|
797
|
+
*
|
|
608
798
|
* @param replacesPrevious CORRECTION semantics: the server updates the session's most
|
|
609
799
|
* recent persisted turn of this role IN PLACE instead of appending (e.g. ElevenLabs'
|
|
610
800
|
* post-barge-in `agent_response_correction`).
|