@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.
- package/README.md +89 -29
- package/dist/cjs/constants/index.d.ts +6 -1
- package/dist/cjs/constants/index.d.ts.map +1 -1
- package/dist/cjs/constants/index.js +8 -3
- package/dist/cjs/constants/index.js.map +1 -1
- package/dist/cjs/core/Agent.d.ts +22 -0
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +113 -26
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/Events.d.ts +13 -0
- package/dist/cjs/core/Events.d.ts.map +1 -1
- package/dist/cjs/core/Events.js +28 -14
- package/dist/cjs/core/Events.js.map +1 -1
- package/dist/cjs/core/ResponseEngine.d.ts +1 -1
- package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
- package/dist/cjs/core/ResponseEngine.js +4 -1
- package/dist/cjs/core/ResponseEngine.js.map +1 -1
- package/dist/cjs/core/Route.d.ts.map +1 -1
- package/dist/cjs/core/Route.js +4 -4
- package/dist/cjs/core/Route.js.map +1 -1
- package/dist/cjs/core/RoutingEngine.d.ts +6 -1
- package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
- package/dist/cjs/core/RoutingEngine.js +116 -41
- package/dist/cjs/core/RoutingEngine.js.map +1 -1
- package/dist/cjs/core/State.d.ts +18 -6
- package/dist/cjs/core/State.d.ts.map +1 -1
- package/dist/cjs/core/State.js +30 -7
- package/dist/cjs/core/State.js.map +1 -1
- package/dist/cjs/core/Tool.d.ts +8 -1
- package/dist/cjs/core/Tool.d.ts.map +1 -1
- package/dist/cjs/core/Tool.js +25 -28
- package/dist/cjs/core/Tool.js.map +1 -1
- package/dist/cjs/core/Transition.js +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +3 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +5 -0
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/agent.js.map +1 -1
- package/dist/cjs/types/route.d.ts +7 -1
- package/dist/cjs/types/route.d.ts.map +1 -1
- package/dist/cjs/types/session.d.ts +13 -2
- package/dist/cjs/types/session.d.ts.map +1 -1
- package/dist/cjs/types/session.js +28 -5
- package/dist/cjs/types/session.js.map +1 -1
- package/dist/cjs/utils/logger.d.ts +10 -0
- package/dist/cjs/utils/logger.d.ts.map +1 -0
- package/dist/cjs/utils/logger.js +23 -0
- package/dist/cjs/utils/logger.js.map +1 -0
- package/dist/constants/index.d.ts +6 -1
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +6 -1
- package/dist/constants/index.js.map +1 -1
- package/dist/core/Agent.d.ts +22 -0
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +113 -26
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/Events.d.ts +13 -0
- package/dist/core/Events.d.ts.map +1 -1
- package/dist/core/Events.js +28 -14
- package/dist/core/Events.js.map +1 -1
- package/dist/core/ResponseEngine.d.ts +1 -1
- package/dist/core/ResponseEngine.d.ts.map +1 -1
- package/dist/core/ResponseEngine.js +4 -1
- package/dist/core/ResponseEngine.js.map +1 -1
- package/dist/core/Route.d.ts.map +1 -1
- package/dist/core/Route.js +4 -4
- package/dist/core/Route.js.map +1 -1
- package/dist/core/RoutingEngine.d.ts +6 -1
- package/dist/core/RoutingEngine.d.ts.map +1 -1
- package/dist/core/RoutingEngine.js +116 -41
- package/dist/core/RoutingEngine.js.map +1 -1
- package/dist/core/State.d.ts +18 -6
- package/dist/core/State.d.ts.map +1 -1
- package/dist/core/State.js +31 -8
- package/dist/core/State.js.map +1 -1
- package/dist/core/Tool.d.ts +8 -1
- package/dist/core/Tool.d.ts.map +1 -1
- package/dist/core/Tool.js +25 -28
- package/dist/core/Tool.js.map +1 -1
- package/dist/core/Transition.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/agent.d.ts +5 -0
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/agent.js.map +1 -1
- package/dist/types/route.d.ts +7 -1
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/session.d.ts +13 -2
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js +28 -5
- package/dist/types/session.js.map +1 -1
- package/dist/utils/logger.d.ts +10 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +17 -0
- package/dist/utils/logger.js.map +1 -0
- package/docs/{CONSTRUCTOR_OPTIONS.md → AGENT.md} +79 -7
- package/docs/API_REFERENCE.md +309 -18
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/DOCS.md +46 -22
- package/docs/GETTING_STARTED.md +1 -1
- package/docs/README.md +13 -5
- package/docs/ROUTES.md +743 -0
- package/docs/STATES.md +798 -0
- package/examples/business-onboarding.ts +46 -5
- package/examples/company-qna-agent.ts +107 -1
- package/examples/custom-database-persistence.ts +44 -1
- package/examples/declarative-agent.ts +80 -37
- package/examples/domain-scoping.ts +91 -21
- package/examples/extracted-data-modification.ts +64 -2
- package/examples/healthcare-agent.ts +61 -4
- package/examples/openai-agent.ts +24 -2
- package/examples/opensearch-persistence.ts +26 -1
- package/examples/persistent-onboarding.ts +84 -18
- package/examples/prisma-persistence.ts +90 -16
- package/examples/redis-persistence.ts +89 -17
- package/examples/rules-prohibitions.ts +300 -139
- package/examples/streaming-agent.ts +60 -0
- package/examples/travel-agent.ts +66 -24
- package/package.json +3 -2
- package/src/constants/index.ts +6 -1
- package/src/core/Agent.ts +140 -24
- package/src/core/Events.ts +73 -10
- package/src/core/ResponseEngine.ts +6 -0
- package/src/core/Route.ts +8 -4
- package/src/core/RoutingEngine.ts +154 -43
- package/src/core/State.ts +45 -12
- package/src/core/Tool.ts +67 -10
- package/src/core/Transition.ts +1 -1
- package/src/index.ts +1 -1
- package/src/types/agent.ts +5 -0
- package/src/types/route.ts +10 -1
- package/src/types/session.ts +47 -7
- 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
|
|
307
|
-
|
|
308
|
-
|
|
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
|
-
|
|
11
|
+
type Event,
|
|
12
|
+
type MessageEventData,
|
|
13
|
+
EventKind,
|
|
12
14
|
EventSource,
|
|
13
|
-
|
|
14
|
-
} from "../src
|
|
15
|
-
import {
|
|
15
|
+
END_STATE,
|
|
16
|
+
} from "../src";
|
|
17
|
+
import { OpenAIProvider } from "../src/providers/OpenAIProvider";
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Create a new agent instance with predefined routes and rules/prohibitions.
|
|
29
|
+
*/
|
|
24
30
|
const agent = new Agent({
|
|
25
|
-
name: "
|
|
26
|
-
description:
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
160
|
+
/**
|
|
161
|
+
* Demonstration function to show how the agent responds to different scenarios.
|
|
162
|
+
*/
|
|
133
163
|
async function demonstrateRulesAndProhibitions() {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
console.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
-
|
|
168
|
-
console.
|
|
169
|
-
console.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
186
|
-
console.
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
-
|
|
204
|
-
console.
|
|
205
|
-
console.
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
218
|
-
console.
|
|
219
|
-
console.
|
|
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
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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.
|
|
231
|
-
rules.forEach((rule, i) => console.
|
|
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.
|
|
398
|
+
console.info(` ❌ Prohibitions (${prohibitions.length}):`);
|
|
237
399
|
prohibitions.forEach((prohibition, i) =>
|
|
238
|
-
console.
|
|
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
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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 };
|