@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
|
@@ -36,7 +36,10 @@ import type { RealtimeVoiceAdapter } from "../../adapters/voice";
|
|
|
36
36
|
import type { ThreadMessageLike } from "../utils/thread-message-like";
|
|
37
37
|
import { notifyEventListeners } from "../../utils/notify-event-listeners";
|
|
38
38
|
import { gateInteractableComposerMetadata } from "../../model-context/interactable-composer-metadata";
|
|
39
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
BaseSubscribable,
|
|
41
|
+
notifySubscribers,
|
|
42
|
+
} from "../../subscribable/subscribable";
|
|
40
43
|
|
|
41
44
|
type BaseThreadAdapters = {
|
|
42
45
|
speech?: SpeechSynthesisAdapter | undefined;
|
|
@@ -168,7 +171,16 @@ export abstract class BaseThreadRuntimeCore
|
|
|
168
171
|
public getEditComposer(messageId: string) {
|
|
169
172
|
return this._editComposers.get(messageId);
|
|
170
173
|
}
|
|
174
|
+
protected _isVoiceMessage(messageId: string | null) {
|
|
175
|
+
return (
|
|
176
|
+
messageId !== null && this._voiceMessages.some((m) => m.id === messageId)
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
171
180
|
public beginEdit(messageId: string) {
|
|
181
|
+
if (this._isVoiceMessage(messageId)) {
|
|
182
|
+
throw new Error("Voice transcript messages cannot be edited");
|
|
183
|
+
}
|
|
172
184
|
if (this._editComposers.has(messageId))
|
|
173
185
|
throw new Error("Edit already in progress");
|
|
174
186
|
|
|
@@ -227,11 +239,27 @@ export abstract class BaseThreadRuntimeCore
|
|
|
227
239
|
notifyEventListeners(subscribers, payload, `Thread runtime "${event}"`);
|
|
228
240
|
}
|
|
229
241
|
|
|
242
|
+
protected _notifyToolApprovalAnswered(
|
|
243
|
+
messageId: string,
|
|
244
|
+
toolCallId: string,
|
|
245
|
+
toolName: string,
|
|
246
|
+
approved: boolean,
|
|
247
|
+
) {
|
|
248
|
+
this._notifyEventSubscribers("toolApprovalAnswered", {
|
|
249
|
+
messageId,
|
|
250
|
+
toolCallId,
|
|
251
|
+
toolName,
|
|
252
|
+
approved,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
230
256
|
public submitFeedback({ messageId, type }: SubmitFeedbackOptions) {
|
|
231
257
|
const adapter = this.adapters?.feedback;
|
|
232
258
|
if (!adapter) throw new Error("Feedback adapter not configured");
|
|
233
259
|
|
|
234
|
-
const
|
|
260
|
+
const entry = this.getMessageById(messageId);
|
|
261
|
+
if (!entry) throw new Error(`Message not found: ${messageId}`);
|
|
262
|
+
const { message, parentId } = entry;
|
|
235
263
|
adapter.submit({ message, type });
|
|
236
264
|
|
|
237
265
|
if (message.role === "assistant") {
|
|
@@ -242,7 +270,18 @@ export abstract class BaseThreadRuntimeCore
|
|
|
242
270
|
submittedFeedback: { type },
|
|
243
271
|
},
|
|
244
272
|
};
|
|
245
|
-
this.
|
|
273
|
+
const voiceIdx = this._voiceMessages.findIndex(
|
|
274
|
+
(voiceMessage) => voiceMessage.id === messageId,
|
|
275
|
+
);
|
|
276
|
+
if (voiceIdx === -1) {
|
|
277
|
+
this.repository.addOrUpdateMessage(parentId, updatedMessage);
|
|
278
|
+
} else {
|
|
279
|
+
this._voiceMessages[voiceIdx] = updatedMessage;
|
|
280
|
+
if (this._currentAssistantMsg === message) {
|
|
281
|
+
this._currentAssistantMsg = updatedMessage as ThreadAssistantMessage;
|
|
282
|
+
}
|
|
283
|
+
this._markVoiceMessagesDirty();
|
|
284
|
+
}
|
|
246
285
|
}
|
|
247
286
|
|
|
248
287
|
this._notifySubscribers();
|
|
@@ -255,36 +294,80 @@ export abstract class BaseThreadRuntimeCore
|
|
|
255
294
|
const adapter = this.adapters?.speech;
|
|
256
295
|
if (!adapter) throw new Error("Speech adapter not configured");
|
|
257
296
|
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
|
|
297
|
+
const entry = this.getMessageById(messageId);
|
|
298
|
+
if (!entry) throw new Error(`Message not found: ${messageId}`);
|
|
299
|
+
const { message } = entry;
|
|
261
300
|
|
|
262
|
-
const
|
|
263
|
-
|
|
301
|
+
const previousStop = this._stopSpeaking;
|
|
302
|
+
let utterance: SpeechSynthesisAdapter.Utterance;
|
|
303
|
+
try {
|
|
304
|
+
previousStop?.();
|
|
305
|
+
utterance = adapter.speak(getThreadMessageText(message));
|
|
306
|
+
} catch (error) {
|
|
307
|
+
if (previousStop && !this._stopSpeaking) {
|
|
308
|
+
try {
|
|
309
|
+
this._notifySubscribers();
|
|
310
|
+
} catch (notificationError) {
|
|
311
|
+
console.error(
|
|
312
|
+
"[assistant-ui] Speech rollback notification threw",
|
|
313
|
+
notificationError,
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
throw error;
|
|
318
|
+
}
|
|
319
|
+
let unsub: Unsubscribe | undefined;
|
|
320
|
+
const clear = () => {
|
|
321
|
+
this._stopSpeaking = undefined;
|
|
322
|
+
this.speech = undefined;
|
|
323
|
+
const cleanup = unsub;
|
|
324
|
+
unsub = undefined;
|
|
325
|
+
cleanup?.();
|
|
326
|
+
};
|
|
327
|
+
const stop = () => {
|
|
328
|
+
if (this._stopSpeaking !== stop) return;
|
|
329
|
+
try {
|
|
330
|
+
clear();
|
|
331
|
+
} finally {
|
|
332
|
+
utterance.cancel();
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
const update = () => {
|
|
336
|
+
if (this._stopSpeaking !== stop) return;
|
|
264
337
|
if (utterance.status.type === "ended") {
|
|
265
|
-
this.
|
|
266
|
-
this.speech = undefined;
|
|
338
|
+
notifySubscribers([clear, () => this._notifySubscribers()]);
|
|
267
339
|
} else {
|
|
268
340
|
this.speech = { messageId, status: utterance.status };
|
|
341
|
+
this._notifySubscribers();
|
|
269
342
|
}
|
|
270
|
-
this._notifySubscribers();
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
this.speech = { messageId, status: utterance.status };
|
|
274
|
-
this._notifySubscribers();
|
|
275
|
-
|
|
276
|
-
this._stopSpeaking = () => {
|
|
277
|
-
utterance.cancel();
|
|
278
|
-
unsub();
|
|
279
|
-
this.speech = undefined;
|
|
280
|
-
this._stopSpeaking = undefined;
|
|
281
343
|
};
|
|
344
|
+
|
|
345
|
+
this._stopSpeaking = stop;
|
|
346
|
+
try {
|
|
347
|
+
unsub = utterance.subscribe(update);
|
|
348
|
+
if (this._stopSpeaking !== stop) {
|
|
349
|
+
unsub();
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
update();
|
|
353
|
+
} catch (error) {
|
|
354
|
+
if (this._stopSpeaking === stop) {
|
|
355
|
+
try {
|
|
356
|
+
notifySubscribers([stop, () => this._notifySubscribers()]);
|
|
357
|
+
} catch (cleanupError) {
|
|
358
|
+
console.error(
|
|
359
|
+
"[assistant-ui] Speech rollback cleanup threw",
|
|
360
|
+
cleanupError,
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
throw error;
|
|
365
|
+
}
|
|
282
366
|
}
|
|
283
367
|
|
|
284
368
|
public stopSpeaking() {
|
|
285
369
|
if (!this._stopSpeaking) throw new Error("No message is being spoken");
|
|
286
|
-
this._stopSpeaking();
|
|
287
|
-
this._notifySubscribers();
|
|
370
|
+
notifySubscribers([this._stopSpeaking, () => this._notifySubscribers()]);
|
|
288
371
|
}
|
|
289
372
|
|
|
290
373
|
private _voiceSession: RealtimeVoiceAdapter.Session | undefined;
|
|
@@ -305,67 +388,111 @@ export abstract class BaseThreadRuntimeCore
|
|
|
305
388
|
const adapter = this.adapters?.voice;
|
|
306
389
|
if (!adapter) throw new Error("Voice adapter not configured");
|
|
307
390
|
|
|
308
|
-
|
|
391
|
+
try {
|
|
392
|
+
this.disconnectVoice();
|
|
393
|
+
} catch (error) {
|
|
394
|
+
console.error(
|
|
395
|
+
"[assistant-ui] Voice cleanup threw before reconnect",
|
|
396
|
+
error,
|
|
397
|
+
);
|
|
398
|
+
}
|
|
309
399
|
|
|
310
400
|
const session = adapter.connect({});
|
|
311
401
|
this._voiceSession = session;
|
|
312
402
|
const unsubs: Array<() => void> = [];
|
|
403
|
+
this._voiceUnsubs = unsubs;
|
|
313
404
|
|
|
314
|
-
|
|
405
|
+
// The cleanup-list identity preserves ownership after an ended status clears the session.
|
|
406
|
+
const finishDetachedSetup = () => {
|
|
407
|
+
if (this._voiceSession === session && this._voiceUnsubs === unsubs) {
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
315
410
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
411
|
+
try {
|
|
412
|
+
notifySubscribers(unsubs.splice(0));
|
|
413
|
+
} catch (error) {
|
|
414
|
+
console.error(
|
|
415
|
+
"[assistant-ui] Detached voice setup cleanup threw",
|
|
416
|
+
error,
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
return true;
|
|
320
420
|
};
|
|
321
|
-
this._voiceVolume = 0;
|
|
322
|
-
this._notifySubscribers();
|
|
323
421
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
if (status.type === "ended") {
|
|
327
|
-
this._finishVoiceAssistantMessage();
|
|
328
|
-
this._voiceSession = undefined;
|
|
329
|
-
this.voice = undefined;
|
|
330
|
-
} else {
|
|
331
|
-
this.voice = {
|
|
332
|
-
status,
|
|
333
|
-
isMuted: session.isMuted,
|
|
334
|
-
mode: currentMode,
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
this._notifySubscribers();
|
|
338
|
-
}),
|
|
339
|
-
);
|
|
422
|
+
try {
|
|
423
|
+
let currentMode: RealtimeVoiceAdapter.Mode = "listening";
|
|
340
424
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
425
|
+
this.voice = {
|
|
426
|
+
status: session.status,
|
|
427
|
+
isMuted: session.isMuted,
|
|
428
|
+
mode: currentMode,
|
|
429
|
+
};
|
|
430
|
+
this._voiceVolume = 0;
|
|
431
|
+
this._notifySubscribers();
|
|
432
|
+
if (finishDetachedSetup()) return;
|
|
433
|
+
|
|
434
|
+
unsubs.push(
|
|
435
|
+
session.onStatusChange((status) => {
|
|
436
|
+
if (status.type === "ended") {
|
|
437
|
+
this._finishVoiceAssistantMessage();
|
|
438
|
+
this._voiceSession = undefined;
|
|
439
|
+
this.voice = undefined;
|
|
440
|
+
} else {
|
|
441
|
+
this.voice = {
|
|
442
|
+
status,
|
|
443
|
+
isMuted: session.isMuted,
|
|
444
|
+
mode: currentMode,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
346
447
|
this._notifySubscribers();
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
)
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
448
|
+
}),
|
|
449
|
+
);
|
|
450
|
+
if (finishDetachedSetup()) return;
|
|
451
|
+
|
|
452
|
+
unsubs.push(
|
|
453
|
+
session.onModeChange((mode) => {
|
|
454
|
+
currentMode = mode;
|
|
455
|
+
if (this.voice) {
|
|
456
|
+
this.voice = { ...this.voice, mode };
|
|
457
|
+
this._notifySubscribers();
|
|
458
|
+
}
|
|
459
|
+
}),
|
|
460
|
+
);
|
|
461
|
+
if (finishDetachedSetup()) return;
|
|
462
|
+
|
|
463
|
+
unsubs.push(
|
|
464
|
+
session.onVolumeChange((volume) => {
|
|
465
|
+
this._voiceVolume = volume;
|
|
466
|
+
notifyEventListeners(
|
|
467
|
+
this._voiceVolumeSubscribers,
|
|
468
|
+
undefined,
|
|
469
|
+
"Voice volume",
|
|
470
|
+
);
|
|
471
|
+
}),
|
|
472
|
+
);
|
|
473
|
+
if (finishDetachedSetup()) return;
|
|
367
474
|
|
|
368
|
-
|
|
475
|
+
unsubs.push(
|
|
476
|
+
session.onTranscript((transcript) => {
|
|
477
|
+
this._handleVoiceTranscript(transcript);
|
|
478
|
+
}),
|
|
479
|
+
);
|
|
480
|
+
finishDetachedSetup();
|
|
481
|
+
} catch (error) {
|
|
482
|
+
if (this._voiceSession === session && this._voiceUnsubs === unsubs) {
|
|
483
|
+
try {
|
|
484
|
+
this.disconnectVoice();
|
|
485
|
+
} catch (cleanupError) {
|
|
486
|
+
console.error(
|
|
487
|
+
"[assistant-ui] Voice rollback cleanup threw",
|
|
488
|
+
cleanupError,
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
} else {
|
|
492
|
+
finishDetachedSetup();
|
|
493
|
+
}
|
|
494
|
+
throw error;
|
|
495
|
+
}
|
|
369
496
|
}
|
|
370
497
|
|
|
371
498
|
private _currentAssistantMsg: ThreadAssistantMessage | null = null;
|
|
@@ -384,7 +511,7 @@ export abstract class BaseThreadRuntimeCore
|
|
|
384
511
|
id: generateId(),
|
|
385
512
|
role: "user",
|
|
386
513
|
content: [{ type: "text", text: transcript.text }],
|
|
387
|
-
metadata: { custom: {} },
|
|
514
|
+
metadata: { modality: "voice", custom: {} },
|
|
388
515
|
createdAt: new Date(),
|
|
389
516
|
status: { type: "complete", reason: "unknown" },
|
|
390
517
|
attachments: [],
|
|
@@ -393,6 +520,10 @@ export abstract class BaseThreadRuntimeCore
|
|
|
393
520
|
this._notifySubscribers();
|
|
394
521
|
}
|
|
395
522
|
} else {
|
|
523
|
+
const status: ThreadAssistantMessage["status"] = transcript.isFinal
|
|
524
|
+
? { type: "complete", reason: "stop" }
|
|
525
|
+
: { type: "running" };
|
|
526
|
+
|
|
396
527
|
if (!this._currentAssistantMsg) {
|
|
397
528
|
this._currentAssistantMsg = {
|
|
398
529
|
id: generateId(),
|
|
@@ -403,9 +534,10 @@ export abstract class BaseThreadRuntimeCore
|
|
|
403
534
|
unstable_annotations: [],
|
|
404
535
|
unstable_data: [],
|
|
405
536
|
steps: [],
|
|
537
|
+
modality: "voice",
|
|
406
538
|
custom: {},
|
|
407
539
|
},
|
|
408
|
-
status
|
|
540
|
+
status,
|
|
409
541
|
createdAt: new Date(),
|
|
410
542
|
};
|
|
411
543
|
this._voiceMessages.push(this._currentAssistantMsg);
|
|
@@ -415,9 +547,7 @@ export abstract class BaseThreadRuntimeCore
|
|
|
415
547
|
const updated: ThreadAssistantMessage = {
|
|
416
548
|
...this._currentAssistantMsg,
|
|
417
549
|
content: [{ type: "text", text: transcript.text }],
|
|
418
|
-
|
|
419
|
-
? { status: { type: "complete", reason: "stop" } }
|
|
420
|
-
: {}),
|
|
550
|
+
status,
|
|
421
551
|
};
|
|
422
552
|
this._voiceMessages[idx] = updated;
|
|
423
553
|
this._currentAssistantMsg = updated;
|
|
@@ -446,22 +576,33 @@ export abstract class BaseThreadRuntimeCore
|
|
|
446
576
|
}
|
|
447
577
|
|
|
448
578
|
public disconnectVoice() {
|
|
449
|
-
this._finishVoiceAssistantMessage();
|
|
450
579
|
this._currentAssistantMsg = null;
|
|
451
|
-
|
|
580
|
+
// Drain the shared list in place so reentrant setup cannot release the same handles again.
|
|
581
|
+
const unsubs = this._voiceUnsubs.splice(0);
|
|
452
582
|
this._voiceUnsubs = [];
|
|
453
|
-
this._voiceSession
|
|
583
|
+
const session = this._voiceSession;
|
|
454
584
|
this._voiceSession = undefined;
|
|
455
585
|
this.voice = undefined;
|
|
456
586
|
this._voiceVolume = 0;
|
|
457
|
-
|
|
458
|
-
this.
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
);
|
|
587
|
+
const stopSpeaking =
|
|
588
|
+
this.speech && this._isVoiceMessage(this.speech.messageId)
|
|
589
|
+
? this._stopSpeaking
|
|
590
|
+
: undefined;
|
|
462
591
|
this._voiceMessages = [];
|
|
463
592
|
this._markVoiceMessagesDirty();
|
|
464
|
-
|
|
593
|
+
|
|
594
|
+
notifySubscribers([
|
|
595
|
+
...unsubs,
|
|
596
|
+
...(stopSpeaking ? [stopSpeaking] : []),
|
|
597
|
+
...(session ? [() => session.disconnect()] : []),
|
|
598
|
+
() =>
|
|
599
|
+
notifyEventListeners(
|
|
600
|
+
this._voiceVolumeSubscribers,
|
|
601
|
+
undefined,
|
|
602
|
+
"Voice volume",
|
|
603
|
+
),
|
|
604
|
+
() => this._notifySubscribers(),
|
|
605
|
+
]);
|
|
465
606
|
}
|
|
466
607
|
|
|
467
608
|
public muteVoice() {
|
|
@@ -21,16 +21,21 @@ export type AttachmentAddErrorEvent = {
|
|
|
21
21
|
|
|
22
22
|
export type ComposerRuntimeEventPayload = {
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
24
|
+
* Fired after a send with the size of what went out. The composer state is
|
|
25
|
+
* already cleared when it fires, so the counts are only available here.
|
|
26
26
|
*/
|
|
27
|
-
send:
|
|
27
|
+
send: {
|
|
28
|
+
readonly chars: number;
|
|
29
|
+
readonly attachments: number;
|
|
30
|
+
};
|
|
28
31
|
/**
|
|
29
32
|
* @deprecated State-derivable. Observe `state.attachments` via `subscribe` +
|
|
30
33
|
* `getState` instead. Kept for backward compatibility.
|
|
31
34
|
*/
|
|
32
|
-
attachmentAdd:
|
|
33
|
-
attachmentAddError: AttachmentAddErrorEvent
|
|
35
|
+
attachmentAdd: { readonly contentType?: string | undefined };
|
|
36
|
+
attachmentAddError: AttachmentAddErrorEvent & {
|
|
37
|
+
readonly contentType?: string | undefined;
|
|
38
|
+
};
|
|
34
39
|
};
|
|
35
40
|
|
|
36
41
|
export type ComposerRuntimeEventType = keyof ComposerRuntimeEventPayload;
|
|
@@ -26,6 +26,7 @@ export type ThreadListRuntimeEvent = {
|
|
|
26
26
|
|
|
27
27
|
export type ThreadListRuntimeCore = {
|
|
28
28
|
readonly isLoading: boolean;
|
|
29
|
+
readonly loadError?: unknown;
|
|
29
30
|
readonly isLoadingMore?: boolean;
|
|
30
31
|
readonly hasMore?: boolean;
|
|
31
32
|
mainThreadId: string;
|
|
@@ -86,7 +87,10 @@ export type ThreadListRuntimeCore = {
|
|
|
86
87
|
initialize(
|
|
87
88
|
threadId: string,
|
|
88
89
|
): Promise<{ remoteId: string; externalId: string | undefined }>;
|
|
89
|
-
generateTitle(
|
|
90
|
+
generateTitle(
|
|
91
|
+
threadId: string,
|
|
92
|
+
options?: { automatic?: boolean },
|
|
93
|
+
): Promise<void>;
|
|
90
94
|
|
|
91
95
|
subscribe(callback: () => void): Unsubscribe;
|
|
92
96
|
};
|
|
@@ -98,6 +98,12 @@ export type SubmittedFeedback = {
|
|
|
98
98
|
};
|
|
99
99
|
|
|
100
100
|
export type ThreadRuntimeEventPayload = {
|
|
101
|
+
toolApprovalAnswered: {
|
|
102
|
+
messageId: string;
|
|
103
|
+
toolCallId: string;
|
|
104
|
+
toolName: string;
|
|
105
|
+
approved: boolean;
|
|
106
|
+
};
|
|
101
107
|
/**
|
|
102
108
|
* @deprecated State-derivable. Observe `state.isRunning` flipping to `true`
|
|
103
109
|
* via `subscribe` + `getState` instead. Note: this event fires at the
|
|
@@ -13,6 +13,11 @@ import type {
|
|
|
13
13
|
} from "./external-thread-queue-adapter";
|
|
14
14
|
|
|
15
15
|
export type MessageQueueDriver = {
|
|
16
|
+
/**
|
|
17
|
+
* A synchronous throw is treated as a run that never started and restores
|
|
18
|
+
* the message. A driver that already started work must call `notifyBusy`
|
|
19
|
+
* before throwing.
|
|
20
|
+
*/
|
|
16
21
|
run: (message: AppendMessage, options: { steer: boolean }) => void;
|
|
17
22
|
/** When omitted, steering degrades to "process next" instead of interrupting. */
|
|
18
23
|
cancel?: (() => void) | undefined;
|
|
@@ -38,6 +43,12 @@ export type MessageQueueController = {
|
|
|
38
43
|
|
|
39
44
|
type Lane = "queue" | "steer";
|
|
40
45
|
|
|
46
|
+
type DispatchItem = {
|
|
47
|
+
id: string;
|
|
48
|
+
item: QueueItemState;
|
|
49
|
+
message: AppendMessage;
|
|
50
|
+
};
|
|
51
|
+
|
|
41
52
|
const getQueueItemParts = (
|
|
42
53
|
message: AppendMessage,
|
|
43
54
|
): readonly (FileMessagePart | TextMessagePart)[] => {
|
|
@@ -83,6 +94,7 @@ export const createMessageQueue = (
|
|
|
83
94
|
// settles from cancelled runs that must drop `running` without advancing
|
|
84
95
|
let cancelSettles = 0;
|
|
85
96
|
let interrupting = false;
|
|
97
|
+
let busyEdges = 0;
|
|
86
98
|
|
|
87
99
|
const notify = () => {
|
|
88
100
|
notifyEventListeners(subscribers, undefined, "Message queue");
|
|
@@ -101,6 +113,19 @@ export const createMessageQueue = (
|
|
|
101
113
|
parts: getQueueItemParts(message),
|
|
102
114
|
});
|
|
103
115
|
|
|
116
|
+
const restore = (lane: Lane, dispatch: DispatchItem, index = 0) => {
|
|
117
|
+
paused = true;
|
|
118
|
+
messages.set(dispatch.id, dispatch.message);
|
|
119
|
+
setLanes({
|
|
120
|
+
...lanes,
|
|
121
|
+
[lane]: [
|
|
122
|
+
...lanes[lane].slice(0, index),
|
|
123
|
+
dispatch.item,
|
|
124
|
+
...lanes[lane].slice(index),
|
|
125
|
+
],
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
|
|
104
129
|
const laneOf = (queueItemId: string): Lane | undefined => {
|
|
105
130
|
if (lanes.steer.some((item) => item.id === queueItemId)) return "steer";
|
|
106
131
|
if (lanes.queue.some((item) => item.id === queueItemId)) return "queue";
|
|
@@ -116,27 +141,61 @@ export const createMessageQueue = (
|
|
|
116
141
|
messages.delete(head.id);
|
|
117
142
|
setLanes({ ...lanes, [lane]: lanes[lane].slice(1) });
|
|
118
143
|
if (!message) return;
|
|
144
|
+
const dispatch = { id: head.id, item: head, message };
|
|
119
145
|
running = true;
|
|
120
|
-
|
|
146
|
+
const busyEdgesBeforeRun = busyEdges;
|
|
147
|
+
try {
|
|
148
|
+
driver.run(dispatchTransform(message), { steer: false });
|
|
149
|
+
} catch (error) {
|
|
150
|
+
if (busyEdges === busyEdgesBeforeRun) {
|
|
151
|
+
running = false;
|
|
152
|
+
restore(lane, dispatch);
|
|
153
|
+
}
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
121
156
|
};
|
|
122
157
|
|
|
123
|
-
const interrupt = (
|
|
158
|
+
const interrupt = (
|
|
159
|
+
dispatch: DispatchItem,
|
|
160
|
+
restoreLane: Lane = "steer",
|
|
161
|
+
restoreIndex = 0,
|
|
162
|
+
) => {
|
|
124
163
|
paused = false;
|
|
125
164
|
// the interrupted run settles exactly once, whether or not it was
|
|
126
165
|
// already cancel-notified
|
|
127
166
|
suppressIdle += Math.max(cancelSettles, 1);
|
|
128
167
|
cancelSettles = 0;
|
|
168
|
+
const restoreInterrupted = (replacementStarted = false) => {
|
|
169
|
+
if (replacementStarted) return;
|
|
170
|
+
// The live count distinguishes an outstanding cancellation settle
|
|
171
|
+
// from one delivered synchronously by cancel().
|
|
172
|
+
const pendingSettles = suppressIdle;
|
|
173
|
+
suppressIdle = Math.max(pendingSettles - 1, 0);
|
|
174
|
+
cancelSettles = pendingSettles > 0 ? 1 : 0;
|
|
175
|
+
running = pendingSettles > 0;
|
|
176
|
+
restore(restoreLane, dispatch, restoreIndex);
|
|
177
|
+
};
|
|
129
178
|
// a driver whose cancel routes through the runtime notifies this queue
|
|
130
179
|
// back; the interrupt already accounted for that settle and is dispatching
|
|
131
180
|
// in its place
|
|
132
181
|
interrupting = true;
|
|
133
182
|
try {
|
|
134
183
|
driver.cancel!();
|
|
184
|
+
} catch (error) {
|
|
185
|
+
restoreInterrupted();
|
|
186
|
+
throw error;
|
|
135
187
|
} finally {
|
|
136
188
|
interrupting = false;
|
|
137
189
|
}
|
|
138
190
|
running = true;
|
|
139
|
-
|
|
191
|
+
const busyEdgesBeforeRun = busyEdges;
|
|
192
|
+
try {
|
|
193
|
+
driver.run(dispatchTransform(dispatch.message), { steer: true });
|
|
194
|
+
} catch (error) {
|
|
195
|
+
const replacementStarted = busyEdges !== busyEdgesBeforeRun;
|
|
196
|
+
restoreInterrupted(replacementStarted);
|
|
197
|
+
throw error;
|
|
198
|
+
}
|
|
140
199
|
};
|
|
141
200
|
|
|
142
201
|
const push = (lane: Lane, message: AppendMessage) => {
|
|
@@ -153,7 +212,8 @@ export const createMessageQueue = (
|
|
|
153
212
|
|
|
154
213
|
const steer = (message: AppendMessage) => {
|
|
155
214
|
if (running && driver.cancel) {
|
|
156
|
-
|
|
215
|
+
const id = generateId();
|
|
216
|
+
interrupt({ id, item: toItem(id, message), message });
|
|
157
217
|
return;
|
|
158
218
|
}
|
|
159
219
|
push("steer", message);
|
|
@@ -164,7 +224,8 @@ export const createMessageQueue = (
|
|
|
164
224
|
if (!fromLane) throw new Error(`Unknown queue item "${queueItemId}".`);
|
|
165
225
|
const toLane = placement.lane ?? fromLane;
|
|
166
226
|
|
|
167
|
-
const
|
|
227
|
+
const fromIndex = lanes[fromLane].findIndex((i) => i.id === queueItemId);
|
|
228
|
+
const item = lanes[fromLane][fromIndex]!;
|
|
168
229
|
const dest = (toLane === fromLane ? lanes[fromLane] : lanes[toLane]).filter(
|
|
169
230
|
(i) => i.id !== queueItemId,
|
|
170
231
|
);
|
|
@@ -217,7 +278,7 @@ export const createMessageQueue = (
|
|
|
217
278
|
queue: lanes.queue.filter((i) => i.id !== queueItemId),
|
|
218
279
|
steer: lanes.steer,
|
|
219
280
|
});
|
|
220
|
-
interrupt(message);
|
|
281
|
+
interrupt({ id: queueItemId, item, message }, fromLane, fromIndex);
|
|
221
282
|
return;
|
|
222
283
|
}
|
|
223
284
|
|
|
@@ -280,6 +341,7 @@ export const createMessageQueue = (
|
|
|
280
341
|
suppressIdle += cancelSettles;
|
|
281
342
|
cancelSettles = 0;
|
|
282
343
|
running = true;
|
|
344
|
+
busyEdges++;
|
|
283
345
|
},
|
|
284
346
|
notifyIdle: () => {
|
|
285
347
|
if (suppressIdle > 0) {
|