@assistant-ui/react 0.12.28 → 0.14.2
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/README.md +58 -42
- package/dist/client/ExternalThread.d.ts +7 -0
- package/dist/client/ExternalThread.d.ts.map +1 -1
- package/dist/client/ExternalThread.js +24 -18
- package/dist/client/ExternalThread.js.map +1 -1
- package/dist/client/InMemoryThreadList.d.ts.map +1 -1
- package/dist/client/InMemoryThreadList.js +3 -0
- package/dist/client/InMemoryThreadList.js.map +1 -1
- package/dist/client/SingleThreadList.d.ts.map +1 -1
- package/dist/client/SingleThreadList.js +3 -0
- package/dist/client/SingleThreadList.js.map +1 -1
- package/dist/context/providers/ThreadViewportProvider.d.ts.map +1 -1
- package/dist/context/providers/ThreadViewportProvider.js +2 -10
- package/dist/context/providers/ThreadViewportProvider.js.map +1 -1
- package/dist/context/stores/ThreadViewport.d.ts +46 -4
- package/dist/context/stores/ThreadViewport.d.ts.map +1 -1
- package/dist/context/stores/ThreadViewport.js +51 -7
- package/dist/context/stores/ThreadViewport.js.map +1 -1
- package/dist/index.d.ts +5 -30
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -28
- package/dist/index.js.map +1 -1
- package/dist/legacy-runtime/cloud/auiV0.d.ts +10 -1
- package/dist/legacy-runtime/cloud/auiV0.d.ts.map +1 -1
- package/dist/legacy-runtime/cloud/auiV0.js +21 -3
- package/dist/legacy-runtime/cloud/auiV0.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/utils.d.ts +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/utils.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/utils.js +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/utils.js.map +1 -1
- package/dist/mcp-apps/McpAppRenderer.d.ts +28 -0
- package/dist/mcp-apps/McpAppRenderer.d.ts.map +1 -0
- package/dist/mcp-apps/McpAppRenderer.js +115 -0
- package/dist/mcp-apps/McpAppRenderer.js.map +1 -0
- package/dist/mcp-apps/McpAppsRemoteHost.d.ts +3 -0
- package/dist/mcp-apps/McpAppsRemoteHost.d.ts.map +1 -0
- package/dist/mcp-apps/McpAppsRemoteHost.js +27 -0
- package/dist/mcp-apps/McpAppsRemoteHost.js.map +1 -0
- package/dist/mcp-apps/app-frame.d.ts +3 -0
- package/dist/mcp-apps/app-frame.d.ts.map +1 -0
- package/dist/mcp-apps/app-frame.js +203 -0
- package/dist/mcp-apps/app-frame.js.map +1 -0
- package/dist/mcp-apps/bridge.d.ts +18 -0
- package/dist/mcp-apps/bridge.d.ts.map +1 -0
- package/dist/mcp-apps/bridge.js +290 -0
- package/dist/mcp-apps/bridge.js.map +1 -0
- package/dist/mcp-apps/index.d.ts +4 -0
- package/dist/mcp-apps/index.d.ts.map +1 -0
- package/dist/mcp-apps/index.js +3 -0
- package/dist/mcp-apps/index.js.map +1 -0
- package/dist/mcp-apps/types.d.ts +144 -0
- package/dist/mcp-apps/types.d.ts.map +1 -0
- package/dist/mcp-apps/types.js +3 -0
- package/dist/mcp-apps/types.js.map +1 -0
- package/dist/mcp-apps/utils.d.ts +5 -0
- package/dist/mcp-apps/utils.d.ts.map +1 -0
- package/dist/mcp-apps/utils.js +10 -0
- package/dist/mcp-apps/utils.js.map +1 -0
- package/dist/primitives/composer/ComposerInput.d.ts +6 -0
- package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerInput.js +28 -6
- package/dist/primitives/composer/ComposerInput.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopover.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopover.js +17 -1
- package/dist/primitives/composer/trigger/TriggerPopover.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.d.ts +33 -0
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js +80 -11
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js.map +1 -1
- package/dist/primitives/composer/trigger/triggerKeyboardResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/triggerKeyboardResource.js +2 -1
- package/dist/primitives/composer/trigger/triggerKeyboardResource.js.map +1 -1
- package/dist/primitives/message/MessageRoot.d.ts +6 -30
- package/dist/primitives/message/MessageRoot.d.ts.map +1 -1
- package/dist/primitives/message/MessageRoot.js +68 -25
- package/dist/primitives/message/MessageRoot.js.map +1 -1
- package/dist/primitives/messagePart/useMessagePartSource.d.ts +22 -3
- package/dist/primitives/messagePart/useMessagePartSource.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadViewport.d.ts +38 -0
- package/dist/primitives/thread/ThreadViewport.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadViewport.js +53 -5
- package/dist/primitives/thread/ThreadViewport.js.map +1 -1
- package/dist/primitives/thread/ThreadViewportFooter.d.ts +2 -1
- package/dist/primitives/thread/ThreadViewportFooter.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadViewportFooter.js +2 -1
- package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -1
- package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.d.ts +22 -0
- package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.d.ts.map +1 -0
- package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.js +53 -0
- package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.js.map +1 -0
- package/dist/primitives/thread/topAnchor/createReserveObservers.d.ts +5 -0
- package/dist/primitives/thread/topAnchor/createReserveObservers.d.ts.map +1 -0
- package/dist/primitives/thread/topAnchor/createReserveObservers.js +38 -0
- package/dist/primitives/thread/topAnchor/createReserveObservers.js.map +1 -0
- package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.d.ts +22 -0
- package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.d.ts.map +1 -0
- package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.js +75 -0
- package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.js.map +1 -0
- package/dist/primitives/thread/topAnchor/topAnchorTurn.d.ts +15 -0
- package/dist/primitives/thread/topAnchor/topAnchorTurn.d.ts.map +1 -0
- package/dist/primitives/thread/topAnchor/topAnchorTurn.js +13 -0
- package/dist/primitives/thread/topAnchor/topAnchorTurn.js.map +1 -0
- package/dist/primitives/thread/topAnchor/topAnchorUtils.d.ts +15 -0
- package/dist/primitives/thread/topAnchor/topAnchorUtils.d.ts.map +1 -0
- package/dist/primitives/thread/topAnchor/topAnchorUtils.js +51 -0
- package/dist/primitives/thread/topAnchor/topAnchorUtils.js.map +1 -0
- package/dist/primitives/thread/topAnchor/useTopAnchorReserve.d.ts +7 -0
- package/dist/primitives/thread/topAnchor/useTopAnchorReserve.d.ts.map +1 -0
- package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js +18 -0
- package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js.map +1 -0
- package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
- package/dist/primitives/thread/useThreadViewportAutoScroll.js +13 -1
- package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
- package/dist/primitives/thread.d.ts +0 -1
- package/dist/primitives/thread.d.ts.map +1 -1
- package/dist/primitives/thread.js +0 -1
- package/dist/primitives/thread.js.map +1 -1
- package/dist/primitives/threadList/ThreadListLoadMore.d.ts +13 -0
- package/dist/primitives/threadList/ThreadListLoadMore.d.ts.map +1 -0
- package/dist/primitives/threadList/ThreadListLoadMore.js +11 -0
- package/dist/primitives/threadList/ThreadListLoadMore.js.map +1 -0
- package/dist/primitives/threadList.d.ts +1 -0
- package/dist/primitives/threadList.d.ts.map +1 -1
- package/dist/primitives/threadList.js +1 -0
- package/dist/primitives/threadList.js.map +1 -1
- package/dist/utils/hooks/useManagedRef.d.ts.map +1 -1
- package/dist/utils/hooks/useManagedRef.js +1 -0
- package/dist/utils/hooks/useManagedRef.js.map +1 -1
- package/dist/utils/hooks/useOnResizeContent.d.ts.map +1 -1
- package/dist/utils/hooks/useOnResizeContent.js +1 -2
- package/dist/utils/hooks/useOnResizeContent.js.map +1 -1
- package/package.json +13 -13
- package/src/client/ExternalThread.ts +32 -19
- package/src/client/InMemoryThreadList.ts +3 -0
- package/src/client/SingleThreadList.ts +3 -0
- package/src/context/providers/ThreadViewportProvider.tsx +2 -12
- package/src/context/stores/ThreadViewport.ts +111 -11
- package/src/index.ts +20 -34
- package/src/legacy-runtime/cloud/auiV0.ts +37 -4
- package/src/legacy-runtime/runtime-cores/assistant-transport/utils.ts +1 -5
- package/src/mcp-apps/McpAppRenderer.tsx +215 -0
- package/src/mcp-apps/McpAppsRemoteHost.ts +52 -0
- package/src/mcp-apps/app-frame.tsx +280 -0
- package/src/mcp-apps/bridge.test.ts +391 -0
- package/src/mcp-apps/bridge.ts +435 -0
- package/src/mcp-apps/index.ts +16 -0
- package/src/mcp-apps/types.ts +158 -0
- package/src/mcp-apps/utils.ts +16 -0
- package/src/primitives/composer/ComposerInput.test.tsx +280 -0
- package/src/primitives/composer/ComposerInput.tsx +29 -6
- package/src/primitives/composer/trigger/TriggerPopover.tsx +21 -1
- package/src/primitives/composer/trigger/TriggerPopoverRootContext.test.tsx +152 -0
- package/src/primitives/composer/trigger/TriggerPopoverRootContext.tsx +134 -17
- package/src/primitives/composer/trigger/triggerKeyboardResource.test.ts +236 -0
- package/src/primitives/composer/trigger/triggerKeyboardResource.ts +2 -1
- package/src/primitives/message/MessageRoot.tsx +135 -57
- package/src/primitives/thread/ThreadViewport.tsx +95 -4
- package/src/primitives/thread/ThreadViewportFooter.tsx +2 -1
- package/src/primitives/thread/topAnchor/computeTopAnchorSlack.test.ts +131 -0
- package/src/primitives/thread/topAnchor/computeTopAnchorSlack.ts +94 -0
- package/src/primitives/thread/topAnchor/createReserveObservers.ts +50 -0
- package/src/primitives/thread/topAnchor/mountTopAnchorReserve.test.ts +131 -0
- package/src/primitives/thread/topAnchor/mountTopAnchorReserve.ts +127 -0
- package/src/primitives/thread/topAnchor/topAnchorTurn.test.ts +46 -0
- package/src/primitives/thread/topAnchor/topAnchorTurn.ts +30 -0
- package/src/primitives/thread/topAnchor/topAnchorUtils.ts +58 -0
- package/src/primitives/thread/topAnchor/useTopAnchorReserve.ts +19 -0
- package/src/primitives/thread/useThreadViewportAutoScroll.ts +15 -1
- package/src/primitives/thread.ts +0 -1
- package/src/primitives/threadList/ThreadListLoadMore.tsx +24 -0
- package/src/primitives/threadList.ts +1 -0
- package/src/tests/BaseComposerRuntimeCore.test.ts +4 -0
- package/src/tests/RemoteThreadListRuntime.adapterProvider.test.tsx +138 -0
- package/src/tests/RemoteThreadListRuntime.deferredProvider.test.tsx +28 -17
- package/src/tests/auiV0Encode.test.ts +55 -0
- package/src/utils/hooks/useManagedRef.ts +1 -0
- package/src/utils/hooks/useOnResizeContent.ts +1 -2
- package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.d.ts +0 -3
- package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.d.ts.map +0 -1
- package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.js +0 -3
- package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.js.map +0 -1
- package/dist/primitives/thread/ThreadViewportSlack.d.ts +0 -20
- package/dist/primitives/thread/ThreadViewportSlack.d.ts.map +0 -1
- package/dist/primitives/thread/ThreadViewportSlack.js +0 -80
- package/dist/primitives/thread/ThreadViewportSlack.js.map +0 -1
- package/src/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.ts +0 -6
- package/src/primitives/thread/ThreadViewportSlack.tsx +0 -116
|
@@ -50,6 +50,13 @@ export type ExternalThreadQueueAdapter = {
|
|
|
50
50
|
export type ExternalThreadProps = {
|
|
51
51
|
messages: readonly ExternalThreadMessage[];
|
|
52
52
|
isRunning?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Whether sending new messages is currently disabled. When `true`, the
|
|
55
|
+
* thread composer's input remains usable but `send()` is a no-op and
|
|
56
|
+
* `composer.canSend` is `false`. Edit composers (saving message edits)
|
|
57
|
+
* intentionally ignore this flag.
|
|
58
|
+
*/
|
|
59
|
+
isSendDisabled?: boolean;
|
|
53
60
|
/**
|
|
54
61
|
* Callback for new messages (non-queue runtimes).
|
|
55
62
|
* @note Unused when `queue` is provided — new messages are routed through `queue.enqueue` instead.
|
|
@@ -146,7 +153,6 @@ const MessageClient = resource(
|
|
|
146
153
|
branchNumber: 1,
|
|
147
154
|
branchCount: 1,
|
|
148
155
|
speech: undefined,
|
|
149
|
-
submittedFeedback: undefined,
|
|
150
156
|
parts: partClients.state,
|
|
151
157
|
isCopied,
|
|
152
158
|
isHovering,
|
|
@@ -242,6 +248,7 @@ type ComposerClientResourceProps = {
|
|
|
242
248
|
type: "thread" | "edit";
|
|
243
249
|
isEditing: boolean;
|
|
244
250
|
canCancel: boolean;
|
|
251
|
+
isSendDisabled?: boolean;
|
|
245
252
|
onCancel: () => void;
|
|
246
253
|
onBeginEdit?: () => void;
|
|
247
254
|
onSend?: (message: AppendMessage) => void;
|
|
@@ -273,6 +280,7 @@ const ComposerClientResource = resource(
|
|
|
273
280
|
type,
|
|
274
281
|
isEditing,
|
|
275
282
|
canCancel,
|
|
283
|
+
isSendDisabled = false,
|
|
276
284
|
onCancel,
|
|
277
285
|
onBeginEdit,
|
|
278
286
|
onSend,
|
|
@@ -342,34 +350,36 @@ const ComposerClientResource = resource(
|
|
|
342
350
|
[queueItems],
|
|
343
351
|
);
|
|
344
352
|
|
|
345
|
-
const state = tapMemo(
|
|
346
|
-
()
|
|
353
|
+
const state = tapMemo(() => {
|
|
354
|
+
const isEmpty = !text.trim() && !attachments.length;
|
|
355
|
+
return {
|
|
347
356
|
text,
|
|
348
357
|
role,
|
|
349
358
|
attachments: attachmentClients.state,
|
|
350
359
|
runConfig,
|
|
351
360
|
isEditing,
|
|
352
361
|
canCancel,
|
|
362
|
+
canSend: isEditing && !isEmpty && !isSendDisabled,
|
|
353
363
|
attachmentAccept: "*",
|
|
354
|
-
isEmpty
|
|
364
|
+
isEmpty,
|
|
355
365
|
type,
|
|
356
366
|
dictation: undefined,
|
|
357
367
|
quote,
|
|
358
368
|
queue: queueItems,
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
);
|
|
369
|
+
};
|
|
370
|
+
}, [
|
|
371
|
+
text,
|
|
372
|
+
role,
|
|
373
|
+
attachmentClients.state,
|
|
374
|
+
runConfig,
|
|
375
|
+
isEditing,
|
|
376
|
+
canCancel,
|
|
377
|
+
isSendDisabled,
|
|
378
|
+
type,
|
|
379
|
+
attachments.length,
|
|
380
|
+
quote,
|
|
381
|
+
queueItems,
|
|
382
|
+
]);
|
|
373
383
|
|
|
374
384
|
return {
|
|
375
385
|
getState: () => state,
|
|
@@ -417,6 +427,8 @@ const ComposerClientResource = resource(
|
|
|
417
427
|
setQuote(undefined);
|
|
418
428
|
},
|
|
419
429
|
send: (opts?: ComposerSendOptions) => {
|
|
430
|
+
if (!state.canSend) return;
|
|
431
|
+
|
|
420
432
|
const currentQuote = quote;
|
|
421
433
|
const composedMessage: AppendMessage = {
|
|
422
434
|
role,
|
|
@@ -459,6 +471,7 @@ export const ExternalThread = resource(
|
|
|
459
471
|
({
|
|
460
472
|
messages,
|
|
461
473
|
isRunning = false,
|
|
474
|
+
isSendDisabled = false,
|
|
462
475
|
onNew,
|
|
463
476
|
onEdit,
|
|
464
477
|
onReload,
|
|
@@ -504,6 +517,7 @@ export const ExternalThread = resource(
|
|
|
504
517
|
type: "thread",
|
|
505
518
|
isEditing: true,
|
|
506
519
|
canCancel: isRunning,
|
|
520
|
+
isSendDisabled,
|
|
507
521
|
onCancel: handleCancelRun,
|
|
508
522
|
onSend: handleSendNew,
|
|
509
523
|
queue,
|
|
@@ -589,7 +603,6 @@ export const ExternalThread = resource(
|
|
|
589
603
|
onStartRun?.();
|
|
590
604
|
},
|
|
591
605
|
resumeRun: () => {},
|
|
592
|
-
unstable_resumeRun: () => {},
|
|
593
606
|
cancelRun: handleCancelRun,
|
|
594
607
|
getModelContext: () => ({ tools: {}, config: {} }),
|
|
595
608
|
export: () => ({ messages: [] }),
|
|
@@ -142,6 +142,8 @@ export const InMemoryThreadList = resource(
|
|
|
142
142
|
mainThreadId,
|
|
143
143
|
newThreadId: null,
|
|
144
144
|
isLoading: false,
|
|
145
|
+
isLoadingMore: false,
|
|
146
|
+
hasMore: false,
|
|
145
147
|
threadIds: regularThreads.map((t) => t.id),
|
|
146
148
|
archivedThreadIds: archivedThreads.map((t) => t.id),
|
|
147
149
|
threadItems: threadListItems.state,
|
|
@@ -155,6 +157,7 @@ export const InMemoryThreadList = resource(
|
|
|
155
157
|
switchToNewThread: handleSwitchToNewThread,
|
|
156
158
|
getLoadThreadsPromise: () => RESOLVED_PROMISE,
|
|
157
159
|
reload: () => RESOLVED_PROMISE,
|
|
160
|
+
loadMore: () => RESOLVED_PROMISE,
|
|
158
161
|
item: (selector) => {
|
|
159
162
|
if (selector === "main") {
|
|
160
163
|
const index = threads.findIndex((t) => t.id === mainThreadId);
|
|
@@ -47,6 +47,8 @@ export const SingleThreadList = resource(
|
|
|
47
47
|
mainThreadId: THREAD_ID,
|
|
48
48
|
newThreadId: null,
|
|
49
49
|
isLoading: false,
|
|
50
|
+
isLoadingMore: false,
|
|
51
|
+
hasMore: false,
|
|
50
52
|
threadIds: [THREAD_ID],
|
|
51
53
|
archivedThreadIds: [],
|
|
52
54
|
threadItems: [itemClient.state],
|
|
@@ -65,6 +67,7 @@ export const SingleThreadList = resource(
|
|
|
65
67
|
},
|
|
66
68
|
getLoadThreadsPromise: () => RESOLVED_PROMISE,
|
|
67
69
|
reload: () => RESOLVED_PROMISE,
|
|
70
|
+
loadMore: () => RESOLVED_PROMISE,
|
|
68
71
|
item: (selector) => {
|
|
69
72
|
if (
|
|
70
73
|
selector !== "main" &&
|
|
@@ -19,6 +19,8 @@ export type ThreadViewportProviderProps = PropsWithChildren<{
|
|
|
19
19
|
|
|
20
20
|
const useThreadViewportStoreValue = (options: ThreadViewportStoreOptions) => {
|
|
21
21
|
const outerViewport = useThreadViewportStore({ optional: true });
|
|
22
|
+
// Viewport options are initial configuration. Keeping them non-reactive avoids
|
|
23
|
+
// fanout through every message in long threads when anchoring config changes.
|
|
22
24
|
const [store] = useState(() => makeThreadViewportStore(options));
|
|
23
25
|
|
|
24
26
|
// Forward scrollToBottom from outer viewport to inner viewport
|
|
@@ -37,18 +39,6 @@ const useThreadViewportStoreValue = (options: ThreadViewportStoreOptions) => {
|
|
|
37
39
|
});
|
|
38
40
|
}, [store, outerViewport]);
|
|
39
41
|
|
|
40
|
-
// Sync options to store when they change
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
const nextState = {
|
|
43
|
-
turnAnchor: options.turnAnchor ?? "bottom",
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const currentState = store.getState();
|
|
47
|
-
if (currentState.turnAnchor !== nextState.turnAnchor) {
|
|
48
|
-
writableStore(store).setState(nextState);
|
|
49
|
-
}
|
|
50
|
-
}, [store, options.turnAnchor]);
|
|
51
|
-
|
|
52
42
|
return store;
|
|
53
43
|
};
|
|
54
44
|
|
|
@@ -60,28 +60,80 @@ export type ThreadViewportState = {
|
|
|
60
60
|
/** Controls scroll anchoring: "top" anchors user messages at top, "bottom" is classic behavior */
|
|
61
61
|
readonly turnAnchor: "top" | "bottom";
|
|
62
62
|
|
|
63
|
+
/** Clamps tall user messages so the assistant response stays in view. */
|
|
64
|
+
readonly topAnchorMessageClamp: {
|
|
65
|
+
readonly tallerThan: string;
|
|
66
|
+
readonly visibleHeight: string;
|
|
67
|
+
};
|
|
68
|
+
|
|
63
69
|
/** Raw height values from registered elements */
|
|
64
70
|
readonly height: {
|
|
65
71
|
/** Total viewport height */
|
|
66
72
|
readonly viewport: number;
|
|
67
73
|
/** Total content inset height (footer, anchor message, etc.) */
|
|
68
74
|
readonly inset: number;
|
|
69
|
-
/** Height of the anchor user message (full height) */
|
|
70
|
-
readonly userMessage: number;
|
|
71
75
|
};
|
|
72
76
|
|
|
77
|
+
/** Current DOM elements used for geometry-based top anchoring */
|
|
78
|
+
readonly element: {
|
|
79
|
+
readonly viewport: HTMLElement | null;
|
|
80
|
+
readonly anchor: HTMLElement | null;
|
|
81
|
+
readonly target: HTMLElement | null;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/** Numeric clamp configuration for the active top-anchor target message */
|
|
85
|
+
readonly targetConfig: {
|
|
86
|
+
readonly tallerThan: number;
|
|
87
|
+
readonly visibleHeight: number;
|
|
88
|
+
} | null;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The current top-anchor turn activated in this viewport session.
|
|
92
|
+
* History-loaded messages do not populate this; it is set when a run creates
|
|
93
|
+
* a live user/assistant pair and remains after the run completes.
|
|
94
|
+
*/
|
|
95
|
+
readonly topAnchorTurn: {
|
|
96
|
+
readonly anchorId: string;
|
|
97
|
+
readonly targetId: string;
|
|
98
|
+
} | null;
|
|
99
|
+
|
|
73
100
|
/** Register a viewport and get a handle to update its height */
|
|
74
101
|
readonly registerViewport: () => SizeHandle;
|
|
75
102
|
|
|
76
103
|
/** Register a content inset (footer, anchor message, etc.) and get a handle to update its height */
|
|
77
104
|
readonly registerContentInset: () => SizeHandle;
|
|
78
105
|
|
|
79
|
-
/** Register the
|
|
80
|
-
readonly
|
|
106
|
+
/** Register the scroll viewport element */
|
|
107
|
+
readonly registerViewportElement: (
|
|
108
|
+
element: HTMLElement | null,
|
|
109
|
+
) => Unsubscribe;
|
|
110
|
+
|
|
111
|
+
/** Register the current anchor user message element */
|
|
112
|
+
readonly registerAnchorElement: (element: HTMLElement | null) => Unsubscribe;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Register the current top-anchor target (last assistant response) element
|
|
116
|
+
* along with its numeric clamp configuration. When unregistered, both
|
|
117
|
+
* `element.target` and `targetConfig` clear together.
|
|
118
|
+
*/
|
|
119
|
+
readonly registerAnchorTargetElement: (
|
|
120
|
+
element: HTMLElement | null,
|
|
121
|
+
config?: { readonly tallerThan: number; readonly visibleHeight: number },
|
|
122
|
+
) => Unsubscribe;
|
|
123
|
+
|
|
124
|
+
readonly setTopAnchorTurn: (
|
|
125
|
+
turn: { readonly anchorId: string; readonly targetId: string } | null,
|
|
126
|
+
) => void;
|
|
81
127
|
};
|
|
82
128
|
|
|
83
129
|
export type ThreadViewportStoreOptions = {
|
|
84
130
|
turnAnchor?: "top" | "bottom" | undefined;
|
|
131
|
+
topAnchorMessageClamp?:
|
|
132
|
+
| {
|
|
133
|
+
tallerThan?: string | undefined;
|
|
134
|
+
visibleHeight?: string | undefined;
|
|
135
|
+
}
|
|
136
|
+
| undefined;
|
|
85
137
|
};
|
|
86
138
|
|
|
87
139
|
export const makeThreadViewportStore = (
|
|
@@ -107,14 +159,27 @@ export const makeThreadViewportStore = (
|
|
|
107
159
|
},
|
|
108
160
|
});
|
|
109
161
|
});
|
|
110
|
-
const
|
|
162
|
+
const registerElementSlot = (
|
|
163
|
+
key: "viewport" | "anchor",
|
|
164
|
+
element: HTMLElement | null,
|
|
165
|
+
) => {
|
|
111
166
|
store.setState({
|
|
112
|
-
|
|
113
|
-
...store.getState().
|
|
114
|
-
|
|
167
|
+
element: {
|
|
168
|
+
...store.getState().element,
|
|
169
|
+
[key]: element,
|
|
115
170
|
},
|
|
116
171
|
});
|
|
117
|
-
|
|
172
|
+
|
|
173
|
+
return () => {
|
|
174
|
+
if (store.getState().element[key] !== element) return;
|
|
175
|
+
store.setState({
|
|
176
|
+
element: {
|
|
177
|
+
...store.getState().element,
|
|
178
|
+
[key]: null,
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
};
|
|
118
183
|
|
|
119
184
|
const store = create<ThreadViewportState>(() => ({
|
|
120
185
|
isAtBottom: true,
|
|
@@ -131,16 +196,51 @@ export const makeThreadViewportStore = (
|
|
|
131
196
|
},
|
|
132
197
|
|
|
133
198
|
turnAnchor: options.turnAnchor ?? "bottom",
|
|
199
|
+
topAnchorMessageClamp: {
|
|
200
|
+
tallerThan: options.topAnchorMessageClamp?.tallerThan ?? "10em",
|
|
201
|
+
visibleHeight: options.topAnchorMessageClamp?.visibleHeight ?? "6em",
|
|
202
|
+
},
|
|
134
203
|
|
|
135
204
|
height: {
|
|
136
205
|
viewport: 0,
|
|
137
206
|
inset: 0,
|
|
138
|
-
userMessage: 0,
|
|
139
207
|
},
|
|
208
|
+
element: {
|
|
209
|
+
viewport: null,
|
|
210
|
+
anchor: null,
|
|
211
|
+
target: null,
|
|
212
|
+
},
|
|
213
|
+
targetConfig: null,
|
|
214
|
+
topAnchorTurn: null,
|
|
140
215
|
|
|
141
216
|
registerViewport: viewportRegistry.register,
|
|
142
217
|
registerContentInset: insetRegistry.register,
|
|
143
|
-
|
|
218
|
+
registerViewportElement: (element) =>
|
|
219
|
+
registerElementSlot("viewport", element),
|
|
220
|
+
registerAnchorElement: (element) => registerElementSlot("anchor", element),
|
|
221
|
+
registerAnchorTargetElement: (element, config) => {
|
|
222
|
+
store.setState({
|
|
223
|
+
element: {
|
|
224
|
+
...store.getState().element,
|
|
225
|
+
target: element,
|
|
226
|
+
},
|
|
227
|
+
targetConfig: element && config ? config : null,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
return () => {
|
|
231
|
+
if (store.getState().element.target !== element) return;
|
|
232
|
+
store.setState({
|
|
233
|
+
element: {
|
|
234
|
+
...store.getState().element,
|
|
235
|
+
target: null,
|
|
236
|
+
},
|
|
237
|
+
targetConfig: null,
|
|
238
|
+
});
|
|
239
|
+
};
|
|
240
|
+
},
|
|
241
|
+
setTopAnchorTurn: (topAnchorTurn) => {
|
|
242
|
+
store.setState({ topAnchorTurn });
|
|
243
|
+
},
|
|
144
244
|
}));
|
|
145
245
|
|
|
146
246
|
return store;
|
package/src/index.ts
CHANGED
|
@@ -125,7 +125,6 @@ export type {
|
|
|
125
125
|
// --- external-store ---
|
|
126
126
|
export type { ThreadMessageLike } from "@assistant-ui/core";
|
|
127
127
|
export {
|
|
128
|
-
getExternalStoreMessage,
|
|
129
128
|
getExternalStoreMessages,
|
|
130
129
|
bindExternalStoreMessage,
|
|
131
130
|
} from "@assistant-ui/core";
|
|
@@ -151,25 +150,13 @@ export type {
|
|
|
151
150
|
LocalRuntimeOptionsBase,
|
|
152
151
|
} from "@assistant-ui/core";
|
|
153
152
|
export { useLocalRuntime } from "./legacy-runtime/runtime-cores/local/useLocalRuntime";
|
|
154
|
-
/**
|
|
155
|
-
* @deprecated Use `useLocalRuntime` instead.
|
|
156
|
-
*/
|
|
157
|
-
export { useLocalRuntime as useLocalThreadRuntime } from "./legacy-runtime/runtime-cores/local/useLocalRuntime";
|
|
158
153
|
export type { LocalRuntimeOptions } from "./legacy-runtime/runtime-cores/local/LocalRuntimeOptions";
|
|
159
154
|
|
|
160
155
|
// --- remote-thread-list ---
|
|
161
156
|
export { useRemoteThreadListRuntime } from "./legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime";
|
|
162
|
-
/** @deprecated Use `useRemoteThreadListRuntime` instead. */
|
|
163
|
-
export { useRemoteThreadListRuntime as unstable_useRemoteThreadListRuntime } from "./legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime";
|
|
164
157
|
export { useCloudThreadListAdapter } from "./legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud";
|
|
165
|
-
/** @deprecated Use `useCloudThreadListAdapter` instead. */
|
|
166
|
-
export { useCloudThreadListAdapter as unstable_useCloudThreadListAdapter } from "./legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud";
|
|
167
158
|
export type { RemoteThreadListAdapter } from "@assistant-ui/core";
|
|
168
|
-
/** @deprecated Use `RemoteThreadListAdapter` instead. */
|
|
169
|
-
export type { RemoteThreadListAdapter as unstable_RemoteThreadListAdapter } from "@assistant-ui/core";
|
|
170
159
|
export { InMemoryThreadListAdapter } from "@assistant-ui/core";
|
|
171
|
-
/** @deprecated Use `InMemoryThreadListAdapter` instead. */
|
|
172
|
-
export { InMemoryThreadListAdapter as unstable_InMemoryThreadListAdapter } from "@assistant-ui/core";
|
|
173
160
|
|
|
174
161
|
// Re-export from @assistant-ui/core (runtime-cores root)
|
|
175
162
|
export type { ExportedMessageRepositoryItem } from "@assistant-ui/core";
|
|
@@ -287,12 +274,14 @@ export type {
|
|
|
287
274
|
AppendMessage,
|
|
288
275
|
TextMessagePart,
|
|
289
276
|
ReasoningMessagePart,
|
|
277
|
+
SourceProviderMetadata,
|
|
290
278
|
SourceMessagePart,
|
|
291
279
|
ImageMessagePart,
|
|
292
280
|
FileMessagePart,
|
|
293
281
|
DataMessagePart,
|
|
294
282
|
Unstable_AudioMessagePart,
|
|
295
283
|
ToolCallMessagePart,
|
|
284
|
+
ToolModelContentPart,
|
|
296
285
|
MessageStatus,
|
|
297
286
|
MessagePartStatus,
|
|
298
287
|
ToolCallMessagePartStatus,
|
|
@@ -392,24 +381,21 @@ export {
|
|
|
392
381
|
|
|
393
382
|
export type { Assistant } from "./augmentations";
|
|
394
383
|
|
|
395
|
-
//
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
* @deprecated Use `AuiIf` instead. This alias will be removed in v0.13.
|
|
414
|
-
*/
|
|
415
|
-
export { AuiIf as AssistantIf } from "@assistant-ui/store";
|
|
384
|
+
// --- mcp-apps ---
|
|
385
|
+
export { McpAppRenderer, McpAppsRemoteHost } from "./mcp-apps";
|
|
386
|
+
export type {
|
|
387
|
+
McpAppRendererOptions,
|
|
388
|
+
McpAppMetadata,
|
|
389
|
+
McpAppResource,
|
|
390
|
+
McpAppResourceMeta,
|
|
391
|
+
McpAppResourceCSP,
|
|
392
|
+
McpAppSandboxConfig,
|
|
393
|
+
McpAppHostInfo,
|
|
394
|
+
McpAppHostContext,
|
|
395
|
+
McpAppDisplayMode,
|
|
396
|
+
McpAppsHost,
|
|
397
|
+
McpAppsRemoteHostOptions,
|
|
398
|
+
McpAppToolCallParams,
|
|
399
|
+
ToolCallMessagePartMcpMetadata,
|
|
400
|
+
} from "./mcp-apps";
|
|
401
|
+
export type { McpAppResourceOutput } from "@assistant-ui/core/react";
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
MessageStatus,
|
|
3
|
+
SourceProviderMetadata,
|
|
4
|
+
ThreadMessage,
|
|
5
|
+
} from "@assistant-ui/core";
|
|
2
6
|
import { fromThreadMessageLike } from "../runtime-cores/external-store/ThreadMessageLike";
|
|
3
7
|
import type { CloudMessage } from "assistant-cloud";
|
|
4
8
|
import { isJSONValue } from "../../utils/json/is-json";
|
|
@@ -23,6 +27,16 @@ type AuiV0MessagePart =
|
|
|
23
27
|
readonly id: string;
|
|
24
28
|
readonly url: string;
|
|
25
29
|
readonly title?: string;
|
|
30
|
+
readonly providerMetadata?: SourceProviderMetadata;
|
|
31
|
+
}
|
|
32
|
+
| {
|
|
33
|
+
readonly type: "source";
|
|
34
|
+
readonly sourceType: "document";
|
|
35
|
+
readonly id: string;
|
|
36
|
+
readonly title: string;
|
|
37
|
+
readonly mediaType: string;
|
|
38
|
+
readonly filename?: string;
|
|
39
|
+
readonly providerMetadata?: SourceProviderMetadata;
|
|
26
40
|
}
|
|
27
41
|
| {
|
|
28
42
|
readonly type: "tool-call";
|
|
@@ -90,12 +104,31 @@ export function auiV0Encode(message: ThreadMessage): AuiV0Message {
|
|
|
90
104
|
return { type: "reasoning", text: part.text };
|
|
91
105
|
|
|
92
106
|
case "source":
|
|
107
|
+
if (part.sourceType === "url") {
|
|
108
|
+
return {
|
|
109
|
+
type: "source",
|
|
110
|
+
sourceType: "url",
|
|
111
|
+
id: part.id,
|
|
112
|
+
url: part.url,
|
|
113
|
+
...(part.title != null ? { title: part.title } : undefined),
|
|
114
|
+
...(part.providerMetadata != null
|
|
115
|
+
? { providerMetadata: part.providerMetadata }
|
|
116
|
+
: undefined),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
93
120
|
return {
|
|
94
121
|
type: "source",
|
|
95
|
-
sourceType:
|
|
122
|
+
sourceType: "document",
|
|
96
123
|
id: part.id,
|
|
97
|
-
|
|
98
|
-
|
|
124
|
+
title: part.title,
|
|
125
|
+
mediaType: part.mediaType,
|
|
126
|
+
...(part.filename != null
|
|
127
|
+
? { filename: part.filename }
|
|
128
|
+
: undefined),
|
|
129
|
+
...(part.providerMetadata != null
|
|
130
|
+
? { providerMetadata: part.providerMetadata }
|
|
131
|
+
: undefined),
|
|
99
132
|
};
|
|
100
133
|
|
|
101
134
|
case "tool-call": {
|