@mgamadeus/ddd-agents 0.0.1-stage → 0.1.0-alpha.22
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 +11 -3
- package/dist/chat.js +5263 -0
- package/dist/chat.js.map +1 -0
- package/dist/chunks/AgentsConversationClientContext-C4T7g_Qk.js +22 -0
- package/dist/chunks/AgentsConversationClientContext-C4T7g_Qk.js.map +1 -0
- package/dist/chunks/ConversationMarkdown-W7NHglmL.js +399 -0
- package/dist/chunks/ConversationMarkdown-W7NHglmL.js.map +1 -0
- package/dist/chunks/WebSearchResultsConversationWidget-BvnLWHyi.js +5059 -0
- package/dist/chunks/WebSearchResultsConversationWidget-BvnLWHyi.js.map +1 -0
- package/dist/chunks/canvas-behaviours-BRFR1ALE.js +45 -0
- package/dist/chunks/canvas-behaviours-BRFR1ALE.js.map +1 -0
- package/dist/chunks/canvas-feature-flags-BmmxC3bz.js +11 -0
- package/dist/chunks/canvas-feature-flags-BmmxC3bz.js.map +1 -0
- package/dist/chunks/canvasBodies-9SuF6NAB.js +289 -0
- package/dist/chunks/canvasBodies-9SuF6NAB.js.map +1 -0
- package/dist/chunks/d3-7.6.1.min.js-DTmPafrl.js +6 -0
- package/dist/chunks/d3-7.6.1.min.js-DTmPafrl.js.map +1 -0
- package/dist/chunks/decide-canvas-open-Ct-wnNEJ.js +20 -0
- package/dist/chunks/decide-canvas-open-Ct-wnNEJ.js.map +1 -0
- package/dist/chunks/widget-image-readiness-signal-DeOuL89j.js +25 -0
- package/dist/chunks/widget-image-readiness-signal-DeOuL89j.js.map +1 -0
- package/dist/chunks/widget-name-resolver-DyIY6Zu4.js +9736 -0
- package/dist/chunks/widget-name-resolver-DyIY6Zu4.js.map +1 -0
- package/dist/chunks/withPollingChangeSubscription-BLDAWF-o.js +251 -0
- package/dist/chunks/withPollingChangeSubscription-BLDAWF-o.js.map +1 -0
- package/dist/client-testing.js +346 -0
- package/dist/client-testing.js.map +1 -0
- package/dist/client.js +16 -0
- package/dist/client.js.map +1 -0
- package/dist/contract.js +31 -0
- package/dist/contract.js.map +1 -0
- package/dist/image-render.js +334 -0
- package/dist/image-render.js.map +1 -0
- package/dist/index.js +80 -0
- package/dist/index.js.map +1 -0
- package/dist/kit.js +13 -0
- package/dist/kit.js.map +1 -0
- package/dist/preview.js +733 -0
- package/dist/preview.js.map +1 -0
- package/dist/renderer.js +115 -0
- package/dist/renderer.js.map +1 -0
- package/dist/styles.css +6768 -0
- package/dist/types/chat/AgentChat/AgentChat.d.ts +37 -0
- package/dist/types/chat/AgentChatActivityHistory/AgentChatActivityHistory.d.ts +6 -0
- package/dist/types/chat/AgentChatActivityIndicator/AgentChatActivityIndicator.d.ts +8 -0
- package/dist/types/chat/CanvasPane/CanvasPane.d.ts +15 -0
- package/dist/types/chat/CanvasResizeHandle/CanvasResizeHandle.d.ts +10 -0
- package/dist/types/chat/CanvasResizeHandle/use-canvas-resize.d.ts +43 -0
- package/dist/types/chat/ConversationClosedBar/ConversationClosedBar.d.ts +10 -0
- package/dist/types/chat/ConversationErrorCard/ConversationErrorCard.d.ts +13 -0
- package/dist/types/chat/ConversationIntroCard/ConversationIntroCard.d.ts +10 -0
- package/dist/types/chat/ConversationLoadingStates.d.ts +2 -0
- package/dist/types/chat/ConversationMessage/ConversationCallMarkerChip/ConversationCallMarkerChip.d.ts +14 -0
- package/dist/types/chat/ConversationMessage/ConversationCallMarkerChip/VoiceBarsIcon/VoiceBarsIcon.d.ts +8 -0
- package/dist/types/chat/ConversationMessage/ConversationMessageSystem/ConversationMessageSystem.d.ts +8 -0
- package/dist/types/chat/ConversationMessage/ConversationMessageSystem/ConversationMessageSystemHeader/ConversationMessageSystemHeader.d.ts +9 -0
- package/dist/types/chat/ConversationMessage/ConversationMessageUser/ConversationMessageUser.d.ts +7 -0
- package/dist/types/chat/ConversationMessage/ConversationMessageUser/ConversationMessageUserWidgets.d.ts +14 -0
- package/dist/types/chat/ConversationMessage/ConversationMessageWidgets/ConversationMessageHeader/ConversationMessageHeader.d.ts +7 -0
- package/dist/types/chat/ConversationMessage/ConversationMessageWidgets/ConversationMessageThinking/ConversationMessageThinking.d.ts +7 -0
- package/dist/types/chat/ConversationMessage/ConversationMessageWidgets/ConversationMessageWidgets.d.ts +29 -0
- package/dist/types/chat/ConversationMessage/ConversationMessageWidgets/copyRichToClipboard.d.ts +1 -0
- package/dist/types/chat/ConversationMessage/ConversationMessageWidgets/hooks/useFreshMessageBlockReveal.d.ts +14 -0
- package/dist/types/chat/ConversationMessage/ConversationMessageWidgets/hooks/useStreamingText.d.ts +8 -0
- package/dist/types/chat/ConversationMessage/ConversationMessageWidgets/hooks/useTypewriter.d.ts +12 -0
- package/dist/types/chat/ConversationMessage/ConversationTaskInstructionDisclosure/ConversationTaskInstructionDisclosure.d.ts +12 -0
- package/dist/types/chat/ConversationMessageInput/ConversationMessageInput.d.ts +111 -0
- package/dist/types/chat/ConversationMessageInput/ConversationMessageInputAttachments/ConversationMessageInputAttachmentPreviewCard.d.ts +34 -0
- package/dist/types/chat/ConversationMessageInput/ConversationMessageInputAttachments/ConversationMessageInputAttachmentsErrorBox.d.ts +22 -0
- package/dist/types/chat/ConversationMessageInput/ConversationMessageInputAttachments/ConversationMessageInputAttachmentsPreviewStrip.d.ts +12 -0
- package/dist/types/chat/ConversationMessageInput/ConversationMessageInputAttachments/convert-bytes-to-size-string.d.ts +2 -0
- package/dist/types/chat/ConversationMessageInput/ConversationMessageInputComposerWidgets/ConversationMessageInputComposerWidgets.d.ts +12 -0
- package/dist/types/chat/ConversationMessageList/ConversationMessageList.d.ts +75 -0
- package/dist/types/chat/ConversationScrollToLatestMessageButton/ConversationScrollToLatestMessageButton.d.ts +6 -0
- package/dist/types/chat/ConversationSuggestionCard/ConversationSuggestionCard.d.ts +7 -0
- package/dist/types/chat/ConversationView.d.ts +216 -0
- package/dist/types/chat/ConversationViewBody/ConversationViewBody.d.ts +214 -0
- package/dist/types/chat/ConversationViewBody/hooks/useIsMessagesBottomOutOfView.d.ts +2 -0
- package/dist/types/chat/ConversationViewBody/hooks/usePinQuestionOnSend.d.ts +24 -0
- package/dist/types/chat/assistant-message-has-renderable-markdown.d.ts +13 -0
- package/dist/types/chat/chat-assistant-identity.d.ts +24 -0
- package/dist/types/chat/chat-message.d.ts +11 -0
- package/dist/types/chat/controller/AgentChatController.d.ts +97 -0
- package/dist/types/chat/controller/activity-ticker.d.ts +120 -0
- package/dist/types/chat/controller/changed-messages-request.d.ts +12 -0
- package/dist/types/chat/controller/chat-scroll-target.d.ts +10 -0
- package/dist/types/chat/controller/conversation-change-signal-rules.d.ts +64 -0
- package/dist/types/chat/controller/derive-agent-activity.d.ts +31 -0
- package/dist/types/chat/controller/merge-activity-elements.d.ts +25 -0
- package/dist/types/chat/controller/pending-start-request.d.ts +38 -0
- package/dist/types/chat/controller/use-activity-ticker.d.ts +60 -0
- package/dist/types/chat/controller/use-conversation-activity.d.ts +38 -0
- package/dist/types/chat/controller/use-conversation-live-updates.d.ts +30 -0
- package/dist/types/chat/controller/use-conversation-message-pages.d.ts +24 -0
- package/dist/types/chat/controller/use-conversation-scroll-jump.d.ts +47 -0
- package/dist/types/chat/controller/use-conversation-search.d.ts +31 -0
- package/dist/types/chat/controller/use-conversation-signals.d.ts +44 -0
- package/dist/types/chat/controller/use-debounced-semantic-search.d.ts +15 -0
- package/dist/types/chat/conversation-send-message.d.ts +43 -0
- package/dist/types/chat/last-wire-message-is-unanswered-user-message.d.ts +22 -0
- package/dist/types/chat/normalize-server-message-to-markdown.d.ts +23 -0
- package/dist/types/chat/store/agents-chat-state.d.ts +132 -0
- package/dist/types/chat/store/conversation-error-type.d.ts +32 -0
- package/dist/types/chat/store/create-agents-chat-store.d.ts +23 -0
- package/dist/types/chat/store/index.d.ts +5 -0
- package/dist/types/chat/store/merge-chat-messages.d.ts +20 -0
- package/dist/types/chat/store/reduce-agents-chat-state.d.ts +7 -0
- package/dist/types/chat/store/use-agents-chat-store.d.ts +22 -0
- package/dist/types/chat/strip-pre-call-message-marker.d.ts +12 -0
- package/dist/types/chat/use-canvas-shell-transitions.d.ts +25 -0
- package/dist/types/client/AgentsConversationClient.d.ts +93 -0
- package/dist/types/client/AgentsConversationClientContext.d.ts +17 -0
- package/dist/types/client/polling/createPollingConversationChangeSubscription.d.ts +62 -0
- package/dist/types/client/polling/withPollingChangeSubscription.d.ts +11 -0
- package/dist/types/client/testing/createInMemoryAgentsConversationClient.d.ts +139 -0
- package/dist/types/contract/conversation.d.ts +370 -0
- package/dist/types/entries/chat.d.ts +21 -0
- package/dist/types/entries/client-testing.d.ts +1 -0
- package/dist/types/entries/client.d.ts +4 -0
- package/dist/types/entries/contract.d.ts +1 -0
- package/dist/types/entries/image-render.d.ts +9 -0
- package/dist/types/entries/index.d.ts +9 -0
- package/dist/types/entries/kit.d.ts +4 -0
- package/dist/types/entries/preview.d.ts +8 -0
- package/dist/types/entries/renderer.d.ts +15 -0
- package/dist/types/entries/widgets.d.ts +16 -0
- package/dist/types/image-render/ComposedViewEmailDataTimes/ComposedViewEmailDataTimes.d.ts +15 -0
- package/dist/types/image-render/WidgetImageRender.d.ts +55 -0
- package/dist/types/image-render/WidgetImageRenderContext.d.ts +14 -0
- package/dist/types/image-render/composed-view-data-times.d.ts +20 -0
- package/dist/types/image-render/frozen-widget-requests.d.ts +2 -0
- package/dist/types/image-render/live-widget-requests.d.ts +4 -0
- package/dist/types/image-render/widget-image-google-map.d.ts +7 -0
- package/dist/types/image-render/widget-image-readiness-signal.d.ts +16 -0
- package/dist/types/image-render/widget-image-readiness.d.ts +9 -0
- package/dist/types/image-render/widget-image-render.types.d.ts +47 -0
- package/dist/types/kit/ComposedViewConversationWidget.d.ts +14 -0
- package/dist/types/kit/ComposedViewDataSourceLoader.d.ts +20 -0
- package/dist/types/kit/ComposedViewRenderer.d.ts +30 -0
- package/dist/types/kit/ComposedViewSlotErrorBoundary.d.ts +23 -0
- package/dist/types/kit/ModelText/ModelText.d.ts +12 -0
- package/dist/types/kit/components/embedding/EmbeddedConversationWidget.d.ts +26 -0
- package/dist/types/kit/components/map/map-full-screen-instance.d.ts +26 -0
- package/dist/types/kit/components/map/map-presentation-context.d.ts +8 -0
- package/dist/types/kit/components/text/shared/text-node-values.d.ts +39 -0
- package/dist/types/kit/composed-view-component-types.d.ts +61 -0
- package/dist/types/kit/composed-view-components.d.ts +7 -0
- package/dist/types/kit/composed-view-tones.d.ts +20 -0
- package/dist/types/kit/entity-detail/EntityDetailCanvasBody.d.ts +9 -0
- package/dist/types/kit/entity-detail/entity-detail-bodies.d.ts +32 -0
- package/dist/types/kit/entity-detail/entity-detail-name.d.ts +9 -0
- package/dist/types/kit/hooks/use-debounced-value.d.ts +2 -0
- package/dist/types/kit/map-full-screen/MapFullScreenCanvasBody.d.ts +11 -0
- package/dist/types/preview/WidgetPreviewHost.d.ts +20 -0
- package/dist/types/preview/preview-stub-components.d.ts +3 -0
- package/dist/types/preview/widget-preview-fixtures.d.ts +17 -0
- package/dist/types/preview/widget-preview-hydration.d.ts +10 -0
- package/dist/types/preview/widget-preview-readiness.d.ts +27 -0
- package/dist/types/preview/widget-preview-requests.d.ts +16 -0
- package/dist/types/preview/widget-preview-signal.d.ts +10 -0
- package/dist/types/preview/widget-preview.types.d.ts +134 -0
- package/dist/types/provider/AgentsProvider.d.ts +33 -0
- package/dist/types/provider/class-names.d.ts +7 -0
- package/dist/types/provider/components/default-components.d.ts +3 -0
- package/dist/types/provider/components/icon-names.d.ts +9 -0
- package/dist/types/provider/components/index.d.ts +39 -0
- package/dist/types/provider/components/types.d.ts +463 -0
- package/dist/types/provider/environment.d.ts +262 -0
- package/dist/types/provider/index.d.ts +4 -0
- package/dist/types/renderer/ConversationDeepLinkedWidget.d.ts +18 -0
- package/dist/types/renderer/ConversationMarkdown.d.ts +21 -0
- package/dist/types/renderer/ConversationWidgetActions/ConversationWidgetActions.d.ts +7 -0
- package/dist/types/renderer/ConversationWidgetCallbacksContext.d.ts +234 -0
- package/dist/types/renderer/ConversationWidgetContext.d.ts +32 -0
- package/dist/types/renderer/ConversationWidgetErrorBoundary.d.ts +25 -0
- package/dist/types/renderer/ConversationWidgetHost.d.ts +36 -0
- package/dist/types/renderer/ConversationWidgetRenderContext.d.ts +3 -0
- package/dist/types/renderer/MarkdownLink.d.ts +6 -0
- package/dist/types/renderer/WindowedWidget/WindowedWidget.d.ts +16 -0
- package/dist/types/renderer/_access/ConversationWidgetFeatureGate.d.ts +21 -0
- package/dist/types/renderer/_agent-space/ConversationWidgetAgentSpaceFrame.d.ts +12 -0
- package/dist/types/renderer/_agent-space/ConversationWidgetAgentSpaceHeader.d.ts +15 -0
- package/dist/types/renderer/_agent-space/agent-space-name.hydrator.d.ts +7 -0
- package/dist/types/renderer/_agent-space/declared-agent-space-key-field-name.d.ts +8 -0
- package/dist/types/renderer/_agent-space/use-resolved-conversation-widget-agent-space-key.d.ts +16 -0
- package/dist/types/renderer/_agent-space/widget-agent-space-key-attribute.d.ts +13 -0
- package/dist/types/renderer/balanced-json-object.d.ts +12 -0
- package/dist/types/renderer/canvas/CanvasRestoreOnMount.d.ts +19 -0
- package/dist/types/renderer/canvas/canvas-behaviours.d.ts +84 -0
- package/dist/types/renderer/canvas/canvas-body-props.d.ts +18 -0
- package/dist/types/renderer/canvas/canvas-feature-flags.d.ts +11 -0
- package/dist/types/renderer/canvas/canvas-reducers.d.ts +46 -0
- package/dist/types/renderer/canvas/canvas-state.d.ts +107 -0
- package/dist/types/renderer/canvas/canvasBodies.d.ts +19 -0
- package/dist/types/renderer/canvas/canvasStorage.d.ts +25 -0
- package/dist/types/renderer/canvas/decide-canvas-open.d.ts +32 -0
- package/dist/types/renderer/canvas/entity-detail-instance.d.ts +27 -0
- package/dist/types/renderer/canvas/find-widget-fences-in-markdown.d.ts +32 -0
- package/dist/types/renderer/canvas/use-anchor-widget-payload.d.ts +8 -0
- package/dist/types/renderer/composer-widget-fence.d.ts +30 -0
- package/dist/types/renderer/conversation-composer-widget.d.ts +13 -0
- package/dist/types/renderer/conversation-widget-props.d.ts +54 -0
- package/dist/types/renderer/conversation-widget-state-partition.d.ts +31 -0
- package/dist/types/renderer/conversationWidgetAstPlugin.d.ts +11 -0
- package/dist/types/renderer/conversationWidgetRegistry.d.ts +74 -0
- package/dist/types/renderer/detect-unrendered-widgets.d.ts +42 -0
- package/dist/types/renderer/markdown-contains-widget.d.ts +13 -0
- package/dist/types/renderer/reference-naked-widget-json.d.ts +1 -0
- package/dist/types/renderer/remarkWidgetFencePlugin.d.ts +22 -0
- package/dist/types/renderer/render-report/widget-render-report-collector.d.ts +57 -0
- package/dist/types/renderer/render-report/widget-render-report.d.ts +29 -0
- package/dist/types/renderer/repair-malformed-widget-fences.d.ts +11 -0
- package/dist/types/renderer/resolve-deep-linkable-widget.d.ts +25 -0
- package/dist/types/renderer/restoreTextDirectivesPlugin.d.ts +12 -0
- package/dist/types/renderer/widget-click-signal-sources.d.ts +15 -0
- package/dist/types/renderer/widget-fence-json.d.ts +16 -0
- package/dist/types/renderer/widget-fence-syntax.d.ts +25 -0
- package/dist/types/renderer/widget-hydration/index.d.ts +8 -0
- package/dist/types/renderer/widget-hydration/section-hydration.d.ts +41 -0
- package/dist/types/renderer/widget-hydration/use-widget-hydration.d.ts +27 -0
- package/dist/types/renderer/widget-hydration/widget-hydration-state-store.d.ts +27 -0
- package/dist/types/renderer/widget-hydration/widget-hydration.reducer.d.ts +39 -0
- package/dist/types/renderer/widget-hydration/widget-hydration.registry.d.ts +7 -0
- package/dist/types/renderer/widget-hydration/widget-hydration.slice.d.ts +8 -0
- package/dist/types/renderer/widget-hydration/widget-hydration.types.d.ts +27 -0
- package/dist/types/renderer/widget-name-resolver.d.ts +22 -0
- package/dist/types/renderer/widget-tree/bounded-json.d.ts +23 -0
- package/dist/types/renderer/widget-tree/composed-node-schema.d.ts +143 -0
- package/dist/types/renderer/widget-tree/composed-view-data-sources.d.ts +41 -0
- package/dist/types/renderer/widget-tree/composed-view-tree.d.ts +111 -0
- package/dist/types/renderer/widget-tree/expression/evaluate-expression.d.ts +65 -0
- package/dist/types/renderer/widget-tree/expression/parse-expression.d.ts +71 -0
- package/dist/types/renderer/widget-tree/resolve-composed-view-values.d.ts +49 -0
- package/dist/types/renderer/widget-tree/use-composed-view-state.d.ts +16 -0
- package/dist/types/renderer/widget-windowing.d.ts +25 -0
- package/dist/types/widgets/CanvasWidgetCard/CanvasWidgetCard.d.ts +79 -0
- package/dist/types/widgets/CanvasWidgetCard/CanvasWidgetSwitch.d.ts +61 -0
- package/dist/types/widgets/CanvasWidgetCard/canvas-for-message-widget.d.ts +8 -0
- package/dist/types/widgets/CanvasWidgetCard/use-canvas-viable.d.ts +15 -0
- package/dist/types/widgets/ClockConversationWidget/ClockConversationWidget.d.ts +11 -0
- package/dist/types/widgets/ClockConversationWidget/ClockWidget/AnalogClockFace.d.ts +12 -0
- package/dist/types/widgets/ClockConversationWidget/ClockWidget/ClockRow.d.ts +23 -0
- package/dist/types/widgets/ClockConversationWidget/ClockWidget/ClockWidget.d.ts +21 -0
- package/dist/types/widgets/ClockConversationWidget/ClockWidget/DayNightGlyph.d.ts +8 -0
- package/dist/types/widgets/ClockConversationWidget/shared/clock-time.d.ts +52 -0
- package/dist/types/widgets/ClockConversationWidget/shared/clock-widget-payload.d.ts +23 -0
- package/dist/types/widgets/ClockConversationWidget/shared/use-clock-settings.d.ts +18 -0
- package/dist/types/widgets/ConceptExplainerConversationWidget/ConceptExplainerConversationWidget.d.ts +14 -0
- package/dist/types/widgets/ConceptExplainerConversationWidget/ConceptExplainerWidget/ConceptExplainerWidget.d.ts +27 -0
- package/dist/types/widgets/ConceptExplainerConversationWidget/shared/ConceptExplainerTextView.d.ts +11 -0
- package/dist/types/widgets/ConceptExplainerConversationWidget/shared/concept-explainer-type.d.ts +89 -0
- package/dist/types/widgets/ConceptExplainerConversationWidget/shared/concept-explainer-types.d.ts +17 -0
- package/dist/types/widgets/ConceptExplainerConversationWidget/shared/concept-explainer-widget-payload.d.ts +25 -0
- package/dist/types/widgets/ConceptExplainerConversationWidget/shared/use-concept-explainer-language.d.ts +8 -0
- package/dist/types/widgets/ConversationSearchResultsConversationWidget/ConversationSearchResultsCanvas.d.ts +9 -0
- package/dist/types/widgets/ConversationSearchResultsConversationWidget/ConversationSearchResultsCanvasBody.d.ts +7 -0
- package/dist/types/widgets/ConversationSearchResultsConversationWidget/ConversationSearchResultsConversationWidget.d.ts +15 -0
- package/dist/types/widgets/ConversationSearchResultsConversationWidget/shared/conversation-search-results-widget-payload.d.ts +42 -0
- package/dist/types/widgets/ConversationSearchResultsConversationWidget/shared/search-hit-excerpt.d.ts +1 -0
- package/dist/types/widgets/CurrencyConverterConversationWidget/CurrencyConverterConversationWidget.d.ts +8 -0
- package/dist/types/widgets/CurrencyConverterConversationWidget/CurrencyConverterWidget/CurrencyConverterWidget.d.ts +17 -0
- package/dist/types/widgets/CurrencyConverterConversationWidget/CurrencyConverterWidget/CurrencyLabel/CurrencyLabel.d.ts +9 -0
- package/dist/types/widgets/CurrencyConverterConversationWidget/shared/currency-converter-widget-payload.d.ts +22 -0
- package/dist/types/widgets/CurrencyConverterConversationWidget/shared/currency-display.d.ts +30 -0
- package/dist/types/widgets/CustomVisualizationConversationWidget/CustomVisualizationConversationWidget.d.ts +11 -0
- package/dist/types/widgets/CustomVisualizationConversationWidget/CustomVisualizationWidget/CustomVisualizationFrame.d.ts +14 -0
- package/dist/types/widgets/CustomVisualizationConversationWidget/CustomVisualizationWidget/CustomVisualizationWidget.d.ts +15 -0
- package/dist/types/widgets/CustomVisualizationConversationWidget/shared/custom-visualization-frame-protocol.d.ts +77 -0
- package/dist/types/widgets/CustomVisualizationConversationWidget/shared/custom-visualization-libraries.d.ts +25 -0
- package/dist/types/widgets/CustomVisualizationConversationWidget/shared/custom-visualization-sandbox-config.d.ts +21 -0
- package/dist/types/widgets/CustomVisualizationConversationWidget/shared/custom-visualization-widget-payload.d.ts +55 -0
- package/dist/types/widgets/CustomVisualizationConversationWidget/shared/read-custom-visualization-theme.d.ts +5 -0
- package/dist/types/widgets/EntityMentionConversationWidget/EntityMentionAskButton/EntityMentionAskButton.d.ts +13 -0
- package/dist/types/widgets/EntityMentionConversationWidget/EntityMentionCard/EntityMentionCard.d.ts +11 -0
- package/dist/types/widgets/EntityMentionConversationWidget/EntityMentionConversationWidget.d.ts +9 -0
- package/dist/types/widgets/EntityMentionConversationWidget/shared/entity-mention-presentation.d.ts +4 -0
- package/dist/types/widgets/EntityMentionConversationWidget/shared/entity-mention.d.ts +33 -0
- package/dist/types/widgets/EntityMentionConversationWidget/shared/use-entity-mention-composer.d.ts +17 -0
- package/dist/types/widgets/MultiChoiceConversationWidget/MultiChoiceConversationWidget.d.ts +2 -0
- package/dist/types/widgets/MultiChoiceConversationWidget/shared/multi-choice-widget-payload.d.ts +16 -0
- package/dist/types/widgets/QuickRepliesConversationWidget/QuickRepliesConversationWidget.d.ts +38 -0
- package/dist/types/widgets/QuickRepliesConversationWidget/shared/quick-replies-widget-payload.d.ts +20 -0
- package/dist/types/widgets/SuggestedActions/SuggestedActions.d.ts +10 -0
- package/dist/types/widgets/ToolTraceConversationWidget/ToolTraceConversationWidget.d.ts +8 -0
- package/dist/types/widgets/WebSearchResultsConversationWidget/SourceFavicon.d.ts +10 -0
- package/dist/types/widgets/WebSearchResultsConversationWidget/WebSearchAnswer.d.ts +6 -0
- package/dist/types/widgets/WebSearchResultsConversationWidget/WebSearchReferences.d.ts +12 -0
- package/dist/types/widgets/WebSearchResultsConversationWidget/WebSearchResultsCanvas.d.ts +10 -0
- package/dist/types/widgets/WebSearchResultsConversationWidget/WebSearchResultsCanvasBody.d.ts +7 -0
- package/dist/types/widgets/WebSearchResultsConversationWidget/WebSearchResultsConversationWidget.d.ts +14 -0
- package/dist/types/widgets/WebSearchResultsConversationWidget/WebSearchSourcesList.d.ts +10 -0
- package/dist/types/widgets/WebSearchResultsConversationWidget/shared/display-hostname.d.ts +9 -0
- package/dist/types/widgets/WebSearchResultsConversationWidget/shared/web-search-results-widget-payload.d.ts +30 -0
- package/dist/types/widgets/WritingDraftConversationWidget/WritingDraftConversationWidget.d.ts +14 -0
- package/dist/types/widgets/WritingDraftConversationWidget/WritingDraftWidget/WritingDraftBody.d.ts +9 -0
- package/dist/types/widgets/WritingDraftConversationWidget/WritingDraftWidget/WritingDraftWidget.d.ts +44 -0
- package/dist/types/widgets/WritingDraftConversationWidget/shared/draft-mail-link.d.ts +17 -0
- package/dist/types/widgets/WritingDraftConversationWidget/shared/draft-plain-text.d.ts +7 -0
- package/dist/types/widgets/WritingDraftConversationWidget/shared/remark-draft-line-breaks.d.ts +13 -0
- package/dist/types/widgets/WritingDraftConversationWidget/shared/writing-draft-widget-payload.d.ts +23 -0
- package/dist/types/widgets/_shared/ConversationWidgetButton.d.ts +4 -0
- package/dist/types/widgets/_shared/DonePill.d.ts +14 -0
- package/dist/types/widgets/_shared/modern/WidgetKpiValue.d.ts +24 -0
- package/dist/types/widgets/_shared/modern/WidgetListRow.d.ts +14 -0
- package/dist/types/widgets/_shared/modern/WidgetStatusChip.d.ts +8 -0
- package/dist/types/widgets/_shared/modern/WidgetSurface.d.ts +13 -0
- package/dist/types/widgets/_shared/modern/WidgetSurfaceSkeleton.d.ts +11 -0
- package/dist/types/widgets/_shared/modern/index.d.ts +16 -0
- package/dist/types/widgets/_shared/skeleton-primitives.d.ts +20 -0
- package/dist/types/widgets/_shared/use-stack-when-wrapped.d.ts +6 -0
- package/dist/types/widgets/_shared/widget-payload-validation.d.ts +22 -0
- package/dist/widgets.js +84 -0
- package/dist/widgets.js.map +1 -0
- package/package.json +120 -3
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { readConversationRunStatusOfRunState, CONVERSATION_RUN_STATES_THAT_END_THE_CONVERSATION, isAgentsClientError } from "../contract.js";
|
|
3
|
+
const POLLING_RUNNING_INTERVAL_MS = 2e3;
|
|
4
|
+
const POLLING_IDLE_INTERVAL_MS = 2e4;
|
|
5
|
+
const POLLING_MAX_BACKOFF_MS = 6e4;
|
|
6
|
+
const POLLING_LOCAL_ACTIVITY_WINDOW_MS = 1e4;
|
|
7
|
+
class GlobalPollingTimers {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.setTimeout = (callback, delayMs) => globalThis.setTimeout(callback, delayMs);
|
|
10
|
+
this.clearTimeout = (timerHandle) => globalThis.clearTimeout(timerHandle);
|
|
11
|
+
this.now = () => Date.now();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
class BrowserDocumentVisibility {
|
|
15
|
+
constructor(browserDocument) {
|
|
16
|
+
this.browserDocument = browserDocument;
|
|
17
|
+
this.isHidden = () => this.browserDocument.visibilityState === "hidden";
|
|
18
|
+
this.listen = (listener) => {
|
|
19
|
+
this.browserDocument.addEventListener("visibilitychange", listener);
|
|
20
|
+
return this.browserDocument.removeEventListener.bind(this.browserDocument, "visibilitychange", listener);
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const readPolledRunStatus = (conversation) => {
|
|
25
|
+
const runStatus = readConversationRunStatusOfRunState(conversation.runState);
|
|
26
|
+
return runStatus === "idle" && conversation.agentTurnOwedAt ? "running" : runStatus;
|
|
27
|
+
};
|
|
28
|
+
const readSubscriptionEndReasonOfReadFailure = (failure) => {
|
|
29
|
+
if (!isAgentsClientError(failure)) return null;
|
|
30
|
+
if (failure.kind === "notFound") return "gone";
|
|
31
|
+
if (failure.kind === "forbidden") return "forbidden";
|
|
32
|
+
return null;
|
|
33
|
+
};
|
|
34
|
+
class ConversationMetadataPoller {
|
|
35
|
+
constructor(conversationId, readMetadata, onSignal, onEnded, options, activePollers) {
|
|
36
|
+
this.conversationId = conversationId;
|
|
37
|
+
this.readMetadata = readMetadata;
|
|
38
|
+
this.onSignal = onSignal;
|
|
39
|
+
this.onEnded = onEnded;
|
|
40
|
+
this.options = options;
|
|
41
|
+
this.activePollers = activePollers;
|
|
42
|
+
this.isStopped = false;
|
|
43
|
+
this.isReading = false;
|
|
44
|
+
this.readAgainAfterCurrentRead = false;
|
|
45
|
+
this.timerHandle = null;
|
|
46
|
+
this.consecutiveFailedReads = 0;
|
|
47
|
+
this.changeCounter = 0;
|
|
48
|
+
this.summaryRevision = 0;
|
|
49
|
+
this.previousChangeFingerprint = null;
|
|
50
|
+
this.previousSummaryFingerprint = null;
|
|
51
|
+
this.runStatus = null;
|
|
52
|
+
this.hasConversationEnded = false;
|
|
53
|
+
this.runningIntervalUntil = 0;
|
|
54
|
+
this.stopListeningToVisibility = null;
|
|
55
|
+
this.start = () => {
|
|
56
|
+
this.activePollers.add(this);
|
|
57
|
+
this.stopListeningToVisibility = this.options.documentVisibility?.listen(this.receiveVisibilityChange) ?? null;
|
|
58
|
+
this.readNow();
|
|
59
|
+
};
|
|
60
|
+
this.stop = () => {
|
|
61
|
+
this.isStopped = true;
|
|
62
|
+
this.activePollers.delete(this);
|
|
63
|
+
this.clearTimer();
|
|
64
|
+
this.stopListeningToVisibility?.();
|
|
65
|
+
this.stopListeningToVisibility = null;
|
|
66
|
+
};
|
|
67
|
+
this.receiveLocalActivity = () => {
|
|
68
|
+
this.runningIntervalUntil = this.options.timers.now() + this.options.localActivityWindowMs;
|
|
69
|
+
this.readNow();
|
|
70
|
+
};
|
|
71
|
+
this.readNow = () => {
|
|
72
|
+
if (this.isStopped) return;
|
|
73
|
+
if (this.isReading) {
|
|
74
|
+
this.readAgainAfterCurrentRead = true;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
this.clearTimer();
|
|
78
|
+
this.isReading = true;
|
|
79
|
+
void this.readMetadataOnce();
|
|
80
|
+
};
|
|
81
|
+
this.readOnTimer = () => {
|
|
82
|
+
this.timerHandle = null;
|
|
83
|
+
this.readNow();
|
|
84
|
+
};
|
|
85
|
+
this.receiveVisibilityChange = () => {
|
|
86
|
+
if (this.isStopped) return;
|
|
87
|
+
if (this.options.documentVisibility?.isHidden()) {
|
|
88
|
+
this.clearTimer();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
this.readNow();
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
async readMetadataOnce() {
|
|
95
|
+
let conversation;
|
|
96
|
+
try {
|
|
97
|
+
conversation = await this.readMetadata(this.conversationId);
|
|
98
|
+
} catch (failure) {
|
|
99
|
+
this.isReading = false;
|
|
100
|
+
this.receiveReadFailure(failure);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
this.isReading = false;
|
|
104
|
+
if (this.isStopped) return;
|
|
105
|
+
this.consecutiveFailedReads = 0;
|
|
106
|
+
this.receiveConversation(conversation);
|
|
107
|
+
this.continueAfterRead(this.readIntervalMs());
|
|
108
|
+
}
|
|
109
|
+
receiveConversation(conversation) {
|
|
110
|
+
const runStatus = readPolledRunStatus(conversation);
|
|
111
|
+
const reportsLastMessageId = conversation.lastMessageId !== void 0;
|
|
112
|
+
const changeFingerprint = JSON.stringify([runStatus, conversation.lastMessageId ?? null, conversation.updated]);
|
|
113
|
+
const summaryFingerprint = JSON.stringify([conversation.title, conversation.summary]);
|
|
114
|
+
const isFirstRead = this.previousChangeFingerprint === null;
|
|
115
|
+
const hasChanged = changeFingerprint !== this.previousChangeFingerprint || !reportsLastMessageId && runStatus === "running";
|
|
116
|
+
const hasSummaryChanged = !isFirstRead && summaryFingerprint !== this.previousSummaryFingerprint;
|
|
117
|
+
if (!isFirstRead && hasChanged) this.changeCounter += 1;
|
|
118
|
+
if (hasSummaryChanged) this.summaryRevision += 1;
|
|
119
|
+
this.previousChangeFingerprint = changeFingerprint;
|
|
120
|
+
this.previousSummaryFingerprint = summaryFingerprint;
|
|
121
|
+
this.runStatus = runStatus;
|
|
122
|
+
this.hasConversationEnded = conversation.runState !== null && CONVERSATION_RUN_STATES_THAT_END_THE_CONVERSATION.includes(conversation.runState);
|
|
123
|
+
if (!isFirstRead && !hasChanged && !hasSummaryChanged) return;
|
|
124
|
+
this.onSignal({
|
|
125
|
+
changeCounter: this.changeCounter,
|
|
126
|
+
lastMessageId: conversation.lastMessageId ?? null,
|
|
127
|
+
runStatus,
|
|
128
|
+
summaryUpdatedAt: this.summaryRevision
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
receiveReadFailure(failure) {
|
|
132
|
+
if (this.isStopped) return;
|
|
133
|
+
const endReason = readSubscriptionEndReasonOfReadFailure(failure);
|
|
134
|
+
if (endReason !== null) {
|
|
135
|
+
this.stop();
|
|
136
|
+
this.onEnded(endReason);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
this.consecutiveFailedReads += 1;
|
|
140
|
+
const backoffMs = this.readIntervalMs() * 2 ** this.consecutiveFailedReads;
|
|
141
|
+
this.continueAfterRead(Math.min(backoffMs, this.options.maxBackoffMs));
|
|
142
|
+
}
|
|
143
|
+
continueAfterRead(nextReadDelayMs) {
|
|
144
|
+
if (this.readAgainAfterCurrentRead) {
|
|
145
|
+
this.readAgainAfterCurrentRead = false;
|
|
146
|
+
this.readNow();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (this.hasConversationEnded) return;
|
|
150
|
+
this.scheduleRead(nextReadDelayMs);
|
|
151
|
+
}
|
|
152
|
+
readIntervalMs() {
|
|
153
|
+
const isShortIntervalDue = this.runStatus === "running" || this.options.timers.now() < this.runningIntervalUntil;
|
|
154
|
+
return isShortIntervalDue ? this.options.runningIntervalMs : this.options.idleIntervalMs;
|
|
155
|
+
}
|
|
156
|
+
/** Arms the next read — not while the page is hidden; its return reads at once. */
|
|
157
|
+
scheduleRead(delayMs) {
|
|
158
|
+
this.clearTimer();
|
|
159
|
+
if (this.isStopped || this.options.documentVisibility?.isHidden()) return;
|
|
160
|
+
this.timerHandle = this.options.timers.setTimeout(this.readOnTimer, delayMs);
|
|
161
|
+
}
|
|
162
|
+
clearTimer() {
|
|
163
|
+
if (this.timerHandle === null) return;
|
|
164
|
+
this.options.timers.clearTimeout(this.timerHandle);
|
|
165
|
+
this.timerHandle = null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
class PollingConversationChangeSubscriptions {
|
|
169
|
+
constructor(readMetadata, options) {
|
|
170
|
+
this.readMetadata = readMetadata;
|
|
171
|
+
this.options = options;
|
|
172
|
+
this.activePollers = /* @__PURE__ */ new Set();
|
|
173
|
+
this.subscribeToConversationChanges = (conversationId, onSignal, onEnded) => {
|
|
174
|
+
const poller = new ConversationMetadataPoller(
|
|
175
|
+
conversationId,
|
|
176
|
+
this.readMetadata,
|
|
177
|
+
onSignal,
|
|
178
|
+
onEnded,
|
|
179
|
+
this.options,
|
|
180
|
+
this.activePollers
|
|
181
|
+
);
|
|
182
|
+
poller.start();
|
|
183
|
+
return poller.stop;
|
|
184
|
+
};
|
|
185
|
+
this.notifyLocalActivity = (conversationId) => {
|
|
186
|
+
for (const poller of [...this.activePollers]) {
|
|
187
|
+
if (poller.conversationId === conversationId) poller.receiveLocalActivity();
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const readDefaultDocumentVisibility = () => typeof document === "undefined" ? null : new BrowserDocumentVisibility(document);
|
|
193
|
+
const createPollingConversationChangeSubscription = (readMetadata, options = {}) => new PollingConversationChangeSubscriptions(readMetadata, {
|
|
194
|
+
runningIntervalMs: options.runningIntervalMs ?? POLLING_RUNNING_INTERVAL_MS,
|
|
195
|
+
idleIntervalMs: options.idleIntervalMs ?? POLLING_IDLE_INTERVAL_MS,
|
|
196
|
+
maxBackoffMs: options.maxBackoffMs ?? POLLING_MAX_BACKOFF_MS,
|
|
197
|
+
localActivityWindowMs: options.localActivityWindowMs ?? POLLING_LOCAL_ACTIVITY_WINDOW_MS,
|
|
198
|
+
timers: options.timers ?? new GlobalPollingTimers(),
|
|
199
|
+
documentVisibility: options.documentVisibility === void 0 ? readDefaultDocumentVisibility() : options.documentVisibility
|
|
200
|
+
});
|
|
201
|
+
class PollingAgentsConversationClient {
|
|
202
|
+
constructor(binding, polling) {
|
|
203
|
+
this.binding = binding;
|
|
204
|
+
this.polling = polling;
|
|
205
|
+
this.getConversationMetadata = (conversationId) => this.binding.getConversationMetadata(conversationId);
|
|
206
|
+
this.getNewestMessagesPage = (conversationId, pageSize) => this.binding.getNewestMessagesPage(conversationId, pageSize);
|
|
207
|
+
this.getOlderMessagesPage = (conversationId, beforeIndex, pageSize) => this.binding.getOlderMessagesPage(conversationId, beforeIndex, pageSize);
|
|
208
|
+
this.getChangedMessages = (conversationId, request) => this.binding.getChangedMessages(conversationId, request);
|
|
209
|
+
this.startConversation = (request) => this.binding.startConversation(request);
|
|
210
|
+
this.postMessage = async (conversationId, message) => {
|
|
211
|
+
const postedMessage = await this.binding.postMessage(conversationId, message);
|
|
212
|
+
this.polling.notifyLocalActivity(conversationId);
|
|
213
|
+
return postedMessage;
|
|
214
|
+
};
|
|
215
|
+
this.injectSignal = async (conversationId, signal) => {
|
|
216
|
+
await this.binding.injectSignal(conversationId, signal);
|
|
217
|
+
this.polling.notifyLocalActivity(conversationId);
|
|
218
|
+
};
|
|
219
|
+
this.retryConversation = async (conversationId) => {
|
|
220
|
+
await this.binding.retryConversation(conversationId);
|
|
221
|
+
this.polling.notifyLocalActivity(conversationId);
|
|
222
|
+
};
|
|
223
|
+
this.renameConversation = (conversationId, title) => this.binding.renameConversation(conversationId, title);
|
|
224
|
+
this.deleteConversation = (conversationId) => this.binding.deleteConversation(conversationId);
|
|
225
|
+
this.listConversations = (agentSpaceKey, options) => this.binding.listConversations(agentSpaceKey, options);
|
|
226
|
+
this.searchConversations = (text, options) => this.binding.searchConversations(text, options);
|
|
227
|
+
this.searchConversationMessages = (conversationId, text, options) => this.binding.searchConversationMessages(conversationId, text, options);
|
|
228
|
+
this.getConversationActivity = (conversationId, turnMessageId) => this.binding.getConversationActivity(conversationId, turnMessageId);
|
|
229
|
+
this.subscribeToConversationChanges = (conversationId, onSignal, onEnded) => this.polling.subscribeToConversationChanges(conversationId, onSignal, onEnded);
|
|
230
|
+
this.getSelectableModels = binding.getSelectableModels?.bind(binding);
|
|
231
|
+
this.composeSentMessageText = binding.composeSentMessageText?.bind(binding);
|
|
232
|
+
this.getMessageSentPayload = binding.getMessageSentPayload?.bind(binding);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const withPollingChangeSubscription = (client, options) => {
|
|
236
|
+
if (client.subscribeToConversationChanges) return client;
|
|
237
|
+
return new PollingAgentsConversationClient(
|
|
238
|
+
client,
|
|
239
|
+
createPollingConversationChangeSubscription(client.getConversationMetadata.bind(client), options)
|
|
240
|
+
);
|
|
241
|
+
};
|
|
242
|
+
export {
|
|
243
|
+
POLLING_IDLE_INTERVAL_MS as P,
|
|
244
|
+
POLLING_LOCAL_ACTIVITY_WINDOW_MS as a,
|
|
245
|
+
POLLING_MAX_BACKOFF_MS as b,
|
|
246
|
+
POLLING_RUNNING_INTERVAL_MS as c,
|
|
247
|
+
createPollingConversationChangeSubscription as d,
|
|
248
|
+
readPolledRunStatus as r,
|
|
249
|
+
withPollingChangeSubscription as w
|
|
250
|
+
};
|
|
251
|
+
//# sourceMappingURL=withPollingChangeSubscription-BLDAWF-o.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withPollingChangeSubscription-BLDAWF-o.js","sources":["../../src/client/polling/createPollingConversationChangeSubscription.ts","../../src/client/polling/withPollingChangeSubscription.ts"],"sourcesContent":["import {\n type AgentsConversation,\n type ConversationChangeSignal,\n type ConversationRunStatus,\n type ConversationSubscriptionEndReason,\n CONVERSATION_RUN_STATES_THAT_END_THE_CONVERSATION,\n isAgentsClientError,\n readConversationRunStatusOfRunState,\n} from \"../../contract/conversation\";\n\n/** Read interval while a turn runs (or right after a local send). */\nexport const POLLING_RUNNING_INTERVAL_MS = 2_000;\n/** Read interval while the conversation is idle or failed. */\nexport const POLLING_IDLE_INTERVAL_MS = 20_000;\n/** Ceiling of the exponential backoff after failed reads. */\nexport const POLLING_MAX_BACKOFF_MS = 60_000;\n/**\n * How long after a local send the poller keeps the running interval although the conversation still reads idle: the\n * server may store the owner's message before it marks the turn as running.\n */\nexport const POLLING_LOCAL_ACTIVITY_WINDOW_MS = 10_000;\n\n/** Reads a conversation's metadata — the port's `getConversationMetadata`. */\nexport type ConversationMetadataReader = (conversationId: number) => Promise<AgentsConversation>;\n\n/** The timer functions the poller uses; a spec hands in fake ones. */\nexport interface PollingTimers {\n setTimeout: (callback: () => void, delayMs: number) => unknown;\n clearTimeout: (timerHandle: unknown) => void;\n now: () => number;\n}\n\n/** Whether the page is hidden, and a way to hear when that changes; a spec hands in its own. */\nexport interface PollingDocumentVisibility {\n isHidden: () => boolean;\n /** Calls `listener` on every visibility change; returns the function that stops it. */\n listen: (listener: () => void) => () => void;\n}\n\nexport interface PollingConversationChangeSubscriptionOptions {\n /** Default `POLLING_RUNNING_INTERVAL_MS` (2 s). */\n runningIntervalMs?: number;\n /** Default `POLLING_IDLE_INTERVAL_MS` (20 s). */\n idleIntervalMs?: number;\n /** Default `POLLING_MAX_BACKOFF_MS` (60 s). */\n maxBackoffMs?: number;\n /** Default `POLLING_LOCAL_ACTIVITY_WINDOW_MS` (10 s). */\n localActivityWindowMs?: number;\n /** Default: the global `setTimeout` / `clearTimeout` and `Date.now`. */\n timers?: PollingTimers;\n /** Default: the browser `document`; `null` = the page counts as always visible (no `document`, a worker). */\n documentVisibility?: PollingDocumentVisibility | null;\n}\n\n/**\n * The polling default of the live updates: the port's `subscribeToConversationChanges` plus\n * `notifyLocalActivity`, which `withPollingChangeSubscription` calls after every send the server accepted.\n */\nexport interface PollingConversationChangeSubscription {\n subscribeToConversationChanges: (\n conversationId: number,\n onSignal: (signal: ConversationChangeSignal) => void,\n onEnded: (reason: ConversationSubscriptionEndReason) => void,\n ) => () => void;\n /** Reads the conversation's metadata now and keeps the running interval for the local-activity window. */\n notifyLocalActivity: (conversationId: number) => void;\n}\n\ninterface ResolvedPollingOptions {\n runningIntervalMs: number;\n idleIntervalMs: number;\n maxBackoffMs: number;\n localActivityWindowMs: number;\n timers: PollingTimers;\n documentVisibility: PollingDocumentVisibility | null;\n}\n\n/** The global timer functions, looked up on each call (so a spec's fake timers installed later still apply). */\nclass GlobalPollingTimers implements PollingTimers {\n setTimeout = (callback: () => void, delayMs: number): unknown => globalThis.setTimeout(callback, delayMs);\n\n clearTimeout = (timerHandle: unknown): void => globalThis.clearTimeout(timerHandle as ReturnType<typeof setTimeout>);\n\n now = (): number => Date.now();\n}\n\n/** The browser document's `visibilityState` and `visibilitychange` event. */\nclass BrowserDocumentVisibility implements PollingDocumentVisibility {\n constructor(protected readonly browserDocument: Document) {}\n\n isHidden = (): boolean => this.browserDocument.visibilityState === \"hidden\";\n\n listen = (listener: () => void): (() => void) => {\n this.browserDocument.addEventListener(\"visibilitychange\", listener);\n return this.browserDocument.removeEventListener.bind(this.browserDocument, \"visibilitychange\", listener);\n };\n}\n\n/**\n * The three-value run status a polled read reports: the stored run state, and \"running\" for an idle conversation the\n * server owes a turn (`agentTurnOwedAt`), as the chat's own derivation does.\n */\nexport const readPolledRunStatus = (conversation: AgentsConversation): ConversationRunStatus | null => {\n const runStatus = readConversationRunStatusOfRunState(conversation.runState);\n return runStatus === \"idle\" && conversation.agentTurnOwedAt ? \"running\" : runStatus;\n};\n\n/** The end of a subscription a failed read means: a vanished conversation or lost access; null for a passing failure. */\nconst readSubscriptionEndReasonOfReadFailure = (failure: unknown): ConversationSubscriptionEndReason | null => {\n if (!isAgentsClientError(failure)) return null;\n if (failure.kind === \"notFound\") return \"gone\";\n if (failure.kind === \"forbidden\") return \"forbidden\";\n return null;\n};\n\n/**\n * One subscription: reads the conversation's metadata on a timer and turns each read into the change signal.\n *\n * Numbering (the signal leaves it open; the metadata carries no server change counter): the poller keeps its own counter. It\n * starts at 0 with the first read and advances by one whenever a read differs from the previous one in the run status,\n * `lastMessageId` or `updated` — so every polled signal is an ordinary change signal (no `isStatusCheck`) and the\n * package rules apply unchanged: an advance reads the changed tail (throttled), a terminal status reads at once,\n * re-reads the metadata and converges on `lastMessageId`. A status check would carry only the run status as news and\n * would miss a new message under an unchanged status. Without `lastMessageId` in the metadata every poll of a running\n * turn counts as a change (the changed tail is read every poll). `summaryUpdatedAt` is a second local counter that\n * advances when `title` or `summary` changed. A read with no change emits nothing.\n */\nclass ConversationMetadataPoller {\n protected isStopped = false;\n protected isReading = false;\n protected readAgainAfterCurrentRead = false;\n protected timerHandle: unknown = null;\n protected consecutiveFailedReads = 0;\n protected changeCounter = 0;\n protected summaryRevision = 0;\n protected previousChangeFingerprint: string | null = null;\n protected previousSummaryFingerprint: string | null = null;\n protected runStatus: ConversationRunStatus | null = null;\n protected hasConversationEnded = false;\n protected runningIntervalUntil = 0;\n protected stopListeningToVisibility: (() => void) | null = null;\n\n constructor(\n readonly conversationId: number,\n protected readonly readMetadata: ConversationMetadataReader,\n protected readonly onSignal: (signal: ConversationChangeSignal) => void,\n protected readonly onEnded: (reason: ConversationSubscriptionEndReason) => void,\n protected readonly options: ResolvedPollingOptions,\n protected readonly activePollers: Set<ConversationMetadataPoller>,\n ) {}\n\n start = (): void => {\n this.activePollers.add(this);\n this.stopListeningToVisibility = this.options.documentVisibility?.listen(this.receiveVisibilityChange) ?? null;\n this.readNow();\n };\n\n /** The unsubscribe: no read, no timer and no signal after it; a read in flight is dropped. */\n stop = (): void => {\n this.isStopped = true;\n this.activePollers.delete(this);\n this.clearTimer();\n this.stopListeningToVisibility?.();\n this.stopListeningToVisibility = null;\n };\n\n receiveLocalActivity = (): void => {\n this.runningIntervalUntil = this.options.timers.now() + this.options.localActivityWindowMs;\n this.readNow();\n };\n\n /** Reads now; a read already in flight is followed by one more read instead (two reads never overlap). */\n protected readNow = (): void => {\n if (this.isStopped) return;\n if (this.isReading) {\n this.readAgainAfterCurrentRead = true;\n return;\n }\n this.clearTimer();\n this.isReading = true;\n void this.readMetadataOnce();\n };\n\n protected async readMetadataOnce(): Promise<void> {\n let conversation: AgentsConversation;\n try {\n conversation = await this.readMetadata(this.conversationId);\n } catch (failure) {\n this.isReading = false;\n this.receiveReadFailure(failure);\n return;\n }\n this.isReading = false;\n if (this.isStopped) return;\n this.consecutiveFailedReads = 0;\n this.receiveConversation(conversation);\n this.continueAfterRead(this.readIntervalMs());\n }\n\n protected receiveConversation(conversation: AgentsConversation): void {\n const runStatus = readPolledRunStatus(conversation);\n const reportsLastMessageId = conversation.lastMessageId !== undefined;\n const changeFingerprint = JSON.stringify([runStatus, conversation.lastMessageId ?? null, conversation.updated]);\n const summaryFingerprint = JSON.stringify([conversation.title, conversation.summary]);\n const isFirstRead = this.previousChangeFingerprint === null;\n const hasChanged =\n changeFingerprint !== this.previousChangeFingerprint || (!reportsLastMessageId && runStatus === \"running\");\n const hasSummaryChanged = !isFirstRead && summaryFingerprint !== this.previousSummaryFingerprint;\n if (!isFirstRead && hasChanged) this.changeCounter += 1;\n if (hasSummaryChanged) this.summaryRevision += 1;\n this.previousChangeFingerprint = changeFingerprint;\n this.previousSummaryFingerprint = summaryFingerprint;\n this.runStatus = runStatus;\n this.hasConversationEnded =\n conversation.runState !== null && CONVERSATION_RUN_STATES_THAT_END_THE_CONVERSATION.includes(conversation.runState);\n if (!isFirstRead && !hasChanged && !hasSummaryChanged) return;\n this.onSignal({\n changeCounter: this.changeCounter,\n lastMessageId: conversation.lastMessageId ?? null,\n runStatus,\n summaryUpdatedAt: this.summaryRevision,\n });\n }\n\n protected receiveReadFailure(failure: unknown): void {\n if (this.isStopped) return;\n const endReason = readSubscriptionEndReasonOfReadFailure(failure);\n if (endReason !== null) {\n this.stop();\n this.onEnded(endReason);\n return;\n }\n this.consecutiveFailedReads += 1;\n const backoffMs = this.readIntervalMs() * 2 ** this.consecutiveFailedReads;\n this.continueAfterRead(Math.min(backoffMs, this.options.maxBackoffMs));\n }\n\n protected continueAfterRead(nextReadDelayMs: number): void {\n if (this.readAgainAfterCurrentRead) {\n this.readAgainAfterCurrentRead = false;\n this.readNow();\n return;\n }\n // A completed or cancelled conversation changes no more: only a local send or the page's return reads it again.\n if (this.hasConversationEnded) return;\n this.scheduleRead(nextReadDelayMs);\n }\n\n protected readIntervalMs(): number {\n const isShortIntervalDue = this.runStatus === \"running\" || this.options.timers.now() < this.runningIntervalUntil;\n return isShortIntervalDue ? this.options.runningIntervalMs : this.options.idleIntervalMs;\n }\n\n /** Arms the next read — not while the page is hidden; its return reads at once. */\n protected scheduleRead(delayMs: number): void {\n this.clearTimer();\n if (this.isStopped || this.options.documentVisibility?.isHidden()) return;\n this.timerHandle = this.options.timers.setTimeout(this.readOnTimer, delayMs);\n }\n\n protected readOnTimer = (): void => {\n this.timerHandle = null;\n this.readNow();\n };\n\n protected receiveVisibilityChange = (): void => {\n if (this.isStopped) return;\n if (this.options.documentVisibility?.isHidden()) {\n this.clearTimer();\n return;\n }\n this.readNow();\n };\n\n protected clearTimer(): void {\n if (this.timerHandle === null) return;\n this.options.timers.clearTimeout(this.timerHandle);\n this.timerHandle = null;\n }\n}\n\n/** Every subscription of one polling default; `notifyLocalActivity` reaches the subscriptions of a conversation. */\nclass PollingConversationChangeSubscriptions implements PollingConversationChangeSubscription {\n protected readonly activePollers = new Set<ConversationMetadataPoller>();\n\n constructor(\n protected readonly readMetadata: ConversationMetadataReader,\n protected readonly options: ResolvedPollingOptions,\n ) {}\n\n subscribeToConversationChanges = (\n conversationId: number,\n onSignal: (signal: ConversationChangeSignal) => void,\n onEnded: (reason: ConversationSubscriptionEndReason) => void,\n ): (() => void) => {\n const poller = new ConversationMetadataPoller(\n conversationId,\n this.readMetadata,\n onSignal,\n onEnded,\n this.options,\n this.activePollers,\n );\n poller.start();\n return poller.stop;\n };\n\n notifyLocalActivity = (conversationId: number): void => {\n for (const poller of [...this.activePollers]) {\n if (poller.conversationId === conversationId) poller.receiveLocalActivity();\n }\n };\n}\n\nconst readDefaultDocumentVisibility = (): PollingDocumentVisibility | null =>\n typeof document === \"undefined\" ? null : new BrowserDocumentVisibility(document);\n\n/**\n * The polling default of `subscribeToConversationChanges` over a metadata read: every 2 s while a turn\n * runs, every 20 s while idle, at once after `notifyLocalActivity`; paused while the page is hidden and read once when\n * it shows again; exponential backoff on failed reads up to 60 s; a `notFound` / `forbidden` read ends the subscription\n * with `gone` / `forbidden`. One poller per subscription; see `ConversationMetadataPoller` for how a read becomes a\n * signal.\n */\nexport const createPollingConversationChangeSubscription = (\n readMetadata: ConversationMetadataReader,\n options: PollingConversationChangeSubscriptionOptions = {},\n): PollingConversationChangeSubscription =>\n new PollingConversationChangeSubscriptions(readMetadata, {\n runningIntervalMs: options.runningIntervalMs ?? POLLING_RUNNING_INTERVAL_MS,\n idleIntervalMs: options.idleIntervalMs ?? POLLING_IDLE_INTERVAL_MS,\n maxBackoffMs: options.maxBackoffMs ?? POLLING_MAX_BACKOFF_MS,\n localActivityWindowMs: options.localActivityWindowMs ?? POLLING_LOCAL_ACTIVITY_WINDOW_MS,\n timers: options.timers ?? new GlobalPollingTimers(),\n documentVisibility: options.documentVisibility === undefined ? readDefaultDocumentVisibility() : options.documentVisibility,\n });\n","import type { AgentsConversationClient } from \"../AgentsConversationClient\";\nimport type {\n AgentsConversation,\n ChangedConversationMessages,\n ChangedMessagesRequest,\n ConversationActivity,\n ConversationAttachmentReference,\n ConversationChangeSignal,\n ConversationListQueryOptions,\n ConversationMessageSearchHit,\n ConversationMessageSentPayload,\n ConversationMessagesPage,\n ConversationSearchGroup,\n ConversationSearchOptions,\n ConversationSignal,\n ConversationSubscriptionEndReason,\n PostedMessage,\n SelectableModel,\n StartedConversation,\n} from \"../../contract/conversation\";\nimport {\n createPollingConversationChangeSubscription,\n type PollingConversationChangeSubscription,\n type PollingConversationChangeSubscriptionOptions,\n} from \"./createPollingConversationChangeSubscription\";\n\n/** A conversation client whose `subscribeToConversationChanges` is present. */\nexport type AgentsConversationClientWithChangeSubscription = AgentsConversationClient &\n Required<Pick<AgentsConversationClient, \"subscribeToConversationChanges\">>;\n\n/**\n * A binding without push, with the polling default as its subscription. Every port function goes to the binding; the\n * three that make the server start a turn on an existing conversation (post, signal, retry) tell the poller once the\n * server accepted them, so the first read does not wait for the idle interval. A start needs no notice: the chat\n * subscribes to the new conversation afterwards, and a subscription reads at once.\n */\nclass PollingAgentsConversationClient implements AgentsConversationClientWithChangeSubscription {\n readonly getSelectableModels?: () => Promise<SelectableModel[]>;\n readonly composeSentMessageText?: (text: string, attachments: ConversationAttachmentReference[] | undefined) => string;\n readonly getMessageSentPayload?: (conversationId: number, messageId: number) => Promise<ConversationMessageSentPayload>;\n\n constructor(\n protected readonly binding: AgentsConversationClient,\n protected readonly polling: PollingConversationChangeSubscription,\n ) {\n // The optional functions exist exactly when the binding has them (the chat reads their presence).\n this.getSelectableModels = binding.getSelectableModels?.bind(binding);\n this.composeSentMessageText = binding.composeSentMessageText?.bind(binding);\n this.getMessageSentPayload = binding.getMessageSentPayload?.bind(binding);\n }\n\n getConversationMetadata = (conversationId: number): Promise<AgentsConversation> =>\n this.binding.getConversationMetadata(conversationId);\n\n getNewestMessagesPage = (conversationId: number, pageSize: number): Promise<ConversationMessagesPage> =>\n this.binding.getNewestMessagesPage(conversationId, pageSize);\n\n getOlderMessagesPage = (conversationId: number, beforeIndex: number, pageSize: number): Promise<ConversationMessagesPage> =>\n this.binding.getOlderMessagesPage(conversationId, beforeIndex, pageSize);\n\n getChangedMessages = (conversationId: number, request: ChangedMessagesRequest): Promise<ChangedConversationMessages> =>\n this.binding.getChangedMessages(conversationId, request);\n\n startConversation = (request: Parameters<AgentsConversationClient[\"startConversation\"]>[0]): Promise<StartedConversation> =>\n this.binding.startConversation(request);\n\n postMessage = async (\n conversationId: number,\n message: { text: string; model?: string; attachments?: ConversationAttachmentReference[] },\n ): Promise<PostedMessage> => {\n const postedMessage = await this.binding.postMessage(conversationId, message);\n this.polling.notifyLocalActivity(conversationId);\n return postedMessage;\n };\n\n injectSignal = async (conversationId: number, signal: ConversationSignal): Promise<void> => {\n await this.binding.injectSignal(conversationId, signal);\n this.polling.notifyLocalActivity(conversationId);\n };\n\n retryConversation = async (conversationId: number): Promise<void> => {\n await this.binding.retryConversation(conversationId);\n this.polling.notifyLocalActivity(conversationId);\n };\n\n renameConversation = (conversationId: number, title: string): Promise<AgentsConversation> =>\n this.binding.renameConversation(conversationId, title);\n\n deleteConversation = (conversationId: number): Promise<void> => this.binding.deleteConversation(conversationId);\n\n listConversations = (agentSpaceKey: number, options?: ConversationListQueryOptions): Promise<AgentsConversation[]> =>\n this.binding.listConversations(agentSpaceKey, options);\n\n searchConversations = (text: string, options?: ConversationSearchOptions): Promise<ConversationSearchGroup[]> =>\n this.binding.searchConversations(text, options);\n\n searchConversationMessages = (\n conversationId: number,\n text: string,\n options?: ConversationSearchOptions,\n ): Promise<ConversationMessageSearchHit[]> => this.binding.searchConversationMessages(conversationId, text, options);\n\n getConversationActivity = (conversationId: number, turnMessageId?: number | null): Promise<ConversationActivity> =>\n this.binding.getConversationActivity(conversationId, turnMessageId);\n\n subscribeToConversationChanges = (\n conversationId: number,\n onSignal: (signal: ConversationChangeSignal) => void,\n onEnded: (reason: ConversationSubscriptionEndReason) => void,\n ): (() => void) => this.polling.subscribeToConversationChanges(conversationId, onSignal, onEnded);\n}\n\n/**\n * The client with live updates: a client that brings its own `subscribeToConversationChanges` (a push\n * transport — the host application's Firebase binding) is returned as it is; any other gets the polling default over its\n * `getConversationMetadata` (`createPollingConversationChangeSubscription`, `options` tune the intervals). The default\n * `AgentChat` calls this by itself.\n */\nexport const withPollingChangeSubscription = (\n client: AgentsConversationClient,\n options?: PollingConversationChangeSubscriptionOptions,\n): AgentsConversationClientWithChangeSubscription => {\n if (client.subscribeToConversationChanges) return client as AgentsConversationClientWithChangeSubscription;\n return new PollingAgentsConversationClient(\n client,\n createPollingConversationChangeSubscription(client.getConversationMetadata.bind(client), options),\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { AgentsClientError, CONVERSATION_RUN_STATES_THAT_END_THE_CONVERSATION, readConversationRunStatusOfRunState } from "./contract.js";
|
|
3
|
+
const DEFAULT_SCRIPTED_ASSISTANT_ANSWER = "Done.";
|
|
4
|
+
const DEFAULT_PAGE_SIZE = 50;
|
|
5
|
+
const copyOf = (value) => JSON.parse(JSON.stringify(value));
|
|
6
|
+
const sortByIndexAscending = (messages) => [...messages].sort((first, second) => (first.indexInConversation ?? 0) - (second.indexInConversation ?? 0));
|
|
7
|
+
const textContains = (text, searchText) => (text ?? "").toLowerCase().includes(searchText.trim().toLowerCase());
|
|
8
|
+
const buildStoredMessageText = (text, attachments) => attachments?.length ? `${text}
|
|
9
|
+
|
|
10
|
+
${attachments.map((attachment) => `[Attached file: ${attachment.fileName ?? "file"} — ${attachment.publicUrl ?? ""}]`).join("\n")}` : text;
|
|
11
|
+
class InMemoryAgentsConversationClient {
|
|
12
|
+
constructor(data) {
|
|
13
|
+
this.recordsByConversationId = /* @__PURE__ */ new Map();
|
|
14
|
+
this.subscribersByConversationId = /* @__PURE__ */ new Map();
|
|
15
|
+
this.signalStateByConversationId = /* @__PURE__ */ new Map();
|
|
16
|
+
this.requestCountsByOperation = /* @__PURE__ */ new Map();
|
|
17
|
+
this.scriptedAssistantAnswersUsed = 0;
|
|
18
|
+
this.listConversations = async (agentSpaceKey, options = {}) => {
|
|
19
|
+
this.countRequest("listConversations");
|
|
20
|
+
const { includeUnsummarized = false, paging = {} } = options;
|
|
21
|
+
const { top, skip = 0 } = paging;
|
|
22
|
+
const conversationsOfAgentSpace = [...this.recordsByConversationId.values()].map((recorded) => recorded.conversation).filter((conversation) => conversation.agentSpaceKey === agentSpaceKey).filter((conversation) => includeUnsummarized || conversation.title !== null).sort((first, second) => second.id - first.id);
|
|
23
|
+
const end = top === void 0 ? void 0 : skip + top;
|
|
24
|
+
return copyOf(conversationsOfAgentSpace.slice(skip, end));
|
|
25
|
+
};
|
|
26
|
+
this.searchConversations = async (text, options = {}) => {
|
|
27
|
+
this.countRequest("searchConversations");
|
|
28
|
+
const searchGroups = [];
|
|
29
|
+
for (const recorded of this.recordsByConversationId.values()) {
|
|
30
|
+
const hits = this.findMessageSearchHits(recorded, text);
|
|
31
|
+
if (hits.length === 0) continue;
|
|
32
|
+
searchGroups.push({
|
|
33
|
+
conversationId: recorded.conversation.id,
|
|
34
|
+
title: recorded.conversation.title,
|
|
35
|
+
summary: null,
|
|
36
|
+
created: recorded.messages[0]?.createdDate ?? null,
|
|
37
|
+
updated: recorded.messages[recorded.messages.length - 1]?.createdDate ?? null,
|
|
38
|
+
relevance: 1,
|
|
39
|
+
hits
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return copyOf(searchGroups.slice(0, options.limit));
|
|
43
|
+
};
|
|
44
|
+
this.getConversationMetadata = async (conversationId) => {
|
|
45
|
+
this.countRequest("getConversationMetadata");
|
|
46
|
+
const recorded = this.readRecord(conversationId);
|
|
47
|
+
return copyOf({ ...recorded.conversation, lastMessageId: sortByIndexAscending(recorded.messages).pop()?.id ?? null });
|
|
48
|
+
};
|
|
49
|
+
this.getNewestMessagesPage = async (conversationId, pageSize) => {
|
|
50
|
+
this.countRequest("getNewestMessagesPage");
|
|
51
|
+
const newestFirst = this.readMessagesNewestFirst(conversationId);
|
|
52
|
+
return copyOf({ messages: newestFirst.slice(0, pageSize), hasMoreOlder: newestFirst.length > pageSize });
|
|
53
|
+
};
|
|
54
|
+
this.getOlderMessagesPage = async (conversationId, beforeIndex, pageSize) => {
|
|
55
|
+
this.countRequest("getOlderMessagesPage");
|
|
56
|
+
const olderMessages = this.readMessagesNewestFirst(conversationId).filter(
|
|
57
|
+
(message) => (message.indexInConversation ?? Number.MAX_SAFE_INTEGER) < beforeIndex
|
|
58
|
+
);
|
|
59
|
+
return copyOf({ messages: olderMessages.slice(0, pageSize), hasMoreOlder: olderMessages.length > pageSize });
|
|
60
|
+
};
|
|
61
|
+
this.getChangedMessages = async (conversationId, request) => {
|
|
62
|
+
this.countRequest("getChangedMessages");
|
|
63
|
+
const changedMessages = this.readMessagesNewestFirst(conversationId).filter(
|
|
64
|
+
(message) => message.id > request.highestKnownId || (message.indexInConversation ?? -1) >= request.fromIndex
|
|
65
|
+
);
|
|
66
|
+
return copyOf({ messages: changedMessages.slice(0, request.pageSize ?? this.defaultPageSize) });
|
|
67
|
+
};
|
|
68
|
+
this.searchConversationMessages = async (conversationId, text, options = {}) => {
|
|
69
|
+
this.countRequest("searchConversationMessages");
|
|
70
|
+
return copyOf(this.findMessageSearchHits(this.readRecord(conversationId), text).slice(0, options.limit));
|
|
71
|
+
};
|
|
72
|
+
this.getConversationActivity = async (conversationId) => {
|
|
73
|
+
this.countRequest("getConversationActivity");
|
|
74
|
+
return copyOf(this.readRecord(conversationId).activity ?? { turnMessageId: null, turnRunning: false, elements: [] });
|
|
75
|
+
};
|
|
76
|
+
this.startConversation = async (request) => {
|
|
77
|
+
this.countRequest("startConversation");
|
|
78
|
+
if (request.text === "" && !request.startSignalText) {
|
|
79
|
+
throw new AgentsClientError("other", { httpStatus: 400, message: "A start needs a message or a signal." });
|
|
80
|
+
}
|
|
81
|
+
const reopenedConversation = request.entryPointKey ? [...this.recordsByConversationId.values()].find(
|
|
82
|
+
(recorded2) => recorded2.conversation.agentSpaceKey === request.agentSpaceKey && recorded2.conversation.entryPointKey === request.entryPointKey
|
|
83
|
+
) : void 0;
|
|
84
|
+
if (reopenedConversation) {
|
|
85
|
+
return { conversation: copyOf(reopenedConversation.conversation), messages: [], reopenedExisting: true };
|
|
86
|
+
}
|
|
87
|
+
const recorded = {
|
|
88
|
+
conversation: {
|
|
89
|
+
id: this.nextConversationId,
|
|
90
|
+
agentSpaceKey: request.agentSpaceKey,
|
|
91
|
+
runState: "IDLE",
|
|
92
|
+
agentTurnOwedAt: null,
|
|
93
|
+
title: null,
|
|
94
|
+
titleManuallyEdited: false,
|
|
95
|
+
summary: null,
|
|
96
|
+
created: null,
|
|
97
|
+
updated: null,
|
|
98
|
+
purposeName: null,
|
|
99
|
+
initiatorType: null,
|
|
100
|
+
scheduleId: null,
|
|
101
|
+
entryPointKey: request.entryPointKey ?? null,
|
|
102
|
+
progressSteps: []
|
|
103
|
+
},
|
|
104
|
+
messages: []
|
|
105
|
+
};
|
|
106
|
+
this.nextConversationId += 1;
|
|
107
|
+
this.recordsByConversationId.set(recorded.conversation.id, recorded);
|
|
108
|
+
if (request.startSignalText) {
|
|
109
|
+
this.appendMessage(recorded, { role: "USER", messageType: "SIGNAL", authorType: "USER", message: request.startSignalText });
|
|
110
|
+
}
|
|
111
|
+
if (request.text !== "") {
|
|
112
|
+
this.appendMessage(recorded, {
|
|
113
|
+
role: "USER",
|
|
114
|
+
messageType: "TEXT",
|
|
115
|
+
authorType: "USER",
|
|
116
|
+
message: buildStoredMessageText(request.text, request.attachments)
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
const messagesBeforeTheAnswer = copyOf(recorded.messages);
|
|
120
|
+
this.appendScriptedAssistantAnswer(recorded);
|
|
121
|
+
return { conversation: copyOf(recorded.conversation), messages: messagesBeforeTheAnswer, reopenedExisting: false };
|
|
122
|
+
};
|
|
123
|
+
this.postMessage = async (conversationId, message) => {
|
|
124
|
+
this.countRequest("postMessage");
|
|
125
|
+
const recorded = this.readOpenRecord(conversationId);
|
|
126
|
+
this.appendMessage(recorded, {
|
|
127
|
+
role: "USER",
|
|
128
|
+
messageType: "TEXT",
|
|
129
|
+
authorType: "USER",
|
|
130
|
+
message: buildStoredMessageText(message.text, message.attachments)
|
|
131
|
+
});
|
|
132
|
+
const messagesBeforeTheAnswer = copyOf(recorded.messages);
|
|
133
|
+
this.appendScriptedAssistantAnswer(recorded);
|
|
134
|
+
return { messages: messagesBeforeTheAnswer };
|
|
135
|
+
};
|
|
136
|
+
this.injectSignal = async (conversationId, signal) => {
|
|
137
|
+
this.countRequest("injectSignal");
|
|
138
|
+
const recorded = this.readOpenRecord(conversationId);
|
|
139
|
+
this.appendMessage(recorded, {
|
|
140
|
+
role: "USER",
|
|
141
|
+
messageType: "SIGNAL",
|
|
142
|
+
authorType: "USER",
|
|
143
|
+
message: signal.text,
|
|
144
|
+
signalSource: signal.source ?? "FRONTEND_WIDGET_CLICK"
|
|
145
|
+
});
|
|
146
|
+
this.appendScriptedAssistantAnswer(recorded);
|
|
147
|
+
};
|
|
148
|
+
this.retryConversation = async (conversationId) => {
|
|
149
|
+
this.countRequest("retryConversation");
|
|
150
|
+
const recorded = this.readRecord(conversationId);
|
|
151
|
+
const newestMessage = sortByIndexAscending(recorded.messages).pop();
|
|
152
|
+
if (newestMessage === void 0 || newestMessage.role === "ASSISTANT") {
|
|
153
|
+
throw new AgentsClientError("other", { httpStatus: 400, message: "Nothing to retry." });
|
|
154
|
+
}
|
|
155
|
+
this.appendScriptedAssistantAnswer(recorded);
|
|
156
|
+
};
|
|
157
|
+
this.renameConversation = async (conversationId, title) => {
|
|
158
|
+
this.countRequest("renameConversation");
|
|
159
|
+
const recorded = this.readRecord(conversationId);
|
|
160
|
+
recorded.conversation.title = title;
|
|
161
|
+
recorded.conversation.titleManuallyEdited = true;
|
|
162
|
+
return copyOf(recorded.conversation);
|
|
163
|
+
};
|
|
164
|
+
this.deleteConversation = async (conversationId) => {
|
|
165
|
+
this.countRequest("deleteConversation");
|
|
166
|
+
this.readRecord(conversationId);
|
|
167
|
+
this.recordsByConversationId.delete(conversationId);
|
|
168
|
+
};
|
|
169
|
+
this.subscribeToRecordedConversationChanges = (conversationId, onChange, onEnded) => {
|
|
170
|
+
const subscriber = { onChange, onEnded };
|
|
171
|
+
const subscribers = this.subscribersByConversationId.get(conversationId) ?? /* @__PURE__ */ new Set();
|
|
172
|
+
subscribers.add(subscriber);
|
|
173
|
+
this.subscribersByConversationId.set(conversationId, subscribers);
|
|
174
|
+
const record = this.recordsByConversationId.get(conversationId);
|
|
175
|
+
if (record) {
|
|
176
|
+
onChange(this.buildSignal(record, this.readSignalState(conversationId), null));
|
|
177
|
+
}
|
|
178
|
+
return () => {
|
|
179
|
+
subscribers.delete(subscriber);
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
this.emit = (conversationId, change = {}) => {
|
|
183
|
+
const record = this.readRecord(conversationId);
|
|
184
|
+
const signalState = this.readSignalState(conversationId);
|
|
185
|
+
signalState.changeCounter += 1;
|
|
186
|
+
if (change.summaryChanged) {
|
|
187
|
+
signalState.summaryUpdatedAt = (signalState.summaryUpdatedAt ?? 0) + 1;
|
|
188
|
+
}
|
|
189
|
+
const signal = this.buildSignal(record, signalState, change.runStatus ?? null);
|
|
190
|
+
for (const subscriber of [...this.subscribersByConversationId.get(conversationId) ?? []]) {
|
|
191
|
+
subscriber.onChange(copyOf(signal));
|
|
192
|
+
}
|
|
193
|
+
return signal;
|
|
194
|
+
};
|
|
195
|
+
this.end = (conversationId, reason) => {
|
|
196
|
+
const subscribers = [...this.subscribersByConversationId.get(conversationId) ?? []];
|
|
197
|
+
this.subscribersByConversationId.delete(conversationId);
|
|
198
|
+
for (const subscriber of subscribers) {
|
|
199
|
+
subscriber.onEnded(reason);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
this.setRunState = (conversationId, runState) => {
|
|
203
|
+
this.readRecord(conversationId).conversation.runState = runState;
|
|
204
|
+
};
|
|
205
|
+
this.readRequestCount = (operation) => {
|
|
206
|
+
if (operation !== void 0) return this.requestCountsByOperation.get(operation) ?? 0;
|
|
207
|
+
let requestCount = 0;
|
|
208
|
+
for (const operationRequestCount of this.requestCountsByOperation.values()) requestCount += operationRequestCount;
|
|
209
|
+
return requestCount;
|
|
210
|
+
};
|
|
211
|
+
this.readStoredMessages = (conversationId) => copyOf(sortByIndexAscending(this.readRecord(conversationId).messages));
|
|
212
|
+
this.readSelectableModels = async () => {
|
|
213
|
+
this.countRequest("getSelectableModels");
|
|
214
|
+
return copyOf(this.selectableModels ?? []);
|
|
215
|
+
};
|
|
216
|
+
this.readMessageSentPayload = async (conversationId, messageId) => {
|
|
217
|
+
this.countRequest("getMessageSentPayload");
|
|
218
|
+
this.readRecord(conversationId);
|
|
219
|
+
const sentPayload = this.sentPayloadsByMessageId?.[messageId];
|
|
220
|
+
if (sentPayload === void 0) {
|
|
221
|
+
throw new AgentsClientError("notFound", { httpStatus: 404, message: `No sent payload for message ${messageId}.` });
|
|
222
|
+
}
|
|
223
|
+
return copyOf(sentPayload);
|
|
224
|
+
};
|
|
225
|
+
this.storeAssistantAnswer = (recorded, answerText) => {
|
|
226
|
+
this.appendMessage(recorded, {
|
|
227
|
+
role: "ASSISTANT",
|
|
228
|
+
messageType: "TEXT",
|
|
229
|
+
authorType: "ASSISTANT",
|
|
230
|
+
message: answerText
|
|
231
|
+
});
|
|
232
|
+
recorded.conversation.runState = "IDLE";
|
|
233
|
+
};
|
|
234
|
+
for (const recordedConversation of copyOf(data.conversations)) {
|
|
235
|
+
this.recordsByConversationId.set(recordedConversation.conversation.id, recordedConversation);
|
|
236
|
+
}
|
|
237
|
+
const scriptedAssistantAnswers = data.scriptedAssistantAnswers ?? [];
|
|
238
|
+
this.scriptedAssistantAnswers = scriptedAssistantAnswers.length > 0 ? [...scriptedAssistantAnswers] : [DEFAULT_SCRIPTED_ASSISTANT_ANSWER];
|
|
239
|
+
this.defaultPageSize = data.defaultPageSize ?? DEFAULT_PAGE_SIZE;
|
|
240
|
+
this.selectableModels = data.selectableModels ? copyOf(data.selectableModels) : void 0;
|
|
241
|
+
if (this.selectableModels) {
|
|
242
|
+
this.getSelectableModels = this.readSelectableModels;
|
|
243
|
+
}
|
|
244
|
+
this.sentPayloadsByMessageId = data.sentPayloadsByMessageId ? copyOf(data.sentPayloadsByMessageId) : void 0;
|
|
245
|
+
if (this.sentPayloadsByMessageId) {
|
|
246
|
+
this.getMessageSentPayload = this.readMessageSentPayload;
|
|
247
|
+
}
|
|
248
|
+
this.assistantAnswerDelayMs = data.assistantAnswerDelayMs ?? 0;
|
|
249
|
+
if (!data.withoutChangeSubscription) {
|
|
250
|
+
this.subscribeToConversationChanges = this.subscribeToRecordedConversationChanges;
|
|
251
|
+
}
|
|
252
|
+
const allMessageIds = data.conversations.flatMap((recorded) => recorded.messages.map((message) => message.id));
|
|
253
|
+
const allConversationIds = data.conversations.map((recorded) => recorded.conversation.id);
|
|
254
|
+
this.nextMessageId = Math.max(0, ...allMessageIds) + 1;
|
|
255
|
+
this.nextConversationId = Math.max(0, ...allConversationIds) + 1;
|
|
256
|
+
}
|
|
257
|
+
// ── Internals ─────────────────────────────────────────────────────────────────────────────────────────────────
|
|
258
|
+
countRequest(operation) {
|
|
259
|
+
this.requestCountsByOperation.set(operation, (this.requestCountsByOperation.get(operation) ?? 0) + 1);
|
|
260
|
+
}
|
|
261
|
+
readMessagesNewestFirst(conversationId) {
|
|
262
|
+
return sortByIndexAscending(this.readRecord(conversationId).messages).reverse();
|
|
263
|
+
}
|
|
264
|
+
readRecord(conversationId) {
|
|
265
|
+
const recorded = this.recordsByConversationId.get(conversationId);
|
|
266
|
+
if (!recorded) {
|
|
267
|
+
throw new AgentsClientError("notFound", { httpStatus: 404, message: `Conversation ${conversationId} not found.` });
|
|
268
|
+
}
|
|
269
|
+
return recorded;
|
|
270
|
+
}
|
|
271
|
+
/** The record of a conversation that still takes input; a completed or cancelled one refuses like the server. */
|
|
272
|
+
readOpenRecord(conversationId) {
|
|
273
|
+
const recorded = this.readRecord(conversationId);
|
|
274
|
+
const runState = recorded.conversation.runState;
|
|
275
|
+
if (runState !== null && CONVERSATION_RUN_STATES_THAT_END_THE_CONVERSATION.includes(runState)) {
|
|
276
|
+
throw new AgentsClientError("closed", { httpStatus: 400, code: "CONVERSATION_CLOSED" });
|
|
277
|
+
}
|
|
278
|
+
return recorded;
|
|
279
|
+
}
|
|
280
|
+
readSignalState(conversationId) {
|
|
281
|
+
const existingSignalState = this.signalStateByConversationId.get(conversationId);
|
|
282
|
+
if (existingSignalState) return existingSignalState;
|
|
283
|
+
const signalState = { changeCounter: 0, summaryUpdatedAt: null };
|
|
284
|
+
this.signalStateByConversationId.set(conversationId, signalState);
|
|
285
|
+
return signalState;
|
|
286
|
+
}
|
|
287
|
+
buildSignal(recorded, signalState, runStatus) {
|
|
288
|
+
const newestMessage = sortByIndexAscending(recorded.messages).pop();
|
|
289
|
+
return {
|
|
290
|
+
changeCounter: signalState.changeCounter,
|
|
291
|
+
lastMessageId: newestMessage?.id ?? null,
|
|
292
|
+
runStatus: runStatus ?? readConversationRunStatusOfRunState(recorded.conversation.runState),
|
|
293
|
+
summaryUpdatedAt: signalState.summaryUpdatedAt
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
appendMessage(recorded, fields) {
|
|
297
|
+
const highestIndex = Math.max(-1, ...recorded.messages.map((message) => message.indexInConversation ?? -1));
|
|
298
|
+
const storedMessage = {
|
|
299
|
+
id: this.nextMessageId,
|
|
300
|
+
conversationId: recorded.conversation.id,
|
|
301
|
+
indexInConversation: highestIndex + 1,
|
|
302
|
+
status: "COMPLETED",
|
|
303
|
+
signalSource: null,
|
|
304
|
+
createdDate: null,
|
|
305
|
+
toolCall: null,
|
|
306
|
+
delegatedConversations: [],
|
|
307
|
+
subAgent: null,
|
|
308
|
+
...fields
|
|
309
|
+
};
|
|
310
|
+
this.nextMessageId += 1;
|
|
311
|
+
recorded.messages.push(storedMessage);
|
|
312
|
+
return storedMessage;
|
|
313
|
+
}
|
|
314
|
+
/** The next scripted answer: stored at once, or after `assistantAnswerDelayMs` with the run state RUNNING meanwhile. */
|
|
315
|
+
appendScriptedAssistantAnswer(recorded) {
|
|
316
|
+
const answerIndex = Math.min(this.scriptedAssistantAnswersUsed, this.scriptedAssistantAnswers.length - 1);
|
|
317
|
+
this.scriptedAssistantAnswersUsed += 1;
|
|
318
|
+
const answerText = this.scriptedAssistantAnswers[answerIndex];
|
|
319
|
+
if (this.assistantAnswerDelayMs <= 0) {
|
|
320
|
+
this.storeAssistantAnswer(recorded, answerText);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
recorded.conversation.runState = "RUNNING";
|
|
324
|
+
setTimeout(this.storeAssistantAnswer, this.assistantAnswerDelayMs, recorded, answerText);
|
|
325
|
+
}
|
|
326
|
+
findMessageSearchHits(recorded, text) {
|
|
327
|
+
if (text.trim() === "") return [];
|
|
328
|
+
return sortByIndexAscending(recorded.messages).filter((message) => message.messageType === "TEXT" && textContains(message.message, text)).map((message) => ({
|
|
329
|
+
messageId: message.id,
|
|
330
|
+
conversationId: recorded.conversation.id,
|
|
331
|
+
indexInConversation: message.indexInConversation,
|
|
332
|
+
role: message.role,
|
|
333
|
+
excerpt: message.message,
|
|
334
|
+
relevance: 1,
|
|
335
|
+
created: message.createdDate,
|
|
336
|
+
updated: null,
|
|
337
|
+
title: recorded.conversation.title
|
|
338
|
+
}));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
const createInMemoryAgentsConversationClient = (data) => new InMemoryAgentsConversationClient(data);
|
|
342
|
+
export {
|
|
343
|
+
InMemoryAgentsConversationClient,
|
|
344
|
+
createInMemoryAgentsConversationClient
|
|
345
|
+
};
|
|
346
|
+
//# sourceMappingURL=client-testing.js.map
|