@agent-native/toolkit 0.228.0-nightly-20261111212500 → 0.228.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 (361) hide show
  1. package/agent-native.eject.json +2 -0
  2. package/dist/app/agentkit/react/approval-card.d.ts.map +1 -1
  3. package/dist/app/agentkit/react/approval-card.js +5 -3
  4. package/dist/app/agentkit/react/approval-card.js.map +1 -1
  5. package/dist/app/agentkit/react/code-block.d.ts +32 -0
  6. package/dist/app/agentkit/react/code-block.d.ts.map +1 -0
  7. package/dist/app/agentkit/react/code-block.js +125 -0
  8. package/dist/app/agentkit/react/code-block.js.map +1 -0
  9. package/dist/app/agentkit/react/components.d.ts +33 -14
  10. package/dist/app/agentkit/react/components.d.ts.map +1 -1
  11. package/dist/app/agentkit/react/components.js +843 -168
  12. package/dist/app/agentkit/react/components.js.map +1 -1
  13. package/dist/app/agentkit/react/context-usage.d.ts +45 -0
  14. package/dist/app/agentkit/react/context-usage.d.ts.map +1 -0
  15. package/dist/app/agentkit/react/context-usage.js +93 -0
  16. package/dist/app/agentkit/react/context-usage.js.map +1 -0
  17. package/dist/app/agentkit/react/context.d.ts +42 -3
  18. package/dist/app/agentkit/react/context.d.ts.map +1 -1
  19. package/dist/app/agentkit/react/context.js +46 -1
  20. package/dist/app/agentkit/react/context.js.map +1 -1
  21. package/dist/app/agentkit/react/disclosure-content.d.ts +12 -0
  22. package/dist/app/agentkit/react/disclosure-content.d.ts.map +1 -0
  23. package/dist/app/agentkit/react/disclosure-content.js +33 -0
  24. package/dist/app/agentkit/react/disclosure-content.js.map +1 -0
  25. package/dist/app/agentkit/react/duration.d.ts +6 -0
  26. package/dist/app/agentkit/react/duration.d.ts.map +1 -0
  27. package/dist/app/agentkit/react/duration.js +21 -0
  28. package/dist/app/agentkit/react/duration.js.map +1 -0
  29. package/dist/app/agentkit/react/file-change.d.ts +33 -0
  30. package/dist/app/agentkit/react/file-change.d.ts.map +1 -0
  31. package/dist/app/agentkit/react/file-change.js +83 -0
  32. package/dist/app/agentkit/react/file-change.js.map +1 -0
  33. package/dist/app/agentkit/react/file-diff.d.ts +17 -0
  34. package/dist/app/agentkit/react/file-diff.d.ts.map +1 -0
  35. package/dist/app/agentkit/react/file-diff.js +94 -0
  36. package/dist/app/agentkit/react/file-diff.js.map +1 -0
  37. package/dist/app/agentkit/react/index.d.ts +7 -0
  38. package/dist/app/agentkit/react/index.d.ts.map +1 -1
  39. package/dist/app/agentkit/react/index.js +7 -0
  40. package/dist/app/agentkit/react/index.js.map +1 -1
  41. package/dist/app/agentkit/react/question-card.d.ts +67 -0
  42. package/dist/app/agentkit/react/question-card.d.ts.map +1 -0
  43. package/dist/app/agentkit/react/question-card.js +198 -0
  44. package/dist/app/agentkit/react/question-card.js.map +1 -0
  45. package/dist/app/agentkit/react/root.d.ts +3 -2
  46. package/dist/app/agentkit/react/root.d.ts.map +1 -1
  47. package/dist/app/agentkit/react/root.js +2 -2
  48. package/dist/app/agentkit/react/root.js.map +1 -1
  49. package/dist/app/agentkit/react/roving-focus.d.ts +4 -0
  50. package/dist/app/agentkit/react/roving-focus.d.ts.map +1 -0
  51. package/dist/app/agentkit/react/roving-focus.js +75 -0
  52. package/dist/app/agentkit/react/roving-focus.js.map +1 -0
  53. package/dist/app/agentkit/react/stack-trace.d.ts +34 -0
  54. package/dist/app/agentkit/react/stack-trace.d.ts.map +1 -0
  55. package/dist/app/agentkit/react/stack-trace.js +121 -0
  56. package/dist/app/agentkit/react/stack-trace.js.map +1 -0
  57. package/dist/app/agentkit/react/stop-button.d.ts.map +1 -1
  58. package/dist/app/agentkit/react/stop-button.js +22 -6
  59. package/dist/app/agentkit/react/stop-button.js.map +1 -1
  60. package/dist/app/agentkit/react/styles.css +1306 -395
  61. package/dist/app/agentkit/react/terminal.d.ts +28 -0
  62. package/dist/app/agentkit/react/terminal.d.ts.map +1 -0
  63. package/dist/app/agentkit/react/terminal.js +84 -0
  64. package/dist/app/agentkit/react/terminal.js.map +1 -0
  65. package/dist/app/agentkit/react/trace.d.ts +31 -0
  66. package/dist/app/agentkit/react/trace.d.ts.map +1 -0
  67. package/dist/app/agentkit/react/trace.js +73 -0
  68. package/dist/app/agentkit/react/trace.js.map +1 -0
  69. package/dist/app/blocks/library/HighlightedCode.d.ts +2 -1
  70. package/dist/app/blocks/library/HighlightedCode.d.ts.map +1 -1
  71. package/dist/app/blocks/library/HighlightedCode.js +8 -111
  72. package/dist/app/blocks/library/HighlightedCode.js.map +1 -1
  73. package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
  74. package/dist/app/chat/AgentKitAssistantChat.js +23 -245
  75. package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
  76. package/dist/app/chat/agentkit-chat/guided-questions.d.ts +15 -1
  77. package/dist/app/chat/agentkit-chat/guided-questions.d.ts.map +1 -1
  78. package/dist/app/chat/agentkit-chat/guided-questions.js +142 -2
  79. package/dist/app/chat/agentkit-chat/guided-questions.js.map +1 -1
  80. package/dist/app/chat/agentkit-chat/history.js +1 -1
  81. package/dist/app/chat/agentkit-chat/history.js.map +1 -1
  82. package/dist/app/chat/agentkit-chat/index.d.ts +1 -1
  83. package/dist/app/chat/agentkit-chat/index.d.ts.map +1 -1
  84. package/dist/app/chat/agentkit-chat/index.js +1 -1
  85. package/dist/app/chat/agentkit-chat/index.js.map +1 -1
  86. package/dist/app/chat/agentkit-chat/labels.d.ts +5 -0
  87. package/dist/app/chat/agentkit-chat/labels.d.ts.map +1 -0
  88. package/dist/app/chat/agentkit-chat/labels.js +245 -0
  89. package/dist/app/chat/agentkit-chat/labels.js.map +1 -0
  90. package/dist/app/chat/agentkit-chat/questions.d.ts +1 -1
  91. package/dist/app/chat/agentkit-chat/questions.d.ts.map +1 -1
  92. package/dist/app/chat/agentkit-chat/questions.js +1 -1
  93. package/dist/app/chat/agentkit-chat/questions.js.map +1 -1
  94. package/dist/app/chat/agentkit-chat/root.d.ts.map +1 -1
  95. package/dist/app/chat/agentkit-chat/root.js +5 -64
  96. package/dist/app/chat/agentkit-chat/root.js.map +1 -1
  97. package/dist/app/chat/agentkit-chat/work-step-labels.d.ts +2 -0
  98. package/dist/app/chat/agentkit-chat/work-step-labels.d.ts.map +1 -1
  99. package/dist/app/chat/agentkit-chat/work-step-labels.js +31 -0
  100. package/dist/app/chat/agentkit-chat/work-step-labels.js.map +1 -1
  101. package/dist/app/chat/chat/markdown-renderer.d.ts +2 -12
  102. package/dist/app/chat/chat/markdown-renderer.d.ts.map +1 -1
  103. package/dist/app/chat/chat/markdown-renderer.js +2 -41
  104. package/dist/app/chat/chat/markdown-renderer.js.map +1 -1
  105. package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
  106. package/dist/app/chat/chat/tool-call-display.js +2 -2
  107. package/dist/app/chat/chat/tool-call-display.js.map +1 -1
  108. package/dist/app/chat/conversation/AgentConversation.d.ts.map +1 -1
  109. package/dist/app/chat/conversation/AgentConversation.js +2 -37
  110. package/dist/app/chat/conversation/AgentConversation.js.map +1 -1
  111. package/dist/app/chat/tool-cells/BashCell.d.ts +3 -1
  112. package/dist/app/chat/tool-cells/BashCell.d.ts.map +1 -1
  113. package/dist/app/chat/tool-cells/BashCell.js +4 -40
  114. package/dist/app/chat/tool-cells/BashCell.js.map +1 -1
  115. package/dist/app/chat/tool-cells/EditCell.d.ts.map +1 -1
  116. package/dist/app/chat/tool-cells/EditCell.js +5 -108
  117. package/dist/app/chat/tool-cells/EditCell.js.map +1 -1
  118. package/dist/app/chat/tool-cells/FilesChangedSummary.d.ts.map +1 -1
  119. package/dist/app/chat/tool-cells/FilesChangedSummary.js +23 -81
  120. package/dist/app/chat/tool-cells/FilesChangedSummary.js.map +1 -1
  121. package/dist/app/chat/tool-cells/WriteCell.d.ts.map +1 -1
  122. package/dist/app/chat/tool-cells/WriteCell.js +5 -24
  123. package/dist/app/chat/tool-cells/WriteCell.js.map +1 -1
  124. package/dist/app/code-highlighter.d.ts +11 -0
  125. package/dist/app/code-highlighter.d.ts.map +1 -0
  126. package/dist/app/code-highlighter.js +122 -0
  127. package/dist/app/code-highlighter.js.map +1 -0
  128. package/dist/app/context-xray/ThreadContextRing.js +3 -3
  129. package/dist/app/context-xray/ThreadContextRing.js.map +1 -1
  130. package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
  131. package/dist/app/i18n/catalogs/ar-SA.js +22 -0
  132. package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
  133. package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
  134. package/dist/app/i18n/catalogs/de-DE.js +22 -0
  135. package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
  136. package/dist/app/i18n/catalogs/en-US.d.ts +22 -0
  137. package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
  138. package/dist/app/i18n/catalogs/en-US.js +22 -0
  139. package/dist/app/i18n/catalogs/en-US.js.map +1 -1
  140. package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
  141. package/dist/app/i18n/catalogs/es-ES.js +22 -0
  142. package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
  143. package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
  144. package/dist/app/i18n/catalogs/fr-FR.js +22 -0
  145. package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
  146. package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
  147. package/dist/app/i18n/catalogs/hi-IN.js +22 -0
  148. package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
  149. package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
  150. package/dist/app/i18n/catalogs/ja-JP.js +22 -0
  151. package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
  152. package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
  153. package/dist/app/i18n/catalogs/ko-KR.js +22 -0
  154. package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
  155. package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
  156. package/dist/app/i18n/catalogs/pt-BR.js +22 -0
  157. package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
  158. package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
  159. package/dist/app/i18n/catalogs/zh-CN.js +22 -0
  160. package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
  161. package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
  162. package/dist/app/i18n/catalogs/zh-TW.js +22 -0
  163. package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
  164. package/dist/app/onboarding/first-run-first-paint.d.ts +10 -0
  165. package/dist/app/onboarding/first-run-first-paint.d.ts.map +1 -0
  166. package/dist/app/onboarding/first-run-first-paint.js +22 -0
  167. package/dist/app/onboarding/first-run-first-paint.js.map +1 -0
  168. package/dist/app/onboarding/first-run-startup-gate.d.ts +3 -1
  169. package/dist/app/onboarding/first-run-startup-gate.d.ts.map +1 -1
  170. package/dist/app/onboarding/first-run-startup-gate.js +30 -6
  171. package/dist/app/onboarding/first-run-startup-gate.js.map +1 -1
  172. package/dist/app/providers/AppProviders.d.ts.map +1 -1
  173. package/dist/app/providers/AppProviders.js +9 -2
  174. package/dist/app/providers/AppProviders.js.map +1 -1
  175. package/dist/app/providers/BuilderSignupActivation.d.ts +2 -1
  176. package/dist/app/providers/BuilderSignupActivation.d.ts.map +1 -1
  177. package/dist/app/providers/BuilderSignupActivation.js +6 -3
  178. package/dist/app/providers/BuilderSignupActivation.js.map +1 -1
  179. package/dist/app/shared/AppShellSkeleton.d.ts.map +1 -1
  180. package/dist/app/shared/AppShellSkeleton.js +11 -1
  181. package/dist/app/shared/AppShellSkeleton.js.map +1 -1
  182. package/dist/app/styles/agent-native.css +2 -2
  183. package/dist/app/styles/tokens/agent-kit.css +20 -3
  184. package/dist/composer/AgentSuggestionBar.d.ts.map +1 -1
  185. package/dist/composer/AgentSuggestionBar.js +2 -2
  186. package/dist/composer/AgentSuggestionBar.js.map +1 -1
  187. package/dist/composer/ComposerContextMenu.js +4 -4
  188. package/dist/composer/ComposerContextMenu.js.map +1 -1
  189. package/dist/composer/ComposerContextPicker.d.ts.map +1 -1
  190. package/dist/composer/ComposerContextPicker.js +2 -2
  191. package/dist/composer/ComposerContextPicker.js.map +1 -1
  192. package/dist/composer/ComposerContextPickerDialog.d.ts.map +1 -1
  193. package/dist/composer/ComposerContextPickerDialog.js +2 -2
  194. package/dist/composer/ComposerContextPickerDialog.js.map +1 -1
  195. package/dist/composer/ComposerModePicker.d.ts.map +1 -1
  196. package/dist/composer/ComposerModePicker.js +2 -1
  197. package/dist/composer/ComposerModePicker.js.map +1 -1
  198. package/dist/composer/ComposerPlusMenu.js +1 -1
  199. package/dist/composer/ComposerPlusMenu.js.map +1 -1
  200. package/dist/composer/MentionChip.js +1 -1
  201. package/dist/composer/MentionChip.js.map +1 -1
  202. package/dist/composer/MentionPopover.d.ts +3 -0
  203. package/dist/composer/MentionPopover.d.ts.map +1 -1
  204. package/dist/composer/MentionPopover.js +34 -15
  205. package/dist/composer/MentionPopover.js.map +1 -1
  206. package/dist/composer/MessageQueueDrawer.d.ts.map +1 -1
  207. package/dist/composer/MessageQueueDrawer.js +14 -9
  208. package/dist/composer/MessageQueueDrawer.js.map +1 -1
  209. package/dist/composer/PastedTextChip.d.ts.map +1 -1
  210. package/dist/composer/PastedTextChip.js +14 -18
  211. package/dist/composer/PastedTextChip.js.map +1 -1
  212. package/dist/composer/PromptBar.js +1 -1
  213. package/dist/composer/PromptBar.js.map +1 -1
  214. package/dist/composer/PromptComposer.d.ts.map +1 -1
  215. package/dist/composer/PromptComposer.js +11 -9
  216. package/dist/composer/PromptComposer.js.map +1 -1
  217. package/dist/composer/RealtimeVoiceMode.js +2 -2
  218. package/dist/composer/RealtimeVoiceMode.js.map +1 -1
  219. package/dist/composer/TiptapComposer.d.ts.map +1 -1
  220. package/dist/composer/TiptapComposer.js +52 -89
  221. package/dist/composer/TiptapComposer.js.map +1 -1
  222. package/dist/composer/VoiceButton.d.ts +3 -1
  223. package/dist/composer/VoiceButton.d.ts.map +1 -1
  224. package/dist/composer/VoiceButton.js +10 -8
  225. package/dist/composer/VoiceButton.js.map +1 -1
  226. package/dist/composer/composer-notice.js +3 -3
  227. package/dist/composer/composer-notice.js.map +1 -1
  228. package/dist/composer/extensions/FileReference.js +1 -1
  229. package/dist/composer/extensions/FileReference.js.map +1 -1
  230. package/dist/composer/extensions/SkillReference.js +1 -1
  231. package/dist/composer/extensions/SkillReference.js.map +1 -1
  232. package/dist/composer/popover-surface.d.ts +1 -1
  233. package/dist/composer/popover-surface.d.ts.map +1 -1
  234. package/dist/composer/popover-surface.js +1 -1
  235. package/dist/composer/popover-surface.js.map +1 -1
  236. package/dist/context-ui/ContextUsageRing.d.ts +1 -45
  237. package/dist/context-ui/ContextUsageRing.d.ts.map +1 -1
  238. package/dist/context-ui/ContextUsageRing.js +2 -87
  239. package/dist/context-ui/ContextUsageRing.js.map +1 -1
  240. package/dist/context-ui/index.d.ts +2 -2
  241. package/dist/context-ui/index.d.ts.map +1 -1
  242. package/dist/context-ui/index.js +2 -2
  243. package/dist/context-ui/index.js.map +1 -1
  244. package/package.json +4 -4
  245. package/src/app/agentkit/react/approval-card.tsx +14 -2
  246. package/src/app/agentkit/react/code-block.spec.tsx +154 -0
  247. package/src/app/agentkit/react/code-block.tsx +317 -0
  248. package/src/app/agentkit/react/components.interaction.spec.tsx +7 -0
  249. package/src/app/agentkit/react/components.papercuts.spec.tsx +143 -2
  250. package/src/app/agentkit/react/components.spec.tsx +40 -47
  251. package/src/app/agentkit/react/components.tsx +1533 -413
  252. package/src/app/agentkit/react/composer-context.spec.tsx +35 -0
  253. package/src/app/agentkit/react/context-usage.tsx +353 -0
  254. package/src/app/agentkit/react/context.tsx +93 -1
  255. package/src/app/agentkit/react/disclosure-content.ts +42 -0
  256. package/src/app/agentkit/react/disclosures.spec.tsx +62 -4
  257. package/src/app/agentkit/react/duration.ts +22 -0
  258. package/src/app/agentkit/react/file-change.spec.tsx +124 -0
  259. package/src/app/agentkit/react/file-change.tsx +228 -0
  260. package/src/app/agentkit/react/file-diff.ts +110 -0
  261. package/src/app/agentkit/react/index.ts +7 -0
  262. package/src/app/agentkit/react/lifecycle.spec.tsx +565 -20
  263. package/src/app/agentkit/react/markdown.spec.tsx +18 -8
  264. package/src/app/agentkit/react/message-actions.spec.tsx +55 -1
  265. package/src/app/agentkit/react/notices.spec.tsx +4 -4
  266. package/src/app/agentkit/react/optimistic-send.spec.tsx +43 -0
  267. package/src/app/agentkit/react/question-card.spec.tsx +276 -0
  268. package/src/app/agentkit/react/question-card.tsx +533 -0
  269. package/src/app/agentkit/react/root.tsx +4 -0
  270. package/src/app/agentkit/react/roving-focus.spec.tsx +114 -0
  271. package/src/app/agentkit/react/roving-focus.ts +82 -0
  272. package/src/app/agentkit/react/stack-trace.spec.tsx +177 -0
  273. package/src/app/agentkit/react/stack-trace.tsx +281 -0
  274. package/src/app/agentkit/react/stop-button.spec.tsx +40 -0
  275. package/src/app/agentkit/react/stop-button.tsx +22 -5
  276. package/src/app/agentkit/react/styles.css +1306 -395
  277. package/src/app/agentkit/react/subagent-step.spec.tsx +554 -0
  278. package/src/app/agentkit/react/terminal.spec.tsx +228 -0
  279. package/src/app/agentkit/react/terminal.tsx +228 -0
  280. package/src/app/agentkit/react/trace.spec.tsx +120 -0
  281. package/src/app/agentkit/react/trace.tsx +239 -0
  282. package/src/app/blocks/library/HighlightedCode.tsx +14 -126
  283. package/src/app/chat/AgentKitAssistantChat.spec.tsx +28 -12
  284. package/src/app/chat/AgentKitAssistantChat.tsx +27 -253
  285. package/src/app/chat/agentkit-chat/approval-card.spec.tsx +1 -0
  286. package/src/app/chat/agentkit-chat/guided-questions.flow.spec.tsx +381 -0
  287. package/src/app/chat/agentkit-chat/guided-questions.tsx +236 -3
  288. package/src/app/chat/agentkit-chat/history.tsx +1 -1
  289. package/src/app/chat/agentkit-chat/index.ts +2 -0
  290. package/src/app/chat/agentkit-chat/labels.ts +259 -0
  291. package/src/app/chat/agentkit-chat/questions.ts +2 -0
  292. package/src/app/chat/agentkit-chat/root.spec.tsx +18 -0
  293. package/src/app/chat/agentkit-chat/root.tsx +5 -64
  294. package/src/app/chat/agentkit-chat/work-step-labels.ts +42 -0
  295. package/src/app/chat/chat/markdown-renderer.tsx +2 -59
  296. package/src/app/chat/chat/tool-call-display.spec.tsx +26 -14
  297. package/src/app/chat/chat/tool-call-display.tsx +2 -1
  298. package/src/app/chat/conversation/AgentConversation.tsx +2 -50
  299. package/src/app/chat/tool-cells/BashCell.tsx +14 -136
  300. package/src/app/chat/tool-cells/EditCell.tsx +11 -248
  301. package/src/app/chat/tool-cells/FilesChangedSummary.spec.tsx +62 -5
  302. package/src/app/chat/tool-cells/FilesChangedSummary.tsx +31 -162
  303. package/src/app/chat/tool-cells/WriteCell.tsx +11 -121
  304. package/src/app/code-highlighter.ts +131 -0
  305. package/src/app/context-xray/ThreadContextRing.tsx +7 -7
  306. package/src/app/i18n/catalogs/ar-SA.ts +22 -0
  307. package/src/app/i18n/catalogs/de-DE.ts +22 -0
  308. package/src/app/i18n/catalogs/en-US.ts +22 -0
  309. package/src/app/i18n/catalogs/es-ES.ts +22 -0
  310. package/src/app/i18n/catalogs/fr-FR.ts +22 -0
  311. package/src/app/i18n/catalogs/hi-IN.ts +22 -0
  312. package/src/app/i18n/catalogs/ja-JP.ts +22 -0
  313. package/src/app/i18n/catalogs/ko-KR.ts +22 -0
  314. package/src/app/i18n/catalogs/pt-BR.ts +22 -0
  315. package/src/app/i18n/catalogs/zh-CN.ts +22 -0
  316. package/src/app/i18n/catalogs/zh-TW.ts +22 -0
  317. package/src/app/onboarding/first-run-first-paint.spec.ts +39 -0
  318. package/src/app/onboarding/first-run-first-paint.ts +24 -0
  319. package/src/app/onboarding/first-run-startup-gate.spec.tsx +125 -13
  320. package/src/app/onboarding/first-run-startup-gate.tsx +48 -5
  321. package/src/app/providers/AppProviders.tsx +18 -0
  322. package/src/app/providers/BuilderSignupActivation.tsx +8 -2
  323. package/src/app/shared/AppShellSkeleton.spec.tsx +60 -1
  324. package/src/app/shared/AppShellSkeleton.tsx +31 -1
  325. package/src/app/styles/agent-native.css +2 -2
  326. package/src/app/styles/agent-native.spec.ts +2 -2
  327. package/src/app/styles/tokens/agent-kit.css +20 -3
  328. package/src/composer/AgentSuggestionBar.spec.tsx +3 -1
  329. package/src/composer/AgentSuggestionBar.tsx +5 -2
  330. package/src/composer/ComposerContextMenu.tsx +4 -4
  331. package/src/composer/ComposerContextPicker.tsx +8 -2
  332. package/src/composer/ComposerContextPickerDialog.tsx +5 -2
  333. package/src/composer/ComposerModePicker.tsx +2 -1
  334. package/src/composer/ComposerPlusMenu.tsx +1 -1
  335. package/src/composer/MentionChip.tsx +1 -1
  336. package/src/composer/MentionPopover.spec.tsx +108 -2
  337. package/src/composer/MentionPopover.tsx +93 -17
  338. package/src/composer/MessageQueueDrawer.spec.tsx +5 -5
  339. package/src/composer/MessageQueueDrawer.tsx +19 -12
  340. package/src/composer/PastedTextChip.spec.tsx +36 -0
  341. package/src/composer/PastedTextChip.tsx +52 -58
  342. package/src/composer/PromptBar.tsx +1 -1
  343. package/src/composer/PromptComposer.context.spec.tsx +2 -2
  344. package/src/composer/PromptComposer.submission.spec.tsx +27 -0
  345. package/src/composer/PromptComposer.tsx +17 -9
  346. package/src/composer/RealtimeVoiceMode.tsx +2 -2
  347. package/src/composer/TiptapComposer.model-picker.spec.tsx +23 -82
  348. package/src/composer/TiptapComposer.tsx +68 -145
  349. package/src/composer/VoiceButton.tsx +12 -7
  350. package/src/composer/composer-notice.tsx +3 -3
  351. package/src/composer/extensions/FileReference.tsx +1 -1
  352. package/src/composer/extensions/SkillReference.tsx +1 -1
  353. package/src/composer/popover-surface.ts +1 -1
  354. package/src/context-ui/ContextUsageRing.spec.tsx +33 -8
  355. package/src/context-ui/ContextUsageRing.tsx +13 -348
  356. package/src/context-ui/index.ts +7 -1
  357. package/dist/composer/ModelPickerParts.d.ts +0 -20
  358. package/dist/composer/ModelPickerParts.d.ts.map +0 -1
  359. package/dist/composer/ModelPickerParts.js +0 -77
  360. package/dist/composer/ModelPickerParts.js.map +0 -1
  361. package/src/composer/ModelPickerParts.tsx +0 -188
@@ -7,6 +7,7 @@ import { createRoot, hydrateRoot, type Root } from "react-dom/client";
7
7
  import { renderToString } from "react-dom/server";
8
8
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
9
9
 
10
+ import { loadCodeHighlighter } from "../../code-highlighter.js";
10
11
  import { AgentMessagePartView } from "./components.js";
11
12
  import { AgentKitProvider } from "./context.js";
12
13
 
@@ -32,6 +33,14 @@ async function renderPart(
32
33
  });
33
34
  }
34
35
 
36
+ async function settleHighlighting() {
37
+ await act(async () => {
38
+ vi.runAllTimers();
39
+ await loadCodeHighlighter();
40
+ await Promise.resolve();
41
+ });
42
+ }
43
+
35
44
  beforeEach(() => {
36
45
  vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
37
46
  vi.useFakeTimers();
@@ -187,16 +196,16 @@ describe("AgentKit Markdown text parts", () => {
187
196
  { active: false, resetKey: "code-block" },
188
197
  );
189
198
 
190
- const figure = container.querySelector("figure.agentkit-code-block");
199
+ const figure = container.querySelector(".agentkit-code-block");
191
200
  const language = figure?.querySelector(
192
- ".agentkit-code-block-header > span.agentkit-code-block-language",
201
+ ".agentkit-code-block-header > span.agentkit-code-block-title",
193
202
  );
194
203
  const pre = figure?.querySelector<HTMLPreElement>(
195
- ":scope > pre[role='region']",
204
+ ":scope > pre[role='group']",
196
205
  );
197
- expect(language?.textContent).toBe("ts");
206
+ expect(language?.textContent).toBe("TypeScript");
198
207
  expect(pre?.tabIndex).toBe(0);
199
- expect(pre?.getAttribute("aria-label")).toBe("ts code");
208
+ expect(pre?.getAttribute("aria-label")).toBe("TypeScript code");
200
209
  const copy = figure?.querySelector<HTMLButtonElement>(
201
210
  ".agentkit-code-block-header button",
202
211
  );
@@ -218,7 +227,7 @@ describe("AgentKit Markdown text parts", () => {
218
227
  { active: false, resetKey: "plain-code-block" },
219
228
  );
220
229
  expect(
221
- container.querySelector("pre[role='region']")?.getAttribute("aria-label"),
230
+ container.querySelector("pre[role='group']")?.getAttribute("aria-label"),
222
231
  ).toBe("Code block");
223
232
  });
224
233
 
@@ -253,7 +262,7 @@ describe("AgentKit Markdown text parts", () => {
253
262
  { active: false, resetKey: "table" },
254
263
  );
255
264
  const table = container.querySelector(
256
- "div.agentkit-markdown-table[role='region'] > table",
265
+ "div.agentkit-markdown-table[role='group'] > table",
257
266
  );
258
267
  expect(table).not.toBeNull();
259
268
  expect(table?.querySelector("[data-prose]")).toBeNull();
@@ -492,7 +501,7 @@ describe("AgentKit streamed Markdown reveal", () => {
492
501
  expect(container.textContent).not.toMatch(/\*\*|\]\(|`|\|\s*-/);
493
502
  }
494
503
  await renderPart(markdown(text), { active: false, resetKey });
495
- await act(async () => vi.runAllTimers());
504
+ await settleHighlighting();
496
505
  const normalize = (html: string) =>
497
506
  html
498
507
  .replace(/<span class="agentkit-stream-word">([^<]*)<\/span>/g, "$1")
@@ -503,6 +512,7 @@ describe("AgentKit streamed Markdown reveal", () => {
503
512
  await act(async () => root.unmount());
504
513
  root = createRoot(container);
505
514
  await renderPart(markdown(text), { active: false, resetKey: "static" });
515
+ await settleHighlighting();
506
516
 
507
517
  expect(streamedHtml).toBe(container.innerHTML);
508
518
  });
@@ -365,7 +365,7 @@ describe("assistant reply toolbar", () => {
365
365
  expect(latest.dataset.latest).toBe("true");
366
366
  expect(older.dataset.latest).toBeUndefined();
367
367
  expect(footer("assistant-latest").dataset.placement).toBe("inline");
368
- expect(latest.getAttribute("role")).toBe("group");
368
+ expect(latest.getAttribute("role")).toBe("toolbar");
369
369
  expect(labelsOf(set(latest, "primary"))).toEqual([
370
370
  "Copy message",
371
371
  "Good response",
@@ -823,6 +823,60 @@ describe("assistant reply toolbar", () => {
823
823
  });
824
824
  });
825
825
 
826
+ describe("assistant reply toolbar keyboard", () => {
827
+ it("costs one tab stop per reply and moves between actions with the arrow keys", async () => {
828
+ const { toolbar } = await renderChat();
829
+ const latest = toolbar("assistant-latest");
830
+ const stops = () =>
831
+ Array.from(latest.querySelectorAll("button")).filter(
832
+ (button) => button.tabIndex === 0,
833
+ );
834
+ expect(stops().map((button) => button.getAttribute("aria-label"))).toEqual([
835
+ "Copy message",
836
+ ]);
837
+
838
+ await act(async () => stops()[0]?.focus());
839
+ await act(async () => {
840
+ document.activeElement?.dispatchEvent(
841
+ new KeyboardEvent("keydown", { key: "ArrowRight", bubbles: true }),
842
+ );
843
+ });
844
+ expect(document.activeElement?.getAttribute("aria-label")).toBe(
845
+ "Good response",
846
+ );
847
+ expect(stops()).toEqual([document.activeElement]);
848
+ });
849
+
850
+ it("keeps Retry focused and enabled while its fork is in flight", async () => {
851
+ const fork = Promise.withResolvers<{
852
+ id: string;
853
+ createdAt: string;
854
+ updatedAt: string;
855
+ }>();
856
+ const { toolbar } = await renderChat({
857
+ transport: {
858
+ forkThread: vi.fn(() => fork.promise),
859
+ assertAiSetupReady: vi.fn(async () => undefined),
860
+ },
861
+ });
862
+ const latest = toolbar("assistant-latest");
863
+ await press(toggle(latest));
864
+ const retry = latest.querySelector<HTMLButtonElement>(
865
+ 'button[aria-label="Retry"]',
866
+ );
867
+ await act(async () => retry?.focus());
868
+ await press(retry);
869
+
870
+ expect(retry?.disabled).toBe(false);
871
+ expect(retry?.getAttribute("aria-busy")).toBe("true");
872
+ expect(document.activeElement).toBe(retry);
873
+ await act(async () => {
874
+ fork.reject(new Error("offline"));
875
+ await new Promise((resolve) => setTimeout(resolve, 0));
876
+ });
877
+ });
878
+ });
879
+
826
880
  describe("assistant reply toolbar placement", () => {
827
881
  it("sits under the reply, not on the Worked for row above it", async () => {
828
882
  const { container, footer, toolbar } = await renderChat({
@@ -272,7 +272,7 @@ describe("AgentKit recoverable failure notices", () => {
272
272
  expect(row()?.textContent).toContain("Connection to the agent was lost.");
273
273
  });
274
274
 
275
- it("keeps red for a final run failure and amber for a recoverable one", async () => {
275
+ it("marks final and recoverable run failures amber with a triangle", async () => {
276
276
  const failures: Record<string, AgentError> = {
277
277
  "thread-retryable": {
278
278
  code: "runtime_error",
@@ -307,13 +307,13 @@ describe("AgentKit recoverable failure notices", () => {
307
307
  () => <AgentKitChat composer={false} />,
308
308
  "thread-retryable",
309
309
  );
310
+ // oracle-change: final run failures are amber like retryable ones, so the tone checks merged into one.
310
311
  const row = () =>
311
312
  view.container.querySelector<HTMLElement>(".agentkit-run-failure");
312
- expect(row()?.dataset.tone).toBe("warning");
313
313
  expect(row()?.querySelector(".tabler-icon-alert-triangle")).not.toBeNull();
314
314
 
315
315
  await view.rerender("thread-final");
316
- expect(row()?.dataset.tone).toBe("danger");
317
- expect(row()?.querySelector(".tabler-icon-alert-circle")).not.toBeNull();
316
+ expect(row()?.querySelector(".tabler-icon-alert-triangle")).not.toBeNull();
317
+ expect(row()?.querySelector(".tabler-icon-alert-circle")).toBeNull();
318
318
  });
319
319
  });
@@ -184,6 +184,49 @@ describe("AgentKit optimistic send", () => {
184
184
  expect(messages[0]?.textContent).toContain("Plan the launch");
185
185
  });
186
186
 
187
+ it("anchors the sent message near the top before the thread confirms it", async () => {
188
+ const readiness = Promise.withResolvers<void>();
189
+ const chat = await renderChat({
190
+ history: [{ id: "user-earlier", text: "Earlier question" }],
191
+ readiness: () => readiness.promise,
192
+ });
193
+ const transcript = chat.container.querySelector(
194
+ ".agentkit-transcript",
195
+ ) as HTMLDivElement;
196
+ const spacer = chat.container.querySelector(
197
+ ".agentkit-turn-spacer",
198
+ ) as HTMLDivElement;
199
+ let scrollTop = 0;
200
+ const height = () =>
201
+ 1_260 + (Number.parseFloat(spacer.style.blockSize) || 0);
202
+ Object.defineProperties(transcript, {
203
+ clientHeight: { configurable: true, get: () => 300 },
204
+ scrollHeight: { configurable: true, get: height },
205
+ scrollTop: {
206
+ configurable: true,
207
+ get: () => scrollTop,
208
+ set: (value: number) => {
209
+ scrollTop = Math.min(value, height() - 300);
210
+ },
211
+ },
212
+ });
213
+ // The sent copy starts 1,210px down the transcript content.
214
+ vi.spyOn(HTMLElement.prototype, "getBoundingClientRect").mockImplementation(
215
+ function (this: HTMLElement) {
216
+ const top = this.dataset.pending === "true" ? 1_210 - scrollTop : 0;
217
+ return { top, bottom: top, left: 0, right: 0 } as DOMRect;
218
+ },
219
+ );
220
+ await act(async () => chat.composerRef.current!.setText("And then?"));
221
+
222
+ await chat.send();
223
+
224
+ expect(chat.userMessages().at(-1)?.dataset.pending).toBe("true");
225
+ expect(scrollTop).toBe(1_178);
226
+ readiness.resolve();
227
+ await chat.settle();
228
+ });
229
+
187
230
  it("puts the draft back and shows the error when readiness fails", async () => {
188
231
  const readiness = Promise.withResolvers<void>();
189
232
  const chat = await renderChat({ readiness: () => readiness.promise });
@@ -0,0 +1,276 @@
1
+ // @vitest-environment happy-dom
2
+
3
+ import { act } from "react";
4
+ import { createRoot, type Root } from "react-dom/client";
5
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
6
+
7
+ import { QuestionCard, type AgentKitQuestion } from "./question-card.js";
8
+
9
+ const questions: AgentKitQuestion[] = [
10
+ {
11
+ id: "cuisine",
12
+ question: "Which cuisine?",
13
+ options: [
14
+ { value: "italian", label: "Italian" },
15
+ { value: "thai", label: "Thai", recommended: true },
16
+ { value: "mexican", label: "Mexican" },
17
+ ],
18
+ },
19
+ {
20
+ id: "courses",
21
+ question: "Which courses?",
22
+ multiSelect: true,
23
+ options: [
24
+ { value: "starter", label: "Starter" },
25
+ { value: "main", label: "Main" },
26
+ { value: "dessert", label: "Dessert" },
27
+ ],
28
+ },
29
+ ];
30
+
31
+ describe("QuestionCard", () => {
32
+ let container: HTMLDivElement;
33
+ let root: Root;
34
+
35
+ beforeEach(() => {
36
+ vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
37
+ container = document.createElement("div");
38
+ document.body.appendChild(container);
39
+ root = createRoot(container);
40
+ });
41
+
42
+ afterEach(() => {
43
+ act(() => root.unmount());
44
+ container.remove();
45
+ vi.unstubAllGlobals();
46
+ });
47
+
48
+ const options = () =>
49
+ Array.from(
50
+ container.querySelectorAll<HTMLButtonElement>(
51
+ ".agentkit-question-option",
52
+ ),
53
+ );
54
+ const button = (name: string) => {
55
+ const match = Array.from(container.querySelectorAll("button")).find(
56
+ (item) => item.textContent?.trim() === name,
57
+ );
58
+ if (!match) throw new Error(`No ${name} button`);
59
+ return match;
60
+ };
61
+ const press = (target: Element | null, key: string) =>
62
+ act(() => {
63
+ target?.dispatchEvent(
64
+ new KeyboardEvent("keydown", { key, bubbles: true }),
65
+ );
66
+ });
67
+
68
+ it("picks with number keys and arrows, and focuses the next question", async () => {
69
+ const onSubmit = vi.fn();
70
+ await act(async () =>
71
+ root.render(
72
+ <QuestionCard
73
+ questions={questions}
74
+ onSubmit={onSubmit}
75
+ onDismiss={vi.fn()}
76
+ />,
77
+ ),
78
+ );
79
+
80
+ // The recommended option comes first and holds the group's one tab stop.
81
+ expect(options().map((option) => option.textContent)).toEqual([
82
+ "1ThaiRecommended",
83
+ "2Italian",
84
+ "3Mexican",
85
+ ]);
86
+ expect(options().map((option) => option.tabIndex)).toEqual([0, -1, -1]);
87
+ expect(
88
+ container
89
+ .querySelector('[role="radiogroup"]')
90
+ ?.getAttribute("aria-labelledby"),
91
+ ).toBe(container.querySelector(".agentkit-question-text")?.id);
92
+
93
+ const [first] = options();
94
+ act(() => first?.focus());
95
+ await press(first, "3");
96
+ expect(options()[2]?.getAttribute("aria-checked")).toBe("true");
97
+ expect(document.activeElement).toBe(options()[2]);
98
+ await press(document.activeElement, "ArrowDown");
99
+ expect(options()[0]?.getAttribute("aria-checked")).toBe("true");
100
+ expect(document.activeElement).toBe(options()[0]);
101
+
102
+ await act(async () => button("Next").click());
103
+ // Focus moves to the new question instead of dropping to the page.
104
+ expect(
105
+ container.querySelector(".agentkit-question-text")?.textContent,
106
+ ).toBe("Which courses?");
107
+ expect(document.activeElement).toBe(options()[0]);
108
+ expect(container.querySelector('[role="group"]')).not.toBeNull();
109
+
110
+ await press(document.activeElement, "1");
111
+ await press(document.activeElement, "3");
112
+ expect(
113
+ options().map((option) => option.getAttribute("aria-checked")),
114
+ ).toEqual(["true", "false", "true"]);
115
+ await act(async () => button("Send").click());
116
+
117
+ expect(onSubmit).toHaveBeenCalledWith({
118
+ cuisine: { values: ["thai"] },
119
+ courses: { values: ["starter", "dessert"] },
120
+ });
121
+ });
122
+
123
+ it("lets a written answer replace a single choice", async () => {
124
+ const onSubmit = vi.fn();
125
+ await act(async () =>
126
+ root.render(
127
+ <QuestionCard
128
+ questions={[questions[0] as AgentKitQuestion]}
129
+ onSubmit={onSubmit}
130
+ onDismiss={vi.fn()}
131
+ />,
132
+ ),
133
+ );
134
+ await act(async () => options()[1]?.click());
135
+ const input = container.querySelector<HTMLInputElement>(
136
+ ".agentkit-question-other input",
137
+ );
138
+ if (!input) throw new Error("No written answer");
139
+ await act(async () => {
140
+ Object.getOwnPropertyDescriptor(
141
+ HTMLInputElement.prototype,
142
+ "value",
143
+ )?.set?.call(input, "Korean");
144
+ input.dispatchEvent(new Event("input", { bubbles: true }));
145
+ });
146
+ expect(options()[1]?.getAttribute("aria-checked")).toBe("false");
147
+ // Number keys belong to the text while it has focus.
148
+ await press(input, "2");
149
+ expect(options()[1]?.getAttribute("aria-checked")).toBe("false");
150
+ await press(input, "Enter");
151
+
152
+ expect(onSubmit).toHaveBeenCalledWith({
153
+ cuisine: { values: [], other: "Korean" },
154
+ });
155
+ });
156
+
157
+ it("keeps a required question from being skipped, and dismisses on close", async () => {
158
+ const onDismiss = vi.fn();
159
+ await act(async () =>
160
+ root.render(
161
+ <QuestionCard
162
+ questions={[
163
+ { ...(questions[0] as AgentKitQuestion), required: true },
164
+ ]}
165
+ onSubmit={vi.fn()}
166
+ onDismiss={onDismiss}
167
+ />,
168
+ ),
169
+ );
170
+
171
+ expect(button("Skip").disabled).toBe(true);
172
+ await act(async () =>
173
+ container
174
+ .querySelector<HTMLButtonElement>(
175
+ 'button[aria-label="Dismiss questions"]',
176
+ )
177
+ ?.click(),
178
+ );
179
+ expect(onDismiss).toHaveBeenCalledTimes(1);
180
+ });
181
+
182
+ it("answers a color, a slider and files", async () => {
183
+ const onSubmit = vi.fn();
184
+ await act(async () =>
185
+ root.render(
186
+ <QuestionCard
187
+ questions={[
188
+ {
189
+ id: "accent",
190
+ question: "Which accent?",
191
+ allowOther: false,
192
+ options: [
193
+ { value: "teal", label: "Teal", color: "teal" },
194
+ { value: "plum", label: "Plum", color: "#8e4585" },
195
+ ],
196
+ },
197
+ {
198
+ id: "volume",
199
+ question: "How loud?",
200
+ options: [],
201
+ allowOther: false,
202
+ range: { min: 0, max: 10, step: 1, initial: 5 },
203
+ },
204
+ {
205
+ id: "brief",
206
+ question: "Any brief to read?",
207
+ options: [],
208
+ allowOther: false,
209
+ files: true,
210
+ },
211
+ ]}
212
+ onSubmit={onSubmit}
213
+ onDismiss={vi.fn()}
214
+ />,
215
+ ),
216
+ );
217
+
218
+ expect(
219
+ container.querySelectorAll(".agentkit-question-swatch"),
220
+ ).toHaveLength(2);
221
+ expect(container.querySelector(".agentkit-question-other")).toBeNull();
222
+ await act(async () => options()[1]?.click());
223
+ await act(async () => button("Next").click());
224
+
225
+ // The slider's shown value is already the answer.
226
+ const slider = container.querySelector<HTMLInputElement>(
227
+ '.agentkit-question-range input[type="range"]',
228
+ );
229
+ expect(slider?.value).toBe("5");
230
+ expect(slider?.getAttribute("aria-labelledby")).toBe(
231
+ container.querySelector(".agentkit-question-text")?.id,
232
+ );
233
+ expect(button("Next").disabled).toBe(false);
234
+ await act(async () => {
235
+ if (!slider) return;
236
+ Object.getOwnPropertyDescriptor(
237
+ HTMLInputElement.prototype,
238
+ "value",
239
+ )?.set?.call(slider, "8");
240
+ slider.dispatchEvent(new Event("input", { bubbles: true }));
241
+ });
242
+ expect(
243
+ container.querySelector(".agentkit-question-range-value")?.textContent,
244
+ ).toBe("8");
245
+ await act(async () => button("Next").click());
246
+
247
+ const brief = new File(["notes"], "brief.md", { type: "text/markdown" });
248
+ const picker = container.querySelector<HTMLInputElement>(
249
+ '.agentkit-question-files input[type="file"]',
250
+ );
251
+ expect(button("Send").disabled).toBe(true);
252
+ await act(async () => {
253
+ if (!picker) return;
254
+ Object.defineProperty(picker, "files", {
255
+ configurable: true,
256
+ value: [brief],
257
+ });
258
+ picker.dispatchEvent(new Event("change", { bubbles: true }));
259
+ });
260
+ expect(
261
+ container.querySelector(".agentkit-question-file-name")?.textContent,
262
+ ).toBe("brief.md");
263
+ expect(
264
+ container
265
+ .querySelector(".agentkit-question-file-remove")
266
+ ?.getAttribute("aria-label"),
267
+ ).toBe("Remove brief.md");
268
+ await act(async () => button("Send").click());
269
+
270
+ expect(onSubmit).toHaveBeenCalledWith({
271
+ accent: { values: ["plum"] },
272
+ volume: { values: ["8"] },
273
+ brief: { values: [], files: [brief] },
274
+ });
275
+ });
276
+ });