@falai/agent 1.1.3 → 1.2.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 (173) 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 -0
  23. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
  24. package/dist/cjs/core/ResponseEngine.js +10 -6
  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 +75 -16
  28. package/dist/cjs/core/ResponseModal.js.map +1 -1
  29. package/dist/cjs/core/RoutingEngine.d.ts +10 -0
  30. package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
  31. package/dist/cjs/core/RoutingEngine.js +3 -2
  32. package/dist/cjs/core/RoutingEngine.js.map +1 -1
  33. package/dist/cjs/core/SessionManager.d.ts.map +1 -1
  34. package/dist/cjs/core/SessionManager.js +20 -0
  35. package/dist/cjs/core/SessionManager.js.map +1 -1
  36. package/dist/cjs/core/StreamingToolExecutor.d.ts +142 -0
  37. package/dist/cjs/core/StreamingToolExecutor.d.ts.map +1 -0
  38. package/dist/cjs/core/StreamingToolExecutor.js +455 -0
  39. package/dist/cjs/core/StreamingToolExecutor.js.map +1 -0
  40. package/dist/cjs/core/ToolManager.d.ts +18 -1
  41. package/dist/cjs/core/ToolManager.d.ts.map +1 -1
  42. package/dist/cjs/core/ToolManager.js +91 -0
  43. package/dist/cjs/core/ToolManager.js.map +1 -1
  44. package/dist/cjs/index.d.ts +5 -1
  45. package/dist/cjs/index.d.ts.map +1 -1
  46. package/dist/cjs/index.js +8 -2
  47. package/dist/cjs/index.js.map +1 -1
  48. package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
  49. package/dist/cjs/providers/AnthropicProvider.js +8 -7
  50. package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
  51. package/dist/cjs/providers/GeminiProvider.d.ts +25 -0
  52. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  53. package/dist/cjs/providers/GeminiProvider.js +79 -51
  54. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  55. package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
  56. package/dist/cjs/providers/OpenAIProvider.js +14 -6
  57. package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
  58. package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
  59. package/dist/cjs/providers/OpenRouterProvider.js +7 -6
  60. package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
  61. package/dist/cjs/types/agent.d.ts +44 -0
  62. package/dist/cjs/types/agent.d.ts.map +1 -1
  63. package/dist/cjs/types/agent.js.map +1 -1
  64. package/dist/cjs/types/compaction.d.ts +50 -0
  65. package/dist/cjs/types/compaction.d.ts.map +1 -0
  66. package/dist/cjs/types/compaction.js +6 -0
  67. package/dist/cjs/types/compaction.js.map +1 -0
  68. package/dist/cjs/types/index.d.ts +4 -2
  69. package/dist/cjs/types/index.d.ts.map +1 -1
  70. package/dist/cjs/types/index.js.map +1 -1
  71. package/dist/cjs/types/tool.d.ts +84 -0
  72. package/dist/cjs/types/tool.d.ts.map +1 -1
  73. package/dist/core/Agent.d.ts +17 -1
  74. package/dist/core/Agent.d.ts.map +1 -1
  75. package/dist/core/Agent.js +47 -0
  76. package/dist/core/Agent.js.map +1 -1
  77. package/dist/core/BatchPromptBuilder.d.ts +3 -0
  78. package/dist/core/BatchPromptBuilder.d.ts.map +1 -1
  79. package/dist/core/BatchPromptBuilder.js +4 -1
  80. package/dist/core/BatchPromptBuilder.js.map +1 -1
  81. package/dist/core/CompactionEngine.d.ts +65 -0
  82. package/dist/core/CompactionEngine.d.ts.map +1 -0
  83. package/dist/core/CompactionEngine.js +244 -0
  84. package/dist/core/CompactionEngine.js.map +1 -0
  85. package/dist/core/PromptComposer.d.ts +8 -1
  86. package/dist/core/PromptComposer.d.ts.map +1 -1
  87. package/dist/core/PromptComposer.js +238 -126
  88. package/dist/core/PromptComposer.js.map +1 -1
  89. package/dist/core/PromptSectionCache.d.ts +57 -0
  90. package/dist/core/PromptSectionCache.d.ts.map +1 -0
  91. package/dist/core/PromptSectionCache.js +104 -0
  92. package/dist/core/PromptSectionCache.js.map +1 -0
  93. package/dist/core/ResponseEngine.d.ts +3 -0
  94. package/dist/core/ResponseEngine.d.ts.map +1 -1
  95. package/dist/core/ResponseEngine.js +10 -6
  96. package/dist/core/ResponseEngine.js.map +1 -1
  97. package/dist/core/ResponseModal.d.ts.map +1 -1
  98. package/dist/core/ResponseModal.js +75 -16
  99. package/dist/core/ResponseModal.js.map +1 -1
  100. package/dist/core/RoutingEngine.d.ts +10 -0
  101. package/dist/core/RoutingEngine.d.ts.map +1 -1
  102. package/dist/core/RoutingEngine.js +3 -2
  103. package/dist/core/RoutingEngine.js.map +1 -1
  104. package/dist/core/SessionManager.d.ts.map +1 -1
  105. package/dist/core/SessionManager.js +17 -0
  106. package/dist/core/SessionManager.js.map +1 -1
  107. package/dist/core/StreamingToolExecutor.d.ts +142 -0
  108. package/dist/core/StreamingToolExecutor.d.ts.map +1 -0
  109. package/dist/core/StreamingToolExecutor.js +448 -0
  110. package/dist/core/StreamingToolExecutor.js.map +1 -0
  111. package/dist/core/ToolManager.d.ts +18 -1
  112. package/dist/core/ToolManager.d.ts.map +1 -1
  113. package/dist/core/ToolManager.js +91 -0
  114. package/dist/core/ToolManager.js.map +1 -1
  115. package/dist/index.d.ts +5 -1
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +3 -0
  118. package/dist/index.js.map +1 -1
  119. package/dist/providers/AnthropicProvider.d.ts.map +1 -1
  120. package/dist/providers/AnthropicProvider.js +8 -7
  121. package/dist/providers/AnthropicProvider.js.map +1 -1
  122. package/dist/providers/GeminiProvider.d.ts +25 -0
  123. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  124. package/dist/providers/GeminiProvider.js +79 -51
  125. package/dist/providers/GeminiProvider.js.map +1 -1
  126. package/dist/providers/OpenAIProvider.d.ts.map +1 -1
  127. package/dist/providers/OpenAIProvider.js +14 -6
  128. package/dist/providers/OpenAIProvider.js.map +1 -1
  129. package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
  130. package/dist/providers/OpenRouterProvider.js +7 -6
  131. package/dist/providers/OpenRouterProvider.js.map +1 -1
  132. package/dist/types/agent.d.ts +44 -0
  133. package/dist/types/agent.d.ts.map +1 -1
  134. package/dist/types/agent.js.map +1 -1
  135. package/dist/types/compaction.d.ts +50 -0
  136. package/dist/types/compaction.d.ts.map +1 -0
  137. package/dist/types/compaction.js +5 -0
  138. package/dist/types/compaction.js.map +1 -0
  139. package/dist/types/index.d.ts +4 -2
  140. package/dist/types/index.d.ts.map +1 -1
  141. package/dist/types/index.js.map +1 -1
  142. package/dist/types/tool.d.ts +84 -0
  143. package/dist/types/tool.d.ts.map +1 -1
  144. package/docs/api/overview.md +140 -0
  145. package/docs/core/tools/enhanced-tool.md +186 -0
  146. package/docs/core/tools/streaming-execution.md +161 -0
  147. package/docs/guides/context-compaction.md +96 -0
  148. package/docs/guides/prompt-optimization.md +164 -0
  149. package/examples/advanced-patterns/context-compaction.ts +223 -0
  150. package/examples/advanced-patterns/streaming-responses.ts +85 -7
  151. package/examples/tools/enhanced-tool-metadata.ts +268 -0
  152. package/examples/tools/streaming-tool-execution.ts +283 -0
  153. package/package.json +1 -1
  154. package/src/core/Agent.ts +58 -2
  155. package/src/core/BatchPromptBuilder.ts +4 -1
  156. package/src/core/CompactionEngine.ts +318 -0
  157. package/src/core/PromptComposer.ts +259 -156
  158. package/src/core/PromptSectionCache.ts +136 -0
  159. package/src/core/ResponseEngine.ts +9 -6
  160. package/src/core/ResponseModal.ts +77 -16
  161. package/src/core/RoutingEngine.ts +13 -2
  162. package/src/core/SessionManager.ts +19 -0
  163. package/src/core/StreamingToolExecutor.ts +572 -0
  164. package/src/core/ToolManager.ts +151 -41
  165. package/src/index.ts +14 -0
  166. package/src/providers/AnthropicProvider.ts +11 -12
  167. package/src/providers/GeminiProvider.ts +83 -52
  168. package/src/providers/OpenAIProvider.ts +21 -13
  169. package/src/providers/OpenRouterProvider.ts +13 -13
  170. package/src/types/agent.ts +45 -0
  171. package/src/types/compaction.ts +52 -0
  172. package/src/types/index.ts +35 -14
  173. package/src/types/tool.ts +108 -0
@@ -10,6 +10,7 @@ import type {
10
10
  import type { Route } from "./Route";
11
11
  import type { Step } from "./Step";
12
12
  import { PromptComposer } from "./PromptComposer";
13
+ import { PromptSectionCache } from "./PromptSectionCache";
13
14
  import { createTemplateContext, render } from "../utils/template";
14
15
 
15
16
  export interface BuildResponsePromptParams<
@@ -43,6 +44,8 @@ export interface BuildFallbackPromptParams<TContext = unknown, TData = unknown>
43
44
  }
44
45
 
45
46
  export class ResponseEngine<TContext = unknown, TData = unknown> {
47
+ constructor(private readonly promptSectionCache?: PromptSectionCache) { }
48
+
46
49
  responseSchemaForRoute(
47
50
  route: Route<TContext, TData>,
48
51
  currentStep?: Step<TContext, TData>,
@@ -96,7 +99,6 @@ export class ResponseEngine<TContext = unknown, TData = unknown> {
96
99
  prohibitions,
97
100
  directives,
98
101
  history,
99
- lastMessage,
100
102
  agentOptions,
101
103
  combinedGuidelines,
102
104
  combinedTerms,
@@ -105,7 +107,7 @@ export class ResponseEngine<TContext = unknown, TData = unknown> {
105
107
  agentSchema,
106
108
  } = params;
107
109
  const templateContext = createTemplateContext({ context, session, history });
108
- const pc = new PromptComposer(templateContext);
110
+ const pc = new PromptComposer(templateContext, this.promptSectionCache);
109
111
 
110
112
  // Create combined agent options with route overrides
111
113
  let effectiveAgentOptions = agentOptions;
@@ -153,8 +155,8 @@ export class ResponseEngine<TContext = unknown, TData = unknown> {
153
155
  await pc.addGlossary(combinedTerms);
154
156
  }
155
157
 
156
- await pc.addInteractionHistory(history);
157
- await pc.addLastMessage(lastMessage);
158
+ // History is now passed natively via GenerateMessageInput.history
159
+ // instead of being embedded in the prompt string (Requirements 17.1, 17.2)
158
160
 
159
161
  // Add data collection instructions - include ALL route fields, not just current step
160
162
  // Collect all fields from route's required and optional fields
@@ -297,10 +299,11 @@ export class ResponseEngine<TContext = unknown, TData = unknown> {
297
299
  const { history, agentOptions, terms, guidelines, context, session } =
298
300
  params;
299
301
  const templateContext = createTemplateContext({ context, session, history });
300
- const pc = new PromptComposer(templateContext);
302
+ const pc = new PromptComposer(templateContext, this.promptSectionCache);
301
303
 
302
304
  await pc.addAgentMeta(agentOptions);
303
- await pc.addInteractionHistory(history);
305
+ // History is now passed natively via GenerateMessageInput.history
306
+ // instead of being embedded in the prompt string (Requirements 17.1, 17.2)
304
307
  await pc.addGlossary(terms);
305
308
  await pc.addGuidelines(guidelines);
306
309
  await pc.addKnowledgeBase(agentOptions.knowledgeBase);
@@ -16,6 +16,7 @@ import type {
16
16
  AgentStructuredResponse,
17
17
  Term,
18
18
  StoppedReason,
19
+ ToolCallRequest,
19
20
  } from "../types";
20
21
  import { EventKind, MessageRole } from "../types";
21
22
  import type { Agent } from "./Agent";
@@ -157,7 +158,7 @@ export class ResponseModal<TContext = unknown, TData = unknown> {
157
158
  private readonly options?: ResponseModalOptions
158
159
  ) {
159
160
  // Initialize response engine
160
- this.responseEngine = new ResponseEngine<TContext, TData>();
161
+ this.responseEngine = new ResponseEngine<TContext, TData>(this.agent.promptSectionCache);
161
162
 
162
163
  // Initialize response pipeline with agent dependencies
163
164
  this.responsePipeline = new ResponsePipeline<TContext, TData>(
@@ -175,7 +176,7 @@ export class ResponseModal<TContext = unknown, TData = unknown> {
175
176
  this.batchExecutor = new BatchExecutor<TContext, TData>();
176
177
 
177
178
  // Initialize batch prompt builder for combined prompts
178
- this.batchPromptBuilder = new BatchPromptBuilder<TContext, TData>();
179
+ this.batchPromptBuilder = new BatchPromptBuilder<TContext, TData>(this.agent.promptSectionCache);
179
180
  }
180
181
 
181
182
  /**
@@ -1640,21 +1641,81 @@ export class ResponseModal<TContext = unknown, TData = unknown> {
1640
1641
  if (chunk.done && chunk.structured?.toolCalls) {
1641
1642
  toolCalls = chunk.structured.toolCalls;
1642
1643
 
1643
- // Execute tools with unified loop handling
1644
- const toolResult = await this.executeUnifiedToolLoop({
1645
- toolCalls,
1646
- context,
1647
- session,
1648
- history,
1649
- selectedRoute,
1650
- responsePrompt,
1651
- availableTools,
1652
- responseSchema,
1653
- signal,
1654
- });
1644
+ const toolManager = this.getToolManager();
1645
+
1646
+ // Use concurrent execution for the initial batch of tool calls
1647
+ if (toolManager && typeof toolManager.executeWithConcurrency === 'function') {
1648
+ const toolCallRequests: ToolCallRequest[] = toolCalls.map((tc, i) => ({
1649
+ id: `${tc.toolName}-${i}-${Date.now()}`,
1650
+ toolName: tc.toolName,
1651
+ arguments: tc.arguments,
1652
+ }));
1653
+
1654
+ const historyEvents = historyToEvents(history);
1655
+
1656
+ try {
1657
+ for await (const update of toolManager.executeWithConcurrency({
1658
+ toolCalls: toolCallRequests,
1659
+ context,
1660
+ data: session.data,
1661
+ history: historyEvents,
1662
+ signal,
1663
+ route: selectedRoute,
1664
+ step: nextStep,
1665
+ })) {
1666
+ // Apply context updates
1667
+ if (update.contextUpdate) {
1668
+ try {
1669
+ await this.agent.updateContext(update.contextUpdate as Partial<TContext>);
1670
+ } catch (error) {
1671
+ logger.error(`[ResponseModal] Failed to update context from concurrent tool:`, error);
1672
+ }
1673
+ }
1655
1674
 
1656
- session = toolResult.session;
1657
- toolCalls = toolResult.finalToolCalls;
1675
+ // Apply data updates
1676
+ if (update.dataUpdate) {
1677
+ try {
1678
+ const updateDataMethod = this.agent.getUpdateDataMethod();
1679
+ session = await updateDataMethod(session, update.dataUpdate);
1680
+ } catch (error) {
1681
+ logger.error(`[ResponseModal] Failed to update data from concurrent tool:`, error);
1682
+ }
1683
+ }
1684
+
1685
+ // Yield progress updates immediately
1686
+ if (update.progress) {
1687
+ yield {
1688
+ delta: '',
1689
+ accumulated: chunk.accumulated,
1690
+ done: false,
1691
+ session,
1692
+ toolCalls: undefined,
1693
+ isRouteComplete: false,
1694
+ metadata: { toolProgress: update.progress, toolCallId: update.toolCallId },
1695
+ };
1696
+ }
1697
+ }
1698
+
1699
+ logger.debug(`[ResponseModal] Concurrent tool execution completed for ${toolCallRequests.length} tools`);
1700
+ } catch (error) {
1701
+ logger.error(`[ResponseModal] Concurrent tool execution failed, falling back to sequential:`, error);
1702
+ // Fall back to the unified tool loop on failure
1703
+ const toolResult = await this.executeUnifiedToolLoop({
1704
+ toolCalls, context, session, history, selectedRoute,
1705
+ responsePrompt, availableTools, responseSchema, signal,
1706
+ });
1707
+ session = toolResult.session;
1708
+ toolCalls = toolResult.finalToolCalls;
1709
+ }
1710
+ } else {
1711
+ // Fallback: no ToolManager or no executeWithConcurrency, use unified tool loop
1712
+ const toolResult = await this.executeUnifiedToolLoop({
1713
+ toolCalls, context, session, history, selectedRoute,
1714
+ responsePrompt, availableTools, responseSchema, signal,
1715
+ });
1716
+ session = toolResult.session;
1717
+ toolCalls = toolResult.finalToolCalls;
1718
+ }
1658
1719
  }
1659
1720
 
1660
1721
  // Extract collected data on final chunk
@@ -10,6 +10,7 @@ import { enterRoute, mergeCollected } from "../utils";
10
10
  import type { Route } from "./Route";
11
11
  import type { Step } from "./Step";
12
12
  import { PromptComposer } from "./PromptComposer";
13
+ import { PromptSectionCache } from "./PromptSectionCache";
13
14
  import { END_ROUTE_ID } from "../constants";
14
15
  import { createTemplateContext, getLastMessageFromHistory, logger } from "../utils";
15
16
 
@@ -41,6 +42,15 @@ export interface RoutingEngineOptions {
41
42
  * @default 15
42
43
  */
43
44
  routeSwitchMargin?: number;
45
+ /**
46
+ * Callback invoked when the active route changes.
47
+ * Used by Agent to invalidate route-dependent prompt cache sections.
48
+ */
49
+ onRouteSwitch?: () => void;
50
+ /**
51
+ * Shared prompt section cache for memoizing static prompt sections.
52
+ */
53
+ promptSectionCache?: PromptSectionCache;
44
54
  }
45
55
 
46
56
  export interface BuildStepSelectionPromptParams<
@@ -91,6 +101,7 @@ export class RoutingEngine<TContext = unknown, TData = unknown> {
91
101
  );
92
102
  }
93
103
  logger.debug(`[RoutingEngine] Entered route: ${route.title}`);
104
+ this.options?.onRouteSwitch?.();
94
105
  return updatedSession;
95
106
  }
96
107
  return session;
@@ -921,7 +932,7 @@ export class RoutingEngine<TContext = unknown, TData = unknown> {
921
932
  includeEndRoute = false,
922
933
  } = params;
923
934
  const templateContext = createTemplateContext({ context, session, history });
924
- const pc = new PromptComposer<TContext, TData>(templateContext);
935
+ const pc = new PromptComposer<TContext, TData>(templateContext, this.options?.promptSectionCache);
925
936
 
926
937
  // Add agent metadata
927
938
  if (agentOptions) {
@@ -1173,7 +1184,7 @@ export class RoutingEngine<TContext = unknown, TData = unknown> {
1173
1184
  routeConditionContext,
1174
1185
  } = params;
1175
1186
  const templateContext = createTemplateContext({ context, session, history });
1176
- const pc = new PromptComposer<TContext, TData>(templateContext);
1187
+ const pc = new PromptComposer<TContext, TData>(templateContext, this.options?.promptSectionCache);
1177
1188
  if (agentOptions) {
1178
1189
  await pc.addAgentMeta(agentOptions);
1179
1190
  }
@@ -5,9 +5,11 @@
5
5
  * in both server and client environments.
6
6
  */
7
7
 
8
+ import log from "loglevel";
8
9
  import type { SessionState } from "../types/session";
9
10
  import type { History, HistoryItem } from "../types/history";
10
11
  import { PersistenceManager } from "./PersistenceManager";
12
+ import { CompactionEngine } from "./CompactionEngine";
11
13
  import type { PersistenceAdapter } from "../types/persistence";
12
14
  import type { Agent } from "./Agent";
13
15
  import { createSession } from "../utils";
@@ -135,6 +137,23 @@ export class SessionManager<TData = unknown> {
135
137
  // Ensure currentSession is updated
136
138
  this.currentSession = session;
137
139
 
140
+ // Apply compaction if configured
141
+ try {
142
+ const compactionOptions = this.agent?.getCompactionOptions();
143
+ if (compactionOptions) {
144
+ const result = await CompactionEngine.checkAndCompact(session.history, compactionOptions);
145
+ if (result.strategy !== 'none') {
146
+ session.history = result.history;
147
+ log.info(
148
+ `CompactionEngine: applied strategy '${result.strategy}', ` +
149
+ `estimatedTokens=${result.estimatedTokens}, messagesCompacted=${result.messagesCompacted}`
150
+ );
151
+ }
152
+ }
153
+ } catch (error) {
154
+ log.warn("CompactionEngine: compaction failed, continuing without compaction", error);
155
+ }
156
+
138
157
  // Auto-save to persistence
139
158
  await this.save();
140
159
  }