@falai/agent 0.6.3 → 0.6.5

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 (137) hide show
  1. package/README.md +89 -29
  2. package/dist/cjs/constants/index.d.ts +6 -1
  3. package/dist/cjs/constants/index.d.ts.map +1 -1
  4. package/dist/cjs/constants/index.js +8 -3
  5. package/dist/cjs/constants/index.js.map +1 -1
  6. package/dist/cjs/core/Agent.d.ts +22 -0
  7. package/dist/cjs/core/Agent.d.ts.map +1 -1
  8. package/dist/cjs/core/Agent.js +113 -26
  9. package/dist/cjs/core/Agent.js.map +1 -1
  10. package/dist/cjs/core/Events.d.ts +13 -0
  11. package/dist/cjs/core/Events.d.ts.map +1 -1
  12. package/dist/cjs/core/Events.js +28 -14
  13. package/dist/cjs/core/Events.js.map +1 -1
  14. package/dist/cjs/core/ResponseEngine.d.ts +1 -1
  15. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
  16. package/dist/cjs/core/ResponseEngine.js +4 -1
  17. package/dist/cjs/core/ResponseEngine.js.map +1 -1
  18. package/dist/cjs/core/Route.d.ts.map +1 -1
  19. package/dist/cjs/core/Route.js +4 -4
  20. package/dist/cjs/core/Route.js.map +1 -1
  21. package/dist/cjs/core/RoutingEngine.d.ts +6 -1
  22. package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
  23. package/dist/cjs/core/RoutingEngine.js +116 -41
  24. package/dist/cjs/core/RoutingEngine.js.map +1 -1
  25. package/dist/cjs/core/State.d.ts +18 -6
  26. package/dist/cjs/core/State.d.ts.map +1 -1
  27. package/dist/cjs/core/State.js +30 -7
  28. package/dist/cjs/core/State.js.map +1 -1
  29. package/dist/cjs/core/Tool.d.ts +8 -1
  30. package/dist/cjs/core/Tool.d.ts.map +1 -1
  31. package/dist/cjs/core/Tool.js +25 -28
  32. package/dist/cjs/core/Tool.js.map +1 -1
  33. package/dist/cjs/core/Transition.js +1 -1
  34. package/dist/cjs/index.d.ts +1 -1
  35. package/dist/cjs/index.d.ts.map +1 -1
  36. package/dist/cjs/index.js +3 -2
  37. package/dist/cjs/index.js.map +1 -1
  38. package/dist/cjs/types/agent.d.ts +5 -0
  39. package/dist/cjs/types/agent.d.ts.map +1 -1
  40. package/dist/cjs/types/agent.js.map +1 -1
  41. package/dist/cjs/types/route.d.ts +7 -1
  42. package/dist/cjs/types/route.d.ts.map +1 -1
  43. package/dist/cjs/types/session.d.ts +13 -2
  44. package/dist/cjs/types/session.d.ts.map +1 -1
  45. package/dist/cjs/types/session.js +28 -5
  46. package/dist/cjs/types/session.js.map +1 -1
  47. package/dist/cjs/utils/logger.d.ts +10 -0
  48. package/dist/cjs/utils/logger.d.ts.map +1 -0
  49. package/dist/cjs/utils/logger.js +23 -0
  50. package/dist/cjs/utils/logger.js.map +1 -0
  51. package/dist/constants/index.d.ts +6 -1
  52. package/dist/constants/index.d.ts.map +1 -1
  53. package/dist/constants/index.js +6 -1
  54. package/dist/constants/index.js.map +1 -1
  55. package/dist/core/Agent.d.ts +22 -0
  56. package/dist/core/Agent.d.ts.map +1 -1
  57. package/dist/core/Agent.js +113 -26
  58. package/dist/core/Agent.js.map +1 -1
  59. package/dist/core/Events.d.ts +13 -0
  60. package/dist/core/Events.d.ts.map +1 -1
  61. package/dist/core/Events.js +28 -14
  62. package/dist/core/Events.js.map +1 -1
  63. package/dist/core/ResponseEngine.d.ts +1 -1
  64. package/dist/core/ResponseEngine.d.ts.map +1 -1
  65. package/dist/core/ResponseEngine.js +4 -1
  66. package/dist/core/ResponseEngine.js.map +1 -1
  67. package/dist/core/Route.d.ts.map +1 -1
  68. package/dist/core/Route.js +4 -4
  69. package/dist/core/Route.js.map +1 -1
  70. package/dist/core/RoutingEngine.d.ts +6 -1
  71. package/dist/core/RoutingEngine.d.ts.map +1 -1
  72. package/dist/core/RoutingEngine.js +116 -41
  73. package/dist/core/RoutingEngine.js.map +1 -1
  74. package/dist/core/State.d.ts +18 -6
  75. package/dist/core/State.d.ts.map +1 -1
  76. package/dist/core/State.js +31 -8
  77. package/dist/core/State.js.map +1 -1
  78. package/dist/core/Tool.d.ts +8 -1
  79. package/dist/core/Tool.d.ts.map +1 -1
  80. package/dist/core/Tool.js +25 -28
  81. package/dist/core/Tool.js.map +1 -1
  82. package/dist/core/Transition.js +1 -1
  83. package/dist/index.d.ts +1 -1
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +1 -1
  86. package/dist/index.js.map +1 -1
  87. package/dist/types/agent.d.ts +5 -0
  88. package/dist/types/agent.d.ts.map +1 -1
  89. package/dist/types/agent.js.map +1 -1
  90. package/dist/types/route.d.ts +7 -1
  91. package/dist/types/route.d.ts.map +1 -1
  92. package/dist/types/session.d.ts +13 -2
  93. package/dist/types/session.d.ts.map +1 -1
  94. package/dist/types/session.js +28 -5
  95. package/dist/types/session.js.map +1 -1
  96. package/dist/utils/logger.d.ts +10 -0
  97. package/dist/utils/logger.d.ts.map +1 -0
  98. package/dist/utils/logger.js +17 -0
  99. package/dist/utils/logger.js.map +1 -0
  100. package/docs/{CONSTRUCTOR_OPTIONS.md → AGENT.md} +79 -7
  101. package/docs/API_REFERENCE.md +309 -18
  102. package/docs/ARCHITECTURE.md +1 -1
  103. package/docs/DOCS.md +46 -22
  104. package/docs/GETTING_STARTED.md +1 -1
  105. package/docs/README.md +13 -5
  106. package/docs/ROUTES.md +743 -0
  107. package/docs/STATES.md +798 -0
  108. package/examples/business-onboarding.ts +46 -5
  109. package/examples/company-qna-agent.ts +107 -1
  110. package/examples/custom-database-persistence.ts +44 -1
  111. package/examples/declarative-agent.ts +80 -37
  112. package/examples/domain-scoping.ts +91 -21
  113. package/examples/extracted-data-modification.ts +64 -2
  114. package/examples/healthcare-agent.ts +61 -4
  115. package/examples/openai-agent.ts +24 -2
  116. package/examples/opensearch-persistence.ts +26 -1
  117. package/examples/persistent-onboarding.ts +84 -18
  118. package/examples/prisma-persistence.ts +90 -16
  119. package/examples/redis-persistence.ts +89 -17
  120. package/examples/rules-prohibitions.ts +300 -139
  121. package/examples/streaming-agent.ts +60 -0
  122. package/examples/travel-agent.ts +66 -24
  123. package/package.json +3 -2
  124. package/src/constants/index.ts +6 -1
  125. package/src/core/Agent.ts +140 -24
  126. package/src/core/Events.ts +73 -10
  127. package/src/core/ResponseEngine.ts +6 -0
  128. package/src/core/Route.ts +8 -4
  129. package/src/core/RoutingEngine.ts +154 -43
  130. package/src/core/State.ts +45 -12
  131. package/src/core/Tool.ts +67 -10
  132. package/src/core/Transition.ts +1 -1
  133. package/src/index.ts +1 -1
  134. package/src/types/agent.ts +5 -0
  135. package/src/types/route.ts +10 -1
  136. package/src/types/session.ts +47 -7
  137. package/src/utils/logger.ts +19 -0
@@ -16,6 +16,7 @@ import {
16
16
  EventSource,
17
17
  MessageEventData,
18
18
  Event,
19
+ END_STATE,
19
20
  } from "../src/index";
20
21
  // @ts-ignore
21
22
  import Redis from "ioredis";
@@ -46,6 +47,17 @@ interface SupportTicketData {
46
47
  description: string;
47
48
  }
48
49
 
50
+ interface QuickChatData {
51
+ topic: string;
52
+ sentiment: "positive" | "neutral" | "negative";
53
+ }
54
+
55
+ interface OrderData {
56
+ productId: string;
57
+ quantity: number;
58
+ shippingAddress: string;
59
+ }
60
+
49
61
  async function example() {
50
62
  // Initialize Redis client
51
63
  const redis = new Redis();
@@ -137,7 +149,8 @@ async function example() {
137
149
  .transitionTo({
138
150
  chatState: "Confirm and create ticket",
139
151
  requiredData: ["issue", "category", "description"],
140
- });
152
+ })
153
+ .transitionTo({ state: END_STATE });
141
154
 
142
155
  const persistence = agent.getPersistenceManager();
143
156
  if (!persistence) return;
@@ -231,6 +244,13 @@ async function example() {
231
244
  content: response2.message,
232
245
  });
233
246
 
247
+ if (response2.isRouteComplete) {
248
+ console.log("\n✅ Support ticket route complete!");
249
+ await fileSupportTicket(
250
+ agent.getExtractedData(session.id) as SupportTicketData
251
+ );
252
+ }
253
+
234
254
  // Load session state from Redis (demonstrates persistence)
235
255
  console.log("\n--- Loading Session from Redis ---");
236
256
  const loadedSession = await persistence.loadSessionState<SupportTicketData>(
@@ -260,11 +280,6 @@ async function example() {
260
280
  async function highThroughputExample() {
261
281
  const redis = new Redis();
262
282
 
263
- interface QuickChatData {
264
- topic: string;
265
- sentiment: "positive" | "neutral" | "negative";
266
- }
267
-
268
283
  const agent = new Agent({
269
284
  name: "Chat Bot",
270
285
  description: "Fast chat responses",
@@ -303,10 +318,12 @@ async function highThroughputExample() {
303
318
  },
304
319
  });
305
320
 
306
- chatRoute.initialState.transitionTo({
307
- chatState: "Chat and extract topic/sentiment",
308
- gather: ["topic", "sentiment"],
309
- });
321
+ chatRoute.initialState
322
+ .transitionTo({
323
+ chatState: "Chat and extract topic/sentiment",
324
+ gather: ["topic", "sentiment"],
325
+ })
326
+ .transitionTo({ state: END_STATE });
310
327
 
311
328
  const persistence = agent.getPersistenceManager()!;
312
329
 
@@ -331,6 +348,14 @@ async function highThroughputExample() {
331
348
 
332
349
  console.log("🤖 Response:", response.message);
333
350
  console.log("📊 Extracted:", response.session?.extracted);
351
+
352
+ if (response.isRouteComplete) {
353
+ console.log("\n✅ Chat analytics route complete!");
354
+ await logChatAnalytics(
355
+ agent.getExtractedData(sessionData.id) as QuickChatData
356
+ );
357
+ }
358
+
334
359
  console.log("💾 Session state cached in Redis!");
335
360
 
336
361
  await redis.quit();
@@ -343,12 +368,6 @@ async function highThroughputExample() {
343
368
  async function sessionRecoveryExample() {
344
369
  const redis = new Redis();
345
370
 
346
- interface OrderData {
347
- productId: string;
348
- quantity: number;
349
- shippingAddress: string;
350
- }
351
-
352
371
  const agent = new Agent({
353
372
  name: "Order Assistant",
354
373
  ai: new GeminiProvider({
@@ -383,7 +402,8 @@ async function sessionRecoveryExample() {
383
402
  .transitionTo({
384
403
  chatState: "Ask for shipping address",
385
404
  gather: ["shippingAddress"],
386
- });
405
+ })
406
+ .transitionTo({ state: END_STATE });
387
407
 
388
408
  const persistence = agent.getPersistenceManager()!;
389
409
 
@@ -446,11 +466,63 @@ async function sessionRecoveryExample() {
446
466
 
447
467
  console.log("🤖 Response:", response2.message);
448
468
  console.log("📊 Final extracted data:", response2.session?.extracted);
469
+
470
+ if (response2.isRouteComplete) {
471
+ console.log("\n✅ Order placement complete!");
472
+ await processOrder(
473
+ agent.getExtractedData(sessionId) as unknown as OrderData
474
+ );
475
+ }
476
+
449
477
  console.log("✅ Order complete with recovered session!");
450
478
 
451
479
  await redis.quit();
452
480
  }
453
481
 
482
+ /**
483
+ * Mock function to file a support ticket.
484
+ * @param data - The support ticket data.
485
+ */
486
+ async function fileSupportTicket(data: SupportTicketData) {
487
+ console.log("\n" + "=".repeat(60));
488
+ console.log("🎫 Filing Support Ticket...");
489
+ console.log("=".repeat(60));
490
+ console.log("Ticket Details:", JSON.stringify(data, null, 2));
491
+ console.log(
492
+ ` - Filing ticket for issue: ${data.issue} with priority: ${data.priority}`
493
+ );
494
+ await new Promise((resolve) => setTimeout(resolve, 1000));
495
+ console.log("✨ Ticket filed successfully!");
496
+ }
497
+
498
+ /**
499
+ * Mock function to log chat analytics.
500
+ * @param data - The chat data.
501
+ */
502
+ async function logChatAnalytics(data: QuickChatData) {
503
+ console.log("\n" + "=".repeat(60));
504
+ console.log("📊 Logging Chat Analytics...");
505
+ console.log("=".repeat(60));
506
+ console.log("Chat Details:", JSON.stringify(data, null, 2));
507
+ console.log(` - Logging chat with topic: ${data.topic}`);
508
+ await new Promise((resolve) => setTimeout(resolve, 500));
509
+ console.log("✨ Analytics logged!");
510
+ }
511
+
512
+ /**
513
+ * Mock function to process an order.
514
+ * @param data - The order data.
515
+ */
516
+ async function processOrder(data: OrderData) {
517
+ console.log("\n" + "=".repeat(60));
518
+ console.log("📦 Processing Order...");
519
+ console.log("=".repeat(60));
520
+ console.log("Order Details:", JSON.stringify(data, null, 2));
521
+ console.log(` - Processing order for product: ${data.productId}`);
522
+ await new Promise((resolve) => setTimeout(resolve, 1000));
523
+ console.log("✨ Order processed successfully!");
524
+ }
525
+
454
526
  // Run the example
455
527
  if (require.main === module) {
456
528
  example().catch(console.error);
@@ -8,26 +8,37 @@
8
8
 
9
9
  import {
10
10
  Agent,
11
- createMessageEvent,
11
+ type Event,
12
+ type MessageEventData,
13
+ EventKind,
12
14
  EventSource,
13
- createSession,
14
- } from "../src/index";
15
- import { AnthropicProvider } from "../src/providers";
15
+ END_STATE,
16
+ } from "../src";
17
+ import { OpenAIProvider } from "../src/providers/OpenAIProvider";
16
18
 
17
- // Initialize AI provider
18
- const ai = new AnthropicProvider({
19
- apiKey: process.env.ANTHROPIC_API_KEY || "your-api-key-here",
20
- model: "claude-sonnet-4-5",
19
+ /**
20
+ * Configuration for the AI provider
21
+ */
22
+ const ai = new OpenAIProvider({
23
+ apiKey: process.env.OPENAI_API_KEY || "your-api-key-here",
24
+ model: "gpt-5",
21
25
  });
22
26
 
23
- // Create WhatsApp support bot with different styles per route
27
+ /**
28
+ * Create a new agent instance with predefined routes and rules/prohibitions.
29
+ */
24
30
  const agent = new Agent({
25
- name: "SupportBot",
26
- description: "Customer support assistant for WhatsApp",
31
+ name: "CustomerServiceAgent",
32
+ description:
33
+ "A versatile customer service agent that adapts its behavior based on the conversation's context.",
34
+ goal: "Provide excellent customer service by following route-specific rules and prohibitions.",
27
35
  ai,
36
+ debug: true,
28
37
  });
29
38
 
30
- // Route 1: Quick Support - Short, direct messages
39
+ /**
40
+ * Add routes to the agent.
41
+ */
31
42
  agent.createRoute({
32
43
  title: "Quick Support",
33
44
  description: "Fast answers for common questions",
@@ -46,7 +57,6 @@ agent.createRoute({
46
57
  ],
47
58
  });
48
59
 
49
- // Route 2: Sales Consultation - Conversational, engaging
50
60
  agent.createRoute({
51
61
  title: "Sales Consultation",
52
62
  description: "Help customer discover needs and present solutions",
@@ -70,7 +80,6 @@ agent.createRoute({
70
80
  ],
71
81
  });
72
82
 
73
- // Route 3: Technical Support - Detailed, step-by-step
74
83
  agent.createRoute({
75
84
  title: "Technical Support",
76
85
  description: "Help with technical issues and troubleshooting",
@@ -90,7 +99,27 @@ agent.createRoute({
90
99
  ],
91
100
  });
92
101
 
93
- // Route 4: Emergency Support - Calm, reassuring, action-oriented
102
+ // Add a stateful feedback flow to the Technical Support route
103
+ const techSupportRoute = agent
104
+ .getRoutes()
105
+ .find((r) => r.title === "Technical Support")!;
106
+ techSupportRoute.initialState
107
+ .transitionTo({
108
+ chatState: "Provide step-by-step technical assistance.",
109
+ })
110
+ .transitionTo({
111
+ chatState: "Ask for a rating of the support provided (1-5).",
112
+ gather: ["feedbackRating"],
113
+ })
114
+ .transitionTo({
115
+ chatState: "Ask for any additional comments.",
116
+ gather: ["feedbackComments"],
117
+ })
118
+ .transitionTo({
119
+ chatState: "Thank the user for their feedback.",
120
+ })
121
+ .transitionTo({ state: END_STATE });
122
+
94
123
  agent.createRoute({
95
124
  title: "Emergency Support",
96
125
  description: "Handle urgent customer issues",
@@ -111,7 +140,6 @@ agent.createRoute({
111
140
  ],
112
141
  });
113
142
 
114
- // Route 5: General Chat - Friendly, casual, helpful
115
143
  agent.createRoute({
116
144
  title: "General Chat",
117
145
  description: "Casual conversation and general questions",
@@ -129,151 +157,284 @@ agent.createRoute({
129
157
  ],
130
158
  });
131
159
 
132
- // Demonstration function
160
+ /**
161
+ * Demonstration function to show how the agent responds to different scenarios.
162
+ */
133
163
  async function demonstrateRulesAndProhibitions() {
134
- console.log("\n=== Rules & Prohibitions Demo ===\n");
135
-
136
- // Example 1: Quick Support - Should be short and direct
137
- console.log("1️⃣ Quick Support Route (short, direct)");
138
- const history1 = [
139
- createMessageEvent(
140
- EventSource.CUSTOMER,
141
- "Alice",
142
- "What are your business hours?"
143
- ),
164
+ const agent = new Agent({
165
+ name: "CustomerServiceAgent",
166
+ description:
167
+ "A versatile customer service agent that adapts its behavior based on the conversation's context.",
168
+ goal: "Provide excellent customer service by following route-specific rules and prohibitions.",
169
+ ai,
170
+ debug: true,
171
+ });
172
+
173
+ // Add domains
174
+ agent.createRoute({
175
+ title: "Quick Support",
176
+ description: "Fast answers for common questions",
177
+ conditions: ["User has a simple question", "User wants quick help"],
178
+ rules: [
179
+ "Keep messages extremely short (1-2 lines maximum)",
180
+ "Use bullet points for lists",
181
+ "Maximum 1 emoji per message 👍",
182
+ "Be direct and to the point",
183
+ ],
184
+ prohibitions: [
185
+ "Never send long paragraphs",
186
+ "Do not over-explain",
187
+ "Never use more than 2 emojis",
188
+ "Do not ask follow-up questions unless necessary",
189
+ ],
190
+ });
191
+
192
+ agent.createRoute({
193
+ title: "Sales Consultation",
194
+ description: "Help customer discover needs and present solutions",
195
+ conditions: [
196
+ "User is interested in buying",
197
+ "User wants product information",
198
+ ],
199
+ rules: [
200
+ "Ask open-ended questions to discover needs",
201
+ "Use storytelling when presenting solutions",
202
+ "Emoji to reinforce positive emotions 😊✨",
203
+ "Present value before mentioning price",
204
+ "Make customer feel special and understood",
205
+ ],
206
+ prohibitions: [
207
+ "Never talk about price before showing value",
208
+ "Do not pressure or push",
209
+ "Avoid technical jargon",
210
+ "Never send more than 2 messages without waiting for response",
211
+ "Do not make promises you cannot keep",
212
+ ],
213
+ });
214
+
215
+ agent.createRoute({
216
+ title: "Technical Support",
217
+ description: "Help with technical issues and troubleshooting",
218
+ conditions: ["User has technical problem", "User needs step-by-step help"],
219
+ rules: [
220
+ "Provide clear, numbered steps",
221
+ "Use simple language for technical concepts",
222
+ "Confirm understanding after each major step",
223
+ "Offer screenshots or visual aids when helpful",
224
+ "Be patient and thorough",
225
+ ],
226
+ prohibitions: [
227
+ "Never skip steps or assume knowledge",
228
+ "Do not use excessive technical terms without explanation",
229
+ "Never blame the user for the issue",
230
+ "Do not rush through explanations",
231
+ ],
232
+ });
233
+
234
+ // Add a stateful feedback flow to the Technical Support route
235
+ const techSupportRoute = agent
236
+ .getRoutes()
237
+ .find((r) => r.title === "Technical Support")!;
238
+ techSupportRoute.initialState
239
+ .transitionTo({
240
+ chatState: "Provide step-by-step technical assistance.",
241
+ })
242
+ .transitionTo({
243
+ chatState: "Ask for a rating of the support provided (1-5).",
244
+ gather: ["feedbackRating"],
245
+ })
246
+ .transitionTo({
247
+ chatState: "Ask for any additional comments.",
248
+ gather: ["feedbackComments"],
249
+ })
250
+ .transitionTo({
251
+ chatState: "Thank the user for their feedback.",
252
+ })
253
+ .transitionTo({ state: END_STATE });
254
+
255
+ agent.createRoute({
256
+ title: "Emergency Support",
257
+ description: "Handle urgent customer issues",
258
+ conditions: ["Customer is frustrated", "Urgent issue", "Service down"],
259
+ rules: [
260
+ "Acknowledge the urgency immediately",
261
+ "Express empathy and understanding",
262
+ "Provide concrete next steps",
263
+ "Set clear expectations on resolution time",
264
+ "Keep customer updated",
265
+ ],
266
+ prohibitions: [
267
+ "Never downplay the customer's concern",
268
+ "Do not use emojis (keep it professional)",
269
+ 'Never say "calm down" or similar dismissive phrases',
270
+ "Do not transfer without explaining why",
271
+ "Never make excuses or blame others",
272
+ ],
273
+ });
274
+
275
+ agent.createRoute({
276
+ title: "General Chat",
277
+ description: "Casual conversation and general questions",
278
+ conditions: ["User is just chatting", "Greeting", "General question"],
279
+ rules: [
280
+ "Be friendly and conversational",
281
+ "Use emojis naturally 😊",
282
+ "Mirror the customer's tone and energy",
283
+ "Keep it light and positive",
284
+ ],
285
+ prohibitions: [
286
+ "Do not be overly formal",
287
+ "Never ignore the customer's mood",
288
+ "Do not push products unless asked",
289
+ ],
290
+ });
291
+
292
+ console.info("\n=== Rules & Prohibitions Demo ===\n");
293
+
294
+ // --- Quick Support ---
295
+ console.info("1️⃣ Quick Support Route (short, direct)");
296
+ const quickSupportHistory: Event[] = [
297
+ {
298
+ kind: EventKind.MESSAGE,
299
+ source: EventSource.CUSTOMER,
300
+ data: {
301
+ participant: { display_name: "User" },
302
+ message: "How do I reset my password?",
303
+ },
304
+ },
144
305
  ];
145
-
146
- // Initialize session state for multi-turn conversation
147
- let session = createSession();
148
-
149
- const response1 = await agent.respond({ history: history1, session });
150
- console.log(`Route: ${response1.session?.currentRoute?.title}`);
151
- console.log(`Response: ${response1.message}`);
152
- console.log(`Expected: Short, direct, max 1 emoji\n`);
153
-
154
- // Update session with progress
155
- session = response1.session!;
156
-
157
- // Example 2: Sales Consultation - Should be engaging and value-focused
158
- console.log("2️⃣ Sales Consultation Route (conversational, value-first)");
159
- const history2 = [
160
- createMessageEvent(
161
- EventSource.CUSTOMER,
162
- "Bob",
163
- "I'm interested in your premium plan"
164
- ),
306
+ const response1 = await agent.respond({ history: quickSupportHistory });
307
+ console.info(`Route: ${response1.session?.currentRoute?.title}`);
308
+ console.info(`Response: ${response1.message}`);
309
+ console.info(`Expected: Short, direct, max 1 emoji\n`);
310
+
311
+ // --- Sales Consultation ---
312
+ console.info("2️⃣ Sales Consultation Route (conversational, value-first)");
313
+ const salesHistory: Event[] = [
314
+ {
315
+ kind: EventKind.MESSAGE,
316
+ source: EventSource.CUSTOMER,
317
+ data: {
318
+ message: "How much does your premium plan cost?",
319
+ participant: { display_name: "User" },
320
+ },
321
+ },
165
322
  ];
166
-
167
- const response2 = await agent.respond({ history: history2, session });
168
- console.log(`Route: ${response2.session?.currentRoute?.title}`);
169
- console.log(`Response: ${response2.message}`);
170
- console.log(`Expected: Ask about needs, show value before price\n`);
171
-
172
- // Update session again
173
- session = response2.session!;
174
-
175
- // Example 3: Technical Support - Should be detailed and step-by-step
176
- console.log("3️⃣ Technical Support Route (detailed, step-by-step)");
177
- const history3 = [
178
- createMessageEvent(
179
- EventSource.CUSTOMER,
180
- "Charlie",
181
- "My app keeps crashing when I try to login"
182
- ),
323
+ const response2 = await agent.respond({ history: salesHistory });
324
+ console.info(`Route: ${response2.session?.currentRoute?.title}`);
325
+ console.info(`Response: ${response2.message}`);
326
+ console.info(`Expected: Ask about needs, show value before price\n`);
327
+
328
+ // --- Technical Support ---
329
+ console.info("3️⃣ Technical Support Route (detailed, step-by-step)");
330
+ const techSupportHistory: Event[] = [
331
+ {
332
+ kind: EventKind.MESSAGE,
333
+ source: EventSource.CUSTOMER,
334
+ data: {
335
+ message: "My new headphones won't connect to Bluetooth.",
336
+ participant: { display_name: "User" },
337
+ },
338
+ },
183
339
  ];
340
+ const response3 = await agent.respond({ history: techSupportHistory });
341
+ console.info(`Route: ${response3.session?.currentRoute?.title}`);
342
+ console.info(`Response: ${response3.message}`);
343
+ console.info(`Expected: Clear steps, simple language, patient\n`);
344
+ if (response3.isRouteComplete) {
345
+ console.info("\n✅ Technical support feedback collected!");
346
+ }
184
347
 
185
- const response3 = await agent.respond({ history: history3, session });
186
- console.log(`Route: ${response3.session?.currentRoute?.title}`);
187
- console.log(`Response: ${response3.message}`);
188
- console.log(`Expected: Clear steps, simple language, patient\n`);
189
-
190
- // Update session again
191
- session = response3.session!;
192
-
193
- // Example 4: Emergency Support - Should be calm and action-oriented
194
- console.log("4️⃣ Emergency Support Route (urgent, professional)");
195
- const history4 = [
196
- createMessageEvent(
197
- EventSource.CUSTOMER,
198
- "Diana",
199
- "This is urgent! My payment failed and I need access NOW!"
200
- ),
348
+ // --- Emergency Support ---
349
+ console.info("4️⃣ Emergency Support Route (urgent, professional)");
350
+ const emergencyHistory: Event[] = [
351
+ {
352
+ kind: EventKind.MESSAGE,
353
+ source: EventSource.CUSTOMER,
354
+ data: {
355
+ message: "My account has been compromised!",
356
+ participant: { display_name: "User" },
357
+ },
358
+ },
201
359
  ];
202
-
203
- const response4 = await agent.respond({ history: history4, session });
204
- console.log(`Route: ${response4.session?.currentRoute?.title}`);
205
- console.log(`Response: ${response4.message}`);
206
- console.log(`Expected: Acknowledge urgency, no emojis, concrete steps\n`);
207
-
208
- // Update session again
209
- session = response4.session!;
210
-
211
- // Example 5: General Chat - Should be friendly and casual
212
- console.log("5️⃣ General Chat Route (friendly, casual)");
213
- const history5 = [
214
- createMessageEvent(EventSource.CUSTOMER, "Eve", "Hey! How's it going?"),
360
+ const response4 = await agent.respond({ history: emergencyHistory });
361
+ console.info(`Route: ${response4.session?.currentRoute?.title}`);
362
+ console.info(`Response: ${response4.message}`);
363
+ console.info(`Expected: Acknowledge urgency, no emojis, concrete steps\n`);
364
+
365
+ // --- General Chat ---
366
+ console.info("5️⃣ General Chat Route (friendly, casual)");
367
+ const generalHistory: Event[] = [
368
+ {
369
+ kind: EventKind.MESSAGE,
370
+ source: EventSource.CUSTOMER,
371
+ data: {
372
+ message: "What's the weather like today?",
373
+ participant: { display_name: "User" },
374
+ },
375
+ } as Event<MessageEventData>,
215
376
  ];
216
-
217
- const response5 = await agent.respond({ history: history5, session });
218
- console.log(`Route: ${response5.session?.currentRoute?.title}`);
219
- console.log(`Response: ${response5.message}`);
220
- console.log(`Expected: Friendly, emojis, mirrors customer tone\n`);
377
+ const response5 = await agent.respond({ history: generalHistory });
378
+ console.info(`Route: ${response5.session?.currentRoute?.title}`);
379
+ console.info(`Response: ${response5.message}`);
380
+ console.info(`Expected: Friendly, emojis, mirrors customer tone\n`);
221
381
  }
222
382
 
223
- // Inspect route configurations
224
- console.log("\n📋 Route Configurations:\n");
225
- for (const route of agent.getRoutes()) {
226
- console.log(`\n🛤️ ${route.title}`);
227
-
383
+ /**
384
+ * Inspect route configurations.
385
+ */
386
+ console.info("\n📋 Route Configurations:\n");
387
+ agent.getRoutes().forEach((route) => {
388
+ console.info(`\n🛤️ ${route.title}`);
228
389
  const rules = route.getRules();
390
+ const prohibitions = route.getProhibitions();
391
+
229
392
  if (rules.length > 0) {
230
- console.log(` ✅ Rules (${rules.length}):`);
231
- rules.forEach((rule, i) => console.log(` ${i + 1}. ${rule}`));
393
+ console.info(` ✅ Rules (${rules.length}):`);
394
+ rules.forEach((rule, i) => console.info(` ${i + 1}. ${rule}`));
232
395
  }
233
396
 
234
- const prohibitions = route.getProhibitions();
235
397
  if (prohibitions.length > 0) {
236
- console.log(` ❌ Prohibitions (${prohibitions.length}):`);
398
+ console.info(` ❌ Prohibitions (${prohibitions.length}):`);
237
399
  prohibitions.forEach((prohibition, i) =>
238
- console.log(` ${i + 1}. ${prohibition}`)
400
+ console.info(` ${i + 1}. ${prohibition}`)
239
401
  );
240
402
  }
241
- }
242
-
243
- // Benefits explanation
244
- console.log(`
245
- \n💡 Benefits of Rules & Prohibitions:
246
-
247
- 1️⃣ **Context-Specific Behavior**
248
- - Each route can have completely different communication styles
249
- - WhatsApp support: short messages
250
- - Sales: engaging, story-driven
251
- - Technical: detailed, step-by-step
252
-
253
- 2️⃣ **Brand Consistency**
254
- - Rules ensure the agent always follows brand guidelines
255
- - Prohibitions prevent off-brand behavior
256
- - Different routes for different contexts
257
-
258
- 3️⃣ **User Experience**
259
- - Emergency route: professional, no emojis
260
- - General chat: friendly, casual
261
- - Technical support: patient, thorough
262
-
263
- 4️⃣ **Automatic Enforcement**
264
- - Rules are applied in the AI prompt automatically
265
- - No manual checking needed
266
- - Consistent behavior across all conversations
403
+ });
267
404
 
268
- 5️⃣ **Easy to Update**
269
- - Change rules without changing code
270
- - A/B test different communication styles
271
- - Iterate based on customer feedback
405
+ /**
406
+ * Benefits explanation.
407
+ */
408
+ console.info(`
409
+ 💡 This demo shows how rules and prohibitions, combined with routing,
410
+ allow a single agent to handle diverse scenarios with tailored,
411
+ context-appropriate behavior.
272
412
  `);
273
413
 
414
+ /**
415
+ * Mock function to log support feedback.
416
+ * @param data - The feedback data.
417
+ */
418
+ async function logSupportFeedback(
419
+ _context: undefined,
420
+ _history: Event[],
421
+ _session: undefined,
422
+ data: { feedbackRating: number; feedbackComments: string }
423
+ ) {
424
+ console.info("\n" + "=".repeat(60));
425
+ console.info("📝 Logging Support Feedback...");
426
+ console.info("=".repeat(60));
427
+ console.info("Feedback Details:", JSON.stringify(data, null, 2));
428
+ console.info(` - Rating: ${data.feedbackRating}`);
429
+ console.info(` - Comments: ${data.feedbackComments}`);
430
+ await new Promise((resolve) => setTimeout(resolve, 500));
431
+ console.info("✨ Feedback logged successfully!");
432
+ return { success: true };
433
+ }
434
+
274
435
  // Run demonstration
275
436
  if (import.meta.url === `file://${process.argv[1]}`) {
276
- demonstrateRulesAndProhibitions().catch(console.error);
437
+ demonstrateRulesAndProhibitions().catch((err) => console.error(err));
277
438
  }
278
439
 
279
440
  export { agent };