@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,102 +1,92 @@
|
|
|
1
1
|
import { Subject } from 'rxjs';
|
|
2
|
+
import { ChannelTabColor } from './realtime-surface-tab-style';
|
|
2
3
|
/**
|
|
3
4
|
* Framework-free state for the call overlay's tabbed surface panel: the ordered tab list
|
|
4
|
-
* (CHANNEL tabs first — the marquee surfaces
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* (CHANNEL tabs first — the marquee surfaces, left cluster — with the session-activity tab
|
|
6
|
+
* pinned LAST and right-aligned by the strip), the active tab, and the transient "flash"
|
|
7
|
+
* highlight for a just-revealed channel tab.
|
|
8
|
+
*
|
|
9
|
+
* The Activity tab is GATED: it isn't listed until {@link SetShowActivityTab}(true) — i.e.
|
|
10
|
+
* once ≥1 agent run has occurred (or in review mode). Channel tabs appear only as channels
|
|
11
|
+
* come into play (the whiteboard up-front; every other channel on first use), so an
|
|
12
|
+
* idle voice-first session shows an empty/near-empty strip rather than a row of unused tabs.
|
|
8
13
|
*
|
|
9
14
|
* Owned by `RealtimeSurfaceTabsComponent`; kept free of Angular runtime imports so the
|
|
10
|
-
* add / focus / dedupe / flash
|
|
11
|
-
*
|
|
15
|
+
* add / focus / dedupe / flash logic is unit-testable in isolation. All collections are
|
|
16
|
+
* REPLACED (never mutated) on change, and every change emits {@link Changed$}.
|
|
12
17
|
*/
|
|
13
18
|
export class RealtimeSurfaceTabsModel {
|
|
14
|
-
/** The fixed key of the
|
|
19
|
+
/** The fixed key of the session-activity tab (pinned LAST, right-aligned). */
|
|
15
20
|
static ActivityTabKey = 'activity';
|
|
16
|
-
/** The
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
/** The activity tab definition, appended last whenever {@link showActivity} is true. */
|
|
22
|
+
static ActivityTab = {
|
|
23
|
+
Key: RealtimeSurfaceTabsModel.ActivityTabKey,
|
|
24
|
+
Title: 'Activity',
|
|
25
|
+
Icon: 'fa-solid fa-wave-square',
|
|
26
|
+
Kind: 'activity'
|
|
27
|
+
};
|
|
28
|
+
/** Channel tabs (left cluster), in registration order. Replaced immutably on change. */
|
|
29
|
+
channelTabs = [];
|
|
30
|
+
/** Whether the gated Activity tab is currently shown (≥1 agent run, or review mode). */
|
|
31
|
+
showActivity = false;
|
|
20
32
|
/** Key of the currently focused tab. */
|
|
21
33
|
ActiveKey = RealtimeSurfaceTabsModel.ActivityTabKey;
|
|
22
34
|
/**
|
|
23
|
-
* Key of the tab currently "flashing" (the brief
|
|
24
|
-
*
|
|
25
|
-
*
|
|
35
|
+
* Key of the tab currently "flashing" (the brief highlight a just-revealed channel tab
|
|
36
|
+
* gets when the agent first acts on it). Cleared by the owning component after a beat via
|
|
37
|
+
* {@link ClearFlash}.
|
|
26
38
|
*/
|
|
27
39
|
FlashKey = null;
|
|
28
|
-
/**
|
|
29
|
-
* Tabs holding content the user hasn't visited yet (the persistent glow): an artifact
|
|
30
|
-
* tab that arrived WITHOUT stealing focus stays marked until it is focused. Replaced
|
|
31
|
-
* immutably on change.
|
|
32
|
-
*/
|
|
33
|
-
unseenKeys = new Set();
|
|
34
40
|
/** Emits after every model change so the owning component can mark for check. */
|
|
35
41
|
Changed$ = new Subject();
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
/**
|
|
43
|
+
* The ordered tabs: channel tabs (left), then the Activity tab LAST when shown. The strip
|
|
44
|
+
* right-aligns the Activity tab via a flex spacer, so this order also matches reading order.
|
|
45
|
+
*/
|
|
46
|
+
get Tabs() {
|
|
47
|
+
return this.showActivity
|
|
48
|
+
? [...this.channelTabs, RealtimeSurfaceTabsModel.ActivityTab]
|
|
49
|
+
: [...this.channelTabs];
|
|
41
50
|
}
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
-
return this.
|
|
51
|
+
/** Whether the Activity tab is currently part of the strip. */
|
|
52
|
+
get IsActivityShown() {
|
|
53
|
+
return this.showActivity;
|
|
45
54
|
}
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
/**
|
|
56
|
+
* The currently focused tab. Resolves to the active key when it still exists, else falls
|
|
57
|
+
* back to the Activity tab (when shown), else the first channel tab, else the Activity tab
|
|
58
|
+
* definition (so a consumer always has SOMETHING to render even on an empty strip).
|
|
59
|
+
*/
|
|
60
|
+
get ActiveTab() {
|
|
61
|
+
const tabs = this.Tabs;
|
|
62
|
+
return tabs.find(t => t.Key === this.ActiveKey)
|
|
63
|
+
?? tabs.find(t => t.Key === RealtimeSurfaceTabsModel.ActivityTabKey)
|
|
64
|
+
?? tabs[0]
|
|
65
|
+
?? RealtimeSurfaceTabsModel.ActivityTab;
|
|
49
66
|
}
|
|
50
67
|
/**
|
|
51
|
-
*
|
|
68
|
+
* Shows or hides the gated Activity tab. Turning it ON when an empty strip was implicitly
|
|
69
|
+
* focusing Activity keeps focus on Activity; turning it OFF while it was focused falls
|
|
70
|
+
* focus back to the first channel tab (if any). No-op (no emission) when unchanged.
|
|
52
71
|
*
|
|
53
|
-
*
|
|
54
|
-
* BEFORE the pinned-last Activity tab, marks it as the {@link FlashKey}, and — unless
|
|
55
|
-
* `focus` is true — leaves focus alone and marks the tab UNSEEN (it glows until
|
|
56
|
-
* visited; per product direction a finished artifact never steals the screen, only the
|
|
57
|
-
* agent's first channel activity does). Subsequent calls for the same artifact version
|
|
58
|
-
* just (optionally) focus the existing tab — no duplicate, no re-flash.
|
|
59
|
-
*
|
|
60
|
-
* @param artifact The produced artifact (id + version id + display name).
|
|
61
|
-
* @param focus Whether to focus the tab (default `false` — glow, don't grab).
|
|
62
|
-
* @param markUnseen Whether an unfocused first arrival glows (default `true`). Pass
|
|
63
|
-
* `false` for HISTORY artifacts (session-review carryover) — they're context, not news.
|
|
64
|
-
* @returns The (new or existing) tab.
|
|
72
|
+
* @param show Whether ≥1 agent run has occurred (or review mode) — the gate.
|
|
65
73
|
*/
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (existing) {
|
|
70
|
-
if (focus) {
|
|
71
|
-
this.Focus(key);
|
|
72
|
-
}
|
|
73
|
-
return existing;
|
|
74
|
-
}
|
|
75
|
-
const tab = {
|
|
76
|
-
Key: key,
|
|
77
|
-
Title: artifact.Name,
|
|
78
|
-
Icon: 'fa-solid fa-file-lines',
|
|
79
|
-
Kind: 'artifact',
|
|
80
|
-
Data: { Artifact: artifact }
|
|
81
|
-
};
|
|
82
|
-
// Insert before the pinned-last Activity tab: channels… | artifacts… | Activity.
|
|
83
|
-
const at = this.activityIndex();
|
|
84
|
-
this.Tabs = [...this.Tabs.slice(0, at), tab, ...this.Tabs.slice(at)];
|
|
85
|
-
this.FlashKey = key;
|
|
86
|
-
if (focus) {
|
|
87
|
-
this.ActiveKey = key;
|
|
74
|
+
SetShowActivityTab(show) {
|
|
75
|
+
if (this.showActivity === show) {
|
|
76
|
+
return;
|
|
88
77
|
}
|
|
89
|
-
|
|
90
|
-
|
|
78
|
+
this.showActivity = show;
|
|
79
|
+
if (!show && this.ActiveKey === RealtimeSurfaceTabsModel.ActivityTabKey) {
|
|
80
|
+
this.ActiveKey = this.channelTabs[0]?.Key ?? RealtimeSurfaceTabsModel.ActivityTabKey;
|
|
91
81
|
}
|
|
92
82
|
this.Changed$.next();
|
|
93
|
-
return tab;
|
|
94
83
|
}
|
|
95
84
|
/**
|
|
96
85
|
* Registers (or updates) an interactive-channel tab. Re-registering an existing key
|
|
97
|
-
* replaces its title/icon/plugin/content in place (this is how a placeholder
|
|
98
|
-
* to the real surface once the channel comes online). New channel tabs
|
|
99
|
-
*
|
|
86
|
+
* replaces its title/icon/color/plugin/content in place (this is how a placeholder
|
|
87
|
+
* upgrades to the real surface once the channel comes online). New channel tabs join the
|
|
88
|
+
* left cluster in registration order. A registration without an explicit {@link
|
|
89
|
+
* RealtimeChannelTabRegistration.Color} gets a deterministic color from its key.
|
|
100
90
|
*
|
|
101
91
|
* @param registration The channel tab registration.
|
|
102
92
|
* @returns The (new or updated) tab.
|
|
@@ -107,57 +97,37 @@ export class RealtimeSurfaceTabsModel {
|
|
|
107
97
|
Title: registration.Title,
|
|
108
98
|
Icon: registration.Icon,
|
|
109
99
|
Kind: 'channel',
|
|
100
|
+
Color: registration.Color ?? ChannelTabColor(registration.Key),
|
|
110
101
|
Data: { Plugin: registration.Plugin, Content: registration.Content }
|
|
111
102
|
};
|
|
112
|
-
const idx = this.
|
|
103
|
+
const idx = this.channelTabs.findIndex(t => t.Key === registration.Key);
|
|
113
104
|
if (idx >= 0) {
|
|
114
|
-
const next = [...this.
|
|
105
|
+
const next = [...this.channelTabs];
|
|
115
106
|
next[idx] = tab;
|
|
116
|
-
this.
|
|
107
|
+
this.channelTabs = next;
|
|
117
108
|
}
|
|
118
109
|
else {
|
|
119
|
-
|
|
120
|
-
const firstNonChannel = this.Tabs.findIndex(t => t.Kind !== 'channel');
|
|
121
|
-
const at = firstNonChannel >= 0 ? firstNonChannel : this.Tabs.length;
|
|
122
|
-
this.Tabs = [...this.Tabs.slice(0, at), tab, ...this.Tabs.slice(at)];
|
|
110
|
+
this.channelTabs = [...this.channelTabs, tab];
|
|
123
111
|
}
|
|
124
112
|
if (registration.Focus) {
|
|
125
113
|
this.ActiveKey = tab.Key;
|
|
126
|
-
this.markSeen(tab.Key);
|
|
127
114
|
}
|
|
128
115
|
this.Changed$.next();
|
|
129
116
|
return tab;
|
|
130
117
|
}
|
|
131
|
-
/** Focuses the tab with `key` (no-op when it doesn't exist
|
|
118
|
+
/** Focuses the tab with `key` (no-op when it doesn't exist or is already active). */
|
|
132
119
|
Focus(key) {
|
|
133
|
-
if (!this.Tabs.some(t => t.Key === key)) {
|
|
120
|
+
if (!this.Tabs.some(t => t.Key === key) || this.ActiveKey === key) {
|
|
134
121
|
return;
|
|
135
122
|
}
|
|
136
|
-
const changed = this.ActiveKey !== key || this.unseenKeys.has(key);
|
|
137
123
|
this.ActiveKey = key;
|
|
138
|
-
this.
|
|
139
|
-
if (changed) {
|
|
140
|
-
this.Changed$.next();
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
/** The index of the pinned-last Activity tab (insertion boundary for content tabs). */
|
|
144
|
-
activityIndex() {
|
|
145
|
-
const idx = this.Tabs.findIndex(t => t.Key === RealtimeSurfaceTabsModel.ActivityTabKey);
|
|
146
|
-
return idx >= 0 ? idx : this.Tabs.length;
|
|
147
|
-
}
|
|
148
|
-
/** Clears a tab's unseen glow (no emission of its own — callers emit). */
|
|
149
|
-
markSeen(key) {
|
|
150
|
-
if (this.unseenKeys.has(key)) {
|
|
151
|
-
const next = new Set(this.unseenKeys);
|
|
152
|
-
next.delete(key);
|
|
153
|
-
this.unseenKeys = next;
|
|
154
|
-
}
|
|
124
|
+
this.Changed$.next();
|
|
155
125
|
}
|
|
156
126
|
/**
|
|
157
|
-
* Marks the tab with `key` as the {@link FlashKey} (the brief
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
127
|
+
* Marks the tab with `key` as the {@link FlashKey} (the brief "just arrived" highlight)
|
|
128
|
+
* WITHOUT changing focus — used by the auto-reveal path when the agent first acts on a
|
|
129
|
+
* channel, so the user's eye lands on the tab that just came alive. No-op for unknown
|
|
130
|
+
* keys; the owning component clears it after a beat via {@link ClearFlash}.
|
|
161
131
|
*/
|
|
162
132
|
FlashTab(key) {
|
|
163
133
|
if (this.FlashKey === key || !this.Tabs.some(t => t.Key === key)) {
|
|
@@ -167,27 +137,29 @@ export class RealtimeSurfaceTabsModel {
|
|
|
167
137
|
this.Changed$.next();
|
|
168
138
|
}
|
|
169
139
|
/**
|
|
170
|
-
* Removes the tab with `key`. Rules:
|
|
171
|
-
* - the Activity tab is IRREMOVABLE
|
|
140
|
+
* Removes the channel tab with `key`. Rules:
|
|
141
|
+
* - the Activity tab is IRREMOVABLE — removing it is a no-op;
|
|
172
142
|
* - an unknown key is a no-op (returns `false`);
|
|
173
|
-
* - when the removed tab was focused, focus falls back to the Activity tab
|
|
143
|
+
* - when the removed tab was focused, focus falls back to the Activity tab (if shown),
|
|
144
|
+
* else the first remaining channel tab;
|
|
174
145
|
* - a pending flash on the removed tab is cleaned up so the highlight can't dangle.
|
|
175
146
|
*
|
|
176
147
|
* @param key The tab key to remove.
|
|
177
148
|
* @returns `true` when a tab was removed.
|
|
178
149
|
*/
|
|
179
150
|
RemoveTab(key) {
|
|
180
|
-
if (key === RealtimeSurfaceTabsModel.ActivityTabKey || !this.
|
|
151
|
+
if (key === RealtimeSurfaceTabsModel.ActivityTabKey || !this.channelTabs.some(t => t.Key === key)) {
|
|
181
152
|
return false;
|
|
182
153
|
}
|
|
183
|
-
this.
|
|
154
|
+
this.channelTabs = this.channelTabs.filter(t => t.Key !== key);
|
|
184
155
|
if (this.ActiveKey === key) {
|
|
185
|
-
this.ActiveKey =
|
|
156
|
+
this.ActiveKey = this.showActivity
|
|
157
|
+
? RealtimeSurfaceTabsModel.ActivityTabKey
|
|
158
|
+
: (this.channelTabs[0]?.Key ?? RealtimeSurfaceTabsModel.ActivityTabKey);
|
|
186
159
|
}
|
|
187
160
|
if (this.FlashKey === key) {
|
|
188
161
|
this.FlashKey = null;
|
|
189
162
|
}
|
|
190
|
-
this.markSeen(key); // a removed tab can't dangle an unseen glow
|
|
191
163
|
this.Changed$.next();
|
|
192
164
|
return true;
|
|
193
165
|
}
|
|
@@ -210,8 +182,6 @@ export class RealtimeSurfaceTabsModel {
|
|
|
210
182
|
* - the live session's resolved channel set has NO Whiteboard channel — when it HAS one, the
|
|
211
183
|
* live plugin re-registers the same tab key and upgrades the pane in place instead.
|
|
212
184
|
*
|
|
213
|
-
* Review ARTIFACT tabs are deliberately NOT removed — they are wanted carryover.
|
|
214
|
-
*
|
|
215
185
|
* Kept framework-free (like the model) so the rule is unit-testable in isolation.
|
|
216
186
|
*/
|
|
217
187
|
export function ShouldRemoveReviewWhiteboardTab(liveSessionActive, reviewWhiteboardTabRegistered, liveChannels) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realtime-surface-tabs.model.js","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-surface-tabs.model.ts"],"names":[],"mappings":"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","sourcesContent":["import { Subject } from 'rxjs';\nimport type { TemplateRef } from '@angular/core';\nimport type { BaseRealtimeChannelClient } from './channels/base-realtime-channel-client';\nimport { ParsedDelegationArtifact } from '../../services/delegation-result-parser';\n\n/**\n * The kind of a surface-panel tab:\n * - `activity` — the always-present first tab hosting the session activity rail.\n * - `artifact` — one tab per artifact produced by a delegated run (auto-opened on arrival).\n * - `channel` — an interactive-channel surface (e.g. the Whiteboard). Registered per\n * registry-resolved plugin via {@link RealtimeSurfaceTabsModel.RegisterChannelTab};\n * renders the plugin's dynamically-created surface component (or a registered template\n * for legacy/template-based panes), with the \"coming online…\" placeholder until either\n * is supplied.\n */\nexport type RealtimeSurfaceTabKind = 'activity' | 'artifact' | 'channel';\n\n/**\n * Per-kind payload carried on a {@link RealtimeSurfaceTab}.\n */\nexport interface RealtimeSurfaceTabData {\n /** For `artifact` tabs: the artifact this tab views (loaded by ArtifactID, latest version). */\n Artifact?: ParsedDelegationArtifact;\n /**\n * For `channel` tabs: the channel PLUGIN whose surface component the pane creates\n * dynamically (and binds back to the plugin) — the registry-driven path every real\n * channel uses. Takes precedence over {@link Content}.\n */\n Plugin?: BaseRealtimeChannelClient;\n /**\n * For `channel` tabs: a TEMPLATE-based pane body. Backward-compatible alternative to\n * {@link Plugin} for hosts that render a bespoke surface without a channel plugin.\n * When BOTH are absent the pane renders the built-in \"coming online…\" placeholder.\n */\n Content?: TemplateRef<unknown>;\n}\n\n/**\n * One tab on the call overlay's tabbed surface panel (the right panel): Activity, an\n * artifact viewer, or an interactive-channel surface.\n */\nexport interface RealtimeSurfaceTab {\n /** Stable unique key (`activity`, `artifact:<versionId>`, or the channel's registered key). */\n Key: string;\n /** Tab strip label (artifact tabs use the artifact's name). */\n Title: string;\n /** Font Awesome icon class for the tab strip (e.g. `fa-solid fa-file-lines`). */\n Icon: string;\n /** What the tab renders. */\n Kind: RealtimeSurfaceTabKind;\n /** Kind-specific payload. */\n Data?: RealtimeSurfaceTabData;\n}\n\n/**\n * Registration for an interactive-channel tab. The overlay shell registers one per\n * registry-resolved channel plugin (supplying {@link Plugin}); supplying {@link Plugin}\n * or {@link Content} later under the same `Key` upgrades a placeholder tab to the real\n * surface.\n */\nexport interface RealtimeChannelTabRegistration {\n /** Stable channel key (the plugin's `ChannelName`, e.g. `Whiteboard`). Re-registering the same key updates the tab. */\n Key: string;\n /** Tab strip label (e.g. `Whiteboard`). */\n Title: string;\n /** Font Awesome icon class (e.g. `fa-solid fa-chalkboard`). */\n Icon: string;\n /** The channel plugin whose surface the pane creates + binds. Preferred over {@link Content}. */\n Plugin?: BaseRealtimeChannelClient;\n /** A template-based pane body (legacy/bespoke panes). Omit both to show the \"coming online…\" placeholder. */\n Content?: TemplateRef<unknown>;\n /** Focus the tab immediately after registration (default `false`). */\n Focus?: boolean;\n}\n\n/**\n * Framework-free state for the call overlay's tabbed surface panel: the ordered tab list\n * (CHANNEL tabs first — the marquee surfaces — then artifact tabs in arrival order, with\n * Activity pinned LAST), the active tab, the transient \"flash\" highlight for a\n * just-arrived tab, and the persistent UNSEEN glow for content that arrived without\n * stealing focus (an artifact tab glows until the user visits it).\n *\n * Owned by `RealtimeSurfaceTabsComponent`; kept free of Angular runtime imports so the\n * add / focus / dedupe / flash / unseen logic is unit-testable in isolation. All\n * collections are REPLACED (never mutated) on change, and every change emits {@link Changed$}.\n */\nexport class RealtimeSurfaceTabsModel {\n /** The fixed key of the always-present Activity tab (pinned as the LAST tab). */\n public static readonly ActivityTabKey = 'activity';\n\n /** The ordered tabs (channels… · artifacts… · Activity last). Replaced immutably on every change. */\n public Tabs: RealtimeSurfaceTab[] = [\n { Key: RealtimeSurfaceTabsModel.ActivityTabKey, Title: 'Activity', Icon: 'fa-solid fa-list-check', Kind: 'activity' }\n ];\n\n /** Key of the currently focused tab. */\n public ActiveKey: string = RealtimeSurfaceTabsModel.ActivityTabKey;\n\n /**\n * Key of the tab currently \"flashing\" (the brief violet highlight a just-arrived\n * artifact tab gets, per the mockup). Cleared by the owning component after a beat\n * via {@link ClearFlash}.\n */\n public FlashKey: string | null = null;\n\n /**\n * Tabs holding content the user hasn't visited yet (the persistent glow): an artifact\n * tab that arrived WITHOUT stealing focus stays marked until it is focused. Replaced\n * immutably on change.\n */\n private unseenKeys: ReadonlySet<string> = new Set<string>();\n\n /** Emits after every model change so the owning component can mark for check. */\n public readonly Changed$ = new Subject<void>();\n\n /** The currently focused tab (always resolvable — Activity is never removed). */\n public get ActiveTab(): RealtimeSurfaceTab {\n return this.Tabs.find(t => t.Key === this.ActiveKey)\n ?? this.Tabs.find(t => t.Key === RealtimeSurfaceTabsModel.ActivityTabKey)\n ?? this.Tabs[0];\n }\n\n /** True while the tab with `key` holds content the user hasn't visited (glow state). */\n public IsUnseen(key: string): boolean {\n return this.unseenKeys.has(key);\n }\n\n /** The stable tab key for an artifact (one tab per produced artifact VERSION). */\n public static ArtifactTabKey(artifact: ParsedDelegationArtifact): string {\n return `artifact:${artifact.ArtifactVersionID}`;\n }\n\n /**\n * Opens (or re-focuses) the tab for an artifact a delegated run produced.\n *\n * First arrival: inserts an `artifact` tab AFTER existing channel/artifact tabs but\n * BEFORE the pinned-last Activity tab, marks it as the {@link FlashKey}, and — unless\n * `focus` is true — leaves focus alone and marks the tab UNSEEN (it glows until\n * visited; per product direction a finished artifact never steals the screen, only the\n * agent's first channel activity does). Subsequent calls for the same artifact version\n * just (optionally) focus the existing tab — no duplicate, no re-flash.\n *\n * @param artifact The produced artifact (id + version id + display name).\n * @param focus Whether to focus the tab (default `false` — glow, don't grab).\n * @param markUnseen Whether an unfocused first arrival glows (default `true`). Pass\n * `false` for HISTORY artifacts (session-review carryover) — they're context, not news.\n * @returns The (new or existing) tab.\n */\n public OpenArtifactTab(artifact: ParsedDelegationArtifact, focus: boolean = false, markUnseen: boolean = true): RealtimeSurfaceTab {\n const key = RealtimeSurfaceTabsModel.ArtifactTabKey(artifact);\n const existing = this.Tabs.find(t => t.Key === key);\n if (existing) {\n if (focus) {\n this.Focus(key);\n }\n return existing;\n }\n const tab: RealtimeSurfaceTab = {\n Key: key,\n Title: artifact.Name,\n Icon: 'fa-solid fa-file-lines',\n Kind: 'artifact',\n Data: { Artifact: artifact }\n };\n // Insert before the pinned-last Activity tab: channels… | artifacts… | Activity.\n const at = this.activityIndex();\n this.Tabs = [...this.Tabs.slice(0, at), tab, ...this.Tabs.slice(at)];\n this.FlashKey = key;\n if (focus) {\n this.ActiveKey = key;\n } else if (markUnseen) {\n this.unseenKeys = new Set([...this.unseenKeys, key]);\n }\n this.Changed$.next();\n return tab;\n }\n\n /**\n * Registers (or updates) an interactive-channel tab. Re-registering an existing key\n * replaces its title/icon/plugin/content in place (this is how a placeholder upgrades\n * to the real surface once the channel comes online). New channel tabs lead the strip\n * (before artifact tabs and the pinned-last Activity tab) — the marquee surfaces.\n *\n * @param registration The channel tab registration.\n * @returns The (new or updated) tab.\n */\n public RegisterChannelTab(registration: RealtimeChannelTabRegistration): RealtimeSurfaceTab {\n const tab: RealtimeSurfaceTab = {\n Key: registration.Key,\n Title: registration.Title,\n Icon: registration.Icon,\n Kind: 'channel',\n Data: { Plugin: registration.Plugin, Content: registration.Content }\n };\n const idx = this.Tabs.findIndex(t => t.Key === registration.Key);\n if (idx >= 0) {\n const next = [...this.Tabs];\n next[idx] = tab;\n this.Tabs = next;\n } else {\n // Insert after existing channel tabs, before artifacts and the pinned-last Activity.\n const firstNonChannel = this.Tabs.findIndex(t => t.Kind !== 'channel');\n const at = firstNonChannel >= 0 ? firstNonChannel : this.Tabs.length;\n this.Tabs = [...this.Tabs.slice(0, at), tab, ...this.Tabs.slice(at)];\n }\n if (registration.Focus) {\n this.ActiveKey = tab.Key;\n this.markSeen(tab.Key);\n }\n this.Changed$.next();\n return tab;\n }\n\n /** Focuses the tab with `key` (no-op when it doesn't exist); visiting clears its unseen glow. */\n public Focus(key: string): void {\n if (!this.Tabs.some(t => t.Key === key)) {\n return;\n }\n const changed = this.ActiveKey !== key || this.unseenKeys.has(key);\n this.ActiveKey = key;\n this.markSeen(key);\n if (changed) {\n this.Changed$.next();\n }\n }\n\n /** The index of the pinned-last Activity tab (insertion boundary for content tabs). */\n private activityIndex(): number {\n const idx = this.Tabs.findIndex(t => t.Key === RealtimeSurfaceTabsModel.ActivityTabKey);\n return idx >= 0 ? idx : this.Tabs.length;\n }\n\n /** Clears a tab's unseen glow (no emission of its own — callers emit). */\n private markSeen(key: string): void {\n if (this.unseenKeys.has(key)) {\n const next = new Set(this.unseenKeys);\n next.delete(key);\n this.unseenKeys = next;\n }\n }\n\n /**\n * Marks the tab with `key` as the {@link FlashKey} (the brief violet \"just arrived\"\n * highlight) WITHOUT changing focus — used by the auto-reveal path when the agent first\n * acts on a channel, so the user's eye lands on the tab that just came alive. No-op for\n * unknown keys; the owning component clears it after a beat via {@link ClearFlash}.\n */\n public FlashTab(key: string): void {\n if (this.FlashKey === key || !this.Tabs.some(t => t.Key === key)) {\n return;\n }\n this.FlashKey = key;\n this.Changed$.next();\n }\n\n /**\n * Removes the tab with `key`. Rules:\n * - the Activity tab is IRREMOVABLE (always the panel's first tab) — removing it is a no-op;\n * - an unknown key is a no-op (returns `false`);\n * - when the removed tab was focused, focus falls back to the Activity tab;\n * - a pending flash on the removed tab is cleaned up so the highlight can't dangle.\n *\n * @param key The tab key to remove.\n * @returns `true` when a tab was removed.\n */\n public RemoveTab(key: string): boolean {\n if (key === RealtimeSurfaceTabsModel.ActivityTabKey || !this.Tabs.some(t => t.Key === key)) {\n return false;\n }\n this.Tabs = this.Tabs.filter(t => t.Key !== key);\n if (this.ActiveKey === key) {\n this.ActiveKey = RealtimeSurfaceTabsModel.ActivityTabKey;\n }\n if (this.FlashKey === key) {\n this.FlashKey = null;\n }\n this.markSeen(key); // a removed tab can't dangle an unseen glow\n this.Changed$.next();\n return true;\n }\n\n /** Clears the transient flash highlight (called by the component after a beat). */\n public ClearFlash(): void {\n if (this.FlashKey !== null) {\n this.FlashKey = null;\n this.Changed$.next();\n }\n }\n}\n\n/**\n * Pure decision helper for the REVIEW→LIVE continuation edge: should the overlay REMOVE the\n * review-registered (template-based, read-only) Whiteboard tab?\n *\n * Yes only when ALL hold:\n * - a live session is active (the channel set emission belongs to a real session start, not\n * the initial/teardown `[]` replay);\n * - review mode actually registered a whiteboard tab (otherwise there is nothing stale);\n * - the live session's resolved channel set has NO Whiteboard channel — when it HAS one, the\n * live plugin re-registers the same tab key and upgrades the pane in place instead.\n *\n * Review ARTIFACT tabs are deliberately NOT removed — they are wanted carryover.\n *\n * Kept framework-free (like the model) so the rule is unit-testable in isolation.\n */\nexport function ShouldRemoveReviewWhiteboardTab(\n liveSessionActive: boolean,\n reviewWhiteboardTabRegistered: boolean,\n liveChannels: ReadonlyArray<{ ChannelName: string }>\n): boolean {\n if (!liveSessionActive || !reviewWhiteboardTabRegistered) {\n return false;\n }\n return !liveChannels.some(c => c.ChannelName?.trim().toLowerCase() === 'whiteboard');\n}\n"]}
|
|
1
|
+
{"version":3,"file":"realtime-surface-tabs.model.js","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-surface-tabs.model.ts"],"names":[],"mappings":"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","sourcesContent":["import { Subject } from 'rxjs';\nimport type { TemplateRef } from '@angular/core';\nimport type { BaseRealtimeChannelClient } from './channels/base-realtime-channel-client';\nimport { ChannelTabColor } from './realtime-surface-tab-style';\n\n/**\n * The kind of a surface-panel tab:\n * - `activity` — the session-activity tab (pinned LAST, right-aligned). Hosts the activity\n * rail AND, since the artifact redesign, the inline artifact previews + the split-pane\n * artifact viewer. Shown only once ≥1 agent run has occurred (see\n * {@link RealtimeSurfaceTabsModel.SetShowActivityTab}).\n * - `channel` — an interactive-channel surface (e.g. the Whiteboard). Registered per\n * used channel via {@link RealtimeSurfaceTabsModel.RegisterChannelTab}; renders the\n * plugin's dynamically-created surface component (or a registered template for\n * legacy/template-based panes), with the \"coming online…\" placeholder until either\n * is supplied.\n *\n * NOTE: artifacts NO LONGER get their own tab. A delegated run's artifacts now render\n * INSIDE the Activity tab (inline previews + an `as-split` viewer pane) — see\n * `RealtimeActivityRailComponent`.\n */\nexport type RealtimeSurfaceTabKind = 'activity' | 'channel';\n\n/**\n * Per-kind payload carried on a {@link RealtimeSurfaceTab}.\n */\nexport interface RealtimeSurfaceTabData {\n /**\n * For `channel` tabs: the channel PLUGIN whose surface component the pane creates\n * dynamically (and binds back to the plugin) — the registry-driven path every real\n * channel uses. Takes precedence over {@link Content}.\n */\n Plugin?: BaseRealtimeChannelClient;\n /**\n * For `channel` tabs: a TEMPLATE-based pane body. Backward-compatible alternative to\n * {@link Plugin} for hosts that render a bespoke surface without a channel plugin.\n * When BOTH are absent the pane renders the built-in \"coming online…\" placeholder.\n */\n Content?: TemplateRef<unknown>;\n}\n\n/**\n * One tab on the call overlay's tabbed surface panel (the right panel): a channel surface\n * (left cluster) or the session-activity tab (right-aligned).\n */\nexport interface RealtimeSurfaceTab {\n /** Stable unique key (`activity`, or the channel's registered key). */\n Key: string;\n /** Tab strip label (channel name, or \"Activity\"). */\n Title: string;\n /** Font Awesome icon class for the tab strip (e.g. `fa-solid fa-chalkboard`). */\n Icon: string;\n /** What the tab renders. */\n Kind: RealtimeSurfaceTabKind;\n /**\n * Accent color for the tab's dot + active underline. Channel tabs carry a distinct color\n * (plugin-supplied or a deterministic hash of the name); the Activity tab uses its own\n * fixed accent in CSS, so its `Color` is left undefined.\n */\n Color?: string;\n /** Kind-specific payload. */\n Data?: RealtimeSurfaceTabData;\n}\n\n/**\n * Registration for an interactive-channel tab. The overlay shell registers one per\n * USED channel plugin (supplying {@link Plugin}); supplying {@link Plugin} or\n * {@link Content} later under the same `Key` upgrades a placeholder tab to the real surface.\n */\nexport interface RealtimeChannelTabRegistration {\n /** Stable channel key (the plugin's `ChannelName`, e.g. `Whiteboard`). Re-registering the same key updates the tab. */\n Key: string;\n /** Tab strip label (e.g. `Whiteboard`). */\n Title: string;\n /** Font Awesome icon class (e.g. `fa-solid fa-chalkboard`). */\n Icon: string;\n /**\n * Optional explicit accent color for the tab. When omitted, a deterministic color is\n * derived from {@link Key} so every channel tab still reads as a distinct surface.\n */\n Color?: string | null;\n /** The channel plugin whose surface the pane creates + binds. Preferred over {@link Content}. */\n Plugin?: BaseRealtimeChannelClient;\n /** A template-based pane body (legacy/bespoke panes). Omit both to show the \"coming online…\" placeholder. */\n Content?: TemplateRef<unknown>;\n /** Focus the tab immediately after registration (default `false`). */\n Focus?: boolean;\n}\n\n/**\n * Framework-free state for the call overlay's tabbed surface panel: the ordered tab list\n * (CHANNEL tabs first — the marquee surfaces, left cluster — with the session-activity tab\n * pinned LAST and right-aligned by the strip), the active tab, and the transient \"flash\"\n * highlight for a just-revealed channel tab.\n *\n * The Activity tab is GATED: it isn't listed until {@link SetShowActivityTab}(true) — i.e.\n * once ≥1 agent run has occurred (or in review mode). Channel tabs appear only as channels\n * come into play (the whiteboard up-front; every other channel on first use), so an\n * idle voice-first session shows an empty/near-empty strip rather than a row of unused tabs.\n *\n * Owned by `RealtimeSurfaceTabsComponent`; kept free of Angular runtime imports so the\n * add / focus / dedupe / flash logic is unit-testable in isolation. All collections are\n * REPLACED (never mutated) on change, and every change emits {@link Changed$}.\n */\nexport class RealtimeSurfaceTabsModel {\n /** The fixed key of the session-activity tab (pinned LAST, right-aligned). */\n public static readonly ActivityTabKey = 'activity';\n\n /** The activity tab definition, appended last whenever {@link showActivity} is true. */\n private static readonly ActivityTab: RealtimeSurfaceTab = {\n Key: RealtimeSurfaceTabsModel.ActivityTabKey,\n Title: 'Activity',\n Icon: 'fa-solid fa-wave-square',\n Kind: 'activity'\n };\n\n /** Channel tabs (left cluster), in registration order. Replaced immutably on change. */\n private channelTabs: RealtimeSurfaceTab[] = [];\n\n /** Whether the gated Activity tab is currently shown (≥1 agent run, or review mode). */\n private showActivity = false;\n\n /** Key of the currently focused tab. */\n public ActiveKey: string = RealtimeSurfaceTabsModel.ActivityTabKey;\n\n /**\n * Key of the tab currently \"flashing\" (the brief highlight a just-revealed channel tab\n * gets when the agent first acts on it). Cleared by the owning component after a beat via\n * {@link ClearFlash}.\n */\n public FlashKey: string | null = null;\n\n /** Emits after every model change so the owning component can mark for check. */\n public readonly Changed$ = new Subject<void>();\n\n /**\n * The ordered tabs: channel tabs (left), then the Activity tab LAST when shown. The strip\n * right-aligns the Activity tab via a flex spacer, so this order also matches reading order.\n */\n public get Tabs(): RealtimeSurfaceTab[] {\n return this.showActivity\n ? [...this.channelTabs, RealtimeSurfaceTabsModel.ActivityTab]\n : [...this.channelTabs];\n }\n\n /** Whether the Activity tab is currently part of the strip. */\n public get IsActivityShown(): boolean {\n return this.showActivity;\n }\n\n /**\n * The currently focused tab. Resolves to the active key when it still exists, else falls\n * back to the Activity tab (when shown), else the first channel tab, else the Activity tab\n * definition (so a consumer always has SOMETHING to render even on an empty strip).\n */\n public get ActiveTab(): RealtimeSurfaceTab {\n const tabs = this.Tabs;\n return tabs.find(t => t.Key === this.ActiveKey)\n ?? tabs.find(t => t.Key === RealtimeSurfaceTabsModel.ActivityTabKey)\n ?? tabs[0]\n ?? RealtimeSurfaceTabsModel.ActivityTab;\n }\n\n /**\n * Shows or hides the gated Activity tab. Turning it ON when an empty strip was implicitly\n * focusing Activity keeps focus on Activity; turning it OFF while it was focused falls\n * focus back to the first channel tab (if any). No-op (no emission) when unchanged.\n *\n * @param show Whether ≥1 agent run has occurred (or review mode) — the gate.\n */\n public SetShowActivityTab(show: boolean): void {\n if (this.showActivity === show) {\n return;\n }\n this.showActivity = show;\n if (!show && this.ActiveKey === RealtimeSurfaceTabsModel.ActivityTabKey) {\n this.ActiveKey = this.channelTabs[0]?.Key ?? RealtimeSurfaceTabsModel.ActivityTabKey;\n }\n this.Changed$.next();\n }\n\n /**\n * Registers (or updates) an interactive-channel tab. Re-registering an existing key\n * replaces its title/icon/color/plugin/content in place (this is how a placeholder\n * upgrades to the real surface once the channel comes online). New channel tabs join the\n * left cluster in registration order. A registration without an explicit {@link\n * RealtimeChannelTabRegistration.Color} gets a deterministic color from its key.\n *\n * @param registration The channel tab registration.\n * @returns The (new or updated) tab.\n */\n public RegisterChannelTab(registration: RealtimeChannelTabRegistration): RealtimeSurfaceTab {\n const tab: RealtimeSurfaceTab = {\n Key: registration.Key,\n Title: registration.Title,\n Icon: registration.Icon,\n Kind: 'channel',\n Color: registration.Color ?? ChannelTabColor(registration.Key),\n Data: { Plugin: registration.Plugin, Content: registration.Content }\n };\n const idx = this.channelTabs.findIndex(t => t.Key === registration.Key);\n if (idx >= 0) {\n const next = [...this.channelTabs];\n next[idx] = tab;\n this.channelTabs = next;\n } else {\n this.channelTabs = [...this.channelTabs, tab];\n }\n if (registration.Focus) {\n this.ActiveKey = tab.Key;\n }\n this.Changed$.next();\n return tab;\n }\n\n /** Focuses the tab with `key` (no-op when it doesn't exist or is already active). */\n public Focus(key: string): void {\n if (!this.Tabs.some(t => t.Key === key) || this.ActiveKey === key) {\n return;\n }\n this.ActiveKey = key;\n this.Changed$.next();\n }\n\n /**\n * Marks the tab with `key` as the {@link FlashKey} (the brief \"just arrived\" highlight)\n * WITHOUT changing focus — used by the auto-reveal path when the agent first acts on a\n * channel, so the user's eye lands on the tab that just came alive. No-op for unknown\n * keys; the owning component clears it after a beat via {@link ClearFlash}.\n */\n public FlashTab(key: string): void {\n if (this.FlashKey === key || !this.Tabs.some(t => t.Key === key)) {\n return;\n }\n this.FlashKey = key;\n this.Changed$.next();\n }\n\n /**\n * Removes the channel tab with `key`. Rules:\n * - the Activity tab is IRREMOVABLE — removing it is a no-op;\n * - an unknown key is a no-op (returns `false`);\n * - when the removed tab was focused, focus falls back to the Activity tab (if shown),\n * else the first remaining channel tab;\n * - a pending flash on the removed tab is cleaned up so the highlight can't dangle.\n *\n * @param key The tab key to remove.\n * @returns `true` when a tab was removed.\n */\n public RemoveTab(key: string): boolean {\n if (key === RealtimeSurfaceTabsModel.ActivityTabKey || !this.channelTabs.some(t => t.Key === key)) {\n return false;\n }\n this.channelTabs = this.channelTabs.filter(t => t.Key !== key);\n if (this.ActiveKey === key) {\n this.ActiveKey = this.showActivity\n ? RealtimeSurfaceTabsModel.ActivityTabKey\n : (this.channelTabs[0]?.Key ?? RealtimeSurfaceTabsModel.ActivityTabKey);\n }\n if (this.FlashKey === key) {\n this.FlashKey = null;\n }\n this.Changed$.next();\n return true;\n }\n\n /** Clears the transient flash highlight (called by the component after a beat). */\n public ClearFlash(): void {\n if (this.FlashKey !== null) {\n this.FlashKey = null;\n this.Changed$.next();\n }\n }\n}\n\n/**\n * Pure decision helper for the REVIEW→LIVE continuation edge: should the overlay REMOVE the\n * review-registered (template-based, read-only) Whiteboard tab?\n *\n * Yes only when ALL hold:\n * - a live session is active (the channel set emission belongs to a real session start, not\n * the initial/teardown `[]` replay);\n * - review mode actually registered a whiteboard tab (otherwise there is nothing stale);\n * - the live session's resolved channel set has NO Whiteboard channel — when it HAS one, the\n * live plugin re-registers the same tab key and upgrades the pane in place instead.\n *\n * Kept framework-free (like the model) so the rule is unit-testable in isolation.\n */\nexport function ShouldRemoveReviewWhiteboardTab(\n liveSessionActive: boolean,\n reviewWhiteboardTabRegistered: boolean,\n liveChannels: ReadonlyArray<{ ChannelName: string }>\n): boolean {\n if (!liveSessionActive || !reviewWhiteboardTabRegistered) {\n return false;\n }\n return !liveChannels.some(c => c.ChannelName?.trim().toLowerCase() === 'whiteboard');\n}\n"]}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Declarative UI configuration for the realtime voice widget.
|
|
3
|
+
*
|
|
4
|
+
* The realtime widget historically decided *what to show* from an internal
|
|
5
|
+
* "disclosure ratchet" ({@link import('./realtime-disclosure').RealtimeDisclosureModel})
|
|
6
|
+
* plus a handful of scattered getters. That made it impossible for a host
|
|
7
|
+
* (the chat overlay, a full-screen route, an embedded demo surface, a kiosk,
|
|
8
|
+
* a mobile sheet…) to tailor the surface to its context.
|
|
9
|
+
*
|
|
10
|
+
* This module introduces a single, pure, side-effect-free resolution step that
|
|
11
|
+
* sits between three concerns:
|
|
12
|
+
*
|
|
13
|
+
* 1. **{@link RealtimeUiInputs}** — the *consumer's intent*. A flat bag of
|
|
14
|
+
* `@Input()`-friendly feature switches ("show the surface panel?",
|
|
15
|
+
* "allow text?", "which chrome?") with documented defaults. A host sets
|
|
16
|
+
* only what it cares about; everything else stays on its sensible default,
|
|
17
|
+
* so the widget behaves exactly as before when no inputs are provided.
|
|
18
|
+
*
|
|
19
|
+
* 2. **{@link RealtimeUiSignals}** — the *live runtime state*. Read-only facts
|
|
20
|
+
* the widget already knows: how wide its container is, whether the user has
|
|
21
|
+
* revealed text, what the disclosure model currently permits, whether a
|
|
22
|
+
* surface/channel/activity exists, the connection state, review/focus modes.
|
|
23
|
+
*
|
|
24
|
+
* 3. **{@link ResolvedRealtimeUi}** — the *answer*. A fully-resolved, boolean
|
|
25
|
+
* view-model the template binds to directly. No `&&` chains in the HTML; no
|
|
26
|
+
* business logic in getters. One source of truth, trivially unit-testable.
|
|
27
|
+
*
|
|
28
|
+
* ## The headline behaviour: auto orb ↔ console
|
|
29
|
+
*
|
|
30
|
+
* The default {@link RealtimeChromeMode} is `'auto'`. In auto mode the widget is
|
|
31
|
+
* a calm **orb** until *two* things are true at once:
|
|
32
|
+
*
|
|
33
|
+
* - the container is at least {@link RealtimeUiInputs.consoleBreakpointPx}
|
|
34
|
+
* wide (there's room for a structured console), **and**
|
|
35
|
+
* - the user has actually asked to see text (`textRevealed`), or the widget
|
|
36
|
+
* is reviewing a past session (which always shows the transcript).
|
|
37
|
+
*
|
|
38
|
+
* In other words: **getting bigger is not enough — if the user hasn't asked for
|
|
39
|
+
* text, we keep the orb.** This preserves the loved "ambient by default"
|
|
40
|
+
* feeling while letting the experience graduate to a full command console the
|
|
41
|
+
* moment it earns the space *and* the intent. Hosts that want to force one
|
|
42
|
+
* chrome forever can pass `chrome: 'orb'` or `chrome: 'console'`.
|
|
43
|
+
*
|
|
44
|
+
* The resolver is intentionally framework-free (no Angular import) so it can be
|
|
45
|
+
* unit-tested in isolation and reused by any host.
|
|
46
|
+
*
|
|
47
|
+
* @module realtime-ui-config
|
|
48
|
+
*/
|
|
49
|
+
/**
|
|
50
|
+
* Which visual chrome the widget renders.
|
|
51
|
+
*
|
|
52
|
+
* - `'orb'` — the ambient hero orb. Minimal controls; transcript/console hidden
|
|
53
|
+
* unless the user reveals them. Best for narrow/overlay/mobile contexts.
|
|
54
|
+
* - `'console'` — the structured command console: header, transcript, composer
|
|
55
|
+
* dock, and (when room allows) the surface panel. Best for full-screen.
|
|
56
|
+
* - `'auto'` — *(default)* start as an orb; graduate to a console when the
|
|
57
|
+
* container is wide enough **and** the user has revealed text. See the module
|
|
58
|
+
* docs for the exact rule.
|
|
59
|
+
*/
|
|
60
|
+
export type RealtimeChromeMode = 'orb' | 'console' | 'auto';
|
|
61
|
+
/**
|
|
62
|
+
* Identifies a control the user invoked. Emitted by the widget's `ControlInvoked`
|
|
63
|
+
* output so a host can observe (or react to) any control — even one it has hidden
|
|
64
|
+
* via inputs and re-rendered itself. Extend the union as new controls are added.
|
|
65
|
+
*/
|
|
66
|
+
export type RealtimeControlId = 'mute' | 'captions' | 'type' | 'end' | 'minimize' | 'surface' | 'gear' | 'reveal-text' | 'pure-audio' | 'density';
|
|
67
|
+
/**
|
|
68
|
+
* The connection lifecycle states the widget cares about for layout decisions.
|
|
69
|
+
* Mirrors the widget's runtime `RealtimeConnectionState`; duplicated as a string
|
|
70
|
+
* union here so this module stays import-free of the Angular component.
|
|
71
|
+
*/
|
|
72
|
+
export type RealtimeUiConnectionState = 'connecting' | 'listening' | 'speaking' | 'thinking' | 'idle' | 'error';
|
|
73
|
+
/**
|
|
74
|
+
* The default container width (px) at or above which `'auto'` chrome is *allowed*
|
|
75
|
+
* to graduate from orb to console — provided the user has also revealed text.
|
|
76
|
+
* Chosen so a typical 390px chat overlay stays an orb, while a half-screen or
|
|
77
|
+
* full-screen surface can become a console. Override per-host via
|
|
78
|
+
* {@link RealtimeUiInputs.consoleBreakpointPx}.
|
|
79
|
+
*/
|
|
80
|
+
export declare const REALTIME_CONSOLE_BREAKPOINT_DEFAULT = 560;
|
|
81
|
+
/**
|
|
82
|
+
* Consumer-facing configuration for the realtime widget — every field is a
|
|
83
|
+
* declarative switch a host can set via an `@Input()`. **All fields are
|
|
84
|
+
* optional**; omitted fields fall back to {@link DEFAULT_REALTIME_UI_INPUTS},
|
|
85
|
+
* which reproduces the widget's historical behaviour. This is the surface that
|
|
86
|
+
* lets the chat overlay slim the widget down, a full-screen route open it up,
|
|
87
|
+
* and unexpected hosts (kiosks, demos, embeds) compose their own variant.
|
|
88
|
+
*
|
|
89
|
+
* A `false` here is a **hard disable** — it removes the affordance regardless of
|
|
90
|
+
* what the disclosure model or runtime state would otherwise permit. A `true`
|
|
91
|
+
* means "allow it"; the affordance still only appears when it's also *earned* by
|
|
92
|
+
* the runtime (e.g. a surface panel only renders once a channel actually exists).
|
|
93
|
+
*/
|
|
94
|
+
export interface RealtimeUiInputs {
|
|
95
|
+
/** Which chrome to render. Default `'auto'`. */
|
|
96
|
+
chrome?: RealtimeChromeMode;
|
|
97
|
+
/**
|
|
98
|
+
* In `'auto'` chrome, the container width (px) at/above which the widget may
|
|
99
|
+
* graduate to a console (still gated on text being revealed). Default
|
|
100
|
+
* {@link REALTIME_CONSOLE_BREAKPOINT_DEFAULT}.
|
|
101
|
+
*/
|
|
102
|
+
consoleBreakpointPx?: number;
|
|
103
|
+
/**
|
|
104
|
+
* Force compact spacing/typography regardless of size — useful for dense
|
|
105
|
+
* mobile sheets. Default `false` (the widget infers compactness from width).
|
|
106
|
+
*/
|
|
107
|
+
compact?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Fade non-essential controls when the session is idle (orb chrome only), for
|
|
110
|
+
* a cinematic feel. Default `true`.
|
|
111
|
+
*/
|
|
112
|
+
autoHideControls?: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* May the user reveal the transcript at all? When `false`, the widget is a
|
|
115
|
+
* pure voice orb with no path to text (and therefore never graduates to a
|
|
116
|
+
* console in `'auto'` mode). Default `true`.
|
|
117
|
+
*/
|
|
118
|
+
allowTextReveal?: boolean;
|
|
119
|
+
/** Show the captions toggle. Default `true`. */
|
|
120
|
+
showCaptionsControl?: boolean;
|
|
121
|
+
/** Show the density picker inside the gear menu. Default `true`. */
|
|
122
|
+
showDensityPicker?: boolean;
|
|
123
|
+
/** Show the minimize control (collapse the call without ending it). Default `true`. */
|
|
124
|
+
showMinimize?: boolean;
|
|
125
|
+
/** Show the end-call control. Default `true`. (Hosts that own their own end button may hide it.) */
|
|
126
|
+
showEnd?: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Show the right-hand surface panel (whiteboard / browser / interactive
|
|
129
|
+
* channels). Default `true`. Only renders in console chrome and once a panel
|
|
130
|
+
* is actually earned.
|
|
131
|
+
*/
|
|
132
|
+
showSurfacePanel?: boolean;
|
|
133
|
+
/** Show the channel strip (active interactive channels). Default `true`. */
|
|
134
|
+
showChannels?: boolean;
|
|
135
|
+
/** Show the Activity rail/tab (delegations, artifacts timeline). Default `true`. */
|
|
136
|
+
showActivityRail?: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Show developer affordances ("open session / open run" links, dev-only
|
|
139
|
+
* panels). Default `true`, but still additionally gated by the per-session
|
|
140
|
+
* dev-mode toggle, so this is a hard *ceiling*, not a force-on.
|
|
141
|
+
*/
|
|
142
|
+
showDevLinks?: boolean;
|
|
143
|
+
/** Allow drag-to-resize of the surface panel. Default `true`. */
|
|
144
|
+
allowResize?: boolean;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The complete, defaulted input set. Spreading this over a partial
|
|
148
|
+
* {@link RealtimeUiInputs} yields a fully-populated config; the resolver does
|
|
149
|
+
* exactly that, so callers never deal with `undefined`.
|
|
150
|
+
*/
|
|
151
|
+
export declare const DEFAULT_REALTIME_UI_INPUTS: Required<RealtimeUiInputs>;
|
|
152
|
+
/**
|
|
153
|
+
* Live runtime facts the widget feeds into the resolver. These are *observed*,
|
|
154
|
+
* not configured — they come from the disclosure model, a `ResizeObserver`, and
|
|
155
|
+
* the session/channel state. Pure data so the resolver stays testable.
|
|
156
|
+
*/
|
|
157
|
+
export interface RealtimeUiSignals {
|
|
158
|
+
/** Current width of the widget's container, in px (from a `ResizeObserver`). */
|
|
159
|
+
containerWidthPx: number;
|
|
160
|
+
/**
|
|
161
|
+
* Has the user revealed text this session? (i.e. tapped "show the
|
|
162
|
+
* conversation" / engaged the composer — disclosure level ≥ 1.) This is the
|
|
163
|
+
* intent half of the auto orb↔console rule.
|
|
164
|
+
*/
|
|
165
|
+
textRevealed: boolean;
|
|
166
|
+
/** Disclosure model says a transcript may be shown. */
|
|
167
|
+
disclosureShowThread: boolean;
|
|
168
|
+
/** Disclosure model says the composer/text dock may be shown. */
|
|
169
|
+
disclosureShowComposer: boolean;
|
|
170
|
+
/** Disclosure model says a surface panel may be shown. */
|
|
171
|
+
disclosureShowPanel: boolean;
|
|
172
|
+
/** Disclosure model says the gear/settings menu may be shown. */
|
|
173
|
+
disclosureShowGear: boolean;
|
|
174
|
+
/** A surface/channel actually exists to populate the panel. */
|
|
175
|
+
surfacePanelEarned: boolean;
|
|
176
|
+
/** ≥ 1 interactive channel is active. */
|
|
177
|
+
hasChannels: boolean;
|
|
178
|
+
/** ≥ 1 delegation/activity has occurred (Activity rail has content). */
|
|
179
|
+
hasActivity: boolean;
|
|
180
|
+
/** Per-session developer mode is on. */
|
|
181
|
+
devMode: boolean;
|
|
182
|
+
/** The widget is reviewing a past (recorded) session, not a live call. */
|
|
183
|
+
isReviewing: boolean;
|
|
184
|
+
/** A single channel surface is maximized (focus mode); the main column is hidden. */
|
|
185
|
+
channelFocus: boolean;
|
|
186
|
+
/** Current connection lifecycle state. */
|
|
187
|
+
connectionState: RealtimeUiConnectionState;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* The resolved, render-ready view-model. Every field is a final boolean (or the
|
|
191
|
+
* effective chrome) — the template binds straight to these with no further
|
|
192
|
+
* logic. This is the single source of truth for "what is on screen right now".
|
|
193
|
+
*/
|
|
194
|
+
export interface ResolvedRealtimeUi {
|
|
195
|
+
/** The effective chrome after resolving `'auto'`. */
|
|
196
|
+
chrome: 'orb' | 'console';
|
|
197
|
+
/** Whether compact spacing/typography applies. */
|
|
198
|
+
compact: boolean;
|
|
199
|
+
/** True while connecting — hosts can show a single, size-independent loader. */
|
|
200
|
+
connecting: boolean;
|
|
201
|
+
/** The big ambient hero orb is the primary surface. */
|
|
202
|
+
showHero: boolean;
|
|
203
|
+
/** The transcript/thread is visible. */
|
|
204
|
+
showThread: boolean;
|
|
205
|
+
/** The text composer dock is visible. */
|
|
206
|
+
showComposer: boolean;
|
|
207
|
+
/** The right-hand surface panel is visible. */
|
|
208
|
+
showSurfacePanel: boolean;
|
|
209
|
+
/** The Activity tab/rail is available. */
|
|
210
|
+
showActivityTab: boolean;
|
|
211
|
+
/** The channel strip is visible. */
|
|
212
|
+
showChannelStrip: boolean;
|
|
213
|
+
/** The captions toggle is available. */
|
|
214
|
+
showCaptionsControl: boolean;
|
|
215
|
+
/** The density picker is available (inside the gear). */
|
|
216
|
+
showDensityPicker: boolean;
|
|
217
|
+
/** The gear/settings affordance is available. */
|
|
218
|
+
showGear: boolean;
|
|
219
|
+
/** Developer links/panels are available. */
|
|
220
|
+
showDevLinks: boolean;
|
|
221
|
+
/** The minimize control is available. */
|
|
222
|
+
showMinimize: boolean;
|
|
223
|
+
/** The end-call control is available. */
|
|
224
|
+
showEnd: boolean;
|
|
225
|
+
/** The surface panel may be drag-resized. */
|
|
226
|
+
allowResize: boolean;
|
|
227
|
+
/** The user has a path to reveal text. */
|
|
228
|
+
allowTextReveal: boolean;
|
|
229
|
+
/** Non-essential controls should auto-fade when idle. */
|
|
230
|
+
autoHideControls: boolean;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* A safe, dependency-free baseline {@link RealtimeUiSignals}. Use this to seed a
|
|
234
|
+
* resolved view-model **before** the component's runtime dependencies (the
|
|
235
|
+
* disclosure model, the session state, the `ResizeObserver`) exist — e.g. in a
|
|
236
|
+
* field initializer. It describes a freshly-connecting widget at zero width with
|
|
237
|
+
* nothing earned yet, so the first paint is a calm orb until `recomputeUi()`
|
|
238
|
+
* runs with real signals. Never read `this` to build the first value.
|
|
239
|
+
*/
|
|
240
|
+
export declare const DEFAULT_REALTIME_UI_SIGNALS: RealtimeUiSignals;
|
|
241
|
+
/**
|
|
242
|
+
* Resolve the consumer config + live signals into a render-ready view-model.
|
|
243
|
+
*
|
|
244
|
+
* Pure and deterministic: same inputs ⇒ same output, no side effects, no clock,
|
|
245
|
+
* no DOM. Safe to call on every change-detection pass and trivial to unit test.
|
|
246
|
+
*
|
|
247
|
+
* The resolution order is:
|
|
248
|
+
* 1. fill defaults,
|
|
249
|
+
* 2. decide the effective {@link RealtimeChromeMode} (the orb↔console rule),
|
|
250
|
+
* 3. for each affordance, AND the consumer's switch with the runtime gate.
|
|
251
|
+
*
|
|
252
|
+
* @param inputs consumer configuration (partial; defaults fill the rest)
|
|
253
|
+
* @param signals live runtime facts
|
|
254
|
+
* @returns the fully-resolved {@link ResolvedRealtimeUi}
|
|
255
|
+
*
|
|
256
|
+
* @example Chat overlay (lean, ambient):
|
|
257
|
+
* ```ts
|
|
258
|
+
* resolveRealtimeUi(
|
|
259
|
+
* { chrome: 'auto', showSurfacePanel: false, showActivityRail: false, showDevLinks: false },
|
|
260
|
+
* signals
|
|
261
|
+
* );
|
|
262
|
+
* ```
|
|
263
|
+
*
|
|
264
|
+
* @example Full-screen route (rich console):
|
|
265
|
+
* ```ts
|
|
266
|
+
* resolveRealtimeUi({ chrome: 'auto', consoleBreakpointPx: 480 }, wideSignals);
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
export declare function resolveRealtimeUi(inputs: RealtimeUiInputs | null | undefined, signals: RealtimeUiSignals): ResolvedRealtimeUi;
|
|
270
|
+
//# sourceMappingURL=realtime-ui-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime-ui-config.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-ui-config.ts"],"names":[],"mappings":"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"}
|