Skip to content

falai-dev/agent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

89 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ€– @falai/agent

Type-Safe AI Conversational Agents That Actually Work in Production

Schema-driven data extraction β€’ Predictable conversations β€’ Enterprise-ready

TypeScript License Bun Website

🌐 Website β€’ Features β€’ Installation β€’ Quick Start β€’ Documentation β€’ Examples


⚑ The @falai/agent Difference

Traditional AI Chat:

// User: "I want to book the Grand Hotel for 2 people next Friday"
// AI: "Sure! Which hotel would you like?" // 😠 Asked already!
// User: "Grand Hotel"
// AI: "How many guests?"                 // 😠 You just told me!
// User: "2 people"
// AI: "What date?"                        // 😠 I said Friday!

With @falai/agent:

// User: "I want to book the Grand Hotel for 2 people next Friday"
// AI: "Perfect! Booking confirmed for 2 guests at Grand Hotel on Friday!" 
// βœ… Extracted all data from one message
// βœ… Skipped unnecessary steps
// βœ… Completed immediately

No more repetitive questions. No more guessing what the AI will ask next.

Intelligent Pre-Extraction - AI automatically captures ALL relevant data from user messages, then determines which step to start at based on what's missing.


πŸ€” Why @falai/agent?

After building production AI applications, we found existing solutions either:

  • Too unpredictable - AI decides everything, including which tools to call (unreliable in production)
  • Too complex - Heavy Python frameworks with massive dependencies
  • Too basic - No structured data extraction or step management

@falai/agent gives you predictable AI - the creativity of LLMs with the reliability of code.

The key insight: Let AI do what it's good at (understanding intent, generating responses, extracting data), and let TypeScript handle the rest (step logic, tool execution, validation).


🌟 Features

🎯 Developer Experience

  • Fully Type-Safe - Generic Agent<TContext> with complete inference
  • Fluent API - Chainable methods for elegant code
  • Modular Design - Use what you need, when you need it

πŸš€ Production Ready

  • Robust Retry Logic - Exponential backoff & backup models
  • AI Provider Strategy - Pluggable backends (Claude, Gemini, OpenAI, OpenRouter)
  • Prompt Composition - Sophisticated prompt building system

πŸ›€οΈ Data-Driven Conversations

  • Intelligent Pre-Extraction - Automatically extract data BEFORE entering steps
  • Schema-First Extraction - Define data contracts with JSON Schema
  • Automatic Route Completion - Routes complete when required fields are collected
  • Smart Step Skipping - Skip steps whose data is already present
  • Always-On Routing - Context-aware routing between different flows

πŸ”§ Tools & Data Integration

  • Advanced Tool System - Context-aware tools with data access and lifecycle integration
  • Dynamic Tool Calling - AI can call tools during streaming responses
  • Tool Result Processing - Tools update context and collected data automatically

πŸ’Ύ Optional Persistence

  • Auto-Save - Automatically persist conversation data and progress
  • Extensible Adapters - Use built-in (Prisma, Redis, etc.) or create your own
  • Custom DB Support - Integrate with your existing database schemas

🎯 Session-Aware Routing

  • Always-On Routing - Users can change their mind mid-conversation
  • Context Awareness - Router sees current progress and collected data

πŸš€ Advanced Features

  • Streaming Responses - Real-time response generation with tool execution
  • Lifecycle Hooks - prepare/finalize functions or tools on steps, context/data update hooks
  • Sequential Steps - Define linear conversation flows with steps array
  • Route Transitions - Automatic flow transitions when routes complete
  • Smart Step Control - skipIf and requires for data-driven flow control

🎨 Behavioral Control

  • Guidelines & Rules - Define agent behavior patterns and restrictions
  • Route-Specific Logic - Different rules for different conversation contexts
  • Knowledge Base - Structured information available to AI during responses
  • Session Step - Track conversation progress across turns

πŸ“¦ Installation

# Using bun (recommended)
bun add @falai/agent

# Using npm
npm install @falai/agent

# Using yarn
yarn add @falai/agent

Requirements: Node.js 18+ or Bun 1.0+


πŸš€ Quick Start

Level 1: Your First Agent (30 seconds)

Create a minimal conversational agent:

import {
  Agent,
  GeminiProvider,
  createMessageEvent,
  EventSource,
} from "@falai/agent";

// Create your agent
const agent = new Agent({
  name: "Assistant",
  description: "A helpful assistant",
  provider: new GeminiProvider({
    apiKey: process.env.GEMINI_API_KEY!,
    model: "models/gemini-2.5-flash",
  }),
});

// Create a simple route with sequential steps
agent.createRoute({
  title: "General Help",
  description: "Answers user questions",
  when: ["User needs help or asks a question"],
  steps: [
    {
      id: "answer_question",
      description: "Answer the user's question helpfully",
      prompt: "Answer the user's question helpfully",
    },
  ],
});

// Start chatting - simple message-based API
const response = await agent.respond("What can you do?");

console.log(response.message);

That's it! You now have a working conversational AI agent.


🎯 Advanced Routing with ConditionTemplate

Flexible Route Conditions

Routes now support powerful condition patterns that combine AI context with programmatic logic:

// String-only conditions (AI context for routing decisions)
agent.createRoute({
  title: "Customer Support",
  when: "User needs help with their account",
  steps: [/* ... */]
});

// Function-only conditions (programmatic evaluation)
agent.createRoute({
  title: "Premium Features",
  when: (ctx) => ctx.data?.userType === 'premium',
  steps: [/* ... */]
});

// Mixed array conditions (AI context + programmatic logic)
agent.createRoute({
  title: "Booking Assistance",
  when: [
    "User wants to make a reservation", // AI context
    (ctx) => ctx.data?.isLoggedIn === true // Programmatic check
  ],
  steps: [/* ... */]
});

// Route skipIf - exclude routes dynamically
agent.createRoute({
  title: "Payment Processing",
  when: ["User wants to make a payment"],
  skipIf: [
    "Payment system is under maintenance", // AI context
    (ctx) => ctx.data?.paymentBlocked === true // Programmatic check
  ],
  steps: [/* ... */]
});

Enhanced Step Conditions

Steps support the same flexible condition patterns:

agent.createRoute({
  title: "Order Process",
  steps: [
    {
      id: "collect_items",
      when: "User wants to add items to cart",
      prompt: "What would you like to order?",
      collect: ["items"]
    },
    {
      id: "payment_step",
      when: [
        "Ready to process payment", // AI context
        (ctx) => ctx.data?.items?.length > 0 // Programmatic check
      ],
      skipIf: (ctx) => ctx.data?.paymentComplete === true,
      prompt: "Let's process your payment",
      tools: ["process_payment"]
    },
    {
      id: "confirmation",
      when: "Order is ready for confirmation",
      skipIf: [
        "Order already confirmed", // AI context
        (ctx) => ctx.data?.orderConfirmed === true // Programmatic check
      ],
      prompt: "Your order is confirmed!",
      finalize: "send_confirmation_email"
    }
  ]
});

Dynamic Guidelines

Guidelines now support flexible conditions for context-aware behavior:

// Add guidelines with mixed condition types
agent.addGuideline({
  title: "Premium User Support",
  condition: [
    "User is asking for help", // AI context
    (ctx) => ctx.data?.userType === 'premium' // Programmatic check
  ],
  content: "Provide priority support with detailed explanations and offer direct phone support."
});

agent.addGuideline({
  title: "Maintenance Mode",
  condition: "System maintenance is active",
  content: "Inform users about scheduled maintenance and provide estimated completion time."
});

// Function-only guideline for specific conditions
agent.addGuideline({
  title: "High Value Customer",
  condition: (ctx) => ctx.data?.totalSpent > 10000,
  content: "Offer VIP treatment and exclusive deals."
});

Key Benefits:

  • βœ… Hybrid Logic - Combine AI understanding with programmatic precision
  • βœ… Context Awareness - AI sees string conditions for better routing decisions
  • βœ… Performance - Functions execute first, strings only used when needed
  • βœ… Flexibility - Use simple strings, functions, or arrays as needed

πŸ”§ Advanced Step Configuration

Simple Tool Creation

Create tools with minimal boilerplate using the unified Tool interface:

// Create a simple tool with the unified interface
agent.addTool({
  id: "validate_user",
  name: "User Data Validator",
  description: "Validate user data before processing",
  parameters: { type: "object", properties: {} },
  handler: async ({ context, data, updateData }) => {
    // Validation logic with helper methods
    if (!data.email?.includes("@")) {
      throw new Error("Invalid email address");
    }
    
    // Mark as validated using helper method
    await updateData({ emailValidated: true });
    
    return "User validation completed successfully";
  },
});

// Use tools in conversation flows and step lifecycle
agent.createRoute({
  title: "User Registration",
  steps: [
    {
      id: "collect_info",
      description: "Collect user information",
      collect: ["name", "email"],
      prompt: "Please provide your name and email.",
      prepare: "validate_user", // Tool executes before AI response
      tools: ["validate_user"], // Tool available during conversation
    },
  ],
});

Benefits:

  • βœ… Simple API - Unified Tool interface with minimal complexity
  • βœ… Type Safety - Full TypeScript support with automatic inference
  • βœ… Flexible Returns - Return simple values or complex ToolResult objects
  • βœ… Helper Methods - Built-in context and data update utilities
  • βœ… Lifecycle Integration - Use tools as prepare/finalize hooks in steps

Level 2: Data Extraction (The Real Power)

Now let's build an agent that intelligently collects structured data:

import {
  Agent,
  OpenAIProvider,
  createMessageEvent,
  EventSource,
} from "@falai/agent";

// 1️⃣ Define the data you want to collect
interface HotelBookingData {
  hotelName: string;
  date: string;
  guests: number;
}

// 2️⃣ Create your agent with centralized data schema
const agent = new Agent<{}, HotelBookingData>({
  name: "BookingBot",
  description: "A hotel booking assistant that collects information.",
  provider: new OpenAIProvider({
    apiKey: process.env.OPENAI_API_KEY,
    model: "gpt-4", // or your preferred model
  }),
  
  // Agent-level schema defines all possible data fields
  schema: {
    type: "object",
    properties: {
      hotelName: { type: "string", description: "The name of the hotel." },
      date: { type: "string", description: "The desired booking date." },
      guests: { type: "number", description: "The number of guests." },
    },
    required: ["hotelName", "date", "guests"],
  },
  
  // Agent-level data validation and enrichment
  hooks: {
    onDataUpdate: async (data, previousData) => {
      // Auto-validate and enrich data
      if (data.guests && data.guests > 10) {
        throw new Error("Maximum 10 guests allowed");
      }
      return data;
    }
  }
});

// 3️⃣ Define a tool using the unified Tool interface
agent.addTool({
  id: "book_hotel",
  name: "Hotel Booking System",
  description: "Books a hotel once all information is collected.",
  parameters: { type: "object", properties: {} },
  handler: async ({ context, data, updateContext }) => {
    // Tool receives complete agent data with simplified context and helper methods
    const bookingId = await hotelAPI.createBooking({
      hotel: data.hotelName,
      date: data.date,
      guests: data.guests,
    });
    
    // Use helper method to update context
    await updateContext({
      lastBookingId: bookingId,
      lastBookingDate: new Date().toISOString(),
    });
    
    return `Booking confirmed! Confirmation #${bookingId} for ${data.guests} guests at ${data.hotelName} on ${data.date}`;
  },
});

// 4️⃣ Create a route with required fields specification
agent.createRoute({
  title: "Book Hotel",
  description: "Guides the user through the hotel booking process.",
  when: ["User wants to book a hotel"],
  requiredFields: ["hotelName", "date", "guests"], // Required for route completion
  
  // 5️⃣ Define the flow to collect data step-by-step
  steps: [
    {
      id: "ask_hotel",
      description: "Ask which hotel they want to book",
      prompt: "Which hotel would you like to book?",
      collect: ["hotelName"],
      skipIf: (data: Partial<HotelBookingData>) => !!data.hotelName,
    },
    {
      id: "ask_date",
      description: "Ask for the booking date",
      prompt: "What date would you like to book for?",
      collect: ["date"],
      requires: ["hotelName"], // Prerequisites from agent data
      skipIf: (data: Partial<HotelBookingData>) => !!data.date,
    },
    {
      id: "ask_guests",
      description: "Ask for the number of guests",
      prompt: "How many guests will be staying?",
      collect: ["guests"],
      requires: ["hotelName", "date"], // Prerequisites from agent data
      skipIf: (data: Partial<HotelBookingData>) => data.guests !== undefined,
    },
    {
      id: "confirm_booking",
      description: "Confirm and book the hotel",
      prompt: "Let me confirm your booking details.",
      tools: ["book_hotel"], // Reference tool by ID
      requires: ["hotelName", "date", "guests"],
    },
  ],
});

// 5️⃣ Start conversing - simple message API
const response = await agent.respond("I want to book a room at the Grand Hotel for 2 people.");

// The agent sees that `hotelName` and `guests` are provided,
// skips the first and third steps, and only asks for the date.
console.log(response.message);
// Expected: "What date would you like to book for?"

That's it! The data-driven agent will:

  • βœ… Understand the Goal - Route to the Book Hotel flow based on user intent.
  • βœ… Extract Known Data - Automatically pull hotelName and guests from the first message.
  • βœ… Skip Unneeded Steps - Use skipIf to bypass questions for data it already has.
  • βœ… Collect Missing Data - Intelligently ask only for the missing date.
  • βœ… Execute Deterministically - Call the bookHotel tool only when all required data is present.

This creates a flexible and natural conversation, guided by a clear data structure.

πŸ“– See more examples β†’ | Full tutorial β†’

⚑ Advanced Features

Streaming responses for real-time UX:

for await (const chunk of agent.respondStream("Hello")) {
  process.stdout.write(chunk.delta);
  if (chunk.done) {
    console.log("\nTool calls:", chunk.toolCalls);
  }
}

Automatic session management for multi-turn conversations:

// Server-side: Create agent with sessionId
const agent = new Agent({
  name: "Assistant",
  provider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
  persistence: { adapter: new PrismaAdapter({ prisma }) },
  sessionId: "user-123" // Automatically loads or creates session
});

// Simple conversation - no manual session management needed
const response = await agent.respond("Hello, how are you?");
console.log(response.message);
console.log(agent.session.id); // Session ID for client

Automatic session persistence with any adapter:

import { PrismaAdapter } from "@falai/agent";

// Server endpoint - sessions managed automatically
app.post('/chat', async (req, res) => {
  const { sessionId, message } = req.body;
  
  const agent = new Agent({
    name: "ChatBot",
    provider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
    persistence: { adapter: new PrismaAdapter({ prisma }) },
    sessionId // Automatically loads or creates this session
  });
  
  const response = await agent.respond(message);
  
  res.json({
    message: response.message,
    sessionId: agent.session.id, // Return session ID to client
    isComplete: response.isRouteComplete
  });
});

πŸ“– See full feature docs β†’


πŸ“š Documentation

πŸ“‹ Complete Documentation Index β†’ - Searchable index of all docs

πŸš€ Getting Started

πŸ—οΈ Core Framework

πŸ’¬ Conversation Flows

  • Routes - Route definition & lifecycle
  • Steps - Step transitions & logic

πŸ€– AI Integration

πŸ”§ Tools & Data

πŸ’Ύ Persistence

πŸš€ Advanced Guides


🎯 Examples - By Domain

πŸ—οΈ Core Concepts

Fundamental patterns every agent needs:

πŸ’¬ Conversation Flows

Building intelligent dialogue systems:

πŸ€– AI Providers

Integrating different AI services:

πŸ’Ύ Persistence

Session storage and data persistence:

πŸ”§ Tools

Tool creation and data manipulation:

πŸš€ Advanced Patterns

Complex use cases and integrations:

πŸ”— Integrations

External service integrations:

πŸ“– See all examples with detailed explanations β†’


πŸ—οΈ How It Works

@falai/agent uses a schema-first, pipeline-driven architecture with intelligent pre-extraction:

User Message + Session State
    ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. ROUTING + PRE-EXTRACTION             β”‚
β”‚    β€’ Evaluate routes (AI scoring)       β”‚
β”‚    β€’ Pre-extract data from message      β”‚
β”‚    β€’ Check route completion             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 2. SMART STEP SELECTION                 β”‚
β”‚    β€’ Filter steps (skipIf, requires)    β”‚
β”‚    β€’ Skip steps with existing data      β”‚
β”‚    β€’ Select optimal next step           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 3. RESPONSE GENERATION                  β”‚
β”‚    β€’ Build prompt with context          β”‚
β”‚    β€’ Generate AI response               β”‚
β”‚    β€’ Execute tools if needed            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 4. COMPLETION HANDLING                  β”‚
β”‚    β€’ Auto-complete when data collected  β”‚
β”‚    β€’ Exclude completed routes           β”‚
β”‚    β€’ Generate completion message        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    ↓
Response + Updated Session State

Key Principles:

βœ… AI decides: Route selection, data extraction, message generation, tool calling βœ… Code decides: Step flow control, route completion, lifecycle hooks, data validation βœ… Result: Efficient conversations that don't waste user time

What Makes It Smart:

🎯 Pre-Extraction - Data extracted BEFORE entering steps (no repeated questions) πŸš€ Auto-Completion - Routes complete automatically when required fields are collected πŸ”’ Completion Protection - Completed routes excluded from future selection ⚑ Smart Skipping - Steps bypassed if their data is already present

πŸ“– Read the detailed architecture β†’


🀝 Contributing

We welcome contributions! See our Contributing Guide for details on:

  • πŸ› Reporting bugs
  • πŸ’‘ Suggesting features
  • πŸ“ Improving documentation
  • πŸ”¨ Submitting pull requests

πŸŽ“ Inspired By

This framework draws inspiration from Parlant by Emcie Co., an excellent Python framework for conversational AI agents. We've adapted and enhanced these concepts for the TypeScript ecosystem with additional type safety and modern patterns.


πŸ“„ License

MIT Β© 2025


πŸš€ Ready to Build?

Choose your path:

πŸ‘Ά New to AI agents? β†’ Quick Start Guide πŸ—οΈ Building production app? β†’ Agent Architecture πŸ’‘ Have questions? β†’ Open a discussion


⭐ Star us on GitHub

Help us reach more developers building production AI!

Report Bug β€’ Request Feature β€’ Contribute

Made with ❀️ for the community

About

Build intelligent, conversational AI agents with TypeScript

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •