An intelligent negotiation platform that uses AI agents to autonomously negotiate prices on behalf of buyers and sellers in a peer-to-peer marketplace.
DealScout enables realistic, human-like price negotiations between buyers and sellers using autonomous AI agents powered by Claude Sonnet 4.5. The system conducts multi-turn negotiations with natural conversation, market-aware pricing strategies, intelligent concessions, and LLM-powered database queries.
Key Features:
- 🤖 Autonomous AI agents (buyer and seller) that negotiate naturally
- 💬 Multi-turn conversational negotiation (up to 8 turns)
- 📊 Market-aware pricing using comparable listings
- 💰 Real-time offer generation with confidence scores
- 🔍 LLM-powered smart search with natural language queries
- 📈 Deal success tracking with savings calculation
- 🌐 Parallel multi-product negotiations with streaming updates
- 📱 Full-stack application with React frontend
HackNYU/
├── api_server.py # FastAPI server with SSE streaming
├── buyer_agent.py # Autonomous buyer agent
├── seller_agent.py # Autonomous seller agent
├── seed_db.py # MongoDB database seeding script
├── requirements.txt # Python dependencies
├── .env # Environment variables (not in repo)
├── .env.example # Example environment config
├── frontend/ # Next.js React application
│ ├── app/
│ │ ├── buyer/ # Buyer pages
│ │ ├── seller/ # Seller pages
│ │ └── page.tsx # Landing page
│ └── components/ # Reusable UI components
└── README.md # This file
Backend:
- Python 3.8+
- FastAPI with async/await
- MongoDB for data persistence
- Claude Sonnet 4.5 via OpenRouter API
- Server-Sent Events (SSE) for real-time streaming
Frontend:
- Next.js 14 (React)
- TypeScript
- Tailwind CSS
- Real-time streaming event handlers
Backend:
pip install -r requirements.txtFrontend:
cd frontend
npm installCreate a .env file in the project root:
OPENROUTER_API_KEY=your_api_key_here
MONGODB_URI=mongodb://localhost:27017
DATABASE_NAME=dealscout
Get your OpenRouter API key from OpenRouter.
# Create data directory
mkdir -p /tmp/mongodb_data
# Start MongoDB
mongod --dbpath /tmp/mongodb_data
# In another terminal, seed the database
python seed_db.pypython api_server.pyThe API server runs on http://localhost:8000
cd frontend
npm run devThe frontend runs on http://localhost:3000
- POST
/api/buyer/search- Search listings and run parallel AI negotiations- Stream-based (Server-Sent Events)
- Finds matching products
- Negotiates with all matching sellers
- Returns best deal recommendation
{
"search_query": "mountain bike under 1000",
"max_budget": 1000,
"top_n": 5
}status- Progress updates (searching, negotiating, analyzing)products_found- List of matching productsnegotiation_start- Negotiation started for a productnegotiation_message- Individual conversation messagesnegotiation_complete- Negotiation finished with resultbest_deal- Final recommendationerror- Any errors encountered
The search system uses an LLM to convert natural language queries into MongoDB filters:
- "mountain bike under 1000" → MongoDB query with regex and price constraints
- Handles product variations and synonyms
- Extracts price constraints automatically
- Falls back to simple regex if parsing fails
When searching:
- Search Phase: Use LLM-generated MongoDB queries to find matching products
- Negotiation Phase: Simultaneously negotiate with all found sellers
- Analysis Phase: Compare results and recommend best deal
- Streaming: Real-time updates to frontend via SSE
Buyer Agent (buyer_agent.py):
- Makes realistic incremental offers
- References platform data to justify prices
- Respects budget constraints
- Can accept, counter, reject, or walk away
- 30-second timeout to prevent hanging
Seller Agent (seller_agent.py):
- Responds strategically to buyer offers
- Enforces minimum acceptable price
- Adapts negotiation strategy by turn number
- Uses market data to defend asking price
- 30-second timeout to prevent hanging
Negotiation Orchestrator (api_server.py):
- Manages turn-based negotiation loop (up to 8 turns)
- Passes full context to each agent
- Handles deal completion and conflicts
- Formats and returns results with savings calculation
// Frontend example with streaming
const eventSource = new EventSource(
'http://localhost:8000/api/buyer/search',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
search_query: 'mountain bike under 1000',
max_budget: 1000,
top_n: 5
})
}
);
eventSource.addEventListener('products_found', (event) => {
const products = JSON.parse(event.data).data;
console.log('Found products:', products);
});
eventSource.addEventListener('negotiation_complete', (event) => {
const result = JSON.parse(event.data).result;
console.log('Negotiation result:', result);
});
eventSource.addEventListener('best_deal', (event) => {
const best = JSON.parse(event.data).data;
console.log('Best deal:', best);
});{
"seller_id": "seller_001",
"item_id": "bike_001",
"product_detail": "Trek X-Caliber 8 Mountain Bike 27.5\" 2022",
"description": "Well-maintained mountain bike with disc brakes and suspension",
"category": "Sports & Outdoors",
"asking_price": 850,
"min_selling_price": 750,
"condition": "good",
"location": "New York, NY",
"zip_code": "10001",
"extras": ["helmet", "lock"],
"created_at": "2025-11-16T04:11:01.027Z",
"updated_at": "2025-11-16T04:11:01.027Z",
"status": "active"
}- Issue: MongoDB datetime objects not serializable to JSON
- Solution: Convert to ISO format strings (lines 1099-1102 in api_server.py)
- Issue: When finding multiple products, only 1 would negotiate
- Solution: Completely reimplemented negotiation loop with:
- Explicit index-based iteration
- Comprehensive error handling per product
- Guaranteed result collection for all products
- Continue-on-error logic to process remaining items
- Issue: Indefinite hanging on API calls
- Solution: Added 30-second timeout to all HTTP requests in buyer_agent.py and seller_agent.py
OPENROUTER_API_KEY # Required: Claude API access
MONGODB_URI # MongoDB connection string (default: mongodb://localhost:27017)
DATABASE_NAME # Database name (default: dealscout)
PORT # Server port (default: 8000)Modify in api_server.py:
MAX_TURNS: Maximum negotiation turns (default: 8)- Buyer budget override in request
- Seller minimum/asking prices from database
- User enters natural language query: "mountain bike under 1000"
- LLM converts to MongoDB filter:
{"product_detail": {"$regex": "bike"}, "asking_price": {"$lte": 1000}} - Search returns all matching products (e.g., 3 mountain bikes)
- Frontend receives product list via SSE
For each found product:
- Initialize buyer/seller preferences and market data
- Run negotiation loop (alternating turns):
- Turn 1: Buyer makes initial offer
- Turn 2: Seller responds
- Continue until deal reached or max turns
- Return result with final price and savings
- Compare all negotiation results
- Calculate best deal (highest savings or fairest price)
- Stream final recommendation to frontend
Test with sample data:
# Seed database with 6 test products
python seed_db.py
# Test search with one product
curl -X POST http://localhost:8000/api/buyer/search \
-H "Content-Type: application/json" \
-d '{"search_query": "macbook", "max_budget": 1000}'
# Test with multiple products
curl -X POST http://localhost:8000/api/buyer/search \
-H "Content-Type: application/json" \
-d '{"search_query": "bike under 1000", "max_budget": 1000}'Sample products in database:
- 3 Mountain Bikes (Trek, Giant, Specialized) - $750-$920
- 3 Electronics (MacBook Air, PS5, iPad) - $450-$950
- Streaming: SSE for real-time updates without polling
- Rate Limiting: 0.5s delay between negotiations to prevent API throttling
- Error Resilience: Comprehensive error handling to continue processing remaining items
- Async/Await: Non-blocking I/O in FastAPI
- Real-time WebSocket instead of SSE
- Negotiation history and analytics
- User authentication and profiles
- Payment integration
- Email notifications
- Advanced search filters
- Seller dashboard with analytics
- Multi-language support
# Find process using port 8000
lsof -i :8000
# Kill it
kill -9 <PID># Check if MongoDB is running
mongod --version
# Start MongoDB
mongod --dbpath /tmp/mongodb_data- Verify
OPENROUTER_API_KEYin.env - Get new key from OpenRouter
- Restart API server after updating
- Check database is seeded:
python seed_db.py - Try simpler search: "bike" instead of specific model
- Check product data in MongoDB:
mongosh
MIT License - Feel free to use and modify for your projects
Contributions welcome! Areas for improvement:
- Additional marketplace features
- Agent prompt optimization
- Performance improvements
- Bug fixes and reliability enhancements
For issues or questions:
- Check
.envhas validOPENROUTER_API_KEY - Verify MongoDB is running:
mongod --dbpath /tmp/mongodb_data - Run
python seed_db.pyto populate database - Check API logs for detailed error messages
Built with ❤️ for HackNYU 2024