@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,5 +1,6 @@
1
1
  /**
2
- * Healthcare agent example demonstrating observations and disambiguation
2
+ * Healthcare agent example demonstrating route-based
3
+ * Updated for v2 architecture with session state management and schema-first data extraction
3
4
  */
4
5
 
5
6
  import {
@@ -9,6 +10,7 @@ import {
9
10
  END_ROUTE,
10
11
  EventSource,
11
12
  createMessageEvent,
13
+ createSession,
12
14
  } from "../src/index";
13
15
 
14
16
  // Context type
@@ -17,6 +19,21 @@ interface HealthcareContext {
17
19
  patientName: string;
18
20
  }
19
21
 
22
+ // Data extraction types for healthcare scenarios
23
+ interface AppointmentData {
24
+ appointmentReason?: string;
25
+ urgency?: "low" | "medium" | "high";
26
+ preferredTime?: string;
27
+ preferredDate?: string;
28
+ appointmentType?: "checkup" | "consultation" | "followup";
29
+ }
30
+
31
+ interface LabResultsData {
32
+ testType?: string;
33
+ testDate?: string;
34
+ resultsNeeded?: boolean;
35
+ }
36
+
20
37
  // Tools
21
38
  const getInsuranceProviders = defineTool<HealthcareContext, [], string[]>(
22
39
  "get_insurance_providers",
@@ -46,17 +63,29 @@ const scheduleAppointment = defineTool<
46
63
  HealthcareContext,
47
64
  [datetime: string],
48
65
  string
49
- >("schedule_appointment", async (_, datetime) => {
50
- return { data: `Appointment scheduled for ${datetime}` };
66
+ >("schedule_appointment", async ({ context, extracted }, datetime) => {
67
+ const appointment = extracted as Partial<AppointmentData>;
68
+ if (!appointment?.preferredDate || !appointment?.preferredTime) {
69
+ return {
70
+ data: "Please specify preferred date and time for the appointment",
71
+ };
72
+ }
73
+ return {
74
+ data: `Appointment scheduled for ${appointment.preferredDate} at ${
75
+ appointment.preferredTime
76
+ } for ${appointment.appointmentReason || "consultation"}`,
77
+ };
51
78
  });
52
79
 
53
80
  const getLabResults = defineTool<HealthcareContext, [], object>(
54
81
  "get_lab_results",
55
- async ({ context }) => {
82
+ async ({ context, extracted }) => {
83
+ const labData = extracted as Partial<LabResultsData>;
56
84
  return {
57
85
  data: {
58
- report: "All tests are within the valid range",
59
- prognosis: "Patient is healthy as a horse!",
86
+ report: `Lab results for ${labData?.testType || "general"} tests`,
87
+ prognosis: "All tests are within the valid range",
88
+ patientName: context.patientName,
60
89
  },
61
90
  };
62
91
  }
@@ -96,113 +125,167 @@ async function createHealthcareAgent() {
96
125
  "The doctor who specializes in neurology and is available on Mondays and Tuesdays.",
97
126
  });
98
127
 
99
- // Create scheduling route
100
- const schedulingRoute = agent.createRoute({
128
+ // Create scheduling route with data extraction schema
129
+ const schedulingRoute = agent.createRoute<AppointmentData>({
101
130
  title: "Schedule an Appointment",
102
131
  description: "Helps the patient find a time for their appointment.",
103
132
  conditions: ["The patient wants to schedule an appointment"],
133
+ gatherSchema: {
134
+ type: "object",
135
+ properties: {
136
+ appointmentReason: {
137
+ type: "string",
138
+ description: "Reason for the appointment",
139
+ },
140
+ urgency: {
141
+ type: "string",
142
+ enum: ["low", "medium", "high"],
143
+ default: "medium",
144
+ },
145
+ preferredTime: {
146
+ type: "string",
147
+ description: "Preferred time slot",
148
+ },
149
+ preferredDate: {
150
+ type: "string",
151
+ description: "Preferred date",
152
+ },
153
+ appointmentType: {
154
+ type: "string",
155
+ enum: ["checkup", "consultation", "followup"],
156
+ default: "consultation",
157
+ },
158
+ },
159
+ required: ["appointmentReason"],
160
+ },
161
+ });
162
+
163
+ // State 1: Gather appointment reason
164
+ const gatherReason = schedulingRoute.initialState.transitionTo({
165
+ chatState: "Ask what the patient needs an appointment for",
166
+ gather: ["appointmentReason"],
167
+ skipIf: (extracted) => !!extracted.appointmentReason,
104
168
  });
105
169
 
106
- const t0 = schedulingRoute.initialState.transitionTo({
107
- chatState: "Determine the reason for the visit",
170
+ // State 2: Check urgency and show available slots
171
+ const checkUrgency = gatherReason.transitionTo({
172
+ chatState: "Check if this is urgent and show available slots",
173
+ gather: ["urgency"],
174
+ skipIf: (extracted) => !!extracted.urgency,
175
+ requiredData: ["appointmentReason"],
108
176
  });
109
177
 
110
- const t1 = t0.transitionTo({
178
+ const showSlots = checkUrgency.transitionTo({
111
179
  toolState: getUpcomingSlots,
112
180
  });
113
181
 
114
- const t2 = t1.transitionTo({
115
- chatState: "List available times and ask which ones works for them",
182
+ // State 3: Present available times
183
+ const presentTimes = showSlots.transitionTo({
184
+ chatState: "List available times and ask which one works for them",
116
185
  });
117
186
 
118
- const t3 = t2.transitionTo(
119
- {
120
- chatState: "Confirm the details with the patient before scheduling",
121
- },
122
- "The patient picks a time"
123
- );
187
+ // State 4: Gather preferred time and date
188
+ const gatherPreferences = presentTimes.transitionTo({
189
+ chatState: "Collect preferred time and date",
190
+ gather: ["preferredTime", "preferredDate"],
191
+ skipIf: (extracted) =>
192
+ !!extracted.preferredTime && !!extracted.preferredDate,
193
+ });
124
194
 
125
- const t4 = t3.transitionTo(
126
- {
127
- toolState: scheduleAppointment,
128
- },
129
- "The patient confirms the details"
130
- );
195
+ // State 5: Confirm details and schedule
196
+ const confirmDetails = gatherPreferences.transitionTo({
197
+ chatState: "Confirm the details with the patient before scheduling",
198
+ gather: ["appointmentType"],
199
+ skipIf: (extracted) => !!extracted.appointmentType,
200
+ requiredData: ["appointmentReason", "preferredTime", "preferredDate"],
201
+ });
131
202
 
132
- const t5 = t4.transitionTo({
203
+ const schedule = confirmDetails.transitionTo({
204
+ toolState: scheduleAppointment,
205
+ requiredData: ["appointmentReason", "preferredTime", "preferredDate"],
206
+ });
207
+
208
+ const confirmation = schedule.transitionTo({
133
209
  chatState: "Confirm the appointment has been scheduled",
134
210
  });
135
211
 
136
- t5.transitionTo({ state: END_ROUTE });
212
+ confirmation.transitionTo({ state: END_ROUTE });
137
213
 
138
- // Alternative path: no times work
139
- const t6 = t2.transitionTo(
140
- {
141
- toolState: getLaterSlots,
142
- },
143
- "None of those times work for the patient"
144
- );
214
+ // Alternative path: no times work - show later slots
215
+ const laterSlots = presentTimes.transitionTo({
216
+ toolState: getLaterSlots,
217
+ });
145
218
 
146
- const t7 = t6.transitionTo({
219
+ laterSlots.transitionTo({
147
220
  chatState: "List later times and ask if any of them works",
148
221
  });
149
222
 
150
- t7.transitionTo(
151
- {
152
- state: t3,
153
- },
154
- "The patient picks a time"
155
- );
156
-
157
- const t8 = t7.transitionTo(
158
- {
223
+ // If no times work at all, end route
224
+ laterSlots
225
+ .transitionTo({
159
226
  chatState:
160
227
  "Ask the patient to call the office to schedule an appointment",
161
- },
162
- "None of those times work for the patient either"
163
- );
164
-
165
- t8.transitionTo({ state: END_ROUTE });
228
+ })
229
+ .transitionTo({ state: END_ROUTE });
166
230
 
167
231
  schedulingRoute.createGuideline({
168
232
  condition: "The patient says their visit is urgent",
169
233
  action: "Tell them to call the office immediately",
170
234
  });
171
235
 
172
- // Create lab results route
173
- const labResultsRoute = agent.createRoute({
236
+ // Create lab results route with data extraction schema
237
+ const labResultsRoute = agent.createRoute<LabResultsData>({
174
238
  title: "Lab Results",
175
239
  description: "Retrieves the patient's lab results and explains them.",
176
240
  conditions: ["The patient wants to see their lab results"],
241
+ gatherSchema: {
242
+ type: "object",
243
+ properties: {
244
+ testType: {
245
+ type: "string",
246
+ description: "Type of lab test",
247
+ },
248
+ testDate: {
249
+ type: "string",
250
+ description: "Date of the lab test",
251
+ },
252
+ resultsNeeded: {
253
+ type: "boolean",
254
+ default: true,
255
+ description: "Whether detailed results are needed",
256
+ },
257
+ },
258
+ required: ["testType"],
259
+ },
177
260
  });
178
261
 
179
- const l0 = labResultsRoute.initialState.transitionTo({
180
- toolState: getLabResults,
262
+ // State 1: Gather test information
263
+ const gatherTestInfo = labResultsRoute.initialState.transitionTo({
264
+ chatState: "Ask what type of test results they want to see",
265
+ gather: ["testType"],
266
+ skipIf: (extracted) => !!extracted.testType,
181
267
  });
182
268
 
183
- l0.transitionTo(
184
- {
185
- chatState:
186
- "Tell the patient that the results are not available yet, and to try again later",
187
- },
188
- "The lab results could not be found"
189
- );
269
+ // State 2: Optional: gather test date
270
+ const gatherTestDate = gatherTestInfo.transitionTo({
271
+ chatState: "Ask for the test date if they remember it",
272
+ gather: ["testDate"],
273
+ skipIf: (extracted) => !!extracted.testDate,
274
+ requiredData: ["testType"],
275
+ });
190
276
 
191
- l0.transitionTo(
192
- {
193
- chatState:
194
- "Explain the lab results to the patient - that they are normal",
195
- },
196
- "The lab results are good - i.e., nothing to worry about"
197
- );
277
+ // State 3: Get lab results
278
+ const getResults = gatherTestDate.transitionTo({
279
+ toolState: getLabResults,
280
+ requiredData: ["testType"],
281
+ });
198
282
 
199
- l0.transitionTo(
200
- {
201
- chatState:
202
- "Present the results and ask them to call the office for clarifications on the results as you are not a doctor",
203
- },
204
- "The lab results are not good - i.e., there's an issue with the patient's health"
205
- );
283
+ // State 4: Present results based on status
284
+ const presentResults = getResults.transitionTo({
285
+ chatState: "Present the lab results and explain what they mean",
286
+ });
287
+
288
+ presentResults.transitionTo({ state: END_ROUTE });
206
289
 
207
290
  labResultsRoute.createGuideline({
208
291
  condition:
@@ -211,14 +294,6 @@ async function createHealthcareAgent() {
211
294
  "Assertively tell them that you cannot help and they should call the office",
212
295
  });
213
296
 
214
- // Create observation for disambiguation
215
- const statusInquiry = agent.createObservation(
216
- "The patient asks to follow up on their visit, but it's not clear in which way"
217
- );
218
-
219
- // Use observation to disambiguate between the two routes
220
- statusInquiry.disambiguate([schedulingRoute, labResultsRoute]);
221
-
222
297
  // Global guidelines
223
298
  agent.createGuideline({
224
299
  condition: "The patient asks about insurance",
@@ -242,10 +317,13 @@ async function createHealthcareAgent() {
242
317
  return agent;
243
318
  }
244
319
 
245
- // Example usage
320
+ // Example usage with session state management
246
321
  async function main() {
247
322
  const agent = await createHealthcareAgent();
248
323
 
324
+ // Initialize session state for multi-turn conversation
325
+ let session = createSession<AppointmentData | LabResultsData>();
326
+
249
327
  const history = [
250
328
  createMessageEvent(
251
329
  EventSource.CUSTOMER,
@@ -259,7 +337,6 @@ async function main() {
259
337
  console.log("\nRoutes:", agent.getRoutes().length);
260
338
  console.log("Terms:", agent.getTerms().length);
261
339
  console.log("Guidelines:", agent.getGuidelines().length);
262
- console.log("Observations:", agent.getObservations().length);
263
340
 
264
341
  // Print routes
265
342
  const routes = agent.getRoutes();
@@ -267,12 +344,39 @@ async function main() {
267
344
  console.log("\n" + route.describe());
268
345
  }
269
346
 
270
- // Print observations
271
- console.log("\nObservations:");
272
- for (const obs of agent.getObservations()) {
273
- console.log(
274
- `- "${obs.description}" (disambiguates ${obs.getRoutes().length} routes)`
275
- );
347
+ // Example conversation with session state
348
+ console.log("\n=== EXAMPLE CONVERSATION ===");
349
+
350
+ // Turn 1: Patient wants to follow up
351
+ const response1 = await agent.respond({ history, session });
352
+ console.log("Patient: Hi, I need to follow up on my visit");
353
+ console.log("Agent:", response1.message);
354
+ console.log("Route:", response1.session?.currentRoute?.title);
355
+ console.log("Extracted:", response1.session?.extracted);
356
+
357
+ // Update session with progress
358
+ session = response1.session!;
359
+
360
+ // Turn 2: Patient specifies they want to schedule an appointment
361
+ if (response1.session?.currentRoute?.title === "Schedule an Appointment") {
362
+ const history2 = [
363
+ ...history,
364
+ createMessageEvent(EventSource.AI_AGENT, "Agent", response1.message),
365
+ createMessageEvent(
366
+ EventSource.CUSTOMER,
367
+ "Patient",
368
+ "I need to schedule a checkup for next week"
369
+ ),
370
+ ];
371
+
372
+ const response2 = await agent.respond({ history: history2, session });
373
+ console.log("\nPatient: I need to schedule a checkup for next week");
374
+ console.log("Agent:", response2.message);
375
+ console.log("Updated extracted:", response2.session?.extracted);
376
+ console.log("Current state:", response2.session?.currentState?.id);
377
+
378
+ // Update session again
379
+ session = response2.session!;
276
380
  }
277
381
  }
278
382
 
@@ -1,8 +1,6 @@
1
1
  /**
2
2
  * Example: OpenAI Agent with multiple providers
3
- *
4
- * This example demonstrates how to use the OpenAI provider
5
- * and how to switch between different AI providers
3
+ * Updated for v2 architecture with session state management and schema-first data extraction
6
4
  */
7
5
 
8
6
  import {
@@ -11,6 +9,8 @@ import {
11
9
  defineTool,
12
10
  createMessageEvent,
13
11
  EventSource,
12
+ createSession,
13
+ END_ROUTE,
14
14
  } from "../src/index";
15
15
 
16
16
  // Custom context type
@@ -20,18 +20,29 @@ interface CustomerContext {
20
20
  preferences: string[];
21
21
  }
22
22
 
23
- // Define a simple tool
23
+ // Data extraction type for weather queries
24
+ interface WeatherData {
25
+ location?: string;
26
+ temperature?: number;
27
+ condition?: string;
28
+ }
29
+
30
+ // Define a tool that can access extracted data
24
31
  const getWeather = defineTool<
25
32
  CustomerContext,
26
33
  [{ location: string }],
27
34
  { location: string; temperature: number; condition: string }
28
35
  >(
29
36
  "get_weather",
30
- async (_context, args) => {
37
+ async ({ context, extracted }, args) => {
38
+ // Use extracted location if available, otherwise use args
39
+ const location =
40
+ (extracted as Partial<WeatherData>)?.location || args.location;
41
+
31
42
  // Simulate API call
32
43
  return {
33
44
  data: {
34
- location: args.location,
45
+ location,
35
46
  temperature: 72,
36
47
  condition: "Sunny",
37
48
  },
@@ -96,33 +107,58 @@ async function main() {
96
107
  enabled: true,
97
108
  });
98
109
 
99
- // Create a simple route
100
- const weatherRoute = agent.createRoute({
110
+ // Create weather route with data extraction schema
111
+ const weatherRoute = agent.createRoute<WeatherData>({
101
112
  title: "Check Weather",
102
113
  description: "Help user check weather for a location",
103
114
  conditions: ["User wants to know the weather"],
115
+ gatherSchema: {
116
+ type: "object",
117
+ properties: {
118
+ location: {
119
+ type: "string",
120
+ description: "City or location for weather check",
121
+ },
122
+ temperature: {
123
+ type: "number",
124
+ description: "Temperature in Fahrenheit",
125
+ },
126
+ condition: {
127
+ type: "string",
128
+ description: "Weather condition (sunny, cloudy, rainy, etc.)",
129
+ },
130
+ },
131
+ required: ["location"],
132
+ },
104
133
  });
105
134
 
106
- // Add states and transitions
135
+ // State 1: Gather location
107
136
  const askLocation = weatherRoute.initialState.transitionTo({
108
137
  chatState: "Ask which city they want weather for",
138
+ gather: ["location"],
139
+ skipIf: (extracted) => !!extracted.location,
109
140
  });
110
141
 
111
- const fetchWeather = askLocation.transitionTo(
112
- {
113
- toolState: getWeather,
114
- },
115
- "User provides a city name"
116
- );
142
+ // State 2: Get weather data
143
+ const fetchWeather = askLocation.transitionTo({
144
+ toolState: getWeather,
145
+ requiredData: ["location"],
146
+ });
117
147
 
148
+ // State 3: Present weather information
118
149
  const showWeather = fetchWeather.transitionTo({
119
150
  chatState:
120
151
  "Present the weather information in a friendly way with temperature and condition",
121
152
  });
122
153
 
123
- // Simulate a conversation
154
+ showWeather.transitionTo({ state: END_ROUTE });
155
+
156
+ // Example conversation with session state management
124
157
  console.log("šŸ¤– Starting OpenAI Agent Example\n");
125
158
 
159
+ // Initialize session state for multi-turn conversation
160
+ let session = createSession<WeatherData>();
161
+
126
162
  // Build history
127
163
  const history = [
128
164
  createMessageEvent(
@@ -133,11 +169,10 @@ async function main() {
133
169
  ];
134
170
 
135
171
  try {
136
- // Generate response (this would call OpenAI)
137
- console.log("šŸ“¤ Sending request to OpenAI...");
172
+ // Turn 1: Process weather query with session state
173
+ console.log("šŸ“¤ Processing with session state...");
174
+ const response = await agent.respond({ history, session });
138
175
 
139
- // In a real scenario, you would call agent.generateMessage() or similar
140
- // For now, let's just show the structure:
141
176
  console.log("\nāœ… Agent Configuration:");
142
177
  console.log(` AI Provider: ${openaiProvider.name}`);
143
178
 
@@ -147,12 +182,19 @@ async function main() {
147
182
  ` States: Initial → Ask Location → Fetch Weather → Show Weather`
148
183
  );
149
184
 
150
- console.log("\nšŸ’¬ Conversation History:");
151
- history.forEach((event, i) => {
152
- console.log(` ${i + 1}. ${event.source}: ${event.data.message}`);
153
- });
185
+ console.log("\nšŸ’¬ Conversation:");
186
+ console.log(` Customer: ${history[0].data.message}`);
187
+ console.log(` Agent: ${response.message}`);
188
+ console.log(` Route: ${response.session?.currentRoute?.title}`);
189
+ console.log(` Extracted:`, response.session?.extracted);
190
+
191
+ // Update session with progress
192
+ session = response.session!;
154
193
 
155
- console.log("\n✨ Ready to process with OpenAI provider!");
194
+ console.log("\n✨ Session state benefits:");
195
+ console.log(" āœ… Data extraction tracked across turns");
196
+ console.log(" āœ… State progression managed automatically");
197
+ console.log(" āœ… Always-on routing respects intent changes");
156
198
  console.log(
157
199
  " (Set OPENAI_API_KEY environment variable to make actual API calls)"
158
200
  );