File: src/tools/UserDataTool.tsTools demonstrating the User API as a persistent per-user storage layer — from simple profile reads to multi-step onboarding state machines.
Onboarding State Machine (Persistent Across Sessions)
The most powerful use of the User API — track multi-step workflows that persist across conversations. If a user leaves mid-onboarding and comes back days later, your agent picks up exactly where they left off.
export class OnboardingStepTool { name = 'onboarding_step'; description = 'Advance the user through onboarding, resuming where they left off'; inputSchema = z.object({ data: z.record(z.any()).optional().describe('Data collected in this step') }); async execute(input: any) { const user = await User.get(); // This persists across conversations — the user can leave and come back const step = user.onboardingStep || 'not_started'; switch (step) { case 'not_started': user.onboardingStep = 'collecting_info'; user.onboardingStartedAt = new Date().toISOString(); user.completedSteps = []; await user.save(); return { nextAction: 'Ask for company name and role' }; case 'collecting_info': // Accumulate data across multiple tool calls user.companyName = input.data?.companyName; user.role = input.data?.role; user.onboardingStep = 'selecting_plan'; user.completedSteps = [...(user.completedSteps || []), 'info_collected']; await user.save(); return { nextAction: 'Present plan options' }; case 'selecting_plan': user.plan = input.data?.plan; user.onboardingStep = 'complete'; user.onboardingCompletedAt = new Date().toISOString(); user.completedSteps = [...(user.completedSteps || []), 'plan_selected']; await user.save(); return { message: `Welcome to the ${user.plan} plan, ${user.companyName}!` }; case 'complete': return { message: 'Onboarding already complete!', completedAt: user.onboardingCompletedAt, plan: user.plan }; } }}
export class SendOrderUpdateTool { async execute(input: { orderId: string, status: string }) { const user = await User.get(); // Send notification to user await user.send([ { type: "text", text: `Hi ${user.name}! Your order #${input.orderId} is now ${input.status}.` }, { type: "text", text: "Thank you for your purchase!" } ]); return { message: "Notification sent to user" }; }}