@athenaintel/react 0.28.1 → 0.32.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 +479 -10
- package/dist/agent-runtime/src/asset-attachment.cjs.map +1 -0
- package/dist/agent-runtime/src/asset-attachment.js.map +1 -0
- package/dist/agent-runtime/src/athena-asset-drag.cjs +44 -0
- package/dist/agent-runtime/src/athena-asset-drag.cjs.map +1 -0
- package/dist/agent-runtime/src/athena-asset-drag.js +44 -0
- package/dist/agent-runtime/src/athena-asset-drag.js.map +1 -0
- package/dist/agent-runtime/src/auth-denial.cjs.map +1 -0
- package/dist/agent-runtime/src/auth-denial.js.map +1 -0
- package/dist/agent-runtime/src/client-tool-bridge.cjs.map +1 -0
- package/dist/agent-runtime/src/client-tool-bridge.js.map +1 -0
- package/dist/agent-runtime/src/client-tools.cjs.map +1 -0
- package/dist/agent-runtime/src/client-tools.js.map +1 -0
- package/dist/agent-runtime/src/composer-markdown.cjs +124 -0
- package/dist/agent-runtime/src/composer-markdown.cjs.map +1 -0
- package/dist/agent-runtime/src/composer-markdown.js +124 -0
- package/dist/agent-runtime/src/composer-markdown.js.map +1 -0
- package/dist/agent-runtime/src/config-mutations.cjs +59 -0
- package/dist/agent-runtime/src/config-mutations.cjs.map +1 -0
- package/dist/agent-runtime/src/config-mutations.js +59 -0
- package/dist/agent-runtime/src/config-mutations.js.map +1 -0
- package/dist/agent-runtime/src/conversation-index.cjs.map +1 -0
- package/dist/agent-runtime/src/conversation-index.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/conversation-list.cjs +36 -0
- package/dist/agent-runtime/src/conversation-list.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/conversation-list.js +36 -0
- package/dist/agent-runtime/src/conversation-list.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/deep-agent-transport-recipe.cjs +5 -3
- package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/deep-agent-transport-recipe.js +6 -4
- package/dist/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -0
- package/dist/agent-runtime/src/edit-command.cjs.map +1 -0
- package/dist/agent-runtime/src/edit-command.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/errors.cjs +23 -0
- package/dist/agent-runtime/src/errors.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/errors.js +23 -0
- package/dist/agent-runtime/src/errors.js.map +1 -0
- package/dist/agent-runtime/src/execute-output.cjs +41 -0
- package/dist/agent-runtime/src/execute-output.cjs.map +1 -0
- package/dist/agent-runtime/src/execute-output.js +41 -0
- package/dist/agent-runtime/src/execute-output.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/generated/runconfig-contract.cjs +16 -2
- package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/generated/runconfig-contract.js +16 -2
- package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -0
- package/dist/agent-runtime/src/github-wake-event.cjs.map +1 -0
- package/dist/agent-runtime/src/github-wake-event.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/interrupts.cjs +24 -1
- package/dist/agent-runtime/src/interrupts.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/interrupts.js +24 -1
- package/dist/agent-runtime/src/interrupts.js.map +1 -0
- package/dist/agent-runtime/src/message-author.cjs.map +1 -0
- package/dist/agent-runtime/src/message-author.js.map +1 -0
- package/dist/agent-runtime/src/message-window.cjs.map +1 -0
- package/dist/agent-runtime/src/message-window.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/messages.cjs +8 -4
- package/dist/agent-runtime/src/messages.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/messages.js +6 -2
- package/dist/agent-runtime/src/messages.js.map +1 -0
- package/dist/agent-runtime/src/model-context.cjs.map +1 -0
- package/dist/agent-runtime/src/model-context.js.map +1 -0
- package/dist/agent-runtime/src/optimistic-content.cjs.map +1 -0
- package/dist/agent-runtime/src/optimistic-content.js.map +1 -0
- package/dist/agent-runtime/src/protocol.cjs.map +1 -0
- package/dist/agent-runtime/src/protocol.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/queue.cjs +23 -2
- package/dist/agent-runtime/src/queue.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/queue.js +23 -2
- package/dist/agent-runtime/src/queue.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/quota-safe-local-storage-session.cjs +71 -13
- package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/quota-safe-local-storage-session.js +73 -15
- package/dist/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -0
- package/dist/agent-runtime/src/runtime-messages.cjs.map +1 -0
- package/dist/agent-runtime/src/runtime-messages.js.map +1 -0
- package/dist/agent-runtime/src/screen-point.cjs.map +1 -0
- package/dist/agent-runtime/src/screen-point.js.map +1 -0
- package/dist/agent-runtime/src/send-recovery.cjs.map +1 -0
- package/dist/agent-runtime/src/send-recovery.js.map +1 -0
- package/dist/agent-runtime/src/statewire-attach-observer.cjs.map +1 -0
- package/dist/agent-runtime/src/statewire-attach-observer.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/statewire-state.cjs +8 -0
- package/dist/agent-runtime/src/statewire-state.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/statewire-state.js +8 -0
- package/dist/agent-runtime/src/statewire-state.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/statewire-suspended.cjs +4 -0
- package/dist/agent-runtime/src/statewire-suspended.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/statewire-suspended.js +4 -0
- package/dist/agent-runtime/src/statewire-suspended.js.map +1 -0
- package/dist/agent-runtime/src/statewire-transport.cjs +43 -0
- package/dist/agent-runtime/src/statewire-transport.cjs.map +1 -0
- package/dist/agent-runtime/src/statewire-transport.js +43 -0
- package/dist/agent-runtime/src/statewire-transport.js.map +1 -0
- package/dist/agent-runtime/src/streaming-markdown.cjs.map +1 -0
- package/dist/agent-runtime/src/streaming-markdown.js.map +1 -0
- package/dist/agent-runtime/src/subscription-wake-event.cjs +252 -0
- package/dist/agent-runtime/src/subscription-wake-event.cjs.map +1 -0
- package/dist/agent-runtime/src/subscription-wake-event.js +252 -0
- package/dist/agent-runtime/src/subscription-wake-event.js.map +1 -0
- package/dist/agent-runtime/src/thread-extras.cjs.map +1 -0
- package/dist/agent-runtime/src/thread-extras.js.map +1 -0
- package/dist/agent-runtime/src/thread-snapshot-cache.cjs.map +1 -0
- package/dist/agent-runtime/src/thread-snapshot-cache.js.map +1 -0
- package/dist/agent-runtime/src/thread-status.cjs.map +1 -0
- package/dist/agent-runtime/src/thread-status.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/tool-metadata.cjs +304 -9
- package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/tool-metadata.js +304 -9
- package/dist/agent-runtime/src/tool-metadata.js.map +1 -0
- package/dist/agent-runtime/src/tool-names.cjs +5 -0
- package/dist/agent-runtime/src/tool-names.cjs.map +1 -0
- package/dist/agent-runtime/src/tool-names.js +5 -0
- package/dist/agent-runtime/src/tool-names.js.map +1 -0
- package/dist/agent-runtime/src/tool-outputs.cjs.map +1 -0
- package/dist/agent-runtime/src/tool-outputs.js.map +1 -0
- package/dist/agent-runtime/src/tool-result.cjs.map +1 -0
- package/dist/agent-runtime/src/tool-result.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/use-conversation-list.cjs +33 -22
- package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/use-conversation-list.js +34 -23
- package/dist/agent-runtime/src/use-conversation-list.js.map +1 -0
- package/dist/agent-runtime/src/use-deep-agent-config.cjs +129 -0
- package/dist/agent-runtime/src/use-deep-agent-config.cjs.map +1 -0
- package/dist/agent-runtime/src/use-deep-agent-config.js +129 -0
- package/dist/agent-runtime/src/use-deep-agent-config.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-edit-submit.cjs +2 -0
- package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-edit-submit.js +2 -0
- package/dist/agent-runtime/src/use-deep-agent-edit-submit.js.map +1 -0
- package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -0
- package/dist/agent-runtime/src/use-deep-agent-runtime.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-thread.cjs +1 -0
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-thread.js +2 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -0
- package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -0
- package/dist/agent-runtime/src/use-deep-agent-window-sync.js.map +1 -0
- package/dist/agent-runtime/src/use-historical-edit-attachments.cjs +52 -0
- package/dist/agent-runtime/src/use-historical-edit-attachments.cjs.map +1 -0
- package/dist/agent-runtime/src/use-historical-edit-attachments.js +52 -0
- package/dist/agent-runtime/src/use-historical-edit-attachments.js.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/voice-presentation.cjs +14 -0
- package/dist/agent-runtime/src/voice-presentation.cjs.map +1 -0
- package/dist/{packages/agent-runtime → agent-runtime}/src/voice-presentation.js +14 -0
- package/dist/agent-runtime/src/voice-presentation.js.map +1 -0
- package/dist/agent-runtime/src/voice-turn-grouping.cjs.map +1 -0
- package/dist/agent-runtime/src/voice-turn-grouping.js.map +1 -0
- package/dist/assets/AthenaAssetEmbed.cjs +13 -2
- package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
- package/dist/assets/AthenaAssetEmbed.d.ts +10 -0
- package/dist/assets/AthenaAssetEmbed.js +14 -3
- package/dist/assets/AthenaAssetEmbed.js.map +1 -1
- package/dist/assets/AthenaLayout.cjs +97 -31
- package/dist/assets/AthenaLayout.cjs.map +1 -1
- package/dist/assets/AthenaLayout.d.ts +13 -0
- package/dist/assets/AthenaLayout.js +98 -32
- package/dist/assets/AthenaLayout.js.map +1 -1
- package/dist/assets/asset-embed-messages.cjs +6 -0
- package/dist/assets/asset-embed-messages.cjs.map +1 -1
- package/dist/assets/asset-embed-messages.d.ts +13 -0
- package/dist/assets/asset-embed-messages.js +6 -0
- package/dist/assets/asset-embed-messages.js.map +1 -1
- package/dist/assets/asset-panel-store.cjs +68 -32
- package/dist/assets/asset-panel-store.cjs.map +1 -1
- package/dist/assets/asset-panel-store.d.ts +47 -1
- package/dist/assets/asset-panel-store.js +68 -32
- package/dist/assets/asset-panel-store.js.map +1 -1
- package/dist/assets/use-asset-embed.cjs +29 -8
- package/dist/assets/use-asset-embed.cjs.map +1 -1
- package/dist/assets/use-asset-embed.d.ts +7 -0
- package/dist/assets/use-asset-embed.js +29 -8
- package/dist/assets/use-asset-embed.js.map +1 -1
- package/dist/catalog/chat-pickers.cjs +152 -0
- package/dist/catalog/chat-pickers.cjs.map +1 -0
- package/dist/catalog/chat-pickers.d.ts +22 -0
- package/dist/catalog/chat-pickers.js +152 -0
- package/dist/catalog/chat-pickers.js.map +1 -0
- package/dist/catalog/runtime-catalog.cjs +181 -0
- package/dist/catalog/runtime-catalog.cjs.map +1 -0
- package/dist/catalog/runtime-catalog.d.ts +100 -0
- package/dist/catalog/runtime-catalog.js +181 -0
- package/dist/catalog/runtime-catalog.js.map +1 -0
- package/dist/chat/AthenaChat.cjs +122 -67
- package/dist/chat/AthenaChat.cjs.map +1 -1
- package/dist/chat/AthenaChat.d.ts +21 -4
- package/dist/chat/AthenaChat.js +124 -69
- package/dist/chat/AthenaChat.js.map +1 -1
- package/dist/chat/StatewireApprovalCard.cjs +38 -37
- package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
- package/dist/chat/StatewireApprovalCard.d.ts +2 -0
- package/dist/chat/StatewireApprovalCard.js +39 -38
- package/dist/chat/StatewireApprovalCard.js.map +1 -1
- package/dist/chat/StatewireClientToolBridge.cjs +2 -2
- package/dist/chat/StatewireClientToolBridge.js +2 -2
- package/dist/chat/StatewireQueuedMessages.cjs +15 -12
- package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
- package/dist/chat/StatewireQueuedMessages.d.ts +22 -2
- package/dist/chat/StatewireQueuedMessages.js +15 -12
- package/dist/chat/StatewireQueuedMessages.js.map +1 -1
- package/dist/chat/StatewireRunRefusalNotice.cjs +48 -0
- package/dist/chat/StatewireRunRefusalNotice.cjs.map +1 -0
- package/dist/chat/StatewireRunRefusalNotice.d.ts +25 -0
- package/dist/chat/StatewireRunRefusalNotice.js +48 -0
- package/dist/chat/StatewireRunRefusalNotice.js.map +1 -0
- package/dist/chat/WaitingOnYouBanner.cjs +2 -2
- package/dist/chat/WaitingOnYouBanner.js +2 -2
- package/dist/chat/athena-citation-links.cjs +19 -15
- package/dist/chat/athena-citation-links.cjs.map +1 -1
- package/dist/chat/athena-citation-links.js +19 -15
- package/dist/chat/athena-citation-links.js.map +1 -1
- package/dist/chat/run-activity.cjs +9 -1
- package/dist/chat/run-activity.cjs.map +1 -1
- package/dist/chat/run-activity.d.ts +6 -0
- package/dist/chat/run-activity.js +10 -2
- package/dist/chat/run-activity.js.map +1 -1
- package/dist/chat/statewire-banners.cjs +30 -1
- package/dist/chat/statewire-banners.cjs.map +1 -1
- package/dist/chat/statewire-banners.d.ts +20 -1
- package/dist/chat/statewire-banners.js +32 -3
- package/dist/chat/statewire-banners.js.map +1 -1
- package/dist/chat/statewire-client-tools.cjs +1 -1
- package/dist/chat/statewire-client-tools.js +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.cjs +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.cjs.map +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.js +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.js.map +1 -1
- package/dist/chat/super-grouping/SuperGroupingCard.cjs +38 -16
- package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
- package/dist/chat/super-grouping/SuperGroupingCard.d.ts +21 -4
- package/dist/chat/super-grouping/SuperGroupingCard.js +39 -17
- package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
- package/dist/chat/super-grouping/SuperGroupingTranscript.cjs +377 -0
- package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -0
- package/dist/chat/super-grouping/SuperGroupingTranscript.d.ts +31 -0
- package/dist/chat/super-grouping/SuperGroupingTranscript.js +377 -0
- package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -0
- package/dist/chat/super-grouping/ToolTimeline.cjs +13 -2
- package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
- package/dist/chat/super-grouping/ToolTimeline.d.ts +10 -3
- package/dist/chat/super-grouping/ToolTimeline.js +13 -2
- package/dist/chat/super-grouping/ToolTimeline.js.map +1 -1
- package/dist/chat/super-grouping/activity-timeline.cjs +69 -29
- package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
- package/dist/chat/super-grouping/activity-timeline.d.ts +60 -9
- package/dist/chat/super-grouping/activity-timeline.js +70 -30
- package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
- package/dist/chat/super-grouping/index.cjs +14 -0
- package/dist/chat/super-grouping/index.cjs.map +1 -1
- package/dist/chat/super-grouping/index.d.ts +7 -2
- package/dist/chat/super-grouping/index.js +16 -2
- package/dist/chat/super-grouping/index.js.map +1 -1
- package/dist/chat/super-grouping/timeline-step.cjs +14 -5
- package/dist/chat/super-grouping/timeline-step.cjs.map +1 -1
- package/dist/chat/super-grouping/timeline-step.d.ts +10 -1
- package/dist/chat/super-grouping/timeline-step.js +15 -6
- package/dist/chat/super-grouping/timeline-step.js.map +1 -1
- package/dist/chat/super-grouping/toolkit-map.cjs +1 -0
- package/dist/chat/super-grouping/toolkit-map.cjs.map +1 -1
- package/dist/chat/super-grouping/toolkit-map.js +1 -0
- package/dist/chat/super-grouping/toolkit-map.js.map +1 -1
- package/dist/chat/super-grouping/turn-segments.cjs +82 -0
- package/dist/chat/super-grouping/turn-segments.cjs.map +1 -0
- package/dist/chat/super-grouping/turn-segments.d.ts +69 -0
- package/dist/chat/super-grouping/turn-segments.js +82 -0
- package/dist/chat/super-grouping/turn-segments.js.map +1 -0
- package/dist/chat/super-grouping/turn-timing.cjs +110 -0
- package/dist/chat/super-grouping/turn-timing.cjs.map +1 -0
- package/dist/chat/super-grouping/turn-timing.d.ts +52 -0
- package/dist/chat/super-grouping/turn-timing.js +110 -0
- package/dist/chat/super-grouping/turn-timing.js.map +1 -0
- package/dist/chat/tiptap-text.cjs +1 -1
- package/dist/chat/tiptap-text.js +1 -1
- package/dist/chat/use-athena-run-live.cjs +1 -1
- package/dist/chat/use-athena-run-live.js +1 -1
- package/dist/chat/use-statewire-approval-request.cjs +73 -4
- package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
- package/dist/chat/use-statewire-approval-request.js +74 -5
- package/dist/chat/use-statewire-approval-request.js.map +1 -1
- package/dist/chat-ui/composer/composer-message.cjs +284 -0
- package/dist/chat-ui/composer/composer-message.cjs.map +1 -0
- package/dist/chat-ui/composer/composer-message.d.ts +152 -0
- package/dist/chat-ui/composer/composer-message.js +284 -0
- package/dist/chat-ui/composer/composer-message.js.map +1 -0
- package/dist/chat-ui/composer/tiptap-composer.cjs +97 -15
- package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
- package/dist/chat-ui/composer/tiptap-composer.d.ts +34 -6
- package/dist/chat-ui/composer/tiptap-composer.js +97 -15
- package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
- package/dist/chat-ui/index.cjs +4 -1
- package/dist/chat-ui/index.cjs.map +1 -1
- package/dist/chat-ui/index.d.ts +3 -2
- package/dist/chat-ui/index.js +5 -2
- package/dist/chat-ui/index.js.map +1 -1
- package/dist/chat-ui/mentions/mention-chip.cjs +31 -3
- package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
- package/dist/chat-ui/mentions/mention-chip.d.ts +2 -5
- package/dist/chat-ui/mentions/mention-chip.js +33 -5
- package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
- package/dist/chat-ui/mentions/mention-extension.cjs +9 -3
- package/dist/chat-ui/mentions/mention-extension.cjs.map +1 -1
- package/dist/chat-ui/mentions/mention-extension.js +9 -3
- package/dist/chat-ui/mentions/mention-extension.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs +3 -1
- package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.js +3 -1
- package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +65 -19
- package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/sources/index.d.ts +15 -0
- package/dist/chat-ui/mentions/suggestions/data/sources/index.js +67 -21
- package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs +4 -2
- 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 +2 -1
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js +5 -3
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js.map +1 -1
- package/dist/chat-ui/mentions/use-account-workspace-id.cjs +61 -0
- package/dist/chat-ui/mentions/use-account-workspace-id.cjs.map +1 -0
- package/dist/chat-ui/mentions/use-account-workspace-id.d.ts +3 -0
- package/dist/chat-ui/mentions/use-account-workspace-id.js +61 -0
- package/dist/chat-ui/mentions/use-account-workspace-id.js.map +1 -0
- package/dist/chat-ui/mentions/use-member-avatar.cjs +75 -0
- package/dist/chat-ui/mentions/use-member-avatar.cjs.map +1 -0
- package/dist/chat-ui/mentions/use-member-avatar.d.ts +2 -0
- package/dist/chat-ui/mentions/use-member-avatar.js +75 -0
- package/dist/chat-ui/mentions/use-member-avatar.js.map +1 -0
- package/dist/chat-ui/messages/message-components.cjs +30 -10
- package/dist/chat-ui/messages/message-components.cjs.map +1 -1
- package/dist/chat-ui/messages/message-components.d.ts +21 -1
- package/dist/chat-ui/messages/message-components.js +30 -10
- package/dist/chat-ui/messages/message-components.js.map +1 -1
- package/dist/chat-ui/messages/runtime-message.cjs +1 -1
- package/dist/chat-ui/messages/runtime-message.js +1 -1
- package/dist/chat-ui/messages/statewire-continue-run.cjs +5 -5
- package/dist/chat-ui/messages/statewire-continue-run.js +5 -5
- package/dist/chat-ui/messages/user-edit-composer.cjs +1 -1
- package/dist/chat-ui/messages/user-edit-composer.js +1 -1
- package/dist/chat-ui/messages/wake-marker.cjs +39 -4
- package/dist/chat-ui/messages/wake-marker.cjs.map +1 -1
- package/dist/chat-ui/messages/wake-marker.d.ts +16 -5
- package/dist/chat-ui/messages/wake-marker.js +40 -5
- package/dist/chat-ui/messages/wake-marker.js.map +1 -1
- package/dist/chat-ui/rich-text/chat-message-body.cjs +12 -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 +6 -1
- package/dist/chat-ui/rich-text/chat-message-body.js +13 -9
- package/dist/chat-ui/rich-text/chat-message-body.js.map +1 -1
- package/dist/chat-ui/rich-text/chat-text-schema.cjs +64 -6
- package/dist/chat-ui/rich-text/chat-text-schema.cjs.map +1 -1
- package/dist/chat-ui/rich-text/chat-text-schema.d.ts +5 -0
- package/dist/chat-ui/rich-text/chat-text-schema.js +66 -8
- package/dist/chat-ui/rich-text/chat-text-schema.js.map +1 -1
- package/dist/chat-ui/statewire.cjs +1 -1
- package/dist/chat-ui/statewire.d.ts +1 -1
- package/dist/chat-ui/statewire.js +1 -1
- package/dist/chat-ui/thread/statewire-history-edge.cjs +2 -2
- package/dist/chat-ui/thread/statewire-history-edge.js +2 -2
- package/dist/collab/client.cjs +282 -16
- package/dist/collab/client.cjs.map +1 -1
- package/dist/collab/client.d.ts +127 -2
- package/dist/collab/client.js +285 -20
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/index.cjs +2 -0
- package/dist/collab/index.cjs.map +1 -1
- package/dist/collab/index.d.ts +1 -1
- package/dist/collab/index.js +3 -1
- package/dist/composer/AttachmentContext.cjs +38 -12
- package/dist/composer/AttachmentContext.cjs.map +1 -1
- package/dist/composer/AttachmentContext.d.ts +22 -1
- package/dist/composer/AttachmentContext.js +40 -14
- package/dist/composer/AttachmentContext.js.map +1 -1
- package/dist/composer/QuoteContext.cjs +80 -28
- package/dist/composer/QuoteContext.cjs.map +1 -1
- package/dist/composer/QuoteContext.d.ts +35 -6
- package/dist/composer/QuoteContext.js +82 -30
- package/dist/composer/QuoteContext.js.map +1 -1
- package/dist/composer/build-composed-message.cjs +27 -0
- package/dist/composer/build-composed-message.cjs.map +1 -1
- package/dist/composer/build-composed-message.d.ts +21 -0
- package/dist/composer/build-composed-message.js +28 -1
- package/dist/composer/build-composed-message.js.map +1 -1
- package/dist/composer/composer-handoff.cjs +13 -1
- package/dist/composer/composer-handoff.cjs.map +1 -1
- package/dist/composer/composer-handoff.d.ts +12 -0
- package/dist/composer/composer-handoff.js +15 -3
- package/dist/composer/composer-handoff.js.map +1 -1
- package/dist/composer/index.d.ts +6 -3
- package/dist/composer/useReadComposerDraft.cjs +16 -0
- package/dist/composer/useReadComposerDraft.cjs.map +1 -0
- package/dist/composer/useReadComposerDraft.d.ts +6 -0
- package/dist/composer/useReadComposerDraft.js +16 -0
- package/dist/composer/useReadComposerDraft.js.map +1 -0
- package/dist/diagnostics/athena-diagnostics.cjs.map +1 -1
- package/dist/diagnostics/athena-diagnostics.d.ts +3 -1
- package/dist/diagnostics/athena-diagnostics.js.map +1 -1
- package/dist/diagnostics/errors.cjs +6 -0
- package/dist/diagnostics/errors.cjs.map +1 -1
- package/dist/diagnostics/errors.d.ts +6 -0
- package/dist/diagnostics/errors.js +6 -0
- package/dist/diagnostics/errors.js.map +1 -1
- package/dist/index.cjs +163 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +55 -12
- package/dist/index.js +170 -14
- package/dist/index.js.map +1 -1
- package/dist/lib/owner-document.cjs +32 -0
- package/dist/lib/owner-document.cjs.map +1 -0
- package/dist/lib/owner-document.d.ts +17 -0
- package/dist/lib/owner-document.js +32 -0
- package/dist/lib/owner-document.js.map +1 -0
- package/dist/lib/portal-surface.cjs +55 -0
- package/dist/lib/portal-surface.cjs.map +1 -0
- package/dist/lib/portal-surface.d.ts +37 -0
- package/dist/lib/portal-surface.js +55 -0
- package/dist/lib/portal-surface.js.map +1 -0
- package/dist/lib/use-athena-rest-query.cjs +34 -0
- package/dist/lib/use-athena-rest-query.cjs.map +1 -0
- package/dist/lib/use-athena-rest-query.d.ts +31 -0
- package/dist/lib/use-athena-rest-query.js +34 -0
- package/dist/lib/use-athena-rest-query.js.map +1 -0
- package/dist/provider/AthenaProvider.cjs +70 -10
- package/dist/provider/AthenaProvider.cjs.map +1 -1
- package/dist/provider/AthenaProvider.d.ts +27 -2
- package/dist/provider/AthenaProvider.js +74 -14
- package/dist/provider/AthenaProvider.js.map +1 -1
- package/dist/provider/citation-links.d.ts +10 -2
- package/dist/{packages/react → react}/package.json.cjs +1 -1
- package/dist/{packages/react → react}/package.json.js +1 -1
- package/dist/runtime/StatewireModelLaneSync.cjs +96 -0
- package/dist/runtime/StatewireModelLaneSync.cjs.map +1 -0
- package/dist/runtime/StatewireModelLaneSync.d.ts +45 -0
- package/dist/runtime/StatewireModelLaneSync.js +96 -0
- package/dist/runtime/StatewireModelLaneSync.js.map +1 -0
- package/dist/runtime/statewire-lifecycle.cjs +20 -5
- package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
- package/dist/runtime/statewire-lifecycle.d.ts +11 -0
- package/dist/runtime/statewire-lifecycle.js +20 -5
- package/dist/runtime/statewire-lifecycle.js.map +1 -1
- package/dist/runtime/statewire-model-lane.cjs +28 -0
- package/dist/runtime/statewire-model-lane.cjs.map +1 -0
- package/dist/runtime/statewire-model-lane.d.ts +64 -0
- package/dist/runtime/statewire-model-lane.js +28 -0
- package/dist/runtime/statewire-model-lane.js.map +1 -0
- package/dist/runtime/statewire-run-config.cjs +16 -2
- package/dist/runtime/statewire-run-config.cjs.map +1 -1
- package/dist/runtime/statewire-run-config.d.ts +10 -0
- package/dist/runtime/statewire-run-config.js +16 -2
- package/dist/runtime/statewire-run-config.js.map +1 -1
- package/dist/runtime/statewire-server-lane-context.cjs +24 -0
- package/dist/runtime/statewire-server-lane-context.cjs.map +1 -0
- package/dist/runtime/statewire-server-lane-context.d.ts +30 -0
- package/dist/runtime/statewire-server-lane-context.js +24 -0
- package/dist/runtime/statewire-server-lane-context.js.map +1 -0
- package/dist/runtime/useAthenaStatewireRuntime.cjs +47 -23
- package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.d.ts +8 -1
- package/dist/runtime/useAthenaStatewireRuntime.js +48 -24
- package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
- package/dist/search/useAthenaRepoSearch.cjs +5 -13
- package/dist/search/useAthenaRepoSearch.cjs.map +1 -1
- package/dist/search/useAthenaRepoSearch.d.ts +3 -3
- package/dist/search/useAthenaRepoSearch.js +6 -14
- package/dist/search/useAthenaRepoSearch.js.map +1 -1
- package/dist/sheet-range/a1.cjs +162 -0
- package/dist/sheet-range/a1.cjs.map +1 -0
- package/dist/sheet-range/a1.d.ts +91 -0
- package/dist/sheet-range/a1.js +162 -0
- package/dist/sheet-range/a1.js.map +1 -0
- package/dist/sheet-range/index.cjs +22 -0
- package/dist/sheet-range/index.cjs.map +1 -0
- package/dist/sheet-range/index.d.ts +12 -0
- package/dist/sheet-range/index.js +22 -0
- package/dist/sheet-range/index.js.map +1 -0
- package/dist/sheet-range/range-preview-table.cjs +75 -0
- package/dist/sheet-range/range-preview-table.cjs.map +1 -0
- package/dist/sheet-range/range-preview-table.d.ts +20 -0
- package/dist/sheet-range/range-preview-table.js +75 -0
- package/dist/sheet-range/range-preview-table.js.map +1 -0
- package/dist/sheet-range/range-preview.cjs +116 -0
- package/dist/sheet-range/range-preview.cjs.map +1 -0
- package/dist/sheet-range/range-preview.d.ts +67 -0
- package/dist/sheet-range/range-preview.js +116 -0
- package/dist/sheet-range/range-preview.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/threads/Inbox.cjs +289 -0
- package/dist/threads/Inbox.cjs.map +1 -0
- package/dist/threads/Inbox.d.ts +46 -0
- package/dist/threads/Inbox.js +289 -0
- package/dist/threads/Inbox.js.map +1 -0
- package/dist/threads/SessionList.cjs +51 -126
- package/dist/threads/SessionList.cjs.map +1 -1
- package/dist/threads/SessionList.d.ts +26 -1
- package/dist/threads/SessionList.js +45 -120
- package/dist/threads/SessionList.js.map +1 -1
- package/dist/threads/SessionsPage.cjs +753 -0
- package/dist/threads/SessionsPage.cjs.map +1 -0
- package/dist/threads/SessionsPage.d.ts +35 -0
- package/dist/threads/SessionsPage.js +753 -0
- package/dist/threads/SessionsPage.js.map +1 -0
- package/dist/threads/api.cjs +23 -2
- package/dist/threads/api.cjs.map +1 -1
- package/dist/threads/api.d.ts +60 -0
- package/dist/threads/api.js +23 -2
- package/dist/threads/api.js.map +1 -1
- package/dist/threads/conversation-list-fetcher.cjs +9 -2
- package/dist/threads/conversation-list-fetcher.cjs.map +1 -1
- package/dist/threads/conversation-list-fetcher.d.ts +14 -1
- package/dist/threads/conversation-list-fetcher.js +9 -2
- package/dist/threads/conversation-list-fetcher.js.map +1 -1
- package/dist/threads/index.d.ts +2 -1
- package/dist/threads/pull-request-display.cjs +25 -0
- package/dist/threads/pull-request-display.cjs.map +1 -0
- package/dist/threads/pull-request-display.d.ts +15 -0
- package/dist/threads/pull-request-display.js +25 -0
- package/dist/threads/pull-request-display.js.map +1 -0
- package/dist/threads/session-list-model.cjs +16 -2
- package/dist/threads/session-list-model.cjs.map +1 -1
- package/dist/threads/session-list-model.d.ts +10 -0
- package/dist/threads/session-list-model.js +16 -2
- package/dist/threads/session-list-model.js.map +1 -1
- package/dist/threads/session-row-parts.cjs +152 -0
- package/dist/threads/session-row-parts.cjs.map +1 -0
- package/dist/threads/session-row-parts.d.ts +50 -0
- package/dist/threads/session-row-parts.js +152 -0
- package/dist/threads/session-row-parts.js.map +1 -0
- package/dist/threads/sessions-page-model.cjs +305 -0
- package/dist/threads/sessions-page-model.cjs.map +1 -0
- package/dist/threads/sessions-page-model.d.ts +86 -0
- package/dist/threads/sessions-page-model.js +305 -0
- package/dist/threads/sessions-page-model.js.map +1 -0
- package/dist/threads/sessions-page-storage.cjs +93 -0
- package/dist/threads/sessions-page-storage.cjs.map +1 -0
- package/dist/threads/sessions-page-storage.d.ts +23 -0
- package/dist/threads/sessions-page-storage.js +93 -0
- package/dist/threads/sessions-page-storage.js.map +1 -0
- package/dist/threads/sessions-query.cjs +235 -0
- package/dist/threads/sessions-query.cjs.map +1 -0
- package/dist/threads/sessions-query.d.ts +119 -0
- package/dist/threads/sessions-query.js +235 -0
- package/dist/threads/sessions-query.js.map +1 -0
- package/dist/threads/statewire-thread-list.cjs +133 -40
- package/dist/threads/statewire-thread-list.cjs.map +1 -1
- package/dist/threads/statewire-thread-list.d.ts +83 -2
- package/dist/threads/statewire-thread-list.js +134 -41
- package/dist/threads/statewire-thread-list.js.map +1 -1
- package/dist/threads/use-athena-sessions.cjs +198 -0
- package/dist/threads/use-athena-sessions.cjs.map +1 -0
- package/dist/threads/use-athena-sessions.d.ts +81 -0
- package/dist/threads/use-athena-sessions.js +198 -0
- package/dist/threads/use-athena-sessions.js.map +1 -0
- package/dist/threads/use-athena-thread-model.cjs +14 -0
- package/dist/threads/use-athena-thread-model.cjs.map +1 -0
- package/dist/threads/use-athena-thread-model.d.ts +22 -0
- package/dist/threads/use-athena-thread-model.js +14 -0
- package/dist/threads/use-athena-thread-model.js.map +1 -0
- package/dist/threads/use-rest-conversation-history.cjs +1 -1
- package/dist/threads/use-rest-conversation-history.js +1 -1
- package/dist/threads/use-statewire-conversation-history.cjs +1 -1
- package/dist/threads/use-statewire-conversation-history.d.ts +3 -0
- package/dist/threads/use-statewire-conversation-history.js +1 -1
- package/dist/threads/use-thread-read-state.cjs +73 -0
- package/dist/threads/use-thread-read-state.cjs.map +1 -0
- package/dist/threads/use-thread-read-state.d.ts +51 -0
- package/dist/threads/use-thread-read-state.js +73 -0
- package/dist/threads/use-thread-read-state.js.map +1 -0
- package/dist/tiptap-markdown-table/src/markdown-table-serializer.cjs.map +1 -0
- package/dist/tiptap-markdown-table/src/markdown-table-serializer.js.map +1 -0
- package/dist/tools/auto-open-tools.cjs +2 -0
- package/dist/tools/auto-open-tools.cjs.map +1 -1
- package/dist/tools/auto-open-tools.js +2 -0
- package/dist/tools/auto-open-tools.js.map +1 -1
- package/dist/tools/file-tool-uis.cjs +18 -43
- package/dist/tools/file-tool-uis.cjs.map +1 -1
- package/dist/tools/file-tool-uis.d.ts +1 -2
- package/dist/tools/file-tool-uis.js +18 -42
- package/dist/tools/file-tool-uis.js.map +1 -1
- package/dist/tools/index.cjs +6 -2
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +6 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/misc-tool-uis.cjs +2 -2
- package/dist/tools/misc-tool-uis.js +2 -2
- package/dist/tools/primitives.cjs +1 -1
- package/dist/tools/primitives.js +1 -1
- package/dist/tools/read-asset-tool-ui.cjs +21 -70
- package/dist/tools/read-asset-tool-ui.cjs.map +1 -1
- package/dist/tools/read-asset-tool-ui.js +21 -70
- package/dist/tools/read-asset-tool-ui.js.map +1 -1
- package/dist/tools/step-text.cjs +21 -0
- package/dist/tools/step-text.cjs.map +1 -0
- package/dist/tools/step-text.d.ts +10 -0
- package/dist/tools/step-text.js +21 -0
- package/dist/tools/step-text.js.map +1 -0
- package/dist/tools/tool-fallback.cjs +24 -5
- package/dist/tools/tool-fallback.cjs.map +1 -1
- package/dist/tools/tool-fallback.d.ts +3 -1
- package/dist/tools/tool-fallback.js +24 -5
- package/dist/tools/tool-fallback.js.map +1 -1
- package/dist/tools/tool-summary.cjs +661 -0
- package/dist/tools/tool-summary.cjs.map +1 -0
- package/dist/tools/tool-summary.d.ts +99 -0
- package/dist/tools/tool-summary.js +661 -0
- package/dist/tools/tool-summary.js.map +1 -0
- package/dist/tools/tool-uis.cjs +37 -95
- package/dist/tools/tool-uis.cjs.map +1 -1
- package/dist/tools/tool-uis.js +37 -95
- package/dist/tools/tool-uis.js.map +1 -1
- package/dist/tools/voice-update-tool-ui.cjs +1 -1
- package/dist/tools/voice-update-tool-ui.js +1 -1
- package/dist/tools/write-todos-tool-ui.cjs +3 -2
- package/dist/tools/write-todos-tool-ui.cjs.map +1 -1
- package/dist/tools/write-todos-tool-ui.d.ts +5 -0
- package/dist/tools/write-todos-tool-ui.js +5 -4
- package/dist/tools/write-todos-tool-ui.js.map +1 -1
- package/dist/ui/popover.cjs +6 -6
- package/dist/ui/popover.cjs.map +1 -1
- package/dist/ui/popover.js +6 -6
- package/dist/ui/popover.js.map +1 -1
- package/dist/ui/tooltip.cjs +16 -2
- package/dist/ui/tooltip.cjs.map +1 -1
- package/dist/ui/tooltip.d.ts +1 -1
- package/dist/ui/tooltip.js +16 -2
- package/dist/ui/tooltip.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/dist/voice/use-athena-voice-session.cjs.map +1 -1
- package/dist/voice/use-athena-voice-session.d.ts +3 -3
- package/dist/voice/use-athena-voice-session.js.map +1 -1
- package/dist/workbench/SessionWorkbench.cjs +378 -0
- package/dist/workbench/SessionWorkbench.cjs.map +1 -0
- package/dist/workbench/SessionWorkbench.d.ts +30 -0
- package/dist/workbench/SessionWorkbench.js +378 -0
- package/dist/workbench/SessionWorkbench.js.map +1 -0
- package/dist/workbench/session-workbench-context.cjs +26 -0
- package/dist/workbench/session-workbench-context.cjs.map +1 -0
- package/dist/workbench/session-workbench-context.d.ts +55 -0
- package/dist/workbench/session-workbench-context.js +26 -0
- package/dist/workbench/session-workbench-context.js.map +1 -0
- package/dist/workbench/session-workbench-model.cjs +288 -0
- package/dist/workbench/session-workbench-model.cjs.map +1 -0
- package/dist/workbench/session-workbench-model.d.ts +168 -0
- package/dist/workbench/session-workbench-model.js +288 -0
- package/dist/workbench/session-workbench-model.js.map +1 -0
- package/dist/workbench/session-workbench-panes.cjs +580 -0
- package/dist/workbench/session-workbench-panes.cjs.map +1 -0
- package/dist/workbench/session-workbench-panes.d.ts +16 -0
- package/dist/workbench/session-workbench-panes.js +580 -0
- package/dist/workbench/session-workbench-panes.js.map +1 -0
- package/dist/workbench/session-workspace-api.cjs +157 -0
- package/dist/workbench/session-workspace-api.cjs.map +1 -0
- package/dist/workbench/session-workspace-api.d.ts +70 -0
- package/dist/workbench/session-workspace-api.js +157 -0
- package/dist/workbench/session-workspace-api.js.map +1 -0
- package/dist/workbench/use-session-workspace.cjs +100 -0
- package/dist/workbench/use-session-workspace.cjs.map +1 -0
- package/dist/workbench/use-session-workspace.d.ts +45 -0
- package/dist/workbench/use-session-workspace.js +100 -0
- package/dist/workbench/use-session-workspace.js.map +1 -0
- package/dist/workbench/workbench-layout-context.cjs +10 -0
- package/dist/workbench/workbench-layout-context.cjs.map +1 -0
- package/dist/workbench/workbench-layout-context.d.ts +17 -0
- package/dist/workbench/workbench-layout-context.js +10 -0
- package/dist/workbench/workbench-layout-context.js.map +1 -0
- package/package.json +21 -10
- package/dist/node_modules/@assistant-ui/react-langchain/dist/converter.cjs +0 -77
- package/dist/node_modules/@assistant-ui/react-langchain/dist/converter.cjs.map +0 -1
- package/dist/node_modules/@assistant-ui/react-langchain/dist/converter.js +0 -77
- package/dist/node_modules/@assistant-ui/react-langchain/dist/converter.js.map +0 -1
- package/dist/node_modules/@assistant-ui/react-langgraph/dist/convertLangChainMessages.cjs +0 -181
- package/dist/node_modules/@assistant-ui/react-langgraph/dist/convertLangChainMessages.cjs.map +0 -1
- package/dist/node_modules/@assistant-ui/react-langgraph/dist/convertLangChainMessages.js +0 -181
- package/dist/node_modules/@assistant-ui/react-langgraph/dist/convertLangChainMessages.js.map +0 -1
- package/dist/packages/agent-runtime/src/asset-attachment.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/asset-attachment.js.map +0 -1
- package/dist/packages/agent-runtime/src/auth-denial.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/auth-denial.js.map +0 -1
- package/dist/packages/agent-runtime/src/client-tool-bridge.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/client-tool-bridge.js.map +0 -1
- package/dist/packages/agent-runtime/src/client-tools.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/client-tools.js.map +0 -1
- package/dist/packages/agent-runtime/src/conversation-index.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/conversation-index.js.map +0 -1
- package/dist/packages/agent-runtime/src/conversation-list.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/conversation-list.js.map +0 -1
- package/dist/packages/agent-runtime/src/deep-agent-transport-recipe.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/deep-agent-transport-recipe.js.map +0 -1
- package/dist/packages/agent-runtime/src/edit-command.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/edit-command.js.map +0 -1
- package/dist/packages/agent-runtime/src/errors.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/errors.js.map +0 -1
- package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/generated/runconfig-contract.js.map +0 -1
- package/dist/packages/agent-runtime/src/github-wake-event.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/github-wake-event.js.map +0 -1
- package/dist/packages/agent-runtime/src/interrupts.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/interrupts.js.map +0 -1
- package/dist/packages/agent-runtime/src/message-author.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/message-author.js.map +0 -1
- package/dist/packages/agent-runtime/src/message-window.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/message-window.js.map +0 -1
- package/dist/packages/agent-runtime/src/messages.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/messages.js.map +0 -1
- package/dist/packages/agent-runtime/src/model-context.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/model-context.js.map +0 -1
- package/dist/packages/agent-runtime/src/optimistic-content.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/optimistic-content.js.map +0 -1
- package/dist/packages/agent-runtime/src/protocol.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/protocol.js.map +0 -1
- package/dist/packages/agent-runtime/src/queue.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/queue.js.map +0 -1
- package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.js.map +0 -1
- package/dist/packages/agent-runtime/src/runtime-messages.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/runtime-messages.js.map +0 -1
- package/dist/packages/agent-runtime/src/screen-point.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/screen-point.js.map +0 -1
- package/dist/packages/agent-runtime/src/send-recovery.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/send-recovery.js.map +0 -1
- package/dist/packages/agent-runtime/src/statewire-attach-observer.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/statewire-attach-observer.js.map +0 -1
- package/dist/packages/agent-runtime/src/statewire-state.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/statewire-state.js.map +0 -1
- package/dist/packages/agent-runtime/src/statewire-suspended.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/statewire-suspended.js.map +0 -1
- package/dist/packages/agent-runtime/src/statewire-transport.cjs +0 -11
- package/dist/packages/agent-runtime/src/statewire-transport.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/statewire-transport.js +0 -11
- package/dist/packages/agent-runtime/src/statewire-transport.js.map +0 -1
- package/dist/packages/agent-runtime/src/streaming-markdown.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/streaming-markdown.js.map +0 -1
- package/dist/packages/agent-runtime/src/thread-extras.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/thread-extras.js.map +0 -1
- package/dist/packages/agent-runtime/src/thread-snapshot-cache.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/thread-snapshot-cache.js.map +0 -1
- package/dist/packages/agent-runtime/src/thread-status.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/thread-status.js.map +0 -1
- package/dist/packages/agent-runtime/src/tool-metadata.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/tool-metadata.js.map +0 -1
- package/dist/packages/agent-runtime/src/tool-outputs.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/tool-outputs.js.map +0 -1
- package/dist/packages/agent-runtime/src/tool-result.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/tool-result.js.map +0 -1
- package/dist/packages/agent-runtime/src/use-conversation-list.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/use-conversation-list.js.map +0 -1
- package/dist/packages/agent-runtime/src/use-deep-agent-config.cjs +0 -13
- package/dist/packages/agent-runtime/src/use-deep-agent-config.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/use-deep-agent-config.js +0 -13
- package/dist/packages/agent-runtime/src/use-deep-agent-config.js.map +0 -1
- package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.js.map +0 -1
- package/dist/packages/agent-runtime/src/use-deep-agent-runtime.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/use-deep-agent-runtime.js.map +0 -1
- package/dist/packages/agent-runtime/src/use-deep-agent-thread.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/use-deep-agent-thread.js.map +0 -1
- package/dist/packages/agent-runtime/src/use-deep-agent-window-sync.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/use-deep-agent-window-sync.js.map +0 -1
- package/dist/packages/agent-runtime/src/voice-presentation.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/voice-presentation.js.map +0 -1
- package/dist/packages/agent-runtime/src/voice-turn-grouping.cjs.map +0 -1
- package/dist/packages/agent-runtime/src/voice-turn-grouping.js.map +0 -1
- package/dist/packages/tiptap-markdown-table/src/markdown-table-serializer.cjs.map +0 -1
- package/dist/packages/tiptap-markdown-table/src/markdown-table-serializer.js.map +0 -1
- /package/dist/{packages/agent-runtime → agent-runtime}/src/asset-attachment.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/asset-attachment.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/auth-denial.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/auth-denial.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/client-tool-bridge.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/client-tool-bridge.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/client-tools.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/client-tools.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/conversation-index.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/conversation-index.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/edit-command.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/edit-command.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/github-wake-event.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/github-wake-event.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/message-author.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/message-author.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/message-window.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/message-window.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/model-context.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/model-context.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/optimistic-content.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/optimistic-content.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/protocol.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/protocol.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/runtime-messages.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/runtime-messages.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/screen-point.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/screen-point.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/send-recovery.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/send-recovery.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/statewire-attach-observer.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/statewire-attach-observer.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/streaming-markdown.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/streaming-markdown.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/thread-extras.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/thread-extras.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/thread-snapshot-cache.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/thread-snapshot-cache.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/thread-status.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/thread-status.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/tool-outputs.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/tool-outputs.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/tool-result.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/tool-result.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-runtime.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-runtime.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-window-sync.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-window-sync.js +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/voice-turn-grouping.cjs +0 -0
- /package/dist/{packages/agent-runtime → agent-runtime}/src/voice-turn-grouping.js +0 -0
- /package/dist/{packages/react → react}/package.json.cjs.map +0 -0
- /package/dist/{packages/react → react}/package.json.js.map +0 -0
- /package/dist/{packages/tiptap-markdown-table → tiptap-markdown-table}/src/markdown-table-serializer.cjs +0 -0
- /package/dist/{packages/tiptap-markdown-table → tiptap-markdown-table}/src/markdown-table-serializer.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-statewire-approval-request.cjs","sources":["../../src/chat/use-statewire-approval-request.ts"],"sourcesContent":["import type { StatewireThread } from '@assistant-ui/react-statewire';\nimport {\n useStatewireRuns,\n useStatewireSendCommand,\n useStatewireState,\n} from '@assistant-ui/react-statewire';\nimport {\n type AbandonedInputRequest,\n asHitlApproval,\n findAbandonedInterrupt,\n HITL_PENDING_RESUME_GRACE_MS,\n type HitlApprovalPayload,\n interruptMirrorPayload,\n isApprovalCardInterrupt,\n type PendingActionRequest,\n pendingActionRequests,\n readAbandonedInputRequests,\n readInterruptMirror,\n readQueuedLaneDecisions,\n useApprovalResumeLock,\n} from '@athenaintel/agent-runtime';\nimport { useCallback, useMemo } from 'react';\nimport { useAthenaRunLive } from './use-athena-run-live';\n\ndeclare module '@assistant-ui/core' {\n namespace Assistant {\n interface Commands {\n /**\n * Decide per-dispatch subagent lanes while the parent run is still\n * streaming (`DeepAgentThread.run_lane_input`). Keys are the lanes'\n * langgraph interrupt ids; the host matches them against the lanes its\n * mirrored interrupt currently parks, answers at once when the run is\n * already parked, and otherwise holds them until it parks — stale or\n * unknown ids are ignored, never carried to a later interrupt.\n */\n runLaneInput: {\n readonly type: 'run/lane-input';\n readonly laneDecisions: Readonly<Record<string, StatewireThread.InputResponse>>;\n };\n /**\n * Re-send the lane decisions the host still holds queued as their\n * approver's resume of the parked request (`DeepAgentThread.run_lane_replay`).\n * The host resumes under the meta the approver's `run/lane-input`\n * recorded and refuses any other caller — every attached client reads\n * the same queue, and only the one that queued it may turn it into a\n * resume. Carries no decisions: the host replays what it recorded.\n */\n runLaneReplay: {\n readonly type: 'run/lane-replay';\n readonly requestId: string;\n };\n }\n }\n}\n\nconst NO_QUEUED_LANE_DECISIONS: Readonly<Record<string, unknown>> = Object.freeze({});\n\n/** Selects which pending interrupt an approval surface answers. */\nexport type StatewireInterruptPredicate = (\n request: StatewireThread.InputRequestState,\n) => request is StatewireThread.CustomInputRequest;\n\nexport interface UseStatewireApprovalRequestOptions {\n /**\n * Which pending interrupt to answer. Defaults to `isApprovalCardInterrupt`\n * (client-tool parks excluded — the client-tool bridge owns those, and a\n * generic resume would corrupt the parked tool call).\n */\n interruptPredicate?: StatewireInterruptPredicate;\n /**\n * How long a sent decision keeps the actions locked when no resume run ever\n * starts. Defaults to {@link HITL_PENDING_RESUME_GRACE_MS}.\n */\n pendingResumeGraceMs?: number;\n /**\n * The host refused the `run/input` (or the transport lost it): the\n * optimistic fold rolls back, the request is on screen again with its\n * actions re-enabled, and this is the surface's one chance to say why.\n */\n onResumeRejected?: (error: unknown, requestId: string) => void;\n /** See {@link UseApprovalResumeLockOptions.onResumeRetry}. */\n onResumeRetry?: (error: unknown, requestId: string, attempt: number) => void;\n}\n\nexport interface StatewireApprovalRequest<TValue> {\n /** The pending interrupt this surface answers, if any. */\n request: StatewireThread.CustomInputRequest | undefined;\n requestId: string | undefined;\n /** The payload narrowed to the Athena HITL approval shape, or `null`. */\n hitl: HitlApprovalPayload | null;\n /** Every gated call the approval covers, in decision order (empty for non-HITL parks). */\n actionRequests: PendingActionRequest[];\n /** An interrupt a non-resume dispatch dropped — the \"approval was cancelled\" notice. */\n abandonedInterrupt: AbandonedInputRequest | undefined;\n /**\n * The mirrored interrupt's HITL payload while the run is still live and no\n * input request is answerable: per-dispatch `task` lanes parked on their\n * gates while sibling lanes stream. `null` once the run parks (the same\n * lanes are then `hitl` / `actionRequests`) and when nothing is parked.\n */\n liveHitl: HitlApprovalPayload | null;\n /** Every gated call `liveHitl` covers (empty when it is `null`). */\n liveActionRequests: PendingActionRequest[];\n /**\n * The decisions the host already holds from a `run/lane-input`, keyed by\n * langgraph interrupt id, to be answered when the run parks — a queued lane\n * reads as decided on every attached client, not just the one that sent it.\n */\n queuedLaneDecisions: Readonly<Record<string, unknown>>;\n /** True after a resume until the request identity changes (or recovery fires). */\n pending: boolean;\n /**\n * Answer the request with `{ type: 'run/input', requestId, response: { type: 'resume', value } }`.\n * Returns the dispatch promise (settles when the host accepts, rejects when\n * it refuses), or `undefined` when the lock dropped the send.\n */\n resume: (value: TValue) => Promise<unknown> | undefined;\n /**\n * Decide per-dispatch lanes by langgraph interrupt id. With a pending\n * request this is the native `lane_decisions` resume through the lock;\n * without one (the run is still streaming siblings) it is `run/lane-input`,\n * which the host queues and answers on the park. Returns the dispatch\n * promise, or `undefined` when the lock dropped a resume.\n */\n sendLaneDecisions: (\n lanes: Readonly<Record<string, StatewireThread.InputResponse>>,\n ) => Promise<unknown> | undefined;\n /**\n * Ask the host to resume the parked `requestId` with the lane decisions it\n * still holds queued, as their approver (`run/lane-replay`). For the card\n * that queued them, after the host's own answerer has stayed silent past\n * its budget; the host refuses every other caller. Settles when the host\n * accepts, rejects when it refuses.\n */\n replayQueuedLanes: (requestId: string) => Promise<unknown>;\n}\n\n/**\n * The headless half of every statewire approval surface: selects the pending\n * interrupt from the runs projection, narrows its payload, reads the\n * host-published abandoned interrupts, and wires the shared optimistic resume\n * lock to the thread's `run/input` command. `StatewireApprovalCard` renders\n * over it; hosts with their own decision UI (per-lane subagent cards) build\n * on it directly so the selection and lock semantics cannot drift.\n *\n * Requires a statewire aui scope (throws outside one, like every\n * `useStatewire*` hook) — gate the mount with `hasStatewireThreadExtras`.\n */\nexport function useStatewireApprovalRequest<\n TValue extends StatewireThread.InputResponse = Record<string, string>,\n>(options: UseStatewireApprovalRequestOptions = {}): StatewireApprovalRequest<TValue> {\n const {\n interruptPredicate = isApprovalCardInterrupt,\n pendingResumeGraceMs = HITL_PENDING_RESUME_GRACE_MS,\n onResumeRejected,\n onResumeRetry,\n } = options;\n const sendCommand = useStatewireSendCommand();\n // The runs projection is memoized by the lib, so this derivation is\n // reference-stable between state updates.\n const request = useStatewireRuns().inputRequests?.find(interruptPredicate);\n const requestId = request?.id;\n\n // The host publishes the interrupts a non-resume dispatch dropped. Select\n // the raw array reference (pre-stream-safe) and derive inline; a `.find`\n // selector would return a fresh object every update.\n const abandoned = useStatewireState(readAbandonedInputRequests);\n const abandonedInterrupt = findAbandonedInterrupt(abandoned);\n\n const hitl = asHitlApproval(request?.payload);\n const actionRequests = useMemo(() => pendingActionRequests(hitl), [hitl]);\n\n const isRunning = useAthenaRunLive();\n // The host mirrors the interrupt into state as soon as a lane parks — while\n // the run manager still reports `running` (siblings streaming) and has no\n // request to answer. Raw reference selectors; derive inline.\n const mirror = useStatewireState(readInterruptMirror);\n const liveHitl =\n request === undefined && isRunning ? asHitlApproval(interruptMirrorPayload(mirror)) : null;\n const liveActionRequests = useMemo(() => pendingActionRequests(liveHitl), [liveHitl]);\n const queuedLaneDecisions =\n useStatewireState(readQueuedLaneDecisions) ?? NO_QUEUED_LANE_DECISIONS;\n\n const { pending, resume } = useApprovalResumeLock<TValue>({\n requestId,\n isRunning,\n pendingResumeGraceMs,\n onResumeRejected,\n onResumeRetry,\n // The dispatch promise is handed to the lock: a refusal releases it and\n // reaches `onResumeRejected`.\n sendResume: (id, value) =>\n sendCommand({\n type: 'run/input',\n requestId: id,\n response: { type: 'resume', value },\n }),\n });\n\n const sendLaneDecisions = useCallback(\n (lanes: Readonly<Record<string, StatewireThread.InputResponse>>) =>\n requestId !== undefined\n ? resume({ lane_decisions: lanes } as unknown as TValue)\n : sendCommand({ type: 'run/lane-input', laneDecisions: lanes }),\n [requestId, resume, sendCommand],\n );\n\n const replayQueuedLanes = useCallback(\n (id: string) => sendCommand({ type: 'run/lane-replay', requestId: id }),\n [sendCommand],\n );\n\n return {\n request,\n requestId,\n hitl,\n actionRequests,\n liveHitl,\n liveActionRequests,\n queuedLaneDecisions,\n abandonedInterrupt,\n pending,\n resume,\n sendLaneDecisions,\n replayQueuedLanes,\n };\n}\n"],"names":["isApprovalCardInterrupt","HITL_PENDING_RESUME_GRACE_MS","useStatewireSendCommand","useStatewireRuns","useStatewireState","readAbandonedInputRequests","findAbandonedInterrupt","asHitlApproval","useMemo","pendingActionRequests","useAthenaRunLive","readInterruptMirror","interruptMirrorPayload","readQueuedLaneDecisions","useApprovalResumeLock","useCallback"],"mappings":";;;;;;AAuDA,MAAM,2BAA8D,OAAO,OAAO,EAAE;AA6F7E,SAAS,4BAEd,UAA8C,IAAsC;;AACpF,QAAM;AAAA,IACJ,qBAAqBA,WAAAA;AAAAA,IACrB,uBAAuBC,WAAAA;AAAAA,IACvB;AAAA,IACA;AAAA,EAAA,IACE;AACJ,QAAM,cAAcC,eAAAA,wBAAA;AAGpB,QAAM,WAAUC,oBAAAA,iBAAA,EAAmB,kBAAnBA,mBAAkC,KAAK;AACvD,QAAM,YAAY,mCAAS;AAK3B,QAAM,YAAYC,eAAAA,kBAAkBC,qCAA0B;AAC9D,QAAM,qBAAqBC,WAAAA,uBAAuB,SAAS;AAE3D,QAAM,OAAOC,WAAAA,eAAe,mCAAS,OAAO;AAC5C,QAAM,iBAAiBC,MAAAA,QAAQ,MAAMC,WAAAA,sBAAsB,IAAI,GAAG,CAAC,IAAI,CAAC;AAExE,QAAM,YAAYC,iBAAAA,iBAAA;AAIlB,QAAM,SAASN,eAAAA,kBAAkBO,8BAAmB;AACpD,QAAM,WACJ,YAAY,UAAa,YAAYJ,WAAAA,eAAeK,WAAAA,uBAAuB,MAAM,CAAC,IAAI;AACxF,QAAM,qBAAqBJ,MAAAA,QAAQ,MAAMC,WAAAA,sBAAsB,QAAQ,GAAG,CAAC,QAAQ,CAAC;AACpF,QAAM,sBACJL,eAAAA,kBAAkBS,WAAAA,uBAAuB,KAAK;AAEhD,QAAM,EAAE,SAAS,OAAA,IAAWC,iCAA8B;AAAA,IACxD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA,YAAY,CAAC,IAAI,UACf,YAAY;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,MACX,UAAU,EAAE,MAAM,UAAU,MAAA;AAAA,IAAM,CACnC;AAAA,EAAA,CACJ;AAED,QAAM,oBAAoBC,MAAAA;AAAAA,IACxB,CAAC,UACC,cAAc,SACV,OAAO,EAAE,gBAAgB,MAAA,CAA4B,IACrD,YAAY,EAAE,MAAM,kBAAkB,eAAe,OAAO;AAAA,IAClE,CAAC,WAAW,QAAQ,WAAW;AAAA,EAAA;AAGjC,QAAM,oBAAoBA,MAAAA;AAAAA,IACxB,CAAC,OAAe,YAAY,EAAE,MAAM,mBAAmB,WAAW,IAAI;AAAA,IACtE,CAAC,WAAW;AAAA,EAAA;AAGd,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;;"}
|
|
1
|
+
{"version":3,"file":"use-statewire-approval-request.cjs","sources":["../../src/chat/use-statewire-approval-request.ts"],"sourcesContent":["import type { StatewireThread } from '@assistant-ui/react-statewire';\nimport {\n useStatewireRuns,\n useStatewireSendCommand,\n useStatewireState,\n} from '@assistant-ui/react-statewire';\nimport {\n type AbandonedInputRequest,\n asHitlApproval,\n findAbandonedInterrupt,\n HITL_PENDING_RESUME_GRACE_MS,\n type HitlApprovalPayload,\n interruptMirrorPayload,\n isApprovalCardInterrupt,\n laneInterruptIds,\n type PendingActionRequest,\n pendingActionRequests,\n readAbandonedInputRequests,\n readInterruptMirror,\n readQueuedLaneDecisions,\n useApprovalResumeLock,\n} from '@athenaintel/agent-runtime';\nimport { useCallback, useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport { useAthenaRunLive } from './use-athena-run-live';\n\ndeclare module '@assistant-ui/core' {\n namespace Assistant {\n interface Commands {\n /**\n * Decide per-dispatch subagent lanes while the parent run is still\n * streaming (`DeepAgentThread.run_lane_input`). Keys are the lanes'\n * langgraph interrupt ids; the host matches them against the lanes its\n * mirrored interrupt currently parks, answers at once when the run is\n * already parked, and otherwise holds them until it parks — stale or\n * unknown ids are ignored, never carried to a later interrupt.\n */\n runLaneInput: {\n readonly type: 'run/lane-input';\n readonly laneDecisions: Readonly<Record<string, StatewireThread.InputResponse>>;\n };\n /**\n * Re-send the lane decisions the host still holds queued as their\n * approver's resume of the parked request (`DeepAgentThread.run_lane_replay`).\n * The host resumes under the meta the approver's `run/lane-input`\n * recorded and refuses any other caller — every attached client reads\n * the same queue, and only the one that queued it may turn it into a\n * resume. Carries no decisions: the host replays what it recorded.\n */\n runLaneReplay: {\n readonly type: 'run/lane-replay';\n readonly requestId: string;\n };\n }\n }\n}\n\nconst NO_QUEUED_LANE_DECISIONS: Readonly<Record<string, unknown>> = Object.freeze({});\nconst NO_ACTION_REQUESTS: PendingActionRequest[] = [];\n\n/**\n * Lane ids of the parked requests this client resumed, keyed by request id\n * and shared by every hook instance on the page (approval card,\n * waiting-on-you banner, host editors) so all of them treat a lingering\n * mirror the same way. Request ids are unique per parked interrupt, so an\n * instance only ever consults the record of the request it saw parked: two\n * chats mounted side by side cannot suppress or clear each other's. A record\n * is retired once the host drops that request's mirror (the resume run\n * started), the surface sees a different request park, or it unmounts.\n */\nconst answeredRequests = new Map<string, readonly string[]>();\nconst answeredListeners = new Set<() => void>();\nlet answeredVersion = 0;\nfunction notifyAnswered(): void {\n answeredVersion += 1;\n for (const listener of answeredListeners) listener();\n}\nfunction recordAnswered(requestId: string, laneIds: readonly string[]): void {\n answeredRequests.set(requestId, laneIds);\n notifyAnswered();\n}\nfunction forgetAnswered(requestId: string): void {\n if (answeredRequests.delete(requestId)) notifyAnswered();\n}\nfunction subscribeAnswered(listener: () => void): () => void {\n answeredListeners.add(listener);\n return () => {\n answeredListeners.delete(listener);\n };\n}\nconst readAnsweredVersion = (): number => answeredVersion;\n\n/**\n * The lanes a resume of the parked request settles: every lane of the request\n * (a resume answers the whole park — lanes already queued through\n * `run/lane-input` ride along) plus any lane named in the `lane_decisions` map.\n */\nfunction answeredLaneIds(value: unknown, actionRequests: readonly PendingActionRequest[]): string[] {\n const ids = laneInterruptIds(actionRequests) ?? [];\n if (typeof value === 'object' && value !== null && 'lane_decisions' in value) {\n const lanes = (value as { lane_decisions: unknown }).lane_decisions;\n if (typeof lanes === 'object' && lanes !== null) {\n for (const id of Object.keys(lanes)) if (!ids.includes(id)) ids.push(id);\n }\n }\n return ids;\n}\n\n/**\n * Whether the host's mirror still shows an interrupt this client already\n * answered. After `run/input` the host drops the parked request at once but\n * keeps `__interrupt__` until the resume run starts and clears it (seconds on\n * a cold checkpoint); without this check the card would re-offer the SAME\n * approval from the mirror, buttons live, and then fold it away again.\n */\nfunction mirrorAlreadyAnswered(\n answeredLanes: readonly string[] | undefined,\n liveActionRequests: readonly PendingActionRequest[],\n): boolean {\n if (answeredLanes === undefined) return false;\n const ids = laneInterruptIds(liveActionRequests);\n if (ids === null) return false;\n return ids.every((id) => answeredLanes.includes(id));\n}\n\n/** Selects which pending interrupt an approval surface answers. */\nexport type StatewireInterruptPredicate = (\n request: StatewireThread.InputRequestState,\n) => request is StatewireThread.CustomInputRequest;\n\nexport interface UseStatewireApprovalRequestOptions {\n /**\n * Which pending interrupt to answer. Defaults to `isApprovalCardInterrupt`\n * (client-tool parks excluded — the client-tool bridge owns those, and a\n * generic resume would corrupt the parked tool call).\n */\n interruptPredicate?: StatewireInterruptPredicate;\n /**\n * How long a sent decision keeps the actions locked when no resume run ever\n * starts. Defaults to {@link HITL_PENDING_RESUME_GRACE_MS}.\n */\n pendingResumeGraceMs?: number;\n /**\n * The host refused the `run/input` (or the transport lost it): the\n * optimistic fold rolls back, the request is on screen again with its\n * actions re-enabled, and this is the surface's one chance to say why.\n */\n onResumeRejected?: (error: unknown, requestId: string) => void;\n /** See {@link UseApprovalResumeLockOptions.onResumeRetry}. */\n onResumeRetry?: (error: unknown, requestId: string, attempt: number) => void;\n}\n\nexport interface StatewireApprovalRequest<TValue> {\n /** The pending interrupt this surface answers, if any. */\n request: StatewireThread.CustomInputRequest | undefined;\n requestId: string | undefined;\n /** The payload narrowed to the Athena HITL approval shape, or `null`. */\n hitl: HitlApprovalPayload | null;\n /** Every gated call the approval covers, in decision order (empty for non-HITL parks). */\n actionRequests: PendingActionRequest[];\n /** An interrupt a non-resume dispatch dropped — the \"approval was cancelled\" notice. */\n abandonedInterrupt: AbandonedInputRequest | undefined;\n /**\n * The mirrored interrupt's HITL payload while the run is still live and no\n * input request is answerable: per-dispatch `task` lanes parked on their\n * gates while sibling lanes stream. `null` once the run parks (the same\n * lanes are then `hitl` / `actionRequests`) and when nothing is parked.\n */\n liveHitl: HitlApprovalPayload | null;\n /** Every gated call `liveHitl` covers (empty when it is `null`). */\n liveActionRequests: PendingActionRequest[];\n /**\n * The decisions the host already holds from a `run/lane-input`, keyed by\n * langgraph interrupt id, to be answered when the run parks — a queued lane\n * reads as decided on every attached client, not just the one that sent it.\n */\n queuedLaneDecisions: Readonly<Record<string, unknown>>;\n /** True after a resume until the request identity changes (or recovery fires). */\n pending: boolean;\n /**\n * Answer the request with `{ type: 'run/input', requestId, response: { type: 'resume', value } }`.\n * Returns the dispatch promise (settles when the host accepts, rejects when\n * it refuses), or `undefined` when the lock dropped the send.\n */\n resume: (value: TValue) => Promise<unknown> | undefined;\n /**\n * Decide per-dispatch lanes by langgraph interrupt id. With a pending\n * request this is the native `lane_decisions` resume through the lock;\n * without one (the run is still streaming siblings) it is `run/lane-input`,\n * which the host queues and answers on the park. Returns the dispatch\n * promise, or `undefined` when the lock dropped a resume.\n */\n sendLaneDecisions: (\n lanes: Readonly<Record<string, StatewireThread.InputResponse>>,\n ) => Promise<unknown> | undefined;\n /**\n * Ask the host to resume the parked `requestId` with the lane decisions it\n * still holds queued, as their approver (`run/lane-replay`). For the card\n * that queued them, after the host's own answerer has stayed silent past\n * its budget; the host refuses every other caller. Settles when the host\n * accepts, rejects when it refuses.\n */\n replayQueuedLanes: (requestId: string) => Promise<unknown>;\n}\n\n/**\n * The headless half of every statewire approval surface: selects the pending\n * interrupt from the runs projection, narrows its payload, reads the\n * host-published abandoned interrupts, and wires the shared optimistic resume\n * lock to the thread's `run/input` command. `StatewireApprovalCard` renders\n * over it; hosts with their own decision UI (per-lane subagent cards) build\n * on it directly so the selection and lock semantics cannot drift.\n *\n * Requires a statewire aui scope (throws outside one, like every\n * `useStatewire*` hook) — gate the mount with `hasStatewireThreadExtras`.\n */\nexport function useStatewireApprovalRequest<\n TValue extends StatewireThread.InputResponse = Record<string, string>,\n>(options: UseStatewireApprovalRequestOptions = {}): StatewireApprovalRequest<TValue> {\n const {\n interruptPredicate = isApprovalCardInterrupt,\n pendingResumeGraceMs = HITL_PENDING_RESUME_GRACE_MS,\n onResumeRejected,\n onResumeRetry,\n } = options;\n const sendCommand = useStatewireSendCommand();\n // The runs projection is memoized by the lib, so this derivation is\n // reference-stable between state updates.\n const request = useStatewireRuns().inputRequests?.find(interruptPredicate);\n const requestId = request?.id;\n\n // The host publishes the interrupts a non-resume dispatch dropped. Select\n // the raw array reference (pre-stream-safe) and derive inline; a `.find`\n // selector would return a fresh object every update.\n const abandoned = useStatewireState(readAbandonedInputRequests);\n const abandonedInterrupt = findAbandonedInterrupt(abandoned);\n\n const hitl = asHitlApproval(request?.payload);\n const actionRequests = useMemo(() => pendingActionRequests(hitl), [hitl]);\n\n const isRunning = useAthenaRunLive();\n // The host mirrors the interrupt into state as soon as a lane parks — while\n // the run manager still reports `running` (siblings streaming) and has no\n // request to answer. Raw reference selectors; derive inline.\n const mirror = useStatewireState(readInterruptMirror);\n const mirrorHitl =\n request === undefined && isRunning ? asHitlApproval(interruptMirrorPayload(mirror)) : null;\n const mirrorActionRequests = useMemo(() => pendingActionRequests(mirrorHitl), [mirrorHitl]);\n\n // The request this surface last saw parked: the only record it may read\n // or retire (the mirror it watches is the one that request's resume clears).\n const lastRequestIdRef = useRef<string>(undefined);\n if (requestId !== undefined) lastRequestIdRef.current = requestId;\n useSyncExternalStore(subscribeAnswered, readAnsweredVersion, readAnsweredVersion);\n const answeredLanes =\n lastRequestIdRef.current === undefined ? undefined : answeredRequests.get(lastRequestIdRef.current);\n const mirrorCleared = interruptMirrorPayload(mirror) === undefined;\n useEffect(() => {\n if (requestId === undefined) return;\n return () => {\n // A different request parks next (or this one unparks for good): the\n // record of this one is stale once it is not the one on screen.\n if (lastRequestIdRef.current !== requestId) forgetAnswered(requestId);\n };\n }, [requestId]);\n useEffect(() => {\n if (mirrorCleared && lastRequestIdRef.current !== undefined) forgetAnswered(lastRequestIdRef.current);\n }, [mirrorCleared]);\n useEffect(\n () => () => {\n if (lastRequestIdRef.current !== undefined) forgetAnswered(lastRequestIdRef.current);\n },\n [],\n );\n const liveHitl = mirrorAlreadyAnswered(answeredLanes, mirrorActionRequests) ? null : mirrorHitl;\n const liveActionRequests = liveHitl === mirrorHitl ? mirrorActionRequests : NO_ACTION_REQUESTS;\n const queuedLaneDecisions =\n useStatewireState(readQueuedLaneDecisions) ?? NO_QUEUED_LANE_DECISIONS;\n\n const { pending, resume: resumeLocked } = useApprovalResumeLock<TValue>({\n requestId,\n isRunning,\n pendingResumeGraceMs,\n onResumeRejected,\n onResumeRetry,\n // The dispatch promise is handed to the lock: a refusal releases it and\n // reaches `onResumeRejected`.\n sendResume: (id, value) =>\n sendCommand({\n type: 'run/input',\n requestId: id,\n response: { type: 'resume', value },\n }),\n });\n\n const resume = useCallback(\n (value: TValue) => {\n if (requestId !== undefined) {\n recordAnswered(requestId, answeredLaneIds(value, actionRequests));\n }\n return resumeLocked(value);\n },\n [requestId, actionRequests, resumeLocked],\n );\n\n const sendLaneDecisions = useCallback(\n (lanes: Readonly<Record<string, StatewireThread.InputResponse>>) =>\n requestId !== undefined\n ? resume({ lane_decisions: lanes } as unknown as TValue)\n : sendCommand({ type: 'run/lane-input', laneDecisions: lanes }),\n [requestId, resume, sendCommand],\n );\n\n const replayQueuedLanes = useCallback(\n (id: string) => sendCommand({ type: 'run/lane-replay', requestId: id }),\n [sendCommand],\n );\n\n return {\n request,\n requestId,\n hitl,\n actionRequests,\n liveHitl,\n liveActionRequests,\n queuedLaneDecisions,\n abandonedInterrupt,\n pending,\n resume,\n sendLaneDecisions,\n replayQueuedLanes,\n };\n}\n"],"names":["laneInterruptIds","isApprovalCardInterrupt","HITL_PENDING_RESUME_GRACE_MS","useStatewireSendCommand","useStatewireRuns","useStatewireState","readAbandonedInputRequests","findAbandonedInterrupt","asHitlApproval","useMemo","pendingActionRequests","useAthenaRunLive","readInterruptMirror","interruptMirrorPayload","useRef","useSyncExternalStore","useEffect","readQueuedLaneDecisions","useApprovalResumeLock","useCallback"],"mappings":"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"}
|
|
@@ -1,8 +1,46 @@
|
|
|
1
1
|
import { useStatewireSendCommand, useStatewireRuns, useStatewireState } from "@assistant-ui/react-statewire";
|
|
2
|
-
import { useMemo, useCallback } from "react";
|
|
2
|
+
import { useMemo, useRef, useSyncExternalStore, useEffect, useCallback } from "react";
|
|
3
3
|
import { useAthenaRunLive } from "./use-athena-run-live.js";
|
|
4
|
-
import { isApprovalCardInterrupt, HITL_PENDING_RESUME_GRACE_MS, readAbandonedInputRequests, findAbandonedInterrupt, asHitlApproval, pendingActionRequests, readInterruptMirror, interruptMirrorPayload, readQueuedLaneDecisions, useApprovalResumeLock } from "../
|
|
4
|
+
import { isApprovalCardInterrupt, HITL_PENDING_RESUME_GRACE_MS, readAbandonedInputRequests, findAbandonedInterrupt, asHitlApproval, pendingActionRequests, readInterruptMirror, interruptMirrorPayload, readQueuedLaneDecisions, useApprovalResumeLock, laneInterruptIds } from "../agent-runtime/src/interrupts.js";
|
|
5
5
|
const NO_QUEUED_LANE_DECISIONS = Object.freeze({});
|
|
6
|
+
const NO_ACTION_REQUESTS = [];
|
|
7
|
+
const answeredRequests = /* @__PURE__ */ new Map();
|
|
8
|
+
const answeredListeners = /* @__PURE__ */ new Set();
|
|
9
|
+
let answeredVersion = 0;
|
|
10
|
+
function notifyAnswered() {
|
|
11
|
+
answeredVersion += 1;
|
|
12
|
+
for (const listener of answeredListeners) listener();
|
|
13
|
+
}
|
|
14
|
+
function recordAnswered(requestId, laneIds) {
|
|
15
|
+
answeredRequests.set(requestId, laneIds);
|
|
16
|
+
notifyAnswered();
|
|
17
|
+
}
|
|
18
|
+
function forgetAnswered(requestId) {
|
|
19
|
+
if (answeredRequests.delete(requestId)) notifyAnswered();
|
|
20
|
+
}
|
|
21
|
+
function subscribeAnswered(listener) {
|
|
22
|
+
answeredListeners.add(listener);
|
|
23
|
+
return () => {
|
|
24
|
+
answeredListeners.delete(listener);
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const readAnsweredVersion = () => answeredVersion;
|
|
28
|
+
function answeredLaneIds(value, actionRequests) {
|
|
29
|
+
const ids = laneInterruptIds(actionRequests) ?? [];
|
|
30
|
+
if (typeof value === "object" && value !== null && "lane_decisions" in value) {
|
|
31
|
+
const lanes = value.lane_decisions;
|
|
32
|
+
if (typeof lanes === "object" && lanes !== null) {
|
|
33
|
+
for (const id of Object.keys(lanes)) if (!ids.includes(id)) ids.push(id);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return ids;
|
|
37
|
+
}
|
|
38
|
+
function mirrorAlreadyAnswered(answeredLanes, liveActionRequests) {
|
|
39
|
+
if (answeredLanes === void 0) return false;
|
|
40
|
+
const ids = laneInterruptIds(liveActionRequests);
|
|
41
|
+
if (ids === null) return false;
|
|
42
|
+
return ids.every((id) => answeredLanes.includes(id));
|
|
43
|
+
}
|
|
6
44
|
function useStatewireApprovalRequest(options = {}) {
|
|
7
45
|
var _a;
|
|
8
46
|
const {
|
|
@@ -20,10 +58,32 @@ function useStatewireApprovalRequest(options = {}) {
|
|
|
20
58
|
const actionRequests = useMemo(() => pendingActionRequests(hitl), [hitl]);
|
|
21
59
|
const isRunning = useAthenaRunLive();
|
|
22
60
|
const mirror = useStatewireState(readInterruptMirror);
|
|
23
|
-
const
|
|
24
|
-
const
|
|
61
|
+
const mirrorHitl = request === void 0 && isRunning ? asHitlApproval(interruptMirrorPayload(mirror)) : null;
|
|
62
|
+
const mirrorActionRequests = useMemo(() => pendingActionRequests(mirrorHitl), [mirrorHitl]);
|
|
63
|
+
const lastRequestIdRef = useRef(void 0);
|
|
64
|
+
if (requestId !== void 0) lastRequestIdRef.current = requestId;
|
|
65
|
+
useSyncExternalStore(subscribeAnswered, readAnsweredVersion, readAnsweredVersion);
|
|
66
|
+
const answeredLanes = lastRequestIdRef.current === void 0 ? void 0 : answeredRequests.get(lastRequestIdRef.current);
|
|
67
|
+
const mirrorCleared = interruptMirrorPayload(mirror) === void 0;
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (requestId === void 0) return;
|
|
70
|
+
return () => {
|
|
71
|
+
if (lastRequestIdRef.current !== requestId) forgetAnswered(requestId);
|
|
72
|
+
};
|
|
73
|
+
}, [requestId]);
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (mirrorCleared && lastRequestIdRef.current !== void 0) forgetAnswered(lastRequestIdRef.current);
|
|
76
|
+
}, [mirrorCleared]);
|
|
77
|
+
useEffect(
|
|
78
|
+
() => () => {
|
|
79
|
+
if (lastRequestIdRef.current !== void 0) forgetAnswered(lastRequestIdRef.current);
|
|
80
|
+
},
|
|
81
|
+
[]
|
|
82
|
+
);
|
|
83
|
+
const liveHitl = mirrorAlreadyAnswered(answeredLanes, mirrorActionRequests) ? null : mirrorHitl;
|
|
84
|
+
const liveActionRequests = liveHitl === mirrorHitl ? mirrorActionRequests : NO_ACTION_REQUESTS;
|
|
25
85
|
const queuedLaneDecisions = useStatewireState(readQueuedLaneDecisions) ?? NO_QUEUED_LANE_DECISIONS;
|
|
26
|
-
const { pending, resume } = useApprovalResumeLock({
|
|
86
|
+
const { pending, resume: resumeLocked } = useApprovalResumeLock({
|
|
27
87
|
requestId,
|
|
28
88
|
isRunning,
|
|
29
89
|
pendingResumeGraceMs,
|
|
@@ -37,6 +97,15 @@ function useStatewireApprovalRequest(options = {}) {
|
|
|
37
97
|
response: { type: "resume", value }
|
|
38
98
|
})
|
|
39
99
|
});
|
|
100
|
+
const resume = useCallback(
|
|
101
|
+
(value) => {
|
|
102
|
+
if (requestId !== void 0) {
|
|
103
|
+
recordAnswered(requestId, answeredLaneIds(value, actionRequests));
|
|
104
|
+
}
|
|
105
|
+
return resumeLocked(value);
|
|
106
|
+
},
|
|
107
|
+
[requestId, actionRequests, resumeLocked]
|
|
108
|
+
);
|
|
40
109
|
const sendLaneDecisions = useCallback(
|
|
41
110
|
(lanes) => requestId !== void 0 ? resume({ lane_decisions: lanes }) : sendCommand({ type: "run/lane-input", laneDecisions: lanes }),
|
|
42
111
|
[requestId, resume, sendCommand]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-statewire-approval-request.js","sources":["../../src/chat/use-statewire-approval-request.ts"],"sourcesContent":["import type { StatewireThread } from '@assistant-ui/react-statewire';\nimport {\n useStatewireRuns,\n useStatewireSendCommand,\n useStatewireState,\n} from '@assistant-ui/react-statewire';\nimport {\n type AbandonedInputRequest,\n asHitlApproval,\n findAbandonedInterrupt,\n HITL_PENDING_RESUME_GRACE_MS,\n type HitlApprovalPayload,\n interruptMirrorPayload,\n isApprovalCardInterrupt,\n type PendingActionRequest,\n pendingActionRequests,\n readAbandonedInputRequests,\n readInterruptMirror,\n readQueuedLaneDecisions,\n useApprovalResumeLock,\n} from '@athenaintel/agent-runtime';\nimport { useCallback, useMemo } from 'react';\nimport { useAthenaRunLive } from './use-athena-run-live';\n\ndeclare module '@assistant-ui/core' {\n namespace Assistant {\n interface Commands {\n /**\n * Decide per-dispatch subagent lanes while the parent run is still\n * streaming (`DeepAgentThread.run_lane_input`). Keys are the lanes'\n * langgraph interrupt ids; the host matches them against the lanes its\n * mirrored interrupt currently parks, answers at once when the run is\n * already parked, and otherwise holds them until it parks — stale or\n * unknown ids are ignored, never carried to a later interrupt.\n */\n runLaneInput: {\n readonly type: 'run/lane-input';\n readonly laneDecisions: Readonly<Record<string, StatewireThread.InputResponse>>;\n };\n /**\n * Re-send the lane decisions the host still holds queued as their\n * approver's resume of the parked request (`DeepAgentThread.run_lane_replay`).\n * The host resumes under the meta the approver's `run/lane-input`\n * recorded and refuses any other caller — every attached client reads\n * the same queue, and only the one that queued it may turn it into a\n * resume. Carries no decisions: the host replays what it recorded.\n */\n runLaneReplay: {\n readonly type: 'run/lane-replay';\n readonly requestId: string;\n };\n }\n }\n}\n\nconst NO_QUEUED_LANE_DECISIONS: Readonly<Record<string, unknown>> = Object.freeze({});\n\n/** Selects which pending interrupt an approval surface answers. */\nexport type StatewireInterruptPredicate = (\n request: StatewireThread.InputRequestState,\n) => request is StatewireThread.CustomInputRequest;\n\nexport interface UseStatewireApprovalRequestOptions {\n /**\n * Which pending interrupt to answer. Defaults to `isApprovalCardInterrupt`\n * (client-tool parks excluded — the client-tool bridge owns those, and a\n * generic resume would corrupt the parked tool call).\n */\n interruptPredicate?: StatewireInterruptPredicate;\n /**\n * How long a sent decision keeps the actions locked when no resume run ever\n * starts. Defaults to {@link HITL_PENDING_RESUME_GRACE_MS}.\n */\n pendingResumeGraceMs?: number;\n /**\n * The host refused the `run/input` (or the transport lost it): the\n * optimistic fold rolls back, the request is on screen again with its\n * actions re-enabled, and this is the surface's one chance to say why.\n */\n onResumeRejected?: (error: unknown, requestId: string) => void;\n /** See {@link UseApprovalResumeLockOptions.onResumeRetry}. */\n onResumeRetry?: (error: unknown, requestId: string, attempt: number) => void;\n}\n\nexport interface StatewireApprovalRequest<TValue> {\n /** The pending interrupt this surface answers, if any. */\n request: StatewireThread.CustomInputRequest | undefined;\n requestId: string | undefined;\n /** The payload narrowed to the Athena HITL approval shape, or `null`. */\n hitl: HitlApprovalPayload | null;\n /** Every gated call the approval covers, in decision order (empty for non-HITL parks). */\n actionRequests: PendingActionRequest[];\n /** An interrupt a non-resume dispatch dropped — the \"approval was cancelled\" notice. */\n abandonedInterrupt: AbandonedInputRequest | undefined;\n /**\n * The mirrored interrupt's HITL payload while the run is still live and no\n * input request is answerable: per-dispatch `task` lanes parked on their\n * gates while sibling lanes stream. `null` once the run parks (the same\n * lanes are then `hitl` / `actionRequests`) and when nothing is parked.\n */\n liveHitl: HitlApprovalPayload | null;\n /** Every gated call `liveHitl` covers (empty when it is `null`). */\n liveActionRequests: PendingActionRequest[];\n /**\n * The decisions the host already holds from a `run/lane-input`, keyed by\n * langgraph interrupt id, to be answered when the run parks — a queued lane\n * reads as decided on every attached client, not just the one that sent it.\n */\n queuedLaneDecisions: Readonly<Record<string, unknown>>;\n /** True after a resume until the request identity changes (or recovery fires). */\n pending: boolean;\n /**\n * Answer the request with `{ type: 'run/input', requestId, response: { type: 'resume', value } }`.\n * Returns the dispatch promise (settles when the host accepts, rejects when\n * it refuses), or `undefined` when the lock dropped the send.\n */\n resume: (value: TValue) => Promise<unknown> | undefined;\n /**\n * Decide per-dispatch lanes by langgraph interrupt id. With a pending\n * request this is the native `lane_decisions` resume through the lock;\n * without one (the run is still streaming siblings) it is `run/lane-input`,\n * which the host queues and answers on the park. Returns the dispatch\n * promise, or `undefined` when the lock dropped a resume.\n */\n sendLaneDecisions: (\n lanes: Readonly<Record<string, StatewireThread.InputResponse>>,\n ) => Promise<unknown> | undefined;\n /**\n * Ask the host to resume the parked `requestId` with the lane decisions it\n * still holds queued, as their approver (`run/lane-replay`). For the card\n * that queued them, after the host's own answerer has stayed silent past\n * its budget; the host refuses every other caller. Settles when the host\n * accepts, rejects when it refuses.\n */\n replayQueuedLanes: (requestId: string) => Promise<unknown>;\n}\n\n/**\n * The headless half of every statewire approval surface: selects the pending\n * interrupt from the runs projection, narrows its payload, reads the\n * host-published abandoned interrupts, and wires the shared optimistic resume\n * lock to the thread's `run/input` command. `StatewireApprovalCard` renders\n * over it; hosts with their own decision UI (per-lane subagent cards) build\n * on it directly so the selection and lock semantics cannot drift.\n *\n * Requires a statewire aui scope (throws outside one, like every\n * `useStatewire*` hook) — gate the mount with `hasStatewireThreadExtras`.\n */\nexport function useStatewireApprovalRequest<\n TValue extends StatewireThread.InputResponse = Record<string, string>,\n>(options: UseStatewireApprovalRequestOptions = {}): StatewireApprovalRequest<TValue> {\n const {\n interruptPredicate = isApprovalCardInterrupt,\n pendingResumeGraceMs = HITL_PENDING_RESUME_GRACE_MS,\n onResumeRejected,\n onResumeRetry,\n } = options;\n const sendCommand = useStatewireSendCommand();\n // The runs projection is memoized by the lib, so this derivation is\n // reference-stable between state updates.\n const request = useStatewireRuns().inputRequests?.find(interruptPredicate);\n const requestId = request?.id;\n\n // The host publishes the interrupts a non-resume dispatch dropped. Select\n // the raw array reference (pre-stream-safe) and derive inline; a `.find`\n // selector would return a fresh object every update.\n const abandoned = useStatewireState(readAbandonedInputRequests);\n const abandonedInterrupt = findAbandonedInterrupt(abandoned);\n\n const hitl = asHitlApproval(request?.payload);\n const actionRequests = useMemo(() => pendingActionRequests(hitl), [hitl]);\n\n const isRunning = useAthenaRunLive();\n // The host mirrors the interrupt into state as soon as a lane parks — while\n // the run manager still reports `running` (siblings streaming) and has no\n // request to answer. Raw reference selectors; derive inline.\n const mirror = useStatewireState(readInterruptMirror);\n const liveHitl =\n request === undefined && isRunning ? asHitlApproval(interruptMirrorPayload(mirror)) : null;\n const liveActionRequests = useMemo(() => pendingActionRequests(liveHitl), [liveHitl]);\n const queuedLaneDecisions =\n useStatewireState(readQueuedLaneDecisions) ?? NO_QUEUED_LANE_DECISIONS;\n\n const { pending, resume } = useApprovalResumeLock<TValue>({\n requestId,\n isRunning,\n pendingResumeGraceMs,\n onResumeRejected,\n onResumeRetry,\n // The dispatch promise is handed to the lock: a refusal releases it and\n // reaches `onResumeRejected`.\n sendResume: (id, value) =>\n sendCommand({\n type: 'run/input',\n requestId: id,\n response: { type: 'resume', value },\n }),\n });\n\n const sendLaneDecisions = useCallback(\n (lanes: Readonly<Record<string, StatewireThread.InputResponse>>) =>\n requestId !== undefined\n ? resume({ lane_decisions: lanes } as unknown as TValue)\n : sendCommand({ type: 'run/lane-input', laneDecisions: lanes }),\n [requestId, resume, sendCommand],\n );\n\n const replayQueuedLanes = useCallback(\n (id: string) => sendCommand({ type: 'run/lane-replay', requestId: id }),\n [sendCommand],\n );\n\n return {\n request,\n requestId,\n hitl,\n actionRequests,\n liveHitl,\n liveActionRequests,\n queuedLaneDecisions,\n abandonedInterrupt,\n pending,\n resume,\n sendLaneDecisions,\n replayQueuedLanes,\n };\n}\n"],"names":[],"mappings":";;;;AAuDA,MAAM,2BAA8D,OAAO,OAAO,EAAE;AA6F7E,SAAS,4BAEd,UAA8C,IAAsC;;AACpF,QAAM;AAAA,IACJ,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB;AAAA,IACA;AAAA,EAAA,IACE;AACJ,QAAM,cAAc,wBAAA;AAGpB,QAAM,WAAU,sBAAA,EAAmB,kBAAnB,mBAAkC,KAAK;AACvD,QAAM,YAAY,mCAAS;AAK3B,QAAM,YAAY,kBAAkB,0BAA0B;AAC9D,QAAM,qBAAqB,uBAAuB,SAAS;AAE3D,QAAM,OAAO,eAAe,mCAAS,OAAO;AAC5C,QAAM,iBAAiB,QAAQ,MAAM,sBAAsB,IAAI,GAAG,CAAC,IAAI,CAAC;AAExE,QAAM,YAAY,iBAAA;AAIlB,QAAM,SAAS,kBAAkB,mBAAmB;AACpD,QAAM,WACJ,YAAY,UAAa,YAAY,eAAe,uBAAuB,MAAM,CAAC,IAAI;AACxF,QAAM,qBAAqB,QAAQ,MAAM,sBAAsB,QAAQ,GAAG,CAAC,QAAQ,CAAC;AACpF,QAAM,sBACJ,kBAAkB,uBAAuB,KAAK;AAEhD,QAAM,EAAE,SAAS,OAAA,IAAW,sBAA8B;AAAA,IACxD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA,YAAY,CAAC,IAAI,UACf,YAAY;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,MACX,UAAU,EAAE,MAAM,UAAU,MAAA;AAAA,IAAM,CACnC;AAAA,EAAA,CACJ;AAED,QAAM,oBAAoB;AAAA,IACxB,CAAC,UACC,cAAc,SACV,OAAO,EAAE,gBAAgB,MAAA,CAA4B,IACrD,YAAY,EAAE,MAAM,kBAAkB,eAAe,OAAO;AAAA,IAClE,CAAC,WAAW,QAAQ,WAAW;AAAA,EAAA;AAGjC,QAAM,oBAAoB;AAAA,IACxB,CAAC,OAAe,YAAY,EAAE,MAAM,mBAAmB,WAAW,IAAI;AAAA,IACtE,CAAC,WAAW;AAAA,EAAA;AAGd,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;"}
|
|
1
|
+
{"version":3,"file":"use-statewire-approval-request.js","sources":["../../src/chat/use-statewire-approval-request.ts"],"sourcesContent":["import type { StatewireThread } from '@assistant-ui/react-statewire';\nimport {\n useStatewireRuns,\n useStatewireSendCommand,\n useStatewireState,\n} from '@assistant-ui/react-statewire';\nimport {\n type AbandonedInputRequest,\n asHitlApproval,\n findAbandonedInterrupt,\n HITL_PENDING_RESUME_GRACE_MS,\n type HitlApprovalPayload,\n interruptMirrorPayload,\n isApprovalCardInterrupt,\n laneInterruptIds,\n type PendingActionRequest,\n pendingActionRequests,\n readAbandonedInputRequests,\n readInterruptMirror,\n readQueuedLaneDecisions,\n useApprovalResumeLock,\n} from '@athenaintel/agent-runtime';\nimport { useCallback, useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport { useAthenaRunLive } from './use-athena-run-live';\n\ndeclare module '@assistant-ui/core' {\n namespace Assistant {\n interface Commands {\n /**\n * Decide per-dispatch subagent lanes while the parent run is still\n * streaming (`DeepAgentThread.run_lane_input`). Keys are the lanes'\n * langgraph interrupt ids; the host matches them against the lanes its\n * mirrored interrupt currently parks, answers at once when the run is\n * already parked, and otherwise holds them until it parks — stale or\n * unknown ids are ignored, never carried to a later interrupt.\n */\n runLaneInput: {\n readonly type: 'run/lane-input';\n readonly laneDecisions: Readonly<Record<string, StatewireThread.InputResponse>>;\n };\n /**\n * Re-send the lane decisions the host still holds queued as their\n * approver's resume of the parked request (`DeepAgentThread.run_lane_replay`).\n * The host resumes under the meta the approver's `run/lane-input`\n * recorded and refuses any other caller — every attached client reads\n * the same queue, and only the one that queued it may turn it into a\n * resume. Carries no decisions: the host replays what it recorded.\n */\n runLaneReplay: {\n readonly type: 'run/lane-replay';\n readonly requestId: string;\n };\n }\n }\n}\n\nconst NO_QUEUED_LANE_DECISIONS: Readonly<Record<string, unknown>> = Object.freeze({});\nconst NO_ACTION_REQUESTS: PendingActionRequest[] = [];\n\n/**\n * Lane ids of the parked requests this client resumed, keyed by request id\n * and shared by every hook instance on the page (approval card,\n * waiting-on-you banner, host editors) so all of them treat a lingering\n * mirror the same way. Request ids are unique per parked interrupt, so an\n * instance only ever consults the record of the request it saw parked: two\n * chats mounted side by side cannot suppress or clear each other's. A record\n * is retired once the host drops that request's mirror (the resume run\n * started), the surface sees a different request park, or it unmounts.\n */\nconst answeredRequests = new Map<string, readonly string[]>();\nconst answeredListeners = new Set<() => void>();\nlet answeredVersion = 0;\nfunction notifyAnswered(): void {\n answeredVersion += 1;\n for (const listener of answeredListeners) listener();\n}\nfunction recordAnswered(requestId: string, laneIds: readonly string[]): void {\n answeredRequests.set(requestId, laneIds);\n notifyAnswered();\n}\nfunction forgetAnswered(requestId: string): void {\n if (answeredRequests.delete(requestId)) notifyAnswered();\n}\nfunction subscribeAnswered(listener: () => void): () => void {\n answeredListeners.add(listener);\n return () => {\n answeredListeners.delete(listener);\n };\n}\nconst readAnsweredVersion = (): number => answeredVersion;\n\n/**\n * The lanes a resume of the parked request settles: every lane of the request\n * (a resume answers the whole park — lanes already queued through\n * `run/lane-input` ride along) plus any lane named in the `lane_decisions` map.\n */\nfunction answeredLaneIds(value: unknown, actionRequests: readonly PendingActionRequest[]): string[] {\n const ids = laneInterruptIds(actionRequests) ?? [];\n if (typeof value === 'object' && value !== null && 'lane_decisions' in value) {\n const lanes = (value as { lane_decisions: unknown }).lane_decisions;\n if (typeof lanes === 'object' && lanes !== null) {\n for (const id of Object.keys(lanes)) if (!ids.includes(id)) ids.push(id);\n }\n }\n return ids;\n}\n\n/**\n * Whether the host's mirror still shows an interrupt this client already\n * answered. After `run/input` the host drops the parked request at once but\n * keeps `__interrupt__` until the resume run starts and clears it (seconds on\n * a cold checkpoint); without this check the card would re-offer the SAME\n * approval from the mirror, buttons live, and then fold it away again.\n */\nfunction mirrorAlreadyAnswered(\n answeredLanes: readonly string[] | undefined,\n liveActionRequests: readonly PendingActionRequest[],\n): boolean {\n if (answeredLanes === undefined) return false;\n const ids = laneInterruptIds(liveActionRequests);\n if (ids === null) return false;\n return ids.every((id) => answeredLanes.includes(id));\n}\n\n/** Selects which pending interrupt an approval surface answers. */\nexport type StatewireInterruptPredicate = (\n request: StatewireThread.InputRequestState,\n) => request is StatewireThread.CustomInputRequest;\n\nexport interface UseStatewireApprovalRequestOptions {\n /**\n * Which pending interrupt to answer. Defaults to `isApprovalCardInterrupt`\n * (client-tool parks excluded — the client-tool bridge owns those, and a\n * generic resume would corrupt the parked tool call).\n */\n interruptPredicate?: StatewireInterruptPredicate;\n /**\n * How long a sent decision keeps the actions locked when no resume run ever\n * starts. Defaults to {@link HITL_PENDING_RESUME_GRACE_MS}.\n */\n pendingResumeGraceMs?: number;\n /**\n * The host refused the `run/input` (or the transport lost it): the\n * optimistic fold rolls back, the request is on screen again with its\n * actions re-enabled, and this is the surface's one chance to say why.\n */\n onResumeRejected?: (error: unknown, requestId: string) => void;\n /** See {@link UseApprovalResumeLockOptions.onResumeRetry}. */\n onResumeRetry?: (error: unknown, requestId: string, attempt: number) => void;\n}\n\nexport interface StatewireApprovalRequest<TValue> {\n /** The pending interrupt this surface answers, if any. */\n request: StatewireThread.CustomInputRequest | undefined;\n requestId: string | undefined;\n /** The payload narrowed to the Athena HITL approval shape, or `null`. */\n hitl: HitlApprovalPayload | null;\n /** Every gated call the approval covers, in decision order (empty for non-HITL parks). */\n actionRequests: PendingActionRequest[];\n /** An interrupt a non-resume dispatch dropped — the \"approval was cancelled\" notice. */\n abandonedInterrupt: AbandonedInputRequest | undefined;\n /**\n * The mirrored interrupt's HITL payload while the run is still live and no\n * input request is answerable: per-dispatch `task` lanes parked on their\n * gates while sibling lanes stream. `null` once the run parks (the same\n * lanes are then `hitl` / `actionRequests`) and when nothing is parked.\n */\n liveHitl: HitlApprovalPayload | null;\n /** Every gated call `liveHitl` covers (empty when it is `null`). */\n liveActionRequests: PendingActionRequest[];\n /**\n * The decisions the host already holds from a `run/lane-input`, keyed by\n * langgraph interrupt id, to be answered when the run parks — a queued lane\n * reads as decided on every attached client, not just the one that sent it.\n */\n queuedLaneDecisions: Readonly<Record<string, unknown>>;\n /** True after a resume until the request identity changes (or recovery fires). */\n pending: boolean;\n /**\n * Answer the request with `{ type: 'run/input', requestId, response: { type: 'resume', value } }`.\n * Returns the dispatch promise (settles when the host accepts, rejects when\n * it refuses), or `undefined` when the lock dropped the send.\n */\n resume: (value: TValue) => Promise<unknown> | undefined;\n /**\n * Decide per-dispatch lanes by langgraph interrupt id. With a pending\n * request this is the native `lane_decisions` resume through the lock;\n * without one (the run is still streaming siblings) it is `run/lane-input`,\n * which the host queues and answers on the park. Returns the dispatch\n * promise, or `undefined` when the lock dropped a resume.\n */\n sendLaneDecisions: (\n lanes: Readonly<Record<string, StatewireThread.InputResponse>>,\n ) => Promise<unknown> | undefined;\n /**\n * Ask the host to resume the parked `requestId` with the lane decisions it\n * still holds queued, as their approver (`run/lane-replay`). For the card\n * that queued them, after the host's own answerer has stayed silent past\n * its budget; the host refuses every other caller. Settles when the host\n * accepts, rejects when it refuses.\n */\n replayQueuedLanes: (requestId: string) => Promise<unknown>;\n}\n\n/**\n * The headless half of every statewire approval surface: selects the pending\n * interrupt from the runs projection, narrows its payload, reads the\n * host-published abandoned interrupts, and wires the shared optimistic resume\n * lock to the thread's `run/input` command. `StatewireApprovalCard` renders\n * over it; hosts with their own decision UI (per-lane subagent cards) build\n * on it directly so the selection and lock semantics cannot drift.\n *\n * Requires a statewire aui scope (throws outside one, like every\n * `useStatewire*` hook) — gate the mount with `hasStatewireThreadExtras`.\n */\nexport function useStatewireApprovalRequest<\n TValue extends StatewireThread.InputResponse = Record<string, string>,\n>(options: UseStatewireApprovalRequestOptions = {}): StatewireApprovalRequest<TValue> {\n const {\n interruptPredicate = isApprovalCardInterrupt,\n pendingResumeGraceMs = HITL_PENDING_RESUME_GRACE_MS,\n onResumeRejected,\n onResumeRetry,\n } = options;\n const sendCommand = useStatewireSendCommand();\n // The runs projection is memoized by the lib, so this derivation is\n // reference-stable between state updates.\n const request = useStatewireRuns().inputRequests?.find(interruptPredicate);\n const requestId = request?.id;\n\n // The host publishes the interrupts a non-resume dispatch dropped. Select\n // the raw array reference (pre-stream-safe) and derive inline; a `.find`\n // selector would return a fresh object every update.\n const abandoned = useStatewireState(readAbandonedInputRequests);\n const abandonedInterrupt = findAbandonedInterrupt(abandoned);\n\n const hitl = asHitlApproval(request?.payload);\n const actionRequests = useMemo(() => pendingActionRequests(hitl), [hitl]);\n\n const isRunning = useAthenaRunLive();\n // The host mirrors the interrupt into state as soon as a lane parks — while\n // the run manager still reports `running` (siblings streaming) and has no\n // request to answer. Raw reference selectors; derive inline.\n const mirror = useStatewireState(readInterruptMirror);\n const mirrorHitl =\n request === undefined && isRunning ? asHitlApproval(interruptMirrorPayload(mirror)) : null;\n const mirrorActionRequests = useMemo(() => pendingActionRequests(mirrorHitl), [mirrorHitl]);\n\n // The request this surface last saw parked: the only record it may read\n // or retire (the mirror it watches is the one that request's resume clears).\n const lastRequestIdRef = useRef<string>(undefined);\n if (requestId !== undefined) lastRequestIdRef.current = requestId;\n useSyncExternalStore(subscribeAnswered, readAnsweredVersion, readAnsweredVersion);\n const answeredLanes =\n lastRequestIdRef.current === undefined ? undefined : answeredRequests.get(lastRequestIdRef.current);\n const mirrorCleared = interruptMirrorPayload(mirror) === undefined;\n useEffect(() => {\n if (requestId === undefined) return;\n return () => {\n // A different request parks next (or this one unparks for good): the\n // record of this one is stale once it is not the one on screen.\n if (lastRequestIdRef.current !== requestId) forgetAnswered(requestId);\n };\n }, [requestId]);\n useEffect(() => {\n if (mirrorCleared && lastRequestIdRef.current !== undefined) forgetAnswered(lastRequestIdRef.current);\n }, [mirrorCleared]);\n useEffect(\n () => () => {\n if (lastRequestIdRef.current !== undefined) forgetAnswered(lastRequestIdRef.current);\n },\n [],\n );\n const liveHitl = mirrorAlreadyAnswered(answeredLanes, mirrorActionRequests) ? null : mirrorHitl;\n const liveActionRequests = liveHitl === mirrorHitl ? mirrorActionRequests : NO_ACTION_REQUESTS;\n const queuedLaneDecisions =\n useStatewireState(readQueuedLaneDecisions) ?? NO_QUEUED_LANE_DECISIONS;\n\n const { pending, resume: resumeLocked } = useApprovalResumeLock<TValue>({\n requestId,\n isRunning,\n pendingResumeGraceMs,\n onResumeRejected,\n onResumeRetry,\n // The dispatch promise is handed to the lock: a refusal releases it and\n // reaches `onResumeRejected`.\n sendResume: (id, value) =>\n sendCommand({\n type: 'run/input',\n requestId: id,\n response: { type: 'resume', value },\n }),\n });\n\n const resume = useCallback(\n (value: TValue) => {\n if (requestId !== undefined) {\n recordAnswered(requestId, answeredLaneIds(value, actionRequests));\n }\n return resumeLocked(value);\n },\n [requestId, actionRequests, resumeLocked],\n );\n\n const sendLaneDecisions = useCallback(\n (lanes: Readonly<Record<string, StatewireThread.InputResponse>>) =>\n requestId !== undefined\n ? resume({ lane_decisions: lanes } as unknown as TValue)\n : sendCommand({ type: 'run/lane-input', laneDecisions: lanes }),\n [requestId, resume, sendCommand],\n );\n\n const replayQueuedLanes = useCallback(\n (id: string) => sendCommand({ type: 'run/lane-replay', requestId: id }),\n [sendCommand],\n );\n\n return {\n request,\n requestId,\n hitl,\n actionRequests,\n liveHitl,\n liveActionRequests,\n queuedLaneDecisions,\n abandonedInterrupt,\n pending,\n resume,\n sendLaneDecisions,\n replayQueuedLanes,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const core = require("@tiptap/core");
|
|
4
|
+
const model = require("@tiptap/pm/model");
|
|
5
|
+
const markdownStorage = require("../markdown-storage.cjs");
|
|
6
|
+
const composerMarkdown = require("../../agent-runtime/src/composer-markdown.cjs");
|
|
7
|
+
function serializeComposerMessage(editor) {
|
|
8
|
+
const storage = markdownStorage.getMarkdownStorage(editor);
|
|
9
|
+
const serializer = storage.serializer;
|
|
10
|
+
if (!isTiptapMarkdownSerializer(serializer)) {
|
|
11
|
+
return storage.getMarkdown();
|
|
12
|
+
}
|
|
13
|
+
return verbatimTextSerializer(serializer).serialize(editor.state.doc);
|
|
14
|
+
}
|
|
15
|
+
const isRecord = (value) => typeof value === "object" && value !== null;
|
|
16
|
+
function isTiptapMarkdownSerializer(value) {
|
|
17
|
+
if (!isRecord(value) || typeof Reflect.get(value, "serialize") !== "function") return false;
|
|
18
|
+
const nodes = Reflect.get(value, "nodes");
|
|
19
|
+
return isRecord(nodes) && typeof nodes.text === "function";
|
|
20
|
+
}
|
|
21
|
+
const writeTextVerbatim = (state, node) => {
|
|
22
|
+
state.text(node.text ?? "", false);
|
|
23
|
+
};
|
|
24
|
+
function writeLineBreak(draftLineBreak) {
|
|
25
|
+
return (state, node, parent, index) => {
|
|
26
|
+
if (state.inTable) {
|
|
27
|
+
draftLineBreak(state, node, parent, index);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (let next = index + 1; next < parent.childCount; next++) {
|
|
31
|
+
if (parent.child(next).type !== node.type) {
|
|
32
|
+
state.write("\n");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function verbatimTextSerializer(serializer) {
|
|
39
|
+
const nodes = serializer.nodes;
|
|
40
|
+
const draftLineBreak = nodes.hardBreak;
|
|
41
|
+
return Object.create(serializer, {
|
|
42
|
+
nodes: {
|
|
43
|
+
value: {
|
|
44
|
+
...nodes,
|
|
45
|
+
text: writeTextVerbatim,
|
|
46
|
+
...draftLineBreak && { hardBreak: writeLineBreak(draftLineBreak) }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function escapeBareUnderscores(text) {
|
|
52
|
+
let escaped = "";
|
|
53
|
+
let backslashes = 0;
|
|
54
|
+
for (const character of text) {
|
|
55
|
+
if (character === "_" && backslashes % 2 === 0) escaped += "\\";
|
|
56
|
+
escaped += character;
|
|
57
|
+
backslashes = character === "\\" ? backslashes + 1 : 0;
|
|
58
|
+
}
|
|
59
|
+
return escaped;
|
|
60
|
+
}
|
|
61
|
+
const CHARACTER_REFERENCE_AMPERSAND = /&(?=(?:[A-Za-z][A-Za-z0-9]*|#[0-9]+|#[xX][0-9A-Fa-f]+);)/g;
|
|
62
|
+
function escapeCharacterReferences(text) {
|
|
63
|
+
return text.replace(CHARACTER_REFERENCE_AMPERSAND, "&");
|
|
64
|
+
}
|
|
65
|
+
function writeTextForDraft(draftText) {
|
|
66
|
+
return (state, node, parent, index) => {
|
|
67
|
+
if (state.inAutolink) {
|
|
68
|
+
state.text(node.text ?? "", false);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const typed = node.text ?? "";
|
|
72
|
+
const referencesKept = escapeCharacterReferences(typed);
|
|
73
|
+
const textNode = referencesKept === typed ? node : node.type.schema.text(referencesKept, node.marks);
|
|
74
|
+
const escapeText = state.esc;
|
|
75
|
+
state.esc = (text, startOfLine) => escapeBareUnderscores(escapeText.call(state, text, startOfLine));
|
|
76
|
+
try {
|
|
77
|
+
draftText(state, textNode, parent, index);
|
|
78
|
+
} finally {
|
|
79
|
+
state.esc = escapeText;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function draftTextSerializer(serializer) {
|
|
84
|
+
const nodes = serializer.nodes;
|
|
85
|
+
const draftText = nodes.text;
|
|
86
|
+
if (!draftText) return serializer;
|
|
87
|
+
return Object.create(serializer, {
|
|
88
|
+
nodes: { value: { ...nodes, text: writeTextForDraft(draftText) } }
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
const LINE_START_REFERENCES = { " ": " ", " ": "	" };
|
|
92
|
+
const STAND_IN_CANDIDATES = [
|
|
93
|
+
" ",
|
|
94
|
+
" ",
|
|
95
|
+
" ",
|
|
96
|
+
" ",
|
|
97
|
+
" ",
|
|
98
|
+
" ",
|
|
99
|
+
" ",
|
|
100
|
+
" ",
|
|
101
|
+
" ",
|
|
102
|
+
" ",
|
|
103
|
+
" ",
|
|
104
|
+
" ",
|
|
105
|
+
" ",
|
|
106
|
+
" "
|
|
107
|
+
];
|
|
108
|
+
function standInsFor(doc) {
|
|
109
|
+
const held = JSON.stringify(doc.toJSON());
|
|
110
|
+
const [space, tab] = STAND_IN_CANDIDATES.filter((candidate) => !held.includes(candidate));
|
|
111
|
+
return space !== void 0 && tab !== void 0 ? { " ": space, " ": tab } : null;
|
|
112
|
+
}
|
|
113
|
+
const isLineStartWhitespace = (character) => character === " " || character === " ";
|
|
114
|
+
function withLineStandIns({
|
|
115
|
+
textblock,
|
|
116
|
+
standIns
|
|
117
|
+
}) {
|
|
118
|
+
const { schema } = textblock.type;
|
|
119
|
+
const lineBreak = schema.linebreakReplacement;
|
|
120
|
+
const isBlank = (child) => child.isText ? !/\S/.test(child.text ?? "") : child.type === lineBreak;
|
|
121
|
+
let blank = true;
|
|
122
|
+
textblock.forEach((child) => {
|
|
123
|
+
blank && (blank = isBlank(child));
|
|
124
|
+
});
|
|
125
|
+
if (blank) return { node: textblock, replaced: 0 };
|
|
126
|
+
const children = [];
|
|
127
|
+
let replaced = 0;
|
|
128
|
+
let atLineStart = true;
|
|
129
|
+
textblock.forEach((child) => {
|
|
130
|
+
const lineStart = atLineStart;
|
|
131
|
+
atLineStart = child.type === lineBreak;
|
|
132
|
+
const text = child.isText ? child.text ?? "" : "";
|
|
133
|
+
const first = text.charAt(0);
|
|
134
|
+
if (lineStart && isLineStartWhitespace(first) && !child.marks.some((mark) => mark.type.spec.code)) {
|
|
135
|
+
replaced += 1;
|
|
136
|
+
children.push(schema.text(standIns[first] + text.slice(1), child.marks));
|
|
137
|
+
} else {
|
|
138
|
+
children.push(child);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
return replaced > 0 ? { node: textblock.copy(model.Fragment.from(children)), replaced } : { node: textblock, replaced: 0 };
|
|
142
|
+
}
|
|
143
|
+
function withLeadingWhitespaceStandIns({
|
|
144
|
+
doc,
|
|
145
|
+
standIns
|
|
146
|
+
}) {
|
|
147
|
+
let replaced = 0;
|
|
148
|
+
const map = (node) => {
|
|
149
|
+
if (node.isTextblock) {
|
|
150
|
+
if (node.type.spec.code) return node;
|
|
151
|
+
const lines = withLineStandIns({ textblock: node, standIns });
|
|
152
|
+
replaced += lines.replaced;
|
|
153
|
+
return lines.node;
|
|
154
|
+
}
|
|
155
|
+
if (node.isLeaf) return node;
|
|
156
|
+
const children = [];
|
|
157
|
+
let changed = false;
|
|
158
|
+
node.forEach((child) => {
|
|
159
|
+
const mapped2 = map(child);
|
|
160
|
+
changed || (changed = mapped2 !== child);
|
|
161
|
+
children.push(mapped2);
|
|
162
|
+
});
|
|
163
|
+
return changed ? node.copy(model.Fragment.from(children)) : node;
|
|
164
|
+
};
|
|
165
|
+
const mapped = map(doc);
|
|
166
|
+
return { doc: mapped, replaced };
|
|
167
|
+
}
|
|
168
|
+
function serializeComposerDraft(editor) {
|
|
169
|
+
const storage = markdownStorage.getMarkdownStorage(editor);
|
|
170
|
+
const serializer = storage.serializer;
|
|
171
|
+
if (!isTiptapMarkdownSerializer(serializer)) return storage.getMarkdown();
|
|
172
|
+
const draft = draftTextSerializer(serializer);
|
|
173
|
+
const source = editor.state.doc;
|
|
174
|
+
const standIns = standInsFor(source);
|
|
175
|
+
if (standIns === null) return draft.serialize(source);
|
|
176
|
+
const lines = withLeadingWhitespaceStandIns({ doc: source, standIns });
|
|
177
|
+
if (lines.replaced === 0) return draft.serialize(source);
|
|
178
|
+
const written = draft.serialize(lines.doc);
|
|
179
|
+
const references = /* @__PURE__ */ new Map([
|
|
180
|
+
[standIns[" "], LINE_START_REFERENCES[" "]],
|
|
181
|
+
[standIns[" "], LINE_START_REFERENCES[" "]]
|
|
182
|
+
]);
|
|
183
|
+
const characters = Array.from(written);
|
|
184
|
+
const standInCount = characters.filter((character) => references.has(character)).length;
|
|
185
|
+
if (standInCount !== lines.replaced) return draft.serialize(source);
|
|
186
|
+
return characters.map((character) => references.get(character) ?? character).join("");
|
|
187
|
+
}
|
|
188
|
+
const LINE_START_WHITESPACE_REFERENCES = new Set(
|
|
189
|
+
Object.values(LINE_START_REFERENCES)
|
|
190
|
+
);
|
|
191
|
+
const KEPT_WHITESPACE_TOKEN = "athena_kept_whitespace";
|
|
192
|
+
const COLLAPSIBLE_WHITESPACE = /[ \t]{2,}|\t/g;
|
|
193
|
+
const keptWhitespace = (whitespace) => `<athena-whitespace style="white-space: pre-wrap">${whitespace}</athena-whitespace>`;
|
|
194
|
+
const draftWhitespaceParsers = /* @__PURE__ */ new WeakSet();
|
|
195
|
+
function keepDraftWhitespace(markdownit) {
|
|
196
|
+
if (draftWhitespaceParsers.has(markdownit)) return;
|
|
197
|
+
draftWhitespaceParsers.add(markdownit);
|
|
198
|
+
markdownit.core.ruler.before("text_join", "athena_kept_whitespace", (state) => {
|
|
199
|
+
for (const block of state.tokens) {
|
|
200
|
+
const inline = block.children ?? [];
|
|
201
|
+
inline.forEach((token, index) => {
|
|
202
|
+
var _a;
|
|
203
|
+
if (token.type !== "text_special" || token.info !== "entity") return;
|
|
204
|
+
if (!LINE_START_WHITESPACE_REFERENCES.has(token.markup)) return;
|
|
205
|
+
token.type = KEPT_WHITESPACE_TOKEN;
|
|
206
|
+
const next = inline[index + 1];
|
|
207
|
+
if ((next == null ? void 0 : next.type) !== "text") return;
|
|
208
|
+
const run = ((_a = /^[ \t]*/.exec(next.content)) == null ? void 0 : _a[0]) ?? "";
|
|
209
|
+
token.content += run;
|
|
210
|
+
next.content = next.content.slice(run.length);
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
const { rules } = markdownit.renderer;
|
|
215
|
+
rules[KEPT_WHITESPACE_TOKEN] = (tokens, index) => {
|
|
216
|
+
var _a;
|
|
217
|
+
return keptWhitespace(((_a = tokens[index]) == null ? void 0 : _a.content) ?? "");
|
|
218
|
+
};
|
|
219
|
+
for (const name of ["text", "code_inline"]) {
|
|
220
|
+
const render = rules[name];
|
|
221
|
+
if (!render) continue;
|
|
222
|
+
rules[name] = (...args) => render(...args).replace(COLLAPSIBLE_WHITESPACE, keptWhitespace);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const ComposerDraftWhitespace = core.Extension.create({
|
|
226
|
+
name: "athenaComposerDraftWhitespace",
|
|
227
|
+
addStorage() {
|
|
228
|
+
return { markdown: { parse: { setup: keepDraftWhitespace } } };
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
function captureComposerSend(editor) {
|
|
232
|
+
return {
|
|
233
|
+
text: serializeComposerMessage(editor).trim(),
|
|
234
|
+
draftMarkdown: composerMarkdown.trimComposerDraft(serializeComposerDraft(editor))
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
const REMEMBERED_SENDS = 50;
|
|
238
|
+
const RETURNED_SEND_WINDOW_MS = 6e4;
|
|
239
|
+
const sends = /* @__PURE__ */ new Map();
|
|
240
|
+
const sendKey = ({ threadId, text }) => JSON.stringify([threadId, text]);
|
|
241
|
+
const isFresh = (send, now) => now - send.sentAt <= RETURNED_SEND_WINDOW_MS;
|
|
242
|
+
function rememberComposerSend({
|
|
243
|
+
threadId,
|
|
244
|
+
text,
|
|
245
|
+
draftMarkdown,
|
|
246
|
+
now = Date.now()
|
|
247
|
+
}) {
|
|
248
|
+
const key = sendKey({ threadId, text });
|
|
249
|
+
const remembered = sends.get(key);
|
|
250
|
+
sends.delete(key);
|
|
251
|
+
const collides = remembered !== void 0 && isFresh(remembered, now) && remembered.draft !== draftMarkdown;
|
|
252
|
+
sends.set(key, { draft: collides ? null : draftMarkdown, sentAt: now });
|
|
253
|
+
while (sends.size > REMEMBERED_SENDS) {
|
|
254
|
+
const oldest = sends.keys().next();
|
|
255
|
+
if (oldest.done) break;
|
|
256
|
+
sends.delete(oldest.value);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function draftForReturnedSend({
|
|
260
|
+
threadId,
|
|
261
|
+
text,
|
|
262
|
+
now = Date.now()
|
|
263
|
+
}) {
|
|
264
|
+
const remembered = sends.get(sendKey({ threadId, text }));
|
|
265
|
+
return remembered !== void 0 && isFresh(remembered, now) ? remembered.draft : null;
|
|
266
|
+
}
|
|
267
|
+
function prepareComposerSend({
|
|
268
|
+
threadId,
|
|
269
|
+
text,
|
|
270
|
+
draftMarkdown
|
|
271
|
+
}) {
|
|
272
|
+
rememberComposerSend({ threadId, text, draftMarkdown });
|
|
273
|
+
composerMarkdown.stageComposerMarkdown({ threadId, text, markdown: draftMarkdown });
|
|
274
|
+
}
|
|
275
|
+
exports.ComposerDraftWhitespace = ComposerDraftWhitespace;
|
|
276
|
+
exports.RETURNED_SEND_WINDOW_MS = RETURNED_SEND_WINDOW_MS;
|
|
277
|
+
exports.captureComposerSend = captureComposerSend;
|
|
278
|
+
exports.draftForReturnedSend = draftForReturnedSend;
|
|
279
|
+
exports.escapeCharacterReferences = escapeCharacterReferences;
|
|
280
|
+
exports.prepareComposerSend = prepareComposerSend;
|
|
281
|
+
exports.rememberComposerSend = rememberComposerSend;
|
|
282
|
+
exports.serializeComposerDraft = serializeComposerDraft;
|
|
283
|
+
exports.serializeComposerMessage = serializeComposerMessage;
|
|
284
|
+
//# sourceMappingURL=composer-message.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composer-message.cjs","sources":["../../../src/chat-ui/composer/composer-message.ts"],"sourcesContent":["import { stageComposerMarkdown, trimComposerDraft } from \"@athenaintel/agent-runtime\";\nimport { type Editor, Extension } from \"@tiptap/core\";\nimport { Fragment, type Node as ProseMirrorNode } from \"@tiptap/pm/model\";\nimport { getMarkdownStorage } from \"../markdown-storage\";\n\n/**\n * The composer's draft as it is sent: its Markdown with every plain-text run\n * written exactly as it was typed. The Olympus chat composer sends the same\n * way (`olympus/src/components/textbox/composer-message-markdown.ts`).\n *\n * `getMarkdown()` escapes plain text for Markdown: prosemirror-markdown's\n * `esc()` puts a backslash before `` ` * \\ ~ [ ] _ `` (and before `#`, `-`,\n * `+`, `>` and `1.` at the start of a line), and tiptap-markdown's text\n * serializer turns `<` and `>` into `<` and `>`. That is right for a\n * draft, which is parsed back, but the sent text is what the model reads, and\n * it reads it literally: `C:\\Users` arrived as `C:\\\\Users`, `arr[0]` as\n * `arr\\[0\\]` and `List<T>` as `List<T>`. A line break typed with\n * Shift+Enter is Markdown's hard break, `\\` before the newline, in the draft;\n * it goes out as the newline alone.\n *\n * Only the plain-text runs and line breaks change. Formatting still\n * serializes as Markdown (bold, italic, strike, inline code, code blocks,\n * lists, headings, links, tables), mention chips still write their `[@Name](url)`\n * links, and code spans and blocks were never escaped.\n */\nexport function serializeComposerMessage(editor: Editor): string {\n const storage = getMarkdownStorage(editor);\n const serializer: unknown = storage.serializer;\n if (!isTiptapMarkdownSerializer(serializer)) {\n // A tiptap-markdown upgrade that reshaped its serializer: keep sending (the\n // escaped draft) rather than fail the send. The tests pin the verbatim\n // output, so such an upgrade fails CI before it ships.\n return storage.getMarkdown();\n }\n return verbatimTextSerializer(serializer).serialize(editor.state.doc);\n}\n\n/** What prosemirror-markdown's serializer state offers a node serializer, as far as text goes. */\ninterface MarkdownSerializerState {\n /** Writes `text`, escaping it for Markdown unless `escapeMarkdown` is `false`. */\n text(text: string, escapeMarkdown?: boolean): void;\n /** The escape `text()` applies to each line (prosemirror-markdown 1.13's `esc()`). */\n esc(text: string, startOfLine?: boolean): string;\n /** Writes `content` as is, after the enclosing blocks' line prefix when a line starts. */\n write(content?: string): void;\n /** True while a table serializer writes a table. */\n readonly inTable?: boolean;\n /**\n * True while prosemirror-markdown writes a link whose text is its URL as an\n * autolink (`<https://…>`), where Markdown reads no backslash escapes.\n */\n readonly inAutolink?: boolean;\n}\n\ntype MarkdownNodeSerializer = (\n state: MarkdownSerializerState,\n node: ProseMirrorNode,\n parent: ProseMirrorNode,\n index: number,\n) => void;\n\n/**\n * The slice of tiptap-markdown 0.9.0's `MarkdownSerializer` this module uses.\n * `nodes` is a getter mapping every schema node type to its Markdown spec's\n * `serialize`, and `serialize(doc)` builds the serializer state from\n * `this.nodes` and `this.marks`, so an object whose prototype is the editor's\n * serializer and whose own `nodes` replaces `text` and `hardBreak` serializes\n * everything else exactly as `getMarkdown()` does.\n */\ninterface TiptapMarkdownSerializer {\n readonly nodes: Readonly<Record<string, MarkdownNodeSerializer | undefined>>;\n serialize(content: ProseMirrorNode): string;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nfunction isTiptapMarkdownSerializer(value: unknown): value is TiptapMarkdownSerializer {\n if (!isRecord(value) || typeof Reflect.get(value, \"serialize\") !== \"function\") return false;\n const nodes: unknown = Reflect.get(value, \"nodes\");\n return isRecord(nodes) && typeof nodes.text === \"function\";\n}\n\nconst writeTextVerbatim: MarkdownNodeSerializer = (state, node) => {\n state.text(node.text ?? \"\", false);\n};\n\n/**\n * A hard break as a plain newline. The draft's serializer (tiptap-markdown's\n * `hard-break.js`) keeps the rest: it writes nothing for a break with only\n * breaks after it, and inside a table, where a cell holds one line, it writes\n * a `<br>` tag.\n */\nfunction writeLineBreak(draftLineBreak: MarkdownNodeSerializer): MarkdownNodeSerializer {\n return (state, node, parent, index) => {\n if (state.inTable) {\n draftLineBreak(state, node, parent, index);\n return;\n }\n for (let next = index + 1; next < parent.childCount; next++) {\n if (parent.child(next).type !== node.type) {\n state.write(\"\\n\");\n return;\n }\n }\n };\n}\n\nfunction verbatimTextSerializer(serializer: TiptapMarkdownSerializer): TiptapMarkdownSerializer {\n const nodes = serializer.nodes;\n const draftLineBreak = nodes.hardBreak;\n return Object.create(serializer, {\n nodes: {\n value: {\n ...nodes,\n text: writeTextVerbatim,\n ...(draftLineBreak && { hardBreak: writeLineBreak(draftLineBreak) }),\n },\n },\n });\n}\n\n/**\n * `text` with every underscore that is not already escaped escaped:\n * prosemirror-markdown's `esc()` leaves an underscore between two word\n * characters bare, and an underscore after an odd run of backslashes is one it\n * escaped itself.\n */\nfunction escapeBareUnderscores(text: string): string {\n let escaped = \"\";\n let backslashes = 0;\n for (const character of text) {\n if (character === \"_\" && backslashes % 2 === 0) escaped += \"\\\\\";\n escaped += character;\n backslashes = character === \"\\\\\" ? backslashes + 1 : 0;\n }\n return escaped;\n}\n\n/**\n * An `&` that starts a character reference (`<`, `©`, `<`,\n * `<`): Markdown decodes those, so typed `<` read back as `<`.\n */\nconst CHARACTER_REFERENCE_AMPERSAND = /&(?=(?:[A-Za-z][A-Za-z0-9]*|#[0-9]+|#[xX][0-9A-Fa-f]+);)/g;\n\n/** `text` with every `&` that starts a character reference written `&`, which reads back as `&`. */\nexport function escapeCharacterReferences(text: string): string {\n return text.replace(CHARACTER_REFERENCE_AMPERSAND, \"&\");\n}\n\n/**\n * The draft's text serializer with every underscore escaped. `esc()` leaves an\n * underscore between word characters bare, so `obj.__init__` was written\n * `obj.\\__init_\\_` and read back as `obj._` + italic `init` + `_` (markdown-it\n * opens emphasis on the inner pair). Every underscore in a text node is typed\n * text (emphasis is a mark, written with `*`), so escaping all of them keeps\n * the round trip exact. Code is written raw and never reaches `esc()`. A typed\n * character reference keeps its `&` too (`&lt;`), so `<` reads back as\n * typed instead of as `<`; tiptap-markdown turns `<` and `>` into `<` and\n * `>` only after that.\n *\n * The text of an autolink (`<https://…>`, a link whose text is its URL) is\n * written raw. Markdown reads no escapes there, so `getMarkdown()`'s own\n * escaping (tiptap-markdown escapes it like any text) read a URL with `~`, `*`\n * or `[` back as another address, and an escaped underscore would too.\n */\nfunction writeTextForDraft(draftText: MarkdownNodeSerializer): MarkdownNodeSerializer {\n return (state, node, parent, index) => {\n if (state.inAutolink) {\n state.text(node.text ?? \"\", false);\n return;\n }\n const typed: string = node.text ?? \"\";\n const referencesKept: string = escapeCharacterReferences(typed);\n const textNode: ProseMirrorNode =\n referencesKept === typed ? node : node.type.schema.text(referencesKept, node.marks);\n const escapeText = state.esc;\n state.esc = (text, startOfLine) =>\n escapeBareUnderscores(escapeText.call(state, text, startOfLine));\n try {\n draftText(state, textNode, parent, index);\n } finally {\n state.esc = escapeText;\n }\n };\n}\n\nfunction draftTextSerializer(serializer: TiptapMarkdownSerializer): TiptapMarkdownSerializer {\n const nodes = serializer.nodes;\n const draftText = nodes.text;\n if (!draftText) return serializer;\n return Object.create(serializer, {\n nodes: { value: { ...nodes, text: writeTextForDraft(draftText) } },\n });\n}\n\n/**\n * What a line's first space or tab is written as in the draft. Agent-runtime's\n * `isComposerMarkdownOfText` and agora's `is_composer_markdown_of_text` decode\n * the same two references.\n */\nconst LINE_START_REFERENCES = { \" \": \" \", \"\\t\": \"	\" } as const;\n\ntype LineStartWhitespace = keyof typeof LINE_START_REFERENCES;\n\n/** The characters standing in for a line's first space and tab while one draft is written. */\ntype LineStartStandIns = Readonly<Record<LineStartWhitespace, string>>;\n\n/**\n * Characters that can stand in for a line's first space or tab while the draft\n * is written: each is whitespace to the serializer (`\\s`), which moves it out\n * of bold and italic like a space, as the sent text does, and none is a space\n * or tab itself. A draft uses two its document does not already hold.\n */\nconst STAND_IN_CANDIDATES: readonly string[] = [\n \" \",\n \" \",\n \" \",\n \" \",\n \" \",\n \" \",\n \" \",\n \" \",\n \" \",\n \" \",\n \" \",\n \" \",\n \" \",\n \" \",\n];\n\n/** Two stand-ins `doc` holds nowhere (text or attributes); `null` in the unlikely case it holds them all. */\nfunction standInsFor(doc: ProseMirrorNode): LineStartStandIns | null {\n const held: string = JSON.stringify(doc.toJSON());\n const [space, tab] = STAND_IN_CANDIDATES.filter((candidate) => !held.includes(candidate));\n return space !== undefined && tab !== undefined ? { \" \": space, \"\\t\": tab } : null;\n}\n\nconst isLineStartWhitespace = (character: string): character is LineStartWhitespace =>\n character === \" \" || character === \"\\t\";\n\n/**\n * `textblock` with the first space or tab of each of its lines replaced by its\n * stand-in, and how many it replaced. A line is the textblock's start or what\n * follows a line break; its whitespace is in the text there (not in code,\n * which Markdown keeps as written). A block of nothing but whitespace is left\n * as it is: Markdown reads it as a blank line, as before, and a composer\n * holding only spaces stays empty to every `trim()`.\n */\nfunction withLineStandIns({\n textblock,\n standIns,\n}: {\n textblock: ProseMirrorNode;\n standIns: LineStartStandIns;\n}): {\n node: ProseMirrorNode;\n replaced: number;\n} {\n const { schema } = textblock.type;\n const lineBreak = schema.linebreakReplacement;\n const isBlank = (child: ProseMirrorNode): boolean =>\n child.isText ? !/\\S/.test(child.text ?? \"\") : child.type === lineBreak;\n let blank = true;\n textblock.forEach((child) => {\n blank &&= isBlank(child);\n });\n if (blank) return { node: textblock, replaced: 0 };\n\n const children: ProseMirrorNode[] = [];\n let replaced = 0;\n let atLineStart = true;\n textblock.forEach((child) => {\n const lineStart: boolean = atLineStart;\n atLineStart = child.type === lineBreak;\n const text: string = child.isText ? (child.text ?? \"\") : \"\";\n const first: string = text.charAt(0);\n if (\n lineStart &&\n isLineStartWhitespace(first) &&\n !child.marks.some((mark) => mark.type.spec.code)\n ) {\n replaced += 1;\n children.push(schema.text(standIns[first] + text.slice(1), child.marks));\n } else {\n children.push(child);\n }\n });\n return replaced > 0\n ? { node: textblock.copy(Fragment.from(children)), replaced }\n : { node: textblock, replaced: 0 };\n}\n\n/**\n * `doc` with the first space or tab of every line in its text replaced by its\n * stand-in, and how many it replaced (see {@link serializeComposerDraft}).\n */\nfunction withLeadingWhitespaceStandIns({\n doc,\n standIns,\n}: {\n doc: ProseMirrorNode;\n standIns: LineStartStandIns;\n}): {\n doc: ProseMirrorNode;\n replaced: number;\n} {\n let replaced = 0;\n const map = (node: ProseMirrorNode): ProseMirrorNode => {\n if (node.isTextblock) {\n if (node.type.spec.code) return node;\n const lines = withLineStandIns({ textblock: node, standIns });\n replaced += lines.replaced;\n return lines.node;\n }\n if (node.isLeaf) return node;\n const children: ProseMirrorNode[] = [];\n let changed = false;\n node.forEach((child) => {\n const mapped = map(child);\n changed ||= mapped !== child;\n children.push(mapped);\n });\n return changed ? node.copy(Fragment.from(children)) : node;\n };\n const mapped = map(doc);\n return { doc: mapped, replaced };\n}\n\n/**\n * The composer's draft: Markdown that reads back into the same document, as\n * the Olympus chat composer writes it\n * (`olympus/src/components/textbox/composer-message-markdown.ts`).\n * `getMarkdown()`, except that every underscore in plain text is escaped, a\n * typed character reference keeps its `&`, and an autolink's URL is written\n * raw (see {@link writeTextForDraft}), and the first space or tab of a line is\n * written as a character reference. The composer mirrors its draft into the\n * composer runtime, remembers a send's draft and attaches it to the message\n * (`metadata.composer_markdown`) in this form.\n *\n * Markdown drops the whitespace a line starts with (four spaces or a tab even\n * start a code block), so pasted code came back without its indentation. The\n * first space or tab of each line is written ` ` / `	` instead, which\n * Markdown reads back as that character in the line's text; the rest of the\n * run is no longer at the line's start, and the composer's parser keeps it\n * ({@link ComposerDraftWhitespace}). The draft is written with a stand-in for\n * each, a character the document holds nowhere else ({@link standInsFor}),\n * that becomes the reference afterwards; should the serializer ever write a\n * different number of them, the draft is written without them.\n */\nexport function serializeComposerDraft(editor: Editor): string {\n const storage = getMarkdownStorage(editor);\n const serializer: unknown = storage.serializer;\n if (!isTiptapMarkdownSerializer(serializer)) return storage.getMarkdown();\n const draft = draftTextSerializer(serializer);\n const source: ProseMirrorNode = editor.state.doc;\n const standIns = standInsFor(source);\n if (standIns === null) return draft.serialize(source);\n const lines = withLeadingWhitespaceStandIns({ doc: source, standIns });\n if (lines.replaced === 0) return draft.serialize(source);\n const written: string = draft.serialize(lines.doc);\n const references = new Map<string, string>([\n [standIns[\" \"], LINE_START_REFERENCES[\" \"]],\n [standIns[\"\\t\"], LINE_START_REFERENCES[\"\\t\"]],\n ]);\n const characters: string[] = Array.from(written);\n const standInCount: number = characters.filter((character) => references.has(character)).length;\n if (standInCount !== lines.replaced) return draft.serialize(source);\n return characters.map((character) => references.get(character) ?? character).join(\"\");\n}\n\n/** The slice of a markdown-it token {@link keepDraftWhitespace} reads and rewrites. */\ninterface MarkdownItToken {\n type: string;\n info: string;\n markup: string;\n content: string;\n children: MarkdownItToken[] | null;\n}\n\ntype MarkdownItRenderRule = (tokens: MarkdownItToken[], index: number, ...rest: unknown[]) => string;\n\n/** The slice of markdown-it (the instance tiptap-markdown parses with) {@link keepDraftWhitespace} configures. */\ninterface MarkdownIt {\n core: {\n ruler: {\n before(\n beforeName: string,\n ruleName: string,\n rule: (state: { tokens: MarkdownItToken[] }) => void,\n ): void;\n };\n };\n renderer: { rules: Record<string, MarkdownItRenderRule | undefined> };\n}\n\nconst LINE_START_WHITESPACE_REFERENCES: ReadonlySet<string> = new Set(\n Object.values(LINE_START_REFERENCES),\n);\n\nconst KEPT_WHITESPACE_TOKEN = \"athena_kept_whitespace\";\n\n/** Whitespace ProseMirror's parser would collapse into one space: a run of two or more, or a tab. */\nconst COLLAPSIBLE_WHITESPACE = /[ \\t]{2,}|\\t/g;\n\n/**\n * `whitespace` in an element ProseMirror's parser keeps the whitespace of\n * (`white-space: pre-wrap` is what it reads as \"preserve\"). No node or mark\n * parses the tag, so its text joins the text around it.\n */\nconst keptWhitespace = (whitespace: string): string =>\n `<athena-whitespace style=\"white-space: pre-wrap\">${whitespace}</athena-whitespace>`;\n\nconst draftWhitespaceParsers = new WeakSet<MarkdownIt>();\n\n/**\n * Markdown read into the composer keeps the spaces and tabs in its text, as\n * the Olympus chat composer's parser does (`ComposerVerbatimTextPaste`).\n * markdown-it keeps a run of spaces inside a line, but ProseMirror's DOM parser\n * collapsed it to one space, and a tab to a space. The draft writes a line's\n * first space or tab as ` ` / `	` ({@link serializeComposerDraft});\n * that reference and the whitespace after it, every other run and every tab\n * are rendered in an element that keeps them. Any other single space stays as\n * Markdown reads it, so a task list's space after its checkbox still goes.\n */\nfunction keepDraftWhitespace(markdownit: MarkdownIt): void {\n if (draftWhitespaceParsers.has(markdownit)) return;\n draftWhitespaceParsers.add(markdownit);\n // Before `text_join`, which folds references back into the text around them.\n markdownit.core.ruler.before(\"text_join\", \"athena_kept_whitespace\", (state) => {\n for (const block of state.tokens) {\n const inline: MarkdownItToken[] = block.children ?? [];\n inline.forEach((token, index) => {\n if (token.type !== \"text_special\" || token.info !== \"entity\") return;\n if (!LINE_START_WHITESPACE_REFERENCES.has(token.markup)) return;\n token.type = KEPT_WHITESPACE_TOKEN;\n const next: MarkdownItToken | undefined = inline[index + 1];\n if (next?.type !== \"text\") return;\n const run: string = /^[ \\t]*/.exec(next.content)?.[0] ?? \"\";\n token.content += run;\n next.content = next.content.slice(run.length);\n });\n }\n });\n const { rules } = markdownit.renderer;\n rules[KEPT_WHITESPACE_TOKEN] = (tokens, index) => keptWhitespace(tokens[index]?.content ?? \"\");\n for (const name of [\"text\", \"code_inline\"]) {\n const render: MarkdownItRenderRule | undefined = rules[name];\n if (!render) continue;\n rules[name] = (...args) => render(...args).replace(COLLAPSIBLE_WHITESPACE, keptWhitespace);\n }\n}\n\n/**\n * The composer's own Markdown reading: a draft restored into it (a returned\n * send, {@link draftForReturnedSend}) keeps its whitespace\n * ({@link keepDraftWhitespace}). The message bubbles read with the chat\n * schema alone.\n */\nexport const ComposerDraftWhitespace = Extension.create({\n name: \"athenaComposerDraftWhitespace\",\n addStorage() {\n return { markdown: { parse: { setup: keepDraftWhitespace } } };\n },\n});\n\n/** What one send captured: the text it delivers and the draft Markdown that text came from. */\nexport interface ComposerSend {\n /** Plain text exactly as typed, formatting as Markdown: what the model reads. */\n readonly text: string;\n /** The same document as a draft ({@link serializeComposerDraft}). */\n readonly draftMarkdown: string;\n}\n\n/**\n * The editor's draft as one send would deliver it, both forms trimmed (the\n * draft as agent-runtime's `trimComposerDraft` trims it, so the ` ` a\n * first line starts with goes with the space the text loses).\n */\nexport function captureComposerSend(editor: Editor): ComposerSend {\n return {\n text: serializeComposerMessage(editor).trim(),\n draftMarkdown: trimComposerDraft(serializeComposerDraft(editor)),\n };\n}\n\n/** How many sends {@link rememberComposerSend} keeps the draft of. */\nconst REMEMBERED_SENDS = 50;\n\n/**\n * How long a send's draft stays restorable. Statewire hands a refused send\n * back while it reconnects, soon after the send; past this window a matching\n * text is a host's own write (`useAppendToComposer`), parsed as Markdown.\n */\nexport const RETURNED_SEND_WINDOW_MS = 60_000;\n\ninterface RememberedSend {\n /** `null` once two different drafts sent the same text in the thread. */\n readonly draft: string | null;\n readonly sentAt: number;\n}\n\n/**\n * A sent text in a thread → the draft Markdown it was serialized from, newest\n * last. The draft is withheld once two different drafts sent the same text in\n * that thread within the window: literal `**strong**` and bold `strong` both\n * send `**strong**`, and the text alone cannot say which message is which.\n */\nconst sends = new Map<string, RememberedSend>();\n\nconst sendKey = ({ threadId, text }: { threadId: string; text: string }): string =>\n JSON.stringify([threadId, text]);\n\nconst isFresh = (send: RememberedSend, now: number): boolean =>\n now - send.sentAt <= RETURNED_SEND_WINDOW_MS;\n\n/**\n * Remember the draft behind a sent text, so a send that comes back to the\n * composer (statewire puts a send it refuses during a reconnect back into an\n * empty composer) is restored from the draft it was sent from rather than\n * parsed from its verbatim text, where Markdown would read a backslash before\n * punctuation, a tag-like `<x>` or `2*3*4` differently.\n */\nexport function rememberComposerSend({\n threadId,\n text,\n draftMarkdown,\n now = Date.now(),\n}: {\n threadId: string;\n text: string;\n draftMarkdown: string;\n /** Test seam: the time of the send. */\n now?: number;\n}): void {\n const key = sendKey({ threadId, text });\n const remembered = sends.get(key);\n sends.delete(key);\n const collides =\n remembered !== undefined && isFresh(remembered, now) && remembered.draft !== draftMarkdown;\n sends.set(key, { draft: collides ? null : draftMarkdown, sentAt: now });\n while (sends.size > REMEMBERED_SENDS) {\n const oldest = sends.keys().next();\n if (oldest.done) break;\n sends.delete(oldest.value);\n }\n}\n\n/**\n * The draft to load for a text that came back to an empty composer: the draft\n * this composer sent it from within {@link RETURNED_SEND_WINDOW_MS}, when that\n * is the only draft that sent this text in the thread; else `null`, and the\n * text is parsed as Markdown (a host's prefill, a send from before a reload).\n */\nexport function draftForReturnedSend({\n threadId,\n text,\n now = Date.now(),\n}: {\n threadId: string;\n text: string;\n /** Test seam: the time the text came back. */\n now?: number;\n}): string | null {\n const remembered = sends.get(sendKey({ threadId, text }));\n return remembered !== undefined && isFresh(remembered, now) ? remembered.draft : null;\n}\n\n/** Test seam: forget every remembered send. */\nexport function resetRememberedComposerSends(): void {\n sends.clear();\n}\n\n/**\n * Get a send ready right before the composer runtime sends its `text`:\n * remember its draft, so a send statewire hands back is restored from it\n * ({@link rememberComposerSend}), and stage the draft as the message's composer\n * markdown (`metadata.composer_markdown`, only when it differs from the text),\n * which the runtime's `getMessageMetadata` (agent-runtime's\n * `withStagedComposerMarkdown`) puts on the submission that follows, as the\n * Olympus composer does.\n */\nexport function prepareComposerSend({\n threadId,\n text,\n draftMarkdown,\n}: {\n threadId: string;\n} & ComposerSend): void {\n rememberComposerSend({ threadId, text, draftMarkdown });\n stageComposerMarkdown({ threadId, text, markdown: draftMarkdown });\n}\n"],"names":["getMarkdownStorage","Fragment","mapped","Extension","trimComposerDraft","stageComposerMarkdown"],"mappings":"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"}
|