Use this file to discover all available pages before exploring further.
An interactive onboarding agent that guides new users through setup, tracks their progress, and adapts to their pace. This example shows long-running conversations with progress tracking, knowledge base search, and dynamic instructions based on user state.
Keep step definitions in a config file so they’re easy to update:
config/steps.ts
export const ONBOARDING_STEPS = [ { id: 'profile', name: 'Complete your profile', description: 'Set up name, photo, and preferences' }, { id: 'workspace', name: 'Create a workspace', description: 'Set up your first workspace' }, { id: 'invite', name: 'Invite team members', description: 'Add at least one teammate' }, { id: 'first-agent', name: 'Create your first agent', description: 'Build and test a simple agent' }, { id: 'deploy', name: 'Deploy to production', description: 'Deploy your agent live' },] as const;export type StepId = (typeof ONBOARDING_STEPS)[number]['id'];
import { ONBOARDING_STEPS } from '../config/steps';const stepList = ONBOARDING_STEPS.map((s, i) => `${i + 1}. **${s.name}**: ${s.description}`).join('\n');export const onboardingPrompt = `You are a friendly onboarding assistant that guides new users through setup.## Onboarding Steps${stepList}## Behavior- Start by checking the user's current progress with get-progress- Guide them through the next incomplete step- Celebrate when they complete a step — use encouragement- If they're stuck, offer tips and link to relevant docs- If they ask about something unrelated, gently steer back to onboarding- Adapt your pace — if they seem experienced, be brief; if they seem new, explain more## Tools- Use **get-progress** at the start of each conversation to know where they are- Use **mark-step-complete** when the user confirms they've finished a step- Never mark a step as complete without the user confirming it## Response Style- Be warm and encouraging but not over-the-top- Use short paragraphs- Use numbered steps when explaining how to do something- End messages with a clear next action`;
import { Agent, openai } from '@runflow-ai/sdk';import { onboardingPrompt } from './prompts';import { getProgressTool, markStepCompleteTool } from './tools';export const onboardingAgent = new Agent({ name: 'Onboarding Assistant', instructions: onboardingPrompt, model: openai('gpt-4o'), memory: { maxTurns: 50, summarizeAfter: 30, summarizePrompt: 'Summarize: completed onboarding steps, current step, user questions, and blockers', }, rag: { vectorStore: 'onboarding-docs', k: 3, threshold: 0.7, searchPrompt: `Search when the user asks how to do something specific, like:- How to create a workspace- How to invite team members- How to deploy an agent`, }, tools: { getProgress: getProgressTool, markStepComplete: markStepCompleteTool, }, observability: 'full',});
The agent calls get-progress at the start of each conversation to know exactly where the user is. This means it can pick up right where they left off — even days later.
Using TypeScript enums for step IDs ensures the LLM can only mark valid steps as complete:
const validStepIds = ONBOARDING_STEPS.map((s) => s.id) as [string, ...string[]];inputSchema: z.object({ stepId: z.enum(validStepIds), // LLM can only choose from valid steps})