Skip to content

Repository files navigation

OfferPilot

OfferPilot is a persistent AI negotiation backend built for the MongoDB Persistent Context Sprint Hackathon. It lets a voice agent identify a caller, recover an active negotiation, reason over policy and similar case memory, write durable checkpoints, and resume naturally after a dropped call.

The app runs as a Next.js API service with an in-browser demo console. It can run fully in seeded in-memory demo mode, or connect to MongoDB Atlas, Fireworks, and ElevenLabs when credentials are configured.

Highlights

  • Persistent caller identity and negotiation session recovery.
  • LangGraph negotiation flow with explicit checkpoint writes.
  • MongoDB collections for customers, cases, sessions, turns, offers, checkpoints, policy snippets, and case memories.
  • Atlas Search for policy retrieval.
  • Atlas Vector Search for similar resolved-case memory.
  • Fireworks-powered reasoning with deterministic fallback logic.
  • ElevenLabs text-to-speech and speech-to-text helper actions.
  • Local demo UI plus shell scripts for repeatable scenario walkthroughs.

Tech Stack

  • Next.js 16 and React 19
  • TypeScript
  • MongoDB Atlas
  • LangGraph
  • Fireworks via the OpenAI-compatible SDK
  • ElevenLabs voice APIs

Getting Started

Use Node.js >=22.0.0.

npm install
cp .env.example .env.local
npm run dev

Open http://localhost:3000 for the demo UI.

The app falls back to seeded in-memory data when MONGODB_URI is not set, so the local demo works before any cloud services are configured.

Environment Variables

Copy .env.example to .env.local and fill in only the services you want to enable.

MONGODB_URI=mongodb+srv://USERNAME:PASSWORD@CLUSTER.mongodb.net/?retryWrites=true&w=majority
MONGODB_DATABASE=offerpilot

FIREWORKS_API_KEY=
FIREWORKS_MODEL=accounts/fireworks/models/deepseek-v4-flash
FIREWORKS_EMBEDDING_MODEL=accounts/fireworks/models/qwen3-embedding-8b

ELEVENLABS_API_KEY=
ELEVENLABS_VOICE_ID=21m00Tcm4TlvDq8ikWAM

Never commit .env.local or real service credentials. The repository ignores local env files and keeps only the placeholder .env.example.

API

All actions are handled by:

POST /api/offerpilot

Health check:

GET /api/offerpilot

Identify Caller

{
  "action": "identify",
  "phone": "+14155550123"
}

Resume Caller

{
  "action": "resume",
  "phone": "+14155550123"
}

Customer Turn

{
  "action": "turn",
  "sessionId": "sess_demo",
  "text": "That $10 is too low. I missed dinner and this is not fair."
}

Mark Disconnect

{
  "action": "disconnect",
  "sessionId": "sess_demo"
}

Close Session

{
  "action": "close",
  "sessionId": "sess_demo",
  "accepted": true
}

ElevenLabs TTS

{
  "action": "tts",
  "text": "I can increase the offer to $25."
}

ElevenLabs STT

{
  "action": "stt",
  "audioBase64": "..."
}

MongoDB Schema

Default database:

offerpilot

Collections:

customers
cases
negotiation_sessions
conversation_turns
offer_events
agent_checkpoints
policy_snippets
case_memories

Core MongoDB usage:

  • customers: caller identity by phone number.
  • negotiation_sessions: active, interrupted, and closed negotiation state.
  • conversation_turns: immutable customer and agent transcript records.
  • offer_events: audit trail for offered, accepted, and max-reached events.
  • agent_checkpoints: durable LangGraph progress checkpoints.
  • policy_snippets: policy text retrieved with Atlas Search.
  • case_memories: similar outcomes retrieved with Atlas Vector Search.

Atlas Indexes

Create an Atlas Search index named policy_search on policy_snippets.

Suggested searchable fields:

text
tags
category

Create an Atlas Vector Search index named case_memory_vector on case_memories.

Suggested vector settings:

path: embedding
filter field: case_type

ElevenLabs Tool Mapping

Configure ElevenLabs webhook tools against POST /api/offerpilot.

Recommended tools:

identify_customer -> { action: "identify", phone }
resume_session -> { action: "resume", phone }
record_turn -> { action: "turn", sessionId, text }
calculate_next_offer -> { action: "turn", sessionId, text }
mark_session_disconnected -> { action: "disconnect", sessionId }
close_session -> { action: "close", sessionId, accepted }

Suggested voice agent guardrails:

You are OfferPilot, a calm and professional negotiation agent.
Never make an offer without calling the backend turn action.
Never exceed the maximum offer returned by the backend.
If resume_session returns prior context, acknowledge it naturally and continue.

Demo Scripts

Start the app locally, then run:

./scripts/demo-chat.sh
./scripts/demo-sentiments.sh

To point a script at a deployed app:

API_BASE=https://your-app.example.com ./scripts/demo-chat.sh

Build and Verify

npm run lint
npm run build

Deploy

Deploy as a standard Next.js app on Vercel or another Node-compatible host.

Set production environment variables in the host dashboard. Use this webhook URL for ElevenLabs:

https://YOUR_APP_DOMAIN/api/offerpilot

Repository Hygiene

Before pushing publicly:

  • Keep .env.local and other .env.* files untracked.
  • Commit .env.example with placeholders only.
  • Do not commit node_modules, .next, .wrangler, .vinext, dist, logs, or local hackathon notes.
  • Rotate any credentials that were ever stored locally before publishing the repository.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages