@adecore/agents-react 0.31.11 → 0.32.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 (404) hide show
  1. package/dist/agents/AccountDot.js +57 -6
  2. package/dist/agents/AgentIcon.js +88 -12
  3. package/dist/agents/ModelOptionControl.js +153 -18
  4. package/dist/agents/ProviderLogo.js +49 -4
  5. package/dist/agents/account-limits.js +17 -14
  6. package/dist/agents/accounts.js +99 -67
  7. package/dist/agents/agent-marks.js +5 -3
  8. package/dist/agents/model-name.js +42 -31
  9. package/dist/agents/model-options.js +8 -8
  10. package/dist/agents/model-requirement.js +17 -14
  11. package/dist/agents/option-words.d.ts +7 -0
  12. package/dist/agents/option-words.js +35 -0
  13. package/dist/agents/provider-paths.js +6 -6
  14. package/dist/agents/status-look.js +32 -12
  15. package/dist/chat/account-choice.d.ts +13 -0
  16. package/dist/chat/account-choice.js +90 -20
  17. package/dist/chat/actions.js +126 -59
  18. package/dist/chat/activity.js +5 -5
  19. package/dist/chat/attachments.js +74 -53
  20. package/dist/chat/bookmarks.js +58 -48
  21. package/dist/chat/chat-client.js +344 -263
  22. package/dist/chat/chat-references.js +3 -3
  23. package/dist/chat/composer-effort.d.ts +5 -0
  24. package/dist/chat/composer-effort.js +26 -0
  25. package/dist/chat/composer-send.js +13 -13
  26. package/dist/chat/drafts.js +115 -79
  27. package/dist/chat/forks.js +81 -24
  28. package/dist/chat/guards.js +15 -43
  29. package/dist/chat/index.d.ts +3 -1
  30. package/dist/chat/index.js +3 -2
  31. package/dist/chat/logic/ansi.js +170 -167
  32. package/dist/chat/logic/answers.js +2 -2
  33. package/dist/chat/logic/bookmarks.js +19 -19
  34. package/dist/chat/logic/command-looks.js +138 -96
  35. package/dist/chat/logic/context-usage.js +13 -9
  36. package/dist/chat/logic/continue-after-stop.js +15 -19
  37. package/dist/chat/logic/effort.d.ts +14 -0
  38. package/dist/chat/logic/effort.js +34 -0
  39. package/dist/chat/logic/embedded-code.js +387 -326
  40. package/dist/chat/logic/fork.js +134 -110
  41. package/dist/chat/logic/generated-image.js +54 -23
  42. package/dist/chat/logic/goal.js +28 -20
  43. package/dist/chat/logic/handback.js +6 -6
  44. package/dist/chat/logic/json.js +2 -2
  45. package/dist/chat/logic/limit.js +46 -30
  46. package/dist/chat/logic/picker-entries.d.ts +5 -3
  47. package/dist/chat/logic/picker-entries.js +83 -43
  48. package/dist/chat/logic/resume-compaction.d.ts +14 -1
  49. package/dist/chat/logic/resume-compaction.js +93 -24
  50. package/dist/chat/logic/scrubber.js +188 -136
  51. package/dist/chat/logic/thought.js +13 -16
  52. package/dist/chat/logic/thread-cards.js +60 -48
  53. package/dist/chat/logic/timeline-copy.js +30 -38
  54. package/dist/chat/logic/timeline-target.js +92 -63
  55. package/dist/chat/logic/timeline.js +499 -355
  56. package/dist/chat/logic/tool-catalog.js +54 -34
  57. package/dist/chat/logic/tools.js +106 -82
  58. package/dist/chat/logic/visual-height.js +18 -18
  59. package/dist/chat/logic/visual-viewport.js +6 -3
  60. package/dist/chat/logic/welcome.js +9 -9
  61. package/dist/chat/logic/workflow.js +45 -34
  62. package/dist/chat/mentions.js +149 -109
  63. package/dist/chat/persisted-json.js +51 -54
  64. package/dist/chat/preferences.d.ts +4 -0
  65. package/dist/chat/preferences.js +162 -84
  66. package/dist/chat/prompt-hold.js +9 -9
  67. package/dist/chat/quote.js +21 -30
  68. package/dist/chat/reading-width.js +12 -10
  69. package/dist/chat/recent-messages.js +34 -21
  70. package/dist/chat/resume-compaction-dismissals.js +25 -5
  71. package/dist/chat/runtime-modes.js +3 -3
  72. package/dist/chat/send-key.js +11 -7
  73. package/dist/chat/stash.js +89 -69
  74. package/dist/chat/subagent-conversation.js +181 -139
  75. package/dist/chat/subagent-list.js +65 -67
  76. package/dist/chat/subagent-support.js +12 -7
  77. package/dist/chat/subagent-view.js +132 -44
  78. package/dist/chat/thumbnails.js +88 -60
  79. package/dist/chat/timeline-flash.js +24 -12
  80. package/dist/chat/timeline-scroll.js +116 -86
  81. package/dist/chat/ui/AccountPill.js +126 -15
  82. package/dist/chat/ui/AnsiOutput.js +62 -6
  83. package/dist/chat/ui/BookmarkMarker.js +231 -41
  84. package/dist/chat/ui/BookmarkSubmenu.js +165 -18
  85. package/dist/chat/ui/ChatActivity.js +649 -70
  86. package/dist/chat/ui/ChatReferenceChip.js +104 -9
  87. package/dist/chat/ui/CodeBlock.js +132 -58
  88. package/dist/chat/ui/Composer.js +866 -132
  89. package/dist/chat/ui/ComposerInput.js +309 -120
  90. package/dist/chat/ui/DiffPool.js +75 -14
  91. package/dist/chat/ui/EditDiff.js +160 -21
  92. package/dist/chat/ui/FadingWords.js +32 -3
  93. package/dist/chat/ui/GoalDock.js +235 -42
  94. package/dist/chat/ui/ImageView.js +617 -61
  95. package/dist/chat/ui/LimitState.js +446 -72
  96. package/dist/chat/ui/Markdown.js +991 -173
  97. package/dist/chat/ui/MermaidBlock.js +238 -68
  98. package/dist/chat/ui/MessageActions.js +251 -39
  99. package/dist/chat/ui/ModelMarks.js +55 -5
  100. package/dist/chat/ui/Pickers.js +664 -113
  101. package/dist/chat/ui/PromptComposer.js +281 -51
  102. package/dist/chat/ui/QuoteButton.js +151 -57
  103. package/dist/chat/ui/ResumeCompactionDock.d.ts +6 -2
  104. package/dist/chat/ui/ResumeCompactionDock.js +141 -6
  105. package/dist/chat/ui/RowTime.js +59 -5
  106. package/dist/chat/ui/RunSettings.js +1744 -154
  107. package/dist/chat/ui/Scrubber.js +517 -88
  108. package/dist/chat/ui/ShellCommand.js +183 -107
  109. package/dist/chat/ui/SubagentControls.js +212 -24
  110. package/dist/chat/ui/SubagentInfo.js +170 -13
  111. package/dist/chat/ui/SubagentStopButton.js +115 -24
  112. package/dist/chat/ui/SubagentTimeline.js +357 -91
  113. package/dist/chat/ui/Timeline.js +988 -476
  114. package/dist/chat/ui/TimelineMenu.js +552 -37
  115. package/dist/chat/ui/UnifiedDiff.js +234 -27
  116. package/dist/chat/ui/UploadThumb.js +37 -7
  117. package/dist/chat/ui/VisualDialogs.js +251 -20
  118. package/dist/chat/ui/VisualFrame.js +321 -95
  119. package/dist/chat/ui/Welcome.js +72 -7
  120. package/dist/chat/ui/chips.js +1 -1
  121. package/dist/chat/ui/code-lines.js +36 -36
  122. package/dist/chat/ui/code-streaming.js +1 -1
  123. package/dist/chat/ui/code-theme.js +7 -7
  124. package/dist/chat/ui/composer/ComposerControls.js +329 -21
  125. package/dist/chat/ui/composer/ComposerMenu.js +358 -30
  126. package/dist/chat/ui/composer/DraftParts.js +185 -11
  127. package/dist/chat/ui/composer/QueuedMessages.js +138 -13
  128. package/dist/chat/ui/composer/chips.js +29 -19
  129. package/dist/chat/ui/composer/editor.js +79 -63
  130. package/dist/chat/ui/composer/insert.js +26 -12
  131. package/dist/chat/ui/composer/key-handler.js +180 -127
  132. package/dist/chat/ui/composer/keys.js +90 -73
  133. package/dist/chat/ui/composer/menu-aria.js +18 -9
  134. package/dist/chat/ui/composer/placeholder.js +78 -31
  135. package/dist/chat/ui/composer/surface.js +13 -37
  136. package/dist/chat/ui/composer/use-chat-controls.js +230 -90
  137. package/dist/chat/ui/composer/use-compaction-offer.js +50 -18
  138. package/dist/chat/ui/composer/use-composer-draft.js +65 -34
  139. package/dist/chat/ui/composer/use-composer-menus.js +478 -193
  140. package/dist/chat/ui/composer/use-composer-submit.js +251 -109
  141. package/dist/chat/ui/composer/use-continuable-turn.js +33 -6
  142. package/dist/chat/ui/composer/use-draft-files.js +245 -93
  143. package/dist/chat/ui/composer/use-effort-stepper.d.ts +13 -0
  144. package/dist/chat/ui/composer/use-effort-stepper.js +88 -0
  145. package/dist/chat/ui/composer/use-notice.js +61 -16
  146. package/dist/chat/ui/composer/use-pending-requests.js +38 -17
  147. package/dist/chat/ui/composer/use-prompt-history.js +117 -45
  148. package/dist/chat/ui/composer/use-prompt-hold.js +119 -35
  149. package/dist/chat/ui/composer/use-take-back.js +94 -72
  150. package/dist/chat/ui/diff/ApprovalReview.js +101 -23
  151. package/dist/chat/ui/diff/DiffFallbackBoundary.js +21 -13
  152. package/dist/chat/ui/diff/DiffOmitted.js +56 -6
  153. package/dist/chat/ui/diff/DiffStack.js +92 -8
  154. package/dist/chat/ui/diff/DiffUnavailable.js +56 -6
  155. package/dist/chat/ui/diff/EditorEditDiff.js +263 -51
  156. package/dist/chat/ui/diff/EditorPatchDiff.js +39 -14
  157. package/dist/chat/ui/diff/LegacyDiffPool.js +27 -10
  158. package/dist/chat/ui/diff/LegacyEditDiff.js +97 -20
  159. package/dist/chat/ui/diff/LegacyUnifiedDiff.js +172 -42
  160. package/dist/chat/ui/diff/RawDiff.js +65 -5
  161. package/dist/chat/ui/diff/ReviewDiff.js +77 -5
  162. package/dist/chat/ui/diff/diff-props.js +1 -1
  163. package/dist/chat/ui/diff/diff-source-budget.js +46 -35
  164. package/dist/chat/ui/diff/editor-edit-model.js +18 -14
  165. package/dist/chat/ui/diff/review-plan.js +63 -40
  166. package/dist/chat/ui/diff/review-settle.js +24 -9
  167. package/dist/chat/ui/diff/syntax-runtime.js +236 -201
  168. package/dist/chat/ui/diff/use-review-stack.js +146 -25
  169. package/dist/chat/ui/diff-syntax.js +70 -58
  170. package/dist/chat/ui/diff-theme.js +31 -12
  171. package/dist/chat/ui/file-links.js +39 -10
  172. package/dist/chat/ui/find-reveal.js +29 -8
  173. package/dist/chat/ui/full-diff.js +17 -12
  174. package/dist/chat/ui/highlighter.js +143 -113
  175. package/dist/chat/ui/icons.js +16 -7
  176. package/dist/chat/ui/index.js +1 -1
  177. package/dist/chat/ui/intelligent-ui/UiBlockFrame.js +556 -82
  178. package/dist/chat/ui/intelligent-ui/UiFallbackPart.js +73 -5
  179. package/dist/chat/ui/intelligent-ui/UiReply.js +666 -262
  180. package/dist/chat/ui/intelligent-ui/block-local.js +59 -31
  181. package/dist/chat/ui/intelligent-ui/chart-data.js +77 -67
  182. package/dist/chat/ui/intelligent-ui/node-text.js +77 -91
  183. package/dist/chat/ui/intelligent-ui/registry.js +46 -46
  184. package/dist/chat/ui/intelligent-ui/render-context.js +1 -1
  185. package/dist/chat/ui/intelligent-ui/renderers/base-land.js +1 -1
  186. package/dist/chat/ui/intelligent-ui/renderers/binding.js +3 -3
  187. package/dist/chat/ui/intelligent-ui/renderers/chart.js +1223 -123
  188. package/dist/chat/ui/intelligent-ui/renderers/choices.js +312 -34
  189. package/dist/chat/ui/intelligent-ui/renderers/content.js +1241 -86
  190. package/dist/chat/ui/intelligent-ui/renderers/data.js +619 -54
  191. package/dist/chat/ui/intelligent-ui/renderers/inputs.js +868 -67
  192. package/dist/chat/ui/intelligent-ui/renderers/links.js +366 -62
  193. package/dist/chat/ui/intelligent-ui/renderers/map-slots.js +118 -60
  194. package/dist/chat/ui/intelligent-ui/renderers/map-style.js +85 -78
  195. package/dist/chat/ui/intelligent-ui/renderers/map-view.js +282 -217
  196. package/dist/chat/ui/intelligent-ui/renderers/map.js +621 -69
  197. package/dist/chat/ui/intelligent-ui/renderers/place-point.js +15 -8
  198. package/dist/chat/ui/intelligent-ui/renderers/structure.js +262 -20
  199. package/dist/chat/ui/intelligent-ui/renderers/text.js +674 -49
  200. package/dist/chat/ui/intelligent-ui/reply-parts.js +24 -15
  201. package/dist/chat/ui/intelligent-ui/table-data.js +97 -57
  202. package/dist/chat/ui/intelligent-ui/tones.js +31 -31
  203. package/dist/chat/ui/intelligent-ui/use-in-view.js +30 -12
  204. package/dist/chat/ui/intelligent-ui/use-later.js +28 -13
  205. package/dist/chat/ui/intelligent-ui/use-truncated.js +45 -21
  206. package/dist/chat/ui/intelligent-ui/use-ui-links.js +296 -109
  207. package/dist/chat/ui/intelligent-ui/use-ui-queries.js +256 -246
  208. package/dist/chat/ui/markdown-blocks.js +296 -262
  209. package/dist/chat/ui/mermaid.js +60 -72
  210. package/dist/chat/ui/quote-selection.js +32 -29
  211. package/dist/chat/ui/rehype-chips.js +35 -23
  212. package/dist/chat/ui/rehype-fade.js +28 -17
  213. package/dist/chat/ui/remark-html-as-text.js +22 -15
  214. package/dist/chat/ui/reply-context.js +1 -1
  215. package/dist/chat/ui/reveal.js +161 -72
  216. package/dist/chat/ui/rows/ForksRow.js +226 -24
  217. package/dist/chat/ui/rows/GeneratedImageRow.js +541 -87
  218. package/dist/chat/ui/rows/MessageRows.js +1706 -159
  219. package/dist/chat/ui/rows/RowContainer.js +57 -7
  220. package/dist/chat/ui/rows/Rows.js +463 -54
  221. package/dist/chat/ui/rows/SubagentRow.js +577 -60
  222. package/dist/chat/ui/rows/TaskRow.js +359 -40
  223. package/dist/chat/ui/rows/VisualRow.js +233 -11
  224. package/dist/chat/ui/rows/WorkRows.js +1946 -163
  225. package/dist/chat/ui/rows/WorkflowRow.js +293 -34
  226. package/dist/chat/ui/rows/row-rhythm.js +27 -17
  227. package/dist/chat/ui/theme-watch.js +26 -23
  228. package/dist/chat/ui/timestamp-format.js +4 -1
  229. package/dist/chat/ui/use-diff-source-tokens.js +70 -34
  230. package/dist/chat/ui/useToggleSet.js +51 -19
  231. package/dist/chat/ui/visual-theme.js +153 -128
  232. package/dist/chat/visual-bridge.js +123 -123
  233. package/dist/chat/visual-viewport.js +94 -83
  234. package/dist/chat/visuals.js +13 -5
  235. package/dist/host-hooks.d.ts +29 -0
  236. package/dist/host-hooks.js +78 -0
  237. package/dist/host.js +120 -48
  238. package/dist/index.js +1 -1
  239. package/dist/lazy.js +38 -32
  240. package/dist/locales/en/agent-chat.d.ts +35 -0
  241. package/dist/locales/en/agent-chat.js +747 -712
  242. package/dist/locales/en/agent-prompts.js +42 -42
  243. package/dist/locales/en/agent-providers.d.ts +1 -0
  244. package/dist/locales/en/agent-providers.js +166 -165
  245. package/dist/locales/en/agent-usage.d.ts +6 -0
  246. package/dist/locales/en/agent-usage.js +129 -123
  247. package/dist/locales/nl/agent-chat.d.ts +35 -0
  248. package/dist/locales/nl/agent-chat.js +747 -712
  249. package/dist/locales/nl/agent-prompts.js +42 -42
  250. package/dist/locales/nl/agent-providers.d.ts +1 -0
  251. package/dist/locales/nl/agent-providers.js +166 -165
  252. package/dist/locales/nl/agent-usage.d.ts +6 -0
  253. package/dist/locales/nl/agent-usage.js +129 -123
  254. package/dist/locales.js +14 -14
  255. package/dist/mounted-registry.js +31 -30
  256. package/dist/port-transport.js +122 -111
  257. package/dist/prompts/index.js +1 -1
  258. package/dist/prompts/logic/focus.js +15 -14
  259. package/dist/prompts/logic/keys.js +93 -59
  260. package/dist/prompts/logic/prompts.js +27 -14
  261. package/dist/prompts/logic/subjects.js +60 -46
  262. package/dist/prompts/logic/useFocusAfterAnswer.js +60 -20
  263. package/dist/prompts/logic/usePromptSession.js +88 -77
  264. package/dist/prompts/ui/ApprovalBody.js +246 -25
  265. package/dist/prompts/ui/PromptActions.js +215 -9
  266. package/dist/prompts/ui/PromptCard.js +215 -36
  267. package/dist/prompts/ui/PromptView.js +372 -34
  268. package/dist/prompts/ui/QuestionBody.js +269 -73
  269. package/dist/providers/AccountColors.js +36 -5
  270. package/dist/providers/AccountDetail.js +683 -50
  271. package/dist/providers/AccountVariables.js +139 -32
  272. package/dist/providers/AddAccountForm.js +125 -38
  273. package/dist/providers/CliDetail.js +343 -36
  274. package/dist/providers/InstallPage.js +644 -59
  275. package/dist/providers/ProviderList.d.ts +2 -1
  276. package/dist/providers/ProviderList.js +215 -23
  277. package/dist/providers/ProvidersPane.d.ts +4 -2
  278. package/dist/providers/ProvidersPane.js +244 -64
  279. package/dist/providers/account-actions.js +54 -30
  280. package/dist/providers/index.js +1 -1
  281. package/dist/providers/install-steps.js +12 -9
  282. package/dist/providers/pane-target.d.ts +3 -0
  283. package/dist/providers/pane-target.js +34 -13
  284. package/dist/providers/parts.js +62 -12
  285. package/dist/providers/provider-abilities.js +5 -5
  286. package/dist/providers/provider-groups.js +75 -40
  287. package/dist/providers/variables.js +73 -39
  288. package/dist/scope.js +6 -6
  289. package/dist/settings/sections.js +18 -18
  290. package/dist/state/chats.d.ts +1 -0
  291. package/dist/state/chats.js +408 -192
  292. package/dist/state/index.js +1 -1
  293. package/dist/state/provider-accounts.js +70 -47
  294. package/dist/state/providers.js +45 -16
  295. package/dist/state/usage.js +154 -77
  296. package/dist/storage.js +69 -68
  297. package/dist/testing/index.js +1 -1
  298. package/dist/testing/prompts.js +105 -67
  299. package/dist/transport.js +10 -10
  300. package/dist/ui/PlainTextarea.js +27 -3
  301. package/dist/usage/LimitsList.js +646 -40
  302. package/dist/usage/UsageBreakdown.js +879 -38
  303. package/dist/usage/UsageChart.js +311 -32
  304. package/dist/usage/UsageDialog.js +46 -4
  305. package/dist/usage/UsageLimits.js +467 -34
  306. package/dist/usage/UsageLimitsCard.js +95 -11
  307. package/dist/usage/UsagePage.js +817 -96
  308. package/dist/usage/UsagePane.js +164 -10
  309. package/dist/usage/UsageSummary.js +151 -6
  310. package/dist/usage/UsageTiles.js +164 -14
  311. package/dist/usage/format.js +32 -32
  312. package/dist/usage/index.d.ts +1 -1
  313. package/dist/usage/index.js +2 -1
  314. package/dist/usage/limit-groups.d.ts +2 -0
  315. package/dist/usage/limit-groups.js +77 -59
  316. package/dist/usage/limits.js +78 -43
  317. package/dist/usage/money.js +20 -4
  318. package/dist/usage/summary.js +85 -64
  319. package/package.json +8 -8
  320. package/src/agents/ModelOptionControl.tsx +3 -1
  321. package/src/agents/option-words.ts +27 -0
  322. package/src/chat/account-choice.ts +41 -1
  323. package/src/chat/composer-effort.ts +32 -0
  324. package/src/chat/forks.ts +4 -5
  325. package/src/chat/index.ts +3 -1
  326. package/src/chat/logic/effort.ts +32 -0
  327. package/src/chat/logic/picker-entries.ts +45 -10
  328. package/src/chat/logic/resume-compaction.ts +95 -17
  329. package/src/chat/logic/timeline.ts +11 -3
  330. package/src/chat/preferences.ts +35 -0
  331. package/src/chat/subagent-view.ts +2 -3
  332. package/src/chat/ui/AnsiOutput.tsx +1 -2
  333. package/src/chat/ui/BookmarkSubmenu.tsx +3 -3
  334. package/src/chat/ui/ChatActivity.tsx +14 -22
  335. package/src/chat/ui/ChatReferenceChip.tsx +2 -3
  336. package/src/chat/ui/Composer.tsx +15 -7
  337. package/src/chat/ui/EditDiff.tsx +2 -3
  338. package/src/chat/ui/LimitState.tsx +2 -2
  339. package/src/chat/ui/Markdown.tsx +10 -8
  340. package/src/chat/ui/MermaidBlock.tsx +2 -3
  341. package/src/chat/ui/Pickers.tsx +49 -29
  342. package/src/chat/ui/PromptComposer.tsx +7 -9
  343. package/src/chat/ui/ResumeCompactionDock.tsx +16 -4
  344. package/src/chat/ui/RunSettings.tsx +67 -28
  345. package/src/chat/ui/Scrubber.tsx +3 -3
  346. package/src/chat/ui/ShellCommand.tsx +2 -0
  347. package/src/chat/ui/SubagentInfo.tsx +2 -3
  348. package/src/chat/ui/SubagentTimeline.tsx +12 -16
  349. package/src/chat/ui/Timeline.tsx +6 -6
  350. package/src/chat/ui/UnifiedDiff.tsx +3 -4
  351. package/src/chat/ui/VisualFrame.tsx +5 -8
  352. package/src/chat/ui/code-theme.ts +4 -4
  353. package/src/chat/ui/composer/placeholder.ts +2 -2
  354. package/src/chat/ui/composer/use-compaction-offer.ts +36 -16
  355. package/src/chat/ui/composer/use-composer-menus.ts +4 -9
  356. package/src/chat/ui/composer/use-composer-submit.ts +2 -1
  357. package/src/chat/ui/composer/use-effort-stepper.ts +56 -0
  358. package/src/chat/ui/composer/use-notice.ts +2 -2
  359. package/src/chat/ui/diff/EditorEditDiff.tsx +9 -13
  360. package/src/chat/ui/diff/LegacyEditDiff.tsx +12 -17
  361. package/src/chat/ui/diff/LegacyUnifiedDiff.tsx +13 -21
  362. package/src/chat/ui/diff/use-review-stack.ts +4 -4
  363. package/src/chat/ui/diff-theme.ts +3 -3
  364. package/src/chat/ui/file-links.ts +2 -2
  365. package/src/chat/ui/intelligent-ui/UiReply.tsx +2 -0
  366. package/src/chat/ui/intelligent-ui/renderers/chart.tsx +3 -3
  367. package/src/chat/ui/intelligent-ui/renderers/content.tsx +5 -6
  368. package/src/chat/ui/intelligent-ui/renderers/map-view.tsx +2 -1
  369. package/src/chat/ui/intelligent-ui/renderers/map.tsx +2 -1
  370. package/src/chat/ui/intelligent-ui/use-truncated.ts +16 -19
  371. package/src/chat/ui/intelligent-ui/use-ui-links.ts +3 -3
  372. package/src/chat/ui/rows/ForksRow.tsx +3 -5
  373. package/src/chat/ui/rows/GeneratedImageRow.tsx +2 -1
  374. package/src/chat/ui/rows/MessageRows.tsx +12 -21
  375. package/src/chat/ui/rows/SubagentRow.tsx +3 -3
  376. package/src/chat/ui/rows/TaskRow.tsx +1 -1
  377. package/src/chat/ui/rows/WorkRows.tsx +20 -7
  378. package/src/chat/ui/useToggleSet.ts +15 -18
  379. package/src/chat/ui/visual-theme.ts +2 -3
  380. package/src/host-hooks.ts +113 -0
  381. package/src/lazy.tsx +2 -0
  382. package/src/locales/en/agent-chat.ts +135 -108
  383. package/src/locales/en/agent-prompts.ts +7 -7
  384. package/src/locales/en/agent-providers.ts +35 -34
  385. package/src/locales/en/agent-usage.ts +26 -20
  386. package/src/locales/nl/agent-chat.ts +127 -100
  387. package/src/locales/nl/agent-prompts.ts +5 -5
  388. package/src/locales/nl/agent-providers.ts +33 -32
  389. package/src/locales/nl/agent-usage.ts +25 -20
  390. package/src/prompts/ui/ApprovalBody.tsx +3 -1
  391. package/src/providers/CliDetail.tsx +2 -1
  392. package/src/providers/InstallPage.tsx +2 -4
  393. package/src/providers/ProviderList.tsx +12 -2
  394. package/src/providers/ProvidersPane.tsx +45 -15
  395. package/src/providers/pane-target.ts +20 -4
  396. package/src/state/chats.ts +7 -2
  397. package/src/usage/LimitsList.tsx +12 -13
  398. package/src/usage/UsageBreakdown.tsx +17 -6
  399. package/src/usage/UsageLimits.tsx +2 -1
  400. package/src/usage/UsagePage.tsx +3 -3
  401. package/src/usage/index.ts +1 -1
  402. package/src/usage/limit-groups.ts +12 -0
  403. package/src/usage/limits.ts +2 -2
  404. package/src/usage/money.ts +1 -2
@@ -4,63 +4,84 @@ import { DEFAULT_READING_WIDTH, isChatReadingWidth } from './reading-width.js';
4
4
  import { DEFAULT_SEND_KEY, isChatSendKey } from './send-key.js';
5
5
  const storageKey = () => chatStorageKey('preferences');
6
6
  export const DEFAULT_CHAT_PREFERENCES = {
7
- selectionByProvider: {},
8
- lastProvider: null,
9
- runtimeMode: 'full-access',
10
- terminalRuntimeMode: 'full-access',
11
- accountByMachine: {},
12
- readingWidth: DEFAULT_READING_WIDTH,
13
- sendKey: DEFAULT_SEND_KEY,
14
- changedAt: 0
7
+ selectionByProvider: {},
8
+ lastProvider: null,
9
+ runtimeMode: 'full-access',
10
+ terminalRuntimeMode: 'full-access',
11
+ accountByMachine: {},
12
+ readingWidth: DEFAULT_READING_WIDTH,
13
+ sendKey: DEFAULT_SEND_KEY,
14
+ favoriteModels: {},
15
+ changedAt: 0
15
16
  };
17
+ /* Only lists of slugs survive, so a hand-edited or older record cannot put something else in the pickers. */
18
+ function parseFavoriteModels(stored) {
19
+ if (typeof stored !== 'object' || stored === null || Array.isArray(stored)) {
20
+ return {};
21
+ }
22
+ return Object.fromEntries(Object.entries(stored).flatMap(([provider, slugs]) => {
23
+ const kept = Array.isArray(slugs) ? slugs.filter(slug => typeof slug === 'string' && slug !== '') : [];
24
+ return kept.length === 0 ? [] : [[provider, kept]];
25
+ }));
26
+ }
16
27
  /*
17
28
  * Only the fields we know today, so what an older build wrote (one global `selection`, the plan
18
29
  * toggle's `interactionMode`) falls away here instead of riding along in every later write. A
19
30
  * global selection cannot be mapped back onto a provider, so it is dropped: one lost pick.
20
31
  */
21
32
  export function parseChatPreferences(raw) {
22
- if (raw === null) {
23
- return DEFAULT_CHAT_PREFERENCES;
24
- }
25
- try {
26
- const stored = JSON.parse(raw);
27
- return {
28
- selectionByProvider: { ...stored.selectionByProvider },
29
- lastProvider: stored.lastProvider ?? null,
30
- runtimeMode: stored.runtimeMode ?? DEFAULT_CHAT_PREFERENCES.runtimeMode,
31
- terminalRuntimeMode: stored.terminalRuntimeMode ?? DEFAULT_CHAT_PREFERENCES.terminalRuntimeMode,
32
- accountByMachine: { ...stored.accountByMachine },
33
- readingWidth: isChatReadingWidth(stored.readingWidth) ? stored.readingWidth : DEFAULT_READING_WIDTH,
34
- sendKey: isChatSendKey(stored.sendKey) ? stored.sendKey : DEFAULT_SEND_KEY,
35
- changedAt: typeof stored.changedAt === 'number' ? stored.changedAt : 0
36
- };
37
- }
38
- catch {
39
- return DEFAULT_CHAT_PREFERENCES;
40
- }
33
+ if (raw === null) {
34
+ return DEFAULT_CHAT_PREFERENCES;
35
+ }
36
+ try {
37
+ const stored = JSON.parse(raw);
38
+ return {
39
+ selectionByProvider: {
40
+ ...stored.selectionByProvider
41
+ },
42
+ lastProvider: stored.lastProvider ?? null,
43
+ runtimeMode: stored.runtimeMode ?? DEFAULT_CHAT_PREFERENCES.runtimeMode,
44
+ terminalRuntimeMode: stored.terminalRuntimeMode ?? DEFAULT_CHAT_PREFERENCES.terminalRuntimeMode,
45
+ accountByMachine: {
46
+ ...stored.accountByMachine
47
+ },
48
+ readingWidth: isChatReadingWidth(stored.readingWidth) ? stored.readingWidth : DEFAULT_READING_WIDTH,
49
+ sendKey: isChatSendKey(stored.sendKey) ? stored.sendKey : DEFAULT_SEND_KEY,
50
+ favoriteModels: parseFavoriteModels(stored.favoriteModels),
51
+ changedAt: typeof stored.changedAt === 'number' ? stored.changedAt : 0
52
+ };
53
+ } catch {
54
+ return DEFAULT_CHAT_PREFERENCES;
55
+ }
41
56
  }
42
57
  /* Which CLI a chat opens on when its node names none: the last one a model was picked for. */
43
58
  export function defaultProvider(preferences) {
44
- return preferences.lastProvider;
59
+ return preferences.lastProvider;
45
60
  }
46
61
  /* The model a chat of this provider starts with; null lets the host fall back to the CLI's own default. */
47
62
  export function selectionFor(preferences, provider) {
48
- const owner = provider ?? preferences.lastProvider;
49
- if (owner === null) {
50
- return null;
51
- }
52
- return preferences.selectionByProvider[owner] ?? null;
63
+ const owner = provider ?? preferences.lastProvider;
64
+ if (owner === null) {
65
+ return null;
66
+ }
67
+ return preferences.selectionByProvider[owner] ?? null;
53
68
  }
54
69
  export function startingSelection(preferences, provider) {
55
- return selectionFor(preferences, provider.kind) ?? (provider.defaultModel === null ? null : { model: provider.defaultModel, options: {} });
70
+ return selectionFor(preferences, provider.kind) ?? (provider.defaultModel === null ? null : {
71
+ model: provider.defaultModel,
72
+ options: {}
73
+ });
56
74
  }
57
75
  /* The pick lands in its provider's slot and makes that provider the global default. */
58
76
  export function withSelection(preferences, provider, selection) {
59
- return {
60
- ...preferences,
61
- selectionByProvider: { ...preferences.selectionByProvider, [provider]: selection },
62
- lastProvider: provider
63
- };
77
+ return {
78
+ ...preferences,
79
+ selectionByProvider: {
80
+ ...preferences.selectionByProvider,
81
+ [provider]: selection
82
+ },
83
+ lastProvider: provider
84
+ };
64
85
  }
65
86
  /*
66
87
  * The account a new agent of this CLI starts under on this machine; null is the CLI's default account.
@@ -68,85 +89,142 @@ export function withSelection(preferences, provider, selection) {
68
89
  * chat is never refused over it; `undefined` is a machine that did not say yet, where the pick stands.
69
90
  */
70
91
  export function accountFor(preferences, scopeId, provider, accounts) {
71
- const picked = preferences.accountByMachine[scopeId]?.[provider] ?? null;
72
- if (picked === null || accounts === undefined) {
73
- return picked;
74
- }
75
- const account = accounts?.accounts[picked];
76
- return account?.kind === provider && account.enabled !== false ? picked : null;
92
+ const picked = preferences.accountByMachine[scopeId]?.[provider] ?? null;
93
+ if (picked === null || accounts === undefined) {
94
+ return picked;
95
+ }
96
+ const account = accounts?.accounts[picked];
97
+ return account?.kind === provider && account.enabled !== false ? picked : null;
77
98
  }
78
99
  /* The default account is what an absent pick means, so picking it takes the pick away. */
79
100
  export function withAccount(preferences, scopeId, provider, account) {
80
- const { [provider]: _previous, ...others } = preferences.accountByMachine[scopeId] ?? {};
81
- const picks = account === null || account === provider ? others : { ...others, [provider]: account };
82
- const { [scopeId]: _machine, ...machines } = preferences.accountByMachine;
83
- return { ...preferences, accountByMachine: Object.keys(picks).length === 0 ? machines : { ...machines, [scopeId]: picks } };
101
+ const {
102
+ [provider]: _previous,
103
+ ...others
104
+ } = preferences.accountByMachine[scopeId] ?? {};
105
+ const picks = account === null || account === provider ? others : {
106
+ ...others,
107
+ [provider]: account
108
+ };
109
+ const {
110
+ [scopeId]: _machine,
111
+ ...machines
112
+ } = preferences.accountByMachine;
113
+ return {
114
+ ...preferences,
115
+ accountByMachine: Object.keys(picks).length === 0 ? machines : {
116
+ ...machines,
117
+ [scopeId]: picks
118
+ }
119
+ };
84
120
  }
85
121
  /* What a machine starts a chat with when it starts one with no client mounting it; `accounts` as `accountFor` takes them. */
86
122
  export function chatPreferencesPayload(preferences, scopeId, accounts) {
87
- const picks = Object.keys(preferences.accountByMachine[scopeId] ?? {}).flatMap((provider) => {
88
- const account = accountFor(preferences, scopeId, provider, accounts);
89
- return account === null ? [] : [[provider, account]];
90
- });
91
- return {
92
- runtimeMode: preferences.runtimeMode,
93
- terminalRuntimeMode: preferences.terminalRuntimeMode,
94
- selections: preferences.selectionByProvider,
95
- ...(picks.length === 0 ? {} : { accounts: Object.fromEntries(picks) }),
96
- changedAt: preferences.changedAt
97
- };
123
+ const picks = Object.keys(preferences.accountByMachine[scopeId] ?? {}).flatMap(provider => {
124
+ const account = accountFor(preferences, scopeId, provider, accounts);
125
+ return account === null ? [] : [[provider, account]];
126
+ });
127
+ return {
128
+ runtimeMode: preferences.runtimeMode,
129
+ terminalRuntimeMode: preferences.terminalRuntimeMode,
130
+ selections: preferences.selectionByProvider,
131
+ ...(picks.length === 0 ? {} : {
132
+ accounts: Object.fromEntries(picks)
133
+ }),
134
+ changedAt: preferences.changedAt
135
+ };
98
136
  }
99
137
  const storage = persistedJson(storageKey, parseChatPreferences, DEFAULT_CHAT_PREFERENCES, () => chatStorageLegacyKeys('preferences'));
100
138
  /* What a new agent starts with: the last model and modes the person picked, like a remembered default. */
101
- export const useChatPreferences = createChatStore(() => DEFAULT_CHAT_PREFERENCES, (store) => store.setState(storage.read(), true));
139
+ export const useChatPreferences = createChatStore(() => DEFAULT_CHAT_PREFERENCES, store => store.setState(storage.read(), true));
102
140
  export function readChatPreferences() {
103
- return useChatPreferences.getState();
141
+ return useChatPreferences.getState();
104
142
  }
105
143
  /* Where the remembered default is kept, which an app with more than one window of the same origin listens for. */
106
144
  export let CHAT_PREFERENCES_KEY = storageKey();
107
145
  onChatStorageConfiguration(() => {
108
- CHAT_PREFERENCES_KEY = storageKey();
146
+ CHAT_PREFERENCES_KEY = storageKey();
109
147
  });
110
148
  /* Reads the remembered default again, once another window of the same origin wrote it. */
111
149
  export function reloadChatPreferences() {
112
- useChatPreferences.setState(storage.read(), true);
150
+ useChatPreferences.setState(storage.read(), true);
113
151
  }
114
152
  function store(preferences) {
115
- useChatPreferences.setState(preferences);
116
- storage.write(preferences);
153
+ useChatPreferences.setState(preferences);
154
+ storage.write(preferences);
117
155
  }
118
156
  function write(preferences) {
119
- store({ ...preferences, changedAt: Date.now() });
157
+ store({
158
+ ...preferences,
159
+ changedAt: Date.now()
160
+ });
120
161
  }
121
162
  /* The composer writes here on every change and the settings dialog too; both edit the same remembered default. */
122
163
  export function rememberChatPreferences(patch) {
123
- write({ ...useChatPreferences.getState(), ...patch });
164
+ write({
165
+ ...useChatPreferences.getState(),
166
+ ...patch
167
+ });
124
168
  }
125
169
  /* The reading width leaves `changedAt` alone: it is no pick a machine weighs against another client's. */
126
170
  export function rememberReadingWidth(readingWidth) {
127
- store({ ...useChatPreferences.getState(), readingWidth });
171
+ store({
172
+ ...useChatPreferences.getState(),
173
+ readingWidth
174
+ });
128
175
  }
129
176
  /* Leaves `changedAt` alone, like the reading width. */
130
177
  export function rememberSendKey(sendKey) {
131
- store({ ...useChatPreferences.getState(), sendKey });
178
+ store({
179
+ ...useChatPreferences.getState(),
180
+ sendKey
181
+ });
132
182
  }
133
183
  export function rememberChatSelection(provider, selection) {
134
- const current = useChatPreferences.getState();
135
- const previous = current.selectionByProvider[provider];
136
- if (current.lastProvider === provider &&
137
- previous?.model === selection.model &&
138
- Object.keys(previous.options).length === Object.keys(selection.options).length &&
139
- Object.entries(selection.options).every(([key, value]) => previous.options[key] === value)) {
140
- return;
141
- }
142
- write(withSelection(current, provider, selection));
184
+ const current = useChatPreferences.getState();
185
+ const previous = current.selectionByProvider[provider];
186
+ if (current.lastProvider === provider && previous?.model === selection.model && Object.keys(previous.options).length === Object.keys(selection.options).length && Object.entries(selection.options).every(([key, value]) => previous.options[key] === value)) {
187
+ return;
188
+ }
189
+ write(withSelection(current, provider, selection));
143
190
  }
144
191
  export function rememberChatAccount(scopeId, provider, account) {
145
- write(withAccount(useChatPreferences.getState(), scopeId, provider, account));
192
+ write(withAccount(useChatPreferences.getState(), scopeId, provider, account));
193
+ }
194
+ /* The starred models of one CLI; a slug only means something inside its own catalog. */
195
+ export function favoriteModelsOf(favorites, provider) {
196
+ return new Set(favorites[provider] ?? []);
197
+ }
198
+ /* Stars a model that was not, and takes the star off one that was. A provider left without any drops out. */
199
+ export function withFavoriteToggled(preferences, provider, slug) {
200
+ const current = preferences.favoriteModels[provider] ?? [];
201
+ const next = current.includes(slug) ? current.filter(each => each !== slug) : [...current, slug];
202
+ const {
203
+ [provider]: _previous,
204
+ ...others
205
+ } = preferences.favoriteModels;
206
+ return {
207
+ ...preferences,
208
+ favoriteModels: next.length === 0 ? others : {
209
+ ...others,
210
+ [provider]: next
211
+ }
212
+ };
213
+ }
214
+ /* Leaves `changedAt` alone: a star orders a person's own pickers and is no pick a machine weighs. */
215
+ export function toggleFavoriteModel(provider, slug) {
216
+ store(withFavoriteToggled(useChatPreferences.getState(), provider, slug));
146
217
  }
147
218
  /* Back to the CLI's own default for this provider; the other providers keep what they had. */
148
219
  export function forgetChatSelection(provider) {
149
- const current = useChatPreferences.getState();
150
- const { [provider]: _dropped, ...rest } = current.selectionByProvider;
151
- write({ ...current, selectionByProvider: rest, lastProvider: current.lastProvider === provider ? null : current.lastProvider });
152
- }
220
+ const current = useChatPreferences.getState();
221
+ const {
222
+ [provider]: _dropped,
223
+ ...rest
224
+ } = current.selectionByProvider;
225
+ write({
226
+ ...current,
227
+ selectionByProvider: rest,
228
+ lastProvider: current.lastProvider === provider ? null : current.lastProvider
229
+ });
230
+ }
@@ -2,15 +2,15 @@
2
2
  export const PROMPT_HOLD_PAUSE_MS = 2000;
3
3
  /* A card waits while the person is composing, or typed less than the pause ago. */
4
4
  export function holdsPrompt(input, now) {
5
- if (input.composing) {
6
- return true;
7
- }
8
- return input.typedAt !== null && now - input.typedAt < PROMPT_HOLD_PAUSE_MS;
5
+ if (input.composing) {
6
+ return true;
7
+ }
8
+ return input.typedAt !== null && now - input.typedAt < PROMPT_HOLD_PAUSE_MS;
9
9
  }
10
10
  /* The milliseconds until the hold lifts by itself; null when it holds until something else lifts it, or does not hold. */
11
11
  export function holdLiftsIn(input, now) {
12
- if (input.composing || input.typedAt === null) {
13
- return null;
14
- }
15
- return Math.max(0, input.typedAt + PROMPT_HOLD_PAUSE_MS - now);
16
- }
12
+ if (input.composing || input.typedAt === null) {
13
+ return null;
14
+ }
15
+ return Math.max(0, input.typedAt + PROMPT_HOLD_PAUSE_MS - now);
16
+ }
@@ -3,42 +3,33 @@
3
3
  * around them, and at most one blank line in a row. A selection of only whitespace quotes nothing.
4
4
  */
5
5
  export function quoteOf(selected) {
6
- const text = selected
7
- .replace(/\r\n?/g, '\n')
8
- .split('\n')
9
- .map((line) => line.replace(/\s+$/, ''))
10
- .join('\n')
11
- .replace(/^\n+|\n+$/g, '')
12
- .replace(/\n{3,}/g, '\n\n');
13
- return text.trim() === '' ? null : text;
6
+ const text = selected.replace(/\r\n?/g, '\n').split('\n').map(line => line.replace(/\s+$/, '')).join('\n').replace(/^\n+|\n+$/g, '').replace(/\n{3,}/g, '\n\n');
7
+ return text.trim() === '' ? null : text;
14
8
  }
15
9
  /* The message as it goes out: the quote as a markdown blockquote, a blank line, then what was typed. */
16
10
  export function withQuote(quote, message) {
17
- if (quote === '') {
18
- return message;
19
- }
20
- const block = quote
21
- .split('\n')
22
- .map((line) => (line === '' ? '>' : `> ${line}`))
23
- .join('\n');
24
- return message === '' ? block : `${block}\n\n${message}`;
11
+ if (quote === '') {
12
+ return message;
13
+ }
14
+ const block = quote.split('\n').map(line => line === '' ? '>' : `> ${line}`).join('\n');
15
+ return message === '' ? block : `${block}\n\n${message}`;
25
16
  }
26
17
  /*
27
18
  * The inverse of `withQuote`: the quote a message opens with and what follows it. Null when the text
28
19
  * does not open with a blockquote that ends on a blank line or the end of the text.
29
20
  */
30
21
  export function splitQuote(text) {
31
- const lines = text.split('\n');
32
- let end = 0;
33
- while (end < lines.length && (lines[end] === '>' || lines[end].startsWith('> '))) {
34
- end += 1;
35
- }
36
- if (end === 0 || (end < lines.length && lines[end] !== '')) {
37
- return null;
38
- }
39
- const quote = lines
40
- .slice(0, end)
41
- .map((line) => line.slice(2))
42
- .join('\n');
43
- return { quote, rest: lines.slice(end + 1).join('\n') };
44
- }
22
+ const lines = text.split('\n');
23
+ let end = 0;
24
+ while (end < lines.length && (lines[end] === '>' || lines[end].startsWith('> '))) {
25
+ end += 1;
26
+ }
27
+ if (end === 0 || end < lines.length && lines[end] !== '') {
28
+ return null;
29
+ }
30
+ const quote = lines.slice(0, end).map(line => line.slice(2)).join('\n');
31
+ return {
32
+ quote,
33
+ rest: lines.slice(end + 1).join('\n')
34
+ };
35
+ }
@@ -3,25 +3,27 @@ export const CHAT_READING_WIDTHS = ['narrow', 'comfortable', 'full'];
3
3
  export const DEFAULT_READING_WIDTH = 'comfortable';
4
4
  // About 75 and 90 characters of the thread's text a line.
5
5
  const MEASURES = {
6
- narrow: 640,
7
- comfortable: 768,
8
- full: Number.POSITIVE_INFINITY
6
+ narrow: 640,
7
+ comfortable: 768,
8
+ full: Number.POSITIVE_INFINITY
9
9
  };
10
10
  export function isChatReadingWidth(value) {
11
- return typeof value === 'string' && CHAT_READING_WIDTHS.includes(value);
11
+ return typeof value === 'string' && CHAT_READING_WIDTHS.includes(value);
12
12
  }
13
13
  /* The widest the content column runs, in pixels; `full` is unbounded. */
14
14
  export function readingMeasure(width) {
15
- return MEASURES[width];
15
+ return MEASURES[width];
16
16
  }
17
17
  /* What `.chat-column-content` and `.chat-composer-content` read their width from. */
18
18
  export function readingWidthStyle(width) {
19
- const measure = MEASURES[width];
20
- return { '--chat-measure': Number.isFinite(measure) ? `${measure}px` : '100%' };
19
+ const measure = MEASURES[width];
20
+ return {
21
+ '--chat-measure': Number.isFinite(measure) ? `${measure}px` : '100%'
22
+ };
21
23
  }
22
24
  export function readingWidthLabel(width) {
23
- return i18next.t(`agent-chat:readingWidth.${width}.label`);
25
+ return i18next.t(`agent-chat:readingWidth.${width}.label`);
24
26
  }
25
27
  export function readingWidthHint(width) {
26
- return i18next.t(`agent-chat:readingWidth.${width}.hint`);
27
- }
28
+ return i18next.t(`agent-chat:readingWidth.${width}.hint`);
29
+ }
@@ -1,36 +1,49 @@
1
1
  const MAX_TOTAL_CHARACTERS = 12_000;
2
2
  const MAX_MESSAGE_CHARACTERS = 3_000;
3
3
  function clipped(text) {
4
- return text.length <= MAX_MESSAGE_CHARACTERS ? { text, truncated: false } : { text: `${text.slice(0, MAX_MESSAGE_CHARACTERS - 1)}…`, truncated: true };
4
+ return text.length <= MAX_MESSAGE_CHARACTERS ? {
5
+ text,
6
+ truncated: false
7
+ } : {
8
+ text: `${text.slice(0, MAX_MESSAGE_CHARACTERS - 1)}…`,
9
+ truncated: true
10
+ };
5
11
  }
6
12
  function isMessage(item) {
7
- return item !== undefined && (item.kind === 'user' || item.kind === 'assistant') && item.text.trim() !== '';
13
+ return item !== undefined && (item.kind === 'user' || item.kind === 'assistant') && item.text.trim() !== '';
8
14
  }
9
15
  /* The last messages of a conversation already cut down to the ones worth reading, clipped to what a reader can take in. */
10
16
  export function recentMessages(eligible, limit) {
11
- const candidates = eligible.slice(-limit);
12
- const messages = [];
13
- let characters = 0;
14
- let truncated = candidates.length < eligible.length;
15
- for (const item of candidates.toReversed()) {
16
- const message = clipped(item.text.trim());
17
- const remaining = MAX_TOTAL_CHARACTERS - characters;
18
- if (remaining <= 0) {
19
- truncated = true;
20
- break;
21
- }
22
- const text = message.text.length <= remaining ? message.text : `${message.text.slice(0, Math.max(0, remaining - 1))}…`;
23
- messages.unshift({ role: item.kind, text, createdAt: item.createdAt });
24
- characters += text.length;
25
- truncated ||= message.truncated || text.length < message.text.length;
17
+ const candidates = eligible.slice(-limit);
18
+ const messages = [];
19
+ let characters = 0;
20
+ let truncated = candidates.length < eligible.length;
21
+ for (const item of candidates.toReversed()) {
22
+ const message = clipped(item.text.trim());
23
+ const remaining = MAX_TOTAL_CHARACTERS - characters;
24
+ if (remaining <= 0) {
25
+ truncated = true;
26
+ break;
26
27
  }
27
- return { messages, truncated };
28
+ const text = message.text.length <= remaining ? message.text : `${message.text.slice(0, Math.max(0, remaining - 1))}…`;
29
+ messages.unshift({
30
+ role: item.kind,
31
+ text,
32
+ createdAt: item.createdAt
33
+ });
34
+ characters += text.length;
35
+ truncated ||= message.truncated || text.length < message.text.length;
36
+ }
37
+ return {
38
+ messages,
39
+ truncated
40
+ };
28
41
  }
29
42
  /* A sub-agent's replies sit in the thread too, and belong to its own conversation rather than the chat's. */
30
43
  export function recentChatMessages(items, order, limit) {
31
- return recentMessages(order.map((id) => items[id]).filter((item) => isMessage(item) && !(item.kind === 'assistant' && item.parentToolUseId)), limit);
44
+ return recentMessages(order.map(id => items[id]).filter(item => isMessage(item) && !(item.kind === 'assistant' && item.parentToolUseId)), limit);
32
45
  }
33
46
  /* Everything in a sub-agent's conversation is its own, so nothing is left out for being nested. */
34
47
  export function recentSubagentMessages(items, limit) {
35
- return recentMessages(items.filter(isMessage), limit);
36
- }
48
+ return recentMessages(items.filter(isMessage), limit);
49
+ }
@@ -1,14 +1,34 @@
1
+ import { c as _c } from "react/compiler-runtime";
1
2
  import { create } from 'zustand';
2
3
  import { useChatScope } from '../scope.js';
3
4
  /*
4
5
  * Which turn a person answered "Keep full history" on, per chat. In memory only: the offer appears
5
6
  * at most once per silence, so a reload asking again costs nothing, and a refusal is not a setting.
6
7
  */
7
- const useDismissals = create(() => ({ byKey: {} }));
8
+ const useDismissals = create(() => ({
9
+ byKey: {}
10
+ }));
8
11
  export function useResumeCompactionDismissal(chatId) {
9
- const { keyOf } = useChatScope();
10
- return useDismissals((s) => s.byKey[keyOf(chatId)] ?? null);
12
+ const $ = _c(3);
13
+ const {
14
+ keyOf
15
+ } = useChatScope();
16
+ let t0;
17
+ if ($[0] !== chatId || $[1] !== keyOf) {
18
+ t0 = s => s.byKey[keyOf(chatId)] ?? null;
19
+ $[0] = chatId;
20
+ $[1] = keyOf;
21
+ $[2] = t0;
22
+ } else {
23
+ t0 = $[2];
24
+ }
25
+ return useDismissals(t0);
11
26
  }
12
27
  export function dismissResumeCompaction(scope, chatId, turnId) {
13
- useDismissals.setState((s) => ({ byKey: { ...s.byKey, [scope.keyOf(chatId)]: turnId } }));
14
- }
28
+ useDismissals.setState(s => ({
29
+ byKey: {
30
+ ...s.byKey,
31
+ [scope.keyOf(chatId)]: turnId
32
+ }
33
+ }));
34
+ }
@@ -6,8 +6,8 @@ import { RuntimeModeSchema } from '@adecore/agent-contracts';
6
6
  */
7
7
  export const RUNTIME_MODES = RuntimeModeSchema.options;
8
8
  export function runtimeModeLabel(mode) {
9
- return i18next.t(`agent-chat:modes.${mode}.label`);
9
+ return i18next.t(`agent-chat:modes.${mode}.label`);
10
10
  }
11
11
  export function runtimeModeHint(mode) {
12
- return i18next.t(`agent-chat:modes.${mode}.hint`);
13
- }
12
+ return i18next.t(`agent-chat:modes.${mode}.hint`);
13
+ }
@@ -3,22 +3,26 @@ import { KEY_SHORTCUTS, shortcut } from '@adecore/ui';
3
3
  export const CHAT_SEND_KEYS = ['enter', 'mod-enter-multiline', 'mod-enter'];
4
4
  export const DEFAULT_SEND_KEY = 'enter';
5
5
  /* Sends, then opens a new chat through the host's `openNewChat`; a key of the composer, for a menu or a list of keys to print. */
6
- export const SEND_AND_NEW_SHORTCUT = /* @__PURE__ */ shortcut('Mod+Alt+Enter');
6
+ export const SEND_AND_NEW_SHORTCUT = /* @__PURE__ */shortcut('Mod+Alt+Enter');
7
7
  export function isChatSendKey(value) {
8
- return typeof value === 'string' && CHAT_SEND_KEYS.includes(value);
8
+ return typeof value === 'string' && CHAT_SEND_KEYS.includes(value);
9
9
  }
10
10
  /* Whether Enter alone adds a line to a message, so only Mod+Enter sends it. */
11
11
  export function modSends(sendKey, multiline) {
12
- return sendKey === 'mod-enter' || (sendKey === 'mod-enter-multiline' && multiline);
12
+ return sendKey === 'mod-enter' || sendKey === 'mod-enter-multiline' && multiline;
13
13
  }
14
14
  /* The key that sends a message, as a hint prints it. */
15
15
  export function sendShortcut(sendKey, multiline) {
16
- return modSends(sendKey, multiline) ? KEY_SHORTCUTS.modEnter : KEY_SHORTCUTS.enter;
16
+ return modSends(sendKey, multiline) ? KEY_SHORTCUTS.modEnter : KEY_SHORTCUTS.enter;
17
17
  }
18
18
  /* `apple` writes Mod as the Command sign, and as Ctrl elsewhere. */
19
19
  export function sendKeyLabel(sendKey, apple) {
20
- return i18next.t(`agent-chat:sendKey.${sendKey}.label`, { mod: apple ? '⌘' : 'Ctrl' });
20
+ return i18next.t(`agent-chat:sendKey.${sendKey}.label`, {
21
+ mod: apple ? '⌘' : 'Ctrl'
22
+ });
21
23
  }
22
24
  export function sendKeyHint(sendKey, apple) {
23
- return i18next.t(`agent-chat:sendKey.${sendKey}.hint`, { mod: apple ? '⌘' : 'Ctrl' });
24
- }
25
+ return i18next.t(`agent-chat:sendKey.${sendKey}.hint`, {
26
+ mod: apple ? '⌘' : 'Ctrl'
27
+ });
28
+ }