An AI-powered meeting scheduling system that autonomously calls participants, negotiates availability through natural conversation, and resolves conflicts to find the optimal meeting time.
- Create a Job — An organiser specifies participants, meeting duration, urgency, and a preferred time window
- AI Calls Participants — The system calls each participant (priority-ranked), engaging in natural conversation to determine availability
- Extracts Availability — LLM parses transcripts into structured time slots with confidence scores
- Resolves Conflicts — A 3-phase algorithm finds the best slot: strict overlap → max coverage → negotiation calls
- Confirms the Meeting — Final time is locked in and participants are notified
Frontend (Next.js) ←→ Backend (Express) ←→ PostgreSQL + Redis + LLM
│
┌──────────────┼──────────────┐
▼ ▼ ▼
BullMQ Worker Agent Chat Conflict Resolver
│ │
▼ ▼
Call Service Transcript Parser → Slot Mapper
(Simulator / Bolna)
Monorepo managed with Turborepo:
apps/web— Next.js 15 frontend with real-time dashboardapps/server— Express backend with BullMQ workerspackages/shared— Shared TypeScript types
| Layer | Technology |
|---|---|
| Frontend | Next.js 15, Tailwind CSS, Socket.io client |
| Backend | Express, TypeScript, BullMQ |
| Database | PostgreSQL (Prisma ORM) |
| Queue | Redis + BullMQ |
| Real-time | Socket.io |
| LLM | Ollama (qwen2.5:1.5b) |
| Call Provider | Simulator (dev) / Bolna (prod) |
- Node.js 20+
- PostgreSQL
- Redis
- Ollama with
qwen2.5:1.5bmodel pulled
# Install dependencies
npm install
# Copy env and configure
cp .env.example .env
# Push database schema
npm run db:push
# Generate Prisma client
npm run db:generate
# Start development
npm run devThe web UI runs on http://localhost:3001 and the API on http://localhost:3000.
With CALL_MODE=simulator, the system uses a chat-based call simulator at /dev/calls where you role-play as participants. The AI agent drives the conversation naturally, asking about availability and ending the call when it has enough information.
- Natural conversation — The AI agent handles vague responses like "after lunch" or "anytime Wednesday" and maps them to concrete time ranges
- Priority-based calling — Participants are ranked by priority, call history, and time-of-day appropriateness
- 3-phase conflict resolution — Finds optimal meeting times through intersection analysis and targeted negotiation
- Real-time dashboard — Live updates via WebSocket as calls progress and slots are collected
- Auto call termination — Agent intelligently ends calls when sufficient availability is gathered
# Start test server (separate DB + port)
npm run test:server
# In another terminal
npm run testTests use an isolated database (meeting_orchestrator_test) and never touch development data.
MIT