@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-queue.js","names":["AppendMessage","FileMessagePart","TextMessagePart","EMPTY_QUEUE_ITEMS","QueueItemState","generateId","getThreadMessageText","ExternalThreadQueueAdapter","QueuePlacement","MessageQueueDriver","run","message","options","steer","cancel","MessageQueueController","adapter","notifyBusy","notifyIdle","notifyCancelled","clear","subscribe","callback","Lane","getQueueItemParts","source","content","attachments","flatMap","attachment","filter","part","type","parts","push","data","image","mimeType","filename","undefined","createMessageQueue","driver","lanes","Record","queue","messages","Map","subscribers","Set","running","paused","dispatchTransform","m","suppressIdle","cancelSettles","interrupting","notify","setLanes","next","items","steerItems","toItem","id","prompt","laneOf","queueItemId","some","item","advance","lane","length","head","get","delete","slice","interrupt","Math","max","set","enqueue","move","placement","fromLane","Error","toLane","find","i","dest","anchorIndex","anchor","index","findIndex","insertAfter","insertBefore","after","before","nextDest","edit","map","remove","__internal_setDispatchTransform","transform","__internal_notifyCancelled","add"],"sources":["../../../src/runtime/queue/message-queue.ts"],"sourcesContent":["import type {\n AppendMessage,\n FileMessagePart,\n TextMessagePart,\n} from \"../../types/message\";\nimport {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../store/scopes/queue-item\";\nimport { generateId } from \"../../utils/id\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport type {\n ExternalThreadQueueAdapter,\n QueuePlacement,\n} from \"./external-thread-queue-adapter\";\n\nexport type MessageQueueDriver = {\n run: (message: AppendMessage, options: { steer: boolean }) => void;\n /** When omitted, steering degrades to \"process next\" instead of interrupting. */\n cancel?: (() => void) | undefined;\n};\n\nexport type MessageQueueController = {\n readonly adapter: ExternalThreadQueueAdapter;\n /** Mark a run as in flight so concurrent sends buffer; call on the rising edge. */\n notifyBusy: () => void;\n /** Advances to the next pending message; call on the run's falling edge. */\n notifyIdle: () => void;\n /**\n * Pauses queue advance for a user-initiated cancel, so the cancelled run's\n * settle keeps the pending items instead of dispatching the next one; the\n * next explicit send or run start re-arms draining. Call before aborting\n * the run.\n */\n notifyCancelled: () => void;\n /** Empties both lanes without dispatching. */\n clear: () => void;\n subscribe: (callback: () => void) => () => void;\n};\n\ntype Lane = \"queue\" | \"steer\";\n\nconst getQueueItemParts = (\n message: AppendMessage,\n): readonly (FileMessagePart | TextMessagePart)[] => {\n // attachment-derived text is the file body, not user-authored prose;\n // project only the file/image content of attachments\n const source = [\n ...message.content,\n ...(message.attachments ?? []).flatMap((attachment) =>\n (attachment.content ?? []).filter((part) => part.type !== \"text\"),\n ),\n ];\n const parts: (FileMessagePart | TextMessagePart)[] = [];\n for (const part of source) {\n if (part.type === \"file\" || part.type === \"text\") {\n parts.push(part);\n } else if (part.type === \"image\") {\n parts.push({\n type: \"file\",\n data: part.image,\n mimeType: \"image/*\",\n ...(part.filename !== undefined && { filename: part.filename }),\n });\n }\n }\n return parts;\n};\n\nexport const createMessageQueue = (\n driver: MessageQueueDriver,\n): MessageQueueController => {\n let lanes: Record<Lane, readonly QueueItemState[]> = {\n queue: EMPTY_QUEUE_ITEMS,\n steer: EMPTY_QUEUE_ITEMS,\n };\n const messages = new Map<string, AppendMessage>();\n const subscribers = new Set<() => void>();\n\n let running = false;\n let paused = false;\n let dispatchTransform: (message: AppendMessage) => AppendMessage = (m) => m;\n // swallow the cancelled run's settle when steering so it does not double-advance\n let suppressIdle = 0;\n // settles from cancelled runs that must drop `running` without advancing\n let cancelSettles = 0;\n let interrupting = false;\n\n const notify = () => {\n for (const callback of subscribers) callback();\n };\n\n const setLanes = (next: Record<Lane, readonly QueueItemState[]>) => {\n lanes = next;\n adapter.items = next.queue;\n adapter.steerItems = next.steer;\n notify();\n };\n\n const toItem = (id: string, message: AppendMessage): QueueItemState => ({\n id,\n prompt: getThreadMessageText(message),\n parts: getQueueItemParts(message),\n });\n\n const laneOf = (queueItemId: string): Lane | undefined => {\n if (lanes.steer.some((item) => item.id === queueItemId)) return \"steer\";\n if (lanes.queue.some((item) => item.id === queueItemId)) return \"queue\";\n return undefined;\n };\n\n const advance = () => {\n if (running || paused) return;\n const lane: Lane = lanes.steer.length > 0 ? \"steer\" : \"queue\";\n const head = lanes[lane][0];\n if (!head) return;\n const message = messages.get(head.id);\n messages.delete(head.id);\n setLanes({ ...lanes, [lane]: lanes[lane].slice(1) });\n if (!message) return;\n running = true;\n driver.run(dispatchTransform(message), { steer: false });\n };\n\n const interrupt = (message: AppendMessage) => {\n paused = false;\n // the interrupted run settles exactly once, whether or not it was\n // already cancel-notified\n suppressIdle += Math.max(cancelSettles, 1);\n cancelSettles = 0;\n // a driver whose cancel routes through the runtime notifies this queue\n // back; the interrupt already accounted for that settle and is dispatching\n // in its place\n interrupting = true;\n try {\n driver.cancel!();\n } finally {\n interrupting = false;\n }\n running = true;\n driver.run(dispatchTransform(message), { steer: true });\n };\n\n const push = (lane: Lane, message: AppendMessage) => {\n paused = false;\n const id = generateId();\n messages.set(id, message);\n setLanes({ ...lanes, [lane]: [...lanes[lane], toItem(id, message)] });\n advance();\n };\n\n const enqueue = (message: AppendMessage) => {\n push(\"queue\", message);\n };\n\n const steer = (message: AppendMessage) => {\n if (running && driver.cancel) {\n interrupt(message);\n return;\n }\n push(\"steer\", message);\n };\n\n const move = (queueItemId: string, placement: QueuePlacement) => {\n const fromLane = laneOf(queueItemId);\n if (!fromLane) throw new Error(`Unknown queue item \"${queueItemId}\".`);\n const toLane = placement.lane ?? fromLane;\n\n const item = lanes[fromLane].find((i) => i.id === queueItemId)!;\n const dest = (toLane === fromLane ? lanes[fromLane] : lanes[toLane]).filter(\n (i) => i.id !== queueItemId,\n );\n\n const anchorIndex = (anchor: string) => {\n if (anchor === queueItemId)\n throw new Error(`Queue item \"${queueItemId}\" cannot anchor itself.`);\n const index = dest.findIndex((i) => i.id === anchor);\n if (index === -1)\n throw new Error(`Unknown anchor \"${anchor}\" in lane \"${toLane}\".`);\n return index;\n };\n\n const { insertAfter, insertBefore } = placement;\n let index: number;\n if (insertAfter === undefined && insertBefore === undefined) {\n index =\n toLane === fromLane\n ? lanes[fromLane].findIndex((i) => i.id === queueItemId)\n : dest.length;\n } else if (insertAfter !== undefined && insertBefore !== undefined) {\n const after = insertAfter === null ? -1 : anchorIndex(insertAfter);\n const before =\n insertBefore === null ? dest.length : anchorIndex(insertBefore);\n if (before !== after + 1)\n throw new Error(\n `insertAfter \"${insertAfter}\" and insertBefore \"${insertBefore}\" are not adjacent in lane \"${toLane}\".`,\n );\n index = after + 1;\n } else if (insertAfter !== undefined) {\n index = insertAfter === null ? 0 : anchorIndex(insertAfter) + 1;\n } else {\n index = insertBefore === null ? dest.length : anchorIndex(insertBefore!);\n }\n\n // placement and immediate dispatch cannot coexist: an anchored move into\n // the steer lane places without interrupting; only an unanchored one\n // cancels the live run and dispatches\n if (\n insertAfter === undefined &&\n insertBefore === undefined &&\n toLane === \"steer\" &&\n fromLane !== \"steer\" &&\n running &&\n driver.cancel\n ) {\n const message = messages.get(queueItemId)!;\n messages.delete(queueItemId);\n setLanes({\n queue: lanes.queue.filter((i) => i.id !== queueItemId),\n steer: lanes.steer,\n });\n interrupt(message);\n return;\n }\n\n const nextDest = [...dest.slice(0, index), item, ...dest.slice(index)];\n const next = { ...lanes, [toLane]: nextDest };\n if (toLane !== fromLane)\n next[fromLane] = lanes[fromLane].filter((i) => i.id !== queueItemId);\n setLanes(next);\n advance();\n };\n\n const edit = (queueItemId: string, message: AppendMessage) => {\n const lane = laneOf(queueItemId);\n if (!lane) throw new Error(`Unknown queue item \"${queueItemId}\".`);\n messages.set(queueItemId, message);\n setLanes({\n ...lanes,\n [lane]: lanes[lane].map((item) =>\n item.id === queueItemId ? toItem(queueItemId, message) : item,\n ),\n });\n };\n\n const remove = (queueItemId: string) => {\n if (!messages.delete(queueItemId)) return;\n setLanes({\n queue: lanes.queue.filter((item) => item.id !== queueItemId),\n steer: lanes.steer.filter((item) => item.id !== queueItemId),\n });\n };\n\n const notifyCancelled = () => {\n if (interrupting) return;\n if (running && cancelSettles === 0) {\n paused = true;\n cancelSettles = 1;\n }\n };\n\n const adapter: ExternalThreadQueueAdapter = {\n items: lanes.queue,\n steerItems: lanes.steer,\n enqueue,\n steer,\n move,\n edit,\n remove,\n __internal_setDispatchTransform: (transform) => {\n dispatchTransform = transform;\n },\n __internal_notifyCancelled: notifyCancelled,\n };\n\n return {\n adapter,\n notifyBusy: () => {\n paused = false;\n // a cancelled run's settle that is still outstanding belongs to a run\n // this new one replaces; swallow it entirely\n suppressIdle += cancelSettles;\n cancelSettles = 0;\n running = true;\n },\n notifyIdle: () => {\n if (suppressIdle > 0) {\n suppressIdle--;\n return;\n }\n if (cancelSettles > 0) cancelSettles--;\n running = false;\n advance();\n },\n notifyCancelled,\n clear: () => {\n messages.clear();\n setLanes({ queue: EMPTY_QUEUE_ITEMS, steer: EMPTY_QUEUE_ITEMS });\n },\n subscribe: (callback) => {\n subscribers.add(callback);\n return () => {\n subscribers.delete(callback);\n };\n },\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"message-queue.js","names":["AppendMessage","FileMessagePart","TextMessagePart","EMPTY_QUEUE_ITEMS","QueueItemState","generateId","notifyEventListeners","getThreadMessageText","ExternalThreadQueueAdapter","QueuePlacement","MessageQueueDriver","run","message","options","steer","cancel","MessageQueueController","adapter","notifyBusy","notifyIdle","notifyCancelled","clear","subscribe","callback","Lane","getQueueItemParts","source","content","attachments","flatMap","attachment","filter","part","type","parts","push","data","image","mimeType","filename","undefined","createMessageQueue","driver","lanes","Record","queue","messages","Map","subscribers","Set","running","paused","dispatchTransform","m","suppressIdle","cancelSettles","interrupting","notify","setLanes","next","items","steerItems","toItem","id","prompt","laneOf","queueItemId","some","item","advance","lane","length","head","get","delete","slice","interrupt","Math","max","set","enqueue","move","placement","fromLane","Error","toLane","find","i","dest","anchorIndex","anchor","index","findIndex","insertAfter","insertBefore","after","before","nextDest","edit","map","remove","__internal_setDispatchTransform","transform","__internal_notifyCancelled","add"],"sources":["../../../src/runtime/queue/message-queue.ts"],"sourcesContent":["import type {\n AppendMessage,\n FileMessagePart,\n TextMessagePart,\n} from \"../../types/message\";\nimport {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../store/scopes/queue-item\";\nimport { generateId } from \"../../utils/id\";\nimport { notifyEventListeners } from \"../../utils/notify-event-listeners\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport type {\n ExternalThreadQueueAdapter,\n QueuePlacement,\n} from \"./external-thread-queue-adapter\";\n\nexport type MessageQueueDriver = {\n run: (message: AppendMessage, options: { steer: boolean }) => void;\n /** When omitted, steering degrades to \"process next\" instead of interrupting. */\n cancel?: (() => void) | undefined;\n};\n\nexport type MessageQueueController = {\n readonly adapter: ExternalThreadQueueAdapter;\n /** Mark a run as in flight so concurrent sends buffer; call on the rising edge. */\n notifyBusy: () => void;\n /** Advances to the next pending message; call on the run's falling edge. */\n notifyIdle: () => void;\n /**\n * Pauses queue advance for a user-initiated cancel, so the cancelled run's\n * settle keeps the pending items instead of dispatching the next one; the\n * next explicit send or run start re-arms draining. Call before aborting\n * the run.\n */\n notifyCancelled: () => void;\n /** Empties both lanes without dispatching. */\n clear: () => void;\n subscribe: (callback: () => void) => () => void;\n};\n\ntype Lane = \"queue\" | \"steer\";\n\nconst getQueueItemParts = (\n message: AppendMessage,\n): readonly (FileMessagePart | TextMessagePart)[] => {\n // attachment-derived text is the file body, not user-authored prose;\n // project only the file/image content of attachments\n const source = [\n ...message.content,\n ...(message.attachments ?? []).flatMap((attachment) =>\n (attachment.content ?? []).filter((part) => part.type !== \"text\"),\n ),\n ];\n const parts: (FileMessagePart | TextMessagePart)[] = [];\n for (const part of source) {\n if (part.type === \"file\" || part.type === \"text\") {\n parts.push(part);\n } else if (part.type === \"image\") {\n parts.push({\n type: \"file\",\n data: part.image,\n mimeType: \"image/*\",\n ...(part.filename !== undefined && { filename: part.filename }),\n });\n }\n }\n return parts;\n};\n\nexport const createMessageQueue = (\n driver: MessageQueueDriver,\n): MessageQueueController => {\n let lanes: Record<Lane, readonly QueueItemState[]> = {\n queue: EMPTY_QUEUE_ITEMS,\n steer: EMPTY_QUEUE_ITEMS,\n };\n const messages = new Map<string, AppendMessage>();\n const subscribers = new Set<() => void>();\n\n let running = false;\n let paused = false;\n let dispatchTransform: (message: AppendMessage) => AppendMessage = (m) => m;\n // swallow the cancelled run's settle when steering so it does not double-advance\n let suppressIdle = 0;\n // settles from cancelled runs that must drop `running` without advancing\n let cancelSettles = 0;\n let interrupting = false;\n\n const notify = () => {\n notifyEventListeners(subscribers, undefined, \"Message queue\");\n };\n\n const setLanes = (next: Record<Lane, readonly QueueItemState[]>) => {\n lanes = next;\n adapter.items = next.queue;\n adapter.steerItems = next.steer;\n notify();\n };\n\n const toItem = (id: string, message: AppendMessage): QueueItemState => ({\n id,\n prompt: getThreadMessageText(message),\n parts: getQueueItemParts(message),\n });\n\n const laneOf = (queueItemId: string): Lane | undefined => {\n if (lanes.steer.some((item) => item.id === queueItemId)) return \"steer\";\n if (lanes.queue.some((item) => item.id === queueItemId)) return \"queue\";\n return undefined;\n };\n\n const advance = () => {\n if (running || paused) return;\n const lane: Lane = lanes.steer.length > 0 ? \"steer\" : \"queue\";\n const head = lanes[lane][0];\n if (!head) return;\n const message = messages.get(head.id);\n messages.delete(head.id);\n setLanes({ ...lanes, [lane]: lanes[lane].slice(1) });\n if (!message) return;\n running = true;\n driver.run(dispatchTransform(message), { steer: false });\n };\n\n const interrupt = (message: AppendMessage) => {\n paused = false;\n // the interrupted run settles exactly once, whether or not it was\n // already cancel-notified\n suppressIdle += Math.max(cancelSettles, 1);\n cancelSettles = 0;\n // a driver whose cancel routes through the runtime notifies this queue\n // back; the interrupt already accounted for that settle and is dispatching\n // in its place\n interrupting = true;\n try {\n driver.cancel!();\n } finally {\n interrupting = false;\n }\n running = true;\n driver.run(dispatchTransform(message), { steer: true });\n };\n\n const push = (lane: Lane, message: AppendMessage) => {\n paused = false;\n const id = generateId();\n messages.set(id, message);\n setLanes({ ...lanes, [lane]: [...lanes[lane], toItem(id, message)] });\n advance();\n };\n\n const enqueue = (message: AppendMessage) => {\n push(\"queue\", message);\n };\n\n const steer = (message: AppendMessage) => {\n if (running && driver.cancel) {\n interrupt(message);\n return;\n }\n push(\"steer\", message);\n };\n\n const move = (queueItemId: string, placement: QueuePlacement) => {\n const fromLane = laneOf(queueItemId);\n if (!fromLane) throw new Error(`Unknown queue item \"${queueItemId}\".`);\n const toLane = placement.lane ?? fromLane;\n\n const item = lanes[fromLane].find((i) => i.id === queueItemId)!;\n const dest = (toLane === fromLane ? lanes[fromLane] : lanes[toLane]).filter(\n (i) => i.id !== queueItemId,\n );\n\n const anchorIndex = (anchor: string) => {\n if (anchor === queueItemId)\n throw new Error(`Queue item \"${queueItemId}\" cannot anchor itself.`);\n const index = dest.findIndex((i) => i.id === anchor);\n if (index === -1)\n throw new Error(`Unknown anchor \"${anchor}\" in lane \"${toLane}\".`);\n return index;\n };\n\n const { insertAfter, insertBefore } = placement;\n let index: number;\n if (insertAfter === undefined && insertBefore === undefined) {\n index =\n toLane === fromLane\n ? lanes[fromLane].findIndex((i) => i.id === queueItemId)\n : dest.length;\n } else if (insertAfter !== undefined && insertBefore !== undefined) {\n const after = insertAfter === null ? -1 : anchorIndex(insertAfter);\n const before =\n insertBefore === null ? dest.length : anchorIndex(insertBefore);\n if (before !== after + 1)\n throw new Error(\n `insertAfter \"${insertAfter}\" and insertBefore \"${insertBefore}\" are not adjacent in lane \"${toLane}\".`,\n );\n index = after + 1;\n } else if (insertAfter !== undefined) {\n index = insertAfter === null ? 0 : anchorIndex(insertAfter) + 1;\n } else {\n index = insertBefore === null ? dest.length : anchorIndex(insertBefore!);\n }\n\n // placement and immediate dispatch cannot coexist: an anchored move into\n // the steer lane places without interrupting; only an unanchored one\n // cancels the live run and dispatches\n if (\n insertAfter === undefined &&\n insertBefore === undefined &&\n toLane === \"steer\" &&\n fromLane !== \"steer\" &&\n running &&\n driver.cancel\n ) {\n const message = messages.get(queueItemId)!;\n messages.delete(queueItemId);\n setLanes({\n queue: lanes.queue.filter((i) => i.id !== queueItemId),\n steer: lanes.steer,\n });\n interrupt(message);\n return;\n }\n\n const nextDest = [...dest.slice(0, index), item, ...dest.slice(index)];\n const next = { ...lanes, [toLane]: nextDest };\n if (toLane !== fromLane)\n next[fromLane] = lanes[fromLane].filter((i) => i.id !== queueItemId);\n setLanes(next);\n advance();\n };\n\n const edit = (queueItemId: string, message: AppendMessage) => {\n const lane = laneOf(queueItemId);\n if (!lane) throw new Error(`Unknown queue item \"${queueItemId}\".`);\n messages.set(queueItemId, message);\n setLanes({\n ...lanes,\n [lane]: lanes[lane].map((item) =>\n item.id === queueItemId ? toItem(queueItemId, message) : item,\n ),\n });\n };\n\n const remove = (queueItemId: string) => {\n if (!messages.delete(queueItemId)) return;\n setLanes({\n queue: lanes.queue.filter((item) => item.id !== queueItemId),\n steer: lanes.steer.filter((item) => item.id !== queueItemId),\n });\n };\n\n const notifyCancelled = () => {\n if (interrupting) return;\n if (running && cancelSettles === 0) {\n paused = true;\n cancelSettles = 1;\n }\n };\n\n const adapter: ExternalThreadQueueAdapter = {\n items: lanes.queue,\n steerItems: lanes.steer,\n enqueue,\n steer,\n move,\n edit,\n remove,\n __internal_setDispatchTransform: (transform) => {\n dispatchTransform = transform;\n },\n __internal_notifyCancelled: notifyCancelled,\n };\n\n return {\n adapter,\n notifyBusy: () => {\n paused = false;\n // a cancelled run's settle that is still outstanding belongs to a run\n // this new one replaces; swallow it entirely\n suppressIdle += cancelSettles;\n cancelSettles = 0;\n running = true;\n },\n notifyIdle: () => {\n if (suppressIdle > 0) {\n suppressIdle--;\n return;\n }\n if (cancelSettles > 0) cancelSettles--;\n running = false;\n advance();\n },\n notifyCancelled,\n clear: () => {\n messages.clear();\n setLanes({ queue: EMPTY_QUEUE_ITEMS, steer: EMPTY_QUEUE_ITEMS });\n },\n subscribe: (callback) => {\n subscribers.add(callback);\n return () => {\n subscribers.delete(callback);\n };\n },\n };\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-repository.d.ts","names":[],"sources":["../../../src/runtime/utils/message-repository.ts"],"mappings":";;;KAOY;EACV,SAAS;EACT;EACA,YAAY;;KAGF;EACV;EACA,UAAU;IACR,SAAS;IACT;IACA,YAAY;;;cAIH;EAEC,YAAA,mBAAS,wBAClB;EAkBM,sBAAA;IACL,SAAS;IACT;OACC;IACS;QACX;;cA6DQ;UACH;UACA;UACA;UAKA;
|
|
1
|
+
{"version":3,"file":"message-repository.d.ts","names":[],"sources":["../../../src/runtime/utils/message-repository.ts"],"mappings":";;;KAOY;EACV,SAAS;EACT;EACA,YAAY;;KAGF;EACV;EACA,UAAU;IACR,SAAS;IACT;IACA,YAAY;;;cAIH;EAEC,YAAA,mBAAS,wBAClB;EAkBM,sBAAA;IACL,SAAS;IACT;OACC;IACS;QACX;;cA6DQ;UACH;UACA;UACA;UAKA;UAgBA;UA2DA;MAQJ;MAIA;EAUJ,YAAY,2BAAe;EAuB3B,mBAAmB,yBAAyB,SAAS;EAiCrD,WAAW;;;;;EAcX,cAAc,mBAAmB;EAsCjC,YAAY;;;;;;;;;UAmBJ;EA+BR,eAAe;EAkBf,UAAU;EAiDV;EAUA,UAAU;EAwBV,SAAS,QAAQ,YAAY"}
|
|
@@ -25,9 +25,9 @@ const ExportedMessageRepository = {
|
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
27
|
const findHead = (message) => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return null;
|
|
28
|
+
let current = message;
|
|
29
|
+
while (current.next) current = current.next;
|
|
30
|
+
return "current" in current ? current : null;
|
|
31
31
|
};
|
|
32
32
|
var CachedValue = class {
|
|
33
33
|
_value = null;
|
|
@@ -51,18 +51,28 @@ var MessageRepository = class {
|
|
|
51
51
|
next: null
|
|
52
52
|
};
|
|
53
53
|
updateLevels(message, newLevel) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
const pending = [{
|
|
55
|
+
message,
|
|
56
|
+
level: newLevel
|
|
57
|
+
}];
|
|
58
|
+
while (pending.length > 0) {
|
|
59
|
+
const current = pending.pop();
|
|
60
|
+
current.message.level = current.level;
|
|
61
|
+
for (const childId of current.message.children) {
|
|
62
|
+
const childMessage = this.messages.get(childId);
|
|
63
|
+
if (childMessage) pending.push({
|
|
64
|
+
message: childMessage,
|
|
65
|
+
level: current.level + 1
|
|
66
|
+
});
|
|
67
|
+
}
|
|
58
68
|
}
|
|
59
69
|
}
|
|
60
70
|
performOp(newParent, child, operation) {
|
|
61
71
|
const parentOrRoot = child.prev ?? this.root;
|
|
62
72
|
const newParentOrRoot = newParent ?? this.root;
|
|
63
73
|
if (operation === "relink" && parentOrRoot === newParentOrRoot) return;
|
|
64
|
-
if (operation
|
|
65
|
-
for (let current = newParent; current; current = current.prev) if (current.current.id === child.current.id) throw new Error("MessageRepository(performOp/
|
|
74
|
+
if (operation === "relink") {
|
|
75
|
+
for (let current = newParent; current; current = current.prev) if (current.current.id === child.current.id) throw new Error("MessageRepository(performOp/relink): A message with the same id already exists in the parent tree. This error occurs if the same message id is found multiple times. This is likely an internal bug in assistant-ui.");
|
|
66
76
|
}
|
|
67
77
|
if (operation !== "link") {
|
|
68
78
|
parentOrRoot.children = parentOrRoot.children.filter((m) => m !== child.current.id);
|
|
@@ -192,16 +202,15 @@ var MessageRepository = class {
|
|
|
192
202
|
if (!message) throw new Error("MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui.");
|
|
193
203
|
const previousHead = this.head;
|
|
194
204
|
if (message.children.length > 0) {
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
205
|
+
const pending = [...message.children];
|
|
206
|
+
while (pending.length > 0) {
|
|
207
|
+
const childId = pending.pop();
|
|
208
|
+
const childMessage = this.messages.get(childId);
|
|
209
|
+
if (childMessage) {
|
|
210
|
+
for (const descendantId of childMessage.children) pending.push(descendantId);
|
|
211
|
+
this.messages.delete(childId);
|
|
202
212
|
}
|
|
203
|
-
}
|
|
204
|
-
deleteDescendants(message);
|
|
213
|
+
}
|
|
205
214
|
message.children = [];
|
|
206
215
|
message.next = null;
|
|
207
216
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-repository.js","names":["ThreadMessage","RunConfig","generateId","ThreadMessageLike","getAutoStatus","fromThreadMessageLike","ExportedMessageRepositoryItem","message","parentId","runConfig","ExportedMessageRepository","headId","messages","Array","fromArray","conv","map","m","undefined","idx","id","fromBranchableArray","items","options","fallbackStatus","Error","RepositoryParent","children","next","RepositoryMessage","prev","current","level","findHead","CachedValue","_value","T","func","constructor","value","dirty","MessageRepository","Map","head","root","updateLevels","newLevel","childId","childMessage","get","performOp","newParent","child","operation","parentOrRoot","newParentOrRoot","filter","fallbackId","at","fallback","_messages","canonicalHeadId","metadata","isOptimistic","getMessages","headMessage","addOrUpdateMessage","existingItem","newItem","set","getMessage","messageId","index","deleteMessage","replacementId","replacement","delete","getBranches","evictOffBranchOptimisticMessages","previousHead","currentHead","onHeadBranch","Set","add","stale","has","push","switchToBranch","prevOrRoot","resetHead","clear","length","deleteDescendants","msg","export","exportItems","import"],"sources":["../../../src/runtime/utils/message-repository.ts"],"sourcesContent":["import type { ThreadMessage } from \"../../types/message\";\nimport type { RunConfig } from \"../../types/message\";\nimport { generateId } from \"../../utils/id\";\nimport type { ThreadMessageLike } from \"./thread-message-like\";\nimport { getAutoStatus } from \"./auto-status\";\nimport { fromThreadMessageLike } from \"./thread-message-like\";\n\nexport type ExportedMessageRepositoryItem = {\n message: ThreadMessage;\n parentId: string | null;\n runConfig?: RunConfig;\n};\n\nexport type ExportedMessageRepository = {\n headId?: string | null;\n messages: Array<{\n message: ThreadMessage;\n parentId: string | null;\n runConfig?: RunConfig;\n }>;\n};\n\nexport const ExportedMessageRepository = {\n fromArray: (\n messages: readonly ThreadMessageLike[],\n ): ExportedMessageRepository => {\n const conv = messages.map((m) =>\n fromThreadMessageLike(\n m,\n generateId(),\n getAutoStatus(false, false, false, false, undefined),\n ),\n );\n\n return {\n messages: conv.map((m, idx) => ({\n parentId: idx > 0 ? conv[idx - 1]!.id : null,\n message: m,\n })),\n };\n },\n\n fromBranchableArray: (\n items: readonly {\n message: ThreadMessageLike;\n parentId: string | null;\n }[],\n options?: { headId?: string | null },\n ): ExportedMessageRepository => {\n const fallbackStatus = getAutoStatus(false, false, false, false, undefined);\n return {\n ...(options?.headId !== undefined\n ? { headId: options.headId }\n : undefined),\n messages: items.map(({ message, parentId }) => {\n if (!message.id) {\n throw new Error(\n \"ExportedMessageRepository.fromBranchableArray: Each message must have an 'id' field set.\",\n );\n }\n return {\n parentId,\n message: fromThreadMessageLike(message, message.id, fallbackStatus),\n };\n }),\n };\n },\n};\n\ntype RepositoryParent = {\n children: string[];\n next: RepositoryMessage | null;\n};\n\ntype RepositoryMessage = RepositoryParent & {\n prev: RepositoryMessage | null;\n current: ThreadMessage;\n level: number;\n};\n\nconst findHead = (\n message: RepositoryMessage | RepositoryParent,\n): RepositoryMessage | null => {\n if (message.next) return findHead(message.next);\n if (\"current\" in message) return message;\n return null;\n};\n\nclass CachedValue<T> {\n private _value: T | null = null;\n\n private func: () => T;\n\n constructor(func: () => T) {\n this.func = func;\n }\n\n get value() {\n if (this._value === null) {\n this._value = this.func();\n }\n return this._value;\n }\n\n dirty() {\n this._value = null;\n }\n}\n\nexport class MessageRepository {\n private messages = new Map<string, RepositoryMessage>();\n private head: RepositoryMessage | null = null;\n private root: RepositoryParent = {\n children: [],\n next: null,\n };\n\n private updateLevels(message: RepositoryMessage, newLevel: number) {\n message.level = newLevel;\n for (const childId of message.children) {\n const childMessage = this.messages.get(childId);\n if (childMessage) {\n this.updateLevels(childMessage, newLevel + 1);\n }\n }\n }\n\n private performOp(\n newParent: RepositoryMessage | null,\n child: RepositoryMessage,\n operation: \"cut\" | \"link\" | \"relink\",\n ) {\n const parentOrRoot = child.prev ?? this.root;\n const newParentOrRoot = newParent ?? this.root;\n\n if (operation === \"relink\" && parentOrRoot === newParentOrRoot) return;\n\n if (operation !== \"cut\") {\n for (\n let current: RepositoryMessage | null = newParent;\n current;\n current = current.prev\n ) {\n if (current.current.id === child.current.id) {\n throw new Error(\n \"MessageRepository(performOp/link): A message with the same id already exists in the parent tree. This error occurs if the same message id is found multiple times. This is likely an internal bug in assistant-ui.\",\n );\n }\n }\n }\n\n if (operation !== \"link\") {\n parentOrRoot.children = parentOrRoot.children.filter(\n (m) => m !== child.current.id,\n );\n\n if (parentOrRoot.next === child) {\n const fallbackId = parentOrRoot.children.at(-1);\n const fallback = fallbackId ? this.messages.get(fallbackId) : null;\n if (fallback === undefined) {\n throw new Error(\n \"MessageRepository(performOp/cut): Fallback sibling message not found. This is likely an internal bug in assistant-ui.\",\n );\n }\n parentOrRoot.next = fallback;\n }\n }\n\n if (operation !== \"cut\") {\n newParentOrRoot.children = [\n ...newParentOrRoot.children,\n child.current.id,\n ];\n\n if (findHead(child) === this.head || newParentOrRoot.next === null) {\n newParentOrRoot.next = child;\n }\n\n child.prev = newParent;\n\n const newLevel = newParent ? newParent.level + 1 : 0;\n this.updateLevels(child, newLevel);\n }\n }\n\n private _messages = new CachedValue<readonly ThreadMessage[]>(() => {\n const messages = new Array<ThreadMessage>((this.head?.level ?? -1) + 1);\n for (let current = this.head; current; current = current.prev) {\n messages[current.level] = current.current;\n }\n return messages;\n });\n\n get headId() {\n return this.head?.current.id ?? null;\n }\n\n get canonicalHeadId() {\n // Optimistic messages are ephemeral, so persisted callers need the nearest\n // non-optimistic ancestor rather than the raw head.\n let head = this.head;\n while (head?.current.metadata?.isOptimistic) {\n head = head.prev;\n }\n return head?.current.id ?? null;\n }\n\n getMessages(headId?: string) {\n if (headId === undefined || headId === this.head?.current.id) {\n return this._messages.value;\n }\n\n const headMessage = this.messages.get(headId);\n if (!headMessage) {\n throw new Error(\n \"MessageRepository(getMessages): Head message not found. This is likely an internal bug in assistant-ui.\",\n );\n }\n\n const messages = new Array<ThreadMessage>(headMessage.level + 1);\n for (\n let current: RepositoryMessage | null = headMessage;\n current;\n current = current.prev\n ) {\n messages[current.level] = current.current;\n }\n return messages;\n }\n\n addOrUpdateMessage(parentId: string | null, message: ThreadMessage) {\n const existingItem = this.messages.get(message.id);\n const prev = parentId ? this.messages.get(parentId) : null;\n if (prev === undefined)\n throw new Error(\n \"MessageRepository(addOrUpdateMessage): Parent message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n if (existingItem) {\n existingItem.current = message;\n this.performOp(prev, existingItem, \"relink\");\n this._messages.dirty();\n return;\n }\n\n const newItem: RepositoryMessage = {\n prev,\n current: message,\n next: null,\n children: [],\n level: prev ? prev.level + 1 : 0,\n };\n\n this.messages.set(message.id, newItem);\n this.performOp(prev, newItem, \"link\");\n\n if (this.head === prev) {\n this.head = newItem;\n }\n\n this._messages.dirty();\n }\n\n getMessage(messageId: string) {\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(updateMessage): Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n return {\n parentId: message.prev?.current.id ?? null,\n message: message.current,\n index: message.level,\n };\n }\n\n deleteMessage(messageId: string, replacementId?: string | null | undefined) {\n const message = this.messages.get(messageId);\n\n if (!message)\n throw new Error(\n \"MessageRepository(deleteMessage): Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const replacement =\n replacementId === undefined\n ? message.prev\n : replacementId === null\n ? null\n : this.messages.get(replacementId);\n if (replacement === undefined)\n throw new Error(\n \"MessageRepository(deleteMessage): Replacement not found. This is likely an internal bug in assistant-ui.\",\n );\n\n for (const child of message.children) {\n const childMessage = this.messages.get(child);\n if (!childMessage)\n throw new Error(\n \"MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui.\",\n );\n this.performOp(replacement, childMessage, \"relink\");\n }\n\n this.performOp(null, message, \"cut\");\n this.messages.delete(messageId);\n\n if (this.head === message) {\n this.head = findHead(replacement ?? this.root);\n }\n\n this._messages.dirty();\n }\n\n getBranches(messageId: string) {\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(getBranches): Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const { children } = message.prev ?? this.root;\n return children;\n }\n\n /**\n * Evicts optimistic messages (`metadata.isOptimistic`) the head just moved\n * away from. Since eviction runs on every head move, the only optimistic\n * messages in the repository live on the branch the head previously pointed\n * at — so we walk just that branch rather than the whole repository. Keeps a\n * client→server id swap from leaving a phantom sibling, and drops off-branch\n * placeholders.\n */\n private evictOffBranchOptimisticMessages(\n previousHead: RepositoryMessage | null,\n currentHead: RepositoryMessage | null,\n ) {\n if (!previousHead) return;\n\n const onHeadBranch = new Set<string>();\n for (let current = currentHead; current; current = current.prev) {\n onHeadBranch.add(current.current.id);\n }\n\n const stale: string[] = [];\n for (\n let current: RepositoryMessage | null = previousHead;\n current;\n current = current.prev\n ) {\n // Stop at the first node shared with the current head branch: every\n // ancestor above it is shared too, so nothing further can be off-branch.\n if (onHeadBranch.has(current.current.id)) break;\n if (current.current.metadata?.isOptimistic) {\n stale.push(current.current.id);\n }\n }\n\n for (const id of stale) {\n // A prior deletion may have already removed this node.\n if (this.messages.has(id)) this.deleteMessage(id);\n }\n }\n\n switchToBranch(messageId: string) {\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(switchToBranch): Branch not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const previousHead = this.head;\n const prevOrRoot = message.prev ?? this.root;\n prevOrRoot.next = message;\n\n this.head = findHead(message);\n\n this.evictOffBranchOptimisticMessages(previousHead, this.head);\n\n this._messages.dirty();\n }\n\n resetHead(messageId: string | null) {\n if (messageId === null) {\n this.clear();\n return;\n }\n\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const previousHead = this.head;\n\n if (message.children.length > 0) {\n const deleteDescendants = (msg: RepositoryMessage) => {\n for (const childId of msg.children) {\n const childMessage = this.messages.get(childId);\n if (childMessage) {\n deleteDescendants(childMessage);\n this.messages.delete(childId);\n }\n }\n };\n deleteDescendants(message);\n\n message.children = [];\n message.next = null;\n }\n\n this.head = message;\n for (\n let current: RepositoryMessage | null = message;\n current;\n current = current.prev\n ) {\n if (current.prev) {\n current.prev.next = current;\n } else {\n this.root.next = current;\n }\n }\n\n this.evictOffBranchOptimisticMessages(previousHead, this.head);\n\n this._messages.dirty();\n }\n\n clear(): void {\n this.messages.clear();\n this.head = null;\n this.root = {\n children: [],\n next: null,\n };\n this._messages.dirty();\n }\n\n export(): ExportedMessageRepository {\n const exportItems: ExportedMessageRepository[\"messages\"] = [];\n\n // Optimistic messages are ephemeral and never persisted. A persisted child\n // of an optimistic node is re-parented onto its nearest persisted ancestor\n // so the exported tree never references a skipped id.\n for (const [, message] of this.messages) {\n if (message.current.metadata?.isOptimistic) continue;\n let prev = message.prev;\n while (prev && prev.current.metadata?.isOptimistic) {\n prev = prev.prev;\n }\n exportItems.push({\n message: message.current,\n parentId: prev?.current.id ?? null,\n });\n }\n\n return {\n headId: this.canonicalHeadId,\n messages: exportItems,\n };\n }\n\n import({ headId, messages }: ExportedMessageRepository) {\n for (const { message, parentId } of messages) {\n this.addOrUpdateMessage(parentId, message);\n }\n\n this.resetHead(headId ?? messages.at(-1)?.message.id ?? null);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"message-repository.js","names":["ThreadMessage","RunConfig","generateId","ThreadMessageLike","getAutoStatus","fromThreadMessageLike","ExportedMessageRepositoryItem","message","parentId","runConfig","ExportedMessageRepository","headId","messages","Array","fromArray","conv","map","m","undefined","idx","id","fromBranchableArray","items","options","fallbackStatus","Error","RepositoryParent","children","next","RepositoryMessage","prev","current","level","findHead","CachedValue","_value","T","func","constructor","value","dirty","MessageRepository","Map","head","root","updateLevels","newLevel","pending","length","pop","childId","childMessage","get","push","performOp","newParent","child","operation","parentOrRoot","newParentOrRoot","filter","fallbackId","at","fallback","_messages","canonicalHeadId","metadata","isOptimistic","getMessages","headMessage","addOrUpdateMessage","existingItem","newItem","set","getMessage","messageId","index","deleteMessage","replacementId","replacement","delete","getBranches","evictOffBranchOptimisticMessages","previousHead","currentHead","onHeadBranch","Set","add","stale","has","switchToBranch","prevOrRoot","resetHead","clear","descendantId","export","exportItems","import"],"sources":["../../../src/runtime/utils/message-repository.ts"],"sourcesContent":["import type { ThreadMessage } from \"../../types/message\";\nimport type { RunConfig } from \"../../types/message\";\nimport { generateId } from \"../../utils/id\";\nimport type { ThreadMessageLike } from \"./thread-message-like\";\nimport { getAutoStatus } from \"./auto-status\";\nimport { fromThreadMessageLike } from \"./thread-message-like\";\n\nexport type ExportedMessageRepositoryItem = {\n message: ThreadMessage;\n parentId: string | null;\n runConfig?: RunConfig;\n};\n\nexport type ExportedMessageRepository = {\n headId?: string | null;\n messages: Array<{\n message: ThreadMessage;\n parentId: string | null;\n runConfig?: RunConfig;\n }>;\n};\n\nexport const ExportedMessageRepository = {\n fromArray: (\n messages: readonly ThreadMessageLike[],\n ): ExportedMessageRepository => {\n const conv = messages.map((m) =>\n fromThreadMessageLike(\n m,\n generateId(),\n getAutoStatus(false, false, false, false, undefined),\n ),\n );\n\n return {\n messages: conv.map((m, idx) => ({\n parentId: idx > 0 ? conv[idx - 1]!.id : null,\n message: m,\n })),\n };\n },\n\n fromBranchableArray: (\n items: readonly {\n message: ThreadMessageLike;\n parentId: string | null;\n }[],\n options?: { headId?: string | null },\n ): ExportedMessageRepository => {\n const fallbackStatus = getAutoStatus(false, false, false, false, undefined);\n return {\n ...(options?.headId !== undefined\n ? { headId: options.headId }\n : undefined),\n messages: items.map(({ message, parentId }) => {\n if (!message.id) {\n throw new Error(\n \"ExportedMessageRepository.fromBranchableArray: Each message must have an 'id' field set.\",\n );\n }\n return {\n parentId,\n message: fromThreadMessageLike(message, message.id, fallbackStatus),\n };\n }),\n };\n },\n};\n\ntype RepositoryParent = {\n children: string[];\n next: RepositoryMessage | null;\n};\n\ntype RepositoryMessage = RepositoryParent & {\n prev: RepositoryMessage | null;\n current: ThreadMessage;\n level: number;\n};\n\nconst findHead = (\n message: RepositoryMessage | RepositoryParent,\n): RepositoryMessage | null => {\n let current = message;\n while (current.next) current = current.next;\n return \"current\" in current ? current : null;\n};\n\nclass CachedValue<T> {\n private _value: T | null = null;\n\n private func: () => T;\n\n constructor(func: () => T) {\n this.func = func;\n }\n\n get value() {\n if (this._value === null) {\n this._value = this.func();\n }\n return this._value;\n }\n\n dirty() {\n this._value = null;\n }\n}\n\nexport class MessageRepository {\n private messages = new Map<string, RepositoryMessage>();\n private head: RepositoryMessage | null = null;\n private root: RepositoryParent = {\n children: [],\n next: null,\n };\n\n private updateLevels(message: RepositoryMessage, newLevel: number) {\n const pending = [{ message, level: newLevel }];\n\n while (pending.length > 0) {\n const current = pending.pop()!;\n current.message.level = current.level;\n\n for (const childId of current.message.children) {\n const childMessage = this.messages.get(childId);\n if (childMessage) {\n pending.push({ message: childMessage, level: current.level + 1 });\n }\n }\n }\n }\n\n private performOp(\n newParent: RepositoryMessage | null,\n child: RepositoryMessage,\n operation: \"cut\" | \"link\" | \"relink\",\n ) {\n const parentOrRoot = child.prev ?? this.root;\n const newParentOrRoot = newParent ?? this.root;\n\n if (operation === \"relink\" && parentOrRoot === newParentOrRoot) return;\n\n // `link` receives a fresh ID from `addOrUpdateMessage`; only `relink` can introduce a cycle.\n if (operation === \"relink\") {\n for (\n let current: RepositoryMessage | null = newParent;\n current;\n current = current.prev\n ) {\n if (current.current.id === child.current.id) {\n throw new Error(\n \"MessageRepository(performOp/relink): A message with the same id already exists in the parent tree. This error occurs if the same message id is found multiple times. This is likely an internal bug in assistant-ui.\",\n );\n }\n }\n }\n\n if (operation !== \"link\") {\n parentOrRoot.children = parentOrRoot.children.filter(\n (m) => m !== child.current.id,\n );\n\n if (parentOrRoot.next === child) {\n const fallbackId = parentOrRoot.children.at(-1);\n const fallback = fallbackId ? this.messages.get(fallbackId) : null;\n if (fallback === undefined) {\n throw new Error(\n \"MessageRepository(performOp/cut): Fallback sibling message not found. This is likely an internal bug in assistant-ui.\",\n );\n }\n parentOrRoot.next = fallback;\n }\n }\n\n if (operation !== \"cut\") {\n newParentOrRoot.children = [\n ...newParentOrRoot.children,\n child.current.id,\n ];\n\n if (findHead(child) === this.head || newParentOrRoot.next === null) {\n newParentOrRoot.next = child;\n }\n\n child.prev = newParent;\n\n const newLevel = newParent ? newParent.level + 1 : 0;\n this.updateLevels(child, newLevel);\n }\n }\n\n private _messages = new CachedValue<readonly ThreadMessage[]>(() => {\n const messages = new Array<ThreadMessage>((this.head?.level ?? -1) + 1);\n for (let current = this.head; current; current = current.prev) {\n messages[current.level] = current.current;\n }\n return messages;\n });\n\n get headId() {\n return this.head?.current.id ?? null;\n }\n\n get canonicalHeadId() {\n // Optimistic messages are ephemeral, so persisted callers need the nearest\n // non-optimistic ancestor rather than the raw head.\n let head = this.head;\n while (head?.current.metadata?.isOptimistic) {\n head = head.prev;\n }\n return head?.current.id ?? null;\n }\n\n getMessages(headId?: string) {\n if (headId === undefined || headId === this.head?.current.id) {\n return this._messages.value;\n }\n\n const headMessage = this.messages.get(headId);\n if (!headMessage) {\n throw new Error(\n \"MessageRepository(getMessages): Head message not found. This is likely an internal bug in assistant-ui.\",\n );\n }\n\n const messages = new Array<ThreadMessage>(headMessage.level + 1);\n for (\n let current: RepositoryMessage | null = headMessage;\n current;\n current = current.prev\n ) {\n messages[current.level] = current.current;\n }\n return messages;\n }\n\n addOrUpdateMessage(parentId: string | null, message: ThreadMessage) {\n const existingItem = this.messages.get(message.id);\n const prev = parentId ? this.messages.get(parentId) : null;\n if (prev === undefined)\n throw new Error(\n \"MessageRepository(addOrUpdateMessage): Parent message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n if (existingItem) {\n existingItem.current = message;\n this.performOp(prev, existingItem, \"relink\");\n this._messages.dirty();\n return;\n }\n\n const newItem: RepositoryMessage = {\n prev,\n current: message,\n next: null,\n children: [],\n level: prev ? prev.level + 1 : 0,\n };\n\n this.messages.set(message.id, newItem);\n this.performOp(prev, newItem, \"link\");\n\n if (this.head === prev) {\n this.head = newItem;\n }\n\n this._messages.dirty();\n }\n\n getMessage(messageId: string) {\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(updateMessage): Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n return {\n parentId: message.prev?.current.id ?? null,\n message: message.current,\n index: message.level,\n };\n }\n\n deleteMessage(messageId: string, replacementId?: string | null | undefined) {\n const message = this.messages.get(messageId);\n\n if (!message)\n throw new Error(\n \"MessageRepository(deleteMessage): Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const replacement =\n replacementId === undefined\n ? message.prev\n : replacementId === null\n ? null\n : this.messages.get(replacementId);\n if (replacement === undefined)\n throw new Error(\n \"MessageRepository(deleteMessage): Replacement not found. This is likely an internal bug in assistant-ui.\",\n );\n\n for (const child of message.children) {\n const childMessage = this.messages.get(child);\n if (!childMessage)\n throw new Error(\n \"MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui.\",\n );\n this.performOp(replacement, childMessage, \"relink\");\n }\n\n this.performOp(null, message, \"cut\");\n this.messages.delete(messageId);\n\n if (this.head === message) {\n this.head = findHead(replacement ?? this.root);\n }\n\n this._messages.dirty();\n }\n\n getBranches(messageId: string) {\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(getBranches): Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const { children } = message.prev ?? this.root;\n return children;\n }\n\n /**\n * Evicts optimistic messages (`metadata.isOptimistic`) the head just moved\n * away from. Since eviction runs on every head move, the only optimistic\n * messages in the repository live on the branch the head previously pointed\n * at — so we walk just that branch rather than the whole repository. Keeps a\n * client→server id swap from leaving a phantom sibling, and drops off-branch\n * placeholders.\n */\n private evictOffBranchOptimisticMessages(\n previousHead: RepositoryMessage | null,\n currentHead: RepositoryMessage | null,\n ) {\n if (!previousHead) return;\n\n const onHeadBranch = new Set<string>();\n for (let current = currentHead; current; current = current.prev) {\n onHeadBranch.add(current.current.id);\n }\n\n const stale: string[] = [];\n for (\n let current: RepositoryMessage | null = previousHead;\n current;\n current = current.prev\n ) {\n // Stop at the first node shared with the current head branch: every\n // ancestor above it is shared too, so nothing further can be off-branch.\n if (onHeadBranch.has(current.current.id)) break;\n if (current.current.metadata?.isOptimistic) {\n stale.push(current.current.id);\n }\n }\n\n for (const id of stale) {\n // A prior deletion may have already removed this node.\n if (this.messages.has(id)) this.deleteMessage(id);\n }\n }\n\n switchToBranch(messageId: string) {\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(switchToBranch): Branch not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const previousHead = this.head;\n const prevOrRoot = message.prev ?? this.root;\n prevOrRoot.next = message;\n\n this.head = findHead(message);\n\n this.evictOffBranchOptimisticMessages(previousHead, this.head);\n\n this._messages.dirty();\n }\n\n resetHead(messageId: string | null) {\n if (messageId === null) {\n this.clear();\n return;\n }\n\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const previousHead = this.head;\n\n if (message.children.length > 0) {\n const pending = [...message.children];\n while (pending.length > 0) {\n const childId = pending.pop()!;\n const childMessage = this.messages.get(childId);\n if (childMessage) {\n for (const descendantId of childMessage.children) {\n pending.push(descendantId);\n }\n this.messages.delete(childId);\n }\n }\n\n message.children = [];\n message.next = null;\n }\n\n this.head = message;\n for (\n let current: RepositoryMessage | null = message;\n current;\n current = current.prev\n ) {\n if (current.prev) {\n current.prev.next = current;\n } else {\n this.root.next = current;\n }\n }\n\n this.evictOffBranchOptimisticMessages(previousHead, this.head);\n\n this._messages.dirty();\n }\n\n clear(): void {\n this.messages.clear();\n this.head = null;\n this.root = {\n children: [],\n next: null,\n };\n this._messages.dirty();\n }\n\n export(): ExportedMessageRepository {\n const exportItems: ExportedMessageRepository[\"messages\"] = [];\n\n // Optimistic messages are ephemeral and never persisted. A persisted child\n // of an optimistic node is re-parented onto its nearest persisted ancestor\n // so the exported tree never references a skipped id.\n for (const [, message] of this.messages) {\n if (message.current.metadata?.isOptimistic) continue;\n let prev = message.prev;\n while (prev && prev.current.metadata?.isOptimistic) {\n prev = prev.prev;\n }\n exportItems.push({\n message: message.current,\n parentId: prev?.current.id ?? null,\n });\n }\n\n return {\n headId: this.canonicalHeadId,\n messages: exportItems,\n };\n }\n\n import({ headId, messages }: ExportedMessageRepository) {\n for (const { message, parentId } of messages) {\n this.addOrUpdateMessage(parentId, message);\n }\n\n this.resetHead(headId ?? messages.at(-1)?.message.id ?? null);\n }\n}\n"],"mappings":";;;;AAsBA,MAAaU,4BAA4B;CACvCI,YACEF,aAC8B;EAC9B,MAAMG,OAAOH,SAASI,KAAKC,MACzBZ,sBACEY,GACAf,WAAW,GACXE,cAAc,OAAO,OAAO,OAAO,OAAOc,KAAAA,CAAS,CACrD,CACF;EAEA,OAAO,EACLN,UAAUG,KAAKC,KAAKC,GAAGE,SAAS;GAC9BX,UAAUW,MAAM,IAAIJ,KAAKI,MAAM,EAAE,CAAEC,KAAK;GACxCb,SAASU;EACX,EAAE,EACJ;CACF;CAEAI,sBACEC,OAIAC,YAC8B;EAC9B,MAAMC,iBAAiBpB,cAAc,OAAO,OAAO,OAAO,OAAOc,KAAAA,CAAS;EAC1E,OAAO;GACL,GAAIK,SAASZ,WAAWO,KAAAA,IACpB,EAAEP,QAAQY,QAAQZ,OAAO,IACzBO,KAAAA;GACJN,UAAUU,MAAMN,KAAK,EAAET,SAASC,eAAe;IAC7C,IAAI,CAACD,QAAQa,IACX,MAAM,IAAIK,MACR,0FACF;IAEF,OAAO;KACLjB;KACAD,SAASF,sBAAsBE,SAASA,QAAQa,IAAII,cAAc;IACpE;GACF,CAAC;EACH;CACF;AACF;AAaA,MAAMS,YACJ1B,YAC6B;CAC7B,IAAIwB,UAAUxB;CACd,OAAOwB,QAAQH,MAAMG,UAAUA,QAAQH;CACvC,OAAO,aAAaG,UAAUA,UAAU;AAC1C;AAEA,IAAMG,cAAN,MAAqB;CACnB,SAA2B;CAE3B;CAEAI,YAAYD,MAAe;EACzB,KAAKA,OAAOA;CACd;CAEA,IAAIE,QAAQ;EACV,IAAI,KAAKJ,WAAW,MAClB,KAAKA,SAAS,KAAKE,KAAK;EAE1B,OAAO,KAAKF;CACd;CAEAK,QAAQ;EACN,KAAKL,SAAS;CAChB;AACF;AAEA,IAAaM,oBAAb,MAA+B;CAC7B,2BAAmB,IAAIC,IAA+B;CACtD,OAAyC;CACzC,OAAiC;EAC/Bf,UAAU,CAAA;EACVC,MAAM;CACR;CAEA,aAAqBrB,SAA4BuC,UAAkB;EACjE,MAAMC,UAAU,CAAC;GAAExC;GAASyB,OAAOc;EAAS,CAAC;EAE7C,OAAOC,QAAQC,SAAS,GAAG;GACzB,MAAMjB,UAAUgB,QAAQE,IAAI;GAC5BlB,QAAQxB,QAAQyB,QAAQD,QAAQC;GAEhC,KAAK,MAAMkB,WAAWnB,QAAQxB,QAAQoB,UAAU;IAC9C,MAAMwB,eAAe,KAAKvC,SAASwC,IAAIF,OAAO;IAC9C,IAAIC,cACFJ,QAAQM,KAAK;KAAE9C,SAAS4C;KAAcnB,OAAOD,QAAQC,QAAQ;IAAE,CAAC;GAEpE;EACF;CACF;CAEA,UACEuB,WACAC,OACAC,WACA;EACA,MAAMC,eAAeF,MAAM1B,QAAQ,KAAKc;EACxC,MAAMe,kBAAkBJ,aAAa,KAAKX;EAE1C,IAAIa,cAAc,YAAYC,iBAAiBC,iBAAiB;EAGhE,IAAIF,cAAc,UAEd;QAAA,IAAI1B,UAAoCwB,WACxCxB,SACAA,UAAUA,QAAQD,MAElB,IAAIC,QAAQA,QAAQX,OAAOoC,MAAMzB,QAAQX,IACvC,MAAM,IAAIK,MACR,sNACF;EAAA;EAKN,IAAIgC,cAAc,QAAQ;GACxBC,aAAa/B,WAAW+B,aAAa/B,SAASiC,QAC3C3C,MAAMA,MAAMuC,MAAMzB,QAAQX,EAC7B;GAEA,IAAIsC,aAAa9B,SAAS4B,OAAO;IAC/B,MAAMK,aAAaH,aAAa/B,SAASmC,GAAG,EAAE;IAC9C,MAAMC,WAAWF,aAAa,KAAKjD,SAASwC,IAAIS,UAAU,IAAI;IAC9D,IAAIE,aAAa7C,KAAAA,GACf,MAAM,IAAIO,MACR,uHACF;IAEFiC,aAAa9B,OAAOmC;GACtB;EACF;EAEA,IAAIN,cAAc,OAAO;GACvBE,gBAAgBhC,WAAW,CACzB,GAAGgC,gBAAgBhC,UACnB6B,MAAMzB,QAAQX,EAAE;GAGlB,IAAIa,SAASuB,KAAK,MAAM,KAAKb,QAAQgB,gBAAgB/B,SAAS,MAC5D+B,gBAAgB/B,OAAO4B;GAGzBA,MAAM1B,OAAOyB;GAEb,MAAMT,WAAWS,YAAYA,UAAUvB,QAAQ,IAAI;GACnD,KAAKa,aAAaW,OAAOV,QAAQ;EACnC;CACF;CAEA,YAAoB,IAAIZ,kBAA4C;EAClE,MAAMtB,WAAW,IAAIC,OAAsB,KAAK8B,MAAMX,SAAS,MAAM,CAAC;EACtE,KAAK,IAAID,UAAU,KAAKY,MAAMZ,SAASA,UAAUA,QAAQD,MACvDlB,SAASmB,QAAQC,SAASD,QAAQA;EAEpC,OAAOnB;CACT,CAAC;CAED,IAAID,SAAS;EACX,OAAO,KAAKgC,MAAMZ,QAAQX,MAAM;CAClC;CAEA,IAAI6C,kBAAkB;EAGpB,IAAItB,OAAO,KAAKA;EAChB,OAAOA,MAAMZ,QAAQmC,UAAUC,cAC7BxB,OAAOA,KAAKb;EAEd,OAAOa,MAAMZ,QAAQX,MAAM;CAC7B;CAEAgD,YAAYzD,QAAiB;EAC3B,IAAIA,WAAWO,KAAAA,KAAaP,WAAW,KAAKgC,MAAMZ,QAAQX,IACxD,OAAO,KAAK4C,UAAUzB;EAGxB,MAAM8B,cAAc,KAAKzD,SAASwC,IAAIzC,MAAM;EAC5C,IAAI,CAAC0D,aACH,MAAM,IAAI5C,MACR,yGACF;EAGF,MAAMb,WAAW,IAAIC,MAAqBwD,YAAYrC,QAAQ,CAAC;EAC/D,KACE,IAAID,UAAoCsC,aACxCtC,SACAA,UAAUA,QAAQD,MAElBlB,SAASmB,QAAQC,SAASD,QAAQA;EAEpC,OAAOnB;CACT;CAEA0D,mBAAmB9D,UAAyBD,SAAwB;EAClE,MAAMgE,eAAe,KAAK3D,SAASwC,IAAI7C,QAAQa,EAAE;EACjD,MAAMU,OAAOtB,WAAW,KAAKI,SAASwC,IAAI5C,QAAQ,IAAI;EACtD,IAAIsB,SAASZ,KAAAA,GACX,MAAM,IAAIO,MACR,kHACF;EAEF,IAAI8C,cAAc;GAChBA,aAAaxC,UAAUxB;GACvB,KAAK+C,UAAUxB,MAAMyC,cAAc,QAAQ;GAC3C,KAAKP,UAAUxB,MAAM;GACrB;EACF;EAEA,MAAMgC,UAA6B;GACjC1C;GACAC,SAASxB;GACTqB,MAAM;GACND,UAAU,CAAA;GACVK,OAAOF,OAAOA,KAAKE,QAAQ,IAAI;EACjC;EAEA,KAAKpB,SAAS6D,IAAIlE,QAAQa,IAAIoD,OAAO;EACrC,KAAKlB,UAAUxB,MAAM0C,SAAS,MAAM;EAEpC,IAAI,KAAK7B,SAASb,MAChB,KAAKa,OAAO6B;EAGd,KAAKR,UAAUxB,MAAM;CACvB;CAEAkC,WAAWC,WAAmB;EAC5B,MAAMpE,UAAU,KAAKK,SAASwC,IAAIuB,SAAS;EAC3C,IAAI,CAACpE,SACH,MAAM,IAAIkB,MACR,sGACF;EAEF,OAAO;GACLjB,UAAUD,QAAQuB,MAAMC,QAAQX,MAAM;GACtCb,SAASA,QAAQwB;GACjB6C,OAAOrE,QAAQyB;EACjB;CACF;CAEA6C,cAAcF,WAAmBG,eAA2C;EAC1E,MAAMvE,UAAU,KAAKK,SAASwC,IAAIuB,SAAS;EAE3C,IAAI,CAACpE,SACH,MAAM,IAAIkB,MACR,sGACF;EAEF,MAAMsD,cACJD,kBAAkB5D,KAAAA,IACdX,QAAQuB,OACRgD,kBAAkB,OAChB,OACA,KAAKlE,SAASwC,IAAI0B,aAAa;EACvC,IAAIC,gBAAgB7D,KAAAA,GAClB,MAAM,IAAIO,MACR,0GACF;EAEF,KAAK,MAAM+B,SAASjD,QAAQoB,UAAU;GACpC,MAAMwB,eAAe,KAAKvC,SAASwC,IAAII,KAAK;GAC5C,IAAI,CAACL,cACH,MAAM,IAAI1B,MACR,4GACF;GACF,KAAK6B,UAAUyB,aAAa5B,cAAc,QAAQ;EACpD;EAEA,KAAKG,UAAU,MAAM/C,SAAS,KAAK;EACnC,KAAKK,SAASoE,OAAOL,SAAS;EAE9B,IAAI,KAAKhC,SAASpC,SAChB,KAAKoC,OAAOV,SAAS8C,eAAe,KAAKnC,IAAI;EAG/C,KAAKoB,UAAUxB,MAAM;CACvB;CAEAyC,YAAYN,WAAmB;EAC7B,MAAMpE,UAAU,KAAKK,SAASwC,IAAIuB,SAAS;EAC3C,IAAI,CAACpE,SACH,MAAM,IAAIkB,MACR,oGACF;EAEF,MAAM,EAAEE,aAAapB,QAAQuB,QAAQ,KAAKc;EAC1C,OAAOjB;CACT;;;;;;;;;CAUA,iCACEwD,cACAC,aACA;EACA,IAAI,CAACD,cAAc;EAEnB,MAAME,+BAAe,IAAIC,IAAY;EACrC,KAAK,IAAIvD,UAAUqD,aAAarD,SAASA,UAAUA,QAAQD,MACzDuD,aAAaE,IAAIxD,QAAQA,QAAQX,EAAE;EAGrC,MAAMoE,QAAkB,CAAA;EACxB,KACE,IAAIzD,UAAoCoD,cACxCpD,SACAA,UAAUA,QAAQD,MAClB;GAGA,IAAIuD,aAAaI,IAAI1D,QAAQA,QAAQX,EAAE,GAAG;GAC1C,IAAIW,QAAQA,QAAQmC,UAAUC,cAC5BqB,MAAMnC,KAAKtB,QAAQA,QAAQX,EAAE;EAEjC;EAEA,KAAK,MAAMA,MAAMoE,OAEf,IAAI,KAAK5E,SAAS6E,IAAIrE,EAAE,GAAG,KAAKyD,cAAczD,EAAE;CAEpD;CAEAsE,eAAef,WAAmB;EAChC,MAAMpE,UAAU,KAAKK,SAASwC,IAAIuB,SAAS;EAC3C,IAAI,CAACpE,SACH,MAAM,IAAIkB,MACR,sGACF;EAEF,MAAM0D,eAAe,KAAKxC;EAC1B,MAAMgD,aAAapF,QAAQuB,QAAQ,KAAKc;EACxC+C,WAAW/D,OAAOrB;EAElB,KAAKoC,OAAOV,SAAS1B,OAAO;EAE5B,KAAK2E,iCAAiCC,cAAc,KAAKxC,IAAI;EAE7D,KAAKqB,UAAUxB,MAAM;CACvB;CAEAoD,UAAUjB,WAA0B;EAClC,IAAIA,cAAc,MAAM;GACtB,KAAKkB,MAAM;GACX;EACF;EAEA,MAAMtF,UAAU,KAAKK,SAASwC,IAAIuB,SAAS;EAC3C,IAAI,CAACpE,SACH,MAAM,IAAIkB,MACR,iGACF;EAEF,MAAM0D,eAAe,KAAKxC;EAE1B,IAAIpC,QAAQoB,SAASqB,SAAS,GAAG;GAC/B,MAAMD,UAAU,CAAC,GAAGxC,QAAQoB,QAAQ;GACpC,OAAOoB,QAAQC,SAAS,GAAG;IACzB,MAAME,UAAUH,QAAQE,IAAI;IAC5B,MAAME,eAAe,KAAKvC,SAASwC,IAAIF,OAAO;IAC9C,IAAIC,cAAc;KAChB,KAAK,MAAM2C,gBAAgB3C,aAAaxB,UACtCoB,QAAQM,KAAKyC,YAAY;KAE3B,KAAKlF,SAASoE,OAAO9B,OAAO;IAC9B;GACF;GAEA3C,QAAQoB,WAAW,CAAA;GACnBpB,QAAQqB,OAAO;EACjB;EAEA,KAAKe,OAAOpC;EACZ,KACE,IAAIwB,UAAoCxB,SACxCwB,SACAA,UAAUA,QAAQD,MAElB,IAAIC,QAAQD,MACVC,QAAQD,KAAKF,OAAOG;OAEpB,KAAKa,KAAKhB,OAAOG;EAIrB,KAAKmD,iCAAiCC,cAAc,KAAKxC,IAAI;EAE7D,KAAKqB,UAAUxB,MAAM;CACvB;CAEAqD,QAAc;EACZ,KAAKjF,SAASiF,MAAM;EACpB,KAAKlD,OAAO;EACZ,KAAKC,OAAO;GACVjB,UAAU,CAAA;GACVC,MAAM;EACR;EACA,KAAKoC,UAAUxB,MAAM;CACvB;CAEAuD,SAAoC;EAClC,MAAMC,cAAqD,CAAA;EAK3D,KAAK,MAAM,GAAGzF,YAAY,KAAKK,UAAU;GACvC,IAAIL,QAAQwB,QAAQmC,UAAUC,cAAc;GAC5C,IAAIrC,OAAOvB,QAAQuB;GACnB,OAAOA,QAAQA,KAAKC,QAAQmC,UAAUC,cACpCrC,OAAOA,KAAKA;GAEdkE,YAAY3C,KAAK;IACf9C,SAASA,QAAQwB;IACjBvB,UAAUsB,MAAMC,QAAQX,MAAM;GAChC,CAAC;EACH;EAEA,OAAO;GACLT,QAAQ,KAAKsD;GACbrD,UAAUoF;EACZ;CACF;CAEAC,OAAO,EAAEtF,QAAQC,YAAuC;EACtD,KAAK,MAAM,EAAEL,SAASC,cAAcI,UAClC,KAAK0D,mBAAmB9D,UAAUD,OAAO;EAG3C,KAAKqF,UAAUjF,UAAUC,SAASkD,GAAG,EAAE,CAAC,EAAEvD,QAAQa,MAAM,IAAI;CAC9D;AACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ThreadRuntimeCore } from "../interfaces/thread-runtime-core.js";
|
|
2
|
+
//#region src/runtime/utils/thread-runtime-lifecycle.d.ts
|
|
3
|
+
declare const captureThreadRuntimeGeneration: (runtime: ThreadRuntimeCore) => number;
|
|
4
|
+
declare const isThreadRuntimeGenerationCurrent: (runtime: ThreadRuntimeCore, generation: number) => boolean;
|
|
5
|
+
declare const invalidateThreadRuntime: (runtime: ThreadRuntimeCore) => void;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { captureThreadRuntimeGeneration, invalidateThreadRuntime, isThreadRuntimeGenerationCurrent };
|
|
8
|
+
//# sourceMappingURL=thread-runtime-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-runtime-lifecycle.d.ts","names":[],"sources":["../../../src/runtime/utils/thread-runtime-lifecycle.ts"],"mappings":";;cAOa,iCAAkC,SAAS;cAG3C,mCACX,SAAS,mBACT;cAGW,0BAA2B,SAAS"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/runtime/utils/thread-runtime-lifecycle.ts
|
|
2
|
+
const generations = /* @__PURE__ */ new WeakMap();
|
|
3
|
+
const captureThreadRuntimeGeneration = (runtime) => generations.get(runtime) ?? 0;
|
|
4
|
+
const isThreadRuntimeGenerationCurrent = (runtime, generation) => captureThreadRuntimeGeneration(runtime) === generation;
|
|
5
|
+
const invalidateThreadRuntime = (runtime) => {
|
|
6
|
+
generations.set(runtime, captureThreadRuntimeGeneration(runtime) + 1);
|
|
7
|
+
};
|
|
8
|
+
//#endregion
|
|
9
|
+
export { captureThreadRuntimeGeneration, invalidateThreadRuntime, isThreadRuntimeGenerationCurrent };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=thread-runtime-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-runtime-lifecycle.js","names":["ThreadRuntimeCore","generations","WeakMap","captureThreadRuntimeGeneration","runtime","get","isThreadRuntimeGenerationCurrent","generation","invalidateThreadRuntime","set"],"sources":["../../../src/runtime/utils/thread-runtime-lifecycle.ts"],"sourcesContent":["import type { ThreadRuntimeCore } from \"../interfaces/thread-runtime-core\";\n\n// Invalidation must stay re-entrant: StrictMode's simulated unmount runs the\n// effect cleanup while the runtime object survives into the next mount, so a\n// permanent disposed mark would swallow every later append.\nconst generations = new WeakMap<ThreadRuntimeCore, number>();\n\nexport const captureThreadRuntimeGeneration = (runtime: ThreadRuntimeCore) =>\n generations.get(runtime) ?? 0;\n\nexport const isThreadRuntimeGenerationCurrent = (\n runtime: ThreadRuntimeCore,\n generation: number,\n) => captureThreadRuntimeGeneration(runtime) === generation;\n\nexport const invalidateThreadRuntime = (runtime: ThreadRuntimeCore) => {\n generations.set(runtime, captureThreadRuntimeGeneration(runtime) + 1);\n};\n"],"mappings":";AAKA,MAAMC,8BAAc,IAAIC,QAAmC;AAE3D,MAAaC,kCAAkCC,YAC7CH,YAAYI,IAAID,OAAO,KAAK;AAE9B,MAAaE,oCACXF,SACAG,eACGJ,+BAA+BC,OAAO,MAAMG;AAEjD,MAAaC,2BAA2BJ,YAA+B;CACrEH,YAAYQ,IAAIL,SAASD,+BAA+BC,OAAO,IAAI,CAAC;AACtE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-store-shared-options.js","names":["ExternalStoreAdapter","ExternalStoreSharedOptions","Pick","pickExternalStoreSharedOptions","options","isDisabled","isSendDisabled","unstable_capabilities","suggestions","Required","K"],"sources":["../../../src/runtimes/external-store/external-store-shared-options.ts"],"sourcesContent":["import type { ExternalStoreAdapter } from \"./external-store-adapter\";\n\nexport type ExternalStoreSharedOptions = Pick<\n ExternalStoreAdapter,\n \"isDisabled\" | \"isSendDisabled\" | \"unstable_capabilities\" | \"suggestions\"\n>;\n\nexport const pickExternalStoreSharedOptions = (\n options: ExternalStoreSharedOptions,\n): ExternalStoreSharedOptions =>\n ({\n isDisabled: options.isDisabled,\n isSendDisabled: options.isSendDisabled,\n unstable_capabilities: options.unstable_capabilities,\n suggestions: options.suggestions,\n }) satisfies {\n [K in keyof Required<ExternalStoreSharedOptions
|
|
1
|
+
{"version":3,"file":"external-store-shared-options.js","names":["ExternalStoreAdapter","ExternalStoreSharedOptions","Pick","pickExternalStoreSharedOptions","options","isDisabled","isSendDisabled","unstable_capabilities","suggestions","Required","K"],"sources":["../../../src/runtimes/external-store/external-store-shared-options.ts"],"sourcesContent":["import type { ExternalStoreAdapter } from \"./external-store-adapter\";\n\nexport type ExternalStoreSharedOptions = Pick<\n ExternalStoreAdapter,\n \"isDisabled\" | \"isSendDisabled\" | \"unstable_capabilities\" | \"suggestions\"\n>;\n\nexport const pickExternalStoreSharedOptions = (\n options: ExternalStoreSharedOptions,\n): ExternalStoreSharedOptions =>\n ({\n isDisabled: options.isDisabled,\n isSendDisabled: options.isSendDisabled,\n unstable_capabilities: options.unstable_capabilities,\n suggestions: options.suggestions,\n }) satisfies {\n [\n K in keyof Required<ExternalStoreSharedOptions>\n ]: ExternalStoreSharedOptions[K];\n };\n"],"mappings":";AAOA,MAAaG,kCACXC,aAEC;CACCC,YAAYD,QAAQC;CACpBC,gBAAgBF,QAAQE;CACxBC,uBAAuBH,QAAQG;CAC/BC,aAAaJ,QAAQI;AACvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-store-thread-list-runtime-core.d.ts","names":[],"sources":["../../../src/runtimes/external-store/external-store-thread-list-runtime-core.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"external-store-thread-list-runtime-core.d.ts","names":[],"sources":["../../../src/runtimes/external-store/external-store-thread-list-runtime-core.ts"],"mappings":";;;;;KAUY,mCAAmC;cAgBlC,8CAA8C;UACjD;UACA;UACA;UACA;UAEA;MAEG;MAIA;MAIA;MAIA;MAIA,eAAW,SAAA,eAAA;EAIf,yBAAqB;UAIpB;MAEG;UAIH;EAGN,YAAA,SAAS,4CACT,eAAe;EAMV,4BAAwB;EAIxB;EAIA,YAAY,mBAAgB;EAI5B,sBACL,SAAS,gCACT;EAsFW,oBAAoB;EASpB,eACX,kBACA;IAAa;MACZ;EAUU,qBAAqB;EAUrB,OAAO,kBAAkB,mBAAmB;EAQ5C,aACX,kBACA,QAAQ,sCACP;EAUU,UAAU;EAIV,QAAQ,mBAAmB;EAQ3B,UAAU,mBAAmB;EAQ7B,OAAO,mBAAmB;EAQhC,WACL,mBACC;IAAU;IAAkB;;EAIxB;UAIC;EAED,UAAU,uBAAuB;UAKhC"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { notifySubscribers } from "../../subscribable/subscribable.js";
|
|
2
|
+
import { invalidateThreadRuntime } from "../../runtime/utils/thread-runtime-lifecycle.js";
|
|
1
3
|
//#region src/runtimes/external-store/external-store-thread-list-runtime-core.ts
|
|
2
4
|
const EMPTY_ARRAY = Object.freeze([]);
|
|
3
5
|
const DEFAULT_THREAD_ID = "DEFAULT_THREAD_ID";
|
|
@@ -78,6 +80,7 @@ var ExternalStoreThreadListRuntimeCore = class {
|
|
|
78
80
|
if (previousThreads !== newThreads) this._threads = this.adapter.threads?.map((t) => t.id) ?? EMPTY_ARRAY;
|
|
79
81
|
if (previousArchivedThreads !== newArchivedThreads) this._archivedThreads = this.adapter.archivedThreads?.map((t) => t.id) ?? EMPTY_ARRAY;
|
|
80
82
|
if (initialLoad || previousThreadId !== newThreadId) {
|
|
83
|
+
if (!initialLoad) invalidateThreadRuntime(this._mainThread);
|
|
81
84
|
this._mainThreadId = newThreadId;
|
|
82
85
|
this._mainThread = this.threadFactory();
|
|
83
86
|
}
|
|
@@ -148,7 +151,7 @@ var ExternalStoreThreadListRuntimeCore = class {
|
|
|
148
151
|
return () => this._subscriptions.delete(callback);
|
|
149
152
|
}
|
|
150
153
|
_notifySubscribers() {
|
|
151
|
-
|
|
154
|
+
notifySubscribers(this._subscriptions);
|
|
152
155
|
}
|
|
153
156
|
};
|
|
154
157
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-store-thread-list-runtime-core.js","names":["Unsubscribe","ExternalStoreThreadRuntimeCore","ThreadListItemCoreState","ThreadListRuntimeCore","ExternalStoreThreadListAdapter","ExternalStoreThreadFactory","EMPTY_ARRAY","Object","freeze","DEFAULT_THREAD_ID","DEFAULT_THREADS","DEFAULT_THREAD","id","remoteId","undefined","externalId","status","RESOLVED_PROMISE","Promise","resolve","DEFAULT_THREAD_DATA","ExternalStoreThreadListRuntimeCore","_mainThreadId","_threads","_archivedThreads","_threadData","Readonly","Record","adapter","isLoading","newThreadId","threadIds","archivedThreadIds","threadItems","getLoadThreadsPromise","_mainThread","mainThreadId","threadFactory","constructor","__internal_setAdapter","getMainThreadRuntimeCore","getThreadRuntimeCore","Error","getItemById","threadId","initialLoad","previousAdapter","newThreads","threads","newArchivedThreads","archivedThreads","previousThreadId","previousThreads","previousArchivedThreads","fromEntries","map","t","_notifySubscribers","reloadMainThread","unstable_refetchThread","switchToThread","_options","unarchive","onSwitchToThread","switchToNewThread","onSwitchToNewThread","rename","newTitle","onRename","updateCustom","custom","onUpdateCustom","detach","archive","onArchive","onUnarchive","delete","onDelete","initialize","generateTitle","_subscriptions","Set","subscribe","callback","add"],"sources":["../../../src/runtimes/external-store/external-store-thread-list-runtime-core.ts"],"sourcesContent":["import type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { ExternalStoreThreadRuntimeCore } from \"./external-store-thread-runtime-core\";\nimport type {\n ThreadListItemCoreState,\n ThreadListRuntimeCore,\n} from \"../../runtime/interfaces/thread-list-runtime-core\";\nimport type { ExternalStoreThreadListAdapter } from \"./external-store-adapter\";\n\nexport type ExternalStoreThreadFactory = () => ExternalStoreThreadRuntimeCore;\n\nconst EMPTY_ARRAY = Object.freeze([]);\nconst DEFAULT_THREAD_ID = \"DEFAULT_THREAD_ID\";\nconst DEFAULT_THREADS = Object.freeze([DEFAULT_THREAD_ID]);\nconst DEFAULT_THREAD = Object.freeze({\n id: DEFAULT_THREAD_ID,\n remoteId: undefined,\n externalId: undefined,\n status: \"regular\",\n});\nconst RESOLVED_PROMISE = Promise.resolve();\nconst DEFAULT_THREAD_DATA = Object.freeze({\n [DEFAULT_THREAD_ID]: DEFAULT_THREAD,\n});\n\nexport class ExternalStoreThreadListRuntimeCore implements ThreadListRuntimeCore {\n private _mainThreadId: string = DEFAULT_THREAD_ID;\n private _threads: readonly string[] = DEFAULT_THREADS;\n private _archivedThreads: readonly string[] = EMPTY_ARRAY;\n private _threadData: Readonly<Record<string, ThreadListItemCoreState>> =\n DEFAULT_THREAD_DATA;\n private adapter: ExternalStoreThreadListAdapter = {};\n\n public get isLoading() {\n return this.adapter.isLoading ?? false;\n }\n\n public get newThreadId() {\n return undefined;\n }\n\n public get threadIds() {\n return this._threads;\n }\n\n public get archivedThreadIds() {\n return this._archivedThreads;\n }\n\n public get threadItems() {\n return this._threadData;\n }\n\n public getLoadThreadsPromise() {\n return RESOLVED_PROMISE;\n }\n\n private _mainThread!: ExternalStoreThreadRuntimeCore;\n\n public get mainThreadId() {\n return this._mainThreadId;\n }\n\n private threadFactory: ExternalStoreThreadFactory;\n\n constructor(\n adapter: ExternalStoreThreadListAdapter = {},\n threadFactory: ExternalStoreThreadFactory,\n ) {\n this.threadFactory = threadFactory;\n this.__internal_setAdapter(adapter, true);\n }\n\n public getMainThreadRuntimeCore() {\n return this._mainThread;\n }\n\n public getThreadRuntimeCore(): never {\n throw new Error(\"Method not implemented.\");\n }\n\n public getItemById(threadId: string) {\n return this._threadData[threadId];\n }\n\n public __internal_setAdapter(\n adapter: ExternalStoreThreadListAdapter,\n initialLoad = false,\n ) {\n const previousAdapter = this.adapter;\n this.adapter = adapter;\n\n const newThreadId = adapter.threadId ?? DEFAULT_THREAD_ID;\n const newThreads = adapter.threads ?? EMPTY_ARRAY;\n const newArchivedThreads = adapter.archivedThreads ?? EMPTY_ARRAY;\n\n const previousThreadId = previousAdapter.threadId ?? DEFAULT_THREAD_ID;\n const previousThreads = previousAdapter.threads ?? EMPTY_ARRAY;\n const previousArchivedThreads =\n previousAdapter.archivedThreads ?? EMPTY_ARRAY;\n\n if (\n !initialLoad &&\n previousThreadId === newThreadId &&\n previousThreads === newThreads &&\n previousArchivedThreads === newArchivedThreads\n ) {\n return;\n }\n\n if (\n previousThreads !== newThreads ||\n previousArchivedThreads !== newArchivedThreads ||\n previousThreadId !== newThreadId\n ) {\n this._threadData = {\n ...DEFAULT_THREAD_DATA,\n ...Object.fromEntries(\n adapter.threads?.map((t) => [\n t.id,\n {\n ...t,\n remoteId: t.remoteId,\n externalId: t.externalId,\n status: \"regular\",\n },\n ]) ?? [],\n ),\n ...Object.fromEntries(\n adapter.archivedThreads?.map((t) => [\n t.id,\n {\n ...t,\n remoteId: t.remoteId,\n externalId: t.externalId,\n status: \"archived\",\n },\n ]) ?? [],\n ),\n };\n }\n\n if (previousThreads !== newThreads) {\n this._threads = this.adapter.threads?.map((t) => t.id) ?? EMPTY_ARRAY;\n }\n\n if (previousArchivedThreads !== newArchivedThreads) {\n this._archivedThreads =\n this.adapter.archivedThreads?.map((t) => t.id) ?? EMPTY_ARRAY;\n }\n\n // `initialLoad ||`: `_mainThread!` must be assigned on construction.\n if (initialLoad || previousThreadId !== newThreadId) {\n this._mainThreadId = newThreadId;\n this._mainThread = this.threadFactory();\n }\n\n if (!this._threadData[this._mainThreadId]) {\n this._threadData = {\n ...this._threadData,\n [this._mainThreadId]: {\n id: this._mainThreadId,\n remoteId: undefined,\n externalId: undefined,\n status: \"regular\",\n },\n };\n }\n\n this._notifySubscribers();\n }\n\n public async reloadMainThread(): Promise<void> {\n // There is no runtime hook to remount here, so the capability is the only\n // path and an adapter without it has nothing to refetch with.\n if (!this._mainThread.unstable_refetchThread) return;\n // No unsent-thread guard: every entry here is regular or archived, so the\n // \"new\" status the remote thread list has to exclude cannot occur.\n await this._mainThread.unstable_refetchThread();\n }\n\n public async switchToThread(\n threadId: string,\n _options?: { unarchive?: boolean },\n ): Promise<void> {\n if (this._mainThreadId === threadId) return;\n const onSwitchToThread = this.adapter.onSwitchToThread;\n if (!onSwitchToThread)\n throw new Error(\n \"External store adapter does not support switching to thread\",\n );\n await onSwitchToThread(threadId);\n }\n\n public async switchToNewThread(): Promise<void> {\n const onSwitchToNewThread = this.adapter.onSwitchToNewThread;\n if (!onSwitchToNewThread)\n throw new Error(\n \"External store adapter does not support switching to new thread\",\n );\n\n await onSwitchToNewThread();\n }\n\n public async rename(threadId: string, newTitle: string): Promise<void> {\n const onRename = this.adapter.onRename;\n if (!onRename)\n throw new Error(\"External store adapter does not support renaming\");\n\n await onRename(threadId, newTitle);\n }\n\n public async updateCustom(\n threadId: string,\n custom: Record<string, unknown> | undefined,\n ): Promise<void> {\n const onUpdateCustom = this.adapter.onUpdateCustom;\n if (!onUpdateCustom)\n throw new Error(\n \"External store adapter does not support updating custom metadata\",\n );\n\n await onUpdateCustom(threadId, custom);\n }\n\n public async detach(): Promise<void> {\n // no-op\n }\n\n public async archive(threadId: string): Promise<void> {\n const onArchive = this.adapter.onArchive;\n if (!onArchive)\n throw new Error(\"External store adapter does not support archiving\");\n\n await onArchive(threadId);\n }\n\n public async unarchive(threadId: string): Promise<void> {\n const onUnarchive = this.adapter.onUnarchive;\n if (!onUnarchive)\n throw new Error(\"External store adapter does not support unarchiving\");\n\n await onUnarchive(threadId);\n }\n\n public async delete(threadId: string): Promise<void> {\n const onDelete = this.adapter.onDelete;\n if (!onDelete)\n throw new Error(\"External store adapter does not support deleting\");\n\n await onDelete(threadId);\n }\n\n public initialize(\n threadId: string,\n ): Promise<{ remoteId: string; externalId: string | undefined }> {\n return Promise.resolve({ remoteId: threadId, externalId: undefined });\n }\n\n public generateTitle(): never {\n throw new Error(\"Method not implemented.\");\n }\n\n private _subscriptions = new Set<() => void>();\n\n public subscribe(callback: () => void): Unsubscribe {\n this._subscriptions.add(callback);\n return () => this._subscriptions.delete(callback);\n }\n\n private _notifySubscribers() {\n for (const callback of this._subscriptions) callback();\n }\n}\n"],"mappings":";AAUA,MAAMM,cAAcC,OAAOC,OAAO,CAAA,CAAE;AACpC,MAAMC,oBAAoB;AAC1B,MAAMC,kBAAkBH,OAAOC,OAAO,CAACC,iBAAiB,CAAC;AACzD,MAAME,iBAAiBJ,OAAOC,OAAO;CACnCI,IAAIH;CACJI,UAAUC,KAAAA;CACVC,YAAYD,KAAAA;CACZE,QAAQ;AACV,CAAC;AACD,MAAMC,mBAAmBC,QAAQC,QAAQ;AACzC,MAAMC,sBAAsBb,OAAOC,OAAO,GACvCC,oBAAoBE,eACvB,CAAC;AAED,IAAaU,qCAAb,MAAiF;CAC/E,gBAAgCZ;CAChC,WAAsCC;CACtC,mBAA8CJ;CAC9C,cACEc;CACF,UAAkD,CAAC;CAEnD,IAAWS,YAAY;EACrB,OAAO,KAAKD,QAAQC,aAAa;CACnC;CAEA,IAAWC,cAAc,CAEzB;CAEA,IAAWC,YAAY;EACrB,OAAO,KAAKR;CACd;CAEA,IAAWS,oBAAoB;EAC7B,OAAO,KAAKR;CACd;CAEA,IAAWS,cAAc;EACvB,OAAO,KAAKR;CACd;CAEA,wBAA+B;EAC7B,OAAOR;CACT;CAEA;CAEA,IAAWmB,eAAe;EACxB,OAAO,KAAKd;CACd;CAEA;CAEAgB,YACEV,UAA0C,CAAC,GAC3CS,eACA;EACA,KAAKA,gBAAgBA;EACrB,KAAKE,sBAAsBX,SAAS,IAAI;CAC1C;CAEA,2BAAkC;EAChC,OAAO,KAAKO;CACd;CAEA,uBAAqC;EACnC,MAAM,IAAIO,MAAM,yBAAyB;CAC3C;CAEA,YAAmBE,UAAkB;EACnC,OAAO,KAAKnB,YAAYmB;CAC1B;CAEA,sBACEhB,SACAiB,cAAc,OACd;EACA,MAAMC,kBAAkB,KAAKlB;EAC7B,KAAKA,UAAUA;EAEf,MAAME,cAAcF,QAAQgB,YAAYnC;EACxC,MAAMsC,aAAanB,QAAQoB,WAAW1C;EACtC,MAAM2C,qBAAqBrB,QAAQsB,mBAAmB5C;EAEtD,MAAM6C,mBAAmBL,gBAAgBF,YAAYnC;EACrD,MAAM2C,kBAAkBN,gBAAgBE,WAAW1C;EACnD,MAAM+C,0BACJP,gBAAgBI,mBAAmB5C;EAErC,IACE,CAACuC,eACDM,qBAAqBrB,eACrBsB,oBAAoBL,cACpBM,4BAA4BJ,oBAE5B;EAGF,IACEG,oBAAoBL,cACpBM,4BAA4BJ,sBAC5BE,qBAAqBrB,aAErB,KAAKL,cAAc;GACjB,GAAGL;GACH,GAAGb,OAAO+C,YACR1B,QAAQoB,SAASO,KAAKC,MAAM,CAC1BA,EAAE5C,IACF;IACE,GAAG4C;IACH3C,UAAU2C,EAAE3C;IACZE,YAAYyC,EAAEzC;IACdC,QAAQ;GACV,CAAC,CACF,KAAK,CAAA,CACR;GACA,GAAGT,OAAO+C,YACR1B,QAAQsB,iBAAiBK,KAAKC,MAAM,CAClCA,EAAE5C,IACF;IACE,GAAG4C;IACH3C,UAAU2C,EAAE3C;IACZE,YAAYyC,EAAEzC;IACdC,QAAQ;GACV,CAAC,CACF,KAAK,CAAA,CACR;EACF;EAGF,IAAIoC,oBAAoBL,YACtB,KAAKxB,WAAW,KAAKK,QAAQoB,SAASO,KAAKC,MAAMA,EAAE5C,EAAE,KAAKN;EAG5D,IAAI+C,4BAA4BJ,oBAC9B,KAAKzB,mBACH,KAAKI,QAAQsB,iBAAiBK,KAAKC,MAAMA,EAAE5C,EAAE,KAAKN;EAItD,IAAIuC,eAAeM,qBAAqBrB,aAAa;GACnD,KAAKR,gBAAgBQ;GACrB,KAAKK,cAAc,KAAKE,cAAc;EACxC;EAEA,IAAI,CAAC,KAAKZ,YAAY,KAAKH,gBACzB,KAAKG,cAAc;GACjB,GAAG,KAAKA;IACP,KAAKH,gBAAgB;IACpBV,IAAI,KAAKU;IACTT,UAAUC,KAAAA;IACVC,YAAYD,KAAAA;IACZE,QAAQ;GACV;EACF;EAGF,KAAKyC,mBAAmB;CAC1B;CAEA,MAAaC,mBAAkC;EAG7C,IAAI,CAAC,KAAKvB,YAAYwB,wBAAwB;EAG9C,MAAM,KAAKxB,YAAYwB,uBAAuB;CAChD;CAEA,MAAaC,eACXhB,UACAiB,UACe;EACf,IAAI,KAAKvC,kBAAkBsB,UAAU;EACrC,MAAMmB,mBAAmB,KAAKnC,QAAQmC;EACtC,IAAI,CAACA,kBACH,MAAM,IAAIrB,MACR,6DACF;EACF,MAAMqB,iBAAiBnB,QAAQ;CACjC;CAEA,MAAaoB,oBAAmC;EAC9C,MAAMC,sBAAsB,KAAKrC,QAAQqC;EACzC,IAAI,CAACA,qBACH,MAAM,IAAIvB,MACR,iEACF;EAEF,MAAMuB,oBAAoB;CAC5B;CAEA,MAAaC,OAAOtB,UAAkBuB,UAAiC;EACrE,MAAMC,WAAW,KAAKxC,QAAQwC;EAC9B,IAAI,CAACA,UACH,MAAM,IAAI1B,MAAM,kDAAkD;EAEpE,MAAM0B,SAASxB,UAAUuB,QAAQ;CACnC;CAEA,MAAaE,aACXzB,UACA0B,QACe;EACf,MAAMC,iBAAiB,KAAK3C,QAAQ2C;EACpC,IAAI,CAACA,gBACH,MAAM,IAAI7B,MACR,kEACF;EAEF,MAAM6B,eAAe3B,UAAU0B,MAAM;CACvC;CAEA,MAAaE,SAAwB,CACnC;CAGF,MAAaC,QAAQ7B,UAAiC;EACpD,MAAM8B,YAAY,KAAK9C,QAAQ8C;EAC/B,IAAI,CAACA,WACH,MAAM,IAAIhC,MAAM,mDAAmD;EAErE,MAAMgC,UAAU9B,QAAQ;CAC1B;CAEA,MAAakB,UAAUlB,UAAiC;EACtD,MAAM+B,cAAc,KAAK/C,QAAQ+C;EACjC,IAAI,CAACA,aACH,MAAM,IAAIjC,MAAM,qDAAqD;EAEvE,MAAMiC,YAAY/B,QAAQ;CAC5B;CAEA,MAAagC,OAAOhC,UAAiC;EACnD,MAAMiC,WAAW,KAAKjD,QAAQiD;EAC9B,IAAI,CAACA,UACH,MAAM,IAAInC,MAAM,kDAAkD;EAEpE,MAAMmC,SAASjC,QAAQ;CACzB;CAEA,WACEA,UAC+D;EAC/D,OAAO1B,QAAQC,QAAQ;GAAEN,UAAU+B;GAAU7B,YAAYD,KAAAA;EAAU,CAAC;CACtE;CAEA,gBAA8B;EAC5B,MAAM,IAAI4B,MAAM,yBAAyB;CAC3C;CAEA,iCAAyB,IAAIuC,IAAgB;CAE7C,UAAiBE,UAAmC;EAClD,KAAKH,eAAeI,IAAID,QAAQ;EAChC,aAAa,KAAKH,eAAeJ,OAAOO,QAAQ;CAClD;CAEA,qBAA6B;EAC3B,KAAK,MAAMA,YAAY,KAAKH,gBAAgBG,SAAS;CACvD;AACF"}
|
|
1
|
+
{"version":3,"file":"external-store-thread-list-runtime-core.js","names":["Unsubscribe","ExternalStoreThreadRuntimeCore","ThreadListItemCoreState","ThreadListRuntimeCore","ExternalStoreThreadListAdapter","invalidateThreadRuntime","notifySubscribers","ExternalStoreThreadFactory","EMPTY_ARRAY","Object","freeze","DEFAULT_THREAD_ID","DEFAULT_THREADS","DEFAULT_THREAD","id","remoteId","undefined","externalId","status","RESOLVED_PROMISE","Promise","resolve","DEFAULT_THREAD_DATA","ExternalStoreThreadListRuntimeCore","_mainThreadId","_threads","_archivedThreads","_threadData","Readonly","Record","adapter","isLoading","newThreadId","threadIds","archivedThreadIds","threadItems","getLoadThreadsPromise","_mainThread","mainThreadId","threadFactory","constructor","__internal_setAdapter","getMainThreadRuntimeCore","getThreadRuntimeCore","Error","getItemById","threadId","initialLoad","previousAdapter","newThreads","threads","newArchivedThreads","archivedThreads","previousThreadId","previousThreads","previousArchivedThreads","fromEntries","map","t","_notifySubscribers","reloadMainThread","unstable_refetchThread","switchToThread","_options","unarchive","onSwitchToThread","switchToNewThread","onSwitchToNewThread","rename","newTitle","onRename","updateCustom","custom","onUpdateCustom","detach","archive","onArchive","onUnarchive","delete","onDelete","initialize","generateTitle","_subscriptions","Set","subscribe","callback","add"],"sources":["../../../src/runtimes/external-store/external-store-thread-list-runtime-core.ts"],"sourcesContent":["import type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { ExternalStoreThreadRuntimeCore } from \"./external-store-thread-runtime-core\";\nimport type {\n ThreadListItemCoreState,\n ThreadListRuntimeCore,\n} from \"../../runtime/interfaces/thread-list-runtime-core\";\nimport type { ExternalStoreThreadListAdapter } from \"./external-store-adapter\";\nimport { invalidateThreadRuntime } from \"../../runtime/utils/thread-runtime-lifecycle\";\nimport { notifySubscribers } from \"../../subscribable/subscribable\";\n\nexport type ExternalStoreThreadFactory = () => ExternalStoreThreadRuntimeCore;\n\nconst EMPTY_ARRAY = Object.freeze([]);\nconst DEFAULT_THREAD_ID = \"DEFAULT_THREAD_ID\";\nconst DEFAULT_THREADS = Object.freeze([DEFAULT_THREAD_ID]);\nconst DEFAULT_THREAD = Object.freeze({\n id: DEFAULT_THREAD_ID,\n remoteId: undefined,\n externalId: undefined,\n status: \"regular\",\n});\nconst RESOLVED_PROMISE = Promise.resolve();\nconst DEFAULT_THREAD_DATA = Object.freeze({\n [DEFAULT_THREAD_ID]: DEFAULT_THREAD,\n});\n\nexport class ExternalStoreThreadListRuntimeCore implements ThreadListRuntimeCore {\n private _mainThreadId: string = DEFAULT_THREAD_ID;\n private _threads: readonly string[] = DEFAULT_THREADS;\n private _archivedThreads: readonly string[] = EMPTY_ARRAY;\n private _threadData: Readonly<Record<string, ThreadListItemCoreState>> =\n DEFAULT_THREAD_DATA;\n private adapter: ExternalStoreThreadListAdapter = {};\n\n public get isLoading() {\n return this.adapter.isLoading ?? false;\n }\n\n public get newThreadId() {\n return undefined;\n }\n\n public get threadIds() {\n return this._threads;\n }\n\n public get archivedThreadIds() {\n return this._archivedThreads;\n }\n\n public get threadItems() {\n return this._threadData;\n }\n\n public getLoadThreadsPromise() {\n return RESOLVED_PROMISE;\n }\n\n private _mainThread!: ExternalStoreThreadRuntimeCore;\n\n public get mainThreadId() {\n return this._mainThreadId;\n }\n\n private threadFactory: ExternalStoreThreadFactory;\n\n constructor(\n adapter: ExternalStoreThreadListAdapter = {},\n threadFactory: ExternalStoreThreadFactory,\n ) {\n this.threadFactory = threadFactory;\n this.__internal_setAdapter(adapter, true);\n }\n\n public getMainThreadRuntimeCore() {\n return this._mainThread;\n }\n\n public getThreadRuntimeCore(): never {\n throw new Error(\"Method not implemented.\");\n }\n\n public getItemById(threadId: string) {\n return this._threadData[threadId];\n }\n\n public __internal_setAdapter(\n adapter: ExternalStoreThreadListAdapter,\n initialLoad = false,\n ) {\n const previousAdapter = this.adapter;\n this.adapter = adapter;\n\n const newThreadId = adapter.threadId ?? DEFAULT_THREAD_ID;\n const newThreads = adapter.threads ?? EMPTY_ARRAY;\n const newArchivedThreads = adapter.archivedThreads ?? EMPTY_ARRAY;\n\n const previousThreadId = previousAdapter.threadId ?? DEFAULT_THREAD_ID;\n const previousThreads = previousAdapter.threads ?? EMPTY_ARRAY;\n const previousArchivedThreads =\n previousAdapter.archivedThreads ?? EMPTY_ARRAY;\n\n if (\n !initialLoad &&\n previousThreadId === newThreadId &&\n previousThreads === newThreads &&\n previousArchivedThreads === newArchivedThreads\n ) {\n return;\n }\n\n if (\n previousThreads !== newThreads ||\n previousArchivedThreads !== newArchivedThreads ||\n previousThreadId !== newThreadId\n ) {\n this._threadData = {\n ...DEFAULT_THREAD_DATA,\n ...Object.fromEntries(\n adapter.threads?.map((t) => [\n t.id,\n {\n ...t,\n remoteId: t.remoteId,\n externalId: t.externalId,\n status: \"regular\",\n },\n ]) ?? [],\n ),\n ...Object.fromEntries(\n adapter.archivedThreads?.map((t) => [\n t.id,\n {\n ...t,\n remoteId: t.remoteId,\n externalId: t.externalId,\n status: \"archived\",\n },\n ]) ?? [],\n ),\n };\n }\n\n if (previousThreads !== newThreads) {\n this._threads = this.adapter.threads?.map((t) => t.id) ?? EMPTY_ARRAY;\n }\n\n if (previousArchivedThreads !== newArchivedThreads) {\n this._archivedThreads =\n this.adapter.archivedThreads?.map((t) => t.id) ?? EMPTY_ARRAY;\n }\n\n // `initialLoad ||`: `_mainThread!` must be assigned on construction.\n if (initialLoad || previousThreadId !== newThreadId) {\n if (!initialLoad) invalidateThreadRuntime(this._mainThread);\n this._mainThreadId = newThreadId;\n this._mainThread = this.threadFactory();\n }\n\n if (!this._threadData[this._mainThreadId]) {\n this._threadData = {\n ...this._threadData,\n [this._mainThreadId]: {\n id: this._mainThreadId,\n remoteId: undefined,\n externalId: undefined,\n status: \"regular\",\n },\n };\n }\n\n this._notifySubscribers();\n }\n\n public async reloadMainThread(): Promise<void> {\n // There is no runtime hook to remount here, so the capability is the only\n // path and an adapter without it has nothing to refetch with.\n if (!this._mainThread.unstable_refetchThread) return;\n // No unsent-thread guard: every entry here is regular or archived, so the\n // \"new\" status the remote thread list has to exclude cannot occur.\n await this._mainThread.unstable_refetchThread();\n }\n\n public async switchToThread(\n threadId: string,\n _options?: { unarchive?: boolean },\n ): Promise<void> {\n if (this._mainThreadId === threadId) return;\n const onSwitchToThread = this.adapter.onSwitchToThread;\n if (!onSwitchToThread)\n throw new Error(\n \"External store adapter does not support switching to thread\",\n );\n await onSwitchToThread(threadId);\n }\n\n public async switchToNewThread(): Promise<void> {\n const onSwitchToNewThread = this.adapter.onSwitchToNewThread;\n if (!onSwitchToNewThread)\n throw new Error(\n \"External store adapter does not support switching to new thread\",\n );\n\n await onSwitchToNewThread();\n }\n\n public async rename(threadId: string, newTitle: string): Promise<void> {\n const onRename = this.adapter.onRename;\n if (!onRename)\n throw new Error(\"External store adapter does not support renaming\");\n\n await onRename(threadId, newTitle);\n }\n\n public async updateCustom(\n threadId: string,\n custom: Record<string, unknown> | undefined,\n ): Promise<void> {\n const onUpdateCustom = this.adapter.onUpdateCustom;\n if (!onUpdateCustom)\n throw new Error(\n \"External store adapter does not support updating custom metadata\",\n );\n\n await onUpdateCustom(threadId, custom);\n }\n\n public async detach(): Promise<void> {\n // no-op\n }\n\n public async archive(threadId: string): Promise<void> {\n const onArchive = this.adapter.onArchive;\n if (!onArchive)\n throw new Error(\"External store adapter does not support archiving\");\n\n await onArchive(threadId);\n }\n\n public async unarchive(threadId: string): Promise<void> {\n const onUnarchive = this.adapter.onUnarchive;\n if (!onUnarchive)\n throw new Error(\"External store adapter does not support unarchiving\");\n\n await onUnarchive(threadId);\n }\n\n public async delete(threadId: string): Promise<void> {\n const onDelete = this.adapter.onDelete;\n if (!onDelete)\n throw new Error(\"External store adapter does not support deleting\");\n\n await onDelete(threadId);\n }\n\n public initialize(\n threadId: string,\n ): Promise<{ remoteId: string; externalId: string | undefined }> {\n return Promise.resolve({ remoteId: threadId, externalId: undefined });\n }\n\n public generateTitle(): never {\n throw new Error(\"Method not implemented.\");\n }\n\n private _subscriptions = new Set<() => void>();\n\n public subscribe(callback: () => void): Unsubscribe {\n this._subscriptions.add(callback);\n return () => this._subscriptions.delete(callback);\n }\n\n private _notifySubscribers() {\n notifySubscribers(this._subscriptions);\n }\n}\n"],"mappings":"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"}
|
|
@@ -38,6 +38,8 @@ declare class ExternalStoreThreadRuntimeCore extends BaseThreadRuntimeCore imple
|
|
|
38
38
|
extras: unknown;
|
|
39
39
|
private _converter;
|
|
40
40
|
private _store;
|
|
41
|
+
private _getInitializePromise?;
|
|
42
|
+
__internal_setGetInitializePromise(getPromise: () => Promise<unknown> | undefined): void;
|
|
41
43
|
private _transformedQueue;
|
|
42
44
|
/**
|
|
43
45
|
* Client-side tool-invocations pipeline. Constructed lazily on first
|
|
@@ -87,6 +89,12 @@ declare class ExternalStoreThreadRuntimeCore extends BaseThreadRuntimeCore imple
|
|
|
87
89
|
resumeRun(config: ResumeRunConfig): Promise<void>;
|
|
88
90
|
exportExternalState(): any;
|
|
89
91
|
importExternalState(state: any): void;
|
|
92
|
+
/**
|
|
93
|
+
* Adapter-facing notification that the backing session was discarded.
|
|
94
|
+
* Clears session-scoped tool-invocation state and parks queued work,
|
|
95
|
+
* without run-cancel semantics (`onCancel`, composer draft restoration).
|
|
96
|
+
*/
|
|
97
|
+
unstable_notifySessionReset(): void;
|
|
90
98
|
cancelRun(): void;
|
|
91
99
|
private dropEmptyOptimisticHead;
|
|
92
100
|
addToolResult(options: AddToolResultOptions): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-store-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtimes/external-store/external-store-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"external-store-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtimes/external-store/external-store-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;;;cAwEa,qBACX,oBACA,mBAAmB;cAKR,uCACH,iCACG;UAEH;MAiBG,gBAAY;UAIf;EACD;EACA;MACI;MAIA;YAIQ,6BAA6B;MAI5B,sEAAK,sDAAA;MAId;kBARqC;;;;;;;MAarC,iCAAiC;EAKrC,sBAAsB;EACtB;UAEC;UAEA;UAEA;EAED,mCACL,kBAAkB;UAKZ;;;;;UAMA;EAEQ,UAAU;EAQxB,YAAA,iBAAiB,sBACjB,OAAO;EAMF,sBAAsB,OAAO;;;;;;;UA2M5B;;;;;UAsEA;UACA;;;;;;;UAQA;EAmBQ,eAAe;;;;;;;;;UA6BvB;EAaK,OAAO,YAAY,gBAAgB;EAoEnC,cAAc,oBAAoB;EAoBxC,0BApBwC;EA0BxC,+BANa;EAUb,cAAc,qBAAqB,WAAW;EAI9C,gBAAgB;EAIV,SAAS,QAAQ,iBAAiB;EAYlC,UAAU,QAAQ,kBAAkB;EAO1C;EAOA,oBAAoB;;;;;;EAqBpB;EAKA;UAmFC;EAOD,cAAc,SAAS;EASvB,eAAe,SAAS;EAoBxB,sBAAsB,SAAS;EAStB,MAAM,2BAA2B;EAMjC,OAAO,MAAM;UAQrB"}
|
|
@@ -6,10 +6,16 @@ import { getAutoStatus, isAutoStatus } from "../../runtime/utils/auto-status.js"
|
|
|
6
6
|
import { ExportedMessageRepository, MessageRepository } from "../../runtime/utils/message-repository.js";
|
|
7
7
|
import { EMPTY_QUEUE_ITEMS } from "../../store/scopes/queue-item.js";
|
|
8
8
|
import { BaseThreadRuntimeCore } from "../../runtime/base/base-thread-runtime-core.js";
|
|
9
|
+
import { captureThreadRuntimeGeneration, isThreadRuntimeGenerationCurrent } from "../../runtime/utils/thread-runtime-lifecycle.js";
|
|
9
10
|
import { ThreadMessageConverter } from "./thread-message-converter.js";
|
|
10
11
|
import { ToolInvocationTracker } from "../tool-invocations/ToolInvocationTracker.js";
|
|
11
12
|
//#region src/runtimes/external-store/external-store-thread-runtime-core.ts
|
|
12
13
|
const EMPTY_ARRAY = Object.freeze([]);
|
|
14
|
+
const observeAdapterCallback = (name, result) => {
|
|
15
|
+
Promise.resolve(result).catch((error) => {
|
|
16
|
+
console.error(`[ExternalStoreThreadRuntimeCore] ${name} callback rejected`, error);
|
|
17
|
+
});
|
|
18
|
+
};
|
|
13
19
|
const shallowEqual = (a, b) => {
|
|
14
20
|
const aKeys = Object.keys(a);
|
|
15
21
|
if (aKeys.length !== Object.keys(b).length) return false;
|
|
@@ -65,6 +71,10 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
|
|
|
65
71
|
extras = void 0;
|
|
66
72
|
_converter = new ThreadMessageConverter();
|
|
67
73
|
_store;
|
|
74
|
+
_getInitializePromise;
|
|
75
|
+
__internal_setGetInitializePromise(getPromise) {
|
|
76
|
+
this._getInitializePromise = getPromise;
|
|
77
|
+
}
|
|
68
78
|
_transformedQueue;
|
|
69
79
|
/**
|
|
70
80
|
* Client-side tool-invocations pipeline. Constructed lazily on first
|
|
@@ -210,7 +220,7 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
|
|
|
210
220
|
try {
|
|
211
221
|
const messageId = this._findMessageIdForToolCall(command.toolCallId);
|
|
212
222
|
if (messageId === void 0) return;
|
|
213
|
-
this._store.onAddToolResult?.({
|
|
223
|
+
observeAdapterCallback("onAddToolResult", this._store.onAddToolResult?.({
|
|
214
224
|
messageId,
|
|
215
225
|
toolCallId: command.toolCallId,
|
|
216
226
|
toolName: command.toolName,
|
|
@@ -218,7 +228,7 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
|
|
|
218
228
|
isError: command.isError,
|
|
219
229
|
...command.artifact !== void 0 && { artifact: command.artifact },
|
|
220
230
|
...command.modelContent !== void 0 && { modelContent: command.modelContent }
|
|
221
|
-
});
|
|
231
|
+
}));
|
|
222
232
|
} catch (err) {
|
|
223
233
|
console.error("[ExternalStoreThreadRuntimeCore] onAddToolResult dispatch failed", err);
|
|
224
234
|
}
|
|
@@ -290,14 +300,20 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
|
|
|
290
300
|
}
|
|
291
301
|
async append(rawMessage) {
|
|
292
302
|
const isEdit = rawMessage.sourceId != null || rawMessage.parentId !== (this.messages.at(-1)?.id ?? null);
|
|
303
|
+
const message = !isEdit && this._store.queue && this._store.queue === this._transformedQueue ? rawMessage : this.enrichAppendMetadata(rawMessage);
|
|
304
|
+
const generation = captureThreadRuntimeGeneration(this);
|
|
305
|
+
this.ensureInitialized();
|
|
306
|
+
const initPromise = this._getInitializePromise?.();
|
|
293
307
|
if (!isEdit && this._store.queue) {
|
|
294
|
-
|
|
295
|
-
if (
|
|
296
|
-
|
|
308
|
+
if (initPromise) await initPromise;
|
|
309
|
+
if (!isThreadRuntimeGenerationCurrent(this, generation)) return;
|
|
310
|
+
if (message.steer ?? this._store.isRunning ?? false) this._store.queue.steer(message);
|
|
311
|
+
else this._store.queue.enqueue(message);
|
|
297
312
|
return;
|
|
298
313
|
}
|
|
299
|
-
|
|
314
|
+
initPromise?.catch(() => {});
|
|
300
315
|
if (message.startRun ?? message.role === "user") await this._toolInvocations?.abort();
|
|
316
|
+
if (!isThreadRuntimeGenerationCurrent(this, generation)) return;
|
|
301
317
|
if (isEdit) {
|
|
302
318
|
if (!this._store.onEdit) throw new Error("Runtime does not support editing messages.");
|
|
303
319
|
await this._store.onEdit(message);
|
|
@@ -341,17 +357,24 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
|
|
|
341
357
|
}
|
|
342
358
|
importExternalState(state) {
|
|
343
359
|
if (!this._store.onLoadExternalState) throw new Error("Runtime does not support importing external states.");
|
|
344
|
-
|
|
345
|
-
this._toolInvocations.reset();
|
|
346
|
-
this._store.setToolStatuses?.({});
|
|
347
|
-
}
|
|
360
|
+
this._toolInvocations?.reset();
|
|
348
361
|
this._store.onLoadExternalState(state);
|
|
349
362
|
}
|
|
363
|
+
/**
|
|
364
|
+
* Adapter-facing notification that the backing session was discarded.
|
|
365
|
+
* Clears session-scoped tool-invocation state and parks queued work,
|
|
366
|
+
* without run-cancel semantics (`onCancel`, composer draft restoration).
|
|
367
|
+
*/
|
|
368
|
+
unstable_notifySessionReset() {
|
|
369
|
+
this._toolInvocations?.reset();
|
|
370
|
+
this._store.queue?.__internal_notifyCancelled?.();
|
|
371
|
+
}
|
|
350
372
|
cancelRun() {
|
|
351
373
|
if (!this._store.onCancel) throw new Error("Runtime does not support cancelling runs.");
|
|
374
|
+
const generation = captureThreadRuntimeGeneration(this);
|
|
352
375
|
this._toolInvocations?.abort();
|
|
353
376
|
this._store.queue?.__internal_notifyCancelled?.();
|
|
354
|
-
this._store.onCancel();
|
|
377
|
+
observeAdapterCallback("onCancel", this._store.onCancel());
|
|
355
378
|
this.dropEmptyOptimisticHead();
|
|
356
379
|
const messages = this.repository.getMessages();
|
|
357
380
|
const previousMessage = messages[messages.length - 1];
|
|
@@ -373,6 +396,7 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
|
|
|
373
396
|
}
|
|
374
397
|
if (!movedLeaf) this._notifySubscribers();
|
|
375
398
|
setTimeout(() => {
|
|
399
|
+
if (!isThreadRuntimeGenerationCurrent(this, generation)) return;
|
|
376
400
|
this.dropEmptyOptimisticHead();
|
|
377
401
|
if (movedLeaf) {
|
|
378
402
|
const current = this.repository.getMessages();
|
|
@@ -388,7 +412,7 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
|
|
|
388
412
|
}
|
|
389
413
|
addToolResult(options) {
|
|
390
414
|
if (!this._store.onAddToolResult) throw new Error("Runtime does not support tool results.");
|
|
391
|
-
this._store.onAddToolResult
|
|
415
|
+
observeAdapterCallback("onAddToolResult", this._store.onAddToolResult(options));
|
|
392
416
|
}
|
|
393
417
|
resumeToolCall(options) {
|
|
394
418
|
if (this._toolInvocations?.resume(options.toolCallId, options.payload) ?? false) return;
|
|
@@ -400,7 +424,7 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
|
|
|
400
424
|
}
|
|
401
425
|
respondToToolApproval(options) {
|
|
402
426
|
if (!this._store.onRespondToToolApproval) throw new Error("Runtime does not support tool approvals.");
|
|
403
|
-
this._store.onRespondToToolApproval(options);
|
|
427
|
+
observeAdapterCallback("onRespondToToolApproval", this._store.onRespondToToolApproval(options));
|
|
404
428
|
}
|
|
405
429
|
reset(initialMessages) {
|
|
406
430
|
const repo = new MessageRepository();
|