@assistant-ui/core 0.2.20 → 0.2.21
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/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/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 +7 -1
- package/dist/internal.js +6 -2
- package/dist/model-context/frame/host.d.ts +0 -1
- package/dist/model-context/frame/host.d.ts.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/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/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/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 +122 -7
- 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/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/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/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/composer/ComposerAttachments.d.ts +4 -3
- package/dist/react/primitives/composer/ComposerAttachments.d.ts.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/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/MessageGroupedParts.d.ts +1 -6
- package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageParts.d.ts +42 -24
- package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageParts.js +2 -1
- 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/thread/ThreadMessages.d.ts +35 -17
- package/dist/react/primitives/thread/ThreadMessages.d.ts.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/threadList/ThreadListItems.d.ts +4 -3
- package/dist/react/primitives/threadList/ThreadListItems.d.ts.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/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/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 +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +3 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +21 -19
- 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/CloudFileAttachmentAdapter.d.ts +1 -4
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +6 -3
- 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 +42 -44
- 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 +2 -5
- package/dist/react/runtimes/useLocalRuntime.d.ts.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 +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-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 +0 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.js +17 -3
- 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 +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-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/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.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/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 +24 -15
- 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 +6 -4
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.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 +0 -1
- 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/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 +0 -1
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/tests/remote-thread-list-test-helpers.d.ts +0 -1
- package/dist/tests/remote-thread-list-test-helpers.d.ts.map +1 -1
- package/dist/types/attachment.d.ts +1 -1
- package/dist/types/attachment.d.ts.map +1 -1
- 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 +70 -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/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/text.d.ts +0 -1
- package/dist/utils/text.d.ts.map +1 -1
- package/package.json +12 -9
- 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/suggestion.test.ts +187 -0
- package/src/adapters/suggestion.ts +75 -1
- package/src/index.ts +15 -1
- package/src/internal.ts +16 -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 +222 -0
- package/src/react/adapters/LocalStorageThreadListAdapter.tsx +214 -7
- 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/useMessageError.test.ts +64 -0
- package/src/react/primitive-hooks/useMessageError.ts +19 -6
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +3 -1
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +48 -19
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.test.ts +111 -0
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +13 -3
- package/src/react/runtimes/cloud/auiV0.ts +71 -2
- package/src/react/runtimes/external-message-converter.test.tsx +102 -0
- package/src/react/runtimes/external-message-converter.ts +35 -10
- package/src/runtime/base/base-composer-runtime-core.ts +26 -7
- package/src/runtime/utils/message-repository.ts +8 -3
- package/src/runtime/utils/thread-message-like.ts +2 -0
- package/src/runtimes/local/local-thread-runtime-core.test.ts +127 -3
- package/src/runtimes/local/local-thread-runtime-core.ts +25 -23
- 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/tests/MessageRepository.test.ts +26 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +42 -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 +79 -5
- package/src/tests/base-composer-runtime-core-send.test.ts +145 -0
- package/src/tests/thread-message-like.test.ts +40 -0
- package/src/types/attachment.ts +1 -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 +11 -3
- 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
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
|
|
3
|
+
import { renderHook } from "@testing-library/react";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
import { useExternalMessageConverter } from "./external-message-converter";
|
|
6
|
+
|
|
7
|
+
type TestMessage = {
|
|
8
|
+
id: string;
|
|
9
|
+
role: "user" | "assistant";
|
|
10
|
+
text: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type TestMetadata = useExternalMessageConverter.Metadata & {
|
|
14
|
+
optimisticMessageId?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const convert: useExternalMessageConverter.Callback<TestMessage> = (
|
|
18
|
+
message,
|
|
19
|
+
metadata,
|
|
20
|
+
) => ({
|
|
21
|
+
role: message.role,
|
|
22
|
+
id: message.id,
|
|
23
|
+
content: [{ type: "text", text: message.text }],
|
|
24
|
+
metadata: {
|
|
25
|
+
...(message.role === "assistant" &&
|
|
26
|
+
message.id === (metadata as TestMetadata).optimisticMessageId && {
|
|
27
|
+
isOptimistic: true,
|
|
28
|
+
}),
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const MESSAGES: TestMessage[] = [
|
|
33
|
+
{ id: "u1", role: "user", text: "hi" },
|
|
34
|
+
{ id: "a1", role: "assistant", text: "hello" },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
const EMPTY: TestMetadata = {};
|
|
38
|
+
|
|
39
|
+
type Props = {
|
|
40
|
+
callback?: useExternalMessageConverter.Callback<TestMessage>;
|
|
41
|
+
metadata?: TestMetadata;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const renderConverter = (initialProps: Props = {}) =>
|
|
45
|
+
renderHook(
|
|
46
|
+
({ callback = convert, metadata = EMPTY }: Props) =>
|
|
47
|
+
useExternalMessageConverter<TestMessage>({
|
|
48
|
+
callback,
|
|
49
|
+
messages: MESSAGES,
|
|
50
|
+
isRunning: false,
|
|
51
|
+
metadata,
|
|
52
|
+
}),
|
|
53
|
+
{ initialProps },
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
describe("useExternalMessageConverter", () => {
|
|
57
|
+
it("reuses converted messages across rerenders when inputs are unchanged", () => {
|
|
58
|
+
const { result, rerender } = renderConverter();
|
|
59
|
+
|
|
60
|
+
const first = result.current;
|
|
61
|
+
rerender({});
|
|
62
|
+
|
|
63
|
+
expect(result.current[0]).toBe(first[0]);
|
|
64
|
+
expect(result.current[1]).toBe(first[1]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("re-converts cached messages when metadata changes", () => {
|
|
68
|
+
const { result, rerender } = renderConverter({
|
|
69
|
+
metadata: { optimisticMessageId: "a1" },
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
expect(result.current.at(-1)?.metadata.isOptimistic).toBe(true);
|
|
73
|
+
|
|
74
|
+
rerender({ metadata: {} });
|
|
75
|
+
|
|
76
|
+
expect(result.current.at(-1)?.metadata.isOptimistic).toBeUndefined();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("re-converts cached messages when the callback changes", () => {
|
|
80
|
+
const upper: useExternalMessageConverter.Callback<TestMessage> = (
|
|
81
|
+
message,
|
|
82
|
+
) => ({
|
|
83
|
+
role: message.role,
|
|
84
|
+
id: message.id,
|
|
85
|
+
content: [{ type: "text", text: message.text.toUpperCase() }],
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const { result, rerender } = renderConverter();
|
|
89
|
+
|
|
90
|
+
expect(result.current[1]?.content[0]).toMatchObject({
|
|
91
|
+
type: "text",
|
|
92
|
+
text: "hello",
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
rerender({ callback: upper });
|
|
96
|
+
|
|
97
|
+
expect(result.current[1]?.content[0]).toMatchObject({
|
|
98
|
+
type: "text",
|
|
99
|
+
text: "HELLO",
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useMemo } from "react";
|
|
3
|
+
import { useMemo, useState } from "react";
|
|
4
4
|
import { ThreadMessageConverter } from "../../runtimes/external-store/thread-message-converter";
|
|
5
5
|
import {
|
|
6
6
|
getExternalStoreMessages,
|
|
@@ -76,6 +76,11 @@ type CallbackResult<T> = {
|
|
|
76
76
|
outputs: useExternalMessageConverter.Message[];
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
+
type CallbackCacheEntry<T> = CallbackResult<T> & {
|
|
80
|
+
metadata: useExternalMessageConverter.Metadata;
|
|
81
|
+
callback: useExternalMessageConverter.Callback<T>;
|
|
82
|
+
};
|
|
83
|
+
|
|
79
84
|
type ChunkResult<T> = {
|
|
80
85
|
inputs: T[];
|
|
81
86
|
outputs: useExternalMessageConverter.Message[];
|
|
@@ -404,28 +409,48 @@ export const useExternalMessageConverter = <T extends WeakKey>({
|
|
|
404
409
|
joinStrategy?: JoinStrategy | undefined;
|
|
405
410
|
metadata?: useExternalMessageConverter.Metadata | undefined;
|
|
406
411
|
}) => {
|
|
412
|
+
// The caches live for the component lifetime; React Compiler hoists
|
|
413
|
+
// allocations without reactive dependencies out of useMemo, so re-creating
|
|
414
|
+
// them on dependency change would not survive compilation. Staleness is
|
|
415
|
+
// instead tracked per entry via the metadata/callback that produced it,
|
|
416
|
+
// keeping correctness independent of memoization (which React treats as
|
|
417
|
+
// droppable). A "use no memo" opt-out would restore the useMemo semantics
|
|
418
|
+
// but leave cache flushing coupled to memo firing.
|
|
419
|
+
const [caches] = useState(() => ({
|
|
420
|
+
callbackCache: new WeakMap<T, CallbackCacheEntry<T>>(),
|
|
421
|
+
chunkCache: new WeakMap<
|
|
422
|
+
useExternalMessageConverter.Message,
|
|
423
|
+
ChunkResult<T>
|
|
424
|
+
>(),
|
|
425
|
+
converterCache: new ThreadMessageConverter(),
|
|
426
|
+
}));
|
|
427
|
+
|
|
407
428
|
const state = useMemo(
|
|
408
429
|
() => ({
|
|
409
430
|
metadata: metadata ?? {},
|
|
410
431
|
callback,
|
|
411
|
-
|
|
412
|
-
chunkCache: new WeakMap<
|
|
413
|
-
useExternalMessageConverter.Message,
|
|
414
|
-
ChunkResult<T>
|
|
415
|
-
>(),
|
|
416
|
-
converterCache: new ThreadMessageConverter(),
|
|
432
|
+
...caches,
|
|
417
433
|
}),
|
|
418
|
-
[callback, metadata],
|
|
434
|
+
[callback, metadata, caches],
|
|
419
435
|
);
|
|
420
436
|
|
|
421
437
|
return useMemo(() => {
|
|
422
438
|
const callbackResults: CallbackResult<T>[] = [];
|
|
423
439
|
for (const message of messages) {
|
|
424
440
|
let result = state.callbackCache.get(message);
|
|
425
|
-
if (
|
|
441
|
+
if (
|
|
442
|
+
!result ||
|
|
443
|
+
result.metadata !== state.metadata ||
|
|
444
|
+
result.callback !== state.callback
|
|
445
|
+
) {
|
|
426
446
|
const output = state.callback(message, state.metadata);
|
|
427
447
|
const outputs = Array.isArray(output) ? output : [output];
|
|
428
|
-
result = {
|
|
448
|
+
result = {
|
|
449
|
+
input: message,
|
|
450
|
+
outputs,
|
|
451
|
+
metadata: state.metadata,
|
|
452
|
+
callback: state.callback,
|
|
453
|
+
};
|
|
429
454
|
state.callbackCache.set(message, result);
|
|
430
455
|
}
|
|
431
456
|
callbackResults.push(result);
|
|
@@ -195,16 +195,30 @@ export abstract class BaseComposerRuntimeCore
|
|
|
195
195
|
)
|
|
196
196
|
: [];
|
|
197
197
|
|
|
198
|
+
const originalAttachments = this.attachments;
|
|
198
199
|
const text = this.text;
|
|
199
200
|
const quote = this._quote;
|
|
200
201
|
this._quote = undefined;
|
|
201
202
|
this._emptyTextAndAttachments();
|
|
202
203
|
|
|
204
|
+
let resolvedAttachments: Awaited<typeof attachments>;
|
|
205
|
+
try {
|
|
206
|
+
resolvedAttachments = await attachments;
|
|
207
|
+
} catch (e) {
|
|
208
|
+
if (this.isEmpty && this._quote === undefined) {
|
|
209
|
+
this._attachments = originalAttachments;
|
|
210
|
+
this._text = text;
|
|
211
|
+
this._quote = quote;
|
|
212
|
+
this._notifySubscribers();
|
|
213
|
+
}
|
|
214
|
+
throw e;
|
|
215
|
+
}
|
|
216
|
+
|
|
203
217
|
const message: Omit<AppendMessage, "parentId" | "sourceId"> = {
|
|
204
218
|
createdAt: new Date(),
|
|
205
219
|
role: this.role,
|
|
206
220
|
content: text ? [{ type: "text", text }] : [],
|
|
207
|
-
attachments:
|
|
221
|
+
attachments: resolvedAttachments,
|
|
208
222
|
runConfig: this.runConfig,
|
|
209
223
|
metadata: { custom: { ...(quote ? { quote } : {}) } },
|
|
210
224
|
};
|
|
@@ -321,7 +335,11 @@ export abstract class BaseComposerRuntimeCore
|
|
|
321
335
|
if (lastAttachment) {
|
|
322
336
|
upsertAttachment({
|
|
323
337
|
...lastAttachment,
|
|
324
|
-
status: {
|
|
338
|
+
status: {
|
|
339
|
+
type: "incomplete",
|
|
340
|
+
reason: "error",
|
|
341
|
+
message: e instanceof Error ? e.message : String(e),
|
|
342
|
+
},
|
|
325
343
|
});
|
|
326
344
|
}
|
|
327
345
|
this._safeEmitAttachmentAddError(
|
|
@@ -333,14 +351,15 @@ export abstract class BaseComposerRuntimeCore
|
|
|
333
351
|
throw e;
|
|
334
352
|
}
|
|
335
353
|
|
|
336
|
-
|
|
354
|
+
if (
|
|
337
355
|
lastAttachment?.status.type === "incomplete" &&
|
|
338
|
-
lastAttachment.status.reason === "error"
|
|
339
|
-
|
|
356
|
+
lastAttachment.status.reason === "error"
|
|
357
|
+
) {
|
|
340
358
|
this._safeEmitAttachmentAddError(
|
|
341
359
|
"adapter-error",
|
|
342
|
-
|
|
343
|
-
|
|
360
|
+
lastAttachment.status.message ??
|
|
361
|
+
"Attachment upload did not complete successfully.",
|
|
362
|
+
lastAttachment.id,
|
|
344
363
|
);
|
|
345
364
|
} else {
|
|
346
365
|
this._notifyEventSubscribers("attachmentAdd", {});
|
|
@@ -436,13 +436,18 @@ export class MessageRepository {
|
|
|
436
436
|
export(): ExportedMessageRepository {
|
|
437
437
|
const exportItems: ExportedMessageRepository["messages"] = [];
|
|
438
438
|
|
|
439
|
-
// Optimistic messages are ephemeral and never persisted.
|
|
440
|
-
//
|
|
439
|
+
// Optimistic messages are ephemeral and never persisted. A persisted child
|
|
440
|
+
// of an optimistic node is re-parented onto its nearest persisted ancestor
|
|
441
|
+
// so the exported tree never references a skipped id.
|
|
441
442
|
for (const [, message] of this.messages) {
|
|
442
443
|
if (message.current.metadata?.isOptimistic) continue;
|
|
444
|
+
let prev = message.prev;
|
|
445
|
+
while (prev && prev.current.metadata?.isOptimistic) {
|
|
446
|
+
prev = prev.prev;
|
|
447
|
+
}
|
|
443
448
|
exportItems.push({
|
|
444
449
|
message: message.current,
|
|
445
|
-
parentId:
|
|
450
|
+
parentId: prev?.current.id ?? null,
|
|
446
451
|
});
|
|
447
452
|
}
|
|
448
453
|
|
|
@@ -20,6 +20,7 @@ import type {
|
|
|
20
20
|
import type { CompleteAttachment } from "../../types/attachment";
|
|
21
21
|
import type {
|
|
22
22
|
MessageTiming,
|
|
23
|
+
PartProviderMetadata,
|
|
23
24
|
TextMessagePart,
|
|
24
25
|
ToolApprovalOption,
|
|
25
26
|
ToolCallTiming,
|
|
@@ -61,6 +62,7 @@ export type ThreadMessageLike = {
|
|
|
61
62
|
readonly messages?: readonly ThreadMessage[] | undefined;
|
|
62
63
|
readonly interrupt?: { type: "human"; payload: unknown };
|
|
63
64
|
readonly timing?: ToolCallTiming;
|
|
65
|
+
readonly providerMetadata?: PartProviderMetadata;
|
|
64
66
|
readonly approval?: {
|
|
65
67
|
readonly id: string;
|
|
66
68
|
readonly approved?: boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
2
|
import { LocalRuntimeCore } from "./local-runtime-core";
|
|
3
3
|
import type {
|
|
4
4
|
ChatModelAdapter,
|
|
@@ -6,13 +6,24 @@ import type {
|
|
|
6
6
|
ChatModelRunResult,
|
|
7
7
|
} from "../../runtime/utils/chat-model-adapter";
|
|
8
8
|
import type { AppendMessage } from "../../types/message";
|
|
9
|
+
import type { LocalRuntimeOptionsBase } from "./local-runtime-options";
|
|
9
10
|
|
|
10
11
|
const flush = () => new Promise((resolve) => setTimeout(resolve, 10));
|
|
11
12
|
|
|
12
|
-
const createThread = (
|
|
13
|
+
const createThread = (
|
|
14
|
+
adapter: ChatModelAdapter,
|
|
15
|
+
options?: {
|
|
16
|
+
suggestion?: LocalRuntimeOptionsBase["adapters"]["suggestion"];
|
|
17
|
+
},
|
|
18
|
+
) => {
|
|
13
19
|
const core = new LocalRuntimeCore(
|
|
14
20
|
{
|
|
15
|
-
adapters: {
|
|
21
|
+
adapters: {
|
|
22
|
+
chatModel: adapter,
|
|
23
|
+
...(options?.suggestion !== undefined && {
|
|
24
|
+
suggestion: options.suggestion,
|
|
25
|
+
}),
|
|
26
|
+
},
|
|
16
27
|
unstable_humanToolNames: ["send_email"],
|
|
17
28
|
},
|
|
18
29
|
undefined,
|
|
@@ -117,6 +128,34 @@ describe("LocalThreadRuntimeCore human-in-the-loop tools", () => {
|
|
|
117
128
|
"text",
|
|
118
129
|
]);
|
|
119
130
|
});
|
|
131
|
+
|
|
132
|
+
it.each([
|
|
133
|
+
["false", false],
|
|
134
|
+
["zero", 0],
|
|
135
|
+
["an empty string", ""],
|
|
136
|
+
["null", null],
|
|
137
|
+
])("resumes when the tool result is %s", async (_label, result) => {
|
|
138
|
+
const { thread, runs } = createApprovalThread(toolCallResult("send_email"));
|
|
139
|
+
|
|
140
|
+
await thread.append(userMessage("send an email"));
|
|
141
|
+
await flush();
|
|
142
|
+
|
|
143
|
+
thread.addToolResult({
|
|
144
|
+
messageId: thread.messages.at(-1)!.id,
|
|
145
|
+
toolCallId: "call-send_email",
|
|
146
|
+
toolName: "send_email",
|
|
147
|
+
result,
|
|
148
|
+
isError: false,
|
|
149
|
+
});
|
|
150
|
+
await flush();
|
|
151
|
+
|
|
152
|
+
expect(runs).toHaveLength(2);
|
|
153
|
+
const toolCall = runs[1]!
|
|
154
|
+
.unstable_getMessage()
|
|
155
|
+
.content.find((part) => part.type === "tool-call");
|
|
156
|
+
expect(toolCall?.result).toEqual(result);
|
|
157
|
+
expect(thread.messages.at(-1)?.status?.type).toBe("complete");
|
|
158
|
+
});
|
|
120
159
|
});
|
|
121
160
|
|
|
122
161
|
describe("LocalThreadRuntimeCore tool approvals", () => {
|
|
@@ -368,3 +407,88 @@ describe("LocalThreadRuntimeCore tool approvals", () => {
|
|
|
368
407
|
).toThrowError(/unstable_humanToolNames/);
|
|
369
408
|
});
|
|
370
409
|
});
|
|
410
|
+
|
|
411
|
+
describe("LocalThreadRuntimeCore suggestions", () => {
|
|
412
|
+
it("cancelRun aborts pending suggestion generation", async () => {
|
|
413
|
+
const generate = vi.fn().mockImplementation(
|
|
414
|
+
({ signal }: { signal?: AbortSignal }) =>
|
|
415
|
+
new Promise<readonly { prompt: string }[]>((resolve) => {
|
|
416
|
+
signal?.addEventListener("abort", () => {
|
|
417
|
+
resolve([{ prompt: "stale" }]);
|
|
418
|
+
});
|
|
419
|
+
}),
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
const thread = createThread(
|
|
423
|
+
{
|
|
424
|
+
async run() {
|
|
425
|
+
return { content: [{ type: "text", text: "hello" }] };
|
|
426
|
+
},
|
|
427
|
+
},
|
|
428
|
+
{ suggestion: { generate } },
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
const appendPromise = thread.append(userMessage("hi"));
|
|
432
|
+
await appendPromise;
|
|
433
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
434
|
+
|
|
435
|
+
expect(generate).toHaveBeenCalledTimes(1);
|
|
436
|
+
const signal = generate.mock.calls[0]![0].signal as AbortSignal;
|
|
437
|
+
expect(signal.aborted).toBe(false);
|
|
438
|
+
|
|
439
|
+
thread.cancelRun();
|
|
440
|
+
expect(signal.aborted).toBe(true);
|
|
441
|
+
expect(thread.suggestions).toEqual([]);
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
it("completes the run when suggestion generation rejects", async () => {
|
|
445
|
+
const generate = vi.fn().mockRejectedValue(new Error("suggestion failed"));
|
|
446
|
+
|
|
447
|
+
const thread = createThread(
|
|
448
|
+
{
|
|
449
|
+
async run() {
|
|
450
|
+
return { content: [{ type: "text", text: "hello" }] };
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
{ suggestion: { generate } },
|
|
454
|
+
);
|
|
455
|
+
|
|
456
|
+
await thread.append(userMessage("hi"));
|
|
457
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
458
|
+
|
|
459
|
+
expect(generate).toHaveBeenCalledTimes(1);
|
|
460
|
+
expect(thread.messages.at(-1)?.status?.type).toBe("complete");
|
|
461
|
+
expect(thread.suggestions).toEqual([]);
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
it("resolves append before suggestion generation completes", async () => {
|
|
465
|
+
let resolveSuggestions!: (value: readonly { prompt: string }[]) => void;
|
|
466
|
+
const suggestionsDeferred = new Promise<readonly { prompt: string }[]>(
|
|
467
|
+
(resolve) => {
|
|
468
|
+
resolveSuggestions = resolve;
|
|
469
|
+
},
|
|
470
|
+
);
|
|
471
|
+
const generate = vi.fn().mockReturnValue(suggestionsDeferred);
|
|
472
|
+
|
|
473
|
+
const thread = createThread(
|
|
474
|
+
{
|
|
475
|
+
async run() {
|
|
476
|
+
return { content: [{ type: "text", text: "hello" }] };
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
{ suggestion: { generate } },
|
|
480
|
+
);
|
|
481
|
+
|
|
482
|
+
await thread.append(userMessage("hi"));
|
|
483
|
+
expect(thread.messages.at(-1)?.status?.type).toBe("complete");
|
|
484
|
+
expect(thread.suggestions).toEqual([]);
|
|
485
|
+
|
|
486
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
487
|
+
expect(generate).toHaveBeenCalledTimes(1);
|
|
488
|
+
expect(thread.suggestions).toEqual([]);
|
|
489
|
+
|
|
490
|
+
resolveSuggestions([{ prompt: "follow up" }]);
|
|
491
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
492
|
+
expect(thread.suggestions).toEqual([{ prompt: "follow up" }]);
|
|
493
|
+
});
|
|
494
|
+
});
|
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
} from "../../runtime/utils/chat-model-adapter";
|
|
7
7
|
import { shouldContinue } from "./should-continue";
|
|
8
8
|
import type { LocalRuntimeOptionsBase } from "./local-runtime-options";
|
|
9
|
+
import { consumeSuggestionResult } from "../../adapters/suggestion";
|
|
9
10
|
import type {
|
|
10
11
|
AddToolResultOptions,
|
|
11
12
|
ResumeToolCallOptions,
|
|
@@ -21,6 +22,7 @@ import type {
|
|
|
21
22
|
ThreadAssistantMessage,
|
|
22
23
|
} from "../../types/message";
|
|
23
24
|
import type { RunConfig } from "../../types/message";
|
|
25
|
+
import { toAssistantError } from "../../types/error";
|
|
24
26
|
import type { ModelContextProvider } from "../../model-context/types";
|
|
25
27
|
import {
|
|
26
28
|
createMessageQueue,
|
|
@@ -375,28 +377,28 @@ export class LocalThreadRuntimeCore
|
|
|
375
377
|
}
|
|
376
378
|
}
|
|
377
379
|
|
|
378
|
-
this._suggestionsController = new AbortController();
|
|
379
|
-
const signal = this._suggestionsController.signal;
|
|
380
380
|
if (
|
|
381
381
|
this.adapters.suggestion &&
|
|
382
382
|
message.status?.type !== "requires-action"
|
|
383
383
|
) {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
384
|
+
this._suggestionsController = new AbortController();
|
|
385
|
+
const signal = this._suggestionsController.signal;
|
|
386
|
+
const adapter = this.adapters.suggestion;
|
|
387
|
+
void (async () => {
|
|
388
|
+
try {
|
|
389
|
+
const promiseOrGenerator = adapter.generate({
|
|
390
|
+
messages: this.messages,
|
|
391
|
+
signal,
|
|
392
|
+
});
|
|
393
|
+
await consumeSuggestionResult(promiseOrGenerator, {
|
|
394
|
+
signal,
|
|
395
|
+
onUpdate: (r) => {
|
|
396
|
+
this._suggestions = r;
|
|
397
|
+
this._notifySubscribers();
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
} catch {}
|
|
401
|
+
})();
|
|
400
402
|
}
|
|
401
403
|
}
|
|
402
404
|
|
|
@@ -539,7 +541,6 @@ export class LocalThreadRuntimeCore
|
|
|
539
541
|
});
|
|
540
542
|
}
|
|
541
543
|
} catch (e) {
|
|
542
|
-
// TODO this should be handled by the run result stream
|
|
543
544
|
if (e instanceof AbortError) {
|
|
544
545
|
updateMessage({
|
|
545
546
|
status: { type: "incomplete", reason: "cancelled" },
|
|
@@ -553,10 +554,7 @@ export class LocalThreadRuntimeCore
|
|
|
553
554
|
status: {
|
|
554
555
|
type: "incomplete",
|
|
555
556
|
reason: "error",
|
|
556
|
-
error:
|
|
557
|
-
e instanceof Error
|
|
558
|
-
? e.message
|
|
559
|
-
: `[${typeof e}] ${new String(e).toString()}`,
|
|
557
|
+
error: toAssistantError(e),
|
|
560
558
|
},
|
|
561
559
|
});
|
|
562
560
|
|
|
@@ -584,6 +582,8 @@ export class LocalThreadRuntimeCore
|
|
|
584
582
|
const error = new AbortError(true);
|
|
585
583
|
this.abortController?.abort(error);
|
|
586
584
|
this.abortController = null;
|
|
585
|
+
this._suggestionsController?.abort();
|
|
586
|
+
this._suggestionsController = null;
|
|
587
587
|
}
|
|
588
588
|
|
|
589
589
|
public cancelRun() {
|
|
@@ -591,6 +591,8 @@ export class LocalThreadRuntimeCore
|
|
|
591
591
|
const error = new AbortError(false);
|
|
592
592
|
this.abortController?.abort(error);
|
|
593
593
|
this.abortController = null;
|
|
594
|
+
this._suggestionsController?.abort();
|
|
595
|
+
this._suggestionsController = null;
|
|
594
596
|
}
|
|
595
597
|
|
|
596
598
|
public addToolResult({
|
|
@@ -23,14 +23,17 @@ export const shouldContinue = (
|
|
|
23
23
|
// TODO legacy behavior -- make specifying human tool names required
|
|
24
24
|
if (humanToolNames === undefined) {
|
|
25
25
|
return result.content.every(
|
|
26
|
-
(c) =>
|
|
26
|
+
(c) =>
|
|
27
|
+
c.type !== "tool-call" ||
|
|
28
|
+
c.result !== undefined ||
|
|
29
|
+
c.approval !== undefined,
|
|
27
30
|
);
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
return result.content.every(
|
|
31
34
|
(c) =>
|
|
32
35
|
c.type !== "tool-call" ||
|
|
33
|
-
|
|
36
|
+
c.result !== undefined ||
|
|
34
37
|
c.approval !== undefined ||
|
|
35
38
|
!humanToolNames.includes(c.toolName),
|
|
36
39
|
);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { InMemoryThreadListAdapter } from "./in-memory";
|
|
3
|
+
|
|
4
|
+
describe("InMemoryThreadListAdapter", () => {
|
|
5
|
+
it("closes its title stream when title generation is unsupported", async () => {
|
|
6
|
+
const adapter = new InMemoryThreadListAdapter();
|
|
7
|
+
const stream = await adapter.generateTitle();
|
|
8
|
+
|
|
9
|
+
await expect(stream.getReader().read()).resolves.toEqual({
|
|
10
|
+
done: true,
|
|
11
|
+
value: undefined,
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -38,10 +38,18 @@ export class InMemoryThreadListAdapter implements RemoteThreadListAdapter {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
generateTitle(): Promise<AssistantStream> {
|
|
41
|
-
return Promise.resolve(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
return Promise.resolve(
|
|
42
|
+
new ReadableStream<AssistantStreamChunk>({
|
|
43
|
+
start(controller) {
|
|
44
|
+
controller.close();
|
|
45
|
+
},
|
|
46
|
+
}),
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
fetch(threadId: string): Promise<RemoteThreadMetadata> {
|
|
51
|
+
return Promise.reject(
|
|
52
|
+
new Error(`Thread "${threadId}" not found in in-memory thread list.`),
|
|
53
|
+
);
|
|
46
54
|
}
|
|
47
55
|
}
|
|
@@ -309,6 +309,32 @@ describe("MessageRepository", () => {
|
|
|
309
309
|
expect(exported.headId).toBe("u");
|
|
310
310
|
});
|
|
311
311
|
|
|
312
|
+
it("re-parents children of a skipped optimistic message in export()", () => {
|
|
313
|
+
repository.addOrUpdateMessage(null, createTestMessage({ id: "u1" }));
|
|
314
|
+
repository.addOrUpdateMessage("u1", optimistic({ id: "a1" }));
|
|
315
|
+
repository.addOrUpdateMessage(
|
|
316
|
+
"a1",
|
|
317
|
+
createTestMessage({ id: "u2", role: "user" }),
|
|
318
|
+
);
|
|
319
|
+
repository.addOrUpdateMessage("u2", createTestMessage({ id: "a2" }));
|
|
320
|
+
repository.resetHead("a2");
|
|
321
|
+
|
|
322
|
+
const exported = repository.export();
|
|
323
|
+
const byId = new Map(exported.messages.map((m) => [m.message.id, m]));
|
|
324
|
+
|
|
325
|
+
expect([...byId.keys()].sort()).toEqual(["a2", "u1", "u2"]);
|
|
326
|
+
expect(byId.get("u2")?.parentId).toBe("u1");
|
|
327
|
+
expect(byId.get("a2")?.parentId).toBe("u2");
|
|
328
|
+
|
|
329
|
+
const restored = new MessageRepository();
|
|
330
|
+
restored.import(exported);
|
|
331
|
+
expect(restored.getMessages().map((m) => m.id)).toEqual([
|
|
332
|
+
"u1",
|
|
333
|
+
"u2",
|
|
334
|
+
"a2",
|
|
335
|
+
]);
|
|
336
|
+
});
|
|
337
|
+
|
|
312
338
|
it("round-trips through export/import without resurrecting the placeholder", () => {
|
|
313
339
|
const parent = createTestMessage({ id: "u" });
|
|
314
340
|
const real = createTestMessage({ id: "a" });
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import { createCore, makeAdapter } from "./remote-thread-list-test-helpers";
|
|
3
|
+
import { InMemoryThreadListAdapter } from "../runtimes/remote-thread-list/adapter/in-memory";
|
|
4
|
+
|
|
5
|
+
describe("RemoteThreadListThreadListRuntimeCore errors", () => {
|
|
6
|
+
it("includes the requested thread id when a thread is missing", () => {
|
|
7
|
+
const core = createCore(makeAdapter());
|
|
8
|
+
|
|
9
|
+
expect(() => core.rename("missing-thread", "New title")).toThrow(
|
|
10
|
+
'Thread "missing-thread" not found while renaming it.',
|
|
11
|
+
);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("includes the requested thread id and status when an operation is invalid", async () => {
|
|
15
|
+
const adapter = makeAdapter({
|
|
16
|
+
list: vi.fn(async () => ({
|
|
17
|
+
threads: [
|
|
18
|
+
{
|
|
19
|
+
status: "archived" as const,
|
|
20
|
+
remoteId: "archived-thread",
|
|
21
|
+
externalId: "archived-thread",
|
|
22
|
+
title: "Archived",
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
})),
|
|
26
|
+
});
|
|
27
|
+
const core = createCore(adapter);
|
|
28
|
+
await core.getLoadThreadsPromise();
|
|
29
|
+
|
|
30
|
+
await expect(core.archive("archived-thread")).rejects.toThrow(
|
|
31
|
+
'Thread "archived-thread" has status "archived", so it cannot be archived.',
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("includes the requested thread id when the in-memory adapter cannot fetch it", async () => {
|
|
36
|
+
const adapter = new InMemoryThreadListAdapter();
|
|
37
|
+
|
|
38
|
+
await expect(adapter.fetch("missing-thread")).rejects.toThrow(
|
|
39
|
+
'Thread "missing-thread" not found in in-memory thread list.',
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
});
|