@falai/agent 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/cjs/core/Agent.d.ts +202 -67
  2. package/dist/cjs/core/Agent.d.ts.map +1 -1
  3. package/dist/cjs/core/Agent.js +366 -158
  4. package/dist/cjs/core/Agent.js.map +1 -1
  5. package/dist/cjs/core/BatchExecutor.d.ts.map +1 -1
  6. package/dist/cjs/core/BatchExecutor.js +4 -2
  7. package/dist/cjs/core/BatchExecutor.js.map +1 -1
  8. package/dist/cjs/core/BatchPromptBuilder.d.ts.map +1 -1
  9. package/dist/cjs/core/BatchPromptBuilder.js +15 -12
  10. package/dist/cjs/core/BatchPromptBuilder.js.map +1 -1
  11. package/dist/cjs/core/PromptComposer.d.ts.map +1 -1
  12. package/dist/cjs/core/PromptComposer.js +16 -8
  13. package/dist/cjs/core/PromptComposer.js.map +1 -1
  14. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
  15. package/dist/cjs/core/ResponseEngine.js +6 -3
  16. package/dist/cjs/core/ResponseEngine.js.map +1 -1
  17. package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
  18. package/dist/cjs/core/ResponseModal.js +22 -21
  19. package/dist/cjs/core/ResponseModal.js.map +1 -1
  20. package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
  21. package/dist/cjs/core/RoutingEngine.js +8 -73
  22. package/dist/cjs/core/RoutingEngine.js.map +1 -1
  23. package/dist/core/Agent.d.ts +202 -67
  24. package/dist/core/Agent.d.ts.map +1 -1
  25. package/dist/core/Agent.js +366 -158
  26. package/dist/core/Agent.js.map +1 -1
  27. package/dist/core/BatchExecutor.d.ts.map +1 -1
  28. package/dist/core/BatchExecutor.js +4 -2
  29. package/dist/core/BatchExecutor.js.map +1 -1
  30. package/dist/core/BatchPromptBuilder.d.ts.map +1 -1
  31. package/dist/core/BatchPromptBuilder.js +15 -12
  32. package/dist/core/BatchPromptBuilder.js.map +1 -1
  33. package/dist/core/PromptComposer.d.ts.map +1 -1
  34. package/dist/core/PromptComposer.js +16 -8
  35. package/dist/core/PromptComposer.js.map +1 -1
  36. package/dist/core/ResponseEngine.d.ts.map +1 -1
  37. package/dist/core/ResponseEngine.js +6 -3
  38. package/dist/core/ResponseEngine.js.map +1 -1
  39. package/dist/core/ResponseModal.d.ts.map +1 -1
  40. package/dist/core/ResponseModal.js +22 -21
  41. package/dist/core/ResponseModal.js.map +1 -1
  42. package/dist/core/RoutingEngine.d.ts.map +1 -1
  43. package/dist/core/RoutingEngine.js +8 -73
  44. package/dist/core/RoutingEngine.js.map +1 -1
  45. package/docs/api/README.md +2 -2
  46. package/docs/api/overview.md +1 -1
  47. package/docs/architecture/data-extraction-flow.md +17 -19
  48. package/docs/core/conversation-flows/data-collection.md +2 -2
  49. package/docs/core/error-handling.md +3 -4
  50. package/package.json +2 -2
  51. package/src/core/Agent.ts +427 -195
  52. package/src/core/BatchExecutor.ts +5 -2
  53. package/src/core/BatchPromptBuilder.ts +51 -48
  54. package/src/core/PromptComposer.ts +30 -13
  55. package/src/core/ResponseEngine.ts +56 -53
  56. package/src/core/ResponseModal.ts +83 -85
  57. package/src/core/RoutingEngine.ts +67 -149
package/src/core/Agent.ts CHANGED
@@ -17,8 +17,9 @@ import type {
17
17
  StructuredSchema,
18
18
  ValidationError,
19
19
  ValidationResult,
20
-
20
+ AiProvider,
21
21
  } from "../types";
22
+ import { CompositionMode } from "../types";
22
23
  import type { StreamOptions, GenerateOptions, RespondParams } from "./ResponseModal";
23
24
  import {
24
25
  mergeCollected,
@@ -63,20 +64,20 @@ class RouteConfigurationError extends Error {
63
64
  */
64
65
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
66
  export class Agent<TContext = any, TData = any> {
66
- private terms: Term<TContext, TData>[] = [];
67
- private guidelines: Guideline<TContext, TData>[] = [];
68
- private tools: Tool<TContext, TData>[] = [];
69
- private routes: Route<TContext, TData>[] = [];
70
- private agentRules: Template<TContext, TData>[] = [];
71
- private agentProhibitions: Template<TContext, TData>[] = [];
72
- private context: TContext | undefined;
73
- private persistenceManager: PersistenceManager<TData> | undefined;
74
- private routingEngine: RoutingEngine<TContext, TData>;
75
- private responseModal: ResponseModal<TContext, TData>;
76
- private currentSession?: SessionState<TData>;
77
- private knowledgeBase: Record<string, unknown> = {};
78
- private schema?: StructuredSchema;
79
- private collectedData: Partial<TData> = {};
67
+ private _terms: Term<TContext, TData>[] = [];
68
+ private _guidelines: Guideline<TContext, TData>[] = [];
69
+ private _tools: Tool<TContext, TData>[] = [];
70
+ private _routes: Route<TContext, TData>[] = [];
71
+ private _rules: Template<TContext, TData>[] = [];
72
+ private _prohibitions: Template<TContext, TData>[] = [];
73
+ private _context: TContext | undefined;
74
+ private _persistenceManager: PersistenceManager<TData> | undefined;
75
+ private _routingEngine: RoutingEngine<TContext, TData>;
76
+ private _responseModal: ResponseModal<TContext, TData>;
77
+ private _currentSession?: SessionState<TData>;
78
+ private _knowledgeBase: Record<string, unknown> = {};
79
+ private _schema?: StructuredSchema;
80
+ private _collectedData: Partial<TData> = {};
80
81
 
81
82
  /** Public session manager for easy session management */
82
83
  public session: SessionManager<TData>;
@@ -84,7 +85,7 @@ export class Agent<TContext = any, TData = any> {
84
85
  /** Public tool manager for simplified tool creation and management */
85
86
  public tool: ToolManager<TContext, TData>;
86
87
 
87
- constructor(private readonly options: AgentOptions<TContext, TData>) {
88
+ constructor(private options: AgentOptions<TContext, TData>) {
88
89
  // Set log level based on debug option
89
90
  if (options.debug) {
90
91
  logger.setLevel(LoggerLevel.DEBUG);
@@ -99,17 +100,17 @@ export class Agent<TContext = any, TData = any> {
99
100
 
100
101
  // Initialize and validate agent-level schema if provided
101
102
  if (options.schema) {
102
- this.schema = options.schema;
103
- this.validateSchema(this.schema);
103
+ this._schema = options.schema;
104
+ this.validateSchema(this._schema);
104
105
  logger.debug("[Agent] Agent-level schema initialized and validated");
105
106
  }
106
107
 
107
108
  // Initialize context if provided
108
- this.context = options.context;
109
+ this._context = options.context;
109
110
 
110
111
  // Initialize collected data with initial data if provided
111
112
  if (options.initialData) {
112
- if (this.schema) {
113
+ if (this._schema) {
113
114
  const validation = this.validateData(options.initialData);
114
115
  if (!validation.valid) {
115
116
  throw new Error(
@@ -117,20 +118,20 @@ export class Agent<TContext = any, TData = any> {
117
118
  );
118
119
  }
119
120
  }
120
- this.collectedData = { ...options.initialData };
121
- logger.debug("[Agent] Initial data set:", this.collectedData);
121
+ this._collectedData = { ...options.initialData };
122
+ logger.debug("[Agent] Initial data set:", this._collectedData);
122
123
  }
123
124
 
124
125
  // Initialize current session if provided
125
- this.currentSession = options.session;
126
+ this._currentSession = options.session;
126
127
 
127
128
  // Initialize routing engine
128
- this.routingEngine = new RoutingEngine<TContext, TData>({
129
+ this._routingEngine = new RoutingEngine<TContext, TData>({
129
130
  routeSwitchMargin: options.routeSwitchMargin,
130
131
  });
131
132
 
132
133
  // Initialize ResponseModal for handling all response generation
133
- this.responseModal = new ResponseModal<TContext, TData>(this);
134
+ this._responseModal = new ResponseModal<TContext, TData>(this);
134
135
 
135
136
  // Initialize persistence if configured
136
137
  if (options.persistence) {
@@ -148,7 +149,7 @@ export class Agent<TContext = any, TData = any> {
148
149
  throw new Error("Persistence adapter must provide a messageRepository");
149
150
  }
150
151
 
151
- this.persistenceManager = new PersistenceManager<TData>(options.persistence);
152
+ this._persistenceManager = new PersistenceManager<TData>(options.persistence);
152
153
 
153
154
  // Initialize the adapter if it has an initialize method
154
155
  if (options.persistence.adapter.initialize) {
@@ -187,10 +188,10 @@ export class Agent<TContext = any, TData = any> {
187
188
 
188
189
  // Initialize agent-level rules and prohibitions
189
190
  if (options.rules) {
190
- this.agentRules = [...options.rules];
191
+ this._rules = [...options.rules];
191
192
  }
192
193
  if (options.prohibitions) {
193
- this.agentProhibitions = [...options.prohibitions];
194
+ this._prohibitions = [...options.prohibitions];
194
195
  }
195
196
 
196
197
  if (options.routes) {
@@ -201,11 +202,11 @@ export class Agent<TContext = any, TData = any> {
201
202
 
202
203
  // Initialize knowledge base
203
204
  if (options.knowledgeBase) {
204
- this.knowledgeBase = { ...options.knowledgeBase };
205
+ this._knowledgeBase = { ...options.knowledgeBase };
205
206
  }
206
207
 
207
208
  // Initialize session manager with reference to this agent for bidirectional sync
208
- this.session = new SessionManager<TData>(this.persistenceManager, this);
209
+ this.session = new SessionManager<TData>(this._persistenceManager, this);
209
210
 
210
211
  // Initialize tool manager with proper type inference
211
212
  this.tool = new ToolManager<TContext, TData>(this);
@@ -217,8 +218,8 @@ export class Agent<TContext = any, TData = any> {
217
218
  this.session.getOrCreate(options.sessionId).then((session) => {
218
219
  // Sync session data to agent collected data
219
220
  if (session.data && Object.keys(session.data).length > 0) {
220
- this.collectedData = { ...session.data };
221
- logger.debug("[Agent] Synced session data to collected data:", this.collectedData);
221
+ this._collectedData = { ...session.data };
222
+ logger.debug("[Agent] Synced session data to collected data:", this._collectedData);
222
223
  }
223
224
  }).catch((err) => {
224
225
  logger.error("Failed to start session", err);
@@ -259,7 +260,7 @@ export class Agent<TContext = any, TData = any> {
259
260
  * Validate data against the agent-level schema
260
261
  */
261
262
  validateData(data: Partial<TData>): ValidationResult {
262
- if (!this.schema) {
263
+ if (!this._schema) {
263
264
  // No schema defined, consider all data valid
264
265
  return { valid: true, errors: [], warnings: [] };
265
266
  }
@@ -268,9 +269,9 @@ export class Agent<TContext = any, TData = any> {
268
269
  const warnings: ValidationError[] = [];
269
270
 
270
271
  // Basic validation - check if provided fields exist in schema
271
- if (this.schema.properties) {
272
+ if (this._schema.properties) {
272
273
  for (const [key, value] of Object.entries(data)) {
273
- if (!(key in this.schema.properties)) {
274
+ if (!(key in this._schema.properties)) {
274
275
  errors.push({
275
276
  field: key,
276
277
  value,
@@ -282,8 +283,8 @@ export class Agent<TContext = any, TData = any> {
282
283
  }
283
284
 
284
285
  // Check required fields if specified
285
- if (this.schema.required && Array.isArray(this.schema.required)) {
286
- for (const requiredField of this.schema.required) {
286
+ if (this._schema.required && Array.isArray(this._schema.required)) {
287
+ for (const requiredField of this._schema.required) {
287
288
  if (!(requiredField in data) || data[requiredField as keyof TData] === undefined) {
288
289
  warnings.push({
289
290
  field: requiredField,
@@ -308,12 +309,12 @@ export class Agent<TContext = any, TData = any> {
308
309
  * @returns true if field exists in schema or no schema is defined, false otherwise
309
310
  */
310
311
  isValidSchemaField(field: keyof TData): boolean {
311
- if (!this.schema || !this.schema.properties) {
312
+ if (!this._schema || !this._schema.properties) {
312
313
  // No schema defined, consider all fields valid
313
314
  return true;
314
315
  }
315
316
 
316
- return field as string in this.schema.properties;
317
+ return field as string in this._schema.properties;
317
318
  }
318
319
 
319
320
  /**
@@ -322,7 +323,7 @@ export class Agent<TContext = any, TData = any> {
322
323
  getCollectedData(): Partial<TData> {
323
324
  // Ensure agent collected data is synced with session
324
325
  this.syncSessionDataToCollectedData();
325
- return { ...this.collectedData };
326
+ return { ...this._collectedData };
326
327
  }
327
328
 
328
329
  /**
@@ -343,35 +344,39 @@ export class Agent<TContext = any, TData = any> {
343
344
  }
344
345
 
345
346
  // Merge updates with current data
346
- const previousData = { ...this.collectedData };
347
- this.collectedData = {
348
- ...this.collectedData,
347
+ const previousData = { ...this._collectedData };
348
+ this._collectedData = {
349
+ ...this._collectedData,
349
350
  ...updates
350
351
  };
351
352
 
352
353
  // Trigger agent-level lifecycle hook if configured
353
354
  if (this.options.hooks?.onDataUpdate) {
354
- this.collectedData = await this.options.hooks.onDataUpdate(
355
- this.collectedData,
355
+ this._collectedData = await this.options.hooks.onDataUpdate(
356
+ this._collectedData,
356
357
  previousData
357
358
  );
358
359
  }
359
360
 
360
361
  // Update current session if it exists to keep it in sync
361
- if (this.currentSession) {
362
- this.currentSession = mergeCollected(this.currentSession, this.collectedData);
362
+ if (this._currentSession) {
363
+ this._currentSession = mergeCollected(this._currentSession, this._collectedData);
363
364
  }
364
365
 
365
366
  // Also update the session manager's session data (avoid circular call)
366
367
  const sessionManagerSession = this.session.current;
367
368
  if (sessionManagerSession) {
368
- sessionManagerSession.data = { ...this.collectedData };
369
+ sessionManagerSession.data = { ...this._collectedData };
369
370
  sessionManagerSession.metadata!.lastUpdatedAt = new Date();
370
371
  }
371
372
 
372
373
  logger.debug("[Agent] Collected data updated:", updates);
373
374
  }
374
375
 
376
+ // ---------------------------------------------------------------------------
377
+ // Property accessors (get / set)
378
+ // ---------------------------------------------------------------------------
379
+
375
380
  /**
376
381
  * Get agent name
377
382
  */
@@ -379,6 +384,13 @@ export class Agent<TContext = any, TData = any> {
379
384
  return this.options.name;
380
385
  }
381
386
 
387
+ /**
388
+ * Set agent name
389
+ */
390
+ set name(value: string) {
391
+ this.options.name = value;
392
+ }
393
+
382
394
  /**
383
395
  * Get agent description
384
396
  */
@@ -386,6 +398,13 @@ export class Agent<TContext = any, TData = any> {
386
398
  return this.options.description;
387
399
  }
388
400
 
401
+ /**
402
+ * Set agent description
403
+ */
404
+ set description(value: string | undefined) {
405
+ this.options.description = value;
406
+ }
407
+
389
408
  /**
390
409
  * Get agent goal
391
410
  */
@@ -393,6 +412,13 @@ export class Agent<TContext = any, TData = any> {
393
412
  return this.options.goal;
394
413
  }
395
414
 
415
+ /**
416
+ * Set agent goal
417
+ */
418
+ set goal(value: string | undefined) {
419
+ this.options.goal = value;
420
+ }
421
+
396
422
  /**
397
423
  * Get agent identity
398
424
  */
@@ -400,6 +426,313 @@ export class Agent<TContext = any, TData = any> {
400
426
  return this.options.identity;
401
427
  }
402
428
 
429
+ /**
430
+ * Set agent identity
431
+ */
432
+ set identity(value: Template<TContext> | undefined) {
433
+ this.options.identity = value;
434
+ }
435
+
436
+ /**
437
+ * Get agent personality
438
+ */
439
+ get personality(): Template<TContext> | undefined {
440
+ return this.options.personality;
441
+ }
442
+
443
+ /**
444
+ * Set agent personality
445
+ */
446
+ set personality(value: Template<TContext> | undefined) {
447
+ this.options.personality = value;
448
+ }
449
+
450
+ /**
451
+ * Get whether debug mode is enabled
452
+ */
453
+ get debug(): boolean {
454
+ return this.options.debug ?? false;
455
+ }
456
+
457
+ /**
458
+ * Set debug mode (also updates logger level)
459
+ */
460
+ set debug(value: boolean) {
461
+ this.options.debug = value;
462
+ logger.setLevel(value ? LoggerLevel.DEBUG : LoggerLevel.INFO);
463
+ }
464
+
465
+ /**
466
+ * Get the AI provider
467
+ */
468
+ get provider(): AiProvider {
469
+ return this.options.provider;
470
+ }
471
+
472
+ /**
473
+ * Set the AI provider
474
+ */
475
+ set provider(value: AiProvider) {
476
+ this.options.provider = value;
477
+ }
478
+
479
+ /**
480
+ * Get the composition mode
481
+ */
482
+ get compositionMode(): CompositionMode {
483
+ return this.options.compositionMode ?? CompositionMode.FLUID;
484
+ }
485
+
486
+ /**
487
+ * Set the composition mode
488
+ */
489
+ set compositionMode(value: CompositionMode) {
490
+ this.options.compositionMode = value;
491
+ }
492
+
493
+ /**
494
+ * Get the route switch margin
495
+ * @default 15
496
+ */
497
+ get routeSwitchMargin(): number {
498
+ return this.options.routeSwitchMargin ?? 15;
499
+ }
500
+
501
+ /**
502
+ * Set the route switch margin
503
+ */
504
+ set routeSwitchMargin(value: number) {
505
+ this.options.routeSwitchMargin = value;
506
+ }
507
+
508
+ /**
509
+ * Get the maximum steps per batch
510
+ * @default 1
511
+ */
512
+ get maxStepsPerBatch(): number {
513
+ return this.options.maxStepsPerBatch ?? 1;
514
+ }
515
+
516
+ /**
517
+ * Set the maximum steps per batch
518
+ */
519
+ set maxStepsPerBatch(value: number) {
520
+ this.options.maxStepsPerBatch = value;
521
+ }
522
+
523
+ /**
524
+ * Get all terms
525
+ */
526
+ get terms(): Term<TContext, TData>[] {
527
+ return [...this._terms];
528
+ }
529
+
530
+ /**
531
+ * Get all guidelines
532
+ */
533
+ get guidelines(): Guideline<TContext, TData>[] {
534
+ return [...this._guidelines];
535
+ }
536
+
537
+ /**
538
+ * Get all tools
539
+ */
540
+ get tools(): Tool<TContext, TData>[] {
541
+ return [...this._tools];
542
+ }
543
+
544
+ /**
545
+ * Get all routes
546
+ */
547
+ get routes(): Route<TContext, TData>[] {
548
+ return [...this._routes];
549
+ }
550
+
551
+ /**
552
+ * Get agent-level rules
553
+ */
554
+ get rules(): Template<TContext, TData>[] {
555
+ return [...this._rules];
556
+ }
557
+
558
+ /**
559
+ * Set agent-level rules
560
+ */
561
+ set rules(value: Template<TContext, TData>[]) {
562
+ this._rules = [...value];
563
+ }
564
+
565
+ /**
566
+ * Get agent-level prohibitions
567
+ */
568
+ get prohibitions(): Template<TContext, TData>[] {
569
+ return [...this._prohibitions];
570
+ }
571
+
572
+ /**
573
+ * Set agent-level prohibitions
574
+ */
575
+ set prohibitions(value: Template<TContext, TData>[]) {
576
+ this._prohibitions = [...value];
577
+ }
578
+
579
+ /**
580
+ * Get current schema
581
+ */
582
+ get schema(): StructuredSchema | undefined {
583
+ return this._schema;
584
+ }
585
+
586
+ /**
587
+ * Set schema (validates structure)
588
+ */
589
+ set schema(value: StructuredSchema | undefined) {
590
+ if (value) {
591
+ this.validateSchema(value);
592
+ }
593
+ this._schema = value;
594
+ }
595
+
596
+ /**
597
+ * Get the agent's knowledge base
598
+ */
599
+ get knowledgeBase(): Record<string, unknown> {
600
+ return { ...this._knowledgeBase };
601
+ }
602
+
603
+ /**
604
+ * Set the agent's knowledge base
605
+ */
606
+ set knowledgeBase(value: Record<string, unknown>) {
607
+ this._knowledgeBase = { ...value };
608
+ }
609
+
610
+ /**
611
+ * Get the current session (if set)
612
+ */
613
+ get currentSession(): SessionState | undefined {
614
+ return this._currentSession;
615
+ }
616
+
617
+ /**
618
+ * Set the current session for convenience methods
619
+ * Set to undefined to clear the current session
620
+ */
621
+ set currentSession(value: SessionState | undefined) {
622
+ this._currentSession = value;
623
+ }
624
+
625
+ // ---------------------------------------------------------------------------
626
+ // Deprecated method-based accessors (for backward compatibility)
627
+ // ---------------------------------------------------------------------------
628
+
629
+ /**
630
+ * Get all terms
631
+ * @deprecated Use `agent.terms` instead
632
+ */
633
+ getTerms(): Term<TContext, TData>[] {
634
+ return this.terms;
635
+ }
636
+
637
+ /**
638
+ * Get all tools
639
+ * @deprecated Use `agent.tools` instead
640
+ */
641
+ getTools(): Tool<TContext, TData>[] {
642
+ return this.tools;
643
+ }
644
+
645
+ /**
646
+ * Get all guidelines
647
+ * @deprecated Use `agent.guidelines` instead
648
+ */
649
+ getGuidelines(): Guideline<TContext, TData>[] {
650
+ return this.guidelines;
651
+ }
652
+
653
+ /**
654
+ * Get all routes
655
+ * @deprecated Use `agent.routes` instead
656
+ */
657
+ getRoutes(): Route<TContext, TData>[] {
658
+ return this.routes;
659
+ }
660
+
661
+ /**
662
+ * Get agent-level rules
663
+ * @deprecated Use `agent.rules` instead
664
+ */
665
+ getRules(): Template<TContext, TData>[] {
666
+ return this.rules;
667
+ }
668
+
669
+ /**
670
+ * Get agent-level prohibitions
671
+ * @deprecated Use `agent.prohibitions` instead
672
+ */
673
+ getProhibitions(): Template<TContext, TData>[] {
674
+ return this.prohibitions;
675
+ }
676
+
677
+ /**
678
+ * Get current schema
679
+ * @deprecated Use `agent.schema` instead
680
+ */
681
+ getSchema(): StructuredSchema | undefined {
682
+ return this.schema;
683
+ }
684
+
685
+ /**
686
+ * Get the agent's knowledge base
687
+ * @deprecated Use `agent.knowledgeBase` instead
688
+ */
689
+ getKnowledgeBase(): Record<string, unknown> {
690
+ return this.knowledgeBase;
691
+ }
692
+
693
+ /**
694
+ * Get the current session (if set)
695
+ * @deprecated Use `agent.currentSession` instead
696
+ */
697
+ getCurrentSession(): SessionState | undefined {
698
+ return this.currentSession;
699
+ }
700
+
701
+ /**
702
+ * Set the current session for convenience methods
703
+ * @deprecated Use `agent.currentSession = session` instead
704
+ * @param session - Session step to use for subsequent calls
705
+ */
706
+ setCurrentSession(session: SessionState): void {
707
+ this.currentSession = session;
708
+ }
709
+
710
+ /**
711
+ * Clear the current session
712
+ * @deprecated Use `agent.currentSession = undefined` instead
713
+ */
714
+ clearCurrentSession(): void {
715
+ this._currentSession = undefined;
716
+ }
717
+
718
+ /**
719
+ * Get the persistence manager (if configured)
720
+ */
721
+ getPersistenceManager(): PersistenceManager<TData> | undefined {
722
+ return this._persistenceManager;
723
+ }
724
+
725
+ /**
726
+ * Check if persistence is enabled
727
+ */
728
+ hasPersistence(): boolean {
729
+ return this._persistenceManager !== undefined;
730
+ }
731
+
732
+ // ---------------------------------------------------------------------------
733
+ // Core methods
734
+ // ---------------------------------------------------------------------------
735
+
403
736
  /**
404
737
  * Create a new route (journey) using agent-level data type
405
738
  */
@@ -407,37 +740,37 @@ export class Agent<TContext = any, TData = any> {
407
740
  options: RouteOptions<TContext, TData>
408
741
  ): Route<TContext, TData> {
409
742
  // Validate that requiredFields exist in agent schema
410
- if (options.requiredFields && this.schema?.properties) {
743
+ if (options.requiredFields && this._schema?.properties) {
411
744
  const invalidRequiredFields = options.requiredFields.filter(
412
- field => !(String(field) in this.schema!.properties!)
745
+ field => !(String(field) in this._schema!.properties!)
413
746
  );
414
747
  if (invalidRequiredFields.length > 0) {
415
748
  throw new RouteConfigurationError(
416
749
  options.title,
417
750
  invalidRequiredFields.map(f => String(f)),
418
751
  `Invalid required fields in route '${options.title}': ${invalidRequiredFields.join(', ')}. ` +
419
- `Must be valid keys from agent schema. Available fields: ${Object.keys(this.schema.properties).join(', ')}.`
752
+ `Must be valid keys from agent schema. Available fields: ${Object.keys(this._schema.properties).join(', ')}.`
420
753
  );
421
754
  }
422
755
  }
423
756
 
424
757
  // Validate that optionalFields exist in agent schema
425
- if (options.optionalFields && this.schema?.properties) {
758
+ if (options.optionalFields && this._schema?.properties) {
426
759
  const invalidOptionalFields = options.optionalFields.filter(
427
- field => !(String(field) in this.schema!.properties!)
760
+ field => !(String(field) in this._schema!.properties!)
428
761
  );
429
762
  if (invalidOptionalFields.length > 0) {
430
763
  throw new RouteConfigurationError(
431
764
  options.title,
432
765
  invalidOptionalFields.map(f => String(f)),
433
766
  `Invalid optional fields in route '${options.title}': ${invalidOptionalFields.join(', ')}. ` +
434
- `Must be valid keys from agent schema. Available fields: ${Object.keys(this.schema.properties).join(', ')}.`
767
+ `Must be valid keys from agent schema. Available fields: ${Object.keys(this._schema.properties).join(', ')}.`
435
768
  );
436
769
  }
437
770
  }
438
771
 
439
772
  const route = new Route<TContext, TData>(options, this);
440
- this.routes.push(route);
773
+ this._routes.push(route);
441
774
  return route;
442
775
  }
443
776
 
@@ -445,7 +778,7 @@ export class Agent<TContext = any, TData = any> {
445
778
  * Create a domain term for the glossary
446
779
  */
447
780
  createTerm(term: Term<TContext, TData>): this {
448
- this.terms.push(term);
781
+ this._terms.push(term);
449
782
  return this;
450
783
  }
451
784
 
@@ -455,10 +788,10 @@ export class Agent<TContext = any, TData = any> {
455
788
  createGuideline(guideline: Guideline<TContext, TData>): this {
456
789
  const guidelineWithId = {
457
790
  ...guideline,
458
- id: guideline.id || `guideline_${this.guidelines.length}`,
791
+ id: guideline.id || `guideline_${this._guidelines.length}`,
459
792
  enabled: guideline.enabled !== false, // Default to true
460
793
  };
461
- this.guidelines.push(guidelineWithId);
794
+ this._guidelines.push(guidelineWithId);
462
795
  return this;
463
796
  }
464
797
 
@@ -474,9 +807,9 @@ export class Agent<TContext = any, TData = any> {
474
807
  if (!tool || !tool.id || !tool.handler) {
475
808
  throw new Error('Invalid tool: must have id and handler properties');
476
809
  }
477
-
810
+
478
811
  // Add directly to agent's tools array, preserving the TResult type
479
- this.tools.push(tool);
812
+ this._tools.push(tool);
480
813
  logger.debug(`[Agent] Added tool to agent scope: ${tool.id}`);
481
814
  return this;
482
815
  }
@@ -491,8 +824,8 @@ export class Agent<TContext = any, TData = any> {
491
824
  if (!tool || !tool.id || !tool.handler) {
492
825
  throw new Error('Invalid tool: must have id and handler properties');
493
826
  }
494
-
495
- this.tools.push(tool);
827
+
828
+ this._tools.push(tool);
496
829
  logger.debug(`[Agent] Created tool (legacy): ${tool.id}`);
497
830
  return this;
498
831
  }
@@ -507,7 +840,7 @@ export class Agent<TContext = any, TData = any> {
507
840
  if (!tool || !tool.id || !tool.handler) {
508
841
  throw new Error(`Invalid tool in batch: must have id and handler properties (tool: ${tool?.id || 'unknown'})`);
509
842
  }
510
- this.tools.push(tool);
843
+ this._tools.push(tool);
511
844
  });
512
845
  logger.debug(`[Agent] Registered ${tools.length} tools`);
513
846
  return this;
@@ -518,30 +851,30 @@ export class Agent<TContext = any, TData = any> {
518
851
  * Triggers both agent-level and route-specific onContextUpdate lifecycle hooks if configured
519
852
  */
520
853
  async updateContext(updates: Partial<TContext>): Promise<void> {
521
- const previousContext = this.context;
854
+ const previousContext = this._context;
522
855
 
523
856
  // Merge updates with current context
524
- this.context = {
525
- ...(this.context as Record<string, unknown>),
857
+ this._context = {
858
+ ...(this._context as Record<string, unknown>),
526
859
  ...(updates as Record<string, unknown>),
527
860
  } as TContext;
528
861
 
529
862
  // Trigger route-specific lifecycle hook if configured and session has current route
530
- if (this.currentSession?.currentRoute) {
531
- const currentRoute = this.routes.find(
532
- (r) => r.id === this.currentSession!.currentRoute?.id
863
+ if (this._currentSession?.currentRoute) {
864
+ const currentRoute = this._routes.find(
865
+ (r) => r.id === this._currentSession!.currentRoute?.id
533
866
  );
534
867
  if (
535
868
  currentRoute?.hooks?.onContextUpdate &&
536
869
  previousContext !== undefined
537
870
  ) {
538
- await currentRoute.handleContextUpdate(this.context, previousContext);
871
+ await currentRoute.handleContextUpdate(this._context, previousContext);
539
872
  }
540
873
  }
541
874
 
542
875
  // Trigger agent-level lifecycle hook if configured
543
876
  if (this.options.hooks?.onContextUpdate && previousContext !== undefined) {
544
- await this.options.hooks.onContextUpdate(this.context, previousContext);
877
+ await this.options.hooks.onContextUpdate(this._context, previousContext);
545
878
  }
546
879
  }
547
880
 
@@ -564,7 +897,7 @@ export class Agent<TContext = any, TData = any> {
564
897
 
565
898
  // Trigger route-specific lifecycle hook if configured and session has a current route
566
899
  if (session.currentRoute) {
567
- const currentRoute = this.routes.find(
900
+ const currentRoute = this._routes.find(
568
901
  (r) => r.id === session.currentRoute?.id
569
902
  );
570
903
  if (currentRoute?.hooks?.onDataUpdate) {
@@ -584,7 +917,7 @@ export class Agent<TContext = any, TData = any> {
584
917
  }
585
918
 
586
919
  // Update agent's collected data to stay in sync
587
- this.collectedData = { ...newCollected };
920
+ this._collectedData = { ...newCollected };
588
921
 
589
922
  // Return updated session
590
923
  return mergeCollected(session, newCollected);
@@ -600,13 +933,7 @@ export class Agent<TContext = any, TData = any> {
600
933
  }
601
934
 
602
935
  // Otherwise return the stored context
603
- return this.context;
604
- }
605
- /**
606
- * Get current schema
607
- */
608
- getSchema(): StructuredSchema | undefined {
609
- return this.schema;
936
+ return this._context;
610
937
  }
611
938
 
612
939
  /**
@@ -614,7 +941,7 @@ export class Agent<TContext = any, TData = any> {
614
941
  */
615
942
  async *respondStream(params: RespondParams<TContext, TData>): AsyncGenerator<AgentResponseStreamChunk<TData>> {
616
943
  // Delegate to ResponseModal
617
- yield* this.responseModal.respondStream(params);
944
+ yield* this._responseModal.respondStream(params);
618
945
  }
619
946
 
620
947
  /**
@@ -622,14 +949,7 @@ export class Agent<TContext = any, TData = any> {
622
949
  */
623
950
  async respond(params: RespondParams<TContext, TData>): Promise<AgentResponse<TData>> {
624
951
  // Delegate to ResponseModal
625
- return this.responseModal.respond(params);
626
- }
627
-
628
- /**
629
- * Get all routes
630
- */
631
- getRoutes(): Route<TContext, TData>[] {
632
- return [...this.routes];
952
+ return this._responseModal.respond(params);
633
953
  }
634
954
 
635
955
  /**
@@ -645,7 +965,7 @@ export class Agent<TContext = any, TData = any> {
645
965
  * @internal Used by ResponseModal
646
966
  */
647
967
  getRoutingEngine(): RoutingEngine<TContext, TData> {
648
- return this.routingEngine;
968
+ return this._routingEngine;
649
969
  }
650
970
 
651
971
  /**
@@ -656,49 +976,6 @@ export class Agent<TContext = any, TData = any> {
656
976
  return this.updateData.bind(this);
657
977
  }
658
978
 
659
-
660
-
661
- /**
662
- * Get all terms
663
- */
664
- getTerms(): Term<TContext, TData>[] {
665
- return [...this.terms];
666
- }
667
-
668
- /**
669
- * Get all tools
670
- */
671
- getTools(): Tool<TContext, TData>[] {
672
- return [...this.tools];
673
- }
674
-
675
-
676
-
677
-
678
-
679
-
680
-
681
- /**
682
- * Get all guidelines
683
- */
684
- getGuidelines(): Guideline<TContext, TData>[] {
685
- return [...this.guidelines];
686
- }
687
-
688
- /**
689
- * Get agent-level rules
690
- */
691
- getRules(): Template<TContext, TData>[] {
692
- return [...this.agentRules];
693
- }
694
-
695
- /**
696
- * Get agent-level prohibitions
697
- */
698
- getProhibitions(): Template<TContext, TData>[] {
699
- return [...this.agentProhibitions];
700
- }
701
-
702
979
  /**
703
980
  * Evaluate and match active guidelines based on their conditions
704
981
  * Returns guidelines that should be active given the current context
@@ -712,7 +989,7 @@ export class Agent<TContext = any, TData = any> {
712
989
  const evaluator = createConditionEvaluator(templateContext);
713
990
  const matches: GuidelineMatch<TContext, TData>[] = [];
714
991
 
715
- for (const guideline of this.guidelines) {
992
+ for (const guideline of this._guidelines) {
716
993
  // Skip disabled guidelines
717
994
  if (guideline.enabled === false) {
718
995
  continue;
@@ -720,7 +997,7 @@ export class Agent<TContext = any, TData = any> {
720
997
 
721
998
  if (guideline.condition) {
722
999
  const evaluation = await evaluator.evaluateCondition(guideline.condition, 'AND');
723
-
1000
+
724
1001
  // Include guideline if:
725
1002
  // 1. No programmatic conditions (only strings) - always active
726
1003
  // 2. Programmatic conditions evaluate to true
@@ -730,7 +1007,7 @@ export class Agent<TContext = any, TData = any> {
730
1007
  : evaluation.hasProgrammaticConditions
731
1008
  ? "Programmatic condition evaluated to true"
732
1009
  : "Always active (no conditions)";
733
-
1010
+
734
1011
  matches.push({
735
1012
  guideline,
736
1013
  rationale
@@ -748,44 +1025,6 @@ export class Agent<TContext = any, TData = any> {
748
1025
  return matches;
749
1026
  }
750
1027
 
751
- /**
752
- * Get the agent's knowledge base
753
- */
754
- getKnowledgeBase(): Record<string, unknown> {
755
- return { ...this.knowledgeBase };
756
- }
757
-
758
-
759
-
760
- /**
761
- * Get the persistence manager (if configured)
762
- */
763
- getPersistenceManager(): PersistenceManager<TData> | undefined {
764
- return this.persistenceManager;
765
- }
766
-
767
- /**
768
- * Check if persistence is enabled
769
- */
770
- hasPersistence(): boolean {
771
- return this.persistenceManager !== undefined;
772
- }
773
-
774
- /**
775
- * Set the current session for convenience methods
776
- * @param session - Session step to use for subsequent calls
777
- */
778
- setCurrentSession(session: SessionState): void {
779
- this.currentSession = session;
780
- }
781
-
782
- /**
783
- * Get the current session (if set)
784
- */
785
- getCurrentSession(): SessionState | undefined {
786
- return this.currentSession;
787
- }
788
-
789
1028
  /**
790
1029
  * Execute a prepare or finalize function/tool
791
1030
  * @internal Used by ResponseModal
@@ -851,13 +1090,6 @@ export class Agent<TContext = any, TData = any> {
851
1090
  }
852
1091
  }
853
1092
 
854
- /**
855
- * Clear the current session
856
- */
857
- clearCurrentSession(): void {
858
- this.currentSession = undefined;
859
- }
860
-
861
1093
  /**
862
1094
  * Sync session data to agent collected data
863
1095
  * @internal Used to keep agent and session data in sync
@@ -865,8 +1097,8 @@ export class Agent<TContext = any, TData = any> {
865
1097
  private syncSessionDataToCollectedData(): void {
866
1098
  const sessionData = this.session.getData();
867
1099
  if (sessionData && Object.keys(sessionData).length > 0) {
868
- this.collectedData = { ...sessionData };
869
- logger.debug("[Agent] Synced session data to collected data:", this.collectedData);
1100
+ this._collectedData = { ...sessionData };
1101
+ logger.debug("[Agent] Synced session data to collected data:", this._collectedData);
870
1102
  }
871
1103
  }
872
1104
 
@@ -878,12 +1110,12 @@ export class Agent<TContext = any, TData = any> {
878
1110
  getData(): Partial<TData> {
879
1111
  // Ensure agent collected data is synced with session
880
1112
  this.syncSessionDataToCollectedData();
881
-
1113
+
882
1114
  // If we have a current session, use session data
883
- if (this.currentSession) {
1115
+ if (this._currentSession) {
884
1116
  // With agent-level data, all routes share the same data structure
885
1117
  // No need for route-specific data access
886
- return (this.currentSession.data) || {};
1118
+ return (this._currentSession.data) || {};
887
1119
  }
888
1120
 
889
1121
  // Otherwise, return agent-level collected data
@@ -913,7 +1145,7 @@ export class Agent<TContext = any, TData = any> {
913
1145
  condition?: Template<TContext, TData>,
914
1146
  history?: Event[]
915
1147
  ): Promise<SessionState<TData>> {
916
- const targetSession = session || this.currentSession;
1148
+ const targetSession = session || this._currentSession;
917
1149
 
918
1150
  if (!targetSession) {
919
1151
  throw new Error(
@@ -922,22 +1154,22 @@ export class Agent<TContext = any, TData = any> {
922
1154
  }
923
1155
 
924
1156
  // Find target route by ID or title
925
- const targetRoute = this.routes.find(
1157
+ const targetRoute = this._routes.find(
926
1158
  (r) => r.id === routeIdOrTitle || r.title === routeIdOrTitle
927
1159
  );
928
1160
 
929
1161
  if (!targetRoute) {
930
1162
  throw new Error(
931
- `Route not found: ${routeIdOrTitle}. Available routes: ${this.routes
1163
+ `Route not found: ${routeIdOrTitle}. Available routes: ${this._routes
932
1164
  .map((r) => r.title)
933
1165
  .join(", ")}`
934
1166
  );
935
1167
  }
936
1168
  const templateContext = createTemplateContext({
937
- context: this.context,
1169
+ context: this._context,
938
1170
  session,
939
1171
  history,
940
- data: this.currentSession?.data,
1172
+ data: this._currentSession?.data,
941
1173
  });
942
1174
  const renderedCondition = await render(condition, templateContext);
943
1175
 
@@ -951,8 +1183,8 @@ export class Agent<TContext = any, TData = any> {
951
1183
  };
952
1184
 
953
1185
  // Update current session if using it
954
- if (!session && this.currentSession) {
955
- this.currentSession = updatedSession;
1186
+ if (!session && this._currentSession) {
1187
+ this._currentSession = updatedSession;
956
1188
  }
957
1189
 
958
1190
  logger.debug(
@@ -971,7 +1203,7 @@ export class Agent<TContext = any, TData = any> {
971
1203
  options?: GenerateOptions<TContext>
972
1204
  ): Promise<AgentResponse<TData>> {
973
1205
  // Delegate to ResponseModal.generate()
974
- return this.responseModal.generate(message, options);
1206
+ return this._responseModal.generate(message, options);
975
1207
  }
976
1208
 
977
1209
  /**
@@ -983,7 +1215,7 @@ export class Agent<TContext = any, TData = any> {
983
1215
  options?: StreamOptions<TContext>
984
1216
  ): AsyncGenerator<AgentResponseStreamChunk<TData>> {
985
1217
  // Delegate to ResponseModal with the same options structure as chat()
986
- yield* this.responseModal.stream(message, {
1218
+ yield* this._responseModal.stream(message, {
987
1219
  history: options?.history,
988
1220
  contextOverride: options?.contextOverride,
989
1221
  signal: options?.signal,