@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.
- package/README.md +9 -0
- package/dist/cjs/core/Agent.d.ts +17 -1
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +47 -0
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/BatchPromptBuilder.d.ts +3 -0
- package/dist/cjs/core/BatchPromptBuilder.d.ts.map +1 -1
- package/dist/cjs/core/BatchPromptBuilder.js +4 -1
- package/dist/cjs/core/BatchPromptBuilder.js.map +1 -1
- package/dist/cjs/core/CompactionEngine.d.ts +65 -0
- package/dist/cjs/core/CompactionEngine.d.ts.map +1 -0
- package/dist/cjs/core/CompactionEngine.js +251 -0
- package/dist/cjs/core/CompactionEngine.js.map +1 -0
- package/dist/cjs/core/PromptComposer.d.ts +8 -1
- package/dist/cjs/core/PromptComposer.d.ts.map +1 -1
- package/dist/cjs/core/PromptComposer.js +238 -126
- package/dist/cjs/core/PromptComposer.js.map +1 -1
- package/dist/cjs/core/PromptSectionCache.d.ts +57 -0
- package/dist/cjs/core/PromptSectionCache.d.ts.map +1 -0
- package/dist/cjs/core/PromptSectionCache.js +108 -0
- package/dist/cjs/core/PromptSectionCache.js.map +1 -0
- package/dist/cjs/core/ResponseEngine.d.ts +3 -2
- package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
- package/dist/cjs/core/ResponseEngine.js +8 -8
- package/dist/cjs/core/ResponseEngine.js.map +1 -1
- package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
- package/dist/cjs/core/ResponseModal.js +120 -70
- package/dist/cjs/core/ResponseModal.js.map +1 -1
- package/dist/cjs/core/ResponsePipeline.d.ts +2 -1
- package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/cjs/core/ResponsePipeline.js +17 -19
- package/dist/cjs/core/ResponsePipeline.js.map +1 -1
- package/dist/cjs/core/RoutingEngine.d.ts +10 -0
- package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
- package/dist/cjs/core/RoutingEngine.js +5 -4
- package/dist/cjs/core/RoutingEngine.js.map +1 -1
- package/dist/cjs/core/SessionManager.d.ts.map +1 -1
- package/dist/cjs/core/SessionManager.js +20 -0
- package/dist/cjs/core/SessionManager.js.map +1 -1
- package/dist/cjs/core/StreamingToolExecutor.d.ts +142 -0
- package/dist/cjs/core/StreamingToolExecutor.d.ts.map +1 -0
- package/dist/cjs/core/StreamingToolExecutor.js +455 -0
- package/dist/cjs/core/StreamingToolExecutor.js.map +1 -0
- package/dist/cjs/core/ToolManager.d.ts +18 -1
- package/dist/cjs/core/ToolManager.d.ts.map +1 -1
- package/dist/cjs/core/ToolManager.js +91 -0
- package/dist/cjs/core/ToolManager.js.map +1 -1
- package/dist/cjs/index.d.ts +5 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +8 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.d.ts +7 -0
- package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.js +109 -19
- package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
- package/dist/cjs/providers/GeminiProvider.d.ts +32 -0
- package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GeminiProvider.js +160 -53
- package/dist/cjs/providers/GeminiProvider.js.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.d.ts +5 -0
- package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.js +65 -18
- package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.d.ts +5 -0
- package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.js +57 -18
- package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +44 -0
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/agent.js.map +1 -1
- package/dist/cjs/types/ai.d.ts +2 -2
- package/dist/cjs/types/ai.d.ts.map +1 -1
- package/dist/cjs/types/compaction.d.ts +50 -0
- package/dist/cjs/types/compaction.d.ts.map +1 -0
- package/dist/cjs/types/compaction.js +6 -0
- package/dist/cjs/types/compaction.js.map +1 -0
- package/dist/cjs/types/index.d.ts +4 -2
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/tool.d.ts +84 -0
- package/dist/cjs/types/tool.d.ts.map +1 -1
- package/dist/core/Agent.d.ts +17 -1
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +47 -0
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/BatchPromptBuilder.d.ts +3 -0
- package/dist/core/BatchPromptBuilder.d.ts.map +1 -1
- package/dist/core/BatchPromptBuilder.js +4 -1
- package/dist/core/BatchPromptBuilder.js.map +1 -1
- package/dist/core/CompactionEngine.d.ts +65 -0
- package/dist/core/CompactionEngine.d.ts.map +1 -0
- package/dist/core/CompactionEngine.js +244 -0
- package/dist/core/CompactionEngine.js.map +1 -0
- package/dist/core/PromptComposer.d.ts +8 -1
- package/dist/core/PromptComposer.d.ts.map +1 -1
- package/dist/core/PromptComposer.js +238 -126
- package/dist/core/PromptComposer.js.map +1 -1
- package/dist/core/PromptSectionCache.d.ts +57 -0
- package/dist/core/PromptSectionCache.d.ts.map +1 -0
- package/dist/core/PromptSectionCache.js +104 -0
- package/dist/core/PromptSectionCache.js.map +1 -0
- package/dist/core/ResponseEngine.d.ts +3 -2
- package/dist/core/ResponseEngine.d.ts.map +1 -1
- package/dist/core/ResponseEngine.js +8 -8
- package/dist/core/ResponseEngine.js.map +1 -1
- package/dist/core/ResponseModal.d.ts.map +1 -1
- package/dist/core/ResponseModal.js +121 -71
- package/dist/core/ResponseModal.js.map +1 -1
- package/dist/core/ResponsePipeline.d.ts +2 -1
- package/dist/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/core/ResponsePipeline.js +18 -20
- package/dist/core/ResponsePipeline.js.map +1 -1
- package/dist/core/RoutingEngine.d.ts +10 -0
- package/dist/core/RoutingEngine.d.ts.map +1 -1
- package/dist/core/RoutingEngine.js +6 -5
- package/dist/core/RoutingEngine.js.map +1 -1
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +17 -0
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/StreamingToolExecutor.d.ts +142 -0
- package/dist/core/StreamingToolExecutor.d.ts.map +1 -0
- package/dist/core/StreamingToolExecutor.js +448 -0
- package/dist/core/StreamingToolExecutor.js.map +1 -0
- package/dist/core/ToolManager.d.ts +18 -1
- package/dist/core/ToolManager.d.ts.map +1 -1
- package/dist/core/ToolManager.js +91 -0
- package/dist/core/ToolManager.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/providers/AnthropicProvider.d.ts +7 -0
- package/dist/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/providers/AnthropicProvider.js +109 -19
- package/dist/providers/AnthropicProvider.js.map +1 -1
- package/dist/providers/GeminiProvider.d.ts +32 -0
- package/dist/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/GeminiProvider.js +160 -53
- package/dist/providers/GeminiProvider.js.map +1 -1
- package/dist/providers/OpenAIProvider.d.ts +5 -0
- package/dist/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/OpenAIProvider.js +65 -18
- package/dist/providers/OpenAIProvider.js.map +1 -1
- package/dist/providers/OpenRouterProvider.d.ts +5 -0
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/providers/OpenRouterProvider.js +57 -18
- package/dist/providers/OpenRouterProvider.js.map +1 -1
- package/dist/types/agent.d.ts +44 -0
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/agent.js.map +1 -1
- package/dist/types/ai.d.ts +2 -2
- package/dist/types/ai.d.ts.map +1 -1
- package/dist/types/compaction.d.ts +50 -0
- package/dist/types/compaction.d.ts.map +1 -0
- package/dist/types/compaction.js +5 -0
- package/dist/types/compaction.js.map +1 -0
- package/dist/types/index.d.ts +4 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/tool.d.ts +84 -0
- package/dist/types/tool.d.ts.map +1 -1
- package/docs/api/overview.md +140 -0
- package/docs/core/tools/enhanced-tool.md +186 -0
- package/docs/core/tools/streaming-execution.md +161 -0
- package/docs/guides/context-compaction.md +96 -0
- package/docs/guides/prompt-optimization.md +164 -0
- package/examples/advanced-patterns/context-compaction.ts +223 -0
- package/examples/advanced-patterns/streaming-responses.ts +85 -7
- package/examples/tools/enhanced-tool-metadata.ts +268 -0
- package/examples/tools/streaming-tool-execution.ts +283 -0
- package/package.json +1 -1
- package/src/core/Agent.ts +58 -2
- package/src/core/BatchPromptBuilder.ts +4 -1
- package/src/core/CompactionEngine.ts +318 -0
- package/src/core/PromptComposer.ts +259 -156
- package/src/core/PromptSectionCache.ts +136 -0
- package/src/core/ResponseEngine.ts +7 -11
- package/src/core/ResponseModal.ts +133 -83
- package/src/core/ResponsePipeline.ts +22 -22
- package/src/core/RoutingEngine.ts +16 -5
- package/src/core/SessionManager.ts +19 -0
- package/src/core/StreamingToolExecutor.ts +572 -0
- package/src/core/ToolManager.ts +151 -41
- package/src/index.ts +14 -0
- package/src/providers/AnthropicProvider.ts +121 -24
- package/src/providers/GeminiProvider.ts +174 -54
- package/src/providers/OpenAIProvider.ts +77 -25
- package/src/providers/OpenRouterProvider.ts +68 -25
- package/src/types/agent.ts +45 -0
- package/src/types/ai.ts +2 -2
- package/src/types/compaction.ts +52 -0
- package/src/types/index.ts +35 -14
- 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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
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
|
|
1340
|
-
const
|
|
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
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
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
|
|
1365
|
-
const
|
|
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:
|
|
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:
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
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(),
|