@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
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
|
|
3
|
+
import { act, render } from "@testing-library/react";
|
|
4
|
+
import { startTransition, Suspense, type ReactNode } from "react";
|
|
5
|
+
import { describe, expect, it, vi } from "vitest";
|
|
6
|
+
import type { AssistantRuntime } from "../../runtime/api/assistant-runtime";
|
|
7
|
+
import type { AppendMessage } from "../../types/message";
|
|
8
|
+
import { makeAdapter } from "../../tests/remote-thread-list-test-helpers";
|
|
9
|
+
import { AssistantRuntimeProvider } from "../AssistantRuntimeProvider";
|
|
10
|
+
import { useExternalStoreRuntime } from "./useExternalStoreRuntime";
|
|
11
|
+
import { useRemoteThreadListRuntime } from "./useRemoteThreadListRuntime";
|
|
12
|
+
|
|
13
|
+
const EMPTY_MESSAGES: readonly never[] = [];
|
|
14
|
+
|
|
15
|
+
const userMessage = (text: string): AppendMessage => ({
|
|
16
|
+
parentId: null,
|
|
17
|
+
sourceId: null,
|
|
18
|
+
runConfig: {},
|
|
19
|
+
role: "user",
|
|
20
|
+
content: [{ type: "text", text }],
|
|
21
|
+
attachments: [],
|
|
22
|
+
metadata: { custom: {} },
|
|
23
|
+
createdAt: new Date(),
|
|
24
|
+
startRun: true,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const getThreadCore = (runtime: AssistantRuntime) =>
|
|
28
|
+
(
|
|
29
|
+
runtime.thread as unknown as {
|
|
30
|
+
__internal_threadBinding: {
|
|
31
|
+
getState(): { append(message: AppendMessage): Promise<void> };
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
).__internal_threadBinding.getState();
|
|
35
|
+
|
|
36
|
+
const createHarness = ({ stableHook = false } = {}) => {
|
|
37
|
+
const adapter = makeAdapter();
|
|
38
|
+
const onNewA = vi.fn(async () => {});
|
|
39
|
+
const onNewB = vi.fn(async () => {});
|
|
40
|
+
const renderB = vi.fn();
|
|
41
|
+
const renderThreadRuntime = vi.fn();
|
|
42
|
+
const runtimeRef: { current: AssistantRuntime | null } = { current: null };
|
|
43
|
+
const pending = new Promise<never>(() => {});
|
|
44
|
+
let suspend = false;
|
|
45
|
+
|
|
46
|
+
const Blocker = () => {
|
|
47
|
+
if (suspend) throw pending;
|
|
48
|
+
return null;
|
|
49
|
+
};
|
|
50
|
+
// Every shipped adapter passes a fresh function expression, so a hoisted
|
|
51
|
+
// variant is the only way to exercise an unchanged published hook.
|
|
52
|
+
const useHoistedThreadRuntime = () => {
|
|
53
|
+
renderThreadRuntime();
|
|
54
|
+
return useExternalStoreRuntime({
|
|
55
|
+
messages: EMPTY_MESSAGES,
|
|
56
|
+
onNew: onNewA,
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
const App = ({
|
|
60
|
+
onNew,
|
|
61
|
+
children,
|
|
62
|
+
}: {
|
|
63
|
+
onNew: typeof onNewA;
|
|
64
|
+
children?: ReactNode;
|
|
65
|
+
}) => {
|
|
66
|
+
if (onNew === onNewB) renderB();
|
|
67
|
+
const useThreadRuntime = stableHook
|
|
68
|
+
? useHoistedThreadRuntime
|
|
69
|
+
: () => {
|
|
70
|
+
renderThreadRuntime();
|
|
71
|
+
return useExternalStoreRuntime({ messages: EMPTY_MESSAGES, onNew });
|
|
72
|
+
};
|
|
73
|
+
const runtime = useRemoteThreadListRuntime({
|
|
74
|
+
adapter,
|
|
75
|
+
runtimeHook: useThreadRuntime,
|
|
76
|
+
});
|
|
77
|
+
runtimeRef.current = runtime;
|
|
78
|
+
return (
|
|
79
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
80
|
+
{children ?? <Blocker />}
|
|
81
|
+
</AssistantRuntimeProvider>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
App,
|
|
87
|
+
onNewA,
|
|
88
|
+
onNewB,
|
|
89
|
+
renderB,
|
|
90
|
+
renderThreadRuntime,
|
|
91
|
+
runtimeRef,
|
|
92
|
+
suspend: () => {
|
|
93
|
+
suspend = true;
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
describe("useRemoteThreadListRuntime concurrent options", () => {
|
|
99
|
+
it("keeps new threads on the committed runtime hook", async () => {
|
|
100
|
+
const { App, onNewA, onNewB, renderB, runtimeRef, suspend } =
|
|
101
|
+
createHarness();
|
|
102
|
+
const view = render(
|
|
103
|
+
<Suspense fallback={null}>
|
|
104
|
+
<App onNew={onNewA} />
|
|
105
|
+
</Suspense>,
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
await act(async () => {
|
|
109
|
+
await getThreadCore(runtimeRef.current!).append(userMessage("first"));
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
act(() => {
|
|
113
|
+
suspend();
|
|
114
|
+
startTransition(() =>
|
|
115
|
+
view.rerender(
|
|
116
|
+
<Suspense fallback={null}>
|
|
117
|
+
<App onNew={onNewB} />
|
|
118
|
+
</Suspense>,
|
|
119
|
+
),
|
|
120
|
+
);
|
|
121
|
+
});
|
|
122
|
+
expect(renderB).toHaveBeenCalled();
|
|
123
|
+
|
|
124
|
+
await act(async () => {
|
|
125
|
+
await runtimeRef.current!.threads.switchToNewThread();
|
|
126
|
+
await getThreadCore(runtimeRef.current!).append(userMessage("second"));
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
expect(onNewA).toHaveBeenCalledTimes(2);
|
|
130
|
+
expect(onNewB).not.toHaveBeenCalled();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("publishes runtime hook changes after a committed render", async () => {
|
|
134
|
+
const { App, onNewA, onNewB, runtimeRef } = createHarness();
|
|
135
|
+
const view = render(<App onNew={onNewA} />);
|
|
136
|
+
|
|
137
|
+
await act(async () => {
|
|
138
|
+
await getThreadCore(runtimeRef.current!).append(userMessage("first"));
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
view.rerender(<App onNew={onNewB} />);
|
|
142
|
+
await act(async () => {
|
|
143
|
+
await getThreadCore(runtimeRef.current!).append(userMessage("second"));
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
expect(onNewA).toHaveBeenCalledTimes(1);
|
|
147
|
+
expect(onNewB).toHaveBeenCalledTimes(1);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("costs two passes per provider commit in the documented shape", async () => {
|
|
151
|
+
// Fresh children on every render, as the AssistantRuntimeProvider JSDoc
|
|
152
|
+
// example does, so its memo does not block: the host renders once against
|
|
153
|
+
// the previously committed hook, then the publish adds the corrective pass.
|
|
154
|
+
const { App, onNewA, renderThreadRuntime } = createHarness();
|
|
155
|
+
const view = render(<App onNew={onNewA} />);
|
|
156
|
+
|
|
157
|
+
await act(async () => {});
|
|
158
|
+
renderThreadRuntime.mockClear();
|
|
159
|
+
|
|
160
|
+
await act(async () => {
|
|
161
|
+
view.rerender(<App onNew={onNewA} />);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
expect(renderThreadRuntime).toHaveBeenCalledTimes(2);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("costs one pass when the provider memo blocks the host render", async () => {
|
|
168
|
+
const { App, onNewA, renderThreadRuntime } = createHarness();
|
|
169
|
+
const children = <div />;
|
|
170
|
+
const view = render(<App onNew={onNewA}>{children}</App>);
|
|
171
|
+
|
|
172
|
+
await act(async () => {});
|
|
173
|
+
renderThreadRuntime.mockClear();
|
|
174
|
+
|
|
175
|
+
await act(async () => {
|
|
176
|
+
view.rerender(<App onNew={onNewA}>{children}</App>);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
expect(renderThreadRuntime).toHaveBeenCalledTimes(1);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("does not re-run thread runtimes when the published hook is unchanged", async () => {
|
|
183
|
+
const { App, onNewA, renderThreadRuntime } = createHarness({
|
|
184
|
+
stableHook: true,
|
|
185
|
+
});
|
|
186
|
+
const children = <div />;
|
|
187
|
+
const view = render(<App onNew={onNewA}>{children}</App>);
|
|
188
|
+
|
|
189
|
+
await act(async () => {});
|
|
190
|
+
renderThreadRuntime.mockClear();
|
|
191
|
+
|
|
192
|
+
await act(async () => {
|
|
193
|
+
view.rerender(<App onNew={onNewA}>{children}</App>);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
expect(renderThreadRuntime).not.toHaveBeenCalled();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it("gives a thread created after an options change the committed hook", async () => {
|
|
200
|
+
const { App, onNewA, onNewB, runtimeRef } = createHarness();
|
|
201
|
+
const view = render(<App onNew={onNewA} />);
|
|
202
|
+
await act(async () => {});
|
|
203
|
+
|
|
204
|
+
await act(async () => {
|
|
205
|
+
view.rerender(<App onNew={onNewB} />);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
await act(async () => {
|
|
209
|
+
await runtimeRef.current!.threads.switchToNewThread();
|
|
210
|
+
await getThreadCore(runtimeRef.current!).append(userMessage("first"));
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
expect(onNewB).toHaveBeenCalledTimes(1);
|
|
214
|
+
expect(onNewA).not.toHaveBeenCalled();
|
|
215
|
+
});
|
|
216
|
+
});
|
|
@@ -12,6 +12,8 @@ import type { RemoteThreadListOptions } from "../../runtimes/remote-thread-list/
|
|
|
12
12
|
import type { AssistantRuntimeCore } from "../../runtime/interfaces/assistant-runtime-core";
|
|
13
13
|
import type { AssistantRuntime } from "../../runtime/api/assistant-runtime";
|
|
14
14
|
import { RemoteThreadListThreadListRuntimeCore } from "./RemoteThreadListThreadListRuntimeCore";
|
|
15
|
+
import { WritableSubscribable } from "../../subscribable/subscribable";
|
|
16
|
+
import { useSubscribable } from "../../store/runtime-clients/useSubscribable";
|
|
15
17
|
import { useAui } from "@assistant-ui/store";
|
|
16
18
|
|
|
17
19
|
class RemoteThreadListRuntimeCore
|
|
@@ -48,14 +50,30 @@ const useRemoteThreadListRuntimeImpl = (
|
|
|
48
50
|
export const useRemoteThreadListRuntime = (
|
|
49
51
|
options: RemoteThreadListOptions,
|
|
50
52
|
): AssistantRuntime => {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
+
const [runtimeHookStore] = useState(
|
|
54
|
+
() => new WritableSubscribable(options.runtimeHook),
|
|
55
|
+
);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
runtimeHookStore.setState(options.runtimeHook);
|
|
58
|
+
}, [runtimeHookStore, options.runtimeHook]);
|
|
53
59
|
|
|
54
60
|
const initialThreadIdRef = useRef(options.initialThreadId);
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
// Thread resources subscribe to the store rather than reading a ref, so a
|
|
63
|
+
// hook published at commit reaches exactly the resources that use it and an
|
|
64
|
+
// abandoned render publishes nothing. The store pins its server snapshot to
|
|
65
|
+
// the constructor value for hydration, which tap reads on any never-mounted
|
|
66
|
+
// fiber, so the live state serves as the server snapshot here.
|
|
67
|
+
const stableRuntimeHook = useCallback(
|
|
68
|
+
function useCommittedRuntimeHook() {
|
|
69
|
+
return useSubscribable({
|
|
70
|
+
subscribe: runtimeHookStore.subscribe,
|
|
71
|
+
getState: runtimeHookStore.getState,
|
|
72
|
+
getServerSnapshot: runtimeHookStore.getState,
|
|
73
|
+
})();
|
|
74
|
+
},
|
|
75
|
+
[runtimeHookStore],
|
|
76
|
+
);
|
|
59
77
|
|
|
60
78
|
const onThreadIdChange = useEffectEvent((threadId: string | undefined) => {
|
|
61
79
|
options.onThreadIdChange?.(threadId);
|
|
@@ -91,7 +109,7 @@ export const useRemoteThreadListRuntime = (
|
|
|
91
109
|
|
|
92
110
|
// If allowNesting is true and already inside a thread list context,
|
|
93
111
|
// just call the runtimeHook directly (no-op behavior)
|
|
94
|
-
return
|
|
112
|
+
return options.runtimeHook();
|
|
95
113
|
}
|
|
96
114
|
|
|
97
115
|
const runtime = useRemoteThreadListRuntimeImpl(stableOptions);
|
|
@@ -83,10 +83,14 @@ export type ToolCallMessagePartProps<
|
|
|
83
83
|
/**
|
|
84
84
|
* Responds to a server-side tool approval gate. Only valid while
|
|
85
85
|
* `approval` is set on the part, `approval.approved === undefined`, and
|
|
86
|
-
* no `approval.resolution` is recorded. Accepts a boolean decision
|
|
87
|
-
* id of one of `approval.options
|
|
86
|
+
* no `approval.resolution` is recorded. Accepts a boolean decision, the
|
|
87
|
+
* id of one of `approval.options` (option kinds resolve to the boolean),
|
|
88
|
+
* or a free-form answer when the request accepts one.
|
|
89
|
+
*
|
|
90
|
+
* Resolves once the runtime has accepted the response, and rejects when
|
|
91
|
+
* it could not be recorded, so the controls can stay retryable.
|
|
88
92
|
*/
|
|
89
|
-
respondToApproval: (response: ToolApprovalResponse) => void
|
|
93
|
+
respondToApproval: (response: ToolApprovalResponse) => Promise<void>;
|
|
90
94
|
};
|
|
91
95
|
|
|
92
96
|
/** Component used to render a tool-call message part. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ToolCallMessagePartComponent } from "../MessagePartComponentTypes";
|
|
2
2
|
import type { Unsubscribe } from "../../..";
|
|
3
|
+
import type { ToolCallText } from "../../../model-context/tool-call-text";
|
|
3
4
|
|
|
4
5
|
export type McpAppResourceOutput = {
|
|
5
6
|
readonly render: ToolCallMessagePartComponent;
|
|
@@ -12,6 +13,7 @@ export type McpAppResourceOutput = {
|
|
|
12
13
|
*/
|
|
13
14
|
type ToolRegistration = {
|
|
14
15
|
readonly render: ToolCallMessagePartComponent;
|
|
16
|
+
readonly renderText?: ToolCallText<any, any, unknown> | undefined;
|
|
15
17
|
/** Whether this UI renders standalone, outside the chain-of-thought trace. */
|
|
16
18
|
readonly standalone: boolean;
|
|
17
19
|
};
|
|
@@ -3,7 +3,7 @@ import type { MessageRole } from "../../types/message";
|
|
|
3
3
|
import type { QuoteInfo } from "../../types/quote";
|
|
4
4
|
import type { Unsubscribe } from "../../types/unsubscribe";
|
|
5
5
|
import type { RunConfig } from "../../types/message";
|
|
6
|
-
import type { QueueItemState } from "
|
|
6
|
+
import type { QueueItemState } from "../queue/queue-item";
|
|
7
7
|
import type { QueuePlacement } from "../queue/external-thread-queue-adapter";
|
|
8
8
|
import {
|
|
9
9
|
LazyMemoizeSubject,
|
|
@@ -28,7 +28,7 @@ type MessagePartSnapshotBinding = SubscribableWithState<
|
|
|
28
28
|
export type MessagePartRuntime = {
|
|
29
29
|
addToolResult(result: any | ToolResponse<any>): void;
|
|
30
30
|
resumeToolCall(payload: unknown): void;
|
|
31
|
-
respondToToolApproval(response: ToolApprovalResponse): void
|
|
31
|
+
respondToToolApproval(response: ToolApprovalResponse): Promise<void>;
|
|
32
32
|
|
|
33
33
|
readonly path: MessagePartRuntimePath;
|
|
34
34
|
getState(): MessagePartState;
|
|
@@ -113,7 +113,7 @@ export class MessagePartRuntimeImpl implements MessagePartRuntime {
|
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
public respondToToolApproval(response: ToolApprovalResponse) {
|
|
116
|
+
public respondToToolApproval(response: ToolApprovalResponse): Promise<void> {
|
|
117
117
|
const state = this.contentBinding.getState();
|
|
118
118
|
if (!state) throw new Error("Message part is not available");
|
|
119
119
|
|
|
@@ -131,7 +131,7 @@ export class MessagePartRuntimeImpl implements MessagePartRuntime {
|
|
|
131
131
|
|
|
132
132
|
if (!this.threadApi) throw new Error("Thread API is not available");
|
|
133
133
|
|
|
134
|
-
this.threadApi
|
|
134
|
+
return this.threadApi
|
|
135
135
|
.getState()
|
|
136
136
|
.respondToToolApproval(
|
|
137
137
|
resolveToolApprovalResponse(state.approval, response),
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import type { CompleteAttachment } from "../../types/attachment";
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
ThreadAssistantMessage,
|
|
5
|
+
ToolCallMessagePartStatus,
|
|
6
|
+
} from "../../types/message";
|
|
4
7
|
import type { ThreadRuntimeCoreBinding } from "./thread-runtime";
|
|
5
8
|
import {
|
|
6
9
|
MessageRuntimeImpl,
|
|
@@ -173,6 +176,30 @@ describe("toMessagePartStatus", () => {
|
|
|
173
176
|
});
|
|
174
177
|
});
|
|
175
178
|
|
|
179
|
+
it("preserves incomplete tool-call status on unresolved tool calls", () => {
|
|
180
|
+
const incompleteStatus = {
|
|
181
|
+
type: "incomplete",
|
|
182
|
+
reason: "tool-calls",
|
|
183
|
+
error: { message: "Tool execution did not finish" },
|
|
184
|
+
} satisfies ToolCallMessagePartStatus;
|
|
185
|
+
const message = createAssistantMessage(
|
|
186
|
+
[
|
|
187
|
+
{
|
|
188
|
+
type: "tool-call",
|
|
189
|
+
toolCallId: "call-1",
|
|
190
|
+
toolName: "weather",
|
|
191
|
+
args: {},
|
|
192
|
+
argsText: "{}",
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
incompleteStatus,
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
expect(toMessagePartStatus(message, 0, message.content[0]!)).toEqual(
|
|
199
|
+
incompleteStatus,
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
|
|
176
203
|
it.each([
|
|
177
204
|
["false", false],
|
|
178
205
|
["zero", 0],
|
|
@@ -7,7 +7,10 @@ import {
|
|
|
7
7
|
SKIP_UPDATE,
|
|
8
8
|
ShallowMemoizeSubject,
|
|
9
9
|
} from "../../subscribable/subscribable";
|
|
10
|
-
import type {
|
|
10
|
+
import type {
|
|
11
|
+
ThreadListRuntimeCore,
|
|
12
|
+
ThreadListRuntimeEvent,
|
|
13
|
+
} from "../interfaces/thread-list-runtime-core";
|
|
11
14
|
import {
|
|
12
15
|
type ThreadListItemRuntime,
|
|
13
16
|
ThreadListItemRuntimeImpl,
|
|
@@ -21,6 +24,7 @@ import {
|
|
|
21
24
|
} from "./thread-runtime";
|
|
22
25
|
|
|
23
26
|
const RESOLVED_PROMISE = Promise.resolve();
|
|
27
|
+
const NOOP_UNSUBSCRIBE = () => {};
|
|
24
28
|
|
|
25
29
|
export type ThreadListState = {
|
|
26
30
|
readonly mainThreadId: string;
|
|
@@ -57,6 +61,16 @@ export type ThreadListRuntime = {
|
|
|
57
61
|
): Promise<void>;
|
|
58
62
|
switchToNewThread(): Promise<void>;
|
|
59
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Observes lifecycle events on every thread this list keeps alive, so an
|
|
66
|
+
* event that fires while its thread is not selected stays observable. Thread
|
|
67
|
+
* lists that mount only the main thread never emit; their main thread's
|
|
68
|
+
* runtime is observed directly.
|
|
69
|
+
*/
|
|
70
|
+
unstable_subscribeThreadEvents(
|
|
71
|
+
callback: (event: ThreadListRuntimeEvent) => void,
|
|
72
|
+
): Unsubscribe;
|
|
73
|
+
|
|
60
74
|
getLoadThreadsPromise(): Promise<void>;
|
|
61
75
|
reload(): Promise<void>;
|
|
62
76
|
/**
|
|
@@ -171,6 +185,8 @@ export class ThreadListRuntimeImpl implements ThreadListRuntime {
|
|
|
171
185
|
protected __internal_bindMethods() {
|
|
172
186
|
this.switchToThread = this.switchToThread.bind(this);
|
|
173
187
|
this.switchToNewThread = this.switchToNewThread.bind(this);
|
|
188
|
+
this.unstable_subscribeThreadEvents =
|
|
189
|
+
this.unstable_subscribeThreadEvents.bind(this);
|
|
174
190
|
this.getLoadThreadsPromise = this.getLoadThreadsPromise.bind(this);
|
|
175
191
|
this.reload = this.reload.bind(this);
|
|
176
192
|
this.reloadMainThread = this.reloadMainThread.bind(this);
|
|
@@ -194,6 +210,14 @@ export class ThreadListRuntimeImpl implements ThreadListRuntime {
|
|
|
194
210
|
return this._core.switchToNewThread();
|
|
195
211
|
}
|
|
196
212
|
|
|
213
|
+
public unstable_subscribeThreadEvents(
|
|
214
|
+
callback: (event: ThreadListRuntimeEvent) => void,
|
|
215
|
+
): Unsubscribe {
|
|
216
|
+
return (
|
|
217
|
+
this._core.unstable_subscribeThreadEvents?.(callback) ?? NOOP_UNSUBSCRIBE
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
197
221
|
public getLoadThreadsPromise(): Promise<void> {
|
|
198
222
|
return this._core.getLoadThreadsPromise();
|
|
199
223
|
}
|
|
@@ -26,21 +26,17 @@ import type {
|
|
|
26
26
|
} from "../interfaces/composer-runtime-core";
|
|
27
27
|
import type { DictationAdapter } from "../../adapters/speech";
|
|
28
28
|
import type { QueuePlacement } from "../queue/external-thread-queue-adapter";
|
|
29
|
-
import {
|
|
30
|
-
EMPTY_QUEUE_ITEMS,
|
|
31
|
-
type QueueItemState,
|
|
32
|
-
} from "../../store/scopes/queue-item";
|
|
29
|
+
import { EMPTY_QUEUE_ITEMS, type QueueItemState } from "../queue/queue-item";
|
|
33
30
|
import { generateId } from "../../utils/id";
|
|
34
31
|
import { notifyEventListeners } from "../../utils/notify-event-listeners";
|
|
32
|
+
import {
|
|
33
|
+
AttachmentAddOperations,
|
|
34
|
+
drainAttachmentAdd,
|
|
35
|
+
} from "../utils/attachment-add-operations";
|
|
35
36
|
|
|
36
37
|
const isAttachmentComplete = (a: Attachment): a is CompleteAttachment =>
|
|
37
38
|
a.status.type === "complete";
|
|
38
39
|
|
|
39
|
-
type AttachmentAddOperation = {
|
|
40
|
-
cancelled: boolean;
|
|
41
|
-
attachmentIds: Set<string>;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
40
|
export abstract class BaseComposerRuntimeCore
|
|
45
41
|
extends BaseSubscribable
|
|
46
42
|
implements ComposerRuntimeCore
|
|
@@ -152,21 +148,14 @@ export abstract class BaseComposerRuntimeCore
|
|
|
152
148
|
protected _isSending = false;
|
|
153
149
|
private _removedDuringSend = new Set<string>();
|
|
154
150
|
private _sendGeneration = 0;
|
|
155
|
-
private _attachmentAddOperations = new
|
|
151
|
+
private _attachmentAddOperations = new AttachmentAddOperations();
|
|
156
152
|
|
|
157
153
|
private _cancelAttachmentAdd(attachmentId: string) {
|
|
158
|
-
|
|
159
|
-
if (!operation.attachmentIds.has(attachmentId)) continue;
|
|
160
|
-
operation.cancelled = true;
|
|
161
|
-
this._attachmentAddOperations.delete(operation);
|
|
162
|
-
}
|
|
154
|
+
this._attachmentAddOperations.cancel(attachmentId);
|
|
163
155
|
}
|
|
164
156
|
|
|
165
157
|
private _cancelAllAttachmentAdds() {
|
|
166
|
-
|
|
167
|
-
operation.cancelled = true;
|
|
168
|
-
}
|
|
169
|
-
this._attachmentAddOperations.clear();
|
|
158
|
+
this._attachmentAddOperations.cancelAll();
|
|
170
159
|
}
|
|
171
160
|
|
|
172
161
|
private _emptyTextAndAttachments() {
|
|
@@ -466,16 +455,10 @@ export abstract class BaseComposerRuntimeCore
|
|
|
466
455
|
throw err;
|
|
467
456
|
}
|
|
468
457
|
|
|
469
|
-
const operation
|
|
470
|
-
cancelled: false,
|
|
471
|
-
attachmentIds: new Set(),
|
|
472
|
-
};
|
|
473
|
-
const operations = this._attachmentAddOperations;
|
|
474
|
-
operations.add(operation);
|
|
458
|
+
const operation = this._attachmentAddOperations.start();
|
|
475
459
|
const upsertAttachment = (a: PendingAttachment) => {
|
|
476
|
-
if (operation.
|
|
460
|
+
if (!this._attachmentAddOperations.accept(operation, a.id)) return false;
|
|
477
461
|
|
|
478
|
-
operation.attachmentIds.add(a.id);
|
|
479
462
|
const idx = this._attachments.findIndex(
|
|
480
463
|
(attachment) => attachment.id === a.id,
|
|
481
464
|
);
|
|
@@ -494,18 +477,15 @@ export abstract class BaseComposerRuntimeCore
|
|
|
494
477
|
};
|
|
495
478
|
let lastAttachment: PendingAttachment | undefined;
|
|
496
479
|
try {
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
lastAttachment =
|
|
501
|
-
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
lastAttachment = await promiseOrGenerator;
|
|
505
|
-
upsertAttachment(lastAttachment);
|
|
506
|
-
}
|
|
480
|
+
await drainAttachmentAdd(
|
|
481
|
+
adapter.add({ file: fileOrAttachment }),
|
|
482
|
+
(attachment) => {
|
|
483
|
+
lastAttachment = attachment;
|
|
484
|
+
return upsertAttachment(attachment);
|
|
485
|
+
},
|
|
486
|
+
);
|
|
507
487
|
} catch (e) {
|
|
508
|
-
if (operation
|
|
488
|
+
if (this._attachmentAddOperations.isCancelled(operation)) return;
|
|
509
489
|
if (lastAttachment) {
|
|
510
490
|
upsertAttachment({
|
|
511
491
|
...lastAttachment,
|
|
@@ -524,10 +504,10 @@ export abstract class BaseComposerRuntimeCore
|
|
|
524
504
|
);
|
|
525
505
|
throw e;
|
|
526
506
|
} finally {
|
|
527
|
-
|
|
507
|
+
this._attachmentAddOperations.finish(operation);
|
|
528
508
|
}
|
|
529
509
|
|
|
530
|
-
if (operation
|
|
510
|
+
if (this._attachmentAddOperations.isCancelled(operation)) return;
|
|
531
511
|
if (
|
|
532
512
|
lastAttachment?.status.type === "incomplete" &&
|
|
533
513
|
lastAttachment.status.reason === "error"
|