@memberjunction/ng-conversations 6.2.0-edge.0 → 6.2.0-edge.2
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/README.md +43 -2
- package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts +19 -3
- 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 +39 -7
- package/dist/lib/components/active-tasks/active-tasks-panel.component.js.map +1 -1
- package/dist/lib/components/agent/active-agent-indicator.component.d.ts +74 -6
- package/dist/lib/components/agent/active-agent-indicator.component.d.ts.map +1 -1
- package/dist/lib/components/agent/active-agent-indicator.component.js +111 -21
- package/dist/lib/components/agent/active-agent-indicator.component.js.map +1 -1
- package/dist/lib/components/agent/agent-process-panel.component.d.ts +31 -5
- package/dist/lib/components/agent/agent-process-panel.component.d.ts.map +1 -1
- package/dist/lib/components/agent/agent-process-panel.component.js +71 -15
- package/dist/lib/components/agent/agent-process-panel.component.js.map +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.d.ts +65 -9
- package/dist/lib/components/artifact/artifact-share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.js +169 -57
- package/dist/lib/components/artifact/artifact-share-modal.component.js.map +1 -1
- package/dist/lib/components/attachment/image-viewer.component.d.ts +77 -11
- package/dist/lib/components/attachment/image-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/attachment/image-viewer.component.js +181 -47
- package/dist/lib/components/attachment/image-viewer.component.js.map +1 -1
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.d.ts +129 -19
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js +350 -116
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js.map +1 -1
- package/dist/lib/components/collection/artifact-create-modal.component.d.ts +60 -8
- package/dist/lib/components/collection/artifact-create-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/artifact-create-modal.component.js +130 -46
- package/dist/lib/components/collection/artifact-create-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-artifact-card.component.d.ts +63 -3
- package/dist/lib/components/collection/collection-artifact-card.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-artifact-card.component.js +113 -19
- package/dist/lib/components/collection/collection-artifact-card.component.js.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.d.ts +54 -8
- package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.js +130 -46
- package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.d.ts +70 -10
- package/dist/lib/components/collection/collection-share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.js +175 -53
- package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.d.ts +89 -9
- package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.js +220 -70
- package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
- package/dist/lib/components/collection/collection-view.component.d.ts +89 -11
- package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +154 -40
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.d.ts +390 -38
- package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +951 -367
- package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
- package/dist/lib/components/composer/ai-composer.component.d.ts +213 -18
- package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -1
- package/dist/lib/components/composer/ai-composer.component.js +388 -44
- package/dist/lib/components/composer/ai-composer.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.d.ts +12 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.js +26 -4
- package/dist/lib/components/conversation/conversation-agent-picker.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +1191 -124
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +2816 -785
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +139 -19
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.js +296 -59
- package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.d.ts +579 -78
- package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.js +2322 -823
- package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
- package/dist/lib/components/conversation/pinned-messages-panel.component.d.ts +42 -4
- package/dist/lib/components/conversation/pinned-messages-panel.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/pinned-messages-panel.component.js +93 -21
- package/dist/lib/components/conversation/pinned-messages-panel.component.js.map +1 -1
- package/dist/lib/components/dialogs/input-dialog.component.d.ts +57 -11
- package/dist/lib/components/dialogs/input-dialog.component.d.ts.map +1 -1
- package/dist/lib/components/dialogs/input-dialog.component.js +128 -16
- package/dist/lib/components/dialogs/input-dialog.component.js.map +1 -1
- package/dist/lib/components/dialogs/rating-dialog.component.d.ts +68 -10
- package/dist/lib/components/dialogs/rating-dialog.component.d.ts.map +1 -1
- package/dist/lib/components/dialogs/rating-dialog.component.js +151 -27
- package/dist/lib/components/dialogs/rating-dialog.component.js.map +1 -1
- package/dist/lib/components/export/export-modal.component.d.ts +84 -10
- package/dist/lib/components/export/export-modal.component.d.ts.map +1 -1
- package/dist/lib/components/export/export-modal.component.js +173 -49
- package/dist/lib/components/export/export-modal.component.js.map +1 -1
- package/dist/lib/components/global-tasks/global-tasks-panel.component.d.ts +29 -3
- package/dist/lib/components/global-tasks/global-tasks-panel.component.d.ts.map +1 -1
- package/dist/lib/components/global-tasks/global-tasks-panel.component.js +58 -12
- package/dist/lib/components/global-tasks/global-tasks-panel.component.js.map +1 -1
- package/dist/lib/components/library/library-full-view.component.d.ts +57 -8
- package/dist/lib/components/library/library-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/library/library-full-view.component.js +119 -35
- package/dist/lib/components/library/library-full-view.component.js.map +1 -1
- package/dist/lib/components/members/members-modal.component.d.ts +76 -10
- package/dist/lib/components/members/members-modal.component.d.ts.map +1 -1
- package/dist/lib/components/members/members-modal.component.js +164 -50
- package/dist/lib/components/members/members-modal.component.js.map +1 -1
- package/dist/lib/components/message/actionable-commands.component.d.ts +49 -5
- package/dist/lib/components/message/actionable-commands.component.d.ts.map +1 -1
- package/dist/lib/components/message/actionable-commands.component.js +140 -26
- package/dist/lib/components/message/actionable-commands.component.js.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.d.ts +46 -10
- package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.js +120 -36
- package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +613 -74
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +1390 -422
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +490 -29
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +1088 -244
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +297 -29
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +598 -123
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/navigation/conversation-navigation.component.d.ts +64 -5
- package/dist/lib/components/navigation/conversation-navigation.component.d.ts.map +1 -1
- package/dist/lib/components/navigation/conversation-navigation.component.js +101 -11
- package/dist/lib/components/navigation/conversation-navigation.component.js.map +1 -1
- package/dist/lib/components/notification/activity-indicator.component.d.ts +6 -2
- package/dist/lib/components/notification/activity-indicator.component.d.ts.map +1 -1
- package/dist/lib/components/notification/activity-indicator.component.js +13 -3
- package/dist/lib/components/notification/activity-indicator.component.js.map +1 -1
- package/dist/lib/components/notification/notification-badge.component.d.ts +15 -3
- package/dist/lib/components/notification/notification-badge.component.d.ts.map +1 -1
- package/dist/lib/components/notification/notification-badge.component.js +36 -8
- package/dist/lib/components/notification/notification-badge.component.js.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.js +4 -4
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.d.ts +93 -11
- package/dist/lib/components/project/project-form-modal.component.d.ts.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.js +348 -87
- package/dist/lib/components/project/project-form-modal.component.js.map +1 -1
- package/dist/lib/components/project/project-selector.component.d.ts +78 -8
- package/dist/lib/components/project/project-selector.component.d.ts.map +1 -1
- package/dist/lib/components/project/project-selector.component.js +177 -46
- package/dist/lib/components/project/project-selector.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.js +2 -2
- package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.js +2 -2
- package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +2 -2
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +18 -18
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts +47 -23
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js +136 -92
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +2 -2
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js +4 -4
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js +3 -3
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
- package/dist/lib/components/realtime/realtime-ui-config.d.ts +13 -11
- package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-ui-config.js +29 -25
- package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +3 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +6 -2
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
- package/dist/lib/components/search/search-panel.component.d.ts +133 -22
- package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
- package/dist/lib/components/search/search-panel.component.js +312 -83
- package/dist/lib/components/search/search-panel.component.js.map +1 -1
- package/dist/lib/components/share/share-modal.component.d.ts +69 -9
- package/dist/lib/components/share/share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/share/share-modal.component.js +139 -31
- package/dist/lib/components/share/share-modal.component.js.map +1 -1
- package/dist/lib/components/shared/user-picker.component.d.ts +48 -8
- package/dist/lib/components/shared/user-picker.component.d.ts.map +1 -1
- package/dist/lib/components/shared/user-picker.component.js +110 -30
- package/dist/lib/components/shared/user-picker.component.js.map +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts +114 -11
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts.map +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.js +199 -21
- package/dist/lib/components/sidebar/conversation-sidebar.component.js.map +1 -1
- package/dist/lib/components/sidebar/routines-section.component.d.ts +20 -1
- package/dist/lib/components/sidebar/routines-section.component.d.ts.map +1 -1
- package/dist/lib/components/sidebar/routines-section.component.js +25 -5
- package/dist/lib/components/sidebar/routines-section.component.js.map +1 -1
- package/dist/lib/components/slots/slot-interfaces.d.ts +19 -0
- package/dist/lib/components/slots/slot-interfaces.d.ts.map +1 -1
- package/dist/lib/components/slots/slot-interfaces.js.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.d.ts +95 -13
- package/dist/lib/components/task/tasks-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.js +223 -75
- package/dist/lib/components/task/tasks-full-view.component.js.map +1 -1
- package/dist/lib/components/tasks/task-widget.component.d.ts +46 -6
- package/dist/lib/components/tasks/task-widget.component.d.ts.map +1 -1
- package/dist/lib/components/tasks/task-widget.component.js +100 -16
- package/dist/lib/components/tasks/task-widget.component.js.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +64 -7
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +127 -27
- package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
- package/dist/lib/components/thread/thread-panel.component.d.ts +66 -8
- package/dist/lib/components/thread/thread-panel.component.d.ts.map +1 -1
- package/dist/lib/components/thread/thread-panel.component.js +146 -36
- package/dist/lib/components/thread/thread-panel.component.js.map +1 -1
- package/dist/lib/components/toast/toast.component.d.ts +11 -1
- package/dist/lib/components/toast/toast.component.d.ts.map +1 -1
- package/dist/lib/components/toast/toast.component.js +25 -5
- package/dist/lib/components/toast/toast.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +385 -42
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +891 -292
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts +8 -0
- package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts.map +1 -1
- package/dist/lib/composer-plugins/base-conversation-mention.provider.js +8 -1
- package/dist/lib/composer-plugins/base-conversation-mention.provider.js.map +1 -1
- package/dist/lib/directives/chat-slot.directive.d.ts +5 -1
- package/dist/lib/directives/chat-slot.directive.d.ts.map +1 -1
- package/dist/lib/directives/chat-slot.directive.js.map +1 -1
- package/dist/lib/directives/search-shortcut.directive.d.ts +9 -1
- package/dist/lib/directives/search-shortcut.directive.d.ts.map +1 -1
- package/dist/lib/directives/search-shortcut.directive.js +14 -4
- package/dist/lib/directives/search-shortcut.directive.js.map +1 -1
- package/dist/lib/events/chat-events.d.ts +34 -7
- package/dist/lib/events/chat-events.d.ts.map +1 -1
- package/dist/lib/events/chat-events.js +37 -7
- package/dist/lib/events/chat-events.js.map +1 -1
- package/dist/lib/models/agent-turn.model.d.ts +113 -0
- package/dist/lib/models/agent-turn.model.d.ts.map +1 -0
- package/dist/lib/models/agent-turn.model.js +12 -0
- package/dist/lib/models/agent-turn.model.js.map +1 -0
- package/dist/lib/models/collection-view.model.js.map +1 -1
- package/dist/lib/models/conversation-state.model.d.ts +8 -0
- 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/models/lazy-artifact-info.d.ts +44 -12
- package/dist/lib/models/lazy-artifact-info.d.ts.map +1 -1
- package/dist/lib/models/lazy-artifact-info.js +98 -34
- package/dist/lib/models/lazy-artifact-info.js.map +1 -1
- package/dist/lib/services/active-tasks.service.d.ts +30 -4
- package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
- package/dist/lib/services/active-tasks.service.js +71 -19
- package/dist/lib/services/active-tasks.service.js.map +1 -1
- package/dist/lib/services/agent-state.service.d.ts +17 -1
- package/dist/lib/services/agent-state.service.d.ts.map +1 -1
- package/dist/lib/services/agent-state.service.js +48 -16
- package/dist/lib/services/agent-state.service.js.map +1 -1
- package/dist/lib/services/artifact-permission.service.d.ts +39 -0
- package/dist/lib/services/artifact-permission.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-permission.service.js +152 -17
- package/dist/lib/services/artifact-permission.service.js.map +1 -1
- package/dist/lib/services/artifact-state.service.d.ts +58 -5
- package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-state.service.js +135 -35
- package/dist/lib/services/artifact-state.service.js.map +1 -1
- package/dist/lib/services/collection-permission.service.d.ts +28 -0
- package/dist/lib/services/collection-permission.service.d.ts.map +1 -1
- package/dist/lib/services/collection-permission.service.js +88 -32
- package/dist/lib/services/collection-permission.service.js.map +1 -1
- package/dist/lib/services/collection-state.service.d.ts +11 -1
- package/dist/lib/services/collection-state.service.d.ts.map +1 -1
- package/dist/lib/services/collection-state.service.js +25 -5
- package/dist/lib/services/collection-state.service.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +47 -4
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +85 -20
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-attachment.service.d.ts +17 -0
- package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-attachment.service.js +38 -10
- package/dist/lib/services/conversation-attachment.service.js.map +1 -1
- package/dist/lib/services/conversation-liveness-dom.service.d.ts +42 -0
- package/dist/lib/services/conversation-liveness-dom.service.d.ts.map +1 -0
- package/dist/lib/services/conversation-liveness-dom.service.js +74 -0
- package/dist/lib/services/conversation-liveness-dom.service.js.map +1 -0
- package/dist/lib/services/conversation-streaming.service.d.ts +22 -0
- package/dist/lib/services/conversation-streaming.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-streaming.service.js +50 -10
- package/dist/lib/services/conversation-streaming.service.js.map +1 -1
- package/dist/lib/services/data-cache.service.d.ts +31 -0
- package/dist/lib/services/data-cache.service.d.ts.map +1 -1
- package/dist/lib/services/data-cache.service.js +71 -15
- package/dist/lib/services/data-cache.service.js.map +1 -1
- package/dist/lib/services/dialog.service.d.ts +13 -0
- package/dist/lib/services/dialog.service.d.ts.map +1 -1
- package/dist/lib/services/dialog.service.js +25 -5
- package/dist/lib/services/dialog.service.js.map +1 -1
- package/dist/lib/services/export.service.d.ts +2 -0
- package/dist/lib/services/export.service.d.ts.map +1 -1
- package/dist/lib/services/export.service.js +5 -1
- package/dist/lib/services/export.service.js.map +1 -1
- package/dist/lib/services/mention-parser.service.d.ts +10 -0
- package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
- package/dist/lib/services/mention-parser.service.js +25 -5
- package/dist/lib/services/mention-parser.service.js.map +1 -1
- package/dist/lib/services/notification.service.d.ts +54 -6
- package/dist/lib/services/notification.service.d.ts.map +1 -1
- package/dist/lib/services/notification.service.js +123 -27
- package/dist/lib/services/notification.service.js.map +1 -1
- package/dist/lib/services/realtime-audio-recorder.d.ts +4 -4
- package/dist/lib/services/realtime-audio-recorder.js +12 -12
- package/dist/lib/services/realtime-audio-recorder.js.map +1 -1
- package/dist/lib/services/realtime-pcm-wav.d.ts +4 -0
- package/dist/lib/services/realtime-pcm-wav.d.ts.map +1 -1
- package/dist/lib/services/realtime-pcm-wav.js +10 -2
- package/dist/lib/services/realtime-pcm-wav.js.map +1 -1
- package/dist/lib/services/search.service.d.ts +42 -9
- package/dist/lib/services/search.service.d.ts.map +1 -1
- package/dist/lib/services/search.service.js +103 -23
- package/dist/lib/services/search.service.js.map +1 -1
- package/dist/lib/services/toast.service.d.ts +19 -1
- package/dist/lib/services/toast.service.d.ts.map +1 -1
- package/dist/lib/services/toast.service.js +45 -9
- package/dist/lib/services/toast.service.js.map +1 -1
- package/dist/lib/services/ui-command-handler.service.d.ts +56 -5
- package/dist/lib/services/ui-command-handler.service.d.ts.map +1 -1
- package/dist/lib/services/ui-command-handler.service.js +113 -16
- package/dist/lib/services/ui-command-handler.service.js.map +1 -1
- package/dist/lib/utils/agent-artifact-summary.d.ts +2 -2
- package/dist/lib/utils/agent-artifact-summary.js +3 -3
- package/dist/lib/utils/agent-artifact-summary.js.map +1 -1
- package/dist/lib/utils/agent-turn-routing.d.ts +70 -0
- package/dist/lib/utils/agent-turn-routing.d.ts.map +1 -0
- package/dist/lib/utils/agent-turn-routing.js +84 -0
- package/dist/lib/utils/agent-turn-routing.js.map +1 -0
- package/dist/lib/utils/artifact-panel-action.d.ts +15 -4
- package/dist/lib/utils/artifact-panel-action.d.ts.map +1 -1
- package/dist/lib/utils/artifact-panel-action.js +10 -2
- package/dist/lib/utils/artifact-panel-action.js.map +1 -1
- package/dist/lib/utils/decision-routing.d.ts +68 -0
- package/dist/lib/utils/decision-routing.d.ts.map +1 -0
- package/dist/lib/utils/decision-routing.js +101 -0
- package/dist/lib/utils/decision-routing.js.map +1 -0
- package/dist/lib/utils/distinct-artifacts.d.ts +2 -0
- package/dist/lib/utils/distinct-artifacts.d.ts.map +1 -1
- package/dist/lib/utils/distinct-artifacts.js +5 -1
- package/dist/lib/utils/distinct-artifacts.js.map +1 -1
- package/dist/lib/utils/plan-mode-preference.d.ts +2 -2
- package/dist/lib/utils/plan-mode-preference.js +6 -6
- package/dist/lib/utils/plan-mode-preference.js.map +1 -1
- package/dist/public-api.d.ts +5 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +8 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +32 -32
|
@@ -15,15 +15,15 @@ export interface ArtifactVersionRef {
|
|
|
15
15
|
*/
|
|
16
16
|
export interface ArtifactPanelBaseline {
|
|
17
17
|
/** artifactId → highest version, from {@link snapshotArtifactVersions}. */
|
|
18
|
-
|
|
18
|
+
Versions: Map<string, number>;
|
|
19
19
|
/** The conversation on screen when the snapshot was taken. */
|
|
20
20
|
conversationId: string | null;
|
|
21
21
|
/** The conversation whose artifacts the map was actually holding, or null if none had loaded. */
|
|
22
|
-
|
|
22
|
+
MapConversationId: string | null;
|
|
23
23
|
/** Paging-merge counter at snapshot time. */
|
|
24
|
-
|
|
24
|
+
MapGeneration: number;
|
|
25
25
|
/** User-selection counter at snapshot time. */
|
|
26
|
-
|
|
26
|
+
SelectionEpoch: number;
|
|
27
27
|
}
|
|
28
28
|
export type ArtifactPanelAction = {
|
|
29
29
|
kind: 'none';
|
|
@@ -42,6 +42,8 @@ export type ArtifactPanelAction = {
|
|
|
42
42
|
* Keys are NORMALIZED UUIDs, so lookups are case-insensitive by construction (SQL Server returns
|
|
43
43
|
* upper case, PostgreSQL lower) at O(1) rather than by scanning every key for a `UUIDsEqual` hit.
|
|
44
44
|
*/
|
|
45
|
+
export declare function SnapshotArtifactVersions(refs: Iterable<ArtifactVersionRef>): Map<string, number>;
|
|
46
|
+
/** @deprecated Use {@link SnapshotArtifactVersions}. */
|
|
45
47
|
export declare function snapshotArtifactVersions(refs: Iterable<ArtifactVersionRef>): Map<string, number>;
|
|
46
48
|
/**
|
|
47
49
|
* Decide what the artifact panel should do after an agent run, from a before/after diff of
|
|
@@ -78,6 +80,15 @@ export declare function snapshotArtifactVersions(refs: Iterable<ArtifactVersionR
|
|
|
78
80
|
* @param input.userChangedSelection - Defaults to false. True when the user picked or closed an
|
|
79
81
|
* artifact while the turn was in flight; the panel is then left where they put it.
|
|
80
82
|
*/
|
|
83
|
+
export declare function DecideArtifactPanelAction(input: {
|
|
84
|
+
panelOpen: boolean;
|
|
85
|
+
selectedArtifactId: string | null;
|
|
86
|
+
before: Map<string, number>;
|
|
87
|
+
after: ArtifactVersionRef[];
|
|
88
|
+
baselineComparable?: boolean;
|
|
89
|
+
userChangedSelection?: boolean;
|
|
90
|
+
}): ArtifactPanelAction;
|
|
91
|
+
/** @deprecated Use {@link DecideArtifactPanelAction}. */
|
|
81
92
|
export declare function decideArtifactPanelAction(input: {
|
|
82
93
|
panelOpen: boolean;
|
|
83
94
|
selectedArtifactId: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-panel-action.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/artifact-panel-action.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,8DAA8D;IAC9D,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iGAAiG;IACjG,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,6CAA6C;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAcnE;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOhG;AA+BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,GAAG,mBAAmB,CAgDtB"}
|
|
1
|
+
{"version":3,"file":"artifact-panel-action.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/artifact-panel-action.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,8DAA8D;IAC9D,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iGAAiG;IACjG,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,6CAA6C;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAcnE;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOhG;AAED,wDAAwD;AACxD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAEhG;AA+BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,GAAG,mBAAmB,CAgDtB;AAED,yDAAyD;AACzD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,GAAG,mBAAmB,CAEtB"}
|
|
@@ -5,7 +5,7 @@ import { NormalizeUUID, UUIDsEqual } from '@memberjunction/global';
|
|
|
5
5
|
* Keys are NORMALIZED UUIDs, so lookups are case-insensitive by construction (SQL Server returns
|
|
6
6
|
* upper case, PostgreSQL lower) at O(1) rather than by scanning every key for a `UUIDsEqual` hit.
|
|
7
7
|
*/
|
|
8
|
-
export function
|
|
8
|
+
export function SnapshotArtifactVersions(refs) {
|
|
9
9
|
const latest = new Map();
|
|
10
10
|
for (const ref of refs) {
|
|
11
11
|
const key = NormalizeUUID(ref.artifactId);
|
|
@@ -13,6 +13,10 @@ export function snapshotArtifactVersions(refs) {
|
|
|
13
13
|
}
|
|
14
14
|
return latest;
|
|
15
15
|
}
|
|
16
|
+
/** @deprecated Use {@link SnapshotArtifactVersions}. */
|
|
17
|
+
export function snapshotArtifactVersions(refs) {
|
|
18
|
+
return SnapshotArtifactVersions(refs);
|
|
19
|
+
}
|
|
16
20
|
/** Same reduction as {@link snapshotArtifactVersions}, keeping the timestamp for ordering. */
|
|
17
21
|
function latestByArtifact(refs) {
|
|
18
22
|
const latest = new Map();
|
|
@@ -74,7 +78,7 @@ function bestCandidate(entries) {
|
|
|
74
78
|
* @param input.userChangedSelection - Defaults to false. True when the user picked or closed an
|
|
75
79
|
* artifact while the turn was in flight; the panel is then left where they put it.
|
|
76
80
|
*/
|
|
77
|
-
export function
|
|
81
|
+
export function DecideArtifactPanelAction(input) {
|
|
78
82
|
const after = latestByArtifact(input.after);
|
|
79
83
|
const entries = [...after.entries()];
|
|
80
84
|
const baselineComparable = input.baselineComparable !== false;
|
|
@@ -119,4 +123,8 @@ export function decideArtifactPanelAction(input) {
|
|
|
119
123
|
const latest = bestCandidate(bumped);
|
|
120
124
|
return { kind: 'open', artifactId: latest.artifactId, versionNumber: latest.versionNumber };
|
|
121
125
|
}
|
|
126
|
+
/** @deprecated Use {@link DecideArtifactPanelAction}. */
|
|
127
|
+
export function decideArtifactPanelAction(input) {
|
|
128
|
+
return DecideArtifactPanelAction(input);
|
|
129
|
+
}
|
|
122
130
|
//# sourceMappingURL=artifact-panel-action.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-panel-action.js","sourceRoot":"","sources":["../../../src/lib/utils/artifact-panel-action.ts"],"names":[],"mappings":"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","sourcesContent":["import { NormalizeUUID, UUIDsEqual } from '@memberjunction/global';\n\nexport interface ArtifactVersionRef {\n artifactId: string;\n versionNumber: number;\n /**\n * When that version row was created. Used ONLY to order candidates against each other, never\n * compared against the client clock — the values come from one database, so their relative\n * order is meaningful even though the absolute offset from the browser's clock is not.\n */\n versionCreatedAt?: Date | null;\n}\n\n/**\n * What the chat area records before a turn so it can later tell whether the artifact population\n * changed BECAUSE of that turn. See `snapshotArtifactPanelBaseline` in the chat area for why the\n * version map on its own is not a sufficient baseline.\n */\nexport interface ArtifactPanelBaseline {\n /** artifactId → highest version, from {@link snapshotArtifactVersions}. */\n versions: Map<string, number>;\n /** The conversation on screen when the snapshot was taken. */\n conversationId: string | null;\n /** The conversation whose artifacts the map was actually holding, or null if none had loaded. */\n mapConversationId: string | null;\n /** Paging-merge counter at snapshot time. */\n mapGeneration: number;\n /** User-selection counter at snapshot time. */\n selectionEpoch: number;\n}\n\nexport type ArtifactPanelAction =\n | { kind: 'none' }\n | { kind: 'open'; artifactId: string; versionNumber: number }\n | { kind: 'refresh'; artifactId: string; versionNumber: number };\n\n/** The highest version seen for one artifact, and when it landed. */\ninterface LatestVersion {\n /**\n * The id AS IT APPEARED in the input, not the normalized lookup key. Ids are matched\n * case-insensitively but handed back untouched, so nothing downstream sees an id in a different\n * case than the row it came from.\n */\n artifactId: string;\n versionNumber: number;\n versionCreatedAt?: Date | null;\n}\n\n/**\n * artifactId → highest version number seen.\n *\n * Keys are NORMALIZED UUIDs, so lookups are case-insensitive by construction (SQL Server returns\n * upper case, PostgreSQL lower) at O(1) rather than by scanning every key for a `UUIDsEqual` hit.\n */\nexport function snapshotArtifactVersions(refs: Iterable<ArtifactVersionRef>): Map<string, number> {\n const latest = new Map<string, number>();\n for (const ref of refs) {\n const key = NormalizeUUID(ref.artifactId);\n latest.set(key, Math.max(latest.get(key) ?? 0, ref.versionNumber));\n }\n return latest;\n}\n\n/** Same reduction as {@link snapshotArtifactVersions}, keeping the timestamp for ordering. */\nfunction latestByArtifact(refs: Iterable<ArtifactVersionRef>): Map<string, LatestVersion> {\n const latest = new Map<string, LatestVersion>();\n for (const ref of refs) {\n const key = NormalizeUUID(ref.artifactId);\n const existing = latest.get(key);\n if (!existing || ref.versionNumber > existing.versionNumber) {\n latest.set(key, { artifactId: ref.artifactId, versionNumber: ref.versionNumber, versionCreatedAt: ref.versionCreatedAt });\n }\n }\n return latest;\n}\n\n/** Newest first, with an absent timestamp sorting last so a real date always wins. */\nfunction newestFirst(a: [string, LatestVersion], b: [string, LatestVersion]): number {\n const at = a[1].versionCreatedAt ? new Date(a[1].versionCreatedAt).getTime() : Number.NEGATIVE_INFINITY;\n const bt = b[1].versionCreatedAt ? new Date(b[1].versionCreatedAt).getTime() : Number.NEGATIVE_INFINITY;\n return bt - at;\n}\n\n/**\n * The best candidate among several: newest version wins, and ties break toward the one seen LAST,\n * which is what the previous \"take the final map entry\" rule did. `sort` is stable, so reversing\n * first is what makes equal timestamps resolve that way rather than the opposite.\n */\nfunction bestCandidate(entries: Array<[string, LatestVersion]>): LatestVersion {\n return [...entries].reverse().sort(newestFirst)[0][1];\n}\n\n/**\n * Decide what the artifact panel should do after an agent run, from a before/after diff of\n * artifact versions across the whole conversation:\n * - a NEW artifact opens, whether or not the panel is open (a `build` in a conversation that\n * already had a component — #529);\n * - a bumped version of the SHOWN artifact refreshes it;\n * - a bumped version of ANOTHER existing artifact switches the panel to it (retargeting);\n * - a version bump with the panel closed does nothing (historical behavior).\n *\n * A creation always wins over a bump: when one run both creates an artifact and versions the shown\n * one, the new artifact opens, because a `build` must surface rather than stay hidden behind it.\n *\n * ## Why \"absent from `before`\" is not on its own enough\n *\n * `before` and `after` are snapshots of a map the component rebuilds for other reasons entirely,\n * so an artifact can enter it without anything having been created: switching conversations leaves\n * the previous conversation's artifacts in place until the rebuild lands, and paging up merges in\n * artifacts from older messages mid-turn. Either way every arriving artifact is absent from\n * `before`, and a set difference alone would open a months-old artifact and claim a run had just\n * built it — while ALSO short-circuiting the refresh of the artifact actually on screen, because a\n * creation outranks a bump. `baselineComparable` is how the caller reports that the two snapshots\n * describe the same population; when it is false, creations are not inferred at all and only the\n * shown artifact's own bump (an inference that needs no baseline, since it is corroborated by the\n * id being present in both snapshots) is acted on.\n *\n * @param input.panelOpen - Whether the artifact panel is currently open.\n * @param input.selectedArtifactId - The artifact currently displayed, if any.\n * @param input.before - Snapshot taken before the turn, from {@link snapshotArtifactVersions}.\n * @param input.after - Every artifact version known now.\n * @param input.baselineComparable - Defaults to true. False when `before` cannot be compared with\n * `after` (the map was holding another conversation's artifacts, or a page of older messages\n * merged in while the turn was in flight).\n * @param input.userChangedSelection - Defaults to false. True when the user picked or closed an\n * artifact while the turn was in flight; the panel is then left where they put it.\n */\nexport function decideArtifactPanelAction(input: {\n panelOpen: boolean;\n selectedArtifactId: string | null;\n before: Map<string, number>;\n after: ArtifactVersionRef[];\n baselineComparable?: boolean;\n userChangedSelection?: boolean;\n}): ArtifactPanelAction {\n const after = latestByArtifact(input.after);\n const entries = [...after.entries()];\n const baselineComparable = input.baselineComparable !== false;\n const userChangedSelection = input.userChangedSelection === true;\n\n // A bump is \"this id was in both snapshots and its version went up\" — self-corroborating, so it\n // survives an untrustworthy baseline.\n const bumped = entries.filter(([id, latest]) => {\n const previous = input.before.get(id);\n return previous !== undefined && latest.versionNumber > previous;\n });\n const shown = bumped.find(([, latest]) => UUIDsEqual(latest.artifactId, input.selectedArtifactId));\n\n // The user's own choice outranks the run's: refresh what they are looking at if it moved, but\n // never pull the panel onto something else underneath them.\n //\n // Only while the panel is OPEN, though. A closed panel is displacing nothing, so a run that\n // genuinely built something still surfaces it — suppressing that would break the very case this\n // feature exists for, and a user who closed the panel mid-run has expressed no preference about\n // an artifact that did not exist yet.\n if (userChangedSelection && input.panelOpen) {\n if (shown) {\n return { kind: 'refresh', artifactId: shown[1].artifactId, versionNumber: shown[1].versionNumber };\n }\n return { kind: 'none' };\n }\n\n if (baselineComparable) {\n const created = entries.filter(([id]) => !input.before.has(id));\n if (created.length > 0) {\n // Newest version wins. The previous \"last entry\" rule inherited map insertion order, which\n // is the order the component happened to iterate conversation details in — not recency.\n const latest = bestCandidate(created);\n return { kind: 'open', artifactId: latest.artifactId, versionNumber: latest.versionNumber };\n }\n }\n\n if (bumped.length === 0 || !input.panelOpen) return { kind: 'none' };\n\n if (shown) return { kind: 'refresh', artifactId: shown[1].artifactId, versionNumber: shown[1].versionNumber };\n\n // Retargeting: the run versioned some other artifact in this conversation. Only meaningful when\n // the two snapshots describe the same population.\n if (!baselineComparable) return { kind: 'none' };\n\n const latest = bestCandidate(bumped);\n return { kind: 'open', artifactId: latest.artifactId, versionNumber: latest.versionNumber };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"artifact-panel-action.js","sourceRoot":"","sources":["../../../src/lib/utils/artifact-panel-action.ts"],"names":[],"mappings":"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","sourcesContent":["import { NormalizeUUID, UUIDsEqual } from '@memberjunction/global';\n\nexport interface ArtifactVersionRef {\n artifactId: string; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n versionNumber: number; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n /**\n * When that version row was created. Used ONLY to order candidates against each other, never\n * compared against the client clock — the values come from one database, so their relative\n * order is meaningful even though the absolute offset from the browser's clock is not.\n */\n versionCreatedAt?: Date | null; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined\n}\n\n/**\n * What the chat area records before a turn so it can later tell whether the artifact population\n * changed BECAUSE of that turn. See `snapshotArtifactPanelBaseline` in the chat area for why the\n * version map on its own is not a sufficient baseline.\n */\nexport interface ArtifactPanelBaseline {\n /** artifactId → highest version, from {@link snapshotArtifactVersions}. */\n Versions: Map<string, number>;\n /** The conversation on screen when the snapshot was taken. */\n conversationId: string | null; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n /** The conversation whose artifacts the map was actually holding, or null if none had loaded. */\n MapConversationId: string | null;\n /** Paging-merge counter at snapshot time. */\n MapGeneration: number;\n /** User-selection counter at snapshot time. */\n SelectionEpoch: number;\n}\n\nexport type ArtifactPanelAction =\n | { kind: 'none' } // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n | { kind: 'open'; artifactId: string; versionNumber: number } // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n | { kind: 'refresh'; artifactId: string; versionNumber: number }; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n\n/** The highest version seen for one artifact, and when it landed. */\ninterface LatestVersion {\n /**\n * The id AS IT APPEARED in the input, not the normalized lookup key. Ids are matched\n * case-insensitively but handed back untouched, so nothing downstream sees an id in a different\n * case than the row it came from.\n */\n artifactId: string;\n versionNumber: number;\n versionCreatedAt?: Date | null;\n}\n\n/**\n * artifactId → highest version number seen.\n *\n * Keys are NORMALIZED UUIDs, so lookups are case-insensitive by construction (SQL Server returns\n * upper case, PostgreSQL lower) at O(1) rather than by scanning every key for a `UUIDsEqual` hit.\n */\nexport function SnapshotArtifactVersions(refs: Iterable<ArtifactVersionRef>): Map<string, number> {\n const latest = new Map<string, number>();\n for (const ref of refs) {\n const key = NormalizeUUID(ref.artifactId);\n latest.set(key, Math.max(latest.get(key) ?? 0, ref.versionNumber));\n }\n return latest;\n}\n\n/** @deprecated Use {@link SnapshotArtifactVersions}. */\nexport function snapshotArtifactVersions(refs: Iterable<ArtifactVersionRef>): Map<string, number> {\n return SnapshotArtifactVersions(refs);\n}\n\n/** Same reduction as {@link snapshotArtifactVersions}, keeping the timestamp for ordering. */\nfunction latestByArtifact(refs: Iterable<ArtifactVersionRef>): Map<string, LatestVersion> {\n const latest = new Map<string, LatestVersion>();\n for (const ref of refs) {\n const key = NormalizeUUID(ref.artifactId);\n const existing = latest.get(key);\n if (!existing || ref.versionNumber > existing.versionNumber) {\n latest.set(key, { artifactId: ref.artifactId, versionNumber: ref.versionNumber, versionCreatedAt: ref.versionCreatedAt });\n }\n }\n return latest;\n}\n\n/** Newest first, with an absent timestamp sorting last so a real date always wins. */\nfunction newestFirst(a: [string, LatestVersion], b: [string, LatestVersion]): number {\n const at = a[1].versionCreatedAt ? new Date(a[1].versionCreatedAt).getTime() : Number.NEGATIVE_INFINITY;\n const bt = b[1].versionCreatedAt ? new Date(b[1].versionCreatedAt).getTime() : Number.NEGATIVE_INFINITY;\n return bt - at;\n}\n\n/**\n * The best candidate among several: newest version wins, and ties break toward the one seen LAST,\n * which is what the previous \"take the final map entry\" rule did. `sort` is stable, so reversing\n * first is what makes equal timestamps resolve that way rather than the opposite.\n */\nfunction bestCandidate(entries: Array<[string, LatestVersion]>): LatestVersion {\n return [...entries].reverse().sort(newestFirst)[0][1];\n}\n\n/**\n * Decide what the artifact panel should do after an agent run, from a before/after diff of\n * artifact versions across the whole conversation:\n * - a NEW artifact opens, whether or not the panel is open (a `build` in a conversation that\n * already had a component — #529);\n * - a bumped version of the SHOWN artifact refreshes it;\n * - a bumped version of ANOTHER existing artifact switches the panel to it (retargeting);\n * - a version bump with the panel closed does nothing (historical behavior).\n *\n * A creation always wins over a bump: when one run both creates an artifact and versions the shown\n * one, the new artifact opens, because a `build` must surface rather than stay hidden behind it.\n *\n * ## Why \"absent from `before`\" is not on its own enough\n *\n * `before` and `after` are snapshots of a map the component rebuilds for other reasons entirely,\n * so an artifact can enter it without anything having been created: switching conversations leaves\n * the previous conversation's artifacts in place until the rebuild lands, and paging up merges in\n * artifacts from older messages mid-turn. Either way every arriving artifact is absent from\n * `before`, and a set difference alone would open a months-old artifact and claim a run had just\n * built it — while ALSO short-circuiting the refresh of the artifact actually on screen, because a\n * creation outranks a bump. `baselineComparable` is how the caller reports that the two snapshots\n * describe the same population; when it is false, creations are not inferred at all and only the\n * shown artifact's own bump (an inference that needs no baseline, since it is corroborated by the\n * id being present in both snapshots) is acted on.\n *\n * @param input.panelOpen - Whether the artifact panel is currently open.\n * @param input.selectedArtifactId - The artifact currently displayed, if any.\n * @param input.before - Snapshot taken before the turn, from {@link snapshotArtifactVersions}.\n * @param input.after - Every artifact version known now.\n * @param input.baselineComparable - Defaults to true. False when `before` cannot be compared with\n * `after` (the map was holding another conversation's artifacts, or a page of older messages\n * merged in while the turn was in flight).\n * @param input.userChangedSelection - Defaults to false. True when the user picked or closed an\n * artifact while the turn was in flight; the panel is then left where they put it.\n */\nexport function DecideArtifactPanelAction(input: {\n panelOpen: boolean;\n selectedArtifactId: string | null;\n before: Map<string, number>;\n after: ArtifactVersionRef[];\n baselineComparable?: boolean;\n userChangedSelection?: boolean;\n}): ArtifactPanelAction {\n const after = latestByArtifact(input.after);\n const entries = [...after.entries()];\n const baselineComparable = input.baselineComparable !== false;\n const userChangedSelection = input.userChangedSelection === true;\n\n // A bump is \"this id was in both snapshots and its version went up\" — self-corroborating, so it\n // survives an untrustworthy baseline.\n const bumped = entries.filter(([id, latest]) => {\n const previous = input.before.get(id);\n return previous !== undefined && latest.versionNumber > previous;\n });\n const shown = bumped.find(([, latest]) => UUIDsEqual(latest.artifactId, input.selectedArtifactId));\n\n // The user's own choice outranks the run's: refresh what they are looking at if it moved, but\n // never pull the panel onto something else underneath them.\n //\n // Only while the panel is OPEN, though. A closed panel is displacing nothing, so a run that\n // genuinely built something still surfaces it — suppressing that would break the very case this\n // feature exists for, and a user who closed the panel mid-run has expressed no preference about\n // an artifact that did not exist yet.\n if (userChangedSelection && input.panelOpen) {\n if (shown) {\n return { kind: 'refresh', artifactId: shown[1].artifactId, versionNumber: shown[1].versionNumber };\n }\n return { kind: 'none' };\n }\n\n if (baselineComparable) {\n const created = entries.filter(([id]) => !input.before.has(id));\n if (created.length > 0) {\n // Newest version wins. The previous \"last entry\" rule inherited map insertion order, which\n // is the order the component happened to iterate conversation details in — not recency.\n const latest = bestCandidate(created);\n return { kind: 'open', artifactId: latest.artifactId, versionNumber: latest.versionNumber };\n }\n }\n\n if (bumped.length === 0 || !input.panelOpen) return { kind: 'none' };\n\n if (shown) return { kind: 'refresh', artifactId: shown[1].artifactId, versionNumber: shown[1].versionNumber };\n\n // Retargeting: the run versioned some other artifact in this conversation. Only meaningful when\n // the two snapshots describe the same population.\n if (!baselineComparable) return { kind: 'none' };\n\n const latest = bestCandidate(bumped);\n return { kind: 'open', artifactId: latest.artifactId, versionNumber: latest.versionNumber };\n}\n\n/** @deprecated Use {@link DecideArtifactPanelAction}. */\nexport function decideArtifactPanelAction(input: {\n panelOpen: boolean;\n selectedArtifactId: string | null;\n before: Map<string, number>;\n after: ArtifactVersionRef[];\n baselineComparable?: boolean;\n userChangedSelection?: boolean;\n}): ArtifactPanelAction {\n return DecideArtifactPanelAction(input);\n}\n"]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Decision routing for an unmentioned message (plan Tasks 3.9 and 3.2): one typed
|
|
3
|
+
* decision that may send the message to a different agent in the conversation than the last one
|
|
4
|
+
* that answered, and may name the artifact version the message modifies.
|
|
5
|
+
*
|
|
6
|
+
* It runs before {@link ResolveAgentTurn}, which stays pure. When the answer is confident, the
|
|
7
|
+
* caller replaces the continuity candidate with {@link ApplyRoutingDecision}; otherwise nothing
|
|
8
|
+
* changes. Every failure keeps today's routing. The chat turns it on with `EnableDecisionRouting`,
|
|
9
|
+
* which is off by default.
|
|
10
|
+
*
|
|
11
|
+
* The decision itself (its input, questions and state, and how its answers are read) is built in
|
|
12
|
+
* `@memberjunction/ai-core-plus` (`conversation-routing-decision.ts`), so the Decision Eval harness
|
|
13
|
+
* measures exactly what the chat sends. What stays here is the call and what the chat does with
|
|
14
|
+
* the outcome. Import the builders and their types from `@memberjunction/ai-core-plus` directly.
|
|
15
|
+
*
|
|
16
|
+
* Kept free of Angular so the whole path, with the decision call mocked, is testable directly;
|
|
17
|
+
* `MessageInputComponent` supplies the conversation and the call.
|
|
18
|
+
*
|
|
19
|
+
* @module @memberjunction/ng-conversations
|
|
20
|
+
*/
|
|
21
|
+
import { type RoutingDecisionInput, type RoutingDecisionOutcome } from '@memberjunction/ai-core-plus';
|
|
22
|
+
import type { RunDecisionParams, RunDecisionResult } from '@memberjunction/graphql-dataprovider';
|
|
23
|
+
import type { AgentReplyMode } from '../models/agent-turn.model';
|
|
24
|
+
import type { AgentTurnCandidates } from './agent-turn-routing';
|
|
25
|
+
/** Runs a decision on the server: `ConversationAgentService.RunDecision` in the chat. */
|
|
26
|
+
export type RoutingDecisionRunner = (params: RunDecisionParams) => Promise<RunDecisionResult>;
|
|
27
|
+
/** What decides whether a message gets a routing decision at all. */
|
|
28
|
+
export interface RoutingDecisionGate {
|
|
29
|
+
/** The chat's `EnableDecisionRouting` input. */
|
|
30
|
+
Enabled: boolean;
|
|
31
|
+
/** The chat's reply mode. */
|
|
32
|
+
ReplyMode: AgentReplyMode;
|
|
33
|
+
/** Agents the message tags. */
|
|
34
|
+
MentionedAgentIds: readonly string[];
|
|
35
|
+
/** The message, as saved. */
|
|
36
|
+
Message: string;
|
|
37
|
+
/** The last agent that answered, other than the conversation manager. */
|
|
38
|
+
ContinuityAgentId: string | null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* True when a message should get a routing decision: routing is on, the reply mode is `Always`,
|
|
42
|
+
* some agent has answered before, and the message tags no agent and is not a form response. A
|
|
43
|
+
* form response always goes back to the agent that asked for it. Every other message keeps
|
|
44
|
+
* today's routing, with no call.
|
|
45
|
+
*/
|
|
46
|
+
export declare function ShouldRunRoutingDecision(gate: RoutingDecisionGate): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Asks one routing decision and reads its answer. It fails toward continuity: an error, no answer
|
|
49
|
+
* within `timeoutMs` (the call is abandoned), or an unsure answer keeps today's routing. Never
|
|
50
|
+
* throws.
|
|
51
|
+
*
|
|
52
|
+
* @param input What to decide. Check it with `CanAskRoutingDecision` first.
|
|
53
|
+
* @param runDecision Runs the decision on the server.
|
|
54
|
+
* @param timeoutMs How long to wait. Defaults to `DECISION_ROUTING_TIMEOUT_MS`.
|
|
55
|
+
*/
|
|
56
|
+
export declare function RunRoutingDecision(input: RoutingDecisionInput, runDecision: RoutingDecisionRunner, timeoutMs?: number): Promise<RoutingDecisionOutcome>;
|
|
57
|
+
/**
|
|
58
|
+
* The candidates with the decision applied: a routed agent replaces continuity and is labelled
|
|
59
|
+
* `DecisionRouted`, and "someone else" clears continuity. Any other outcome, or none, leaves the
|
|
60
|
+
* candidates as they are.
|
|
61
|
+
*/
|
|
62
|
+
export declare function ApplyRoutingDecision(candidates: AgentTurnCandidates, outcome: RoutingDecisionOutcome | null): AgentTurnCandidates;
|
|
63
|
+
/**
|
|
64
|
+
* The artifact version to hand a turn's agent: the decision's target, when it is one of that
|
|
65
|
+
* agent's versions. Null otherwise, including after a redirect to another agent.
|
|
66
|
+
*/
|
|
67
|
+
export declare function ArtifactVersionForTurn(outcome: RoutingDecisionOutcome | null, agentId: string): string | null;
|
|
68
|
+
//# sourceMappingURL=decision-routing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-routing.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/decision-routing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAOH,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC9B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEjG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,yFAAyF;AACzF,MAAM,MAAM,qBAAqB,GAAG,CAAC,MAAM,EAAE,iBAAiB,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE9F,qEAAqE;AACrE,MAAM,WAAW,mBAAmB;IAChC,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,6BAA6B;IAC7B,SAAS,EAAE,cAAc,CAAC;IAC1B,+BAA+B;IAC/B,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAM3E;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACpC,KAAK,EAAE,oBAAoB,EAC3B,WAAW,EAAE,qBAAqB,EAClC,SAAS,GAAE,MAAoC,GAChD,OAAO,CAAC,sBAAsB,CAAC,CAUjC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAChC,UAAU,EAAE,mBAAmB,EAC/B,OAAO,EAAE,sBAAsB,GAAG,IAAI,GACvC,mBAAmB,CAQrB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG7G"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Decision routing for an unmentioned message (plan Tasks 3.9 and 3.2): one typed
|
|
3
|
+
* decision that may send the message to a different agent in the conversation than the last one
|
|
4
|
+
* that answered, and may name the artifact version the message modifies.
|
|
5
|
+
*
|
|
6
|
+
* It runs before {@link ResolveAgentTurn}, which stays pure. When the answer is confident, the
|
|
7
|
+
* caller replaces the continuity candidate with {@link ApplyRoutingDecision}; otherwise nothing
|
|
8
|
+
* changes. Every failure keeps today's routing. The chat turns it on with `EnableDecisionRouting`,
|
|
9
|
+
* which is off by default.
|
|
10
|
+
*
|
|
11
|
+
* The decision itself (its input, questions and state, and how its answers are read) is built in
|
|
12
|
+
* `@memberjunction/ai-core-plus` (`conversation-routing-decision.ts`), so the Decision Eval harness
|
|
13
|
+
* measures exactly what the chat sends. What stays here is the call and what the chat does with
|
|
14
|
+
* the outcome. Import the builders and their types from `@memberjunction/ai-core-plus` directly.
|
|
15
|
+
*
|
|
16
|
+
* Kept free of Angular so the whole path, with the decision call mocked, is testable directly;
|
|
17
|
+
* `MessageInputComponent` supplies the conversation and the call.
|
|
18
|
+
*
|
|
19
|
+
* @module @memberjunction/ng-conversations
|
|
20
|
+
*/
|
|
21
|
+
import { BuildRoutingQuestions, BuildRoutingState, ConversationUtility, DECISION_ROUTING_TIMEOUT_MS, InterpretRoutingAnswers, KeptContinuityOutcome } from '@memberjunction/ai-core-plus';
|
|
22
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
23
|
+
/**
|
|
24
|
+
* True when a message should get a routing decision: routing is on, the reply mode is `Always`,
|
|
25
|
+
* some agent has answered before, and the message tags no agent and is not a form response. A
|
|
26
|
+
* form response always goes back to the agent that asked for it. Every other message keeps
|
|
27
|
+
* today's routing, with no call.
|
|
28
|
+
*/
|
|
29
|
+
export function ShouldRunRoutingDecision(gate) {
|
|
30
|
+
return gate.Enabled
|
|
31
|
+
&& gate.ReplyMode === 'Always'
|
|
32
|
+
&& !!gate.ContinuityAgentId
|
|
33
|
+
&& gate.MentionedAgentIds.length === 0
|
|
34
|
+
&& !ConversationUtility.ContainsFormResponse(gate.Message);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Asks one routing decision and reads its answer. It fails toward continuity: an error, no answer
|
|
38
|
+
* within `timeoutMs` (the call is abandoned), or an unsure answer keeps today's routing. Never
|
|
39
|
+
* throws.
|
|
40
|
+
*
|
|
41
|
+
* @param input What to decide. Check it with `CanAskRoutingDecision` first.
|
|
42
|
+
* @param runDecision Runs the decision on the server.
|
|
43
|
+
* @param timeoutMs How long to wait. Defaults to `DECISION_ROUTING_TIMEOUT_MS`.
|
|
44
|
+
*/
|
|
45
|
+
export async function RunRoutingDecision(input, runDecision, timeoutMs = DECISION_ROUTING_TIMEOUT_MS) {
|
|
46
|
+
const params = {
|
|
47
|
+
State: BuildRoutingState(input),
|
|
48
|
+
Questions: BuildRoutingQuestions(input),
|
|
49
|
+
TimeoutMS: timeoutMs
|
|
50
|
+
};
|
|
51
|
+
const result = await runWithDeadline(() => runDecision(params), timeoutMs);
|
|
52
|
+
return result
|
|
53
|
+
? InterpretRoutingAnswers(input, result)
|
|
54
|
+
: KeptContinuityOutcome(`no answer within ${timeoutMs} ms`);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The candidates with the decision applied: a routed agent replaces continuity and is labelled
|
|
58
|
+
* `DecisionRouted`, and "someone else" clears continuity. Any other outcome, or none, leaves the
|
|
59
|
+
* candidates as they are.
|
|
60
|
+
*/
|
|
61
|
+
export function ApplyRoutingDecision(candidates, outcome) {
|
|
62
|
+
if (outcome?.Verdict === 'Routed' && outcome.RoutedAgentId) {
|
|
63
|
+
return { ...candidates, ContinuityAgentId: outcome.RoutedAgentId, ContinuityDecisionRouted: true };
|
|
64
|
+
}
|
|
65
|
+
if (outcome?.Verdict === 'SomeoneElse') {
|
|
66
|
+
return { ...candidates, ContinuityAgentId: null };
|
|
67
|
+
}
|
|
68
|
+
return candidates;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The artifact version to hand a turn's agent: the decision's target, when it is one of that
|
|
72
|
+
* agent's versions. Null otherwise, including after a redirect to another agent.
|
|
73
|
+
*/
|
|
74
|
+
export function ArtifactVersionForTurn(outcome, agentId) {
|
|
75
|
+
const target = outcome?.TargetArtifact;
|
|
76
|
+
return target && UUIDsEqual(target.AgentId, agentId) ? target.ArtifactVersionId : null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Runs the call, or gives up on it after `timeoutMs`. Resolves with the result, a failed result
|
|
80
|
+
* when the call throws, or null when it didn't answer in time. A late answer is ignored.
|
|
81
|
+
*/
|
|
82
|
+
async function runWithDeadline(call, timeoutMs) {
|
|
83
|
+
let timer;
|
|
84
|
+
const deadline = new Promise(resolve => {
|
|
85
|
+
timer = setTimeout(() => resolve(null), timeoutMs);
|
|
86
|
+
});
|
|
87
|
+
const answer = Promise.resolve()
|
|
88
|
+
.then(call)
|
|
89
|
+
.catch((error) => ({
|
|
90
|
+
Success: false,
|
|
91
|
+
ErrorMessage: error instanceof Error ? error.message : String(error),
|
|
92
|
+
Answers: {}
|
|
93
|
+
}));
|
|
94
|
+
try {
|
|
95
|
+
return await Promise.race([answer, deadline]);
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
clearTimeout(timer);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=decision-routing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-routing.js","sourceRoot":"","sources":["../../../src/lib/utils/decision-routing.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Decision routing for an unmentioned message (plan Tasks 3.9 and 3.2): one typed\n * decision that may send the message to a different agent in the conversation than the last one\n * that answered, and may name the artifact version the message modifies.\n *\n * It runs before {@link ResolveAgentTurn}, which stays pure. When the answer is confident, the\n * caller replaces the continuity candidate with {@link ApplyRoutingDecision}; otherwise nothing\n * changes. Every failure keeps today's routing. The chat turns it on with `EnableDecisionRouting`,\n * which is off by default.\n *\n * The decision itself (its input, questions and state, and how its answers are read) is built in\n * `@memberjunction/ai-core-plus` (`conversation-routing-decision.ts`), so the Decision Eval harness\n * measures exactly what the chat sends. What stays here is the call and what the chat does with\n * the outcome. Import the builders and their types from `@memberjunction/ai-core-plus` directly.\n *\n * Kept free of Angular so the whole path, with the decision call mocked, is testable directly;\n * `MessageInputComponent` supplies the conversation and the call.\n *\n * @module @memberjunction/ng-conversations\n */\n\nimport {\n BuildRoutingQuestions,\n BuildRoutingState,\n ConversationUtility,\n DECISION_ROUTING_TIMEOUT_MS,\n InterpretRoutingAnswers,\n KeptContinuityOutcome,\n type RoutingDecisionInput,\n type RoutingDecisionOutcome\n} from '@memberjunction/ai-core-plus';\nimport type { RunDecisionParams, RunDecisionResult } from '@memberjunction/graphql-dataprovider';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport type { AgentReplyMode } from '../models/agent-turn.model';\nimport type { AgentTurnCandidates } from './agent-turn-routing';\n\n/** Runs a decision on the server: `ConversationAgentService.RunDecision` in the chat. */\nexport type RoutingDecisionRunner = (params: RunDecisionParams) => Promise<RunDecisionResult>;\n\n/** What decides whether a message gets a routing decision at all. */\nexport interface RoutingDecisionGate {\n /** The chat's `EnableDecisionRouting` input. */\n Enabled: boolean;\n /** The chat's reply mode. */\n ReplyMode: AgentReplyMode;\n /** Agents the message tags. */\n MentionedAgentIds: readonly string[];\n /** The message, as saved. */\n Message: string;\n /** The last agent that answered, other than the conversation manager. */\n ContinuityAgentId: string | null;\n}\n\n/**\n * True when a message should get a routing decision: routing is on, the reply mode is `Always`,\n * some agent has answered before, and the message tags no agent and is not a form response. A\n * form response always goes back to the agent that asked for it. Every other message keeps\n * today's routing, with no call.\n */\nexport function ShouldRunRoutingDecision(gate: RoutingDecisionGate): boolean {\n return gate.Enabled\n && gate.ReplyMode === 'Always'\n && !!gate.ContinuityAgentId\n && gate.MentionedAgentIds.length === 0\n && !ConversationUtility.ContainsFormResponse(gate.Message);\n}\n\n/**\n * Asks one routing decision and reads its answer. It fails toward continuity: an error, no answer\n * within `timeoutMs` (the call is abandoned), or an unsure answer keeps today's routing. Never\n * throws.\n *\n * @param input What to decide. Check it with `CanAskRoutingDecision` first.\n * @param runDecision Runs the decision on the server.\n * @param timeoutMs How long to wait. Defaults to `DECISION_ROUTING_TIMEOUT_MS`.\n */\nexport async function RunRoutingDecision(\n input: RoutingDecisionInput,\n runDecision: RoutingDecisionRunner,\n timeoutMs: number = DECISION_ROUTING_TIMEOUT_MS\n): Promise<RoutingDecisionOutcome> {\n const params: RunDecisionParams = {\n State: BuildRoutingState(input),\n Questions: BuildRoutingQuestions(input),\n TimeoutMS: timeoutMs\n };\n const result = await runWithDeadline(() => runDecision(params), timeoutMs);\n return result\n ? InterpretRoutingAnswers(input, result)\n : KeptContinuityOutcome(`no answer within ${timeoutMs} ms`);\n}\n\n/**\n * The candidates with the decision applied: a routed agent replaces continuity and is labelled\n * `DecisionRouted`, and \"someone else\" clears continuity. Any other outcome, or none, leaves the\n * candidates as they are.\n */\nexport function ApplyRoutingDecision(\n candidates: AgentTurnCandidates,\n outcome: RoutingDecisionOutcome | null\n): AgentTurnCandidates {\n if (outcome?.Verdict === 'Routed' && outcome.RoutedAgentId) {\n return { ...candidates, ContinuityAgentId: outcome.RoutedAgentId, ContinuityDecisionRouted: true };\n }\n if (outcome?.Verdict === 'SomeoneElse') {\n return { ...candidates, ContinuityAgentId: null };\n }\n return candidates;\n}\n\n/**\n * The artifact version to hand a turn's agent: the decision's target, when it is one of that\n * agent's versions. Null otherwise, including after a redirect to another agent.\n */\nexport function ArtifactVersionForTurn(outcome: RoutingDecisionOutcome | null, agentId: string): string | null {\n const target = outcome?.TargetArtifact;\n return target && UUIDsEqual(target.AgentId, agentId) ? target.ArtifactVersionId : null;\n}\n\n/**\n * Runs the call, or gives up on it after `timeoutMs`. Resolves with the result, a failed result\n * when the call throws, or null when it didn't answer in time. A late answer is ignored.\n */\nasync function runWithDeadline(\n call: () => Promise<RunDecisionResult>,\n timeoutMs: number\n): Promise<RunDecisionResult | null> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<null>(resolve => {\n timer = setTimeout(() => resolve(null), timeoutMs);\n });\n const answer = Promise.resolve()\n .then(call)\n .catch((error: unknown): RunDecisionResult => ({\n Success: false,\n ErrorMessage: error instanceof Error ? error.message : String(error),\n Answers: {}\n }));\n try {\n return await Promise.race([answer, deadline]);\n } finally {\n clearTimeout(timer);\n }\n}\n"]}
|
|
@@ -26,5 +26,7 @@ export interface DistinctArtifactKey {
|
|
|
26
26
|
* the whole conversation to id → max version for a before/after diff. This one is per-message and
|
|
27
27
|
* returns the objects themselves.
|
|
28
28
|
*/
|
|
29
|
+
export declare function SelectDistinctLatestArtifacts<T extends DistinctArtifactKey>(list: readonly T[]): T[];
|
|
30
|
+
/** @deprecated Use {@link SelectDistinctLatestArtifacts}. */
|
|
29
31
|
export declare function selectDistinctLatestArtifacts<T extends DistinctArtifactKey>(list: readonly T[]): T[];
|
|
30
32
|
//# sourceMappingURL=distinct-artifacts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distinct-artifacts.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/distinct-artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,6BAA6B,CAAC,CAAC,SAAS,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,CAUpG"}
|
|
1
|
+
{"version":3,"file":"distinct-artifacts.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/distinct-artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,6BAA6B,CAAC,CAAC,SAAS,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,CAUpG;AAED,6DAA6D;AAC7D,wBAAgB,6BAA6B,CAAC,CAAC,SAAS,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,CAEpG"}
|
|
@@ -22,7 +22,7 @@ import { NormalizeUUID } from '@memberjunction/global';
|
|
|
22
22
|
* the whole conversation to id → max version for a before/after diff. This one is per-message and
|
|
23
23
|
* returns the objects themselves.
|
|
24
24
|
*/
|
|
25
|
-
export function
|
|
25
|
+
export function SelectDistinctLatestArtifacts(list) {
|
|
26
26
|
const latestByArtifact = new Map();
|
|
27
27
|
for (const info of list) {
|
|
28
28
|
const key = NormalizeUUID(info.artifactId);
|
|
@@ -33,4 +33,8 @@ export function selectDistinctLatestArtifacts(list) {
|
|
|
33
33
|
}
|
|
34
34
|
return Array.from(latestByArtifact.values());
|
|
35
35
|
}
|
|
36
|
+
/** @deprecated Use {@link SelectDistinctLatestArtifacts}. */
|
|
37
|
+
export function selectDistinctLatestArtifacts(list) {
|
|
38
|
+
return SelectDistinctLatestArtifacts(list);
|
|
39
|
+
}
|
|
36
40
|
//# sourceMappingURL=distinct-artifacts.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distinct-artifacts.js","sourceRoot":"","sources":["../../../src/lib/utils/distinct-artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAQvD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,6BAA6B,CAAgC,IAAkB;IAC7F,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAa,CAAC;IAC9C,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC7D,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC;AAC/C,CAAC","sourcesContent":["/**\n * Artifact-grouping utilities for rendering a message's attached artifacts.\n *\n * A single conversation message can carry more than one DISTINCT artifact — for\n * example a research report PLUS a standalone generated infographic. The UI must\n * surface all of them. At the same time, a single artifact can have multiple\n * versions, and only the latest should render. This helper reconciles both.\n */\n\nimport { NormalizeUUID } from '@memberjunction/global';\n\n/** Minimal shape needed to dedupe artifacts — satisfied by `LazyArtifactInfo`. */\nexport interface DistinctArtifactKey {\n artifactId: string
|
|
1
|
+
{"version":3,"file":"distinct-artifacts.js","sourceRoot":"","sources":["../../../src/lib/utils/distinct-artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAQvD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,6BAA6B,CAAgC,IAAkB;IAC7F,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAa,CAAC;IAC9C,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC7D,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,6BAA6B,CAAgC,IAAkB;IAC7F,OAAO,6BAA6B,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["/**\n * Artifact-grouping utilities for rendering a message's attached artifacts.\n *\n * A single conversation message can carry more than one DISTINCT artifact — for\n * example a research report PLUS a standalone generated infographic. The UI must\n * surface all of them. At the same time, a single artifact can have multiple\n * versions, and only the latest should render. This helper reconciles both.\n */\n\nimport { NormalizeUUID } from '@memberjunction/global';\n\n/** Minimal shape needed to dedupe artifacts — satisfied by `LazyArtifactInfo`. */\nexport interface DistinctArtifactKey {\n artifactId: string; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n versionNumber: number; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n}\n\n/**\n * Collapses a message's artifact list to one entry per distinct `artifactId`,\n * keeping the highest `versionNumber` for each. Distinct artifacts are all\n * retained (so a report and an image both surface); multiple versions of the\n * SAME artifact collapse to the latest. Input order of distinct artifacts is\n * preserved (first-seen wins for ordering).\n *\n * Ids are grouped as UUIDs, not as raw strings: SQL Server returns them upper-case and PostgreSQL\n * lower-case, so a list assembled from differently-cased sources would otherwise render the same\n * artifact as two cards.\n *\n * Related but NOT interchangeable: `snapshotArtifactVersions` in `artifact-panel-action.ts` reduces\n * the whole conversation to id → max version for a before/after diff. This one is per-message and\n * returns the objects themselves.\n */\nexport function SelectDistinctLatestArtifacts<T extends DistinctArtifactKey>(list: readonly T[]): T[] {\n const latestByArtifact = new Map<string, T>();\n for (const info of list) {\n const key = NormalizeUUID(info.artifactId);\n const existing = latestByArtifact.get(key);\n if (!existing || info.versionNumber > existing.versionNumber) {\n latestByArtifact.set(key, info);\n }\n }\n return Array.from(latestByArtifact.values());\n}\n\n/** @deprecated Use {@link SelectDistinctLatestArtifacts}. */\nexport function selectDistinctLatestArtifacts<T extends DistinctArtifactKey>(list: readonly T[]): T[] {\n return SelectDistinctLatestArtifacts(list);\n}\n"]}
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
/** Static utility — all state lives in UserInfoEngine's cache; this class only parses/writes. */
|
|
26
26
|
export declare class PlanModePreference {
|
|
27
27
|
/** `MJ: User Settings` key for the per-conversation plan-mode map. */
|
|
28
|
-
private static readonly
|
|
28
|
+
private static readonly prefKey;
|
|
29
29
|
/** v1 stored a single global boolean — superseded by per-conversation scoping; deleted on sight. */
|
|
30
|
-
private static readonly
|
|
30
|
+
private static readonly legacyPrefKey;
|
|
31
31
|
/** Cap on tracked conversations (oldest entries dropped beyond this). */
|
|
32
32
|
private static readonly MAX_TRACKED;
|
|
33
33
|
/** Memoized parse of the raw setting string (avoids JSON.parse per change-detection pass). */
|
|
@@ -27,9 +27,9 @@ import { NormalizeUUID } from '@memberjunction/global';
|
|
|
27
27
|
/** Static utility — all state lives in UserInfoEngine's cache; this class only parses/writes. */
|
|
28
28
|
export class PlanModePreference {
|
|
29
29
|
/** `MJ: User Settings` key for the per-conversation plan-mode map. */
|
|
30
|
-
static
|
|
30
|
+
static prefKey = 'mj.conversations.planMode.v2';
|
|
31
31
|
/** v1 stored a single global boolean — superseded by per-conversation scoping; deleted on sight. */
|
|
32
|
-
static
|
|
32
|
+
static legacyPrefKey = 'mj.conversations.planMode.v1';
|
|
33
33
|
/** Cap on tracked conversations (oldest entries dropped beyond this). */
|
|
34
34
|
static MAX_TRACKED = 100;
|
|
35
35
|
/** Memoized parse of the raw setting string (avoids JSON.parse per change-detection pass). */
|
|
@@ -87,8 +87,8 @@ export class PlanModePreference {
|
|
|
87
87
|
static Warm() {
|
|
88
88
|
UserInfoEngine.Instance.Config()
|
|
89
89
|
.then(() => {
|
|
90
|
-
if (UserInfoEngine.Instance.GetSetting(this.
|
|
91
|
-
void UserInfoEngine.Instance.DeleteSetting(this.
|
|
90
|
+
if (UserInfoEngine.Instance.GetSetting(this.legacyPrefKey) !== undefined) {
|
|
91
|
+
void UserInfoEngine.Instance.DeleteSetting(this.legacyPrefKey);
|
|
92
92
|
}
|
|
93
93
|
})
|
|
94
94
|
.catch(() => { });
|
|
@@ -96,7 +96,7 @@ export class PlanModePreference {
|
|
|
96
96
|
/** Read + memoize the persisted state. Defensive: any failure yields the last-known state. */
|
|
97
97
|
static read() {
|
|
98
98
|
try {
|
|
99
|
-
const raw = UserInfoEngine.Instance.GetSetting(this.
|
|
99
|
+
const raw = UserInfoEngine.Instance.GetSetting(this.prefKey);
|
|
100
100
|
if (raw !== this.rawCache) {
|
|
101
101
|
this.rawCache = raw;
|
|
102
102
|
this.stateCache = raw ? JSON.parse(raw) : {};
|
|
@@ -109,7 +109,7 @@ export class PlanModePreference {
|
|
|
109
109
|
}
|
|
110
110
|
static write(state) {
|
|
111
111
|
try {
|
|
112
|
-
UserInfoEngine.Instance.SetSettingDebounced(this.
|
|
112
|
+
UserInfoEngine.Instance.SetSettingDebounced(this.prefKey, JSON.stringify(state));
|
|
113
113
|
}
|
|
114
114
|
catch (error) {
|
|
115
115
|
console.warn('[PlanModePreference] Failed to persist plan-mode preference:', error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan-mode-preference.js","sourceRoot":"","sources":["../../../src/lib/utils/plan-mode-preference.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Per-conversation Plan Mode preference.\n *\n * Plan Mode is scoped to a CONVERSATION, not globally to the user: toggling it in one\n * conversation must not bleed into others. State is persisted server-side in a single\n * `MJ: User Settings` row (via `UserInfoEngine`, debounced writes + read-after-write\n * cache) so it survives component recreation, navigation, reloads, and sessions:\n *\n * ```json\n * { \"pendingNew\": true, \"byConversation\": { \"<conversationId>\": true, ... } }\n * ```\n *\n * - `pendingNew` — the toggle state chosen on a composer with NO conversation yet (the\n * empty-state / new-conversation composer). It is CLAIMED by (moved onto) the actual\n * conversation when its first message is routed.\n * - `byConversation` — per-conversation flags, capped at {@link MAX_TRACKED} entries\n * (oldest dropped) so the settings row stays small. Keys are normalized UUIDs so\n * SQL Server (uppercase) and PostgreSQL (lowercase) ids can't create duplicates.\n *\n * All composer instances (empty-state, chat-area, thread panel) and the plan-approval\n * form handler read/write through this ONE class, so they can never disagree.\n *\n * @module @memberjunction/ng-conversations\n */\n\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { NormalizeUUID } from '@memberjunction/global';\n\n/** Persisted shape of the plan-mode preference setting. */\ninterface PlanModeState {\n /** Toggle state chosen before the conversation exists (new-conversation composer). */\n pendingNew?: boolean;\n /** Per-conversation toggle states, keyed by normalized conversation ID. */\n byConversation?: Record<string, boolean>;\n}\n\n/** Static utility — all state lives in UserInfoEngine's cache; this class only parses/writes. */\nexport class PlanModePreference {\n /** `MJ: User Settings` key for the per-conversation plan-mode map. */\n private static readonly
|
|
1
|
+
{"version":3,"file":"plan-mode-preference.js","sourceRoot":"","sources":["../../../src/lib/utils/plan-mode-preference.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Per-conversation Plan Mode preference.\n *\n * Plan Mode is scoped to a CONVERSATION, not globally to the user: toggling it in one\n * conversation must not bleed into others. State is persisted server-side in a single\n * `MJ: User Settings` row (via `UserInfoEngine`, debounced writes + read-after-write\n * cache) so it survives component recreation, navigation, reloads, and sessions:\n *\n * ```json\n * { \"pendingNew\": true, \"byConversation\": { \"<conversationId>\": true, ... } }\n * ```\n *\n * - `pendingNew` — the toggle state chosen on a composer with NO conversation yet (the\n * empty-state / new-conversation composer). It is CLAIMED by (moved onto) the actual\n * conversation when its first message is routed.\n * - `byConversation` — per-conversation flags, capped at {@link MAX_TRACKED} entries\n * (oldest dropped) so the settings row stays small. Keys are normalized UUIDs so\n * SQL Server (uppercase) and PostgreSQL (lowercase) ids can't create duplicates.\n *\n * All composer instances (empty-state, chat-area, thread panel) and the plan-approval\n * form handler read/write through this ONE class, so they can never disagree.\n *\n * @module @memberjunction/ng-conversations\n */\n\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { NormalizeUUID } from '@memberjunction/global';\n\n/** Persisted shape of the plan-mode preference setting. */\ninterface PlanModeState {\n /** Toggle state chosen before the conversation exists (new-conversation composer). */\n pendingNew?: boolean;\n /** Per-conversation toggle states, keyed by normalized conversation ID. */\n byConversation?: Record<string, boolean>;\n}\n\n/** Static utility — all state lives in UserInfoEngine's cache; this class only parses/writes. */\nexport class PlanModePreference {\n /** `MJ: User Settings` key for the per-conversation plan-mode map. */\n private static readonly prefKey = 'mj.conversations.planMode.v2';\n /** v1 stored a single global boolean — superseded by per-conversation scoping; deleted on sight. */\n private static readonly legacyPrefKey = 'mj.conversations.planMode.v1';\n /** Cap on tracked conversations (oldest entries dropped beyond this). */\n private static readonly MAX_TRACKED = 100;\n\n /** Memoized parse of the raw setting string (avoids JSON.parse per change-detection pass). */\n private static rawCache: string | undefined = undefined;\n private static stateCache: PlanModeState = {};\n\n /**\n * Whether Plan Mode is on for the given conversation (or for the not-yet-created\n * conversation when `conversationId` is null/undefined). Synchronous cache read —\n * safe to call from Angular getters every change-detection pass.\n */\n public static IsEnabled(conversationId: string | null | undefined): boolean {\n const state = this.read();\n if (!conversationId) {\n return state.pendingNew === true;\n }\n return state.byConversation?.[NormalizeUUID(conversationId)] === true;\n }\n\n /** Sets Plan Mode for the given conversation (or the pending-new bucket when no id yet). */\n public static Set(conversationId: string | null | undefined, enabled: boolean): void {\n const state = { ...this.read() };\n if (!conversationId) {\n state.pendingNew = enabled;\n } else {\n state.byConversation = this.capped({\n ...(state.byConversation ?? {}),\n [NormalizeUUID(conversationId)]: enabled,\n });\n }\n this.write(state);\n }\n\n /**\n * Moves a `pendingNew` choice onto the actual conversation. Call when routing the FIRST\n * message of a conversation — whichever composer instance sends it claims the pending\n * value (the empty-state composer that set it never routes; it hands off via\n * `emptyStateSubmit`). No-op when nothing is pending.\n */\n public static ClaimPendingNew(conversationId: string): void {\n const state = this.read();\n if (state.pendingNew === undefined) {\n return;\n }\n const next: PlanModeState = {\n byConversation: this.capped({\n ...(state.byConversation ?? {}),\n [NormalizeUUID(conversationId)]: state.pendingNew,\n }),\n };\n this.write(next);\n }\n\n /**\n * Warm the UserInfoEngine cache and drop the superseded v1 (global) setting if present.\n * Fire-and-forget from component init; failures just leave the default (off).\n */\n public static Warm(): void {\n UserInfoEngine.Instance.Config()\n .then(() => {\n if (UserInfoEngine.Instance.GetSetting(this.legacyPrefKey) !== undefined) {\n void UserInfoEngine.Instance.DeleteSetting(this.legacyPrefKey);\n }\n })\n .catch(() => { /* reads fall back to default (off) until the engine loads */ });\n }\n\n /** Read + memoize the persisted state. Defensive: any failure yields the last-known state. */\n private static read(): PlanModeState {\n try {\n const raw = UserInfoEngine.Instance.GetSetting(this.prefKey);\n if (raw !== this.rawCache) {\n this.rawCache = raw;\n this.stateCache = raw ? (JSON.parse(raw) as PlanModeState) : {};\n }\n return this.stateCache;\n } catch {\n return this.stateCache; // engine not configured yet or malformed payload\n }\n }\n\n private static write(state: PlanModeState): void {\n try {\n UserInfoEngine.Instance.SetSettingDebounced(this.prefKey, JSON.stringify(state));\n } catch (error) {\n console.warn('[PlanModePreference] Failed to persist plan-mode preference:', error);\n }\n }\n\n /** Cap the per-conversation map, dropping the OLDEST entries (insertion order). */\n private static capped(map: Record<string, boolean>): Record<string, boolean> {\n const keys = Object.keys(map);\n if (keys.length <= this.MAX_TRACKED) {\n return map;\n }\n for (const stale of keys.slice(0, keys.length - this.MAX_TRACKED)) {\n delete map[stale];\n }\n return map;\n }\n}\n"]}
|
package/dist/public-api.d.ts
CHANGED
|
@@ -3,9 +3,13 @@ export * from './lib/models/conversation-state.model';
|
|
|
3
3
|
export * from './lib/models/notification.model';
|
|
4
4
|
export * from './lib/models/lazy-artifact-info';
|
|
5
5
|
export * from './lib/models/navigation-request.model';
|
|
6
|
+
export * from './lib/models/agent-turn.model';
|
|
7
|
+
export * from './lib/utils/agent-turn-routing';
|
|
8
|
+
export * from './lib/utils/decision-routing';
|
|
6
9
|
export * from './lib/services/data-cache.service';
|
|
7
10
|
export * from './lib/services/artifact-state.service';
|
|
8
11
|
export * from './lib/services/agent-state.service';
|
|
12
|
+
export * from './lib/services/conversation-liveness-dom.service';
|
|
9
13
|
export * from './lib/services/conversation-agent.service';
|
|
10
14
|
export * from './lib/services/active-tasks.service';
|
|
11
15
|
export * from './lib/services/conversation-streaming.service';
|
|
@@ -84,6 +88,7 @@ export * from './lib/components/shared/user-picker.component';
|
|
|
84
88
|
export * from './lib/components/tasks/tasks-dropdown.component';
|
|
85
89
|
export * from './lib/components/thread/thread-panel.component';
|
|
86
90
|
export * from './lib/directives/search-shortcut.directive';
|
|
91
|
+
export type { SearchResult, SearchResultType } from './lib/services/search.service';
|
|
87
92
|
export * from './lib/services/conversations-runtime-bootstrap.service';
|
|
88
93
|
export * from './lib/directives/chat-slot.directive';
|
|
89
94
|
export * from './lib/components/slots/slot-interfaces';
|
package/dist/public-api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAKA,cAAc,4BAA4B,CAAC;AAG3C,cAAc,uCAAuC,CAAC;AACtD,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"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"}
|
package/dist/public-api.js
CHANGED
|
@@ -8,10 +8,18 @@ export * from './lib/models/conversation-state.model';
|
|
|
8
8
|
export * from './lib/models/notification.model';
|
|
9
9
|
export * from './lib/models/lazy-artifact-info';
|
|
10
10
|
export * from './lib/models/navigation-request.model';
|
|
11
|
+
// Host rules for an agent turn: reply mode, routes, and the host turn handler contract
|
|
12
|
+
export * from './lib/models/agent-turn.model';
|
|
13
|
+
export * from './lib/utils/agent-turn-routing';
|
|
14
|
+
// Opt-in decision routing for an unmentioned message (EnableDecisionRouting)
|
|
15
|
+
// NOTE: the routing decision's builders and types, and IsAgentAllowed, live in
|
|
16
|
+
// @memberjunction/ai-core-plus — import them from there directly.
|
|
17
|
+
export * from './lib/utils/decision-routing';
|
|
11
18
|
// Services - State
|
|
12
19
|
export * from './lib/services/data-cache.service';
|
|
13
20
|
export * from './lib/services/artifact-state.service';
|
|
14
21
|
export * from './lib/services/agent-state.service';
|
|
22
|
+
export * from './lib/services/conversation-liveness-dom.service';
|
|
15
23
|
export * from './lib/services/conversation-agent.service';
|
|
16
24
|
export * from './lib/services/active-tasks.service';
|
|
17
25
|
export * from './lib/services/conversation-streaming.service';
|