Skip to main content
An SDR agent that qualifies leads via WhatsApp, schedules callbacks when the lead asks (“call me tomorrow at noon”), and automatically follows up on leads that stopped responding. The agent uses identify() + Memory to resume conversations exactly where they left off — no context lost.

Project Structure

How It Works

Two scenarios, same agent:

Session Lifecycle

The agent controls the session status through tools. The developer never calls Memory.setStatus() manually — the tools do it:

Step 1: The Agent

agent.ts

Step 2: Tools That Control Session Status

The tools set the session status automatically — the LLM decides when to call them based on the conversation.

Qualify Lead

tools/qualify-lead.ts

Close Conversation

tools/close-conversation.ts

Step 3: The Entry Point

main.ts handles all entry points — regular messages, scheduled callbacks, and CRON follow-ups:
main.ts

Step 4: Scheduled Callback (Automatic)

When a lead says “me liga amanha meio dia”, the LLM calls create_schedule. Here’s what happens behind the scenes:
The developer writes zero extra code for this. The context capture and restoration is handled by the SDK and trigger engine.

Step 5: Inactive Lead Follow-up

For leads that stopped responding, create a CRON trigger in the portal that runs every 2 hours during business hours:
Then handle it in main.ts:
main.ts
No identify() in the loop. Since identify() sets a global singleton, calling it repeatedly in a loop would cause race conditions. Instead, pass entityType/entityValue directly in the agent.process() input — the agent resolves the memory key from the input fields.

Key Concepts

Tools Control Status, Not the Developer

The developer never calls Memory.setStatus() directly. The tools do it: Memory.list() then filters by status to find only active leads.

Memory Drives Everything

The entire follow-up system relies on identify() setting the right memory key. No external CRM needed for basic context — the conversation history IS the context.

Same Agent, Multiple Entry Points

The agent doesn’t need to know if it’s handling a live conversation, a scheduled callback, or a batch follow-up. The main.ts normalizes the input and the agent processes it the same way.

Next Steps

Schedule

Schedule tools reference and security guide

Memory

How memory and identify() work

Observability

Track lead qualification metrics

Multi-Agent

Supervisor pattern for complex routing