@memberjunction/ng-conversations 5.40.2 → 5.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -0
- package/dist/__tests__/channel-optional-surface.test.d.ts +2 -0
- package/dist/__tests__/channel-optional-surface.test.d.ts.map +1 -0
- package/dist/__tests__/channel-optional-surface.test.js +53 -0
- package/dist/__tests__/channel-optional-surface.test.js.map +1 -0
- package/dist/__tests__/chat-events.test.d.ts +14 -0
- package/dist/__tests__/chat-events.test.d.ts.map +1 -0
- package/dist/__tests__/chat-events.test.js +109 -0
- package/dist/__tests__/chat-events.test.js.map +1 -0
- package/dist/__tests__/conversation-naming.test.d.ts +2 -0
- package/dist/__tests__/conversation-naming.test.d.ts.map +1 -0
- package/dist/__tests__/conversation-naming.test.js +110 -0
- package/dist/__tests__/conversation-naming.test.js.map +1 -0
- package/dist/__tests__/delegation-result-parser.test.d.ts +2 -0
- package/dist/__tests__/delegation-result-parser.test.d.ts.map +1 -0
- package/dist/__tests__/delegation-result-parser.test.js +107 -0
- package/dist/__tests__/delegation-result-parser.test.js.map +1 -0
- package/dist/__tests__/event-wiring.test.d.ts +15 -0
- package/dist/__tests__/event-wiring.test.d.ts.map +1 -0
- package/dist/__tests__/event-wiring.test.js +100 -0
- package/dist/__tests__/event-wiring.test.js.map +1 -0
- package/dist/__tests__/narration-template.test.d.ts +2 -0
- package/dist/__tests__/narration-template.test.d.ts.map +1 -0
- package/dist/__tests__/narration-template.test.js +76 -0
- package/dist/__tests__/narration-template.test.js.map +1 -0
- package/dist/__tests__/realtime-agent-picker-models.test.d.ts +2 -0
- package/dist/__tests__/realtime-agent-picker-models.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-agent-picker-models.test.js +49 -0
- package/dist/__tests__/realtime-agent-picker-models.test.js.map +1 -0
- package/dist/__tests__/realtime-audio-visuals.test.d.ts +2 -0
- package/dist/__tests__/realtime-audio-visuals.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-audio-visuals.test.js +123 -0
- package/dist/__tests__/realtime-audio-visuals.test.js.map +1 -0
- package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts +2 -0
- package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-delegation-card-cancel.test.js +48 -0
- package/dist/__tests__/realtime-delegation-card-cancel.test.js.map +1 -0
- package/dist/__tests__/realtime-disclosure.test.d.ts +2 -0
- package/dist/__tests__/realtime-disclosure.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-disclosure.test.js +164 -0
- package/dist/__tests__/realtime-disclosure.test.js.map +1 -0
- package/dist/__tests__/realtime-pairing.test.d.ts +2 -0
- package/dist/__tests__/realtime-pairing.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-pairing.test.js +207 -0
- package/dist/__tests__/realtime-pairing.test.js.map +1 -0
- package/dist/__tests__/realtime-review-lifecycle.test.d.ts +2 -0
- package/dist/__tests__/realtime-review-lifecycle.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-review-lifecycle.test.js +154 -0
- package/dist/__tests__/realtime-review-lifecycle.test.js.map +1 -0
- package/dist/__tests__/realtime-session-cancel-usage.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-cancel-usage.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-cancel-usage.test.js +230 -0
- package/dist/__tests__/realtime-session-cancel-usage.test.js.map +1 -0
- package/dist/__tests__/realtime-session-channels.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-channels.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-channels.test.js +252 -0
- package/dist/__tests__/realtime-session-channels.test.js.map +1 -0
- package/dist/__tests__/realtime-session-client-tools.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-client-tools.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-client-tools.test.js +103 -0
- package/dist/__tests__/realtime-session-client-tools.test.js.map +1 -0
- package/dist/__tests__/realtime-session-minimized.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-minimized.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-minimized.test.js +32 -0
- package/dist/__tests__/realtime-session-minimized.test.js.map +1 -0
- package/dist/__tests__/realtime-session-mint.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-mint.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-mint.test.js +69 -0
- package/dist/__tests__/realtime-session-mint.test.js.map +1 -0
- package/dist/__tests__/realtime-session-policy.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-policy.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-policy.test.js +303 -0
- package/dist/__tests__/realtime-session-policy.test.js.map +1 -0
- package/dist/__tests__/realtime-session-review.service.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-review.service.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-review.service.test.js +743 -0
- package/dist/__tests__/realtime-session-review.service.test.js.map +1 -0
- package/dist/__tests__/realtime-session-state.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-state.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-state.test.js +83 -0
- package/dist/__tests__/realtime-session-state.test.js.map +1 -0
- package/dist/__tests__/realtime-session-timeline-card.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-timeline-card.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-timeline-card.test.js +106 -0
- package/dist/__tests__/realtime-session-timeline-card.test.js.map +1 -0
- package/dist/__tests__/realtime-session-timeline.test.d.ts +2 -0
- package/dist/__tests__/realtime-session-timeline.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-session-timeline.test.js +142 -0
- package/dist/__tests__/realtime-session-timeline.test.js.map +1 -0
- package/dist/__tests__/realtime-sessions-adapter.test.d.ts +19 -0
- package/dist/__tests__/realtime-sessions-adapter.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-sessions-adapter.test.js +188 -0
- package/dist/__tests__/realtime-sessions-adapter.test.js.map +1 -0
- package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts +2 -0
- package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-surface-panel-prefs.test.js +100 -0
- package/dist/__tests__/realtime-surface-panel-prefs.test.js.map +1 -0
- package/dist/__tests__/realtime-surface-tabs-model.test.d.ts +2 -0
- package/dist/__tests__/realtime-surface-tabs-model.test.d.ts.map +1 -0
- package/dist/__tests__/realtime-surface-tabs-model.test.js +193 -0
- package/dist/__tests__/realtime-surface-tabs-model.test.js.map +1 -0
- package/dist/__tests__/remote-browser-audio-player.test.d.ts +2 -0
- package/dist/__tests__/remote-browser-audio-player.test.d.ts.map +1 -0
- package/dist/__tests__/remote-browser-audio-player.test.js +137 -0
- package/dist/__tests__/remote-browser-audio-player.test.js.map +1 -0
- package/dist/__tests__/remote-browser-channel.test.d.ts +2 -0
- package/dist/__tests__/remote-browser-channel.test.d.ts.map +1 -0
- package/dist/__tests__/remote-browser-channel.test.js +423 -0
- package/dist/__tests__/remote-browser-channel.test.js.map +1 -0
- package/dist/__tests__/slot-defaults.test.d.ts +24 -0
- package/dist/__tests__/slot-defaults.test.d.ts.map +1 -0
- package/dist/__tests__/slot-defaults.test.js +63 -0
- package/dist/__tests__/slot-defaults.test.js.map +1 -0
- package/dist/__tests__/user-authorization.test.d.ts +2 -0
- package/dist/__tests__/user-authorization.test.d.ts.map +1 -0
- package/dist/__tests__/user-authorization.test.js +97 -0
- package/dist/__tests__/user-authorization.test.js.map +1 -0
- package/dist/__tests__/voice-session-narration.test.d.ts +2 -0
- package/dist/__tests__/voice-session-narration.test.d.ts.map +1 -0
- package/dist/__tests__/voice-session-narration.test.js +609 -0
- package/dist/__tests__/voice-session-narration.test.js.map +1 -0
- package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts +2 -0
- package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts.map +1 -0
- package/dist/__tests__/whiteboard-artifact-viewer.test.js +101 -0
- package/dist/__tests__/whiteboard-artifact-viewer.test.js.map +1 -0
- package/dist/__tests__/whiteboard-channel.test.d.ts +2 -0
- package/dist/__tests__/whiteboard-channel.test.d.ts.map +1 -0
- package/dist/__tests__/whiteboard-channel.test.js +260 -0
- package/dist/__tests__/whiteboard-channel.test.js.map +1 -0
- package/dist/__tests__/whiteboard-restore-state.test.d.ts +2 -0
- package/dist/__tests__/whiteboard-restore-state.test.d.ts.map +1 -0
- package/dist/__tests__/whiteboard-restore-state.test.js +108 -0
- package/dist/__tests__/whiteboard-restore-state.test.js.map +1 -0
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +205 -3
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +911 -342
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/mention/mention-dropdown.component.js +35 -17
- package/dist/lib/components/mention/mention-dropdown.component.js.map +1 -1
- package/dist/lib/components/mention/mention-editor.component.d.ts +4 -0
- package/dist/lib/components/mention/mention-editor.component.d.ts.map +1 -1
- package/dist/lib/components/mention/mention-editor.component.js +43 -19
- package/dist/lib/components/mention/mention-editor.component.js.map +1 -1
- package/dist/lib/components/message/message-input-box.component.d.ts +17 -1
- package/dist/lib/components/message/message-input-box.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input-box.component.js +73 -15
- package/dist/lib/components/message/message-input-box.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +142 -6
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +328 -82
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +28 -3
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +180 -108
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +81 -2
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +252 -87
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +282 -0
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +1 -0
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +158 -0
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +1 -0
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts +25 -0
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js +140 -0
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js.map +1 -0
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +35 -0
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +58 -0
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +63 -0
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-activity-rail.component.js +260 -0
- package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +117 -0
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-agent-banner.component.js +504 -0
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +168 -0
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-agent-picker.component.js +556 -0
- package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +97 -0
- package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-audio-visuals.js +139 -0
- package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -0
- package/dist/lib/components/realtime/realtime-channel-strip.component.d.ts +29 -0
- package/dist/lib/components/realtime/realtime-channel-strip.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-channel-strip.component.js +69 -0
- package/dist/lib/components/realtime/realtime-channel-strip.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-composer.component.d.ts +65 -0
- package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-composer.component.js +256 -0
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +71 -0
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-delegation-card.component.js +324 -0
- package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-disclosure.d.ts +135 -0
- package/dist/lib/components/realtime/realtime-disclosure.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-disclosure.js +188 -0
- package/dist/lib/components/realtime/realtime-disclosure.js.map +1 -0
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +491 -0
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +1274 -0
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-session-state.d.ts +191 -0
- package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-session-state.js +244 -0
- package/dist/lib/components/realtime/realtime-session-state.js.map +1 -0
- package/dist/lib/components/realtime/realtime-session-thread.component.d.ts +56 -0
- package/dist/lib/components/realtime/realtime-session-thread.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-session-thread.component.js +246 -0
- package/dist/lib/components/realtime/realtime-session-thread.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts +51 -0
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js +193 -0
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-panel-prefs.d.ts +77 -0
- package/dist/lib/components/realtime/realtime-surface-panel-prefs.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-panel-prefs.js +114 -0
- package/dist/lib/components/realtime/realtime-surface-panel-prefs.js.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +173 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js +496 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +181 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js +223 -0
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.d.ts +163 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.d.ts.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.js +309 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.js.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +168 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +524 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts +346 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +851 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-tools.d.ts +86 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-tools.d.ts.map +1 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-tools.js +210 -0
- package/dist/lib/components/realtime/remote-browser/remote-browser-tools.js.map +1 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.d.ts +48 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.d.ts.map +1 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.js +180 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.js.map +1 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +119 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +274 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -0
- package/dist/lib/components/slots/mj-chat-agent-presence-default.component.d.ts +11 -0
- package/dist/lib/components/slots/mj-chat-agent-presence-default.component.d.ts.map +1 -0
- package/dist/lib/components/slots/mj-chat-agent-presence-default.component.js +98 -0
- package/dist/lib/components/slots/mj-chat-agent-presence-default.component.js.map +1 -0
- package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.d.ts +9 -0
- package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.d.ts.map +1 -0
- package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.js +35 -0
- package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.js.map +1 -0
- package/dist/lib/components/slots/mj-chat-empty-state-default.component.d.ts +28 -0
- package/dist/lib/components/slots/mj-chat-empty-state-default.component.d.ts.map +1 -0
- package/dist/lib/components/slots/mj-chat-empty-state-default.component.js +104 -0
- package/dist/lib/components/slots/mj-chat-empty-state-default.component.js.map +1 -0
- package/dist/lib/components/slots/mj-chat-header-default.component.d.ts +11 -0
- package/dist/lib/components/slots/mj-chat-header-default.component.d.ts.map +1 -0
- package/dist/lib/components/slots/mj-chat-header-default.component.js +103 -0
- package/dist/lib/components/slots/mj-chat-header-default.component.js.map +1 -0
- package/dist/lib/components/slots/mj-chat-message-bubble-default.component.d.ts +15 -0
- package/dist/lib/components/slots/mj-chat-message-bubble-default.component.d.ts.map +1 -0
- package/dist/lib/components/slots/mj-chat-message-bubble-default.component.js +73 -0
- package/dist/lib/components/slots/mj-chat-message-bubble-default.component.js.map +1 -0
- package/dist/lib/components/slots/mj-chat-message-extra-default.component.d.ts +9 -0
- package/dist/lib/components/slots/mj-chat-message-extra-default.component.d.ts.map +1 -0
- package/dist/lib/components/slots/mj-chat-message-extra-default.component.js +34 -0
- package/dist/lib/components/slots/mj-chat-message-extra-default.component.js.map +1 -0
- package/dist/lib/components/slots/slot-interfaces.d.ts +95 -0
- package/dist/lib/components/slots/slot-interfaces.d.ts.map +1 -0
- package/dist/lib/components/slots/slot-interfaces.js +18 -0
- package/dist/lib/components/slots/slot-interfaces.js.map +1 -0
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +11 -0
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +28 -4
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/conversations.module.d.ts +12 -1
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js +93 -5
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/directives/chat-slot.directive.d.ts +44 -0
- package/dist/lib/directives/chat-slot.directive.d.ts.map +1 -0
- package/dist/lib/directives/chat-slot.directive.js +54 -0
- package/dist/lib/directives/chat-slot.directive.js.map +1 -0
- package/dist/lib/events/chat-events.d.ts +137 -0
- package/dist/lib/events/chat-events.d.ts.map +1 -0
- package/dist/lib/events/chat-events.js +189 -0
- package/dist/lib/events/chat-events.js.map +1 -0
- package/dist/lib/models/conversation-state.model.d.ts +2 -1
- package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
- package/dist/lib/models/conversation-state.model.js.map +1 -1
- package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-state.service.js +23 -6
- package/dist/lib/services/artifact-state.service.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +60 -74
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +100 -313
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-bridge.service.d.ts +11 -70
- package/dist/lib/services/conversation-bridge.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-bridge.service.js +51 -85
- package/dist/lib/services/conversation-bridge.service.js.map +1 -1
- package/dist/lib/services/conversation-naming.d.ts +63 -0
- package/dist/lib/services/conversation-naming.d.ts.map +1 -0
- package/dist/lib/services/conversation-naming.js +58 -0
- package/dist/lib/services/conversation-naming.js.map +1 -0
- package/dist/lib/services/conversation-streaming.service.d.ts +24 -154
- package/dist/lib/services/conversation-streaming.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-streaming.service.js +39 -361
- package/dist/lib/services/conversation-streaming.service.js.map +1 -1
- package/dist/lib/services/conversations-runtime-bootstrap.service.d.ts +10 -0
- package/dist/lib/services/conversations-runtime-bootstrap.service.d.ts.map +1 -0
- package/dist/lib/services/conversations-runtime-bootstrap.service.js +104 -0
- package/dist/lib/services/conversations-runtime-bootstrap.service.js.map +1 -0
- package/dist/lib/services/delegation-result-parser.d.ts +45 -0
- package/dist/lib/services/delegation-result-parser.d.ts.map +1 -0
- package/dist/lib/services/delegation-result-parser.js +48 -0
- package/dist/lib/services/delegation-result-parser.js.map +1 -0
- package/dist/lib/services/mention-autocomplete.service.d.ts +19 -4
- package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.js +65 -4
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
- package/dist/lib/services/mention-parser.service.d.ts +8 -53
- package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
- package/dist/lib/services/mention-parser.service.js +32 -243
- package/dist/lib/services/mention-parser.service.js.map +1 -1
- package/dist/lib/services/narration-template.d.ts +42 -0
- package/dist/lib/services/narration-template.d.ts.map +1 -0
- package/dist/lib/services/narration-template.js +73 -0
- package/dist/lib/services/narration-template.js.map +1 -0
- package/dist/lib/services/realtime-pairing.d.ts +120 -0
- package/dist/lib/services/realtime-pairing.d.ts.map +1 -0
- package/dist/lib/services/realtime-pairing.js +150 -0
- package/dist/lib/services/realtime-pairing.js.map +1 -0
- package/dist/lib/services/realtime-session-review.service.d.ts +233 -0
- package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -0
- package/dist/lib/services/realtime-session-review.service.js +417 -0
- package/dist/lib/services/realtime-session-review.service.js.map +1 -0
- package/dist/lib/services/realtime-session.service.d.ts +739 -0
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -0
- package/dist/lib/services/realtime-session.service.js +1647 -0
- package/dist/lib/services/realtime-session.service.js.map +1 -0
- package/dist/lib/services/realtime-sessions-adapter.d.ts +54 -0
- package/dist/lib/services/realtime-sessions-adapter.d.ts.map +1 -0
- package/dist/lib/services/realtime-sessions-adapter.js +154 -0
- package/dist/lib/services/realtime-sessions-adapter.js.map +1 -0
- package/dist/lib/services/user-authorization.d.ts +67 -0
- package/dist/lib/services/user-authorization.d.ts.map +1 -0
- package/dist/lib/services/user-authorization.js +66 -0
- package/dist/lib/services/user-authorization.js.map +1 -0
- package/dist/lib/utils/realtime-session-timeline.d.ts +84 -0
- package/dist/lib/utils/realtime-session-timeline.d.ts.map +1 -0
- package/dist/lib/utils/realtime-session-timeline.js +94 -0
- package/dist/lib/utils/realtime-session-timeline.js.map +1 -0
- package/dist/public-api.d.ts +41 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +50 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +27 -24
- package/dist/__tests__/conversation-bridge.service.test.d.ts +0 -2
- package/dist/__tests__/conversation-bridge.service.test.d.ts.map +0 -1
- package/dist/__tests__/conversation-bridge.service.test.js +0 -98
- package/dist/__tests__/conversation-bridge.service.test.js.map +0 -1
- package/dist/__tests__/mention-parser.test.d.ts +0 -2
- package/dist/__tests__/mention-parser.test.d.ts.map +0 -1
- package/dist/__tests__/mention-parser.test.js +0 -154
- package/dist/__tests__/mention-parser.test.js.map +0 -1
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var WhiteboardArtifactViewerComponent_1;
|
|
8
|
+
import { Component } from '@angular/core';
|
|
9
|
+
import { DataSnapshot } from '@memberjunction/core';
|
|
10
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
11
|
+
import { BaseArtifactViewerPluginComponent } from '@memberjunction/ng-artifacts';
|
|
12
|
+
import { BuildWhiteboardExportHtml, BuildWhiteboardExportSvg, ParseBoardStateJson, WhiteboardSnapshotComponent } from '@memberjunction/ng-whiteboard';
|
|
13
|
+
import * as i0 from "@angular/core";
|
|
14
|
+
/**
|
|
15
|
+
* ARTIFACT VIEWER PLUGIN for saved whiteboards — renders the session-channel board
|
|
16
|
+
* artifact (a {@link WhiteboardState.ToJSON} payload) as a read-only snapshot with the
|
|
17
|
+
* same export affordances the live board offers (Download HTML / Download SVG / Print).
|
|
18
|
+
*
|
|
19
|
+
* Resolved dynamically by the artifact plugin host via the MJ ClassFactory (keyed by the
|
|
20
|
+
* artifact type's DriverClass), which instantiates the class ONCE with a bare `new` to
|
|
21
|
+
* discover the component type — so this class must stay constructible outside an Angular
|
|
22
|
+
* injection context (no `inject()` field initializers, no constructor DI).
|
|
23
|
+
*/
|
|
24
|
+
let WhiteboardArtifactViewerComponent = class WhiteboardArtifactViewerComponent extends BaseArtifactViewerPluginComponent {
|
|
25
|
+
static { WhiteboardArtifactViewerComponent_1 = this; }
|
|
26
|
+
/** Memoized parse — keyed by the raw content string so version switches re-parse. */
|
|
27
|
+
parsedForJson = null;
|
|
28
|
+
parsedState = null;
|
|
29
|
+
/** Raw board payload fed to the snapshot component (setter-driven re-parse there). */
|
|
30
|
+
get ContentJson() {
|
|
31
|
+
return this.getRawContent() ?? '';
|
|
32
|
+
}
|
|
33
|
+
/** Rehydrated board engine for export/snapshot duty (null when content is malformed). */
|
|
34
|
+
get BoardState() {
|
|
35
|
+
const json = this.getRawContent();
|
|
36
|
+
if (json !== this.parsedForJson) {
|
|
37
|
+
this.parsedForJson = json;
|
|
38
|
+
this.parsedState = ParseBoardStateJson(json);
|
|
39
|
+
}
|
|
40
|
+
return this.parsedState;
|
|
41
|
+
}
|
|
42
|
+
get HasBoard() {
|
|
43
|
+
return this.BoardState !== null;
|
|
44
|
+
}
|
|
45
|
+
get hasDisplayContent() {
|
|
46
|
+
return this.HasBoard;
|
|
47
|
+
}
|
|
48
|
+
GetCurrentStateSnapshot() {
|
|
49
|
+
const state = this.BoardState;
|
|
50
|
+
if (!state) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const scene = state.BuildSceneSummary();
|
|
54
|
+
const snap = new DataSnapshot();
|
|
55
|
+
snap.title = this.getDisplayTitle() ?? 'Whiteboard';
|
|
56
|
+
snap.interpretation = scene.summary;
|
|
57
|
+
snap.custom = { elementCounts: scene.counts };
|
|
58
|
+
return snap;
|
|
59
|
+
}
|
|
60
|
+
// ────────────────────────────────────────────── export actions (live-board parity)
|
|
61
|
+
/** Download the board as one self-contained HTML document. */
|
|
62
|
+
OnDownloadHtml() {
|
|
63
|
+
const state = this.BoardState;
|
|
64
|
+
if (!state) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
this.downloadBlob(this.buildExportHtml(state), 'text/html', `whiteboard-${WhiteboardArtifactViewerComponent_1.exportDateStamp()}.html`);
|
|
68
|
+
}
|
|
69
|
+
/** Download the board as a standalone SVG document. */
|
|
70
|
+
OnDownloadSvg() {
|
|
71
|
+
const state = this.BoardState;
|
|
72
|
+
if (!state) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
this.downloadBlob(BuildWhiteboardExportSvg(state), 'image/svg+xml', `whiteboard-${WhiteboardArtifactViewerComponent_1.exportDateStamp()}.svg`);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Print the board: open a blank window, write the self-contained export document and
|
|
79
|
+
* invoke the print dialog (same precedent as the live board host's print path). When
|
|
80
|
+
* the popup is blocked this is a logged no-op — nothing breaks, the user can retry.
|
|
81
|
+
*/
|
|
82
|
+
OnPrint() {
|
|
83
|
+
const state = this.BoardState;
|
|
84
|
+
if (!state) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const printWindow = window.open('about:blank', '_blank');
|
|
88
|
+
if (!printWindow) {
|
|
89
|
+
console.warn('Whiteboard print: popup was blocked — allow popups for this site and retry.');
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
printWindow.document.write(this.buildExportHtml(state));
|
|
93
|
+
printWindow.document.close();
|
|
94
|
+
printWindow.focus();
|
|
95
|
+
// let the document lay out before invoking the dialog (artifact-viewer precedent)
|
|
96
|
+
setTimeout(() => printWindow.print(), 250);
|
|
97
|
+
}
|
|
98
|
+
buildExportHtml(state) {
|
|
99
|
+
return BuildWhiteboardExportHtml(state, {
|
|
100
|
+
Title: this.getDisplayTitle() ?? 'Whiteboard',
|
|
101
|
+
AgentName: 'Agent',
|
|
102
|
+
GeneratedAt: new Date().toLocaleString()
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
downloadBlob(content, mimeType, fileName) {
|
|
106
|
+
const url = URL.createObjectURL(new Blob([content], { type: mimeType }));
|
|
107
|
+
const anchor = document.createElement('a');
|
|
108
|
+
anchor.href = url;
|
|
109
|
+
anchor.download = fileName;
|
|
110
|
+
anchor.click();
|
|
111
|
+
URL.revokeObjectURL(url);
|
|
112
|
+
}
|
|
113
|
+
static exportDateStamp() {
|
|
114
|
+
return new Date().toISOString().slice(0, 10);
|
|
115
|
+
}
|
|
116
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵWhiteboardArtifactViewerComponent_BaseFactory; return function WhiteboardArtifactViewerComponent_Factory(__ngFactoryType__) { return (ɵWhiteboardArtifactViewerComponent_BaseFactory || (ɵWhiteboardArtifactViewerComponent_BaseFactory = i0.ɵɵgetInheritedFactory(WhiteboardArtifactViewerComponent)))(__ngFactoryType__ || WhiteboardArtifactViewerComponent); }; })();
|
|
117
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: WhiteboardArtifactViewerComponent, selectors: [["mj-whiteboard-artifact-viewer"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 12, vars: 8, consts: [[1, "wb-artifact-toolbar"], ["type", "button", "title", "Download as HTML", 1, "wb-tool-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-file-code"], ["type", "button", "title", "Download as SVG", 1, "wb-tool-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-bezier-curve"], ["type", "button", "title", "Print board", 1, "wb-tool-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-print"], [1, "wb-artifact-board", 3, "StateJson"]], template: function WhiteboardArtifactViewerComponent_Template(rf, ctx) { if (rf & 1) {
|
|
118
|
+
i0.ɵɵelementStart(0, "div")(1, "div", 0)(2, "button", 1);
|
|
119
|
+
i0.ɵɵlistener("click", function WhiteboardArtifactViewerComponent_Template_button_click_2_listener() { return ctx.OnDownloadHtml(); });
|
|
120
|
+
i0.ɵɵelement(3, "i", 2);
|
|
121
|
+
i0.ɵɵtext(4, " HTML ");
|
|
122
|
+
i0.ɵɵelementEnd();
|
|
123
|
+
i0.ɵɵelementStart(5, "button", 3);
|
|
124
|
+
i0.ɵɵlistener("click", function WhiteboardArtifactViewerComponent_Template_button_click_5_listener() { return ctx.OnDownloadSvg(); });
|
|
125
|
+
i0.ɵɵelement(6, "i", 4);
|
|
126
|
+
i0.ɵɵtext(7, " SVG ");
|
|
127
|
+
i0.ɵɵelementEnd();
|
|
128
|
+
i0.ɵɵelementStart(8, "button", 5);
|
|
129
|
+
i0.ɵɵlistener("click", function WhiteboardArtifactViewerComponent_Template_button_click_8_listener() { return ctx.OnPrint(); });
|
|
130
|
+
i0.ɵɵelement(9, "i", 6);
|
|
131
|
+
i0.ɵɵtext(10, " Print ");
|
|
132
|
+
i0.ɵɵelementEnd()();
|
|
133
|
+
i0.ɵɵelement(11, "mj-whiteboard-snapshot", 7);
|
|
134
|
+
i0.ɵɵelementEnd();
|
|
135
|
+
} if (rf & 2) {
|
|
136
|
+
i0.ɵɵclassMap("wb-artifact-viewer " + (ctx.cssClass || ""));
|
|
137
|
+
i0.ɵɵstyleProp("height", ctx.height || null);
|
|
138
|
+
i0.ɵɵadvance(2);
|
|
139
|
+
i0.ɵɵproperty("disabled", !ctx.HasBoard);
|
|
140
|
+
i0.ɵɵadvance(3);
|
|
141
|
+
i0.ɵɵproperty("disabled", !ctx.HasBoard);
|
|
142
|
+
i0.ɵɵadvance(3);
|
|
143
|
+
i0.ɵɵproperty("disabled", !ctx.HasBoard);
|
|
144
|
+
i0.ɵɵadvance(3);
|
|
145
|
+
i0.ɵɵproperty("StateJson", ctx.ContentJson);
|
|
146
|
+
} }, dependencies: [WhiteboardSnapshotComponent], styles: ["[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: 100%;\n min-height: 0;\n }\n .wb-artifact-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: 100%;\n min-height: 0;\n }\n .wb-artifact-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n padding: 8px;\n flex-shrink: 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n }\n .wb-tool-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 11px;\n font-size: 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm, 4px);\n }\n .wb-tool-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n }\n .wb-tool-btn[_ngcontent-%COMP%]:disabled {\n color: var(--mj-text-disabled);\n cursor: default;\n }\n .wb-artifact-board[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n }"] });
|
|
147
|
+
};
|
|
148
|
+
WhiteboardArtifactViewerComponent = WhiteboardArtifactViewerComponent_1 = __decorate([
|
|
149
|
+
RegisterClass(BaseArtifactViewerPluginComponent, 'WhiteboardArtifactViewerPlugin')
|
|
150
|
+
], WhiteboardArtifactViewerComponent);
|
|
151
|
+
export { WhiteboardArtifactViewerComponent };
|
|
152
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(WhiteboardArtifactViewerComponent, [{
|
|
153
|
+
type: Component,
|
|
154
|
+
args: [{ standalone: true, selector: 'mj-whiteboard-artifact-viewer', imports: [WhiteboardSnapshotComponent], template: `
|
|
155
|
+
<div [class]="'wb-artifact-viewer ' + (cssClass || '')" [style.height]="height || null">
|
|
156
|
+
<div class="wb-artifact-toolbar">
|
|
157
|
+
<button type="button" class="wb-tool-btn" title="Download as HTML" [disabled]="!HasBoard" (click)="OnDownloadHtml()">
|
|
158
|
+
<i class="fa-solid fa-file-code" aria-hidden="true"></i> HTML
|
|
159
|
+
</button>
|
|
160
|
+
<button type="button" class="wb-tool-btn" title="Download as SVG" [disabled]="!HasBoard" (click)="OnDownloadSvg()">
|
|
161
|
+
<i class="fa-solid fa-bezier-curve" aria-hidden="true"></i> SVG
|
|
162
|
+
</button>
|
|
163
|
+
<button type="button" class="wb-tool-btn" title="Print board" [disabled]="!HasBoard" (click)="OnPrint()">
|
|
164
|
+
<i class="fa-solid fa-print" aria-hidden="true"></i> Print
|
|
165
|
+
</button>
|
|
166
|
+
</div>
|
|
167
|
+
<mj-whiteboard-snapshot class="wb-artifact-board" [StateJson]="ContentJson" />
|
|
168
|
+
</div>
|
|
169
|
+
`, styles: ["\n :host {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: 100%;\n min-height: 0;\n }\n .wb-artifact-viewer {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: 100%;\n min-height: 0;\n }\n .wb-artifact-toolbar {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n padding: 8px;\n flex-shrink: 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n }\n .wb-tool-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 11px;\n font-size: 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm, 4px);\n }\n .wb-tool-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n }\n .wb-tool-btn:disabled {\n color: var(--mj-text-disabled);\n cursor: default;\n }\n .wb-artifact-board {\n flex: 1;\n min-height: 0;\n }\n "] }]
|
|
170
|
+
}], null, null); })();
|
|
171
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(WhiteboardArtifactViewerComponent, { className: "WhiteboardArtifactViewerComponent", filePath: "src/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.ts", lineNumber: 93 }); })();
|
|
172
|
+
/**
|
|
173
|
+
* Tree-shaking prevention: the plugin is resolved dynamically through the MJ ClassFactory
|
|
174
|
+
* (keyed by the artifact type's DriverClass), so this static call keeps the @RegisterClass
|
|
175
|
+
* side effect from being eliminated by the bundler.
|
|
176
|
+
*/
|
|
177
|
+
export function LoadWhiteboardArtifactViewer() {
|
|
178
|
+
// intentional no-op — the import side effect performs the registration
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=whiteboard-artifact-viewer.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whiteboard-artifact-viewer.component.js","sourceRoot":"","sources":["../../../../../src/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component } from '@angular/core';\nimport { DataSnapshot } from '@memberjunction/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseArtifactViewerPluginComponent } from '@memberjunction/ng-artifacts';\nimport {\n BuildWhiteboardExportHtml, BuildWhiteboardExportSvg, ParseBoardStateJson,\n WhiteboardSnapshotComponent, WhiteboardState\n} from '@memberjunction/ng-whiteboard';\n\n/**\n * ARTIFACT VIEWER PLUGIN for saved whiteboards — renders the session-channel board\n * artifact (a {@link WhiteboardState.ToJSON} payload) as a read-only snapshot with the\n * same export affordances the live board offers (Download HTML / Download SVG / Print).\n *\n * Resolved dynamically by the artifact plugin host via the MJ ClassFactory (keyed by the\n * artifact type's DriverClass), which instantiates the class ONCE with a bare `new` to\n * discover the component type — so this class must stay constructible outside an Angular\n * injection context (no `inject()` field initializers, no constructor DI).\n */\n@Component({\n standalone: true,\n selector: 'mj-whiteboard-artifact-viewer',\n imports: [WhiteboardSnapshotComponent],\n template: `\n <div [class]=\"'wb-artifact-viewer ' + (cssClass || '')\" [style.height]=\"height || null\">\n <div class=\"wb-artifact-toolbar\">\n <button type=\"button\" class=\"wb-tool-btn\" title=\"Download as HTML\" [disabled]=\"!HasBoard\" (click)=\"OnDownloadHtml()\">\n <i class=\"fa-solid fa-file-code\" aria-hidden=\"true\"></i> HTML\n </button>\n <button type=\"button\" class=\"wb-tool-btn\" title=\"Download as SVG\" [disabled]=\"!HasBoard\" (click)=\"OnDownloadSvg()\">\n <i class=\"fa-solid fa-bezier-curve\" aria-hidden=\"true\"></i> SVG\n </button>\n <button type=\"button\" class=\"wb-tool-btn\" title=\"Print board\" [disabled]=\"!HasBoard\" (click)=\"OnPrint()\">\n <i class=\"fa-solid fa-print\" aria-hidden=\"true\"></i> Print\n </button>\n </div>\n <mj-whiteboard-snapshot class=\"wb-artifact-board\" [StateJson]=\"ContentJson\" />\n </div>\n `,\n styles: [`\n :host {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: 100%;\n min-height: 0;\n }\n .wb-artifact-viewer {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: 100%;\n min-height: 0;\n }\n .wb-artifact-toolbar {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n padding: 8px;\n flex-shrink: 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n }\n .wb-tool-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 11px;\n font-size: 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm, 4px);\n }\n .wb-tool-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n }\n .wb-tool-btn:disabled {\n color: var(--mj-text-disabled);\n cursor: default;\n }\n .wb-artifact-board {\n flex: 1;\n min-height: 0;\n }\n `]\n})\n@RegisterClass(BaseArtifactViewerPluginComponent, 'WhiteboardArtifactViewerPlugin')\nexport class WhiteboardArtifactViewerComponent extends BaseArtifactViewerPluginComponent {\n /** Memoized parse — keyed by the raw content string so version switches re-parse. */\n private parsedForJson: string | null = null;\n private parsedState: WhiteboardState | null = null;\n\n /** Raw board payload fed to the snapshot component (setter-driven re-parse there). */\n public get ContentJson(): string {\n return this.getRawContent() ?? '';\n }\n\n /** Rehydrated board engine for export/snapshot duty (null when content is malformed). */\n public get BoardState(): WhiteboardState | null {\n const json = this.getRawContent();\n if (json !== this.parsedForJson) {\n this.parsedForJson = json;\n this.parsedState = ParseBoardStateJson(json);\n }\n return this.parsedState;\n }\n\n public get HasBoard(): boolean {\n return this.BoardState !== null;\n }\n\n public override get hasDisplayContent(): boolean {\n return this.HasBoard;\n }\n\n public override GetCurrentStateSnapshot(): DataSnapshot | null {\n const state = this.BoardState;\n if (!state) {\n return null;\n }\n const scene = state.BuildSceneSummary();\n const snap = new DataSnapshot();\n snap.title = this.getDisplayTitle() ?? 'Whiteboard';\n snap.interpretation = scene.summary;\n snap.custom = { elementCounts: scene.counts };\n return snap;\n }\n\n // ────────────────────────────────────────────── export actions (live-board parity)\n\n /** Download the board as one self-contained HTML document. */\n public OnDownloadHtml(): void {\n const state = this.BoardState;\n if (!state) {\n return;\n }\n this.downloadBlob(this.buildExportHtml(state), 'text/html', `whiteboard-${WhiteboardArtifactViewerComponent.exportDateStamp()}.html`);\n }\n\n /** Download the board as a standalone SVG document. */\n public OnDownloadSvg(): void {\n const state = this.BoardState;\n if (!state) {\n return;\n }\n this.downloadBlob(BuildWhiteboardExportSvg(state), 'image/svg+xml', `whiteboard-${WhiteboardArtifactViewerComponent.exportDateStamp()}.svg`);\n }\n\n /**\n * Print the board: open a blank window, write the self-contained export document and\n * invoke the print dialog (same precedent as the live board host's print path). When\n * the popup is blocked this is a logged no-op — nothing breaks, the user can retry.\n */\n public OnPrint(): void {\n const state = this.BoardState;\n if (!state) {\n return;\n }\n const printWindow = window.open('about:blank', '_blank');\n if (!printWindow) {\n console.warn('Whiteboard print: popup was blocked — allow popups for this site and retry.');\n return;\n }\n printWindow.document.write(this.buildExportHtml(state));\n printWindow.document.close();\n printWindow.focus();\n // let the document lay out before invoking the dialog (artifact-viewer precedent)\n setTimeout(() => printWindow.print(), 250);\n }\n\n private buildExportHtml(state: WhiteboardState): string {\n return BuildWhiteboardExportHtml(state, {\n Title: this.getDisplayTitle() ?? 'Whiteboard',\n AgentName: 'Agent',\n GeneratedAt: new Date().toLocaleString()\n });\n }\n\n private downloadBlob(content: string, mimeType: string, fileName: string): void {\n const url = URL.createObjectURL(new Blob([content], { type: mimeType }));\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = fileName;\n anchor.click();\n URL.revokeObjectURL(url);\n }\n\n private static exportDateStamp(): string {\n return new Date().toISOString().slice(0, 10);\n }\n}\n\n/**\n * Tree-shaking prevention: the plugin is resolved dynamically through the MJ ClassFactory\n * (keyed by the artifact type's DriverClass), so this static call keeps the @RegisterClass\n * side effect from being eliminated by the bundler.\n */\nexport function LoadWhiteboardArtifactViewer(): void {\n // intentional no-op — the import side effect performs the registration\n}\n"]}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { Type } from '@angular/core';
|
|
2
|
+
import { RealtimeToolDefinition } from '@memberjunction/ai';
|
|
3
|
+
import { BaseRealtimeChannelClient, ChannelOnboardingDetails } from '../channels/base-realtime-channel-client';
|
|
4
|
+
import { RealtimeWhiteboardHostComponent, WhiteboardState } from '@memberjunction/ng-whiteboard';
|
|
5
|
+
/**
|
|
6
|
+
* Per-widget throttle window for AMBIENT interaction context notes: at most one note per
|
|
7
|
+
* widget per this many ms — within the window the LATEST summary wins (chatty widgets
|
|
8
|
+
* collapse to one trailing-edge note instead of flooding the model's context).
|
|
9
|
+
*/
|
|
10
|
+
export declare const WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS = 4000;
|
|
11
|
+
/**
|
|
12
|
+
* The LIVE WHITEBOARD as a pluggable interactive channel — the canonical
|
|
13
|
+
* {@link BaseRealtimeChannelClient} implementation, resolved from the `MJ: AI Agent
|
|
14
|
+
* Channels` registry row whose `ClientPluginClass` is `'RealtimeWhiteboardChannel'`.
|
|
15
|
+
*
|
|
16
|
+
* One instance per session (created via ClassFactory at session start). It owns the
|
|
17
|
+
* board's {@link WhiteboardState} engine and contributes the channel's full contract:
|
|
18
|
+
*
|
|
19
|
+
* - **Action**: the `Whiteboard_*` client-executed tool set
|
|
20
|
+
* ({@link WHITEBOARD_TOOL_DEFINITIONS}); {@link ApplyAgentTool} prefers the BOUND host
|
|
21
|
+
* component (board mutation + violet pop-in / toast / presence-cursor garnish) and
|
|
22
|
+
* falls back to the pure {@link ApplyWhiteboardAgentTool} engine call when no surface
|
|
23
|
+
* is bound (e.g. the surface panel is collapsed) — the channel keeps working, just
|
|
24
|
+
* without the garnish.
|
|
25
|
+
* - **Perception**: {@link BindSurface} subscribes the host's coalesced (750 ms)
|
|
26
|
+
* `SceneDelta` stream and pipes each delta into the live model's context as a
|
|
27
|
+
* `[whiteboard]` background note; the agent-undo toast click flows the same way.
|
|
28
|
+
* - **Surface**: {@link RealtimeWhiteboardHostComponent}, created dynamically by the
|
|
29
|
+
* overlay's channel tab; the host's Focus toggle rides `Context.SetFocusMode` so the
|
|
30
|
+
* shell can collapse/restore the main call column.
|
|
31
|
+
* - **State of record**: every board mutation (user edits AND agent tool calls) requests
|
|
32
|
+
* a save of {@link WhiteboardState.ToJSON} under channel name `'Whiteboard'` — the
|
|
33
|
+
* host debounces and flushes at teardown.
|
|
34
|
+
*
|
|
35
|
+
* A PRIOR session's persisted board is restored through {@link RestoreState} (invoked by
|
|
36
|
+
* the session host after Initialize, before any surface binding): the saved JSON is
|
|
37
|
+
* rehydrated IN PLACE into the same {@link WhiteboardState} instance, so the save
|
|
38
|
+
* subscription and any later surface binding keep pointing at one engine. Malformed or
|
|
39
|
+
* incompatible payloads are tolerated — the board simply starts fresh.
|
|
40
|
+
*/
|
|
41
|
+
export declare class RealtimeWhiteboardChannel extends BaseRealtimeChannelClient<RealtimeWhiteboardHostComponent> {
|
|
42
|
+
/** The board's state of record — created fresh with the plugin (one per session). */
|
|
43
|
+
readonly State: WhiteboardState;
|
|
44
|
+
/** The live bound surface, when the channel tab's pane is instantiated. */
|
|
45
|
+
private host;
|
|
46
|
+
/** Output subscriptions on the bound surface (SceneDelta / AgentUndo / FocusModeChange). */
|
|
47
|
+
private surfaceSubs;
|
|
48
|
+
/** Board-mutation subscription driving the debounced state-of-record save. */
|
|
49
|
+
private stateChangedSub;
|
|
50
|
+
/** Per-widget ambient-interaction note throttles (ItemID → window state). */
|
|
51
|
+
private interactionThrottles;
|
|
52
|
+
get ChannelName(): string;
|
|
53
|
+
get ToolNamePrefix(): string;
|
|
54
|
+
get TabTitle(): string;
|
|
55
|
+
get TabIcon(): string;
|
|
56
|
+
GetToolDefinitions(): RealtimeToolDefinition[];
|
|
57
|
+
GetSurfaceComponent(): Type<RealtimeWhiteboardHostComponent>;
|
|
58
|
+
/** First-run intro shown the first time the user opens the Whiteboard tab (once per user). */
|
|
59
|
+
GetOnboardingDetails(): ChannelOnboardingDetails;
|
|
60
|
+
/** Persist the board (host-debounced) on EVERY board mutation — user edits AND agent tools. */
|
|
61
|
+
protected OnInitialize(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Wires the dynamically-created board host: inputs (shared state engine + agent name)
|
|
64
|
+
* are set BEFORE the component's first change detection, and the perception/garnish
|
|
65
|
+
* outputs are subscribed back into the host context — the overlay never sees any of it.
|
|
66
|
+
*/
|
|
67
|
+
BindSurface(instance: RealtimeWhiteboardHostComponent): void;
|
|
68
|
+
UnbindSurface(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Routes one ambient widget-interaction batch to the agent as a throttled background
|
|
71
|
+
* context note: outside an open window the note goes out immediately and opens a
|
|
72
|
+
* {@link WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS} window; within the window the LATEST
|
|
73
|
+
* event is stashed and a trailing-edge timer sends it when the window closes (one note
|
|
74
|
+
* per widget per window, latest summary wins).
|
|
75
|
+
*/
|
|
76
|
+
private onWidgetInteraction;
|
|
77
|
+
/** The ambient-note framing: background etiquette rides in the note itself (like scene deltas). */
|
|
78
|
+
private sendInteractionNote;
|
|
79
|
+
/** Cancels all pending ambient-note timers and resets the per-widget throttle windows. */
|
|
80
|
+
private clearInteractionThrottles;
|
|
81
|
+
/**
|
|
82
|
+
* Persists the current board as a `MJ: Artifacts` snapshot via the host context
|
|
83
|
+
* (best-effort; the host logs failures). On success the agent is told via a context
|
|
84
|
+
* note so it can reference the saved artifact naturally.
|
|
85
|
+
*/
|
|
86
|
+
private saveBoardAsArtifact;
|
|
87
|
+
/**
|
|
88
|
+
* Executes one `Whiteboard_*` tool call LOCALLY. Prefers the live bound host (board
|
|
89
|
+
* mutation + UI garnish); falls back to the pure engine function when no surface is
|
|
90
|
+
* bound so the channel keeps working with the pane collapsed.
|
|
91
|
+
*/
|
|
92
|
+
ApplyAgentTool(toolName: string, argsJson: string): string;
|
|
93
|
+
/** The board's serialized state of record (persisted under {@link ChannelName}). */
|
|
94
|
+
SerializeState(): string | null;
|
|
95
|
+
/**
|
|
96
|
+
* Rehydrates a prior session's saved board into THIS session's state engine (in place —
|
|
97
|
+
* the {@link State} instance and its subscriptions are preserved). Returns `true` on
|
|
98
|
+
* success; malformed / incompatible JSON returns `false` and the board stays fresh
|
|
99
|
+
* (never throws — {@link WhiteboardState.LoadFromJSON} is tolerant by contract).
|
|
100
|
+
*/
|
|
101
|
+
RestoreState(stateJson: string): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Exit focus mode THROUGH the bound host (its own Focus button state stays in sync; it
|
|
104
|
+
* re-emits `FocusModeChange(false)` → `Context.SetFocusMode(false)`). When no surface is
|
|
105
|
+
* bound the overlay's defensive flag clear covers it.
|
|
106
|
+
*/
|
|
107
|
+
RequestFocusExit(): void;
|
|
108
|
+
Dispose(): void;
|
|
109
|
+
/** Unsubscribes surface outputs, cancels pending ambient notes and drops the host reference. */
|
|
110
|
+
private releaseSurface;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Tree-shaking prevention: the whiteboard channel is resolved dynamically through the
|
|
114
|
+
* ClassFactory (by the registry row's `ClientPluginClass` key), so this static call is
|
|
115
|
+
* what keeps its `@RegisterClass` side effect from being eliminated by the bundler.
|
|
116
|
+
* Called by `RealtimeSessionService` alongside the realtime-client driver Load calls.
|
|
117
|
+
*/
|
|
118
|
+
export declare function LoadRealtimeWhiteboardChannel(): void;
|
|
119
|
+
//# sourceMappingURL=whiteboard-channel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whiteboard-channel.d.ts","sourceRoot":"","sources":["../../../../../src/lib/components/realtime/whiteboard/whiteboard-channel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AAC/G,OAAO,EACqB,+BAA+B,EACjC,eAAe,EACxC,MAAM,+BAA+B,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,uCAAuC,OAAO,CAAC;AAY5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBACa,yBAA0B,SAAQ,yBAAyB,CAAC,+BAA+B,CAAC;IACvG,qFAAqF;IACrF,SAAgB,KAAK,kBAAyB;IAE9C,2EAA2E;IAC3E,OAAO,CAAC,IAAI,CAAgD;IAC5D,4FAA4F;IAC5F,OAAO,CAAC,WAAW,CAAsB;IACzC,8EAA8E;IAC9E,OAAO,CAAC,eAAe,CAA6B;IACpD,6EAA6E;IAC7E,OAAO,CAAC,oBAAoB,CAA+C;IAE3E,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED,IAAW,cAAc,IAAI,MAAM,CAElC;IAED,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAED,IAAW,OAAO,IAAI,MAAM,CAE3B;IAEM,kBAAkB,IAAI,sBAAsB,EAAE;IAIrC,mBAAmB,IAAI,IAAI,CAAC,+BAA+B,CAAC;IAI5E,8FAA8F;IAC9E,oBAAoB,IAAI,wBAAwB;IAehE,+FAA+F;cAC5E,YAAY,IAAI,IAAI;IAMvC;;;;OAIG;IACI,WAAW,CAAC,QAAQ,EAAE,+BAA+B,GAAG,IAAI;IAqDnD,aAAa,IAAI,IAAI;IAIrC;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAuB3B,mGAAmG;IACnG,OAAO,CAAC,mBAAmB;IAO3B,0FAA0F;IAC1F,OAAO,CAAC,yBAAyB;IASjC;;;;OAIG;YACW,mBAAmB;IAajC;;;;OAIG;IACI,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAOjE,oFAAoF;IACpE,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/C;;;;;OAKG;IACa,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIxD;;;;OAIG;IACa,gBAAgB,IAAI,IAAI;IAMxB,OAAO,IAAI,IAAI;IAM/B,gGAAgG;IAChG,OAAO,CAAC,cAAc;CAQvB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,IAAI,IAAI,CAEpD"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
8
|
+
import { BaseRealtimeChannelClient } from '../channels/base-realtime-channel-client';
|
|
9
|
+
import { ApplyWhiteboardAgentTool, RealtimeWhiteboardHostComponent, WHITEBOARD_TOOL_DEFINITIONS, WHITEBOARD_TOOL_PREFIX, WhiteboardState } from '@memberjunction/ng-whiteboard';
|
|
10
|
+
/**
|
|
11
|
+
* Per-widget throttle window for AMBIENT interaction context notes: at most one note per
|
|
12
|
+
* widget per this many ms — within the window the LATEST summary wins (chatty widgets
|
|
13
|
+
* collapse to one trailing-edge note instead of flooding the model's context).
|
|
14
|
+
*/
|
|
15
|
+
export const WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS = 4000;
|
|
16
|
+
/**
|
|
17
|
+
* The LIVE WHITEBOARD as a pluggable interactive channel — the canonical
|
|
18
|
+
* {@link BaseRealtimeChannelClient} implementation, resolved from the `MJ: AI Agent
|
|
19
|
+
* Channels` registry row whose `ClientPluginClass` is `'RealtimeWhiteboardChannel'`.
|
|
20
|
+
*
|
|
21
|
+
* One instance per session (created via ClassFactory at session start). It owns the
|
|
22
|
+
* board's {@link WhiteboardState} engine and contributes the channel's full contract:
|
|
23
|
+
*
|
|
24
|
+
* - **Action**: the `Whiteboard_*` client-executed tool set
|
|
25
|
+
* ({@link WHITEBOARD_TOOL_DEFINITIONS}); {@link ApplyAgentTool} prefers the BOUND host
|
|
26
|
+
* component (board mutation + violet pop-in / toast / presence-cursor garnish) and
|
|
27
|
+
* falls back to the pure {@link ApplyWhiteboardAgentTool} engine call when no surface
|
|
28
|
+
* is bound (e.g. the surface panel is collapsed) — the channel keeps working, just
|
|
29
|
+
* without the garnish.
|
|
30
|
+
* - **Perception**: {@link BindSurface} subscribes the host's coalesced (750 ms)
|
|
31
|
+
* `SceneDelta` stream and pipes each delta into the live model's context as a
|
|
32
|
+
* `[whiteboard]` background note; the agent-undo toast click flows the same way.
|
|
33
|
+
* - **Surface**: {@link RealtimeWhiteboardHostComponent}, created dynamically by the
|
|
34
|
+
* overlay's channel tab; the host's Focus toggle rides `Context.SetFocusMode` so the
|
|
35
|
+
* shell can collapse/restore the main call column.
|
|
36
|
+
* - **State of record**: every board mutation (user edits AND agent tool calls) requests
|
|
37
|
+
* a save of {@link WhiteboardState.ToJSON} under channel name `'Whiteboard'` — the
|
|
38
|
+
* host debounces and flushes at teardown.
|
|
39
|
+
*
|
|
40
|
+
* A PRIOR session's persisted board is restored through {@link RestoreState} (invoked by
|
|
41
|
+
* the session host after Initialize, before any surface binding): the saved JSON is
|
|
42
|
+
* rehydrated IN PLACE into the same {@link WhiteboardState} instance, so the save
|
|
43
|
+
* subscription and any later surface binding keep pointing at one engine. Malformed or
|
|
44
|
+
* incompatible payloads are tolerated — the board simply starts fresh.
|
|
45
|
+
*/
|
|
46
|
+
let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseRealtimeChannelClient {
|
|
47
|
+
/** The board's state of record — created fresh with the plugin (one per session). */
|
|
48
|
+
State = new WhiteboardState();
|
|
49
|
+
/** The live bound surface, when the channel tab's pane is instantiated. */
|
|
50
|
+
host = null;
|
|
51
|
+
/** Output subscriptions on the bound surface (SceneDelta / AgentUndo / FocusModeChange). */
|
|
52
|
+
surfaceSubs = [];
|
|
53
|
+
/** Board-mutation subscription driving the debounced state-of-record save. */
|
|
54
|
+
stateChangedSub = null;
|
|
55
|
+
/** Per-widget ambient-interaction note throttles (ItemID → window state). */
|
|
56
|
+
interactionThrottles = new Map();
|
|
57
|
+
get ChannelName() {
|
|
58
|
+
return 'Whiteboard';
|
|
59
|
+
}
|
|
60
|
+
get ToolNamePrefix() {
|
|
61
|
+
return WHITEBOARD_TOOL_PREFIX;
|
|
62
|
+
}
|
|
63
|
+
get TabTitle() {
|
|
64
|
+
return 'Whiteboard';
|
|
65
|
+
}
|
|
66
|
+
get TabIcon() {
|
|
67
|
+
return 'fa-solid fa-chalkboard';
|
|
68
|
+
}
|
|
69
|
+
GetToolDefinitions() {
|
|
70
|
+
return WHITEBOARD_TOOL_DEFINITIONS;
|
|
71
|
+
}
|
|
72
|
+
GetSurfaceComponent() {
|
|
73
|
+
return RealtimeWhiteboardHostComponent;
|
|
74
|
+
}
|
|
75
|
+
/** First-run intro shown the first time the user opens the Whiteboard tab (once per user). */
|
|
76
|
+
GetOnboardingDetails() {
|
|
77
|
+
return {
|
|
78
|
+
Heading: 'Whiteboard',
|
|
79
|
+
Description: 'A shared canvas the agent can sketch, write and annotate on live during the call — ' +
|
|
80
|
+
'whatever it draws appears here instantly, and anything you add is something it can see too.',
|
|
81
|
+
Tips: [
|
|
82
|
+
'Watch the board fill in as you talk — the agent updates it in real time.',
|
|
83
|
+
'Add your own notes or shapes; the agent perceives your edits and can build on them.',
|
|
84
|
+
'Use Focus to give the board the whole screen, and save it to artifacts to keep it.'
|
|
85
|
+
],
|
|
86
|
+
IconClass: 'fa-solid fa-chalkboard'
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** Persist the board (host-debounced) on EVERY board mutation — user edits AND agent tools. */
|
|
90
|
+
OnInitialize() {
|
|
91
|
+
this.stateChangedSub = this.State.Changed$.subscribe(() => {
|
|
92
|
+
this.Context?.RequestSave(this.State.ToJSON());
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Wires the dynamically-created board host: inputs (shared state engine + agent name)
|
|
97
|
+
* are set BEFORE the component's first change detection, and the perception/garnish
|
|
98
|
+
* outputs are subscribed back into the host context — the overlay never sees any of it.
|
|
99
|
+
*/
|
|
100
|
+
BindSurface(instance) {
|
|
101
|
+
this.releaseSurface();
|
|
102
|
+
this.host = instance;
|
|
103
|
+
instance.State = this.State;
|
|
104
|
+
instance.AgentName = this.Context?.AgentName ?? 'Agent';
|
|
105
|
+
this.surfaceSubs.push(
|
|
106
|
+
// The board's coalesced scene delta — the perception feed the agent "sees".
|
|
107
|
+
instance.SceneDelta.subscribe((deltaJson) => {
|
|
108
|
+
// Background PERCEPTION, not conversation: the model sees every user edit without
|
|
109
|
+
// being told, but must not narrate minor changes — only react when something is
|
|
110
|
+
// significant (or when asked). The etiquette rides in the note itself so any
|
|
111
|
+
// realtime model gets it regardless of system-prompt sync state.
|
|
112
|
+
this.Context?.SendContextNote('[whiteboard] board update (background context — do NOT comment on minor edits; ' +
|
|
113
|
+
'only mention it if the change is significant to the discussion): ' + deltaJson);
|
|
114
|
+
}),
|
|
115
|
+
// The user clicked Undo on the agent-action toast (the undo already applied locally).
|
|
116
|
+
instance.AgentUndo.subscribe(() => {
|
|
117
|
+
this.Context?.SendContextNote('[whiteboard] user undid your last change');
|
|
118
|
+
}),
|
|
119
|
+
// A sandboxed HTML widget submitted user input (MJWhiteboard.submit) — already
|
|
120
|
+
// validated, size-capped and not canceled (the host's cancelable WidgetSubmitting
|
|
121
|
+
// event ran first). Surface it to the agent so it can react to quiz answers /
|
|
122
|
+
// micro-form input it asked for.
|
|
123
|
+
instance.WidgetSubmitted.subscribe((submit) => {
|
|
124
|
+
// Durable awareness first (the note persists in the model's context)…
|
|
125
|
+
this.Context?.SendContextNote(`[whiteboard] the user submitted input in widget "${submit.Title || submit.ItemID}": ${submit.DataJson}`);
|
|
126
|
+
// …then make the model REACT — a submission is explicit user input the user is
|
|
127
|
+
// waiting on; without this trigger, SendContextNote alone produces dead silence
|
|
128
|
+
// ("I clicked Submit and nothing happened").
|
|
129
|
+
this.Context?.RequestSpokenResponse?.(`The user just submitted input in the whiteboard widget "${submit.Title || submit.ItemID}": ${submit.DataJson}. ` +
|
|
130
|
+
`React to it now in your own voice — acknowledge their choice and continue naturally.`);
|
|
131
|
+
}),
|
|
132
|
+
// AMBIENT widget telemetry (the injected recorder, NOT widget-authored script):
|
|
133
|
+
// clicks / changes / typing summarized by the board. Pure background perception —
|
|
134
|
+
// throttled per widget so chatty widgets don't flood the model's context, and framed
|
|
135
|
+
// with do-not-respond etiquette (explicit MJWhiteboard.submit input arrives above).
|
|
136
|
+
instance.WidgetInteraction.subscribe((interaction) => {
|
|
137
|
+
this.onWidgetInteraction(interaction);
|
|
138
|
+
}),
|
|
139
|
+
// The board's Focus toggle — ask the shell to collapse/restore the main call column.
|
|
140
|
+
instance.FocusModeChange.subscribe((focused) => {
|
|
141
|
+
this.Context?.SetFocusMode(focused);
|
|
142
|
+
}),
|
|
143
|
+
// "Save to artifacts": snapshot the board as a first-class versioned artifact.
|
|
144
|
+
instance.SaveToArtifactsRequested.subscribe(() => {
|
|
145
|
+
void this.saveBoardAsArtifact();
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
UnbindSurface() {
|
|
149
|
+
this.releaseSurface();
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Routes one ambient widget-interaction batch to the agent as a throttled background
|
|
153
|
+
* context note: outside an open window the note goes out immediately and opens a
|
|
154
|
+
* {@link WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS} window; within the window the LATEST
|
|
155
|
+
* event is stashed and a trailing-edge timer sends it when the window closes (one note
|
|
156
|
+
* per widget per window, latest summary wins).
|
|
157
|
+
*/
|
|
158
|
+
onWidgetInteraction(interaction) {
|
|
159
|
+
const now = Date.now();
|
|
160
|
+
const entry = this.interactionThrottles.get(interaction.ItemID);
|
|
161
|
+
if (!entry || (entry.Timer === null && now - entry.LastSentAt >= WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS)) {
|
|
162
|
+
this.sendInteractionNote(interaction);
|
|
163
|
+
this.interactionThrottles.set(interaction.ItemID, { LastSentAt: now, Timer: null, Pending: null });
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
entry.Pending = interaction; // latest wins within the window
|
|
167
|
+
if (entry.Timer === null) {
|
|
168
|
+
const wait = Math.max(0, entry.LastSentAt + WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS - now);
|
|
169
|
+
entry.Timer = setTimeout(() => {
|
|
170
|
+
entry.Timer = null;
|
|
171
|
+
const pending = entry.Pending;
|
|
172
|
+
entry.Pending = null;
|
|
173
|
+
if (pending) {
|
|
174
|
+
entry.LastSentAt = Date.now();
|
|
175
|
+
this.sendInteractionNote(pending);
|
|
176
|
+
}
|
|
177
|
+
}, wait);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/** The ambient-note framing: background etiquette rides in the note itself (like scene deltas). */
|
|
181
|
+
sendInteractionNote(interaction) {
|
|
182
|
+
this.Context?.SendContextNote(`[whiteboard] ambient activity in widget "${interaction.Title || interaction.ItemID}" ` +
|
|
183
|
+
'(background — do NOT respond unless it is significant or you are asked; ' +
|
|
184
|
+
`explicit submissions arrive separately): ${interaction.Summary}`);
|
|
185
|
+
}
|
|
186
|
+
/** Cancels all pending ambient-note timers and resets the per-widget throttle windows. */
|
|
187
|
+
clearInteractionThrottles() {
|
|
188
|
+
for (const entry of this.interactionThrottles.values()) {
|
|
189
|
+
if (entry.Timer !== null) {
|
|
190
|
+
clearTimeout(entry.Timer);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
this.interactionThrottles.clear();
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Persists the current board as a `MJ: Artifacts` snapshot via the host context
|
|
197
|
+
* (best-effort; the host logs failures). On success the agent is told via a context
|
|
198
|
+
* note so it can reference the saved artifact naturally.
|
|
199
|
+
*/
|
|
200
|
+
async saveBoardAsArtifact() {
|
|
201
|
+
const ctx = this.Context;
|
|
202
|
+
if (!ctx) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const now = new Date();
|
|
206
|
+
const name = `Whiteboard — ${now.toLocaleDateString()} ${now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;
|
|
207
|
+
const artifactId = await ctx.SaveAsArtifact(name, this.State.ToJSON());
|
|
208
|
+
if (artifactId) {
|
|
209
|
+
ctx.SendContextNote(`[whiteboard] the user saved the current board as the artifact "${name}"`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Executes one `Whiteboard_*` tool call LOCALLY. Prefers the live bound host (board
|
|
214
|
+
* mutation + UI garnish); falls back to the pure engine function when no surface is
|
|
215
|
+
* bound so the channel keeps working with the pane collapsed.
|
|
216
|
+
*/
|
|
217
|
+
ApplyAgentTool(toolName, argsJson) {
|
|
218
|
+
if (this.host) {
|
|
219
|
+
return this.host.ApplyAgentTool(toolName, argsJson);
|
|
220
|
+
}
|
|
221
|
+
return ApplyWhiteboardAgentTool(this.State, toolName, argsJson);
|
|
222
|
+
}
|
|
223
|
+
/** The board's serialized state of record (persisted under {@link ChannelName}). */
|
|
224
|
+
SerializeState() {
|
|
225
|
+
return this.State.ToJSON();
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Rehydrates a prior session's saved board into THIS session's state engine (in place —
|
|
229
|
+
* the {@link State} instance and its subscriptions are preserved). Returns `true` on
|
|
230
|
+
* success; malformed / incompatible JSON returns `false` and the board stays fresh
|
|
231
|
+
* (never throws — {@link WhiteboardState.LoadFromJSON} is tolerant by contract).
|
|
232
|
+
*/
|
|
233
|
+
RestoreState(stateJson) {
|
|
234
|
+
return this.State.LoadFromJSON(stateJson);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Exit focus mode THROUGH the bound host (its own Focus button state stays in sync; it
|
|
238
|
+
* re-emits `FocusModeChange(false)` → `Context.SetFocusMode(false)`). When no surface is
|
|
239
|
+
* bound the overlay's defensive flag clear covers it.
|
|
240
|
+
*/
|
|
241
|
+
RequestFocusExit() {
|
|
242
|
+
if (this.host?.FocusMode) {
|
|
243
|
+
this.host.ToggleFocus();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
Dispose() {
|
|
247
|
+
this.stateChangedSub?.unsubscribe();
|
|
248
|
+
this.stateChangedSub = null;
|
|
249
|
+
super.Dispose(); // releases the surface binding + context
|
|
250
|
+
}
|
|
251
|
+
/** Unsubscribes surface outputs, cancels pending ambient notes and drops the host reference. */
|
|
252
|
+
releaseSurface() {
|
|
253
|
+
for (const sub of this.surfaceSubs) {
|
|
254
|
+
sub.unsubscribe();
|
|
255
|
+
}
|
|
256
|
+
this.surfaceSubs = [];
|
|
257
|
+
this.clearInteractionThrottles();
|
|
258
|
+
this.host = null;
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
RealtimeWhiteboardChannel = __decorate([
|
|
262
|
+
RegisterClass(BaseRealtimeChannelClient, 'RealtimeWhiteboardChannel')
|
|
263
|
+
], RealtimeWhiteboardChannel);
|
|
264
|
+
export { RealtimeWhiteboardChannel };
|
|
265
|
+
/**
|
|
266
|
+
* Tree-shaking prevention: the whiteboard channel is resolved dynamically through the
|
|
267
|
+
* ClassFactory (by the registry row's `ClientPluginClass` key), so this static call is
|
|
268
|
+
* what keeps its `@RegisterClass` side effect from being eliminated by the bundler.
|
|
269
|
+
* Called by `RealtimeSessionService` alongside the realtime-client driver Load calls.
|
|
270
|
+
*/
|
|
271
|
+
export function LoadRealtimeWhiteboardChannel() {
|
|
272
|
+
// intentional no-op — the import side effect performs the registration
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=whiteboard-channel.js.map
|