@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,191 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import type { RealtimeVoiceAdapter } from "../../adapters/voice";
|
|
3
|
+
import type { AppendMessage } from "../../types/message";
|
|
4
|
+
import type {
|
|
5
|
+
AddToolResultOptions,
|
|
6
|
+
ResumeRunConfig,
|
|
7
|
+
ResumeToolCallOptions,
|
|
8
|
+
RespondToToolApprovalOptions,
|
|
9
|
+
RuntimeCapabilities,
|
|
10
|
+
StartRunConfig,
|
|
11
|
+
ThreadSuggestion,
|
|
12
|
+
} from "../interfaces/thread-runtime-core";
|
|
13
|
+
import { BaseThreadRuntimeCore } from "./base-thread-runtime-core";
|
|
14
|
+
|
|
15
|
+
const createVoiceAdapter = () => {
|
|
16
|
+
let volumeCallback: ((volume: number) => void) | undefined;
|
|
17
|
+
const session: RealtimeVoiceAdapter.Session = {
|
|
18
|
+
status: { type: "running" },
|
|
19
|
+
isMuted: false,
|
|
20
|
+
disconnect: vi.fn(),
|
|
21
|
+
mute: vi.fn(),
|
|
22
|
+
unmute: vi.fn(),
|
|
23
|
+
onStatusChange: () => () => {},
|
|
24
|
+
onTranscript: () => () => {},
|
|
25
|
+
onModeChange: () => () => {},
|
|
26
|
+
onVolumeChange: (callback) => {
|
|
27
|
+
volumeCallback = callback;
|
|
28
|
+
return () => {
|
|
29
|
+
volumeCallback = undefined;
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
adapter: { connect: () => session },
|
|
36
|
+
emitVolume: (volume: number) => volumeCallback?.(volume),
|
|
37
|
+
session,
|
|
38
|
+
} satisfies {
|
|
39
|
+
adapter: RealtimeVoiceAdapter;
|
|
40
|
+
emitVolume: (volume: number) => void;
|
|
41
|
+
session: RealtimeVoiceAdapter.Session;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
class TestRuntime extends BaseThreadRuntimeCore {
|
|
46
|
+
private readonly voiceAdapter: ReturnType<typeof createVoiceAdapter>;
|
|
47
|
+
|
|
48
|
+
constructor(voiceAdapter: ReturnType<typeof createVoiceAdapter>) {
|
|
49
|
+
super({ getModelContext: () => ({}) });
|
|
50
|
+
this.voiceAdapter = voiceAdapter;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
get adapters() {
|
|
54
|
+
return { voice: this.voiceAdapter.adapter };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get isDisabled() {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get isSendDisabled() {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get isLoading() {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get suggestions(): readonly ThreadSuggestion[] {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get extras() {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
get capabilities(): RuntimeCapabilities {
|
|
78
|
+
return {
|
|
79
|
+
switchToBranch: false,
|
|
80
|
+
switchBranchDuringRun: false,
|
|
81
|
+
edit: false,
|
|
82
|
+
delete: false,
|
|
83
|
+
reload: false,
|
|
84
|
+
refetchThread: false,
|
|
85
|
+
cancel: false,
|
|
86
|
+
unstable_copy: false,
|
|
87
|
+
speech: false,
|
|
88
|
+
dictation: false,
|
|
89
|
+
voice: true,
|
|
90
|
+
attachments: false,
|
|
91
|
+
feedback: false,
|
|
92
|
+
queue: false,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
append(_message: AppendMessage) {}
|
|
97
|
+
deleteMessage(_messageId: string) {}
|
|
98
|
+
startRun(_config: StartRunConfig) {}
|
|
99
|
+
resumeRun(_config: ResumeRunConfig) {}
|
|
100
|
+
addToolResult(_options: AddToolResultOptions) {}
|
|
101
|
+
resumeToolCall(_options: ResumeToolCallOptions) {}
|
|
102
|
+
respondToToolApproval(_options: RespondToToolApprovalOptions) {}
|
|
103
|
+
cancelRun() {}
|
|
104
|
+
exportExternalState() {
|
|
105
|
+
return {};
|
|
106
|
+
}
|
|
107
|
+
importExternalState(_state: unknown) {}
|
|
108
|
+
unstable_notifySessionReset() {}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
afterEach(() => {
|
|
112
|
+
vi.restoreAllMocks();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe("BaseThreadRuntimeCore voice volume subscriptions", () => {
|
|
116
|
+
it("continues notifying subscribers when one throws", () => {
|
|
117
|
+
const consoleError = vi
|
|
118
|
+
.spyOn(console, "error")
|
|
119
|
+
.mockImplementation(() => {});
|
|
120
|
+
const voice = createVoiceAdapter();
|
|
121
|
+
const runtime = new TestRuntime(voice);
|
|
122
|
+
runtime.connectVoice();
|
|
123
|
+
|
|
124
|
+
const listenerError = new Error("listener failed");
|
|
125
|
+
const laterListener = vi.fn();
|
|
126
|
+
runtime.subscribeVoiceVolume(() => {
|
|
127
|
+
throw listenerError;
|
|
128
|
+
});
|
|
129
|
+
runtime.subscribeVoiceVolume(laterListener);
|
|
130
|
+
|
|
131
|
+
expect(() => voice.emitVolume(0.5)).not.toThrow();
|
|
132
|
+
expect(laterListener).toHaveBeenCalledOnce();
|
|
133
|
+
expect(runtime.getVoiceVolume()).toBe(0.5);
|
|
134
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
135
|
+
"[assistant-ui] Voice volume listener threw an error",
|
|
136
|
+
listenerError,
|
|
137
|
+
);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("continues disconnect cleanup when a subscriber throws", () => {
|
|
141
|
+
const consoleError = vi
|
|
142
|
+
.spyOn(console, "error")
|
|
143
|
+
.mockImplementation(() => {});
|
|
144
|
+
const voice = createVoiceAdapter();
|
|
145
|
+
const runtime = new TestRuntime(voice);
|
|
146
|
+
runtime.connectVoice();
|
|
147
|
+
|
|
148
|
+
const listenerError = new Error("disconnect listener failed");
|
|
149
|
+
const laterListener = vi.fn();
|
|
150
|
+
runtime.subscribeVoiceVolume(() => {
|
|
151
|
+
throw listenerError;
|
|
152
|
+
});
|
|
153
|
+
runtime.subscribeVoiceVolume(laterListener);
|
|
154
|
+
|
|
155
|
+
expect(() => runtime.disconnectVoice()).not.toThrow();
|
|
156
|
+
expect(laterListener).toHaveBeenCalledOnce();
|
|
157
|
+
expect(runtime.getVoiceVolume()).toBe(0);
|
|
158
|
+
expect(runtime.voice).toBeUndefined();
|
|
159
|
+
expect(voice.session.disconnect).toHaveBeenCalledOnce();
|
|
160
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
161
|
+
"[assistant-ui] Voice volume listener threw an error",
|
|
162
|
+
listenerError,
|
|
163
|
+
);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("reports rejected subscriber thenables", async () => {
|
|
167
|
+
const consoleError = vi
|
|
168
|
+
.spyOn(console, "error")
|
|
169
|
+
.mockImplementation(() => {});
|
|
170
|
+
const voice = createVoiceAdapter();
|
|
171
|
+
const runtime = new TestRuntime(voice);
|
|
172
|
+
runtime.connectVoice();
|
|
173
|
+
|
|
174
|
+
const listenerError = new Error("async listener failed");
|
|
175
|
+
const laterListener = vi.fn();
|
|
176
|
+
runtime.subscribeVoiceVolume(async () => {
|
|
177
|
+
throw listenerError;
|
|
178
|
+
});
|
|
179
|
+
runtime.subscribeVoiceVolume(laterListener);
|
|
180
|
+
|
|
181
|
+
voice.emitVolume(0.5);
|
|
182
|
+
|
|
183
|
+
await vi.waitFor(() => {
|
|
184
|
+
expect(laterListener).toHaveBeenCalledOnce();
|
|
185
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
186
|
+
"[assistant-ui] Voice volume listener threw an error",
|
|
187
|
+
listenerError,
|
|
188
|
+
);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
});
|
|
@@ -69,6 +69,7 @@ export abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
|
|
|
69
69
|
public abstract cancelRun(): void;
|
|
70
70
|
public abstract exportExternalState(): any;
|
|
71
71
|
public abstract importExternalState(state: any): void;
|
|
72
|
+
public abstract unstable_notifySessionReset(): void;
|
|
72
73
|
|
|
73
74
|
protected _voiceMessages: ThreadMessage[] = [];
|
|
74
75
|
protected _voiceGeneration = 0;
|
|
@@ -355,7 +356,11 @@ export abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
|
|
|
355
356
|
unsubs.push(
|
|
356
357
|
session.onVolumeChange((volume) => {
|
|
357
358
|
this._voiceVolume = volume;
|
|
358
|
-
|
|
359
|
+
notifyEventListeners(
|
|
360
|
+
this._voiceVolumeSubscribers,
|
|
361
|
+
undefined,
|
|
362
|
+
"Voice volume",
|
|
363
|
+
);
|
|
359
364
|
}),
|
|
360
365
|
);
|
|
361
366
|
|
|
@@ -454,7 +459,11 @@ export abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
|
|
|
454
459
|
this._voiceSession = undefined;
|
|
455
460
|
this.voice = undefined;
|
|
456
461
|
this._voiceVolume = 0;
|
|
457
|
-
|
|
462
|
+
notifyEventListeners(
|
|
463
|
+
this._voiceVolumeSubscribers,
|
|
464
|
+
undefined,
|
|
465
|
+
"Voice volume",
|
|
466
|
+
);
|
|
458
467
|
this._voiceMessages = [];
|
|
459
468
|
this._markVoiceMessagesDirty();
|
|
460
469
|
this._notifySubscribers();
|
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
ThreadComposerRuntimeCore,
|
|
7
7
|
} from "../interfaces/composer-runtime-core";
|
|
8
8
|
import type { ThreadRuntimeCore } from "../interfaces/thread-runtime-core";
|
|
9
|
+
import { getThreadRuntimeCoreIsRunning } from "../api/thread-runtime";
|
|
9
10
|
import type { QueuePlacement } from "../queue/external-thread-queue-adapter";
|
|
10
11
|
import {
|
|
11
12
|
EMPTY_QUEUE_ITEMS,
|
|
@@ -13,13 +14,18 @@ import {
|
|
|
13
14
|
} from "../../store/scopes/queue-item";
|
|
14
15
|
import { BaseComposerRuntimeCore } from "./base-composer-runtime-core";
|
|
15
16
|
|
|
17
|
+
const isCancelable = (runtime: Omit<ThreadRuntimeCore, "composer">) => {
|
|
18
|
+
// capabilities is a subclass field assigned after this composer is constructed
|
|
19
|
+
if (!runtime.capabilities?.cancel) return false;
|
|
20
|
+
return getThreadRuntimeCoreIsRunning(runtime);
|
|
21
|
+
};
|
|
22
|
+
|
|
16
23
|
export class DefaultThreadComposerRuntimeCore
|
|
17
24
|
extends BaseComposerRuntimeCore
|
|
18
25
|
implements ThreadComposerRuntimeCore
|
|
19
26
|
{
|
|
20
|
-
private _canCancel = false;
|
|
21
27
|
public get canCancel() {
|
|
22
|
-
return this.
|
|
28
|
+
return isCancelable(this.runtime);
|
|
23
29
|
}
|
|
24
30
|
|
|
25
31
|
public get canSend() {
|
|
@@ -94,12 +100,14 @@ export class DefaultThreadComposerRuntimeCore
|
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
public connect() {
|
|
103
|
+
let lastCanCancel = false;
|
|
97
104
|
let lastIsSendDisabled = this.runtime.isSendDisabled;
|
|
98
105
|
let lastQueue = this.queue;
|
|
99
106
|
return this.runtime.subscribe(() => {
|
|
100
107
|
let changed = false;
|
|
101
|
-
|
|
102
|
-
|
|
108
|
+
const nextCanCancel = this.canCancel;
|
|
109
|
+
if (lastCanCancel !== nextCanCancel) {
|
|
110
|
+
lastCanCancel = nextCanCancel;
|
|
103
111
|
changed = true;
|
|
104
112
|
}
|
|
105
113
|
if (lastIsSendDisabled !== this.runtime.isSendDisabled) {
|
|
@@ -72,6 +72,11 @@ export type SubmitFeedbackOptions = {
|
|
|
72
72
|
};
|
|
73
73
|
|
|
74
74
|
export type ThreadSuggestion = {
|
|
75
|
+
/** Display heading for the suggestion. Falls back to the prompt when absent. */
|
|
76
|
+
title?: string;
|
|
77
|
+
/** Secondary display text shown alongside the title. */
|
|
78
|
+
label?: string;
|
|
79
|
+
/** The message text sent when the suggestion is selected. */
|
|
75
80
|
prompt: string;
|
|
76
81
|
};
|
|
77
82
|
|
|
@@ -156,6 +161,7 @@ export type ThreadRuntimeCore = Readonly<{
|
|
|
156
161
|
startRun: (config: StartRunConfig) => void;
|
|
157
162
|
resumeRun: (config: ResumeRunConfig) => void;
|
|
158
163
|
cancelRun: () => void;
|
|
164
|
+
unstable_notifySessionReset: () => void;
|
|
159
165
|
|
|
160
166
|
addToolResult: (options: AddToolResultOptions) => void;
|
|
161
167
|
resumeToolCall: (options: ResumeToolCallOptions) => void;
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type QueueItemState,
|
|
9
9
|
} from "../../store/scopes/queue-item";
|
|
10
10
|
import { generateId } from "../../utils/id";
|
|
11
|
+
import { notifyEventListeners } from "../../utils/notify-event-listeners";
|
|
11
12
|
import { getThreadMessageText } from "../../utils/text";
|
|
12
13
|
import type {
|
|
13
14
|
ExternalThreadQueueAdapter,
|
|
@@ -87,7 +88,7 @@ export const createMessageQueue = (
|
|
|
87
88
|
let interrupting = false;
|
|
88
89
|
|
|
89
90
|
const notify = () => {
|
|
90
|
-
|
|
91
|
+
notifyEventListeners(subscribers, undefined, "Message queue");
|
|
91
92
|
};
|
|
92
93
|
|
|
93
94
|
const setLanes = (next: Record<Lane, readonly QueueItemState[]>) => {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ThreadRuntimeCore } from "../interfaces/thread-runtime-core";
|
|
2
|
+
|
|
3
|
+
// Invalidation must stay re-entrant: StrictMode's simulated unmount runs the
|
|
4
|
+
// effect cleanup while the runtime object survives into the next mount, so a
|
|
5
|
+
// permanent disposed mark would swallow every later append.
|
|
6
|
+
const generations = new WeakMap<ThreadRuntimeCore, number>();
|
|
7
|
+
|
|
8
|
+
export const captureThreadRuntimeGeneration = (runtime: ThreadRuntimeCore) =>
|
|
9
|
+
generations.get(runtime) ?? 0;
|
|
10
|
+
|
|
11
|
+
export const isThreadRuntimeGenerationCurrent = (
|
|
12
|
+
runtime: ThreadRuntimeCore,
|
|
13
|
+
generation: number,
|
|
14
|
+
) => captureThreadRuntimeGeneration(runtime) === generation;
|
|
15
|
+
|
|
16
|
+
export const invalidateThreadRuntime = (runtime: ThreadRuntimeCore) => {
|
|
17
|
+
generations.set(runtime, captureThreadRuntimeGeneration(runtime) + 1);
|
|
18
|
+
};
|
|
@@ -14,5 +14,7 @@ export const pickExternalStoreSharedOptions = (
|
|
|
14
14
|
unstable_capabilities: options.unstable_capabilities,
|
|
15
15
|
suggestions: options.suggestions,
|
|
16
16
|
}) satisfies {
|
|
17
|
-
[
|
|
17
|
+
[
|
|
18
|
+
K in keyof Required<ExternalStoreSharedOptions>
|
|
19
|
+
]: ExternalStoreSharedOptions[K];
|
|
18
20
|
};
|
|
@@ -5,6 +5,8 @@ import type {
|
|
|
5
5
|
ThreadListRuntimeCore,
|
|
6
6
|
} from "../../runtime/interfaces/thread-list-runtime-core";
|
|
7
7
|
import type { ExternalStoreThreadListAdapter } from "./external-store-adapter";
|
|
8
|
+
import { invalidateThreadRuntime } from "../../runtime/utils/thread-runtime-lifecycle";
|
|
9
|
+
import { notifySubscribers } from "../../subscribable/subscribable";
|
|
8
10
|
|
|
9
11
|
export type ExternalStoreThreadFactory = () => ExternalStoreThreadRuntimeCore;
|
|
10
12
|
|
|
@@ -150,6 +152,7 @@ export class ExternalStoreThreadListRuntimeCore implements ThreadListRuntimeCore
|
|
|
150
152
|
|
|
151
153
|
// `initialLoad ||`: `_mainThread!` must be assigned on construction.
|
|
152
154
|
if (initialLoad || previousThreadId !== newThreadId) {
|
|
155
|
+
if (!initialLoad) invalidateThreadRuntime(this._mainThread);
|
|
153
156
|
this._mainThreadId = newThreadId;
|
|
154
157
|
this._mainThread = this.threadFactory();
|
|
155
158
|
}
|
|
@@ -268,6 +271,6 @@ export class ExternalStoreThreadListRuntimeCore implements ThreadListRuntimeCore
|
|
|
268
271
|
}
|
|
269
272
|
|
|
270
273
|
private _notifySubscribers() {
|
|
271
|
-
|
|
274
|
+
notifySubscribers(this._subscriptions);
|
|
272
275
|
}
|
|
273
276
|
}
|
|
@@ -42,9 +42,25 @@ import { generateId } from "../../utils/id";
|
|
|
42
42
|
import { ToolInvocationTracker } from "../tool-invocations/ToolInvocationTracker";
|
|
43
43
|
import { EMPTY_QUEUE_ITEMS } from "../../store/scopes/queue-item";
|
|
44
44
|
import type { QuoteInfo } from "../../types/quote";
|
|
45
|
+
import {
|
|
46
|
+
captureThreadRuntimeGeneration,
|
|
47
|
+
isThreadRuntimeGenerationCurrent,
|
|
48
|
+
} from "../../runtime/utils/thread-runtime-lifecycle";
|
|
45
49
|
|
|
46
50
|
const EMPTY_ARRAY: readonly ThreadSuggestion[] = Object.freeze([]);
|
|
47
51
|
|
|
52
|
+
const observeAdapterCallback = (
|
|
53
|
+
name: "onAddToolResult" | "onRespondToToolApproval" | "onCancel",
|
|
54
|
+
result: Promise<void> | void,
|
|
55
|
+
) => {
|
|
56
|
+
void Promise.resolve(result).catch((error) => {
|
|
57
|
+
console.error(
|
|
58
|
+
`[ExternalStoreThreadRuntimeCore] ${name} callback rejected`,
|
|
59
|
+
error,
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
|
|
48
64
|
const shallowEqual = (a: object, b: object): boolean => {
|
|
49
65
|
const aKeys = Object.keys(a);
|
|
50
66
|
if (aKeys.length !== Object.keys(b).length) return false;
|
|
@@ -122,6 +138,14 @@ export class ExternalStoreThreadRuntimeCore
|
|
|
122
138
|
|
|
123
139
|
private _store!: ExternalStoreAdapter<any>;
|
|
124
140
|
|
|
141
|
+
private _getInitializePromise?: () => Promise<unknown> | undefined;
|
|
142
|
+
|
|
143
|
+
public __internal_setGetInitializePromise(
|
|
144
|
+
getPromise: () => Promise<unknown> | undefined,
|
|
145
|
+
) {
|
|
146
|
+
this._getInitializePromise = getPromise;
|
|
147
|
+
}
|
|
148
|
+
|
|
125
149
|
private _transformedQueue: ExternalThreadQueueAdapter | undefined;
|
|
126
150
|
|
|
127
151
|
/**
|
|
@@ -375,19 +399,22 @@ export class ExternalStoreThreadRuntimeCore
|
|
|
375
399
|
// rolled back). Drop the result.
|
|
376
400
|
return;
|
|
377
401
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
402
|
+
observeAdapterCallback(
|
|
403
|
+
"onAddToolResult",
|
|
404
|
+
this._store.onAddToolResult?.({
|
|
405
|
+
messageId,
|
|
406
|
+
toolCallId: command.toolCallId,
|
|
407
|
+
toolName: command.toolName,
|
|
408
|
+
result: command.result,
|
|
409
|
+
isError: command.isError,
|
|
410
|
+
...(command.artifact !== undefined && {
|
|
411
|
+
artifact: command.artifact,
|
|
412
|
+
}),
|
|
413
|
+
...(command.modelContent !== undefined && {
|
|
414
|
+
modelContent: command.modelContent,
|
|
415
|
+
}),
|
|
389
416
|
}),
|
|
390
|
-
|
|
417
|
+
);
|
|
391
418
|
} catch (err) {
|
|
392
419
|
console.error(
|
|
393
420
|
"[ExternalStoreThreadRuntimeCore] onAddToolResult dispatch failed",
|
|
@@ -492,22 +519,46 @@ export class ExternalStoreThreadRuntimeCore
|
|
|
492
519
|
rawMessage.sourceId != null ||
|
|
493
520
|
rawMessage.parentId !== (this.messages.at(-1)?.id ?? null);
|
|
494
521
|
|
|
495
|
-
//
|
|
496
|
-
//
|
|
522
|
+
// A transformed-queue send is stamped at flush; any other queue's
|
|
523
|
+
// transform would gate against its own thread's messages, so those stamp
|
|
524
|
+
// at send.
|
|
525
|
+
const message =
|
|
526
|
+
!isEdit &&
|
|
527
|
+
this._store.queue &&
|
|
528
|
+
this._store.queue === this._transformedQueue
|
|
529
|
+
? rawMessage
|
|
530
|
+
: this.enrichAppendMetadata(rawMessage);
|
|
531
|
+
|
|
532
|
+
const generation = captureThreadRuntimeGeneration(this);
|
|
533
|
+
this.ensureInitialized();
|
|
534
|
+
|
|
535
|
+
// The getter call is what starts thread initialization.
|
|
536
|
+
const initPromise = this._getInitializePromise?.();
|
|
537
|
+
|
|
538
|
+
// The queue driver dispatches through the host adapter, outside this
|
|
539
|
+
// core, so the initialization barrier must run before a message can
|
|
540
|
+
// enter the queue.
|
|
497
541
|
if (!isEdit && this._store.queue) {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
542
|
+
if (initPromise) {
|
|
543
|
+
await initPromise;
|
|
544
|
+
}
|
|
545
|
+
if (!isThreadRuntimeGenerationCurrent(this, generation)) return;
|
|
546
|
+
|
|
547
|
+
// Buffering does not start a run, so the tool-abort below must wait
|
|
548
|
+
// until the queue flushes. By then the prior run (and its tools) has
|
|
549
|
+
// settled.
|
|
550
|
+
if (message.steer ?? this._store.isRunning ?? false)
|
|
551
|
+
this._store.queue.steer(message);
|
|
552
|
+
else this._store.queue.enqueue(message);
|
|
507
553
|
return;
|
|
508
554
|
}
|
|
509
555
|
|
|
510
|
-
|
|
556
|
+
// The optimistic insert lives inside the adapter's dispatch, so holding
|
|
557
|
+
// `onNew` on initialization would keep the message off screen for the
|
|
558
|
+
// whole roundtrip. Seams that need the remote identity await
|
|
559
|
+
// `threadListItem.initialize()` themselves, and a rejection surfaces
|
|
560
|
+
// there.
|
|
561
|
+
void initPromise?.catch(() => {});
|
|
511
562
|
|
|
512
563
|
// Auto-abort in-flight client-side tool executions when a new run is
|
|
513
564
|
// about to start. Without this, a tool that finishes after the new turn
|
|
@@ -518,6 +569,7 @@ export class ExternalStoreThreadRuntimeCore
|
|
|
518
569
|
if (message.startRun ?? message.role === "user") {
|
|
519
570
|
await this._toolInvocations?.abort();
|
|
520
571
|
}
|
|
572
|
+
if (!isThreadRuntimeGenerationCurrent(this, generation)) return;
|
|
521
573
|
|
|
522
574
|
if (isEdit) {
|
|
523
575
|
if (!this._store.onEdit)
|
|
@@ -600,17 +652,24 @@ export class ExternalStoreThreadRuntimeCore
|
|
|
600
652
|
// imported state) is treated as historical — no streamCall/execute
|
|
601
653
|
// fires for the loaded tool calls. The adapter is expected to update
|
|
602
654
|
// its messages in response to onLoadExternalState; that update flows
|
|
603
|
-
// back here via __internal_setAdapter.
|
|
604
|
-
//
|
|
605
|
-
//
|
|
606
|
-
|
|
607
|
-
this._toolInvocations.reset();
|
|
608
|
-
this._store.setToolStatuses?.({});
|
|
609
|
-
}
|
|
655
|
+
// back here via __internal_setAdapter. The tracker publishes the
|
|
656
|
+
// cleared status map itself, so adapter-side statuses reset only when
|
|
657
|
+
// the tracker is the source of truth.
|
|
658
|
+
this._toolInvocations?.reset();
|
|
610
659
|
|
|
611
660
|
this._store.onLoadExternalState(state);
|
|
612
661
|
}
|
|
613
662
|
|
|
663
|
+
/**
|
|
664
|
+
* Adapter-facing notification that the backing session was discarded.
|
|
665
|
+
* Clears session-scoped tool-invocation state and parks queued work,
|
|
666
|
+
* without run-cancel semantics (`onCancel`, composer draft restoration).
|
|
667
|
+
*/
|
|
668
|
+
public unstable_notifySessionReset(): void {
|
|
669
|
+
this._toolInvocations?.reset();
|
|
670
|
+
this._store.queue?.__internal_notifyCancelled?.();
|
|
671
|
+
}
|
|
672
|
+
|
|
614
673
|
public cancelRun(): void {
|
|
615
674
|
if (!this._store.onCancel)
|
|
616
675
|
throw new Error("Runtime does not support cancelling runs.");
|
|
@@ -625,7 +684,7 @@ export class ExternalStoreThreadRuntimeCore
|
|
|
625
684
|
// stopped.
|
|
626
685
|
this._store.queue?.__internal_notifyCancelled?.();
|
|
627
686
|
|
|
628
|
-
this._store.onCancel();
|
|
687
|
+
observeAdapterCallback("onCancel", this._store.onCancel());
|
|
629
688
|
|
|
630
689
|
this.dropEmptyOptimisticHead();
|
|
631
690
|
|
|
@@ -700,7 +759,10 @@ export class ExternalStoreThreadRuntimeCore
|
|
|
700
759
|
public addToolResult(options: AddToolResultOptions) {
|
|
701
760
|
if (!this._store.onAddToolResult)
|
|
702
761
|
throw new Error("Runtime does not support tool results.");
|
|
703
|
-
|
|
762
|
+
observeAdapterCallback(
|
|
763
|
+
"onAddToolResult",
|
|
764
|
+
this._store.onAddToolResult(options),
|
|
765
|
+
);
|
|
704
766
|
}
|
|
705
767
|
|
|
706
768
|
public resumeToolCall(options: ResumeToolCallOptions) {
|
|
@@ -726,7 +788,10 @@ export class ExternalStoreThreadRuntimeCore
|
|
|
726
788
|
public respondToToolApproval(options: RespondToToolApprovalOptions) {
|
|
727
789
|
if (!this._store.onRespondToToolApproval)
|
|
728
790
|
throw new Error("Runtime does not support tool approvals.");
|
|
729
|
-
|
|
791
|
+
observeAdapterCallback(
|
|
792
|
+
"onRespondToToolApproval",
|
|
793
|
+
this._store.onRespondToToolApproval(options),
|
|
794
|
+
);
|
|
730
795
|
}
|
|
731
796
|
|
|
732
797
|
public override reset(initialMessages?: readonly ThreadMessageLike[]) {
|