@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
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
2
|
import type { RealtimeVoiceAdapter } from "../../adapters/voice";
|
|
3
|
+
import type { ModelContextProvider } from "../../model-context/types";
|
|
3
4
|
import type { AppendMessage } from "../../types/message";
|
|
5
|
+
import { CompositeContextProvider } from "../../utils/composite-context-provider";
|
|
4
6
|
import type {
|
|
5
7
|
AddToolResultOptions,
|
|
6
8
|
ResumeRunConfig,
|
|
@@ -45,8 +47,11 @@ const createVoiceAdapter = () => {
|
|
|
45
47
|
class TestRuntime extends BaseThreadRuntimeCore {
|
|
46
48
|
private readonly voiceAdapter: ReturnType<typeof createVoiceAdapter>;
|
|
47
49
|
|
|
48
|
-
constructor(
|
|
49
|
-
|
|
50
|
+
constructor(
|
|
51
|
+
voiceAdapter: ReturnType<typeof createVoiceAdapter>,
|
|
52
|
+
contextProvider: ModelContextProvider = { getModelContext: () => ({}) },
|
|
53
|
+
) {
|
|
54
|
+
super(contextProvider);
|
|
50
55
|
this.voiceAdapter = voiceAdapter;
|
|
51
56
|
}
|
|
52
57
|
|
|
@@ -99,7 +104,7 @@ class TestRuntime extends BaseThreadRuntimeCore {
|
|
|
99
104
|
resumeRun(_config: ResumeRunConfig) {}
|
|
100
105
|
addToolResult(_options: AddToolResultOptions) {}
|
|
101
106
|
resumeToolCall(_options: ResumeToolCallOptions) {}
|
|
102
|
-
respondToToolApproval(_options: RespondToToolApprovalOptions) {}
|
|
107
|
+
async respondToToolApproval(_options: RespondToToolApprovalOptions) {}
|
|
103
108
|
cancelRun() {}
|
|
104
109
|
exportExternalState() {
|
|
105
110
|
return {};
|
|
@@ -112,6 +117,108 @@ afterEach(() => {
|
|
|
112
117
|
vi.restoreAllMocks();
|
|
113
118
|
});
|
|
114
119
|
|
|
120
|
+
describe("BaseThreadRuntimeCore subscriptions", () => {
|
|
121
|
+
it("notifies later subscribers when an earlier subscriber throws", () => {
|
|
122
|
+
const runtime = new TestRuntime(createVoiceAdapter());
|
|
123
|
+
const error = new Error("subscriber failed");
|
|
124
|
+
const laterSubscriber = vi.fn();
|
|
125
|
+
|
|
126
|
+
runtime.subscribe(() => {
|
|
127
|
+
throw error;
|
|
128
|
+
});
|
|
129
|
+
runtime.subscribe(laterSubscriber);
|
|
130
|
+
|
|
131
|
+
expect(() => runtime.reset()).toThrow(error);
|
|
132
|
+
expect(laterSubscriber).toHaveBeenCalledOnce();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("isolates initialize listener errors during late replay", async () => {
|
|
136
|
+
const consoleError = vi
|
|
137
|
+
.spyOn(console, "error")
|
|
138
|
+
.mockImplementation(() => {});
|
|
139
|
+
const runtime = new TestRuntime(createVoiceAdapter());
|
|
140
|
+
runtime.reset();
|
|
141
|
+
|
|
142
|
+
const syncError = new Error("sync listener failed");
|
|
143
|
+
const asyncError = new Error("async listener failed");
|
|
144
|
+
runtime.unstable_on("initialize", () => {
|
|
145
|
+
throw syncError;
|
|
146
|
+
});
|
|
147
|
+
runtime.unstable_on("initialize", async () => {
|
|
148
|
+
throw asyncError;
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
await vi.waitFor(() => {
|
|
152
|
+
expect(consoleError).toHaveBeenCalledTimes(2);
|
|
153
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
154
|
+
'[assistant-ui] Thread runtime "initialize" listener threw an error',
|
|
155
|
+
syncError,
|
|
156
|
+
);
|
|
157
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
158
|
+
'[assistant-ui] Thread runtime "initialize" listener threw an error',
|
|
159
|
+
asyncError,
|
|
160
|
+
);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("isolates modelContextUpdate listener errors during context updates", () => {
|
|
165
|
+
const consoleError = vi
|
|
166
|
+
.spyOn(console, "error")
|
|
167
|
+
.mockImplementation(() => {});
|
|
168
|
+
const provider = new CompositeContextProvider();
|
|
169
|
+
const runtime = new TestRuntime(createVoiceAdapter(), provider);
|
|
170
|
+
const listenerError = new Error("model context listener failed");
|
|
171
|
+
const laterListener = vi.fn();
|
|
172
|
+
|
|
173
|
+
runtime.unstable_on("modelContextUpdate", () => {
|
|
174
|
+
throw listenerError;
|
|
175
|
+
});
|
|
176
|
+
runtime.unstable_on("modelContextUpdate", laterListener);
|
|
177
|
+
|
|
178
|
+
const unregister = provider.registerModelContextProvider({
|
|
179
|
+
getModelContext: () => ({}),
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
expect(laterListener).toHaveBeenCalledOnce();
|
|
183
|
+
expect(consoleError).toHaveBeenNthCalledWith(
|
|
184
|
+
1,
|
|
185
|
+
'[assistant-ui] Thread runtime "modelContextUpdate" listener threw an error',
|
|
186
|
+
listenerError,
|
|
187
|
+
);
|
|
188
|
+
expect(() => unregister()).not.toThrow();
|
|
189
|
+
expect(laterListener).toHaveBeenCalledTimes(2);
|
|
190
|
+
expect(consoleError).toHaveBeenNthCalledWith(
|
|
191
|
+
2,
|
|
192
|
+
'[assistant-ui] Thread runtime "modelContextUpdate" listener threw an error',
|
|
193
|
+
listenerError,
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("observes rejected modelContextUpdate listener promises", async () => {
|
|
198
|
+
const consoleError = vi
|
|
199
|
+
.spyOn(console, "error")
|
|
200
|
+
.mockImplementation(() => {});
|
|
201
|
+
const provider = new CompositeContextProvider();
|
|
202
|
+
const runtime = new TestRuntime(createVoiceAdapter(), provider);
|
|
203
|
+
const listenerError = new Error("async model context listener failed");
|
|
204
|
+
|
|
205
|
+
runtime.unstable_on("modelContextUpdate", async () => {
|
|
206
|
+
throw listenerError;
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
expect(() =>
|
|
210
|
+
provider.registerModelContextProvider({ getModelContext: () => ({}) }),
|
|
211
|
+
).not.toThrow();
|
|
212
|
+
|
|
213
|
+
await vi.waitFor(() => {
|
|
214
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
215
|
+
'[assistant-ui] Thread runtime "modelContextUpdate" listener threw an error',
|
|
216
|
+
listenerError,
|
|
217
|
+
);
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
115
222
|
describe("BaseThreadRuntimeCore voice volume subscriptions", () => {
|
|
116
223
|
it("continues notifying subscribers when one throws", () => {
|
|
117
224
|
const consoleError = vi
|
|
@@ -36,6 +36,7 @@ import type { RealtimeVoiceAdapter } from "../../adapters/voice";
|
|
|
36
36
|
import type { ThreadMessageLike } from "../utils/thread-message-like";
|
|
37
37
|
import { notifyEventListeners } from "../../utils/notify-event-listeners";
|
|
38
38
|
import { gateInteractableComposerMetadata } from "../../model-context/interactable-composer-metadata";
|
|
39
|
+
import { BaseSubscribable } from "../../subscribable/subscribable";
|
|
39
40
|
|
|
40
41
|
type BaseThreadAdapters = {
|
|
41
42
|
speech?: SpeechSynthesisAdapter | undefined;
|
|
@@ -44,11 +45,13 @@ type BaseThreadAdapters = {
|
|
|
44
45
|
voice?: RealtimeVoiceAdapter | undefined;
|
|
45
46
|
};
|
|
46
47
|
|
|
47
|
-
export abstract class BaseThreadRuntimeCore
|
|
48
|
-
|
|
48
|
+
export abstract class BaseThreadRuntimeCore
|
|
49
|
+
extends BaseSubscribable
|
|
50
|
+
implements ThreadRuntimeCore
|
|
51
|
+
{
|
|
49
52
|
private _isInitialized = false;
|
|
50
53
|
|
|
51
|
-
protected
|
|
54
|
+
protected repository = new MessageRepository();
|
|
52
55
|
public abstract get adapters(): BaseThreadAdapters | undefined;
|
|
53
56
|
public abstract get isDisabled(): boolean;
|
|
54
57
|
public abstract get isSendDisabled(): boolean;
|
|
@@ -65,7 +68,7 @@ export abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
|
|
|
65
68
|
public abstract resumeToolCall(options: ResumeToolCallOptions): void;
|
|
66
69
|
public abstract respondToToolApproval(
|
|
67
70
|
options: RespondToToolApprovalOptions,
|
|
68
|
-
): void
|
|
71
|
+
): Promise<void>;
|
|
69
72
|
public abstract cancelRun(): void;
|
|
70
73
|
public abstract exportExternalState(): any;
|
|
71
74
|
public abstract importExternalState(state: any): void;
|
|
@@ -118,6 +121,7 @@ export abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
|
|
|
118
121
|
private readonly _contextProvider: ModelContextProvider;
|
|
119
122
|
|
|
120
123
|
constructor(_contextProvider: ModelContextProvider) {
|
|
124
|
+
super();
|
|
121
125
|
this._contextProvider = _contextProvider;
|
|
122
126
|
}
|
|
123
127
|
|
|
@@ -213,10 +217,6 @@ export abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
|
|
|
213
217
|
this._notifySubscribers();
|
|
214
218
|
}
|
|
215
219
|
|
|
216
|
-
protected _notifySubscribers() {
|
|
217
|
-
for (const callback of this._subscriptions) callback();
|
|
218
|
-
}
|
|
219
|
-
|
|
220
220
|
public _notifyEventSubscribers<E extends ThreadRuntimeEventType>(
|
|
221
221
|
event: E,
|
|
222
222
|
payload: ThreadRuntimeEventPayload[E],
|
|
@@ -227,11 +227,6 @@ export abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
|
|
|
227
227
|
notifyEventListeners(subscribers, payload, `Thread runtime "${event}"`);
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
public subscribe(callback: () => void): Unsubscribe {
|
|
231
|
-
this._subscriptions.add(callback);
|
|
232
|
-
return () => this._subscriptions.delete(callback);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
230
|
public submitFeedback({ messageId, type }: SubmitFeedbackOptions) {
|
|
236
231
|
const adapter = this.adapters?.feedback;
|
|
237
232
|
if (!adapter) throw new Error("Feedback adapter not configured");
|
|
@@ -523,7 +518,11 @@ export abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
|
|
|
523
518
|
const wrapped = callback as (payload?: unknown) => void;
|
|
524
519
|
if (event === "modelContextUpdate") {
|
|
525
520
|
// provider.subscribe is `() => void`; pump the typed empty payload to the user callback.
|
|
526
|
-
return
|
|
521
|
+
return (
|
|
522
|
+
this._contextProvider.subscribe?.(() =>
|
|
523
|
+
notifyEventListeners([wrapped], {}, `Thread runtime "${event}"`),
|
|
524
|
+
) ?? (() => {})
|
|
525
|
+
);
|
|
527
526
|
}
|
|
528
527
|
|
|
529
528
|
let subscribers = this._eventSubscribers.get(event);
|
|
@@ -537,7 +536,9 @@ export abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
|
|
|
537
536
|
// after the thread already initialized, mirroring a BehaviorSubject.
|
|
538
537
|
if (event === "initialize" && this._isInitialized) {
|
|
539
538
|
queueMicrotask(() => {
|
|
540
|
-
if (subscribers.has(wrapped))
|
|
539
|
+
if (subscribers.has(wrapped)) {
|
|
540
|
+
notifyEventListeners([wrapped], {}, `Thread runtime "${event}"`);
|
|
541
|
+
}
|
|
541
542
|
});
|
|
542
543
|
}
|
|
543
544
|
|
|
@@ -8,10 +8,7 @@ import type {
|
|
|
8
8
|
import type { ThreadRuntimeCore } from "../interfaces/thread-runtime-core";
|
|
9
9
|
import { getThreadRuntimeCoreIsRunning } from "../api/thread-runtime";
|
|
10
10
|
import type { QueuePlacement } from "../queue/external-thread-queue-adapter";
|
|
11
|
-
import {
|
|
12
|
-
EMPTY_QUEUE_ITEMS,
|
|
13
|
-
type QueueItemState,
|
|
14
|
-
} from "../../store/scopes/queue-item";
|
|
11
|
+
import { EMPTY_QUEUE_ITEMS, type QueueItemState } from "../queue/queue-item";
|
|
15
12
|
import { BaseComposerRuntimeCore } from "./base-composer-runtime-core";
|
|
16
13
|
|
|
17
14
|
const isCancelable = (runtime: Omit<ThreadRuntimeCore, "composer">) => {
|
|
@@ -4,7 +4,7 @@ import type { Attachment, CreateAttachment } from "../../types/attachment";
|
|
|
4
4
|
import type { Unsubscribe } from "../../types/unsubscribe";
|
|
5
5
|
import type { RunConfig } from "../../types/message";
|
|
6
6
|
import type { DictationAdapter } from "../../adapters/speech";
|
|
7
|
-
import type { QueueItemState } from "
|
|
7
|
+
import type { QueueItemState } from "../queue/queue-item";
|
|
8
8
|
import type { QueuePlacement } from "../queue/external-thread-queue-adapter";
|
|
9
9
|
|
|
10
10
|
export type AttachmentAddErrorReason =
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { Unsubscribe } from "../../types/unsubscribe";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
ThreadRuntimeCore,
|
|
4
|
+
ThreadRuntimeEventType,
|
|
5
|
+
} from "./thread-runtime-core";
|
|
3
6
|
|
|
4
7
|
export type ThreadListItemStatus = "archived" | "regular" | "new" | "deleted";
|
|
5
8
|
|
|
@@ -16,6 +19,11 @@ export type ThreadListItemCoreState = {
|
|
|
16
19
|
readonly runtime?: ThreadRuntimeCore | undefined;
|
|
17
20
|
};
|
|
18
21
|
|
|
22
|
+
export type ThreadListRuntimeEvent = {
|
|
23
|
+
readonly threadId: string;
|
|
24
|
+
readonly type: ThreadRuntimeEventType;
|
|
25
|
+
};
|
|
26
|
+
|
|
19
27
|
export type ThreadListRuntimeCore = {
|
|
20
28
|
readonly isLoading: boolean;
|
|
21
29
|
readonly isLoadingMore?: boolean;
|
|
@@ -41,6 +49,17 @@ export type ThreadListRuntimeCore = {
|
|
|
41
49
|
*/
|
|
42
50
|
unstable_isThreadRunning?(threadId: string): boolean;
|
|
43
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Lifecycle events from every thread this list keeps alive, including
|
|
54
|
+
* threads that are not the main one. Implemented by thread lists that keep
|
|
55
|
+
* runtimes alive for non-main threads. A thread list that mounts only the
|
|
56
|
+
* main thread leaves this undefined: its other threads have no runtime and so
|
|
57
|
+
* emit nothing, and the main thread's runtime is observed directly.
|
|
58
|
+
*/
|
|
59
|
+
unstable_subscribeThreadEvents?(
|
|
60
|
+
callback: (event: ThreadListRuntimeEvent) => void,
|
|
61
|
+
): Unsubscribe;
|
|
62
|
+
|
|
44
63
|
getItemById(threadId: string): ThreadListItemCoreState | undefined;
|
|
45
64
|
|
|
46
65
|
switchToThread(
|
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
EditComposerRuntimeCore,
|
|
17
17
|
ThreadComposerRuntimeCore,
|
|
18
18
|
} from "./composer-runtime-core";
|
|
19
|
-
import type { QueueItemState } from "
|
|
19
|
+
import type { QueueItemState } from "../queue/queue-item";
|
|
20
20
|
import type { QueuePlacement } from "../queue/external-thread-queue-adapter";
|
|
21
21
|
|
|
22
22
|
export type RuntimeCapabilities = {
|
|
@@ -63,6 +63,8 @@ export type RespondToToolApprovalOptions = {
|
|
|
63
63
|
approved: boolean;
|
|
64
64
|
/** The approval option that produced this decision, when the request carried options. */
|
|
65
65
|
optionId?: string;
|
|
66
|
+
/** The free-form answer, when the request asked for one. */
|
|
67
|
+
text?: string;
|
|
66
68
|
reason?: string;
|
|
67
69
|
};
|
|
68
70
|
|
|
@@ -165,7 +167,21 @@ export type ThreadRuntimeCore = Readonly<{
|
|
|
165
167
|
|
|
166
168
|
addToolResult: (options: AddToolResultOptions) => void;
|
|
167
169
|
resumeToolCall: (options: ResumeToolCallOptions) => void;
|
|
168
|
-
|
|
170
|
+
/**
|
|
171
|
+
* Records a decision on a tool approval gate. Resolves once the runtime has
|
|
172
|
+
* accepted the response and rejects when it could not be recorded, so a
|
|
173
|
+
* caller can leave the gate retryable rather than spending it. A capability
|
|
174
|
+
* or state precondition still throws synchronously; a failure to record
|
|
175
|
+
* arrives as a rejection, including one an adapter raises synchronously.
|
|
176
|
+
*
|
|
177
|
+
* Acceptance is as far as the runtime can see the response: one that records
|
|
178
|
+
* the decision locally settles on the record, while one that answers by
|
|
179
|
+
* resuming a run settles on the resume. A failure of the work the decision
|
|
180
|
+
* unblocks is reported through the runtime's own error channel, not here.
|
|
181
|
+
*/
|
|
182
|
+
respondToToolApproval: (
|
|
183
|
+
options: RespondToToolApprovalOptions,
|
|
184
|
+
) => Promise<void>;
|
|
169
185
|
|
|
170
186
|
speak: (messageId: string) => void;
|
|
171
187
|
stopSpeaking: () => void;
|
package/src/runtime/internal.ts
CHANGED
|
@@ -56,3 +56,8 @@ export {
|
|
|
56
56
|
MessageRepository,
|
|
57
57
|
} from "./utils/message-repository";
|
|
58
58
|
export type { ExportedMessageRepositoryItem } from "./utils/message-repository";
|
|
59
|
+
export { createMessageRepositorySession } from "./utils/message-repository-session";
|
|
60
|
+
export type {
|
|
61
|
+
MessageRepositorySession,
|
|
62
|
+
MessageRepositorySessionOptions,
|
|
63
|
+
} from "./utils/message-repository-session";
|
|
@@ -3,10 +3,7 @@ import type {
|
|
|
3
3
|
FileMessagePart,
|
|
4
4
|
TextMessagePart,
|
|
5
5
|
} from "../../types/message";
|
|
6
|
-
import {
|
|
7
|
-
EMPTY_QUEUE_ITEMS,
|
|
8
|
-
type QueueItemState,
|
|
9
|
-
} from "../../store/scopes/queue-item";
|
|
6
|
+
import { EMPTY_QUEUE_ITEMS, type QueueItemState } from "./queue-item";
|
|
10
7
|
import { generateId } from "../../utils/id";
|
|
11
8
|
import { notifyEventListeners } from "../../utils/notify-event-listeners";
|
|
12
9
|
import { getThreadMessageText } from "../../utils/text";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FileMessagePart, TextMessagePart } from "../../types/message";
|
|
2
|
+
|
|
3
|
+
export type QueueItemState = {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
/** @deprecated Derive from the text parts of `parts` instead. Removal after 2026-11-05. */
|
|
6
|
+
readonly prompt: string;
|
|
7
|
+
readonly parts: readonly (FileMessagePart | TextMessagePart)[];
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const EMPTY_QUEUE_ITEMS: readonly QueueItemState[] = Object.freeze([]);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { createAbortableThreadLoad } from "./abortable-thread-load";
|
|
3
|
+
|
|
4
|
+
const callbacks = () => ({
|
|
5
|
+
onSettled: vi.fn(),
|
|
6
|
+
onInitialError: vi.fn(),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
describe("createAbortableThreadLoad", () => {
|
|
10
|
+
it("defers a reload to an in-flight initial load", async () => {
|
|
11
|
+
let resolveInitial!: () => void;
|
|
12
|
+
const initialLoad = vi.fn(
|
|
13
|
+
() =>
|
|
14
|
+
new Promise<void>((resolve) => {
|
|
15
|
+
resolveInitial = resolve;
|
|
16
|
+
}),
|
|
17
|
+
);
|
|
18
|
+
const reloadLoad = vi.fn(() => Promise.resolve());
|
|
19
|
+
const controller = createAbortableThreadLoad();
|
|
20
|
+
|
|
21
|
+
const initial = controller.run({
|
|
22
|
+
purpose: "initial",
|
|
23
|
+
load: initialLoad,
|
|
24
|
+
...callbacks(),
|
|
25
|
+
});
|
|
26
|
+
const reload = controller.run({
|
|
27
|
+
purpose: "reload",
|
|
28
|
+
load: reloadLoad,
|
|
29
|
+
...callbacks(),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
expect(reloadLoad).not.toHaveBeenCalled();
|
|
33
|
+
resolveInitial();
|
|
34
|
+
await Promise.all([initial, reload]);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("aborts a superseded load and swallows its failure", async () => {
|
|
38
|
+
let rejectFirst!: (error: Error) => void;
|
|
39
|
+
let firstSignal!: AbortSignal;
|
|
40
|
+
const controller = createAbortableThreadLoad();
|
|
41
|
+
const first = controller.run({
|
|
42
|
+
purpose: "reload",
|
|
43
|
+
load: (signal) => {
|
|
44
|
+
firstSignal = signal;
|
|
45
|
+
return new Promise<void>((_, reject) => {
|
|
46
|
+
rejectFirst = reject;
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
...callbacks(),
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const second = controller.run({
|
|
53
|
+
purpose: "initial",
|
|
54
|
+
load: () => Promise.resolve(),
|
|
55
|
+
...callbacks(),
|
|
56
|
+
});
|
|
57
|
+
rejectFirst(new Error("aborted"));
|
|
58
|
+
|
|
59
|
+
expect(firstSignal.aborted).toBe(true);
|
|
60
|
+
await expect(first).resolves.toBeUndefined();
|
|
61
|
+
await second;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("swallows initial failures and surfaces reload failures", async () => {
|
|
65
|
+
const controller = createAbortableThreadLoad();
|
|
66
|
+
const initialCallbacks = callbacks();
|
|
67
|
+
const initialError = new Error("initial");
|
|
68
|
+
|
|
69
|
+
await expect(
|
|
70
|
+
controller.run({
|
|
71
|
+
purpose: "initial",
|
|
72
|
+
load: () => Promise.reject(initialError),
|
|
73
|
+
...initialCallbacks,
|
|
74
|
+
}),
|
|
75
|
+
).resolves.toBeUndefined();
|
|
76
|
+
expect(initialCallbacks.onInitialError).toHaveBeenCalledWith(initialError);
|
|
77
|
+
|
|
78
|
+
const reloadError = new Error("reload");
|
|
79
|
+
await expect(
|
|
80
|
+
controller.run({
|
|
81
|
+
purpose: "reload",
|
|
82
|
+
load: () => Promise.reject(reloadError),
|
|
83
|
+
...callbacks(),
|
|
84
|
+
}),
|
|
85
|
+
).rejects.toBe(reloadError);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export type AbortableThreadLoadPurpose = "initial" | "reload";
|
|
2
|
+
|
|
3
|
+
type AbortableThreadLoadOptions = {
|
|
4
|
+
purpose?: AbortableThreadLoadPurpose;
|
|
5
|
+
load: (signal: AbortSignal) => Promise<void>;
|
|
6
|
+
onSettled: () => void;
|
|
7
|
+
onInitialError: (error: unknown) => void;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const createAbortableThreadLoad = () => {
|
|
11
|
+
let current: {
|
|
12
|
+
controller: AbortController;
|
|
13
|
+
purpose: AbortableThreadLoadPurpose;
|
|
14
|
+
promise?: Promise<void>;
|
|
15
|
+
} | null = null;
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
abort(purpose?: AbortableThreadLoadPurpose) {
|
|
19
|
+
if (purpose !== undefined && current?.purpose !== purpose) return;
|
|
20
|
+
current?.controller.abort();
|
|
21
|
+
},
|
|
22
|
+
run({
|
|
23
|
+
purpose = "initial",
|
|
24
|
+
load,
|
|
25
|
+
onSettled,
|
|
26
|
+
onInitialError,
|
|
27
|
+
}: AbortableThreadLoadOptions): Promise<void> {
|
|
28
|
+
if (purpose === "reload" && current?.purpose === "initial") {
|
|
29
|
+
return current.promise ?? Promise.resolve();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
current?.controller.abort();
|
|
33
|
+
const controller = new AbortController();
|
|
34
|
+
const record: NonNullable<typeof current> = { controller, purpose };
|
|
35
|
+
current = record;
|
|
36
|
+
|
|
37
|
+
const task = load(controller.signal)
|
|
38
|
+
.catch((error: unknown) => {
|
|
39
|
+
if (controller.signal.aborted) return;
|
|
40
|
+
throw error;
|
|
41
|
+
})
|
|
42
|
+
.finally(() => {
|
|
43
|
+
if (current?.controller === controller) current = null;
|
|
44
|
+
if (controller.signal.aborted) return;
|
|
45
|
+
onSettled();
|
|
46
|
+
});
|
|
47
|
+
record.promise = task;
|
|
48
|
+
|
|
49
|
+
if (purpose === "reload") return task;
|
|
50
|
+
return task.catch(onInitialError);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export type AttachmentAddOperation = {
|
|
2
|
+
cancelled: boolean;
|
|
3
|
+
attachmentIds: Set<string>;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export class AttachmentAddOperations {
|
|
7
|
+
private readonly operations = new Set<AttachmentAddOperation>();
|
|
8
|
+
|
|
9
|
+
start() {
|
|
10
|
+
const operation: AttachmentAddOperation = {
|
|
11
|
+
cancelled: false,
|
|
12
|
+
attachmentIds: new Set(),
|
|
13
|
+
};
|
|
14
|
+
this.operations.add(operation);
|
|
15
|
+
return operation;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
accept(operation: AttachmentAddOperation, attachmentId: string) {
|
|
19
|
+
if (operation.cancelled) return false;
|
|
20
|
+
operation.attachmentIds.add(attachmentId);
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
finish(operation: AttachmentAddOperation) {
|
|
25
|
+
this.operations.delete(operation);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
isCancelled(operation: AttachmentAddOperation) {
|
|
29
|
+
return operation.cancelled;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
cancel(attachmentId: string) {
|
|
33
|
+
for (const operation of [...this.operations]) {
|
|
34
|
+
if (!operation.attachmentIds.has(attachmentId)) continue;
|
|
35
|
+
operation.cancelled = true;
|
|
36
|
+
this.operations.delete(operation);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
cancelAll() {
|
|
41
|
+
for (const operation of this.operations) {
|
|
42
|
+
operation.cancelled = true;
|
|
43
|
+
}
|
|
44
|
+
this.operations.clear();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const drainAttachmentAdd = async <T>(
|
|
49
|
+
result: Promise<T> | AsyncIterable<T>,
|
|
50
|
+
accept: (attachment: T) => boolean,
|
|
51
|
+
) => {
|
|
52
|
+
if (Symbol.asyncIterator in result) {
|
|
53
|
+
for await (const attachment of result) {
|
|
54
|
+
if (!accept(attachment)) break;
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
accept(await result);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { getAutoStatus } from "./auto-status";
|
|
3
|
+
|
|
4
|
+
describe("getAutoStatus", () => {
|
|
5
|
+
it("reports a cancelled message as incomplete", () => {
|
|
6
|
+
expect(
|
|
7
|
+
getAutoStatus(true, false, false, false, undefined, true),
|
|
8
|
+
).toMatchObject({ type: "incomplete", reason: "cancelled" });
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("keeps a cancelled message incomplete once a later message arrives", () => {
|
|
12
|
+
expect(
|
|
13
|
+
getAutoStatus(false, false, false, false, undefined, true),
|
|
14
|
+
).toMatchObject({ type: "incomplete", reason: "cancelled" });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("reports an uncancelled message as complete", () => {
|
|
18
|
+
expect(
|
|
19
|
+
getAutoStatus(true, false, false, false, undefined, false),
|
|
20
|
+
).toMatchObject({ type: "complete", reason: "unknown" });
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it.each([
|
|
24
|
+
["running", { type: "running" }, true, false, false, undefined],
|
|
25
|
+
[
|
|
26
|
+
"an interrupted tool call",
|
|
27
|
+
{ type: "requires-action", reason: "interrupt" },
|
|
28
|
+
false,
|
|
29
|
+
true,
|
|
30
|
+
true,
|
|
31
|
+
undefined,
|
|
32
|
+
],
|
|
33
|
+
[
|
|
34
|
+
"a pending tool call",
|
|
35
|
+
{ type: "requires-action", reason: "tool-calls" },
|
|
36
|
+
false,
|
|
37
|
+
false,
|
|
38
|
+
true,
|
|
39
|
+
undefined,
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
"an error",
|
|
43
|
+
{ type: "incomplete", reason: "error", error: "boom" },
|
|
44
|
+
false,
|
|
45
|
+
false,
|
|
46
|
+
false,
|
|
47
|
+
"boom",
|
|
48
|
+
],
|
|
49
|
+
])(
|
|
50
|
+
"keeps %s ahead of cancellation",
|
|
51
|
+
(_label, expected, isRunning, interrupted, pending, error) => {
|
|
52
|
+
expect(
|
|
53
|
+
getAutoStatus(true, isRunning, interrupted, pending, error, true),
|
|
54
|
+
).toMatchObject(expected);
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
});
|