A local-first WhatsApp CRM dashboard with safe Nano Bots, manual approval, and per-contact AI memory.
ReplyWise helps you decide whether to reply, what to reply, when to reply, and whether it is safe to send.
Quick Start · Dashboard System · Nano Bots · Safety · Troubleshooting
ReplyWise Local is a local-first AI communication assistant for WhatsApp browser sessions, with optional Telegram and experimental WeChat support.
It is not just a chatbot that writes replies. It is designed as a CRM-style control center for personal or business messaging:
- Incoming chat inbox
- Per-contact memory
- AI reply suggestions
- Manual approval queue
- Auto-reply rules
- Smart routing
- Scheduled sends
- Logs and error monitor
- AI usage/cost visibility
- Safety guardrails before anything is sent
The main question ReplyWise answers is:
“Should I reply, and is it safe to send this reply to this exact contact?”
Most AI reply tools only answer:
“What should I reply?”
ReplyWise answers the more important questions first:
Should I reply?
Should I wait?
Should this be manual approval?
Is this a group message?
Is the contact blocked?
Is the AI mixing up contacts?
Is the reply safe to send?It analyzes timing, tone, emotional state, urgency, lead quality, group context, boundaries, and per-contact memory before suggesting or sending anything.
ReplyWise is designed to feel like an operational dashboard, not only a terminal bot.
| Section | Purpose |
|---|---|
| All Chats | Every private and group conversation |
| Unread | Chats that need attention |
| Groups | Group conversations with stricter rules |
| Mentions | Group messages that directly mention you |
| Starred | Important contacts or conversations |
| Blocked | Contacts where automation must not reply |
| Section | Purpose |
|---|---|
| AI Agents | Shows WhatsApp/Telegram/WeChat agent health |
| Auto Reply Rules | Per-contact and global auto-reply controls |
| Smart Routing | Routes leads, support, personal, group, spam, or unknown messages |
| Scheduled | Delayed replies waiting to be sent |
| Manual Approval | Drafts that need human review before sending |
| Section | Purpose |
|---|---|
| Leads | Lead score, stage, urgency, and intent |
| Analytics | Message volume, reply rate, confidence, errors, usage |
| Contact Memory | Style, language, tone, boundaries, and notes per contact |
| Section | Purpose |
|---|---|
| Settings | AI provider, auto-send, fallback, session, and privacy settings |
| Logs | Real system events, AI failures, safety blocks, and send status |
| Billing & Usage | Local AI/cloud usage counters and estimated cost, not payment billing |
ReplyWise is built around one powerful idea:
Different contact = different memory = different reply style.
The same message can produce different replies depending on who sent it.
| Contact | Style Memory | Example Reply Style |
|---|---|---|
| Ayesha | Roman Urdu, playful, light emojis | “Weekend ka plan abhi pending hai 😂 tumhara?” |
| Sara | Mature English, low emojis | “Nothing fixed yet. Probably a quiet weekend. What about you?” |
| Hina | Short, direct, busy | “Nothing fixed yet. You?” |
| Noor | Sarcastic, meme energy | “Survive, eat, repeat. Very ambitious plan 😂” |
This makes ReplyWise feel like a personal communication brain, not a generic chatbot.
ReplyWise should not let one big AI directly read a message and send a reply.
Instead, the system uses small Nano Bots. Each bot has one job, and only the Sender Bot can send messages.
WhatsApp Message
↓
Receiver Bot
↓
Identity Bot
↓
Triage Bot
↓
Memory Bot
↓
Reply Bot
↓
Safety Bot
↓
Approval Bot
↓
Sender Bot| Bot | Responsibility | Can Send? |
|---|---|---|
| Receiver Bot | Receives message and stores chatId, messageId, sender, text, timestamp | No |
| Identity Bot | Detects private/group chat, blocked status, mention status, known contact | No |
| Triage Bot | Classifies intent: greeting, lead, support, complaint, spam, personal, unknown | No |
| Memory Bot | Loads memory only for the same chatId |
No |
| Reply Bot | Generates a suggested reply | No |
| Safety Bot | Blocks unsafe, wrong-contact, rude, risky, or group-misbehaviour replies | No |
| Approval Bot | Decides auto-send vs manual approval | No |
| Sender Bot | Sends only after all checks pass | Yes |
Every message must carry its own isolated context:
{
"messageId": "wa_msg_123",
"chatId": "9198xxxxxx@c.us",
"contactName": "Raja",
"channel": "whatsapp",
"text": "Hi",
"receivedAt": "2026-05-28T18:00:00.000Z"
}Before sending, the Sender Bot must verify:
same chatId
same messageId or linked source message
single recipient only
contact is not blocked
reply is not empty
reply passed safety
reply was not already sentThis prevents dangerous bugs like:
one reply sent to all contacts
reply sent to wrong contact
same reply sent twice
AI mixing memory between contacts
group auto-reply without mention|
Every incoming message gets a structured decision: {
"decision": "reply_now | wait | no_reply | repair | end",
"confidence": 87,
"risk": "low | medium | high",
"reason": "They asked a warm open-ended question.",
"best_move": "Answer lightly and ask back.",
"avoid": "Do not over-flirt or write a long reply."
} |
ReplyWise remembers:
|
|
Voice messages can be transcribed before the reply pipeline runs. Supported options:
|
Group messages use stricter rules:
|
|
No Ollama required. ReplyWise can use:
If an API limit or provider error happens, it falls back safely. |
By default:
|
| Channel | Mode | Status |
|---|---|---|
whatsapp-web.js browser session |
Primary MVP channel | |
| Telegram | Playwright browser session | Secondary MVP channel |
| Playwright browser session / WeChat Web | Experimental |
WeChat support is included, but treat it as experimental until tested with your own WeChat Web session.
WhatsApp / Telegram / WeChat Web
↓
Browser Agent
↓
Incoming Message Ingest API
↓
Per-Contact Queue + Duplicate Guard
↓
Nano Bot Pipeline
↓
Should-I-Reply Decision
↓
Per-Contact Memory + Custom Persona
↓
Reply Generator
↓
Safety / Group Rules / Sender Guard
↓
Manual Approval Dashboard
↓
Outgoing Queue
↓
Browser Agent Claims One Pending Message
↓
Browser Agent Sends Through Web UIgit clone https://github.com/raja21068/ReplyWise-Local.git
cd ReplyWise-Local
npm installcp .env.example .envRecommended safe first-run .env:
PORT=3000
APP_BASE_URL=http://localhost:3000
AI_PROVIDER=local
AI_PROVIDER_CHAIN=local
ALLOW_AUTOSEND=false
DRY_RUN_SEND=true
ENABLED_AGENTS=whatsapp
BROWSER_HEADLESS=false
SESSION_DIR=./data/sessions
SCREENSHOT_ON_ERROR=false
LIVE_SCREENSHOT=false
OCR_ENABLED=falsenpm run devOpen:
http://localhost:3000npm run agent:whatsappScan the WhatsApp Web QR code, then test with one trusted contact first.
Use this before real auto-send:
1. Start dashboard with AI_PROVIDER=local and DRY_RUN_SEND=true
2. Start WhatsApp agent
3. Send one message from a trusted test contact
4. Confirm the message appears in All Chats
5. Confirm the Nano Bot pipeline creates a decision
6. Confirm the reply appears in Manual Approval
7. Approve/edit the reply
8. Confirm outgoing queue changes pending → sending → sent or dry-run sent
9. Send 3 quick messages from the same contact
10. Confirm they process one-by-one and do not get stuckSuccess means:
- Incoming message detected
- Contact isolated by
chatId - Decision created
- Reply suggestion shown
- Manual approval required by default
- Outgoing message queued once
- Browser agent sends only one claimed message
- No reply is sent to the wrong contact
For cloud AI with local fallback:
AI_PROVIDER=easy
AI_PROVIDER_CHAIN=gemini,openrouter,groq,local
GEMINI_API_KEY=
OPENROUTER_API_KEY=
GROQ_API_KEY=
MAX_CLOUD_CALLS_PER_DAY=200
DAILY_AI_BUDGET_USD=1.00
FALLBACK_TO_LOCAL_ON_LIMIT=true
ALLOW_AUTOSEND=false
DRY_RUN_SEND=trueFallback flow:
Try Gemini
↓ if no key / rate limit / error
Try OpenRouter
↓ if no key / rate limit / error
Try Groq
↓ if no key / rate limit / error
Use local safe fallbackThis is provider fallback, not quota abuse or key rotation.
ReplyWise can run without any cloud API key:
AI_PROVIDER=local
AI_PROVIDER_CHAIN=local
ALLOW_AUTOSEND=false
DRY_RUN_SEND=trueLocal mode still supports:
- Should-I-reply decisions
- Basic reply templates
- Energy matching
- Group rules
- Anti-cringe checks
- Manual approval dashboard
- Error and queue visibility
Group chats are not treated like private chats.
| Situation | Decision |
|---|---|
| Random group message, no mention | Usually no reply |
| Direct @mention | Short neutral reply allowed |
| Question to everyone | Optional short reply or manual approval |
| Flirty context in group | Block/avoid |
| Conflict in group | Calm repair or no reply |
| Unknown media/file in group | Review manually |
Recommended group rule:
If group message does not mention you and is not a direct reply to you, do not auto-send.Each contact can override the global persona.
Example:
Ayesha:
Reply in playful Roman Urdu, short messages, light emojis.
Do not over-flirt. Do not pressure during exams.This lets ReplyWise adapt to different people naturally.
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
Dashboard/API port |
APP_BASE_URL |
http://localhost:3000 |
Orchestrator URL used by agents |
AI_PROVIDER |
easy |
easy, local, gemini, openrouter, groq, or optional ollama |
AI_PROVIDER_CHAIN |
gemini,openrouter,groq,local |
Provider fallback order |
GEMINI_API_KEY |
empty | Optional Gemini key |
OPENROUTER_API_KEY |
empty | Optional OpenRouter key |
GROQ_API_KEY |
empty | Optional Groq key |
MAX_CLOUD_CALLS_PER_DAY |
200 |
Daily cap for cloud AI calls |
DAILY_AI_BUDGET_USD |
1.00 |
Soft budget shown in dashboard/status |
FALLBACK_TO_LOCAL_ON_LIMIT |
true |
Use local fallback on API limit/error |
ALLOW_AUTOSEND |
false |
Keep false unless intentionally enabling safe autopilot |
DRY_RUN_SEND |
true |
Recommended for first tests; simulates send without real delivery |
ENABLED_AGENTS |
whatsapp |
Example: whatsapp,telegram,wechat |
BROWSER_HEADLESS |
false |
Set true after login is stable |
SESSION_DIR |
./data/sessions |
Persistent browser session folder |
SCREENSHOT_ON_ERROR |
false |
Emergency debugging only |
LIVE_SCREENSHOT |
false |
Keep off in free-cost mode |
OCR_ENABLED |
false |
Keep off; not needed for normal reading |
TRANSCRIBE_ENABLED |
false |
Enable local voice transcription |
TRANSCRIBE_BACKEND |
auto |
auto, whisper_cpp, python_whisper, http, or command |
TRANSCRIBE_COMMAND |
empty | Custom transcription command |
TRANSCRIBE_HTTP_URL |
empty | Local transcription server URL |
BRIDGE_POLL_MS |
5000 |
Outgoing queue polling interval |
HEALTH_CHECK_INTERVAL |
60 |
Agent health interval in seconds |
The dashboard should be powered by real backend state, not static demo data.
Recommended API surface:
GET /api/state
GET /api/conversations
GET /api/messages/:contactId
GET /api/agents
GET /api/logs
GET /api/errors
GET /api/outgoing
POST /api/ingest
POST /api/reply/approve
POST /api/reply/skip
POST /api/contact/:id/autopilot
POST /api/contact/:id/block
POST /api/outgoing/claim
POST /api/outgoing/:id/sent
POST /api/outgoing/:id/failedAyesha · WhatsApp
"So what's your weekend plan?"
Decision:
✅ Reply now
Why:
She asked an open question and the tone is warm.
Best move:
Keep it light and ask back.
Avoid:
Do not over-flirt or write a long message.
Option 1:
"Nothing fixed yet, maybe food and rest. Tumhara kya scene hai?"
Option 2:
"Plan toh pending hai, agar koi acha idea mil gaya toh weekend bach jayega 😂"
Option 3:
"Weekend depends on company tbh 😄 tumhara kya plan?"
[Send] [Edit] [Wait] [Skip]npm run setup
npm run dev
npm run reset
npm run seed
npm run agents
npm run agent:whatsapp
npm run agent:telegram
npm run agent:wechat
npm run agent:all
npm run syntax
npm run style-test
npm run v7-test
npm run easy-test
npm test✅ Dashboard opens at http://localhost:3000
✅ All Chats, Unread, Groups, Mentions, Starred, Blocked sections appear
✅ AI Agents, Auto Reply Rules, Smart Routing, Scheduled, Manual Approval sections appear
✅ Leads, Analytics, Contact Memory sections appear
✅ Settings, Logs, Billing & Usage sections appear
✅ Incoming WhatsApp message creates exactly one stored message
✅ Same contact sending 3 quick messages does not stuck the system
✅ Outgoing queue uses pending → sending → sent / failed
✅ Same outgoing message cannot be claimed twice
✅ Sender Guard blocks missing or multi-recipient destination
✅ Group message without mention gives no-reply decision
✅ Direct group mention gives short neutral reply or manual approval
✅ Contact custom persona overrides global persona
✅ API provider error falls back to local safe mode
✅ AI error appears in dashboard Logs
✅ Audio-only message does not crash ingest pipelineThe decision object is being logged without formatting.
Expected readable log:
Processed — decision: reply_now 87% risk:low — They asked a warm question.Use a per-contact queue and process by chatId:
Raja queue: msg1 → msg2 → msg3
Amit queue: msg1 → msg2Never use a global currentChat, lastChatId, or lastReply for sending.
This is usually a shared-state or outgoing-claim bug.
Required protections:
one outgoing row per reply
single recipient only
claim pending message before sending
change pending → sending before delivery
Sender Bot checks original chatId
block if destination has multiple recipients
block if contact is blockedSwitch to local mode first:
AI_PROVIDER=local DRY_RUN_SEND=true npm run devThen check Logs in the dashboard before enabling cloud providers again.
ReplyWise is a human-in-the-loop communication assistant.
Do not use it for:
- Spam
- Harassment
- Manipulation
- Impersonation
- Fully autonomous messaging without review
- Bypassing platform enforcement
- Sending messages without user intent
Hard rules:
No auto-send by default.
No stealth/bypass logic.
No screenshot reading loop.
No OCR-based message reading.
No global currentChat/currentReply for sending.
No multi-recipient sends from one AI reply.
No reply after clear rejection or boundary.
No flirty or romantic replies in group chats.
No blind replies to audio/video/file messages without enough context.
Stop cloud AI calls when daily limit is reached.
Fallback to local safe mode when API providers fail.Browser automation may violate the terms of service of some platforms. Sessions can break, selectors can change, and accounts may face restrictions.
Use this project for personal experimentation and local prototyping only. Prefer read-only or manual-approval mode during testing. Use a secondary account where appropriate.
| Version | Focus |
|---|---|
| v0.1 | WhatsApp proof, dashboard, local decision engine |
| v0.2 | Telegram support |
| v0.2.5 | Experimental WeChat |
| v0.3 | Better memory, repair mode, feedback learning |
| v0.4 | Desktop app / local encrypted database |
| v0.5 | Easy AI mode, Gemini/OpenRouter/Groq fallback |
| v0.6 | Voice/media/group intelligence |
| v0.7 | Real CRM dashboard, Nano Bots, sender guard, queue safety |
Reliability and judgment are more important than channel count.
Before adding new platforms, improve:
- Decision quality
- Contact memory
- Safety rules
- WhatsApp reliability
- Telegram reliability
- WeChat experimental reliability
- Easy setup for non-technical users
- Voice/group/persona test coverage
- Dashboard logs and queue visibility
MIT License.
ReplyWise Local is an experimental local-first assistant. It is not affiliated with WhatsApp, Telegram, WeChat, Meta, Tencent, or any messaging platform. Use responsibly, respect privacy, and always remain the author of your own messages.


