@falai/agent 0.4.1 → 0.5.1

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 +464 -291
  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 +55 -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 -12
  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 +77 -0
  78. package/dist/cjs/types/session.d.ts.map +1 -0
  79. package/dist/cjs/types/session.js +146 -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 +464 -291
  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 +55 -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 -12
  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 +77 -0
  167. package/dist/types/session.d.ts.map +1 -0
  168. package/dist/types/session.js +138 -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 +329 -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 +668 -356
  206. package/src/core/Events.ts +12 -2
  207. package/src/core/PersistenceManager.ts +81 -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 -13
  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 +219 -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 -116
  240. package/dist/cjs/core/PreparationEngine.d.ts.map +0 -1
  241. package/dist/cjs/core/PreparationEngine.js +0 -353
  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 -116
  264. package/dist/core/PreparationEngine.d.ts.map +0 -1
  265. package/dist/core/PreparationEngine.js +0 -349
  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 -561
  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,14 +1,22 @@
1
1
  /**
2
- * Example: Using Redis for Persistence
2
+ * Example: Using Redis for Persistence with Session State
3
3
  *
4
4
  * Fast, in-memory persistence perfect for:
5
5
  * - High-throughput applications
6
- * - Session caching
6
+ * - Session caching with extracted data
7
7
  * - Real-time chat applications
8
8
  * - Temporary conversation storage
9
9
  */
10
10
 
11
- import { Agent, GeminiProvider, RedisAdapter } from "../src/index";
11
+ import {
12
+ Agent,
13
+ GeminiProvider,
14
+ RedisAdapter,
15
+ createMessageEvent,
16
+ EventSource,
17
+ MessageEventData,
18
+ Event,
19
+ } from "../src/index";
12
20
  // @ts-ignore
13
21
  import Redis from "ioredis";
14
22
 
@@ -25,65 +33,427 @@ import Redis from "ioredis";
25
33
  * 3. Run this example
26
34
  */
27
35
 
36
+ interface ChatContext {
37
+ userId: string;
38
+ userName: string;
39
+ chatType: "support" | "sales" | "general";
40
+ }
41
+
42
+ interface SupportTicketData {
43
+ issue: string;
44
+ category: "technical" | "billing" | "account" | "other";
45
+ priority: "low" | "medium" | "high";
46
+ description: string;
47
+ }
48
+
28
49
  async function example() {
29
50
  // Initialize Redis client
30
51
  const redis = new Redis();
31
52
 
53
+ const userId = "user_123";
54
+
32
55
  // Create agent with Redis persistence
33
- const agent = new Agent({
34
- name: "Chat Assistant",
35
- description: "Fast, real-time chat assistant",
56
+ const agent = new Agent<ChatContext>({
57
+ name: "Support Assistant",
58
+ description: "Fast, real-time support assistant",
59
+ goal: "Help users resolve issues quickly",
36
60
  ai: new GeminiProvider({
37
61
  apiKey: process.env.GEMINI_API_KEY!,
38
62
  model: "models/gemini-2.0-flash-exp",
39
63
  }),
64
+ context: {
65
+ userId,
66
+ userName: "Alice",
67
+ chatType: "support",
68
+ },
40
69
  // ✨ Redis adapter with custom options
41
70
  persistence: {
42
71
  adapter: new RedisAdapter({
43
72
  redis,
44
- keyPrefix: "chat:", // Custom prefix
73
+ keyPrefix: "support:", // Custom prefix
45
74
  sessionTTL: 24 * 60 * 60, // 24 hours
46
75
  messageTTL: 7 * 24 * 60 * 60, // 7 days
47
76
  }),
48
- autoSave: true,
49
- userId: "user_123",
77
+ autoSave: true, // Auto-save session state
78
+ userId,
79
+ },
80
+ });
81
+
82
+ // Create support ticket route with data gathering
83
+ const ticketRoute = agent.createRoute<SupportTicketData>({
84
+ title: "Create Support Ticket",
85
+ description: "Help user create and track support tickets",
86
+ conditions: [
87
+ "User needs help with an issue",
88
+ "User wants to report a problem",
89
+ "User mentions support, help, or issue",
90
+ ],
91
+ gatherSchema: {
92
+ type: "object",
93
+ properties: {
94
+ issue: {
95
+ type: "string",
96
+ description: "Brief summary of the issue",
97
+ },
98
+ category: {
99
+ type: "string",
100
+ enum: ["technical", "billing", "account", "other"],
101
+ description: "Issue category",
102
+ },
103
+ priority: {
104
+ type: "string",
105
+ enum: ["low", "medium", "high"],
106
+ default: "medium",
107
+ description: "Issue priority",
108
+ },
109
+ description: {
110
+ type: "string",
111
+ description: "Detailed description of the issue",
112
+ },
113
+ },
114
+ required: ["issue", "category", "description"],
50
115
  },
51
116
  });
52
117
 
118
+ // State flow
119
+ ticketRoute.initialState
120
+ .transitionTo({
121
+ chatState: "Ask what the issue is",
122
+ gather: ["issue", "category"],
123
+ skipIf: (data) => !!data.issue && !!data.category,
124
+ })
125
+ .transitionTo({
126
+ chatState: "Ask for priority",
127
+ gather: ["priority"],
128
+ skipIf: (data) => !!data.priority,
129
+ requiredData: ["issue", "category"],
130
+ })
131
+ .transitionTo({
132
+ chatState: "Ask for detailed description",
133
+ gather: ["description"],
134
+ skipIf: (data) => !!data.description,
135
+ requiredData: ["issue", "category"],
136
+ })
137
+ .transitionTo({
138
+ chatState: "Confirm and create ticket",
139
+ requiredData: ["issue", "category", "description"],
140
+ });
141
+
53
142
  const persistence = agent.getPersistenceManager();
54
143
  if (!persistence) return;
55
144
 
56
- // Create session
57
- const session = await persistence.createSession({
58
- userId: "user_123",
59
- agentName: "Chat Assistant",
60
- initialData: { chatType: "support" },
145
+ // Create session with state support
146
+ const { sessionData, sessionState } =
147
+ await persistence.createSessionWithState<SupportTicketData>({
148
+ userId,
149
+ agentName: "Support Assistant",
150
+ initialData: {
151
+ priority: "medium", // Default priority
152
+ },
153
+ });
154
+
155
+ console.log("✨ Session created in Redis:", sessionData.id);
156
+ console.log("📊 Initial state:", {
157
+ extracted: sessionState.extracted,
158
+ });
159
+
160
+ // Turn 1: User provides issue
161
+ const history: Event<MessageEventData>[] = [];
162
+ let session = sessionState;
163
+
164
+ const message1 = createMessageEvent(
165
+ EventSource.CUSTOMER,
166
+ "Alice",
167
+ "I can't log into my account, it's a technical issue and it's urgent!"
168
+ );
169
+ history.push(message1);
170
+
171
+ const response1 = await agent.respond({
172
+ history,
173
+ session,
174
+ });
175
+
176
+ console.log("\n--- Turn 1 ---");
177
+ console.log("🤖 Agent:", response1.message);
178
+ console.log("📊 Extracted data:", response1.session?.extracted);
179
+
180
+ // Save messages
181
+ await persistence.saveMessage({
182
+ sessionId: sessionData.id,
183
+ role: "user",
184
+ content: message1.data.message,
185
+ });
186
+
187
+ await persistence.saveMessage({
188
+ sessionId: sessionData.id,
189
+ role: "agent",
190
+ content: response1.message,
191
+ route: response1.session?.currentRoute?.id,
192
+ state: response1.session?.currentState?.id,
193
+ });
194
+
195
+ session = response1.session!;
196
+
197
+ // Turn 2: Provide more details
198
+ history.push(
199
+ createMessageEvent(
200
+ EventSource.AI_AGENT,
201
+ "Support Assistant",
202
+ response1.message
203
+ )
204
+ );
205
+
206
+ const message2 = createMessageEvent(
207
+ EventSource.CUSTOMER,
208
+ "Alice",
209
+ "I keep getting 'Invalid credentials' error even though I reset my password"
210
+ );
211
+ history.push(message2);
212
+
213
+ const response2 = await agent.respond({
214
+ history,
215
+ session,
61
216
  });
62
217
 
63
- console.log(" Session created in Redis:", session.id);
218
+ console.log("\n--- Turn 2 ---");
219
+ console.log("🤖 Agent:", response2.message);
220
+ console.log("📊 Extracted data:", response2.session?.extracted);
64
221
 
65
- // Save a message
66
222
  await persistence.saveMessage({
67
- sessionId: session.id,
223
+ sessionId: sessionData.id,
68
224
  role: "user",
69
- content: "Hello! I need help",
225
+ content: message2.data.message,
226
+ });
227
+
228
+ await persistence.saveMessage({
229
+ sessionId: sessionData.id,
230
+ role: "agent",
231
+ content: response2.message,
70
232
  });
71
233
 
72
- // Load messages
73
- const messages = await persistence.getSessionMessages(session.id);
74
- console.log(`💬 ${messages.length} messages in session`);
234
+ // Load session state from Redis (demonstrates persistence)
235
+ console.log("\n--- Loading Session from Redis ---");
236
+ const loadedSession = await persistence.loadSessionState<SupportTicketData>(
237
+ sessionData.id
238
+ );
239
+
240
+ console.log("📥 Loaded session:", {
241
+ currentRoute: loadedSession?.currentRoute?.title,
242
+ extracted: loadedSession?.extracted,
243
+ });
244
+
245
+ // Get messages
246
+ const messages = await persistence.getSessionMessages(sessionData.id);
247
+ console.log(`\n💬 ${messages.length} messages in session`);
75
248
 
76
249
  // Complete session
77
- await persistence.completeSession(session.id);
250
+ await persistence.completeSession(sessionData.id);
78
251
  console.log("✅ Session completed");
79
252
 
80
253
  // Cleanup
81
254
  await redis.quit();
82
255
  }
83
256
 
257
+ /**
258
+ * Advanced Example: High-Throughput Chat with Session State
259
+ */
260
+ async function highThroughputExample() {
261
+ const redis = new Redis();
262
+
263
+ interface QuickChatData {
264
+ topic: string;
265
+ sentiment: "positive" | "neutral" | "negative";
266
+ }
267
+
268
+ const agent = new Agent({
269
+ name: "Chat Bot",
270
+ description: "Fast chat responses",
271
+ ai: new GeminiProvider({
272
+ apiKey: process.env.GEMINI_API_KEY!,
273
+ model: "models/gemini-2.0-flash-exp",
274
+ }),
275
+ persistence: {
276
+ adapter: new RedisAdapter({
277
+ redis,
278
+ keyPrefix: "chat:",
279
+ sessionTTL: 60 * 60, // 1 hour for quick chats
280
+ }),
281
+ autoSave: true,
282
+ userId: "user_456",
283
+ },
284
+ });
285
+
286
+ // Simple chat route that extracts topic and sentiment
287
+ const chatRoute = agent.createRoute<QuickChatData>({
288
+ title: "General Chat",
289
+ gatherSchema: {
290
+ type: "object",
291
+ properties: {
292
+ topic: {
293
+ type: "string",
294
+ description: "Main topic of conversation",
295
+ },
296
+ sentiment: {
297
+ type: "string",
298
+ enum: ["positive", "neutral", "negative"],
299
+ description: "User's sentiment",
300
+ },
301
+ },
302
+ required: ["topic", "sentiment"],
303
+ },
304
+ });
305
+
306
+ chatRoute.initialState.transitionTo({
307
+ chatState: "Chat and extract topic/sentiment",
308
+ gather: ["topic", "sentiment"],
309
+ });
310
+
311
+ const persistence = agent.getPersistenceManager()!;
312
+
313
+ // Create session
314
+ const { sessionData, sessionState } =
315
+ await persistence.createSessionWithState<QuickChatData>({
316
+ userId: "user_456",
317
+ agentName: "Chat Bot",
318
+ });
319
+
320
+ // Quick chat interaction
321
+ const response = await agent.respond({
322
+ history: [
323
+ createMessageEvent(
324
+ EventSource.CUSTOMER,
325
+ "User",
326
+ "I'm loving the new features you added!"
327
+ ),
328
+ ],
329
+ session: sessionState,
330
+ });
331
+
332
+ console.log("🤖 Response:", response.message);
333
+ console.log("📊 Extracted:", response.session?.extracted);
334
+ console.log("💾 Session state cached in Redis!");
335
+
336
+ await redis.quit();
337
+ }
338
+
339
+ /**
340
+ * Session Recovery Example
341
+ * Shows how to resume conversations from Redis
342
+ */
343
+ async function sessionRecoveryExample() {
344
+ const redis = new Redis();
345
+
346
+ interface OrderData {
347
+ productId: string;
348
+ quantity: number;
349
+ shippingAddress: string;
350
+ }
351
+
352
+ const agent = new Agent({
353
+ name: "Order Assistant",
354
+ ai: new GeminiProvider({
355
+ apiKey: process.env.GEMINI_API_KEY!,
356
+ model: "models/gemini-2.0-flash-exp",
357
+ }),
358
+ persistence: {
359
+ adapter: new RedisAdapter({ redis }),
360
+ autoSave: true,
361
+ userId: "user_789",
362
+ },
363
+ });
364
+
365
+ const orderRoute = agent.createRoute<OrderData>({
366
+ title: "Place Order",
367
+ gatherSchema: {
368
+ type: "object",
369
+ properties: {
370
+ productId: { type: "string" },
371
+ quantity: { type: "number", minimum: 1 },
372
+ shippingAddress: { type: "string" },
373
+ },
374
+ required: ["productId", "quantity", "shippingAddress"],
375
+ },
376
+ });
377
+
378
+ orderRoute.initialState
379
+ .transitionTo({
380
+ chatState: "Ask what to order",
381
+ gather: ["productId", "quantity"],
382
+ })
383
+ .transitionTo({
384
+ chatState: "Ask for shipping address",
385
+ gather: ["shippingAddress"],
386
+ });
387
+
388
+ const persistence = agent.getPersistenceManager()!;
389
+
390
+ // Start a new session
391
+ const { sessionData, sessionState } =
392
+ await persistence.createSessionWithState<OrderData>({
393
+ userId: "user_789",
394
+ agentName: "Order Assistant",
395
+ });
396
+
397
+ const sessionId = sessionData.id;
398
+
399
+ console.log("✨ New order session:", sessionId);
400
+
401
+ // First interaction
402
+ const response1 = await agent.respond({
403
+ history: [
404
+ createMessageEvent(
405
+ EventSource.CUSTOMER,
406
+ "User",
407
+ "I want to order product ABC123, 2 units"
408
+ ),
409
+ ],
410
+ session: sessionState,
411
+ });
412
+
413
+ console.log("🤖 Response:", response1.message);
414
+ console.log("📊 Extracted so far:", response1.session?.extracted);
415
+
416
+ // --- Simulate user disconnecting and reconnecting ---
417
+ console.log("\n--- User Reconnects ---");
418
+
419
+ // Load session from Redis
420
+ const recoveredSession = await persistence.loadSessionState<OrderData>(
421
+ sessionId
422
+ );
423
+
424
+ console.log("📥 Recovered session state:", {
425
+ currentRoute: recoveredSession?.currentRoute?.title,
426
+ extracted: recoveredSession?.extracted,
427
+ });
428
+
429
+ // Load message history
430
+ const history = await persistence.loadSessionHistory(sessionId);
431
+ console.log(`📜 Loaded ${history.length} messages from history`);
432
+
433
+ // Continue conversation
434
+ history.push(
435
+ createMessageEvent(
436
+ EventSource.CUSTOMER,
437
+ "User",
438
+ "Ship to 123 Main St, New York"
439
+ )
440
+ );
441
+
442
+ const response2 = await agent.respond({
443
+ history,
444
+ session: recoveredSession!,
445
+ });
446
+
447
+ console.log("🤖 Response:", response2.message);
448
+ console.log("📊 Final extracted data:", response2.session?.extracted);
449
+ console.log("✅ Order complete with recovered session!");
450
+
451
+ await redis.quit();
452
+ }
453
+
84
454
  // Run the example
85
455
  if (require.main === module) {
86
456
  example().catch(console.error);
87
457
  }
88
458
 
89
- export { example };
459
+ export { example, highThroughputExample, sessionRecoveryExample };
@@ -1,11 +1,17 @@
1
1
  /**
2
2
  * Rules & Prohibitions Example
3
+ * Updated for v2 architecture with session state management
3
4
  *
4
5
  * Demonstrates how to use rules and prohibitions to control agent behavior
5
6
  * in different conversation routes (e.g., WhatsApp bot with different styles)
6
7
  */
7
8
 
8
- import { Agent, createMessageEvent, EventSource } from "../src/index";
9
+ import {
10
+ Agent,
11
+ createMessageEvent,
12
+ EventSource,
13
+ createSession,
14
+ } from "../src/index";
9
15
  import { AnthropicProvider } from "../src/providers";
10
16
 
11
17
  // Initialize AI provider
@@ -137,11 +143,17 @@ async function demonstrateRulesAndProhibitions() {
137
143
  ),
138
144
  ];
139
145
 
140
- const response1 = await agent.respond({ history: history1 });
141
- console.log(`Route: ${response1.route?.title}`);
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}`);
142
151
  console.log(`Response: ${response1.message}`);
143
152
  console.log(`Expected: Short, direct, max 1 emoji\n`);
144
153
 
154
+ // Update session with progress
155
+ session = response1.session!;
156
+
145
157
  // Example 2: Sales Consultation - Should be engaging and value-focused
146
158
  console.log("2️⃣ Sales Consultation Route (conversational, value-first)");
147
159
  const history2 = [
@@ -152,11 +164,14 @@ async function demonstrateRulesAndProhibitions() {
152
164
  ),
153
165
  ];
154
166
 
155
- const response2 = await agent.respond({ history: history2 });
156
- console.log(`Route: ${response2.route?.title}`);
167
+ const response2 = await agent.respond({ history: history2, session });
168
+ console.log(`Route: ${response2.session?.currentRoute?.title}`);
157
169
  console.log(`Response: ${response2.message}`);
158
170
  console.log(`Expected: Ask about needs, show value before price\n`);
159
171
 
172
+ // Update session again
173
+ session = response2.session!;
174
+
160
175
  // Example 3: Technical Support - Should be detailed and step-by-step
161
176
  console.log("3️⃣ Technical Support Route (detailed, step-by-step)");
162
177
  const history3 = [
@@ -167,11 +182,14 @@ async function demonstrateRulesAndProhibitions() {
167
182
  ),
168
183
  ];
169
184
 
170
- const response3 = await agent.respond({ history: history3 });
171
- console.log(`Route: ${response3.route?.title}`);
185
+ const response3 = await agent.respond({ history: history3, session });
186
+ console.log(`Route: ${response3.session?.currentRoute?.title}`);
172
187
  console.log(`Response: ${response3.message}`);
173
188
  console.log(`Expected: Clear steps, simple language, patient\n`);
174
189
 
190
+ // Update session again
191
+ session = response3.session!;
192
+
175
193
  // Example 4: Emergency Support - Should be calm and action-oriented
176
194
  console.log("4️⃣ Emergency Support Route (urgent, professional)");
177
195
  const history4 = [
@@ -182,19 +200,22 @@ async function demonstrateRulesAndProhibitions() {
182
200
  ),
183
201
  ];
184
202
 
185
- const response4 = await agent.respond({ history: history4 });
186
- console.log(`Route: ${response4.route?.title}`);
203
+ const response4 = await agent.respond({ history: history4, session });
204
+ console.log(`Route: ${response4.session?.currentRoute?.title}`);
187
205
  console.log(`Response: ${response4.message}`);
188
206
  console.log(`Expected: Acknowledge urgency, no emojis, concrete steps\n`);
189
207
 
208
+ // Update session again
209
+ session = response4.session!;
210
+
190
211
  // Example 5: General Chat - Should be friendly and casual
191
212
  console.log("5️⃣ General Chat Route (friendly, casual)");
192
213
  const history5 = [
193
214
  createMessageEvent(EventSource.CUSTOMER, "Eve", "Hey! How's it going?"),
194
215
  ];
195
216
 
196
- const response5 = await agent.respond({ history: history5 });
197
- console.log(`Route: ${response5.route?.title}`);
217
+ const response5 = await agent.respond({ history: history5, session });
218
+ console.log(`Route: ${response5.session?.currentRoute?.title}`);
198
219
  console.log(`Response: ${response5.message}`);
199
220
  console.log(`Expected: Friendly, emojis, mirrors customer tone\n`);
200
221
  }