@dxos/plugin-assistant 0.8.4-staging.60fe92afc8 → 0.9.1-main.c7dcc2e112

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 (254) hide show
  1. package/dist/lib/neutral/{AgentArticle-K7XM46OQ.mjs → AgentArticle-2BEPWUMN.mjs} +9 -7
  2. package/dist/lib/neutral/AgentArticle-2BEPWUMN.mjs.map +7 -0
  3. package/dist/lib/neutral/AssistantPlugin.mjs +1 -1
  4. package/dist/lib/neutral/{AssistantSettings-GG52BLKS.mjs → AssistantSettings-7ALY4BMS.mjs} +3 -3
  5. package/dist/lib/neutral/AssistantSettings-7ALY4BMS.mjs.map +7 -0
  6. package/dist/lib/neutral/{ChatArticle-VNVZCDUR.mjs → ChatArticle-KT46SUFU.mjs} +2 -2
  7. package/dist/lib/neutral/{ChatCompanion-LBUHYWQG.mjs → ChatCompanion-YHC43RYQ.mjs} +4 -4
  8. package/dist/lib/neutral/ChatCompanion-YHC43RYQ.mjs.map +7 -0
  9. package/dist/lib/neutral/{ChatDialog-DCA6FLOV.mjs → ChatDialog-YZDZLIQA.mjs} +5 -4
  10. package/dist/lib/neutral/ChatDialog-YZDZLIQA.mjs.map +7 -0
  11. package/dist/lib/neutral/{PlanArticle-TS5ULWYS.mjs → PlanArticle-VPK2IYWU.mjs} +8 -2
  12. package/dist/lib/neutral/PlanArticle-VPK2IYWU.mjs.map +7 -0
  13. package/dist/lib/neutral/{RoutineArticle-5NYXHRG6.mjs → RoutineArticle-FK5BXQN5.mjs} +3 -3
  14. package/dist/lib/neutral/RoutineArticle-FK5BXQN5.mjs.map +7 -0
  15. package/dist/lib/neutral/SpaceHomePrompt-HTWQKLGI.mjs +113 -0
  16. package/dist/lib/neutral/SpaceHomePrompt-HTWQKLGI.mjs.map +7 -0
  17. package/dist/lib/neutral/SpaceHomeSuggestions-6G4E7GNJ.mjs +50 -0
  18. package/dist/lib/neutral/SpaceHomeSuggestions-6G4E7GNJ.mjs.map +7 -0
  19. package/dist/lib/neutral/TracePanel-T552TAOH.mjs +12 -0
  20. package/dist/lib/neutral/TracePanel-T552TAOH.mjs.map +7 -0
  21. package/dist/lib/neutral/{TriggerStatus-X7Y5JFZJ.mjs → TriggerStatus-RBOHHDOK.mjs} +3 -3
  22. package/dist/lib/neutral/TriggerStatus-RBOHHDOK.mjs.map +7 -0
  23. package/dist/lib/neutral/{agent-service-WCAP5MLI.mjs → agent-service-WV5CSHAG.mjs} +4 -2
  24. package/dist/lib/neutral/{agent-service-WCAP5MLI.mjs.map → agent-service-WV5CSHAG.mjs.map} +3 -3
  25. package/dist/lib/neutral/{app-graph-builder-WUFHQH3Y.mjs → app-graph-builder-PTSRZXRN.mjs} +13 -13
  26. package/dist/lib/neutral/app-graph-builder-PTSRZXRN.mjs.map +7 -0
  27. package/dist/lib/neutral/{blueprint-definition-MH2QLYQH.mjs → blueprint-definition-2XPYI35X.mjs} +4 -3
  28. package/dist/lib/neutral/blueprint-definition-2XPYI35X.mjs.map +7 -0
  29. package/dist/lib/neutral/capabilities/index.mjs +8 -8
  30. package/dist/lib/neutral/capabilities/index.mjs.map +2 -2
  31. package/dist/lib/neutral/{chunk-HLANPOBA.mjs → chunk-35EL65O4.mjs} +3 -3
  32. package/dist/lib/neutral/chunk-35EL65O4.mjs.map +7 -0
  33. package/dist/lib/neutral/chunk-54W7N6M6.mjs +445 -0
  34. package/dist/lib/neutral/chunk-54W7N6M6.mjs.map +7 -0
  35. package/dist/lib/neutral/{chunk-YXRGZYYH.mjs → chunk-5KB2WRI2.mjs} +6 -6
  36. package/dist/lib/neutral/chunk-5KB2WRI2.mjs.map +7 -0
  37. package/dist/lib/neutral/{TracePanel-KTZJ6JNR.mjs → chunk-5LKNH7FD.mjs} +5 -20
  38. package/dist/lib/neutral/chunk-5LKNH7FD.mjs.map +7 -0
  39. package/dist/lib/neutral/{chunk-SMFJD7BP.mjs → chunk-7FQT4XMI.mjs} +2 -2
  40. package/dist/lib/neutral/{chunk-RKVVK3R3.mjs → chunk-H77JTXAN.mjs} +17 -9
  41. package/dist/lib/neutral/chunk-H77JTXAN.mjs.map +7 -0
  42. package/dist/lib/neutral/{chunk-QAZMOFPI.mjs → chunk-IQZJ5TTM.mjs} +4 -4
  43. package/dist/lib/neutral/chunk-IQZJ5TTM.mjs.map +7 -0
  44. package/dist/lib/neutral/chunk-ZNDQVYUN.mjs +53 -0
  45. package/dist/lib/neutral/chunk-ZNDQVYUN.mjs.map +7 -0
  46. package/dist/lib/neutral/components/index.mjs +296 -109
  47. package/dist/lib/neutral/components/index.mjs.map +3 -3
  48. package/dist/lib/neutral/containers/index.mjs +12 -8
  49. package/dist/lib/neutral/containers/index.mjs.map +3 -3
  50. package/dist/lib/neutral/{create-chat-SGGQ6HVN.mjs → create-chat-Z3FNA6OJ.mjs} +2 -2
  51. package/dist/lib/neutral/{create-chat-SGGQ6HVN.mjs.map → create-chat-Z3FNA6OJ.mjs.map} +2 -2
  52. package/dist/lib/neutral/{create-object-U2SOFZLR.mjs → create-object-BJUDDKQQ.mjs} +2 -2
  53. package/dist/lib/neutral/execution-graph/index.mjs +156 -0
  54. package/dist/lib/neutral/execution-graph/index.mjs.map +4 -4
  55. package/dist/lib/neutral/{fork-chat-34KEF4ZJ.mjs → fork-chat-UYXYT6BT.mjs} +4 -4
  56. package/dist/lib/neutral/fork-chat-UYXYT6BT.mjs.map +7 -0
  57. package/dist/lib/neutral/hooks/index.mjs +233 -438
  58. package/dist/lib/neutral/hooks/index.mjs.map +4 -4
  59. package/dist/lib/neutral/index.mjs +3 -3
  60. package/dist/lib/neutral/markdown-extension-IJ5RQMQ4.mjs +126 -0
  61. package/dist/lib/neutral/markdown-extension-IJ5RQMQ4.mjs.map +7 -0
  62. package/dist/lib/neutral/meta.json +1 -1
  63. package/dist/lib/neutral/meta.mjs +1 -1
  64. package/dist/lib/neutral/operations/index.mjs +1 -1
  65. package/dist/lib/neutral/plugin.mjs +2 -2
  66. package/dist/lib/neutral/{react-surface-XRTBW5OJ.mjs → react-surface-ES7UHZ65.mjs} +29 -17
  67. package/dist/lib/neutral/react-surface-ES7UHZ65.mjs.map +7 -0
  68. package/dist/lib/neutral/{run-prompt-in-new-chat-D5IIE2C7.mjs → run-prompt-in-new-chat-NIAGCKQV.mjs} +11 -8
  69. package/dist/lib/neutral/run-prompt-in-new-chat-NIAGCKQV.mjs.map +7 -0
  70. package/dist/lib/neutral/{settings-W4BLWQ53.mjs → settings-7Q3RITIT.mjs} +3 -3
  71. package/dist/lib/neutral/{settings-W4BLWQ53.mjs.map → settings-7Q3RITIT.mjs.map} +3 -3
  72. package/dist/lib/neutral/{state-H3G7QCU6.mjs → state-XO2UYSSG.mjs} +2 -2
  73. package/dist/lib/neutral/{state-H3G7QCU6.mjs.map → state-XO2UYSSG.mjs.map} +3 -3
  74. package/dist/lib/neutral/testing.mjs +1 -1
  75. package/dist/lib/neutral/translations.mjs +18 -11
  76. package/dist/lib/neutral/translations.mjs.map +3 -3
  77. package/dist/lib/neutral/types/index.mjs +1 -1
  78. package/dist/types/dx.config.d.ts +28 -0
  79. package/dist/types/dx.config.d.ts.map +1 -0
  80. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  81. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -1
  82. package/dist/types/src/capabilities/index.d.ts +17 -57
  83. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  84. package/dist/types/src/capabilities/react-surface.d.ts +2 -2
  85. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  86. package/dist/types/src/components/Chat/Chat.d.ts +6 -3
  87. package/dist/types/src/components/Chat/Chat.d.ts.map +1 -1
  88. package/dist/types/src/components/Chat/Chat.stories.d.ts +32 -0
  89. package/dist/types/src/components/Chat/Chat.stories.d.ts.map +1 -0
  90. package/dist/types/src/components/ChatPrompt/ChatActions.d.ts.map +1 -1
  91. package/dist/types/src/components/ChatPrompt/ChatOptions.d.ts.map +1 -1
  92. package/dist/types/src/components/ProcessTree/ProcessTree.d.ts +6 -0
  93. package/dist/types/src/components/ProcessTree/ProcessTree.d.ts.map +1 -1
  94. package/dist/types/src/components/ProcessTree/ProcessTree.stories.d.ts +1 -0
  95. package/dist/types/src/components/ProcessTree/ProcessTree.stories.d.ts.map +1 -1
  96. package/dist/types/src/components/TaskList/TaskList.d.ts +8 -0
  97. package/dist/types/src/components/TaskList/TaskList.d.ts.map +1 -1
  98. package/dist/types/src/components/TaskList/TaskList.stories.d.ts +3 -0
  99. package/dist/types/src/components/TaskList/TaskList.stories.d.ts.map +1 -1
  100. package/dist/types/src/components/index.d.ts +1 -0
  101. package/dist/types/src/components/index.d.ts.map +1 -1
  102. package/dist/types/src/containers/ChatArticle/ChatArticle.d.ts +2 -2
  103. package/dist/types/src/containers/ChatArticle/ChatArticle.d.ts.map +1 -1
  104. package/dist/types/src/containers/ChatCompanion/ChatCompanion.d.ts +2 -2
  105. package/dist/types/src/containers/ChatDialog/ChatDialog.d.ts.map +1 -1
  106. package/dist/types/src/containers/PlanArticle/PlanArticle.d.ts.map +1 -1
  107. package/dist/types/src/containers/SpaceHomePrompt/SpaceHomePrompt.d.ts +15 -0
  108. package/dist/types/src/containers/SpaceHomePrompt/SpaceHomePrompt.d.ts.map +1 -0
  109. package/dist/types/src/containers/SpaceHomePrompt/index.d.ts +2 -0
  110. package/dist/types/src/containers/SpaceHomePrompt/index.d.ts.map +1 -0
  111. package/dist/types/src/containers/SpaceHomeSuggestions/SpaceHomeSuggestions.d.ts +13 -0
  112. package/dist/types/src/containers/SpaceHomeSuggestions/SpaceHomeSuggestions.d.ts.map +1 -0
  113. package/dist/types/src/containers/SpaceHomeSuggestions/index.d.ts +2 -0
  114. package/dist/types/src/containers/SpaceHomeSuggestions/index.d.ts.map +1 -0
  115. package/dist/types/src/containers/TracePanel/TracePanel.d.ts.map +1 -1
  116. package/dist/types/src/containers/index.d.ts +2 -0
  117. package/dist/types/src/containers/index.d.ts.map +1 -1
  118. package/dist/types/src/execution-graph/execution-graph.d.ts +18 -0
  119. package/dist/types/src/execution-graph/execution-graph.d.ts.map +1 -1
  120. package/dist/types/src/execution-graph/index.d.ts +2 -1
  121. package/dist/types/src/execution-graph/index.d.ts.map +1 -1
  122. package/dist/types/src/execution-graph/pending-block-status.d.ts +26 -0
  123. package/dist/types/src/execution-graph/pending-block-status.d.ts.map +1 -0
  124. package/dist/types/src/execution-graph/pending-block-status.test.d.ts +2 -0
  125. package/dist/types/src/execution-graph/pending-block-status.test.d.ts.map +1 -0
  126. package/dist/types/src/extensions/prompt-extension.d.ts +1 -1
  127. package/dist/types/src/extensions/prompt-extension.d.ts.map +1 -1
  128. package/dist/types/src/feed-logger.d.ts +3 -2
  129. package/dist/types/src/feed-logger.d.ts.map +1 -1
  130. package/dist/types/src/hooks/index.d.ts +2 -0
  131. package/dist/types/src/hooks/index.d.ts.map +1 -1
  132. package/dist/types/src/hooks/useProcessEphemeralStatus.d.ts +10 -0
  133. package/dist/types/src/hooks/useProcessEphemeralStatus.d.ts.map +1 -0
  134. package/dist/types/src/hooks/useTraceMessages.d.ts +12 -0
  135. package/dist/types/src/hooks/useTraceMessages.d.ts.map +1 -0
  136. package/dist/types/src/meta.d.ts +28 -2
  137. package/dist/types/src/meta.d.ts.map +1 -1
  138. package/dist/types/src/operations/run-prompt-in-new-chat.d.ts.map +1 -1
  139. package/dist/types/src/paths.d.ts.map +1 -1
  140. package/dist/types/src/processor/processor.d.ts +23 -0
  141. package/dist/types/src/processor/processor.d.ts.map +1 -1
  142. package/dist/types/src/translations.d.ts.map +1 -1
  143. package/dist/types/src/types/Assistant.d.ts +1 -1
  144. package/dist/types/src/types/AssistantCapabilities.d.ts.map +1 -1
  145. package/dist/types/src/types/AssistantEvents.d.ts.map +1 -1
  146. package/dist/types/src/types/AssistantOperation.d.ts +7 -7
  147. package/dist/types/src/util/error-cause.d.ts +3 -0
  148. package/dist/types/src/util/error-cause.d.ts.map +1 -0
  149. package/dist/types/tsconfig.tsbuildinfo +1 -1
  150. package/dx.config.ts +38 -0
  151. package/package.json +71 -70
  152. package/src/AssistantPlugin.conversations.json +1 -1
  153. package/src/AssistantPlugin.test.ts +1 -1
  154. package/src/AssistantPlugin.ts +2 -2
  155. package/src/capabilities/agent-service.ts +5 -1
  156. package/src/capabilities/app-graph-builder.ts +15 -20
  157. package/src/capabilities/blueprint-definition.ts +2 -0
  158. package/src/capabilities/index.ts +1 -7
  159. package/src/capabilities/markdown-extension.ts +5 -1
  160. package/src/capabilities/react-surface.tsx +38 -23
  161. package/src/capabilities/settings.ts +2 -2
  162. package/src/capabilities/state.ts +1 -1
  163. package/src/components/AgentProperties/AgentProperties.tsx +1 -1
  164. package/src/components/AssistantSettings/AssistantSettings.tsx +2 -2
  165. package/src/components/Chat/Chat.stories.tsx +94 -0
  166. package/src/components/Chat/Chat.tsx +39 -6
  167. package/src/components/ChatPrompt/ChatActions.tsx +4 -2
  168. package/src/components/ChatPrompt/ChatMcpErrors.tsx +1 -1
  169. package/src/components/ChatPrompt/ChatOptions.tsx +26 -29
  170. package/src/components/ChatPrompt/ChatPrompt.tsx +1 -1
  171. package/src/components/ChatPrompt/ChatReferences.tsx +1 -1
  172. package/src/components/ChatThread/Anchor.stories.tsx +1 -1
  173. package/src/components/ChatThread/ChatThread.stories.tsx +1 -1
  174. package/src/components/ChatThread/DEBUG.md +23 -0
  175. package/src/components/ChatThread/widgets/SummaryWidget.tsx +1 -1
  176. package/src/components/ChatThread/widgets/ToolWidget.tsx +1 -1
  177. package/src/components/ProcessTree/ProcessTree.stories.tsx +7 -0
  178. package/src/components/ProcessTree/ProcessTree.tsx +191 -88
  179. package/src/components/TaskList/TaskList.stories.tsx +23 -2
  180. package/src/components/TaskList/TaskList.tsx +122 -28
  181. package/src/components/TemplateEditor/TemplateEditor.tsx +1 -1
  182. package/src/components/TemplateEditor/TemplateForm.tsx +1 -1
  183. package/src/components/ToolBlock/ToolBlock.tsx +1 -1
  184. package/src/components/index.ts +1 -0
  185. package/src/containers/AgentArticle/AgentArticle.stories.tsx +4 -4
  186. package/src/containers/AgentArticle/AgentArticle.tsx +9 -9
  187. package/src/containers/ChatArticle/ChatArticle.tsx +18 -10
  188. package/src/containers/ChatCompanion/ChatCompanion.tsx +2 -2
  189. package/src/containers/ChatDialog/ChatDialog.tsx +5 -3
  190. package/src/containers/PlanArticle/PlanArticle.tsx +5 -1
  191. package/src/containers/RoutineArticle/RoutineArticle.tsx +2 -2
  192. package/src/containers/SpaceHomePrompt/SpaceHomePrompt.tsx +105 -0
  193. package/src/containers/SpaceHomePrompt/index.ts +5 -0
  194. package/src/containers/SpaceHomeSuggestions/SpaceHomeSuggestions.tsx +69 -0
  195. package/src/containers/SpaceHomeSuggestions/index.ts +5 -0
  196. package/src/containers/TracePanel/TracePanel.tsx +3 -30
  197. package/src/containers/TriggerStatus/TriggerStatus.tsx +2 -2
  198. package/src/containers/index.ts +2 -0
  199. package/src/execution-graph/execution-graph.ts +130 -0
  200. package/src/execution-graph/index.ts +10 -0
  201. package/src/execution-graph/pending-block-status.test.ts +114 -0
  202. package/src/execution-graph/pending-block-status.ts +88 -0
  203. package/src/execution-graph/sub-agent-delegation.test.ts +16 -1
  204. package/src/extensions/prompt-extension.ts +102 -73
  205. package/src/feed-logger.ts +21 -19
  206. package/src/hooks/index.ts +2 -0
  207. package/src/hooks/useChatProcessor.ts +1 -1
  208. package/src/hooks/useChatServices.ts +2 -2
  209. package/src/hooks/useChatToolbarActions.ts +5 -5
  210. package/src/hooks/useContextBinder.ts +1 -1
  211. package/src/hooks/useProcessEphemeralStatus.ts +192 -0
  212. package/src/hooks/useTraceMessages.ts +41 -0
  213. package/src/meta.ts +3 -31
  214. package/src/operations/create-chat.ts +1 -1
  215. package/src/operations/fork-chat.ts +3 -3
  216. package/src/operations/run-prompt-in-new-chat.ts +5 -3
  217. package/src/paths.ts +2 -2
  218. package/src/processor/processor.node.test.ts +71 -1
  219. package/src/processor/processor.ts +58 -2
  220. package/src/testing/data/trace-timeline-multiple.dx.json +1 -1
  221. package/src/testing/data/trace-timeline-remote.dx.json +1 -1
  222. package/src/testing/data/trace-timeline.dx.json +0 -1
  223. package/src/translations.ts +18 -10
  224. package/src/types/AssistantCapabilities.ts +3 -3
  225. package/src/types/AssistantEvents.ts +1 -1
  226. package/src/types/AssistantOperation.ts +1 -1
  227. package/src/util/error-cause.ts +21 -0
  228. package/dist/lib/neutral/AgentArticle-K7XM46OQ.mjs.map +0 -7
  229. package/dist/lib/neutral/AssistantSettings-GG52BLKS.mjs.map +0 -7
  230. package/dist/lib/neutral/ChatCompanion-LBUHYWQG.mjs.map +0 -7
  231. package/dist/lib/neutral/ChatDialog-DCA6FLOV.mjs.map +0 -7
  232. package/dist/lib/neutral/PlanArticle-TS5ULWYS.mjs.map +0 -7
  233. package/dist/lib/neutral/RoutineArticle-5NYXHRG6.mjs.map +0 -7
  234. package/dist/lib/neutral/TracePanel-KTZJ6JNR.mjs.map +0 -7
  235. package/dist/lib/neutral/TriggerStatus-X7Y5JFZJ.mjs.map +0 -7
  236. package/dist/lib/neutral/app-graph-builder-WUFHQH3Y.mjs.map +0 -7
  237. package/dist/lib/neutral/blueprint-definition-MH2QLYQH.mjs.map +0 -7
  238. package/dist/lib/neutral/chunk-HLANPOBA.mjs.map +0 -7
  239. package/dist/lib/neutral/chunk-QAZMOFPI.mjs.map +0 -7
  240. package/dist/lib/neutral/chunk-RKVVK3R3.mjs.map +0 -7
  241. package/dist/lib/neutral/chunk-VTK5R4H3.mjs +0 -9
  242. package/dist/lib/neutral/chunk-VTK5R4H3.mjs.map +0 -7
  243. package/dist/lib/neutral/chunk-XYHPOGTK.mjs +0 -43
  244. package/dist/lib/neutral/chunk-XYHPOGTK.mjs.map +0 -7
  245. package/dist/lib/neutral/chunk-YXRGZYYH.mjs.map +0 -7
  246. package/dist/lib/neutral/fork-chat-34KEF4ZJ.mjs.map +0 -7
  247. package/dist/lib/neutral/markdown-extension-YMIFDMYF.mjs +0 -110
  248. package/dist/lib/neutral/markdown-extension-YMIFDMYF.mjs.map +0 -7
  249. package/dist/lib/neutral/react-surface-XRTBW5OJ.mjs.map +0 -7
  250. package/dist/lib/neutral/run-prompt-in-new-chat-D5IIE2C7.mjs.map +0 -7
  251. package/src/testing/trace-timeline.node.conversations.json +0 -1
  252. /package/dist/lib/neutral/{ChatArticle-VNVZCDUR.mjs.map → ChatArticle-KT46SUFU.mjs.map} +0 -0
  253. /package/dist/lib/neutral/{chunk-SMFJD7BP.mjs.map → chunk-7FQT4XMI.mjs.map} +0 -0
  254. /package/dist/lib/neutral/{create-object-U2SOFZLR.mjs.map → create-object-BJUDDKQQ.mjs.map} +0 -0
@@ -43,7 +43,7 @@ import { AssistantEvents, type AssistantPluginOptions } from '#types';
43
43
  // eslint-disable-next-line import/no-relative-packages
44
44
  import pluginSpec from '../PLUGIN.mdl?raw';
45
45
 
46
- const StateReady = AppActivationEvents.createStateEvent(meta.id);
46
+ const StateReady = AppActivationEvents.createStateEvent(meta.profile.key);
47
47
 
48
48
  export const AssistantPlugin = Plugin.define<AssistantPluginOptions | void>(meta)
49
49
  .pipe(
@@ -150,7 +150,7 @@ export const AssistantPlugin = Plugin.define<AssistantPluginOptions | void>(meta
150
150
  activate: IntegrationProvider,
151
151
  }),
152
152
  AppPlugin.addPluginAssetModule({
153
- asset: { pluginId: meta.id, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },
153
+ asset: { pluginId: meta.profile.key, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },
154
154
  }),
155
155
  Plugin.make,
156
156
  );
@@ -28,7 +28,11 @@ const AgentServiceSpec = LayerSpec.make(
28
28
  Effect.gen(function* () {
29
29
  // Optional supervisor behaviour, contributed by a plugin that knows the agent/plan model.
30
30
  const strategies = yield* Capability.getAll(AutomationCapabilities.AgentDelegationStrategy);
31
- return AgentService.layer({ delegationStrategy: strategies[0] });
31
+ const completionGuards = yield* Capability.getAll(AutomationCapabilities.AgentCompletionGuard);
32
+ return AgentService.layer({
33
+ delegationStrategy: strategies[0],
34
+ completionGuard: completionGuards[0],
35
+ });
32
36
  }),
33
37
  ),
34
38
  );
@@ -7,15 +7,7 @@ import { pipe } from 'effect/Function';
7
7
  import * as Option from 'effect/Option';
8
8
 
9
9
  import { Capability } from '@dxos/app-framework';
10
- import {
11
- AppCapabilities,
12
- AppNode,
13
- LayoutOperation,
14
- createTypeSectionExtension,
15
- createTypeSectionPathResolver,
16
- getActiveSpace,
17
- getPersonalSpace,
18
- } from '@dxos/app-toolkit';
10
+ import { AppCapabilities, AppNode, AppSpace, LayoutOperation, TypeSection } from '@dxos/app-toolkit';
19
11
  import { AgentPrompt, Chat } from '@dxos/assistant-toolkit';
20
12
  import { isSpace } from '@dxos/client/echo';
21
13
  import { Operation, Routine } from '@dxos/compute';
@@ -61,7 +53,7 @@ export default Capability.makeModule(
61
53
  yield* Operation.invoke(AssistantOperation.UpdateChatName, { chat }, { spaceId: db.spaceId });
62
54
  }),
63
55
  properties: {
64
- label: ['chat-update-name.label', { ns: meta.id }],
56
+ label: ['chat-update-name.label', { ns: meta.profile.key }],
65
57
  icon: 'ph--magic-wand--regular',
66
58
  disposition: 'list-item',
67
59
  },
@@ -80,7 +72,7 @@ export default Capability.makeModule(
80
72
  data: Effect.fnUntraced(function* () {
81
73
  const capabilities = yield* Capability.Service;
82
74
  const client = yield* Capability.get(ClientCapabilities.Client);
83
- const space = getActiveSpace(client, capabilities) ?? getPersonalSpace(client);
75
+ const space = AppSpace.getActiveSpace(client, capabilities) ?? AppSpace.getPersonalSpace(client);
84
76
  if (!space) {
85
77
  return;
86
78
  }
@@ -100,7 +92,7 @@ export default Capability.makeModule(
100
92
  yield* Database.flush();
101
93
  }),
102
94
  properties: {
103
- label: ['import-compute-operations.label', { ns: meta.id }],
95
+ label: ['import-compute-operations.label', { ns: meta.profile.key }],
104
96
  icon: 'ph--download-simple--regular',
105
97
  },
106
98
  }),
@@ -108,7 +100,7 @@ export default Capability.makeModule(
108
100
  id: AssistantOperation.ToggleTracePanelDebug.meta.key,
109
101
  data: () => Operation.invoke(AssistantOperation.ToggleTracePanelDebug, {}),
110
102
  properties: {
111
- label: ['toggle-trace-panel-debug.label', { ns: meta.id }],
103
+ label: ['toggle-trace-panel-debug.label', { ns: meta.profile.key }],
112
104
  icon: 'ph--brackets-curly--regular',
113
105
  },
114
106
  }),
@@ -139,7 +131,7 @@ export default Capability.makeModule(
139
131
  return [
140
132
  AppNode.makeCompanion({
141
133
  id: linkedSegment(ASSISTANT_COMPANION_VARIANT),
142
- label: ['assistant-chat.label', { ns: meta.id }],
134
+ label: ['assistant-chat.label', { ns: meta.profile.key }],
143
135
  icon: 'ph--sparkle--regular',
144
136
  data: chat,
145
137
  position: 'first',
@@ -158,7 +150,7 @@ export default Capability.makeModule(
158
150
  Effect.succeed([
159
151
  AppNode.makeCompanion({
160
152
  id: 'invocations',
161
- label: ['invocations.label', { ns: meta.id }],
153
+ label: ['invocations.label', { ns: meta.profile.key }],
162
154
  icon: 'ph--clock-countdown--regular',
163
155
  data: 'invocations',
164
156
  }),
@@ -172,16 +164,16 @@ export default Capability.makeModule(
172
164
  Effect.succeed([
173
165
  AppNode.makeDeckCompanion({
174
166
  id: linkedSegment('trace'),
175
- label: ['trace.label', { ns: meta.id }],
167
+ label: ['trace.label', { ns: meta.profile.key }],
176
168
  icon: 'ph--line-segments--regular',
177
- data: 'trace' as const,
169
+ data: 'trace',
178
170
  position: 'last',
179
171
  }),
180
172
  ]),
181
173
  }),
182
174
 
183
175
  // Section node: standalone Chat.Chat objects per space (companions are excluded).
184
- createTypeSectionExtension(Chat.Chat, {
176
+ TypeSection.createTypeSectionExtension(Chat.Chat, {
185
177
  // Exclude chats that are the source of a CompanionTo relation; those belong to
186
178
  // their primary object's companion panel and should not appear in the top-level list.
187
179
  query: Query.without(
@@ -220,7 +212,7 @@ export default Capability.makeModule(
220
212
  );
221
213
  }),
222
214
  properties: {
223
- label: ['create-chat.label', { ns: meta.id }],
215
+ label: ['create-chat.label', { ns: meta.profile.key }],
224
216
  icon: 'ph--plus--regular',
225
217
  disposition: 'list-item-primary',
226
218
  },
@@ -231,7 +223,10 @@ export default Capability.makeModule(
231
223
 
232
224
  return [
233
225
  Capability.contributes(AppCapabilities.AppGraphBuilder, extensions),
234
- Capability.contributes(AppCapabilities.NavigationPathResolver, createTypeSectionPathResolver(Chat.Chat)),
226
+ Capability.contributes(
227
+ AppCapabilities.NavigationPathResolver,
228
+ TypeSection.createTypeSectionPathResolver(Chat.Chat),
229
+ ),
235
230
  ];
236
231
  }),
237
232
  );
@@ -27,6 +27,7 @@ import {
27
27
  DelegationBlueprint,
28
28
  DelegationHandlers,
29
29
  makeDelegationStrategy,
30
+ makePlanCompletionGuard,
30
31
  } from '@dxos/assistant-toolkit';
31
32
  import { AutomationCapabilities } from '@dxos/plugin-automation';
32
33
 
@@ -60,6 +61,7 @@ const blueprintDefinition: () => Effect.Effect<Capability.Capability<unknown>[]>
60
61
  // Run the conversational agent as a supervisor: delegate in-progress plan tasks to sub-agents
61
62
  // and fold their results back into the conversation (consumed by the AgentService LayerSpec).
62
63
  Capability.contributes(AutomationCapabilities.AgentDelegationStrategy, makeDelegationStrategy()),
64
+ Capability.contributes(AutomationCapabilities.AgentCompletionGuard, makePlanCompletionGuard()),
63
65
  ]);
64
66
 
65
67
  export default blueprintDefinition;
@@ -4,7 +4,6 @@
4
4
 
5
5
  import { Capability } from '@dxos/app-framework';
6
6
  import type { OperationHandlerSet } from '@dxos/compute';
7
- import { AutomationCapabilities } from '@dxos/plugin-automation';
8
7
 
9
8
  import type { AssistantPluginOptions } from '#types';
10
9
 
@@ -20,12 +19,7 @@ export const IntegrationProvider = Capability.lazy(
20
19
  () => import('./integration-provider'),
21
20
  );
22
21
  export const AppGraphBuilder = Capability.lazy('AppGraphBuilder', () => import('./app-graph-builder'));
23
- // Explicit annotation: the contributed capability type references `Template` from @dxos/plugin-automation,
24
- // so the inferred lazy type needs annotating to stay portable (TS2883).
25
- export const AutomationTemplates: Capability.LazyCapability<
26
- void,
27
- Capability.Capability<typeof AutomationCapabilities.Template>[]
28
- > = Capability.lazy('AutomationTemplates', () => import('./automation-templates'));
22
+ export const AutomationTemplates = Capability.lazy('AutomationTemplates', () => import('./automation-templates'));
29
23
  export const BlueprintDefinition = Capability.lazy('BlueprintDefinition', () => import('./blueprint-definition'));
30
24
  export const CompanionChatProvisioner = Capability.lazy(
31
25
  'CompanionChatProvisioner',
@@ -17,7 +17,11 @@ export default Capability.makeModule(
17
17
  const capabilities = yield* Capability.Service;
18
18
 
19
19
  return Capability.contributes(MarkdownCapabilities.ExtensionProvider, [
20
- ({ document: doc }) => {
20
+ ({ document: doc, viewMode }) => {
21
+ if (viewMode === 'source') {
22
+ return undefined;
23
+ }
24
+
21
25
  if (!doc) {
22
26
  return undefined;
23
27
  }
@@ -15,6 +15,8 @@ import { Sequence } from '@dxos/conductor';
15
15
  import { InvocationTraceContainer } from '@dxos/devtools';
16
16
  import { Feed, Obj } from '@dxos/echo';
17
17
  import { log } from '@dxos/log';
18
+ import { SpaceHomeContent, SpaceHomePinBottom } from '@dxos/plugin-space';
19
+ import { Prompts } from '@dxos/plugin-space';
18
20
  import { Panel } from '@dxos/react-ui';
19
21
 
20
22
  import { AssistantSettings } from '#components';
@@ -28,6 +30,8 @@ import {
28
30
  PlanArticle,
29
31
  RoutineArticle,
30
32
  RoutineList,
33
+ SpaceHomePrompt,
34
+ SpaceHomeSuggestions,
31
35
  TracePanel,
32
36
  TriggerStatus,
33
37
  } from '#containers';
@@ -39,19 +43,30 @@ export default Capability.makeModule(() =>
39
43
  Capability.contributes(Capabilities.ReactSurface, [
40
44
  Surface.create({
41
45
  id: 'pluginSettings',
42
- filter: AppSurface.settings(AppSurface.Article, meta.id),
46
+ filter: AppSurface.settings(AppSurface.Article, meta.profile.key),
43
47
  component: ({ data: { subject } }) => {
44
48
  const { settings, updateSettings } = useSettingsState<Assistant.Settings>(subject.atom);
45
49
  return <AssistantSettings settings={settings} onSettingsChange={updateSettings} />;
46
50
  },
47
51
  }),
52
+ Surface.create({
53
+ id: 'spaceHomePrompt',
54
+ filter: Surface.makeFilter(SpaceHomePinBottom),
55
+ component: ({ data }) => <SpaceHomePrompt space={data.space} />,
56
+ }),
57
+ Surface.create({
58
+ id: 'spaceHomeSuggestions',
59
+ filter: Surface.makeFilter(SpaceHomeContent),
60
+ position: 'last',
61
+ component: ({ data }) => <SpaceHomeSuggestions space={data.space} />,
62
+ }),
48
63
  Surface.create({
49
64
  id: 'chat',
50
- role: 'article',
51
- filter: (data): data is { attendableId: string; subject: Chat.Chat; variant: undefined } =>
52
- typeof data.attendableId === 'string' &&
53
- Obj.instanceOf(Chat.Chat, data.subject) &&
54
- data.variant !== ASSISTANT_COMPANION_VARIANT,
65
+ filter: AppSurface.object(
66
+ AppSurface.Article,
67
+ Chat.Chat,
68
+ (data) => data.variant !== ASSISTANT_COMPANION_VARIANT,
69
+ ),
55
70
  component: ({ data, role, ref }) => {
56
71
  return <ChatArticle role={role} subject={data.subject} attendableId={data.attendableId} ref={ref} />;
57
72
  },
@@ -64,17 +79,17 @@ export default Capability.makeModule(() =>
64
79
  ),
65
80
  }),
66
81
  Surface.create({
67
- id: 'agentProperties',
82
+ id: 'objectProperties',
68
83
  filter: AppSurface.object(AppSurface.ObjectProperties, Agent.Agent),
69
84
  component: ({ data }) => <AgentProperties subject={data.subject} />,
70
85
  }),
71
86
  Surface.create({
72
87
  id: 'companionChat',
73
- role: 'article',
74
- filter: (data): data is { subject: Chat.Chat | null; attendableId: string; companionTo: Obj.Unknown } =>
75
- typeof data.attendableId === 'string' &&
76
- Obj.isObject(data.companionTo) &&
77
- (Obj.instanceOf(Chat.Chat, data.subject) || data.subject === null),
88
+ filter: Surface.makeFilter(
89
+ AppSurface.Article,
90
+ (data) =>
91
+ Obj.isObject(data.companionTo) && (Obj.instanceOf(Chat.Chat, data.subject) || data.subject === null),
92
+ ),
78
93
  component: ({ data: { subject, attendableId, companionTo }, role, ref }) => (
79
94
  <ChatCompanion
80
95
  role={role}
@@ -87,10 +102,13 @@ export default Capability.makeModule(() =>
87
102
  }),
88
103
  Surface.create({
89
104
  id: 'companionInvocations',
90
- role: 'article',
91
- filter: (data): data is { companionTo: Sequence.Sequence } =>
92
- (Obj.instanceOf(Sequence.Sequence, data.companionTo) || Obj.instanceOf(Routine.Routine, data.companionTo)) &&
93
- data.subject === 'invocations',
105
+ filter: AppSurface.allOf(
106
+ AppSurface.literal(AppSurface.Article, 'invocations'),
107
+ AppSurface.oneOf(
108
+ AppSurface.companion(AppSurface.Article, Sequence.Sequence),
109
+ AppSurface.companion(AppSurface.Article, Routine.Routine),
110
+ ),
111
+ ),
94
112
  component: ({ data, role }) => {
95
113
  const space = getSpace(data.companionTo);
96
114
  const feed = space?.properties.invocationTraceFeed?.target;
@@ -100,7 +118,7 @@ export default Capability.makeModule(() =>
100
118
 
101
119
  return (
102
120
  <Panel.Root role={role} className='dx-document'>
103
- <Panel.Content asChild>
121
+ <Panel.Content>
104
122
  <InvocationTraceContainer db={space?.db} feedDXN={feedDXN} target={target} detailAxis='block' />
105
123
  </Panel.Content>
106
124
  </Panel.Root>
@@ -135,7 +153,7 @@ export default Capability.makeModule(() =>
135
153
  }),
136
154
  Surface.create({
137
155
  id: 'trace',
138
- filter: AppSurface.literal(Surface.makeType<{ subject: string }>('deck-companion--trace'), 'trace'),
156
+ filter: Surface.makeFilter(AppSurface.deckCompanion('trace')),
139
157
  component: () => {
140
158
  const space = useActiveSpace();
141
159
  useEffect(() => {
@@ -151,7 +169,7 @@ export default Capability.makeModule(() =>
151
169
  }),
152
170
  Surface.create({
153
171
  id: 'triggerStatus',
154
- role: 'status-indicator',
172
+ filter: Surface.makeFilter(AppSurface.StatusIndicator),
155
173
  component: () => {
156
174
  const space = useActiveSpace();
157
175
  if (!space) {
@@ -163,10 +181,7 @@ export default Capability.makeModule(() =>
163
181
  }),
164
182
  Surface.create({
165
183
  id: 'prompts',
166
- filter: AppSurface.subject(
167
- Surface.makeType<{ subject: Obj.Any; attendableId: string }>('prompts'),
168
- Obj.isObject,
169
- ),
184
+ filter: AppSurface.subject(Prompts, Obj.isObject),
170
185
  component: ({ data }) => <RoutineList subject={data.subject} />,
171
186
  }),
172
187
  ]),
@@ -14,7 +14,7 @@ import { Assistant, AssistantCapabilities } from '#types';
14
14
  export default Capability.makeModule(() =>
15
15
  Effect.sync(() => {
16
16
  const settingsAtom = createKvsStore({
17
- key: meta.id,
17
+ key: meta.profile.key,
18
18
  schema: Assistant.Settings,
19
19
  defaultValue: () => ({}),
20
20
  });
@@ -22,7 +22,7 @@ export default Capability.makeModule(() =>
22
22
  return [
23
23
  Capability.contributes(AssistantCapabilities.Settings, settingsAtom),
24
24
  Capability.contributes(AppCapabilities.Settings, {
25
- prefix: meta.id,
25
+ prefix: meta.profile.key,
26
26
  schema: Assistant.Settings,
27
27
  atom: settingsAtom,
28
28
  }),
@@ -17,7 +17,7 @@ export default Capability.makeModule(() =>
17
17
  // NOTE: This needs to be a chat object rather than a string id to avoid a query race.
18
18
  // TODO(wittjosiah): Handle serialization and hydration for this so it can be cached.
19
19
  const stateAtom = createKvsStore({
20
- key: meta.id,
20
+ key: meta.profile.key,
21
21
  schema: AssistantCapabilities.StateSchema,
22
22
  defaultValue: () => ({
23
23
  currentChat: {},
@@ -21,7 +21,7 @@ export type AgentPropertiesProps = {
21
21
  };
22
22
 
23
23
  export const AgentProperties = ({ agent }: AgentPropertiesProps) => {
24
- const { t } = useTranslation(meta.id);
24
+ const { t } = useTranslation(meta.profile.key);
25
25
  const db = Obj.getDatabase(agent);
26
26
 
27
27
  // Build a filter matching objects of any schema annotated as a feed.
@@ -15,7 +15,7 @@ import { Assistant } from '#types';
15
15
  export type AssistantSettingsProps = AppSurface.SettingsArticleProps<Assistant.Settings>;
16
16
 
17
17
  export const AssistantSettings = ({ settings, onSettingsChange }: AssistantSettingsProps) => {
18
- const { t } = useTranslation(meta.id);
18
+ const { t } = useTranslation(meta.profile.key);
19
19
  const fieldMap = useMemo(
20
20
  () => ({
21
21
  modelDefaults: {
@@ -29,7 +29,7 @@ export const AssistantSettings = ({ settings, onSettingsChange }: AssistantSetti
29
29
 
30
30
  return (
31
31
  <SettingsForm.Viewport>
32
- <SettingsForm.Section title={t('settings.title', { ns: meta.id })}>
32
+ <SettingsForm.Section title={t('settings.title', { ns: meta.profile.key })}>
33
33
  <SettingsForm.FieldSet<Assistant.Settings>
34
34
  readonly={!onSettingsChange}
35
35
  schema={Assistant.Settings}
@@ -0,0 +1,94 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React, { useState } from 'react';
7
+
8
+ import { Button, Toast, useTranslation } from '@dxos/react-ui';
9
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
10
+
11
+ import { meta as pluginMeta } from '#meta';
12
+ import { translations } from '#translations';
13
+
14
+ import { AiUsageQuotaError, parseError } from '../../processor';
15
+
16
+ type FailureToastProps = {
17
+ /**
18
+ * Raw failure exactly as it reaches {@link parseError}. The agent runs in a separate process and its
19
+ * failure cause is rendered to a string before it returns, so production typically surfaces a string
20
+ * here (not a typed error); the scenarios below mirror that.
21
+ */
22
+ rawError: unknown;
23
+ };
24
+
25
+ /**
26
+ * Renders the failure toast that `Chat.Thread` shows when a request fails: the title comes from the
27
+ * `ai-service-error.label` translation and the description is the message produced by {@link parseError}.
28
+ * Driving the real {@link parseError} keeps the displayed text identical to production for each failure
29
+ * class. The toast is held open (controlled) so it can be reviewed; production auto-dismisses after 20s.
30
+ */
31
+ const FailureToast = ({ rawError }: FailureToastProps) => {
32
+ const { t } = useTranslation(pluginMeta.profile.key);
33
+ const [open, setOpen] = useState(true);
34
+ const error = parseError(rawError);
35
+ const action = error instanceof AiUsageQuotaError ? error.action : undefined;
36
+
37
+ return (
38
+ <Toast.Provider>
39
+ <Toast.Viewport />
40
+ {/* Long, 32-bit-safe duration keeps the toast up for review; larger values overflow setTimeout and fire immediately. */}
41
+ <Toast.Root type='foreground' open={open} duration={24 * 60 * 60 * 1000} onOpenChange={setOpen}>
42
+ <Toast.Title icon='ph--warning--regular' onClose={() => setOpen(false)}>
43
+ {t('ai-service-error.label')}
44
+ </Toast.Title>
45
+ <Toast.Description>{error.message}</Toast.Description>
46
+ {action && (
47
+ <Toast.Actions>
48
+ <Toast.Action altText={t(action.labelKey)} asChild>
49
+ <Button onClick={() => setOpen(false)}>{t(action.labelKey)}</Button>
50
+ </Toast.Action>
51
+ </Toast.Actions>
52
+ )}
53
+ </Toast.Root>
54
+ </Toast.Provider>
55
+ );
56
+ };
57
+
58
+ const meta = {
59
+ title: 'plugins/plugin-assistant/components/Chat',
60
+ render: FailureToast,
61
+ decorators: [withTheme(), withLayout({ layout: 'fullscreen' })],
62
+ parameters: { translations },
63
+ } satisfies Meta<typeof FailureToast>;
64
+
65
+ export default meta;
66
+
67
+ type Story = StoryObj<typeof meta>;
68
+
69
+ /**
70
+ * The over-quota (HTTP 429) failure — the case this story exists for. EDGE rejects the request and
71
+ * `@effect/ai` surfaces an `HttpResponseError` whose message embeds the 429 status; the agent process
72
+ * stringifies it before it reaches the chat. Previously this fell through to "An unexpected error
73
+ * occurred."; it is now mapped to the actionable usage-limit message.
74
+ */
75
+ export const QuotaExceeded: Story = {
76
+ args: {
77
+ rawError:
78
+ 'HttpResponseError: StatusCode: An HTTP response error occurred. (429 POST https://edge.dxos.workers.dev/ai/v1/messages)\nResponse Body: {"error":{"message":"You have exceeded your usage quota."}}',
79
+ },
80
+ };
81
+
82
+ /** A configured model that the service does not recognize — the model name is surfaced to the user. */
83
+ export const ModelUnavailable: Story = {
84
+ args: {
85
+ rawError: "UnknownError: ChatCompletionsClient.streamText: model 'gemma3:27b' not found",
86
+ },
87
+ };
88
+
89
+ /** Any unrecognized failure falls back to a generic message rather than leaking implementation detail. */
90
+ export const UnexpectedError: Story = {
91
+ args: {
92
+ rawError: 'something unexpected blew up',
93
+ },
94
+ };
@@ -9,17 +9,19 @@ import React, { type PropsWithChildren, useCallback, useEffect, useMemo, useRef,
9
9
 
10
10
  import { Agent, Plan } from '@dxos/assistant-toolkit';
11
11
  import { Event } from '@dxos/async';
12
+ import { getSpace } from '@dxos/client/echo';
12
13
  import { type Database, type Feed, Filter, Obj, Query } from '@dxos/echo';
13
14
  import { useQuery } from '@dxos/react-client/echo';
14
15
  import { useIdentity } from '@dxos/react-client/halo';
15
- import { Toast, composable, composableProps, useTranslation } from '@dxos/react-ui';
16
+ import { Button, Toast, composable, composableProps, useTranslation } from '@dxos/react-ui';
16
17
  import { type MarkdownStreamController } from '@dxos/react-ui-markdown';
17
18
  import { Menu, MenuRootProps } from '@dxos/react-ui-menu';
18
19
  import { Message } from '@dxos/types';
19
20
 
20
- import { useChatKeymapExtensions, useChatToolbarActions, useDebug } from '#hooks';
21
+ import { useChatKeymapExtensions, useChatToolbarActions, useDebug, useTraceMessages } from '#hooks';
21
22
  import { meta } from '#meta';
22
23
 
24
+ import { AiUsageQuotaError } from '../../processor';
23
25
  import {
24
26
  ChatStatus,
25
27
  ChatPrompt as NaturalChatPrompt,
@@ -212,15 +214,20 @@ ChatContent.displayName = CHAT_CONTENT_NAME;
212
214
 
213
215
  const CHAT_THREAD_NAME = 'Chat.Thread';
214
216
 
215
- type ChatThreadProps = Omit<NaturalChatThreadProps, 'identity' | 'messages' | 'tools'>;
217
+ type ChatThreadProps = Omit<NaturalChatThreadProps, 'identity' | 'messages' | 'tools'> & {
218
+ /** Invoked from the over-quota error toast to open the usage dashboard. */
219
+ onViewUsage?: () => void;
220
+ };
216
221
 
217
- const ChatThread = ({ viewType, debug: debugProp, ...props }: ChatThreadProps) => {
218
- const { t } = useTranslation(meta.id);
222
+ const ChatThread = ({ viewType, debug: debugProp, onViewUsage, ...props }: ChatThreadProps) => {
223
+ const { t } = useTranslation(meta.profile.key);
219
224
  const { debug, event, messages, processor } = useChatContext(CHAT_THREAD_NAME);
220
225
  const extensions = useChatKeymapExtensions({ event });
221
226
  const identity = useIdentity();
222
227
  const error = useAtomValue(processor.error).pipe(Option.getOrUndefined);
223
228
  const [toastError, setToastError] = useState<Error | undefined>(undefined);
229
+ // The toast renders whatever action the error declares (data-driven) rather than branching on type.
230
+ const toastAction = toastError instanceof AiUsageQuotaError ? toastError.action : undefined;
224
231
  const debugView = viewType === 'debug';
225
232
 
226
233
  const controllerRef = useRef<MarkdownStreamController | null>(null);
@@ -279,6 +286,20 @@ const ChatThread = ({ viewType, debug: debugProp, ...props }: ChatThreadProps) =
279
286
  {t('ai-service-error.label')}
280
287
  </Toast.Title>
281
288
  <Toast.Description>{toastError?.message}</Toast.Description>
289
+ {toastAction && onViewUsage && (
290
+ <Toast.Actions>
291
+ <Toast.Action altText={t(toastAction.labelKey)} asChild>
292
+ <Button
293
+ onClick={() => {
294
+ setToastError(undefined);
295
+ onViewUsage();
296
+ }}
297
+ >
298
+ {t(toastAction.labelKey)}
299
+ </Button>
300
+ </Toast.Action>
301
+ </Toast.Actions>
302
+ )}
282
303
  </Toast.Root>
283
304
  </>
284
305
  );
@@ -316,11 +337,23 @@ const ChatTaskList = composable<HTMLDivElement, ChatTaskListProps>(({ plan: plan
316
337
  const parent = chat ? Obj.getParent(chat) : undefined;
317
338
  const agent = parent && Obj.instanceOf(Agent.Agent, parent) ? parent : undefined;
318
339
  const plan = planProp ?? agent?.plan.target;
340
+ const space = chat ? getSpace(chat) : undefined;
341
+ const traceMessages = useTraceMessages(space);
342
+ const conversationId = chat?.feed?.target?.id;
319
343
  if (!plan) {
320
344
  return null;
321
345
  }
322
346
 
323
- return <TaskList {...props} plan={plan} ref={forwardedRef} />;
347
+ return (
348
+ <TaskList
349
+ {...props}
350
+ plan={plan}
351
+ space={space}
352
+ traceMessages={traceMessages}
353
+ conversationId={conversationId}
354
+ ref={forwardedRef}
355
+ />
356
+ );
324
357
  });
325
358
 
326
359
  ChatTaskList.displayName = CHAT_TASK_LIST_NAME;
@@ -30,7 +30,7 @@ export const ChatActions = ({
30
30
  debug,
31
31
  onEvent,
32
32
  }: ChatActionsProps) => {
33
- const { t } = useTranslation(meta.id);
33
+ const { t } = useTranslation(meta.profile.key);
34
34
 
35
35
  return (
36
36
  <div className={mx('flex items-center', classNames)}>
@@ -68,7 +68,9 @@ export const ChatActions = ({
68
68
  icon='ph--x--regular'
69
69
  iconOnly
70
70
  label={t('cancel-processing.button')}
71
- onClick={() => onEvent?.({ type: 'cancel' })}
71
+ onClick={() => {
72
+ onEvent?.({ type: 'cancel' });
73
+ }}
72
74
  />
73
75
  </div>
74
76
  );
@@ -20,7 +20,7 @@ export type ChatMcpErrorsProps = ThemedClassName<{
20
20
  * The chat itself keeps working without these servers — this just lets the user see what was dropped.
21
21
  */
22
22
  export const ChatMcpErrors = ({ classNames, processor }: ChatMcpErrorsProps) => {
23
- const { t } = useTranslation(meta.id);
23
+ const { t } = useTranslation(meta.profile.key);
24
24
  const errors = useAtomValue(processor.mcpErrors);
25
25
 
26
26
  const handleDismiss = useCallback(() => {