@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,608 +0,0 @@
1
- import type {
2
- CachePolicy,
3
- ChatFallback,
4
- ChatInputDuringExecutionMode,
5
- ChatMessage,
6
- ChatThinkingPolicy,
7
- ChatToolChoice,
8
- ChatToolDefinition,
9
- ChatToolHandlers,
10
- } from '@genesislcap/foundation-ai';
11
-
12
- export type {
13
- CachePolicy,
14
- ChatFallback,
15
- ChatInputDuringExecutionMode,
16
- ChatThinkingPolicy,
17
- ChatToolChoice,
18
- };
19
-
20
- /**
21
- * Context passed to `onActivate` / `onDeactivate` lifecycle hooks on an agent.
22
- *
23
- * @beta
24
- */
25
- export interface AgentLifecycleContext {
26
- /** The agent the hook is firing for. */
27
- agentName: string;
28
- /** The assistant session key — stable across reloads, unique per assistant instance. */
29
- sessionKey: string;
30
- /** The agent that was active immediately before this one, if any. Only set on `onActivate`. */
31
- previousAgentName?: string;
32
- /** Aborted if the session disconnects mid-activation. */
33
- signal: AbortSignal;
34
- /**
35
- * A previously-serialized state image for this agent (from the agent's
36
- * `serialize`), passed only on `onActivate` when resuming a persisted
37
- * session. A stateful
38
- * agent's `init` rebuilds from it — e.g. via `restoreMachine` — or starts
39
- * fresh when it is `undefined`.
40
- */
41
- restored?: unknown;
42
- }
43
-
44
- /**
45
- * Context passed to an agent's `resumable` predicate (GENC-1351 §5.9), evaluated
46
- * at session-save time on the active agent (which, for a locked guided flow, is
47
- * the flow-owner).
48
- *
49
- * @beta
50
- */
51
- export interface AgentPersistenceContext {
52
- /** The agent being consulted. */
53
- agentName: string;
54
- /** The assistant session key — stable across reloads. */
55
- sessionKey: string;
56
- /**
57
- * This agent's just-serialized state image — the value its `serialize()`
58
- * returned for this save (or the carried-forward image). Inspect the machine
59
- * step here. Derive the decision from this (not live closure state): the
60
- * predicate must be a pure function of the state so a resumable snapshot stays
61
- * resumable when re-evaluated on restore.
62
- */
63
- state: unknown;
64
- /** Full conversation transcript at save time. */
65
- messages: ReadonlyArray<ChatMessage>;
66
- /** True when this agent currently owns the guided flow (`name === flowOwnerAgentName`). */
67
- isFlowOwner: boolean;
68
- }
69
-
70
- /**
71
- * Context passed to the function form of `systemPrompt` / `toolDefinitions`.
72
- * Resolved each tool-loop iteration so the agent can vary what the LLM sees per turn.
73
- *
74
- * @beta
75
- */
76
- export interface SystemPromptContext {
77
- /** The active agent's name. */
78
- agentName: string;
79
- /** Full conversation history up to (but not including) the message being processed. */
80
- history: ReadonlyArray<ChatMessage>;
81
- /** 0 = first LLM call this turn; > 0 = retry or subsequent tool-loop iteration. */
82
- turnIndex: number;
83
- /** Aborted if the turn is cancelled. */
84
- signal: AbortSignal;
85
- }
86
-
87
- /**
88
- * System prompt for an agent. Either a static string (resolved once) or a function
89
- * resolved each tool-loop iteration. The function form lets the agent compute the
90
- * prompt from external state — e.g. a state machine's current step.
91
- *
92
- * @beta
93
- */
94
- export type SystemPromptInput = string | ((ctx: SystemPromptContext) => string | Promise<string>);
95
-
96
- /**
97
- * Tool definitions for an agent. Either a static array (the conventional shape) or
98
- * a function resolved each tool-loop iteration. The function form lets the agent
99
- * narrow the tool surface per turn — e.g. expose only the tools valid in the
100
- * current state of a state machine.
101
- *
102
- * @beta
103
- */
104
- export type ToolDefinitionsInput =
105
- | ChatToolDefinition[]
106
- | ((ctx: SystemPromptContext) => ChatToolDefinition[] | Promise<ChatToolDefinition[]>);
107
-
108
- /**
109
- * Tool handlers for an agent. Either a static map (the conventional shape) or a
110
- * function resolved each tool-loop iteration. The function form lets the agent
111
- * narrow the dispatchable handler set per turn — pair it with the function form
112
- * of `toolDefinitions` so the LLM-visible tools and the dispatchable handlers
113
- * stay in lockstep, and handlers don't have to defend themselves against being
114
- * dispatched in states where their tool isn't advertised.
115
- *
116
- * @beta
117
- */
118
- export type ToolHandlersInput =
119
- | ChatToolHandlers
120
- | ((ctx: SystemPromptContext) => ChatToolHandlers | Promise<ChatToolHandlers>);
121
-
122
- /**
123
- * Names which registered `AIProviderRegistry` entry an agent uses. Either
124
- * a static string (resolved once at agent registration) or a function resolved
125
- * each tool-loop iteration — pick the function form to vary the provider by
126
- * current state (e.g. a stateful agent that switches providers between
127
- * machine states).
128
- *
129
- * Unknown provider names hard-error: static names at agent registration time,
130
- * function-resolved names on first resolution.
131
- *
132
- * @beta
133
- */
134
- export type ProviderInput = string | ((ctx: SystemPromptContext) => string | Promise<string>);
135
-
136
- /**
137
- * Sampling temperature for an agent, normalized to `0`–`1` (`0` = deterministic,
138
- * `1` = the most random the active provider allows). Either a static number
139
- * (resolved once) or a function resolved each tool-loop iteration — pick the
140
- * function form to vary it by current state (e.g. a lower temperature for a
141
- * precise extraction step, higher for brainstorming). Each transport translates
142
- * the normalized value into its own native range. Omit to use the
143
- * provider/model default. See `ChatRequestOptions.temperature`.
144
- *
145
- * @beta
146
- */
147
- export type TemperatureInput = number | ((ctx: SystemPromptContext) => number | Promise<number>);
148
-
149
- /**
150
- * Tool-call mode for an agent. Either a static `ChatToolChoice` (resolved
151
- * once) or a function resolved each tool-loop iteration — pick the function form
152
- * to vary it by current state (e.g. force a classifier tool in an intake step,
153
- * then `'auto'` everywhere multi-step work happens). Omit to use the default
154
- * (`'auto'`, except sub-agent turns which force `'required'`).
155
- *
156
- * @beta
157
- */
158
- export type ToolChoiceInput =
159
- | ChatToolChoice
160
- | ((ctx: SystemPromptContext) => ChatToolChoice | Promise<ChatToolChoice>);
161
-
162
- /**
163
- * Prompt-cache policy for an agent. Either a static `CachePolicy` (resolved once) or a
164
- * function resolved each tool-loop iteration — pick the function form to vary it by current state
165
- * (e.g. cache `'history'` in a long generating phase, `'default'` in short low-touch ones). Omit
166
- * to request no caching. Resolved and applied the same way as {@link TemperatureInput}.
167
- *
168
- * @beta
169
- */
170
- export type CachePolicyInput =
171
- | CachePolicy
172
- | ((ctx: SystemPromptContext) => CachePolicy | Promise<CachePolicy>);
173
-
174
- /**
175
- * Extended-thinking posture for an agent — whether the model reasons before answering. Either a
176
- * static `ChatThinkingPolicy` or a function resolved **once per user turn**, at the start of the
177
- * tool loop. Pick the function form to vary it by current state: reason in the state that makes a
178
- * real decision, and drop it in states that only step a known sequence, where reasoning bills at
179
- * the full output rate to re-derive what the state machine already knows.
180
- *
181
- * Note the resolution point, which differs from every other per-turn input here: a tool-use loop
182
- * is a single assistant turn and its thinking mode must hold for the whole of it, so this resolver
183
- * is consulted on the first model call of a turn and its answer reused for the rest. A resolver
184
- * that returns a different value part-way through a loop will not see it applied until the next
185
- * user turn.
186
- *
187
- * **Omit — or return `undefined` from the function — to keep the model's own default**, which is
188
- * a distinct third state rather than a synonym for either value: Sonnet 5 and Fable 5 think by
189
- * default, the rest do not. So an agent that leaves this unset, or a resolver that answers
190
- * `undefined` on some turns, behaves and prices exactly as it did before this option existed.
191
- *
192
- * A request, not a guarantee — transports clamp what a model cannot honour (Fable 5 and Gemini
193
- * 2.5 Pro always think) and warn once instead of failing the turn. Resolved and applied the same
194
- * way as {@link TemperatureInput}. See `ChatThinkingPolicy`.
195
- *
196
- * @beta
197
- */
198
- export type ThinkingPolicyInput =
199
- | ChatThinkingPolicy
200
- | ((
201
- ctx: SystemPromptContext,
202
- ) => ChatThinkingPolicy | undefined | Promise<ChatThinkingPolicy | undefined>);
203
-
204
- /**
205
- * Per-turn tail context for an agent — volatile content (current file/spec, diagnostics, live
206
- * state) injected at the tail of every model-call so the model sees it without invalidating the
207
- * cached prefix. Either a static string or a function resolved each tool-loop iteration. **Provide
208
- * raw content** — the framework frames it (wraps it in a `<system-reminder>` marker) so the model
209
- * reads it as ambient context, not user input. Omit, or return an empty string, for none.
210
- *
211
- * @beta
212
- */
213
- export type TailContextInput = string | ((ctx: SystemPromptContext) => string | Promise<string>);
214
-
215
- /**
216
- * Structured-output schema for an agent. When set, the model's final (non-tool) answer is
217
- * constrained to this JSON Schema instead of free text. Either a static schema or a function
218
- * resolved each tool-loop iteration — return the schema on the turn(s) it should apply and
219
- * `undefined` otherwise, so "whole-loop" vs "finalize-turn" enforcement is just what the
220
- * resolver returns (e.g. `({ state }) => state.machine.matches('finalizing') ? schema : undefined`).
221
- *
222
- * Orthogonal to {@link ToolChoiceInput}: an agent can carry both `tools` and a `responseSchema`.
223
- * Each provider applies it natively where possible (Anthropic `output_config.format`, Gemini
224
- * JSON mode) and degrades gracefully otherwise. The schema is a plain JSON Schema object; keep to
225
- * the portable subset providers share (`additionalProperties: false`, explicit `required`, enums,
226
- * `anyOf` for nullables — no numeric/string constraints or recursion).
227
- *
228
- * @beta
229
- */
230
- export type ResponseSchemaInput =
231
- | object
232
- | ((ctx: SystemPromptContext) => object | undefined | Promise<object | undefined>);
233
-
234
- /**
235
- * Context passed to an agent's `onUnresolvedTool` hook when the model calls a
236
- * tool the driver cannot dispatch.
237
- *
238
- * @beta
239
- */
240
- export interface UnresolvedToolContext {
241
- /** The tool name the model attempted to call. */
242
- toolName: string;
243
- /**
244
- * Why the call could not be dispatched:
245
- * - `'stale'` — the tool was advertised earlier this activation but is not
246
- * part of the current step (e.g. a stateful agent has moved on).
247
- * - `'unknown'` — the tool was never advertised this activation (a
248
- * hallucinated name).
249
- */
250
- kind: 'stale' | 'unknown';
251
- /**
252
- * The tool names dispatchable right now, so the hook can steer the model
253
- * back to a valid call.
254
- */
255
- availableTools: string[];
256
- }
257
-
258
- /**
259
- * Optional per-agent hook consulted only on the already-failing unresolved-tool
260
- * path — when the model calls a tool the driver cannot dispatch. Lets the agent
261
- * replace the framework's default message with a context-aware redirect.
262
- *
263
- * Return a non-empty string to override the default tool-result message; return
264
- * `undefined` (or an empty/whitespace string, or throw) to fall back to the
265
- * framework default. The happy path is never affected. See
266
- * {@link UnresolvedToolContext}.
267
- *
268
- * @beta
269
- */
270
- export type UnresolvedToolInput = (
271
- ctx: UnresolvedToolContext,
272
- ) => string | undefined | Promise<string | undefined>;
273
-
274
- /**
275
- * Opts an agent in to manual selection from the assistant's agent picker.
276
- *
277
- * Only applies to top-level agents — sub-agents are never user-selectable.
278
- * Has no effect unless the assistant's `agentPicker` is also enabled.
279
- *
280
- * @beta
281
- */
282
- export interface ManualSelectionConfig {
283
- /**
284
- * Whether this agent appears in the picker.
285
- */
286
- enabled: boolean;
287
- /**
288
- * Optional short description shown as a tooltip on the picker entry, and as
289
- * a secondary line in the dropdown variant.
290
- */
291
- hint?: string;
292
- }
293
-
294
- interface BaseAgentConfig {
295
- /**
296
- * Stable identity for this agent. Used for classifier routing, manual
297
- * pinning, and history filtering — must not vary per turn. For a per-turn
298
- * display label (e.g. "Guided Booking (Counterparties)"), supply
299
- * {@link BaseAgentConfig.displayName}.
300
- */
301
- name: string;
302
- /**
303
- * Optional per-turn display label. Resolved each tool-loop iteration and
304
- * stamped onto outgoing messages (`agentLabel`) and the debug-log timeline.
305
- * Renderers fall back to `name` when this is unset. Use the function form
306
- * to vary the label by current state (e.g. a state machine's step).
307
- *
308
- * Identity stays on `name` — this is for UX only.
309
- */
310
- displayName?: SystemPromptInput;
311
- /**
312
- * System prompt injected into every conversation turn for this agent.
313
- *
314
- * Either a string (resolved once) or a function resolved each tool-loop
315
- * iteration — pick the function form when the prompt depends on per-turn state
316
- * (e.g. a state machine's current step). See {@link SystemPromptInput}.
317
- */
318
- systemPrompt?: SystemPromptInput;
319
- /**
320
- * Tool definitions (JSON Schema) passed to the AI provider for this agent.
321
- *
322
- * Either a static array or a function resolved each tool-loop iteration —
323
- * pick the function form to narrow the tool surface per turn (e.g. expose
324
- * only the tools valid in the current state of a state machine).
325
- * See {@link ToolDefinitionsInput}.
326
- */
327
- toolDefinitions?: ToolDefinitionsInput;
328
- /**
329
- * Tool handler implementations for this agent.
330
- *
331
- * Either a static map or a function resolved each tool-loop iteration —
332
- * pick the function form to narrow the dispatchable handler set per turn,
333
- * matching the function form of `toolDefinitions`.
334
- * See {@link ToolHandlersInput}.
335
- */
336
- toolHandlers?: ToolHandlersInput;
337
- /**
338
- * Which registered AI provider this agent uses, by name. Either a static
339
- * string (resolved once at agent registration) or a function resolved each
340
- * tool-loop iteration — pick the function form to vary the provider by
341
- * current state (e.g. a stateful agent that switches providers between
342
- * machine states).
343
- *
344
- * Omit to use the registry's default provider. Unknown names hard-error:
345
- * static names at registration time, function-resolved names on first
346
- * resolution.
347
- *
348
- * Known limitation: switching provider mid-conversation can blow the
349
- * smaller provider's context window if history accumulated under a
350
- * larger one. No automatic trimming is performed.
351
- *
352
- * @beta
353
- */
354
- provider?: ProviderInput;
355
- /**
356
- * Sampling temperature for this agent, normalized to `0`–`1`. Either a static
357
- * number or a function resolved each tool-loop iteration — pick the function
358
- * form to vary it by current state. Omit to use the provider/model default.
359
- * Resolved and applied the same way as {@link BaseAgentConfig.provider}.
360
- * See {@link TemperatureInput}.
361
- *
362
- * @beta
363
- */
364
- temperature?: TemperatureInput;
365
- /**
366
- * Tool-call mode for this agent — whether the model may, must, or must not
367
- * call a tool this turn (and optionally which one). Either a static value or
368
- * a function resolved each tool-loop iteration — pick the function form to
369
- * vary it by current state (e.g. force a single tool at a known juncture).
370
- * Omit to use the default (`'auto'`, except sub-agent turns which force
371
- * `'required'`). See {@link ToolChoiceInput}.
372
- *
373
- * @beta
374
- */
375
- toolChoice?: ToolChoiceInput;
376
- /**
377
- * Prompt-cache policy for this agent — whether to emit cache breakpoints and how far up the
378
- * prefix. Either a static value or a function resolved each tool-loop iteration (vary by state).
379
- * Resolved and applied the same way as {@link BaseAgentConfig.temperature}. Omit to request no
380
- * caching. Provider-neutral — see {@link CachePolicyInput} / `CachePolicy` for the
381
- * Anthropic-vs-Gemini behaviour. See {@link CachePolicyInput}.
382
- *
383
- * @beta
384
- */
385
- cachePolicy?: CachePolicyInput;
386
- /**
387
- * Extended-thinking posture for this agent — whether the model reasons before answering. Either
388
- * a static value or a function resolved **once per user turn** and held for that turn's whole
389
- * tool loop (vary by state: `'auto'` where the turn is a genuine decision, `'off'` where it only
390
- * steps a known sequence and reasoning is billed at the full output rate for no benefit). Omit —
391
- * or return `undefined` — to keep the model's own default, which is neither `'auto'` nor `'off'`
392
- * uniformly. Provider-neutral; transports clamp models that cannot honour it.
393
- * See {@link ThinkingPolicyInput}.
394
- *
395
- * @beta
396
- */
397
- thinkingPolicy?: ThinkingPolicyInput;
398
- /**
399
- * Volatile per-turn context injected at the tail of every model-call (after the history and any
400
- * cache breakpoint), so it is seen each turn without busting the cached prefix — the place to put
401
- * the changing parts (current file/spec, diagnostics, live state) that would otherwise
402
- * destabilize a cached system prompt. Provide *raw* content; the framework frames it (wraps it in
403
- * a `<system-reminder>` marker). Resolved per turn like {@link BaseAgentConfig.temperature}. See
404
- * {@link TailContextInput}.
405
- *
406
- * @beta
407
- */
408
- tailContext?: TailContextInput;
409
- /**
410
- * Structured-output schema for this agent. When resolved to a schema on a turn, the model's
411
- * final (non-tool) answer is constrained to it instead of free text. Composes with `tools`;
412
- * resolved per turn like {@link BaseAgentConfig.cachePolicy}, so returning `undefined` on
413
- * working turns and the schema on the finalize turn gives finalize-turn enforcement for free.
414
- * See {@link ResponseSchemaInput}.
415
- *
416
- * @beta
417
- */
418
- responseSchema?: ResponseSchemaInput;
419
- /**
420
- * Refusal-fallback chain for this agent (provider-neutral). If the model declines a turn
421
- * (`stop_reason: 'refusal'` — e.g. Fable 5 safety classifiers), the provider re-runs it on the
422
- * next listed model. Typical use: a Fable 5 agent with `[{ model: 'claude-opus-4-8' }]`. Static
423
- * (not per-turn); providers that support it apply it server-side, others ignore it.
424
- *
425
- * @beta
426
- */
427
- fallbacks?: ChatFallback[];
428
- /**
429
- * Optional hook consulted when the model calls a tool the driver cannot
430
- * dispatch — either a *stale* tool (advertised earlier this activation but
431
- * not part of the current step) or an *unknown* one (never advertised this
432
- * activation). Return a context-aware redirect string to replace the
433
- * framework's default message, or `undefined` to keep it. Consulted only on
434
- * the already-failing unresolved-tool path; the happy path is unaffected.
435
- * See {@link UnresolvedToolInput}.
436
- *
437
- * @beta
438
- */
439
- onUnresolvedTool?: UnresolvedToolInput;
440
- /**
441
- * Optional primer history prepended to every call (not visible to the user).
442
- * Used to establish agent identity and behavioural rules.
443
- */
444
- primerHistory?: ChatMessage[];
445
- /**
446
- * Sub-agents available to this agent's tool handlers via `requestSubAgent`.
447
- */
448
- subAgents?: AgentConfig[];
449
- /**
450
- * How the main chat input area behaves while this agent is executing.
451
- * Defaults to `'disabled'`. See {@link ChatInputDuringExecutionMode}.
452
- */
453
- chatInputDuringExecution?: ChatInputDuringExecutionMode;
454
- /**
455
- * Opts this agent in to manual selection from the assistant's agent picker.
456
- * Has no effect on sub-agents or when the assistant's `agentPicker` is
457
- * disabled. See {@link ManualSelectionConfig}.
458
- */
459
- manualSelection?: ManualSelectionConfig;
460
- /**
461
- * Fires when this agent becomes the active specialist (including being pinned).
462
- * Use to instantiate per-agent state that should outlive a single turn — e.g.
463
- * a state machine the agent owns across the conversation. Awaited before the
464
- * agent's first turn runs.
465
- *
466
- * Capture dependencies (services, redux store refs, etc.) via closure on the
467
- * host element rather than expecting them on the context.
468
- *
469
- * @beta
470
- */
471
- onActivate?: (ctx: AgentLifecycleContext) => void | Promise<void>;
472
- /**
473
- * Fires when this agent is being deactivated (the user switches to another
474
- * agent, the session is torn down, or the agent is unpinned and replaced).
475
- * Use to dispose per-agent state created in `onActivate`. Awaited before the
476
- * incoming agent's `onActivate` runs.
477
- *
478
- * @beta
479
- */
480
- onDeactivate?: (ctx: AgentLifecycleContext) => void | Promise<void>;
481
- /**
482
- * Returns an agent-supplied debug payload for the export log. Called once per
483
- * LLM call by the driver (alongside the resolved prompt and tool list) and
484
- * once at log-export time for the latest snapshot. Stateful agents should
485
- * return their machine state and captured context so the exported timeline
486
- * captures what drove each turn.
487
- *
488
- * Return value must be JSON-serializable. {@link defineStatefulAgent} wires a
489
- * sensible default that snapshots any machine-shaped state automatically.
490
- *
491
- * @beta
492
- */
493
- getDebugSnapshot?: () => unknown;
494
- /**
495
- * Returns a lossless, JSON-serializable image of the agent's state for session
496
- * persistence — distinct from `getDebugSnapshot`, which may abbreviate for
497
- * readability. Pass the value back to the agent on restore (as
498
- * `ctx.restored` in its `init`) to resume. {@link defineStatefulAgent} wires a
499
- * default that snapshots any machine-shaped state via `getPersistedSnapshot()`
500
- * and returns plain state as-is.
501
- *
502
- * @beta
503
- */
504
- serialize?: () => unknown;
505
- /**
506
- * Whether the agent's current state is resumable — i.e. worth persisting so the
507
- * session can be restored mid-flow (GENC-1351 §5.9). Consulted at save time on
508
- * the active agent (the flow-owner during a locked flow). Return `true`
509
- * (or leave the field absent) to persist and resume normally; return `false`
510
- * for a point that shouldn't be resumed — the session is not persisted, and on
511
- * return the assistant shows {@link AgentConfig.notResumableMessage} (or a
512
- * default) and pre-fills the composer with the prompt that started the flow so
513
- * the user can re-run it.
514
- *
515
- * Only consulted when the user has persistence enabled. Must be a **pure
516
- * function of `ctx.state`** — it may be re-evaluated on a restored snapshot, so
517
- * a resumable state must stay resumable. A thrown error is treated as `true`
518
- * (fail-safe: never drop a resumable chat on a predicate bug).
519
- *
520
- * @beta
521
- */
522
- resumable?: (ctx: AgentPersistenceContext) => boolean | Promise<boolean>;
523
- /**
524
- * Message shown on return when {@link AgentConfig.resumable} returned `false`
525
- * and the user comes back to a non-resumable session (GENC-1351 §5.9). Falls
526
- * back to a built-in default when omitted.
527
- *
528
- * @beta
529
- */
530
- notResumableMessage?: string;
531
- }
532
-
533
- /**
534
- * Configuration for a specialist agent.
535
- *
536
- * Specialist agents are offered to the classifier for intent routing. The
537
- * `description` is used to auto-generate the classifier prompt — no manual
538
- * routing prompt authoring required.
539
- *
540
- * @beta
541
- */
542
- export interface SpecialistAgentConfig extends BaseAgentConfig {
543
- /**
544
- * Plain-language description of what this agent handles.
545
- * Used by the classifier to auto-generate its routing prompt.
546
- */
547
- description: string;
548
- fallback?: never;
549
- /**
550
- * When `true`, the classifier never auto-routes to this agent. The user can
551
- * still select it manually via the picker, provided both prerequisites are
552
- * met: this agent has `manualSelection.enabled` set to `true`, *and* the
553
- * assistant has the picker enabled via `chatConfig.picker.mode`.
554
- *
555
- * Use this for agents that overlap heavily with a sibling (e.g. a guided
556
- * wizard sitting next to a free-form agent in the same domain) and should
557
- * only be reached intentionally rather than via classifier routing.
558
- *
559
- * @beta
560
- */
561
- excludeFromClassifier?: boolean;
562
- }
563
-
564
- /**
565
- * Configuration for a fallback agent.
566
- *
567
- * Invoked when the classifier returns no match. Excluded from the classifier
568
- * prompt. Only one fallback is permitted per agents array.
569
- *
570
- * @beta
571
- */
572
- export interface FallbackAgentConfig extends BaseAgentConfig {
573
- /**
574
- * Marks this agent as the fallback for unrecognised requests.
575
- */
576
- fallback: true;
577
- description?: never;
578
- }
579
-
580
- /**
581
- * Configuration for an agent passed to `FoundationAiAssistant`.
582
- *
583
- * Either a specialist (requires `description`) or a fallback (requires
584
- * `fallback: true`). Passing both or neither is a compile error.
585
- *
586
- * @beta
587
- */
588
- export type AgentConfig = SpecialistAgentConfig | FallbackAgentConfig;
589
-
590
- /**
591
- * Identity helper that infers the narrowest possible type for an agent config,
592
- * preserving string literal types (including `name`) without requiring `as const`.
593
- *
594
- * Use this when you need `typeof myAgent` to carry the literal `name` type —
595
- * for example, when wiring `ChatToolHandlers<typeof myAgent>`.
596
- *
597
- * ```ts
598
- * const myAgent = defineAgent({ name: 'my_agent', ... });
599
- * type Handlers = ChatToolHandlers<typeof myAgent>;
600
- * // requestSubAgent name param is now typed as 'my_agent'
601
- * ```
602
- *
603
- * @beta
604
- */
605
-
606
- export function defineAgent<const T extends AgentConfig>(config: T): T {
607
- return config;
608
- }
@@ -1,64 +0,0 @@
1
- import { assert, createLogicSuite } from '@genesislcap/foundation-testing';
2
- import type { AgentLifecycleContext } from './config';
3
- import { defineStatefulAgent } from './define-stateful-agent';
4
-
5
- // A minimal lifecycle context — `onActivate`/`onDeactivate` only read what the
6
- // helper passes through, so the agent name, session key, and a live signal are
7
- // enough to drive init/dispose in a Node-runnable test.
8
- const lifecycleCtx = (): AgentLifecycleContext => ({
9
- agentName: 'wizard',
10
- sessionKey: 'test-session',
11
- signal: new AbortController().signal,
12
- });
13
-
14
- const onUnresolvedTool = createLogicSuite('defineStatefulAgent onUnresolvedTool');
15
-
16
- onUnresolvedTool('threads the live state into the hook after init', async () => {
17
- const config = defineStatefulAgent<{ step: string }>({
18
- name: 'wizard',
19
- description: 'guided wizard',
20
- init: () => ({ step: 'intake' }),
21
- onUnresolvedTool: ({ state, toolName, kind, availableTools }) =>
22
- `step=${state.step} tool=${toolName} kind=${kind} avail=${availableTools.join(',')}`,
23
- });
24
-
25
- await config.onActivate!(lifecycleCtx());
26
-
27
- const result = await config.onUnresolvedTool!({
28
- toolName: 'generate_view',
29
- kind: 'stale',
30
- availableTools: ['ask_user', 'validate'],
31
- });
32
- assert.is(result, 'step=intake tool=generate_view kind=stale avail=ask_user,validate');
33
- });
34
-
35
- onUnresolvedTool('returns undefined before init rather than throwing', async () => {
36
- const config = defineStatefulAgent<{ step: string }>({
37
- name: 'wizard',
38
- description: 'guided wizard',
39
- init: () => ({ step: 'intake' }),
40
- // Would throw if it were ever reached without state — proves the wrapper
41
- // short-circuits before delegating.
42
- onUnresolvedTool: ({ state }) => `step=${state.step}`,
43
- });
44
-
45
- // No `onActivate` call — state has not been built yet.
46
- const result = await config.onUnresolvedTool!({
47
- toolName: 'generate_view',
48
- kind: 'unknown',
49
- availableTools: [],
50
- });
51
- assert.is(result, undefined, 'a pre-init call must degrade to the framework default');
52
- });
53
-
54
- onUnresolvedTool('omits the hook from the config when not supplied', () => {
55
- const config = defineStatefulAgent<{ step: string }>({
56
- name: 'wizard',
57
- description: 'guided wizard',
58
- init: () => ({ step: 'intake' }),
59
- });
60
-
61
- assert.is(config.onUnresolvedTool, undefined);
62
- });
63
-
64
- onUnresolvedTool.run();