@genesislcap/ai-assistant 15.19.0 → 15.19.1

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 (288) hide show
  1. package/package.json +17 -18
  2. package/api-extractor.json +0 -11
  3. package/dist/dts/components/chat-driver/chat-driver.compact.test.d.ts +0 -2
  4. package/dist/dts/components/chat-driver/chat-driver.compact.test.d.ts.map +0 -1
  5. package/dist/dts/components/chat-driver/chat-driver.invocation-scope.test.d.ts +0 -2
  6. package/dist/dts/components/chat-driver/chat-driver.invocation-scope.test.d.ts.map +0 -1
  7. package/dist/dts/components/chat-driver/chat-driver.test.d.ts +0 -2
  8. package/dist/dts/components/chat-driver/chat-driver.test.d.ts.map +0 -1
  9. package/dist/dts/components/chat-driver/chat-driver.thinking-policy.test.d.ts +0 -2
  10. package/dist/dts/components/chat-driver/chat-driver.thinking-policy.test.d.ts.map +0 -1
  11. package/dist/dts/components/chat-driver/chat-driver.trace-capture.test.d.ts +0 -2
  12. package/dist/dts/components/chat-driver/chat-driver.trace-capture.test.d.ts.map +0 -1
  13. package/dist/dts/components/chat-driver/chat-driver.turn-usage.test.d.ts +0 -2
  14. package/dist/dts/components/chat-driver/chat-driver.turn-usage.test.d.ts.map +0 -1
  15. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.test.d.ts +0 -2
  16. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.test.d.ts.map +0 -1
  17. package/dist/dts/components/orchestrating-driver/orchestrating-driver.budget.test.d.ts +0 -2
  18. package/dist/dts/components/orchestrating-driver/orchestrating-driver.budget.test.d.ts.map +0 -1
  19. package/dist/dts/components/orchestrating-driver/orchestrating-driver.cost.test.d.ts +0 -2
  20. package/dist/dts/components/orchestrating-driver/orchestrating-driver.cost.test.d.ts.map +0 -1
  21. package/dist/dts/components/orchestrating-driver/orchestrating-driver.pin.test.d.ts +0 -2
  22. package/dist/dts/components/orchestrating-driver/orchestrating-driver.pin.test.d.ts.map +0 -1
  23. package/dist/dts/components/settings-modal/settings-modal.styles.test.d.ts +0 -2
  24. package/dist/dts/components/settings-modal/settings-modal.styles.test.d.ts.map +0 -1
  25. package/dist/dts/components/settings-modal/settings-modal.template.test.d.ts +0 -2
  26. package/dist/dts/components/settings-modal/settings-modal.template.test.d.ts.map +0 -1
  27. package/dist/dts/config/define-stateful-agent.test.d.ts +0 -2
  28. package/dist/dts/config/define-stateful-agent.test.d.ts.map +0 -1
  29. package/dist/dts/config/validate-providers.test.d.ts +0 -2
  30. package/dist/dts/config/validate-providers.test.d.ts.map +0 -1
  31. package/dist/dts/main/blocked-state.test.d.ts +0 -2
  32. package/dist/dts/main/blocked-state.test.d.ts.map +0 -1
  33. package/dist/dts/main/budget-meter.test.d.ts +0 -2
  34. package/dist/dts/main/budget-meter.test.d.ts.map +0 -1
  35. package/dist/dts/main/cost-session-banking.test.d.ts +0 -2
  36. package/dist/dts/main/cost-session-banking.test.d.ts.map +0 -1
  37. package/dist/dts/main/file-attachments.test.d.ts +0 -2
  38. package/dist/dts/main/file-attachments.test.d.ts.map +0 -1
  39. package/dist/dts/main/interaction-cost.test.d.ts +0 -2
  40. package/dist/dts/main/interaction-cost.test.d.ts.map +0 -1
  41. package/dist/dts/main/main.styles.test.d.ts +0 -2
  42. package/dist/dts/main/main.styles.test.d.ts.map +0 -1
  43. package/dist/dts/main/persistence-broken-sources.test.d.ts +0 -2
  44. package/dist/dts/main/persistence-broken-sources.test.d.ts.map +0 -1
  45. package/dist/dts/main/popout-interaction-gate.test.d.ts +0 -2
  46. package/dist/dts/main/popout-interaction-gate.test.d.ts.map +0 -1
  47. package/dist/dts/state/ai-assistant-slice.test.d.ts +0 -2
  48. package/dist/dts/state/ai-assistant-slice.test.d.ts.map +0 -1
  49. package/dist/dts/state/debug-event-log.test.d.ts +0 -2
  50. package/dist/dts/state/debug-event-log.test.d.ts.map +0 -1
  51. package/dist/dts/state/driver-registry.test.d.ts +0 -2
  52. package/dist/dts/state/driver-registry.test.d.ts.map +0 -1
  53. package/dist/dts/state/interaction-context.test.d.ts +0 -2
  54. package/dist/dts/state/interaction-context.test.d.ts.map +0 -1
  55. package/dist/dts/state/persistence/diagnostics-cursors.test.d.ts +0 -2
  56. package/dist/dts/state/persistence/diagnostics-cursors.test.d.ts.map +0 -1
  57. package/dist/dts/state/persistence/diagnostics.test.d.ts +0 -2
  58. package/dist/dts/state/persistence/diagnostics.test.d.ts.map +0 -1
  59. package/dist/dts/state/persistence/session-persistence-provider.test.d.ts +0 -2
  60. package/dist/dts/state/persistence/session-persistence-provider.test.d.ts.map +0 -1
  61. package/dist/dts/state/persistence/session-persistence.integration.test.d.ts +0 -2
  62. package/dist/dts/state/persistence/session-persistence.integration.test.d.ts.map +0 -1
  63. package/dist/dts/state/persistence/session-persister.test.d.ts +0 -2
  64. package/dist/dts/state/persistence/session-persister.test.d.ts.map +0 -1
  65. package/dist/dts/state/persistence/session-snapshot.test.d.ts +0 -2
  66. package/dist/dts/state/persistence/session-snapshot.test.d.ts.map +0 -1
  67. package/dist/dts/state/persistence/stateful-restore.e2e.test.d.ts +0 -2
  68. package/dist/dts/state/persistence/stateful-restore.e2e.test.d.ts.map +0 -1
  69. package/dist/dts/utils/animation-exclusivity.test.d.ts +0 -2
  70. package/dist/dts/utils/animation-exclusivity.test.d.ts.map +0 -1
  71. package/dist/dts/utils/collect-session-models.test.d.ts +0 -2
  72. package/dist/dts/utils/collect-session-models.test.d.ts.map +0 -1
  73. package/dist/dts/utils/condense-history.test.d.ts +0 -2
  74. package/dist/dts/utils/condense-history.test.d.ts.map +0 -1
  75. package/dist/dts/utils/cost-session-history.test.d.ts +0 -2
  76. package/dist/dts/utils/cost-session-history.test.d.ts.map +0 -1
  77. package/dist/dts/utils/derive-cost-session-title.test.d.ts +0 -2
  78. package/dist/dts/utils/derive-cost-session-title.test.d.ts.map +0 -1
  79. package/dist/dts/utils/flatten-sub-agent-messages.test.d.ts +0 -2
  80. package/dist/dts/utils/flatten-sub-agent-messages.test.d.ts.map +0 -1
  81. package/dist/dts/utils/history-transform.test.d.ts +0 -2
  82. package/dist/dts/utils/history-transform.test.d.ts.map +0 -1
  83. package/dist/dts/utils/message-partition.test.d.ts +0 -2
  84. package/dist/dts/utils/message-partition.test.d.ts.map +0 -1
  85. package/dist/dts/utils/resolve-cost-history-config.test.d.ts +0 -2
  86. package/dist/dts/utils/resolve-cost-history-config.test.d.ts.map +0 -1
  87. package/dist/dts/utils/resolve-preference-baseline.test.d.ts +0 -2
  88. package/dist/dts/utils/resolve-preference-baseline.test.d.ts.map +0 -1
  89. package/dist/dts/utils/strip-agent-handlers.test.d.ts +0 -2
  90. package/dist/dts/utils/strip-agent-handlers.test.d.ts.map +0 -1
  91. package/dist/dts/utils/sum-costs.test.d.ts +0 -2
  92. package/dist/dts/utils/sum-costs.test.d.ts.map +0 -1
  93. package/dist/dts/utils/sum-tokens.test.d.ts +0 -2
  94. package/dist/dts/utils/sum-tokens.test.d.ts.map +0 -1
  95. package/dist/dts/utils/sum-usage.test.d.ts +0 -2
  96. package/dist/dts/utils/sum-usage.test.d.ts.map +0 -1
  97. package/dist/dts/utils/usage-rows.test.d.ts +0 -2
  98. package/dist/dts/utils/usage-rows.test.d.ts.map +0 -1
  99. package/dist/esm/components/chat-driver/chat-driver.compact.test.js +0 -93
  100. package/dist/esm/components/chat-driver/chat-driver.invocation-scope.test.js +0 -238
  101. package/dist/esm/components/chat-driver/chat-driver.test.js +0 -2770
  102. package/dist/esm/components/chat-driver/chat-driver.thinking-policy.test.js +0 -137
  103. package/dist/esm/components/chat-driver/chat-driver.trace-capture.test.js +0 -200
  104. package/dist/esm/components/chat-driver/chat-driver.turn-usage.test.js +0 -268
  105. package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.test.js +0 -104
  106. package/dist/esm/components/orchestrating-driver/orchestrating-driver.budget.test.js +0 -312
  107. package/dist/esm/components/orchestrating-driver/orchestrating-driver.cost.test.js +0 -76
  108. package/dist/esm/components/orchestrating-driver/orchestrating-driver.pin.test.js +0 -61
  109. package/dist/esm/components/settings-modal/settings-modal.styles.test.js +0 -80
  110. package/dist/esm/components/settings-modal/settings-modal.template.test.js +0 -91
  111. package/dist/esm/config/define-stateful-agent.test.js +0 -53
  112. package/dist/esm/config/validate-providers.test.js +0 -100
  113. package/dist/esm/main/blocked-state.test.js +0 -1065
  114. package/dist/esm/main/budget-meter.test.js +0 -359
  115. package/dist/esm/main/cost-session-banking.test.js +0 -538
  116. package/dist/esm/main/file-attachments.test.js +0 -164
  117. package/dist/esm/main/interaction-cost.test.js +0 -107
  118. package/dist/esm/main/main.styles.test.js +0 -161
  119. package/dist/esm/main/persistence-broken-sources.test.js +0 -180
  120. package/dist/esm/main/popout-interaction-gate.test.js +0 -54
  121. package/dist/esm/state/ai-assistant-slice.test.js +0 -229
  122. package/dist/esm/state/debug-event-log.test.js +0 -117
  123. package/dist/esm/state/driver-registry.test.js +0 -55
  124. package/dist/esm/state/interaction-context.test.js +0 -78
  125. package/dist/esm/state/persistence/diagnostics-cursors.test.js +0 -30
  126. package/dist/esm/state/persistence/diagnostics.test.js +0 -280
  127. package/dist/esm/state/persistence/session-persistence-provider.test.js +0 -110
  128. package/dist/esm/state/persistence/session-persistence.integration.test.js +0 -113
  129. package/dist/esm/state/persistence/session-persister.test.js +0 -613
  130. package/dist/esm/state/persistence/session-snapshot.test.js +0 -256
  131. package/dist/esm/state/persistence/stateful-restore.e2e.test.js +0 -158
  132. package/dist/esm/utils/animation-exclusivity.test.js +0 -52
  133. package/dist/esm/utils/collect-session-models.test.js +0 -53
  134. package/dist/esm/utils/condense-history.test.js +0 -547
  135. package/dist/esm/utils/cost-session-history.test.js +0 -174
  136. package/dist/esm/utils/derive-cost-session-title.test.js +0 -37
  137. package/dist/esm/utils/flatten-sub-agent-messages.test.js +0 -139
  138. package/dist/esm/utils/history-transform.test.js +0 -158
  139. package/dist/esm/utils/message-partition.test.js +0 -90
  140. package/dist/esm/utils/resolve-cost-history-config.test.js +0 -32
  141. package/dist/esm/utils/resolve-preference-baseline.test.js +0 -69
  142. package/dist/esm/utils/strip-agent-handlers.test.js +0 -81
  143. package/dist/esm/utils/sum-costs.test.js +0 -114
  144. package/dist/esm/utils/sum-tokens.test.js +0 -51
  145. package/dist/esm/utils/sum-usage.test.js +0 -164
  146. package/dist/esm/utils/usage-rows.test.js +0 -189
  147. package/dist/tsconfig.tsbuildinfo +0 -1
  148. package/license.txt +0 -46
  149. package/sandbox/tsconfig.json +0 -8
  150. package/src/channel/ai-activity-bus.ts +0 -209
  151. package/src/channel/ai-activity-channel.ts +0 -146
  152. package/src/chat-driver-node.ts +0 -159
  153. package/src/components/activity-halo/activity-halo.ts +0 -106
  154. package/src/components/agent-picker/agent-picker.constants.ts +0 -2
  155. package/src/components/agent-picker/agent-picker.styles.ts +0 -24
  156. package/src/components/agent-picker/agent-picker.template.ts +0 -54
  157. package/src/components/agent-picker/agent-picker.ts +0 -99
  158. package/src/components/agent-picker/index.ts +0 -1
  159. package/src/components/ai-driver/ai-driver.ts +0 -166
  160. package/src/components/ai-driver/index.ts +0 -1
  161. package/src/components/chat-bubble/chat-bubble.styles.ts +0 -194
  162. package/src/components/chat-bubble/chat-bubble.template.ts +0 -67
  163. package/src/components/chat-bubble/chat-bubble.ts +0 -436
  164. package/src/components/chat-bubble/index.ts +0 -1
  165. package/src/components/chat-driver/align-event-globals.ts +0 -23
  166. package/src/components/chat-driver/chat-driver.compact.test.ts +0 -131
  167. package/src/components/chat-driver/chat-driver.invocation-scope.test.ts +0 -285
  168. package/src/components/chat-driver/chat-driver.test.ts +0 -3679
  169. package/src/components/chat-driver/chat-driver.thinking-policy.test.ts +0 -185
  170. package/src/components/chat-driver/chat-driver.trace-capture.test.ts +0 -251
  171. package/src/components/chat-driver/chat-driver.ts +0 -3925
  172. package/src/components/chat-driver/chat-driver.turn-usage.test.ts +0 -362
  173. package/src/components/chat-driver/index.ts +0 -1
  174. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.styles.ts +0 -7
  175. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.template.ts +0 -6
  176. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.test.ts +0 -144
  177. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.ts +0 -243
  178. package/src/components/chat-interaction-wrapper/index.ts +0 -3
  179. package/src/components/chat-markdown/chat-markdown.ts +0 -89
  180. package/src/components/chat-markdown/index.ts +0 -1
  181. package/src/components/flowing-waves-indicator.ts +0 -286
  182. package/src/components/halo-overlay.ts +0 -184
  183. package/src/components/orchestrating-driver/index.ts +0 -1
  184. package/src/components/orchestrating-driver/orchestrating-driver.budget.test.ts +0 -438
  185. package/src/components/orchestrating-driver/orchestrating-driver.cost.test.ts +0 -107
  186. package/src/components/orchestrating-driver/orchestrating-driver.pin.test.ts +0 -96
  187. package/src/components/orchestrating-driver/orchestrating-driver.ts +0 -813
  188. package/src/components/plasma-orb-indicator.ts +0 -281
  189. package/src/components/popout-manager/index.ts +0 -1
  190. package/src/components/popout-manager/popout-manager.ts +0 -212
  191. package/src/components/settings-modal/index.ts +0 -2
  192. package/src/components/settings-modal/settings-modal.styles.test.ts +0 -94
  193. package/src/components/settings-modal/settings-modal.styles.ts +0 -853
  194. package/src/components/settings-modal/settings-modal.template.test.ts +0 -124
  195. package/src/components/settings-modal/settings-modal.template.ts +0 -943
  196. package/src/components/waves-indicator.ts +0 -241
  197. package/src/config/config.ts +0 -608
  198. package/src/config/define-stateful-agent.test.ts +0 -64
  199. package/src/config/define-stateful-agent.ts +0 -642
  200. package/src/config/fallback-agents.ts +0 -29
  201. package/src/config/index.ts +0 -2
  202. package/src/config/validate-providers.test.ts +0 -148
  203. package/src/config/validate-providers.ts +0 -58
  204. package/src/index.ts +0 -29
  205. package/src/main/blocked-state.test.ts +0 -1444
  206. package/src/main/budget-meter.test.ts +0 -477
  207. package/src/main/cost-session-banking.test.ts +0 -679
  208. package/src/main/file-attachments.test.ts +0 -215
  209. package/src/main/index.ts +0 -3
  210. package/src/main/interaction-cost.test.ts +0 -140
  211. package/src/main/main.styles.test.ts +0 -216
  212. package/src/main/main.styles.ts +0 -995
  213. package/src/main/main.template.ts +0 -1119
  214. package/src/main/main.ts +0 -5432
  215. package/src/main/main.types.ts +0 -225
  216. package/src/main/persistence-broken-sources.test.ts +0 -219
  217. package/src/main/popout-interaction-gate.test.ts +0 -87
  218. package/src/provider/ai-provider-switcher.ts +0 -40
  219. package/src/provider/assistant-app-settings.ts +0 -84
  220. package/src/state/ai-assistant-slice.test.ts +0 -336
  221. package/src/state/ai-assistant-slice.ts +0 -604
  222. package/src/state/debug-event-log.test.ts +0 -154
  223. package/src/state/debug-event-log.ts +0 -358
  224. package/src/state/driver-registry.test.ts +0 -70
  225. package/src/state/driver-registry.ts +0 -79
  226. package/src/state/interaction-context.test.ts +0 -90
  227. package/src/state/interaction-context.ts +0 -101
  228. package/src/state/persistence/build-timeline-entries.ts +0 -66
  229. package/src/state/persistence/diagnostics-cursors.test.ts +0 -53
  230. package/src/state/persistence/diagnostics-cursors.ts +0 -80
  231. package/src/state/persistence/diagnostics.test.ts +0 -346
  232. package/src/state/persistence/diagnostics.ts +0 -220
  233. package/src/state/persistence/index.ts +0 -10
  234. package/src/state/persistence/persister-registry.ts +0 -55
  235. package/src/state/persistence/session-persistence-provider.test.ts +0 -136
  236. package/src/state/persistence/session-persistence-provider.ts +0 -226
  237. package/src/state/persistence/session-persistence.integration.test.ts +0 -141
  238. package/src/state/persistence/session-persister.test.ts +0 -787
  239. package/src/state/persistence/session-persister.ts +0 -917
  240. package/src/state/persistence/session-snapshot.test.ts +0 -352
  241. package/src/state/persistence/session-snapshot.ts +0 -344
  242. package/src/state/persistence/stateful-restore.e2e.test.ts +0 -229
  243. package/src/state/session-store.ts +0 -56
  244. package/src/styles/ai-colours.ts +0 -30
  245. package/src/styles/menu.ts +0 -187
  246. package/src/styles/settings-section.ts +0 -40
  247. package/src/suggestions/chat-suggestions.ts +0 -186
  248. package/src/tags/index.ts +0 -1
  249. package/src/types/ai-chat-widget.ts +0 -67
  250. package/src/types/interaction-context.ts +0 -82
  251. package/src/utils/animated-panel-toggle.ts +0 -62
  252. package/src/utils/animation-exclusivity.test.ts +0 -72
  253. package/src/utils/animation-exclusivity.ts +0 -40
  254. package/src/utils/banked-usage-baselines.ts +0 -90
  255. package/src/utils/collect-session-models.test.ts +0 -82
  256. package/src/utils/collect-session-models.ts +0 -65
  257. package/src/utils/condense-history.test.ts +0 -746
  258. package/src/utils/condense-history.ts +0 -448
  259. package/src/utils/cost-session-history.test.ts +0 -226
  260. package/src/utils/cost-session-history.ts +0 -218
  261. package/src/utils/derive-cost-session-title.test.ts +0 -63
  262. package/src/utils/derive-cost-session-title.ts +0 -76
  263. package/src/utils/flatten-sub-agent-messages.test.ts +0 -163
  264. package/src/utils/flatten-sub-agent-messages.ts +0 -88
  265. package/src/utils/format-usd.ts +0 -26
  266. package/src/utils/history-transform.test.ts +0 -228
  267. package/src/utils/history-transform.ts +0 -163
  268. package/src/utils/index.ts +0 -3
  269. package/src/utils/logger.ts +0 -3
  270. package/src/utils/message-partition.test.ts +0 -129
  271. package/src/utils/message-partition.ts +0 -115
  272. package/src/utils/resolve-cost-history-config.test.ts +0 -38
  273. package/src/utils/resolve-cost-history-config.ts +0 -38
  274. package/src/utils/resolve-preference-baseline.test.ts +0 -84
  275. package/src/utils/resolve-preference-baseline.ts +0 -80
  276. package/src/utils/strip-agent-handlers.test.ts +0 -99
  277. package/src/utils/strip-agent-handlers.ts +0 -53
  278. package/src/utils/sum-costs.test.ts +0 -136
  279. package/src/utils/sum-costs.ts +0 -18
  280. package/src/utils/sum-tokens.test.ts +0 -93
  281. package/src/utils/sum-tokens.ts +0 -68
  282. package/src/utils/sum-usage.test.ts +0 -191
  283. package/src/utils/sum-usage.ts +0 -208
  284. package/src/utils/tool-fold.ts +0 -181
  285. package/src/utils/usage-rows.test.ts +0 -237
  286. package/src/utils/usage-rows.ts +0 -187
  287. package/src/utils/with-timeout.ts +0 -24
  288. package/tsconfig.json +0 -9
@@ -1,225 +0,0 @@
1
- /**
2
- * State of the AI assistant component.
3
- *
4
- * `cancelling` is a refinement of `loading`: a stop was requested but the turn
5
- * is still winding down (e.g. a tool mid-execution finishing). It is "busy"
6
- * like `loading` — use the host's `busy` getter for "is a turn active" gates.
7
- *
8
- * @beta
9
- */
10
- export type AiAssistantState = 'idle' | 'loading' | 'cancelling' | 'error';
11
-
12
- /**
13
- * Controls the pop-out button shown in the assistant header.
14
- * - `"expand"` — assistant is embedded in the bubble dialog; button expands it to a layout panel.
15
- * - `"collapse"` — assistant is in a layout panel; button collapses it back to the bubble.
16
- *
17
- * @beta
18
- */
19
- export type PopoutMode = 'expand' | 'collapse';
20
-
21
- export type { AgentPickerMode } from '@genesislcap/foundation-ai';
22
-
23
- /**
24
- * Result returned by {@link FoundationAiAssistant.submitMessage}.
25
- *
26
- * `ok` is `false` when the assistant is busy, the message is empty, or any
27
- * supplied file failed validation — in which case no send was dispatched and
28
- * `errors` lists the reasons.
29
- *
30
- * @beta
31
- */
32
- export interface SubmitMessageResult {
33
- ok: boolean;
34
- errors: string[];
35
- }
36
-
37
- /**
38
- * `detail` of the `AiAssistantEvent.SessionCleared` event. Captured *before*
39
- * teardown so a host can tidy up whatever the active agent was working on
40
- * (generated files, server-side scratch, …). `agentSnapshot` is the agent's
41
- * `serialize()` output (a state-machine image for machine-backed agents).
42
- *
43
- * @beta
44
- */
45
- export interface SessionClearedDetail {
46
- sessionKey: string | undefined;
47
- agentName: string | undefined;
48
- agentSnapshot: unknown;
49
- }
50
-
51
- /**
52
- * `detail` of the `AiAssistantEvent.ChatHeaderMouseDown` event.
53
- *
54
- * @beta
55
- */
56
- export interface ChatHeaderMouseDownDetail {
57
- clientX: number;
58
- clientY: number;
59
- }
60
-
61
- /**
62
- * DOM events the `<foundation-ai-assistant>` element dispatches to its host.
63
- * All bubble and are `composed` (they cross the shadow boundary), so a host can
64
- * listen on the element — or any ancestor — to react. Use these constants to
65
- * wire listeners instead of hand-typing event-name strings.
66
- *
67
- * An `as const` map (not a TS `enum` — this package ships none), so it serves as
68
- * both the listener-name value and, via the same-named type below, a union.
69
- *
70
- * @example
71
- * ```ts
72
- * import { AiAssistantEvent, type SessionClearedDetail } from '@genesislcap/ai-assistant';
73
- *
74
- * el.addEventListener(AiAssistantEvent.SessionCleared, (e) => {
75
- * const { agentName, agentSnapshot } = (e as CustomEvent<SessionClearedDetail>).detail;
76
- * // …clean up external state the agent was working on…
77
- * });
78
- * ```
79
- *
80
- * @beta
81
- */
82
- export const AiAssistantEvent = {
83
- /** Session wiped via the lifecycle menu's Clear. `detail`: `SessionClearedDetail`. */
84
- SessionCleared: 'session-cleared',
85
- /** Header pressed in `popout-mode="expand"` (drag-to-popout hosts). `detail`: `ChatHeaderMouseDownDetail`. */
86
- ChatHeaderMouseDown: 'chat-header-mousedown',
87
- } as const;
88
-
89
- /**
90
- * One of the `AiAssistantEvent` event-name values.
91
- *
92
- * @beta
93
- */
94
- export type AiAssistantEvent = (typeof AiAssistantEvent)[keyof typeof AiAssistantEvent];
95
-
96
- /**
97
- * One rendered row of the settings-modal budget meter (GENC-1464) — a vendor
98
- * that currently has budget figures, pre-formatted so the template stays a pure
99
- * binding layer (and so tests can pin the exact text a user reads).
100
- *
101
- * @beta
102
- */
103
- export interface SettingsBudgetRow {
104
- /** The vendor the row describes (an `AIProviderType` member). */
105
- vendor: string;
106
- /** Display name from `VENDOR_LABELS`, e.g. `Anthropic`. */
107
- label: string;
108
- /**
109
- * The real figures — `$45.00 / $50.00 (90%)`. The percentage is NOT clamped:
110
- * spend can genuinely overshoot the cap (the last allowed call may cross it),
111
- * and the text tells the truth about it.
112
- */
113
- figures: string;
114
- /**
115
- * The bar's value, clamped to `0..100` — a progress bar past its end renders
116
- * nonsense, so only the bar clamps (mirroring the context-usage indicator's
117
- * `Math.min(100, …)`).
118
- */
119
- barValue: number;
120
- }
121
-
122
- /**
123
- * State of the chat suggestions feature.
124
- *
125
- * @beta
126
- */
127
- export type SuggestionsState =
128
- | { status: 'idle' }
129
- | { status: 'loading' }
130
- | { status: 'loaded'; suggestions: string[] }
131
- | { status: 'error'; message: string };
132
-
133
- /**
134
- * Metadata describing a UI animation in the assistant.
135
- *
136
- * @beta
137
- */
138
- export interface AiAssistantAnimationDef {
139
- /** Display label shown in the settings multiselect. */
140
- label: string;
141
- /** Short description shown beneath the label in the categorized multiselect. */
142
- description: string;
143
- /** Group heading the option is listed under in the settings multiselect. */
144
- category: string;
145
- }
146
-
147
- /**
148
- * Registry of all available animations with their display metadata.
149
- * Adding an entry here automatically extends the {@link AiAssistantAnimation} type.
150
- *
151
- * @remarks
152
- * `loading` (dots), `waves`, `flowingWaves` and `plasma` are interchangeable
153
- * styles of the same "is the assistant working" indicator and are therefore
154
- * grouped under the same {@link AiAssistantAnimationDef.category}. They are
155
- * mutually exclusive — see `LOADING_STYLE_ANIMATIONS`.
156
- *
157
- * @beta
158
- */
159
- export const ANIMATION_DEFS = {
160
- loading: {
161
- label: 'Dots',
162
- description: 'Shows pulsing dots while the assistant is generating a response.',
163
- category: 'Loading style',
164
- },
165
- waves: {
166
- label: 'Waves',
167
- description:
168
- 'Shows glowing sine waves inside a circle while the assistant is generating a response.',
169
- category: 'Loading style',
170
- },
171
- flowingWaves: {
172
- label: 'Flowing waves',
173
- description:
174
- 'Shows coloured waves rising and settling from a line while the assistant is generating a response.',
175
- category: 'Loading style',
176
- },
177
- plasma: {
178
- label: 'Plasma orb',
179
- description:
180
- 'Shows a glowing plasma sphere with drifting energy while the assistant is generating a response.',
181
- category: 'Loading style',
182
- },
183
- halo: {
184
- label: 'Halo',
185
- description:
186
- 'Displays a glowing halo around the assistant avatar while a response is streaming.',
187
- category: 'Effects',
188
- },
189
- } satisfies Record<string, AiAssistantAnimationDef>;
190
-
191
- /**
192
- * Union of all available animation names, derived from {@link ANIMATION_DEFS}.
193
- *
194
- * @beta
195
- */
196
- export type AiAssistantAnimation = keyof typeof ANIMATION_DEFS;
197
-
198
- /**
199
- * All available animation names, derived from the registry.
200
- *
201
- * @internal
202
- */
203
- export const ALL_ANIMATIONS = Object.keys(ANIMATION_DEFS) as AiAssistantAnimation[];
204
-
205
- /**
206
- * The interchangeable "assistant is working" loading-indicator styles. At most
207
- * one of these may be enabled at a time — enabling one disables the other.
208
- *
209
- * @internal
210
- */
211
- export const LOADING_STYLE_ANIMATIONS = [
212
- 'loading',
213
- 'waves',
214
- 'flowingWaves',
215
- 'plasma',
216
- ] as const satisfies readonly AiAssistantAnimation[];
217
-
218
- /**
219
- * Animations enabled by default when a consumer opts into the animations
220
- * feature without specifying an explicit `enabled` list. Keeps the dots loading
221
- * style (the long-standing default); the waves style is opt-in.
222
- *
223
- * @internal
224
- */
225
- export const DEFAULT_ANIMATIONS: AiAssistantAnimation[] = ['loading', 'halo'];
@@ -1,219 +0,0 @@
1
- import { assert, createLogicSuite } from '@genesislcap/foundation-testing';
2
- import { DOM } from '@genesislcap/web-core';
3
- import { FoundationAiAssistant } from './main';
4
-
5
- // Hold a reference so the custom-element registration isn't tree-shaken.
6
- FoundationAiAssistant;
7
-
8
- // GENC-1511 — the blocking "not saving" modal has MORE THAN ONE reporter: this element's own
9
- // session persister (`sessions/<key>`), and a host reporting its own keyspaces through the public
10
- // API (Create's `projects/<id>.json`, which holds the app rather than the transcript).
11
- //
12
- // It was first built on a single `persistenceBroken` boolean, and review caught what that costs:
13
- // whichever reporter recovered FIRST closed the modal for both, and the host's own re-entry guard
14
- // then kept it from ever being raised again. This suite pins the per-source behaviour so that
15
- // collision cannot come back.
16
- //
17
- // Like `blocked-state.test.ts`, this exercises the METHODS the template bindings read rather than
18
- // the rendered DOM: `document.createElement` upgrades the element (constructor) without connecting
19
- // it, so `connectedCallback` never runs and nothing subscribes to `agenticActivityBus` — which
20
- // would otherwise hold the test runner's event loop open.
21
- const Suite = createLogicSuite('FoundationAiAssistant persistence-broken sources');
22
-
23
- /** A fresh, unconnected element. Nothing here needs a session store. */
24
- const element = (): FoundationAiAssistant =>
25
- document.createElement('foundation-ai-assistant') as FoundationAiAssistant;
26
-
27
- /** The modal's visible copy, as the template bindings read it. */
28
- const copy = (el: FoundationAiAssistant) => ({
29
- broken: el.persistenceBroken,
30
- message: el.persistenceBrokenMessage,
31
- detail: el.persistenceBrokenDetail,
32
- });
33
-
34
- const SESSION = 'session';
35
- const PROJECT = 'project';
36
-
37
- Suite('a single reporter raises and withdraws its own warning', () => {
38
- const el = element();
39
- assert.is(el.persistenceBroken, false);
40
-
41
- el.reportPersistenceBroken({ detail: '2 messages have not been saved.', source: SESSION });
42
- assert.is(el.persistenceBroken, true);
43
- assert.is(el.persistenceBrokenDetail, '2 messages have not been saved.');
44
-
45
- el.reportPersistenceRecovered(SESSION);
46
- assert.is(el.persistenceBroken, false);
47
- assert.is(el.persistenceBrokenMessage, undefined);
48
- assert.is(el.persistenceBrokenDetail, undefined);
49
- });
50
-
51
- Suite('one source recovering does NOT withdraw another still-broken source', () => {
52
- const el = element();
53
- el.reportPersistenceBroken({ detail: 'session detail', source: SESSION });
54
- el.reportPersistenceBroken({ message: 'project copy', source: PROJECT });
55
-
56
- // The session's own save lands. Its warning goes; the project's must not.
57
- el.reportPersistenceRecovered(SESSION);
58
-
59
- assert.is(el.persistenceBroken, true, 'modal must stay up while the project store is failing');
60
- assert.is(el.persistenceBrokenMessage, 'project copy', 'and must still describe THAT failure');
61
-
62
- el.reportPersistenceRecovered(PROJECT);
63
- assert.is(el.persistenceBroken, false, 'only once nothing is broken');
64
- });
65
-
66
- Suite('a later report does not overwrite an earlier source with its own copy', () => {
67
- const el = element();
68
- el.reportPersistenceBroken({
69
- message: 'project copy',
70
- detail: 'project detail',
71
- source: PROJECT,
72
- });
73
-
74
- // The session reports with NO message override — it wants the template's session default.
75
- // Before per-source tracking this assigned `undefined` over the project wording, so the modal
76
- // claimed "this session has stopped saving" about a failed PROJECT write.
77
- el.reportPersistenceBroken({ detail: 'session detail', source: SESSION });
78
- assert.is(el.persistenceBrokenMessage, undefined, 'newest source wins while it is broken');
79
- assert.is(el.persistenceBrokenDetail, 'session detail');
80
-
81
- // ...and when the newest recovers, the copy falls BACK to the survivor rather than staying
82
- // on the recovered source's wording (or reverting to the default).
83
- el.reportPersistenceRecovered(SESSION);
84
- assert.is(el.persistenceBrokenMessage, 'project copy');
85
- assert.is(el.persistenceBrokenDetail, 'project detail');
86
- assert.is(el.persistenceBroken, true);
87
- });
88
-
89
- Suite('recovering an unknown or already-recovered source is a no-op', () => {
90
- const el = element();
91
- el.reportPersistenceBroken({ message: 'project copy', source: PROJECT });
92
-
93
- el.reportPersistenceRecovered(SESSION); // never reported
94
- assert.equal(copy(el), { broken: true, message: 'project copy', detail: undefined });
95
-
96
- el.reportPersistenceRecovered(PROJECT);
97
- el.reportPersistenceRecovered(PROJECT); // twice
98
- assert.equal(copy(el), { broken: false, message: undefined, detail: undefined });
99
- });
100
-
101
- Suite('re-reporting the same source refreshes its copy without duplicating it', () => {
102
- const el = element();
103
- el.reportPersistenceBroken({ detail: '2 messages have not been saved.', source: SESSION });
104
- el.reportPersistenceBroken({ detail: '5 messages have not been saved.', source: SESSION });
105
- assert.is(el.persistenceBrokenDetail, '5 messages have not been saved.');
106
-
107
- // One recovery must clear it — a second entry for the same source would leave it stuck on.
108
- el.reportPersistenceRecovered(SESSION);
109
- assert.is(el.persistenceBroken, false);
110
- });
111
-
112
- Suite('a host that omits the source gets a default it can still recover', () => {
113
- const el = element();
114
- el.reportPersistenceBroken({ message: 'host copy' });
115
- assert.is(el.persistenceBroken, true);
116
-
117
- el.reportPersistenceRecovered();
118
- assert.is(el.persistenceBroken, false);
119
- });
120
-
121
- Suite("a host's default source is independent of the session's", () => {
122
- const el = element();
123
- el.reportPersistenceBroken({ detail: 'session detail', source: SESSION });
124
- el.reportPersistenceBroken({ message: 'host copy' });
125
-
126
- el.reportPersistenceRecovered(); // the host's
127
- assert.is(el.persistenceBroken, true, 'the session failure is still live');
128
- assert.is(el.persistenceBrokenDetail, 'session detail');
129
- });
130
-
131
- // GENC-1511 (PR #2472 review) — the deferred show is a separate race from the source tracking.
132
- // `persistenceBrokenChanged` queues the show via `DOM.queueUpdate`, and the queued callback used
133
- // not to re-read the flag. A `true → false` inside the same batch runs the `!broken` branch against
134
- // a modal that was never shown (both statements no-op), and the callback then raised a blocking,
135
- // NON-DISMISSIBLE modal for a problem that had already fixed itself — with no further change event
136
- // left to close it, so the only way out was a reload nobody needed.
137
- //
138
- // Reachable because `maybeReportBroken` fires before `provider.save` in `persistSession`, so a
139
- // report and the write that withdraws it can share a tick.
140
-
141
- /** Minimal stand-in for the design-system modal, recording what the callback did to it. */
142
- function modalStub() {
143
- const calls = { show: 0, close: 0 };
144
- const dialog = document.createElement('dialog');
145
- return {
146
- calls,
147
- modal: {
148
- open: false,
149
- mainElement: dialog,
150
- show() {
151
- calls.show += 1;
152
- this.open = true;
153
- },
154
- close() {
155
- calls.close += 1;
156
- this.open = false;
157
- },
158
- },
159
- };
160
- }
161
-
162
- /**
163
- * Drain the FAST update queue SYNCHRONOUSLY.
164
- *
165
- * `DOM.processUpdates()` and not an `await setTimeout(0)`: the queue lands on
166
- * `requestAnimationFrame`, which a zero-delay timer does not reliably cover. A timer-based flush
167
- * made these tests pass or fail on scheduling luck — the "does not show" assertion passed for the
168
- * wrong reason, and its positive control passed only because earlier tests had pumped the queue.
169
- */
170
- const flush = () => DOM.processUpdates();
171
-
172
- const withModal = (el: FoundationAiAssistant, modal: unknown) => {
173
- (el as unknown as { persistenceModal: unknown }).persistenceModal = modal;
174
- };
175
-
176
- // POSITIVE CONTROL for the test below. Without it, a queue that never drains in this environment
177
- // would make the "does not show" assertion pass for entirely the wrong reason.
178
- Suite('the deferred show DOES raise the modal when the failure is still live', () => {
179
- const el = element();
180
- const { calls, modal } = modalStub();
181
- withModal(el, modal);
182
-
183
- el.reportPersistenceBroken({ detail: 'session detail', source: SESSION });
184
- flush();
185
-
186
- assert.is(calls.show, 1, 'precondition: the queued callback runs in this environment');
187
- assert.is(modal.open, true);
188
- });
189
-
190
- Suite('a recovery inside the same batch cancels the deferred show', () => {
191
- const el = element();
192
- const { calls, modal } = modalStub();
193
- withModal(el, modal);
194
-
195
- el.reportPersistenceBroken({ detail: 'session detail', source: SESSION });
196
- el.reportPersistenceRecovered(SESSION); // lands before the queue flushes
197
- flush();
198
-
199
- assert.is(el.persistenceBroken, false);
200
- assert.is(calls.show, 0, 'must not raise a blocking modal for a resolved failure');
201
- assert.is(modal.open, false);
202
- });
203
-
204
- Suite('a recovery of ONE source still shows for the source left broken', () => {
205
- const el = element();
206
- const { calls, modal } = modalStub();
207
- withModal(el, modal);
208
-
209
- el.reportPersistenceBroken({ detail: 'session detail', source: SESSION });
210
- el.reportPersistenceBroken({ message: 'project copy', source: PROJECT });
211
- el.reportPersistenceRecovered(SESSION);
212
- flush();
213
-
214
- assert.is(el.persistenceBroken, true);
215
- assert.is(calls.show, 1, 'the project failure still warrants the modal');
216
- assert.is(el.persistenceBrokenMessage, 'project copy');
217
- });
218
-
219
- Suite.run();
@@ -1,87 +0,0 @@
1
- import type { ChatMessage } from '@genesislcap/foundation-ai';
2
- import { assert, createLogicSuite } from '@genesislcap/foundation-testing';
3
- import { FoundationAiAssistant } from './main';
4
-
5
- // Hold a reference so the custom-element registration isn't tree-shaken.
6
- FoundationAiAssistant;
7
-
8
- // GENC-1351 §5.11 (PR review): the single-element popout refactor removed the
9
- // `claimSideEffect` first-writer latch, so the only thing preventing a pending
10
- // interaction widget from being re-instantiated (and re-firing its side effect) on a
11
- // dock/undock move is that the popout control is disabled while an interaction is
12
- // pending — the template binds `?disabled=${x.hasActivePendingInteraction}`
13
- // (`main.template.ts`). This suite pins the GATE LOGIC (`hasActivePendingInteraction`)
14
- // that binding depends on, so a change to when the gate opens/closes is caught.
15
- //
16
- // Note: this deliberately does NOT mount the assistant. Mounting runs `connectedCallback`,
17
- // which subscribes to `agenticActivityBus` — opening a cross-tab `BroadcastChannel` in a browser
18
- // env and leaving the runner's event loop open. A getter-level test needs no mount and stays fast
19
- // + reliable. `document.createElement` only upgrades the element (constructor) — it does not
20
- // connect — so nothing subscribes, and the bus opens its channel lazily on first use, so none is
21
- // ever created here (no teardown needed).
22
-
23
- const Suite = createLogicSuite('FoundationAiAssistant popout interaction gate');
24
-
25
- /** A fresh (unconnected) element with a fake session store wired in. */
26
- function elementWith(state: string, messages: ChatMessage[]): FoundationAiAssistant {
27
- const el = document.createElement('foundation-ai-assistant') as FoundationAiAssistant;
28
- (el as unknown as { _sessionRef: unknown })._sessionRef = {
29
- store: { aiAssistant: { state, messages } },
30
- };
31
- return el;
32
- }
33
-
34
- const withInteraction = (resolved: boolean | { value: string }): ChatMessage[] => [
35
- { role: 'user', content: 'hi' } as ChatMessage,
36
- {
37
- role: 'assistant',
38
- content: resolved ? 'done' : '',
39
- interaction: { interactionId: '1', componentName: 'x', data: {}, resolved },
40
- } as unknown as ChatMessage,
41
- ];
42
-
43
- Suite('is true only while a turn is running AND a pending interaction is the last message', () => {
44
- // Gated: a turn is running and the last message is an unresolved interaction. This is
45
- // the state during which the popout/dock control MUST be disabled.
46
- assert.is(
47
- elementWith('loading', withInteraction(false)).hasActivePendingInteraction,
48
- true,
49
- 'busy + unresolved interaction → gated',
50
- );
51
- // `cancelling` counts as busy too (a stop was requested but the turn is winding down).
52
- assert.is(
53
- elementWith('cancelling', withInteraction(false)).hasActivePendingInteraction,
54
- true,
55
- 'cancelling + unresolved interaction → gated',
56
- );
57
- });
58
-
59
- Suite('is false when idle, when the interaction is resolved, or when there is none', () => {
60
- // Not busy → never gated, even with an unresolved interaction present.
61
- assert.is(
62
- elementWith('idle', withInteraction(false)).hasActivePendingInteraction,
63
- false,
64
- 'idle → not gated',
65
- );
66
- // Busy but the interaction has resolved → the widget is answered, nothing to strand.
67
- assert.is(
68
- elementWith('loading', withInteraction({ value: 'ok' })).hasActivePendingInteraction,
69
- false,
70
- 'resolved interaction → not gated',
71
- );
72
- // Busy but the last message is not an interaction at all.
73
- assert.is(
74
- elementWith('loading', [{ role: 'assistant', content: 'thinking' } as ChatMessage])
75
- .hasActivePendingInteraction,
76
- false,
77
- 'no interaction → not gated',
78
- );
79
- // No session / empty transcript.
80
- assert.is(
81
- elementWith('loading', []).hasActivePendingInteraction,
82
- false,
83
- 'empty transcript → not gated',
84
- );
85
- });
86
-
87
- Suite.run();
@@ -1,40 +0,0 @@
1
- import { DI } from '@genesislcap/web-core';
2
-
3
- /**
4
- * Optional app-registered policy for which cloud vendor backs the tier-shaped
5
- * provider registry slots (`low` / `high` / …). Apps inject a concrete
6
- * implementation on this DI token at bootstrap; consumers include the
7
- * slotted `settings-model` component or a header vendor control.
8
- * The platform settings modal does not render vendor UI itself.
9
- *
10
- * @beta
11
- */
12
- export interface AIProviderSwitcher {
13
- readonly vendor: string;
14
- readonly vendors: readonly string[];
15
- switchTo(vendor: string): void;
16
- subscribe(listener: (vendor: string) => void): () => void;
17
- }
18
-
19
- class NoopAIProviderSwitcher implements AIProviderSwitcher {
20
- readonly vendor = '';
21
- readonly vendors: readonly string[] = [];
22
- switchTo(): void {
23
- /* no-op */
24
- }
25
- subscribe(): () => void {
26
- return () => {
27
- /* no-op */
28
- };
29
- }
30
- }
31
-
32
- /**
33
- * The DI token for the {@link (AIProviderSwitcher:interface)}. Resolves a noop until the app
34
- * registers one.
35
- *
36
- * @beta
37
- */
38
- export const AIProviderSwitcher = DI.createInterface<AIProviderSwitcher>((x) =>
39
- x.singleton(NoopAIProviderSwitcher),
40
- );
@@ -1,84 +0,0 @@
1
- import { DI } from '@genesislcap/web-core';
2
-
3
- /**
4
- * One boolean toggle rendered in the platform settings modal app section.
5
- *
6
- * @beta
7
- */
8
- export interface AssistantAppSettingsToggle {
9
- /** Stable id passed to {@link (AssistantAppSettingsProvider:interface).getValue} / `setValue`. */
10
- id: string;
11
- title: string;
12
- description: string;
13
- /** Optional `part` name for the toggle row (defaults to `app-toggle-${id}`). */
14
- part?: string;
15
- /** When provided and returns false, the toggle is hidden. */
16
- visible?: () => boolean;
17
- /** When provided and returns true, the switch is disabled. */
18
- disabled?: () => boolean;
19
- /** Optional footnote rendered below the row when the string is non-empty. */
20
- hint?: () => string | undefined;
21
- }
22
-
23
- /**
24
- * Optional heading above a provider's toggle group.
25
- *
26
- * Entirely host-supplied — the assistant has no default title and no default icon, because the
27
- * section belongs to the host. Omit it and the toggles render bare, which is right when the
28
- * host's slotted content already titles them.
29
- *
30
- * @beta
31
- */
32
- export interface AssistantAppSettingsHeading {
33
- readonly title: string;
34
- /**
35
- * Icon name for the design system's icon element (a Font Awesome free name, e.g.
36
- * `'object-group'`). Omitted renders text only; an unknown name renders nothing at all, so
37
- * check it against the installed Font Awesome set.
38
- */
39
- readonly icon?: string;
40
- }
41
-
42
- /**
43
- * App-supplied settings for the host's own section of the settings modal. Register a concrete
44
- * implementation on the DI token at app bootstrap; the assistant renders the toggles with the
45
- * same row layout as AI Chat Bot settings.
46
- *
47
- * The section itself is untitled by the assistant — no heading text and no icon — because only
48
- * the host knows what it is. Title it from the `settings-app` slot, which renders above these
49
- * toggles, and apply `assistantSettingsSectionTitleStyles` to match the built-in headings.
50
- *
51
- * @beta
52
- */
53
- export interface AssistantAppSettingsProvider {
54
- readonly toggles: readonly AssistantAppSettingsToggle[];
55
- /**
56
- * Heading for the toggle group, for hosts that put other controls in the `settings-app` slot
57
- * and need these distinguished from them. No default: absent means no heading.
58
- */
59
- readonly togglesHeading?: AssistantAppSettingsHeading;
60
- getValue(id: string): boolean;
61
- setValue(id: string, value: boolean): void;
62
- /** Notify the assistant to re-read toggle values / visibility. */
63
- subscribe?(listener: () => void): () => void;
64
- }
65
-
66
- class NoopAssistantAppSettingsProvider implements AssistantAppSettingsProvider {
67
- readonly toggles: readonly AssistantAppSettingsToggle[] = [];
68
- getValue(): boolean {
69
- return false;
70
- }
71
- setValue(): void {
72
- /* no-op */
73
- }
74
- }
75
-
76
- /**
77
- * The DI token for the {@link (AssistantAppSettingsProvider:interface)}. Resolves a noop
78
- * until the host registers one.
79
- *
80
- * @beta
81
- */
82
- export const AssistantAppSettingsProvider = DI.createInterface<AssistantAppSettingsProvider>((x) =>
83
- x.singleton(NoopAssistantAppSettingsProvider),
84
- );