@falai/agent 0.4.0 → 0.5.0

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 (285) hide show
  1. package/README.md +21 -74
  2. package/dist/cjs/core/Agent.d.ts +22 -29
  3. package/dist/cjs/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/core/Agent.js +465 -275
  5. package/dist/cjs/core/Agent.js.map +1 -1
  6. package/dist/cjs/core/Events.d.ts +10 -1
  7. package/dist/cjs/core/Events.d.ts.map +1 -1
  8. package/dist/cjs/core/Events.js +3 -2
  9. package/dist/cjs/core/Events.js.map +1 -1
  10. package/dist/cjs/core/PersistenceManager.d.ts +19 -0
  11. package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
  12. package/dist/cjs/core/PersistenceManager.js +57 -0
  13. package/dist/cjs/core/PersistenceManager.js.map +1 -1
  14. package/dist/cjs/core/PromptComposer.d.ts +24 -0
  15. package/dist/cjs/core/PromptComposer.d.ts.map +1 -0
  16. package/dist/cjs/core/PromptComposer.js +127 -0
  17. package/dist/cjs/core/PromptComposer.js.map +1 -0
  18. package/dist/cjs/core/ResponseEngine.d.ts +19 -0
  19. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -0
  20. package/dist/cjs/core/ResponseEngine.js +51 -0
  21. package/dist/cjs/core/ResponseEngine.js.map +1 -0
  22. package/dist/cjs/core/Route.d.ts +18 -12
  23. package/dist/cjs/core/Route.d.ts.map +1 -1
  24. package/dist/cjs/core/Route.js +15 -9
  25. package/dist/cjs/core/Route.js.map +1 -1
  26. package/dist/cjs/core/RoutingEngine.d.ts +38 -0
  27. package/dist/cjs/core/RoutingEngine.d.ts.map +1 -0
  28. package/dist/cjs/core/RoutingEngine.js +110 -0
  29. package/dist/cjs/core/RoutingEngine.js.map +1 -0
  30. package/dist/cjs/core/State.d.ts +15 -4
  31. package/dist/cjs/core/State.d.ts.map +1 -1
  32. package/dist/cjs/core/State.js +21 -2
  33. package/dist/cjs/core/State.js.map +1 -1
  34. package/dist/cjs/core/ToolExecutor.d.ts +29 -0
  35. package/dist/cjs/core/ToolExecutor.d.ts.map +1 -0
  36. package/dist/cjs/core/ToolExecutor.js +73 -0
  37. package/dist/cjs/core/ToolExecutor.js.map +1 -0
  38. package/dist/cjs/core/Transition.d.ts +5 -5
  39. package/dist/cjs/core/Transition.d.ts.map +1 -1
  40. package/dist/cjs/core/Transition.js.map +1 -1
  41. package/dist/cjs/index.d.ts +6 -8
  42. package/dist/cjs/index.d.ts.map +1 -1
  43. package/dist/cjs/index.js +8 -10
  44. package/dist/cjs/index.js.map +1 -1
  45. package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
  46. package/dist/cjs/providers/AnthropicProvider.js +10 -13
  47. package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
  48. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  49. package/dist/cjs/providers/GeminiProvider.js +12 -8
  50. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  51. package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
  52. package/dist/cjs/providers/OpenAIProvider.js +10 -53
  53. package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
  54. package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
  55. package/dist/cjs/providers/OpenRouterProvider.js +10 -53
  56. package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
  57. package/dist/cjs/types/agent.d.ts +13 -9
  58. package/dist/cjs/types/agent.d.ts.map +1 -1
  59. package/dist/cjs/types/ai.d.ts +8 -2
  60. package/dist/cjs/types/ai.d.ts.map +1 -1
  61. package/dist/cjs/types/history.d.ts +8 -0
  62. package/dist/cjs/types/history.d.ts.map +1 -1
  63. package/dist/cjs/types/index.d.ts +0 -3
  64. package/dist/cjs/types/index.d.ts.map +1 -1
  65. package/dist/cjs/types/index.js +1 -3
  66. package/dist/cjs/types/index.js.map +1 -1
  67. package/dist/cjs/types/route.d.ts +39 -4
  68. package/dist/cjs/types/route.d.ts.map +1 -1
  69. package/dist/cjs/types/routing.d.ts +16 -0
  70. package/dist/cjs/types/routing.d.ts.map +1 -0
  71. package/dist/cjs/types/routing.js +3 -0
  72. package/dist/cjs/types/routing.js.map +1 -0
  73. package/dist/cjs/types/schema.d.ts +22 -0
  74. package/dist/cjs/types/schema.d.ts.map +1 -0
  75. package/dist/cjs/types/schema.js +3 -0
  76. package/dist/cjs/types/schema.js.map +1 -0
  77. package/dist/cjs/types/session.d.ts +72 -0
  78. package/dist/cjs/types/session.d.ts.map +1 -0
  79. package/dist/cjs/types/session.js +140 -0
  80. package/dist/cjs/types/session.js.map +1 -0
  81. package/dist/cjs/types/tool.d.ts +11 -5
  82. package/dist/cjs/types/tool.d.ts.map +1 -1
  83. package/dist/cjs/utils/id.d.ts +0 -5
  84. package/dist/cjs/utils/id.d.ts.map +1 -1
  85. package/dist/cjs/utils/id.js +0 -10
  86. package/dist/cjs/utils/id.js.map +1 -1
  87. package/dist/cjs/utils/schema.d.ts +17 -0
  88. package/dist/cjs/utils/schema.d.ts.map +1 -0
  89. package/dist/cjs/utils/schema.js +32 -0
  90. package/dist/cjs/utils/schema.js.map +1 -0
  91. package/dist/core/Agent.d.ts +22 -29
  92. package/dist/core/Agent.d.ts.map +1 -1
  93. package/dist/core/Agent.js +465 -275
  94. package/dist/core/Agent.js.map +1 -1
  95. package/dist/core/Events.d.ts +10 -1
  96. package/dist/core/Events.d.ts.map +1 -1
  97. package/dist/core/Events.js +3 -2
  98. package/dist/core/Events.js.map +1 -1
  99. package/dist/core/PersistenceManager.d.ts +19 -0
  100. package/dist/core/PersistenceManager.d.ts.map +1 -1
  101. package/dist/core/PersistenceManager.js +57 -0
  102. package/dist/core/PersistenceManager.js.map +1 -1
  103. package/dist/core/PromptComposer.d.ts +24 -0
  104. package/dist/core/PromptComposer.d.ts.map +1 -0
  105. package/dist/core/PromptComposer.js +123 -0
  106. package/dist/core/PromptComposer.js.map +1 -0
  107. package/dist/core/ResponseEngine.d.ts +19 -0
  108. package/dist/core/ResponseEngine.d.ts.map +1 -0
  109. package/dist/core/ResponseEngine.js +47 -0
  110. package/dist/core/ResponseEngine.js.map +1 -0
  111. package/dist/core/Route.d.ts +18 -12
  112. package/dist/core/Route.d.ts.map +1 -1
  113. package/dist/core/Route.js +15 -9
  114. package/dist/core/Route.js.map +1 -1
  115. package/dist/core/RoutingEngine.d.ts +38 -0
  116. package/dist/core/RoutingEngine.d.ts.map +1 -0
  117. package/dist/core/RoutingEngine.js +106 -0
  118. package/dist/core/RoutingEngine.js.map +1 -0
  119. package/dist/core/State.d.ts +15 -4
  120. package/dist/core/State.d.ts.map +1 -1
  121. package/dist/core/State.js +21 -2
  122. package/dist/core/State.js.map +1 -1
  123. package/dist/core/ToolExecutor.d.ts +29 -0
  124. package/dist/core/ToolExecutor.d.ts.map +1 -0
  125. package/dist/core/ToolExecutor.js +69 -0
  126. package/dist/core/ToolExecutor.js.map +1 -0
  127. package/dist/core/Transition.d.ts +5 -5
  128. package/dist/core/Transition.d.ts.map +1 -1
  129. package/dist/core/Transition.js.map +1 -1
  130. package/dist/index.d.ts +6 -8
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +3 -5
  133. package/dist/index.js.map +1 -1
  134. package/dist/providers/AnthropicProvider.d.ts.map +1 -1
  135. package/dist/providers/AnthropicProvider.js +10 -13
  136. package/dist/providers/AnthropicProvider.js.map +1 -1
  137. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  138. package/dist/providers/GeminiProvider.js +12 -8
  139. package/dist/providers/GeminiProvider.js.map +1 -1
  140. package/dist/providers/OpenAIProvider.d.ts.map +1 -1
  141. package/dist/providers/OpenAIProvider.js +10 -53
  142. package/dist/providers/OpenAIProvider.js.map +1 -1
  143. package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
  144. package/dist/providers/OpenRouterProvider.js +10 -53
  145. package/dist/providers/OpenRouterProvider.js.map +1 -1
  146. package/dist/types/agent.d.ts +13 -9
  147. package/dist/types/agent.d.ts.map +1 -1
  148. package/dist/types/ai.d.ts +8 -2
  149. package/dist/types/ai.d.ts.map +1 -1
  150. package/dist/types/history.d.ts +8 -0
  151. package/dist/types/history.d.ts.map +1 -1
  152. package/dist/types/index.d.ts +0 -3
  153. package/dist/types/index.d.ts.map +1 -1
  154. package/dist/types/index.js +0 -1
  155. package/dist/types/index.js.map +1 -1
  156. package/dist/types/route.d.ts +39 -4
  157. package/dist/types/route.d.ts.map +1 -1
  158. package/dist/types/routing.d.ts +16 -0
  159. package/dist/types/routing.d.ts.map +1 -0
  160. package/dist/types/routing.js +2 -0
  161. package/dist/types/routing.js.map +1 -0
  162. package/dist/types/schema.d.ts +22 -0
  163. package/dist/types/schema.d.ts.map +1 -0
  164. package/dist/types/schema.js +2 -0
  165. package/dist/types/schema.js.map +1 -0
  166. package/dist/types/session.d.ts +72 -0
  167. package/dist/types/session.d.ts.map +1 -0
  168. package/dist/types/session.js +132 -0
  169. package/dist/types/session.js.map +1 -0
  170. package/dist/types/tool.d.ts +11 -5
  171. package/dist/types/tool.d.ts.map +1 -1
  172. package/dist/utils/id.d.ts +0 -5
  173. package/dist/utils/id.d.ts.map +1 -1
  174. package/dist/utils/id.js +0 -9
  175. package/dist/utils/id.js.map +1 -1
  176. package/dist/utils/schema.d.ts +17 -0
  177. package/dist/utils/schema.d.ts.map +1 -0
  178. package/dist/utils/schema.js +27 -0
  179. package/dist/utils/schema.js.map +1 -0
  180. package/docs/ADAPTERS.md +83 -3
  181. package/docs/API_REFERENCE.md +95 -104
  182. package/docs/ARCHITECTURE.md +284 -286
  183. package/docs/CONSTRUCTOR_OPTIONS.md +192 -135
  184. package/docs/CONTEXT_MANAGEMENT.md +311 -28
  185. package/docs/CONTRIBUTING.md +1 -1
  186. package/docs/DOMAINS.md +61 -0
  187. package/docs/GETTING_STARTED.md +177 -88
  188. package/docs/PERSISTENCE.md +170 -23
  189. package/docs/README.md +7 -10
  190. package/examples/business-onboarding.ts +21 -9
  191. package/examples/company-qna-agent.ts +508 -0
  192. package/examples/declarative-agent.ts +143 -26
  193. package/examples/domain-scoping.ts +31 -10
  194. package/examples/extracted-data-modification.ts +415 -0
  195. package/examples/healthcare-agent.ts +194 -90
  196. package/examples/openai-agent.ts +67 -25
  197. package/examples/opensearch-persistence.ts +455 -151
  198. package/examples/persistent-onboarding.ts +162 -96
  199. package/examples/prisma-persistence.ts +371 -125
  200. package/examples/redis-persistence.ts +393 -23
  201. package/examples/rules-prohibitions.ts +32 -11
  202. package/examples/streaming-agent.ts +61 -13
  203. package/examples/travel-agent.ts +266 -133
  204. package/package.json +1 -1
  205. package/src/core/Agent.ts +679 -332
  206. package/src/core/Events.ts +12 -2
  207. package/src/core/PersistenceManager.ts +83 -0
  208. package/src/core/PromptComposer.ts +143 -0
  209. package/src/core/ResponseEngine.ts +82 -0
  210. package/src/core/Route.ts +32 -17
  211. package/src/core/RoutingEngine.ts +165 -0
  212. package/src/core/State.ts +55 -15
  213. package/src/core/ToolExecutor.ts +117 -0
  214. package/src/core/Transition.ts +5 -5
  215. package/src/index.ts +12 -21
  216. package/src/providers/AnthropicProvider.ts +10 -13
  217. package/src/providers/GeminiProvider.ts +12 -8
  218. package/src/providers/OpenAIProvider.ts +10 -56
  219. package/src/providers/OpenRouterProvider.ts +10 -56
  220. package/src/types/agent.ts +16 -10
  221. package/src/types/ai.ts +6 -2
  222. package/src/types/history.ts +8 -0
  223. package/src/types/index.ts +0 -11
  224. package/src/types/route.ts +41 -5
  225. package/src/types/routing.ts +18 -0
  226. package/src/types/schema.ts +23 -0
  227. package/src/types/session.ts +207 -0
  228. package/src/types/tool.ts +29 -7
  229. package/src/utils/id.ts +0 -10
  230. package/src/utils/schema.ts +32 -0
  231. package/dist/cjs/core/ConditionEvaluator.d.ts +0 -72
  232. package/dist/cjs/core/ConditionEvaluator.d.ts.map +0 -1
  233. package/dist/cjs/core/ConditionEvaluator.js +0 -272
  234. package/dist/cjs/core/ConditionEvaluator.js.map +0 -1
  235. package/dist/cjs/core/Observation.d.ts +0 -24
  236. package/dist/cjs/core/Observation.d.ts.map +0 -1
  237. package/dist/cjs/core/Observation.js +0 -39
  238. package/dist/cjs/core/Observation.js.map +0 -1
  239. package/dist/cjs/core/PreparationEngine.d.ts +0 -105
  240. package/dist/cjs/core/PreparationEngine.d.ts.map +0 -1
  241. package/dist/cjs/core/PreparationEngine.js +0 -320
  242. package/dist/cjs/core/PreparationEngine.js.map +0 -1
  243. package/dist/cjs/core/PromptBuilder.d.ts +0 -136
  244. package/dist/cjs/core/PromptBuilder.d.ts.map +0 -1
  245. package/dist/cjs/core/PromptBuilder.js +0 -421
  246. package/dist/cjs/core/PromptBuilder.js.map +0 -1
  247. package/dist/cjs/types/observation.d.ts +0 -27
  248. package/dist/cjs/types/observation.d.ts.map +0 -1
  249. package/dist/cjs/types/observation.js +0 -6
  250. package/dist/cjs/types/observation.js.map +0 -1
  251. package/dist/cjs/types/prompt.d.ts +0 -46
  252. package/dist/cjs/types/prompt.d.ts.map +0 -1
  253. package/dist/cjs/types/prompt.js +0 -19
  254. package/dist/cjs/types/prompt.js.map +0 -1
  255. package/dist/core/ConditionEvaluator.d.ts +0 -72
  256. package/dist/core/ConditionEvaluator.d.ts.map +0 -1
  257. package/dist/core/ConditionEvaluator.js +0 -268
  258. package/dist/core/ConditionEvaluator.js.map +0 -1
  259. package/dist/core/Observation.d.ts +0 -24
  260. package/dist/core/Observation.d.ts.map +0 -1
  261. package/dist/core/Observation.js +0 -35
  262. package/dist/core/Observation.js.map +0 -1
  263. package/dist/core/PreparationEngine.d.ts +0 -105
  264. package/dist/core/PreparationEngine.d.ts.map +0 -1
  265. package/dist/core/PreparationEngine.js +0 -316
  266. package/dist/core/PreparationEngine.js.map +0 -1
  267. package/dist/core/PromptBuilder.d.ts +0 -136
  268. package/dist/core/PromptBuilder.d.ts.map +0 -1
  269. package/dist/core/PromptBuilder.js +0 -417
  270. package/dist/core/PromptBuilder.js.map +0 -1
  271. package/dist/types/observation.d.ts +0 -27
  272. package/dist/types/observation.d.ts.map +0 -1
  273. package/dist/types/observation.js +0 -5
  274. package/dist/types/observation.js.map +0 -1
  275. package/dist/types/prompt.d.ts +0 -46
  276. package/dist/types/prompt.d.ts.map +0 -1
  277. package/dist/types/prompt.js +0 -16
  278. package/dist/types/prompt.js.map +0 -1
  279. package/docs/STRUCTURE.md +0 -58
  280. package/src/core/ConditionEvaluator.ts +0 -381
  281. package/src/core/Observation.ts +0 -47
  282. package/src/core/PreparationEngine.ts +0 -500
  283. package/src/core/PromptBuilder.ts +0 -617
  284. package/src/types/observation.ts +0 -29
  285. package/src/types/prompt.ts +0 -49
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Business Onboarding Example
3
+ * Updated for v2 architecture with session state management and schema-first data extraction
3
4
  *
4
5
  * Real-world example showing:
5
- * - Complex multi-step onboarding flow
6
- * - Tools with contextUpdate for automatic state management
7
- * - Lifecycle hooks for persistence
8
- * - Branching logic (physical vs online business)
9
- * - Both step-by-step and chained transition approaches
10
- * - Agent caching with lifecycle hooks
6
+ * - Complex multi-step onboarding flow with schema-based data extraction
7
+ * - Tools with enhanced context access for automatic state management
8
+ * - Lifecycle hooks for data validation and persistence
9
+ * - Branching logic (physical vs online business) with skipIf conditions
10
+ * - Code-based state progression instead of fuzzy conditions
11
11
  */
12
12
 
13
13
  import {
@@ -17,6 +17,7 @@ import {
17
17
  EventSource,
18
18
  createMessageEvent,
19
19
  OpenAIProvider,
20
+ createSession,
20
21
  type ToolContext,
21
22
  } from "../src/index";
22
23
 
@@ -690,10 +691,21 @@ async function main() {
690
691
 
691
692
  // Generate response (requires valid API key)
692
693
  try {
693
- const response = await agent.respond({ history });
694
+ // Initialize session state for multi-turn conversation
695
+ let session = createSession<OnboardingData>();
696
+
697
+ const response = await agent.respond({ history, session });
694
698
  console.log("Agent:", response.message);
695
- console.log("\nRoute:", response.route?.title);
696
- console.log("State:", response.state?.description);
699
+ console.log("\nRoute:", response.session?.currentRoute?.title);
700
+ console.log("Extracted:", response.session?.extracted);
701
+
702
+ // Update session with progress
703
+ session = response.session!;
704
+
705
+ console.log("\n✅ Session state benefits:");
706
+ console.log(" - Data extraction tracked across turns");
707
+ console.log(" - State progression managed automatically");
708
+ console.log(" - Always-on routing respects intent changes");
697
709
  } catch (error: any) {
698
710
  console.log("\n(Skipping AI response - requires valid API key)");
699
711
  console.log("Error:", error.message);
@@ -0,0 +1,508 @@
1
+ /**
2
+ * Example: Company Q&A Agent (Stateless, Knowledge-Based)
3
+ *
4
+ * This demonstrates:
5
+ * 1. Schema-first architecture for stateless Q&A routes (no gatherSchema)
6
+ * 2. Tools for context enrichment (not data extraction)
7
+ * 3. Session state management even for stateless conversations
8
+ * 4. Always-on routing with context awareness
9
+ * 5. Three-phase pipeline: PREPARATION → ROUTING → RESPONSE
10
+ */
11
+
12
+ import {
13
+ Agent,
14
+ createSession,
15
+ EventSource,
16
+ createMessageEvent,
17
+ EventKind,
18
+ } from "../src";
19
+ import type { Event } from "../src/types";
20
+ import type { ToolRef } from "../src/types/tool";
21
+
22
+ // ==============================================================================
23
+ // CONTEXT: Company Knowledge Base
24
+ // ==============================================================================
25
+
26
+ interface CompanyContext {
27
+ companyInfo: {
28
+ name: string;
29
+ founded: number;
30
+ employees: number;
31
+ headquarters: string;
32
+ };
33
+ products: Array<{
34
+ id: string;
35
+ name: string;
36
+ description: string;
37
+ price: string;
38
+ category: string;
39
+ }>;
40
+ policies: {
41
+ returnPolicy: string;
42
+ shippingPolicy: string;
43
+ warrantyPolicy: string;
44
+ };
45
+ faqs: Array<{
46
+ question: string;
47
+ answer: string;
48
+ category: string;
49
+ }>;
50
+ recentNews?: Array<{
51
+ title: string;
52
+ date: string;
53
+ summary: string;
54
+ }>;
55
+ }
56
+
57
+ // ==============================================================================
58
+ // TOOLS: Context Enrichment (PREPARATION Phase)
59
+ // ==============================================================================
60
+
61
+ // Tool: Fetch latest company news (context enrichment)
62
+ const fetchNewsTool: ToolRef<CompanyContext, [], void> = {
63
+ id: "fetch_news",
64
+ name: "Fetch Company News",
65
+ description: "Retrieve latest company news and updates",
66
+ handler: async (context) => {
67
+ // Simulate API call to news service
68
+ const news = [
69
+ {
70
+ title: "New Product Launch: Acme Widget Pro",
71
+ date: "2025-10-10",
72
+ summary: "We're excited to announce the Acme Widget Pro...",
73
+ },
74
+ {
75
+ title: "Company Expands to European Market",
76
+ date: "2025-10-01",
77
+ summary: "Acme Corp opens new offices in London and Berlin...",
78
+ },
79
+ ];
80
+
81
+ console.log(`[Tool] Fetched ${news.length} news articles`);
82
+
83
+ return {
84
+ data: undefined,
85
+ contextUpdate: {
86
+ recentNews: news,
87
+ },
88
+ };
89
+ },
90
+ };
91
+
92
+ // Tool: Search knowledge base (context enrichment)
93
+ const searchKnowledgeTool: ToolRef<CompanyContext, [], string> = {
94
+ id: "search_knowledge",
95
+ name: "Search Knowledge Base",
96
+ description: "Search FAQs and documentation",
97
+ handler: async (context) => {
98
+ const { history } = context;
99
+
100
+ // Get last user message
101
+ const lastMessage = history
102
+ .filter(
103
+ (e) => e.kind === EventKind.MESSAGE && e.source === EventSource.CUSTOMER
104
+ )
105
+ .pop();
106
+
107
+ if (!lastMessage) {
108
+ return { data: "No query found" };
109
+ }
110
+
111
+ const query = (lastMessage.data as any).message.toLowerCase();
112
+
113
+ // Simple keyword matching (in real app, use vector search)
114
+ const relevantFaqs = context.context.faqs.filter(
115
+ (faq) =>
116
+ faq.question.toLowerCase().includes(query) ||
117
+ faq.answer.toLowerCase().includes(query)
118
+ );
119
+
120
+ console.log(`[Tool] Found ${relevantFaqs.length} relevant FAQs`);
121
+
122
+ return {
123
+ data: relevantFaqs
124
+ .map((faq) => `Q: ${faq.question}\nA: ${faq.answer}`)
125
+ .join("\n\n"),
126
+ };
127
+ },
128
+ };
129
+
130
+ // ==============================================================================
131
+ // AGENT SETUP
132
+ // ==============================================================================
133
+
134
+ const agent = new Agent<CompanyContext>({
135
+ name: "Acme Support Agent",
136
+ goal: "Answer questions about Acme Corp and our products",
137
+ description:
138
+ "I'm here to help you learn about Acme Corp, our products, and policies",
139
+ personality:
140
+ "Friendly, helpful, and knowledgeable. Always professional but approachable.",
141
+ ai: null as any, // Replace with actual AI provider
142
+
143
+ // Initialize with company knowledge
144
+ context: {
145
+ companyInfo: {
146
+ name: "Acme Corporation",
147
+ founded: 2010,
148
+ employees: 500,
149
+ headquarters: "San Francisco, CA",
150
+ },
151
+ products: [
152
+ {
153
+ id: "widget-1",
154
+ name: "Acme Widget",
155
+ description: "Our flagship product for all your widget needs",
156
+ price: "$99.99",
157
+ category: "widgets",
158
+ },
159
+ {
160
+ id: "gadget-1",
161
+ name: "Acme Gadget",
162
+ description: "The revolutionary gadget that changed everything",
163
+ price: "$149.99",
164
+ category: "gadgets",
165
+ },
166
+ ],
167
+ policies: {
168
+ returnPolicy: "30-day money-back guarantee, no questions asked",
169
+ shippingPolicy:
170
+ "Free shipping on orders over $50. 2-5 business days delivery",
171
+ warrantyPolicy: "1-year warranty on all products",
172
+ },
173
+ faqs: [
174
+ {
175
+ question: "What is your return policy?",
176
+ answer: "We offer a 30-day money-back guarantee on all products.",
177
+ category: "returns",
178
+ },
179
+ {
180
+ question: "Do you ship internationally?",
181
+ answer: "Yes, we ship to over 50 countries worldwide.",
182
+ category: "shipping",
183
+ },
184
+ {
185
+ question: "How long is the warranty?",
186
+ answer: "All products come with a 1-year manufacturer warranty.",
187
+ category: "warranty",
188
+ },
189
+ ],
190
+ },
191
+
192
+ // Add domain terms for better understanding
193
+ terms: [
194
+ {
195
+ name: "Widget",
196
+ description: "Our core product line for task automation",
197
+ },
198
+ {
199
+ name: "Gadget",
200
+ description: "Advanced tools for power users",
201
+ },
202
+ ],
203
+
204
+ // General guidelines (no tools attached - just behavioral)
205
+ guidelines: [
206
+ {
207
+ action: "Always be polite and professional",
208
+ enabled: true,
209
+ },
210
+ {
211
+ action:
212
+ "If you don't know the answer, admit it and offer to connect them with a human",
213
+ enabled: true,
214
+ },
215
+ {
216
+ action: "Provide specific, accurate information from the knowledge base",
217
+ enabled: true,
218
+ },
219
+ ],
220
+ });
221
+
222
+ // ==============================================================================
223
+ // ROUTES: STATELESS Q&A ROUTES (Schema-First Architecture)
224
+ // ==============================================================================
225
+
226
+ // Route 1: Company Information (stateless - no data extraction)
227
+ const companyInfoRoute = agent.createRoute({
228
+ title: "Company Information",
229
+ description: "Answer general questions about Acme Corp",
230
+ conditions: [
231
+ "User asks about the company",
232
+ "Questions about company history, size, location",
233
+ "When was the company founded",
234
+ "How many employees",
235
+ "Where is the headquarters",
236
+ ],
237
+ // NO gatherSchema - stateless Q&A route
238
+ // Just use initial state with chatState for response generation
239
+ });
240
+
241
+ // Initial state: Answer from knowledge base (no data gathering needed)
242
+
243
+ // Route 2: Product Information (stateless)
244
+ const productInfoRoute = agent.createRoute({
245
+ title: "Product Information",
246
+ description: "Answer questions about products",
247
+ conditions: [
248
+ "User asks about products",
249
+ "Questions about features, pricing, availability",
250
+ "What products do you offer",
251
+ "Tell me about your widgets",
252
+ ],
253
+ // NO gatherSchema - just answering questions
254
+ });
255
+
256
+ // Initial state is enough - no transitions needed for simple Q&A
257
+
258
+ // Route 3: Policy Questions (stateless)
259
+ const policyRoute = agent.createRoute({
260
+ title: "Policy Information",
261
+ description: "Answer questions about company policies",
262
+ conditions: [
263
+ "User asks about policies",
264
+ "Return policy",
265
+ "Shipping information",
266
+ "Warranty questions",
267
+ ],
268
+ // NO gatherSchema
269
+ });
270
+
271
+ // Initial state is enough - no extra setup needed
272
+
273
+ // Route 4: News & Updates (uses tool, but still stateless)
274
+ const newsRoute = agent.createRoute({
275
+ title: "Company News",
276
+ description: "Share latest company news and updates",
277
+ conditions: [
278
+ "User asks about news",
279
+ "What's new",
280
+ "Recent updates",
281
+ "Latest announcements",
282
+ ],
283
+ });
284
+
285
+ // Add tool to initial state to fetch news
286
+ const fetchNews = newsRoute.initialState.transitionTo({
287
+ toolState: fetchNewsTool,
288
+ });
289
+
290
+ const shareNews = fetchNews.transitionTo({
291
+ chatState: "Share the latest company news from context",
292
+ });
293
+
294
+ // Route 5: General FAQ Search (uses tool)
295
+ const faqRoute = agent.createRoute({
296
+ title: "FAQ Search",
297
+ description: "Search FAQs for relevant answers",
298
+ conditions: [
299
+ "User has a question that might be in FAQs",
300
+ "How do I...",
301
+ "Can I...",
302
+ "Is there...",
303
+ ],
304
+ });
305
+
306
+ const searchFaqs = faqRoute.initialState.transitionTo({
307
+ toolState: searchKnowledgeTool,
308
+ });
309
+
310
+ const provideFaqAnswer = searchFaqs.transitionTo({
311
+ chatState: "Provide answer based on FAQ search results",
312
+ });
313
+
314
+ // Route 6: Fallback (generic response)
315
+ const fallbackRoute = agent.createRoute({
316
+ title: "General Conversation",
317
+ description: "Handle general conversation or unclear questions",
318
+ conditions: [
319
+ "User message doesn't match other routes",
320
+ "Greetings",
321
+ "Small talk",
322
+ "Unclear intent",
323
+ ],
324
+ });
325
+
326
+ // Initial state is enough for fallback conversations
327
+
328
+ // ==============================================================================
329
+ // USAGE EXAMPLES: Three-Phase Pipeline Demonstration
330
+ // ==============================================================================
331
+
332
+ async function exampleConversations() {
333
+ let session = createSession();
334
+
335
+ // =========================================================================
336
+ // Example 1: Simple company info question (stateless)
337
+ // =========================================================================
338
+ console.log("\n=== EXAMPLE 1: Company Info (Stateless Q&A) ===");
339
+ const history1: Event[] = [
340
+ createMessageEvent(
341
+ EventSource.CUSTOMER,
342
+ "User",
343
+ "How many employees does Acme have?"
344
+ ),
345
+ ];
346
+
347
+ const response1 = await agent.respond({ history: history1, session });
348
+ console.log("AI:", response1.message);
349
+ console.log("Route:", response1.session?.currentRoute?.title);
350
+
351
+ /*
352
+ * ARCHITECTURE FLOW:
353
+ * 1. PREPARATION: No tools needed for simple Q&A
354
+ * 2. ROUTING: Framework routes to "Company Information" (score: 95)
355
+ * 3. RESPONSE: AI answers from context knowledge
356
+ * - Route: "Company Information"
357
+ * - Session: Updated with route/state (even for stateless)
358
+ * - No data extraction (stateless route)
359
+ */
360
+
361
+ // =========================================================================
362
+ // Example 2: Product question (stateless)
363
+ // =========================================================================
364
+ console.log("\n=== EXAMPLE 2: Product Info ===");
365
+ const history2: Event[] = [
366
+ createMessageEvent(
367
+ EventSource.CUSTOMER,
368
+ "User",
369
+ "What products do you offer?"
370
+ ),
371
+ ];
372
+
373
+ const response2 = await agent.respond({ history: history2, session });
374
+ console.log("AI:", response2.message);
375
+ console.log("Route:", response2.session?.currentRoute?.title);
376
+ // Expected: "We offer two main products: Acme Widget ($99.99)..."
377
+ // Route: "Product Information"
378
+
379
+ // =========================================================================
380
+ // Example 3: Policy question (stateless)
381
+ // =========================================================================
382
+ console.log("\n=== EXAMPLE 3: Policy Question ===");
383
+ const history3: Event[] = [
384
+ createMessageEvent(
385
+ EventSource.CUSTOMER,
386
+ "User",
387
+ "What's your return policy?"
388
+ ),
389
+ ];
390
+
391
+ const response3 = await agent.respond({ history: history3, session });
392
+ console.log("AI:", response3.message);
393
+ console.log("Route:", response3.session?.currentRoute?.title);
394
+ // Expected: "We offer a 30-day money-back guarantee..."
395
+ // Route: "Policy Information"
396
+
397
+ // =========================================================================
398
+ // Example 4: News request (tool execution, but still stateless)
399
+ // =========================================================================
400
+ console.log("\n=== EXAMPLE 4: Latest News ===");
401
+ const history4: Event[] = [
402
+ createMessageEvent(EventSource.CUSTOMER, "User", "What's new at Acme?"),
403
+ ];
404
+
405
+ const response4 = await agent.respond({ history: history4, session });
406
+ console.log("AI:", response4.message);
407
+ console.log("Route:", response4.session?.currentRoute?.title);
408
+ // Tool fetches news → Updates context → AI responds with news
409
+ // Route: "Company News"
410
+ // NO data extraction - tool just enriches context
411
+
412
+ // =========================================================================
413
+ // Example 5: Multi-turn conversation (context maintained)
414
+ // =========================================================================
415
+ console.log("\n=== EXAMPLE 5: Multi-turn ===");
416
+
417
+ // Turn 1
418
+ const turn1: Event[] = [
419
+ createMessageEvent(
420
+ EventSource.CUSTOMER,
421
+ "User",
422
+ "Tell me about the Acme Widget"
423
+ ),
424
+ ];
425
+ const resp1 = await agent.respond({ history: turn1, session });
426
+ console.log("User: Tell me about the Acme Widget");
427
+ console.log("AI:", resp1.message);
428
+
429
+ // Turn 2 - follow-up question
430
+ const turn2: Event[] = [
431
+ ...turn1,
432
+ createMessageEvent(EventSource.AI_AGENT, "Agent", resp1.message),
433
+ createMessageEvent(EventSource.CUSTOMER, "User", "How much does it cost?"),
434
+ ];
435
+ const resp2 = await agent.respond({
436
+ history: turn2,
437
+ session: resp1.session, // Pass previous session
438
+ });
439
+ console.log("User: How much does it cost?");
440
+ console.log("AI:", resp2.message);
441
+ // AI understands "it" refers to Acme Widget from context
442
+ }
443
+
444
+ // ==============================================================================
445
+ // KEY TAKEAWAYS FOR Q&A USE CASES
446
+ // ==============================================================================
447
+
448
+ /*
449
+ * 1. NO STATE MACHINES REQUIRED
450
+ * - Just use the initial state with a chatState description
451
+ * - No gather, no skipIf, no state transitions
452
+ * - Perfect for stateless question-answering
453
+ *
454
+ * 2. ROUTING STILL WORKS
455
+ * - Framework routes to most relevant Q&A route
456
+ * - Always-on routing handles topic switches
457
+ * - Conditions guide the AI to the right knowledge domain
458
+ *
459
+ * 3. TOOLS FOR CONTEXT ENRICHMENT
460
+ * - Tools fetch additional data (news, search results)
461
+ * - Updates context (not extracted data)
462
+ * - AI uses enriched context to answer
463
+ *
464
+ * 4. KNOWLEDGE IN CONTEXT
465
+ * - Store company knowledge in context
466
+ * - Use contextProvider for always-fresh data
467
+ * - Tools can augment context at runtime
468
+ *
469
+ * 5. MIX STATEFUL & STATELESS
470
+ * - Have Q&A routes (stateless)
471
+ * - AND booking/onboarding routes (stateful)
472
+ * - Framework handles both seamlessly
473
+ *
474
+ * 6. GUIDELINES FOR BEHAVIOR
475
+ * - Use guidelines for general behavioral rules
476
+ * - No need for complex state machines for simple policies
477
+ * - Keep it simple!
478
+ *
479
+ * ARCHITECTURE FOR Q&A:
480
+ *
481
+ * User Question
482
+ * ↓
483
+ * Routing (score all Q&A routes)
484
+ * ↓
485
+ * Tool Execution (if needed - fetch data)
486
+ * ↓
487
+ * Response (AI answers from context)
488
+ * ↓
489
+ * Done (no state tracking needed)
490
+ *
491
+ * vs. STATEFUL FLOWS (booking, onboarding):
492
+ *
493
+ * User Intent
494
+ * ↓
495
+ * Routing
496
+ * ↓
497
+ * State Machine (gather data step-by-step)
498
+ * ↓
499
+ * Tools (validate/enrich extracted data)
500
+ * ↓
501
+ * Response (continue conversation)
502
+ * ↓
503
+ * Track Session (extracted data, current state)
504
+ */
505
+
506
+ if (require.main === module) {
507
+ exampleConversations().catch(console.error);
508
+ }