@falai/agent 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -74
- package/dist/cjs/core/Agent.d.ts +22 -29
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +464 -291
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/Events.d.ts +10 -1
- package/dist/cjs/core/Events.d.ts.map +1 -1
- package/dist/cjs/core/Events.js +3 -2
- package/dist/cjs/core/Events.js.map +1 -1
- package/dist/cjs/core/PersistenceManager.d.ts +19 -0
- package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
- package/dist/cjs/core/PersistenceManager.js +57 -0
- package/dist/cjs/core/PersistenceManager.js.map +1 -1
- package/dist/cjs/core/PromptComposer.d.ts +24 -0
- package/dist/cjs/core/PromptComposer.d.ts.map +1 -0
- package/dist/cjs/core/PromptComposer.js +127 -0
- package/dist/cjs/core/PromptComposer.js.map +1 -0
- package/dist/cjs/core/ResponseEngine.d.ts +19 -0
- package/dist/cjs/core/ResponseEngine.d.ts.map +1 -0
- package/dist/cjs/core/ResponseEngine.js +51 -0
- package/dist/cjs/core/ResponseEngine.js.map +1 -0
- package/dist/cjs/core/Route.d.ts +18 -12
- package/dist/cjs/core/Route.d.ts.map +1 -1
- package/dist/cjs/core/Route.js +15 -9
- package/dist/cjs/core/Route.js.map +1 -1
- package/dist/cjs/core/RoutingEngine.d.ts +38 -0
- package/dist/cjs/core/RoutingEngine.d.ts.map +1 -0
- package/dist/cjs/core/RoutingEngine.js +110 -0
- package/dist/cjs/core/RoutingEngine.js.map +1 -0
- package/dist/cjs/core/State.d.ts +15 -4
- package/dist/cjs/core/State.d.ts.map +1 -1
- package/dist/cjs/core/State.js +21 -2
- package/dist/cjs/core/State.js.map +1 -1
- package/dist/cjs/core/ToolExecutor.d.ts +29 -0
- package/dist/cjs/core/ToolExecutor.d.ts.map +1 -0
- package/dist/cjs/core/ToolExecutor.js +73 -0
- package/dist/cjs/core/ToolExecutor.js.map +1 -0
- package/dist/cjs/core/Transition.d.ts +5 -5
- package/dist/cjs/core/Transition.d.ts.map +1 -1
- package/dist/cjs/core/Transition.js.map +1 -1
- package/dist/cjs/index.d.ts +6 -8
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +8 -10
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.js +10 -13
- package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
- package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GeminiProvider.js +12 -8
- package/dist/cjs/providers/GeminiProvider.js.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.js +10 -53
- package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.js +10 -53
- package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +13 -12
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/ai.d.ts +8 -2
- package/dist/cjs/types/ai.d.ts.map +1 -1
- package/dist/cjs/types/history.d.ts +8 -0
- package/dist/cjs/types/history.d.ts.map +1 -1
- package/dist/cjs/types/index.d.ts +0 -3
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +1 -3
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/route.d.ts +39 -4
- package/dist/cjs/types/route.d.ts.map +1 -1
- package/dist/cjs/types/routing.d.ts +16 -0
- package/dist/cjs/types/routing.d.ts.map +1 -0
- package/dist/cjs/types/routing.js +3 -0
- package/dist/cjs/types/routing.js.map +1 -0
- package/dist/cjs/types/schema.d.ts +22 -0
- package/dist/cjs/types/schema.d.ts.map +1 -0
- package/dist/cjs/types/schema.js +3 -0
- package/dist/cjs/types/schema.js.map +1 -0
- package/dist/cjs/types/session.d.ts +72 -0
- package/dist/cjs/types/session.d.ts.map +1 -0
- package/dist/cjs/types/session.js +140 -0
- package/dist/cjs/types/session.js.map +1 -0
- package/dist/cjs/types/tool.d.ts +11 -5
- package/dist/cjs/types/tool.d.ts.map +1 -1
- package/dist/cjs/utils/id.d.ts +0 -5
- package/dist/cjs/utils/id.d.ts.map +1 -1
- package/dist/cjs/utils/id.js +0 -10
- package/dist/cjs/utils/id.js.map +1 -1
- package/dist/cjs/utils/schema.d.ts +17 -0
- package/dist/cjs/utils/schema.d.ts.map +1 -0
- package/dist/cjs/utils/schema.js +32 -0
- package/dist/cjs/utils/schema.js.map +1 -0
- package/dist/core/Agent.d.ts +22 -29
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +464 -291
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/Events.d.ts +10 -1
- package/dist/core/Events.d.ts.map +1 -1
- package/dist/core/Events.js +3 -2
- package/dist/core/Events.js.map +1 -1
- package/dist/core/PersistenceManager.d.ts +19 -0
- package/dist/core/PersistenceManager.d.ts.map +1 -1
- package/dist/core/PersistenceManager.js +57 -0
- package/dist/core/PersistenceManager.js.map +1 -1
- package/dist/core/PromptComposer.d.ts +24 -0
- package/dist/core/PromptComposer.d.ts.map +1 -0
- package/dist/core/PromptComposer.js +123 -0
- package/dist/core/PromptComposer.js.map +1 -0
- package/dist/core/ResponseEngine.d.ts +19 -0
- package/dist/core/ResponseEngine.d.ts.map +1 -0
- package/dist/core/ResponseEngine.js +47 -0
- package/dist/core/ResponseEngine.js.map +1 -0
- package/dist/core/Route.d.ts +18 -12
- package/dist/core/Route.d.ts.map +1 -1
- package/dist/core/Route.js +15 -9
- package/dist/core/Route.js.map +1 -1
- package/dist/core/RoutingEngine.d.ts +38 -0
- package/dist/core/RoutingEngine.d.ts.map +1 -0
- package/dist/core/RoutingEngine.js +106 -0
- package/dist/core/RoutingEngine.js.map +1 -0
- package/dist/core/State.d.ts +15 -4
- package/dist/core/State.d.ts.map +1 -1
- package/dist/core/State.js +21 -2
- package/dist/core/State.js.map +1 -1
- package/dist/core/ToolExecutor.d.ts +29 -0
- package/dist/core/ToolExecutor.d.ts.map +1 -0
- package/dist/core/ToolExecutor.js +69 -0
- package/dist/core/ToolExecutor.js.map +1 -0
- package/dist/core/Transition.d.ts +5 -5
- package/dist/core/Transition.d.ts.map +1 -1
- package/dist/core/Transition.js.map +1 -1
- package/dist/index.d.ts +6 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -5
- package/dist/index.js.map +1 -1
- package/dist/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/providers/AnthropicProvider.js +10 -13
- package/dist/providers/AnthropicProvider.js.map +1 -1
- package/dist/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/GeminiProvider.js +12 -8
- package/dist/providers/GeminiProvider.js.map +1 -1
- package/dist/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/OpenAIProvider.js +10 -53
- package/dist/providers/OpenAIProvider.js.map +1 -1
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/providers/OpenRouterProvider.js +10 -53
- package/dist/providers/OpenRouterProvider.js.map +1 -1
- package/dist/types/agent.d.ts +13 -12
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/ai.d.ts +8 -2
- package/dist/types/ai.d.ts.map +1 -1
- package/dist/types/history.d.ts +8 -0
- package/dist/types/history.d.ts.map +1 -1
- package/dist/types/index.d.ts +0 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +0 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/route.d.ts +39 -4
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/routing.d.ts +16 -0
- package/dist/types/routing.d.ts.map +1 -0
- package/dist/types/routing.js +2 -0
- package/dist/types/routing.js.map +1 -0
- package/dist/types/schema.d.ts +22 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/types/schema.js +2 -0
- package/dist/types/schema.js.map +1 -0
- package/dist/types/session.d.ts +72 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +132 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/tool.d.ts +11 -5
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/utils/id.d.ts +0 -5
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +0 -9
- package/dist/utils/id.js.map +1 -1
- package/dist/utils/schema.d.ts +17 -0
- package/dist/utils/schema.d.ts.map +1 -0
- package/dist/utils/schema.js +27 -0
- package/dist/utils/schema.js.map +1 -0
- package/docs/ADAPTERS.md +83 -3
- package/docs/API_REFERENCE.md +95 -104
- package/docs/ARCHITECTURE.md +284 -286
- package/docs/CONSTRUCTOR_OPTIONS.md +192 -135
- package/docs/CONTEXT_MANAGEMENT.md +311 -28
- package/docs/CONTRIBUTING.md +1 -1
- package/docs/DOMAINS.md +61 -0
- package/docs/GETTING_STARTED.md +177 -88
- package/docs/PERSISTENCE.md +170 -23
- package/docs/README.md +7 -10
- package/examples/business-onboarding.ts +21 -9
- package/examples/company-qna-agent.ts +508 -0
- package/examples/declarative-agent.ts +143 -26
- package/examples/domain-scoping.ts +31 -10
- package/examples/extracted-data-modification.ts +415 -0
- package/examples/healthcare-agent.ts +194 -90
- package/examples/openai-agent.ts +67 -25
- package/examples/opensearch-persistence.ts +455 -151
- package/examples/persistent-onboarding.ts +162 -96
- package/examples/prisma-persistence.ts +371 -125
- package/examples/redis-persistence.ts +393 -23
- package/examples/rules-prohibitions.ts +32 -11
- package/examples/streaming-agent.ts +61 -13
- package/examples/travel-agent.ts +266 -133
- package/package.json +1 -1
- package/src/core/Agent.ts +674 -356
- package/src/core/Events.ts +12 -2
- package/src/core/PersistenceManager.ts +83 -0
- package/src/core/PromptComposer.ts +143 -0
- package/src/core/ResponseEngine.ts +82 -0
- package/src/core/Route.ts +32 -17
- package/src/core/RoutingEngine.ts +165 -0
- package/src/core/State.ts +55 -15
- package/src/core/ToolExecutor.ts +117 -0
- package/src/core/Transition.ts +5 -5
- package/src/index.ts +12 -21
- package/src/providers/AnthropicProvider.ts +10 -13
- package/src/providers/GeminiProvider.ts +12 -8
- package/src/providers/OpenAIProvider.ts +10 -56
- package/src/providers/OpenRouterProvider.ts +10 -56
- package/src/types/agent.ts +16 -13
- package/src/types/ai.ts +6 -2
- package/src/types/history.ts +8 -0
- package/src/types/index.ts +0 -11
- package/src/types/route.ts +41 -5
- package/src/types/routing.ts +18 -0
- package/src/types/schema.ts +23 -0
- package/src/types/session.ts +207 -0
- package/src/types/tool.ts +29 -7
- package/src/utils/id.ts +0 -10
- package/src/utils/schema.ts +32 -0
- package/dist/cjs/core/ConditionEvaluator.d.ts +0 -72
- package/dist/cjs/core/ConditionEvaluator.d.ts.map +0 -1
- package/dist/cjs/core/ConditionEvaluator.js +0 -272
- package/dist/cjs/core/ConditionEvaluator.js.map +0 -1
- package/dist/cjs/core/Observation.d.ts +0 -24
- package/dist/cjs/core/Observation.d.ts.map +0 -1
- package/dist/cjs/core/Observation.js +0 -39
- package/dist/cjs/core/Observation.js.map +0 -1
- package/dist/cjs/core/PreparationEngine.d.ts +0 -116
- package/dist/cjs/core/PreparationEngine.d.ts.map +0 -1
- package/dist/cjs/core/PreparationEngine.js +0 -353
- package/dist/cjs/core/PreparationEngine.js.map +0 -1
- package/dist/cjs/core/PromptBuilder.d.ts +0 -136
- package/dist/cjs/core/PromptBuilder.d.ts.map +0 -1
- package/dist/cjs/core/PromptBuilder.js +0 -421
- package/dist/cjs/core/PromptBuilder.js.map +0 -1
- package/dist/cjs/types/observation.d.ts +0 -27
- package/dist/cjs/types/observation.d.ts.map +0 -1
- package/dist/cjs/types/observation.js +0 -6
- package/dist/cjs/types/observation.js.map +0 -1
- package/dist/cjs/types/prompt.d.ts +0 -46
- package/dist/cjs/types/prompt.d.ts.map +0 -1
- package/dist/cjs/types/prompt.js +0 -19
- package/dist/cjs/types/prompt.js.map +0 -1
- package/dist/core/ConditionEvaluator.d.ts +0 -72
- package/dist/core/ConditionEvaluator.d.ts.map +0 -1
- package/dist/core/ConditionEvaluator.js +0 -268
- package/dist/core/ConditionEvaluator.js.map +0 -1
- package/dist/core/Observation.d.ts +0 -24
- package/dist/core/Observation.d.ts.map +0 -1
- package/dist/core/Observation.js +0 -35
- package/dist/core/Observation.js.map +0 -1
- package/dist/core/PreparationEngine.d.ts +0 -116
- package/dist/core/PreparationEngine.d.ts.map +0 -1
- package/dist/core/PreparationEngine.js +0 -349
- package/dist/core/PreparationEngine.js.map +0 -1
- package/dist/core/PromptBuilder.d.ts +0 -136
- package/dist/core/PromptBuilder.d.ts.map +0 -1
- package/dist/core/PromptBuilder.js +0 -417
- package/dist/core/PromptBuilder.js.map +0 -1
- package/dist/types/observation.d.ts +0 -27
- package/dist/types/observation.d.ts.map +0 -1
- package/dist/types/observation.js +0 -5
- package/dist/types/observation.js.map +0 -1
- package/dist/types/prompt.d.ts +0 -46
- package/dist/types/prompt.d.ts.map +0 -1
- package/dist/types/prompt.js +0 -16
- package/dist/types/prompt.js.map +0 -1
- package/docs/STRUCTURE.md +0 -58
- package/src/core/ConditionEvaluator.ts +0 -381
- package/src/core/Observation.ts +0 -47
- package/src/core/PreparationEngine.ts +0 -561
- package/src/core/PromptBuilder.ts +0 -617
- package/src/types/observation.ts +0 -29
- package/src/types/prompt.ts +0 -49
package/dist/cjs/core/Agent.js
CHANGED
|
@@ -4,12 +4,27 @@
|
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.Agent = void 0;
|
|
7
|
+
const session_1 = require("../types/session");
|
|
8
|
+
const history_1 = require("../types/history");
|
|
9
|
+
const PromptComposer_1 = require("./PromptComposer");
|
|
7
10
|
const Route_1 = require("./Route");
|
|
8
11
|
const DomainRegistry_1 = require("./DomainRegistry");
|
|
9
|
-
const PromptBuilder_1 = require("./PromptBuilder");
|
|
10
|
-
const Observation_1 = require("./Observation");
|
|
11
12
|
const PersistenceManager_1 = require("./PersistenceManager");
|
|
12
|
-
const
|
|
13
|
+
const RoutingEngine_1 = require("./RoutingEngine");
|
|
14
|
+
const ResponseEngine_1 = require("./ResponseEngine");
|
|
15
|
+
const ToolExecutor_1 = require("./ToolExecutor");
|
|
16
|
+
/**
|
|
17
|
+
* Helper to extract last message from history
|
|
18
|
+
*/
|
|
19
|
+
function getLastMessageFromHistory(history) {
|
|
20
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
21
|
+
const event = history[i];
|
|
22
|
+
if (event.kind === history_1.EventKind.MESSAGE) {
|
|
23
|
+
return event.data.message;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return "";
|
|
27
|
+
}
|
|
13
28
|
/**
|
|
14
29
|
* Main Agent class with generic context support
|
|
15
30
|
*/
|
|
@@ -19,28 +34,26 @@ class Agent {
|
|
|
19
34
|
this.terms = [];
|
|
20
35
|
this.guidelines = [];
|
|
21
36
|
this.capabilities = [];
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
38
|
this.routes = [];
|
|
23
|
-
this.observations = [];
|
|
24
39
|
this.domainRegistry = new DomainRegistry_1.DomainRegistry();
|
|
25
40
|
/**
|
|
26
41
|
* Dynamic domain property - populated via addDomain
|
|
27
42
|
*/
|
|
28
43
|
this.domain = {};
|
|
29
|
-
// Initialize with default values
|
|
30
|
-
if (!this.options.maxEngineIterations) {
|
|
31
|
-
this.options.maxEngineIterations = 1;
|
|
32
|
-
}
|
|
33
44
|
// Validate context configuration
|
|
34
45
|
if (options.context !== undefined && options.contextProvider) {
|
|
35
46
|
throw new Error("Cannot provide both 'context' and 'contextProvider'. Choose one.");
|
|
36
47
|
}
|
|
37
48
|
// Initialize context if provided
|
|
38
49
|
this.context = options.context;
|
|
39
|
-
// Initialize
|
|
40
|
-
this.
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
// Initialize routing and response engines
|
|
51
|
+
this.routingEngine = new RoutingEngine_1.RoutingEngine({
|
|
52
|
+
maxCandidates: 5,
|
|
53
|
+
allowRouteSwitch: true,
|
|
54
|
+
switchThreshold: 70,
|
|
43
55
|
});
|
|
56
|
+
this.responseEngine = new ResponseEngine_1.ResponseEngine();
|
|
44
57
|
// Initialize persistence if configured
|
|
45
58
|
if (options.persistence) {
|
|
46
59
|
this.persistenceManager = new PersistenceManager_1.PersistenceManager(options.persistence);
|
|
@@ -70,23 +83,6 @@ class Agent {
|
|
|
70
83
|
this.createRoute(routeOptions);
|
|
71
84
|
});
|
|
72
85
|
}
|
|
73
|
-
if (options.observations) {
|
|
74
|
-
options.observations.forEach((obsOptions) => {
|
|
75
|
-
const obs = this.createObservation(obsOptions.description);
|
|
76
|
-
// If route refs were provided, resolve and disambiguate
|
|
77
|
-
if (obsOptions.routeRefs && obsOptions.routeRefs.length > 0) {
|
|
78
|
-
const resolvedRoutes = obsOptions.routeRefs
|
|
79
|
-
.map((ref) => {
|
|
80
|
-
// Try to find route by ID or title
|
|
81
|
-
return this.routes.find((r) => r.id === ref || r.title === ref);
|
|
82
|
-
})
|
|
83
|
-
.filter((r) => r !== undefined);
|
|
84
|
-
if (resolvedRoutes.length > 0) {
|
|
85
|
-
obs.disambiguate(resolvedRoutes);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
86
|
}
|
|
91
87
|
/**
|
|
92
88
|
* Get agent name
|
|
@@ -108,6 +104,7 @@ class Agent {
|
|
|
108
104
|
}
|
|
109
105
|
/**
|
|
110
106
|
* Create a new route (journey)
|
|
107
|
+
* @template TExtracted - Type of data extracted throughout the route
|
|
111
108
|
*/
|
|
112
109
|
createRoute(options) {
|
|
113
110
|
const route = new Route_1.Route(options);
|
|
@@ -144,21 +141,28 @@ class Agent {
|
|
|
144
141
|
this.capabilities.push(capabilityWithId);
|
|
145
142
|
return this;
|
|
146
143
|
}
|
|
147
|
-
/**
|
|
148
|
-
* Create an observation for disambiguation
|
|
149
|
-
*/
|
|
150
|
-
createObservation(description) {
|
|
151
|
-
const observation = new Observation_1.Observation({ description });
|
|
152
|
-
this.observations.push(observation);
|
|
153
|
-
return observation;
|
|
154
|
-
}
|
|
155
144
|
/**
|
|
156
145
|
* Add a domain with its tools/methods
|
|
146
|
+
* Automatically tags all ToolRef objects with their domain name for security enforcement
|
|
157
147
|
*/
|
|
158
148
|
addDomain(name, domainObject) {
|
|
159
|
-
this
|
|
149
|
+
// Tag all tools in this domain with the domain name for security enforcement
|
|
150
|
+
const taggedDomain = { ...domainObject };
|
|
151
|
+
for (const key in taggedDomain) {
|
|
152
|
+
const value = taggedDomain[key];
|
|
153
|
+
// Check if value is a ToolRef (has handler, id, name properties)
|
|
154
|
+
if (value &&
|
|
155
|
+
typeof value === "object" &&
|
|
156
|
+
"handler" in value &&
|
|
157
|
+
"id" in value &&
|
|
158
|
+
"name" in value) {
|
|
159
|
+
// Tag the tool with its domain name
|
|
160
|
+
value.domainName = name;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
this.domainRegistry.register(name, taggedDomain);
|
|
160
164
|
// Attach to the domain property for easy access
|
|
161
|
-
this.domain[name] =
|
|
165
|
+
this.domain[name] = taggedDomain;
|
|
162
166
|
}
|
|
163
167
|
/**
|
|
164
168
|
* Update the agent's context
|
|
@@ -176,6 +180,26 @@ class Agent {
|
|
|
176
180
|
await this.options.hooks.onContextUpdate(this.context, previousContext);
|
|
177
181
|
}
|
|
178
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Update extracted data in session with lifecycle hook support
|
|
185
|
+
* Triggers the onExtractedUpdate lifecycle hook if configured
|
|
186
|
+
* @internal
|
|
187
|
+
*/
|
|
188
|
+
async updateExtracted(session, extractedUpdate) {
|
|
189
|
+
const previousExtracted = { ...session.extracted };
|
|
190
|
+
// Merge new extracted data
|
|
191
|
+
let newExtracted = {
|
|
192
|
+
...session.extracted,
|
|
193
|
+
...extractedUpdate,
|
|
194
|
+
};
|
|
195
|
+
// Trigger lifecycle hook if configured
|
|
196
|
+
if (this.options.hooks?.onExtractedUpdate) {
|
|
197
|
+
const updatedExtracted = (await this.options.hooks.onExtractedUpdate(newExtracted, previousExtracted));
|
|
198
|
+
newExtracted = updatedExtracted;
|
|
199
|
+
}
|
|
200
|
+
// Return updated session
|
|
201
|
+
return (0, session_1.mergeExtracted)(session, newExtracted);
|
|
202
|
+
}
|
|
179
203
|
/**
|
|
180
204
|
* Get current context (fetches from provider if configured)
|
|
181
205
|
* @internal
|
|
@@ -188,6 +212,46 @@ class Agent {
|
|
|
188
212
|
// Otherwise return the stored context
|
|
189
213
|
return this.context;
|
|
190
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Determine the next state in a route based on extracted data
|
|
217
|
+
* @internal
|
|
218
|
+
*/
|
|
219
|
+
getNextState(route, currentState, extracted) {
|
|
220
|
+
// If no current state, start from initial state
|
|
221
|
+
if (!currentState) {
|
|
222
|
+
// Check if initial state should be skipped
|
|
223
|
+
if (route.initialState.shouldSkip(extracted)) {
|
|
224
|
+
return this.getNextState(route, route.initialState, extracted);
|
|
225
|
+
}
|
|
226
|
+
return route.initialState;
|
|
227
|
+
}
|
|
228
|
+
// Get transitions from current state
|
|
229
|
+
const transitions = currentState.getTransitions();
|
|
230
|
+
// If no transitions, stay in current state
|
|
231
|
+
if (transitions.length === 0) {
|
|
232
|
+
return currentState;
|
|
233
|
+
}
|
|
234
|
+
// Try to find the next state to transition to
|
|
235
|
+
for (const transition of transitions) {
|
|
236
|
+
const target = transition.getTarget();
|
|
237
|
+
if (!target)
|
|
238
|
+
continue;
|
|
239
|
+
// Check if target state should be skipped
|
|
240
|
+
if (target.shouldSkip(extracted)) {
|
|
241
|
+
// Recursively find next non-skipped state
|
|
242
|
+
return this.getNextState(route, target, extracted);
|
|
243
|
+
}
|
|
244
|
+
// Check if target state has required data
|
|
245
|
+
if (!target.hasRequiredData(extracted)) {
|
|
246
|
+
// Cannot enter this state yet, stay in current state
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
// Found valid next state
|
|
250
|
+
return target;
|
|
251
|
+
}
|
|
252
|
+
// No valid transition found, stay in current state
|
|
253
|
+
return currentState;
|
|
254
|
+
}
|
|
191
255
|
/**
|
|
192
256
|
* Generate a response based on history and context as a stream
|
|
193
257
|
*/
|
|
@@ -202,145 +266,208 @@ class Agent {
|
|
|
202
266
|
this.context = currentContext;
|
|
203
267
|
}
|
|
204
268
|
// Merge context with override
|
|
205
|
-
|
|
269
|
+
const effectiveContext = {
|
|
206
270
|
...currentContext,
|
|
207
271
|
...contextOverride,
|
|
208
272
|
};
|
|
209
|
-
//
|
|
210
|
-
|
|
211
|
-
// 1
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
273
|
+
// Initialize or get session
|
|
274
|
+
let session = params.session || (0, session_1.createSession)();
|
|
275
|
+
// PHASE 1: TOOL EXECUTION - Execute tools if current state has toolState
|
|
276
|
+
if (session.currentRoute && session.currentState) {
|
|
277
|
+
const currentRoute = this.routes.find((r) => r.id === session.currentRoute?.id);
|
|
278
|
+
if (currentRoute) {
|
|
279
|
+
const currentState = currentRoute.getState(session.currentState.id);
|
|
280
|
+
if (currentState) {
|
|
281
|
+
const transitions = currentState.getTransitions();
|
|
282
|
+
const toolTransition = transitions.find((t) => t.spec.toolState);
|
|
283
|
+
if (toolTransition?.spec.toolState) {
|
|
284
|
+
const toolExecutor = new ToolExecutor_1.ToolExecutor();
|
|
285
|
+
// Get allowed domains from current route for security enforcement
|
|
286
|
+
const allowedDomains = currentRoute.getDomains();
|
|
287
|
+
const result = await toolExecutor.executeTool(toolTransition.spec.toolState, effectiveContext, this.updateContext.bind(this), history, session.extracted, allowedDomains);
|
|
288
|
+
// Update context with tool results
|
|
289
|
+
if (result.contextUpdate) {
|
|
290
|
+
await this.updateContext(result.contextUpdate);
|
|
291
|
+
}
|
|
292
|
+
// Update extracted data with tool results
|
|
293
|
+
if (result.extractedUpdate) {
|
|
294
|
+
session = await this.updateExtracted(session, result.extractedUpdate);
|
|
295
|
+
console.log(`[Agent] Tool updated extracted data:`, result.extractedUpdate);
|
|
296
|
+
}
|
|
297
|
+
console.log(`[Agent] Executed tool: ${result.toolName} (success: ${result.success})`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
235
301
|
}
|
|
236
|
-
//
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (this.
|
|
240
|
-
|
|
302
|
+
// PHASE 2: ROUTING - Determine which route to use
|
|
303
|
+
let selectedRoute;
|
|
304
|
+
let responseDirectives;
|
|
305
|
+
if (this.routes.length > 0) {
|
|
306
|
+
// Get last user message
|
|
307
|
+
const lastUserMessage = getLastMessageFromHistory(history);
|
|
308
|
+
// Build routing schema
|
|
309
|
+
const routingSchema = this.routingEngine.buildDynamicRoutingSchema(this.routes);
|
|
310
|
+
// Build routing prompt with session context
|
|
311
|
+
const routingPrompt = this.routingEngine.buildRoutingPrompt(history, this.routes, lastUserMessage, {
|
|
241
312
|
name: this.options.name,
|
|
313
|
+
goal: this.options.goal,
|
|
242
314
|
description: this.options.description,
|
|
315
|
+
personality: this.options.personality,
|
|
316
|
+
}, session // Pass session for context-aware routing
|
|
317
|
+
);
|
|
318
|
+
// Call AI to score routes (non-streaming for routing decision)
|
|
319
|
+
const routingResult = await this.options.ai.generateMessage({
|
|
320
|
+
prompt: routingPrompt,
|
|
321
|
+
history,
|
|
322
|
+
context: effectiveContext,
|
|
323
|
+
signal,
|
|
324
|
+
parameters: {
|
|
325
|
+
jsonSchema: routingSchema,
|
|
326
|
+
schemaName: "routing_output",
|
|
327
|
+
},
|
|
243
328
|
});
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
description: obs.description,
|
|
268
|
-
routes: obs.getRoutes().map((routeRef) => {
|
|
269
|
-
const route = this.routes.find((r) => r.id === routeRef.id);
|
|
270
|
-
return { title: route?.title || routeRef.id };
|
|
271
|
-
}),
|
|
272
|
-
}))
|
|
273
|
-
.filter((obs) => obs.routes.length > 0);
|
|
274
|
-
if (observationsWithRoutes.length > 0) {
|
|
275
|
-
promptBuilder.addObservations(observationsWithRoutes);
|
|
329
|
+
// Select best route from scores
|
|
330
|
+
if (routingResult.structured?.routes) {
|
|
331
|
+
const decision = this.routingEngine.decideRouteFromScores({
|
|
332
|
+
context: routingResult.structured.context,
|
|
333
|
+
routes: routingResult.structured.routes,
|
|
334
|
+
responseDirectives: routingResult.structured.responseDirectives,
|
|
335
|
+
});
|
|
336
|
+
selectedRoute = this.routes.find((r) => r.id === decision.routeId);
|
|
337
|
+
responseDirectives = routingResult.structured.responseDirectives;
|
|
338
|
+
if (selectedRoute) {
|
|
339
|
+
console.log(`[Agent] Selected route: ${selectedRoute.title} (score: ${decision.maxScore})`);
|
|
340
|
+
// Update session with selected route (if changed)
|
|
341
|
+
if (!session.currentRoute ||
|
|
342
|
+
session.currentRoute.id !== selectedRoute.id) {
|
|
343
|
+
session = (0, session_1.enterRoute)(session, selectedRoute.id, selectedRoute.title);
|
|
344
|
+
// Merge initial data if provided by the route
|
|
345
|
+
if (selectedRoute.initialData) {
|
|
346
|
+
session = (0, session_1.mergeExtracted)(session, selectedRoute.initialData);
|
|
347
|
+
console.log(`[Agent] Merged initial data:`, selectedRoute.initialData);
|
|
348
|
+
}
|
|
349
|
+
console.log(`[Agent] Entered route: ${selectedRoute.title}`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
276
352
|
}
|
|
277
353
|
}
|
|
278
|
-
//
|
|
279
|
-
if (
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
354
|
+
// PHASE 3: RESPONSE - Stream message using selected route
|
|
355
|
+
if (selectedRoute) {
|
|
356
|
+
// Determine next state based on current extracted data
|
|
357
|
+
const currentStateRef = session.currentState;
|
|
358
|
+
const currentState = currentStateRef
|
|
359
|
+
? selectedRoute.getState(currentStateRef.id)
|
|
360
|
+
: undefined;
|
|
361
|
+
const nextState = this.getNextState(selectedRoute, currentState, session.extracted);
|
|
362
|
+
// Update session with next state
|
|
363
|
+
session = (0, session_1.enterState)(session, nextState.id, nextState.description);
|
|
364
|
+
console.log(`[Agent] Entered state: ${nextState.id}`);
|
|
365
|
+
// Get last user message
|
|
366
|
+
const lastUserMessage = getLastMessageFromHistory(history);
|
|
367
|
+
// Build response schema for this route (with gather fields from state)
|
|
368
|
+
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, nextState);
|
|
369
|
+
// Build response prompt
|
|
370
|
+
const responsePrompt = this.responseEngine.buildResponsePrompt(selectedRoute, selectedRoute.getRules(), selectedRoute.getProhibitions(), responseDirectives, history, lastUserMessage, {
|
|
371
|
+
name: this.options.name,
|
|
372
|
+
goal: this.options.goal,
|
|
373
|
+
description: this.options.description,
|
|
374
|
+
personality: this.options.personality,
|
|
375
|
+
});
|
|
376
|
+
// Generate message stream using AI provider
|
|
377
|
+
const stream = this.options.ai.generateMessageStream({
|
|
378
|
+
prompt: responsePrompt,
|
|
379
|
+
history,
|
|
380
|
+
context: effectiveContext,
|
|
381
|
+
signal,
|
|
382
|
+
parameters: {
|
|
383
|
+
jsonSchema: responseSchema,
|
|
384
|
+
schemaName: "response_stream_output",
|
|
385
|
+
},
|
|
386
|
+
});
|
|
387
|
+
// Stream chunks to caller
|
|
388
|
+
for await (const chunk of stream) {
|
|
389
|
+
const toolCalls = undefined;
|
|
390
|
+
// Extract gathered data on final chunk
|
|
391
|
+
if (chunk.done && chunk.structured && nextState.gatherFields) {
|
|
392
|
+
const gatheredData = {};
|
|
393
|
+
// The structured response includes both base fields and gathered extraction fields
|
|
394
|
+
const structuredData = chunk.structured;
|
|
395
|
+
for (const field of nextState.gatherFields) {
|
|
396
|
+
if (field in structuredData) {
|
|
397
|
+
gatheredData[field] = structuredData[field];
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
// Merge gathered data into session
|
|
401
|
+
if (Object.keys(gatheredData).length > 0) {
|
|
402
|
+
session = await this.updateExtracted(session, gatheredData);
|
|
403
|
+
console.log(`[Agent] Extracted data:`, gatheredData);
|
|
321
404
|
}
|
|
322
405
|
}
|
|
323
|
-
//
|
|
324
|
-
if (chunk.
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
406
|
+
// Extract any additional data from structured response on final chunk
|
|
407
|
+
if (chunk.done &&
|
|
408
|
+
chunk.structured &&
|
|
409
|
+
typeof chunk.structured === "object" &&
|
|
410
|
+
"contextUpdate" in chunk.structured) {
|
|
411
|
+
await this.updateContext(chunk.structured
|
|
412
|
+
.contextUpdate);
|
|
329
413
|
}
|
|
330
|
-
//
|
|
331
|
-
if (chunk.
|
|
332
|
-
|
|
333
|
-
|
|
414
|
+
// Auto-save session state on final chunk
|
|
415
|
+
if (chunk.done &&
|
|
416
|
+
this.persistenceManager &&
|
|
417
|
+
session.metadata?.sessionId &&
|
|
418
|
+
this.options.persistence?.autoSave !== false) {
|
|
419
|
+
await this.persistenceManager.saveSessionState(session.metadata.sessionId, session);
|
|
420
|
+
console.log(`[Agent] Auto-saved session state to persistence: ${session.metadata.sessionId}`);
|
|
334
421
|
}
|
|
422
|
+
yield {
|
|
423
|
+
delta: chunk.delta,
|
|
424
|
+
accumulated: chunk.accumulated,
|
|
425
|
+
done: chunk.done,
|
|
426
|
+
session, // Return updated session
|
|
427
|
+
toolCalls,
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
// Fallback: No routes defined, stream a simple response
|
|
433
|
+
const fallbackPrompt = new PromptComposer_1.PromptComposer()
|
|
434
|
+
.addAgentMeta({
|
|
435
|
+
name: this.options.name,
|
|
436
|
+
goal: this.options.goal,
|
|
437
|
+
description: this.options.description,
|
|
438
|
+
})
|
|
439
|
+
.addPersonality(this.options.personality)
|
|
440
|
+
.addInteractionHistory(history)
|
|
441
|
+
.addGlossary(this.terms)
|
|
442
|
+
.addGuidelines(this.guidelines)
|
|
443
|
+
.addCapabilities(this.capabilities)
|
|
444
|
+
.build();
|
|
445
|
+
const stream = this.options.ai.generateMessageStream({
|
|
446
|
+
prompt: fallbackPrompt,
|
|
447
|
+
history,
|
|
448
|
+
context: effectiveContext,
|
|
449
|
+
signal,
|
|
450
|
+
parameters: {
|
|
451
|
+
jsonSchema: {
|
|
452
|
+
type: "object",
|
|
453
|
+
properties: {
|
|
454
|
+
message: { type: "string" },
|
|
455
|
+
},
|
|
456
|
+
required: ["message"],
|
|
457
|
+
additionalProperties: false,
|
|
458
|
+
},
|
|
459
|
+
schemaName: "fallback_stream_response",
|
|
460
|
+
},
|
|
461
|
+
});
|
|
462
|
+
for await (const chunk of stream) {
|
|
463
|
+
yield {
|
|
464
|
+
delta: chunk.delta,
|
|
465
|
+
accumulated: chunk.accumulated,
|
|
466
|
+
done: chunk.done,
|
|
467
|
+
session, // Return updated session
|
|
468
|
+
toolCalls: undefined,
|
|
469
|
+
};
|
|
335
470
|
}
|
|
336
|
-
yield {
|
|
337
|
-
delta: chunk.delta,
|
|
338
|
-
accumulated: chunk.accumulated,
|
|
339
|
-
done: chunk.done,
|
|
340
|
-
route: route || undefined,
|
|
341
|
-
state: state || undefined,
|
|
342
|
-
toolCalls,
|
|
343
|
-
};
|
|
344
471
|
}
|
|
345
472
|
}
|
|
346
473
|
/**
|
|
@@ -357,142 +484,194 @@ class Agent {
|
|
|
357
484
|
this.context = currentContext;
|
|
358
485
|
}
|
|
359
486
|
// Merge context with override
|
|
360
|
-
|
|
487
|
+
const effectiveContext = {
|
|
361
488
|
...currentContext,
|
|
362
489
|
...contextOverride,
|
|
363
490
|
};
|
|
364
|
-
//
|
|
365
|
-
|
|
366
|
-
// 1
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
491
|
+
// Initialize or get session
|
|
492
|
+
let session = params.session || (0, session_1.createSession)();
|
|
493
|
+
// PHASE 1: TOOL EXECUTION - Execute tools if current state has toolState
|
|
494
|
+
if (session.currentRoute && session.currentState) {
|
|
495
|
+
const currentRoute = this.routes.find((r) => r.id === session.currentRoute?.id);
|
|
496
|
+
if (currentRoute) {
|
|
497
|
+
const currentState = currentRoute.getState(session.currentState.id);
|
|
498
|
+
if (currentState) {
|
|
499
|
+
const transitions = currentState.getTransitions();
|
|
500
|
+
const toolTransition = transitions.find((t) => t.spec.toolState);
|
|
501
|
+
if (toolTransition?.spec.toolState) {
|
|
502
|
+
const toolExecutor = new ToolExecutor_1.ToolExecutor();
|
|
503
|
+
// Get allowed domains from current route for security enforcement
|
|
504
|
+
const allowedDomains = currentRoute.getDomains();
|
|
505
|
+
const result = await toolExecutor.executeTool(toolTransition.spec.toolState, effectiveContext, this.updateContext.bind(this), history, session.extracted, allowedDomains);
|
|
506
|
+
// Update context with tool results
|
|
507
|
+
if (result.contextUpdate) {
|
|
508
|
+
await this.updateContext(result.contextUpdate);
|
|
509
|
+
}
|
|
510
|
+
// Update extracted data with tool results
|
|
511
|
+
if (result.extractedUpdate) {
|
|
512
|
+
session = await this.updateExtracted(session, result.extractedUpdate);
|
|
513
|
+
console.log(`[Agent] Tool updated extracted data:`, result.extractedUpdate);
|
|
514
|
+
}
|
|
515
|
+
console.log(`[Agent] Executed tool: ${result.toolName} (success: ${result.success})`);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
390
519
|
}
|
|
391
|
-
//
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
if (this.
|
|
395
|
-
|
|
520
|
+
// PHASE 2: ROUTING - Determine which route to use
|
|
521
|
+
let selectedRoute;
|
|
522
|
+
let responseDirectives;
|
|
523
|
+
if (this.routes.length > 0) {
|
|
524
|
+
// Get last user message
|
|
525
|
+
const lastUserMessage = getLastMessageFromHistory(history);
|
|
526
|
+
// Build routing schema
|
|
527
|
+
const routingSchema = this.routingEngine.buildDynamicRoutingSchema(this.routes);
|
|
528
|
+
// Build routing prompt with session context
|
|
529
|
+
const routingPrompt = this.routingEngine.buildRoutingPrompt(history, this.routes, lastUserMessage, {
|
|
396
530
|
name: this.options.name,
|
|
531
|
+
goal: this.options.goal,
|
|
397
532
|
description: this.options.description,
|
|
533
|
+
personality: this.options.personality,
|
|
534
|
+
}, session // Pass session for context-aware routing
|
|
535
|
+
);
|
|
536
|
+
// Call AI to score routes
|
|
537
|
+
const routingResult = await this.options.ai.generateMessage({
|
|
538
|
+
prompt: routingPrompt,
|
|
539
|
+
history,
|
|
540
|
+
context: effectiveContext,
|
|
541
|
+
signal,
|
|
542
|
+
parameters: {
|
|
543
|
+
jsonSchema: routingSchema,
|
|
544
|
+
schemaName: "routing_output",
|
|
545
|
+
},
|
|
398
546
|
});
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
description: obs.description,
|
|
423
|
-
routes: obs.getRoutes().map((routeRef) => {
|
|
424
|
-
const route = this.routes.find((r) => r.id === routeRef.id);
|
|
425
|
-
return { title: route?.title || routeRef.id };
|
|
426
|
-
}),
|
|
427
|
-
}))
|
|
428
|
-
.filter((obs) => obs.routes.length > 0);
|
|
429
|
-
if (observationsWithRoutes.length > 0) {
|
|
430
|
-
promptBuilder.addObservations(observationsWithRoutes);
|
|
547
|
+
// Select best route from scores
|
|
548
|
+
if (routingResult.structured?.routes) {
|
|
549
|
+
const decision = this.routingEngine.decideRouteFromScores({
|
|
550
|
+
context: routingResult.structured.context,
|
|
551
|
+
routes: routingResult.structured.routes,
|
|
552
|
+
responseDirectives: routingResult.structured.responseDirectives,
|
|
553
|
+
});
|
|
554
|
+
selectedRoute = this.routes.find((r) => r.id === decision.routeId);
|
|
555
|
+
responseDirectives = routingResult.structured.responseDirectives;
|
|
556
|
+
if (selectedRoute) {
|
|
557
|
+
console.log(`[Agent] Selected route: ${selectedRoute.title} (score: ${decision.maxScore})`);
|
|
558
|
+
// Update session with selected route (if changed)
|
|
559
|
+
if (!session.currentRoute ||
|
|
560
|
+
session.currentRoute.id !== selectedRoute.id) {
|
|
561
|
+
session = (0, session_1.enterRoute)(session, selectedRoute.id, selectedRoute.title);
|
|
562
|
+
// Merge initial data if provided by the route
|
|
563
|
+
if (selectedRoute.initialData) {
|
|
564
|
+
session = (0, session_1.mergeExtracted)(session, selectedRoute.initialData);
|
|
565
|
+
console.log(`[Agent] Merged initial data:`, selectedRoute.initialData);
|
|
566
|
+
}
|
|
567
|
+
console.log(`[Agent] Entered route: ${selectedRoute.title}`);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
431
570
|
}
|
|
432
571
|
}
|
|
433
|
-
//
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
message = result.structured
|
|
469
|
-
//
|
|
470
|
-
if (result.structured.
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
572
|
+
// PHASE 3: RESPONSE - Generate message using selected route
|
|
573
|
+
let message;
|
|
574
|
+
const toolCalls = undefined;
|
|
575
|
+
if (selectedRoute) {
|
|
576
|
+
// Determine next state based on current extracted data
|
|
577
|
+
const currentStateRef = session.currentState;
|
|
578
|
+
const currentState = currentStateRef
|
|
579
|
+
? selectedRoute.getState(currentStateRef.id)
|
|
580
|
+
: undefined;
|
|
581
|
+
const nextState = this.getNextState(selectedRoute, currentState, session.extracted);
|
|
582
|
+
// Update session with next state
|
|
583
|
+
session = (0, session_1.enterState)(session, nextState.id, nextState.description);
|
|
584
|
+
console.log(`[Agent] Entered state: ${nextState.id}`);
|
|
585
|
+
// Get last user message
|
|
586
|
+
const lastUserMessage = getLastMessageFromHistory(history);
|
|
587
|
+
// Build response schema for this route (with gather fields from state)
|
|
588
|
+
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, nextState);
|
|
589
|
+
// Build response prompt
|
|
590
|
+
const responsePrompt = this.responseEngine.buildResponsePrompt(selectedRoute, selectedRoute.getRules(), selectedRoute.getProhibitions(), responseDirectives, history, lastUserMessage, {
|
|
591
|
+
name: this.options.name,
|
|
592
|
+
goal: this.options.goal,
|
|
593
|
+
description: this.options.description,
|
|
594
|
+
personality: this.options.personality,
|
|
595
|
+
});
|
|
596
|
+
// Generate message using AI provider
|
|
597
|
+
const result = await this.options.ai.generateMessage({
|
|
598
|
+
prompt: responsePrompt,
|
|
599
|
+
history,
|
|
600
|
+
context: effectiveContext,
|
|
601
|
+
signal,
|
|
602
|
+
parameters: {
|
|
603
|
+
jsonSchema: responseSchema,
|
|
604
|
+
schemaName: "response_output",
|
|
605
|
+
},
|
|
606
|
+
});
|
|
607
|
+
message = result.structured?.message || result.message;
|
|
608
|
+
// Extract gathered data from response
|
|
609
|
+
if (result.structured && nextState.gatherFields) {
|
|
610
|
+
const gatheredData = {};
|
|
611
|
+
// The structured response includes both base fields and gathered extraction fields
|
|
612
|
+
const structuredData = result.structured;
|
|
613
|
+
for (const field of nextState.gatherFields) {
|
|
614
|
+
if (field in structuredData) {
|
|
615
|
+
gatheredData[field] = structuredData[field];
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
// Merge gathered data into session
|
|
619
|
+
if (Object.keys(gatheredData).length > 0) {
|
|
620
|
+
session = (0, session_1.mergeExtracted)(session, gatheredData);
|
|
621
|
+
console.log(`[Agent] Extracted data:`, gatheredData);
|
|
477
622
|
}
|
|
478
623
|
}
|
|
479
|
-
//
|
|
480
|
-
if (result.structured
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
}
|
|
486
|
-
// Extract tool calls
|
|
487
|
-
if (result.structured.toolCalls &&
|
|
488
|
-
result.structured.toolCalls.length > 0) {
|
|
489
|
-
toolCalls = result.structured.toolCalls;
|
|
624
|
+
// Extract any additional data from structured response
|
|
625
|
+
if (result.structured &&
|
|
626
|
+
typeof result.structured === "object" &&
|
|
627
|
+
"contextUpdate" in result.structured) {
|
|
628
|
+
await this.updateContext(result.structured
|
|
629
|
+
.contextUpdate);
|
|
490
630
|
}
|
|
491
631
|
}
|
|
632
|
+
else {
|
|
633
|
+
// Fallback: No routes defined, generate a simple response
|
|
634
|
+
const fallbackPrompt = new PromptComposer_1.PromptComposer()
|
|
635
|
+
.addAgentMeta({
|
|
636
|
+
name: this.options.name,
|
|
637
|
+
goal: this.options.goal,
|
|
638
|
+
description: this.options.description,
|
|
639
|
+
})
|
|
640
|
+
.addPersonality(this.options.personality)
|
|
641
|
+
.addInteractionHistory(history)
|
|
642
|
+
.addGlossary(this.terms)
|
|
643
|
+
.addGuidelines(this.guidelines)
|
|
644
|
+
.addCapabilities(this.capabilities)
|
|
645
|
+
.build();
|
|
646
|
+
const result = await this.options.ai.generateMessage({
|
|
647
|
+
prompt: fallbackPrompt,
|
|
648
|
+
history,
|
|
649
|
+
context: effectiveContext,
|
|
650
|
+
signal,
|
|
651
|
+
parameters: {
|
|
652
|
+
jsonSchema: {
|
|
653
|
+
type: "object",
|
|
654
|
+
properties: {
|
|
655
|
+
message: { type: "string" },
|
|
656
|
+
},
|
|
657
|
+
required: ["message"],
|
|
658
|
+
additionalProperties: false,
|
|
659
|
+
},
|
|
660
|
+
schemaName: "fallback_response",
|
|
661
|
+
},
|
|
662
|
+
});
|
|
663
|
+
message = result.structured?.message || result.message;
|
|
664
|
+
}
|
|
665
|
+
// Auto-save session state to persistence if configured
|
|
666
|
+
if (this.persistenceManager &&
|
|
667
|
+
session.metadata?.sessionId &&
|
|
668
|
+
this.options.persistence?.autoSave !== false) {
|
|
669
|
+
await this.persistenceManager.saveSessionState(session.metadata.sessionId, session);
|
|
670
|
+
console.log(`[Agent] Auto-saved session state to persistence: ${session.metadata.sessionId}`);
|
|
671
|
+
}
|
|
492
672
|
return {
|
|
493
673
|
message,
|
|
494
|
-
|
|
495
|
-
state: state || undefined,
|
|
674
|
+
session, // Return updated session with route/state info
|
|
496
675
|
toolCalls,
|
|
497
676
|
};
|
|
498
677
|
}
|
|
@@ -520,12 +699,6 @@ class Agent {
|
|
|
520
699
|
getCapabilities() {
|
|
521
700
|
return [...this.capabilities];
|
|
522
701
|
}
|
|
523
|
-
/**
|
|
524
|
-
* Get all observations
|
|
525
|
-
*/
|
|
526
|
-
getObservations() {
|
|
527
|
-
return [...this.observations];
|
|
528
|
-
}
|
|
529
702
|
/**
|
|
530
703
|
* Get the domain registry
|
|
531
704
|
*/
|