@falai/agent 0.4.0 → 0.5.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 (285) hide show
  1. package/README.md +21 -74
  2. package/dist/cjs/core/Agent.d.ts +22 -29
  3. package/dist/cjs/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/core/Agent.js +465 -275
  5. package/dist/cjs/core/Agent.js.map +1 -1
  6. package/dist/cjs/core/Events.d.ts +10 -1
  7. package/dist/cjs/core/Events.d.ts.map +1 -1
  8. package/dist/cjs/core/Events.js +3 -2
  9. package/dist/cjs/core/Events.js.map +1 -1
  10. package/dist/cjs/core/PersistenceManager.d.ts +19 -0
  11. package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
  12. package/dist/cjs/core/PersistenceManager.js +57 -0
  13. package/dist/cjs/core/PersistenceManager.js.map +1 -1
  14. package/dist/cjs/core/PromptComposer.d.ts +24 -0
  15. package/dist/cjs/core/PromptComposer.d.ts.map +1 -0
  16. package/dist/cjs/core/PromptComposer.js +127 -0
  17. package/dist/cjs/core/PromptComposer.js.map +1 -0
  18. package/dist/cjs/core/ResponseEngine.d.ts +19 -0
  19. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -0
  20. package/dist/cjs/core/ResponseEngine.js +51 -0
  21. package/dist/cjs/core/ResponseEngine.js.map +1 -0
  22. package/dist/cjs/core/Route.d.ts +18 -12
  23. package/dist/cjs/core/Route.d.ts.map +1 -1
  24. package/dist/cjs/core/Route.js +15 -9
  25. package/dist/cjs/core/Route.js.map +1 -1
  26. package/dist/cjs/core/RoutingEngine.d.ts +38 -0
  27. package/dist/cjs/core/RoutingEngine.d.ts.map +1 -0
  28. package/dist/cjs/core/RoutingEngine.js +110 -0
  29. package/dist/cjs/core/RoutingEngine.js.map +1 -0
  30. package/dist/cjs/core/State.d.ts +15 -4
  31. package/dist/cjs/core/State.d.ts.map +1 -1
  32. package/dist/cjs/core/State.js +21 -2
  33. package/dist/cjs/core/State.js.map +1 -1
  34. package/dist/cjs/core/ToolExecutor.d.ts +29 -0
  35. package/dist/cjs/core/ToolExecutor.d.ts.map +1 -0
  36. package/dist/cjs/core/ToolExecutor.js +73 -0
  37. package/dist/cjs/core/ToolExecutor.js.map +1 -0
  38. package/dist/cjs/core/Transition.d.ts +5 -5
  39. package/dist/cjs/core/Transition.d.ts.map +1 -1
  40. package/dist/cjs/core/Transition.js.map +1 -1
  41. package/dist/cjs/index.d.ts +6 -8
  42. package/dist/cjs/index.d.ts.map +1 -1
  43. package/dist/cjs/index.js +8 -10
  44. package/dist/cjs/index.js.map +1 -1
  45. package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
  46. package/dist/cjs/providers/AnthropicProvider.js +10 -13
  47. package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
  48. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  49. package/dist/cjs/providers/GeminiProvider.js +12 -8
  50. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  51. package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
  52. package/dist/cjs/providers/OpenAIProvider.js +10 -53
  53. package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
  54. package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
  55. package/dist/cjs/providers/OpenRouterProvider.js +10 -53
  56. package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
  57. package/dist/cjs/types/agent.d.ts +13 -9
  58. package/dist/cjs/types/agent.d.ts.map +1 -1
  59. package/dist/cjs/types/ai.d.ts +8 -2
  60. package/dist/cjs/types/ai.d.ts.map +1 -1
  61. package/dist/cjs/types/history.d.ts +8 -0
  62. package/dist/cjs/types/history.d.ts.map +1 -1
  63. package/dist/cjs/types/index.d.ts +0 -3
  64. package/dist/cjs/types/index.d.ts.map +1 -1
  65. package/dist/cjs/types/index.js +1 -3
  66. package/dist/cjs/types/index.js.map +1 -1
  67. package/dist/cjs/types/route.d.ts +39 -4
  68. package/dist/cjs/types/route.d.ts.map +1 -1
  69. package/dist/cjs/types/routing.d.ts +16 -0
  70. package/dist/cjs/types/routing.d.ts.map +1 -0
  71. package/dist/cjs/types/routing.js +3 -0
  72. package/dist/cjs/types/routing.js.map +1 -0
  73. package/dist/cjs/types/schema.d.ts +22 -0
  74. package/dist/cjs/types/schema.d.ts.map +1 -0
  75. package/dist/cjs/types/schema.js +3 -0
  76. package/dist/cjs/types/schema.js.map +1 -0
  77. package/dist/cjs/types/session.d.ts +72 -0
  78. package/dist/cjs/types/session.d.ts.map +1 -0
  79. package/dist/cjs/types/session.js +140 -0
  80. package/dist/cjs/types/session.js.map +1 -0
  81. package/dist/cjs/types/tool.d.ts +11 -5
  82. package/dist/cjs/types/tool.d.ts.map +1 -1
  83. package/dist/cjs/utils/id.d.ts +0 -5
  84. package/dist/cjs/utils/id.d.ts.map +1 -1
  85. package/dist/cjs/utils/id.js +0 -10
  86. package/dist/cjs/utils/id.js.map +1 -1
  87. package/dist/cjs/utils/schema.d.ts +17 -0
  88. package/dist/cjs/utils/schema.d.ts.map +1 -0
  89. package/dist/cjs/utils/schema.js +32 -0
  90. package/dist/cjs/utils/schema.js.map +1 -0
  91. package/dist/core/Agent.d.ts +22 -29
  92. package/dist/core/Agent.d.ts.map +1 -1
  93. package/dist/core/Agent.js +465 -275
  94. package/dist/core/Agent.js.map +1 -1
  95. package/dist/core/Events.d.ts +10 -1
  96. package/dist/core/Events.d.ts.map +1 -1
  97. package/dist/core/Events.js +3 -2
  98. package/dist/core/Events.js.map +1 -1
  99. package/dist/core/PersistenceManager.d.ts +19 -0
  100. package/dist/core/PersistenceManager.d.ts.map +1 -1
  101. package/dist/core/PersistenceManager.js +57 -0
  102. package/dist/core/PersistenceManager.js.map +1 -1
  103. package/dist/core/PromptComposer.d.ts +24 -0
  104. package/dist/core/PromptComposer.d.ts.map +1 -0
  105. package/dist/core/PromptComposer.js +123 -0
  106. package/dist/core/PromptComposer.js.map +1 -0
  107. package/dist/core/ResponseEngine.d.ts +19 -0
  108. package/dist/core/ResponseEngine.d.ts.map +1 -0
  109. package/dist/core/ResponseEngine.js +47 -0
  110. package/dist/core/ResponseEngine.js.map +1 -0
  111. package/dist/core/Route.d.ts +18 -12
  112. package/dist/core/Route.d.ts.map +1 -1
  113. package/dist/core/Route.js +15 -9
  114. package/dist/core/Route.js.map +1 -1
  115. package/dist/core/RoutingEngine.d.ts +38 -0
  116. package/dist/core/RoutingEngine.d.ts.map +1 -0
  117. package/dist/core/RoutingEngine.js +106 -0
  118. package/dist/core/RoutingEngine.js.map +1 -0
  119. package/dist/core/State.d.ts +15 -4
  120. package/dist/core/State.d.ts.map +1 -1
  121. package/dist/core/State.js +21 -2
  122. package/dist/core/State.js.map +1 -1
  123. package/dist/core/ToolExecutor.d.ts +29 -0
  124. package/dist/core/ToolExecutor.d.ts.map +1 -0
  125. package/dist/core/ToolExecutor.js +69 -0
  126. package/dist/core/ToolExecutor.js.map +1 -0
  127. package/dist/core/Transition.d.ts +5 -5
  128. package/dist/core/Transition.d.ts.map +1 -1
  129. package/dist/core/Transition.js.map +1 -1
  130. package/dist/index.d.ts +6 -8
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +3 -5
  133. package/dist/index.js.map +1 -1
  134. package/dist/providers/AnthropicProvider.d.ts.map +1 -1
  135. package/dist/providers/AnthropicProvider.js +10 -13
  136. package/dist/providers/AnthropicProvider.js.map +1 -1
  137. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  138. package/dist/providers/GeminiProvider.js +12 -8
  139. package/dist/providers/GeminiProvider.js.map +1 -1
  140. package/dist/providers/OpenAIProvider.d.ts.map +1 -1
  141. package/dist/providers/OpenAIProvider.js +10 -53
  142. package/dist/providers/OpenAIProvider.js.map +1 -1
  143. package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
  144. package/dist/providers/OpenRouterProvider.js +10 -53
  145. package/dist/providers/OpenRouterProvider.js.map +1 -1
  146. package/dist/types/agent.d.ts +13 -9
  147. package/dist/types/agent.d.ts.map +1 -1
  148. package/dist/types/ai.d.ts +8 -2
  149. package/dist/types/ai.d.ts.map +1 -1
  150. package/dist/types/history.d.ts +8 -0
  151. package/dist/types/history.d.ts.map +1 -1
  152. package/dist/types/index.d.ts +0 -3
  153. package/dist/types/index.d.ts.map +1 -1
  154. package/dist/types/index.js +0 -1
  155. package/dist/types/index.js.map +1 -1
  156. package/dist/types/route.d.ts +39 -4
  157. package/dist/types/route.d.ts.map +1 -1
  158. package/dist/types/routing.d.ts +16 -0
  159. package/dist/types/routing.d.ts.map +1 -0
  160. package/dist/types/routing.js +2 -0
  161. package/dist/types/routing.js.map +1 -0
  162. package/dist/types/schema.d.ts +22 -0
  163. package/dist/types/schema.d.ts.map +1 -0
  164. package/dist/types/schema.js +2 -0
  165. package/dist/types/schema.js.map +1 -0
  166. package/dist/types/session.d.ts +72 -0
  167. package/dist/types/session.d.ts.map +1 -0
  168. package/dist/types/session.js +132 -0
  169. package/dist/types/session.js.map +1 -0
  170. package/dist/types/tool.d.ts +11 -5
  171. package/dist/types/tool.d.ts.map +1 -1
  172. package/dist/utils/id.d.ts +0 -5
  173. package/dist/utils/id.d.ts.map +1 -1
  174. package/dist/utils/id.js +0 -9
  175. package/dist/utils/id.js.map +1 -1
  176. package/dist/utils/schema.d.ts +17 -0
  177. package/dist/utils/schema.d.ts.map +1 -0
  178. package/dist/utils/schema.js +27 -0
  179. package/dist/utils/schema.js.map +1 -0
  180. package/docs/ADAPTERS.md +83 -3
  181. package/docs/API_REFERENCE.md +95 -104
  182. package/docs/ARCHITECTURE.md +284 -286
  183. package/docs/CONSTRUCTOR_OPTIONS.md +192 -135
  184. package/docs/CONTEXT_MANAGEMENT.md +311 -28
  185. package/docs/CONTRIBUTING.md +1 -1
  186. package/docs/DOMAINS.md +61 -0
  187. package/docs/GETTING_STARTED.md +177 -88
  188. package/docs/PERSISTENCE.md +170 -23
  189. package/docs/README.md +7 -10
  190. package/examples/business-onboarding.ts +21 -9
  191. package/examples/company-qna-agent.ts +508 -0
  192. package/examples/declarative-agent.ts +143 -26
  193. package/examples/domain-scoping.ts +31 -10
  194. package/examples/extracted-data-modification.ts +415 -0
  195. package/examples/healthcare-agent.ts +194 -90
  196. package/examples/openai-agent.ts +67 -25
  197. package/examples/opensearch-persistence.ts +455 -151
  198. package/examples/persistent-onboarding.ts +162 -96
  199. package/examples/prisma-persistence.ts +371 -125
  200. package/examples/redis-persistence.ts +393 -23
  201. package/examples/rules-prohibitions.ts +32 -11
  202. package/examples/streaming-agent.ts +61 -13
  203. package/examples/travel-agent.ts +266 -133
  204. package/package.json +1 -1
  205. package/src/core/Agent.ts +679 -332
  206. package/src/core/Events.ts +12 -2
  207. package/src/core/PersistenceManager.ts +83 -0
  208. package/src/core/PromptComposer.ts +143 -0
  209. package/src/core/ResponseEngine.ts +82 -0
  210. package/src/core/Route.ts +32 -17
  211. package/src/core/RoutingEngine.ts +165 -0
  212. package/src/core/State.ts +55 -15
  213. package/src/core/ToolExecutor.ts +117 -0
  214. package/src/core/Transition.ts +5 -5
  215. package/src/index.ts +12 -21
  216. package/src/providers/AnthropicProvider.ts +10 -13
  217. package/src/providers/GeminiProvider.ts +12 -8
  218. package/src/providers/OpenAIProvider.ts +10 -56
  219. package/src/providers/OpenRouterProvider.ts +10 -56
  220. package/src/types/agent.ts +16 -10
  221. package/src/types/ai.ts +6 -2
  222. package/src/types/history.ts +8 -0
  223. package/src/types/index.ts +0 -11
  224. package/src/types/route.ts +41 -5
  225. package/src/types/routing.ts +18 -0
  226. package/src/types/schema.ts +23 -0
  227. package/src/types/session.ts +207 -0
  228. package/src/types/tool.ts +29 -7
  229. package/src/utils/id.ts +0 -10
  230. package/src/utils/schema.ts +32 -0
  231. package/dist/cjs/core/ConditionEvaluator.d.ts +0 -72
  232. package/dist/cjs/core/ConditionEvaluator.d.ts.map +0 -1
  233. package/dist/cjs/core/ConditionEvaluator.js +0 -272
  234. package/dist/cjs/core/ConditionEvaluator.js.map +0 -1
  235. package/dist/cjs/core/Observation.d.ts +0 -24
  236. package/dist/cjs/core/Observation.d.ts.map +0 -1
  237. package/dist/cjs/core/Observation.js +0 -39
  238. package/dist/cjs/core/Observation.js.map +0 -1
  239. package/dist/cjs/core/PreparationEngine.d.ts +0 -105
  240. package/dist/cjs/core/PreparationEngine.d.ts.map +0 -1
  241. package/dist/cjs/core/PreparationEngine.js +0 -320
  242. package/dist/cjs/core/PreparationEngine.js.map +0 -1
  243. package/dist/cjs/core/PromptBuilder.d.ts +0 -136
  244. package/dist/cjs/core/PromptBuilder.d.ts.map +0 -1
  245. package/dist/cjs/core/PromptBuilder.js +0 -421
  246. package/dist/cjs/core/PromptBuilder.js.map +0 -1
  247. package/dist/cjs/types/observation.d.ts +0 -27
  248. package/dist/cjs/types/observation.d.ts.map +0 -1
  249. package/dist/cjs/types/observation.js +0 -6
  250. package/dist/cjs/types/observation.js.map +0 -1
  251. package/dist/cjs/types/prompt.d.ts +0 -46
  252. package/dist/cjs/types/prompt.d.ts.map +0 -1
  253. package/dist/cjs/types/prompt.js +0 -19
  254. package/dist/cjs/types/prompt.js.map +0 -1
  255. package/dist/core/ConditionEvaluator.d.ts +0 -72
  256. package/dist/core/ConditionEvaluator.d.ts.map +0 -1
  257. package/dist/core/ConditionEvaluator.js +0 -268
  258. package/dist/core/ConditionEvaluator.js.map +0 -1
  259. package/dist/core/Observation.d.ts +0 -24
  260. package/dist/core/Observation.d.ts.map +0 -1
  261. package/dist/core/Observation.js +0 -35
  262. package/dist/core/Observation.js.map +0 -1
  263. package/dist/core/PreparationEngine.d.ts +0 -105
  264. package/dist/core/PreparationEngine.d.ts.map +0 -1
  265. package/dist/core/PreparationEngine.js +0 -316
  266. package/dist/core/PreparationEngine.js.map +0 -1
  267. package/dist/core/PromptBuilder.d.ts +0 -136
  268. package/dist/core/PromptBuilder.d.ts.map +0 -1
  269. package/dist/core/PromptBuilder.js +0 -417
  270. package/dist/core/PromptBuilder.js.map +0 -1
  271. package/dist/types/observation.d.ts +0 -27
  272. package/dist/types/observation.d.ts.map +0 -1
  273. package/dist/types/observation.js +0 -5
  274. package/dist/types/observation.js.map +0 -1
  275. package/dist/types/prompt.d.ts +0 -46
  276. package/dist/types/prompt.d.ts.map +0 -1
  277. package/dist/types/prompt.js +0 -16
  278. package/dist/types/prompt.js.map +0 -1
  279. package/docs/STRUCTURE.md +0 -58
  280. package/src/core/ConditionEvaluator.ts +0 -381
  281. package/src/core/Observation.ts +0 -47
  282. package/src/core/PreparationEngine.ts +0 -500
  283. package/src/core/PromptBuilder.ts +0 -617
  284. package/src/types/observation.ts +0 -29
  285. package/src/types/prompt.ts +0 -49
@@ -1,500 +0,0 @@
1
- /**
2
- * PreparationEngine - Handles the preparation iteration loop
3
- *
4
- * This engine implements the core Parlant/Emcie architecture:
5
- * 1. Before generating a message, run preparation iterations
6
- * 2. Each iteration:
7
- * - Match guidelines against current context
8
- * - Walk the state machine and execute tool transitions
9
- * - Execute tools when conditions are met
10
- * - Update context from tool results
11
- * - Check if prepared to respond
12
- * 3. After preparation, the AI generates the final message
13
- *
14
- * The AI NEVER sees tools - tools execute automatically based on:
15
- * - State machine transitions ({ toolState: tool })
16
- * - Guideline matching with associated tools
17
- */
18
-
19
- import type { Event, StateRef, AiProvider } from "../types/index";
20
- import type { Guideline, GuidelineMatch } from "../types/agent";
21
- import type { ToolRef } from "../types/tool";
22
- import type { Route } from "./Route";
23
- import { State } from "./State";
24
- import { ConditionEvaluator } from "./ConditionEvaluator";
25
-
26
- /**
27
- * Tool execution result
28
- */
29
- export interface ToolExecutionResult {
30
- toolName: string;
31
- arguments: Record<string, unknown>;
32
- result: unknown;
33
- success: boolean;
34
- error?: string;
35
- }
36
-
37
- /**
38
- * Preparation iteration state
39
- */
40
- export interface IterationState {
41
- iterationNumber: number;
42
- matchedGuidelines: GuidelineMatch[];
43
- executedTools: ToolExecutionResult[];
44
- contextUpdates: Record<string, unknown>;
45
- preparedToRespond: boolean;
46
- }
47
-
48
- /**
49
- * Preparation context
50
- */
51
- export interface PreparationContext<TContext = unknown> {
52
- history: Event[];
53
- currentState?: StateRef;
54
- context: TContext;
55
- routes: Route<TContext>[];
56
- guidelines: Guideline[];
57
- maxIterations: number;
58
- }
59
-
60
- /**
61
- * Preparation result
62
- */
63
- export interface PreparationResult<TContext = unknown> {
64
- iterations: IterationState[];
65
- finalContext: TContext;
66
- toolExecutions: ToolExecutionResult[];
67
- preparedToRespond: boolean;
68
- }
69
-
70
- /**
71
- * PreparationEngine - Executes the preparation iteration loop
72
- */
73
- export class PreparationEngine<TContext = unknown> {
74
- private readonly conditionEvaluator?: ConditionEvaluator<TContext>;
75
-
76
- constructor(ai?: AiProvider) {
77
- if (ai) {
78
- this.conditionEvaluator = new ConditionEvaluator<TContext>(ai);
79
- }
80
- }
81
-
82
- /**
83
- * Run preparation iterations before message generation
84
- *
85
- * This is the core engine that executes tools automatically
86
- * based on state machine transitions and guideline matching.
87
- */
88
- async prepare(
89
- preparationContext: PreparationContext<TContext>
90
- ): Promise<PreparationResult<TContext>> {
91
- const iterations: IterationState[] = [];
92
- let currentContext = { ...preparationContext.context };
93
- const allToolExecutions: ToolExecutionResult[] = [];
94
- let preparedToRespond = false;
95
-
96
- // Run preparation iterations
97
- for (
98
- let i = 0;
99
- i < preparationContext.maxIterations && !preparedToRespond;
100
- i++
101
- ) {
102
- const iteration = await this.runIteration({
103
- iterationNumber: i + 1,
104
- history: preparationContext.history,
105
- currentState: preparationContext.currentState,
106
- context: currentContext,
107
- routes: preparationContext.routes,
108
- guidelines: preparationContext.guidelines,
109
- });
110
-
111
- iterations.push(iteration);
112
- allToolExecutions.push(...iteration.executedTools);
113
-
114
- // Update context from tool results
115
- if (Object.keys(iteration.contextUpdates).length > 0) {
116
- currentContext = {
117
- ...currentContext,
118
- ...iteration.contextUpdates,
119
- } as TContext;
120
- }
121
-
122
- // Check if we're prepared to respond
123
- // We're prepared if:
124
- // 1. No tools were executed in this iteration (nothing left to do)
125
- // 2. OR we've reached max iterations
126
- // 3. OR iteration explicitly set preparedToRespond to true
127
- if (
128
- iteration.executedTools.length === 0 ||
129
- i === preparationContext.maxIterations - 1 ||
130
- iteration.preparedToRespond
131
- ) {
132
- preparedToRespond = true;
133
- }
134
- }
135
-
136
- return {
137
- iterations,
138
- finalContext: currentContext,
139
- toolExecutions: allToolExecutions,
140
- preparedToRespond,
141
- };
142
- }
143
-
144
- /**
145
- * Run a single preparation iteration
146
- */
147
- private async runIteration(params: {
148
- iterationNumber: number;
149
- history: Event[];
150
- currentState?: StateRef;
151
- context: TContext;
152
- routes: Route<TContext>[];
153
- guidelines: Guideline[];
154
- }): Promise<IterationState> {
155
- const executedTools: ToolExecutionResult[] = [];
156
- const contextUpdates: Record<string, unknown> = {};
157
- const matchedGuidelines: GuidelineMatch[] = [];
158
-
159
- // Step 1: Match guidelines against current context
160
- const matchedResults = await this.matchGuidelines(
161
- params.guidelines,
162
- params.context,
163
- params.history
164
- );
165
- matchedGuidelines.push(...matchedResults);
166
-
167
- // Step 2: Execute tools from matched guidelines
168
- // Guidelines with associated tools should execute those tools
169
- for (const match of matchedGuidelines) {
170
- if (match.guideline.tools && match.guideline.tools.length > 0) {
171
- for (const tool of match.guideline.tools) {
172
- const toolResult = await this.executeTool(
173
- tool as ToolRef<TContext, unknown[], unknown>,
174
- params.context,
175
- params.history
176
- );
177
- if (toolResult) {
178
- executedTools.push(toolResult);
179
-
180
- // Update context from tool result if tool provided context updates
181
- if (toolResult.result && typeof toolResult.result === "object") {
182
- const result = toolResult.result as Record<string, unknown>;
183
- if (result.contextUpdate) {
184
- Object.assign(contextUpdates, result.contextUpdate);
185
- }
186
- }
187
- }
188
- }
189
- }
190
- }
191
-
192
- // Step 3: Walk state machine and execute tool transitions
193
- // Find current route and state, then execute any toolState transitions
194
- if (params.currentState?.id) {
195
- const currentRoute = params.routes.find(
196
- (r) => r.id === params.currentState!.routeId
197
- );
198
-
199
- if (currentRoute) {
200
- const toolResults = await this.executeStateToolTransitions(
201
- currentRoute,
202
- params.currentState,
203
- params.context,
204
- params.history
205
- );
206
- executedTools.push(...toolResults);
207
-
208
- // Update context from state tool results
209
- for (const toolResult of toolResults) {
210
- if (toolResult.result && typeof toolResult.result === "object") {
211
- const result = toolResult.result as Record<string, unknown>;
212
- if (result.contextUpdate) {
213
- Object.assign(contextUpdates, result.contextUpdate);
214
- }
215
- }
216
- }
217
- }
218
- }
219
-
220
- return {
221
- iterationNumber: params.iterationNumber,
222
- matchedGuidelines,
223
- executedTools,
224
- contextUpdates,
225
- preparedToRespond: false, // Will be determined by caller
226
- };
227
- }
228
-
229
- /**
230
- * Match guidelines against current context
231
- *
232
- * Evaluates guideline conditions against the current context and history
233
- * using AI to determine relevance and priority
234
- */
235
- private async matchGuidelines(
236
- guidelines: Guideline[],
237
- context: TContext,
238
- history: Event[]
239
- ): Promise<GuidelineMatch[]> {
240
- const matches: GuidelineMatch[] = [];
241
-
242
- for (const guideline of guidelines) {
243
- // Skip disabled guidelines
244
- if (guideline.enabled === false) {
245
- continue;
246
- }
247
-
248
- // If guideline has no condition, it's always matched
249
- if (!guideline.condition) {
250
- matches.push({
251
- guideline,
252
- rationale: "Guideline has no condition - always active",
253
- });
254
- continue;
255
- }
256
-
257
- // Evaluate condition using AI if evaluator is available
258
- if (!this.conditionEvaluator) {
259
- // No AI available, match all enabled guidelines with conditions
260
- matches.push({
261
- guideline,
262
- rationale: "AI not available - defaulting to match",
263
- });
264
- continue;
265
- }
266
-
267
- const evaluation =
268
- await this.conditionEvaluator.evaluateGuidelineCondition(
269
- guideline,
270
- context,
271
- history
272
- );
273
-
274
- if (evaluation.matches) {
275
- matches.push({
276
- guideline,
277
- rationale: evaluation.rationale || "Condition evaluated as true",
278
- });
279
- }
280
- }
281
-
282
- return matches;
283
- }
284
-
285
- /**
286
- * Execute a single tool
287
- */
288
- private async executeTool(
289
- tool: ToolRef<TContext, unknown[], unknown>,
290
- context: TContext,
291
- history: Event[]
292
- ): Promise<ToolExecutionResult | null> {
293
- try {
294
- // Extract arguments from context and history
295
- let args: unknown[];
296
-
297
- if (this.conditionEvaluator && tool.parameters) {
298
- // Use AI-powered extraction if available
299
- const extraction = await this.conditionEvaluator.extractToolArguments(
300
- tool,
301
- context,
302
- history
303
- );
304
- args = extraction.arguments;
305
- } else {
306
- // Fallback to simple extraction
307
- args = this.conditionEvaluator
308
- ? this.conditionEvaluator.simpleArgumentExtraction(tool, context)
309
- : [];
310
- }
311
-
312
- // Execute the tool handler
313
- const result = await tool.handler(
314
- {
315
- context,
316
- history,
317
- updateContext: async (_updates: Partial<TContext>) => {
318
- // Context updates are handled separately in the preparation loop
319
- // This is a no-op placeholder
320
- },
321
- },
322
- ...args
323
- );
324
-
325
- return {
326
- toolName: tool.name,
327
- arguments: { args }, // Wrap array in object for logging
328
- result,
329
- success: true,
330
- };
331
- } catch (error) {
332
- console.error(
333
- `[PreparationEngine] Tool execution failed: ${tool.name}`,
334
- error
335
- );
336
- return {
337
- toolName: tool.name,
338
- arguments: {},
339
- result: null,
340
- success: false,
341
- error: error instanceof Error ? error.message : String(error),
342
- };
343
- }
344
- }
345
-
346
- /**
347
- * Execute tool transitions in the state machine
348
- *
349
- * Walks through state transitions and executes tools when
350
- * reaching a { toolState: tool } transition
351
- */
352
- private async executeStateToolTransitions(
353
- route: Route<TContext>,
354
- currentStateRef: StateRef,
355
- context: TContext,
356
- history: Event[]
357
- ): Promise<ToolExecutionResult[]> {
358
- const executedTools: ToolExecutionResult[] = [];
359
-
360
- // Get the current state from the route or use initial state
361
- let stateToWalk: State<TContext>;
362
-
363
- try {
364
- const foundState = route.getState(currentStateRef.id);
365
- if (foundState) {
366
- stateToWalk = foundState;
367
- } else {
368
- stateToWalk = route.initialState;
369
- }
370
- } catch {
371
- // If any error occurs, fallback to initial state
372
- stateToWalk = route.initialState;
373
- }
374
-
375
- // Walk the state machine starting from the determined state
376
- const toolResults = await this.walkStateChain(
377
- stateToWalk,
378
- context,
379
- history,
380
- new Set() // Track visited states to prevent loops
381
- );
382
-
383
- executedTools.push(...toolResults);
384
-
385
- return executedTools;
386
- }
387
-
388
- /**
389
- * Walk through a chain of states, executing tools along the way
390
- */
391
- private async walkStateChain(
392
- state: State<TContext>,
393
- context: TContext,
394
- history: Event[],
395
- visited: Set<string>
396
- ): Promise<ToolExecutionResult[]> {
397
- const executedTools: ToolExecutionResult[] = [];
398
-
399
- // Prevent infinite loops
400
- if (visited.has(state.id)) {
401
- return executedTools;
402
- }
403
- visited.add(state.id);
404
-
405
- // Get all transitions from this state
406
- const transitions = state.getTransitions();
407
-
408
- // Process each transition
409
- for (const transition of transitions) {
410
- // Check if transition has a condition
411
- if (transition.hasCondition()) {
412
- // Evaluate condition
413
- const shouldFollow = await this.evaluateTransitionCondition(
414
- transition,
415
- context,
416
- history
417
- );
418
-
419
- if (!shouldFollow) {
420
- continue; // Skip this transition
421
- }
422
- }
423
-
424
- // Check if this is a toolState transition
425
- if (transition.spec.toolState) {
426
- // Execute the tool
427
- const toolResult = await this.executeTool(
428
- transition.spec.toolState,
429
- context,
430
- history
431
- );
432
-
433
- if (toolResult) {
434
- executedTools.push(toolResult);
435
-
436
- // Update context with tool results for next transitions
437
- if (toolResult.result && typeof toolResult.result === "object") {
438
- const result = toolResult.result as Record<string, unknown>;
439
- if (result.contextUpdate) {
440
- context = {
441
- ...context,
442
- ...(result.contextUpdate as Partial<TContext>),
443
- };
444
- }
445
- }
446
- }
447
- }
448
-
449
- // Get the target state and recursively walk it
450
- const targetState = transition.getTarget();
451
- if (targetState && !visited.has(targetState.id)) {
452
- const childResults = await this.walkStateChain(
453
- targetState,
454
- context,
455
- history,
456
- visited
457
- );
458
- executedTools.push(...childResults);
459
- }
460
- }
461
-
462
- return executedTools;
463
- }
464
-
465
- /**
466
- * Evaluate a transition condition
467
- */
468
- private async evaluateTransitionCondition(
469
- transition: { condition?: string },
470
- context: TContext,
471
- history: Event[]
472
- ): Promise<boolean> {
473
- if (!transition.condition) {
474
- return true; // No condition = always follow
475
- }
476
-
477
- // If no AI evaluator available, default to true
478
- if (!this.conditionEvaluator) {
479
- return true;
480
- }
481
-
482
- try {
483
- const evaluation =
484
- await this.conditionEvaluator.evaluateTransitionCondition(
485
- transition.condition,
486
- context,
487
- history
488
- );
489
-
490
- return evaluation.shouldFollow;
491
- } catch (error) {
492
- console.error(
493
- `[PreparationEngine] Failed to evaluate transition condition`,
494
- error
495
- );
496
- // On error, default to false (don't follow)
497
- return false;
498
- }
499
- }
500
- }