@falai/agent 2.1.0 → 2.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 (138) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapters/SQLiteAdapter.d.ts +3 -3
  3. package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
  4. package/dist/adapters/index.d.ts +1 -1
  5. package/dist/adapters/index.d.ts.map +1 -1
  6. package/dist/cjs/adapters/SQLiteAdapter.d.ts +3 -3
  7. package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
  8. package/dist/cjs/adapters/index.d.ts +1 -1
  9. package/dist/cjs/adapters/index.d.ts.map +1 -1
  10. package/dist/cjs/core/Agent.js +2 -2
  11. package/dist/cjs/core/Agent.js.map +1 -1
  12. package/dist/cjs/core/Flow.d.ts +1 -6
  13. package/dist/cjs/core/Flow.d.ts.map +1 -1
  14. package/dist/cjs/core/Flow.js +0 -7
  15. package/dist/cjs/core/Flow.js.map +1 -1
  16. package/dist/cjs/core/PromptSectionCache.d.ts +2 -11
  17. package/dist/cjs/core/PromptSectionCache.d.ts.map +1 -1
  18. package/dist/cjs/core/PromptSectionCache.js.map +1 -1
  19. package/dist/cjs/core/ResponseModal.d.ts +5 -5
  20. package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
  21. package/dist/cjs/core/ResponseModal.js +38 -182
  22. package/dist/cjs/core/ResponseModal.js.map +1 -1
  23. package/dist/cjs/core/ToolManager.d.ts +1 -33
  24. package/dist/cjs/core/ToolManager.d.ts.map +1 -1
  25. package/dist/cjs/core/ToolManager.js +2 -189
  26. package/dist/cjs/core/ToolManager.js.map +1 -1
  27. package/dist/cjs/index.d.ts +3 -3
  28. package/dist/cjs/index.d.ts.map +1 -1
  29. package/dist/cjs/index.js +2 -4
  30. package/dist/cjs/index.js.map +1 -1
  31. package/dist/cjs/types/agent.d.ts +1 -8
  32. package/dist/cjs/types/agent.d.ts.map +1 -1
  33. package/dist/cjs/types/agent.js +0 -9
  34. package/dist/cjs/types/agent.js.map +1 -1
  35. package/dist/cjs/types/history.d.ts +0 -2
  36. package/dist/cjs/types/history.d.ts.map +1 -1
  37. package/dist/cjs/types/history.js.map +1 -1
  38. package/dist/cjs/types/index.d.ts +1 -6
  39. package/dist/cjs/types/index.d.ts.map +1 -1
  40. package/dist/cjs/types/index.js +1 -20
  41. package/dist/cjs/types/index.js.map +1 -1
  42. package/dist/cjs/types/prompt-cache.d.ts +15 -0
  43. package/dist/cjs/types/prompt-cache.d.ts.map +1 -0
  44. package/dist/cjs/types/prompt-cache.js +6 -0
  45. package/dist/cjs/types/prompt-cache.js.map +1 -0
  46. package/dist/cjs/types/schema.d.ts +0 -7
  47. package/dist/cjs/types/schema.d.ts.map +1 -1
  48. package/dist/cjs/types/tool.d.ts.map +1 -1
  49. package/dist/cjs/utils/history.d.ts +0 -5
  50. package/dist/cjs/utils/history.d.ts.map +1 -1
  51. package/dist/cjs/utils/history.js +0 -8
  52. package/dist/cjs/utils/history.js.map +1 -1
  53. package/dist/cjs/utils/index.d.ts +2 -2
  54. package/dist/cjs/utils/index.d.ts.map +1 -1
  55. package/dist/cjs/utils/index.js +1 -4
  56. package/dist/cjs/utils/index.js.map +1 -1
  57. package/dist/cjs/utils/template.d.ts +0 -2
  58. package/dist/cjs/utils/template.d.ts.map +1 -1
  59. package/dist/cjs/utils/template.js +0 -2
  60. package/dist/cjs/utils/template.js.map +1 -1
  61. package/dist/core/Agent.js +2 -2
  62. package/dist/core/Agent.js.map +1 -1
  63. package/dist/core/Flow.d.ts +1 -6
  64. package/dist/core/Flow.d.ts.map +1 -1
  65. package/dist/core/Flow.js +0 -7
  66. package/dist/core/Flow.js.map +1 -1
  67. package/dist/core/PromptSectionCache.d.ts +2 -11
  68. package/dist/core/PromptSectionCache.d.ts.map +1 -1
  69. package/dist/core/PromptSectionCache.js.map +1 -1
  70. package/dist/core/ResponseModal.d.ts +5 -5
  71. package/dist/core/ResponseModal.d.ts.map +1 -1
  72. package/dist/core/ResponseModal.js +38 -182
  73. package/dist/core/ResponseModal.js.map +1 -1
  74. package/dist/core/ToolManager.d.ts +1 -33
  75. package/dist/core/ToolManager.d.ts.map +1 -1
  76. package/dist/core/ToolManager.js +2 -189
  77. package/dist/core/ToolManager.js.map +1 -1
  78. package/dist/index.d.ts +3 -3
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +2 -2
  81. package/dist/index.js.map +1 -1
  82. package/dist/types/agent.d.ts +1 -8
  83. package/dist/types/agent.d.ts.map +1 -1
  84. package/dist/types/agent.js +1 -8
  85. package/dist/types/agent.js.map +1 -1
  86. package/dist/types/history.d.ts +0 -2
  87. package/dist/types/history.d.ts.map +1 -1
  88. package/dist/types/history.js.map +1 -1
  89. package/dist/types/index.d.ts +1 -6
  90. package/dist/types/index.d.ts.map +1 -1
  91. package/dist/types/index.js +0 -4
  92. package/dist/types/index.js.map +1 -1
  93. package/dist/types/prompt-cache.d.ts +15 -0
  94. package/dist/types/prompt-cache.d.ts.map +1 -0
  95. package/dist/types/prompt-cache.js +5 -0
  96. package/dist/types/prompt-cache.js.map +1 -0
  97. package/dist/types/schema.d.ts +0 -7
  98. package/dist/types/schema.d.ts.map +1 -1
  99. package/dist/types/tool.d.ts.map +1 -1
  100. package/dist/utils/history.d.ts +0 -5
  101. package/dist/utils/history.d.ts.map +1 -1
  102. package/dist/utils/history.js +0 -7
  103. package/dist/utils/history.js.map +1 -1
  104. package/dist/utils/index.d.ts +2 -2
  105. package/dist/utils/index.d.ts.map +1 -1
  106. package/dist/utils/index.js +2 -2
  107. package/dist/utils/index.js.map +1 -1
  108. package/dist/utils/template.d.ts +0 -2
  109. package/dist/utils/template.d.ts.map +1 -1
  110. package/dist/utils/template.js +0 -2
  111. package/dist/utils/template.js.map +1 -1
  112. package/package.json +8 -17
  113. package/src/adapters/SQLiteAdapter.ts +3 -3
  114. package/src/adapters/index.ts +1 -1
  115. package/src/core/Agent.ts +3 -3
  116. package/src/core/Flow.ts +0 -9
  117. package/src/core/PromptSectionCache.ts +2 -13
  118. package/src/core/ResponseModal.ts +39 -197
  119. package/src/core/ToolManager.ts +2 -234
  120. package/src/index.ts +2 -3
  121. package/src/types/agent.ts +1 -9
  122. package/src/types/history.ts +0 -4
  123. package/src/types/index.ts +2 -9
  124. package/src/types/prompt-cache.ts +17 -0
  125. package/src/types/schema.ts +0 -8
  126. package/src/types/tool.ts +0 -2
  127. package/src/utils/history.ts +1 -7
  128. package/src/utils/index.ts +0 -3
  129. package/src/utils/template.ts +0 -2
  130. package/dist/cjs/types/routing.d.ts +0 -12
  131. package/dist/cjs/types/routing.d.ts.map +0 -1
  132. package/dist/cjs/types/routing.js +0 -3
  133. package/dist/cjs/types/routing.js.map +0 -1
  134. package/dist/types/routing.d.ts +0 -12
  135. package/dist/types/routing.d.ts.map +0 -1
  136. package/dist/types/routing.js +0 -2
  137. package/dist/types/routing.js.map +0 -1
  138. package/src/types/routing.ts +0 -13
@@ -363,18 +363,11 @@ export class ResponseModal<TContext = unknown, TData = unknown> {
363
363
  }
364
364
 
365
365
  /**
366
- * Get the ToolManager instance from the agent
366
+ * Get the ToolManager instance from the agent.
367
367
  * @private
368
368
  */
369
- private getToolManager(): ToolManager<TContext, TData> | undefined {
370
- // Check if agent has a tool property (ToolManager)
371
- if (this.agent && 'tool' in this.agent && this.agent.tool) {
372
- return this.agent.tool;
373
- }
374
-
375
- // Log warning if ToolManager is not available
376
- logger.warn(`[ResponseModal] ToolManager not available on agent - tool execution will use fallback methods`);
377
- return undefined;
369
+ private getToolManager(): ToolManager<TContext, TData> {
370
+ return this.agent.tool;
378
371
  }
379
372
 
380
373
  /**
@@ -1983,7 +1976,7 @@ export class ResponseModal<TContext = unknown, TData = unknown> {
1983
1976
  const toolManager = this.getToolManager();
1984
1977
 
1985
1978
  // Use concurrent execution for the initial batch of tool calls
1986
- if (toolManager && typeof toolManager.executeWithConcurrency === 'function') {
1979
+ {
1987
1980
  const toolCallRequests: ToolCallRequest[] = toolCalls.map((tc, i) => ({
1988
1981
  id: `${tc.toolName}-${i}-${Date.now()}`,
1989
1982
  toolName: tc.toolName,
@@ -2046,14 +2039,6 @@ export class ResponseModal<TContext = unknown, TData = unknown> {
2046
2039
  session = toolResult.session;
2047
2040
  toolCalls = toolResult.finalToolCalls;
2048
2041
  }
2049
- } else {
2050
- // Fallback: no ToolManager or no executeWithConcurrency, use unified tool loop
2051
- const toolResult = await this.executeUnifiedToolLoop({
2052
- toolCalls, context, session, history, selectedFlow,
2053
- responsePrompt, availableTools, responseSchema, signal,
2054
- });
2055
- session = toolResult.session;
2056
- toolCalls = toolResult.finalToolCalls;
2057
2042
  }
2058
2043
  }
2059
2044
 
@@ -2150,22 +2135,15 @@ export class ResponseModal<TContext = unknown, TData = unknown> {
2150
2135
  try {
2151
2136
  // Use ToolManager for unified tool execution
2152
2137
  const toolManager = this.getToolManager();
2153
- let toolResult;
2154
-
2155
- if (toolManager) {
2156
- toolResult = await toolManager.executeTool({
2157
- tool: tool,
2158
- context,
2159
- updateContext: this.agent.updateContext.bind(this.agent),
2160
- updateData: this.agent.updateCollectedData.bind(this.agent),
2161
- history: historyEvents, // Use Event[] for tool execution
2162
- data: session.data,
2163
- toolArguments: toolCall.arguments,
2164
- });
2165
- } else {
2166
- // Fallback: execute tool directly if ToolManager not available
2167
- throw new Error(`ToolManager not available for tool execution: ${toolCall.toolName}`);
2168
- }
2138
+ const toolResult = await toolManager.executeTool({
2139
+ tool: tool,
2140
+ context,
2141
+ updateContext: this.agent.updateContext.bind(this.agent),
2142
+ updateData: this.agent.updateCollectedData.bind(this.agent),
2143
+ history: historyEvents, // Use Event[] for tool execution
2144
+ data: session.data,
2145
+ toolArguments: toolCall.arguments,
2146
+ });
2169
2147
 
2170
2148
  // Store the actual tool result data for history
2171
2149
  toolResultsMap.set(toolCall.toolName, serializeToolResult(toolResult));
@@ -2298,22 +2276,15 @@ export class ResponseModal<TContext = unknown, TData = unknown> {
2298
2276
  try {
2299
2277
  // Use ToolManager for unified tool execution
2300
2278
  const toolManager = this.getToolManager();
2301
- let toolResult;
2302
-
2303
- if (toolManager) {
2304
- toolResult = await toolManager.executeTool({
2305
- tool: tool,
2306
- context,
2307
- updateContext: this.agent.updateContext.bind(this.agent),
2308
- updateData: this.agent.updateCollectedData.bind(this.agent),
2309
- history: historyToEvents(updatedHistory), // Convert to Event[] for tool execution
2310
- data: session.data,
2311
- toolArguments: toolCall.arguments,
2312
- });
2313
- } else {
2314
- // Fallback: execute tool directly if ToolManager not available
2315
- throw new Error(`ToolManager not available for follow-up tool execution: ${toolCall.toolName}`);
2316
- }
2279
+ const toolResult = await toolManager.executeTool({
2280
+ tool: tool,
2281
+ context,
2282
+ updateContext: this.agent.updateContext.bind(this.agent),
2283
+ updateData: this.agent.updateCollectedData.bind(this.agent),
2284
+ history: historyToEvents(updatedHistory), // Convert to Event[] for tool execution
2285
+ data: session.data,
2286
+ toolArguments: toolCall.arguments,
2287
+ });
2317
2288
 
2318
2289
  // Check if tool execution was successful
2319
2290
  if (!toolResult.success) {
@@ -2815,41 +2786,20 @@ export class ResponseModal<TContext = unknown, TData = unknown> {
2815
2786
 
2816
2787
 
2817
2788
  /**
2818
- * Find an available tool by name for the given flow using ToolManager
2819
- * Delegates to ToolManager for unified tool resolution
2789
+ * Find an available tool by name for the given flow.
2790
+ * Delegates to ToolManager for unified tool resolution.
2820
2791
  * @private
2821
2792
  */
2822
2793
  private findAvailableTool(
2823
2794
  toolName: string,
2824
2795
  flow?: Flow<TContext, TData>
2825
2796
  ): Tool<TContext, TData> | undefined {
2826
- // Use ToolManager for unified tool resolution
2827
- const toolManager = this.getToolManager();
2828
- if (toolManager) {
2829
- return toolManager.find(toolName, undefined, undefined, flow);
2830
- }
2831
-
2832
- // Fallback to legacy resolution if ToolManager not available
2833
- logger.warn(`[ResponseModal] ToolManager not available, using legacy tool resolution for: ${toolName}`);
2834
-
2835
- // Check flow-level tools first (if flow provided)
2836
- if (flow) {
2837
- const flowTool = flow
2838
- .getTools()
2839
- .find((tool: Tool<TContext, TData>) => tool.id === toolName || tool.id === toolName);
2840
- if (flowTool) return flowTool;
2841
- }
2842
-
2843
- // Fall back to agent-level tools
2844
- const agentTools = this.agent.getTools();
2845
- return agentTools.find(
2846
- (tool) => tool.id === toolName || tool.id === toolName
2847
- );
2797
+ return this.getToolManager().find(toolName, undefined, undefined, flow);
2848
2798
  }
2849
2799
 
2850
2800
  /**
2851
- * Collect all available tools for the given flow and step context using ToolManager
2852
- * Delegates to ToolManager for unified tool resolution and deduplication
2801
+ * Collect all available tools for the given flow and step context.
2802
+ * Delegates to ToolManager for unified tool resolution and deduplication.
2853
2803
  * @private
2854
2804
  */
2855
2805
  private collectAvailableTools(
@@ -2861,77 +2811,10 @@ export class ResponseModal<TContext = unknown, TData = unknown> {
2861
2811
  description?: string;
2862
2812
  parameters?: unknown;
2863
2813
  }> {
2864
- // Use ToolManager for unified tool collection if available
2865
- const toolManager = this.getToolManager();
2866
- if (toolManager) {
2867
- const availableTools = toolManager.getAvailable(undefined, step, flow);
2868
- return availableTools.map((tool) => ({
2869
- id: tool.id,
2870
- name: tool.id || tool.id,
2871
- description: tool.description,
2872
- parameters: tool.parameters,
2873
- }));
2874
- }
2875
-
2876
- // Fallback to legacy collection logic if ToolManager not available
2877
- logger.warn(`[ResponseModal] ToolManager not available, using legacy tool collection`);
2878
-
2879
- const availableTools = new Map<string, Tool<TContext, TData>>();
2880
-
2881
- // Add agent-level tools
2882
- this.agent.getTools().forEach((tool) => {
2883
- availableTools.set(tool.id, tool);
2884
- });
2885
-
2886
- // Add flow-level tools (these take precedence)
2887
- if (flow) {
2888
- flow.getTools().forEach((tool: Tool<TContext, TData>) => {
2889
- availableTools.set(tool.id, tool);
2890
- });
2891
- }
2892
-
2893
- // Filter by step-level allowed tools if specified
2894
- if (step?.tools) {
2895
- const allowedToolIds = new Set<string>();
2896
- const stepTools: Tool<TContext, TData>[] = [];
2897
-
2898
- for (const toolRef of step.tools) {
2899
- if (typeof toolRef === "string") {
2900
- // Reference to registered tool
2901
- allowedToolIds.add(toolRef);
2902
- } else {
2903
- // Inline tool definition
2904
- if (toolRef.id) {
2905
- allowedToolIds.add(toolRef.id);
2906
- stepTools.push(toolRef);
2907
- }
2908
- }
2909
- }
2910
-
2911
- // If step specifies tools, only include those
2912
- if (allowedToolIds.size > 0) {
2913
- const filteredTools = new Map<string, Tool<TContext, TData>>();
2914
- for (const toolId of Array.from(allowedToolIds)) {
2915
- const tool = availableTools.get(toolId);
2916
- if (tool) {
2917
- filteredTools.set(toolId, tool);
2918
- }
2919
- }
2920
- // Add inline tools
2921
- stepTools.forEach((tool) => {
2922
- if (tool.id) {
2923
- filteredTools.set(tool.id, tool);
2924
- }
2925
- });
2926
- availableTools.clear();
2927
- filteredTools.forEach((tool, id) => availableTools.set(id, tool));
2928
- }
2929
- }
2930
-
2931
- // Convert to the format expected by AI providers
2932
- return Array.from(availableTools.values()).map((tool) => ({
2814
+ const availableTools = this.getToolManager().getAvailable(undefined, step, flow);
2815
+ return availableTools.map((tool) => ({
2933
2816
  id: tool.id,
2934
- name: tool.id || tool.id,
2817
+ name: tool.id,
2935
2818
  description: tool.description,
2936
2819
  parameters: tool.parameters,
2937
2820
  }));
@@ -2963,40 +2846,7 @@ export class ResponseModal<TContext = unknown, TData = unknown> {
2963
2846
 
2964
2847
  if (typeof prepareOrFinalize === "string") {
2965
2848
  // Tool ID - use ToolManager for unified resolution
2966
- const toolManager = this.getToolManager();
2967
- if (toolManager) {
2968
- tool = toolManager.find(prepareOrFinalize, undefined, step, flow);
2969
- } else {
2970
- // Fallback to legacy resolution if ToolManager not available
2971
- logger.warn(`[ResponseModal] ToolManager not available, using legacy tool resolution for prepare/finalize: ${prepareOrFinalize}`);
2972
-
2973
- const availableTools = new Map<string, Tool<TContext, TData>>();
2974
-
2975
- // Add agent-level tools
2976
- this.agent.getTools().forEach((t) => {
2977
- availableTools.set(t.id, t);
2978
- });
2979
-
2980
- // Add flow-level tools
2981
- if (flow) {
2982
- flow.getTools().forEach((t: Tool<TContext, TData>) => {
2983
- availableTools.set(t.id, t);
2984
- });
2985
- }
2986
-
2987
- // Add step-level tools
2988
- if (step?.tools) {
2989
- for (const toolRef of step.tools) {
2990
- if (typeof toolRef === "string") {
2991
- // Keep as is
2992
- } else if (typeof toolRef === 'object' && 'id' in toolRef && toolRef.id) {
2993
- availableTools.set(toolRef.id, toolRef);
2994
- }
2995
- }
2996
- }
2997
-
2998
- tool = availableTools.get(prepareOrFinalize);
2999
- }
2849
+ tool = this.getToolManager().find(prepareOrFinalize, undefined, step, flow);
3000
2850
  } else {
3001
2851
  // Tool object - use directly
3002
2852
  tool = prepareOrFinalize;
@@ -3004,22 +2854,14 @@ export class ResponseModal<TContext = unknown, TData = unknown> {
3004
2854
 
3005
2855
  if (tool) {
3006
2856
  // Use ToolManager for unified tool execution
3007
- const toolManager = this.getToolManager();
3008
- let result;
3009
-
3010
- if (toolManager) {
3011
- result = await toolManager.executeTool({
3012
- tool,
3013
- context,
3014
- updateContext: this.agent.updateContext.bind(this.agent),
3015
- updateData: this.agent.updateCollectedData.bind(this.agent),
3016
- history: [], // Empty history for prepare/finalize
3017
- data,
3018
- });
3019
- } else {
3020
- // Fallback: execute tool directly if ToolManager not available
3021
- throw new Error(`ToolManager not available for prepare/finalize tool execution: ${typeof prepareOrFinalize === "string" ? prepareOrFinalize : "inline tool"}`);
3022
- }
2857
+ const result = await this.getToolManager().executeTool({
2858
+ tool,
2859
+ context,
2860
+ updateContext: this.agent.updateContext.bind(this.agent),
2861
+ updateData: this.agent.updateCollectedData.bind(this.agent),
2862
+ history: [], // Empty history for prepare/finalize
2863
+ data,
2864
+ });
3023
2865
 
3024
2866
  if (!result.success) {
3025
2867
  logger.error(
@@ -663,193 +663,7 @@ export class ToolManager<TContext = unknown, TData = unknown> {
663
663
  }
664
664
 
665
665
  /**
666
- * Execute a tool by ID with proper error handling and fallback strategies
667
- * Consolidates tool execution logic from ToolExecutor and ResponseModal
668
- */
669
- async execute(
670
- toolId: string,
671
- args?: Record<string, unknown>,
672
- context?: {
673
- step?: Step<TContext, TData>;
674
- flow?: Flow<TContext, TData>;
675
- context?: TContext;
676
- data?: Partial<TData>;
677
- history?: Event[];
678
- updateContext?: (updates: Partial<TContext>) => Promise<void>;
679
- updateData?: (updates: Partial<TData>) => Promise<void>;
680
- fallbackTools?: string[]; // Alternative tools to try if primary fails
681
- retryCount?: number; // Number of retries for transient failures
682
- }
683
- ): Promise<ToolExecutionResult> {
684
- const maxRetries = context?.retryCount || 2;
685
- const fallbackTools = context?.fallbackTools || [];
686
- let lastError: Error | undefined;
687
-
688
- // Validate input parameters
689
- if (!toolId || typeof toolId !== 'string' || toolId.trim() === '') {
690
- return {
691
- success: false,
692
- error: 'Tool ID is required and must be a non-empty string',
693
- metadata: { toolId, args }
694
- };
695
- }
696
-
697
- // Try primary tool with retries
698
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
699
- try {
700
- const tool = this.find(toolId, undefined, context?.step, context?.flow);
701
- if (!tool) {
702
- // Tool not found - try fallback tools if available
703
- if (fallbackTools.length > 0) {
704
- logger.warn(`[ToolManager] Primary tool '${toolId}' not found, trying fallback tools: ${fallbackTools.join(', ')}`);
705
-
706
- for (const fallbackId of fallbackTools) {
707
- const fallbackResult = await this.execute(fallbackId, args, {
708
- ...context,
709
- fallbackTools: [], // Prevent infinite recursion
710
- retryCount: 0 // Don't retry fallback tools
711
- });
712
-
713
- if (fallbackResult.success) {
714
- logger.info(`[ToolManager] Fallback tool '${fallbackId}' succeeded for primary tool '${toolId}'`);
715
- return {
716
- ...fallbackResult,
717
- metadata: {
718
- ...fallbackResult.metadata,
719
- primaryTool: toolId,
720
- fallbackUsed: fallbackId
721
- }
722
- };
723
- }
724
- }
725
- }
726
-
727
- return {
728
- success: false,
729
- error: `Tool not found: ${toolId}${fallbackTools.length > 0 ? ` (fallback tools also failed: ${fallbackTools.join(', ')})` : ''}`,
730
- metadata: { toolId, args, fallbackTools }
731
- };
732
- }
733
-
734
- // Execute the tool with proper context
735
- const result = await this.executeTool({
736
- tool,
737
- context: context?.context || (await this.agent.getContext()) as TContext,
738
- updateContext: context?.updateContext || this.agent.updateContext.bind(this.agent),
739
- updateData: context?.updateData || this.agent.updateCollectedData.bind(this.agent),
740
- history: context?.history || [],
741
- data: context?.data,
742
- toolArguments: args,
743
- });
744
-
745
- // Success - return result with execution metadata
746
- if (result.success) {
747
- return {
748
- ...result,
749
- metadata: {
750
- ...result.metadata,
751
- toolId,
752
- attempt: attempt + 1,
753
- maxRetries
754
- }
755
- };
756
- } else {
757
- // Tool execution returned failure - don't retry, return immediately
758
- return {
759
- ...result,
760
- metadata: {
761
- ...result.metadata,
762
- toolId,
763
- attempt: attempt + 1,
764
- maxRetries
765
- }
766
- };
767
- }
768
- } catch (error) {
769
- lastError = error instanceof Error ? error : new Error(String(error));
770
- const errorMessage = lastError.message;
771
-
772
- // Check if this is a transient error that should be retried
773
- const isTransientError = this.isTransientError(lastError);
774
-
775
- if (attempt < maxRetries && isTransientError) {
776
- logger.warn(`[ToolManager] Tool execution attempt ${attempt + 1} failed for ${toolId}, retrying: ${errorMessage}`);
777
-
778
- // Exponential backoff for retries
779
- const delay = Math.min(1000 * Math.pow(2, attempt), 5000);
780
- await new Promise(resolve => setTimeout(resolve, delay));
781
- continue;
782
- } else {
783
- logger.error(`[ToolManager] Tool execution failed for ${toolId} after ${attempt + 1} attempts: ${errorMessage}`);
784
- break;
785
- }
786
- }
787
- }
788
-
789
- // All retries failed - try fallback tools
790
- if (fallbackTools.length > 0) {
791
- logger.warn(`[ToolManager] Primary tool '${toolId}' failed after retries, trying fallback tools: ${fallbackTools.join(', ')}`);
792
-
793
- for (const fallbackId of fallbackTools) {
794
- try {
795
- const fallbackResult = await this.execute(fallbackId, args, {
796
- ...context,
797
- fallbackTools: [], // Prevent infinite recursion
798
- retryCount: 0 // Don't retry fallback tools
799
- });
800
-
801
- if (fallbackResult.success) {
802
- logger.info(`[ToolManager] Fallback tool '${fallbackId}' succeeded for failed primary tool '${toolId}'`);
803
- return {
804
- ...fallbackResult,
805
- metadata: {
806
- ...fallbackResult.metadata,
807
- primaryTool: toolId,
808
- primaryError: lastError?.message,
809
- fallbackUsed: fallbackId
810
- }
811
- };
812
- }
813
- } catch (fallbackError) {
814
- logger.warn(`[ToolManager] Fallback tool '${fallbackId}' also failed: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`);
815
- }
816
- }
817
- }
818
-
819
- // All attempts and fallbacks failed
820
- throw new ToolExecutionError(
821
- `[ToolExecutionError] Tool "${toolId}" execution failed: all ${maxRetries + 1} attempts exhausted${fallbackTools.length > 0 ? ` and fallback tools [${fallbackTools.join(', ')}] also failed` : ''}. ` +
822
- `Check the tool handler for errors or increase maxRetries. Last error: ${lastError?.message || 'Unknown'}.`,
823
- toolId,
824
- { args, context, attempts: maxRetries + 1, fallbackTools },
825
- lastError
826
- );
827
- }
828
-
829
- /**
830
- * Determine if an error is transient and should be retried
831
- */
832
- private isTransientError(error: Error): boolean {
833
- const transientPatterns = [
834
- /network/i,
835
- /timeout/i,
836
- /connection/i,
837
- /temporary/i,
838
- /rate limit/i,
839
- /503/,
840
- /502/,
841
- /504/,
842
- /ECONNRESET/,
843
- /ETIMEDOUT/,
844
- /ENOTFOUND/
845
- ];
846
-
847
- return transientPatterns.some(pattern => pattern.test(error.message));
848
- }
849
-
850
- /**
851
- * Execute a single tool with context and collected data
852
- * Consolidates logic from ToolExecutor class with enhanced error handling
666
+ * Execute a single tool with context and collected data.
853
667
  */
854
668
  async executeTool(params: {
855
669
  tool: Tool<TContext, TData>;
@@ -1023,57 +837,11 @@ export class ToolManager<TContext = unknown, TData = unknown> {
1023
837
 
1024
838
  logger.error(`[ToolManager] Tool execution error for ${tool.id} after ${executionTime}ms:`, error);
1025
839
 
1026
- // Re-throw the error so the execute method can handle retries
840
+ // Re-throw the error so callers can handle it
1027
841
  throw error;
1028
842
  }
1029
843
  }
1030
844
 
1031
- /**
1032
- * Execute multiple tools in sequence
1033
- * Consolidates logic from ToolExecutor class
1034
- */
1035
- async executeTools(params: {
1036
- tools: Array<Tool<TContext, TData>>;
1037
- context: TContext;
1038
- updateContext: (updates: Partial<TContext>) => Promise<void>;
1039
- updateData: (updates: Partial<TData>) => Promise<void>;
1040
- history: Event[];
1041
- data?: Partial<TData>;
1042
- }): Promise<ToolExecutionResult[]> {
1043
- const { tools, context, updateContext, updateData, history, data } = params;
1044
- const results: ToolExecutionResult[] = [];
1045
-
1046
- for (const tool of tools) {
1047
- const result = await this.executeTool({
1048
- tool,
1049
- context,
1050
- updateContext,
1051
- updateData,
1052
- history,
1053
- data,
1054
- });
1055
- results.push(result);
1056
-
1057
- // If tool failed, stop execution chain
1058
- if (!result.success) {
1059
- logger.error(`[ToolManager] Tool ${tool.id || "unknown"} failed:`, result.error);
1060
- break;
1061
- }
1062
-
1063
- // Apply context updates from tool result
1064
- if (result.contextUpdate) {
1065
- await updateContext(result.contextUpdate as Partial<TContext>);
1066
- }
1067
-
1068
- // Apply data updates from tool result
1069
- if (result.dataUpdate) {
1070
- await updateData(result.dataUpdate as Partial<TData>);
1071
- }
1072
- }
1073
-
1074
- return results;
1075
- }
1076
-
1077
845
  /**
1078
846
  * Execute tool calls with concurrency control using StreamingToolExecutor.
1079
847
  * Creates a StreamingToolExecutor, resolves tools, queues them, and yields
package/src/index.ts CHANGED
@@ -57,7 +57,7 @@ export type {
57
57
  export { SQLiteAdapter } from "./adapters/SQLiteAdapter";
58
58
  export type {
59
59
  SqliteDatabase,
60
- SqliteStepment,
60
+ SqliteStatement,
61
61
  SQLiteAdapterOptions,
62
62
  } from "./adapters/SQLiteAdapter";
63
63
  export { MemoryAdapter } from "./adapters/MemoryAdapter";
@@ -77,7 +77,6 @@ export {
77
77
  hasProgrammaticConditions
78
78
  } from "./utils/condition";
79
79
  export {
80
- normalizeHistory,
81
80
  historyItemToEvent,
82
81
  historyToEvents,
83
82
  eventToHistoryItem,
@@ -181,5 +180,5 @@ export type {
181
180
  ConditionIf,
182
181
  ConditionWhen,
183
182
  } from "./types";
184
- export { CompositionMode, EventKind, MessageRole } from "./types";
183
+ export { EventKind, MessageRole } from "./types";
185
184
  export { createSession, createSessionId, enterFlow, enterStep, completeCurrentFlow, isFlowCompletedThisSession, mergeCollected } from "./utils";
@@ -12,7 +12,7 @@ import type { StructuredSchema } from "./schema";
12
12
  import type { Event } from "./history";
13
13
  import type { Template } from "./template";
14
14
  import type { ConditionWhen, ConditionIf } from "./flow";
15
- import type { PromptCacheConfig } from "../core/PromptSectionCache";
15
+ import type { PromptCacheConfig } from "./prompt-cache";
16
16
 
17
17
  /**
18
18
  * Context passed to every lifecycle hook (flow and step).
@@ -73,14 +73,6 @@ export interface AgentCompactionConfig {
73
73
  enabled?: boolean;
74
74
  }
75
75
 
76
- /**
77
- * Composition mode determines how the agent processes and structures responses
78
- */
79
- export enum CompositionMode {
80
- /** Fluid, natural conversation without strict structure */
81
- FLUID = "fluid",
82
- }
83
-
84
76
  /**
85
77
  * Context lifecycle hooks for managing step persistence
86
78
  */
@@ -16,8 +16,6 @@ export enum MessageRole {
16
16
  SYSTEM = "system",
17
17
  }
18
18
 
19
- export type MessageRoleType = MessageRole;
20
-
21
19
  import type { SessionState } from "./session";
22
20
 
23
21
  /**
@@ -32,8 +30,6 @@ export enum EventKind {
32
30
  STATUS = "status",
33
31
  }
34
32
 
35
- export type EventKindType = EventKind;
36
-
37
33
  /**
38
34
  * Participant in a conversation
39
35
  */
@@ -19,7 +19,6 @@ export type {
19
19
  HookContext,
20
20
  ExitReason,
21
21
  } from "./agent";
22
- export { CompositionMode } from "./agent";
23
22
 
24
23
  // History types
25
24
  export type {
@@ -41,7 +40,6 @@ export type {
41
40
  ToolHistoryItem,
42
41
  } from "./history";
43
42
  export { EventKind, MessageRole } from "./history";
44
- export * from "./history";
45
43
 
46
44
  // Flow types
47
45
  export type {
@@ -105,12 +103,12 @@ export type {
105
103
  CompactionResult,
106
104
  } from "./compaction";
107
105
 
108
- // Prompt cache types (re-exported from core)
106
+ // Prompt cache types
109
107
  export type {
110
108
  PromptSectionType,
111
109
  PromptCacheConfig,
112
110
  SectionCompute,
113
- } from "../core/PromptSectionCache";
111
+ } from "./prompt-cache";
114
112
 
115
113
  // AI provider types
116
114
  export type {
@@ -125,10 +123,6 @@ export type {
125
123
  // Schema types
126
124
  export type { StructuredSchema } from "./schema";
127
125
 
128
- // Routing types
129
- export type { RoutingDecision } from "./routing";
130
- export * from "./routing";
131
-
132
126
  // Persistence types
133
127
  export type {
134
128
  SessionData,
@@ -143,7 +137,6 @@ export type {
143
137
  SaveMessageOptions,
144
138
  CollectedStateData,
145
139
  } from "./persistence";
146
- export * from "./persistence";
147
140
 
148
141
  // Template types
149
142
  export type {