@assistant-ui/react-ai-sdk 1.3.28 → 1.3.31
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/assistant-stream/dist/core/tool/schema-utils.d.ts +15 -0
- package/dist/assistant-stream/dist/core/tool/schema-utils.d.ts.map +1 -0
- package/dist/{packages/assistant-stream → assistant-stream}/dist/core/tool/schema-utils.js +9 -3
- package/dist/assistant-stream/dist/core/tool/schema-utils.js.map +1 -0
- package/dist/{packages/assistant-stream → assistant-stream}/dist/core/tool/tool-types.d.ts +27 -1
- package/dist/assistant-stream/dist/core/tool/tool-types.d.ts.map +1 -0
- package/dist/assistant-stream/dist/index.d.ts +2 -0
- package/dist/{node_modules → assistant-stream/dist/node_modules}/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts +4 -5
- package/dist/assistant-stream/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts.map +1 -0
- package/dist/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.d.ts.map +1 -0
- package/dist/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js.map +1 -0
- package/dist/assistant-stream/dist/utils/json/json-value.d.ts.map +1 -0
- package/dist/frontendTools.d.ts +33 -6
- package/dist/frontendTools.d.ts.map +1 -1
- package/dist/frontendTools.js +3 -2
- package/dist/frontendTools.js.map +1 -1
- package/dist/generativeTools.d.ts +44 -0
- package/dist/generativeTools.d.ts.map +1 -0
- package/dist/generativeTools.js +55 -0
- package/dist/generativeTools.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -2
- package/dist/modelContentEnvelope.d.ts +1 -1
- package/dist/modelContentEnvelope.d.ts.map +1 -1
- package/dist/ui/resumable.d.ts +1 -1
- package/dist/ui/resumable.js +1 -1
- package/dist/ui/use-chat/AssistantChatTransport.d.ts.map +1 -1
- package/dist/ui/use-chat/AssistantChatTransport.js +2 -2
- package/dist/ui/use-chat/useAISDKRuntime.d.ts +3 -16
- package/dist/ui/use-chat/useAISDKRuntime.d.ts.map +1 -1
- package/dist/ui/use-chat/useAISDKRuntime.js +22 -35
- package/dist/ui/use-chat/useAISDKRuntime.js.map +1 -1
- package/dist/ui/use-chat/useChatRuntime.d.ts +2 -3
- package/dist/ui/use-chat/useChatRuntime.d.ts.map +1 -1
- package/dist/ui/use-chat/useChatRuntime.js +4 -3
- package/dist/ui/use-chat/useChatRuntime.js.map +1 -1
- package/dist/ui/use-chat/useExternalHistory.d.ts.map +1 -1
- package/dist/ui/use-chat/useExternalHistory.js +16 -8
- package/dist/ui/use-chat/useExternalHistory.js.map +1 -1
- package/dist/ui/utils/convertMessage.d.ts +3 -2
- package/dist/ui/utils/convertMessage.d.ts.map +1 -1
- package/dist/ui/utils/convertMessage.js +3 -1
- package/dist/ui/utils/convertMessage.js.map +1 -1
- package/dist/usage.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/frontendTools.test.ts +24 -0
- package/src/frontendTools.ts +4 -6
- package/src/generativeTools.ts +90 -0
- package/src/index.ts +4 -1
- package/src/ui/use-chat/useAISDKRuntime.test.ts +36 -0
- package/src/ui/use-chat/useAISDKRuntime.ts +41 -52
- package/src/ui/use-chat/useChatRuntime.ts +22 -21
- package/src/ui/use-chat/useExternalHistory.test.ts +60 -1
- package/src/ui/use-chat/useExternalHistory.ts +17 -8
- package/src/ui/utils/convertMessage.test.ts +34 -6
- package/src/ui/utils/convertMessage.ts +6 -0
- package/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts.map +0 -1
- package/dist/packages/assistant-stream/dist/core/tool/schema-utils.d.ts +0 -1
- package/dist/packages/assistant-stream/dist/core/tool/schema-utils.js.map +0 -1
- package/dist/packages/assistant-stream/dist/core/tool/tool-types.d.ts.map +0 -1
- package/dist/packages/assistant-stream/dist/index.d.ts +0 -1
- package/dist/packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.d.ts.map +0 -1
- package/dist/packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js.map +0 -1
- package/dist/packages/assistant-stream/dist/utils/json/json-value.d.ts.map +0 -1
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/AssistantStream.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/AssistantStreamChunk.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/accumulators/AssistantMessageStream.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/accumulators/assistant-message-accumulator.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/modules/assistant-stream.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/modules/text.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/modules/tool-call.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/serialization/PlainText.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/serialization/assistant-transport/AssistantTransport.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/serialization/data-stream/DataStream.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/serialization/ui-message-stream/UIMessageStream.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/tool/ToolExecutionStream.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/tool/toolResultStream.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/utils/stream/AssistantMetaTransformStream.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/utils/stream/AssistantTransformStream.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/core/utils/types.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/resumable/createResumableAssistantStreamResponse.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/resumable/createResumableAssistantStreamResponse.js +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/resumable/index.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/utils/json/json-value.d.ts +0 -0
- /package/dist/{packages/assistant-stream → assistant-stream}/dist/utils.d.ts +0 -0
package/src/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="@assistant-ui/core/store" />
|
|
2
1
|
/// <reference types="@assistant-ui/core/react" />
|
|
3
2
|
|
|
4
3
|
export { useAISDKRuntime } from "./ui/use-chat/useAISDKRuntime";
|
|
@@ -14,6 +13,10 @@ export type {
|
|
|
14
13
|
ResumableClientStorage,
|
|
15
14
|
} from "./ui/resumable";
|
|
16
15
|
export { frontendTools } from "./frontendTools";
|
|
16
|
+
export {
|
|
17
|
+
generativeTools,
|
|
18
|
+
type GenerativeToolsOptions,
|
|
19
|
+
} from "./generativeTools";
|
|
17
20
|
export { injectQuoteContext } from "./injectQuoteContext";
|
|
18
21
|
export type { ThreadTokenUsage, TokenUsageExtractableMessage } from "./usage";
|
|
19
22
|
export { getThreadMessageTokenUsage, useThreadTokenUsage } from "./usage";
|
|
@@ -354,4 +354,40 @@ describe("useAISDKRuntime", () => {
|
|
|
354
354
|
metadata: { custom: { maxTokens: 100 } },
|
|
355
355
|
});
|
|
356
356
|
});
|
|
357
|
+
|
|
358
|
+
it("forwards isDisabled to thread state", () => {
|
|
359
|
+
const chat = createChatHelpers();
|
|
360
|
+
const { result } = renderHook(() =>
|
|
361
|
+
useAISDKRuntime(chat, { isDisabled: true }),
|
|
362
|
+
);
|
|
363
|
+
expect(result.current.thread.getState().isDisabled).toBe(true);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
it("forwards isSendDisabled to the composer canSend gate", () => {
|
|
367
|
+
const chat = createChatHelpers();
|
|
368
|
+
const { result } = renderHook(() =>
|
|
369
|
+
useAISDKRuntime(chat, { isSendDisabled: true }),
|
|
370
|
+
);
|
|
371
|
+
act(() => {
|
|
372
|
+
result.current.thread.composer.setText("hello");
|
|
373
|
+
});
|
|
374
|
+
expect(result.current.thread.composer.getState().canSend).toBe(false);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it("forwards unstable_capabilities to thread capabilities", () => {
|
|
378
|
+
const chat = createChatHelpers();
|
|
379
|
+
const { result } = renderHook(() =>
|
|
380
|
+
useAISDKRuntime(chat, { unstable_capabilities: { copy: false } }),
|
|
381
|
+
);
|
|
382
|
+
expect(result.current.thread.getState().capabilities.unstable_copy).toBe(
|
|
383
|
+
false,
|
|
384
|
+
);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
it("forwards suggestions to thread state", () => {
|
|
388
|
+
const chat = createChatHelpers();
|
|
389
|
+
const suggestions = [{ prompt: "tell me a joke" }];
|
|
390
|
+
const { result } = renderHook(() => useAISDKRuntime(chat, { suggestions }));
|
|
391
|
+
expect(result.current.thread.getState().suggestions).toEqual(suggestions);
|
|
392
|
+
});
|
|
357
393
|
});
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { useMemo, useRef, useState } from "react";
|
|
4
4
|
import type { UIMessage, useChat, CreateUIMessage } from "@ai-sdk/react";
|
|
5
5
|
import { isToolUIPart, generateId } from "ai";
|
|
6
6
|
import {
|
|
7
7
|
useExternalStoreRuntime,
|
|
8
8
|
useRuntimeAdapters,
|
|
9
|
-
useToolInvocations,
|
|
10
|
-
type ToolExecutionStatus,
|
|
11
9
|
} from "@assistant-ui/core/react";
|
|
10
|
+
import type { ToolExecutionStatus } from "@assistant-ui/core";
|
|
12
11
|
import type {
|
|
13
12
|
ExternalStoreAdapter,
|
|
13
|
+
ExternalStoreSharedOptions,
|
|
14
14
|
ThreadHistoryAdapter,
|
|
15
15
|
AssistantRuntime,
|
|
16
16
|
ThreadMessage,
|
|
17
|
-
ThreadSuggestion,
|
|
18
17
|
MessageFormatAdapter,
|
|
19
18
|
MessageFormatItem,
|
|
20
19
|
MessageFormatRepository,
|
|
@@ -22,7 +21,10 @@ import type {
|
|
|
22
21
|
RunConfig,
|
|
23
22
|
McpAppMetadata,
|
|
24
23
|
} from "@assistant-ui/core";
|
|
25
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
getExternalStoreMessages,
|
|
26
|
+
pickExternalStoreSharedOptions,
|
|
27
|
+
} from "@assistant-ui/core";
|
|
26
28
|
import type { ReadonlyJSONObject } from "assistant-stream/utils";
|
|
27
29
|
import { sliceMessagesUntil } from "../utils/sliceMessagesUntil";
|
|
28
30
|
import { toCreateMessage } from "../utils/toCreateMessage";
|
|
@@ -56,7 +58,7 @@ const toUIMessage = <UI_MESSAGE extends UIMessage>(
|
|
|
56
58
|
role: createMessage.role ?? fallbackRole,
|
|
57
59
|
}) as UI_MESSAGE;
|
|
58
60
|
|
|
59
|
-
export type AISDKRuntimeAdapter = {
|
|
61
|
+
export type AISDKRuntimeAdapter = ExternalStoreSharedOptions & {
|
|
60
62
|
adapters?:
|
|
61
63
|
| (NonNullable<ExternalStoreAdapter["adapters"]> & {
|
|
62
64
|
history?: ThreadHistoryAdapter | undefined;
|
|
@@ -80,25 +82,18 @@ export type AISDKRuntimeAdapter = {
|
|
|
80
82
|
* (for example, an SSE reconnect endpoint keyed by turn id).
|
|
81
83
|
*/
|
|
82
84
|
onResume?: ExternalStoreAdapter["onResume"];
|
|
83
|
-
/**
|
|
84
|
-
* Follow up suggestions to surface on the thread. Use this to drive
|
|
85
|
-
* dynamic suggestions from application state, tool results, or backend
|
|
86
|
-
* responses; flows into `thread.suggestions` and is rendered by
|
|
87
|
-
* components that read it (such as the shadcn `ThreadFollowupSuggestions`).
|
|
88
|
-
*/
|
|
89
|
-
suggestions?: readonly ThreadSuggestion[] | undefined;
|
|
90
85
|
};
|
|
91
86
|
|
|
92
87
|
export const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
93
88
|
chatHelpers: ReturnType<typeof useChat<UI_MESSAGE>>,
|
|
94
|
-
{
|
|
89
|
+
adapter: AISDKRuntimeAdapter = {},
|
|
90
|
+
) => {
|
|
91
|
+
const {
|
|
95
92
|
adapters,
|
|
96
93
|
toCreateMessage: customToCreateMessage,
|
|
97
94
|
cancelPendingToolCallsOnSend = true,
|
|
98
95
|
onResume,
|
|
99
|
-
|
|
100
|
-
}: AISDKRuntimeAdapter = {},
|
|
101
|
-
) => {
|
|
96
|
+
} = adapter;
|
|
102
97
|
const contextAdapters = useRuntimeAdapters();
|
|
103
98
|
const [toolStatuses, setToolStatuses] = useState<
|
|
104
99
|
Record<string, ToolExecutionStatus>
|
|
@@ -122,6 +117,12 @@ export const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
|
122
117
|
|
|
123
118
|
const messageTiming = useStreamingTiming(chatHelpers.messages, isRunning);
|
|
124
119
|
|
|
120
|
+
// Flag the streaming message optimistic: its id can be swapped for a server
|
|
121
|
+
// id mid-run, and the repository then drops the orphaned pre-swap id (#4037).
|
|
122
|
+
const lastMessage = chatHelpers.messages.at(-1);
|
|
123
|
+
const optimisticMessageId =
|
|
124
|
+
isRunning && lastMessage?.role === "assistant" ? lastMessage.id : undefined;
|
|
125
|
+
|
|
125
126
|
const messages = AISDKMessageConverter.useThreadMessages({
|
|
126
127
|
isRunning,
|
|
127
128
|
messages: chatHelpers.messages,
|
|
@@ -132,9 +133,10 @@ export const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
|
132
133
|
toolArgsKeyOrderCache: toolArgsKeyOrderCacheRef.current,
|
|
133
134
|
toolLastInputCache: toolLastInputCacheRef.current,
|
|
134
135
|
mcpAppMetadataCache: mcpAppMetadataCacheRef.current,
|
|
136
|
+
...(optimisticMessageId && { optimisticMessageId }),
|
|
135
137
|
...(chatHelpers.error && { error: chatHelpers.error.message }),
|
|
136
138
|
}),
|
|
137
|
-
[toolStatuses, messageTiming, chatHelpers.error],
|
|
139
|
+
[toolStatuses, messageTiming, optimisticMessageId, chatHelpers.error],
|
|
138
140
|
),
|
|
139
141
|
});
|
|
140
142
|
|
|
@@ -144,29 +146,6 @@ export const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
|
144
146
|
},
|
|
145
147
|
}));
|
|
146
148
|
|
|
147
|
-
const toolInvocations = useToolInvocations({
|
|
148
|
-
state: {
|
|
149
|
-
messages,
|
|
150
|
-
isRunning,
|
|
151
|
-
},
|
|
152
|
-
getTools: () => runtimeRef.current.thread.getModelContext().tools,
|
|
153
|
-
onResult: (command) => {
|
|
154
|
-
if (command.type === "add-tool-result") {
|
|
155
|
-
const output =
|
|
156
|
-
command.modelContent !== undefined
|
|
157
|
-
? wrapModelContentEnvelope(command.result, command.modelContent)
|
|
158
|
-
: command.result;
|
|
159
|
-
chatHelpers.addToolResult({
|
|
160
|
-
tool: command.toolName,
|
|
161
|
-
toolCallId: command.toolCallId,
|
|
162
|
-
output,
|
|
163
|
-
options: { metadata: lastRunConfigRef.current },
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
setToolStatuses,
|
|
168
|
-
});
|
|
169
|
-
|
|
170
149
|
const isLoading = useExternalHistory(
|
|
171
150
|
runtimeRef,
|
|
172
151
|
adapters?.history ?? contextAdapters?.history,
|
|
@@ -185,7 +164,9 @@ export const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
|
185
164
|
const completePendingToolCalls = async () => {
|
|
186
165
|
if (!cancelPendingToolCallsOnSend) return;
|
|
187
166
|
|
|
188
|
-
|
|
167
|
+
// The runtime auto-aborts in-flight tool invocations when a new run
|
|
168
|
+
// is dispatched (append() / startRun()). All we need to do here is
|
|
169
|
+
// mark any tool without a result as cancelled in the UI message list.
|
|
189
170
|
|
|
190
171
|
// Mark any tool without a result as cancelled (uses setMessages to avoid triggering sendAutomaticallyWhen)
|
|
191
172
|
chatHelpers.setMessages((messages) => {
|
|
@@ -214,6 +195,8 @@ export const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
|
214
195
|
const runtime = useExternalStoreRuntime({
|
|
215
196
|
isRunning,
|
|
216
197
|
messages,
|
|
198
|
+
unstable_enableToolInvocations: true,
|
|
199
|
+
setToolStatuses,
|
|
217
200
|
setMessages: (messages) =>
|
|
218
201
|
chatHelpers.setMessages(
|
|
219
202
|
messages
|
|
@@ -278,7 +261,6 @@ export const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
|
278
261
|
},
|
|
279
262
|
onCancel: async () => {
|
|
280
263
|
chatHelpers.stop();
|
|
281
|
-
await toolInvocations.abort();
|
|
282
264
|
},
|
|
283
265
|
onNew: async (message) => {
|
|
284
266
|
const createMessage = (
|
|
@@ -327,29 +309,36 @@ export const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
|
327
309
|
|
|
328
310
|
await chatHelpers.regenerate({ metadata: config.runConfig });
|
|
329
311
|
},
|
|
330
|
-
onAddToolResult: ({
|
|
312
|
+
onAddToolResult: ({
|
|
313
|
+
toolCallId,
|
|
314
|
+
toolName,
|
|
315
|
+
result,
|
|
316
|
+
isError,
|
|
317
|
+
modelContent,
|
|
318
|
+
}) => {
|
|
331
319
|
const options = { metadata: lastRunConfigRef.current };
|
|
332
320
|
if (isError) {
|
|
333
321
|
chatHelpers.addToolOutput({
|
|
334
322
|
state: "output-error",
|
|
335
|
-
tool: toolCallId,
|
|
323
|
+
tool: toolName ?? toolCallId,
|
|
336
324
|
toolCallId,
|
|
337
325
|
errorText:
|
|
338
326
|
typeof result === "string" ? result : JSON.stringify(result),
|
|
339
327
|
options,
|
|
340
328
|
});
|
|
341
329
|
} else {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
330
|
+
const output =
|
|
331
|
+
modelContent !== undefined
|
|
332
|
+
? wrapModelContentEnvelope(result, modelContent)
|
|
333
|
+
: result;
|
|
334
|
+
chatHelpers.addToolResult({
|
|
335
|
+
tool: toolName,
|
|
345
336
|
toolCallId,
|
|
346
|
-
output
|
|
337
|
+
output,
|
|
347
338
|
options,
|
|
348
339
|
});
|
|
349
340
|
}
|
|
350
341
|
},
|
|
351
|
-
onResumeToolCall: (options) =>
|
|
352
|
-
toolInvocations.resume(options.toolCallId, options.payload),
|
|
353
342
|
onRespondToToolApproval: ({ approvalId, approved, reason }) => {
|
|
354
343
|
void chatHelpers.addToolApprovalResponse({
|
|
355
344
|
id: approvalId,
|
|
@@ -358,8 +347,8 @@ export const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
|
358
347
|
options: { metadata: lastRunConfigRef.current },
|
|
359
348
|
});
|
|
360
349
|
},
|
|
350
|
+
...pickExternalStoreSharedOptions(adapter),
|
|
361
351
|
...(onResume && { onResume }),
|
|
362
|
-
...(suggestions && { suggestions }),
|
|
363
352
|
adapters: {
|
|
364
353
|
attachments: vercelAttachmentAdapter,
|
|
365
354
|
...contextAdapters,
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import { useChat, type UIMessage } from "@ai-sdk/react";
|
|
4
4
|
import type { AssistantCloud } from "assistant-cloud";
|
|
5
|
-
import
|
|
5
|
+
import {
|
|
6
|
+
pickExternalStoreSharedOptions,
|
|
7
|
+
type AssistantRuntime,
|
|
8
|
+
type ExternalStoreSharedOptions,
|
|
9
|
+
} from "@assistant-ui/core";
|
|
6
10
|
import {
|
|
7
11
|
useCloudThreadListAdapter,
|
|
8
12
|
useRemoteThreadListRuntime,
|
|
@@ -19,24 +23,21 @@ import type { AssistantChatResumableOptions } from "../resumable";
|
|
|
19
23
|
import { useEffect, useMemo, useRef } from "react";
|
|
20
24
|
|
|
21
25
|
export type UseChatRuntimeOptions<UI_MESSAGE extends UIMessage = UIMessage> =
|
|
22
|
-
ChatInit<UI_MESSAGE> &
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
ChatInit<UI_MESSAGE> &
|
|
27
|
+
ExternalStoreSharedOptions & {
|
|
28
|
+
cloud?: AssistantCloud | undefined;
|
|
29
|
+
adapters?: AISDKRuntimeAdapter["adapters"] | undefined;
|
|
30
|
+
toCreateMessage?: CustomToCreateMessageFunction;
|
|
31
|
+
onResume?: AISDKRuntimeAdapter["onResume"];
|
|
32
|
+
};
|
|
29
33
|
|
|
30
34
|
const useDynamicChatTransport = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
31
35
|
transport: ChatTransport<UI_MESSAGE>,
|
|
32
36
|
): ChatTransport<UI_MESSAGE> => {
|
|
33
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
34
37
|
const transportRef = useRef<ChatTransport<UI_MESSAGE>>(transport);
|
|
35
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
36
38
|
useEffect(() => {
|
|
37
39
|
transportRef.current = transport;
|
|
38
40
|
});
|
|
39
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
40
41
|
const dynamicTransport = useMemo(
|
|
41
42
|
() =>
|
|
42
43
|
new Proxy(transportRef.current, {
|
|
@@ -72,33 +73,36 @@ const useChatThreadRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
|
72
73
|
adapters,
|
|
73
74
|
transport: transportOptions,
|
|
74
75
|
toCreateMessage,
|
|
76
|
+
isDisabled: _isDisabled,
|
|
77
|
+
isSendDisabled: _isSendDisabled,
|
|
78
|
+
unstable_capabilities: _unstable_capabilities,
|
|
79
|
+
suggestions: _suggestions,
|
|
75
80
|
onResume,
|
|
76
|
-
suggestions,
|
|
77
81
|
...chatOptions
|
|
78
82
|
} = options ?? {};
|
|
83
|
+
// peel guard: any shared key left in `chatOptions` collapses this to `never`
|
|
84
|
+
true satisfies keyof typeof chatOptions &
|
|
85
|
+
keyof ExternalStoreSharedOptions extends never
|
|
86
|
+
? true
|
|
87
|
+
: never;
|
|
79
88
|
|
|
80
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
81
89
|
const transport = useDynamicChatTransport(
|
|
82
90
|
transportOptions ?? new AssistantChatTransport(),
|
|
83
91
|
);
|
|
84
92
|
|
|
85
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
86
93
|
const id = useAuiState((s) => s.threadListItem.id);
|
|
87
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
88
94
|
const aui = useAui();
|
|
89
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
90
95
|
const chat = useChat({
|
|
91
96
|
...chatOptions,
|
|
92
97
|
id,
|
|
93
98
|
transport,
|
|
94
99
|
});
|
|
95
100
|
|
|
96
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
97
101
|
const runtime = useAISDKRuntime(chat, {
|
|
98
102
|
adapters,
|
|
103
|
+
...pickExternalStoreSharedOptions(options ?? {}),
|
|
99
104
|
...(toCreateMessage && { toCreateMessage }),
|
|
100
105
|
...(onResume && { onResume }),
|
|
101
|
-
...(suggestions && { suggestions }),
|
|
102
106
|
});
|
|
103
107
|
|
|
104
108
|
if (transport instanceof AssistantChatTransport) {
|
|
@@ -108,9 +112,7 @@ const useChatThreadRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
|
108
112
|
);
|
|
109
113
|
}
|
|
110
114
|
|
|
111
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
112
115
|
const resumeFiredRef = useRef(false);
|
|
113
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
114
116
|
useEffect(() => {
|
|
115
117
|
if (resumeFiredRef.current) return;
|
|
116
118
|
const adapter = getResumableAdapter(transport);
|
|
@@ -137,7 +139,6 @@ export const useChatRuntime = <UI_MESSAGE extends UIMessage = UIMessage>({
|
|
|
137
139
|
const cloudAdapter = useCloudThreadListAdapter({ cloud });
|
|
138
140
|
return useRemoteThreadListRuntime({
|
|
139
141
|
runtimeHook: function RuntimeHook() {
|
|
140
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
141
142
|
return useChatThreadRuntime(options);
|
|
142
143
|
},
|
|
143
144
|
adapter: cloudAdapter,
|
|
@@ -5,6 +5,7 @@ import { describe, expect, it, vi } from "vitest";
|
|
|
5
5
|
import type {
|
|
6
6
|
AssistantRuntime,
|
|
7
7
|
MessageFormatAdapter,
|
|
8
|
+
MessageFormatRepository,
|
|
8
9
|
ThreadHistoryAdapter,
|
|
9
10
|
ThreadMessage,
|
|
10
11
|
} from "@assistant-ui/core";
|
|
@@ -15,7 +16,11 @@ vi.mock("@assistant-ui/store", () => ({
|
|
|
15
16
|
}),
|
|
16
17
|
}));
|
|
17
18
|
|
|
18
|
-
import {
|
|
19
|
+
import { MessageRepository } from "@assistant-ui/core/internal";
|
|
20
|
+
import {
|
|
21
|
+
toExportedMessageRepository,
|
|
22
|
+
useExternalHistory,
|
|
23
|
+
} from "./useExternalHistory";
|
|
19
24
|
|
|
20
25
|
const noopThread = {
|
|
21
26
|
subscribe: () => () => {},
|
|
@@ -105,3 +110,57 @@ describe("useExternalHistory withFormat contract", () => {
|
|
|
105
110
|
expect(adapter.withFormat).toHaveBeenCalledWith(storageFormat);
|
|
106
111
|
});
|
|
107
112
|
});
|
|
113
|
+
|
|
114
|
+
describe("toExportedMessageRepository", () => {
|
|
115
|
+
const convert = (items: { id: string; ok: boolean }[]): ThreadMessage[] =>
|
|
116
|
+
items[0]!.ok ? [{ id: items[0]!.id } as ThreadMessage] : [];
|
|
117
|
+
|
|
118
|
+
it("drops a malformed row together with its now-orphaned descendants", () => {
|
|
119
|
+
const repo: MessageFormatRepository<{ id: string; ok: boolean }> = {
|
|
120
|
+
headId: "c",
|
|
121
|
+
messages: [
|
|
122
|
+
{ parentId: null, message: { id: "a", ok: true } },
|
|
123
|
+
{ parentId: "a", message: { id: "b", ok: false } },
|
|
124
|
+
{ parentId: "b", message: { id: "c", ok: true } },
|
|
125
|
+
],
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const result = toExportedMessageRepository(convert, repo);
|
|
129
|
+
|
|
130
|
+
expect(result.messages.map((m) => m.message.id)).toEqual(["a"]);
|
|
131
|
+
expect(result.headId).toBeNull();
|
|
132
|
+
expect(() => new MessageRepository().import(result)).not.toThrow();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("drops a headId that points at a filtered row", () => {
|
|
136
|
+
const repo: MessageFormatRepository<{ id: string; ok: boolean }> = {
|
|
137
|
+
headId: "b",
|
|
138
|
+
messages: [
|
|
139
|
+
{ parentId: null, message: { id: "a", ok: true } },
|
|
140
|
+
{ parentId: "a", message: { id: "b", ok: false } },
|
|
141
|
+
],
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const result = toExportedMessageRepository(convert, repo);
|
|
145
|
+
|
|
146
|
+
expect(result.messages.map((m) => m.message.id)).toEqual(["a"]);
|
|
147
|
+
expect(result.headId).toBeNull();
|
|
148
|
+
expect(() => new MessageRepository().import(result)).not.toThrow();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("drops a malformed root and its entire subtree", () => {
|
|
152
|
+
const repo: MessageFormatRepository<{ id: string; ok: boolean }> = {
|
|
153
|
+
headId: "b",
|
|
154
|
+
messages: [
|
|
155
|
+
{ parentId: null, message: { id: "a", ok: false } },
|
|
156
|
+
{ parentId: "a", message: { id: "b", ok: true } },
|
|
157
|
+
],
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const result = toExportedMessageRepository(convert, repo);
|
|
161
|
+
|
|
162
|
+
expect(result.messages).toHaveLength(0);
|
|
163
|
+
expect(result.headId).toBeNull();
|
|
164
|
+
expect(() => new MessageRepository().import(result)).not.toThrow();
|
|
165
|
+
});
|
|
166
|
+
});
|
|
@@ -24,15 +24,24 @@ export const toExportedMessageRepository = <TMessage>(
|
|
|
24
24
|
toThreadMessages: (messages: TMessage[]) => ThreadMessage[],
|
|
25
25
|
messages: MessageFormatRepository<TMessage>,
|
|
26
26
|
): ExportedMessageRepository => {
|
|
27
|
+
const survivingIds = new Set<string>();
|
|
28
|
+
const survivors = messages.messages.flatMap((m) => {
|
|
29
|
+
const message = toThreadMessages([m.message])[0];
|
|
30
|
+
if (!message) {
|
|
31
|
+
console.warn("Skipping a stored message that could not be loaded.");
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
if (m.parentId && !survivingIds.has(m.parentId)) return [];
|
|
35
|
+
survivingIds.add(message.id);
|
|
36
|
+
return [{ ...m, message }];
|
|
37
|
+
});
|
|
38
|
+
|
|
27
39
|
return {
|
|
28
|
-
headId:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
message,
|
|
34
|
-
};
|
|
35
|
-
}),
|
|
40
|
+
headId:
|
|
41
|
+
messages.headId && survivingIds.has(messages.headId)
|
|
42
|
+
? messages.headId
|
|
43
|
+
: null,
|
|
44
|
+
messages: survivors,
|
|
36
45
|
};
|
|
37
46
|
};
|
|
38
47
|
|
|
@@ -1,8 +1,36 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import type { ReadonlyJSONObject } from "assistant-stream/utils";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
AISDKMessageConverter,
|
|
5
|
+
type AISDKMessageConverterMetadata,
|
|
6
|
+
} from "./convertMessage";
|
|
4
7
|
|
|
5
8
|
describe("AISDKMessageConverter", () => {
|
|
9
|
+
it("flags the streaming assistant message as optimistic", () => {
|
|
10
|
+
const metadata: AISDKMessageConverterMetadata = {
|
|
11
|
+
optimisticMessageId: "a1",
|
|
12
|
+
};
|
|
13
|
+
const converted = AISDKMessageConverter.toThreadMessages(
|
|
14
|
+
[
|
|
15
|
+
{ id: "u1", role: "user", parts: [{ type: "text", text: "hi" }] },
|
|
16
|
+
{ id: "a1", role: "assistant", parts: [{ type: "text", text: "yo" }] },
|
|
17
|
+
] as any,
|
|
18
|
+
true,
|
|
19
|
+
metadata,
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
expect(converted[0]?.metadata.isOptimistic).toBeFalsy();
|
|
23
|
+
expect(converted[1]?.metadata.isOptimistic).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("does not flag messages when no optimistic id is provided", () => {
|
|
27
|
+
const converted = AISDKMessageConverter.toThreadMessages([
|
|
28
|
+
{ id: "a1", role: "assistant", parts: [{ type: "text", text: "yo" }] },
|
|
29
|
+
] as any);
|
|
30
|
+
|
|
31
|
+
expect(converted[0]?.metadata.isOptimistic).toBeFalsy();
|
|
32
|
+
});
|
|
33
|
+
|
|
6
34
|
it("converts user files into attachments and keeps text content", () => {
|
|
7
35
|
const converted = AISDKMessageConverter.toThreadMessages([
|
|
8
36
|
{
|
|
@@ -338,7 +366,7 @@ describe("AISDKMessageConverter", () => {
|
|
|
338
366
|
});
|
|
339
367
|
|
|
340
368
|
it("keeps observed key order from streaming snapshots for final tool args", () => {
|
|
341
|
-
const metadata = {
|
|
369
|
+
const metadata: AISDKMessageConverterMetadata = {
|
|
342
370
|
toolArgsKeyOrderCache: new Map<string, Map<string, string[]>>(),
|
|
343
371
|
};
|
|
344
372
|
|
|
@@ -410,7 +438,7 @@ describe("AISDKMessageConverter", () => {
|
|
|
410
438
|
});
|
|
411
439
|
|
|
412
440
|
it("merges duplicate toolCallId across assistant snapshots", () => {
|
|
413
|
-
const metadata = {
|
|
441
|
+
const metadata: AISDKMessageConverterMetadata = {
|
|
414
442
|
toolArgsKeyOrderCache: new Map<string, Map<string, string[]>>(),
|
|
415
443
|
};
|
|
416
444
|
|
|
@@ -463,7 +491,7 @@ describe("AISDKMessageConverter", () => {
|
|
|
463
491
|
});
|
|
464
492
|
|
|
465
493
|
it("preserves last good input when AI SDK briefly emits null input", () => {
|
|
466
|
-
const metadata = {
|
|
494
|
+
const metadata: AISDKMessageConverterMetadata = {
|
|
467
495
|
toolArgsKeyOrderCache: new Map<string, Map<string, string[]>>(),
|
|
468
496
|
toolLastInputCache: new Map<string, ReadonlyJSONObject>(),
|
|
469
497
|
};
|
|
@@ -506,7 +534,7 @@ describe("AISDKMessageConverter", () => {
|
|
|
506
534
|
});
|
|
507
535
|
|
|
508
536
|
it("preserves last good input across terminal state transitions", () => {
|
|
509
|
-
const metadata = {
|
|
537
|
+
const metadata: AISDKMessageConverterMetadata = {
|
|
510
538
|
toolArgsKeyOrderCache: new Map<string, Map<string, string[]>>(),
|
|
511
539
|
toolLastInputCache: new Map<string, ReadonlyJSONObject>(),
|
|
512
540
|
};
|
|
@@ -690,7 +718,7 @@ describe("AISDKMessageConverter", () => {
|
|
|
690
718
|
});
|
|
691
719
|
|
|
692
720
|
it("memoizes MCP app metadata across conversions by resourceUri", () => {
|
|
693
|
-
const metadata = {
|
|
721
|
+
const metadata: AISDKMessageConverterMetadata = {
|
|
694
722
|
mcpAppMetadataCache: new Map(),
|
|
695
723
|
};
|
|
696
724
|
|
|
@@ -24,6 +24,8 @@ export type AISDKMessageConverterMetadata =
|
|
|
24
24
|
toolArgsKeyOrderCache?: Map<string, Map<string, string[]>>;
|
|
25
25
|
toolLastInputCache?: Map<string, ReadonlyJSONObject>;
|
|
26
26
|
mcpAppMetadataCache?: Map<string, McpAppMetadata>;
|
|
27
|
+
/** Id of the currently-streaming message, flagged optimistic (#4037). */
|
|
28
|
+
optimisticMessageId?: string | undefined;
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
function stripClosingDelimiters(json: string): string {
|
|
@@ -393,6 +395,9 @@ export const AISDKMessageConverter = unstable_createMessageConverter(
|
|
|
393
395
|
case "system":
|
|
394
396
|
case "assistant": {
|
|
395
397
|
const timing = metadata.messageTiming?.[message.id];
|
|
398
|
+
const isOptimistic =
|
|
399
|
+
message.role === "assistant" &&
|
|
400
|
+
message.id === metadata.optimisticMessageId;
|
|
396
401
|
return {
|
|
397
402
|
role: message.role,
|
|
398
403
|
id: message.id,
|
|
@@ -401,6 +406,7 @@ export const AISDKMessageConverter = unstable_createMessageConverter(
|
|
|
401
406
|
metadata: {
|
|
402
407
|
...(message.metadata as MessageMetadata),
|
|
403
408
|
...(timing && { timing }),
|
|
409
|
+
...(isOptimistic && { isOptimistic: true }),
|
|
404
410
|
},
|
|
405
411
|
};
|
|
406
412
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":["JSONSchema4TypeName","JSONSchema4Type","JSONSchema4Object","JSONSchema4Array","key","Array","JSONSchema4Version","JSONSchema4","id","$ref","$schema","title","description","default","multipleOf","maximum","exclusiveMaximum","minimum","exclusiveMinimum","maxLength","minLength","pattern","additionalItems","items","maxItems","minItems","uniqueItems","maxProperties","minProperties","required","additionalProperties","definitions","k","properties","patternProperties","dependencies","enum","type","allOf","anyOf","oneOf","not","extends","format","JSONSchema6TypeName","JSONSchema6Type","JSONSchema6Object","JSONSchema6Array","JSONSchema6Version","JSONSchema6Definition","JSONSchema6","$id","contains","propertyNames","const","examples","JSONSchema7TypeName","JSONSchema7Type","JSONSchema7Object","JSONSchema7Array","JSONSchema7Version","JSONSchema7Definition","JSONSchema7","$comment","$defs","if","then","else","contentMediaType","contentEncoding","readOnly","writeOnly","ValidationResult","ValidationError","valid","errors","property","message","validate","instance","schema","checkPropertyChange","value","mustBeValid","result"],"sources":["../../../../../../../../../node_modules/.pnpm/@types+json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts"],"x_google_ignoreList":[0],"mappings":";;;;;;;;;;KA+iBYwD,mBAAAA;AAAAA;;;;;KAaAC,eAAAA;AAAAA,qBAINC,iBAAAA,GACAC,gBAAgB;AAAA;AAAA,UAILD,iBAAAA;EAAAA,CACZtD,GAAAA,WAAcqD,eAAe;AAAA;AAAA;AAAA;AAAA,UAKjBE,gBAAAA,SAAyBtD,KAAK,CAACoD,eAAAA;;;;;;;;;;;;KAapCG,kBAAAA;;;;;KAMAC,qBAAAA,GAAwBC,WAAW;AAAA,UAC9BA,WAAAA;EACbX,GAAAA;EACA1C,IAAAA;EACAC,OAAAA,GAAUkD,kBAAAA;EACVG,QAAAA;;;;;EAMAC,KAAAA;IAAAA,CACK5D,GAAAA,WAAcyD,qBAAAA;EAAAA;;;;EAMnBxB,IAAAA,GAAOmB,mBAAAA,GAAsBA,mBAAAA;EAC7BpB,IAAAA,GAAOqB,eAAAA;EACPH,KAAAA,GAAQG,eAAAA;;;;EAKR3C,UAAAA;EACAC,OAAAA;EACAC,gBAAAA;EACAC,OAAAA;EACAC,gBAAAA;;;;EAKAC,SAAAA;EACAC,SAAAA;EACAC,OAAAA;;;;EAKAE,KAAAA,GAAQsC,qBAAAA,GAAwBA,qBAAAA;EAChCvC,eAAAA,GAAkBuC,qBAAAA;EAClBrC,QAAAA;EACAC,QAAAA;EACAC,WAAAA;EACA0B,QAAAA,GAAWS,qBAAAA;;;;EAKXlC,aAAAA;EACAC,aAAAA;EACAC,QAAAA;EACAI,UAAAA;IAAAA,CACK7B,GAAAA,WAAcyD,qBAAAA;EAAAA;EAEnB3B,iBAAAA;IAAAA,CACK9B,GAAAA,WAAcyD,qBAAAA;EAAAA;EAEnB/B,oBAAAA,GAAuB+B,qBAAAA;EACvB1B,YAAAA;IAAAA,CACK/B,GAAAA,WAAcyD,qBAAAA;EAAAA;EAEnBR,aAAAA,GAAgBQ,qBAAAA;;;;EAKhBI,EAAAA,GAAKJ,qBAAAA;EACLK,IAAAA,GAAOL,qBAAAA;EACPM,IAAAA,GAAON,qBAAAA;;;;EAKPvB,KAAAA,GAAQuB,qBAAAA;EACRtB,KAAAA,GAAQsB,qBAAAA;EACRrB,KAAAA,GAAQqB,qBAAAA;EACRpB,GAAAA,GAAMoB,qBAAAA;;;;EAKNlB,MAAAA;;;;EAKAyB,gBAAAA;EACAC,eAAAA;;;;EAKAtC,WAAAA;IAAAA,CACK3B,GAAAA,WAAcyD,qBAAAA;EAAAA;;;;EAMnBlD,KAAAA;EACAC,WAAAA;EACAC,OAAAA,GAAU4C,eAAAA;EACVa,QAAAA;EACAC,SAAAA;EACAhB,QAAAA,GAAWE,eAAAA;AAAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema-utils.js","names":[],"sources":["../../../../../../../assistant-stream/dist/core/tool/schema-utils.js"],"sourcesContent":["//#region src/core/tool/schema-utils.ts\nfunction isStandardSchema(schema) {\n\treturn typeof schema === \"object\" && schema !== null && \"~standard\" in schema && typeof schema[\"~standard\"] === \"object\";\n}\nfunction hasToJSONSchemaMethod(schema) {\n\treturn typeof schema === \"object\" && schema !== null && \"toJSONSchema\" in schema && typeof schema.toJSONSchema === \"function\";\n}\nfunction hasToJSONMethod(schema) {\n\treturn typeof schema === \"object\" && schema !== null && \"toJSON\" in schema && typeof schema.toJSON === \"function\";\n}\n/**\n* Converts a schema to JSONSchema7.\n* Supports:\n* - StandardSchemaV1 with ~standard.toJSONSchema (e.g., Zod v4)\n* - StandardSchemaV1 with ~standard.jsonSchema.input() (e.g., Zod v4)\n* - Objects with toJSONSchema() method (e.g., Zod v4)\n* - Objects with toJSON() method\n* - Plain JSONSchema7 objects (must have a \"type\" property)\n*/\nfunction toJSONSchema(schema) {\n\tif (isStandardSchema(schema)) {\n\t\tconst toJSONSchemaMethod = schema[\"~standard\"].toJSONSchema;\n\t\tif (typeof toJSONSchemaMethod === \"function\") return toJSONSchemaMethod();\n\t\tconst jsonSchema = schema[\"~standard\"].jsonSchema;\n\t\tif (typeof jsonSchema === \"object\" && jsonSchema !== null && typeof jsonSchema.input === \"function\") return jsonSchema.input();\n\t}\n\tif (hasToJSONSchemaMethod(schema)) return schema.toJSONSchema();\n\tif (hasToJSONMethod(schema)) return schema.toJSON();\n\tif (isStandardSchema(schema)) throw new Error(\"Could not convert schema to JSON Schema. The schema implements Standard Schema but does not support JSON Schema conversion. If you are using Zod, please upgrade to Zod v4 (npm install zod@latest). Alternatively, pass a plain JSON Schema object instead.\");\n\treturn schema;\n}\n/**\n* Returns a copy of the JSON Schema with `required` removed recursively,\n* making every property optional. Array item schemas are left unchanged.\n*/\nfunction toPartialJSONSchema(schema) {\n\tconst { required: _, ...result } = schema;\n\tif (result.properties) result.properties = Object.fromEntries(Object.entries(result.properties).map(([key, prop]) => {\n\t\tif (typeof prop === \"object\" && prop !== null && !Array.isArray(prop)) {\n\t\t\tconst p = prop;\n\t\t\treturn [key, p.properties != null ? toPartialJSONSchema(p) : prop];\n\t\t}\n\t\treturn [key, prop];\n\t}));\n\treturn result;\n}\nfunction defaultToolFilter(_name, tool) {\n\treturn !tool.disabled && tool.type !== \"backend\";\n}\n/**\n* Converts a record of tools to a record of tool definitions with JSON Schema parameters.\n* By default, filters out disabled tools and backend tools.\n*/\nfunction toToolsJSONSchema(tools, options = {}) {\n\tif (!tools) return {};\n\tconst filter = options.filter ?? defaultToolFilter;\n\treturn Object.fromEntries(Object.entries(tools).filter(([name, tool]) => filter(name, tool) && tool.parameters).map(([name, tool]) => [name, {\n\t\t...tool.description && { description: tool.description },\n\t\tparameters: toJSONSchema(tool.parameters)\n\t}]));\n}\n//#endregion\nexport { toJSONSchema, toPartialJSONSchema, toToolsJSONSchema };\n\n//# sourceMappingURL=schema-utils.js.map"],"mappings":";AACA,SAAS,iBAAiB,QAAQ;CACjC,OAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,eAAe,UAAU,OAAO,OAAO,iBAAiB;AACjH;AACA,SAAS,sBAAsB,QAAQ;CACtC,OAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,kBAAkB,UAAU,OAAO,OAAO,iBAAiB;AACpH;AACA,SAAS,gBAAgB,QAAQ;CAChC,OAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,YAAY,UAAU,OAAO,OAAO,WAAW;AACxG;;;;;;;;;;AAUA,SAAS,aAAa,QAAQ;CAC7B,IAAI,iBAAiB,MAAM,GAAG;EAC7B,MAAM,qBAAqB,OAAO,aAAa;EAC/C,IAAI,OAAO,uBAAuB,YAAY,OAAO,mBAAmB;EACxE,MAAM,aAAa,OAAO,aAAa;EACvC,IAAI,OAAO,eAAe,YAAY,eAAe,QAAQ,OAAO,WAAW,UAAU,YAAY,OAAO,WAAW,MAAM;CAC9H;CACA,IAAI,sBAAsB,MAAM,GAAG,OAAO,OAAO,aAAa;CAC9D,IAAI,gBAAgB,MAAM,GAAG,OAAO,OAAO,OAAO;CAClD,IAAI,iBAAiB,MAAM,GAAG,MAAM,IAAI,MAAM,8PAA8P;CAC5S,OAAO;AACR;AAgBA,SAAS,kBAAkB,OAAO,MAAM;CACvC,OAAO,CAAC,KAAK,YAAY,KAAK,SAAS;AACxC;;;;;AAKA,SAAS,kBAAkB,OAAO,UAAU,CAAC,GAAG;CAC/C,IAAI,CAAC,OAAO,OAAO,CAAC;CACpB,MAAM,SAAS,QAAQ,UAAU;CACjC,OAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,QAAQ,CAAC,MAAM,UAAU,OAAO,MAAM,IAAI,KAAK,KAAK,UAAU,EAAE,KAAK,CAAC,MAAM,UAAU,CAAC,MAAM;EAC5I,GAAG,KAAK,eAAe,EAAE,aAAa,KAAK,YAAY;EACvD,YAAY,aAAa,KAAK,UAAU;CACzC,CAAC,CAAC,CAAC;AACJ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-types.d.ts","names":["AsyncIterableStream","JSONSchema7","DeepPartial","TypeAtPath","TypePath","ToolResponse","StandardSchemaV1","ToolModelContentPart","type","text","data","mediaType","filename","ToolModelOutputFunction","TArgs","TResult","Promise","toolCallId","input","output","options","ToolCallArgsReader","PathT","Record","U","Array","get","fieldPath","streamValues","streamText","forEach","ToolCallResponseReader","ToolCallReader","args","response","result","ToolExecutionContext","AbortSignal","abortSignal","human","payload","ToolExecuteFunction","context","ToolStreamCallFunction","reader","OnSchemaValidationErrorFunction","ToolBase","streamCall","BackendTool","description","parameters","disabled","execute","toModelOutput","experimental_onSchemaValidationError","FrontendTool","HumanTool","Tool","ToolWithoutType","Omit"],"sources":["../../../../../../../assistant-stream/dist/core/tool/tool-types.d.ts"],"mappings":";;KAOKO,oBAAAA;EAEME,4EADmED,IAAAA,UACnEC;EAAAA,SAAAA,IAAAA;AAAAA;EAQAE,4EANmEH,IAAAA;EAOnEI;;AAAQ;;EAARA,SAFAF,IAAAA;WACAC,SAAAA;WACAC,QAAAA;AAAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import { ToolModelContentPart } from "./core/tool/tool-types.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createResumableAssistantStreamResponse.d.ts","names":["AssistantStreamController","AssistantStreamEncoder","ResumableStreamContext","RESUMABLE_STREAM_ID_HEADER","CreateResumableAssistantStreamResponseOptions","PromiseLike","HeadersInit","context","streamId","callback","controller","encoder","headers","createResumableAssistantStreamResponse","Response","Promise","options","CreateResumeAssistantStreamResponseOptions","missingResponse","createResumeAssistantStreamResponse"],"sources":["../../../../../../assistant-stream/dist/resumable/createResumableAssistantStreamResponse.d.ts"],"mappings":";;cAKcG,0BAAAA"}
|
package/dist/packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createResumableAssistantStreamResponse.js","names":[],"sources":["../../../../../../assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js"],"sourcesContent":["import { DataStreamEncoder } from \"../core/serialization/data-stream/DataStream.js\";\nimport { createAssistantStream } from \"../core/modules/assistant-stream.js\";\n//#region src/resumable/createResumableAssistantStreamResponse.ts\nconst RESUMABLE_STREAM_ID_HEADER = \"x-resumable-stream-id\";\nasync function createResumableAssistantStreamResponse(options) {\n\tconst encoder = (options.encoder ?? (() => new DataStreamEncoder()))();\n\tconst stream = await options.context.run(options.streamId, () => {\n\t\treturn createAssistantStream(options.callback).pipeThrough(encoder);\n\t});\n\treturn new Response(stream, { headers: mergeHeaders(encoder.headers, options.headers, options.streamId) });\n}\nasync function createResumeAssistantStreamResponse(options) {\n\tconst stream = await options.context.resume(options.streamId);\n\tif (!stream) return options.missingResponse?.() ?? defaultMissingResponse();\n\tconst encoder = (options.encoder ?? (() => new DataStreamEncoder()))();\n\treturn new Response(stream, { headers: mergeHeaders(encoder.headers, options.headers, options.streamId) });\n}\nfunction defaultMissingResponse() {\n\treturn new Response(JSON.stringify({ error: \"stream not found\" }), {\n\t\tstatus: 404,\n\t\theaders: { \"Content-Type\": \"application/json\" }\n\t});\n}\nfunction mergeHeaders(encoderHeaders, extra, streamId) {\n\tconst merged = new Headers(encoderHeaders ?? {});\n\tif (extra) for (const [key, value] of new Headers(extra)) merged.set(key, value);\n\tmerged.set(RESUMABLE_STREAM_ID_HEADER, streamId);\n\treturn merged;\n}\n//#endregion\nexport { RESUMABLE_STREAM_ID_HEADER, createResumableAssistantStreamResponse, createResumeAssistantStreamResponse };\n\n//# sourceMappingURL=createResumableAssistantStreamResponse.js.map"],"mappings":";AAGA,MAAM,6BAA6B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"json-value.d.ts","names":["ReadonlyJSONValue","ReadonlyJSONObject","ReadonlyJSONArray","key"],"sources":["../../../../../../../assistant-stream/dist/utils/json/json-value.d.ts"],"mappings":";;KACKA,iBAAAA,sCAAuDC,kBAAAA,GAAqBC,iBAAiB;AAAA,KAC7FD,kBAAAA;EAAAA,UACOE,GAAAA,WAAcH,iBAAiB;AAAA;AAAA,KAEtCE,iBAAAA,YAA6BF,iBAAiB"}
|
|
File without changes
|
/package/dist/{packages/assistant-stream → assistant-stream}/dist/core/AssistantStreamChunk.d.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/{packages/assistant-stream → assistant-stream}/dist/core/modules/assistant-stream.d.ts
RENAMED
|
File without changes
|
|
File without changes
|
/package/dist/{packages/assistant-stream → assistant-stream}/dist/core/modules/tool-call.d.ts
RENAMED
|
File without changes
|