@athenaintel/react 0.43.0 → 0.50.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 +258 -8
- 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/call-recap.cjs +319 -0
- package/dist/agent-runtime/src/call-recap.cjs.map +1 -0
- package/dist/agent-runtime/src/call-recap.d.ts +142 -0
- package/dist/agent-runtime/src/call-recap.js +319 -0
- package/dist/agent-runtime/src/call-recap.js.map +1 -0
- package/dist/agent-runtime/src/chat-outbox-store.cjs +1 -0
- package/dist/agent-runtime/src/chat-outbox-store.cjs.map +1 -1
- package/dist/agent-runtime/src/chat-outbox-store.d.ts +7 -0
- package/dist/agent-runtime/src/chat-outbox-store.js +1 -0
- package/dist/agent-runtime/src/chat-outbox-store.js.map +1 -1
- package/dist/agent-runtime/src/chat-outbox.cjs +46 -5
- package/dist/agent-runtime/src/chat-outbox.cjs.map +1 -1
- package/dist/agent-runtime/src/chat-outbox.d.ts +29 -0
- package/dist/agent-runtime/src/chat-outbox.js +46 -5
- package/dist/agent-runtime/src/chat-outbox.js.map +1 -1
- 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-index.d.ts +7 -0
- package/dist/agent-runtime/src/conversation-index.js.map +1 -1
- package/dist/agent-runtime/src/conversation-list.cjs +2 -1
- package/dist/agent-runtime/src/conversation-list.cjs.map +1 -1
- package/dist/agent-runtime/src/conversation-list.d.ts +19 -3
- package/dist/agent-runtime/src/conversation-list.js +2 -1
- package/dist/agent-runtime/src/conversation-list.js.map +1 -1
- 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 +16 -9
- package/dist/agent-runtime/src/interrupts.cjs +71 -19
- package/dist/agent-runtime/src/interrupts.cjs.map +1 -1
- package/dist/agent-runtime/src/interrupts.d.ts +40 -3
- package/dist/agent-runtime/src/interrupts.js +56 -4
- 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/model-context.cjs +3 -2
- package/dist/agent-runtime/src/model-context.cjs.map +1 -1
- package/dist/agent-runtime/src/model-context.d.ts +6 -1
- package/dist/agent-runtime/src/model-context.js +3 -2
- package/dist/agent-runtime/src/model-context.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 +41 -0
- package/dist/agent-runtime/src/send-recovery.cjs +37 -3
- package/dist/agent-runtime/src/send-recovery.cjs.map +1 -1
- package/dist/agent-runtime/src/send-recovery.d.ts +19 -0
- package/dist/agent-runtime/src/send-recovery.js +37 -3
- package/dist/agent-runtime/src/send-recovery.js.map +1 -1
- 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 +868 -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 -25
- 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 -25
- 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 +14 -13
- package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -1
- package/dist/agent-runtime/src/use-conversation-list.d.ts +6 -0
- package/dist/agent-runtime/src/use-conversation-list.js +3 -2
- package/dist/agent-runtime/src/use-conversation-list.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +45 -20
- 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 +10 -3
- package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +27 -2
- 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 +40 -22
- package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-runtime.d.ts +17 -0
- package/dist/agent-runtime/src/use-deep-agent-runtime.js +24 -6
- package/dist/agent-runtime/src/use-deep-agent-runtime.js.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 +588 -130
- package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +162 -10
- package/dist/agent-runtime/src/use-deep-agent-voice.js +529 -71
- 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 +34 -26
- package/dist/agent-runtime/src/voice-earcon.cjs +139 -0
- package/dist/agent-runtime/src/voice-earcon.cjs.map +1 -0
- package/dist/agent-runtime/src/voice-earcon.d.ts +38 -0
- package/dist/agent-runtime/src/voice-earcon.js +139 -0
- package/dist/agent-runtime/src/voice-earcon.js.map +1 -0
- 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 +63 -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-presentation.cjs +2 -0
- package/dist/agent-runtime/src/voice-presentation.cjs.map +1 -1
- package/dist/agent-runtime/src/voice-presentation.js +2 -0
- package/dist/agent-runtime/src/voice-presentation.js.map +1 -1
- 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 +18 -5
- 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 +23 -6
- 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 +166 -37
- package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
- package/dist/chat/StatewireApprovalCard.d.ts +91 -2
- package/dist/chat/StatewireApprovalCard.js +156 -27
- 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 +81 -69
- package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
- package/dist/chat/StatewireQueuedMessages.d.ts +25 -13
- package/dist/chat/StatewireQueuedMessages.js +73 -61
- package/dist/chat/StatewireQueuedMessages.js.map +1 -1
- package/dist/chat/WaitingOnYouBanner.cjs +9 -5
- package/dist/chat/WaitingOnYouBanner.cjs.map +1 -1
- package/dist/chat/WaitingOnYouBanner.js +7 -3
- package/dist/chat/WaitingOnYouBanner.js.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 +96 -29
- package/dist/chat/chat-voice-controls.cjs.map +1 -1
- package/dist/chat/chat-voice-controls.d.ts +42 -3
- package/dist/chat/chat-voice-controls.js +92 -25
- 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 +52 -36
- package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
- package/dist/chat/super-grouping/SuperGroupingCard.d.ts +19 -4
- package/dist/chat/super-grouping/SuperGroupingCard.js +29 -13
- 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 +73 -40
- package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
- package/dist/chat/super-grouping/ToolTimeline.d.ts +10 -2
- package/dist/chat/super-grouping/ToolTimeline.js +69 -36
- 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 +5 -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/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 +21 -0
- package/dist/chat-ui/index.cjs.map +1 -1
- package/dist/chat-ui/index.d.ts +8 -1
- package/dist/chat-ui/index.js +21 -0
- package/dist/chat-ui/index.js.map +1 -1
- package/dist/chat-ui/mentions/mention-chip.cjs +4 -4
- package/dist/chat-ui/mentions/mention-chip.cjs.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 +3 -3
- package/dist/chat-ui/mentions/use-mention-asset.cjs.map +1 -1
- 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/from-the-call-card.cjs +124 -0
- package/dist/chat-ui/messages/from-the-call-card.cjs.map +1 -0
- package/dist/chat-ui/messages/from-the-call-card.d.ts +17 -0
- package/dist/chat-ui/messages/from-the-call-card.js +124 -0
- package/dist/chat-ui/messages/from-the-call-card.js.map +1 -0
- 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 +3 -2
- package/dist/chat-ui/rich-text/chat-link.cjs.map +1 -1
- package/dist/chat-ui/rich-text/chat-link.d.ts +4 -0
- package/dist/chat-ui/rich-text/chat-link.js +4 -3
- package/dist/chat-ui/rich-text/chat-link.js.map +1 -1
- package/dist/chat-ui/rich-text/chat-message-body.cjs +9 -8
- package/dist/chat-ui/rich-text/chat-message-body.cjs.map +1 -1
- package/dist/chat-ui/rich-text/chat-message-body.d.ts +12 -0
- package/dist/chat-ui/rich-text/chat-message-body.js +2 -1
- package/dist/chat-ui/rich-text/chat-message-body.js.map +1 -1
- package/dist/chat-ui/rich-text/chat-node-views.cjs +6 -6
- package/dist/chat-ui/rich-text/chat-node-views.cjs.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 +45 -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 +37 -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 +52 -3
- package/dist/collab/client.cjs.map +1 -1
- package/dist/collab/client.d.ts +27 -0
- package/dist/collab/client.js +52 -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/index.d.ts +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 +27 -8
- package/dist/composer/useReadComposerDraft.cjs.map +1 -1
- package/dist/composer/useReadComposerDraft.d.ts +23 -1
- package/dist/composer/useReadComposerDraft.js +27 -8
- package/dist/composer/useReadComposerDraft.js.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 +29 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +18 -4
- package/dist/index.js +30 -3
- 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/unconfirmed-update-attributions.cjs +190 -0
- package/dist/keryx-http/src/unconfirmed-update-attributions.cjs.map +1 -0
- package/dist/keryx-http/src/unconfirmed-update-attributions.d.ts +132 -0
- package/dist/keryx-http/src/unconfirmed-update-attributions.js +190 -0
- package/dist/keryx-http/src/unconfirmed-update-attributions.js.map +1 -0
- package/dist/keryx-http/src/update-attributions.cjs +141 -0
- package/dist/keryx-http/src/update-attributions.cjs.map +1 -0
- package/dist/keryx-http/src/update-attributions.d.ts +107 -0
- package/dist/keryx-http/src/update-attributions.js +141 -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 +120 -79
- package/dist/provider/AthenaProvider.cjs.map +1 -1
- package/dist/provider/AthenaProvider.d.ts +11 -1
- package/dist/provider/AthenaProvider.js +44 -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/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/api.cjs.map +1 -1
- package/dist/threads/api.d.ts +15 -0
- package/dist/threads/api.js.map +1 -1
- package/dist/threads/conversation-list-fetcher.cjs +13 -5
- package/dist/threads/conversation-list-fetcher.cjs.map +1 -1
- package/dist/threads/conversation-list-fetcher.d.ts +4 -1
- package/dist/threads/conversation-list-fetcher.js +13 -5
- package/dist/threads/conversation-list-fetcher.js.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 +79 -57
- package/dist/threads/statewire-thread-list.cjs.map +1 -1
- package/dist/threads/statewire-thread-list.d.ts +20 -8
- package/dist/threads/statewire-thread-list.js +28 -6
- 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 +37 -15
- package/dist/threads/use-athena-sessions.cjs.map +1 -1
- package/dist/threads/use-athena-sessions.d.ts +10 -5
- package/dist/threads/use-athena-sessions.js +28 -6
- package/dist/threads/use-athena-sessions.js.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-rest-conversation-history.d.ts +1 -0
- 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-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":"SessionsPage.cjs","sources":["../../src/threads/SessionsPage.tsx"],"sourcesContent":["/**\n * `SessionsPage` — a full-page, Devin-style session list: filter chips that\n * the server applies (status, pull requests, unread, pinned, creator, agent,\n * mode, origin, created / updated date), a title search, display options\n * (sort, direction, grouping, columns), an attention-coloured status column\n * that says what the person must do next, row actions (read, pin, archive)\n * and a CSV export of the loaded rows. Live through the thread-list\n * provider's conversation index; renders nothing outside\n * `<AthenaProvider enableThreadList>`.\n */\nimport {\n ArchiveIcon,\n CheckIcon,\n DownloadIcon,\n FilterIcon,\n MailIcon,\n MailOpenIcon,\n PinIcon,\n PlusIcon,\n RefreshCwIcon,\n SearchIcon,\n SlidersHorizontalIcon,\n XIcon,\n} from 'lucide-react';\nimport type { FC, ReactNode } from 'react';\nimport { useContext, useEffect, useMemo, useRef, useState } from 'react';\nimport { cn } from '../lib/utils';\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';\nimport { SessionListSkeleton, type SessionOpenTarget } from './SessionList';\nimport { pullRequestChip, relativeTime, sessionOriginLabel } from './session-list-model';\nimport { FOCUS_RING_CLASS, PullRequestChip, RowIconButton, StatusChip } from './session-row-parts';\nimport {\n agentLabel,\n channelLabel,\n creatorLabel,\n datePresetBounds,\n groupSessionsBy,\n runStatusLabel,\n SESSIONS_COLUMNS,\n SESSIONS_DATE_PRESETS,\n type SessionsColumnId,\n type SessionsDatePreset,\n type SessionsGroupBy,\n type SessionsLabels,\n sessionsCsv,\n sessionsFilterChips,\n plainExcerpt,\n sessionStatusChip,\n} from './sessions-page-model';\nimport {\n readSessionsPageSettings,\n type SessionsPageDisplay,\n writeSessionsPageSettings,\n} from './sessions-page-storage';\nimport {\n type AthenaSessionsQuery,\n type AthenaSessionsQueryField,\n DEFAULT_COLLAB_CHANNEL,\n normalizeSessionsQuery,\n SESSION_RUN_STATUSES,\n type SessionRunStatus,\n sessionsQueryKey,\n} from './sessions-query';\nimport {\n AthenaSessionsLiveContext,\n type AthenaStatewireThreadListState,\n type AthenaStatewireThreadSummary,\n useAthenaStatewireThreadList,\n} from './statewire-thread-list';\nimport { useAthenaSessions } from './use-athena-sessions';\n\nexport interface SessionsPageProps {\n className?: string;\n /** Heading (default \"Sessions\"). */\n title?: string;\n /**\n * Called after a row is selected (the provider's chat switches to it), so\n * a host can navigate to its chat view.\n */\n onOpenSession?: (target: SessionOpenTarget) => void;\n /** Names for collab agents and channels (filters, the Mode column, CSV); ids show otherwise. */\n labels?: SessionsLabels;\n /**\n * Namespaces what this browser remembers — \"Save as default\" and the\n * display options — so a host with several pages keeps them apart\n * (default `\"default\"`).\n */\n storageKey?: string;\n /** The filters before anything is saved as default. */\n defaultQuery?: AthenaSessionsQuery;\n /** Rows per page (default 50). */\n pageSize?: number;\n /** Offer \"New session\" (default `true`). */\n showNewSession?: boolean;\n /** Called after \"New session\" starts a fresh chat, so a host can show its chat view. */\n onNewSession?: () => void;\n}\n\n/** What each query field is called in notices. */\nconst FIELD_LABEL: Record<AthenaSessionsQueryField, string> = {\n search: 'search',\n collabAgentIds: 'agent',\n collabChannelIds: 'mode',\n startChannels: 'origin',\n createdAfter: 'created date',\n createdBefore: 'created date',\n updatedAfter: 'updated date',\n updatedBefore: 'updated date',\n favoritesOnly: 'pinned',\n unreadOnly: 'unread',\n runStatuses: 'status',\n sessionStatuses: 'session status',\n hasPullRequests: 'pull requests',\n createdByMe: 'creator',\n excludeDismissed: 'dismissed',\n excludeTriggered: 'who started it',\n sort: 'sort',\n direction: 'sort direction',\n};\n\n/** \"agent\", \"agent and mode\", \"agent, mode and unread\". */\nfunction fieldList(fields: readonly AthenaSessionsQueryField[]): string {\n const names = [...new Set(fields.map((field) => FIELD_LABEL[field]))];\n return names.length <= 1 ? (names[0] ?? '') : `${names.slice(0, -1).join(', ')} and ${names.at(-1)}`;\n}\n\nconst COLUMN_WIDTH: Record<SessionsColumnId, string> = {\n status: 'w-56',\n origin: 'w-24',\n mode: 'w-28',\n pullRequests: 'w-24',\n creator: 'w-32',\n created: 'w-24',\n updated: 'w-24',\n};\n\n/** Save `text` as a file in the browser. */\nfunction downloadText(filename: string, text: string, type: string): void {\n if (typeof document === 'undefined') return;\n const url = URL.createObjectURL(new Blob([text], { type }));\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = filename;\n anchor.rel = 'noopener';\n document.body.appendChild(anchor);\n anchor.click();\n anchor.remove();\n setTimeout(() => URL.revokeObjectURL(url), 0);\n}\n\nconst SECTION_HEADING_CLASS =\n 'px-3 pb-1 pt-3 text-left font-medium text-[11px] text-muted-foreground/70 uppercase tracking-wide';\n\n/** A pressable option in a filter or display menu. */\nconst MenuOption: FC<{\n label: string;\n selected: boolean;\n onSelect: () => void;\n disabled?: boolean;\n role?: 'menuitemcheckbox' | 'menuitemradio';\n}> = ({ label, selected, onSelect, disabled = false, role = 'menuitemcheckbox' }) => (\n <button\n type=\"button\"\n role={role}\n aria-checked={selected}\n disabled={disabled}\n onClick={onSelect}\n className={cn(\n 'flex w-full items-center gap-2 rounded-sm px-2 py-1 text-left text-xs transition-colors hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50',\n FOCUS_RING_CLASS,\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn(\n 'flex size-3.5 shrink-0 items-center justify-center rounded-sm border border-border',\n selected && 'border-primary bg-primary text-primary-foreground',\n )}\n >\n {selected ? <CheckIcon className=\"size-3\" /> : null}\n </span>\n <span className=\"truncate\">{label}</span>\n </button>\n);\n\nconst MenuSection: FC<{ title: string; hint?: string | null; children: ReactNode }> = ({\n title,\n hint,\n children,\n}) => (\n <section aria-label={title} className=\"py-1\">\n <h4 className=\"px-2 pb-0.5 font-medium text-[11px] text-muted-foreground uppercase tracking-wide\">\n {title}\n </h4>\n {hint ? <p className=\"px-2 pb-1 text-[11px] text-muted-foreground\">{hint}</p> : null}\n {children}\n </section>\n);\n\nfunction toggleValue<T extends string>(values: readonly T[] | undefined, value: T): T[] {\n const current = values ?? [];\n return current.includes(value) ? current.filter((item) => item !== value) : [...current, value];\n}\n\nfunction datePresetOf(after: string | undefined, before: string | undefined, presets: Record<SessionsDatePreset, { after?: string; before?: string }>): SessionsDatePreset | null {\n for (const preset of SESSIONS_DATE_PRESETS) {\n const bounds = presets[preset.id];\n if ((bounds.after ?? undefined) === after && (bounds.before ?? undefined) === before) {\n return preset.id;\n }\n }\n return null;\n}\n\ninterface FilterMenuProps {\n query: AthenaSessionsQuery;\n setQuery: (update: (query: AthenaSessionsQuery) => AthenaSessionsQuery) => void;\n unavailable: ReadonlySet<AthenaSessionsQueryField>;\n agentOptions: readonly string[];\n channelOptions: readonly string[];\n originOptions: readonly string[];\n labels: SessionsLabels | undefined;\n}\n\nconst UNAVAILABLE_HINT = 'This Athena server cannot filter by this yet.';\n\n/** Every filter, stacked by kind; each option toggles at once. */\nconst FilterMenu: FC<FilterMenuProps> = ({\n query,\n setQuery,\n unavailable,\n agentOptions,\n channelOptions,\n originOptions,\n labels,\n}) => {\n // The presets' bounds are captured when the menu opens, so a selected\n // preset stays recognisable while it is open.\n const [presetBounds] = useState(() =>\n Object.fromEntries(\n SESSIONS_DATE_PRESETS.map((preset) => [preset.id, datePresetBounds(preset.id)]),\n ) as Record<SessionsDatePreset, { after?: string; before?: string }>,\n );\n const createdPreset = datePresetOf(query.createdAfter, query.createdBefore, presetBounds);\n const updatedPreset = datePresetOf(query.updatedAfter, query.updatedBefore, presetBounds);\n const setPreset = (\n kind: 'created' | 'updated',\n preset: SessionsDatePreset | null,\n ) =>\n setQuery((current) => {\n const bounds = preset ? presetBounds[preset] : {};\n return kind === 'created'\n ? { ...current, createdAfter: bounds.after, createdBefore: bounds.before }\n : { ...current, updatedAfter: bounds.after, updatedBefore: bounds.before };\n });\n const disabledHint = (field: AthenaSessionsQueryField) =>\n unavailable.has(field) ? UNAVAILABLE_HINT : null;\n\n return (\n <div role=\"menu\" aria-label=\"Filters\" className=\"max-h-[70vh] overflow-y-auto p-1\">\n <MenuSection title=\"Status\" hint={disabledHint('runStatuses')}>\n {SESSION_RUN_STATUSES.map((status) => (\n <MenuOption\n key={status}\n label={runStatusLabel(status)}\n selected={query.runStatuses?.includes(status) ?? false}\n disabled={unavailable.has('runStatuses')}\n onSelect={() =>\n setQuery((current) => ({\n ...current,\n runStatuses: toggleValue<SessionRunStatus>(current.runStatuses, status),\n }))\n }\n />\n ))}\n </MenuSection>\n <MenuSection title=\"Pull requests\" hint={disabledHint('hasPullRequests')}>\n {(\n [\n ['Has pull requests', true],\n ['No pull requests', false],\n ] as const\n ).map(([label, value]) => (\n <MenuOption\n key={label}\n role=\"menuitemradio\"\n label={label}\n selected={query.hasPullRequests === value}\n disabled={unavailable.has('hasPullRequests')}\n onSelect={() =>\n setQuery((current) => ({\n ...current,\n hasPullRequests: current.hasPullRequests === value ? undefined : value,\n }))\n }\n />\n ))}\n </MenuSection>\n <MenuSection title=\"Read and pinned\">\n <MenuOption\n label=\"Unread\"\n selected={query.unreadOnly === true}\n disabled={unavailable.has('unreadOnly')}\n onSelect={() => setQuery((current) => ({ ...current, unreadOnly: !current.unreadOnly }))}\n />\n <MenuOption\n label=\"Pinned\"\n selected={query.favoritesOnly === true}\n disabled={unavailable.has('favoritesOnly')}\n onSelect={() =>\n setQuery((current) => ({ ...current, favoritesOnly: !current.favoritesOnly }))\n }\n />\n </MenuSection>\n <MenuSection title=\"Creator\" hint={disabledHint('createdByMe')}>\n {(\n [\n ['You', true],\n ['Shared with you', false],\n ] as const\n ).map(([label, value]) => (\n <MenuOption\n key={label}\n role=\"menuitemradio\"\n label={label}\n selected={query.createdByMe === value}\n disabled={unavailable.has('createdByMe')}\n onSelect={() =>\n setQuery((current) => ({\n ...current,\n createdByMe: current.createdByMe === value ? undefined : value,\n }))\n }\n />\n ))}\n <MenuOption\n label=\"Started by a person\"\n selected={query.excludeTriggered === true}\n onSelect={() =>\n setQuery((current) => ({ ...current, excludeTriggered: !current.excludeTriggered }))\n }\n />\n </MenuSection>\n {agentOptions.length > 0 ? (\n <MenuSection title=\"Agent\" hint={disabledHint('collabAgentIds')}>\n {agentOptions.map((agentId) => (\n <MenuOption\n key={agentId}\n label={agentLabel(agentId, labels)}\n selected={query.collabAgentIds?.includes(agentId) ?? false}\n disabled={unavailable.has('collabAgentIds')}\n onSelect={() =>\n setQuery((current) => ({\n ...current,\n collabAgentIds: toggleValue(current.collabAgentIds, agentId),\n }))\n }\n />\n ))}\n </MenuSection>\n ) : null}\n {agentOptions.length > 0 ? (\n <MenuSection\n title=\"Mode\"\n hint={\n disabledHint('collabChannelIds') ??\n (query.collabAgentIds?.length ? null : 'Pick an agent first: a mode is one of its channels.')\n }\n >\n {channelOptions.map((channelId) => (\n <MenuOption\n key={channelId}\n label={channelLabel(channelId, labels)}\n selected={query.collabChannelIds?.includes(channelId) ?? false}\n disabled={unavailable.has('collabChannelIds') || !query.collabAgentIds?.length}\n onSelect={() =>\n setQuery((current) => ({\n ...current,\n collabChannelIds: toggleValue(current.collabChannelIds, channelId),\n }))\n }\n />\n ))}\n </MenuSection>\n ) : null}\n {originOptions.length > 0 ? (\n <MenuSection title=\"Origin\" hint={disabledHint('startChannels')}>\n {originOptions.map((channel) => (\n <MenuOption\n key={channel}\n label={sessionOriginLabel({ startChannel: channel, appId: null, triggerType: null }) ?? channel}\n selected={query.startChannels?.includes(channel) ?? false}\n disabled={unavailable.has('startChannels')}\n onSelect={() =>\n setQuery((current) => ({\n ...current,\n startChannels: toggleValue(current.startChannels, channel),\n }))\n }\n />\n ))}\n </MenuSection>\n ) : null}\n <MenuSection title=\"Created\">\n {SESSIONS_DATE_PRESETS.map((preset) => (\n <MenuOption\n key={preset.id}\n role=\"menuitemradio\"\n label={preset.label}\n selected={createdPreset === preset.id}\n onSelect={() => setPreset('created', createdPreset === preset.id ? null : preset.id)}\n />\n ))}\n </MenuSection>\n <MenuSection title=\"Updated\">\n {SESSIONS_DATE_PRESETS.map((preset) => (\n <MenuOption\n key={preset.id}\n role=\"menuitemradio\"\n label={preset.label}\n selected={updatedPreset === preset.id}\n onSelect={() => setPreset('updated', updatedPreset === preset.id ? null : preset.id)}\n />\n ))}\n </MenuSection>\n </div>\n );\n};\n\nconst DisplayMenu: FC<{\n query: AthenaSessionsQuery;\n setQuery: (update: (query: AthenaSessionsQuery) => AthenaSessionsQuery) => void;\n display: SessionsPageDisplay;\n setDisplay: (update: (display: SessionsPageDisplay) => SessionsPageDisplay) => void;\n}> = ({ query, setQuery, display, setDisplay }) => {\n const sort = query.sort ?? 'updated';\n const direction = query.direction ?? 'desc';\n return (\n <div role=\"menu\" aria-label=\"Display options\" className=\"p-1\">\n <MenuSection title=\"Sort by\">\n {(\n [\n ['updated', 'Last updated'],\n ['created', 'Created'],\n ] as const\n ).map(([value, label]) => (\n <MenuOption\n key={value}\n role=\"menuitemradio\"\n label={label}\n selected={sort === value}\n onSelect={() => setQuery((current) => ({ ...current, sort: value }))}\n />\n ))}\n </MenuSection>\n <MenuSection title=\"Order\">\n {(\n [\n ['desc', 'Newest first'],\n ['asc', 'Oldest first'],\n ] as const\n ).map(([value, label]) => (\n <MenuOption\n key={value}\n role=\"menuitemradio\"\n label={label}\n selected={direction === value}\n onSelect={() => setQuery((current) => ({ ...current, direction: value }))}\n />\n ))}\n </MenuSection>\n <MenuSection title=\"Group by\">\n {(\n [\n ['attention', 'What it needs'],\n ['status', 'Run status'],\n ['none', 'No grouping'],\n ] as const\n ).map(([value, label]) => (\n <MenuOption\n key={value}\n role=\"menuitemradio\"\n label={label}\n selected={display.groupBy === value}\n onSelect={() => setDisplay((current) => ({ ...current, groupBy: value }))}\n />\n ))}\n </MenuSection>\n <MenuSection title=\"Columns\">\n {SESSIONS_COLUMNS.map((column) => (\n <MenuOption\n key={column.id}\n label={column.label}\n selected={display.columns.includes(column.id)}\n onSelect={() =>\n setDisplay((current) => ({\n ...current,\n columns: current.columns.includes(column.id)\n ? current.columns.filter((id) => id !== column.id)\n : SESSIONS_COLUMNS.map((candidate) => candidate.id).filter(\n (id) => id === column.id || current.columns.includes(id),\n ),\n }))\n }\n />\n ))}\n </MenuSection>\n </div>\n );\n};\n\nconst HEADER_BUTTON_CLASS = cn(\n 'inline-flex h-8 items-center gap-1.5 rounded-md border border-border/60 px-2.5 font-medium text-muted-foreground text-xs transition-colors hover:bg-muted hover:text-foreground disabled:opacity-50',\n FOCUS_RING_CLASS,\n);\n\nconst SessionsRow: FC<{\n row: AthenaStatewireThreadSummary;\n columns: readonly SessionsColumnId[];\n isActive: boolean;\n labels: SessionsLabels | undefined;\n list: AthenaStatewireThreadListState;\n onOpen: (row: AthenaStatewireThreadSummary) => void;\n}> = ({ row, columns, isActive, labels, list, onOpen }) => {\n const status = sessionStatusChip(row);\n const excerpt = plainExcerpt(row.preview);\n const chip = pullRequestChip(row.pullRequests);\n const origin = sessionOriginLabel(row);\n const cell = (id: SessionsColumnId): ReactNode => {\n switch (id) {\n case 'status':\n return <StatusChip label={status.label} tone={status.tone} detail={status.detail} />;\n case 'origin':\n return origin ? (\n <span className=\"rounded-full border border-border/60 px-1.5 py-px text-[10px] text-muted-foreground\">\n {origin}\n </span>\n ) : null;\n case 'mode':\n return row.collabAgentId ? (\n <span className=\"truncate text-muted-foreground text-xs\">\n {channelLabel(row.collabChannelId, labels)}\n </span>\n ) : null;\n case 'pullRequests':\n return chip ? <PullRequestChip chip={chip} pullRequests={row.pullRequests ?? []} /> : null;\n case 'creator':\n return (\n <span className=\"truncate text-muted-foreground text-xs\">{creatorLabel(row.createdByMe)}</span>\n );\n case 'created':\n return (\n <span className=\"text-muted-foreground text-xs\">\n {row.createdAt ? relativeTime(row.createdAt) : ''}\n </span>\n );\n case 'updated':\n return <span className=\"text-muted-foreground text-xs\">{relativeTime(row.updatedAt)}</span>;\n }\n };\n return (\n <tr\n data-thread-id={row.id}\n data-active={isActive || undefined}\n data-unread={row.isUnread || undefined}\n onClick={() => onOpen(row)}\n className={cn(\n 'group cursor-pointer border-border/40 border-b transition-colors hover:bg-muted/40',\n isActive && 'bg-muted',\n )}\n >\n <td className=\"min-w-0 py-2 pr-2 pl-3 align-top\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span\n role={row.isUnread ? 'img' : undefined}\n aria-label={row.isUnread ? 'Unread' : undefined}\n aria-hidden={row.isUnread ? undefined : true}\n className={cn('size-2 shrink-0 rounded-full', row.isUnread ? 'bg-primary' : 'bg-transparent')}\n />\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onOpen(row);\n }}\n className={cn(\n 'min-w-0 truncate text-left text-foreground text-sm',\n row.isUnread ? 'font-semibold' : 'font-medium',\n FOCUS_RING_CLASS,\n )}\n >\n {row.title ?? 'Untitled'}\n </button>\n {row.isFavorited ? (\n <PinIcon role=\"img\" aria-label=\"Pinned\" className=\"size-3 shrink-0 fill-current text-muted-foreground\" />\n ) : null}\n </div>\n {excerpt ? <p className=\"mt-0.5 truncate pl-4 text-muted-foreground text-xs\">{excerpt}</p> : null}\n </td>\n {columns.map((id) => (\n <td key={id} data-column={id} className=\"min-w-0 truncate px-2 py-2 align-top\">\n {cell(id)}\n </td>\n ))}\n <td className=\"py-1.5 pr-2 align-top\">\n <div data-row-actions className=\"flex items-center justify-end gap-0.5\">\n <RowIconButton\n label={row.isUnread ? 'Mark read' : 'Mark unread'}\n action=\"read-state\"\n pending={list.readStatePendingThreadIds.has(row.id)}\n onClick={() =>\n list.setReadState({ threadId: row.id, isUnread: !row.isUnread, updatedAt: row.updatedAt })\n }\n >\n {row.isUnread ? <MailOpenIcon className=\"size-3.5\" aria-hidden /> : <MailIcon className=\"size-3.5\" aria-hidden />}\n </RowIconButton>\n {list.favoriteToggleAvailable ? (\n <RowIconButton\n label={row.isFavorited ? 'Unpin session' : 'Pin session'}\n action=\"pin\"\n pressed={row.isFavorited}\n pending={list.favoritePendingThreadIds.has(row.id)}\n onClick={() => list.setFavorited({ threadId: row.id, isFavorited: !row.isFavorited })}\n >\n <PinIcon className={cn('size-3.5', row.isFavorited && 'fill-current')} aria-hidden />\n </RowIconButton>\n ) : null}\n {list.archiveAvailable ? (\n <RowIconButton\n label=\"Archive session\"\n action=\"archive\"\n pending={list.archivePendingThreadIds.has(row.id)}\n onClick={() => list.archiveThread(row.id)}\n >\n <ArchiveIcon className=\"size-3.5\" aria-hidden />\n </RowIconButton>\n ) : null}\n </div>\n </td>\n </tr>\n );\n};\n\nfunction SessionsPageBody({\n className,\n title = 'Sessions',\n onOpenSession,\n labels,\n storageKey = 'default',\n defaultQuery,\n pageSize,\n showNewSession = true,\n onNewSession,\n list,\n}: SessionsPageProps & { list: AthenaStatewireThreadListState }) {\n const [initial] = useState(() => readSessionsPageSettings(storageKey));\n const [savedDefault, setSavedDefault] = useState<AthenaSessionsQuery | null>(initial.defaultQuery);\n const [query, setQueryState] = useState<AthenaSessionsQuery>(\n () => initial.defaultQuery ?? normalizeSessionsQuery(defaultQuery ?? {}),\n );\n const [display, setDisplayState] = useState<SessionsPageDisplay>(initial.display);\n const [searchInput, setSearchInput] = useState(query.search ?? '');\n\n const setQuery = (update: (current: AthenaSessionsQuery) => AthenaSessionsQuery) =>\n setQueryState((current) => normalizeSessionsQuery(update(current)));\n const setDisplay = (update: (current: SessionsPageDisplay) => SessionsPageDisplay) =>\n setDisplayState((current) => {\n const next = update(current);\n writeSessionsPageSettings(storageKey, { defaultQuery: savedDefault, display: next });\n return next;\n });\n\n // The search box types freely; the list follows a beat later.\n useEffect(() => {\n const handle = setTimeout(() => {\n setQueryState((current) => {\n const search = searchInput.trim();\n if ((current.search ?? '') === search) return current;\n return normalizeSessionsQuery({ ...current, search });\n });\n }, 250);\n return () => clearTimeout(handle);\n }, [searchInput]);\n\n const sessions = useAthenaSessions({ query, ...(pageSize ? { pageSize } : {}) });\n const unavailable = useMemo(\n () => new Set([...sessions.unsupportedFields, ...sessions.unavailableFields]),\n [sessions.unsupportedFields, sessions.unavailableFields],\n );\n\n // Filter options: every agent, channel and origin this page has shown, so\n // narrowing the list never hides the option that would widen it again.\n const seenRef = useRef({ agents: new Set<string>(), channels: new Set<string>(), origins: new Set<string>() });\n for (const row of sessions.rows) {\n if (row.collabAgentId) {\n seenRef.current.agents.add(row.collabAgentId);\n seenRef.current.channels.add(row.collabChannelId || DEFAULT_COLLAB_CHANNEL);\n }\n if (row.startChannel) seenRef.current.origins.add(row.startChannel);\n }\n const agentOptions = [\n ...new Set([...Object.keys(labels?.agents ?? {}), ...seenRef.current.agents, ...(query.collabAgentIds ?? [])]),\n ];\n const channelOptions = [\n ...new Set([\n DEFAULT_COLLAB_CHANNEL,\n ...Object.keys(labels?.channels ?? {}),\n ...seenRef.current.channels,\n ...(query.collabChannelIds ?? []),\n ]),\n ];\n const originOptions = [...new Set([...seenRef.current.origins, ...(query.startChannels ?? [])])];\n\n const chips = sessionsFilterChips(query, labels);\n const sections = groupSessionsBy(sessions.rows, display.groupBy);\n const columns = SESSIONS_COLUMNS.map((column) => column.id).filter((id) => display.columns.includes(id));\n const { search: _search, ...queryWithoutSearch } = query;\n const isSavedDefault =\n savedDefault !== null && sessionsQueryKey(savedDefault) === sessionsQueryKey(queryWithoutSearch);\n const hasFilters = chips.length > 0;\n\n const open = (row: AthenaStatewireThreadSummary) => {\n list.selectThread(row.id);\n onOpenSession?.({ threadId: row.id, title: row.title });\n };\n const saveAsDefault = () => {\n const saved = normalizeSessionsQuery(queryWithoutSearch);\n setSavedDefault(saved);\n writeSessionsPageSettings(storageKey, { defaultQuery: saved, display });\n };\n const resetToDefault = () => {\n setQueryState({ ...(savedDefault ?? normalizeSessionsQuery(defaultQuery ?? {})) });\n setSearchInput('');\n };\n const clearFilters = () => {\n setQuery((current) => ({ sort: current.sort, direction: current.direction, search: current.search }));\n };\n const removeChip = (field: AthenaSessionsQueryField) =>\n setQuery((current) => {\n const next: AthenaSessionsQuery = { ...current, [field]: undefined };\n if (field === 'collabAgentIds') next.collabChannelIds = undefined;\n return next;\n });\n const exportCsv = () =>\n downloadText(\n `sessions-${new Date().toISOString().slice(0, 10)}.csv`,\n sessionsCsv(sessions.rows, labels),\n 'text/csv;charset=utf-8',\n );\n\n // Skeletons only while there is nothing to show; a changed query keeps the\n // previous rows (narrowed by it) until its own page answers.\n const showSkeleton =\n sessions.rows.length === 0 && (!sessions.hasResolvedFirstPage || sessions.isFetching);\n\n return (\n <div\n data-testid=\"sessions-page\"\n className={cn('athena-sdk-chrome flex min-h-0 flex-col gap-3 p-4', className)}\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"font-semibold text-base text-foreground\">{title}</h2>\n <span data-testid=\"sessions-count\" className=\"text-muted-foreground text-xs\">\n {sessions.rows.length}\n {sessions.hasNextPage ? '+' : ''}\n </span>\n <div className=\"flex-1\" />\n <label className=\"relative block w-64 max-w-full\">\n <SearchIcon className=\"pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2 text-muted-foreground\" />\n <span className=\"sr-only\">Search sessions</span>\n <input\n type=\"search\"\n value={searchInput}\n onChange={(event) => setSearchInput(event.target.value)}\n placeholder=\"Search sessions…\"\n className=\"h-8 w-full rounded-md border border-border/60 bg-muted/40 pr-2 pl-8 text-sm outline-none focus:border-primary focus:bg-background\"\n />\n </label>\n <Popover>\n <PopoverTrigger asChild>\n <button type=\"button\" className={HEADER_BUTTON_CLASS} aria-label=\"Display options\">\n <SlidersHorizontalIcon className=\"size-3.5\" aria-hidden />\n Display\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-56\">\n <DisplayMenu query={query} setQuery={setQuery} display={display} setDisplay={setDisplay} />\n </PopoverContent>\n </Popover>\n <button\n type=\"button\"\n onClick={exportCsv}\n disabled={sessions.rows.length === 0}\n className={HEADER_BUTTON_CLASS}\n title=\"Export the loaded sessions as CSV\"\n >\n <DownloadIcon className=\"size-3.5\" aria-hidden />\n Export CSV\n </button>\n <button\n type=\"button\"\n onClick={sessions.refresh}\n disabled={sessions.isFetching}\n className={HEADER_BUTTON_CLASS}\n aria-label=\"Refresh sessions\"\n title=\"Refresh sessions\"\n >\n <RefreshCwIcon className={cn('size-3.5', sessions.isFetching && 'animate-spin')} aria-hidden />\n </button>\n {showNewSession ? (\n <button\n type=\"button\"\n onClick={() => {\n list.newThread();\n onNewSession?.();\n }}\n className={cn(\n 'inline-flex h-8 items-center gap-1.5 rounded-md bg-primary px-3 font-medium text-primary-foreground text-xs transition-colors hover:bg-primary/90',\n FOCUS_RING_CLASS,\n )}\n >\n <PlusIcon className=\"size-3.5\" aria-hidden />\n New session\n </button>\n ) : null}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-1.5\" data-testid=\"sessions-filters\">\n <Popover>\n <PopoverTrigger asChild>\n <button type=\"button\" className={HEADER_BUTTON_CLASS}>\n <FilterIcon className=\"size-3.5\" aria-hidden />\n Filter\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-64\">\n <FilterMenu\n query={query}\n setQuery={setQuery}\n unavailable={unavailable}\n agentOptions={agentOptions}\n channelOptions={channelOptions}\n originOptions={originOptions}\n labels={labels}\n />\n </PopoverContent>\n </Popover>\n {chips.map((chip) => (\n <span\n key={chip.field + chip.label}\n data-filter-chip={chip.field}\n className=\"inline-flex h-7 items-center gap-1 rounded-full border border-border/60 bg-muted/40 pr-1 pl-2.5 text-foreground text-xs\"\n >\n {chip.label}\n <button\n type=\"button\"\n aria-label={`Remove filter ${chip.label}`}\n onClick={() => removeChip(chip.field)}\n className={cn('rounded-full p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground', FOCUS_RING_CLASS)}\n >\n <XIcon className=\"size-3\" aria-hidden />\n </button>\n </span>\n ))}\n {hasFilters ? (\n <button type=\"button\" onClick={clearFilters} className={cn('px-1.5 text-muted-foreground text-xs hover:text-foreground', FOCUS_RING_CLASS)}>\n Clear\n </button>\n ) : null}\n <div className=\"flex-1\" />\n {savedDefault !== null && !isSavedDefault ? (\n <button type=\"button\" onClick={resetToDefault} className={cn('px-1.5 text-muted-foreground text-xs hover:text-foreground', FOCUS_RING_CLASS)}>\n Reset to default\n </button>\n ) : null}\n <button\n type=\"button\"\n onClick={saveAsDefault}\n disabled={isSavedDefault}\n className={cn('px-1.5 text-muted-foreground text-xs hover:text-foreground disabled:opacity-50', FOCUS_RING_CLASS)}\n >\n {isSavedDefault ? 'Saved as default' : 'Save as default'}\n </button>\n </div>\n\n {sessions.degradedFields.length > 0 || sessions.unavailableFields.length > 0 ? (\n <p\n role=\"status\"\n data-testid=\"sessions-degraded\"\n className=\"rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-amber-900 text-xs\"\n >\n {sessions.degradedFields.length > 0\n ? `This Athena server cannot filter by ${fieldList(sessions.degradedFields)} yet, so they apply to the sessions loaded so far. `\n : ''}\n {sessions.unavailableFields.length > 0\n ? `Filtering by ${fieldList(sessions.unavailableFields)} is not available on this server yet and is off.`\n : ''}\n </p>\n ) : null}\n\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {showSkeleton ? (\n <SessionListSkeleton rows={6} />\n ) : sections.length === 0 ? (\n <div data-testid=\"sessions-empty\" className=\"flex flex-col items-center gap-2 py-12 text-center\">\n <p className=\"text-muted-foreground text-sm\">\n {hasFilters || query.search ? 'No sessions match these filters.' : 'No sessions yet.'}\n </p>\n {hasFilters ? (\n <button type=\"button\" onClick={clearFilters} className={HEADER_BUTTON_CLASS}>\n Clear filters\n </button>\n ) : null}\n </div>\n ) : (\n <table className=\"w-full table-fixed border-collapse text-sm\" aria-busy={sessions.isFetching || undefined}>\n <thead>\n <tr className=\"border-border/60 border-b text-left text-[11px] text-muted-foreground uppercase tracking-wide\">\n <th scope=\"col\" className=\"py-2 pl-7 font-medium\">\n Session\n </th>\n {columns.map((id) => (\n <th key={id} scope=\"col\" className={cn('px-2 py-2 font-medium', COLUMN_WIDTH[id])}>\n {SESSIONS_COLUMNS.find((column) => column.id === id)?.label}\n </th>\n ))}\n <th scope=\"col\" className=\"w-24 py-2 pr-2\">\n <span className=\"sr-only\">Actions</span>\n </th>\n </tr>\n </thead>\n {sections.map((section) => (\n <tbody key={section.key} data-group={section.label ?? undefined}>\n {section.label ? (\n <tr>\n <th colSpan={columns.length + 2} scope=\"colgroup\" className={SECTION_HEADING_CLASS}>\n {section.label}\n <span className=\"ml-1.5 font-normal normal-case tracking-normal\">{section.items.length}</span>\n </th>\n </tr>\n ) : null}\n {section.items.map((row) => (\n <SessionsRow\n key={row.id}\n row={row}\n columns={columns}\n isActive={row.id === list.activeThreadId}\n labels={labels}\n list={list}\n onOpen={open}\n />\n ))}\n </tbody>\n ))}\n </table>\n )}\n {sessions.hasNextPage && !showSkeleton ? (\n <button\n type=\"button\"\n onClick={sessions.fetchNextPage}\n disabled={sessions.isFetchingNextPage}\n className={cn('mt-2 w-full rounded-md py-2 text-muted-foreground text-xs transition-colors hover:bg-muted disabled:opacity-50', FOCUS_RING_CLASS)}\n >\n {sessions.isFetchingNextPage ? 'Loading…' : sessions.isFetchNextPageError ? 'Retry loading more' : 'Load more'}\n </button>\n ) : null}\n </div>\n </div>\n );\n}\n\n/**\n * A full-page session list with server-side filters, display options, an\n * attention-coloured status column and CSV export. Renders nothing outside\n * `<AthenaProvider enableThreadList>`.\n */\nexport function SessionsPage(props: SessionsPageProps) {\n const list = useAthenaStatewireThreadList();\n const live = useContext(AthenaSessionsLiveContext);\n if (!list || !live) return null;\n return <SessionsPageBody {...props} list={list} />;\n}\n"],"names":["jsxs","cn","FOCUS_RING_CLASS","jsx","CheckIcon","SESSIONS_DATE_PRESETS","useState","datePresetBounds","SESSION_RUN_STATUSES","runStatusLabel","_a","agentLabel","channelLabel","sessionOriginLabel","SESSIONS_COLUMNS","sessionStatusChip","plainExcerpt","pullRequestChip","StatusChip","PullRequestChip","creatorLabel","relativeTime","PinIcon","RowIconButton","MailOpenIcon","MailIcon","ArchiveIcon","readSessionsPageSettings","normalizeSessionsQuery","writeSessionsPageSettings","useEffect","useAthenaSessions","useMemo","useRef","DEFAULT_COLLAB_CHANNEL","sessionsFilterChips","groupSessionsBy","sessionsQueryKey","sessionsCsv","SearchIcon","Popover","PopoverTrigger","SlidersHorizontalIcon","PopoverContent","DownloadIcon","RefreshCwIcon","PlusIcon","FilterIcon","XIcon","SessionListSkeleton","useAthenaStatewireThreadList","useContext","AthenaSessionsLiveContext"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SessionsPage.cjs","sources":["../../src/threads/SessionsPage.tsx"],"sourcesContent":["/**\n * `SessionsPage` — a full-page, Devin-style session list: filter chips that\n * the server applies (status, pull requests, unread, pinned, creator, agent,\n * mode, origin, created / updated date), a title search, display options\n * (sort, direction, grouping, columns), an attention-coloured status column\n * that says what the person must do next, row actions (read, pin, archive)\n * and a CSV export of the loaded rows. Live through the thread-list\n * provider's conversation index; renders nothing outside\n * `<AthenaProvider enableThreadList>`.\n */\nimport {\n ArchiveIcon,\n CheckIcon,\n DownloadIcon,\n FilterIcon,\n MailIcon,\n MailOpenIcon,\n PinIcon,\n PlusIcon,\n RefreshCwIcon,\n SearchIcon,\n SlidersHorizontalIcon,\n XIcon,\n} from 'lucide-react';\nimport type { FC, ReactNode } from 'react';\nimport { useContext, useEffect, useMemo, useRef, useState } from 'react';\nimport { cn } from '../lib/utils';\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';\nimport { SessionListSkeleton, type SessionOpenTarget } from './SessionList';\nimport { pullRequestChip, relativeTime, sessionOriginLabel } from './session-list-model';\nimport { FOCUS_RING_CLASS, PullRequestChip, RowIconButton, StatusChip } from './session-row-parts';\nimport {\n agentLabel,\n channelLabel,\n creatorLabel,\n datePresetBounds,\n groupSessionsBy,\n runStatusLabel,\n SESSIONS_COLUMNS,\n SESSIONS_DATE_PRESETS,\n type SessionsColumnId,\n type SessionsDatePreset,\n type SessionsGroupBy,\n type SessionsLabels,\n sessionsCsv,\n sessionsFilterChips,\n plainExcerpt,\n sessionStatusChip,\n} from './sessions-page-model';\nimport {\n readSessionsPageSettings,\n type SessionsPageDisplay,\n writeSessionsPageSettings,\n} from './sessions-page-storage';\nimport {\n type AthenaSessionsQuery,\n type AthenaSessionsQueryField,\n DEFAULT_COLLAB_CHANNEL,\n normalizeSessionsQuery,\n SESSION_RUN_STATUSES,\n type SessionRunStatus,\n sessionsQueryKey,\n} from './sessions-query';\nimport {\n AthenaSessionsLiveContext,\n type AthenaStatewireThreadListState,\n type AthenaStatewireThreadSummary,\n useAthenaStatewireThreadList,\n} from './statewire-thread-list';\nimport { useAthenaSessions } from './use-athena-sessions';\n\nexport interface SessionsPageProps {\n className?: string;\n /** Heading (default \"Sessions\"). */\n title?: string;\n /**\n * Called after a row is selected (the provider's chat switches to it), so\n * a host can navigate to its chat view.\n */\n onOpenSession?: (target: SessionOpenTarget) => void;\n /** Names for collab agents and channels (filters, the Mode column, CSV); ids show otherwise. */\n labels?: SessionsLabels;\n /**\n * Namespaces what this browser remembers — \"Save as default\" and the\n * display options — so a host with several pages keeps them apart\n * (default `\"default\"`).\n */\n storageKey?: string;\n /** The filters before anything is saved as default. */\n defaultQuery?: AthenaSessionsQuery;\n /** Rows per page (default 50). */\n pageSize?: number;\n /** Offer \"New session\" (default `true`). */\n showNewSession?: boolean;\n /** Called after \"New session\" starts a fresh chat, so a host can show its chat view. */\n onNewSession?: () => void;\n}\n\n/** What each query field is called in notices. */\nconst FIELD_LABEL: Record<AthenaSessionsQueryField, string> = {\n search: 'search',\n collabAgentIds: 'agent',\n collabChannelIds: 'mode',\n startChannels: 'origin',\n createdAfter: 'created date',\n createdBefore: 'created date',\n updatedAfter: 'updated date',\n updatedBefore: 'updated date',\n favoritesOnly: 'pinned',\n unreadOnly: 'unread',\n runStatuses: 'status',\n sessionStatuses: 'session status',\n hasPullRequests: 'pull requests',\n createdByMe: 'creator',\n excludeDismissed: 'dismissed',\n excludeTriggered: 'who started it',\n sort: 'sort',\n direction: 'sort direction',\n};\n\n/** \"agent\", \"agent and mode\", \"agent, mode and unread\". */\nfunction fieldList(fields: readonly AthenaSessionsQueryField[]): string {\n const names = [...new Set(fields.map((field) => FIELD_LABEL[field]))];\n return names.length <= 1 ? (names[0] ?? '') : `${names.slice(0, -1).join(', ')} and ${names.at(-1)}`;\n}\n\nconst COLUMN_WIDTH: Record<SessionsColumnId, string> = {\n status: 'w-56',\n origin: 'w-24',\n mode: 'w-28',\n pullRequests: 'w-24',\n creator: 'w-32',\n created: 'w-24',\n updated: 'w-24',\n};\n\n/** Save `text` as a file in the browser. */\nfunction downloadText(filename: string, text: string, type: string): void {\n if (typeof document === 'undefined') return;\n const url = URL.createObjectURL(new Blob([text], { type }));\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = filename;\n anchor.rel = 'noopener';\n document.body.appendChild(anchor);\n anchor.click();\n anchor.remove();\n setTimeout(() => URL.revokeObjectURL(url), 0);\n}\n\nconst SECTION_HEADING_CLASS =\n 'px-3 pb-1 pt-3 text-left font-medium text-[11px] text-muted-foreground/70 uppercase tracking-wide';\n\n/** A pressable option in a filter or display menu. */\nconst MenuOption: FC<{\n label: string;\n selected: boolean;\n onSelect: () => void;\n disabled?: boolean;\n role?: 'menuitemcheckbox' | 'menuitemradio';\n}> = ({ label, selected, onSelect, disabled = false, role = 'menuitemcheckbox' }) => (\n <button\n type=\"button\"\n role={role}\n aria-checked={selected}\n disabled={disabled}\n onClick={onSelect}\n className={cn(\n 'flex w-full items-center gap-2 rounded-sm px-2 py-1 text-left text-xs transition-colors hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50',\n FOCUS_RING_CLASS,\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn(\n 'flex size-3.5 shrink-0 items-center justify-center rounded-sm border border-border',\n selected && 'border-primary bg-primary text-primary-foreground',\n )}\n >\n {selected ? <CheckIcon className=\"size-3\" /> : null}\n </span>\n <span className=\"truncate\">{label}</span>\n </button>\n);\n\nconst MenuSection: FC<{ title: string; hint?: string | null; children: ReactNode }> = ({\n title,\n hint,\n children,\n}) => (\n <section aria-label={title} className=\"py-1\">\n <h4 className=\"px-2 pb-0.5 font-medium text-[11px] text-muted-foreground uppercase tracking-wide\">\n {title}\n </h4>\n {hint ? <p className=\"px-2 pb-1 text-[11px] text-muted-foreground\">{hint}</p> : null}\n {children}\n </section>\n);\n\nfunction toggleValue<T extends string>(values: readonly T[] | undefined, value: T): T[] {\n const current = values ?? [];\n return current.includes(value) ? current.filter((item) => item !== value) : [...current, value];\n}\n\nfunction datePresetOf(after: string | undefined, before: string | undefined, presets: Record<SessionsDatePreset, { after?: string; before?: string }>): SessionsDatePreset | null {\n for (const preset of SESSIONS_DATE_PRESETS) {\n const bounds = presets[preset.id];\n if ((bounds.after ?? undefined) === after && (bounds.before ?? undefined) === before) {\n return preset.id;\n }\n }\n return null;\n}\n\ninterface FilterMenuProps {\n query: AthenaSessionsQuery;\n setQuery: (update: (query: AthenaSessionsQuery) => AthenaSessionsQuery) => void;\n unavailable: ReadonlySet<AthenaSessionsQueryField>;\n agentOptions: readonly string[];\n channelOptions: readonly string[];\n originOptions: readonly string[];\n labels: SessionsLabels | undefined;\n}\n\nconst UNAVAILABLE_HINT = 'This Athena server cannot filter by this yet.';\n\n/** Every filter, stacked by kind; each option toggles at once. */\nconst FilterMenu: FC<FilterMenuProps> = ({\n query,\n setQuery,\n unavailable,\n agentOptions,\n channelOptions,\n originOptions,\n labels,\n}) => {\n // The presets' bounds are captured when the menu opens, so a selected\n // preset stays recognisable while it is open.\n const [presetBounds] = useState(() =>\n Object.fromEntries(\n SESSIONS_DATE_PRESETS.map((preset) => [preset.id, datePresetBounds(preset.id)]),\n ) as Record<SessionsDatePreset, { after?: string; before?: string }>,\n );\n const createdPreset = datePresetOf(query.createdAfter, query.createdBefore, presetBounds);\n const updatedPreset = datePresetOf(query.updatedAfter, query.updatedBefore, presetBounds);\n const setPreset = (\n kind: 'created' | 'updated',\n preset: SessionsDatePreset | null,\n ) =>\n setQuery((current) => {\n const bounds = preset ? presetBounds[preset] : {};\n return kind === 'created'\n ? { ...current, createdAfter: bounds.after, createdBefore: bounds.before }\n : { ...current, updatedAfter: bounds.after, updatedBefore: bounds.before };\n });\n const disabledHint = (field: AthenaSessionsQueryField) =>\n unavailable.has(field) ? UNAVAILABLE_HINT : null;\n\n return (\n <div role=\"menu\" aria-label=\"Filters\" className=\"max-h-[70vh] overflow-y-auto p-1\">\n <MenuSection title=\"Status\" hint={disabledHint('runStatuses')}>\n {SESSION_RUN_STATUSES.map((status) => (\n <MenuOption\n key={status}\n label={runStatusLabel(status)}\n selected={query.runStatuses?.includes(status) ?? false}\n disabled={unavailable.has('runStatuses')}\n onSelect={() =>\n setQuery((current) => ({\n ...current,\n runStatuses: toggleValue<SessionRunStatus>(current.runStatuses, status),\n }))\n }\n />\n ))}\n </MenuSection>\n <MenuSection title=\"Pull requests\" hint={disabledHint('hasPullRequests')}>\n {(\n [\n ['Has pull requests', true],\n ['No pull requests', false],\n ] as const\n ).map(([label, value]) => (\n <MenuOption\n key={label}\n role=\"menuitemradio\"\n label={label}\n selected={query.hasPullRequests === value}\n disabled={unavailable.has('hasPullRequests')}\n onSelect={() =>\n setQuery((current) => ({\n ...current,\n hasPullRequests: current.hasPullRequests === value ? undefined : value,\n }))\n }\n />\n ))}\n </MenuSection>\n <MenuSection title=\"Read and pinned\">\n <MenuOption\n label=\"Unread\"\n selected={query.unreadOnly === true}\n disabled={unavailable.has('unreadOnly')}\n onSelect={() => setQuery((current) => ({ ...current, unreadOnly: !current.unreadOnly }))}\n />\n <MenuOption\n label=\"Pinned\"\n selected={query.favoritesOnly === true}\n disabled={unavailable.has('favoritesOnly')}\n onSelect={() =>\n setQuery((current) => ({ ...current, favoritesOnly: !current.favoritesOnly }))\n }\n />\n </MenuSection>\n <MenuSection title=\"Creator\" hint={disabledHint('createdByMe')}>\n {(\n [\n ['You', true],\n ['Shared with you', false],\n ] as const\n ).map(([label, value]) => (\n <MenuOption\n key={label}\n role=\"menuitemradio\"\n label={label}\n selected={query.createdByMe === value}\n disabled={unavailable.has('createdByMe')}\n onSelect={() =>\n setQuery((current) => ({\n ...current,\n createdByMe: current.createdByMe === value ? undefined : value,\n }))\n }\n />\n ))}\n <MenuOption\n label=\"Started by a person\"\n selected={query.excludeTriggered === true}\n onSelect={() =>\n setQuery((current) => ({ ...current, excludeTriggered: !current.excludeTriggered }))\n }\n />\n </MenuSection>\n {agentOptions.length > 0 ? (\n <MenuSection title=\"Agent\" hint={disabledHint('collabAgentIds')}>\n {agentOptions.map((agentId) => (\n <MenuOption\n key={agentId}\n label={agentLabel(agentId, labels)}\n selected={query.collabAgentIds?.includes(agentId) ?? false}\n disabled={unavailable.has('collabAgentIds')}\n onSelect={() =>\n setQuery((current) => ({\n ...current,\n collabAgentIds: toggleValue(current.collabAgentIds, agentId),\n }))\n }\n />\n ))}\n </MenuSection>\n ) : null}\n {agentOptions.length > 0 ? (\n <MenuSection\n title=\"Mode\"\n hint={\n disabledHint('collabChannelIds') ??\n (query.collabAgentIds?.length ? null : 'Pick an agent first: a mode is one of its channels.')\n }\n >\n {channelOptions.map((channelId) => (\n <MenuOption\n key={channelId}\n label={channelLabel(channelId, labels)}\n selected={query.collabChannelIds?.includes(channelId) ?? false}\n disabled={unavailable.has('collabChannelIds') || !query.collabAgentIds?.length}\n onSelect={() =>\n setQuery((current) => ({\n ...current,\n collabChannelIds: toggleValue(current.collabChannelIds, channelId),\n }))\n }\n />\n ))}\n </MenuSection>\n ) : null}\n {originOptions.length > 0 ? (\n <MenuSection title=\"Origin\" hint={disabledHint('startChannels')}>\n {originOptions.map((channel) => (\n <MenuOption\n key={channel}\n label={sessionOriginLabel({ startChannel: channel, appId: null, triggerType: null }) ?? channel}\n selected={query.startChannels?.includes(channel) ?? false}\n disabled={unavailable.has('startChannels')}\n onSelect={() =>\n setQuery((current) => ({\n ...current,\n startChannels: toggleValue(current.startChannels, channel),\n }))\n }\n />\n ))}\n </MenuSection>\n ) : null}\n <MenuSection title=\"Created\">\n {SESSIONS_DATE_PRESETS.map((preset) => (\n <MenuOption\n key={preset.id}\n role=\"menuitemradio\"\n label={preset.label}\n selected={createdPreset === preset.id}\n onSelect={() => setPreset('created', createdPreset === preset.id ? null : preset.id)}\n />\n ))}\n </MenuSection>\n <MenuSection title=\"Updated\">\n {SESSIONS_DATE_PRESETS.map((preset) => (\n <MenuOption\n key={preset.id}\n role=\"menuitemradio\"\n label={preset.label}\n selected={updatedPreset === preset.id}\n onSelect={() => setPreset('updated', updatedPreset === preset.id ? null : preset.id)}\n />\n ))}\n </MenuSection>\n </div>\n );\n};\n\nconst DisplayMenu: FC<{\n query: AthenaSessionsQuery;\n setQuery: (update: (query: AthenaSessionsQuery) => AthenaSessionsQuery) => void;\n display: SessionsPageDisplay;\n setDisplay: (update: (display: SessionsPageDisplay) => SessionsPageDisplay) => void;\n}> = ({ query, setQuery, display, setDisplay }) => {\n const sort = query.sort ?? 'updated';\n const direction = query.direction ?? 'desc';\n return (\n <div role=\"menu\" aria-label=\"Display options\" className=\"p-1\">\n <MenuSection title=\"Sort by\">\n {(\n [\n ['updated', 'Last updated'],\n ['created', 'Created'],\n ] as const\n ).map(([value, label]) => (\n <MenuOption\n key={value}\n role=\"menuitemradio\"\n label={label}\n selected={sort === value}\n onSelect={() => setQuery((current) => ({ ...current, sort: value }))}\n />\n ))}\n </MenuSection>\n <MenuSection title=\"Order\">\n {(\n [\n ['desc', 'Newest first'],\n ['asc', 'Oldest first'],\n ] as const\n ).map(([value, label]) => (\n <MenuOption\n key={value}\n role=\"menuitemradio\"\n label={label}\n selected={direction === value}\n onSelect={() => setQuery((current) => ({ ...current, direction: value }))}\n />\n ))}\n </MenuSection>\n <MenuSection title=\"Group by\">\n {(\n [\n ['attention', 'What it needs'],\n ['status', 'Run status'],\n ['none', 'No grouping'],\n ] as const\n ).map(([value, label]) => (\n <MenuOption\n key={value}\n role=\"menuitemradio\"\n label={label}\n selected={display.groupBy === value}\n onSelect={() => setDisplay((current) => ({ ...current, groupBy: value }))}\n />\n ))}\n </MenuSection>\n <MenuSection title=\"Columns\">\n {SESSIONS_COLUMNS.map((column) => (\n <MenuOption\n key={column.id}\n label={column.label}\n selected={display.columns.includes(column.id)}\n onSelect={() =>\n setDisplay((current) => ({\n ...current,\n columns: current.columns.includes(column.id)\n ? current.columns.filter((id) => id !== column.id)\n : SESSIONS_COLUMNS.map((candidate) => candidate.id).filter(\n (id) => id === column.id || current.columns.includes(id),\n ),\n }))\n }\n />\n ))}\n </MenuSection>\n </div>\n );\n};\n\nconst HEADER_BUTTON_CLASS = cn(\n 'inline-flex h-8 items-center gap-1.5 rounded-md border border-border/60 px-2.5 font-medium text-muted-foreground text-xs transition-colors hover:bg-muted hover:text-foreground disabled:opacity-50',\n FOCUS_RING_CLASS,\n);\n\nconst SessionsRow: FC<{\n row: AthenaStatewireThreadSummary;\n columns: readonly SessionsColumnId[];\n isActive: boolean;\n labels: SessionsLabels | undefined;\n list: AthenaStatewireThreadListState;\n onOpen: (row: AthenaStatewireThreadSummary) => void;\n}> = ({ row, columns, isActive, labels, list, onOpen }) => {\n const status = sessionStatusChip(row);\n const excerpt = plainExcerpt(row.preview);\n const chip = pullRequestChip(row.pullRequests);\n const origin = sessionOriginLabel(row);\n const cell = (id: SessionsColumnId): ReactNode => {\n switch (id) {\n case 'status':\n return <StatusChip label={status.label} tone={status.tone} detail={status.detail} />;\n case 'origin':\n return origin ? (\n <span className=\"rounded-full border border-border/60 px-1.5 py-px text-[10px] text-muted-foreground\">\n {origin}\n </span>\n ) : null;\n case 'mode':\n return row.collabAgentId ? (\n <span className=\"truncate text-muted-foreground text-xs\">\n {channelLabel(row.collabChannelId, labels)}\n </span>\n ) : null;\n case 'pullRequests':\n return chip ? <PullRequestChip chip={chip} pullRequests={row.pullRequests ?? []} /> : null;\n case 'creator':\n return (\n <span className=\"truncate text-muted-foreground text-xs\">{creatorLabel(row.createdByMe)}</span>\n );\n case 'created':\n return (\n <span className=\"text-muted-foreground text-xs\">\n {row.createdAt ? relativeTime(row.createdAt) : ''}\n </span>\n );\n case 'updated':\n return <span className=\"text-muted-foreground text-xs\">{relativeTime(row.updatedAt)}</span>;\n }\n };\n return (\n <tr\n data-thread-id={row.id}\n data-active={isActive || undefined}\n data-unread={row.isUnread || undefined}\n onClick={() => onOpen(row)}\n className={cn(\n 'group cursor-pointer border-border/40 border-b transition-colors hover:bg-muted/40',\n isActive && 'bg-muted',\n )}\n >\n <td className=\"min-w-0 py-2 pr-2 pl-3 align-top\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span\n role={row.isUnread ? 'img' : undefined}\n aria-label={row.isUnread ? 'Unread' : undefined}\n aria-hidden={row.isUnread ? undefined : true}\n className={cn('size-2 shrink-0 rounded-full', row.isUnread ? 'bg-primary' : 'bg-transparent')}\n />\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onOpen(row);\n }}\n className={cn(\n 'min-w-0 truncate text-left text-foreground text-sm',\n row.isUnread ? 'font-semibold' : 'font-medium',\n FOCUS_RING_CLASS,\n )}\n >\n {row.title ?? 'Untitled'}\n </button>\n {row.isFavorited ? (\n <PinIcon role=\"img\" aria-label=\"Pinned\" className=\"size-3 shrink-0 fill-current text-muted-foreground\" />\n ) : null}\n </div>\n {excerpt ? <p className=\"mt-0.5 truncate pl-4 text-muted-foreground text-xs\">{excerpt}</p> : null}\n </td>\n {columns.map((id) => (\n <td key={id} data-column={id} className=\"min-w-0 truncate px-2 py-2 align-top\">\n {cell(id)}\n </td>\n ))}\n <td className=\"py-1.5 pr-2 align-top\">\n <div data-row-actions className=\"flex items-center justify-end gap-0.5\">\n <RowIconButton\n label={row.isUnread ? 'Mark read' : 'Mark unread'}\n action=\"read-state\"\n pending={list.readStatePendingThreadIds.has(row.id)}\n onClick={() =>\n list.setReadState({ threadId: row.id, isUnread: !row.isUnread, updatedAt: row.updatedAt })\n }\n >\n {row.isUnread ? <MailOpenIcon className=\"size-3.5\" aria-hidden /> : <MailIcon className=\"size-3.5\" aria-hidden />}\n </RowIconButton>\n {list.favoriteToggleAvailable ? (\n <RowIconButton\n label={row.isFavorited ? 'Unpin session' : 'Pin session'}\n action=\"pin\"\n pressed={row.isFavorited}\n pending={list.favoritePendingThreadIds.has(row.id)}\n onClick={() => list.setFavorited({ threadId: row.id, isFavorited: !row.isFavorited })}\n >\n <PinIcon className={cn('size-3.5', row.isFavorited && 'fill-current')} aria-hidden />\n </RowIconButton>\n ) : null}\n {list.archiveAvailable ? (\n <RowIconButton\n label=\"Archive session\"\n action=\"archive\"\n pending={list.archivePendingThreadIds.has(row.id)}\n onClick={() => list.archiveThread(row.id)}\n >\n <ArchiveIcon className=\"size-3.5\" aria-hidden />\n </RowIconButton>\n ) : null}\n </div>\n </td>\n </tr>\n );\n};\n\nfunction SessionsPageBody({\n className,\n title = 'Sessions',\n onOpenSession,\n labels,\n storageKey = 'default',\n defaultQuery,\n pageSize,\n showNewSession = true,\n onNewSession,\n list,\n}: SessionsPageProps & { list: AthenaStatewireThreadListState }) {\n const [initial] = useState(() => readSessionsPageSettings(storageKey));\n const [savedDefault, setSavedDefault] = useState<AthenaSessionsQuery | null>(initial.defaultQuery);\n const [query, setQueryState] = useState<AthenaSessionsQuery>(\n () => initial.defaultQuery ?? normalizeSessionsQuery(defaultQuery ?? {}),\n );\n const [display, setDisplayState] = useState<SessionsPageDisplay>(initial.display);\n const [searchInput, setSearchInput] = useState(query.search ?? '');\n\n const setQuery = (update: (current: AthenaSessionsQuery) => AthenaSessionsQuery) =>\n setQueryState((current) => normalizeSessionsQuery(update(current)));\n const setDisplay = (update: (current: SessionsPageDisplay) => SessionsPageDisplay) =>\n setDisplayState((current) => {\n const next = update(current);\n writeSessionsPageSettings(storageKey, { defaultQuery: savedDefault, display: next });\n return next;\n });\n\n // The search box types freely; the list follows a beat later.\n useEffect(() => {\n const handle = setTimeout(() => {\n setQueryState((current) => {\n const search = searchInput.trim();\n if ((current.search ?? '') === search) return current;\n return normalizeSessionsQuery({ ...current, search });\n });\n }, 250);\n return () => clearTimeout(handle);\n }, [searchInput]);\n\n const sessions = useAthenaSessions({ query, ...(pageSize ? { pageSize } : {}) });\n const unavailable = useMemo(\n () => new Set([...sessions.unsupportedFields, ...sessions.unavailableFields]),\n [sessions.unsupportedFields, sessions.unavailableFields],\n );\n\n // Filter options: every agent, channel and origin this page has shown, so\n // narrowing the list never hides the option that would widen it again.\n const seenRef = useRef({ agents: new Set<string>(), channels: new Set<string>(), origins: new Set<string>() });\n for (const row of sessions.rows) {\n if (row.collabAgentId) {\n seenRef.current.agents.add(row.collabAgentId);\n seenRef.current.channels.add(row.collabChannelId || DEFAULT_COLLAB_CHANNEL);\n }\n if (row.startChannel) seenRef.current.origins.add(row.startChannel);\n }\n const agentOptions = [\n ...new Set([...Object.keys(labels?.agents ?? {}), ...seenRef.current.agents, ...(query.collabAgentIds ?? [])]),\n ];\n const channelOptions = [\n ...new Set([\n DEFAULT_COLLAB_CHANNEL,\n ...Object.keys(labels?.channels ?? {}),\n ...seenRef.current.channels,\n ...(query.collabChannelIds ?? []),\n ]),\n ];\n const originOptions = [...new Set([...seenRef.current.origins, ...(query.startChannels ?? [])])];\n\n const chips = sessionsFilterChips(query, labels);\n const sections = groupSessionsBy(sessions.rows, display.groupBy);\n const columns = SESSIONS_COLUMNS.map((column) => column.id).filter((id) => display.columns.includes(id));\n const { search: _search, ...queryWithoutSearch } = query;\n const isSavedDefault =\n savedDefault !== null && sessionsQueryKey(savedDefault) === sessionsQueryKey(queryWithoutSearch);\n const hasFilters = chips.length > 0;\n\n const open = (row: AthenaStatewireThreadSummary) => {\n list.selectThread(row.id);\n onOpenSession?.({ threadId: row.id, title: row.title });\n };\n const saveAsDefault = () => {\n const saved = normalizeSessionsQuery(queryWithoutSearch);\n setSavedDefault(saved);\n writeSessionsPageSettings(storageKey, { defaultQuery: saved, display });\n };\n const resetToDefault = () => {\n setQueryState({ ...(savedDefault ?? normalizeSessionsQuery(defaultQuery ?? {})) });\n setSearchInput('');\n };\n const clearFilters = () => {\n setQuery((current) => ({ sort: current.sort, direction: current.direction, search: current.search }));\n };\n const removeChip = (field: AthenaSessionsQueryField) =>\n setQuery((current) => {\n const next: AthenaSessionsQuery = { ...current, [field]: undefined };\n if (field === 'collabAgentIds') next.collabChannelIds = undefined;\n return next;\n });\n const exportCsv = () =>\n downloadText(\n `sessions-${new Date().toISOString().slice(0, 10)}.csv`,\n sessionsCsv(sessions.rows, labels),\n 'text/csv;charset=utf-8',\n );\n\n // Skeletons only while there is nothing to show; a changed query keeps the\n // previous rows (narrowed by it) until its own page answers.\n const showSkeleton =\n sessions.rows.length === 0 && (!sessions.hasResolvedFirstPage || sessions.isFetching);\n\n return (\n <div\n data-testid=\"sessions-page\"\n className={cn('athena-sdk-chrome flex min-h-0 flex-col gap-3 p-4', className)}\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"font-semibold text-base text-foreground\">{title}</h2>\n <span data-testid=\"sessions-count\" className=\"text-muted-foreground text-xs\">\n {sessions.rows.length}\n {sessions.hasNextPage ? '+' : ''}\n </span>\n <div className=\"flex-1\" />\n <label className=\"relative block w-64 max-w-full\">\n <SearchIcon className=\"pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2 text-muted-foreground\" />\n <span className=\"sr-only\">Search sessions</span>\n <input\n type=\"search\"\n value={searchInput}\n onChange={(event) => setSearchInput(event.target.value)}\n placeholder=\"Search sessions…\"\n className=\"h-8 w-full rounded-md border border-border/60 bg-muted/40 pr-2 pl-8 text-sm outline-none focus:border-primary focus:bg-background\"\n />\n </label>\n <Popover>\n <PopoverTrigger asChild>\n <button type=\"button\" className={HEADER_BUTTON_CLASS} aria-label=\"Display options\">\n <SlidersHorizontalIcon className=\"size-3.5\" aria-hidden />\n Display\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-56\">\n <DisplayMenu query={query} setQuery={setQuery} display={display} setDisplay={setDisplay} />\n </PopoverContent>\n </Popover>\n <button\n type=\"button\"\n onClick={exportCsv}\n disabled={sessions.rows.length === 0}\n className={HEADER_BUTTON_CLASS}\n title=\"Export the loaded sessions as CSV\"\n >\n <DownloadIcon className=\"size-3.5\" aria-hidden />\n Export CSV\n </button>\n <button\n type=\"button\"\n onClick={sessions.refresh}\n disabled={sessions.isFetching}\n className={HEADER_BUTTON_CLASS}\n aria-label=\"Refresh sessions\"\n title=\"Refresh sessions\"\n >\n <RefreshCwIcon className={cn('size-3.5', sessions.isFetching && 'animate-spin')} aria-hidden />\n </button>\n {showNewSession ? (\n <button\n type=\"button\"\n onClick={() => {\n list.newThread();\n onNewSession?.();\n }}\n className={cn(\n 'inline-flex h-8 items-center gap-1.5 rounded-md bg-primary px-3 font-medium text-primary-foreground text-xs transition-colors hover:bg-primary/90',\n FOCUS_RING_CLASS,\n )}\n >\n <PlusIcon className=\"size-3.5\" aria-hidden />\n New session\n </button>\n ) : null}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-1.5\" data-testid=\"sessions-filters\">\n <Popover>\n <PopoverTrigger asChild>\n <button type=\"button\" className={HEADER_BUTTON_CLASS}>\n <FilterIcon className=\"size-3.5\" aria-hidden />\n Filter\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-64\">\n <FilterMenu\n query={query}\n setQuery={setQuery}\n unavailable={unavailable}\n agentOptions={agentOptions}\n channelOptions={channelOptions}\n originOptions={originOptions}\n labels={labels}\n />\n </PopoverContent>\n </Popover>\n {chips.map((chip) => (\n <span\n key={chip.field + chip.label}\n data-filter-chip={chip.field}\n className=\"inline-flex h-7 items-center gap-1 rounded-full border border-border/60 bg-muted/40 pr-1 pl-2.5 text-foreground text-xs\"\n >\n {chip.label}\n <button\n type=\"button\"\n aria-label={`Remove filter ${chip.label}`}\n onClick={() => removeChip(chip.field)}\n className={cn('rounded-full p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground', FOCUS_RING_CLASS)}\n >\n <XIcon className=\"size-3\" aria-hidden />\n </button>\n </span>\n ))}\n {hasFilters ? (\n <button type=\"button\" onClick={clearFilters} className={cn('px-1.5 text-muted-foreground text-xs hover:text-foreground', FOCUS_RING_CLASS)}>\n Clear\n </button>\n ) : null}\n <div className=\"flex-1\" />\n {savedDefault !== null && !isSavedDefault ? (\n <button type=\"button\" onClick={resetToDefault} className={cn('px-1.5 text-muted-foreground text-xs hover:text-foreground', FOCUS_RING_CLASS)}>\n Reset to default\n </button>\n ) : null}\n <button\n type=\"button\"\n onClick={saveAsDefault}\n disabled={isSavedDefault}\n className={cn('px-1.5 text-muted-foreground text-xs hover:text-foreground disabled:opacity-50', FOCUS_RING_CLASS)}\n >\n {isSavedDefault ? 'Saved as default' : 'Save as default'}\n </button>\n </div>\n\n {sessions.degradedFields.length > 0 || sessions.unavailableFields.length > 0 ? (\n <p\n role=\"status\"\n data-testid=\"sessions-degraded\"\n className=\"rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-amber-900 text-xs\"\n >\n {sessions.degradedFields.length > 0\n ? `This Athena server cannot filter by ${fieldList(sessions.degradedFields)} yet, so they apply to the sessions loaded so far. `\n : ''}\n {sessions.unavailableFields.length > 0\n ? `Filtering by ${fieldList(sessions.unavailableFields)} is not available on this server yet and is off.`\n : ''}\n </p>\n ) : null}\n\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {showSkeleton ? (\n <SessionListSkeleton rows={6} />\n ) : sections.length === 0 ? (\n <div data-testid=\"sessions-empty\" className=\"flex flex-col items-center gap-2 py-12 text-center\">\n <p className=\"text-muted-foreground text-sm\">\n {hasFilters || query.search ? 'No sessions match these filters.' : 'No sessions yet.'}\n </p>\n {hasFilters ? (\n <button type=\"button\" onClick={clearFilters} className={HEADER_BUTTON_CLASS}>\n Clear filters\n </button>\n ) : null}\n </div>\n ) : (\n <table className=\"w-full table-fixed border-collapse text-sm\" aria-busy={sessions.isFetching || undefined}>\n <thead>\n <tr className=\"border-border/60 border-b text-left text-[11px] text-muted-foreground uppercase tracking-wide\">\n <th scope=\"col\" className=\"py-2 pl-7 font-medium\">\n Session\n </th>\n {columns.map((id) => (\n <th key={id} scope=\"col\" className={cn('px-2 py-2 font-medium', COLUMN_WIDTH[id])}>\n {SESSIONS_COLUMNS.find((column) => column.id === id)?.label}\n </th>\n ))}\n <th scope=\"col\" className=\"w-24 py-2 pr-2\">\n <span className=\"sr-only\">Actions</span>\n </th>\n </tr>\n </thead>\n {sections.map((section) => (\n <tbody key={section.key} data-group={section.label ?? undefined}>\n {section.label ? (\n <tr>\n <th colSpan={columns.length + 2} scope=\"colgroup\" className={SECTION_HEADING_CLASS}>\n {section.label}\n <span className=\"ml-1.5 font-normal normal-case tracking-normal\">{section.items.length}</span>\n </th>\n </tr>\n ) : null}\n {section.items.map((row) => (\n <SessionsRow\n key={row.id}\n row={row}\n columns={columns}\n isActive={row.id === list.activeThreadId}\n labels={labels}\n list={list}\n onOpen={open}\n />\n ))}\n </tbody>\n ))}\n </table>\n )}\n {sessions.hasNextPage && !showSkeleton ? (\n <button\n type=\"button\"\n onClick={sessions.fetchNextPage}\n disabled={sessions.isFetchingNextPage}\n className={cn('mt-2 w-full rounded-md py-2 text-muted-foreground text-xs transition-colors hover:bg-muted disabled:opacity-50', FOCUS_RING_CLASS)}\n >\n {sessions.isFetchingNextPage ? 'Loading…' : sessions.isFetchNextPageError ? 'Retry loading more' : 'Load more'}\n </button>\n ) : null}\n </div>\n </div>\n );\n}\n\n/**\n * A full-page session list with server-side filters, display options, an\n * attention-coloured status column and CSV export. Renders nothing outside\n * `<AthenaProvider enableThreadList>`.\n */\nexport function SessionsPage(props: SessionsPageProps) {\n const list = useAthenaStatewireThreadList();\n const live = useContext(AthenaSessionsLiveContext);\n if (!list || !live) return null;\n return <SessionsPageBody {...props} list={list} />;\n}\n"],"names":["jsxs","cn","FOCUS_RING_CLASS","jsx","CheckIcon","SESSIONS_DATE_PRESETS","useState","datePresetBounds","SESSION_RUN_STATUSES","runStatusLabel","_a","agentLabel","channelLabel","sessionOriginLabel","SESSIONS_COLUMNS","sessionStatusChip","plainExcerpt","pullRequestChip","StatusChip","PullRequestChip","creatorLabel","relativeTime","PinIcon","RowIconButton","MailOpenIcon","MailIcon","ArchiveIcon","readSessionsPageSettings","normalizeSessionsQuery","writeSessionsPageSettings","useEffect","useAthenaSessions","useMemo","useRef","DEFAULT_COLLAB_CHANNEL","sessionsFilterChips","groupSessionsBy","sessionsQueryKey","sessionsCsv","SearchIcon","Popover","PopoverTrigger","SlidersHorizontalIcon","PopoverContent","DownloadIcon","RefreshCwIcon","PlusIcon","FilterIcon","XIcon","SessionListSkeleton","useAthenaStatewireThreadList","useContext","AthenaSessionsLiveContext"],"mappings":"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"}
|
package/dist/threads/api.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.cjs","sources":["../../src/threads/api.ts"],"sourcesContent":["/**\n * Athena thread API client.\n * Calls existing REST endpoints for thread CRUD.\n */\n\nimport type {\n ConversationAttention,\n ConversationAttentionSource,\n} from '@athenaintel/agent-runtime';\nimport { athenaDiagnostics } from '../diagnostics/athena-diagnostics';\nimport { AthenaSdkError, type AthenaSdkErrorCode, isAthenaSdkError } from '../diagnostics/errors';\n\n/**\n * Live GitHub state of a pull request the thread opened, read by the server\n * when the list renders (agora `agent_pr_threads` is the only stored link).\n */\nexport interface ThreadPullRequest {\n /** `owner/repo` the pull request lives in. */\n repo_full_name: string;\n number: number;\n url: string;\n title: string;\n state: 'OPEN' | 'CLOSED' | 'MERGED';\n is_draft: boolean;\n /** GitHub's review decision (APPROVED, CHANGES_REQUESTED, REVIEW_REQUIRED) or null. */\n review_decision: string | null;\n /** Combined state of the checks on the head commit. */\n checks_state: 'SUCCESS' | 'FAILURE' | 'PENDING' | 'NONE';\n /** ISO 8601 timestamp of the pull request's last update on GitHub. */\n updated_at: string;\n}\n\n/** The last event that woke a resting thread (a GitHub webhook, a schedule, a handoff). */\nexport interface ThreadWake {\n source: string | null;\n reason: string | null;\n /** ISO 8601 timestamp of the wake. */\n at: string | null;\n}\n\nexport interface ThreadSummary {\n thread_id: string;\n title: string;\n created_at: string;\n updated_at: string;\n last_message: string | null;\n message_count: number;\n state: string | null;\n start_channel?: string | null;\n last_channel?: string | null;\n /** Client app that created the session (SESSION_APP_ID_GUIDE). */\n app_id?: string | null;\n /** Collab agent and channel the session started on; older servers omit them. */\n collab_agent_id?: string | null;\n collab_channel_id?: string | null;\n /** Trigger marker for automated/background sessions. */\n trigger_type?: string | null;\n /** Whether the calling user has seen this thread since it last changed. */\n is_unread?: boolean;\n /**\n * Canonical status_v2 planes (`idle | active | needs_input | error` and\n * `scheduled | queued | running | needs_input | completed | failed |\n * canceled`); older servers omit them.\n */\n session_status?: string | null;\n run_status?: string | null;\n /**\n * The viewer's attention state, the one-line next action (≤ 80 chars) and\n * the signal that produced them, derived server-side; older servers omit them.\n */\n attention?: ConversationAttention | null;\n next_action?: string | null;\n attention_source?: ConversationAttentionSource | null;\n /** Whether the calling user favorited (pinned) the thread; older servers omit it. */\n is_favorited?: boolean;\n /** The last wake of a resting thread; older servers omit it. */\n last_wake?: ThreadWake | null;\n /** Whether the calling user started the thread (`false`: shared with them); older servers omit it. */\n created_by_me?: boolean;\n /**\n * Pull requests the thread opened with their live GitHub state. `[]` when\n * it opened none, `null` when the state could not be read right now;\n * older servers omit the field.\n */\n pull_requests?: ThreadPullRequest[] | null;\n}\n\n/**\n * True for fetch cancellations (unmount/remount aborts, StrictMode double\n * effects). These are lifecycle noise, not failures: emitting them as\n * `*.error` diagnostics floods the console with\n * \"signal is aborted without reason\" for requests the caller itself aborted.\n */\nfunction isAbortError(error: unknown): boolean {\n return (\n (error instanceof DOMException && error.name === 'AbortError') ||\n (error instanceof Error && error.name === 'AbortError')\n );\n}\n\nexport interface ThreadListResponse {\n threads: ThreadSummary[];\n /** Server lookahead result. Older servers may omit this field. */\n has_more?: boolean;\n /**\n * Every request field the server applies beyond paging. The server ignores\n * fields it does not know, so a filter missing from this list came back\n * unapplied; servers that predate the list omit it (none of the\n * `ThreadListFilterBody` fields are applied there).\n */\n supported_filters?: string[];\n}\n\n/**\n * The server-side filters and order of `POST /api/conversations/threads/list`\n * beyond the original `app_id` / `start_channel` / `search` /\n * `exclude_triggered` set. Each is a predicate of the server's one page\n * statement, so a page is exact; a server that predates a field ignores it\n * (check `ThreadListResponse.supported_filters`).\n */\nexport interface ThreadListFilterBody {\n /** Original fields, accepted here too so one body can carry a whole query. */\n search?: string;\n exclude_triggered?: boolean;\n app_ids?: string[];\n start_channels?: string[];\n created_after?: string;\n created_before?: string;\n updated_after?: string;\n updated_before?: string;\n collab_agent_ids?: string[];\n /** `'default'` matches the agent's default channel (no channel stamp); needs `collab_agent_ids`. */\n collab_channel_ids?: string[];\n favorites_only?: boolean;\n unread_only?: boolean;\n run_statuses?: string[];\n session_statuses?: string[];\n has_pull_requests?: boolean;\n created_by_me?: boolean;\n exclude_dismissed?: boolean;\n sort?: 'updated' | 'created';\n direction?: 'desc' | 'asc';\n}\n\nexport interface ThreadCreateResponse {\n thread_id: string;\n}\n\ninterface AuthConfig {\n apiKey?: string;\n token?: string | null;\n credentials?: RequestCredentials;\n}\n\nfunction getAuthHeaders(auth: AuthConfig): Record<string, string> {\n if (auth.token) {\n return { Authorization: `Bearer ${auth.token}` };\n }\n if (auth.apiKey) {\n return { 'X-API-KEY': auth.apiKey };\n }\n return {};\n}\n\n/**\n * Resolves the Athena API base URL from backendUrl.\n * Thread endpoints live under `/api/conversations/threads/*` and `/api/unstable/threads/`.\n * If backendUrl points at a nested Athena endpoint, trim it back to the API base first.\n */\nfunction getAthenaApiBaseUrl(backendUrl: string): string {\n const stripped = backendUrl.replace(/\\/api\\/assistant-ui\\/?$/, '');\n // If the suffix wasn't found, assume the URL already points to the API base\n if (stripped === backendUrl) {\n return backendUrl.replace(/\\/$/, '');\n }\n return stripped;\n}\n\nexport async function listThreads(\n backendUrl: string,\n auth: AuthConfig,\n opts: {\n limit?: number;\n offset?: number;\n exclude_triggered?: boolean;\n app_id?: string;\n start_channel?: string;\n search?: string;\n /** Ask the server for live GitHub state on `pull_requests` (off by default: it costs a lookup). */\n include_pull_requests?: boolean;\n /** Server-side filters and order beyond the original set (see `ThreadListFilterBody`). */\n filters?: ThreadListFilterBody;\n signal?: AbortSignal;\n } = {},\n): Promise<ThreadListResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const endSpan = athenaDiagnostics.span('threads.list', 'threads.list.start', {\n auth_mode: getAuthMode(auth),\n app_id: opts.app_id,\n });\n try {\n const res = await fetch(`${base}/api/conversations/threads/list`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n signal: opts.signal ?? null,\n body: JSON.stringify({\n limit: opts.limit ?? 50,\n offset: opts.offset ?? 0,\n // Default to the full recent-conversations set unless a caller\n // explicitly asks to hide triggered/background sessions.\n exclude_triggered: opts.exclude_triggered ?? false,\n ...(opts.app_id ? { app_id: opts.app_id } : {}),\n ...(opts.start_channel ? { start_channel: opts.start_channel } : {}),\n ...(opts.search ? { search: opts.search } : {}),\n ...(opts.include_pull_requests ? { include_pull_requests: true } : {}),\n ...opts.filters,\n }),\n });\n if (!res.ok) {\n throw new AthenaSdkError({\n code: res.status === 401 || res.status === 403 ? 'auth_rejected' : 'threads_list_failed',\n message: `Failed to list threads: ${res.status}`,\n status: res.status,\n hint:\n res.status === 401 || res.status === 403\n ? 'The credential was refused. Check the token/API key and that the user belongs to the workspace.'\n : 'Check backendUrl points at the Agora API base.',\n context: { auth_mode: getAuthMode(auth) },\n });\n }\n const data = (await res.json()) as ThreadListResponse;\n endSpan('threads.list.done', { data: { count: data.threads?.length ?? 0 } });\n return data;\n } catch (error) {\n // Cancellation is lifecycle noise (unmount/remount aborts): log it as an\n // informational abort, not an error — passing `error` would force the\n // span end to error level and spam the console.\n if (isAbortError(error)) {\n endSpan('threads.list.aborted', { data: { reason: 'request aborted' } });\n } else {\n endSpan('threads.list.error', { error });\n }\n throw error;\n }\n}\n\n/** The `(workspace, user)` pair the credential resolves to on the backend. */\nexport interface AccountIdentity {\n userId: string;\n /** `null` for a user with no current workspace. */\n workspaceId: string | null;\n}\n\n/**\n * Resolve the credential's agora identity. The conversation index is one\n * statewire instance per `(workspace, user)`, and neither half is knowable\n * from the credential alone: the SDK's auth context carries an identity\n * provider user id, not agora's, and never a workspace.\n */\nexport async function fetchAccountIdentity(\n backendUrl: string,\n auth: AuthConfig,\n opts: { signal?: AbortSignal } = {},\n): Promise<AccountIdentity> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/v0/me`, {\n headers: getAuthHeaders(auth),\n signal: opts.signal ?? null,\n credentials: auth.credentials,\n });\n if (!res.ok) {\n throw new AthenaSdkError({\n code: res.status === 401 || res.status === 403 ? 'auth_rejected' : 'threads_list_failed',\n message: `Failed to resolve account identity: ${res.status}`,\n status: res.status,\n hint:\n res.status === 401 || res.status === 403\n ? 'The credential was refused. Check the token/API key and that the user belongs to the workspace.'\n : 'Check backendUrl points at the Agora API base.',\n context: { auth_mode: getAuthMode(auth) },\n });\n }\n const body = (await res.json()) as { user_id?: unknown; workspace_id?: unknown };\n if (typeof body.user_id !== 'string' || body.user_id.length === 0) {\n throw new AthenaSdkError({\n code: 'threads_list_failed',\n message: 'Account identity lookup returned no user id.',\n context: { auth_mode: getAuthMode(auth) },\n });\n }\n return {\n userId: body.user_id,\n workspaceId: typeof body.workspace_id === 'string' ? body.workspace_id : null,\n };\n}\n\nexport interface ThreadReadStateResponse {\n thread_id: string;\n is_unread: boolean;\n}\n\n/** Store the calling user's read receipt for a thread. */\nexport async function setThreadReadState(\n backendUrl: string,\n auth: AuthConfig,\n opts: { threadId: string; isUnread: boolean },\n): Promise<ThreadReadStateResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/conversations/threads/read-state`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n body: JSON.stringify({\n thread_id: opts.threadId,\n is_unread: opts.isUnread,\n }),\n });\n if (!res.ok) {\n throw new AthenaSdkError({\n code: res.status === 401 || res.status === 403 ? 'auth_rejected' : 'unknown',\n message: `Failed to set thread read state: ${res.status}`,\n status: res.status,\n });\n }\n return res.json();\n}\n\nexport interface ThreadInboxDismissResponse {\n success: boolean;\n dismissed: boolean;\n}\n\n/**\n * Dismiss a session from the inbox, or bring it back\n * (`POST /api/conversations/threads/notifications/dismiss`). A dismissed\n * session returns on its own with its next message. The state lives on the\n * session for its creator's inbox, so the route takes EDIT on the session\n * (403 for a VIEW share).\n */\nexport async function dismissThreadFromInbox(\n backendUrl: string,\n auth: AuthConfig,\n opts: { threadId: string; dismissed: boolean },\n): Promise<ThreadInboxDismissResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/conversations/threads/notifications/dismiss`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n body: JSON.stringify({ thread_id: opts.threadId, dismissed: opts.dismissed }),\n });\n if (!res.ok) {\n throw new AthenaSdkError({\n code: res.status === 401 || res.status === 403 ? 'auth_rejected' : 'unknown',\n message: `Failed to ${opts.dismissed ? 'dismiss' : 'restore'} the session: ${res.status}`,\n status: res.status,\n hint:\n res.status === 403\n ? 'Only someone who can edit the session (its creator, usually) can dismiss it from the inbox.'\n : undefined,\n context: { thread_id: opts.threadId, auth_mode: getAuthMode(auth) },\n });\n }\n return res.json();\n}\n\nexport interface ThreadFavoriteResponse {\n thread_id: string;\n /** The server's state after the write. */\n is_favorited: boolean;\n}\n\n/**\n * Classify a 4xx from one of the per-thread write routes (`favorite`,\n * `rename`, `archive`). A 404 there is ambiguous: FastAPI answers\n * `{\"detail\":\"Not Found\"}` for a route an older agora does not have, the\n * archive route answers `\"Endpoint not available\"` on an agora without the\n * checkpointer — and each route answers 404 for a thread that no longer\n * exists (`\"Thread <id> not found\"`, `\"Conversation with langchain thread id\n * <id> not found\"`). The routes' own not-found answers name the thread, so a\n * body that does not is the ROUTE missing, and only that withdraws the\n * feature; a stale row must not disable the action for every other row.\n */\nfunction classifyThreadRouteRejection(\n status: number,\n body: string,\n threadId: string,\n): { routeMissing: boolean; detail: unknown } {\n let detail: unknown = body || undefined;\n try {\n const parsed: unknown = JSON.parse(body);\n if (parsed && typeof parsed === 'object') {\n const record = parsed as { detail?: unknown; message?: unknown };\n detail = record.detail ?? record.message ?? parsed;\n }\n } catch {\n // A non-JSON body (a proxy page) is kept as text.\n }\n const routeMissing = status === 405 || (status === 404 && !mentionsThread(body, threadId));\n return { routeMissing, detail };\n}\n\n/**\n * Whether an error body names the thread as a whole token (the routes embed\n * the id between spaces: `Thread <id> not found`); a substring match would\n * let a short id match a letter inside `\"detail\"`.\n */\nfunction mentionsThread(body: string, threadId: string): boolean {\n if (!threadId) return false;\n const escaped = threadId.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n return new RegExp(`(^|[^A-Za-z0-9_-])${escaped}($|[^A-Za-z0-9_-])`).test(body);\n}\n\n/** True when a per-thread write was rejected because the backend has no such route. */\nfunction isThreadRouteUnavailableError(error: unknown, code: AthenaSdkErrorCode): boolean {\n return isAthenaSdkError(error) && error.code === code && error.context.route_missing === true;\n}\n\n/**\n * Pin (favorite) or unpin a thread for the calling user. The response is the\n * server's truth after the write. Rejections: 401 / 403 when the caller\n * cannot view the thread (`auth_rejected`), otherwise `thread_favorite_failed`\n * with the HTTP status — 404 / 405 from an agora that predates the route,\n * which `isThreadFavoriteUnavailableError` recognizes so callers can fall\n * back to a read-only pin.\n */\nexport async function setThreadFavorite(\n backendUrl: string,\n auth: AuthConfig,\n opts: { threadId: string; isFavorited: boolean },\n): Promise<ThreadFavoriteResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/conversations/threads/favorite`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n body: JSON.stringify({\n thread_id: opts.threadId,\n is_favorited: opts.isFavorited,\n }),\n });\n if (!res.ok) {\n const refused = res.status === 401 || res.status === 403;\n const { routeMissing, detail } = classifyThreadRouteRejection(\n res.status,\n await getResponseErrorBody(res),\n opts.threadId,\n );\n throw new AthenaSdkError({\n code: refused ? 'auth_rejected' : 'thread_favorite_failed',\n message: `Failed to set thread favorite: ${res.status}`,\n status: res.status,\n detail,\n hint: refused\n ? 'The credential cannot view this thread.'\n : routeMissing\n ? 'The backend has no favorite route yet (older agora); the pin stays read-only until it deploys.'\n : res.status === 404\n ? 'The thread no longer exists on the server (archived or deleted elsewhere); refresh the list.'\n : 'Check backendUrl points at the Agora API base.',\n context: { thread_id: opts.threadId, auth_mode: getAuthMode(auth), route_missing: routeMissing },\n });\n }\n return res.json();\n}\n\n/**\n * True when `setThreadFavorite` failed because the backend has no favorite\n * route (a 405, or a 404 whose body does not name the thread — see\n * `classifyThreadRouteRejection`); a 404 for a thread that is gone is a\n * per-row failure and leaves the toggle available.\n */\nexport function isThreadFavoriteUnavailableError(error: unknown): boolean {\n return isThreadRouteUnavailableError(error, 'thread_favorite_failed');\n}\n\nexport interface ThreadRenameResponse {\n thread_id: string;\n /** The stored title after the write (trimmed by the server). */\n title: string;\n}\n\n/** The longest title the rename route accepts; the server answers 422 past it. */\nexport const THREAD_TITLE_MAX_LENGTH = 200;\n\n/**\n * Rename a thread for every viewer (`POST /api/conversations/threads/rename`).\n * The server trims the title and stores 1–200 characters; the response is the\n * row's title after the write. Rejections: 401 / 403 when the caller cannot\n * edit the thread (`auth_rejected` — a viewer can pin a shared session but not\n * retitle it), otherwise `thread_rename_failed` with the HTTP status — 404 /\n * 405 from an agora that predates the route, which\n * `isThreadRenameUnavailableError` recognizes so callers can drop the action.\n */\nexport async function renameThread(\n backendUrl: string,\n auth: AuthConfig,\n opts: { threadId: string; title: string },\n): Promise<ThreadRenameResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/conversations/threads/rename`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n body: JSON.stringify({\n thread_id: opts.threadId,\n title: opts.title,\n }),\n });\n if (!res.ok) {\n const refused = res.status === 401 || res.status === 403;\n const { routeMissing, detail } = classifyThreadRouteRejection(\n res.status,\n await getResponseErrorBody(res),\n opts.threadId,\n );\n throw new AthenaSdkError({\n code: refused ? 'auth_rejected' : 'thread_rename_failed',\n message: `Failed to rename thread: ${res.status}`,\n status: res.status,\n detail,\n hint: refused\n ? 'The credential cannot edit this thread (a viewer can pin a shared session, not retitle it).'\n : routeMissing\n ? 'The backend has no rename route yet (older agora); sessions cannot be renamed from here until it deploys.'\n : res.status === 404\n ? 'The thread no longer exists on the server (archived or deleted elsewhere); refresh the list.'\n : res.status === 422\n ? `The title must be 1–${THREAD_TITLE_MAX_LENGTH} characters after trimming.`\n : 'Check backendUrl points at the Agora API base.',\n context: { thread_id: opts.threadId, auth_mode: getAuthMode(auth), route_missing: routeMissing },\n });\n }\n return res.json();\n}\n\n/**\n * True when `renameThread` failed because the backend has no rename route\n * (a 405, or a 404 whose body does not name the thread); a 404 for a thread\n * that is gone is a per-row failure and leaves the action offered.\n */\nexport function isThreadRenameUnavailableError(error: unknown): boolean {\n return isThreadRouteUnavailableError(error, 'thread_rename_failed');\n}\n\n/**\n * True when `archiveThread` failed because the backend offers no archive\n * route: a 405, FastAPI's bare 404 on an agora without the route, or the\n * route's own `\"Endpoint not available\"` 404 on an agora without the\n * checkpointer. The route's `\"Thread <id> not found\"` 404 for a stale row is\n * a per-row failure and leaves the action offered on every other row.\n */\nexport function isThreadArchiveUnavailableError(error: unknown): boolean {\n return isThreadRouteUnavailableError(error, 'thread_archive_failed');\n}\n\nexport async function createThread(\n backendUrl: string,\n auth: AuthConfig,\n opts: { systemPrompt?: string; enabledTools?: string[]; appId?: string } = {},\n): Promise<ThreadCreateResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/unstable/threads/`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n body: JSON.stringify({\n config: {\n system_prompt: opts.systemPrompt ?? '',\n enabled_tools: opts.enabledTools,\n ...(opts.appId ? { app_id: opts.appId } : {}),\n },\n }),\n });\n if (!res.ok) {\n throw new Error(`[AthenaSDK] Failed to create thread: ${res.status}`);\n }\n return res.json();\n}\n\nexport interface ThreadStateResponse {\n thread_id: string;\n messages: unknown[];\n status?: string;\n [key: string]: unknown;\n}\n\ninterface ConversationThreadResponse {\n thread?: {\n thread_id?: string;\n state?: string | null;\n channel_values?: Record<string, unknown> | null;\n messages?: unknown[] | null;\n } | null;\n thread_found?: boolean;\n}\n\n/**\n * Deserialize a LangChain serialized message.\n * The API returns messages in `{lc, type: \"constructor\", id, kwargs}` format.\n * We need the plain format: `{type: \"human\", content: \"...\", id: \"...\"}`.\n */\nfunction deserializeMessage(msg: unknown): unknown {\n if (\n msg &&\n typeof msg === 'object' &&\n 'lc' in msg &&\n 'kwargs' in msg &&\n (msg as Record<string, unknown>).type === 'constructor'\n ) {\n const kwargs = (msg as { kwargs: Record<string, unknown> }).kwargs;\n\n // Recursively deserialize nested content without mutating the original\n const deserializedToolCalls = Array.isArray(kwargs.tool_calls)\n ? kwargs.tool_calls.map((tc: unknown) => {\n if (tc && typeof tc === 'object' && 'lc' in tc && 'kwargs' in tc) {\n return (tc as { kwargs: unknown }).kwargs;\n }\n return tc;\n })\n : kwargs.tool_calls;\n\n return { ...kwargs, tool_calls: deserializedToolCalls };\n }\n return msg;\n}\n\n/** Return a non-sensitive auth label for request diagnostics. */\nfunction getAuthMode(auth: AuthConfig): 'bearer' | 'api-key' | 'none' {\n if (auth.token) {\n return 'bearer';\n }\n if (auth.apiKey) {\n return 'api-key';\n }\n return 'none';\n}\n\n/** Safely read a response body for error messages without masking the root failure. */\nfunction getResponseErrorBody(response: Response): Promise<string> {\n return response.text().catch(() => '');\n}\n\n/**\n * Fetch persisted thread state from the conversations API.\n *\n * This endpoint is the same source used by Athena's conversation sidebar and\n * supports API-key auth plus BYO SSO session tokens sent as Bearer tokens.\n */\nexport async function getThreadState(\n backendUrl: string,\n auth: AuthConfig,\n threadId: string,\n opts: {\n /**\n * Bypass the server's Redis thread cache and read the checkpoint (default\n * `true`, the history load's contract). A warm-up read that only seeds a\n * first paint passes `false`: the cached copy is cheaper and the attach\n * snapshot replaces it anyway.\n */\n skipCache?: boolean;\n signal?: AbortSignal;\n } = {},\n): Promise<ThreadStateResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const authMode = getAuthMode(auth);\n const endpoint = `${base}/api/conversations/threads/get`;\n\n const endSpan = athenaDiagnostics.span('threads.history', 'threads.history.start', {\n thread_id: threadId,\n auth_mode: authMode,\n });\n\n let res: Response;\n try {\n res = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n signal: opts.signal ?? null,\n body: JSON.stringify({\n thread_id: threadId,\n skip_cache: opts.skipCache ?? true,\n }),\n });\n } catch (error) {\n if (isAbortError(error)) {\n endSpan('threads.history.aborted', {\n data: { thread_id: threadId, reason: 'request aborted' },\n });\n } else {\n endSpan('threads.history.error', { error, data: { thread_id: threadId } });\n }\n throw error;\n }\n if (!res.ok) {\n const body = await getResponseErrorBody(res);\n const error = new AthenaSdkError({\n code: res.status === 401 || res.status === 403 ? 'auth_rejected' : 'thread_load_failed',\n message: `Failed to get thread state: ${res.status} (${authMode})${\n body ? `: ${body.slice(0, 300)}` : ''\n }`,\n status: res.status,\n hint: 'A brand-new thread may not be persisted yet; anything else means the credential or backendUrl is wrong.',\n context: { thread_id: threadId, auth_mode: authMode },\n });\n endSpan('threads.history.error', { error, data: { thread_id: threadId } });\n throw error;\n }\n const data = (await res.json()) as ConversationThreadResponse;\n const channelMessages = data.thread?.channel_values?.messages;\n endSpan('threads.history.done', {\n data: {\n thread_id: threadId,\n found: data.thread_found !== false,\n message_count: Array.isArray(channelMessages)\n ? channelMessages.length\n : (data.thread?.messages?.length ?? 0),\n },\n });\n const thread = data.thread;\n\n if (data.thread_found === false || !thread) {\n return {\n thread_id: threadId,\n messages: [],\n };\n }\n\n const channelValues = thread.channel_values ?? {};\n const rawMessages = Array.isArray(channelValues.messages)\n ? channelValues.messages\n : Array.isArray(thread.messages)\n ? thread.messages\n : [];\n\n return {\n ...channelValues,\n thread_id: thread.thread_id ?? threadId,\n messages: rawMessages.map(deserializeMessage),\n ...(thread.state ? { status: thread.state } : {}),\n };\n}\n\n/**\n * Archive a thread (`POST /api/conversations/threads/archive`): it leaves\n * every list but keeps its state. Rejections: 401 / 403 when the caller\n * cannot access the thread (`auth_rejected`), otherwise\n * `thread_archive_failed` with the HTTP status — 404 / 405 when the backend\n * has no archive route, which `isThreadArchiveUnavailableError` recognizes.\n */\nexport async function archiveThread(\n backendUrl: string,\n auth: AuthConfig,\n threadId: string,\n): Promise<void> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/conversations/threads/archive`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n body: JSON.stringify({ thread_id: threadId }),\n });\n if (!res.ok) {\n const refused = res.status === 401 || res.status === 403;\n const { routeMissing, detail } = classifyThreadRouteRejection(\n res.status,\n await getResponseErrorBody(res),\n threadId,\n );\n throw new AthenaSdkError({\n code: refused ? 'auth_rejected' : 'thread_archive_failed',\n message: `Failed to archive thread: ${res.status}`,\n status: res.status,\n detail,\n hint: refused\n ? 'The credential cannot access this thread.'\n : routeMissing\n ? 'The backend has no archive route (no checkpointer, or an older agora).'\n : res.status === 404\n ? 'The thread no longer exists on the server (archived or deleted elsewhere); refresh the list.'\n : 'Check backendUrl points at the Agora API base.',\n context: { thread_id: threadId, auth_mode: getAuthMode(auth), route_missing: routeMissing },\n });\n }\n}\n"],"names":["athenaDiagnostics","AthenaSdkError","isAthenaSdkError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api.cjs","sources":["../../src/threads/api.ts"],"sourcesContent":["/**\n * Athena thread API client.\n * Calls existing REST endpoints for thread CRUD.\n */\n\nimport type {\n ConversationAttention,\n ConversationAttentionSource,\n} from '@athenaintel/agent-runtime';\nimport { athenaDiagnostics } from '../diagnostics/athena-diagnostics';\nimport { AthenaSdkError, type AthenaSdkErrorCode, isAthenaSdkError } from '../diagnostics/errors';\n\n/**\n * Live GitHub state of a pull request the thread opened, read by the server\n * when the list renders (agora `agent_pr_threads` is the only stored link).\n */\nexport interface ThreadPullRequest {\n /** `owner/repo` the pull request lives in. */\n repo_full_name: string;\n number: number;\n url: string;\n title: string;\n state: 'OPEN' | 'CLOSED' | 'MERGED';\n is_draft: boolean;\n /** GitHub's review decision (APPROVED, CHANGES_REQUESTED, REVIEW_REQUIRED) or null. */\n review_decision: string | null;\n /** Combined state of the checks on the head commit. */\n checks_state: 'SUCCESS' | 'FAILURE' | 'PENDING' | 'NONE';\n /** ISO 8601 timestamp of the pull request's last update on GitHub. */\n updated_at: string;\n}\n\n/** The last event that woke a resting thread (a GitHub webhook, a schedule, a handoff). */\nexport interface ThreadWake {\n source: string | null;\n reason: string | null;\n /** ISO 8601 timestamp of the wake. */\n at: string | null;\n}\n\nexport interface ThreadSummary {\n thread_id: string;\n title: string;\n created_at: string;\n updated_at: string;\n last_message: string | null;\n message_count: number;\n state: string | null;\n start_channel?: string | null;\n last_channel?: string | null;\n /** Client app that created the session (SESSION_APP_ID_GUIDE). */\n app_id?: string | null;\n /** Collab agent and channel the session started on; older servers omit them. */\n collab_agent_id?: string | null;\n collab_channel_id?: string | null;\n /** Trigger marker for automated/background sessions. */\n trigger_type?: string | null;\n /** Whether the calling user has seen this thread since it last changed. */\n is_unread?: boolean;\n /**\n * Canonical status_v2 planes (`idle | active | needs_input | error` and\n * `scheduled | queued | running | needs_input | completed | failed |\n * canceled`); older servers omit them.\n */\n session_status?: string | null;\n run_status?: string | null;\n /**\n * The viewer's attention state, the one-line next action (≤ 80 chars) and\n * the signal that produced them, derived server-side; older servers omit them.\n */\n attention?: ConversationAttention | null;\n next_action?: string | null;\n attention_source?: ConversationAttentionSource | null;\n /** Whether the calling user favorited (pinned) the thread; older servers omit it. */\n is_favorited?: boolean;\n /** The last wake of a resting thread; older servers omit it. */\n last_wake?: ThreadWake | null;\n /** Whether the calling user started the thread (`false`: shared with them); older servers omit it. */\n created_by_me?: boolean;\n /**\n * Pull requests the thread opened with their live GitHub state. `[]` when\n * it opened none, `null` when the state could not be read right now;\n * older servers omit the field.\n */\n pull_requests?: ThreadPullRequest[] | null;\n}\n\n/**\n * True for fetch cancellations (unmount/remount aborts, StrictMode double\n * effects). These are lifecycle noise, not failures: emitting them as\n * `*.error` diagnostics floods the console with\n * \"signal is aborted without reason\" for requests the caller itself aborted.\n */\nfunction isAbortError(error: unknown): boolean {\n return (\n (error instanceof DOMException && error.name === 'AbortError') ||\n (error instanceof Error && error.name === 'AbortError')\n );\n}\n\nexport interface ThreadListResponse {\n threads: ThreadSummary[];\n /** Server lookahead result. Older servers may omit this field. */\n has_more?: boolean;\n /**\n * Every request field the server applies beyond paging. The server ignores\n * fields it does not know, so a filter missing from this list came back\n * unapplied; servers that predate the list omit it (none of the\n * `ThreadListFilterBody` fields are applied there).\n */\n supported_filters?: string[];\n /**\n * Whether the page also holds the conversations with the `home_agent_id`\n * agent: true only when the request named one, the agent has a home app set\n * and the caller can open the agent. Servers that predate the field omit it,\n * which reads as false.\n */\n home_agent_applied?: boolean;\n}\n\n/**\n * The server-side filters and order of `POST /api/conversations/threads/list`\n * beyond the original `app_id` / `start_channel` / `search` /\n * `exclude_triggered` set. Each is a predicate of the server's one page\n * statement, so a page is exact; a server that predates a field ignores it\n * (check `ThreadListResponse.supported_filters`).\n */\nexport interface ThreadListFilterBody {\n /** Original fields, accepted here too so one body can carry a whole query. */\n search?: string;\n exclude_triggered?: boolean;\n app_ids?: string[];\n /**\n * A collab agent (`asset_<uuid>`) whose home this list's app is. When the\n * agent has a home app set and the caller can open the agent, the app scope\n * (`app_id` / `app_ids`) widens to every conversation with the agent too,\n * ANDed with the other filters as usual; `home_agent_applied` on the answer\n * says whether it did.\n */\n home_agent_id?: string;\n start_channels?: string[];\n created_after?: string;\n created_before?: string;\n updated_after?: string;\n updated_before?: string;\n collab_agent_ids?: string[];\n /** `'default'` matches the agent's default channel (no channel stamp); needs `collab_agent_ids`. */\n collab_channel_ids?: string[];\n favorites_only?: boolean;\n unread_only?: boolean;\n run_statuses?: string[];\n session_statuses?: string[];\n has_pull_requests?: boolean;\n created_by_me?: boolean;\n exclude_dismissed?: boolean;\n sort?: 'updated' | 'created';\n direction?: 'desc' | 'asc';\n}\n\nexport interface ThreadCreateResponse {\n thread_id: string;\n}\n\ninterface AuthConfig {\n apiKey?: string;\n token?: string | null;\n credentials?: RequestCredentials;\n}\n\nfunction getAuthHeaders(auth: AuthConfig): Record<string, string> {\n if (auth.token) {\n return { Authorization: `Bearer ${auth.token}` };\n }\n if (auth.apiKey) {\n return { 'X-API-KEY': auth.apiKey };\n }\n return {};\n}\n\n/**\n * Resolves the Athena API base URL from backendUrl.\n * Thread endpoints live under `/api/conversations/threads/*` and `/api/unstable/threads/`.\n * If backendUrl points at a nested Athena endpoint, trim it back to the API base first.\n */\nfunction getAthenaApiBaseUrl(backendUrl: string): string {\n const stripped = backendUrl.replace(/\\/api\\/assistant-ui\\/?$/, '');\n // If the suffix wasn't found, assume the URL already points to the API base\n if (stripped === backendUrl) {\n return backendUrl.replace(/\\/$/, '');\n }\n return stripped;\n}\n\nexport async function listThreads(\n backendUrl: string,\n auth: AuthConfig,\n opts: {\n limit?: number;\n offset?: number;\n exclude_triggered?: boolean;\n app_id?: string;\n start_channel?: string;\n search?: string;\n /** Ask the server for live GitHub state on `pull_requests` (off by default: it costs a lookup). */\n include_pull_requests?: boolean;\n /** Server-side filters and order beyond the original set (see `ThreadListFilterBody`). */\n filters?: ThreadListFilterBody;\n signal?: AbortSignal;\n } = {},\n): Promise<ThreadListResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const endSpan = athenaDiagnostics.span('threads.list', 'threads.list.start', {\n auth_mode: getAuthMode(auth),\n app_id: opts.app_id,\n });\n try {\n const res = await fetch(`${base}/api/conversations/threads/list`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n signal: opts.signal ?? null,\n body: JSON.stringify({\n limit: opts.limit ?? 50,\n offset: opts.offset ?? 0,\n // Default to the full recent-conversations set unless a caller\n // explicitly asks to hide triggered/background sessions.\n exclude_triggered: opts.exclude_triggered ?? false,\n ...(opts.app_id ? { app_id: opts.app_id } : {}),\n ...(opts.start_channel ? { start_channel: opts.start_channel } : {}),\n ...(opts.search ? { search: opts.search } : {}),\n ...(opts.include_pull_requests ? { include_pull_requests: true } : {}),\n ...opts.filters,\n }),\n });\n if (!res.ok) {\n throw new AthenaSdkError({\n code: res.status === 401 || res.status === 403 ? 'auth_rejected' : 'threads_list_failed',\n message: `Failed to list threads: ${res.status}`,\n status: res.status,\n hint:\n res.status === 401 || res.status === 403\n ? 'The credential was refused. Check the token/API key and that the user belongs to the workspace.'\n : 'Check backendUrl points at the Agora API base.',\n context: { auth_mode: getAuthMode(auth) },\n });\n }\n const data = (await res.json()) as ThreadListResponse;\n endSpan('threads.list.done', { data: { count: data.threads?.length ?? 0 } });\n return data;\n } catch (error) {\n // Cancellation is lifecycle noise (unmount/remount aborts): log it as an\n // informational abort, not an error — passing `error` would force the\n // span end to error level and spam the console.\n if (isAbortError(error)) {\n endSpan('threads.list.aborted', { data: { reason: 'request aborted' } });\n } else {\n endSpan('threads.list.error', { error });\n }\n throw error;\n }\n}\n\n/** The `(workspace, user)` pair the credential resolves to on the backend. */\nexport interface AccountIdentity {\n userId: string;\n /** `null` for a user with no current workspace. */\n workspaceId: string | null;\n}\n\n/**\n * Resolve the credential's agora identity. The conversation index is one\n * statewire instance per `(workspace, user)`, and neither half is knowable\n * from the credential alone: the SDK's auth context carries an identity\n * provider user id, not agora's, and never a workspace.\n */\nexport async function fetchAccountIdentity(\n backendUrl: string,\n auth: AuthConfig,\n opts: { signal?: AbortSignal } = {},\n): Promise<AccountIdentity> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/v0/me`, {\n headers: getAuthHeaders(auth),\n signal: opts.signal ?? null,\n credentials: auth.credentials,\n });\n if (!res.ok) {\n throw new AthenaSdkError({\n code: res.status === 401 || res.status === 403 ? 'auth_rejected' : 'threads_list_failed',\n message: `Failed to resolve account identity: ${res.status}`,\n status: res.status,\n hint:\n res.status === 401 || res.status === 403\n ? 'The credential was refused. Check the token/API key and that the user belongs to the workspace.'\n : 'Check backendUrl points at the Agora API base.',\n context: { auth_mode: getAuthMode(auth) },\n });\n }\n const body = (await res.json()) as { user_id?: unknown; workspace_id?: unknown };\n if (typeof body.user_id !== 'string' || body.user_id.length === 0) {\n throw new AthenaSdkError({\n code: 'threads_list_failed',\n message: 'Account identity lookup returned no user id.',\n context: { auth_mode: getAuthMode(auth) },\n });\n }\n return {\n userId: body.user_id,\n workspaceId: typeof body.workspace_id === 'string' ? body.workspace_id : null,\n };\n}\n\nexport interface ThreadReadStateResponse {\n thread_id: string;\n is_unread: boolean;\n}\n\n/** Store the calling user's read receipt for a thread. */\nexport async function setThreadReadState(\n backendUrl: string,\n auth: AuthConfig,\n opts: { threadId: string; isUnread: boolean },\n): Promise<ThreadReadStateResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/conversations/threads/read-state`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n body: JSON.stringify({\n thread_id: opts.threadId,\n is_unread: opts.isUnread,\n }),\n });\n if (!res.ok) {\n throw new AthenaSdkError({\n code: res.status === 401 || res.status === 403 ? 'auth_rejected' : 'unknown',\n message: `Failed to set thread read state: ${res.status}`,\n status: res.status,\n });\n }\n return res.json();\n}\n\nexport interface ThreadInboxDismissResponse {\n success: boolean;\n dismissed: boolean;\n}\n\n/**\n * Dismiss a session from the inbox, or bring it back\n * (`POST /api/conversations/threads/notifications/dismiss`). A dismissed\n * session returns on its own with its next message. The state lives on the\n * session for its creator's inbox, so the route takes EDIT on the session\n * (403 for a VIEW share).\n */\nexport async function dismissThreadFromInbox(\n backendUrl: string,\n auth: AuthConfig,\n opts: { threadId: string; dismissed: boolean },\n): Promise<ThreadInboxDismissResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/conversations/threads/notifications/dismiss`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n body: JSON.stringify({ thread_id: opts.threadId, dismissed: opts.dismissed }),\n });\n if (!res.ok) {\n throw new AthenaSdkError({\n code: res.status === 401 || res.status === 403 ? 'auth_rejected' : 'unknown',\n message: `Failed to ${opts.dismissed ? 'dismiss' : 'restore'} the session: ${res.status}`,\n status: res.status,\n hint:\n res.status === 403\n ? 'Only someone who can edit the session (its creator, usually) can dismiss it from the inbox.'\n : undefined,\n context: { thread_id: opts.threadId, auth_mode: getAuthMode(auth) },\n });\n }\n return res.json();\n}\n\nexport interface ThreadFavoriteResponse {\n thread_id: string;\n /** The server's state after the write. */\n is_favorited: boolean;\n}\n\n/**\n * Classify a 4xx from one of the per-thread write routes (`favorite`,\n * `rename`, `archive`). A 404 there is ambiguous: FastAPI answers\n * `{\"detail\":\"Not Found\"}` for a route an older agora does not have, the\n * archive route answers `\"Endpoint not available\"` on an agora without the\n * checkpointer — and each route answers 404 for a thread that no longer\n * exists (`\"Thread <id> not found\"`, `\"Conversation with langchain thread id\n * <id> not found\"`). The routes' own not-found answers name the thread, so a\n * body that does not is the ROUTE missing, and only that withdraws the\n * feature; a stale row must not disable the action for every other row.\n */\nfunction classifyThreadRouteRejection(\n status: number,\n body: string,\n threadId: string,\n): { routeMissing: boolean; detail: unknown } {\n let detail: unknown = body || undefined;\n try {\n const parsed: unknown = JSON.parse(body);\n if (parsed && typeof parsed === 'object') {\n const record = parsed as { detail?: unknown; message?: unknown };\n detail = record.detail ?? record.message ?? parsed;\n }\n } catch {\n // A non-JSON body (a proxy page) is kept as text.\n }\n const routeMissing = status === 405 || (status === 404 && !mentionsThread(body, threadId));\n return { routeMissing, detail };\n}\n\n/**\n * Whether an error body names the thread as a whole token (the routes embed\n * the id between spaces: `Thread <id> not found`); a substring match would\n * let a short id match a letter inside `\"detail\"`.\n */\nfunction mentionsThread(body: string, threadId: string): boolean {\n if (!threadId) return false;\n const escaped = threadId.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n return new RegExp(`(^|[^A-Za-z0-9_-])${escaped}($|[^A-Za-z0-9_-])`).test(body);\n}\n\n/** True when a per-thread write was rejected because the backend has no such route. */\nfunction isThreadRouteUnavailableError(error: unknown, code: AthenaSdkErrorCode): boolean {\n return isAthenaSdkError(error) && error.code === code && error.context.route_missing === true;\n}\n\n/**\n * Pin (favorite) or unpin a thread for the calling user. The response is the\n * server's truth after the write. Rejections: 401 / 403 when the caller\n * cannot view the thread (`auth_rejected`), otherwise `thread_favorite_failed`\n * with the HTTP status — 404 / 405 from an agora that predates the route,\n * which `isThreadFavoriteUnavailableError` recognizes so callers can fall\n * back to a read-only pin.\n */\nexport async function setThreadFavorite(\n backendUrl: string,\n auth: AuthConfig,\n opts: { threadId: string; isFavorited: boolean },\n): Promise<ThreadFavoriteResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/conversations/threads/favorite`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n body: JSON.stringify({\n thread_id: opts.threadId,\n is_favorited: opts.isFavorited,\n }),\n });\n if (!res.ok) {\n const refused = res.status === 401 || res.status === 403;\n const { routeMissing, detail } = classifyThreadRouteRejection(\n res.status,\n await getResponseErrorBody(res),\n opts.threadId,\n );\n throw new AthenaSdkError({\n code: refused ? 'auth_rejected' : 'thread_favorite_failed',\n message: `Failed to set thread favorite: ${res.status}`,\n status: res.status,\n detail,\n hint: refused\n ? 'The credential cannot view this thread.'\n : routeMissing\n ? 'The backend has no favorite route yet (older agora); the pin stays read-only until it deploys.'\n : res.status === 404\n ? 'The thread no longer exists on the server (archived or deleted elsewhere); refresh the list.'\n : 'Check backendUrl points at the Agora API base.',\n context: { thread_id: opts.threadId, auth_mode: getAuthMode(auth), route_missing: routeMissing },\n });\n }\n return res.json();\n}\n\n/**\n * True when `setThreadFavorite` failed because the backend has no favorite\n * route (a 405, or a 404 whose body does not name the thread — see\n * `classifyThreadRouteRejection`); a 404 for a thread that is gone is a\n * per-row failure and leaves the toggle available.\n */\nexport function isThreadFavoriteUnavailableError(error: unknown): boolean {\n return isThreadRouteUnavailableError(error, 'thread_favorite_failed');\n}\n\nexport interface ThreadRenameResponse {\n thread_id: string;\n /** The stored title after the write (trimmed by the server). */\n title: string;\n}\n\n/** The longest title the rename route accepts; the server answers 422 past it. */\nexport const THREAD_TITLE_MAX_LENGTH = 200;\n\n/**\n * Rename a thread for every viewer (`POST /api/conversations/threads/rename`).\n * The server trims the title and stores 1–200 characters; the response is the\n * row's title after the write. Rejections: 401 / 403 when the caller cannot\n * edit the thread (`auth_rejected` — a viewer can pin a shared session but not\n * retitle it), otherwise `thread_rename_failed` with the HTTP status — 404 /\n * 405 from an agora that predates the route, which\n * `isThreadRenameUnavailableError` recognizes so callers can drop the action.\n */\nexport async function renameThread(\n backendUrl: string,\n auth: AuthConfig,\n opts: { threadId: string; title: string },\n): Promise<ThreadRenameResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/conversations/threads/rename`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n body: JSON.stringify({\n thread_id: opts.threadId,\n title: opts.title,\n }),\n });\n if (!res.ok) {\n const refused = res.status === 401 || res.status === 403;\n const { routeMissing, detail } = classifyThreadRouteRejection(\n res.status,\n await getResponseErrorBody(res),\n opts.threadId,\n );\n throw new AthenaSdkError({\n code: refused ? 'auth_rejected' : 'thread_rename_failed',\n message: `Failed to rename thread: ${res.status}`,\n status: res.status,\n detail,\n hint: refused\n ? 'The credential cannot edit this thread (a viewer can pin a shared session, not retitle it).'\n : routeMissing\n ? 'The backend has no rename route yet (older agora); sessions cannot be renamed from here until it deploys.'\n : res.status === 404\n ? 'The thread no longer exists on the server (archived or deleted elsewhere); refresh the list.'\n : res.status === 422\n ? `The title must be 1–${THREAD_TITLE_MAX_LENGTH} characters after trimming.`\n : 'Check backendUrl points at the Agora API base.',\n context: { thread_id: opts.threadId, auth_mode: getAuthMode(auth), route_missing: routeMissing },\n });\n }\n return res.json();\n}\n\n/**\n * True when `renameThread` failed because the backend has no rename route\n * (a 405, or a 404 whose body does not name the thread); a 404 for a thread\n * that is gone is a per-row failure and leaves the action offered.\n */\nexport function isThreadRenameUnavailableError(error: unknown): boolean {\n return isThreadRouteUnavailableError(error, 'thread_rename_failed');\n}\n\n/**\n * True when `archiveThread` failed because the backend offers no archive\n * route: a 405, FastAPI's bare 404 on an agora without the route, or the\n * route's own `\"Endpoint not available\"` 404 on an agora without the\n * checkpointer. The route's `\"Thread <id> not found\"` 404 for a stale row is\n * a per-row failure and leaves the action offered on every other row.\n */\nexport function isThreadArchiveUnavailableError(error: unknown): boolean {\n return isThreadRouteUnavailableError(error, 'thread_archive_failed');\n}\n\nexport async function createThread(\n backendUrl: string,\n auth: AuthConfig,\n opts: { systemPrompt?: string; enabledTools?: string[]; appId?: string } = {},\n): Promise<ThreadCreateResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/unstable/threads/`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n body: JSON.stringify({\n config: {\n system_prompt: opts.systemPrompt ?? '',\n enabled_tools: opts.enabledTools,\n ...(opts.appId ? { app_id: opts.appId } : {}),\n },\n }),\n });\n if (!res.ok) {\n throw new Error(`[AthenaSDK] Failed to create thread: ${res.status}`);\n }\n return res.json();\n}\n\nexport interface ThreadStateResponse {\n thread_id: string;\n messages: unknown[];\n status?: string;\n [key: string]: unknown;\n}\n\ninterface ConversationThreadResponse {\n thread?: {\n thread_id?: string;\n state?: string | null;\n channel_values?: Record<string, unknown> | null;\n messages?: unknown[] | null;\n } | null;\n thread_found?: boolean;\n}\n\n/**\n * Deserialize a LangChain serialized message.\n * The API returns messages in `{lc, type: \"constructor\", id, kwargs}` format.\n * We need the plain format: `{type: \"human\", content: \"...\", id: \"...\"}`.\n */\nfunction deserializeMessage(msg: unknown): unknown {\n if (\n msg &&\n typeof msg === 'object' &&\n 'lc' in msg &&\n 'kwargs' in msg &&\n (msg as Record<string, unknown>).type === 'constructor'\n ) {\n const kwargs = (msg as { kwargs: Record<string, unknown> }).kwargs;\n\n // Recursively deserialize nested content without mutating the original\n const deserializedToolCalls = Array.isArray(kwargs.tool_calls)\n ? kwargs.tool_calls.map((tc: unknown) => {\n if (tc && typeof tc === 'object' && 'lc' in tc && 'kwargs' in tc) {\n return (tc as { kwargs: unknown }).kwargs;\n }\n return tc;\n })\n : kwargs.tool_calls;\n\n return { ...kwargs, tool_calls: deserializedToolCalls };\n }\n return msg;\n}\n\n/** Return a non-sensitive auth label for request diagnostics. */\nfunction getAuthMode(auth: AuthConfig): 'bearer' | 'api-key' | 'none' {\n if (auth.token) {\n return 'bearer';\n }\n if (auth.apiKey) {\n return 'api-key';\n }\n return 'none';\n}\n\n/** Safely read a response body for error messages without masking the root failure. */\nfunction getResponseErrorBody(response: Response): Promise<string> {\n return response.text().catch(() => '');\n}\n\n/**\n * Fetch persisted thread state from the conversations API.\n *\n * This endpoint is the same source used by Athena's conversation sidebar and\n * supports API-key auth plus BYO SSO session tokens sent as Bearer tokens.\n */\nexport async function getThreadState(\n backendUrl: string,\n auth: AuthConfig,\n threadId: string,\n opts: {\n /**\n * Bypass the server's Redis thread cache and read the checkpoint (default\n * `true`, the history load's contract). A warm-up read that only seeds a\n * first paint passes `false`: the cached copy is cheaper and the attach\n * snapshot replaces it anyway.\n */\n skipCache?: boolean;\n signal?: AbortSignal;\n } = {},\n): Promise<ThreadStateResponse> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const authMode = getAuthMode(auth);\n const endpoint = `${base}/api/conversations/threads/get`;\n\n const endSpan = athenaDiagnostics.span('threads.history', 'threads.history.start', {\n thread_id: threadId,\n auth_mode: authMode,\n });\n\n let res: Response;\n try {\n res = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n signal: opts.signal ?? null,\n body: JSON.stringify({\n thread_id: threadId,\n skip_cache: opts.skipCache ?? true,\n }),\n });\n } catch (error) {\n if (isAbortError(error)) {\n endSpan('threads.history.aborted', {\n data: { thread_id: threadId, reason: 'request aborted' },\n });\n } else {\n endSpan('threads.history.error', { error, data: { thread_id: threadId } });\n }\n throw error;\n }\n if (!res.ok) {\n const body = await getResponseErrorBody(res);\n const error = new AthenaSdkError({\n code: res.status === 401 || res.status === 403 ? 'auth_rejected' : 'thread_load_failed',\n message: `Failed to get thread state: ${res.status} (${authMode})${\n body ? `: ${body.slice(0, 300)}` : ''\n }`,\n status: res.status,\n hint: 'A brand-new thread may not be persisted yet; anything else means the credential or backendUrl is wrong.',\n context: { thread_id: threadId, auth_mode: authMode },\n });\n endSpan('threads.history.error', { error, data: { thread_id: threadId } });\n throw error;\n }\n const data = (await res.json()) as ConversationThreadResponse;\n const channelMessages = data.thread?.channel_values?.messages;\n endSpan('threads.history.done', {\n data: {\n thread_id: threadId,\n found: data.thread_found !== false,\n message_count: Array.isArray(channelMessages)\n ? channelMessages.length\n : (data.thread?.messages?.length ?? 0),\n },\n });\n const thread = data.thread;\n\n if (data.thread_found === false || !thread) {\n return {\n thread_id: threadId,\n messages: [],\n };\n }\n\n const channelValues = thread.channel_values ?? {};\n const rawMessages = Array.isArray(channelValues.messages)\n ? channelValues.messages\n : Array.isArray(thread.messages)\n ? thread.messages\n : [];\n\n return {\n ...channelValues,\n thread_id: thread.thread_id ?? threadId,\n messages: rawMessages.map(deserializeMessage),\n ...(thread.state ? { status: thread.state } : {}),\n };\n}\n\n/**\n * Archive a thread (`POST /api/conversations/threads/archive`): it leaves\n * every list but keeps its state. Rejections: 401 / 403 when the caller\n * cannot access the thread (`auth_rejected`), otherwise\n * `thread_archive_failed` with the HTTP status — 404 / 405 when the backend\n * has no archive route, which `isThreadArchiveUnavailableError` recognizes.\n */\nexport async function archiveThread(\n backendUrl: string,\n auth: AuthConfig,\n threadId: string,\n): Promise<void> {\n const base = getAthenaApiBaseUrl(backendUrl);\n const res = await fetch(`${base}/api/conversations/threads/archive`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...getAuthHeaders(auth) },\n body: JSON.stringify({ thread_id: threadId }),\n });\n if (!res.ok) {\n const refused = res.status === 401 || res.status === 403;\n const { routeMissing, detail } = classifyThreadRouteRejection(\n res.status,\n await getResponseErrorBody(res),\n threadId,\n );\n throw new AthenaSdkError({\n code: refused ? 'auth_rejected' : 'thread_archive_failed',\n message: `Failed to archive thread: ${res.status}`,\n status: res.status,\n detail,\n hint: refused\n ? 'The credential cannot access this thread.'\n : routeMissing\n ? 'The backend has no archive route (no checkpointer, or an older agora).'\n : res.status === 404\n ? 'The thread no longer exists on the server (archived or deleted elsewhere); refresh the list.'\n : 'Check backendUrl points at the Agora API base.',\n context: { thread_id: threadId, auth_mode: getAuthMode(auth), route_missing: routeMissing },\n });\n }\n}\n"],"names":["athenaDiagnostics","AthenaSdkError","isAthenaSdkError"],"mappings":";;;;AA6FA,SAAS,aAAa,OAAyB;AAC7C,SACG,iBAAiB,gBAAgB,MAAM,SAAS,gBAChD,iBAAiB,SAAS,MAAM,SAAS;AAE9C;AAuEA,SAAS,eAAe,MAA0C;AAChE,MAAI,KAAK,OAAO;AACd,WAAO,EAAE,eAAe,UAAU,KAAK,KAAK,GAAA;AAAA,EAC9C;AACA,MAAI,KAAK,QAAQ;AACf,WAAO,EAAE,aAAa,KAAK,OAAA;AAAA,EAC7B;AACA,SAAO,CAAA;AACT;AAOA,SAAS,oBAAoB,YAA4B;AACvD,QAAM,WAAW,WAAW,QAAQ,2BAA2B,EAAE;AAEjE,MAAI,aAAa,YAAY;AAC3B,WAAO,WAAW,QAAQ,OAAO,EAAE;AAAA,EACrC;AACA,SAAO;AACT;AAEA,eAAsB,YACpB,YACA,MACA,OAYI,CAAA,GACyB;;AAC7B,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,UAAUA,kBAAAA,kBAAkB,KAAK,gBAAgB,sBAAsB;AAAA,IAC3E,WAAW,YAAY,IAAI;AAAA,IAC3B,QAAQ,KAAK;AAAA,EAAA,CACd;AACD,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,IAAI,mCAAmC;AAAA,MAChE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,oBAAoB,GAAG,eAAe,IAAI,EAAA;AAAA,MACrE,QAAQ,KAAK,UAAU;AAAA,MACvB,MAAM,KAAK,UAAU;AAAA,QACnB,OAAO,KAAK,SAAS;AAAA,QACrB,QAAQ,KAAK,UAAU;AAAA;AAAA;AAAA,QAGvB,mBAAmB,KAAK,qBAAqB;AAAA,QAC7C,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAA,IAAW,CAAA;AAAA,QAC5C,GAAI,KAAK,gBAAgB,EAAE,eAAe,KAAK,cAAA,IAAkB,CAAA;AAAA,QACjE,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAA,IAAW,CAAA;AAAA,QAC5C,GAAI,KAAK,wBAAwB,EAAE,uBAAuB,KAAA,IAAS,CAAA;AAAA,QACnE,GAAG,KAAK;AAAA,MAAA,CACT;AAAA,IAAA,CACF;AACD,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAIC,OAAAA,eAAe;AAAA,QACvB,MAAM,IAAI,WAAW,OAAO,IAAI,WAAW,MAAM,kBAAkB;AAAA,QACnE,SAAS,2BAA2B,IAAI,MAAM;AAAA,QAC9C,QAAQ,IAAI;AAAA,QACZ,MACE,IAAI,WAAW,OAAO,IAAI,WAAW,MACjC,oGACA;AAAA,QACN,SAAS,EAAE,WAAW,YAAY,IAAI,EAAA;AAAA,MAAE,CACzC;AAAA,IACH;AACA,UAAM,OAAQ,MAAM,IAAI,KAAA;AACxB,YAAQ,qBAAqB,EAAE,MAAM,EAAE,SAAO,UAAK,YAAL,mBAAc,WAAU,EAAA,GAAK;AAC3E,WAAO;AAAA,EACT,SAAS,OAAO;AAId,QAAI,aAAa,KAAK,GAAG;AACvB,cAAQ,wBAAwB,EAAE,MAAM,EAAE,QAAQ,kBAAA,GAAqB;AAAA,IACzE,OAAO;AACL,cAAQ,sBAAsB,EAAE,OAAO;AAAA,IACzC;AACA,UAAM;AAAA,EACR;AACF;AAeA,eAAsB,qBACpB,YACA,MACA,OAAiC,CAAA,GACP;AAC1B,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,MAAM,MAAM,MAAM,GAAG,IAAI,cAAc;AAAA,IAC3C,SAAS,eAAe,IAAI;AAAA,IAC5B,QAAQ,KAAK,UAAU;AAAA,IACvB,aAAa,KAAK;AAAA,EAAA,CACnB;AACD,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAIA,OAAAA,eAAe;AAAA,MACvB,MAAM,IAAI,WAAW,OAAO,IAAI,WAAW,MAAM,kBAAkB;AAAA,MACnE,SAAS,uCAAuC,IAAI,MAAM;AAAA,MAC1D,QAAQ,IAAI;AAAA,MACZ,MACE,IAAI,WAAW,OAAO,IAAI,WAAW,MACjC,oGACA;AAAA,MACN,SAAS,EAAE,WAAW,YAAY,IAAI,EAAA;AAAA,IAAE,CACzC;AAAA,EACH;AACA,QAAM,OAAQ,MAAM,IAAI,KAAA;AACxB,MAAI,OAAO,KAAK,YAAY,YAAY,KAAK,QAAQ,WAAW,GAAG;AACjE,UAAM,IAAIA,OAAAA,eAAe;AAAA,MACvB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,EAAE,WAAW,YAAY,IAAI,EAAA;AAAA,IAAE,CACzC;AAAA,EACH;AACA,SAAO;AAAA,IACL,QAAQ,KAAK;AAAA,IACb,aAAa,OAAO,KAAK,iBAAiB,WAAW,KAAK,eAAe;AAAA,EAAA;AAE7E;AAQA,eAAsB,mBACpB,YACA,MACA,MACkC;AAClC,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,MAAM,MAAM,MAAM,GAAG,IAAI,yCAAyC;AAAA,IACtE,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,oBAAoB,GAAG,eAAe,IAAI,EAAA;AAAA,IACrE,MAAM,KAAK,UAAU;AAAA,MACnB,WAAW,KAAK;AAAA,MAChB,WAAW,KAAK;AAAA,IAAA,CACjB;AAAA,EAAA,CACF;AACD,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAIA,OAAAA,eAAe;AAAA,MACvB,MAAM,IAAI,WAAW,OAAO,IAAI,WAAW,MAAM,kBAAkB;AAAA,MACnE,SAAS,oCAAoC,IAAI,MAAM;AAAA,MACvD,QAAQ,IAAI;AAAA,IAAA,CACb;AAAA,EACH;AACA,SAAO,IAAI,KAAA;AACb;AAcA,eAAsB,uBACpB,YACA,MACA,MACqC;AACrC,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,MAAM,MAAM,MAAM,GAAG,IAAI,oDAAoD;AAAA,IACjF,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,oBAAoB,GAAG,eAAe,IAAI,EAAA;AAAA,IACrE,MAAM,KAAK,UAAU,EAAE,WAAW,KAAK,UAAU,WAAW,KAAK,UAAA,CAAW;AAAA,EAAA,CAC7E;AACD,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAIA,OAAAA,eAAe;AAAA,MACvB,MAAM,IAAI,WAAW,OAAO,IAAI,WAAW,MAAM,kBAAkB;AAAA,MACnE,SAAS,aAAa,KAAK,YAAY,YAAY,SAAS,iBAAiB,IAAI,MAAM;AAAA,MACvF,QAAQ,IAAI;AAAA,MACZ,MACE,IAAI,WAAW,MACX,gGACA;AAAA,MACN,SAAS,EAAE,WAAW,KAAK,UAAU,WAAW,YAAY,IAAI,EAAA;AAAA,IAAE,CACnE;AAAA,EACH;AACA,SAAO,IAAI,KAAA;AACb;AAmBA,SAAS,6BACP,QACA,MACA,UAC4C;AAC5C,MAAI,SAAkB,QAAQ;AAC9B,MAAI;AACF,UAAM,SAAkB,KAAK,MAAM,IAAI;AACvC,QAAI,UAAU,OAAO,WAAW,UAAU;AACxC,YAAM,SAAS;AACf,eAAS,OAAO,UAAU,OAAO,WAAW;AAAA,IAC9C;AAAA,EACF,QAAQ;AAAA,EAER;AACA,QAAM,eAAe,WAAW,OAAQ,WAAW,OAAO,CAAC,eAAe,MAAM,QAAQ;AACxF,SAAO,EAAE,cAAc,OAAA;AACzB;AAOA,SAAS,eAAe,MAAc,UAA2B;AAC/D,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,UAAU,SAAS,QAAQ,uBAAuB,MAAM;AAC9D,SAAO,IAAI,OAAO,qBAAqB,OAAO,oBAAoB,EAAE,KAAK,IAAI;AAC/E;AAGA,SAAS,8BAA8B,OAAgB,MAAmC;AACxF,SAAOC,OAAAA,iBAAiB,KAAK,KAAK,MAAM,SAAS,QAAQ,MAAM,QAAQ,kBAAkB;AAC3F;AAUA,eAAsB,kBACpB,YACA,MACA,MACiC;AACjC,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,MAAM,MAAM,MAAM,GAAG,IAAI,uCAAuC;AAAA,IACpE,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,oBAAoB,GAAG,eAAe,IAAI,EAAA;AAAA,IACrE,MAAM,KAAK,UAAU;AAAA,MACnB,WAAW,KAAK;AAAA,MAChB,cAAc,KAAK;AAAA,IAAA,CACpB;AAAA,EAAA,CACF;AACD,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,UAAU,IAAI,WAAW,OAAO,IAAI,WAAW;AACrD,UAAM,EAAE,cAAc,OAAA,IAAW;AAAA,MAC/B,IAAI;AAAA,MACJ,MAAM,qBAAqB,GAAG;AAAA,MAC9B,KAAK;AAAA,IAAA;AAEP,UAAM,IAAID,OAAAA,eAAe;AAAA,MACvB,MAAM,UAAU,kBAAkB;AAAA,MAClC,SAAS,kCAAkC,IAAI,MAAM;AAAA,MACrD,QAAQ,IAAI;AAAA,MACZ;AAAA,MACA,MAAM,UACF,4CACA,eACE,mGACA,IAAI,WAAW,MACb,iGACA;AAAA,MACR,SAAS,EAAE,WAAW,KAAK,UAAU,WAAW,YAAY,IAAI,GAAG,eAAe,aAAA;AAAA,IAAa,CAChG;AAAA,EACH;AACA,SAAO,IAAI,KAAA;AACb;AAQO,SAAS,iCAAiC,OAAyB;AACxE,SAAO,8BAA8B,OAAO,wBAAwB;AACtE;AASO,MAAM,0BAA0B;AAWvC,eAAsB,aACpB,YACA,MACA,MAC+B;AAC/B,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,MAAM,MAAM,MAAM,GAAG,IAAI,qCAAqC;AAAA,IAClE,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,oBAAoB,GAAG,eAAe,IAAI,EAAA;AAAA,IACrE,MAAM,KAAK,UAAU;AAAA,MACnB,WAAW,KAAK;AAAA,MAChB,OAAO,KAAK;AAAA,IAAA,CACb;AAAA,EAAA,CACF;AACD,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,UAAU,IAAI,WAAW,OAAO,IAAI,WAAW;AACrD,UAAM,EAAE,cAAc,OAAA,IAAW;AAAA,MAC/B,IAAI;AAAA,MACJ,MAAM,qBAAqB,GAAG;AAAA,MAC9B,KAAK;AAAA,IAAA;AAEP,UAAM,IAAIA,OAAAA,eAAe;AAAA,MACvB,MAAM,UAAU,kBAAkB;AAAA,MAClC,SAAS,4BAA4B,IAAI,MAAM;AAAA,MAC/C,QAAQ,IAAI;AAAA,MACZ;AAAA,MACA,MAAM,UACF,gGACA,eACE,8GACA,IAAI,WAAW,MACb,iGACA,IAAI,WAAW,MACb,uBAAuB,uBAAuB,gCAC9C;AAAA,MACV,SAAS,EAAE,WAAW,KAAK,UAAU,WAAW,YAAY,IAAI,GAAG,eAAe,aAAA;AAAA,IAAa,CAChG;AAAA,EACH;AACA,SAAO,IAAI,KAAA;AACb;AAOO,SAAS,+BAA+B,OAAyB;AACtE,SAAO,8BAA8B,OAAO,sBAAsB;AACpE;AASO,SAAS,gCAAgC,OAAyB;AACvE,SAAO,8BAA8B,OAAO,uBAAuB;AACrE;AAEA,eAAsB,aACpB,YACA,MACA,OAA2E,CAAA,GAC5C;AAC/B,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,MAAM,MAAM,MAAM,GAAG,IAAI,0BAA0B;AAAA,IACvD,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,oBAAoB,GAAG,eAAe,IAAI,EAAA;AAAA,IACrE,MAAM,KAAK,UAAU;AAAA,MACnB,QAAQ;AAAA,QACN,eAAe,KAAK,gBAAgB;AAAA,QACpC,eAAe,KAAK;AAAA,QACpB,GAAI,KAAK,QAAQ,EAAE,QAAQ,KAAK,MAAA,IAAU,CAAA;AAAA,MAAC;AAAA,IAC7C,CACD;AAAA,EAAA,CACF;AACD,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI,MAAM,wCAAwC,IAAI,MAAM,EAAE;AAAA,EACtE;AACA,SAAO,IAAI,KAAA;AACb;AAwBA,SAAS,mBAAmB,KAAuB;AACjD,MACE,OACA,OAAO,QAAQ,YACf,QAAQ,OACR,YAAY,OACX,IAAgC,SAAS,eAC1C;AACA,UAAM,SAAU,IAA4C;AAG5D,UAAM,wBAAwB,MAAM,QAAQ,OAAO,UAAU,IACzD,OAAO,WAAW,IAAI,CAAC,OAAgB;AACrC,UAAI,MAAM,OAAO,OAAO,YAAY,QAAQ,MAAM,YAAY,IAAI;AAChE,eAAQ,GAA2B;AAAA,MACrC;AACA,aAAO;AAAA,IACT,CAAC,IACD,OAAO;AAEX,WAAO,EAAE,GAAG,QAAQ,YAAY,sBAAA;AAAA,EAClC;AACA,SAAO;AACT;AAGA,SAAS,YAAY,MAAiD;AACpE,MAAI,KAAK,OAAO;AACd,WAAO;AAAA,EACT;AACA,MAAI,KAAK,QAAQ;AACf,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAGA,SAAS,qBAAqB,UAAqC;AACjE,SAAO,SAAS,KAAA,EAAO,MAAM,MAAM,EAAE;AACvC;AAQA,eAAsB,eACpB,YACA,MACA,UACA,OASI,CAAA,GAC0B;;AAC9B,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,WAAW,YAAY,IAAI;AACjC,QAAM,WAAW,GAAG,IAAI;AAExB,QAAM,UAAUD,kBAAAA,kBAAkB,KAAK,mBAAmB,yBAAyB;AAAA,IACjF,WAAW;AAAA,IACX,WAAW;AAAA,EAAA,CACZ;AAED,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,UAAU;AAAA,MAC1B,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,oBAAoB,GAAG,eAAe,IAAI,EAAA;AAAA,MACrE,QAAQ,KAAK,UAAU;AAAA,MACvB,MAAM,KAAK,UAAU;AAAA,QACnB,WAAW;AAAA,QACX,YAAY,KAAK,aAAa;AAAA,MAAA,CAC/B;AAAA,IAAA,CACF;AAAA,EACH,SAAS,OAAO;AACd,QAAI,aAAa,KAAK,GAAG;AACvB,cAAQ,2BAA2B;AAAA,QACjC,MAAM,EAAE,WAAW,UAAU,QAAQ,kBAAA;AAAA,MAAkB,CACxD;AAAA,IACH,OAAO;AACL,cAAQ,yBAAyB,EAAE,OAAO,MAAM,EAAE,WAAW,SAAA,GAAY;AAAA,IAC3E;AACA,UAAM;AAAA,EACR;AACA,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAO,MAAM,qBAAqB,GAAG;AAC3C,UAAM,QAAQ,IAAIC,sBAAe;AAAA,MAC/B,MAAM,IAAI,WAAW,OAAO,IAAI,WAAW,MAAM,kBAAkB;AAAA,MACnE,SAAS,+BAA+B,IAAI,MAAM,KAAK,QAAQ,IAC7D,OAAO,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC,KAAK,EACrC;AAAA,MACA,QAAQ,IAAI;AAAA,MACZ,MAAM;AAAA,MACN,SAAS,EAAE,WAAW,UAAU,WAAW,SAAA;AAAA,IAAS,CACrD;AACD,YAAQ,yBAAyB,EAAE,OAAO,MAAM,EAAE,WAAW,SAAA,GAAY;AACzE,UAAM;AAAA,EACR;AACA,QAAM,OAAQ,MAAM,IAAI,KAAA;AACxB,QAAM,mBAAkB,gBAAK,WAAL,mBAAa,mBAAb,mBAA6B;AACrD,UAAQ,wBAAwB;AAAA,IAC9B,MAAM;AAAA,MACJ,WAAW;AAAA,MACX,OAAO,KAAK,iBAAiB;AAAA,MAC7B,eAAe,MAAM,QAAQ,eAAe,IACxC,gBAAgB,WACf,gBAAK,WAAL,mBAAa,aAAb,mBAAuB,WAAU;AAAA,IAAA;AAAA,EACxC,CACD;AACD,QAAM,SAAS,KAAK;AAEpB,MAAI,KAAK,iBAAiB,SAAS,CAAC,QAAQ;AAC1C,WAAO;AAAA,MACL,WAAW;AAAA,MACX,UAAU,CAAA;AAAA,IAAC;AAAA,EAEf;AAEA,QAAM,gBAAgB,OAAO,kBAAkB,CAAA;AAC/C,QAAM,cAAc,MAAM,QAAQ,cAAc,QAAQ,IACpD,cAAc,WACd,MAAM,QAAQ,OAAO,QAAQ,IAC3B,OAAO,WACP,CAAA;AAEN,SAAO;AAAA,IACL,GAAG;AAAA,IACH,WAAW,OAAO,aAAa;AAAA,IAC/B,UAAU,YAAY,IAAI,kBAAkB;AAAA,IAC5C,GAAI,OAAO,QAAQ,EAAE,QAAQ,OAAO,MAAA,IAAU,CAAA;AAAA,EAAC;AAEnD;AASA,eAAsB,cACpB,YACA,MACA,UACe;AACf,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,MAAM,MAAM,MAAM,GAAG,IAAI,sCAAsC;AAAA,IACnE,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,oBAAoB,GAAG,eAAe,IAAI,EAAA;AAAA,IACrE,MAAM,KAAK,UAAU,EAAE,WAAW,UAAU;AAAA,EAAA,CAC7C;AACD,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,UAAU,IAAI,WAAW,OAAO,IAAI,WAAW;AACrD,UAAM,EAAE,cAAc,OAAA,IAAW;AAAA,MAC/B,IAAI;AAAA,MACJ,MAAM,qBAAqB,GAAG;AAAA,MAC9B;AAAA,IAAA;AAEF,UAAM,IAAIA,OAAAA,eAAe;AAAA,MACvB,MAAM,UAAU,kBAAkB;AAAA,MAClC,SAAS,6BAA6B,IAAI,MAAM;AAAA,MAChD,QAAQ,IAAI;AAAA,MACZ;AAAA,MACA,MAAM,UACF,8CACA,eACE,2EACA,IAAI,WAAW,MACb,iGACA;AAAA,MACR,SAAS,EAAE,WAAW,UAAU,WAAW,YAAY,IAAI,GAAG,eAAe,aAAA;AAAA,IAAa,CAC3F;AAAA,EACH;AACF;;;;;;;;;;;;;;"}
|
package/dist/threads/api.d.ts
CHANGED
|
@@ -86,6 +86,13 @@ export interface ThreadListResponse {
|
|
|
86
86
|
* `ThreadListFilterBody` fields are applied there).
|
|
87
87
|
*/
|
|
88
88
|
supported_filters?: string[];
|
|
89
|
+
/**
|
|
90
|
+
* Whether the page also holds the conversations with the `home_agent_id`
|
|
91
|
+
* agent: true only when the request named one, the agent has a home app set
|
|
92
|
+
* and the caller can open the agent. Servers that predate the field omit it,
|
|
93
|
+
* which reads as false.
|
|
94
|
+
*/
|
|
95
|
+
home_agent_applied?: boolean;
|
|
89
96
|
}
|
|
90
97
|
/**
|
|
91
98
|
* The server-side filters and order of `POST /api/conversations/threads/list`
|
|
@@ -99,6 +106,14 @@ export interface ThreadListFilterBody {
|
|
|
99
106
|
search?: string;
|
|
100
107
|
exclude_triggered?: boolean;
|
|
101
108
|
app_ids?: string[];
|
|
109
|
+
/**
|
|
110
|
+
* A collab agent (`asset_<uuid>`) whose home this list's app is. When the
|
|
111
|
+
* agent has a home app set and the caller can open the agent, the app scope
|
|
112
|
+
* (`app_id` / `app_ids`) widens to every conversation with the agent too,
|
|
113
|
+
* ANDed with the other filters as usual; `home_agent_applied` on the answer
|
|
114
|
+
* says whether it did.
|
|
115
|
+
*/
|
|
116
|
+
home_agent_id?: string;
|
|
102
117
|
start_channels?: string[];
|
|
103
118
|
created_after?: string;
|
|
104
119
|
created_before?: string;
|