@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
@@ -12,10 +12,36 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
12
12
  import {
13
13
  askUserQuestion,
14
14
  GUIDED_QUESTIONS_SUBMITTED_EVENT,
15
+ GuidedQuestionCard,
15
16
  GuidedQuestionFlow,
16
17
  useGuidedQuestionFlow,
17
18
  } from "./guided-questions.js";
18
19
 
20
+ // Real dictation needs the app's tooltip provider and a microphone.
21
+ vi.mock("../../../composer/useVoiceDictation.js", () => ({
22
+ useVoiceDictation: (options: { onTranscript: (text: string) => void }) => ({
23
+ options,
24
+ }),
25
+ }));
26
+ vi.mock("../../../composer/VoiceButton.js", () => ({
27
+ VoiceButton: ({
28
+ voice,
29
+ disabled,
30
+ }: {
31
+ voice: { options: { onTranscript: (text: string) => void } };
32
+ disabled?: boolean;
33
+ }) => (
34
+ <button
35
+ type="button"
36
+ data-dictation="true"
37
+ disabled={disabled}
38
+ onClick={() => voice.options.onTranscript("Make it vegetarian")}
39
+ >
40
+ Dictate
41
+ </button>
42
+ ),
43
+ }));
44
+
19
45
  vi.mock("@agent-native/core/client/agent-chat", async (importOriginal) => ({
20
46
  ...(await importOriginal<
21
47
  typeof import("@agent-native/core/client/agent-chat")
@@ -1287,6 +1313,361 @@ describe("useGuidedQuestionFlow scoped reads", () => {
1287
1313
  expect(onSkip).not.toHaveBeenCalled();
1288
1314
  });
1289
1315
 
1316
+ const buttonNamed = (name: string) => {
1317
+ const match = Array.from(
1318
+ container.querySelectorAll<HTMLButtonElement>("button"),
1319
+ ).find((button) => button.textContent?.trim() === name);
1320
+ if (!match) throw new Error(`No ${name} button`);
1321
+ return match;
1322
+ };
1323
+ const optionLabels = () =>
1324
+ Array.from(
1325
+ container.querySelectorAll(".agentkit-question-option-label"),
1326
+ (label) => label.textContent,
1327
+ );
1328
+
1329
+ it("renders choice questions as the Questions card, without the old chrome", async () => {
1330
+ await act(async () => {
1331
+ root.render(
1332
+ <GuidedQuestionCard
1333
+ questions={[
1334
+ {
1335
+ id: "audience",
1336
+ type: "text-options",
1337
+ header: "Audience",
1338
+ question: "Who is this for?",
1339
+ options: [
1340
+ { label: "Board", value: "board" },
1341
+ { label: "Team", value: "team", recommended: true },
1342
+ { label: "Customers", value: "customers" },
1343
+ ],
1344
+ },
1345
+ ]}
1346
+ onSubmit={vi.fn()}
1347
+ onSkip={vi.fn()}
1348
+ />,
1349
+ );
1350
+ });
1351
+
1352
+ expect(container.querySelector(".guided-question-flow")).toBe(null);
1353
+ expect(
1354
+ container.querySelector(".agentkit-question-title")?.textContent,
1355
+ ).toBe("Question");
1356
+ // One question has no step count, and no option is picked for the user.
1357
+ expect(container.querySelector(".agentkit-question-progress")).toBe(null);
1358
+ expect(container.querySelector(".agentkit-question-description")).toBe(
1359
+ null,
1360
+ );
1361
+ expect(container.textContent).not.toContain("Audience");
1362
+ expect(optionLabels()).toEqual(["Team", "Board", "Customers"]);
1363
+ expect(
1364
+ container.querySelectorAll('[role="radio"][aria-checked="true"]'),
1365
+ ).toHaveLength(0);
1366
+ expect(
1367
+ container.querySelector<HTMLInputElement>(
1368
+ ".agentkit-question-other input",
1369
+ )?.placeholder,
1370
+ ).toBe("Or write your own response");
1371
+ expect(buttonNamed("Send").disabled).toBe(true);
1372
+ });
1373
+
1374
+ it("renders a caller-supplied description", async () => {
1375
+ await act(async () => {
1376
+ root.render(
1377
+ <GuidedQuestionCard
1378
+ questions={[{ id: "notes", type: "freeform", question: "Notes?" }]}
1379
+ description="Answer what matters."
1380
+ onSubmit={vi.fn()}
1381
+ onSkip={vi.fn()}
1382
+ />,
1383
+ );
1384
+ });
1385
+
1386
+ expect(
1387
+ container.querySelector(".agentkit-question-description")?.textContent,
1388
+ ).toBe("Answer what matters.");
1389
+ });
1390
+
1391
+ it("adds Explore and Decide rows only when a question opts in", async () => {
1392
+ await act(async () => {
1393
+ root.render(
1394
+ <GuidedQuestionCard
1395
+ questions={[
1396
+ {
1397
+ id: "style",
1398
+ type: "text-options",
1399
+ question: "Which style?",
1400
+ allowOther: false,
1401
+ includeExplore: true,
1402
+ includeDecide: true,
1403
+ options: [{ label: "Bold", value: "bold" }],
1404
+ },
1405
+ {
1406
+ id: "tone",
1407
+ type: "text-options",
1408
+ question: "Which tone?",
1409
+ allowOther: false,
1410
+ includeDecide: true,
1411
+ options: [{ label: "Calm", value: "calm" }],
1412
+ },
1413
+ ]}
1414
+ onSubmit={vi.fn()}
1415
+ onSkip={vi.fn()}
1416
+ />,
1417
+ );
1418
+ });
1419
+
1420
+ expect(optionLabels()).toEqual([
1421
+ "Bold",
1422
+ "Explore a few options",
1423
+ "Let the agent decide",
1424
+ ]);
1425
+ await act(async () => buttonNamed("Skip").click());
1426
+ expect(optionLabels()).toEqual(["Calm", "Let the agent decide"]);
1427
+ });
1428
+
1429
+ it("steps through several questions and sends every answer together", async () => {
1430
+ const onSubmit = vi.fn();
1431
+ await act(async () => {
1432
+ root.render(
1433
+ <GuidedQuestionCard
1434
+ questions={[
1435
+ {
1436
+ id: "tone",
1437
+ type: "text-options",
1438
+ question: "Which tone?",
1439
+ options: [{ label: "Calm", value: "calm" }],
1440
+ },
1441
+ {
1442
+ id: "length",
1443
+ type: "text-options",
1444
+ question: "How long?",
1445
+ options: [{ label: "Short", value: "short" }],
1446
+ },
1447
+ { id: "notes", type: "freeform", question: "Anything else?" },
1448
+ ]}
1449
+ onSubmit={onSubmit}
1450
+ onSkip={vi.fn()}
1451
+ />,
1452
+ );
1453
+ });
1454
+ const progress = () =>
1455
+ container.querySelector(".agentkit-question-progress")?.textContent;
1456
+ const optionNamed = (label: string) => {
1457
+ const match = Array.from(
1458
+ container.querySelectorAll<HTMLButtonElement>(
1459
+ ".agentkit-question-option",
1460
+ ),
1461
+ ).find((option) => option.textContent?.includes(label));
1462
+ if (!match) throw new Error(`No ${label} option`);
1463
+ return match;
1464
+ };
1465
+
1466
+ expect(progress()).toBe("1/3");
1467
+ expect(
1468
+ container.querySelector(".agentkit-question-title")?.textContent,
1469
+ ).toBe("Question 1 of 3");
1470
+ expect(buttonNamed("Next").disabled).toBe(true);
1471
+ await act(async () => optionNamed("Calm").click());
1472
+ await act(async () => buttonNamed("Next").click());
1473
+ expect(progress()).toBe("2/3");
1474
+ expect(
1475
+ container.querySelector(".agentkit-question-text")?.textContent,
1476
+ ).toBe("How long?");
1477
+
1478
+ // Skipping leaves that question unanswered, not answered with a guess.
1479
+ await act(async () => buttonNamed("Skip").click());
1480
+ expect(progress()).toBe("3/3");
1481
+ const notes = container.querySelector<HTMLInputElement>(
1482
+ ".agentkit-question-other input",
1483
+ );
1484
+ if (!notes) throw new Error("No written answer");
1485
+ expect(notes.placeholder).toBe("Write your answer");
1486
+ await act(async () => {
1487
+ const setValue = Object.getOwnPropertyDescriptor(
1488
+ HTMLInputElement.prototype,
1489
+ "value",
1490
+ )?.set;
1491
+ setValue?.call(notes, "Keep it warm");
1492
+ notes.dispatchEvent(new Event("input", { bubbles: true }));
1493
+ });
1494
+ expect(onSubmit).not.toHaveBeenCalled();
1495
+ await act(async () => buttonNamed("Send").click());
1496
+
1497
+ expect(onSubmit).toHaveBeenCalledTimes(1);
1498
+ expect(onSubmit).toHaveBeenCalledWith({
1499
+ tone: "calm",
1500
+ notes: "Keep it warm",
1501
+ });
1502
+ });
1503
+
1504
+ it("dismisses instead of sending when every question is skipped", async () => {
1505
+ const onSubmit = vi.fn();
1506
+ const onSkip = vi.fn();
1507
+ await act(async () => {
1508
+ root.render(
1509
+ <GuidedQuestionCard
1510
+ questions={[
1511
+ {
1512
+ id: "tone",
1513
+ type: "text-options",
1514
+ question: "Which tone?",
1515
+ options: [{ label: "Calm", value: "calm" }],
1516
+ },
1517
+ ]}
1518
+ onSubmit={onSubmit}
1519
+ onSkip={onSkip}
1520
+ />,
1521
+ );
1522
+ });
1523
+
1524
+ await act(async () => buttonNamed("Skip").click());
1525
+ expect(onSkip).toHaveBeenCalledTimes(1);
1526
+ expect(onSubmit).not.toHaveBeenCalled();
1527
+ });
1528
+
1529
+ it("sends a slider's shown value as a number", async () => {
1530
+ const onSubmit = vi.fn();
1531
+ await act(async () => {
1532
+ root.render(
1533
+ <GuidedQuestionCard
1534
+ questions={[
1535
+ {
1536
+ id: "volume",
1537
+ type: "slider",
1538
+ question: "How loud?",
1539
+ min: 0,
1540
+ max: 10,
1541
+ step: 2,
1542
+ },
1543
+ ]}
1544
+ onSubmit={onSubmit}
1545
+ onSkip={vi.fn()}
1546
+ />,
1547
+ );
1548
+ });
1549
+
1550
+ // The midpoint on the slider's own steps, sent without touching it.
1551
+ expect(
1552
+ container.querySelector<HTMLInputElement>('input[type="range"]')?.value,
1553
+ ).toBe("6");
1554
+ await act(async () => buttonNamed("Send").click());
1555
+ expect(onSubmit).toHaveBeenCalledWith({ volume: 6 });
1556
+ });
1557
+
1558
+ it("dictates into the written response beside Skip", async () => {
1559
+ const onSubmit = vi.fn();
1560
+ await act(async () => {
1561
+ root.render(
1562
+ <GuidedQuestionCard
1563
+ questions={[
1564
+ {
1565
+ id: "menu",
1566
+ type: "text-options",
1567
+ question: "Which menu?",
1568
+ options: [{ label: "Three courses", value: "three" }],
1569
+ },
1570
+ ]}
1571
+ onSubmit={onSubmit}
1572
+ onSkip={vi.fn()}
1573
+ />,
1574
+ );
1575
+ });
1576
+
1577
+ const dictate = container.querySelector<HTMLButtonElement>(
1578
+ ".agentkit-question-actions [data-dictation]",
1579
+ );
1580
+ expect(dictate?.nextElementSibling?.textContent).toBe("Skip");
1581
+ await act(async () => dictate?.click());
1582
+ expect(
1583
+ container.querySelector<HTMLInputElement>(
1584
+ ".agentkit-question-other input",
1585
+ )?.value,
1586
+ ).toBe("Make it vegetarian");
1587
+ await act(async () => buttonNamed("Send").click());
1588
+ expect(onSubmit).toHaveBeenCalledWith({
1589
+ menu: "Other: Make it vegetarian",
1590
+ });
1591
+ });
1592
+
1593
+ it("disables question inputs and continuation controls while provider setup is required", async () => {
1594
+ const onSubmit = vi.fn();
1595
+ const onSkip = vi.fn();
1596
+
1597
+ await act(async () => {
1598
+ root.render(
1599
+ <GuidedQuestionCard
1600
+ questions={[
1601
+ {
1602
+ id: "variant",
1603
+ type: "text-options",
1604
+ question: "Which screen should I keep?",
1605
+ required: true,
1606
+ submitOnSelect: true,
1607
+ options: [{ label: "Soft Cards", value: "soft-cards" }],
1608
+ },
1609
+ ]}
1610
+ onSubmit={onSubmit}
1611
+ onSkip={onSkip}
1612
+ isSubmissionBlocked
1613
+ providerStatus="unavailable"
1614
+ />,
1615
+ );
1616
+ });
1617
+
1618
+ const softCards = container.querySelector<HTMLButtonElement>(
1619
+ ".agentkit-question-option",
1620
+ );
1621
+ expect(softCards?.getAttribute("aria-disabled")).toBe("true");
1622
+ expect(container.textContent).toContain("Couldn't confirm AI is ready.");
1623
+
1624
+ await act(async () => {
1625
+ softCards?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
1626
+ await Promise.resolve();
1627
+ });
1628
+
1629
+ expect(softCards?.getAttribute("aria-checked")).toBe("false");
1630
+ expect(onSubmit).not.toHaveBeenCalled();
1631
+ expect(onSkip).not.toHaveBeenCalled();
1632
+ });
1633
+
1634
+ it("allows question drafts while provider status is unknown but blocks continuation", async () => {
1635
+ const onSubmit = vi.fn();
1636
+ const onSkip = vi.fn();
1637
+
1638
+ await act(async () => {
1639
+ root.render(
1640
+ <GuidedQuestionCard
1641
+ questions={[
1642
+ {
1643
+ id: "variant",
1644
+ type: "text-options",
1645
+ question: "Which screen should I keep?",
1646
+ submitOnSelect: true,
1647
+ options: [{ label: "Soft Cards", value: "soft-cards" }],
1648
+ },
1649
+ ]}
1650
+ onSubmit={onSubmit}
1651
+ onSkip={onSkip}
1652
+ isSubmissionBlocked
1653
+ providerStatus="unknown"
1654
+ />,
1655
+ );
1656
+ });
1657
+
1658
+ const softCards = container.querySelector<HTMLButtonElement>(
1659
+ ".agentkit-question-option",
1660
+ );
1661
+ await act(async () => {
1662
+ softCards?.click();
1663
+ });
1664
+ expect(softCards?.getAttribute("aria-checked")).toBe("true");
1665
+ expect(buttonNamed("Send").disabled).toBe(true);
1666
+ expect(buttonNamed("Skip").disabled).toBe(true);
1667
+ expect(onSubmit).not.toHaveBeenCalled();
1668
+ expect(onSkip).not.toHaveBeenCalled();
1669
+ });
1670
+
1290
1671
  it("submits selected option values as authoritative context", async () => {
1291
1672
  const selectedInstruction =
1292
1673
  'Keep "Command Deck" (variant-command-deck.html, file id file-command). Then call edit-design with fileId file-command.';
@@ -34,6 +34,13 @@ import {
34
34
  useState,
35
35
  } from "react";
36
36
 
37
+ import { useVoiceDictation } from "../../../composer/useVoiceDictation.js";
38
+ import { VoiceButton } from "../../../composer/VoiceButton.js";
39
+ import {
40
+ QuestionCard as AgentKitQuestionCard,
41
+ type AgentKitQuestion,
42
+ type AgentKitQuestionAnswers,
43
+ } from "../../agentkit/react/question-card.js";
37
44
  import { BuilderSetupCard } from "../chat/run-recovery.js";
38
45
 
39
46
  export type GuidedQuestionType =
@@ -454,11 +461,118 @@ export interface GuidedQuestionFlowProps {
454
461
  isSubmissionBlocked?: boolean;
455
462
  providerStatus?: AgentEngineConfiguredState;
456
463
  modelListUnavailable?: boolean;
457
- onRetryProviderStatus?: () => void;
464
+ onRetryProviderStatus?: (() => void) | undefined;
458
465
  showProviderStatusGate?: boolean;
459
466
  className?: string;
460
467
  }
461
468
 
469
+ function toQuestionCardQuestion(
470
+ question: GuidedQuestion,
471
+ defaults: { explore: GuidedQuestionOption; decide: GuidedQuestionOption },
472
+ ): AgentKitQuestion {
473
+ const choices =
474
+ question.type === "text-options"
475
+ ? withDefaultOptions(question, defaults)
476
+ : question.type === "color-options"
477
+ ? recommendedFirst(question.options ?? question.choices ?? [])
478
+ : [];
479
+ const options = choices.map((option) => ({
480
+ value: option.value,
481
+ label: option.label,
482
+ ...(option.recommended ? { recommended: true } : {}),
483
+ ...(question.type === "color-options"
484
+ ? { color: option.color || option.value }
485
+ : {}),
486
+ }));
487
+ const min = question.min ?? 0;
488
+ const max = question.max ?? 100;
489
+ const step = question.step ?? 1;
490
+ return {
491
+ id: question.id,
492
+ question: question.question,
493
+ options,
494
+ ...(question.description ? { description: question.description } : {}),
495
+ ...(question.placeholder ? { placeholder: question.placeholder } : {}),
496
+ ...(question.type === "slider"
497
+ ? {
498
+ range: {
499
+ min,
500
+ max,
501
+ step,
502
+ initial: min + Math.round((max - min) / 2 / step) * step,
503
+ },
504
+ }
505
+ : {}),
506
+ ...(question.type === "file" ? { files: true } : {}),
507
+ multiSelect: question.multiSelect === true,
508
+ allowOther:
509
+ question.type === "freeform" ||
510
+ (question.type === "text-options" && question.allowOther !== false),
511
+ required: question.required === true,
512
+ submitOnSelect: question.submitOnSelect === true,
513
+ };
514
+ }
515
+
516
+ function fromQuestionCardAnswers(
517
+ questions: readonly GuidedQuestion[],
518
+ answers: AgentKitQuestionAnswers,
519
+ ): GuidedQuestionAnswers {
520
+ const result: GuidedQuestionAnswers = {};
521
+ for (const question of questions) {
522
+ const answer = answers[question.id] as
523
+ | AgentKitQuestionAnswers[string]
524
+ | undefined;
525
+ if (!answer) continue;
526
+ const other = answer.other?.trim() ?? "";
527
+ if (question.type === "freeform") {
528
+ if (other) result[question.id] = other;
529
+ continue;
530
+ }
531
+ if (question.type === "slider") {
532
+ if (answer.values.length > 0) {
533
+ result[question.id] = Number(answer.values[0]);
534
+ }
535
+ continue;
536
+ }
537
+ if (question.type === "file") {
538
+ if (answer.files?.length) result[question.id] = answer.files;
539
+ continue;
540
+ }
541
+ if (question.multiSelect) {
542
+ result[question.id] = [
543
+ ...answer.values,
544
+ ...(other ? [makeOtherGuidedAnswer(other)] : []),
545
+ ];
546
+ continue;
547
+ }
548
+ if (answer.values.length > 0) result[question.id] = answer.values[0];
549
+ else if (other) result[question.id] = makeOtherGuidedAnswer(other);
550
+ }
551
+ return result;
552
+ }
553
+
554
+ function GuidedQuestionDictation({
555
+ onTranscript,
556
+ disabled,
557
+ }: {
558
+ onTranscript: (text: string) => void;
559
+ disabled: boolean;
560
+ }) {
561
+ const voice = useVoiceDictation({ onTranscript });
562
+ const isMac =
563
+ typeof navigator !== "undefined" &&
564
+ /Mac|iPhone|iPad/.test(navigator.userAgent);
565
+ return (
566
+ <VoiceButton
567
+ voice={voice}
568
+ isMac={isMac}
569
+ disabled={disabled}
570
+ voiceChat={false}
571
+ showShortcut={false}
572
+ />
573
+ );
574
+ }
575
+
462
576
  export function GuidedQuestionProviderGate({
463
577
  providerStatus,
464
578
  modelListUnavailable = false,
@@ -505,6 +619,99 @@ export function GuidedQuestionProviderGate({
505
619
  );
506
620
  }
507
621
 
622
+ /** Docked above a chat composer; full-panel hosts use `GuidedQuestionFlow`. */
623
+ export function GuidedQuestionCard({
624
+ questions,
625
+ onSubmit,
626
+ onSkip,
627
+ title,
628
+ description,
629
+ skipLabel,
630
+ submitLabel,
631
+ isSubmitting = false,
632
+ isSubmissionBlocked = false,
633
+ providerStatus = "configured",
634
+ modelListUnavailable = false,
635
+ onRetryProviderStatus,
636
+ showProviderStatusGate = true,
637
+ className,
638
+ }: GuidedQuestionFlowProps) {
639
+ const t = useT();
640
+ const questionsFingerprint = useMemo(
641
+ () => guidedQuestionsFingerprint(questions),
642
+ [questions],
643
+ );
644
+ const inputsDisabled =
645
+ isSubmitting || (isSubmissionBlocked && providerStatus !== "unknown");
646
+ const exploreLabel = t("agentChat.guided.exploreLabel");
647
+ const exploreDescription = t("agentChat.guided.exploreDescription");
648
+ const decideLabel = t("agentChat.guided.decideLabel");
649
+ const decideDescription = t("agentChat.guided.decideDescription");
650
+ const cardQuestions = useMemo(
651
+ () =>
652
+ questions.map((question) =>
653
+ toQuestionCardQuestion(question, {
654
+ explore: {
655
+ label: exploreLabel,
656
+ value: EXPLORE_OPTION_VALUE,
657
+ description: exploreDescription,
658
+ },
659
+ decide: {
660
+ label: decideLabel,
661
+ value: DECIDE_OPTION_VALUE,
662
+ description: decideDescription,
663
+ },
664
+ }),
665
+ ),
666
+ [
667
+ questions,
668
+ exploreLabel,
669
+ exploreDescription,
670
+ decideLabel,
671
+ decideDescription,
672
+ ],
673
+ );
674
+ const providerGate =
675
+ isSubmissionBlocked && showProviderStatusGate ? (
676
+ <div className="guided-question-provider-gate">
677
+ <GuidedQuestionProviderGate
678
+ providerStatus={providerStatus}
679
+ modelListUnavailable={modelListUnavailable}
680
+ {...(onRetryProviderStatus ? { onRetry: onRetryProviderStatus } : {})}
681
+ />
682
+ </div>
683
+ ) : null;
684
+
685
+ return (
686
+ <AgentKitQuestionCard
687
+ // A new set of questions starts over at the first one.
688
+ key={questionsFingerprint}
689
+ questions={cardQuestions}
690
+ {...(title ? { title } : {})}
691
+ {...(description ? { description } : {})}
692
+ {...(skipLabel ? { skipLabel } : {})}
693
+ {...(submitLabel ? { submitLabel } : {})}
694
+ {...(className ? { className } : {})}
695
+ busy={isSubmitting}
696
+ disabled={inputsDisabled}
697
+ submitBlocked={isSubmissionBlocked}
698
+ footer={providerGate}
699
+ renderResponseControl={({ append, disabled }) => (
700
+ <GuidedQuestionDictation onTranscript={append} disabled={disabled} />
701
+ )}
702
+ onDismiss={onSkip}
703
+ onSubmit={(cardAnswers) => {
704
+ if (isSubmissionBlocked || isSubmitting) return;
705
+ onSubmit(
706
+ normalizeGuidedAnswers(
707
+ fromQuestionCardAnswers(questions, cardAnswers),
708
+ ),
709
+ );
710
+ }}
711
+ />
712
+ );
713
+ }
714
+
508
715
  export function GuidedQuestionFlow({
509
716
  questions,
510
717
  onSubmit,
@@ -661,7 +868,7 @@ function QuestionCard({
661
868
  const t = useT();
662
869
  const questionId = useId();
663
870
  return (
664
- <section className="guided-question-card border-t border-border/60 py-3 first:border-t-0 first:pt-0 last:pb-0">
871
+ <section className="guided-question-card border-t border-border py-3 first:border-t-0 first:pt-0 last:pb-0">
665
872
  <div className="mb-2 flex gap-2.5">
666
873
  <div className="guided-question-index mt-0.5 min-w-4 text-xs font-medium tabular-nums text-muted-foreground">
667
874
  {index + 1}
@@ -899,7 +1106,7 @@ function OptionButton({
899
1106
  </span>
900
1107
  )}
901
1108
  {option.preview && (
902
- <span className="mt-1.5 block max-h-40 overflow-auto whitespace-pre-wrap rounded border border-border/60 bg-background/60 px-2 py-1.5 font-mono text-[11px] leading-4 text-muted-foreground">
1109
+ <span className="mt-1.5 block max-h-40 overflow-auto whitespace-pre-wrap rounded border border-border bg-background/60 px-2 py-1.5 font-mono text-[11px] leading-4 text-muted-foreground">
903
1110
  {option.preview}
904
1111
  </span>
905
1112
  )}
@@ -1507,3 +1714,29 @@ export function useGuidedQuestionFlow({
1507
1714
  refetchPendingQuestionStatus,
1508
1715
  };
1509
1716
  }
1717
+
1718
+ /**
1719
+ * Nothing else wakes the question reader when `ask-question` finishes: without
1720
+ * this the question waits for window focus or a reload.
1721
+ */
1722
+ export function useRefetchGuidedQuestionsWhenAsked({
1723
+ tools,
1724
+ refetch,
1725
+ }: {
1726
+ /** The thread's tool calls, read by the host from its own AgentKit context. */
1727
+ tools: Readonly<Record<string, { name: string; status: string }>>;
1728
+ refetch: () => unknown;
1729
+ }) {
1730
+ const askedIds = Object.entries(tools)
1731
+ .filter(
1732
+ ([, tool]) => tool.name === "ask-question" && tool.status === "completed",
1733
+ )
1734
+ .map(([id]) => id)
1735
+ .sort()
1736
+ .join("\n");
1737
+ const refetchRef = useRef(refetch);
1738
+ refetchRef.current = refetch;
1739
+ useEffect(() => {
1740
+ if (askedIds) void refetchRef.current();
1741
+ }, [askedIds]);
1742
+ }
@@ -421,7 +421,7 @@ function RevertConfirmPopover({
421
421
  side="top"
422
422
  align="start"
423
423
  sideOffset={6}
424
- className="w-56 rounded-lg p-3"
424
+ className="w-56 rounded-[var(--agent-kit-radius-sm,0.5rem)] p-3"
425
425
  >
426
426
  {phase === "confirming" ? (
427
427
  <div className="grid gap-2">
@@ -1,8 +1,10 @@
1
1
  export { CoreComposerRuntimeProvider } from "../composer/runtime-adapters.js";
2
2
  export {
3
+ GuidedQuestionCard,
3
4
  GuidedQuestionFlow,
4
5
  GuidedQuestionProviderGate,
5
6
  useGuidedQuestionFlow,
7
+ useRefetchGuidedQuestionsWhenAsked,
6
8
  } from "./questions.js";
7
9
  export {
8
10
  askUserQuestion,