@assistant-ui/core 0.2.20 → 0.2.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/dist/adapters/attachment.d.ts +2 -2
- package/dist/adapters/attachment.d.ts.map +1 -1
- package/dist/adapters/attachment.js +14 -7
- package/dist/adapters/attachment.js.map +1 -1
- package/dist/adapters/directive-formatter.d.ts +0 -1
- package/dist/adapters/directive-formatter.d.ts.map +1 -1
- package/dist/adapters/feedback.d.ts +0 -1
- package/dist/adapters/feedback.d.ts.map +1 -1
- package/dist/adapters/index.d.ts +2 -2
- package/dist/adapters/index.js +2 -1
- package/dist/adapters/speech.d.ts +0 -1
- package/dist/adapters/speech.d.ts.map +1 -1
- package/dist/adapters/speech.js +9 -2
- package/dist/adapters/speech.js.map +1 -1
- package/dist/adapters/suggestion.d.ts +16 -2
- package/dist/adapters/suggestion.d.ts.map +1 -1
- package/dist/adapters/suggestion.js +36 -0
- package/dist/adapters/suggestion.js.map +1 -0
- package/dist/adapters/thread-history.d.ts +2 -2
- package/dist/adapters/thread-history.d.ts.map +1 -1
- package/dist/adapters/trigger.d.ts +5 -3
- package/dist/adapters/trigger.d.ts.map +1 -1
- package/dist/adapters/voice.d.ts +0 -1
- package/dist/adapters/voice.d.ts.map +1 -1
- package/dist/adapters/voice.js +13 -5
- package/dist/adapters/voice.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/duplicate-detection.d.ts.map +1 -1
- package/dist/internal.d.ts +9 -1
- package/dist/internal.js +8 -2
- package/dist/model-context/frame/host.d.ts +1 -1
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js +5 -0
- package/dist/model-context/frame/host.js.map +1 -1
- package/dist/model-context/frame/provider.d.ts +0 -1
- package/dist/model-context/frame/provider.d.ts.map +1 -1
- package/dist/model-context/frame/provider.js +1 -0
- package/dist/model-context/frame/provider.js.map +1 -1
- package/dist/model-context/frame/types.d.ts.map +1 -1
- package/dist/model-context/interactable-composer-metadata.d.ts +4 -2
- package/dist/model-context/interactable-composer-metadata.d.ts.map +1 -1
- package/dist/model-context/interactable-composer-metadata.js.map +1 -1
- package/dist/model-context/registry-handles.d.ts +0 -1
- package/dist/model-context/registry-handles.d.ts.map +1 -1
- package/dist/model-context/registry.d.ts +0 -1
- package/dist/model-context/registry.d.ts.map +1 -1
- package/dist/model-context/tool.d.ts +23 -9
- package/dist/model-context/tool.d.ts.map +1 -1
- package/dist/model-context/tool.js +0 -25
- package/dist/model-context/tool.js.map +1 -1
- package/dist/model-context/types.d.ts +0 -1
- package/dist/model-context/types.d.ts.map +1 -1
- package/dist/react/AssistantProvider.d.ts +0 -1
- package/dist/react/AssistantProvider.d.ts.map +1 -1
- package/dist/react/AssistantProvider.js.map +1 -1
- package/dist/react/AssistantRuntimeProvider.d.ts +1 -6
- package/dist/react/AssistantRuntimeProvider.d.ts.map +1 -1
- package/dist/react/RuntimeAdapter.d.ts +1 -0
- package/dist/react/RuntimeAdapter.d.ts.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts +13 -2
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.js +196 -54
- package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
- package/dist/react/adapters/TitleGenerationAdapter.d.ts +0 -1
- package/dist/react/adapters/TitleGenerationAdapter.d.ts.map +1 -1
- package/dist/react/client/DataRenderers.d.ts +0 -1
- package/dist/react/client/DataRenderers.d.ts.map +1 -1
- package/dist/react/client/Interactables.d.ts +0 -1
- package/dist/react/client/Interactables.d.ts.map +1 -1
- package/dist/react/client/Interactables.js.map +1 -1
- package/dist/react/client/Tools.d.ts +3 -2
- package/dist/react/client/Tools.d.ts.map +1 -1
- package/dist/react/client/interactable-model-context.d.ts +0 -1
- package/dist/react/client/interactable-model-context.d.ts.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/interactables-legacy/Interactables.d.ts +0 -1
- package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
- package/dist/react/interactables-legacy/interactable-model-context.d.ts +0 -1
- package/dist/react/interactables-legacy/interactable-model-context.d.ts.map +1 -1
- package/dist/react/interactables-legacy/scopes.d.ts +4 -2
- package/dist/react/interactables-legacy/scopes.d.ts.map +1 -1
- package/dist/react/interactables-legacy/useAssistantInteractable.d.ts +0 -1
- package/dist/react/interactables-legacy/useAssistantInteractable.d.ts.map +1 -1
- package/dist/react/interactables-legacy/useInteractableState.d.ts.map +1 -1
- package/dist/react/model-context/define-mcp-toolkit.d.ts +19 -4
- package/dist/react/model-context/define-mcp-toolkit.d.ts.map +1 -1
- package/dist/react/model-context/define-mcp-toolkit.js +17 -5
- package/dist/react/model-context/define-mcp-toolkit.js.map +1 -1
- package/dist/react/model-context/define-toolkit.d.ts +1 -2
- package/dist/react/model-context/define-toolkit.d.ts.map +1 -1
- package/dist/react/model-context/external-tool.d.ts.map +1 -1
- package/dist/react/model-context/human-tool.d.ts.map +1 -1
- package/dist/react/model-context/interactableTool.d.ts +2 -2
- package/dist/react/model-context/interactableTool.d.ts.map +1 -1
- package/dist/react/model-context/makeAssistantDataUI.d.ts +2 -2
- package/dist/react/model-context/makeAssistantDataUI.d.ts.map +1 -1
- package/dist/react/model-context/makeAssistantTool.d.ts +2 -2
- package/dist/react/model-context/makeAssistantTool.d.ts.map +1 -1
- package/dist/react/model-context/makeAssistantToolUI.d.ts +2 -2
- package/dist/react/model-context/makeAssistantToolUI.d.ts.map +1 -1
- package/dist/react/model-context/provider-tool.d.ts +0 -1
- package/dist/react/model-context/provider-tool.d.ts.map +1 -1
- package/dist/react/model-context/stub-tool.d.ts.map +1 -1
- package/dist/react/model-context/toolbox.d.ts +5 -5
- package/dist/react/model-context/toolbox.d.ts.map +1 -1
- package/dist/react/model-context/useAssistantContext.d.ts +1 -0
- package/dist/react/model-context/useAssistantContext.d.ts.map +1 -1
- package/dist/react/model-context/useAssistantDataUI.d.ts +3 -2
- package/dist/react/model-context/useAssistantDataUI.d.ts.map +1 -1
- package/dist/react/model-context/useAssistantInstructions.d.ts +1 -0
- package/dist/react/model-context/useAssistantInstructions.d.ts.map +1 -1
- package/dist/react/model-context/useAssistantTool.d.ts +4 -2
- package/dist/react/model-context/useAssistantTool.d.ts.map +1 -1
- package/dist/react/model-context/useAssistantToolUI.d.ts +3 -2
- package/dist/react/model-context/useAssistantToolUI.d.ts.map +1 -1
- package/dist/react/model-context/useAuiToolOverrides.d.ts +0 -1
- package/dist/react/model-context/useAuiToolOverrides.d.ts.map +1 -1
- package/dist/react/model-context/useInlineRender.d.ts +0 -1
- package/dist/react/model-context/useInlineRender.d.ts.map +1 -1
- package/dist/react/model-context/useInteractable.d.ts +7 -4
- package/dist/react/model-context/useInteractable.d.ts.map +1 -1
- package/dist/react/model-context/useInteractable.js.map +1 -1
- package/dist/react/model-context/useInteractableState.d.ts.map +1 -1
- package/dist/react/model-context/useInteractableVersions.d.ts +0 -1
- package/dist/react/model-context/useInteractableVersions.d.ts.map +1 -1
- package/dist/react/model-context/useToolArgsStatus.d.ts +3 -1
- package/dist/react/model-context/useToolArgsStatus.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useActionBarCopy.d.ts +1 -4
- package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useActionBarCopy.js +13 -13
- package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useActionBarFeedback.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useActionBarSpeak.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useActionBarStopSpeaking.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerNext.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts +0 -1
- package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useComposerDictate.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useComposerSend.d.ts +0 -1
- package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useEditComposerCancel.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useEditComposerSend.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useMessageBranching.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useMessageError.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useMessageError.js +5 -1
- package/dist/react/primitive-hooks/useMessageError.js.map +1 -1
- package/dist/react/primitive-hooks/useMessageReload.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts +1 -5
- package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadListItemArchive.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadListItemDelete.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadListItemTrigger.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadListItemUnarchive.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadListNew.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadMessageIds.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadMessages.d.ts +0 -1
- package/dist/react/primitive-hooks/useThreadMessages.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useVoice.d.ts +0 -1
- package/dist/react/primitive-hooks/useVoice.d.ts.map +1 -1
- package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts +7 -4
- package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts.map +1 -1
- package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js +1 -1
- package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
- package/dist/react/primitives/composer/ComposerAttachments.d.ts +4 -3
- package/dist/react/primitives/composer/ComposerAttachments.d.ts.map +1 -1
- package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
- package/dist/react/primitives/composer/ComposerIf.d.ts +4 -3
- package/dist/react/primitives/composer/ComposerIf.d.ts.map +1 -1
- package/dist/react/primitives/composer/ComposerQueue.d.ts +2 -2
- package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
- package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
- package/dist/react/primitives/generativeUI/GenerativeUI.d.ts +2 -2
- package/dist/react/primitives/generativeUI/GenerativeUI.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageAttachments.d.ts +4 -3
- package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.d.ts +1 -6
- package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
- package/dist/react/primitives/message/MessageParts.d.ts +44 -25
- package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageParts.js +48 -37
- package/dist/react/primitives/message/MessageParts.js.map +1 -1
- package/dist/react/primitives/message/MessageQuote.d.ts +2 -2
- package/dist/react/primitives/message/MessageQuote.d.ts.map +1 -1
- package/dist/react/primitives/messagePart/MessagePartInProgress.d.ts +0 -1
- package/dist/react/primitives/messagePart/MessagePartInProgress.d.ts.map +1 -1
- package/dist/react/primitives/part/PartMessages.d.ts +2 -2
- package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
- package/dist/react/primitives/part/PartMessages.js.map +1 -1
- package/dist/react/primitives/thread/ThreadMessages.d.ts +35 -17
- package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
- package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
- package/dist/react/primitives/thread/ThreadSuggestions.d.ts +6 -4
- package/dist/react/primitives/thread/ThreadSuggestions.d.ts.map +1 -1
- package/dist/react/primitives/thread/ThreadSuggestions.js.map +1 -1
- package/dist/react/primitives/threadList/ThreadListItems.d.ts +4 -3
- package/dist/react/primitives/threadList/ThreadListItems.d.ts.map +1 -1
- package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
- package/dist/react/primitives/threadListItem/ThreadListItemTitle.d.ts +0 -1
- package/dist/react/primitives/threadListItem/ThreadListItemTitle.d.ts.map +1 -1
- package/dist/react/providers/AttachmentByIndexProvider.d.ts +0 -1
- package/dist/react/providers/AttachmentByIndexProvider.d.ts.map +1 -1
- package/dist/react/providers/ChainOfThoughtByIndicesProvider.d.ts +0 -1
- package/dist/react/providers/ChainOfThoughtByIndicesProvider.d.ts.map +1 -1
- package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts +0 -1
- package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +1 -1
- package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js +18 -30
- package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js.map +1 -1
- package/dist/react/providers/MessageByIdProvider.d.ts +0 -1
- package/dist/react/providers/MessageByIdProvider.d.ts.map +1 -1
- package/dist/react/providers/MessageByIndexProvider.d.ts +0 -1
- package/dist/react/providers/MessageByIndexProvider.d.ts.map +1 -1
- package/dist/react/providers/PartByIndexProvider.d.ts +0 -1
- package/dist/react/providers/PartByIndexProvider.d.ts.map +1 -1
- package/dist/react/providers/PartByIndexProvider.js +18 -30
- package/dist/react/providers/PartByIndexProvider.js.map +1 -1
- package/dist/react/providers/QueueItemByIndexProvider.d.ts +0 -1
- package/dist/react/providers/QueueItemByIndexProvider.d.ts.map +1 -1
- package/dist/react/providers/ReadonlyThreadProvider.d.ts +0 -1
- package/dist/react/providers/ReadonlyThreadProvider.d.ts.map +1 -1
- package/dist/react/providers/SuggestionByIndexProvider.d.ts +0 -1
- package/dist/react/providers/SuggestionByIndexProvider.d.ts.map +1 -1
- package/dist/react/providers/TextMessagePartProvider.d.ts +0 -1
- package/dist/react/providers/TextMessagePartProvider.d.ts.map +1 -1
- package/dist/react/providers/ThreadListItemByIndexProvider.d.ts +0 -1
- package/dist/react/providers/ThreadListItemByIndexProvider.d.ts.map +1 -1
- package/dist/react/providers/ThreadListItemRuntimeProvider.d.ts +1 -1
- package/dist/react/providers/ThreadListItemRuntimeProvider.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +2 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +2 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +12 -3
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +70 -27
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +0 -1
- package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +0 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +1 -4
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +8 -4
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.d.ts +12 -2
- package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.js +30 -1
- package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts +0 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/createMessageConverter.d.ts +1 -7
- package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -1
- package/dist/react/runtimes/createRuntimeExtras.d.ts +0 -1
- package/dist/react/runtimes/createRuntimeExtras.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.d.ts +1 -8
- package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.js +43 -45
- package/dist/react/runtimes/external-message-converter.js.map +1 -1
- package/dist/react/runtimes/useExternalStoreRuntime.d.ts +0 -1
- package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -1
- package/dist/react/runtimes/useExternalStoreSharedOptions.d.ts +0 -1
- package/dist/react/runtimes/useExternalStoreSharedOptions.d.ts.map +1 -1
- package/dist/react/runtimes/useLocalRuntime.d.ts +3 -5
- package/dist/react/runtimes/useLocalRuntime.d.ts.map +1 -1
- package/dist/react/runtimes/useLocalRuntime.js +9 -1
- package/dist/react/runtimes/useLocalRuntime.js.map +1 -1
- package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts +0 -1
- package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
- package/dist/react/runtimes/useStreamingTiming.d.ts +0 -1
- package/dist/react/runtimes/useStreamingTiming.d.ts.map +1 -1
- package/dist/react/types/MessagePartComponentTypes.d.ts +6 -3
- package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
- package/dist/react/types/scopes/dataRenderers.d.ts +1 -1
- package/dist/react/types/scopes/dataRenderers.d.ts.map +1 -1
- package/dist/react/types/scopes/interactables.d.ts +4 -2
- package/dist/react/types/scopes/interactables.d.ts.map +1 -1
- package/dist/react/types/scopes/tools.d.ts +5 -3
- package/dist/react/types/scopes/tools.d.ts.map +1 -1
- package/dist/react/types/store-augmentation.d.ts +1 -2
- package/dist/react/types/store-augmentation.d.ts.map +1 -1
- package/dist/react/utils/getMessageQuote.d.ts +0 -1
- package/dist/react/utils/getMessageQuote.d.ts.map +1 -1
- package/dist/react/utils/groupParts.d.ts +2 -2
- package/dist/react/utils/groupParts.d.ts.map +1 -1
- package/dist/react/utils/useJSONEqual.d.ts.map +1 -1
- package/dist/runtime/api/assistant-runtime.d.ts +0 -1
- package/dist/runtime/api/assistant-runtime.d.ts.map +1 -1
- package/dist/runtime/api/attachment-runtime.d.ts +0 -1
- package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
- package/dist/runtime/api/bindings.d.ts +0 -1
- package/dist/runtime/api/bindings.d.ts.map +1 -1
- package/dist/runtime/api/composer-runtime.d.ts +6 -4
- package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
- package/dist/runtime/api/message-part-runtime.d.ts +0 -1
- package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
- package/dist/runtime/api/message-runtime.d.ts +6 -16
- package/dist/runtime/api/message-runtime.d.ts.map +1 -1
- package/dist/runtime/api/message-runtime.js +5 -5
- package/dist/runtime/api/message-runtime.js.map +1 -1
- package/dist/runtime/api/paths.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-item-runtime.d.ts +0 -1
- package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-item-runtime.js +2 -1
- package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
- package/dist/runtime/api/thread-list-runtime.d.ts +0 -1
- package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-runtime.d.ts +3 -1
- package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/base/base-assistant-runtime-core.d.ts +0 -1
- package/dist/runtime/base/base-assistant-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts +4 -2
- package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.js +51 -10
- package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -4
- package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.js +3 -2
- package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
- package/dist/runtime/base/default-edit-composer-runtime-core.d.ts +1 -5
- package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/default-edit-composer-runtime-core.js +4 -2
- package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +1 -0
- package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.js +2 -2
- package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
- package/dist/runtime/branch/external-thread-branch-adapter.d.ts.map +1 -1
- package/dist/runtime/interfaces/assistant-runtime-core.d.ts +0 -1
- package/dist/runtime/interfaces/assistant-runtime-core.d.ts.map +1 -1
- package/dist/runtime/interfaces/composer-runtime-core.d.ts +2 -2
- package/dist/runtime/interfaces/composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +0 -1
- package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtime/interfaces/thread-runtime-core.d.ts +2 -2
- package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/queue/external-thread-queue-adapter.d.ts +0 -1
- package/dist/runtime/queue/external-thread-queue-adapter.d.ts.map +1 -1
- package/dist/runtime/queue/message-queue.d.ts +6 -4
- package/dist/runtime/queue/message-queue.d.ts.map +1 -1
- package/dist/runtime/queue/message-queue.js +1 -1
- package/dist/runtime/utils/auto-status.d.ts +0 -1
- package/dist/runtime/utils/auto-status.d.ts.map +1 -1
- package/dist/runtime/utils/chat-model-adapter.d.ts +0 -1
- package/dist/runtime/utils/chat-model-adapter.d.ts.map +1 -1
- package/dist/runtime/utils/external-store-message.d.ts +0 -1
- package/dist/runtime/utils/external-store-message.d.ts.map +1 -1
- package/dist/runtime/utils/message-repository.d.ts +1 -5
- package/dist/runtime/utils/message-repository.d.ts.map +1 -1
- package/dist/runtime/utils/message-repository.js +3 -1
- package/dist/runtime/utils/message-repository.js.map +1 -1
- package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +0 -1
- package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -1
- package/dist/runtime/utils/streaming-timing.d.ts +5 -3
- package/dist/runtime/utils/streaming-timing.d.ts.map +1 -1
- package/dist/runtime/utils/thread-message-like.d.ts +2 -2
- package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
- package/dist/runtime/utils/thread-message-like.js +4 -1
- package/dist/runtime/utils/thread-message-like.js.map +1 -1
- package/dist/runtimes/assistant-transport/utils.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-adapter.d.ts +2 -2
- package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-runtime-core.d.ts +0 -1
- package/dist/runtimes/external-store/external-store-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-shared-options.d.ts +0 -1
- package/dist/runtimes/external-store/external-store-shared-options.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +0 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +2 -0
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/external-store/thread-message-converter.d.ts +0 -1
- package/dist/runtimes/external-store/thread-message-converter.d.ts.map +1 -1
- package/dist/runtimes/local/local-runtime-core.d.ts +0 -1
- package/dist/runtimes/local/local-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-runtime-options.d.ts +0 -1
- package/dist/runtimes/local/local-runtime-options.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-list-runtime-core.d.ts +0 -1
- package/dist/runtimes/local/local-thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts +5 -21
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +29 -17
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/local/should-continue.d.ts +0 -1
- package/dist/runtimes/local/should-continue.d.ts.map +1 -1
- package/dist/runtimes/local/should-continue.js +2 -2
- package/dist/runtimes/local/should-continue.js.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +0 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts +1 -2
- package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/adapter/in-memory.js +5 -3
- package/dist/runtimes/remote-thread-list/adapter/in-memory.js.map +1 -1
- package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts +0 -1
- package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +10 -8
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.js +22 -9
- package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
- package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +0 -1
- package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/types.d.ts +1 -2
- package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +2 -2
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +1 -2
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
- package/dist/store/clients/chain-of-thought-client.d.ts +0 -1
- package/dist/store/clients/chain-of-thought-client.d.ts.map +1 -1
- package/dist/store/clients/model-context-client.d.ts +0 -1
- package/dist/store/clients/model-context-client.d.ts.map +1 -1
- package/dist/store/clients/no-op-composer-client.d.ts +0 -1
- package/dist/store/clients/no-op-composer-client.d.ts.map +1 -1
- package/dist/store/clients/runtime-adapter.d.ts +0 -1
- package/dist/store/clients/runtime-adapter.d.ts.map +1 -1
- package/dist/store/clients/suggestions.d.ts +0 -1
- package/dist/store/clients/suggestions.d.ts.map +1 -1
- package/dist/store/clients/thread-message-client.d.ts +0 -1
- package/dist/store/clients/thread-message-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/attachment-runtime-client.d.ts +0 -1
- package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/composer-runtime-client.d.ts +0 -1
- package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/liveRef.d.ts.map +1 -1
- package/dist/store/runtime-clients/message-part-runtime-client.d.ts +0 -1
- package/dist/store/runtime-clients/message-part-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/message-runtime-client.d.ts +0 -1
- package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts +0 -1
- package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-list-runtime-client.d.ts +0 -1
- package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-runtime-client.d.ts +0 -1
- package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/useSubscribable.d.ts +0 -1
- package/dist/store/runtime-clients/useSubscribable.d.ts.map +1 -1
- package/dist/store/scope-registration.d.ts +1 -2
- package/dist/store/scope-registration.d.ts.map +1 -1
- package/dist/store/scopes/attachment.d.ts +0 -1
- package/dist/store/scopes/attachment.d.ts.map +1 -1
- package/dist/store/scopes/chain-of-thought.d.ts +0 -1
- package/dist/store/scopes/chain-of-thought.d.ts.map +1 -1
- package/dist/store/scopes/composer.d.ts +0 -1
- package/dist/store/scopes/composer.d.ts.map +1 -1
- package/dist/store/scopes/message.d.ts +6 -4
- package/dist/store/scopes/message.d.ts.map +1 -1
- package/dist/store/scopes/model-context.d.ts +0 -1
- package/dist/store/scopes/model-context.d.ts.map +1 -1
- package/dist/store/scopes/part.d.ts +0 -1
- package/dist/store/scopes/part.d.ts.map +1 -1
- package/dist/store/scopes/queue-item.d.ts.map +1 -1
- package/dist/store/scopes/suggestion.d.ts.map +1 -1
- package/dist/store/scopes/suggestions.d.ts +0 -1
- package/dist/store/scopes/suggestions.d.ts.map +1 -1
- package/dist/store/scopes/thread-list-item.d.ts +0 -1
- package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
- package/dist/store/scopes/thread.d.ts +4 -3
- package/dist/store/scopes/thread.d.ts.map +1 -1
- package/dist/store/scopes/threads.d.ts +0 -1
- package/dist/store/scopes/threads.d.ts.map +1 -1
- package/dist/subscribable/subscribable.d.ts +1 -2
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/subscribable/subscribable.js +11 -3
- package/dist/subscribable/subscribable.js.map +1 -1
- package/dist/tests/remote-thread-list-test-helpers.d.ts +2 -2
- package/dist/tests/remote-thread-list-test-helpers.d.ts.map +1 -1
- package/dist/tests/remote-thread-list-test-helpers.js +5 -2
- package/dist/tests/remote-thread-list-test-helpers.js.map +1 -1
- package/dist/types/attachment.d.ts +3 -2
- package/dist/types/attachment.d.ts.map +1 -1
- package/dist/types/attachment.js +6 -0
- package/dist/types/attachment.js.map +1 -0
- package/dist/types/directive.d.ts +3 -2
- package/dist/types/directive.d.ts.map +1 -1
- package/dist/types/error.d.ts +15 -0
- package/dist/types/error.d.ts.map +1 -0
- package/dist/types/error.js +46 -0
- package/dist/types/error.js.map +1 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/message.d.ts +71 -33
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/message.js.map +1 -1
- package/dist/types/quote.d.ts.map +1 -1
- package/dist/types/trigger.d.ts +0 -1
- package/dist/types/trigger.d.ts.map +1 -1
- package/dist/types/unsubscribe.d.ts.map +1 -1
- package/dist/utils/composite-context-provider.d.ts +1 -0
- package/dist/utils/composite-context-provider.d.ts.map +1 -1
- package/dist/utils/data-url.d.ts +9 -0
- package/dist/utils/data-url.d.ts.map +1 -0
- package/dist/utils/data-url.js +14 -0
- package/dist/utils/data-url.js.map +1 -0
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/json/is-json-equal.d.ts.map +1 -1
- package/dist/utils/json/is-json.d.ts +0 -1
- package/dist/utils/json/is-json.d.ts.map +1 -1
- package/dist/utils/json/is-json.js +1 -1
- package/dist/utils/json/is-json.js.map +1 -1
- package/dist/utils/json/stable-stringify-tool-args.d.ts +7 -0
- package/dist/utils/json/stable-stringify-tool-args.d.ts.map +1 -0
- package/dist/utils/json/stable-stringify-tool-args.js +32 -0
- package/dist/utils/json/stable-stringify-tool-args.js.map +1 -0
- package/dist/utils/notify-event-listeners.d.ts +6 -0
- package/dist/utils/notify-event-listeners.d.ts.map +1 -0
- package/dist/utils/notify-event-listeners.js +16 -0
- package/dist/utils/notify-event-listeners.js.map +1 -0
- package/dist/utils/text.d.ts +0 -1
- package/dist/utils/text.d.ts.map +1 -1
- package/package.json +14 -10
- package/src/adapters/attachment.test.ts +107 -0
- package/src/adapters/attachment.ts +20 -10
- package/src/adapters/index.ts +6 -1
- package/src/adapters/speech.test.ts +88 -0
- package/src/adapters/speech.ts +17 -2
- package/src/adapters/suggestion.test.ts +187 -0
- package/src/adapters/suggestion.ts +75 -1
- package/src/adapters/voice.test.ts +130 -0
- package/src/adapters/voice.ts +26 -6
- package/src/index.ts +15 -1
- package/src/internal.ts +21 -0
- package/src/model-context/frame/host.test.ts +100 -0
- package/src/model-context/frame/host.ts +10 -0
- package/src/model-context/frame/provider.test.ts +83 -0
- package/src/model-context/frame/provider.ts +1 -0
- package/src/model-context/tool.test.ts +110 -0
- package/src/model-context/tool.ts +31 -9
- package/src/react/adapters/LocalStorageThreadListAdapter.test.ts +304 -0
- package/src/react/adapters/LocalStorageThreadListAdapter.tsx +307 -60
- package/src/react/index.ts +2 -0
- package/src/react/model-context/define-mcp-toolkit.ts +39 -6
- package/src/react/model-context/define-toolkit.test.ts +107 -0
- package/src/react/primitive-hooks/useActionBarCopy.test.ts +79 -0
- package/src/react/primitive-hooks/useActionBarCopy.ts +4 -3
- package/src/react/primitive-hooks/useMessageError.test.ts +64 -0
- package/src/react/primitive-hooks/useMessageError.ts +19 -6
- package/src/react/primitives/chainOfThought/ChainOfThoughtParts.tsx +1 -3
- package/src/react/primitives/message/MessageParts.tsx +48 -35
- package/src/react/providers/ChainOfThoughtPartByIndexProvider.tsx +19 -2
- package/src/react/providers/PartByIndexProvider.tsx +16 -2
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +18 -0
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +4 -1
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +96 -26
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +69 -0
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +1 -1
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.test.ts +127 -0
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +15 -4
- package/src/react/runtimes/cloud/auiV0.ts +71 -2
- package/src/react/runtimes/external-message-converter.test.tsx +123 -0
- package/src/react/runtimes/external-message-converter.ts +36 -11
- package/src/react/runtimes/useLocalRuntime.test.tsx +56 -0
- package/src/react/runtimes/useLocalRuntime.ts +13 -1
- package/src/runtime/api/message-runtime.test.ts +81 -0
- package/src/runtime/api/message-runtime.ts +4 -6
- package/src/runtime/api/thread-list-item-runtime.ts +6 -1
- package/src/runtime/base/base-composer-runtime-core.ts +95 -30
- package/src/runtime/base/base-thread-runtime-core.ts +2 -1
- package/src/runtime/base/default-edit-composer-runtime-core.ts +4 -2
- package/src/runtime/base/default-thread-composer-runtime-core.ts +2 -2
- package/src/runtime/utils/message-repository.ts +8 -3
- package/src/runtime/utils/thread-message-like.ts +3 -0
- package/src/runtimes/local/local-thread-runtime-core.test.ts +276 -3
- package/src/runtimes/local/local-thread-runtime-core.ts +29 -25
- package/src/runtimes/local/should-continue.ts +5 -2
- package/src/runtimes/remote-thread-list/adapter/in-memory.test.ts +14 -0
- package/src/runtimes/remote-thread-list/adapter/in-memory.ts +13 -5
- package/src/runtimes/remote-thread-list/optimistic-state.test.ts +63 -0
- package/src/runtimes/remote-thread-list/optimistic-state.ts +49 -17
- package/src/runtimes/remote-thread-list/types.ts +1 -1
- package/src/runtimes/tool-invocations/EDGE_CASES.md +13 -19
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +127 -6
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +4 -2
- package/src/subscribable/subscribable.test.ts +58 -0
- package/src/subscribable/subscribable.ts +13 -3
- package/src/tests/MessageRepository.test.ts +26 -0
- package/src/tests/OptimisticState-list-race.test.ts +33 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +42 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-order.test.ts +223 -0
- package/src/tests/attachment-adapters.test.ts +14 -2
- package/src/tests/auiV0Encode.test.ts +134 -1
- package/src/tests/base-composer-runtime-core-addAttachment.test.ts +123 -5
- package/src/tests/base-composer-runtime-core-send.test.ts +573 -0
- package/src/tests/default-edit-composer-runtime-core.test.ts +43 -5
- package/src/tests/event-subscription-listener-errors.test.ts +205 -0
- package/src/tests/remote-thread-list-test-helpers.ts +14 -7
- package/src/tests/thread-message-like.test.ts +97 -0
- package/src/types/attachment.ts +6 -0
- package/src/types/error.test.ts +122 -0
- package/src/types/error.ts +74 -0
- package/src/types/index.ts +1 -0
- package/src/types/message.ts +12 -3
- package/src/utils/data-url.test.ts +50 -0
- package/src/utils/data-url.ts +9 -0
- package/src/utils/json/is-json-equal.test.ts +84 -0
- package/src/utils/json/is-json.test.ts +123 -0
- package/src/utils/json/is-json.ts +1 -1
- package/src/utils/json/stable-stringify-tool-args.test.ts +105 -0
- package/src/utils/json/stable-stringify-tool-args.ts +70 -0
- package/src/utils/notify-event-listeners.ts +30 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { getFileDataURL, SimpleImageAttachmentAdapter } from "./attachment";
|
|
3
|
+
|
|
4
|
+
const originalFileReader = globalThis.FileReader;
|
|
5
|
+
const originalBuffer = globalThis.Buffer;
|
|
6
|
+
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
globalThis.FileReader = originalFileReader;
|
|
9
|
+
globalThis.Buffer = originalBuffer;
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
describe("getFileDataURL", () => {
|
|
13
|
+
it("uses FileReader when available", async () => {
|
|
14
|
+
class FakeFileReader {
|
|
15
|
+
result: string | null = null;
|
|
16
|
+
onload: (() => void) | null = null;
|
|
17
|
+
onerror: ((error: unknown) => void) | null = null;
|
|
18
|
+
readAsDataURL(file: File) {
|
|
19
|
+
file
|
|
20
|
+
.arrayBuffer()
|
|
21
|
+
.then((buf) => {
|
|
22
|
+
this.result = `data:${file.type};base64,${originalBuffer.from(buf).toString("base64")}`;
|
|
23
|
+
this.onload?.();
|
|
24
|
+
})
|
|
25
|
+
.catch((error) => this.onerror?.(error));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
globalThis.FileReader = FakeFileReader as unknown as typeof FileReader;
|
|
29
|
+
|
|
30
|
+
const file = new File(["hello"], "a.txt", { type: "text/plain" });
|
|
31
|
+
expect(await getFileDataURL(file)).toBe(
|
|
32
|
+
`data:text/plain;base64,${originalBuffer.from("hello").toString("base64")}`,
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("falls back to Buffer when FileReader is absent", async () => {
|
|
37
|
+
globalThis.FileReader = undefined as unknown as typeof FileReader;
|
|
38
|
+
|
|
39
|
+
const file = new File(["hello"], "a.txt", { type: "text/plain" });
|
|
40
|
+
expect(await getFileDataURL(file)).toBe(
|
|
41
|
+
`data:text/plain;base64,${originalBuffer.from("hello").toString("base64")}`,
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("defaults to application/octet-stream when the file has no type", async () => {
|
|
46
|
+
globalThis.FileReader = undefined as unknown as typeof FileReader;
|
|
47
|
+
|
|
48
|
+
const file = new File(["hello"], "a.bin", { type: "" });
|
|
49
|
+
expect(await getFileDataURL(file)).toBe(
|
|
50
|
+
`data:application/octet-stream;base64,${originalBuffer.from("hello").toString("base64")}`,
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("falls back to chunked btoa when neither FileReader nor Buffer exist", async () => {
|
|
55
|
+
globalThis.FileReader = undefined as unknown as typeof FileReader;
|
|
56
|
+
globalThis.Buffer = undefined as unknown as typeof Buffer;
|
|
57
|
+
|
|
58
|
+
const file = new File(["hello"], "a.txt", { type: "text/plain" });
|
|
59
|
+
expect(await getFileDataURL(file)).toBe(
|
|
60
|
+
`data:text/plain;base64,${originalBuffer.from("hello").toString("base64")}`,
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("encodes large inputs without RangeError on the btoa path", async () => {
|
|
65
|
+
globalThis.FileReader = undefined as unknown as typeof FileReader;
|
|
66
|
+
globalThis.Buffer = undefined as unknown as typeof Buffer;
|
|
67
|
+
|
|
68
|
+
const bytes = new Uint8Array(100_000);
|
|
69
|
+
for (let i = 0; i < bytes.length; i++) bytes[i] = i % 256;
|
|
70
|
+
const file = new File([bytes], "big.bin", {
|
|
71
|
+
type: "application/octet-stream",
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
expect(await getFileDataURL(file)).toBe(
|
|
75
|
+
`data:application/octet-stream;base64,${originalBuffer.from(bytes).toString("base64")}`,
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe("SimpleImageAttachmentAdapter", () => {
|
|
81
|
+
it("assigns unique IDs to files with the same name", async () => {
|
|
82
|
+
const adapter = new SimpleImageAttachmentAdapter();
|
|
83
|
+
const first = await adapter.add({
|
|
84
|
+
file: new File(["first"], "image.png", { type: "image/png" }),
|
|
85
|
+
});
|
|
86
|
+
const second = await adapter.add({
|
|
87
|
+
file: new File(["second"], "image.png", { type: "image/png" }),
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
expect(first.id).not.toBe(second.id);
|
|
91
|
+
expect(first.name).toBe("image.png");
|
|
92
|
+
expect(second.name).toBe("image.png");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("sends an image as a data URL", async () => {
|
|
96
|
+
globalThis.FileReader = undefined as unknown as typeof FileReader;
|
|
97
|
+
|
|
98
|
+
const file = new File(["img"], "a.png", { type: "image/png" });
|
|
99
|
+
const adapter = new SimpleImageAttachmentAdapter();
|
|
100
|
+
const result = await adapter.send(await adapter.add({ file }));
|
|
101
|
+
const part = result.content[0];
|
|
102
|
+
if (part?.type !== "image") throw new Error("expected image content part");
|
|
103
|
+
expect(part.image).toBe(
|
|
104
|
+
`data:image/png;base64,${originalBuffer.from("img").toString("base64")}`,
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
@@ -20,7 +20,7 @@ export class SimpleImageAttachmentAdapter implements AttachmentAdapter {
|
|
|
20
20
|
|
|
21
21
|
public async add(state: { file: File }): Promise<PendingAttachment> {
|
|
22
22
|
return {
|
|
23
|
-
id:
|
|
23
|
+
id: generateId(),
|
|
24
24
|
type: "image",
|
|
25
25
|
name: state.file.name,
|
|
26
26
|
contentType: state.file.type,
|
|
@@ -49,21 +49,31 @@ export class SimpleImageAttachmentAdapter implements AttachmentAdapter {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
const bytesToBase64 = (bytes: Uint8Array): string =>
|
|
53
|
-
(
|
|
52
|
+
const bytesToBase64 = (bytes: Uint8Array): string => {
|
|
53
|
+
const nodeBuffer = (
|
|
54
54
|
globalThis as {
|
|
55
|
-
Buffer
|
|
55
|
+
Buffer?: {
|
|
56
56
|
from(bytes: Uint8Array): { toString(encoding: string): string };
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
).Buffer
|
|
59
|
+
).Buffer;
|
|
60
|
+
if (nodeBuffer) {
|
|
61
|
+
return nodeBuffer.from(bytes).toString("base64");
|
|
62
|
+
}
|
|
63
|
+
let binary = "";
|
|
64
|
+
const chunkSize = 0x8000;
|
|
65
|
+
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
66
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
|
|
67
|
+
}
|
|
68
|
+
return btoa(binary);
|
|
69
|
+
};
|
|
60
70
|
|
|
61
71
|
// React Native's Blob polyfill has FileReader but not file.text()/arrayBuffer(); Node has
|
|
62
72
|
// the reverse. Prefer FileReader when present, falling back to the Blob methods otherwise.
|
|
63
|
-
const getFileDataURL = async (file: File): Promise<string> => {
|
|
73
|
+
export const getFileDataURL = async (file: File): Promise<string> => {
|
|
64
74
|
if (typeof FileReader === "undefined") {
|
|
65
75
|
const buffer = await file.arrayBuffer();
|
|
66
|
-
return `data:${file.type};base64,${bytesToBase64(new Uint8Array(buffer))}`;
|
|
76
|
+
return `data:${file.type || "application/octet-stream"};base64,${bytesToBase64(new Uint8Array(buffer))}`;
|
|
67
77
|
}
|
|
68
78
|
return new Promise<string>((resolve, reject) => {
|
|
69
79
|
const reader = new FileReader();
|
|
@@ -75,11 +85,11 @@ const getFileDataURL = async (file: File): Promise<string> => {
|
|
|
75
85
|
|
|
76
86
|
export class SimpleTextAttachmentAdapter implements AttachmentAdapter {
|
|
77
87
|
public accept =
|
|
78
|
-
"text/plain,text/html,text/markdown,text/csv,text/xml,text/json,text/css";
|
|
88
|
+
"text/plain,text/html,text/markdown,text/csv,text/xml,text/json,application/json,text/css";
|
|
79
89
|
|
|
80
90
|
public async add(state: { file: File }): Promise<PendingAttachment> {
|
|
81
91
|
return {
|
|
82
|
-
id:
|
|
92
|
+
id: generateId(),
|
|
83
93
|
type: "document",
|
|
84
94
|
name: state.file.name,
|
|
85
95
|
contentType: state.file.type,
|
|
@@ -133,7 +143,7 @@ export function fileMatchesAccept(
|
|
|
133
143
|
.map((type) => type.trim().toLowerCase());
|
|
134
144
|
|
|
135
145
|
const fileExtension = `.${file.name.split(".").pop()!.toLowerCase()}`;
|
|
136
|
-
const fileMimeType = file.type.toLowerCase();
|
|
146
|
+
const fileMimeType = file.type.split(";", 1)[0]!.trim().toLowerCase();
|
|
137
147
|
|
|
138
148
|
for (const type of allowedTypes) {
|
|
139
149
|
if (type.startsWith(".") && type === fileExtension) {
|
package/src/adapters/index.ts
CHANGED
|
@@ -19,7 +19,12 @@ export type { VoiceSessionControls, VoiceSessionHelpers } from "./voice";
|
|
|
19
19
|
export type { FeedbackAdapter } from "./feedback";
|
|
20
20
|
|
|
21
21
|
// Suggestion adapter
|
|
22
|
-
export type {
|
|
22
|
+
export type {
|
|
23
|
+
SuggestionAdapter,
|
|
24
|
+
SuggestionAdapterGenerateOptions,
|
|
25
|
+
CreateSuggestionAdapterOptions,
|
|
26
|
+
} from "./suggestion";
|
|
27
|
+
export { createSuggestionAdapter } from "./suggestion";
|
|
23
28
|
|
|
24
29
|
// Trigger adapter (generic)
|
|
25
30
|
export type { Unstable_TriggerAdapter } from "./trigger";
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { WebSpeechSynthesisAdapter } from "./speech";
|
|
3
|
+
|
|
4
|
+
afterEach(() => {
|
|
5
|
+
vi.restoreAllMocks();
|
|
6
|
+
vi.unstubAllGlobals();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
describe("WebSpeechSynthesisAdapter", () => {
|
|
10
|
+
it("isolates a late subscriber that throws after the utterance ended", async () => {
|
|
11
|
+
const listeners = new Map<string, EventListener>();
|
|
12
|
+
class MockSpeechSynthesisUtterance {
|
|
13
|
+
addEventListener(type: string, listener: EventListener) {
|
|
14
|
+
listeners.set(type, listener);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
vi.stubGlobal("SpeechSynthesisUtterance", MockSpeechSynthesisUtterance);
|
|
18
|
+
vi.stubGlobal("window", {
|
|
19
|
+
speechSynthesis: {
|
|
20
|
+
speak: vi.fn(),
|
|
21
|
+
cancel: vi.fn(),
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
const listenerError = new Error("late listener failed");
|
|
25
|
+
const consoleError = vi
|
|
26
|
+
.spyOn(console, "error")
|
|
27
|
+
.mockImplementation(() => {});
|
|
28
|
+
|
|
29
|
+
const result = new WebSpeechSynthesisAdapter().speak("Hello");
|
|
30
|
+
listeners.get("end")!(new Event("end"));
|
|
31
|
+
|
|
32
|
+
const lateListener = vi.fn();
|
|
33
|
+
result.subscribe(() => {
|
|
34
|
+
throw listenerError;
|
|
35
|
+
});
|
|
36
|
+
result.subscribe(lateListener);
|
|
37
|
+
await Promise.resolve();
|
|
38
|
+
|
|
39
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
40
|
+
"[assistant-ui] Speech synthesis listener threw an error",
|
|
41
|
+
listenerError,
|
|
42
|
+
);
|
|
43
|
+
expect(lateListener).toHaveBeenCalledOnce();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("continues notifying listeners when one throws", () => {
|
|
47
|
+
const listeners = new Map<string, EventListener>();
|
|
48
|
+
class MockSpeechSynthesisUtterance {
|
|
49
|
+
addEventListener(type: string, listener: EventListener) {
|
|
50
|
+
listeners.set(type, listener);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const speak = vi.fn();
|
|
54
|
+
vi.stubGlobal("SpeechSynthesisUtterance", MockSpeechSynthesisUtterance);
|
|
55
|
+
vi.stubGlobal("window", {
|
|
56
|
+
speechSynthesis: {
|
|
57
|
+
speak,
|
|
58
|
+
cancel: vi.fn(),
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
const listenerError = new Error("listener failed");
|
|
62
|
+
const consoleError = vi
|
|
63
|
+
.spyOn(console, "error")
|
|
64
|
+
.mockImplementation(() => {});
|
|
65
|
+
const result = new WebSpeechSynthesisAdapter().speak("Hello");
|
|
66
|
+
const laterListener = vi.fn();
|
|
67
|
+
|
|
68
|
+
result.subscribe(() => {
|
|
69
|
+
throw listenerError;
|
|
70
|
+
});
|
|
71
|
+
result.subscribe(laterListener);
|
|
72
|
+
listeners.get("end")?.({} as Event);
|
|
73
|
+
|
|
74
|
+
expect(speak).toHaveBeenCalledWith(
|
|
75
|
+
expect.any(MockSpeechSynthesisUtterance),
|
|
76
|
+
);
|
|
77
|
+
expect(laterListener).toHaveBeenCalledOnce();
|
|
78
|
+
expect(result.status).toEqual({
|
|
79
|
+
type: "ended",
|
|
80
|
+
reason: "finished",
|
|
81
|
+
error: undefined,
|
|
82
|
+
});
|
|
83
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
84
|
+
"[assistant-ui] Speech synthesis listener threw an error",
|
|
85
|
+
listenerError,
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
});
|
package/src/adapters/speech.ts
CHANGED
|
@@ -22,6 +22,21 @@ export type SpeechSynthesisAdapter = {
|
|
|
22
22
|
speak: (text: string) => SpeechSynthesisAdapter.Utterance;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
+
const notifySpeechSynthesisListeners = (
|
|
26
|
+
listeners: Iterable<() => void>,
|
|
27
|
+
): void => {
|
|
28
|
+
for (const listener of listeners) {
|
|
29
|
+
try {
|
|
30
|
+
listener();
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error(
|
|
33
|
+
"[assistant-ui] Speech synthesis listener threw an error",
|
|
34
|
+
error,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
25
40
|
export namespace DictationAdapter {
|
|
26
41
|
export type Status =
|
|
27
42
|
| {
|
|
@@ -64,7 +79,7 @@ export class WebSpeechSynthesisAdapter implements SpeechSynthesisAdapter {
|
|
|
64
79
|
if (res.status.type === "ended") return;
|
|
65
80
|
|
|
66
81
|
res.status = { type: "ended", reason, error };
|
|
67
|
-
subscribers
|
|
82
|
+
notifySpeechSynthesisListeners(subscribers);
|
|
68
83
|
};
|
|
69
84
|
|
|
70
85
|
utterance.addEventListener("end", () => handleEnd("finished"));
|
|
@@ -82,7 +97,7 @@ export class WebSpeechSynthesisAdapter implements SpeechSynthesisAdapter {
|
|
|
82
97
|
if (res.status.type === "ended") {
|
|
83
98
|
let cancelled = false;
|
|
84
99
|
queueMicrotask(() => {
|
|
85
|
-
if (!cancelled) callback
|
|
100
|
+
if (!cancelled) notifySpeechSynthesisListeners([callback]);
|
|
86
101
|
});
|
|
87
102
|
return () => {
|
|
88
103
|
cancelled = true;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { consumeSuggestionResult, createSuggestionAdapter } from "./suggestion";
|
|
3
|
+
import type { ThreadMessage } from "../types/message";
|
|
4
|
+
import type { ThreadSuggestion } from "../runtime/interfaces/thread-runtime-core";
|
|
5
|
+
|
|
6
|
+
const message = (
|
|
7
|
+
role: "user" | "assistant" | "system",
|
|
8
|
+
text: string,
|
|
9
|
+
id = `${role}-${text}`,
|
|
10
|
+
): ThreadMessage =>
|
|
11
|
+
({
|
|
12
|
+
id,
|
|
13
|
+
role,
|
|
14
|
+
content: text ? [{ type: "text", text }] : [],
|
|
15
|
+
createdAt: new Date(),
|
|
16
|
+
status:
|
|
17
|
+
role === "assistant" ? { type: "complete", reason: "stop" } : undefined,
|
|
18
|
+
metadata: {
|
|
19
|
+
unstable_state: null,
|
|
20
|
+
unstable_annotations: [],
|
|
21
|
+
unstable_data: [],
|
|
22
|
+
custom: {},
|
|
23
|
+
},
|
|
24
|
+
}) as unknown as ThreadMessage;
|
|
25
|
+
|
|
26
|
+
describe("createSuggestionAdapter", () => {
|
|
27
|
+
it("builds a role-labeled transcript from recent messages and honors maxMessages", async () => {
|
|
28
|
+
const complete = vi.fn().mockResolvedValue(["follow up"]);
|
|
29
|
+
const adapter = createSuggestionAdapter({ complete, maxMessages: 2 });
|
|
30
|
+
|
|
31
|
+
await adapter.generate({
|
|
32
|
+
messages: [
|
|
33
|
+
message("user", "first"),
|
|
34
|
+
message("assistant", "second"),
|
|
35
|
+
message("user", "third"),
|
|
36
|
+
message("assistant", "fourth"),
|
|
37
|
+
],
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(complete).toHaveBeenCalledTimes(1);
|
|
41
|
+
const prompt = complete.mock.calls[0]![0].prompt as string;
|
|
42
|
+
expect(prompt).toContain("user: third");
|
|
43
|
+
expect(prompt).toContain("assistant: fourth");
|
|
44
|
+
expect(prompt).not.toContain("user: first");
|
|
45
|
+
expect(prompt).not.toContain("assistant: second");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("skips messages with empty text in the transcript", async () => {
|
|
49
|
+
const complete = vi.fn().mockResolvedValue(["follow up"]);
|
|
50
|
+
const adapter = createSuggestionAdapter({ complete });
|
|
51
|
+
|
|
52
|
+
await adapter.generate({
|
|
53
|
+
messages: [
|
|
54
|
+
message("user", "hello"),
|
|
55
|
+
message("assistant", ""),
|
|
56
|
+
message("user", "again"),
|
|
57
|
+
],
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const prompt = complete.mock.calls[0]![0].prompt as string;
|
|
61
|
+
expect(prompt).toContain("user: hello");
|
|
62
|
+
expect(prompt).toContain("user: again");
|
|
63
|
+
expect(prompt).not.toMatch(/^assistant:/m);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("includes count and instructions in the prompt", async () => {
|
|
67
|
+
const complete = vi.fn().mockResolvedValue(["a", "b", "c", "d", "e"]);
|
|
68
|
+
const adapter = createSuggestionAdapter({
|
|
69
|
+
complete,
|
|
70
|
+
count: 5,
|
|
71
|
+
instructions: "Prefer short product questions",
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
await adapter.generate({
|
|
75
|
+
messages: [message("user", "hello")],
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const prompt = complete.mock.calls[0]![0].prompt as string;
|
|
79
|
+
expect(prompt).toContain("exactly 5");
|
|
80
|
+
expect(prompt).toContain("Prefer short product questions");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("trims, drops empties, and clamps results to count", async () => {
|
|
84
|
+
const complete = vi
|
|
85
|
+
.fn()
|
|
86
|
+
.mockResolvedValue([" one ", "", " ", "two", "three", "four"]);
|
|
87
|
+
const adapter = createSuggestionAdapter({ complete, count: 2 });
|
|
88
|
+
|
|
89
|
+
const result = await adapter.generate({
|
|
90
|
+
messages: [message("user", "hello")],
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
expect(result).toEqual([{ prompt: "one" }, { prompt: "two" }]);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("forwards the generate signal to complete when defined", async () => {
|
|
97
|
+
const complete = vi.fn().mockResolvedValue(["ok"]);
|
|
98
|
+
const adapter = createSuggestionAdapter({ complete });
|
|
99
|
+
const controller = new AbortController();
|
|
100
|
+
|
|
101
|
+
await adapter.generate({
|
|
102
|
+
messages: [message("user", "hello")],
|
|
103
|
+
signal: controller.signal,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
expect(complete).toHaveBeenCalledWith({
|
|
107
|
+
prompt: expect.any(String),
|
|
108
|
+
signal: controller.signal,
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("omits signal from complete options when generate has no signal", async () => {
|
|
113
|
+
const complete = vi.fn().mockResolvedValue(["ok"]);
|
|
114
|
+
const adapter = createSuggestionAdapter({ complete });
|
|
115
|
+
|
|
116
|
+
await adapter.generate({
|
|
117
|
+
messages: [message("user", "hello")],
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
expect(complete).toHaveBeenCalledWith({
|
|
121
|
+
prompt: expect.any(String),
|
|
122
|
+
});
|
|
123
|
+
expect(complete.mock.calls[0]![0]).not.toHaveProperty("signal");
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("treats maxMessages 0 as an empty transcript while still calling complete", async () => {
|
|
127
|
+
const complete = vi.fn().mockResolvedValue(["follow up"]);
|
|
128
|
+
const adapter = createSuggestionAdapter({ complete, maxMessages: 0 });
|
|
129
|
+
|
|
130
|
+
await adapter.generate({
|
|
131
|
+
messages: [message("user", "first"), message("assistant", "second")],
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
expect(complete).toHaveBeenCalledTimes(1);
|
|
135
|
+
const prompt = complete.mock.calls[0]![0].prompt as string;
|
|
136
|
+
expect(prompt).toContain("Conversation:\n");
|
|
137
|
+
expect(prompt).not.toContain("user: first");
|
|
138
|
+
expect(prompt).not.toContain("assistant: second");
|
|
139
|
+
expect(prompt).toContain("exactly 3");
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe("consumeSuggestionResult", () => {
|
|
144
|
+
it("calls onUpdate for each yield and stops after abort mid-stream", async () => {
|
|
145
|
+
const controller = new AbortController();
|
|
146
|
+
const updates: ThreadSuggestion[][] = [];
|
|
147
|
+
const onUpdate = vi.fn((s: readonly ThreadSuggestion[]) => {
|
|
148
|
+
updates.push([...s]);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
async function* generate() {
|
|
152
|
+
yield [{ prompt: "one" }];
|
|
153
|
+
yield [{ prompt: "two" }];
|
|
154
|
+
controller.abort();
|
|
155
|
+
yield [{ prompt: "three" }];
|
|
156
|
+
yield [{ prompt: "four" }];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
await consumeSuggestionResult(generate(), {
|
|
160
|
+
signal: controller.signal,
|
|
161
|
+
onUpdate,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
expect(onUpdate).toHaveBeenCalledTimes(2);
|
|
165
|
+
expect(updates).toEqual([[{ prompt: "one" }], [{ prompt: "two" }]]);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("drops the promise result when aborted before resolve", async () => {
|
|
169
|
+
const controller = new AbortController();
|
|
170
|
+
const onUpdate = vi.fn();
|
|
171
|
+
let resolve!: (value: readonly ThreadSuggestion[]) => void;
|
|
172
|
+
const promise = new Promise<readonly ThreadSuggestion[]>((r) => {
|
|
173
|
+
resolve = r;
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const consumption = consumeSuggestionResult(promise, {
|
|
177
|
+
signal: controller.signal,
|
|
178
|
+
onUpdate,
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
controller.abort();
|
|
182
|
+
resolve([{ prompt: "late" }]);
|
|
183
|
+
await consumption;
|
|
184
|
+
|
|
185
|
+
expect(onUpdate).not.toHaveBeenCalled();
|
|
186
|
+
});
|
|
187
|
+
});
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { ThreadMessage } from "../types/message";
|
|
2
2
|
import type { ThreadSuggestion } from "../runtime/interfaces/thread-runtime-core";
|
|
3
|
+
import { getThreadMessageText } from "../utils/text";
|
|
3
4
|
|
|
4
|
-
type SuggestionAdapterGenerateOptions = {
|
|
5
|
+
export type SuggestionAdapterGenerateOptions = {
|
|
5
6
|
messages: readonly ThreadMessage[];
|
|
7
|
+
signal?: AbortSignal;
|
|
6
8
|
};
|
|
7
9
|
|
|
8
10
|
export type SuggestionAdapter = {
|
|
@@ -12,3 +14,75 @@ export type SuggestionAdapter = {
|
|
|
12
14
|
| Promise<readonly ThreadSuggestion[]>
|
|
13
15
|
| AsyncGenerator<readonly ThreadSuggestion[], void>;
|
|
14
16
|
};
|
|
17
|
+
|
|
18
|
+
export const consumeSuggestionResult = async (
|
|
19
|
+
result: ReturnType<SuggestionAdapter["generate"]>,
|
|
20
|
+
options: {
|
|
21
|
+
signal: AbortSignal;
|
|
22
|
+
onUpdate: (suggestions: readonly ThreadSuggestion[]) => void;
|
|
23
|
+
},
|
|
24
|
+
): Promise<void> => {
|
|
25
|
+
const { signal, onUpdate } = options;
|
|
26
|
+
if (Symbol.asyncIterator in result) {
|
|
27
|
+
for await (const r of result) {
|
|
28
|
+
if (signal.aborted) break;
|
|
29
|
+
onUpdate(r);
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
const suggestions = await result;
|
|
33
|
+
if (signal.aborted) return;
|
|
34
|
+
onUpdate(suggestions);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type CreateSuggestionAdapterOptions = {
|
|
39
|
+
complete: (options: {
|
|
40
|
+
prompt: string;
|
|
41
|
+
signal?: AbortSignal;
|
|
42
|
+
}) => Promise<readonly string[]>;
|
|
43
|
+
count?: number | undefined;
|
|
44
|
+
instructions?: string | undefined;
|
|
45
|
+
maxMessages?: number | undefined;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const createSuggestionAdapter = (
|
|
49
|
+
options: CreateSuggestionAdapterOptions,
|
|
50
|
+
): SuggestionAdapter => {
|
|
51
|
+
const count = options.count ?? 3;
|
|
52
|
+
const maxMessages = options.maxMessages ?? 10;
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
async generate({ messages, signal }) {
|
|
56
|
+
const limit = Math.max(0, Math.floor(maxMessages));
|
|
57
|
+
const recent = limit === 0 ? [] : messages.slice(-limit);
|
|
58
|
+
const transcript = recent
|
|
59
|
+
.map((message) => {
|
|
60
|
+
const text = getThreadMessageText(message).trim();
|
|
61
|
+
if (!text) return null;
|
|
62
|
+
return `${message.role}: ${text}`;
|
|
63
|
+
})
|
|
64
|
+
.filter((line): line is string => line != null)
|
|
65
|
+
.join("\n");
|
|
66
|
+
|
|
67
|
+
let prompt =
|
|
68
|
+
`Based on the following conversation, suggest exactly ${count} short follow-up prompts that the USER would plausibly send next. ` +
|
|
69
|
+
`Write each prompt in the user's voice as something they would type. ` +
|
|
70
|
+
`Return only the prompts, one per line, with no numbering or extra commentary.\n\n` +
|
|
71
|
+
`Conversation:\n${transcript}`;
|
|
72
|
+
|
|
73
|
+
if (options.instructions) {
|
|
74
|
+
prompt += `\n\nAdditional instructions:\n${options.instructions}`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const results = await options.complete({
|
|
78
|
+
prompt,
|
|
79
|
+
...(signal !== undefined && { signal }),
|
|
80
|
+
});
|
|
81
|
+
return results
|
|
82
|
+
.map((s) => s.trim())
|
|
83
|
+
.filter((s) => s.length > 0)
|
|
84
|
+
.slice(0, count)
|
|
85
|
+
.map((text) => ({ prompt: text }));
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
};
|