@athenaintel/react 0.42.2 → 0.48.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 +225 -3
- package/dist/agent-runtime/src/answer-label.cjs +137 -0
- package/dist/agent-runtime/src/answer-label.cjs.map +1 -0
- package/dist/agent-runtime/src/answer-label.d.ts +104 -0
- package/dist/agent-runtime/src/answer-label.js +137 -0
- package/dist/agent-runtime/src/answer-label.js.map +1 -0
- package/dist/agent-runtime/src/answer-rows.cjs +180 -0
- package/dist/agent-runtime/src/answer-rows.cjs.map +1 -0
- package/dist/agent-runtime/src/answer-rows.d.ts +86 -0
- package/dist/agent-runtime/src/answer-rows.js +180 -0
- package/dist/agent-runtime/src/answer-rows.js.map +1 -0
- package/dist/agent-runtime/src/client-tool-bridge.cjs +15 -15
- package/dist/agent-runtime/src/client-tool-bridge.cjs.map +1 -1
- package/dist/agent-runtime/src/conversation-index.cjs +8 -8
- package/dist/agent-runtime/src/conversation-index.cjs.map +1 -1
- package/dist/agent-runtime/src/conversation-list-groups.d.ts +74 -0
- package/dist/agent-runtime/src/decision-checks.cjs +207 -0
- package/dist/agent-runtime/src/decision-checks.cjs.map +1 -0
- package/dist/agent-runtime/src/decision-checks.d.ts +142 -0
- package/dist/agent-runtime/src/decision-checks.js +207 -0
- package/dist/agent-runtime/src/decision-checks.js.map +1 -0
- package/dist/agent-runtime/src/desktop-handoff.d.ts +12 -0
- package/dist/agent-runtime/src/errors.cjs +18 -0
- package/dist/agent-runtime/src/errors.cjs.map +1 -1
- package/dist/agent-runtime/src/errors.d.ts +7 -0
- package/dist/agent-runtime/src/errors.js +18 -0
- package/dist/agent-runtime/src/errors.js.map +1 -1
- package/dist/agent-runtime/src/generated/runconfig-contract.cjs +12 -0
- package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
- package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +6 -6
- package/dist/agent-runtime/src/generated/runconfig-contract.js +12 -0
- package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
- package/dist/agent-runtime/src/handoff-arrival.cjs +60 -0
- package/dist/agent-runtime/src/handoff-arrival.cjs.map +1 -0
- package/dist/agent-runtime/src/handoff-arrival.d.ts +46 -0
- package/dist/agent-runtime/src/handoff-arrival.js +60 -0
- package/dist/agent-runtime/src/handoff-arrival.js.map +1 -0
- package/dist/agent-runtime/src/index.d.ts +15 -8
- package/dist/agent-runtime/src/interrupts.cjs +43 -18
- package/dist/agent-runtime/src/interrupts.cjs.map +1 -1
- package/dist/agent-runtime/src/interrupts.d.ts +19 -2
- package/dist/agent-runtime/src/interrupts.js +28 -3
- package/dist/agent-runtime/src/interrupts.js.map +1 -1
- package/dist/agent-runtime/src/lane-history.cjs +8 -8
- package/dist/agent-runtime/src/lane-history.cjs.map +1 -1
- package/dist/agent-runtime/src/messages.cjs +43 -8
- package/dist/agent-runtime/src/messages.cjs.map +1 -1
- package/dist/agent-runtime/src/messages.d.ts +25 -3
- package/dist/agent-runtime/src/messages.js +43 -8
- package/dist/agent-runtime/src/messages.js.map +1 -1
- package/dist/agent-runtime/src/offline-status.cjs +36 -0
- package/dist/agent-runtime/src/offline-status.cjs.map +1 -0
- package/dist/agent-runtime/src/offline-status.d.ts +118 -3
- package/dist/agent-runtime/src/offline-status.js +36 -0
- package/dist/agent-runtime/src/offline-status.js.map +1 -0
- package/dist/agent-runtime/src/queue.cjs +0 -9
- package/dist/agent-runtime/src/queue.cjs.map +1 -1
- package/dist/agent-runtime/src/queue.js +0 -9
- package/dist/agent-runtime/src/queue.js.map +1 -1
- package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +9 -9
- package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
- package/dist/agent-runtime/src/runtime-catalog.cjs +42 -0
- package/dist/agent-runtime/src/runtime-catalog.cjs.map +1 -0
- package/dist/agent-runtime/src/runtime-catalog.d.ts +35 -0
- package/dist/agent-runtime/src/runtime-catalog.js +42 -0
- package/dist/agent-runtime/src/runtime-catalog.js.map +1 -0
- package/dist/agent-runtime/src/runtime-messages.cjs.map +1 -1
- package/dist/agent-runtime/src/runtime-messages.d.ts +1 -1
- package/dist/agent-runtime/src/runtime-messages.js.map +1 -1
- package/dist/agent-runtime/src/runtime.d.ts +40 -0
- package/dist/agent-runtime/src/statewire-suspended.cjs +3 -3
- package/dist/agent-runtime/src/statewire-suspended.cjs.map +1 -1
- package/dist/agent-runtime/src/subagents.cjs +32 -2
- package/dist/agent-runtime/src/subagents.cjs.map +1 -1
- package/dist/agent-runtime/src/subagents.d.ts +9 -0
- package/dist/agent-runtime/src/subagents.js +30 -0
- package/dist/agent-runtime/src/subagents.js.map +1 -1
- package/dist/agent-runtime/src/thread-driver.cjs +67 -0
- package/dist/agent-runtime/src/thread-driver.cjs.map +1 -0
- package/dist/agent-runtime/src/thread-driver.d.ts +49 -0
- package/dist/agent-runtime/src/thread-driver.js +67 -0
- package/dist/agent-runtime/src/thread-driver.js.map +1 -0
- package/dist/agent-runtime/src/thread-handoff-flow-machine.d.ts +172 -0
- package/dist/agent-runtime/src/thread-handoff-protocol.d.ts +756 -0
- package/dist/agent-runtime/src/thread-handoff-qr.d.ts +11 -0
- package/dist/agent-runtime/src/thread-handoff.d.ts +3 -364
- package/dist/agent-runtime/src/thread-status.cjs +3 -3
- package/dist/agent-runtime/src/thread-status.cjs.map +1 -1
- package/dist/agent-runtime/src/tool-metadata.cjs +210 -33
- package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
- package/dist/agent-runtime/src/tool-metadata.d.ts +12 -0
- package/dist/agent-runtime/src/tool-metadata.js +210 -33
- package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
- package/dist/agent-runtime/src/tool-names.cjs +2 -0
- package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
- package/dist/agent-runtime/src/tool-names.d.ts +2 -0
- package/dist/agent-runtime/src/tool-names.js +2 -0
- package/dist/agent-runtime/src/tool-names.js.map +1 -1
- package/dist/agent-runtime/src/types.d.ts +10 -2
- package/dist/agent-runtime/src/use-conversation-list.cjs +11 -11
- package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +24 -19
- package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-chat-outbox.d.ts +2 -1
- package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +6 -1
- package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-config.cjs +14 -14
- package/dist/agent-runtime/src/use-deep-agent-config.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs +6 -6
- package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +16 -16
- package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs +45 -45
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-voice.cjs +572 -134
- package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +137 -10
- package/dist/agent-runtime/src/use-deep-agent-voice.js +514 -76
- package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs +26 -26
- package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -1
- package/dist/agent-runtime/src/use-historical-edit-attachments.cjs +4 -4
- package/dist/agent-runtime/src/use-historical-edit-attachments.cjs.map +1 -1
- package/dist/agent-runtime/src/use-thread-handoff-flow.d.ts +28 -26
- package/dist/agent-runtime/src/voice-media.cjs +117 -0
- package/dist/agent-runtime/src/voice-media.cjs.map +1 -0
- package/dist/agent-runtime/src/voice-media.d.ts +49 -0
- package/dist/agent-runtime/src/voice-media.js +117 -0
- package/dist/agent-runtime/src/voice-media.js.map +1 -0
- package/dist/agent-runtime/src/voice-wire-types.d.ts +32 -0
- package/dist/assets/AssetPanel.cjs +11 -11
- package/dist/assets/AssetPanel.cjs.map +1 -1
- package/dist/assets/AthenaAssetEmbed.cjs +11 -9
- package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
- package/dist/assets/AthenaAssetEmbed.d.ts +7 -0
- package/dist/assets/AthenaAssetEmbed.js +4 -2
- package/dist/assets/AthenaAssetEmbed.js.map +1 -1
- package/dist/assets/AthenaLayout.cjs +16 -16
- package/dist/assets/AthenaLayout.cjs.map +1 -1
- package/dist/assets/use-asset-content.cjs +4 -4
- package/dist/assets/use-asset-content.cjs.map +1 -1
- package/dist/assets/use-asset-embed.cjs +14 -7
- package/dist/assets/use-asset-embed.cjs.map +1 -1
- package/dist/assets/use-asset-embed.d.ts +11 -1
- package/dist/assets/use-asset-embed.js +10 -3
- package/dist/assets/use-asset-embed.js.map +1 -1
- package/dist/auth/AthenaAuthContext.cjs +3 -3
- package/dist/auth/AthenaAuthContext.cjs.map +1 -1
- package/dist/auth/AthenaAuthProvider.cjs +8 -8
- package/dist/auth/AthenaAuthProvider.cjs.map +1 -1
- package/dist/auth/AthenaCredentialSourceContext.cjs +5 -5
- package/dist/auth/AthenaCredentialSourceContext.cjs.map +1 -1
- package/dist/auth/AthenaSSOProvider.cjs +14 -14
- package/dist/auth/AthenaSSOProvider.cjs.map +1 -1
- package/dist/auth/credential-source.cjs +26 -13
- package/dist/auth/credential-source.cjs.map +1 -1
- package/dist/auth/credential-source.d.ts +8 -0
- package/dist/auth/credential-source.js +26 -13
- package/dist/auth/credential-source.js.map +1 -1
- package/dist/catalog/agent-model-options.cjs +25 -17
- package/dist/catalog/agent-model-options.cjs.map +1 -1
- package/dist/catalog/agent-model-options.d.ts +38 -5
- package/dist/catalog/agent-model-options.js +25 -17
- package/dist/catalog/agent-model-options.js.map +1 -1
- package/dist/catalog/channel-refusal.cjs +36 -0
- package/dist/catalog/channel-refusal.cjs.map +1 -0
- package/dist/catalog/channel-refusal.d.ts +29 -0
- package/dist/catalog/channel-refusal.js +36 -0
- package/dist/catalog/channel-refusal.js.map +1 -0
- package/dist/catalog/chat-pickers.cjs +60 -24
- package/dist/catalog/chat-pickers.cjs.map +1 -1
- package/dist/catalog/chat-pickers.d.ts +12 -2
- package/dist/catalog/chat-pickers.js +56 -20
- package/dist/catalog/chat-pickers.js.map +1 -1
- package/dist/catalog/runtime-catalog.cjs +89 -23
- package/dist/catalog/runtime-catalog.cjs.map +1 -1
- package/dist/catalog/runtime-catalog.d.ts +8 -2
- package/dist/catalog/runtime-catalog.js +83 -17
- package/dist/catalog/runtime-catalog.js.map +1 -1
- package/dist/catalog/use-athena-chat-mode.cjs +12 -12
- package/dist/catalog/use-athena-chat-mode.cjs.map +1 -1
- package/dist/chat/AthenaChat.cjs +155 -67
- package/dist/chat/AthenaChat.cjs.map +1 -1
- package/dist/chat/AthenaChat.d.ts +42 -2
- package/dist/chat/AthenaChat.js +106 -18
- package/dist/chat/AthenaChat.js.map +1 -1
- package/dist/chat/AthenaChatErrorBoundary.cjs +3 -3
- package/dist/chat/AthenaChatErrorBoundary.cjs.map +1 -1
- package/dist/chat/DrivingOnChip.cjs +23 -0
- package/dist/chat/DrivingOnChip.cjs.map +1 -0
- package/dist/chat/DrivingOnChip.d.ts +17 -0
- package/dist/chat/DrivingOnChip.js +23 -0
- package/dist/chat/DrivingOnChip.js.map +1 -0
- package/dist/chat/StatewireApprovalCard.cjs +125 -31
- package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
- package/dist/chat/StatewireApprovalCard.d.ts +73 -1
- package/dist/chat/StatewireApprovalCard.js +115 -21
- package/dist/chat/StatewireApprovalCard.js.map +1 -1
- package/dist/chat/StatewireClientToolBridge.cjs +2 -2
- package/dist/chat/StatewireClientToolBridge.cjs.map +1 -1
- package/dist/chat/StatewireQueuedMessages.cjs +25 -63
- package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
- package/dist/chat/StatewireQueuedMessages.d.ts +11 -13
- package/dist/chat/StatewireQueuedMessages.js +16 -54
- package/dist/chat/StatewireQueuedMessages.js.map +1 -1
- package/dist/chat/WaitingOnYouBanner.cjs +3 -3
- package/dist/chat/WaitingOnYouBanner.cjs.map +1 -1
- package/dist/chat/athena-chat-welcome.cjs +2 -2
- package/dist/chat/athena-chat-welcome.cjs.map +1 -1
- package/dist/chat/athena-citation-links.cjs +5 -5
- package/dist/chat/athena-citation-links.cjs.map +1 -1
- package/dist/chat/athena-composer-controls.cjs +26 -16
- package/dist/chat/athena-composer-controls.cjs.map +1 -1
- package/dist/chat/athena-composer-controls.d.ts +6 -0
- package/dist/chat/athena-composer-controls.js +26 -16
- package/dist/chat/athena-composer-controls.js.map +1 -1
- package/dist/chat/athena-turn-end-status.cjs +42 -0
- package/dist/chat/athena-turn-end-status.cjs.map +1 -0
- package/dist/chat/athena-turn-end-status.d.ts +24 -0
- package/dist/chat/athena-turn-end-status.js +42 -0
- package/dist/chat/athena-turn-end-status.js.map +1 -0
- package/dist/chat/browser-decision-check.cjs +131 -0
- package/dist/chat/browser-decision-check.cjs.map +1 -0
- package/dist/chat/browser-decision-check.d.ts +61 -0
- package/dist/chat/browser-decision-check.js +131 -0
- package/dist/chat/browser-decision-check.js.map +1 -0
- package/dist/chat/chat-outbox-rows.cjs +3 -3
- package/dist/chat/chat-outbox-rows.cjs.map +1 -1
- package/dist/chat/chat-voice-controls.cjs +93 -28
- package/dist/chat/chat-voice-controls.cjs.map +1 -1
- package/dist/chat/chat-voice-controls.d.ts +36 -2
- package/dist/chat/chat-voice-controls.js +89 -24
- package/dist/chat/chat-voice-controls.js.map +1 -1
- package/dist/chat/composer-keyboard-hint.cjs +5 -5
- package/dist/chat/composer-keyboard-hint.cjs.map +1 -1
- package/dist/chat/device-operation.cjs +29 -0
- package/dist/chat/device-operation.cjs.map +1 -0
- package/dist/chat/device-operation.d.ts +34 -0
- package/dist/chat/device-operation.js +29 -0
- package/dist/chat/device-operation.js.map +1 -0
- package/dist/chat/super-grouping/CollapsibleGroup.cjs +14 -14
- package/dist/chat/super-grouping/CollapsibleGroup.cjs.map +1 -1
- package/dist/chat/super-grouping/GroupedMessageParts.cjs +4 -4
- package/dist/chat/super-grouping/GroupedMessageParts.cjs.map +1 -1
- package/dist/chat/super-grouping/SuperGroupingCard.cjs +60 -38
- package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
- package/dist/chat/super-grouping/SuperGroupingCard.d.ts +24 -4
- package/dist/chat/super-grouping/SuperGroupingCard.js +37 -15
- package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
- package/dist/chat/super-grouping/SuperGroupingTranscript.cjs +32 -32
- package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -1
- package/dist/chat/super-grouping/SuperGroupingTranscript.js +3 -3
- package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -1
- package/dist/chat/super-grouping/ToolTimeline.cjs +97 -37
- package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
- package/dist/chat/super-grouping/ToolTimeline.d.ts +14 -2
- package/dist/chat/super-grouping/ToolTimeline.js +94 -34
- package/dist/chat/super-grouping/ToolTimeline.js.map +1 -1
- package/dist/chat/super-grouping/activity-timeline.cjs +47 -12
- package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
- package/dist/chat/super-grouping/activity-timeline.d.ts +21 -0
- package/dist/chat/super-grouping/activity-timeline.js +47 -12
- package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
- package/dist/chat/super-grouping/grouping-function.cjs +4 -0
- package/dist/chat/super-grouping/grouping-function.cjs.map +1 -1
- package/dist/chat/super-grouping/grouping-function.d.ts +7 -0
- package/dist/chat/super-grouping/grouping-function.js +5 -1
- package/dist/chat/super-grouping/grouping-function.js.map +1 -1
- package/dist/chat/super-grouping/index.cjs +6 -0
- package/dist/chat/super-grouping/index.cjs.map +1 -1
- package/dist/chat/super-grouping/index.d.ts +6 -2
- package/dist/chat/super-grouping/index.js +7 -1
- package/dist/chat/super-grouping/index.js.map +1 -1
- package/dist/chat/super-grouping/timeline-step.cjs +61 -2
- package/dist/chat/super-grouping/timeline-step.cjs.map +1 -1
- package/dist/chat/super-grouping/timeline-step.d.ts +13 -1
- package/dist/chat/super-grouping/timeline-step.js +61 -2
- package/dist/chat/super-grouping/timeline-step.js.map +1 -1
- package/dist/chat/super-grouping/tool-part-placement.cjs +17 -0
- package/dist/chat/super-grouping/tool-part-placement.cjs.map +1 -0
- package/dist/chat/super-grouping/tool-part-placement.d.ts +22 -0
- package/dist/chat/super-grouping/tool-part-placement.js +17 -0
- package/dist/chat/super-grouping/tool-part-placement.js.map +1 -0
- package/dist/chat/thread-scroll-to-bottom.cjs +2 -2
- package/dist/chat/thread-scroll-to-bottom.cjs.map +1 -1
- package/dist/chat/thread-scroll-to-bottom.d.ts +10 -7
- package/dist/chat/thread-scroll-to-bottom.js +2 -2
- package/dist/chat/thread-scroll-to-bottom.js.map +1 -1
- package/dist/chat/tooltip-icon-button.cjs +2 -2
- package/dist/chat/tooltip-icon-button.cjs.map +1 -1
- package/dist/chat/use-athena-voice-live.cjs +11 -0
- package/dist/chat/use-athena-voice-live.cjs.map +1 -0
- package/dist/chat/use-athena-voice-live.d.ts +11 -0
- package/dist/chat/use-athena-voice-live.js +11 -0
- package/dist/chat/use-athena-voice-live.js.map +1 -0
- package/dist/chat/use-statewire-approval-request.cjs +56 -24
- package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
- package/dist/chat/use-statewire-approval-request.d.ts +33 -4
- package/dist/chat/use-statewire-approval-request.js +41 -9
- package/dist/chat/use-statewire-approval-request.js.map +1 -1
- package/dist/chat-ui/auth/sign-in-card.cjs +2 -2
- package/dist/chat-ui/auth/sign-in-card.cjs.map +1 -1
- package/dist/chat-ui/composer/tiptap-composer.cjs +138 -107
- package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
- package/dist/chat-ui/composer/tiptap-composer.d.ts +20 -4
- package/dist/chat-ui/composer/tiptap-composer.js +85 -54
- package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
- package/dist/chat-ui/header/conversation-history-panel.cjs +49 -23
- package/dist/chat-ui/header/conversation-history-panel.cjs.map +1 -1
- package/dist/chat-ui/header/conversation-history-panel.d.ts +12 -1
- package/dist/chat-ui/header/conversation-history-panel.js +38 -12
- package/dist/chat-ui/header/conversation-history-panel.js.map +1 -1
- package/dist/chat-ui/index.cjs +18 -0
- package/dist/chat-ui/index.cjs.map +1 -1
- package/dist/chat-ui/index.d.ts +7 -1
- package/dist/chat-ui/index.js +18 -0
- package/dist/chat-ui/index.js.map +1 -1
- package/dist/chat-ui/mentions/mention-chip.cjs +147 -38
- package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
- package/dist/chat-ui/mentions/mention-chip.d.ts +17 -1
- package/dist/chat-ui/mentions/mention-chip.js +146 -37
- package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs +10 -9
- package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js +3 -2
- package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs +2 -2
- package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs +29 -6
- package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/menu-list.d.ts +7 -1
- package/dist/chat-ui/mentions/suggestions/components/menu-list.js +25 -2
- package/dist/chat-ui/mentions/suggestions/components/menu-list.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/use-keyboard-navigation.cjs +2 -2
- package/dist/chat-ui/mentions/suggestions/components/use-keyboard-navigation.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/use-menu-navigation.cjs +2 -2
- package/dist/chat-ui/mentions/suggestions/components/use-menu-navigation.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +3 -3
- package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/orchestrator.cjs +56 -2
- package/dist/chat-ui/mentions/suggestions/data/orchestrator.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/orchestrator.d.ts +12 -0
- package/dist/chat-ui/mentions/suggestions/data/orchestrator.js +56 -2
- package/dist/chat-ui/mentions/suggestions/data/orchestrator.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +24 -3
- package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/sources/index.d.ts +7 -0
- package/dist/chat-ui/mentions/suggestions/data/sources/index.js +24 -3
- package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs +35 -13
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.d.ts +15 -1
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js +28 -6
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/use-menu-items.cjs +9 -6
- package/dist/chat-ui/mentions/suggestions/data/use-menu-items.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/use-menu-items.d.ts +3 -0
- package/dist/chat-ui/mentions/suggestions/data/use-menu-items.js +5 -2
- package/dist/chat-ui/mentions/suggestions/data/use-menu-items.js.map +1 -1
- package/dist/chat-ui/mentions/use-account-workspace-id.cjs +45 -10
- package/dist/chat-ui/mentions/use-account-workspace-id.cjs.map +1 -1
- package/dist/chat-ui/mentions/use-account-workspace-id.d.ts +24 -1
- package/dist/chat-ui/mentions/use-account-workspace-id.js +46 -11
- package/dist/chat-ui/mentions/use-account-workspace-id.js.map +1 -1
- package/dist/chat-ui/mentions/use-member-avatar.cjs +4 -4
- package/dist/chat-ui/mentions/use-member-avatar.cjs.map +1 -1
- package/dist/chat-ui/mentions/use-mention-asset.cjs +140 -0
- package/dist/chat-ui/mentions/use-mention-asset.cjs.map +1 -0
- package/dist/chat-ui/mentions/use-mention-asset.d.ts +16 -0
- package/dist/chat-ui/mentions/use-mention-asset.js +140 -0
- package/dist/chat-ui/mentions/use-mention-asset.js.map +1 -0
- package/dist/chat-ui/messages/answer-label.cjs +42 -0
- package/dist/chat-ui/messages/answer-label.cjs.map +1 -0
- package/dist/chat-ui/messages/answer-label.d.ts +33 -0
- package/dist/chat-ui/messages/answer-label.js +42 -0
- package/dist/chat-ui/messages/answer-label.js.map +1 -0
- package/dist/chat-ui/messages/arrival-animation.cjs +13 -0
- package/dist/chat-ui/messages/arrival-animation.cjs.map +1 -0
- package/dist/chat-ui/messages/arrival-animation.d.ts +14 -0
- package/dist/chat-ui/messages/arrival-animation.js +13 -0
- package/dist/chat-ui/messages/arrival-animation.js.map +1 -0
- package/dist/chat-ui/messages/continue-pill.cjs +5 -5
- package/dist/chat-ui/messages/continue-pill.cjs.map +1 -1
- package/dist/chat-ui/messages/handoff-arrival-divider.cjs +44 -0
- package/dist/chat-ui/messages/handoff-arrival-divider.cjs.map +1 -0
- package/dist/chat-ui/messages/handoff-arrival-divider.d.ts +17 -0
- package/dist/chat-ui/messages/handoff-arrival-divider.js +44 -0
- package/dist/chat-ui/messages/handoff-arrival-divider.js.map +1 -0
- package/dist/chat-ui/messages/message-actions-config.cjs +3 -3
- package/dist/chat-ui/messages/message-actions-config.cjs.map +1 -1
- package/dist/chat-ui/messages/message-components.cjs +8 -4
- package/dist/chat-ui/messages/message-components.cjs.map +1 -1
- package/dist/chat-ui/messages/message-components.js +5 -1
- package/dist/chat-ui/messages/message-components.js.map +1 -1
- package/dist/chat-ui/messages/message-images.cjs +66 -0
- package/dist/chat-ui/messages/message-images.cjs.map +1 -0
- package/dist/chat-ui/messages/message-images.d.ts +16 -0
- package/dist/chat-ui/messages/message-images.js +66 -0
- package/dist/chat-ui/messages/message-images.js.map +1 -0
- package/dist/chat-ui/messages/user-edit-composer.cjs +2 -2
- package/dist/chat-ui/messages/user-edit-composer.cjs.map +1 -1
- package/dist/chat-ui/messages/wake-marker.cjs +3 -3
- package/dist/chat-ui/messages/wake-marker.cjs.map +1 -1
- package/dist/chat-ui/rich-text/chat-link.cjs +7 -6
- package/dist/chat-ui/rich-text/chat-link.cjs.map +1 -1
- package/dist/chat-ui/rich-text/chat-link.d.ts +2 -3
- package/dist/chat-ui/rich-text/chat-link.js +6 -5
- package/dist/chat-ui/rich-text/chat-link.js.map +1 -1
- package/dist/chat-ui/rich-text/chat-message-body.cjs +8 -8
- package/dist/chat-ui/rich-text/chat-message-body.cjs.map +1 -1
- package/dist/chat-ui/rich-text/chat-node-views.cjs +7 -6
- package/dist/chat-ui/rich-text/chat-node-views.cjs.map +1 -1
- package/dist/chat-ui/rich-text/chat-node-views.js +1 -0
- package/dist/chat-ui/rich-text/chat-node-views.js.map +1 -1
- package/dist/chat-ui/rich-text/dom-output-spec.cjs +2 -2
- package/dist/chat-ui/rich-text/dom-output-spec.cjs.map +1 -1
- package/dist/chat-ui/statewire.cjs +3 -0
- package/dist/chat-ui/statewire.cjs.map +1 -1
- package/dist/chat-ui/statewire.d.ts +2 -1
- package/dist/chat-ui/statewire.js +3 -0
- package/dist/chat-ui/statewire.js.map +1 -1
- package/dist/chat-ui/thread/chat-thread-shell.cjs +43 -14
- package/dist/chat-ui/thread/chat-thread-shell.cjs.map +1 -1
- package/dist/chat-ui/thread/chat-thread-shell.d.ts +16 -2
- package/dist/chat-ui/thread/chat-thread-shell.js +35 -6
- package/dist/chat-ui/thread/chat-thread-shell.js.map +1 -1
- package/dist/chat-ui/thread/composer-send-or-stop.cjs +30 -20
- package/dist/chat-ui/thread/composer-send-or-stop.cjs.map +1 -1
- package/dist/chat-ui/thread/composer-send-or-stop.d.ts +8 -0
- package/dist/chat-ui/thread/composer-send-or-stop.js +29 -19
- package/dist/chat-ui/thread/composer-send-or-stop.js.map +1 -1
- package/dist/chat-ui/thread/statewire-history-edge.cjs +20 -21
- package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
- package/dist/chat-ui/thread/statewire-history-edge.js +3 -4
- package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
- package/dist/chat-ui/thread/thread-loading-overlay.cjs +5 -5
- package/dist/chat-ui/thread/thread-loading-overlay.cjs.map +1 -1
- package/dist/collab/client.cjs +40 -3
- package/dist/collab/client.cjs.map +1 -1
- package/dist/collab/client.d.ts +25 -0
- package/dist/collab/client.js +40 -3
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/document-status.cjs +150 -0
- package/dist/collab/document-status.cjs.map +1 -0
- package/dist/collab/document-status.d.ts +68 -0
- package/dist/collab/document-status.js +150 -0
- package/dist/collab/document-status.js.map +1 -0
- package/dist/collab/index.cjs +7 -0
- package/dist/collab/index.cjs.map +1 -1
- package/dist/collab/index.d.ts +6 -1
- package/dist/collab/index.js +7 -0
- package/dist/collab/index.js.map +1 -1
- package/dist/collab/presence-react.cjs +11 -11
- package/dist/collab/presence-react.cjs.map +1 -1
- package/dist/collab/react.cjs +6 -6
- package/dist/collab/react.cjs.map +1 -1
- package/dist/composer/AttachmentContext.cjs +24 -11
- package/dist/composer/AttachmentContext.cjs.map +1 -1
- package/dist/composer/AttachmentContext.js +18 -5
- package/dist/composer/AttachmentContext.js.map +1 -1
- package/dist/composer/ComposerAttachmentPreview.cjs +78 -23
- package/dist/composer/ComposerAttachmentPreview.cjs.map +1 -1
- package/dist/composer/ComposerAttachmentPreview.d.ts +5 -3
- package/dist/composer/ComposerAttachmentPreview.js +79 -24
- package/dist/composer/ComposerAttachmentPreview.js.map +1 -1
- package/dist/composer/ComposerDropZone.cjs +7 -7
- package/dist/composer/ComposerDropZone.cjs.map +1 -1
- package/dist/composer/FileUploadButton.cjs +37 -22
- package/dist/composer/FileUploadButton.cjs.map +1 -1
- package/dist/composer/FileUploadButton.d.ts +6 -0
- package/dist/composer/FileUploadButton.js +34 -19
- package/dist/composer/FileUploadButton.js.map +1 -1
- package/dist/composer/QuoteContext.cjs +8 -8
- package/dist/composer/QuoteContext.cjs.map +1 -1
- package/dist/composer/composer-handoff.cjs +4 -4
- package/dist/composer/composer-handoff.cjs.map +1 -1
- package/dist/composer/useAppendToComposer.cjs +4 -4
- package/dist/composer/useAppendToComposer.cjs.map +1 -1
- package/dist/composer/useAttachFiles.cjs +23 -6
- package/dist/composer/useAttachFiles.cjs.map +1 -1
- package/dist/composer/useAttachFiles.d.ts +15 -7
- package/dist/composer/useAttachFiles.js +22 -5
- package/dist/composer/useAttachFiles.js.map +1 -1
- package/dist/composer/useComposerAttachment.cjs +4 -4
- package/dist/composer/useComposerAttachment.cjs.map +1 -1
- package/dist/composer/useFileUpload.cjs +21 -16
- package/dist/composer/useFileUpload.cjs.map +1 -1
- package/dist/composer/useFileUpload.d.ts +12 -0
- package/dist/composer/useFileUpload.js +12 -7
- package/dist/composer/useFileUpload.js.map +1 -1
- package/dist/composer/useReadComposerDraft.cjs +2 -2
- package/dist/composer/useReadComposerDraft.cjs.map +1 -1
- package/dist/composer/useSendMessage.cjs +4 -4
- package/dist/composer/useSendMessage.cjs.map +1 -1
- package/dist/diagnostics/useAthenaDiagnostics.cjs +4 -4
- package/dist/diagnostics/useAthenaDiagnostics.cjs.map +1 -1
- package/dist/dictation/audio-level-history.cjs +3 -3
- package/dist/dictation/audio-level-history.cjs.map +1 -1
- package/dist/dictation/dictation-controls.cjs +24 -20
- package/dist/dictation/dictation-controls.cjs.map +1 -1
- package/dist/dictation/dictation-controls.d.ts +6 -1
- package/dist/dictation/dictation-controls.js +24 -20
- package/dist/dictation/dictation-controls.js.map +1 -1
- package/dist/dictation/use-athena-dictation-engine.cjs +3 -3
- package/dist/dictation/use-athena-dictation-engine.cjs.map +1 -1
- package/dist/dictation/use-dictation.cjs +22 -22
- package/dist/dictation/use-dictation.cjs.map +1 -1
- package/dist/index.cjs +26 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +15 -3
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/dist/keryx-http/src/receive-only-socket.cjs +40 -0
- package/dist/keryx-http/src/receive-only-socket.cjs.map +1 -0
- package/dist/keryx-http/src/receive-only-socket.d.ts +27 -0
- package/dist/keryx-http/src/receive-only-socket.js +40 -0
- package/dist/keryx-http/src/receive-only-socket.js.map +1 -0
- package/dist/keryx-http/src/update-attributions.cjs +111 -0
- package/dist/keryx-http/src/update-attributions.cjs.map +1 -0
- package/dist/keryx-http/src/update-attributions.d.ts +75 -0
- package/dist/keryx-http/src/update-attributions.js +111 -0
- package/dist/keryx-http/src/update-attributions.js.map +1 -0
- package/dist/lib/owner-document.cjs +6 -6
- package/dist/lib/owner-document.cjs.map +1 -1
- package/dist/lib/use-athena-rest-query.cjs +4 -4
- package/dist/lib/use-athena-rest-query.cjs.map +1 -1
- package/dist/lib/use-document-active.cjs +4 -4
- package/dist/lib/use-document-active.cjs.map +1 -1
- package/dist/lib/use-prefers-reduced-motion.cjs +2 -2
- package/dist/lib/use-prefers-reduced-motion.cjs.map +1 -1
- package/dist/offline/offline-history.cjs +7 -7
- package/dist/offline/offline-history.cjs.map +1 -1
- package/dist/provider/AthenaContext.cjs +3 -3
- package/dist/provider/AthenaContext.cjs.map +1 -1
- package/dist/provider/AthenaProvider.cjs +116 -79
- package/dist/provider/AthenaProvider.cjs.map +1 -1
- package/dist/provider/AthenaProvider.js +40 -3
- package/dist/provider/AthenaProvider.js.map +1 -1
- package/dist/provider/PostHogProvider.cjs +2 -2
- package/dist/provider/PostHogProvider.cjs.map +1 -1
- package/dist/provider/agent-selection-context.cjs +2 -2
- package/dist/provider/agent-selection-context.cjs.map +1 -1
- package/dist/provider/chat-mode-context.cjs +2 -2
- package/dist/provider/chat-mode-context.cjs.map +1 -1
- package/dist/provider/session-persistence-context.cjs +10 -0
- package/dist/provider/session-persistence-context.cjs.map +1 -0
- package/dist/provider/session-persistence-context.d.ts +15 -0
- package/dist/provider/session-persistence-context.js +10 -0
- package/dist/provider/session-persistence-context.js.map +1 -0
- package/dist/provider/statewire-history-context.cjs +4 -4
- package/dist/provider/statewire-history-context.cjs.map +1 -1
- package/dist/provider/statewire-lifecycle-context.cjs +3 -3
- package/dist/provider/statewire-lifecycle-context.cjs.map +1 -1
- package/dist/provider/statewire-window-context.cjs +3 -3
- package/dist/provider/statewire-window-context.cjs.map +1 -1
- package/dist/provider/theme-style-context.cjs +3 -3
- package/dist/provider/theme-style-context.cjs.map +1 -1
- package/dist/react/package.json.cjs +1 -1
- package/dist/react/package.json.js +1 -1
- package/dist/references/src/tool-option-schemas.d.ts +0 -34
- package/dist/runtime/StatewireThreadConfigLaneSync.cjs +10 -10
- package/dist/runtime/StatewireThreadConfigLaneSync.cjs.map +1 -1
- package/dist/runtime/auth-refusal-restart.cjs +7 -7
- package/dist/runtime/auth-refusal-restart.cjs.map +1 -1
- package/dist/runtime/auth.cjs +13 -13
- package/dist/runtime/auth.cjs.map +1 -1
- package/dist/runtime/statewire-lifecycle.cjs +1 -0
- package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
- package/dist/runtime/statewire-lifecycle.d.ts +3 -1
- package/dist/runtime/statewire-lifecycle.js +2 -1
- package/dist/runtime/statewire-lifecycle.js.map +1 -1
- package/dist/runtime/statewire-server-lane-context.cjs +2 -2
- package/dist/runtime/statewire-server-lane-context.cjs.map +1 -1
- package/dist/runtime/statewire-session-lane.cjs +4 -4
- package/dist/runtime/statewire-session-lane.cjs.map +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.cjs +10 -8
- package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.d.ts +2 -0
- package/dist/runtime/useAthenaStatewireRuntime.js +2 -0
- package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/threads/Inbox.cjs +8 -8
- package/dist/threads/Inbox.cjs.map +1 -1
- package/dist/threads/SessionList.cjs +9 -9
- package/dist/threads/SessionList.cjs.map +1 -1
- package/dist/threads/SessionsPage.cjs +11 -11
- package/dist/threads/SessionsPage.cjs.map +1 -1
- package/dist/threads/index-triggered-refresh.cjs +10 -10
- package/dist/threads/index-triggered-refresh.cjs.map +1 -1
- package/dist/threads/mark-viewed-thread-read.cjs +12 -12
- package/dist/threads/mark-viewed-thread-read.cjs.map +1 -1
- package/dist/threads/offline-session-list.cjs +3 -3
- package/dist/threads/offline-session-list.cjs.map +1 -1
- package/dist/threads/session-list-tab-share.cjs +5 -5
- package/dist/threads/session-list-tab-share.cjs.map +1 -1
- package/dist/threads/statewire-thread-list.cjs +55 -51
- package/dist/threads/statewire-thread-list.cjs.map +1 -1
- package/dist/threads/statewire-thread-list.js +6 -2
- package/dist/threads/statewire-thread-list.js.map +1 -1
- package/dist/threads/thread-id-context.cjs +5 -5
- package/dist/threads/thread-id-context.cjs.map +1 -1
- package/dist/threads/use-athena-session-attention.cjs +2 -2
- package/dist/threads/use-athena-session-attention.cjs.map +1 -1
- package/dist/threads/use-athena-sessions.cjs +10 -10
- package/dist/threads/use-athena-sessions.cjs.map +1 -1
- package/dist/threads/use-athena-thread-model.cjs +3 -3
- package/dist/threads/use-athena-thread-model.cjs.map +1 -1
- package/dist/threads/use-rest-conversation-history.cjs +3 -3
- package/dist/threads/use-rest-conversation-history.cjs.map +1 -1
- package/dist/threads/use-statewire-conversation-history.cjs +8 -8
- package/dist/threads/use-statewire-conversation-history.cjs.map +1 -1
- package/dist/threads/use-thread-archive.cjs +9 -9
- package/dist/threads/use-thread-archive.cjs.map +1 -1
- package/dist/threads/use-thread-favorite.cjs +2 -2
- package/dist/threads/use-thread-favorite.cjs.map +1 -1
- package/dist/threads/use-thread-field-override.cjs +20 -20
- package/dist/threads/use-thread-field-override.cjs.map +1 -1
- package/dist/threads/use-thread-read-state.cjs +4 -4
- package/dist/threads/use-thread-read-state.cjs.map +1 -1
- package/dist/threads/use-thread-rename.cjs +2 -2
- package/dist/threads/use-thread-rename.cjs.map +1 -1
- package/dist/threads/useAthenaThreadManager.cjs +2 -2
- package/dist/threads/useAthenaThreadManager.cjs.map +1 -1
- package/dist/tools/NestedPtcMessages.cjs +6 -6
- package/dist/tools/NestedPtcMessages.cjs.map +1 -1
- package/dist/tools/append-document-tool-ui.cjs +7 -7
- package/dist/tools/append-document-tool-ui.cjs.map +1 -1
- package/dist/tools/file-tool-uis.cjs +2 -2
- package/dist/tools/file-tool-uis.cjs.map +1 -1
- package/dist/tools/misc-tool-uis.cjs +2 -2
- package/dist/tools/misc-tool-uis.cjs.map +1 -1
- package/dist/tools/primitives.cjs +6 -6
- package/dist/tools/primitives.cjs.map +1 -1
- package/dist/tools/read-asset-tool-ui.cjs +6 -6
- package/dist/tools/read-asset-tool-ui.cjs.map +1 -1
- package/dist/tools/subagent-task-tool-ui.cjs +21 -21
- package/dist/tools/subagent-task-tool-ui.cjs.map +1 -1
- package/dist/tools/test-recording-tool-uis.cjs +16 -16
- package/dist/tools/test-recording-tool-uis.cjs.map +1 -1
- package/dist/tools/todo-plan-store.cjs +4 -4
- package/dist/tools/todo-plan-store.cjs.map +1 -1
- package/dist/tools/tool-appearance.cjs +3 -3
- package/dist/tools/tool-appearance.cjs.map +1 -1
- package/dist/tools/tool-fallback.cjs +14 -14
- package/dist/tools/tool-fallback.cjs.map +1 -1
- package/dist/tools/tool-summary.cjs +0 -2
- package/dist/tools/tool-summary.cjs.map +1 -1
- package/dist/tools/tool-summary.js +0 -2
- package/dist/tools/tool-summary.js.map +1 -1
- package/dist/tools/tool-uis.cjs +74 -74
- package/dist/tools/tool-uis.cjs.map +1 -1
- package/dist/tools/use-elapsed-seconds.cjs +3 -3
- package/dist/tools/use-elapsed-seconds.cjs.map +1 -1
- package/dist/tools/write-todos-tool-ui.cjs +9 -9
- package/dist/tools/write-todos-tool-ui.cjs.map +1 -1
- package/dist/ui/image-viewer.cjs +382 -0
- package/dist/ui/image-viewer.cjs.map +1 -0
- package/dist/ui/image-viewer.d.ts +50 -0
- package/dist/ui/image-viewer.js +382 -0
- package/dist/ui/image-viewer.js.map +1 -0
- package/dist/voice/chat.cjs +6 -0
- package/dist/voice/chat.cjs.map +1 -1
- package/dist/voice/chat.d.ts +1 -1
- package/dist/voice/chat.js +8 -2
- package/dist/voice/livekit-join.cjs +52 -101
- package/dist/voice/livekit-join.cjs.map +1 -1
- package/dist/voice/livekit-join.d.ts +1 -6
- package/dist/voice/livekit-join.js +52 -101
- package/dist/voice/livekit-join.js.map +1 -1
- package/dist/voice/livekit.cjs.map +1 -1
- package/dist/voice/livekit.d.ts +11 -1
- package/dist/voice/livekit.js.map +1 -1
- package/dist/voice/use-athena-voice-session.cjs +34 -34
- package/dist/voice/use-athena-voice-session.cjs.map +1 -1
- package/dist/workbench/ComputerLiveDesktop.cjs +13 -13
- package/dist/workbench/ComputerLiveDesktop.cjs.map +1 -1
- package/dist/workbench/SessionWorkbench.cjs +22 -22
- package/dist/workbench/SessionWorkbench.cjs.map +1 -1
- package/dist/workbench/session-workbench-context.cjs +3 -3
- package/dist/workbench/session-workbench-context.cjs.map +1 -1
- package/dist/workbench/session-workbench-panes.cjs +8 -8
- package/dist/workbench/session-workbench-panes.cjs.map +1 -1
- package/dist/workbench/workbench-layout-context.cjs +3 -3
- package/dist/workbench/workbench-layout-context.cjs.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../../src/chat-ui/mentions/suggestions/data/sources/index.ts"],"sourcesContent":["/**\n * Mention data sources shared by every chat host.\n *\n * Each source function implements the SourceFn interface:\n * (context: SourceContext) => Promise<SourceResult>\n *\n * Sources are either:\n * - FETCHERS: Call GraphQL API (assets, folders, team, etc.)\n * - TRANSFORMERS: Return static/local data (root categories, host-provided items)\n */\n\nimport type {\n MenuItem,\n MentionTool,\n SourceFn,\n SourceResult,\n SourceToRegister,\n FetchMetadata,\n WebpageMention,\n} from \"../types\";\nimport { MentionMenuSection } from \"../types\";\nimport {\n fetchGraphQL,\n SIMPLE_SEARCH_QUERY,\n PAGINATED_ASSETS_QUERY,\n WORKSPACE_MEMBERS_QUERY,\n TOOL_CATALOG_QUERY,\n type MentionAuthContext,\n type AssetResult,\n type WorkspaceMember,\n type ToolCatalogResult,\n} from \"../api-client\";\nimport { assetTypeToThumb, assetTypeToIcon } from \"./asset-type-icons\";\n\n// ── Helpers ──\n\nfunction assetToMenuItem(asset: AssetResult): MenuItem {\n const isFolder = asset.athenaOriginalType === \"folder\";\n const displayType = asset.athenaConvertedType || asset.athenaOriginalType;\n return {\n id: asset.id,\n name: asset.title || \"Untitled\",\n type: isFolder ? \"folder\" : \"asset\",\n thumbnailUrl: assetTypeToThumb(displayType),\n fallbackIcon: assetTypeToIcon(displayType),\n navigatesToScope: isFolder ? asset.id : undefined,\n visibleInScopes: new Set(),\n updatedAt: asset.updatedAt ?? undefined,\n extra: {\n athenaOriginalType: asset.athenaOriginalType,\n athenaConvertedType: asset.athenaConvertedType,\n parentFolderId: asset.parentFolderId,\n },\n };\n}\n\nasync function querySimpleSearch(\n auth: MentionAuthContext,\n opts: {\n query?: string;\n limit: number;\n offset: number;\n includeTypes?: string[];\n excludeTypes?: string[];\n },\n): Promise<{ items: MenuItem[]; hasMore: boolean }> {\n const searchRequest: Record<string, any> = {\n query: opts.query?.trim() || \"\",\n type: opts.includeTypes || [],\n notType: opts.excludeTypes || [],\n limit: opts.limit,\n offset: opts.offset,\n };\n\n const input = {\n searchRequest,\n returnFullAsset: true,\n shouldCalculateTotal: false,\n sort: { field: \"UPDATED_AT\", direction: \"DESC\" },\n filterColumns: { isArchived: false, isHidden: false },\n };\n\n const data = await fetchGraphQL<{\n simpleSearch: { assets: AssetResult[]; totalCount: number };\n }>(auth, SIMPLE_SEARCH_QUERY, { input });\n\n const assets = data.simpleSearch?.assets || [];\n return {\n items: assets.map(assetToMenuItem),\n hasMore: assets.length === opts.limit,\n };\n}\n\n// ══════════════════════════════════════════════════════════════════════\n// ROOT CATEGORIES (Transformer)\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface RootCategoriesConfig {\n categories: string[];\n getWebpages: () => readonly WebpageMention[];\n}\n\nconst CATEGORY_DEFS: Record<\n string,\n { name: string; icon: string; scope: string }\n> = {\n favorites: { name: \"Favorites\", icon: \"star\", scope: \"favorites\" },\n assets: { name: \"Assets\", icon: \"file-text\", scope: \"athena_assets\" },\n projects: {\n name: \"Projects\",\n icon: \"folder-kanban\",\n scope: \"athena_projects\",\n },\n browse_profiles: {\n name: \"Browse Profiles\",\n icon: \"globe\",\n scope: \"athena_browse_profiles\",\n },\n folders: { name: \"Folders\", icon: \"folder\", scope: \"athena_folders\" },\n tools: { name: \"Tools\", icon: \"wrench\", scope: \"tools\" },\n toolkits: { name: \"Toolkits\", icon: \"package\", scope: \"toolkits\" },\n team: { name: \"Team\", icon: \"users\", scope: \"team\" },\n drives: { name: \"Drives\", icon: \"hard-drive\", scope: \"drive_catalogs\" },\n};\n\nfunction webpageDescription(webpage: WebpageMention): string {\n try {\n const hostname = new URL(webpage.url).hostname;\n return webpage.isCurrent ? `${webpage.title} · ${hostname}` : hostname;\n } catch {\n return webpage.title;\n }\n}\n\nfunction webpageToMenuItem(webpage: WebpageMention): MenuItem {\n return {\n id: `webpage-tab-${webpage.tabId}`,\n name: webpage.isCurrent ? \"This webpage\" : webpage.title,\n type: \"tab\",\n thumbnailUrl: assetTypeToThumb(\"web_page\"),\n fallbackIcon: \"globe\",\n visibleInScopes: new Set([\"root\"]),\n description: webpageDescription(webpage),\n url: webpage.url,\n menuSection: webpage.isCurrent\n ? MentionMenuSection.CURRENT_WEBPAGE\n : MentionMenuSection.OTHER_WEBPAGES,\n extra: {\n tabId: webpage.tabId,\n title: webpage.title,\n isCurrent: webpage.isCurrent,\n },\n };\n}\n\nexport function buildRootMenuItems({\n categories,\n webpages,\n}: {\n categories: readonly string[];\n webpages: readonly WebpageMention[];\n}): MenuItem[] {\n const webpageItems = webpages.map(webpageToMenuItem);\n const categoryItems = categories\n .filter((cat: string) => CATEGORY_DEFS[cat])\n .map((cat: string) => {\n const def = CATEGORY_DEFS[cat];\n return {\n id: cat,\n name: def.name,\n type: \"menu\" as const,\n fallbackIcon: def.icon,\n visibleInScopes: new Set([\"root\"]),\n navigatesToScope: def.scope,\n isNavigationOnly: true,\n menuSection: MentionMenuSection.LIBRARY,\n };\n });\n\n return [...webpageItems, ...categoryItems];\n}\n\nexport const transformRootCategories: SourceFn<RootCategoriesConfig> = async (\n context,\n) => {\n const { sourceConfig } = context;\n const items = buildRootMenuItems({\n categories: sourceConfig.categories,\n webpages: sourceConfig.getWebpages(),\n });\n\n return { items, pagination: { hasMore: false } };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// ASSETS (Fetcher) — All non-folder assets via SimpleSearch\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface AssetsConfig {\n auth: MentionAuthContext;\n limit?: number;\n}\n\nexport const fetchAssets: SourceFn<AssetsConfig> = async (context) => {\n const { query, fetchState, sourceConfig } = context;\n const limit = sourceConfig.limit ?? 50;\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n const result = await querySimpleSearch(sourceConfig.auth, {\n query,\n limit,\n offset,\n excludeTypes: [\"folder\", \"catalog\", \"session\"],\n });\n\n return {\n items: result.items,\n pagination: { hasMore: result.hasMore },\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// FAVORITES (Fetcher) — Favorited assets\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface FavoritesConfig {\n auth: MentionAuthContext;\n limit?: number;\n}\n\nexport const fetchFavorites: SourceFn<FavoritesConfig> = async (context) => {\n const { query, fetchState, sourceConfig } = context;\n const limit = sourceConfig.limit ?? 50;\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n const data = await fetchGraphQL<{\n getPaginatedAssetsForWorkspace: AssetResult[];\n }>(sourceConfig.auth, PAGINATED_ASSETS_QUERY, {\n limit,\n offset,\n parentFolderId: null,\n filterTypes: null,\n filterColumns: {\n isFavorited: true,\n isArchived: false,\n isHidden: false,\n },\n });\n\n const assets = data.getPaginatedAssetsForWorkspace || [];\n const items = assets.map(assetToMenuItem);\n\n return {\n items,\n pagination: { hasMore: assets.length === limit },\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// FOLDERS (Fetcher) — All folders as flat list\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface FoldersConfig {\n auth: MentionAuthContext;\n limit?: number;\n}\n\nexport const fetchFolders: SourceFn<FoldersConfig> = async (context) => {\n const { query, fetchState, sourceConfig } = context;\n const limit = sourceConfig.limit ?? 50;\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n const result = await querySimpleSearch(sourceConfig.auth, {\n query,\n limit,\n offset,\n includeTypes: [\"folder\"],\n });\n\n return {\n items: result.items,\n pagination: { hasMore: result.hasMore },\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// FOLDER CONTENTS (Fetcher) — Contents of a specific folder\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface FolderContentsConfig {\n auth: MentionAuthContext;\n limit?: number;\n}\n\nexport const fetchFolderContents: SourceFn<FolderContentsConfig> = async (\n context,\n) => {\n const { scope, query, fetchState, sourceConfig } = context;\n const limit = sourceConfig.limit ?? 50;\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n // Scope IS the folder ID (or 'internal_drive' for root)\n const parentFolderId = scope === \"internal_drive\" ? null : scope;\n\n const data = await fetchGraphQL<{\n getPaginatedAssetsForWorkspace: AssetResult[];\n }>(sourceConfig.auth, PAGINATED_ASSETS_QUERY, {\n limit,\n offset,\n parentFolderId,\n filterTypes: null,\n filterColumns: {\n isArchived: false,\n isHidden: false,\n ...(query ? { title: [{ op: \"LIKE\", value: `%${query}%` }] } : {}),\n },\n });\n\n const rawAssets = data.getPaginatedAssetsForWorkspace || [];\n // Exclude catalogs from folder contents\n const assets = rawAssets.filter(\n (a) =>\n a.athenaConvertedType !== \"catalog\" && a.athenaOriginalType !== \"catalog\",\n );\n const items = assets.map(assetToMenuItem);\n\n return {\n items,\n pagination: {\n hasMore: rawAssets.length === limit,\n consumedCount: rawAssets.length,\n },\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// PROJECTS (Fetcher) — Project assets\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface TypedAssetsConfig {\n auth: MentionAuthContext;\n includeOnlyTypes: string[];\n limit?: number;\n}\n\nexport const fetchTypedAssets: SourceFn<TypedAssetsConfig> = async (\n context,\n) => {\n const { query, fetchState, sourceConfig } = context;\n const limit = sourceConfig.limit ?? 50;\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n const result = await querySimpleSearch(sourceConfig.auth, {\n query,\n limit,\n offset,\n includeTypes: sourceConfig.includeOnlyTypes,\n });\n\n return {\n items: result.items,\n pagination: { hasMore: result.hasMore },\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// TEAM (Fetcher) — Workspace members\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface TeamConfig {\n auth: MentionAuthContext;\n /** Shared member loader, so browsing Team and searching read one fetch. */\n loadTeam?: () => Promise<MenuItem[]>;\n}\n\n// Person mentions are keyed on email (`mention://person?id=<email>&email=…`),\n// so a member without one cannot be mentioned.\nfunction memberToMenuItem(\n member: WorkspaceMember & { email: string },\n): MenuItem {\n const displayName =\n [member.firstName, member.lastName].filter(Boolean).join(\" \").trim() ||\n member.email;\n\n return {\n id: member.email,\n name: displayName,\n type: \"user\" as const,\n fallbackIcon: \"user\",\n thumbnailUrl: member.avatarUrl || undefined,\n visibleInScopes: new Set<string>(),\n email: member.email,\n extra: { isAdmin: member.isAdmin },\n };\n}\n\nasync function queryTeam(auth: MentionAuthContext): Promise<MenuItem[]> {\n if (!auth.workspaceId) return [];\n const data = await fetchGraphQL<{ getUsersInWorkspace: WorkspaceMember[] }>(\n auth,\n WORKSPACE_MEMBERS_QUERY,\n { workspaceId: auth.workspaceId },\n );\n return (data.getUsersInWorkspace || [])\n .filter((member): member is WorkspaceMember & { email: string } =>\n Boolean(member.email),\n )\n .map(memberToMenuItem);\n}\n\n/**\n * One workspace-member fetch per store: every keystroke of a root search\n * reads the same list. A failed fetch is forgotten so the next one retries.\n */\nexport function createTeamLoader(\n auth: MentionAuthContext,\n): () => Promise<MenuItem[]> {\n let pending: Promise<MenuItem[]> | null = null;\n return () => {\n pending ??= queryTeam(auth).catch((error: unknown) => {\n pending = null;\n throw error;\n });\n return pending;\n };\n}\n\nexport const fetchTeam: SourceFn<TeamConfig> = async (context) => {\n const { auth, loadTeam } = context.sourceConfig;\n const items = await (loadTeam ? loadTeam() : queryTeam(auth));\n return { items, pagination: { hasMore: false } };\n};\n\n// Asset results never wait on the roster for longer than this; a slow roster\n// lands on a later keystroke, which reads the same pending request.\nconst TEAM_WAIT_MS = 1500;\n\nfunction withinTeamWait(members: Promise<MenuItem[]>): Promise<MenuItem[]> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<MenuItem[]>((resolve) => {\n timer = setTimeout(() => resolve([]), TEAM_WAIT_MS);\n });\n return Promise.race([members.catch(() => []), timeout]).finally(() =>\n clearTimeout(timer),\n );\n}\n\n/**\n * Add workspace members to a root search's first page, so `@<name>` finds\n * people beside assets (the cache filters them by the query). Like\n * `withProvidedTools`, `consumedCount` stays the server's row count so the\n * members never advance the asset offset; a failed member fetch leaves the\n * asset results alone.\n */\nexport function withTeam<TConfig>(\n source: SourceFn<TConfig>,\n loadTeam: () => Promise<MenuItem[]>,\n): SourceFn<TConfig> {\n return async (context) => {\n const meta = (context.fetchState.meta as FetchMetadata) || {};\n const isFirstPage = (meta.validatedCount || 0) === 0;\n const [result, team] = await Promise.all([\n source(context),\n isFirstPage && context.query?.trim()\n ? withinTeamWait(loadTeam())\n : Promise.resolve([]),\n ]);\n if (team.length === 0) return result;\n return {\n ...result,\n items: [...team, ...result.items],\n pagination: {\n ...result.pagination,\n hasMore: result.pagination?.hasMore ?? false,\n consumedCount: result.pagination?.consumedCount ?? result.items.length,\n },\n };\n };\n}\n\n// ══════════════════════════════════════════════════════════════════════\n// TOOLS / TOOLKITS (Fetcher) — Mentionable tool catalog\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface ToolCatalogConfig {\n auth: MentionAuthContext;\n}\n\n// getToolkitToToolsMapping is already filtered server-side for the\n// authenticated user (admin-only entries, beta allowlist, workspace registry),\n// so only mention/menu visibility is applied here.\nasync function queryToolCatalog(\n auth: MentionAuthContext,\n): Promise<ToolCatalogResult[\"getToolkitToToolsMapping\"]> {\n const data = await fetchGraphQL<ToolCatalogResult>(auth, TOOL_CATALOG_QUERY);\n return data.getToolkitToToolsMapping;\n}\n\nexport const fetchTools: SourceFn<ToolCatalogConfig> = async (context) => {\n const catalog = await queryToolCatalog(context.sourceConfig.auth);\n\n const items: MenuItem[] = catalog.tools\n .filter((tool) => tool.isMentionable)\n .map((tool) => ({\n id: tool.id,\n name: tool.name,\n type: \"tool\" as const,\n fallbackIcon: tool.icon,\n description: tool.description ?? undefined,\n visibleInScopes: new Set<string>(),\n ...(tool.adminOnly ? { extra: { isAdminOnly: true } } : {}),\n }));\n\n return { items, pagination: { hasMore: false } };\n};\n\nexport const fetchToolkits: SourceFn<ToolCatalogConfig> = async (context) => {\n const catalog = await queryToolCatalog(context.sourceConfig.auth);\n\n const items: MenuItem[] = catalog.toolkits\n .filter((toolkit) => toolkit.isMentionable && !toolkit.hideFromMenu)\n .map((toolkit) => ({\n id: toolkit.name,\n name: toolkit.displayName,\n type: \"toolkit\" as const,\n fallbackIcon: toolkit.icon,\n description: toolkit.description || undefined,\n visibleInScopes: new Set<string>(),\n ...(toolkit.onlyAdmin ? { extra: { isAdminOnly: true } } : {}),\n }));\n\n return { items, pagination: { hasMore: false } };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// DRIVES (Fetcher) — Drive catalog assets\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface DrivesConfig {\n auth: MentionAuthContext;\n}\n\nexport const fetchDrives: SourceFn<DrivesConfig> = async (context) => {\n const { fetchState, sourceConfig } = context;\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n const result = await querySimpleSearch(sourceConfig.auth, {\n limit: 50,\n offset,\n includeTypes: [\"catalog\"],\n });\n\n // Drive catalogs are navigation-only (navigate into them to see contents)\n const items: MenuItem[] = result.items.map((item) => ({\n ...item,\n type: \"drive_catalog\" as const,\n fallbackIcon: \"hard-drive\",\n isNavigationOnly: true,\n navigatesToScope: item.id,\n }));\n\n // Register folder contents source for each catalog\n const sources: SourceToRegister[] = items.map((item) => ({\n scope: item.id,\n sourceFn: fetchFolderContents,\n sourceConfig: { auth: sourceConfig.auth, limit: 50 },\n }));\n\n return {\n items,\n pagination: { hasMore: result.hasMore },\n sources,\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// GLOBAL SEARCH (Fetcher) — Aggregated search across all sources\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface GlobalSearchConfig {\n auth: MentionAuthContext;\n}\n\nexport const fetchGlobalSearch: SourceFn<GlobalSearchConfig> = async (\n context,\n) => {\n const { query, fetchState, sourceConfig } = context;\n if (!query?.trim()) return { items: [], pagination: { hasMore: false } };\n\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n const result = await querySimpleSearch(sourceConfig.auth, {\n query,\n limit: 50,\n offset,\n excludeTypes: [\"catalog\", \"session\"],\n });\n\n return {\n items: result.items,\n pagination: { hasMore: result.hasMore },\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// HOST-PROVIDED TOOLS (Transformer) — a host's own Tools / Toolkits list\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface ProvidedToolsConfig {\n getTools: () => readonly MentionTool[];\n type: MentionTool[\"type\"];\n}\n\n/** Menu items for a host-provided tool list, in the host's order. */\nexport function providedToolMenuItems(\n tools: readonly MentionTool[],\n type?: MentionTool[\"type\"],\n): MenuItem[] {\n return tools\n .filter((tool) => type === undefined || tool.type === type)\n .map((tool) => ({\n id: tool.id,\n name: tool.name,\n type: tool.type,\n fallbackIcon: tool.icon ?? (tool.type === \"toolkit\" ? \"Package\" : \"Wrench\"),\n description: tool.description,\n visibleInScopes: new Set<string>(),\n }));\n}\n\nexport const transformProvidedTools: SourceFn<ProvidedToolsConfig> = async (\n context,\n) => ({\n items: providedToolMenuItems(\n context.sourceConfig.getTools(),\n context.sourceConfig.type,\n ),\n pagination: { hasMore: false },\n});\n\n/**\n * Prepend a host's tool list to another source's items so a root query matches\n * them the way it matches assets (the cache filters by query and sorts\n * toolkits first). The wrapped source's offset bookkeeping is preserved:\n * `consumedCount` stays the number of rows the server returned, so the added\n * items never advance the next page's offset.\n */\nexport function withProvidedTools<TConfig>(\n source: SourceFn<TConfig>,\n getTools: () => readonly MentionTool[],\n): SourceFn<TConfig> {\n return async (context) => {\n const result = await source(context);\n return {\n ...result,\n items: [...providedToolMenuItems(getTools()), ...result.items],\n pagination: {\n ...result.pagination,\n hasMore: result.pagination?.hasMore ?? false,\n consumedCount: result.pagination?.consumedCount ?? result.items.length,\n },\n };\n };\n}\n"],"names":[],"mappings":";;;AAoCA,SAAS,gBAAgB,OAA8B;AACrD,QAAM,WAAW,MAAM,uBAAuB;AAC9C,QAAM,cAAc,MAAM,uBAAuB,MAAM;AACvD,SAAO;AAAA,IACL,IAAI,MAAM;AAAA,IACV,MAAM,MAAM,SAAS;AAAA,IACrB,MAAM,WAAW,WAAW;AAAA,IAC5B,cAAc,iBAAiB,WAAW;AAAA,IAC1C,cAAc,gBAAgB,WAAW;AAAA,IACzC,kBAAkB,WAAW,MAAM,KAAK;AAAA,IACxC,qCAAqB,IAAA;AAAA,IACrB,WAAW,MAAM,aAAa;AAAA,IAC9B,OAAO;AAAA,MACL,oBAAoB,MAAM;AAAA,MAC1B,qBAAqB,MAAM;AAAA,MAC3B,gBAAgB,MAAM;AAAA,IAAA;AAAA,EACxB;AAEJ;AAEA,eAAe,kBACb,MACA,MAOkD;;AAClD,QAAM,gBAAqC;AAAA,IACzC,SAAO,UAAK,UAAL,mBAAY,WAAU;AAAA,IAC7B,MAAM,KAAK,gBAAgB,CAAA;AAAA,IAC3B,SAAS,KAAK,gBAAgB,CAAA;AAAA,IAC9B,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,EAAA;AAGf,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,iBAAiB;AAAA,IACjB,sBAAsB;AAAA,IACtB,MAAM,EAAE,OAAO,cAAc,WAAW,OAAA;AAAA,IACxC,eAAe,EAAE,YAAY,OAAO,UAAU,MAAA;AAAA,EAAM;AAGtD,QAAM,OAAO,MAAM,aAEhB,MAAM,qBAAqB,EAAE,OAAO;AAEvC,QAAM,WAAS,UAAK,iBAAL,mBAAmB,WAAU,CAAA;AAC5C,SAAO;AAAA,IACL,OAAO,OAAO,IAAI,eAAe;AAAA,IACjC,SAAS,OAAO,WAAW,KAAK;AAAA,EAAA;AAEpC;AAWA,MAAM,gBAGF;AAAA,EACF,WAAW,EAAE,MAAM,aAAa,MAAM,QAAQ,OAAO,YAAA;AAAA,EACrD,QAAQ,EAAE,MAAM,UAAU,MAAM,aAAa,OAAO,gBAAA;AAAA,EACpD,UAAU;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAET,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAET,SAAS,EAAE,MAAM,WAAW,MAAM,UAAU,OAAO,iBAAA;AAAA,EACnD,OAAO,EAAE,MAAM,SAAS,MAAM,UAAU,OAAO,QAAA;AAAA,EAC/C,UAAU,EAAE,MAAM,YAAY,MAAM,WAAW,OAAO,WAAA;AAAA,EACtD,MAAM,EAAE,MAAM,QAAQ,MAAM,SAAS,OAAO,OAAA;AAAA,EAC5C,QAAQ,EAAE,MAAM,UAAU,MAAM,cAAc,OAAO,iBAAA;AACvD;AAEA,SAAS,mBAAmB,SAAiC;AAC3D,MAAI;AACF,UAAM,WAAW,IAAI,IAAI,QAAQ,GAAG,EAAE;AACtC,WAAO,QAAQ,YAAY,GAAG,QAAQ,KAAK,MAAM,QAAQ,KAAK;AAAA,EAChE,QAAQ;AACN,WAAO,QAAQ;AAAA,EACjB;AACF;AAEA,SAAS,kBAAkB,SAAmC;AAC5D,SAAO;AAAA,IACL,IAAI,eAAe,QAAQ,KAAK;AAAA,IAChC,MAAM,QAAQ,YAAY,iBAAiB,QAAQ;AAAA,IACnD,MAAM;AAAA,IACN,cAAc,iBAAiB,UAAU;AAAA,IACzC,cAAc;AAAA,IACd,iBAAiB,oBAAI,IAAI,CAAC,MAAM,CAAC;AAAA,IACjC,aAAa,mBAAmB,OAAO;AAAA,IACvC,KAAK,QAAQ;AAAA,IACb,aAAa,QAAQ,YACjB,mBAAmB,kBACnB,mBAAmB;AAAA,IACvB,OAAO;AAAA,MACL,OAAO,QAAQ;AAAA,MACf,OAAO,QAAQ;AAAA,MACf,WAAW,QAAQ;AAAA,IAAA;AAAA,EACrB;AAEJ;AAEO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AACF,GAGe;AACb,QAAM,eAAe,SAAS,IAAI,iBAAiB;AACnD,QAAM,gBAAgB,WACnB,OAAO,CAAC,QAAgB,cAAc,GAAG,CAAC,EAC1C,IAAI,CAAC,QAAgB;AACpB,UAAM,MAAM,cAAc,GAAG;AAC7B,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM,IAAI;AAAA,MACV,MAAM;AAAA,MACN,cAAc,IAAI;AAAA,MAClB,iBAAiB,oBAAI,IAAI,CAAC,MAAM,CAAC;AAAA,MACjC,kBAAkB,IAAI;AAAA,MACtB,kBAAkB;AAAA,MAClB,aAAa,mBAAmB;AAAA,IAAA;AAAA,EAEpC,CAAC;AAEH,SAAO,CAAC,GAAG,cAAc,GAAG,aAAa;AAC3C;AAEO,MAAM,0BAA0D,OACrE,YACG;AACH,QAAM,EAAE,iBAAiB;AACzB,QAAM,QAAQ,mBAAmB;AAAA,IAC/B,YAAY,aAAa;AAAA,IACzB,UAAU,aAAa,YAAA;AAAA,EAAY,CACpC;AAED,SAAO,EAAE,OAAO,YAAY,EAAE,SAAS,QAAM;AAC/C;AAWO,MAAM,cAAsC,OAAO,YAAY;AACpE,QAAM,EAAE,OAAO,YAAY,aAAA,IAAiB;AAC5C,QAAM,QAAQ,aAAa,SAAS;AACpC,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,QAAM,SAAS,MAAM,kBAAkB,aAAa,MAAM;AAAA,IACxD;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,CAAC,UAAU,WAAW,SAAS;AAAA,EAAA,CAC9C;AAED,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,YAAY,EAAE,SAAS,OAAO,QAAA;AAAA,EAAQ;AAE1C;AAWO,MAAM,iBAA4C,OAAO,YAAY;AAC1E,QAAM,EAAE,OAAO,YAAY,aAAA,IAAiB;AAC5C,QAAM,QAAQ,aAAa,SAAS;AACpC,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,QAAM,OAAO,MAAM,aAEhB,aAAa,MAAM,wBAAwB;AAAA,IAC5C;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,eAAe;AAAA,MACb,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,UAAU;AAAA,IAAA;AAAA,EACZ,CACD;AAED,QAAM,SAAS,KAAK,kCAAkC,CAAA;AACtD,QAAM,QAAQ,OAAO,IAAI,eAAe;AAExC,SAAO;AAAA,IACL;AAAA,IACA,YAAY,EAAE,SAAS,OAAO,WAAW,MAAA;AAAA,EAAM;AAEnD;AAWO,MAAM,eAAwC,OAAO,YAAY;AACtE,QAAM,EAAE,OAAO,YAAY,aAAA,IAAiB;AAC5C,QAAM,QAAQ,aAAa,SAAS;AACpC,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,QAAM,SAAS,MAAM,kBAAkB,aAAa,MAAM;AAAA,IACxD;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,CAAC,QAAQ;AAAA,EAAA,CACxB;AAED,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,YAAY,EAAE,SAAS,OAAO,QAAA;AAAA,EAAQ;AAE1C;AAWO,MAAM,sBAAsD,OACjE,YACG;AACH,QAAM,EAAE,OAAO,OAAO,YAAY,iBAAiB;AACnD,QAAM,QAAQ,aAAa,SAAS;AACpC,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAGtC,QAAM,iBAAiB,UAAU,mBAAmB,OAAO;AAE3D,QAAM,OAAO,MAAM,aAEhB,aAAa,MAAM,wBAAwB;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,eAAe;AAAA,MACb,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,GAAI,QAAQ,EAAE,OAAO,CAAC,EAAE,IAAI,QAAQ,OAAO,IAAI,KAAK,IAAA,CAAK,EAAA,IAAM,CAAA;AAAA,IAAC;AAAA,EAClE,CACD;AAED,QAAM,YAAY,KAAK,kCAAkC,CAAA;AAEzD,QAAM,SAAS,UAAU;AAAA,IACvB,CAAC,MACC,EAAE,wBAAwB,aAAa,EAAE,uBAAuB;AAAA,EAAA;AAEpE,QAAM,QAAQ,OAAO,IAAI,eAAe;AAExC,SAAO;AAAA,IACL;AAAA,IACA,YAAY;AAAA,MACV,SAAS,UAAU,WAAW;AAAA,MAC9B,eAAe,UAAU;AAAA,IAAA;AAAA,EAC3B;AAEJ;AAYO,MAAM,mBAAgD,OAC3D,YACG;AACH,QAAM,EAAE,OAAO,YAAY,aAAA,IAAiB;AAC5C,QAAM,QAAQ,aAAa,SAAS;AACpC,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,QAAM,SAAS,MAAM,kBAAkB,aAAa,MAAM;AAAA,IACxD;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,aAAa;AAAA,EAAA,CAC5B;AAED,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,YAAY,EAAE,SAAS,OAAO,QAAA;AAAA,EAAQ;AAE1C;AAcA,SAAS,iBACP,QACU;AACV,QAAM,cACJ,CAAC,OAAO,WAAW,OAAO,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAAE,KAAA,KAC9D,OAAO;AAET,SAAO;AAAA,IACL,IAAI,OAAO;AAAA,IACX,MAAM;AAAA,IACN,MAAM;AAAA,IACN,cAAc;AAAA,IACd,cAAc,OAAO,aAAa;AAAA,IAClC,qCAAqB,IAAA;AAAA,IACrB,OAAO,OAAO;AAAA,IACd,OAAO,EAAE,SAAS,OAAO,QAAA;AAAA,EAAQ;AAErC;AAEA,eAAe,UAAU,MAA+C;AACtE,MAAI,CAAC,KAAK,YAAa,QAAO,CAAA;AAC9B,QAAM,OAAO,MAAM;AAAA,IACjB;AAAA,IACA;AAAA,IACA,EAAE,aAAa,KAAK,YAAA;AAAA,EAAY;AAElC,UAAQ,KAAK,uBAAuB,CAAA,GACjC;AAAA,IAAO,CAAC,WACP,QAAQ,OAAO,KAAK;AAAA,EAAA,EAErB,IAAI,gBAAgB;AACzB;AAMO,SAAS,iBACd,MAC2B;AAC3B,MAAI,UAAsC;AAC1C,SAAO,MAAM;AACX,0BAAY,UAAU,IAAI,EAAE,MAAM,CAAC,UAAmB;AACpD,gBAAU;AACV,YAAM;AAAA,IACR,CAAC;AACD,WAAO;AAAA,EACT;AACF;AAEO,MAAM,YAAkC,OAAO,YAAY;AAChE,QAAM,EAAE,MAAM,SAAA,IAAa,QAAQ;AACnC,QAAM,QAAQ,OAAO,WAAW,SAAA,IAAa,UAAU,IAAI;AAC3D,SAAO,EAAE,OAAO,YAAY,EAAE,SAAS,QAAM;AAC/C;AAIA,MAAM,eAAe;AAErB,SAAS,eAAe,SAAmD;AACzE,MAAI;AACJ,QAAM,UAAU,IAAI,QAAoB,CAAC,YAAY;AACnD,YAAQ,WAAW,MAAM,QAAQ,CAAA,CAAE,GAAG,YAAY;AAAA,EACpD,CAAC;AACD,SAAO,QAAQ,KAAK,CAAC,QAAQ,MAAM,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE;AAAA,IAAQ,MAC9D,aAAa,KAAK;AAAA,EAAA;AAEtB;AASO,SAAS,SACd,QACA,UACmB;AACnB,SAAO,OAAO,YAAY;;AACxB,UAAM,OAAQ,QAAQ,WAAW,QAA0B,CAAA;AAC3D,UAAM,eAAe,KAAK,kBAAkB,OAAO;AACnD,UAAM,CAAC,QAAQ,IAAI,IAAI,MAAM,QAAQ,IAAI;AAAA,MACvC,OAAO,OAAO;AAAA,MACd,iBAAe,aAAQ,UAAR,mBAAe,UAC1B,eAAe,UAAU,IACzB,QAAQ,QAAQ,CAAA,CAAE;AAAA,IAAA,CACvB;AACD,QAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,CAAC,GAAG,MAAM,GAAG,OAAO,KAAK;AAAA,MAChC,YAAY;AAAA,QACV,GAAG,OAAO;AAAA,QACV,WAAS,YAAO,eAAP,mBAAmB,YAAW;AAAA,QACvC,iBAAe,YAAO,eAAP,mBAAmB,kBAAiB,OAAO,MAAM;AAAA,MAAA;AAAA,IAClE;AAAA,EAEJ;AACF;AAaA,eAAe,iBACb,MACwD;AACxD,QAAM,OAAO,MAAM,aAAgC,MAAM,kBAAkB;AAC3E,SAAO,KAAK;AACd;AAEO,MAAM,aAA0C,OAAO,YAAY;AACxE,QAAM,UAAU,MAAM,iBAAiB,QAAQ,aAAa,IAAI;AAEhE,QAAM,QAAoB,QAAQ,MAC/B,OAAO,CAAC,SAAS,KAAK,aAAa,EACnC,IAAI,CAAC,UAAU;AAAA,IACd,IAAI,KAAK;AAAA,IACT,MAAM,KAAK;AAAA,IACX,MAAM;AAAA,IACN,cAAc,KAAK;AAAA,IACnB,aAAa,KAAK,eAAe;AAAA,IACjC,qCAAqB,IAAA;AAAA,IACrB,GAAI,KAAK,YAAY,EAAE,OAAO,EAAE,aAAa,KAAA,MAAW,CAAA;AAAA,EAAC,EACzD;AAEJ,SAAO,EAAE,OAAO,YAAY,EAAE,SAAS,QAAM;AAC/C;AAEO,MAAM,gBAA6C,OAAO,YAAY;AAC3E,QAAM,UAAU,MAAM,iBAAiB,QAAQ,aAAa,IAAI;AAEhE,QAAM,QAAoB,QAAQ,SAC/B,OAAO,CAAC,YAAY,QAAQ,iBAAiB,CAAC,QAAQ,YAAY,EAClE,IAAI,CAAC,aAAa;AAAA,IACjB,IAAI,QAAQ;AAAA,IACZ,MAAM,QAAQ;AAAA,IACd,MAAM;AAAA,IACN,cAAc,QAAQ;AAAA,IACtB,aAAa,QAAQ,eAAe;AAAA,IACpC,qCAAqB,IAAA;AAAA,IACrB,GAAI,QAAQ,YAAY,EAAE,OAAO,EAAE,aAAa,KAAA,MAAW,CAAA;AAAA,EAAC,EAC5D;AAEJ,SAAO,EAAE,OAAO,YAAY,EAAE,SAAS,QAAM;AAC/C;AAUO,MAAM,cAAsC,OAAO,YAAY;AACpE,QAAM,EAAE,YAAY,aAAA,IAAiB;AACrC,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,QAAM,SAAS,MAAM,kBAAkB,aAAa,MAAM;AAAA,IACxD,OAAO;AAAA,IACP;AAAA,IACA,cAAc,CAAC,SAAS;AAAA,EAAA,CACzB;AAGD,QAAM,QAAoB,OAAO,MAAM,IAAI,CAAC,UAAU;AAAA,IACpD,GAAG;AAAA,IACH,MAAM;AAAA,IACN,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,kBAAkB,KAAK;AAAA,EAAA,EACvB;AAGF,QAAM,UAA8B,MAAM,IAAI,CAAC,UAAU;AAAA,IACvD,OAAO,KAAK;AAAA,IACZ,UAAU;AAAA,IACV,cAAc,EAAE,MAAM,aAAa,MAAM,OAAO,GAAA;AAAA,EAAG,EACnD;AAEF,SAAO;AAAA,IACL;AAAA,IACA,YAAY,EAAE,SAAS,OAAO,QAAA;AAAA,IAC9B;AAAA,EAAA;AAEJ;AAUO,MAAM,oBAAkD,OAC7D,YACG;AACH,QAAM,EAAE,OAAO,YAAY,aAAA,IAAiB;AAC5C,MAAI,EAAC,+BAAO,QAAQ,QAAO,EAAE,OAAO,CAAA,GAAI,YAAY,EAAE,SAAS,QAAM;AAErE,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,QAAM,SAAS,MAAM,kBAAkB,aAAa,MAAM;AAAA,IACxD;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA,cAAc,CAAC,WAAW,SAAS;AAAA,EAAA,CACpC;AAED,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,YAAY,EAAE,SAAS,OAAO,QAAA;AAAA,EAAQ;AAE1C;AAYO,SAAS,sBACd,OACA,MACY;AACZ,SAAO,MACJ,OAAO,CAAC,SAAS,SAAS,UAAa,KAAK,SAAS,IAAI,EACzD,IAAI,CAAC,UAAU;AAAA,IACd,IAAI,KAAK;AAAA,IACT,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,IACX,cAAc,KAAK,SAAS,KAAK,SAAS,YAAY,YAAY;AAAA,IAClE,aAAa,KAAK;AAAA,IAClB,qCAAqB,IAAA;AAAA,EAAY,EACjC;AACN;AAEO,MAAM,yBAAwD,OACnE,aACI;AAAA,EACJ,OAAO;AAAA,IACL,QAAQ,aAAa,SAAA;AAAA,IACrB,QAAQ,aAAa;AAAA,EAAA;AAAA,EAEvB,YAAY,EAAE,SAAS,MAAA;AACzB;AASO,SAAS,kBACd,QACA,UACmB;AACnB,SAAO,OAAO,YAAY;;AACxB,UAAM,SAAS,MAAM,OAAO,OAAO;AACnC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,CAAC,GAAG,sBAAsB,UAAU,GAAG,GAAG,OAAO,KAAK;AAAA,MAC7D,YAAY;AAAA,QACV,GAAG,OAAO;AAAA,QACV,WAAS,YAAO,eAAP,mBAAmB,YAAW;AAAA,QACvC,iBAAe,YAAO,eAAP,mBAAmB,kBAAiB,OAAO,MAAM;AAAA,MAAA;AAAA,IAClE;AAAA,EAEJ;AACF;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../../src/chat-ui/mentions/suggestions/data/sources/index.ts"],"sourcesContent":["/**\n * Mention data sources shared by every chat host.\n *\n * Each source function implements the SourceFn interface:\n * (context: SourceContext) => Promise<SourceResult>\n *\n * Sources are either:\n * - FETCHERS: Call GraphQL API (assets, folders, team, etc.)\n * - TRANSFORMERS: Return static/local data (root categories, host-provided items)\n */\n\nimport type {\n MenuItem,\n MentionTool,\n SourceFn,\n SourceResult,\n SourceToRegister,\n FetchMetadata,\n WebpageMention,\n} from \"../types\";\nimport { MentionMenuSection } from \"../types\";\nimport {\n fetchGraphQL,\n SIMPLE_SEARCH_QUERY,\n PAGINATED_ASSETS_QUERY,\n WORKSPACE_MEMBERS_QUERY,\n TOOL_CATALOG_QUERY,\n type MentionAuthContext,\n type AssetResult,\n type WorkspaceMember,\n type ToolCatalogResult,\n} from \"../api-client\";\nimport { assetTypeToThumb, assetTypeToIcon } from \"./asset-type-icons\";\n\n// ── Helpers ──\n\nfunction assetToMenuItem(asset: AssetResult): MenuItem {\n const isFolder = asset.athenaOriginalType === \"folder\";\n const displayType = asset.athenaConvertedType || asset.athenaOriginalType;\n return {\n id: asset.id,\n name: asset.title || \"Untitled\",\n type: isFolder ? \"folder\" : \"asset\",\n thumbnailUrl: assetTypeToThumb(displayType),\n fallbackIcon: assetTypeToIcon(displayType),\n navigatesToScope: isFolder ? asset.id : undefined,\n visibleInScopes: new Set(),\n updatedAt: asset.updatedAt ?? undefined,\n extra: {\n athenaOriginalType: asset.athenaOriginalType,\n athenaConvertedType: asset.athenaConvertedType,\n parentFolderId: asset.parentFolderId,\n },\n };\n}\n\nasync function querySimpleSearch(\n auth: MentionAuthContext,\n opts: {\n query?: string;\n limit: number;\n offset: number;\n includeTypes?: string[];\n excludeTypes?: string[];\n },\n): Promise<{ items: MenuItem[]; hasMore: boolean }> {\n const searchRequest: Record<string, any> = {\n query: opts.query?.trim() || \"\",\n type: opts.includeTypes || [],\n notType: opts.excludeTypes || [],\n limit: opts.limit,\n offset: opts.offset,\n };\n\n const input = {\n searchRequest,\n returnFullAsset: true,\n shouldCalculateTotal: false,\n sort: { field: \"UPDATED_AT\", direction: \"DESC\" },\n filterColumns: { isArchived: false, isHidden: false },\n };\n\n const data = await fetchGraphQL<{\n simpleSearch: { assets: AssetResult[]; totalCount: number };\n }>(auth, SIMPLE_SEARCH_QUERY, { input });\n\n const assets = data.simpleSearch?.assets || [];\n return {\n items: assets.map(assetToMenuItem),\n hasMore: assets.length === opts.limit,\n };\n}\n\n// ══════════════════════════════════════════════════════════════════════\n// ROOT CATEGORIES (Transformer)\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface RootCategoriesConfig {\n categories: string[];\n getWebpages: () => readonly WebpageMention[];\n}\n\nconst CATEGORY_DEFS: Record<\n string,\n { name: string; icon: string; scope: string }\n> = {\n favorites: { name: \"Favorites\", icon: \"star\", scope: \"favorites\" },\n assets: { name: \"Assets\", icon: \"file-text\", scope: \"athena_assets\" },\n projects: {\n name: \"Projects\",\n icon: \"folder-kanban\",\n scope: \"athena_projects\",\n },\n browse_profiles: {\n name: \"Browse Profiles\",\n icon: \"globe\",\n scope: \"athena_browse_profiles\",\n },\n folders: { name: \"Folders\", icon: \"folder\", scope: \"athena_folders\" },\n tools: { name: \"Tools\", icon: \"wrench\", scope: \"tools\" },\n toolkits: { name: \"Toolkits\", icon: \"package\", scope: \"toolkits\" },\n team: { name: \"Team\", icon: \"users\", scope: \"team\" },\n drives: { name: \"Drives\", icon: \"hard-drive\", scope: \"drive_catalogs\" },\n};\n\nfunction webpageDescription(webpage: WebpageMention): string {\n try {\n const hostname = new URL(webpage.url).hostname;\n return webpage.isCurrent ? `${webpage.title} · ${hostname}` : hostname;\n } catch {\n return webpage.title;\n }\n}\n\nfunction webpageToMenuItem(webpage: WebpageMention): MenuItem {\n return {\n id: `webpage-tab-${webpage.tabId}`,\n name: webpage.isCurrent ? \"This webpage\" : webpage.title,\n type: \"tab\",\n thumbnailUrl: assetTypeToThumb(\"web_page\"),\n fallbackIcon: \"globe\",\n visibleInScopes: new Set([\"root\"]),\n description: webpageDescription(webpage),\n url: webpage.url,\n menuSection: webpage.isCurrent\n ? MentionMenuSection.CURRENT_WEBPAGE\n : MentionMenuSection.OTHER_WEBPAGES,\n extra: {\n tabId: webpage.tabId,\n title: webpage.title,\n isCurrent: webpage.isCurrent,\n },\n };\n}\n\nexport function buildRootMenuItems({\n categories,\n webpages,\n}: {\n categories: readonly string[];\n webpages: readonly WebpageMention[];\n}): MenuItem[] {\n const webpageItems = webpages.map(webpageToMenuItem);\n const categoryItems = categories\n .filter((cat: string) => CATEGORY_DEFS[cat])\n .map((cat: string) => {\n const def = CATEGORY_DEFS[cat];\n return {\n id: cat,\n name: def.name,\n type: \"menu\" as const,\n fallbackIcon: def.icon,\n visibleInScopes: new Set([\"root\"]),\n navigatesToScope: def.scope,\n isNavigationOnly: true,\n menuSection: MentionMenuSection.LIBRARY,\n };\n });\n\n return [...webpageItems, ...categoryItems];\n}\n\nexport const transformRootCategories: SourceFn<RootCategoriesConfig> = async (\n context,\n) => {\n const { sourceConfig } = context;\n const items = buildRootMenuItems({\n categories: sourceConfig.categories,\n webpages: sourceConfig.getWebpages(),\n });\n\n return { items, pagination: { hasMore: false } };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// ASSETS (Fetcher) — All non-folder assets via SimpleSearch\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface AssetsConfig {\n auth: MentionAuthContext;\n limit?: number;\n}\n\nexport const fetchAssets: SourceFn<AssetsConfig> = async (context) => {\n const { query, fetchState, sourceConfig } = context;\n const limit = sourceConfig.limit ?? 50;\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n const result = await querySimpleSearch(sourceConfig.auth, {\n query,\n limit,\n offset,\n excludeTypes: [\"folder\", \"catalog\", \"session\"],\n });\n\n return {\n items: result.items,\n pagination: { hasMore: result.hasMore },\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// FAVORITES (Fetcher) — Favorited assets\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface FavoritesConfig {\n auth: MentionAuthContext;\n limit?: number;\n}\n\nexport const fetchFavorites: SourceFn<FavoritesConfig> = async (context) => {\n const { query, fetchState, sourceConfig } = context;\n const limit = sourceConfig.limit ?? 50;\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n const data = await fetchGraphQL<{\n getPaginatedAssetsForWorkspace: AssetResult[];\n }>(sourceConfig.auth, PAGINATED_ASSETS_QUERY, {\n limit,\n offset,\n parentFolderId: null,\n filterTypes: null,\n filterColumns: {\n isFavorited: true,\n isArchived: false,\n isHidden: false,\n },\n });\n\n const assets = data.getPaginatedAssetsForWorkspace || [];\n const items = assets.map(assetToMenuItem);\n\n return {\n items,\n pagination: { hasMore: assets.length === limit },\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// FOLDERS (Fetcher) — All folders as flat list\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface FoldersConfig {\n auth: MentionAuthContext;\n limit?: number;\n}\n\nexport const fetchFolders: SourceFn<FoldersConfig> = async (context) => {\n const { query, fetchState, sourceConfig } = context;\n const limit = sourceConfig.limit ?? 50;\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n const result = await querySimpleSearch(sourceConfig.auth, {\n query,\n limit,\n offset,\n includeTypes: [\"folder\"],\n });\n\n return {\n items: result.items,\n pagination: { hasMore: result.hasMore },\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// FOLDER CONTENTS (Fetcher) — Contents of a specific folder\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface FolderContentsConfig {\n auth: MentionAuthContext;\n limit?: number;\n}\n\nexport const fetchFolderContents: SourceFn<FolderContentsConfig> = async (\n context,\n) => {\n const { scope, query, fetchState, sourceConfig } = context;\n const limit = sourceConfig.limit ?? 50;\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n // Scope IS the folder ID (or 'internal_drive' for root)\n const parentFolderId = scope === \"internal_drive\" ? null : scope;\n\n const data = await fetchGraphQL<{\n getPaginatedAssetsForWorkspace: AssetResult[];\n }>(sourceConfig.auth, PAGINATED_ASSETS_QUERY, {\n limit,\n offset,\n parentFolderId,\n filterTypes: null,\n filterColumns: {\n isArchived: false,\n isHidden: false,\n ...(query ? { title: [{ op: \"LIKE\", value: `%${query}%` }] } : {}),\n },\n });\n\n const rawAssets = data.getPaginatedAssetsForWorkspace || [];\n // Exclude catalogs from folder contents\n const assets = rawAssets.filter(\n (a) =>\n a.athenaConvertedType !== \"catalog\" && a.athenaOriginalType !== \"catalog\",\n );\n const items = assets.map(assetToMenuItem);\n\n return {\n items,\n pagination: {\n hasMore: rawAssets.length === limit,\n consumedCount: rawAssets.length,\n },\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// PROJECTS (Fetcher) — Project assets\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface TypedAssetsConfig {\n auth: MentionAuthContext;\n includeOnlyTypes: string[];\n limit?: number;\n}\n\nexport const fetchTypedAssets: SourceFn<TypedAssetsConfig> = async (\n context,\n) => {\n const { query, fetchState, sourceConfig } = context;\n const limit = sourceConfig.limit ?? 50;\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n const result = await querySimpleSearch(sourceConfig.auth, {\n query,\n limit,\n offset,\n includeTypes: sourceConfig.includeOnlyTypes,\n });\n\n return {\n items: result.items,\n pagination: { hasMore: result.hasMore },\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// TEAM (Fetcher) — Workspace members\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface TeamConfig {\n auth: MentionAuthContext;\n /** Shared member loader, so browsing Team and searching read one fetch. */\n loadTeam?: () => Promise<MenuItem[]>;\n}\n\n// Person mentions are keyed on email (`mention://person?id=<email>&email=…`),\n// so a member without one cannot be mentioned.\nfunction memberToMenuItem(\n member: WorkspaceMember & { email: string },\n): MenuItem {\n const displayName =\n [member.firstName, member.lastName].filter(Boolean).join(\" \").trim() ||\n member.email;\n\n return {\n id: member.email,\n name: displayName,\n type: \"user\" as const,\n fallbackIcon: \"user\",\n thumbnailUrl: member.avatarUrl || undefined,\n visibleInScopes: new Set<string>(),\n email: member.email,\n extra: { isAdmin: member.isAdmin },\n };\n}\n\nasync function queryTeam(auth: MentionAuthContext): Promise<MenuItem[]> {\n if (!auth.workspaceId) return [];\n const data = await fetchGraphQL<{ getUsersInWorkspace: WorkspaceMember[] }>(\n auth,\n WORKSPACE_MEMBERS_QUERY,\n { workspaceId: auth.workspaceId },\n );\n return (data.getUsersInWorkspace || [])\n .filter((member): member is WorkspaceMember & { email: string } =>\n Boolean(member.email),\n )\n .map(memberToMenuItem);\n}\n\n/**\n * One workspace-member fetch per store: every keystroke of a root search\n * reads the same list. A failed fetch is forgotten so the next one retries.\n */\nexport function createTeamLoader(\n auth: MentionAuthContext,\n): () => Promise<MenuItem[]> {\n let pending: Promise<MenuItem[]> | null = null;\n return () => {\n pending ??= queryTeam(auth).catch((error: unknown) => {\n pending = null;\n throw error;\n });\n return pending;\n };\n}\n\nexport const fetchTeam: SourceFn<TeamConfig> = async (context) => {\n const { auth, loadTeam } = context.sourceConfig;\n const items = await (loadTeam ? loadTeam() : queryTeam(auth));\n return { items, pagination: { hasMore: false } };\n};\n\n// Asset results never wait on the roster for longer than this; a slow roster\n// lands on a later keystroke, which reads the same pending request.\nconst TEAM_WAIT_MS = 1500;\n\nfunction withinTeamWait(members: Promise<MenuItem[]>): Promise<MenuItem[]> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<MenuItem[]>((resolve) => {\n timer = setTimeout(() => resolve([]), TEAM_WAIT_MS);\n });\n return Promise.race([members.catch(() => []), timeout]).finally(() =>\n clearTimeout(timer),\n );\n}\n\n/**\n * Add workspace members to a root search's first page, so `@<name>` finds\n * people beside assets (the cache filters them by the query). Like\n * `withProvidedTools`, `consumedCount` stays the server's row count so the\n * members never advance the asset offset; a failed member fetch leaves the\n * asset results alone.\n */\nexport function withTeam<TConfig>(\n source: SourceFn<TConfig>,\n loadTeam: () => Promise<MenuItem[]>,\n): SourceFn<TConfig> {\n // Members come from Athena: while it can't be reached, only what the wrapped source can list\n // without it stands in (a host's own tools).\n return keepOfflineItems(source, async (context) => {\n const meta = (context.fetchState.meta as FetchMetadata) || {};\n const isFirstPage = (meta.validatedCount || 0) === 0;\n const [result, team] = await Promise.all([\n source(context),\n isFirstPage && context.query?.trim()\n ? withinTeamWait(loadTeam())\n : Promise.resolve([]),\n ]);\n if (team.length === 0) return result;\n return {\n ...result,\n items: [...team, ...result.items],\n pagination: {\n ...result.pagination,\n hasMore: result.pagination?.hasMore ?? false,\n consumedCount: result.pagination?.consumedCount ?? result.items.length,\n },\n };\n });\n}\n\n// ══════════════════════════════════════════════════════════════════════\n// TOOLS / TOOLKITS (Fetcher) — Mentionable tool catalog\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface ToolCatalogConfig {\n auth: MentionAuthContext;\n}\n\n// getToolkitToToolsMapping is already filtered server-side for the\n// authenticated user (admin-only entries, beta allowlist, workspace registry),\n// so only mention/menu visibility is applied here.\nasync function queryToolCatalog(\n auth: MentionAuthContext,\n): Promise<ToolCatalogResult[\"getToolkitToToolsMapping\"]> {\n const data = await fetchGraphQL<ToolCatalogResult>(auth, TOOL_CATALOG_QUERY);\n return data.getToolkitToToolsMapping;\n}\n\nexport const fetchTools: SourceFn<ToolCatalogConfig> = async (context) => {\n const catalog = await queryToolCatalog(context.sourceConfig.auth);\n\n const items: MenuItem[] = catalog.tools\n .filter((tool) => tool.isMentionable)\n .map((tool) => ({\n id: tool.id,\n name: tool.name,\n type: \"tool\" as const,\n fallbackIcon: tool.icon,\n description: tool.description ?? undefined,\n visibleInScopes: new Set<string>(),\n ...(tool.adminOnly ? { extra: { isAdminOnly: true } } : {}),\n }));\n\n return { items, pagination: { hasMore: false } };\n};\n\nexport const fetchToolkits: SourceFn<ToolCatalogConfig> = async (context) => {\n const catalog = await queryToolCatalog(context.sourceConfig.auth);\n\n const items: MenuItem[] = catalog.toolkits\n .filter((toolkit) => toolkit.isMentionable && !toolkit.hideFromMenu)\n .map((toolkit) => ({\n id: toolkit.name,\n name: toolkit.displayName,\n type: \"toolkit\" as const,\n fallbackIcon: toolkit.icon,\n description: toolkit.description || undefined,\n visibleInScopes: new Set<string>(),\n ...(toolkit.onlyAdmin ? { extra: { isAdminOnly: true } } : {}),\n }));\n\n return { items, pagination: { hasMore: false } };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// DRIVES (Fetcher) — Drive catalog assets\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface DrivesConfig {\n auth: MentionAuthContext;\n}\n\nexport const fetchDrives: SourceFn<DrivesConfig> = async (context) => {\n const { fetchState, sourceConfig } = context;\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n const result = await querySimpleSearch(sourceConfig.auth, {\n limit: 50,\n offset,\n includeTypes: [\"catalog\"],\n });\n\n // Drive catalogs are navigation-only (navigate into them to see contents)\n const items: MenuItem[] = result.items.map((item) => ({\n ...item,\n type: \"drive_catalog\" as const,\n fallbackIcon: \"hard-drive\",\n isNavigationOnly: true,\n navigatesToScope: item.id,\n }));\n\n // Register folder contents source for each catalog\n const sources: SourceToRegister[] = items.map((item) => ({\n scope: item.id,\n sourceFn: fetchFolderContents,\n sourceConfig: { auth: sourceConfig.auth, limit: 50 },\n }));\n\n return {\n items,\n pagination: { hasMore: result.hasMore },\n sources,\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// GLOBAL SEARCH (Fetcher) — Aggregated search across all sources\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface GlobalSearchConfig {\n auth: MentionAuthContext;\n}\n\nexport const fetchGlobalSearch: SourceFn<GlobalSearchConfig> = async (\n context,\n) => {\n const { query, fetchState, sourceConfig } = context;\n if (!query?.trim()) return { items: [], pagination: { hasMore: false } };\n\n const meta = (fetchState.meta as FetchMetadata) || {};\n const offset = meta.validatedCount || 0;\n\n const result = await querySimpleSearch(sourceConfig.auth, {\n query,\n limit: 50,\n offset,\n excludeTypes: [\"catalog\", \"session\"],\n });\n\n return {\n items: result.items,\n pagination: { hasMore: result.hasMore },\n };\n};\n\n// ══════════════════════════════════════════════════════════════════════\n// HOST-PROVIDED TOOLS (Transformer) — a host's own Tools / Toolkits list\n// ══════════════════════════════════════════════════════════════════════\n\nexport interface ProvidedToolsConfig {\n getTools: () => readonly MentionTool[];\n type: MentionTool[\"type\"];\n}\n\n/** Menu items for a host-provided tool list, in the host's order. */\nexport function providedToolMenuItems(\n tools: readonly MentionTool[],\n type?: MentionTool[\"type\"],\n): MenuItem[] {\n return tools\n .filter((tool) => type === undefined || tool.type === type)\n .map((tool) => ({\n id: tool.id,\n name: tool.name,\n type: tool.type,\n fallbackIcon: tool.icon ?? (tool.type === \"toolkit\" ? \"Package\" : \"Wrench\"),\n description: tool.description,\n visibleInScopes: new Set<string>(),\n }));\n}\n\nexport const transformProvidedTools: SourceFn<ProvidedToolsConfig> = async (\n context,\n) => ({\n items: providedToolMenuItems(\n context.sourceConfig.getTools(),\n context.sourceConfig.type,\n ),\n pagination: { hasMore: false },\n});\n\n/**\n * Prepend a host's tool list to another source's items so a root query matches\n * them the way it matches assets (the cache filters by query and sorts\n * toolkits first). The wrapped source's offset bookkeeping is preserved:\n * `consumedCount` stays the number of rows the server returned, so the added\n * items never advance the next page's offset.\n */\nexport function withProvidedTools<TConfig>(\n source: SourceFn<TConfig>,\n getTools: () => readonly MentionTool[],\n): SourceFn<TConfig> {\n const wrapped: SourceFn<TConfig> = async (context) => {\n const result = await source(context);\n return {\n ...result,\n items: [...providedToolMenuItems(getTools()), ...result.items],\n pagination: {\n ...result.pagination,\n hasMore: result.pagination?.hasMore ?? false,\n consumedCount: result.pagination?.consumedCount ?? result.items.length,\n },\n };\n };\n // The host's tools are the host's own: while Athena can't be reached, a search still finds them.\n OFFLINE_ITEMS.set(wrapped as SourceFn, () => providedToolMenuItems(getTools()));\n return wrapped;\n}\n\n/**\n * What a source that asks Athena can still list while Athena can't be reached: the host's own items\n * it carries (a host's tool list), by source. The source itself is never called then.\n */\nconst OFFLINE_ITEMS = new WeakMap<SourceFn, () => MenuItem[]>();\n\n/** `wrapped` keeps what `inner` lists without Athena (a wrapper that adds Athena's items alone). */\nfunction keepOfflineItems<TConfig>(\n inner: SourceFn<TConfig>,\n wrapped: SourceFn<TConfig>,\n): SourceFn<TConfig> {\n const offline = OFFLINE_ITEMS.get(inner as SourceFn);\n if (offline) OFFLINE_ITEMS.set(wrapped as SourceFn, offline);\n return wrapped;\n}\n\n/**\n * The host's own items a source asking Athena can still list while Athena can't be reached (a\n * root search's host tools), unfiltered; none for a source that holds no such items.\n */\nexport function offlineItemsOf(sourceFn: SourceFn): MenuItem[] {\n return OFFLINE_ITEMS.get(sourceFn)?.() ?? [];\n}\n\n// ══════════════════════════════════════════════════════════════════════\n// LOCAL SOURCES — what a scope can show while Athena can't be reached\n// ══════════════════════════════════════════════════════════════════════\n\n/**\n * The transformers: they read only what the host already holds (its tabs, its\n * own tool list), so their scopes keep working while Athena can't be reached.\n * Every other source asks Athena.\n */\nconst LOCAL_SOURCES: ReadonlySet<SourceFn> = new Set<SourceFn>([\n transformRootCategories,\n transformProvidedTools,\n]);\n\n/** Whether a scope's source asks Athena for its items (a fetcher, not a transformer). */\nexport function sourceAsksAthena(sourceFn: SourceFn): boolean {\n return !LOCAL_SOURCES.has(sourceFn);\n}\n"],"names":[],"mappings":";;;AAoCA,SAAS,gBAAgB,OAA8B;AACrD,QAAM,WAAW,MAAM,uBAAuB;AAC9C,QAAM,cAAc,MAAM,uBAAuB,MAAM;AACvD,SAAO;AAAA,IACL,IAAI,MAAM;AAAA,IACV,MAAM,MAAM,SAAS;AAAA,IACrB,MAAM,WAAW,WAAW;AAAA,IAC5B,cAAc,iBAAiB,WAAW;AAAA,IAC1C,cAAc,gBAAgB,WAAW;AAAA,IACzC,kBAAkB,WAAW,MAAM,KAAK;AAAA,IACxC,qCAAqB,IAAA;AAAA,IACrB,WAAW,MAAM,aAAa;AAAA,IAC9B,OAAO;AAAA,MACL,oBAAoB,MAAM;AAAA,MAC1B,qBAAqB,MAAM;AAAA,MAC3B,gBAAgB,MAAM;AAAA,IAAA;AAAA,EACxB;AAEJ;AAEA,eAAe,kBACb,MACA,MAOkD;;AAClD,QAAM,gBAAqC;AAAA,IACzC,SAAO,UAAK,UAAL,mBAAY,WAAU;AAAA,IAC7B,MAAM,KAAK,gBAAgB,CAAA;AAAA,IAC3B,SAAS,KAAK,gBAAgB,CAAA;AAAA,IAC9B,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,EAAA;AAGf,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,iBAAiB;AAAA,IACjB,sBAAsB;AAAA,IACtB,MAAM,EAAE,OAAO,cAAc,WAAW,OAAA;AAAA,IACxC,eAAe,EAAE,YAAY,OAAO,UAAU,MAAA;AAAA,EAAM;AAGtD,QAAM,OAAO,MAAM,aAEhB,MAAM,qBAAqB,EAAE,OAAO;AAEvC,QAAM,WAAS,UAAK,iBAAL,mBAAmB,WAAU,CAAA;AAC5C,SAAO;AAAA,IACL,OAAO,OAAO,IAAI,eAAe;AAAA,IACjC,SAAS,OAAO,WAAW,KAAK;AAAA,EAAA;AAEpC;AAWA,MAAM,gBAGF;AAAA,EACF,WAAW,EAAE,MAAM,aAAa,MAAM,QAAQ,OAAO,YAAA;AAAA,EACrD,QAAQ,EAAE,MAAM,UAAU,MAAM,aAAa,OAAO,gBAAA;AAAA,EACpD,UAAU;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAET,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAET,SAAS,EAAE,MAAM,WAAW,MAAM,UAAU,OAAO,iBAAA;AAAA,EACnD,OAAO,EAAE,MAAM,SAAS,MAAM,UAAU,OAAO,QAAA;AAAA,EAC/C,UAAU,EAAE,MAAM,YAAY,MAAM,WAAW,OAAO,WAAA;AAAA,EACtD,MAAM,EAAE,MAAM,QAAQ,MAAM,SAAS,OAAO,OAAA;AAAA,EAC5C,QAAQ,EAAE,MAAM,UAAU,MAAM,cAAc,OAAO,iBAAA;AACvD;AAEA,SAAS,mBAAmB,SAAiC;AAC3D,MAAI;AACF,UAAM,WAAW,IAAI,IAAI,QAAQ,GAAG,EAAE;AACtC,WAAO,QAAQ,YAAY,GAAG,QAAQ,KAAK,MAAM,QAAQ,KAAK;AAAA,EAChE,QAAQ;AACN,WAAO,QAAQ;AAAA,EACjB;AACF;AAEA,SAAS,kBAAkB,SAAmC;AAC5D,SAAO;AAAA,IACL,IAAI,eAAe,QAAQ,KAAK;AAAA,IAChC,MAAM,QAAQ,YAAY,iBAAiB,QAAQ;AAAA,IACnD,MAAM;AAAA,IACN,cAAc,iBAAiB,UAAU;AAAA,IACzC,cAAc;AAAA,IACd,iBAAiB,oBAAI,IAAI,CAAC,MAAM,CAAC;AAAA,IACjC,aAAa,mBAAmB,OAAO;AAAA,IACvC,KAAK,QAAQ;AAAA,IACb,aAAa,QAAQ,YACjB,mBAAmB,kBACnB,mBAAmB;AAAA,IACvB,OAAO;AAAA,MACL,OAAO,QAAQ;AAAA,MACf,OAAO,QAAQ;AAAA,MACf,WAAW,QAAQ;AAAA,IAAA;AAAA,EACrB;AAEJ;AAEO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AACF,GAGe;AACb,QAAM,eAAe,SAAS,IAAI,iBAAiB;AACnD,QAAM,gBAAgB,WACnB,OAAO,CAAC,QAAgB,cAAc,GAAG,CAAC,EAC1C,IAAI,CAAC,QAAgB;AACpB,UAAM,MAAM,cAAc,GAAG;AAC7B,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM,IAAI;AAAA,MACV,MAAM;AAAA,MACN,cAAc,IAAI;AAAA,MAClB,iBAAiB,oBAAI,IAAI,CAAC,MAAM,CAAC;AAAA,MACjC,kBAAkB,IAAI;AAAA,MACtB,kBAAkB;AAAA,MAClB,aAAa,mBAAmB;AAAA,IAAA;AAAA,EAEpC,CAAC;AAEH,SAAO,CAAC,GAAG,cAAc,GAAG,aAAa;AAC3C;AAEO,MAAM,0BAA0D,OACrE,YACG;AACH,QAAM,EAAE,iBAAiB;AACzB,QAAM,QAAQ,mBAAmB;AAAA,IAC/B,YAAY,aAAa;AAAA,IACzB,UAAU,aAAa,YAAA;AAAA,EAAY,CACpC;AAED,SAAO,EAAE,OAAO,YAAY,EAAE,SAAS,QAAM;AAC/C;AAWO,MAAM,cAAsC,OAAO,YAAY;AACpE,QAAM,EAAE,OAAO,YAAY,aAAA,IAAiB;AAC5C,QAAM,QAAQ,aAAa,SAAS;AACpC,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,QAAM,SAAS,MAAM,kBAAkB,aAAa,MAAM;AAAA,IACxD;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,CAAC,UAAU,WAAW,SAAS;AAAA,EAAA,CAC9C;AAED,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,YAAY,EAAE,SAAS,OAAO,QAAA;AAAA,EAAQ;AAE1C;AAWO,MAAM,iBAA4C,OAAO,YAAY;AAC1E,QAAM,EAAE,OAAO,YAAY,aAAA,IAAiB;AAC5C,QAAM,QAAQ,aAAa,SAAS;AACpC,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,QAAM,OAAO,MAAM,aAEhB,aAAa,MAAM,wBAAwB;AAAA,IAC5C;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,eAAe;AAAA,MACb,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,UAAU;AAAA,IAAA;AAAA,EACZ,CACD;AAED,QAAM,SAAS,KAAK,kCAAkC,CAAA;AACtD,QAAM,QAAQ,OAAO,IAAI,eAAe;AAExC,SAAO;AAAA,IACL;AAAA,IACA,YAAY,EAAE,SAAS,OAAO,WAAW,MAAA;AAAA,EAAM;AAEnD;AAWO,MAAM,eAAwC,OAAO,YAAY;AACtE,QAAM,EAAE,OAAO,YAAY,aAAA,IAAiB;AAC5C,QAAM,QAAQ,aAAa,SAAS;AACpC,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,QAAM,SAAS,MAAM,kBAAkB,aAAa,MAAM;AAAA,IACxD;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,CAAC,QAAQ;AAAA,EAAA,CACxB;AAED,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,YAAY,EAAE,SAAS,OAAO,QAAA;AAAA,EAAQ;AAE1C;AAWO,MAAM,sBAAsD,OACjE,YACG;AACH,QAAM,EAAE,OAAO,OAAO,YAAY,iBAAiB;AACnD,QAAM,QAAQ,aAAa,SAAS;AACpC,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAGtC,QAAM,iBAAiB,UAAU,mBAAmB,OAAO;AAE3D,QAAM,OAAO,MAAM,aAEhB,aAAa,MAAM,wBAAwB;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,eAAe;AAAA,MACb,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,GAAI,QAAQ,EAAE,OAAO,CAAC,EAAE,IAAI,QAAQ,OAAO,IAAI,KAAK,IAAA,CAAK,EAAA,IAAM,CAAA;AAAA,IAAC;AAAA,EAClE,CACD;AAED,QAAM,YAAY,KAAK,kCAAkC,CAAA;AAEzD,QAAM,SAAS,UAAU;AAAA,IACvB,CAAC,MACC,EAAE,wBAAwB,aAAa,EAAE,uBAAuB;AAAA,EAAA;AAEpE,QAAM,QAAQ,OAAO,IAAI,eAAe;AAExC,SAAO;AAAA,IACL;AAAA,IACA,YAAY;AAAA,MACV,SAAS,UAAU,WAAW;AAAA,MAC9B,eAAe,UAAU;AAAA,IAAA;AAAA,EAC3B;AAEJ;AAYO,MAAM,mBAAgD,OAC3D,YACG;AACH,QAAM,EAAE,OAAO,YAAY,aAAA,IAAiB;AAC5C,QAAM,QAAQ,aAAa,SAAS;AACpC,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,QAAM,SAAS,MAAM,kBAAkB,aAAa,MAAM;AAAA,IACxD;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,aAAa;AAAA,EAAA,CAC5B;AAED,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,YAAY,EAAE,SAAS,OAAO,QAAA;AAAA,EAAQ;AAE1C;AAcA,SAAS,iBACP,QACU;AACV,QAAM,cACJ,CAAC,OAAO,WAAW,OAAO,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAAE,KAAA,KAC9D,OAAO;AAET,SAAO;AAAA,IACL,IAAI,OAAO;AAAA,IACX,MAAM;AAAA,IACN,MAAM;AAAA,IACN,cAAc;AAAA,IACd,cAAc,OAAO,aAAa;AAAA,IAClC,qCAAqB,IAAA;AAAA,IACrB,OAAO,OAAO;AAAA,IACd,OAAO,EAAE,SAAS,OAAO,QAAA;AAAA,EAAQ;AAErC;AAEA,eAAe,UAAU,MAA+C;AACtE,MAAI,CAAC,KAAK,YAAa,QAAO,CAAA;AAC9B,QAAM,OAAO,MAAM;AAAA,IACjB;AAAA,IACA;AAAA,IACA,EAAE,aAAa,KAAK,YAAA;AAAA,EAAY;AAElC,UAAQ,KAAK,uBAAuB,CAAA,GACjC;AAAA,IAAO,CAAC,WACP,QAAQ,OAAO,KAAK;AAAA,EAAA,EAErB,IAAI,gBAAgB;AACzB;AAMO,SAAS,iBACd,MAC2B;AAC3B,MAAI,UAAsC;AAC1C,SAAO,MAAM;AACX,0BAAY,UAAU,IAAI,EAAE,MAAM,CAAC,UAAmB;AACpD,gBAAU;AACV,YAAM;AAAA,IACR,CAAC;AACD,WAAO;AAAA,EACT;AACF;AAEO,MAAM,YAAkC,OAAO,YAAY;AAChE,QAAM,EAAE,MAAM,SAAA,IAAa,QAAQ;AACnC,QAAM,QAAQ,OAAO,WAAW,SAAA,IAAa,UAAU,IAAI;AAC3D,SAAO,EAAE,OAAO,YAAY,EAAE,SAAS,QAAM;AAC/C;AAIA,MAAM,eAAe;AAErB,SAAS,eAAe,SAAmD;AACzE,MAAI;AACJ,QAAM,UAAU,IAAI,QAAoB,CAAC,YAAY;AACnD,YAAQ,WAAW,MAAM,QAAQ,CAAA,CAAE,GAAG,YAAY;AAAA,EACpD,CAAC;AACD,SAAO,QAAQ,KAAK,CAAC,QAAQ,MAAM,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE;AAAA,IAAQ,MAC9D,aAAa,KAAK;AAAA,EAAA;AAEtB;AASO,SAAS,SACd,QACA,UACmB;AAGnB,SAAO,iBAAiB,QAAQ,OAAO,YAAY;;AACjD,UAAM,OAAQ,QAAQ,WAAW,QAA0B,CAAA;AAC3D,UAAM,eAAe,KAAK,kBAAkB,OAAO;AACnD,UAAM,CAAC,QAAQ,IAAI,IAAI,MAAM,QAAQ,IAAI;AAAA,MACvC,OAAO,OAAO;AAAA,MACd,iBAAe,aAAQ,UAAR,mBAAe,UAC1B,eAAe,UAAU,IACzB,QAAQ,QAAQ,CAAA,CAAE;AAAA,IAAA,CACvB;AACD,QAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,CAAC,GAAG,MAAM,GAAG,OAAO,KAAK;AAAA,MAChC,YAAY;AAAA,QACV,GAAG,OAAO;AAAA,QACV,WAAS,YAAO,eAAP,mBAAmB,YAAW;AAAA,QACvC,iBAAe,YAAO,eAAP,mBAAmB,kBAAiB,OAAO,MAAM;AAAA,MAAA;AAAA,IAClE;AAAA,EAEJ,CAAC;AACH;AAaA,eAAe,iBACb,MACwD;AACxD,QAAM,OAAO,MAAM,aAAgC,MAAM,kBAAkB;AAC3E,SAAO,KAAK;AACd;AAEO,MAAM,aAA0C,OAAO,YAAY;AACxE,QAAM,UAAU,MAAM,iBAAiB,QAAQ,aAAa,IAAI;AAEhE,QAAM,QAAoB,QAAQ,MAC/B,OAAO,CAAC,SAAS,KAAK,aAAa,EACnC,IAAI,CAAC,UAAU;AAAA,IACd,IAAI,KAAK;AAAA,IACT,MAAM,KAAK;AAAA,IACX,MAAM;AAAA,IACN,cAAc,KAAK;AAAA,IACnB,aAAa,KAAK,eAAe;AAAA,IACjC,qCAAqB,IAAA;AAAA,IACrB,GAAI,KAAK,YAAY,EAAE,OAAO,EAAE,aAAa,KAAA,MAAW,CAAA;AAAA,EAAC,EACzD;AAEJ,SAAO,EAAE,OAAO,YAAY,EAAE,SAAS,QAAM;AAC/C;AAEO,MAAM,gBAA6C,OAAO,YAAY;AAC3E,QAAM,UAAU,MAAM,iBAAiB,QAAQ,aAAa,IAAI;AAEhE,QAAM,QAAoB,QAAQ,SAC/B,OAAO,CAAC,YAAY,QAAQ,iBAAiB,CAAC,QAAQ,YAAY,EAClE,IAAI,CAAC,aAAa;AAAA,IACjB,IAAI,QAAQ;AAAA,IACZ,MAAM,QAAQ;AAAA,IACd,MAAM;AAAA,IACN,cAAc,QAAQ;AAAA,IACtB,aAAa,QAAQ,eAAe;AAAA,IACpC,qCAAqB,IAAA;AAAA,IACrB,GAAI,QAAQ,YAAY,EAAE,OAAO,EAAE,aAAa,KAAA,MAAW,CAAA;AAAA,EAAC,EAC5D;AAEJ,SAAO,EAAE,OAAO,YAAY,EAAE,SAAS,QAAM;AAC/C;AAUO,MAAM,cAAsC,OAAO,YAAY;AACpE,QAAM,EAAE,YAAY,aAAA,IAAiB;AACrC,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,QAAM,SAAS,MAAM,kBAAkB,aAAa,MAAM;AAAA,IACxD,OAAO;AAAA,IACP;AAAA,IACA,cAAc,CAAC,SAAS;AAAA,EAAA,CACzB;AAGD,QAAM,QAAoB,OAAO,MAAM,IAAI,CAAC,UAAU;AAAA,IACpD,GAAG;AAAA,IACH,MAAM;AAAA,IACN,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,kBAAkB,KAAK;AAAA,EAAA,EACvB;AAGF,QAAM,UAA8B,MAAM,IAAI,CAAC,UAAU;AAAA,IACvD,OAAO,KAAK;AAAA,IACZ,UAAU;AAAA,IACV,cAAc,EAAE,MAAM,aAAa,MAAM,OAAO,GAAA;AAAA,EAAG,EACnD;AAEF,SAAO;AAAA,IACL;AAAA,IACA,YAAY,EAAE,SAAS,OAAO,QAAA;AAAA,IAC9B;AAAA,EAAA;AAEJ;AAUO,MAAM,oBAAkD,OAC7D,YACG;AACH,QAAM,EAAE,OAAO,YAAY,aAAA,IAAiB;AAC5C,MAAI,EAAC,+BAAO,QAAQ,QAAO,EAAE,OAAO,CAAA,GAAI,YAAY,EAAE,SAAS,QAAM;AAErE,QAAM,OAAQ,WAAW,QAA0B,CAAA;AACnD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,QAAM,SAAS,MAAM,kBAAkB,aAAa,MAAM;AAAA,IACxD;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA,cAAc,CAAC,WAAW,SAAS;AAAA,EAAA,CACpC;AAED,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,YAAY,EAAE,SAAS,OAAO,QAAA;AAAA,EAAQ;AAE1C;AAYO,SAAS,sBACd,OACA,MACY;AACZ,SAAO,MACJ,OAAO,CAAC,SAAS,SAAS,UAAa,KAAK,SAAS,IAAI,EACzD,IAAI,CAAC,UAAU;AAAA,IACd,IAAI,KAAK;AAAA,IACT,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,IACX,cAAc,KAAK,SAAS,KAAK,SAAS,YAAY,YAAY;AAAA,IAClE,aAAa,KAAK;AAAA,IAClB,qCAAqB,IAAA;AAAA,EAAY,EACjC;AACN;AAEO,MAAM,yBAAwD,OACnE,aACI;AAAA,EACJ,OAAO;AAAA,IACL,QAAQ,aAAa,SAAA;AAAA,IACrB,QAAQ,aAAa;AAAA,EAAA;AAAA,EAEvB,YAAY,EAAE,SAAS,MAAA;AACzB;AASO,SAAS,kBACd,QACA,UACmB;AACnB,QAAM,UAA6B,OAAO,YAAY;;AACpD,UAAM,SAAS,MAAM,OAAO,OAAO;AACnC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,CAAC,GAAG,sBAAsB,UAAU,GAAG,GAAG,OAAO,KAAK;AAAA,MAC7D,YAAY;AAAA,QACV,GAAG,OAAO;AAAA,QACV,WAAS,YAAO,eAAP,mBAAmB,YAAW;AAAA,QACvC,iBAAe,YAAO,eAAP,mBAAmB,kBAAiB,OAAO,MAAM;AAAA,MAAA;AAAA,IAClE;AAAA,EAEJ;AAEA,gBAAc,IAAI,SAAqB,MAAM,sBAAsB,SAAA,CAAU,CAAC;AAC9E,SAAO;AACT;AAMA,MAAM,oCAAoB,QAAA;AAG1B,SAAS,iBACP,OACA,SACmB;AACnB,QAAM,UAAU,cAAc,IAAI,KAAiB;AACnD,MAAI,QAAS,eAAc,IAAI,SAAqB,OAAO;AAC3D,SAAO;AACT;AAMO,SAAS,eAAe,UAAgC;;AAC7D,WAAO,mBAAc,IAAI,QAAQ,MAA1B,yBAAmC,CAAA;AAC5C;AAWA,MAAM,oCAA2C,IAAc;AAAA,EAC7D;AAAA,EACA;AACF,CAAC;AAGM,SAAS,iBAAiB,UAA6B;AAC5D,SAAO,CAAC,cAAc,IAAI,QAAQ;AACpC;"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const store = require("@tanstack/store");
|
|
4
|
-
const
|
|
4
|
+
const require$$0 = require("react");
|
|
5
5
|
const apiClient = require("./api-client.cjs");
|
|
6
6
|
const itemCache = require("./item-cache.cjs");
|
|
7
|
+
const orchestrator = require("./orchestrator.cjs");
|
|
7
8
|
const scopeRegistry = require("./scope-registry.cjs");
|
|
8
9
|
const index = require("./sources/index.cjs");
|
|
9
10
|
function webpageMentionFingerprint(webpages) {
|
|
@@ -42,7 +43,8 @@ function buildStore({
|
|
|
42
43
|
auth,
|
|
43
44
|
getWebpages,
|
|
44
45
|
getTools,
|
|
45
|
-
rootCategories
|
|
46
|
+
rootCategories,
|
|
47
|
+
athenaUnavailable
|
|
46
48
|
}) {
|
|
47
49
|
const registry = scopeRegistry.createScopeRegistry();
|
|
48
50
|
const cache = itemCache.createItemCache();
|
|
@@ -97,25 +99,37 @@ function buildStore({
|
|
|
97
99
|
}
|
|
98
100
|
scopeRegistry.registerSource(registry, "team", index.fetchTeam, { auth, loadTeam });
|
|
99
101
|
scopeRegistry.registerSource(registry, "drive_catalogs", index.fetchDrives, { auth });
|
|
100
|
-
return new store.Store({
|
|
102
|
+
return new store.Store({
|
|
103
|
+
registry,
|
|
104
|
+
cache,
|
|
105
|
+
athenaUnavailable
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function sameReason(a, b) {
|
|
109
|
+
if (a === null || b === null) return a === b;
|
|
110
|
+
return a.label === b.label && a.detail === b.detail;
|
|
101
111
|
}
|
|
102
112
|
function useMentionSuggestions({
|
|
103
113
|
webpages,
|
|
104
114
|
tools,
|
|
105
|
-
rootCategories = ROOT_MENTION_CATEGORIES
|
|
115
|
+
rootCategories = ROOT_MENTION_CATEGORIES,
|
|
116
|
+
athenaUnavailable = null
|
|
106
117
|
}) {
|
|
107
118
|
const auth = apiClient.useMentionAuth();
|
|
108
|
-
const webpagesRef =
|
|
119
|
+
const webpagesRef = require$$0.useRef(webpages);
|
|
109
120
|
webpagesRef.current = webpages;
|
|
110
|
-
const toolsRef =
|
|
121
|
+
const toolsRef = require$$0.useRef(tools);
|
|
111
122
|
toolsRef.current = tools;
|
|
112
123
|
const hasProvidedTools = tools !== void 0;
|
|
113
|
-
const
|
|
124
|
+
const athenaUnavailableRef = require$$0.useRef(athenaUnavailable);
|
|
125
|
+
athenaUnavailableRef.current = athenaUnavailable;
|
|
126
|
+
const store2 = require$$0.useMemo(
|
|
114
127
|
() => buildStore({
|
|
115
128
|
auth,
|
|
116
129
|
getWebpages: () => webpagesRef.current,
|
|
117
130
|
getTools: hasProvidedTools ? () => toolsRef.current ?? [] : void 0,
|
|
118
|
-
rootCategories
|
|
131
|
+
rootCategories,
|
|
132
|
+
athenaUnavailable: athenaUnavailableRef.current
|
|
119
133
|
}),
|
|
120
134
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
121
135
|
[
|
|
@@ -128,7 +142,7 @@ function useMentionSuggestions({
|
|
|
128
142
|
rootCategories.join(",")
|
|
129
143
|
]
|
|
130
144
|
);
|
|
131
|
-
const invalidate =
|
|
145
|
+
const invalidate = require$$0.useMemo(
|
|
132
146
|
() => (scope) => {
|
|
133
147
|
const state = store2.state;
|
|
134
148
|
const { registry, cache } = state;
|
|
@@ -149,16 +163,24 @@ function useMentionSuggestions({
|
|
|
149
163
|
},
|
|
150
164
|
[store2]
|
|
151
165
|
);
|
|
166
|
+
require$$0.useLayoutEffect(() => {
|
|
167
|
+
const unavailableBefore = store2.state.athenaUnavailable;
|
|
168
|
+
if (sameReason(unavailableBefore, athenaUnavailable)) return;
|
|
169
|
+
store2.setState((prev) => ({ ...prev, athenaUnavailable }));
|
|
170
|
+
if (unavailableBefore !== null && athenaUnavailable === null) {
|
|
171
|
+
orchestrator.retryFailedFetches(store2);
|
|
172
|
+
}
|
|
173
|
+
}, [athenaUnavailable, store2]);
|
|
152
174
|
const webpageFingerprint = webpageMentionFingerprint(webpages);
|
|
153
|
-
const previousWebpageFingerprintRef =
|
|
154
|
-
|
|
175
|
+
const previousWebpageFingerprintRef = require$$0.useRef(null);
|
|
176
|
+
require$$0.useEffect(() => {
|
|
155
177
|
if (previousWebpageFingerprintRef.current === webpageFingerprint) return;
|
|
156
178
|
previousWebpageFingerprintRef.current = webpageFingerprint;
|
|
157
179
|
invalidate("root");
|
|
158
180
|
}, [invalidate, webpageFingerprint]);
|
|
159
181
|
const toolsFingerprint = tools ? providedToolsFingerprint(tools) : null;
|
|
160
|
-
const previousToolsFingerprintRef =
|
|
161
|
-
|
|
182
|
+
const previousToolsFingerprintRef = require$$0.useRef(null);
|
|
183
|
+
require$$0.useEffect(() => {
|
|
162
184
|
if (previousToolsFingerprintRef.current === toolsFingerprint) return;
|
|
163
185
|
previousToolsFingerprintRef.current = toolsFingerprint;
|
|
164
186
|
if (toolsFingerprint === null) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-mention-suggestions.cjs","sources":["../../../../../src/chat-ui/mentions/suggestions/data/use-mention-suggestions.ts"],"sourcesContent":["/**\n * Mention Suggestions Store — shared by every Athena chat host (the Chrome\n * side panel, the Office task pane, the SDK's AthenaChat).\n *\n * Full Olympus-style mention store with all categories:\n * Favorites, Assets, Projects, Browse Profiles, Folders,\n * current/group webpages, Team, Workspace, Drives + Global Search (assets,\n * plus workspace members when Team is offered).\n *\n * Uses registry + cache architecture from Olympus with\n * async data fetching via GraphQL. A host may hand the Tools / Toolkits\n * categories its own list instead of the server catalog (`tools`).\n */\n\nimport { Store } from \"@tanstack/store\";\nimport { useEffect, useMemo, useRef } from \"react\";\nimport type { MentionAuthContext } from \"./api-client\";\nimport { useMentionAuth } from \"./api-client\";\nimport { createItemCache, type ItemCache } from \"./item-cache\";\nimport {\n createScopeRegistry,\n registerSource,\n bindScopes,\n type ScopeRegistry,\n} from \"./scope-registry\";\nimport {\n transformRootCategories,\n fetchAssets,\n fetchFavorites,\n fetchFolders,\n fetchFolderContents,\n fetchTypedAssets,\n fetchTeam,\n fetchTools,\n fetchToolkits,\n fetchDrives,\n fetchGlobalSearch,\n transformProvidedTools,\n withProvidedTools,\n createTeamLoader,\n withTeam,\n} from \"./sources\";\nimport type { MentionTool, WebpageMention } from \"./types\";\n\nexport function webpageMentionFingerprint(\n webpages: readonly WebpageMention[],\n): string {\n return JSON.stringify(\n webpages.map(({ tabId, title, url, isCurrent }) => [\n tabId,\n title,\n url,\n isCurrent,\n ]),\n );\n}\n\n// ── Store types ──\n\nexport interface MentionSuggestionsStoreState {\n registry: ScopeRegistry;\n cache: ItemCache;\n}\n\nexport type MentionSuggestionsStore = Store<MentionSuggestionsStoreState>;\n\n// ── Categories ──\n\n/**\n * All mention menu categories, in display order.\n */\nexport const ROOT_MENTION_CATEGORIES = [\n \"favorites\",\n \"assets\",\n \"projects\",\n \"browse_profiles\",\n \"folders\",\n \"tools\",\n \"toolkits\",\n \"team\",\n \"drives\",\n] as const;\n\nexport type MentionRootCategory = (typeof ROOT_MENTION_CATEGORIES)[number];\n\n// ── Store builder ──\n\n/** Stable fingerprint of a host's tool list, for cache invalidation. */\nexport function providedToolsFingerprint(tools: readonly MentionTool[]): string {\n return JSON.stringify(\n tools.map(({ id, name, type, description, icon }) => [\n id,\n name,\n type,\n description ?? null,\n icon ?? null,\n ]),\n );\n}\n\nfunction buildStore({\n auth,\n getWebpages,\n getTools,\n rootCategories,\n}: {\n auth: MentionAuthContext;\n getWebpages: () => readonly WebpageMention[];\n /** Present when the host supplies the Tools / Toolkits list itself. */\n getTools?: () => readonly MentionTool[];\n rootCategories: readonly MentionRootCategory[];\n}): MentionSuggestionsStore {\n const registry = createScopeRegistry();\n const cache = createItemCache();\n\n // ── Root categories ──\n registerSource(registry, \"root\", transformRootCategories, {\n categories: [...rootCategories],\n getWebpages,\n });\n\n const loadTeam = createTeamLoader(auth);\n\n // ── Global search (aggregated) ──\n // A host's own tools ride along so a root query finds them beside assets,\n // and so do workspace members when the host offers Team.\n const withHostTools = getTools\n ? withProvidedTools(fetchGlobalSearch, getTools)\n : fetchGlobalSearch;\n registerSource(\n registry,\n \"global_search\",\n rootCategories.includes(\"team\") ? withTeam(withHostTools, loadTeam) : withHostTools,\n { auth },\n );\n bindScopes(registry, \"root\", \"global_search\");\n\n // ── Assets ──\n registerSource(registry, \"athena_assets\", fetchAssets, { auth, limit: 50 });\n\n // ── Favorites ──\n registerSource(registry, \"favorites\", fetchFavorites, { auth, limit: 50 });\n\n // ── Folders (flat list) ──\n registerSource(\n registry,\n \"athena_folders\",\n fetchFolders,\n { auth, limit: 50 },\n true /* isFlat */,\n );\n\n // ── Internal drive (folder navigation root) ──\n registerSource(registry, \"internal_drive\", fetchFolderContents, {\n auth,\n limit: 50,\n });\n\n // ── Projects ──\n registerSource(registry, \"athena_projects\", fetchTypedAssets, {\n auth,\n includeOnlyTypes: [\"project\"],\n limit: 50,\n });\n\n // ── Browse Profiles ──\n registerSource(registry, \"athena_browse_profiles\", fetchTypedAssets, {\n auth,\n includeOnlyTypes: [\"browse_profile\"],\n limit: 50,\n });\n\n // ── Tools & Toolkits ── the server catalog, or the host's own list\n if (getTools) {\n registerSource(registry, \"tools\", transformProvidedTools, {\n getTools,\n type: \"tool\",\n });\n registerSource(registry, \"toolkits\", transformProvidedTools, {\n getTools,\n type: \"toolkit\",\n });\n } else {\n registerSource(registry, \"tools\", fetchTools, { auth });\n registerSource(registry, \"toolkits\", fetchToolkits, { auth });\n }\n\n // ── Team ──\n registerSource(registry, \"team\", fetchTeam, { auth, loadTeam });\n\n // ── Drives (catalogs) ──\n registerSource(registry, \"drive_catalogs\", fetchDrives, { auth });\n\n return new Store<MentionSuggestionsStoreState>({ registry, cache });\n}\n\n// ── Hook ──\n\n/**\n * Creates a stable MentionSuggestionsStore.\n * Uses MentionAuthCtx for API credentials.\n */\nexport function useMentionSuggestions({\n webpages,\n tools,\n rootCategories = ROOT_MENTION_CATEGORIES,\n}: {\n webpages: readonly WebpageMention[];\n /**\n * Host-provided Tools / Toolkits candidates. When set (even empty) they\n * replace the server tool catalog for those categories and join root\n * search results; omitted, the categories fetch the catalog.\n */\n tools?: readonly MentionTool[];\n /** Categories shown at the top level; hosts can narrow the default set. */\n rootCategories?: readonly MentionRootCategory[];\n}): {\n store: MentionSuggestionsStore;\n invalidate: (scope: string) => void;\n} {\n const auth = useMentionAuth();\n const webpagesRef = useRef(webpages);\n webpagesRef.current = webpages;\n const toolsRef = useRef(tools);\n toolsRef.current = tools;\n const hasProvidedTools = tools !== undefined;\n\n // Depend on primitive values to avoid rebuilding store on object identity changes\n const store = useMemo(\n () =>\n buildStore({\n auth,\n getWebpages: () => webpagesRef.current,\n getTools: hasProvidedTools ? () => toolsRef.current ?? [] : undefined,\n rootCategories,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n auth.backendUrl,\n auth.accessToken,\n auth.apiKey,\n auth.workspaceId,\n auth.userId,\n hasProvidedTools,\n rootCategories.join(\",\"),\n ],\n );\n\n const invalidate = useMemo(\n () => (scope: string) => {\n const state = store.state;\n const { registry, cache } = state;\n\n // Clear scope from cache\n if (cache.items) {\n for (const item of Object.values(cache.items)) {\n item.visibleInScopes.delete(scope);\n }\n // Remove orphaned items\n for (const [id, item] of Object.entries(cache.items)) {\n if (item.visibleInScopes.size === 0) {\n delete cache.items[id];\n }\n }\n }\n\n // Reset fetch states\n if (registry.entries[scope]) {\n registry.entries[scope].fetchStates = {};\n }\n\n store.setState((prev) => ({ ...prev }));\n },\n [store],\n );\n\n const webpageFingerprint = webpageMentionFingerprint(webpages);\n const previousWebpageFingerprintRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (previousWebpageFingerprintRef.current === webpageFingerprint) return;\n previousWebpageFingerprintRef.current = webpageFingerprint;\n invalidate(\"root\");\n }, [invalidate, webpageFingerprint]);\n\n // A changed tool list drops the cached Tools / Toolkits entries (and the\n // root search results they were folded into) so the next open re-reads it.\n const toolsFingerprint = tools ? providedToolsFingerprint(tools) : null;\n const previousToolsFingerprintRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (previousToolsFingerprintRef.current === toolsFingerprint) return;\n previousToolsFingerprintRef.current = toolsFingerprint;\n if (toolsFingerprint === null) return;\n invalidate(\"tools\");\n invalidate(\"toolkits\");\n invalidate(\"global_search\");\n }, [invalidate, toolsFingerprint]);\n\n return { store, invalidate };\n}\n"],"names":["createScopeRegistry","createItemCache","registerSource","transformRootCategories","createTeamLoader","withProvidedTools","fetchGlobalSearch","withTeam","bindScopes","fetchAssets","fetchFavorites","fetchFolders","fetchFolderContents","fetchTypedAssets","transformProvidedTools","fetchTools","fetchToolkits","fetchTeam","fetchDrives","Store","useMentionAuth","useRef","store","useMemo","useEffect"],"mappings":";;;;;;;;AA4CO,SAAS,0BACd,UACQ;AACR,SAAO,KAAK;AAAA,IACV,SAAS,IAAI,CAAC,EAAE,OAAO,OAAO,KAAK,gBAAgB;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAAA,EAAA;AAEL;AAgBO,MAAM,0BAA0B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAOO,SAAS,yBAAyB,OAAuC;AAC9E,SAAO,KAAK;AAAA,IACV,MAAM,IAAI,CAAC,EAAE,IAAI,MAAM,MAAM,aAAa,WAAW;AAAA,MACnD;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf,QAAQ;AAAA,IAAA,CACT;AAAA,EAAA;AAEL;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAM4B;AAC1B,QAAM,WAAWA,cAAAA,oBAAA;AACjB,QAAM,QAAQC,UAAAA,gBAAA;AAGdC,+BAAe,UAAU,QAAQC,+BAAyB;AAAA,IACxD,YAAY,CAAC,GAAG,cAAc;AAAA,IAC9B;AAAA,EAAA,CACD;AAED,QAAM,WAAWC,MAAAA,iBAAiB,IAAI;AAKtC,QAAM,gBAAgB,WAClBC,MAAAA,kBAAkBC,MAAAA,mBAAmB,QAAQ,IAC7CA,MAAAA;AACJJ,gBAAAA;AAAAA,IACE;AAAA,IACA;AAAA,IACA,eAAe,SAAS,MAAM,IAAIK,MAAAA,SAAS,eAAe,QAAQ,IAAI;AAAA,IACtE,EAAE,KAAA;AAAA,EAAK;AAETC,2BAAW,UAAU,QAAQ,eAAe;AAG5CN,gBAAAA,eAAe,UAAU,iBAAiBO,MAAAA,aAAa,EAAE,MAAM,OAAO,IAAI;AAG1EP,gBAAAA,eAAe,UAAU,aAAaQ,MAAAA,gBAAgB,EAAE,MAAM,OAAO,IAAI;AAGzER,gBAAAA;AAAAA,IACE;AAAA,IACA;AAAA,IACAS,MAAAA;AAAAA,IACA,EAAE,MAAM,OAAO,GAAA;AAAA,IACf;AAAA,EAAA;AAIFT,+BAAe,UAAU,kBAAkBU,2BAAqB;AAAA,IAC9D;AAAA,IACA,OAAO;AAAA,EAAA,CACR;AAGDV,+BAAe,UAAU,mBAAmBW,wBAAkB;AAAA,IAC5D;AAAA,IACA,kBAAkB,CAAC,SAAS;AAAA,IAC5B,OAAO;AAAA,EAAA,CACR;AAGDX,+BAAe,UAAU,0BAA0BW,wBAAkB;AAAA,IACnE;AAAA,IACA,kBAAkB,CAAC,gBAAgB;AAAA,IACnC,OAAO;AAAA,EAAA,CACR;AAGD,MAAI,UAAU;AACZX,iCAAe,UAAU,SAASY,8BAAwB;AAAA,MACxD;AAAA,MACA,MAAM;AAAA,IAAA,CACP;AACDZ,iCAAe,UAAU,YAAYY,8BAAwB;AAAA,MAC3D;AAAA,MACA,MAAM;AAAA,IAAA,CACP;AAAA,EACH,OAAO;AACLZ,kBAAAA,eAAe,UAAU,SAASa,MAAAA,YAAY,EAAE,MAAM;AACtDb,kBAAAA,eAAe,UAAU,YAAYc,MAAAA,eAAe,EAAE,MAAM;AAAA,EAC9D;AAGAd,gBAAAA,eAAe,UAAU,QAAQe,MAAAA,WAAW,EAAE,MAAM,UAAU;AAG9Df,gBAAAA,eAAe,UAAU,kBAAkBgB,MAAAA,aAAa,EAAE,MAAM;AAEhE,SAAO,IAAIC,MAAAA,MAAoC,EAAE,UAAU,OAAO;AACpE;AAQO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA,iBAAiB;AACnB,GAaE;AACA,QAAM,OAAOC,UAAAA,eAAA;AACb,QAAM,cAAcC,MAAAA,OAAO,QAAQ;AACnC,cAAY,UAAU;AACtB,QAAM,WAAWA,MAAAA,OAAO,KAAK;AAC7B,WAAS,UAAU;AACnB,QAAM,mBAAmB,UAAU;AAGnC,QAAMC,SAAQC,MAAAA;AAAAA,IACZ,MACE,WAAW;AAAA,MACT;AAAA,MACA,aAAa,MAAM,YAAY;AAAA,MAC/B,UAAU,mBAAmB,MAAM,SAAS,WAAW,CAAA,IAAK;AAAA,MAC5D;AAAA,IAAA,CACD;AAAA;AAAA,IAEH;AAAA,MACE,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA,eAAe,KAAK,GAAG;AAAA,IAAA;AAAA,EACzB;AAGF,QAAM,aAAaA,MAAAA;AAAAA,IACjB,MAAM,CAAC,UAAkB;AACvB,YAAM,QAAQD,OAAM;AACpB,YAAM,EAAE,UAAU,MAAA,IAAU;AAG5B,UAAI,MAAM,OAAO;AACf,mBAAW,QAAQ,OAAO,OAAO,MAAM,KAAK,GAAG;AAC7C,eAAK,gBAAgB,OAAO,KAAK;AAAA,QACnC;AAEA,mBAAW,CAAC,IAAI,IAAI,KAAK,OAAO,QAAQ,MAAM,KAAK,GAAG;AACpD,cAAI,KAAK,gBAAgB,SAAS,GAAG;AACnC,mBAAO,MAAM,MAAM,EAAE;AAAA,UACvB;AAAA,QACF;AAAA,MACF;AAGA,UAAI,SAAS,QAAQ,KAAK,GAAG;AAC3B,iBAAS,QAAQ,KAAK,EAAE,cAAc,CAAA;AAAA,MACxC;AAEA,MAAAA,OAAM,SAAS,CAAC,UAAU,EAAE,GAAG,OAAO;AAAA,IACxC;AAAA,IACA,CAACA,MAAK;AAAA,EAAA;AAGR,QAAM,qBAAqB,0BAA0B,QAAQ;AAC7D,QAAM,gCAAgCD,MAAAA,OAAsB,IAAI;AAEhEG,QAAAA,UAAU,MAAM;AACd,QAAI,8BAA8B,YAAY,mBAAoB;AAClE,kCAA8B,UAAU;AACxC,eAAW,MAAM;AAAA,EACnB,GAAG,CAAC,YAAY,kBAAkB,CAAC;AAInC,QAAM,mBAAmB,QAAQ,yBAAyB,KAAK,IAAI;AACnE,QAAM,8BAA8BH,MAAAA,OAAsB,IAAI;AAE9DG,QAAAA,UAAU,MAAM;AACd,QAAI,4BAA4B,YAAY,iBAAkB;AAC9D,gCAA4B,UAAU;AACtC,QAAI,qBAAqB,KAAM;AAC/B,eAAW,OAAO;AAClB,eAAW,UAAU;AACrB,eAAW,eAAe;AAAA,EAC5B,GAAG,CAAC,YAAY,gBAAgB,CAAC;AAEjC,SAAO,EAAE,OAAAF,QAAO,WAAA;AAClB;;;;;"}
|
|
1
|
+
{"version":3,"file":"use-mention-suggestions.cjs","sources":["../../../../../src/chat-ui/mentions/suggestions/data/use-mention-suggestions.ts"],"sourcesContent":["/**\n * Mention Suggestions Store — shared by every Athena chat host (the Chrome\n * side panel, the Office task pane, the SDK's AthenaChat).\n *\n * Full Olympus-style mention store with all categories:\n * Favorites, Assets, Projects, Browse Profiles, Folders,\n * current/group webpages, Team, Workspace, Drives + Global Search (assets,\n * plus workspace members when Team is offered).\n *\n * Uses registry + cache architecture from Olympus with\n * async data fetching via GraphQL. A host may hand the Tools / Toolkits\n * categories its own list instead of the server catalog (`tools`).\n */\n\nimport type { LabelCopy } from \"@athenaintel/agent-runtime/offline-status\";\nimport { Store } from \"@tanstack/store\";\nimport { useEffect, useLayoutEffect, useMemo, useRef } from \"react\";\nimport type { MentionAuthContext } from \"./api-client\";\nimport { useMentionAuth } from \"./api-client\";\nimport { createItemCache, type ItemCache } from \"./item-cache\";\nimport { retryFailedFetches } from \"./orchestrator\";\nimport {\n createScopeRegistry,\n registerSource,\n bindScopes,\n type ScopeRegistry,\n} from \"./scope-registry\";\nimport {\n transformRootCategories,\n fetchAssets,\n fetchFavorites,\n fetchFolders,\n fetchFolderContents,\n fetchTypedAssets,\n fetchTeam,\n fetchTools,\n fetchToolkits,\n fetchDrives,\n fetchGlobalSearch,\n transformProvidedTools,\n withProvidedTools,\n createTeamLoader,\n withTeam,\n} from \"./sources\";\nimport type { MentionTool, WebpageMention } from \"./types\";\n\nexport function webpageMentionFingerprint(\n webpages: readonly WebpageMention[],\n): string {\n return JSON.stringify(\n webpages.map(({ tabId, title, url, isCurrent }) => [\n tabId,\n title,\n url,\n isCurrent,\n ]),\n );\n}\n\n// ── Store types ──\n\nexport interface MentionSuggestionsStoreState {\n registry: ScopeRegistry;\n cache: ItemCache;\n /**\n * Why nothing is asked of Athena right now, or `null` while it answers: the\n * scopes whose source asks Athena fetch nothing and say this instead, while\n * the host's own items (its tabs, its tool list) and what was already loaded\n * still show.\n */\n athenaUnavailable: LabelCopy | null;\n}\n\nexport type MentionSuggestionsStore = Store<MentionSuggestionsStoreState>;\n\n// ── Categories ──\n\n/**\n * All mention menu categories, in display order.\n */\nexport const ROOT_MENTION_CATEGORIES = [\n \"favorites\",\n \"assets\",\n \"projects\",\n \"browse_profiles\",\n \"folders\",\n \"tools\",\n \"toolkits\",\n \"team\",\n \"drives\",\n] as const;\n\nexport type MentionRootCategory = (typeof ROOT_MENTION_CATEGORIES)[number];\n\n// ── Store builder ──\n\n/** Stable fingerprint of a host's tool list, for cache invalidation. */\nexport function providedToolsFingerprint(tools: readonly MentionTool[]): string {\n return JSON.stringify(\n tools.map(({ id, name, type, description, icon }) => [\n id,\n name,\n type,\n description ?? null,\n icon ?? null,\n ]),\n );\n}\n\nfunction buildStore({\n auth,\n getWebpages,\n getTools,\n rootCategories,\n athenaUnavailable,\n}: {\n auth: MentionAuthContext;\n getWebpages: () => readonly WebpageMention[];\n /** Present when the host supplies the Tools / Toolkits list itself. */\n getTools?: () => readonly MentionTool[];\n rootCategories: readonly MentionRootCategory[];\n athenaUnavailable: LabelCopy | null;\n}): MentionSuggestionsStore {\n const registry = createScopeRegistry();\n const cache = createItemCache();\n\n // ── Root categories ──\n registerSource(registry, \"root\", transformRootCategories, {\n categories: [...rootCategories],\n getWebpages,\n });\n\n const loadTeam = createTeamLoader(auth);\n\n // ── Global search (aggregated) ──\n // A host's own tools ride along so a root query finds them beside assets,\n // and so do workspace members when the host offers Team.\n const withHostTools = getTools\n ? withProvidedTools(fetchGlobalSearch, getTools)\n : fetchGlobalSearch;\n registerSource(\n registry,\n \"global_search\",\n rootCategories.includes(\"team\") ? withTeam(withHostTools, loadTeam) : withHostTools,\n { auth },\n );\n bindScopes(registry, \"root\", \"global_search\");\n\n // ── Assets ──\n registerSource(registry, \"athena_assets\", fetchAssets, { auth, limit: 50 });\n\n // ── Favorites ──\n registerSource(registry, \"favorites\", fetchFavorites, { auth, limit: 50 });\n\n // ── Folders (flat list) ──\n registerSource(\n registry,\n \"athena_folders\",\n fetchFolders,\n { auth, limit: 50 },\n true /* isFlat */,\n );\n\n // ── Internal drive (folder navigation root) ──\n registerSource(registry, \"internal_drive\", fetchFolderContents, {\n auth,\n limit: 50,\n });\n\n // ── Projects ──\n registerSource(registry, \"athena_projects\", fetchTypedAssets, {\n auth,\n includeOnlyTypes: [\"project\"],\n limit: 50,\n });\n\n // ── Browse Profiles ──\n registerSource(registry, \"athena_browse_profiles\", fetchTypedAssets, {\n auth,\n includeOnlyTypes: [\"browse_profile\"],\n limit: 50,\n });\n\n // ── Tools & Toolkits ── the server catalog, or the host's own list\n if (getTools) {\n registerSource(registry, \"tools\", transformProvidedTools, {\n getTools,\n type: \"tool\",\n });\n registerSource(registry, \"toolkits\", transformProvidedTools, {\n getTools,\n type: \"toolkit\",\n });\n } else {\n registerSource(registry, \"tools\", fetchTools, { auth });\n registerSource(registry, \"toolkits\", fetchToolkits, { auth });\n }\n\n // ── Team ──\n registerSource(registry, \"team\", fetchTeam, { auth, loadTeam });\n\n // ── Drives (catalogs) ──\n registerSource(registry, \"drive_catalogs\", fetchDrives, { auth });\n\n return new Store<MentionSuggestionsStoreState>({\n registry,\n cache,\n athenaUnavailable,\n });\n}\n\n/** Two reasons say the same thing (a host may hand a new object with the same words). */\nfunction sameReason(a: LabelCopy | null, b: LabelCopy | null): boolean {\n if (a === null || b === null) return a === b;\n return a.label === b.label && a.detail === b.detail;\n}\n\n// ── Hook ──\n\n/**\n * Creates a stable MentionSuggestionsStore.\n * Uses MentionAuthCtx for API credentials.\n */\nexport function useMentionSuggestions({\n webpages,\n tools,\n rootCategories = ROOT_MENTION_CATEGORIES,\n athenaUnavailable = null,\n}: {\n webpages: readonly WebpageMention[];\n /**\n * Host-provided Tools / Toolkits candidates. When set (even empty) they\n * replace the server tool catalog for those categories and join root\n * search results; omitted, the categories fetch the catalog.\n */\n tools?: readonly MentionTool[];\n /** Categories shown at the top level; hosts can narrow the default set. */\n rootCategories?: readonly MentionRootCategory[];\n /**\n * Why nothing may be asked of Athena right now (`NEEDS_CONNECTION` while\n * Athena can't be reached), or `null`. Once it clears, the lookups that\n * failed meanwhile run again.\n */\n athenaUnavailable?: LabelCopy | null;\n}): {\n store: MentionSuggestionsStore;\n invalidate: (scope: string) => void;\n} {\n const auth = useMentionAuth();\n const webpagesRef = useRef(webpages);\n webpagesRef.current = webpages;\n const toolsRef = useRef(tools);\n toolsRef.current = tools;\n const hasProvidedTools = tools !== undefined;\n // Read once per store build: a store rebuilt meanwhile starts where the host stands.\n const athenaUnavailableRef = useRef(athenaUnavailable);\n athenaUnavailableRef.current = athenaUnavailable;\n\n // Depend on primitive values to avoid rebuilding store on object identity changes\n const store = useMemo(\n () =>\n buildStore({\n auth,\n getWebpages: () => webpagesRef.current,\n getTools: hasProvidedTools ? () => toolsRef.current ?? [] : undefined,\n rootCategories,\n athenaUnavailable: athenaUnavailableRef.current,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n auth.backendUrl,\n auth.accessToken,\n auth.apiKey,\n auth.workspaceId,\n auth.userId,\n hasProvidedTools,\n rootCategories.join(\",\"),\n ],\n );\n\n const invalidate = useMemo(\n () => (scope: string) => {\n const state = store.state;\n const { registry, cache } = state;\n\n // Clear scope from cache\n if (cache.items) {\n for (const item of Object.values(cache.items)) {\n item.visibleInScopes.delete(scope);\n }\n // Remove orphaned items\n for (const [id, item] of Object.entries(cache.items)) {\n if (item.visibleInScopes.size === 0) {\n delete cache.items[id];\n }\n }\n }\n\n // Reset fetch states\n if (registry.entries[scope]) {\n registry.entries[scope].fetchStates = {};\n }\n\n store.setState((prev) => ({ ...prev }));\n },\n [store],\n );\n\n // Before the menu's own effects run, so no lookup leaves under a stale answer;\n // a value that changed nothing keeps the store's state (and its readers) as is.\n useLayoutEffect(() => {\n const unavailableBefore = store.state.athenaUnavailable;\n if (sameReason(unavailableBefore, athenaUnavailable)) return;\n store.setState((prev) => ({ ...prev, athenaUnavailable }));\n if (unavailableBefore !== null && athenaUnavailable === null) {\n retryFailedFetches(store);\n }\n }, [athenaUnavailable, store]);\n\n const webpageFingerprint = webpageMentionFingerprint(webpages);\n const previousWebpageFingerprintRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (previousWebpageFingerprintRef.current === webpageFingerprint) return;\n previousWebpageFingerprintRef.current = webpageFingerprint;\n invalidate(\"root\");\n }, [invalidate, webpageFingerprint]);\n\n // A changed tool list drops the cached Tools / Toolkits entries (and the\n // root search results they were folded into) so the next open re-reads it.\n const toolsFingerprint = tools ? providedToolsFingerprint(tools) : null;\n const previousToolsFingerprintRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (previousToolsFingerprintRef.current === toolsFingerprint) return;\n previousToolsFingerprintRef.current = toolsFingerprint;\n if (toolsFingerprint === null) return;\n invalidate(\"tools\");\n invalidate(\"toolkits\");\n invalidate(\"global_search\");\n }, [invalidate, toolsFingerprint]);\n\n return { store, invalidate };\n}\n"],"names":["createScopeRegistry","createItemCache","registerSource","transformRootCategories","createTeamLoader","withProvidedTools","fetchGlobalSearch","withTeam","bindScopes","fetchAssets","fetchFavorites","fetchFolders","fetchFolderContents","fetchTypedAssets","transformProvidedTools","fetchTools","fetchToolkits","fetchTeam","fetchDrives","Store","useMentionAuth","useRef","store","useMemo","useLayoutEffect","retryFailedFetches","useEffect"],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* async data fetching via GraphQL. A host may hand the Tools / Toolkits
|
|
12
12
|
* categories its own list instead of the server catalog (`tools`).
|
|
13
13
|
*/
|
|
14
|
+
import type { LabelCopy } from "../../../../agent-runtime/src/offline-status";
|
|
14
15
|
import { Store } from "@tanstack/store";
|
|
15
16
|
import { type ItemCache } from "./item-cache";
|
|
16
17
|
import { type ScopeRegistry } from "./scope-registry";
|
|
@@ -19,6 +20,13 @@ export declare function webpageMentionFingerprint(webpages: readonly WebpageMent
|
|
|
19
20
|
export interface MentionSuggestionsStoreState {
|
|
20
21
|
registry: ScopeRegistry;
|
|
21
22
|
cache: ItemCache;
|
|
23
|
+
/**
|
|
24
|
+
* Why nothing is asked of Athena right now, or `null` while it answers: the
|
|
25
|
+
* scopes whose source asks Athena fetch nothing and say this instead, while
|
|
26
|
+
* the host's own items (its tabs, its tool list) and what was already loaded
|
|
27
|
+
* still show.
|
|
28
|
+
*/
|
|
29
|
+
athenaUnavailable: LabelCopy | null;
|
|
22
30
|
}
|
|
23
31
|
export type MentionSuggestionsStore = Store<MentionSuggestionsStoreState>;
|
|
24
32
|
/**
|
|
@@ -32,7 +40,7 @@ export declare function providedToolsFingerprint(tools: readonly MentionTool[]):
|
|
|
32
40
|
* Creates a stable MentionSuggestionsStore.
|
|
33
41
|
* Uses MentionAuthCtx for API credentials.
|
|
34
42
|
*/
|
|
35
|
-
export declare function useMentionSuggestions({ webpages, tools, rootCategories, }: {
|
|
43
|
+
export declare function useMentionSuggestions({ webpages, tools, rootCategories, athenaUnavailable, }: {
|
|
36
44
|
webpages: readonly WebpageMention[];
|
|
37
45
|
/**
|
|
38
46
|
* Host-provided Tools / Toolkits candidates. When set (even empty) they
|
|
@@ -42,6 +50,12 @@ export declare function useMentionSuggestions({ webpages, tools, rootCategories,
|
|
|
42
50
|
tools?: readonly MentionTool[];
|
|
43
51
|
/** Categories shown at the top level; hosts can narrow the default set. */
|
|
44
52
|
rootCategories?: readonly MentionRootCategory[];
|
|
53
|
+
/**
|
|
54
|
+
* Why nothing may be asked of Athena right now (`NEEDS_CONNECTION` while
|
|
55
|
+
* Athena can't be reached), or `null`. Once it clears, the lookups that
|
|
56
|
+
* failed meanwhile run again.
|
|
57
|
+
*/
|
|
58
|
+
athenaUnavailable?: LabelCopy | null;
|
|
45
59
|
}): {
|
|
46
60
|
store: MentionSuggestionsStore;
|
|
47
61
|
invalidate: (scope: string) => void;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Store } from "@tanstack/store";
|
|
2
|
-
import { useRef, useMemo, useEffect } from "react";
|
|
2
|
+
import { useRef, useMemo, useLayoutEffect, useEffect } from "react";
|
|
3
3
|
import { useMentionAuth } from "./api-client.js";
|
|
4
4
|
import { createItemCache } from "./item-cache.js";
|
|
5
|
+
import { retryFailedFetches } from "./orchestrator.js";
|
|
5
6
|
import { registerSource, bindScopes, createScopeRegistry } from "./scope-registry.js";
|
|
6
|
-
import { transformRootCategories,
|
|
7
|
+
import { transformRootCategories, withProvidedTools, fetchGlobalSearch, withTeam, fetchAssets, fetchFavorites, fetchFolders, fetchFolderContents, fetchTypedAssets, transformProvidedTools, fetchTools, fetchToolkits, fetchTeam, fetchDrives, createTeamLoader } from "./sources/index.js";
|
|
7
8
|
function webpageMentionFingerprint(webpages) {
|
|
8
9
|
return JSON.stringify(
|
|
9
10
|
webpages.map(({ tabId, title, url, isCurrent }) => [
|
|
@@ -40,7 +41,8 @@ function buildStore({
|
|
|
40
41
|
auth,
|
|
41
42
|
getWebpages,
|
|
42
43
|
getTools,
|
|
43
|
-
rootCategories
|
|
44
|
+
rootCategories,
|
|
45
|
+
athenaUnavailable
|
|
44
46
|
}) {
|
|
45
47
|
const registry = createScopeRegistry();
|
|
46
48
|
const cache = createItemCache();
|
|
@@ -95,12 +97,21 @@ function buildStore({
|
|
|
95
97
|
}
|
|
96
98
|
registerSource(registry, "team", fetchTeam, { auth, loadTeam });
|
|
97
99
|
registerSource(registry, "drive_catalogs", fetchDrives, { auth });
|
|
98
|
-
return new Store({
|
|
100
|
+
return new Store({
|
|
101
|
+
registry,
|
|
102
|
+
cache,
|
|
103
|
+
athenaUnavailable
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function sameReason(a, b) {
|
|
107
|
+
if (a === null || b === null) return a === b;
|
|
108
|
+
return a.label === b.label && a.detail === b.detail;
|
|
99
109
|
}
|
|
100
110
|
function useMentionSuggestions({
|
|
101
111
|
webpages,
|
|
102
112
|
tools,
|
|
103
|
-
rootCategories = ROOT_MENTION_CATEGORIES
|
|
113
|
+
rootCategories = ROOT_MENTION_CATEGORIES,
|
|
114
|
+
athenaUnavailable = null
|
|
104
115
|
}) {
|
|
105
116
|
const auth = useMentionAuth();
|
|
106
117
|
const webpagesRef = useRef(webpages);
|
|
@@ -108,12 +119,15 @@ function useMentionSuggestions({
|
|
|
108
119
|
const toolsRef = useRef(tools);
|
|
109
120
|
toolsRef.current = tools;
|
|
110
121
|
const hasProvidedTools = tools !== void 0;
|
|
122
|
+
const athenaUnavailableRef = useRef(athenaUnavailable);
|
|
123
|
+
athenaUnavailableRef.current = athenaUnavailable;
|
|
111
124
|
const store = useMemo(
|
|
112
125
|
() => buildStore({
|
|
113
126
|
auth,
|
|
114
127
|
getWebpages: () => webpagesRef.current,
|
|
115
128
|
getTools: hasProvidedTools ? () => toolsRef.current ?? [] : void 0,
|
|
116
|
-
rootCategories
|
|
129
|
+
rootCategories,
|
|
130
|
+
athenaUnavailable: athenaUnavailableRef.current
|
|
117
131
|
}),
|
|
118
132
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
119
133
|
[
|
|
@@ -147,6 +161,14 @@ function useMentionSuggestions({
|
|
|
147
161
|
},
|
|
148
162
|
[store]
|
|
149
163
|
);
|
|
164
|
+
useLayoutEffect(() => {
|
|
165
|
+
const unavailableBefore = store.state.athenaUnavailable;
|
|
166
|
+
if (sameReason(unavailableBefore, athenaUnavailable)) return;
|
|
167
|
+
store.setState((prev) => ({ ...prev, athenaUnavailable }));
|
|
168
|
+
if (unavailableBefore !== null && athenaUnavailable === null) {
|
|
169
|
+
retryFailedFetches(store);
|
|
170
|
+
}
|
|
171
|
+
}, [athenaUnavailable, store]);
|
|
150
172
|
const webpageFingerprint = webpageMentionFingerprint(webpages);
|
|
151
173
|
const previousWebpageFingerprintRef = useRef(null);
|
|
152
174
|
useEffect(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-mention-suggestions.js","sources":["../../../../../src/chat-ui/mentions/suggestions/data/use-mention-suggestions.ts"],"sourcesContent":["/**\n * Mention Suggestions Store — shared by every Athena chat host (the Chrome\n * side panel, the Office task pane, the SDK's AthenaChat).\n *\n * Full Olympus-style mention store with all categories:\n * Favorites, Assets, Projects, Browse Profiles, Folders,\n * current/group webpages, Team, Workspace, Drives + Global Search (assets,\n * plus workspace members when Team is offered).\n *\n * Uses registry + cache architecture from Olympus with\n * async data fetching via GraphQL. A host may hand the Tools / Toolkits\n * categories its own list instead of the server catalog (`tools`).\n */\n\nimport { Store } from \"@tanstack/store\";\nimport { useEffect, useMemo, useRef } from \"react\";\nimport type { MentionAuthContext } from \"./api-client\";\nimport { useMentionAuth } from \"./api-client\";\nimport { createItemCache, type ItemCache } from \"./item-cache\";\nimport {\n createScopeRegistry,\n registerSource,\n bindScopes,\n type ScopeRegistry,\n} from \"./scope-registry\";\nimport {\n transformRootCategories,\n fetchAssets,\n fetchFavorites,\n fetchFolders,\n fetchFolderContents,\n fetchTypedAssets,\n fetchTeam,\n fetchTools,\n fetchToolkits,\n fetchDrives,\n fetchGlobalSearch,\n transformProvidedTools,\n withProvidedTools,\n createTeamLoader,\n withTeam,\n} from \"./sources\";\nimport type { MentionTool, WebpageMention } from \"./types\";\n\nexport function webpageMentionFingerprint(\n webpages: readonly WebpageMention[],\n): string {\n return JSON.stringify(\n webpages.map(({ tabId, title, url, isCurrent }) => [\n tabId,\n title,\n url,\n isCurrent,\n ]),\n );\n}\n\n// ── Store types ──\n\nexport interface MentionSuggestionsStoreState {\n registry: ScopeRegistry;\n cache: ItemCache;\n}\n\nexport type MentionSuggestionsStore = Store<MentionSuggestionsStoreState>;\n\n// ── Categories ──\n\n/**\n * All mention menu categories, in display order.\n */\nexport const ROOT_MENTION_CATEGORIES = [\n \"favorites\",\n \"assets\",\n \"projects\",\n \"browse_profiles\",\n \"folders\",\n \"tools\",\n \"toolkits\",\n \"team\",\n \"drives\",\n] as const;\n\nexport type MentionRootCategory = (typeof ROOT_MENTION_CATEGORIES)[number];\n\n// ── Store builder ──\n\n/** Stable fingerprint of a host's tool list, for cache invalidation. */\nexport function providedToolsFingerprint(tools: readonly MentionTool[]): string {\n return JSON.stringify(\n tools.map(({ id, name, type, description, icon }) => [\n id,\n name,\n type,\n description ?? null,\n icon ?? null,\n ]),\n );\n}\n\nfunction buildStore({\n auth,\n getWebpages,\n getTools,\n rootCategories,\n}: {\n auth: MentionAuthContext;\n getWebpages: () => readonly WebpageMention[];\n /** Present when the host supplies the Tools / Toolkits list itself. */\n getTools?: () => readonly MentionTool[];\n rootCategories: readonly MentionRootCategory[];\n}): MentionSuggestionsStore {\n const registry = createScopeRegistry();\n const cache = createItemCache();\n\n // ── Root categories ──\n registerSource(registry, \"root\", transformRootCategories, {\n categories: [...rootCategories],\n getWebpages,\n });\n\n const loadTeam = createTeamLoader(auth);\n\n // ── Global search (aggregated) ──\n // A host's own tools ride along so a root query finds them beside assets,\n // and so do workspace members when the host offers Team.\n const withHostTools = getTools\n ? withProvidedTools(fetchGlobalSearch, getTools)\n : fetchGlobalSearch;\n registerSource(\n registry,\n \"global_search\",\n rootCategories.includes(\"team\") ? withTeam(withHostTools, loadTeam) : withHostTools,\n { auth },\n );\n bindScopes(registry, \"root\", \"global_search\");\n\n // ── Assets ──\n registerSource(registry, \"athena_assets\", fetchAssets, { auth, limit: 50 });\n\n // ── Favorites ──\n registerSource(registry, \"favorites\", fetchFavorites, { auth, limit: 50 });\n\n // ── Folders (flat list) ──\n registerSource(\n registry,\n \"athena_folders\",\n fetchFolders,\n { auth, limit: 50 },\n true /* isFlat */,\n );\n\n // ── Internal drive (folder navigation root) ──\n registerSource(registry, \"internal_drive\", fetchFolderContents, {\n auth,\n limit: 50,\n });\n\n // ── Projects ──\n registerSource(registry, \"athena_projects\", fetchTypedAssets, {\n auth,\n includeOnlyTypes: [\"project\"],\n limit: 50,\n });\n\n // ── Browse Profiles ──\n registerSource(registry, \"athena_browse_profiles\", fetchTypedAssets, {\n auth,\n includeOnlyTypes: [\"browse_profile\"],\n limit: 50,\n });\n\n // ── Tools & Toolkits ── the server catalog, or the host's own list\n if (getTools) {\n registerSource(registry, \"tools\", transformProvidedTools, {\n getTools,\n type: \"tool\",\n });\n registerSource(registry, \"toolkits\", transformProvidedTools, {\n getTools,\n type: \"toolkit\",\n });\n } else {\n registerSource(registry, \"tools\", fetchTools, { auth });\n registerSource(registry, \"toolkits\", fetchToolkits, { auth });\n }\n\n // ── Team ──\n registerSource(registry, \"team\", fetchTeam, { auth, loadTeam });\n\n // ── Drives (catalogs) ──\n registerSource(registry, \"drive_catalogs\", fetchDrives, { auth });\n\n return new Store<MentionSuggestionsStoreState>({ registry, cache });\n}\n\n// ── Hook ──\n\n/**\n * Creates a stable MentionSuggestionsStore.\n * Uses MentionAuthCtx for API credentials.\n */\nexport function useMentionSuggestions({\n webpages,\n tools,\n rootCategories = ROOT_MENTION_CATEGORIES,\n}: {\n webpages: readonly WebpageMention[];\n /**\n * Host-provided Tools / Toolkits candidates. When set (even empty) they\n * replace the server tool catalog for those categories and join root\n * search results; omitted, the categories fetch the catalog.\n */\n tools?: readonly MentionTool[];\n /** Categories shown at the top level; hosts can narrow the default set. */\n rootCategories?: readonly MentionRootCategory[];\n}): {\n store: MentionSuggestionsStore;\n invalidate: (scope: string) => void;\n} {\n const auth = useMentionAuth();\n const webpagesRef = useRef(webpages);\n webpagesRef.current = webpages;\n const toolsRef = useRef(tools);\n toolsRef.current = tools;\n const hasProvidedTools = tools !== undefined;\n\n // Depend on primitive values to avoid rebuilding store on object identity changes\n const store = useMemo(\n () =>\n buildStore({\n auth,\n getWebpages: () => webpagesRef.current,\n getTools: hasProvidedTools ? () => toolsRef.current ?? [] : undefined,\n rootCategories,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n auth.backendUrl,\n auth.accessToken,\n auth.apiKey,\n auth.workspaceId,\n auth.userId,\n hasProvidedTools,\n rootCategories.join(\",\"),\n ],\n );\n\n const invalidate = useMemo(\n () => (scope: string) => {\n const state = store.state;\n const { registry, cache } = state;\n\n // Clear scope from cache\n if (cache.items) {\n for (const item of Object.values(cache.items)) {\n item.visibleInScopes.delete(scope);\n }\n // Remove orphaned items\n for (const [id, item] of Object.entries(cache.items)) {\n if (item.visibleInScopes.size === 0) {\n delete cache.items[id];\n }\n }\n }\n\n // Reset fetch states\n if (registry.entries[scope]) {\n registry.entries[scope].fetchStates = {};\n }\n\n store.setState((prev) => ({ ...prev }));\n },\n [store],\n );\n\n const webpageFingerprint = webpageMentionFingerprint(webpages);\n const previousWebpageFingerprintRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (previousWebpageFingerprintRef.current === webpageFingerprint) return;\n previousWebpageFingerprintRef.current = webpageFingerprint;\n invalidate(\"root\");\n }, [invalidate, webpageFingerprint]);\n\n // A changed tool list drops the cached Tools / Toolkits entries (and the\n // root search results they were folded into) so the next open re-reads it.\n const toolsFingerprint = tools ? providedToolsFingerprint(tools) : null;\n const previousToolsFingerprintRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (previousToolsFingerprintRef.current === toolsFingerprint) return;\n previousToolsFingerprintRef.current = toolsFingerprint;\n if (toolsFingerprint === null) return;\n invalidate(\"tools\");\n invalidate(\"toolkits\");\n invalidate(\"global_search\");\n }, [invalidate, toolsFingerprint]);\n\n return { store, invalidate };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-mention-suggestions.js","sources":["../../../../../src/chat-ui/mentions/suggestions/data/use-mention-suggestions.ts"],"sourcesContent":["/**\n * Mention Suggestions Store — shared by every Athena chat host (the Chrome\n * side panel, the Office task pane, the SDK's AthenaChat).\n *\n * Full Olympus-style mention store with all categories:\n * Favorites, Assets, Projects, Browse Profiles, Folders,\n * current/group webpages, Team, Workspace, Drives + Global Search (assets,\n * plus workspace members when Team is offered).\n *\n * Uses registry + cache architecture from Olympus with\n * async data fetching via GraphQL. A host may hand the Tools / Toolkits\n * categories its own list instead of the server catalog (`tools`).\n */\n\nimport type { LabelCopy } from \"@athenaintel/agent-runtime/offline-status\";\nimport { Store } from \"@tanstack/store\";\nimport { useEffect, useLayoutEffect, useMemo, useRef } from \"react\";\nimport type { MentionAuthContext } from \"./api-client\";\nimport { useMentionAuth } from \"./api-client\";\nimport { createItemCache, type ItemCache } from \"./item-cache\";\nimport { retryFailedFetches } from \"./orchestrator\";\nimport {\n createScopeRegistry,\n registerSource,\n bindScopes,\n type ScopeRegistry,\n} from \"./scope-registry\";\nimport {\n transformRootCategories,\n fetchAssets,\n fetchFavorites,\n fetchFolders,\n fetchFolderContents,\n fetchTypedAssets,\n fetchTeam,\n fetchTools,\n fetchToolkits,\n fetchDrives,\n fetchGlobalSearch,\n transformProvidedTools,\n withProvidedTools,\n createTeamLoader,\n withTeam,\n} from \"./sources\";\nimport type { MentionTool, WebpageMention } from \"./types\";\n\nexport function webpageMentionFingerprint(\n webpages: readonly WebpageMention[],\n): string {\n return JSON.stringify(\n webpages.map(({ tabId, title, url, isCurrent }) => [\n tabId,\n title,\n url,\n isCurrent,\n ]),\n );\n}\n\n// ── Store types ──\n\nexport interface MentionSuggestionsStoreState {\n registry: ScopeRegistry;\n cache: ItemCache;\n /**\n * Why nothing is asked of Athena right now, or `null` while it answers: the\n * scopes whose source asks Athena fetch nothing and say this instead, while\n * the host's own items (its tabs, its tool list) and what was already loaded\n * still show.\n */\n athenaUnavailable: LabelCopy | null;\n}\n\nexport type MentionSuggestionsStore = Store<MentionSuggestionsStoreState>;\n\n// ── Categories ──\n\n/**\n * All mention menu categories, in display order.\n */\nexport const ROOT_MENTION_CATEGORIES = [\n \"favorites\",\n \"assets\",\n \"projects\",\n \"browse_profiles\",\n \"folders\",\n \"tools\",\n \"toolkits\",\n \"team\",\n \"drives\",\n] as const;\n\nexport type MentionRootCategory = (typeof ROOT_MENTION_CATEGORIES)[number];\n\n// ── Store builder ──\n\n/** Stable fingerprint of a host's tool list, for cache invalidation. */\nexport function providedToolsFingerprint(tools: readonly MentionTool[]): string {\n return JSON.stringify(\n tools.map(({ id, name, type, description, icon }) => [\n id,\n name,\n type,\n description ?? null,\n icon ?? null,\n ]),\n );\n}\n\nfunction buildStore({\n auth,\n getWebpages,\n getTools,\n rootCategories,\n athenaUnavailable,\n}: {\n auth: MentionAuthContext;\n getWebpages: () => readonly WebpageMention[];\n /** Present when the host supplies the Tools / Toolkits list itself. */\n getTools?: () => readonly MentionTool[];\n rootCategories: readonly MentionRootCategory[];\n athenaUnavailable: LabelCopy | null;\n}): MentionSuggestionsStore {\n const registry = createScopeRegistry();\n const cache = createItemCache();\n\n // ── Root categories ──\n registerSource(registry, \"root\", transformRootCategories, {\n categories: [...rootCategories],\n getWebpages,\n });\n\n const loadTeam = createTeamLoader(auth);\n\n // ── Global search (aggregated) ──\n // A host's own tools ride along so a root query finds them beside assets,\n // and so do workspace members when the host offers Team.\n const withHostTools = getTools\n ? withProvidedTools(fetchGlobalSearch, getTools)\n : fetchGlobalSearch;\n registerSource(\n registry,\n \"global_search\",\n rootCategories.includes(\"team\") ? withTeam(withHostTools, loadTeam) : withHostTools,\n { auth },\n );\n bindScopes(registry, \"root\", \"global_search\");\n\n // ── Assets ──\n registerSource(registry, \"athena_assets\", fetchAssets, { auth, limit: 50 });\n\n // ── Favorites ──\n registerSource(registry, \"favorites\", fetchFavorites, { auth, limit: 50 });\n\n // ── Folders (flat list) ──\n registerSource(\n registry,\n \"athena_folders\",\n fetchFolders,\n { auth, limit: 50 },\n true /* isFlat */,\n );\n\n // ── Internal drive (folder navigation root) ──\n registerSource(registry, \"internal_drive\", fetchFolderContents, {\n auth,\n limit: 50,\n });\n\n // ── Projects ──\n registerSource(registry, \"athena_projects\", fetchTypedAssets, {\n auth,\n includeOnlyTypes: [\"project\"],\n limit: 50,\n });\n\n // ── Browse Profiles ──\n registerSource(registry, \"athena_browse_profiles\", fetchTypedAssets, {\n auth,\n includeOnlyTypes: [\"browse_profile\"],\n limit: 50,\n });\n\n // ── Tools & Toolkits ── the server catalog, or the host's own list\n if (getTools) {\n registerSource(registry, \"tools\", transformProvidedTools, {\n getTools,\n type: \"tool\",\n });\n registerSource(registry, \"toolkits\", transformProvidedTools, {\n getTools,\n type: \"toolkit\",\n });\n } else {\n registerSource(registry, \"tools\", fetchTools, { auth });\n registerSource(registry, \"toolkits\", fetchToolkits, { auth });\n }\n\n // ── Team ──\n registerSource(registry, \"team\", fetchTeam, { auth, loadTeam });\n\n // ── Drives (catalogs) ──\n registerSource(registry, \"drive_catalogs\", fetchDrives, { auth });\n\n return new Store<MentionSuggestionsStoreState>({\n registry,\n cache,\n athenaUnavailable,\n });\n}\n\n/** Two reasons say the same thing (a host may hand a new object with the same words). */\nfunction sameReason(a: LabelCopy | null, b: LabelCopy | null): boolean {\n if (a === null || b === null) return a === b;\n return a.label === b.label && a.detail === b.detail;\n}\n\n// ── Hook ──\n\n/**\n * Creates a stable MentionSuggestionsStore.\n * Uses MentionAuthCtx for API credentials.\n */\nexport function useMentionSuggestions({\n webpages,\n tools,\n rootCategories = ROOT_MENTION_CATEGORIES,\n athenaUnavailable = null,\n}: {\n webpages: readonly WebpageMention[];\n /**\n * Host-provided Tools / Toolkits candidates. When set (even empty) they\n * replace the server tool catalog for those categories and join root\n * search results; omitted, the categories fetch the catalog.\n */\n tools?: readonly MentionTool[];\n /** Categories shown at the top level; hosts can narrow the default set. */\n rootCategories?: readonly MentionRootCategory[];\n /**\n * Why nothing may be asked of Athena right now (`NEEDS_CONNECTION` while\n * Athena can't be reached), or `null`. Once it clears, the lookups that\n * failed meanwhile run again.\n */\n athenaUnavailable?: LabelCopy | null;\n}): {\n store: MentionSuggestionsStore;\n invalidate: (scope: string) => void;\n} {\n const auth = useMentionAuth();\n const webpagesRef = useRef(webpages);\n webpagesRef.current = webpages;\n const toolsRef = useRef(tools);\n toolsRef.current = tools;\n const hasProvidedTools = tools !== undefined;\n // Read once per store build: a store rebuilt meanwhile starts where the host stands.\n const athenaUnavailableRef = useRef(athenaUnavailable);\n athenaUnavailableRef.current = athenaUnavailable;\n\n // Depend on primitive values to avoid rebuilding store on object identity changes\n const store = useMemo(\n () =>\n buildStore({\n auth,\n getWebpages: () => webpagesRef.current,\n getTools: hasProvidedTools ? () => toolsRef.current ?? [] : undefined,\n rootCategories,\n athenaUnavailable: athenaUnavailableRef.current,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n auth.backendUrl,\n auth.accessToken,\n auth.apiKey,\n auth.workspaceId,\n auth.userId,\n hasProvidedTools,\n rootCategories.join(\",\"),\n ],\n );\n\n const invalidate = useMemo(\n () => (scope: string) => {\n const state = store.state;\n const { registry, cache } = state;\n\n // Clear scope from cache\n if (cache.items) {\n for (const item of Object.values(cache.items)) {\n item.visibleInScopes.delete(scope);\n }\n // Remove orphaned items\n for (const [id, item] of Object.entries(cache.items)) {\n if (item.visibleInScopes.size === 0) {\n delete cache.items[id];\n }\n }\n }\n\n // Reset fetch states\n if (registry.entries[scope]) {\n registry.entries[scope].fetchStates = {};\n }\n\n store.setState((prev) => ({ ...prev }));\n },\n [store],\n );\n\n // Before the menu's own effects run, so no lookup leaves under a stale answer;\n // a value that changed nothing keeps the store's state (and its readers) as is.\n useLayoutEffect(() => {\n const unavailableBefore = store.state.athenaUnavailable;\n if (sameReason(unavailableBefore, athenaUnavailable)) return;\n store.setState((prev) => ({ ...prev, athenaUnavailable }));\n if (unavailableBefore !== null && athenaUnavailable === null) {\n retryFailedFetches(store);\n }\n }, [athenaUnavailable, store]);\n\n const webpageFingerprint = webpageMentionFingerprint(webpages);\n const previousWebpageFingerprintRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (previousWebpageFingerprintRef.current === webpageFingerprint) return;\n previousWebpageFingerprintRef.current = webpageFingerprint;\n invalidate(\"root\");\n }, [invalidate, webpageFingerprint]);\n\n // A changed tool list drops the cached Tools / Toolkits entries (and the\n // root search results they were folded into) so the next open re-reads it.\n const toolsFingerprint = tools ? providedToolsFingerprint(tools) : null;\n const previousToolsFingerprintRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (previousToolsFingerprintRef.current === toolsFingerprint) return;\n previousToolsFingerprintRef.current = toolsFingerprint;\n if (toolsFingerprint === null) return;\n invalidate(\"tools\");\n invalidate(\"toolkits\");\n invalidate(\"global_search\");\n }, [invalidate, toolsFingerprint]);\n\n return { store, invalidate };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const reactStore = require("@tanstack/react-store");
|
|
4
|
-
const
|
|
4
|
+
const require$$0 = require("react");
|
|
5
5
|
const orchestrator = require("./orchestrator.cjs");
|
|
6
6
|
function useMenuItems(store, options) {
|
|
7
7
|
const { scope, query = "", minItems = 50, parentScope } = options;
|
|
8
|
-
const [targetCount, setTargetCount] =
|
|
9
|
-
|
|
8
|
+
const [targetCount, setTargetCount] = require$$0.useState(minItems);
|
|
9
|
+
require$$0.useEffect(() => {
|
|
10
10
|
setTargetCount(minItems);
|
|
11
11
|
}, [scope, query, minItems]);
|
|
12
12
|
const snapshot = reactStore.useStore(
|
|
13
13
|
store,
|
|
14
14
|
() => orchestrator.selectItems(store, scope, query, targetCount, parentScope)
|
|
15
15
|
);
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const waitsOnAthena = snapshot.unavailable !== null;
|
|
17
|
+
require$$0.useEffect(() => {
|
|
18
|
+
if (!waitsOnAthena && snapshot.items.length < targetCount && snapshot.hasMore && !snapshot.isFetching) {
|
|
18
19
|
orchestrator.triggerFetchIfNeeded(store, scope, query, targetCount, parentScope);
|
|
19
20
|
}
|
|
20
21
|
}, [
|
|
@@ -23,12 +24,13 @@ function useMenuItems(store, options) {
|
|
|
23
24
|
query,
|
|
24
25
|
targetCount,
|
|
25
26
|
parentScope,
|
|
27
|
+
waitsOnAthena,
|
|
26
28
|
snapshot.items.length,
|
|
27
29
|
snapshot.hasMore,
|
|
28
30
|
snapshot.isFetching
|
|
29
31
|
]);
|
|
30
32
|
const loadMore = () => {
|
|
31
|
-
if (snapshot.hasMore && !snapshot.isFetching) {
|
|
33
|
+
if (!waitsOnAthena && snapshot.hasMore && !snapshot.isFetching) {
|
|
32
34
|
setTargetCount((prev) => prev + 50);
|
|
33
35
|
}
|
|
34
36
|
};
|
|
@@ -36,6 +38,7 @@ function useMenuItems(store, options) {
|
|
|
36
38
|
items: snapshot.items,
|
|
37
39
|
isFetching: snapshot.isFetching,
|
|
38
40
|
hasMore: snapshot.hasMore,
|
|
41
|
+
unavailable: snapshot.unavailable,
|
|
39
42
|
loadMore,
|
|
40
43
|
targetCount
|
|
41
44
|
// Expose for debugging
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-menu-items.cjs","sources":["../../../../../src/chat-ui/mentions/suggestions/data/use-menu-items.ts"],"sourcesContent":["import { useStore } from '@tanstack/react-store';\nimport { useEffect, useState } from 'react';\nimport { selectItems, triggerFetchIfNeeded } from './orchestrator';\nimport type { MenuItem, MenuScope } from './types';\nimport type { MentionSuggestionsStore } from './use-mention-suggestions';\n\n/**\n * useMenuItems - Like React Query, but for menu items\n *\n * Clean, automatic hook that:\n * - Reads items from store (reactive!)\n * - Auto-fetches if needed (in useEffect)\n * - Returns clean interface { items, isFetching, hasMore }\n *\n * Usage:\n * ```typescript\n * const { items, isFetching, hasMore } = useMenuItems(store, {\n * scope: 'athena_folders',\n * query: 'doc',\n * minItems: 10,\n * parentScope: 'root'\n * });\n * ```\n */\nexport interface UseMenuItemsOptions {\n scope: MenuScope;\n query?: string;\n minItems?: number;\n parentScope?: MenuScope;\n}\n\nexport interface UseMenuItemsResult {\n items: MenuItem[];\n isFetching: boolean;\n hasMore: boolean;\n loadMore: () => void; // Explicit load more (not automatic!)\n targetCount: number; // Current target for debugging\n}\n\nexport function useMenuItems(\n store: MentionSuggestionsStore,\n options: UseMenuItemsOptions\n): UseMenuItemsResult {\n const { scope, query = '', minItems = 50, parentScope } = options;\n\n // Target item count (increases when user clicks \"Load More\")\n const [targetCount, setTargetCount] = useState(minItems);\n\n // Reset target when scope/query changes\n // biome-ignore lint/correctness/useExhaustiveDependencies: We intentionally reset on scope/query change\n useEffect(() => {\n setTargetCount(minItems);\n }, [scope, query, minItems]);\n\n // Read from store (pure, reactive)\n const snapshot = useStore(store, () =>\n selectItems(store, scope, query, targetCount, parentScope)\n );\n\n // Auto-fetch when: cached < target AND hasMore AND !fetching\n useEffect(() => {\n if (snapshot.items.length < targetCount
|
|
1
|
+
{"version":3,"file":"use-menu-items.cjs","sources":["../../../../../src/chat-ui/mentions/suggestions/data/use-menu-items.ts"],"sourcesContent":["import type { LabelCopy } from '@athenaintel/agent-runtime/offline-status';\nimport { useStore } from '@tanstack/react-store';\nimport { useEffect, useState } from 'react';\nimport { selectItems, triggerFetchIfNeeded } from './orchestrator';\nimport type { MenuItem, MenuScope } from './types';\nimport type { MentionSuggestionsStore } from './use-mention-suggestions';\n\n/**\n * useMenuItems - Like React Query, but for menu items\n *\n * Clean, automatic hook that:\n * - Reads items from store (reactive!)\n * - Auto-fetches if needed (in useEffect)\n * - Returns clean interface { items, isFetching, hasMore }\n *\n * Usage:\n * ```typescript\n * const { items, isFetching, hasMore } = useMenuItems(store, {\n * scope: 'athena_folders',\n * query: 'doc',\n * minItems: 10,\n * parentScope: 'root'\n * });\n * ```\n */\nexport interface UseMenuItemsOptions {\n scope: MenuScope;\n query?: string;\n minItems?: number;\n parentScope?: MenuScope;\n}\n\nexport interface UseMenuItemsResult {\n items: MenuItem[];\n isFetching: boolean;\n hasMore: boolean;\n /** Why this scope can't load from Athena right now (`null` while it can, or for local items). */\n unavailable: LabelCopy | null;\n loadMore: () => void; // Explicit load more (not automatic!)\n targetCount: number; // Current target for debugging\n}\n\nexport function useMenuItems(\n store: MentionSuggestionsStore,\n options: UseMenuItemsOptions\n): UseMenuItemsResult {\n const { scope, query = '', minItems = 50, parentScope } = options;\n\n // Target item count (increases when user clicks \"Load More\")\n const [targetCount, setTargetCount] = useState(minItems);\n\n // Reset target when scope/query changes\n // biome-ignore lint/correctness/useExhaustiveDependencies: We intentionally reset on scope/query change\n useEffect(() => {\n setTargetCount(minItems);\n }, [scope, query, minItems]);\n\n // Read from store (pure, reactive)\n const snapshot = useStore(store, () =>\n selectItems(store, scope, query, targetCount, parentScope)\n );\n\n // Auto-fetch when: cached < target AND hasMore AND !fetching (and Athena can be asked)\n const waitsOnAthena = snapshot.unavailable !== null;\n useEffect(() => {\n if (\n !waitsOnAthena &&\n snapshot.items.length < targetCount &&\n snapshot.hasMore &&\n !snapshot.isFetching\n ) {\n triggerFetchIfNeeded(store, scope, query, targetCount, parentScope);\n }\n }, [\n store,\n scope,\n query,\n targetCount,\n parentScope,\n waitsOnAthena,\n snapshot.items.length,\n snapshot.hasMore,\n snapshot.isFetching,\n ]);\n\n // Explicit load more: Increase target by 50\n const loadMore = () => {\n if (!waitsOnAthena && snapshot.hasMore && !snapshot.isFetching) {\n setTargetCount((prev) => prev + 50);\n }\n };\n\n return {\n items: snapshot.items,\n isFetching: snapshot.isFetching,\n hasMore: snapshot.hasMore,\n unavailable: snapshot.unavailable,\n loadMore,\n targetCount, // Expose for debugging\n };\n}\n"],"names":["useState","useEffect","useStore","selectItems","triggerFetchIfNeeded"],"mappings":";;;;;AA0CO,SAAS,aACd,OACA,SACoB;AACpB,QAAM,EAAE,OAAO,QAAQ,IAAI,WAAW,IAAI,gBAAgB;AAG1D,QAAM,CAAC,aAAa,cAAc,IAAIA,WAAAA,SAAS,QAAQ;AAIvDC,aAAAA,UAAU,MAAM;AACd,mBAAe,QAAQ;AAAA,EACzB,GAAG,CAAC,OAAO,OAAO,QAAQ,CAAC;AAG3B,QAAM,WAAWC,WAAAA;AAAAA,IAAS;AAAA,IAAO,MAC/BC,aAAAA,YAAY,OAAO,OAAO,OAAO,aAAa,WAAW;AAAA,EAAA;AAI3D,QAAM,gBAAgB,SAAS,gBAAgB;AAC/CF,aAAAA,UAAU,MAAM;AACd,QACE,CAAC,iBACD,SAAS,MAAM,SAAS,eACxB,SAAS,WACT,CAAC,SAAS,YACV;AACAG,mBAAAA,qBAAqB,OAAO,OAAO,OAAO,aAAa,WAAW;AAAA,IACpE;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,MAAM;AAAA,IACf,SAAS;AAAA,IACT,SAAS;AAAA,EAAA,CACV;AAGD,QAAM,WAAW,MAAM;AACrB,QAAI,CAAC,iBAAiB,SAAS,WAAW,CAAC,SAAS,YAAY;AAC9D,qBAAe,CAAC,SAAS,OAAO,EAAE;AAAA,IACpC;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,SAAS;AAAA,IAChB,YAAY,SAAS;AAAA,IACrB,SAAS,SAAS;AAAA,IAClB,aAAa,SAAS;AAAA,IACtB;AAAA,IACA;AAAA;AAAA,EAAA;AAEJ;;"}
|