@adecore/agents-react 0.31.12 → 0.33.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 (409) hide show
  1. package/README.md +1 -1
  2. package/dist/agents/AccountDot.js +57 -6
  3. package/dist/agents/AgentIcon.js +88 -12
  4. package/dist/agents/ModelOptionControl.js +153 -18
  5. package/dist/agents/ProviderLogo.js +49 -4
  6. package/dist/agents/account-limits.js +17 -14
  7. package/dist/agents/accounts.js +99 -67
  8. package/dist/agents/agent-marks.js +5 -3
  9. package/dist/agents/model-name.js +42 -31
  10. package/dist/agents/model-options.js +8 -8
  11. package/dist/agents/model-requirement.js +17 -14
  12. package/dist/agents/option-words.d.ts +7 -0
  13. package/dist/agents/option-words.js +35 -0
  14. package/dist/agents/provider-paths.js +6 -6
  15. package/dist/agents/status-look.js +32 -12
  16. package/dist/chat/account-choice.d.ts +13 -0
  17. package/dist/chat/account-choice.js +90 -20
  18. package/dist/chat/actions.js +126 -59
  19. package/dist/chat/activity.js +5 -5
  20. package/dist/chat/attachments.js +74 -53
  21. package/dist/chat/bookmarks.js +58 -48
  22. package/dist/chat/chat-client.js +344 -263
  23. package/dist/chat/chat-references.js +3 -3
  24. package/dist/chat/composer-effort.d.ts +5 -0
  25. package/dist/chat/composer-effort.js +26 -0
  26. package/dist/chat/composer-send.js +13 -13
  27. package/dist/chat/drafts.js +115 -79
  28. package/dist/chat/forks.js +81 -24
  29. package/dist/chat/guards.js +15 -43
  30. package/dist/chat/index.d.ts +3 -1
  31. package/dist/chat/index.js +3 -2
  32. package/dist/chat/logic/ansi.js +170 -167
  33. package/dist/chat/logic/answers.js +2 -2
  34. package/dist/chat/logic/bookmarks.js +19 -19
  35. package/dist/chat/logic/command-looks.js +138 -96
  36. package/dist/chat/logic/context-usage.js +13 -9
  37. package/dist/chat/logic/continue-after-stop.js +15 -19
  38. package/dist/chat/logic/effort.d.ts +14 -0
  39. package/dist/chat/logic/effort.js +34 -0
  40. package/dist/chat/logic/embedded-code.js +387 -326
  41. package/dist/chat/logic/fork.js +134 -110
  42. package/dist/chat/logic/generated-image.js +54 -23
  43. package/dist/chat/logic/goal.js +28 -20
  44. package/dist/chat/logic/handback.js +6 -6
  45. package/dist/chat/logic/json.js +2 -2
  46. package/dist/chat/logic/limit.js +46 -30
  47. package/dist/chat/logic/picker-entries.d.ts +5 -3
  48. package/dist/chat/logic/picker-entries.js +83 -43
  49. package/dist/chat/logic/resume-compaction.d.ts +14 -1
  50. package/dist/chat/logic/resume-compaction.js +93 -24
  51. package/dist/chat/logic/scrubber.js +188 -136
  52. package/dist/chat/logic/thought.js +13 -16
  53. package/dist/chat/logic/thread-cards.js +60 -48
  54. package/dist/chat/logic/timeline-copy.js +30 -38
  55. package/dist/chat/logic/timeline-target.js +92 -63
  56. package/dist/chat/logic/timeline.js +499 -355
  57. package/dist/chat/logic/tool-catalog.js +54 -34
  58. package/dist/chat/logic/tools.js +106 -82
  59. package/dist/chat/logic/visual-height.js +18 -18
  60. package/dist/chat/logic/visual-viewport.js +6 -3
  61. package/dist/chat/logic/welcome.js +9 -9
  62. package/dist/chat/logic/workflow.d.ts +10 -0
  63. package/dist/chat/logic/workflow.js +130 -32
  64. package/dist/chat/mentions.js +149 -109
  65. package/dist/chat/persisted-json.js +51 -54
  66. package/dist/chat/preferences.d.ts +4 -0
  67. package/dist/chat/preferences.js +162 -84
  68. package/dist/chat/prompt-hold.js +9 -9
  69. package/dist/chat/quote.js +21 -30
  70. package/dist/chat/reading-width.js +12 -10
  71. package/dist/chat/recent-messages.js +34 -21
  72. package/dist/chat/resume-compaction-dismissals.js +25 -5
  73. package/dist/chat/runtime-modes.js +3 -3
  74. package/dist/chat/send-key.js +11 -7
  75. package/dist/chat/stash.js +89 -69
  76. package/dist/chat/subagent-conversation.js +181 -139
  77. package/dist/chat/subagent-list.js +65 -67
  78. package/dist/chat/subagent-support.js +12 -7
  79. package/dist/chat/subagent-view.js +132 -44
  80. package/dist/chat/thumbnails.js +88 -60
  81. package/dist/chat/timeline-flash.js +24 -12
  82. package/dist/chat/timeline-scroll.js +116 -86
  83. package/dist/chat/ui/AccountPill.js +126 -15
  84. package/dist/chat/ui/AnsiOutput.js +62 -6
  85. package/dist/chat/ui/BookmarkMarker.js +231 -41
  86. package/dist/chat/ui/BookmarkSubmenu.js +165 -18
  87. package/dist/chat/ui/ChatActivity.js +649 -70
  88. package/dist/chat/ui/ChatReferenceChip.js +104 -9
  89. package/dist/chat/ui/CodeBlock.js +132 -58
  90. package/dist/chat/ui/Composer.js +866 -132
  91. package/dist/chat/ui/ComposerInput.js +309 -120
  92. package/dist/chat/ui/DiffPool.js +75 -14
  93. package/dist/chat/ui/EditDiff.js +160 -21
  94. package/dist/chat/ui/FadingWords.js +32 -3
  95. package/dist/chat/ui/GoalDock.js +235 -42
  96. package/dist/chat/ui/ImageView.js +617 -61
  97. package/dist/chat/ui/LimitState.js +446 -72
  98. package/dist/chat/ui/Markdown.js +991 -173
  99. package/dist/chat/ui/MermaidBlock.js +285 -79
  100. package/dist/chat/ui/MessageActions.js +251 -39
  101. package/dist/chat/ui/ModelMarks.js +55 -5
  102. package/dist/chat/ui/Pickers.js +664 -113
  103. package/dist/chat/ui/PromptComposer.js +281 -51
  104. package/dist/chat/ui/QuoteButton.js +151 -57
  105. package/dist/chat/ui/ResumeCompactionDock.d.ts +6 -2
  106. package/dist/chat/ui/ResumeCompactionDock.js +141 -6
  107. package/dist/chat/ui/RowTime.js +59 -5
  108. package/dist/chat/ui/RunSettings.js +1744 -154
  109. package/dist/chat/ui/Scrubber.js +517 -88
  110. package/dist/chat/ui/ShellCommand.js +183 -107
  111. package/dist/chat/ui/SubagentControls.js +212 -24
  112. package/dist/chat/ui/SubagentInfo.js +170 -13
  113. package/dist/chat/ui/SubagentStopButton.js +115 -24
  114. package/dist/chat/ui/SubagentTimeline.js +357 -91
  115. package/dist/chat/ui/Timeline.js +988 -476
  116. package/dist/chat/ui/TimelineMenu.js +552 -37
  117. package/dist/chat/ui/UnifiedDiff.js +234 -27
  118. package/dist/chat/ui/UploadThumb.js +37 -7
  119. package/dist/chat/ui/VisualDialogs.js +251 -20
  120. package/dist/chat/ui/VisualFrame.js +321 -95
  121. package/dist/chat/ui/Welcome.js +72 -7
  122. package/dist/chat/ui/chips.js +1 -1
  123. package/dist/chat/ui/code-lines.js +36 -36
  124. package/dist/chat/ui/code-streaming.js +1 -1
  125. package/dist/chat/ui/code-theme.js +7 -7
  126. package/dist/chat/ui/composer/ComposerControls.js +329 -21
  127. package/dist/chat/ui/composer/ComposerMenu.js +358 -30
  128. package/dist/chat/ui/composer/DraftParts.js +185 -11
  129. package/dist/chat/ui/composer/QueuedMessages.js +138 -13
  130. package/dist/chat/ui/composer/chips.js +29 -19
  131. package/dist/chat/ui/composer/editor.js +79 -63
  132. package/dist/chat/ui/composer/insert.js +26 -12
  133. package/dist/chat/ui/composer/key-handler.js +180 -127
  134. package/dist/chat/ui/composer/keys.js +90 -73
  135. package/dist/chat/ui/composer/menu-aria.js +18 -9
  136. package/dist/chat/ui/composer/placeholder.js +78 -31
  137. package/dist/chat/ui/composer/surface.js +13 -37
  138. package/dist/chat/ui/composer/use-chat-controls.js +230 -90
  139. package/dist/chat/ui/composer/use-compaction-offer.js +50 -18
  140. package/dist/chat/ui/composer/use-composer-draft.js +65 -34
  141. package/dist/chat/ui/composer/use-composer-menus.js +478 -193
  142. package/dist/chat/ui/composer/use-composer-submit.js +251 -109
  143. package/dist/chat/ui/composer/use-continuable-turn.js +33 -6
  144. package/dist/chat/ui/composer/use-draft-files.js +245 -93
  145. package/dist/chat/ui/composer/use-effort-stepper.d.ts +13 -0
  146. package/dist/chat/ui/composer/use-effort-stepper.js +88 -0
  147. package/dist/chat/ui/composer/use-notice.js +61 -16
  148. package/dist/chat/ui/composer/use-pending-requests.js +38 -17
  149. package/dist/chat/ui/composer/use-prompt-history.js +117 -45
  150. package/dist/chat/ui/composer/use-prompt-hold.js +119 -35
  151. package/dist/chat/ui/composer/use-take-back.js +94 -72
  152. package/dist/chat/ui/diff/ApprovalReview.js +101 -23
  153. package/dist/chat/ui/diff/DiffFallbackBoundary.js +21 -13
  154. package/dist/chat/ui/diff/DiffOmitted.js +56 -6
  155. package/dist/chat/ui/diff/DiffStack.js +92 -8
  156. package/dist/chat/ui/diff/DiffUnavailable.js +56 -6
  157. package/dist/chat/ui/diff/EditorEditDiff.js +263 -51
  158. package/dist/chat/ui/diff/EditorPatchDiff.js +39 -14
  159. package/dist/chat/ui/diff/LegacyDiffPool.js +27 -10
  160. package/dist/chat/ui/diff/LegacyEditDiff.js +97 -20
  161. package/dist/chat/ui/diff/LegacyUnifiedDiff.js +172 -42
  162. package/dist/chat/ui/diff/RawDiff.js +65 -5
  163. package/dist/chat/ui/diff/ReviewDiff.js +77 -5
  164. package/dist/chat/ui/diff/diff-props.js +1 -1
  165. package/dist/chat/ui/diff/diff-source-budget.js +46 -35
  166. package/dist/chat/ui/diff/editor-edit-model.js +18 -14
  167. package/dist/chat/ui/diff/review-plan.js +63 -40
  168. package/dist/chat/ui/diff/review-settle.js +24 -9
  169. package/dist/chat/ui/diff/syntax-runtime.js +236 -201
  170. package/dist/chat/ui/diff/use-review-stack.js +146 -25
  171. package/dist/chat/ui/diff-syntax.js +70 -58
  172. package/dist/chat/ui/diff-theme.js +31 -12
  173. package/dist/chat/ui/file-links.js +39 -10
  174. package/dist/chat/ui/find-reveal.js +29 -8
  175. package/dist/chat/ui/full-diff.js +17 -12
  176. package/dist/chat/ui/highlighter.js +143 -113
  177. package/dist/chat/ui/icons.js +16 -7
  178. package/dist/chat/ui/index.js +1 -1
  179. package/dist/chat/ui/intelligent-ui/UiBlockFrame.js +556 -82
  180. package/dist/chat/ui/intelligent-ui/UiFallbackPart.js +73 -5
  181. package/dist/chat/ui/intelligent-ui/UiReply.js +666 -262
  182. package/dist/chat/ui/intelligent-ui/block-local.js +59 -31
  183. package/dist/chat/ui/intelligent-ui/chart-data.js +77 -67
  184. package/dist/chat/ui/intelligent-ui/node-text.js +77 -91
  185. package/dist/chat/ui/intelligent-ui/registry.js +46 -46
  186. package/dist/chat/ui/intelligent-ui/render-context.js +1 -1
  187. package/dist/chat/ui/intelligent-ui/renderers/base-land.js +1 -1
  188. package/dist/chat/ui/intelligent-ui/renderers/binding.js +3 -3
  189. package/dist/chat/ui/intelligent-ui/renderers/chart.js +1223 -123
  190. package/dist/chat/ui/intelligent-ui/renderers/choices.js +312 -34
  191. package/dist/chat/ui/intelligent-ui/renderers/content.js +1241 -86
  192. package/dist/chat/ui/intelligent-ui/renderers/data.js +619 -54
  193. package/dist/chat/ui/intelligent-ui/renderers/inputs.js +868 -67
  194. package/dist/chat/ui/intelligent-ui/renderers/links.js +366 -62
  195. package/dist/chat/ui/intelligent-ui/renderers/map-slots.js +118 -60
  196. package/dist/chat/ui/intelligent-ui/renderers/map-style.js +85 -78
  197. package/dist/chat/ui/intelligent-ui/renderers/map-view.js +282 -217
  198. package/dist/chat/ui/intelligent-ui/renderers/map.js +621 -69
  199. package/dist/chat/ui/intelligent-ui/renderers/place-point.js +15 -8
  200. package/dist/chat/ui/intelligent-ui/renderers/structure.js +262 -20
  201. package/dist/chat/ui/intelligent-ui/renderers/text.js +674 -49
  202. package/dist/chat/ui/intelligent-ui/reply-parts.js +24 -15
  203. package/dist/chat/ui/intelligent-ui/table-data.js +97 -57
  204. package/dist/chat/ui/intelligent-ui/tones.js +31 -31
  205. package/dist/chat/ui/intelligent-ui/use-in-view.js +30 -12
  206. package/dist/chat/ui/intelligent-ui/use-later.js +28 -13
  207. package/dist/chat/ui/intelligent-ui/use-truncated.js +45 -21
  208. package/dist/chat/ui/intelligent-ui/use-ui-links.js +296 -109
  209. package/dist/chat/ui/intelligent-ui/use-ui-queries.js +256 -246
  210. package/dist/chat/ui/markdown-blocks.js +296 -262
  211. package/dist/chat/ui/mermaid.d.ts +8 -20
  212. package/dist/chat/ui/mermaid.js +47 -84
  213. package/dist/chat/ui/quote-selection.js +32 -29
  214. package/dist/chat/ui/rehype-chips.js +35 -23
  215. package/dist/chat/ui/rehype-fade.js +28 -17
  216. package/dist/chat/ui/remark-html-as-text.js +22 -15
  217. package/dist/chat/ui/reply-context.js +1 -1
  218. package/dist/chat/ui/reveal.js +161 -72
  219. package/dist/chat/ui/rows/ForksRow.js +226 -24
  220. package/dist/chat/ui/rows/GeneratedImageRow.js +541 -87
  221. package/dist/chat/ui/rows/MessageRows.js +1706 -159
  222. package/dist/chat/ui/rows/RowContainer.js +57 -7
  223. package/dist/chat/ui/rows/Rows.js +463 -54
  224. package/dist/chat/ui/rows/SubagentRow.js +577 -60
  225. package/dist/chat/ui/rows/TaskRow.js +359 -40
  226. package/dist/chat/ui/rows/VisualRow.js +233 -11
  227. package/dist/chat/ui/rows/WorkRows.d.ts +3 -0
  228. package/dist/chat/ui/rows/WorkRows.js +1945 -164
  229. package/dist/chat/ui/rows/WorkflowRow.js +756 -37
  230. package/dist/chat/ui/rows/row-rhythm.js +27 -17
  231. package/dist/chat/ui/theme-watch.js +26 -23
  232. package/dist/chat/ui/timestamp-format.js +4 -1
  233. package/dist/chat/ui/use-diff-source-tokens.js +70 -34
  234. package/dist/chat/ui/useToggleSet.js +51 -19
  235. package/dist/chat/ui/visual-theme.js +153 -128
  236. package/dist/chat/visual-bridge.js +123 -123
  237. package/dist/chat/visual-viewport.js +94 -83
  238. package/dist/chat/visuals.js +13 -5
  239. package/dist/host-hooks.d.ts +29 -0
  240. package/dist/host-hooks.js +78 -0
  241. package/dist/host.js +120 -48
  242. package/dist/index.js +1 -1
  243. package/dist/lazy.js +38 -32
  244. package/dist/locales/en/agent-chat.d.ts +42 -0
  245. package/dist/locales/en/agent-chat.js +755 -713
  246. package/dist/locales/en/agent-prompts.js +42 -42
  247. package/dist/locales/en/agent-providers.d.ts +1 -0
  248. package/dist/locales/en/agent-providers.js +166 -165
  249. package/dist/locales/en/agent-usage.d.ts +6 -0
  250. package/dist/locales/en/agent-usage.js +129 -123
  251. package/dist/locales/nl/agent-chat.d.ts +42 -0
  252. package/dist/locales/nl/agent-chat.js +755 -713
  253. package/dist/locales/nl/agent-prompts.js +42 -42
  254. package/dist/locales/nl/agent-providers.d.ts +1 -0
  255. package/dist/locales/nl/agent-providers.js +166 -165
  256. package/dist/locales/nl/agent-usage.d.ts +6 -0
  257. package/dist/locales/nl/agent-usage.js +129 -123
  258. package/dist/locales.js +14 -14
  259. package/dist/mounted-registry.js +31 -30
  260. package/dist/port-transport.js +122 -111
  261. package/dist/prompts/index.js +1 -1
  262. package/dist/prompts/logic/focus.js +15 -14
  263. package/dist/prompts/logic/keys.js +93 -59
  264. package/dist/prompts/logic/prompts.js +27 -14
  265. package/dist/prompts/logic/subjects.js +60 -46
  266. package/dist/prompts/logic/useFocusAfterAnswer.js +60 -20
  267. package/dist/prompts/logic/usePromptSession.js +88 -77
  268. package/dist/prompts/ui/ApprovalBody.js +246 -27
  269. package/dist/prompts/ui/PromptActions.js +215 -9
  270. package/dist/prompts/ui/PromptCard.js +215 -36
  271. package/dist/prompts/ui/PromptView.js +372 -34
  272. package/dist/prompts/ui/QuestionBody.js +269 -73
  273. package/dist/providers/AccountColors.js +36 -5
  274. package/dist/providers/AccountDetail.js +683 -50
  275. package/dist/providers/AccountVariables.js +139 -32
  276. package/dist/providers/AddAccountForm.js +125 -38
  277. package/dist/providers/CliDetail.js +343 -36
  278. package/dist/providers/InstallPage.js +644 -59
  279. package/dist/providers/ProviderList.d.ts +2 -1
  280. package/dist/providers/ProviderList.js +215 -23
  281. package/dist/providers/ProvidersPane.d.ts +4 -2
  282. package/dist/providers/ProvidersPane.js +244 -64
  283. package/dist/providers/account-actions.js +54 -30
  284. package/dist/providers/index.js +1 -1
  285. package/dist/providers/install-steps.js +12 -9
  286. package/dist/providers/pane-target.d.ts +3 -0
  287. package/dist/providers/pane-target.js +34 -13
  288. package/dist/providers/parts.js +62 -12
  289. package/dist/providers/provider-abilities.js +5 -5
  290. package/dist/providers/provider-groups.js +75 -40
  291. package/dist/providers/variables.js +73 -39
  292. package/dist/scope.js +6 -6
  293. package/dist/settings/sections.js +18 -18
  294. package/dist/state/chats.js +404 -192
  295. package/dist/state/index.js +1 -1
  296. package/dist/state/provider-accounts.js +70 -47
  297. package/dist/state/providers.js +45 -16
  298. package/dist/state/usage.js +154 -77
  299. package/dist/storage.js +69 -68
  300. package/dist/testing/index.js +1 -1
  301. package/dist/testing/prompts.js +105 -67
  302. package/dist/transport.js +10 -10
  303. package/dist/ui/PlainTextarea.js +27 -3
  304. package/dist/usage/LimitsList.js +646 -40
  305. package/dist/usage/UsageBreakdown.js +879 -38
  306. package/dist/usage/UsageChart.js +311 -32
  307. package/dist/usage/UsageDialog.js +46 -4
  308. package/dist/usage/UsageLimits.js +467 -34
  309. package/dist/usage/UsageLimitsCard.js +95 -11
  310. package/dist/usage/UsagePage.js +817 -96
  311. package/dist/usage/UsagePane.js +164 -10
  312. package/dist/usage/UsageSummary.js +151 -6
  313. package/dist/usage/UsageTiles.js +164 -14
  314. package/dist/usage/format.js +32 -32
  315. package/dist/usage/index.d.ts +1 -1
  316. package/dist/usage/index.js +2 -1
  317. package/dist/usage/limit-groups.d.ts +2 -0
  318. package/dist/usage/limit-groups.js +77 -59
  319. package/dist/usage/limits.js +78 -43
  320. package/dist/usage/money.js +20 -4
  321. package/dist/usage/summary.js +85 -64
  322. package/package.json +9 -9
  323. package/src/agents/ModelOptionControl.tsx +3 -1
  324. package/src/agents/option-words.ts +27 -0
  325. package/src/chat/account-choice.ts +41 -1
  326. package/src/chat/composer-effort.ts +32 -0
  327. package/src/chat/forks.ts +4 -5
  328. package/src/chat/index.ts +3 -1
  329. package/src/chat/logic/effort.ts +32 -0
  330. package/src/chat/logic/picker-entries.ts +45 -10
  331. package/src/chat/logic/resume-compaction.ts +95 -17
  332. package/src/chat/logic/timeline.ts +11 -3
  333. package/src/chat/logic/workflow.ts +86 -4
  334. package/src/chat/preferences.ts +35 -0
  335. package/src/chat/subagent-view.ts +2 -3
  336. package/src/chat/ui/AnsiOutput.tsx +1 -2
  337. package/src/chat/ui/BookmarkSubmenu.tsx +3 -3
  338. package/src/chat/ui/ChatActivity.tsx +14 -22
  339. package/src/chat/ui/ChatReferenceChip.tsx +2 -3
  340. package/src/chat/ui/Composer.tsx +15 -7
  341. package/src/chat/ui/EditDiff.tsx +2 -3
  342. package/src/chat/ui/LimitState.tsx +2 -2
  343. package/src/chat/ui/Markdown.tsx +10 -8
  344. package/src/chat/ui/MermaidBlock.tsx +57 -49
  345. package/src/chat/ui/Pickers.tsx +49 -29
  346. package/src/chat/ui/PromptComposer.tsx +7 -9
  347. package/src/chat/ui/ResumeCompactionDock.tsx +16 -4
  348. package/src/chat/ui/RunSettings.tsx +67 -28
  349. package/src/chat/ui/Scrubber.tsx +3 -3
  350. package/src/chat/ui/ShellCommand.tsx +2 -0
  351. package/src/chat/ui/SubagentInfo.tsx +2 -3
  352. package/src/chat/ui/SubagentTimeline.tsx +12 -16
  353. package/src/chat/ui/Timeline.tsx +6 -6
  354. package/src/chat/ui/UnifiedDiff.tsx +3 -4
  355. package/src/chat/ui/VisualFrame.tsx +5 -8
  356. package/src/chat/ui/code-theme.ts +4 -4
  357. package/src/chat/ui/composer/placeholder.ts +2 -2
  358. package/src/chat/ui/composer/use-compaction-offer.ts +36 -16
  359. package/src/chat/ui/composer/use-composer-menus.ts +4 -9
  360. package/src/chat/ui/composer/use-composer-submit.ts +2 -1
  361. package/src/chat/ui/composer/use-effort-stepper.ts +56 -0
  362. package/src/chat/ui/composer/use-notice.ts +2 -2
  363. package/src/chat/ui/diff/EditorEditDiff.tsx +9 -13
  364. package/src/chat/ui/diff/LegacyEditDiff.tsx +12 -17
  365. package/src/chat/ui/diff/LegacyUnifiedDiff.tsx +13 -21
  366. package/src/chat/ui/diff/use-review-stack.ts +4 -4
  367. package/src/chat/ui/diff-theme.ts +3 -3
  368. package/src/chat/ui/file-links.ts +2 -2
  369. package/src/chat/ui/intelligent-ui/UiReply.tsx +2 -0
  370. package/src/chat/ui/intelligent-ui/renderers/chart.tsx +3 -3
  371. package/src/chat/ui/intelligent-ui/renderers/content.tsx +5 -6
  372. package/src/chat/ui/intelligent-ui/renderers/map-view.tsx +2 -1
  373. package/src/chat/ui/intelligent-ui/renderers/map.tsx +2 -1
  374. package/src/chat/ui/intelligent-ui/use-truncated.ts +16 -19
  375. package/src/chat/ui/intelligent-ui/use-ui-links.ts +3 -3
  376. package/src/chat/ui/mermaid.ts +52 -96
  377. package/src/chat/ui/rows/ForksRow.tsx +3 -5
  378. package/src/chat/ui/rows/GeneratedImageRow.tsx +2 -1
  379. package/src/chat/ui/rows/MessageRows.tsx +12 -21
  380. package/src/chat/ui/rows/SubagentRow.tsx +3 -3
  381. package/src/chat/ui/rows/TaskRow.tsx +1 -1
  382. package/src/chat/ui/rows/WorkRows.tsx +11 -6
  383. package/src/chat/ui/rows/WorkflowRow.tsx +144 -54
  384. package/src/chat/ui/useToggleSet.ts +15 -18
  385. package/src/chat/ui/visual-theme.ts +2 -3
  386. package/src/host-hooks.ts +113 -0
  387. package/src/lazy.tsx +2 -0
  388. package/src/locales/en/agent-chat.ts +142 -108
  389. package/src/locales/en/agent-prompts.ts +7 -7
  390. package/src/locales/en/agent-providers.ts +35 -34
  391. package/src/locales/en/agent-usage.ts +26 -20
  392. package/src/locales/nl/agent-chat.ts +134 -100
  393. package/src/locales/nl/agent-prompts.ts +5 -5
  394. package/src/locales/nl/agent-providers.ts +33 -32
  395. package/src/locales/nl/agent-usage.ts +25 -20
  396. package/src/providers/CliDetail.tsx +2 -1
  397. package/src/providers/InstallPage.tsx +2 -4
  398. package/src/providers/ProviderList.tsx +12 -2
  399. package/src/providers/ProvidersPane.tsx +45 -15
  400. package/src/providers/pane-target.ts +20 -4
  401. package/src/state/chats.ts +2 -2
  402. package/src/usage/LimitsList.tsx +12 -13
  403. package/src/usage/UsageBreakdown.tsx +17 -6
  404. package/src/usage/UsageLimits.tsx +2 -1
  405. package/src/usage/UsagePage.tsx +3 -3
  406. package/src/usage/index.ts +1 -1
  407. package/src/usage/limit-groups.ts +12 -0
  408. package/src/usage/limits.ts +2 -2
  409. package/src/usage/money.ts +1 -2
@@ -1,93 +1,56 @@
1
- /* The token each color reads. Borders carry an alpha, so they are resolved over the ground. */
2
- export const MERMAID_TOKENS = {
3
- ground: '--chat-code-bg',
4
- node: '--surface-raised',
5
- nodeBorder: '--border-strong',
6
- text: '--text',
7
- line: '--text-muted',
8
- cluster: '--surface',
9
- clusterBorder: '--border',
10
- note: '--accent-soft'
1
+ /* The variable of Pele each token of the theme fills. Borders carry an alpha, so every color is resolved over the ground. */
2
+ export const DIAGRAM_TOKENS = {
3
+ '--pele-bg': '--chat-code-bg',
4
+ '--pele-fg': '--text',
5
+ '--pele-muted': '--text-muted',
6
+ '--pele-line': '--text-muted',
7
+ '--pele-surface': '--surface-raised',
8
+ '--pele-surface-alt': '--surface',
9
+ '--pele-border': '--border-strong',
10
+ '--pele-accent': '--accent',
11
+ '--pele-critical': '--status-error',
12
+ '--pele-series-1': '--accent',
13
+ '--pele-series-2': '--chart-2',
14
+ '--pele-series-3': '--chart-3',
15
+ '--pele-series-4': '--chart-4',
16
+ '--pele-series-5': '--chart-5',
17
+ '--pele-series-6': '--chart-6'
11
18
  };
12
- // Mermaid's own list plus what keeps a diagram in the theme and out of HTML: a directive in the text cannot change these.
13
- const SECURE_KEYS = [
14
- 'secure',
15
- 'securityLevel',
16
- 'startOnLoad',
17
- 'maxTextSize',
18
- 'maxEdges',
19
- 'suppressErrorRendering',
20
- 'htmlLabels',
21
- 'theme',
22
- 'themeVariables',
23
- 'themeCSS',
24
- 'darkMode',
25
- 'fontFamily'
26
- ];
19
+ export const GROUND_TOKEN = DIAGRAM_TOKENS['--pele-bg'];
27
20
  /*
28
- * Strict: no HTML in labels, no click handlers, no links that run script. What comes out is drawn as an
29
- * image as well, which never runs script and loads nothing, whatever the text of the diagram says.
21
+ * At the size it was laid out at, since an image has no container to shrink to. No links and no images, and no
22
+ * math or icon resolver, which are the only markup Pele inserts unfiltered. What comes out is drawn as an image as
23
+ * well, which never runs script and loads nothing, whatever the text of the diagram says.
30
24
  */
31
- export function mermaidConfig(colors, dark, font) {
32
- return {
33
- startOnLoad: false,
34
- securityLevel: 'strict',
35
- htmlLabels: false,
36
- suppressErrorRendering: true,
37
- secure: SECURE_KEYS,
38
- theme: 'base',
39
- darkMode: dark,
40
- fontFamily: font.family,
41
- themeVariables: {
42
- darkMode: dark,
43
- fontFamily: font.family,
44
- fontSize: font.size,
45
- background: colors.ground,
46
- primaryColor: colors.node,
47
- primaryTextColor: colors.text,
48
- primaryBorderColor: colors.nodeBorder,
49
- secondaryColor: colors.note,
50
- tertiaryColor: colors.cluster,
51
- mainBkg: colors.node,
52
- nodeBorder: colors.nodeBorder,
53
- textColor: colors.text,
54
- titleColor: colors.text,
55
- lineColor: colors.line,
56
- clusterBkg: colors.cluster,
57
- clusterBorder: colors.clusterBorder,
58
- edgeLabelBackground: colors.ground,
59
- noteBkgColor: colors.note,
60
- noteTextColor: colors.text,
61
- noteBorderColor: colors.nodeBorder
62
- }
63
- };
25
+ export function renderOptions(font, idPrefix) {
26
+ return {
27
+ responsive: false,
28
+ idPrefix,
29
+ fontFamily: font.family,
30
+ fontFamilyMono: font.mono,
31
+ fontSize: font.size,
32
+ links: false,
33
+ images: false
34
+ };
64
35
  }
65
36
  const ROOT = /<svg\b[^>]*>/;
66
- const VIEW_BOX = /\sviewBox="([^"]*)"/;
67
- const SIZE_ATTRIBUTES = /\s(?:width|height|style)="[^"]*"/g;
37
+ const STYLE = /\sstyle="/;
38
+ function attributeText(value) {
39
+ return value.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;');
40
+ }
68
41
  /*
69
- * The diagram at the size it was laid out at. Mermaid fits it to the width of its container instead,
70
- * which an image does not have, so the root takes the size its view box names. Null for anything
71
- * without one.
42
+ * The drawing with the colors set on its root. An image does not see the variables of the page, so they are
43
+ * written in, and a change of the theme only writes them again.
72
44
  */
73
- export function sizedSvg(svg) {
74
- const root = ROOT.exec(svg);
75
- const viewBox = root === null ? null : VIEW_BOX.exec(root[0]);
76
- if (root === null || viewBox === null) {
77
- return null;
78
- }
79
- const [, , boxWidth, boxHeight] = viewBox[1]
80
- .trim()
81
- .split(/[\s,]+/)
82
- .map(Number);
83
- if (!Number.isFinite(boxWidth) || !Number.isFinite(boxHeight) || boxWidth <= 0 || boxHeight <= 0) {
84
- return null;
85
- }
86
- const width = Math.ceil(boxWidth);
87
- const height = Math.ceil(boxHeight);
88
- const tag = root[0].replace(SIZE_ATTRIBUTES, '').replace(/^<svg\b/, `<svg width="${width}" height="${height}"`);
89
- return { svg: svg.slice(0, root.index) + tag + svg.slice(root.index + root[0].length), width, height };
45
+ export function themedSvg(svg, colors) {
46
+ const root = ROOT.exec(svg);
47
+ if (root === null) {
48
+ return svg;
49
+ }
50
+ const variables = attributeText(Object.entries(colors).map(([name, value]) => `${name}:${value};`).join(''));
51
+ const tag = STYLE.test(root[0]) ? root[0].replace(STYLE, style => style + variables) : root[0].replace(/^<svg\b/, `<svg style="${variables}"`);
52
+ return svg.slice(0, root.index) + tag + svg.slice(root.index + root[0].length);
90
53
  }
91
54
  export function svgDataUrl(svg) {
92
- return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
93
- }
55
+ return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
56
+ }
@@ -5,7 +5,7 @@ const ANSWER = '[data-quote-answer]';
5
5
  /* Registers the composer below a thread as the one its quote button hands a quote to, until the returned call. */
6
6
  export const QuoteTakerContext = createContext(null);
7
7
  function answerAt(node) {
8
- return (node instanceof Element ? node : node.parentElement)?.closest(ANSWER) ?? null;
8
+ return (node instanceof Element ? node : node.parentElement)?.closest(ANSWER) ?? null;
9
9
  }
10
10
  /*
11
11
  * Whether the range selects text a person can see outside the answer. A triple-click on a paragraph
@@ -13,35 +13,38 @@ function answerAt(node) {
13
13
  * paragraph alone.
14
14
  */
15
15
  function selectsOutside(range, answer) {
16
- const walker = document.createTreeWalker(range.commonAncestorContainer, NodeFilter.SHOW_TEXT);
17
- for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {
18
- if (!range.intersectsNode(node) || answer.contains(node)) {
19
- continue;
20
- }
21
- const text = node.textContent ?? '';
22
- const start = node === range.startContainer ? range.startOffset : 0;
23
- const end = node === range.endContainer ? range.endOffset : text.length;
24
- const parent = node.parentElement;
25
- if (text.slice(start, end).trim() !== '' && parent !== null && getComputedStyle(parent).userSelect !== 'none') {
26
- return true;
27
- }
16
+ const walker = document.createTreeWalker(range.commonAncestorContainer, NodeFilter.SHOW_TEXT);
17
+ for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {
18
+ if (!range.intersectsNode(node) || answer.contains(node)) {
19
+ continue;
28
20
  }
29
- return false;
21
+ const text = node.textContent ?? '';
22
+ const start = node === range.startContainer ? range.startOffset : 0;
23
+ const end = node === range.endContainer ? range.endOffset : text.length;
24
+ const parent = node.parentElement;
25
+ if (text.slice(start, end).trim() !== '' && parent !== null && getComputedStyle(parent).userSelect !== 'none') {
26
+ return true;
27
+ }
28
+ }
29
+ return false;
30
30
  }
31
31
  /* The quote the selection makes, when it lies in one answer of this thread, and the reply it was taken from. */
32
32
  export function selectedAnswerQuote(selection, thread) {
33
- if (thread === null || selection === null || selection.isCollapsed || selection.rangeCount === 0) {
34
- return null;
35
- }
36
- const range = selection.getRangeAt(0);
37
- const answer = answerAt(range.startContainer) ?? answerAt(range.endContainer);
38
- if (answer === null || !thread.contains(answer)) {
39
- return null;
40
- }
41
- const inside = answer.contains(range.startContainer) && answer.contains(range.endContainer);
42
- if (!inside && selectsOutside(range, answer)) {
43
- return null;
44
- }
45
- const text = quoteOf(selection.toString());
46
- return text === null ? null : { text, itemId: answer.closest('[data-find-item]')?.getAttribute('data-find-item') ?? null };
47
- }
33
+ if (thread === null || selection === null || selection.isCollapsed || selection.rangeCount === 0) {
34
+ return null;
35
+ }
36
+ const range = selection.getRangeAt(0);
37
+ const answer = answerAt(range.startContainer) ?? answerAt(range.endContainer);
38
+ if (answer === null || !thread.contains(answer)) {
39
+ return null;
40
+ }
41
+ const inside = answer.contains(range.startContainer) && answer.contains(range.endContainer);
42
+ if (!inside && selectsOutside(range, answer)) {
43
+ return null;
44
+ }
45
+ const text = quoteOf(selection.toString());
46
+ return text === null ? null : {
47
+ text,
48
+ itemId: answer.closest('[data-find-item]')?.getAttribute('data-find-item') ?? null
49
+ };
50
+ }
@@ -3,30 +3,42 @@ import { chipText, tokenizeChips } from '../mentions.js';
3
3
  const SKIPPED = new Set(['code', 'pre']);
4
4
  /* A chip as an element: the renderer reads `data-chip` and `data-value`, the text keeps the sigil. */
5
5
  function chipElement(segment) {
6
- return {
7
- type: 'element',
8
- tagName: 'span',
9
- properties: { dataChip: segment.kind, dataValue: segment.kind === 'mention' ? segment.path : segment.name },
10
- children: [{ type: 'text', value: chipText(segment) }]
11
- };
6
+ return {
7
+ type: 'element',
8
+ tagName: 'span',
9
+ properties: {
10
+ dataChip: segment.kind,
11
+ dataValue: segment.kind === 'mention' ? segment.path : segment.name
12
+ },
13
+ children: [{
14
+ type: 'text',
15
+ value: chipText(segment)
16
+ }]
17
+ };
12
18
  }
13
19
  function split(parent, mentions, skills) {
14
- parent.children = parent.children.flatMap((child) => {
15
- if (child.type === 'text') {
16
- return tokenizeChips(child.value, mentions, skills).map((segment) => segment.kind === 'text' ? { type: 'text', value: segment.text } : chipElement(segment));
17
- }
18
- if (child.type === 'element' && !SKIPPED.has(child.tagName)) {
19
- split(child, mentions, skills);
20
- }
21
- return [child];
22
- });
20
+ parent.children = parent.children.flatMap(child => {
21
+ if (child.type === 'text') {
22
+ return tokenizeChips(child.value, mentions, skills).map(segment => segment.kind === 'text' ? {
23
+ type: 'text',
24
+ value: segment.text
25
+ } : chipElement(segment));
26
+ }
27
+ if (child.type === 'element' && !SKIPPED.has(child.tagName)) {
28
+ split(child, mentions, skills);
29
+ }
30
+ return [child];
31
+ });
23
32
  }
24
33
  /* The `@path` and `$name` tokens a person picked in the composer, cut out of the text as chips. */
25
- export function rehypeChips({ mentions = [], skills = [] } = {}) {
26
- return (tree) => {
27
- if (mentions.length === 0 && skills.length === 0) {
28
- return;
29
- }
30
- split(tree, mentions, skills);
31
- };
32
- }
34
+ export function rehypeChips({
35
+ mentions = [],
36
+ skills = []
37
+ } = {}) {
38
+ return tree => {
39
+ if (mentions.length === 0 && skills.length === 0) {
40
+ return;
41
+ }
42
+ split(tree, mentions, skills);
43
+ };
44
+ }
@@ -6,23 +6,34 @@ const SKIPPED = new Set(['code', 'pre']);
6
6
  const WHITESPACE = /^\s+$/;
7
7
  /* A text cut into its words and the whitespace between them, in order. */
8
8
  export function wordSegments(text) {
9
- return text.split(/(\s+)/).filter((segment) => segment !== '');
9
+ return text.split(/(\s+)/).filter(segment => segment !== '');
10
10
  }
11
11
  export function isWhitespace(segment) {
12
- return WHITESPACE.test(segment);
12
+ return WHITESPACE.test(segment);
13
13
  }
14
14
  function wrap(parent) {
15
- parent.children = parent.children.flatMap((child) => {
16
- if (child.type === 'text') {
17
- return wordSegments(child.value).map((segment) => isWhitespace(segment)
18
- ? { type: 'text', value: segment }
19
- : { type: 'element', tagName: 'span', properties: { className: [FADE_CLASS] }, children: [{ type: 'text', value: segment }] });
20
- }
21
- if (child.type === 'element' && !SKIPPED.has(child.tagName)) {
22
- wrap(child);
23
- }
24
- return [child];
25
- });
15
+ parent.children = parent.children.flatMap(child => {
16
+ if (child.type === 'text') {
17
+ return wordSegments(child.value).map(segment => isWhitespace(segment) ? {
18
+ type: 'text',
19
+ value: segment
20
+ } : {
21
+ type: 'element',
22
+ tagName: 'span',
23
+ properties: {
24
+ className: [FADE_CLASS]
25
+ },
26
+ children: [{
27
+ type: 'text',
28
+ value: segment
29
+ }]
30
+ });
31
+ }
32
+ if (child.type === 'element' && !SKIPPED.has(child.tagName)) {
33
+ wrap(child);
34
+ }
35
+ return [child];
36
+ });
26
37
  }
27
38
  /*
28
39
  * Every word of a reply that is still streaming in a span that fades in. Words only ever arrive at
@@ -30,7 +41,7 @@ function wrap(parent) {
30
41
  * on screen keep their element and their fade does not start again.
31
42
  */
32
43
  export function rehypeFadeWords() {
33
- return (tree) => {
34
- wrap(tree);
35
- };
36
- }
44
+ return tree => {
45
+ wrap(tree);
46
+ };
47
+ }
@@ -1,18 +1,25 @@
1
1
  // Parents whose children are blocks, where a bare text node would stand outside any paragraph.
2
2
  const FLOW_PARENTS = new Set(['root', 'blockquote', 'listItem', 'footnoteDefinition']);
3
3
  function literal(parent) {
4
- if (parent.children === undefined) {
5
- return;
4
+ if (parent.children === undefined) {
5
+ return;
6
+ }
7
+ const flow = FLOW_PARENTS.has(parent.type);
8
+ parent.children = parent.children.map(child => {
9
+ if (child.type !== 'html') {
10
+ literal(child);
11
+ return child;
6
12
  }
7
- const flow = FLOW_PARENTS.has(parent.type);
8
- parent.children = parent.children.map((child) => {
9
- if (child.type !== 'html') {
10
- literal(child);
11
- return child;
12
- }
13
- const text = { ...child, type: 'text' };
14
- return flow ? { type: 'paragraph', position: child.position, children: [text] } : text;
15
- });
13
+ const text = {
14
+ ...child,
15
+ type: 'text'
16
+ };
17
+ return flow ? {
18
+ type: 'paragraph',
19
+ position: child.position,
20
+ children: [text]
21
+ } : text;
22
+ });
16
23
  }
17
24
  /*
18
25
  * Raw HTML in a message as the characters a person typed. react-markdown drops an `html` node, so
@@ -20,7 +27,7 @@ function literal(parent) {
20
27
  * newlines of an HTML block still become line breaks.
21
28
  */
22
29
  export function remarkHtmlAsText() {
23
- return (tree) => {
24
- literal(tree);
25
- };
26
- }
30
+ return tree => {
31
+ literal(tree);
32
+ };
33
+ }
@@ -1,3 +1,3 @@
1
1
  import { createContext } from 'react';
2
2
  export const ReplyContext = createContext(null);
3
- export const UiReplyNavigationContext = createContext(null);
3
+ export const UiReplyNavigationContext = createContext(null);
@@ -1,3 +1,4 @@
1
+ import { c as _c } from "react/compiler-runtime";
1
2
  import { useEffect, useRef, useState } from 'react';
2
3
  /* How long a word takes to fade in. `.chat-fade` in styles.css carries the same number. */
3
4
  export const REVEAL_FADE_MS = 300;
@@ -14,7 +15,7 @@ export const REVEAL_MAX_HELD_WORD = 32;
14
15
  // The span mounts a commit after the frame that grew the text, so its fade ends a little later than that frame plus the duration.
15
16
  const FADE_SETTLE_MS = REVEAL_FADE_MS + 50;
16
17
  function isSpace(text, index) {
17
- return index >= 0 && index < text.length && /\s/.test(text[index]);
18
+ return index >= 0 && index < text.length && /\s/.test(text[index]);
18
19
  }
19
20
  /*
20
21
  * Where the reveal stands `elapsedMs` after it stood at `position`, with `target` characters
@@ -22,13 +23,13 @@ function isSpace(text, index) {
22
23
  * rate of the screen.
23
24
  */
24
25
  export function advanceReveal(position, target, elapsedMs, finished) {
25
- if (position >= target) {
26
- return target;
27
- }
28
- const elapsed = Math.min(Math.max(elapsedMs, 0), REVEAL_MAX_FRAME_MS);
29
- const eased = (target - position) * (1 - Math.exp(-elapsed / REVEAL_TAU_MS));
30
- const floor = ((finished ? REVEAL_FINISH_MIN_CPS : REVEAL_MIN_CPS) * elapsed) / 1000;
31
- return Math.min(target, position + Math.max(eased, floor));
26
+ if (position >= target) {
27
+ return target;
28
+ }
29
+ const elapsed = Math.min(Math.max(elapsedMs, 0), REVEAL_MAX_FRAME_MS);
30
+ const eased = (target - position) * (1 - Math.exp(-elapsed / REVEAL_TAU_MS));
31
+ const floor = (finished ? REVEAL_FINISH_MIN_CPS : REVEAL_MIN_CPS) * elapsed / 1000;
32
+ return Math.min(target, position + Math.max(eased, floor));
32
33
  }
33
34
  /*
34
35
  * How much of `text` to draw for a reveal at `position`: back to the last word boundary, because a
@@ -37,20 +38,20 @@ export function advanceReveal(position, target, elapsedMs, finished) {
37
38
  * whitespace after it.
38
39
  */
39
40
  export function revealBoundary(text, position, complete) {
40
- const end = Math.min(text.length, Math.max(0, Math.floor(position)));
41
- if (end === text.length && complete) {
42
- return end;
43
- }
44
- let cut = end;
45
- while (cut > 0 && !isSpace(text, cut) && !isSpace(text, cut - 1)) {
46
- cut -= 1;
47
- }
48
- if (end - cut <= REVEAL_MAX_HELD_WORD) {
49
- return cut;
50
- }
51
- // Half of a surrogate pair renders as a replacement box.
52
- const last = text.charCodeAt(end - 1);
53
- return last >= 0xd800 && last <= 0xdbff ? end - 1 : end;
41
+ const end = Math.min(text.length, Math.max(0, Math.floor(position)));
42
+ if (end === text.length && complete) {
43
+ return end;
44
+ }
45
+ let cut = end;
46
+ while (cut > 0 && !isSpace(text, cut) && !isSpace(text, cut - 1)) {
47
+ cut -= 1;
48
+ }
49
+ if (end - cut <= REVEAL_MAX_HELD_WORD) {
50
+ return cut;
51
+ }
52
+ // Half of a surrogate pair renders as a replacement box.
53
+ const last = text.charCodeAt(end - 1);
54
+ return last >= 0xd800 && last <= 0xdbff ? end - 1 : end;
54
55
  }
55
56
  /*
56
57
  * The part of a streaming text that is on screen, catching up with what arrived over time. It starts
@@ -58,57 +59,145 @@ export function revealBoundary(text, position, complete) {
58
59
  * was already done on mount is shown whole at once.
59
60
  */
60
61
  export function useRevealedText(text, streaming) {
61
- const [active, setActive] = useState(streaming);
62
- const [shown, setShown] = useState(() => revealBoundary(text, text.length, !streaming));
63
- const latest = useRef({ text, streaming });
64
- const position = useRef(text.length);
65
- const shownRef = useRef(shown);
66
- const activeRef = useRef(active);
67
- useEffect(() => {
68
- latest.current = { text, streaming };
69
- });
70
- // Turning streaming on for a text that stood still (the setting flipped mid-reply) starts from what is there.
71
- useEffect(() => {
72
- if (!streaming || activeRef.current) {
73
- return;
62
+ const $ = _c(22);
63
+ const [active, setActive] = useState(streaming);
64
+ let t0;
65
+ if ($[0] !== streaming || $[1] !== text) {
66
+ t0 = () => revealBoundary(text, text.length, !streaming);
67
+ $[0] = streaming;
68
+ $[1] = text;
69
+ $[2] = t0;
70
+ } else {
71
+ t0 = $[2];
72
+ }
73
+ const [shown, setShown] = useState(t0);
74
+ let t1;
75
+ if ($[3] !== streaming || $[4] !== text) {
76
+ t1 = {
77
+ text,
78
+ streaming
79
+ };
80
+ $[3] = streaming;
81
+ $[4] = text;
82
+ $[5] = t1;
83
+ } else {
84
+ t1 = $[5];
85
+ }
86
+ const latest = useRef(t1);
87
+ const position = useRef(text.length);
88
+ const shownRef = useRef(shown);
89
+ const activeRef = useRef(active);
90
+ let t2;
91
+ if ($[6] !== streaming || $[7] !== text) {
92
+ t2 = () => {
93
+ latest.current = {
94
+ text,
95
+ streaming
96
+ };
97
+ };
98
+ $[6] = streaming;
99
+ $[7] = text;
100
+ $[8] = t2;
101
+ } else {
102
+ t2 = $[8];
103
+ }
104
+ useEffect(t2);
105
+ let t3;
106
+ let t4;
107
+ if ($[9] !== streaming) {
108
+ t3 = () => {
109
+ if (!streaming || activeRef.current) {
110
+ return;
111
+ }
112
+ position.current = latest.current.text.length;
113
+ shownRef.current = revealBoundary(latest.current.text, position.current, false);
114
+ activeRef.current = true;
115
+ setShown(shownRef.current);
116
+ setActive(true);
117
+ };
118
+ t4 = [streaming];
119
+ $[9] = streaming;
120
+ $[10] = t3;
121
+ $[11] = t4;
122
+ } else {
123
+ t3 = $[10];
124
+ t4 = $[11];
125
+ }
126
+ useEffect(t3, t4);
127
+ let t5;
128
+ let t6;
129
+ if ($[12] !== active) {
130
+ t5 = () => {
131
+ if (!active) {
132
+ return;
133
+ }
134
+ let frame = 0;
135
+ let previous = null;
136
+ let grewAt = -Infinity;
137
+ const tick = now => {
138
+ const elapsed = previous === null ? 0 : now - previous;
139
+ previous = now;
140
+ const current = latest.current;
141
+ const finished = !current.streaming;
142
+ position.current = advanceReveal(position.current, current.text.length, elapsed, finished);
143
+ const length = revealBoundary(current.text, position.current, finished);
144
+ if (length !== shownRef.current) {
145
+ shownRef.current = length;
146
+ grewAt = now;
147
+ setShown(length);
74
148
  }
75
- position.current = latest.current.text.length;
76
- shownRef.current = revealBoundary(latest.current.text, position.current, false);
77
- activeRef.current = true;
78
- setShown(shownRef.current);
79
- setActive(true);
80
- }, [streaming]);
81
- useEffect(() => {
82
- if (!active) {
83
- return;
149
+ if (finished && length >= current.text.length && now - grewAt >= FADE_SETTLE_MS) {
150
+ activeRef.current = false;
151
+ setActive(false);
152
+ return;
84
153
  }
85
- let frame = 0;
86
- let previous = null;
87
- let grewAt = -Infinity;
88
- const tick = (now) => {
89
- const elapsed = previous === null ? 0 : now - previous;
90
- previous = now;
91
- const current = latest.current;
92
- const finished = !current.streaming;
93
- position.current = advanceReveal(position.current, current.text.length, elapsed, finished);
94
- const length = revealBoundary(current.text, position.current, finished);
95
- if (length !== shownRef.current) {
96
- shownRef.current = length;
97
- grewAt = now;
98
- setShown(length);
99
- }
100
- if (finished && length >= current.text.length && now - grewAt >= FADE_SETTLE_MS) {
101
- activeRef.current = false;
102
- setActive(false);
103
- return;
104
- }
105
- frame = requestAnimationFrame(tick);
106
- };
107
154
  frame = requestAnimationFrame(tick);
108
- return () => cancelAnimationFrame(frame);
109
- }, [active]);
110
- if (!active) {
111
- return { text, active: false };
155
+ };
156
+ frame = requestAnimationFrame(tick);
157
+ return () => cancelAnimationFrame(frame);
158
+ };
159
+ t6 = [active];
160
+ $[12] = active;
161
+ $[13] = t5;
162
+ $[14] = t6;
163
+ } else {
164
+ t5 = $[13];
165
+ t6 = $[14];
166
+ }
167
+ useEffect(t5, t6);
168
+ if (!active) {
169
+ let t7;
170
+ if ($[15] !== text) {
171
+ t7 = {
172
+ text,
173
+ active: false
174
+ };
175
+ $[15] = text;
176
+ $[16] = t7;
177
+ } else {
178
+ t7 = $[16];
112
179
  }
113
- return { text: text.slice(0, Math.min(shown, text.length)), active: true };
114
- }
180
+ return t7;
181
+ }
182
+ let t7;
183
+ if ($[17] !== shown || $[18] !== text) {
184
+ t7 = text.slice(0, Math.min(shown, text.length));
185
+ $[17] = shown;
186
+ $[18] = text;
187
+ $[19] = t7;
188
+ } else {
189
+ t7 = $[19];
190
+ }
191
+ let t8;
192
+ if ($[20] !== t7) {
193
+ t8 = {
194
+ text: t7,
195
+ active: true
196
+ };
197
+ $[20] = t7;
198
+ $[21] = t8;
199
+ } else {
200
+ t8 = $[21];
201
+ }
202
+ return t8;
203
+ }