@falai/agent 2.6.1 → 2.7.0

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 (320) hide show
  1. package/README.md +1 -1
  2. package/dist/adapters/MemoryAdapter.js +29 -33
  3. package/dist/adapters/MemoryAdapter.js.map +1 -1
  4. package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  5. package/dist/adapters/PostgreSQLAdapter.js +16 -11
  6. package/dist/adapters/PostgreSQLAdapter.js.map +1 -1
  7. package/dist/adapters/RedisAdapter.d.ts +1 -0
  8. package/dist/adapters/RedisAdapter.d.ts.map +1 -1
  9. package/dist/adapters/RedisAdapter.js +75 -25
  10. package/dist/adapters/RedisAdapter.js.map +1 -1
  11. package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
  12. package/dist/adapters/SQLiteAdapter.js +7 -29
  13. package/dist/adapters/SQLiteAdapter.js.map +1 -1
  14. package/dist/adapters/sessionRow.d.ts +22 -0
  15. package/dist/adapters/sessionRow.d.ts.map +1 -0
  16. package/dist/adapters/sessionRow.js +48 -0
  17. package/dist/adapters/sessionRow.js.map +1 -0
  18. package/dist/cjs/adapters/MemoryAdapter.js +29 -33
  19. package/dist/cjs/adapters/MemoryAdapter.js.map +1 -1
  20. package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  21. package/dist/cjs/adapters/PostgreSQLAdapter.js +16 -11
  22. package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -1
  23. package/dist/cjs/adapters/RedisAdapter.d.ts +1 -0
  24. package/dist/cjs/adapters/RedisAdapter.d.ts.map +1 -1
  25. package/dist/cjs/adapters/RedisAdapter.js +75 -25
  26. package/dist/cjs/adapters/RedisAdapter.js.map +1 -1
  27. package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
  28. package/dist/cjs/adapters/SQLiteAdapter.js +7 -29
  29. package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -1
  30. package/dist/cjs/adapters/sessionRow.d.ts +22 -0
  31. package/dist/cjs/adapters/sessionRow.d.ts.map +1 -0
  32. package/dist/cjs/adapters/sessionRow.js +52 -0
  33. package/dist/cjs/adapters/sessionRow.js.map +1 -0
  34. package/dist/cjs/core/Agent.d.ts +8 -0
  35. package/dist/cjs/core/Agent.d.ts.map +1 -1
  36. package/dist/cjs/core/Agent.js +40 -2
  37. package/dist/cjs/core/Agent.js.map +1 -1
  38. package/dist/cjs/core/AutoChainExecutor.d.ts +8 -18
  39. package/dist/cjs/core/AutoChainExecutor.d.ts.map +1 -1
  40. package/dist/cjs/core/AutoChainExecutor.js +23 -26
  41. package/dist/cjs/core/AutoChainExecutor.js.map +1 -1
  42. package/dist/cjs/core/CompactionEngine.d.ts +14 -1
  43. package/dist/cjs/core/CompactionEngine.d.ts.map +1 -1
  44. package/dist/cjs/core/CompactionEngine.js +30 -6
  45. package/dist/cjs/core/CompactionEngine.js.map +1 -1
  46. package/dist/cjs/core/FlowRouter.d.ts.map +1 -1
  47. package/dist/cjs/core/FlowRouter.js +32 -10
  48. package/dist/cjs/core/FlowRouter.js.map +1 -1
  49. package/dist/cjs/core/ResponseGenerationError.d.ts.map +1 -1
  50. package/dist/cjs/core/ResponseGenerationError.js +3 -5
  51. package/dist/cjs/core/ResponseGenerationError.js.map +1 -1
  52. package/dist/cjs/core/ResponseModal.d.ts +29 -0
  53. package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
  54. package/dist/cjs/core/ResponseModal.js +141 -18
  55. package/dist/cjs/core/ResponseModal.js.map +1 -1
  56. package/dist/cjs/core/ResponsePipeline.d.ts +36 -6
  57. package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -1
  58. package/dist/cjs/core/ResponsePipeline.js +208 -73
  59. package/dist/cjs/core/ResponsePipeline.js.map +1 -1
  60. package/dist/cjs/core/SessionFinalizer.d.ts.map +1 -1
  61. package/dist/cjs/core/SessionFinalizer.js +30 -3
  62. package/dist/cjs/core/SessionFinalizer.js.map +1 -1
  63. package/dist/cjs/core/SessionManager.d.ts +10 -1
  64. package/dist/cjs/core/SessionManager.d.ts.map +1 -1
  65. package/dist/cjs/core/SessionManager.js +43 -16
  66. package/dist/cjs/core/SessionManager.js.map +1 -1
  67. package/dist/cjs/core/SignalProcessor.d.ts.map +1 -1
  68. package/dist/cjs/core/SignalProcessor.js +5 -77
  69. package/dist/cjs/core/SignalProcessor.js.map +1 -1
  70. package/dist/cjs/core/Step.d.ts.map +1 -1
  71. package/dist/cjs/core/Step.js +50 -2
  72. package/dist/cjs/core/Step.js.map +1 -1
  73. package/dist/cjs/core/StepLifecycle.d.ts +16 -6
  74. package/dist/cjs/core/StepLifecycle.d.ts.map +1 -1
  75. package/dist/cjs/core/StepLifecycle.js +97 -14
  76. package/dist/cjs/core/StepLifecycle.js.map +1 -1
  77. package/dist/cjs/core/StreamingToolExecutor.d.ts.map +1 -1
  78. package/dist/cjs/core/StreamingToolExecutor.js +28 -4
  79. package/dist/cjs/core/StreamingToolExecutor.js.map +1 -1
  80. package/dist/cjs/core/ToolLoopExecutor.d.ts +5 -1
  81. package/dist/cjs/core/ToolLoopExecutor.d.ts.map +1 -1
  82. package/dist/cjs/core/ToolLoopExecutor.js +155 -63
  83. package/dist/cjs/core/ToolLoopExecutor.js.map +1 -1
  84. package/dist/cjs/core/ToolManager.d.ts +1 -1
  85. package/dist/cjs/core/ToolManager.d.ts.map +1 -1
  86. package/dist/cjs/core/ToolManager.js +40 -17
  87. package/dist/cjs/core/ToolManager.js.map +1 -1
  88. package/dist/cjs/core/flow-namespace.d.ts +15 -0
  89. package/dist/cjs/core/flow-namespace.d.ts.map +1 -1
  90. package/dist/cjs/core/flow-namespace.js +22 -0
  91. package/dist/cjs/core/flow-namespace.js.map +1 -1
  92. package/dist/cjs/index.d.ts +4 -1
  93. package/dist/cjs/index.d.ts.map +1 -1
  94. package/dist/cjs/index.js +5 -2
  95. package/dist/cjs/index.js.map +1 -1
  96. package/dist/cjs/providers/AnthropicProvider.d.ts +10 -3
  97. package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
  98. package/dist/cjs/providers/AnthropicProvider.js +54 -73
  99. package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
  100. package/dist/cjs/providers/GeminiProvider.d.ts +9 -3
  101. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  102. package/dist/cjs/providers/GeminiProvider.js +24 -68
  103. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  104. package/dist/cjs/providers/OpenAICompatibleProvider.d.ts +9 -0
  105. package/dist/cjs/providers/OpenAICompatibleProvider.d.ts.map +1 -1
  106. package/dist/cjs/providers/OpenAICompatibleProvider.js +101 -74
  107. package/dist/cjs/providers/OpenAICompatibleProvider.js.map +1 -1
  108. package/dist/cjs/providers/OpenAIProvider.d.ts +1 -1
  109. package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
  110. package/dist/cjs/providers/OpenAIProvider.js +1 -1
  111. package/dist/cjs/providers/errorClassification.d.ts +7 -0
  112. package/dist/cjs/providers/errorClassification.d.ts.map +1 -1
  113. package/dist/cjs/providers/errorClassification.js +27 -0
  114. package/dist/cjs/providers/errorClassification.js.map +1 -1
  115. package/dist/cjs/types/agent.d.ts +26 -0
  116. package/dist/cjs/types/agent.d.ts.map +1 -1
  117. package/dist/cjs/types/flow.d.ts +49 -32
  118. package/dist/cjs/types/flow.d.ts.map +1 -1
  119. package/dist/cjs/types/index.d.ts +1 -1
  120. package/dist/cjs/types/index.d.ts.map +1 -1
  121. package/dist/cjs/types/index.js.map +1 -1
  122. package/dist/cjs/types/tool.d.ts +2 -0
  123. package/dist/cjs/types/tool.d.ts.map +1 -1
  124. package/dist/cjs/types/tool.js.map +1 -1
  125. package/dist/cjs/utils/index.d.ts +4 -4
  126. package/dist/cjs/utils/index.d.ts.map +1 -1
  127. package/dist/cjs/utils/index.js +10 -1
  128. package/dist/cjs/utils/index.js.map +1 -1
  129. package/dist/cjs/utils/retry.d.ts +99 -1
  130. package/dist/cjs/utils/retry.d.ts.map +1 -1
  131. package/dist/cjs/utils/retry.js +140 -3
  132. package/dist/cjs/utils/retry.js.map +1 -1
  133. package/dist/cjs/utils/serialize.d.ts +17 -0
  134. package/dist/cjs/utils/serialize.d.ts.map +1 -1
  135. package/dist/cjs/utils/serialize.js +33 -0
  136. package/dist/cjs/utils/serialize.js.map +1 -1
  137. package/dist/cjs/utils/session.d.ts +21 -1
  138. package/dist/cjs/utils/session.d.ts.map +1 -1
  139. package/dist/cjs/utils/session.js +36 -4
  140. package/dist/cjs/utils/session.js.map +1 -1
  141. package/dist/core/Agent.d.ts +8 -0
  142. package/dist/core/Agent.d.ts.map +1 -1
  143. package/dist/core/Agent.js +40 -2
  144. package/dist/core/Agent.js.map +1 -1
  145. package/dist/core/AutoChainExecutor.d.ts +8 -18
  146. package/dist/core/AutoChainExecutor.d.ts.map +1 -1
  147. package/dist/core/AutoChainExecutor.js +23 -26
  148. package/dist/core/AutoChainExecutor.js.map +1 -1
  149. package/dist/core/CompactionEngine.d.ts +14 -1
  150. package/dist/core/CompactionEngine.d.ts.map +1 -1
  151. package/dist/core/CompactionEngine.js +30 -6
  152. package/dist/core/CompactionEngine.js.map +1 -1
  153. package/dist/core/FlowRouter.d.ts.map +1 -1
  154. package/dist/core/FlowRouter.js +32 -10
  155. package/dist/core/FlowRouter.js.map +1 -1
  156. package/dist/core/ResponseGenerationError.d.ts.map +1 -1
  157. package/dist/core/ResponseGenerationError.js +3 -5
  158. package/dist/core/ResponseGenerationError.js.map +1 -1
  159. package/dist/core/ResponseModal.d.ts +29 -0
  160. package/dist/core/ResponseModal.d.ts.map +1 -1
  161. package/dist/core/ResponseModal.js +142 -19
  162. package/dist/core/ResponseModal.js.map +1 -1
  163. package/dist/core/ResponsePipeline.d.ts +36 -6
  164. package/dist/core/ResponsePipeline.d.ts.map +1 -1
  165. package/dist/core/ResponsePipeline.js +208 -73
  166. package/dist/core/ResponsePipeline.js.map +1 -1
  167. package/dist/core/SessionFinalizer.d.ts.map +1 -1
  168. package/dist/core/SessionFinalizer.js +31 -4
  169. package/dist/core/SessionFinalizer.js.map +1 -1
  170. package/dist/core/SessionManager.d.ts +10 -1
  171. package/dist/core/SessionManager.d.ts.map +1 -1
  172. package/dist/core/SessionManager.js +44 -17
  173. package/dist/core/SessionManager.js.map +1 -1
  174. package/dist/core/SignalProcessor.d.ts.map +1 -1
  175. package/dist/core/SignalProcessor.js +5 -77
  176. package/dist/core/SignalProcessor.js.map +1 -1
  177. package/dist/core/Step.d.ts.map +1 -1
  178. package/dist/core/Step.js +50 -2
  179. package/dist/core/Step.js.map +1 -1
  180. package/dist/core/StepLifecycle.d.ts +16 -6
  181. package/dist/core/StepLifecycle.d.ts.map +1 -1
  182. package/dist/core/StepLifecycle.js +97 -14
  183. package/dist/core/StepLifecycle.js.map +1 -1
  184. package/dist/core/StreamingToolExecutor.d.ts.map +1 -1
  185. package/dist/core/StreamingToolExecutor.js +28 -4
  186. package/dist/core/StreamingToolExecutor.js.map +1 -1
  187. package/dist/core/ToolLoopExecutor.d.ts +5 -1
  188. package/dist/core/ToolLoopExecutor.d.ts.map +1 -1
  189. package/dist/core/ToolLoopExecutor.js +155 -63
  190. package/dist/core/ToolLoopExecutor.js.map +1 -1
  191. package/dist/core/ToolManager.d.ts +1 -1
  192. package/dist/core/ToolManager.d.ts.map +1 -1
  193. package/dist/core/ToolManager.js +41 -18
  194. package/dist/core/ToolManager.js.map +1 -1
  195. package/dist/core/flow-namespace.d.ts +15 -0
  196. package/dist/core/flow-namespace.d.ts.map +1 -1
  197. package/dist/core/flow-namespace.js +22 -0
  198. package/dist/core/flow-namespace.js.map +1 -1
  199. package/dist/index.d.ts +4 -1
  200. package/dist/index.d.ts.map +1 -1
  201. package/dist/index.js +2 -1
  202. package/dist/index.js.map +1 -1
  203. package/dist/providers/AnthropicProvider.d.ts +10 -3
  204. package/dist/providers/AnthropicProvider.d.ts.map +1 -1
  205. package/dist/providers/AnthropicProvider.js +56 -75
  206. package/dist/providers/AnthropicProvider.js.map +1 -1
  207. package/dist/providers/GeminiProvider.d.ts +9 -3
  208. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  209. package/dist/providers/GeminiProvider.js +26 -70
  210. package/dist/providers/GeminiProvider.js.map +1 -1
  211. package/dist/providers/OpenAICompatibleProvider.d.ts +9 -0
  212. package/dist/providers/OpenAICompatibleProvider.d.ts.map +1 -1
  213. package/dist/providers/OpenAICompatibleProvider.js +103 -76
  214. package/dist/providers/OpenAICompatibleProvider.js.map +1 -1
  215. package/dist/providers/OpenAIProvider.d.ts +1 -1
  216. package/dist/providers/OpenAIProvider.d.ts.map +1 -1
  217. package/dist/providers/OpenAIProvider.js +1 -1
  218. package/dist/providers/errorClassification.d.ts +7 -0
  219. package/dist/providers/errorClassification.d.ts.map +1 -1
  220. package/dist/providers/errorClassification.js +26 -0
  221. package/dist/providers/errorClassification.js.map +1 -1
  222. package/dist/types/agent.d.ts +26 -0
  223. package/dist/types/agent.d.ts.map +1 -1
  224. package/dist/types/flow.d.ts +49 -32
  225. package/dist/types/flow.d.ts.map +1 -1
  226. package/dist/types/index.d.ts +1 -1
  227. package/dist/types/index.d.ts.map +1 -1
  228. package/dist/types/index.js.map +1 -1
  229. package/dist/types/tool.d.ts +2 -0
  230. package/dist/types/tool.d.ts.map +1 -1
  231. package/dist/types/tool.js.map +1 -1
  232. package/dist/utils/index.d.ts +4 -4
  233. package/dist/utils/index.d.ts.map +1 -1
  234. package/dist/utils/index.js +3 -3
  235. package/dist/utils/index.js.map +1 -1
  236. package/dist/utils/retry.d.ts +99 -1
  237. package/dist/utils/retry.d.ts.map +1 -1
  238. package/dist/utils/retry.js +137 -3
  239. package/dist/utils/retry.js.map +1 -1
  240. package/dist/utils/serialize.d.ts +17 -0
  241. package/dist/utils/serialize.d.ts.map +1 -1
  242. package/dist/utils/serialize.js +31 -0
  243. package/dist/utils/serialize.js.map +1 -1
  244. package/dist/utils/session.d.ts +21 -1
  245. package/dist/utils/session.d.ts.map +1 -1
  246. package/dist/utils/session.js +33 -4
  247. package/dist/utils/session.js.map +1 -1
  248. package/docs/concepts/architecture.md +3 -3
  249. package/docs/concepts/directives.md +1 -1
  250. package/docs/guides/error-handling.md +46 -45
  251. package/docs/guides/flow-control.md +8 -1
  252. package/docs/guides/instructions.md +15 -6
  253. package/docs/guides/persistence.md +12 -5
  254. package/docs/guides/streaming.md +10 -0
  255. package/docs/migration/README.md +4 -0
  256. package/docs/migration/v2-3-to-v2-4.md +4 -0
  257. package/docs/migration/v2-6-to-v2-7.md +246 -0
  258. package/docs/reference/adapters.md +15 -1
  259. package/docs/reference/create-agent.md +28 -0
  260. package/docs/reference/directive.md +1 -1
  261. package/docs/reference/errors.md +29 -31
  262. package/docs/reference/providers.md +23 -19
  263. package/docs/reference/step.md +28 -21
  264. package/docs/reference/tool.md +14 -5
  265. package/docs/start/02-first-agent.md +8 -4
  266. package/docs/start/03-collect-data.md +19 -10
  267. package/examples/01-quickstart.ts +1 -1
  268. package/examples/02-data-extraction.ts +1 -1
  269. package/examples/03-tools.ts +1 -1
  270. package/examples/04-instructions.ts +1 -1
  271. package/examples/05-branching.ts +1 -1
  272. package/examples/06-flow-control.ts +3 -3
  273. package/examples/07-streaming.ts +1 -1
  274. package/examples/08-persistence.ts +1 -1
  275. package/examples/09-signals.ts +1 -1
  276. package/package.json +2 -2
  277. package/src/adapters/MemoryAdapter.ts +29 -33
  278. package/src/adapters/PostgreSQLAdapter.ts +23 -18
  279. package/src/adapters/RedisAdapter.ts +81 -34
  280. package/src/adapters/SQLiteAdapter.ts +10 -31
  281. package/src/adapters/sessionRow.ts +57 -0
  282. package/src/core/Agent.ts +48 -2
  283. package/src/core/AutoChainExecutor.ts +37 -50
  284. package/src/core/CompactionEngine.ts +40 -6
  285. package/src/core/FlowRouter.ts +38 -12
  286. package/src/core/ResponseGenerationError.ts +3 -6
  287. package/src/core/ResponseModal.ts +185 -19
  288. package/src/core/ResponsePipeline.ts +259 -85
  289. package/src/core/SessionFinalizer.ts +35 -5
  290. package/src/core/SessionManager.ts +55 -21
  291. package/src/core/SignalProcessor.ts +5 -85
  292. package/src/core/Step.ts +79 -2
  293. package/src/core/StepLifecycle.ts +125 -22
  294. package/src/core/StreamingToolExecutor.ts +31 -6
  295. package/src/core/ToolLoopExecutor.ts +200 -74
  296. package/src/core/ToolManager.ts +45 -18
  297. package/src/core/flow-namespace.ts +29 -0
  298. package/src/index.ts +4 -1
  299. package/src/providers/AnthropicProvider.ts +83 -131
  300. package/src/providers/GeminiProvider.ts +42 -116
  301. package/src/providers/OpenAICompatibleProvider.ts +132 -133
  302. package/src/providers/OpenAIProvider.ts +2 -2
  303. package/src/providers/errorClassification.ts +34 -0
  304. package/src/types/agent.ts +25 -0
  305. package/src/types/flow.ts +37 -39
  306. package/src/types/index.ts +1 -0
  307. package/src/types/tool.ts +2 -0
  308. package/src/utils/index.ts +22 -3
  309. package/src/utils/retry.ts +251 -2
  310. package/src/utils/serialize.ts +38 -0
  311. package/src/utils/session.ts +41 -4
  312. package/dist/cjs/core/DirectiveBus.d.ts +0 -88
  313. package/dist/cjs/core/DirectiveBus.d.ts.map +0 -1
  314. package/dist/cjs/core/DirectiveBus.js +0 -196
  315. package/dist/cjs/core/DirectiveBus.js.map +0 -1
  316. package/dist/core/DirectiveBus.d.ts +0 -88
  317. package/dist/core/DirectiveBus.d.ts.map +0 -1
  318. package/dist/core/DirectiveBus.js +0 -192
  319. package/dist/core/DirectiveBus.js.map +0 -1
  320. package/src/core/DirectiveBus.ts +0 -248
@@ -1,88 +0,0 @@
1
- /**
2
- * DirectiveBus — per-turn collection mechanism for directives emitted by
3
- * hooks, tools, and branches.
4
- *
5
- * Two phases per turn:
6
- * 1. Pre-LLM: collects from `prepare` hooks and `onEnter` hooks.
7
- * 2. Post-LLM: collects from `finalize`, tools via `executeToolCalls`,
8
- * branches via `evaluateBranches`.
9
- *
10
- * Each entry is stamped with an emitter ID for debug logging. At phase
11
- * boundaries, the bus contents are merged using `flow.merge` and the
12
- * result is returned via `drain()`.
13
- *
14
- * Algorithm 4: position precedence `abort > complete > goTo/goToStep > reset`,
15
- * ties broken by emission order (last wins).
16
- *
17
- * **Validates: Requirements 1.3, 10.4, 10.5, 10.6**
18
- */
19
- import type { Directive } from "../types/flow";
20
- /** Phase of the turn pipeline the bus is currently collecting for. */
21
- export type DirectiveBusPhase = "pre-llm" | "post-llm";
22
- /** A single entry on the bus, stamped with its emitter for debug logging. */
23
- export interface DirectiveBusEntry<TContext = unknown, TData = unknown> {
24
- directive: Directive<TContext, TData>;
25
- emitterId: string;
26
- phase: DirectiveBusPhase;
27
- /** Monotonically increasing emission index within the phase. */
28
- order: number;
29
- }
30
- /**
31
- * Per-turn directive collection bus.
32
- *
33
- * Usage:
34
- * ```ts
35
- * const bus = new DirectiveBus();
36
- * bus.setPhase('pre-llm');
37
- * bus.emit({ goTo: 'Booking' }, 'step.onEnter:ask_date');
38
- * bus.emit({ appendPrompt: ['Be concise.'] }, 'step.prepare:ask_date');
39
- * const merged = bus.drain(); // merges all collected directives
40
- * bus.setPhase('post-llm');
41
- * // ... collect post-LLM emissions ...
42
- * const postMerged = bus.drain();
43
- * ```
44
- */
45
- export declare class DirectiveBus<TContext = unknown, TData = unknown> {
46
- private entries;
47
- private currentPhase;
48
- private orderCounter;
49
- /** Set the current collection phase. Resets the order counter for the new phase. */
50
- setPhase(phase: DirectiveBusPhase): void;
51
- /** Get the current phase. */
52
- getPhase(): DirectiveBusPhase;
53
- /**
54
- * Emit a directive onto the bus.
55
- *
56
- * @param directive - The directive to collect.
57
- * @param emitterId - Human-readable identifier of the emitter (for debug logging).
58
- */
59
- emit(directive: Directive<TContext, TData>, emitterId: string): void;
60
- /**
61
- * Drain the bus: merge all collected directives for the current phase
62
- * using Algorithm 4 (position precedence, last-wins tie-breaking,
63
- * shallow-merge for state writes).
64
- *
65
- * Returns `undefined` if no directives were collected.
66
- * After draining, the entries for the current phase are cleared.
67
- */
68
- drain(): Directive<TContext, TData> | undefined;
69
- /**
70
- * Drain ALL entries regardless of phase. Used for final turn cleanup.
71
- * Returns `undefined` if no directives were collected.
72
- */
73
- drainAll(): Directive<TContext, TData> | undefined;
74
- /** Clear all collected entries and reset the bus for a new turn. */
75
- clear(): void;
76
- /** Get the number of entries currently on the bus. */
77
- get size(): number;
78
- /** Get all entries (for inspection/testing). */
79
- getEntries(): ReadonlyArray<DirectiveBusEntry<TContext, TData>>;
80
- /** Check if the bus has any entries for the current phase. */
81
- hasEntries(): boolean;
82
- /**
83
- * Log debug-level conflict warnings when multiple emitters set position
84
- * fields or reply fields in the same phase.
85
- */
86
- private logConflicts;
87
- }
88
- //# sourceMappingURL=DirectiveBus.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DirectiveBus.d.ts","sourceRoot":"","sources":["../../../src/core/DirectiveBus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C,sEAAsE;AACtE,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,UAAU,CAAC;AAEvD,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB,CAAC,QAAQ,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO;IAClE,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,iBAAiB,CAAC;IACzB,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAY,CAAC,QAAQ,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO;IACzD,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,YAAY,CAAK;IAEzB,oFAAoF;IACpF,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAMxC,6BAA6B;IAC7B,QAAQ,IAAI,iBAAiB;IAI7B;;;;;OAKG;IACH,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAyBpE;;;;;;;OAOG;IACH,KAAK,IAAI,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,SAAS;IA4D/C;;;OAGG;IACH,QAAQ,IAAI,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,SAAS;IAgBlD,oEAAoE;IACpE,KAAK,IAAI,IAAI;IAMb,sDAAsD;IACtD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,gDAAgD;IAChD,UAAU,IAAI,aAAa,CAAC,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAI/D,8DAA8D;IAC9D,UAAU,IAAI,OAAO;IAMrB;;;OAGG;IACH,OAAO,CAAC,YAAY;CAiCvB"}
@@ -1,196 +0,0 @@
1
- "use strict";
2
- /**
3
- * DirectiveBus — per-turn collection mechanism for directives emitted by
4
- * hooks, tools, and branches.
5
- *
6
- * Two phases per turn:
7
- * 1. Pre-LLM: collects from `prepare` hooks and `onEnter` hooks.
8
- * 2. Post-LLM: collects from `finalize`, tools via `executeToolCalls`,
9
- * branches via `evaluateBranches`.
10
- *
11
- * Each entry is stamped with an emitter ID for debug logging. At phase
12
- * boundaries, the bus contents are merged using `flow.merge` and the
13
- * result is returned via `drain()`.
14
- *
15
- * Algorithm 4: position precedence `abort > complete > goTo/goToStep > reset`,
16
- * ties broken by emission order (last wins).
17
- *
18
- * **Validates: Requirements 1.3, 10.4, 10.5, 10.6**
19
- */
20
- Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.DirectiveBus = void 0;
22
- const flow_namespace_1 = require("./flow-namespace");
23
- const utils_1 = require("../utils");
24
- /**
25
- * Per-turn directive collection bus.
26
- *
27
- * Usage:
28
- * ```ts
29
- * const bus = new DirectiveBus();
30
- * bus.setPhase('pre-llm');
31
- * bus.emit({ goTo: 'Booking' }, 'step.onEnter:ask_date');
32
- * bus.emit({ appendPrompt: ['Be concise.'] }, 'step.prepare:ask_date');
33
- * const merged = bus.drain(); // merges all collected directives
34
- * bus.setPhase('post-llm');
35
- * // ... collect post-LLM emissions ...
36
- * const postMerged = bus.drain();
37
- * ```
38
- */
39
- class DirectiveBus {
40
- constructor() {
41
- this.entries = [];
42
- this.currentPhase = "pre-llm";
43
- this.orderCounter = 0;
44
- }
45
- /** Set the current collection phase. Resets the order counter for the new phase. */
46
- setPhase(phase) {
47
- this.currentPhase = phase;
48
- // Order counter is NOT reset — emission order is global within the turn
49
- // so that cross-phase comparisons (if ever needed) remain consistent.
50
- }
51
- /** Get the current phase. */
52
- getPhase() {
53
- return this.currentPhase;
54
- }
55
- /**
56
- * Emit a directive onto the bus.
57
- *
58
- * @param directive - The directive to collect.
59
- * @param emitterId - Human-readable identifier of the emitter (for debug logging).
60
- */
61
- emit(directive, emitterId) {
62
- if (!directive || typeof directive !== "object" || Array.isArray(directive)) {
63
- return; // Silently ignore non-object values (void returns from hooks)
64
- }
65
- // Check if the directive has any meaningful fields set
66
- const hasFields = Object.keys(directive).some((k) => directive[k] !== undefined);
67
- if (!hasFields) {
68
- return; // Empty directive — nothing to collect
69
- }
70
- this.entries.push({
71
- directive,
72
- emitterId,
73
- phase: this.currentPhase,
74
- order: this.orderCounter++,
75
- });
76
- utils_1.logger.debug(`[DirectiveBus] Collected directive from "${emitterId}" (phase=${this.currentPhase}, order=${this.orderCounter - 1})`);
77
- }
78
- /**
79
- * Drain the bus: merge all collected directives for the current phase
80
- * using Algorithm 4 (position precedence, last-wins tie-breaking,
81
- * shallow-merge for state writes).
82
- *
83
- * Returns `undefined` if no directives were collected.
84
- * After draining, the entries for the current phase are cleared.
85
- */
86
- drain() {
87
- const phaseEntries = this.entries.filter((e) => e.phase === this.currentPhase);
88
- if (phaseEntries.length === 0) {
89
- return undefined;
90
- }
91
- // Log conflicts when multiple emitters set position or reply fields
92
- this.logConflicts(phaseEntries);
93
- // Merge all directives in emission order using flow.merge (pairwise reduction).
94
- // flow.merge implements Algorithm 4: position precedence with last-wins tie-breaking.
95
- let merged = phaseEntries[0].directive;
96
- for (let i = 1; i < phaseEntries.length; i++) {
97
- merged = flow_namespace_1.flow.merge(merged, phaseEntries[i].directive);
98
- }
99
- // Strip pre-LLM-only fields from post-LLM phase emissions
100
- if (this.currentPhase === "post-llm") {
101
- const asAny = merged;
102
- const preLlmFields = ["appendPrompt", "injectTools", "halt"];
103
- // Identify which fields are present BEFORE stripping (the merge may
104
- // alias phaseEntries[0].directive when there is a single emitter, so
105
- // we must collect emitter names first).
106
- const droppedFields = [];
107
- for (const f of preLlmFields) {
108
- if (asAny[f] !== undefined) {
109
- droppedFields.push(f);
110
- }
111
- }
112
- if (droppedFields.length > 0) {
113
- // Identify emitters that contributed the dropped fields.
114
- const emitters = phaseEntries
115
- .filter((e) => {
116
- const d = e.directive;
117
- return droppedFields.some((f) => d[f] !== undefined);
118
- })
119
- .map((e) => e.emitterId);
120
- // Now strip the fields from the merged result.
121
- for (const f of droppedFields) {
122
- delete asAny[f];
123
- }
124
- utils_1.logger.debug(`[DirectiveBus] Dropped pre-LLM-only fields [${droppedFields.join(", ")}] from post-LLM emitters: ${emitters.join(", ")}`);
125
- }
126
- }
127
- // Clear entries for the drained phase
128
- this.entries = this.entries.filter((e) => e.phase !== this.currentPhase);
129
- return merged;
130
- }
131
- /**
132
- * Drain ALL entries regardless of phase. Used for final turn cleanup.
133
- * Returns `undefined` if no directives were collected.
134
- */
135
- drainAll() {
136
- if (this.entries.length === 0) {
137
- return undefined;
138
- }
139
- this.logConflicts(this.entries);
140
- let merged = this.entries[0].directive;
141
- for (let i = 1; i < this.entries.length; i++) {
142
- merged = flow_namespace_1.flow.merge(merged, this.entries[i].directive);
143
- }
144
- this.entries = [];
145
- return merged;
146
- }
147
- /** Clear all collected entries and reset the bus for a new turn. */
148
- clear() {
149
- this.entries = [];
150
- this.orderCounter = 0;
151
- this.currentPhase = "pre-llm";
152
- }
153
- /** Get the number of entries currently on the bus. */
154
- get size() {
155
- return this.entries.length;
156
- }
157
- /** Get all entries (for inspection/testing). */
158
- getEntries() {
159
- return this.entries;
160
- }
161
- /** Check if the bus has any entries for the current phase. */
162
- hasEntries() {
163
- return this.entries.some((e) => e.phase === this.currentPhase);
164
- }
165
- // ─── Private helpers ─────────────────────────────────────────────────────
166
- /**
167
- * Log debug-level conflict warnings when multiple emitters set position
168
- * fields or reply fields in the same phase.
169
- */
170
- logConflicts(entries) {
171
- // Check for position field conflicts
172
- const positionEmitters = [];
173
- for (const entry of entries) {
174
- const d = entry.directive;
175
- for (const field of ["abort", "complete", "goTo", "goToStep", "reset"]) {
176
- if (d[field] !== undefined) {
177
- positionEmitters.push({ emitterId: entry.emitterId, field });
178
- }
179
- }
180
- }
181
- if (positionEmitters.length > 1) {
182
- const details = positionEmitters
183
- .map((e) => `${e.emitterId}(${e.field})`)
184
- .join(", ");
185
- utils_1.logger.debug(`[DirectiveBus] Multiple position fields in one turn — conflict resolution applied. Emitters: ${details}`);
186
- }
187
- // Check for reply conflicts
188
- const replyEmitters = entries.filter((e) => e.directive.reply !== undefined);
189
- if (replyEmitters.length > 1) {
190
- const emitterIds = replyEmitters.map((e) => e.emitterId).join(", ");
191
- utils_1.logger.debug(`[DirectiveBus] Multiple reply fields in one turn — using last emission. Emitters: ${emitterIds}`);
192
- }
193
- }
194
- }
195
- exports.DirectiveBus = DirectiveBus;
196
- //# sourceMappingURL=DirectiveBus.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DirectiveBus.js","sourceRoot":"","sources":["../../../src/core/DirectiveBus.ts"],"names":[],"mappings":"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"}
@@ -1,88 +0,0 @@
1
- /**
2
- * DirectiveBus — per-turn collection mechanism for directives emitted by
3
- * hooks, tools, and branches.
4
- *
5
- * Two phases per turn:
6
- * 1. Pre-LLM: collects from `prepare` hooks and `onEnter` hooks.
7
- * 2. Post-LLM: collects from `finalize`, tools via `executeToolCalls`,
8
- * branches via `evaluateBranches`.
9
- *
10
- * Each entry is stamped with an emitter ID for debug logging. At phase
11
- * boundaries, the bus contents are merged using `flow.merge` and the
12
- * result is returned via `drain()`.
13
- *
14
- * Algorithm 4: position precedence `abort > complete > goTo/goToStep > reset`,
15
- * ties broken by emission order (last wins).
16
- *
17
- * **Validates: Requirements 1.3, 10.4, 10.5, 10.6**
18
- */
19
- import type { Directive } from "../types/flow";
20
- /** Phase of the turn pipeline the bus is currently collecting for. */
21
- export type DirectiveBusPhase = "pre-llm" | "post-llm";
22
- /** A single entry on the bus, stamped with its emitter for debug logging. */
23
- export interface DirectiveBusEntry<TContext = unknown, TData = unknown> {
24
- directive: Directive<TContext, TData>;
25
- emitterId: string;
26
- phase: DirectiveBusPhase;
27
- /** Monotonically increasing emission index within the phase. */
28
- order: number;
29
- }
30
- /**
31
- * Per-turn directive collection bus.
32
- *
33
- * Usage:
34
- * ```ts
35
- * const bus = new DirectiveBus();
36
- * bus.setPhase('pre-llm');
37
- * bus.emit({ goTo: 'Booking' }, 'step.onEnter:ask_date');
38
- * bus.emit({ appendPrompt: ['Be concise.'] }, 'step.prepare:ask_date');
39
- * const merged = bus.drain(); // merges all collected directives
40
- * bus.setPhase('post-llm');
41
- * // ... collect post-LLM emissions ...
42
- * const postMerged = bus.drain();
43
- * ```
44
- */
45
- export declare class DirectiveBus<TContext = unknown, TData = unknown> {
46
- private entries;
47
- private currentPhase;
48
- private orderCounter;
49
- /** Set the current collection phase. Resets the order counter for the new phase. */
50
- setPhase(phase: DirectiveBusPhase): void;
51
- /** Get the current phase. */
52
- getPhase(): DirectiveBusPhase;
53
- /**
54
- * Emit a directive onto the bus.
55
- *
56
- * @param directive - The directive to collect.
57
- * @param emitterId - Human-readable identifier of the emitter (for debug logging).
58
- */
59
- emit(directive: Directive<TContext, TData>, emitterId: string): void;
60
- /**
61
- * Drain the bus: merge all collected directives for the current phase
62
- * using Algorithm 4 (position precedence, last-wins tie-breaking,
63
- * shallow-merge for state writes).
64
- *
65
- * Returns `undefined` if no directives were collected.
66
- * After draining, the entries for the current phase are cleared.
67
- */
68
- drain(): Directive<TContext, TData> | undefined;
69
- /**
70
- * Drain ALL entries regardless of phase. Used for final turn cleanup.
71
- * Returns `undefined` if no directives were collected.
72
- */
73
- drainAll(): Directive<TContext, TData> | undefined;
74
- /** Clear all collected entries and reset the bus for a new turn. */
75
- clear(): void;
76
- /** Get the number of entries currently on the bus. */
77
- get size(): number;
78
- /** Get all entries (for inspection/testing). */
79
- getEntries(): ReadonlyArray<DirectiveBusEntry<TContext, TData>>;
80
- /** Check if the bus has any entries for the current phase. */
81
- hasEntries(): boolean;
82
- /**
83
- * Log debug-level conflict warnings when multiple emitters set position
84
- * fields or reply fields in the same phase.
85
- */
86
- private logConflicts;
87
- }
88
- //# sourceMappingURL=DirectiveBus.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DirectiveBus.d.ts","sourceRoot":"","sources":["../../src/core/DirectiveBus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C,sEAAsE;AACtE,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,UAAU,CAAC;AAEvD,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB,CAAC,QAAQ,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO;IAClE,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,iBAAiB,CAAC;IACzB,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAY,CAAC,QAAQ,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO;IACzD,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,YAAY,CAAK;IAEzB,oFAAoF;IACpF,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAMxC,6BAA6B;IAC7B,QAAQ,IAAI,iBAAiB;IAI7B;;;;;OAKG;IACH,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAyBpE;;;;;;;OAOG;IACH,KAAK,IAAI,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,SAAS;IA4D/C;;;OAGG;IACH,QAAQ,IAAI,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,SAAS;IAgBlD,oEAAoE;IACpE,KAAK,IAAI,IAAI;IAMb,sDAAsD;IACtD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,gDAAgD;IAChD,UAAU,IAAI,aAAa,CAAC,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAI/D,8DAA8D;IAC9D,UAAU,IAAI,OAAO;IAMrB;;;OAGG;IACH,OAAO,CAAC,YAAY;CAiCvB"}
@@ -1,192 +0,0 @@
1
- /**
2
- * DirectiveBus — per-turn collection mechanism for directives emitted by
3
- * hooks, tools, and branches.
4
- *
5
- * Two phases per turn:
6
- * 1. Pre-LLM: collects from `prepare` hooks and `onEnter` hooks.
7
- * 2. Post-LLM: collects from `finalize`, tools via `executeToolCalls`,
8
- * branches via `evaluateBranches`.
9
- *
10
- * Each entry is stamped with an emitter ID for debug logging. At phase
11
- * boundaries, the bus contents are merged using `flow.merge` and the
12
- * result is returned via `drain()`.
13
- *
14
- * Algorithm 4: position precedence `abort > complete > goTo/goToStep > reset`,
15
- * ties broken by emission order (last wins).
16
- *
17
- * **Validates: Requirements 1.3, 10.4, 10.5, 10.6**
18
- */
19
- import { flow } from "./flow-namespace";
20
- import { logger } from "../utils";
21
- /**
22
- * Per-turn directive collection bus.
23
- *
24
- * Usage:
25
- * ```ts
26
- * const bus = new DirectiveBus();
27
- * bus.setPhase('pre-llm');
28
- * bus.emit({ goTo: 'Booking' }, 'step.onEnter:ask_date');
29
- * bus.emit({ appendPrompt: ['Be concise.'] }, 'step.prepare:ask_date');
30
- * const merged = bus.drain(); // merges all collected directives
31
- * bus.setPhase('post-llm');
32
- * // ... collect post-LLM emissions ...
33
- * const postMerged = bus.drain();
34
- * ```
35
- */
36
- export class DirectiveBus {
37
- constructor() {
38
- this.entries = [];
39
- this.currentPhase = "pre-llm";
40
- this.orderCounter = 0;
41
- }
42
- /** Set the current collection phase. Resets the order counter for the new phase. */
43
- setPhase(phase) {
44
- this.currentPhase = phase;
45
- // Order counter is NOT reset — emission order is global within the turn
46
- // so that cross-phase comparisons (if ever needed) remain consistent.
47
- }
48
- /** Get the current phase. */
49
- getPhase() {
50
- return this.currentPhase;
51
- }
52
- /**
53
- * Emit a directive onto the bus.
54
- *
55
- * @param directive - The directive to collect.
56
- * @param emitterId - Human-readable identifier of the emitter (for debug logging).
57
- */
58
- emit(directive, emitterId) {
59
- if (!directive || typeof directive !== "object" || Array.isArray(directive)) {
60
- return; // Silently ignore non-object values (void returns from hooks)
61
- }
62
- // Check if the directive has any meaningful fields set
63
- const hasFields = Object.keys(directive).some((k) => directive[k] !== undefined);
64
- if (!hasFields) {
65
- return; // Empty directive — nothing to collect
66
- }
67
- this.entries.push({
68
- directive,
69
- emitterId,
70
- phase: this.currentPhase,
71
- order: this.orderCounter++,
72
- });
73
- logger.debug(`[DirectiveBus] Collected directive from "${emitterId}" (phase=${this.currentPhase}, order=${this.orderCounter - 1})`);
74
- }
75
- /**
76
- * Drain the bus: merge all collected directives for the current phase
77
- * using Algorithm 4 (position precedence, last-wins tie-breaking,
78
- * shallow-merge for state writes).
79
- *
80
- * Returns `undefined` if no directives were collected.
81
- * After draining, the entries for the current phase are cleared.
82
- */
83
- drain() {
84
- const phaseEntries = this.entries.filter((e) => e.phase === this.currentPhase);
85
- if (phaseEntries.length === 0) {
86
- return undefined;
87
- }
88
- // Log conflicts when multiple emitters set position or reply fields
89
- this.logConflicts(phaseEntries);
90
- // Merge all directives in emission order using flow.merge (pairwise reduction).
91
- // flow.merge implements Algorithm 4: position precedence with last-wins tie-breaking.
92
- let merged = phaseEntries[0].directive;
93
- for (let i = 1; i < phaseEntries.length; i++) {
94
- merged = flow.merge(merged, phaseEntries[i].directive);
95
- }
96
- // Strip pre-LLM-only fields from post-LLM phase emissions
97
- if (this.currentPhase === "post-llm") {
98
- const asAny = merged;
99
- const preLlmFields = ["appendPrompt", "injectTools", "halt"];
100
- // Identify which fields are present BEFORE stripping (the merge may
101
- // alias phaseEntries[0].directive when there is a single emitter, so
102
- // we must collect emitter names first).
103
- const droppedFields = [];
104
- for (const f of preLlmFields) {
105
- if (asAny[f] !== undefined) {
106
- droppedFields.push(f);
107
- }
108
- }
109
- if (droppedFields.length > 0) {
110
- // Identify emitters that contributed the dropped fields.
111
- const emitters = phaseEntries
112
- .filter((e) => {
113
- const d = e.directive;
114
- return droppedFields.some((f) => d[f] !== undefined);
115
- })
116
- .map((e) => e.emitterId);
117
- // Now strip the fields from the merged result.
118
- for (const f of droppedFields) {
119
- delete asAny[f];
120
- }
121
- logger.debug(`[DirectiveBus] Dropped pre-LLM-only fields [${droppedFields.join(", ")}] from post-LLM emitters: ${emitters.join(", ")}`);
122
- }
123
- }
124
- // Clear entries for the drained phase
125
- this.entries = this.entries.filter((e) => e.phase !== this.currentPhase);
126
- return merged;
127
- }
128
- /**
129
- * Drain ALL entries regardless of phase. Used for final turn cleanup.
130
- * Returns `undefined` if no directives were collected.
131
- */
132
- drainAll() {
133
- if (this.entries.length === 0) {
134
- return undefined;
135
- }
136
- this.logConflicts(this.entries);
137
- let merged = this.entries[0].directive;
138
- for (let i = 1; i < this.entries.length; i++) {
139
- merged = flow.merge(merged, this.entries[i].directive);
140
- }
141
- this.entries = [];
142
- return merged;
143
- }
144
- /** Clear all collected entries and reset the bus for a new turn. */
145
- clear() {
146
- this.entries = [];
147
- this.orderCounter = 0;
148
- this.currentPhase = "pre-llm";
149
- }
150
- /** Get the number of entries currently on the bus. */
151
- get size() {
152
- return this.entries.length;
153
- }
154
- /** Get all entries (for inspection/testing). */
155
- getEntries() {
156
- return this.entries;
157
- }
158
- /** Check if the bus has any entries for the current phase. */
159
- hasEntries() {
160
- return this.entries.some((e) => e.phase === this.currentPhase);
161
- }
162
- // ─── Private helpers ─────────────────────────────────────────────────────
163
- /**
164
- * Log debug-level conflict warnings when multiple emitters set position
165
- * fields or reply fields in the same phase.
166
- */
167
- logConflicts(entries) {
168
- // Check for position field conflicts
169
- const positionEmitters = [];
170
- for (const entry of entries) {
171
- const d = entry.directive;
172
- for (const field of ["abort", "complete", "goTo", "goToStep", "reset"]) {
173
- if (d[field] !== undefined) {
174
- positionEmitters.push({ emitterId: entry.emitterId, field });
175
- }
176
- }
177
- }
178
- if (positionEmitters.length > 1) {
179
- const details = positionEmitters
180
- .map((e) => `${e.emitterId}(${e.field})`)
181
- .join(", ");
182
- logger.debug(`[DirectiveBus] Multiple position fields in one turn — conflict resolution applied. Emitters: ${details}`);
183
- }
184
- // Check for reply conflicts
185
- const replyEmitters = entries.filter((e) => e.directive.reply !== undefined);
186
- if (replyEmitters.length > 1) {
187
- const emitterIds = replyEmitters.map((e) => e.emitterId).join(", ");
188
- logger.debug(`[DirectiveBus] Multiple reply fields in one turn — using last emission. Emitters: ${emitterIds}`);
189
- }
190
- }
191
- }
192
- //# sourceMappingURL=DirectiveBus.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DirectiveBus.js","sourceRoot":"","sources":["../../src/core/DirectiveBus.ts"],"names":[],"mappings":"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"}