@falai/agent 1.1.1 → 1.1.2
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/dist/cjs/core/Agent.d.ts +202 -67
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +366 -158
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/BatchExecutor.d.ts.map +1 -1
- package/dist/cjs/core/BatchExecutor.js +4 -2
- package/dist/cjs/core/BatchExecutor.js.map +1 -1
- package/dist/cjs/core/BatchPromptBuilder.d.ts.map +1 -1
- package/dist/cjs/core/BatchPromptBuilder.js +5 -2
- package/dist/cjs/core/BatchPromptBuilder.js.map +1 -1
- package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
- package/dist/cjs/core/ResponseEngine.js +6 -3
- 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 +18 -17
- package/dist/cjs/core/ResponseModal.js.map +1 -1
- package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
- package/dist/cjs/core/RoutingEngine.js +8 -73
- package/dist/cjs/core/RoutingEngine.js.map +1 -1
- package/dist/core/Agent.d.ts +202 -67
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +366 -158
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/BatchExecutor.d.ts.map +1 -1
- package/dist/core/BatchExecutor.js +4 -2
- package/dist/core/BatchExecutor.js.map +1 -1
- package/dist/core/BatchPromptBuilder.d.ts.map +1 -1
- package/dist/core/BatchPromptBuilder.js +5 -2
- package/dist/core/BatchPromptBuilder.js.map +1 -1
- package/dist/core/ResponseEngine.d.ts.map +1 -1
- package/dist/core/ResponseEngine.js +6 -3
- package/dist/core/ResponseEngine.js.map +1 -1
- package/dist/core/ResponseModal.d.ts.map +1 -1
- package/dist/core/ResponseModal.js +18 -17
- package/dist/core/ResponseModal.js.map +1 -1
- package/dist/core/RoutingEngine.d.ts.map +1 -1
- package/dist/core/RoutingEngine.js +8 -73
- package/dist/core/RoutingEngine.js.map +1 -1
- package/docs/api/README.md +2 -2
- package/docs/api/overview.md +1 -1
- package/docs/architecture/data-extraction-flow.md +17 -19
- package/docs/core/conversation-flows/data-collection.md +2 -2
- package/docs/core/error-handling.md +3 -4
- package/package.json +2 -2
- package/src/core/Agent.ts +427 -195
- package/src/core/BatchExecutor.ts +5 -2
- package/src/core/BatchPromptBuilder.ts +41 -38
- package/src/core/ResponseEngine.ts +56 -53
- package/src/core/ResponseModal.ts +79 -81
- package/src/core/RoutingEngine.ts +67 -149
package/dist/core/Agent.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core Agent implementation
|
|
3
3
|
*/
|
|
4
|
+
import { CompositionMode } from "../types";
|
|
4
5
|
import { mergeCollected, logger, LoggerLevel, render, createTemplateContext, createConditionEvaluator, } from "../utils";
|
|
5
6
|
import { Route } from "./Route";
|
|
6
7
|
import { PersistenceManager } from "./PersistenceManager";
|
|
@@ -36,14 +37,14 @@ class RouteConfigurationError extends Error {
|
|
|
36
37
|
export class Agent {
|
|
37
38
|
constructor(options) {
|
|
38
39
|
this.options = options;
|
|
39
|
-
this.
|
|
40
|
-
this.
|
|
41
|
-
this.
|
|
42
|
-
this.
|
|
43
|
-
this.
|
|
44
|
-
this.
|
|
45
|
-
this.
|
|
46
|
-
this.
|
|
40
|
+
this._terms = [];
|
|
41
|
+
this._guidelines = [];
|
|
42
|
+
this._tools = [];
|
|
43
|
+
this._routes = [];
|
|
44
|
+
this._rules = [];
|
|
45
|
+
this._prohibitions = [];
|
|
46
|
+
this._knowledgeBase = {};
|
|
47
|
+
this._collectedData = {};
|
|
47
48
|
// Set log level based on debug option
|
|
48
49
|
if (options.debug) {
|
|
49
50
|
logger.setLevel(LoggerLevel.DEBUG);
|
|
@@ -54,31 +55,31 @@ export class Agent {
|
|
|
54
55
|
}
|
|
55
56
|
// Initialize and validate agent-level schema if provided
|
|
56
57
|
if (options.schema) {
|
|
57
|
-
this.
|
|
58
|
-
this.validateSchema(this.
|
|
58
|
+
this._schema = options.schema;
|
|
59
|
+
this.validateSchema(this._schema);
|
|
59
60
|
logger.debug("[Agent] Agent-level schema initialized and validated");
|
|
60
61
|
}
|
|
61
62
|
// Initialize context if provided
|
|
62
|
-
this.
|
|
63
|
+
this._context = options.context;
|
|
63
64
|
// Initialize collected data with initial data if provided
|
|
64
65
|
if (options.initialData) {
|
|
65
|
-
if (this.
|
|
66
|
+
if (this._schema) {
|
|
66
67
|
const validation = this.validateData(options.initialData);
|
|
67
68
|
if (!validation.valid) {
|
|
68
69
|
throw new Error(`Initial data validation failed: ${validation.errors.map(e => e.message).join(', ')}`);
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
|
-
this.
|
|
72
|
-
logger.debug("[Agent] Initial data set:", this.
|
|
72
|
+
this._collectedData = { ...options.initialData };
|
|
73
|
+
logger.debug("[Agent] Initial data set:", this._collectedData);
|
|
73
74
|
}
|
|
74
75
|
// Initialize current session if provided
|
|
75
|
-
this.
|
|
76
|
+
this._currentSession = options.session;
|
|
76
77
|
// Initialize routing engine
|
|
77
|
-
this.
|
|
78
|
+
this._routingEngine = new RoutingEngine({
|
|
78
79
|
routeSwitchMargin: options.routeSwitchMargin,
|
|
79
80
|
});
|
|
80
81
|
// Initialize ResponseModal for handling all response generation
|
|
81
|
-
this.
|
|
82
|
+
this._responseModal = new ResponseModal(this);
|
|
82
83
|
// Initialize persistence if configured
|
|
83
84
|
if (options.persistence) {
|
|
84
85
|
try {
|
|
@@ -92,7 +93,7 @@ export class Agent {
|
|
|
92
93
|
if (!options.persistence.adapter.messageRepository) {
|
|
93
94
|
throw new Error("Persistence adapter must provide a messageRepository");
|
|
94
95
|
}
|
|
95
|
-
this.
|
|
96
|
+
this._persistenceManager = new PersistenceManager(options.persistence);
|
|
96
97
|
// Initialize the adapter if it has an initialize method
|
|
97
98
|
if (options.persistence.adapter.initialize) {
|
|
98
99
|
options.persistence.adapter.initialize().catch((error) => {
|
|
@@ -124,10 +125,10 @@ export class Agent {
|
|
|
124
125
|
}
|
|
125
126
|
// Initialize agent-level rules and prohibitions
|
|
126
127
|
if (options.rules) {
|
|
127
|
-
this.
|
|
128
|
+
this._rules = [...options.rules];
|
|
128
129
|
}
|
|
129
130
|
if (options.prohibitions) {
|
|
130
|
-
this.
|
|
131
|
+
this._prohibitions = [...options.prohibitions];
|
|
131
132
|
}
|
|
132
133
|
if (options.routes) {
|
|
133
134
|
options.routes.forEach((routeOptions) => {
|
|
@@ -136,10 +137,10 @@ export class Agent {
|
|
|
136
137
|
}
|
|
137
138
|
// Initialize knowledge base
|
|
138
139
|
if (options.knowledgeBase) {
|
|
139
|
-
this.
|
|
140
|
+
this._knowledgeBase = { ...options.knowledgeBase };
|
|
140
141
|
}
|
|
141
142
|
// Initialize session manager with reference to this agent for bidirectional sync
|
|
142
|
-
this.session = new SessionManager(this.
|
|
143
|
+
this.session = new SessionManager(this._persistenceManager, this);
|
|
143
144
|
// Initialize tool manager with proper type inference
|
|
144
145
|
this.tool = new ToolManager(this);
|
|
145
146
|
// Store sessionId for later use in getOrCreate calls
|
|
@@ -149,8 +150,8 @@ export class Agent {
|
|
|
149
150
|
this.session.getOrCreate(options.sessionId).then((session) => {
|
|
150
151
|
// Sync session data to agent collected data
|
|
151
152
|
if (session.data && Object.keys(session.data).length > 0) {
|
|
152
|
-
this.
|
|
153
|
-
logger.debug("[Agent] Synced session data to collected data:", this.
|
|
153
|
+
this._collectedData = { ...session.data };
|
|
154
|
+
logger.debug("[Agent] Synced session data to collected data:", this._collectedData);
|
|
154
155
|
}
|
|
155
156
|
}).catch((err) => {
|
|
156
157
|
logger.error("Failed to start session", err);
|
|
@@ -180,16 +181,16 @@ export class Agent {
|
|
|
180
181
|
* Validate data against the agent-level schema
|
|
181
182
|
*/
|
|
182
183
|
validateData(data) {
|
|
183
|
-
if (!this.
|
|
184
|
+
if (!this._schema) {
|
|
184
185
|
// No schema defined, consider all data valid
|
|
185
186
|
return { valid: true, errors: [], warnings: [] };
|
|
186
187
|
}
|
|
187
188
|
const errors = [];
|
|
188
189
|
const warnings = [];
|
|
189
190
|
// Basic validation - check if provided fields exist in schema
|
|
190
|
-
if (this.
|
|
191
|
+
if (this._schema.properties) {
|
|
191
192
|
for (const [key, value] of Object.entries(data)) {
|
|
192
|
-
if (!(key in this.
|
|
193
|
+
if (!(key in this._schema.properties)) {
|
|
193
194
|
errors.push({
|
|
194
195
|
field: key,
|
|
195
196
|
value,
|
|
@@ -200,8 +201,8 @@ export class Agent {
|
|
|
200
201
|
}
|
|
201
202
|
}
|
|
202
203
|
// Check required fields if specified
|
|
203
|
-
if (this.
|
|
204
|
-
for (const requiredField of this.
|
|
204
|
+
if (this._schema.required && Array.isArray(this._schema.required)) {
|
|
205
|
+
for (const requiredField of this._schema.required) {
|
|
205
206
|
if (!(requiredField in data) || data[requiredField] === undefined) {
|
|
206
207
|
warnings.push({
|
|
207
208
|
field: requiredField,
|
|
@@ -224,11 +225,11 @@ export class Agent {
|
|
|
224
225
|
* @returns true if field exists in schema or no schema is defined, false otherwise
|
|
225
226
|
*/
|
|
226
227
|
isValidSchemaField(field) {
|
|
227
|
-
if (!this.
|
|
228
|
+
if (!this._schema || !this._schema.properties) {
|
|
228
229
|
// No schema defined, consider all fields valid
|
|
229
230
|
return true;
|
|
230
231
|
}
|
|
231
|
-
return field in this.
|
|
232
|
+
return field in this._schema.properties;
|
|
232
233
|
}
|
|
233
234
|
/**
|
|
234
235
|
* Get the current collected data
|
|
@@ -236,7 +237,7 @@ export class Agent {
|
|
|
236
237
|
getCollectedData() {
|
|
237
238
|
// Ensure agent collected data is synced with session
|
|
238
239
|
this.syncSessionDataToCollectedData();
|
|
239
|
-
return { ...this.
|
|
240
|
+
return { ...this._collectedData };
|
|
240
241
|
}
|
|
241
242
|
/**
|
|
242
243
|
* Update collected data with validation
|
|
@@ -254,80 +255,366 @@ export class Agent {
|
|
|
254
255
|
logger.warn(`[Agent] Data validation warnings: ${warningMessages}`);
|
|
255
256
|
}
|
|
256
257
|
// Merge updates with current data
|
|
257
|
-
const previousData = { ...this.
|
|
258
|
-
this.
|
|
259
|
-
...this.
|
|
258
|
+
const previousData = { ...this._collectedData };
|
|
259
|
+
this._collectedData = {
|
|
260
|
+
...this._collectedData,
|
|
260
261
|
...updates
|
|
261
262
|
};
|
|
262
263
|
// Trigger agent-level lifecycle hook if configured
|
|
263
264
|
if (this.options.hooks?.onDataUpdate) {
|
|
264
|
-
this.
|
|
265
|
+
this._collectedData = await this.options.hooks.onDataUpdate(this._collectedData, previousData);
|
|
265
266
|
}
|
|
266
267
|
// Update current session if it exists to keep it in sync
|
|
267
|
-
if (this.
|
|
268
|
-
this.
|
|
268
|
+
if (this._currentSession) {
|
|
269
|
+
this._currentSession = mergeCollected(this._currentSession, this._collectedData);
|
|
269
270
|
}
|
|
270
271
|
// Also update the session manager's session data (avoid circular call)
|
|
271
272
|
const sessionManagerSession = this.session.current;
|
|
272
273
|
if (sessionManagerSession) {
|
|
273
|
-
sessionManagerSession.data = { ...this.
|
|
274
|
+
sessionManagerSession.data = { ...this._collectedData };
|
|
274
275
|
sessionManagerSession.metadata.lastUpdatedAt = new Date();
|
|
275
276
|
}
|
|
276
277
|
logger.debug("[Agent] Collected data updated:", updates);
|
|
277
278
|
}
|
|
279
|
+
// ---------------------------------------------------------------------------
|
|
280
|
+
// Property accessors (get / set)
|
|
281
|
+
// ---------------------------------------------------------------------------
|
|
278
282
|
/**
|
|
279
283
|
* Get agent name
|
|
280
284
|
*/
|
|
281
285
|
get name() {
|
|
282
286
|
return this.options.name;
|
|
283
287
|
}
|
|
288
|
+
/**
|
|
289
|
+
* Set agent name
|
|
290
|
+
*/
|
|
291
|
+
set name(value) {
|
|
292
|
+
this.options.name = value;
|
|
293
|
+
}
|
|
284
294
|
/**
|
|
285
295
|
* Get agent description
|
|
286
296
|
*/
|
|
287
297
|
get description() {
|
|
288
298
|
return this.options.description;
|
|
289
299
|
}
|
|
300
|
+
/**
|
|
301
|
+
* Set agent description
|
|
302
|
+
*/
|
|
303
|
+
set description(value) {
|
|
304
|
+
this.options.description = value;
|
|
305
|
+
}
|
|
290
306
|
/**
|
|
291
307
|
* Get agent goal
|
|
292
308
|
*/
|
|
293
309
|
get goal() {
|
|
294
310
|
return this.options.goal;
|
|
295
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Set agent goal
|
|
314
|
+
*/
|
|
315
|
+
set goal(value) {
|
|
316
|
+
this.options.goal = value;
|
|
317
|
+
}
|
|
296
318
|
/**
|
|
297
319
|
* Get agent identity
|
|
298
320
|
*/
|
|
299
321
|
get identity() {
|
|
300
322
|
return this.options.identity;
|
|
301
323
|
}
|
|
324
|
+
/**
|
|
325
|
+
* Set agent identity
|
|
326
|
+
*/
|
|
327
|
+
set identity(value) {
|
|
328
|
+
this.options.identity = value;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Get agent personality
|
|
332
|
+
*/
|
|
333
|
+
get personality() {
|
|
334
|
+
return this.options.personality;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Set agent personality
|
|
338
|
+
*/
|
|
339
|
+
set personality(value) {
|
|
340
|
+
this.options.personality = value;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Get whether debug mode is enabled
|
|
344
|
+
*/
|
|
345
|
+
get debug() {
|
|
346
|
+
return this.options.debug ?? false;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Set debug mode (also updates logger level)
|
|
350
|
+
*/
|
|
351
|
+
set debug(value) {
|
|
352
|
+
this.options.debug = value;
|
|
353
|
+
logger.setLevel(value ? LoggerLevel.DEBUG : LoggerLevel.INFO);
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Get the AI provider
|
|
357
|
+
*/
|
|
358
|
+
get provider() {
|
|
359
|
+
return this.options.provider;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Set the AI provider
|
|
363
|
+
*/
|
|
364
|
+
set provider(value) {
|
|
365
|
+
this.options.provider = value;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Get the composition mode
|
|
369
|
+
*/
|
|
370
|
+
get compositionMode() {
|
|
371
|
+
return this.options.compositionMode ?? CompositionMode.FLUID;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Set the composition mode
|
|
375
|
+
*/
|
|
376
|
+
set compositionMode(value) {
|
|
377
|
+
this.options.compositionMode = value;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Get the route switch margin
|
|
381
|
+
* @default 15
|
|
382
|
+
*/
|
|
383
|
+
get routeSwitchMargin() {
|
|
384
|
+
return this.options.routeSwitchMargin ?? 15;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Set the route switch margin
|
|
388
|
+
*/
|
|
389
|
+
set routeSwitchMargin(value) {
|
|
390
|
+
this.options.routeSwitchMargin = value;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Get the maximum steps per batch
|
|
394
|
+
* @default 1
|
|
395
|
+
*/
|
|
396
|
+
get maxStepsPerBatch() {
|
|
397
|
+
return this.options.maxStepsPerBatch ?? 1;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Set the maximum steps per batch
|
|
401
|
+
*/
|
|
402
|
+
set maxStepsPerBatch(value) {
|
|
403
|
+
this.options.maxStepsPerBatch = value;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Get all terms
|
|
407
|
+
*/
|
|
408
|
+
get terms() {
|
|
409
|
+
return [...this._terms];
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Get all guidelines
|
|
413
|
+
*/
|
|
414
|
+
get guidelines() {
|
|
415
|
+
return [...this._guidelines];
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Get all tools
|
|
419
|
+
*/
|
|
420
|
+
get tools() {
|
|
421
|
+
return [...this._tools];
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Get all routes
|
|
425
|
+
*/
|
|
426
|
+
get routes() {
|
|
427
|
+
return [...this._routes];
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Get agent-level rules
|
|
431
|
+
*/
|
|
432
|
+
get rules() {
|
|
433
|
+
return [...this._rules];
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Set agent-level rules
|
|
437
|
+
*/
|
|
438
|
+
set rules(value) {
|
|
439
|
+
this._rules = [...value];
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Get agent-level prohibitions
|
|
443
|
+
*/
|
|
444
|
+
get prohibitions() {
|
|
445
|
+
return [...this._prohibitions];
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Set agent-level prohibitions
|
|
449
|
+
*/
|
|
450
|
+
set prohibitions(value) {
|
|
451
|
+
this._prohibitions = [...value];
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Get current schema
|
|
455
|
+
*/
|
|
456
|
+
get schema() {
|
|
457
|
+
return this._schema;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Set schema (validates structure)
|
|
461
|
+
*/
|
|
462
|
+
set schema(value) {
|
|
463
|
+
if (value) {
|
|
464
|
+
this.validateSchema(value);
|
|
465
|
+
}
|
|
466
|
+
this._schema = value;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Get the agent's knowledge base
|
|
470
|
+
*/
|
|
471
|
+
get knowledgeBase() {
|
|
472
|
+
return { ...this._knowledgeBase };
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Set the agent's knowledge base
|
|
476
|
+
*/
|
|
477
|
+
set knowledgeBase(value) {
|
|
478
|
+
this._knowledgeBase = { ...value };
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Get the current session (if set)
|
|
482
|
+
*/
|
|
483
|
+
get currentSession() {
|
|
484
|
+
return this._currentSession;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Set the current session for convenience methods
|
|
488
|
+
* Set to undefined to clear the current session
|
|
489
|
+
*/
|
|
490
|
+
set currentSession(value) {
|
|
491
|
+
this._currentSession = value;
|
|
492
|
+
}
|
|
493
|
+
// ---------------------------------------------------------------------------
|
|
494
|
+
// Deprecated method-based accessors (for backward compatibility)
|
|
495
|
+
// ---------------------------------------------------------------------------
|
|
496
|
+
/**
|
|
497
|
+
* Get all terms
|
|
498
|
+
* @deprecated Use `agent.terms` instead
|
|
499
|
+
*/
|
|
500
|
+
getTerms() {
|
|
501
|
+
return this.terms;
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Get all tools
|
|
505
|
+
* @deprecated Use `agent.tools` instead
|
|
506
|
+
*/
|
|
507
|
+
getTools() {
|
|
508
|
+
return this.tools;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Get all guidelines
|
|
512
|
+
* @deprecated Use `agent.guidelines` instead
|
|
513
|
+
*/
|
|
514
|
+
getGuidelines() {
|
|
515
|
+
return this.guidelines;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Get all routes
|
|
519
|
+
* @deprecated Use `agent.routes` instead
|
|
520
|
+
*/
|
|
521
|
+
getRoutes() {
|
|
522
|
+
return this.routes;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Get agent-level rules
|
|
526
|
+
* @deprecated Use `agent.rules` instead
|
|
527
|
+
*/
|
|
528
|
+
getRules() {
|
|
529
|
+
return this.rules;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Get agent-level prohibitions
|
|
533
|
+
* @deprecated Use `agent.prohibitions` instead
|
|
534
|
+
*/
|
|
535
|
+
getProhibitions() {
|
|
536
|
+
return this.prohibitions;
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Get current schema
|
|
540
|
+
* @deprecated Use `agent.schema` instead
|
|
541
|
+
*/
|
|
542
|
+
getSchema() {
|
|
543
|
+
return this.schema;
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Get the agent's knowledge base
|
|
547
|
+
* @deprecated Use `agent.knowledgeBase` instead
|
|
548
|
+
*/
|
|
549
|
+
getKnowledgeBase() {
|
|
550
|
+
return this.knowledgeBase;
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Get the current session (if set)
|
|
554
|
+
* @deprecated Use `agent.currentSession` instead
|
|
555
|
+
*/
|
|
556
|
+
getCurrentSession() {
|
|
557
|
+
return this.currentSession;
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Set the current session for convenience methods
|
|
561
|
+
* @deprecated Use `agent.currentSession = session` instead
|
|
562
|
+
* @param session - Session step to use for subsequent calls
|
|
563
|
+
*/
|
|
564
|
+
setCurrentSession(session) {
|
|
565
|
+
this.currentSession = session;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Clear the current session
|
|
569
|
+
* @deprecated Use `agent.currentSession = undefined` instead
|
|
570
|
+
*/
|
|
571
|
+
clearCurrentSession() {
|
|
572
|
+
this._currentSession = undefined;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Get the persistence manager (if configured)
|
|
576
|
+
*/
|
|
577
|
+
getPersistenceManager() {
|
|
578
|
+
return this._persistenceManager;
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Check if persistence is enabled
|
|
582
|
+
*/
|
|
583
|
+
hasPersistence() {
|
|
584
|
+
return this._persistenceManager !== undefined;
|
|
585
|
+
}
|
|
586
|
+
// ---------------------------------------------------------------------------
|
|
587
|
+
// Core methods
|
|
588
|
+
// ---------------------------------------------------------------------------
|
|
302
589
|
/**
|
|
303
590
|
* Create a new route (journey) using agent-level data type
|
|
304
591
|
*/
|
|
305
592
|
createRoute(options) {
|
|
306
593
|
// Validate that requiredFields exist in agent schema
|
|
307
|
-
if (options.requiredFields && this.
|
|
308
|
-
const invalidRequiredFields = options.requiredFields.filter(field => !(String(field) in this.
|
|
594
|
+
if (options.requiredFields && this._schema?.properties) {
|
|
595
|
+
const invalidRequiredFields = options.requiredFields.filter(field => !(String(field) in this._schema.properties));
|
|
309
596
|
if (invalidRequiredFields.length > 0) {
|
|
310
597
|
throw new RouteConfigurationError(options.title, invalidRequiredFields.map(f => String(f)), `Invalid required fields in route '${options.title}': ${invalidRequiredFields.join(', ')}. ` +
|
|
311
|
-
`Must be valid keys from agent schema. Available fields: ${Object.keys(this.
|
|
598
|
+
`Must be valid keys from agent schema. Available fields: ${Object.keys(this._schema.properties).join(', ')}.`);
|
|
312
599
|
}
|
|
313
600
|
}
|
|
314
601
|
// Validate that optionalFields exist in agent schema
|
|
315
|
-
if (options.optionalFields && this.
|
|
316
|
-
const invalidOptionalFields = options.optionalFields.filter(field => !(String(field) in this.
|
|
602
|
+
if (options.optionalFields && this._schema?.properties) {
|
|
603
|
+
const invalidOptionalFields = options.optionalFields.filter(field => !(String(field) in this._schema.properties));
|
|
317
604
|
if (invalidOptionalFields.length > 0) {
|
|
318
605
|
throw new RouteConfigurationError(options.title, invalidOptionalFields.map(f => String(f)), `Invalid optional fields in route '${options.title}': ${invalidOptionalFields.join(', ')}. ` +
|
|
319
|
-
`Must be valid keys from agent schema. Available fields: ${Object.keys(this.
|
|
606
|
+
`Must be valid keys from agent schema. Available fields: ${Object.keys(this._schema.properties).join(', ')}.`);
|
|
320
607
|
}
|
|
321
608
|
}
|
|
322
609
|
const route = new Route(options, this);
|
|
323
|
-
this.
|
|
610
|
+
this._routes.push(route);
|
|
324
611
|
return route;
|
|
325
612
|
}
|
|
326
613
|
/**
|
|
327
614
|
* Create a domain term for the glossary
|
|
328
615
|
*/
|
|
329
616
|
createTerm(term) {
|
|
330
|
-
this.
|
|
617
|
+
this._terms.push(term);
|
|
331
618
|
return this;
|
|
332
619
|
}
|
|
333
620
|
/**
|
|
@@ -336,10 +623,10 @@ export class Agent {
|
|
|
336
623
|
createGuideline(guideline) {
|
|
337
624
|
const guidelineWithId = {
|
|
338
625
|
...guideline,
|
|
339
|
-
id: guideline.id || `guideline_${this.
|
|
626
|
+
id: guideline.id || `guideline_${this._guidelines.length}`,
|
|
340
627
|
enabled: guideline.enabled !== false, // Default to true
|
|
341
628
|
};
|
|
342
|
-
this.
|
|
629
|
+
this._guidelines.push(guidelineWithId);
|
|
343
630
|
return this;
|
|
344
631
|
}
|
|
345
632
|
/**
|
|
@@ -353,7 +640,7 @@ export class Agent {
|
|
|
353
640
|
throw new Error('Invalid tool: must have id and handler properties');
|
|
354
641
|
}
|
|
355
642
|
// Add directly to agent's tools array, preserving the TResult type
|
|
356
|
-
this.
|
|
643
|
+
this._tools.push(tool);
|
|
357
644
|
logger.debug(`[Agent] Added tool to agent scope: ${tool.id}`);
|
|
358
645
|
return this;
|
|
359
646
|
}
|
|
@@ -367,7 +654,7 @@ export class Agent {
|
|
|
367
654
|
if (!tool || !tool.id || !tool.handler) {
|
|
368
655
|
throw new Error('Invalid tool: must have id and handler properties');
|
|
369
656
|
}
|
|
370
|
-
this.
|
|
657
|
+
this._tools.push(tool);
|
|
371
658
|
logger.debug(`[Agent] Created tool (legacy): ${tool.id}`);
|
|
372
659
|
return this;
|
|
373
660
|
}
|
|
@@ -381,7 +668,7 @@ export class Agent {
|
|
|
381
668
|
if (!tool || !tool.id || !tool.handler) {
|
|
382
669
|
throw new Error(`Invalid tool in batch: must have id and handler properties (tool: ${tool?.id || 'unknown'})`);
|
|
383
670
|
}
|
|
384
|
-
this.
|
|
671
|
+
this._tools.push(tool);
|
|
385
672
|
});
|
|
386
673
|
logger.debug(`[Agent] Registered ${tools.length} tools`);
|
|
387
674
|
return this;
|
|
@@ -391,23 +678,23 @@ export class Agent {
|
|
|
391
678
|
* Triggers both agent-level and route-specific onContextUpdate lifecycle hooks if configured
|
|
392
679
|
*/
|
|
393
680
|
async updateContext(updates) {
|
|
394
|
-
const previousContext = this.
|
|
681
|
+
const previousContext = this._context;
|
|
395
682
|
// Merge updates with current context
|
|
396
|
-
this.
|
|
397
|
-
...this.
|
|
683
|
+
this._context = {
|
|
684
|
+
...this._context,
|
|
398
685
|
...updates,
|
|
399
686
|
};
|
|
400
687
|
// Trigger route-specific lifecycle hook if configured and session has current route
|
|
401
|
-
if (this.
|
|
402
|
-
const currentRoute = this.
|
|
688
|
+
if (this._currentSession?.currentRoute) {
|
|
689
|
+
const currentRoute = this._routes.find((r) => r.id === this._currentSession.currentRoute?.id);
|
|
403
690
|
if (currentRoute?.hooks?.onContextUpdate &&
|
|
404
691
|
previousContext !== undefined) {
|
|
405
|
-
await currentRoute.handleContextUpdate(this.
|
|
692
|
+
await currentRoute.handleContextUpdate(this._context, previousContext);
|
|
406
693
|
}
|
|
407
694
|
}
|
|
408
695
|
// Trigger agent-level lifecycle hook if configured
|
|
409
696
|
if (this.options.hooks?.onContextUpdate && previousContext !== undefined) {
|
|
410
|
-
await this.options.hooks.onContextUpdate(this.
|
|
697
|
+
await this.options.hooks.onContextUpdate(this._context, previousContext);
|
|
411
698
|
}
|
|
412
699
|
}
|
|
413
700
|
/**
|
|
@@ -424,7 +711,7 @@ export class Agent {
|
|
|
424
711
|
};
|
|
425
712
|
// Trigger route-specific lifecycle hook if configured and session has a current route
|
|
426
713
|
if (session.currentRoute) {
|
|
427
|
-
const currentRoute = this.
|
|
714
|
+
const currentRoute = this._routes.find((r) => r.id === session.currentRoute?.id);
|
|
428
715
|
if (currentRoute?.hooks?.onDataUpdate) {
|
|
429
716
|
newCollected = await currentRoute.handleDataUpdate(newCollected, previousCollected);
|
|
430
717
|
}
|
|
@@ -434,7 +721,7 @@ export class Agent {
|
|
|
434
721
|
newCollected = (await this.options.hooks.onDataUpdate(newCollected, previousCollected));
|
|
435
722
|
}
|
|
436
723
|
// Update agent's collected data to stay in sync
|
|
437
|
-
this.
|
|
724
|
+
this._collectedData = { ...newCollected };
|
|
438
725
|
// Return updated session
|
|
439
726
|
return mergeCollected(session, newCollected);
|
|
440
727
|
}
|
|
@@ -447,33 +734,21 @@ export class Agent {
|
|
|
447
734
|
return await this.options.contextProvider();
|
|
448
735
|
}
|
|
449
736
|
// Otherwise return the stored context
|
|
450
|
-
return this.
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Get current schema
|
|
454
|
-
*/
|
|
455
|
-
getSchema() {
|
|
456
|
-
return this.schema;
|
|
737
|
+
return this._context;
|
|
457
738
|
}
|
|
458
739
|
/**
|
|
459
740
|
* Generate a response based on history and context as a stream
|
|
460
741
|
*/
|
|
461
742
|
async *respondStream(params) {
|
|
462
743
|
// Delegate to ResponseModal
|
|
463
|
-
yield* this.
|
|
744
|
+
yield* this._responseModal.respondStream(params);
|
|
464
745
|
}
|
|
465
746
|
/**
|
|
466
747
|
* Generate a response based on history and context
|
|
467
748
|
*/
|
|
468
749
|
async respond(params) {
|
|
469
750
|
// Delegate to ResponseModal
|
|
470
|
-
return this.
|
|
471
|
-
}
|
|
472
|
-
/**
|
|
473
|
-
* Get all routes
|
|
474
|
-
*/
|
|
475
|
-
getRoutes() {
|
|
476
|
-
return [...this.routes];
|
|
751
|
+
return this._responseModal.respond(params);
|
|
477
752
|
}
|
|
478
753
|
/**
|
|
479
754
|
* Get agent options
|
|
@@ -487,7 +762,7 @@ export class Agent {
|
|
|
487
762
|
* @internal Used by ResponseModal
|
|
488
763
|
*/
|
|
489
764
|
getRoutingEngine() {
|
|
490
|
-
return this.
|
|
765
|
+
return this._routingEngine;
|
|
491
766
|
}
|
|
492
767
|
/**
|
|
493
768
|
* Get the updateData method bound to this agent
|
|
@@ -496,36 +771,6 @@ export class Agent {
|
|
|
496
771
|
getUpdateDataMethod() {
|
|
497
772
|
return this.updateData.bind(this);
|
|
498
773
|
}
|
|
499
|
-
/**
|
|
500
|
-
* Get all terms
|
|
501
|
-
*/
|
|
502
|
-
getTerms() {
|
|
503
|
-
return [...this.terms];
|
|
504
|
-
}
|
|
505
|
-
/**
|
|
506
|
-
* Get all tools
|
|
507
|
-
*/
|
|
508
|
-
getTools() {
|
|
509
|
-
return [...this.tools];
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
* Get all guidelines
|
|
513
|
-
*/
|
|
514
|
-
getGuidelines() {
|
|
515
|
-
return [...this.guidelines];
|
|
516
|
-
}
|
|
517
|
-
/**
|
|
518
|
-
* Get agent-level rules
|
|
519
|
-
*/
|
|
520
|
-
getRules() {
|
|
521
|
-
return [...this.agentRules];
|
|
522
|
-
}
|
|
523
|
-
/**
|
|
524
|
-
* Get agent-level prohibitions
|
|
525
|
-
*/
|
|
526
|
-
getProhibitions() {
|
|
527
|
-
return [...this.agentProhibitions];
|
|
528
|
-
}
|
|
529
774
|
/**
|
|
530
775
|
* Evaluate and match active guidelines based on their conditions
|
|
531
776
|
* Returns guidelines that should be active given the current context
|
|
@@ -534,7 +779,7 @@ export class Agent {
|
|
|
534
779
|
const templateContext = { context, session, history, data: session?.data };
|
|
535
780
|
const evaluator = createConditionEvaluator(templateContext);
|
|
536
781
|
const matches = [];
|
|
537
|
-
for (const guideline of this.
|
|
782
|
+
for (const guideline of this._guidelines) {
|
|
538
783
|
// Skip disabled guidelines
|
|
539
784
|
if (guideline.enabled === false) {
|
|
540
785
|
continue;
|
|
@@ -566,37 +811,6 @@ export class Agent {
|
|
|
566
811
|
}
|
|
567
812
|
return matches;
|
|
568
813
|
}
|
|
569
|
-
/**
|
|
570
|
-
* Get the agent's knowledge base
|
|
571
|
-
*/
|
|
572
|
-
getKnowledgeBase() {
|
|
573
|
-
return { ...this.knowledgeBase };
|
|
574
|
-
}
|
|
575
|
-
/**
|
|
576
|
-
* Get the persistence manager (if configured)
|
|
577
|
-
*/
|
|
578
|
-
getPersistenceManager() {
|
|
579
|
-
return this.persistenceManager;
|
|
580
|
-
}
|
|
581
|
-
/**
|
|
582
|
-
* Check if persistence is enabled
|
|
583
|
-
*/
|
|
584
|
-
hasPersistence() {
|
|
585
|
-
return this.persistenceManager !== undefined;
|
|
586
|
-
}
|
|
587
|
-
/**
|
|
588
|
-
* Set the current session for convenience methods
|
|
589
|
-
* @param session - Session step to use for subsequent calls
|
|
590
|
-
*/
|
|
591
|
-
setCurrentSession(session) {
|
|
592
|
-
this.currentSession = session;
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* Get the current session (if set)
|
|
596
|
-
*/
|
|
597
|
-
getCurrentSession() {
|
|
598
|
-
return this.currentSession;
|
|
599
|
-
}
|
|
600
814
|
/**
|
|
601
815
|
* Execute a prepare or finalize function/tool
|
|
602
816
|
* @internal Used by ResponseModal
|
|
@@ -647,12 +861,6 @@ export class Agent {
|
|
|
647
861
|
}
|
|
648
862
|
}
|
|
649
863
|
}
|
|
650
|
-
/**
|
|
651
|
-
* Clear the current session
|
|
652
|
-
*/
|
|
653
|
-
clearCurrentSession() {
|
|
654
|
-
this.currentSession = undefined;
|
|
655
|
-
}
|
|
656
864
|
/**
|
|
657
865
|
* Sync session data to agent collected data
|
|
658
866
|
* @internal Used to keep agent and session data in sync
|
|
@@ -660,8 +868,8 @@ export class Agent {
|
|
|
660
868
|
syncSessionDataToCollectedData() {
|
|
661
869
|
const sessionData = this.session.getData();
|
|
662
870
|
if (sessionData && Object.keys(sessionData).length > 0) {
|
|
663
|
-
this.
|
|
664
|
-
logger.debug("[Agent] Synced session data to collected data:", this.
|
|
871
|
+
this._collectedData = { ...sessionData };
|
|
872
|
+
logger.debug("[Agent] Synced session data to collected data:", this._collectedData);
|
|
665
873
|
}
|
|
666
874
|
}
|
|
667
875
|
/**
|
|
@@ -673,10 +881,10 @@ export class Agent {
|
|
|
673
881
|
// Ensure agent collected data is synced with session
|
|
674
882
|
this.syncSessionDataToCollectedData();
|
|
675
883
|
// If we have a current session, use session data
|
|
676
|
-
if (this.
|
|
884
|
+
if (this._currentSession) {
|
|
677
885
|
// With agent-level data, all routes share the same data structure
|
|
678
886
|
// No need for route-specific data access
|
|
679
|
-
return (this.
|
|
887
|
+
return (this._currentSession.data) || {};
|
|
680
888
|
}
|
|
681
889
|
// Otherwise, return agent-level collected data
|
|
682
890
|
return this.getCollectedData();
|
|
@@ -699,22 +907,22 @@ export class Agent {
|
|
|
699
907
|
* }
|
|
700
908
|
*/
|
|
701
909
|
async nextStepRoute(routeIdOrTitle, session, condition, history) {
|
|
702
|
-
const targetSession = session || this.
|
|
910
|
+
const targetSession = session || this._currentSession;
|
|
703
911
|
if (!targetSession) {
|
|
704
912
|
throw new Error("No session provided and no current session available. Please provide a session to transition.");
|
|
705
913
|
}
|
|
706
914
|
// Find target route by ID or title
|
|
707
|
-
const targetRoute = this.
|
|
915
|
+
const targetRoute = this._routes.find((r) => r.id === routeIdOrTitle || r.title === routeIdOrTitle);
|
|
708
916
|
if (!targetRoute) {
|
|
709
|
-
throw new Error(`Route not found: ${routeIdOrTitle}. Available routes: ${this.
|
|
917
|
+
throw new Error(`Route not found: ${routeIdOrTitle}. Available routes: ${this._routes
|
|
710
918
|
.map((r) => r.title)
|
|
711
919
|
.join(", ")}`);
|
|
712
920
|
}
|
|
713
921
|
const templateContext = createTemplateContext({
|
|
714
|
-
context: this.
|
|
922
|
+
context: this._context,
|
|
715
923
|
session,
|
|
716
924
|
history,
|
|
717
|
-
data: this.
|
|
925
|
+
data: this._currentSession?.data,
|
|
718
926
|
});
|
|
719
927
|
const renderedCondition = await render(condition, templateContext);
|
|
720
928
|
const updatedSession = {
|
|
@@ -726,8 +934,8 @@ export class Agent {
|
|
|
726
934
|
},
|
|
727
935
|
};
|
|
728
936
|
// Update current session if using it
|
|
729
|
-
if (!session && this.
|
|
730
|
-
this.
|
|
937
|
+
if (!session && this._currentSession) {
|
|
938
|
+
this._currentSession = updatedSession;
|
|
731
939
|
}
|
|
732
940
|
logger.debug(`[Agent] Set pending transition to route: ${targetRoute.title}`);
|
|
733
941
|
return updatedSession;
|
|
@@ -738,7 +946,7 @@ export class Agent {
|
|
|
738
946
|
*/
|
|
739
947
|
async chat(message, options) {
|
|
740
948
|
// Delegate to ResponseModal.generate()
|
|
741
|
-
return this.
|
|
949
|
+
return this._responseModal.generate(message, options);
|
|
742
950
|
}
|
|
743
951
|
/**
|
|
744
952
|
* Modern streaming API - simple interface like chat() but returns a stream
|
|
@@ -746,7 +954,7 @@ export class Agent {
|
|
|
746
954
|
*/
|
|
747
955
|
async *stream(message, options) {
|
|
748
956
|
// Delegate to ResponseModal with the same options structure as chat()
|
|
749
|
-
yield* this.
|
|
957
|
+
yield* this._responseModal.stream(message, {
|
|
750
958
|
history: options?.history,
|
|
751
959
|
contextOverride: options?.contextOverride,
|
|
752
960
|
signal: options?.signal,
|