@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
|
@@ -54,6 +54,83 @@ const renderConverter = (initialProps: Props = {}) =>
|
|
|
54
54
|
);
|
|
55
55
|
|
|
56
56
|
describe("useExternalMessageConverter", () => {
|
|
57
|
+
it("refreshes positional fallback ids when an id-less message is prepended", () => {
|
|
58
|
+
const idlessConvert: useExternalMessageConverter.Callback<TestMessage> = (
|
|
59
|
+
message,
|
|
60
|
+
) => ({
|
|
61
|
+
role: message.role,
|
|
62
|
+
content: [{ type: "text", text: message.text }],
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const older: TestMessage = { id: "u0", role: "user", text: "older" };
|
|
66
|
+
const newer: TestMessage = { id: "u1", role: "user", text: "newer" };
|
|
67
|
+
|
|
68
|
+
const { result, rerender } = renderHook(
|
|
69
|
+
({ messages }: { messages: TestMessage[] }) =>
|
|
70
|
+
useExternalMessageConverter<TestMessage>({
|
|
71
|
+
callback: idlessConvert,
|
|
72
|
+
messages,
|
|
73
|
+
isRunning: false,
|
|
74
|
+
metadata: EMPTY,
|
|
75
|
+
}),
|
|
76
|
+
{ initialProps: { messages: [newer] } },
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
rerender({ messages: [older, newer] });
|
|
80
|
+
|
|
81
|
+
const ids = result.current.map((message) => message.id);
|
|
82
|
+
expect(ids).toEqual([
|
|
83
|
+
"__external_store_fallback_0",
|
|
84
|
+
"__external_store_fallback_1",
|
|
85
|
+
]);
|
|
86
|
+
expect(
|
|
87
|
+
result.current.map((message) => (message.content[0] as any).text),
|
|
88
|
+
).toEqual(["older", "newer"]);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("never rewrites a caller-supplied id that matches the generated shape", () => {
|
|
92
|
+
const explicitConvert: useExternalMessageConverter.Callback<TestMessage> = (
|
|
93
|
+
message,
|
|
94
|
+
) => ({
|
|
95
|
+
role: message.role,
|
|
96
|
+
id: message.id === "explicit" ? "__external_store_fallback_0" : undefined,
|
|
97
|
+
content: [{ type: "text", text: message.text }],
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const explicit: TestMessage = {
|
|
101
|
+
id: "explicit",
|
|
102
|
+
role: "user",
|
|
103
|
+
text: "kept",
|
|
104
|
+
};
|
|
105
|
+
const older: TestMessage = { id: "u0", role: "user", text: "older" };
|
|
106
|
+
|
|
107
|
+
const { result, rerender } = renderHook(
|
|
108
|
+
({ messages }: { messages: TestMessage[] }) =>
|
|
109
|
+
useExternalMessageConverter<TestMessage>({
|
|
110
|
+
callback: explicitConvert,
|
|
111
|
+
messages,
|
|
112
|
+
isRunning: false,
|
|
113
|
+
metadata: EMPTY,
|
|
114
|
+
}),
|
|
115
|
+
{ initialProps: { messages: [explicit] } },
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
rerender({ messages: [older, explicit] });
|
|
119
|
+
|
|
120
|
+
// The caller-supplied id survives untouched — at the cost of colliding
|
|
121
|
+
// with the id minted for the prepended message, since the caller chose an
|
|
122
|
+
// id inside the reserved fallback namespace. The full list makes that
|
|
123
|
+
// trade-off explicit.
|
|
124
|
+
expect(result.current.map((message) => message.id)).toEqual([
|
|
125
|
+
"__external_store_fallback_0",
|
|
126
|
+
"__external_store_fallback_0",
|
|
127
|
+
]);
|
|
128
|
+
const explicitOut = result.current.find(
|
|
129
|
+
(message) => (message.content[0] as any).text === "kept",
|
|
130
|
+
);
|
|
131
|
+
expect(explicitOut?.id).toBe("__external_store_fallback_0");
|
|
132
|
+
});
|
|
133
|
+
|
|
57
134
|
it("reuses converted messages across rerenders when inputs are unchanged", () => {
|
|
58
135
|
const { result, rerender } = renderConverter();
|
|
59
136
|
|
|
@@ -1,432 +1,46 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useMemo, useState } from "react";
|
|
4
|
-
import { ThreadMessageConverter } from "../../runtimes/external-store/thread-message-converter";
|
|
5
|
-
import {
|
|
6
|
-
getExternalStoreMessages,
|
|
7
|
-
symbolInnerMessage,
|
|
8
|
-
bindExternalStoreMessage,
|
|
9
|
-
} from "../../runtime/utils/external-store-message";
|
|
10
4
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
type ThreadMessageLikeContentItem = Exclude<
|
|
28
|
-
ThreadMessageLike["content"],
|
|
29
|
-
string
|
|
30
|
-
>[number];
|
|
5
|
+
chunkExternalMessages,
|
|
6
|
+
completeExternalMessageConversion,
|
|
7
|
+
convertExternalMessageCallback,
|
|
8
|
+
convertExternalMessageChunk,
|
|
9
|
+
convertExternalMessages as convertExternalMessagesInternal,
|
|
10
|
+
shallowArrayEqual,
|
|
11
|
+
type ExternalMessageConverterCallback,
|
|
12
|
+
type ExternalMessageConverterCallbackResult,
|
|
13
|
+
type ExternalMessageConverterChunk,
|
|
14
|
+
type ExternalMessageConverterMessage,
|
|
15
|
+
type ExternalMessageConverterMetadata,
|
|
16
|
+
type JoinStrategy,
|
|
17
|
+
} from "../../runtime/utils/external-message-conversion";
|
|
18
|
+
import { bindExternalStoreMessage } from "../../runtime/utils/external-store-message";
|
|
19
|
+
import { ThreadMessageConverter } from "../../runtimes/external-store/thread-message-converter";
|
|
20
|
+
import type { ThreadMessage } from "../../types/message";
|
|
31
21
|
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
// Generatedness is tracked by identity, not by id shape: a caller-supplied id
|
|
23
|
+
// that happens to match the generated pattern must never be rewritten.
|
|
24
|
+
const generatedFallbackMessages = new WeakSet<object>();
|
|
34
25
|
|
|
35
|
-
|
|
36
|
-
if (c.type !== "tool-call" || c.result !== undefined) return false;
|
|
37
|
-
return (
|
|
38
|
-
c.interrupt != null ||
|
|
39
|
-
(c.approval != null &&
|
|
40
|
-
c.approval.approved === undefined &&
|
|
41
|
-
c.approval.resolution === undefined)
|
|
42
|
-
);
|
|
43
|
-
};
|
|
26
|
+
export type { JoinStrategy };
|
|
44
27
|
|
|
45
28
|
export namespace useExternalMessageConverter {
|
|
46
|
-
export type Message =
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
readonly joinStrategy?: JoinStrategy;
|
|
50
|
-
};
|
|
51
|
-
})
|
|
52
|
-
| {
|
|
53
|
-
role: "tool";
|
|
54
|
-
toolCallId: string;
|
|
55
|
-
toolName?: string | undefined;
|
|
56
|
-
result: any;
|
|
57
|
-
artifact?: any;
|
|
58
|
-
isError?: boolean;
|
|
59
|
-
messages?: readonly ThreadMessage[];
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export type Metadata = {
|
|
63
|
-
readonly toolStatuses?: Record<string, ToolExecutionStatus>;
|
|
64
|
-
readonly error?: ReadonlyJSONValue;
|
|
65
|
-
readonly messageTiming?: Record<string, MessageTiming>;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export type Callback<T> = (
|
|
69
|
-
message: T,
|
|
70
|
-
metadata: Metadata,
|
|
71
|
-
) => Message | Message[];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
type CallbackResult<T> = {
|
|
75
|
-
input: T;
|
|
76
|
-
outputs: useExternalMessageConverter.Message[];
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const stringifyForError = (value: unknown) => {
|
|
80
|
-
let text;
|
|
81
|
-
try {
|
|
82
|
-
text = value instanceof Error ? String(value) : JSON.stringify(value);
|
|
83
|
-
} catch {
|
|
84
|
-
/* circular */
|
|
85
|
-
}
|
|
86
|
-
text ??= String(value);
|
|
87
|
-
return text.length > 200 ? `${text.slice(0, 200)}…` : text;
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const toCallbackOutputs = (
|
|
91
|
-
output:
|
|
92
|
-
| useExternalMessageConverter.Message
|
|
93
|
-
| useExternalMessageConverter.Message[],
|
|
94
|
-
input: unknown,
|
|
95
|
-
): useExternalMessageConverter.Message[] => {
|
|
96
|
-
const outputs = Array.isArray(output) ? output : [output];
|
|
97
|
-
for (const o of outputs) {
|
|
98
|
-
const valid =
|
|
99
|
-
typeof o === "object" &&
|
|
100
|
-
o !== null &&
|
|
101
|
-
(o.role === "tool" ||
|
|
102
|
-
((o.role === "assistant" || o.role === "user" || o.role === "system") &&
|
|
103
|
-
(typeof o.content === "string" || Array.isArray(o.content))));
|
|
104
|
-
if (!valid)
|
|
105
|
-
throw new Error(
|
|
106
|
-
`External message converter: the converter callback returned an invalid message (${stringifyForError(o)}) for input ${stringifyForError(input)}. Return an empty array to skip a message.`,
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
return outputs;
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
type CallbackCacheEntry<T> = CallbackResult<T> & {
|
|
113
|
-
metadata: useExternalMessageConverter.Metadata;
|
|
114
|
-
callback: useExternalMessageConverter.Callback<T>;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
type ChunkResult<T> = {
|
|
118
|
-
inputs: T[];
|
|
119
|
-
outputs: useExternalMessageConverter.Message[];
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
type Mutable<T> = {
|
|
123
|
-
-readonly [P in keyof T]: T[P];
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
const mergeInnerMessages = (existing: object, incoming: object) => ({
|
|
127
|
-
[symbolInnerMessage]: [
|
|
128
|
-
...((existing as any)[symbolInnerMessage] ?? []),
|
|
129
|
-
...((incoming as any)[symbolInnerMessage] ?? []),
|
|
130
|
-
],
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
const joinExternalMessages = (
|
|
134
|
-
messages: readonly useExternalMessageConverter.Message[],
|
|
135
|
-
): ThreadMessageLike => {
|
|
136
|
-
const assistantMessage: Mutable<Omit<ThreadMessageLike, "metadata">> & {
|
|
137
|
-
content: Exclude<ThreadMessageLike["content"][0], string>[];
|
|
138
|
-
metadata?: Mutable<ThreadMessageLike["metadata"]>;
|
|
139
|
-
} = {
|
|
140
|
-
role: "assistant",
|
|
141
|
-
content: [],
|
|
142
|
-
};
|
|
143
|
-
for (const output of messages) {
|
|
144
|
-
if (output.role === "tool") {
|
|
145
|
-
const toolCallIdx = assistantMessage.content.findIndex(
|
|
146
|
-
(c) => c.type === "tool-call" && c.toolCallId === output.toolCallId,
|
|
147
|
-
);
|
|
148
|
-
// Ignore orphaned tool results so one bad tool message does not
|
|
149
|
-
// prevent rendering the rest of the conversation.
|
|
150
|
-
if (toolCallIdx !== -1) {
|
|
151
|
-
const toolCall = assistantMessage.content[
|
|
152
|
-
toolCallIdx
|
|
153
|
-
]! as ToolCallMessagePart;
|
|
154
|
-
if (output.toolName != null) {
|
|
155
|
-
if (toolCall.toolName !== output.toolName)
|
|
156
|
-
throw new Error(
|
|
157
|
-
`Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`,
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
assistantMessage.content[toolCallIdx] = {
|
|
161
|
-
...toolCall,
|
|
162
|
-
...{
|
|
163
|
-
[symbolInnerMessage]: [
|
|
164
|
-
...((toolCall as any)[symbolInnerMessage] ?? []),
|
|
165
|
-
output,
|
|
166
|
-
],
|
|
167
|
-
},
|
|
168
|
-
result: output.result,
|
|
169
|
-
artifact: output.artifact,
|
|
170
|
-
isError: output.isError,
|
|
171
|
-
messages: output.messages,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
} else {
|
|
175
|
-
const role = output.role;
|
|
176
|
-
const content = (
|
|
177
|
-
typeof output.content === "string"
|
|
178
|
-
? [{ type: "text" as const, text: output.content }]
|
|
179
|
-
: output.content
|
|
180
|
-
).map((c) => ({
|
|
181
|
-
...c,
|
|
182
|
-
...{ [symbolInnerMessage]: [output] },
|
|
183
|
-
}));
|
|
184
|
-
switch (role) {
|
|
185
|
-
case "system":
|
|
186
|
-
case "user":
|
|
187
|
-
return {
|
|
188
|
-
...output,
|
|
189
|
-
content,
|
|
190
|
-
};
|
|
191
|
-
case "assistant":
|
|
192
|
-
if (assistantMessage.content.length === 0) {
|
|
193
|
-
assistantMessage.id = output.id;
|
|
194
|
-
assistantMessage.createdAt ??= output.createdAt;
|
|
195
|
-
assistantMessage.status ??= output.status;
|
|
196
|
-
|
|
197
|
-
if (output.attachments) {
|
|
198
|
-
assistantMessage.attachments = [
|
|
199
|
-
...(assistantMessage.attachments ?? []),
|
|
200
|
-
...output.attachments,
|
|
201
|
-
];
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (output.metadata) {
|
|
206
|
-
assistantMessage.metadata ??= {};
|
|
207
|
-
if (output.metadata.unstable_state !== undefined) {
|
|
208
|
-
assistantMessage.metadata.unstable_state =
|
|
209
|
-
output.metadata.unstable_state;
|
|
210
|
-
}
|
|
211
|
-
if (output.metadata.unstable_annotations) {
|
|
212
|
-
assistantMessage.metadata.unstable_annotations = [
|
|
213
|
-
...(assistantMessage.metadata.unstable_annotations ?? []),
|
|
214
|
-
...output.metadata.unstable_annotations,
|
|
215
|
-
];
|
|
216
|
-
}
|
|
217
|
-
if (output.metadata.unstable_data) {
|
|
218
|
-
assistantMessage.metadata.unstable_data = [
|
|
219
|
-
...(assistantMessage.metadata.unstable_data ?? []),
|
|
220
|
-
...output.metadata.unstable_data,
|
|
221
|
-
];
|
|
222
|
-
}
|
|
223
|
-
if (output.metadata.steps) {
|
|
224
|
-
assistantMessage.metadata.steps = [
|
|
225
|
-
...(assistantMessage.metadata.steps ?? []),
|
|
226
|
-
...output.metadata.steps,
|
|
227
|
-
];
|
|
228
|
-
}
|
|
229
|
-
if (output.metadata.custom) {
|
|
230
|
-
assistantMessage.metadata.custom = {
|
|
231
|
-
...(assistantMessage.metadata.custom ?? {}),
|
|
232
|
-
...output.metadata.custom,
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
if (output.metadata.timing) {
|
|
237
|
-
assistantMessage.metadata.timing = output.metadata.timing;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (output.metadata.submittedFeedback) {
|
|
241
|
-
assistantMessage.metadata.submittedFeedback =
|
|
242
|
-
output.metadata.submittedFeedback;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (output.metadata.isOptimistic) {
|
|
246
|
-
assistantMessage.metadata.isOptimistic = true;
|
|
247
|
-
}
|
|
248
|
-
// TODO keep this in sync with ThreadMessageLike["metadata"] / fromThreadMessageLike
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// Add content parts, merging reasoning parts with same parentId
|
|
252
|
-
for (const part of content) {
|
|
253
|
-
if (part.type === "tool-call") {
|
|
254
|
-
const existingIdx = assistantMessage.content.findIndex(
|
|
255
|
-
(c) =>
|
|
256
|
-
c.type === "tool-call" && c.toolCallId === part.toolCallId,
|
|
257
|
-
);
|
|
258
|
-
if (existingIdx !== -1) {
|
|
259
|
-
const existing = assistantMessage.content[
|
|
260
|
-
existingIdx
|
|
261
|
-
] as typeof part;
|
|
262
|
-
assistantMessage.content[existingIdx] = {
|
|
263
|
-
...existing,
|
|
264
|
-
...part,
|
|
265
|
-
...mergeInnerMessages(existing, part),
|
|
266
|
-
};
|
|
267
|
-
continue;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (
|
|
272
|
-
part.type === "reasoning" &&
|
|
273
|
-
"parentId" in part &&
|
|
274
|
-
part.parentId
|
|
275
|
-
) {
|
|
276
|
-
const existingIdx = assistantMessage.content.findIndex(
|
|
277
|
-
(c) =>
|
|
278
|
-
c.type === "reasoning" &&
|
|
279
|
-
"parentId" in c &&
|
|
280
|
-
c.parentId === part.parentId,
|
|
281
|
-
);
|
|
282
|
-
if (existingIdx !== -1) {
|
|
283
|
-
const existing = assistantMessage.content[
|
|
284
|
-
existingIdx
|
|
285
|
-
] as typeof part;
|
|
286
|
-
assistantMessage.content[existingIdx] = {
|
|
287
|
-
...existing,
|
|
288
|
-
text: `${existing.text}\n\n${part.text}`,
|
|
289
|
-
...mergeInnerMessages(existing, part),
|
|
290
|
-
};
|
|
291
|
-
continue;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
assistantMessage.content.push(part);
|
|
295
|
-
}
|
|
296
|
-
break;
|
|
297
|
-
default: {
|
|
298
|
-
const unsupportedRole: never = role;
|
|
299
|
-
throw new Error(`Unknown message role: ${unsupportedRole}`);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
return assistantMessage;
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
const chunkExternalMessages = <T>(
|
|
308
|
-
callbackResults: CallbackResult<T>[],
|
|
309
|
-
joinStrategy?: JoinStrategy,
|
|
310
|
-
) => {
|
|
311
|
-
const results: ChunkResult<T>[] = [];
|
|
312
|
-
let isAssistant = false;
|
|
313
|
-
let pendingNone = false; // true if the previous assistant message had joinStrategy "none"
|
|
314
|
-
let inputs: T[] = [];
|
|
315
|
-
let outputs: useExternalMessageConverter.Message[] = [];
|
|
316
|
-
|
|
317
|
-
const flush = () => {
|
|
318
|
-
if (outputs.length) {
|
|
319
|
-
results.push({
|
|
320
|
-
inputs,
|
|
321
|
-
outputs,
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
inputs = [];
|
|
325
|
-
outputs = [];
|
|
326
|
-
isAssistant = false;
|
|
327
|
-
pendingNone = false;
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
for (const callbackResult of callbackResults) {
|
|
331
|
-
for (const output of callbackResult.outputs) {
|
|
332
|
-
if (
|
|
333
|
-
(pendingNone && output.role !== "tool") ||
|
|
334
|
-
!isAssistant ||
|
|
335
|
-
output.role === "user" ||
|
|
336
|
-
output.role === "system"
|
|
337
|
-
) {
|
|
338
|
-
flush();
|
|
339
|
-
}
|
|
340
|
-
isAssistant = output.role === "assistant" || output.role === "tool";
|
|
341
|
-
|
|
342
|
-
if (inputs.at(-1) !== callbackResult.input) {
|
|
343
|
-
inputs.push(callbackResult.input);
|
|
344
|
-
}
|
|
345
|
-
outputs.push(output);
|
|
346
|
-
|
|
347
|
-
if (
|
|
348
|
-
output.role === "assistant" &&
|
|
349
|
-
(output.convertConfig?.joinStrategy === "none" ||
|
|
350
|
-
joinStrategy === "none")
|
|
351
|
-
) {
|
|
352
|
-
pendingNone = true;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
flush();
|
|
357
|
-
return results;
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
function createErrorAssistantMessage(
|
|
361
|
-
error: ReadonlyJSONValue,
|
|
362
|
-
): ThreadAssistantMessage {
|
|
363
|
-
const msg: ThreadAssistantMessage = {
|
|
364
|
-
id: generateErrorMessageId(),
|
|
365
|
-
role: "assistant",
|
|
366
|
-
content: [],
|
|
367
|
-
status: { type: "incomplete", reason: "error", error },
|
|
368
|
-
createdAt: new Date(),
|
|
369
|
-
metadata: {
|
|
370
|
-
unstable_state: null,
|
|
371
|
-
unstable_annotations: [],
|
|
372
|
-
unstable_data: [],
|
|
373
|
-
custom: {},
|
|
374
|
-
steps: [],
|
|
375
|
-
},
|
|
376
|
-
};
|
|
377
|
-
bindExternalStoreMessage(msg, []);
|
|
378
|
-
return msg;
|
|
29
|
+
export type Message = ExternalMessageConverterMessage;
|
|
30
|
+
export type Metadata = ExternalMessageConverterMetadata;
|
|
31
|
+
export type Callback<T> = ExternalMessageConverterCallback<T>;
|
|
379
32
|
}
|
|
380
33
|
|
|
381
|
-
export const convertExternalMessages
|
|
34
|
+
export const convertExternalMessages: <T extends WeakKey>(
|
|
382
35
|
messages: T[],
|
|
383
36
|
callback: useExternalMessageConverter.Callback<T>,
|
|
384
37
|
isRunning: boolean,
|
|
385
38
|
metadata: useExternalMessageConverter.Metadata,
|
|
386
|
-
) =>
|
|
387
|
-
const callbackResults: CallbackResult<T>[] = [];
|
|
388
|
-
for (const message of messages) {
|
|
389
|
-
const output = callback(message, metadata);
|
|
390
|
-
const outputs = toCallbackOutputs(output, message);
|
|
391
|
-
const result = { input: message, outputs };
|
|
392
|
-
callbackResults.push(result);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
const chunks = chunkExternalMessages(callbackResults);
|
|
396
|
-
|
|
397
|
-
const result = chunks.map((message, idx) => {
|
|
398
|
-
const isLast = idx === chunks.length - 1;
|
|
399
|
-
const joined = joinExternalMessages(message.outputs);
|
|
400
|
-
const hasInterruptedToolCalls =
|
|
401
|
-
typeof joined.content === "object" &&
|
|
402
|
-
joined.content.some(isInterruptedToolCall);
|
|
403
|
-
const hasPendingToolCalls =
|
|
404
|
-
typeof joined.content === "object" &&
|
|
405
|
-
joined.content.some(isPendingToolCall);
|
|
406
|
-
const autoStatus = getAutoStatus(
|
|
407
|
-
isLast,
|
|
408
|
-
isRunning,
|
|
409
|
-
hasInterruptedToolCalls,
|
|
410
|
-
hasPendingToolCalls,
|
|
411
|
-
isLast ? metadata.error : undefined,
|
|
412
|
-
);
|
|
413
|
-
const newMessage = fromThreadMessageLike(
|
|
414
|
-
joined,
|
|
415
|
-
idx.toString(),
|
|
416
|
-
autoStatus,
|
|
417
|
-
);
|
|
418
|
-
bindExternalStoreMessage(newMessage, message.inputs);
|
|
419
|
-
return newMessage;
|
|
420
|
-
});
|
|
39
|
+
) => ThreadMessage[] = convertExternalMessagesInternal;
|
|
421
40
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
result.push(createErrorAssistantMessage(metadata.error));
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
return result;
|
|
41
|
+
type CallbackCacheEntry<T> = ExternalMessageConverterCallbackResult<T> & {
|
|
42
|
+
metadata: useExternalMessageConverter.Metadata;
|
|
43
|
+
callback: useExternalMessageConverter.Callback<T>;
|
|
430
44
|
};
|
|
431
45
|
|
|
432
46
|
export const useExternalMessageConverter = <T extends WeakKey>({
|
|
@@ -452,8 +66,8 @@ export const useExternalMessageConverter = <T extends WeakKey>({
|
|
|
452
66
|
const [caches] = useState(() => ({
|
|
453
67
|
callbackCache: new WeakMap<T, CallbackCacheEntry<T>>(),
|
|
454
68
|
chunkCache: new WeakMap<
|
|
455
|
-
|
|
456
|
-
|
|
69
|
+
ExternalMessageConverterMessage,
|
|
70
|
+
ExternalMessageConverterChunk<T>
|
|
457
71
|
>(),
|
|
458
72
|
converterCache: new ThreadMessageConverter(),
|
|
459
73
|
}));
|
|
@@ -468,7 +82,7 @@ export const useExternalMessageConverter = <T extends WeakKey>({
|
|
|
468
82
|
);
|
|
469
83
|
|
|
470
84
|
return useMemo(() => {
|
|
471
|
-
const callbackResults:
|
|
85
|
+
const callbackResults: ExternalMessageConverterCallbackResult<T>[] = [];
|
|
472
86
|
for (const message of messages) {
|
|
473
87
|
let result = state.callbackCache.get(message);
|
|
474
88
|
if (
|
|
@@ -476,11 +90,12 @@ export const useExternalMessageConverter = <T extends WeakKey>({
|
|
|
476
90
|
result.metadata !== state.metadata ||
|
|
477
91
|
result.callback !== state.callback
|
|
478
92
|
) {
|
|
479
|
-
const output = state.callback(message, state.metadata);
|
|
480
|
-
const outputs = toCallbackOutputs(output, message);
|
|
481
93
|
result = {
|
|
482
|
-
|
|
483
|
-
|
|
94
|
+
...convertExternalMessageCallback(
|
|
95
|
+
message,
|
|
96
|
+
state.callback,
|
|
97
|
+
state.metadata,
|
|
98
|
+
),
|
|
484
99
|
metadata: state.metadata,
|
|
485
100
|
callback: state.callback,
|
|
486
101
|
};
|
|
@@ -490,77 +105,39 @@ export const useExternalMessageConverter = <T extends WeakKey>({
|
|
|
490
105
|
}
|
|
491
106
|
|
|
492
107
|
const chunks = chunkExternalMessages(callbackResults, joinStrategy).map(
|
|
493
|
-
(
|
|
494
|
-
const key =
|
|
495
|
-
if (!key) return
|
|
108
|
+
(message) => {
|
|
109
|
+
const key = message.outputs[0];
|
|
110
|
+
if (!key) return message;
|
|
496
111
|
|
|
497
112
|
const cached = state.chunkCache.get(key);
|
|
498
|
-
if (cached && shallowArrayEqual(cached.outputs,
|
|
113
|
+
if (cached && shallowArrayEqual(cached.outputs, message.outputs)) {
|
|
499
114
|
return cached;
|
|
500
|
-
|
|
501
|
-
|
|
115
|
+
}
|
|
116
|
+
state.chunkCache.set(key, message);
|
|
117
|
+
return message;
|
|
502
118
|
},
|
|
503
119
|
);
|
|
504
120
|
|
|
505
121
|
const threadMessages = state.converterCache.convertMessages(
|
|
506
122
|
chunks,
|
|
507
|
-
(cache, message, idx) =>
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
typeof joined.content === "object" &&
|
|
513
|
-
joined.content.some(isInterruptedToolCall);
|
|
514
|
-
const hasPendingToolCalls =
|
|
515
|
-
typeof joined.content === "object" &&
|
|
516
|
-
joined.content.some(isPendingToolCall);
|
|
517
|
-
const autoStatus = getAutoStatus(
|
|
518
|
-
isLast,
|
|
123
|
+
(cache, message, idx) =>
|
|
124
|
+
convertExternalMessageChunk(
|
|
125
|
+
message,
|
|
126
|
+
idx,
|
|
127
|
+
chunks.length,
|
|
519
128
|
isRunning,
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
cache &&
|
|
527
|
-
(cache.role !== "assistant" ||
|
|
528
|
-
!isAutoStatus(cache.status) ||
|
|
529
|
-
cache.status === autoStatus)
|
|
530
|
-
) {
|
|
531
|
-
const inputs = getExternalStoreMessages<T>(cache);
|
|
532
|
-
if (shallowArrayEqual(inputs, message.inputs)) {
|
|
533
|
-
return cache;
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
const newMessage = fromThreadMessageLike(
|
|
538
|
-
joined,
|
|
539
|
-
idx.toString(),
|
|
540
|
-
autoStatus,
|
|
541
|
-
);
|
|
542
|
-
bindExternalStoreMessage(newMessage, message.inputs);
|
|
543
|
-
return newMessage;
|
|
544
|
-
},
|
|
129
|
+
state.metadata.error,
|
|
130
|
+
{
|
|
131
|
+
message: cache,
|
|
132
|
+
generatedFallbackMessages,
|
|
133
|
+
},
|
|
134
|
+
),
|
|
545
135
|
);
|
|
546
136
|
|
|
547
137
|
bindExternalStoreMessage(threadMessages, messages);
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
threadMessages.push(createErrorAssistantMessage(state.metadata.error));
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
return threadMessages;
|
|
138
|
+
return completeExternalMessageConversion(
|
|
139
|
+
threadMessages,
|
|
140
|
+
state.metadata.error,
|
|
141
|
+
);
|
|
557
142
|
}, [state, messages, isRunning, joinStrategy]);
|
|
558
143
|
};
|
|
559
|
-
|
|
560
|
-
const shallowArrayEqual = (a: unknown[], b: unknown[]) => {
|
|
561
|
-
if (a.length !== b.length) return false;
|
|
562
|
-
for (let i = 0; i < a.length; i++) {
|
|
563
|
-
if (a[i] !== b[i]) return false;
|
|
564
|
-
}
|
|
565
|
-
return true;
|
|
566
|
-
};
|
|
@@ -3,7 +3,7 @@ import type { MessageRole } from "../../types/message";
|
|
|
3
3
|
import type { QuoteInfo } from "../../types/quote";
|
|
4
4
|
import type { Unsubscribe } from "../../types/unsubscribe";
|
|
5
5
|
import type { RunConfig } from "../../types/message";
|
|
6
|
-
import type { QueueItemState } from "
|
|
6
|
+
import type { QueueItemState } from "../queue/queue-item";
|
|
7
7
|
import type { QueuePlacement } from "../queue/external-thread-queue-adapter";
|
|
8
8
|
import {
|
|
9
9
|
LazyMemoizeSubject,
|