@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
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Domain Scoping Example
3
+ *
4
+ * This example demonstrates how to use domain scoping to restrict which tools
5
+ * are available in different conversation routes for security and clarity.
6
+ */
7
+
8
+ import { Agent, createMessageEvent, EventSource } from "../src/index";
9
+ import { GeminiProvider } from "../src/providers/GeminiProvider";
10
+
11
+ // Initialize AI provider
12
+ const ai = new GeminiProvider({
13
+ apiKey: process.env.GEMINI_API_KEY || "your-api-key-here",
14
+ model: "gemini-2.0-flash-exp",
15
+ });
16
+
17
+ // Create agent
18
+ const agent = new Agent({
19
+ name: "Multi-Domain Assistant",
20
+ description:
21
+ "An assistant that handles different tasks with domain-scoped tools",
22
+ ai,
23
+ });
24
+
25
+ // Register different domains with their tools
26
+ agent.addDomain("scraping", {
27
+ scrapeSite: async (url: string) => {
28
+ console.log(`[Scraping] Scraping site: ${url}`);
29
+ return { success: true, data: "Scraped content..." };
30
+ },
31
+ extractData: async (html: string, selector: string) => {
32
+ console.log(`[Scraping] Extracting data with selector: ${selector}`);
33
+ return { elements: [] };
34
+ },
35
+ });
36
+
37
+ agent.addDomain("calendar", {
38
+ scheduleEvent: async (date: Date, title: string, description?: string) => {
39
+ console.log(`[Calendar] Scheduling event: ${title} on ${date}`);
40
+ return { eventId: "evt_123", success: true };
41
+ },
42
+ listEvents: async (startDate: Date, endDate: Date) => {
43
+ console.log(`[Calendar] Listing events from ${startDate} to ${endDate}`);
44
+ return { events: [] };
45
+ },
46
+ cancelEvent: async (eventId: string) => {
47
+ console.log(`[Calendar] Cancelling event: ${eventId}`);
48
+ return { success: true };
49
+ },
50
+ });
51
+
52
+ agent.addDomain("payment", {
53
+ processPayment: async (amount: number, currency: string) => {
54
+ console.log(`[Payment] Processing payment: ${amount} ${currency}`);
55
+ return { transactionId: "txn_456", success: true };
56
+ },
57
+ refund: async (transactionId: string) => {
58
+ console.log(`[Payment] Processing refund for: ${transactionId}`);
59
+ return { success: true };
60
+ },
61
+ checkBalance: async () => {
62
+ console.log(`[Payment] Checking balance`);
63
+ return { balance: 1000, currency: "USD" };
64
+ },
65
+ });
66
+
67
+ agent.addDomain("analytics", {
68
+ trackEvent: async (
69
+ eventName: string,
70
+ properties: Record<string, unknown>
71
+ ) => {
72
+ console.log(`[Analytics] Tracking event: ${eventName}`, properties);
73
+ return { success: true };
74
+ },
75
+ generateReport: async (
76
+ reportType: string,
77
+ dateRange: { start: Date; end: Date }
78
+ ) => {
79
+ console.log(`[Analytics] Generating ${reportType} report`);
80
+ return { report: {} };
81
+ },
82
+ });
83
+
84
+ // Create routes with domain scoping
85
+ agent.createRoute({
86
+ title: "Data Collection",
87
+ description: "Collect and process web data",
88
+ conditions: ["User wants to scrape or extract data from websites"],
89
+ domains: ["scraping"], // ✅ Only scraping tools available
90
+ });
91
+
92
+ agent.createRoute({
93
+ title: "Schedule Meeting",
94
+ description: "Book and manage appointments",
95
+ conditions: ["User wants to schedule, view, or cancel events"],
96
+ domains: ["calendar"], // ✅ Only calendar tools available
97
+ });
98
+
99
+ agent.createRoute({
100
+ title: "Checkout Process",
101
+ description: "Process purchases and payments",
102
+ conditions: ["User wants to make a purchase or payment"],
103
+ domains: ["payment", "analytics"], // ✅ Multiple domains allowed
104
+ });
105
+
106
+ agent.createRoute({
107
+ title: "Customer Support",
108
+ description: "Answer general questions and provide help",
109
+ conditions: ["User has general questions or needs support"],
110
+ domains: [], // ✅ No tools available (conversation only)
111
+ });
112
+
113
+ agent.createRoute({
114
+ title: "Admin Support",
115
+ description: "Administrative tasks with full access",
116
+ conditions: ["User is admin and needs full system access"],
117
+ // domains not specified = all domains available
118
+ });
119
+
120
+ // Example conversations
121
+ async function demonstrateScoping() {
122
+ console.log("\n=== Domain Scoping Demo ===\n");
123
+
124
+ // Example 1: Data Collection route - only scraping tools available
125
+ console.log("1️⃣ Example: User wants to scrape data");
126
+ const history1 = [
127
+ createMessageEvent(
128
+ EventSource.CUSTOMER,
129
+ "Alice",
130
+ "Can you scrape the homepage of example.com?"
131
+ ),
132
+ ];
133
+
134
+ const response1 = await agent.respond({ history: history1 });
135
+ console.log(`Route chosen: ${response1.route?.title}`);
136
+ console.log(`Available tools in this route: scraping only`);
137
+ console.log(`Response: ${response1.message}\n`);
138
+
139
+ // Example 2: Schedule Meeting route - only calendar tools available
140
+ console.log("2️⃣ Example: User wants to schedule a meeting");
141
+ const history2 = [
142
+ createMessageEvent(
143
+ EventSource.CUSTOMER,
144
+ "Bob",
145
+ "Schedule a meeting for tomorrow at 2pm"
146
+ ),
147
+ ];
148
+
149
+ const response2 = await agent.respond({ history: history2 });
150
+ console.log(`Route chosen: ${response2.route?.title}`);
151
+ console.log(`Available tools in this route: calendar only`);
152
+ console.log(`Response: ${response2.message}\n`);
153
+
154
+ // Example 3: Customer Support route - NO tools available
155
+ console.log("3️⃣ Example: User has a general question");
156
+ const history3 = [
157
+ createMessageEvent(
158
+ EventSource.CUSTOMER,
159
+ "Charlie",
160
+ "What are your business hours?"
161
+ ),
162
+ ];
163
+
164
+ const response3 = await agent.respond({ history: history3 });
165
+ console.log(`Route chosen: ${response3.route?.title}`);
166
+ console.log(`Available tools in this route: none (conversation only)`);
167
+ console.log(`Response: ${response3.message}\n`);
168
+
169
+ // Example 4: Admin Support route - ALL tools available (for demo purposes)
170
+ console.log("4️⃣ Example: Admin needs full access");
171
+ const history4 = [
172
+ createMessageEvent(
173
+ EventSource.CUSTOMER,
174
+ "Admin",
175
+ "I need to generate a report and process a refund"
176
+ ),
177
+ ];
178
+
179
+ const response4 = await agent.respond({ history: history4 });
180
+ console.log(`Route chosen: ${response4.route?.title}`);
181
+ console.log(`Available tools in this route: all domains`);
182
+ console.log(`Response: ${response4.message}\n`);
183
+ }
184
+
185
+ // Benefits demonstration
186
+ console.log(`
187
+ 🔒 Security Benefits:
188
+ - Customer Support route cannot accidentally call payment.processPayment()
189
+ - Data Collection route cannot access calendar.scheduleEvent()
190
+ - Each route has minimum necessary permissions
191
+
192
+ ⚡ Performance Benefits:
193
+ - AI only sees relevant tools for each route
194
+ - Faster decision making with reduced context
195
+ - Clearer intent and fewer errors
196
+
197
+ 🎯 Clarity Benefits:
198
+ - Routes clearly document their capabilities
199
+ - Easy to audit what each route can do
200
+ - Better debugging when tools are called
201
+ `);
202
+
203
+ // Inspect route configurations
204
+ console.log("\n📋 Route Configurations:\n");
205
+ for (const route of agent.getRoutes()) {
206
+ const domains = route.getDomains();
207
+ const domainsText =
208
+ domains === undefined
209
+ ? "all domains"
210
+ : domains.length === 0
211
+ ? "no tools (conversation only)"
212
+ : domains.join(", ");
213
+
214
+ console.log(`• ${route.title}: ${domainsText}`);
215
+ }
216
+
217
+ // Validate tool calls (example helper function)
218
+ function validateToolCall(toolName: string, routeTitle: string): boolean {
219
+ const route = agent.getRoutes().find((r) => r.title === routeTitle);
220
+ if (!route) return false;
221
+
222
+ const allowedDomains = route.getDomains();
223
+
224
+ // If undefined, all domains allowed
225
+ if (allowedDomains === undefined) return true;
226
+
227
+ // If empty array, no tools allowed
228
+ if (allowedDomains.length === 0) return false;
229
+
230
+ // Check if tool's domain is in allowed list
231
+ const [domain] = toolName.split(".");
232
+ return allowedDomains.includes(domain);
233
+ }
234
+
235
+ console.log("\n✅ Validation Examples:");
236
+ console.log(
237
+ `- scraping.scrapeSite in "Data Collection": ${validateToolCall(
238
+ "scraping.scrapeSite",
239
+ "Data Collection"
240
+ )}`
241
+ );
242
+ console.log(
243
+ `- calendar.scheduleEvent in "Data Collection": ${validateToolCall(
244
+ "calendar.scheduleEvent",
245
+ "Data Collection"
246
+ )}`
247
+ );
248
+ console.log(
249
+ `- payment.processPayment in "Customer Support": ${validateToolCall(
250
+ "payment.processPayment",
251
+ "Customer Support"
252
+ )}`
253
+ );
254
+ console.log(
255
+ `- analytics.trackEvent in "Admin Support": ${validateToolCall(
256
+ "analytics.trackEvent",
257
+ "Admin Support"
258
+ )}`
259
+ );
260
+
261
+ // Run demonstration
262
+ if (import.meta.url === `file://${process.argv[1]}`) {
263
+ demonstrateScoping().catch(console.error);
264
+ }
265
+
266
+ export { agent };
@@ -107,54 +107,54 @@ async function createHealthcareAgent() {
107
107
  chatState: "Determine the reason for the visit",
108
108
  });
109
109
 
110
- const t1 = t0.target.transitionTo({
110
+ const t1 = t0.transitionTo({
111
111
  toolState: getUpcomingSlots,
112
112
  });
113
113
 
114
- const t2 = t1.target.transitionTo({
114
+ const t2 = t1.transitionTo({
115
115
  chatState: "List available times and ask which ones works for them",
116
116
  });
117
117
 
118
- const t3 = t2.target.transitionTo(
118
+ const t3 = t2.transitionTo(
119
119
  {
120
120
  chatState: "Confirm the details with the patient before scheduling",
121
121
  },
122
122
  "The patient picks a time"
123
123
  );
124
124
 
125
- const t4 = t3.target.transitionTo(
125
+ const t4 = t3.transitionTo(
126
126
  {
127
127
  toolState: scheduleAppointment,
128
128
  },
129
129
  "The patient confirms the details"
130
130
  );
131
131
 
132
- const t5 = t4.target.transitionTo({
132
+ const t5 = t4.transitionTo({
133
133
  chatState: "Confirm the appointment has been scheduled",
134
134
  });
135
135
 
136
- t5.target.transitionTo({ state: END_ROUTE });
136
+ t5.transitionTo({ state: END_ROUTE });
137
137
 
138
138
  // Alternative path: no times work
139
- const t6 = t2.target.transitionTo(
139
+ const t6 = t2.transitionTo(
140
140
  {
141
141
  toolState: getLaterSlots,
142
142
  },
143
143
  "None of those times work for the patient"
144
144
  );
145
145
 
146
- const t7 = t6.target.transitionTo({
146
+ const t7 = t6.transitionTo({
147
147
  chatState: "List later times and ask if any of them works",
148
148
  });
149
149
 
150
- t7.target.transitionTo(
150
+ t7.transitionTo(
151
151
  {
152
- state: t3.target,
152
+ state: t3,
153
153
  },
154
154
  "The patient picks a time"
155
155
  );
156
156
 
157
- const t8 = t7.target.transitionTo(
157
+ const t8 = t7.transitionTo(
158
158
  {
159
159
  chatState:
160
160
  "Ask the patient to call the office to schedule an appointment",
@@ -162,7 +162,7 @@ async function createHealthcareAgent() {
162
162
  "None of those times work for the patient either"
163
163
  );
164
164
 
165
- t8.target.transitionTo({ state: END_ROUTE });
165
+ t8.transitionTo({ state: END_ROUTE });
166
166
 
167
167
  schedulingRoute.createGuideline({
168
168
  condition: "The patient says their visit is urgent",
@@ -180,7 +180,7 @@ async function createHealthcareAgent() {
180
180
  toolState: getLabResults,
181
181
  });
182
182
 
183
- l0.target.transitionTo(
183
+ l0.transitionTo(
184
184
  {
185
185
  chatState:
186
186
  "Tell the patient that the results are not available yet, and to try again later",
@@ -188,7 +188,7 @@ async function createHealthcareAgent() {
188
188
  "The lab results could not be found"
189
189
  );
190
190
 
191
- l0.target.transitionTo(
191
+ l0.transitionTo(
192
192
  {
193
193
  chatState:
194
194
  "Explain the lab results to the patient - that they are normal",
@@ -196,7 +196,7 @@ async function createHealthcareAgent() {
196
196
  "The lab results are good - i.e., nothing to worry about"
197
197
  );
198
198
 
199
- l0.target.transitionTo(
199
+ l0.transitionTo(
200
200
  {
201
201
  chatState:
202
202
  "Present the results and ask them to call the office for clarifications on the results as you are not a doctor",
@@ -108,12 +108,12 @@ async function main() {
108
108
  chatState: "Ask which city they want weather for",
109
109
  });
110
110
 
111
- const fetchWeather = askLocation.target.transitionTo({
111
+ const fetchWeather = askLocation.transitionTo({
112
112
  toolState: getWeather,
113
113
  condition: "User provides a city name",
114
114
  });
115
115
 
116
- const showWeather = fetchWeather.target.transitionTo({
116
+ const showWeather = fetchWeather.transitionTo({
117
117
  chatState:
118
118
  "Present the weather information in a friendly way with temperature and condition",
119
119
  });
@@ -243,34 +243,34 @@ async function createPersistentOnboardingAgent(sessionId: string) {
243
243
  chatState: "Ask for business name and a brief description",
244
244
  });
245
245
 
246
- const saveBusinessStep = askBusinessInfo.target.transitionTo({
246
+ const saveBusinessStep = askBusinessInfo.transitionTo({
247
247
  toolState: saveBusinessInfo,
248
248
  });
249
249
 
250
250
  // Step 2: Collect industry
251
- const askIndustry = saveBusinessStep.target.transitionTo({
251
+ const askIndustry = saveBusinessStep.transitionTo({
252
252
  chatState: "Ask what industry the business operates in",
253
253
  });
254
254
 
255
- const saveIndustryStep = askIndustry.target.transitionTo({
255
+ const saveIndustryStep = askIndustry.transitionTo({
256
256
  toolState: saveIndustry,
257
257
  });
258
258
 
259
259
  // Step 3: Collect contact
260
- const askContact = saveIndustryStep.target.transitionTo({
260
+ const askContact = saveIndustryStep.transitionTo({
261
261
  chatState: "Ask for their contact email",
262
262
  });
263
263
 
264
- const saveContactStep = askContact.target.transitionTo({
264
+ const saveContactStep = askContact.transitionTo({
265
265
  toolState: saveContactEmail,
266
266
  });
267
267
 
268
268
  // Step 4: Confirmation
269
- const confirm = saveContactStep.target.transitionTo({
269
+ const confirm = saveContactStep.transitionTo({
270
270
  chatState: "Summarize all collected information and ask for confirmation",
271
271
  });
272
272
 
273
- confirm.target.transitionTo({ state: END_ROUTE });
273
+ confirm.transitionTo({ state: END_ROUTE });
274
274
 
275
275
  // Guidelines
276
276
  onboardingRoute.createGuideline({
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Rules & Prohibitions Example
3
+ *
4
+ * Demonstrates how to use rules and prohibitions to control agent behavior
5
+ * in different conversation routes (e.g., WhatsApp bot with different styles)
6
+ */
7
+
8
+ import { Agent, createMessageEvent, EventSource } from "../src/index";
9
+ import { GeminiProvider } from "../src/providers/GeminiProvider";
10
+
11
+ // Initialize AI provider
12
+ const ai = new GeminiProvider({
13
+ apiKey: process.env.GEMINI_API_KEY || "your-api-key-here",
14
+ model: "gemini-2.0-flash-exp",
15
+ });
16
+
17
+ // Create WhatsApp support bot with different styles per route
18
+ const agent = new Agent({
19
+ name: "SupportBot",
20
+ description: "Customer support assistant for WhatsApp",
21
+ ai,
22
+ });
23
+
24
+ // Route 1: Quick Support - Short, direct messages
25
+ agent.createRoute({
26
+ title: "Quick Support",
27
+ description: "Fast answers for common questions",
28
+ conditions: ["User has a simple question", "User wants quick help"],
29
+ rules: [
30
+ "Keep messages extremely short (1-2 lines maximum)",
31
+ "Use bullet points for lists",
32
+ "Maximum 1 emoji per message 👍",
33
+ "Be direct and to the point",
34
+ ],
35
+ prohibitions: [
36
+ "Never send long paragraphs",
37
+ "Do not over-explain",
38
+ "Never use more than 2 emojis",
39
+ "Do not ask follow-up questions unless necessary",
40
+ ],
41
+ });
42
+
43
+ // Route 2: Sales Consultation - Conversational, engaging
44
+ agent.createRoute({
45
+ title: "Sales Consultation",
46
+ description: "Help customer discover needs and present solutions",
47
+ conditions: [
48
+ "User is interested in buying",
49
+ "User wants product information",
50
+ ],
51
+ rules: [
52
+ "Ask open-ended questions to discover needs",
53
+ "Use storytelling when presenting solutions",
54
+ "Emoji to reinforce positive emotions 😊✨",
55
+ "Present value before mentioning price",
56
+ "Make customer feel special and understood",
57
+ ],
58
+ prohibitions: [
59
+ "Never talk about price before showing value",
60
+ "Do not pressure or push",
61
+ "Avoid technical jargon",
62
+ "Never send more than 2 messages without waiting for response",
63
+ "Do not make promises you cannot keep",
64
+ ],
65
+ });
66
+
67
+ // Route 3: Technical Support - Detailed, step-by-step
68
+ agent.createRoute({
69
+ title: "Technical Support",
70
+ description: "Help with technical issues and troubleshooting",
71
+ conditions: ["User has technical problem", "User needs step-by-step help"],
72
+ rules: [
73
+ "Provide clear, numbered steps",
74
+ "Use simple language for technical concepts",
75
+ "Confirm understanding after each major step",
76
+ "Offer screenshots or visual aids when helpful",
77
+ "Be patient and thorough",
78
+ ],
79
+ prohibitions: [
80
+ "Never skip steps or assume knowledge",
81
+ "Do not use excessive technical terms without explanation",
82
+ "Never blame the user for the issue",
83
+ "Do not rush through explanations",
84
+ ],
85
+ });
86
+
87
+ // Route 4: Emergency Support - Calm, reassuring, action-oriented
88
+ agent.createRoute({
89
+ title: "Emergency Support",
90
+ description: "Handle urgent customer issues",
91
+ conditions: ["Customer is frustrated", "Urgent issue", "Service down"],
92
+ rules: [
93
+ "Acknowledge the urgency immediately",
94
+ "Express empathy and understanding",
95
+ "Provide concrete next steps",
96
+ "Set clear expectations on resolution time",
97
+ "Keep customer updated",
98
+ ],
99
+ prohibitions: [
100
+ "Never downplay the customer's concern",
101
+ "Do not use emojis (keep it professional)",
102
+ 'Never say "calm down" or similar dismissive phrases',
103
+ "Do not transfer without explaining why",
104
+ "Never make excuses or blame others",
105
+ ],
106
+ });
107
+
108
+ // Route 5: General Chat - Friendly, casual, helpful
109
+ agent.createRoute({
110
+ title: "General Chat",
111
+ description: "Casual conversation and general questions",
112
+ conditions: ["User is just chatting", "Greeting", "General question"],
113
+ rules: [
114
+ "Be friendly and conversational",
115
+ "Use emojis naturally 😊",
116
+ "Mirror the customer's tone and energy",
117
+ "Keep it light and positive",
118
+ ],
119
+ prohibitions: [
120
+ "Do not be overly formal",
121
+ "Never ignore the customer's mood",
122
+ "Do not push products unless asked",
123
+ ],
124
+ });
125
+
126
+ // Demonstration function
127
+ async function demonstrateRulesAndProhibitions() {
128
+ console.log("\n=== Rules & Prohibitions Demo ===\n");
129
+
130
+ // Example 1: Quick Support - Should be short and direct
131
+ console.log("1️⃣ Quick Support Route (short, direct)");
132
+ const history1 = [
133
+ createMessageEvent(
134
+ EventSource.CUSTOMER,
135
+ "Alice",
136
+ "What are your business hours?"
137
+ ),
138
+ ];
139
+
140
+ const response1 = await agent.respond({ history: history1 });
141
+ console.log(`Route: ${response1.route?.title}`);
142
+ console.log(`Response: ${response1.message}`);
143
+ console.log(`Expected: Short, direct, max 1 emoji\n`);
144
+
145
+ // Example 2: Sales Consultation - Should be engaging and value-focused
146
+ console.log("2️⃣ Sales Consultation Route (conversational, value-first)");
147
+ const history2 = [
148
+ createMessageEvent(
149
+ EventSource.CUSTOMER,
150
+ "Bob",
151
+ "I'm interested in your premium plan"
152
+ ),
153
+ ];
154
+
155
+ const response2 = await agent.respond({ history: history2 });
156
+ console.log(`Route: ${response2.route?.title}`);
157
+ console.log(`Response: ${response2.message}`);
158
+ console.log(`Expected: Ask about needs, show value before price\n`);
159
+
160
+ // Example 3: Technical Support - Should be detailed and step-by-step
161
+ console.log("3️⃣ Technical Support Route (detailed, step-by-step)");
162
+ const history3 = [
163
+ createMessageEvent(
164
+ EventSource.CUSTOMER,
165
+ "Charlie",
166
+ "My app keeps crashing when I try to login"
167
+ ),
168
+ ];
169
+
170
+ const response3 = await agent.respond({ history: history3 });
171
+ console.log(`Route: ${response3.route?.title}`);
172
+ console.log(`Response: ${response3.message}`);
173
+ console.log(`Expected: Clear steps, simple language, patient\n`);
174
+
175
+ // Example 4: Emergency Support - Should be calm and action-oriented
176
+ console.log("4️⃣ Emergency Support Route (urgent, professional)");
177
+ const history4 = [
178
+ createMessageEvent(
179
+ EventSource.CUSTOMER,
180
+ "Diana",
181
+ "This is urgent! My payment failed and I need access NOW!"
182
+ ),
183
+ ];
184
+
185
+ const response4 = await agent.respond({ history: history4 });
186
+ console.log(`Route: ${response4.route?.title}`);
187
+ console.log(`Response: ${response4.message}`);
188
+ console.log(`Expected: Acknowledge urgency, no emojis, concrete steps\n`);
189
+
190
+ // Example 5: General Chat - Should be friendly and casual
191
+ console.log("5️⃣ General Chat Route (friendly, casual)");
192
+ const history5 = [
193
+ createMessageEvent(EventSource.CUSTOMER, "Eve", "Hey! How's it going?"),
194
+ ];
195
+
196
+ const response5 = await agent.respond({ history: history5 });
197
+ console.log(`Route: ${response5.route?.title}`);
198
+ console.log(`Response: ${response5.message}`);
199
+ console.log(`Expected: Friendly, emojis, mirrors customer tone\n`);
200
+ }
201
+
202
+ // Inspect route configurations
203
+ console.log("\n📋 Route Configurations:\n");
204
+ for (const route of agent.getRoutes()) {
205
+ console.log(`\n🛤️ ${route.title}`);
206
+
207
+ const rules = route.getRules();
208
+ if (rules.length > 0) {
209
+ console.log(` ✅ Rules (${rules.length}):`);
210
+ rules.forEach((rule, i) => console.log(` ${i + 1}. ${rule}`));
211
+ }
212
+
213
+ const prohibitions = route.getProhibitions();
214
+ if (prohibitions.length > 0) {
215
+ console.log(` ❌ Prohibitions (${prohibitions.length}):`);
216
+ prohibitions.forEach((prohibition, i) =>
217
+ console.log(` ${i + 1}. ${prohibition}`)
218
+ );
219
+ }
220
+ }
221
+
222
+ // Benefits explanation
223
+ console.log(`
224
+ \n💡 Benefits of Rules & Prohibitions:
225
+
226
+ 1️⃣ **Context-Specific Behavior**
227
+ - Each route can have completely different communication styles
228
+ - WhatsApp support: short messages
229
+ - Sales: engaging, story-driven
230
+ - Technical: detailed, step-by-step
231
+
232
+ 2️⃣ **Brand Consistency**
233
+ - Rules ensure the agent always follows brand guidelines
234
+ - Prohibitions prevent off-brand behavior
235
+ - Different routes for different contexts
236
+
237
+ 3️⃣ **User Experience**
238
+ - Emergency route: professional, no emojis
239
+ - General chat: friendly, casual
240
+ - Technical support: patient, thorough
241
+
242
+ 4️⃣ **Automatic Enforcement**
243
+ - Rules are applied in the AI prompt automatically
244
+ - No manual checking needed
245
+ - Consistent behavior across all conversations
246
+
247
+ 5️⃣ **Easy to Update**
248
+ - Change rules without changing code
249
+ - A/B test different communication styles
250
+ - Iterate based on customer feedback
251
+ `);
252
+
253
+ // Run demonstration
254
+ if (import.meta.url === `file://${process.argv[1]}`) {
255
+ demonstrateRulesAndProhibitions().catch(console.error);
256
+ }
257
+
258
+ export { agent };