@assistant-ui/core 0.3.13 → 0.3.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/speech.d.ts.map +1 -1
- package/dist/adapters/speech.js +9 -15
- package/dist/adapters/speech.js.map +1 -1
- package/dist/adapters/thread-history.d.ts +2 -0
- package/dist/adapters/thread-history.d.ts.map +1 -1
- package/dist/adapters/voice.d.ts.map +1 -1
- package/dist/adapters/voice.js +38 -15
- package/dist/adapters/voice.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +3 -2
- package/dist/internal.js +8 -7
- package/dist/model-context/frame/host.d.ts +1 -1
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js +19 -4
- package/dist/model-context/frame/host.js.map +1 -1
- package/dist/model-context/frame/provider.d.ts +4 -0
- package/dist/model-context/frame/provider.d.ts.map +1 -1
- package/dist/model-context/frame/provider.js +50 -3
- package/dist/model-context/frame/provider.js.map +1 -1
- package/dist/model-context/frame/types.d.ts +4 -1
- package/dist/model-context/frame/types.d.ts.map +1 -1
- package/dist/model-context/frame/types.js.map +1 -1
- package/dist/model-context/registry.d.ts.map +1 -1
- package/dist/model-context/registry.js +16 -4
- package/dist/model-context/registry.js.map +1 -1
- package/dist/react/RuntimeAdapter.d.ts +8 -1
- package/dist/react/RuntimeAdapter.d.ts.map +1 -1
- package/dist/react/RuntimeAdapter.js +23 -18
- package/dist/react/RuntimeAdapter.js.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.js +28 -12
- package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
- package/dist/react/client/AdaptedRemoteThread.d.ts +11 -0
- package/dist/react/client/AdaptedRemoteThread.d.ts.map +1 -0
- package/dist/react/client/AdaptedRemoteThread.js +27 -0
- package/dist/react/client/AdaptedRemoteThread.js.map +1 -0
- package/dist/react/client/InMemoryThreadList.d.ts +19 -0
- package/dist/react/client/InMemoryThreadList.d.ts.map +1 -0
- package/dist/react/client/InMemoryThreadList.js +418 -0
- package/dist/react/client/InMemoryThreadList.js.map +1 -0
- package/dist/react/client/Interactables.d.ts.map +1 -1
- package/dist/react/client/Interactables.js +159 -102
- package/dist/react/client/Interactables.js.map +1 -1
- package/dist/react/client/RemoteThreadList.d.ts +34 -0
- package/dist/react/client/RemoteThreadList.d.ts.map +1 -0
- package/dist/react/client/RemoteThreadList.js +898 -0
- package/dist/react/client/RemoteThreadList.js.map +1 -0
- package/dist/react/client/Tools.d.ts.map +1 -1
- package/dist/react/client/Tools.js +38 -27
- package/dist/react/client/Tools.js.map +1 -1
- package/dist/react/index.d.ts +7 -2
- package/dist/react/index.js +5 -2
- package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
- package/dist/react/interactables-legacy/Interactables.js +145 -110
- package/dist/react/interactables-legacy/Interactables.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useActionBarCopy.js +20 -19
- package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useActionBarEdit.js +2 -4
- package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useActionBarReload.js +2 -4
- package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerNext.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerNext.js +2 -6
- package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useBranchPickerPrevious.js +2 -6
- package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
- package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useComposerCancel.js +2 -4
- package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
- package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useComposerSend.js +2 -4
- package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
- package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useSuggestionTrigger.js +6 -2
- package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts +3 -0
- package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsEmpty.js +3 -0
- package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +3 -0
- package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsRunning.js +3 -0
- package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -1
- package/dist/react/primitives/message/MessageParts.d.ts +13 -0
- package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageParts.js.map +1 -1
- package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
- package/dist/react/primitives/thread/ThreadMessages.js +1 -1
- package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +24 -10
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +115 -71
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +14 -2
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +232 -63
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadResource.d.ts +30 -0
- package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -0
- package/dist/react/runtimes/RemoteThreadResource.js +136 -0
- package/dist/react/runtimes/RemoteThreadResource.js.map +1 -0
- package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +3 -10
- package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
- package/dist/react/runtimes/RuntimeAdapterProvider.js +3 -6
- package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -1
- package/dist/react/runtimes/assistant-transport/commandQueue.d.ts +17 -0
- package/dist/react/runtimes/assistant-transport/commandQueue.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/commandQueue.js +55 -0
- package/dist/react/runtimes/assistant-transport/commandQueue.js.map +1 -0
- package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts +11 -0
- package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js +165 -0
- package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js.map +1 -0
- package/dist/react/runtimes/assistant-transport/runManager.d.ts +15 -0
- package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/runManager.js +86 -0
- package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -0
- package/dist/react/runtimes/assistant-transport/types.d.ts +130 -0
- package/dist/react/runtimes/assistant-transport/types.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/types.js +0 -0
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts +14 -0
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +296 -0
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -0
- package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts +7 -0
- package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/useConvertedState.js +25 -0
- package/dist/react/runtimes/assistant-transport/useConvertedState.js.map +1 -0
- package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts +7 -0
- package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts.map +1 -0
- package/dist/react/runtimes/assistant-transport/useLatestRef.js +27 -0
- package/dist/react/runtimes/assistant-transport/useLatestRef.js.map +1 -0
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +39 -13
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +2 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +3 -3
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.d.ts +4 -0
- package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.js +7 -0
- package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +60 -17
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts +16 -0
- package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js +36 -0
- package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -0
- package/dist/react/runtimes/external-message-converter.js +14 -14
- package/dist/react/runtimes/external-message-converter.js.map +1 -1
- package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -1
- package/dist/react/runtimes/useExternalStoreRuntime.js +44 -28
- package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
- package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
- package/dist/react/runtimes/useLocalRuntime.js +1 -1
- package/dist/react/runtimes/useRuntimeAdapters.d.ts +9 -0
- package/dist/react/runtimes/useRuntimeAdapters.d.ts.map +1 -0
- package/dist/react/runtimes/useRuntimeAdapters.js +20 -0
- package/dist/react/runtimes/useRuntimeAdapters.js.map +1 -0
- package/dist/runtime/api/composer-runtime.d.ts +5 -0
- package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
- package/dist/runtime/api/composer-runtime.js.map +1 -1
- package/dist/runtime/api/message-runtime.js +1 -1
- package/dist/runtime/api/thread-list-runtime.d.ts +1 -0
- package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-runtime.js +4 -2
- package/dist/runtime/api/thread-list-runtime.js.map +1 -1
- package/dist/runtime/api/thread-runtime.d.ts +12 -2
- package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-runtime.js +8 -2
- package/dist/runtime/api/thread-runtime.js.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.js +8 -7
- package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts +1 -0
- package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.js +3 -3
- package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +0 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.js +10 -4
- package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
- package/dist/runtime/interfaces/thread-runtime-core.d.ts +6 -0
- package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/internal.js +5 -5
- package/dist/runtime/queue/message-queue.d.ts.map +1 -1
- package/dist/runtime/queue/message-queue.js +2 -1
- package/dist/runtime/queue/message-queue.js.map +1 -1
- package/dist/runtime/utils/message-repository.d.ts.map +1 -1
- package/dist/runtime/utils/message-repository.js +27 -18
- package/dist/runtime/utils/message-repository.js.map +1 -1
- package/dist/runtime/utils/thread-runtime-lifecycle.d.ts +8 -0
- package/dist/runtime/utils/thread-runtime-lifecycle.d.ts.map +1 -0
- package/dist/runtime/utils/thread-runtime-lifecycle.js +11 -0
- package/dist/runtime/utils/thread-runtime-lifecycle.js.map +1 -0
- package/dist/runtimes/external-store/external-store-shared-options.js.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +4 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +8 -0
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js +37 -13
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +102 -0
- package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -0
- package/dist/runtimes/inert/InertThreadRuntimeCore.js +156 -0
- package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -0
- package/dist/runtimes/internal.d.ts +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -0
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +78 -19
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +12 -59
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +10 -142
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
- package/dist/runtimes/remote-thread-list/adapter-changed.d.ts +9 -0
- package/dist/runtimes/remote-thread-list/adapter-changed.d.ts.map +1 -0
- package/dist/runtimes/remote-thread-list/adapter-changed.js +13 -0
- package/dist/runtimes/remote-thread-list/adapter-changed.js.map +1 -0
- package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/empty-thread-core.js +16 -152
- package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +2 -0
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.js +11 -0
- package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
- package/dist/runtimes/remote-thread-list/types.d.ts +32 -1
- package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +1 -12
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +67 -38
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
- package/dist/store/clients/external-thread.js +1 -1
- package/dist/store/clients/external-thread.js.map +1 -1
- package/dist/store/clients/suggestions.js +2 -2
- package/dist/store/clients/suggestions.js.map +1 -1
- package/dist/store/clients/thread-selection-events.d.ts +10 -0
- package/dist/store/clients/thread-selection-events.d.ts.map +1 -0
- package/dist/store/clients/thread-selection-events.js +40 -0
- package/dist/store/clients/thread-selection-events.js.map +1 -0
- package/dist/store/env.d.ts +5 -0
- package/dist/store/env.d.ts.map +1 -0
- package/dist/store/env.js +12 -0
- package/dist/store/env.js.map +1 -0
- package/dist/store/index.d.ts +5 -3
- package/dist/store/index.js +4 -2
- package/dist/store/internal.d.ts +4 -1
- package/dist/store/internal.js +4 -1
- package/dist/store/primitive-predicates.d.ts +19 -0
- package/dist/store/primitive-predicates.d.ts.map +1 -0
- package/dist/store/primitive-predicates.js +19 -0
- package/dist/store/primitive-predicates.js.map +1 -0
- package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/attachment-runtime-client.js +18 -11
- package/dist/store/runtime-clients/attachment-runtime-client.js.map +1 -1
- package/dist/store/runtime-clients/handle-runtime-action.d.ts +5 -0
- package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -0
- package/dist/store/runtime-clients/handle-runtime-action.js +14 -0
- package/dist/store/runtime-clients/handle-runtime-action.js.map +1 -0
- package/dist/store/runtime-clients/handle-thread-list-action.d.ts +5 -0
- package/dist/store/runtime-clients/handle-thread-list-action.d.ts.map +1 -0
- package/dist/store/runtime-clients/handle-thread-list-action.js +7 -0
- package/dist/store/runtime-clients/handle-thread-list-action.js.map +1 -0
- package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-list-item-runtime-client.js +62 -29
- package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
- package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-list-runtime-client.js +5 -6
- package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
- package/dist/store/scopes/composer.d.ts +9 -4
- package/dist/store/scopes/composer.d.ts.map +1 -1
- package/dist/store/scopes/thread-list-item.d.ts +7 -6
- package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
- package/dist/store/scopes/thread.d.ts +8 -7
- package/dist/store/scopes/thread.d.ts.map +1 -1
- package/dist/store/scopes/threads.d.ts +17 -1
- package/dist/store/scopes/threads.d.ts.map +1 -1
- package/dist/subscribable/subscribable.d.ts +2 -1
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/subscribable/subscribable.js +23 -18
- package/dist/subscribable/subscribable.js.map +1 -1
- package/dist/types/message.d.ts +1 -1
- package/dist/types/message.js.map +1 -1
- package/dist/utils/composite-context-provider.d.ts +1 -0
- package/dist/utils/composite-context-provider.d.ts.map +1 -1
- package/dist/utils/composite-context-provider.js +25 -9
- package/dist/utils/composite-context-provider.js.map +1 -1
- package/dist/utils/notify-event-listeners.d.ts +2 -2
- package/dist/utils/notify-event-listeners.d.ts.map +1 -1
- package/dist/utils/notify-event-listeners.js +2 -2
- package/dist/utils/notify-event-listeners.js.map +1 -1
- package/dist/utils/silent-runtime-action.d.ts +6 -0
- package/dist/utils/silent-runtime-action.d.ts.map +1 -0
- package/dist/utils/silent-runtime-action.js +7 -0
- package/dist/utils/silent-runtime-action.js.map +1 -0
- package/package.json +8 -8
- package/src/adapters/speech.test.ts +118 -1
- package/src/adapters/speech.ts +21 -22
- package/src/adapters/thread-history.ts +2 -0
- package/src/adapters/voice.test.ts +134 -0
- package/src/adapters/voice.ts +35 -27
- package/src/index.ts +1 -0
- package/src/internal.ts +1 -0
- package/src/model-context/frame/host.test.ts +87 -5
- package/src/model-context/frame/host.ts +18 -4
- package/src/model-context/frame/provider.test.ts +347 -20
- package/src/model-context/frame/provider.ts +58 -2
- package/src/model-context/frame/types.ts +5 -0
- package/src/model-context/registry.test.ts +131 -0
- package/src/model-context/registry.ts +16 -6
- package/src/react/RuntimeAdapter.test.ts +2 -0
- package/src/react/RuntimeAdapter.ts +20 -8
- package/src/react/adapters/LocalStorageThreadListAdapter.tsx +34 -17
- package/src/react/client/AdaptedRemoteThread.ts +41 -0
- package/src/react/client/InMemoryThreadList.test.tsx +148 -0
- package/src/react/client/InMemoryThreadList.ts +290 -0
- package/src/react/client/Interactables.test.ts +326 -2
- package/src/react/client/Interactables.ts +227 -110
- package/src/react/client/RemoteThreadList.test.ts +1222 -0
- package/src/react/client/RemoteThreadList.ts +1136 -0
- package/src/react/client/Tools.ts +36 -29
- package/src/react/index.ts +13 -0
- package/src/react/interactables-legacy/Interactables.test.ts +317 -0
- package/src/react/interactables-legacy/Interactables.ts +204 -128
- package/src/react/primitive-hooks/useActionBarCopy.test.ts +15 -0
- package/src/react/primitive-hooks/useActionBarCopy.ts +15 -10
- package/src/react/primitive-hooks/useActionBarEdit.ts +2 -1
- package/src/react/primitive-hooks/useActionBarReload.ts +2 -6
- package/src/react/primitive-hooks/useBranchPickerNext.ts +2 -7
- package/src/react/primitive-hooks/useBranchPickerPrevious.ts +2 -7
- package/src/react/primitive-hooks/useComposerCancel.ts +2 -1
- package/src/react/primitive-hooks/useComposerSend.ts +2 -5
- package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +11 -0
- package/src/react/primitive-hooks/useSuggestionTrigger.ts +4 -5
- package/src/react/primitive-hooks/useThreadIsEmpty.ts +3 -0
- package/src/react/primitive-hooks/useThreadIsRunning.ts +3 -0
- package/src/react/primitives/message/MessageParts.tsx +0 -1
- package/src/react/primitives/thread/ThreadMessages.tsx +2 -1
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.retry.test.tsx +116 -0
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +1 -1
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +57 -6
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.title.test.tsx +272 -0
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +171 -124
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.republish.test.ts +87 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +327 -83
- package/src/react/runtimes/RemoteThreadResource.test.ts +141 -0
- package/src/react/runtimes/RemoteThreadResource.ts +233 -0
- package/src/react/runtimes/RuntimeAdapterProvider.tsx +8 -20
- package/src/react/runtimes/assistant-transport/commandQueue.ts +68 -0
- package/src/react/runtimes/assistant-transport/replayBoundaryStream.test.ts +455 -0
- package/src/react/runtimes/assistant-transport/replayBoundaryStream.ts +172 -0
- package/src/react/runtimes/assistant-transport/runManager.ts +124 -0
- package/src/react/runtimes/assistant-transport/transport-delivery.test.tsx +79 -0
- package/src/react/runtimes/assistant-transport/transport-parentid.test.tsx +97 -0
- package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +414 -0
- package/src/react/runtimes/assistant-transport/types.ts +170 -0
- package/src/react/runtimes/assistant-transport/useAssistantTransport.spec.md +141 -0
- package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +683 -0
- package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +483 -0
- package/src/react/runtimes/assistant-transport/useConvertedState.ts +20 -0
- package/src/react/runtimes/assistant-transport/useLatestRef.ts +9 -0
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +131 -6
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +61 -15
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +6 -4
- package/src/react/runtimes/cloud/auiV0.ts +17 -1
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +98 -3
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +104 -27
- package/src/react/runtimes/cloud/useCloudThreadListRuntime.test.tsx +56 -0
- package/src/react/runtimes/cloud/useCloudThreadListRuntime.ts +31 -0
- package/src/react/runtimes/external-message-converter.test.ts +143 -0
- package/src/react/runtimes/external-message-converter.ts +41 -41
- package/src/react/runtimes/remote-thread-hook-on-tap.test.ts +58 -0
- package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +83 -0
- package/src/react/runtimes/useExternalStoreRuntime.suggestions.test.tsx +13 -3
- package/src/react/runtimes/useExternalStoreRuntime.ts +7 -0
- package/src/react/runtimes/useExternalStoreSharedOptions.ts +3 -1
- package/src/react/runtimes/useLocalRuntime.test.tsx +134 -8
- package/src/react/runtimes/useRuntimeAdapters.test.tsx +62 -0
- package/src/react/runtimes/useRuntimeAdapters.ts +28 -0
- package/src/runtime/api/composer-runtime.ts +5 -0
- package/src/runtime/api/thread-list-runtime.ts +3 -1
- package/src/runtime/api/thread-runtime.ts +20 -2
- package/src/runtime/base/base-composer-runtime-core.ts +6 -5
- package/src/runtime/base/base-thread-runtime-core.test.ts +191 -0
- package/src/runtime/base/base-thread-runtime-core.ts +11 -2
- package/src/runtime/base/default-thread-composer-runtime-core.ts +12 -4
- package/src/runtime/interfaces/thread-runtime-core.ts +6 -0
- package/src/runtime/queue/message-queue.ts +2 -1
- package/src/runtime/utils/message-repository.ts +26 -18
- package/src/runtime/utils/thread-runtime-lifecycle.ts +18 -0
- package/src/runtimes/external-store/external-store-shared-options.ts +3 -1
- package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +4 -1
- package/src/runtimes/external-store/external-store-thread-runtime-core.ts +103 -34
- package/src/runtimes/inert/InertThreadRuntimeCore.test.ts +253 -0
- package/src/runtimes/inert/InertThreadRuntimeCore.ts +232 -0
- package/src/runtimes/local/local-thread-runtime-core.test.ts +692 -4
- package/src/runtimes/local/local-thread-runtime-core.ts +117 -22
- package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +17 -205
- package/src/runtimes/remote-thread-list/adapter-changed.ts +10 -0
- package/src/runtimes/remote-thread-list/empty-thread-core.ts +28 -217
- package/src/runtimes/remote-thread-list/optimistic-state.test.ts +18 -0
- package/src/runtimes/remote-thread-list/optimistic-state.ts +13 -0
- package/src/runtimes/remote-thread-list/types.ts +34 -0
- package/src/runtimes/tool-invocations/EDGE_CASES.md +17 -6
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +243 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +127 -61
- package/src/store/clients/external-thread.ts +1 -1
- package/src/store/clients/model-context-client.test.ts +16 -8
- package/src/store/clients/suggestions.ts +2 -2
- package/src/store/clients/thread-selection-events.ts +21 -0
- package/src/store/env.ts +11 -0
- package/src/store/index.ts +14 -1
- package/src/store/internal.ts +13 -0
- package/src/store/primitive-predicates.test.ts +184 -0
- package/src/store/primitive-predicates.ts +43 -0
- package/src/store/runtime-clients/attachment-runtime-client.test.ts +41 -0
- package/src/store/runtime-clients/attachment-runtime-client.ts +2 -1
- package/src/store/runtime-clients/handle-runtime-action.test.ts +40 -0
- package/src/store/runtime-clients/handle-runtime-action.ts +14 -0
- package/src/store/runtime-clients/handle-thread-list-action.test.ts +69 -0
- package/src/store/runtime-clients/handle-thread-list-action.ts +6 -0
- package/src/store/runtime-clients/thread-list-item-runtime-client.ts +15 -7
- package/src/store/runtime-clients/thread-list-runtime-client.ts +9 -6
- package/src/store/scopes/composer.ts +9 -4
- package/src/store/scopes/thread-list-item.ts +7 -6
- package/src/store/scopes/thread.ts +8 -7
- package/src/store/scopes/threads.ts +14 -0
- package/src/subscribable/subscribable.test.ts +77 -1
- package/src/subscribable/subscribable.ts +38 -23
- package/src/tests/MessageRepository.test.ts +48 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +2 -2
- package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +8 -6
- package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-unarchive.test.ts +25 -0
- package/src/tests/auiV0Encode.test.ts +66 -0
- package/src/tests/base-composer-runtime-core-send.test.ts +30 -0
- package/src/tests/base-composer-runtime-core.test.ts +28 -0
- package/src/tests/composer-can-cancel.test.ts +101 -0
- package/src/tests/empty-thread-core.test.ts +6 -0
- package/src/tests/external-store-thread-list-runtime-core.test.ts +101 -0
- package/src/tests/external-store-thread-runtime-core-adapter.test.ts +211 -1
- package/src/tests/external-store-thread-runtime-core.test.ts +124 -0
- package/src/tests/external-thread-isEmpty.test.tsx +100 -0
- package/src/tests/interactables-toolui-migration.test.tsx +66 -0
- package/src/tests/message-queue.test.ts +28 -0
- package/src/tests/remote-thread-list-adapter-switch.test.ts +383 -0
- package/src/tests/session-reset-notification.test.ts +145 -0
- package/src/tests/thread-switch-events.test.tsx +99 -1
- package/src/tests/tools-scope-migration.test.tsx +58 -0
- package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +67 -0
- package/src/types/message.ts +1 -1
- package/src/utils/composite-context-provider.test.ts +139 -0
- package/src/utils/composite-context-provider.ts +26 -8
- package/src/utils/notify-event-listeners.ts +10 -5
- package/src/utils/silent-runtime-action.ts +6 -0
|
@@ -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
|
-
|
|
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
|
+
}),
|
|
386
416
|
}),
|
|
387
|
-
|
|
388
|
-
modelContent: command.modelContent,
|
|
389
|
-
}),
|
|
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,21 +652,30 @@ 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.");
|
|
617
676
|
|
|
677
|
+
const generation = captureThreadRuntimeGeneration(this);
|
|
678
|
+
|
|
618
679
|
// Abort any in-flight client-side tool executions. Fire-and-forget —
|
|
619
680
|
// the abort resolves once executions settle, but we don't gate the
|
|
620
681
|
// cancel on it.
|
|
@@ -625,7 +686,7 @@ export class ExternalStoreThreadRuntimeCore
|
|
|
625
686
|
// stopped.
|
|
626
687
|
this._store.queue?.__internal_notifyCancelled?.();
|
|
627
688
|
|
|
628
|
-
this._store.onCancel();
|
|
689
|
+
observeAdapterCallback("onCancel", this._store.onCancel());
|
|
629
690
|
|
|
630
691
|
this.dropEmptyOptimisticHead();
|
|
631
692
|
|
|
@@ -672,6 +733,8 @@ export class ExternalStoreThreadRuntimeCore
|
|
|
672
733
|
// tick. Read the repository at flush time and re-apply the rollbacks to
|
|
673
734
|
// it, instead of stamping a snapshot captured above over the newer state.
|
|
674
735
|
setTimeout(() => {
|
|
736
|
+
if (!isThreadRuntimeGenerationCurrent(this, generation)) return;
|
|
737
|
+
|
|
675
738
|
this.dropEmptyOptimisticHead();
|
|
676
739
|
if (movedLeaf) {
|
|
677
740
|
const current = this.repository.getMessages();
|
|
@@ -700,7 +763,10 @@ export class ExternalStoreThreadRuntimeCore
|
|
|
700
763
|
public addToolResult(options: AddToolResultOptions) {
|
|
701
764
|
if (!this._store.onAddToolResult)
|
|
702
765
|
throw new Error("Runtime does not support tool results.");
|
|
703
|
-
|
|
766
|
+
observeAdapterCallback(
|
|
767
|
+
"onAddToolResult",
|
|
768
|
+
this._store.onAddToolResult(options),
|
|
769
|
+
);
|
|
704
770
|
}
|
|
705
771
|
|
|
706
772
|
public resumeToolCall(options: ResumeToolCallOptions) {
|
|
@@ -726,7 +792,10 @@ export class ExternalStoreThreadRuntimeCore
|
|
|
726
792
|
public respondToToolApproval(options: RespondToToolApprovalOptions) {
|
|
727
793
|
if (!this._store.onRespondToToolApproval)
|
|
728
794
|
throw new Error("Runtime does not support tool approvals.");
|
|
729
|
-
|
|
795
|
+
observeAdapterCallback(
|
|
796
|
+
"onRespondToToolApproval",
|
|
797
|
+
this._store.onRespondToToolApproval(options),
|
|
798
|
+
);
|
|
730
799
|
}
|
|
731
800
|
|
|
732
801
|
public override reset(initialMessages?: readonly ThreadMessageLike[]) {
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { BaseSubscribable } from "../../subscribable/subscribable";
|
|
3
|
+
import { ReadonlyThreadRuntimeCore } from "../readonly/ReadonlyThreadRuntimeCore";
|
|
4
|
+
import { EMPTY_THREAD_CORE } from "../remote-thread-list/empty-thread-core";
|
|
5
|
+
|
|
6
|
+
const READONLY_ERROR = /readonly thread/;
|
|
7
|
+
const EMPTY_ERROR = /empty thread/;
|
|
8
|
+
|
|
9
|
+
const SHARED_THROWING_METHODS = [
|
|
10
|
+
"switchToBranch",
|
|
11
|
+
"append",
|
|
12
|
+
"deleteMessage",
|
|
13
|
+
"startRun",
|
|
14
|
+
"resumeRun",
|
|
15
|
+
"unstable_notifySessionReset",
|
|
16
|
+
"addToolResult",
|
|
17
|
+
"resumeToolCall",
|
|
18
|
+
"respondToToolApproval",
|
|
19
|
+
"speak",
|
|
20
|
+
"connectVoice",
|
|
21
|
+
"muteVoice",
|
|
22
|
+
"unmuteVoice",
|
|
23
|
+
"submitFeedback",
|
|
24
|
+
"exportExternalState",
|
|
25
|
+
"importExternalState",
|
|
26
|
+
"beginEdit",
|
|
27
|
+
"import",
|
|
28
|
+
"reset",
|
|
29
|
+
] as const;
|
|
30
|
+
|
|
31
|
+
const SHARED_THROWING_COMPOSER_METHODS = [
|
|
32
|
+
"setText",
|
|
33
|
+
"setRole",
|
|
34
|
+
"setRunConfig",
|
|
35
|
+
"send",
|
|
36
|
+
"startDictation",
|
|
37
|
+
"setQuote",
|
|
38
|
+
] as const;
|
|
39
|
+
|
|
40
|
+
const SHARED_NOOP_COMPOSER_METHODS = [
|
|
41
|
+
"cancel",
|
|
42
|
+
"stopDictation",
|
|
43
|
+
"moveQueueItem",
|
|
44
|
+
"removeQueueItem",
|
|
45
|
+
] as const;
|
|
46
|
+
|
|
47
|
+
type AnyCore = Record<string, any>;
|
|
48
|
+
|
|
49
|
+
const cores = [
|
|
50
|
+
[
|
|
51
|
+
"ReadonlyThreadRuntimeCore",
|
|
52
|
+
() => new ReadonlyThreadRuntimeCore() as unknown as AnyCore,
|
|
53
|
+
READONLY_ERROR,
|
|
54
|
+
],
|
|
55
|
+
[
|
|
56
|
+
"EMPTY_THREAD_CORE",
|
|
57
|
+
() => EMPTY_THREAD_CORE as unknown as AnyCore,
|
|
58
|
+
EMPTY_ERROR,
|
|
59
|
+
],
|
|
60
|
+
] as const;
|
|
61
|
+
|
|
62
|
+
describe.each(cores)("%s shared inert surface", (_name, makeCore, error) => {
|
|
63
|
+
it.each(SHARED_THROWING_METHODS)("%s throws the core's error", (method) => {
|
|
64
|
+
expect(() => makeCore()[method]!()).toThrow(error);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it.each(SHARED_THROWING_COMPOSER_METHODS)(
|
|
68
|
+
"composer.%s throws the core's error",
|
|
69
|
+
(method) => {
|
|
70
|
+
expect(() => makeCore().composer[method]!()).toThrow(error);
|
|
71
|
+
},
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
it.each(["addAttachment", "removeAttachment"] as const)(
|
|
75
|
+
"composer.%s rejects with the core's error",
|
|
76
|
+
async (method) => {
|
|
77
|
+
await expect(makeCore().composer[method]!()).rejects.toThrow(error);
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
it.each(SHARED_NOOP_COMPOSER_METHODS)("composer.%s is a no-op", (method) => {
|
|
82
|
+
expect(() => makeCore().composer[method]!()).not.toThrow();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("composer.reset and composer.clearAttachments resolve without throwing", async () => {
|
|
86
|
+
const core = makeCore();
|
|
87
|
+
await expect(core.composer.reset()).resolves.toBeUndefined();
|
|
88
|
+
await expect(core.composer.clearAttachments()).resolves.toBeUndefined();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("reports every capability as disabled", () => {
|
|
92
|
+
expect(makeCore().capabilities).toEqual({
|
|
93
|
+
switchToBranch: false,
|
|
94
|
+
switchBranchDuringRun: false,
|
|
95
|
+
edit: false,
|
|
96
|
+
delete: false,
|
|
97
|
+
reload: false,
|
|
98
|
+
refetchThread: false,
|
|
99
|
+
cancel: false,
|
|
100
|
+
unstable_copy: false,
|
|
101
|
+
speech: false,
|
|
102
|
+
dictation: false,
|
|
103
|
+
voice: false,
|
|
104
|
+
attachments: false,
|
|
105
|
+
feedback: false,
|
|
106
|
+
queue: false,
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("exposes inert read-only state", () => {
|
|
111
|
+
const core = makeCore();
|
|
112
|
+
expect(core.getModelContext()).toEqual({});
|
|
113
|
+
expect(core.getEditComposer()).toBeUndefined();
|
|
114
|
+
expect(core.getVoiceVolume()).toBe(0);
|
|
115
|
+
expect(core.speech).toBeUndefined();
|
|
116
|
+
expect(core.voice).toBeUndefined();
|
|
117
|
+
expect(core.state).toBeNull();
|
|
118
|
+
expect(core.suggestions).toEqual([]);
|
|
119
|
+
expect(core.extras).toBeUndefined();
|
|
120
|
+
expect(core.isDisabled).toBe(false);
|
|
121
|
+
expect(core.isSendDisabled).toBe(false);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("exposes an empty composer that accepts everything and holds nothing", () => {
|
|
125
|
+
const composer = makeCore().composer;
|
|
126
|
+
expect(composer.attachmentAccept).toBe("*");
|
|
127
|
+
expect(composer.attachments).toEqual([]);
|
|
128
|
+
expect(composer.text).toBe("");
|
|
129
|
+
expect(composer.role).toBe("user");
|
|
130
|
+
expect(composer.runConfig).toEqual({});
|
|
131
|
+
expect(composer.queue).toEqual([]);
|
|
132
|
+
expect(composer.dictation).toBeUndefined();
|
|
133
|
+
expect(composer.quote).toBeUndefined();
|
|
134
|
+
expect(composer.isEmpty).toBe(true);
|
|
135
|
+
expect(composer.canSend).toBe(false);
|
|
136
|
+
expect(composer.canCancel).toBe(false);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("throws one stable error object from every mutator", () => {
|
|
140
|
+
const core = makeCore();
|
|
141
|
+
const thrown = SHARED_THROWING_METHODS.map((method) => {
|
|
142
|
+
try {
|
|
143
|
+
core[method]!();
|
|
144
|
+
return undefined;
|
|
145
|
+
} catch (e) {
|
|
146
|
+
return e;
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
expect(thrown[0]).toBeInstanceOf(Error);
|
|
151
|
+
expect(thrown.every((e) => e === thrown[0])).toBe(true);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("throws a receiver TypeError when a mutator is detached", () => {
|
|
155
|
+
const detached = makeCore().append!;
|
|
156
|
+
expect(() => detached()).toThrow(TypeError);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("subscribeVoiceVolume and unstable_on hand back no-op unsubscribers", () => {
|
|
160
|
+
const core = makeCore();
|
|
161
|
+
expect(() => core.subscribeVoiceVolume(() => {})()).not.toThrow();
|
|
162
|
+
expect(() => core.unstable_on("runStart", () => {})()).not.toThrow();
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
describe("no-op versus throw divergences", () => {
|
|
167
|
+
it.each(["cancelRun", "stopSpeaking", "disconnectVoice"] as const)(
|
|
168
|
+
"%s is a no-op on the readonly core but throws on the empty core",
|
|
169
|
+
(method) => {
|
|
170
|
+
const readonly = new ReadonlyThreadRuntimeCore() as unknown as AnyCore;
|
|
171
|
+
expect(() => readonly[method]!()).not.toThrow();
|
|
172
|
+
expect(() =>
|
|
173
|
+
(EMPTY_THREAD_CORE as unknown as AnyCore)[method]!(),
|
|
174
|
+
).toThrow(EMPTY_ERROR);
|
|
175
|
+
},
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
it("readonly is not loading; empty is loading so it is not read as an empty conversation", () => {
|
|
179
|
+
expect(new ReadonlyThreadRuntimeCore().isLoading).toBe(false);
|
|
180
|
+
expect(EMPTY_THREAD_CORE.isLoading).toBe(true);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it("readonly composer is not editing; empty composer is", () => {
|
|
184
|
+
expect(new ReadonlyThreadRuntimeCore().composer.isEditing).toBe(false);
|
|
185
|
+
expect(EMPTY_THREAD_CORE.composer.isEditing).toBe(true);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("the two cores carry distinct error objects and messages", () => {
|
|
189
|
+
const grab = (fn: () => void) => {
|
|
190
|
+
try {
|
|
191
|
+
fn();
|
|
192
|
+
return undefined;
|
|
193
|
+
} catch (e) {
|
|
194
|
+
return e as Error;
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const readonlyError = grab(() => new ReadonlyThreadRuntimeCore().append());
|
|
199
|
+
const emptyError = grab(() =>
|
|
200
|
+
(EMPTY_THREAD_CORE as unknown as AnyCore).append!(),
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
expect(readonlyError).not.toBe(emptyError);
|
|
204
|
+
expect(readonlyError?.message).toBe(
|
|
205
|
+
"This is a readonly thread. You cannot perform mutations on readonly threads.",
|
|
206
|
+
);
|
|
207
|
+
expect(emptyError?.message).toMatch(/placeholder for the main thread/);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
describe("readonly notifications", () => {
|
|
212
|
+
it("notifies subscribers and settles waitForUpdate when messages change", async () => {
|
|
213
|
+
const core = new ReadonlyThreadRuntimeCore();
|
|
214
|
+
const seen: number[] = [];
|
|
215
|
+
const unsubscribe = core.subscribe(() => {
|
|
216
|
+
seen.push(core.messages.length);
|
|
217
|
+
});
|
|
218
|
+
const update = core.waitForUpdate();
|
|
219
|
+
|
|
220
|
+
core.setMessages([
|
|
221
|
+
{
|
|
222
|
+
id: "m1",
|
|
223
|
+
role: "user",
|
|
224
|
+
content: [{ type: "text", text: "hi" }],
|
|
225
|
+
createdAt: new Date(0),
|
|
226
|
+
status: { type: "complete", reason: "stop" },
|
|
227
|
+
metadata: { custom: {} },
|
|
228
|
+
} as any,
|
|
229
|
+
]);
|
|
230
|
+
|
|
231
|
+
await expect(update).resolves.toBeUndefined();
|
|
232
|
+
expect(seen).toEqual([1]);
|
|
233
|
+
unsubscribe();
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
describe("empty singleton", () => {
|
|
238
|
+
it("does not retain subscribe callbacks", () => {
|
|
239
|
+
const subscribers = (
|
|
240
|
+
EMPTY_THREAD_CORE as unknown as Record<string, unknown>
|
|
241
|
+
)._subscribers as Set<unknown>;
|
|
242
|
+
const before = subscribers.size;
|
|
243
|
+
const unsubscribe = EMPTY_THREAD_CORE.subscribe(() => undefined);
|
|
244
|
+
expect(subscribers.size).toBe(before);
|
|
245
|
+
expect(() => unsubscribe()).not.toThrow();
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it("rejects waitForUpdate instead of hanging", async () => {
|
|
249
|
+
await expect(
|
|
250
|
+
(EMPTY_THREAD_CORE as unknown as BaseSubscribable).waitForUpdate(),
|
|
251
|
+
).rejects.toThrow(EMPTY_ERROR);
|
|
252
|
+
});
|
|
253
|
+
});
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import type { Unsubscribe } from "../../types/unsubscribe";
|
|
2
|
+
import type { ThreadMessage } from "../../types/message";
|
|
3
|
+
import type { ThreadRuntimeCore } from "../../runtime/interfaces/thread-runtime-core";
|
|
4
|
+
import type { ExportedMessageRepository } from "../../runtime/utils/message-repository";
|
|
5
|
+
import { BaseSubscribable } from "../../subscribable/subscribable";
|
|
6
|
+
|
|
7
|
+
export const createInertComposer = <TIsEditing extends boolean>(
|
|
8
|
+
error: Error,
|
|
9
|
+
isEditing: TIsEditing,
|
|
10
|
+
) => ({
|
|
11
|
+
attachments: [] as never[],
|
|
12
|
+
attachmentAccept: "*",
|
|
13
|
+
|
|
14
|
+
async addAttachment() {
|
|
15
|
+
throw error;
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
async removeAttachment() {
|
|
19
|
+
throw error;
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
isEditing,
|
|
23
|
+
canCancel: false,
|
|
24
|
+
canSend: false,
|
|
25
|
+
isEmpty: true,
|
|
26
|
+
text: "",
|
|
27
|
+
|
|
28
|
+
setText() {
|
|
29
|
+
throw error;
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
role: "user" as const,
|
|
33
|
+
|
|
34
|
+
setRole() {
|
|
35
|
+
throw error;
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
runConfig: {},
|
|
39
|
+
|
|
40
|
+
setRunConfig() {
|
|
41
|
+
throw error;
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
async reset() {},
|
|
45
|
+
|
|
46
|
+
async clearAttachments() {},
|
|
47
|
+
|
|
48
|
+
send() {
|
|
49
|
+
throw error;
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
cancel() {},
|
|
53
|
+
|
|
54
|
+
queue: [] as never[],
|
|
55
|
+
moveQueueItem() {},
|
|
56
|
+
removeQueueItem() {},
|
|
57
|
+
|
|
58
|
+
dictation: undefined,
|
|
59
|
+
|
|
60
|
+
startDictation() {
|
|
61
|
+
throw error;
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
stopDictation() {},
|
|
65
|
+
|
|
66
|
+
quote: undefined,
|
|
67
|
+
|
|
68
|
+
setQuote() {
|
|
69
|
+
throw error;
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
subscribe() {
|
|
73
|
+
return () => {};
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
unstable_on() {
|
|
77
|
+
return () => {};
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
export abstract class InertThreadRuntimeCore
|
|
82
|
+
extends BaseSubscribable
|
|
83
|
+
implements ThreadRuntimeCore
|
|
84
|
+
{
|
|
85
|
+
protected abstract get error(): Error;
|
|
86
|
+
|
|
87
|
+
abstract readonly messages: readonly ThreadMessage[];
|
|
88
|
+
abstract readonly isLoading: boolean;
|
|
89
|
+
abstract readonly composer: ThreadRuntimeCore["composer"];
|
|
90
|
+
|
|
91
|
+
abstract getMessageById(messageId: string):
|
|
92
|
+
| {
|
|
93
|
+
parentId: string | null;
|
|
94
|
+
message: ThreadMessage;
|
|
95
|
+
index: number;
|
|
96
|
+
}
|
|
97
|
+
| undefined;
|
|
98
|
+
|
|
99
|
+
abstract getBranches(messageId: string): readonly string[];
|
|
100
|
+
|
|
101
|
+
abstract export(): ExportedMessageRepository;
|
|
102
|
+
|
|
103
|
+
switchToBranch(): void {
|
|
104
|
+
throw this.error;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
append(): void {
|
|
108
|
+
throw this.error;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
deleteMessage(): void {
|
|
112
|
+
throw this.error;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
startRun(): void {
|
|
116
|
+
throw this.error;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
resumeRun(): void {
|
|
120
|
+
throw this.error;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
cancelRun(): void {
|
|
124
|
+
throw this.error;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
unstable_notifySessionReset(): void {
|
|
128
|
+
throw this.error;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
addToolResult(): void {
|
|
132
|
+
throw this.error;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
resumeToolCall(): void {
|
|
136
|
+
throw this.error;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
respondToToolApproval(): void {
|
|
140
|
+
throw this.error;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
speak(): void {
|
|
144
|
+
throw this.error;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
stopSpeaking(): void {
|
|
148
|
+
throw this.error;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
connectVoice(): void {
|
|
152
|
+
throw this.error;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
disconnectVoice(): void {
|
|
156
|
+
throw this.error;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
muteVoice(): void {
|
|
160
|
+
throw this.error;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
unmuteVoice(): void {
|
|
164
|
+
throw this.error;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
submitFeedback(): void {
|
|
168
|
+
throw this.error;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
exportExternalState(): void {
|
|
172
|
+
throw this.error;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
importExternalState(): void {
|
|
176
|
+
throw this.error;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
beginEdit(): void {
|
|
180
|
+
throw this.error;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
import(): void {
|
|
184
|
+
throw this.error;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
reset(): void {
|
|
188
|
+
throw this.error;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
getModelContext() {
|
|
192
|
+
return {};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
getEditComposer() {
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
getVoiceVolume = () => 0;
|
|
200
|
+
subscribeVoiceVolume = (): Unsubscribe => () => {};
|
|
201
|
+
|
|
202
|
+
speech = undefined;
|
|
203
|
+
voice = undefined;
|
|
204
|
+
|
|
205
|
+
capabilities = {
|
|
206
|
+
switchToBranch: false,
|
|
207
|
+
switchBranchDuringRun: false,
|
|
208
|
+
edit: false,
|
|
209
|
+
delete: false,
|
|
210
|
+
reload: false,
|
|
211
|
+
refetchThread: false,
|
|
212
|
+
cancel: false,
|
|
213
|
+
unstable_copy: false,
|
|
214
|
+
speech: false,
|
|
215
|
+
dictation: false,
|
|
216
|
+
voice: false,
|
|
217
|
+
attachments: false,
|
|
218
|
+
feedback: false,
|
|
219
|
+
queue: false,
|
|
220
|
+
} as const;
|
|
221
|
+
|
|
222
|
+
isDisabled = false;
|
|
223
|
+
isSendDisabled = false;
|
|
224
|
+
|
|
225
|
+
state = null;
|
|
226
|
+
suggestions = [] as never[];
|
|
227
|
+
extras = undefined;
|
|
228
|
+
|
|
229
|
+
unstable_on(): Unsubscribe {
|
|
230
|
+
return () => {};
|
|
231
|
+
}
|
|
232
|
+
}
|