@assistant-ui/react 0.12.27 → 0.14.0

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 (140) hide show
  1. package/dist/client/ExternalThread.d.ts.map +1 -1
  2. package/dist/client/ExternalThread.js +0 -2
  3. package/dist/client/ExternalThread.js.map +1 -1
  4. package/dist/client/InMemoryThreadList.d.ts.map +1 -1
  5. package/dist/client/InMemoryThreadList.js +3 -0
  6. package/dist/client/InMemoryThreadList.js.map +1 -1
  7. package/dist/client/SingleThreadList.d.ts.map +1 -1
  8. package/dist/client/SingleThreadList.js +3 -0
  9. package/dist/client/SingleThreadList.js.map +1 -1
  10. package/dist/context/providers/ThreadViewportProvider.d.ts.map +1 -1
  11. package/dist/context/providers/ThreadViewportProvider.js +2 -10
  12. package/dist/context/providers/ThreadViewportProvider.js.map +1 -1
  13. package/dist/context/stores/ThreadViewport.d.ts +46 -4
  14. package/dist/context/stores/ThreadViewport.d.ts.map +1 -1
  15. package/dist/context/stores/ThreadViewport.js +51 -7
  16. package/dist/context/stores/ThreadViewport.js.map +1 -1
  17. package/dist/index.d.ts +2 -30
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +1 -28
  20. package/dist/index.js.map +1 -1
  21. package/dist/legacy-runtime/runtime-cores/assistant-transport/utils.d.ts +1 -1
  22. package/dist/legacy-runtime/runtime-cores/assistant-transport/utils.d.ts.map +1 -1
  23. package/dist/legacy-runtime/runtime-cores/assistant-transport/utils.js +1 -1
  24. package/dist/legacy-runtime/runtime-cores/assistant-transport/utils.js.map +1 -1
  25. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  26. package/dist/primitives/composer/ComposerInput.js +9 -4
  27. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  28. package/dist/primitives/message/MessagePartsGrouped.d.ts +6 -21
  29. package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
  30. package/dist/primitives/message/MessagePartsGrouped.js +6 -21
  31. package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
  32. package/dist/primitives/message/MessageRoot.d.ts +6 -30
  33. package/dist/primitives/message/MessageRoot.d.ts.map +1 -1
  34. package/dist/primitives/message/MessageRoot.js +68 -25
  35. package/dist/primitives/message/MessageRoot.js.map +1 -1
  36. package/dist/primitives/message.d.ts +1 -0
  37. package/dist/primitives/message.d.ts.map +1 -1
  38. package/dist/primitives/message.js +1 -0
  39. package/dist/primitives/message.js.map +1 -1
  40. package/dist/primitives/thread/ThreadViewport.d.ts +38 -0
  41. package/dist/primitives/thread/ThreadViewport.d.ts.map +1 -1
  42. package/dist/primitives/thread/ThreadViewport.js +53 -5
  43. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  44. package/dist/primitives/thread/ThreadViewportFooter.d.ts +2 -1
  45. package/dist/primitives/thread/ThreadViewportFooter.d.ts.map +1 -1
  46. package/dist/primitives/thread/ThreadViewportFooter.js +2 -1
  47. package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -1
  48. package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.d.ts +22 -0
  49. package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.d.ts.map +1 -0
  50. package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.js +53 -0
  51. package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.js.map +1 -0
  52. package/dist/primitives/thread/topAnchor/createReserveObservers.d.ts +5 -0
  53. package/dist/primitives/thread/topAnchor/createReserveObservers.d.ts.map +1 -0
  54. package/dist/primitives/thread/topAnchor/createReserveObservers.js +38 -0
  55. package/dist/primitives/thread/topAnchor/createReserveObservers.js.map +1 -0
  56. package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.d.ts +22 -0
  57. package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.d.ts.map +1 -0
  58. package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.js +75 -0
  59. package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.js.map +1 -0
  60. package/dist/primitives/thread/topAnchor/topAnchorTurn.d.ts +15 -0
  61. package/dist/primitives/thread/topAnchor/topAnchorTurn.d.ts.map +1 -0
  62. package/dist/primitives/thread/topAnchor/topAnchorTurn.js +13 -0
  63. package/dist/primitives/thread/topAnchor/topAnchorTurn.js.map +1 -0
  64. package/dist/primitives/thread/topAnchor/topAnchorUtils.d.ts +15 -0
  65. package/dist/primitives/thread/topAnchor/topAnchorUtils.d.ts.map +1 -0
  66. package/dist/primitives/thread/topAnchor/topAnchorUtils.js +51 -0
  67. package/dist/primitives/thread/topAnchor/topAnchorUtils.js.map +1 -0
  68. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.d.ts +7 -0
  69. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.d.ts.map +1 -0
  70. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js +18 -0
  71. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js.map +1 -0
  72. package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
  73. package/dist/primitives/thread/useThreadViewportAutoScroll.js +13 -1
  74. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  75. package/dist/primitives/thread.d.ts +0 -1
  76. package/dist/primitives/thread.d.ts.map +1 -1
  77. package/dist/primitives/thread.js +0 -1
  78. package/dist/primitives/thread.js.map +1 -1
  79. package/dist/primitives/threadList/ThreadListLoadMore.d.ts +13 -0
  80. package/dist/primitives/threadList/ThreadListLoadMore.d.ts.map +1 -0
  81. package/dist/primitives/threadList/ThreadListLoadMore.js +11 -0
  82. package/dist/primitives/threadList/ThreadListLoadMore.js.map +1 -0
  83. package/dist/primitives/threadList.d.ts +1 -0
  84. package/dist/primitives/threadList.d.ts.map +1 -1
  85. package/dist/primitives/threadList.js +1 -0
  86. package/dist/primitives/threadList.js.map +1 -1
  87. package/dist/tests/remote-thread-list-test-helpers.d.ts +3 -0
  88. package/dist/tests/remote-thread-list-test-helpers.d.ts.map +1 -0
  89. package/dist/tests/remote-thread-list-test-helpers.js +27 -0
  90. package/dist/tests/remote-thread-list-test-helpers.js.map +1 -0
  91. package/dist/utils/hooks/useManagedRef.d.ts.map +1 -1
  92. package/dist/utils/hooks/useManagedRef.js +1 -0
  93. package/dist/utils/hooks/useManagedRef.js.map +1 -1
  94. package/dist/utils/hooks/useOnResizeContent.d.ts.map +1 -1
  95. package/dist/utils/hooks/useOnResizeContent.js +1 -2
  96. package/dist/utils/hooks/useOnResizeContent.js.map +1 -1
  97. package/package.json +10 -10
  98. package/src/client/ExternalThread.ts +0 -2
  99. package/src/client/InMemoryThreadList.ts +3 -0
  100. package/src/client/SingleThreadList.ts +3 -0
  101. package/src/context/providers/ThreadViewportProvider.tsx +2 -12
  102. package/src/context/stores/ThreadViewport.ts +111 -11
  103. package/src/index.ts +2 -35
  104. package/src/legacy-runtime/runtime-cores/assistant-transport/utils.ts +1 -5
  105. package/src/primitives/composer/ComposerInput.test.tsx +232 -0
  106. package/src/primitives/composer/ComposerInput.tsx +9 -4
  107. package/src/primitives/message/MessagePartsGrouped.tsx +6 -21
  108. package/src/primitives/message/MessageRoot.tsx +135 -57
  109. package/src/primitives/message.ts +1 -0
  110. package/src/primitives/thread/ThreadViewport.tsx +95 -4
  111. package/src/primitives/thread/ThreadViewportFooter.tsx +2 -1
  112. package/src/primitives/thread/topAnchor/computeTopAnchorSlack.test.ts +131 -0
  113. package/src/primitives/thread/topAnchor/computeTopAnchorSlack.ts +94 -0
  114. package/src/primitives/thread/topAnchor/createReserveObservers.ts +50 -0
  115. package/src/primitives/thread/topAnchor/mountTopAnchorReserve.test.ts +131 -0
  116. package/src/primitives/thread/topAnchor/mountTopAnchorReserve.ts +127 -0
  117. package/src/primitives/thread/topAnchor/topAnchorTurn.test.ts +46 -0
  118. package/src/primitives/thread/topAnchor/topAnchorTurn.ts +30 -0
  119. package/src/primitives/thread/topAnchor/topAnchorUtils.ts +58 -0
  120. package/src/primitives/thread/topAnchor/useTopAnchorReserve.ts +19 -0
  121. package/src/primitives/thread/useThreadViewportAutoScroll.ts +15 -1
  122. package/src/primitives/thread.ts +0 -1
  123. package/src/primitives/threadList/ThreadListLoadMore.tsx +24 -0
  124. package/src/primitives/threadList.ts +1 -0
  125. package/src/tests/BaseComposerRuntimeCore.test.ts +9 -0
  126. package/src/tests/RemoteThreadListRuntime.adapterProvider.test.tsx +138 -0
  127. package/src/tests/RemoteThreadListRuntime.deferredProvider.test.tsx +29 -18
  128. package/src/tests/remote-thread-list-test-helpers.ts +33 -0
  129. package/src/utils/hooks/useManagedRef.ts +1 -0
  130. package/src/utils/hooks/useOnResizeContent.ts +1 -2
  131. package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.d.ts +0 -3
  132. package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.d.ts.map +0 -1
  133. package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.js +0 -3
  134. package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.js.map +0 -1
  135. package/dist/primitives/thread/ThreadViewportSlack.d.ts +0 -20
  136. package/dist/primitives/thread/ThreadViewportSlack.d.ts.map +0 -1
  137. package/dist/primitives/thread/ThreadViewportSlack.js +0 -80
  138. package/dist/primitives/thread/ThreadViewportSlack.js.map +0 -1
  139. package/src/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.ts +0 -6
  140. package/src/primitives/thread/ThreadViewportSlack.tsx +0 -116
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadViewportFooter.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewportFooter.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,iCAA8B;AAClD,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,wBAAwB,EAE9B,MAAM,OAAO,CAAC;AAIf,yBAAiB,6BAA6B,CAAC;IAC7C,KAAY,OAAO,GAAG,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACzD,KAAY,KAAK,GAAG,wBAAwB,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;CACpE;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,6BAA6B;;;;0GAexC,CAAC"}
1
+ {"version":3,"file":"ThreadViewportFooter.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewportFooter.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,iCAA8B;AAClD,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,wBAAwB,EAE9B,MAAM,OAAO,CAAC;AAIf,yBAAiB,6BAA6B,CAAC;IAC7C,KAAY,OAAO,GAAG,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACzD,KAAY,KAAK,GAAG,wBAAwB,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;CACpE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,6BAA6B;;;;0GAexC,CAAC"}
@@ -9,7 +9,8 @@ import { useThreadViewport } from "../../context/react/ThreadViewportContext.js"
9
9
  * A footer container that measures its height for scroll calculations.
10
10
  *
11
11
  * This component measures its height and provides it to the viewport context
12
- * for use in scroll calculations (e.g., ViewportSlack min-height).
12
+ * so the auto-scroll system can account for any sticky footer overlapping the
13
+ * message list.
13
14
  *
14
15
  * Multiple ViewportFooter components can be used - their heights are summed.
15
16
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadViewportFooter.js","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewportFooter.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,iCAA8B;AAClD,OAAO,EAEL,UAAU,EAEV,WAAW,GACZ,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,aAAa,EAAE,2CAAwC;AAChE,OAAO,EAAE,iBAAiB,EAAE,qDAAkD;AAO9E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,UAAU,CAGrD,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;IACxB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,EAAe,EAAE,EAAE;QAChD,MAAM,SAAS,GAAG,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAClE,OAAO,EAAE,CAAC,YAAY,GAAG,SAAS,CAAC;IACrC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAErD,MAAM,GAAG,GAAG,eAAe,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAErD,OAAO,KAAC,SAAS,CAAC,GAAG,OAAK,KAAK,EAAE,GAAG,EAAE,GAAG,GAAI,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,6BAA6B,CAAC,WAAW,GAAG,gCAAgC,CAAC"}
1
+ {"version":3,"file":"ThreadViewportFooter.js","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewportFooter.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,iCAA8B;AAClD,OAAO,EAEL,UAAU,EAEV,WAAW,GACZ,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,aAAa,EAAE,2CAAwC;AAChE,OAAO,EAAE,iBAAiB,EAAE,qDAAkD;AAO9E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,UAAU,CAGrD,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;IACxB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,EAAe,EAAE,EAAE;QAChD,MAAM,SAAS,GAAG,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAClE,OAAO,EAAE,CAAC,YAAY,GAAG,SAAS,CAAC;IACrC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAErD,MAAM,GAAG,GAAG,eAAe,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAErD,OAAO,KAAC,SAAS,CAAC,GAAG,OAAK,KAAK,EAAE,GAAG,EAAE,GAAG,GAAI,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,6BAA6B,CAAC,WAAW,GAAG,gCAAgC,CAAC"}
@@ -0,0 +1,22 @@
1
+ export type ComputeTopAnchorTargetOptions = {
2
+ viewport: HTMLElement;
3
+ anchor: HTMLElement;
4
+ tallerThan: number;
5
+ visibleHeight: number;
6
+ };
7
+ export type ComputeTopAnchorReserveOptions = ComputeTopAnchorTargetOptions & {
8
+ reserve: HTMLElement;
9
+ };
10
+ /**
11
+ * Compute the scroll position that pins the anchor (last user message) to the
12
+ * top of the viewport. For tall user messages the anchor is intentionally
13
+ * over-scrolled so only `visibleHeight` of it remains visible, leaving room
14
+ * for the assistant message below.
15
+ *
16
+ * Depends only on the anchor's offset within the scroll content; never reads
17
+ * `viewport.scrollHeight` (which is volatile while the assistant message
18
+ * streams in).
19
+ */
20
+ export declare const computeTopAnchorTargetScrollTop: ({ viewport, anchor, tallerThan, visibleHeight, }: ComputeTopAnchorTargetOptions) => number;
21
+ export declare const computeTopAnchorReserve: ({ viewport, reserve, ...targetOptions }: ComputeTopAnchorReserveOptions) => number;
22
+ //# sourceMappingURL=computeTopAnchorSlack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computeTopAnchorSlack.d.ts","sourceRoot":"","sources":["../../../../src/primitives/thread/topAnchor/computeTopAnchorSlack.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,6BAA6B,GAAG;IAC1C,QAAQ,EAAE,WAAW,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG,6BAA6B,GAAG;IAC3E,OAAO,EAAE,WAAW,CAAC;CACtB,CAAC;AAqCF;;;;;;;;;GASG;AACH,eAAO,MAAM,+BAA+B,GAAI,kDAK7C,6BAA6B,KAAG,MAOlC,CAAC;AAaF,eAAO,MAAM,uBAAuB,GAAI,yCAIrC,8BAA8B,KAAG,MAMnC,CAAC"}
@@ -0,0 +1,53 @@
1
+ "use client";
2
+ const getDocumentOffsetTop = (element) => {
3
+ let top = 0;
4
+ let current = element;
5
+ while (current) {
6
+ top += current.offsetTop;
7
+ current = current.offsetParent;
8
+ }
9
+ return top;
10
+ };
11
+ const getLayoutOffsetTop = (element, ancestor) => {
12
+ // Use layout geometry, not visual rects, so entrance transforms/animations
13
+ // on the anchor do not shift the scroll target while they settle.
14
+ let top = 0;
15
+ let current = element;
16
+ while (current && current !== ancestor) {
17
+ top += current.offsetTop;
18
+ current = current.offsetParent;
19
+ }
20
+ if (current === ancestor)
21
+ return top;
22
+ return getDocumentOffsetTop(element) - getDocumentOffsetTop(ancestor);
23
+ };
24
+ /**
25
+ * Compute the scroll position that pins the anchor (last user message) to the
26
+ * top of the viewport. For tall user messages the anchor is intentionally
27
+ * over-scrolled so only `visibleHeight` of it remains visible, leaving room
28
+ * for the assistant message below.
29
+ *
30
+ * Depends only on the anchor's offset within the scroll content; never reads
31
+ * `viewport.scrollHeight` (which is volatile while the assistant message
32
+ * streams in).
33
+ */
34
+ export const computeTopAnchorTargetScrollTop = ({ viewport, anchor, tallerThan, visibleHeight, }) => {
35
+ const anchorTop = getLayoutOffsetTop(anchor, viewport);
36
+ const anchorHeight = anchor.offsetHeight;
37
+ const visibleAnchorHeight = anchorHeight <= tallerThan ? anchorHeight : visibleHeight;
38
+ return anchorTop + Math.max(0, anchorHeight - visibleAnchorHeight);
39
+ };
40
+ const computeTopAnchorSlack = ({ scrollHeight, ...targetOptions }) => {
41
+ const { viewport } = targetOptions;
42
+ const targetScrollTop = computeTopAnchorTargetScrollTop(targetOptions);
43
+ const targetScrollHeight = targetScrollTop + viewport.clientHeight;
44
+ return Math.max(0, targetScrollHeight - scrollHeight);
45
+ };
46
+ export const computeTopAnchorReserve = ({ viewport, reserve, ...targetOptions }) => {
47
+ return computeTopAnchorSlack({
48
+ viewport,
49
+ ...targetOptions,
50
+ scrollHeight: viewport.scrollHeight - reserve.offsetHeight,
51
+ });
52
+ };
53
+ //# sourceMappingURL=computeTopAnchorSlack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computeTopAnchorSlack.js","sourceRoot":"","sources":["../../../../src/primitives/thread/topAnchor/computeTopAnchorSlack.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAiBb,MAAM,oBAAoB,GAAG,CAAC,OAAoB,EAAU,EAAE;IAC5D,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,OAAO,GAAuB,OAAO,CAAC;IAE1C,OAAO,OAAO,EAAE,CAAC;QACf,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;QACzB,OAAO,GAAG,OAAO,CAAC,YAAkC,CAAC;IACvD,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CACzB,OAAoB,EACpB,QAAqB,EACb,EAAE;IACV,2EAA2E;IAC3E,kEAAkE;IAClE,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,OAAO,GAAuB,OAAO,CAAC;IAE1C,OAAO,OAAO,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACvC,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;QACzB,OAAO,GAAG,OAAO,CAAC,YAAkC,CAAC;IACvD,CAAC;IAED,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IAErC,OAAO,oBAAoB,CAAC,OAAO,CAAC,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;AACxE,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,EAC9C,QAAQ,EACR,MAAM,EACN,UAAU,EACV,aAAa,GACiB,EAAU,EAAE;IAC1C,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvD,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;IACzC,MAAM,mBAAmB,GACvB,YAAY,IAAI,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC;IAE5D,OAAO,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,mBAAmB,CAAC,CAAC;AACrE,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,EAC7B,YAAY,EACZ,GAAG,aAAa,EACa,EAAU,EAAE;IACzC,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC;IACnC,MAAM,eAAe,GAAG,+BAA+B,CAAC,aAAa,CAAC,CAAC;IACvE,MAAM,kBAAkB,GAAG,eAAe,GAAG,QAAQ,CAAC,YAAY,CAAC;IAEnE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,GAAG,YAAY,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,EACtC,QAAQ,EACR,OAAO,EACP,GAAG,aAAa,EACe,EAAU,EAAE;IAC3C,OAAO,qBAAqB,CAAC;QAC3B,QAAQ;QACR,GAAG,aAAa;QAChB,YAAY,EAAE,QAAQ,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY;KAC3D,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const createReserveObservers: (onChange: () => void) => {
2
+ target: (viewport: HTMLElement, anchor: HTMLElement, target: HTMLElement) => void;
3
+ disconnect: () => void;
4
+ };
5
+ //# sourceMappingURL=createReserveObservers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createReserveObservers.d.ts","sourceRoot":"","sources":["../../../../src/primitives/thread/topAnchor/createReserveObservers.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,sBAAsB,GAAI,UAAU,MAAM,IAAI;uBAkB3C,WAAW,UACb,WAAW,UACX,WAAW;;CA2BxB,CAAC"}
@@ -0,0 +1,38 @@
1
+ "use client";
2
+ export const createReserveObservers = (onChange) => {
3
+ const resizeObserver = new ResizeObserver(onChange);
4
+ const mutationObserver = new MutationObserver(onChange);
5
+ let observedViewport = null;
6
+ let observedAnchor = null;
7
+ let observedTarget = null;
8
+ const disconnect = () => {
9
+ resizeObserver.disconnect();
10
+ mutationObserver.disconnect();
11
+ observedViewport = null;
12
+ observedAnchor = null;
13
+ observedTarget = null;
14
+ };
15
+ return {
16
+ target: (viewport, anchor, target) => {
17
+ if (observedViewport === viewport &&
18
+ observedAnchor === anchor &&
19
+ observedTarget === target) {
20
+ return;
21
+ }
22
+ disconnect();
23
+ resizeObserver.observe(viewport);
24
+ resizeObserver.observe(anchor);
25
+ resizeObserver.observe(target);
26
+ mutationObserver.observe(target, {
27
+ childList: true,
28
+ subtree: true,
29
+ characterData: true,
30
+ });
31
+ observedViewport = viewport;
32
+ observedAnchor = anchor;
33
+ observedTarget = target;
34
+ },
35
+ disconnect,
36
+ };
37
+ };
38
+ //# sourceMappingURL=createReserveObservers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createReserveObservers.js","sourceRoot":"","sources":["../../../../src/primitives/thread/topAnchor/createReserveObservers.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,QAAoB,EAAE,EAAE;IAC7D,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAC;IACpD,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAExD,IAAI,gBAAgB,GAAuB,IAAI,CAAC;IAChD,IAAI,cAAc,GAAuB,IAAI,CAAC;IAC9C,IAAI,cAAc,GAAuB,IAAI,CAAC;IAE9C,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,cAAc,CAAC,UAAU,EAAE,CAAC;QAC5B,gBAAgB,CAAC,UAAU,EAAE,CAAC;QAC9B,gBAAgB,GAAG,IAAI,CAAC;QACxB,cAAc,GAAG,IAAI,CAAC;QACtB,cAAc,GAAG,IAAI,CAAC;IACxB,CAAC,CAAC;IAEF,OAAO;QACL,MAAM,EAAE,CACN,QAAqB,EACrB,MAAmB,EACnB,MAAmB,EACnB,EAAE;YACF,IACE,gBAAgB,KAAK,QAAQ;gBAC7B,cAAc,KAAK,MAAM;gBACzB,cAAc,KAAK,MAAM,EACzB,CAAC;gBACD,OAAO;YACT,CAAC;YAED,UAAU,EAAE,CAAC;YAEb,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACjC,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC/B,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC/B,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE;gBAC/B,SAAS,EAAE,IAAI;gBACf,OAAO,EAAE,IAAI;gBACb,aAAa,EAAE,IAAI;aACpB,CAAC,CAAC;YAEH,gBAAgB,GAAG,QAAQ,CAAC;YAC5B,cAAc,GAAG,MAAM,CAAC;YACxB,cAAc,GAAG,MAAM,CAAC;QAC1B,CAAC;QACD,UAAU;KACX,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Minimal slice of `ThreadViewportStore` that the top-anchor reserve needs.
3
+ * Decoupling from the full store keeps `mountTopAnchorReserve` testable in
4
+ * isolation and re-usable from any consumer that can adapt to this shape.
5
+ */
6
+ export type TopAnchorStore = {
7
+ getState(): {
8
+ turnAnchor: "top" | "bottom";
9
+ element: {
10
+ viewport: HTMLElement | null;
11
+ anchor: HTMLElement | null;
12
+ target: HTMLElement | null;
13
+ };
14
+ targetConfig: {
15
+ tallerThan: number;
16
+ visibleHeight: number;
17
+ } | null;
18
+ };
19
+ subscribe(fn: () => void): () => void;
20
+ };
21
+ export declare const mountTopAnchorReserve: (store: TopAnchorStore) => () => void;
22
+ //# sourceMappingURL=mountTopAnchorReserve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mountTopAnchorReserve.d.ts","sourceRoot":"","sources":["../../../../src/primitives/thread/topAnchor/mountTopAnchorReserve.ts"],"names":[],"mappings":"AAcA;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,IAAI;QACV,UAAU,EAAE,KAAK,GAAG,QAAQ,CAAC;QAC7B,OAAO,EAAE;YACP,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;YAC7B,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;YAC3B,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;SAC5B,CAAC;QACF,YAAY,EAAE;YACZ,UAAU,EAAE,MAAM,CAAC;YACnB,aAAa,EAAE,MAAM,CAAC;SACvB,GAAG,IAAI,CAAC;KACV,CAAC;IACF,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CACvC,CAAC;AAsBF,eAAO,MAAM,qBAAqB,GAAI,OAAO,cAAc,eAuE1D,CAAC"}
@@ -0,0 +1,75 @@
1
+ "use client";
2
+ import { computeTopAnchorReserve, computeTopAnchorTargetScrollTop, } from "./computeTopAnchorSlack.js";
3
+ import { createReserveObservers } from "./createReserveObservers.js";
4
+ import { createReserveElement, getAnchorId, setReserveHeight, snapScrollTop, } from "./topAnchorUtils.js";
5
+ const createFrameScheduler = (fn) => {
6
+ let frame = null;
7
+ return {
8
+ schedule: () => {
9
+ if (frame !== null)
10
+ return;
11
+ frame = requestAnimationFrame(() => {
12
+ frame = null;
13
+ fn();
14
+ });
15
+ },
16
+ cancel: () => {
17
+ if (frame !== null) {
18
+ cancelAnimationFrame(frame);
19
+ frame = null;
20
+ }
21
+ },
22
+ };
23
+ };
24
+ export const mountTopAnchorReserve = (store) => {
25
+ let reserve = null;
26
+ let lastScrolledAnchorId;
27
+ function apply() {
28
+ const state = store.getState();
29
+ const { viewport, anchor, target } = state.element;
30
+ const clamp = state.targetConfig;
31
+ if (state.turnAnchor !== "top" ||
32
+ !viewport ||
33
+ !anchor ||
34
+ !target ||
35
+ !clamp) {
36
+ observers.disconnect();
37
+ if (reserve) {
38
+ setReserveHeight(reserve, 0);
39
+ reserve.remove();
40
+ }
41
+ return;
42
+ }
43
+ reserve ??= createReserveElement();
44
+ if (reserve.parentElement !== target.parentElement ||
45
+ reserve.previousElementSibling !== target) {
46
+ target.after(reserve);
47
+ }
48
+ observers.target(viewport, anchor, target);
49
+ const reserveChanged = setReserveHeight(reserve, computeTopAnchorReserve({ viewport, anchor, reserve, ...clamp }));
50
+ if (reserveChanged) {
51
+ scheduler.schedule();
52
+ return;
53
+ }
54
+ const anchorId = getAnchorId(anchor);
55
+ if (anchorId !== undefined && lastScrolledAnchorId === anchorId)
56
+ return;
57
+ const targetScrollTop = snapScrollTop(computeTopAnchorTargetScrollTop({ viewport, anchor, ...clamp }));
58
+ if (Math.abs(viewport.scrollTop - targetScrollTop) > 1) {
59
+ viewport.scrollTo({ top: targetScrollTop, behavior: "smooth" });
60
+ }
61
+ if (anchorId !== undefined)
62
+ lastScrolledAnchorId = anchorId;
63
+ }
64
+ const scheduler = createFrameScheduler(apply);
65
+ const observers = createReserveObservers(scheduler.schedule);
66
+ scheduler.schedule();
67
+ const unsubscribe = store.subscribe(scheduler.schedule);
68
+ return () => {
69
+ scheduler.cancel();
70
+ unsubscribe();
71
+ observers.disconnect();
72
+ reserve?.remove();
73
+ };
74
+ };
75
+ //# sourceMappingURL=mountTopAnchorReserve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mountTopAnchorReserve.js","sourceRoot":"","sources":["../../../../src/primitives/thread/topAnchor/mountTopAnchorReserve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ type TopAnchorTurnMessage = {
2
+ readonly id: string;
3
+ readonly role: string;
4
+ };
5
+ export declare const getActiveTopAnchorTurn: ({ isRunning, messages, }: {
6
+ readonly isRunning: boolean;
7
+ readonly messages: readonly TopAnchorTurnMessage[];
8
+ }) => {
9
+ anchorId: string;
10
+ targetId: string;
11
+ } | null;
12
+ export declare const getActiveTopAnchorAnchorId: (options: Parameters<typeof getActiveTopAnchorTurn>[0]) => string | undefined;
13
+ export declare const getActiveTopAnchorTargetId: (options: Parameters<typeof getActiveTopAnchorTurn>[0]) => string | undefined;
14
+ export {};
15
+ //# sourceMappingURL=topAnchorTurn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topAnchorTurn.d.ts","sourceRoot":"","sources":["../../../../src/primitives/thread/topAnchor/topAnchorTurn.ts"],"names":[],"mappings":"AAEA,KAAK,oBAAoB,GAAG;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,0BAGpC;IACD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACpD;;;QAQA,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,SAAS,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,uBACT,CAAC;AAE/C,eAAO,MAAM,0BAA0B,GACrC,SAAS,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,uBACT,CAAC"}
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ export const getActiveTopAnchorTurn = ({ isRunning, messages, }) => {
3
+ if (!isRunning)
4
+ return null;
5
+ const target = messages.at(-1);
6
+ const anchor = messages.at(-2);
7
+ if (anchor?.role !== "user" || target?.role !== "assistant")
8
+ return null;
9
+ return { anchorId: anchor.id, targetId: target.id };
10
+ };
11
+ export const getActiveTopAnchorAnchorId = (options) => getActiveTopAnchorTurn(options)?.anchorId;
12
+ export const getActiveTopAnchorTargetId = (options) => getActiveTopAnchorTurn(options)?.targetId;
13
+ //# sourceMappingURL=topAnchorTurn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topAnchorTurn.js","sourceRoot":"","sources":["../../../../src/primitives/thread/topAnchor/topAnchorTurn.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAOb,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,EACrC,SAAS,EACT,QAAQ,GAIT,EAAE,EAAE;IACH,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAE5B,MAAM,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,MAAM,EAAE,IAAI,KAAK,MAAM,IAAI,MAAM,EAAE,IAAI,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAEzE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;AACtD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,OAAqD,EACrD,EAAE,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC;AAE/C,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,OAAqD,EACrD,EAAE,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Convert a supported CSS length string (`px`, `em`, `rem`) into pixels,
3
+ * resolving font-relative units against the supplied element's computed style.
4
+ * Unsupported or malformed values disable the tall-message clamp.
5
+ *
6
+ * Part of the top-anchor package's public input contract: consumers may pass
7
+ * clamp configuration as supported CSS-length strings, and this function is the
8
+ * single place that converts them into the pixel values the package operates on.
9
+ */
10
+ export declare const parseCssLength: (value: string, element: HTMLElement) => number;
11
+ export declare const getAnchorId: (anchor: HTMLElement) => string | undefined;
12
+ export declare const createReserveElement: () => HTMLDivElement;
13
+ export declare const setReserveHeight: (reserve: HTMLElement, height: number) => boolean;
14
+ export declare const snapScrollTop: (top: number) => number;
15
+ //# sourceMappingURL=topAnchorUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topAnchorUtils.d.ts","sourceRoot":"","sources":["../../../../src/primitives/thread/topAnchor/topAnchorUtils.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,EAAE,SAAS,WAAW,KAAG,MAkBpE,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,QAAQ,WAAW,uBAA6B,CAAC;AAE7E,eAAO,MAAM,oBAAoB,sBAShC,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,SAAS,WAAW,EAAE,QAAQ,MAAM,YAQpE,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,WAGxC,CAAC"}
@@ -0,0 +1,51 @@
1
+ "use client";
2
+ /**
3
+ * Convert a supported CSS length string (`px`, `em`, `rem`) into pixels,
4
+ * resolving font-relative units against the supplied element's computed style.
5
+ * Unsupported or malformed values disable the tall-message clamp.
6
+ *
7
+ * Part of the top-anchor package's public input contract: consumers may pass
8
+ * clamp configuration as supported CSS-length strings, and this function is the
9
+ * single place that converts them into the pixel values the package operates on.
10
+ */
11
+ export const parseCssLength = (value, element) => {
12
+ const match = value.trim().match(/^(\d+(?:\.\d+)?|\.\d+)(em|px|rem)$/);
13
+ if (!match)
14
+ return Number.POSITIVE_INFINITY;
15
+ const num = Number(match[1]);
16
+ const unit = match[2];
17
+ if (unit === "px")
18
+ return num;
19
+ if (unit === "em") {
20
+ const fontSize = parseFloat(getComputedStyle(element).fontSize) || 16;
21
+ return num * fontSize;
22
+ }
23
+ if (unit === "rem") {
24
+ const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
25
+ return num * rootFontSize;
26
+ }
27
+ return Number.POSITIVE_INFINITY;
28
+ };
29
+ export const getAnchorId = (anchor) => anchor.dataset.messageId;
30
+ export const createReserveElement = () => {
31
+ const reserve = document.createElement("div");
32
+ reserve.dataset.auiTopAnchorReserve = "";
33
+ reserve.style.height = "0px";
34
+ reserve.style.flexShrink = "0";
35
+ reserve.style.pointerEvents = "none";
36
+ reserve.setAttribute("aria-hidden", "true");
37
+ return reserve;
38
+ };
39
+ export const setReserveHeight = (reserve, height) => {
40
+ const nextHeight = `${height}px`;
41
+ if (reserve.style.height !== nextHeight) {
42
+ reserve.style.height = nextHeight;
43
+ return true;
44
+ }
45
+ return false;
46
+ };
47
+ export const snapScrollTop = (top) => {
48
+ const pixelRatio = window.devicePixelRatio || 1;
49
+ return Math.round(top * pixelRatio) / pixelRatio;
50
+ };
51
+ //# sourceMappingURL=topAnchorUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topAnchorUtils.js","sourceRoot":"","sources":["../../../../src/primitives/thread/topAnchor/topAnchorUtils.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,OAAoB,EAAU,EAAE;IAC5E,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACvE,IAAI,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC,iBAAiB,CAAC;IAE5C,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEtB,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAC9B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,UAAU,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtE,OAAO,GAAG,GAAG,QAAQ,CAAC;IACxB,CAAC;IACD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,MAAM,YAAY,GAChB,UAAU,CAAC,gBAAgB,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACxE,OAAO,GAAG,GAAG,YAAY,CAAC;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC,iBAAiB,CAAC;AAClC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAmB,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;AAE7E,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,EAAE;IACvC,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,CAAC,OAAO,CAAC,mBAAmB,GAAG,EAAE,CAAC;IACzC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;IAC7B,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;IAC/B,OAAO,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAE5C,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAoB,EAAE,MAAc,EAAE,EAAE;IACvE,MAAM,UAAU,GAAG,GAAG,MAAM,IAAI,CAAC;IACjC,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,EAAE;IAC3C,MAAM,UAAU,GAAG,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,UAAU,CAAC;AACnD,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Mounts the top-turn-anchor reserve element against the active
3
+ * `ThreadViewport` store. Call this from inside the scrollable viewport so
4
+ * the reserve `<div>` is appended next to the streaming assistant message.
5
+ */
6
+ export declare const useTopAnchorReserve: (enabled: boolean) => void;
7
+ //# sourceMappingURL=useTopAnchorReserve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTopAnchorReserve.d.ts","sourceRoot":"","sources":["../../../../src/primitives/thread/topAnchor/useTopAnchorReserve.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,OAAO,SAOnD,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { useLayoutEffect } from "react";
3
+ import { useThreadViewportStore } from "../../../context/react/ThreadViewportContext.js";
4
+ import { mountTopAnchorReserve } from "./mountTopAnchorReserve.js";
5
+ /**
6
+ * Mounts the top-turn-anchor reserve element against the active
7
+ * `ThreadViewport` store. Call this from inside the scrollable viewport so
8
+ * the reserve `<div>` is appended next to the streaming assistant message.
9
+ */
10
+ export const useTopAnchorReserve = (enabled) => {
11
+ const threadViewportStore = useThreadViewportStore();
12
+ useLayoutEffect(() => {
13
+ if (!enabled)
14
+ return;
15
+ return mountTopAnchorReserve(threadViewportStore);
16
+ }, [enabled, threadViewportStore]);
17
+ };
18
+ //# sourceMappingURL=useTopAnchorReserve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTopAnchorReserve.js","sourceRoot":"","sources":["../../../../src/primitives/thread/topAnchor/useTopAnchorReserve.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,wDAAqD;AACtF,OAAO,EAAE,qBAAqB,EAAE,mCAAgC;AAEhE;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAgB,EAAE,EAAE;IACtD,MAAM,mBAAmB,GAAG,sBAAsB,EAAE,CAAC;IAErD,eAAe,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,OAAO,qBAAqB,CAAC,mBAAmB,CAAC,CAAC;IACpD,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC;AACrC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useThreadViewportAutoScroll.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAQ9D,yBAAiB,2BAA2B,CAAC;IAC3C,KAAY,OAAO,GAAG;QACpB;;;;;WAKG;QACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjC;;;;WAIG;QACH,wBAAwB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAE/C;;;;WAIG;QACH,0BAA0B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjD;;;;WAIG;QACH,4BAA4B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KACpD,CAAC;CACH;AAED,eAAO,MAAM,2BAA2B,GAAI,QAAQ,SAAS,WAAW,EAAE,qGAKvE,2BAA2B,CAAC,OAAO,KAAG,WAAW,CAAC,QAAQ,CAuG5D,CAAC"}
1
+ {"version":3,"file":"useThreadViewportAutoScroll.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAQ9D,yBAAiB,2BAA2B,CAAC;IAC3C,KAAY,OAAO,GAAG;QACpB;;;;;WAKG;QACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjC;;;;WAIG;QACH,wBAAwB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAE/C;;;;WAIG;QACH,0BAA0B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjD;;;;WAIG;QACH,4BAA4B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KACpD,CAAC;CACH;AAED,eAAO,MAAM,2BAA2B,GAAI,QAAQ,SAAS,WAAW,EAAE,qGAKvE,2BAA2B,CAAC,OAAO,KAAG,WAAW,CAAC,QAAQ,CAqH5D,CAAC"}
@@ -25,6 +25,12 @@ export const useThreadViewportAutoScroll = ({ autoScroll, scrollToBottomOnRunSta
25
25
  scrollingToBottomBehaviorRef.current = behavior;
26
26
  div.scrollTo({ top: div.scrollHeight, behavior });
27
27
  }, []);
28
+ const hasActiveTopAnchor = useCallback(() => {
29
+ const state = threadViewportStore.getState();
30
+ return (state.turnAnchor === "top" &&
31
+ state.element.viewport === divRef.current &&
32
+ state.element.anchor !== null);
33
+ }, [threadViewportStore]);
28
34
  const handleScroll = () => {
29
35
  const div = divRef.current;
30
36
  if (!div)
@@ -50,7 +56,11 @@ export const useThreadViewportAutoScroll = ({ autoScroll, scrollToBottomOnRunSta
50
56
  };
51
57
  const resizeRef = useOnResizeContent(() => {
52
58
  const scrollBehavior = scrollingToBottomBehaviorRef.current;
53
- if (scrollBehavior) {
59
+ if (scrollBehavior && hasActiveTopAnchor()) {
60
+ // Let the top-anchor reserve own scrolling while a run starts to avoid a bottom-scroll race.
61
+ scrollingToBottomBehaviorRef.current = null;
62
+ }
63
+ else if (scrollBehavior) {
54
64
  scrollToBottom(scrollBehavior);
55
65
  }
56
66
  else if (autoScroll && threadViewportStore.getState().isAtBottom) {
@@ -71,6 +81,8 @@ export const useThreadViewportAutoScroll = ({ autoScroll, scrollToBottomOnRunSta
71
81
  useAuiEvent("thread.runStart", () => {
72
82
  if (!scrollToBottomOnRunStart)
73
83
  return;
84
+ if (threadViewportStore.getState().turnAnchor === "top")
85
+ return;
74
86
  scrollingToBottomBehaviorRef.current = "auto";
75
87
  requestAnimationFrame(() => {
76
88
  scrollToBottom("auto");
@@ -1 +1 @@
1
- {"version":3,"file":"useThreadViewportAutoScroll.js","sourceRoot":"","sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useThreadViewportAutoScroll.js","sourceRoot":"","sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,EAAoB,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,gDAA6C;AAC1E,OAAO,EAAE,mBAAmB,EAAE,iDAA8C;AAC5E,OAAO,EAAE,aAAa,EAAE,2CAAwC;AAChE,OAAO,EAAE,aAAa,EAAE,uCAAoC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,qDAAkD;AAmCnF,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAA+B,EACxE,UAAU,EACV,wBAAwB,GAAG,IAAI,EAC/B,0BAA0B,GAAG,IAAI,EACjC,4BAA4B,GAAG,IAAI,GACC,EAAyB,EAAE;IAC/D,MAAM,MAAM,GAAG,MAAM,CAAW,IAAI,CAAC,CAAC;IAEtC,MAAM,mBAAmB,GAAG,sBAAsB,EAAE,CAAC;IACrD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,UAAU,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAC,UAAU,KAAK,KAAK,CAAC;IACnE,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,CAAS,CAAC,CAAC,CAAC;IAExC,iFAAiF;IACjF,uDAAuD;IACvD,sFAAsF;IACtF,MAAM,4BAA4B,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IAEzE,MAAM,cAAc,GAAG,WAAW,CAAC,CAAC,QAAwB,EAAE,EAAE;QAC9D,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,GAAG;YAAE,OAAO;QAEjB,4BAA4B,CAAC,OAAO,GAAG,QAAQ,CAAC;QAChD,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,kBAAkB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC1C,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAC;QAC7C,OAAO,CACL,KAAK,CAAC,UAAU,KAAK,KAAK;YAC1B,KAAK,CAAC,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,OAAO;YACzC,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,IAAI,CAC9B,CAAC;IACJ,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAE1B,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,GAAG;YAAE,OAAO;QAEjB,MAAM,UAAU,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC;QAC7D,MAAM,aAAa,GACjB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC;YACjE,GAAG,CAAC,YAAY,IAAI,GAAG,CAAC,YAAY,CAAC;QAEvC,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,OAAO,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC;YAC5D,qBAAqB;QACvB,CAAC;aAAM,CAAC;YACN,IAAI,aAAa,EAAE,CAAC;gBAClB,4BAA4B,CAAC,OAAO,GAAG,IAAI,CAAC;YAC9C,CAAC;YAED,MAAM,YAAY,GAChB,aAAa,IAAI,4BAA4B,CAAC,OAAO,KAAK,IAAI,CAAC;YAEjE,IAAI,YAAY,IAAI,aAAa,KAAK,UAAU,EAAE,CAAC;gBACjD,aAAa,CAAC,mBAAmB,CAAC,CAAC,QAAQ,CAAC;oBAC1C,UAAU,EAAE,aAAa;iBAC1B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,aAAa,CAAC,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC;IACxC,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,EAAE;QACxC,MAAM,cAAc,GAAG,4BAA4B,CAAC,OAAO,CAAC;QAC5D,IAAI,cAAc,IAAI,kBAAkB,EAAE,EAAE,CAAC;YAC3C,6FAA6F;YAC7F,4BAA4B,CAAC,OAAO,GAAG,IAAI,CAAC;QAC9C,CAAC;aAAM,IAAI,cAAc,EAAE,CAAC;YAC1B,cAAc,CAAC,cAAc,CAAC,CAAC;QACjC,CAAC;aAAM,IAAI,UAAU,IAAI,mBAAmB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,CAAC;YACnE,cAAc,CAAC,SAAS,CAAC,CAAC;QAC5B,CAAC;QAED,YAAY,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,aAAa,CAAc,CAAC,EAAE,EAAE,EAAE;QAClD,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC5C,OAAO,GAAG,EAAE;YACV,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QACjD,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,mBAAmB,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;QACnC,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,0BAA0B;IAC1B,WAAW,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAClC,IAAI,CAAC,wBAAwB;YAAE,OAAO;QACtC,IAAI,mBAAmB,CAAC,QAAQ,EAAE,CAAC,UAAU,KAAK,KAAK;YAAE,OAAO;QAEhE,4BAA4B,CAAC,OAAO,GAAG,MAAM,CAAC;QAC9C,qBAAqB,CAAC,GAAG,EAAE;YACzB,cAAc,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,iEAAiE;IACjE,WAAW,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACpC,IAAI,CAAC,0BAA0B;YAAE,OAAO;QACxC,4BAA4B,CAAC,OAAO,GAAG,SAAS,CAAC;QACjD,qBAAqB,CAAC,GAAG,EAAE;YACzB,cAAc,CAAC,SAAS,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,oDAAoD;IACpD,WAAW,CAAC,2BAA2B,EAAE,GAAG,EAAE;QAC5C,IAAI,CAAC,4BAA4B;YAAE,OAAO;QAC1C,4BAA4B,CAAC,OAAO,GAAG,SAAS,CAAC;QACjD,qBAAqB,CAAC,GAAG,EAAE;YACzB,cAAc,CAAC,SAAS,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,eAAe,CAAW,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAC9E,OAAO,aAAsC,CAAC;AAChD,CAAC,CAAC"}
@@ -4,7 +4,6 @@ export { ThreadPrimitiveIf as If } from "./thread/ThreadIf.js";
4
4
  export { ThreadPrimitiveViewport as Viewport } from "./thread/ThreadViewport.js";
5
5
  export { ThreadPrimitiveViewportProvider as ViewportProvider } from "../context/providers/ThreadViewportProvider.js";
6
6
  export { ThreadPrimitiveViewportFooter as ViewportFooter } from "./thread/ThreadViewportFooter.js";
7
- export { ThreadPrimitiveViewportSlack as ViewportSlack } from "./thread/ThreadViewportSlack.js";
8
7
  export { ThreadPrimitiveMessages as Messages } from "./thread/ThreadMessages.js";
9
8
  export { ThreadPrimitiveMessageByIndex as MessageByIndex } from "./thread/ThreadMessages.js";
10
9
  export { ThreadPrimitiveScrollToBottom as ScrollToBottom } from "./thread/ThreadScrollToBottom.js";
@@ -1 +1 @@
1
- {"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/primitives/thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,IAAI,EAAE,+BAA4B;AAClE,OAAO,EAAE,oBAAoB,IAAI,KAAK,EAAE,gCAA6B;AACrE,OAAO,EAAE,iBAAiB,IAAI,EAAE,EAAE,6BAA0B;AAC5D,OAAO,EAAE,uBAAuB,IAAI,QAAQ,EAAE,mCAAgC;AAC9E,OAAO,EAAE,+BAA+B,IAAI,gBAAgB,EAAE,uDAAoD;AAClH,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,yCAAsC;AAChG,OAAO,EAAE,4BAA4B,IAAI,aAAa,EAAE,wCAAqC;AAC7F,OAAO,EAAE,uBAAuB,IAAI,QAAQ,EAAE,mCAAgC;AAC9E,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,mCAAgC;AAC1F,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,yCAAsC;AAChG,OAAO,EAAE,yBAAyB,IAAI,UAAU,EAAE,qCAAkC;AACpF,OAAO,EACL,0BAA0B,IAAI,WAAW,EACzC,gCAAgC,IAAI,iBAAiB,GACtD,sCAAmC"}
1
+ {"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/primitives/thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,IAAI,EAAE,+BAA4B;AAClE,OAAO,EAAE,oBAAoB,IAAI,KAAK,EAAE,gCAA6B;AACrE,OAAO,EAAE,iBAAiB,IAAI,EAAE,EAAE,6BAA0B;AAC5D,OAAO,EAAE,uBAAuB,IAAI,QAAQ,EAAE,mCAAgC;AAC9E,OAAO,EAAE,+BAA+B,IAAI,gBAAgB,EAAE,uDAAoD;AAClH,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,yCAAsC;AAChG,OAAO,EAAE,uBAAuB,IAAI,QAAQ,EAAE,mCAAgC;AAC9E,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,mCAAgC;AAC1F,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,yCAAsC;AAChG,OAAO,EAAE,yBAAyB,IAAI,UAAU,EAAE,qCAAkC;AACpF,OAAO,EACL,0BAA0B,IAAI,WAAW,EACzC,gCAAgC,IAAI,iBAAiB,GACtD,sCAAmC"}
@@ -4,7 +4,6 @@ export { ThreadPrimitiveIf as If } from "./thread/ThreadIf.js";
4
4
  export { ThreadPrimitiveViewport as Viewport } from "./thread/ThreadViewport.js";
5
5
  export { ThreadPrimitiveViewportProvider as ViewportProvider } from "../context/providers/ThreadViewportProvider.js";
6
6
  export { ThreadPrimitiveViewportFooter as ViewportFooter } from "./thread/ThreadViewportFooter.js";
7
- export { ThreadPrimitiveViewportSlack as ViewportSlack } from "./thread/ThreadViewportSlack.js";
8
7
  export { ThreadPrimitiveMessages as Messages } from "./thread/ThreadMessages.js";
9
8
  export { ThreadPrimitiveMessageByIndex as MessageByIndex } from "./thread/ThreadMessages.js";
10
9
  export { ThreadPrimitiveScrollToBottom as ScrollToBottom } from "./thread/ThreadScrollToBottom.js";
@@ -1 +1 @@
1
- {"version":3,"file":"thread.js","sourceRoot":"","sources":["../../src/primitives/thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,IAAI,EAAE,+BAA4B;AAClE,OAAO,EAAE,oBAAoB,IAAI,KAAK,EAAE,gCAA6B;AACrE,OAAO,EAAE,iBAAiB,IAAI,EAAE,EAAE,6BAA0B;AAC5D,OAAO,EAAE,uBAAuB,IAAI,QAAQ,EAAE,mCAAgC;AAC9E,OAAO,EAAE,+BAA+B,IAAI,gBAAgB,EAAE,uDAAoD;AAClH,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,yCAAsC;AAChG,OAAO,EAAE,4BAA4B,IAAI,aAAa,EAAE,wCAAqC;AAC7F,OAAO,EAAE,uBAAuB,IAAI,QAAQ,EAAE,mCAAgC;AAC9E,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,mCAAgC;AAC1F,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,yCAAsC;AAChG,OAAO,EAAE,yBAAyB,IAAI,UAAU,EAAE,qCAAkC;AACpF,OAAO,EACL,0BAA0B,IAAI,WAAW,EACzC,gCAAgC,IAAI,iBAAiB,GACtD,sCAAmC"}
1
+ {"version":3,"file":"thread.js","sourceRoot":"","sources":["../../src/primitives/thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,IAAI,EAAE,+BAA4B;AAClE,OAAO,EAAE,oBAAoB,IAAI,KAAK,EAAE,gCAA6B;AACrE,OAAO,EAAE,iBAAiB,IAAI,EAAE,EAAE,6BAA0B;AAC5D,OAAO,EAAE,uBAAuB,IAAI,QAAQ,EAAE,mCAAgC;AAC9E,OAAO,EAAE,+BAA+B,IAAI,gBAAgB,EAAE,uDAAoD;AAClH,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,yCAAsC;AAChG,OAAO,EAAE,uBAAuB,IAAI,QAAQ,EAAE,mCAAgC;AAC9E,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,mCAAgC;AAC1F,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,yCAAsC;AAChG,OAAO,EAAE,yBAAyB,IAAI,UAAU,EAAE,qCAAkC;AACpF,OAAO,EACL,0BAA0B,IAAI,WAAW,EACzC,gCAAgC,IAAI,iBAAiB,GACtD,sCAAmC"}
@@ -0,0 +1,13 @@
1
+ import { type ActionButtonElement, type ActionButtonProps } from "../../utils/createActionButton.js";
2
+ declare const useThreadListLoadMore: () => (() => void) | null;
3
+ export declare namespace ThreadListPrimitiveLoadMore {
4
+ type Element = ActionButtonElement;
5
+ type Props = ActionButtonProps<typeof useThreadListLoadMore>;
6
+ }
7
+ export declare const ThreadListPrimitiveLoadMore: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement> & {
8
+ asChild?: boolean;
9
+ }, "ref"> & {
10
+ render?: import("react").ReactElement | undefined;
11
+ } & import("react").RefAttributes<HTMLButtonElement>, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
12
+ export {};
13
+ //# sourceMappingURL=ThreadListLoadMore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThreadListLoadMore.d.ts","sourceRoot":"","sources":["../../../src/primitives/threadList/ThreadListLoadMore.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EAEvB,0CAAuC;AAGxC,QAAA,MAAM,qBAAqB,2BAI1B,CAAC;AAEF,yBAAiB,2BAA2B,CAAC;IAC3C,KAAY,OAAO,GAAG,mBAAmB,CAAC;IAC1C,KAAY,KAAK,GAAG,iBAAiB,CAAC,OAAO,qBAAqB,CAAC,CAAC;CACrE;AAED,eAAO,MAAM,2BAA2B;;;;gHAGvC,CAAC"}
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ import { createActionButton, } from "../../utils/createActionButton.js";
3
+ import { useThreadListLoadMore as useThreadListLoadMoreBehavior } from "@assistant-ui/core/react";
4
+ const useThreadListLoadMore = () => {
5
+ const { loadMore, disabled } = useThreadListLoadMoreBehavior();
6
+ if (disabled)
7
+ return null;
8
+ return loadMore;
9
+ };
10
+ export const ThreadListPrimitiveLoadMore = createActionButton("ThreadListPrimitive.LoadMore", useThreadListLoadMore);
11
+ //# sourceMappingURL=ThreadListLoadMore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThreadListLoadMore.js","sourceRoot":"","sources":["../../../src/primitives/threadList/ThreadListLoadMore.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAGL,kBAAkB,GACnB,0CAAuC;AACxC,OAAO,EAAE,qBAAqB,IAAI,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAElG,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACjC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,6BAA6B,EAAE,CAAC;IAC/D,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAOF,MAAM,CAAC,MAAM,2BAA2B,GAAG,kBAAkB,CAC3D,8BAA8B,EAC9B,qBAAqB,CACtB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export { ThreadListPrimitiveNew as New } from "./threadList/ThreadListNew.js";
2
2
  export { ThreadListPrimitiveItems as Items } from "./threadList/ThreadListItems.js";
3
3
  export { ThreadListPrimitiveItemByIndex as ItemByIndex } from "./threadList/ThreadListItems.js";
4
+ export { ThreadListPrimitiveLoadMore as LoadMore } from "./threadList/ThreadListLoadMore.js";
4
5
  export { ThreadListPrimitiveRoot as Root } from "./threadList/ThreadListRoot.js";
5
6
  //# sourceMappingURL=threadList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"threadList.d.ts","sourceRoot":"","sources":["../../src/primitives/threadList.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,IAAI,GAAG,EAAE,sCAAmC;AAC3E,OAAO,EAAE,wBAAwB,IAAI,KAAK,EAAE,wCAAqC;AACjF,OAAO,EAAE,8BAA8B,IAAI,WAAW,EAAE,wCAAqC;AAC7F,OAAO,EAAE,uBAAuB,IAAI,IAAI,EAAE,uCAAoC"}
1
+ {"version":3,"file":"threadList.d.ts","sourceRoot":"","sources":["../../src/primitives/threadList.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,IAAI,GAAG,EAAE,sCAAmC;AAC3E,OAAO,EAAE,wBAAwB,IAAI,KAAK,EAAE,wCAAqC;AACjF,OAAO,EAAE,8BAA8B,IAAI,WAAW,EAAE,wCAAqC;AAC7F,OAAO,EAAE,2BAA2B,IAAI,QAAQ,EAAE,2CAAwC;AAC1F,OAAO,EAAE,uBAAuB,IAAI,IAAI,EAAE,uCAAoC"}
@@ -1,5 +1,6 @@
1
1
  export { ThreadListPrimitiveNew as New } from "./threadList/ThreadListNew.js";
2
2
  export { ThreadListPrimitiveItems as Items } from "./threadList/ThreadListItems.js";
3
3
  export { ThreadListPrimitiveItemByIndex as ItemByIndex } from "./threadList/ThreadListItems.js";
4
+ export { ThreadListPrimitiveLoadMore as LoadMore } from "./threadList/ThreadListLoadMore.js";
4
5
  export { ThreadListPrimitiveRoot as Root } from "./threadList/ThreadListRoot.js";
5
6
  //# sourceMappingURL=threadList.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"threadList.js","sourceRoot":"","sources":["../../src/primitives/threadList.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,IAAI,GAAG,EAAE,sCAAmC;AAC3E,OAAO,EAAE,wBAAwB,IAAI,KAAK,EAAE,wCAAqC;AACjF,OAAO,EAAE,8BAA8B,IAAI,WAAW,EAAE,wCAAqC;AAC7F,OAAO,EAAE,uBAAuB,IAAI,IAAI,EAAE,uCAAoC"}
1
+ {"version":3,"file":"threadList.js","sourceRoot":"","sources":["../../src/primitives/threadList.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,IAAI,GAAG,EAAE,sCAAmC;AAC3E,OAAO,EAAE,wBAAwB,IAAI,KAAK,EAAE,wCAAqC;AACjF,OAAO,EAAE,8BAA8B,IAAI,WAAW,EAAE,wCAAqC;AAC7F,OAAO,EAAE,2BAA2B,IAAI,QAAQ,EAAE,2CAAwC;AAC1F,OAAO,EAAE,uBAAuB,IAAI,IAAI,EAAE,uCAAoC"}
@@ -0,0 +1,3 @@
1
+ import type { RemoteThreadListAdapter } from "../index.js";
2
+ export declare function makeAdapter(overrides?: Partial<RemoteThreadListAdapter>): RemoteThreadListAdapter;
3
+ //# sourceMappingURL=remote-thread-list-test-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-thread-list-test-helpers.d.ts","sourceRoot":"","sources":["../../src/tests/remote-thread-list-test-helpers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,oBAAiB;AAExD,wBAAgB,WAAW,CACzB,SAAS,GAAE,OAAO,CAAC,uBAAuB,CAAM,GAC/C,uBAAuB,CA2BzB"}