@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
@@ -11,80 +11,91 @@ const storageKey = () => chatStorageKey('stash');
11
11
  // Past this the list is an archive nobody reads; the oldest entry makes room for a new one.
12
12
  export const STASH_LIMIT = 20;
13
13
  function strings(value) {
14
- return Array.isArray(value) ? value.filter((entry) => typeof entry === 'string') : [];
14
+ return Array.isArray(value) ? value.filter(entry => typeof entry === 'string') : [];
15
15
  }
16
16
  function attachments(value) {
17
- if (!Array.isArray(value)) {
18
- return [];
19
- }
20
- return value.filter(isRecord).map((entry) => ({
21
- name: typeof entry.name === 'string' ? entry.name : '',
22
- mime: typeof entry.mime === 'string' ? entry.mime : '',
23
- size: typeof entry.size === 'number' ? entry.size : 0
24
- }));
17
+ if (!Array.isArray(value)) {
18
+ return [];
19
+ }
20
+ return value.filter(isRecord).map(entry => ({
21
+ name: typeof entry.name === 'string' ? entry.name : '',
22
+ mime: typeof entry.mime === 'string' ? entry.mime : '',
23
+ size: typeof entry.size === 'number' ? entry.size : 0
24
+ }));
25
25
  }
26
26
  function stashedQuote(value) {
27
- if (!isRecord(value) || typeof value.text !== 'string' || typeof value.chatId !== 'string' || typeof value.itemId !== 'string') {
28
- return undefined;
29
- }
30
- return { text: value.text, chatId: value.chatId, itemId: value.itemId };
27
+ if (!isRecord(value) || typeof value.text !== 'string' || typeof value.chatId !== 'string' || typeof value.itemId !== 'string') {
28
+ return undefined;
29
+ }
30
+ return {
31
+ text: value.text,
32
+ chatId: value.chatId,
33
+ itemId: value.itemId
34
+ };
31
35
  }
32
36
  function stashedQuoteField(value) {
33
- const quote = stashedQuote(value);
34
- return quote === undefined ? {} : { quote };
37
+ const quote = stashedQuote(value);
38
+ return quote === undefined ? {} : {
39
+ quote
40
+ };
35
41
  }
36
42
  /* Only the fields we know today, so anything an older or a broken write left behind falls away here. */
37
43
  export function parseStash(raw) {
38
- if (raw === null) {
39
- return [];
40
- }
41
- try {
42
- const stored = JSON.parse(raw);
43
- if (!Array.isArray(stored)) {
44
- return [];
45
- }
46
- return stored
47
- .filter(isRecord)
48
- .filter((entry) => typeof entry.id === 'string' && typeof entry.text === 'string')
49
- .map((entry) => ({
50
- id: entry.id,
51
- text: entry.text,
52
- mentions: strings(entry.mentions),
53
- skills: strings(entry.skills),
54
- chats: strings(entry.chats),
55
- attachments: attachments(entry.attachments),
56
- ...stashedQuoteField(entry.quote),
57
- createdAt: typeof entry.createdAt === 'number' ? entry.createdAt : 0
58
- }))
59
- .slice(0, STASH_LIMIT);
60
- }
61
- catch {
62
- return [];
44
+ if (raw === null) {
45
+ return [];
46
+ }
47
+ try {
48
+ const stored = JSON.parse(raw);
49
+ if (!Array.isArray(stored)) {
50
+ return [];
63
51
  }
52
+ return stored.filter(isRecord).filter(entry => typeof entry.id === 'string' && typeof entry.text === 'string').map(entry => ({
53
+ id: entry.id,
54
+ text: entry.text,
55
+ mentions: strings(entry.mentions),
56
+ skills: strings(entry.skills),
57
+ chats: strings(entry.chats),
58
+ attachments: attachments(entry.attachments),
59
+ ...stashedQuoteField(entry.quote),
60
+ createdAt: typeof entry.createdAt === 'number' ? entry.createdAt : 0
61
+ })).slice(0, STASH_LIMIT);
62
+ } catch {
63
+ return [];
64
+ }
64
65
  }
65
66
  /* Newest first, capped: the entry that has been waiting longest is the one nobody comes back for. */
66
67
  export function withStashed(prompts, entry) {
67
- return [entry, ...prompts].slice(0, STASH_LIMIT);
68
+ return [entry, ...prompts].slice(0, STASH_LIMIT);
68
69
  }
69
70
  /*
70
71
  * What a draft looks like on the shelf; null when there is nothing worth putting there. A quote that
71
72
  * knows its reply stays apart, since it leads back to that reply in `chatId`; any other is folded into the text.
72
73
  */
73
74
  export function stashedFrom(draft, id, now, chatId) {
74
- if (isEmptyDraft(draft)) {
75
- return null;
76
- }
77
- const kept = draft.quote !== '' && draft.quoteSource !== null;
78
- return {
79
- id,
80
- text: kept ? draft.text : withQuote(draft.quote, draft.text),
81
- ...(kept ? { quote: { text: draft.quote, chatId, itemId: draft.quoteSource } } : {}),
82
- mentions: [...draft.mentions],
83
- skills: [...draft.skills],
84
- chats: [...draft.chats],
85
- attachments: draft.attachments.map((attachment) => ({ name: attachment.name, mime: attachment.mime, size: uploadBytes(attachment) })),
86
- createdAt: now
87
- };
75
+ if (isEmptyDraft(draft)) {
76
+ return null;
77
+ }
78
+ const kept = draft.quote !== '' && draft.quoteSource !== null;
79
+ return {
80
+ id,
81
+ text: kept ? draft.text : withQuote(draft.quote, draft.text),
82
+ ...(kept ? {
83
+ quote: {
84
+ text: draft.quote,
85
+ chatId,
86
+ itemId: draft.quoteSource
87
+ }
88
+ } : {}),
89
+ mentions: [...draft.mentions],
90
+ skills: [...draft.skills],
91
+ chats: [...draft.chats],
92
+ attachments: draft.attachments.map(attachment => ({
93
+ name: attachment.name,
94
+ mime: attachment.mime,
95
+ size: uploadBytes(attachment)
96
+ })),
97
+ createdAt: now
98
+ };
88
99
  }
89
100
  /* The limit of `chats` in a send. */
90
101
  export const STASH_CHATS_LIMIT = 16;
@@ -93,26 +104,35 @@ export const STASH_CHATS_LIMIT = 16;
93
104
  * order they were picked. `dropped` counts the chats left out because the project no longer has them.
94
105
  */
95
106
  export function restorableChats(stashed, referable, chatId) {
96
- const others = stashed.filter((id) => id !== chatId);
97
- const chats = others.filter((id) => referable.has(id));
98
- return { chats: chats.slice(0, STASH_CHATS_LIMIT), dropped: others.length - chats.length };
107
+ const others = stashed.filter(id => id !== chatId);
108
+ const chats = others.filter(id => referable.has(id));
109
+ return {
110
+ chats: chats.slice(0, STASH_CHATS_LIMIT),
111
+ dropped: others.length - chats.length
112
+ };
99
113
  }
100
114
  const storage = persistedJson(storageKey, parseStash, [], () => chatStorageLegacyKeys('stash'));
101
115
  /* Prompts put aside for later can move to another chat, so the shelf is shared across chats. */
102
- export const useStash = createChatStore(() => ({ prompts: [] }), (store) => store.setState({ prompts: storage.read() }));
116
+ export const useStash = createChatStore(() => ({
117
+ prompts: []
118
+ }), store => store.setState({
119
+ prompts: storage.read()
120
+ }));
103
121
  function write(prompts) {
104
- useStash.setState({ prompts });
105
- storage.write(prompts);
122
+ useStash.setState({
123
+ prompts
124
+ });
125
+ storage.write(prompts);
106
126
  }
107
127
  /* Puts a draft on the shelf; false when the composer held nothing to put there. */
108
128
  export function stashDraft(draft, chatId) {
109
- const entry = stashedFrom(draft, `stash-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`, Date.now(), chatId);
110
- if (!entry) {
111
- return false;
112
- }
113
- write(withStashed(useStash.getState().prompts, entry));
114
- return true;
129
+ const entry = stashedFrom(draft, `stash-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`, Date.now(), chatId);
130
+ if (!entry) {
131
+ return false;
132
+ }
133
+ write(withStashed(useStash.getState().prompts, entry));
134
+ return true;
115
135
  }
116
136
  export function forgetStashed(id) {
117
- write(useStash.getState().prompts.filter((entry) => entry.id !== id));
118
- }
137
+ write(useStash.getState().prompts.filter(entry => entry.id !== id));
138
+ }
@@ -3,16 +3,16 @@ import { errorCode, isConnectionError } from '../transport.js';
3
3
  // What the panel opens on: the newest end of the conversation, which is where an agent that works is.
4
4
  export const SUBAGENT_PAGE = 60;
5
5
  export const INITIAL_CONVERSATION = {
6
- status: 'loading',
7
- items: [],
8
- pending: [],
9
- source: null,
10
- context: null,
11
- cursor: null,
12
- live: false,
13
- loadingEarlier: false,
14
- error: null,
15
- unsupported: false
6
+ status: 'loading',
7
+ items: [],
8
+ pending: [],
9
+ source: null,
10
+ context: null,
11
+ cursor: null,
12
+ live: false,
13
+ loadingEarlier: false,
14
+ error: null,
15
+ unsupported: false
16
16
  };
17
17
  /*
18
18
  * The newest page laid over what is on screen. An item that is already there is replaced where it
@@ -20,27 +20,32 @@ export const INITIAL_CONVERSATION = {
20
20
  * happened than one page holds, so what is held is dropped for it rather than shown with a hole.
21
21
  */
22
22
  export function mergeNewest(current, currentCursor, page, pageCursor) {
23
- const known = new Map(current.map((item, index) => [item.id, index]));
24
- if (current.length > 0 && page.length > 0 && !page.some((item) => known.has(item.id))) {
25
- return { items: page, cursor: pageCursor };
23
+ const known = new Map(current.map((item, index) => [item.id, index]));
24
+ if (current.length > 0 && page.length > 0 && !page.some(item => known.has(item.id))) {
25
+ return {
26
+ items: page,
27
+ cursor: pageCursor
28
+ };
29
+ }
30
+ const items = [...current];
31
+ for (const item of page) {
32
+ const index = known.get(item.id);
33
+ if (index === undefined) {
34
+ items.push(item);
35
+ } else {
36
+ items[index] = item;
26
37
  }
27
- const items = [...current];
28
- for (const item of page) {
29
- const index = known.get(item.id);
30
- if (index === undefined) {
31
- items.push(item);
32
- }
33
- else {
34
- items[index] = item;
35
- }
36
- }
37
- return { items, cursor: current.length === 0 ? pageCursor : currentCursor };
38
+ }
39
+ return {
40
+ items,
41
+ cursor: current.length === 0 ? pageCursor : currentCursor
42
+ };
38
43
  }
39
44
  function pendingOf(items) {
40
- return items.filter((item) => (item.kind === 'approval' && item.decision === 'pending') || (item.kind === 'question' && item.state === 'pending'));
45
+ return items.filter(item => item.kind === 'approval' && item.decision === 'pending' || item.kind === 'question' && item.state === 'pending');
41
46
  }
42
47
  function messageOf(error) {
43
- return error instanceof Error ? error.message : i18next.t('agent-chat:subagents.noAnswer');
48
+ return error instanceof Error ? error.message : i18next.t('agent-chat:subagents.noAnswer');
44
49
  }
45
50
  /*
46
51
  * One subagent's conversation as a panel follows it. Opening asks for the newest page and holds the
@@ -49,125 +54,162 @@ function messageOf(error) {
49
54
  * last thing it says.
50
55
  */
51
56
  export class SubagentConversation {
52
- transport;
53
- chatId;
54
- toolUseId;
55
- onChange;
56
- unsubscribe = [];
57
- state = INITIAL_CONVERSATION;
58
- disposed = false;
59
- // One request at a time, so a refresh never lands under an older page that arrived after it.
60
- queue = Promise.resolve();
61
- refreshWaiting = false;
62
- earlier = null;
63
- constructor(transport, chatId, toolUseId, onChange) {
64
- this.transport = transport;
65
- this.chatId = chatId;
66
- this.toolUseId = toolUseId;
67
- this.onChange = onChange;
68
- }
69
- get current() {
70
- return this.state;
57
+ transport;
58
+ chatId;
59
+ toolUseId;
60
+ onChange;
61
+ unsubscribe = [];
62
+ state = INITIAL_CONVERSATION;
63
+ disposed = false;
64
+ // One request at a time, so a refresh never lands under an older page that arrived after it.
65
+ queue = Promise.resolve();
66
+ refreshWaiting = false;
67
+ earlier = null;
68
+ constructor(transport, chatId, toolUseId, onChange) {
69
+ this.transport = transport;
70
+ this.chatId = chatId;
71
+ this.toolUseId = toolUseId;
72
+ this.onChange = onChange;
73
+ }
74
+ get current() {
75
+ return this.state;
76
+ }
77
+ start() {
78
+ this.unsubscribe.push(this.transport.on('chat.subagentChanged', event => {
79
+ if (event.chatId === this.chatId && event.toolUseId === this.toolUseId) {
80
+ void this.refresh();
81
+ }
82
+ }), this.transport.subscribeStatus(status => {
83
+ if (status === 'open') {
84
+ void this.enqueue(() => this.readNewest(true));
85
+ }
86
+ }));
87
+ return this.enqueue(() => this.readNewest(true));
88
+ }
89
+ /* The newest page again; calls that arrive while one waits become that one. */
90
+ refresh() {
91
+ if (this.refreshWaiting) {
92
+ return this.queue;
71
93
  }
72
- start() {
73
- this.unsubscribe.push(this.transport.on('chat.subagentChanged', (event) => {
74
- if (event.chatId === this.chatId && event.toolUseId === this.toolUseId) {
75
- void this.refresh();
76
- }
77
- }), this.transport.subscribeStatus((status) => {
78
- if (status === 'open') {
79
- void this.enqueue(() => this.readNewest(true));
80
- }
81
- }));
82
- return this.enqueue(() => this.readNewest(true));
83
- }
84
- /* The newest page again; calls that arrive while one waits become that one. */
85
- refresh() {
86
- if (this.refreshWaiting) {
87
- return this.queue;
88
- }
89
- this.refreshWaiting = true;
90
- return this.enqueue(() => {
91
- this.refreshWaiting = false;
92
- return this.readNewest(false);
94
+ this.refreshWaiting = true;
95
+ return this.enqueue(() => {
96
+ this.refreshWaiting = false;
97
+ return this.readNewest(false);
98
+ });
99
+ }
100
+ loadEarlier() {
101
+ // A page on its way answers every call made meanwhile; a scroll asks for one on every frame.
102
+ this.earlier ??= this.enqueue(async () => {
103
+ const cursor = this.state.cursor;
104
+ if (cursor === null) {
105
+ return;
106
+ }
107
+ this.set({
108
+ loadingEarlier: true
109
+ });
110
+ try {
111
+ const page = await this.ask({
112
+ cursor,
113
+ limit: SUBAGENT_PAGE
93
114
  });
94
- }
95
- loadEarlier() {
96
- // A page on its way answers every call made meanwhile; a scroll asks for one on every frame.
97
- this.earlier ??= this.enqueue(async () => {
98
- const cursor = this.state.cursor;
99
- if (cursor === null) {
100
- return;
101
- }
102
- this.set({ loadingEarlier: true });
103
- try {
104
- const page = await this.ask({ cursor, limit: SUBAGENT_PAGE });
105
- const items = [...page.items, ...this.state.items];
106
- this.set({ items, pending: page.pending ?? pendingOf(items), cursor: page.history.cursor, live: page.live, loadingEarlier: false });
107
- }
108
- catch (error) {
109
- if (errorCode(error) === 'history-expired') {
110
- // The record was written again under this panel; what it holds now is the only truth.
111
- this.set({ items: [], cursor: null, loadingEarlier: false });
112
- await this.readNewest(false);
113
- return;
114
- }
115
- this.set({ loadingEarlier: false, error: messageOf(error) });
116
- }
117
- }).finally(() => {
118
- this.earlier = null;
115
+ const items = [...page.items, ...this.state.items];
116
+ this.set({
117
+ items,
118
+ pending: page.pending ?? pendingOf(items),
119
+ cursor: page.history.cursor,
120
+ live: page.live,
121
+ loadingEarlier: false
119
122
  });
120
- return this.earlier;
121
- }
122
- dispose() {
123
- if (this.disposed) {
124
- return;
125
- }
126
- this.disposed = true;
127
- for (const off of this.unsubscribe.splice(0)) {
128
- off();
129
- }
130
- if (this.transport.status === 'open') {
131
- void this.transport.request('chat.subagent', { chatId: this.chatId, toolUseId: this.toolUseId, limit: 1, watch: false }).catch(() => undefined);
123
+ } catch (error) {
124
+ if (errorCode(error) === 'history-expired') {
125
+ // The record was written again under this panel; what it holds now is the only truth.
126
+ this.set({
127
+ items: [],
128
+ cursor: null,
129
+ loadingEarlier: false
130
+ });
131
+ await this.readNewest(false);
132
+ return;
132
133
  }
134
+ this.set({
135
+ loadingEarlier: false,
136
+ error: messageOf(error)
137
+ });
138
+ }
139
+ }).finally(() => {
140
+ this.earlier = null;
141
+ });
142
+ return this.earlier;
143
+ }
144
+ dispose() {
145
+ if (this.disposed) {
146
+ return;
133
147
  }
134
- async readNewest(watch) {
135
- try {
136
- const page = await this.ask({ limit: SUBAGENT_PAGE, ...(watch ? { watch: true } : {}) });
137
- const merged = mergeNewest(this.state.items, this.state.cursor, page.items, page.history.cursor);
138
- this.set({
139
- status: 'ready',
140
- items: merged.items,
141
- pending: page.pending ?? pendingOf(merged.items),
142
- cursor: merged.cursor,
143
- live: page.live,
144
- source: page.source,
145
- context: page.context ?? null,
146
- error: null
147
- });
148
- }
149
- catch (error) {
150
- if (this.state.status === 'ready' && isConnectionError(error)) {
151
- // What is on screen stays; the socket that comes back asks again.
152
- return;
153
- }
154
- const unsupported = errorCode(error) === 'unknown-request';
155
- this.set({ status: 'failed', error: messageOf(error), unsupported });
156
- }
148
+ this.disposed = true;
149
+ for (const off of this.unsubscribe.splice(0)) {
150
+ off();
157
151
  }
158
- ask(extra) {
159
- return this.transport.request('chat.subagent', { chatId: this.chatId, toolUseId: this.toolUseId, ...extra });
152
+ if (this.transport.status === 'open') {
153
+ void this.transport.request('chat.subagent', {
154
+ chatId: this.chatId,
155
+ toolUseId: this.toolUseId,
156
+ limit: 1,
157
+ watch: false
158
+ }).catch(() => undefined);
160
159
  }
161
- enqueue(work) {
162
- const next = this.queue.then(() => (this.disposed ? undefined : work()));
163
- this.queue = next.catch(() => undefined);
164
- return next;
160
+ }
161
+ async readNewest(watch) {
162
+ try {
163
+ const page = await this.ask({
164
+ limit: SUBAGENT_PAGE,
165
+ ...(watch ? {
166
+ watch: true
167
+ } : {})
168
+ });
169
+ const merged = mergeNewest(this.state.items, this.state.cursor, page.items, page.history.cursor);
170
+ this.set({
171
+ status: 'ready',
172
+ items: merged.items,
173
+ pending: page.pending ?? pendingOf(merged.items),
174
+ cursor: merged.cursor,
175
+ live: page.live,
176
+ source: page.source,
177
+ context: page.context ?? null,
178
+ error: null
179
+ });
180
+ } catch (error) {
181
+ if (this.state.status === 'ready' && isConnectionError(error)) {
182
+ // What is on screen stays; the socket that comes back asks again.
183
+ return;
184
+ }
185
+ const unsupported = errorCode(error) === 'unknown-request';
186
+ this.set({
187
+ status: 'failed',
188
+ error: messageOf(error),
189
+ unsupported
190
+ });
165
191
  }
166
- set(patch) {
167
- if (this.disposed) {
168
- return;
169
- }
170
- this.state = { ...this.state, ...patch };
171
- this.onChange(this.state);
192
+ }
193
+ ask(extra) {
194
+ return this.transport.request('chat.subagent', {
195
+ chatId: this.chatId,
196
+ toolUseId: this.toolUseId,
197
+ ...extra
198
+ });
199
+ }
200
+ enqueue(work) {
201
+ const next = this.queue.then(() => this.disposed ? undefined : work());
202
+ this.queue = next.catch(() => undefined);
203
+ return next;
204
+ }
205
+ set(patch) {
206
+ if (this.disposed) {
207
+ return;
172
208
  }
173
- }
209
+ this.state = {
210
+ ...this.state,
211
+ ...patch
212
+ };
213
+ this.onChange(this.state);
214
+ }
215
+ }