@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,175 +1,479 @@
1
1
  /**
2
- * OpenSearch Persistence Example
2
+ * Example: Using OpenSearch for Persistence with Session State
3
3
  *
4
- * This example demonstrates how to use the OpenSearchAdapter for persistent storage.
5
- * Also compatible with Elasticsearch 7.x.
6
- *
7
- * Setup:
8
- * 1. Install the OpenSearch client: npm install @opensearch-project/opensearch
9
- * 2. Run OpenSearch locally:
10
- * docker run -d -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" opensearchproject/opensearch:latest
11
- * 3. Run this example: bun run examples/opensearch-persistence.ts
4
+ * OpenSearch provides powerful persistence with:
5
+ * - Full-text search across conversations
6
+ * - Analytics and aggregations on extracted data
7
+ * - Time-series analysis of sessions
8
+ * - Compatible with Elasticsearch 7.x
12
9
  */
13
10
 
14
- // @ts-ignore - OpenSearch is a peer dependency
15
- import { Client } from "@opensearch-project/opensearch";
16
11
  import {
17
12
  Agent,
18
13
  GeminiProvider,
19
14
  OpenSearchAdapter,
20
- defineTool,
21
15
  createMessageEvent,
22
16
  EventSource,
23
- } from "../src/index.js";
24
-
25
- // Initialize OpenSearch client
26
- const client = new Client({
27
- node: process.env.OPENSEARCH_URL || "https://localhost:9200",
28
- auth: {
29
- username: process.env.OPENSEARCH_USERNAME || "admin",
30
- password: process.env.OPENSEARCH_PASSWORD || "admin",
31
- },
32
- ssl: {
33
- rejectUnauthorized: false, // For development only!
34
- },
35
- });
36
-
37
- // Create adapter with custom index names
38
- const adapter = new OpenSearchAdapter(client, {
39
- indices: {
40
- sessions: "my_agent_sessions",
41
- messages: "my_agent_messages",
42
- },
43
- autoCreateIndices: true, // Automatically create indices with mappings
44
- refresh: "wait_for", // Wait for documents to be searchable (slower but consistent)
45
- });
46
-
47
- // Define context type
48
- interface TravelContext {
17
+ MessageEventData,
18
+ Event,
19
+ } from "../src/index";
20
+ // @ts-ignore
21
+ import { Client } from "@opensearch-project/opensearch";
22
+
23
+ /**
24
+ * Setup Steps:
25
+ *
26
+ * 1. Install OpenSearch and client:
27
+ * brew install opensearch (macOS) or docker run opensearch
28
+ * npm install @opensearch-project/opensearch
29
+ *
30
+ * 2. Start OpenSearch:
31
+ * opensearch or docker start opensearch
32
+ *
33
+ * 3. Run this example
34
+ */
35
+
36
+ interface ConversationContext {
49
37
  userId: string;
50
38
  userName: string;
39
+ department: string;
40
+ }
41
+
42
+ interface ComplaintData {
43
+ category: string;
44
+ severity: "low" | "medium" | "high" | "critical";
45
+ description: string;
46
+ affectedService?: string;
47
+ requestedResolution?: string;
51
48
  }
52
49
 
53
- // Define a simple tool
54
- const bookFlight = defineTool<
55
- TravelContext,
56
- [destination: string, date: string],
57
- { success: boolean; confirmation: string }
58
- >(
59
- "book_flight",
60
- async ({ context }, destination, date) => {
61
- console.log(`šŸ“ Booking flight for ${context.userName}...`);
62
- return {
63
- data: {
64
- success: true,
65
- confirmation: `Flight to ${destination} booked for ${date}`,
50
+ async function example() {
51
+ // Initialize OpenSearch client
52
+ const client = new Client({
53
+ node: process.env.OPENSEARCH_URL || "https://localhost:9200",
54
+ ssl: {
55
+ rejectUnauthorized: false, // For development only
56
+ },
57
+ auth: {
58
+ username: "admin",
59
+ password: "admin",
60
+ },
61
+ });
62
+
63
+ const userId = "user_123";
64
+
65
+ // Create adapter
66
+ const adapter = new OpenSearchAdapter(client, {
67
+ indices: {
68
+ sessions: "agent_sessions",
69
+ messages: "agent_messages",
70
+ },
71
+ autoCreateIndices: true,
72
+ refresh: "wait_for", // Ensure searchability immediately
73
+ });
74
+
75
+ // Initialize indices
76
+ await adapter.initialize();
77
+
78
+ // Create agent with OpenSearch persistence
79
+ const agent = new Agent<ConversationContext>({
80
+ name: "Customer Service Agent",
81
+ description: "Handle customer complaints with full-text search",
82
+ goal: "Resolve customer issues efficiently",
83
+ ai: new GeminiProvider({
84
+ apiKey: process.env.GEMINI_API_KEY!,
85
+ model: "models/gemini-2.0-flash-exp",
86
+ }),
87
+ context: {
88
+ userId,
89
+ userName: "Alice",
90
+ department: "customer_service",
91
+ },
92
+ persistence: {
93
+ adapter,
94
+ autoSave: true, // Auto-save session state with extracted data
95
+ userId,
96
+ },
97
+ });
98
+
99
+ // Create complaint handling route
100
+ const complaintRoute = agent.createRoute<ComplaintData>({
101
+ title: "Handle Customer Complaint",
102
+ description: "Process and resolve customer complaints",
103
+ conditions: [
104
+ "User has a complaint",
105
+ "User reports an issue or problem",
106
+ "User is dissatisfied",
107
+ ],
108
+ gatherSchema: {
109
+ type: "object",
110
+ properties: {
111
+ category: {
112
+ type: "string",
113
+ description: "Complaint category",
114
+ },
115
+ severity: {
116
+ type: "string",
117
+ enum: ["low", "medium", "high", "critical"],
118
+ default: "medium",
119
+ description: "Severity level",
120
+ },
121
+ description: {
122
+ type: "string",
123
+ description: "Detailed complaint description",
124
+ },
125
+ affectedService: {
126
+ type: "string",
127
+ description: "Which service is affected",
128
+ },
129
+ requestedResolution: {
130
+ type: "string",
131
+ description: "What resolution the customer wants",
132
+ },
133
+ },
134
+ required: ["category", "severity", "description"],
135
+ },
136
+ });
137
+
138
+ // State flow
139
+ complaintRoute.initialState
140
+ .transitionTo({
141
+ chatState: "Understand the complaint",
142
+ gather: ["category", "severity", "description"],
143
+ skipIf: (data) => !!data.description,
144
+ })
145
+ .transitionTo({
146
+ chatState: "Identify affected service",
147
+ gather: ["affectedService"],
148
+ skipIf: (data) => !!data.affectedService,
149
+ requiredData: ["description"],
150
+ })
151
+ .transitionTo({
152
+ chatState: "Ask for desired resolution",
153
+ gather: ["requestedResolution"],
154
+ skipIf: (data) => !!data.requestedResolution,
155
+ requiredData: ["category", "description"],
156
+ })
157
+ .transitionTo({
158
+ chatState: "Propose solution and close complaint",
159
+ requiredData: ["category", "description"],
160
+ });
161
+
162
+ const persistence = agent.getPersistenceManager();
163
+ if (!persistence) return;
164
+
165
+ // Create session with state
166
+ const { sessionData, sessionState } =
167
+ await persistence.createSessionWithState<ComplaintData>({
168
+ userId,
169
+ agentName: "Customer Service Agent",
170
+ initialData: {
171
+ severity: "medium",
172
+ },
173
+ });
174
+
175
+ console.log("✨ Session created in OpenSearch:", sessionData.id);
176
+
177
+ // Conversation flow
178
+ const history: Event<MessageEventData>[] = [];
179
+ let session = sessionState;
180
+
181
+ // Turn 1
182
+ console.log("\n--- Turn 1 ---");
183
+ const message1 = createMessageEvent(
184
+ EventSource.CUSTOMER,
185
+ "Alice",
186
+ "I'm very upset! Your app keeps crashing when I try to make a payment. This is critical!"
187
+ );
188
+ history.push(message1);
189
+
190
+ const response1 = await agent.respond({ history, session });
191
+
192
+ console.log("šŸ¤– Agent:", response1.message);
193
+ console.log("šŸ“Š Extracted:", response1.session?.extracted);
194
+
195
+ await persistence.saveMessage({
196
+ sessionId: sessionData.id,
197
+ role: "user",
198
+ content: message1.data.message,
199
+ event: message1,
200
+ });
201
+
202
+ await persistence.saveMessage({
203
+ sessionId: sessionData.id,
204
+ role: "agent",
205
+ content: response1.message,
206
+ route: response1.session?.currentRoute?.id,
207
+ state: response1.session?.currentState?.id,
208
+ });
209
+
210
+ session = response1.session!;
211
+
212
+ // Turn 2
213
+ console.log("\n--- Turn 2 ---");
214
+ history.push(
215
+ createMessageEvent(EventSource.AI_AGENT, "Agent", response1.message)
216
+ );
217
+
218
+ const message2 = createMessageEvent(
219
+ EventSource.CUSTOMER,
220
+ "Alice",
221
+ "It's the payment service. I want a full refund and compensation!"
222
+ );
223
+ history.push(message2);
224
+
225
+ const response2 = await agent.respond({ history, session });
226
+
227
+ console.log("šŸ¤– Agent:", response2.message);
228
+ console.log("šŸ“Š Extracted:", response2.session?.extracted);
229
+
230
+ await persistence.saveMessage({
231
+ sessionId: sessionData.id,
232
+ role: "user",
233
+ content: message2.data.message,
234
+ });
235
+
236
+ await persistence.saveMessage({
237
+ sessionId: sessionData.id,
238
+ role: "agent",
239
+ content: response2.message,
240
+ });
241
+
242
+ // Load session from OpenSearch
243
+ console.log("\n--- Loading Session from OpenSearch ---");
244
+ const loadedSession = await persistence.loadSessionState<ComplaintData>(
245
+ sessionData.id
246
+ );
247
+
248
+ console.log("šŸ“„ Loaded session:", {
249
+ currentRoute: loadedSession?.currentRoute?.title,
250
+ extracted: loadedSession?.extracted,
251
+ });
252
+
253
+ // Demonstrate full-text search
254
+ console.log("\n--- Full-Text Search Example ---");
255
+ const searchResults = await client.search({
256
+ index: "agent_messages",
257
+ body: {
258
+ query: {
259
+ match: {
260
+ content: "payment crash",
261
+ },
66
262
  },
67
- };
68
- },
69
- {
70
- description: "Book a flight for the user",
71
- parameters: {
263
+ },
264
+ });
265
+
266
+ console.log(
267
+ `šŸ” Found ${searchResults.body.hits.total.value} messages matching "payment crash"`
268
+ );
269
+
270
+ // Demonstrate aggregations
271
+ console.log("\n--- Analytics Example ---");
272
+ const aggResults = await client.search({
273
+ index: "agent_sessions",
274
+ body: {
275
+ size: 0,
276
+ aggs: {
277
+ by_status: {
278
+ terms: { field: "status.keyword" },
279
+ },
280
+ by_agent: {
281
+ terms: { field: "agentName.keyword" },
282
+ },
283
+ },
284
+ },
285
+ });
286
+
287
+ console.log("šŸ“Š Session statistics:", aggResults.body.aggregations);
288
+
289
+ // Complete session
290
+ await persistence.completeSession(sessionData.id);
291
+ console.log("\nāœ… Session completed and indexed!");
292
+
293
+ // Cleanup
294
+ if (adapter.disconnect) {
295
+ await adapter.disconnect();
296
+ }
297
+ }
298
+
299
+ /**
300
+ * Advanced Example: Search and Analytics on Extracted Data
301
+ */
302
+ async function analyticsExample() {
303
+ const client = new Client({
304
+ node: process.env.OPENSEARCH_URL || "https://localhost:9200",
305
+ ssl: { rejectUnauthorized: false },
306
+ auth: { username: "admin", password: "admin" },
307
+ });
308
+
309
+ const adapter = new OpenSearchAdapter(client, {
310
+ indices: {
311
+ sessions: "support_sessions",
312
+ messages: "support_messages",
313
+ },
314
+ autoCreateIndices: true,
315
+ });
316
+
317
+ await adapter.initialize();
318
+
319
+ interface TicketData {
320
+ ticketType: string;
321
+ priority: string;
322
+ tags: string[];
323
+ }
324
+
325
+ const agent = new Agent({
326
+ name: "Support Analyzer",
327
+ ai: new GeminiProvider({
328
+ apiKey: process.env.GEMINI_API_KEY!,
329
+ model: "models/gemini-2.0-flash-exp",
330
+ }),
331
+ persistence: {
332
+ adapter,
333
+ autoSave: true,
334
+ userId: "analyst_001",
335
+ },
336
+ });
337
+
338
+ const ticketRoute = agent.createRoute<TicketData>({
339
+ title: "Analyze Support Ticket",
340
+ gatherSchema: {
72
341
  type: "object",
73
342
  properties: {
74
- destination: { type: "string", description: "Destination city" },
75
- date: { type: "string", description: "Travel date" },
343
+ ticketType: { type: "string" },
344
+ priority: { type: "string" },
345
+ tags: {
346
+ type: "array",
347
+ items: { type: "string" },
348
+ },
76
349
  },
77
- required: ["destination", "date"],
350
+ required: ["ticketType", "priority"],
78
351
  },
352
+ });
353
+
354
+ ticketRoute.initialState.transitionTo({
355
+ chatState: "Analyze and categorize ticket",
356
+ gather: ["ticketType", "priority", "tags"],
357
+ });
358
+
359
+ const persistence = agent.getPersistenceManager()!;
360
+
361
+ // Create multiple sessions
362
+ for (let i = 0; i < 3; i++) {
363
+ const { sessionData, sessionState } =
364
+ await persistence.createSessionWithState<TicketData>({
365
+ userId: "analyst_001",
366
+ agentName: "Support Analyzer",
367
+ });
368
+
369
+ const response = await agent.respond({
370
+ history: [
371
+ createMessageEvent(
372
+ EventSource.CUSTOMER,
373
+ "User",
374
+ `Support ticket ${i + 1}: ${
375
+ ["Billing issue", "Technical problem", "Feature request"][i]
376
+ }`
377
+ ),
378
+ ],
379
+ session: sessionState,
380
+ });
381
+
382
+ await persistence.saveMessage({
383
+ sessionId: sessionData.id,
384
+ role: "agent",
385
+ content: response.message,
386
+ });
387
+
388
+ await persistence.completeSession(sessionData.id);
79
389
  }
80
- );
81
-
82
- // Create agent with OpenSearch persistence
83
- const agent = new Agent<TravelContext>({
84
- name: "Travel Assistant",
85
- description: "A helpful travel booking assistant",
86
- ai: new GeminiProvider({
87
- apiKey: process.env.GEMINI_API_KEY || "",
88
- model: "gemini-2.0-flash-exp",
89
- }),
90
- context: {
91
- userId: "user_123",
92
- userName: "Alex",
93
- },
94
- persistence: {
95
- adapter,
96
- autoSave: true,
97
- userId: "user_123",
98
- },
99
- capabilities: [
100
- {
101
- title: "Flight Booking",
102
- description: "Book flights for travel",
103
- tools: [bookFlight],
390
+
391
+ // Search across all sessions
392
+ console.log("\n--- Search All Sessions ---");
393
+ const allSessions = await client.search({
394
+ index: "support_sessions",
395
+ body: {
396
+ query: { match_all: {} },
104
397
  },
105
- ],
106
- });
107
-
108
- async function main() {
109
- try {
110
- console.log("šŸš€ Starting OpenSearch persistence example...\n");
111
-
112
- // First conversation
113
- console.log("šŸ’¬ User: I need to book a flight to Tokyo");
114
- const history1 = [
115
- createMessageEvent(
116
- EventSource.CUSTOMER,
117
- "Alex",
118
- "I need to book a flight to Tokyo"
119
- ),
120
- ];
121
- let response = await agent.respond({ history: history1 });
122
- console.log("šŸ¤– Agent:", response.message);
123
- console.log();
124
-
125
- // Continue conversation (uses same session)
126
- console.log("šŸ’¬ User: Make it for next Monday");
127
- const history2 = [
128
- ...history1,
129
- createMessageEvent(
130
- EventSource.AI_AGENT,
131
- "Travel Assistant",
132
- response.message
133
- ),
134
- createMessageEvent(
135
- EventSource.CUSTOMER,
136
- "Alex",
137
- "Make it for next Monday"
138
- ),
139
- ];
140
- response = await agent.respond({ history: history2 });
141
- console.log("šŸ¤– Agent:", response.message);
142
- console.log();
143
-
144
- // Get persistence manager
145
- const pm = agent.getPersistenceManager();
146
- if (pm) {
147
- // Query sessions
148
- const sessions = await pm.getUserSessions("user_123");
149
- console.log(`šŸ“Š Found ${sessions.length} session(s) for user_123`);
150
-
151
- if (sessions.length > 0) {
152
- const session = sessions[0];
153
- console.log(` Session ID: ${session.id}`);
154
- console.log(` Status: ${session.status}`);
155
- console.log(` Messages: ${session.messageCount || 0}`);
156
- console.log();
157
-
158
- // Query messages
159
- const messages = await pm.getSessionMessages(session.id);
160
- console.log(`šŸ“ Session has ${messages.length} message(s):`);
161
- messages.forEach((msg, idx) => {
162
- console.log(
163
- ` ${idx + 1}. [${msg.role}] ${msg.content.substring(0, 50)}...`
164
- );
165
- });
166
- }
167
- }
168
-
169
- console.log("\nāœ… OpenSearch persistence example completed!");
170
- } catch (error) {
171
- console.error("āŒ Error:", error);
398
+ });
399
+
400
+ console.log(
401
+ `šŸ“Š Total sessions indexed: ${allSessions.body.hits.total.value}`
402
+ );
403
+
404
+ // Analyze extracted data patterns
405
+ console.log("\n--- Analyze Extracted Data ---");
406
+ const sessions = allSessions.body.hits.hits;
407
+
408
+ sessions.forEach((hit: any) => {
409
+ const collectedData = hit._source.collectedData;
410
+ console.log(`Session ${hit._id}:`, {
411
+ extracted: collectedData?.extracted,
412
+ route: hit._source.currentRoute,
413
+ });
414
+ });
415
+
416
+ console.log("āœ… Analytics complete!");
417
+
418
+ if (adapter.disconnect) {
419
+ await adapter.disconnect();
172
420
  }
173
421
  }
174
422
 
175
- main();
423
+ /**
424
+ * Time-Series Analysis Example
425
+ */
426
+ async function timeSeriesExample() {
427
+ const client = new Client({
428
+ node: process.env.OPENSEARCH_URL || "https://localhost:9200",
429
+ ssl: { rejectUnauthorized: false },
430
+ auth: { username: "admin", password: "admin" },
431
+ });
432
+
433
+ const adapter = new OpenSearchAdapter(client);
434
+ await adapter.initialize();
435
+
436
+ const agent = new Agent({
437
+ name: "Metrics Agent",
438
+ ai: new GeminiProvider({
439
+ apiKey: process.env.GEMINI_API_KEY!,
440
+ model: "models/gemini-2.0-flash-exp",
441
+ }),
442
+ persistence: { adapter, userId: "metrics_user" },
443
+ });
444
+
445
+ const persistence = agent.getPersistenceManager()!;
446
+
447
+ // Query sessions over time
448
+ const timeQuery = await client.search({
449
+ index: "agent_sessions",
450
+ body: {
451
+ size: 0,
452
+ aggs: {
453
+ sessions_over_time: {
454
+ date_histogram: {
455
+ field: "createdAt",
456
+ calendar_interval: "day",
457
+ },
458
+ },
459
+ avg_message_count: {
460
+ avg: { field: "messageCount" },
461
+ },
462
+ },
463
+ },
464
+ });
465
+
466
+ console.log("šŸ“ˆ Time-series metrics:", timeQuery.body.aggregations);
467
+ console.log("āœ… Time-series analysis complete!");
468
+
469
+ if (adapter.disconnect) {
470
+ await adapter.disconnect();
471
+ }
472
+ }
473
+
474
+ // Run the example
475
+ if (require.main === module) {
476
+ example().catch(console.error);
477
+ }
478
+
479
+ export { example, analyticsExample, timeSeriesExample };