@slices.sh/ai-chat 0.1.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 (393) hide show
  1. package/LICENSE +21 -0
  2. package/dist/exports.json +794 -0
  3. package/dist/fixture/fixture-approval.d.ts +4 -0
  4. package/dist/fixture/fixture-approval.js +59 -0
  5. package/dist/fixture/fixture-artifacts.d.ts +2 -0
  6. package/dist/fixture/fixture-artifacts.js +48 -0
  7. package/dist/fixture/fixture-question.d.ts +5 -0
  8. package/dist/fixture/fixture-question.js +93 -0
  9. package/dist/fixture/fixture-script.d.ts +35 -0
  10. package/dist/fixture/fixture-script.js +280 -0
  11. package/dist/fixture/fixture-selection.d.ts +5 -0
  12. package/dist/fixture/fixture-selection.js +20 -0
  13. package/dist/fixture/fixture.d.ts +20 -0
  14. package/dist/fixture/fixture.js +75 -0
  15. package/dist/fixture/provider.d.ts +15 -0
  16. package/dist/fixture/provider.js +14 -0
  17. package/dist/headless/always-allow.d.ts +2 -0
  18. package/dist/headless/always-allow.js +24 -0
  19. package/dist/headless/answer.d.ts +6 -0
  20. package/dist/headless/answer.js +29 -0
  21. package/dist/headless/approval-error.d.ts +2 -0
  22. package/dist/headless/approval-error.js +16 -0
  23. package/dist/headless/approval-reason.d.ts +2 -0
  24. package/dist/headless/approval-reason.js +13 -0
  25. package/dist/headless/approval-receipt.d.ts +4 -0
  26. package/dist/headless/approval-receipt.js +13 -0
  27. package/dist/headless/approve.d.ts +4 -0
  28. package/dist/headless/approve.js +15 -0
  29. package/dist/headless/branch-navigation.d.ts +2 -0
  30. package/dist/headless/branch-navigation.js +11 -0
  31. package/dist/headless/branch-next.d.ts +2 -0
  32. package/dist/headless/branch-next.js +21 -0
  33. package/dist/headless/branch-page.d.ts +5 -0
  34. package/dist/headless/branch-page.js +13 -0
  35. package/dist/headless/branch-previous.d.ts +2 -0
  36. package/dist/headless/branch-previous.js +21 -0
  37. package/dist/headless/cancel-edit.d.ts +2 -0
  38. package/dist/headless/cancel-edit.js +10 -0
  39. package/dist/headless/cancel-queue-edit.d.ts +2 -0
  40. package/dist/headless/cancel-queue-edit.js +15 -0
  41. package/dist/headless/cancel-queued.d.ts +2 -0
  42. package/dist/headless/cancel-queued.js +15 -0
  43. package/dist/headless/chat-dictation/confirm.d.ts +2 -0
  44. package/dist/headless/chat-dictation/confirm.js +14 -0
  45. package/dist/headless/chat-dictation/index.d.ts +12 -0
  46. package/dist/headless/chat-dictation/index.js +9 -0
  47. package/dist/headless/chat-dictation/input.d.ts +3 -0
  48. package/dist/headless/chat-dictation/input.js +42 -0
  49. package/dist/headless/chat-dictation/root.d.ts +3 -0
  50. package/dist/headless/chat-dictation/root.js +42 -0
  51. package/dist/headless/chat-dictation/text.d.ts +3 -0
  52. package/dist/headless/chat-dictation/text.js +14 -0
  53. package/dist/headless/chat-dictation/voice.d.ts +3 -0
  54. package/dist/headless/chat-dictation/voice.js +35 -0
  55. package/dist/headless/citation-content.d.ts +3 -0
  56. package/dist/headless/citation-content.js +19 -0
  57. package/dist/headless/citation-description.d.ts +2 -0
  58. package/dist/headless/citation-description.js +12 -0
  59. package/dist/headless/citation-root.d.ts +2 -0
  60. package/dist/headless/citation-root.js +13 -0
  61. package/dist/headless/citation-title.d.ts +2 -0
  62. package/dist/headless/citation-title.js +12 -0
  63. package/dist/headless/citation-trigger.d.ts +2 -0
  64. package/dist/headless/citation-trigger.js +12 -0
  65. package/dist/headless/clear-answer.d.ts +5 -0
  66. package/dist/headless/clear-answer.js +19 -0
  67. package/dist/headless/composer-root.d.ts +14 -0
  68. package/dist/headless/composer-root.js +12 -0
  69. package/dist/headless/composer-standalone.d.ts +3 -0
  70. package/dist/headless/composer-standalone.js +10 -0
  71. package/dist/headless/composer.d.ts +3 -0
  72. package/dist/headless/composer.js +24 -0
  73. package/dist/headless/context-usage.d.ts +3 -0
  74. package/dist/headless/context-usage.js +13 -0
  75. package/dist/headless/contexts.d.ts +77 -0
  76. package/dist/headless/contexts.js +53 -0
  77. package/dist/headless/continue.d.ts +4 -0
  78. package/dist/headless/continue.js +26 -0
  79. package/dist/headless/copy.d.ts +11 -0
  80. package/dist/headless/copy.js +21 -0
  81. package/dist/headless/deny.d.ts +4 -0
  82. package/dist/headless/deny.js +15 -0
  83. package/dist/headless/edit-queued.d.ts +2 -0
  84. package/dist/headless/edit-queued.js +15 -0
  85. package/dist/headless/edit.d.ts +2 -0
  86. package/dist/headless/edit.js +17 -0
  87. package/dist/headless/edited-attachments.d.ts +5 -0
  88. package/dist/headless/edited-attachments.js +11 -0
  89. package/dist/headless/edited-input.d.ts +2 -0
  90. package/dist/headless/edited-input.js +28 -0
  91. package/dist/headless/empty.d.ts +3 -0
  92. package/dist/headless/empty.js +12 -0
  93. package/dist/headless/failed.d.ts +15 -0
  94. package/dist/headless/failed.js +17 -0
  95. package/dist/headless/feedback-error.d.ts +2 -0
  96. package/dist/headless/feedback-error.js +11 -0
  97. package/dist/headless/feedback-root.d.ts +2 -0
  98. package/dist/headless/feedback-root.js +24 -0
  99. package/dist/headless/feedback.d.ts +4 -0
  100. package/dist/headless/feedback.js +18 -0
  101. package/dist/headless/file-audio.d.ts +2 -0
  102. package/dist/headless/file-audio.js +16 -0
  103. package/dist/headless/file-context.d.ts +4 -0
  104. package/dist/headless/file-context.js +7 -0
  105. package/dist/headless/file-img.d.ts +2 -0
  106. package/dist/headless/file-img.js +21 -0
  107. package/dist/headless/file-kind-gate.d.ts +5 -0
  108. package/dist/headless/file-kind-gate.js +11 -0
  109. package/dist/headless/file-link.d.ts +3 -0
  110. package/dist/headless/file-link.js +14 -0
  111. package/dist/headless/file-root.d.ts +5 -0
  112. package/dist/headless/file-root.js +13 -0
  113. package/dist/headless/file-unavailable.d.ts +2 -0
  114. package/dist/headless/file-unavailable.js +12 -0
  115. package/dist/headless/file-video.d.ts +2 -0
  116. package/dist/headless/file-video.js +16 -0
  117. package/dist/headless/follow-ups.d.ts +5 -0
  118. package/dist/headless/follow-ups.js +20 -0
  119. package/dist/headless/forget-approval.d.ts +2 -0
  120. package/dist/headless/forget-approval.js +21 -0
  121. package/dist/headless/gate-content.d.ts +2 -0
  122. package/dist/headless/gate-content.js +6 -0
  123. package/dist/headless/index.d.ts +249 -0
  124. package/dist/headless/index.js +251 -0
  125. package/dist/headless/input.d.ts +11 -0
  126. package/dist/headless/input.js +18 -0
  127. package/dist/headless/jump-to-latest.d.ts +3 -0
  128. package/dist/headless/jump-to-latest.js +14 -0
  129. package/dist/headless/message-edit-root.d.ts +2 -0
  130. package/dist/headless/message-edit-root.js +13 -0
  131. package/dist/headless/message-editing.d.ts +2 -0
  132. package/dist/headless/message-editing.js +10 -0
  133. package/dist/headless/message-editor.d.ts +2 -0
  134. package/dist/headless/message-editor.js +19 -0
  135. package/dist/headless/message-footer.d.ts +3 -0
  136. package/dist/headless/message-footer.js +15 -0
  137. package/dist/headless/message-reading.d.ts +2 -0
  138. package/dist/headless/message-reading.js +10 -0
  139. package/dist/headless/message.d.ts +11 -0
  140. package/dist/headless/message.js +34 -0
  141. package/dist/headless/messages.d.ts +9 -0
  142. package/dist/headless/messages.js +19 -0
  143. package/dist/headless/model-picker.d.ts +2 -0
  144. package/dist/headless/model-picker.js +14 -0
  145. package/dist/headless/model.d.ts +4 -0
  146. package/dist/headless/model.js +13 -0
  147. package/dist/headless/models.d.ts +5 -0
  148. package/dist/headless/models.js +11 -0
  149. package/dist/headless/optional-tools.d.ts +7 -0
  150. package/dist/headless/optional-tools.js +12 -0
  151. package/dist/headless/other-answer.d.ts +5 -0
  152. package/dist/headless/other-answer.js +32 -0
  153. package/dist/headless/part-approval.d.ts +2 -0
  154. package/dist/headless/part-approval.js +33 -0
  155. package/dist/headless/part-file.d.ts +6 -0
  156. package/dist/headless/part-file.js +11 -0
  157. package/dist/headless/part-question.d.ts +2 -0
  158. package/dist/headless/part-question.js +57 -0
  159. package/dist/headless/part-reasoning.d.ts +15 -0
  160. package/dist/headless/part-reasoning.js +26 -0
  161. package/dist/headless/part-source.d.ts +5 -0
  162. package/dist/headless/part-source.js +20 -0
  163. package/dist/headless/part-text.d.ts +16 -0
  164. package/dist/headless/part-text.js +29 -0
  165. package/dist/headless/part-tool.d.ts +16 -0
  166. package/dist/headless/part-tool.js +14 -0
  167. package/dist/headless/parts.d.ts +11 -0
  168. package/dist/headless/parts.js +11 -0
  169. package/dist/headless/question-back.d.ts +2 -0
  170. package/dist/headless/question-back.js +16 -0
  171. package/dist/headless/question-error.d.ts +2 -0
  172. package/dist/headless/question-error.js +14 -0
  173. package/dist/headless/question-invalid.d.ts +8 -0
  174. package/dist/headless/question-invalid.js +18 -0
  175. package/dist/headless/question-item.d.ts +8 -0
  176. package/dist/headless/question-item.js +51 -0
  177. package/dist/headless/question-next.d.ts +3 -0
  178. package/dist/headless/question-next.js +16 -0
  179. package/dist/headless/question-other.d.ts +5 -0
  180. package/dist/headless/question-other.js +22 -0
  181. package/dist/headless/question-progress.d.ts +8 -0
  182. package/dist/headless/question-progress.js +14 -0
  183. package/dist/headless/question-receipt.d.ts +11 -0
  184. package/dist/headless/question-receipt.js +29 -0
  185. package/dist/headless/questions.d.ts +3 -0
  186. package/dist/headless/questions.js +13 -0
  187. package/dist/headless/queue-editing.d.ts +4 -0
  188. package/dist/headless/queue-editing.js +11 -0
  189. package/dist/headless/queue-item.d.ts +2 -0
  190. package/dist/headless/queue-item.js +10 -0
  191. package/dist/headless/queue-items.d.ts +2 -0
  192. package/dist/headless/queue-items.js +11 -0
  193. package/dist/headless/queue-preview.d.ts +6 -0
  194. package/dist/headless/queue-preview.js +11 -0
  195. package/dist/headless/queued-input.d.ts +2 -0
  196. package/dist/headless/queued-input.js +27 -0
  197. package/dist/headless/queued.d.ts +17 -0
  198. package/dist/headless/queued.js +16 -0
  199. package/dist/headless/read-aloud.d.ts +5 -0
  200. package/dist/headless/read-aloud.js +19 -0
  201. package/dist/headless/reasoning-disclosure.d.ts +3 -0
  202. package/dist/headless/reasoning-disclosure.js +17 -0
  203. package/dist/headless/reasoning-timer.d.ts +5 -0
  204. package/dist/headless/reasoning-timer.js +13 -0
  205. package/dist/headless/references.d.ts +6 -0
  206. package/dist/headless/references.js +13 -0
  207. package/dist/headless/regenerate.d.ts +3 -0
  208. package/dist/headless/regenerate.js +22 -0
  209. package/dist/headless/remembered-approval.d.ts +2 -0
  210. package/dist/headless/remembered-approval.js +14 -0
  211. package/dist/headless/root.d.ts +30 -0
  212. package/dist/headless/root.js +99 -0
  213. package/dist/headless/save-edit.d.ts +2 -0
  214. package/dist/headless/save-edit.js +16 -0
  215. package/dist/headless/save-queued.d.ts +2 -0
  216. package/dist/headless/save-queued.js +15 -0
  217. package/dist/headless/send-now.d.ts +2 -0
  218. package/dist/headless/send-now.js +17 -0
  219. package/dist/headless/settings.d.ts +2 -0
  220. package/dist/headless/settings.js +10 -0
  221. package/dist/headless/skip-questions.d.ts +6 -0
  222. package/dist/headless/skip-questions.js +18 -0
  223. package/dist/headless/source-context.d.ts +5 -0
  224. package/dist/headless/source-context.js +9 -0
  225. package/dist/headless/source-link.d.ts +2 -0
  226. package/dist/headless/source-link.js +13 -0
  227. package/dist/headless/source-primitives.d.ts +1 -0
  228. package/dist/headless/source-primitives.js +7 -0
  229. package/dist/headless/source-root.d.ts +5 -0
  230. package/dist/headless/source-root.js +9 -0
  231. package/dist/headless/source-sheet-close.d.ts +2 -0
  232. package/dist/headless/source-sheet-close.js +12 -0
  233. package/dist/headless/source-sheet-content.d.ts +3 -0
  234. package/dist/headless/source-sheet-content.js +16 -0
  235. package/dist/headless/source-sheet-description.d.ts +2 -0
  236. package/dist/headless/source-sheet-description.js +12 -0
  237. package/dist/headless/source-sheet-root.d.ts +2 -0
  238. package/dist/headless/source-sheet-root.js +13 -0
  239. package/dist/headless/source-sheet-title.d.ts +2 -0
  240. package/dist/headless/source-sheet-title.js +12 -0
  241. package/dist/headless/source-sheet-trigger.d.ts +2 -0
  242. package/dist/headless/source-sheet-trigger.js +12 -0
  243. package/dist/headless/source-unavailable.d.ts +2 -0
  244. package/dist/headless/source-unavailable.js +9 -0
  245. package/dist/headless/sources.d.ts +14 -0
  246. package/dist/headless/sources.js +12 -0
  247. package/dist/headless/speaker.d.ts +13 -0
  248. package/dist/headless/speaker.js +10 -0
  249. package/dist/headless/step-boundary.d.ts +4 -0
  250. package/dist/headless/step-boundary.js +16 -0
  251. package/dist/headless/stop.d.ts +10 -0
  252. package/dist/headless/stop.js +18 -0
  253. package/dist/headless/stopped.d.ts +11 -0
  254. package/dist/headless/stopped.js +17 -0
  255. package/dist/headless/submit-answers.d.ts +3 -0
  256. package/dist/headless/submit-answers.js +12 -0
  257. package/dist/headless/submit.d.ts +23 -0
  258. package/dist/headless/submit.js +24 -0
  259. package/dist/headless/suggestion.d.ts +10 -0
  260. package/dist/headless/suggestion.js +14 -0
  261. package/dist/headless/suggestions.d.ts +8 -0
  262. package/dist/headless/suggestions.js +12 -0
  263. package/dist/headless/thread.d.ts +3 -0
  264. package/dist/headless/thread.js +25 -0
  265. package/dist/headless/timing.d.ts +5 -0
  266. package/dist/headless/timing.js +13 -0
  267. package/dist/headless/toggle-tool.d.ts +4 -0
  268. package/dist/headless/toggle-tool.js +15 -0
  269. package/dist/headless/tool-error.d.ts +4 -0
  270. package/dist/headless/tool-error.js +13 -0
  271. package/dist/headless/tool-input.d.ts +4 -0
  272. package/dist/headless/tool-input.js +13 -0
  273. package/dist/headless/tool-output.d.ts +4 -0
  274. package/dist/headless/tool-output.js +13 -0
  275. package/dist/headless/tool-renderer.d.ts +13 -0
  276. package/dist/headless/tool-renderer.js +15 -0
  277. package/dist/headless/transcript.d.ts +23 -0
  278. package/dist/headless/transcript.js +24 -0
  279. package/dist/headless/try-again.d.ts +2 -0
  280. package/dist/headless/try-again.js +24 -0
  281. package/dist/headless/unavailable.d.ts +8 -0
  282. package/dist/headless/unavailable.js +9 -0
  283. package/dist/headless/usage.d.ts +13 -0
  284. package/dist/headless/usage.js +15 -0
  285. package/dist/headless/use-merged-ref.d.ts +2 -0
  286. package/dist/headless/use-merged-ref.js +17 -0
  287. package/dist/headless/use-question.d.ts +3 -0
  288. package/dist/headless/use-question.js +9 -0
  289. package/dist/headless/waiting.d.ts +13 -0
  290. package/dist/headless/waiting.js +12 -0
  291. package/dist/headless/writing.d.ts +13 -0
  292. package/dist/headless/writing.js +12 -0
  293. package/dist/hooks/chat-refusal.d.ts +18 -0
  294. package/dist/hooks/chat-refusal.js +44 -0
  295. package/dist/hooks/turn-mailbox.d.ts +14 -0
  296. package/dist/hooks/turn-mailbox.js +114 -0
  297. package/dist/hooks/use-branches.d.ts +10 -0
  298. package/dist/hooks/use-branches.js +69 -0
  299. package/dist/hooks/use-chat-instance.d.ts +28 -0
  300. package/dist/hooks/use-chat-instance.js +44 -0
  301. package/dist/hooks/use-chat-settings.d.ts +11 -0
  302. package/dist/hooks/use-chat-settings.js +33 -0
  303. package/dist/hooks/use-chat-sink.d.ts +19 -0
  304. package/dist/hooks/use-chat-sink.js +56 -0
  305. package/dist/hooks/use-composer.d.ts +33 -0
  306. package/dist/hooks/use-composer.js +45 -0
  307. package/dist/hooks/use-context-usage.d.ts +8 -0
  308. package/dist/hooks/use-context-usage.js +14 -0
  309. package/dist/hooks/use-copied.d.ts +14 -0
  310. package/dist/hooks/use-copied.js +22 -0
  311. package/dist/hooks/use-draft.d.ts +6 -0
  312. package/dist/hooks/use-draft.js +38 -0
  313. package/dist/hooks/use-feedback.d.ts +8 -0
  314. package/dist/hooks/use-feedback.js +28 -0
  315. package/dist/hooks/use-follow.d.ts +15 -0
  316. package/dist/hooks/use-follow.js +30 -0
  317. package/dist/hooks/use-media-load.d.ts +5 -0
  318. package/dist/hooks/use-media-load.js +12 -0
  319. package/dist/hooks/use-media.d.ts +3 -0
  320. package/dist/hooks/use-media.js +9 -0
  321. package/dist/hooks/use-question-check.d.ts +11 -0
  322. package/dist/hooks/use-question-check.js +29 -0
  323. package/dist/hooks/use-question-draft.d.ts +34 -0
  324. package/dist/hooks/use-question-draft.js +57 -0
  325. package/dist/hooks/use-question-steps.d.ts +18 -0
  326. package/dist/hooks/use-question-steps.js +31 -0
  327. package/dist/hooks/use-question-write.d.ts +8 -0
  328. package/dist/hooks/use-question-write.js +25 -0
  329. package/dist/hooks/use-read-aloud.d.ts +8 -0
  330. package/dist/hooks/use-read-aloud.js +60 -0
  331. package/dist/hooks/use-reasoning.d.ts +8 -0
  332. package/dist/hooks/use-reasoning.js +32 -0
  333. package/dist/hooks/use-remembered-approvals.d.ts +9 -0
  334. package/dist/hooks/use-remembered-approvals.js +40 -0
  335. package/dist/hooks/use-reply.d.ts +3 -0
  336. package/dist/hooks/use-reply.js +9 -0
  337. package/dist/hooks/use-report-missing-configuration.d.ts +9 -0
  338. package/dist/hooks/use-report-missing-configuration.js +14 -0
  339. package/dist/hooks/use-retry-delay.d.ts +5 -0
  340. package/dist/hooks/use-retry-delay.js +17 -0
  341. package/dist/hooks/use-sent-draft.d.ts +8 -0
  342. package/dist/hooks/use-sent-draft.js +25 -0
  343. package/dist/hooks/use-source-disclosure.d.ts +5 -0
  344. package/dist/hooks/use-source-disclosure.js +9 -0
  345. package/dist/hooks/use-sources.d.ts +3 -0
  346. package/dist/hooks/use-sources.js +9 -0
  347. package/dist/hooks/use-tool-approval-memory.d.ts +8 -0
  348. package/dist/hooks/use-tool-approval-memory.js +16 -0
  349. package/dist/hooks/use-tool-approval.d.ts +10 -0
  350. package/dist/hooks/use-tool-approval.js +26 -0
  351. package/dist/hooks/use-turn-queue.d.ts +32 -0
  352. package/dist/hooks/use-turn-queue.js +33 -0
  353. package/dist/index.d.ts +10 -0
  354. package/dist/index.js +5 -0
  355. package/dist/next.d.ts +43 -0
  356. package/dist/next.js +10 -0
  357. package/dist/services/approval-memory.d.ts +9 -0
  358. package/dist/services/approval-memory.js +32 -0
  359. package/dist/services/approval.d.ts +14 -0
  360. package/dist/services/approval.js +37 -0
  361. package/dist/services/branches.d.ts +27 -0
  362. package/dist/services/branches.js +131 -0
  363. package/dist/services/chat-session.d.ts +20 -0
  364. package/dist/services/chat-session.js +61 -0
  365. package/dist/services/choices.d.ts +31 -0
  366. package/dist/services/choices.js +39 -0
  367. package/dist/services/continue.d.ts +8 -0
  368. package/dist/services/continue.js +24 -0
  369. package/dist/services/errors.d.ts +52 -0
  370. package/dist/services/errors.js +54 -0
  371. package/dist/services/media.d.ts +9 -0
  372. package/dist/services/media.js +19 -0
  373. package/dist/services/messages.d.ts +44 -0
  374. package/dist/services/messages.js +0 -0
  375. package/dist/services/optional.d.ts +7 -0
  376. package/dist/services/optional.js +7 -0
  377. package/dist/services/ports.d.ts +31 -0
  378. package/dist/services/ports.js +0 -0
  379. package/dist/services/questions.d.ts +67 -0
  380. package/dist/services/questions.js +119 -0
  381. package/dist/services/request.d.ts +26 -0
  382. package/dist/services/request.js +85 -0
  383. package/dist/services/selection.d.ts +10 -0
  384. package/dist/services/selection.js +49 -0
  385. package/dist/services/sources.d.ts +11 -0
  386. package/dist/services/sources.js +29 -0
  387. package/dist/services/tools.d.ts +11 -0
  388. package/dist/services/tools.js +0 -0
  389. package/dist/services/turn.d.ts +84 -0
  390. package/dist/services/turn.js +0 -0
  391. package/dist/services/types.d.ts +23 -0
  392. package/dist/services/types.js +15 -0
  393. package/package.json +822 -0
@@ -0,0 +1,99 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useChatSettings } from "../hooks/use-chat-settings.js";
4
+ import { useBranches } from "../hooks/use-branches.js";
5
+ import { useToolApprovalMemory } from "../hooks/use-tool-approval-memory.js";
6
+ import { useRememberedApprovals } from "../hooks/use-remembered-approvals.js";
7
+ import { MessageScroller } from "@shadcn/react/message-scroller";
8
+ import { useChat } from "@ai-sdk/react";
9
+ import { useCallback, useContext } from "react";
10
+ import { SinkProvider } from "@slices.sh/composer";
11
+ import { useChatInstance } from "../hooks/use-chat-instance.js";
12
+ import { useComposer } from "../hooks/use-composer.js";
13
+ import { useFollow } from "../hooks/use-follow.js";
14
+ import { useReply } from "../hooks/use-reply.js";
15
+ import { useTurnQueue } from "../hooks/use-turn-queue.js";
16
+ import { Provide } from "@slices.sh/core/part";
17
+ import { useChatSink } from "../hooks/use-chat-sink.js";
18
+ import {
19
+ SettingsContext,
20
+ FeedbackOptionsContext,
21
+ BranchContext,
22
+ ApprovalMemoryContext,
23
+ ApprovalAutomationContext,
24
+ ChatContext,
25
+ ChatConfigContext,
26
+ ComposerContext,
27
+ ComposerStandaloneContext,
28
+ FollowContext,
29
+ QueueContext,
30
+ SourceContext
31
+ } from "./contexts.js";
32
+ function Root(props) {
33
+ const outer = useContext(ChatContext);
34
+ const outerConfig = useContext(ChatConfigContext);
35
+ if (outer && !props.chat && (props.config === void 0 || props.config === outerConfig)) {
36
+ return /* @__PURE__ */ jsx(ComposerStandaloneContext, { value: "embedded", children: props.children });
37
+ }
38
+ return /* @__PURE__ */ jsx(MessageScroller.Provider, { autoScroll: true, defaultScrollPosition: "last-anchor", scrollPreviousItemPeek: 64, children: /* @__PURE__ */ jsx(Session, { ...props }) });
39
+ }
40
+ function Session({
41
+ config,
42
+ enabled,
43
+ name = config ?? "default",
44
+ chat: given,
45
+ settings: givenSettings,
46
+ queue = true,
47
+ rememberApprovals = true,
48
+ onFeedback,
49
+ children
50
+ }) {
51
+ const { chat, source, settings: ownSettings } = useChatInstance(name, given, { config, enabled });
52
+ const { status, messages } = useChat({ chat });
53
+ const waiting = useTurnQueue(chat);
54
+ const settings = useChatSettings(chat, given ? givenSettings ?? null : ownSettings, waiting.waiting);
55
+ const branches = useBranches(chat, source !== "missing" && waiting.waiting === 0);
56
+ const approvals = useToolApprovalMemory(chat, rememberApprovals);
57
+ const automation = useRememberedApprovals(chat, approvals);
58
+ const send = useReply(chat);
59
+ const stop = useCallback(() => {
60
+ if (chat.status !== "submitted" && chat.status !== "streaming") return false;
61
+ void chat.stop();
62
+ return true;
63
+ }, [chat]);
64
+ const composer = useComposer({
65
+ scope: chat,
66
+ onStop: stop,
67
+ onRemoveLast: settings.removeLast,
68
+ onSend: queue ? waiting.enqueue : send,
69
+ // Nothing answers a chat with no backend, and with no queue the composer is what refuses
70
+ // a second message: one turn at a time is a property of the chat, and the person should
71
+ // see which control is holding it.
72
+ disabled: source === "missing" || !queue && (status === "submitted" || status === "streaming")
73
+ });
74
+ const sink = useChatSink({ chat, source, config, queue, enqueue: waiting.enqueue, stop, removeLast: settings.removeLast });
75
+ const follow = useFollow(messages.findLast((message) => message.role === "user")?.id);
76
+ return /* @__PURE__ */ jsx(
77
+ Provide,
78
+ {
79
+ values: [
80
+ [ChatContext, chat],
81
+ [ChatConfigContext, config ?? "default"],
82
+ [ComposerStandaloneContext, "standalone"],
83
+ [SettingsContext, settings],
84
+ [FeedbackOptionsContext, { onFeedback }],
85
+ [BranchContext, branches],
86
+ [ApprovalMemoryContext, approvals],
87
+ [ApprovalAutomationContext, automation],
88
+ [SourceContext, source],
89
+ [ComposerContext, composer],
90
+ [FollowContext, follow],
91
+ [QueueContext, waiting]
92
+ ],
93
+ children: /* @__PURE__ */ jsx(SinkProvider, { value: sink, children })
94
+ }
95
+ );
96
+ }
97
+ export {
98
+ Root
99
+ };
@@ -0,0 +1,2 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ export declare function SaveEdit(props: PartProps<"button">): import("react").ReactNode;
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import { usePart, useRequired } from "@slices.sh/core/part";
3
+ import { BranchContext, MessageScope, SentDraftContext } from "./contexts.js";
4
+ function SaveEdit(props) {
5
+ const branches = useRequired(BranchContext, "Chat.SaveEdit requires Chat.Root.");
6
+ const message = useRequired(MessageScope, "Chat.SaveEdit requires Chat.Messages.");
7
+ const draft = useRequired(SentDraftContext, "Chat.SaveEdit requires Chat.MessageEditRoot.");
8
+ const empty = !draft.value?.trim() && !message.parts.some((part) => part.type === "file");
9
+ return usePart("button", props, {
10
+ defaults: { type: "submit" },
11
+ locked: { disabled: branches.blocked || draft.value === null || empty }
12
+ });
13
+ }
14
+ export {
15
+ SaveEdit
16
+ };
@@ -0,0 +1,2 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ export declare function SaveQueued(props: PartProps<"button">): import("react").ReactNode;
@@ -0,0 +1,15 @@
1
+ "use client";
2
+ import { usePart, useRequired } from "@slices.sh/core/part";
3
+ import { QueueContext, QueueScope } from "./contexts.js";
4
+ function SaveQueued(props) {
5
+ const queue = useRequired(QueueContext, "Chat.SaveQueued requires Chat.Root.");
6
+ const item = useRequired(QueueScope, "Chat.SaveQueued requires Chat.QueueItems.");
7
+ return usePart("button", props, {
8
+ defaults: { type: "button" },
9
+ locked: { disabled: item.draft === null || !item.draft.trim() && !item.files?.length },
10
+ behavior: { onClick: () => queue.change({ type: "save-edit", id: item.id }) }
11
+ });
12
+ }
13
+ export {
14
+ SaveQueued
15
+ };
@@ -0,0 +1,2 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ export declare function SendNow(props: PartProps<"button">): import("react").ReactNode;
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import { usePart, useRequired } from "@slices.sh/core/part";
3
+ import { QueueContext, QueueScope } from "./contexts.js";
4
+ function SendNow(props) {
5
+ const queue = useRequired(QueueContext, "Chat.SendNow requires Chat.Root.");
6
+ const item = useRequired(QueueScope, "Chat.SendNow requires Chat.QueueItems.");
7
+ return usePart("button", props, {
8
+ defaults: { type: "button" },
9
+ // An open question is no reason to wait: sending now skips it and sends this as the reply.
10
+ // A tool decision is one, and its buttons are in the transcript.
11
+ locked: { disabled: queue.blockedBy !== null && queue.blockedBy !== "question" || item.draft !== null },
12
+ behavior: { onClick: () => queue.change({ type: "send-now", id: item.id }) }
13
+ });
14
+ }
15
+ export {
16
+ SendNow
17
+ };
@@ -0,0 +1,2 @@
1
+ import { type GateProps } from "@slices.sh/core/part";
2
+ export declare function Settings({ children }: GateProps): import("react").ReactNode;
@@ -0,0 +1,10 @@
1
+ "use client";
2
+ import { useRequired } from "@slices.sh/core/part";
3
+ import { SettingsContext } from "./contexts.js";
4
+ function Settings({ children }) {
5
+ const { choices } = useRequired(SettingsContext, "Chat.Settings requires Chat.Root.");
6
+ return choices && (choices.models?.length || choices.tools?.length) ? children : null;
7
+ }
8
+ export {
9
+ Settings
10
+ };
@@ -0,0 +1,6 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ /**
3
+ * Dismisses the open question without answering it. The queue decides what the model hears next:
4
+ * the message the person typed meanwhile, as their reply, or else a nudge to carry on.
5
+ */
6
+ export declare function SkipQuestions(props: PartProps<"button">): import("react").ReactNode;
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { isToolUIPart } from "ai";
3
+ import { usePart, useRequired } from "@slices.sh/core/part";
4
+ import { PartScope, QueueContext, QuestionWriteContext } from "./contexts.js";
5
+ function SkipQuestions(props) {
6
+ const queue = useRequired(QueueContext, "Chat.SkipQuestions requires Chat.Root.");
7
+ const write = useRequired(QuestionWriteContext, "Chat.SkipQuestions requires Chat.PartQuestion.");
8
+ const part = useRequired(PartScope, "Chat.SkipQuestions requires Chat.Parts.");
9
+ const id = isToolUIPart(part) ? part.toolCallId : null;
10
+ return usePart("button", props, {
11
+ defaults: { type: "button" },
12
+ locked: { disabled: write.pending || id === null },
13
+ behavior: { onClick: () => id !== null && queue.change({ type: "skip-question", toolCallId: id }) }
14
+ });
15
+ }
16
+ export {
17
+ SkipQuestions
18
+ };
@@ -0,0 +1,5 @@
1
+ import type { ChatSource } from "../services/types";
2
+ import type { SourceDisclosure } from "../hooks/use-source-disclosure";
3
+ export declare const SourceScope: import("react").Context<ChatSource | null>;
4
+ export declare const CitationDisclosureContext: import("react").Context<SourceDisclosure | null>;
5
+ export declare const SourceSheetContext: import("react").Context<SourceDisclosure | null>;
@@ -0,0 +1,9 @@
1
+ import { createContext } from "react";
2
+ const SourceScope = createContext(null);
3
+ const CitationDisclosureContext = createContext(null);
4
+ const SourceSheetContext = createContext(null);
5
+ export {
6
+ CitationDisclosureContext,
7
+ SourceScope,
8
+ SourceSheetContext
9
+ };
@@ -0,0 +1,2 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ export declare function SourceLink(props: PartProps<"a">): import("react").ReactNode;
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import { usePart, useRequired } from "@slices.sh/core/part";
3
+ import { SourceScope } from "./source-context.js";
4
+ function SourceLink(props) {
5
+ const source = useRequired(SourceScope, "Chat.SourceLink requires Chat.SourceRoot.");
6
+ const element = usePart("a", props, {
7
+ locked: { href: source.href ?? void 0, target: "_blank", rel: "noopener noreferrer" }
8
+ });
9
+ return source.href ? element : null;
10
+ }
11
+ export {
12
+ SourceLink
13
+ };
@@ -0,0 +1 @@
1
+ export { Popover, Dialog, MotionPopover, MotionDialog } from "@slices.sh/core/motion-base-ui";
@@ -0,0 +1,7 @@
1
+ import { Popover, Dialog, MotionPopover, MotionDialog } from "@slices.sh/core/motion-base-ui";
2
+ export {
3
+ Dialog,
4
+ MotionDialog,
5
+ MotionPopover,
6
+ Popover
7
+ };
@@ -0,0 +1,5 @@
1
+ import type { ChatSource } from "../services/types";
2
+ import type { RootProps } from "@slices.sh/core/part";
3
+ export declare function SourceRoot({ source, children }: RootProps & {
4
+ source: ChatSource;
5
+ }): import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { SourceScope } from "./source-context.js";
4
+ function SourceRoot({ source, children }) {
5
+ return /* @__PURE__ */ jsx(SourceScope, { value: source, children });
6
+ }
7
+ export {
8
+ SourceRoot
9
+ };
@@ -0,0 +1,2 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ export declare function SourceSheetClose(props: PartProps<"button">): string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react").JSX.Element | null | undefined;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { isValidElement } from "react";
4
+ import { Dialog } from "./source-primitives.js";
5
+ import { usePart } from "@slices.sh/core/part";
6
+ function SourceSheetClose(props) {
7
+ const element = usePart("button", props);
8
+ return isValidElement(element) ? /* @__PURE__ */ jsx(Dialog.Close, { render: element }) : element;
9
+ }
10
+ export {
11
+ SourceSheetClose
12
+ };
@@ -0,0 +1,3 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ /** The skin's surface preserves the corresponding Motion primitive adapter. */
3
+ export declare function SourceSheetContent(props: PartProps<"div">): import("react").ReactNode;
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { MotionDialog } from "./source-primitives.js";
4
+ import { usePart, useRequired } from "@slices.sh/core/part";
5
+ import { SourceSheetContext } from "./source-context.js";
6
+ function SourceSheetContent(props) {
7
+ const disclosure = useRequired(SourceSheetContext, "Chat.SourceSheetContent requires Chat.SourceSheetRoot.");
8
+ return usePart(
9
+ "div",
10
+ { ...props, render: props.render ?? /* @__PURE__ */ jsx(MotionDialog, {}) },
11
+ { locked: { open: disclosure.open } }
12
+ );
13
+ }
14
+ export {
15
+ SourceSheetContent
16
+ };
@@ -0,0 +1,2 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ export declare function SourceSheetDescription(props: PartProps<"p">): string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react").JSX.Element | null | undefined;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { isValidElement } from "react";
4
+ import { Dialog } from "./source-primitives.js";
5
+ import { usePart } from "@slices.sh/core/part";
6
+ function SourceSheetDescription(props) {
7
+ const element = usePart("p", props);
8
+ return isValidElement(element) ? /* @__PURE__ */ jsx(Dialog.Description, { render: element }) : element;
9
+ }
10
+ export {
11
+ SourceSheetDescription
12
+ };
@@ -0,0 +1,2 @@
1
+ import { type RootProps } from "@slices.sh/core/part";
2
+ export declare function SourceSheetRoot({ children }: RootProps): import("react").JSX.Element;
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { Dialog } from "./source-primitives.js";
4
+ import { useSourceDisclosure } from "../hooks/use-source-disclosure.js";
5
+ import { Provide } from "@slices.sh/core/part";
6
+ import { SourceSheetContext } from "./source-context.js";
7
+ function SourceSheetRoot({ children }) {
8
+ const disclosure = useSourceDisclosure();
9
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: disclosure.open, onOpenChange: disclosure.setOpen, children: /* @__PURE__ */ jsx(Provide, { values: [[SourceSheetContext, disclosure]], children }) });
10
+ }
11
+ export {
12
+ SourceSheetRoot
13
+ };
@@ -0,0 +1,2 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ export declare function SourceSheetTitle(props: PartProps<"h2">): string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react").JSX.Element | null | undefined;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { isValidElement } from "react";
4
+ import { Dialog } from "./source-primitives.js";
5
+ import { usePart } from "@slices.sh/core/part";
6
+ function SourceSheetTitle(props) {
7
+ const element = usePart("h2", props);
8
+ return isValidElement(element) ? /* @__PURE__ */ jsx(Dialog.Title, { render: element }) : element;
9
+ }
10
+ export {
11
+ SourceSheetTitle
12
+ };
@@ -0,0 +1,2 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ export declare function SourceSheetTrigger(props: PartProps<"button">): string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react").JSX.Element | null | undefined;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { isValidElement } from "react";
4
+ import { Dialog } from "./source-primitives.js";
5
+ import { usePart } from "@slices.sh/core/part";
6
+ function SourceSheetTrigger(props) {
7
+ const element = usePart("button", props);
8
+ return isValidElement(element) ? /* @__PURE__ */ jsx(Dialog.Trigger, { render: element }) : element;
9
+ }
10
+ export {
11
+ SourceSheetTrigger
12
+ };
@@ -0,0 +1,2 @@
1
+ import { type GateProps } from "@slices.sh/core/part";
2
+ export declare function SourceUnavailable({ children }: GateProps): import("react").ReactNode;
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { useRequired } from "@slices.sh/core/part";
3
+ import { SourceScope } from "./source-context.js";
4
+ function SourceUnavailable({ children }) {
5
+ return useRequired(SourceScope, "Chat.SourceUnavailable requires Chat.SourceRoot.").href ? null : children;
6
+ }
7
+ export {
8
+ SourceUnavailable
9
+ };
@@ -0,0 +1,14 @@
1
+ import type { SourceUrlUIPart } from "ai";
2
+ import { type GateProps } from "@slices.sh/core/part";
3
+ /**
4
+ * What the answer was drawn from, the SDK's `source-url` parts, collected.
5
+ *
6
+ * A footer rather than a part in the flow: citations arrive interleaved with the prose and
7
+ * read as an appendix, and a reader who wants them wants all of them at once. A document
8
+ * source has no URL to open, and a citation nobody can follow is a row that looks like a
9
+ * link and is not one. Nothing is rendered where the backend sent none, which is most
10
+ * backends.
11
+ */
12
+ export declare function Sources({ children }: GateProps<{
13
+ sources: SourceUrlUIPart[];
14
+ }>): import("react").ReactNode;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import { useRequired } from "@slices.sh/core/part";
3
+ import { MessageScope } from "./contexts.js";
4
+ import { gateContent } from "./gate-content.js";
5
+ function Sources({ children }) {
6
+ const message = useRequired(MessageScope, "Chat.Sources must be inside <Chat.Messages>.");
7
+ const sources = message.parts.filter((part) => part.type === "source-url");
8
+ return sources.length > 0 ? gateContent(children, { sources }) : null;
9
+ }
10
+ export {
11
+ Sources
12
+ };
@@ -0,0 +1,13 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ import type { AiChatMessage } from "../services/types";
3
+ /**
4
+ * Who said it, in words.
5
+ *
6
+ * Colour and alignment are the only thing that told the two apart, which is nothing at all
7
+ * to a screen reader and very little on a low-contrast theme. The default skin hides this
8
+ * visually and leaves it in the accessibility tree, where it is the difference between a
9
+ * conversation and a run of anonymous paragraphs.
10
+ */
11
+ export declare function Speaker(props: PartProps<"span", {
12
+ role: AiChatMessage["role"];
13
+ }>): import("react").ReactNode;
@@ -0,0 +1,10 @@
1
+ "use client";
2
+ import { usePart, useRequired } from "@slices.sh/core/part";
3
+ import { MessageScope } from "./contexts.js";
4
+ function Speaker(props) {
5
+ const message = useRequired(MessageScope, "Chat.Speaker must be inside <Chat.Messages>.");
6
+ return usePart("span", props, { state: { role: message.role } });
7
+ }
8
+ export {
9
+ Speaker
10
+ };
@@ -0,0 +1,4 @@
1
+ import { type GateProps } from "@slices.sh/core/part";
2
+ export declare function StepBoundary({ children }: GateProps<{
3
+ number: number;
4
+ }>): import("react").ReactNode;
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import { useRequired } from "@slices.sh/core/part";
3
+ import { MessageScope, PartScope } from "./contexts.js";
4
+ import { gateContent } from "./gate-content.js";
5
+ function StepBoundary({ children }) {
6
+ const part = useRequired(PartScope, "Chat.StepBoundary requires Chat.Parts.");
7
+ const message = useRequired(MessageScope, "Chat.StepBoundary requires Chat.Messages.");
8
+ if (part.type !== "step-start") return null;
9
+ const index = message.parts.indexOf(part);
10
+ return gateContent(children, {
11
+ number: message.parts.slice(0, index + 1).filter((p) => p.type === "step-start").length
12
+ });
13
+ }
14
+ export {
15
+ StepBoundary
16
+ };
@@ -0,0 +1,10 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ /**
3
+ * Stops a reply that is streaming. Stopping is the chat's own behaviour, so it is not a mode
4
+ * of `Composer.Submit`: no generic part can express it.
5
+ *
6
+ * It is disabled while nothing streams, never unmounted: a button that came and went with
7
+ * every turn moved the controls beside it under a cursor already on its way, and dropped
8
+ * focus to the body when the turn ended with it focused.
9
+ */
10
+ export declare function Stop(props: PartProps<"button">): import("react").ReactNode;
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { useChat } from "@ai-sdk/react";
3
+ import { usePart, useRequired } from "@slices.sh/core/part";
4
+ import { ChatContext } from "./contexts.js";
5
+ function Stop(props) {
6
+ const chat = useRequired(ChatContext, "Chat.Stop must be inside <Chat.Root>.");
7
+ const { status, stop } = useChat({ chat });
8
+ const running = status === "submitted" || status === "streaming";
9
+ return usePart("button", props, {
10
+ defaults: { type: "button" },
11
+ behavior: { onClick: () => void stop() },
12
+ locked: { type: "button", disabled: !running },
13
+ attributes: { active: running }
14
+ });
15
+ }
16
+ export {
17
+ Stop
18
+ };
@@ -0,0 +1,11 @@
1
+ import { type GateProps } from "@slices.sh/core/part";
2
+ /**
3
+ * This reply was cut off, and somebody should be told in words.
4
+ *
5
+ * Fading the text was the whole account of it before, which is a contrast regression that
6
+ * says nothing: the reader could not tell whether they had stopped it, the model had, or
7
+ * the network went. → components/headless/ai-chat/writing.ts
8
+ */
9
+ export declare function Stopped({ children }: GateProps<{
10
+ reason: "length" | "interrupted";
11
+ }>): import("react").ReactNode;
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import { useChat } from "@ai-sdk/react";
3
+ import { useRequired } from "@slices.sh/core/part";
4
+ import { gateContent } from "./gate-content.js";
5
+ import { ChatContext, MessageScope } from "./contexts.js";
6
+ import { isCutOff, isWriting } from "./writing.js";
7
+ function Stopped({ children }) {
8
+ const message = useRequired(MessageScope, "Chat.Stopped must be inside <Chat.Messages>.");
9
+ const chat = useRequired(ChatContext, "Chat.Stopped must be inside <Chat.Root>.");
10
+ const { messages, status } = useChat({ chat });
11
+ return isCutOff(message, isWriting(message, messages, status)) ? gateContent(children, {
12
+ reason: message.metadata?.finishReason === "length" ? "length" : "interrupted"
13
+ }) : null;
14
+ }
15
+ export {
16
+ Stopped
17
+ };
@@ -0,0 +1,3 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ /** On the last question only: before it, Next is the way on. */
3
+ export declare function SubmitAnswers(props: PartProps<"button">): import("react").ReactNode;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import { usePart, useRequired } from "@slices.sh/core/part";
3
+ import { QuestionStepsContext, QuestionWriteContext } from "./contexts.js";
4
+ function SubmitAnswers(props) {
5
+ const write = useRequired(QuestionWriteContext, "Chat.SubmitAnswers requires Chat.PartQuestion.");
6
+ const steps = useRequired(QuestionStepsContext, "Chat.SubmitAnswers requires Chat.PartQuestion.");
7
+ const element = usePart("button", props, { locked: { type: "submit", disabled: write.pending } });
8
+ return steps.index === steps.count - 1 ? element : null;
9
+ }
10
+ export {
11
+ SubmitAnswers
12
+ };
@@ -0,0 +1,23 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ /**
3
+ * One control that sends, and stops what it sent with the SDK's `stop`.
4
+ *
5
+ * The composer's only submit, and the only button that ever occupies this spot. A separate
6
+ * stop button had to appear between send and its neighbour mid-turn, which moved the most
7
+ * used control in the component under a cursor already on its way down; it also unmounted
8
+ * itself the instant the turn ended, dropping focus to the body if anyone had tabbed to it.
9
+ * Morphing solves both: the element is the same element, and it is `type="submit"` only
10
+ * while submitting is what it does. → docs/rules/one-submit-per-form.md
11
+ *
12
+ * It stops an answer while there is nothing to send, and sends while there is — which is
13
+ * the only reading that leaves the queue reachable by touch. Otherwise the one button
14
+ * beside the box said "stop" the whole time an answer was arriving, so a follow-up typed
15
+ * on a phone could be sent only from the software keyboard's own return key, and the
16
+ * control right next to it did something else. Where the composer refuses a second message
17
+ * outright (`queue` off) there is nothing to send by definition, so this is stop again.
18
+ *
19
+ * @deprecated Chat.Submit becomes Composer.Submit, and its stopping half is Chat.Stop.
20
+ */
21
+ export declare function Submit(props: PartProps<"button", {
22
+ stopping: boolean;
23
+ }>): import("react").ReactNode;
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { useContext } from "react";
3
+ import { useChat } from "@ai-sdk/react";
4
+ import { usePart, useRequired } from "@slices.sh/core/part";
5
+ import { ChatContext, ComposerContext, ComposerAttachmentsContext } from "./contexts.js";
6
+ function Submit(props) {
7
+ const chat = useRequired(ChatContext, "Chat.Submit must be inside <Chat.Root>.");
8
+ const composer = useRequired(ComposerContext, "Chat.Submit must be inside <Chat.Root>.");
9
+ const { status, stop } = useChat({ chat });
10
+ const running = status === "submitted" || status === "streaming";
11
+ const attachments = useContext(ComposerAttachmentsContext);
12
+ const sendable = (composer.draft.trim().length > 0 || (attachments?.count ?? 0) > 0) && !composer.disabled && !attachments?.blocked;
13
+ const stopping = running && !sendable;
14
+ return usePart("button", props, {
15
+ state: { stopping },
16
+ defaults: { type: "submit" },
17
+ behavior: { onClick: stopping ? () => void stop() : void 0 },
18
+ locked: { type: stopping ? "button" : "submit", disabled: !stopping && !sendable },
19
+ attributes: { active: stopping }
20
+ });
21
+ }
22
+ export {
23
+ Submit
24
+ };
@@ -0,0 +1,10 @@
1
+ import { type PartProps } from "@slices.sh/core/part";
2
+ type SuggestionProps = PartProps<"button"> & {
3
+ text: string;
4
+ };
5
+ /**
6
+ * Sends its own text. It goes through the composer rather than the chat, so a suggestion
7
+ * queued behind a running turn waits exactly as a typed message does.
8
+ */
9
+ export declare function Suggestion({ text, ...props }: SuggestionProps): import("react").ReactNode;
10
+ export {};