@assistant-ui/core 0.2.6 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/attachment.d.ts.map +1 -1
- package/dist/adapters/speech.d.ts.map +1 -1
- package/dist/adapters/speech.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -0
- package/dist/internal/duplicate-detection.d.ts +5 -0
- package/dist/internal/duplicate-detection.d.ts.map +1 -0
- package/dist/internal/duplicate-detection.js +11 -0
- package/dist/internal/duplicate-detection.js.map +1 -0
- package/dist/internal.d.ts +2 -2
- package/dist/internal.js +2 -2
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js.map +1 -1
- package/dist/model-context/frame/provider.d.ts.map +1 -1
- package/dist/model-context/frame/provider.js.map +1 -1
- package/dist/model-context/registry.d.ts.map +1 -1
- package/dist/model-context/tool.d.ts.map +1 -1
- package/dist/react/AssistantProvider.d.ts.map +1 -1
- package/dist/react/AssistantProvider.js.map +1 -1
- package/dist/react/client/Interactables.js.map +1 -1
- package/dist/react/client/Tools.d.ts.map +1 -1
- package/dist/react/client/Tools.js +26 -15
- package/dist/react/client/Tools.js.map +1 -1
- package/dist/react/index.d.ts +5 -4
- package/dist/react/index.js +2 -2
- package/dist/react/model-context/toolbox.d.ts +29 -2
- package/dist/react/model-context/toolbox.d.ts.map +1 -1
- package/dist/react/model-context/toolbox.js +18 -0
- package/dist/react/model-context/toolbox.js.map +1 -0
- package/dist/react/model-context/useAssistantTool.d.ts.map +1 -1
- package/dist/react/model-context/useAssistantTool.js +6 -3
- package/dist/react/model-context/useAssistantTool.js.map +1 -1
- package/dist/react/model-context/useAssistantToolUI.d.ts +6 -0
- package/dist/react/model-context/useAssistantToolUI.d.ts.map +1 -1
- package/dist/react/model-context/useAssistantToolUI.js +4 -2
- package/dist/react/model-context/useAssistantToolUI.js.map +1 -1
- package/dist/react/model-context/useInlineRender.js.map +1 -1
- package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.d.ts +49 -7
- package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.js +28 -3
- package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
- package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageParts.js +2 -7
- package/dist/react/primitives/message/MessageParts.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
- package/dist/react/runtimes/RuntimeAdapterProvider.js +6 -5
- package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
- package/dist/react/runtimes/external-message-converter.d.ts +1 -1
- package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.js +1 -0
- package/dist/react/runtimes/external-message-converter.js.map +1 -1
- package/dist/react/runtimes/useExternalStoreSharedOptions.d.ts +7 -0
- package/dist/react/runtimes/useExternalStoreSharedOptions.d.ts.map +1 -0
- package/dist/react/runtimes/useExternalStoreSharedOptions.js +21 -0
- package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -0
- package/dist/react/runtimes/useLocalRuntime.d.ts.map +1 -1
- package/dist/react/runtimes/useLocalRuntime.js.map +1 -1
- package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
- package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
- package/dist/react/types/scopes/tools.d.ts +19 -2
- package/dist/react/types/scopes/tools.d.ts.map +1 -1
- package/dist/react/utils/groupParts.d.ts +32 -11
- package/dist/react/utils/groupParts.d.ts.map +1 -1
- package/dist/react/utils/groupParts.js +13 -6
- package/dist/react/utils/groupParts.js.map +1 -1
- package/dist/runtime/api/assistant-runtime.d.ts.map +1 -1
- package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
- package/dist/runtime/api/attachment-runtime.js.map +1 -1
- package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
- package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
- package/dist/runtime/api/message-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/base/base-assistant-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/interfaces/thread-runtime-core.d.ts +8 -0
- package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/utils/message-repository.d.ts +9 -1
- package/dist/runtime/utils/message-repository.d.ts.map +1 -1
- package/dist/runtime/utils/message-repository.js +34 -14
- package/dist/runtime/utils/message-repository.js.map +1 -1
- package/dist/runtime/utils/thread-message-like.d.ts +1 -0
- package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
- package/dist/runtime/utils/thread-message-like.js +2 -1
- package/dist/runtime/utils/thread-message-like.js.map +1 -1
- package/dist/runtimes/external-store/external-store-adapter.d.ts +31 -0
- package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-shared-options.d.ts +8 -0
- package/dist/runtimes/external-store/external-store-shared-options.d.ts.map +1 -0
- package/dist/runtimes/external-store/external-store-shared-options.js +11 -0
- package/dist/runtimes/external-store/external-store-shared-options.js.map +1 -0
- 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.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +25 -2
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js +106 -26
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/external-store/thread-message-converter.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +168 -0
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -0
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +449 -0
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -0
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/subscribable/subscribable.js.map +1 -1
- package/dist/tests/remote-thread-list-test-helpers.d.ts.map +1 -1
- package/dist/types/message.d.ts +6 -0
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/message.js.map +1 -1
- package/dist/utils/composite-context-provider.d.ts.map +1 -1
- package/dist/utils/id.d.ts +1 -3
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +1 -4
- package/dist/utils/id.js.map +1 -1
- package/package.json +10 -10
- package/src/adapters/index.ts +1 -4
- package/src/adapters/speech.ts +0 -1
- package/src/index.ts +12 -0
- package/src/internal/duplicate-detection.ts +26 -0
- package/src/internal.ts +0 -2
- package/src/model-context/frame/host.ts +0 -1
- package/src/model-context/frame/provider.ts +0 -1
- package/src/react/AssistantProvider.tsx +2 -3
- package/src/react/client/Interactables.ts +0 -1
- package/src/react/client/Tools.ts +50 -25
- package/src/react/index.ts +9 -8
- package/src/react/model-context/toolbox.ts +46 -1
- package/src/react/model-context/useAssistantTool.ts +8 -3
- package/src/react/model-context/useAssistantToolUI.ts +9 -2
- package/src/react/model-context/useInlineRender.ts +0 -1
- package/src/react/primitives/chainOfThought/ChainOfThoughtParts.tsx +1 -2
- package/src/react/primitives/message/MessageAttachments.test.tsx +1 -1
- package/src/react/primitives/message/MessageGroupedParts.tsx +102 -13
- package/src/react/primitives/message/MessageParts.tsx +4 -7
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +0 -3
- package/src/react/runtimes/RuntimeAdapterProvider.tsx +12 -7
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +0 -3
- package/src/react/runtimes/external-message-converter.ts +5 -1
- package/src/react/runtimes/useExternalStoreSharedOptions.ts +23 -0
- package/src/react/runtimes/useLocalRuntime.ts +0 -10
- package/src/react/runtimes/useRemoteThreadListRuntime.ts +0 -6
- package/src/react/types/scopes/tools.ts +20 -1
- package/src/react/utils/groupParts.ts +49 -18
- package/src/runtime/api/attachment-runtime.ts +1 -2
- package/src/runtime/interfaces/thread-runtime-core.ts +8 -0
- package/src/runtime/internal.ts +1 -4
- package/src/runtime/utils/message-repository.ts +57 -16
- package/src/runtime/utils/thread-message-like.ts +2 -0
- package/src/runtimes/external-store/external-store-adapter.ts +33 -0
- package/src/runtimes/external-store/external-store-shared-options.ts +18 -0
- package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +1 -3
- package/src/runtimes/external-store/external-store-thread-runtime-core.ts +179 -37
- package/src/runtimes/tool-invocations/EDGE_CASES.md +194 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +1054 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +782 -0
- package/src/subscribable/subscribable.ts +3 -3
- package/src/tests/MessageRepository.test.ts +83 -52
- package/src/tests/OptimisticState-delete-crash.test.ts +2 -0
- package/src/tests/OptimisticState-list-race.test.ts +2 -4
- package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +5 -5
- package/src/tests/auiV0Encode.test.ts +1 -1
- package/src/tests/composer-can-send.test.ts +8 -4
- package/src/tests/duplicate-detection.test.ts +34 -0
- package/src/tests/external-store-thread-list-runtime-core.test.ts +1 -1
- package/src/tests/external-store-thread-runtime-core.test.ts +112 -79
- package/src/tests/groupParts.test.ts +70 -0
- package/src/tests/no-unsafe-process-env.test.ts +1 -0
- package/src/tests/remote-thread-list-isLoading.test.ts +2 -5
- package/src/tests/thread-message-like.test.ts +4 -1
- package/src/types/index.ts +1 -4
- package/src/types/message.ts +6 -0
- package/src/utils/id.ts +0 -4
- package/dist/react/runtimes/useToolInvocations.d.ts +0 -53
- package/dist/react/runtimes/useToolInvocations.d.ts.map +0 -1
- package/dist/react/runtimes/useToolInvocations.js +0 -380
- package/dist/react/runtimes/useToolInvocations.js.map +0 -1
- package/src/react/runtimes/useToolInvocations.ts +0 -694
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
import {
|
|
12
12
|
buildGroupTree,
|
|
13
13
|
GROUPBY_MEMO_KEY,
|
|
14
|
+
type GroupByContext,
|
|
14
15
|
type GroupNode,
|
|
15
16
|
} from "../../utils/groupParts";
|
|
16
17
|
import { MessagePartChildren, type EnrichedPartState } from "./MessageParts";
|
|
@@ -28,13 +29,40 @@ export namespace MessagePrimitiveGroupedParts {
|
|
|
28
29
|
readonly indices: readonly number[];
|
|
29
30
|
};
|
|
30
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Synthetic trailing slot for a streaming/loading affordance (a
|
|
34
|
+
* "thinking…" dot, etc.). Surfaced through the same `{ part }` channel
|
|
35
|
+
* as groups and leaf parts so a single `switch (part.type)` renders it
|
|
36
|
+
* via `case "indicator"`.
|
|
37
|
+
*
|
|
38
|
+
* It is only ever emitted while the message is running, so its presence
|
|
39
|
+
* alone means "render your loading UI here" — there's no `status` to
|
|
40
|
+
* branch on.
|
|
41
|
+
*/
|
|
42
|
+
export type IndicatorPart = {
|
|
43
|
+
readonly type: "indicator";
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* When to emit the synthetic {@link IndicatorPart}. It is **only** emitted
|
|
48
|
+
* while the message is running (streaming); the mode further restricts
|
|
49
|
+
* which running states qualify:
|
|
50
|
+
* - `"never"` — never.
|
|
51
|
+
* - `"empty"` — only when the message has no parts yet.
|
|
52
|
+
* - `"no-text"` (default) — when the last part isn't `text`/`reasoning`
|
|
53
|
+
* (e.g. it ended on a tool call, so the assistant likely isn't done).
|
|
54
|
+
* - `"always"` — whenever the message is running, regardless of parts.
|
|
55
|
+
*/
|
|
56
|
+
export type IndicatorMode = "never" | "empty" | "no-text" | "always";
|
|
57
|
+
|
|
31
58
|
export type RenderInfo<TKey extends `group-${string}` = `group-${string}`> = {
|
|
32
59
|
/**
|
|
33
60
|
* Either a coalesced group ({@link GroupPart}, identified by a
|
|
34
|
-
* `group-…` `type`)
|
|
35
|
-
* `
|
|
61
|
+
* `group-…` `type`), a single enriched leaf part, or the synthetic
|
|
62
|
+
* {@link IndicatorPart} (`type: "indicator"`). Use one switch over
|
|
63
|
+
* `part.type` to handle all three.
|
|
36
64
|
*/
|
|
37
|
-
readonly part: GroupPart<TKey> | EnrichedPartState;
|
|
65
|
+
readonly part: GroupPart<TKey> | EnrichedPartState | IndicatorPart;
|
|
38
66
|
/**
|
|
39
67
|
* For group nodes: the recursively-rendered subtree (subgroups +
|
|
40
68
|
* leaf parts). For leaf parts: a sentinel that throws when rendered
|
|
@@ -59,6 +87,9 @@ export namespace MessagePrimitiveGroupedParts {
|
|
|
59
87
|
* the helper isn't expressive enough (e.g. branching on
|
|
60
88
|
* `part.toolName` or part metadata).
|
|
61
89
|
*
|
|
90
|
+
* The second argument is a {@link GroupByContext} carrying the tool-UI
|
|
91
|
+
* registry, for grouping that depends on it (e.g. standalone tool calls).
|
|
92
|
+
*
|
|
62
93
|
* @example
|
|
63
94
|
* ```tsx
|
|
64
95
|
* import { groupPartByType } from "@assistant-ui/react";
|
|
@@ -71,12 +102,27 @@ export namespace MessagePrimitiveGroupedParts {
|
|
|
71
102
|
* >
|
|
72
103
|
* ```
|
|
73
104
|
*/
|
|
74
|
-
readonly groupBy: (
|
|
105
|
+
readonly groupBy: (
|
|
106
|
+
part: PartState,
|
|
107
|
+
context: GroupByContext,
|
|
108
|
+
) => readonly TKey[] | null;
|
|
75
109
|
|
|
76
110
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
111
|
+
* Controls emission of the synthetic {@link IndicatorPart} — a
|
|
112
|
+
* trailing `{ part: { type: "indicator", status } }` render call you
|
|
113
|
+
* handle with `case "indicator"` to show loading/status UI.
|
|
114
|
+
*
|
|
115
|
+
* @default "no-text"
|
|
116
|
+
* @see IndicatorMode
|
|
117
|
+
*/
|
|
118
|
+
readonly indicator?: IndicatorMode;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Render function called once per group node, once per leaf part, and
|
|
122
|
+
* (when the `indicator` condition is met) once for the trailing
|
|
123
|
+
* {@link IndicatorPart}. Switch on `part.type`: `"group-…"` cases wrap
|
|
124
|
+
* `children`; real part types (`"text"`, `"tool-call"`, …) render the
|
|
125
|
+
* part directly; `"indicator"` renders status/loading UI.
|
|
80
126
|
*
|
|
81
127
|
* Leaf parts receive the same {@link EnrichedPartState} that
|
|
82
128
|
* `<MessagePrimitive.Parts>` would produce (`toolUI`, `addResult`,
|
|
@@ -88,6 +134,31 @@ export namespace MessagePrimitiveGroupedParts {
|
|
|
88
134
|
|
|
89
135
|
const COMPLETE_STATUS: MessagePartStatus = Object.freeze({ type: "complete" });
|
|
90
136
|
|
|
137
|
+
const shouldShowIndicator = (
|
|
138
|
+
mode: MessagePrimitiveGroupedParts.IndicatorMode,
|
|
139
|
+
parts: readonly PartState[],
|
|
140
|
+
isRunning: boolean,
|
|
141
|
+
): boolean => {
|
|
142
|
+
// The indicator is a streaming affordance — never show it on a settled
|
|
143
|
+
// message, whatever the mode.
|
|
144
|
+
if (!isRunning) return false;
|
|
145
|
+
|
|
146
|
+
switch (mode) {
|
|
147
|
+
case "never":
|
|
148
|
+
return false;
|
|
149
|
+
case "always":
|
|
150
|
+
return true;
|
|
151
|
+
case "empty":
|
|
152
|
+
return parts.length === 0;
|
|
153
|
+
case "no-text": {
|
|
154
|
+
const last = parts[parts.length - 1];
|
|
155
|
+
return (
|
|
156
|
+
last !== undefined && last.type !== "text" && last.type !== "reasoning"
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
91
162
|
/**
|
|
92
163
|
* `children` placeholder passed for leaf-part renders. Leaf parts have no
|
|
93
164
|
* inner subtree; rendering this sentinel signals the consumer wrote
|
|
@@ -161,6 +232,7 @@ const renderNode = <TKey extends `group-${string}`>(
|
|
|
161
232
|
* case "group-tool": return <ToolStack>{children}</ToolStack>;
|
|
162
233
|
* case "text": return <MarkdownText />;
|
|
163
234
|
* case "tool-call": return part.toolUI ?? <ToolFallback {...part} />;
|
|
235
|
+
* case "indicator": return <LoadingDots />;
|
|
164
236
|
* default: return null;
|
|
165
237
|
* }
|
|
166
238
|
* }}
|
|
@@ -169,9 +241,17 @@ const renderNode = <TKey extends `group-${string}`>(
|
|
|
169
241
|
*/
|
|
170
242
|
export const MessagePrimitiveGroupedParts = <TKey extends `group-${string}`>({
|
|
171
243
|
groupBy,
|
|
244
|
+
indicator = "no-text",
|
|
172
245
|
children,
|
|
173
246
|
}: MessagePrimitiveGroupedParts.Props<TKey>): ReactNode => {
|
|
174
247
|
const parts = useAuiState(useShallow((s) => s.message.parts));
|
|
248
|
+
// Handed to `groupBy` as its `context` argument (see GroupByContext).
|
|
249
|
+
const toolUIs = useAuiState((s) => s.tools.toolUIs);
|
|
250
|
+
// Subscribe to a boolean, not the status object: the tree only needs to
|
|
251
|
+
// re-render when running-ness flips, and `"never"` opts out entirely.
|
|
252
|
+
const isRunning = useAuiState((s) =>
|
|
253
|
+
indicator === "never" ? false : s.message.status?.type === "running",
|
|
254
|
+
);
|
|
175
255
|
|
|
176
256
|
// Helpers like `groupPartByType` tag the function with `GROUPBY_MEMO_KEY`
|
|
177
257
|
// (a stable string fingerprint of the helper config). When present,
|
|
@@ -182,13 +262,22 @@ export const MessagePrimitiveGroupedParts = <TKey extends `group-${string}`>({
|
|
|
182
262
|
GROUPBY_MEMO_KEY
|
|
183
263
|
];
|
|
184
264
|
const memoDep = memoKey ?? groupBy;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
);
|
|
265
|
+
const tree = useMemo(() => {
|
|
266
|
+
const context: GroupByContext = { toolUIs };
|
|
267
|
+
return buildGroupTree(parts.map((part) => groupBy(part, context) ?? []));
|
|
268
|
+
// oxlint-disable-next-line tap-hooks/exhaustive-deps -- groupBy is captured via memoDep (either its identity or the helper's memoKey fingerprint); listing it directly would defeat the helper-tagged memo path
|
|
269
|
+
}, [parts, memoDep, toolUIs]);
|
|
190
270
|
|
|
191
|
-
return
|
|
271
|
+
return (
|
|
272
|
+
<>
|
|
273
|
+
{tree.map((node) => renderNode(node, parts, children))}
|
|
274
|
+
{shouldShowIndicator(indicator, parts, isRunning) &&
|
|
275
|
+
children({
|
|
276
|
+
part: { type: "indicator" },
|
|
277
|
+
children: <PartChildrenSentinel />,
|
|
278
|
+
})}
|
|
279
|
+
</>
|
|
280
|
+
);
|
|
192
281
|
};
|
|
193
282
|
|
|
194
283
|
MessagePrimitiveGroupedParts.displayName = "MessagePrimitive.GroupedParts";
|
|
@@ -308,11 +308,9 @@ const ToolUIDisplay = ({
|
|
|
308
308
|
}: {
|
|
309
309
|
Fallback: ToolCallMessagePartComponent | undefined;
|
|
310
310
|
} & ToolCallMessagePartProps) => {
|
|
311
|
-
const Render = useAuiState(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
return Render;
|
|
315
|
-
});
|
|
311
|
+
const Render = useAuiState(
|
|
312
|
+
(s) => s.tools.toolUIs[props.toolName]?.[0]?.render ?? Fallback,
|
|
313
|
+
);
|
|
316
314
|
if (!Render) return null;
|
|
317
315
|
return <Render {...props} />;
|
|
318
316
|
};
|
|
@@ -574,8 +572,7 @@ function resolveToolRender(
|
|
|
574
572
|
toolsState: ToolsState,
|
|
575
573
|
part: Extract<PartState, { type: "tool-call" }>,
|
|
576
574
|
): ToolCallMessagePartComponent | null {
|
|
577
|
-
const
|
|
578
|
-
const named = Array.isArray(entry) ? (entry[0] ?? null) : (entry ?? null);
|
|
575
|
+
const named = toolsState.toolUIs[part.toolName]?.[0]?.render ?? null;
|
|
579
576
|
if (named) return named;
|
|
580
577
|
if (isMcpAppUri(part.mcp?.app?.resourceUri) && toolsState.mcpApp) {
|
|
581
578
|
return toolsState.mcpApp.render;
|
|
@@ -62,7 +62,6 @@ export class RemoteThreadListThreadListRuntimeCore
|
|
|
62
62
|
isLoading: true,
|
|
63
63
|
};
|
|
64
64
|
},
|
|
65
|
-
// biome-ignore lint/suspicious/noThenProperty: OptimisticState reducer pattern
|
|
66
65
|
then: (state, l) => {
|
|
67
66
|
if (generation !== this._loadGeneration) return state;
|
|
68
67
|
const fresh = classifyThreads(l.threads, {
|
|
@@ -120,7 +119,6 @@ export class RemoteThreadListThreadListRuntimeCore
|
|
|
120
119
|
.optimisticUpdate({
|
|
121
120
|
execute: () => adapter.list({ after: cursor }),
|
|
122
121
|
loading: (state) => ({ ...state, isLoadingMore: true }),
|
|
123
|
-
// biome-ignore lint/suspicious/noThenProperty: OptimisticState reducer pattern
|
|
124
122
|
then: (state, l) => {
|
|
125
123
|
if (generation !== this._loadGeneration) return state;
|
|
126
124
|
if (adapter !== this._options.adapter) return state;
|
|
@@ -423,7 +421,6 @@ export class RemoteThreadListThreadListRuntimeCore
|
|
|
423
421
|
},
|
|
424
422
|
};
|
|
425
423
|
},
|
|
426
|
-
// biome-ignore lint/suspicious/noThenProperty: OptimisticState reducer pattern
|
|
427
424
|
then: (state, { remoteId, externalId }) => {
|
|
428
425
|
const data = getThreadData(state, threadId);
|
|
429
426
|
if (!data) return state;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
type FC,
|
|
4
|
+
type ReactNode,
|
|
5
|
+
useContext,
|
|
6
|
+
useMemo,
|
|
7
|
+
} from "react";
|
|
2
8
|
import type { ThreadHistoryAdapter } from "../../adapters/thread-history";
|
|
3
9
|
import type { AttachmentAdapter } from "../../adapters/attachment";
|
|
4
10
|
import type { ModelContextProvider } from "../../model-context/types";
|
|
@@ -23,13 +29,12 @@ export const RuntimeAdapterProvider: FC<RuntimeAdapterProvider.Props> = ({
|
|
|
23
29
|
children,
|
|
24
30
|
}) => {
|
|
25
31
|
const context = useContext(RuntimeAdaptersContext);
|
|
32
|
+
const value = useMemo(
|
|
33
|
+
() => ({ ...context, ...adapters }),
|
|
34
|
+
[context, adapters],
|
|
35
|
+
);
|
|
26
36
|
return (
|
|
27
|
-
<RuntimeAdaptersContext.Provider
|
|
28
|
-
value={{
|
|
29
|
-
...context,
|
|
30
|
-
...adapters,
|
|
31
|
-
}}
|
|
32
|
-
>
|
|
37
|
+
<RuntimeAdaptersContext.Provider value={value}>
|
|
33
38
|
{children}
|
|
34
39
|
</RuntimeAdaptersContext.Provider>
|
|
35
40
|
);
|
|
@@ -43,20 +43,17 @@ export const useCloudThreadListAdapter = (
|
|
|
43
43
|
|
|
44
44
|
const unstable_Provider = useCallback<FC<PropsWithChildren>>(
|
|
45
45
|
function Provider({ children }) {
|
|
46
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
47
46
|
const history = useAssistantCloudThreadHistoryAdapter({
|
|
48
47
|
get current() {
|
|
49
48
|
return adapterRef.current.cloud ?? autoCloud!;
|
|
50
49
|
},
|
|
51
50
|
});
|
|
52
51
|
const cloudInstance = adapterRef.current.cloud ?? autoCloud!;
|
|
53
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
54
52
|
const attachments = useMemo(
|
|
55
53
|
() => new CloudFileAttachmentAdapter(cloudInstance),
|
|
56
54
|
[cloudInstance],
|
|
57
55
|
);
|
|
58
56
|
|
|
59
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
60
57
|
const adapters = useMemo(
|
|
61
58
|
() => ({
|
|
62
59
|
history,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
type ThreadMessageLike,
|
|
13
13
|
} from "../../runtime/utils/thread-message-like";
|
|
14
14
|
import { getAutoStatus, isAutoStatus } from "../../runtime/utils/auto-status";
|
|
15
|
-
import type { ToolExecutionStatus } from "
|
|
15
|
+
import type { ToolExecutionStatus } from "../../runtimes/tool-invocations/ToolInvocationTracker";
|
|
16
16
|
import type { ReadonlyJSONValue } from "assistant-stream/utils";
|
|
17
17
|
import { generateErrorMessageId } from "../../utils/id";
|
|
18
18
|
import type {
|
|
@@ -198,6 +198,10 @@ const joinExternalMessages = (
|
|
|
198
198
|
assistantMessage.metadata.submittedFeedback =
|
|
199
199
|
output.metadata.submittedFeedback;
|
|
200
200
|
}
|
|
201
|
+
|
|
202
|
+
if (output.metadata.isOptimistic) {
|
|
203
|
+
assistantMessage.metadata.isOptimistic = true;
|
|
204
|
+
}
|
|
201
205
|
}
|
|
202
206
|
// TODO keep this in sync
|
|
203
207
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import type { ExternalStoreSharedOptions } from "../../runtimes/external-store/external-store-shared-options";
|
|
5
|
+
|
|
6
|
+
export const useExternalStoreSharedOptions = (
|
|
7
|
+
options: ExternalStoreSharedOptions,
|
|
8
|
+
): ExternalStoreSharedOptions => {
|
|
9
|
+
const { isDisabled, isSendDisabled, unstable_capabilities, suggestions } =
|
|
10
|
+
options;
|
|
11
|
+
return useMemo(
|
|
12
|
+
() =>
|
|
13
|
+
({
|
|
14
|
+
isDisabled,
|
|
15
|
+
isSendDisabled,
|
|
16
|
+
unstable_capabilities,
|
|
17
|
+
suggestions,
|
|
18
|
+
}) satisfies {
|
|
19
|
+
[K in keyof Required<ExternalStoreSharedOptions>]: ExternalStoreSharedOptions[K];
|
|
20
|
+
},
|
|
21
|
+
[isDisabled, isSendDisabled, unstable_capabilities, suggestions],
|
|
22
|
+
);
|
|
23
|
+
};
|
|
@@ -22,7 +22,6 @@ const useLocalThreadRuntime = (
|
|
|
22
22
|
chatModel: ChatModelAdapter,
|
|
23
23
|
{ initialMessages, ...options }: LocalRuntimeOptions,
|
|
24
24
|
): AssistantRuntime => {
|
|
25
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
26
25
|
const { modelContext, ...threadListAdapters } = useRuntimeAdapters() ?? {};
|
|
27
26
|
const opt = {
|
|
28
27
|
...options,
|
|
@@ -33,41 +32,33 @@ const useLocalThreadRuntime = (
|
|
|
33
32
|
},
|
|
34
33
|
};
|
|
35
34
|
|
|
36
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
37
35
|
const [runtime] = useState(() => new LocalRuntimeCore(opt, initialMessages));
|
|
38
36
|
|
|
39
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
40
37
|
const threadIdRef = useRef<string | undefined>(undefined);
|
|
41
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
42
38
|
threadIdRef.current = useAuiState((s) => s.threadListItem.remoteId);
|
|
43
39
|
|
|
44
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
45
40
|
useEffect(() => {
|
|
46
41
|
runtime.threads
|
|
47
42
|
.getMainThreadRuntimeCore()
|
|
48
43
|
.__internal_setGetThreadId(() => threadIdRef.current);
|
|
49
44
|
}, [runtime]);
|
|
50
45
|
|
|
51
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
52
46
|
useEffect(() => {
|
|
53
47
|
return () => {
|
|
54
48
|
runtime.threads.getMainThreadRuntimeCore().detach();
|
|
55
49
|
};
|
|
56
50
|
}, [runtime]);
|
|
57
51
|
|
|
58
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
59
52
|
useEffect(() => {
|
|
60
53
|
runtime.threads.getMainThreadRuntimeCore().__internal_setOptions(opt);
|
|
61
54
|
runtime.threads.getMainThreadRuntimeCore().__internal_load();
|
|
62
55
|
});
|
|
63
56
|
|
|
64
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
65
57
|
useEffect(() => {
|
|
66
58
|
if (!modelContext) return undefined;
|
|
67
59
|
return runtime.registerModelContextProvider(modelContext);
|
|
68
60
|
}, [modelContext, runtime]);
|
|
69
61
|
|
|
70
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
71
62
|
return useMemo(() => new AssistantRuntimeImpl(runtime), [runtime]);
|
|
72
63
|
};
|
|
73
64
|
|
|
@@ -102,7 +93,6 @@ export const useLocalRuntime = (
|
|
|
102
93
|
const cloudAdapter = useCloudThreadListAdapter({ cloud });
|
|
103
94
|
return useRemoteThreadListRuntime({
|
|
104
95
|
runtimeHook: function RuntimeHook() {
|
|
105
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
106
96
|
return useLocalThreadRuntime(chatModel, options);
|
|
107
97
|
},
|
|
108
98
|
adapter: cloudAdapter,
|
|
@@ -29,15 +29,12 @@ class RemoteThreadListRuntimeCore
|
|
|
29
29
|
const useRemoteThreadListRuntimeImpl = (
|
|
30
30
|
options: RemoteThreadListOptions,
|
|
31
31
|
): AssistantRuntime => {
|
|
32
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
33
32
|
const [runtime] = useState(() => new RemoteThreadListRuntimeCore(options));
|
|
34
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
35
33
|
useEffect(() => {
|
|
36
34
|
runtime.threads.__internal_setOptions(options);
|
|
37
35
|
runtime.threads.__internal_load();
|
|
38
36
|
}, [runtime, options]);
|
|
39
37
|
|
|
40
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
41
38
|
return useMemo(() => new AssistantRuntimeImpl(runtime), [runtime]);
|
|
42
39
|
};
|
|
43
40
|
|
|
@@ -80,12 +77,9 @@ export const useRemoteThreadListRuntime = (
|
|
|
80
77
|
return stableRuntimeHook();
|
|
81
78
|
}
|
|
82
79
|
|
|
83
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
84
80
|
const runtime = useRemoteThreadListRuntimeImpl(stableOptions);
|
|
85
81
|
|
|
86
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
87
82
|
const prevThreadIdRef = useRef(options.threadId);
|
|
88
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
89
83
|
useEffect(() => {
|
|
90
84
|
if (options.threadId === prevThreadIdRef.current) return;
|
|
91
85
|
prevThreadIdRef.current = options.threadId;
|
|
@@ -5,9 +5,27 @@ export type McpAppResourceOutput = {
|
|
|
5
5
|
readonly render: ToolCallMessagePartComponent;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* A single tool-UI registration: the renderer plus its presentation options.
|
|
10
|
+
* Stored as a per-tool-name list so the name stays registered while any
|
|
11
|
+
* registration of it is mounted.
|
|
12
|
+
*/
|
|
13
|
+
type ToolRegistration = {
|
|
14
|
+
readonly render: ToolCallMessagePartComponent;
|
|
15
|
+
/** Whether this UI renders standalone, outside the chain-of-thought trace. */
|
|
16
|
+
readonly standalone: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
8
19
|
export type ToolsState = {
|
|
9
|
-
|
|
20
|
+
/** Registered tool UIs (renderer + presentation options) keyed by tool name. */
|
|
21
|
+
toolUIs: Record<string, readonly ToolRegistration[]>;
|
|
10
22
|
mcpApp?: McpAppResourceOutput | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated Use {@link toolUIs} instead, whose entries carry the renderer
|
|
25
|
+
* alongside its presentation options. This component-only map is kept for
|
|
26
|
+
* back-compat and will be removed in v0.15.
|
|
27
|
+
*/
|
|
28
|
+
tools: Record<string, ToolCallMessagePartComponent[]>;
|
|
11
29
|
};
|
|
12
30
|
|
|
13
31
|
export type ToolsMethods = {
|
|
@@ -15,6 +33,7 @@ export type ToolsMethods = {
|
|
|
15
33
|
setToolUI(
|
|
16
34
|
toolName: string,
|
|
17
35
|
render: ToolCallMessagePartComponent,
|
|
36
|
+
options?: { standalone?: boolean },
|
|
18
37
|
): Unsubscribe;
|
|
19
38
|
};
|
|
20
39
|
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { isMcpAppUri } from "../../types/message";
|
|
2
2
|
import type { PartState } from "../../store/scopes/part";
|
|
3
|
+
import type { ToolsState } from "../types/scopes/tools";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Registry context passed to a `groupBy` function as its second argument by
|
|
7
|
+
* `<MessagePrimitive.GroupedParts>`. Carries the live tool-UI registry so a
|
|
8
|
+
* `groupBy` can resolve registry-driven grouping (e.g. standalone tool calls)
|
|
9
|
+
* without the part itself having to carry that information.
|
|
10
|
+
*/
|
|
11
|
+
export type GroupByContext = {
|
|
12
|
+
/** Tool UIs registered in the tool-UI registry, keyed by tool name. */
|
|
13
|
+
readonly toolUIs?: ToolsState["toolUIs"];
|
|
14
|
+
};
|
|
3
15
|
|
|
4
16
|
/**
|
|
5
17
|
* Hierarchical adjacent-coalescing grouping for message parts.
|
|
@@ -25,12 +37,20 @@ export const GROUPBY_MEMO_KEY: unique symbol = Symbol.for(
|
|
|
25
37
|
);
|
|
26
38
|
|
|
27
39
|
/**
|
|
28
|
-
* Synthetic part-type
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
40
|
+
* Synthetic part-type keys recognized by {@link groupPartByType}, in
|
|
41
|
+
* addition to real {@link PartState} types:
|
|
42
|
+
*
|
|
43
|
+
* - `"standalone-tool-call"` — a tool-call whose UI should be presented on its
|
|
44
|
+
* own, outside the chain-of-thought grouping. Matches MCP-app tool calls plus
|
|
45
|
+
* any tool-call whose registered UI opts into standalone display (human
|
|
46
|
+
* tools, the built-in generative-UI tool, and tools that set
|
|
47
|
+
* `display: "standalone"`). Resolving the registry-driven cases reads the
|
|
48
|
+
* {@link GroupByContext} passed to the `groupBy` function. Takes precedence
|
|
49
|
+
* over the `"tool-call"` entry.
|
|
50
|
+
* - `"mcp-app"` — **deprecated**, kept for back-compat. Matches only MCP-app
|
|
51
|
+
* tool calls. Prefer `"standalone-tool-call"`, which is a superset.
|
|
32
52
|
*/
|
|
33
|
-
type GroupPartType = PartState["type"] | "mcp-app";
|
|
53
|
+
type GroupPartType = PartState["type"] | "standalone-tool-call" | "mcp-app";
|
|
34
54
|
|
|
35
55
|
/**
|
|
36
56
|
* Build a `groupBy` from a `part.type → group-key path` lookup.
|
|
@@ -38,9 +58,12 @@ type GroupPartType = PartState["type"] | "mcp-app";
|
|
|
38
58
|
* function carries a stable {@link GROUPBY_MEMO_KEY} fingerprint so
|
|
39
59
|
* `<MessagePrimitive.GroupedParts>` can memoize its tree across renders.
|
|
40
60
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* the
|
|
61
|
+
* The synthetic `"standalone-tool-call"` key matches tool calls that should
|
|
62
|
+
* render outside the chain-of-thought grouping. MCP-app calls are detected from
|
|
63
|
+
* the part alone; the registry-driven cases (human tools, the generative-UI
|
|
64
|
+
* tool, `display: "standalone"` opt-ins) are resolved from the
|
|
65
|
+
* {@link GroupByContext} that `<MessagePrimitive.GroupedParts>` passes to the
|
|
66
|
+
* `groupBy` function — the helper needs nothing threaded into it.
|
|
44
67
|
*
|
|
45
68
|
* @example
|
|
46
69
|
* ```tsx
|
|
@@ -48,7 +71,7 @@ type GroupPartType = PartState["type"] | "mcp-app";
|
|
|
48
71
|
* groupBy={groupPartByType({
|
|
49
72
|
* reasoning: ["group-thought", "group-reasoning"],
|
|
50
73
|
* "tool-call": ["group-thought", "group-tool"],
|
|
51
|
-
* "
|
|
74
|
+
* "standalone-tool-call": [],
|
|
52
75
|
* })}
|
|
53
76
|
* >
|
|
54
77
|
* {({ part, children }) => { ... }}
|
|
@@ -57,18 +80,26 @@ type GroupPartType = PartState["type"] | "mcp-app";
|
|
|
57
80
|
*/
|
|
58
81
|
export const groupPartByType = <TKey extends `group-${string}`>(
|
|
59
82
|
map: Partial<Readonly<Record<GroupPartType, readonly TKey[]>>>,
|
|
60
|
-
): ((part: PartState) => readonly TKey[]) => {
|
|
83
|
+
): ((part: PartState, context?: GroupByContext) => readonly TKey[]) => {
|
|
61
84
|
const lookup = map as Readonly<Record<string, readonly TKey[] | undefined>>;
|
|
62
|
-
const fn = ((part) => {
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
85
|
+
const fn = ((part, context) => {
|
|
86
|
+
if (part.type === "tool-call") {
|
|
87
|
+
const isMcpApp = isMcpAppUri(part.mcp?.app?.resourceUri);
|
|
88
|
+
// Read the first registration's flag — the same one `resolveToolRender`
|
|
89
|
+
// renders — so grouping and rendering never disagree for a tool name.
|
|
90
|
+
const isStandalone =
|
|
91
|
+
isMcpApp ||
|
|
92
|
+
(context?.toolUIs?.[part.toolName]?.[0]?.standalone ?? false);
|
|
93
|
+
if (isStandalone && lookup["standalone-tool-call"] !== undefined) {
|
|
94
|
+
return lookup["standalone-tool-call"]!;
|
|
95
|
+
}
|
|
96
|
+
// TODO(v0.15): drop the deprecated "mcp-app" key (superseded by "standalone-tool-call").
|
|
97
|
+
if (isMcpApp && lookup["mcp-app"] !== undefined) {
|
|
98
|
+
return lookup["mcp-app"]!;
|
|
99
|
+
}
|
|
69
100
|
}
|
|
70
101
|
return lookup[part.type] ?? [];
|
|
71
|
-
}) as ((part: PartState) => readonly TKey[]) & {
|
|
102
|
+
}) as ((part: PartState, context?: GroupByContext) => readonly TKey[]) & {
|
|
72
103
|
[GROUPBY_MEMO_KEY]?: string;
|
|
73
104
|
};
|
|
74
105
|
// Sort keys so the fingerprint is insensitive to map insertion order —
|
|
@@ -42,8 +42,7 @@ export type AttachmentRuntime<
|
|
|
42
42
|
|
|
43
43
|
export abstract class AttachmentRuntimeImpl<
|
|
44
44
|
Source extends AttachmentRuntimeSource = AttachmentRuntimeSource,
|
|
45
|
-
> implements AttachmentRuntime
|
|
46
|
-
{
|
|
45
|
+
> implements AttachmentRuntime {
|
|
47
46
|
public get path() {
|
|
48
47
|
return this._core.path;
|
|
49
48
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ToolModelContentPart } from "assistant-stream";
|
|
1
2
|
import type { ReadonlyJSONValue } from "assistant-stream/utils";
|
|
2
3
|
import type { ModelContext } from "../../model-context/types";
|
|
3
4
|
import type { Unsubscribe } from "../../types/unsubscribe";
|
|
@@ -38,6 +39,13 @@ export type AddToolResultOptions = {
|
|
|
38
39
|
result: ReadonlyJSONValue;
|
|
39
40
|
isError: boolean;
|
|
40
41
|
artifact?: ReadonlyJSONValue | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Optional model-content payload produced by the tool. Populated when a
|
|
44
|
+
* client-side `execute()` or `streamCall` returns a `ToolResponse` with
|
|
45
|
+
* `modelContent`. Forwarded through `adapter.onAddToolResult` so the
|
|
46
|
+
* adapter can include it when sending the result back to its backend.
|
|
47
|
+
*/
|
|
48
|
+
modelContent?: readonly ToolModelContentPart[] | undefined;
|
|
41
49
|
};
|
|
42
50
|
|
|
43
51
|
export type ResumeToolCallOptions = {
|
package/src/runtime/internal.ts
CHANGED
|
@@ -18,10 +18,7 @@ export { DefaultEditComposerRuntimeCore } from "./base/default-edit-composer-run
|
|
|
18
18
|
// Runtime Impl Classes
|
|
19
19
|
export { AssistantRuntimeImpl } from "./api/assistant-runtime";
|
|
20
20
|
|
|
21
|
-
export {
|
|
22
|
-
getThreadState,
|
|
23
|
-
ThreadRuntimeImpl,
|
|
24
|
-
} from "./api/thread-runtime";
|
|
21
|
+
export { getThreadState, ThreadRuntimeImpl } from "./api/thread-runtime";
|
|
25
22
|
export type {
|
|
26
23
|
ThreadRuntimeCoreBinding,
|
|
27
24
|
ThreadListItemRuntimeBinding,
|