Skip to content

Atlas AI Chatbot

The Atlas chatbot is a property search assistant that lets users find investment properties through natural language. It enforces a strict 3-step workflow — extract filters → preview cost → execute — with confirmation gates between each step to avoid accidental credit usage.

Model

SettingValue
ModelGPT-5.2 (chat-model)
ProviderVercel AI SDK (@ai-sdk/openai)
StreamingServer-Sent Events (SSE), word-level chunking
Max duration60 seconds per request
Title modelGPT-5.2 (title-model, max 80 chars)
Reasoning modelGPT-5.2 extended thinking (chat-model-reasoning)

3-Step Workflow

The AI is instructed never to skip or reorder these steps:

AI Tools

analyzeSearchQuery — Step 1

Parses natural language into a structured filter object. Called first, before any credits are touched.

Inputs:

  • User message
  • Existing filters (if updating a previous search)

Supported filter categories:

CategoryExamples
Locationzip, city, county, state
Property typeresidential, commercial, vacant land, multi-family
Value rangemin/max estimated value
Ownershipowner-occupied, absentee, corporate, LLC
Equityequity %, LTV ratio
Buildingbeds, baths, sqft, pool, garage, year built
Motivation signalssale propensity score
Statusforeclosure, pre-foreclosure, tax-default, vacant
Quick listspreforeclosure, free-and-clear, high-equity, etc.
Result counthow many records the user wants

Output: Structured filter object + diff summary (what changed from previous search).


previewSearchCost — Step 2

Queries BatchData for a count without fetching full records. Shows the user how many results match and how many credits it will cost before charging anything.

Inputs: Filters, user ID

Output:

FieldDescription
totalCountTotal matching properties in BatchData
viewableHow many the user can actually view (limited by available credits)
creditsNeededTotal credits for all results
userFriendlyMessagePlain-text cost summary shown in chat

executePropertySearch — Step 3

Runs the actual search, deducts credits, and returns property records. Only called after explicit user confirmation.

Inputs: Confirmed filters, user ID, page, limit

Output: Properties array, credits used, remaining balance, pagination info.

The first 3 records in any search are free (preview). Credits are only charged for records beyond that.


Streaming Architecture

  • Endpoint: POST /api/chat
  • Format: SSE via JsonToSseTransformStream
  • Chunking: smoothStream({ chunking: "word" }) — streams word by word rather than token by token for better UX
  • Resumable streams: Optional Redis-backed stream resumption (if connection drops mid-response)

Context Injected Per Request

ContextSource
Full conversation historygetMessagesByChatId() → passed as convertToModelMessages()
Current search filtersChat.filters from DB
Filter versionChat.filterVersion — tracks filter changes across turns
User ID + roleSession (USER / ADMIN)
Credit balanceQueried before stream starts
Rate limit checkMessage count today vs. daily allowance

Rate Limits

RoleMessages / day
USER20
ADMIN100

Enforced at the /api/chat route before the stream starts. Returns an error message if exceeded.

Database

Chat

FieldPurpose
idMongoDB ObjectId
titleAuto-generated by title-model on first message
userIdOwner
filtersCurrent search filter state (Json)
filterVersionIncremented each time filters change
propertiesIdObjectIds of properties found in this session
messagesRelation to Message[]
streamsRelation to Stream[] (for resumable streams)

Message

FieldPurpose
chatIdParent chat
roleuser | assistant
partsJson — message content including tool call results
attachmentsJson — any file attachments
votesRelation — user thumbs up/down on messages

Voice

The chatbot supports two voice modes:

Realtime Voice (/api/chat/session)

  • Uses OpenAI Realtime API (gpt-4o-realtime-preview-2024-12-17)
  • Returns a client_secret for a WebRTC direct connection from the browser
  • Server-side VAD (voice activity detection) with 200ms silence threshold
  • Full duplex — audio streams both ways in real time

Fallback Voice Transcription (/api/chat/voice)

  • Accepts audio blobs: webm, wav, mpeg, mp4, aac, ogg
  • Transcribes using gpt-4o-mini-transcribe
  • Quality validation: minimum 2 words, rejects heavily repetitive output
  • Returns clean transcript or a rejection reason (user is prompted to retry)

System Prompt Rules

Key constraints enforced in the system prompt (property-prompts.ts):

  • Scope guard — Refuses non-real-estate questions
  • Step ordering — Must always call tools in order: analyze → preview → execute
  • No skipping — Cannot call executePropertySearch without first calling previewSearchCost
  • Confirmation gates — Waits for explicit user "yes" before advancing to the next step
  • No emojis — Text-only responses
  • Credit transparency — Always shows cost before charging
  • Filter diff — Summarizes what changed when filters are updated