@assistant-ui/core 0.2.21 → 0.2.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/attachment.d.ts.map +1 -1
- package/dist/adapters/speech.d.ts.map +1 -1
- package/dist/adapters/speech.js +9 -2
- package/dist/adapters/speech.js.map +1 -1
- package/dist/adapters/thread-history.d.ts +8 -0
- package/dist/adapters/thread-history.d.ts.map +1 -1
- package/dist/adapters/voice.d.ts.map +1 -1
- package/dist/adapters/voice.js +13 -5
- package/dist/adapters/voice.js.map +1 -1
- package/dist/internal.d.ts +5 -2
- package/dist/internal.js +5 -2
- package/dist/model-context/frame/host.d.ts +1 -0
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js +41 -21
- package/dist/model-context/frame/host.js.map +1 -1
- package/dist/model-context/frame/provider.d.ts.map +1 -1
- package/dist/model-context/frame/provider.js +1 -0
- package/dist/model-context/frame/provider.js.map +1 -1
- package/dist/model-context/interactable-composer-metadata.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/AssistantProvider.js.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.js +78 -50
- package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
- package/dist/react/client/Interactables.js.map +1 -1
- package/dist/react/client/Tools.d.ts.map +1 -1
- package/dist/react/client/interactable-model-context.d.ts.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/useInteractableState.js +1 -0
- package/dist/react/interactables-legacy/useInteractableState.js.map +1 -1
- package/dist/react/model-context/useInteractable.js.map +1 -1
- package/dist/react/model-context/useInteractableState.js +1 -0
- 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 +14 -13
- package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarEdit.js +1 -0
- package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarFeedback.js +1 -0
- package/dist/react/primitive-hooks/useActionBarFeedback.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarReload.js +1 -0
- package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarSpeak.js +1 -0
- package/dist/react/primitive-hooks/useActionBarSpeak.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarStopSpeaking.js +1 -0
- package/dist/react/primitive-hooks/useActionBarStopSpeaking.js.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerNext.js +1 -0
- package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerPrevious.js +1 -0
- package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
- package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useComposerAddAttachment.js +1 -0
- package/dist/react/primitive-hooks/useComposerAddAttachment.js.map +1 -1
- package/dist/react/primitive-hooks/useComposerCancel.js +1 -0
- package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
- package/dist/react/primitive-hooks/useComposerDictate.js +1 -0
- package/dist/react/primitive-hooks/useComposerDictate.js.map +1 -1
- package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useComposerSend.js +1 -0
- package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
- package/dist/react/primitive-hooks/useEditComposerCancel.js +1 -0
- package/dist/react/primitive-hooks/useEditComposerCancel.js.map +1 -1
- package/dist/react/primitive-hooks/useEditComposerSend.js +1 -0
- package/dist/react/primitive-hooks/useEditComposerSend.js.map +1 -1
- package/dist/react/primitive-hooks/useMessageBranching.js +1 -0
- package/dist/react/primitive-hooks/useMessageBranching.js.map +1 -1
- package/dist/react/primitive-hooks/useMessageReload.js +1 -0
- package/dist/react/primitive-hooks/useMessageReload.js.map +1 -1
- package/dist/react/primitive-hooks/useSuggestionTrigger.js +1 -0
- package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListItemArchive.js +1 -0
- package/dist/react/primitive-hooks/useThreadListItemArchive.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListItemDelete.js +1 -0
- package/dist/react/primitive-hooks/useThreadListItemDelete.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListItemTrigger.js +1 -0
- package/dist/react/primitive-hooks/useThreadListItemTrigger.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListItemUnarchive.js +1 -0
- package/dist/react/primitive-hooks/useThreadListItemUnarchive.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListLoadMore.js +1 -0
- package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListNew.js +1 -0
- package/dist/react/primitive-hooks/useThreadListNew.js.map +1 -1
- package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts.map +1 -1
- package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js +1 -1
- package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
- package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
- package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
- package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
- package/dist/react/primitives/generativeUI/GenerativeUI.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
- package/dist/react/primitives/message/MessageParts.d.ts +2 -1
- package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageParts.js +46 -36
- package/dist/react/primitives/message/MessageParts.js.map +1 -1
- package/dist/react/primitives/part/PartMessages.js.map +1 -1
- package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
- package/dist/react/primitives/thread/ThreadSuggestions.js.map +1 -1
- package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
- package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +1 -1
- package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js +18 -30
- package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js.map +1 -1
- package/dist/react/providers/PartByIndexProvider.d.ts.map +1 -1
- package/dist/react/providers/PartByIndexProvider.js +18 -30
- package/dist/react/providers/PartByIndexProvider.js.map +1 -1
- package/dist/react/providers/TextMessagePartProvider.js +1 -0
- package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +1 -0
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +9 -2
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +55 -12
- 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 +12 -2
- 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 +3 -2
- 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/createMessageConverter.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.js +2 -2
- 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.map +1 -1
- package/dist/react/runtimes/useLocalRuntime.js +9 -1
- package/dist/react/runtimes/useLocalRuntime.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 +6 -6
- 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 +4 -3
- 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/api/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts +4 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.js +41 -14
- package/dist/runtime/base/base-composer-runtime-core.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 +3 -2
- package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
- package/dist/runtime/base/default-edit-composer-runtime-core.d.ts +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 +6 -4
- 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 +3 -3
- 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/runtime/utils/thread-message-like.js +4 -1
- package/dist/runtime/utils/thread-message-like.js.map +1 -1
- package/dist/runtimes/external-store/external-store-runtime-core.d.ts.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-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -0
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +49 -15
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +4 -4
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.js +22 -9
- package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
- package/dist/runtimes/remote-thread-list/types.d.ts +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 +3 -2
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
- package/dist/store/clients/chain-of-thought-client.d.ts.map +1 -1
- package/dist/store/clients/no-op-composer-client.d.ts.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/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/message-part-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.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 +4 -4
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/subscribable/subscribable.js +14 -6
- package/dist/subscribable/subscribable.js.map +1 -1
- package/dist/tests/remote-thread-list-test-helpers.d.ts +2 -1
- package/dist/tests/remote-thread-list-test-helpers.d.ts.map +1 -1
- package/dist/tests/remote-thread-list-test-helpers.js +5 -2
- package/dist/tests/remote-thread-list-test-helpers.js.map +1 -1
- package/dist/types/attachment.d.ts +2 -1
- package/dist/types/attachment.d.ts.map +1 -1
- package/dist/types/attachment.js +6 -0
- package/dist/types/attachment.js.map +1 -0
- package/dist/types/message.d.ts +1 -0
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/message.js.map +1 -1
- package/dist/utils/data-url.d.ts +9 -0
- package/dist/utils/data-url.d.ts.map +1 -0
- package/dist/utils/data-url.js +14 -0
- package/dist/utils/data-url.js.map +1 -0
- package/dist/utils/notify-event-listeners.d.ts +6 -0
- package/dist/utils/notify-event-listeners.d.ts.map +1 -0
- package/dist/utils/notify-event-listeners.js +16 -0
- package/dist/utils/notify-event-listeners.js.map +1 -0
- package/package.json +10 -9
- package/src/adapters/speech.test.ts +88 -0
- package/src/adapters/speech.ts +17 -2
- package/src/adapters/thread-history.ts +8 -0
- package/src/adapters/voice.test.ts +130 -0
- package/src/adapters/voice.ts +26 -6
- package/src/internal.ts +6 -1
- package/src/model-context/frame/host.test.ts +147 -0
- package/src/model-context/frame/host.ts +56 -19
- package/src/model-context/frame/provider.test.ts +83 -0
- package/src/model-context/frame/provider.ts +1 -0
- package/src/model-context/types.ts +16 -6
- package/src/react/adapters/LocalStorageThreadListAdapter.test.ts +82 -0
- package/src/react/adapters/LocalStorageThreadListAdapter.tsx +108 -58
- package/src/react/primitive-hooks/useActionBarCopy.test.ts +79 -0
- package/src/react/primitive-hooks/useActionBarCopy.ts +4 -3
- package/src/react/primitives/chainOfThought/ChainOfThoughtParts.tsx +1 -3
- package/src/react/primitives/message/MessageParts.tsx +48 -35
- package/src/react/providers/ChainOfThoughtPartByIndexProvider.tsx +19 -2
- package/src/react/providers/PartByIndexProvider.tsx +16 -2
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +18 -0
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +1 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +68 -13
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +34 -0
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +69 -0
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +27 -6
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.test.ts +16 -0
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +7 -2
- package/src/react/runtimes/cloud/auiV0.ts +14 -0
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +90 -88
- package/src/react/runtimes/external-message-converter.test.ts +346 -0
- package/src/react/runtimes/external-message-converter.test.tsx +21 -0
- package/src/react/runtimes/external-message-converter.ts +2 -2
- package/src/react/runtimes/useLocalRuntime.test.tsx +99 -0
- package/src/react/runtimes/useLocalRuntime.ts +13 -1
- 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.test.ts +81 -0
- package/src/runtime/api/message-runtime.ts +11 -8
- package/src/runtime/api/thread-list-item-runtime.ts +13 -3
- package/src/runtime/api/thread-list-runtime.ts +10 -2
- package/src/runtime/base/base-composer-runtime-core.ts +77 -31
- package/src/runtime/base/base-thread-runtime-core.ts +7 -2
- package/src/runtime/base/default-edit-composer-runtime-core.ts +18 -4
- package/src/runtime/base/default-thread-composer-runtime-core.ts +13 -3
- package/src/runtime/utils/message-repository.ts +19 -13
- package/src/runtime/utils/thread-message-like.ts +1 -0
- 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 +746 -1
- package/src/runtimes/local/local-thread-runtime-core.ts +89 -23
- package/src/runtimes/local/should-continue.test.ts +122 -0
- package/src/runtimes/remote-thread-list/optimistic-state.test.ts +63 -0
- package/src/runtimes/remote-thread-list/optimistic-state.ts +49 -17
- package/src/runtimes/remote-thread-list/types.ts +1 -1
- package/src/runtimes/tool-invocations/EDGE_CASES.md +13 -19
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +128 -8
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +42 -34
- package/src/store/clients/model-context-client.test.ts +21 -1
- package/src/store/runtime-clients/thread-runtime-client.ts +2 -1
- package/src/store/scopes/thread.ts +1 -0
- package/src/subscribable/subscribable.test.ts +58 -0
- package/src/subscribable/subscribable.ts +29 -11
- package/src/tests/MessageRepository.test.ts +12 -0
- package/src/tests/OptimisticState-list-race.test.ts +33 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-order.test.ts +223 -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-addAttachment.test.ts +44 -0
- package/src/tests/base-composer-runtime-core-send.test.ts +433 -5
- package/src/tests/base-composer-runtime-core.test.ts +422 -0
- package/src/tests/default-edit-composer-runtime-core.test.ts +43 -5
- package/src/tests/event-subscription-listener-errors.test.ts +205 -0
- package/src/tests/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/remote-thread-list-test-helpers.ts +14 -7
- package/src/tests/thread-message-like.test.ts +57 -0
- package/src/types/attachment.ts +5 -0
- package/src/types/message.ts +1 -0
- package/src/utils/data-url.test.ts +50 -0
- package/src/utils/data-url.ts +9 -0
- package/src/utils/notify-event-listeners.ts +30 -0
- package/src/tests/OptimisticState-delete-crash.test.ts +0 -208
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Interactables.js","names":["useState","useEffect","useCallback","useRef","useMemo","resource","useAssistantClientRef","ClientOutput","attachTransformScopes","Unstable_InteractablesState","Unstable_InteractableRegistration","Unstable_InteractablePersistedState","Unstable_InteractablePersistenceAdapter","Unstable_InteractablesConfig","toJSONSchema","toPartialJSONSchema","ModelContext","buildInteractableModelContext","PartialJSONSchema","findModelKnownState","interactableToolName","PERSISTENCE_DEBOUNCE_MS","RestorePersistedStateOptions","stash","Map","shouldStash","id","shouldApply","def","ToolCallLikePart","type","toolCallId","toolName","MessageLike","role","content","InternalInteractableRegistration","scope","hasInteractableCreateCall","messages","name","some","message","part","p","useInteractablesResource","persistence","state","setState","definitions","clientRef","stateRef","subscribersRef","Set","partialSchemaCacheRef","streamBaselinesRef","targetId","detachedAppStateRef","detachedThreadStateRef","registrationCountsRef","updateToolUIsRef","count","unsubscribe","loadedStateRef","touchedIdsRef","adapterRef","undefined","debounceTimerRef","ReturnType","setTimeout","syncSeqRef","hasPendingLocalChangeRef","flushResolversRef","Array","dirtyIdsRef","setStateAndRef","updater","prev","next","current","exportState","result","Object","entries","runPersistence","adapter","resolve","seq","dirtyIds","clear","payload","fromEntries","map","isPending","error","save","e","size","schedulePersistence","add","clearTimeout","restorePersistedState","saved","options","entry","set","changed","importState","applyLoadedState","has","loadFromAdapter","load","console","warn","setPersistenceAdapter","getCurrentThreadId","client","threadListItem","source","getState","threads","mainThreadId","flush","Promise","push","flushIfPending","setDefState","existing","provider","getModelContext","defs","subscribe","callback","delete","cb","modelContext","register","threadAccessor","thread","threadMessages","process","env","NODE_ENV","get","releaseUpdateToolUI","updateRender","toolsAccessor","tools","setToolUI","standalone","jsonSchema","stateSchema","threadId","detached","loaded","known","description","initialState","remaining","stateById","_","rest","__","restPersistence","unstable_Interactables","scopes","parent"],"sources":["../../../src/react/client/Interactables.ts"],"sourcesContent":["import { useState, useEffect, useCallback, useRef, useMemo } from \"react\";\nimport { resource } from \"@assistant-ui/tap\";\nimport {\n useAssistantClientRef,\n type ClientOutput,\n attachTransformScopes,\n} from \"@assistant-ui/store\";\nimport type {\n Unstable_InteractablesState,\n Unstable_InteractableRegistration,\n Unstable_InteractablePersistedState,\n Unstable_InteractablePersistenceAdapter,\n Unstable_InteractablesConfig,\n} from \"../types/scopes/interactables\";\nimport { toJSONSchema, toPartialJSONSchema } from \"assistant-stream\";\nimport { ModelContext } from \"../../store\";\nimport {\n buildInteractableModelContext,\n type PartialJSONSchema,\n} from \"./interactable-model-context\";\nimport {\n findModelKnownState,\n interactableToolName,\n} from \"../../model-context/interactable-composer-metadata\";\n\nconst PERSISTENCE_DEBOUNCE_MS = 500;\n\ntype RestorePersistedStateOptions = {\n stash: Map<string, unknown>;\n shouldStash?: (id: string) => boolean;\n shouldApply?: (\n id: string,\n def: Unstable_InteractablesState[\"definitions\"][string],\n ) => boolean;\n};\n\ntype ToolCallLikePart = {\n type?: string;\n toolCallId?: string;\n toolName?: string;\n};\n\ntype MessageLike = {\n role?: string;\n content?: readonly unknown[] | undefined;\n};\n\ntype InternalInteractableRegistration = Unstable_InteractableRegistration & {\n scope?: \"thread\" | undefined;\n};\n\nconst hasInteractableCreateCall = (\n messages: readonly MessageLike[],\n id: string,\n name: string,\n) =>\n messages.some(\n (message) =>\n message.role === \"assistant\" &&\n message.content?.some((part) => {\n if (!part || typeof part !== \"object\") return false;\n const p = part as ToolCallLikePart;\n return (\n p.type === \"tool-call\" && p.toolCallId === id && p.toolName === name\n );\n }),\n );\n\nconst useInteractablesResource = ({\n persistence,\n}: Unstable_InteractablesConfig = {}): ClientOutput<\"unstable_interactables\"> => {\n const [state, setState] = useState<Unstable_InteractablesState>(() => ({\n definitions: {},\n persistence: {},\n }));\n\n const clientRef = useAssistantClientRef();\n\n const stateRef = useRef(state);\n\n const subscribersRef = useRef(new Set<() => void>());\n const partialSchemaCacheRef = useRef(new Map<string, PartialJSONSchema>());\n const streamBaselinesRef = useRef(\n new Map<string, { targetId: string; state: unknown }>(),\n );\n const detachedAppStateRef = useRef(new Map<string, unknown>());\n const detachedThreadStateRef = useRef(\n new Map<string, Map<string, unknown>>(),\n );\n // An instance may be registered from several anchors (its creating tool\n // call plus update_* calls); the definition lives until the last one leaves.\n const registrationCountsRef = useRef(new Map<string, number>());\n // One update-tool UI per interactable name, alive while any registrant\n // that supplied an updateRender is mounted.\n const updateToolUIsRef = useRef(\n new Map<string, { count: number; unsubscribe: () => void }>(),\n );\n // App-scoped state restored via adapter.load(), consumed as components register.\n const loadedStateRef = useRef(new Map<string, unknown>());\n // Ids edited locally this session — a local edit always wins over a slow load.\n const touchedIdsRef = useRef(new Set<string>());\n\n const adapterRef = useRef<\n Unstable_InteractablePersistenceAdapter | undefined\n >(undefined);\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n const syncSeqRef = useRef(0);\n const hasPendingLocalChangeRef = useRef(false);\n const flushResolversRef = useRef<Array<() => void>>([]);\n const dirtyIdsRef = useRef(new Set<string>());\n\n const setStateAndRef = useCallback(\n (\n updater: (\n prev: Unstable_InteractablesState,\n ) => Unstable_InteractablesState,\n ) => {\n const next = updater(stateRef.current);\n stateRef.current = next;\n setState(next);\n },\n [],\n );\n\n const exportState = useCallback((): Unstable_InteractablePersistedState => {\n const result: Unstable_InteractablePersistedState = {};\n for (const [id, def] of Object.entries(stateRef.current.definitions)) {\n if (def.scope === \"thread\") continue; // thread items persist via snapshot, not the adapter\n result[id] = { name: def.name, state: def.state };\n }\n return result;\n }, []);\n\n const runPersistence = useCallback(async () => {\n const adapter = adapterRef.current;\n if (!adapter) {\n for (const resolve of flushResolversRef.current) resolve();\n flushResolversRef.current = [];\n return;\n }\n\n const seq = ++syncSeqRef.current;\n const dirtyIds = new Set(dirtyIdsRef.current);\n dirtyIdsRef.current.clear();\n hasPendingLocalChangeRef.current = true;\n\n // Snapshot before any await so unregistered definitions are still included.\n const payload = exportState();\n\n setStateAndRef((prev) => ({\n ...prev,\n persistence: {\n ...prev.persistence,\n ...Object.fromEntries(\n [...dirtyIds].map((id) => [\n id,\n { isPending: true, error: undefined },\n ]),\n ),\n },\n }));\n\n try {\n await adapter.save(payload);\n if (syncSeqRef.current === seq) {\n hasPendingLocalChangeRef.current = false;\n setStateAndRef((prev) => {\n const persistence = { ...prev.persistence };\n for (const id of dirtyIds) delete persistence[id];\n return { ...prev, persistence };\n });\n }\n } catch (e) {\n if (syncSeqRef.current === seq) {\n hasPendingLocalChangeRef.current = false;\n setStateAndRef((prev) => ({\n ...prev,\n persistence: {\n ...prev.persistence,\n ...Object.fromEntries(\n [...dirtyIds].map((id) => [id, { isPending: false, error: e }]),\n ),\n },\n }));\n }\n } finally {\n if (dirtyIdsRef.current.size > 0 && adapterRef.current) {\n runPersistence();\n } else {\n for (const resolve of flushResolversRef.current) resolve();\n flushResolversRef.current = [];\n }\n }\n }, [exportState, setStateAndRef]);\n\n const schedulePersistence = useCallback(\n (id: string) => {\n if (!adapterRef.current) return;\n dirtyIdsRef.current.add(id);\n if (debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n }\n debounceTimerRef.current = setTimeout(() => {\n debounceTimerRef.current = undefined;\n if (!hasPendingLocalChangeRef.current) {\n runPersistence();\n } else {\n debounceTimerRef.current = setTimeout(() => {\n debounceTimerRef.current = undefined;\n runPersistence();\n }, PERSISTENCE_DEBOUNCE_MS);\n }\n }, PERSISTENCE_DEBOUNCE_MS);\n },\n [runPersistence],\n );\n\n const restorePersistedState = useCallback(\n (\n saved: Unstable_InteractablePersistedState,\n options: RestorePersistedStateOptions,\n ) => {\n const shouldStash = options.shouldStash ?? (() => true);\n const shouldApply = options.shouldApply ?? (() => true);\n\n for (const [id, entry] of Object.entries(saved)) {\n if (shouldStash(id)) options.stash.set(id, entry.state);\n }\n setStateAndRef((prev) => {\n let changed = false;\n const definitions = { ...prev.definitions };\n for (const [id, entry] of Object.entries(saved)) {\n const def = definitions[id];\n if (!def || !shouldApply(id, def)) continue;\n definitions[id] = { ...def, state: entry.state };\n changed = true;\n }\n if (!changed) return prev;\n return { ...prev, definitions };\n });\n },\n [setStateAndRef],\n );\n\n const importState = useCallback(\n (saved: Unstable_InteractablePersistedState) => {\n restorePersistedState(saved, { stash: detachedAppStateRef.current });\n },\n [restorePersistedState],\n );\n\n // Applies adapter.load() output: a local edit made while the load was in\n // flight wins, and thread-scoped items never restore from the adapter.\n const applyLoadedState = useCallback(\n (saved: Unstable_InteractablePersistedState) => {\n restorePersistedState(saved, {\n stash: loadedStateRef.current,\n shouldStash: (id) => !touchedIdsRef.current.has(id),\n shouldApply: (id, def) =>\n !touchedIdsRef.current.has(id) && def.scope !== \"thread\",\n });\n },\n [restorePersistedState],\n );\n\n const loadFromAdapter = useCallback(\n async (adapter: Unstable_InteractablePersistenceAdapter) => {\n if (!adapter.load) return;\n try {\n const saved = await adapter.load();\n if (!saved || adapterRef.current !== adapter) return;\n applyLoadedState(saved);\n } catch (e) {\n console.warn(\"[Interactables] Persistence load failed.\", e);\n }\n },\n [applyLoadedState],\n );\n\n const setPersistenceAdapter = useCallback(\n (adapter: Unstable_InteractablePersistenceAdapter | undefined) => {\n adapterRef.current = adapter;\n if (adapter) void loadFromAdapter(adapter);\n },\n [loadFromAdapter],\n );\n\n const getCurrentThreadId = useCallback((): string | undefined => {\n const client = clientRef.current;\n if (!client) return undefined;\n\n const threadListItem = client.threadListItem;\n if (threadListItem.source != null) {\n return threadListItem().getState().id;\n }\n\n const threads = client.threads;\n if (threads.source != null) {\n return threads().getState().mainThreadId;\n }\n\n return undefined;\n }, [clientRef]);\n\n useEffect(() => {\n if (!persistence) return;\n setPersistenceAdapter(persistence);\n return () => {\n if (adapterRef.current === persistence) {\n adapterRef.current = undefined;\n }\n };\n }, [persistence, setPersistenceAdapter]);\n\n const flush = useCallback(async () => {\n if (debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n if (!adapterRef.current) return;\n if (!hasPendingLocalChangeRef.current && dirtyIdsRef.current.size === 0)\n return;\n const p = new Promise<void>((resolve) => {\n flushResolversRef.current.push(resolve);\n });\n if (!hasPendingLocalChangeRef.current) {\n runPersistence();\n }\n return p;\n }, [runPersistence]);\n\n const flushIfPending = useCallback(() => {\n if (adapterRef.current && debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n runPersistence();\n }\n }, [runPersistence]);\n\n const setDefState = useCallback(\n (id: string, updater: (prev: unknown) => unknown) => {\n touchedIdsRef.current.add(id);\n setStateAndRef((prev) => {\n const existing = prev.definitions[id];\n if (!existing) return prev;\n return {\n ...prev,\n definitions: {\n ...prev.definitions,\n [id]: { ...existing, state: updater(existing.state) },\n },\n };\n });\n if (stateRef.current.definitions[id]?.scope !== \"thread\") {\n schedulePersistence(id);\n }\n },\n [schedulePersistence, setStateAndRef],\n );\n\n const provider = useMemo(\n () => ({\n getModelContext: () => {\n const defs = stateRef.current.definitions;\n return (\n buildInteractableModelContext(\n defs,\n partialSchemaCacheRef.current,\n setDefState,\n streamBaselinesRef.current,\n ) ?? {}\n );\n },\n subscribe: (callback: () => void) => {\n subscribersRef.current.add(callback);\n return () => {\n subscribersRef.current.delete(callback);\n };\n },\n }),\n [setDefState],\n );\n\n useEffect(() => {\n for (const cb of subscribersRef.current) cb();\n }, [state]);\n\n useEffect(() => {\n return clientRef.current!.modelContext().register(provider);\n }, [clientRef, provider]);\n\n const register = useCallback(\n (def: InternalInteractableRegistration) => {\n const threadAccessor = clientRef.current?.thread;\n const threadMessages =\n threadAccessor && threadAccessor.source != null\n ? (threadAccessor().getState().messages ?? [])\n : [];\n const scope =\n def.scope ??\n (hasInteractableCreateCall(threadMessages, def.id, def.name)\n ? \"thread\"\n : \"app\");\n\n if (\n process.env.NODE_ENV !== \"production\" &&\n stateRef.current.definitions[def.id] &&\n scope !== \"thread\"\n ) {\n console.warn(\n `[Interactables] \"${def.name}\" (${def.id}) is already registered. ` +\n `Register an app-scoped interactable once (unstable_useInteractable) and ` +\n `read it from other components with unstable_useInteractableState.`,\n );\n }\n\n registrationCountsRef.current.set(\n def.id,\n (registrationCountsRef.current.get(def.id) ?? 0) + 1,\n );\n\n let releaseUpdateToolUI: (() => void) | undefined;\n if (def.updateRender) {\n const toolsAccessor = clientRef.current?.tools;\n if (toolsAccessor && toolsAccessor.source != null) {\n const toolName = interactableToolName(def.name);\n const existing = updateToolUIsRef.current.get(def.name);\n if (existing) {\n existing.count++;\n } else {\n updateToolUIsRef.current.set(def.name, {\n count: 1,\n unsubscribe: toolsAccessor().setToolUI(\n toolName,\n def.updateRender,\n { standalone: true },\n ),\n });\n }\n releaseUpdateToolUI = () => {\n const entry = updateToolUIsRef.current.get(def.name);\n if (!entry) return;\n if (--entry.count === 0) {\n updateToolUIsRef.current.delete(def.name);\n entry.unsubscribe();\n }\n };\n } else if (process.env.NODE_ENV !== \"production\") {\n console.warn(\n `[Interactables] \"${def.name}\" supplied an updateRender, but no ` +\n `tools scope is available to install it into.`,\n );\n }\n }\n\n // The same id re-registers once per anchor (its create call + each update_*).\n if (!partialSchemaCacheRef.current.has(def.id)) {\n try {\n const jsonSchema = toJSONSchema(def.stateSchema);\n partialSchemaCacheRef.current.set(\n def.id,\n toPartialJSONSchema(jsonSchema),\n );\n } catch (e) {\n console.warn(\n `[Interactables] Failed to create partial schema for \"${def.name}\". The update tool will accept arbitrary fields without validation.`,\n e,\n );\n }\n }\n\n const threadId = scope === \"thread\" ? getCurrentThreadId() : undefined;\n const detached =\n scope === \"thread\"\n ? threadId\n ? detachedThreadStateRef.current.get(threadId)?.get(def.id)\n : undefined\n : detachedAppStateRef.current.get(def.id);\n if (scope === \"thread\") {\n if (threadId)\n detachedThreadStateRef.current.get(threadId)?.delete(def.id);\n } else {\n detachedAppStateRef.current.delete(def.id);\n }\n const loaded =\n scope === \"thread\" ? undefined : loadedStateRef.current.get(def.id);\n\n // Tool-created items restore from what the model already knows in this\n // thread (the creating call's args, sent snapshots, and the model's own\n // update_* calls) on a fresh reload; detached (in-session remount) still\n // wins so an unsent edit survives a scroll/virtualization cycle.\n const known =\n scope === \"thread\"\n ? findModelKnownState(threadMessages, def.id, def.name)\n : undefined;\n\n setStateAndRef((prev) => ({\n ...prev,\n definitions: {\n ...prev.definitions,\n [def.id]: {\n id: def.id,\n name: def.name,\n description: def.description,\n stateSchema: def.stateSchema,\n initialState: def.initialState,\n scope,\n state:\n prev.definitions[def.id]?.state ??\n detached ??\n known?.state ??\n loaded ??\n def.initialState,\n },\n },\n }));\n\n return () => {\n releaseUpdateToolUI?.();\n\n const remaining = (registrationCountsRef.current.get(def.id) ?? 1) - 1;\n if (remaining > 0) {\n registrationCountsRef.current.set(def.id, remaining);\n return;\n }\n registrationCountsRef.current.delete(def.id);\n\n flushIfPending();\n setStateAndRef((prev) => {\n const existing = prev.definitions[def.id];\n if (existing) {\n if (existing.scope === \"thread\") {\n const threadId = getCurrentThreadId();\n if (threadId) {\n let stateById = detachedThreadStateRef.current.get(threadId);\n if (!stateById) {\n stateById = new Map();\n detachedThreadStateRef.current.set(threadId, stateById);\n }\n stateById.set(def.id, existing.state);\n }\n } else {\n detachedAppStateRef.current.set(def.id, existing.state);\n }\n }\n partialSchemaCacheRef.current.delete(def.id);\n const { [def.id]: _, ...rest } = prev.definitions;\n const { [def.id]: __, ...restPersistence } = prev.persistence;\n return { ...prev, definitions: rest, persistence: restPersistence };\n });\n };\n },\n [flushIfPending, clientRef, getCurrentThreadId, setStateAndRef],\n );\n\n return {\n getState: () => stateRef.current,\n register,\n setState: setDefState,\n exportState,\n importState,\n setPersistenceAdapter,\n flush,\n };\n};\n\n/**\n * Registers the unstable interactables store scope.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_Interactables = resource(useInteractablesResource);\n\nattachTransformScopes(useInteractablesResource, (scopes, parent) => {\n if (!scopes.modelContext && parent.modelContext.source === null) {\n scopes.modelContext = ModelContext();\n }\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Interactables.js","names":["useState","useEffect","useCallback","useRef","useMemo","resource","useAssistantClientRef","ClientOutput","attachTransformScopes","Unstable_InteractablesState","Unstable_InteractableRegistration","Unstable_InteractablePersistedState","Unstable_InteractablePersistenceAdapter","Unstable_InteractablesConfig","toJSONSchema","toPartialJSONSchema","ModelContext","buildInteractableModelContext","PartialJSONSchema","findModelKnownState","interactableToolName","PERSISTENCE_DEBOUNCE_MS","RestorePersistedStateOptions","stash","Map","shouldStash","id","shouldApply","def","ToolCallLikePart","type","toolCallId","toolName","MessageLike","role","content","InternalInteractableRegistration","scope","hasInteractableCreateCall","messages","name","some","message","part","p","useInteractablesResource","persistence","state","setState","definitions","clientRef","stateRef","subscribersRef","Set","partialSchemaCacheRef","streamBaselinesRef","targetId","detachedAppStateRef","detachedThreadStateRef","registrationCountsRef","updateToolUIsRef","count","unsubscribe","loadedStateRef","touchedIdsRef","adapterRef","undefined","debounceTimerRef","ReturnType","setTimeout","syncSeqRef","hasPendingLocalChangeRef","flushResolversRef","Array","dirtyIdsRef","setStateAndRef","updater","prev","next","current","exportState","result","Object","entries","runPersistence","adapter","resolve","seq","dirtyIds","clear","payload","fromEntries","map","isPending","error","save","e","size","schedulePersistence","add","clearTimeout","restorePersistedState","saved","options","entry","set","changed","importState","applyLoadedState","has","loadFromAdapter","load","console","warn","setPersistenceAdapter","getCurrentThreadId","client","threadListItem","source","getState","threads","mainThreadId","flush","Promise","push","flushIfPending","setDefState","existing","provider","getModelContext","defs","subscribe","callback","delete","cb","modelContext","register","threadAccessor","thread","threadMessages","process","env","NODE_ENV","get","releaseUpdateToolUI","updateRender","toolsAccessor","tools","setToolUI","standalone","jsonSchema","stateSchema","threadId","detached","loaded","known","description","initialState","remaining","stateById","_","rest","__","restPersistence","unstable_Interactables","scopes","parent"],"sources":["../../../src/react/client/Interactables.ts"],"sourcesContent":["import { useState, useEffect, useCallback, useRef, useMemo } from \"react\";\nimport { resource } from \"@assistant-ui/tap\";\nimport {\n useAssistantClientRef,\n type ClientOutput,\n attachTransformScopes,\n} from \"@assistant-ui/store\";\nimport type {\n Unstable_InteractablesState,\n Unstable_InteractableRegistration,\n Unstable_InteractablePersistedState,\n Unstable_InteractablePersistenceAdapter,\n Unstable_InteractablesConfig,\n} from \"../types/scopes/interactables\";\nimport { toJSONSchema, toPartialJSONSchema } from \"assistant-stream\";\nimport { ModelContext } from \"../../store\";\nimport {\n buildInteractableModelContext,\n type PartialJSONSchema,\n} from \"./interactable-model-context\";\nimport {\n findModelKnownState,\n interactableToolName,\n} from \"../../model-context/interactable-composer-metadata\";\n\nconst PERSISTENCE_DEBOUNCE_MS = 500;\n\ntype RestorePersistedStateOptions = {\n stash: Map<string, unknown>;\n shouldStash?: (id: string) => boolean;\n shouldApply?: (\n id: string,\n def: Unstable_InteractablesState[\"definitions\"][string],\n ) => boolean;\n};\n\ntype ToolCallLikePart = {\n type?: string;\n toolCallId?: string;\n toolName?: string;\n};\n\ntype MessageLike = {\n role?: string;\n content?: readonly unknown[] | undefined;\n};\n\ntype InternalInteractableRegistration = Unstable_InteractableRegistration & {\n scope?: \"thread\" | undefined;\n};\n\nconst hasInteractableCreateCall = (\n messages: readonly MessageLike[],\n id: string,\n name: string,\n) =>\n messages.some(\n (message) =>\n message.role === \"assistant\" &&\n message.content?.some((part) => {\n if (!part || typeof part !== \"object\") return false;\n const p = part as ToolCallLikePart;\n return (\n p.type === \"tool-call\" && p.toolCallId === id && p.toolName === name\n );\n }),\n );\n\nconst useInteractablesResource = ({\n persistence,\n}: Unstable_InteractablesConfig = {}): ClientOutput<\"unstable_interactables\"> => {\n const [state, setState] = useState<Unstable_InteractablesState>(() => ({\n definitions: {},\n persistence: {},\n }));\n\n const clientRef = useAssistantClientRef();\n\n const stateRef = useRef(state);\n\n const subscribersRef = useRef(new Set<() => void>());\n const partialSchemaCacheRef = useRef(new Map<string, PartialJSONSchema>());\n const streamBaselinesRef = useRef(\n new Map<string, { targetId: string; state: unknown }>(),\n );\n const detachedAppStateRef = useRef(new Map<string, unknown>());\n const detachedThreadStateRef = useRef(\n new Map<string, Map<string, unknown>>(),\n );\n // An instance may be registered from several anchors (its creating tool\n // call plus update_* calls); the definition lives until the last one leaves.\n const registrationCountsRef = useRef(new Map<string, number>());\n // One update-tool UI per interactable name, alive while any registrant\n // that supplied an updateRender is mounted.\n const updateToolUIsRef = useRef(\n new Map<string, { count: number; unsubscribe: () => void }>(),\n );\n // App-scoped state restored via adapter.load(), consumed as components register.\n const loadedStateRef = useRef(new Map<string, unknown>());\n // Ids edited locally this session — a local edit always wins over a slow load.\n const touchedIdsRef = useRef(new Set<string>());\n\n const adapterRef = useRef<\n Unstable_InteractablePersistenceAdapter | undefined\n >(undefined);\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n const syncSeqRef = useRef(0);\n const hasPendingLocalChangeRef = useRef(false);\n const flushResolversRef = useRef<Array<() => void>>([]);\n const dirtyIdsRef = useRef(new Set<string>());\n\n const setStateAndRef = useCallback(\n (\n updater: (\n prev: Unstable_InteractablesState,\n ) => Unstable_InteractablesState,\n ) => {\n const next = updater(stateRef.current);\n stateRef.current = next;\n setState(next);\n },\n [],\n );\n\n const exportState = useCallback((): Unstable_InteractablePersistedState => {\n const result: Unstable_InteractablePersistedState = {};\n for (const [id, def] of Object.entries(stateRef.current.definitions)) {\n if (def.scope === \"thread\") continue; // thread items persist via snapshot, not the adapter\n result[id] = { name: def.name, state: def.state };\n }\n return result;\n }, []);\n\n const runPersistence = useCallback(async () => {\n const adapter = adapterRef.current;\n if (!adapter) {\n for (const resolve of flushResolversRef.current) resolve();\n flushResolversRef.current = [];\n return;\n }\n\n const seq = ++syncSeqRef.current;\n const dirtyIds = new Set(dirtyIdsRef.current);\n dirtyIdsRef.current.clear();\n hasPendingLocalChangeRef.current = true;\n\n // Snapshot before any await so unregistered definitions are still included.\n const payload = exportState();\n\n setStateAndRef((prev) => ({\n ...prev,\n persistence: {\n ...prev.persistence,\n ...Object.fromEntries(\n [...dirtyIds].map((id) => [\n id,\n { isPending: true, error: undefined },\n ]),\n ),\n },\n }));\n\n try {\n await adapter.save(payload);\n if (syncSeqRef.current === seq) {\n hasPendingLocalChangeRef.current = false;\n setStateAndRef((prev) => {\n const persistence = { ...prev.persistence };\n for (const id of dirtyIds) delete persistence[id];\n return { ...prev, persistence };\n });\n }\n } catch (e) {\n if (syncSeqRef.current === seq) {\n hasPendingLocalChangeRef.current = false;\n setStateAndRef((prev) => ({\n ...prev,\n persistence: {\n ...prev.persistence,\n ...Object.fromEntries(\n [...dirtyIds].map((id) => [id, { isPending: false, error: e }]),\n ),\n },\n }));\n }\n } finally {\n if (dirtyIdsRef.current.size > 0 && adapterRef.current) {\n runPersistence();\n } else {\n for (const resolve of flushResolversRef.current) resolve();\n flushResolversRef.current = [];\n }\n }\n }, [exportState, setStateAndRef]);\n\n const schedulePersistence = useCallback(\n (id: string) => {\n if (!adapterRef.current) return;\n dirtyIdsRef.current.add(id);\n if (debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n }\n debounceTimerRef.current = setTimeout(() => {\n debounceTimerRef.current = undefined;\n if (!hasPendingLocalChangeRef.current) {\n runPersistence();\n } else {\n debounceTimerRef.current = setTimeout(() => {\n debounceTimerRef.current = undefined;\n runPersistence();\n }, PERSISTENCE_DEBOUNCE_MS);\n }\n }, PERSISTENCE_DEBOUNCE_MS);\n },\n [runPersistence],\n );\n\n const restorePersistedState = useCallback(\n (\n saved: Unstable_InteractablePersistedState,\n options: RestorePersistedStateOptions,\n ) => {\n const shouldStash = options.shouldStash ?? (() => true);\n const shouldApply = options.shouldApply ?? (() => true);\n\n for (const [id, entry] of Object.entries(saved)) {\n if (shouldStash(id)) options.stash.set(id, entry.state);\n }\n setStateAndRef((prev) => {\n let changed = false;\n const definitions = { ...prev.definitions };\n for (const [id, entry] of Object.entries(saved)) {\n const def = definitions[id];\n if (!def || !shouldApply(id, def)) continue;\n definitions[id] = { ...def, state: entry.state };\n changed = true;\n }\n if (!changed) return prev;\n return { ...prev, definitions };\n });\n },\n [setStateAndRef],\n );\n\n const importState = useCallback(\n (saved: Unstable_InteractablePersistedState) => {\n restorePersistedState(saved, { stash: detachedAppStateRef.current });\n },\n [restorePersistedState],\n );\n\n // Applies adapter.load() output: a local edit made while the load was in\n // flight wins, and thread-scoped items never restore from the adapter.\n const applyLoadedState = useCallback(\n (saved: Unstable_InteractablePersistedState) => {\n restorePersistedState(saved, {\n stash: loadedStateRef.current,\n shouldStash: (id) => !touchedIdsRef.current.has(id),\n shouldApply: (id, def) =>\n !touchedIdsRef.current.has(id) && def.scope !== \"thread\",\n });\n },\n [restorePersistedState],\n );\n\n const loadFromAdapter = useCallback(\n async (adapter: Unstable_InteractablePersistenceAdapter) => {\n if (!adapter.load) return;\n try {\n const saved = await adapter.load();\n if (!saved || adapterRef.current !== adapter) return;\n applyLoadedState(saved);\n } catch (e) {\n console.warn(\"[Interactables] Persistence load failed.\", e);\n }\n },\n [applyLoadedState],\n );\n\n const setPersistenceAdapter = useCallback(\n (adapter: Unstable_InteractablePersistenceAdapter | undefined) => {\n adapterRef.current = adapter;\n if (adapter) void loadFromAdapter(adapter);\n },\n [loadFromAdapter],\n );\n\n const getCurrentThreadId = useCallback((): string | undefined => {\n const client = clientRef.current;\n if (!client) return undefined;\n\n const threadListItem = client.threadListItem;\n if (threadListItem.source != null) {\n return threadListItem().getState().id;\n }\n\n const threads = client.threads;\n if (threads.source != null) {\n return threads().getState().mainThreadId;\n }\n\n return undefined;\n }, [clientRef]);\n\n useEffect(() => {\n if (!persistence) return;\n setPersistenceAdapter(persistence);\n return () => {\n if (adapterRef.current === persistence) {\n adapterRef.current = undefined;\n }\n };\n }, [persistence, setPersistenceAdapter]);\n\n const flush = useCallback(async () => {\n if (debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n if (!adapterRef.current) return;\n if (!hasPendingLocalChangeRef.current && dirtyIdsRef.current.size === 0)\n return;\n const p = new Promise<void>((resolve) => {\n flushResolversRef.current.push(resolve);\n });\n if (!hasPendingLocalChangeRef.current) {\n runPersistence();\n }\n return p;\n }, [runPersistence]);\n\n const flushIfPending = useCallback(() => {\n if (adapterRef.current && debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n runPersistence();\n }\n }, [runPersistence]);\n\n const setDefState = useCallback(\n (id: string, updater: (prev: unknown) => unknown) => {\n touchedIdsRef.current.add(id);\n setStateAndRef((prev) => {\n const existing = prev.definitions[id];\n if (!existing) return prev;\n return {\n ...prev,\n definitions: {\n ...prev.definitions,\n [id]: { ...existing, state: updater(existing.state) },\n },\n };\n });\n if (stateRef.current.definitions[id]?.scope !== \"thread\") {\n schedulePersistence(id);\n }\n },\n [schedulePersistence, setStateAndRef],\n );\n\n const provider = useMemo(\n () => ({\n getModelContext: () => {\n const defs = stateRef.current.definitions;\n return (\n buildInteractableModelContext(\n defs,\n partialSchemaCacheRef.current,\n setDefState,\n streamBaselinesRef.current,\n ) ?? {}\n );\n },\n subscribe: (callback: () => void) => {\n subscribersRef.current.add(callback);\n return () => {\n subscribersRef.current.delete(callback);\n };\n },\n }),\n [setDefState],\n );\n\n useEffect(() => {\n for (const cb of subscribersRef.current) cb();\n }, [state]);\n\n useEffect(() => {\n return clientRef.current!.modelContext().register(provider);\n }, [clientRef, provider]);\n\n const register = useCallback(\n (def: InternalInteractableRegistration) => {\n const threadAccessor = clientRef.current?.thread;\n const threadMessages =\n threadAccessor && threadAccessor.source != null\n ? (threadAccessor().getState().messages ?? [])\n : [];\n const scope =\n def.scope ??\n (hasInteractableCreateCall(threadMessages, def.id, def.name)\n ? \"thread\"\n : \"app\");\n\n if (\n process.env.NODE_ENV !== \"production\" &&\n stateRef.current.definitions[def.id] &&\n scope !== \"thread\"\n ) {\n console.warn(\n `[Interactables] \"${def.name}\" (${def.id}) is already registered. ` +\n `Register an app-scoped interactable once (unstable_useInteractable) and ` +\n `read it from other components with unstable_useInteractableState.`,\n );\n }\n\n registrationCountsRef.current.set(\n def.id,\n (registrationCountsRef.current.get(def.id) ?? 0) + 1,\n );\n\n let releaseUpdateToolUI: (() => void) | undefined;\n if (def.updateRender) {\n const toolsAccessor = clientRef.current?.tools;\n if (toolsAccessor && toolsAccessor.source != null) {\n const toolName = interactableToolName(def.name);\n const existing = updateToolUIsRef.current.get(def.name);\n if (existing) {\n existing.count++;\n } else {\n updateToolUIsRef.current.set(def.name, {\n count: 1,\n unsubscribe: toolsAccessor().setToolUI(\n toolName,\n def.updateRender,\n { standalone: true },\n ),\n });\n }\n releaseUpdateToolUI = () => {\n const entry = updateToolUIsRef.current.get(def.name);\n if (!entry) return;\n if (--entry.count === 0) {\n updateToolUIsRef.current.delete(def.name);\n entry.unsubscribe();\n }\n };\n } else if (process.env.NODE_ENV !== \"production\") {\n console.warn(\n `[Interactables] \"${def.name}\" supplied an updateRender, but no ` +\n `tools scope is available to install it into.`,\n );\n }\n }\n\n // The same id re-registers once per anchor (its create call + each update_*).\n if (!partialSchemaCacheRef.current.has(def.id)) {\n try {\n const jsonSchema = toJSONSchema(def.stateSchema);\n partialSchemaCacheRef.current.set(\n def.id,\n toPartialJSONSchema(jsonSchema),\n );\n } catch (e) {\n console.warn(\n `[Interactables] Failed to create partial schema for \"${def.name}\". The update tool will accept arbitrary fields without validation.`,\n e,\n );\n }\n }\n\n const threadId = scope === \"thread\" ? getCurrentThreadId() : undefined;\n const detached =\n scope === \"thread\"\n ? threadId\n ? detachedThreadStateRef.current.get(threadId)?.get(def.id)\n : undefined\n : detachedAppStateRef.current.get(def.id);\n if (scope === \"thread\") {\n if (threadId)\n detachedThreadStateRef.current.get(threadId)?.delete(def.id);\n } else {\n detachedAppStateRef.current.delete(def.id);\n }\n const loaded =\n scope === \"thread\" ? undefined : loadedStateRef.current.get(def.id);\n\n // Tool-created items restore from what the model already knows in this\n // thread (the creating call's args, sent snapshots, and the model's own\n // update_* calls) on a fresh reload; detached (in-session remount) still\n // wins so an unsent edit survives a scroll/virtualization cycle.\n const known =\n scope === \"thread\"\n ? findModelKnownState(threadMessages, def.id, def.name)\n : undefined;\n\n setStateAndRef((prev) => ({\n ...prev,\n definitions: {\n ...prev.definitions,\n [def.id]: {\n id: def.id,\n name: def.name,\n description: def.description,\n stateSchema: def.stateSchema,\n initialState: def.initialState,\n scope,\n state:\n prev.definitions[def.id]?.state ??\n detached ??\n known?.state ??\n loaded ??\n def.initialState,\n },\n },\n }));\n\n return () => {\n releaseUpdateToolUI?.();\n\n const remaining = (registrationCountsRef.current.get(def.id) ?? 1) - 1;\n if (remaining > 0) {\n registrationCountsRef.current.set(def.id, remaining);\n return;\n }\n registrationCountsRef.current.delete(def.id);\n\n flushIfPending();\n setStateAndRef((prev) => {\n const existing = prev.definitions[def.id];\n if (existing) {\n if (existing.scope === \"thread\") {\n const threadId = getCurrentThreadId();\n if (threadId) {\n let stateById = detachedThreadStateRef.current.get(threadId);\n if (!stateById) {\n stateById = new Map();\n detachedThreadStateRef.current.set(threadId, stateById);\n }\n stateById.set(def.id, existing.state);\n }\n } else {\n detachedAppStateRef.current.set(def.id, existing.state);\n }\n }\n partialSchemaCacheRef.current.delete(def.id);\n const { [def.id]: _, ...rest } = prev.definitions;\n const { [def.id]: __, ...restPersistence } = prev.persistence;\n return { ...prev, definitions: rest, persistence: restPersistence };\n });\n };\n },\n [flushIfPending, clientRef, getCurrentThreadId, setStateAndRef],\n );\n\n return {\n getState: () => stateRef.current,\n register,\n setState: setDefState,\n exportState,\n importState,\n setPersistenceAdapter,\n flush,\n };\n};\n\n/**\n * Registers the unstable interactables store scope.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_Interactables = resource(useInteractablesResource);\n\nattachTransformScopes(useInteractablesResource, (scopes, parent) => {\n if (!scopes.modelContext && parent.modelContext.source === null) {\n scopes.modelContext = ModelContext();\n }\n});\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tools.d.ts","names":[],"sources":["../../../src/react/client/Tools.ts"],"mappings":";;;;;cA6Ja,mCAAK,SAAA;;
|
|
1
|
+
{"version":3,"file":"Tools.d.ts","names":[],"sources":["../../../src/react/client/Tools.ts"],"mappings":";;;;;cA6Ja,mCAAK,SAAA;;EAxHN,UAAA;;EAED,SAAA,gBAAgB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactable-model-context.d.ts","names":[],"sources":["../../../src/react/client/interactable-model-context.ts"],"mappings":";;;KAWY,oBAAoB,kBAAkB;iBA2HlC,8BACd,aAAa,eAAe,kCAC5B,oBAAoB,YAAY,oBAChC,cAAc,YAAY,UAAU,oCACpC,kBAAe
|
|
1
|
+
{"version":3,"file":"interactable-model-context.d.ts","names":[],"sources":["../../../src/react/client/interactable-model-context.ts"],"mappings":";;;KAWY,oBAAoB,kBAAkB;iBA2HlC,8BACd,aAAa,eAAe,kCAC5B,oBAAoB,YAAY,oBAChC,cAAc,YAAY,UAAU,oCACpC,kBAAe;EAA+B;EAAe;;EAGzD,OAAO,eAAe;EACtB,4BAA4B"}
|
|
@@ -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":";;;;;AAaA,MAAMU,cAAc;CAClBC,MAAM;CACNE,aACE;AACJ;AAEA,MAAMC,iBAAiBC,WAAoC;CACzD,MAAME,aAAaF,OAAOE;CAC1B,OAAOV,SAASU,UAAU,KAAKA,WAAWC,OAAOC,KAAAA;AACnD;AAEA,MAAMC,sBAAsBL,YAAqC;CAC/D,GAAGA;CACHM,UAAU,CAAC,IAAI;AACjB;AAIA,MAAMC,iBAAiBP,WAAoC;CACzD,MAAM,EAAEG,IAAIK,UAAU,GAAGN,eAAeV,SAASQ,OAAOE,UAAU,IAC9DF,OAAOE,aACP,CAAC;CACL,MAAMI,WAAWG,MAAMC,QAAQV,OAAOM,QAAQ,IAC1CN,OAAOM,SAASK,QAAQC,QAAQA,QAAQ,IAAI,IAC5CZ,OAAOM;CACX,OAAO;EAAE,GAAGN;EAAQE;EAAYI;CAAS;AAC3C;AAEA,MAAMO,uBAAuBb,QAAiBc,UAAkB;CAC9D,IAAI,CAACtB,SAASQ,MAAM,KAAKA,OAAOJ,SAAS,SAAS,OAAOI;CACzD,MAAMe,aAAaf,OAAOgB;CAC1B,IAAIP,MAAMC,QAAQK,UAAU,KAAK,CAACvB,SAASuB,UAAU,GAAG,OAAOf;CAE/D,MAAMiB,UAAUlB,cAAcgB,UAAU;CACxC,MAAMb,aAAsC;EAC1CgB,KAAK;GACHtB,MAAM;GACNoB,OAAOC,UAAUV,cAAcQ,UAAU,IAAIA;EAC/C;EACAI,QAAQ;GACNvB,MAAM;GACNoB,OAAOC,UAAUtB,cAAcoB;EACjC;EACAK,OAAO,EAAExB,MAAM,UAAU;CAC3B;CAEA,IAAIqB,SACFf,WAAWmB,SAAS;EAClBzB,MAAM;EACNoB,OAAOX,mBAAmBU,UAAU;CACtC;CAGF,OAAO;EACLnB,MAAM;EACNE,aACE,+BAA+BgB,MAAK;EAItCZ;EACAoB,sBAAsB;CACxB;AACF;AAIA,MAAMC,0BACJrB,eACgB;CAChB,MAAMuB,wBAAQ,IAAID,IAAY;CAC9B,KAAK,MAAM,CAACZ,KAAKc,UAAUC,OAAOC,QAAQ1B,UAAU,GAClD,IACEV,SAASkC,KAAK,KACdA,MAAM9B,SAAS,WACfJ,SAASkC,MAAMV,KAAK,KACpBjB,cAAc2B,MAAMV,KAAK,GAEzBS,MAAMP,IAAIN,GAAG;CAGjB,OAAOa;AACT;AAEA,MAAMI,0BAA0B3B,eAC9ByB,OAAOG,YACLH,OAAOC,QAAQ1B,UAAU,CAAC,CAAC6B,KAAK,CAACnB,KAAKc,WAAW,CAC/Cd,KACAC,oBAAoBa,OAAOd,GAAG,CAAC,CAChC,CACH;;;;;;AAOF,SAASoB,eAAeC,SAAwC;CAC9D,IAAI,CAACA,WAAW,OAAOA,YAAY,YAAYA,QAAQrC,SAAS,UAC9D,OAAO;EACLA,MAAM;EACNM,YAAY,EAAEC,IAAIR,YAAY;EAC9BW,UAAU,CAAC,IAAI;EACfgB,sBAAsB;CACxB;CAEF,IAAIY,QAAQC,IAAIC,aAAa,gBAAgBH,QAAQ/B,YAAYC,IAC/DkC,QAAQC,KACN,kNAGF;CAEF,MAAM,EAAEnC,IAAIoC,WAAW,GAAGrC,eAAe+B,QAAQ/B,cAAc,CAAC;CAChE,OAAO;EACL,GAAG+B;EACH/B,YAAY;GAAEC,IAAIR;GAAa,GAAGkC,uBAAuB3B,UAAU;EAAE;EACrEI,UAAU,CAAC,IAAI;CACjB;AACF;AAEA,SAAgBkC,8BACdC,aACAC,oBACAE,aACAG,kCAAkB,IAAIJ,IAAkD,GAM5D;CACZ,MAAMf,UAAUD,OAAOyB,OAAOX,WAAW;CACzC,IAAIb,QAAQyB,WAAW,GAAG,OAAOjD,KAAAA;CAEjC,MAAMkD,yBAAS,IAAIX,IAA+C;CAClE,KAAK,MAAMY,OAAO3B,SAAS;EACzB,MAAM4B,OAAOF,OAAOG,IAAIF,IAAIG,IAAI,KAAK,CAAA;EACrCF,KAAKG,KAAKJ,GAAG;EACbD,OAAOM,IAAIL,IAAIG,MAAMF,IAAI;CAC3B;CAEA,MAAMN,QAAwC,CAAC;CAE/C,KAAK,MAAM,CAACQ,MAAMG,cAAcP,QAAQ;EACtC,MAAMQ,WAAW1E,qBAAqBsE,IAAI;EAC1C,IAAIR,MAAMY,WAAW;GACnB,IAAI5B,QAAQC,IAAIC,aAAa,cAC3BC,QAAQC,KACN,uCAAuCoB,KAAI,gEACNI,SAAQ,uBAC/C;GAEF;EACF;EAEA,MAAMC,QAAQF,UAAU;EACxB,MAAMG,gBAAgBtB,mBAAmBe,IAAIM,MAAM5D,EAAE;EACrD,MAAM8D,gBACJD,iBAAiBxE,SAASwE,cAAc9D,UAAU,IAC9CqB,uBAAuByC,cAAc9D,UAAU,oBAC/C,IAAIsB,IAAY;EAItB,MAAM0C,iBACJ/D,OACgD;GAChD,IAAI,OAAOA,OAAO,UAAU;IAC1B,MAAMoD,MAAMd,YAAYtC;IACxB,OAAOoD,KAAKG,SAASA,OAAOH,MAAMnD,KAAAA;GACpC;GACA,OAAOyD,UAAUR,WAAW,IAAIU,QAAQ3D,KAAAA;EAC1C;EAEA8C,MAAMY,YAAY;GAChBlE,MAAM;GACNE,aACE,+CAA+C4D,KAAI,KAAMK,MAAMjE,YAAW;GAI5EqE,YAAYnC,eAAegC,aAAa;GACxCI,YAAY,OAAOC,QAAQ,EAAEC,iBAAiB;IAC5C,IAAI;KACF,WAAW,MAAMC,eAAeF,OAAOG,KAAKC,aAAa,GAAG;MAC1D,IAAI,CAACF,eAAe,OAAOA,gBAAgB,UAAU;MACrD,MAAMC,OAAOD;MACb,MAAMG,OAAO/C,OAAO+C,KAAKF,IAAI;MAE7B,IADgBE,KAAKE,QAAQ,IACzBD,MAAYD,KAAKrB,SAAS,GAAG;MAEjC,MAAM,EAAElD,IAAI,GAAG8B,YAAYuC;MAC3B,IAAI7C,OAAO+C,KAAKzC,OAAO,CAAC,CAACoB,WAAW,GAAG;MACvC,MAAMwB,SAASX,cAAc/D,EAAE;MAC/B,IAAI,CAAC0E,QAAQ;MAEb,MAAMC,WAAW/B,gBAAgBU,IAAIa,UAAU;MAC/C,MAAMS,gBACJD,UAAU9B,aAAa6B,OAAO1E,KAAK2E,SAAS7B,QAAQ4B,OAAO5B;MAC7D,IAAI,CAAC6B,YAAYA,SAAS9B,aAAa6B,OAAO1E,IAC5C4C,gBAAgBa,IAAIU,YAAY;OAC9BtB,UAAU6B,OAAO1E;OACjB8C,OAAO4B,OAAO5B;MAChB,CAAC;MAGHL,YAAYiC,OAAO1E,KAAK2C,SACtBzD,8BAA8ByD,MAAMb,SAAS,EAAE8C,cAAc,CAAC,CAChE;KACF;IACF,QAAQ,CACN;GAEJ;GACAC,SAAS,OAAOR,MAAe,EAAEF,iBAAiB;IAChD,MAAM,EAAEnE,IAAI,GAAG8B,YAAauC,QAAQ,CAAC;IACrC,MAAMK,SAASX,cAAc/D,EAAE;IAC/B,IAAI,CAAC0E,QAAQ;KACX,MAAMI,WAAWpB,UAAU9B,KAAKmD,MAAMA,EAAE/E,EAAE;KAC1C,OAAO;MACLgF,SAAS;MACTC,OAAO,cAAcC,KAAKC,UAAUnF,EAAE,EAAC,qBAAsBuD,KAAI,gBAAiBuB,SAASM,KAAK,IAAI;KACtG;IACF;IACA,MAAMT,WAAW/B,gBAAgBU,IAAIa,UAAU;IAC/CvB,gBAAgByC,OAAOlB,UAAU;IACjC,MAAMmB,eAAyC,CAAC;IAChD7C,YAAYiC,OAAO1E,KAAK2C,SACtBzD,8BAA8ByD,MAAMb,SAAS;KAC3C8C,eACED,UAAU9B,aAAa6B,OAAO1E,KAAK2E,SAAS7B,QAAQ7C,KAAAA;KACtDsF,YAAY5E,UAAU;MACpB,MAAM6E,SAASpG,WAAW;MAC1B,CAACkG,aAAa3E,WAAW,CAAA,EAAA,CAAI6C,KAAKgC,MAAM;MACxC,OAAOA;KACT;KACA1B;IACF,CAAC,CACH;IAGA,MAAM2B,SAIF;KAAET,SAAS;KAAMhF,IAAI0E,OAAO1E;IAAG;IACnC,IAAIwB,OAAO+C,KAAKe,YAAY,CAAC,CAACpC,SAAS,GACrCuC,OAAOH,eAAeA;IAExB,OAAOG;GACT;EACF;CACF;CASA,OAAO;EAAE1C;EAAOC,2BAA2B,EAAE0C,eAPejE,QAAQG,KACjEwB,SAAS;GACRpD,IAAIoD,IAAIpD;GACRuD,MAAMH,IAAIG;GACVT,OAAOM,IAAIN;EACb,EAE2C4C,EAAc;CAAE;AAC/D"}
|
|
@@ -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().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":"
|
|
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,cAAe,CAAC,CAAAQ,SAAUf,KAAIF,SAAA;IAC/B,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,cAAe,CAAC,CAAAW,YAAalB,IAAIiB,QAAQ;EAAC;EAC9Cf,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,cAAe,CAAC,CAAAa,MAAO;EAAClB,EAAA,KAAAE;EAAAF,EAAA,KAAAiB;CAAA,OAAAA,KAAAjB,EAAA;CAA3D,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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInteractable.js","names":["useEffect","useId","useMemo","useRef","useAui","useAuiState","Unstable_InteractableStateSchema","ToolCallMessagePartComponent","unstable_getInteractableVersions","getInteractableVersions","interactableToolName","unstable_useInteractableState","useInteractableState","useJSONEqual","Unstable_InferInteractableState","TSchema","types","output","TOutput","Unstable_InteractableVersionInfo","state","TState","isLatest","restore","Unstable_InteractableConfig","description","stateSchema","initialState","id","updateRender","useInteractable","name","config","version","setState","updater","prev","isPending","error","flush","Promise","aui","autoId","replace","inPart","part","source","updateToolName","s","undefined","p","type","inferredId","toolName","result","Record","args","success","internalScope","stateSchemaRef","current","initialStateRef","interactables","unstable_interactables","register","scope","Parameters","myToolCallId","toolCallId","registeredState","methods","versionValue","versions","thread","messages","some","v","origin","mine","find","latestToolCallId","findLast","const","unstable_useInteractable"],"sources":["../../../src/react/model-context/useInteractable.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useId, useMemo, useRef } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type { Unstable_InteractableStateSchema } from \"../types/scopes/interactables\";\nimport type { ToolCallMessagePartComponent } from \"../types/MessagePartComponentTypes\";\nimport {\n unstable_getInteractableVersions as getInteractableVersions,\n interactableToolName,\n} from \"../../model-context/interactable-composer-metadata\";\nimport { unstable_useInteractableState as useInteractableState } from \"./useInteractableState\";\nimport { useJSONEqual } from \"../utils/useJSONEqual\";\n\n/**\n * The state type described by an interactable's `stateSchema`. Resolves the\n * output type of a StandardSchemaV1 schema (e.g. Zod); plain JSON Schema\n * falls back to `unknown`.\n */\nexport type Unstable_InferInteractableState<TSchema> = TSchema extends {\n \"~standard\": { types?: { output: infer TOutput } | undefined };\n}\n ? TOutput\n : unknown;\n\n/**\n * One message's version of an interactable, for components rendered inside\n * tool-call parts. Show `state` to display history; call `restore()` to set\n * the live instance back to it.\n */\nexport type Unstable_InteractableVersionInfo<TState> = {\n /** The interactable's state as it was at this message. */\n state: TState;\n /** Whether this message holds the instance's most recent tool-driven version. */\n isLatest: boolean;\n /** Sets the live state back to this version. */\n restore: () => void;\n};\n\n/**\n * Unstable / Experimental — the interactables API is still evolving and may change in any release.\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport type Unstable_InteractableConfig<\n TSchema extends Unstable_InteractableStateSchema,\n> = {\n description: string;\n stateSchema: TSchema;\n initialState: Unstable_InferInteractableState<TSchema>;\n /** Unique instance ID; required to address this instance when multiple interactables share a name. Auto-generated if omitted. */\n id?: string | undefined;\n /**\n * Component installed as the tool UI for this interactable's `update_{name}`\n * tool calls, so a model edit re-renders the interactable at the message\n * that made it instead of only mutating an earlier one. Prefer\n * `unstable_interactableTool`, which wires this up. Pass a stable component reference;\n * changing identity re-registers the tool UI.\n */\n updateRender?: ToolCallMessagePartComponent | undefined;\n};\n\nconst useInteractable = <TSchema extends Unstable_InteractableStateSchema>(\n name: string,\n config: Unstable_InteractableConfig<TSchema>,\n): readonly [\n Unstable_InferInteractableState<TSchema>,\n {\n id: string;\n /**\n * This message's version of the instance, when rendered inside a\n * tool-created interactable message part; `undefined` elsewhere.\n */\n version:\n | Unstable_InteractableVersionInfo<\n Unstable_InferInteractableState<TSchema>\n >\n | undefined;\n setState: (\n updater:\n | Unstable_InferInteractableState<TSchema>\n | ((\n prev: Unstable_InferInteractableState<TSchema>,\n ) => Unstable_InferInteractableState<TSchema>),\n ) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] => {\n const aui = useAui();\n\n const autoId = useId().replace(/[^a-zA-Z0-9]/g, \"\");\n\n // Whether this component renders inside a message part is fixed for its\n // lifetime, so conditioning the selectors on it is safe.\n const inPart = aui.part.source != null;\n const updateToolName = interactableToolName(name);\n const part = useAuiState((s) => {\n if (!inPart) return undefined;\n const p = s.part;\n return p.type === \"tool-call\" ? p : undefined;\n });\n\n // Inside an update_{name} part, the instance id comes from the call itself:\n // the result's resolved id (covers id-less calls), or the id argument.\n let inferredId: string | undefined;\n if (part?.toolName === updateToolName) {\n const result = part.result as Record<string, unknown> | undefined;\n const args = part.args as Record<string, unknown> | undefined;\n if (result?.success !== false) {\n if (typeof result?.id === \"string\") inferredId = result.id;\n else if (typeof args?.id === \"string\") inferredId = args.id;\n }\n }\n\n const id = config.id ?? inferredId ?? autoId;\n const internalScope =\n part?.toolName === name || part?.toolName === updateToolName\n ? \"thread\"\n : undefined;\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 const interactables = useAuiState(() => aui.unstable_interactables());\n\n useEffect(() => {\n return interactables.register({\n id,\n name,\n description: config.description,\n stateSchema: stateSchemaRef.current,\n initialState: initialStateRef.current,\n updateRender: config.updateRender,\n ...(internalScope ? { scope: internalScope } : {}),\n } as Parameters<typeof interactables.register>[0] & {\n scope?: \"thread\" | undefined;\n });\n }, [\n interactables,\n id,\n name,\n config.description,\n internalScope,\n config.updateRender,\n ]);\n\n const myToolCallId = part?.toolCallId;\n\n const [registeredState, methods] =\n useInteractableState<Unstable_InferInteractableState<TSchema>>(id);\n const { setState } = methods;\n\n const versionValue = useAuiState(\n useJSONEqual((s) => {\n if (!internalScope || !myToolCallId) return undefined;\n const versions = getInteractableVersions(s.thread.messages, id, name);\n if (!versions.some((v) => v.origin === \"create\" && v.toolCallId === id)) {\n return undefined;\n }\n const mine = versions.find((v) => v.toolCallId === myToolCallId);\n if (!mine) return undefined;\n const latestToolCallId = versions.findLast(\n (v) => v.toolCallId !== undefined,\n )?.toolCallId;\n return { state: mine.state, isLatest: latestToolCallId === myToolCallId };\n }),\n );\n\n const version = useMemo(\n () =>\n versionValue && {\n state: versionValue.state as Unstable_InferInteractableState<TSchema>,\n isLatest: versionValue.isLatest,\n restore: () =>\n setState(\n versionValue.state as Unstable_InferInteractableState<TSchema>,\n ),\n },\n [versionValue, setState],\n );\n\n const state =\n registeredState === undefined ? config.initialState : registeredState;\n\n return [state, { id, version, ...methods }] as const;\n};\n\n/**\n * Registers an interactable with the AI assistant and returns its live state,\n * like `useState` that the model can also read and update.\n *\n * Call this once per place that shows the interactable. Other components can\n * read and write the same instance by passing its `id` to\n * `unstable_useInteractableState`.\n *\n * For tool-created interactables rendered inside tool-call message parts,\n * `version` carries this message's version of the instance — its state as of\n * that point in the conversation, whether it is the most recent tool-driven\n * version, and a `restore()` back to it. Whether older messages render frozen history or stay\n * live-editable is the component's choice. Inside an `update_{name}` part the\n * instance `id` is inferred from the call, so the same component works at the\n * creating call and at update calls.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_useInteractable: <\n TSchema extends Unstable_InteractableStateSchema,\n>(\n name: string,\n config: Unstable_InteractableConfig<TSchema>,\n) => readonly [\n Unstable_InferInteractableState<TSchema>,\n {\n id: string;\n version:\n | Unstable_InteractableVersionInfo<\n Unstable_InferInteractableState<TSchema>\n >\n | undefined;\n setState: (\n updater:\n | Unstable_InferInteractableState<TSchema>\n | ((\n prev: Unstable_InferInteractableState<TSchema>,\n ) => Unstable_InferInteractableState<TSchema>),\n ) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] = useInteractable;\n"],"mappings":";;;;;;;AA4DA,MAAM8B,mBACJC,MACAC,WAyBG;CACH,MAAMS,MAAMrC,OAAO;CAEnB,MAAMsC,SAASzC,MAAM,CAAC,CAAC0C,QAAQ,iBAAiB,EAAE;CAIlD,MAAMC,SAASH,IAAII,KAAKC,UAAU;CAClC,MAAMC,iBAAiBrC,qBAAqBqB,IAAI;CAChD,MAAMc,OAAOxC,aAAa2C,MAAM;EAC9B,IAAI,CAACJ,QAAQ,OAAOK,KAAAA;EACpB,MAAMC,IAAIF,EAAEH;EACZ,OAAOK,EAAEC,SAAS,cAAcD,IAAID,KAAAA;CACtC,CAAC;CAID,IAAIG;CACJ,IAAIP,MAAMQ,aAAaN,gBAAgB;EACrC,MAAMO,SAAST,KAAKS;EACpB,MAAME,OAAOX,KAAKW;EAClB,IAAIF,QAAQG,YAAY;OAClB,OAAOH,QAAQ1B,OAAO,UAAUwB,aAAaE,OAAO1B;QACnD,IAAI,OAAO4B,MAAM5B,OAAO,UAAUwB,aAAaI,KAAK5B;EAAAA;CAE7D;CAEA,MAAMA,KAAKI,OAAOJ,MAAMwB,cAAcV;CACtC,MAAMgB,gBACJb,MAAMQ,aAAatB,QAAQc,MAAMQ,aAAaN,iBAC1C,WACAE,KAAAA;CAEN,MAAMU,iBAAiBxD,OAAO6B,OAAON,WAAW;CAChDiC,eAAeC,UAAU5B,OAAON;CAChC,MAAMmC,kBAAkB1D,OAAO6B,OAAOL,YAAY;CAClDkC,gBAAgBD,UAAU5B,OAAOL;CAEjC,MAAMmC,gBAAgBzD,kBAAkBoC,IAAIsB,uBAAuB,CAAC;CAEpE/D,gBAAgB;EACd,OAAO8D,cAAcE,SAAS;GAC5BpC;GACAG;GACAN,aAAaO,OAAOP;GACpBC,aAAaiC,eAAeC;GAC5BjC,cAAckC,gBAAgBD;GAC9B/B,cAAcG,OAAOH;GACrB,GAAI6B,gBAAgB,EAAEO,OAAOP,cAAc,IAAI,CAAC;EAClD,CAEC;CACH,GAAG;EACDI;EACAlC;EACAG;EACAC,OAAOP;EACPiC;EACA1B,OAAOH;CAAY,CACpB;CAED,MAAMsC,eAAetB,MAAMuB;CAE3B,MAAM,CAACC,iBAAiBC,WACtB1D,8BAA+DgB,EAAE;CACnE,MAAM,EAAEM,aAAaoC;CAErB,MAAMC,eAAelE,YACnBQ,cAAcmC,QAAM;EAClB,IAAI,CAACU,iBAAiB,CAACS,cAAc,OAAOlB,KAAAA;EAC5C,MAAMuB,WAAW/D,iCAAwBuC,IAAEyB,OAAOC,UAAU9C,IAAIG,IAAI;EACpE,IAAI,CAACyC,SAASG,MAAMC,MAAMA,EAAEC,WAAW,YAAYD,EAAER,eAAexC,EAAE,GACpE;EAEF,MAAMkD,OAAON,SAASO,MAAMH,QAAMA,IAAER,eAAeD,YAAY;EAC/D,IAAI,CAACW,MAAM,OAAO7B,KAAAA;EAClB,MAAM+B,mBAAmBR,SAASS,UAC/BL,QAAMA,IAAER,eAAenB,KAAAA,CAC1B,CAAC,EAAEmB;EACH,OAAO;GAAEhD,OAAO0D,KAAK1D;GAAOE,UAAU0D,qBAAqBb;EAAa;CAC1E,CAAC,CACH;CAEA,MAAMlC,UAAU/B,cAEZqE,gBAAgB;EACdnD,OAAOmD,aAAanD;EACpBE,UAAUiD,aAAajD;EACvBC,eACEW,SACEqC,aAAanD,KACf;CACJ,GACF,CAACmD,cAAcrC,QAAQ,CACzB;CAKA,OAAO,CAFLmC,oBAAoBpB,KAAAA,IAAYjB,OAAOL,eAAe0C,iBAEzC;EAAEzC;EAAIK;EAAS,GAAGqC;CAAQ,CAAC;AAC5C;;;;;;;;;;;;;;;;;;;AAoBA,MAAaa,2BAyBTrD"}
|
|
1
|
+
{"version":3,"file":"useInteractable.js","names":["useEffect","useId","useMemo","useRef","useAui","useAuiState","Unstable_InteractableStateSchema","ToolCallMessagePartComponent","unstable_getInteractableVersions","getInteractableVersions","interactableToolName","unstable_useInteractableState","useInteractableState","useJSONEqual","Unstable_InferInteractableState","TSchema","types","output","TOutput","Unstable_InteractableVersionInfo","state","TState","isLatest","restore","Unstable_InteractableConfig","description","stateSchema","initialState","id","updateRender","useInteractable","name","config","version","setState","updater","prev","isPending","error","flush","Promise","aui","autoId","replace","inPart","part","source","updateToolName","s","undefined","p","type","inferredId","toolName","result","Record","args","success","internalScope","stateSchemaRef","current","initialStateRef","interactables","unstable_interactables","register","scope","Parameters","myToolCallId","toolCallId","registeredState","methods","versionValue","versions","thread","messages","some","v","origin","mine","find","latestToolCallId","findLast","const","unstable_useInteractable"],"sources":["../../../src/react/model-context/useInteractable.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useId, useMemo, useRef } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type { Unstable_InteractableStateSchema } from \"../types/scopes/interactables\";\nimport type { ToolCallMessagePartComponent } from \"../types/MessagePartComponentTypes\";\nimport {\n unstable_getInteractableVersions as getInteractableVersions,\n interactableToolName,\n} from \"../../model-context/interactable-composer-metadata\";\nimport { unstable_useInteractableState as useInteractableState } from \"./useInteractableState\";\nimport { useJSONEqual } from \"../utils/useJSONEqual\";\n\n/**\n * The state type described by an interactable's `stateSchema`. Resolves the\n * output type of a StandardSchemaV1 schema (e.g. Zod); plain JSON Schema\n * falls back to `unknown`.\n */\nexport type Unstable_InferInteractableState<TSchema> = TSchema extends {\n \"~standard\": { types?: { output: infer TOutput } | undefined };\n}\n ? TOutput\n : unknown;\n\n/**\n * One message's version of an interactable, for components rendered inside\n * tool-call parts. Show `state` to display history; call `restore()` to set\n * the live instance back to it.\n */\nexport type Unstable_InteractableVersionInfo<TState> = {\n /** The interactable's state as it was at this message. */\n state: TState;\n /** Whether this message holds the instance's most recent tool-driven version. */\n isLatest: boolean;\n /** Sets the live state back to this version. */\n restore: () => void;\n};\n\n/**\n * Unstable / Experimental — the interactables API is still evolving and may change in any release.\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport type Unstable_InteractableConfig<\n TSchema extends Unstable_InteractableStateSchema,\n> = {\n description: string;\n stateSchema: TSchema;\n initialState: Unstable_InferInteractableState<TSchema>;\n /** Unique instance ID; required to address this instance when multiple interactables share a name. Auto-generated if omitted. */\n id?: string | undefined;\n /**\n * Component installed as the tool UI for this interactable's `update_{name}`\n * tool calls, so a model edit re-renders the interactable at the message\n * that made it instead of only mutating an earlier one. Prefer\n * `unstable_interactableTool`, which wires this up. Pass a stable component reference;\n * changing identity re-registers the tool UI.\n */\n updateRender?: ToolCallMessagePartComponent | undefined;\n};\n\nconst useInteractable = <TSchema extends Unstable_InteractableStateSchema>(\n name: string,\n config: Unstable_InteractableConfig<TSchema>,\n): readonly [\n Unstable_InferInteractableState<TSchema>,\n {\n id: string;\n /**\n * This message's version of the instance, when rendered inside a\n * tool-created interactable message part; `undefined` elsewhere.\n */\n version:\n | Unstable_InteractableVersionInfo<\n Unstable_InferInteractableState<TSchema>\n >\n | undefined;\n setState: (\n updater:\n | Unstable_InferInteractableState<TSchema>\n | ((\n prev: Unstable_InferInteractableState<TSchema>,\n ) => Unstable_InferInteractableState<TSchema>),\n ) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] => {\n const aui = useAui();\n\n const autoId = useId().replace(/[^a-zA-Z0-9]/g, \"\");\n\n // Whether this component renders inside a message part is fixed for its\n // lifetime, so conditioning the selectors on it is safe.\n const inPart = aui.part.source != null;\n const updateToolName = interactableToolName(name);\n const part = useAuiState((s) => {\n if (!inPart) return undefined;\n const p = s.part;\n return p.type === \"tool-call\" ? p : undefined;\n });\n\n // Inside an update_{name} part, the instance id comes from the call itself:\n // the result's resolved id (covers id-less calls), or the id argument.\n let inferredId: string | undefined;\n if (part?.toolName === updateToolName) {\n const result = part.result as Record<string, unknown> | undefined;\n const args = part.args as Record<string, unknown> | undefined;\n if (result?.success !== false) {\n if (typeof result?.id === \"string\") inferredId = result.id;\n else if (typeof args?.id === \"string\") inferredId = args.id;\n }\n }\n\n const id = config.id ?? inferredId ?? autoId;\n const internalScope =\n part?.toolName === name || part?.toolName === updateToolName\n ? \"thread\"\n : undefined;\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 const interactables = useAuiState(() => aui.unstable_interactables());\n\n useEffect(() => {\n return interactables.register({\n id,\n name,\n description: config.description,\n stateSchema: stateSchemaRef.current,\n initialState: initialStateRef.current,\n updateRender: config.updateRender,\n ...(internalScope ? { scope: internalScope } : {}),\n } as Parameters<typeof interactables.register>[0] & {\n scope?: \"thread\" | undefined;\n });\n }, [\n interactables,\n id,\n name,\n config.description,\n internalScope,\n config.updateRender,\n ]);\n\n const myToolCallId = part?.toolCallId;\n\n const [registeredState, methods] =\n useInteractableState<Unstable_InferInteractableState<TSchema>>(id);\n const { setState } = methods;\n\n const versionValue = useAuiState(\n useJSONEqual((s) => {\n if (!internalScope || !myToolCallId) return undefined;\n const versions = getInteractableVersions(s.thread.messages, id, name);\n if (!versions.some((v) => v.origin === \"create\" && v.toolCallId === id)) {\n return undefined;\n }\n const mine = versions.find((v) => v.toolCallId === myToolCallId);\n if (!mine) return undefined;\n const latestToolCallId = versions.findLast(\n (v) => v.toolCallId !== undefined,\n )?.toolCallId;\n return { state: mine.state, isLatest: latestToolCallId === myToolCallId };\n }),\n );\n\n const version = useMemo(\n () =>\n versionValue && {\n state: versionValue.state as Unstable_InferInteractableState<TSchema>,\n isLatest: versionValue.isLatest,\n restore: () =>\n setState(\n versionValue.state as Unstable_InferInteractableState<TSchema>,\n ),\n },\n [versionValue, setState],\n );\n\n const state =\n registeredState === undefined ? config.initialState : registeredState;\n\n return [state, { id, version, ...methods }] as const;\n};\n\n/**\n * Registers an interactable with the AI assistant and returns its live state,\n * like `useState` that the model can also read and update.\n *\n * Call this once per place that shows the interactable. Other components can\n * read and write the same instance by passing its `id` to\n * `unstable_useInteractableState`.\n *\n * For tool-created interactables rendered inside tool-call message parts,\n * `version` carries this message's version of the instance — its state as of\n * that point in the conversation, whether it is the most recent tool-driven\n * version, and a `restore()` back to it. Whether older messages render frozen history or stay\n * live-editable is the component's choice. Inside an `update_{name}` part the\n * instance `id` is inferred from the call, so the same component works at the\n * creating call and at update calls.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_useInteractable: <\n TSchema extends Unstable_InteractableStateSchema,\n>(\n name: string,\n config: Unstable_InteractableConfig<TSchema>,\n) => readonly [\n Unstable_InferInteractableState<TSchema>,\n {\n id: string;\n version:\n | Unstable_InteractableVersionInfo<\n Unstable_InferInteractableState<TSchema>\n >\n | undefined;\n setState: (\n updater:\n | Unstable_InferInteractableState<TSchema>\n | ((\n prev: Unstable_InferInteractableState<TSchema>,\n ) => Unstable_InferInteractableState<TSchema>),\n ) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] = useInteractable;\n"],"mappings":";;;;;;;AA4DA,MAAM8B,mBACJC,MACAC,WAyBG;CACH,MAAMS,MAAMrC,OAAO;CAEnB,MAAMsC,SAASzC,MAAM,CAAC,CAAC0C,QAAQ,iBAAiB,EAAE;CAIlD,MAAMC,SAASH,IAAII,KAAKC,UAAU;CAClC,MAAMC,iBAAiBrC,qBAAqBqB,IAAI;CAChD,MAAMc,OAAOxC,aAAa2C,MAAM;EAC9B,IAAI,CAACJ,QAAQ,OAAOK,KAAAA;EACpB,MAAMC,IAAIF,EAAEH;EACZ,OAAOK,EAAEC,SAAS,cAAcD,IAAID,KAAAA;CACtC,CAAC;CAID,IAAIG;CACJ,IAAIP,MAAMQ,aAAaN,gBAAgB;EACrC,MAAMO,SAAST,KAAKS;EACpB,MAAME,OAAOX,KAAKW;EAClB,IAAIF,QAAQG,YAAY,OAClB;OAAA,OAAOH,QAAQ1B,OAAO,UAAUwB,aAAaE,OAAO1B;QACnD,IAAI,OAAO4B,MAAM5B,OAAO,UAAUwB,aAAaI,KAAK5B;EAAAA;CAE7D;CAEA,MAAMA,KAAKI,OAAOJ,MAAMwB,cAAcV;CACtC,MAAMgB,gBACJb,MAAMQ,aAAatB,QAAQc,MAAMQ,aAAaN,iBAC1C,WACAE,KAAAA;CAEN,MAAMU,iBAAiBxD,OAAO6B,OAAON,WAAW;CAChDiC,eAAeC,UAAU5B,OAAON;CAChC,MAAMmC,kBAAkB1D,OAAO6B,OAAOL,YAAY;CAClDkC,gBAAgBD,UAAU5B,OAAOL;CAEjC,MAAMmC,gBAAgBzD,kBAAkBoC,IAAIsB,uBAAuB,CAAC;CAEpE/D,gBAAgB;EACd,OAAO8D,cAAcE,SAAS;GAC5BpC;GACAG;GACAN,aAAaO,OAAOP;GACpBC,aAAaiC,eAAeC;GAC5BjC,cAAckC,gBAAgBD;GAC9B/B,cAAcG,OAAOH;GACrB,GAAI6B,gBAAgB,EAAEO,OAAOP,cAAc,IAAI,CAAC;EAClD,CAEC;CACH,GAAG;EACDI;EACAlC;EACAG;EACAC,OAAOP;EACPiC;EACA1B,OAAOH;CAAY,CACpB;CAED,MAAMsC,eAAetB,MAAMuB;CAE3B,MAAM,CAACC,iBAAiBC,WACtB1D,8BAA+DgB,EAAE;CACnE,MAAM,EAAEM,aAAaoC;CAErB,MAAMC,eAAelE,YACnBQ,cAAcmC,QAAM;EAClB,IAAI,CAACU,iBAAiB,CAACS,cAAc,OAAOlB,KAAAA;EAC5C,MAAMuB,WAAW/D,iCAAwBuC,IAAEyB,OAAOC,UAAU9C,IAAIG,IAAI;EACpE,IAAI,CAACyC,SAASG,MAAMC,MAAMA,EAAEC,WAAW,YAAYD,EAAER,eAAexC,EAAE,GACpE;EAEF,MAAMkD,OAAON,SAASO,MAAMH,QAAMA,IAAER,eAAeD,YAAY;EAC/D,IAAI,CAACW,MAAM,OAAO7B,KAAAA;EAClB,MAAM+B,mBAAmBR,SAASS,UAC/BL,QAAMA,IAAER,eAAenB,KAAAA,CAC1B,CAAC,EAAEmB;EACH,OAAO;GAAEhD,OAAO0D,KAAK1D;GAAOE,UAAU0D,qBAAqBb;EAAa;CAC1E,CAAC,CACH;CAEA,MAAMlC,UAAU/B,cAEZqE,gBAAgB;EACdnD,OAAOmD,aAAanD;EACpBE,UAAUiD,aAAajD;EACvBC,eACEW,SACEqC,aAAanD,KACf;CACJ,GACF,CAACmD,cAAcrC,QAAQ,CACzB;CAKA,OAAO,CAFLmC,oBAAoBpB,KAAAA,IAAYjB,OAAOL,eAAe0C,iBAEzC;EAAEzC;EAAIK;EAAS,GAAGqC;CAAQ,CAAC;AAC5C;;;;;;;;;;;;;;;;;;;AAoBA,MAAaa,2BAyBTrD"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
3
|
+
import "@assistant-ui/tap/react-shim";
|
|
3
4
|
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
4
5
|
//#region src/react/model-context/useInteractableState.ts
|
|
5
6
|
const useInteractableState = (id) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInteractableState.js","names":["c","_c","useCallback","useAui","useAuiState","StateUpdater","TState","prev","useInteractableState","id","$","aui","t0","s","unstable_interactables","definitions","state","t1","s_0","persistence","persistenceStatus","t2","updater","setState","t3","flush","t4","isPending","t5","error","t6","t7","unstable_useInteractableState","Promise"],"sources":["../../../src/react/model-context/useInteractableState.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\n\ntype StateUpdater<TState> = TState | ((prev: TState) => TState);\n\nconst useInteractableState = <TState>(\n id: string,\n): [\n TState | undefined,\n {\n setState: (updater: StateUpdater<TState>) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] => {\n const aui = useAui();\n\n const state = useAuiState(\n (s) => s.unstable_interactables.definitions[id]?.state,\n ) as TState | undefined;\n\n const persistenceStatus = useAuiState(\n (s) => s.unstable_interactables.persistence[id],\n );\n\n const setState = useCallback(\n (updater: StateUpdater<TState>) => {\n aui.unstable_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 flush = useCallback(() => aui.unstable_interactables().flush(), [aui]);\n\n return [\n state,\n {\n setState,\n isPending: persistenceStatus?.isPending ?? false,\n error: persistenceStatus?.error,\n flush,\n },\n ];\n};\n\n/**\n * Reads and writes the state of an interactable registered elsewhere, by id.\n *\n * Use this from secondary readers (children, siblings); the owning component\n * registers with `unstable_useInteractable`, which returns state directly. Returns\n * `undefined` until the owning interactable is registered.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_useInteractableState: <TState>(id: string) => [\n TState | undefined,\n {\n setState: (updater: StateUpdater<TState>) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] = useInteractableState;\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useInteractableState.js","names":["c","_c","useCallback","useAui","useAuiState","StateUpdater","TState","prev","useInteractableState","id","$","aui","t0","s","unstable_interactables","definitions","state","t1","s_0","persistence","persistenceStatus","t2","updater","setState","t3","flush","t4","isPending","t5","error","t6","t7","unstable_useInteractableState","Promise"],"sources":["../../../src/react/model-context/useInteractableState.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\n\ntype StateUpdater<TState> = TState | ((prev: TState) => TState);\n\nconst useInteractableState = <TState>(\n id: string,\n): [\n TState | undefined,\n {\n setState: (updater: StateUpdater<TState>) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] => {\n const aui = useAui();\n\n const state = useAuiState(\n (s) => s.unstable_interactables.definitions[id]?.state,\n ) as TState | undefined;\n\n const persistenceStatus = useAuiState(\n (s) => s.unstable_interactables.persistence[id],\n );\n\n const setState = useCallback(\n (updater: StateUpdater<TState>) => {\n aui.unstable_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 flush = useCallback(() => aui.unstable_interactables().flush(), [aui]);\n\n return [\n state,\n {\n setState,\n isPending: persistenceStatus?.isPending ?? false,\n error: persistenceStatus?.error,\n flush,\n },\n ];\n};\n\n/**\n * Reads and writes the state of an interactable registered elsewhere, by id.\n *\n * Use this from secondary readers (children, siblings); the owning component\n * registers with `unstable_useInteractable`, which returns state directly. Returns\n * `undefined` until the owning interactable is registered.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_useInteractableState: <TState>(id: string) => [\n TState | undefined,\n {\n setState: (updater: StateUpdater<TState>) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] = useInteractableState;\n"],"mappings":";;;;;AAOA,MAAMQ,wBAAuBC,OAAA;CAAA,MAAAC,IAAAT,EAAA,EAAA;CAW3B,MAAAU,MAAYR,OAAO;CAAE,IAAAS;CAAA,IAAAF,EAAA,OAAAD,IAAA;EAGnBG,MAAAC,MAAOA,EAACC,uBAAuBC,YAAaN,GAAU,EAAAO;EAAAN,EAAA,KAAAD;EAAAC,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CADxD,MAAAM,QAAcZ,YACZQ,EACF;CAAwB,IAAAK;CAAA,IAAAP,EAAA,OAAAD,IAAA;EAGtBQ,MAAAC,QAAOL,IAACC,uBAAuBK,YAAaV;EAAGC,EAAA,KAAAD;EAAAC,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CADjD,MAAAU,oBAA0BhB,YACxBa,EACF;CAAE,IAAAI;CAAA,IAAAX,EAAA,OAAAC,OAAAD,EAAA,OAAAD,IAAA;EAGAY,MAAAC,YAAA;GACEX,IAAGG,uBAAwB,CAAC,CAAAS,SAAUd,KAAIF,SAAA;IACxC,IAAI,OAAOe,YAAY,YAAU,OACvBA,QAAqCf,IAAc;IAC5D,OACMe;GAAO,CACf;EAAC;EACHZ,EAAA,KAAAC;EAAAD,EAAA,KAAAD;EAAAC,EAAA,KAAAW;CAAA,OAAAA,KAAAX,EAAA;CARH,MAAAa,WAAiBF;CAUf,IAAAG;CAAA,IAAAd,EAAA,OAAAC,KAAA;EAEwBa,WAAMb,IAAGG,uBAAwB,CAAC,CAAAW,MAAO;EAACf,EAAA,KAAAC;EAAAD,EAAA,KAAAc;CAAA,OAAAA,KAAAd,EAAA;CAApE,MAAAe,QAAcD;CAMC,MAAAE,KAAAN,mBAAiBO,aAAjB;CACJ,MAAAC,KAAAR,mBAAiBS;CAAO,IAAAC;CAAA,IAAApB,EAAA,OAAAe,SAAAf,EAAA,QAAAa,YAAAb,EAAA,QAAAgB,MAAAhB,EAAA,QAAAkB,IAAA;EAHjCE,KAAA;GAAAP;GAAAI,WAEaD;GAAqCG,OACzCD;GAAwBH;EAEjC;EAACf,EAAA,KAAAe;EAAAf,EAAA,MAAAa;EAAAb,EAAA,MAAAgB;EAAAhB,EAAA,MAAAkB;EAAAlB,EAAA,MAAAoB;CAAA,OAAAA,KAAApB,EAAA;CAAA,IAAAqB;CAAA,IAAArB,EAAA,QAAAM,SAAAN,EAAA,QAAAoB,IAAA;EAPIC,KAAA,CACLf,OACAc,EAKC;EACFpB,EAAA,MAAAM;EAAAN,EAAA,MAAAoB;EAAApB,EAAA,MAAAqB;CAAA,OAAAA,KAAArB,EAAA;CAAA,OARMqB;AAQN;;;;;;;;;;AAYH,MAAaC,gCAQTxB"}
|
|
@@ -2,6 +2,7 @@ import { unstable_getInteractableVersions } from "../../model-context/interactab
|
|
|
2
2
|
import { unstable_useInteractableState } from "./useInteractableState.js";
|
|
3
3
|
import { useJSONEqual } from "../utils/useJSONEqual.js";
|
|
4
4
|
import { useAuiState } from "@assistant-ui/store";
|
|
5
|
+
import "@assistant-ui/tap/react-shim";
|
|
5
6
|
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
6
7
|
//#region src/react/model-context/useInteractableVersions.ts
|
|
7
8
|
const useInteractableVersions = (id, name) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInteractableVersions.js","names":["useMemo","useAuiState","unstable_getInteractableVersions","getInteractableVersions","Unstable_InteractableVersion","unstable_useInteractableState","useInteractableState","useJSONEqual","useInteractableVersions","id","name","$","_c","t0","s","thread","messages","versions","t1","setState","t2","t3","v","state","TState","restore","map","unstable_useInteractableVersions","Omit"],"sources":["../../../src/react/model-context/useInteractableVersions.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport {\n unstable_getInteractableVersions as getInteractableVersions,\n type Unstable_InteractableVersion,\n} from \"../../model-context/interactable-composer-metadata\";\nimport { unstable_useInteractableState as useInteractableState } from \"./useInteractableState\";\nimport { useJSONEqual } from \"../utils/useJSONEqual\";\n\nconst useInteractableVersions = <TState = unknown>(\n id: string,\n name: string,\n): (Omit<Unstable_InteractableVersion, \"state\"> & {\n state: TState;\n restore: () => void;\n})[] => {\n const versions = useAuiState(\n useJSONEqual((s) => getInteractableVersions(s.thread.messages, id, name)),\n );\n const [, { setState }] = useInteractableState<TState>(id);\n\n return useMemo(\n () =>\n versions.map((v) => ({\n ...v,\n state: v.state as TState,\n restore: () => setState(v.state as TState),\n })),\n [versions, setState],\n );\n};\n\n/**\n * Every version of a tool-created interactable recorded in the current\n * thread, oldest first: the creating tool call, each user edit, and each\n * `update_*` call. Each entry carries the full state as of that version and a\n * `restore()` that sets the live instance back to it — enough for a version\n * picker like an artifact's history dropdown.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_useInteractableVersions: <TState = unknown>(\n id: string,\n name: string,\n) => (Omit<Unstable_InteractableVersion, \"state\"> & {\n state: TState;\n restore: () => void;\n})[] = useInteractableVersions;\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useInteractableVersions.js","names":["useMemo","useAuiState","unstable_getInteractableVersions","getInteractableVersions","Unstable_InteractableVersion","unstable_useInteractableState","useInteractableState","useJSONEqual","useInteractableVersions","id","name","$","_c","t0","s","thread","messages","versions","t1","setState","t2","t3","v","state","TState","restore","map","unstable_useInteractableVersions","Omit"],"sources":["../../../src/react/model-context/useInteractableVersions.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport {\n unstable_getInteractableVersions as getInteractableVersions,\n type Unstable_InteractableVersion,\n} from \"../../model-context/interactable-composer-metadata\";\nimport { unstable_useInteractableState as useInteractableState } from \"./useInteractableState\";\nimport { useJSONEqual } from \"../utils/useJSONEqual\";\n\nconst useInteractableVersions = <TState = unknown>(\n id: string,\n name: string,\n): (Omit<Unstable_InteractableVersion, \"state\"> & {\n state: TState;\n restore: () => void;\n})[] => {\n const versions = useAuiState(\n useJSONEqual((s) => getInteractableVersions(s.thread.messages, id, name)),\n );\n const [, { setState }] = useInteractableState<TState>(id);\n\n return useMemo(\n () =>\n versions.map((v) => ({\n ...v,\n state: v.state as TState,\n restore: () => setState(v.state as TState),\n })),\n [versions, setState],\n );\n};\n\n/**\n * Every version of a tool-created interactable recorded in the current\n * thread, oldest first: the creating tool call, each user edit, and each\n * `update_*` call. Each entry carries the full state as of that version and a\n * `restore()` that sets the live instance back to it — enough for a version\n * picker like an artifact's history dropdown.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_useInteractableVersions: <TState = unknown>(\n id: string,\n name: string,\n) => (Omit<Unstable_InteractableVersion, \"state\"> & {\n state: TState;\n restore: () => void;\n})[] = useInteractableVersions;\n"],"mappings":";;;;;;;AASA,MAAMQ,2BAA0BC,IAAAC,SAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAF,MAAAE,EAAA,OAAAD,MAAA;EAQfG,MAAAC,MAAOX,iCAAwBW,EAACC,OAAOC,UAAWP,IAAIC,IAAI;EAACC,EAAA,KAAAF;EAAAE,EAAA,KAAAD;EAAAC,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAD1E,MAAAM,WAAiBhB,YACfM,aAAaM,EAA2D,CAC1E;CACA,MAAA,GAAAK,MAAyBZ,8BAA6BG,EAAE;CAA/C,MAAA,EAAAU,aAAAD;CAAY,IAAAE;CAAA,IAAAT,EAAA,OAAAQ,YAAAR,EAAA,OAAAM,UAAA;EAAA,IAAAI;EAAA,IAAAV,EAAA,OAAAQ,UAAA;GAIJE,MAAAC,OAAQ;IAAA,GAChBA;IAACC,OACGD,EAACC;IAAgBE,eACTN,SAASG,EAACC,KAAgB;GAC3C;GAAEZ,EAAA,KAAAQ;GAAAR,EAAA,KAAAU;EAAA,OAAAA,KAAAV,EAAA;EAJFS,KAAAH,SAAQS,IAAKL,EAIX;EAACV,EAAA,KAAAQ;EAAAR,EAAA,KAAAM;EAAAN,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,OAJHS;AAIG;;;;;;;;;;AAcT,MAAaO,mCAMNnB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getPartialJsonObjectFieldState, getPartialJsonObjectMeta } from "assistant-stream/utils";
|
|
2
2
|
import { useAuiState } from "@assistant-ui/store";
|
|
3
|
+
import "@assistant-ui/tap/react-shim";
|
|
3
4
|
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
4
5
|
//#region src/react/model-context/useToolArgsStatus.ts
|
|
5
6
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useToolArgsStatus.js","names":["useMemo","useAuiState","getPartialJsonObjectFieldState","getPartialJsonObjectMeta","PropFieldStatus","ToolArgsStatus","Record","status","propStatus","Partial","TArgs","useToolArgsStatus","$","_c","part","_temp","t0","statusType","type","Error","isStreaming","args","t1","t2","meta","key","Object","keys","fieldState","t3","t4","s"],"sources":["../../../src/react/model-context/useToolArgsStatus.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport {\n getPartialJsonObjectFieldState,\n getPartialJsonObjectMeta,\n} from \"assistant-stream/utils\";\n\ntype PropFieldStatus = \"streaming\" | \"complete\";\n\n/**\n * Streaming completion status for the arguments of the current tool call.\n */\nexport type ToolArgsStatus<\n TArgs extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** Overall lifecycle state of the tool-call part. */\n status: \"running\" | \"complete\" | \"incomplete\" | \"requires-action\";\n /** Per-argument status keyed by argument name. */\n propStatus: Partial<Record<keyof TArgs, PropFieldStatus>>;\n};\n\n/**\n * Reads whether each argument field for the current tool-call message part is\n * still streaming or complete.\n *\n * Use inside a tool-call renderer to avoid showing incomplete argument values\n * as final.\n *\n * @throws If called outside a tool-call message part.\n *\n * @example\n * ```tsx\n * function WeatherToolUI({\n * args,\n * }: ToolCallMessagePartProps<{ city: string }>) {\n * const { propStatus } = useToolArgsStatus<{ city: string }>();\n *\n * return (\n * <span>\n * {propStatus.city === \"streaming\" ? \"Reading city...\" : args.city}\n * </span>\n * );\n * }\n * ```\n */\nexport const useToolArgsStatus = <\n TArgs extends Record<string, unknown> = Record<string, unknown>,\n>(): ToolArgsStatus<TArgs> => {\n const part = useAuiState((s) => s.part);\n\n return useMemo(() => {\n const statusType = part.status.type;\n\n if (part.type !== \"tool-call\") {\n throw new Error(\n \"useToolArgsStatus can only be used inside tool-call message parts\",\n );\n }\n\n const isStreaming = statusType === \"running\";\n const args = part.args as Record<string, unknown>;\n const meta = getPartialJsonObjectMeta(args as Record<symbol, unknown>);\n const propStatus: Partial<Record<string, PropFieldStatus>> = {};\n\n for (const key of Object.keys(args)) {\n if (meta) {\n const fieldState = getPartialJsonObjectFieldState(args, [key]);\n propStatus[key] =\n fieldState === \"complete\" || !isStreaming ? \"complete\" : \"streaming\";\n } else {\n propStatus[key] = isStreaming ? \"streaming\" : \"complete\";\n }\n }\n\n return {\n status: statusType,\n propStatus: propStatus as Partial<Record<keyof TArgs, PropFieldStatus>>,\n };\n }, [part]);\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useToolArgsStatus.js","names":["useMemo","useAuiState","getPartialJsonObjectFieldState","getPartialJsonObjectMeta","PropFieldStatus","ToolArgsStatus","Record","status","propStatus","Partial","TArgs","useToolArgsStatus","$","_c","part","_temp","t0","statusType","type","Error","isStreaming","args","t1","t2","meta","key","Object","keys","fieldState","t3","t4","s"],"sources":["../../../src/react/model-context/useToolArgsStatus.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport {\n getPartialJsonObjectFieldState,\n getPartialJsonObjectMeta,\n} from \"assistant-stream/utils\";\n\ntype PropFieldStatus = \"streaming\" | \"complete\";\n\n/**\n * Streaming completion status for the arguments of the current tool call.\n */\nexport type ToolArgsStatus<\n TArgs extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** Overall lifecycle state of the tool-call part. */\n status: \"running\" | \"complete\" | \"incomplete\" | \"requires-action\";\n /** Per-argument status keyed by argument name. */\n propStatus: Partial<Record<keyof TArgs, PropFieldStatus>>;\n};\n\n/**\n * Reads whether each argument field for the current tool-call message part is\n * still streaming or complete.\n *\n * Use inside a tool-call renderer to avoid showing incomplete argument values\n * as final.\n *\n * @throws If called outside a tool-call message part.\n *\n * @example\n * ```tsx\n * function WeatherToolUI({\n * args,\n * }: ToolCallMessagePartProps<{ city: string }>) {\n * const { propStatus } = useToolArgsStatus<{ city: string }>();\n *\n * return (\n * <span>\n * {propStatus.city === \"streaming\" ? \"Reading city...\" : args.city}\n * </span>\n * );\n * }\n * ```\n */\nexport const useToolArgsStatus = <\n TArgs extends Record<string, unknown> = Record<string, unknown>,\n>(): ToolArgsStatus<TArgs> => {\n const part = useAuiState((s) => s.part);\n\n return useMemo(() => {\n const statusType = part.status.type;\n\n if (part.type !== \"tool-call\") {\n throw new Error(\n \"useToolArgsStatus can only be used inside tool-call message parts\",\n );\n }\n\n const isStreaming = statusType === \"running\";\n const args = part.args as Record<string, unknown>;\n const meta = getPartialJsonObjectMeta(args as Record<symbol, unknown>);\n const propStatus: Partial<Record<string, PropFieldStatus>> = {};\n\n for (const key of Object.keys(args)) {\n if (meta) {\n const fieldState = getPartialJsonObjectFieldState(args, [key]);\n propStatus[key] =\n fieldState === \"complete\" || !isStreaming ? \"complete\" : \"streaming\";\n } else {\n propStatus[key] = isStreaming ? \"streaming\" : \"complete\";\n }\n }\n\n return {\n status: statusType,\n propStatus: propStatus as Partial<Record<keyof TArgs, PropFieldStatus>>,\n };\n }, [part]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,MAAaW,0BAAoB;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAG/B,MAAAC,OAAab,YAAYc,KAAa;CAAE,IAAAC;CAGtC,MAAAC,aAAmBH,KAAIP,OAAOW;CAE9B,IAAIJ,KAAII,SAAU,aAChB,MAAM,IAAIC,MACR,mEACF;CAGF,MAAAC,cAAoBH,eAAe;CACnC,MAAAI,OAAaP,KAAIO;CACqB,MAAAC,KAAAD;CAA+B,IAAAE;CAAA,IAAAX,EAAA,OAAAU,IAAA;EAAxDC,KAAApB,yBAAyBmB,EAA+B;EAACV,EAAA,KAAAU;EAAAV,EAAA,KAAAW;CAAA,OAAAA,KAAAX,EAAA;CAAtE,MAAAY,OAAaD;CAA0D,IAAAf;CAAA,IAAAI,EAAA,OAAAS,QAAAT,EAAA,OAAAQ,eAAAR,EAAA,OAAAY,MAAA;EACvEhB,aAA6D,CAAC;EAE9D,KAAK,MAAAiB,OAAaC,OAAMC,KAAMN,IAAI,GAChC,IAAIG,MAAI;GACN,MAAAI,aAAmB1B,+BAA+BmB,MAAM,CAACI,GAAG,CAAC;GAC7DjB,WAAWiB,OACTG,eAAe,cAAf,CAA8BR,cAA9B,aAAA;EADa,OAGfZ,WAAWiB,OAAOL,cAAA,cAAA;EAErBR,EAAA,KAAAS;EAAAT,EAAA,KAAAQ;EAAAR,EAAA,KAAAY;EAAAZ,EAAA,KAAAJ;CAAA,OAAAA,aAAAI,EAAA;CAIa,MAAAiB,KAAArB;CAA2D,IAAAsB;CAAA,IAAAlB,EAAA,OAAAK,cAAAL,EAAA,OAAAiB,IAAA;EAFlEC,KAAA;GAAAvB,QACGU;GAAUT,YACNqB;EACd;EAACjB,EAAA,KAAAK;EAAAL,EAAA,KAAAiB;EAAAjB,EAAA,KAAAkB;CAAA,OAAAA,KAAAlB,EAAA;CAHDI,KAAOc;CAGL,OA3BGd;AA4BG;AAjCqB,SAAAD,MAAAgB,GAAA;CAAA,OAGCA,EAACjB;AAAK"}
|
|
@@ -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/primitive-hooks/useActionBarCopy.ts
|
|
4
5
|
const useActionBarCopy = (t0) => {
|
|
@@ -19,13 +20,13 @@ const useActionBarCopy = (t0) => {
|
|
|
19
20
|
let t3;
|
|
20
21
|
if ($[2] !== aui || $[3] !== composerValue || $[4] !== copiedDuration || $[5] !== copyToClipboard || $[6] !== isEditing) {
|
|
21
22
|
t3 = () => {
|
|
23
|
+
if (!copyToClipboard) return;
|
|
22
24
|
const valueToCopy = isEditing ? composerValue : aui.message().getCopyText();
|
|
23
25
|
if (!valueToCopy) return;
|
|
24
|
-
|
|
25
|
-
Promise.resolve(write(valueToCopy)).then(() => {
|
|
26
|
+
Promise.resolve(copyToClipboard(valueToCopy)).then(() => {
|
|
26
27
|
aui.message().setIsCopied(true);
|
|
27
28
|
setTimeout(() => aui.message().setIsCopied(false), copiedDuration);
|
|
28
|
-
},
|
|
29
|
+
}, _temp6);
|
|
29
30
|
};
|
|
30
31
|
$[2] = aui;
|
|
31
32
|
$[3] = composerValue;
|
|
@@ -35,19 +36,20 @@ const useActionBarCopy = (t0) => {
|
|
|
35
36
|
$[7] = t3;
|
|
36
37
|
} else t3 = $[7];
|
|
37
38
|
const copy = t3;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
const t4 = disabled || !copyToClipboard;
|
|
40
|
+
let t5;
|
|
41
|
+
if ($[8] !== copy || $[9] !== isCopied || $[10] !== t4) {
|
|
42
|
+
t5 = {
|
|
41
43
|
copy,
|
|
42
|
-
disabled,
|
|
44
|
+
disabled: t4,
|
|
43
45
|
isCopied
|
|
44
46
|
};
|
|
45
47
|
$[8] = copy;
|
|
46
|
-
$[9] =
|
|
47
|
-
$[10] =
|
|
48
|
-
$[11] =
|
|
49
|
-
} else
|
|
50
|
-
return
|
|
48
|
+
$[9] = isCopied;
|
|
49
|
+
$[10] = t4;
|
|
50
|
+
$[11] = t5;
|
|
51
|
+
} else t5 = $[11];
|
|
52
|
+
return t5;
|
|
51
53
|
};
|
|
52
54
|
function _temp(c) {
|
|
53
55
|
return c.type === "text" && c.text.length > 0;
|
|
@@ -65,7 +67,6 @@ function _temp5(s_2) {
|
|
|
65
67
|
return s_2.composer.text;
|
|
66
68
|
}
|
|
67
69
|
function _temp6() {}
|
|
68
|
-
function _temp7() {}
|
|
69
70
|
//#endregion
|
|
70
71
|
export { useActionBarCopy };
|
|
71
72
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useActionBarCopy.js","names":["useCallback","useAui","useAuiState","UseActionBarCopyOptions","copiedDuration","copyToClipboard","text","Promise","useActionBarCopy","t0","$","_c","t1","undefined","t2","aui","disabled","_temp2","isCopied","_temp3","isEditing","_temp4","composerValue","_temp5","t3","valueToCopy","message","getCopyText","
|
|
1
|
+
{"version":3,"file":"useActionBarCopy.js","names":["useCallback","useAui","useAuiState","UseActionBarCopyOptions","copiedDuration","copyToClipboard","text","Promise","useActionBarCopy","t0","$","_c","t1","undefined","t2","aui","disabled","_temp2","isCopied","_temp3","isEditing","_temp4","composerValue","_temp5","t3","valueToCopy","message","getCopyText","resolve","then","setIsCopied","setTimeout","_temp6","copy","t4","t5","_temp","c","type","length","s","role","status","parts","some","s_0","s_1","composer","s_2"],"sources":["../../../src/react/primitive-hooks/useActionBarCopy.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\n\nexport type UseActionBarCopyOptions = {\n copiedDuration?: number | undefined;\n copyToClipboard?: ((text: string) => void | Promise<void>) | undefined;\n};\n\nexport const useActionBarCopy = ({\n copiedDuration = 3000,\n copyToClipboard,\n}: UseActionBarCopyOptions = {}) => {\n const aui = useAui();\n const disabled = useAuiState((s) => {\n return !(\n (s.message.role !== \"assistant\" ||\n s.message.status?.type !== \"running\") &&\n s.message.parts.some((c) => c.type === \"text\" && c.text.length > 0)\n );\n });\n const isCopied = useAuiState((s) => s.message.isCopied);\n const isEditing = useAuiState((s) => s.composer.isEditing);\n const composerValue = useAuiState((s) => s.composer.text);\n\n const copy = useCallback(() => {\n if (!copyToClipboard) return;\n\n const valueToCopy = isEditing ? composerValue : aui.message().getCopyText();\n if (!valueToCopy) return;\n\n // The rejection handler swallows clipboard write failures (permission denied,\n // API unavailable) so they don't surface as unhandled promise rejections.\n Promise.resolve(copyToClipboard(valueToCopy)).then(\n () => {\n aui.message().setIsCopied(true);\n setTimeout(() => aui.message().setIsCopied(false), copiedDuration);\n },\n () => {},\n );\n }, [aui, isEditing, composerValue, copiedDuration, copyToClipboard]);\n\n return { copy, disabled: disabled || !copyToClipboard, isCopied };\n};\n"],"mappings":";;;;AAQA,MAAaQ,oBAAmBC,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAD,IAAA;EAACG,KAAAH,OAAAI,KAAAA,IAAA,CAGH,IAHGJ;EAGFC,EAAA,KAAAD;EAAAC,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAHE,MAAA,EAAAN,gBAAAU,IAAAT,oBAAAO;CAC/B,MAAAR,iBAAAU,OAAAD,KAAAA,IAAA,MAAAC;CAGA,MAAAC,MAAYd,OAAO;CACnB,MAAAe,WAAiBd,YAAYe,MAM5B;CACD,MAAAC,WAAiBhB,YAAYiB,MAAyB;CACtD,MAAAC,YAAkBlB,YAAYmB,MAA2B;CACzD,MAAAC,gBAAsBpB,YAAYqB,MAAsB;CAAE,IAAAC;CAAA,IAAAd,EAAA,OAAAK,OAAAL,EAAA,OAAAY,iBAAAZ,EAAA,OAAAN,kBAAAM,EAAA,OAAAL,mBAAAK,EAAA,OAAAU,WAAA;EAEjCI,WAAA;GACvB,IAAI,CAACnB,iBAAe;GAEpB,MAAAoB,cAAoBL,YAAAE,gBAA4BP,IAAGW,QAAS,CAAC,CAAAC,YAAa;GAC1E,IAAI,CAACF,aAAW;GAIhBlB,QAAOqB,QAASvB,gBAAgBoB,WAAW,CAAC,CAAC,CAAAI,WAC3C;IACEd,IAAGW,QAAS,CAAC,CAAAI,YAAa,IAAI;IAC9BC,iBAAiBhB,IAAGW,QAAS,CAAC,CAAAI,YAAa,KAAK,GAAG1B,cAAc;GAAC,GAEpE4B,MACF;EAAC;EACFtB,EAAA,KAAAK;EAAAL,EAAA,KAAAY;EAAAZ,EAAA,KAAAN;EAAAM,EAAA,KAAAL;EAAAK,EAAA,KAAAU;EAAAV,EAAA,KAAAc;CAAA,OAAAA,KAAAd,EAAA;CAfD,MAAAuB,OAAaT;CAiBY,MAAAU,KAAAlB,YAAA,CAAaX;CAAe,IAAA8B;CAAA,IAAAzB,EAAA,OAAAuB,QAAAvB,EAAA,OAAAQ,YAAAR,EAAA,QAAAwB,IAAA;EAA9CC,KAAA;GAAAF;GAAAjB,UAAkBkB;GAA4BhB;EAAW;EAACR,EAAA,KAAAuB;EAAAvB,EAAA,KAAAQ;EAAAR,EAAA,MAAAwB;EAAAxB,EAAA,MAAAyB;CAAA,OAAAA,KAAAzB,EAAA;CAAA,OAA1DyB;AAA0D;AAjCnC,SAAAC,MAAAC,GAAA;CAAA,OASEA,EAACC,SAAU,UAAUD,EAAC/B,KAAKiC,SAAU;AAAC;AATxC,SAAAtB,OAAAuB,GAAA;CAAA,OAMrB,GACJA,EAACd,QAAQe,SAAU,eAClBD,EAACd,QAAQgB,QAAaJ,SAAK,cAC7BE,EAACd,QAAQiB,MAAMC,KAAMR,KAA6C;AACnE;AAV2B,SAAAjB,OAAA0B,KAAA;CAAA,OAYML,IAACd,QAAQR;AAAS;AAZxB,SAAAG,OAAAyB,KAAA;CAAA,OAaON,IAACO,SAAS3B;AAAU;AAb3B,SAAAG,OAAAyB,KAAA;CAAA,OAcWR,IAACO,SAASzC;AAAK;AAd1B,SAAA0B,SAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useActionBarEdit.js","names":["useCallback","useAui","useAuiState","useActionBarEdit","$","_c","aui","disabled","_temp","t0","composer","beginEdit","edit","t1","s","isEditing"],"sources":["../../../src/react/primitive-hooks/useActionBarEdit.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\n\nexport const useActionBarEdit = () => {\n const aui = useAui();\n const disabled = useAuiState((s) => s.composer.isEditing);\n\n const edit = useCallback(() => {\n aui.composer().beginEdit();\n }, [aui]);\n\n return { edit, disabled };\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useActionBarEdit.js","names":["useCallback","useAui","useAuiState","useActionBarEdit","$","_c","aui","disabled","_temp","t0","composer","beginEdit","edit","t1","s","isEditing"],"sources":["../../../src/react/primitive-hooks/useActionBarEdit.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\n\nexport const useActionBarEdit = () => {\n const aui = useAui();\n const disabled = useAuiState((s) => s.composer.isEditing);\n\n const edit = useCallback(() => {\n aui.composer().beginEdit();\n }, [aui]);\n\n return { edit, disabled };\n};\n"],"mappings":";;;;AAGA,MAAaG,yBAAmB;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAC9B,MAAAC,MAAYL,OAAO;CACnB,MAAAM,WAAiBL,YAAYM,KAA2B;CAAE,IAAAC;CAAA,IAAAL,EAAA,OAAAE,KAAA;EAEjCG,WAAA;GACvBH,IAAGI,SAAU,CAAC,CAAAC,UAAW;EAAC;EAC3BP,EAAA,KAAAE;EAAAF,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAFD,MAAAQ,OAAaH;CAEH,IAAAI;CAAA,IAAAT,EAAA,OAAAG,YAAAH,EAAA,OAAAQ,MAAA;EAEHC,KAAA;GAAAD;GAAAL;EAAiB;EAACH,EAAA,KAAAG;EAAAH,EAAA,KAAAQ;EAAAR,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,OAAlBS;AAAkB;AARK,SAAAL,MAAAM,GAAA;CAAA,OAEMA,EAACJ,SAASK;AAAU"}
|
|
@@ -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/primitive-hooks/useActionBarFeedback.ts
|
|
4
5
|
const useActionBarFeedbackPositive = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useActionBarFeedback.js","names":["useCallback","useAui","useAuiState","useActionBarFeedbackPositive","$","_c","aui","isSubmitted","_temp","t0","message","submitFeedback","type","submit","t1","useActionBarFeedbackNegative","_temp2","s","metadata","submittedFeedback"],"sources":["../../../src/react/primitive-hooks/useActionBarFeedback.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\n\nexport const useActionBarFeedbackPositive = () => {\n const aui = useAui();\n const isSubmitted = useAuiState(\n (s) => s.message.metadata.submittedFeedback?.type === \"positive\",\n );\n\n const submit = useCallback(() => {\n aui.message().submitFeedback({ type: \"positive\" });\n }, [aui]);\n\n return { submit, isSubmitted };\n};\n\nexport const useActionBarFeedbackNegative = () => {\n const aui = useAui();\n const isSubmitted = useAuiState(\n (s) => s.message.metadata.submittedFeedback?.type === \"negative\",\n );\n\n const submit = useCallback(() => {\n aui.message().submitFeedback({ type: \"negative\" });\n }, [aui]);\n\n return { submit, isSubmitted };\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useActionBarFeedback.js","names":["useCallback","useAui","useAuiState","useActionBarFeedbackPositive","$","_c","aui","isSubmitted","_temp","t0","message","submitFeedback","type","submit","t1","useActionBarFeedbackNegative","_temp2","s","metadata","submittedFeedback"],"sources":["../../../src/react/primitive-hooks/useActionBarFeedback.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\n\nexport const useActionBarFeedbackPositive = () => {\n const aui = useAui();\n const isSubmitted = useAuiState(\n (s) => s.message.metadata.submittedFeedback?.type === \"positive\",\n );\n\n const submit = useCallback(() => {\n aui.message().submitFeedback({ type: \"positive\" });\n }, [aui]);\n\n return { submit, isSubmitted };\n};\n\nexport const useActionBarFeedbackNegative = () => {\n const aui = useAui();\n const isSubmitted = useAuiState(\n (s) => s.message.metadata.submittedFeedback?.type === \"negative\",\n );\n\n const submit = useCallback(() => {\n aui.message().submitFeedback({ type: \"negative\" });\n }, [aui]);\n\n return { submit, isSubmitted };\n};\n"],"mappings":";;;;AAGA,MAAaG,qCAA+B;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAC1C,MAAAC,MAAYL,OAAO;CACnB,MAAAM,cAAoBL,YAClBM,KACF;CAAE,IAAAC;CAAA,IAAAL,EAAA,OAAAE,KAAA;EAEyBG,WAAA;GACzBH,IAAGI,QAAS,CAAC,CAAAC,eAAgB,EAAAC,MAAQ,WAAW,CAAC;EAAC;EACnDR,EAAA,KAAAE;EAAAF,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAFD,MAAAS,SAAeJ;CAEL,IAAAK;CAAA,IAAAV,EAAA,OAAAG,eAAAH,EAAA,OAAAS,QAAA;EAEHC,KAAA;GAAAD;GAAAN;EAAsB;EAACH,EAAA,KAAAG;EAAAH,EAAA,KAAAS;EAAAT,EAAA,KAAAU;CAAA,OAAAA,KAAAV,EAAA;CAAA,OAAvBU;AAAuB;AAGhC,MAAaC,qCAA+B;CAAA,MAAAX,IAAAC,EAAA,CAAA;CAC1C,MAAAC,MAAYL,OAAO;CACnB,MAAAM,cAAoBL,YAClBc,MACF;CAAE,IAAAP;CAAA,IAAAL,EAAA,OAAAE,KAAA;EAEyBG,WAAA;GACzBH,IAAGI,QAAS,CAAC,CAAAC,eAAgB,EAAAC,MAAQ,WAAW,CAAC;EAAC;EACnDR,EAAA,KAAAE;EAAAF,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAFD,MAAAS,SAAeJ;CAEL,IAAAK;CAAA,IAAAV,EAAA,OAAAG,eAAAH,EAAA,OAAAS,QAAA;EAEHC,KAAA;GAAAD;GAAAN;EAAsB;EAACH,EAAA,KAAAG;EAAAH,EAAA,KAAAS;EAAAT,EAAA,KAAAU;CAAA,OAAAA,KAAAV,EAAA;CAAA,OAAvBU;AAAuB;AAvBY,SAAAN,MAAAS,GAAA;CAAA,OAGjCA,EAACP,QAAQQ,SAASC,mBAAwBP,SAAK;AAAU;AAUxB,SAAAI,OAAAC,GAAA;CAAA,OAGjCA,EAACP,QAAQQ,SAASC,mBAAwBP,SAAK;AAAU"}
|