@adecore/agents-react 0.23.0 → 0.24.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 (341) hide show
  1. package/README.md +14 -11
  2. package/dist/agents/AccountDot.js +3 -1
  3. package/dist/agents/accounts.d.ts +3 -2
  4. package/dist/agents/accounts.js +5 -6
  5. package/dist/chat/actions.d.ts +2 -2
  6. package/dist/chat/actions.js +8 -5
  7. package/dist/chat/bookmarks.d.ts +5 -3
  8. package/dist/chat/bookmarks.js +13 -14
  9. package/dist/chat/chat-client.d.ts +1 -0
  10. package/dist/chat/chat-client.js +7 -0
  11. package/dist/chat/composer-send.d.ts +3 -0
  12. package/dist/chat/composer-send.js +22 -0
  13. package/dist/chat/forks.js +22 -5
  14. package/dist/chat/index.d.ts +31 -0
  15. package/dist/chat/index.js +28 -0
  16. package/dist/chat/logic/embedded-code.d.ts +8 -0
  17. package/dist/chat/logic/embedded-code.js +371 -0
  18. package/dist/chat/logic/fork.js +1 -0
  19. package/dist/chat/logic/goal.d.ts +6 -0
  20. package/dist/chat/logic/goal.js +26 -0
  21. package/dist/chat/logic/scrubber.d.ts +1 -1
  22. package/dist/chat/logic/scrubber.js +6 -5
  23. package/dist/chat/logic/thought.d.ts +3 -0
  24. package/dist/chat/logic/thought.js +35 -0
  25. package/dist/chat/logic/thread-cards.js +2 -0
  26. package/dist/chat/logic/timeline.d.ts +5 -0
  27. package/dist/chat/logic/timeline.js +22 -1
  28. package/dist/chat/logic/tool-catalog.d.ts +1 -0
  29. package/dist/chat/logic/tool-catalog.js +3 -1
  30. package/dist/chat/logic/tools.d.ts +14 -0
  31. package/dist/chat/logic/tools.js +57 -0
  32. package/dist/chat/preferences.d.ts +6 -0
  33. package/dist/chat/preferences.js +19 -3
  34. package/dist/chat/reading-width.d.ts +9 -0
  35. package/dist/chat/reading-width.js +27 -0
  36. package/dist/chat/send-key.d.ts +10 -0
  37. package/dist/chat/send-key.js +24 -0
  38. package/dist/chat/ui/BookmarkMarker.js +4 -2
  39. package/dist/chat/ui/BookmarkSubmenu.js +4 -3
  40. package/dist/chat/ui/ChatActivity.js +14 -10
  41. package/dist/chat/ui/ChatReferenceChip.js +3 -4
  42. package/dist/chat/ui/CodeBlock.d.ts +2 -1
  43. package/dist/chat/ui/CodeBlock.js +14 -96
  44. package/dist/chat/ui/Composer.d.ts +1 -1
  45. package/dist/chat/ui/Composer.js +117 -906
  46. package/dist/chat/ui/ComposerInput.js +5 -4
  47. package/dist/chat/ui/EditDiff.js +3 -2
  48. package/dist/chat/ui/GoalDock.d.ts +9 -0
  49. package/dist/chat/ui/GoalDock.js +63 -0
  50. package/dist/chat/ui/LimitState.js +5 -3
  51. package/dist/chat/ui/Markdown.d.ts +2 -1
  52. package/dist/chat/ui/Markdown.js +70 -31
  53. package/dist/chat/ui/MermaidBlock.d.ts +3 -0
  54. package/dist/chat/ui/MermaidBlock.js +73 -0
  55. package/dist/chat/ui/MessageActions.js +12 -7
  56. package/dist/chat/ui/Pickers.js +6 -5
  57. package/dist/chat/ui/PromptComposer.js +4 -3
  58. package/dist/chat/ui/RowTime.d.ts +3 -0
  59. package/dist/chat/ui/RowTime.js +12 -0
  60. package/dist/chat/ui/RunSettings.js +5 -4
  61. package/dist/chat/ui/ShellCommand.d.ts +3 -0
  62. package/dist/chat/ui/ShellCommand.js +110 -0
  63. package/dist/chat/ui/SubagentInfo.js +4 -3
  64. package/dist/chat/ui/SubagentStopButton.js +4 -3
  65. package/dist/chat/ui/SubagentTimeline.js +4 -1
  66. package/dist/chat/ui/Timeline.js +70 -40
  67. package/dist/chat/ui/TimelineMenu.d.ts +2 -1
  68. package/dist/chat/ui/TimelineMenu.js +18 -8
  69. package/dist/chat/ui/UnifiedDiff.js +3 -2
  70. package/dist/chat/ui/VisualFrame.js +6 -7
  71. package/dist/chat/ui/code-theme.d.ts +2 -1
  72. package/dist/chat/ui/code-theme.js +4 -4
  73. package/dist/chat/ui/composer/ComposerControls.d.ts +27 -0
  74. package/dist/chat/ui/composer/ComposerControls.js +34 -0
  75. package/dist/chat/ui/composer/ComposerMenu.d.ts +4 -0
  76. package/dist/chat/ui/composer/ComposerMenu.js +46 -0
  77. package/dist/chat/ui/composer/DraftParts.d.ts +18 -0
  78. package/dist/chat/ui/composer/DraftParts.js +25 -0
  79. package/dist/chat/ui/composer/QueuedMessages.d.ts +10 -0
  80. package/dist/chat/ui/composer/QueuedMessages.js +20 -0
  81. package/dist/chat/ui/composer/key-handler.d.ts +20 -0
  82. package/dist/chat/ui/composer/key-handler.js +150 -0
  83. package/dist/chat/ui/composer/keys.d.ts +7 -2
  84. package/dist/chat/ui/composer/keys.js +19 -9
  85. package/dist/chat/ui/composer/placeholder.d.ts +9 -0
  86. package/dist/chat/ui/composer/placeholder.js +38 -0
  87. package/dist/chat/ui/composer/use-chat-controls.d.ts +28 -0
  88. package/dist/chat/ui/composer/use-chat-controls.js +112 -0
  89. package/dist/chat/ui/composer/use-compaction-offer.d.ts +2 -0
  90. package/dist/chat/ui/composer/use-compaction-offer.js +23 -0
  91. package/dist/chat/ui/composer/use-composer-draft.d.ts +14 -0
  92. package/dist/chat/ui/composer/use-composer-draft.js +39 -0
  93. package/dist/chat/ui/composer/use-composer-menus.d.ts +52 -0
  94. package/dist/chat/ui/composer/use-composer-menus.js +232 -0
  95. package/dist/chat/ui/composer/use-composer-submit.d.ts +32 -0
  96. package/dist/chat/ui/composer/use-composer-submit.js +113 -0
  97. package/dist/chat/ui/composer/use-draft-files.d.ts +27 -0
  98. package/dist/chat/ui/composer/use-draft-files.js +111 -0
  99. package/dist/chat/ui/composer/use-notice.d.ts +6 -0
  100. package/dist/chat/ui/composer/use-notice.js +18 -0
  101. package/dist/chat/ui/composer/use-pending-requests.d.ts +2 -0
  102. package/dist/chat/ui/composer/use-pending-requests.js +22 -0
  103. package/dist/chat/ui/composer/use-prompt-history.d.ts +8 -0
  104. package/dist/chat/ui/composer/use-prompt-history.js +57 -0
  105. package/dist/chat/ui/composer/use-prompt-hold.d.ts +6 -0
  106. package/dist/chat/ui/composer/use-prompt-hold.js +48 -0
  107. package/dist/chat/ui/composer/use-take-back.d.ts +13 -0
  108. package/dist/chat/ui/composer/use-take-back.js +82 -0
  109. package/dist/chat/ui/diff/EditorEditDiff.js +4 -3
  110. package/dist/chat/ui/diff/LegacyDiffPool.js +3 -2
  111. package/dist/chat/ui/diff/LegacyEditDiff.js +3 -2
  112. package/dist/chat/ui/diff/LegacyUnifiedDiff.js +3 -2
  113. package/dist/chat/ui/diff/syntax-runtime.d.ts +2 -1
  114. package/dist/chat/ui/diff/syntax-runtime.js +9 -5
  115. package/dist/chat/ui/diff-syntax.d.ts +2 -2
  116. package/dist/chat/ui/diff-syntax.js +1 -2
  117. package/dist/chat/ui/diff-theme.js +10 -9
  118. package/dist/chat/ui/file-links.d.ts +1 -1
  119. package/dist/chat/ui/file-links.js +7 -5
  120. package/dist/chat/ui/highlighter.d.ts +27 -0
  121. package/dist/chat/ui/highlighter.js +151 -0
  122. package/dist/chat/ui/index.d.ts +67 -0
  123. package/dist/chat/ui/index.js +64 -0
  124. package/dist/chat/ui/intelligent-ui/UiReply.js +3 -2
  125. package/dist/chat/ui/intelligent-ui/renderers/content.js +3 -2
  126. package/dist/chat/ui/intelligent-ui/use-ui-links.js +2 -2
  127. package/dist/chat/ui/intelligent-ui/use-ui-queries.js +4 -3
  128. package/dist/chat/ui/markdown-blocks.d.ts +8 -0
  129. package/dist/chat/ui/markdown-blocks.js +260 -12
  130. package/dist/chat/ui/mermaid.d.ts +23 -0
  131. package/dist/chat/ui/mermaid.js +93 -0
  132. package/dist/chat/ui/rows/ForksRow.js +5 -3
  133. package/dist/chat/ui/rows/GeneratedImageRow.js +6 -4
  134. package/dist/chat/ui/rows/MessageRows.d.ts +4 -0
  135. package/dist/chat/ui/rows/MessageRows.js +36 -13
  136. package/dist/chat/ui/rows/Rows.js +3 -1
  137. package/dist/chat/ui/rows/SubagentRow.js +3 -2
  138. package/dist/chat/ui/rows/VisualRow.js +3 -2
  139. package/dist/chat/ui/rows/WorkRows.d.ts +6 -3
  140. package/dist/chat/ui/rows/WorkRows.js +57 -20
  141. package/dist/chat/ui/rows/WorkflowRow.js +3 -2
  142. package/dist/chat/ui/timestamp-format.d.ts +1 -0
  143. package/dist/chat/ui/timestamp-format.js +2 -0
  144. package/dist/chat/ui/use-diff-source-tokens.js +6 -3
  145. package/dist/chat/ui/visual-theme.js +3 -2
  146. package/dist/host.d.ts +9 -6
  147. package/dist/host.js +19 -8
  148. package/dist/index.d.ts +8 -0
  149. package/dist/index.js +9 -0
  150. package/dist/locales/en/agent-chat.d.ts +658 -0
  151. package/dist/locales/en/agent-chat.js +657 -0
  152. package/dist/locales/en/agent-prompts.d.ts +44 -0
  153. package/dist/locales/en/agent-prompts.js +43 -0
  154. package/dist/locales/en/agent-providers.d.ts +132 -0
  155. package/dist/locales/en/agent-providers.js +131 -0
  156. package/dist/locales/en/agent-usage.d.ts +132 -0
  157. package/dist/locales/en/agent-usage.js +131 -0
  158. package/dist/locales/nl/agent-chat.d.ts +658 -0
  159. package/dist/locales/nl/agent-chat.js +657 -0
  160. package/dist/locales/nl/agent-prompts.d.ts +44 -0
  161. package/dist/locales/nl/agent-prompts.js +43 -0
  162. package/dist/locales/nl/agent-providers.d.ts +132 -0
  163. package/dist/locales/nl/agent-providers.js +131 -0
  164. package/dist/locales/nl/agent-usage.d.ts +132 -0
  165. package/dist/locales/nl/agent-usage.js +131 -0
  166. package/dist/locales.js +9 -8
  167. package/dist/prompts/index.d.ts +11 -0
  168. package/dist/prompts/index.js +12 -0
  169. package/dist/prompts/logic/subjects.d.ts +2 -1
  170. package/dist/prompts/logic/subjects.js +6 -4
  171. package/dist/prompts/ui/ApprovalBody.js +6 -4
  172. package/dist/prompts/ui/PromptCard.js +5 -4
  173. package/dist/prompts/ui/PromptView.js +3 -2
  174. package/dist/prompts/ui/QuestionBody.js +3 -2
  175. package/dist/providers/AccountColors.js +2 -2
  176. package/dist/providers/AccountDetail.js +7 -6
  177. package/dist/providers/AccountVariables.js +3 -1
  178. package/dist/providers/AddAccountForm.js +3 -2
  179. package/dist/providers/ProvidersPane.js +4 -3
  180. package/dist/providers/account-actions.d.ts +4 -3
  181. package/dist/providers/account-actions.js +6 -7
  182. package/dist/providers/index.d.ts +16 -0
  183. package/dist/providers/index.js +17 -0
  184. package/dist/providers/provider-abilities.d.ts +2 -1
  185. package/dist/providers/provider-abilities.js +4 -0
  186. package/dist/state/chats.js +4 -2
  187. package/dist/state/index.d.ts +4 -0
  188. package/dist/state/index.js +5 -0
  189. package/dist/testing/index.d.ts +1 -0
  190. package/dist/testing/index.js +2 -0
  191. package/dist/{prompts/logic/prompts.fixtures.d.ts → testing/prompts.d.ts} +1 -1
  192. package/dist/theme.css +13 -3
  193. package/dist/usage/UsageBreakdown.js +3 -2
  194. package/dist/usage/UsageLimits.js +4 -3
  195. package/dist/usage/UsagePage.js +3 -2
  196. package/dist/usage/index.d.ts +15 -0
  197. package/dist/usage/index.js +15 -0
  198. package/package.json +53 -1031
  199. package/src/agents/AccountDot.tsx +3 -1
  200. package/src/agents/accounts.ts +6 -6
  201. package/src/chat/actions.ts +8 -5
  202. package/src/chat/bookmarks.ts +23 -14
  203. package/src/chat/chat-client.ts +8 -0
  204. package/src/chat/composer-send.ts +27 -0
  205. package/src/chat/forks.ts +27 -6
  206. package/src/chat/index.ts +98 -0
  207. package/src/chat/logic/embedded-code.ts +409 -0
  208. package/src/chat/logic/fork.ts +1 -0
  209. package/src/chat/logic/goal.ts +33 -0
  210. package/src/chat/logic/scrubber.ts +6 -5
  211. package/src/chat/logic/thought.ts +40 -0
  212. package/src/chat/logic/thread-cards.ts +2 -0
  213. package/src/chat/logic/timeline.ts +25 -1
  214. package/src/chat/logic/tool-catalog.ts +5 -1
  215. package/src/chat/logic/tools.ts +76 -0
  216. package/src/chat/preferences.ts +26 -3
  217. package/src/chat/reading-width.ts +39 -0
  218. package/src/chat/send-key.ts +38 -0
  219. package/src/chat/ui/BookmarkMarker.tsx +4 -2
  220. package/src/chat/ui/BookmarkSubmenu.tsx +4 -3
  221. package/src/chat/ui/ChatActivity.tsx +14 -10
  222. package/src/chat/ui/ChatReferenceChip.tsx +3 -4
  223. package/src/chat/ui/CodeBlock.tsx +33 -124
  224. package/src/chat/ui/Composer.tsx +162 -1324
  225. package/src/chat/ui/ComposerInput.tsx +5 -4
  226. package/src/chat/ui/EditDiff.tsx +3 -2
  227. package/src/chat/ui/GoalDock.tsx +104 -0
  228. package/src/chat/ui/LimitState.tsx +5 -3
  229. package/src/chat/ui/Markdown.tsx +113 -39
  230. package/src/chat/ui/MermaidBlock.tsx +119 -0
  231. package/src/chat/ui/MessageActions.tsx +13 -8
  232. package/src/chat/ui/Pickers.tsx +8 -7
  233. package/src/chat/ui/PromptComposer.tsx +4 -3
  234. package/src/chat/ui/RowTime.tsx +21 -0
  235. package/src/chat/ui/RunSettings.tsx +9 -4
  236. package/src/chat/ui/ShellCommand.tsx +134 -0
  237. package/src/chat/ui/SubagentInfo.tsx +4 -3
  238. package/src/chat/ui/SubagentStopButton.tsx +4 -3
  239. package/src/chat/ui/SubagentTimeline.tsx +5 -1
  240. package/src/chat/ui/Timeline.tsx +167 -105
  241. package/src/chat/ui/TimelineMenu.tsx +42 -7
  242. package/src/chat/ui/UnifiedDiff.tsx +3 -2
  243. package/src/chat/ui/VisualFrame.tsx +6 -7
  244. package/src/chat/ui/code-theme.ts +4 -4
  245. package/src/chat/ui/composer/ComposerControls.tsx +147 -0
  246. package/src/chat/ui/composer/ComposerMenu.tsx +138 -0
  247. package/src/chat/ui/composer/DraftParts.tsx +86 -0
  248. package/src/chat/ui/composer/QueuedMessages.tsx +64 -0
  249. package/src/chat/ui/composer/key-handler.ts +174 -0
  250. package/src/chat/ui/composer/keys.ts +32 -10
  251. package/src/chat/ui/composer/placeholder.ts +48 -0
  252. package/src/chat/ui/composer/use-chat-controls.ts +134 -0
  253. package/src/chat/ui/composer/use-compaction-offer.ts +25 -0
  254. package/src/chat/ui/composer/use-composer-draft.ts +71 -0
  255. package/src/chat/ui/composer/use-composer-menus.ts +289 -0
  256. package/src/chat/ui/composer/use-composer-submit.ts +163 -0
  257. package/src/chat/ui/composer/use-draft-files.ts +135 -0
  258. package/src/chat/ui/composer/use-notice.ts +28 -0
  259. package/src/chat/ui/composer/use-pending-requests.ts +23 -0
  260. package/src/chat/ui/composer/use-prompt-history.ts +76 -0
  261. package/src/chat/ui/composer/use-prompt-hold.ts +58 -0
  262. package/src/chat/ui/composer/use-take-back.ts +91 -0
  263. package/src/chat/ui/diff/DiffFallbackBoundary.tsx +2 -2
  264. package/src/chat/ui/diff/EditorEditDiff.tsx +4 -3
  265. package/src/chat/ui/diff/LegacyDiffPool.tsx +3 -2
  266. package/src/chat/ui/diff/LegacyEditDiff.tsx +3 -2
  267. package/src/chat/ui/diff/LegacyUnifiedDiff.tsx +3 -2
  268. package/src/chat/ui/diff/syntax-runtime.ts +10 -5
  269. package/src/chat/ui/diff-syntax.ts +2 -2
  270. package/src/chat/ui/diff-theme.ts +10 -9
  271. package/src/chat/ui/file-links.ts +7 -5
  272. package/src/chat/ui/highlighter.ts +185 -0
  273. package/src/chat/ui/index.ts +109 -0
  274. package/src/chat/ui/intelligent-ui/UiReply.tsx +5 -4
  275. package/src/chat/ui/intelligent-ui/renderers/content.tsx +3 -2
  276. package/src/chat/ui/intelligent-ui/use-ui-links.ts +2 -2
  277. package/src/chat/ui/intelligent-ui/use-ui-queries.ts +4 -3
  278. package/src/chat/ui/markdown-blocks.ts +300 -12
  279. package/src/chat/ui/mermaid.ts +118 -0
  280. package/src/chat/ui/rows/ForksRow.tsx +5 -3
  281. package/src/chat/ui/rows/GeneratedImageRow.tsx +6 -4
  282. package/src/chat/ui/rows/MessageRows.tsx +73 -18
  283. package/src/chat/ui/rows/Rows.tsx +14 -1
  284. package/src/chat/ui/rows/SubagentRow.tsx +3 -2
  285. package/src/chat/ui/rows/VisualRow.tsx +3 -2
  286. package/src/chat/ui/rows/WorkRows.tsx +148 -47
  287. package/src/chat/ui/rows/WorkflowRow.tsx +3 -2
  288. package/src/chat/ui/timestamp-format.ts +2 -0
  289. package/src/chat/ui/use-diff-source-tokens.ts +10 -4
  290. package/src/chat/ui/visual-theme.ts +3 -2
  291. package/src/host.ts +31 -15
  292. package/src/index.ts +49 -0
  293. package/src/locales/en/agent-chat.ts +657 -0
  294. package/src/locales/en/agent-prompts.ts +43 -0
  295. package/src/locales/en/agent-providers.ts +131 -0
  296. package/src/locales/en/agent-usage.ts +131 -0
  297. package/src/locales/nl/agent-chat.ts +657 -0
  298. package/src/locales/nl/agent-prompts.ts +43 -0
  299. package/src/locales/nl/agent-providers.ts +131 -0
  300. package/src/locales/nl/agent-usage.ts +132 -0
  301. package/src/locales.ts +9 -8
  302. package/src/prompts/index.ts +35 -0
  303. package/src/prompts/logic/subjects.ts +12 -4
  304. package/src/prompts/ui/ApprovalBody.tsx +6 -4
  305. package/src/prompts/ui/PromptCard.tsx +11 -4
  306. package/src/prompts/ui/PromptView.tsx +3 -2
  307. package/src/prompts/ui/QuestionBody.tsx +3 -2
  308. package/src/providers/AccountColors.tsx +2 -2
  309. package/src/providers/AccountDetail.tsx +13 -7
  310. package/src/providers/AccountVariables.tsx +3 -1
  311. package/src/providers/AddAccountForm.tsx +3 -2
  312. package/src/providers/ProvidersPane.tsx +4 -3
  313. package/src/providers/account-actions.ts +7 -7
  314. package/src/providers/index.ts +17 -0
  315. package/src/providers/provider-abilities.ts +6 -1
  316. package/src/state/chats.ts +4 -2
  317. package/src/state/index.ts +39 -0
  318. package/src/testing/index.ts +2 -0
  319. package/src/{prompts/logic/prompts.fixtures.ts → testing/prompts.ts} +1 -1
  320. package/src/theme.css +13 -3
  321. package/src/usage/UsageBreakdown.tsx +3 -2
  322. package/src/usage/UsageLimits.tsx +4 -3
  323. package/src/usage/UsagePage.tsx +3 -2
  324. package/src/usage/index.ts +16 -0
  325. package/dist/locales/en/agent-chat.json +0 -597
  326. package/dist/locales/en/agent-prompts.json +0 -43
  327. package/dist/locales/en/agent-providers.json +0 -131
  328. package/dist/locales/en/agent-usage.json +0 -131
  329. package/dist/locales/nl/agent-chat.json +0 -597
  330. package/dist/locales/nl/agent-prompts.json +0 -43
  331. package/dist/locales/nl/agent-providers.json +0 -131
  332. package/dist/locales/nl/agent-usage.json +0 -131
  333. package/src/locales/en/agent-chat.json +0 -597
  334. package/src/locales/en/agent-prompts.json +0 -43
  335. package/src/locales/en/agent-providers.json +0 -131
  336. package/src/locales/en/agent-usage.json +0 -131
  337. package/src/locales/nl/agent-chat.json +0 -597
  338. package/src/locales/nl/agent-prompts.json +0 -43
  339. package/src/locales/nl/agent-providers.json +0 -131
  340. package/src/locales/nl/agent-usage.json +0 -131
  341. /package/dist/{prompts/logic/prompts.fixtures.js → testing/prompts.js} +0 -0
@@ -1,9 +1,11 @@
1
1
  import clsx from 'clsx';
2
+ import { useChatHost } from '../host';
2
3
  import { accountColor } from './accounts';
3
4
 
4
5
  /* The color an account wears, or the app's accent while it wears none of the accents. */
5
6
  export function AccountDot({ color, className }: { color: string | undefined; className?: string }) {
6
- const paint = accountColor(color);
7
+ const { accents } = useChatHost();
8
+ const paint = accountColor(color, accents.all);
7
9
  return (
8
10
  <span
9
11
  aria-hidden
@@ -1,13 +1,13 @@
1
1
  import i18next from 'i18next';
2
2
  import type { AgentKind, ProviderAccount, ProviderAccounts, ProviderAccountStatus } from '@adecore/agent-contracts';
3
- import { chatHost } from '../host';
3
+ import type { AccentChoice, ChatHost } from '../host';
4
4
 
5
5
  /*
6
6
  * An account wears one of the host's accents, so the app paints from one palette. A color that is none
7
7
  * of them (an older name, or one written by hand) reads as undefined, and the dot takes the accent.
8
8
  */
9
- export function accountColor(color: string | undefined): string | undefined {
10
- return chatHost().accents.all.find((entry) => entry.id === color)?.color;
9
+ export function accountColor(color: string | undefined, accents: readonly AccentChoice[]): string | undefined {
10
+ return accents.find((entry) => entry.id === color)?.color;
11
11
  }
12
12
 
13
13
  /*
@@ -102,9 +102,9 @@ export function mintAccountId(kind: AgentKind, label: string, taken: ReadonlySet
102
102
  * The first featured accent no account of the CLI wears yet, then any other, so a new one stands apart.
103
103
  * An account without a color of its own wears `fallback`, the accent the app is painted in.
104
104
  */
105
- export function freeAccountColor(entries: readonly AccountEntry[], fallback: string): string {
106
- const { all, featured } = chatHost().accents;
107
- const worn = new Set(entries.map((entry) => (accountColor(entry.account.color) === undefined ? fallback : entry.account.color)));
105
+ export function freeAccountColor(entries: readonly AccountEntry[], accents: ChatHost['accents'], fallback: string): string {
106
+ const { all, featured } = accents;
107
+ const worn = new Set(entries.map((entry) => (accountColor(entry.account.color, all) === undefined ? fallback : entry.account.color)));
108
108
  const choices = [...featured, ...all.map((entry) => entry.id).filter((id) => !featured.includes(id))];
109
109
  return choices.find((id) => !worn.has(id)) ?? featured[entries.length % featured.length] ?? fallback;
110
110
  }
@@ -1,5 +1,5 @@
1
1
  import i18next from 'i18next';
2
- import { chatHost, type ChatActions } from '../host';
2
+ import { useChatHost, type ChatActions, type ChatHost } from '../host';
3
3
  import { useChatScope, type ChatScope } from '../scope';
4
4
  import { ChatTransportError, type ChatTransport } from '../transport';
5
5
 
@@ -38,6 +38,9 @@ export function transportActions(transport: ChatTransport): ChatActions {
38
38
  stopTask: async (chatId, taskId) => {
39
39
  await transport.request('chat.stopTask', { chatId, taskId });
40
40
  },
41
+ goal: async (chatId, action) => {
42
+ await transport.request('chat.goal', { chatId, action });
43
+ },
41
44
  approve: async (chatId, requestId, decision, message) => {
42
45
  await transport.request('chat.approve', { chatId, requestId, decision, ...(message === undefined ? {} : { message }) });
43
46
  },
@@ -52,9 +55,9 @@ export function transportActions(transport: ChatTransport): ChatActions {
52
55
 
53
56
  const byTransport = new WeakMap<ChatTransport, ChatActions>();
54
57
 
55
- /* The app's own actions when it has them, and the requests of this scope's host otherwise. */
56
- export function actionsOf(scope: ChatScope): ChatActions {
57
- const own = chatHost().actions;
58
+ /* The app's own actions when its host has them, and the requests of this scope's host of chats otherwise. */
59
+ export function actionsOf(scope: ChatScope, host: Pick<ChatHost, 'actions'>): ChatActions {
60
+ const own = host.actions;
58
61
  if (own !== null) {
59
62
  return own;
60
63
  }
@@ -68,5 +71,5 @@ export function actionsOf(scope: ChatScope): ChatActions {
68
71
  }
69
72
 
70
73
  export function useChatActions(): ChatActions {
71
- return actionsOf(useChatScope());
74
+ return actionsOf(useChatScope(), useChatHost());
72
75
  }
@@ -1,7 +1,7 @@
1
1
  import i18next from 'i18next';
2
2
  import { create } from 'zustand';
3
3
  import type { ChatBookmark } from '@adecore/agent-contracts';
4
- import { chatHost } from '../host';
4
+ import type { ChatHost } from '../host';
5
5
  import type { ChatScope } from '../scope';
6
6
  import { jumpToTimelineItem } from './timeline-scroll';
7
7
 
@@ -20,24 +20,26 @@ export const useBookmarkNaming = create<BookmarkNaming>((set) => ({
20
20
  close: () => set({ chatKey: null, itemId: null })
21
21
  }));
22
22
 
23
- function failed(title: string, e: unknown): void {
24
- chatHost().notify({ title, description: e instanceof Error ? e.message : String(e), kind: 'error' });
23
+ type Notifier = Pick<ChatHost, 'notify'>;
24
+
25
+ function failed(host: Notifier, title: string, e: unknown): void {
26
+ host.notify({ title, description: e instanceof Error ? e.message : String(e), kind: 'error' });
25
27
  }
26
28
 
27
- async function add(scope: ChatScope, chatId: string, itemId: string, name?: string): Promise<boolean> {
29
+ async function add(scope: ChatScope, host: Notifier, chatId: string, itemId: string, name?: string): Promise<boolean> {
28
30
  try {
29
31
  await scope.chats.addBookmark(chatId, itemId, name);
30
32
  return true;
31
33
  } catch (e) {
32
- failed(i18next.t('agent-chat:bookmarks.addFailed'), e);
34
+ failed(host, i18next.t('agent-chat:bookmarks.addFailed'), e);
33
35
  return false;
34
36
  }
35
37
  }
36
38
 
37
39
  /* Marks a message and opens the field for its name at once, before the host answered. */
38
- export async function placeBookmark(scope: ChatScope, chatId: string, itemId: string): Promise<void> {
40
+ export async function placeBookmark(scope: ChatScope, host: Notifier, chatId: string, itemId: string): Promise<void> {
39
41
  useBookmarkNaming.getState().open(scope.keyOf(chatId), itemId);
40
- if (!(await add(scope, chatId, itemId))) {
42
+ if (!(await add(scope, host, chatId, itemId))) {
41
43
  useBookmarkNaming.getState().close();
42
44
  }
43
45
  }
@@ -46,34 +48,41 @@ export async function placeBookmark(scope: ChatScope, chatId: string, itemId: st
46
48
  * The name a field settles on. A name goes through `addBookmark`, which also names a bookmark that
47
49
  * already stands, so a name typed before the mark itself landed is not refused.
48
50
  */
49
- export async function nameBookmark(scope: ChatScope, chatId: string, itemId: string, name: string, previous: string | undefined): Promise<void> {
51
+ export async function nameBookmark(
52
+ scope: ChatScope,
53
+ host: Notifier,
54
+ chatId: string,
55
+ itemId: string,
56
+ name: string,
57
+ previous: string | undefined
58
+ ): Promise<void> {
50
59
  const next = name.trim();
51
60
  if (next === (previous ?? '')) {
52
61
  return;
53
62
  }
54
63
  if (next !== '') {
55
- await add(scope, chatId, itemId, next);
64
+ await add(scope, host, chatId, itemId, next);
56
65
  return;
57
66
  }
58
67
  try {
59
68
  await scope.chats.renameBookmark(chatId, itemId, '');
60
69
  } catch (e) {
61
- failed(i18next.t('agent-chat:bookmarks.renameFailed'), e);
70
+ failed(host, i18next.t('agent-chat:bookmarks.renameFailed'), e);
62
71
  }
63
72
  }
64
73
 
65
74
  /* Takes a bookmark away at once; the toast puts it back, name and all. */
66
- export async function removeBookmark(scope: ChatScope, chatId: string, bookmark: ChatBookmark): Promise<void> {
75
+ export async function removeBookmark(scope: ChatScope, host: Notifier, chatId: string, bookmark: ChatBookmark): Promise<void> {
67
76
  try {
68
77
  await scope.chats.removeBookmark(chatId, bookmark.itemId);
69
78
  } catch (e) {
70
- failed(i18next.t('agent-chat:bookmarks.removeFailed'), e);
79
+ failed(host, i18next.t('agent-chat:bookmarks.removeFailed'), e);
71
80
  return;
72
81
  }
73
- chatHost().notify({
82
+ host.notify({
74
83
  title: i18next.t('agent-chat:bookmarks.removed'),
75
84
  kind: 'deleted',
76
- action: { label: i18next.t('agent-chat:common.action.undo'), run: () => void add(scope, chatId, bookmark.itemId, bookmark.name) }
85
+ action: { label: i18next.t('agent-chat:common.action.undo'), run: () => void add(scope, host, chatId, bookmark.itemId, bookmark.name) }
77
86
  });
78
87
  }
79
88
 
@@ -216,6 +216,14 @@ export class ChatClient {
216
216
  await this.transport.request('chat.clear', { chatId, ...(force ? { force: true } : {}) });
217
217
  }
218
218
 
219
+ /*
220
+ * Ends the chat's CLI and keeps its conversation, which the next message resumes in a fresh process
221
+ * that reads its skills, plugins and servers again; refused with `chat-busy` while the chat works.
222
+ */
223
+ async restart(chatId: string): Promise<void> {
224
+ await this.transport.request('chat.restart', { chatId });
225
+ }
226
+
219
227
  async kill(chatId: string): Promise<void> {
220
228
  this.mounted.delete(chatId);
221
229
  this.sink.forget(chatId);
@@ -0,0 +1,27 @@
1
+ /* `alternate` sends with the delivery a running turn does not get by default; `and-new` also opens a new chat once it went. */
2
+ export type ComposerSend = 'default' | 'alternate' | 'and-new';
3
+
4
+ /*
5
+ * A command outside the composer, such as a menu row, sends what a composer on screen holds the way its
6
+ * keys do. Keyed with the scope's `keyOf`, the way the app's shortcuts name the chat that has the focus.
7
+ */
8
+ const senders = new Map<string, (how: ComposerSend) => void>();
9
+
10
+ export function registerComposerSender(key: string, send: (how: ComposerSend) => void): () => void {
11
+ senders.set(key, send);
12
+ return () => {
13
+ if (senders.get(key) === send) {
14
+ senders.delete(key);
15
+ }
16
+ };
17
+ }
18
+
19
+ /* False when that chat has no composer on screen. An empty or unsendable draft sends nothing, as with the keys. */
20
+ export function sendFromComposer(key: string, how: ComposerSend = 'default'): boolean {
21
+ const send = senders.get(key);
22
+ if (send === undefined) {
23
+ return false;
24
+ }
25
+ send(how);
26
+ return true;
27
+ }
package/src/chat/forks.ts CHANGED
@@ -2,18 +2,37 @@ import { useMemo } from 'react';
2
2
  import type { ChatInfo } from '@adecore/agent-contracts';
3
3
  import { forkIdsAfter, forkedTurnIds } from './logic/fork';
4
4
  import { useChatScope } from '../scope';
5
- import { useChats, type ChatsById } from '../state/chats';
5
+ import { useChats, type ChatStatuses } from '../state/chats';
6
6
 
7
7
  /* The chats this client holds of one host, which is where the forks it knows of are. */
8
- function* forkInfosOn(byKey: ChatsById, owns: (key: string) => boolean): Generator<ChatInfo> {
9
- for (const [key, state] of Object.entries(byKey)) {
8
+ function* forkInfosOn(statuses: ChatStatuses, owns: (key: string) => boolean): Generator<ChatInfo> {
9
+ for (const [key, state] of Object.entries(statuses)) {
10
10
  if (state.info.forkOf !== undefined && owns(key)) {
11
11
  yield state.info;
12
12
  }
13
13
  }
14
14
  }
15
15
 
16
- /* Selectors answer a joined string, never a new array or set, and split it again in a memo. */
16
+ /*
17
+ * Selectors answer a joined string, never a new array or set, and split it again in a memo. One runs on
18
+ * every write to the store, a streamed word included, so it walks the chats again only once the
19
+ * statuses, which change with an info alone, are others.
20
+ */
21
+ function joinedForks(
22
+ owns: (key: string) => boolean,
23
+ collect: (infos: Iterable<ChatInfo>) => Iterable<string>
24
+ ): (state: { statusByKey: ChatStatuses }) => string {
25
+ let statuses: ChatStatuses | null = null;
26
+ let joined = '';
27
+ return (state) => {
28
+ if (state.statusByKey !== statuses) {
29
+ statuses = state.statusByKey;
30
+ joined = [...collect(forkInfosOn(statuses, owns))].join('\n');
31
+ }
32
+ return joined;
33
+ };
34
+ }
35
+
17
36
  function splitIds(joined: string): string[] {
18
37
  return joined === '' ? [] : joined.split('\n');
19
38
  }
@@ -21,13 +40,15 @@ function splitIds(joined: string): string[] {
21
40
  /* The turns of this chat a fork went on after, for the thread to put a line under. */
22
41
  export function useForkedTurns(chatId: string): ReadonlySet<string> {
23
42
  const { owns } = useChatScope();
24
- const joined = useChats((s) => [...forkedTurnIds(forkInfosOn(s.byKey, owns), chatId)].join('\n'));
43
+ const select = useMemo(() => joinedForks(owns, (infos) => forkedTurnIds(infos, chatId)), [owns, chatId]);
44
+ const joined = useChats(select);
25
45
  return useMemo(() => new Set(splitIds(joined)), [joined]);
26
46
  }
27
47
 
28
48
  /* The forks that went on after this turn of this chat. */
29
49
  export function useForkIdsAfter(chatId: string, turnId: string): string[] {
30
50
  const { owns } = useChatScope();
31
- const joined = useChats((s) => forkIdsAfter(forkInfosOn(s.byKey, owns), chatId, turnId).join('\n'));
51
+ const select = useMemo(() => joinedForks(owns, (infos) => forkIdsAfter(infos, chatId, turnId)), [owns, chatId, turnId]);
52
+ const joined = useChats(select);
32
53
  return useMemo(() => splitIds(joined), [joined]);
33
54
  }
@@ -0,0 +1,98 @@
1
+ // Public API: exports.test.ts snapshots this list, so a name added or dropped here is an API change.
2
+ export { type AccountChoice, useAccountChoice } from './account-choice';
3
+ export { transportActions, actionsOf, useChatActions } from './actions';
4
+ export { backgroundCounts } from './activity';
5
+ export {
6
+ isImageAttachment,
7
+ fileBadge,
8
+ formatBytes,
9
+ checkAttachmentLimits,
10
+ filesOf,
11
+ readAttachments,
12
+ readStoredAttachments,
13
+ uploadPreviewUrl,
14
+ uploadBytes
15
+ } from './attachments';
16
+ export { type ChatSendExtras, ChatClient } from './chat-client';
17
+ export type { ProjectChat } from './chat-references';
18
+ export { sendFromComposer, type ComposerSend } from './composer-send';
19
+ export { EMPTY_DRAFT, useDrafts, readDraft, writeDraft, offerDraft, type ChatDraft } from './drafts';
20
+ export { stripAnsi } from './logic/ansi';
21
+ export {
22
+ FORKABLE_PROVIDERS,
23
+ forkRefusal,
24
+ summaryRefusal,
25
+ lastSettledTurn,
26
+ forkPointOf,
27
+ forkPointLabel,
28
+ type ForkShape,
29
+ forkShapes,
30
+ type ForkCliChoice,
31
+ forkPayload,
32
+ branchRefusal,
33
+ type ForkPoint,
34
+ type ForkWorktreeChoice
35
+ } from './logic/fork';
36
+ export { handbackReportOf } from './logic/handback';
37
+ export { limitView, type LimitView } from './logic/limit';
38
+ export type { TickKind, ScrubberTick } from './logic/scrubber';
39
+ export { type TimedRow, cardRows, visualRows, withTimedRows, timedRowsOf, withThreadCards } from './logic/thread-cards';
40
+ export { EMPTY_TARGET, readTimelineTarget, type TimelineTarget } from './logic/timeline-target';
41
+ export { type TimelineRow, summarizeGroup, deriveTimelineRows, type SubagentBranch, type BaseMoved } from './logic/timeline';
42
+ export { toolSummary, fileChanges, unifiedChanges, approvalChanges, hasFileChanges, type FileChange } from './logic/tools';
43
+ export {
44
+ MENTION_DRAG_TYPE,
45
+ LEGACY_MENTION_DRAG_TYPE,
46
+ MENTION_DRAG_TYPES,
47
+ carriesMentions,
48
+ droppedMentions,
49
+ writeMentionDrag,
50
+ findMentionQuery,
51
+ findSkillQuery,
52
+ insertMention,
53
+ insertSkill,
54
+ presentMentions,
55
+ chipText,
56
+ tokenizeChips,
57
+ type MentionQuery,
58
+ type ChipSegment
59
+ } from './mentions';
60
+ export {
61
+ defaultProvider,
62
+ selectionFor,
63
+ startingSelection,
64
+ accountFor,
65
+ chatPreferencesPayload,
66
+ useChatPreferences,
67
+ readChatPreferences,
68
+ CHAT_PREFERENCES_KEY,
69
+ chatPreferencesKey,
70
+ reloadChatPreferences,
71
+ rememberChatPreferences,
72
+ rememberReadingWidth,
73
+ rememberSendKey,
74
+ rememberChatSelection,
75
+ type ChatPreferences
76
+ } from './preferences';
77
+ export type { HoldRelease } from './prompt-hold';
78
+ export { CHAT_READING_WIDTHS, readingWidthLabel, readingWidthHint, type ChatReadingWidth } from './reading-width';
79
+ export { recentChatMessages, recentSubagentMessages, type RecentChatMessage, type RecentChatMessages } from './recent-messages';
80
+ export { RUNTIME_MODES, runtimeModeLabel, runtimeModeHint } from './runtime-modes';
81
+ export { CHAT_SEND_KEYS, SEND_AND_NEW_SHORTCUT, sendKeyLabel, sendKeyHint, type ChatSendKey } from './send-key';
82
+ export type { StashedAttachment, StashedPrompt, StashedQuote } from './stash';
83
+ export { subagentTitle, summaryWordOf, stopOf, type SubagentStop } from './subagent-list';
84
+ export { useSubagentSupport } from './subagent-support';
85
+ export {
86
+ crumbOf,
87
+ openFromMain,
88
+ composerWrites,
89
+ canOpenSubagent,
90
+ useSubagentView,
91
+ useSubagentTrail,
92
+ useSubagentItem,
93
+ type SubagentStep,
94
+ type SubagentTrail
95
+ } from './subagent-view';
96
+ export { THUMBNAIL_PX, useUploadThumbnail } from './thumbnails';
97
+ export { stepTimelineMessage, jumpToTimelineItem, type TurnTarget, registerTurnJumper, jumpToTimelineTurn, type ItemJumpOptions } from './timeline-scroll';
98
+ export { type StatusWord, statusLookOf, taskStatusWord, type StatusLook, type TaskState } from '../agents/status-look';