@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,79 +0,0 @@
1
- import type { AiDriver } from '../components/ai-driver/ai-driver';
2
-
3
- /**
4
- * Module-level registry of AI drivers keyed by session identity string.
5
- *
6
- * Driver lifetime is tied to the conversation session, not the DOM.
7
- * Components look up or create drivers on connect and only unwire
8
- * event listeners on disconnect — the driver is never destroyed by
9
- * a lifecycle event.
10
- *
11
- * @internal
12
- */
13
- interface DriverRegistryEntry {
14
- driver: AiDriver;
15
- /**
16
- * Fingerprint (see `FoundationAiAssistant.getAgentsKey`) of the agents array
17
- * the driver was built for. Lets a second component sharing the same session
18
- * key recognise that the registry driver already matches its desired agents
19
- * and ADOPT it, instead of tearing it down and recreating — which would evict
20
- * the sibling's driver and orphan whichever element is mid-turn on it
21
- * (GENC-1388).
22
- */
23
- agentsKey: string;
24
- }
25
-
26
- const driverRegistry = new Map<string, DriverRegistryEntry>();
27
-
28
- /**
29
- * Returns the existing driver for the given key, or calls the factory to create
30
- * and register a new one. `agentsKey` is the fingerprint of the agents the
31
- * driver is being built for; it is recorded only when a driver is created (a
32
- * reused driver keeps the fingerprint it was originally built with).
33
- */
34
- export function getOrCreateDriver(
35
- key: string,
36
- agentsKey: string,
37
- factory: () => AiDriver,
38
- ): AiDriver {
39
- const existing = driverRegistry.get(key);
40
- if (existing) return existing.driver;
41
- const driver = factory();
42
- driverRegistry.set(key, { driver, agentsKey });
43
- return driver;
44
- }
45
-
46
- /**
47
- * Returns the existing driver for the given key, or `undefined`.
48
- */
49
- export function getDriver(key: string): AiDriver | undefined {
50
- return driverRegistry.get(key)?.driver;
51
- }
52
-
53
- /**
54
- * The agents fingerprint the registry driver for `key` was built with, or
55
- * `undefined` if no driver is registered. Used by `agentsChanged` to decide
56
- * whether a sibling has already rebuilt the shared driver to the desired agents.
57
- */
58
- export function getDriverAgentsKey(key: string): string | undefined {
59
- return driverRegistry.get(key)?.agentsKey;
60
- }
61
-
62
- /**
63
- * Removes and returns the driver for the given key.
64
- * Used when agents change (driver must be rebuilt) or on explicit session teardown.
65
- */
66
- export function deleteDriver(key: string): AiDriver | undefined {
67
- const entry = driverRegistry.get(key);
68
- driverRegistry.delete(key);
69
- return entry?.driver;
70
- }
71
-
72
- /**
73
- * Removes all entries. Exposed for test isolation only — not part of the public API.
74
- *
75
- * @internal
76
- */
77
- export function clearDriverRegistry(): void {
78
- driverRegistry.clear();
79
- }
@@ -1,90 +0,0 @@
1
- import { assert, createLogicSuite } from '@genesislcap/foundation-testing';
2
- import { createInteractionContext } from './interaction-context';
3
-
4
- const suite = createLogicSuite('interaction-context factory');
5
-
6
- suite('once runs the factory a single time and memoises the result', () => {
7
- const { context } = createInteractionContext('id-1');
8
- let calls = 0;
9
- const first = context.once('ws', () => {
10
- calls += 1;
11
- return { socket: true };
12
- });
13
- const second = context.once('ws', () => {
14
- calls += 1;
15
- return { socket: false };
16
- });
17
- assert.is(calls, 1, 'factory ran once');
18
- assert.is(second, first, 'the memoised value is returned on the second call');
19
- });
20
-
21
- suite('subscribe/notify fans out to listeners; unsubscribe stops them', () => {
22
- const { context } = createInteractionContext('id-2');
23
- let a = 0;
24
- let b = 0;
25
- const unsubA = context.subscribe(() => (a += 1));
26
- context.subscribe(() => (b += 1));
27
-
28
- context.notify();
29
- assert.is(a, 1);
30
- assert.is(b, 1);
31
-
32
- unsubA();
33
- context.notify();
34
- assert.is(a, 1, 'unsubscribed listener no longer fires');
35
- assert.is(b, 2, 'remaining listener still fires');
36
- });
37
-
38
- suite('a throwing subscriber does not stop the others', () => {
39
- const { context } = createInteractionContext('id-3');
40
- let reached = false;
41
- context.subscribe(() => {
42
- throw new Error('boom');
43
- });
44
- context.subscribe(() => (reached = true));
45
- context.notify();
46
- assert.ok(reached, 'later subscriber still ran after an earlier one threw');
47
- });
48
-
49
- suite('dispose runs every onDispose callback once, then is idempotent', () => {
50
- const { context, dispose } = createInteractionContext('id-4');
51
- let count = 0;
52
- context.onDispose(() => (count += 1));
53
- context.onDispose(() => (count += 1));
54
-
55
- dispose();
56
- assert.is(count, 2, 'both disposers ran');
57
- dispose();
58
- assert.is(count, 2, 'a second dispose is a no-op');
59
- });
60
-
61
- suite('onDispose registered after dispose runs immediately', () => {
62
- const { context, dispose } = createInteractionContext('id-5');
63
- dispose();
64
- let ran = false;
65
- context.onDispose(() => (ran = true));
66
- assert.ok(ran, 'late onDispose runs immediately so no resource leaks');
67
- });
68
-
69
- suite('notify after dispose is a no-op (listeners cleared)', () => {
70
- const { context, dispose } = createInteractionContext('id-6');
71
- let fired = 0;
72
- context.subscribe(() => (fired += 1));
73
- dispose();
74
- context.notify();
75
- assert.is(fired, 0, 'no listeners fire after dispose');
76
- });
77
-
78
- suite('once after dispose returns null without running the factory', () => {
79
- const { context, dispose } = createInteractionContext('id-7');
80
- dispose();
81
- let calls = 0;
82
- const result = context.once('late', () => {
83
- calls += 1;
84
- return { socket: true };
85
- });
86
- assert.is(calls, 0, 'the factory never ran on an ended interaction (no leaked resource)');
87
- assert.is(result, null, 'once returns null after dispose');
88
- });
89
-
90
- suite.run();
@@ -1,101 +0,0 @@
1
- import type { InteractionContext } from '../types/interaction-context';
2
- import { logger } from '../utils/logger';
3
-
4
- /**
5
- * A created {@link InteractionContext} plus the host-only `dispose` handle. The
6
- * driver keeps the handle (so it can tear the context down on resolve/evict) and
7
- * hands only `context` to the widget — widgets must not dispose their own context.
8
- *
9
- * @internal
10
- */
11
- export interface InteractionContextHandle {
12
- readonly context: InteractionContext;
13
- /**
14
- * Run every registered `onDispose` callback once (in registration order), then
15
- * clear listeners. Idempotent. Called by the driver from `resolveInteraction`
16
- * and on driver teardown — never on element unmount.
17
- */
18
- dispose(): void;
19
- }
20
-
21
- /**
22
- * Create a live, per-interaction context (GENC-1390). Framework-agnostic: the
23
- * `subscribe`/`notify` pair is a plain observer set, not FAST reactivity. See
24
- * {@link InteractionContext} for the lifetime/semantics contract.
25
- *
26
- * @internal
27
- */
28
- export function createInteractionContext(interactionId: string): InteractionContextHandle {
29
- const state: Record<string, unknown> = {};
30
- const onceCache = new Map<string, unknown>();
31
- const listeners = new Set<() => void>();
32
- const disposers = new Set<() => void>();
33
- let disposed = false;
34
-
35
- const context: InteractionContext = {
36
- interactionId,
37
- state,
38
- once<T>(key: string, factory: () => T): T | null {
39
- if (onceCache.has(key)) return onceCache.get(key) as T;
40
- // Interaction already ended (resolve/timeout/evict): refuse to run the factory.
41
- // A resource created here would leak — dispose has already run every `onDispose`
42
- // and won't run again. Return null so a stray late call (e.g. an async callback
43
- // that lands after a `timeoutMs` timeout) degrades instead of crashing or leaking.
44
- if (disposed) {
45
- logger.warn(
46
- `InteractionContext.once("${key}") called after dispose; not creating a resource on an ended interaction.`,
47
- );
48
- return null;
49
- }
50
- const value = factory();
51
- onceCache.set(key, value);
52
- return value;
53
- },
54
- notify(): void {
55
- // A Set tolerates a listener unsubscribing mid-walk (matches
56
- // interaction-panel-session's forEach); a throwing subscriber must not stop the rest.
57
- for (const listener of listeners) {
58
- try {
59
- listener();
60
- } catch (e) {
61
- logger.error('InteractionContext subscriber threw during notify()', e);
62
- }
63
- }
64
- },
65
- subscribe(listener: () => void): () => void {
66
- listeners.add(listener);
67
- return () => {
68
- listeners.delete(listener);
69
- };
70
- },
71
- onDispose(fn: () => void): void {
72
- // Late registration after the interaction already ended: run immediately so
73
- // callers never leak a resource by registering a beat too late.
74
- if (disposed) {
75
- fn();
76
- return;
77
- }
78
- disposers.add(fn);
79
- },
80
- };
81
-
82
- return {
83
- context,
84
- dispose(): void {
85
- if (disposed) return;
86
- disposed = true;
87
- for (const fn of disposers) {
88
- try {
89
- fn();
90
- } catch (e) {
91
- logger.error('InteractionContext onDispose callback threw', e);
92
- }
93
- }
94
- disposers.clear();
95
- listeners.clear();
96
- // Release memoised `once` values (sockets, timers, service handles) for GC — the resources
97
- // themselves are closed via their `onDispose`, but drop the references too.
98
- onceCache.clear();
99
- },
100
- };
101
- }
@@ -1,66 +0,0 @@
1
- /**
2
- * Shared, pure builder for the debug-log timeline entries (`message` / `turn` / `event`) — the
3
- * common core of the host element's `buildDiagnosticEntries` and any HEADLESS consumer that drives
4
- * a `ChatDriver` of its own (e.g. `ai-service` running the engine server-side) and needs to harvest
5
- * that engine's debug log for the client to fold into its own download / persisted stream
6
- * (GENC-1461 unified diagnostics). DOM-clean and dependency-light so it works in bare Node.
7
- *
8
- * It deliberately excludes the `meta-snapshot` entry: that block is host/DOM-specific (it reads
9
- * `window.location.host`, the element's agent list, live context/cost), and a merged log keeps only
10
- * the newest snapshot anyway — a headless source's agent/prompt/tools are already captured in its
11
- * `turn` entries.
12
- *
13
- * @packageDocumentation
14
- */
15
-
16
- import type { ChatMessage } from '@genesislcap/foundation-ai';
17
- import { flattenSubAgentMessages } from '../../utils/flatten-sub-agent-messages';
18
- import type { MetaEvent } from '../debug-event-log';
19
- import type { DiagnosticEntry } from './diagnostics';
20
-
21
- /**
22
- * The minimal shape this builder reads off a turn snapshot. The driver's full `TurnSnapshot` is a
23
- * structural superset, so it assigns to this without the builder depending on the component layer.
24
- */
25
- export interface TurnSnapshotLike {
26
- turnIndex: string;
27
- systemPrompt?: string;
28
- }
29
-
30
- /**
31
- * Build the `message` / `turn` / `event` timeline entries from a driver's pull surfaces
32
- * (`getRawHistory()` / `getTurnSnapshots()` / `getMetaEvents(sessionKey)`). Order within the array
33
- * is message → turn → event; the caller (`assembleDebugLog`) sorts the whole timeline by timestamp,
34
- * so this ordering only sets the co-timestamp tie-break. Pure.
35
- */
36
- export function buildTimelineEntries(input: {
37
- turnSnapshots: readonly TurnSnapshotLike[];
38
- messages: readonly ChatMessage[];
39
- metaEvents: readonly MetaEvent[];
40
- }): DiagnosticEntry[] {
41
- const { turnSnapshots, messages, metaEvents } = input;
42
-
43
- // Collapse a turn's systemPrompt when byte-identical to the previous turn's — a stable agent
44
- // repeats the same (often multi-KB) prompt every turn, while a stateful agent's changes. The
45
- // prompt is shown in full whenever it changes, so prompt evolution stays visible.
46
- let lastFullPrompt: string | undefined;
47
- let lastFullIndex = '';
48
- const turns = turnSnapshots.map((t) => {
49
- let { systemPrompt } = t;
50
- if (systemPrompt != null && systemPrompt === lastFullPrompt) {
51
- systemPrompt = `<repeated — identical to turn ${lastFullIndex}>`;
52
- } else if (systemPrompt != null) {
53
- lastFullPrompt = systemPrompt;
54
- lastFullIndex = t.turnIndex;
55
- }
56
- return { kind: 'turn' as const, ...t, systemPrompt };
57
- });
58
-
59
- // Sub-agent conversations are stored nested on the parent tool call's `subAgentTrace`;
60
- // `flattenSubAgentMessages` hoists them to top-level `kind: 'message'` entries (breadcrumbed +
61
- // correlated, the nested copy moved out — not duplicated) so the timeline reads chronologically.
62
- const messageEntries = flattenSubAgentMessages(messages);
63
- const eventEntries = metaEvents.map((e) => ({ kind: 'event' as const, ...e }));
64
-
65
- return [...messageEntries, ...turns, ...eventEntries] as DiagnosticEntry[];
66
- }
@@ -1,53 +0,0 @@
1
- import { assert, createLogicSuite } from '@genesislcap/foundation-testing';
2
- import {
3
- clearDiagnosticsCursorRegistry,
4
- deleteDiagnosticsCursorsFor,
5
- getDiagnosticsCursors,
6
- resetDiagnosticsCursorsFor,
7
- } from './diagnostics-cursors';
8
-
9
- // GENC-1351 §5.8/§5.12 (#9): the forward-capture cursors, and the crucial difference
10
- // between the Clear reset (keep the event high-water) and the in-place-switch delete
11
- // (fresh cursors, because the meta-event buffer is torn down and its indices restart).
12
-
13
- const KEY = 'session-1';
14
-
15
- const Suite = createLogicSuite('diagnostics-cursors');
16
-
17
- Suite.before.each(() => {
18
- clearDiagnosticsCursorRegistry();
19
- });
20
-
21
- Suite('resetDiagnosticsCursorsFor KEEPS lastEventIndex (Clear: meta buffer keeps climbing)', () => {
22
- const c = getDiagnosticsCursors(KEY);
23
- c.lastEventIndex = 40;
24
- c.emittedMsgKeys.add('m');
25
- c.restoredMsgKeys.add('r');
26
- resetDiagnosticsCursorsFor(KEY);
27
- const after = getDiagnosticsCursors(KEY);
28
- assert.is(
29
- after.lastEventIndex,
30
- 40,
31
- 'event high-water kept — Clear does not reset the meta buffer',
32
- );
33
- assert.is(after.emittedMsgKeys.size, 0, 'per-conversation message cursors restarted');
34
- assert.is(after.restoredMsgKeys.size, 0, 'restore watermark restarted');
35
- });
36
-
37
- Suite(
38
- 'deleteDiagnosticsCursorsFor RESETS lastEventIndex (switch: meta buffer restarts at 0)',
39
- () => {
40
- const c = getDiagnosticsCursors(KEY);
41
- c.lastEventIndex = 40;
42
- deleteDiagnosticsCursorsFor(KEY);
43
- // A later return re-creates fresh cursors on first access.
44
- const after = getDiagnosticsCursors(KEY);
45
- assert.is(
46
- after.lastEventIndex,
47
- -1,
48
- 'fresh cursor — a returning session whose events restart at 0 is NOT skipped',
49
- );
50
- },
51
- );
52
-
53
- Suite.run();
@@ -1,80 +0,0 @@
1
- /**
2
- * Per-session forward-capture cursors for the server-saved diagnostics stream
3
- * (GENC-1351 §5.8). Module-level and keyed by the session `stateKey` — exactly like
4
- * the meta-event buffer — so the (up to two) element instances that share one
5
- * session (a collapsed bubble + a popped-out panel) share ONE set of cursors.
6
- *
7
- * Without this each instance keeps its own cursors and both independently append
8
- * the shared driver's activity, double-writing the stream — and, worse, the second
9
- * instance (which never runs restore, so its message watermark stays empty)
10
- * re-appends the *entire* restored history on every reload. Module state dies with
11
- * the JS realm, so these reset for free on a real page reload (like the meta
12
- * buffer), which is exactly the "fresh capture per page load" behaviour we want.
13
- *
14
- * @internal
15
- */
16
- export interface DiagnosticsCursors {
17
- /** Message identities present at restore — never appended (they live in a prior load's stream). */
18
- restoredMsgKeys: Set<string>;
19
- /** Message identities already appended this load. */
20
- emittedMsgKeys: Set<string>;
21
- /** Turn indices already appended this load. */
22
- emittedTurnKeys: Set<string>;
23
- /** Highest meta-event index already appended. */
24
- lastEventIndex: number;
25
- /** JSON of the last meta-snapshot appended — skip re-appending an unchanged block. */
26
- lastMetaJson: string;
27
- }
28
-
29
- const cursorsByKey = new Map<string, DiagnosticsCursors>();
30
-
31
- const freshCursors = (): DiagnosticsCursors => ({
32
- restoredMsgKeys: new Set(),
33
- emittedMsgKeys: new Set(),
34
- emittedTurnKeys: new Set(),
35
- lastEventIndex: -1,
36
- lastMetaJson: '',
37
- });
38
-
39
- /** The shared cursors for `key`, created (empty) on first access. @internal */
40
- export function getDiagnosticsCursors(key: string): DiagnosticsCursors {
41
- let cursors = cursorsByKey.get(key);
42
- if (!cursors) {
43
- cursors = freshCursors();
44
- cursorsByKey.set(key, cursors);
45
- }
46
- return cursors;
47
- }
48
-
49
- /**
50
- * Restart the per-conversation cursors for `key` on Clear — a new conversation in
51
- * the same page load. `lastEventIndex` is intentionally kept: Clear does NOT reset
52
- * the meta-event buffer, so its indices keep climbing and mustn't be re-emitted.
53
- *
54
- * @internal
55
- */
56
- export function resetDiagnosticsCursorsFor(key: string): void {
57
- const cursors = getDiagnosticsCursors(key);
58
- cursors.restoredMsgKeys = new Set();
59
- cursors.emittedMsgKeys = new Set();
60
- cursors.emittedTurnKeys = new Set();
61
- }
62
-
63
- /**
64
- * Drop the cursors for `key` entirely — the in-place session switch teardown
65
- * (GENC-1351 §5.12). Unlike {@link resetDiagnosticsCursorsFor}, this does NOT keep
66
- * `lastEventIndex`: a switch also tears down the session's meta-event buffer (its
67
- * indices restart at 0 on a later return), so a kept high-water index would skip
68
- * every event of the resumed session. A return re-creates fresh cursors on first
69
- * access.
70
- *
71
- * @internal
72
- */
73
- export function deleteDiagnosticsCursorsFor(key: string): void {
74
- cursorsByKey.delete(key);
75
- }
76
-
77
- /** Drop all cursors — test isolation only. @internal */
78
- export function clearDiagnosticsCursorRegistry(): void {
79
- cursorsByKey.clear();
80
- }