@assistant-ui/core 0.3.13 → 0.3.14
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 +27 -15
- package/dist/adapters/voice.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.js +6 -6
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js +2 -1
- package/dist/model-context/frame/host.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 +826 -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 +13 -18
- 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/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 +22 -10
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +109 -71
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +8 -2
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +40 -13
- 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 +134 -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 +22 -12
- 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/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 +35 -13
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- 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 +53 -13
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +1 -0
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +3 -0
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
- package/dist/runtimes/remote-thread-list/empty-thread-core.js +3 -0
- package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
- package/dist/runtimes/remote-thread-list/types.d.ts +29 -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/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 +12 -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/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/package.json +7 -7
- 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 +69 -0
- package/src/adapters/voice.ts +27 -27
- package/src/index.ts +1 -0
- package/src/model-context/frame/host.test.ts +23 -0
- package/src/model-context/frame/host.ts +2 -1
- 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 +1026 -0
- package/src/react/client/RemoteThreadList.ts +1067 -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.ts +2 -7
- 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/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 +159 -124
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +59 -20
- package/src/react/runtimes/RemoteThreadResource.test.ts +141 -0
- package/src/react/runtimes/RemoteThreadResource.ts +231 -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 +625 -0
- package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +481 -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.tsx +36 -21
- 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 +130 -4
- 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/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 +99 -34
- package/src/runtimes/local/local-thread-runtime-core.test.ts +373 -4
- package/src/runtimes/local/local-thread-runtime-core.ts +79 -14
- package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +4 -0
- package/src/runtimes/remote-thread-list/empty-thread-core.ts +4 -0
- package/src/runtimes/remote-thread-list/types.ts +30 -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/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.ts +11 -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/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/external-store-thread-list-runtime-core.test.ts +101 -0
- package/src/tests/external-store-thread-runtime-core-adapter.test.ts +191 -1
- package/src/tests/external-store-thread-runtime-core.test.ts +124 -0
- package/src/tests/interactables-toolui-migration.test.tsx +66 -0
- package/src/tests/message-queue.test.ts +28 -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/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
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
|
|
3
|
+
import { StrictMode } from "react";
|
|
4
|
+
import { act, render } from "@testing-library/react";
|
|
5
|
+
import { describe, expect, it, vi } from "vitest";
|
|
6
|
+
import { useExternalStoreRuntime } from "./useExternalStoreRuntime";
|
|
7
|
+
import type { AssistantRuntime } from "../../runtime/api/assistant-runtime";
|
|
8
|
+
|
|
9
|
+
describe("useExternalStoreRuntime lifecycle", () => {
|
|
10
|
+
it("keeps dispatching appends after StrictMode's simulated remount", async () => {
|
|
11
|
+
const onNew = vi.fn(async () => {});
|
|
12
|
+
const capture: { runtime: AssistantRuntime | null } = { runtime: null };
|
|
13
|
+
const App = () => {
|
|
14
|
+
const runtime = useExternalStoreRuntime({ messages: [], onNew });
|
|
15
|
+
capture.runtime = runtime;
|
|
16
|
+
return null;
|
|
17
|
+
};
|
|
18
|
+
render(
|
|
19
|
+
<StrictMode>
|
|
20
|
+
<App />
|
|
21
|
+
</StrictMode>,
|
|
22
|
+
);
|
|
23
|
+
expect(capture.runtime).not.toBeNull();
|
|
24
|
+
|
|
25
|
+
await act(async () => {
|
|
26
|
+
await capture.runtime!.thread.append({
|
|
27
|
+
role: "user",
|
|
28
|
+
content: [{ type: "text", text: "hello" }],
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
expect(onNew).toHaveBeenCalledTimes(1);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("dispatches an append before unmount", async () => {
|
|
36
|
+
let resolveInitialization!: () => void;
|
|
37
|
+
const initialization = new Promise<void>((resolve) => {
|
|
38
|
+
resolveInitialization = resolve;
|
|
39
|
+
});
|
|
40
|
+
const onNew = vi.fn(async () => {});
|
|
41
|
+
const capture: { runtime: AssistantRuntime | null } = { runtime: null };
|
|
42
|
+
const App = () => {
|
|
43
|
+
const runtime = useExternalStoreRuntime({ messages: [], onNew });
|
|
44
|
+
capture.runtime = runtime;
|
|
45
|
+
return null;
|
|
46
|
+
};
|
|
47
|
+
const view = render(<App />);
|
|
48
|
+
expect(capture.runtime).not.toBeNull();
|
|
49
|
+
const core = (
|
|
50
|
+
capture.runtime!.thread as unknown as {
|
|
51
|
+
__internal_threadBinding: {
|
|
52
|
+
getState(): {
|
|
53
|
+
__internal_setGetInitializePromise(
|
|
54
|
+
getPromise: () => Promise<unknown> | undefined,
|
|
55
|
+
): void;
|
|
56
|
+
append(message: unknown): Promise<void>;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
).__internal_threadBinding.getState();
|
|
61
|
+
core.__internal_setGetInitializePromise(() => initialization);
|
|
62
|
+
|
|
63
|
+
const appendPromise = core.append({
|
|
64
|
+
parentId: null,
|
|
65
|
+
sourceId: null,
|
|
66
|
+
runConfig: {},
|
|
67
|
+
role: "user",
|
|
68
|
+
content: [{ type: "text", text: "hello" }],
|
|
69
|
+
attachments: [],
|
|
70
|
+
metadata: { custom: {} },
|
|
71
|
+
createdAt: new Date(0),
|
|
72
|
+
});
|
|
73
|
+
await Promise.resolve();
|
|
74
|
+
|
|
75
|
+
expect(onNew).toHaveBeenCalledTimes(1);
|
|
76
|
+
|
|
77
|
+
view.unmount();
|
|
78
|
+
resolveInitialization();
|
|
79
|
+
|
|
80
|
+
await appendPromise;
|
|
81
|
+
expect(onNew).toHaveBeenCalledTimes(1);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -52,20 +52,30 @@ afterEach(() => {
|
|
|
52
52
|
describe("useExternalStoreRuntime suggestions scope", () => {
|
|
53
53
|
it("exposes runtime suggestions on the suggestions scope", () => {
|
|
54
54
|
render(
|
|
55
|
-
<App
|
|
55
|
+
<App
|
|
56
|
+
suggestions={[
|
|
57
|
+
{ title: "Weather", label: "in SF", prompt: "What's the weather?" },
|
|
58
|
+
{ prompt: "Help" },
|
|
59
|
+
]}
|
|
60
|
+
/>,
|
|
56
61
|
);
|
|
57
62
|
|
|
58
63
|
expect(scopeSuggestions).toEqual([
|
|
59
|
-
{ title: "
|
|
64
|
+
{ title: "Weather", label: "in SF", prompt: "What's the weather?" },
|
|
60
65
|
{ title: "Help", label: "", prompt: "Help" },
|
|
61
66
|
]);
|
|
67
|
+
expect(aui.suggestions.suggestion({ index: 0 }).getState()).toEqual({
|
|
68
|
+
title: "Weather",
|
|
69
|
+
label: "in SF",
|
|
70
|
+
prompt: "What's the weather?",
|
|
71
|
+
});
|
|
62
72
|
expect(aui.suggestions.suggestion({ index: 1 }).getState()).toEqual({
|
|
63
73
|
title: "Help",
|
|
64
74
|
label: "",
|
|
65
75
|
prompt: "Help",
|
|
66
76
|
});
|
|
67
77
|
expect(aui.thread.getState().suggestions).toEqual([
|
|
68
|
-
{
|
|
78
|
+
{ title: "Weather", label: "in SF", prompt: "What's the weather?" },
|
|
69
79
|
{ prompt: "Help" },
|
|
70
80
|
]);
|
|
71
81
|
});
|
|
@@ -5,6 +5,7 @@ import { ExternalStoreRuntimeCore } from "../../runtimes/internal";
|
|
|
5
5
|
import type { ExternalStoreAdapter } from "../../runtimes/external-store/external-store-adapter";
|
|
6
6
|
import type { AssistantRuntime } from "../../runtime/api/assistant-runtime";
|
|
7
7
|
import { AssistantRuntimeImpl } from "../../runtime/internal";
|
|
8
|
+
import { invalidateThreadRuntime } from "../../runtime/utils/thread-runtime-lifecycle";
|
|
8
9
|
import { useRuntimeAdapters } from "./RuntimeAdapterProvider";
|
|
9
10
|
|
|
10
11
|
export const useExternalStoreRuntime = <T>(
|
|
@@ -12,6 +13,12 @@ export const useExternalStoreRuntime = <T>(
|
|
|
12
13
|
): AssistantRuntime => {
|
|
13
14
|
const [runtime] = useState(() => new ExternalStoreRuntimeCore(store));
|
|
14
15
|
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
return () => {
|
|
18
|
+
invalidateThreadRuntime(runtime.threads.getMainThreadRuntimeCore());
|
|
19
|
+
};
|
|
20
|
+
}, [runtime]);
|
|
21
|
+
|
|
15
22
|
useEffect(() => {
|
|
16
23
|
runtime.setAdapter(store);
|
|
17
24
|
});
|
|
@@ -16,7 +16,9 @@ export const useExternalStoreSharedOptions = (
|
|
|
16
16
|
unstable_capabilities,
|
|
17
17
|
suggestions,
|
|
18
18
|
}) satisfies {
|
|
19
|
-
[
|
|
19
|
+
[
|
|
20
|
+
K in keyof Required<ExternalStoreSharedOptions>
|
|
21
|
+
]: ExternalStoreSharedOptions[K];
|
|
20
22
|
},
|
|
21
23
|
[isDisabled, isSendDisabled, unstable_capabilities, suggestions],
|
|
22
24
|
);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// @vitest-environment jsdom
|
|
2
2
|
|
|
3
|
-
import { render, waitFor } from "@testing-library/react";
|
|
4
|
-
import { StrictMode } from "react";
|
|
3
|
+
import { act, render, waitFor } from "@testing-library/react";
|
|
4
|
+
import { type FC, StrictMode } from "react";
|
|
5
5
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
6
6
|
import type { AssistantCloud } from "assistant-cloud";
|
|
7
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
7
8
|
import type { ChatModelAdapter } from "../../runtime/utils/chat-model-adapter";
|
|
8
9
|
import { AssistantRuntimeProvider } from "../AssistantRuntimeProvider";
|
|
9
10
|
import { useLocalRuntime } from "./useLocalRuntime";
|
|
@@ -17,13 +18,49 @@ const makeCloud = () =>
|
|
|
17
18
|
threads: {
|
|
18
19
|
list: vi.fn().mockResolvedValue({ threads: [] }),
|
|
19
20
|
},
|
|
21
|
+
files: {
|
|
22
|
+
generatePresignedUploadUrl: vi.fn().mockResolvedValue({
|
|
23
|
+
signedUrl: "https://storage.example/upload",
|
|
24
|
+
publicUrl: "https://cdn.example/file.txt",
|
|
25
|
+
}),
|
|
26
|
+
},
|
|
20
27
|
}) as unknown as AssistantCloud;
|
|
21
28
|
|
|
22
29
|
afterEach(() => {
|
|
30
|
+
vi.unstubAllGlobals();
|
|
23
31
|
vi.restoreAllMocks();
|
|
24
32
|
});
|
|
25
33
|
|
|
26
34
|
describe("useLocalRuntime", () => {
|
|
35
|
+
it("surfaces the live thread after mount without user input", async () => {
|
|
36
|
+
const auiRef: { current: ReturnType<typeof useAui> | null } = {
|
|
37
|
+
current: null,
|
|
38
|
+
};
|
|
39
|
+
const loadingRef = { current: true };
|
|
40
|
+
const Capture: FC = () => {
|
|
41
|
+
auiRef.current = useAui();
|
|
42
|
+
loadingRef.current = useAuiState((s) => s.thread.isLoading);
|
|
43
|
+
return null;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const App = () => {
|
|
47
|
+
const runtime = useLocalRuntime(chatModel, {
|
|
48
|
+
unstable_enableMessageQueue: true,
|
|
49
|
+
});
|
|
50
|
+
return (
|
|
51
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
52
|
+
<Capture />
|
|
53
|
+
</AssistantRuntimeProvider>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
render(<App />);
|
|
58
|
+
await waitFor(() => {
|
|
59
|
+
expect(loadingRef.current).toBe(false);
|
|
60
|
+
expect(auiRef.current!.thread.getState().capabilities.queue).toBe(true);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
27
64
|
it("keeps the Cloud thread list loaded across unrelated rerenders", async () => {
|
|
28
65
|
const firstCloud = makeCloud();
|
|
29
66
|
const secondCloud = makeCloud();
|
|
@@ -59,6 +96,47 @@ describe("useLocalRuntime", () => {
|
|
|
59
96
|
expect(firstCloud.threads.list).toHaveBeenCalledOnce();
|
|
60
97
|
});
|
|
61
98
|
|
|
99
|
+
it("uses the current Cloud client for attachment uploads", async () => {
|
|
100
|
+
vi.stubGlobal("fetch", vi.fn().mockResolvedValue({ ok: true }));
|
|
101
|
+
const firstCloud = makeCloud();
|
|
102
|
+
const secondCloud = makeCloud();
|
|
103
|
+
let addAttachment: ((file: File) => Promise<void>) | undefined;
|
|
104
|
+
let getAttachmentStatus: (() => unknown) | undefined;
|
|
105
|
+
|
|
106
|
+
const App = ({ cloud }: { cloud: AssistantCloud }) => {
|
|
107
|
+
const runtime = useLocalRuntime(chatModel, { cloud });
|
|
108
|
+
addAttachment = (file) => runtime.thread.composer.addAttachment(file);
|
|
109
|
+
getAttachmentStatus = () =>
|
|
110
|
+
runtime.thread.composer.getState().attachments[0]?.status;
|
|
111
|
+
return (
|
|
112
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
113
|
+
<div />
|
|
114
|
+
</AssistantRuntimeProvider>
|
|
115
|
+
);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const { rerender } = render(<App cloud={firstCloud} />);
|
|
119
|
+
|
|
120
|
+
await waitFor(() => {
|
|
121
|
+
expect(firstCloud.threads.list).toHaveBeenCalledOnce();
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
rerender(<App cloud={secondCloud} />);
|
|
125
|
+
|
|
126
|
+
await act(async () => {
|
|
127
|
+
await addAttachment!(
|
|
128
|
+
new File(["hello"], "notes.txt", { type: "text/plain" }),
|
|
129
|
+
);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
expect(firstCloud.files.generatePresignedUploadUrl).not.toHaveBeenCalled();
|
|
133
|
+
expect(secondCloud.files.generatePresignedUploadUrl).toHaveBeenCalledOnce();
|
|
134
|
+
expect(getAttachmentStatus!()).toEqual({
|
|
135
|
+
type: "requires-action",
|
|
136
|
+
reason: "composer-send",
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
62
140
|
it("handles rejected history loads", async () => {
|
|
63
141
|
const error = new Error("history unavailable");
|
|
64
142
|
const consoleError = vi
|
|
@@ -92,8 +170,56 @@ describe("useLocalRuntime", () => {
|
|
|
92
170
|
);
|
|
93
171
|
});
|
|
94
172
|
|
|
173
|
+
const loadsAfterMount = history.load.mock.calls.length;
|
|
174
|
+
const errorsAfterMount = consoleError.mock.calls.length;
|
|
175
|
+
expect(loadsAfterMount).toBeGreaterThan(0);
|
|
95
176
|
rerender(renderApp());
|
|
96
|
-
expect(history.load).toHaveBeenCalledTimes(
|
|
97
|
-
expect(consoleError).toHaveBeenCalledTimes(
|
|
177
|
+
expect(history.load).toHaveBeenCalledTimes(loadsAfterMount);
|
|
178
|
+
expect(consoleError).toHaveBeenCalledTimes(errorsAfterMount);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("exposes composer.canCancel while a run started after initial messages is in flight", async () => {
|
|
182
|
+
const hangingModel: ChatModelAdapter = {
|
|
183
|
+
async *run({ abortSignal }) {
|
|
184
|
+
await new Promise<void>((resolve) => {
|
|
185
|
+
if (abortSignal.aborted) {
|
|
186
|
+
resolve();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
abortSignal.addEventListener("abort", () => resolve(), {
|
|
190
|
+
once: true,
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
let runtime: ReturnType<typeof useLocalRuntime> | null = null;
|
|
196
|
+
const App = () => {
|
|
197
|
+
runtime = useLocalRuntime(hangingModel, {
|
|
198
|
+
initialMessages: [
|
|
199
|
+
{
|
|
200
|
+
role: "assistant",
|
|
201
|
+
content: [{ type: "text", text: "Hello" }],
|
|
202
|
+
status: { type: "complete", reason: "stop" },
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
});
|
|
206
|
+
return (
|
|
207
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
208
|
+
<div />
|
|
209
|
+
</AssistantRuntimeProvider>
|
|
210
|
+
);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
render(<App />);
|
|
214
|
+
act(() => {
|
|
215
|
+
runtime!.thread.append("Run");
|
|
216
|
+
});
|
|
217
|
+
await waitFor(() => {
|
|
218
|
+
expect(runtime!.thread.getState().isRunning).toBe(true);
|
|
219
|
+
expect(runtime!.thread.composer.getState().canCancel).toBe(true);
|
|
220
|
+
});
|
|
221
|
+
act(() => {
|
|
222
|
+
runtime!.thread.cancelRun();
|
|
223
|
+
});
|
|
98
224
|
});
|
|
99
225
|
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
|
|
3
|
+
import { renderHook } from "@testing-library/react";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
import { useStableRuntimeAdapters } from "./useRuntimeAdapters";
|
|
6
|
+
import type { RuntimeAdapters } from "../../runtimes/remote-thread-list/types";
|
|
7
|
+
import type { ThreadHistoryAdapter } from "../../adapters/thread-history";
|
|
8
|
+
|
|
9
|
+
const makeHistory = (): ThreadHistoryAdapter => ({
|
|
10
|
+
load: async () => ({ messages: [] }),
|
|
11
|
+
append: async () => {},
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
describe("useStableRuntimeAdapters", () => {
|
|
15
|
+
it("keeps the previous bag when a fresh literal is shallow-equal", () => {
|
|
16
|
+
const history = makeHistory();
|
|
17
|
+
const { result, rerender } = renderHook(
|
|
18
|
+
({ adapters }: { adapters: RuntimeAdapters | null }) =>
|
|
19
|
+
useStableRuntimeAdapters(adapters),
|
|
20
|
+
{ initialProps: { adapters: { history } } },
|
|
21
|
+
);
|
|
22
|
+
const first = result.current;
|
|
23
|
+
|
|
24
|
+
rerender({ adapters: { history } });
|
|
25
|
+
|
|
26
|
+
expect(result.current).toBe(first);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("adopts the new bag when a field changes", () => {
|
|
30
|
+
const first = makeHistory();
|
|
31
|
+
const second = makeHistory();
|
|
32
|
+
const { result, rerender } = renderHook(
|
|
33
|
+
({ adapters }: { adapters: RuntimeAdapters | null }) =>
|
|
34
|
+
useStableRuntimeAdapters(adapters),
|
|
35
|
+
{ initialProps: { adapters: { history: first } } },
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
rerender({ adapters: { history: second } });
|
|
39
|
+
|
|
40
|
+
expect(result.current?.history).toBe(second);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("moves between null and a bag", () => {
|
|
44
|
+
const history = makeHistory();
|
|
45
|
+
const { result, rerender } = renderHook(
|
|
46
|
+
({ adapters }: { adapters: RuntimeAdapters | null }) =>
|
|
47
|
+
useStableRuntimeAdapters(adapters),
|
|
48
|
+
{ initialProps: { adapters: null as RuntimeAdapters | null } },
|
|
49
|
+
);
|
|
50
|
+
expect(result.current).toBeNull();
|
|
51
|
+
|
|
52
|
+
rerender({ adapters: { history } });
|
|
53
|
+
expect(result.current?.history).toBe(history);
|
|
54
|
+
|
|
55
|
+
rerender({ adapters: null });
|
|
56
|
+
expect(result.current).toBeNull();
|
|
57
|
+
|
|
58
|
+
rerender({ adapters: {} });
|
|
59
|
+
expect(result.current).not.toBeNull();
|
|
60
|
+
expect(result.current).toEqual({});
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
import { useContextProvider } from "@assistant-ui/tap";
|
|
3
|
+
import { useShallowStable } from "@assistant-ui/store/internal";
|
|
4
|
+
import type { RuntimeAdapters } from "../../runtimes/remote-thread-list/types";
|
|
5
|
+
|
|
6
|
+
const RuntimeAdaptersContext = createContext<RuntimeAdapters | null>(null);
|
|
7
|
+
|
|
8
|
+
export const useRuntimeAdaptersProvider = <T>(
|
|
9
|
+
adapters: RuntimeAdapters | null,
|
|
10
|
+
fn: () => T,
|
|
11
|
+
): T => useContextProvider(RuntimeAdaptersContext, adapters, fn);
|
|
12
|
+
|
|
13
|
+
export const useRuntimeAdapters = () => {
|
|
14
|
+
return useContext(RuntimeAdaptersContext);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const NO_ADAPTERS: RuntimeAdapters = {};
|
|
18
|
+
|
|
19
|
+
// Both adapter faces absorb a fresh but shallow-equal bag from
|
|
20
|
+
// `unstable_useAdapters`, so a per-render literal does not churn the context.
|
|
21
|
+
export const useStableRuntimeAdapters = (
|
|
22
|
+
adapters: RuntimeAdapters | null | undefined,
|
|
23
|
+
): RuntimeAdapters | null => {
|
|
24
|
+
const stable = useShallowStable(adapters ?? NO_ADAPTERS);
|
|
25
|
+
return adapters == null ? null : stable;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export { RuntimeAdaptersContext };
|
|
@@ -42,6 +42,11 @@ export type {
|
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
type BaseComposerState = {
|
|
45
|
+
/**
|
|
46
|
+
* Whether the composer can cancel the current run. `true` when the runtime
|
|
47
|
+
* supports cancel and a run is in flight, not merely when cancel is a
|
|
48
|
+
* capability.
|
|
49
|
+
*/
|
|
45
50
|
readonly canCancel: boolean;
|
|
46
51
|
readonly canSend: boolean;
|
|
47
52
|
readonly isEditing: boolean;
|
|
@@ -114,6 +114,7 @@ export type ThreadListRuntimeCoreBinding = ThreadListRuntimeCore;
|
|
|
114
114
|
|
|
115
115
|
export class ThreadListRuntimeImpl implements ThreadListRuntime {
|
|
116
116
|
private _getState;
|
|
117
|
+
private _stateBinding: LazyMemoizeSubject<ThreadListState, object>;
|
|
117
118
|
private _core: ThreadListRuntimeCoreBinding;
|
|
118
119
|
private _runtimeFactory: new (
|
|
119
120
|
binding: ThreadRuntimeCoreBinding,
|
|
@@ -136,6 +137,7 @@ export class ThreadListRuntimeImpl implements ThreadListRuntime {
|
|
|
136
137
|
});
|
|
137
138
|
|
|
138
139
|
this._getState = stateBinding.getState.bind(stateBinding);
|
|
140
|
+
this._stateBinding = stateBinding;
|
|
139
141
|
|
|
140
142
|
this._mainThreadListItemRuntime = new ThreadListItemRuntimeImpl(
|
|
141
143
|
new ShallowMemoizeSubject({
|
|
@@ -213,7 +215,7 @@ export class ThreadListRuntimeImpl implements ThreadListRuntime {
|
|
|
213
215
|
}
|
|
214
216
|
|
|
215
217
|
public subscribe(callback: () => void): Unsubscribe {
|
|
216
|
-
return this.
|
|
218
|
+
return this._stateBinding.subscribe(callback);
|
|
217
219
|
}
|
|
218
220
|
|
|
219
221
|
private _mainThreadListItemRuntime;
|
|
@@ -199,7 +199,7 @@ export type ThreadState = {
|
|
|
199
199
|
* reports it directly; the rest fall back to the trailing assistant message.
|
|
200
200
|
*/
|
|
201
201
|
export const getThreadRuntimeCoreIsRunning = (
|
|
202
|
-
runtime: ThreadRuntimeCore,
|
|
202
|
+
runtime: Pick<ThreadRuntimeCore, "isRunning" | "messages">,
|
|
203
203
|
): boolean => {
|
|
204
204
|
if (runtime.isRunning !== undefined) return runtime.isRunning;
|
|
205
205
|
const lastMessage = runtime.messages.at(-1);
|
|
@@ -294,6 +294,13 @@ export type ThreadRuntime = {
|
|
|
294
294
|
|
|
295
295
|
subscribe(callback: () => void): Unsubscribe;
|
|
296
296
|
cancelRun(): void;
|
|
297
|
+
/**
|
|
298
|
+
* Notifies the runtime that the adapter discarded its backing session.
|
|
299
|
+
* Clears session-scoped tool-invocation state without run-cancel side
|
|
300
|
+
* effects such as composer draft restoration. Internal API for
|
|
301
|
+
* external-store adapter authors.
|
|
302
|
+
*/
|
|
303
|
+
unstable_notifySessionReset(): void;
|
|
297
304
|
getModelContext(): ModelContext;
|
|
298
305
|
|
|
299
306
|
export(): ExportedMessageRepository;
|
|
@@ -339,6 +346,10 @@ export class ThreadRuntimeImpl implements ThreadRuntime {
|
|
|
339
346
|
private readonly _threadBinding: ThreadRuntimeCoreBinding & {
|
|
340
347
|
getStateState(): ThreadState;
|
|
341
348
|
};
|
|
349
|
+
private readonly _stateBinding: ShallowMemoizeSubject<
|
|
350
|
+
ThreadState,
|
|
351
|
+
ThreadRuntimePath
|
|
352
|
+
>;
|
|
342
353
|
|
|
343
354
|
constructor(
|
|
344
355
|
threadBinding: ThreadRuntimeCoreBinding,
|
|
@@ -361,6 +372,7 @@ export class ThreadRuntimeImpl implements ThreadRuntime {
|
|
|
361
372
|
},
|
|
362
373
|
});
|
|
363
374
|
|
|
375
|
+
this._stateBinding = stateBinding;
|
|
364
376
|
this._threadBinding = {
|
|
365
377
|
path: threadBinding.path,
|
|
366
378
|
getState: () => threadBinding.getState(),
|
|
@@ -392,6 +404,8 @@ export class ThreadRuntimeImpl implements ThreadRuntime {
|
|
|
392
404
|
this.exportExternalState = this.exportExternalState.bind(this);
|
|
393
405
|
this.startRun = this.startRun.bind(this);
|
|
394
406
|
this.cancelRun = this.cancelRun.bind(this);
|
|
407
|
+
this.unstable_notifySessionReset =
|
|
408
|
+
this.unstable_notifySessionReset.bind(this);
|
|
395
409
|
this.stopSpeaking = this.stopSpeaking.bind(this);
|
|
396
410
|
this.connectVoice = this.connectVoice.bind(this);
|
|
397
411
|
this.disconnectVoice = this.disconnectVoice.bind(this);
|
|
@@ -435,7 +449,7 @@ export class ThreadRuntimeImpl implements ThreadRuntime {
|
|
|
435
449
|
}
|
|
436
450
|
|
|
437
451
|
public subscribe(callback: () => void) {
|
|
438
|
-
return this.
|
|
452
|
+
return this._stateBinding.subscribe(callback);
|
|
439
453
|
}
|
|
440
454
|
|
|
441
455
|
public getModelContext() {
|
|
@@ -462,6 +476,10 @@ export class ThreadRuntimeImpl implements ThreadRuntime {
|
|
|
462
476
|
this._threadBinding.getState().cancelRun();
|
|
463
477
|
}
|
|
464
478
|
|
|
479
|
+
public unstable_notifySessionReset() {
|
|
480
|
+
this._threadBinding.getState().unstable_notifySessionReset();
|
|
481
|
+
}
|
|
482
|
+
|
|
465
483
|
public stopSpeaking() {
|
|
466
484
|
return this._threadBinding.getState().stopSpeaking();
|
|
467
485
|
}
|
|
@@ -240,6 +240,8 @@ export abstract class BaseComposerRuntimeCore
|
|
|
240
240
|
const originalAttachments = this.attachments;
|
|
241
241
|
const text = this.text;
|
|
242
242
|
const quote = this._quote;
|
|
243
|
+
const role = this.role;
|
|
244
|
+
const runConfig = this.runConfig;
|
|
243
245
|
this._quote = undefined;
|
|
244
246
|
this._text = "";
|
|
245
247
|
this._isSending = true;
|
|
@@ -291,10 +293,10 @@ export abstract class BaseComposerRuntimeCore
|
|
|
291
293
|
|
|
292
294
|
const message: Omit<AppendMessage, "parentId" | "sourceId"> = {
|
|
293
295
|
createdAt: new Date(),
|
|
294
|
-
role
|
|
296
|
+
role,
|
|
295
297
|
content: text ? [{ type: "text", text }] : [],
|
|
296
298
|
attachments: finalAttachments,
|
|
297
|
-
runConfig
|
|
299
|
+
runConfig,
|
|
298
300
|
metadata: { custom: { ...(quote ? { quote } : {}) } },
|
|
299
301
|
};
|
|
300
302
|
|
|
@@ -718,9 +720,8 @@ export abstract class BaseComposerRuntimeCore
|
|
|
718
720
|
|
|
719
721
|
const session = this._dictationSession;
|
|
720
722
|
const sessionId = this._activeDictationSessionId;
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
});
|
|
723
|
+
const cleanup = () => this._cleanupDictation({ sessionId });
|
|
724
|
+
void session.stop().then(cleanup, cleanup);
|
|
724
725
|
}
|
|
725
726
|
|
|
726
727
|
private _cleanupDictation(options?: { sessionId: number | undefined }): void {
|