@falai/agent 1.1.3 → 1.2.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 (193) hide show
  1. package/README.md +9 -0
  2. package/dist/cjs/core/Agent.d.ts +17 -1
  3. package/dist/cjs/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/core/Agent.js +47 -0
  5. package/dist/cjs/core/Agent.js.map +1 -1
  6. package/dist/cjs/core/BatchPromptBuilder.d.ts +3 -0
  7. package/dist/cjs/core/BatchPromptBuilder.d.ts.map +1 -1
  8. package/dist/cjs/core/BatchPromptBuilder.js +4 -1
  9. package/dist/cjs/core/BatchPromptBuilder.js.map +1 -1
  10. package/dist/cjs/core/CompactionEngine.d.ts +65 -0
  11. package/dist/cjs/core/CompactionEngine.d.ts.map +1 -0
  12. package/dist/cjs/core/CompactionEngine.js +251 -0
  13. package/dist/cjs/core/CompactionEngine.js.map +1 -0
  14. package/dist/cjs/core/PromptComposer.d.ts +8 -1
  15. package/dist/cjs/core/PromptComposer.d.ts.map +1 -1
  16. package/dist/cjs/core/PromptComposer.js +238 -126
  17. package/dist/cjs/core/PromptComposer.js.map +1 -1
  18. package/dist/cjs/core/PromptSectionCache.d.ts +57 -0
  19. package/dist/cjs/core/PromptSectionCache.d.ts.map +1 -0
  20. package/dist/cjs/core/PromptSectionCache.js +108 -0
  21. package/dist/cjs/core/PromptSectionCache.js.map +1 -0
  22. package/dist/cjs/core/ResponseEngine.d.ts +3 -2
  23. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
  24. package/dist/cjs/core/ResponseEngine.js +8 -8
  25. package/dist/cjs/core/ResponseEngine.js.map +1 -1
  26. package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
  27. package/dist/cjs/core/ResponseModal.js +120 -70
  28. package/dist/cjs/core/ResponseModal.js.map +1 -1
  29. package/dist/cjs/core/ResponsePipeline.d.ts +2 -1
  30. package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -1
  31. package/dist/cjs/core/ResponsePipeline.js +17 -19
  32. package/dist/cjs/core/ResponsePipeline.js.map +1 -1
  33. package/dist/cjs/core/RoutingEngine.d.ts +10 -0
  34. package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
  35. package/dist/cjs/core/RoutingEngine.js +5 -4
  36. package/dist/cjs/core/RoutingEngine.js.map +1 -1
  37. package/dist/cjs/core/SessionManager.d.ts.map +1 -1
  38. package/dist/cjs/core/SessionManager.js +20 -0
  39. package/dist/cjs/core/SessionManager.js.map +1 -1
  40. package/dist/cjs/core/StreamingToolExecutor.d.ts +142 -0
  41. package/dist/cjs/core/StreamingToolExecutor.d.ts.map +1 -0
  42. package/dist/cjs/core/StreamingToolExecutor.js +455 -0
  43. package/dist/cjs/core/StreamingToolExecutor.js.map +1 -0
  44. package/dist/cjs/core/ToolManager.d.ts +18 -1
  45. package/dist/cjs/core/ToolManager.d.ts.map +1 -1
  46. package/dist/cjs/core/ToolManager.js +91 -0
  47. package/dist/cjs/core/ToolManager.js.map +1 -1
  48. package/dist/cjs/index.d.ts +5 -1
  49. package/dist/cjs/index.d.ts.map +1 -1
  50. package/dist/cjs/index.js +8 -2
  51. package/dist/cjs/index.js.map +1 -1
  52. package/dist/cjs/providers/AnthropicProvider.d.ts +7 -0
  53. package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
  54. package/dist/cjs/providers/AnthropicProvider.js +109 -19
  55. package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
  56. package/dist/cjs/providers/GeminiProvider.d.ts +32 -0
  57. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  58. package/dist/cjs/providers/GeminiProvider.js +160 -53
  59. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  60. package/dist/cjs/providers/OpenAIProvider.d.ts +5 -0
  61. package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
  62. package/dist/cjs/providers/OpenAIProvider.js +65 -18
  63. package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
  64. package/dist/cjs/providers/OpenRouterProvider.d.ts +5 -0
  65. package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
  66. package/dist/cjs/providers/OpenRouterProvider.js +57 -18
  67. package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
  68. package/dist/cjs/types/agent.d.ts +44 -0
  69. package/dist/cjs/types/agent.d.ts.map +1 -1
  70. package/dist/cjs/types/agent.js.map +1 -1
  71. package/dist/cjs/types/ai.d.ts +2 -2
  72. package/dist/cjs/types/ai.d.ts.map +1 -1
  73. package/dist/cjs/types/compaction.d.ts +50 -0
  74. package/dist/cjs/types/compaction.d.ts.map +1 -0
  75. package/dist/cjs/types/compaction.js +6 -0
  76. package/dist/cjs/types/compaction.js.map +1 -0
  77. package/dist/cjs/types/index.d.ts +4 -2
  78. package/dist/cjs/types/index.d.ts.map +1 -1
  79. package/dist/cjs/types/index.js.map +1 -1
  80. package/dist/cjs/types/tool.d.ts +84 -0
  81. package/dist/cjs/types/tool.d.ts.map +1 -1
  82. package/dist/core/Agent.d.ts +17 -1
  83. package/dist/core/Agent.d.ts.map +1 -1
  84. package/dist/core/Agent.js +47 -0
  85. package/dist/core/Agent.js.map +1 -1
  86. package/dist/core/BatchPromptBuilder.d.ts +3 -0
  87. package/dist/core/BatchPromptBuilder.d.ts.map +1 -1
  88. package/dist/core/BatchPromptBuilder.js +4 -1
  89. package/dist/core/BatchPromptBuilder.js.map +1 -1
  90. package/dist/core/CompactionEngine.d.ts +65 -0
  91. package/dist/core/CompactionEngine.d.ts.map +1 -0
  92. package/dist/core/CompactionEngine.js +244 -0
  93. package/dist/core/CompactionEngine.js.map +1 -0
  94. package/dist/core/PromptComposer.d.ts +8 -1
  95. package/dist/core/PromptComposer.d.ts.map +1 -1
  96. package/dist/core/PromptComposer.js +238 -126
  97. package/dist/core/PromptComposer.js.map +1 -1
  98. package/dist/core/PromptSectionCache.d.ts +57 -0
  99. package/dist/core/PromptSectionCache.d.ts.map +1 -0
  100. package/dist/core/PromptSectionCache.js +104 -0
  101. package/dist/core/PromptSectionCache.js.map +1 -0
  102. package/dist/core/ResponseEngine.d.ts +3 -2
  103. package/dist/core/ResponseEngine.d.ts.map +1 -1
  104. package/dist/core/ResponseEngine.js +8 -8
  105. package/dist/core/ResponseEngine.js.map +1 -1
  106. package/dist/core/ResponseModal.d.ts.map +1 -1
  107. package/dist/core/ResponseModal.js +121 -71
  108. package/dist/core/ResponseModal.js.map +1 -1
  109. package/dist/core/ResponsePipeline.d.ts +2 -1
  110. package/dist/core/ResponsePipeline.d.ts.map +1 -1
  111. package/dist/core/ResponsePipeline.js +18 -20
  112. package/dist/core/ResponsePipeline.js.map +1 -1
  113. package/dist/core/RoutingEngine.d.ts +10 -0
  114. package/dist/core/RoutingEngine.d.ts.map +1 -1
  115. package/dist/core/RoutingEngine.js +6 -5
  116. package/dist/core/RoutingEngine.js.map +1 -1
  117. package/dist/core/SessionManager.d.ts.map +1 -1
  118. package/dist/core/SessionManager.js +17 -0
  119. package/dist/core/SessionManager.js.map +1 -1
  120. package/dist/core/StreamingToolExecutor.d.ts +142 -0
  121. package/dist/core/StreamingToolExecutor.d.ts.map +1 -0
  122. package/dist/core/StreamingToolExecutor.js +448 -0
  123. package/dist/core/StreamingToolExecutor.js.map +1 -0
  124. package/dist/core/ToolManager.d.ts +18 -1
  125. package/dist/core/ToolManager.d.ts.map +1 -1
  126. package/dist/core/ToolManager.js +91 -0
  127. package/dist/core/ToolManager.js.map +1 -1
  128. package/dist/index.d.ts +5 -1
  129. package/dist/index.d.ts.map +1 -1
  130. package/dist/index.js +3 -0
  131. package/dist/index.js.map +1 -1
  132. package/dist/providers/AnthropicProvider.d.ts +7 -0
  133. package/dist/providers/AnthropicProvider.d.ts.map +1 -1
  134. package/dist/providers/AnthropicProvider.js +109 -19
  135. package/dist/providers/AnthropicProvider.js.map +1 -1
  136. package/dist/providers/GeminiProvider.d.ts +32 -0
  137. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  138. package/dist/providers/GeminiProvider.js +160 -53
  139. package/dist/providers/GeminiProvider.js.map +1 -1
  140. package/dist/providers/OpenAIProvider.d.ts +5 -0
  141. package/dist/providers/OpenAIProvider.d.ts.map +1 -1
  142. package/dist/providers/OpenAIProvider.js +65 -18
  143. package/dist/providers/OpenAIProvider.js.map +1 -1
  144. package/dist/providers/OpenRouterProvider.d.ts +5 -0
  145. package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
  146. package/dist/providers/OpenRouterProvider.js +57 -18
  147. package/dist/providers/OpenRouterProvider.js.map +1 -1
  148. package/dist/types/agent.d.ts +44 -0
  149. package/dist/types/agent.d.ts.map +1 -1
  150. package/dist/types/agent.js.map +1 -1
  151. package/dist/types/ai.d.ts +2 -2
  152. package/dist/types/ai.d.ts.map +1 -1
  153. package/dist/types/compaction.d.ts +50 -0
  154. package/dist/types/compaction.d.ts.map +1 -0
  155. package/dist/types/compaction.js +5 -0
  156. package/dist/types/compaction.js.map +1 -0
  157. package/dist/types/index.d.ts +4 -2
  158. package/dist/types/index.d.ts.map +1 -1
  159. package/dist/types/index.js.map +1 -1
  160. package/dist/types/tool.d.ts +84 -0
  161. package/dist/types/tool.d.ts.map +1 -1
  162. package/docs/api/overview.md +140 -0
  163. package/docs/core/tools/enhanced-tool.md +186 -0
  164. package/docs/core/tools/streaming-execution.md +161 -0
  165. package/docs/guides/context-compaction.md +96 -0
  166. package/docs/guides/prompt-optimization.md +164 -0
  167. package/examples/advanced-patterns/context-compaction.ts +223 -0
  168. package/examples/advanced-patterns/streaming-responses.ts +85 -7
  169. package/examples/tools/enhanced-tool-metadata.ts +268 -0
  170. package/examples/tools/streaming-tool-execution.ts +283 -0
  171. package/package.json +1 -1
  172. package/src/core/Agent.ts +58 -2
  173. package/src/core/BatchPromptBuilder.ts +4 -1
  174. package/src/core/CompactionEngine.ts +318 -0
  175. package/src/core/PromptComposer.ts +259 -156
  176. package/src/core/PromptSectionCache.ts +136 -0
  177. package/src/core/ResponseEngine.ts +7 -11
  178. package/src/core/ResponseModal.ts +133 -83
  179. package/src/core/ResponsePipeline.ts +22 -22
  180. package/src/core/RoutingEngine.ts +16 -5
  181. package/src/core/SessionManager.ts +19 -0
  182. package/src/core/StreamingToolExecutor.ts +572 -0
  183. package/src/core/ToolManager.ts +151 -41
  184. package/src/index.ts +14 -0
  185. package/src/providers/AnthropicProvider.ts +121 -24
  186. package/src/providers/GeminiProvider.ts +174 -54
  187. package/src/providers/OpenAIProvider.ts +77 -25
  188. package/src/providers/OpenRouterProvider.ts +68 -25
  189. package/src/types/agent.ts +45 -0
  190. package/src/types/ai.ts +2 -2
  191. package/src/types/compaction.ts +52 -0
  192. package/src/types/index.ts +35 -14
  193. package/src/types/tool.ts +108 -0
@@ -2,13 +2,12 @@
2
2
  * ResponseModal handles all response generation logic for the Agent
3
3
  * Provides both streaming and non-streaming response generation with unified logic
4
4
  */
5
- import { EventKind, MessageRole } from "../types";
6
5
  import { Step } from "./Step";
7
6
  import { ResponseEngine } from "./ResponseEngine";
8
7
  import { ResponsePipeline } from "./ResponsePipeline";
9
8
  import { BatchExecutor } from "./BatchExecutor";
10
9
  import { BatchPromptBuilder } from "./BatchPromptBuilder";
11
- import { cloneDeep, mergeCollected, enterStep, getLastMessageFromHistory, render, logger, historyToEvents } from "../utils";
10
+ import { cloneDeep, mergeCollected, enterStep, getLastMessageFromHistory, render, logger, historyToEvents, eventsToHistory } from "../utils";
12
11
  import { createTemplateContext } from "../utils/template";
13
12
  import { END_ROUTE_ID } from "../constants";
14
13
  /**
@@ -47,14 +46,14 @@ export class ResponseModal {
47
46
  this.agent = agent;
48
47
  this.options = options;
49
48
  // Initialize response engine
50
- this.responseEngine = new ResponseEngine();
49
+ this.responseEngine = new ResponseEngine(this.agent.promptSectionCache);
51
50
  // Initialize response pipeline with agent dependencies
52
51
  this.responsePipeline = new ResponsePipeline(this.agent.getAgentOptions(), () => this.agent.getRoutes(), // Pass a function to get routes dynamically
53
52
  this.agent.getTools(), this.agent.getRoutingEngine(), this.agent.updateContext.bind(this.agent), this.agent.getUpdateDataMethod(), this.agent.updateCollectedData.bind(this.agent), this.getToolManager());
54
53
  // Initialize batch executor for multi-step execution
55
54
  this.batchExecutor = new BatchExecutor();
56
55
  // Initialize batch prompt builder for combined prompts
57
- this.batchPromptBuilder = new BatchPromptBuilder();
56
+ this.batchPromptBuilder = new BatchPromptBuilder(this.agent.promptSectionCache);
58
57
  }
59
58
  /**
60
59
  * Generate a non-streaming response using unified logic
@@ -443,12 +442,14 @@ export class ResponseModal {
443
442
  extractionPrompt.push(`Optional fields: ${route.optionalFields.join(', ')}`);
444
443
  }
445
444
  extractionPrompt.push(``, `Return ONLY the extracted data as JSON. If no data can be extracted, return an empty object {}.`);
445
+ // Convert Event[] to HistoryItem[] for provider call
446
+ const historyItems = eventsToHistory(history);
446
447
  // Call AI to extract data
447
448
  const agentOptions = this.agent.getAgentOptions();
448
449
  try {
449
450
  const result = await agentOptions.provider.generateMessage({
450
451
  prompt: extractionPrompt.join('\n'),
451
- history,
452
+ history: historyItems,
452
453
  context: {}, // Passed as empty object so AI doesn't "extract" from context
453
454
  // NOTE: context is intentionally NOT passed here.
454
455
  // Passing context caused the AI to "extract" data from the lead's context
@@ -476,7 +477,6 @@ export class ResponseModal {
476
477
  // Get last user message (needed for both route and completion handling)
477
478
  // Convert HistoryItem[] to Event[] for internal processing
478
479
  const historyEvents = historyToEvents(history);
479
- const lastMessageText = getLastMessageFromHistory(historyEvents);
480
480
  let message;
481
481
  let toolCalls = undefined;
482
482
  let executedSteps;
@@ -511,7 +511,6 @@ export class ResponseModal {
511
511
  session,
512
512
  history,
513
513
  context: effectiveContext,
514
- lastMessageText,
515
514
  historyEvents,
516
515
  signal: undefined,
517
516
  });
@@ -536,7 +535,7 @@ export class ResponseModal {
536
535
  selectedRoute,
537
536
  session,
538
537
  context: effectiveContext,
539
- lastMessageText,
538
+ history,
540
539
  historyEvents,
541
540
  signal: undefined,
542
541
  });
@@ -556,7 +555,7 @@ export class ResponseModal {
556
555
  else {
557
556
  // Fallback: No routes defined, generate a simple response
558
557
  message = await this.generateFallbackResponse({
559
- history: historyEvents, // Use Event[] for fallback response
558
+ history,
560
559
  context: effectiveContext,
561
560
  session,
562
561
  });
@@ -642,7 +641,7 @@ export class ResponseModal {
642
641
  const agentOptions = this.agent.getAgentOptions();
643
642
  const result = await agentOptions.provider.generateMessage({
644
643
  prompt: batchPromptResult.prompt,
645
- history: historyEvents,
644
+ history, // Use HistoryItem[] for AI provider
646
645
  context,
647
646
  tools: availableTools,
648
647
  signal,
@@ -798,7 +797,6 @@ export class ResponseModal {
798
797
  // Get last user message (needed for both route and completion handling)
799
798
  // Convert HistoryItem[] to Event[] for internal processing
800
799
  const historyEvents = historyToEvents(history);
801
- const lastMessageText = getLastMessageFromHistory(historyEvents);
802
800
  if (selectedRoute && !isRouteComplete) {
803
801
  // Check if we have batch steps to execute
804
802
  if (batchSteps && batchSteps.length > 0) {
@@ -825,7 +823,6 @@ export class ResponseModal {
825
823
  session,
826
824
  history,
827
825
  context: effectiveContext,
828
- lastMessageText,
829
826
  historyEvents,
830
827
  });
831
828
  }
@@ -836,14 +833,14 @@ export class ResponseModal {
836
833
  selectedRoute,
837
834
  session,
838
835
  context: effectiveContext,
839
- lastMessageText,
836
+ history,
840
837
  historyEvents,
841
838
  });
842
839
  }
843
840
  else {
844
841
  // Fallback: No routes defined, stream a simple response
845
842
  yield* this.streamFallbackResponse({
846
- history: historyEvents, // Use Event[] for fallback response
843
+ history,
847
844
  context: effectiveContext,
848
845
  session,
849
846
  });
@@ -857,7 +854,7 @@ export class ResponseModal {
857
854
  * @private
858
855
  */
859
856
  async *streamBatchResponse(params) {
860
- const { selectedRoute, batchSteps, context, historyEvents, batchStoppedReason, signal } = params;
857
+ const { selectedRoute, batchSteps, history, context, historyEvents, batchStoppedReason, signal } = params;
861
858
  let session = params.session;
862
859
  // Create hook executor function
863
860
  const executeHook = async (hook, hookContext, data, step) => {
@@ -898,7 +895,7 @@ export class ResponseModal {
898
895
  const agentOptions = this.agent.getAgentOptions();
899
896
  const stream = agentOptions.provider.generateMessageStream({
900
897
  prompt: batchPromptResult.prompt,
901
- history: historyEvents,
898
+ history, // Use HistoryItem[] for AI provider
902
899
  context,
903
900
  tools: availableTools,
904
901
  signal,
@@ -994,7 +991,7 @@ export class ResponseModal {
994
991
  * @private
995
992
  */
996
993
  async processRouteResponse(params) {
997
- const { selectedRoute, selectedStep, responseDirectives, history, context, lastMessageText, historyEvents, signal } = params;
994
+ const { selectedRoute, selectedStep, responseDirectives, history, context, historyEvents, signal } = params;
998
995
  let session = params.session;
999
996
  // Determine next step
1000
997
  let nextStep;
@@ -1061,8 +1058,7 @@ export class ResponseModal {
1061
1058
  rules: selectedRoute.getRules(),
1062
1059
  prohibitions: selectedRoute.getProhibitions(),
1063
1060
  directives: responseDirectives,
1064
- history: historyEvents, // Use Event[] for buildResponsePrompt
1065
- lastMessage: lastMessageText, // Use string for buildResponsePrompt
1061
+ history: historyEvents,
1066
1062
  agentOptions: this.agent.getAgentOptions(),
1067
1063
  combinedGuidelines: [...this.agent.getGuidelines(), ...selectedRoute.getGuidelines()],
1068
1064
  combinedTerms: this.mergeTerms(this.agent.getTerms(), selectedRoute.getTerms()),
@@ -1076,7 +1072,7 @@ export class ResponseModal {
1076
1072
  const agentOptions = this.agent.getAgentOptions();
1077
1073
  const result = await agentOptions.provider.generateMessage({
1078
1074
  prompt: responsePrompt,
1079
- history: historyEvents, // Use Event[] for AI provider
1075
+ history, // Use HistoryItem[] for AI provider
1080
1076
  context,
1081
1077
  tools: availableTools,
1082
1078
  signal,
@@ -1118,7 +1114,7 @@ export class ResponseModal {
1118
1114
  * @private
1119
1115
  */
1120
1116
  async *processRouteStreamingResponse(params) {
1121
- const { selectedRoute, selectedStep, responseDirectives, history, context, lastMessageText, historyEvents, signal } = params;
1117
+ const { selectedRoute, selectedStep, responseDirectives, history, context, historyEvents, signal } = params;
1122
1118
  let session = params.session;
1123
1119
  // Determine next step (same logic as non-streaming)
1124
1120
  let nextStep;
@@ -1179,8 +1175,7 @@ export class ResponseModal {
1179
1175
  rules: selectedRoute.getRules(),
1180
1176
  prohibitions: selectedRoute.getProhibitions(),
1181
1177
  directives: responseDirectives,
1182
- history: historyEvents, // Use Event[] for buildResponsePrompt
1183
- lastMessage: lastMessageText, // Use string for buildResponsePrompt
1178
+ history: historyEvents,
1184
1179
  agentOptions: this.agent.getAgentOptions(),
1185
1180
  combinedGuidelines: [...this.agent.getGuidelines(), ...selectedRoute.getGuidelines()],
1186
1181
  combinedTerms: this.mergeTerms(this.agent.getTerms(), selectedRoute.getTerms()),
@@ -1194,7 +1189,7 @@ export class ResponseModal {
1194
1189
  const agentOptions = this.agent.getAgentOptions();
1195
1190
  const stream = agentOptions.provider.generateMessageStream({
1196
1191
  prompt: responsePrompt,
1197
- history: historyEvents, // Use Event[] for AI provider
1192
+ history, // Use HistoryItem[] for AI provider
1198
1193
  context,
1199
1194
  tools: availableTools,
1200
1195
  signal,
@@ -1206,20 +1201,79 @@ export class ResponseModal {
1206
1201
  // Extract tool calls from AI response on final chunk
1207
1202
  if (chunk.done && chunk.structured?.toolCalls) {
1208
1203
  toolCalls = chunk.structured.toolCalls;
1209
- // Execute tools with unified loop handling
1210
- const toolResult = await this.executeUnifiedToolLoop({
1211
- toolCalls,
1212
- context,
1213
- session,
1214
- history,
1215
- selectedRoute,
1216
- responsePrompt,
1217
- availableTools,
1218
- responseSchema,
1219
- signal,
1220
- });
1221
- session = toolResult.session;
1222
- toolCalls = toolResult.finalToolCalls;
1204
+ const toolManager = this.getToolManager();
1205
+ // Use concurrent execution for the initial batch of tool calls
1206
+ if (toolManager && typeof toolManager.executeWithConcurrency === 'function') {
1207
+ const toolCallRequests = toolCalls.map((tc, i) => ({
1208
+ id: `${tc.toolName}-${i}-${Date.now()}`,
1209
+ toolName: tc.toolName,
1210
+ arguments: tc.arguments,
1211
+ }));
1212
+ const historyEvents = historyToEvents(history);
1213
+ try {
1214
+ for await (const update of toolManager.executeWithConcurrency({
1215
+ toolCalls: toolCallRequests,
1216
+ context,
1217
+ data: session.data,
1218
+ history: historyEvents,
1219
+ signal,
1220
+ route: selectedRoute,
1221
+ step: nextStep,
1222
+ })) {
1223
+ // Apply context updates
1224
+ if (update.contextUpdate) {
1225
+ try {
1226
+ await this.agent.updateContext(update.contextUpdate);
1227
+ }
1228
+ catch (error) {
1229
+ logger.error(`[ResponseModal] Failed to update context from concurrent tool:`, error);
1230
+ }
1231
+ }
1232
+ // Apply data updates
1233
+ if (update.dataUpdate) {
1234
+ try {
1235
+ const updateDataMethod = this.agent.getUpdateDataMethod();
1236
+ session = await updateDataMethod(session, update.dataUpdate);
1237
+ }
1238
+ catch (error) {
1239
+ logger.error(`[ResponseModal] Failed to update data from concurrent tool:`, error);
1240
+ }
1241
+ }
1242
+ // Yield progress updates immediately
1243
+ if (update.progress) {
1244
+ yield {
1245
+ delta: '',
1246
+ accumulated: chunk.accumulated,
1247
+ done: false,
1248
+ session,
1249
+ toolCalls: undefined,
1250
+ isRouteComplete: false,
1251
+ metadata: { toolProgress: update.progress, toolCallId: update.toolCallId },
1252
+ };
1253
+ }
1254
+ }
1255
+ logger.debug(`[ResponseModal] Concurrent tool execution completed for ${toolCallRequests.length} tools`);
1256
+ }
1257
+ catch (error) {
1258
+ logger.error(`[ResponseModal] Concurrent tool execution failed, falling back to sequential:`, error);
1259
+ // Fall back to the unified tool loop on failure
1260
+ const toolResult = await this.executeUnifiedToolLoop({
1261
+ toolCalls, context, session, history, selectedRoute,
1262
+ responsePrompt, availableTools, responseSchema, signal,
1263
+ });
1264
+ session = toolResult.session;
1265
+ toolCalls = toolResult.finalToolCalls;
1266
+ }
1267
+ }
1268
+ else {
1269
+ // Fallback: no ToolManager or no executeWithConcurrency, use unified tool loop
1270
+ const toolResult = await this.executeUnifiedToolLoop({
1271
+ toolCalls, context, session, history, selectedRoute,
1272
+ responsePrompt, availableTools, responseSchema, signal,
1273
+ });
1274
+ session = toolResult.session;
1275
+ toolCalls = toolResult.finalToolCalls;
1276
+ }
1223
1277
  }
1224
1278
  // Extract collected data on final chunk
1225
1279
  if (chunk.done && chunk.structured && nextStep.collect) {
@@ -1336,33 +1390,33 @@ export class ResponseModal {
1336
1390
  while (hasToolCalls && toolLoopCount < MAX_TOOL_LOOPS) {
1337
1391
  toolLoopCount++;
1338
1392
  logger.debug(`[ResponseModal] Starting tool loop ${toolLoopCount}/${MAX_TOOL_LOOPS} with ${toolCalls?.length || 0} tool calls`);
1339
- // Create tool result events with proper Event format structure
1340
- const toolResultEvents = [];
1393
+ // Create tool result history items
1394
+ const toolResultHistoryItems = [];
1341
1395
  for (const toolCall of toolCalls || []) {
1342
1396
  const tool = this.findAvailableTool(toolCall.toolName, selectedRoute);
1343
1397
  if (tool) {
1344
- // Create proper Event format for tool results
1345
- const toolResultEvent = {
1346
- kind: EventKind.TOOL,
1347
- source: MessageRole.AGENT,
1348
- timestamp: new Date().toISOString(),
1349
- data: {
1350
- tool_calls: [
1351
- {
1352
- tool_id: toolCall.toolName,
1353
- arguments: toolCall.arguments,
1354
- result: {
1355
- data: "Tool executed successfully",
1356
- },
1357
- },
1358
- ],
1359
- },
1360
- };
1361
- toolResultEvents.push(toolResultEvent);
1398
+ // Create HistoryItem format for tool results
1399
+ // Add assistant message with tool_calls
1400
+ toolResultHistoryItems.push({
1401
+ role: "assistant",
1402
+ content: null,
1403
+ tool_calls: [{
1404
+ id: toolCall.toolName,
1405
+ name: toolCall.toolName,
1406
+ arguments: toolCall.arguments,
1407
+ }],
1408
+ });
1409
+ // Add tool result
1410
+ toolResultHistoryItems.push({
1411
+ role: "tool",
1412
+ tool_call_id: toolCall.toolName,
1413
+ name: toolCall.toolName,
1414
+ content: "Tool executed successfully",
1415
+ });
1362
1416
  }
1363
1417
  }
1364
- // Create updated history with tool results (combine Event arrays)
1365
- const updatedHistoryEvents = [...historyEvents, ...toolResultEvents];
1418
+ // Create updated history with tool results
1419
+ const updatedHistory = [...history, ...toolResultHistoryItems];
1366
1420
  // Make follow-up AI call to see if more tools are needed
1367
1421
  // After first iteration, don't provide tools to force a text response
1368
1422
  const agentOptions = this.agent.getAgentOptions();
@@ -1374,7 +1428,7 @@ export class ResponseModal {
1374
1428
  });
1375
1429
  const followUpResult = await agentOptions.provider.generateMessage({
1376
1430
  prompt: responsePrompt + (toolLoopCount > 1 ? "\n\nProvide a text response to the user based on the tool results." : ""),
1377
- history: updatedHistoryEvents, // Use Event[] for AI provider
1431
+ history: updatedHistory, // Use HistoryItem[] for AI provider
1378
1432
  context,
1379
1433
  tools: shouldProvideTools ? availableTools : [], // Only provide tools on first iteration
1380
1434
  parameters: responseSchema ? {
@@ -1412,7 +1466,7 @@ export class ResponseModal {
1412
1466
  context,
1413
1467
  updateContext: this.agent.updateContext.bind(this.agent),
1414
1468
  updateData: this.agent.updateCollectedData.bind(this.agent),
1415
- history: updatedHistoryEvents, // Use Event[] for tool execution
1469
+ history: historyToEvents(updatedHistory), // Convert to Event[] for tool execution
1416
1470
  data: session.data,
1417
1471
  toolArguments: toolCall.arguments,
1418
1472
  });
@@ -1567,7 +1621,7 @@ export class ResponseModal {
1567
1621
  * @private
1568
1622
  */
1569
1623
  async handleRouteCompletion(params) {
1570
- const { selectedRoute, session, context, lastMessageText, historyEvents, signal } = params;
1624
+ const { selectedRoute, session, context, history, historyEvents, signal } = params;
1571
1625
  // Get endStep spec from route
1572
1626
  const endStepSpec = selectedRoute.endStepSpec;
1573
1627
  // Create a temporary step for completion message generation using endStep configuration
@@ -1617,7 +1671,6 @@ export class ResponseModal {
1617
1671
  completitionPrompt,
1618
1672
  ],
1619
1673
  history: historyEvents,
1620
- lastMessage: lastMessageText,
1621
1674
  agentOptions: this.agent.getAgentOptions(),
1622
1675
  combinedGuidelines: alwaysActiveGuidelines, // Only non-conditional guidelines
1623
1676
  combinedTerms: this.mergeTerms(this.agent.getTerms(), selectedRoute.getTerms()),
@@ -1630,7 +1683,7 @@ export class ResponseModal {
1630
1683
  logger.debug(`[ResponseModal] Calling AI provider for completion message...`);
1631
1684
  const completionResult = await agentOptions.provider.generateMessage({
1632
1685
  prompt: completionPrompt,
1633
- history: historyEvents,
1686
+ history, // Use HistoryItem[] for AI provider
1634
1687
  context,
1635
1688
  signal,
1636
1689
  parameters: { jsonSchema: completionSchema, schemaName: "completion_message" },
@@ -1664,7 +1717,7 @@ export class ResponseModal {
1664
1717
  * @private
1665
1718
  */
1666
1719
  async *streamRouteCompletion(params) {
1667
- const { selectedRoute, context, lastMessageText, historyEvents, signal } = params;
1720
+ const { selectedRoute, context, history, historyEvents, signal } = params;
1668
1721
  let session = params.session;
1669
1722
  // Get endStep spec from route
1670
1723
  const endStepSpec = selectedRoute.endStepSpec;
@@ -1686,8 +1739,7 @@ export class ResponseModal {
1686
1739
  rules: selectedRoute.getRules(),
1687
1740
  prohibitions: selectedRoute.getProhibitions(),
1688
1741
  directives: undefined, // No directives for completion
1689
- history: historyEvents, // Use Event[] for buildResponsePrompt
1690
- lastMessage: lastMessageText, // Use string for buildResponsePrompt
1742
+ history: historyEvents,
1691
1743
  agentOptions: this.agent.getAgentOptions(),
1692
1744
  combinedGuidelines: [...this.agent.getGuidelines(), ...selectedRoute.getGuidelines()],
1693
1745
  combinedTerms: this.mergeTerms(this.agent.getTerms(), selectedRoute.getTerms()),
@@ -1699,7 +1751,7 @@ export class ResponseModal {
1699
1751
  const agentOptions = this.agent.getAgentOptions();
1700
1752
  const stream = agentOptions.provider.generateMessageStream({
1701
1753
  prompt: completionPrompt,
1702
- history: historyEvents, // Use Event[] for AI provider
1754
+ history, // Use HistoryItem[] for AI provider
1703
1755
  context,
1704
1756
  signal,
1705
1757
  parameters: { jsonSchema: responseSchema, schemaName: "completion_message_stream" },
@@ -1763,7 +1815,6 @@ export class ResponseModal {
1763
1815
  logger.debug(`[ResponseModal] No route selected, generating basic response`);
1764
1816
  // Build basic response prompt without route context
1765
1817
  const fallbackPrompt = await this.responseEngine.buildFallbackPrompt({
1766
- history,
1767
1818
  agentOptions: this.agent.getAgentOptions(),
1768
1819
  terms: this.agent.getTerms(),
1769
1820
  guidelines: this.agent.getGuidelines(),
@@ -1795,7 +1846,6 @@ export class ResponseModal {
1795
1846
  async *streamFallbackResponse(params) {
1796
1847
  const { history, context, session, signal } = params;
1797
1848
  const fallbackPrompt = await this.responseEngine.buildFallbackPrompt({
1798
- history,
1799
1849
  agentOptions: this.agent.getAgentOptions(),
1800
1850
  terms: this.agent.getTerms(),
1801
1851
  guidelines: this.agent.getGuidelines(),