@falai/agent 0.2.0 → 0.3.10

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 (62) hide show
  1. package/README.md +160 -11
  2. package/dist/cjs/core/Agent.d.ts +12 -0
  3. package/dist/cjs/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/core/Agent.js +37 -1
  5. package/dist/cjs/core/Agent.js.map +1 -1
  6. package/dist/cjs/core/DomainRegistry.d.ts +10 -0
  7. package/dist/cjs/core/DomainRegistry.d.ts.map +1 -1
  8. package/dist/cjs/core/DomainRegistry.js +25 -0
  9. package/dist/cjs/core/DomainRegistry.js.map +1 -1
  10. package/dist/cjs/core/PromptBuilder.d.ts +9 -1
  11. package/dist/cjs/core/PromptBuilder.d.ts.map +1 -1
  12. package/dist/cjs/core/PromptBuilder.js +49 -2
  13. package/dist/cjs/core/PromptBuilder.js.map +1 -1
  14. package/dist/cjs/core/Route.d.ts +16 -0
  15. package/dist/cjs/core/Route.d.ts.map +1 -1
  16. package/dist/cjs/core/Route.js +22 -0
  17. package/dist/cjs/core/Route.js.map +1 -1
  18. package/dist/cjs/core/State.d.ts +1 -1
  19. package/dist/cjs/core/State.d.ts.map +1 -1
  20. package/dist/cjs/core/State.js +4 -10
  21. package/dist/cjs/core/State.js.map +1 -1
  22. package/dist/cjs/types/route.d.ts +10 -6
  23. package/dist/cjs/types/route.d.ts.map +1 -1
  24. package/dist/core/Agent.d.ts +12 -0
  25. package/dist/core/Agent.d.ts.map +1 -1
  26. package/dist/core/Agent.js +37 -1
  27. package/dist/core/Agent.js.map +1 -1
  28. package/dist/core/DomainRegistry.d.ts +10 -0
  29. package/dist/core/DomainRegistry.d.ts.map +1 -1
  30. package/dist/core/DomainRegistry.js +25 -0
  31. package/dist/core/DomainRegistry.js.map +1 -1
  32. package/dist/core/PromptBuilder.d.ts +9 -1
  33. package/dist/core/PromptBuilder.d.ts.map +1 -1
  34. package/dist/core/PromptBuilder.js +49 -2
  35. package/dist/core/PromptBuilder.js.map +1 -1
  36. package/dist/core/Route.d.ts +16 -0
  37. package/dist/core/Route.d.ts.map +1 -1
  38. package/dist/core/Route.js +22 -0
  39. package/dist/core/Route.js.map +1 -1
  40. package/dist/core/State.d.ts +1 -1
  41. package/dist/core/State.d.ts.map +1 -1
  42. package/dist/core/State.js +4 -10
  43. package/dist/core/State.js.map +1 -1
  44. package/dist/types/route.d.ts +10 -6
  45. package/dist/types/route.d.ts.map +1 -1
  46. package/docs/API_REFERENCE.md +124 -3
  47. package/docs/CONSTRUCTOR_OPTIONS.md +178 -37
  48. package/docs/GETTING_STARTED.md +13 -5
  49. package/examples/business-onboarding.ts +707 -0
  50. package/examples/domain-scoping.ts +266 -0
  51. package/examples/healthcare-agent.ts +15 -15
  52. package/examples/openai-agent.ts +2 -2
  53. package/examples/persistent-onboarding.ts +7 -7
  54. package/examples/rules-prohibitions.ts +258 -0
  55. package/examples/travel-agent.ts +17 -17
  56. package/package.json +1 -1
  57. package/src/core/Agent.ts +46 -1
  58. package/src/core/DomainRegistry.ts +30 -0
  59. package/src/core/PromptBuilder.ts +70 -3
  60. package/src/core/Route.ts +28 -0
  61. package/src/core/State.ts +6 -25
  62. package/src/types/route.ts +13 -9
@@ -21,7 +21,7 @@ export class State {
21
21
  *
22
22
  * @param spec - Transition specification (chatState, toolState, or direct state)
23
23
  * @param condition - Optional condition for this transition
24
- * @returns Object with target state that supports chaining
24
+ * @returns TransitionResult that supports chaining
25
25
  */
26
26
  transitionTo(spec, condition) {
27
27
  // Handle END_ROUTE
@@ -31,26 +31,20 @@ export class State {
31
31
  const endTransition = new Transition(this.getRef(), { state: END_ROUTE }, condition);
32
32
  this.transitions.push(endTransition);
33
33
  // Return a terminal state reference
34
- return {
35
- target: this.createTerminalRef(),
36
- };
34
+ return this.createTerminalRef();
37
35
  }
38
36
  // Handle direct state reference
39
37
  if (spec.state && typeof spec.state !== "symbol") {
40
38
  const transition = new Transition(this.getRef(), spec, condition);
41
39
  this.transitions.push(transition);
42
- return {
43
- target: this.createStateRefWithTransition(spec.state),
44
- };
40
+ return this.createStateRefWithTransition(spec.state);
45
41
  }
46
42
  // Create new target state for chatState or toolState
47
43
  const targetState = new State(this.routeId, spec.chatState);
48
44
  const transition = new Transition(this.getRef(), spec, condition);
49
45
  transition.setTarget(targetState);
50
46
  this.transitions.push(transition);
51
- return {
52
- target: this.createStateRefWithTransition(targetState.getRef(), targetState),
53
- };
47
+ return this.createStateRefWithTransition(targetState.getRef(), targetState);
54
48
  }
55
49
  /**
56
50
  * Add a guideline specific to this state
@@ -1 +1 @@
1
- {"version":3,"file":"State.js","sourceRoot":"","sources":["../../src/core/State.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"State.js","sourceRoot":"","sources":["../../src/core/State.ts"],"names":[],"mappings":"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"}
@@ -36,6 +36,12 @@ export interface RouteOptions {
36
36
  conditions?: string[];
37
37
  /** Initial guidelines for this route */
38
38
  guidelines?: Guideline[];
39
+ /** Domain names that are allowed in this route (undefined = all domains) */
40
+ domains?: string[];
41
+ /** Absolute rules the agent must follow in this route */
42
+ rules?: string[];
43
+ /** Absolute prohibitions the agent must never do in this route */
44
+ prohibitions?: string[];
39
45
  }
40
46
  /**
41
47
  * Specification for a state transition
@@ -50,12 +56,10 @@ export interface TransitionSpec<TContext = unknown> {
50
56
  }
51
57
  /**
52
58
  * Result of a transition operation
59
+ * Combines state reference with the ability to chain transitions
53
60
  */
54
- export interface TransitionResult<TContext = unknown> {
55
- /** The target state after transition */
56
- target: StateRef & {
57
- /** Allow chaining transitions */
58
- transitionTo: (spec: TransitionSpec<TContext>, condition?: string) => TransitionResult<TContext>;
59
- };
61
+ export interface TransitionResult<TContext = unknown> extends StateRef {
62
+ /** Allow chaining transitions */
63
+ transitionTo: (spec: TransitionSpec<TContext>, condition?: string) => TransitionResult<TContext>;
60
64
  }
61
65
  //# sourceMappingURL=route.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/types/route.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,qGAAqG;IACrG,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,wCAAwC;IACxC,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,QAAQ,GAAG,OAAO;IAChD,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mCAAmC;IAEnC,SAAS,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;IAC1C,mDAAmD;IACnD,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,QAAQ,GAAG,OAAO;IAClD,wCAAwC;IACxC,MAAM,EAAE,QAAQ,GAAG;QACjB,iCAAiC;QACjC,YAAY,EAAE,CACZ,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,EAC9B,SAAS,CAAC,EAAE,MAAM,KACf,gBAAgB,CAAC,QAAQ,CAAC,CAAC;KACjC,CAAC;CACH"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/types/route.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,qGAAqG;IACrG,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,wCAAwC;IACxC,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,QAAQ,GAAG,OAAO;IAChD,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mCAAmC;IAEnC,SAAS,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;IAC1C,mDAAmD;IACnD,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,QAAQ,GAAG,OAAO,CAAE,SAAQ,QAAQ;IACpE,iCAAiC;IACjC,YAAY,EAAE,CACZ,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,EAC9B,SAAS,CAAC,EAAE,MAAM,KACf,gBAAgB,CAAC,QAAQ,CAAC,CAAC;CACjC"}
@@ -40,9 +40,17 @@ Adds an agent capability. Returns `this` for chaining.
40
40
 
41
41
  Creates an observation for disambiguation.
42
42
 
43
- ##### `addDomain<TName, TDomain>(name: TName, domainObject: TDomain): this`
43
+ ##### `addDomain<TName, TDomain>(name: TName, domainObject: TDomain): void`
44
44
 
45
- Registers a domain with tools/methods. Returns `this` for chaining.
45
+ Registers a domain with tools/methods.
46
+
47
+ ##### `getDomainsForRoute(routeId: string): Record<string, Record<string, unknown>>`
48
+
49
+ Gets allowed domains for a specific route by ID. Returns filtered domains based on route's `domains` property, or all domains if route has no restrictions.
50
+
51
+ ##### `getDomainsForRouteByTitle(routeTitle: string): Record<string, Record<string, unknown>>`
52
+
53
+ Gets allowed domains for a specific route by title. Returns filtered domains based on route's `domains` property, or all domains if route has no restrictions.
46
54
 
47
55
  ##### `respond(input: RespondInput<TContext>): Promise<RespondOutput>`
48
56
 
@@ -136,6 +144,9 @@ interface RouteOptions {
136
144
  description?: string; // Route description
137
145
  conditions?: string[]; // Conditions that activate this route
138
146
  guidelines?: Guideline[]; // Initial guidelines for this route
147
+ domains?: string[]; // Domain names allowed in this route (undefined = all domains)
148
+ rules?: string[]; // Absolute rules the agent MUST follow in this route
149
+ prohibitions?: string[]; // Absolute prohibitions the agent MUST NEVER do in this route
139
150
  }
140
151
  ```
141
152
 
@@ -151,6 +162,18 @@ Adds a guideline specific to this route. Returns `this` for chaining.
151
162
 
152
163
  Returns all guidelines for this route.
153
164
 
165
+ ##### `getDomains(): string[] | undefined`
166
+
167
+ Returns allowed domain names for this route. Returns `undefined` if all domains are allowed, or an array of domain names if restricted.
168
+
169
+ ##### `getRules(): string[]`
170
+
171
+ Returns the rules that must be followed in this route.
172
+
173
+ ##### `getProhibitions(): string[]`
174
+
175
+ Returns the prohibitions that must never be done in this route.
176
+
154
177
  ##### `getRef(): RouteRef`
155
178
 
156
179
  Returns a reference to this route.
@@ -195,7 +218,7 @@ Represents a state within a conversation route.
195
218
 
196
219
  ##### `transitionTo(spec: TransitionSpec, condition?: string): TransitionResult`
197
220
 
198
- Creates a transition from this state.
221
+ Creates a transition from this state and returns a chainable result.
199
222
 
200
223
  ```typescript
201
224
  interface TransitionSpec {
@@ -203,6 +226,52 @@ interface TransitionSpec {
203
226
  toolState?: ToolRef; // Transition to execute a tool
204
227
  state?: StateRef | symbol; // Transition to specific state or END_ROUTE
205
228
  }
229
+
230
+ interface TransitionResult {
231
+ id: string; // State identifier
232
+ routeId: string; // Route identifier
233
+ transitionTo: (spec: TransitionSpec, condition?: string) => TransitionResult;
234
+ }
235
+ ```
236
+
237
+ **Returns:** A `TransitionResult` that includes the target state's reference (`id`, `routeId`) and a `transitionTo` method for chaining additional transitions.
238
+
239
+ **Example:**
240
+
241
+ ```typescript
242
+ // Approach 1: Step-by-step (ideal for complex flows with branching)
243
+ const t0 = route.initialState.transitionTo({
244
+ chatState: "Ask for user name",
245
+ });
246
+
247
+ const t1 = t0.transitionTo({
248
+ chatState: "Ask for email",
249
+ });
250
+
251
+ const t2 = t1.transitionTo({
252
+ chatState: "Confirm details",
253
+ });
254
+
255
+ // Access state properties
256
+ console.log(t1.id); // State ID
257
+ console.log(t1.routeId); // Route ID
258
+
259
+ // Use saved references for branching
260
+ t1.transitionTo(
261
+ { chatState: "Handle invalid email" },
262
+ "Email validation failed"
263
+ );
264
+
265
+ // Approach 2: Fluent chaining (elegant for linear flows)
266
+ route.initialState
267
+ .transitionTo({ chatState: "Ask for user name" })
268
+ .transitionTo({ chatState: "Ask for email" })
269
+ .transitionTo({ chatState: "Confirm details" })
270
+ .transitionTo({ state: END_ROUTE });
271
+
272
+ // Both approaches are equivalent - choose based on your needs:
273
+ // - Use step-by-step for complex flows with conditional branches
274
+ // - Use chaining for simple linear flows for conciseness
206
275
  ```
207
276
 
208
277
  ##### `addGuideline(guideline: Guideline): void`
@@ -265,6 +334,58 @@ Observation description (readonly).
265
334
 
266
335
  ---
267
336
 
337
+ ### `DomainRegistry`
338
+
339
+ Registry for organizing agent tools and methods by domain.
340
+
341
+ #### Methods
342
+
343
+ ##### `register<TDomain>(name: string, domain: TDomain): void`
344
+
345
+ Registers a new domain with its tools/methods. Throws error if domain name already exists.
346
+
347
+ ##### `get<TDomain>(name: string): TDomain | undefined`
348
+
349
+ Gets a registered domain by name. Returns `undefined` if not found.
350
+
351
+ ##### `has(name: string): boolean`
352
+
353
+ Checks if a domain is registered.
354
+
355
+ ##### `all(): Record<string, Record<string, unknown>>`
356
+
357
+ Returns all registered domains as a single object.
358
+
359
+ ##### `getFiltered(allowedNames?: string[]): Record<string, Record<string, unknown>>`
360
+
361
+ Returns filtered domains by names. If `allowedNames` is `undefined`, returns all domains.
362
+
363
+ **Example:**
364
+
365
+ ```typescript
366
+ const registry = new DomainRegistry();
367
+
368
+ registry.register("payment", {
369
+ processPayment: async (amount: number) => { /* ... */ },
370
+ });
371
+
372
+ registry.register("shipping", {
373
+ calculateShipping: (zipCode: string) => { /* ... */ },
374
+ });
375
+
376
+ // Get specific domains
377
+ const filtered = registry.getFiltered(["payment"]); // Only payment domain
378
+
379
+ // Get all domains
380
+ const all = registry.getFiltered(); // payment + shipping
381
+ ```
382
+
383
+ ##### `getDomainNames(): string[]`
384
+
385
+ Returns list of all registered domain names.
386
+
387
+ ---
388
+
268
389
  ### `GeminiProvider`
269
390
 
270
391
  AI provider implementation for Google Gemini.
@@ -41,48 +41,48 @@ interface AgentOptions<TContext = unknown> {
41
41
 
42
42
  ```typescript
43
43
  const agent = new Agent({
44
- name: "SupportBot",
45
- description: "Helpful customer support",
46
- goal: "Resolve issues efficiently",
47
- ai: new GeminiProvider({ apiKey: "...", model: "..." }),
48
- context: { userId: "123" },
44
+ name: 'SupportBot',
45
+ description: 'Helpful customer support',
46
+ goal: 'Resolve issues efficiently',
47
+ ai: new GeminiProvider({ apiKey: '...', model: '...' }),
48
+ context: { userId: '123' },
49
49
 
50
50
  terms: [
51
51
  {
52
- name: "SLA",
53
- description: "Service Level Agreement",
54
- synonyms: ["response time"],
52
+ name: 'SLA',
53
+ description: 'Service Level Agreement',
54
+ synonyms: ['response time'],
55
55
  },
56
56
  ],
57
57
 
58
58
  guidelines: [
59
59
  {
60
- condition: "User is frustrated",
61
- action: "Show empathy and offer escalation",
62
- tags: ["support"],
60
+ condition: 'User is frustrated',
61
+ action: 'Show empathy and offer escalation',
62
+ tags: ['support'],
63
63
  enabled: true,
64
64
  },
65
65
  ],
66
66
 
67
67
  capabilities: [
68
- { title: "Ticket Management", description: "Create and track tickets" },
68
+ { title: 'Ticket Management', description: 'Create and track tickets' },
69
69
  ],
70
70
 
71
71
  routes: [
72
72
  {
73
- title: "Create Ticket",
74
- description: "Help user create a support ticket",
75
- conditions: ["User wants to report an issue"],
73
+ title: 'Create Ticket',
74
+ description: 'Help user create a support ticket',
75
+ conditions: ['User wants to report an issue'],
76
76
  guidelines: [
77
- { condition: "Issue is urgent", action: "Prioritize immediately" },
77
+ { condition: 'Issue is urgent', action: 'Prioritize immediately' },
78
78
  ],
79
79
  },
80
80
  ],
81
81
 
82
82
  observations: [
83
83
  {
84
- description: "User mentions problem but unclear what kind",
85
- routeRefs: ["Create Ticket", "Check Ticket Status"], // By title!
84
+ description: 'User mentions problem but unclear what kind',
85
+ routeRefs: ['Create Ticket', 'Check Ticket Status'], // By title!
86
86
  },
87
87
  ],
88
88
  });
@@ -98,33 +98,49 @@ interface RouteOptions {
98
98
  title: string;
99
99
 
100
100
  // Optional
101
+ id?: string; // Custom ID (auto-generated from title if not provided)
101
102
  description?: string;
102
103
  conditions?: string[];
103
- guidelines?: Guideline[]; // NEW!
104
+ guidelines?: Guideline[];
105
+ domains?: string[]; // Restrict which domains are available in this route
106
+ rules?: string[]; // Absolute rules the agent MUST follow
107
+ prohibitions?: string[]; // Absolute prohibitions the agent MUST NEVER do
104
108
  }
105
109
  ```
106
110
 
111
+ **Domain Scoping:**
112
+ - Use `domains` to limit which registered domains (tools/methods) can be accessed during this route
113
+ - If `undefined` or omitted, all registered domains are available
114
+ - Useful for security (preventing unauthorized tool calls) and performance (reducing AI decision space)
115
+
116
+ **Rules & Prohibitions:**
117
+ - **Rules**: Absolute requirements the agent must follow in this route (style, format, behavior)
118
+ - **Prohibitions**: Things the agent must never do in this route
119
+ - These override general guidelines if there's any conflict
120
+ - Applied automatically when the route is active
121
+ - Perfect for controlling message style, tone, length, emoji usage, etc.
122
+
107
123
  ### Example: Route with Nested Guidelines
108
124
 
109
125
  ```typescript
110
126
  const agent = new Agent({
111
- name: "Bot",
127
+ name: 'Bot',
112
128
  ai: provider,
113
129
  routes: [
114
130
  {
115
- title: "Onboarding",
116
- description: "Guide new users",
117
- conditions: ["User is new"],
131
+ title: 'Onboarding',
132
+ description: 'Guide new users',
133
+ conditions: ['User is new'],
118
134
  guidelines: [
119
135
  {
120
- condition: "User skips a step",
136
+ condition: 'User skips a step',
121
137
  action: "Gently remind them it's important",
122
- tags: ["onboarding"],
138
+ tags: ['onboarding'],
123
139
  },
124
140
  {
125
- condition: "User seems confused",
126
- action: "Offer a quick tutorial video",
127
- tags: ["help"],
141
+ condition: 'User seems confused',
142
+ action: 'Offer a quick tutorial video',
143
+ tags: ['help'],
128
144
  },
129
145
  ],
130
146
  },
@@ -132,6 +148,131 @@ const agent = new Agent({
132
148
  });
133
149
  ```
134
150
 
151
+ ### Example: Route with Domain Scoping
152
+
153
+ ```typescript
154
+ // Register domains
155
+ agent.addDomain('scraping', {
156
+ scrapeSite: async (url: string) => {
157
+ /* ... */
158
+ },
159
+ extractData: async (html: string) => {
160
+ /* ... */
161
+ },
162
+ });
163
+
164
+ agent.addDomain('calendar', {
165
+ scheduleEvent: async (date: Date, title: string) => {
166
+ /* ... */
167
+ },
168
+ listEvents: async () => {
169
+ /* ... */
170
+ },
171
+ });
172
+
173
+ agent.addDomain('payment', {
174
+ processPayment: async (amount: number) => {
175
+ /* ... */
176
+ },
177
+ });
178
+
179
+ // Create routes with domain restrictions
180
+ agent.createRoute({
181
+ title: 'Data Collection',
182
+ description: 'Collect and process web data',
183
+ domains: ['scraping'], // ✅ Only scraping tools available
184
+ });
185
+
186
+ agent.createRoute({
187
+ title: 'Schedule Meeting',
188
+ description: 'Book appointments',
189
+ domains: ['calendar'], // ✅ Only calendar tools available
190
+ });
191
+
192
+ agent.createRoute({
193
+ title: 'Checkout',
194
+ description: 'Process purchase',
195
+ domains: ['payment', 'calendar'], // ✅ Multiple domains allowed
196
+ });
197
+
198
+ agent.createRoute({
199
+ title: 'FAQ Support',
200
+ description: 'Answer general questions',
201
+ domains: [], // ✅ No tools available (conversation only)
202
+ });
203
+
204
+ agent.createRoute({
205
+ title: 'Admin Support',
206
+ description: 'Administrative tasks',
207
+ // domains not specified = all domains available (for demo purposes)
208
+ });
209
+ ```
210
+
211
+ ### Example: Route with Rules & Prohibitions
212
+
213
+ ```typescript
214
+ // WhatsApp support bot with different styles per route
215
+ agent.createRoute({
216
+ title: 'Customer Support',
217
+ description: 'Help customers with issues',
218
+ domains: [],
219
+ rules: [
220
+ 'Keep messages short (maximum 2 lines per message)',
221
+ 'Use maximum 1 emoji per message',
222
+ 'Always ask if the issue is resolved before ending',
223
+ 'Professional but friendly tone'
224
+ ],
225
+ prohibitions: [
226
+ 'Never send messages longer than 3 paragraphs',
227
+ 'Do not use slang or informal language',
228
+ 'Never promise what you cannot deliver',
229
+ 'Do not ask for sensitive information via chat'
230
+ ]
231
+ });
232
+
233
+ agent.createRoute({
234
+ title: 'Sales Consultation',
235
+ description: 'Help customer discover needs and present solutions',
236
+ domains: ['calendar', 'analytics'],
237
+ rules: [
238
+ 'Ask open-ended questions to discover needs',
239
+ 'Use storytelling when presenting solutions',
240
+ 'Emoji only to reinforce positive emotions 😊',
241
+ 'Always present value before mentioning price'
242
+ ],
243
+ prohibitions: [
244
+ 'Never talk about price before showing value',
245
+ 'Do not pressure the customer',
246
+ 'Avoid complex technical terms',
247
+ 'Never send more than 2 messages in a row without customer response'
248
+ ]
249
+ });
250
+
251
+ agent.createRoute({
252
+ title: 'Emergency Support',
253
+ description: 'Handle urgent customer issues',
254
+ domains: ['notifications', 'ticketing'],
255
+ rules: [
256
+ 'Respond immediately and acknowledge urgency',
257
+ 'Use clear, direct language',
258
+ 'Provide concrete next steps',
259
+ 'Set clear expectations on resolution time'
260
+ ],
261
+ prohibitions: [
262
+ 'Never downplay the customer\'s concern',
263
+ 'Do not use emojis',
264
+ 'Never say "calm down" or similar phrases',
265
+ 'Do not transfer without explaining why'
266
+ ]
267
+ });
268
+ ```
269
+
270
+ **How it works:**
271
+ - Rules and prohibitions are automatically applied when the route is active
272
+ - They override general guidelines if there's any conflict
273
+ - Perfect for controlling communication style per context
274
+ - Applied in the AI prompt to ensure compliance
275
+
135
276
  ---
136
277
 
137
278
  ## 🔍 Observation Options
@@ -175,14 +316,14 @@ All constructor options also have fluent methods that **return `this`** for chai
175
316
 
176
317
  ```typescript
177
318
  agent
178
- .createTerm({ name: "API", description: "..." })
179
- .createGuideline({ condition: "...", action: "..." })
180
- .createCapability({ title: "...", description: "..." });
319
+ .createTerm({ name: 'API', description: '...' })
320
+ .createGuideline({ condition: '...', action: '...' })
321
+ .createCapability({ title: '...', description: '...' });
181
322
 
182
- const route = agent.createRoute({ title: "..." });
183
- route.createGuideline({ condition: "...", action: "..." });
323
+ const route = agent.createRoute({ title: '...' });
324
+ route.createGuideline({ condition: '...', action: '...' });
184
325
 
185
- const obs = agent.createObservation("User intent unclear");
326
+ const obs = agent.createObservation('User intent unclear');
186
327
  obs.disambiguate([route1, route2]);
187
328
  ```
188
329
 
@@ -209,7 +350,7 @@ obs.disambiguate([route1, route2]);
209
350
  ```typescript
210
351
  // Start with static config
211
352
  const agent = new Agent({
212
- name: "Bot",
353
+ name: 'Bot',
213
354
  ai: provider,
214
355
  terms: loadTermsFromFile(),
215
356
  guidelines: loadGuidelinesFromDB(),
@@ -218,8 +359,8 @@ const agent = new Agent({
218
359
  // Add dynamic features
219
360
  if (user.isPremium) {
220
361
  agent.createGuideline({
221
- condition: "User asks for priority support",
222
- action: "Escalate immediately to premium team",
362
+ condition: 'User asks for priority support',
363
+ action: 'Escalate immediately to premium team',
223
364
  });
224
365
  }
225
366
  ```
@@ -154,21 +154,29 @@ const onboardingRoute = agent.createRoute({
154
154
  conditions: ["User is new and needs onboarding"],
155
155
  });
156
156
 
157
- // Build the flow
157
+ // Build the flow - two approaches:
158
+
159
+ // Approach 1: Step-by-step (great for complex flows with branching)
158
160
  const step1 = onboardingRoute.initialState.transitionTo({
159
161
  chatState: "Ask for user's name",
160
162
  });
161
163
 
162
- const step2 = step1.target.transitionTo({
164
+ const step2 = step1.transitionTo({
163
165
  chatState: "Ask for user's email",
164
166
  });
165
167
 
166
- const step3 = step2.target.transitionTo({
168
+ const step3 = step2.transitionTo({
167
169
  chatState: "Confirm details and welcome user",
168
170
  });
169
171
 
170
- // End the route
171
- step3.target.transitionTo({ state: END_ROUTE });
172
+ step3.transitionTo({ state: END_ROUTE });
173
+
174
+ // Approach 2: Fluent chaining (concise for linear flows)
175
+ onboardingRoute.initialState
176
+ .transitionTo({ chatState: "Ask for user's name" })
177
+ .transitionTo({ chatState: "Ask for user's email" })
178
+ .transitionTo({ chatState: "Confirm details and welcome user" })
179
+ .transitionTo({ state: END_ROUTE });
172
180
  ```
173
181
 
174
182
  ### Handle Context Dynamically