@assistant-ui/core 0.3.15 → 0.3.16
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/internal.d.ts +7 -2
- package/dist/internal.js +8 -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 +2 -0
- package/dist/model-context/frame/provider.d.ts.map +1 -1
- package/dist/model-context/frame/provider.js +88 -25
- 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/react/client/InMemoryThreadList.d.ts.map +1 -1
- package/dist/react/client/InMemoryThreadList.js +24 -20
- 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 +59 -177
- package/dist/react/client/Interactables.js.map +1 -1
- package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
- package/dist/react/client/RemoteThreadList.js +23 -56
- package/dist/react/client/RemoteThreadList.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
- package/dist/react/interactables-legacy/Interactables.js +56 -174
- 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/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/message/MessageParts.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +23 -55
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.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/cloud/AssistantCloudThreadHistoryAdapter.d.ts +3 -10
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +20 -67
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
- 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/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/runtime/api/composer-runtime.d.ts +1 -1
- package/dist/runtime/api/composer-runtime.js.map +1 -1
- package/dist/runtime/api/thread-runtime.d.ts +1 -2
- 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 +2 -4
- package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.js +3 -9
- 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-runtime-core.d.ts +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 +6 -1
- package/dist/runtime/utils/auto-status.d.ts.map +1 -1
- package/dist/runtime/utils/auto-status.js +7 -1
- package/dist/runtime/utils/auto-status.js.map +1 -1
- package/dist/runtime/utils/external-message-conversion.d.ts +47 -0
- package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -0
- package/dist/runtime/utils/external-message-conversion.js +221 -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/thread-message-like.d.ts +2 -1
- package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
- package/dist/runtime/utils/thread-message-like.js.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 +19 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js +122 -20
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +20 -2
- 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 +77 -1
- package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -0
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
- package/dist/store/clients/external-thread.d.ts.map +1 -1
- package/dist/store/clients/external-thread.js +74 -99
- 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 +1 -1
- 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 +16 -7
- package/dist/store/clients/suggestions.js.map +1 -1
- package/dist/store/index.d.ts +4 -2
- 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/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/types/message.d.ts +7 -3
- package/dist/types/message.d.ts.map +1 -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 +10 -10
- package/src/internal.ts +12 -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 +267 -12
- package/src/model-context/frame/provider.ts +113 -31
- 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/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.test.ts +96 -0
- package/src/react/client/RemoteThreadList.ts +27 -59
- 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/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +26 -56
- package/src/react/runtimes/assistant-transport/runManager.ts +4 -17
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +92 -0
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +40 -141
- package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.test.ts +37 -0
- package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.ts +18 -0
- 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 +58 -481
- package/src/runtime/api/composer-runtime.ts +1 -1
- package/src/runtime/api/message-runtime.test.ts +28 -1
- package/src/runtime/base/base-composer-runtime-core.ts +20 -40
- package/src/runtime/base/base-thread-runtime-core.test.ts +16 -0
- package/src/runtime/base/base-thread-runtime-core.ts +6 -11
- 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-runtime-core.ts +1 -1
- 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.ts +33 -0
- package/src/runtime/utils/external-message-conversion.test.ts +113 -0
- package/src/runtime/utils/external-message-conversion.ts +494 -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/thread-message-like.ts +2 -0
- 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 +175 -28
- package/src/runtimes/local/local-thread-runtime-core.test.ts +172 -1
- package/src/runtimes/local/local-thread-runtime-core.ts +48 -3
- package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +37 -0
- package/src/runtimes/remote-thread-list/remote-thread-state.ts +123 -0
- package/src/runtimes/tool-invocations/EDGE_CASES.md +17 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +140 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +3 -0
- package/src/store/clients/external-thread.ts +16 -61
- package/src/store/clients/single-thread-list.ts +4 -1
- package/src/store/clients/suggestions.test.ts +31 -0
- package/src/store/clients/suggestions.ts +18 -19
- package/src/store/scopes/message.ts +1 -1
- package/src/store/scopes/queue-item.ts +2 -9
- package/src/tests/MessageRepository.test.ts +77 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +194 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-title-race.test.ts +158 -0
- package/src/tests/external-store-thread-runtime-core-adapter.test.ts +164 -0
- package/src/tests/external-store-thread-runtime-core.test.ts +642 -0
- package/src/tests/external-thread-attachments.test.tsx +173 -0
- package/src/tests/single-thread-list-item.test.tsx +47 -0
- package/src/tests/thread-message-like.test.ts +39 -1
- package/src/types/message.ts +8 -3
- 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,8 +1,13 @@
|
|
|
1
1
|
import { MessageStatus } from "../../types/message.js";
|
|
2
|
+
import { ThreadMessageLike } from "./thread-message-like.js";
|
|
2
3
|
import { ReadonlyJSONValue } from "assistant-stream/utils";
|
|
3
4
|
//#region src/runtime/utils/auto-status.d.ts
|
|
5
|
+
type ThreadMessageLikeContentItem = Exclude<ThreadMessageLike["content"], string>[number];
|
|
6
|
+
declare const isPendingToolCall: (c: ThreadMessageLikeContentItem) => boolean;
|
|
7
|
+
declare const isInterruptedToolCall: (c: ThreadMessageLikeContentItem) => boolean;
|
|
4
8
|
declare const isAutoStatus: (status: MessageStatus) => boolean;
|
|
5
9
|
declare const getAutoStatus: (isLast: boolean, isRunning: boolean, hasInterruptedToolCalls: boolean, hasPendingToolCalls: boolean, error?: ReadonlyJSONValue) => MessageStatus;
|
|
10
|
+
declare const getContentAutoStatus: (content: ThreadMessageLike["content"], isLast: boolean, isRunning: boolean) => MessageStatus;
|
|
6
11
|
//#endregion
|
|
7
|
-
export { getAutoStatus, isAutoStatus };
|
|
12
|
+
export { getAutoStatus, getContentAutoStatus, isAutoStatus, isInterruptedToolCall, isPendingToolCall };
|
|
8
13
|
//# sourceMappingURL=auto-status.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-status.d.ts","names":[],"sources":["../../../src/runtime/utils/auto-status.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"auto-status.d.ts","names":[],"sources":["../../../src/runtime/utils/auto-status.ts"],"mappings":";;;;KAIK,+BAA+B,QAClC;cAIW,oBAAqB,GAAG;cAGxB,wBACX,GAAG;cA8CQ,eAAgB,QAAQ;cAGxB,gBACX,iBACA,oBACA,kCACA,8BACA,QAAQ,sBACP;cAqBU,uBACX,SAAS,8BACT,iBACA,uBACC"}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
//#region src/runtime/utils/auto-status.ts
|
|
2
|
+
const isPendingToolCall = (c) => c.type === "tool-call" && c.result === void 0;
|
|
3
|
+
const isInterruptedToolCall = (c) => {
|
|
4
|
+
if (c.type !== "tool-call" || c.result !== void 0) return false;
|
|
5
|
+
return c.interrupt != null || c.approval != null && c.approval.approved === void 0 && c.approval.resolution === void 0;
|
|
6
|
+
};
|
|
2
7
|
const symbolAutoStatus = Symbol("autoStatus");
|
|
3
8
|
const AUTO_STATUS_RUNNING = Object.freeze(Object.assign({ type: "running" }, { [symbolAutoStatus]: true }));
|
|
4
9
|
const AUTO_STATUS_COMPLETE = Object.freeze(Object.assign({
|
|
@@ -22,7 +27,8 @@ const getAutoStatus = (isLast, isRunning, hasInterruptedToolCalls, hasPendingToo
|
|
|
22
27
|
}, { [symbolAutoStatus]: true });
|
|
23
28
|
return isLast && isRunning ? AUTO_STATUS_RUNNING : hasInterruptedToolCalls ? AUTO_STATUS_INTERRUPT : hasPendingToolCalls ? AUTO_STATUS_PENDING : AUTO_STATUS_COMPLETE;
|
|
24
29
|
};
|
|
30
|
+
const getContentAutoStatus = (content, isLast, isRunning) => getAutoStatus(isLast, isRunning, typeof content !== "string" && content.some(isInterruptedToolCall), typeof content !== "string" && content.some(isPendingToolCall));
|
|
25
31
|
//#endregion
|
|
26
|
-
export { getAutoStatus, isAutoStatus };
|
|
32
|
+
export { getAutoStatus, getContentAutoStatus, isAutoStatus, isInterruptedToolCall, isPendingToolCall };
|
|
27
33
|
|
|
28
34
|
//# sourceMappingURL=auto-status.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-status.js","names":["MessageStatus","ReadonlyJSONValue","symbolAutoStatus","Symbol","AUTO_STATUS_RUNNING","Object","freeze","assign","
|
|
1
|
+
{"version":3,"file":"auto-status.js","names":["MessageStatus","ReadonlyJSONValue","ThreadMessageLike","ThreadMessageLikeContentItem","Exclude","isPendingToolCall","c","type","result","undefined","isInterruptedToolCall","interrupt","approval","approved","resolution","symbolAutoStatus","Symbol","AUTO_STATUS_RUNNING","Object","freeze","assign","const","AUTO_STATUS_COMPLETE","reason","AUTO_STATUS_PENDING","AUTO_STATUS_INTERRUPT","isAutoStatus","status","getAutoStatus","isLast","isRunning","hasInterruptedToolCalls","hasPendingToolCalls","error","getContentAutoStatus","content","some"],"sources":["../../../src/runtime/utils/auto-status.ts"],"sourcesContent":["import type { MessageStatus } from \"../../types/message\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport type { ThreadMessageLike } from \"./thread-message-like\";\n\ntype ThreadMessageLikeContentItem = Exclude<\n ThreadMessageLike[\"content\"],\n string\n>[number];\n\nexport const isPendingToolCall = (c: ThreadMessageLikeContentItem): boolean =>\n c.type === \"tool-call\" && c.result === undefined;\n\nexport const isInterruptedToolCall = (\n c: ThreadMessageLikeContentItem,\n): boolean => {\n if (c.type !== \"tool-call\" || c.result !== undefined) return false;\n return (\n c.interrupt != null ||\n (c.approval != null &&\n c.approval.approved === undefined &&\n c.approval.resolution === undefined)\n );\n};\n\nconst symbolAutoStatus = Symbol(\"autoStatus\");\n\nconst AUTO_STATUS_RUNNING = Object.freeze(\n Object.assign({ type: \"running\" as const }, { [symbolAutoStatus]: true }),\n);\nconst AUTO_STATUS_COMPLETE = Object.freeze(\n Object.assign(\n {\n type: \"complete\" as const,\n reason: \"unknown\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nconst AUTO_STATUS_PENDING = Object.freeze(\n Object.assign(\n {\n type: \"requires-action\" as const,\n reason: \"tool-calls\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nconst AUTO_STATUS_INTERRUPT = Object.freeze(\n Object.assign(\n {\n type: \"requires-action\" as const,\n reason: \"interrupt\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nexport const isAutoStatus = (status: MessageStatus) =>\n (status as any)[symbolAutoStatus] === true;\n\nexport const getAutoStatus = (\n isLast: boolean,\n isRunning: boolean,\n hasInterruptedToolCalls: boolean,\n hasPendingToolCalls: boolean,\n error?: ReadonlyJSONValue,\n): MessageStatus => {\n if (isLast && error) {\n return Object.assign(\n {\n type: \"incomplete\" as const,\n reason: \"error\" as const,\n error: error,\n },\n { [symbolAutoStatus]: true },\n );\n }\n\n return isLast && isRunning\n ? AUTO_STATUS_RUNNING\n : hasInterruptedToolCalls\n ? AUTO_STATUS_INTERRUPT\n : hasPendingToolCalls\n ? AUTO_STATUS_PENDING\n : AUTO_STATUS_COMPLETE;\n};\n\nexport const getContentAutoStatus = (\n content: ThreadMessageLike[\"content\"],\n isLast: boolean,\n isRunning: boolean,\n): MessageStatus =>\n getAutoStatus(\n isLast,\n isRunning,\n typeof content !== \"string\" && content.some(isInterruptedToolCall),\n typeof content !== \"string\" && content.some(isPendingToolCall),\n );\n"],"mappings":";AASA,MAAaK,qBAAqBC,MAChCA,EAAEC,SAAS,eAAeD,EAAEE,WAAWC,KAAAA;AAEzC,MAAaC,yBACXJ,MACY;CACZ,IAAIA,EAAEC,SAAS,eAAeD,EAAEE,WAAWC,KAAAA,GAAW,OAAO;CAC7D,OACEH,EAAEK,aAAa,QACdL,EAAEM,YAAY,QACbN,EAAEM,SAASC,aAAaJ,KAAAA,KACxBH,EAAEM,SAASE,eAAeL,KAAAA;AAEhC;AAEA,MAAMM,mBAAmBC,OAAO,YAAY;AAE5C,MAAMC,sBAAsBC,OAAOC,OACjCD,OAAOE,OAAO,EAAEb,MAAM,UAAmB,GAAG,GAAGQ,mBAAmB,KAAK,CAAC,CAC1E;AACA,MAAMO,uBAAuBJ,OAAOC,OAClCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAMS,sBAAsBN,OAAOC,OACjCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAMU,wBAAwBP,OAAOC,OACnCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAaW,gBAAgBC,WAC1BA,OAAeZ,sBAAsB;AAExC,MAAaa,iBACXC,QACAC,WACAC,yBACAC,qBACAC,UACkB;CAClB,IAAIJ,UAAUI,OACZ,OAAOf,OAAOE,OACZ;EACEb,MAAM;EACNgB,QAAQ;EACDU;CACT,GACA,GAAGlB,mBAAmB,KAAK,CAC7B;CAGF,OAAOc,UAAUC,YACbb,sBACAc,0BACEN,wBACAO,sBACER,sBACAF;AACV;AAEA,MAAaY,wBACXC,SACAN,QACAC,cAEAF,cACEC,QACAC,WACA,OAAOK,YAAY,YAAYA,QAAQC,KAAK1B,qBAAqB,GACjE,OAAOyB,YAAY,YAAYA,QAAQC,KAAK/B,iBAAiB,CAC/D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { MessageTiming, ThreadMessage } from "../../types/message.js";
|
|
2
|
+
import { ThreadMessageLike } from "./thread-message-like.js";
|
|
3
|
+
import { ToolExecutionStatus } from "../../runtimes/tool-invocations/ToolInvocationTracker.js";
|
|
4
|
+
import { ReadonlyJSONValue } from "assistant-stream/utils";
|
|
5
|
+
//#region src/runtime/utils/external-message-conversion.d.ts
|
|
6
|
+
type JoinStrategy = "concat-content" | "none";
|
|
7
|
+
type ExternalMessageConverterMessage = (ThreadMessageLike & {
|
|
8
|
+
readonly convertConfig?: {
|
|
9
|
+
readonly joinStrategy?: JoinStrategy;
|
|
10
|
+
};
|
|
11
|
+
}) | {
|
|
12
|
+
role: "tool";
|
|
13
|
+
toolCallId: string;
|
|
14
|
+
toolName?: string | undefined;
|
|
15
|
+
result: any;
|
|
16
|
+
artifact?: any;
|
|
17
|
+
isError?: boolean;
|
|
18
|
+
messages?: readonly ThreadMessage[];
|
|
19
|
+
};
|
|
20
|
+
type ExternalMessageConverterMetadata = {
|
|
21
|
+
readonly toolStatuses?: Record<string, ToolExecutionStatus>;
|
|
22
|
+
readonly error?: ReadonlyJSONValue;
|
|
23
|
+
readonly messageTiming?: Record<string, MessageTiming>;
|
|
24
|
+
};
|
|
25
|
+
type ExternalMessageConverterCallback<T> = (message: T, metadata: ExternalMessageConverterMetadata) => ExternalMessageConverterMessage | ExternalMessageConverterMessage[];
|
|
26
|
+
type ExternalMessageConverterCallbackResult<T> = {
|
|
27
|
+
input: T;
|
|
28
|
+
outputs: ExternalMessageConverterMessage[];
|
|
29
|
+
};
|
|
30
|
+
type ExternalMessageConverterChunk<T> = {
|
|
31
|
+
inputs: T[];
|
|
32
|
+
outputs: ExternalMessageConverterMessage[];
|
|
33
|
+
};
|
|
34
|
+
declare const convertExternalMessageCallback: <T>(input: T, callback: ExternalMessageConverterCallback<T>, metadata: ExternalMessageConverterMetadata) => ExternalMessageConverterCallbackResult<T>;
|
|
35
|
+
declare const joinExternalMessages: (messages: readonly ExternalMessageConverterMessage[]) => ThreadMessageLike;
|
|
36
|
+
declare const chunkExternalMessages: <T>(callbackResults: ExternalMessageConverterCallbackResult<T>[], joinStrategy?: JoinStrategy) => ExternalMessageConverterChunk<T>[];
|
|
37
|
+
declare const shallowArrayEqual: (a: unknown[], b: unknown[]) => boolean;
|
|
38
|
+
type ExternalMessageConversionCache = {
|
|
39
|
+
message: ThreadMessage | undefined;
|
|
40
|
+
generatedFallbackMessages: WeakSet<object>;
|
|
41
|
+
};
|
|
42
|
+
declare const convertExternalMessageChunk: <T>(message: ExternalMessageConverterChunk<T>, idx: number, chunkCount: number, isRunning: boolean, error: ReadonlyJSONValue | undefined, cache?: ExternalMessageConversionCache) => ThreadMessage;
|
|
43
|
+
declare const completeExternalMessageConversion: (messages: ThreadMessage[], error: ReadonlyJSONValue | undefined) => ThreadMessage[];
|
|
44
|
+
declare const convertExternalMessages: <T extends WeakKey>(messages: T[], callback: ExternalMessageConverterCallback<T>, isRunning: boolean, metadata: ExternalMessageConverterMetadata) => ThreadMessage[];
|
|
45
|
+
//#endregion
|
|
46
|
+
export { ExternalMessageConverterCallback, ExternalMessageConverterCallbackResult, ExternalMessageConverterChunk, ExternalMessageConverterMessage, ExternalMessageConverterMetadata, JoinStrategy, chunkExternalMessages, completeExternalMessageConversion, convertExternalMessageCallback, convertExternalMessageChunk, convertExternalMessages, joinExternalMessages, shallowArrayEqual };
|
|
47
|
+
//# sourceMappingURL=external-message-conversion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-message-conversion.d.ts","names":[],"sources":["../../../src/runtime/utils/external-message-conversion.ts"],"mappings":";;;;;KA2BY;KAEA,mCACP;WACU;aACE,eAAe;;;EAI1B;EACA;EACA;EACA;EACA;EACA;EACA,oBAAoB;;KAGd;WACD,eAAe,eAAe;WAC9B,QAAQ;WACR,gBAAgB,eAAe;;KAG9B,iCAAiC,MAC3C,SAAS,GACT,UAAU,qCACP,kCAAkC;KAE3B,uCAAuC;EACjD,OAAO;EACP,SAAS;;KAGC,8BAA8B;EACxC,QAAQ;EACR,SAAS;;cAsDE,iCAAkC,GAC7C,OAAO,GACP,UAAU,iCAAiC,IAC3C,UAAU,qCACT,uCAAuC;cAY7B,uBACX,mBAAmB,sCAClB;cA4KU,wBAAyB,GACpC,iBAAiB,uCAAuC,MACxD,eAAe,iBAAY,8BAAA;cAmDhB,oBAAqB,cAAc;KAQ3C;EACH,SAAS;EACT,2BAA2B;;cAGhB,8BAA+B,GAC1C,SAAS,8BAA8B,IACvC,aACA,oBACA,oBACA,OAAO,+BACP,QAAQ,mCAA8B;cAiF3B,oCACX,UAAU,iBACV,OAAO,kCAA6B;cAWzB,0BAA2B,UAAU,SAChD,UAAU,KACV,UAAU,iCAAiC,IAC3C,oBACA,UAAU,qCAAgC"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { isJSONValueEqual } from "../../utils/json/is-json-equal.js";
|
|
2
|
+
import { generateErrorMessageId } from "../../utils/id.js";
|
|
3
|
+
import { fromThreadMessageLike } from "./thread-message-like.js";
|
|
4
|
+
import { FALLBACK_ID_PREFIX, bindExternalStoreMessage, getExternalStoreMessages, symbolInnerMessage } from "./external-store-message.js";
|
|
5
|
+
import { getAutoStatus, isAutoStatus, isInterruptedToolCall, isPendingToolCall } from "./auto-status.js";
|
|
6
|
+
//#region src/runtime/utils/external-message-conversion.ts
|
|
7
|
+
const stringifyForError = (value) => {
|
|
8
|
+
let text;
|
|
9
|
+
try {
|
|
10
|
+
text = value instanceof Error ? String(value) : JSON.stringify(value);
|
|
11
|
+
} catch {}
|
|
12
|
+
text ??= String(value);
|
|
13
|
+
return text.length > 200 ? `${text.slice(0, 200)}…` : text;
|
|
14
|
+
};
|
|
15
|
+
const toCallbackOutputs = (output, input) => {
|
|
16
|
+
const outputs = Array.isArray(output) ? output : [output];
|
|
17
|
+
for (const o of outputs) if (!(typeof o === "object" && o !== null && (o.role === "tool" || (o.role === "assistant" || o.role === "user" || o.role === "system") && (typeof o.content === "string" || Array.isArray(o.content))))) throw new Error(`External message converter: the converter callback returned an invalid message (${stringifyForError(o)}) for input ${stringifyForError(input)}. Return an empty array to skip a message.`);
|
|
18
|
+
return outputs.filter((o) => {
|
|
19
|
+
if (o.role !== "tool") return true;
|
|
20
|
+
if (typeof o.toolCallId === "string" && o.toolCallId.length > 0) return true;
|
|
21
|
+
if (!warnedDroppedToolResults.has(o)) {
|
|
22
|
+
warnedDroppedToolResults.add(o);
|
|
23
|
+
console.warn(`External message converter: dropping a tool result without a toolCallId (${stringifyForError(o)}) for input ${stringifyForError(input)}.`);
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
const warnedDroppedToolResults = /* @__PURE__ */ new WeakSet();
|
|
29
|
+
const convertExternalMessageCallback = (input, callback, metadata) => ({
|
|
30
|
+
input,
|
|
31
|
+
outputs: toCallbackOutputs(callback(input, metadata), input)
|
|
32
|
+
});
|
|
33
|
+
const mergeInnerMessages = (existing, incoming) => ({ [symbolInnerMessage]: [...existing[symbolInnerMessage] ?? [], ...incoming[symbolInnerMessage] ?? []] });
|
|
34
|
+
const joinExternalMessages = (messages) => {
|
|
35
|
+
const assistantMessage = {
|
|
36
|
+
role: "assistant",
|
|
37
|
+
content: []
|
|
38
|
+
};
|
|
39
|
+
for (const output of messages) if (output.role === "tool") {
|
|
40
|
+
const toolCallIdx = assistantMessage.content.findIndex((c) => c.type === "tool-call" && c.toolCallId === output.toolCallId);
|
|
41
|
+
if (toolCallIdx !== -1) {
|
|
42
|
+
const toolCall = assistantMessage.content[toolCallIdx];
|
|
43
|
+
if (output.toolName != null) {
|
|
44
|
+
if (toolCall.toolName !== output.toolName) throw new Error(`Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`);
|
|
45
|
+
}
|
|
46
|
+
assistantMessage.content[toolCallIdx] = {
|
|
47
|
+
...toolCall,
|
|
48
|
+
[symbolInnerMessage]: [...toolCall[symbolInnerMessage] ?? [], output],
|
|
49
|
+
result: output.result,
|
|
50
|
+
artifact: output.artifact,
|
|
51
|
+
isError: output.isError,
|
|
52
|
+
messages: output.messages
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
const role = output.role;
|
|
57
|
+
const content = (typeof output.content === "string" ? [{
|
|
58
|
+
type: "text",
|
|
59
|
+
text: output.content
|
|
60
|
+
}] : output.content).map((c) => ({
|
|
61
|
+
...c,
|
|
62
|
+
[symbolInnerMessage]: [output]
|
|
63
|
+
}));
|
|
64
|
+
switch (role) {
|
|
65
|
+
case "system":
|
|
66
|
+
case "user": return {
|
|
67
|
+
...output,
|
|
68
|
+
content
|
|
69
|
+
};
|
|
70
|
+
case "assistant":
|
|
71
|
+
if (assistantMessage.content.length === 0) {
|
|
72
|
+
assistantMessage.id = output.id;
|
|
73
|
+
assistantMessage.createdAt ??= output.createdAt;
|
|
74
|
+
assistantMessage.status ??= output.status;
|
|
75
|
+
if (output.attachments) assistantMessage.attachments = [...assistantMessage.attachments ?? [], ...output.attachments];
|
|
76
|
+
}
|
|
77
|
+
if (output.metadata) {
|
|
78
|
+
assistantMessage.metadata ??= {};
|
|
79
|
+
if (output.metadata.unstable_state !== void 0) assistantMessage.metadata.unstable_state = output.metadata.unstable_state;
|
|
80
|
+
if (output.metadata.unstable_annotations) assistantMessage.metadata.unstable_annotations = [...assistantMessage.metadata.unstable_annotations ?? [], ...output.metadata.unstable_annotations];
|
|
81
|
+
if (output.metadata.unstable_data) assistantMessage.metadata.unstable_data = [...assistantMessage.metadata.unstable_data ?? [], ...output.metadata.unstable_data];
|
|
82
|
+
if (output.metadata.steps) assistantMessage.metadata.steps = [...assistantMessage.metadata.steps ?? [], ...output.metadata.steps];
|
|
83
|
+
if (output.metadata.custom) assistantMessage.metadata.custom = {
|
|
84
|
+
...assistantMessage.metadata.custom ?? {},
|
|
85
|
+
...output.metadata.custom
|
|
86
|
+
};
|
|
87
|
+
if (output.metadata.timing) assistantMessage.metadata.timing = output.metadata.timing;
|
|
88
|
+
if (output.metadata.submittedFeedback) assistantMessage.metadata.submittedFeedback = output.metadata.submittedFeedback;
|
|
89
|
+
if (output.metadata.isOptimistic) assistantMessage.metadata.isOptimistic = true;
|
|
90
|
+
}
|
|
91
|
+
for (const part of content) {
|
|
92
|
+
if (part.type === "tool-call") {
|
|
93
|
+
const existingIdx = assistantMessage.content.findIndex((c) => c.type === "tool-call" && c.toolCallId === part.toolCallId);
|
|
94
|
+
if (existingIdx !== -1) {
|
|
95
|
+
const existing = assistantMessage.content[existingIdx];
|
|
96
|
+
assistantMessage.content[existingIdx] = {
|
|
97
|
+
...existing,
|
|
98
|
+
...part,
|
|
99
|
+
...mergeInnerMessages(existing, part)
|
|
100
|
+
};
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (part.type === "reasoning" && "parentId" in part && part.parentId) {
|
|
105
|
+
const existingIdx = assistantMessage.content.findIndex((c) => c.type === "reasoning" && "parentId" in c && c.parentId === part.parentId);
|
|
106
|
+
if (existingIdx !== -1) {
|
|
107
|
+
const existing = assistantMessage.content[existingIdx];
|
|
108
|
+
assistantMessage.content[existingIdx] = {
|
|
109
|
+
...existing,
|
|
110
|
+
text: `${existing.text}\n\n${part.text}`,
|
|
111
|
+
...mergeInnerMessages(existing, part)
|
|
112
|
+
};
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
assistantMessage.content.push(part);
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
119
|
+
default: throw new Error(`Unknown message role: ${role}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return assistantMessage;
|
|
123
|
+
};
|
|
124
|
+
const chunkExternalMessages = (callbackResults, joinStrategy) => {
|
|
125
|
+
const results = [];
|
|
126
|
+
let isAssistant = false;
|
|
127
|
+
let pendingNone = false;
|
|
128
|
+
let inputs = [];
|
|
129
|
+
let outputs = [];
|
|
130
|
+
const flush = () => {
|
|
131
|
+
if (outputs.length) results.push({
|
|
132
|
+
inputs,
|
|
133
|
+
outputs
|
|
134
|
+
});
|
|
135
|
+
inputs = [];
|
|
136
|
+
outputs = [];
|
|
137
|
+
isAssistant = false;
|
|
138
|
+
pendingNone = false;
|
|
139
|
+
};
|
|
140
|
+
for (const callbackResult of callbackResults) for (const output of callbackResult.outputs) {
|
|
141
|
+
if (pendingNone && output.role !== "tool" || !isAssistant || output.role === "user" || output.role === "system") flush();
|
|
142
|
+
isAssistant = output.role === "assistant" || output.role === "tool";
|
|
143
|
+
if (inputs.at(-1) !== callbackResult.input) inputs.push(callbackResult.input);
|
|
144
|
+
outputs.push(output);
|
|
145
|
+
if (output.role === "assistant" && (output.convertConfig?.joinStrategy === "none" || joinStrategy === "none")) pendingNone = true;
|
|
146
|
+
}
|
|
147
|
+
flush();
|
|
148
|
+
return results;
|
|
149
|
+
};
|
|
150
|
+
const shallowArrayEqual = (a, b) => {
|
|
151
|
+
if (a.length !== b.length) return false;
|
|
152
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
153
|
+
return true;
|
|
154
|
+
};
|
|
155
|
+
const convertExternalMessageChunk = (message, idx, chunkCount, isRunning, error, cache) => {
|
|
156
|
+
const isLast = idx === chunkCount - 1;
|
|
157
|
+
const joined = joinExternalMessages(message.outputs);
|
|
158
|
+
const hasInterruptedToolCalls = typeof joined.content === "object" && joined.content.some(isInterruptedToolCall);
|
|
159
|
+
const hasPendingToolCalls = typeof joined.content === "object" && joined.content.some(isPendingToolCall);
|
|
160
|
+
const autoStatus = getAutoStatus(isLast, isRunning, hasInterruptedToolCalls, hasPendingToolCalls, isLast ? error : void 0);
|
|
161
|
+
const fallbackId = `${FALLBACK_ID_PREFIX}${idx}`;
|
|
162
|
+
const cachedMessage = cache?.message;
|
|
163
|
+
if (cachedMessage && (cachedMessage.role !== "assistant" || !isAutoStatus(cachedMessage.status) || cachedMessage.status === autoStatus || cachedMessage.status.type === "incomplete" && cachedMessage.status.reason === "error" && cachedMessage.status.error !== void 0 && autoStatus.type === "incomplete" && autoStatus.reason === "error" && autoStatus.error !== void 0 && (cachedMessage.status.error === autoStatus.error || isJSONValueEqual(cachedMessage.status.error, autoStatus.error)))) {
|
|
164
|
+
const inputs = getExternalStoreMessages(cachedMessage);
|
|
165
|
+
if (shallowArrayEqual(inputs, message.inputs)) {
|
|
166
|
+
if (cache.generatedFallbackMessages.has(cachedMessage) && cachedMessage.id !== fallbackId) {
|
|
167
|
+
const updated = {
|
|
168
|
+
...cachedMessage,
|
|
169
|
+
id: fallbackId
|
|
170
|
+
};
|
|
171
|
+
cache.generatedFallbackMessages.add(updated);
|
|
172
|
+
bindExternalStoreMessage(updated, message.inputs);
|
|
173
|
+
return updated;
|
|
174
|
+
}
|
|
175
|
+
return cachedMessage;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const newMessage = fromThreadMessageLike(joined, fallbackId, autoStatus);
|
|
179
|
+
if (cache && joined.id == null) cache.generatedFallbackMessages.add(newMessage);
|
|
180
|
+
bindExternalStoreMessage(newMessage, message.inputs);
|
|
181
|
+
return newMessage;
|
|
182
|
+
};
|
|
183
|
+
function createErrorAssistantMessage(error) {
|
|
184
|
+
const msg = {
|
|
185
|
+
id: generateErrorMessageId(),
|
|
186
|
+
role: "assistant",
|
|
187
|
+
content: [],
|
|
188
|
+
status: {
|
|
189
|
+
type: "incomplete",
|
|
190
|
+
reason: "error",
|
|
191
|
+
error
|
|
192
|
+
},
|
|
193
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
194
|
+
metadata: {
|
|
195
|
+
unstable_state: null,
|
|
196
|
+
unstable_annotations: [],
|
|
197
|
+
unstable_data: [],
|
|
198
|
+
custom: {},
|
|
199
|
+
steps: []
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
bindExternalStoreMessage(msg, []);
|
|
203
|
+
return msg;
|
|
204
|
+
}
|
|
205
|
+
const completeExternalMessageConversion = (messages, error) => {
|
|
206
|
+
if (error) {
|
|
207
|
+
const lastMessage = messages.at(-1);
|
|
208
|
+
if (!lastMessage || lastMessage.role !== "assistant") messages.push(createErrorAssistantMessage(error));
|
|
209
|
+
}
|
|
210
|
+
return messages;
|
|
211
|
+
};
|
|
212
|
+
const convertExternalMessages = (messages, callback, isRunning, metadata) => {
|
|
213
|
+
const callbackResults = messages.map((message) => convertExternalMessageCallback(message, callback, metadata));
|
|
214
|
+
const chunks = chunkExternalMessages(callbackResults);
|
|
215
|
+
const result = chunks.map((message, idx) => convertExternalMessageChunk(message, idx, chunks.length, isRunning, metadata.error));
|
|
216
|
+
return completeExternalMessageConversion(result, metadata.error);
|
|
217
|
+
};
|
|
218
|
+
//#endregion
|
|
219
|
+
export { chunkExternalMessages, completeExternalMessageConversion, convertExternalMessageCallback, convertExternalMessageChunk, convertExternalMessages, joinExternalMessages, shallowArrayEqual };
|
|
220
|
+
|
|
221
|
+
//# sourceMappingURL=external-message-conversion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-message-conversion.js","names":["ReadonlyJSONValue","ToolExecutionStatus","ThreadAssistantMessage","ThreadMessage","ToolCallMessagePart","MessageTiming","generateErrorMessageId","isJSONValueEqual","getAutoStatus","isAutoStatus","isInterruptedToolCall","isPendingToolCall","bindExternalStoreMessage","FALLBACK_ID_PREFIX","getExternalStoreMessages","symbolInnerMessage","fromThreadMessageLike","ThreadMessageLike","JoinStrategy","ExternalMessageConverterMessage","convertConfig","joinStrategy","role","toolCallId","toolName","result","artifact","isError","messages","ExternalMessageConverterMetadata","toolStatuses","Record","error","messageTiming","ExternalMessageConverterCallback","message","T","metadata","ExternalMessageConverterCallbackResult","input","outputs","ExternalMessageConverterChunk","inputs","Mutable","P","stringifyForError","value","text","Error","String","JSON","stringify","length","slice","toCallbackOutputs","output","Array","isArray","o","valid","content","filter","warnedDroppedToolResults","has","add","console","warn","WeakSet","convertExternalMessageCallback","callback","mergeInnerMessages","existing","incoming","joinExternalMessages","assistantMessage","Omit","Exclude","toolCallIdx","findIndex","c","type","toolCall","const","map","id","createdAt","status","attachments","unstable_state","undefined","unstable_annotations","unstable_data","steps","custom","timing","submittedFeedback","isOptimistic","part","existingIdx","parentId","push","unsupportedRole","chunkExternalMessages","callbackResults","results","isAssistant","pendingNone","flush","callbackResult","at","shallowArrayEqual","a","b","i","ExternalMessageConversionCache","generatedFallbackMessages","convertExternalMessageChunk","idx","chunkCount","isRunning","cache","isLast","joined","hasInterruptedToolCalls","some","hasPendingToolCalls","autoStatus","fallbackId","cachedMessage","reason","updated","newMessage","createErrorAssistantMessage","msg","Date","completeExternalMessageConversion","lastMessage","convertExternalMessages","WeakKey","chunks"],"sources":["../../../src/runtime/utils/external-message-conversion.ts"],"sourcesContent":["import type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport type { ToolExecutionStatus } from \"../../runtimes/tool-invocations/ToolInvocationTracker\";\nimport type {\n ThreadAssistantMessage,\n ThreadMessage,\n ToolCallMessagePart,\n} from \"../../types/message\";\nimport type { MessageTiming } from \"../../types/message\";\nimport { generateErrorMessageId } from \"../../utils/id\";\nimport { isJSONValueEqual } from \"../../utils/json/is-json-equal\";\nimport {\n getAutoStatus,\n isAutoStatus,\n isInterruptedToolCall,\n isPendingToolCall,\n} from \"./auto-status\";\nimport {\n bindExternalStoreMessage,\n FALLBACK_ID_PREFIX,\n getExternalStoreMessages,\n symbolInnerMessage,\n} from \"./external-store-message\";\nimport {\n fromThreadMessageLike,\n type ThreadMessageLike,\n} from \"./thread-message-like\";\n\nexport type JoinStrategy = \"concat-content\" | \"none\";\n\nexport type ExternalMessageConverterMessage =\n | (ThreadMessageLike & {\n readonly convertConfig?: {\n readonly joinStrategy?: JoinStrategy;\n };\n })\n | {\n role: \"tool\";\n toolCallId: string;\n toolName?: string | undefined;\n result: any;\n artifact?: any;\n isError?: boolean;\n messages?: readonly ThreadMessage[];\n };\n\nexport type ExternalMessageConverterMetadata = {\n readonly toolStatuses?: Record<string, ToolExecutionStatus>;\n readonly error?: ReadonlyJSONValue;\n readonly messageTiming?: Record<string, MessageTiming>;\n};\n\nexport type ExternalMessageConverterCallback<T> = (\n message: T,\n metadata: ExternalMessageConverterMetadata,\n) => ExternalMessageConverterMessage | ExternalMessageConverterMessage[];\n\nexport type ExternalMessageConverterCallbackResult<T> = {\n input: T;\n outputs: ExternalMessageConverterMessage[];\n};\n\nexport type ExternalMessageConverterChunk<T> = {\n inputs: T[];\n outputs: ExternalMessageConverterMessage[];\n};\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nconst stringifyForError = (value: unknown) => {\n let text;\n try {\n text = value instanceof Error ? String(value) : JSON.stringify(value);\n } catch {\n /* circular */\n }\n text ??= String(value);\n return text.length > 200 ? `${text.slice(0, 200)}…` : text;\n};\n\nconst toCallbackOutputs = (\n output: ExternalMessageConverterMessage | ExternalMessageConverterMessage[],\n input: unknown,\n): ExternalMessageConverterMessage[] => {\n const outputs = Array.isArray(output) ? output : [output];\n for (const o of outputs) {\n const valid =\n typeof o === \"object\" &&\n o !== null &&\n (o.role === \"tool\" ||\n ((o.role === \"assistant\" || o.role === \"user\" || o.role === \"system\") &&\n (typeof o.content === \"string\" || Array.isArray(o.content))));\n if (!valid)\n throw new Error(\n `External message converter: the converter callback returned an invalid message (${stringifyForError(o)}) for input ${stringifyForError(input)}. Return an empty array to skip a message.`,\n );\n }\n // Providers can emit tool results without a usable id (react-langchain maps\n // a missing tool_call_id to \"\"); converters must not throw on those, so the\n // result is dropped like any other orphaned tool output.\n return outputs.filter((o) => {\n if (o.role !== \"tool\") return true;\n if (typeof o.toolCallId === \"string\" && o.toolCallId.length > 0)\n return true;\n if (!warnedDroppedToolResults.has(o)) {\n warnedDroppedToolResults.add(o);\n console.warn(\n `External message converter: dropping a tool result without a toolCallId (${stringifyForError(o)}) for input ${stringifyForError(input)}.`,\n );\n }\n return false;\n });\n};\n\nconst warnedDroppedToolResults = new WeakSet<object>();\n\nexport const convertExternalMessageCallback = <T>(\n input: T,\n callback: ExternalMessageConverterCallback<T>,\n metadata: ExternalMessageConverterMetadata,\n): ExternalMessageConverterCallbackResult<T> => ({\n input,\n outputs: toCallbackOutputs(callback(input, metadata), input),\n});\n\nconst mergeInnerMessages = (existing: object, incoming: object) => ({\n [symbolInnerMessage]: [\n ...((existing as any)[symbolInnerMessage] ?? []),\n ...((incoming as any)[symbolInnerMessage] ?? []),\n ],\n});\n\nexport const joinExternalMessages = (\n messages: readonly ExternalMessageConverterMessage[],\n): ThreadMessageLike => {\n const assistantMessage: Mutable<Omit<ThreadMessageLike, \"metadata\">> & {\n content: Exclude<ThreadMessageLike[\"content\"][0], string>[];\n metadata?: Mutable<ThreadMessageLike[\"metadata\"]>;\n } = {\n role: \"assistant\",\n content: [],\n };\n for (const output of messages) {\n if (output.role === \"tool\") {\n const toolCallIdx = assistantMessage.content.findIndex(\n (c) => c.type === \"tool-call\" && c.toolCallId === output.toolCallId,\n );\n // Ignore orphaned tool results so one bad tool message does not\n // prevent rendering the rest of the conversation.\n if (toolCallIdx !== -1) {\n const toolCall = assistantMessage.content[\n toolCallIdx\n ]! as ToolCallMessagePart;\n if (output.toolName != null) {\n if (toolCall.toolName !== output.toolName)\n throw new Error(\n `Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`,\n );\n }\n assistantMessage.content[toolCallIdx] = {\n ...toolCall,\n ...{\n [symbolInnerMessage]: [\n ...((toolCall as any)[symbolInnerMessage] ?? []),\n output,\n ],\n },\n result: output.result,\n artifact: output.artifact,\n isError: output.isError,\n messages: output.messages,\n };\n }\n } else {\n const role = output.role;\n const content = (\n typeof output.content === \"string\"\n ? [{ type: \"text\" as const, text: output.content }]\n : output.content\n ).map((c) => ({\n ...c,\n ...{ [symbolInnerMessage]: [output] },\n }));\n switch (role) {\n case \"system\":\n case \"user\":\n return {\n ...output,\n content,\n };\n case \"assistant\":\n if (assistantMessage.content.length === 0) {\n assistantMessage.id = output.id;\n assistantMessage.createdAt ??= output.createdAt;\n assistantMessage.status ??= output.status;\n\n if (output.attachments) {\n assistantMessage.attachments = [\n ...(assistantMessage.attachments ?? []),\n ...output.attachments,\n ];\n }\n }\n\n if (output.metadata) {\n assistantMessage.metadata ??= {};\n if (output.metadata.unstable_state !== undefined) {\n assistantMessage.metadata.unstable_state =\n output.metadata.unstable_state;\n }\n if (output.metadata.unstable_annotations) {\n assistantMessage.metadata.unstable_annotations = [\n ...(assistantMessage.metadata.unstable_annotations ?? []),\n ...output.metadata.unstable_annotations,\n ];\n }\n if (output.metadata.unstable_data) {\n assistantMessage.metadata.unstable_data = [\n ...(assistantMessage.metadata.unstable_data ?? []),\n ...output.metadata.unstable_data,\n ];\n }\n if (output.metadata.steps) {\n assistantMessage.metadata.steps = [\n ...(assistantMessage.metadata.steps ?? []),\n ...output.metadata.steps,\n ];\n }\n if (output.metadata.custom) {\n assistantMessage.metadata.custom = {\n ...(assistantMessage.metadata.custom ?? {}),\n ...output.metadata.custom,\n };\n }\n\n if (output.metadata.timing) {\n assistantMessage.metadata.timing = output.metadata.timing;\n }\n\n if (output.metadata.submittedFeedback) {\n assistantMessage.metadata.submittedFeedback =\n output.metadata.submittedFeedback;\n }\n\n if (output.metadata.isOptimistic) {\n assistantMessage.metadata.isOptimistic = true;\n }\n // TODO keep this in sync with ThreadMessageLike[\"metadata\"] / fromThreadMessageLike\n }\n\n // Add content parts, merging reasoning parts with same parentId\n for (const part of content) {\n if (part.type === \"tool-call\") {\n const existingIdx = assistantMessage.content.findIndex(\n (c) =>\n c.type === \"tool-call\" && c.toolCallId === part.toolCallId,\n );\n if (existingIdx !== -1) {\n const existing = assistantMessage.content[\n existingIdx\n ] as typeof part;\n assistantMessage.content[existingIdx] = {\n ...existing,\n ...part,\n ...mergeInnerMessages(existing, part),\n };\n continue;\n }\n }\n\n if (\n part.type === \"reasoning\" &&\n \"parentId\" in part &&\n part.parentId\n ) {\n const existingIdx = assistantMessage.content.findIndex(\n (c) =>\n c.type === \"reasoning\" &&\n \"parentId\" in c &&\n c.parentId === part.parentId,\n );\n if (existingIdx !== -1) {\n const existing = assistantMessage.content[\n existingIdx\n ] as typeof part;\n assistantMessage.content[existingIdx] = {\n ...existing,\n text: `${existing.text}\\n\\n${part.text}`,\n ...mergeInnerMessages(existing, part),\n };\n continue;\n }\n }\n assistantMessage.content.push(part);\n }\n break;\n default: {\n const unsupportedRole: never = role;\n throw new Error(`Unknown message role: ${unsupportedRole}`);\n }\n }\n }\n }\n return assistantMessage;\n};\n\nexport const chunkExternalMessages = <T>(\n callbackResults: ExternalMessageConverterCallbackResult<T>[],\n joinStrategy?: JoinStrategy,\n) => {\n const results: ExternalMessageConverterChunk<T>[] = [];\n let isAssistant = false;\n let pendingNone = false; // true if the previous assistant message had joinStrategy \"none\"\n let inputs: T[] = [];\n let outputs: ExternalMessageConverterMessage[] = [];\n\n const flush = () => {\n if (outputs.length) {\n results.push({\n inputs,\n outputs,\n });\n }\n inputs = [];\n outputs = [];\n isAssistant = false;\n pendingNone = false;\n };\n\n for (const callbackResult of callbackResults) {\n for (const output of callbackResult.outputs) {\n if (\n (pendingNone && output.role !== \"tool\") ||\n !isAssistant ||\n output.role === \"user\" ||\n output.role === \"system\"\n ) {\n flush();\n }\n isAssistant = output.role === \"assistant\" || output.role === \"tool\";\n\n if (inputs.at(-1) !== callbackResult.input) {\n inputs.push(callbackResult.input);\n }\n outputs.push(output);\n\n if (\n output.role === \"assistant\" &&\n (output.convertConfig?.joinStrategy === \"none\" ||\n joinStrategy === \"none\")\n ) {\n pendingNone = true;\n }\n }\n }\n flush();\n return results;\n};\n\nexport const shallowArrayEqual = (a: unknown[], b: unknown[]) => {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n\ntype ExternalMessageConversionCache = {\n message: ThreadMessage | undefined;\n generatedFallbackMessages: WeakSet<object>;\n};\n\nexport const convertExternalMessageChunk = <T>(\n message: ExternalMessageConverterChunk<T>,\n idx: number,\n chunkCount: number,\n isRunning: boolean,\n error: ReadonlyJSONValue | undefined,\n cache?: ExternalMessageConversionCache,\n) => {\n const isLast = idx === chunkCount - 1;\n const joined = joinExternalMessages(message.outputs);\n const hasInterruptedToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isInterruptedToolCall);\n const hasPendingToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isPendingToolCall);\n const autoStatus = getAutoStatus(\n isLast,\n isRunning,\n hasInterruptedToolCalls,\n hasPendingToolCalls,\n isLast ? error : undefined,\n );\n const fallbackId = `${FALLBACK_ID_PREFIX}${idx}`;\n\n const cachedMessage = cache?.message;\n if (\n cachedMessage &&\n (cachedMessage.role !== \"assistant\" ||\n !isAutoStatus(cachedMessage.status) ||\n cachedMessage.status === autoStatus ||\n (cachedMessage.status.type === \"incomplete\" &&\n cachedMessage.status.reason === \"error\" &&\n cachedMessage.status.error !== undefined &&\n autoStatus.type === \"incomplete\" &&\n autoStatus.reason === \"error\" &&\n autoStatus.error !== undefined &&\n (cachedMessage.status.error === autoStatus.error ||\n isJSONValueEqual(cachedMessage.status.error, autoStatus.error))))\n ) {\n const inputs = getExternalStoreMessages<T>(cachedMessage);\n if (shallowArrayEqual(inputs, message.inputs)) {\n // A positional fallback id goes stale when messages are prepended\n // or reordered; serving it unchanged makes two messages collide on\n // one id and the dedup downstream drops one of them.\n if (\n cache.generatedFallbackMessages.has(cachedMessage) &&\n cachedMessage.id !== fallbackId\n ) {\n const updated = { ...cachedMessage, id: fallbackId };\n cache.generatedFallbackMessages.add(updated);\n bindExternalStoreMessage(updated, message.inputs);\n return updated;\n }\n return cachedMessage;\n }\n }\n\n const newMessage = fromThreadMessageLike(joined, fallbackId, autoStatus);\n if (cache && joined.id == null) {\n cache.generatedFallbackMessages.add(newMessage);\n }\n bindExternalStoreMessage(newMessage, message.inputs);\n return newMessage;\n};\n\nfunction createErrorAssistantMessage(\n error: ReadonlyJSONValue,\n): ThreadAssistantMessage {\n const msg: ThreadAssistantMessage = {\n id: generateErrorMessageId(),\n role: \"assistant\",\n content: [],\n status: { type: \"incomplete\", reason: \"error\", error },\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n custom: {},\n steps: [],\n },\n };\n bindExternalStoreMessage(msg, []);\n return msg;\n}\n\nexport const completeExternalMessageConversion = (\n messages: ThreadMessage[],\n error: ReadonlyJSONValue | undefined,\n) => {\n if (error) {\n const lastMessage = messages.at(-1);\n if (!lastMessage || lastMessage.role !== \"assistant\") {\n messages.push(createErrorAssistantMessage(error));\n }\n }\n return messages;\n};\n\nexport const convertExternalMessages = <T extends WeakKey>(\n messages: T[],\n callback: ExternalMessageConverterCallback<T>,\n isRunning: boolean,\n metadata: ExternalMessageConverterMetadata,\n) => {\n const callbackResults = messages.map((message) =>\n convertExternalMessageCallback(message, callback, metadata),\n );\n const chunks = chunkExternalMessages(callbackResults);\n const result = chunks.map((message, idx) =>\n convertExternalMessageChunk(\n message,\n idx,\n chunks.length,\n isRunning,\n metadata.error,\n ),\n );\n return completeExternalMessageConversion(result, metadata.error);\n};\n"],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ declare const bindExternalStoreMessage: <T>(target: object, message: T | T[]) =>
|
|
|
12
12
|
declare const getExternalStoreMessages: <T>(input: {
|
|
13
13
|
messages: readonly ThreadMessage[];
|
|
14
14
|
} | ThreadMessage | ThreadMessage["content"][number]) => T[];
|
|
15
|
+
declare const FALLBACK_ID_PREFIX = "__external_store_fallback_";
|
|
15
16
|
//#endregion
|
|
16
|
-
export { bindExternalStoreMessage, getExternalStoreMessages, symbolInnerMessage };
|
|
17
|
+
export { FALLBACK_ID_PREFIX, bindExternalStoreMessage, getExternalStoreMessages, symbolInnerMessage };
|
|
17
18
|
//# sourceMappingURL=external-store-message.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-store-message.d.ts","names":[],"sources":["../../../src/runtime/utils/external-store-message.ts"],"mappings":";;cAEa;;;;;;;;cAiBA,2BAA4B,GACvC,gBACA,SAAS,IAAI;cAMF,2BAA4B,GACvC;EACM,mBAAmB;IACrB,gBACA,qCAAgC"}
|
|
1
|
+
{"version":3,"file":"external-store-message.d.ts","names":[],"sources":["../../../src/runtime/utils/external-store-message.ts"],"mappings":";;cAEa;;;;;;;;cAiBA,2BAA4B,GACvC,gBACA,SAAS,IAAI;cAMF,2BAA4B,GACvC;EACM,mBAAmB;IACrB,gBACA,qCAAgC;cAczB"}
|
|
@@ -21,7 +21,8 @@ const getExternalStoreMessages = (input) => {
|
|
|
21
21
|
container[symbolInnerMessages] = [value];
|
|
22
22
|
return container[symbolInnerMessages];
|
|
23
23
|
};
|
|
24
|
+
const FALLBACK_ID_PREFIX = "__external_store_fallback_";
|
|
24
25
|
//#endregion
|
|
25
|
-
export { bindExternalStoreMessage, getExternalStoreMessages, symbolInnerMessage };
|
|
26
|
+
export { FALLBACK_ID_PREFIX, bindExternalStoreMessage, getExternalStoreMessages, symbolInnerMessage };
|
|
26
27
|
|
|
27
28
|
//# sourceMappingURL=external-store-message.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-store-message.js","names":["ThreadMessage","symbolInnerMessage","Symbol","symbolInnerMessages","WithInnerMessages","T","EMPTY_ARRAY","bindExternalStoreMessage","target","message","getExternalStoreMessages","input","messages","container","value","Array","isArray"],"sources":["../../../src/runtime/utils/external-store-message.ts"],"sourcesContent":["import type { ThreadMessage } from \"../../types/message\";\n\nexport const symbolInnerMessage = Symbol(\"innerMessage\");\nconst symbolInnerMessages = Symbol(\"innerMessages\");\n\ntype WithInnerMessages<T> = {\n [symbolInnerMessage]?: T | T[];\n [symbolInnerMessages]?: T[];\n};\n\nconst EMPTY_ARRAY: never[] = [];\n\n/**\n * Attach the original external store message(s) to a ThreadMessage or message part.\n * This is a no-op if the target already has a bound message.\n * Use `getExternalStoreMessages` to retrieve the bound messages later.\n *\n * @deprecated This API is experimental and may change without notice.\n */\nexport const bindExternalStoreMessage = <T>(\n target: object,\n message: T | T[],\n): void => {\n if (symbolInnerMessage in target) return;\n (target as WithInnerMessages<T>)[symbolInnerMessage] = message;\n};\n\nexport const getExternalStoreMessages = <T>(\n input:\n | { messages: readonly ThreadMessage[] }\n | ThreadMessage\n | ThreadMessage[\"content\"][number],\n) => {\n const container = (\n \"messages\" in input ? input.messages : input\n ) as WithInnerMessages<T>;\n const value = container[symbolInnerMessages] || container[symbolInnerMessage];\n if (!value) return EMPTY_ARRAY;\n if (Array.isArray(value)) {\n return value;\n }\n container[symbolInnerMessages] = [value];\n return container[symbolInnerMessages];\n};\n"],"mappings":";AAEA,MAAaC,qBAAqBC,OAAO,cAAc;AACvD,MAAMC,sBAAsBD,OAAO,eAAe;AAOlD,MAAMI,cAAuB,CAAA;;;;;;;;AAS7B,MAAaC,4BACXC,QACAC,YACS;CACT,IAAIR,sBAAsBO,QAAQ;CAClC,OAAiCP,sBAAsBQ;AACzD;AAEA,MAAaC,4BACXC,UAIG;CACH,MAAME,YACJ,cAAcF,QAAQA,MAAMC,WAAWD;CAEzC,MAAMG,QAAQD,UAAUV,wBAAwBU,UAAUZ;CAC1D,IAAI,CAACa,OAAO,OAAOR;CACnB,IAAIS,MAAMC,QAAQF,KAAK,GACrB,OAAOA;CAETD,UAAUV,uBAAuB,CAACW,KAAK;CACvC,OAAOD,UAAUV;AACnB"}
|
|
1
|
+
{"version":3,"file":"external-store-message.js","names":["ThreadMessage","symbolInnerMessage","Symbol","symbolInnerMessages","WithInnerMessages","T","EMPTY_ARRAY","bindExternalStoreMessage","target","message","getExternalStoreMessages","input","messages","container","value","Array","isArray","FALLBACK_ID_PREFIX"],"sources":["../../../src/runtime/utils/external-store-message.ts"],"sourcesContent":["import type { ThreadMessage } from \"../../types/message\";\n\nexport const symbolInnerMessage = Symbol(\"innerMessage\");\nconst symbolInnerMessages = Symbol(\"innerMessages\");\n\ntype WithInnerMessages<T> = {\n [symbolInnerMessage]?: T | T[];\n [symbolInnerMessages]?: T[];\n};\n\nconst EMPTY_ARRAY: never[] = [];\n\n/**\n * Attach the original external store message(s) to a ThreadMessage or message part.\n * This is a no-op if the target already has a bound message.\n * Use `getExternalStoreMessages` to retrieve the bound messages later.\n *\n * @deprecated This API is experimental and may change without notice.\n */\nexport const bindExternalStoreMessage = <T>(\n target: object,\n message: T | T[],\n): void => {\n if (symbolInnerMessage in target) return;\n (target as WithInnerMessages<T>)[symbolInnerMessage] = message;\n};\n\nexport const getExternalStoreMessages = <T>(\n input:\n | { messages: readonly ThreadMessage[] }\n | ThreadMessage\n | ThreadMessage[\"content\"][number],\n) => {\n const container = (\n \"messages\" in input ? input.messages : input\n ) as WithInnerMessages<T>;\n const value = container[symbolInnerMessages] || container[symbolInnerMessage];\n if (!value) return EMPTY_ARRAY;\n if (Array.isArray(value)) {\n return value;\n }\n container[symbolInnerMessages] = [value];\n return container[symbolInnerMessages];\n};\n\nexport const FALLBACK_ID_PREFIX = \"__external_store_fallback_\";\n"],"mappings":";AAEA,MAAaC,qBAAqBC,OAAO,cAAc;AACvD,MAAMC,sBAAsBD,OAAO,eAAe;AAOlD,MAAMI,cAAuB,CAAA;;;;;;;;AAS7B,MAAaC,4BACXC,QACAC,YACS;CACT,IAAIR,sBAAsBO,QAAQ;CAClC,OAAiCP,sBAAsBQ;AACzD;AAEA,MAAaC,4BACXC,UAIG;CACH,MAAME,YACJ,cAAcF,QAAQA,MAAMC,WAAWD;CAEzC,MAAMG,QAAQD,UAAUV,wBAAwBU,UAAUZ;CAC1D,IAAI,CAACa,OAAO,OAAOR;CACnB,IAAIS,MAAMC,QAAQF,KAAK,GACrB,OAAOA;CAETD,UAAUV,uBAAuB,CAACW,KAAK;CACvC,OAAOD,UAAUV;AACnB;AAEA,MAAac,qBAAqB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ThreadMessage } from "../../types/message.js";
|
|
2
|
+
import { ExportedMessageRepository, MessageRepository } from "./message-repository.js";
|
|
3
|
+
//#region src/runtime/utils/message-repository-session.d.ts
|
|
4
|
+
type MessageRepositorySessionOptions = {
|
|
5
|
+
decorateExport?: (exported: ExportedMessageRepository, repository: MessageRepository) => ExportedMessageRepository;
|
|
6
|
+
};
|
|
7
|
+
declare const createMessageRepositorySession: (options?: MessageRepositorySessionOptions) => {
|
|
8
|
+
getMessages: () => readonly ThreadMessage[];
|
|
9
|
+
readonly headId: string | null;
|
|
10
|
+
export: () => ExportedMessageRepository;
|
|
11
|
+
tryGetMessage: (messageId: string) => {
|
|
12
|
+
parentId: string | null;
|
|
13
|
+
message: ThreadMessage;
|
|
14
|
+
index: number;
|
|
15
|
+
} | undefined;
|
|
16
|
+
tryGetMessages: (messageId: string) => readonly ThreadMessage[] | undefined;
|
|
17
|
+
hasMessage: (messageId: string) => boolean;
|
|
18
|
+
addOrUpdateMessage: (parentId: string | null, message: ThreadMessage) => void;
|
|
19
|
+
deleteMessage: (messageId: string, replacementId?: string | null) => void;
|
|
20
|
+
tryDeleteMessage: (messageId: string) => boolean;
|
|
21
|
+
switchToBranch: (messageId: string) => void;
|
|
22
|
+
resetHead: (messageId: string | null) => void;
|
|
23
|
+
clear: () => void;
|
|
24
|
+
updateMessage: (messageId: string, updater: (message: ThreadMessage) => ThreadMessage) => boolean;
|
|
25
|
+
applyExternalMessageRepository: (loaded: ExportedMessageRepository) => void;
|
|
26
|
+
};
|
|
27
|
+
type MessageRepositorySession = ReturnType<typeof createMessageRepositorySession>;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { MessageRepositorySession, MessageRepositorySessionOptions, createMessageRepositorySession };
|
|
30
|
+
//# sourceMappingURL=message-repository-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-repository-session.d.ts","names":[],"sources":["../../../src/runtime/utils/message-repository-session.ts"],"mappings":";;;KAMY;EACV,kBACE,UAAU,2BACV,YAAY,sBACT;;cAGM,iCACX,UAAS;EAKe,4BAAS;;EAsInB,cAAA;EAlIoB,gBAAA;;;;;EASrB,iBAAA,+BACD;EAQmB,aAAA;EAKnB,qBAAA,yBAAa,SACd;EAOE,gBAAA,mBAAM;EAOkB,mBAAA;EAMF,iBAAA;EAKL,YAAA;EAKZ;EAML,gBAAA,mBAAM,UACP,SAAS,kBAAkB;EAW7B,iCAAA,QAAA;;KA8EA,2BAA2B,kBAC9B"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { MessageRepository } from "./message-repository.js";
|
|
2
|
+
//#region src/runtime/utils/message-repository-session.ts
|
|
3
|
+
const createMessageRepositorySession = (options = {}) => {
|
|
4
|
+
const repository = new MessageRepository();
|
|
5
|
+
let exportedRepository;
|
|
6
|
+
const getMessages = () => {
|
|
7
|
+
return repository.getMessages();
|
|
8
|
+
};
|
|
9
|
+
const tryGetMessage = (messageId) => {
|
|
10
|
+
try {
|
|
11
|
+
return repository.getMessage(messageId);
|
|
12
|
+
} catch {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const tryGetMessages = (messageId) => {
|
|
17
|
+
try {
|
|
18
|
+
return repository.getMessages(messageId);
|
|
19
|
+
} catch {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const hasMessage = (messageId) => {
|
|
24
|
+
return tryGetMessage(messageId) !== void 0;
|
|
25
|
+
};
|
|
26
|
+
const addOrUpdateMessage = (parentId, message) => {
|
|
27
|
+
repository.addOrUpdateMessage(parentId, message);
|
|
28
|
+
exportedRepository = void 0;
|
|
29
|
+
};
|
|
30
|
+
const deleteMessage = (messageId, replacementId) => {
|
|
31
|
+
repository.deleteMessage(messageId, replacementId);
|
|
32
|
+
exportedRepository = void 0;
|
|
33
|
+
};
|
|
34
|
+
const tryDeleteMessage = (messageId) => {
|
|
35
|
+
if (!hasMessage(messageId)) return false;
|
|
36
|
+
deleteMessage(messageId);
|
|
37
|
+
return true;
|
|
38
|
+
};
|
|
39
|
+
const switchToBranch = (messageId) => {
|
|
40
|
+
repository.switchToBranch(messageId);
|
|
41
|
+
exportedRepository = void 0;
|
|
42
|
+
};
|
|
43
|
+
const resetHead = (messageId) => {
|
|
44
|
+
repository.resetHead(messageId);
|
|
45
|
+
exportedRepository = void 0;
|
|
46
|
+
};
|
|
47
|
+
const clear = () => {
|
|
48
|
+
repository.clear();
|
|
49
|
+
exportedRepository = void 0;
|
|
50
|
+
};
|
|
51
|
+
const updateMessage = (messageId, updater) => {
|
|
52
|
+
const item = tryGetMessage(messageId);
|
|
53
|
+
if (!item) return false;
|
|
54
|
+
const message = updater(item.message);
|
|
55
|
+
if (message === item.message) return false;
|
|
56
|
+
addOrUpdateMessage(item.parentId, message);
|
|
57
|
+
return true;
|
|
58
|
+
};
|
|
59
|
+
const applyExternalMessageRepository = (loaded) => {
|
|
60
|
+
const headId = loaded.headId ?? loaded.messages.at(-1)?.message.id ?? null;
|
|
61
|
+
const ids = /* @__PURE__ */ new Set();
|
|
62
|
+
let degenerate = false;
|
|
63
|
+
for (const { message } of loaded.messages) {
|
|
64
|
+
if (ids.has(message.id)) {
|
|
65
|
+
degenerate = true;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
ids.add(message.id);
|
|
69
|
+
}
|
|
70
|
+
if (headId !== null && !ids.has(headId)) degenerate = true;
|
|
71
|
+
if (!degenerate) {
|
|
72
|
+
clear();
|
|
73
|
+
let pending = [...loaded.messages];
|
|
74
|
+
const importedIds = /* @__PURE__ */ new Set();
|
|
75
|
+
while (pending.length > 0) {
|
|
76
|
+
const unresolved = [];
|
|
77
|
+
let progressed = false;
|
|
78
|
+
for (const item of pending) {
|
|
79
|
+
if (item.parentId !== null && !importedIds.has(item.parentId)) {
|
|
80
|
+
unresolved.push(item);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
addOrUpdateMessage(item.parentId, item.message);
|
|
84
|
+
importedIds.add(item.message.id);
|
|
85
|
+
progressed = true;
|
|
86
|
+
}
|
|
87
|
+
if (!progressed) {
|
|
88
|
+
degenerate = true;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
pending = unresolved;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (degenerate) {
|
|
95
|
+
clear();
|
|
96
|
+
let previousId = null;
|
|
97
|
+
for (const { message } of loaded.messages) {
|
|
98
|
+
const existing = tryGetMessage(message.id);
|
|
99
|
+
addOrUpdateMessage(existing ? existing.parentId : previousId, message);
|
|
100
|
+
previousId = message.id;
|
|
101
|
+
}
|
|
102
|
+
resetHead(previousId);
|
|
103
|
+
} else resetHead(headId);
|
|
104
|
+
};
|
|
105
|
+
return {
|
|
106
|
+
getMessages,
|
|
107
|
+
get headId() {
|
|
108
|
+
return repository.headId;
|
|
109
|
+
},
|
|
110
|
+
export: () => {
|
|
111
|
+
exportedRepository ??= options.decorateExport ? options.decorateExport(repository.export(), repository) : repository.export();
|
|
112
|
+
return exportedRepository;
|
|
113
|
+
},
|
|
114
|
+
tryGetMessage,
|
|
115
|
+
tryGetMessages,
|
|
116
|
+
hasMessage,
|
|
117
|
+
addOrUpdateMessage,
|
|
118
|
+
deleteMessage,
|
|
119
|
+
tryDeleteMessage,
|
|
120
|
+
switchToBranch,
|
|
121
|
+
resetHead,
|
|
122
|
+
clear,
|
|
123
|
+
updateMessage,
|
|
124
|
+
applyExternalMessageRepository
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
//#endregion
|
|
128
|
+
export { createMessageRepositorySession };
|
|
129
|
+
|
|
130
|
+
//# sourceMappingURL=message-repository-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-repository-session.js","names":["ThreadMessage","MessageRepository","ExportedMessageRepository","MessageRepositorySessionOptions","decorateExport","exported","repository","createMessageRepositorySession","options","exportedRepository","getMessages","tryGetMessage","messageId","getMessage","undefined","tryGetMessages","hasMessage","addOrUpdateMessage","parentId","message","deleteMessage","replacementId","tryDeleteMessage","switchToBranch","resetHead","clear","updateMessage","updater","item","applyExternalMessageRepository","loaded","headId","messages","at","id","ids","Set","degenerate","has","add","pending","importedIds","length","unresolved","progressed","push","previousId","existing","export","MessageRepositorySession","ReturnType"],"sources":["../../../src/runtime/utils/message-repository-session.ts"],"sourcesContent":["import type { ThreadMessage } from \"../../types/message\";\nimport {\n MessageRepository,\n type ExportedMessageRepository,\n} from \"./message-repository\";\n\nexport type MessageRepositorySessionOptions = {\n decorateExport?: (\n exported: ExportedMessageRepository,\n repository: MessageRepository,\n ) => ExportedMessageRepository;\n};\n\nexport const createMessageRepositorySession = (\n options: MessageRepositorySessionOptions = {},\n) => {\n const repository = new MessageRepository();\n let exportedRepository: ExportedMessageRepository | undefined;\n\n const getMessages = (): readonly ThreadMessage[] => {\n return repository.getMessages();\n };\n\n const tryGetMessage = (messageId: string) => {\n try {\n return repository.getMessage(messageId);\n } catch {\n return undefined;\n }\n };\n\n const tryGetMessages = (\n messageId: string,\n ): readonly ThreadMessage[] | undefined => {\n try {\n return repository.getMessages(messageId);\n } catch {\n return undefined;\n }\n };\n\n const hasMessage = (messageId: string): boolean => {\n return tryGetMessage(messageId) !== undefined;\n };\n\n const addOrUpdateMessage = (\n parentId: string | null,\n message: ThreadMessage,\n ): void => {\n repository.addOrUpdateMessage(parentId, message);\n exportedRepository = undefined;\n };\n\n const deleteMessage = (\n messageId: string,\n replacementId?: string | null,\n ): void => {\n repository.deleteMessage(messageId, replacementId);\n exportedRepository = undefined;\n };\n\n const tryDeleteMessage = (messageId: string): boolean => {\n if (!hasMessage(messageId)) return false;\n deleteMessage(messageId);\n return true;\n };\n\n const switchToBranch = (messageId: string): void => {\n repository.switchToBranch(messageId);\n exportedRepository = undefined;\n };\n\n const resetHead = (messageId: string | null): void => {\n repository.resetHead(messageId);\n exportedRepository = undefined;\n };\n\n const clear = (): void => {\n repository.clear();\n exportedRepository = undefined;\n };\n\n const updateMessage = (\n messageId: string,\n updater: (message: ThreadMessage) => ThreadMessage,\n ): boolean => {\n const item = tryGetMessage(messageId);\n if (!item) return false;\n const message = updater(item.message);\n if (message === item.message) return false;\n addOrUpdateMessage(item.parentId, message);\n return true;\n };\n\n const applyExternalMessageRepository = (\n loaded: ExportedMessageRepository,\n ): void => {\n const headId = loaded.headId ?? loaded.messages.at(-1)?.message.id ?? null;\n const ids = new Set<string>();\n let degenerate = false;\n for (const { message } of loaded.messages) {\n if (ids.has(message.id)) {\n degenerate = true;\n break;\n }\n ids.add(message.id);\n }\n if (headId !== null && !ids.has(headId)) degenerate = true;\n\n if (!degenerate) {\n clear();\n let pending = [...loaded.messages];\n const importedIds = new Set<string>();\n\n while (pending.length > 0) {\n const unresolved: typeof pending = [];\n let progressed = false;\n for (const item of pending) {\n if (item.parentId !== null && !importedIds.has(item.parentId)) {\n unresolved.push(item);\n continue;\n }\n addOrUpdateMessage(item.parentId, item.message);\n importedIds.add(item.message.id);\n progressed = true;\n }\n if (!progressed) {\n degenerate = true;\n break;\n }\n pending = unresolved;\n }\n }\n\n if (degenerate) {\n clear();\n let previousId: string | null = null;\n for (const { message } of loaded.messages) {\n const existing = tryGetMessage(message.id);\n addOrUpdateMessage(existing ? existing.parentId : previousId, message);\n previousId = message.id;\n }\n resetHead(previousId);\n } else {\n resetHead(headId);\n }\n };\n\n return {\n getMessages,\n get headId() {\n return repository.headId;\n },\n export: (): ExportedMessageRepository => {\n exportedRepository ??= options.decorateExport\n ? options.decorateExport(repository.export(), repository)\n : repository.export();\n return exportedRepository;\n },\n tryGetMessage,\n tryGetMessages,\n hasMessage,\n addOrUpdateMessage,\n deleteMessage,\n tryDeleteMessage,\n switchToBranch,\n resetHead,\n clear,\n updateMessage,\n applyExternalMessageRepository,\n };\n};\n\nexport type MessageRepositorySession = ReturnType<\n typeof createMessageRepositorySession\n>;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-repository.d.ts","names":[],"sources":["../../../src/runtime/utils/message-repository.ts"],"mappings":";;;KAOY;EACV,SAAS;EACT;EACA,YAAY;;KAGF;EACV;EACA,UAAU;IACR,SAAS;IACT;IACA,YAAY;;;cAIH;EAEC,YAAA,mBAAS,wBAClB;EAkBM,sBAAA;IACL,SAAS;IACT;OACC;IACS;QACX;;
|
|
1
|
+
{"version":3,"file":"message-repository.d.ts","names":[],"sources":["../../../src/runtime/utils/message-repository.ts"],"mappings":";;;KAOY;EACV,SAAS;EACT;EACA,YAAY;;KAGF;EACV;EACA,UAAU;IACR,SAAS;IACT;IACA,YAAY;;;cAIH;EAEC,YAAA,mBAAS,wBAClB;EAkBM,sBAAA;IACL,SAAS;IACT;OACC;IACS;QACX;;cAgEQ;UACH;UACA;UACA;UAKA;UAgBA;UA2DA;MAQJ;MAIA;EAUJ,YAAY,2BAAe;EAuB3B,mBAAmB,yBAAyB,SAAS;EAiCrD,WAAW;;;;;EAcX,cAAc,mBAAmB;EAsCjC,YAAY;;;;;;;;;UAmBJ;EA+BR,eAAe;EAkBf,UAAU;EAiDV;EAUA,UAAU;EAwBV,SAAS,QAAQ,YAAY"}
|