@falai/agent 0.3.0 → 0.3.11

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 (114) hide show
  1. package/README.md +257 -24
  2. package/dist/cjs/core/Agent.d.ts +37 -0
  3. package/dist/cjs/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/core/Agent.js +167 -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/index.d.ts +2 -0
  19. package/dist/cjs/index.d.ts.map +1 -1
  20. package/dist/cjs/index.js +3 -1
  21. package/dist/cjs/index.js.map +1 -1
  22. package/dist/cjs/providers/AnthropicProvider.d.ts +43 -0
  23. package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -0
  24. package/dist/cjs/providers/AnthropicProvider.js +328 -0
  25. package/dist/cjs/providers/AnthropicProvider.js.map +1 -0
  26. package/dist/cjs/providers/GeminiProvider.d.ts +4 -1
  27. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  28. package/dist/cjs/providers/GeminiProvider.js +96 -0
  29. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  30. package/dist/cjs/providers/OpenAIProvider.d.ts +4 -1
  31. package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
  32. package/dist/cjs/providers/OpenAIProvider.js +115 -0
  33. package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
  34. package/dist/cjs/providers/OpenRouterProvider.d.ts +4 -1
  35. package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
  36. package/dist/cjs/providers/OpenRouterProvider.js +115 -0
  37. package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
  38. package/dist/cjs/providers/index.d.ts +13 -0
  39. package/dist/cjs/providers/index.d.ts.map +1 -0
  40. package/dist/cjs/providers/index.js +16 -0
  41. package/dist/cjs/providers/index.js.map +1 -0
  42. package/dist/cjs/types/ai.d.ts +28 -0
  43. package/dist/cjs/types/ai.d.ts.map +1 -1
  44. package/dist/cjs/types/route.d.ts +6 -0
  45. package/dist/cjs/types/route.d.ts.map +1 -1
  46. package/dist/core/Agent.d.ts +37 -0
  47. package/dist/core/Agent.d.ts.map +1 -1
  48. package/dist/core/Agent.js +167 -1
  49. package/dist/core/Agent.js.map +1 -1
  50. package/dist/core/DomainRegistry.d.ts +10 -0
  51. package/dist/core/DomainRegistry.d.ts.map +1 -1
  52. package/dist/core/DomainRegistry.js +25 -0
  53. package/dist/core/DomainRegistry.js.map +1 -1
  54. package/dist/core/PromptBuilder.d.ts +9 -1
  55. package/dist/core/PromptBuilder.d.ts.map +1 -1
  56. package/dist/core/PromptBuilder.js +49 -2
  57. package/dist/core/PromptBuilder.js.map +1 -1
  58. package/dist/core/Route.d.ts +16 -0
  59. package/dist/core/Route.d.ts.map +1 -1
  60. package/dist/core/Route.js +22 -0
  61. package/dist/core/Route.js.map +1 -1
  62. package/dist/index.d.ts +2 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +1 -0
  65. package/dist/index.js.map +1 -1
  66. package/dist/providers/AnthropicProvider.d.ts +43 -0
  67. package/dist/providers/AnthropicProvider.d.ts.map +1 -0
  68. package/dist/providers/AnthropicProvider.js +321 -0
  69. package/dist/providers/AnthropicProvider.js.map +1 -0
  70. package/dist/providers/GeminiProvider.d.ts +4 -1
  71. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  72. package/dist/providers/GeminiProvider.js +96 -0
  73. package/dist/providers/GeminiProvider.js.map +1 -1
  74. package/dist/providers/OpenAIProvider.d.ts +4 -1
  75. package/dist/providers/OpenAIProvider.d.ts.map +1 -1
  76. package/dist/providers/OpenAIProvider.js +115 -0
  77. package/dist/providers/OpenAIProvider.js.map +1 -1
  78. package/dist/providers/OpenRouterProvider.d.ts +4 -1
  79. package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
  80. package/dist/providers/OpenRouterProvider.js +115 -0
  81. package/dist/providers/OpenRouterProvider.js.map +1 -1
  82. package/dist/providers/index.d.ts +13 -0
  83. package/dist/providers/index.d.ts.map +1 -0
  84. package/dist/providers/index.js +9 -0
  85. package/dist/providers/index.js.map +1 -0
  86. package/dist/types/ai.d.ts +28 -0
  87. package/dist/types/ai.d.ts.map +1 -1
  88. package/dist/types/route.d.ts +6 -0
  89. package/dist/types/route.d.ts.map +1 -1
  90. package/docs/API_REFERENCE.md +357 -2
  91. package/docs/CONSTRUCTOR_OPTIONS.md +178 -37
  92. package/docs/GETTING_STARTED.md +10 -2
  93. package/docs/PROVIDERS.md +139 -2
  94. package/examples/business-onboarding.ts +708 -0
  95. package/examples/declarative-agent.ts +1 -1
  96. package/examples/domain-scoping.ts +267 -0
  97. package/examples/healthcare-agent.ts +4 -4
  98. package/examples/openai-agent.ts +6 -4
  99. package/examples/rules-prohibitions.ts +258 -0
  100. package/examples/streaming-agent.ts +371 -0
  101. package/examples/travel-agent.ts +7 -4
  102. package/package.json +2 -1
  103. package/src/core/Agent.ts +220 -1
  104. package/src/core/DomainRegistry.ts +30 -0
  105. package/src/core/PromptBuilder.ts +70 -3
  106. package/src/core/Route.ts +28 -0
  107. package/src/index.ts +2 -0
  108. package/src/providers/AnthropicProvider.ts +467 -0
  109. package/src/providers/GeminiProvider.ts +135 -0
  110. package/src/providers/OpenAIProvider.ts +157 -0
  111. package/src/providers/OpenRouterProvider.ts +157 -0
  112. package/src/providers/index.ts +16 -0
  113. package/src/types/ai.ts +32 -0
  114. package/src/types/route.ts +6 -0
@@ -0,0 +1,267 @@
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 { OpenRouterProvider } from "../src/providers";
10
+
11
+ // Initialize AI provider
12
+ const ai = new OpenRouterProvider({
13
+ apiKey: process.env.OPENROUTER_API_KEY || "your-api-key-here",
14
+ model: "google/gemini-2.0-flash-exp",
15
+ backupModels: ["anthropic/claude-sonnet-4-5"],
16
+ });
17
+
18
+ // Create agent
19
+ const agent = new Agent({
20
+ name: "Multi-Domain Assistant",
21
+ description:
22
+ "An assistant that handles different tasks with domain-scoped tools",
23
+ ai,
24
+ });
25
+
26
+ // Register different domains with their tools
27
+ agent.addDomain("scraping", {
28
+ scrapeSite: async (url: string) => {
29
+ console.log(`[Scraping] Scraping site: ${url}`);
30
+ return { success: true, data: "Scraped content..." };
31
+ },
32
+ extractData: async (html: string, selector: string) => {
33
+ console.log(`[Scraping] Extracting data with selector: ${selector}`);
34
+ return { elements: [] };
35
+ },
36
+ });
37
+
38
+ agent.addDomain("calendar", {
39
+ scheduleEvent: async (date: Date, title: string, description?: string) => {
40
+ console.log(`[Calendar] Scheduling event: ${title} on ${date}`);
41
+ return { eventId: "evt_123", success: true };
42
+ },
43
+ listEvents: async (startDate: Date, endDate: Date) => {
44
+ console.log(`[Calendar] Listing events from ${startDate} to ${endDate}`);
45
+ return { events: [] };
46
+ },
47
+ cancelEvent: async (eventId: string) => {
48
+ console.log(`[Calendar] Cancelling event: ${eventId}`);
49
+ return { success: true };
50
+ },
51
+ });
52
+
53
+ agent.addDomain("payment", {
54
+ processPayment: async (amount: number, currency: string) => {
55
+ console.log(`[Payment] Processing payment: ${amount} ${currency}`);
56
+ return { transactionId: "txn_456", success: true };
57
+ },
58
+ refund: async (transactionId: string) => {
59
+ console.log(`[Payment] Processing refund for: ${transactionId}`);
60
+ return { success: true };
61
+ },
62
+ checkBalance: async () => {
63
+ console.log(`[Payment] Checking balance`);
64
+ return { balance: 1000, currency: "USD" };
65
+ },
66
+ });
67
+
68
+ agent.addDomain("analytics", {
69
+ trackEvent: async (
70
+ eventName: string,
71
+ properties: Record<string, unknown>
72
+ ) => {
73
+ console.log(`[Analytics] Tracking event: ${eventName}`, properties);
74
+ return { success: true };
75
+ },
76
+ generateReport: async (
77
+ reportType: string,
78
+ dateRange: { start: Date; end: Date }
79
+ ) => {
80
+ console.log(`[Analytics] Generating ${reportType} report`);
81
+ return { report: {} };
82
+ },
83
+ });
84
+
85
+ // Create routes with domain scoping
86
+ agent.createRoute({
87
+ title: "Data Collection",
88
+ description: "Collect and process web data",
89
+ conditions: ["User wants to scrape or extract data from websites"],
90
+ domains: ["scraping"], // ✅ Only scraping tools available
91
+ });
92
+
93
+ agent.createRoute({
94
+ title: "Schedule Meeting",
95
+ description: "Book and manage appointments",
96
+ conditions: ["User wants to schedule, view, or cancel events"],
97
+ domains: ["calendar"], // ✅ Only calendar tools available
98
+ });
99
+
100
+ agent.createRoute({
101
+ title: "Checkout Process",
102
+ description: "Process purchases and payments",
103
+ conditions: ["User wants to make a purchase or payment"],
104
+ domains: ["payment", "analytics"], // ✅ Multiple domains allowed
105
+ });
106
+
107
+ agent.createRoute({
108
+ title: "Customer Support",
109
+ description: "Answer general questions and provide help",
110
+ conditions: ["User has general questions or needs support"],
111
+ domains: [], // ✅ No tools available (conversation only)
112
+ });
113
+
114
+ agent.createRoute({
115
+ title: "Admin Support",
116
+ description: "Administrative tasks with full access",
117
+ conditions: ["User is admin and needs full system access"],
118
+ // domains not specified = all domains available
119
+ });
120
+
121
+ // Example conversations
122
+ async function demonstrateScoping() {
123
+ console.log("\n=== Domain Scoping Demo ===\n");
124
+
125
+ // Example 1: Data Collection route - only scraping tools available
126
+ console.log("1️⃣ Example: User wants to scrape data");
127
+ const history1 = [
128
+ createMessageEvent(
129
+ EventSource.CUSTOMER,
130
+ "Alice",
131
+ "Can you scrape the homepage of example.com?"
132
+ ),
133
+ ];
134
+
135
+ const response1 = await agent.respond({ history: history1 });
136
+ console.log(`Route chosen: ${response1.route?.title}`);
137
+ console.log(`Available tools in this route: scraping only`);
138
+ console.log(`Response: ${response1.message}\n`);
139
+
140
+ // Example 2: Schedule Meeting route - only calendar tools available
141
+ console.log("2️⃣ Example: User wants to schedule a meeting");
142
+ const history2 = [
143
+ createMessageEvent(
144
+ EventSource.CUSTOMER,
145
+ "Bob",
146
+ "Schedule a meeting for tomorrow at 2pm"
147
+ ),
148
+ ];
149
+
150
+ const response2 = await agent.respond({ history: history2 });
151
+ console.log(`Route chosen: ${response2.route?.title}`);
152
+ console.log(`Available tools in this route: calendar only`);
153
+ console.log(`Response: ${response2.message}\n`);
154
+
155
+ // Example 3: Customer Support route - NO tools available
156
+ console.log("3️⃣ Example: User has a general question");
157
+ const history3 = [
158
+ createMessageEvent(
159
+ EventSource.CUSTOMER,
160
+ "Charlie",
161
+ "What are your business hours?"
162
+ ),
163
+ ];
164
+
165
+ const response3 = await agent.respond({ history: history3 });
166
+ console.log(`Route chosen: ${response3.route?.title}`);
167
+ console.log(`Available tools in this route: none (conversation only)`);
168
+ console.log(`Response: ${response3.message}\n`);
169
+
170
+ // Example 4: Admin Support route - ALL tools available (for demo purposes)
171
+ console.log("4️⃣ Example: Admin needs full access");
172
+ const history4 = [
173
+ createMessageEvent(
174
+ EventSource.CUSTOMER,
175
+ "Admin",
176
+ "I need to generate a report and process a refund"
177
+ ),
178
+ ];
179
+
180
+ const response4 = await agent.respond({ history: history4 });
181
+ console.log(`Route chosen: ${response4.route?.title}`);
182
+ console.log(`Available tools in this route: all domains`);
183
+ console.log(`Response: ${response4.message}\n`);
184
+ }
185
+
186
+ // Benefits demonstration
187
+ console.log(`
188
+ 🔒 Security Benefits:
189
+ - Customer Support route cannot accidentally call payment.processPayment()
190
+ - Data Collection route cannot access calendar.scheduleEvent()
191
+ - Each route has minimum necessary permissions
192
+
193
+ ⚡ Performance Benefits:
194
+ - AI only sees relevant tools for each route
195
+ - Faster decision making with reduced context
196
+ - Clearer intent and fewer errors
197
+
198
+ 🎯 Clarity Benefits:
199
+ - Routes clearly document their capabilities
200
+ - Easy to audit what each route can do
201
+ - Better debugging when tools are called
202
+ `);
203
+
204
+ // Inspect route configurations
205
+ console.log("\n📋 Route Configurations:\n");
206
+ for (const route of agent.getRoutes()) {
207
+ const domains = route.getDomains();
208
+ const domainsText =
209
+ domains === undefined
210
+ ? "all domains"
211
+ : domains.length === 0
212
+ ? "no tools (conversation only)"
213
+ : domains.join(", ");
214
+
215
+ console.log(`• ${route.title}: ${domainsText}`);
216
+ }
217
+
218
+ // Validate tool calls (example helper function)
219
+ function validateToolCall(toolName: string, routeTitle: string): boolean {
220
+ const route = agent.getRoutes().find((r) => r.title === routeTitle);
221
+ if (!route) return false;
222
+
223
+ const allowedDomains = route.getDomains();
224
+
225
+ // If undefined, all domains allowed
226
+ if (allowedDomains === undefined) return true;
227
+
228
+ // If empty array, no tools allowed
229
+ if (allowedDomains.length === 0) return false;
230
+
231
+ // Check if tool's domain is in allowed list
232
+ const [domain] = toolName.split(".");
233
+ return allowedDomains.includes(domain);
234
+ }
235
+
236
+ console.log("\n✅ Validation Examples:");
237
+ console.log(
238
+ `- scraping.scrapeSite in "Data Collection": ${validateToolCall(
239
+ "scraping.scrapeSite",
240
+ "Data Collection"
241
+ )}`
242
+ );
243
+ console.log(
244
+ `- calendar.scheduleEvent in "Data Collection": ${validateToolCall(
245
+ "calendar.scheduleEvent",
246
+ "Data Collection"
247
+ )}`
248
+ );
249
+ console.log(
250
+ `- payment.processPayment in "Customer Support": ${validateToolCall(
251
+ "payment.processPayment",
252
+ "Customer Support"
253
+ )}`
254
+ );
255
+ console.log(
256
+ `- analytics.trackEvent in "Admin Support": ${validateToolCall(
257
+ "analytics.trackEvent",
258
+ "Admin Support"
259
+ )}`
260
+ );
261
+
262
+ // Run demonstration
263
+ if (import.meta.url === `file://${process.argv[1]}`) {
264
+ demonstrateScoping().catch(console.error);
265
+ }
266
+
267
+ export { agent };
@@ -5,7 +5,7 @@
5
5
  import {
6
6
  Agent,
7
7
  defineTool,
8
- GeminiProvider,
8
+ AnthropicProvider,
9
9
  END_ROUTE,
10
10
  EventSource,
11
11
  createMessageEvent,
@@ -63,9 +63,9 @@ const getLabResults = defineTool<HealthcareContext, [], object>(
63
63
  );
64
64
 
65
65
  async function createHealthcareAgent() {
66
- const provider = new GeminiProvider({
67
- apiKey: process.env.GEMINI_API_KEY || "test-key",
68
- model: "models/gemini-2.5-flash",
66
+ const provider = new AnthropicProvider({
67
+ apiKey: process.env.ANTHROPIC_API_KEY || "test-key",
68
+ model: "claude-sonnet-4-5",
69
69
  });
70
70
 
71
71
  const agent = new Agent<HealthcareContext>({
@@ -108,10 +108,12 @@ async function main() {
108
108
  chatState: "Ask which city they want weather for",
109
109
  });
110
110
 
111
- const fetchWeather = askLocation.transitionTo({
112
- toolState: getWeather,
113
- condition: "User provides a city name",
114
- });
111
+ const fetchWeather = askLocation.transitionTo(
112
+ {
113
+ toolState: getWeather,
114
+ },
115
+ "User provides a city name"
116
+ );
115
117
 
116
118
  const showWeather = fetchWeather.transitionTo({
117
119
  chatState:
@@ -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 { AnthropicProvider } from "../src/providers";
10
+
11
+ // Initialize AI provider
12
+ const ai = new AnthropicProvider({
13
+ apiKey: process.env.ANTHROPIC_API_KEY || "your-api-key-here",
14
+ model: "claude-sonnet-4-5",
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 };