@assistant-ui/core 0.2.19 → 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/generativeUI/GenerativeUI.js +1 -1
- package/dist/react/primitives/generativeUI/GenerativeUI.js.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/primitives/generativeUI/GenerativeUI.tsx +5 -1
- 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,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,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
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ export type {
|
|
|
12
12
|
// Message parts
|
|
13
13
|
TextMessagePart,
|
|
14
14
|
ReasoningMessagePart,
|
|
15
|
+
PartProviderMetadata,
|
|
15
16
|
SourceProviderMetadata,
|
|
16
17
|
SourceMessagePart,
|
|
17
18
|
ImageMessagePart,
|
|
@@ -149,7 +150,12 @@ export type {
|
|
|
149
150
|
export type { FeedbackAdapter } from "./adapters/feedback";
|
|
150
151
|
|
|
151
152
|
// Suggestion adapter
|
|
152
|
-
export type {
|
|
153
|
+
export type {
|
|
154
|
+
SuggestionAdapter,
|
|
155
|
+
SuggestionAdapterGenerateOptions,
|
|
156
|
+
CreateSuggestionAdapterOptions,
|
|
157
|
+
} from "./adapters/suggestion";
|
|
158
|
+
export { createSuggestionAdapter } from "./adapters/suggestion";
|
|
153
159
|
|
|
154
160
|
// Directive formatter
|
|
155
161
|
export { unstable_defaultDirectiveFormatter } from "./adapters/directive-formatter";
|
|
@@ -188,6 +194,14 @@ export type {
|
|
|
188
194
|
ThreadComposerRuntimeCore,
|
|
189
195
|
} from "./runtime/interfaces/composer-runtime-core";
|
|
190
196
|
|
|
197
|
+
export type {
|
|
198
|
+
ErrorSeverity,
|
|
199
|
+
ErrorDisplay,
|
|
200
|
+
AssistantErrorCode,
|
|
201
|
+
AssistantError,
|
|
202
|
+
} from "./types/error";
|
|
203
|
+
export { toAssistantError, isAssistantError } from "./types/error";
|
|
204
|
+
|
|
191
205
|
export type {
|
|
192
206
|
RuntimeCapabilities,
|
|
193
207
|
AddToolResultOptions,
|
package/src/internal.ts
CHANGED
|
@@ -33,10 +33,26 @@ export {
|
|
|
33
33
|
// Message utilities
|
|
34
34
|
export { getThreadMessageText } from "./utils/text";
|
|
35
35
|
export { resolveToolApprovalResponse } from "./runtime/utils/resolveToolApprovalResponse";
|
|
36
|
+
export { consumeSuggestionResult } from "./adapters/suggestion";
|
|
36
37
|
|
|
37
38
|
// Composite context provider
|
|
38
39
|
export { CompositeContextProvider } from "./utils/composite-context-provider";
|
|
39
40
|
|
|
41
|
+
// Shared attachment data-URL encoder, reused by framework adapters so the
|
|
42
|
+
// FileReader fallback lives in one place.
|
|
43
|
+
export { getFileDataURL } from "./adapters/attachment";
|
|
44
|
+
|
|
45
|
+
// Streaming-stable tool-args stringifier, reused by framework adapters so the
|
|
46
|
+
// key-order stabilization lives in one place.
|
|
47
|
+
export {
|
|
48
|
+
stableStringifyToolArgs,
|
|
49
|
+
trackToolArgsKeyOrder,
|
|
50
|
+
} from "./utils/json/stable-stringify-tool-args";
|
|
51
|
+
|
|
52
|
+
// JSON type guards, reused by framework bindings so the depth-guarded
|
|
53
|
+
// validation lives in one place.
|
|
54
|
+
export { isJSONValue, isRecord } from "./utils/json/is-json";
|
|
55
|
+
|
|
40
56
|
// Runtime extras helper for external-store adapters. Internal because the
|
|
41
57
|
// tap-native runtime path replaces the `thread.extras` side-channel it wraps.
|
|
42
58
|
export {
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { describe, expect, expectTypeOf, it } from "vitest";
|
|
2
|
+
import type { Tool } from "assistant-stream";
|
|
3
|
+
import type { AsyncIterableStream } from "assistant-stream/utils";
|
|
4
|
+
import { tool } from "./tool";
|
|
5
|
+
|
|
6
|
+
type TestStandardSchema<TInput> = {
|
|
7
|
+
readonly "~standard": {
|
|
8
|
+
readonly version: 1;
|
|
9
|
+
readonly vendor: "test";
|
|
10
|
+
readonly types?: {
|
|
11
|
+
readonly input: TInput;
|
|
12
|
+
readonly output: TInput;
|
|
13
|
+
};
|
|
14
|
+
readonly validate: (value: unknown) => { readonly value: TInput };
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const checkStandardSchemaInference = () => {
|
|
19
|
+
const weatherSchema = {} as TestStandardSchema<{
|
|
20
|
+
city: string;
|
|
21
|
+
unit?: "c" | "f";
|
|
22
|
+
tags: string[];
|
|
23
|
+
}>;
|
|
24
|
+
|
|
25
|
+
const getWeather = tool({
|
|
26
|
+
type: "frontend",
|
|
27
|
+
parameters: weatherSchema,
|
|
28
|
+
execute: async (args) => {
|
|
29
|
+
expectTypeOf(args.city).toEqualTypeOf<string>();
|
|
30
|
+
expectTypeOf(args.unit).toEqualTypeOf<"c" | "f" | undefined>();
|
|
31
|
+
expectTypeOf(args.tags).toEqualTypeOf<string[]>();
|
|
32
|
+
// @ts-expect-error unknown schema fields should not be accepted
|
|
33
|
+
void args.missing;
|
|
34
|
+
|
|
35
|
+
return `Weather in ${args.city}`;
|
|
36
|
+
},
|
|
37
|
+
streamCall: async (reader) => {
|
|
38
|
+
const city = await reader.args.get("city");
|
|
39
|
+
expectTypeOf(city).toEqualTypeOf<string>();
|
|
40
|
+
expectTypeOf(reader.args.forEach("tags")).toEqualTypeOf<
|
|
41
|
+
AsyncIterableStream<string>
|
|
42
|
+
>();
|
|
43
|
+
// @ts-expect-error unknown argument paths should not be accepted
|
|
44
|
+
reader.args.get("missing");
|
|
45
|
+
},
|
|
46
|
+
toModelOutput: ({ input }) => {
|
|
47
|
+
expectTypeOf(input.city).toEqualTypeOf<string>();
|
|
48
|
+
expectTypeOf(input.unit).toEqualTypeOf<"c" | "f" | undefined>();
|
|
49
|
+
return [{ type: "text", text: input.city }];
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
expectTypeOf(getWeather).toEqualTypeOf<
|
|
54
|
+
Tool<
|
|
55
|
+
{
|
|
56
|
+
city: string;
|
|
57
|
+
unit?: "c" | "f";
|
|
58
|
+
tags: string[];
|
|
59
|
+
},
|
|
60
|
+
string
|
|
61
|
+
>
|
|
62
|
+
>();
|
|
63
|
+
};
|
|
64
|
+
expectTypeOf(checkStandardSchemaInference).toEqualTypeOf<() => void>();
|
|
65
|
+
|
|
66
|
+
const checkUnknownStandardSchemaInputFallsBackToRecord = () => {
|
|
67
|
+
const unknownSchema = {} as TestStandardSchema<unknown>;
|
|
68
|
+
|
|
69
|
+
const passthrough = tool({
|
|
70
|
+
type: "frontend",
|
|
71
|
+
parameters: unknownSchema,
|
|
72
|
+
execute: async (args) => {
|
|
73
|
+
expectTypeOf(args).toEqualTypeOf<Record<string, unknown>>();
|
|
74
|
+
return args;
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
expectTypeOf(passthrough).toEqualTypeOf<
|
|
79
|
+
Tool<Record<string, unknown>, Record<string, unknown>>
|
|
80
|
+
>();
|
|
81
|
+
};
|
|
82
|
+
expectTypeOf(checkUnknownStandardSchemaInputFallsBackToRecord).toEqualTypeOf<
|
|
83
|
+
() => void
|
|
84
|
+
>();
|
|
85
|
+
|
|
86
|
+
const checkExplicitJsonSchemaTypesStillWork = () => {
|
|
87
|
+
const getWeather = tool<{ city: string }, string>({
|
|
88
|
+
type: "frontend",
|
|
89
|
+
parameters: {
|
|
90
|
+
type: "object",
|
|
91
|
+
properties: { city: { type: "string" } },
|
|
92
|
+
required: ["city"],
|
|
93
|
+
},
|
|
94
|
+
execute: async ({ city }) => city,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
expectTypeOf(getWeather).toEqualTypeOf<Tool<{ city: string }, string>>();
|
|
98
|
+
};
|
|
99
|
+
expectTypeOf(checkExplicitJsonSchemaTypesStillWork).toEqualTypeOf<() => void>();
|
|
100
|
+
|
|
101
|
+
describe("tool", () => {
|
|
102
|
+
it("returns the tool definition at runtime", () => {
|
|
103
|
+
const definition = {
|
|
104
|
+
type: "frontend" as const,
|
|
105
|
+
parameters: { type: "object" as const, properties: {} },
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
expect(tool(definition)).toBe(definition);
|
|
109
|
+
});
|
|
110
|
+
});
|