@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,642 +0,0 @@
1
- import type {
2
- CachePolicy,
3
- ChatMessage,
4
- ChatThinkingPolicy,
5
- ChatToolChoice,
6
- ChatToolDefinition,
7
- ChatToolHandlers,
8
- } from '@genesislcap/foundation-ai';
9
- import { TOOL_FOLD_SYMBOL } from '../utils/tool-fold';
10
- import type {
11
- AgentConfig,
12
- AgentLifecycleContext,
13
- AgentPersistenceContext,
14
- CachePolicyInput,
15
- ChatInputDuringExecutionMode,
16
- ManualSelectionConfig,
17
- ProviderInput,
18
- SystemPromptContext,
19
- SystemPromptInput,
20
- TailContextInput,
21
- TemperatureInput,
22
- ThinkingPolicyInput,
23
- ToolChoiceInput,
24
- ToolDefinitionsInput,
25
- ToolHandlersInput,
26
- UnresolvedToolContext,
27
- UnresolvedToolInput,
28
- } from './config';
29
-
30
- /**
31
- * Context passed to per-turn resolvers on a stateful agent — the standard
32
- * {@link SystemPromptContext} plus the live `state` value. Used by
33
- * `systemPrompt`, `displayName`, and the function form of `toolDefinitions`.
34
- *
35
- * Exported so consumers can lift resolvers into separate files without
36
- * re-deriving the shape.
37
- *
38
- * @beta
39
- */
40
- export type StatefulAgentContext<S> = SystemPromptContext & { state: S };
41
-
42
- /**
43
- * Context passed to a stateful agent's `resumable` predicate (GENC-1351 §5.9) —
44
- * the standard {@link AgentPersistenceContext} but with `state` as the **live**
45
- * state bag `S` (not the serialized image), so a machine agent can gate on its
46
- * current step directly.
47
- *
48
- * @beta
49
- */
50
- export type StatefulAgentPersistenceContext<S> = Omit<AgentPersistenceContext, 'state'> & {
51
- state: S;
52
- };
53
-
54
- /**
55
- * Init options for {@link defineStatefulAgent}. Generic over the state shape `S`
56
- * the agent owns (a state machine, an observable controller, anything).
57
- *
58
- * The helper threads `state` through `systemPrompt`, `toolDefinitions`, and the
59
- * `toolHandlers` factory so consumer code never has to reach for a closure or
60
- * a module-level mutable.
61
- *
62
- * @beta
63
- */
64
- export interface StatefulAgentInit<S> {
65
- /** Display name — must be unique within the agents array. */
66
- name: string;
67
- /** Plain-language description used by the classifier. Required: stateful agents are always specialists. */
68
- description: string;
69
- /**
70
- * Hide this agent from the classifier — only reachable via manual pinning.
71
- * Stateful agents are always specialists; they cannot be the fallback (a
72
- * fallback is a leaf invoked when no specialist matches, with no flow to
73
- * own state for).
74
- */
75
- excludeFromClassifier?: boolean;
76
- /** Static primer history prepended to every call (not visible to the user). */
77
- primerHistory?: ChatMessage[];
78
- /** Sub-agents available to this agent's tool handlers via `requestSubAgent`. */
79
- subAgents?: AgentConfig[];
80
- /** Opt this agent in to manual picker selection. */
81
- manualSelection?: ManualSelectionConfig;
82
- /** How the main chat input behaves while this agent is executing. */
83
- chatInputDuringExecution?: ChatInputDuringExecutionMode;
84
-
85
- /**
86
- * Construct the agent-scoped state. Called by the framework when this agent
87
- * becomes active (`onActivate`). Awaited before the agent's first turn runs.
88
- *
89
- * On a persisted-session restore, `ctx.restored` carries this agent's previous
90
- * `serialize` output — rebuild from it (e.g. via `restoreMachine`), or start
91
- * fresh when it is `undefined`.
92
- */
93
- init: (ctx: AgentLifecycleContext) => S | Promise<S>;
94
-
95
- /**
96
- * Tear down the agent-scoped state. Called when the agent is being replaced.
97
- * Awaited before the incoming agent's `init` runs.
98
- */
99
- dispose?: (ctx: AgentLifecycleContext & { state: S }) => void | Promise<void>;
100
-
101
- /**
102
- * System prompt composed from current state. Resolved each tool-loop
103
- * iteration. Use this to feed the LLM whatever the current state implies
104
- * (e.g. a state machine's `meta.systemPrompt` plus captured context).
105
- */
106
- systemPrompt?: (ctx: StatefulAgentContext<S>) => string | Promise<string>;
107
-
108
- /**
109
- * Per-turn display label, e.g. "Guided Booking (Counterparties)". Resolved
110
- * each tool-loop iteration and stamped onto outgoing messages and the
111
- * debug-log timeline — display only. The agent's `name` stays as the
112
- * canonical identity used for routing/history filtering.
113
- */
114
- displayName?: (ctx: StatefulAgentContext<S>) => string | Promise<string>;
115
-
116
- /**
117
- * Tool definitions the LLM sees. Either a static array (resolved once) or a
118
- * function resolved each tool-loop iteration. The function form is how a
119
- * machine-driven agent narrows the surface per state.
120
- *
121
- * **Constraint:** the resolved handlers (returned from {@link StatefulAgentInit.toolHandlers})
122
- * must not include fold facades. Folds are an LLM-driven UX optimisation
123
- * that competes with the machine for control of the tool view; one of them
124
- * has to be in charge. Helper throws at init time if a fold-tagged handler
125
- * is detected.
126
- */
127
- toolDefinitions?:
128
- | ChatToolDefinition[]
129
- | ((ctx: StatefulAgentContext<S>) => ChatToolDefinition[] | Promise<ChatToolDefinition[]>);
130
-
131
- /**
132
- * Factory returning the handler map for the **current state**. Called each
133
- * tool-loop iteration with the live `state` value, so the handler set the
134
- * driver dispatches against matches what `toolDefinitions` exposes to the
135
- * LLM that turn. Return only the handlers valid right now — no need to
136
- * advertise every handler the agent might ever expose, and no defensive
137
- * `if (!machine.matches(...))` guards inside each handler.
138
- *
139
- * Pair with the function form of `toolDefinitions` so the visible tools and
140
- * the dispatchable handlers stay in lockstep.
141
- *
142
- * **Constraint:** resolved handlers must not include fold facades. Folds and
143
- * state-machine-driven tool filtering both try to control the LLM's tool
144
- * view — pick one. Helper samples once on activation (init state) and
145
- * throws if a fold-tagged handler is detected; subsequent resolves also
146
- * validate, so misuse on a non-init state surfaces when that state is
147
- * reached.
148
- */
149
- toolHandlers?: (state: S) => ChatToolHandlers | Promise<ChatToolHandlers>;
150
-
151
- /**
152
- * Which registered AI provider this agent uses, by name. Either a static
153
- * string or a function resolved each tool-loop iteration with the current
154
- * `state` — pick the function form to vary provider per machine state
155
- * (e.g. swap to a heavier model only for the planning step).
156
- *
157
- * Omit to use the registry's default provider. Unknown names hard-error.
158
- */
159
- provider?: string | ((ctx: StatefulAgentContext<S>) => string | Promise<string>);
160
-
161
- /**
162
- * Sampling temperature, normalized to `0`–`1`. Either a static number or a
163
- * function resolved each tool-loop iteration with the current `state` — pick
164
- * the function form to vary it per machine state (e.g. low for a precise
165
- * extraction step, higher for free-form drafting). Omit for the default.
166
- */
167
- temperature?: number | ((ctx: StatefulAgentContext<S>) => number | Promise<number>);
168
-
169
- /**
170
- * Tool-call mode. Either a static `ChatToolChoice` or a function
171
- * resolved each tool-loop iteration with the current `state` — pick the
172
- * function form to force a specific tool in one state (e.g. a classifier in
173
- * intake) and leave `'auto'` in states where multi-step work happens. Omit
174
- * for the default.
175
- */
176
- toolChoice?:
177
- | ChatToolChoice
178
- | ((ctx: StatefulAgentContext<S>) => ChatToolChoice | Promise<ChatToolChoice>);
179
-
180
- /**
181
- * Prompt-cache policy. Either a static `CachePolicy` or a function resolved each tool-loop
182
- * iteration with the current `state` — pick the function form to vary it per machine state
183
- * (e.g. `'history'` in a long generating phase, `'default'` in short low-touch ones). Omit to
184
- * request no caching.
185
- */
186
- cachePolicy?:
187
- | CachePolicy
188
- | ((ctx: StatefulAgentContext<S>) => CachePolicy | Promise<CachePolicy>);
189
-
190
- /**
191
- * Extended-thinking posture. Either a static `ChatThinkingPolicy` or a function resolved with
192
- * the current `state` **once per user turn** — the function form is the point of this option on
193
- * a machine agent: `'auto'` in the state that makes a real decision, `'off'` in the states that
194
- * only step a known sequence, where reasoning is billed at the full output rate to re-derive
195
- * what the machine already knows. Omit, or return `undefined` from the function, to keep the
196
- * model's own default for that turn.
197
- *
198
- * Resolved once per turn rather than per tool-loop iteration (unlike `temperature` and
199
- * `toolChoice`): a tool-use loop is one assistant turn and its thinking mode must hold for the
200
- * whole of it. A state transition part-way through a loop therefore takes effect on the next
201
- * user turn, not immediately.
202
- */
203
- thinkingPolicy?:
204
- | ChatThinkingPolicy
205
- | ((
206
- ctx: StatefulAgentContext<S>,
207
- ) => ChatThinkingPolicy | undefined | Promise<ChatThinkingPolicy | undefined>);
208
-
209
- /**
210
- * Volatile per-turn tail context (current file/spec, diagnostics, live state). Either a static
211
- * string or a function resolved each tool-loop iteration with the current `state`. Provide raw
212
- * content; the framework frames it. Omit, or return an empty string, for none.
213
- */
214
- tailContext?: string | ((ctx: StatefulAgentContext<S>) => string | Promise<string>);
215
-
216
- /**
217
- * Hook consulted when the model calls a tool that isn't dispatchable in the
218
- * current state — a *stale* tool (valid in an earlier state of this agent) or
219
- * an *unknown* one. Receives the current `state` alongside the attempted tool
220
- * name and the currently dispatchable tools, so a machine-driven agent can
221
- * return a step-aware redirect (e.g. "that belongs to a later step — finish
222
- * this one first"). Return `undefined` to keep the framework default; a
223
- * pre-init call also degrades to the default rather than throwing.
224
- * See {@link UnresolvedToolContext}.
225
- */
226
- onUnresolvedTool?: (
227
- ctx: UnresolvedToolContext & { state: S },
228
- ) => string | undefined | Promise<string | undefined>;
229
-
230
- /**
231
- * Optional getter for the debug-log snapshot. Defaults to auto-snapshotting
232
- * any property on `state` that looks like a foundation-state-machine
233
- * instance (has `state`, `context`, and `complete` fields). Override when
234
- * the default doesn't capture what you need — e.g. multiple machines, or
235
- * non-machine state worth recording.
236
- *
237
- * Return value must be JSON-serializable.
238
- */
239
- getDebugSnapshot?: (state: S) => unknown;
240
-
241
- /**
242
- * Lossless serializer for session persistence — infra-agnostic. Return any
243
- * JSON/structured-clone-safe image of `state`.
244
- * • Machine agents (`{ machine }`): omit — the default snapshots every
245
- * machine-shaped property via `getPersistedSnapshot()`.
246
- * • Plain-data agents (e.g. `{ plan, cursor }`): omit too — the default
247
- * returns plain state as-is. Provide one only when the state holds
248
- * something the default can't capture.
249
- * Distinct from `getDebugSnapshot` (which may be lossy by design). Pair with
250
- * `init` reading `ctx.restored` to rebuild.
251
- */
252
- serialize?: (state: S) => unknown;
253
-
254
- /**
255
- * Whether the agent's current state is resumable — worth persisting so the
256
- * session restores mid-flow (GENC-1351 §5.9). Receives the **live** state bag
257
- * `S` (like the other per-turn resolvers), so a machine agent gates on its step
258
- * directly: `resumable: ({ state }) => state.machine.state !== 'confirm'`.
259
- * Return `false` for a point that shouldn't resume — the session isn't persisted,
260
- * and on return the assistant shows {@link StatefulAgentInit.notResumableMessage}
261
- * (or a default) and pre-fills the composer with the prompt that started the flow.
262
- * Only consulted with persistence enabled; a thrown error is treated as `true`
263
- * (fail-safe — never drop a resumable chat on a predicate bug).
264
- */
265
- resumable?: (ctx: StatefulAgentPersistenceContext<S>) => boolean | Promise<boolean>;
266
- /**
267
- * Message shown on return when {@link StatefulAgentInit.resumable} returned
268
- * `false`. Falls back to a built-in default when omitted.
269
- */
270
- notResumableMessage?: string;
271
- }
272
-
273
- /**
274
- * Walk a state object and snapshot any machine-shaped values found on it.
275
- * Recognises foundation-state-machine instances by structural shape rather
276
- * than `instanceof`, so the helper stays free of a runtime dep on
277
- * foundation-state-machine.
278
- *
279
- * Strips the `errors`/`error` framework noise from each machine's context —
280
- * these are foundation-state-machine internals (an ErrorMap instance and its
281
- * last-error pointer) that bloat the debug payload without aiding debugging.
282
- */
283
- function defaultStatefulDebugSnapshot(state: unknown): unknown {
284
- if (!state || typeof state !== 'object') return state;
285
- const result: Record<string, unknown> = {};
286
- for (const [key, val] of Object.entries(state as Record<string, unknown>)) {
287
- if (val && typeof val === 'object' && 'state' in val && 'context' in val && 'complete' in val) {
288
- const m = val as {
289
- state: unknown;
290
- context: Record<string, unknown>;
291
- complete: unknown;
292
- output?: unknown;
293
- };
294
- const ctx = m.context ?? {};
295
- const { errors: _e, error: _err, ...userContext } = ctx;
296
- result[key] = {
297
- state: m.state,
298
- context: userContext,
299
- complete: m.complete,
300
- output: m.output,
301
- };
302
- }
303
- }
304
- return Object.keys(result).length
305
- ? result
306
- : '<no auto-snapshot — state has no machine-shaped properties; provide getDebugSnapshot>';
307
- }
308
-
309
- /**
310
- * Build a restore-ready snapshot of agent state. Each property exposing a
311
- * `getPersistedSnapshot()` method (a foundation-state-machine `AbstractMachine`)
312
- * is replaced by its persisted snapshot — the lossless, JSON-safe image
313
- * {@link restoreMachine} feeds back via `start({ state })`. Every other property
314
- * is kept as-is, so plain serializable state (e.g. a planner's `{ plan, cursor }`)
315
- * round-trips directly with no per-agent `serialize`.
316
- *
317
- * Distinct from `defaultStatefulDebugSnapshot`, which abbreviates for the debug
318
- * log and is not guaranteed lossless.
319
- */
320
- function defaultStatefulSerialize(state: unknown): unknown {
321
- if (!state || typeof state !== 'object') return state;
322
- const result: Record<string, unknown> = {};
323
- for (const [key, val] of Object.entries(state as Record<string, unknown>)) {
324
- result[key] =
325
- val &&
326
- typeof val === 'object' &&
327
- typeof (val as { getPersistedSnapshot?: unknown }).getPersistedSnapshot === 'function'
328
- ? (val as { getPersistedSnapshot: () => unknown }).getPersistedSnapshot()
329
- : val;
330
- }
331
- return result;
332
- }
333
-
334
- /**
335
- * Restore a foundation-state-machine instance from a snapshot produced by the
336
- * default serializer (or `machine.getPersistedSnapshot()`). Call inside a
337
- * stateful agent's `init` to resume the machine in its exact prior place:
338
- *
339
- * ```ts
340
- * init: ({ restored }) => {
341
- * const machine = new MyMachine();
342
- * restoreMachine(machine, restored); // resume, or no-op on a fresh start
343
- * return { machine };
344
- * }
345
- * ```
346
- *
347
- * No-ops when there is nothing to restore (a fresh session), leaving the
348
- * freshly-constructed machine in its initial state.
349
- *
350
- * @param machine - the machine to restore (already constructed/started).
351
- * @param restored - the agent's serialized image (`ctx.restored` in `init`).
352
- * @param key - the property the machine occupies in the snapshot; defaults to
353
- * `'machine'` to match the conventional `{ machine }` state bag.
354
- * @beta
355
- */
356
- export function restoreMachine(
357
- machine: { stop: () => void; start: (options?: { state?: unknown }) => void },
358
- restored: unknown,
359
- key = 'machine',
360
- ): void {
361
- const snapshot = (restored as Record<string, unknown> | undefined)?.[key];
362
- if (snapshot === undefined || snapshot === null) {
363
- return;
364
- }
365
- machine.stop();
366
- machine.start({ state: snapshot });
367
- }
368
-
369
- /**
370
- * Build an `AgentConfig` whose `systemPrompt`, `toolDefinitions`, and tool
371
- * handlers all close over a long-lived state object created on activation.
372
- *
373
- * The framework wires the lifecycle: `init` on `onActivate`, `dispose` on
374
- * `onDeactivate`. State is held inside the helper's closure — never exposed on
375
- * the resulting `AgentConfig` — so the redux serializer doesn't see it.
376
- *
377
- * @example
378
- * ```ts
379
- * const guidedBooking = defineStatefulAgent<{ machine: GuidedBookingMachine }>({
380
- * name: 'Guided Booking',
381
- * description: 'Books a trade via a guided wizard.',
382
- * excludeFromClassifier: true,
383
- * manualSelection: { enabled: true, hint: 'Step-by-step trade booking' },
384
- * init: () => ({ machine: new GuidedBookingMachine() }),
385
- * dispose: ({ state }) => state.machine.stop(),
386
- * systemPrompt: ({ state }) => composeFromMachine(state.machine),
387
- * toolDefinitions: ({ state }) => toolsForState(state.machine.state),
388
- * toolHandlers: ({ machine }) => ({ ... }),
389
- * });
390
- * ```
391
- *
392
- * @beta
393
- */
394
- export function defineStatefulAgent<S>(opts: StatefulAgentInit<S>): AgentConfig {
395
- let state: S | undefined;
396
-
397
- const assertNoFolds = (handlers: ChatToolHandlers): void => {
398
- for (const [name, handler] of Object.entries(handlers)) {
399
- if ((handler as any)[TOOL_FOLD_SYMBOL]) {
400
- throw new Error(
401
- `Stateful agent "${opts.name}" tool "${name}" carries fold metadata. ` +
402
- `Folds and state-machine-driven tool filtering both try to control the ` +
403
- `LLM's tool view — pick one. Remove the fold or migrate this agent to ` +
404
- `a non-stateful AgentConfig.`,
405
- );
406
- }
407
- }
408
- };
409
-
410
- // Wrap the optional dynamic-tools factory so it threads `state` in and asserts
411
- // we never accidentally resolved a fold-tagged tool. Static arrays are passed
412
- // through unchanged.
413
- const wrappedTools: ToolDefinitionsInput | undefined = (() => {
414
- const td = opts.toolDefinitions;
415
- if (typeof td === 'function') {
416
- return async (ctx: SystemPromptContext) => {
417
- if (!state) {
418
- throw new Error(`Stateful agent "${opts.name}" tools called before init`);
419
- }
420
- return td({ ...ctx, state });
421
- };
422
- }
423
- return td;
424
- })();
425
-
426
- // Wrap the handler factory into the ctx-shaped form the driver expects, and
427
- // validate folds on each resolve. The driver re-resolves this per tool-loop
428
- // iteration, so the handler set the driver dispatches against always
429
- // matches the LLM-visible tools for the current state — handlers don't need
430
- // defensive `if (!machine.matches(...))` guards.
431
- const wrappedHandlers: ToolHandlersInput | undefined = opts.toolHandlers
432
- ? async () => {
433
- if (!state) {
434
- throw new Error(`Stateful agent "${opts.name}" handlers called before init`);
435
- }
436
- const handlers = await opts.toolHandlers!(state);
437
- assertNoFolds(handlers);
438
- return handlers;
439
- }
440
- : undefined;
441
-
442
- const wrappedDisplayName: SystemPromptInput | undefined = opts.displayName
443
- ? async (ctx: SystemPromptContext) => {
444
- if (!state) {
445
- throw new Error(`Stateful agent "${opts.name}" displayName called before init`);
446
- }
447
- return opts.displayName!({ ...ctx, state });
448
- }
449
- : undefined;
450
-
451
- // Function-form `provider` needs `state` injected the same way the other
452
- // per-turn resolvers do; the static-string form is passed through unchanged
453
- // and validated up-front by OrchestratingDriver.
454
- const wrappedProvider: ProviderInput | undefined =
455
- typeof opts.provider === 'function'
456
- ? async (ctx: SystemPromptContext) => {
457
- if (!state) {
458
- throw new Error(`Stateful agent "${opts.name}" provider called before init`);
459
- }
460
- return (opts.provider as (ctx: StatefulAgentContext<S>) => string | Promise<string>)({
461
- ...ctx,
462
- state,
463
- });
464
- }
465
- : opts.provider;
466
-
467
- // `temperature` and `toolChoice` thread `state` in exactly like `provider`;
468
- // static values pass through unchanged.
469
- const wrappedTemperature: TemperatureInput | undefined =
470
- typeof opts.temperature === 'function'
471
- ? async (ctx: SystemPromptContext) => {
472
- if (!state) {
473
- throw new Error(`Stateful agent "${opts.name}" temperature called before init`);
474
- }
475
- return (opts.temperature as (ctx: StatefulAgentContext<S>) => number | Promise<number>)({
476
- ...ctx,
477
- state,
478
- });
479
- }
480
- : opts.temperature;
481
-
482
- const wrappedToolChoice: ToolChoiceInput | undefined =
483
- typeof opts.toolChoice === 'function'
484
- ? async (ctx: SystemPromptContext) => {
485
- if (!state) {
486
- throw new Error(`Stateful agent "${opts.name}" toolChoice called before init`);
487
- }
488
- return (
489
- opts.toolChoice as (
490
- ctx: StatefulAgentContext<S>,
491
- ) => ChatToolChoice | Promise<ChatToolChoice>
492
- )({ ...ctx, state });
493
- }
494
- : opts.toolChoice;
495
-
496
- const wrappedCachePolicy: CachePolicyInput | undefined =
497
- typeof opts.cachePolicy === 'function'
498
- ? async (ctx: SystemPromptContext) => {
499
- if (!state) {
500
- throw new Error(`Stateful agent "${opts.name}" cachePolicy called before init`);
501
- }
502
- return (
503
- opts.cachePolicy as (ctx: StatefulAgentContext<S>) => CachePolicy | Promise<CachePolicy>
504
- )({ ...ctx, state });
505
- }
506
- : opts.cachePolicy;
507
-
508
- // Unlike the resolvers above, a pre-init call returns `undefined` rather than throwing: that is
509
- // this option's "model default" state, so degrading to it costs a turn its thinking preference
510
- // instead of breaking the turn outright.
511
- const wrappedThinkingPolicy: ThinkingPolicyInput | undefined =
512
- typeof opts.thinkingPolicy === 'function'
513
- ? async (ctx: SystemPromptContext) => {
514
- if (!state) return undefined;
515
- return (
516
- opts.thinkingPolicy as (
517
- ctx: StatefulAgentContext<S>,
518
- ) => ChatThinkingPolicy | undefined | Promise<ChatThinkingPolicy | undefined>
519
- )({ ...ctx, state });
520
- }
521
- : opts.thinkingPolicy;
522
-
523
- const wrappedTailContext: TailContextInput | undefined =
524
- typeof opts.tailContext === 'function'
525
- ? async (ctx: SystemPromptContext) => {
526
- if (!state) {
527
- throw new Error(`Stateful agent "${opts.name}" tailContext called before init`);
528
- }
529
- return (opts.tailContext as (ctx: StatefulAgentContext<S>) => string | Promise<string>)({
530
- ...ctx,
531
- state,
532
- });
533
- }
534
- : opts.tailContext;
535
-
536
- // `onUnresolvedTool` threads `state` in like the resolvers above, but unlike
537
- // them returns `undefined` before init rather than throwing: it fires on the
538
- // tool-dispatch path, so a pre-init call must degrade to the framework
539
- // default instead of breaking dispatch.
540
- const wrappedOnUnresolvedTool: UnresolvedToolInput | undefined =
541
- typeof opts.onUnresolvedTool === 'function'
542
- ? async (ctx) => {
543
- if (!state) {
544
- return undefined;
545
- }
546
- return opts.onUnresolvedTool!({ ...ctx, state });
547
- }
548
- : opts.onUnresolvedTool;
549
-
550
- // `resumable` threads the LIVE state bag in (like the resolvers above) rather
551
- // than the serialized image the raw `AgentConfig` form receives — so a machine
552
- // agent gates on `state.machine.state` directly. Consulted only while active
553
- // (state is set); a pre-init call degrades to `true` (resumable, fail-safe).
554
- const wrappedResumable: AgentConfig['resumable'] | undefined = opts.resumable
555
- ? async (ctx: AgentPersistenceContext): Promise<boolean> => {
556
- if (state === undefined) return true;
557
- return opts.resumable!({
558
- agentName: ctx.agentName,
559
- sessionKey: ctx.sessionKey,
560
- messages: ctx.messages,
561
- isFlowOwner: ctx.isFlowOwner,
562
- state,
563
- });
564
- }
565
- : undefined;
566
-
567
- const base = {
568
- name: opts.name,
569
- displayName: wrappedDisplayName,
570
- primerHistory: opts.primerHistory,
571
- subAgents: opts.subAgents,
572
- manualSelection: opts.manualSelection,
573
- chatInputDuringExecution: opts.chatInputDuringExecution,
574
- toolDefinitions: wrappedTools,
575
- toolHandlers: wrappedHandlers,
576
- provider: wrappedProvider,
577
- temperature: wrappedTemperature,
578
- toolChoice: wrappedToolChoice,
579
- cachePolicy: wrappedCachePolicy,
580
- thinkingPolicy: wrappedThinkingPolicy,
581
- tailContext: wrappedTailContext,
582
- onUnresolvedTool: wrappedOnUnresolvedTool,
583
- resumable: wrappedResumable,
584
- notResumableMessage: opts.notResumableMessage,
585
-
586
- onActivate: async (ctx: AgentLifecycleContext) => {
587
- state = await opts.init(ctx);
588
- // Sample once with the init state to fail loud on fold misuse at the
589
- // agent-switch boundary instead of waiting for the first tool call.
590
- // The driver re-resolves the factory each iteration, so misuse on
591
- // handlers gated behind a non-init state surfaces when that state is
592
- // reached — same loud failure mode, narrower coverage.
593
- if (opts.toolHandlers) {
594
- const sampled = await opts.toolHandlers(state);
595
- assertNoFolds(sampled);
596
- }
597
- },
598
-
599
- onDeactivate: async (ctx: AgentLifecycleContext) => {
600
- if (state !== undefined && opts.dispose) {
601
- await opts.dispose({ ...ctx, state });
602
- }
603
- // Orchestrator serializes onActivate/onDeactivate; concurrent calls
604
- // cannot interleave the read-then-write of `state`.
605
- // eslint-disable-next-line require-atomic-updates
606
- state = undefined;
607
- },
608
-
609
- systemPrompt: opts.systemPrompt
610
- ? async (ctx: SystemPromptContext) => {
611
- if (!state) {
612
- throw new Error(`Stateful agent "${opts.name}" systemPrompt called before init`);
613
- }
614
- return opts.systemPrompt!({ ...ctx, state });
615
- }
616
- : undefined,
617
-
618
- // Called per LLM call by ChatDriver, and once at debug-log export time.
619
- // Returns `undefined` before activation (state hasn't been built yet) and
620
- // after deactivation (state was disposed) — the snapshotter is best-effort
621
- // and the driver tolerates undefined.
622
- getDebugSnapshot: () => {
623
- if (!state) return undefined;
624
- return opts.getDebugSnapshot
625
- ? opts.getDebugSnapshot(state)
626
- : defaultStatefulDebugSnapshot(state);
627
- },
628
-
629
- // Lossless restore image for session persistence (see `serialize` on the
630
- // config). Returns undefined before activation / after disposal.
631
- serialize: () => {
632
- if (state === undefined) return undefined;
633
- return opts.serialize ? opts.serialize(state) : defaultStatefulSerialize(state);
634
- },
635
- };
636
-
637
- return {
638
- ...base,
639
- description: opts.description,
640
- excludeFromClassifier: opts.excludeFromClassifier,
641
- } as AgentConfig;
642
- }
@@ -1,29 +0,0 @@
1
- import type { FallbackAgentConfig } from './config';
2
-
3
- /**
4
- * A warm, conversational fallback agent. Acknowledges it can't help directly,
5
- * explains what the available specialists can do, and invites the user to retry.
6
- *
7
- * The system prompt is generated at runtime by `OrchestratingDriver` from the
8
- * specialist list — no manual authoring required.
9
- *
10
- * @beta
11
- */
12
- export const friendlyFallbackAgent: FallbackAgentConfig = {
13
- name: 'Assistant',
14
- fallback: true,
15
- systemPrompt: `You are a warm, friendly assistant. For general conversation like "Hi" or "How are you", you can have a friendly chat. For anything more complex, you cannot directly help, but you can explain what specialists are available. The available specialists are:\n\n{{agents}}\n\nPolitely let the user know what you can help with and invite them to rephrase their request if it is outside your scope.`,
16
- };
17
-
18
- /**
19
- * A brief, professional fallback agent. States what is available without
20
- * elaboration. The `{{agents}}` placeholder is replaced at runtime by
21
- * `OrchestratingDriver` with the generated specialist list.
22
- *
23
- * @beta
24
- */
25
- export const strictFallbackAgent: FallbackAgentConfig = {
26
- name: 'Assistant',
27
- fallback: true,
28
- systemPrompt: `You are a concise assistant. The user's request is outside your scope. Respond with a single short sentence stating what you can assist with. Do not elaborate. The available specialists are: {{agents}}.`,
29
- };
@@ -1,2 +0,0 @@
1
- export * from './config';
2
- export * from './fallback-agents';