@assistant-ui/react 0.11.37 → 0.11.38

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.
Files changed (27) hide show
  1. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  2. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.js +34 -1
  3. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  4. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.d.ts.map +1 -1
  5. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.js +9 -0
  6. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.js.map +1 -1
  7. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.d.ts +2 -1
  8. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.d.ts.map +1 -1
  9. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.js +3 -0
  10. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.js.map +1 -1
  11. package/dist/legacy-runtime/runtime-cores/remote-thread-list/types.d.ts +1 -0
  12. package/dist/legacy-runtime/runtime-cores/remote-thread-list/types.d.ts.map +1 -1
  13. package/dist/primitives/assistantModal/scope.d.ts +2 -3
  14. package/dist/primitives/assistantModal/scope.d.ts.map +1 -1
  15. package/dist/primitives/assistantModal/scope.js.map +1 -1
  16. package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
  17. package/dist/primitives/thread/useThreadViewportAutoScroll.js +11 -12
  18. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  19. package/dist/tests/setup.js +287 -125
  20. package/dist/tests/setup.js.map +1 -1
  21. package/package.json +8 -8
  22. package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.tsx +49 -2
  23. package/src/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.tsx +10 -0
  24. package/src/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.tsx +5 -0
  25. package/src/legacy-runtime/runtime-cores/remote-thread-list/types.tsx +1 -0
  26. package/src/primitives/assistantModal/scope.tsx +3 -1
  27. package/src/primitives/thread/useThreadViewportAutoScroll.tsx +14 -13
package/package.json CHANGED
@@ -28,7 +28,7 @@
28
28
  "conversational-ui",
29
29
  "conversational-ai"
30
30
  ],
31
- "version": "0.11.37",
31
+ "version": "0.11.38",
32
32
  "license": "MIT",
33
33
  "type": "module",
34
34
  "exports": {
@@ -48,14 +48,14 @@
48
48
  ],
49
49
  "sideEffects": false,
50
50
  "dependencies": {
51
- "assistant-cloud": "^0.1.6",
51
+ "assistant-cloud": "^0.1.7",
52
52
  "@assistant-ui/tap": "^0.1.5",
53
53
  "@radix-ui/primitive": "^1.1.3",
54
54
  "@radix-ui/react-compose-refs": "^1.1.2",
55
- "@radix-ui/react-context": "^1.1.2",
55
+ "@radix-ui/react-context": "^1.1.3",
56
56
  "@radix-ui/react-popover": "^1.1.15",
57
- "@radix-ui/react-primitive": "^2.1.3",
58
- "@radix-ui/react-slot": "^1.2.3",
57
+ "@radix-ui/react-primitive": "^2.1.4",
58
+ "@radix-ui/react-slot": "^1.2.4",
59
59
  "@radix-ui/react-use-callback-ref": "^1.1.1",
60
60
  "@radix-ui/react-use-escape-keydown": "^1.1.1",
61
61
  "@standard-schema/spec": "^1.0.0",
@@ -84,11 +84,11 @@
84
84
  "@stryker-mutator/core": "^9.3.0",
85
85
  "@stryker-mutator/vitest-runner": "^9.3.0",
86
86
  "@types/json-schema": "^7.0.15",
87
- "@types/node": "^24.10.0",
87
+ "@types/node": "^24.10.1",
88
88
  "eslint": "^9",
89
- "eslint-config-next": "16.0.1",
89
+ "eslint-config-next": "16.0.3",
90
90
  "tsx": "^4.20.6",
91
- "vitest": "^4.0.6",
91
+ "vitest": "^4.0.8",
92
92
  "@assistant-ui/x-buildutils": "0.0.1"
93
93
  },
94
94
  "publishConfig": {
@@ -308,9 +308,56 @@ export class RemoteThreadListThreadListRuntimeCore
308
308
  }
309
309
 
310
310
  public async switchToThread(threadIdOrRemoteId: string): Promise<void> {
311
- const data = this.getItemById(threadIdOrRemoteId);
312
- if (!data) throw new Error("Thread not found");
311
+ let data = this.getItemById(threadIdOrRemoteId);
312
+
313
+ if (!data) {
314
+ const remoteMetadata =
315
+ await this._options.adapter.fetch(threadIdOrRemoteId);
316
+ const state = this._state.value;
317
+ const mappingId = createThreadMappingId(remoteMetadata.remoteId);
318
+
319
+ const newThreadData = {
320
+ ...state.threadData,
321
+ [mappingId]: {
322
+ id: mappingId,
323
+ initializeTask: Promise.resolve({
324
+ remoteId: remoteMetadata.remoteId,
325
+ externalId: remoteMetadata.externalId,
326
+ }),
327
+ remoteId: remoteMetadata.remoteId,
328
+ externalId: remoteMetadata.externalId,
329
+ status: remoteMetadata.status,
330
+ title: remoteMetadata.title,
331
+ } as RemoteThreadData,
332
+ };
333
+
334
+ const newThreadIdMap = {
335
+ ...state.threadIdMap,
336
+ [remoteMetadata.remoteId]: mappingId,
337
+ };
338
+
339
+ const newThreadIds =
340
+ remoteMetadata.status === "regular"
341
+ ? [...state.threadIds, remoteMetadata.remoteId]
342
+ : state.threadIds;
343
+
344
+ const newArchivedThreadIds =
345
+ remoteMetadata.status === "archived"
346
+ ? [...state.archivedThreadIds, remoteMetadata.remoteId]
347
+ : state.archivedThreadIds;
313
348
 
349
+ this._state.update({
350
+ ...state,
351
+ threadIds: newThreadIds,
352
+ archivedThreadIds: newArchivedThreadIds,
353
+ threadIdMap: newThreadIdMap,
354
+ threadData: newThreadData,
355
+ });
356
+
357
+ data = this.getItemById(threadIdOrRemoteId);
358
+ }
359
+
360
+ if (!data) throw new Error("Thread not found");
314
361
  if (this._mainThreadId === data.id) return;
315
362
 
316
363
  const task = this._hookManager.startThreadRuntime(data.id);
@@ -121,6 +121,16 @@ export const useCloudThreadListAdapter = (
121
121
  });
122
122
  },
123
123
 
124
+ fetch: async (threadId: string) => {
125
+ const thread = await cloud.threads.get(threadId);
126
+ return {
127
+ status: thread.is_archived ? "archived" : "regular",
128
+ remoteId: thread.id,
129
+ title: thread.title,
130
+ externalId: thread.external_id ?? undefined,
131
+ };
132
+ },
133
+
124
134
  unstable_Provider,
125
135
  };
126
136
  };
@@ -3,6 +3,7 @@ import {
3
3
  RemoteThreadInitializeResponse,
4
4
  RemoteThreadListAdapter,
5
5
  RemoteThreadListResponse,
6
+ RemoteThreadMetadata,
6
7
  } from "../types";
7
8
 
8
9
  export class InMemoryThreadListAdapter implements RemoteThreadListAdapter {
@@ -35,4 +36,8 @@ export class InMemoryThreadListAdapter implements RemoteThreadListAdapter {
35
36
  generateTitle(): Promise<AssistantStream> {
36
37
  return Promise.resolve(new ReadableStream<AssistantStreamChunk>());
37
38
  }
39
+
40
+ fetch(_threadId: string): Promise<RemoteThreadMetadata> {
41
+ return Promise.reject(new Error("Thread not found"));
42
+ }
38
43
  }
@@ -31,6 +31,7 @@ export type RemoteThreadListAdapter = {
31
31
  remoteId: string,
32
32
  unstable_messages: readonly ThreadMessage[],
33
33
  ): Promise<AssistantStream>;
34
+ fetch(threadId: string): Promise<RemoteThreadMetadata>;
34
35
 
35
36
  unstable_Provider?: ComponentType<PropsWithChildren>;
36
37
  };
@@ -1,5 +1,7 @@
1
1
  import * as PopoverPrimitive from "@radix-ui/react-popover";
2
2
  import type { Scope } from "@radix-ui/react-context";
3
3
 
4
- export const usePopoverScope = PopoverPrimitive.createPopoverScope();
4
+ export const usePopoverScope: ReturnType<
5
+ typeof PopoverPrimitive.createPopoverScope
6
+ > = PopoverPrimitive.createPopoverScope();
5
7
  export type ScopedProps<P> = P & { __scopeAssistantModal?: Scope };
@@ -28,16 +28,13 @@ export const useThreadViewportAutoScroll = <TElement extends HTMLElement>({
28
28
  // fix: delay the state change until the scroll is done
29
29
  const isScrollingToBottomRef = useRef(false);
30
30
 
31
- const scrollToBottom = useCallback(
32
- (behavior: ScrollBehavior) => {
33
- const div = divRef.current;
34
- if (!div || !autoScroll) return;
31
+ const scrollToBottom = useCallback((behavior: ScrollBehavior) => {
32
+ const div = divRef.current;
33
+ if (!div) return;
35
34
 
36
- isScrollingToBottomRef.current = true;
37
- div.scrollTo({ top: div.scrollHeight, behavior });
38
- },
39
- [autoScroll],
40
- );
35
+ isScrollingToBottomRef.current = true;
36
+ div.scrollTo({ top: div.scrollHeight, behavior });
37
+ }, []);
41
38
 
42
39
  const handleScroll = () => {
43
40
  const div = divRef.current;
@@ -45,7 +42,8 @@ export const useThreadViewportAutoScroll = <TElement extends HTMLElement>({
45
42
 
46
43
  const isAtBottom = threadViewportStore.getState().isAtBottom;
47
44
  const newIsAtBottom =
48
- div.scrollHeight - div.scrollTop <= div.clientHeight + 1; // TODO figure out why +1 is needed
45
+ Math.abs(div.scrollHeight - div.scrollTop - div.clientHeight) < 1 ||
46
+ div.scrollHeight <= div.clientHeight;
49
47
 
50
48
  if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
51
49
  // ignore scroll down
@@ -66,8 +64,9 @@ export const useThreadViewportAutoScroll = <TElement extends HTMLElement>({
66
64
 
67
65
  const resizeRef = useOnResizeContent(() => {
68
66
  if (
69
- isScrollingToBottomRef.current ||
70
- threadViewportStore.getState().isAtBottom
67
+ autoScroll &&
68
+ (isScrollingToBottomRef.current ||
69
+ threadViewportStore.getState().isAtBottom)
71
70
  ) {
72
71
  scrollToBottom("instant");
73
72
  }
@@ -87,7 +86,9 @@ export const useThreadViewportAutoScroll = <TElement extends HTMLElement>({
87
86
  });
88
87
 
89
88
  // autoscroll on run start
90
- useAssistantEvent("thread.run-start", () => scrollToBottom("auto"));
89
+ useAssistantEvent("thread.run-start", () => {
90
+ if (autoScroll) scrollToBottom("auto");
91
+ });
91
92
 
92
93
  const autoScrollRef = useComposedRefs<TElement>(resizeRef, scrollRef, divRef);
93
94
  return autoScrollRef as RefCallback<TElement>;