@assistant-ui/core 0.2.22 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/thread-history.d.ts +8 -0
- package/dist/adapters/thread-history.d.ts.map +1 -1
- package/dist/internal.d.ts +3 -2
- package/dist/internal.js +3 -2
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js +36 -21
- package/dist/model-context/frame/host.js.map +1 -1
- package/dist/model-context/types.d.ts.map +1 -1
- package/dist/model-context/types.js +13 -4
- package/dist/model-context/types.js.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.js +3 -2
- package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
- package/dist/react/client/Tools.d.ts.map +1 -1
- package/dist/react/client/Tools.js +40 -55
- package/dist/react/client/Tools.js.map +1 -1
- package/dist/react/client/interactable-model-context.js +1 -0
- package/dist/react/client/interactable-model-context.js.map +1 -1
- package/dist/react/interactables-legacy/useAssistantInteractable.js +1 -1
- package/dist/react/interactables-legacy/useAssistantInteractable.js.map +1 -1
- package/dist/react/interactables-legacy/useInteractableState.js +4 -3
- package/dist/react/interactables-legacy/useInteractableState.js.map +1 -1
- package/dist/react/model-context/useAssistantContext.js +1 -1
- package/dist/react/model-context/useAssistantContext.js.map +1 -1
- package/dist/react/model-context/useAssistantDataUI.js +1 -1
- package/dist/react/model-context/useAssistantDataUI.js.map +1 -1
- package/dist/react/model-context/useAssistantInstructions.js +1 -1
- package/dist/react/model-context/useAssistantInstructions.js.map +1 -1
- package/dist/react/model-context/useAssistantTool.js +29 -25
- package/dist/react/model-context/useAssistantTool.js.map +1 -1
- package/dist/react/model-context/useAssistantToolUI.js +1 -1
- package/dist/react/model-context/useAssistantToolUI.js.map +1 -1
- package/dist/react/model-context/useAuiToolOverrides.js +1 -1
- package/dist/react/model-context/useAuiToolOverrides.js.map +1 -1
- package/dist/react/model-context/useInteractable.js +1 -1
- package/dist/react/model-context/useInteractable.js.map +1 -1
- package/dist/react/model-context/useInteractableState.js +3 -2
- package/dist/react/model-context/useInteractableState.js.map +1 -1
- package/dist/react/model-context/useInteractableVersions.js +1 -0
- package/dist/react/model-context/useInteractableVersions.js.map +1 -1
- package/dist/react/model-context/useToolArgsStatus.js +1 -0
- package/dist/react/model-context/useToolArgsStatus.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarCopy.js +4 -3
- package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarEdit.js +2 -1
- package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarFeedback.js +3 -2
- package/dist/react/primitive-hooks/useActionBarFeedback.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarReload.js +2 -1
- package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarSpeak.js +2 -1
- package/dist/react/primitive-hooks/useActionBarSpeak.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarStopSpeaking.js +2 -1
- package/dist/react/primitive-hooks/useActionBarStopSpeaking.js.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerNext.js +2 -1
- package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerPrevious.js +2 -1
- package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
- package/dist/react/primitive-hooks/useComposerAddAttachment.js +2 -1
- package/dist/react/primitive-hooks/useComposerAddAttachment.js.map +1 -1
- package/dist/react/primitive-hooks/useComposerCancel.js +2 -1
- package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
- package/dist/react/primitive-hooks/useComposerDictate.js +2 -1
- package/dist/react/primitive-hooks/useComposerDictate.js.map +1 -1
- package/dist/react/primitive-hooks/useComposerSend.js +2 -1
- package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
- package/dist/react/primitive-hooks/useEditComposerCancel.js +2 -1
- package/dist/react/primitive-hooks/useEditComposerCancel.js.map +1 -1
- package/dist/react/primitive-hooks/useEditComposerSend.js +2 -1
- package/dist/react/primitive-hooks/useEditComposerSend.js.map +1 -1
- package/dist/react/primitive-hooks/useMessageBranching.js +3 -2
- package/dist/react/primitive-hooks/useMessageBranching.js.map +1 -1
- package/dist/react/primitive-hooks/useMessageReload.js +2 -1
- package/dist/react/primitive-hooks/useMessageReload.js.map +1 -1
- package/dist/react/primitive-hooks/useSuggestionTrigger.js +8 -7
- package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListItemArchive.js +2 -1
- package/dist/react/primitive-hooks/useThreadListItemArchive.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListItemDelete.js +2 -1
- package/dist/react/primitive-hooks/useThreadListItemDelete.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListItemTrigger.js +2 -1
- package/dist/react/primitive-hooks/useThreadListItemTrigger.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListItemUnarchive.js +2 -1
- package/dist/react/primitive-hooks/useThreadListItemUnarchive.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListLoadMore.js +2 -1
- package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListNew.js +2 -1
- package/dist/react/primitive-hooks/useThreadListNew.js.map +1 -1
- package/dist/react/primitive-hooks/useVoice.js +5 -13
- package/dist/react/primitive-hooks/useVoice.js.map +1 -1
- package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js +1 -1
- package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
- package/dist/react/primitives/composer/ComposerAttachments.js +1 -1
- package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
- package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
- package/dist/react/primitives/composer/ComposerQueue.js +1 -1
- package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
- package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageAttachments.js +1 -1
- package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
- package/dist/react/primitives/message/MessageParts.js +84 -122
- package/dist/react/primitives/message/MessageParts.js.map +1 -1
- package/dist/react/primitives/thread/ThreadMessages.js +1 -1
- package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
- package/dist/react/primitives/thread/ThreadSuggestions.js +1 -1
- package/dist/react/primitives/thread/ThreadSuggestions.js.map +1 -1
- package/dist/react/primitives/threadList/ThreadListItems.js +1 -1
- package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
- package/dist/react/providers/AttachmentByIndexProvider.js +2 -2
- package/dist/react/providers/AttachmentByIndexProvider.js.map +1 -1
- package/dist/react/providers/ChainOfThoughtByIndicesProvider.js +1 -1
- package/dist/react/providers/ChainOfThoughtByIndicesProvider.js.map +1 -1
- package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +1 -1
- package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js +30 -18
- package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js.map +1 -1
- package/dist/react/providers/MessageByIdProvider.js +2 -2
- package/dist/react/providers/MessageByIdProvider.js.map +1 -1
- package/dist/react/providers/MessageByIndexProvider.js +2 -2
- package/dist/react/providers/MessageByIndexProvider.js.map +1 -1
- package/dist/react/providers/PartByIndexProvider.d.ts.map +1 -1
- package/dist/react/providers/PartByIndexProvider.js +30 -18
- package/dist/react/providers/PartByIndexProvider.js.map +1 -1
- package/dist/react/providers/QueueItemByIndexProvider.js +1 -1
- package/dist/react/providers/QueueItemByIndexProvider.js.map +1 -1
- package/dist/react/providers/ReadonlyThreadProvider.js +1 -1
- package/dist/react/providers/ReadonlyThreadProvider.js.map +1 -1
- package/dist/react/providers/SuggestionByIndexProvider.js +1 -1
- package/dist/react/providers/SuggestionByIndexProvider.js.map +1 -1
- package/dist/react/providers/TextMessagePartProvider.js +1 -0
- package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
- package/dist/react/providers/ThreadListItemByIndexProvider.js +1 -1
- package/dist/react/providers/ThreadListItemByIndexProvider.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +3 -3
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +6 -4
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +31 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +42 -20
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.d.ts +12 -1
- package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.js +2 -1
- package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +75 -73
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
- package/dist/react/runtimes/createRuntimeExtras.js +1 -1
- package/dist/react/runtimes/createRuntimeExtras.js.map +1 -1
- package/dist/react/runtimes/external-message-converter.js +1 -1
- package/dist/react/runtimes/external-message-converter.js.map +1 -1
- package/dist/react/runtimes/useExternalStoreSharedOptions.js +1 -0
- package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
- package/dist/react/runtimes/useLocalRuntime.d.ts +0 -1
- package/dist/react/runtimes/useLocalRuntime.d.ts.map +1 -1
- package/dist/react/types/scopes/tools.d.ts +0 -6
- package/dist/react/types/scopes/tools.d.ts.map +1 -1
- package/dist/react/utils/groupParts.d.ts +1 -3
- package/dist/react/utils/groupParts.d.ts.map +1 -1
- package/dist/react/utils/groupParts.js +1 -3
- package/dist/react/utils/groupParts.js.map +1 -1
- package/dist/runtime/api/assistant-runtime.d.ts +1 -1
- package/dist/runtime/api/assistant-runtime.d.ts.map +1 -1
- package/dist/runtime/api/assistant-runtime.js +1 -1
- package/dist/runtime/api/assistant-runtime.js.map +1 -1
- package/dist/runtime/api/attachment-runtime.d.ts +1 -1
- package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
- package/dist/runtime/api/attachment-runtime.js +1 -1
- package/dist/runtime/api/attachment-runtime.js.map +1 -1
- package/dist/runtime/api/composer-runtime.d.ts +2 -2
- package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
- package/dist/runtime/api/composer-runtime.js +2 -2
- package/dist/runtime/api/composer-runtime.js.map +1 -1
- package/dist/runtime/api/message-part-runtime.d.ts +4 -4
- package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
- package/dist/runtime/api/message-part-runtime.js +3 -3
- package/dist/runtime/api/message-part-runtime.js.map +1 -1
- package/dist/runtime/api/message-runtime.d.ts +1 -1
- package/dist/runtime/api/message-runtime.d.ts.map +1 -1
- package/dist/runtime/api/message-runtime.js +2 -2
- package/dist/runtime/api/message-runtime.js.map +1 -1
- package/dist/runtime/api/thread-list-item-runtime.d.ts +1 -1
- package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-item-runtime.js +2 -2
- package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
- package/dist/runtime/api/thread-list-runtime.d.ts +1 -1
- package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-runtime.js +1 -1
- package/dist/runtime/api/thread-list-runtime.js.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts +1 -1
- 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/base-thread-runtime-core.js.map +1 -1
- package/dist/runtime/base/default-edit-composer-runtime-core.d.ts +2 -2
- package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/default-edit-composer-runtime-core.js +2 -2
- package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.js +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
- package/dist/runtime/utils/message-repository.d.ts.map +1 -1
- package/dist/runtime/utils/message-repository.js +4 -2
- package/dist/runtime/utils/message-repository.js.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +1 -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-list-runtime-core.js +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
- 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 +12 -0
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/internal.d.ts +2 -1
- package/dist/runtimes/internal.js +2 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -0
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +44 -13
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +32 -27
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -0
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
- package/dist/store/clients/no-op-composer-client.js +1 -0
- package/dist/store/clients/no-op-composer-client.js.map +1 -1
- package/dist/store/clients/runtime-adapter.js +3 -3
- package/dist/store/clients/runtime-adapter.js.map +1 -1
- package/dist/store/runtime-clients/thread-list-runtime-client.js +1 -0
- package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
- package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-runtime-client.js +17 -15
- package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
- package/dist/store/scopes/thread.d.ts +1 -0
- package/dist/store/scopes/thread.d.ts.map +1 -1
- package/dist/subscribable/subscribable.d.ts +3 -3
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/subscribable/subscribable.js +3 -3
- package/dist/subscribable/subscribable.js.map +1 -1
- package/package.json +8 -8
- package/src/adapters/thread-history.ts +8 -0
- package/src/internal.ts +1 -1
- package/src/model-context/frame/host.test.ts +47 -0
- package/src/model-context/frame/host.ts +46 -19
- package/src/model-context/types.ts +16 -6
- package/src/react/adapters/LocalStorageThreadListAdapter.tsx +17 -7
- package/src/react/client/Tools.ts +0 -7
- package/src/react/interactables-legacy/useAssistantInteractable.ts +1 -1
- package/src/react/interactables-legacy/useInteractableState.ts +3 -3
- package/src/react/model-context/useAssistantContext.ts +1 -1
- package/src/react/model-context/useAssistantDataUI.ts +1 -1
- package/src/react/model-context/useAssistantInstructions.ts +1 -1
- package/src/react/model-context/useAssistantTool.ts +2 -2
- package/src/react/model-context/useAssistantToolUI.ts +1 -1
- package/src/react/model-context/useAuiToolOverrides.ts +1 -1
- package/src/react/model-context/useInteractable.ts +1 -1
- package/src/react/model-context/useInteractableState.ts +2 -2
- package/src/react/primitive-hooks/useActionBarCopy.test.ts +2 -2
- package/src/react/primitive-hooks/useActionBarCopy.ts +3 -3
- package/src/react/primitive-hooks/useActionBarEdit.ts +1 -1
- package/src/react/primitive-hooks/useActionBarFeedback.ts +2 -2
- package/src/react/primitive-hooks/useActionBarReload.ts +1 -1
- package/src/react/primitive-hooks/useActionBarSpeak.ts +1 -1
- package/src/react/primitive-hooks/useActionBarStopSpeaking.ts +1 -1
- package/src/react/primitive-hooks/useBranchPickerNext.ts +1 -1
- package/src/react/primitive-hooks/useBranchPickerPrevious.ts +1 -1
- package/src/react/primitive-hooks/useComposerAddAttachment.ts +1 -1
- package/src/react/primitive-hooks/useComposerCancel.ts +1 -1
- package/src/react/primitive-hooks/useComposerDictate.ts +1 -1
- package/src/react/primitive-hooks/useComposerSend.ts +1 -1
- package/src/react/primitive-hooks/useEditComposerCancel.ts +1 -1
- package/src/react/primitive-hooks/useEditComposerSend.ts +1 -1
- package/src/react/primitive-hooks/useMessageBranching.ts +2 -2
- package/src/react/primitive-hooks/useMessageReload.ts +1 -1
- package/src/react/primitive-hooks/useSuggestionTrigger.ts +9 -9
- package/src/react/primitive-hooks/useThreadListItemArchive.ts +1 -1
- package/src/react/primitive-hooks/useThreadListItemDelete.ts +1 -1
- package/src/react/primitive-hooks/useThreadListItemTrigger.ts +1 -1
- package/src/react/primitive-hooks/useThreadListItemUnarchive.ts +1 -1
- package/src/react/primitive-hooks/useThreadListLoadMore.ts +1 -1
- package/src/react/primitive-hooks/useThreadListNew.ts +1 -1
- package/src/react/primitive-hooks/useVoice.ts +5 -5
- package/src/react/primitives/chainOfThought/ChainOfThoughtParts.tsx +1 -1
- package/src/react/primitives/composer/ComposerAttachments.tsx +1 -1
- package/src/react/primitives/composer/ComposerQueue.tsx +1 -3
- package/src/react/primitives/message/MessageAttachments.tsx +1 -3
- package/src/react/primitives/message/MessageParts.tsx +9 -9
- package/src/react/primitives/thread/ThreadMessages.tsx +1 -1
- package/src/react/primitives/thread/ThreadSuggestions.tsx +1 -1
- package/src/react/primitives/threadList/ThreadListItems.tsx +1 -1
- package/src/react/providers/AttachmentByIndexProvider.tsx +2 -2
- package/src/react/providers/ChainOfThoughtByIndicesProvider.tsx +1 -1
- package/src/react/providers/ChainOfThoughtPartByIndexProvider.tsx +2 -19
- package/src/react/providers/MessageByIdProvider.tsx +2 -2
- package/src/react/providers/MessageByIndexProvider.tsx +2 -2
- package/src/react/providers/PartByIndexProvider.tsx +2 -16
- package/src/react/providers/QueueItemByIndexProvider.tsx +1 -1
- package/src/react/providers/ReadonlyThreadProvider.tsx +1 -1
- package/src/react/providers/SuggestionByIndexProvider.tsx +1 -1
- package/src/react/providers/ThreadListItemByIndexProvider.tsx +1 -1
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +3 -3
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +20 -6
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +34 -0
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +32 -7
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +47 -16
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +5 -1
- package/src/react/runtimes/cloud/auiV0.ts +14 -0
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +90 -88
- package/src/react/runtimes/createRuntimeExtras.test.ts +1 -1
- package/src/react/runtimes/createRuntimeExtras.ts +1 -1
- package/src/react/runtimes/external-message-converter.test.ts +346 -0
- package/src/react/runtimes/external-message-converter.ts +1 -1
- package/src/react/runtimes/useLocalRuntime.test.tsx +43 -0
- package/src/react/types/scopes/tools.ts +0 -6
- package/src/react/utils/groupParts.ts +1 -7
- package/src/runtime/api/assistant-runtime.ts +4 -1
- package/src/runtime/api/attachment-runtime.ts +8 -2
- package/src/runtime/api/composer-runtime.ts +9 -5
- package/src/runtime/api/message-part-runtime.ts +10 -3
- package/src/runtime/api/message-runtime.ts +7 -2
- package/src/runtime/api/thread-list-item-runtime.ts +7 -2
- package/src/runtime/api/thread-list-runtime.ts +10 -2
- package/src/runtime/base/base-thread-runtime-core.ts +5 -1
- package/src/runtime/base/default-edit-composer-runtime-core.ts +14 -2
- package/src/runtime/base/default-thread-composer-runtime-core.ts +11 -1
- package/src/runtime/utils/message-repository.ts +19 -13
- package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +4 -1
- package/src/runtimes/external-store/external-store-thread-runtime-core.ts +15 -0
- package/src/runtimes/internal.ts +3 -0
- package/src/runtimes/local/local-thread-runtime-core.test.ts +596 -0
- package/src/runtimes/local/local-thread-runtime-core.ts +85 -21
- package/src/runtimes/local/should-continue.test.ts +122 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +9 -10
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +38 -32
- package/src/store/clients/model-context-client.test.ts +21 -1
- package/src/store/clients/runtime-adapter.ts +3 -3
- package/src/store/runtime-clients/thread-runtime-client.ts +2 -1
- package/src/store/scopes/thread.ts +1 -0
- package/src/subscribable/subscribable.ts +16 -8
- package/src/tests/MessageRepository.test.ts +12 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-position.test.ts +121 -0
- package/src/tests/auiV0Encode.test.ts +74 -0
- package/src/tests/base-composer-runtime-core.test.ts +422 -0
- package/src/tests/external-store-thread-list-runtime-core.test.ts +6 -6
- package/src/tests/external-store-thread-runtime-core-adapter.test.ts +575 -0
- package/src/tests/external-store-thread-runtime-core.test.ts +55 -1
- package/src/tests/groupParts.test.ts +3 -48
- package/src/tests/OptimisticState-delete-crash.test.ts +0 -208
|
@@ -14,7 +14,7 @@ import { resource, useResources, withKey } from "@assistant-ui/tap";
|
|
|
14
14
|
* message rendering.
|
|
15
15
|
*/
|
|
16
16
|
const useTools = (t0) => {
|
|
17
|
-
const $ = c(
|
|
17
|
+
const $ = c(12);
|
|
18
18
|
const { toolkit, mcpApp } = t0;
|
|
19
19
|
let t1;
|
|
20
20
|
if ($[0] !== mcpApp) {
|
|
@@ -25,28 +25,20 @@ const useTools = (t0) => {
|
|
|
25
25
|
const mcpAppOutput = useResources(t1)[0];
|
|
26
26
|
const [toolUIs, setToolUIs] = useState(_temp);
|
|
27
27
|
let t2;
|
|
28
|
-
if ($[2] !== toolUIs) {
|
|
29
|
-
t2 =
|
|
30
|
-
$[2] = toolUIs;
|
|
31
|
-
$[3] = t2;
|
|
32
|
-
} else t2 = $[3];
|
|
33
|
-
let t3;
|
|
34
|
-
if ($[4] !== mcpAppOutput || $[5] !== t2 || $[6] !== toolUIs) {
|
|
35
|
-
t3 = {
|
|
28
|
+
if ($[2] !== mcpAppOutput || $[3] !== toolUIs) {
|
|
29
|
+
t2 = {
|
|
36
30
|
toolUIs,
|
|
37
|
-
mcpApp: mcpAppOutput
|
|
38
|
-
tools: t2
|
|
31
|
+
mcpApp: mcpAppOutput
|
|
39
32
|
};
|
|
40
|
-
$[
|
|
41
|
-
$[
|
|
42
|
-
$[
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const state = t3;
|
|
33
|
+
$[2] = mcpAppOutput;
|
|
34
|
+
$[3] = toolUIs;
|
|
35
|
+
$[4] = t2;
|
|
36
|
+
} else t2 = $[4];
|
|
37
|
+
const state = t2;
|
|
46
38
|
const clientRef = useAssistantClientRef();
|
|
47
|
-
let
|
|
48
|
-
if ($[
|
|
49
|
-
|
|
39
|
+
let t3;
|
|
40
|
+
if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
|
|
41
|
+
t3 = (toolName, render, options) => {
|
|
50
42
|
const registration = {
|
|
51
43
|
render,
|
|
52
44
|
standalone: options?.standalone ?? false
|
|
@@ -57,7 +49,7 @@ const useTools = (t0) => {
|
|
|
57
49
|
}));
|
|
58
50
|
return () => {
|
|
59
51
|
setToolUIs((prev_0) => {
|
|
60
|
-
const next = prev_0[toolName]?.filter((
|
|
52
|
+
const next = prev_0[toolName]?.filter((r) => r !== registration) ?? [];
|
|
61
53
|
if (next.length > 0) return {
|
|
62
54
|
...prev_0,
|
|
63
55
|
[toolName]: next
|
|
@@ -68,13 +60,13 @@ const useTools = (t0) => {
|
|
|
68
60
|
});
|
|
69
61
|
};
|
|
70
62
|
};
|
|
71
|
-
$[
|
|
72
|
-
} else
|
|
73
|
-
const setToolUI =
|
|
63
|
+
$[5] = t3;
|
|
64
|
+
} else t3 = $[5];
|
|
65
|
+
const setToolUI = t3;
|
|
66
|
+
let t4;
|
|
74
67
|
let t5;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
t5 = () => {
|
|
68
|
+
if ($[6] !== clientRef || $[7] !== toolkit) {
|
|
69
|
+
t4 = () => {
|
|
78
70
|
if (!toolkit) return;
|
|
79
71
|
const unsubscribes = [];
|
|
80
72
|
for (const [toolName_0, tool] of Object.entries(toolkit)) {
|
|
@@ -83,36 +75,36 @@ const useTools = (t0) => {
|
|
|
83
75
|
const render_0 = toolRender ?? (toolRenderText ? makeToolCallTextComponent(toolRenderText) : void 0);
|
|
84
76
|
if (render_0) unsubscribes.push(setToolUI(toolName_0, render_0, { standalone: isStandaloneToolDisplay(tool) }));
|
|
85
77
|
}
|
|
86
|
-
const toolsWithoutRender = Object.entries(toolkit).reduce(
|
|
78
|
+
const toolsWithoutRender = Object.entries(toolkit).reduce(_temp2, {});
|
|
87
79
|
unsubscribes.push(clientRef.current.modelContext().register({ getModelContext: () => ({ tools: toolsWithoutRender }) }));
|
|
88
80
|
return () => {
|
|
89
|
-
unsubscribes.forEach(
|
|
81
|
+
unsubscribes.forEach(_temp3);
|
|
90
82
|
};
|
|
91
83
|
};
|
|
92
|
-
|
|
84
|
+
t5 = [
|
|
93
85
|
toolkit,
|
|
94
86
|
setToolUI,
|
|
95
87
|
clientRef
|
|
96
88
|
];
|
|
97
|
-
$[
|
|
98
|
-
$[
|
|
99
|
-
$[
|
|
100
|
-
$[
|
|
89
|
+
$[6] = clientRef;
|
|
90
|
+
$[7] = toolkit;
|
|
91
|
+
$[8] = t4;
|
|
92
|
+
$[9] = t5;
|
|
101
93
|
} else {
|
|
102
|
-
|
|
103
|
-
|
|
94
|
+
t4 = $[8];
|
|
95
|
+
t5 = $[9];
|
|
104
96
|
}
|
|
105
|
-
useEffect(
|
|
106
|
-
let
|
|
107
|
-
if ($[
|
|
108
|
-
|
|
97
|
+
useEffect(t4, t5);
|
|
98
|
+
let t6;
|
|
99
|
+
if ($[10] !== state) {
|
|
100
|
+
t6 = {
|
|
109
101
|
getState: () => state,
|
|
110
102
|
setToolUI
|
|
111
103
|
};
|
|
112
|
-
$[
|
|
113
|
-
$[
|
|
114
|
-
} else
|
|
115
|
-
return
|
|
104
|
+
$[10] = state;
|
|
105
|
+
$[11] = t6;
|
|
106
|
+
} else t6 = $[11];
|
|
107
|
+
return t6;
|
|
116
108
|
};
|
|
117
109
|
const Tools = resource(useTools);
|
|
118
110
|
attachTransformScopes(useTools, (scopes, parent) => {
|
|
@@ -121,21 +113,14 @@ attachTransformScopes(useTools, (scopes, parent) => {
|
|
|
121
113
|
function _temp() {
|
|
122
114
|
return {};
|
|
123
115
|
}
|
|
124
|
-
function _temp2(
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
function _temp3(t0) {
|
|
128
|
-
const [name, regs] = t0;
|
|
129
|
-
return [name, regs.map(_temp2)];
|
|
130
|
-
}
|
|
131
|
-
function _temp4(acc, t0) {
|
|
132
|
-
const [name_0, tool_0] = t0;
|
|
116
|
+
function _temp2(acc, t0) {
|
|
117
|
+
const [name, tool_0] = t0;
|
|
133
118
|
if (tool_0.type === "mcp") return acc;
|
|
134
119
|
const { display: _display, render: _render, renderText: _renderText, ...rest_0 } = tool_0;
|
|
135
|
-
acc[
|
|
120
|
+
acc[name] = rest_0;
|
|
136
121
|
return acc;
|
|
137
122
|
}
|
|
138
|
-
function
|
|
123
|
+
function _temp3(fn) {
|
|
139
124
|
return fn();
|
|
140
125
|
}
|
|
141
126
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tools.js","names":["useState","useEffect","useCallback","useMemo","useResources","resource","withKey","ResourceElement","useAssistantClientRef","ClientOutput","attachTransformScopes","McpAppResourceOutput","ToolsState","Tool","isStandaloneToolDisplay","makeToolCallTextComponent","Toolkit","ToolCallMessagePartComponent","ModelContext","useTools","t0","$","_c","toolkit","mcpApp","t1","mcpAppOutputs","mcpAppOutput","toolUIs","setToolUIs","_temp","t2","
|
|
1
|
+
{"version":3,"file":"Tools.js","names":["useState","useEffect","useCallback","useMemo","useResources","resource","withKey","ResourceElement","useAssistantClientRef","ClientOutput","attachTransformScopes","McpAppResourceOutput","ToolsState","Tool","isStandaloneToolDisplay","makeToolCallTextComponent","Toolkit","ToolCallMessagePartComponent","ModelContext","useTools","t0","$","_c","toolkit","mcpApp","t1","mcpAppOutputs","mcpAppOutput","toolUIs","setToolUIs","_temp","t2","state","clientRef","t3","Symbol","for","toolName","render","options","registration","standalone","prev","prev_0","next","filter","r","length","rest","setToolUI","t4","t5","unsubscribes","toolName_0","tool","Object","entries","toolRender","undefined","toolRenderText","renderText","render_0","push","toolsWithoutRender","reduce","_temp2","Record","modelContextProvider","getModelContext","tools","current","modelContext","register","forEach","_temp3","t6","getState","Tools","scopes","parent","source","acc","name","tool_0","type","display","_display","_render","_renderText","rest_0","fn"],"sources":["../../../src/react/client/Tools.ts"],"sourcesContent":["import { useState, useEffect, useCallback, useMemo } from \"react\";\nimport {\n useResources,\n resource,\n withKey,\n type ResourceElement,\n} from \"@assistant-ui/tap\";\nimport {\n useAssistantClientRef,\n type ClientOutput,\n attachTransformScopes,\n} from \"@assistant-ui/store\";\nimport type { McpAppResourceOutput, ToolsState } from \"../types/scopes/tools\";\nimport type { Tool } from \"assistant-stream\";\nimport {\n isStandaloneToolDisplay,\n makeToolCallTextComponent,\n type Toolkit,\n} from \"../model-context/toolbox\";\nimport type { ToolCallMessagePartComponent } from \"../types/MessagePartComponentTypes\";\nimport { ModelContext } from \"../../store\";\n\nexport type { McpAppResourceOutput };\n\n/**\n * Registers tools with model context and installs tool-call renderers.\n *\n * Mount this resource near an assistant subtree when you want to expose a\n * group of tools declaratively. Tool definitions are registered with model\n * context, while each tool renderer is registered with the tools scope for\n * message rendering.\n */\nconst useTools = ({\n toolkit,\n mcpApp,\n}: {\n /** Tools to expose to the model and optional renderers to install. */\n toolkit?: Toolkit;\n /** Optional MCP app resource whose tools should be merged into context. */\n mcpApp?: ResourceElement<McpAppResourceOutput> | undefined;\n}): ClientOutput<\"tools\"> => {\n const mcpAppOutputs = useResources(mcpApp ? [withKey(\"mcpApp\", mcpApp)] : []);\n const mcpAppOutput = mcpAppOutputs[0];\n\n const [toolUIs, setToolUIs] = useState<ToolsState[\"toolUIs\"]>(() => ({}));\n\n const state = useMemo(\n (): ToolsState => ({\n toolUIs,\n mcpApp: mcpAppOutput,\n }),\n [toolUIs, mcpAppOutput],\n );\n\n const clientRef = useAssistantClientRef();\n\n const setToolUI = useCallback(\n (\n toolName: string,\n render: ToolCallMessagePartComponent,\n options?: { standalone?: boolean },\n ) => {\n // One registration object per call; identity is the removal key, so\n // the per-name list stays correctly ref-counted across re-registers.\n const registration = {\n render,\n standalone: options?.standalone ?? false,\n };\n\n setToolUIs((prev) => ({\n ...prev,\n [toolName]: [...(prev[toolName] ?? []), registration],\n }));\n\n return () => {\n setToolUIs((prev) => {\n const next = prev[toolName]?.filter((r) => r !== registration) ?? [];\n if (next.length > 0) return { ...prev, [toolName]: next };\n // Drop the key entirely so repeatedly mounted/unmounted tools\n // don't leave empty arrays accumulating across a long session.\n const rest = { ...prev };\n delete rest[toolName];\n return rest;\n });\n };\n },\n [],\n );\n\n useEffect(() => {\n if (!toolkit) return;\n const unsubscribes: (() => void)[] = [];\n\n // Register tool UIs (exclude symbols)\n for (const [toolName, tool] of Object.entries(toolkit)) {\n const toolRender = \"render\" in tool ? tool.render : undefined;\n const toolRenderText = \"renderText\" in tool ? tool.renderText : undefined;\n const render =\n toolRender ??\n (toolRenderText\n ? makeToolCallTextComponent(toolRenderText)\n : undefined);\n if (render) {\n unsubscribes.push(\n setToolUI(toolName, render, {\n standalone: isStandaloneToolDisplay(tool),\n }),\n );\n }\n }\n\n // Register tools with model context (exclude symbols). `render`,\n // `renderText`, and `display` are client-only presentation concerns and\n // never reach the model.\n const toolsWithoutRender = Object.entries(toolkit).reduce(\n (acc, [name, tool]) => {\n if (tool.type === \"mcp\") return acc;\n const {\n display: _display,\n render: _render,\n renderText: _renderText,\n ...rest\n } = tool as typeof tool & { renderText?: unknown };\n acc[name] = rest as Tool<any, any>;\n return acc;\n },\n {} as Record<string, Tool<any, any>>,\n );\n\n const modelContextProvider = {\n getModelContext: () => ({\n tools: toolsWithoutRender,\n }),\n };\n\n unsubscribes.push(\n clientRef.current!.modelContext().register(modelContextProvider),\n );\n\n return () => {\n unsubscribes.forEach((fn) => fn());\n };\n }, [toolkit, setToolUI, clientRef]);\n\n return {\n getState: () => state,\n setToolUI,\n };\n};\n\nexport const Tools = resource(useTools);\n\nattachTransformScopes(useTools, (scopes, parent) => {\n if (!scopes.modelContext && parent.modelContext.source === null) {\n scopes.modelContext = ModelContext();\n }\n});\n"],"mappings":";;;;;;;;;;;;;;;AAgCA,MAAMmB,YAAWC,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAC,MAAA,EAAAC,SAAAC,WAAAJ;CAQjB,IAAAK;CAAA,IAAAJ,EAAA,OAAAG,QAAA;EACoCC,KAAAD,SAAA,CAAUlB,QAAQ,UAAUkB,MAAM,CAAC,IAAnC,CAAA;EAAyCH,EAAA,KAAAG;EAAAH,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAC5E,MAAAM,eADsBvB,aAAaqB,EACdC,CAAa,CAAA;CAElC,MAAA,CAAAE,SAAAC,cAA8B7B,SAAgC8B,KAAU;CAAE,IAAAC;CAAA,IAAAV,EAAA,OAAAM,gBAAAN,EAAA,OAAAO,SAAA;EAGrDG,KAAA;GAAAH;GAAAJ,QAETG;EACV;EAACN,EAAA,KAAAM;EAAAN,EAAA,KAAAO;EAAAP,EAAA,KAAAU;CAAA,OAAAA,KAAAV,EAAA;CAJH,MAAAW,QACqBD;CAOrB,MAAAE,YAAkBzB,sBAAsB;CAAE,IAAA0B;CAAA,IAAAb,EAAA,OAAAc,OAAAC,IAAA,2BAAA,GAAA;EAGxCF,MAAAG,UAAAC,QAAAC,YAAA;GAOE,MAAAC,eAAqB;IAAAF;IAAAG,YAEPF,SAAOE,cAAP;GACd;GAEAZ,YAAWa,UAAW;IAAA,GACjBA;KACFL,WAAW,CAAA,GAAKK,KAAKL,aAAL,CAAA,GAAuBG,YAAY;GACtD,EAAE;GAAC,aAEI;IACLX,YAAWc,WAAA;KACT,MAAAC,OAAaF,OAAKL,SAAiB,EAAAQ,QAACC,MAAOA,MAAMN,YAAkB,KAAtD,CAAA;KACb,IAAII,KAAIG,SAAU,GAAC,OAAS;MAAA,GAAKL;OAAOL,WAAWO;KAAK;KAGxD,MAAAI,OAAa,EAAA,GAAKN,OAAK;KACvB,OAAOM,KAAKX;KAAS,OACdW;IAAI,CACZ;GAAC;EACH;EACF3B,EAAA,KAAAa;CAAA,OAAAA,KAAAb,EAAA;CA7BH,MAAA4B,YAAkBf;CA+BhB,IAAAgB;CAAA,IAAAC;CAAA,IAAA9B,EAAA,OAAAY,aAAAZ,EAAA,OAAAE,SAAA;EAEQ2B,WAAA;GACR,IAAI,CAAC3B,SAAO;GACZ,MAAA6B,eAAqC,CAAA;GAGrC,KAAK,MAAA,CAAAC,YAAAC,SAA0BC,OAAMC,QAASjC,OAAO,GAAC;IACpD,MAAAkC,aAAmB,YAAYH,OAAOA,KAAIhB,SAAvBoB,KAAAA;IACnB,MAAAC,iBAAuB,gBAAgBL,OAAOA,KAAIM,aAA3BF,KAAAA;IACvB,MAAAG,WACEJ,eACCE,iBACG5C,0BAA0B4C,cAClB,IAFXD,KAAAA;IAGH,IAAIpB,UACFc,aAAYU,KACVb,UAAUZ,YAAUC,UAAQ,EAAAG,YACd3B,wBAAwBwC,IAAI,EAC1C,CAAC,CACH;GACD;GAMH,MAAAS,qBAA2BR,OAAMC,QAASjC,OAAO,CAAC,CAAAyC,OAChDC,QAWA,CAAC,CACH;GAQAb,aAAYU,KACV7B,UAASqC,QAAQC,aAAe,CAAC,CAAAC,SAAUL,EAPhBC,wBACH,EAAAC,OACfN,mBACT,GAI2CI,CAAoB,CACjE;GAAC,aAEM;IACLf,aAAYqB,QAASC,MAAY;GAAC;EACnC;EACAvB,KAAA;GAAC5B;GAAS0B;GAAWhB;EAAS;EAACZ,EAAA,KAAAY;EAAAZ,EAAA,KAAAE;EAAAF,EAAA,KAAA6B;EAAA7B,EAAA,KAAA8B;CAAA,OAAA;EAAAD,KAAA7B,EAAA;EAAA8B,KAAA9B,EAAA;CAAA;CArDlCpB,UAAUiD,IAqDPC,EAA+B;CAAC,IAAAwB;CAAA,IAAAtD,EAAA,QAAAW,OAAA;EAE5B2C,KAAA;GAAAC,gBACW5C;GAAKiB;EAEvB;EAAC5B,EAAA,MAAAW;EAAAX,EAAA,MAAAsD;CAAA,OAAAA,KAAAtD,EAAA;CAAA,OAHMsD;AAGN;AAGH,MAAaE,QAAQxE,SAASc,QAAQ;AAEtCT,sBAAsBS,WAAW2D,QAAQC,WAAW;CAClD,IAAI,CAACD,OAAOP,gBAAgBQ,OAAOR,aAAaS,WAAW,MACzDF,OAAOP,eAAerD,aAAa;AAEvC,CAAC;AA5HgB,SAAAY,QAAA;CAAA,OAYsD,CAAC;AAAC;AAZxD,SAAAmC,OAAAgB,KAAA7D,IAAA;CAmFL,MAAA,CAAA8D,MAAAC,UAAA/D;CACJ,IAAIkC,OAAI8B,SAAU,OAAK,OAASH;CAChC,MAAA,EAAAI,SAAAC,UAAAhD,QAAAiD,SAAA3B,YAAA4B,aAAA,GAAAC,WAKInC;CACJ2B,IAAIC,QAAQlC;CAAH,OACFiC;AAAG;AA5FD,SAAAP,OAAAgB,IAAA;CAAA,OA4GkBA,GAAG;AAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isRecord } from "../../utils/json/is-json.js";
|
|
2
2
|
import { interactableToolName, shallowMergeInteractableState } from "../../model-context/interactable-composer-metadata.js";
|
|
3
3
|
import { generateId } from "../../utils/id.js";
|
|
4
|
+
import "assistant-stream";
|
|
4
5
|
//#region src/react/client/interactable-model-context.ts
|
|
5
6
|
const ID_PROPERTY = {
|
|
6
7
|
type: "string",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactable-model-context.js","names":["Tool","toJSONSchema","Unstable_InteractableDefinition","interactableToolName","shallowMergeInteractableState","Unstable_InteractableSnapshotEntry","generateId","isRecord","PartialJSONSchema","ReturnType","ID_PROPERTY","type","const","description","hasIdProperty","schema","Record","properties","id","undefined","withRequiredItemId","required","withoutItemId","_omitted","Array","isArray","filter","key","toArrayUpdateSchema","field","itemSchema","items","idKeyed","add","remove","clear","update","additionalProperties","idKeyedArrayFieldNames","Set","names","value","Object","entries","withArrayUpdateSchemas","fromEntries","map","withRequiredId","partial","process","env","NODE_ENV","console","warn","_reserved","buildInteractableModelContext","definitions","partialSchemaCache","Map","setDefState","updater","prev","streamBaselines","targetId","state","tools","unstable_composerMetadata","values","length","byName","def","list","get","name","push","set","instances","toolName","first","partialSchema","idKeyedFields","resolveTarget","parameters","streamCall","reader","toolCallId","partialArgs","args","streamValues","keys","idIndex","indexOf","target","baseline","arrayBaseline","execute","validIds","d","success","error","JSON","stringify","join","delete","addedItemIds","idFactory","itemId","result","interactables"],"sources":["../../../src/react/client/interactable-model-context.ts"],"sourcesContent":["import type { Tool } from \"assistant-stream\";\nimport { toJSONSchema } from \"assistant-stream\";\nimport type { Unstable_InteractableDefinition } from \"../types/scopes/interactables\";\nimport {\n interactableToolName,\n shallowMergeInteractableState,\n type Unstable_InteractableSnapshotEntry,\n} from \"../../model-context/interactable-composer-metadata\";\nimport { generateId } from \"../../utils/id\";\nimport { isRecord } from \"../../utils/json/is-json\";\n\nexport type PartialJSONSchema = ReturnType<typeof toJSONSchema>;\n\nconst ID_PROPERTY = {\n type: \"string\" as const,\n description:\n \"The id of the instance to update, as shown in its state snapshot in the conversation.\",\n};\n\nconst hasIdProperty = (schema: Record<string, unknown>) => {\n const properties = schema.properties;\n return isRecord(properties) && properties.id !== undefined;\n};\n\nconst withRequiredItemId = (schema: Record<string, unknown>) => ({\n ...schema,\n required: [\"id\"],\n});\n\n// The framework assigns ids to new items, so the model never sees the `id`\n// field when adding (it can't address an item that doesn't exist yet).\nconst withoutItemId = (schema: Record<string, unknown>) => {\n const { id: _omitted, ...properties } = isRecord(schema.properties)\n ? schema.properties\n : {};\n const required = Array.isArray(schema.required)\n ? schema.required.filter((key) => key !== \"id\")\n : schema.required;\n return { ...schema, properties, required };\n};\n\nconst toArrayUpdateSchema = (schema: unknown, field: string) => {\n if (!isRecord(schema) || schema.type !== \"array\") return schema;\n const itemSchema = schema.items;\n if (Array.isArray(itemSchema) || !isRecord(itemSchema)) return schema;\n\n const idKeyed = hasIdProperty(itemSchema);\n const properties: Record<string, unknown> = {\n add: {\n type: \"array\",\n items: idKeyed ? withoutItemId(itemSchema) : itemSchema,\n },\n remove: {\n type: \"array\",\n items: idKeyed ? ID_PROPERTY : itemSchema,\n },\n clear: { type: \"boolean\" },\n };\n\n if (idKeyed) {\n properties.update = {\n type: \"array\",\n items: withRequiredItemId(itemSchema),\n };\n }\n\n return {\n type: \"object\" as const,\n description:\n `Operations for array field \"${field}\". To change one item use update ` +\n `with its id; add new items (their ids are assigned for you), remove items ` +\n `by id, or clear to empty. Change only the items you mean to — never resend ` +\n `the whole array to edit one item.`,\n properties,\n additionalProperties: false,\n };\n};\n\n// Top-level array fields whose items carry an `id` — the fields the framework\n// mints ids for on add.\nconst idKeyedArrayFieldNames = (\n properties: Record<string, unknown>,\n): Set<string> => {\n const names = new Set<string>();\n for (const [key, value] of Object.entries(properties)) {\n if (\n isRecord(value) &&\n value.type === \"array\" &&\n isRecord(value.items) &&\n hasIdProperty(value.items)\n ) {\n names.add(key);\n }\n }\n return names;\n};\n\nconst withArrayUpdateSchemas = (properties: Record<string, unknown>) =>\n Object.fromEntries(\n Object.entries(properties).map(([key, value]) => [\n key,\n toArrayUpdateSchema(value, key),\n ]),\n );\n\n/**\n * Wraps an interactable's partial state schema with the required `id`\n * parameter. Falls back to a permissive schema when the partial conversion\n * failed at registration time.\n */\nfunction withRequiredId(partial: PartialJSONSchema | undefined) {\n if (!partial || typeof partial !== \"object\" || partial.type !== \"object\") {\n return {\n type: \"object\" as const,\n properties: { id: ID_PROPERTY },\n required: [\"id\"],\n additionalProperties: true,\n };\n }\n if (process.env.NODE_ENV !== \"production\" && partial.properties?.id) {\n console.warn(\n `[Interactables] a top-level \"id\" field in an interactable's stateSchema is ` +\n `reserved for instance addressing by the update tool and cannot be updated ` +\n `by the model. Rename the field to make it model-writable.`,\n );\n }\n const { id: _reserved, ...properties } = partial.properties ?? {};\n return {\n ...partial,\n properties: { id: ID_PROPERTY, ...withArrayUpdateSchemas(properties) },\n required: [\"id\"],\n };\n}\n\nexport function buildInteractableModelContext(\n definitions: Record<string, Unstable_InteractableDefinition>,\n partialSchemaCache: Map<string, PartialJSONSchema>,\n setDefState: (id: string, updater: (prev: unknown) => unknown) => void,\n streamBaselines = new Map<string, { targetId: string; state: unknown }>(),\n):\n | {\n tools: Record<string, Tool<any, any>>;\n unstable_composerMetadata?: Record<string, unknown>;\n }\n | undefined {\n const entries = Object.values(definitions);\n if (entries.length === 0) return undefined;\n\n const byName = new Map<string, Unstable_InteractableDefinition[]>();\n for (const def of entries) {\n const list = byName.get(def.name) ?? [];\n list.push(def);\n byName.set(def.name, list);\n }\n\n const tools: Record<string, Tool<any, any>> = {};\n\n for (const [name, instances] of byName) {\n const toolName = interactableToolName(name);\n if (tools[toolName]) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\n `[Interactables] interactable names \"${name}\" and another registered name ` +\n `both sanitize to the tool name \"${toolName}\". Rename one of them.`,\n );\n }\n continue;\n }\n\n const first = instances[0]!;\n const partialSchema = partialSchemaCache.get(first.id);\n const idKeyedFields =\n partialSchema && isRecord(partialSchema.properties)\n ? idKeyedArrayFieldNames(partialSchema.properties)\n : new Set<string>();\n\n // `id` resolves to a definition of this name; an id-less call is accepted\n // only while exactly one instance exists.\n const resolveTarget = (\n id: unknown,\n ): Unstable_InteractableDefinition | undefined => {\n if (typeof id === \"string\") {\n const def = definitions[id];\n return def?.name === name ? def : undefined;\n }\n return instances.length === 1 ? first : undefined;\n };\n\n tools[toolName] = {\n type: \"frontend\",\n description:\n `Update the state of interactable component \"${name}\". ${first.description} ` +\n `Pass the id of the instance to update — instance ids and current state ` +\n `appear in the conversation as state snapshots. Only include the fields ` +\n `you want to change; omitted fields keep their current values.`,\n parameters: withRequiredId(partialSchema),\n streamCall: async (reader, { toolCallId }) => {\n try {\n for await (const partialArgs of reader.args.streamValues()) {\n if (!partialArgs || typeof partialArgs !== \"object\") continue;\n const args = partialArgs as Record<string, unknown>;\n const keys = Object.keys(args);\n const idIndex = keys.indexOf(\"id\");\n if (idIndex === keys.length - 1) continue;\n\n const { id, ...partial } = args;\n if (Object.keys(partial).length === 0) continue;\n const target = resolveTarget(id);\n if (!target) continue;\n\n const baseline = streamBaselines.get(toolCallId);\n const arrayBaseline =\n baseline?.targetId === target.id ? baseline.state : target.state;\n if (!baseline || baseline.targetId !== target.id) {\n streamBaselines.set(toolCallId, {\n targetId: target.id,\n state: target.state,\n });\n }\n\n setDefState(target.id, (prev) =>\n shallowMergeInteractableState(prev, partial, { arrayBaseline }),\n );\n }\n } catch {\n // Non-fatal: execute handles the final state\n }\n },\n execute: async (args: unknown, { toolCallId }) => {\n const { id, ...partial } = (args ?? {}) as Record<string, unknown>;\n const target = resolveTarget(id);\n if (!target) {\n const validIds = instances.map((d) => d.id);\n return {\n success: false,\n error: `Unknown id ${JSON.stringify(id)} for interactable \"${name}\". Valid ids: ${validIds.join(\", \")}`,\n };\n }\n const baseline = streamBaselines.get(toolCallId);\n streamBaselines.delete(toolCallId);\n const addedItemIds: Record<string, string[]> = {};\n setDefState(target.id, (prev) =>\n shallowMergeInteractableState(prev, partial, {\n arrayBaseline:\n baseline?.targetId === target.id ? baseline.state : undefined,\n idFactory: (field) => {\n const itemId = generateId();\n (addedItemIds[field] ??= []).push(itemId);\n return itemId;\n },\n idKeyedFields,\n }),\n );\n // The resolved id lets an id-less call's UI (and the model) address\n // the instance that was actually updated.\n const result: {\n success: true;\n id: string;\n addedItemIds?: Record<string, string[]>;\n } = { success: true, id: target.id };\n if (Object.keys(addedItemIds).length > 0) {\n result.addedItemIds = addedItemIds;\n }\n return result;\n },\n };\n }\n\n const interactables: Unstable_InteractableSnapshotEntry[] = entries.map(\n (def) => ({\n id: def.id,\n name: def.name,\n state: def.state,\n }),\n );\n return { tools, unstable_composerMetadata: { interactables } };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"interactable-model-context.js","names":["Tool","toJSONSchema","Unstable_InteractableDefinition","interactableToolName","shallowMergeInteractableState","Unstable_InteractableSnapshotEntry","generateId","isRecord","PartialJSONSchema","ReturnType","ID_PROPERTY","type","const","description","hasIdProperty","schema","Record","properties","id","undefined","withRequiredItemId","required","withoutItemId","_omitted","Array","isArray","filter","key","toArrayUpdateSchema","field","itemSchema","items","idKeyed","add","remove","clear","update","additionalProperties","idKeyedArrayFieldNames","Set","names","value","Object","entries","withArrayUpdateSchemas","fromEntries","map","withRequiredId","partial","process","env","NODE_ENV","console","warn","_reserved","buildInteractableModelContext","definitions","partialSchemaCache","Map","setDefState","updater","prev","streamBaselines","targetId","state","tools","unstable_composerMetadata","values","length","byName","def","list","get","name","push","set","instances","toolName","first","partialSchema","idKeyedFields","resolveTarget","parameters","streamCall","reader","toolCallId","partialArgs","args","streamValues","keys","idIndex","indexOf","target","baseline","arrayBaseline","execute","validIds","d","success","error","JSON","stringify","join","delete","addedItemIds","idFactory","itemId","result","interactables"],"sources":["../../../src/react/client/interactable-model-context.ts"],"sourcesContent":["import type { Tool } from \"assistant-stream\";\nimport { toJSONSchema } from \"assistant-stream\";\nimport type { Unstable_InteractableDefinition } from \"../types/scopes/interactables\";\nimport {\n interactableToolName,\n shallowMergeInteractableState,\n type Unstable_InteractableSnapshotEntry,\n} from \"../../model-context/interactable-composer-metadata\";\nimport { generateId } from \"../../utils/id\";\nimport { isRecord } from \"../../utils/json/is-json\";\n\nexport type PartialJSONSchema = ReturnType<typeof toJSONSchema>;\n\nconst ID_PROPERTY = {\n type: \"string\" as const,\n description:\n \"The id of the instance to update, as shown in its state snapshot in the conversation.\",\n};\n\nconst hasIdProperty = (schema: Record<string, unknown>) => {\n const properties = schema.properties;\n return isRecord(properties) && properties.id !== undefined;\n};\n\nconst withRequiredItemId = (schema: Record<string, unknown>) => ({\n ...schema,\n required: [\"id\"],\n});\n\n// The framework assigns ids to new items, so the model never sees the `id`\n// field when adding (it can't address an item that doesn't exist yet).\nconst withoutItemId = (schema: Record<string, unknown>) => {\n const { id: _omitted, ...properties } = isRecord(schema.properties)\n ? schema.properties\n : {};\n const required = Array.isArray(schema.required)\n ? schema.required.filter((key) => key !== \"id\")\n : schema.required;\n return { ...schema, properties, required };\n};\n\nconst toArrayUpdateSchema = (schema: unknown, field: string) => {\n if (!isRecord(schema) || schema.type !== \"array\") return schema;\n const itemSchema = schema.items;\n if (Array.isArray(itemSchema) || !isRecord(itemSchema)) return schema;\n\n const idKeyed = hasIdProperty(itemSchema);\n const properties: Record<string, unknown> = {\n add: {\n type: \"array\",\n items: idKeyed ? withoutItemId(itemSchema) : itemSchema,\n },\n remove: {\n type: \"array\",\n items: idKeyed ? ID_PROPERTY : itemSchema,\n },\n clear: { type: \"boolean\" },\n };\n\n if (idKeyed) {\n properties.update = {\n type: \"array\",\n items: withRequiredItemId(itemSchema),\n };\n }\n\n return {\n type: \"object\" as const,\n description:\n `Operations for array field \"${field}\". To change one item use update ` +\n `with its id; add new items (their ids are assigned for you), remove items ` +\n `by id, or clear to empty. Change only the items you mean to — never resend ` +\n `the whole array to edit one item.`,\n properties,\n additionalProperties: false,\n };\n};\n\n// Top-level array fields whose items carry an `id` — the fields the framework\n// mints ids for on add.\nconst idKeyedArrayFieldNames = (\n properties: Record<string, unknown>,\n): Set<string> => {\n const names = new Set<string>();\n for (const [key, value] of Object.entries(properties)) {\n if (\n isRecord(value) &&\n value.type === \"array\" &&\n isRecord(value.items) &&\n hasIdProperty(value.items)\n ) {\n names.add(key);\n }\n }\n return names;\n};\n\nconst withArrayUpdateSchemas = (properties: Record<string, unknown>) =>\n Object.fromEntries(\n Object.entries(properties).map(([key, value]) => [\n key,\n toArrayUpdateSchema(value, key),\n ]),\n );\n\n/**\n * Wraps an interactable's partial state schema with the required `id`\n * parameter. Falls back to a permissive schema when the partial conversion\n * failed at registration time.\n */\nfunction withRequiredId(partial: PartialJSONSchema | undefined) {\n if (!partial || typeof partial !== \"object\" || partial.type !== \"object\") {\n return {\n type: \"object\" as const,\n properties: { id: ID_PROPERTY },\n required: [\"id\"],\n additionalProperties: true,\n };\n }\n if (process.env.NODE_ENV !== \"production\" && partial.properties?.id) {\n console.warn(\n `[Interactables] a top-level \"id\" field in an interactable's stateSchema is ` +\n `reserved for instance addressing by the update tool and cannot be updated ` +\n `by the model. Rename the field to make it model-writable.`,\n );\n }\n const { id: _reserved, ...properties } = partial.properties ?? {};\n return {\n ...partial,\n properties: { id: ID_PROPERTY, ...withArrayUpdateSchemas(properties) },\n required: [\"id\"],\n };\n}\n\nexport function buildInteractableModelContext(\n definitions: Record<string, Unstable_InteractableDefinition>,\n partialSchemaCache: Map<string, PartialJSONSchema>,\n setDefState: (id: string, updater: (prev: unknown) => unknown) => void,\n streamBaselines = new Map<string, { targetId: string; state: unknown }>(),\n):\n | {\n tools: Record<string, Tool<any, any>>;\n unstable_composerMetadata?: Record<string, unknown>;\n }\n | undefined {\n const entries = Object.values(definitions);\n if (entries.length === 0) return undefined;\n\n const byName = new Map<string, Unstable_InteractableDefinition[]>();\n for (const def of entries) {\n const list = byName.get(def.name) ?? [];\n list.push(def);\n byName.set(def.name, list);\n }\n\n const tools: Record<string, Tool<any, any>> = {};\n\n for (const [name, instances] of byName) {\n const toolName = interactableToolName(name);\n if (tools[toolName]) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\n `[Interactables] interactable names \"${name}\" and another registered name ` +\n `both sanitize to the tool name \"${toolName}\". Rename one of them.`,\n );\n }\n continue;\n }\n\n const first = instances[0]!;\n const partialSchema = partialSchemaCache.get(first.id);\n const idKeyedFields =\n partialSchema && isRecord(partialSchema.properties)\n ? idKeyedArrayFieldNames(partialSchema.properties)\n : new Set<string>();\n\n // `id` resolves to a definition of this name; an id-less call is accepted\n // only while exactly one instance exists.\n const resolveTarget = (\n id: unknown,\n ): Unstable_InteractableDefinition | undefined => {\n if (typeof id === \"string\") {\n const def = definitions[id];\n return def?.name === name ? def : undefined;\n }\n return instances.length === 1 ? first : undefined;\n };\n\n tools[toolName] = {\n type: \"frontend\",\n description:\n `Update the state of interactable component \"${name}\". ${first.description} ` +\n `Pass the id of the instance to update — instance ids and current state ` +\n `appear in the conversation as state snapshots. Only include the fields ` +\n `you want to change; omitted fields keep their current values.`,\n parameters: withRequiredId(partialSchema),\n streamCall: async (reader, { toolCallId }) => {\n try {\n for await (const partialArgs of reader.args.streamValues()) {\n if (!partialArgs || typeof partialArgs !== \"object\") continue;\n const args = partialArgs as Record<string, unknown>;\n const keys = Object.keys(args);\n const idIndex = keys.indexOf(\"id\");\n if (idIndex === keys.length - 1) continue;\n\n const { id, ...partial } = args;\n if (Object.keys(partial).length === 0) continue;\n const target = resolveTarget(id);\n if (!target) continue;\n\n const baseline = streamBaselines.get(toolCallId);\n const arrayBaseline =\n baseline?.targetId === target.id ? baseline.state : target.state;\n if (!baseline || baseline.targetId !== target.id) {\n streamBaselines.set(toolCallId, {\n targetId: target.id,\n state: target.state,\n });\n }\n\n setDefState(target.id, (prev) =>\n shallowMergeInteractableState(prev, partial, { arrayBaseline }),\n );\n }\n } catch {\n // Non-fatal: execute handles the final state\n }\n },\n execute: async (args: unknown, { toolCallId }) => {\n const { id, ...partial } = (args ?? {}) as Record<string, unknown>;\n const target = resolveTarget(id);\n if (!target) {\n const validIds = instances.map((d) => d.id);\n return {\n success: false,\n error: `Unknown id ${JSON.stringify(id)} for interactable \"${name}\". Valid ids: ${validIds.join(\", \")}`,\n };\n }\n const baseline = streamBaselines.get(toolCallId);\n streamBaselines.delete(toolCallId);\n const addedItemIds: Record<string, string[]> = {};\n setDefState(target.id, (prev) =>\n shallowMergeInteractableState(prev, partial, {\n arrayBaseline:\n baseline?.targetId === target.id ? baseline.state : undefined,\n idFactory: (field) => {\n const itemId = generateId();\n (addedItemIds[field] ??= []).push(itemId);\n return itemId;\n },\n idKeyedFields,\n }),\n );\n // The resolved id lets an id-less call's UI (and the model) address\n // the instance that was actually updated.\n const result: {\n success: true;\n id: string;\n addedItemIds?: Record<string, string[]>;\n } = { success: true, id: target.id };\n if (Object.keys(addedItemIds).length > 0) {\n result.addedItemIds = addedItemIds;\n }\n return result;\n },\n };\n }\n\n const interactables: Unstable_InteractableSnapshotEntry[] = entries.map(\n (def) => ({\n id: def.id,\n name: def.name,\n state: def.state,\n }),\n );\n return { tools, unstable_composerMetadata: { interactables } };\n}\n"],"mappings":"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"}
|
|
@@ -22,7 +22,7 @@ const useAssistantInteractable = (name, config) => {
|
|
|
22
22
|
const initialStateRef = useRef(config.initialState);
|
|
23
23
|
initialStateRef.current = config.initialState;
|
|
24
24
|
useEffect(() => {
|
|
25
|
-
return aui.interactables
|
|
25
|
+
return aui.interactables.register({
|
|
26
26
|
id,
|
|
27
27
|
name,
|
|
28
28
|
description: config.description,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssistantInteractable.js","names":["useEffect","useId","useRef","useAui","InteractableStateSchema","AssistantInteractableProps","description","stateSchema","initialState","id","selected","useAssistantInteractable","name","config","aui","autoId","replace","stateSchemaRef","current","initialStateRef","interactables","register"],"sources":["../../../src/react/interactables-legacy/useAssistantInteractable.ts"],"sourcesContent":["import { useEffect, useId, useRef } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { InteractableStateSchema } from \"./scopes\";\n\n/**\n * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.\n * Scheduled for removal on/after 2026-09-14. See\n * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.\n */\nexport type AssistantInteractableProps = {\n description: string;\n stateSchema: InteractableStateSchema;\n initialState: unknown;\n id?: string;\n selected?: boolean;\n};\n\n/**\n * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.\n * Scheduled for removal on/after 2026-09-14. See\n * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.\n *\n * Registers an interactable with the AI assistant.\n *\n * This hook handles registration only. To read and write the interactable's\n * state, use {@link useInteractableState} with the returned id.\n *\n * @returns The interactable instance id.\n */\nexport const useAssistantInteractable = (\n name: string,\n config: AssistantInteractableProps,\n): string => {\n const aui = useAui();\n\n const autoId = useId().replace(/[^a-zA-Z0-9]/g, \"\");\n const id = config.id ?? autoId;\n\n const stateSchemaRef = useRef(config.stateSchema);\n stateSchemaRef.current = config.stateSchema;\n const initialStateRef = useRef(config.initialState);\n initialStateRef.current = config.initialState;\n\n useEffect(() => {\n return aui.interactables
|
|
1
|
+
{"version":3,"file":"useAssistantInteractable.js","names":["useEffect","useId","useRef","useAui","InteractableStateSchema","AssistantInteractableProps","description","stateSchema","initialState","id","selected","useAssistantInteractable","name","config","aui","autoId","replace","stateSchemaRef","current","initialStateRef","interactables","register"],"sources":["../../../src/react/interactables-legacy/useAssistantInteractable.ts"],"sourcesContent":["import { useEffect, useId, useRef } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { InteractableStateSchema } from \"./scopes\";\n\n/**\n * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.\n * Scheduled for removal on/after 2026-09-14. See\n * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.\n */\nexport type AssistantInteractableProps = {\n description: string;\n stateSchema: InteractableStateSchema;\n initialState: unknown;\n id?: string;\n selected?: boolean;\n};\n\n/**\n * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.\n * Scheduled for removal on/after 2026-09-14. See\n * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.\n *\n * Registers an interactable with the AI assistant.\n *\n * This hook handles registration only. To read and write the interactable's\n * state, use {@link useInteractableState} with the returned id.\n *\n * @returns The interactable instance id.\n */\nexport const useAssistantInteractable = (\n name: string,\n config: AssistantInteractableProps,\n): string => {\n const aui = useAui();\n\n const autoId = useId().replace(/[^a-zA-Z0-9]/g, \"\");\n const id = config.id ?? autoId;\n\n const stateSchemaRef = useRef(config.stateSchema);\n stateSchemaRef.current = config.stateSchema;\n const initialStateRef = useRef(config.initialState);\n initialStateRef.current = config.initialState;\n\n useEffect(() => {\n return aui.interactables.register({\n id,\n name,\n description: config.description,\n stateSchema: stateSchemaRef.current,\n initialState: initialStateRef.current,\n selected: config.selected,\n });\n }, [aui, id, name, config.description, config.selected]);\n\n return id;\n};\n"],"mappings":";;;;;;;;;;;;;;;AA6BA,MAAaW,4BACXC,MACAC,WACW;CACX,MAAMC,MAAMX,OAAO;CAEnB,MAAMY,SAASd,MAAM,CAAC,CAACe,QAAQ,iBAAiB,EAAE;CAClD,MAAMP,KAAKI,OAAOJ,MAAMM;CAExB,MAAME,iBAAiBf,OAAOW,OAAON,WAAW;CAChDU,eAAeC,UAAUL,OAAON;CAChC,MAAMY,kBAAkBjB,OAAOW,OAAOL,YAAY;CAClDW,gBAAgBD,UAAUL,OAAOL;CAEjCR,gBAAgB;EACd,OAAOc,IAAIM,cAAcC,SAAS;GAChCZ;GACAG;GACAN,aAAaO,OAAOP;GACpBC,aAAaU,eAAeC;GAC5BV,cAAcW,gBAAgBD;GAC9BR,UAAUG,OAAOH;EACnB,CAAC;CACH,GAAG;EAACI;EAAKL;EAAIG;EAAMC,OAAOP;EAAaO,OAAOH;CAAQ,CAAC;CAEvD,OAAOD;AACT"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
2
|
+
import "@assistant-ui/tap/react-shim";
|
|
2
3
|
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
3
4
|
//#region src/react/interactables-legacy/useInteractableState.ts
|
|
4
5
|
/**
|
|
@@ -24,7 +25,7 @@ const useInteractableState = (id, fallback) => {
|
|
|
24
25
|
let t1;
|
|
25
26
|
if ($[2] !== aui || $[3] !== id) {
|
|
26
27
|
t1 = (updater) => {
|
|
27
|
-
aui.interactables
|
|
28
|
+
aui.interactables.setState(id, (prev) => {
|
|
28
29
|
if (typeof updater === "function") return updater(prev);
|
|
29
30
|
return updater;
|
|
30
31
|
});
|
|
@@ -37,7 +38,7 @@ const useInteractableState = (id, fallback) => {
|
|
|
37
38
|
let t2;
|
|
38
39
|
if ($[5] !== aui || $[6] !== id) {
|
|
39
40
|
t2 = (selected) => {
|
|
40
|
-
aui.interactables
|
|
41
|
+
aui.interactables.setSelected(id, selected);
|
|
41
42
|
};
|
|
42
43
|
$[5] = aui;
|
|
43
44
|
$[6] = id;
|
|
@@ -46,7 +47,7 @@ const useInteractableState = (id, fallback) => {
|
|
|
46
47
|
const setSelected = t2;
|
|
47
48
|
let t3;
|
|
48
49
|
if ($[8] !== aui) {
|
|
49
|
-
t3 = () => aui.interactables
|
|
50
|
+
t3 = () => aui.interactables.flush();
|
|
50
51
|
$[8] = aui;
|
|
51
52
|
$[9] = t3;
|
|
52
53
|
} else t3 = $[9];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInteractableState.js","names":["useCallback","useAui","useAuiState","StateUpdater","TState","prev","useInteractableState","id","fallback","$","_c","aui","state","s","interactables","definitions","t0","s_0","persistence","persistenceStatus","t1","updater","setState","t2","selected","setSelected","t3","flush","t4","isPending","t5","error","t6","t7"],"sources":["../../../src/react/interactables-legacy/useInteractableState.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\n\ntype StateUpdater<TState> = TState | ((prev: TState) => TState);\n\n/**\n * Reads and writes the state of a registered interactable.\n *\n * Pair with {@link useAssistantInteractable} which handles registration.\n *\n * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.\n * Scheduled for removal on/after 2026-09-14. See\n * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.\n */\nexport const useInteractableState = <TState>(\n id: string,\n fallback: TState,\n): [\n TState,\n {\n setState: (updater: StateUpdater<TState>) => void;\n setSelected: (selected: boolean) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] => {\n const aui = useAui();\n\n const state =\n (useAuiState((s) => s.interactables.definitions[id]?.state) as TState) ??\n (fallback as TState);\n\n const persistenceStatus = useAuiState((s) => s.interactables.persistence[id]);\n\n const setState = useCallback(\n (updater: StateUpdater<TState>) => {\n aui.interactables
|
|
1
|
+
{"version":3,"file":"useInteractableState.js","names":["useCallback","useAui","useAuiState","StateUpdater","TState","prev","useInteractableState","id","fallback","$","_c","aui","state","s","interactables","definitions","t0","s_0","persistence","persistenceStatus","t1","updater","setState","t2","selected","setSelected","t3","flush","t4","isPending","t5","error","t6","t7"],"sources":["../../../src/react/interactables-legacy/useInteractableState.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\n\ntype StateUpdater<TState> = TState | ((prev: TState) => TState);\n\n/**\n * Reads and writes the state of a registered interactable.\n *\n * Pair with {@link useAssistantInteractable} which handles registration.\n *\n * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.\n * Scheduled for removal on/after 2026-09-14. See\n * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.\n */\nexport const useInteractableState = <TState>(\n id: string,\n fallback: TState,\n): [\n TState,\n {\n setState: (updater: StateUpdater<TState>) => void;\n setSelected: (selected: boolean) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] => {\n const aui = useAui();\n\n const state =\n (useAuiState((s) => s.interactables.definitions[id]?.state) as TState) ??\n (fallback as TState);\n\n const persistenceStatus = useAuiState((s) => s.interactables.persistence[id]);\n\n const setState = useCallback(\n (updater: StateUpdater<TState>) => {\n aui.interactables.setState(id, (prev) => {\n if (typeof updater === \"function\") {\n return (updater as (prev: TState) => TState)(prev as TState);\n }\n return updater;\n });\n },\n [aui, id],\n );\n\n const setSelected = useCallback(\n (selected: boolean) => {\n aui.interactables.setSelected(id, selected);\n },\n [aui, id],\n );\n\n const flush = useCallback(() => aui.interactables.flush(), [aui]);\n\n return [\n state,\n {\n setState,\n setSelected,\n isPending: persistenceStatus?.isPending ?? false,\n error: persistenceStatus?.error,\n flush,\n },\n ];\n};\n"],"mappings":";;;;;;;;;;;;;AAcA,MAAaM,wBAAuBC,IAAAC,aAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAalC,MAAAC,MAAYV,OAAO;CAEnB,MAAAW,QACGV,aAAYW,MAAOA,EAACC,cAAcC,YAAaR,GAAU,EAAAK,KAAA,KACzDJ;CAAoB,IAAAQ;CAAA,IAAAP,EAAA,OAAAF,IAAA;EAEeS,MAAAC,QAAOJ,IAACC,cAAcI,YAAaX;EAAGE,EAAA,KAAAF;EAAAE,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAA5E,MAAAU,oBAA0BjB,YAAYc,EAAsC;CAAE,IAAAI;CAAA,IAAAX,EAAA,OAAAE,OAAAF,EAAA,OAAAF,IAAA;EAG5Ea,MAAAC,YAAA;GACEV,IAAGG,cAAcQ,SAAUf,KAAIF,SAAA;IAC7B,IAAI,OAAOgB,YAAY,YAAU,OACvBA,QAAqChB,IAAc;IAC5D,OACMgB;GAAO,CACf;EAAC;EACHZ,EAAA,KAAAE;EAAAF,EAAA,KAAAF;EAAAE,EAAA,KAAAW;CAAA,OAAAA,KAAAX,EAAA;CARH,MAAAa,WAAiBF;CAUf,IAAAG;CAAA,IAAAd,EAAA,OAAAE,OAAAF,EAAA,OAAAF,IAAA;EAGAgB,MAAAC,aAAA;GACEb,IAAGG,cAAcW,YAAalB,IAAIiB,QAAQ;EAAC;EAC5Cf,EAAA,KAAAE;EAAAF,EAAA,KAAAF;EAAAE,EAAA,KAAAc;CAAA,OAAAA,KAAAd,EAAA;CAHH,MAAAgB,cAAoBF;CAKlB,IAAAG;CAAA,IAAAjB,EAAA,OAAAE,KAAA;EAEwBe,WAAMf,IAAGG,cAAca,MAAO;EAAClB,EAAA,KAAAE;EAAAF,EAAA,KAAAiB;CAAA,OAAAA,KAAAjB,EAAA;CAAzD,MAAAkB,QAAcD;CAOC,MAAAE,KAAAT,mBAAiBU,aAAjB;CACJ,MAAAC,KAAAX,mBAAiBY;CAAO,IAAAC;CAAA,IAAAvB,EAAA,QAAAkB,SAAAlB,EAAA,QAAAgB,eAAAhB,EAAA,QAAAa,YAAAb,EAAA,QAAAmB,MAAAnB,EAAA,QAAAqB,IAAA;EAJjCE,KAAA;GAAAV;GAAAG;GAAAI,WAGaD;GAAqCG,OACzCD;GAAwBH;EAEjC;EAAClB,EAAA,MAAAkB;EAAAlB,EAAA,MAAAgB;EAAAhB,EAAA,MAAAa;EAAAb,EAAA,MAAAmB;EAAAnB,EAAA,MAAAqB;EAAArB,EAAA,MAAAuB;CAAA,OAAAA,KAAAvB,EAAA;CAAA,IAAAwB;CAAA,IAAAxB,EAAA,QAAAG,SAAAH,EAAA,QAAAuB,IAAA;EARIC,KAAA,CACLrB,OACAoB,EAMC;EACFvB,EAAA,MAAAG;EAAAH,EAAA,MAAAuB;EAAAvB,EAAA,MAAAwB;CAAA,OAAAA,KAAAxB,EAAA;CAAA,OATMwB;AASN"}
|
|
@@ -8,7 +8,7 @@ const useAssistantContext = (config) => {
|
|
|
8
8
|
getContextRef.current = getContext;
|
|
9
9
|
useEffect(() => {
|
|
10
10
|
if (disabled) return;
|
|
11
|
-
return aui.modelContext
|
|
11
|
+
return aui.modelContext.register({ getModelContext: () => ({ system: getContextRef.current() }) });
|
|
12
12
|
}, [aui, disabled]);
|
|
13
13
|
};
|
|
14
14
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssistantContext.js","names":["useEffect","useRef","useAui","AssistantContextConfig","useAssistantContext","config","getContext","disabled","aui","getContextRef","current","modelContext","register","getModelContext","system"],"sources":["../../../src/react/model-context/useAssistantContext.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { AssistantContextConfig } from \"../..\";\n\nexport type { AssistantContextConfig };\n\nexport const useAssistantContext = (config: AssistantContextConfig) => {\n const { getContext, disabled = false } = config;\n const aui = useAui();\n const getContextRef = useRef(getContext);\n getContextRef.current = getContext;\n\n useEffect(() => {\n if (disabled) return;\n\n return aui.modelContext
|
|
1
|
+
{"version":3,"file":"useAssistantContext.js","names":["useEffect","useRef","useAui","AssistantContextConfig","useAssistantContext","config","getContext","disabled","aui","getContextRef","current","modelContext","register","getModelContext","system"],"sources":["../../../src/react/model-context/useAssistantContext.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { AssistantContextConfig } from \"../..\";\n\nexport type { AssistantContextConfig };\n\nexport const useAssistantContext = (config: AssistantContextConfig) => {\n const { getContext, disabled = false } = config;\n const aui = useAui();\n const getContextRef = useRef(getContext);\n getContextRef.current = getContext;\n\n useEffect(() => {\n if (disabled) return;\n\n return aui.modelContext.register({\n getModelContext: () => ({\n system: getContextRef.current(),\n }),\n });\n }, [aui, disabled]);\n};\n"],"mappings":";;;AAMA,MAAaI,uBAAuBC,WAAmC;CACrE,MAAM,EAAEC,YAAYC,WAAW,UAAUF;CACzC,MAAMG,MAAMN,OAAO;CACnB,MAAMO,gBAAgBR,OAAOK,UAAU;CACvCG,cAAcC,UAAUJ;CAExBN,gBAAgB;EACd,IAAIO,UAAU;EAEd,OAAOC,IAAIG,aAAaC,SAAS,EAC/BC,wBAAwB,EACtBC,QAAQL,cAAcC,QAAQ,EAChC,GACF,CAAC;CACH,GAAG,CAACF,KAAKD,QAAQ,CAAC;AACpB"}
|
|
@@ -15,7 +15,7 @@ const useAssistantDataUI = (dataUI) => {
|
|
|
15
15
|
if ($[0] !== aui || $[1] !== dataUI) {
|
|
16
16
|
t0 = () => {
|
|
17
17
|
if (!dataUI?.name || !dataUI?.render) return;
|
|
18
|
-
return aui.dataRenderers
|
|
18
|
+
return aui.dataRenderers.setDataUI(dataUI.name, dataUI.render);
|
|
19
19
|
};
|
|
20
20
|
$[0] = aui;
|
|
21
21
|
$[1] = dataUI;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssistantDataUI.js","names":["useEffect","useAui","DataMessagePartComponent","AssistantDataUIProps","name","render","T","useAssistantDataUI","dataUI","$","_c","aui","t0","dataRenderers","setDataUI","t1","t2","t3"],"sources":["../../../src/react/model-context/useAssistantDataUI.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { DataMessagePartComponent } from \"../types/MessagePartComponentTypes\";\n\n/** Props used to register a renderer for `data` message parts. */\nexport type AssistantDataUIProps<T = any> = {\n /** Data part name this renderer handles. */\n name: string;\n /** Component rendered for matching data message parts. */\n render: DataMessagePartComponent<T>;\n};\n\n/**\n * Registers a renderer for named `data` message parts while the component is\n * mounted.\n *\n * @param dataUI - Data renderer registration, or `null` to skip registration.\n */\nexport const useAssistantDataUI = (dataUI: AssistantDataUIProps | null) => {\n const aui = useAui();\n useEffect(() => {\n if (!dataUI?.name || !dataUI?.render) return undefined;\n return aui.dataRenderers
|
|
1
|
+
{"version":3,"file":"useAssistantDataUI.js","names":["useEffect","useAui","DataMessagePartComponent","AssistantDataUIProps","name","render","T","useAssistantDataUI","dataUI","$","_c","aui","t0","dataRenderers","setDataUI","t1","t2","t3"],"sources":["../../../src/react/model-context/useAssistantDataUI.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { DataMessagePartComponent } from \"../types/MessagePartComponentTypes\";\n\n/** Props used to register a renderer for `data` message parts. */\nexport type AssistantDataUIProps<T = any> = {\n /** Data part name this renderer handles. */\n name: string;\n /** Component rendered for matching data message parts. */\n render: DataMessagePartComponent<T>;\n};\n\n/**\n * Registers a renderer for named `data` message parts while the component is\n * mounted.\n *\n * @param dataUI - Data renderer registration, or `null` to skip registration.\n */\nexport const useAssistantDataUI = (dataUI: AssistantDataUIProps | null) => {\n const aui = useAui();\n useEffect(() => {\n if (!dataUI?.name || !dataUI?.render) return undefined;\n return aui.dataRenderers.setDataUI(dataUI.name, dataUI.render);\n }, [aui, dataUI?.name, dataUI?.render]);\n};\n"],"mappings":";;;;;;;;;;AAkBA,MAAaO,sBAAqBC,WAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAChC,MAAAC,MAAYV,OAAO;CAAE,IAAAW;CAAA,IAAAH,EAAA,OAAAE,OAAAF,EAAA,OAAAD,QAAA;EACXI,WAAA;GACR,IAAI,CAACJ,QAAMJ,QAAP,CAAkBI,QAAMH,QAAQ;GAAmB,OAChDM,IAAGE,cAAcC,UAAWN,OAAMJ,MAAOI,OAAMH,MAAO;EAAC;EAC/DI,EAAA,KAAAE;EAAAF,EAAA,KAAAD;EAAAC,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAAQ,MAAAM,KAAAP,QAAMJ;CAAQ,MAAAY,KAAAR,QAAMH;CAAQ,IAAAY;CAAA,IAAAR,EAAA,OAAAE,OAAAF,EAAA,OAAAM,MAAAN,EAAA,OAAAO,IAAA;EAAlCC,KAAA;GAACN;GAAKI;GAAcC;EAAc;EAACP,EAAA,KAAAE;EAAAF,EAAA,KAAAM;EAAAN,EAAA,KAAAO;EAAAP,EAAA,KAAAQ;CAAA,OAAAA,KAAAR,EAAA;CAHtCT,UAAUY,IAGPK,EAAmC;AAAC"}
|
|
@@ -23,7 +23,7 @@ const useAssistantInstructions = (config) => {
|
|
|
23
23
|
t2 = () => {
|
|
24
24
|
if (disabled) return;
|
|
25
25
|
const config_0 = { system: instruction };
|
|
26
|
-
return aui.modelContext
|
|
26
|
+
return aui.modelContext.register({ getModelContext: () => config_0 });
|
|
27
27
|
};
|
|
28
28
|
t3 = [
|
|
29
29
|
aui,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssistantInstructions.js","names":["useEffect","useAui","AssistantInstructionsConfig","getInstructions","instruction","useAssistantInstructions","config","$","_c","t0","disabled","t1","undefined","aui","t2","t3","config_0","system","modelContext","register","getModelContext"],"sources":["../../../src/react/model-context/useAssistantInstructions.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { AssistantInstructionsConfig } from \"../..\";\n\nexport type { AssistantInstructionsConfig };\n\nconst getInstructions = (\n instruction: string | AssistantInstructionsConfig,\n): AssistantInstructionsConfig => {\n if (typeof instruction === \"string\") return { instruction };\n return instruction;\n};\n\nexport const useAssistantInstructions = (\n config: string | AssistantInstructionsConfig,\n) => {\n const { instruction, disabled = false } = getInstructions(config);\n const aui = useAui();\n\n useEffect(() => {\n if (disabled) return;\n\n const config = {\n system: instruction,\n };\n return aui.modelContext
|
|
1
|
+
{"version":3,"file":"useAssistantInstructions.js","names":["useEffect","useAui","AssistantInstructionsConfig","getInstructions","instruction","useAssistantInstructions","config","$","_c","t0","disabled","t1","undefined","aui","t2","t3","config_0","system","modelContext","register","getModelContext"],"sources":["../../../src/react/model-context/useAssistantInstructions.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { AssistantInstructionsConfig } from \"../..\";\n\nexport type { AssistantInstructionsConfig };\n\nconst getInstructions = (\n instruction: string | AssistantInstructionsConfig,\n): AssistantInstructionsConfig => {\n if (typeof instruction === \"string\") return { instruction };\n return instruction;\n};\n\nexport const useAssistantInstructions = (\n config: string | AssistantInstructionsConfig,\n) => {\n const { instruction, disabled = false } = getInstructions(config);\n const aui = useAui();\n\n useEffect(() => {\n if (disabled) return;\n\n const config = {\n system: instruction,\n };\n return aui.modelContext.register({\n getModelContext: () => config,\n });\n }, [aui, instruction, disabled]);\n};\n"],"mappings":";;;;AAMA,MAAMG,mBACJC,gBACgC;CAChC,IAAI,OAAOA,gBAAgB,UAAU,OAAO,EAAEA,YAAY;CAC1D,OAAOA;AACT;AAEA,MAAaC,4BAA2BC,WAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAD,QAAA;EAGIG,KAAAN,gBAAgBG,MAAM;EAACC,EAAA,KAAAD;EAAAC,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAjE,MAAA,EAAAH,aAAAM,UAAAC,OAA0CF;CAArB,MAAAC,WAAAC,OAAAC,KAAAA,IAAA,QAAAD;CACrB,MAAAE,MAAYZ,OAAO;CAAE,IAAAa;CAAA,IAAAC;CAAA,IAAAR,EAAA,OAAAM,OAAAN,EAAA,OAAAG,YAAAH,EAAA,OAAAH,aAAA;EAEXU,WAAA;GACR,IAAIJ,UAAQ;GAEZ,MAAAM,WAAe,EAAAC,QACLb,YACV;GAAE,OACKS,IAAGK,aAAaC,SAAU,EAAAC,uBACRd,SACzB,CAAC;EAAC;EACDS,KAAA;GAACF;GAAKT;GAAaM;EAAQ;EAACH,EAAA,KAAAM;EAAAN,EAAA,KAAAG;EAAAH,EAAA,KAAAH;EAAAG,EAAA,KAAAO;EAAAP,EAAA,KAAAQ;CAAA,OAAA;EAAAD,KAAAP,EAAA;EAAAQ,KAAAR,EAAA;CAAA;CAT/BP,UAAUc,IASPC,EAA4B;AAAC"}
|
|
@@ -38,7 +38,7 @@ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
|
38
38
|
* ```
|
|
39
39
|
*/
|
|
40
40
|
const useAssistantTool = (tool) => {
|
|
41
|
-
const $ = c(
|
|
41
|
+
const $ = c(20);
|
|
42
42
|
const aui = useAui();
|
|
43
43
|
let t0;
|
|
44
44
|
if ($[0] !== tool) {
|
|
@@ -56,46 +56,50 @@ const useAssistantTool = (tool) => {
|
|
|
56
56
|
const renderTextComponent = t1;
|
|
57
57
|
const render = tool.render ?? renderTextComponent;
|
|
58
58
|
let t2;
|
|
59
|
-
|
|
60
|
-
if ($[4] !== aui || $[5] !== render || $[6] !== standalone || $[7] !== tool.toolName) {
|
|
59
|
+
if ($[4] !== aui.tools || $[5] !== render || $[6] !== standalone || $[7] !== tool.toolName) {
|
|
61
60
|
t2 = () => {
|
|
62
61
|
if (!render) return;
|
|
63
|
-
return aui.tools
|
|
62
|
+
return aui.tools.setToolUI(tool.toolName, render, { standalone });
|
|
64
63
|
};
|
|
64
|
+
$[4] = aui.tools;
|
|
65
|
+
$[5] = render;
|
|
66
|
+
$[6] = standalone;
|
|
67
|
+
$[7] = tool.toolName;
|
|
68
|
+
$[8] = t2;
|
|
69
|
+
} else t2 = $[8];
|
|
70
|
+
let t3;
|
|
71
|
+
if ($[9] !== aui || $[10] !== render || $[11] !== standalone || $[12] !== tool.toolName) {
|
|
65
72
|
t3 = [
|
|
66
73
|
aui,
|
|
67
74
|
tool.toolName,
|
|
68
75
|
render,
|
|
69
76
|
standalone
|
|
70
77
|
];
|
|
71
|
-
$[
|
|
72
|
-
$[
|
|
73
|
-
$[
|
|
74
|
-
$[
|
|
75
|
-
$[
|
|
76
|
-
|
|
77
|
-
} else {
|
|
78
|
-
t2 = $[8];
|
|
79
|
-
t3 = $[9];
|
|
80
|
-
}
|
|
78
|
+
$[9] = aui;
|
|
79
|
+
$[10] = render;
|
|
80
|
+
$[11] = standalone;
|
|
81
|
+
$[12] = tool.toolName;
|
|
82
|
+
$[13] = t3;
|
|
83
|
+
} else t3 = $[13];
|
|
81
84
|
useEffect(t2, t3);
|
|
82
85
|
let t4;
|
|
83
|
-
|
|
84
|
-
if ($[10] !== aui || $[11] !== tool) {
|
|
86
|
+
if ($[14] !== aui.modelContext || $[15] !== tool) {
|
|
85
87
|
t4 = () => {
|
|
86
88
|
const { toolName, render: render_0, renderText, display, ...rest } = tool;
|
|
87
89
|
const context = { tools: { [toolName]: rest } };
|
|
88
|
-
return aui.modelContext
|
|
90
|
+
return aui.modelContext.register({ getModelContext: () => context });
|
|
89
91
|
};
|
|
92
|
+
$[14] = aui.modelContext;
|
|
93
|
+
$[15] = tool;
|
|
94
|
+
$[16] = t4;
|
|
95
|
+
} else t4 = $[16];
|
|
96
|
+
let t5;
|
|
97
|
+
if ($[17] !== aui || $[18] !== tool) {
|
|
90
98
|
t5 = [aui, tool];
|
|
91
|
-
$[
|
|
92
|
-
$[
|
|
93
|
-
$[
|
|
94
|
-
|
|
95
|
-
} else {
|
|
96
|
-
t4 = $[12];
|
|
97
|
-
t5 = $[13];
|
|
98
|
-
}
|
|
99
|
+
$[17] = aui;
|
|
100
|
+
$[18] = tool;
|
|
101
|
+
$[19] = t5;
|
|
102
|
+
} else t5 = $[19];
|
|
99
103
|
useEffect(t4, t5);
|
|
100
104
|
};
|
|
101
105
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssistantTool.js","names":["useEffect","useMemo","useAui","ToolCallMessagePartComponent","AssistantToolProps","CoreAssistantToolProps","isStandaloneToolDisplay","makeToolCallTextComponent","ToolCallText","Record","TArgs","TResult","render","renderText","useAssistantTool","tool","$","_c","aui","t0","standalone","t1","undefined","renderTextComponent","t2","
|
|
1
|
+
{"version":3,"file":"useAssistantTool.js","names":["useEffect","useMemo","useAui","ToolCallMessagePartComponent","AssistantToolProps","CoreAssistantToolProps","isStandaloneToolDisplay","makeToolCallTextComponent","ToolCallText","Record","TArgs","TResult","render","renderText","useAssistantTool","tool","$","_c","aui","t0","standalone","t1","undefined","renderTextComponent","t2","tools","toolName","setToolUI","t3","t4","modelContext","render_0","display","rest","context","register","getModelContext","t5"],"sources":["../../../src/react/model-context/useAssistantTool.ts"],"sourcesContent":["import { useEffect, useMemo } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { ToolCallMessagePartComponent } from \"../types/MessagePartComponentTypes\";\nimport type { AssistantToolProps as CoreAssistantToolProps } from \"../..\";\nimport {\n isStandaloneToolDisplay,\n makeToolCallTextComponent,\n type ToolCallText,\n} from \"./toolbox\";\n\n/**\n * Props used to register a tool from React.\n *\n * @deprecated Use a toolkit with `Tools({ toolkit })` and register it via\n * `useAui({ tools: Tools({ toolkit }) })` instead. See\n * https://assistant-ui.com/docs/migrations/toolkit-tools.\n */\nexport type AssistantToolProps<\n TArgs extends Record<string, unknown>,\n TResult,\n> = CoreAssistantToolProps<TArgs, TResult> & {\n /** Component used to render calls to this tool in assistant messages. */\n render?: ToolCallMessagePartComponent<TArgs, TResult> | undefined;\n /** Lightweight text rendered while a tool call is running or complete. */\n renderText?: ToolCallText<TArgs, TResult> | undefined;\n};\n\n/**\n * Registers a tool with the assistant model context while the component is\n * mounted.\n *\n * If `render` is provided, it is also installed as the renderer for matching\n * tool-call message parts. The registration is removed automatically when the\n * component unmounts or the tool definition changes.\n *\n * Pass a referentially stable tool object, such as one declared at module\n * scope or memoized with `useMemo`, to avoid re-registering on every render.\n *\n * @param tool - Tool definition and name to register.\n *\n * @deprecated Use a toolkit with `Tools({ toolkit })` and register it via\n * `useAui({ tools: Tools({ toolkit }) })` instead. See\n * https://assistant-ui.com/docs/migrations/toolkit-tools.\n *\n * @example\n * ```tsx\n * const weatherTool = {\n * toolName: \"get_weather\",\n * type: \"frontend\",\n * description: \"Get the weather for a city.\",\n * parameters: weatherSchema,\n * execute: async ({ city }: { city: string }) => fetchWeather(city),\n * render: WeatherToolUI,\n * } satisfies AssistantToolProps<{ city: string }, Weather>;\n *\n * function WeatherToolRegistration() {\n * useAssistantTool(weatherTool);\n * return null;\n * }\n * ```\n */\nexport const useAssistantTool = <\n TArgs extends Record<string, unknown>,\n TResult,\n>(\n tool: AssistantToolProps<TArgs, TResult>,\n) => {\n const aui = useAui();\n\n const standalone = isStandaloneToolDisplay(tool);\n const renderTextComponent = useMemo(\n () =>\n tool.renderText ? makeToolCallTextComponent(tool.renderText) : undefined,\n [tool.renderText],\n );\n const render = tool.render ?? renderTextComponent;\n\n useEffect(() => {\n if (!render) return undefined;\n return aui.tools.setToolUI(tool.toolName, render, { standalone });\n }, [aui, tool.toolName, render, standalone]);\n\n useEffect(() => {\n // `render`, `renderText`, and `display` are client-only presentation\n // concerns and never reach the model.\n const { toolName, render, renderText, display, ...rest } = tool;\n const context = {\n tools: {\n [toolName]: rest,\n },\n };\n return aui.modelContext.register({\n getModelContext: () => context,\n });\n }, [aui, tool]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,MAAac,oBAAmBC,SAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAM9B,MAAAC,MAAYhB,OAAO;CAAE,IAAAiB;CAAA,IAAAH,EAAA,OAAAD,MAAA;EAEFI,KAAAb,wBAAwBS,IAAI;EAACC,EAAA,KAAAD;EAAAC,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAAhD,MAAAI,aAAmBD;CAA8B,IAAAE;CAAA,IAAAL,EAAA,OAAAD,KAAAF,YAAA;EAG7CQ,KAAAN,KAAIF,aAAcN,0BAA0BQ,KAAIF,UAAuB,IAAvES,KAAAA;EAAwEN,EAAA,KAAAD,KAAAF;EAAAG,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAF5E,MAAAO,sBAEIF;CAGJ,MAAAT,SAAeG,KAAIH,UAAJW;CAAmC,IAAAC;CAAA,IAAAR,EAAA,OAAAE,IAAAO,SAAAT,EAAA,OAAAJ,UAAAI,EAAA,OAAAI,cAAAJ,EAAA,OAAAD,KAAAW,UAAA;EAExCF,WAAA;GACR,IAAI,CAACZ,QAAM;GAAmB,OACvBM,IAAGO,MAAME,UAAWZ,KAAIW,UAAWd,QAAQ,EAAAQ,WAAa,CAAC;EAAC;EAClEJ,EAAA,KAAAE,IAAAO;EAAAT,EAAA,KAAAJ;EAAAI,EAAA,KAAAI;EAAAJ,EAAA,KAAAD,KAAAW;EAAAV,EAAA,KAAAQ;CAAA,OAAAA,KAAAR,EAAA;CAAA,IAAAY;CAAA,IAAAZ,EAAA,OAAAE,OAAAF,EAAA,QAAAJ,UAAAI,EAAA,QAAAI,cAAAJ,EAAA,QAAAD,KAAAW,UAAA;EAAEE,KAAA;GAACV;GAAKH,KAAIW;GAAWd;GAAQQ;EAAU;EAACJ,EAAA,KAAAE;EAAAF,EAAA,MAAAJ;EAAAI,EAAA,MAAAI;EAAAJ,EAAA,MAAAD,KAAAW;EAAAV,EAAA,MAAAY;CAAA,OAAAA,KAAAZ,EAAA;CAH3ChB,UAAUwB,IAGPI,EAAwC;CAAC,IAAAC;CAAA,IAAAb,EAAA,QAAAE,IAAAY,gBAAAd,EAAA,QAAAD,MAAA;EAElCc,WAAA;GAGR,MAAA,EAAAH,UAAAd,QAAAmB,UAAAlB,YAAAmB,SAAA,GAAAC,SAA2DlB;GAC3D,MAAAmB,UAAgB,EAAAT,OACP,GACJC,WAAWO,KACd,EACF;GAAE,OACKf,IAAGY,aAAaK,SAAU,EAAAC,uBACRF,QACzB,CAAC;EAAC;EACHlB,EAAA,MAAAE,IAAAY;EAAAd,EAAA,MAAAD;EAAAC,EAAA,MAAAa;CAAA,OAAAA,KAAAb,EAAA;CAAA,IAAAqB;CAAA,IAAArB,EAAA,QAAAE,OAAAF,EAAA,QAAAD,MAAA;EAAEsB,KAAA,CAACnB,KAAKH,IAAI;EAACC,EAAA,MAAAE;EAAAF,EAAA,MAAAD;EAAAC,EAAA,MAAAqB;CAAA,OAAAA,KAAArB,EAAA;CAZdhB,UAAU6B,IAYPQ,EAAW;AAAC"}
|
|
@@ -22,7 +22,7 @@ const useAssistantToolUI = (tool) => {
|
|
|
22
22
|
if ($[0] !== aui || $[1] !== standalone || $[2] !== tool) {
|
|
23
23
|
t0 = () => {
|
|
24
24
|
if (!tool?.toolName || !tool?.render) return;
|
|
25
|
-
return aui.tools
|
|
25
|
+
return aui.tools.setToolUI(tool.toolName, tool.render, { standalone });
|
|
26
26
|
};
|
|
27
27
|
$[0] = aui;
|
|
28
28
|
$[1] = standalone;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssistantToolUI.js","names":["useEffect","useAui","ToolCallMessagePartComponent","AssistantToolUIProps","toolName","render","TArgs","TResult","display","useAssistantToolUI","tool","$","_c","aui","standalone","t0","tools","setToolUI","t1","t2","t3"],"sources":["../../../src/react/model-context/useAssistantToolUI.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { ToolCallMessagePartComponent } from \"../types/MessagePartComponentTypes\";\n\n/**\n * Props used to register a renderer for tool-call message parts.\n *\n * @deprecated Put `render`/`renderText` on the matching toolkit entry, or use\n * `MessagePrimitive.Parts` inline tool render overrides for per-message UI.\n * See https://assistant-ui.com/docs/migrations/toolkit-tools.\n */\nexport type AssistantToolUIProps<TArgs, TResult> = {\n /** Name of the tool whose calls should use this renderer. */\n toolName: string;\n /** Component rendered for matching tool-call message parts. */\n render: ToolCallMessagePartComponent<TArgs, TResult>;\n /**\n * How the UI is presented relative to the chain-of-thought trace. Set\n * `\"standalone\"` to surface it on its own (e.g. human-in-the-loop or\n * generative UI for a backend/MCP tool). Defaults to `\"inline\"`.\n */\n display?: \"standalone\" | \"inline\";\n};\n\n/**\n * Registers a tool-call renderer while the component is mounted.\n *\n * This only affects rendering. Pair it with {@link Tools} or a backend tool\n * registry to expose the actual tool definition to the model.\n *\n * @param tool - Tool renderer registration, or `null` to skip registration.\n *\n * @deprecated Put `render`/`renderText` on the matching toolkit entry, or use\n * `MessagePrimitive.Parts` inline tool render overrides for per-message UI.\n * See https://assistant-ui.com/docs/migrations/toolkit-tools.\n */\nexport const useAssistantToolUI = (\n tool: AssistantToolUIProps<any, any> | null,\n) => {\n const aui = useAui();\n const standalone = tool?.display === \"standalone\";\n useEffect(() => {\n if (!tool?.toolName || !tool?.render) return undefined;\n return aui.tools
|
|
1
|
+
{"version":3,"file":"useAssistantToolUI.js","names":["useEffect","useAui","ToolCallMessagePartComponent","AssistantToolUIProps","toolName","render","TArgs","TResult","display","useAssistantToolUI","tool","$","_c","aui","standalone","t0","tools","setToolUI","t1","t2","t3"],"sources":["../../../src/react/model-context/useAssistantToolUI.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { ToolCallMessagePartComponent } from \"../types/MessagePartComponentTypes\";\n\n/**\n * Props used to register a renderer for tool-call message parts.\n *\n * @deprecated Put `render`/`renderText` on the matching toolkit entry, or use\n * `MessagePrimitive.Parts` inline tool render overrides for per-message UI.\n * See https://assistant-ui.com/docs/migrations/toolkit-tools.\n */\nexport type AssistantToolUIProps<TArgs, TResult> = {\n /** Name of the tool whose calls should use this renderer. */\n toolName: string;\n /** Component rendered for matching tool-call message parts. */\n render: ToolCallMessagePartComponent<TArgs, TResult>;\n /**\n * How the UI is presented relative to the chain-of-thought trace. Set\n * `\"standalone\"` to surface it on its own (e.g. human-in-the-loop or\n * generative UI for a backend/MCP tool). Defaults to `\"inline\"`.\n */\n display?: \"standalone\" | \"inline\";\n};\n\n/**\n * Registers a tool-call renderer while the component is mounted.\n *\n * This only affects rendering. Pair it with {@link Tools} or a backend tool\n * registry to expose the actual tool definition to the model.\n *\n * @param tool - Tool renderer registration, or `null` to skip registration.\n *\n * @deprecated Put `render`/`renderText` on the matching toolkit entry, or use\n * `MessagePrimitive.Parts` inline tool render overrides for per-message UI.\n * See https://assistant-ui.com/docs/migrations/toolkit-tools.\n */\nexport const useAssistantToolUI = (\n tool: AssistantToolUIProps<any, any> | null,\n) => {\n const aui = useAui();\n const standalone = tool?.display === \"standalone\";\n useEffect(() => {\n if (!tool?.toolName || !tool?.render) return undefined;\n return aui.tools.setToolUI(tool.toolName, tool.render, { standalone });\n }, [aui, tool?.toolName, tool?.render, standalone]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAoCA,MAAaS,sBAAqBC,SAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAGhC,MAAAC,MAAYZ,OAAO;CACnB,MAAAa,aAAmBJ,MAAIF,YAAc;CAAa,IAAAO;CAAA,IAAAJ,EAAA,OAAAE,OAAAF,EAAA,OAAAG,cAAAH,EAAA,OAAAD,MAAA;EACxCK,WAAA;GACR,IAAI,CAACL,MAAIN,YAAL,CAAoBM,MAAIL,QAAQ;GAAmB,OAChDQ,IAAGG,MAAMC,UAAWP,KAAIN,UAAWM,KAAIL,QAAS,EAAAS,WAAa,CAAC;EAAC;EACvEH,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAD;EAAAC,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAAQ,MAAAO,KAAAR,MAAIN;CAAY,MAAAe,KAAAT,MAAIL;CAAQ,IAAAe;CAAA,IAAAT,EAAA,OAAAE,OAAAF,EAAA,OAAAG,cAAAH,EAAA,OAAAO,MAAAP,EAAA,OAAAQ,IAAA;EAAlCC,KAAA;GAACP;GAAKK;GAAgBC;GAAcL;EAAU;EAACH,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAO;EAAAP,EAAA,KAAAQ;EAAAR,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAHlDX,UAAUe,IAGPK,EAA+C;AAAC"}
|
|
@@ -19,7 +19,7 @@ function useAuiToolOverrides(overrides) {
|
|
|
19
19
|
const overridesRef = useRef(overrides);
|
|
20
20
|
overridesRef.current = overrides;
|
|
21
21
|
useEffect(() => {
|
|
22
|
-
return aui.modelContext
|
|
22
|
+
return aui.modelContext.register({ getModelContext: () => ({
|
|
23
23
|
priority: 1e3,
|
|
24
24
|
tools: overridesRef.current
|
|
25
25
|
}) });
|