@assistant-ui/core 0.3.17 → 0.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/attachment.d.ts.map +1 -1
- package/dist/adapters/attachment.js +5 -4
- package/dist/adapters/attachment.js.map +1 -1
- package/dist/adapters/speech.d.ts.map +1 -1
- package/dist/adapters/speech.js +13 -3
- package/dist/adapters/speech.js.map +1 -1
- package/dist/adapters/thread-history.d.ts +4 -0
- package/dist/adapters/thread-history.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +4 -3
- package/dist/internal.js +3 -2
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js +35 -14
- package/dist/model-context/frame/host.js.map +1 -1
- package/dist/model-context/frame/provider.d.ts +2 -0
- package/dist/model-context/frame/provider.d.ts.map +1 -1
- package/dist/model-context/frame/provider.js +30 -7
- package/dist/model-context/frame/provider.js.map +1 -1
- package/dist/model-context/interactable-composer-metadata.d.ts.map +1 -1
- package/dist/model-context/interactable-composer-metadata.js +27 -18
- package/dist/model-context/interactable-composer-metadata.js.map +1 -1
- package/dist/model-context/registry.d.ts.map +1 -1
- package/dist/model-context/registry.js +3 -5
- package/dist/model-context/registry.js.map +1 -1
- package/dist/model-context/types.d.ts.map +1 -1
- package/dist/model-context/types.js +5 -4
- package/dist/model-context/types.js.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.js +45 -7
- package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
- package/dist/react/client/DataRenderers.d.ts.map +1 -1
- package/dist/react/client/DataRenderers.js +20 -15
- package/dist/react/client/DataRenderers.js.map +1 -1
- package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
- package/dist/react/client/InMemoryThreadList.js +62 -56
- 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 +35 -32
- package/dist/react/client/Interactables.js.map +1 -1
- package/dist/react/client/RemoteThreadList.d.ts +1 -0
- package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
- package/dist/react/client/RemoteThreadList.js +154 -143
- 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 +18 -16
- package/dist/react/client/Tools.js.map +1 -1
- package/dist/react/client/interactable-model-context.d.ts.map +1 -1
- package/dist/react/client/interactable-model-context.js +3 -2
- package/dist/react/client/interactable-model-context.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +2 -2
- package/dist/react/interactables-legacy/Interactables.js +242 -121
- package/dist/react/interactables-legacy/Interactables.js.map +1 -1
- package/dist/react/interactables-legacy/useAssistantInteractable.d.ts.map +1 -1
- package/dist/react/interactables-legacy/useAssistantInteractable.js +3 -0
- package/dist/react/interactables-legacy/useAssistantInteractable.js.map +1 -1
- package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -1
- package/dist/react/interactables-shared/useInteractablePersistenceQueue.js +11 -9
- package/dist/react/interactables-shared/useInteractablePersistenceQueue.js.map +1 -1
- package/dist/react/model-context/makeAssistantTool.d.ts +2 -2
- package/dist/react/model-context/makeAssistantTool.js +1 -1
- package/dist/react/model-context/makeAssistantTool.js.map +1 -1
- package/dist/react/model-context/useAssistantTool.d.ts +2 -2
- package/dist/react/model-context/useAssistantTool.js +1 -1
- package/dist/react/model-context/useAssistantTool.js.map +1 -1
- package/dist/react/model-context/useInteractable.d.ts.map +1 -1
- package/dist/react/model-context/useInteractable.js +4 -1
- package/dist/react/model-context/useInteractable.js.map +1 -1
- package/dist/react/model-context/useInteractableVersions.js +1 -1
- package/dist/react/model-context/useToolArgsStatus.d.ts.map +1 -1
- package/dist/react/model-context/useToolArgsStatus.js +2 -1
- package/dist/react/model-context/useToolArgsStatus.js.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.d.ts +11 -2
- package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.js +3 -2
- package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
- package/dist/react/primitives/part/PartMessages.d.ts +1 -0
- package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
- package/dist/react/primitives/part/PartMessages.js +1 -0
- package/dist/react/primitives/part/PartMessages.js.map +1 -1
- package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
- package/dist/react/primitives/thread/ThreadMessages.js +6 -5
- package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +16 -8
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +5 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +105 -104
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadResource.d.ts +1 -0
- package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadResource.js +13 -11
- package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +5 -24
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +354 -226
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +1 -0
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +22 -2
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.d.ts +40 -15
- package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.js +62 -15
- package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +2 -1
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js +6 -1
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/sdkIdentity.d.ts +6 -0
- package/dist/react/runtimes/cloud/sdkIdentity.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/sdkIdentity.js +9 -0
- package/dist/react/runtimes/cloud/sdkIdentity.js.map +1 -0
- package/dist/react/runtimes/external-message-converter.d.ts +12 -2
- package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.js +26 -61
- package/dist/react/runtimes/external-message-converter.js.map +1 -1
- package/dist/react/runtimes/useExternalStoreRuntime.js +75 -46
- package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
- package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
- package/dist/react/runtimes/useRemoteThreadListRuntime.js +64 -24
- package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
- package/dist/react/utils/groupParts.d.ts +6 -1
- package/dist/react/utils/groupParts.d.ts.map +1 -1
- package/dist/react/utils/groupParts.js +6 -0
- package/dist/react/utils/groupParts.js.map +1 -1
- package/dist/react/utils/useJSONEqual.d.ts +3 -1
- package/dist/react/utils/useJSONEqual.d.ts.map +1 -1
- package/dist/react/utils/useJSONEqual.js +6 -1
- package/dist/react/utils/useJSONEqual.js.map +1 -1
- package/dist/react/utils/useJSONSchemaDependency.d.ts +7 -0
- package/dist/react/utils/useJSONSchemaDependency.d.ts.map +1 -0
- package/dist/react/utils/useJSONSchemaDependency.js +20 -0
- package/dist/react/utils/useJSONSchemaDependency.js.map +1 -0
- package/dist/runtime/api/thread-list-item-runtime.d.ts +7 -3
- package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-item-runtime.js +2 -2
- package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
- package/dist/runtime/api/thread-list-runtime.d.ts +3 -0
- package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-runtime.js +18 -14
- package/dist/runtime/api/thread-list-runtime.js.map +1 -1
- package/dist/runtime/api/thread-runtime.d.ts +4 -0
- package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-runtime.js +3 -6
- package/dist/runtime/api/thread-runtime.js.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -0
- package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.js +62 -22
- package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -0
- package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.js +161 -69
- package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
- package/dist/runtime/interfaces/composer-runtime-core.d.ts +12 -5
- package/dist/runtime/interfaces/composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +4 -1
- package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtime/interfaces/thread-runtime-core.d.ts +6 -0
- package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/queue/message-queue.d.ts +5 -0
- package/dist/runtime/queue/message-queue.d.ts.map +1 -1
- package/dist/runtime/queue/message-queue.js +61 -6
- package/dist/runtime/queue/message-queue.js.map +1 -1
- package/dist/runtime/utils/auto-status.d.ts +6 -2
- package/dist/runtime/utils/auto-status.d.ts.map +1 -1
- package/dist/runtime/utils/auto-status.js +12 -4
- package/dist/runtime/utils/auto-status.js.map +1 -1
- package/dist/runtime/utils/external-message-conversion.d.ts +16 -4
- package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -1
- package/dist/runtime/utils/external-message-conversion.js +49 -13
- package/dist/runtime/utils/external-message-conversion.js.map +1 -1
- package/dist/runtime/utils/message-repository.d.ts +1 -0
- package/dist/runtime/utils/message-repository.d.ts.map +1 -1
- package/dist/runtime/utils/message-repository.js +18 -9
- package/dist/runtime/utils/message-repository.js.map +1 -1
- package/dist/runtime/utils/thread-message-like.d.ts +2 -1
- package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
- package/dist/runtime/utils/thread-message-like.js +5 -3
- package/dist/runtime/utils/thread-message-like.js.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +21 -27
- 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.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js +8 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/internal.d.ts +3 -3
- package/dist/runtimes/internal.js +2 -2
- package/dist/runtimes/local/local-thread-runtime-core.d.ts +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +4 -1
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +18 -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 +130 -42
- package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
- package/dist/runtimes/remote-thread-list/title-generation.d.ts +49 -0
- package/dist/runtimes/remote-thread-list/title-generation.d.ts.map +1 -0
- package/dist/runtimes/remote-thread-list/title-generation.js +197 -0
- package/dist/runtimes/remote-thread-list/title-generation.js.map +1 -0
- package/dist/runtimes/remote-thread-list/title.d.ts +3 -1
- package/dist/runtimes/remote-thread-list/title.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/title.js +9 -1
- package/dist/runtimes/remote-thread-list/title.js.map +1 -1
- package/dist/runtimes/remote-thread-list/types.d.ts +10 -0
- package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
- package/dist/store/clients/external-thread.d.ts.map +1 -1
- package/dist/store/clients/external-thread.js +260 -203
- package/dist/store/clients/external-thread.js.map +1 -1
- package/dist/store/clients/model-context-client.d.ts.map +1 -1
- package/dist/store/clients/model-context-client.js +2 -1
- package/dist/store/clients/model-context-client.js.map +1 -1
- package/dist/store/clients/single-thread-list.d.ts.map +1 -1
- package/dist/store/clients/single-thread-list.js +1 -0
- 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 +5 -4
- package/dist/store/clients/suggestions.js.map +1 -1
- package/dist/store/clients/thread-tasks.d.ts +13 -0
- package/dist/store/clients/thread-tasks.d.ts.map +1 -0
- package/dist/store/clients/thread-tasks.js +69 -0
- package/dist/store/clients/thread-tasks.js.map +1 -0
- package/dist/store/index.d.ts +3 -2
- package/dist/store/index.js +3 -3
- package/dist/store/primitive-predicates.d.ts.map +1 -1
- package/dist/store/primitive-predicates.js +4 -4
- package/dist/store/primitive-predicates.js.map +1 -1
- package/dist/store/runtime-clients/composer-runtime-client.d.ts +1 -0
- package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/composer-runtime-client.js +97 -61
- package/dist/store/runtime-clients/composer-runtime-client.js.map +1 -1
- package/dist/store/runtime-clients/message-runtime-client.d.ts +1 -0
- package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/message-runtime-client.js +221 -144
- package/dist/store/runtime-clients/message-runtime-client.js.map +1 -1
- package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-list-item-runtime-client.js +1 -1
- package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
- package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-list-runtime-client.js +54 -52
- package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
- package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-runtime-client.js +246 -126
- package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
- package/dist/store/scope-registration.d.ts +2 -0
- package/dist/store/scope-registration.d.ts.map +1 -1
- package/dist/store/scopes/composer.d.ts +10 -2
- package/dist/store/scopes/composer.d.ts.map +1 -1
- package/dist/store/scopes/message.d.ts +30 -1
- package/dist/store/scopes/message.d.ts.map +1 -1
- package/dist/store/scopes/task.d.ts +36 -0
- package/dist/store/scopes/task.d.ts.map +1 -0
- package/dist/store/scopes/task.js +0 -0
- package/dist/store/scopes/thread-list-item.d.ts +2 -2
- package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
- package/dist/store/scopes/thread.d.ts +28 -0
- package/dist/store/scopes/thread.d.ts.map +1 -1
- package/dist/store/scopes/threads.d.ts +1 -0
- package/dist/store/scopes/threads.d.ts.map +1 -1
- package/dist/subscribable/subscribable.d.ts +2 -1
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/subscribable/subscribable.js +23 -15
- package/dist/subscribable/subscribable.js.map +1 -1
- package/dist/types/attachment.d.ts +2 -1
- package/dist/types/attachment.d.ts.map +1 -1
- package/dist/types/attachment.js +2 -1
- package/dist/types/attachment.js.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/message.d.ts +8 -1
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/message.js.map +1 -1
- package/dist/utils/abortable-iterable.d.ts +19 -0
- package/dist/utils/abortable-iterable.d.ts.map +1 -0
- package/dist/utils/abortable-iterable.js +88 -0
- package/dist/utils/abortable-iterable.js.map +1 -0
- package/dist/utils/composite-context-provider.d.ts.map +1 -1
- package/dist/utils/composite-context-provider.js +20 -2
- package/dist/utils/composite-context-provider.js.map +1 -1
- package/dist/utils/getGroupStatus.d.ts +18 -2
- package/dist/utils/getGroupStatus.d.ts.map +1 -1
- package/dist/utils/getGroupStatus.js +32 -7
- package/dist/utils/getGroupStatus.js.map +1 -1
- package/dist/utils/record.d.ts +11 -0
- package/dist/utils/record.d.ts.map +1 -0
- package/dist/utils/record.js +12 -0
- package/dist/utils/record.js.map +1 -0
- package/dist/utils/wire-media.d.ts.map +1 -1
- package/dist/utils/wire-media.js +2 -2
- package/dist/utils/wire-media.js.map +1 -1
- package/package.json +11 -11
- package/src/adapters/attachment.test.ts +50 -1
- package/src/adapters/attachment.ts +7 -4
- package/src/adapters/speech.test.ts +236 -0
- package/src/adapters/speech.ts +17 -10
- package/src/adapters/thread-history.ts +3 -0
- package/src/index.ts +2 -0
- package/src/internal.ts +4 -0
- package/src/model-context/frame/host.test.ts +137 -1
- package/src/model-context/frame/host.ts +49 -16
- package/src/model-context/frame/provider.test.ts +71 -0
- package/src/model-context/frame/provider.ts +37 -7
- package/src/model-context/interactable-composer-metadata.test.ts +58 -0
- package/src/model-context/interactable-composer-metadata.ts +19 -13
- package/src/model-context/registry.test.ts +12 -0
- package/src/model-context/registry.ts +3 -2
- package/src/model-context/types.test.ts +25 -0
- package/src/model-context/types.ts +9 -4
- package/src/react/RuntimeAdapter.test.ts +34 -0
- package/src/react/adapters/LocalStorageThreadListAdapter.test.ts +244 -0
- package/src/react/adapters/LocalStorageThreadListAdapter.tsx +104 -7
- package/src/react/client/DataRenderers.test.tsx +45 -0
- package/src/react/client/DataRenderers.ts +13 -9
- package/src/react/client/InMemoryThreadList.ts +1 -0
- package/src/react/client/Interactables.test.ts +72 -1
- package/src/react/client/Interactables.ts +22 -14
- package/src/react/client/RemoteThreadList.background.test.ts +148 -6
- package/src/react/client/RemoteThreadList.concurrent.test.tsx +42 -1
- package/src/react/client/RemoteThreadList.test.ts +386 -4
- package/src/react/client/RemoteThreadList.ts +181 -112
- package/src/react/client/Tools.ts +22 -11
- package/src/react/client/interactable-model-context.test.ts +44 -0
- package/src/react/client/interactable-model-context.ts +3 -2
- package/src/react/index.ts +5 -1
- package/src/react/interactables-legacy/Interactables.ts +16 -16
- package/src/react/interactables-legacy/useAssistantInteractable.test.tsx +132 -0
- package/src/react/interactables-legacy/useAssistantInteractable.ts +10 -1
- package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +9 -10
- package/src/react/model-context/makeAssistantTool.ts +2 -2
- package/src/react/model-context/useAssistantTool.ts +2 -2
- package/src/react/model-context/useInteractable.test.tsx +177 -0
- package/src/react/model-context/useInteractable.ts +3 -0
- package/src/react/model-context/useToolArgsStatus.test.tsx +30 -0
- package/src/react/model-context/useToolArgsStatus.ts +2 -1
- package/src/react/primitive-hooks/useActionBarCopy.test.ts +0 -1
- package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +0 -1
- package/src/react/primitives/message/MessageGroupedParts.test.tsx +96 -0
- package/src/react/primitives/message/MessageGroupedParts.tsx +15 -4
- package/src/react/primitives/part/PartMessages.test.tsx +104 -1
- package/src/react/primitives/part/PartMessages.tsx +1 -0
- package/src/react/primitives/thread/ThreadMessages.test.tsx +142 -0
- package/src/react/primitives/thread/ThreadMessages.tsx +8 -5
- package/src/react/providers/ReadonlyThreadProvider.test.tsx +56 -0
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.destroy.test.tsx +172 -0
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +33 -0
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +7 -1
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +28 -5
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.load-error.test.ts +132 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.switch-delete.test.ts +105 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +143 -112
- package/src/react/runtimes/RemoteThreadResource.test.ts +9 -0
- package/src/react/runtimes/RemoteThreadResource.ts +19 -12
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +20 -14
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +703 -6
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +492 -402
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.test.ts +77 -0
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +27 -1
- package/src/react/runtimes/cloud/auiV0.ts +160 -25
- package/src/react/runtimes/cloud/createCloudThreadListAdapter.test.ts +36 -0
- package/src/react/runtimes/cloud/createCloudThreadListAdapter.ts +8 -1
- package/src/react/runtimes/cloud/sdkIdentity.ts +9 -0
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +18 -4
- package/src/react/runtimes/external-message-converter.test.ts +136 -1
- package/src/react/runtimes/external-message-converter.ts +39 -93
- package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +41 -0
- package/src/react/runtimes/useExternalStoreRuntime.ts +10 -4
- package/src/react/runtimes/useLocalRuntime.test.tsx +20 -0
- package/src/react/runtimes/useRemoteThreadListRuntime.load-error.test.tsx +108 -0
- package/src/react/runtimes/useRemoteThreadListRuntime.ts +34 -1
- package/src/react/utils/groupParts.ts +12 -1
- package/src/react/utils/useJSONEqual.ts +9 -0
- package/src/react/utils/useJSONSchemaDependency.ts +22 -0
- package/src/runtime/api/message-runtime.test.ts +75 -0
- package/src/runtime/api/thread-list-item-runtime.ts +10 -3
- package/src/runtime/api/thread-list-runtime.ts +21 -11
- package/src/runtime/api/thread-runtime.test.ts +136 -0
- package/src/runtime/api/thread-runtime.ts +10 -5
- package/src/runtime/base/base-composer-runtime-core.ts +105 -24
- package/src/runtime/base/base-thread-runtime-core.test.ts +1063 -2
- package/src/runtime/base/base-thread-runtime-core.ts +228 -87
- package/src/runtime/interfaces/composer-runtime-core.ts +10 -5
- package/src/runtime/interfaces/thread-list-runtime-core.ts +5 -1
- package/src/runtime/interfaces/thread-runtime-core.ts +6 -0
- package/src/runtime/queue/message-queue.ts +68 -6
- package/src/runtime/utils/auto-status.test.ts +112 -1
- package/src/runtime/utils/auto-status.ts +31 -5
- package/src/runtime/utils/external-message-conversion.test.ts +202 -0
- package/src/runtime/utils/external-message-conversion.ts +123 -32
- package/src/runtime/utils/message-repository.test.ts +49 -0
- package/src/runtime/utils/message-repository.ts +32 -20
- package/src/runtime/utils/thread-message-like.test.ts +52 -0
- package/src/runtime/utils/thread-message-like.ts +5 -1
- package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +18 -13
- package/src/runtimes/external-store/external-store-thread-runtime-core.ts +31 -1
- package/src/runtimes/internal.ts +1 -0
- package/src/runtimes/local/local-thread-runtime-core.test.ts +21 -0
- package/src/runtimes/local/local-thread-runtime-core.ts +11 -1
- package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +128 -2
- package/src/runtimes/remote-thread-list/remote-thread-state.ts +182 -42
- package/src/runtimes/remote-thread-list/title-generation.test.ts +602 -0
- package/src/runtimes/remote-thread-list/title-generation.ts +329 -0
- package/src/runtimes/remote-thread-list/title.test.ts +62 -0
- package/src/runtimes/remote-thread-list/title.ts +13 -0
- package/src/runtimes/remote-thread-list/types.ts +10 -0
- package/src/runtimes/tool-invocations/EDGE_CASES.md +2 -6
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +133 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +10 -6
- package/src/store/clients/external-thread.ts +67 -4
- package/src/store/clients/model-context-client.ts +5 -1
- package/src/store/clients/single-thread-list.ts +1 -0
- package/src/store/clients/suggestions.test.ts +40 -0
- package/src/store/clients/suggestions.ts +13 -10
- package/src/store/clients/thread-tasks.test.ts +274 -0
- package/src/store/clients/thread-tasks.ts +138 -0
- package/src/store/index.ts +8 -0
- package/src/store/primitive-predicates.test.ts +48 -5
- package/src/store/primitive-predicates.ts +7 -2
- package/src/store/runtime-clients/composer-runtime-client.ts +42 -9
- package/src/store/runtime-clients/message-runtime-client.ts +54 -6
- package/src/store/runtime-clients/thread-list-item-runtime-client.ts +4 -2
- package/src/store/runtime-clients/thread-list-runtime-client.ts +1 -0
- package/src/store/runtime-clients/thread-runtime-client.ts +89 -11
- package/src/store/scope-registration.ts +2 -0
- package/src/store/scopes/composer.ts +16 -4
- package/src/store/scopes/message.ts +14 -0
- package/src/store/scopes/task.ts +34 -0
- package/src/store/scopes/thread-list-item.ts +5 -2
- package/src/store/scopes/thread.ts +20 -0
- package/src/store/scopes/threads.ts +1 -0
- package/src/store/thread-tasks.test.tsx +209 -0
- package/src/subscribable/subscribable.test.ts +156 -1
- package/src/subscribable/subscribable.ts +25 -15
- package/src/tests/MessageRepository.test.ts +117 -5
- package/src/tests/OptimisticState-list-race.test.ts +1 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-initialize-adapter-change.test.ts +38 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +47 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-title-race.test.ts +89 -0
- package/src/tests/attachment-adapters.test.ts +14 -0
- package/src/tests/auiV0Encode.test.ts +300 -0
- package/src/tests/base-composer-runtime-core-send.test.ts +51 -0
- package/src/tests/base-composer-runtime-core.test.ts +353 -2
- package/src/tests/external-store-thread-list-runtime-core.test.ts +83 -0
- package/src/tests/external-store-thread-runtime-core-adapter.test.ts +178 -18
- package/src/tests/external-thread-attachments.test.tsx +208 -0
- package/src/tests/external-thread-parity.test.tsx +57 -0
- package/src/tests/groupParts.test.ts +71 -0
- package/src/tests/message-queue.test.ts +253 -0
- package/src/tests/remote-thread-list-isLoading.test.ts +1 -0
- package/src/tests/remote-thread-list-reactive-threadId.test.ts +51 -0
- package/src/tests/thread-list-runtime-getLoadThreadsPromise.test.ts +1 -0
- package/src/tests/thread-switch-events.test.tsx +78 -0
- package/src/tests/tools-scope-migration.test.tsx +28 -0
- package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +43 -0
- package/src/types/attachment.ts +4 -0
- package/src/types/index.ts +1 -0
- package/src/types/message.ts +8 -0
- package/src/utils/abortable-iterable.test.ts +328 -0
- package/src/utils/abortable-iterable.ts +104 -0
- package/src/utils/composite-context-provider.test.ts +25 -0
- package/src/utils/composite-context-provider.ts +23 -2
- package/src/utils/getGroupStatus.test.ts +70 -4
- package/src/utils/getGroupStatus.ts +35 -12
- package/src/utils/record.test.ts +48 -0
- package/src/utils/record.ts +11 -0
- package/src/utils/wire-media.test.ts +10 -0
- package/src/utils/wire-media.ts +6 -2
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
type MessageStateBinding,
|
|
12
12
|
} from "./message-runtime";
|
|
13
13
|
import { toMessagePartStatus } from "../../utils/normalizePartStatus";
|
|
14
|
+
import { convertExternalMessageChunk } from "../utils/external-message-conversion";
|
|
14
15
|
|
|
15
16
|
const messagePath = {
|
|
16
17
|
ref: "threads.main.messages[0]",
|
|
@@ -256,6 +257,80 @@ describe("toMessagePartStatus", () => {
|
|
|
256
257
|
});
|
|
257
258
|
|
|
258
259
|
describe("MessageRuntimeImpl paths", () => {
|
|
260
|
+
it.each([undefined, ""])(
|
|
261
|
+
"looks up separate tool calls with ID %s without breaking provider result matching",
|
|
262
|
+
(toolCallId) => {
|
|
263
|
+
const id = toolCallId === undefined ? {} : { toolCallId };
|
|
264
|
+
const converted = convertExternalMessageChunk(
|
|
265
|
+
{
|
|
266
|
+
inputs: [{}],
|
|
267
|
+
outputs: [
|
|
268
|
+
{
|
|
269
|
+
role: "assistant",
|
|
270
|
+
content: [
|
|
271
|
+
{ type: "tool-call", ...id, toolName: "weather", args: {} },
|
|
272
|
+
{ type: "tool-call", ...id, toolName: "search", args: {} },
|
|
273
|
+
{
|
|
274
|
+
type: "tool-call",
|
|
275
|
+
toolCallId: "provider-call",
|
|
276
|
+
toolName: "calendar",
|
|
277
|
+
args: { day: "Monday" },
|
|
278
|
+
},
|
|
279
|
+
],
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
role: "assistant",
|
|
283
|
+
content: [
|
|
284
|
+
{
|
|
285
|
+
type: "tool-call",
|
|
286
|
+
toolCallId: "provider-call",
|
|
287
|
+
toolName: "calendar",
|
|
288
|
+
args: { day: "Tuesday" },
|
|
289
|
+
},
|
|
290
|
+
],
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
role: "tool",
|
|
294
|
+
toolCallId: "provider-call",
|
|
295
|
+
toolName: "calendar",
|
|
296
|
+
result: "Meeting at noon",
|
|
297
|
+
},
|
|
298
|
+
],
|
|
299
|
+
},
|
|
300
|
+
0,
|
|
301
|
+
1,
|
|
302
|
+
false,
|
|
303
|
+
undefined,
|
|
304
|
+
);
|
|
305
|
+
const runtime = new MessageRuntimeImpl(
|
|
306
|
+
{
|
|
307
|
+
...messageBinding,
|
|
308
|
+
getState: () => ({ ...message, ...converted }),
|
|
309
|
+
},
|
|
310
|
+
threadBinding,
|
|
311
|
+
);
|
|
312
|
+
const calls = converted.content.filter(
|
|
313
|
+
(part) => part.type === "tool-call",
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
expect(
|
|
317
|
+
calls.map((call) =>
|
|
318
|
+
runtime.getMessagePartByToolCallId(call.toolCallId).getState(),
|
|
319
|
+
),
|
|
320
|
+
).toMatchObject([
|
|
321
|
+
{ type: "tool-call", toolName: "weather" },
|
|
322
|
+
{ type: "tool-call", toolName: "search" },
|
|
323
|
+
{
|
|
324
|
+
type: "tool-call",
|
|
325
|
+
toolCallId: "provider-call",
|
|
326
|
+
toolName: "calendar",
|
|
327
|
+
args: { day: "Tuesday" },
|
|
328
|
+
result: "Meeting at noon",
|
|
329
|
+
},
|
|
330
|
+
]);
|
|
331
|
+
},
|
|
332
|
+
);
|
|
333
|
+
|
|
259
334
|
it("appends nested selectors to the message path", () => {
|
|
260
335
|
const runtime = new MessageRuntimeImpl(messageBinding, threadBinding);
|
|
261
336
|
|
|
@@ -30,12 +30,17 @@ import type { ThreadListItemStatus } from "../interfaces/thread-list-runtime-cor
|
|
|
30
30
|
|
|
31
31
|
export type { ThreadListItemState, ThreadListItemStatus };
|
|
32
32
|
|
|
33
|
+
export type ThreadListItemGenerateTitleOptions = {
|
|
34
|
+
/** Marks a generation started by the automatic title trigger. */
|
|
35
|
+
automatic?: boolean;
|
|
36
|
+
};
|
|
37
|
+
|
|
33
38
|
export type ThreadListItemRuntime = {
|
|
34
39
|
readonly path: ThreadListItemRuntimePath;
|
|
35
40
|
getState(): ThreadListItemState;
|
|
36
41
|
|
|
37
42
|
initialize(): Promise<{ remoteId: string; externalId: string | undefined }>;
|
|
38
|
-
generateTitle(): Promise<void>;
|
|
43
|
+
generateTitle(options?: ThreadListItemGenerateTitleOptions): Promise<void>;
|
|
39
44
|
|
|
40
45
|
switchTo(options?: { unarchive?: boolean }): Promise<void>;
|
|
41
46
|
rename(newTitle: string): Promise<void>;
|
|
@@ -147,9 +152,11 @@ export class ThreadListItemRuntimeImpl implements ThreadListItemRuntime {
|
|
|
147
152
|
return this._threadListBinding.initialize(state.id);
|
|
148
153
|
}
|
|
149
154
|
|
|
150
|
-
public generateTitle(
|
|
155
|
+
public generateTitle(
|
|
156
|
+
options?: ThreadListItemGenerateTitleOptions,
|
|
157
|
+
): Promise<void> {
|
|
151
158
|
const state = this._core.getState();
|
|
152
|
-
return this._threadListBinding.generateTitle(state.id);
|
|
159
|
+
return this._threadListBinding.generateTitle(state.id, options);
|
|
153
160
|
}
|
|
154
161
|
|
|
155
162
|
public unstable_on<E extends ThreadListItemEventType>(
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
type ThreadListItemRuntime,
|
|
16
16
|
ThreadListItemRuntimeImpl,
|
|
17
17
|
type ThreadListItemState,
|
|
18
|
+
type ThreadListItemStateBinding,
|
|
18
19
|
} from "./thread-list-item-runtime";
|
|
19
20
|
import {
|
|
20
21
|
type ThreadListItemRuntimeBinding,
|
|
@@ -32,6 +33,8 @@ export type ThreadListState = {
|
|
|
32
33
|
readonly threadIds: readonly string[];
|
|
33
34
|
readonly archivedThreadIds: readonly string[];
|
|
34
35
|
readonly isLoading: boolean;
|
|
36
|
+
/** The error thrown by the most recent thread list load that failed, cleared when a later load starts. */
|
|
37
|
+
readonly loadError: unknown;
|
|
35
38
|
readonly isLoadingMore: boolean;
|
|
36
39
|
readonly hasMore: boolean;
|
|
37
40
|
readonly threadItems: Readonly<
|
|
@@ -97,6 +100,7 @@ const getThreadListState = (
|
|
|
97
100
|
threadIds: threadList.threadIds,
|
|
98
101
|
archivedThreadIds: threadList.archivedThreadIds,
|
|
99
102
|
isLoading: threadList.isLoading,
|
|
103
|
+
loadError: threadList.loadError,
|
|
100
104
|
isLoadingMore: threadList.isLoadingMore ?? false,
|
|
101
105
|
hasMore: threadList.hasMore ?? false,
|
|
102
106
|
threadItems: threadList.threadItems,
|
|
@@ -250,6 +254,21 @@ export class ThreadListRuntimeImpl implements ThreadListRuntime {
|
|
|
250
254
|
return this._mainThreadListItemRuntime;
|
|
251
255
|
}
|
|
252
256
|
|
|
257
|
+
private _createItemStateBinding(
|
|
258
|
+
threadId: string,
|
|
259
|
+
): ThreadListItemStateBinding {
|
|
260
|
+
return new ShallowMemoizeSubject({
|
|
261
|
+
path: {
|
|
262
|
+
ref: `threadItems[threadId=${threadId}]`,
|
|
263
|
+
threadSelector: { type: "threadId", threadId },
|
|
264
|
+
},
|
|
265
|
+
getState: () => {
|
|
266
|
+
return getThreadListItemState(this._core, threadId);
|
|
267
|
+
},
|
|
268
|
+
subscribe: (callback) => this._core.subscribe(callback),
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
253
272
|
public getById(threadId: string) {
|
|
254
273
|
return new this._runtimeFactory(
|
|
255
274
|
new NestedSubscriptionSubject({
|
|
@@ -260,7 +279,7 @@ export class ThreadListRuntimeImpl implements ThreadListRuntime {
|
|
|
260
279
|
getState: () => this._core.getThreadRuntimeCore(threadId),
|
|
261
280
|
subscribe: (callback) => this._core.subscribe(callback),
|
|
262
281
|
}),
|
|
263
|
-
this.
|
|
282
|
+
this._createItemStateBinding(threadId),
|
|
264
283
|
);
|
|
265
284
|
}
|
|
266
285
|
|
|
@@ -301,16 +320,7 @@ export class ThreadListRuntimeImpl implements ThreadListRuntime {
|
|
|
301
320
|
|
|
302
321
|
public getItemById(threadId: string) {
|
|
303
322
|
return new ThreadListItemRuntimeImpl(
|
|
304
|
-
|
|
305
|
-
path: {
|
|
306
|
-
ref: `threadItems[threadId=${threadId}]`,
|
|
307
|
-
threadSelector: { type: "threadId", threadId },
|
|
308
|
-
},
|
|
309
|
-
getState: () => {
|
|
310
|
-
return getThreadListItemState(this._core, threadId);
|
|
311
|
-
},
|
|
312
|
-
subscribe: (callback) => this._core.subscribe(callback),
|
|
313
|
-
}),
|
|
323
|
+
this._createItemStateBinding(threadId),
|
|
314
324
|
this._core,
|
|
315
325
|
);
|
|
316
326
|
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { LocalRuntimeCore } from "../../runtimes/local/local-runtime-core";
|
|
3
|
+
import { ExternalStoreRuntimeCore } from "../../runtimes/external-store/external-store-runtime-core";
|
|
4
|
+
import { ReadonlyThreadRuntimeCore } from "../../runtimes/readonly/ReadonlyThreadRuntimeCore";
|
|
5
|
+
import { AssistantRuntimeImpl } from "./assistant-runtime";
|
|
6
|
+
import {
|
|
7
|
+
ThreadRuntimeImpl,
|
|
8
|
+
type ThreadListItemRuntimeBinding,
|
|
9
|
+
type ThreadRuntimeCoreBinding,
|
|
10
|
+
} from "./thread-runtime";
|
|
11
|
+
|
|
12
|
+
describe("ThreadRuntime.append", () => {
|
|
13
|
+
it.each([
|
|
14
|
+
{ parent: { parentId: null }, expectedParent: null, visible: ["new"] },
|
|
15
|
+
{
|
|
16
|
+
parent: {},
|
|
17
|
+
expectedParent: "tail",
|
|
18
|
+
visible: ["root", "tail", "new"],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
parent: { parentId: "root" },
|
|
22
|
+
expectedParent: "root",
|
|
23
|
+
visible: ["root", "new"],
|
|
24
|
+
},
|
|
25
|
+
])(
|
|
26
|
+
"selects the branch under $expectedParent",
|
|
27
|
+
({ parent, expectedParent, visible }) => {
|
|
28
|
+
const core = new LocalRuntimeCore(
|
|
29
|
+
{ adapters: { chatModel: { run: async () => ({ content: [] }) } } },
|
|
30
|
+
[
|
|
31
|
+
{ id: "root", role: "user", content: "root" },
|
|
32
|
+
{ id: "tail", role: "assistant", content: "tail" },
|
|
33
|
+
],
|
|
34
|
+
);
|
|
35
|
+
const thread = new AssistantRuntimeImpl(core).thread;
|
|
36
|
+
|
|
37
|
+
thread.append({
|
|
38
|
+
...parent,
|
|
39
|
+
content: [{ type: "text", text: "new" }],
|
|
40
|
+
startRun: false,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
expect(
|
|
44
|
+
thread.getState().messages.map((message) => message.content),
|
|
45
|
+
).toEqual(visible.map((text) => [{ type: "text", text }]));
|
|
46
|
+
expect(thread.export().messages.at(-1)?.parentId).toBe(expectedParent);
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe("ThreadRuntime.append with an external store", () => {
|
|
52
|
+
it("routes an explicit root parent to onEdit instead of onNew", async () => {
|
|
53
|
+
const onNew = vi.fn(async () => {});
|
|
54
|
+
const onEdit = vi.fn(async () => {});
|
|
55
|
+
const core = new ExternalStoreRuntimeCore({
|
|
56
|
+
messages: [
|
|
57
|
+
{
|
|
58
|
+
id: "old",
|
|
59
|
+
role: "user",
|
|
60
|
+
content: [{ type: "text", text: "old" }],
|
|
61
|
+
createdAt: new Date(0),
|
|
62
|
+
attachments: [],
|
|
63
|
+
metadata: { custom: {} },
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
onNew,
|
|
67
|
+
onEdit,
|
|
68
|
+
});
|
|
69
|
+
const thread = new AssistantRuntimeImpl(core).thread;
|
|
70
|
+
|
|
71
|
+
thread.append({
|
|
72
|
+
parentId: null,
|
|
73
|
+
content: [{ type: "text", text: "new root" }],
|
|
74
|
+
startRun: false,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
await vi.waitFor(() =>
|
|
78
|
+
expect(onEdit).toHaveBeenCalledExactlyOnceWith(
|
|
79
|
+
expect.objectContaining({ parentId: null }),
|
|
80
|
+
),
|
|
81
|
+
);
|
|
82
|
+
expect(onNew).not.toHaveBeenCalled();
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe("ThreadRuntime state subscriptions", () => {
|
|
87
|
+
it("tears down every source before reconnecting after an error", () => {
|
|
88
|
+
const core = new ReadonlyThreadRuntimeCore();
|
|
89
|
+
const cleanupError = new Error("thread cleanup failed");
|
|
90
|
+
const threadCleanup = vi.fn(() => {
|
|
91
|
+
throw cleanupError;
|
|
92
|
+
});
|
|
93
|
+
const itemCleanup = vi.fn();
|
|
94
|
+
let threadSubscriptions = 0;
|
|
95
|
+
let itemSubscriptions = 0;
|
|
96
|
+
const path = {
|
|
97
|
+
ref: "test.thread",
|
|
98
|
+
threadSelector: { type: "main" as const },
|
|
99
|
+
};
|
|
100
|
+
const runtime = new ThreadRuntimeImpl(
|
|
101
|
+
{
|
|
102
|
+
path,
|
|
103
|
+
getState: () => core,
|
|
104
|
+
subscribe: () => {
|
|
105
|
+
threadSubscriptions += 1;
|
|
106
|
+
return threadCleanup;
|
|
107
|
+
},
|
|
108
|
+
outerSubscribe: () => () => {},
|
|
109
|
+
} satisfies ThreadRuntimeCoreBinding,
|
|
110
|
+
{
|
|
111
|
+
path,
|
|
112
|
+
getState: () => ({
|
|
113
|
+
id: "test",
|
|
114
|
+
remoteId: undefined,
|
|
115
|
+
externalId: undefined,
|
|
116
|
+
isMain: true,
|
|
117
|
+
isRunning: false,
|
|
118
|
+
status: "regular",
|
|
119
|
+
title: undefined,
|
|
120
|
+
}),
|
|
121
|
+
subscribe: () => {
|
|
122
|
+
itemSubscriptions += 1;
|
|
123
|
+
return itemCleanup;
|
|
124
|
+
},
|
|
125
|
+
} satisfies ThreadListItemRuntimeBinding,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
const unsubscribe = runtime.subscribe(() => {});
|
|
129
|
+
expect(() => unsubscribe()).toThrow(cleanupError);
|
|
130
|
+
expect(itemCleanup).toHaveBeenCalledOnce();
|
|
131
|
+
|
|
132
|
+
runtime.subscribe(() => {});
|
|
133
|
+
expect(threadSubscriptions).toBe(2);
|
|
134
|
+
expect(itemSubscriptions).toBe(2);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
} from "./message-runtime";
|
|
19
19
|
import { NestedSubscriptionSubject } from "../../subscribable/subscribable";
|
|
20
20
|
import {
|
|
21
|
+
runCleanups,
|
|
21
22
|
ShallowMemoizeSubject,
|
|
22
23
|
SKIP_UPDATE,
|
|
23
24
|
} from "../../subscribable/subscribable";
|
|
@@ -77,6 +78,10 @@ const toStartRunConfig = (message: CreateStartRunConfig): StartRunConfig => {
|
|
|
77
78
|
export type CreateAppendMessage =
|
|
78
79
|
| string
|
|
79
80
|
| {
|
|
81
|
+
/**
|
|
82
|
+
* An omitted value or `undefined` selects the current tail.
|
|
83
|
+
* `null` selects a root branch.
|
|
84
|
+
*/
|
|
80
85
|
parentId?: string | null | undefined;
|
|
81
86
|
sourceId?: string | null | undefined;
|
|
82
87
|
role?: AppendMessage["role"] | undefined;
|
|
@@ -107,7 +112,10 @@ const toAppendMessage = (
|
|
|
107
112
|
|
|
108
113
|
return {
|
|
109
114
|
createdAt: message.createdAt ?? new Date(),
|
|
110
|
-
parentId:
|
|
115
|
+
parentId:
|
|
116
|
+
message.parentId === undefined
|
|
117
|
+
? (messages.at(-1)?.id ?? null)
|
|
118
|
+
: message.parentId,
|
|
111
119
|
sourceId: message.sourceId ?? null,
|
|
112
120
|
role: message.role ?? "user",
|
|
113
121
|
content: message.content,
|
|
@@ -365,10 +373,7 @@ export class ThreadRuntimeImpl implements ThreadRuntime {
|
|
|
365
373
|
subscribe: (callback) => {
|
|
366
374
|
const sub1 = threadBinding.subscribe(callback);
|
|
367
375
|
const sub2 = threadListItemBinding.subscribe(callback);
|
|
368
|
-
return () =>
|
|
369
|
-
sub1();
|
|
370
|
-
sub2();
|
|
371
|
-
};
|
|
376
|
+
return () => runCleanups([sub1, sub2]);
|
|
372
377
|
},
|
|
373
378
|
});
|
|
374
379
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
isAttachmentComplete,
|
|
2
3
|
isCreateAttachment,
|
|
3
4
|
type Attachment,
|
|
4
5
|
type CompleteAttachment,
|
|
@@ -34,9 +35,6 @@ import {
|
|
|
34
35
|
drainAttachmentAdd,
|
|
35
36
|
} from "../utils/attachment-add-operations";
|
|
36
37
|
|
|
37
|
-
const isAttachmentComplete = (a: Attachment): a is CompleteAttachment =>
|
|
38
|
-
a.status.type === "complete";
|
|
39
|
-
|
|
40
38
|
export abstract class BaseComposerRuntimeCore
|
|
41
39
|
extends BaseSubscribable
|
|
42
40
|
implements ComposerRuntimeCore
|
|
@@ -161,6 +159,7 @@ export abstract class BaseComposerRuntimeCore
|
|
|
161
159
|
private _emptyTextAndAttachments() {
|
|
162
160
|
this._attachments = [];
|
|
163
161
|
this._text = "";
|
|
162
|
+
this._rebaseDictation("");
|
|
164
163
|
this._notifySubscribers();
|
|
165
164
|
}
|
|
166
165
|
|
|
@@ -168,7 +167,7 @@ export abstract class BaseComposerRuntimeCore
|
|
|
168
167
|
const adapter = this.getAttachmentAdapter();
|
|
169
168
|
if (adapter) {
|
|
170
169
|
const pending = this._attachments.filter((a) => !isAttachmentComplete(a));
|
|
171
|
-
await Promise.all(pending.map((a) => adapter.remove(a)));
|
|
170
|
+
await Promise.all(pending.map(async (a) => adapter.remove(a)));
|
|
172
171
|
}
|
|
173
172
|
}
|
|
174
173
|
|
|
@@ -204,6 +203,10 @@ export abstract class BaseComposerRuntimeCore
|
|
|
204
203
|
|
|
205
204
|
public async clearAttachments() {
|
|
206
205
|
this._cancelAllAttachmentAdds();
|
|
206
|
+
if (this._isSending) {
|
|
207
|
+
for (const attachment of this._attachments)
|
|
208
|
+
this._removedDuringSend.add(attachment.id);
|
|
209
|
+
}
|
|
207
210
|
const task = this._onClearAttachments();
|
|
208
211
|
this.setAttachments([]);
|
|
209
212
|
|
|
@@ -214,8 +217,13 @@ export abstract class BaseComposerRuntimeCore
|
|
|
214
217
|
if (!this.canSend || this._isSending) return;
|
|
215
218
|
|
|
216
219
|
if (this._dictationSession) {
|
|
217
|
-
|
|
218
|
-
|
|
220
|
+
try {
|
|
221
|
+
this._dictationSession.cancel();
|
|
222
|
+
} catch (error) {
|
|
223
|
+
console.error("[assistant-ui] Dictation session cancel threw", error);
|
|
224
|
+
} finally {
|
|
225
|
+
this._cleanupDictation();
|
|
226
|
+
}
|
|
219
227
|
}
|
|
220
228
|
|
|
221
229
|
const adapter = this.getAttachmentAdapter();
|
|
@@ -301,7 +309,10 @@ export abstract class BaseComposerRuntimeCore
|
|
|
301
309
|
void sendTask.catch((error) => {
|
|
302
310
|
this._restoreUnsentDraft(error, generation, draft);
|
|
303
311
|
});
|
|
304
|
-
this._notifyEventSubscribers("send", {
|
|
312
|
+
this._notifyEventSubscribers("send", {
|
|
313
|
+
chars: text.length,
|
|
314
|
+
attachments: finalAttachments.length,
|
|
315
|
+
});
|
|
305
316
|
}
|
|
306
317
|
|
|
307
318
|
/**
|
|
@@ -417,6 +428,7 @@ export abstract class BaseComposerRuntimeCore
|
|
|
417
428
|
message,
|
|
418
429
|
undefined,
|
|
419
430
|
err,
|
|
431
|
+
fileOrAttachment.contentType,
|
|
420
432
|
);
|
|
421
433
|
throw err;
|
|
422
434
|
}
|
|
@@ -431,7 +443,9 @@ export abstract class BaseComposerRuntimeCore
|
|
|
431
443
|
};
|
|
432
444
|
this._attachments = [...this._attachments, a];
|
|
433
445
|
this._notifySubscribers();
|
|
434
|
-
this._notifyEventSubscribers("attachmentAdd", {
|
|
446
|
+
this._notifyEventSubscribers("attachmentAdd", {
|
|
447
|
+
...(a.contentType ? { contentType: a.contentType } : undefined),
|
|
448
|
+
});
|
|
435
449
|
return;
|
|
436
450
|
}
|
|
437
451
|
|
|
@@ -439,7 +453,13 @@ export abstract class BaseComposerRuntimeCore
|
|
|
439
453
|
if (!adapter) {
|
|
440
454
|
const message = "Attachments are not supported";
|
|
441
455
|
const err = new Error(message);
|
|
442
|
-
this._safeEmitAttachmentAddError(
|
|
456
|
+
this._safeEmitAttachmentAddError(
|
|
457
|
+
"no-adapter",
|
|
458
|
+
message,
|
|
459
|
+
undefined,
|
|
460
|
+
err,
|
|
461
|
+
fileOrAttachment.type,
|
|
462
|
+
);
|
|
443
463
|
throw err;
|
|
444
464
|
}
|
|
445
465
|
|
|
@@ -451,7 +471,13 @@ export abstract class BaseComposerRuntimeCore
|
|
|
451
471
|
) {
|
|
452
472
|
const message = `File type ${fileOrAttachment.type || "unknown"} is not accepted. Accepted types: ${adapter.accept}`;
|
|
453
473
|
const err = new Error(message);
|
|
454
|
-
this._safeEmitAttachmentAddError(
|
|
474
|
+
this._safeEmitAttachmentAddError(
|
|
475
|
+
"not-accepted",
|
|
476
|
+
message,
|
|
477
|
+
undefined,
|
|
478
|
+
err,
|
|
479
|
+
fileOrAttachment.type,
|
|
480
|
+
);
|
|
455
481
|
throw err;
|
|
456
482
|
}
|
|
457
483
|
|
|
@@ -501,6 +527,7 @@ export abstract class BaseComposerRuntimeCore
|
|
|
501
527
|
e instanceof Error ? e.message : String(e),
|
|
502
528
|
lastAttachment?.id,
|
|
503
529
|
e instanceof Error ? e : undefined,
|
|
530
|
+
lastAttachment?.contentType || fileOrAttachment.type,
|
|
504
531
|
);
|
|
505
532
|
throw e;
|
|
506
533
|
} finally {
|
|
@@ -517,9 +544,17 @@ export abstract class BaseComposerRuntimeCore
|
|
|
517
544
|
lastAttachment.status.message ??
|
|
518
545
|
"Attachment upload did not complete successfully.",
|
|
519
546
|
lastAttachment.id,
|
|
547
|
+
undefined,
|
|
548
|
+
lastAttachment.contentType || fileOrAttachment.type,
|
|
520
549
|
);
|
|
521
550
|
} else {
|
|
522
|
-
this._notifyEventSubscribers("attachmentAdd", {
|
|
551
|
+
this._notifyEventSubscribers("attachmentAdd", {
|
|
552
|
+
...(lastAttachment?.contentType
|
|
553
|
+
? { contentType: lastAttachment.contentType }
|
|
554
|
+
: fileOrAttachment.type
|
|
555
|
+
? { contentType: fileOrAttachment.type }
|
|
556
|
+
: undefined),
|
|
557
|
+
});
|
|
523
558
|
}
|
|
524
559
|
}
|
|
525
560
|
|
|
@@ -528,6 +563,7 @@ export abstract class BaseComposerRuntimeCore
|
|
|
528
563
|
message: string,
|
|
529
564
|
attachmentId?: string,
|
|
530
565
|
error?: Error,
|
|
566
|
+
contentType?: string,
|
|
531
567
|
) {
|
|
532
568
|
try {
|
|
533
569
|
this._notifyEventSubscribers("attachmentAddError", {
|
|
@@ -535,6 +571,7 @@ export abstract class BaseComposerRuntimeCore
|
|
|
535
571
|
message,
|
|
536
572
|
...(attachmentId !== undefined && { attachmentId }),
|
|
537
573
|
...(error !== undefined && { error }),
|
|
574
|
+
...(contentType ? { contentType } : undefined),
|
|
538
575
|
});
|
|
539
576
|
} catch (subscriberError) {
|
|
540
577
|
console.error(
|
|
@@ -608,14 +645,11 @@ export abstract class BaseComposerRuntimeCore
|
|
|
608
645
|
throw new Error("Dictation adapter not configured");
|
|
609
646
|
}
|
|
610
647
|
|
|
648
|
+
const isReplacing = this._dictationSession !== undefined;
|
|
611
649
|
if (this._dictationSession) {
|
|
612
|
-
for (const unsub of this._dictationUnsubscribes) {
|
|
613
|
-
unsub();
|
|
614
|
-
}
|
|
615
|
-
this._dictationUnsubscribes = [];
|
|
616
650
|
const oldSession = this._dictationSession;
|
|
617
|
-
|
|
618
|
-
this.
|
|
651
|
+
this._cleanupDictation({ notify: false });
|
|
652
|
+
this._stopDictationSession(oldSession);
|
|
619
653
|
}
|
|
620
654
|
|
|
621
655
|
const inputDisabled = adapter.disableInputDuringDictation ?? false;
|
|
@@ -623,7 +657,22 @@ export abstract class BaseComposerRuntimeCore
|
|
|
623
657
|
this._dictationBaseText = this._text;
|
|
624
658
|
this._currentInterimText = "";
|
|
625
659
|
|
|
626
|
-
|
|
660
|
+
let session: DictationAdapter.Session;
|
|
661
|
+
try {
|
|
662
|
+
session = adapter.listen();
|
|
663
|
+
} catch (error) {
|
|
664
|
+
if (isReplacing) {
|
|
665
|
+
try {
|
|
666
|
+
this._notifySubscribers();
|
|
667
|
+
} catch (notifyError) {
|
|
668
|
+
console.error(
|
|
669
|
+
"[assistant-ui] Dictation replacement rollback notification threw",
|
|
670
|
+
notifyError,
|
|
671
|
+
);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
throw error;
|
|
675
|
+
}
|
|
627
676
|
this._dictationSession = session;
|
|
628
677
|
const sessionId = ++this._dictationSessionIdCounter;
|
|
629
678
|
this._activeDictationSessionId = sessionId;
|
|
@@ -701,27 +750,59 @@ export abstract class BaseComposerRuntimeCore
|
|
|
701
750
|
const session = this._dictationSession;
|
|
702
751
|
const sessionId = this._activeDictationSessionId;
|
|
703
752
|
const cleanup = () => this._cleanupDictation({ sessionId });
|
|
704
|
-
|
|
753
|
+
this._stopDictationSession(session, cleanup);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
private _stopDictationSession(
|
|
757
|
+
session: DictationAdapter.Session,
|
|
758
|
+
onSettled: () => void = () => {},
|
|
759
|
+
): void {
|
|
760
|
+
let task: Promise<void>;
|
|
761
|
+
try {
|
|
762
|
+
task = session.stop();
|
|
763
|
+
} catch (error) {
|
|
764
|
+
console.error("[assistant-ui] Dictation session stop threw", error);
|
|
765
|
+
onSettled();
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
void task.then(onSettled, (error) => {
|
|
770
|
+
console.error("[assistant-ui] Dictation session stop rejected", error);
|
|
771
|
+
onSettled();
|
|
772
|
+
});
|
|
705
773
|
}
|
|
706
774
|
|
|
707
|
-
private _cleanupDictation(options?: {
|
|
775
|
+
private _cleanupDictation(options?: {
|
|
776
|
+
sessionId?: number | undefined;
|
|
777
|
+
notify?: boolean | undefined;
|
|
778
|
+
}): void {
|
|
708
779
|
const isStaleSession =
|
|
709
780
|
options?.sessionId !== undefined &&
|
|
710
781
|
options.sessionId !== this._activeDictationSessionId;
|
|
711
782
|
if (isStaleSession || this._isCleaningDictation) return;
|
|
712
783
|
|
|
713
784
|
this._isCleaningDictation = true;
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
785
|
+
const runCleanup = (cleanup: () => void) => {
|
|
786
|
+
try {
|
|
787
|
+
cleanup();
|
|
788
|
+
} catch (error) {
|
|
789
|
+
console.error("[assistant-ui] Dictation cleanup threw", error);
|
|
717
790
|
}
|
|
791
|
+
};
|
|
792
|
+
|
|
793
|
+
try {
|
|
794
|
+
const unsubscribes = this._dictationUnsubscribes;
|
|
718
795
|
this._dictationUnsubscribes = [];
|
|
719
796
|
this._dictationSession = undefined;
|
|
720
797
|
this._activeDictationSessionId = undefined;
|
|
721
798
|
this._dictation = undefined;
|
|
722
799
|
this._dictationBaseText = "";
|
|
723
800
|
this._currentInterimText = "";
|
|
724
|
-
|
|
801
|
+
|
|
802
|
+
for (const unsubscribe of unsubscribes) runCleanup(unsubscribe);
|
|
803
|
+
if (options?.notify !== false) {
|
|
804
|
+
runCleanup(() => this._notifySubscribers());
|
|
805
|
+
}
|
|
725
806
|
} finally {
|
|
726
807
|
this._isCleaningDictation = false;
|
|
727
808
|
}
|