@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,229 +0,0 @@
1
- import type {
2
- AIProvider,
3
- AIProviderRegistry,
4
- ChatMessage,
5
- ChatRequestOptions,
6
- } from '@genesislcap/foundation-ai';
7
- import { assert, createLogicSuite } from '@genesislcap/foundation-testing';
8
- // Side-effect import — MUST precede the driver import so it subclasses jsdom's
9
- // EventTarget (CustomEvent dispatch then works in node).
10
- import '../../components/chat-driver/align-event-globals';
11
- import { OrchestratingDriver } from '../../components/orchestrating-driver/orchestrating-driver';
12
- import type { AgentConfig } from '../../config/config';
13
- import { clearDiagnosticsCursorRegistry } from './diagnostics-cursors';
14
- import { clearPersisterRegistry } from './persister-registry';
15
- import { SessionPersister, type SessionPersisterDeps } from './session-persister';
16
- import type { PersistedSession } from './session-snapshot';
17
-
18
- // GENC-1351 — end-to-end save→restore→route→re-activate proof. The persister unit
19
- // tests exercise `persistSession`/`restore` against a FAKE driver; the driver pin/
20
- // flow-owner tests exercise routing against a real driver. NOTHING wired the two
21
- // together — the exact integration that broke once (bug #2: the live agent's
22
- // `serialize()` was read via `driver.getActiveAgent()` — a host minting fresh
23
- // configs handed back a never-activated closure whose `serialize()` returned
24
- // undefined, so the machine reset on reload). This test closes that gap with a REAL
25
- // `OrchestratingDriver` + a REAL `SessionPersister` + an in-memory provider:
26
- // persist (capture the LIVE agent's state) → restore (prime + re-lock routing) →
27
- // send (route back to the flow-owner without re-classifying) → re-activate aligned.
28
- // `Planner` is `excludeFromClassifier` AND never pinned, so a turn landing on it after
29
- // restore proves the RESTORED flow-owner lock (not the pin, not the classifier) routed
30
- // it — the `setFlowOwner`-on-restore half of the fix.
31
-
32
- const KEY = 'e2e-session';
33
-
34
- const makeRegistry = (provider: AIProvider): AIProviderRegistry => ({
35
- get: () => provider,
36
- default: () => provider,
37
- defaultName: () => 'test',
38
- names: () => ['test'],
39
- getStatus: async () => null,
40
- listStatuses: async () => [],
41
- });
42
-
43
- /** A provider that ends every turn immediately with a plain-text reply (no tools). */
44
- const noToolProvider = (): AIProvider =>
45
- ({
46
- chat: async (
47
- _history: ChatMessage[],
48
- _userMessage: string,
49
- _options?: ChatRequestOptions,
50
- ): Promise<ChatMessage> => ({ role: 'assistant', content: 'ok' }),
51
- }) as AIProvider;
52
-
53
- const agentCfg = (overrides: Partial<AgentConfig> & { name: string }): AgentConfig =>
54
- ({ description: 'test agent', ...overrides }) as AgentConfig;
55
-
56
- /** In-memory persistence provider (single session), enough for one save + one load. */
57
- function makeMemoryProvider() {
58
- let stored: PersistedSession | null = null;
59
- return {
60
- saveDebounceMs: 0,
61
- save: async (_k: string, snap: PersistedSession) => {
62
- stored = snap;
63
- },
64
- load: async () => stored,
65
- clear: async () => {
66
- stored = null;
67
- },
68
- get current(): PersistedSession | null {
69
- return stored;
70
- },
71
- };
72
- }
73
-
74
- /** The functional store shape the persister reads scalars from / hydrates into. */
75
- function makeStoreFake(over: Record<string, unknown> = {}) {
76
- return {
77
- store: {
78
- aiAssistant: {
79
- messages: [] as ChatMessage[],
80
- flowOwnerAgentName: null as string | null,
81
- flowActivationPrompt: null as string | null,
82
- activeAgent: undefined as { name: string } | undefined,
83
- pinnedAgentName: null as string | null,
84
- // The persister reads `sessionUsage.costUsd` when building a snapshot, so this
85
- // has to be the object rather than a bare cost scalar.
86
- sessionUsage: {
87
- costUsd: 0,
88
- uncachedInputTokens: 0,
89
- cacheReadTokens: 0,
90
- cacheWriteTokens: 0,
91
- outputTokens: 0,
92
- },
93
- contextTokens: 0,
94
- contextLimit: 0,
95
- activeModel: undefined,
96
- activeProviderName: undefined,
97
- restoring: false,
98
- ...over,
99
- },
100
- },
101
- actions: {
102
- aiAssistant: {
103
- loadSession: () => {},
104
- setInputValue: () => {},
105
- },
106
- },
107
- };
108
- }
109
-
110
- function makePersister(driver: unknown, storeFake: unknown, provider: unknown): SessionPersister {
111
- const deps: SessionPersisterDeps = {
112
- stateKey: KEY,
113
- getPersistence: () => ({ enabled: true, provider: provider as never }),
114
- getAgentNames: () => ['Genesis Assistant', 'Planner'],
115
- getDriver: () => driver as never,
116
- getStore: () => storeFake as never,
117
- getDiagnosticEntries: () => [],
118
- };
119
- return new SessionPersister(deps);
120
- }
121
-
122
- const tick = (): Promise<void> =>
123
- new Promise((r) => {
124
- setTimeout(r, 0);
125
- });
126
-
127
- const Suite = createLogicSuite('stateful-restore-e2e');
128
-
129
- Suite.before.each(() => {
130
- clearPersisterRegistry();
131
- clearDiagnosticsCursorRegistry();
132
- });
133
-
134
- Suite(
135
- 'a flow-owned stateful agent survives persist → restore → resume, routing back without re-classifying',
136
- async () => {
137
- const provider = makeMemoryProvider();
138
-
139
- // ── Persist side ────────────────────────────────────────────────────────────
140
- // `stateA` is the Planner's live state bag; `serialize` closes over it, exactly
141
- // like a real stateful agent's machine snapshot.
142
- let stateA: { cursor: number } = { cursor: 0 };
143
- const planner1 = agentCfg({
144
- name: 'Planner',
145
- excludeFromClassifier: true,
146
- onActivate: async ({ restored }) => {
147
- if (restored !== undefined) stateA = restored as { cursor: number };
148
- },
149
- serialize: () => stateA,
150
- systemPrompt: () => 'planner',
151
- });
152
- const driver1 = new OrchestratingDriver(
153
- makeRegistry(noToolProvider()),
154
- [agentCfg({ name: 'Genesis Assistant' }), planner1],
155
- { sessionKey: KEY },
156
- );
157
-
158
- // Flow-owned but NOT pinned, then run a turn: the flow-owner lock routes the
159
- // Planner (it's excludeFromClassifier, so the classifier could never pick it).
160
- driver1.setFlowOwner('Planner');
161
- await driver1.sendMessage('go');
162
- assert.is(
163
- driver1.getActiveAgent()?.name,
164
- 'Planner',
165
- 'flow-owner routed the Planner on persist side',
166
- );
167
-
168
- // The flow advances — mutate the SAME object `serialize()` returns.
169
- stateA.cursor = 3;
170
-
171
- // The store mirrors what main.ts keeps: the flow-owner lock lives in the store
172
- // (that's the scalar `persistSession` reads).
173
- const storeFake1 = makeStoreFake({ flowOwnerAgentName: 'Planner' });
174
- const persister1 = makePersister(driver1, storeFake1, provider);
175
- persister1.scheduleSave();
176
- await tick();
177
- await tick();
178
-
179
- const saved = provider.current;
180
- assert.ok(saved, 'a snapshot was persisted');
181
- assert.is(saved!.flowOwnerAgentName, 'Planner', 'flow-owner lock persisted');
182
- // Bug-#2 assertion: the LIVE (activated) agent's serialize was captured via
183
- // driver.getActiveAgent(), so the advanced state is in the snapshot.
184
- assert.equal(
185
- saved!.agentSnapshots.Planner,
186
- { cursor: 3 },
187
- "live agent's advanced state captured (not a never-activated closure)",
188
- );
189
-
190
- // ── Restore side (fresh instances share the same in-memory provider) ──────────
191
- let stateB: { cursor: number } = { cursor: -1 }; // sentinel; restore must overwrite
192
- const planner2 = agentCfg({
193
- name: 'Planner',
194
- excludeFromClassifier: true,
195
- onActivate: async ({ restored }) => {
196
- if (restored !== undefined) stateB = restored as { cursor: number };
197
- },
198
- serialize: () => stateB,
199
- systemPrompt: () => 'planner',
200
- });
201
- const driver2 = new OrchestratingDriver(
202
- makeRegistry(noToolProvider()),
203
- [agentCfg({ name: 'Genesis Assistant' }), planner2],
204
- { sessionKey: KEY },
205
- );
206
- const storeFake2 = makeStoreFake();
207
- const persister2 = makePersister(driver2, storeFake2, provider);
208
-
209
- await persister2.restore();
210
- // The restored flow-owner lock (setFlowOwner-on-restore) routes the next turn
211
- // back to the Planner without re-classifying.
212
- await driver2.sendMessage('again');
213
-
214
- assert.is(
215
- driver2.getActiveAgent()?.name,
216
- 'Planner',
217
- 'restored flow-owner routed the Planner (excludeFromClassifier + unpinned ⇒ only the restored lock could have)',
218
- );
219
- // primeRestoredAgentState → onActivate({ restored }) fed the snapshot back, so
220
- // the fresh Planner resumed exactly where the persisted one left off.
221
- assert.equal(
222
- stateB,
223
- { cursor: 3 },
224
- 'restored agent re-activated aligned to the persisted state',
225
- );
226
- },
227
- );
228
-
229
- Suite.run();
@@ -1,56 +0,0 @@
1
- import { createStore } from '@genesislcap/foundation-redux';
2
- import {
3
- aiAssistantSlice,
4
- defaultSessionState,
5
- type AiAssistantSessionState,
6
- } from './ai-assistant-slice';
7
-
8
- type SessionStoreReturn = ReturnType<typeof makeStore>;
9
-
10
- const sessionStores = new Map<string, SessionStoreReturn>();
11
-
12
- function makeStore(devTools: boolean | undefined) {
13
- return createStore(
14
- [aiAssistantSlice],
15
- { aiAssistant: defaultSessionState },
16
- devTools !== undefined ? { devTools } : undefined,
17
- );
18
- }
19
-
20
- /**
21
- * Returns the session store for the given key, creating one if it does not
22
- * already exist. Omit `devTools` (or pass `undefined`) to defer to `isDev()`.
23
- * Pass `true` to force-enable or `false` to force-disable Redux DevTools.
24
- */
25
- export function getSessionStore(key: string, devTools?: boolean): SessionStoreReturn {
26
- const existing = sessionStores.get(key);
27
- if (existing) return existing;
28
- const created = makeStore(devTools);
29
- sessionStores.set(key, created);
30
- return created;
31
- }
32
-
33
- /**
34
- * Returns true if a session store already exists for the given key.
35
- */
36
- export function hasSessionStore(key: string): boolean {
37
- return sessionStores.has(key);
38
- }
39
-
40
- /**
41
- * Deletes the session store for the given key.
42
- */
43
- export function deleteSessionStore(key: string): void {
44
- sessionStores.delete(key);
45
- }
46
-
47
- /**
48
- * Removes all session stores. Exposed for test isolation only — not part of the public API.
49
- *
50
- * @internal
51
- */
52
- export function clearAllSessionStores(): void {
53
- sessionStores.clear();
54
- }
55
-
56
- export type { SessionStoreReturn, AiAssistantSessionState };
@@ -1,30 +0,0 @@
1
- /**
2
- * Shared brand colours used across the AI animation effects
3
- * (halo overlay border/glow and loading dot indicators).
4
- * Defined once here so both stay in sync.
5
- */
6
- export const AI_COLOUR_AMBER = '#feb60a';
7
- export const AI_COLOUR_PINK = '#ff0062';
8
- export const AI_COLOUR_CYAN = '#00dbf9';
9
- export const AI_COLOUR_VIOLET = '#da00f7';
10
-
11
- /**
12
- * Pin tint palette, cycled by an agent's position in the assistant's `agents`
13
- * array. Lives here beside the other brand colours because two components need
14
- * it: the composer's agent button tints its pin with the ACTIVE agent's colour,
15
- * and the picker menu tints every row's dot — and those two have to agree, so
16
- * they read the same list and index it the same way.
17
- */
18
- export const PIN_COLOURS = [
19
- AI_COLOUR_AMBER,
20
- AI_COLOUR_PINK,
21
- AI_COLOUR_CYAN,
22
- AI_COLOUR_VIOLET,
23
- ] as const;
24
-
25
- /**
26
- * The tint for the agent at `index` in the full agents array, or `undefined`
27
- * when the index is out of range (an unknown or stale agent name).
28
- */
29
- export const pinColourAt = (index: number): string | undefined =>
30
- index < 0 ? undefined : PIN_COLOURS[index % PIN_COLOURS.length];
@@ -1,187 +0,0 @@
1
- import { css } from '@genesislcap/web-core';
2
-
3
- /**
4
- * The look of a row inside a composer menu — the agent picker and the session
5
- * (⋮) menu.
6
- *
7
- * Shared as a `css` partial rather than written twice because the two menus live
8
- * in DIFFERENT shadow roots: the picker is its own custom element, the session
9
- * menu is rendered by the assistant's own template. Hand-matching them is what
10
- * let them drift apart in the first place, so the rows are defined once here and
11
- * imported by both stylesheets. The *panel* around them (surface, position,
12
- * animation) belongs to the assistant, which renders both — see
13
- * `composerMenuStyles` in `main.styles.ts`.
14
- *
15
- * Expects markup shaped as:
16
- *
17
- * ```html
18
- * <button class="menu-item" role="menuitemradio" aria-checked="true">
19
- * <span class="menu-item-mark"></span>
20
- * <span class="menu-item-body">
21
- * <span class="menu-item-name">Positions</span>
22
- * <span class="menu-item-hint">Read-only position queries</span>
23
- * </span>
24
- * </button>
25
- * ```
26
- *
27
- * `--menu-item-mark` (unset by default) tints the leading dot; a row that sets
28
- * it gets a filled dot in that colour, one that doesn't gets a hollow ring.
29
- *
30
- * An ACTION menu (the session menu) swaps `.menu-item-mark` for
31
- * `.menu-item-icon` in the same leading slot — a dot would imply a selectable
32
- * state the row doesn't have — and marks a destructive row with `.is-danger`.
33
- *
34
- * @internal
35
- */
36
- export const menuItemStyles = css`
37
- .menu-item {
38
- display: flex;
39
- align-items: flex-start;
40
- gap: calc(var(--design-unit) * 2px);
41
- width: 100%;
42
- box-sizing: border-box;
43
- padding: calc(var(--design-unit) * 1.5px) calc(var(--design-unit) * 2px);
44
- border: none;
45
- border-radius: calc(var(--control-corner-radius) * 1px);
46
- background: transparent;
47
- color: var(--neutral-foreground-rest);
48
- font-family: var(--body-font);
49
- font-size: var(--type-ramp-minus-1-font-size, 0.85em);
50
- text-align: start;
51
- cursor: pointer;
52
- }
53
-
54
- .menu-item:hover {
55
- background: var(--neutral-fill-stealth-hover);
56
- }
57
-
58
- .menu-item:focus-visible {
59
- outline: 1px solid var(--focus-stroke-outer);
60
- outline-offset: -1px;
61
- }
62
-
63
- .menu-item[disabled] {
64
- opacity: 45%;
65
- cursor: not-allowed;
66
- }
67
-
68
- .menu-item[disabled]:hover {
69
- background: transparent;
70
- }
71
-
72
- /* The leading slot, shared by both menus so their text columns line up at the
73
- same indent whichever kind of row is in it. Sized for the icon (the larger
74
- of the two occupants) and positioned on the name's first line — a
75
- flex-start row keeps a two-line item's marker beside the name rather than
76
- floating to the vertical middle of the block. */
77
- .menu-item-mark,
78
- .menu-item-icon {
79
- flex: 0 0 12px;
80
- display: flex;
81
- align-items: center;
82
- justify-content: center;
83
- height: 12px;
84
- margin-top: 0.3em;
85
- }
86
-
87
- /* The dot itself, centred in that slot rather than filling it. */
88
- .menu-item-mark::before {
89
- content: '';
90
- width: 8px;
91
- height: 8px;
92
- box-sizing: border-box;
93
- border-radius: 50%;
94
- background: var(--menu-item-mark, transparent);
95
- border: 1px solid var(--menu-item-mark, var(--neutral-stroke-rest));
96
- }
97
-
98
- /* The checked row reads by weight + the filled dot, not by a tick glyph: a
99
- tick would need a column of its own that every other row pays for in
100
- indentation. */
101
- .menu-item[aria-checked='true'] {
102
- background: var(--neutral-fill-stealth-rest);
103
- }
104
-
105
- .menu-item[aria-checked='true'] .menu-item-name {
106
- font-weight: 600;
107
- }
108
-
109
- .menu-item[aria-checked='true'] .menu-item-mark::before {
110
- background: var(--menu-item-mark, var(--accent-fill-rest));
111
- border-color: var(--menu-item-mark, var(--accent-fill-rest));
112
- }
113
-
114
- /* Auto is not one of the agents — it is the absence of a pin, so it reads as a
115
- different KIND of row rather than a first entry in the list. Its marker stays
116
- a ring in every state: a filled dot is what says "this particular agent",
117
- and Auto is precisely the choice not to name one. Selected, the ring picks up
118
- the accent so the state is still legible; unselected it keeps the neutral
119
- stroke every other unselected row has. */
120
- .menu-item.menu-item-auto .menu-item-mark::before {
121
- background: transparent;
122
- border-color: var(--neutral-stroke-rest);
123
- }
124
-
125
- .menu-item.menu-item-auto[aria-checked='true'] .menu-item-mark::before {
126
- background: transparent;
127
- border-color: var(--accent-fill-rest);
128
- }
129
-
130
- /* Kept quieter than a pinned row's fill — the mode is the default, not a
131
- choice the user made and needs reflected back at them. */
132
- .menu-item.menu-item-auto[aria-checked='true'] {
133
- background: var(--neutral-fill-stealth-hover);
134
- }
135
-
136
- /* A rule between Auto and the agents, drawn as its own element so neither row's
137
- hover background has to give up its rounded corners to carry a border. */
138
- .menu-separator {
139
- height: 1px;
140
- margin: calc(var(--design-unit) * 1px) calc(var(--design-unit) * 2px);
141
- background: var(--neutral-stroke-divider-rest);
142
- }
143
-
144
- .menu-item-body {
145
- display: flex;
146
- flex-direction: column;
147
- gap: 1px;
148
- min-width: 0;
149
- }
150
-
151
- .menu-item-name {
152
- /* Long agent names wrap rather than truncate — the menu is the one place
153
- the full name has to be readable, since the composer button truncates it. */
154
- overflow-wrap: anywhere;
155
- }
156
-
157
- .menu-item-hint {
158
- color: var(--neutral-foreground-hint);
159
- font-size: 0.9em;
160
- line-height: 1.35;
161
- }
162
-
163
- /* Action rows put an icon in that slot — a dot would imply a selectable state
164
- the row doesn't have. */
165
- .menu-item-icon {
166
- font-size: 0.9em;
167
- color: var(--neutral-foreground-hint);
168
- }
169
-
170
- .menu-item:hover .menu-item-icon {
171
- color: inherit;
172
- }
173
-
174
- .menu-item.is-danger {
175
- color: var(--error-color);
176
- }
177
-
178
- .menu-item.is-danger .menu-item-icon,
179
- .menu-item.is-danger .menu-item-hint {
180
- color: inherit;
181
- opacity: 80%;
182
- }
183
-
184
- .menu-item.is-danger:hover {
185
- background: color-mix(in srgb, var(--error-color), transparent 88%);
186
- }
187
- `;
@@ -1,40 +0,0 @@
1
- import { css, type ElementStyles } from '@genesislcap/web-core';
2
-
3
- /**
4
- * Heading style for a settings-modal section, published so a host can title its own section.
5
- *
6
- * The assistant renders no heading for the `settings-app` slot — no text and no icon — because
7
- * only the host knows what that section is. The consequence is that a host supplying one has to
8
- * reproduce the styling of the built-in headings beside it, and a copied rule drifts the moment
9
- * either side changes. So the declarations live here, are applied by the assistant's own
10
- * headings, and are exported for the host to apply to its.
11
- *
12
- * Compose it into a component's styles and put `ai-settings-section-title` on the heading:
13
- *
14
- * ```ts
15
- * import { assistantSettingsSectionTitleStyles } from '@genesislcap/ai-assistant';
16
- *
17
- * const styles = css`
18
- * ${assistantSettingsSectionTitleStyles}
19
- * :host { display: block; }
20
- * `;
21
- * ```
22
- *
23
- * Carries no margin on purpose: spacing belongs to the surrounding layout, which differs
24
- * between the assistant's own sections and a slotted one, and is the single declaration hosts
25
- * had to diverge on when they copied this rule.
26
- *
27
- * @beta
28
- */
29
- export const assistantSettingsSectionTitleStyles: ElementStyles = css`
30
- .ai-settings-section-title {
31
- display: flex;
32
- align-items: center;
33
- gap: calc(var(--design-unit) * 2px);
34
- font-size: 11px;
35
- font-weight: 600;
36
- letter-spacing: 0.08em;
37
- text-transform: uppercase;
38
- color: var(--neutral-foreground-hint);
39
- }
40
- `;