@assistant-ui/core 0.3.13 → 0.3.15
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/speech.d.ts.map +1 -1
- package/dist/adapters/speech.js +9 -15
- package/dist/adapters/speech.js.map +1 -1
- package/dist/adapters/thread-history.d.ts +2 -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 +38 -15
- package/dist/adapters/voice.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +3 -2
- package/dist/internal.js +8 -7
- package/dist/model-context/frame/host.d.ts +1 -1
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js +19 -4
- package/dist/model-context/frame/host.js.map +1 -1
- package/dist/model-context/frame/provider.d.ts +4 -0
- package/dist/model-context/frame/provider.d.ts.map +1 -1
- package/dist/model-context/frame/provider.js +50 -3
- package/dist/model-context/frame/provider.js.map +1 -1
- package/dist/model-context/frame/types.d.ts +4 -1
- package/dist/model-context/frame/types.d.ts.map +1 -1
- package/dist/model-context/frame/types.js.map +1 -1
- package/dist/model-context/registry.d.ts.map +1 -1
- package/dist/model-context/registry.js +16 -4
- package/dist/model-context/registry.js.map +1 -1
- package/dist/react/RuntimeAdapter.d.ts +8 -1
- package/dist/react/RuntimeAdapter.d.ts.map +1 -1
- package/dist/react/RuntimeAdapter.js +23 -18
- package/dist/react/RuntimeAdapter.js.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.js +28 -12
- package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
- package/dist/react/client/AdaptedRemoteThread.d.ts +11 -0
- package/dist/react/client/AdaptedRemoteThread.d.ts.map +1 -0
- package/dist/react/client/AdaptedRemoteThread.js +27 -0
- package/dist/react/client/AdaptedRemoteThread.js.map +1 -0
- package/dist/react/client/InMemoryThreadList.d.ts +19 -0
- package/dist/react/client/InMemoryThreadList.d.ts.map +1 -0
- package/dist/react/client/InMemoryThreadList.js +418 -0
- package/dist/react/client/InMemoryThreadList.js.map +1 -0
- package/dist/react/client/Interactables.d.ts.map +1 -1
- package/dist/react/client/Interactables.js +159 -102
- package/dist/react/client/Interactables.js.map +1 -1
- package/dist/react/client/RemoteThreadList.d.ts +34 -0
- package/dist/react/client/RemoteThreadList.d.ts.map +1 -0
- package/dist/react/client/RemoteThreadList.js +898 -0
- package/dist/react/client/RemoteThreadList.js.map +1 -0
- package/dist/react/client/Tools.d.ts.map +1 -1
- package/dist/react/client/Tools.js +38 -27
- package/dist/react/client/Tools.js.map +1 -1
- package/dist/react/index.d.ts +7 -2
- package/dist/react/index.js +5 -2
- package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
- package/dist/react/interactables-legacy/Interactables.js +145 -110
- package/dist/react/interactables-legacy/Interactables.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useActionBarCopy.js +20 -19
- package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useActionBarEdit.js +2 -4
- package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useActionBarReload.js +2 -4
- package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerNext.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerNext.js +2 -6
- package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerPrevious.js +2 -6
- package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
- package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useComposerCancel.js +2 -4
- package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
- package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useComposerSend.js +2 -4
- package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
- package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useSuggestionTrigger.js +6 -2
- package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts +3 -0
- package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsEmpty.js +3 -0
- package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +3 -0
- package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsRunning.js +3 -0
- package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -1
- package/dist/react/primitives/message/MessageParts.d.ts +13 -0
- package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageParts.js.map +1 -1
- package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
- package/dist/react/primitives/thread/ThreadMessages.js +1 -1
- package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +24 -10
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +115 -71
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +14 -2
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +232 -63
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadResource.d.ts +30 -0
- package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -0
- package/dist/react/runtimes/RemoteThreadResource.js +136 -0
- package/dist/react/runtimes/RemoteThreadResource.js.map +1 -0
- package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +3 -10
- package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
- package/dist/react/runtimes/RuntimeAdapterProvider.js +3 -6
- package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -1
- package/dist/react/runtimes/assistant-transport/commandQueue.d.ts +17 -0
- package/dist/react/runtimes/assistant-transport/commandQueue.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/commandQueue.js +55 -0
- package/dist/react/runtimes/assistant-transport/commandQueue.js.map +1 -0
- package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts +11 -0
- package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js +165 -0
- package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js.map +1 -0
- package/dist/react/runtimes/assistant-transport/runManager.d.ts +15 -0
- package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/runManager.js +86 -0
- package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -0
- package/dist/react/runtimes/assistant-transport/types.d.ts +130 -0
- package/dist/react/runtimes/assistant-transport/types.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/types.js +0 -0
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts +14 -0
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +296 -0
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -0
- package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts +7 -0
- package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/useConvertedState.js +25 -0
- package/dist/react/runtimes/assistant-transport/useConvertedState.js.map +1 -0
- package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts +7 -0
- package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/useLatestRef.js +27 -0
- package/dist/react/runtimes/assistant-transport/useLatestRef.js.map +1 -0
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +39 -13
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +2 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +3 -3
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.d.ts +4 -0
- package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.js +7 -0
- package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +60 -17
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts +16 -0
- package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js +36 -0
- package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -0
- package/dist/react/runtimes/external-message-converter.js +14 -14
- package/dist/react/runtimes/external-message-converter.js.map +1 -1
- package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -1
- package/dist/react/runtimes/useExternalStoreRuntime.js +44 -28
- package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
- package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
- package/dist/react/runtimes/useLocalRuntime.js +1 -1
- package/dist/react/runtimes/useRuntimeAdapters.d.ts +9 -0
- package/dist/react/runtimes/useRuntimeAdapters.d.ts.map +1 -0
- package/dist/react/runtimes/useRuntimeAdapters.js +20 -0
- package/dist/react/runtimes/useRuntimeAdapters.js.map +1 -0
- package/dist/runtime/api/composer-runtime.d.ts +5 -0
- package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
- package/dist/runtime/api/composer-runtime.js.map +1 -1
- package/dist/runtime/api/message-runtime.js +1 -1
- package/dist/runtime/api/thread-list-runtime.d.ts +1 -0
- package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-runtime.js +4 -2
- package/dist/runtime/api/thread-list-runtime.js.map +1 -1
- package/dist/runtime/api/thread-runtime.d.ts +12 -2
- package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-runtime.js +8 -2
- package/dist/runtime/api/thread-runtime.js.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.js +8 -7
- package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts +1 -0
- package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.js +3 -3
- package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +0 -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 +10 -4
- package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
- package/dist/runtime/interfaces/thread-runtime-core.d.ts +6 -0
- package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/internal.js +5 -5
- package/dist/runtime/queue/message-queue.d.ts.map +1 -1
- package/dist/runtime/queue/message-queue.js +2 -1
- package/dist/runtime/queue/message-queue.js.map +1 -1
- package/dist/runtime/utils/message-repository.d.ts.map +1 -1
- package/dist/runtime/utils/message-repository.js +27 -18
- package/dist/runtime/utils/message-repository.js.map +1 -1
- package/dist/runtime/utils/thread-runtime-lifecycle.d.ts +8 -0
- package/dist/runtime/utils/thread-runtime-lifecycle.d.ts.map +1 -0
- package/dist/runtime/utils/thread-runtime-lifecycle.js +11 -0
- package/dist/runtime/utils/thread-runtime-lifecycle.js.map +1 -0
- package/dist/runtimes/external-store/external-store-shared-options.js.map +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 +4 -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 +8 -0
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js +37 -13
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +102 -0
- package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -0
- package/dist/runtimes/inert/InertThreadRuntimeCore.js +156 -0
- package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -0
- package/dist/runtimes/internal.d.ts +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 +78 -19
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +12 -59
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +10 -142
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
- package/dist/runtimes/remote-thread-list/adapter-changed.d.ts +9 -0
- package/dist/runtimes/remote-thread-list/adapter-changed.d.ts.map +1 -0
- package/dist/runtimes/remote-thread-list/adapter-changed.js +13 -0
- package/dist/runtimes/remote-thread-list/adapter-changed.js.map +1 -0
- package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/empty-thread-core.js +16 -152
- package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +2 -0
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.js +11 -0
- package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
- package/dist/runtimes/remote-thread-list/types.d.ts +32 -1
- package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +1 -12
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +67 -38
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
- package/dist/store/clients/external-thread.js +1 -1
- package/dist/store/clients/external-thread.js.map +1 -1
- package/dist/store/clients/suggestions.js +2 -2
- package/dist/store/clients/suggestions.js.map +1 -1
- package/dist/store/clients/thread-selection-events.d.ts +10 -0
- package/dist/store/clients/thread-selection-events.d.ts.map +1 -0
- package/dist/store/clients/thread-selection-events.js +40 -0
- package/dist/store/clients/thread-selection-events.js.map +1 -0
- package/dist/store/env.d.ts +5 -0
- package/dist/store/env.d.ts.map +1 -0
- package/dist/store/env.js +12 -0
- package/dist/store/env.js.map +1 -0
- package/dist/store/index.d.ts +5 -3
- package/dist/store/index.js +4 -2
- package/dist/store/internal.d.ts +4 -1
- package/dist/store/internal.js +4 -1
- package/dist/store/primitive-predicates.d.ts +19 -0
- package/dist/store/primitive-predicates.d.ts.map +1 -0
- package/dist/store/primitive-predicates.js +19 -0
- package/dist/store/primitive-predicates.js.map +1 -0
- package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/attachment-runtime-client.js +18 -11
- package/dist/store/runtime-clients/attachment-runtime-client.js.map +1 -1
- package/dist/store/runtime-clients/handle-runtime-action.d.ts +5 -0
- package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -0
- package/dist/store/runtime-clients/handle-runtime-action.js +14 -0
- package/dist/store/runtime-clients/handle-runtime-action.js.map +1 -0
- package/dist/store/runtime-clients/handle-thread-list-action.d.ts +5 -0
- package/dist/store/runtime-clients/handle-thread-list-action.d.ts.map +1 -0
- package/dist/store/runtime-clients/handle-thread-list-action.js +7 -0
- package/dist/store/runtime-clients/handle-thread-list-action.js.map +1 -0
- package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-list-item-runtime-client.js +62 -29
- package/dist/store/runtime-clients/thread-list-item-runtime-client.js.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 +5 -6
- package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
- package/dist/store/scopes/composer.d.ts +9 -4
- package/dist/store/scopes/composer.d.ts.map +1 -1
- package/dist/store/scopes/thread-list-item.d.ts +7 -6
- package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
- package/dist/store/scopes/thread.d.ts +8 -7
- package/dist/store/scopes/thread.d.ts.map +1 -1
- package/dist/store/scopes/threads.d.ts +17 -1
- package/dist/store/scopes/threads.d.ts.map +1 -1
- package/dist/subscribable/subscribable.d.ts +2 -1
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/subscribable/subscribable.js +23 -18
- package/dist/subscribable/subscribable.js.map +1 -1
- package/dist/types/message.d.ts +1 -1
- package/dist/types/message.js.map +1 -1
- package/dist/utils/composite-context-provider.d.ts +1 -0
- package/dist/utils/composite-context-provider.d.ts.map +1 -1
- package/dist/utils/composite-context-provider.js +25 -9
- package/dist/utils/composite-context-provider.js.map +1 -1
- package/dist/utils/notify-event-listeners.d.ts +2 -2
- package/dist/utils/notify-event-listeners.d.ts.map +1 -1
- package/dist/utils/notify-event-listeners.js +2 -2
- package/dist/utils/notify-event-listeners.js.map +1 -1
- package/dist/utils/silent-runtime-action.d.ts +6 -0
- package/dist/utils/silent-runtime-action.d.ts.map +1 -0
- package/dist/utils/silent-runtime-action.js +7 -0
- package/dist/utils/silent-runtime-action.js.map +1 -0
- package/package.json +8 -8
- package/src/adapters/speech.test.ts +118 -1
- package/src/adapters/speech.ts +21 -22
- package/src/adapters/thread-history.ts +2 -0
- package/src/adapters/voice.test.ts +134 -0
- package/src/adapters/voice.ts +35 -27
- package/src/index.ts +1 -0
- package/src/internal.ts +1 -0
- package/src/model-context/frame/host.test.ts +87 -5
- package/src/model-context/frame/host.ts +18 -4
- package/src/model-context/frame/provider.test.ts +347 -20
- package/src/model-context/frame/provider.ts +58 -2
- package/src/model-context/frame/types.ts +5 -0
- package/src/model-context/registry.test.ts +131 -0
- package/src/model-context/registry.ts +16 -6
- package/src/react/RuntimeAdapter.test.ts +2 -0
- package/src/react/RuntimeAdapter.ts +20 -8
- package/src/react/adapters/LocalStorageThreadListAdapter.tsx +34 -17
- package/src/react/client/AdaptedRemoteThread.ts +41 -0
- package/src/react/client/InMemoryThreadList.test.tsx +148 -0
- package/src/react/client/InMemoryThreadList.ts +290 -0
- package/src/react/client/Interactables.test.ts +326 -2
- package/src/react/client/Interactables.ts +227 -110
- package/src/react/client/RemoteThreadList.test.ts +1222 -0
- package/src/react/client/RemoteThreadList.ts +1136 -0
- package/src/react/client/Tools.ts +36 -29
- package/src/react/index.ts +13 -0
- package/src/react/interactables-legacy/Interactables.test.ts +317 -0
- package/src/react/interactables-legacy/Interactables.ts +204 -128
- package/src/react/primitive-hooks/useActionBarCopy.test.ts +15 -0
- package/src/react/primitive-hooks/useActionBarCopy.ts +15 -10
- package/src/react/primitive-hooks/useActionBarEdit.ts +2 -1
- package/src/react/primitive-hooks/useActionBarReload.ts +2 -6
- package/src/react/primitive-hooks/useBranchPickerNext.ts +2 -7
- package/src/react/primitive-hooks/useBranchPickerPrevious.ts +2 -7
- package/src/react/primitive-hooks/useComposerCancel.ts +2 -1
- package/src/react/primitive-hooks/useComposerSend.ts +2 -5
- package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +11 -0
- package/src/react/primitive-hooks/useSuggestionTrigger.ts +4 -5
- package/src/react/primitive-hooks/useThreadIsEmpty.ts +3 -0
- package/src/react/primitive-hooks/useThreadIsRunning.ts +3 -0
- package/src/react/primitives/message/MessageParts.tsx +0 -1
- package/src/react/primitives/thread/ThreadMessages.tsx +2 -1
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.retry.test.tsx +116 -0
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +1 -1
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +57 -6
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.title.test.tsx +272 -0
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +171 -124
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.republish.test.ts +87 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +327 -83
- package/src/react/runtimes/RemoteThreadResource.test.ts +141 -0
- package/src/react/runtimes/RemoteThreadResource.ts +233 -0
- package/src/react/runtimes/RuntimeAdapterProvider.tsx +8 -20
- package/src/react/runtimes/assistant-transport/commandQueue.ts +68 -0
- package/src/react/runtimes/assistant-transport/replayBoundaryStream.test.ts +455 -0
- package/src/react/runtimes/assistant-transport/replayBoundaryStream.ts +172 -0
- package/src/react/runtimes/assistant-transport/runManager.ts +124 -0
- package/src/react/runtimes/assistant-transport/transport-delivery.test.tsx +79 -0
- package/src/react/runtimes/assistant-transport/transport-parentid.test.tsx +97 -0
- package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +414 -0
- package/src/react/runtimes/assistant-transport/types.ts +170 -0
- package/src/react/runtimes/assistant-transport/useAssistantTransport.spec.md +141 -0
- package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +683 -0
- package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +483 -0
- package/src/react/runtimes/assistant-transport/useConvertedState.ts +20 -0
- package/src/react/runtimes/assistant-transport/useLatestRef.ts +9 -0
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +131 -6
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +61 -15
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +6 -4
- package/src/react/runtimes/cloud/auiV0.ts +17 -1
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +98 -3
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +104 -27
- package/src/react/runtimes/cloud/useCloudThreadListRuntime.test.tsx +56 -0
- package/src/react/runtimes/cloud/useCloudThreadListRuntime.ts +31 -0
- package/src/react/runtimes/external-message-converter.test.ts +143 -0
- package/src/react/runtimes/external-message-converter.ts +41 -41
- package/src/react/runtimes/remote-thread-hook-on-tap.test.ts +58 -0
- package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +83 -0
- package/src/react/runtimes/useExternalStoreRuntime.suggestions.test.tsx +13 -3
- package/src/react/runtimes/useExternalStoreRuntime.ts +7 -0
- package/src/react/runtimes/useExternalStoreSharedOptions.ts +3 -1
- package/src/react/runtimes/useLocalRuntime.test.tsx +134 -8
- package/src/react/runtimes/useRuntimeAdapters.test.tsx +62 -0
- package/src/react/runtimes/useRuntimeAdapters.ts +28 -0
- package/src/runtime/api/composer-runtime.ts +5 -0
- package/src/runtime/api/thread-list-runtime.ts +3 -1
- package/src/runtime/api/thread-runtime.ts +20 -2
- package/src/runtime/base/base-composer-runtime-core.ts +6 -5
- package/src/runtime/base/base-thread-runtime-core.test.ts +191 -0
- package/src/runtime/base/base-thread-runtime-core.ts +11 -2
- package/src/runtime/base/default-thread-composer-runtime-core.ts +12 -4
- package/src/runtime/interfaces/thread-runtime-core.ts +6 -0
- package/src/runtime/queue/message-queue.ts +2 -1
- package/src/runtime/utils/message-repository.ts +26 -18
- package/src/runtime/utils/thread-runtime-lifecycle.ts +18 -0
- package/src/runtimes/external-store/external-store-shared-options.ts +3 -1
- 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 +103 -34
- package/src/runtimes/inert/InertThreadRuntimeCore.test.ts +253 -0
- package/src/runtimes/inert/InertThreadRuntimeCore.ts +232 -0
- package/src/runtimes/local/local-thread-runtime-core.test.ts +692 -4
- package/src/runtimes/local/local-thread-runtime-core.ts +117 -22
- package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +17 -205
- package/src/runtimes/remote-thread-list/adapter-changed.ts +10 -0
- package/src/runtimes/remote-thread-list/empty-thread-core.ts +28 -217
- package/src/runtimes/remote-thread-list/optimistic-state.test.ts +18 -0
- package/src/runtimes/remote-thread-list/optimistic-state.ts +13 -0
- package/src/runtimes/remote-thread-list/types.ts +34 -0
- package/src/runtimes/tool-invocations/EDGE_CASES.md +17 -6
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +243 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +127 -61
- package/src/store/clients/external-thread.ts +1 -1
- package/src/store/clients/model-context-client.test.ts +16 -8
- package/src/store/clients/suggestions.ts +2 -2
- package/src/store/clients/thread-selection-events.ts +21 -0
- package/src/store/env.ts +11 -0
- package/src/store/index.ts +14 -1
- package/src/store/internal.ts +13 -0
- package/src/store/primitive-predicates.test.ts +184 -0
- package/src/store/primitive-predicates.ts +43 -0
- package/src/store/runtime-clients/attachment-runtime-client.test.ts +41 -0
- package/src/store/runtime-clients/attachment-runtime-client.ts +2 -1
- package/src/store/runtime-clients/handle-runtime-action.test.ts +40 -0
- package/src/store/runtime-clients/handle-runtime-action.ts +14 -0
- package/src/store/runtime-clients/handle-thread-list-action.test.ts +69 -0
- package/src/store/runtime-clients/handle-thread-list-action.ts +6 -0
- package/src/store/runtime-clients/thread-list-item-runtime-client.ts +15 -7
- package/src/store/runtime-clients/thread-list-runtime-client.ts +9 -6
- package/src/store/scopes/composer.ts +9 -4
- package/src/store/scopes/thread-list-item.ts +7 -6
- package/src/store/scopes/thread.ts +8 -7
- package/src/store/scopes/threads.ts +14 -0
- package/src/subscribable/subscribable.test.ts +77 -1
- package/src/subscribable/subscribable.ts +38 -23
- package/src/tests/MessageRepository.test.ts +48 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +2 -2
- package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +8 -6
- package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-unarchive.test.ts +25 -0
- package/src/tests/auiV0Encode.test.ts +66 -0
- package/src/tests/base-composer-runtime-core-send.test.ts +30 -0
- package/src/tests/base-composer-runtime-core.test.ts +28 -0
- package/src/tests/composer-can-cancel.test.ts +101 -0
- package/src/tests/empty-thread-core.test.ts +6 -0
- package/src/tests/external-store-thread-list-runtime-core.test.ts +101 -0
- package/src/tests/external-store-thread-runtime-core-adapter.test.ts +211 -1
- package/src/tests/external-store-thread-runtime-core.test.ts +124 -0
- package/src/tests/external-thread-isEmpty.test.tsx +100 -0
- package/src/tests/interactables-toolui-migration.test.tsx +66 -0
- package/src/tests/message-queue.test.ts +28 -0
- package/src/tests/remote-thread-list-adapter-switch.test.ts +383 -0
- package/src/tests/session-reset-notification.test.ts +145 -0
- package/src/tests/thread-switch-events.test.tsx +99 -1
- package/src/tests/tools-scope-migration.test.tsx +58 -0
- package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +67 -0
- package/src/types/message.ts +1 -1
- package/src/utils/composite-context-provider.test.ts +139 -0
- package/src/utils/composite-context-provider.ts +26 -8
- package/src/utils/notify-event-listeners.ts +10 -5
- package/src/utils/silent-runtime-action.ts +6 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { AssistantState } from "@assistant-ui/store";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Disabled predicates shared by every binding's primitive layer. Each binding
|
|
5
|
+
* consumes these as state selectors so the disabled semantics of a primitive
|
|
6
|
+
* cannot drift between frameworks.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export const composerSendDisabled = (s: AssistantState): boolean =>
|
|
10
|
+
!s.composer.canSend || (s.thread.isRunning && !s.thread.capabilities.queue);
|
|
11
|
+
|
|
12
|
+
export const composerCancelDisabled = (s: AssistantState): boolean =>
|
|
13
|
+
!s.composer.canCancel;
|
|
14
|
+
|
|
15
|
+
export const composerInputDisabled = (s: AssistantState): boolean =>
|
|
16
|
+
s.thread.isDisabled || s.composer.dictation?.inputDisabled === true;
|
|
17
|
+
|
|
18
|
+
export const actionBarEditDisabled = (s: AssistantState): boolean =>
|
|
19
|
+
s.composer.isEditing;
|
|
20
|
+
|
|
21
|
+
export const actionBarReloadDisabled = (s: AssistantState): boolean =>
|
|
22
|
+
s.thread.isRunning || s.thread.isDisabled || s.message.role !== "assistant";
|
|
23
|
+
|
|
24
|
+
export const actionBarCopyDisabled = (s: AssistantState): boolean =>
|
|
25
|
+
!(
|
|
26
|
+
(s.message.role !== "assistant" || s.message.status?.type !== "running") &&
|
|
27
|
+
s.message.parts.some((part) => part.type === "text" && part.text.length > 0)
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export const branchPickerPreviousDisabled = (s: AssistantState): boolean =>
|
|
31
|
+
s.message.branchNumber <= 1 ||
|
|
32
|
+
(s.thread.isRunning && !s.thread.capabilities.switchBranchDuringRun);
|
|
33
|
+
|
|
34
|
+
export const branchPickerNextDisabled = (s: AssistantState): boolean =>
|
|
35
|
+
s.message.branchNumber >= s.message.branchCount ||
|
|
36
|
+
(s.thread.isRunning && !s.thread.capabilities.switchBranchDuringRun);
|
|
37
|
+
|
|
38
|
+
export const suggestionTriggerDisabled = (
|
|
39
|
+
s: AssistantState,
|
|
40
|
+
send: boolean,
|
|
41
|
+
): boolean =>
|
|
42
|
+
s.thread.isDisabled ||
|
|
43
|
+
(send && s.thread.isRunning && !s.thread.capabilities.queue);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createTapRoot, useResource } from "@assistant-ui/tap";
|
|
2
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
3
|
+
import type { AttachmentRuntime } from "../../runtime/api/attachment-runtime";
|
|
4
|
+
import { AttachmentRuntimeClient } from "./attachment-runtime-client";
|
|
5
|
+
|
|
6
|
+
describe("AttachmentRuntimeClient", () => {
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
vi.restoreAllMocks();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("reports attachment removal failures", async () => {
|
|
12
|
+
const error = new Error("storage unavailable");
|
|
13
|
+
const consoleError = vi
|
|
14
|
+
.spyOn(console, "error")
|
|
15
|
+
.mockImplementation(() => {});
|
|
16
|
+
const state = {
|
|
17
|
+
id: "attachment-1",
|
|
18
|
+
type: "file",
|
|
19
|
+
name: "notes.txt",
|
|
20
|
+
status: { type: "complete" },
|
|
21
|
+
content: [],
|
|
22
|
+
source: "thread-composer",
|
|
23
|
+
};
|
|
24
|
+
const runtime = {
|
|
25
|
+
getState: () => state,
|
|
26
|
+
subscribe: () => () => {},
|
|
27
|
+
remove: () => Promise.reject(error),
|
|
28
|
+
} as unknown as AttachmentRuntime;
|
|
29
|
+
const root = createTapRoot(function AttachmentClientRoot() {
|
|
30
|
+
return useResource(AttachmentRuntimeClient({ runtime }));
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await expect(root.getValue().remove()).rejects.toBe(error);
|
|
34
|
+
|
|
35
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
36
|
+
"[assistant-ui] attachment remove failed:",
|
|
37
|
+
error,
|
|
38
|
+
);
|
|
39
|
+
root.unmount();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { resource } from "@assistant-ui/tap";
|
|
2
2
|
import type { ClientOutput } from "@assistant-ui/store";
|
|
3
3
|
import type { AttachmentRuntime } from "../../runtime/api/attachment-runtime";
|
|
4
|
+
import { handleRuntimeAction } from "./handle-runtime-action";
|
|
4
5
|
import { useSubscribable } from "./useSubscribable";
|
|
5
6
|
|
|
6
7
|
const useAttachmentRuntimeClient = ({
|
|
@@ -12,7 +13,7 @@ const useAttachmentRuntimeClient = ({
|
|
|
12
13
|
|
|
13
14
|
return {
|
|
14
15
|
getState: () => state,
|
|
15
|
-
remove: runtime.remove,
|
|
16
|
+
remove: () => handleRuntimeAction("attachment remove", runtime.remove),
|
|
16
17
|
__internal_getRuntime: () => runtime,
|
|
17
18
|
};
|
|
18
19
|
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { ThreadListAdapterChangedError } from "../../runtimes/remote-thread-list/adapter-changed";
|
|
3
|
+
import { handleRuntimeAction } from "./handle-runtime-action";
|
|
4
|
+
|
|
5
|
+
describe("handleRuntimeAction", () => {
|
|
6
|
+
it("does not log a silent adapter-change cancellation", async () => {
|
|
7
|
+
const error = new ThreadListAdapterChangedError();
|
|
8
|
+
const consoleError = vi
|
|
9
|
+
.spyOn(console, "error")
|
|
10
|
+
.mockImplementation(() => {});
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
await expect(
|
|
14
|
+
handleRuntimeAction("thread list archive", () => Promise.reject(error)),
|
|
15
|
+
).rejects.toBe(error);
|
|
16
|
+
expect(consoleError).not.toHaveBeenCalled();
|
|
17
|
+
} finally {
|
|
18
|
+
consoleError.mockRestore();
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("logs an ordinary rejection", async () => {
|
|
23
|
+
const error = new Error("archive failed");
|
|
24
|
+
const consoleError = vi
|
|
25
|
+
.spyOn(console, "error")
|
|
26
|
+
.mockImplementation(() => {});
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
await expect(
|
|
30
|
+
handleRuntimeAction("thread list archive", () => Promise.reject(error)),
|
|
31
|
+
).rejects.toBe(error);
|
|
32
|
+
expect(consoleError).toHaveBeenCalledExactlyOnceWith(
|
|
33
|
+
"[assistant-ui] thread list archive failed:",
|
|
34
|
+
error,
|
|
35
|
+
);
|
|
36
|
+
} finally {
|
|
37
|
+
consoleError.mockRestore();
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { isSilentRuntimeAction } from "../../utils/silent-runtime-action";
|
|
2
|
+
|
|
3
|
+
export const handleRuntimeAction = (
|
|
4
|
+
label: string,
|
|
5
|
+
execute: () => Promise<void>,
|
|
6
|
+
): Promise<void> => {
|
|
7
|
+
const task = execute();
|
|
8
|
+
|
|
9
|
+
void task.catch((error: unknown) => {
|
|
10
|
+
if (isSilentRuntimeAction(error)) return;
|
|
11
|
+
console.error(`[assistant-ui] ${label} failed:`, error);
|
|
12
|
+
});
|
|
13
|
+
return task;
|
|
14
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { handleThreadListAction } from "./handle-thread-list-action";
|
|
3
|
+
|
|
4
|
+
describe("handleThreadListAction", () => {
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
vi.restoreAllMocks();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it("reports a rejected task", async () => {
|
|
10
|
+
const error = new Error("unavailable");
|
|
11
|
+
const task = Promise.reject(error);
|
|
12
|
+
const consoleError = vi
|
|
13
|
+
.spyOn(console, "error")
|
|
14
|
+
.mockImplementation(() => {});
|
|
15
|
+
|
|
16
|
+
const result = handleThreadListAction("delete", () => task);
|
|
17
|
+
|
|
18
|
+
expect(result).toBe(task);
|
|
19
|
+
await expect(result).rejects.toBe(error);
|
|
20
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
21
|
+
"[assistant-ui] thread list delete failed:",
|
|
22
|
+
error,
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("preserves synchronous failures", () => {
|
|
27
|
+
const error = new Error("invalid thread");
|
|
28
|
+
const consoleError = vi
|
|
29
|
+
.spyOn(console, "error")
|
|
30
|
+
.mockImplementation(() => {});
|
|
31
|
+
|
|
32
|
+
expect(() =>
|
|
33
|
+
handleThreadListAction("switch", () => {
|
|
34
|
+
throw error;
|
|
35
|
+
}),
|
|
36
|
+
).toThrow(error);
|
|
37
|
+
expect(consoleError).not.toHaveBeenCalled();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("does not leak an ignored action as an unhandled rejection", async () => {
|
|
41
|
+
const error = new Error("delete failed");
|
|
42
|
+
const consoleError = vi
|
|
43
|
+
.spyOn(console, "error")
|
|
44
|
+
.mockImplementation(() => {});
|
|
45
|
+
const rejections: unknown[] = [];
|
|
46
|
+
const onUnhandledRejection = (reason: unknown) => {
|
|
47
|
+
rejections.push(reason);
|
|
48
|
+
};
|
|
49
|
+
const priorListeners = process.listeners("unhandledRejection");
|
|
50
|
+
process.removeAllListeners("unhandledRejection");
|
|
51
|
+
process.on("unhandledRejection", onUnhandledRejection);
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
handleThreadListAction("delete", () => Promise.reject(error));
|
|
55
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
56
|
+
} finally {
|
|
57
|
+
process.removeListener("unhandledRejection", onUnhandledRejection);
|
|
58
|
+
for (const listener of priorListeners) {
|
|
59
|
+
process.on("unhandledRejection", listener);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
expect(rejections).toEqual([]);
|
|
64
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
65
|
+
"[assistant-ui] thread list delete failed:",
|
|
66
|
+
error,
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -4,6 +4,7 @@ import type { ClientOutput } from "@assistant-ui/store";
|
|
|
4
4
|
import { useAssistantEmit } from "@assistant-ui/store/client";
|
|
5
5
|
import type { ThreadListItemRuntime } from "../../runtime/api/thread-list-item-runtime";
|
|
6
6
|
import { useSubscribable } from "./useSubscribable";
|
|
7
|
+
import { handleThreadListAction } from "./handle-thread-list-action";
|
|
7
8
|
|
|
8
9
|
const useThreadListItemClient = ({
|
|
9
10
|
runtime,
|
|
@@ -39,13 +40,20 @@ const useThreadListItemClient = ({
|
|
|
39
40
|
|
|
40
41
|
return {
|
|
41
42
|
getState: () => state,
|
|
42
|
-
switchTo:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
switchTo: (options) =>
|
|
44
|
+
handleThreadListAction("switch", () => runtime.switchTo(options)),
|
|
45
|
+
rename: (newTitle) =>
|
|
46
|
+
handleThreadListAction("rename", () => runtime.rename(newTitle)),
|
|
47
|
+
updateCustom: (custom) =>
|
|
48
|
+
handleThreadListAction("update custom metadata", () =>
|
|
49
|
+
runtime.updateCustom(custom),
|
|
50
|
+
),
|
|
51
|
+
archive: () => handleThreadListAction("archive", () => runtime.archive()),
|
|
52
|
+
unarchive: () =>
|
|
53
|
+
handleThreadListAction("unarchive", () => runtime.unarchive()),
|
|
54
|
+
delete: () => handleThreadListAction("delete", () => runtime.delete()),
|
|
55
|
+
generateTitle: () =>
|
|
56
|
+
handleThreadListAction("generate title", () => runtime.generateTitle()),
|
|
49
57
|
initialize: runtime.initialize,
|
|
50
58
|
detach: runtime.detach,
|
|
51
59
|
__internal_getRuntime: () => runtime,
|
|
@@ -2,12 +2,14 @@ import { useMemo } from "react";
|
|
|
2
2
|
import { useResource, withKey, resource } from "@assistant-ui/tap";
|
|
3
3
|
import type { ClientOutput } from "@assistant-ui/store";
|
|
4
4
|
import { useClientLookup, useClientResource } from "@assistant-ui/store/client";
|
|
5
|
+
import { useThreadSelectionEvents } from "../clients/thread-selection-events";
|
|
5
6
|
import type { ThreadListRuntime } from "../../runtime/api/thread-list-runtime";
|
|
6
7
|
import type { AssistantRuntime } from "../../runtime/api/assistant-runtime";
|
|
7
8
|
import { useSubscribable } from "./useSubscribable";
|
|
8
9
|
import { ThreadListItemClient } from "./thread-list-item-runtime-client";
|
|
9
10
|
import { ThreadClient } from "./thread-runtime-client";
|
|
10
11
|
import type { ThreadsState } from "../scopes/threads";
|
|
12
|
+
import { handleThreadListAction } from "./handle-thread-list-action";
|
|
11
13
|
|
|
12
14
|
const useThreadListItemClientById = ({
|
|
13
15
|
runtime,
|
|
@@ -40,6 +42,7 @@ const useThreadListClient = ({
|
|
|
40
42
|
__internal_assistantRuntime: AssistantRuntime;
|
|
41
43
|
}): ClientOutput<"threads"> => {
|
|
42
44
|
const runtimeState = useSubscribable(runtime);
|
|
45
|
+
useThreadSelectionEvents(runtimeState.mainThreadId);
|
|
43
46
|
|
|
44
47
|
const main = useClientResource(
|
|
45
48
|
ThreadClient({
|
|
@@ -93,12 +96,12 @@ const useThreadListClient = ({
|
|
|
93
96
|
: state.threadIds[index]!;
|
|
94
97
|
return threadItems.get({ key: id });
|
|
95
98
|
},
|
|
96
|
-
switchToThread:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
switchToThread: (threadId, options) =>
|
|
100
|
+
handleThreadListAction("switch", () =>
|
|
101
|
+
runtime.switchToThread(threadId, options),
|
|
102
|
+
),
|
|
103
|
+
switchToNewThread: () =>
|
|
104
|
+
handleThreadListAction("create", () => runtime.switchToNewThread()),
|
|
102
105
|
getLoadThreadsPromise: () => runtime.getLoadThreadsPromise(),
|
|
103
106
|
reload: () => runtime.reload(),
|
|
104
107
|
reloadMainThread: () => runtime.reloadMainThread(),
|
|
@@ -27,6 +27,11 @@ export type ComposerState = {
|
|
|
27
27
|
readonly attachments: readonly Attachment[];
|
|
28
28
|
readonly runConfig: RunConfig;
|
|
29
29
|
readonly isEditing: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Whether the composer can cancel the current run. `true` when the runtime
|
|
32
|
+
* supports cancel and a run is in flight, not merely when cancel is a
|
|
33
|
+
* capability.
|
|
34
|
+
*/
|
|
30
35
|
readonly canCancel: boolean;
|
|
31
36
|
/**
|
|
32
37
|
* Whether the composer is currently willing to send. `true` when the
|
|
@@ -104,13 +109,13 @@ export type ComposerMeta = {
|
|
|
104
109
|
|
|
105
110
|
export type ComposerEvents = {
|
|
106
111
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
112
|
+
* The user sent the composer contents. `messageId` is set when the send
|
|
113
|
+
* came from an edit composer.
|
|
109
114
|
*/
|
|
110
115
|
"composer.send": { threadId: string; messageId?: string };
|
|
111
116
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
117
|
+
* An attachment was added to the composer. `messageId` is set when the
|
|
118
|
+
* attachment was added to an edit composer.
|
|
114
119
|
*/
|
|
115
120
|
"composer.attachmentAdd": { threadId: string; messageId?: string };
|
|
116
121
|
"composer.attachmentAddError": {
|
|
@@ -42,15 +42,16 @@ export type ThreadListItemMeta = {
|
|
|
42
42
|
|
|
43
43
|
export type ThreadListItemEvents = {
|
|
44
44
|
/**
|
|
45
|
-
* @deprecated
|
|
46
|
-
*
|
|
47
|
-
*
|
|
45
|
+
* @deprecated Use `threads.selectionChanged` instead; its `threadId` is the
|
|
46
|
+
* newly selected thread. Inside a per-item `threadListItem` scope, filter by
|
|
47
|
+
* `threadId === threadListItem.id` to reproduce the per-item delivery. Kept
|
|
48
|
+
* for backward compatibility.
|
|
48
49
|
*/
|
|
49
50
|
"threadListItem.switchedTo": { threadId: string };
|
|
50
51
|
/**
|
|
51
|
-
* @deprecated
|
|
52
|
-
*
|
|
53
|
-
* compatibility.
|
|
52
|
+
* @deprecated Use `threads.selectionChanged` instead; its
|
|
53
|
+
* `previousThreadId` is the thread that was switched away from. Kept for
|
|
54
|
+
* backward compatibility.
|
|
54
55
|
*/
|
|
55
56
|
"threadListItem.switchedAway": { threadId: string };
|
|
56
57
|
};
|
|
@@ -145,19 +145,20 @@ export type ThreadMeta = {
|
|
|
145
145
|
|
|
146
146
|
export type ThreadEvents = {
|
|
147
147
|
/**
|
|
148
|
-
*
|
|
149
|
-
* `
|
|
148
|
+
* A run started on this thread. Also observable as `isRunning` flipping to
|
|
149
|
+
* `true` in thread state.
|
|
150
150
|
*/
|
|
151
151
|
"thread.runStart": { threadId: string };
|
|
152
152
|
/**
|
|
153
|
-
*
|
|
154
|
-
* `
|
|
153
|
+
* A run on this thread ended, whether it completed, errored, or was
|
|
154
|
+
* cancelled. Also observable as `isRunning` flipping to `false` in thread
|
|
155
|
+
* state.
|
|
155
156
|
*/
|
|
156
157
|
"thread.runEnd": { threadId: string };
|
|
157
158
|
/**
|
|
158
|
-
*
|
|
159
|
-
* added
|
|
160
|
-
*
|
|
159
|
+
* The thread transitioned from new to initialized. Fires before the first
|
|
160
|
+
* message is added, so read thread state via `useAuiState` rather than
|
|
161
|
+
* inside this event handler.
|
|
161
162
|
*/
|
|
162
163
|
"thread.initialize": { threadId: string };
|
|
163
164
|
/**
|
|
@@ -35,6 +35,20 @@ export type ThreadsMethods = {
|
|
|
35
35
|
__internal_getAssistantRuntime?(): AssistantRuntime;
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
+
export type ThreadsEvents = {
|
|
39
|
+
/**
|
|
40
|
+
* The main thread selection changed. Fires once per switch with the newly
|
|
41
|
+
* selected thread and the thread that was selected before. Does not fire
|
|
42
|
+
* for the initially selected thread on mount. Runtimes that resolve a
|
|
43
|
+
* deep-linked `threadId`/`initialThreadId` after mount (such as
|
|
44
|
+
* `useRemoteThreadListRuntime`) start on a placeholder new thread, so the
|
|
45
|
+
* deep link's resolution fires this event with the placeholder as
|
|
46
|
+
* `previousThreadId`.
|
|
47
|
+
*/
|
|
48
|
+
"threads.selectionChanged": { threadId: string; previousThreadId: string };
|
|
49
|
+
};
|
|
50
|
+
|
|
38
51
|
export type ThreadsClientSchema = {
|
|
39
52
|
methods: ThreadsMethods;
|
|
53
|
+
events: ThreadsEvents;
|
|
40
54
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from "vitest";
|
|
2
2
|
import type { SubscribableWithState } from "./subscribable";
|
|
3
|
-
import { ShallowMemoizeSubject } from "./subscribable";
|
|
3
|
+
import { LazyMemoizeSubject, ShallowMemoizeSubject } from "./subscribable";
|
|
4
4
|
|
|
5
5
|
type TestState = {
|
|
6
6
|
status: string;
|
|
@@ -26,6 +26,9 @@ const createBinding = (initialState: TestState) => {
|
|
|
26
26
|
state = nextState;
|
|
27
27
|
for (const callback of subscribers) callback();
|
|
28
28
|
},
|
|
29
|
+
replace(nextState: TestState) {
|
|
30
|
+
state = nextState;
|
|
31
|
+
},
|
|
29
32
|
};
|
|
30
33
|
};
|
|
31
34
|
|
|
@@ -55,4 +58,77 @@ describe("ShallowMemoizeSubject", () => {
|
|
|
55
58
|
|
|
56
59
|
expect(subscriber).not.toHaveBeenCalled();
|
|
57
60
|
});
|
|
61
|
+
|
|
62
|
+
it("notifies later subscribers when one throws", () => {
|
|
63
|
+
const source = createBinding({ status: "empty" });
|
|
64
|
+
const subject = new ShallowMemoizeSubject(source.binding);
|
|
65
|
+
const error = new Error("subscriber failed");
|
|
66
|
+
const laterSubscriber = vi.fn();
|
|
67
|
+
subject.subscribe(() => {
|
|
68
|
+
throw error;
|
|
69
|
+
});
|
|
70
|
+
subject.subscribe(laterSubscriber);
|
|
71
|
+
|
|
72
|
+
expect(() => source.update({ status: "ready" })).toThrow(error);
|
|
73
|
+
expect(laterSubscriber).toHaveBeenCalledOnce();
|
|
74
|
+
expect(subject.getState()).toEqual({ status: "ready" });
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("reads a value that landed while nobody was subscribed", () => {
|
|
78
|
+
const source = createBinding({ status: "empty" });
|
|
79
|
+
const subject = new ShallowMemoizeSubject(source.binding);
|
|
80
|
+
expect(subject.getState()).toEqual({ status: "empty" });
|
|
81
|
+
|
|
82
|
+
source.update({ status: "ready" });
|
|
83
|
+
const subscriber = vi.fn();
|
|
84
|
+
subject.subscribe(subscriber);
|
|
85
|
+
|
|
86
|
+
expect(subject.getState()).toEqual({ status: "ready" });
|
|
87
|
+
expect(subscriber).not.toHaveBeenCalled();
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe("LazyMemoizeSubject", () => {
|
|
92
|
+
it("notifies later subscribers when one throws", () => {
|
|
93
|
+
const source = createBinding({ status: "empty" });
|
|
94
|
+
const subject = new LazyMemoizeSubject(source.binding);
|
|
95
|
+
const error = new Error("subscriber failed");
|
|
96
|
+
const laterSubscriber = vi.fn();
|
|
97
|
+
subject.subscribe(() => {
|
|
98
|
+
throw error;
|
|
99
|
+
});
|
|
100
|
+
subject.subscribe(laterSubscriber);
|
|
101
|
+
|
|
102
|
+
expect(() => source.update({ status: "ready" })).toThrow(error);
|
|
103
|
+
expect(laterSubscriber).toHaveBeenCalledOnce();
|
|
104
|
+
expect(subject.getState()).toEqual({ status: "ready" });
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("reads a value replaced before connecting", () => {
|
|
108
|
+
const source = createBinding({ status: "empty" });
|
|
109
|
+
const subject = new LazyMemoizeSubject(source.binding);
|
|
110
|
+
expect(subject.getState()).toEqual({ status: "empty" });
|
|
111
|
+
|
|
112
|
+
source.replace({ status: "ready" });
|
|
113
|
+
const subscriber = vi.fn();
|
|
114
|
+
const unsubscribe = subject.subscribe(subscriber);
|
|
115
|
+
|
|
116
|
+
expect(subject.getState()).toEqual({ status: "ready" });
|
|
117
|
+
expect(subscriber).not.toHaveBeenCalled();
|
|
118
|
+
unsubscribe();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("resynchronizes after reconnecting", () => {
|
|
122
|
+
const source = createBinding({ status: "empty" });
|
|
123
|
+
const subject = new LazyMemoizeSubject(source.binding);
|
|
124
|
+
expect(subject.getState()).toEqual({ status: "empty" });
|
|
125
|
+
|
|
126
|
+
const unsubscribe = subject.subscribe(() => {});
|
|
127
|
+
unsubscribe();
|
|
128
|
+
source.replace({ status: "ready" });
|
|
129
|
+
const reconnect = subject.subscribe(() => {});
|
|
130
|
+
|
|
131
|
+
expect(subject.getState()).toEqual({ status: "ready" });
|
|
132
|
+
reconnect();
|
|
133
|
+
});
|
|
58
134
|
});
|
|
@@ -32,6 +32,31 @@ export type EventSubscribable<TEvent extends string> = {
|
|
|
32
32
|
>;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
export const notifySubscribers = <TArgs extends unknown[]>(
|
|
36
|
+
subscribers: Iterable<(...args: TArgs) => void>,
|
|
37
|
+
...args: TArgs
|
|
38
|
+
): void => {
|
|
39
|
+
const errors: unknown[] = [];
|
|
40
|
+
for (const callback of subscribers) {
|
|
41
|
+
try {
|
|
42
|
+
callback(...args);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
errors.push(error);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (errors.length === 1) {
|
|
49
|
+
throw errors[0];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (errors.length > 1) {
|
|
53
|
+
for (const error of errors) {
|
|
54
|
+
console.error(error);
|
|
55
|
+
}
|
|
56
|
+
throw new AggregateError(errors);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
35
60
|
function shallowEqual<T extends object>(
|
|
36
61
|
objA: T | undefined,
|
|
37
62
|
objB: T | undefined,
|
|
@@ -70,25 +95,7 @@ export class BaseSubscribable {
|
|
|
70
95
|
}
|
|
71
96
|
|
|
72
97
|
protected _notifySubscribers() {
|
|
73
|
-
|
|
74
|
-
for (const callback of this._subscribers) {
|
|
75
|
-
try {
|
|
76
|
-
callback();
|
|
77
|
-
} catch (error) {
|
|
78
|
-
errors.push(error);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (errors.length > 0) {
|
|
83
|
-
if (errors.length === 1) {
|
|
84
|
-
throw errors[0];
|
|
85
|
-
} else {
|
|
86
|
-
for (const error of errors) {
|
|
87
|
-
console.error(error);
|
|
88
|
-
}
|
|
89
|
-
throw new AggregateError(errors);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
98
|
+
notifySubscribers(this._subscribers);
|
|
92
99
|
}
|
|
93
100
|
}
|
|
94
101
|
|
|
@@ -109,7 +116,7 @@ export abstract class BaseSubject {
|
|
|
109
116
|
return;
|
|
110
117
|
}
|
|
111
118
|
|
|
112
|
-
|
|
119
|
+
notifySubscribers(this._subscriptions, payload);
|
|
113
120
|
}
|
|
114
121
|
|
|
115
122
|
private _updateConnection() {
|
|
@@ -173,7 +180,9 @@ export class ShallowMemoizeSubject<TState extends object, TPath>
|
|
|
173
180
|
}
|
|
174
181
|
};
|
|
175
182
|
|
|
176
|
-
|
|
183
|
+
const unsubscribe = this.binding.subscribe(callback);
|
|
184
|
+
this._syncState();
|
|
185
|
+
return unsubscribe;
|
|
177
186
|
}
|
|
178
187
|
}
|
|
179
188
|
|
|
@@ -197,7 +206,11 @@ export class LazyMemoizeSubject<TState extends object, TPath>
|
|
|
197
206
|
public getState = () => {
|
|
198
207
|
if (!this.isConnected || this._previousStateDirty) {
|
|
199
208
|
const newState = this.binding.getState();
|
|
200
|
-
if (
|
|
209
|
+
if (
|
|
210
|
+
newState !== SKIP_UPDATE &&
|
|
211
|
+
(this._previousState === undefined ||
|
|
212
|
+
!shallowEqual(newState, this._previousState))
|
|
213
|
+
) {
|
|
201
214
|
this._previousState = newState;
|
|
202
215
|
}
|
|
203
216
|
this._previousStateDirty = false;
|
|
@@ -213,7 +226,9 @@ export class LazyMemoizeSubject<TState extends object, TPath>
|
|
|
213
226
|
this.notifySubscribers();
|
|
214
227
|
};
|
|
215
228
|
|
|
216
|
-
|
|
229
|
+
const unsubscribe = this.binding.subscribe(callback);
|
|
230
|
+
this._previousStateDirty = true;
|
|
231
|
+
return unsubscribe;
|
|
217
232
|
}
|
|
218
233
|
}
|
|
219
234
|
|