@assistant-ui/core 0.3.15 → 0.3.17
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/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +8 -2
- package/dist/internal.js +9 -3
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js +3 -2
- package/dist/model-context/frame/host.js.map +1 -1
- package/dist/model-context/frame/provider.d.ts +5 -0
- package/dist/model-context/frame/provider.d.ts.map +1 -1
- package/dist/model-context/frame/provider.js +141 -28
- package/dist/model-context/frame/provider.js.map +1 -1
- package/dist/model-context/interactable-composer-metadata.d.ts +1 -1
- package/dist/model-context/interactable-composer-metadata.js +1 -1
- package/dist/model-context/interactable-composer-metadata.js.map +1 -1
- package/dist/model-context/registry.d.ts +2 -2
- package/dist/model-context/registry.d.ts.map +1 -1
- package/dist/model-context/registry.js +9 -28
- package/dist/model-context/registry.js.map +1 -1
- package/dist/model-context/tool-call-text.d.ts +26 -0
- package/dist/model-context/tool-call-text.d.ts.map +1 -0
- package/dist/model-context/tool-call-text.js +18 -0
- package/dist/model-context/tool-call-text.js.map +1 -0
- package/dist/react/RuntimeAdapter.js +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.js +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
- package/dist/react/client/AdaptedRemoteThread.js +1 -1
- package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
- package/dist/react/client/InMemoryThreadList.js +25 -21
- package/dist/react/client/InMemoryThreadList.js.map +1 -1
- package/dist/react/client/Interactables.d.ts.map +1 -1
- package/dist/react/client/Interactables.js +60 -178
- package/dist/react/client/Interactables.js.map +1 -1
- package/dist/react/client/RemoteThreadList.d.ts +15 -0
- package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
- package/dist/react/client/RemoteThreadList.js +263 -194
- package/dist/react/client/RemoteThreadList.js.map +1 -1
- package/dist/react/client/Tools.d.ts.map +1 -1
- package/dist/react/client/Tools.js +6 -2
- package/dist/react/client/Tools.js.map +1 -1
- package/dist/react/index.d.ts +4 -2
- package/dist/react/index.js +2 -1
- package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
- package/dist/react/interactables-legacy/Interactables.js +60 -178
- package/dist/react/interactables-legacy/Interactables.js.map +1 -1
- package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts +24 -0
- package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -0
- package/dist/react/interactables-shared/useInteractablePersistenceQueue.js +138 -0
- package/dist/react/interactables-shared/useInteractablePersistenceQueue.js.map +1 -0
- package/dist/react/model-context/toolbox.d.ts +2 -14
- package/dist/react/model-context/toolbox.d.ts.map +1 -1
- package/dist/react/model-context/toolbox.js +1 -13
- package/dist/react/model-context/toolbox.js.map +1 -1
- package/dist/react/model-context/useAssistantContext.js +37 -7
- package/dist/react/model-context/useAssistantContext.js.map +1 -1
- package/dist/react/model-context/useAuiToolOverrides.js +31 -5
- package/dist/react/model-context/useAuiToolOverrides.js.map +1 -1
- package/dist/react/model-context/useInlineRender.d.ts.map +1 -1
- package/dist/react/model-context/useInlineRender.js +10 -36
- package/dist/react/model-context/useInlineRender.js.map +1 -1
- package/dist/react/primitive-hooks/useMessageError.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useMessageError.js +2 -8
- package/dist/react/primitive-hooks/useMessageError.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadListLoadMore.js +2 -4
- package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
- package/dist/react/primitives/composer/ComposerAttachments.d.ts.map +1 -1
- package/dist/react/primitives/composer/ComposerAttachments.js +4 -3
- package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
- package/dist/react/primitives/composer/ComposerIf.js.map +1 -1
- package/dist/react/primitives/composer/ComposerQueue.d.ts +2 -1
- package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
- package/dist/react/primitives/composer/ComposerQueue.js +4 -3
- package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
- package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageAttachments.js +7 -6
- package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.js +2 -2
- package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
- package/dist/react/primitives/message/MessageParts.js +3 -3
- package/dist/react/primitives/message/MessageParts.js.map +1 -1
- package/dist/react/primitives/threadList/ThreadListItems.d.ts.map +1 -1
- package/dist/react/primitives/threadList/ThreadListItems.js +5 -4
- package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +7 -5
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +44 -22
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +7 -6
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +102 -117
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadResource.d.ts +1 -6
- package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadResource.js +3 -3
- package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
- package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -1
- package/dist/react/runtimes/assistant-transport/runManager.js +2 -12
- package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -1
- package/dist/react/runtimes/assistant-transport/useLatestRef.js +2 -2
- package/dist/react/runtimes/assistant-transport/useLatestRef.js.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +3 -10
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +43 -85
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.d.ts +5 -1
- package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +29 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js +159 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js.map +1 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts +12 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.js +10 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.js.map +1 -0
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts +1 -9
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +16 -153
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -1
- package/dist/react/runtimes/createMessageConverter.d.ts +2 -1
- package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.d.ts +6 -25
- package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.js +33 -233
- package/dist/react/runtimes/external-message-converter.js.map +1 -1
- package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
- package/dist/react/runtimes/useRemoteThreadListRuntime.js +14 -6
- package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
- package/dist/react/types/MessagePartComponentTypes.d.ts +7 -3
- package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
- package/dist/react/types/scopes/tools.d.ts +2 -0
- package/dist/react/types/scopes/tools.d.ts.map +1 -1
- package/dist/runtime/api/composer-runtime.d.ts +1 -1
- package/dist/runtime/api/composer-runtime.js.map +1 -1
- package/dist/runtime/api/message-part-runtime.d.ts +2 -2
- package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
- package/dist/runtime/api/message-part-runtime.js +1 -1
- package/dist/runtime/api/message-part-runtime.js.map +1 -1
- package/dist/runtime/api/thread-list-runtime.d.ts +9 -1
- package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-runtime.js +5 -0
- package/dist/runtime/api/thread-list-runtime.js.map +1 -1
- package/dist/runtime/api/thread-runtime.d.ts +2 -3
- package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.js +14 -29
- package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts +4 -6
- package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.js +5 -11
- package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +1 -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 +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
- package/dist/runtime/interfaces/composer-runtime-core.d.ts +1 -1
- package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +14 -2
- package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtime/interfaces/thread-runtime-core.d.ts +16 -2
- package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/internal.d.ts +2 -1
- package/dist/runtime/internal.js +2 -1
- package/dist/runtime/queue/external-thread-queue-adapter.d.ts +1 -1
- package/dist/runtime/queue/message-queue.d.ts.map +1 -1
- package/dist/runtime/queue/message-queue.js +1 -1
- package/dist/runtime/queue/message-queue.js.map +1 -1
- package/dist/runtime/queue/queue-item.d.ts +12 -0
- package/dist/runtime/queue/queue-item.d.ts.map +1 -0
- package/dist/runtime/queue/queue-item.js +6 -0
- package/dist/runtime/queue/queue-item.js.map +1 -0
- package/dist/runtime/utils/abortable-thread-load.d.ts +15 -0
- package/dist/runtime/utils/abortable-thread-load.d.ts.map +1 -0
- package/dist/runtime/utils/abortable-thread-load.js +35 -0
- package/dist/runtime/utils/abortable-thread-load.js.map +1 -0
- package/dist/runtime/utils/attachment-add-operations.d.ts +18 -0
- package/dist/runtime/utils/attachment-add-operations.d.ts.map +1 -0
- package/dist/runtime/utils/attachment-add-operations.js +43 -0
- package/dist/runtime/utils/attachment-add-operations.js.map +1 -0
- package/dist/runtime/utils/auto-status.d.ts +7 -2
- package/dist/runtime/utils/auto-status.d.ts.map +1 -1
- package/dist/runtime/utils/auto-status.js +13 -3
- package/dist/runtime/utils/auto-status.js.map +1 -1
- package/dist/runtime/utils/external-message-conversion.d.ts +48 -0
- package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -0
- package/dist/runtime/utils/external-message-conversion.js +222 -0
- package/dist/runtime/utils/external-message-conversion.js.map +1 -0
- package/dist/runtime/utils/external-store-message.d.ts +2 -1
- package/dist/runtime/utils/external-store-message.d.ts.map +1 -1
- package/dist/runtime/utils/external-store-message.js +2 -1
- package/dist/runtime/utils/external-store-message.js.map +1 -1
- package/dist/runtime/utils/message-repository-session.d.ts +30 -0
- package/dist/runtime/utils/message-repository-session.d.ts.map +1 -0
- package/dist/runtime/utils/message-repository-session.js +130 -0
- package/dist/runtime/utils/message-repository-session.js.map +1 -0
- package/dist/runtime/utils/message-repository.d.ts.map +1 -1
- package/dist/runtime/utils/message-repository.js +3 -4
- package/dist/runtime/utils/message-repository.js.map +1 -1
- package/dist/runtime/utils/pending-tool-calls.d.ts +20 -0
- package/dist/runtime/utils/pending-tool-calls.d.ts.map +1 -0
- package/dist/runtime/utils/pending-tool-calls.js +22 -0
- package/dist/runtime/utils/pending-tool-calls.js.map +1 -0
- package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +6 -3
- package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -1
- package/dist/runtime/utils/resolveToolApprovalResponse.js +12 -3
- package/dist/runtime/utils/resolveToolApprovalResponse.js.map +1 -1
- package/dist/runtime/utils/thread-message-like.d.ts +3 -10
- package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
- package/dist/runtime/utils/thread-message-like.js.map +1 -1
- package/dist/runtime/utils/tool-call-tree.d.ts +39 -0
- package/dist/runtime/utils/tool-call-tree.d.ts.map +1 -0
- package/dist/runtime/utils/tool-call-tree.js +85 -0
- package/dist/runtime/utils/tool-call-tree.js.map +1 -0
- package/dist/runtimes/external-store/external-store-adapter.d.ts +29 -2
- package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +2 -5
- 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 +3 -10
- 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 +21 -2
- 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 +154 -46
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +1 -1
- package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts +4 -2
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +23 -3
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +12 -1
- package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/remote-thread-state.js +107 -14
- package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
- package/dist/runtimes/remote-thread-list/title.d.ts +9 -0
- package/dist/runtimes/remote-thread-list/title.d.ts.map +1 -0
- package/dist/runtimes/remote-thread-list/title.js +6 -0
- package/dist/runtimes/remote-thread-list/title.js.map +1 -0
- package/dist/runtimes/remote-thread-list/types.d.ts +6 -5
- package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +31 -8
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +98 -59
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
- package/dist/store/clients/external-thread.d.ts +1 -1
- package/dist/store/clients/external-thread.d.ts.map +1 -1
- package/dist/store/clients/external-thread.js +85 -103
- package/dist/store/clients/external-thread.js.map +1 -1
- package/dist/store/clients/single-thread-list.d.ts.map +1 -1
- package/dist/store/clients/single-thread-list.js +2 -2
- package/dist/store/clients/single-thread-list.js.map +1 -1
- package/dist/store/clients/suggestions.d.ts.map +1 -1
- package/dist/store/clients/suggestions.js +33 -12
- package/dist/store/clients/suggestions.js.map +1 -1
- package/dist/store/clients/thread-message-client.js +1 -1
- package/dist/store/clients/thread-selection-events.js +1 -1
- package/dist/store/index.d.ts +6 -3
- package/dist/store/index.js +2 -1
- package/dist/store/internal.d.ts +2 -2
- package/dist/store/internal.js +2 -2
- package/dist/store/primitive-predicates.d.ts +4 -1
- package/dist/store/primitive-predicates.d.ts.map +1 -1
- package/dist/store/primitive-predicates.js +9 -1
- package/dist/store/primitive-predicates.js.map +1 -1
- package/dist/store/runtime-clients/composer-runtime-client.js +1 -1
- package/dist/store/runtime-clients/message-runtime-client.js +1 -1
- package/dist/store/runtime-clients/thread-list-item-runtime-client.js +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 +124 -105
- package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
- package/dist/store/runtime-clients/thread-runtime-client.js +1 -1
- package/dist/store/runtime-clients/useSubscribable.d.ts +3 -1
- package/dist/store/runtime-clients/useSubscribable.d.ts.map +1 -1
- package/dist/store/runtime-clients/useSubscribable.js +1 -1
- package/dist/store/runtime-clients/useSubscribable.js.map +1 -1
- package/dist/store/scope-registration.d.ts +1 -1
- package/dist/store/scopes/composer.d.ts +2 -1
- package/dist/store/scopes/composer.d.ts.map +1 -1
- package/dist/store/scopes/message.d.ts +1 -1
- package/dist/store/scopes/part.d.ts +6 -3
- package/dist/store/scopes/part.d.ts.map +1 -1
- package/dist/store/scopes/queue-item.d.ts +2 -9
- package/dist/store/scopes/queue-item.d.ts.map +1 -1
- package/dist/store/scopes/queue-item.js +0 -6
- package/dist/subscribable/subscribable.d.ts +8 -1
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/subscribable/subscribable.js +24 -16
- package/dist/subscribable/subscribable.js.map +1 -1
- package/dist/types/message.d.ts +47 -4
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/message.js +7 -1
- package/dist/types/message.js.map +1 -1
- package/dist/utils/data-url.d.ts +14 -1
- package/dist/utils/data-url.d.ts.map +1 -1
- package/dist/utils/data-url.js +13 -1
- package/dist/utils/data-url.js.map +1 -1
- package/dist/utils/invoke-user-callback.d.ts +5 -0
- package/dist/utils/invoke-user-callback.d.ts.map +1 -0
- package/dist/utils/invoke-user-callback.js +19 -0
- package/dist/utils/invoke-user-callback.js.map +1 -0
- package/dist/utils/normalizePartStatus.js.map +1 -1
- package/package.json +12 -17
- package/src/index.ts +6 -1
- package/src/internal.ts +20 -0
- package/src/model-context/frame/host.test.ts +91 -7
- package/src/model-context/frame/host.ts +7 -2
- package/src/model-context/frame/provider.test.ts +484 -13
- package/src/model-context/frame/provider.ts +205 -35
- package/src/model-context/interactable-composer-metadata.ts +1 -1
- package/src/model-context/registry.test.ts +44 -0
- package/src/model-context/registry.ts +13 -35
- package/src/model-context/tool-call-text.test.ts +67 -0
- package/src/model-context/tool-call-text.ts +67 -0
- package/src/react/AssistantRuntimeProvider.test.tsx +66 -2
- package/src/react/adapters/LocalStorageThreadListAdapter.tsx +1 -3
- package/src/react/client/InMemoryThreadList.test.tsx +49 -0
- package/src/react/client/InMemoryThreadList.ts +7 -1
- package/src/react/client/Interactables.ts +19 -178
- package/src/react/client/RemoteThreadList.background.test.ts +384 -0
- package/src/react/client/RemoteThreadList.concurrent.test.tsx +274 -0
- package/src/react/client/RemoteThreadList.test.ts +369 -1
- package/src/react/client/RemoteThreadList.ts +320 -142
- package/src/react/client/Tools.ts +7 -1
- package/src/react/index.ts +4 -0
- package/src/react/interactables-legacy/Interactables.ts +20 -177
- package/src/react/interactables-shared/useInteractablePersistenceQueue.test.tsx +161 -0
- package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +206 -0
- package/src/react/model-context/modelContextHooks.test.tsx +131 -0
- package/src/react/model-context/toolbox.test.ts +9 -9
- package/src/react/model-context/toolbox.ts +9 -36
- package/src/react/model-context/useAssistantContext.ts +4 -2
- package/src/react/model-context/useAuiToolOverrides.ts +4 -2
- package/src/react/model-context/useInlineRender.test.tsx +48 -0
- package/src/react/model-context/useInlineRender.ts +14 -10
- package/src/react/primitive-hooks/useMessageError.ts +2 -19
- package/src/react/primitive-hooks/useThreadListLoadMore.ts +2 -3
- package/src/react/primitives/composer/ComposerAttachments.test.tsx +76 -0
- package/src/react/primitives/composer/ComposerAttachments.tsx +9 -4
- package/src/react/primitives/composer/ComposerQueue.test.tsx +72 -0
- package/src/react/primitives/composer/ComposerQueue.tsx +7 -4
- package/src/react/primitives/message/MessageAttachments.test.tsx +107 -37
- package/src/react/primitives/message/MessageAttachments.tsx +10 -7
- package/src/react/primitives/message/MessageGroupedParts.tsx +2 -2
- package/src/react/primitives/message/MessageParts.tsx +3 -3
- package/src/react/primitives/threadList/ThreadListItems.test.tsx +99 -0
- package/src/react/primitives/threadList/ThreadListItems.tsx +8 -5
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +94 -1
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +72 -31
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.switch-delete.test.ts +169 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +140 -124
- package/src/react/runtimes/RemoteThreadResource.ts +1 -4
- package/src/react/runtimes/assistant-transport/runManager.ts +4 -17
- package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +51 -2
- package/src/react/runtimes/assistant-transport/useLatestRef.ts +2 -2
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +45 -0
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +157 -1
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +82 -176
- package/src/react/runtimes/cloud/auiV0.ts +5 -0
- package/src/react/runtimes/cloud/createCloudThreadListAdapter.test.ts +88 -0
- package/src/react/runtimes/cloud/createCloudThreadListAdapter.ts +236 -0
- package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.test.ts +37 -0
- package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.ts +18 -0
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +90 -1
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +33 -238
- package/src/react/runtimes/external-message-converter.test.ts +0 -14
- package/src/react/runtimes/external-message-converter.test.tsx +77 -0
- package/src/react/runtimes/external-message-converter.ts +59 -481
- package/src/react/runtimes/useRemoteThreadListRuntime.concurrent.test.tsx +216 -0
- package/src/react/runtimes/useRemoteThreadListRuntime.ts +24 -6
- package/src/react/types/MessagePartComponentTypes.ts +7 -3
- package/src/react/types/scopes/tools.ts +2 -0
- package/src/runtime/api/composer-runtime.ts +1 -1
- package/src/runtime/api/message-part-runtime.ts +3 -3
- package/src/runtime/api/message-runtime.test.ts +28 -1
- package/src/runtime/api/thread-list-runtime.ts +25 -1
- package/src/runtime/base/base-composer-runtime-core.ts +20 -40
- package/src/runtime/base/base-thread-runtime-core.test.ts +110 -3
- package/src/runtime/base/base-thread-runtime-core.ts +16 -15
- package/src/runtime/base/default-thread-composer-runtime-core.ts +1 -4
- package/src/runtime/interfaces/composer-runtime-core.ts +1 -1
- package/src/runtime/interfaces/thread-list-runtime-core.ts +20 -1
- package/src/runtime/interfaces/thread-runtime-core.ts +18 -2
- package/src/runtime/internal.ts +5 -0
- package/src/runtime/queue/external-thread-queue-adapter.ts +1 -1
- package/src/runtime/queue/message-queue.ts +1 -4
- package/src/runtime/queue/queue-item.ts +10 -0
- package/src/runtime/utils/abortable-thread-load.test.ts +87 -0
- package/src/runtime/utils/abortable-thread-load.ts +53 -0
- package/src/runtime/utils/attachment-add-operations.ts +59 -0
- package/src/runtime/utils/auto-status.test.ts +57 -0
- package/src/runtime/utils/auto-status.ts +46 -1
- package/src/runtime/utils/external-message-conversion.test.ts +210 -0
- package/src/runtime/utils/external-message-conversion.ts +510 -0
- package/src/runtime/utils/external-store-message.ts +2 -0
- package/src/runtime/utils/message-repository-session.test.ts +195 -0
- package/src/runtime/utils/message-repository-session.ts +176 -0
- package/src/runtime/utils/message-repository.ts +7 -4
- package/src/runtime/utils/pending-tool-calls.test.ts +57 -0
- package/src/runtime/utils/pending-tool-calls.ts +35 -0
- package/src/runtime/utils/resolveToolApprovalResponse.test.ts +73 -0
- package/src/runtime/utils/resolveToolApprovalResponse.ts +27 -6
- package/src/runtime/utils/thread-message-like.ts +4 -10
- package/src/runtime/utils/tool-call-tree.test.ts +191 -0
- package/src/runtime/utils/tool-call-tree.ts +97 -0
- package/src/runtimes/external-store/external-store-adapter.ts +38 -2
- package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +6 -14
- package/src/runtimes/external-store/external-store-thread-runtime-core.ts +231 -61
- package/src/runtimes/inert/InertThreadRuntimeCore.ts +1 -1
- package/src/runtimes/local/local-thread-runtime-core.test.ts +201 -4
- package/src/runtimes/local/local-thread-runtime-core.ts +53 -4
- package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +149 -0
- package/src/runtimes/remote-thread-list/remote-thread-state.ts +178 -16
- package/src/runtimes/remote-thread-list/title.ts +3 -0
- package/src/runtimes/remote-thread-list/types.ts +6 -5
- package/src/runtimes/tool-invocations/EDGE_CASES.md +125 -3
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +856 -102
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +145 -89
- package/src/store/clients/external-thread.ts +30 -69
- package/src/store/clients/single-thread-list.ts +4 -1
- package/src/store/clients/suggestions.test.ts +185 -0
- package/src/store/clients/suggestions.ts +42 -35
- package/src/store/index.ts +4 -0
- package/src/store/internal.ts +2 -0
- package/src/store/primitive-predicates.ts +35 -0
- package/src/store/runtime-clients/thread-list-runtime-client.ts +16 -2
- package/src/store/runtime-clients/useSubscribable.ts +8 -2
- package/src/store/scopes/message.ts +1 -1
- package/src/store/scopes/part.ts +6 -3
- package/src/store/scopes/queue-item.ts +2 -9
- package/src/subscribable/subscribable.test.ts +50 -0
- package/src/subscribable/subscribable.ts +33 -21
- package/src/tests/MessageRepository.test.ts +77 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +305 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +78 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-reload.test.ts +52 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-title-race.test.ts +158 -0
- package/src/tests/external-store-optimistic-id.test.ts +79 -0
- package/src/tests/external-store-repository-instance.test.ts +166 -0
- package/src/tests/external-store-thread-runtime-core-adapter.test.ts +186 -16
- package/src/tests/external-store-thread-runtime-core.test.ts +642 -0
- package/src/tests/external-thread-attachments.test.tsx +258 -1
- package/src/tests/remote-thread-list-adapter-switch.test.ts +66 -1
- package/src/tests/single-thread-list-item.test.tsx +47 -0
- package/src/tests/thread-message-like.test.ts +39 -1
- package/src/tests/thread-switch-events.test.tsx +397 -2
- package/src/types/message.ts +58 -5
- package/src/utils/data-url.test.ts +52 -1
- package/src/utils/data-url.ts +21 -0
- package/src/utils/invoke-user-callback.test.ts +82 -0
- package/src/utils/invoke-user-callback.ts +31 -0
- package/src/utils/normalizePartStatus.ts +1 -1
- package/dist/store/scopes/queue-item.js.map +0 -1
|
@@ -1155,3 +1155,645 @@ describe("ExternalStoreThreadRuntimeCore - message queue", () => {
|
|
|
1155
1155
|
expect(queue.remove).toHaveBeenCalledWith("q1");
|
|
1156
1156
|
});
|
|
1157
1157
|
});
|
|
1158
|
+
|
|
1159
|
+
describe("ExternalStoreThreadRuntimeCore - deleteMessage via setMessages", () => {
|
|
1160
|
+
const message = (id: string, role: "user" | "assistant", text: string) =>
|
|
1161
|
+
({
|
|
1162
|
+
id,
|
|
1163
|
+
role,
|
|
1164
|
+
content: [{ type: "text", text }],
|
|
1165
|
+
createdAt: new Date(0),
|
|
1166
|
+
metadata: { custom: {} },
|
|
1167
|
+
...(role === "assistant"
|
|
1168
|
+
? { status: { type: "complete", reason: "stop" } }
|
|
1169
|
+
: {}),
|
|
1170
|
+
}) as unknown as import("../types/message").ThreadMessage;
|
|
1171
|
+
|
|
1172
|
+
const setup = (initial: import("../types/message").ThreadMessage[]) => {
|
|
1173
|
+
let current = initial;
|
|
1174
|
+
const setMessages = vi.fn(
|
|
1175
|
+
(m: import("../types/message").ThreadMessage[]) => {
|
|
1176
|
+
current = m;
|
|
1177
|
+
},
|
|
1178
|
+
);
|
|
1179
|
+
const store = () => makeStore({ messages: current, setMessages });
|
|
1180
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1181
|
+
mockContextProvider,
|
|
1182
|
+
store(),
|
|
1183
|
+
);
|
|
1184
|
+
return {
|
|
1185
|
+
runtime,
|
|
1186
|
+
setMessages,
|
|
1187
|
+
setStoreMessages: (m: import("../types/message").ThreadMessage[]) => {
|
|
1188
|
+
current = m;
|
|
1189
|
+
},
|
|
1190
|
+
syncSnapshot: () => runtime.__internal_setAdapter(store()),
|
|
1191
|
+
};
|
|
1192
|
+
};
|
|
1193
|
+
|
|
1194
|
+
it("leaves no sibling branch behind", async () => {
|
|
1195
|
+
const { runtime, syncSnapshot } = setup([
|
|
1196
|
+
message("u1", "user", "hi"),
|
|
1197
|
+
message("a1", "assistant", "hello"),
|
|
1198
|
+
]);
|
|
1199
|
+
|
|
1200
|
+
await runtime.deleteMessage("u1");
|
|
1201
|
+
syncSnapshot();
|
|
1202
|
+
|
|
1203
|
+
expect(runtime.messages.map((m) => m.id)).toEqual(["a1"]);
|
|
1204
|
+
expect(runtime.getBranches("a1")).toEqual(["a1"]);
|
|
1205
|
+
});
|
|
1206
|
+
|
|
1207
|
+
it("relinks children when deleting mid-thread", async () => {
|
|
1208
|
+
const { runtime, syncSnapshot } = setup([
|
|
1209
|
+
message("u1", "user", "one"),
|
|
1210
|
+
message("a1", "assistant", "two"),
|
|
1211
|
+
message("u2", "user", "three"),
|
|
1212
|
+
message("a2", "assistant", "four"),
|
|
1213
|
+
]);
|
|
1214
|
+
|
|
1215
|
+
await runtime.deleteMessage("u2");
|
|
1216
|
+
syncSnapshot();
|
|
1217
|
+
|
|
1218
|
+
expect(runtime.messages.map((m) => m.id)).toEqual(["u1", "a1", "a2"]);
|
|
1219
|
+
expect(runtime.getBranches("a2")).toEqual(["a2"]);
|
|
1220
|
+
});
|
|
1221
|
+
|
|
1222
|
+
it("relinks every child branch when deleting a message with siblings", async () => {
|
|
1223
|
+
const { runtime, syncSnapshot, setStoreMessages } = setup([
|
|
1224
|
+
message("u1", "user", "one"),
|
|
1225
|
+
message("a1", "assistant", "two"),
|
|
1226
|
+
message("u2", "user", "three"),
|
|
1227
|
+
message("a2", "assistant", "four"),
|
|
1228
|
+
]);
|
|
1229
|
+
|
|
1230
|
+
setStoreMessages([
|
|
1231
|
+
message("u1", "user", "one"),
|
|
1232
|
+
message("a1", "assistant", "two"),
|
|
1233
|
+
message("u2", "user", "three"),
|
|
1234
|
+
message("a3", "assistant", "five"),
|
|
1235
|
+
]);
|
|
1236
|
+
syncSnapshot();
|
|
1237
|
+
expect(runtime.getBranches("a3")).toEqual(["a2", "a3"]);
|
|
1238
|
+
|
|
1239
|
+
await runtime.deleteMessage("u2");
|
|
1240
|
+
syncSnapshot();
|
|
1241
|
+
|
|
1242
|
+
expect(runtime.messages.map((m) => m.id)).toEqual(["u1", "a1", "a3"]);
|
|
1243
|
+
expect(runtime.getBranches("a3")).toEqual(["a2", "a3"]);
|
|
1244
|
+
});
|
|
1245
|
+
|
|
1246
|
+
it("does not resurrect deleted content through switchToBranch", async () => {
|
|
1247
|
+
const { runtime, setMessages, syncSnapshot } = setup([
|
|
1248
|
+
message("u1", "user", "hi"),
|
|
1249
|
+
message("a1", "assistant", "hello"),
|
|
1250
|
+
]);
|
|
1251
|
+
|
|
1252
|
+
await runtime.deleteMessage("u1");
|
|
1253
|
+
syncSnapshot();
|
|
1254
|
+
setMessages.mockClear();
|
|
1255
|
+
|
|
1256
|
+
expect(() => runtime.switchToBranch("u1")).toThrow(
|
|
1257
|
+
"MessageRepository(switchToBranch): Branch not found",
|
|
1258
|
+
);
|
|
1259
|
+
expect(setMessages).not.toHaveBeenCalled();
|
|
1260
|
+
});
|
|
1261
|
+
|
|
1262
|
+
it("exposes a consistent messages/branch view at notify time", async () => {
|
|
1263
|
+
const { runtime } = setup([
|
|
1264
|
+
message("u1", "user", "hi"),
|
|
1265
|
+
message("a1", "assistant", "hello"),
|
|
1266
|
+
]);
|
|
1267
|
+
|
|
1268
|
+
const observed: { ids: string[]; branches: readonly string[] }[] = [];
|
|
1269
|
+
runtime.subscribe(() => {
|
|
1270
|
+
observed.push({
|
|
1271
|
+
ids: runtime.messages.map((m) => m.id),
|
|
1272
|
+
branches: runtime.getBranches(runtime.messages.at(-1)!.id),
|
|
1273
|
+
});
|
|
1274
|
+
});
|
|
1275
|
+
|
|
1276
|
+
await runtime.deleteMessage("u1");
|
|
1277
|
+
|
|
1278
|
+
expect(observed).toContainEqual({ ids: ["a1"], branches: ["a1"] });
|
|
1279
|
+
for (const snapshot of observed) {
|
|
1280
|
+
expect(snapshot.ids).not.toContain("u1");
|
|
1281
|
+
expect(snapshot.branches).not.toContain("u1");
|
|
1282
|
+
}
|
|
1283
|
+
});
|
|
1284
|
+
|
|
1285
|
+
it("evicts the deleted message on the onDelete path too", async () => {
|
|
1286
|
+
let current = [
|
|
1287
|
+
message("u1", "user", "hi"),
|
|
1288
|
+
message("a1", "assistant", "hello"),
|
|
1289
|
+
];
|
|
1290
|
+
const onDelete = vi.fn(async (id: string) => {
|
|
1291
|
+
current = current.filter((m) => m.id !== id);
|
|
1292
|
+
});
|
|
1293
|
+
const store = () =>
|
|
1294
|
+
makeStore({ messages: current, onDelete, setMessages: vi.fn() });
|
|
1295
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1296
|
+
mockContextProvider,
|
|
1297
|
+
store(),
|
|
1298
|
+
);
|
|
1299
|
+
|
|
1300
|
+
await runtime.deleteMessage("u1");
|
|
1301
|
+
runtime.__internal_setAdapter(store());
|
|
1302
|
+
|
|
1303
|
+
expect(runtime.messages.map((m) => m.id)).toEqual(["a1"]);
|
|
1304
|
+
expect(runtime.getBranches("a1")).toEqual(["a1"]);
|
|
1305
|
+
expect(() => runtime.switchToBranch("u1")).toThrow(
|
|
1306
|
+
"MessageRepository(switchToBranch): Branch not found",
|
|
1307
|
+
);
|
|
1308
|
+
});
|
|
1309
|
+
|
|
1310
|
+
it("keeps an off-branch sibling the host declined to delete", async () => {
|
|
1311
|
+
let current = [
|
|
1312
|
+
message("u1", "user", "hi"),
|
|
1313
|
+
message("a1", "assistant", "one"),
|
|
1314
|
+
];
|
|
1315
|
+
const onDelete = vi.fn(async (id: string) => {
|
|
1316
|
+
current = current.filter((m) => m.id !== id);
|
|
1317
|
+
});
|
|
1318
|
+
const store = () => makeStore({ messages: current, onDelete });
|
|
1319
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1320
|
+
mockContextProvider,
|
|
1321
|
+
store(),
|
|
1322
|
+
);
|
|
1323
|
+
|
|
1324
|
+
current = [current[0]!, message("a2", "assistant", "two")];
|
|
1325
|
+
runtime.__internal_setAdapter(store());
|
|
1326
|
+
expect(runtime.getBranches("a2")).toEqual(["a1", "a2"]);
|
|
1327
|
+
|
|
1328
|
+
await runtime.deleteMessage("a1");
|
|
1329
|
+
current = [...current];
|
|
1330
|
+
runtime.__internal_setAdapter(store());
|
|
1331
|
+
|
|
1332
|
+
expect(onDelete).toHaveBeenCalledWith("a1");
|
|
1333
|
+
expect(runtime.getBranches("a2")).toEqual(["a1", "a2"]);
|
|
1334
|
+
});
|
|
1335
|
+
|
|
1336
|
+
it("keeps the eviction when a send races an in-flight delete", async () => {
|
|
1337
|
+
let current = [
|
|
1338
|
+
message("u1", "user", "hi"),
|
|
1339
|
+
message("a1", "assistant", "hello"),
|
|
1340
|
+
];
|
|
1341
|
+
let resolveDelete!: () => void;
|
|
1342
|
+
const onDelete = vi.fn(
|
|
1343
|
+
(id: string) =>
|
|
1344
|
+
new Promise<void>((resolve) => {
|
|
1345
|
+
resolveDelete = () => {
|
|
1346
|
+
current = current.filter((m) => m.id !== id);
|
|
1347
|
+
resolve();
|
|
1348
|
+
};
|
|
1349
|
+
}),
|
|
1350
|
+
);
|
|
1351
|
+
const onNew = vi.fn();
|
|
1352
|
+
const store = () =>
|
|
1353
|
+
makeStore({ messages: current, onDelete, onNew, setMessages: vi.fn() });
|
|
1354
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1355
|
+
mockContextProvider,
|
|
1356
|
+
store(),
|
|
1357
|
+
);
|
|
1358
|
+
|
|
1359
|
+
const deletePromise = runtime.deleteMessage("u1");
|
|
1360
|
+
await runtime.append({
|
|
1361
|
+
role: "user",
|
|
1362
|
+
content: [{ type: "text", text: "while deleting" }],
|
|
1363
|
+
attachments: [],
|
|
1364
|
+
createdAt: new Date(0),
|
|
1365
|
+
parentId: "a1",
|
|
1366
|
+
sourceId: null,
|
|
1367
|
+
runConfig: {},
|
|
1368
|
+
metadata: { custom: {} },
|
|
1369
|
+
});
|
|
1370
|
+
resolveDelete();
|
|
1371
|
+
await deletePromise;
|
|
1372
|
+
runtime.__internal_setAdapter(store());
|
|
1373
|
+
|
|
1374
|
+
expect(onNew).toHaveBeenCalled();
|
|
1375
|
+
expect(runtime.getBranches("a1")).toEqual(["a1"]);
|
|
1376
|
+
expect(() => runtime.switchToBranch("u1")).toThrow(
|
|
1377
|
+
"MessageRepository(switchToBranch): Branch not found",
|
|
1378
|
+
);
|
|
1379
|
+
});
|
|
1380
|
+
|
|
1381
|
+
it("keeps a pending eviction across a branch switch swallowed mid-run", async () => {
|
|
1382
|
+
let current = [
|
|
1383
|
+
message("u1", "user", "hi"),
|
|
1384
|
+
message("a1", "assistant", "hello"),
|
|
1385
|
+
];
|
|
1386
|
+
const onDelete = vi.fn(async (id: string) => {
|
|
1387
|
+
current = current.filter((m) => m.id !== id);
|
|
1388
|
+
});
|
|
1389
|
+
const store = (isRunning: boolean) =>
|
|
1390
|
+
makeStore({
|
|
1391
|
+
messages: current,
|
|
1392
|
+
onDelete,
|
|
1393
|
+
setMessages: vi.fn(),
|
|
1394
|
+
isRunning,
|
|
1395
|
+
});
|
|
1396
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1397
|
+
mockContextProvider,
|
|
1398
|
+
store(true),
|
|
1399
|
+
);
|
|
1400
|
+
|
|
1401
|
+
await runtime.deleteMessage("u1");
|
|
1402
|
+
runtime.switchToBranch("a1");
|
|
1403
|
+
runtime.__internal_setAdapter(store(true));
|
|
1404
|
+
|
|
1405
|
+
expect(runtime.getBranches("a1")).toEqual(["a1"]);
|
|
1406
|
+
|
|
1407
|
+
runtime.__internal_setAdapter(store(false));
|
|
1408
|
+
expect(() => runtime.switchToBranch("u1")).toThrow(
|
|
1409
|
+
"MessageRepository(switchToBranch): Branch not found",
|
|
1410
|
+
);
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
it("keeps a visible message the host declined to delete", async () => {
|
|
1414
|
+
const current = [
|
|
1415
|
+
message("u1", "user", "hi"),
|
|
1416
|
+
message("a1", "assistant", "hello"),
|
|
1417
|
+
];
|
|
1418
|
+
const onDelete = vi.fn(async () => {});
|
|
1419
|
+
const store = () =>
|
|
1420
|
+
makeStore({ messages: current, onDelete, setMessages: vi.fn() });
|
|
1421
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1422
|
+
mockContextProvider,
|
|
1423
|
+
store(),
|
|
1424
|
+
);
|
|
1425
|
+
|
|
1426
|
+
await runtime.deleteMessage("u1");
|
|
1427
|
+
runtime.__internal_setAdapter(store());
|
|
1428
|
+
|
|
1429
|
+
expect(onDelete).toHaveBeenCalledWith("u1");
|
|
1430
|
+
expect(runtime.messages.map((m) => m.id)).toEqual(["u1", "a1"]);
|
|
1431
|
+
expect(runtime.getBranches("a1")).toEqual(["a1"]);
|
|
1432
|
+
|
|
1433
|
+
runtime.__internal_setAdapter(
|
|
1434
|
+
makeStore({ messages: [...current], onDelete, setMessages: vi.fn() }),
|
|
1435
|
+
);
|
|
1436
|
+
expect(runtime.messages.map((m) => m.id)).toEqual(["u1", "a1"]);
|
|
1437
|
+
});
|
|
1438
|
+
|
|
1439
|
+
it("evicts when the host publishes the confirming snapshot before onDelete resolves", async () => {
|
|
1440
|
+
let current = [
|
|
1441
|
+
message("u1", "user", "hi"),
|
|
1442
|
+
message("a1", "assistant", "hello"),
|
|
1443
|
+
];
|
|
1444
|
+
let syncSnapshot!: () => void;
|
|
1445
|
+
const onDelete = vi.fn(async (id: string) => {
|
|
1446
|
+
current = current.filter((m) => m.id !== id);
|
|
1447
|
+
syncSnapshot();
|
|
1448
|
+
await Promise.resolve();
|
|
1449
|
+
});
|
|
1450
|
+
const store = () =>
|
|
1451
|
+
makeStore({ messages: current, onDelete, setMessages: vi.fn() });
|
|
1452
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1453
|
+
mockContextProvider,
|
|
1454
|
+
store(),
|
|
1455
|
+
);
|
|
1456
|
+
syncSnapshot = () => runtime.__internal_setAdapter(store());
|
|
1457
|
+
|
|
1458
|
+
await runtime.deleteMessage("u1");
|
|
1459
|
+
|
|
1460
|
+
expect(runtime.getBranches("a1")).toEqual(["a1"]);
|
|
1461
|
+
expect(() => runtime.switchToBranch("u1")).toThrow(
|
|
1462
|
+
"MessageRepository(switchToBranch): Branch not found",
|
|
1463
|
+
);
|
|
1464
|
+
});
|
|
1465
|
+
|
|
1466
|
+
it("keeps the message when onDelete rejects", async () => {
|
|
1467
|
+
const current = [
|
|
1468
|
+
message("u1", "user", "hi"),
|
|
1469
|
+
message("a1", "assistant", "hello"),
|
|
1470
|
+
];
|
|
1471
|
+
const onDelete = vi.fn(async () => {
|
|
1472
|
+
throw new Error("server down");
|
|
1473
|
+
});
|
|
1474
|
+
const store = () =>
|
|
1475
|
+
makeStore({ messages: current, onDelete, setMessages: vi.fn() });
|
|
1476
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1477
|
+
mockContextProvider,
|
|
1478
|
+
store(),
|
|
1479
|
+
);
|
|
1480
|
+
|
|
1481
|
+
await expect(runtime.deleteMessage("u1")).rejects.toThrow("server down");
|
|
1482
|
+
|
|
1483
|
+
runtime.__internal_setAdapter(
|
|
1484
|
+
makeStore({ messages: [...current], onDelete, setMessages: vi.fn() }),
|
|
1485
|
+
);
|
|
1486
|
+
expect(runtime.messages.map((m) => m.id)).toEqual(["u1", "a1"]);
|
|
1487
|
+
expect(runtime.getBranches("a1")).toEqual(["a1"]);
|
|
1488
|
+
|
|
1489
|
+
runtime.__internal_setAdapter(
|
|
1490
|
+
makeStore({
|
|
1491
|
+
messages: [
|
|
1492
|
+
message("u1b", "user", "other"),
|
|
1493
|
+
message("a1b", "assistant", "branch"),
|
|
1494
|
+
],
|
|
1495
|
+
onDelete,
|
|
1496
|
+
setMessages: vi.fn(),
|
|
1497
|
+
}),
|
|
1498
|
+
);
|
|
1499
|
+
expect(runtime.getBranches("u1b")).toEqual(["u1", "u1b"]);
|
|
1500
|
+
});
|
|
1501
|
+
|
|
1502
|
+
it("does not evict a declined delete when a later mutation changes the branch", async () => {
|
|
1503
|
+
let current = [
|
|
1504
|
+
message("u1", "user", "hi"),
|
|
1505
|
+
message("a1", "assistant", "one"),
|
|
1506
|
+
];
|
|
1507
|
+
const onDelete = vi.fn(async () => {});
|
|
1508
|
+
const setMessages = vi.fn((m: unknown[]) => {
|
|
1509
|
+
current = m as typeof current;
|
|
1510
|
+
});
|
|
1511
|
+
const store = () => makeStore({ messages: current, onDelete, setMessages });
|
|
1512
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1513
|
+
mockContextProvider,
|
|
1514
|
+
store(),
|
|
1515
|
+
);
|
|
1516
|
+
|
|
1517
|
+
current = [current[0]!, message("a2", "assistant", "two")];
|
|
1518
|
+
runtime.__internal_setAdapter(store());
|
|
1519
|
+
expect(runtime.getBranches("a2")).toEqual(["a1", "a2"]);
|
|
1520
|
+
|
|
1521
|
+
await runtime.deleteMessage("a2");
|
|
1522
|
+
|
|
1523
|
+
runtime.switchToBranch("a1");
|
|
1524
|
+
runtime.__internal_setAdapter(store());
|
|
1525
|
+
|
|
1526
|
+
expect(runtime.messages.map((m) => m.id)).toEqual(["u1", "a1"]);
|
|
1527
|
+
expect(runtime.getBranches("a1")).toEqual(["a1", "a2"]);
|
|
1528
|
+
});
|
|
1529
|
+
|
|
1530
|
+
it("leaves positional fallback ids for the snapshot remapping to prune", async () => {
|
|
1531
|
+
const convertMessage = (m: { text: string }): ThreadMessageLike => ({
|
|
1532
|
+
role: "user",
|
|
1533
|
+
content: [{ type: "text", text: m.text }],
|
|
1534
|
+
});
|
|
1535
|
+
let current = [{ text: "first" }, { text: "second" }];
|
|
1536
|
+
const setMessages = vi.fn((m: typeof current) => {
|
|
1537
|
+
current = m;
|
|
1538
|
+
});
|
|
1539
|
+
const store = () =>
|
|
1540
|
+
makeStore({ messages: current, convertMessage, setMessages });
|
|
1541
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1542
|
+
mockContextProvider,
|
|
1543
|
+
store(),
|
|
1544
|
+
);
|
|
1545
|
+
const firstId = runtime.messages[0]!.id;
|
|
1546
|
+
|
|
1547
|
+
await runtime.deleteMessage(firstId);
|
|
1548
|
+
runtime.__internal_setAdapter(store());
|
|
1549
|
+
|
|
1550
|
+
expect(runtime.messages).toHaveLength(1);
|
|
1551
|
+
expect(runtime.getBranches(runtime.messages[0]!.id)).toEqual([
|
|
1552
|
+
runtime.messages[0]!.id,
|
|
1553
|
+
]);
|
|
1554
|
+
});
|
|
1555
|
+
});
|
|
1556
|
+
|
|
1557
|
+
describe("ExternalStoreThreadRuntimeCore - id-less converted messages", () => {
|
|
1558
|
+
const convertMessage = (m: {
|
|
1559
|
+
role?: "user" | "assistant";
|
|
1560
|
+
text: string;
|
|
1561
|
+
}): ThreadMessageLike => ({
|
|
1562
|
+
role: m.role ?? "user",
|
|
1563
|
+
content: [{ type: "text", text: m.text }],
|
|
1564
|
+
});
|
|
1565
|
+
|
|
1566
|
+
const storeWith = (
|
|
1567
|
+
messages: { role?: "user" | "assistant"; text: string }[],
|
|
1568
|
+
isRunning = false,
|
|
1569
|
+
) => makeStore({ messages, convertMessage, isRunning });
|
|
1570
|
+
|
|
1571
|
+
const textOf = (message: { content: readonly { type: string }[] }) => {
|
|
1572
|
+
const part = message.content[0];
|
|
1573
|
+
return part && part.type === "text" && "text" in part
|
|
1574
|
+
? part.text
|
|
1575
|
+
: undefined;
|
|
1576
|
+
};
|
|
1577
|
+
|
|
1578
|
+
it("keeps a prepended history message", () => {
|
|
1579
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
1580
|
+
try {
|
|
1581
|
+
const m0 = { text: "older-user" };
|
|
1582
|
+
const m1 = { text: "newer-user" };
|
|
1583
|
+
const m2 = { role: "assistant" as const, text: "newer-assistant" };
|
|
1584
|
+
|
|
1585
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1586
|
+
mockContextProvider,
|
|
1587
|
+
storeWith([m1, m2]),
|
|
1588
|
+
);
|
|
1589
|
+
expect(runtime.messages).toHaveLength(2);
|
|
1590
|
+
|
|
1591
|
+
runtime.__internal_setAdapter(storeWith([m0, m1, m2]));
|
|
1592
|
+
|
|
1593
|
+
expect(warn).not.toHaveBeenCalled();
|
|
1594
|
+
expect(runtime.messages).toHaveLength(3);
|
|
1595
|
+
expect(runtime.messages.map(textOf)).toEqual([
|
|
1596
|
+
"older-user",
|
|
1597
|
+
"newer-user",
|
|
1598
|
+
"newer-assistant",
|
|
1599
|
+
]);
|
|
1600
|
+
} finally {
|
|
1601
|
+
warn.mockRestore();
|
|
1602
|
+
}
|
|
1603
|
+
});
|
|
1604
|
+
|
|
1605
|
+
it("keeps the last message id when its host object is replaced while running", () => {
|
|
1606
|
+
const user = { text: "hi" };
|
|
1607
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1608
|
+
mockContextProvider,
|
|
1609
|
+
storeWith([user, { role: "assistant", text: "he" }], true),
|
|
1610
|
+
);
|
|
1611
|
+
const assistantId = runtime.messages[1]!.id;
|
|
1612
|
+
|
|
1613
|
+
runtime.__internal_setAdapter(
|
|
1614
|
+
storeWith([user, { role: "assistant", text: "hel" }], true),
|
|
1615
|
+
);
|
|
1616
|
+
runtime.__internal_setAdapter(
|
|
1617
|
+
storeWith([user, { role: "assistant", text: "hello" }], true),
|
|
1618
|
+
);
|
|
1619
|
+
|
|
1620
|
+
expect(runtime.messages[1]!.id).toBe(assistantId);
|
|
1621
|
+
expect(runtime.getBranches(assistantId)).toEqual([assistantId]);
|
|
1622
|
+
expect(textOf(runtime.messages[1]!)).toBe("hello");
|
|
1623
|
+
});
|
|
1624
|
+
|
|
1625
|
+
it("does not rewrite an explicit host id when the list shifts", () => {
|
|
1626
|
+
const convertWithId = (m: {
|
|
1627
|
+
id?: string;
|
|
1628
|
+
text: string;
|
|
1629
|
+
}): ThreadMessageLike => ({
|
|
1630
|
+
...(m.id !== undefined ? { id: m.id } : {}),
|
|
1631
|
+
role: "user",
|
|
1632
|
+
content: [{ type: "text", text: m.text }],
|
|
1633
|
+
});
|
|
1634
|
+
|
|
1635
|
+
const explicit = { id: "host-a", text: "kept" };
|
|
1636
|
+
const idLess = { text: "id-less" };
|
|
1637
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1638
|
+
mockContextProvider,
|
|
1639
|
+
makeStore({
|
|
1640
|
+
messages: [explicit],
|
|
1641
|
+
convertMessage: convertWithId,
|
|
1642
|
+
}),
|
|
1643
|
+
);
|
|
1644
|
+
|
|
1645
|
+
runtime.__internal_setAdapter(
|
|
1646
|
+
makeStore({
|
|
1647
|
+
messages: [idLess, explicit],
|
|
1648
|
+
convertMessage: convertWithId,
|
|
1649
|
+
}),
|
|
1650
|
+
);
|
|
1651
|
+
|
|
1652
|
+
expect(runtime.messages.map((m) => m.id)).toEqual([
|
|
1653
|
+
expect.stringMatching(/^__external_store_fallback_/),
|
|
1654
|
+
"host-a",
|
|
1655
|
+
]);
|
|
1656
|
+
expect(runtime.messages.map(textOf)).toEqual(["id-less", "kept"]);
|
|
1657
|
+
});
|
|
1658
|
+
});
|
|
1659
|
+
|
|
1660
|
+
describe("ExternalStoreThreadRuntimeCore - convertMessage auto status", () => {
|
|
1661
|
+
const toolCall = (extra?: Record<string, unknown>) => ({
|
|
1662
|
+
type: "tool-call" as const,
|
|
1663
|
+
toolCallId: "t1",
|
|
1664
|
+
toolName: "search",
|
|
1665
|
+
args: {},
|
|
1666
|
+
argsText: "{}",
|
|
1667
|
+
...extra,
|
|
1668
|
+
});
|
|
1669
|
+
|
|
1670
|
+
const makeRuntime = (assistant: ThreadMessageLike, isRunning = false) =>
|
|
1671
|
+
new ExternalStoreThreadRuntimeCore(
|
|
1672
|
+
mockContextProvider,
|
|
1673
|
+
makeStore({
|
|
1674
|
+
isRunning,
|
|
1675
|
+
messages: [{ role: "user", content: "run it" }, assistant],
|
|
1676
|
+
convertMessage: (m: ThreadMessageLike) => m,
|
|
1677
|
+
setMessages: vi.fn(),
|
|
1678
|
+
}),
|
|
1679
|
+
);
|
|
1680
|
+
|
|
1681
|
+
it("reports requires-action for a tool call without a result", () => {
|
|
1682
|
+
const runtime = makeRuntime({ role: "assistant", content: [toolCall()] });
|
|
1683
|
+
expect(runtime.messages[1]!.status).toMatchObject({
|
|
1684
|
+
type: "requires-action",
|
|
1685
|
+
reason: "tool-calls",
|
|
1686
|
+
});
|
|
1687
|
+
});
|
|
1688
|
+
|
|
1689
|
+
it("reports an interrupt for an unresolved approval", () => {
|
|
1690
|
+
const runtime = makeRuntime({
|
|
1691
|
+
role: "assistant",
|
|
1692
|
+
content: [toolCall({ approval: { id: "a1" } })],
|
|
1693
|
+
});
|
|
1694
|
+
expect(runtime.messages[1]!.status).toMatchObject({
|
|
1695
|
+
type: "requires-action",
|
|
1696
|
+
reason: "interrupt",
|
|
1697
|
+
});
|
|
1698
|
+
});
|
|
1699
|
+
|
|
1700
|
+
it("reports an interrupt for a human interrupt", () => {
|
|
1701
|
+
const runtime = makeRuntime({
|
|
1702
|
+
role: "assistant",
|
|
1703
|
+
content: [toolCall({ interrupt: { type: "human", payload: {} } })],
|
|
1704
|
+
});
|
|
1705
|
+
expect(runtime.messages[1]!.status).toMatchObject({
|
|
1706
|
+
type: "requires-action",
|
|
1707
|
+
reason: "interrupt",
|
|
1708
|
+
});
|
|
1709
|
+
});
|
|
1710
|
+
|
|
1711
|
+
it("reports complete once the tool call has a result", () => {
|
|
1712
|
+
const runtime = makeRuntime({
|
|
1713
|
+
role: "assistant",
|
|
1714
|
+
content: [toolCall({ result: "ok" })],
|
|
1715
|
+
});
|
|
1716
|
+
expect(runtime.messages[1]!.status).toMatchObject({ type: "complete" });
|
|
1717
|
+
});
|
|
1718
|
+
|
|
1719
|
+
it("keeps the last message running while a tool call is still pending", () => {
|
|
1720
|
+
const runtime = makeRuntime(
|
|
1721
|
+
{ role: "assistant", content: [toolCall()] },
|
|
1722
|
+
true,
|
|
1723
|
+
);
|
|
1724
|
+
expect(runtime.messages[1]!.status).toMatchObject({ type: "running" });
|
|
1725
|
+
});
|
|
1726
|
+
|
|
1727
|
+
it("reuses the converted message until its auto status changes", () => {
|
|
1728
|
+
const pending: ThreadMessageLike = {
|
|
1729
|
+
role: "assistant",
|
|
1730
|
+
content: [toolCall()],
|
|
1731
|
+
};
|
|
1732
|
+
const user: ThreadMessageLike = { role: "user", content: "run it" };
|
|
1733
|
+
const convertMessage = vi.fn((m: ThreadMessageLike) => m);
|
|
1734
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1735
|
+
mockContextProvider,
|
|
1736
|
+
makeStore({
|
|
1737
|
+
isRunning: false,
|
|
1738
|
+
messages: [user, pending],
|
|
1739
|
+
convertMessage,
|
|
1740
|
+
setMessages: vi.fn(),
|
|
1741
|
+
}),
|
|
1742
|
+
);
|
|
1743
|
+
const first = runtime.messages[1]!;
|
|
1744
|
+
expect(convertMessage).toHaveBeenCalledTimes(2);
|
|
1745
|
+
|
|
1746
|
+
runtime.__internal_setAdapter(
|
|
1747
|
+
makeStore({
|
|
1748
|
+
isRunning: false,
|
|
1749
|
+
messages: [user, pending],
|
|
1750
|
+
convertMessage,
|
|
1751
|
+
setMessages: vi.fn(),
|
|
1752
|
+
}),
|
|
1753
|
+
);
|
|
1754
|
+
expect(runtime.messages[1]).toBe(first);
|
|
1755
|
+
expect(convertMessage).toHaveBeenCalledTimes(2);
|
|
1756
|
+
|
|
1757
|
+
runtime.__internal_setAdapter(
|
|
1758
|
+
makeStore({
|
|
1759
|
+
isRunning: false,
|
|
1760
|
+
messages: [user, { ...pending, content: [toolCall({ result: "ok" })] }],
|
|
1761
|
+
convertMessage,
|
|
1762
|
+
setMessages: vi.fn(),
|
|
1763
|
+
}),
|
|
1764
|
+
);
|
|
1765
|
+
expect(runtime.messages[1]!.status).toMatchObject({ type: "complete" });
|
|
1766
|
+
});
|
|
1767
|
+
|
|
1768
|
+
it("recomputes a cached message's status when the run ends", () => {
|
|
1769
|
+
const pending: ThreadMessageLike = {
|
|
1770
|
+
role: "assistant",
|
|
1771
|
+
content: [toolCall()],
|
|
1772
|
+
};
|
|
1773
|
+
const user: ThreadMessageLike = { role: "user", content: "run it" };
|
|
1774
|
+
const convertMessage = vi.fn((m: ThreadMessageLike) => m);
|
|
1775
|
+
const runtime = new ExternalStoreThreadRuntimeCore(
|
|
1776
|
+
mockContextProvider,
|
|
1777
|
+
makeStore({
|
|
1778
|
+
isRunning: true,
|
|
1779
|
+
messages: [user, pending],
|
|
1780
|
+
convertMessage,
|
|
1781
|
+
setMessages: vi.fn(),
|
|
1782
|
+
}),
|
|
1783
|
+
);
|
|
1784
|
+
expect(runtime.messages[1]!.status).toMatchObject({ type: "running" });
|
|
1785
|
+
|
|
1786
|
+
runtime.__internal_setAdapter(
|
|
1787
|
+
makeStore({
|
|
1788
|
+
isRunning: false,
|
|
1789
|
+
messages: [user, pending],
|
|
1790
|
+
convertMessage,
|
|
1791
|
+
setMessages: vi.fn(),
|
|
1792
|
+
}),
|
|
1793
|
+
);
|
|
1794
|
+
expect(runtime.messages[1]!.status).toMatchObject({
|
|
1795
|
+
type: "requires-action",
|
|
1796
|
+
reason: "tool-calls",
|
|
1797
|
+
});
|
|
1798
|
+
});
|
|
1799
|
+
});
|