Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.heylua.ai/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Real estate agent assistant integrating with MLS (Multiple Listing Service) API and Lua Data API for enhanced property search. What it does:
  • Search properties via MLS API
  • Save favorite properties
  • Schedule viewings
  • Compare properties
  • Get neighborhood info
APIs used: External MLS API + Lua Data API

Complete Implementation

src/index.ts

import { LuaAgent, LuaSkill } from "lua-cli";
import {
  SearchPropertiesTool,
  GetPropertyDetailsTool,
  ScheduleViewingTool,
  SaveFavoriteTool,
  ComparePropertiesTool
} from "./tools/RealEstateTools";

// Real estate skill
const realEstateSkill = new LuaSkill({
  name: "real-estate-assistant",
  description: "Real estate search and showing scheduler",
  context: `
    This skill helps clients search and view properties.
    
    - search_properties: Search MLS for properties matching criteria
    - get_property_details: Get full details for a specific property
    - schedule_viewing: Book property showing appointment
    - save_favorite: Save property to client's favorites
    - compare_properties: Compare multiple properties side by side
    
    Always ask about budget, location preferences, and must-haves.
    Highlight unique features of properties.
    Be enthusiastic and professional.
  `,
  tools: [
    new SearchPropertiesTool(),
    new GetPropertyDetailsTool(),
    new ScheduleViewingTool(),
    new SaveFavoriteTool(),
    new ComparePropertiesTool()
  ]
});

// Configure agent (v3.0.0)
export const agent = new LuaAgent({
  name: "real-estate-assistant",
  
  persona: `You are an experienced and enthusiastic real estate agent.
  
Your role:
- Help clients find their dream home
- Search MLS listings based on preferences
- Schedule property viewings
- Provide market insights
- Guide through the home-buying process

Communication style:
- Enthusiastic and positive
- Professional and knowledgeable
- Patient and understanding
- Detail-oriented
- Market-savvy

Best practices:
- Always ask about budget and location preferences
- Inquire about must-have features vs nice-to-haves
- Highlight unique property features
- Provide honest market assessments
- Suggest neighborhoods that match lifestyle
- Offer to schedule viewings immediately

When to escalate:
- Making offers (requires human agent)
- Legal questions (refer to attorney)
- Complex financing (refer to mortgage specialist)
- Commercial properties (different department)`,

  
  skills: [realEstateSkill]
});
v3.0.0 Pattern: This demo now uses LuaAgent to configure the agent’s persona, welcome message, and skills.

Tools Implementation

import { LuaTool, Data, env } from "lua-cli";
import { z } from "zod";

// 1. Search Properties (External MLS API)
export class SearchPropertiesTool implements LuaTool {
  name = "search_properties";
  description = "Search real estate listings";
  
  inputSchema = z.object({
    location: z.string(),
    minPrice: z.number().optional(),
    maxPrice: z.number().optional(),
    bedrooms: z.number().optional(),
    propertyType: z.enum(['house', 'condo', 'apartment', 'townhouse']).optional()
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    const mlsApiKey = env('MLS_API_KEY');
    
    // Call MLS API
    const response = await fetch('https://api.mlslistings.com/api/v1/search', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${mlsApiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        location: input.location,
        price_min: input.minPrice,
        price_max: input.maxPrice,
        bedrooms: input.bedrooms,
        property_type: input.propertyType
      })
    });
    
    const data = await response.json();
    
    // Save to Lua Data for vector search capabilities
    for (const property of data.listings) {
      const searchText = `${property.address} ${property.city} ${property.description} ${property.features.join(' ')}`;
      await Data.create('property_cache', property, searchText);
    }
    
    return {
      properties: data.listings.map(p => ({
        id: p.mls_id,
        address: p.address,
        city: p.city,
        price: `$${p.price.toLocaleString()}`,
        bedrooms: p.bedrooms,
        bathrooms: p.bathrooms,
        sqft: p.square_feet,
        type: p.property_type,
        description: p.description.substring(0, 150) + '...'
      })),
      count: data.listings.length
    };
  }
}

// 2. Save Favorite (Lua Data)
export class SaveFavoriteTool implements LuaTool {
  name = "save_favorite";
  description = "Save a property to favorites";
  
  inputSchema = z.object({
    mlsId: z.string(),
    notes: z.string().optional()
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    await Data.create('favorites', {
      mlsId: input.mlsId,
      notes: input.notes,
      savedAt: new Date().toISOString()
    });
    
    return {
      success: true,
      message: "Property saved to favorites"
    };
  }
}

// 3. Schedule Viewing
export class ScheduleViewingTool implements LuaTool {
  name = "schedule_viewing";
  description = "Schedule a property viewing";
  
  inputSchema = z.object({
    mlsId: z.string(),
    date: z.string(),
    time: z.string(),
    clientName: z.string(),
    clientEmail: z.string().email(),
    clientPhone: z.string()
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    const viewing = await Data.create('viewings', {
      ...input,
      status: 'scheduled',
      createdAt: new Date().toISOString()
    });
    
    return {
      success: true,
      viewingId: viewing.id,
      message: `Viewing scheduled for ${input.date} at ${input.time}`
    };
  }
}

Environment Setup

# .env
MLS_API_KEY=your_mls_api_key
MLS_API_URL=https://api.mlslistings.com

Key Features

External MLS

Real MLS property data

Vector Search

Semantic property search