@assistant-ui/core 0.3.15 → 0.3.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +8 -2
- package/dist/internal.js +9 -3
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js +3 -2
- package/dist/model-context/frame/host.js.map +1 -1
- package/dist/model-context/frame/provider.d.ts +5 -0
- package/dist/model-context/frame/provider.d.ts.map +1 -1
- package/dist/model-context/frame/provider.js +141 -28
- package/dist/model-context/frame/provider.js.map +1 -1
- package/dist/model-context/interactable-composer-metadata.d.ts +1 -1
- package/dist/model-context/interactable-composer-metadata.js +1 -1
- package/dist/model-context/interactable-composer-metadata.js.map +1 -1
- package/dist/model-context/registry.d.ts +2 -2
- package/dist/model-context/registry.d.ts.map +1 -1
- package/dist/model-context/registry.js +9 -28
- package/dist/model-context/registry.js.map +1 -1
- package/dist/model-context/tool-call-text.d.ts +26 -0
- package/dist/model-context/tool-call-text.d.ts.map +1 -0
- package/dist/model-context/tool-call-text.js +18 -0
- package/dist/model-context/tool-call-text.js.map +1 -0
- package/dist/react/RuntimeAdapter.js +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.js +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
- package/dist/react/client/AdaptedRemoteThread.js +1 -1
- package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
- package/dist/react/client/InMemoryThreadList.js +25 -21
- package/dist/react/client/InMemoryThreadList.js.map +1 -1
- package/dist/react/client/Interactables.d.ts.map +1 -1
- package/dist/react/client/Interactables.js +60 -178
- package/dist/react/client/Interactables.js.map +1 -1
- package/dist/react/client/RemoteThreadList.d.ts +15 -0
- package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
- package/dist/react/client/RemoteThreadList.js +263 -194
- package/dist/react/client/RemoteThreadList.js.map +1 -1
- package/dist/react/client/Tools.d.ts.map +1 -1
- package/dist/react/client/Tools.js +6 -2
- package/dist/react/client/Tools.js.map +1 -1
- package/dist/react/index.d.ts +4 -2
- package/dist/react/index.js +2 -1
- package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
- package/dist/react/interactables-legacy/Interactables.js +60 -178
- package/dist/react/interactables-legacy/Interactables.js.map +1 -1
- package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts +24 -0
- package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -0
- package/dist/react/interactables-shared/useInteractablePersistenceQueue.js +138 -0
- package/dist/react/interactables-shared/useInteractablePersistenceQueue.js.map +1 -0
- package/dist/react/model-context/toolbox.d.ts +2 -14
- package/dist/react/model-context/toolbox.d.ts.map +1 -1
- package/dist/react/model-context/toolbox.js +1 -13
- package/dist/react/model-context/toolbox.js.map +1 -1
- package/dist/react/model-context/useAssistantContext.js +37 -7
- package/dist/react/model-context/useAssistantContext.js.map +1 -1
- package/dist/react/model-context/useAuiToolOverrides.js +31 -5
- package/dist/react/model-context/useAuiToolOverrides.js.map +1 -1
- package/dist/react/model-context/useInlineRender.d.ts.map +1 -1
- package/dist/react/model-context/useInlineRender.js +10 -36
- package/dist/react/model-context/useInlineRender.js.map +1 -1
- package/dist/react/primitive-hooks/useMessageError.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useMessageError.js +2 -8
- package/dist/react/primitive-hooks/useMessageError.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadListLoadMore.js +2 -4
- package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
- package/dist/react/primitives/composer/ComposerAttachments.d.ts.map +1 -1
- package/dist/react/primitives/composer/ComposerAttachments.js +4 -3
- package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
- package/dist/react/primitives/composer/ComposerIf.js.map +1 -1
- package/dist/react/primitives/composer/ComposerQueue.d.ts +2 -1
- package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
- package/dist/react/primitives/composer/ComposerQueue.js +4 -3
- package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
- package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageAttachments.js +7 -6
- package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.js +2 -2
- package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
- package/dist/react/primitives/message/MessageParts.js +3 -3
- package/dist/react/primitives/message/MessageParts.js.map +1 -1
- package/dist/react/primitives/threadList/ThreadListItems.d.ts.map +1 -1
- package/dist/react/primitives/threadList/ThreadListItems.js +5 -4
- package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +7 -5
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +44 -22
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +7 -6
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +102 -117
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadResource.d.ts +1 -6
- package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadResource.js +3 -3
- package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
- package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -1
- package/dist/react/runtimes/assistant-transport/runManager.js +2 -12
- package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -1
- package/dist/react/runtimes/assistant-transport/useLatestRef.js +2 -2
- package/dist/react/runtimes/assistant-transport/useLatestRef.js.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +3 -10
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +43 -85
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.d.ts +5 -1
- package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +29 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js +159 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js.map +1 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts +12 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.js +10 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.js.map +1 -0
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts +1 -9
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +16 -153
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -1
- package/dist/react/runtimes/createMessageConverter.d.ts +2 -1
- package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.d.ts +6 -25
- package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.js +33 -233
- package/dist/react/runtimes/external-message-converter.js.map +1 -1
- package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
- package/dist/react/runtimes/useRemoteThreadListRuntime.js +14 -6
- package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
- package/dist/react/types/MessagePartComponentTypes.d.ts +7 -3
- package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
- package/dist/react/types/scopes/tools.d.ts +2 -0
- package/dist/react/types/scopes/tools.d.ts.map +1 -1
- package/dist/runtime/api/composer-runtime.d.ts +1 -1
- package/dist/runtime/api/composer-runtime.js.map +1 -1
- package/dist/runtime/api/message-part-runtime.d.ts +2 -2
- package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
- package/dist/runtime/api/message-part-runtime.js +1 -1
- package/dist/runtime/api/message-part-runtime.js.map +1 -1
- package/dist/runtime/api/thread-list-runtime.d.ts +9 -1
- package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-runtime.js +5 -0
- package/dist/runtime/api/thread-list-runtime.js.map +1 -1
- package/dist/runtime/api/thread-runtime.d.ts +2 -3
- package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.js +14 -29
- package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts +4 -6
- package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.js +5 -11
- package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.js +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
- package/dist/runtime/interfaces/composer-runtime-core.d.ts +1 -1
- package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +14 -2
- package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtime/interfaces/thread-runtime-core.d.ts +16 -2
- package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/internal.d.ts +2 -1
- package/dist/runtime/internal.js +2 -1
- package/dist/runtime/queue/external-thread-queue-adapter.d.ts +1 -1
- package/dist/runtime/queue/message-queue.d.ts.map +1 -1
- package/dist/runtime/queue/message-queue.js +1 -1
- package/dist/runtime/queue/message-queue.js.map +1 -1
- package/dist/runtime/queue/queue-item.d.ts +12 -0
- package/dist/runtime/queue/queue-item.d.ts.map +1 -0
- package/dist/runtime/queue/queue-item.js +6 -0
- package/dist/runtime/queue/queue-item.js.map +1 -0
- package/dist/runtime/utils/abortable-thread-load.d.ts +15 -0
- package/dist/runtime/utils/abortable-thread-load.d.ts.map +1 -0
- package/dist/runtime/utils/abortable-thread-load.js +35 -0
- package/dist/runtime/utils/abortable-thread-load.js.map +1 -0
- package/dist/runtime/utils/attachment-add-operations.d.ts +18 -0
- package/dist/runtime/utils/attachment-add-operations.d.ts.map +1 -0
- package/dist/runtime/utils/attachment-add-operations.js +43 -0
- package/dist/runtime/utils/attachment-add-operations.js.map +1 -0
- package/dist/runtime/utils/auto-status.d.ts +7 -2
- package/dist/runtime/utils/auto-status.d.ts.map +1 -1
- package/dist/runtime/utils/auto-status.js +13 -3
- package/dist/runtime/utils/auto-status.js.map +1 -1
- package/dist/runtime/utils/external-message-conversion.d.ts +48 -0
- package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -0
- package/dist/runtime/utils/external-message-conversion.js +222 -0
- package/dist/runtime/utils/external-message-conversion.js.map +1 -0
- package/dist/runtime/utils/external-store-message.d.ts +2 -1
- package/dist/runtime/utils/external-store-message.d.ts.map +1 -1
- package/dist/runtime/utils/external-store-message.js +2 -1
- package/dist/runtime/utils/external-store-message.js.map +1 -1
- package/dist/runtime/utils/message-repository-session.d.ts +30 -0
- package/dist/runtime/utils/message-repository-session.d.ts.map +1 -0
- package/dist/runtime/utils/message-repository-session.js +130 -0
- package/dist/runtime/utils/message-repository-session.js.map +1 -0
- package/dist/runtime/utils/message-repository.d.ts.map +1 -1
- package/dist/runtime/utils/message-repository.js +3 -4
- package/dist/runtime/utils/message-repository.js.map +1 -1
- package/dist/runtime/utils/pending-tool-calls.d.ts +20 -0
- package/dist/runtime/utils/pending-tool-calls.d.ts.map +1 -0
- package/dist/runtime/utils/pending-tool-calls.js +22 -0
- package/dist/runtime/utils/pending-tool-calls.js.map +1 -0
- package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +6 -3
- package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -1
- package/dist/runtime/utils/resolveToolApprovalResponse.js +12 -3
- package/dist/runtime/utils/resolveToolApprovalResponse.js.map +1 -1
- package/dist/runtime/utils/thread-message-like.d.ts +3 -10
- package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
- package/dist/runtime/utils/thread-message-like.js.map +1 -1
- package/dist/runtime/utils/tool-call-tree.d.ts +39 -0
- package/dist/runtime/utils/tool-call-tree.d.ts.map +1 -0
- package/dist/runtime/utils/tool-call-tree.js +85 -0
- package/dist/runtime/utils/tool-call-tree.js.map +1 -0
- package/dist/runtimes/external-store/external-store-adapter.d.ts +29 -2
- package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +2 -5
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +3 -10
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +21 -2
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js +154 -46
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +1 -1
- package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts +4 -2
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +23 -3
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +12 -1
- package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/remote-thread-state.js +107 -14
- package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
- package/dist/runtimes/remote-thread-list/title.d.ts +9 -0
- package/dist/runtimes/remote-thread-list/title.d.ts.map +1 -0
- package/dist/runtimes/remote-thread-list/title.js +6 -0
- package/dist/runtimes/remote-thread-list/title.js.map +1 -0
- package/dist/runtimes/remote-thread-list/types.d.ts +6 -5
- package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +31 -8
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +98 -59
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
- package/dist/store/clients/external-thread.d.ts +1 -1
- package/dist/store/clients/external-thread.d.ts.map +1 -1
- package/dist/store/clients/external-thread.js +85 -103
- package/dist/store/clients/external-thread.js.map +1 -1
- package/dist/store/clients/single-thread-list.d.ts.map +1 -1
- package/dist/store/clients/single-thread-list.js +2 -2
- package/dist/store/clients/single-thread-list.js.map +1 -1
- package/dist/store/clients/suggestions.d.ts.map +1 -1
- package/dist/store/clients/suggestions.js +33 -12
- package/dist/store/clients/suggestions.js.map +1 -1
- package/dist/store/clients/thread-message-client.js +1 -1
- package/dist/store/clients/thread-selection-events.js +1 -1
- package/dist/store/index.d.ts +6 -3
- package/dist/store/index.js +2 -1
- package/dist/store/internal.d.ts +2 -2
- package/dist/store/internal.js +2 -2
- package/dist/store/primitive-predicates.d.ts +4 -1
- package/dist/store/primitive-predicates.d.ts.map +1 -1
- package/dist/store/primitive-predicates.js +9 -1
- package/dist/store/primitive-predicates.js.map +1 -1
- package/dist/store/runtime-clients/composer-runtime-client.js +1 -1
- package/dist/store/runtime-clients/message-runtime-client.js +1 -1
- package/dist/store/runtime-clients/thread-list-item-runtime-client.js +1 -1
- package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-list-runtime-client.js +124 -105
- package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
- package/dist/store/runtime-clients/thread-runtime-client.js +1 -1
- package/dist/store/runtime-clients/useSubscribable.d.ts +3 -1
- package/dist/store/runtime-clients/useSubscribable.d.ts.map +1 -1
- package/dist/store/runtime-clients/useSubscribable.js +1 -1
- package/dist/store/runtime-clients/useSubscribable.js.map +1 -1
- package/dist/store/scope-registration.d.ts +1 -1
- package/dist/store/scopes/composer.d.ts +2 -1
- package/dist/store/scopes/composer.d.ts.map +1 -1
- package/dist/store/scopes/message.d.ts +1 -1
- package/dist/store/scopes/part.d.ts +6 -3
- package/dist/store/scopes/part.d.ts.map +1 -1
- package/dist/store/scopes/queue-item.d.ts +2 -9
- package/dist/store/scopes/queue-item.d.ts.map +1 -1
- package/dist/store/scopes/queue-item.js +0 -6
- package/dist/subscribable/subscribable.d.ts +8 -1
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/subscribable/subscribable.js +24 -16
- package/dist/subscribable/subscribable.js.map +1 -1
- package/dist/types/message.d.ts +47 -4
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/message.js +7 -1
- package/dist/types/message.js.map +1 -1
- package/dist/utils/data-url.d.ts +14 -1
- package/dist/utils/data-url.d.ts.map +1 -1
- package/dist/utils/data-url.js +13 -1
- package/dist/utils/data-url.js.map +1 -1
- package/dist/utils/invoke-user-callback.d.ts +5 -0
- package/dist/utils/invoke-user-callback.d.ts.map +1 -0
- package/dist/utils/invoke-user-callback.js +19 -0
- package/dist/utils/invoke-user-callback.js.map +1 -0
- package/dist/utils/normalizePartStatus.js.map +1 -1
- package/package.json +12 -17
- package/src/index.ts +6 -1
- package/src/internal.ts +20 -0
- package/src/model-context/frame/host.test.ts +91 -7
- package/src/model-context/frame/host.ts +7 -2
- package/src/model-context/frame/provider.test.ts +484 -13
- package/src/model-context/frame/provider.ts +205 -35
- package/src/model-context/interactable-composer-metadata.ts +1 -1
- package/src/model-context/registry.test.ts +44 -0
- package/src/model-context/registry.ts +13 -35
- package/src/model-context/tool-call-text.test.ts +67 -0
- package/src/model-context/tool-call-text.ts +67 -0
- package/src/react/AssistantRuntimeProvider.test.tsx +66 -2
- package/src/react/adapters/LocalStorageThreadListAdapter.tsx +1 -3
- package/src/react/client/InMemoryThreadList.test.tsx +49 -0
- package/src/react/client/InMemoryThreadList.ts +7 -1
- package/src/react/client/Interactables.ts +19 -178
- package/src/react/client/RemoteThreadList.background.test.ts +384 -0
- package/src/react/client/RemoteThreadList.concurrent.test.tsx +274 -0
- package/src/react/client/RemoteThreadList.test.ts +369 -1
- package/src/react/client/RemoteThreadList.ts +320 -142
- package/src/react/client/Tools.ts +7 -1
- package/src/react/index.ts +4 -0
- package/src/react/interactables-legacy/Interactables.ts +20 -177
- package/src/react/interactables-shared/useInteractablePersistenceQueue.test.tsx +161 -0
- package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +206 -0
- package/src/react/model-context/modelContextHooks.test.tsx +131 -0
- package/src/react/model-context/toolbox.test.ts +9 -9
- package/src/react/model-context/toolbox.ts +9 -36
- package/src/react/model-context/useAssistantContext.ts +4 -2
- package/src/react/model-context/useAuiToolOverrides.ts +4 -2
- package/src/react/model-context/useInlineRender.test.tsx +48 -0
- package/src/react/model-context/useInlineRender.ts +14 -10
- package/src/react/primitive-hooks/useMessageError.ts +2 -19
- package/src/react/primitive-hooks/useThreadListLoadMore.ts +2 -3
- package/src/react/primitives/composer/ComposerAttachments.test.tsx +76 -0
- package/src/react/primitives/composer/ComposerAttachments.tsx +9 -4
- package/src/react/primitives/composer/ComposerQueue.test.tsx +72 -0
- package/src/react/primitives/composer/ComposerQueue.tsx +7 -4
- package/src/react/primitives/message/MessageAttachments.test.tsx +107 -37
- package/src/react/primitives/message/MessageAttachments.tsx +10 -7
- package/src/react/primitives/message/MessageGroupedParts.tsx +2 -2
- package/src/react/primitives/message/MessageParts.tsx +3 -3
- package/src/react/primitives/threadList/ThreadListItems.test.tsx +99 -0
- package/src/react/primitives/threadList/ThreadListItems.tsx +8 -5
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +94 -1
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +72 -31
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.switch-delete.test.ts +169 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +140 -124
- package/src/react/runtimes/RemoteThreadResource.ts +1 -4
- package/src/react/runtimes/assistant-transport/runManager.ts +4 -17
- package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +51 -2
- package/src/react/runtimes/assistant-transport/useLatestRef.ts +2 -2
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +45 -0
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +157 -1
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +82 -176
- package/src/react/runtimes/cloud/auiV0.ts +5 -0
- package/src/react/runtimes/cloud/createCloudThreadListAdapter.test.ts +88 -0
- package/src/react/runtimes/cloud/createCloudThreadListAdapter.ts +236 -0
- package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.test.ts +37 -0
- package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.ts +18 -0
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +90 -1
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +33 -238
- package/src/react/runtimes/external-message-converter.test.ts +0 -14
- package/src/react/runtimes/external-message-converter.test.tsx +77 -0
- package/src/react/runtimes/external-message-converter.ts +59 -481
- package/src/react/runtimes/useRemoteThreadListRuntime.concurrent.test.tsx +216 -0
- package/src/react/runtimes/useRemoteThreadListRuntime.ts +24 -6
- package/src/react/types/MessagePartComponentTypes.ts +7 -3
- package/src/react/types/scopes/tools.ts +2 -0
- package/src/runtime/api/composer-runtime.ts +1 -1
- package/src/runtime/api/message-part-runtime.ts +3 -3
- package/src/runtime/api/message-runtime.test.ts +28 -1
- package/src/runtime/api/thread-list-runtime.ts +25 -1
- package/src/runtime/base/base-composer-runtime-core.ts +20 -40
- package/src/runtime/base/base-thread-runtime-core.test.ts +110 -3
- package/src/runtime/base/base-thread-runtime-core.ts +16 -15
- package/src/runtime/base/default-thread-composer-runtime-core.ts +1 -4
- package/src/runtime/interfaces/composer-runtime-core.ts +1 -1
- package/src/runtime/interfaces/thread-list-runtime-core.ts +20 -1
- package/src/runtime/interfaces/thread-runtime-core.ts +18 -2
- package/src/runtime/internal.ts +5 -0
- package/src/runtime/queue/external-thread-queue-adapter.ts +1 -1
- package/src/runtime/queue/message-queue.ts +1 -4
- package/src/runtime/queue/queue-item.ts +10 -0
- package/src/runtime/utils/abortable-thread-load.test.ts +87 -0
- package/src/runtime/utils/abortable-thread-load.ts +53 -0
- package/src/runtime/utils/attachment-add-operations.ts +59 -0
- package/src/runtime/utils/auto-status.test.ts +57 -0
- package/src/runtime/utils/auto-status.ts +46 -1
- package/src/runtime/utils/external-message-conversion.test.ts +210 -0
- package/src/runtime/utils/external-message-conversion.ts +510 -0
- package/src/runtime/utils/external-store-message.ts +2 -0
- package/src/runtime/utils/message-repository-session.test.ts +195 -0
- package/src/runtime/utils/message-repository-session.ts +176 -0
- package/src/runtime/utils/message-repository.ts +7 -4
- package/src/runtime/utils/pending-tool-calls.test.ts +57 -0
- package/src/runtime/utils/pending-tool-calls.ts +35 -0
- package/src/runtime/utils/resolveToolApprovalResponse.test.ts +73 -0
- package/src/runtime/utils/resolveToolApprovalResponse.ts +27 -6
- package/src/runtime/utils/thread-message-like.ts +4 -10
- package/src/runtime/utils/tool-call-tree.test.ts +191 -0
- package/src/runtime/utils/tool-call-tree.ts +97 -0
- package/src/runtimes/external-store/external-store-adapter.ts +38 -2
- package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +6 -14
- package/src/runtimes/external-store/external-store-thread-runtime-core.ts +231 -61
- package/src/runtimes/inert/InertThreadRuntimeCore.ts +1 -1
- package/src/runtimes/local/local-thread-runtime-core.test.ts +201 -4
- package/src/runtimes/local/local-thread-runtime-core.ts +53 -4
- package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +149 -0
- package/src/runtimes/remote-thread-list/remote-thread-state.ts +178 -16
- package/src/runtimes/remote-thread-list/title.ts +3 -0
- package/src/runtimes/remote-thread-list/types.ts +6 -5
- package/src/runtimes/tool-invocations/EDGE_CASES.md +125 -3
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +856 -102
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +145 -89
- package/src/store/clients/external-thread.ts +30 -69
- package/src/store/clients/single-thread-list.ts +4 -1
- package/src/store/clients/suggestions.test.ts +185 -0
- package/src/store/clients/suggestions.ts +42 -35
- package/src/store/index.ts +4 -0
- package/src/store/internal.ts +2 -0
- package/src/store/primitive-predicates.ts +35 -0
- package/src/store/runtime-clients/thread-list-runtime-client.ts +16 -2
- package/src/store/runtime-clients/useSubscribable.ts +8 -2
- package/src/store/scopes/message.ts +1 -1
- package/src/store/scopes/part.ts +6 -3
- package/src/store/scopes/queue-item.ts +2 -9
- package/src/subscribable/subscribable.test.ts +50 -0
- package/src/subscribable/subscribable.ts +33 -21
- package/src/tests/MessageRepository.test.ts +77 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +305 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +78 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-reload.test.ts +52 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-title-race.test.ts +158 -0
- package/src/tests/external-store-optimistic-id.test.ts +79 -0
- package/src/tests/external-store-repository-instance.test.ts +166 -0
- package/src/tests/external-store-thread-runtime-core-adapter.test.ts +186 -16
- package/src/tests/external-store-thread-runtime-core.test.ts +642 -0
- package/src/tests/external-thread-attachments.test.tsx +258 -1
- package/src/tests/remote-thread-list-adapter-switch.test.ts +66 -1
- package/src/tests/single-thread-list-item.test.tsx +47 -0
- package/src/tests/thread-message-like.test.ts +39 -1
- package/src/tests/thread-switch-events.test.tsx +397 -2
- package/src/types/message.ts +58 -5
- package/src/utils/data-url.test.ts +52 -1
- package/src/utils/data-url.ts +21 -0
- package/src/utils/invoke-user-callback.test.ts +82 -0
- package/src/utils/invoke-user-callback.ts +31 -0
- package/src/utils/normalizePartStatus.ts +1 -1
- package/dist/store/scopes/queue-item.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-composer-runtime-core.js","names":["isCreateAttachment","Attachment","CompleteAttachment","CreateAttachment","PendingAttachment","MessageRole","AppendMessage","isMessageNotSentError","QuoteInfo","Unsubscribe","RunConfig","BaseSubscribable","AttachmentAdapter","fileMatchesAccept","AttachmentAddErrorReason","ComposerRuntimeCore","ComposerRuntimeEventCallback","ComposerRuntimeEventPayload","ComposerRuntimeEventType","DictationState","SendOptions","DictationAdapter","QueuePlacement","EMPTY_QUEUE_ITEMS","QueueItemState","generateId","notifyEventListeners","isAttachmentComplete","a","status","type","AttachmentAddOperation","cancelled","attachmentIds","Set","BaseComposerRuntimeCore","isEditing","getAttachmentAdapter","getDictationAdapter","enrichWithComposerMetadata","metadata","custom","Record","message","T","composerMetadata","attachmentAccept","accept","_attachments","attachments","setAttachments","value","_notifySubscribers","canCancel","canSend","isEmpty","text","trim","length","_text","_role","role","_runConfig","runConfig","_quote","undefined","quote","setQuote","setText","_rebaseDictation","_dictation","_dictationBaseText","_currentInterimText","inputDisabled","setRole","setRunConfig","_isSending","_removedDuringSend","_sendGeneration","_attachmentAddOperations","_cancelAttachmentAdd","attachmentId","operation","has","delete","_cancelAllAttachmentAdds","clear","_emptyTextAndAttachments","_onClearAttachments","adapter","pending","filter","Promise","all","map","remove","reset","Object","keys","task","clearAttachments","send","options","_dictationSession","cancel","_cleanupDictation","attachmentTasks","Error","result","originalAttachments","generation","resolvedAttachments","e","allSettled","then","sentIds","id","finalAttachments","Omit","createdAt","Date","content","draft","sendTask","handleSend","error","_restoreUnsentDraft","catch","_notifyEventSubscribers","restoreDraft","retractDraft","attachmentsUntouched","handleCancel","queue","moveQueueItem","_queueItemId","_placement","removeQueueItem","addAttachment","fileOrAttachment","File","name","contentType","err","_safeEmitAttachmentAddError","operations","add","upsertAttachment","idx","findIndex","attachment","slice","lastAttachment","promiseOrGenerator","file","Symbol","asyncIterator","r","reason","String","subscriberError","console","removeAttachment","index","candidate","Session","_dictationUnsubscribes","_dictationSessionIdCounter","_activeDictationSessionId","_isCleaningDictation","dictation","_isActiveSession","sessionId","session","startDictation","unsub","oldSession","stop","disableInputDuringDictation","listen","unsubSpeech","onSpeech","isFinal","needsSeparator","endsWith","transcript","separator","_","rest","push","unsubStart","onSpeechStart","unsubEnd","onSpeechEnd","statusInterval","setInterval","clearInterval","stopDictation","cleanup","isStaleSession","_eventSubscribers","Map","payload","event","E","subscribers","get","unstable_on","callback","wrapped","set"],"sources":["../../../src/runtime/base/base-composer-runtime-core.ts"],"sourcesContent":["import {\n isCreateAttachment,\n type Attachment,\n type CompleteAttachment,\n type CreateAttachment,\n type PendingAttachment,\n} from \"../../types/attachment\";\nimport type { MessageRole, AppendMessage } from \"../../types/message\";\nimport { isMessageNotSentError } from \"../../types/error\";\nimport type { QuoteInfo } from \"../../types/quote\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { RunConfig } from \"../../types/message\";\nimport { BaseSubscribable } from \"../../subscribable/subscribable\";\nimport {\n type AttachmentAdapter,\n fileMatchesAccept,\n} from \"../../adapters/attachment\";\nimport type {\n AttachmentAddErrorReason,\n ComposerRuntimeCore,\n ComposerRuntimeEventCallback,\n ComposerRuntimeEventPayload,\n ComposerRuntimeEventType,\n DictationState,\n SendOptions,\n} from \"../interfaces/composer-runtime-core\";\nimport type { DictationAdapter } from \"../../adapters/speech\";\nimport type { QueuePlacement } from \"../queue/external-thread-queue-adapter\";\nimport {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../store/scopes/queue-item\";\nimport { generateId } from \"../../utils/id\";\nimport { notifyEventListeners } from \"../../utils/notify-event-listeners\";\n\nconst isAttachmentComplete = (a: Attachment): a is CompleteAttachment =>\n a.status.type === \"complete\";\n\ntype AttachmentAddOperation = {\n cancelled: boolean;\n attachmentIds: Set<string>;\n};\n\nexport abstract class BaseComposerRuntimeCore\n extends BaseSubscribable\n implements ComposerRuntimeCore\n{\n public readonly isEditing = true;\n\n protected abstract getAttachmentAdapter(): AttachmentAdapter | undefined;\n protected abstract getDictationAdapter(): DictationAdapter | undefined;\n\n protected enrichWithComposerMetadata<\n T extends { metadata?: { custom?: Record<string, unknown> } },\n >(message: T, composerMetadata: Record<string, unknown> | undefined): T {\n if (!composerMetadata) return message;\n return {\n ...message,\n metadata: {\n ...message.metadata,\n custom: { ...message.metadata?.custom, ...composerMetadata },\n },\n } as T;\n }\n\n public get attachmentAccept(): string {\n return this.getAttachmentAdapter()?.accept ?? \"*\";\n }\n\n private _attachments: readonly Attachment[] = [];\n public get attachments() {\n return this._attachments;\n }\n\n protected setAttachments(value: readonly Attachment[]) {\n this._attachments = value;\n this._notifySubscribers();\n }\n\n public abstract get canCancel(): boolean;\n public abstract get canSend(): boolean;\n\n public get isEmpty() {\n return !this.text.trim() && !this.attachments.length;\n }\n\n private _text = \"\";\n\n get text() {\n return this._text;\n }\n\n private _role: MessageRole = \"user\";\n\n get role() {\n return this._role;\n }\n\n private _runConfig: RunConfig = {};\n\n get runConfig() {\n return this._runConfig;\n }\n\n private _quote: QuoteInfo | undefined = undefined;\n\n get quote() {\n return this._quote;\n }\n\n public setQuote(quote: QuoteInfo | undefined) {\n if (this._quote === quote) return;\n\n this._quote = quote;\n this._notifySubscribers();\n }\n\n public setText(value: string) {\n if (this._text === value) return;\n\n this._text = value;\n this._rebaseDictation(value);\n this._notifySubscribers();\n }\n\n // A live dictation session appends to the text it last saw, so any write\n // that bypasses `setText` has to move that baseline or the next transcript\n // overwrites what was just written.\n private _rebaseDictation(value: string) {\n if (!this._dictation) return;\n\n this._dictationBaseText = value;\n this._currentInterimText = \"\";\n const { status, inputDisabled } = this._dictation;\n this._dictation = inputDisabled ? { status, inputDisabled } : { status };\n }\n\n public setRole(role: MessageRole) {\n if (this._role === role) return;\n\n this._role = role;\n this._notifySubscribers();\n }\n\n public setRunConfig(runConfig: RunConfig) {\n if (this._runConfig === runConfig) return;\n\n this._runConfig = runConfig;\n this._notifySubscribers();\n }\n\n protected _isSending = false;\n private _removedDuringSend = new Set<string>();\n private _sendGeneration = 0;\n private _attachmentAddOperations = new Set<AttachmentAddOperation>();\n\n private _cancelAttachmentAdd(attachmentId: string) {\n for (const operation of [...this._attachmentAddOperations]) {\n if (!operation.attachmentIds.has(attachmentId)) continue;\n operation.cancelled = true;\n this._attachmentAddOperations.delete(operation);\n }\n }\n\n private _cancelAllAttachmentAdds() {\n for (const operation of this._attachmentAddOperations) {\n operation.cancelled = true;\n }\n this._attachmentAddOperations.clear();\n }\n\n private _emptyTextAndAttachments() {\n this._attachments = [];\n this._text = \"\";\n this._notifySubscribers();\n }\n\n private async _onClearAttachments() {\n const adapter = this.getAttachmentAdapter();\n if (adapter) {\n const pending = this._attachments.filter((a) => !isAttachmentComplete(a));\n await Promise.all(pending.map((a) => adapter.remove(a)));\n }\n }\n\n public async reset() {\n this._cancelAllAttachmentAdds();\n\n // A send whose adapter never settles must not brick the composer; reset is\n // the escape hatch that releases the in-flight lock. Bumping the generation\n // invalidates that send entirely so a late-settling upload can neither\n // append the discarded draft nor touch a newer send's lock.\n this._sendGeneration++;\n this._isSending = false;\n this._removedDuringSend.clear();\n\n if (\n this._attachments.length === 0 &&\n this._text === \"\" &&\n this._role === \"user\" &&\n Object.keys(this._runConfig).length === 0 &&\n this._quote === undefined\n ) {\n return;\n }\n\n this._role = \"user\";\n this._runConfig = {};\n this._quote = undefined;\n\n const task = this._onClearAttachments();\n this._emptyTextAndAttachments();\n await task;\n }\n\n public async clearAttachments() {\n this._cancelAllAttachmentAdds();\n const task = this._onClearAttachments();\n this.setAttachments([]);\n\n await task;\n }\n\n public async send(options?: SendOptions) {\n if (!this.canSend || this._isSending) return;\n\n if (this._dictationSession) {\n this._dictationSession.cancel();\n this._cleanupDictation();\n }\n\n const adapter = this.getAttachmentAdapter();\n const attachmentTasks = this.attachments.map(async (a) => {\n if (isAttachmentComplete(a)) return a;\n if (!adapter) throw new Error(\"Attachments are not supported\");\n const result = await adapter.send(a);\n return result as CompleteAttachment;\n });\n\n const originalAttachments = this.attachments;\n const text = this.text;\n const quote = this._quote;\n const role = this.role;\n const runConfig = this.runConfig;\n this._quote = undefined;\n this._text = \"\";\n this._isSending = true;\n const generation = ++this._sendGeneration;\n this._notifySubscribers();\n\n let resolvedAttachments: CompleteAttachment[];\n try {\n resolvedAttachments = await Promise.all(attachmentTasks);\n } catch (e) {\n if (generation === this._sendGeneration) {\n if (!this.text.trim() && this._quote === undefined) {\n this._text = text;\n this._rebaseDictation(text);\n this._quote = quote;\n this._notifySubscribers();\n }\n // Promise.all rejects on the first failure, but sibling uploads from\n // this batch keep running; the send rejects immediately while the\n // retry lock is held until they settle, or a retry could re-send\n // attachments that are still in flight.\n void Promise.allSettled(attachmentTasks).then(() => {\n if (generation !== this._sendGeneration) return;\n this._removedDuringSend.clear();\n this._isSending = false;\n this._notifySubscribers();\n });\n }\n throw e;\n }\n\n // A reset during the upload discarded this send's draft; the settled\n // uploads must not append it or touch the lock a newer send may own.\n if (generation !== this._sendGeneration) return;\n\n // Drop by id, not wholesale: the user may have added or removed chips while\n // the upload was in flight.\n const sentIds = new Set(originalAttachments.map((a) => a.id));\n this._attachments = this._attachments.filter((a) => !sentIds.has(a.id));\n this._isSending = false;\n this._notifySubscribers();\n\n // An attachment removed mid-upload can't be cancelled, but it can still be\n // dropped from the outgoing message instead of silently being sent anyway.\n const finalAttachments = resolvedAttachments.filter(\n (a) => !this._removedDuringSend.has(a.id),\n );\n this._removedDuringSend.clear();\n\n const message: Omit<AppendMessage, \"parentId\" | \"sourceId\"> = {\n createdAt: new Date(),\n role,\n content: text ? [{ type: \"text\", text }] : [],\n attachments: finalAttachments,\n runConfig,\n metadata: { custom: { ...(quote ? { quote } : {}) } },\n };\n\n const draft = { text, quote, attachments: finalAttachments };\n let sendTask: void | Promise<void>;\n try {\n sendTask = this.handleSend(message, options);\n } catch (error) {\n this._restoreUnsentDraft(error, generation, draft);\n throw error;\n }\n if (sendTask)\n void sendTask.catch((error) => {\n this._restoreUnsentDraft(error, generation, draft);\n });\n this._notifyEventSubscribers(\"send\", {});\n }\n\n /**\n * Take a message back into the composer when it has nowhere else to live:\n * a send the runtime never dispatched, or a message a cancelled run is\n * removing from the thread. Reports whether the composer accepted it, so a\n * caller that is also removing the message can keep it instead of dropping\n * it. Refused, and left untouched, while the composer holds anything of its\n * own.\n */\n public restoreDraft(draft: {\n text: string;\n quote?: QuoteInfo | undefined;\n attachments?: readonly Attachment[] | undefined;\n }): boolean {\n if (\n this._text.trim() ||\n this._quote !== undefined ||\n this._attachments.length > 0\n )\n return false;\n\n this._text = draft.text;\n this._rebaseDictation(draft.text);\n this._quote = draft.quote;\n this._attachments = draft.attachments ?? [];\n this._notifySubscribers();\n return true;\n }\n\n /**\n * Inverse of `restoreDraft`: clears the composer while it still holds\n * exactly the given draft. A draft the user has edited since is left\n * untouched.\n */\n public retractDraft(draft: {\n text: string;\n quote?: QuoteInfo | undefined;\n attachments?: readonly Attachment[] | undefined;\n }): void {\n const attachmentsUntouched =\n draft.attachments !== undefined\n ? this._attachments === draft.attachments\n : this._attachments.length === 0;\n if (\n this._text !== draft.text ||\n this._quote !== draft.quote ||\n !attachmentsUntouched\n )\n return;\n\n this._text = \"\";\n this._rebaseDictation(\"\");\n this._quote = undefined;\n this._attachments = [];\n this._notifySubscribers();\n }\n\n // The generation check is what a reset and a later send use to invalidate a\n // draft, so of several queued drafts only the most recent one is still\n // restorable.\n private _restoreUnsentDraft(\n error: unknown,\n generation: number,\n draft: {\n text: string;\n quote: QuoteInfo | undefined;\n attachments: readonly CompleteAttachment[];\n },\n ) {\n if (!isMessageNotSentError(error)) return;\n if (generation !== this._sendGeneration) return;\n this.restoreDraft(draft);\n }\n\n public cancel() {\n this.handleCancel();\n }\n\n public get queue(): readonly QueueItemState[] {\n return EMPTY_QUEUE_ITEMS;\n }\n\n public moveQueueItem(\n _queueItemId: string,\n _placement: QueuePlacement,\n ): void {}\n public removeQueueItem(_queueItemId: string): void {}\n\n protected abstract handleSend(\n message: Omit<AppendMessage, \"parentId\" | \"sourceId\">,\n options?: SendOptions,\n ): void | Promise<void>;\n protected abstract handleCancel(): void;\n\n async addAttachment(fileOrAttachment: File | CreateAttachment) {\n if (isCreateAttachment(fileOrAttachment)) {\n const adapter = this.getAttachmentAdapter();\n if (\n adapter &&\n !fileMatchesAccept(\n {\n name: fileOrAttachment.name,\n type: fileOrAttachment.contentType ?? \"\",\n },\n adapter.accept,\n )\n ) {\n const message = `File type ${fileOrAttachment.contentType || \"unknown\"} is not accepted. Accepted types: ${adapter.accept}`;\n const err = new Error(message);\n this._safeEmitAttachmentAddError(\n \"not-accepted\",\n message,\n undefined,\n err,\n );\n throw err;\n }\n\n const a: CompleteAttachment = {\n id: fileOrAttachment.id ?? generateId(),\n type: fileOrAttachment.type ?? \"document\",\n name: fileOrAttachment.name,\n contentType: fileOrAttachment.contentType,\n content: fileOrAttachment.content,\n status: { type: \"complete\" },\n };\n this._attachments = [...this._attachments, a];\n this._notifySubscribers();\n this._notifyEventSubscribers(\"attachmentAdd\", {});\n return;\n }\n\n const adapter = this.getAttachmentAdapter();\n if (!adapter) {\n const message = \"Attachments are not supported\";\n const err = new Error(message);\n this._safeEmitAttachmentAddError(\"no-adapter\", message, undefined, err);\n throw err;\n }\n\n if (\n !fileMatchesAccept(\n { name: fileOrAttachment.name, type: fileOrAttachment.type },\n adapter.accept,\n )\n ) {\n const message = `File type ${fileOrAttachment.type || \"unknown\"} is not accepted. Accepted types: ${adapter.accept}`;\n const err = new Error(message);\n this._safeEmitAttachmentAddError(\"not-accepted\", message, undefined, err);\n throw err;\n }\n\n const operation: AttachmentAddOperation = {\n cancelled: false,\n attachmentIds: new Set(),\n };\n const operations = this._attachmentAddOperations;\n operations.add(operation);\n const upsertAttachment = (a: PendingAttachment) => {\n if (operation.cancelled) return false;\n\n operation.attachmentIds.add(a.id);\n const idx = this._attachments.findIndex(\n (attachment) => attachment.id === a.id,\n );\n if (idx !== -1)\n this._attachments = [\n ...this._attachments.slice(0, idx),\n a,\n ...this._attachments.slice(idx + 1),\n ];\n else {\n this._attachments = [...this._attachments, a];\n }\n\n this._notifySubscribers();\n return true;\n };\n let lastAttachment: PendingAttachment | undefined;\n try {\n const promiseOrGenerator = adapter.add({ file: fileOrAttachment });\n if (Symbol.asyncIterator in promiseOrGenerator) {\n for await (const r of promiseOrGenerator) {\n lastAttachment = r;\n if (!upsertAttachment(r)) break;\n }\n } else {\n lastAttachment = await promiseOrGenerator;\n upsertAttachment(lastAttachment);\n }\n } catch (e) {\n if (operation.cancelled) return;\n if (lastAttachment) {\n upsertAttachment({\n ...lastAttachment,\n status: {\n type: \"incomplete\",\n reason: \"error\",\n message: e instanceof Error ? e.message : String(e),\n },\n });\n }\n this._safeEmitAttachmentAddError(\n \"adapter-error\",\n e instanceof Error ? e.message : String(e),\n lastAttachment?.id,\n e instanceof Error ? e : undefined,\n );\n throw e;\n } finally {\n operations.delete(operation);\n }\n\n if (operation.cancelled) return;\n if (\n lastAttachment?.status.type === \"incomplete\" &&\n lastAttachment.status.reason === \"error\"\n ) {\n this._safeEmitAttachmentAddError(\n \"adapter-error\",\n lastAttachment.status.message ??\n \"Attachment upload did not complete successfully.\",\n lastAttachment.id,\n );\n } else {\n this._notifyEventSubscribers(\"attachmentAdd\", {});\n }\n }\n\n private _safeEmitAttachmentAddError(\n reason: AttachmentAddErrorReason,\n message: string,\n attachmentId?: string,\n error?: Error,\n ) {\n try {\n this._notifyEventSubscribers(\"attachmentAddError\", {\n reason,\n message,\n ...(attachmentId !== undefined && { attachmentId }),\n ...(error !== undefined && { error }),\n });\n } catch (subscriberError) {\n console.error(\n \"[assistant-ui] attachmentAddError subscriber threw:\",\n subscriberError,\n );\n }\n }\n\n async removeAttachment(attachmentId: string) {\n const index = this._attachments.findIndex((a) => a.id === attachmentId);\n if (index === -1) throw new Error(\"Attachment not found\");\n const attachment = this._attachments[index]!;\n\n this._cancelAttachmentAdd(attachmentId);\n\n // A send in flight may already be uploading this attachment; the upload\n // can't be cancelled, so mark it to be dropped from the outgoing message\n // before any await gives the upload a chance to settle first.\n if (this._isSending) this._removedDuringSend.add(attachmentId);\n\n if (!isAttachmentComplete(attachment)) {\n const adapter = this.getAttachmentAdapter();\n if (!adapter) throw new Error(\"Attachments are not supported\");\n try {\n await adapter.remove(attachment);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this._attachments = this._attachments.map((candidate) =>\n candidate.id === attachmentId && !isAttachmentComplete(candidate)\n ? {\n ...candidate,\n status: { type: \"incomplete\", reason: \"error\", message },\n }\n : candidate,\n );\n this._notifySubscribers();\n throw error;\n }\n }\n this._attachments = this._attachments.filter((a) => a.id !== attachmentId);\n this._notifySubscribers();\n }\n\n private _dictation: DictationState | undefined;\n private _dictationSession: DictationAdapter.Session | undefined;\n private _dictationUnsubscribes: Unsubscribe[] = [];\n private _dictationBaseText = \"\";\n private _currentInterimText = \"\";\n private _dictationSessionIdCounter = 0;\n private _activeDictationSessionId: number | undefined;\n private _isCleaningDictation = false;\n\n public get dictation(): DictationState | undefined {\n return this._dictation;\n }\n\n private _isActiveSession(\n sessionId: number,\n session: DictationAdapter.Session,\n ): boolean {\n return (\n this._activeDictationSessionId === sessionId &&\n this._dictationSession === session\n );\n }\n\n public startDictation(): void {\n const adapter = this.getDictationAdapter();\n if (!adapter) {\n throw new Error(\"Dictation adapter not configured\");\n }\n\n if (this._dictationSession) {\n for (const unsub of this._dictationUnsubscribes) {\n unsub();\n }\n this._dictationUnsubscribes = [];\n const oldSession = this._dictationSession;\n oldSession.stop().catch(() => {});\n this._dictationSession = undefined;\n }\n\n const inputDisabled = adapter.disableInputDuringDictation ?? false;\n\n this._dictationBaseText = this._text;\n this._currentInterimText = \"\";\n\n const session = adapter.listen();\n this._dictationSession = session;\n const sessionId = ++this._dictationSessionIdCounter;\n this._activeDictationSessionId = sessionId;\n this._dictation = { status: session.status, inputDisabled };\n this._notifySubscribers();\n\n const unsubSpeech = session.onSpeech((result) => {\n if (!this._isActiveSession(sessionId, session)) return;\n const isFinal = result.isFinal !== false;\n\n const needsSeparator =\n this._dictationBaseText &&\n !this._dictationBaseText.endsWith(\" \") &&\n result.transcript;\n const separator = needsSeparator ? \" \" : \"\";\n\n if (isFinal) {\n this._dictationBaseText =\n this._dictationBaseText + separator + result.transcript;\n this._currentInterimText = \"\";\n this._text = this._dictationBaseText;\n\n if (this._dictation) {\n const { transcript: _, ...rest } = this._dictation;\n this._dictation = rest;\n }\n this._notifySubscribers();\n } else {\n this._currentInterimText = separator + result.transcript;\n this._text = this._dictationBaseText + this._currentInterimText;\n\n if (this._dictation) {\n this._dictation = {\n ...this._dictation,\n transcript: result.transcript,\n };\n }\n this._notifySubscribers();\n }\n });\n this._dictationUnsubscribes.push(unsubSpeech);\n\n const unsubStart = session.onSpeechStart(() => {\n if (!this._isActiveSession(sessionId, session)) return;\n\n this._dictation = {\n status: { type: \"running\" },\n inputDisabled,\n ...(this._dictation?.transcript && {\n transcript: this._dictation.transcript,\n }),\n };\n this._notifySubscribers();\n });\n this._dictationUnsubscribes.push(unsubStart);\n\n const unsubEnd = session.onSpeechEnd(() => {\n this._cleanupDictation({ sessionId });\n });\n this._dictationUnsubscribes.push(unsubEnd);\n\n const statusInterval = setInterval(() => {\n if (!this._isActiveSession(sessionId, session)) return;\n\n if (session.status.type === \"ended\") {\n this._cleanupDictation({ sessionId });\n }\n }, 100);\n this._dictationUnsubscribes.push(() => clearInterval(statusInterval));\n }\n\n public stopDictation(): void {\n if (!this._dictationSession) return;\n\n const session = this._dictationSession;\n const sessionId = this._activeDictationSessionId;\n const cleanup = () => this._cleanupDictation({ sessionId });\n void session.stop().then(cleanup, cleanup);\n }\n\n private _cleanupDictation(options?: { sessionId: number | undefined }): void {\n const isStaleSession =\n options?.sessionId !== undefined &&\n options.sessionId !== this._activeDictationSessionId;\n if (isStaleSession || this._isCleaningDictation) return;\n\n this._isCleaningDictation = true;\n try {\n for (const unsub of this._dictationUnsubscribes) {\n unsub();\n }\n this._dictationUnsubscribes = [];\n this._dictationSession = undefined;\n this._activeDictationSessionId = undefined;\n this._dictation = undefined;\n this._dictationBaseText = \"\";\n this._currentInterimText = \"\";\n this._notifySubscribers();\n } finally {\n this._isCleaningDictation = false;\n }\n }\n\n private _eventSubscribers = new Map<\n ComposerRuntimeEventType,\n Set<(payload?: unknown) => void>\n >();\n\n protected _notifyEventSubscribers<E extends ComposerRuntimeEventType>(\n event: E,\n payload: ComposerRuntimeEventPayload[E],\n ) {\n const subscribers = this._eventSubscribers.get(event);\n if (!subscribers) return;\n\n notifyEventListeners(subscribers, payload, `Composer runtime \"${event}\"`);\n }\n\n public unstable_on<E extends ComposerRuntimeEventType>(\n event: E,\n callback: ComposerRuntimeEventCallback<E>,\n ) {\n const wrapped = callback as (payload?: unknown) => void;\n let subscribers = this._eventSubscribers.get(event);\n if (!subscribers) {\n subscribers = new Set();\n this._eventSubscribers.set(event, subscribers);\n }\n subscribers.add(wrapped);\n\n return () => {\n this._eventSubscribers.get(event)?.delete(wrapped);\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base-composer-runtime-core.js","names":["isCreateAttachment","Attachment","CompleteAttachment","CreateAttachment","PendingAttachment","MessageRole","AppendMessage","isMessageNotSentError","QuoteInfo","Unsubscribe","RunConfig","BaseSubscribable","AttachmentAdapter","fileMatchesAccept","AttachmentAddErrorReason","ComposerRuntimeCore","ComposerRuntimeEventCallback","ComposerRuntimeEventPayload","ComposerRuntimeEventType","DictationState","SendOptions","DictationAdapter","QueuePlacement","EMPTY_QUEUE_ITEMS","QueueItemState","generateId","notifyEventListeners","AttachmentAddOperations","drainAttachmentAdd","isAttachmentComplete","a","status","type","BaseComposerRuntimeCore","isEditing","getAttachmentAdapter","getDictationAdapter","enrichWithComposerMetadata","metadata","custom","Record","message","T","composerMetadata","attachmentAccept","accept","_attachments","attachments","setAttachments","value","_notifySubscribers","canCancel","canSend","isEmpty","text","trim","length","_text","_role","role","_runConfig","runConfig","_quote","undefined","quote","setQuote","setText","_rebaseDictation","_dictation","_dictationBaseText","_currentInterimText","inputDisabled","setRole","setRunConfig","_isSending","_removedDuringSend","Set","_sendGeneration","_attachmentAddOperations","_cancelAttachmentAdd","attachmentId","cancel","_cancelAllAttachmentAdds","cancelAll","_emptyTextAndAttachments","_onClearAttachments","adapter","pending","filter","Promise","all","map","remove","reset","clear","Object","keys","task","clearAttachments","send","options","_dictationSession","_cleanupDictation","attachmentTasks","Error","result","originalAttachments","generation","resolvedAttachments","e","allSettled","then","sentIds","id","has","finalAttachments","Omit","createdAt","Date","content","draft","sendTask","handleSend","error","_restoreUnsentDraft","catch","_notifyEventSubscribers","restoreDraft","retractDraft","attachmentsUntouched","handleCancel","queue","moveQueueItem","_queueItemId","_placement","removeQueueItem","addAttachment","fileOrAttachment","File","name","contentType","err","_safeEmitAttachmentAddError","operation","start","upsertAttachment","idx","findIndex","attachment","slice","lastAttachment","add","file","isCancelled","reason","String","finish","subscriberError","console","removeAttachment","index","candidate","Session","_dictationUnsubscribes","_dictationSessionIdCounter","_activeDictationSessionId","_isCleaningDictation","dictation","_isActiveSession","sessionId","session","startDictation","unsub","oldSession","stop","disableInputDuringDictation","listen","unsubSpeech","onSpeech","isFinal","needsSeparator","endsWith","transcript","separator","_","rest","push","unsubStart","onSpeechStart","unsubEnd","onSpeechEnd","statusInterval","setInterval","clearInterval","stopDictation","cleanup","isStaleSession","_eventSubscribers","Map","payload","event","E","subscribers","get","unstable_on","callback","wrapped","set","delete"],"sources":["../../../src/runtime/base/base-composer-runtime-core.ts"],"sourcesContent":["import {\n isCreateAttachment,\n type Attachment,\n type CompleteAttachment,\n type CreateAttachment,\n type PendingAttachment,\n} from \"../../types/attachment\";\nimport type { MessageRole, AppendMessage } from \"../../types/message\";\nimport { isMessageNotSentError } from \"../../types/error\";\nimport type { QuoteInfo } from \"../../types/quote\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { RunConfig } from \"../../types/message\";\nimport { BaseSubscribable } from \"../../subscribable/subscribable\";\nimport {\n type AttachmentAdapter,\n fileMatchesAccept,\n} from \"../../adapters/attachment\";\nimport type {\n AttachmentAddErrorReason,\n ComposerRuntimeCore,\n ComposerRuntimeEventCallback,\n ComposerRuntimeEventPayload,\n ComposerRuntimeEventType,\n DictationState,\n SendOptions,\n} from \"../interfaces/composer-runtime-core\";\nimport type { DictationAdapter } from \"../../adapters/speech\";\nimport type { QueuePlacement } from \"../queue/external-thread-queue-adapter\";\nimport { EMPTY_QUEUE_ITEMS, type QueueItemState } from \"../queue/queue-item\";\nimport { generateId } from \"../../utils/id\";\nimport { notifyEventListeners } from \"../../utils/notify-event-listeners\";\nimport {\n AttachmentAddOperations,\n drainAttachmentAdd,\n} from \"../utils/attachment-add-operations\";\n\nconst isAttachmentComplete = (a: Attachment): a is CompleteAttachment =>\n a.status.type === \"complete\";\n\nexport abstract class BaseComposerRuntimeCore\n extends BaseSubscribable\n implements ComposerRuntimeCore\n{\n public readonly isEditing = true;\n\n protected abstract getAttachmentAdapter(): AttachmentAdapter | undefined;\n protected abstract getDictationAdapter(): DictationAdapter | undefined;\n\n protected enrichWithComposerMetadata<\n T extends { metadata?: { custom?: Record<string, unknown> } },\n >(message: T, composerMetadata: Record<string, unknown> | undefined): T {\n if (!composerMetadata) return message;\n return {\n ...message,\n metadata: {\n ...message.metadata,\n custom: { ...message.metadata?.custom, ...composerMetadata },\n },\n } as T;\n }\n\n public get attachmentAccept(): string {\n return this.getAttachmentAdapter()?.accept ?? \"*\";\n }\n\n private _attachments: readonly Attachment[] = [];\n public get attachments() {\n return this._attachments;\n }\n\n protected setAttachments(value: readonly Attachment[]) {\n this._attachments = value;\n this._notifySubscribers();\n }\n\n public abstract get canCancel(): boolean;\n public abstract get canSend(): boolean;\n\n public get isEmpty() {\n return !this.text.trim() && !this.attachments.length;\n }\n\n private _text = \"\";\n\n get text() {\n return this._text;\n }\n\n private _role: MessageRole = \"user\";\n\n get role() {\n return this._role;\n }\n\n private _runConfig: RunConfig = {};\n\n get runConfig() {\n return this._runConfig;\n }\n\n private _quote: QuoteInfo | undefined = undefined;\n\n get quote() {\n return this._quote;\n }\n\n public setQuote(quote: QuoteInfo | undefined) {\n if (this._quote === quote) return;\n\n this._quote = quote;\n this._notifySubscribers();\n }\n\n public setText(value: string) {\n if (this._text === value) return;\n\n this._text = value;\n this._rebaseDictation(value);\n this._notifySubscribers();\n }\n\n // A live dictation session appends to the text it last saw, so any write\n // that bypasses `setText` has to move that baseline or the next transcript\n // overwrites what was just written.\n private _rebaseDictation(value: string) {\n if (!this._dictation) return;\n\n this._dictationBaseText = value;\n this._currentInterimText = \"\";\n const { status, inputDisabled } = this._dictation;\n this._dictation = inputDisabled ? { status, inputDisabled } : { status };\n }\n\n public setRole(role: MessageRole) {\n if (this._role === role) return;\n\n this._role = role;\n this._notifySubscribers();\n }\n\n public setRunConfig(runConfig: RunConfig) {\n if (this._runConfig === runConfig) return;\n\n this._runConfig = runConfig;\n this._notifySubscribers();\n }\n\n protected _isSending = false;\n private _removedDuringSend = new Set<string>();\n private _sendGeneration = 0;\n private _attachmentAddOperations = new AttachmentAddOperations();\n\n private _cancelAttachmentAdd(attachmentId: string) {\n this._attachmentAddOperations.cancel(attachmentId);\n }\n\n private _cancelAllAttachmentAdds() {\n this._attachmentAddOperations.cancelAll();\n }\n\n private _emptyTextAndAttachments() {\n this._attachments = [];\n this._text = \"\";\n this._notifySubscribers();\n }\n\n private async _onClearAttachments() {\n const adapter = this.getAttachmentAdapter();\n if (adapter) {\n const pending = this._attachments.filter((a) => !isAttachmentComplete(a));\n await Promise.all(pending.map((a) => adapter.remove(a)));\n }\n }\n\n public async reset() {\n this._cancelAllAttachmentAdds();\n\n // A send whose adapter never settles must not brick the composer; reset is\n // the escape hatch that releases the in-flight lock. Bumping the generation\n // invalidates that send entirely so a late-settling upload can neither\n // append the discarded draft nor touch a newer send's lock.\n this._sendGeneration++;\n this._isSending = false;\n this._removedDuringSend.clear();\n\n if (\n this._attachments.length === 0 &&\n this._text === \"\" &&\n this._role === \"user\" &&\n Object.keys(this._runConfig).length === 0 &&\n this._quote === undefined\n ) {\n return;\n }\n\n this._role = \"user\";\n this._runConfig = {};\n this._quote = undefined;\n\n const task = this._onClearAttachments();\n this._emptyTextAndAttachments();\n await task;\n }\n\n public async clearAttachments() {\n this._cancelAllAttachmentAdds();\n const task = this._onClearAttachments();\n this.setAttachments([]);\n\n await task;\n }\n\n public async send(options?: SendOptions) {\n if (!this.canSend || this._isSending) return;\n\n if (this._dictationSession) {\n this._dictationSession.cancel();\n this._cleanupDictation();\n }\n\n const adapter = this.getAttachmentAdapter();\n const attachmentTasks = this.attachments.map(async (a) => {\n if (isAttachmentComplete(a)) return a;\n if (!adapter) throw new Error(\"Attachments are not supported\");\n const result = await adapter.send(a);\n return result as CompleteAttachment;\n });\n\n const originalAttachments = this.attachments;\n const text = this.text;\n const quote = this._quote;\n const role = this.role;\n const runConfig = this.runConfig;\n this._quote = undefined;\n this._text = \"\";\n this._isSending = true;\n const generation = ++this._sendGeneration;\n this._notifySubscribers();\n\n let resolvedAttachments: CompleteAttachment[];\n try {\n resolvedAttachments = await Promise.all(attachmentTasks);\n } catch (e) {\n if (generation === this._sendGeneration) {\n if (!this.text.trim() && this._quote === undefined) {\n this._text = text;\n this._rebaseDictation(text);\n this._quote = quote;\n this._notifySubscribers();\n }\n // Promise.all rejects on the first failure, but sibling uploads from\n // this batch keep running; the send rejects immediately while the\n // retry lock is held until they settle, or a retry could re-send\n // attachments that are still in flight.\n void Promise.allSettled(attachmentTasks).then(() => {\n if (generation !== this._sendGeneration) return;\n this._removedDuringSend.clear();\n this._isSending = false;\n this._notifySubscribers();\n });\n }\n throw e;\n }\n\n // A reset during the upload discarded this send's draft; the settled\n // uploads must not append it or touch the lock a newer send may own.\n if (generation !== this._sendGeneration) return;\n\n // Drop by id, not wholesale: the user may have added or removed chips while\n // the upload was in flight.\n const sentIds = new Set(originalAttachments.map((a) => a.id));\n this._attachments = this._attachments.filter((a) => !sentIds.has(a.id));\n this._isSending = false;\n this._notifySubscribers();\n\n // An attachment removed mid-upload can't be cancelled, but it can still be\n // dropped from the outgoing message instead of silently being sent anyway.\n const finalAttachments = resolvedAttachments.filter(\n (a) => !this._removedDuringSend.has(a.id),\n );\n this._removedDuringSend.clear();\n\n const message: Omit<AppendMessage, \"parentId\" | \"sourceId\"> = {\n createdAt: new Date(),\n role,\n content: text ? [{ type: \"text\", text }] : [],\n attachments: finalAttachments,\n runConfig,\n metadata: { custom: { ...(quote ? { quote } : {}) } },\n };\n\n const draft = { text, quote, attachments: finalAttachments };\n let sendTask: void | Promise<void>;\n try {\n sendTask = this.handleSend(message, options);\n } catch (error) {\n this._restoreUnsentDraft(error, generation, draft);\n throw error;\n }\n if (sendTask)\n void sendTask.catch((error) => {\n this._restoreUnsentDraft(error, generation, draft);\n });\n this._notifyEventSubscribers(\"send\", {});\n }\n\n /**\n * Take a message back into the composer when it has nowhere else to live:\n * a send the runtime never dispatched, or a message a cancelled run is\n * removing from the thread. Reports whether the composer accepted it, so a\n * caller that is also removing the message can keep it instead of dropping\n * it. Refused, and left untouched, while the composer holds anything of its\n * own.\n */\n public restoreDraft(draft: {\n text: string;\n quote?: QuoteInfo | undefined;\n attachments?: readonly Attachment[] | undefined;\n }): boolean {\n if (\n this._text.trim() ||\n this._quote !== undefined ||\n this._attachments.length > 0\n )\n return false;\n\n this._text = draft.text;\n this._rebaseDictation(draft.text);\n this._quote = draft.quote;\n this._attachments = draft.attachments ?? [];\n this._notifySubscribers();\n return true;\n }\n\n /**\n * Inverse of `restoreDraft`: clears the composer while it still holds\n * exactly the given draft. A draft the user has edited since is left\n * untouched.\n */\n public retractDraft(draft: {\n text: string;\n quote?: QuoteInfo | undefined;\n attachments?: readonly Attachment[] | undefined;\n }): void {\n const attachmentsUntouched =\n draft.attachments !== undefined\n ? this._attachments === draft.attachments\n : this._attachments.length === 0;\n if (\n this._text !== draft.text ||\n this._quote !== draft.quote ||\n !attachmentsUntouched\n )\n return;\n\n this._text = \"\";\n this._rebaseDictation(\"\");\n this._quote = undefined;\n this._attachments = [];\n this._notifySubscribers();\n }\n\n // The generation check is what a reset and a later send use to invalidate a\n // draft, so of several queued drafts only the most recent one is still\n // restorable.\n private _restoreUnsentDraft(\n error: unknown,\n generation: number,\n draft: {\n text: string;\n quote: QuoteInfo | undefined;\n attachments: readonly CompleteAttachment[];\n },\n ) {\n if (!isMessageNotSentError(error)) return;\n if (generation !== this._sendGeneration) return;\n this.restoreDraft(draft);\n }\n\n public cancel() {\n this.handleCancel();\n }\n\n public get queue(): readonly QueueItemState[] {\n return EMPTY_QUEUE_ITEMS;\n }\n\n public moveQueueItem(\n _queueItemId: string,\n _placement: QueuePlacement,\n ): void {}\n public removeQueueItem(_queueItemId: string): void {}\n\n protected abstract handleSend(\n message: Omit<AppendMessage, \"parentId\" | \"sourceId\">,\n options?: SendOptions,\n ): void | Promise<void>;\n protected abstract handleCancel(): void;\n\n async addAttachment(fileOrAttachment: File | CreateAttachment) {\n if (isCreateAttachment(fileOrAttachment)) {\n const adapter = this.getAttachmentAdapter();\n if (\n adapter &&\n !fileMatchesAccept(\n {\n name: fileOrAttachment.name,\n type: fileOrAttachment.contentType ?? \"\",\n },\n adapter.accept,\n )\n ) {\n const message = `File type ${fileOrAttachment.contentType || \"unknown\"} is not accepted. Accepted types: ${adapter.accept}`;\n const err = new Error(message);\n this._safeEmitAttachmentAddError(\n \"not-accepted\",\n message,\n undefined,\n err,\n );\n throw err;\n }\n\n const a: CompleteAttachment = {\n id: fileOrAttachment.id ?? generateId(),\n type: fileOrAttachment.type ?? \"document\",\n name: fileOrAttachment.name,\n contentType: fileOrAttachment.contentType,\n content: fileOrAttachment.content,\n status: { type: \"complete\" },\n };\n this._attachments = [...this._attachments, a];\n this._notifySubscribers();\n this._notifyEventSubscribers(\"attachmentAdd\", {});\n return;\n }\n\n const adapter = this.getAttachmentAdapter();\n if (!adapter) {\n const message = \"Attachments are not supported\";\n const err = new Error(message);\n this._safeEmitAttachmentAddError(\"no-adapter\", message, undefined, err);\n throw err;\n }\n\n if (\n !fileMatchesAccept(\n { name: fileOrAttachment.name, type: fileOrAttachment.type },\n adapter.accept,\n )\n ) {\n const message = `File type ${fileOrAttachment.type || \"unknown\"} is not accepted. Accepted types: ${adapter.accept}`;\n const err = new Error(message);\n this._safeEmitAttachmentAddError(\"not-accepted\", message, undefined, err);\n throw err;\n }\n\n const operation = this._attachmentAddOperations.start();\n const upsertAttachment = (a: PendingAttachment) => {\n if (!this._attachmentAddOperations.accept(operation, a.id)) return false;\n\n const idx = this._attachments.findIndex(\n (attachment) => attachment.id === a.id,\n );\n if (idx !== -1)\n this._attachments = [\n ...this._attachments.slice(0, idx),\n a,\n ...this._attachments.slice(idx + 1),\n ];\n else {\n this._attachments = [...this._attachments, a];\n }\n\n this._notifySubscribers();\n return true;\n };\n let lastAttachment: PendingAttachment | undefined;\n try {\n await drainAttachmentAdd(\n adapter.add({ file: fileOrAttachment }),\n (attachment) => {\n lastAttachment = attachment;\n return upsertAttachment(attachment);\n },\n );\n } catch (e) {\n if (this._attachmentAddOperations.isCancelled(operation)) return;\n if (lastAttachment) {\n upsertAttachment({\n ...lastAttachment,\n status: {\n type: \"incomplete\",\n reason: \"error\",\n message: e instanceof Error ? e.message : String(e),\n },\n });\n }\n this._safeEmitAttachmentAddError(\n \"adapter-error\",\n e instanceof Error ? e.message : String(e),\n lastAttachment?.id,\n e instanceof Error ? e : undefined,\n );\n throw e;\n } finally {\n this._attachmentAddOperations.finish(operation);\n }\n\n if (this._attachmentAddOperations.isCancelled(operation)) return;\n if (\n lastAttachment?.status.type === \"incomplete\" &&\n lastAttachment.status.reason === \"error\"\n ) {\n this._safeEmitAttachmentAddError(\n \"adapter-error\",\n lastAttachment.status.message ??\n \"Attachment upload did not complete successfully.\",\n lastAttachment.id,\n );\n } else {\n this._notifyEventSubscribers(\"attachmentAdd\", {});\n }\n }\n\n private _safeEmitAttachmentAddError(\n reason: AttachmentAddErrorReason,\n message: string,\n attachmentId?: string,\n error?: Error,\n ) {\n try {\n this._notifyEventSubscribers(\"attachmentAddError\", {\n reason,\n message,\n ...(attachmentId !== undefined && { attachmentId }),\n ...(error !== undefined && { error }),\n });\n } catch (subscriberError) {\n console.error(\n \"[assistant-ui] attachmentAddError subscriber threw:\",\n subscriberError,\n );\n }\n }\n\n async removeAttachment(attachmentId: string) {\n const index = this._attachments.findIndex((a) => a.id === attachmentId);\n if (index === -1) throw new Error(\"Attachment not found\");\n const attachment = this._attachments[index]!;\n\n this._cancelAttachmentAdd(attachmentId);\n\n // A send in flight may already be uploading this attachment; the upload\n // can't be cancelled, so mark it to be dropped from the outgoing message\n // before any await gives the upload a chance to settle first.\n if (this._isSending) this._removedDuringSend.add(attachmentId);\n\n if (!isAttachmentComplete(attachment)) {\n const adapter = this.getAttachmentAdapter();\n if (!adapter) throw new Error(\"Attachments are not supported\");\n try {\n await adapter.remove(attachment);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this._attachments = this._attachments.map((candidate) =>\n candidate.id === attachmentId && !isAttachmentComplete(candidate)\n ? {\n ...candidate,\n status: { type: \"incomplete\", reason: \"error\", message },\n }\n : candidate,\n );\n this._notifySubscribers();\n throw error;\n }\n }\n this._attachments = this._attachments.filter((a) => a.id !== attachmentId);\n this._notifySubscribers();\n }\n\n private _dictation: DictationState | undefined;\n private _dictationSession: DictationAdapter.Session | undefined;\n private _dictationUnsubscribes: Unsubscribe[] = [];\n private _dictationBaseText = \"\";\n private _currentInterimText = \"\";\n private _dictationSessionIdCounter = 0;\n private _activeDictationSessionId: number | undefined;\n private _isCleaningDictation = false;\n\n public get dictation(): DictationState | undefined {\n return this._dictation;\n }\n\n private _isActiveSession(\n sessionId: number,\n session: DictationAdapter.Session,\n ): boolean {\n return (\n this._activeDictationSessionId === sessionId &&\n this._dictationSession === session\n );\n }\n\n public startDictation(): void {\n const adapter = this.getDictationAdapter();\n if (!adapter) {\n throw new Error(\"Dictation adapter not configured\");\n }\n\n if (this._dictationSession) {\n for (const unsub of this._dictationUnsubscribes) {\n unsub();\n }\n this._dictationUnsubscribes = [];\n const oldSession = this._dictationSession;\n oldSession.stop().catch(() => {});\n this._dictationSession = undefined;\n }\n\n const inputDisabled = adapter.disableInputDuringDictation ?? false;\n\n this._dictationBaseText = this._text;\n this._currentInterimText = \"\";\n\n const session = adapter.listen();\n this._dictationSession = session;\n const sessionId = ++this._dictationSessionIdCounter;\n this._activeDictationSessionId = sessionId;\n this._dictation = { status: session.status, inputDisabled };\n this._notifySubscribers();\n\n const unsubSpeech = session.onSpeech((result) => {\n if (!this._isActiveSession(sessionId, session)) return;\n const isFinal = result.isFinal !== false;\n\n const needsSeparator =\n this._dictationBaseText &&\n !this._dictationBaseText.endsWith(\" \") &&\n result.transcript;\n const separator = needsSeparator ? \" \" : \"\";\n\n if (isFinal) {\n this._dictationBaseText =\n this._dictationBaseText + separator + result.transcript;\n this._currentInterimText = \"\";\n this._text = this._dictationBaseText;\n\n if (this._dictation) {\n const { transcript: _, ...rest } = this._dictation;\n this._dictation = rest;\n }\n this._notifySubscribers();\n } else {\n this._currentInterimText = separator + result.transcript;\n this._text = this._dictationBaseText + this._currentInterimText;\n\n if (this._dictation) {\n this._dictation = {\n ...this._dictation,\n transcript: result.transcript,\n };\n }\n this._notifySubscribers();\n }\n });\n this._dictationUnsubscribes.push(unsubSpeech);\n\n const unsubStart = session.onSpeechStart(() => {\n if (!this._isActiveSession(sessionId, session)) return;\n\n this._dictation = {\n status: { type: \"running\" },\n inputDisabled,\n ...(this._dictation?.transcript && {\n transcript: this._dictation.transcript,\n }),\n };\n this._notifySubscribers();\n });\n this._dictationUnsubscribes.push(unsubStart);\n\n const unsubEnd = session.onSpeechEnd(() => {\n this._cleanupDictation({ sessionId });\n });\n this._dictationUnsubscribes.push(unsubEnd);\n\n const statusInterval = setInterval(() => {\n if (!this._isActiveSession(sessionId, session)) return;\n\n if (session.status.type === \"ended\") {\n this._cleanupDictation({ sessionId });\n }\n }, 100);\n this._dictationUnsubscribes.push(() => clearInterval(statusInterval));\n }\n\n public stopDictation(): void {\n if (!this._dictationSession) return;\n\n const session = this._dictationSession;\n const sessionId = this._activeDictationSessionId;\n const cleanup = () => this._cleanupDictation({ sessionId });\n void session.stop().then(cleanup, cleanup);\n }\n\n private _cleanupDictation(options?: { sessionId: number | undefined }): void {\n const isStaleSession =\n options?.sessionId !== undefined &&\n options.sessionId !== this._activeDictationSessionId;\n if (isStaleSession || this._isCleaningDictation) return;\n\n this._isCleaningDictation = true;\n try {\n for (const unsub of this._dictationUnsubscribes) {\n unsub();\n }\n this._dictationUnsubscribes = [];\n this._dictationSession = undefined;\n this._activeDictationSessionId = undefined;\n this._dictation = undefined;\n this._dictationBaseText = \"\";\n this._currentInterimText = \"\";\n this._notifySubscribers();\n } finally {\n this._isCleaningDictation = false;\n }\n }\n\n private _eventSubscribers = new Map<\n ComposerRuntimeEventType,\n Set<(payload?: unknown) => void>\n >();\n\n protected _notifyEventSubscribers<E extends ComposerRuntimeEventType>(\n event: E,\n payload: ComposerRuntimeEventPayload[E],\n ) {\n const subscribers = this._eventSubscribers.get(event);\n if (!subscribers) return;\n\n notifyEventListeners(subscribers, payload, `Composer runtime \"${event}\"`);\n }\n\n public unstable_on<E extends ComposerRuntimeEventType>(\n event: E,\n callback: ComposerRuntimeEventCallback<E>,\n ) {\n const wrapped = callback as (payload?: unknown) => void;\n let subscribers = this._eventSubscribers.get(event);\n if (!subscribers) {\n subscribers = new Set();\n this._eventSubscribers.set(event, subscribers);\n }\n subscribers.add(wrapped);\n\n return () => {\n this._eventSubscribers.get(event)?.delete(wrapped);\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ import { ModelContext, ModelContextProvider } from "../../model-context/types.js
|
|
|
8
8
|
import { ThreadMessageLike } from "../utils/thread-message-like.js";
|
|
9
9
|
import { ExportedMessageRepository, MessageRepository } from "../utils/message-repository.js";
|
|
10
10
|
import { AddToolResultOptions, RespondToToolApprovalOptions, ResumeRunConfig, ResumeToolCallOptions, RuntimeCapabilities, SpeechState, StartRunConfig, SubmitFeedbackOptions, ThreadRuntimeCore, ThreadRuntimeEventCallback, ThreadRuntimeEventPayload, ThreadRuntimeEventType, ThreadSuggestion, VoiceSessionState } from "../interfaces/thread-runtime-core.js";
|
|
11
|
+
import { BaseSubscribable } from "../../subscribable/subscribable.js";
|
|
11
12
|
import { DefaultThreadComposerRuntimeCore } from "./default-thread-composer-runtime-core.js";
|
|
12
13
|
import { DefaultEditComposerRuntimeCore } from "./default-edit-composer-runtime-core.js";
|
|
13
14
|
import "../../index.js";
|
|
@@ -18,10 +19,9 @@ type BaseThreadAdapters = {
|
|
|
18
19
|
attachments?: AttachmentAdapter | undefined;
|
|
19
20
|
voice?: RealtimeVoiceAdapter | undefined;
|
|
20
21
|
};
|
|
21
|
-
declare abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
|
|
22
|
-
private _subscriptions;
|
|
22
|
+
declare abstract class BaseThreadRuntimeCore extends BaseSubscribable implements ThreadRuntimeCore {
|
|
23
23
|
private _isInitialized;
|
|
24
|
-
protected
|
|
24
|
+
protected repository: MessageRepository;
|
|
25
25
|
abstract get adapters(): BaseThreadAdapters | undefined;
|
|
26
26
|
abstract get isDisabled(): boolean;
|
|
27
27
|
abstract get isSendDisabled(): boolean;
|
|
@@ -35,7 +35,7 @@ declare abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
|
|
|
35
35
|
abstract resumeRun(config: ResumeRunConfig): void;
|
|
36
36
|
abstract addToolResult(options: AddToolResultOptions): void;
|
|
37
37
|
abstract resumeToolCall(options: ResumeToolCallOptions): void;
|
|
38
|
-
abstract respondToToolApproval(options: RespondToToolApprovalOptions): void
|
|
38
|
+
abstract respondToToolApproval(options: RespondToToolApprovalOptions): Promise<void>;
|
|
39
39
|
abstract cancelRun(): void;
|
|
40
40
|
abstract exportExternalState(): any;
|
|
41
41
|
abstract importExternalState(state: any): void;
|
|
@@ -77,9 +77,7 @@ declare abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {
|
|
|
77
77
|
} | undefined;
|
|
78
78
|
getBranches(messageId: string): string[];
|
|
79
79
|
switchToBranch(branchId: string): void;
|
|
80
|
-
protected _notifySubscribers(): void;
|
|
81
80
|
_notifyEventSubscribers<E extends ThreadRuntimeEventType>(event: E, payload: ThreadRuntimeEventPayload[E]): void;
|
|
82
|
-
subscribe(callback: () => void): Unsubscribe;
|
|
83
81
|
submitFeedback({ messageId, type }: SubmitFeedbackOptions): void;
|
|
84
82
|
private _stopSpeaking;
|
|
85
83
|
speech: SpeechState | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/base/base-thread-runtime-core.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"base-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/base/base-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;;KAwCK;EACH,SAAS;EACT,WAAW;EACX,cAAc;EACd,QAAQ;;uBAGY,8BACZ,4BACG;UAEH;YAEE,YAAU;eACA,YAAY;eACZ;eACA;eACA;eACA,wBAAwB;eACxB;eAEA,gBAAgB;WACpB,OAAO,SAAS;WAChB,cAAc,2BAA2B;WACzC,SAAS,QAAQ;WACjB,UAAU,QAAQ;WAClB,cAAc,SAAS;WACvB,eAAe,SAAS;WACxB,sBACd,SAAS,+BACR;WACa;WACA;WACA,oBAAoB;WACpB;YAEN,gBAAgB;YAChB;UACF;UACA;UACA;YAEE;YAKA,6BAA6B;MAI5B,qBAAqB;MAgBrB,sEAAK,sDAAA;WAWA,UAAQ;mBAEP;EAEL,YAAA,kBAAkB;EAKvB,mBALuB;;;;;;;;;;;;;;YAsBpB,qBACR,SAAS,eACT,2BACC;UAmBK;EACD,gBAAgB,oBAAiB;EAGjC,UAAU;EAeV,eAAe;;;;;EAsBf,YAAY;EAOZ,eAAe;EAKf,wBAAwB,UAAU,wBACvC,OAAO,GACP,SAAS,0BAA0B;EAQ9B,iBAAiB,WAAW,QAAQ;UAqBnC;EACD,QAAQ;EAER,MAAM;EA8BN;UAMC;UACA;EACD,OAAO;UAEN;UACA;EAED;EAEA,uBAAwB,yBAAuB;EAK/C;UAmEC;UAEA;UA8DA;EAaD;EAmBA;EAUA;YAUG;EAOH,UAAM;EAIN,OAAO,MAAM;EAOb,MAAM,2BAA2B;UAIhC;EAKD,YAAY,UAAU,wBAC3B,OAAO,GACP,UAAU,2BAA2B,KAAE"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { gateInteractableComposerMetadata } from "../../model-context/interactable-composer-metadata.js";
|
|
2
2
|
import { notifyEventListeners } from "../../utils/notify-event-listeners.js";
|
|
3
|
+
import { BaseSubscribable } from "../../subscribable/subscribable.js";
|
|
3
4
|
import { generateId } from "../../utils/id.js";
|
|
4
5
|
import { getThreadMessageText } from "../../utils/text.js";
|
|
5
6
|
import { ExportedMessageRepository, MessageRepository } from "../utils/message-repository.js";
|
|
6
7
|
import { DefaultThreadComposerRuntimeCore } from "./default-thread-composer-runtime-core.js";
|
|
7
8
|
import { DefaultEditComposerRuntimeCore } from "./default-edit-composer-runtime-core.js";
|
|
8
9
|
//#region src/runtime/base/base-thread-runtime-core.ts
|
|
9
|
-
var BaseThreadRuntimeCore = class {
|
|
10
|
-
_subscriptions = /* @__PURE__ */ new Set();
|
|
10
|
+
var BaseThreadRuntimeCore = class extends BaseSubscribable {
|
|
11
11
|
_isInitialized = false;
|
|
12
12
|
repository = new MessageRepository();
|
|
13
13
|
_voiceMessages = [];
|
|
@@ -40,6 +40,7 @@ var BaseThreadRuntimeCore = class {
|
|
|
40
40
|
composer = new DefaultThreadComposerRuntimeCore(this);
|
|
41
41
|
_contextProvider;
|
|
42
42
|
constructor(_contextProvider) {
|
|
43
|
+
super();
|
|
43
44
|
this._contextProvider = _contextProvider;
|
|
44
45
|
}
|
|
45
46
|
getModelContext() {
|
|
@@ -106,18 +107,11 @@ var BaseThreadRuntimeCore = class {
|
|
|
106
107
|
this.repository.switchToBranch(branchId);
|
|
107
108
|
this._notifySubscribers();
|
|
108
109
|
}
|
|
109
|
-
_notifySubscribers() {
|
|
110
|
-
for (const callback of this._subscriptions) callback();
|
|
111
|
-
}
|
|
112
110
|
_notifyEventSubscribers(event, payload) {
|
|
113
111
|
const subscribers = this._eventSubscribers.get(event);
|
|
114
112
|
if (!subscribers) return;
|
|
115
113
|
notifyEventListeners(subscribers, payload, `Thread runtime "${event}"`);
|
|
116
114
|
}
|
|
117
|
-
subscribe(callback) {
|
|
118
|
-
this._subscriptions.add(callback);
|
|
119
|
-
return () => this._subscriptions.delete(callback);
|
|
120
|
-
}
|
|
121
115
|
submitFeedback({ messageId, type }) {
|
|
122
116
|
const adapter = this.adapters?.feedback;
|
|
123
117
|
if (!adapter) throw new Error("Feedback adapter not configured");
|
|
@@ -364,7 +358,7 @@ var BaseThreadRuntimeCore = class {
|
|
|
364
358
|
_eventSubscribers = /* @__PURE__ */ new Map();
|
|
365
359
|
unstable_on(event, callback) {
|
|
366
360
|
const wrapped = callback;
|
|
367
|
-
if (event === "modelContextUpdate") return this._contextProvider.subscribe?.(() => wrapped
|
|
361
|
+
if (event === "modelContextUpdate") return this._contextProvider.subscribe?.(() => notifyEventListeners([wrapped], {}, `Thread runtime "${event}"`)) ?? (() => {});
|
|
368
362
|
let subscribers = this._eventSubscribers.get(event);
|
|
369
363
|
if (!subscribers) {
|
|
370
364
|
subscribers = /* @__PURE__ */ new Set();
|
|
@@ -372,7 +366,7 @@ var BaseThreadRuntimeCore = class {
|
|
|
372
366
|
}
|
|
373
367
|
subscribers.add(wrapped);
|
|
374
368
|
if (event === "initialize" && this._isInitialized) queueMicrotask(() => {
|
|
375
|
-
if (subscribers.has(wrapped)) wrapped
|
|
369
|
+
if (subscribers.has(wrapped)) notifyEventListeners([wrapped], {}, `Thread runtime "${event}"`);
|
|
376
370
|
});
|
|
377
371
|
return () => {
|
|
378
372
|
this._eventSubscribers.get(event)?.delete(wrapped);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-thread-runtime-core.js","names":["AppendMessage","ThreadAssistantMessage","ThreadMessage","Unsubscribe","ModelContextProvider","getThreadMessageText","generateId","ExportedMessageRepository","MessageRepository","DefaultThreadComposerRuntimeCore","AddToolResultOptions","ResumeToolCallOptions","RespondToToolApprovalOptions","ThreadSuggestion","SubmitFeedbackOptions","ThreadRuntimeCore","SpeechState","VoiceSessionState","RuntimeCapabilities","ThreadRuntimeEventCallback","ThreadRuntimeEventPayload","ThreadRuntimeEventType","StartRunConfig","ResumeRunConfig","DefaultEditComposerRuntimeCore","SpeechSynthesisAdapter","FeedbackAdapter","AttachmentAdapter","RealtimeVoiceAdapter","ThreadMessageLike","notifyEventListeners","gateInteractableComposerMetadata","BaseThreadAdapters","speech","feedback","attachments","voice","BaseThreadRuntimeCore","_subscriptions","Set","_isInitialized","repository","adapters","isDisabled","isSendDisabled","isLoading","suggestions","extras","capabilities","append","message","deleteMessage","messageId","Promise","startRun","config","resumeRun","addToolResult","options","resumeToolCall","respondToToolApproval","cancelRun","exportExternalState","importExternalState","state","unstable_notifySessionReset","_voiceMessages","_voiceGeneration","_cachedMergedMessages","_cachedVoiceGeneration","_cachedMergedBase","_markVoiceMessagesDirty","_getBaseMessages","getMessages","messages","length","base","mostRecentAssistantMessage","this","role","metadata","unstable_state","composer","_contextProvider","constructor","getModelContext","enrichAppendMetadata","anchorId","parentId","parentIndex","findIndex","m","id","composerMetadata","unstable_composerMetadata","slice","custom","_editComposers","Map","getEditComposer","get","beginEdit","has","Error","set","delete","getMessage","_notifySubscribers","getMessageById","baseMessages","voiceIdx","at","index","undefined","getBranches","some","switchToBranch","branchId","callback","_notifyEventSubscribers","event","E","payload","subscribers","_eventSubscribers","subscribe","add","submitFeedback","type","adapter","submit","updatedMessage","submittedFeedback","addOrUpdateMessage","_stopSpeaking","speak","utterance","unsub","status","cancel","stopSpeaking","_voiceSession","Session","_voiceUnsubs","Array","_voiceVolume","_voiceVolumeSubscribers","getVoiceVolume","subscribeVoiceVolume","connectVoice","disconnectVoice","session","connect","unsubs","currentMode","Mode","isMuted","mode","push","onStatusChange","_finishVoiceAssistantMessage","onModeChange","onVolumeChange","volume","onTranscript","transcript","_handleVoiceTranscript","_currentAssistantMsg","TranscriptItem","ensureInitialized","isFinal","content","text","createdAt","Date","reason","unstable_annotations","unstable_data","steps","idx","indexOf","updated","last","disconnect","muteVoice","mute","unmuteVoice","unmute","export","import","data","clear","reset","initialMessages","fromArray","unstable_on","wrapped","queueMicrotask"],"sources":["../../../src/runtime/base/base-thread-runtime-core.ts"],"sourcesContent":["import type {\n AppendMessage,\n ThreadAssistantMessage,\n ThreadMessage,\n} from \"../../types/message\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { ModelContextProvider } from \"../../model-context/types\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport { generateId } from \"../../utils/id\";\nimport {\n ExportedMessageRepository,\n MessageRepository,\n} from \"../utils/message-repository\";\nimport { DefaultThreadComposerRuntimeCore } from \"./default-thread-composer-runtime-core\";\nimport type {\n AddToolResultOptions,\n ResumeToolCallOptions,\n RespondToToolApprovalOptions,\n ThreadSuggestion,\n SubmitFeedbackOptions,\n ThreadRuntimeCore,\n SpeechState,\n VoiceSessionState,\n RuntimeCapabilities,\n ThreadRuntimeEventCallback,\n ThreadRuntimeEventPayload,\n ThreadRuntimeEventType,\n StartRunConfig,\n ResumeRunConfig,\n} from \"../interfaces/thread-runtime-core\";\nimport { DefaultEditComposerRuntimeCore } from \"./default-edit-composer-runtime-core\";\nimport type { SpeechSynthesisAdapter } from \"../../adapters/speech\";\nimport type { FeedbackAdapter } from \"../../adapters/feedback\";\nimport type { AttachmentAdapter } from \"../../adapters/attachment\";\nimport type { RealtimeVoiceAdapter } from \"../../adapters/voice\";\nimport type { ThreadMessageLike } from \"../utils/thread-message-like\";\nimport { notifyEventListeners } from \"../../utils/notify-event-listeners\";\nimport { gateInteractableComposerMetadata } from \"../../model-context/interactable-composer-metadata\";\n\ntype BaseThreadAdapters = {\n speech?: SpeechSynthesisAdapter | undefined;\n feedback?: FeedbackAdapter | undefined;\n attachments?: AttachmentAdapter | undefined;\n voice?: RealtimeVoiceAdapter | undefined;\n};\n\nexport abstract class BaseThreadRuntimeCore implements ThreadRuntimeCore {\n private _subscriptions = new Set<() => void>();\n private _isInitialized = false;\n\n protected readonly repository = new MessageRepository();\n public abstract get adapters(): BaseThreadAdapters | undefined;\n public abstract get isDisabled(): boolean;\n public abstract get isSendDisabled(): boolean;\n public abstract get isLoading(): boolean;\n public abstract get suggestions(): readonly ThreadSuggestion[];\n public abstract get extras(): unknown;\n\n public abstract get capabilities(): RuntimeCapabilities;\n public abstract append(message: AppendMessage): void;\n public abstract deleteMessage(messageId: string): void | Promise<void>;\n public abstract startRun(config: StartRunConfig): void;\n public abstract resumeRun(config: ResumeRunConfig): void;\n public abstract addToolResult(options: AddToolResultOptions): void;\n public abstract resumeToolCall(options: ResumeToolCallOptions): void;\n public abstract respondToToolApproval(\n options: RespondToToolApprovalOptions,\n ): void;\n public abstract cancelRun(): void;\n public abstract exportExternalState(): any;\n public abstract importExternalState(state: any): void;\n public abstract unstable_notifySessionReset(): void;\n\n protected _voiceMessages: ThreadMessage[] = [];\n protected _voiceGeneration = 0;\n private _cachedMergedMessages: readonly ThreadMessage[] | null = null;\n private _cachedVoiceGeneration = -1;\n private _cachedMergedBase: readonly ThreadMessage[] | null = null;\n\n protected _markVoiceMessagesDirty() {\n this._voiceGeneration++;\n this._cachedMergedMessages = null;\n }\n\n protected _getBaseMessages(): readonly ThreadMessage[] {\n return this.repository.getMessages();\n }\n\n public get messages(): readonly ThreadMessage[] {\n if (this._voiceMessages.length === 0) {\n return this._getBaseMessages();\n }\n const base = this._getBaseMessages();\n if (\n this._cachedVoiceGeneration !== this._voiceGeneration ||\n this._cachedMergedBase !== base\n ) {\n this._cachedMergedMessages = [...base, ...this._voiceMessages];\n this._cachedVoiceGeneration = this._voiceGeneration;\n this._cachedMergedBase = base;\n }\n return this._cachedMergedMessages!;\n }\n\n public get state() {\n let mostRecentAssistantMessage: (typeof this.messages)[number] | undefined;\n for (const message of this.messages) {\n if (message.role === \"assistant\") {\n mostRecentAssistantMessage = message;\n }\n }\n\n return mostRecentAssistantMessage?.metadata.unstable_state ?? null;\n }\n\n public readonly composer = new DefaultThreadComposerRuntimeCore(this);\n\n private readonly _contextProvider: ModelContextProvider;\n\n constructor(_contextProvider: ModelContextProvider) {\n this._contextProvider = _contextProvider;\n }\n\n public getModelContext() {\n return this._contextProvider.getModelContext();\n }\n\n /**\n * Stamps provider-contributed composer metadata onto an outgoing message.\n * Called at dispatch rather than in the composer, so programmatic sends are\n * covered too, and exactly once per message: a queued send is stamped when\n * it leaves the lane, never when it enters.\n *\n * Only user messages are stamped, matching the readers: both the version\n * fold and the model injection skip every other role.\n *\n * @param anchorId Message the gated branch prefix ends at. A queued send\n * passes the current tail, having waited through a run that grew the prefix\n * past the parent it was created with.\n */\n protected enrichAppendMetadata(\n message: AppendMessage,\n anchorId: string | null = message.parentId,\n ): AppendMessage {\n if (message.role !== \"user\") return message;\n const messages = this.messages;\n const parentIndex =\n anchorId === null ? -1 : messages.findIndex((m) => m.id === anchorId);\n const composerMetadata = gateInteractableComposerMetadata(\n this.getModelContext().unstable_composerMetadata,\n messages.slice(0, parentIndex + 1),\n );\n if (!composerMetadata) return message;\n return {\n ...message,\n metadata: {\n ...message.metadata,\n custom: { ...message.metadata?.custom, ...composerMetadata },\n },\n };\n }\n\n private _editComposers = new Map<string, DefaultEditComposerRuntimeCore>();\n public getEditComposer(messageId: string) {\n return this._editComposers.get(messageId);\n }\n public beginEdit(messageId: string) {\n if (this._editComposers.has(messageId))\n throw new Error(\"Edit already in progress\");\n\n this._editComposers.set(\n messageId,\n new DefaultEditComposerRuntimeCore(\n this,\n () => this._editComposers.delete(messageId),\n this.repository.getMessage(messageId),\n ),\n );\n this._notifySubscribers();\n }\n\n public getMessageById(messageId: string) {\n try {\n return this.repository.getMessage(messageId);\n } catch {\n // Check voice messages\n const baseMessages = this.repository.getMessages();\n const voiceIdx = this._voiceMessages.findIndex((m) => m.id === messageId);\n if (voiceIdx !== -1) {\n const parentId =\n voiceIdx > 0\n ? this._voiceMessages[voiceIdx - 1]!.id\n : (baseMessages.at(-1)?.id ?? null);\n return {\n parentId,\n message: this._voiceMessages[voiceIdx]!,\n index: baseMessages.length + voiceIdx,\n };\n }\n return undefined;\n }\n }\n\n public getBranches(messageId: string): string[] {\n if (this._voiceMessages.some((m) => m.id === messageId)) {\n return [];\n }\n return this.repository.getBranches(messageId);\n }\n\n public switchToBranch(branchId: string): void {\n this.repository.switchToBranch(branchId);\n this._notifySubscribers();\n }\n\n protected _notifySubscribers() {\n for (const callback of this._subscriptions) callback();\n }\n\n public _notifyEventSubscribers<E extends ThreadRuntimeEventType>(\n event: E,\n payload: ThreadRuntimeEventPayload[E],\n ) {\n const subscribers = this._eventSubscribers.get(event);\n if (!subscribers) return;\n\n notifyEventListeners(subscribers, payload, `Thread runtime \"${event}\"`);\n }\n\n public subscribe(callback: () => void): Unsubscribe {\n this._subscriptions.add(callback);\n return () => this._subscriptions.delete(callback);\n }\n\n public submitFeedback({ messageId, type }: SubmitFeedbackOptions) {\n const adapter = this.adapters?.feedback;\n if (!adapter) throw new Error(\"Feedback adapter not configured\");\n\n const { message, parentId } = this.repository.getMessage(messageId);\n adapter.submit({ message, type });\n\n if (message.role === \"assistant\") {\n const updatedMessage: ThreadMessage = {\n ...message,\n metadata: {\n ...message.metadata,\n submittedFeedback: { type },\n },\n };\n this.repository.addOrUpdateMessage(parentId, updatedMessage);\n }\n\n this._notifySubscribers();\n }\n\n private _stopSpeaking: Unsubscribe | undefined;\n public speech: SpeechState | undefined;\n\n public speak(messageId: string) {\n const adapter = this.adapters?.speech;\n if (!adapter) throw new Error(\"Speech adapter not configured\");\n\n const { message } = this.repository.getMessage(messageId);\n\n this._stopSpeaking?.();\n\n const utterance = adapter.speak(getThreadMessageText(message));\n const unsub = utterance.subscribe(() => {\n if (utterance.status.type === \"ended\") {\n this._stopSpeaking = undefined;\n this.speech = undefined;\n } else {\n this.speech = { messageId, status: utterance.status };\n }\n this._notifySubscribers();\n });\n\n this.speech = { messageId, status: utterance.status };\n this._notifySubscribers();\n\n this._stopSpeaking = () => {\n utterance.cancel();\n unsub();\n this.speech = undefined;\n this._stopSpeaking = undefined;\n };\n }\n\n public stopSpeaking() {\n if (!this._stopSpeaking) throw new Error(\"No message is being spoken\");\n this._stopSpeaking();\n this._notifySubscribers();\n }\n\n private _voiceSession: RealtimeVoiceAdapter.Session | undefined;\n private _voiceUnsubs: Array<() => void> = [];\n public voice: VoiceSessionState | undefined;\n\n private _voiceVolume = 0;\n private _voiceVolumeSubscribers = new Set<() => void>();\n\n public getVoiceVolume = () => this._voiceVolume;\n\n public subscribeVoiceVolume = (callback: () => void): Unsubscribe => {\n this._voiceVolumeSubscribers.add(callback);\n return () => this._voiceVolumeSubscribers.delete(callback);\n };\n\n public connectVoice() {\n const adapter = this.adapters?.voice;\n if (!adapter) throw new Error(\"Voice adapter not configured\");\n\n this.disconnectVoice();\n\n const session = adapter.connect({});\n this._voiceSession = session;\n const unsubs: Array<() => void> = [];\n\n let currentMode: RealtimeVoiceAdapter.Mode = \"listening\";\n\n this.voice = {\n status: session.status,\n isMuted: session.isMuted,\n mode: currentMode,\n };\n this._voiceVolume = 0;\n this._notifySubscribers();\n\n unsubs.push(\n session.onStatusChange((status) => {\n if (status.type === \"ended\") {\n this._finishVoiceAssistantMessage();\n this._voiceSession = undefined;\n this.voice = undefined;\n } else {\n this.voice = {\n status,\n isMuted: session.isMuted,\n mode: currentMode,\n };\n }\n this._notifySubscribers();\n }),\n );\n\n unsubs.push(\n session.onModeChange((mode) => {\n currentMode = mode;\n if (this.voice) {\n this.voice = { ...this.voice, mode };\n this._notifySubscribers();\n }\n }),\n );\n\n unsubs.push(\n session.onVolumeChange((volume) => {\n this._voiceVolume = volume;\n notifyEventListeners(\n this._voiceVolumeSubscribers,\n undefined,\n \"Voice volume\",\n );\n }),\n );\n\n unsubs.push(\n session.onTranscript((transcript) => {\n this._handleVoiceTranscript(transcript);\n }),\n );\n\n this._voiceUnsubs = unsubs;\n }\n\n private _currentAssistantMsg: ThreadAssistantMessage | null = null;\n\n private _handleVoiceTranscript(\n transcript: RealtimeVoiceAdapter.TranscriptItem,\n ) {\n this.ensureInitialized();\n\n if (transcript.role === \"user\") {\n this._finishVoiceAssistantMessage();\n this._currentAssistantMsg = null;\n\n if (transcript.isFinal) {\n this._voiceMessages.push({\n id: generateId(),\n role: \"user\",\n content: [{ type: \"text\", text: transcript.text }],\n metadata: { custom: {} },\n createdAt: new Date(),\n status: { type: \"complete\", reason: \"unknown\" },\n attachments: [],\n });\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n } else {\n if (!this._currentAssistantMsg) {\n this._currentAssistantMsg = {\n id: generateId(),\n role: \"assistant\",\n content: [{ type: \"text\", text: transcript.text }],\n metadata: {\n unstable_state: this.state,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n status: { type: \"running\" },\n createdAt: new Date(),\n };\n this._voiceMessages.push(this._currentAssistantMsg);\n } else {\n const idx = this._voiceMessages.indexOf(this._currentAssistantMsg);\n if (idx === -1) return;\n const updated: ThreadAssistantMessage = {\n ...this._currentAssistantMsg,\n content: [{ type: \"text\", text: transcript.text }],\n ...(transcript.isFinal\n ? { status: { type: \"complete\", reason: \"stop\" } }\n : {}),\n };\n this._voiceMessages[idx] = updated;\n this._currentAssistantMsg = updated;\n }\n\n if (transcript.isFinal) {\n this._currentAssistantMsg = null;\n }\n\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n }\n\n private _finishVoiceAssistantMessage() {\n const last = this._voiceMessages.at(-1);\n if (last?.role === \"assistant\" && last.status.type === \"running\") {\n const idx = this._voiceMessages.length - 1;\n this._voiceMessages[idx] = {\n ...(last as ThreadAssistantMessage),\n status: { type: \"complete\", reason: \"stop\" },\n };\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n }\n\n public disconnectVoice() {\n this._finishVoiceAssistantMessage();\n this._currentAssistantMsg = null;\n for (const unsub of this._voiceUnsubs) unsub();\n this._voiceUnsubs = [];\n this._voiceSession?.disconnect();\n this._voiceSession = undefined;\n this.voice = undefined;\n this._voiceVolume = 0;\n notifyEventListeners(\n this._voiceVolumeSubscribers,\n undefined,\n \"Voice volume\",\n );\n this._voiceMessages = [];\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n\n public muteVoice() {\n if (!this._voiceSession) throw new Error(\"No active voice session\");\n this._voiceSession.mute();\n this.voice = {\n ...this.voice!,\n isMuted: true,\n };\n this._notifySubscribers();\n }\n\n public unmuteVoice() {\n if (!this._voiceSession) throw new Error(\"No active voice session\");\n this._voiceSession.unmute();\n this.voice = {\n ...this.voice!,\n isMuted: false,\n };\n this._notifySubscribers();\n }\n\n protected ensureInitialized() {\n if (!this._isInitialized) {\n this._isInitialized = true;\n this._notifyEventSubscribers(\"initialize\", {});\n }\n }\n\n public export() {\n return this.repository.export();\n }\n\n public import(data: ExportedMessageRepository) {\n this.ensureInitialized();\n this.repository.clear();\n this.repository.import(data);\n this._notifySubscribers();\n }\n\n public reset(initialMessages?: readonly ThreadMessageLike[]) {\n this.import(ExportedMessageRepository.fromArray(initialMessages ?? []));\n }\n\n private _eventSubscribers = new Map<\n ThreadRuntimeEventType,\n Set<(payload?: unknown) => void>\n >();\n\n public unstable_on<E extends ThreadRuntimeEventType>(\n event: E,\n callback: ThreadRuntimeEventCallback<E>,\n ) {\n const wrapped = callback as (payload?: unknown) => void;\n if (event === \"modelContextUpdate\") {\n // provider.subscribe is `() => void`; pump the typed empty payload to the user callback.\n return this._contextProvider.subscribe?.(() => wrapped({})) ?? (() => {});\n }\n\n let subscribers = this._eventSubscribers.get(event);\n if (!subscribers) {\n subscribers = new Set();\n this._eventSubscribers.set(event, subscribers);\n }\n subscribers.add(wrapped);\n\n // `initialize` latches: replay it (deferred) to subscribers that attach\n // after the thread already initialized, mirroring a BehaviorSubject.\n if (event === \"initialize\" && this._isInitialized) {\n queueMicrotask(() => {\n if (subscribers.has(wrapped)) wrapped({});\n });\n }\n\n return () => {\n this._eventSubscribers.get(event)?.delete(wrapped);\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base-thread-runtime-core.js","names":["AppendMessage","ThreadAssistantMessage","ThreadMessage","Unsubscribe","ModelContextProvider","getThreadMessageText","generateId","ExportedMessageRepository","MessageRepository","DefaultThreadComposerRuntimeCore","AddToolResultOptions","ResumeToolCallOptions","RespondToToolApprovalOptions","ThreadSuggestion","SubmitFeedbackOptions","ThreadRuntimeCore","SpeechState","VoiceSessionState","RuntimeCapabilities","ThreadRuntimeEventCallback","ThreadRuntimeEventPayload","ThreadRuntimeEventType","StartRunConfig","ResumeRunConfig","DefaultEditComposerRuntimeCore","SpeechSynthesisAdapter","FeedbackAdapter","AttachmentAdapter","RealtimeVoiceAdapter","ThreadMessageLike","notifyEventListeners","gateInteractableComposerMetadata","BaseSubscribable","BaseThreadAdapters","speech","feedback","attachments","voice","BaseThreadRuntimeCore","_isInitialized","repository","adapters","isDisabled","isSendDisabled","isLoading","suggestions","extras","capabilities","append","message","deleteMessage","messageId","Promise","startRun","config","resumeRun","addToolResult","options","resumeToolCall","respondToToolApproval","cancelRun","exportExternalState","importExternalState","state","unstable_notifySessionReset","_voiceMessages","_voiceGeneration","_cachedMergedMessages","_cachedVoiceGeneration","_cachedMergedBase","_markVoiceMessagesDirty","_getBaseMessages","getMessages","messages","length","base","mostRecentAssistantMessage","this","role","metadata","unstable_state","composer","_contextProvider","constructor","getModelContext","enrichAppendMetadata","anchorId","parentId","parentIndex","findIndex","m","id","composerMetadata","unstable_composerMetadata","slice","custom","_editComposers","Map","getEditComposer","get","beginEdit","has","Error","set","delete","getMessage","_notifySubscribers","getMessageById","baseMessages","voiceIdx","at","index","undefined","getBranches","some","switchToBranch","branchId","_notifyEventSubscribers","event","E","payload","subscribers","_eventSubscribers","submitFeedback","type","adapter","submit","updatedMessage","submittedFeedback","addOrUpdateMessage","_stopSpeaking","speak","utterance","unsub","subscribe","status","cancel","stopSpeaking","_voiceSession","Session","_voiceUnsubs","Array","_voiceVolume","_voiceVolumeSubscribers","Set","getVoiceVolume","subscribeVoiceVolume","callback","add","connectVoice","disconnectVoice","session","connect","unsubs","currentMode","Mode","isMuted","mode","push","onStatusChange","_finishVoiceAssistantMessage","onModeChange","onVolumeChange","volume","onTranscript","transcript","_handleVoiceTranscript","_currentAssistantMsg","TranscriptItem","ensureInitialized","isFinal","content","text","createdAt","Date","reason","unstable_annotations","unstable_data","steps","idx","indexOf","updated","last","disconnect","muteVoice","mute","unmuteVoice","unmute","export","import","data","clear","reset","initialMessages","fromArray","unstable_on","wrapped","queueMicrotask"],"sources":["../../../src/runtime/base/base-thread-runtime-core.ts"],"sourcesContent":["import type {\n AppendMessage,\n ThreadAssistantMessage,\n ThreadMessage,\n} from \"../../types/message\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { ModelContextProvider } from \"../../model-context/types\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport { generateId } from \"../../utils/id\";\nimport {\n ExportedMessageRepository,\n MessageRepository,\n} from \"../utils/message-repository\";\nimport { DefaultThreadComposerRuntimeCore } from \"./default-thread-composer-runtime-core\";\nimport type {\n AddToolResultOptions,\n ResumeToolCallOptions,\n RespondToToolApprovalOptions,\n ThreadSuggestion,\n SubmitFeedbackOptions,\n ThreadRuntimeCore,\n SpeechState,\n VoiceSessionState,\n RuntimeCapabilities,\n ThreadRuntimeEventCallback,\n ThreadRuntimeEventPayload,\n ThreadRuntimeEventType,\n StartRunConfig,\n ResumeRunConfig,\n} from \"../interfaces/thread-runtime-core\";\nimport { DefaultEditComposerRuntimeCore } from \"./default-edit-composer-runtime-core\";\nimport type { SpeechSynthesisAdapter } from \"../../adapters/speech\";\nimport type { FeedbackAdapter } from \"../../adapters/feedback\";\nimport type { AttachmentAdapter } from \"../../adapters/attachment\";\nimport type { RealtimeVoiceAdapter } from \"../../adapters/voice\";\nimport type { ThreadMessageLike } from \"../utils/thread-message-like\";\nimport { notifyEventListeners } from \"../../utils/notify-event-listeners\";\nimport { gateInteractableComposerMetadata } from \"../../model-context/interactable-composer-metadata\";\nimport { BaseSubscribable } from \"../../subscribable/subscribable\";\n\ntype BaseThreadAdapters = {\n speech?: SpeechSynthesisAdapter | undefined;\n feedback?: FeedbackAdapter | undefined;\n attachments?: AttachmentAdapter | undefined;\n voice?: RealtimeVoiceAdapter | undefined;\n};\n\nexport abstract class BaseThreadRuntimeCore\n extends BaseSubscribable\n implements ThreadRuntimeCore\n{\n private _isInitialized = false;\n\n protected repository = new MessageRepository();\n public abstract get adapters(): BaseThreadAdapters | undefined;\n public abstract get isDisabled(): boolean;\n public abstract get isSendDisabled(): boolean;\n public abstract get isLoading(): boolean;\n public abstract get suggestions(): readonly ThreadSuggestion[];\n public abstract get extras(): unknown;\n\n public abstract get capabilities(): RuntimeCapabilities;\n public abstract append(message: AppendMessage): void;\n public abstract deleteMessage(messageId: string): void | Promise<void>;\n public abstract startRun(config: StartRunConfig): void;\n public abstract resumeRun(config: ResumeRunConfig): void;\n public abstract addToolResult(options: AddToolResultOptions): void;\n public abstract resumeToolCall(options: ResumeToolCallOptions): void;\n public abstract respondToToolApproval(\n options: RespondToToolApprovalOptions,\n ): Promise<void>;\n public abstract cancelRun(): void;\n public abstract exportExternalState(): any;\n public abstract importExternalState(state: any): void;\n public abstract unstable_notifySessionReset(): void;\n\n protected _voiceMessages: ThreadMessage[] = [];\n protected _voiceGeneration = 0;\n private _cachedMergedMessages: readonly ThreadMessage[] | null = null;\n private _cachedVoiceGeneration = -1;\n private _cachedMergedBase: readonly ThreadMessage[] | null = null;\n\n protected _markVoiceMessagesDirty() {\n this._voiceGeneration++;\n this._cachedMergedMessages = null;\n }\n\n protected _getBaseMessages(): readonly ThreadMessage[] {\n return this.repository.getMessages();\n }\n\n public get messages(): readonly ThreadMessage[] {\n if (this._voiceMessages.length === 0) {\n return this._getBaseMessages();\n }\n const base = this._getBaseMessages();\n if (\n this._cachedVoiceGeneration !== this._voiceGeneration ||\n this._cachedMergedBase !== base\n ) {\n this._cachedMergedMessages = [...base, ...this._voiceMessages];\n this._cachedVoiceGeneration = this._voiceGeneration;\n this._cachedMergedBase = base;\n }\n return this._cachedMergedMessages!;\n }\n\n public get state() {\n let mostRecentAssistantMessage: (typeof this.messages)[number] | undefined;\n for (const message of this.messages) {\n if (message.role === \"assistant\") {\n mostRecentAssistantMessage = message;\n }\n }\n\n return mostRecentAssistantMessage?.metadata.unstable_state ?? null;\n }\n\n public readonly composer = new DefaultThreadComposerRuntimeCore(this);\n\n private readonly _contextProvider: ModelContextProvider;\n\n constructor(_contextProvider: ModelContextProvider) {\n super();\n this._contextProvider = _contextProvider;\n }\n\n public getModelContext() {\n return this._contextProvider.getModelContext();\n }\n\n /**\n * Stamps provider-contributed composer metadata onto an outgoing message.\n * Called at dispatch rather than in the composer, so programmatic sends are\n * covered too, and exactly once per message: a queued send is stamped when\n * it leaves the lane, never when it enters.\n *\n * Only user messages are stamped, matching the readers: both the version\n * fold and the model injection skip every other role.\n *\n * @param anchorId Message the gated branch prefix ends at. A queued send\n * passes the current tail, having waited through a run that grew the prefix\n * past the parent it was created with.\n */\n protected enrichAppendMetadata(\n message: AppendMessage,\n anchorId: string | null = message.parentId,\n ): AppendMessage {\n if (message.role !== \"user\") return message;\n const messages = this.messages;\n const parentIndex =\n anchorId === null ? -1 : messages.findIndex((m) => m.id === anchorId);\n const composerMetadata = gateInteractableComposerMetadata(\n this.getModelContext().unstable_composerMetadata,\n messages.slice(0, parentIndex + 1),\n );\n if (!composerMetadata) return message;\n return {\n ...message,\n metadata: {\n ...message.metadata,\n custom: { ...message.metadata?.custom, ...composerMetadata },\n },\n };\n }\n\n private _editComposers = new Map<string, DefaultEditComposerRuntimeCore>();\n public getEditComposer(messageId: string) {\n return this._editComposers.get(messageId);\n }\n public beginEdit(messageId: string) {\n if (this._editComposers.has(messageId))\n throw new Error(\"Edit already in progress\");\n\n this._editComposers.set(\n messageId,\n new DefaultEditComposerRuntimeCore(\n this,\n () => this._editComposers.delete(messageId),\n this.repository.getMessage(messageId),\n ),\n );\n this._notifySubscribers();\n }\n\n public getMessageById(messageId: string) {\n try {\n return this.repository.getMessage(messageId);\n } catch {\n // Check voice messages\n const baseMessages = this.repository.getMessages();\n const voiceIdx = this._voiceMessages.findIndex((m) => m.id === messageId);\n if (voiceIdx !== -1) {\n const parentId =\n voiceIdx > 0\n ? this._voiceMessages[voiceIdx - 1]!.id\n : (baseMessages.at(-1)?.id ?? null);\n return {\n parentId,\n message: this._voiceMessages[voiceIdx]!,\n index: baseMessages.length + voiceIdx,\n };\n }\n return undefined;\n }\n }\n\n public getBranches(messageId: string): string[] {\n if (this._voiceMessages.some((m) => m.id === messageId)) {\n return [];\n }\n return this.repository.getBranches(messageId);\n }\n\n public switchToBranch(branchId: string): void {\n this.repository.switchToBranch(branchId);\n this._notifySubscribers();\n }\n\n public _notifyEventSubscribers<E extends ThreadRuntimeEventType>(\n event: E,\n payload: ThreadRuntimeEventPayload[E],\n ) {\n const subscribers = this._eventSubscribers.get(event);\n if (!subscribers) return;\n\n notifyEventListeners(subscribers, payload, `Thread runtime \"${event}\"`);\n }\n\n public submitFeedback({ messageId, type }: SubmitFeedbackOptions) {\n const adapter = this.adapters?.feedback;\n if (!adapter) throw new Error(\"Feedback adapter not configured\");\n\n const { message, parentId } = this.repository.getMessage(messageId);\n adapter.submit({ message, type });\n\n if (message.role === \"assistant\") {\n const updatedMessage: ThreadMessage = {\n ...message,\n metadata: {\n ...message.metadata,\n submittedFeedback: { type },\n },\n };\n this.repository.addOrUpdateMessage(parentId, updatedMessage);\n }\n\n this._notifySubscribers();\n }\n\n private _stopSpeaking: Unsubscribe | undefined;\n public speech: SpeechState | undefined;\n\n public speak(messageId: string) {\n const adapter = this.adapters?.speech;\n if (!adapter) throw new Error(\"Speech adapter not configured\");\n\n const { message } = this.repository.getMessage(messageId);\n\n this._stopSpeaking?.();\n\n const utterance = adapter.speak(getThreadMessageText(message));\n const unsub = utterance.subscribe(() => {\n if (utterance.status.type === \"ended\") {\n this._stopSpeaking = undefined;\n this.speech = undefined;\n } else {\n this.speech = { messageId, status: utterance.status };\n }\n this._notifySubscribers();\n });\n\n this.speech = { messageId, status: utterance.status };\n this._notifySubscribers();\n\n this._stopSpeaking = () => {\n utterance.cancel();\n unsub();\n this.speech = undefined;\n this._stopSpeaking = undefined;\n };\n }\n\n public stopSpeaking() {\n if (!this._stopSpeaking) throw new Error(\"No message is being spoken\");\n this._stopSpeaking();\n this._notifySubscribers();\n }\n\n private _voiceSession: RealtimeVoiceAdapter.Session | undefined;\n private _voiceUnsubs: Array<() => void> = [];\n public voice: VoiceSessionState | undefined;\n\n private _voiceVolume = 0;\n private _voiceVolumeSubscribers = new Set<() => void>();\n\n public getVoiceVolume = () => this._voiceVolume;\n\n public subscribeVoiceVolume = (callback: () => void): Unsubscribe => {\n this._voiceVolumeSubscribers.add(callback);\n return () => this._voiceVolumeSubscribers.delete(callback);\n };\n\n public connectVoice() {\n const adapter = this.adapters?.voice;\n if (!adapter) throw new Error(\"Voice adapter not configured\");\n\n this.disconnectVoice();\n\n const session = adapter.connect({});\n this._voiceSession = session;\n const unsubs: Array<() => void> = [];\n\n let currentMode: RealtimeVoiceAdapter.Mode = \"listening\";\n\n this.voice = {\n status: session.status,\n isMuted: session.isMuted,\n mode: currentMode,\n };\n this._voiceVolume = 0;\n this._notifySubscribers();\n\n unsubs.push(\n session.onStatusChange((status) => {\n if (status.type === \"ended\") {\n this._finishVoiceAssistantMessage();\n this._voiceSession = undefined;\n this.voice = undefined;\n } else {\n this.voice = {\n status,\n isMuted: session.isMuted,\n mode: currentMode,\n };\n }\n this._notifySubscribers();\n }),\n );\n\n unsubs.push(\n session.onModeChange((mode) => {\n currentMode = mode;\n if (this.voice) {\n this.voice = { ...this.voice, mode };\n this._notifySubscribers();\n }\n }),\n );\n\n unsubs.push(\n session.onVolumeChange((volume) => {\n this._voiceVolume = volume;\n notifyEventListeners(\n this._voiceVolumeSubscribers,\n undefined,\n \"Voice volume\",\n );\n }),\n );\n\n unsubs.push(\n session.onTranscript((transcript) => {\n this._handleVoiceTranscript(transcript);\n }),\n );\n\n this._voiceUnsubs = unsubs;\n }\n\n private _currentAssistantMsg: ThreadAssistantMessage | null = null;\n\n private _handleVoiceTranscript(\n transcript: RealtimeVoiceAdapter.TranscriptItem,\n ) {\n this.ensureInitialized();\n\n if (transcript.role === \"user\") {\n this._finishVoiceAssistantMessage();\n this._currentAssistantMsg = null;\n\n if (transcript.isFinal) {\n this._voiceMessages.push({\n id: generateId(),\n role: \"user\",\n content: [{ type: \"text\", text: transcript.text }],\n metadata: { custom: {} },\n createdAt: new Date(),\n status: { type: \"complete\", reason: \"unknown\" },\n attachments: [],\n });\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n } else {\n if (!this._currentAssistantMsg) {\n this._currentAssistantMsg = {\n id: generateId(),\n role: \"assistant\",\n content: [{ type: \"text\", text: transcript.text }],\n metadata: {\n unstable_state: this.state,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n status: { type: \"running\" },\n createdAt: new Date(),\n };\n this._voiceMessages.push(this._currentAssistantMsg);\n } else {\n const idx = this._voiceMessages.indexOf(this._currentAssistantMsg);\n if (idx === -1) return;\n const updated: ThreadAssistantMessage = {\n ...this._currentAssistantMsg,\n content: [{ type: \"text\", text: transcript.text }],\n ...(transcript.isFinal\n ? { status: { type: \"complete\", reason: \"stop\" } }\n : {}),\n };\n this._voiceMessages[idx] = updated;\n this._currentAssistantMsg = updated;\n }\n\n if (transcript.isFinal) {\n this._currentAssistantMsg = null;\n }\n\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n }\n\n private _finishVoiceAssistantMessage() {\n const last = this._voiceMessages.at(-1);\n if (last?.role === \"assistant\" && last.status.type === \"running\") {\n const idx = this._voiceMessages.length - 1;\n this._voiceMessages[idx] = {\n ...(last as ThreadAssistantMessage),\n status: { type: \"complete\", reason: \"stop\" },\n };\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n }\n\n public disconnectVoice() {\n this._finishVoiceAssistantMessage();\n this._currentAssistantMsg = null;\n for (const unsub of this._voiceUnsubs) unsub();\n this._voiceUnsubs = [];\n this._voiceSession?.disconnect();\n this._voiceSession = undefined;\n this.voice = undefined;\n this._voiceVolume = 0;\n notifyEventListeners(\n this._voiceVolumeSubscribers,\n undefined,\n \"Voice volume\",\n );\n this._voiceMessages = [];\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n\n public muteVoice() {\n if (!this._voiceSession) throw new Error(\"No active voice session\");\n this._voiceSession.mute();\n this.voice = {\n ...this.voice!,\n isMuted: true,\n };\n this._notifySubscribers();\n }\n\n public unmuteVoice() {\n if (!this._voiceSession) throw new Error(\"No active voice session\");\n this._voiceSession.unmute();\n this.voice = {\n ...this.voice!,\n isMuted: false,\n };\n this._notifySubscribers();\n }\n\n protected ensureInitialized() {\n if (!this._isInitialized) {\n this._isInitialized = true;\n this._notifyEventSubscribers(\"initialize\", {});\n }\n }\n\n public export() {\n return this.repository.export();\n }\n\n public import(data: ExportedMessageRepository) {\n this.ensureInitialized();\n this.repository.clear();\n this.repository.import(data);\n this._notifySubscribers();\n }\n\n public reset(initialMessages?: readonly ThreadMessageLike[]) {\n this.import(ExportedMessageRepository.fromArray(initialMessages ?? []));\n }\n\n private _eventSubscribers = new Map<\n ThreadRuntimeEventType,\n Set<(payload?: unknown) => void>\n >();\n\n public unstable_on<E extends ThreadRuntimeEventType>(\n event: E,\n callback: ThreadRuntimeEventCallback<E>,\n ) {\n const wrapped = callback as (payload?: unknown) => void;\n if (event === \"modelContextUpdate\") {\n // provider.subscribe is `() => void`; pump the typed empty payload to the user callback.\n return (\n this._contextProvider.subscribe?.(() =>\n notifyEventListeners([wrapped], {}, `Thread runtime \"${event}\"`),\n ) ?? (() => {})\n );\n }\n\n let subscribers = this._eventSubscribers.get(event);\n if (!subscribers) {\n subscribers = new Set();\n this._eventSubscribers.set(event, subscribers);\n }\n subscribers.add(wrapped);\n\n // `initialize` latches: replay it (deferred) to subscribers that attach\n // after the thread already initialized, mirroring a BehaviorSubject.\n if (event === \"initialize\" && this._isInitialized) {\n queueMicrotask(() => {\n if (subscribers.has(wrapped)) {\n notifyEventListeners([wrapped], {}, `Thread runtime \"${event}\"`);\n }\n });\n }\n\n return () => {\n this._eventSubscribers.get(event)?.delete(wrapped);\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -2,8 +2,8 @@ import { AppendMessage } from "../../types/message.js";
|
|
|
2
2
|
import { AttachmentAdapter } from "../../adapters/attachment.js";
|
|
3
3
|
import { Unsubscribe } from "../../types/unsubscribe.js";
|
|
4
4
|
import { DictationAdapter } from "../../adapters/speech.js";
|
|
5
|
+
import { QueueItemState } from "../queue/queue-item.js";
|
|
5
6
|
import { QueuePlacement } from "../queue/external-thread-queue-adapter.js";
|
|
6
|
-
import { QueueItemState } from "../../store/scopes/queue-item.js";
|
|
7
7
|
import { SendOptions, ThreadComposerRuntimeCore } from "../interfaces/composer-runtime-core.js";
|
|
8
8
|
import { ThreadRuntimeCore } from "../interfaces/thread-runtime-core.js";
|
|
9
9
|
import { BaseComposerRuntimeCore } from "./base-composer-runtime-core.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-thread-composer-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/base/default-thread-composer-runtime-core.ts"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"default-thread-composer-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/base/default-thread-composer-runtime-core.ts"],"mappings":";;;;;;;;;;;cAmBa,yCACH,mCACG;MAEA;MAIA;UAIH;MAQY,kBAAkB;EAgBtB,cACd,qBACA,WAAW;EAKG,gBAAgB;YAItB,wBAAoB;YAIpB,uBAAmB;UAIrB;EAUN,YAAA,SAAS,KAAK;IACZ;MAEM,cAAc;MACd,YAAY;;;EAUf,WAVe;EAiCT,WACX,SAAS,KAAK,yCACd,UAAU,cAAW;EAWV,gBAAY"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EMPTY_QUEUE_ITEMS } from "
|
|
1
|
+
import { EMPTY_QUEUE_ITEMS } from "../queue/queue-item.js";
|
|
2
2
|
import { getThreadRuntimeCoreIsRunning } from "../api/thread-runtime.js";
|
|
3
3
|
import { BaseComposerRuntimeCore } from "./base-composer-runtime-core.js";
|
|
4
4
|
//#region src/runtime/base/default-thread-composer-runtime-core.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-thread-composer-runtime-core.js","names":["AppendMessage","AttachmentAdapter","DictationAdapter","SendOptions","ThreadComposerRuntimeCore","ThreadRuntimeCore","getThreadRuntimeCoreIsRunning","QueuePlacement","EMPTY_QUEUE_ITEMS","QueueItemState","BaseComposerRuntimeCore","isCancelable","runtime","Omit","capabilities","cancel","DefaultThreadComposerRuntimeCore","canCancel","canSend","isEmpty","isSendDisabled","_isSending","_queueCache","steer","queue","flat","getSteerQueueItems","getQueueItems","cache","length","moveQueueItem","queueItemId","placement","removeQueueItem","getAttachmentAdapter","adapters","attachments","getDictationAdapter","dictation","constructor","connect","lastCanCancel","lastIsSendDisabled","lastQueue","subscribe","changed","nextCanCancel","_notifySubscribers","handleSend","message","options","append","parentId","messages","at","id","sourceId","startRun","handleCancel","cancelRun"],"sources":["../../../src/runtime/base/default-thread-composer-runtime-core.ts"],"sourcesContent":["import type { AppendMessage } from \"../../types/message\";\nimport type { AttachmentAdapter } from \"../../adapters/attachment\";\nimport type { DictationAdapter } from \"../../adapters/speech\";\nimport type {\n SendOptions,\n ThreadComposerRuntimeCore,\n} from \"../interfaces/composer-runtime-core\";\nimport type { ThreadRuntimeCore } from \"../interfaces/thread-runtime-core\";\nimport { getThreadRuntimeCoreIsRunning } from \"../api/thread-runtime\";\nimport type { QueuePlacement } from \"../queue/external-thread-queue-adapter\";\nimport {
|
|
1
|
+
{"version":3,"file":"default-thread-composer-runtime-core.js","names":["AppendMessage","AttachmentAdapter","DictationAdapter","SendOptions","ThreadComposerRuntimeCore","ThreadRuntimeCore","getThreadRuntimeCoreIsRunning","QueuePlacement","EMPTY_QUEUE_ITEMS","QueueItemState","BaseComposerRuntimeCore","isCancelable","runtime","Omit","capabilities","cancel","DefaultThreadComposerRuntimeCore","canCancel","canSend","isEmpty","isSendDisabled","_isSending","_queueCache","steer","queue","flat","getSteerQueueItems","getQueueItems","cache","length","moveQueueItem","queueItemId","placement","removeQueueItem","getAttachmentAdapter","adapters","attachments","getDictationAdapter","dictation","constructor","connect","lastCanCancel","lastIsSendDisabled","lastQueue","subscribe","changed","nextCanCancel","_notifySubscribers","handleSend","message","options","append","parentId","messages","at","id","sourceId","startRun","handleCancel","cancelRun"],"sources":["../../../src/runtime/base/default-thread-composer-runtime-core.ts"],"sourcesContent":["import type { AppendMessage } from \"../../types/message\";\nimport type { AttachmentAdapter } from \"../../adapters/attachment\";\nimport type { DictationAdapter } from \"../../adapters/speech\";\nimport type {\n SendOptions,\n ThreadComposerRuntimeCore,\n} from \"../interfaces/composer-runtime-core\";\nimport type { ThreadRuntimeCore } from \"../interfaces/thread-runtime-core\";\nimport { getThreadRuntimeCoreIsRunning } from \"../api/thread-runtime\";\nimport type { QueuePlacement } from \"../queue/external-thread-queue-adapter\";\nimport { EMPTY_QUEUE_ITEMS, type QueueItemState } from \"../queue/queue-item\";\nimport { BaseComposerRuntimeCore } from \"./base-composer-runtime-core\";\n\nconst isCancelable = (runtime: Omit<ThreadRuntimeCore, \"composer\">) => {\n // capabilities is a subclass field assigned after this composer is constructed\n if (!runtime.capabilities?.cancel) return false;\n return getThreadRuntimeCoreIsRunning(runtime);\n};\n\nexport class DefaultThreadComposerRuntimeCore\n extends BaseComposerRuntimeCore\n implements ThreadComposerRuntimeCore\n{\n public get canCancel() {\n return isCancelable(this.runtime);\n }\n\n public get canSend() {\n return !this.isEmpty && !this.runtime.isSendDisabled && !this._isSending;\n }\n\n private _queueCache:\n | {\n steer: readonly QueueItemState[];\n queue: readonly QueueItemState[];\n flat: readonly QueueItemState[];\n }\n | undefined;\n\n public override get queue(): readonly QueueItemState[] {\n const steer = this.runtime.getSteerQueueItems?.() ?? EMPTY_QUEUE_ITEMS;\n const queue = this.runtime.getQueueItems?.() ?? EMPTY_QUEUE_ITEMS;\n const cache = this._queueCache;\n if (cache && cache.steer === steer && cache.queue === queue)\n return cache.flat;\n const flat =\n steer.length === 0\n ? queue\n : queue.length === 0\n ? steer\n : [...steer, ...queue];\n this._queueCache = { steer, queue, flat };\n return flat;\n }\n\n public override moveQueueItem(\n queueItemId: string,\n placement: QueuePlacement,\n ): void {\n this.runtime.moveQueueItem?.(queueItemId, placement);\n }\n\n public override removeQueueItem(queueItemId: string): void {\n this.runtime.removeQueueItem?.(queueItemId);\n }\n\n protected getAttachmentAdapter() {\n return this.runtime.adapters?.attachments;\n }\n\n protected getDictationAdapter() {\n return this.runtime.adapters?.dictation;\n }\n\n private runtime: Omit<ThreadRuntimeCore, \"composer\"> & {\n adapters?:\n | {\n attachments?: AttachmentAdapter | undefined;\n dictation?: DictationAdapter | undefined;\n }\n | undefined;\n };\n\n constructor(\n runtime: Omit<ThreadRuntimeCore, \"composer\"> & {\n adapters?:\n | {\n attachments?: AttachmentAdapter | undefined;\n dictation?: DictationAdapter | undefined;\n }\n | undefined;\n },\n ) {\n super();\n this.runtime = runtime;\n this.connect();\n }\n\n public connect() {\n let lastCanCancel = false;\n let lastIsSendDisabled = this.runtime.isSendDisabled;\n let lastQueue = this.queue;\n return this.runtime.subscribe(() => {\n let changed = false;\n const nextCanCancel = this.canCancel;\n if (lastCanCancel !== nextCanCancel) {\n lastCanCancel = nextCanCancel;\n changed = true;\n }\n if (lastIsSendDisabled !== this.runtime.isSendDisabled) {\n lastIsSendDisabled = this.runtime.isSendDisabled;\n changed = true;\n }\n if (lastQueue !== this.queue) {\n lastQueue = this.queue;\n changed = true;\n }\n if (changed) this._notifySubscribers();\n });\n }\n\n public async handleSend(\n message: Omit<AppendMessage, \"parentId\" | \"sourceId\">,\n options?: SendOptions,\n ) {\n return this.runtime.append({\n ...(message as AppendMessage),\n parentId: this.runtime.messages.at(-1)?.id ?? null,\n sourceId: null,\n startRun: options?.startRun,\n steer: options?.steer,\n });\n }\n\n public async handleCancel() {\n this.runtime.cancelRun();\n }\n}\n"],"mappings":";;;;AAaA,MAAMW,gBAAgBC,YAAiD;CAErE,IAAI,CAACA,QAAQE,cAAcC,QAAQ,OAAO;CAC1C,OAAOT,8BAA8BM,OAAO;AAC9C;AAEA,IAAaI,mCAAb,cACUN,wBAEV;CACE,IAAWO,YAAY;EACrB,OAAON,aAAa,KAAKC,OAAO;CAClC;CAEA,IAAWM,UAAU;EACnB,OAAO,CAAC,KAAKC,WAAW,CAAC,KAAKP,QAAQQ,kBAAkB,CAAC,KAAKC;CAChE;CAEA;CAQA,IAAoBG,QAAmC;EACrD,MAAMD,QAAQ,KAAKX,QAAQc,qBAAqB,KAAKlB;EACrD,MAAMgB,QAAQ,KAAKZ,QAAQe,gBAAgB,KAAKnB;EAChD,MAAMoB,QAAQ,KAAKN;EACnB,IAAIM,SAASA,MAAML,UAAUA,SAASK,MAAMJ,UAAUA,OACpD,OAAOI,MAAMH;EACf,MAAMA,OACJF,MAAMM,WAAW,IACbL,QACAA,MAAMK,WAAW,IACfN,QACA,CAAC,GAAGA,OAAO,GAAGC,KAAK;EAC3B,KAAKF,cAAc;GAAEC;GAAOC;GAAOC;EAAK;EACxC,OAAOA;CACT;CAEA,cACEM,aACAC,WACM;EACN,KAAKpB,QAAQkB,gBAAgBC,aAAaC,SAAS;CACrD;CAEA,gBAAgCD,aAA2B;EACzD,KAAKnB,QAAQqB,kBAAkBF,WAAW;CAC5C;CAEA,uBAAiC;EAC/B,OAAO,KAAKnB,QAAQuB,UAAUC;CAChC;CAEA,sBAAgC;EAC9B,OAAO,KAAKxB,QAAQuB,UAAUG;CAChC;CAEA;CASAC,YACE3B,SAQA;EACA,MAAM;EACN,KAAKA,UAAUA;EACf,KAAK4B,QAAQ;CACf;CAEA,UAAiB;EACf,IAAIC,gBAAgB;EACpB,IAAIC,qBAAqB,KAAK9B,QAAQQ;EACtC,IAAIuB,YAAY,KAAKnB;EACrB,OAAO,KAAKZ,QAAQgC,gBAAgB;GAClC,IAAIC,UAAU;GACd,MAAMC,gBAAgB,KAAK7B;GAC3B,IAAIwB,kBAAkBK,eAAe;IACnCL,gBAAgBK;IAChBD,UAAU;GACZ;GACA,IAAIH,uBAAuB,KAAK9B,QAAQQ,gBAAgB;IACtDsB,qBAAqB,KAAK9B,QAAQQ;IAClCyB,UAAU;GACZ;GACA,IAAIF,cAAc,KAAKnB,OAAO;IAC5BmB,YAAY,KAAKnB;IACjBqB,UAAU;GACZ;GACA,IAAIA,SAAS,KAAKE,mBAAmB;EACvC,CAAC;CACH;CAEA,MAAaC,WACXC,SACAC,SACA;EACA,OAAO,KAAKtC,QAAQuC,OAAO;GACzB,GAAIF;GACJG,UAAU,KAAKxC,QAAQyC,SAASC,GAAG,EAAE,CAAC,EAAEC,MAAM;GAC9CC,UAAU;GACVC,UAAUP,SAASO;GACnBlC,OAAO2B,SAAS3B;EAClB,CAAC;CACH;CAEA,MAAamC,eAAe;EAC1B,KAAK9C,QAAQ+C,UAAU;CACzB;AACF"}
|
|
@@ -3,8 +3,8 @@ import { Attachment, CreateAttachment } from "../../types/attachment.js";
|
|
|
3
3
|
import { Unsubscribe } from "../../types/unsubscribe.js";
|
|
4
4
|
import { DictationAdapter } from "../../adapters/speech.js";
|
|
5
5
|
import { QuoteInfo } from "../../types/quote.js";
|
|
6
|
+
import { QueueItemState } from "../queue/queue-item.js";
|
|
6
7
|
import { QueuePlacement } from "../queue/external-thread-queue-adapter.js";
|
|
7
|
-
import { QueueItemState } from "../../store/scopes/queue-item.js";
|
|
8
8
|
//#region src/runtime/interfaces/composer-runtime-core.d.ts
|
|
9
9
|
type AttachmentAddErrorReason = "no-adapter" | "not-accepted" | "adapter-error";
|
|
10
10
|
type AttachmentAddErrorEvent = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Unsubscribe } from "../../types/unsubscribe.js";
|
|
2
|
-
import { ThreadRuntimeCore } from "./thread-runtime-core.js";
|
|
2
|
+
import { ThreadRuntimeCore, ThreadRuntimeEventType } from "./thread-runtime-core.js";
|
|
3
3
|
//#region src/runtime/interfaces/thread-list-runtime-core.d.ts
|
|
4
4
|
type ThreadListItemStatus = "archived" | "regular" | "new" | "deleted";
|
|
5
5
|
type ThreadListItemCoreState = {
|
|
@@ -12,6 +12,10 @@ type ThreadListItemCoreState = {
|
|
|
12
12
|
readonly custom?: Record<string, unknown> | undefined;
|
|
13
13
|
readonly runtime?: ThreadRuntimeCore | undefined;
|
|
14
14
|
};
|
|
15
|
+
type ThreadListRuntimeEvent = {
|
|
16
|
+
readonly threadId: string;
|
|
17
|
+
readonly type: ThreadRuntimeEventType;
|
|
18
|
+
};
|
|
15
19
|
type ThreadListRuntimeCore = {
|
|
16
20
|
readonly isLoading: boolean;
|
|
17
21
|
readonly isLoadingMore?: boolean;
|
|
@@ -32,6 +36,14 @@ type ThreadListRuntimeCore = {
|
|
|
32
36
|
* running, and the main thread's run state is read from its runtime directly.
|
|
33
37
|
*/
|
|
34
38
|
unstable_isThreadRunning?(threadId: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Lifecycle events from every thread this list keeps alive, including
|
|
41
|
+
* threads that are not the main one. Implemented by thread lists that keep
|
|
42
|
+
* runtimes alive for non-main threads. A thread list that mounts only the
|
|
43
|
+
* main thread leaves this undefined: its other threads have no runtime and so
|
|
44
|
+
* emit nothing, and the main thread's runtime is observed directly.
|
|
45
|
+
*/
|
|
46
|
+
unstable_subscribeThreadEvents?(callback: (event: ThreadListRuntimeEvent) => void): Unsubscribe;
|
|
35
47
|
getItemById(threadId: string): ThreadListItemCoreState | undefined;
|
|
36
48
|
switchToThread(threadId: string, options?: {
|
|
37
49
|
unarchive?: boolean;
|
|
@@ -55,5 +67,5 @@ type ThreadListRuntimeCore = {
|
|
|
55
67
|
subscribe(callback: () => void): Unsubscribe;
|
|
56
68
|
};
|
|
57
69
|
//#endregion
|
|
58
|
-
export { ThreadListItemCoreState, ThreadListItemStatus, ThreadListRuntimeCore };
|
|
70
|
+
export { ThreadListItemCoreState, ThreadListItemStatus, ThreadListRuntimeCore, ThreadListRuntimeEvent };
|
|
59
71
|
//# sourceMappingURL=thread-list-runtime-core.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-list-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/interfaces/thread-list-runtime-core.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"thread-list-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/interfaces/thread-list-runtime-core.ts"],"mappings":";;;KAMY;KAEA;WACD;WACA;WACA;WAEA,QAAQ;WACR;WACA,gBAAgB;WAChB,SAAS;WAET,UAAU;;KAGT;WACD;WACA,MAAM;;KAGL;WACD;WACA;WACA;EACT;EACA;EAEA;EACA;WAES,aAAa,SAAS,eAAe;EAE9C,4BAA4B;EAC5B,qBAAqB,mBAAmB;;;;;;;;;EAUxC,0BAA0B;;;;;;;;EAS1B,gCACE,WAAW,OAAO,kCACjB;EAEH,YAAY,mBAAmB;EAE/B,eACE,kBACA;IAAY;MACX;EACH,qBAAqB;EAErB,yBAAyB;EACzB,WAAW;EACX,qBAAqB;EACrB,aAAa;EAEb,OAAO,mBAAmB;EAC1B,OAAO,kBAAkB,mBAAmB;EAC5C,cACE,kBACA,QAAQ,sCACP;EACH,QAAQ,mBAAmB;EAC3B,UAAU,mBAAmB;EAC7B,OAAO,mBAAmB;EAE1B,WACE,mBACC;IAAU;IAAkB;;EAC/B,cAAc,mBAAmB;EAEjC,UAAU,uBAAuB"}
|