An AI-powered marketplace research assistant that helps you evaluate and compare online listings to identify the best deals.
Lookout combines a React frontend, FastAPI backend, and Google Gemini AI to provide intelligent analysis of marketplace listings (cars, laptops, electronics, etc.). The agent scores listings from 0-100, provides detailed rationales, asks clarifying questions, and learns your preferences over time.
- AI-Powered Evaluation: Get 0-100 scores and detailed rationales for each listing
- Smart Questions: Agent asks clarifying questions only when needed
- Preference Learning: System remembers your preferences across sessions
- Session Requirements: Capture must-have criteria once per session and let the agent enforce them
- Manual Re-evaluation: Re-run the agent on any listing with a single click when details change
- Listing Clarifications: View and answer one or more agent questions directly on each listing card
- Inline Editing: Update listing details/description at any time and the agent re-evaluates automatically
- Real-time Chat: Interactive conversation with the AI agent
- Session Management: Organize your searches by category
- Deal Quality Labels: Clear "horrible/poor/fair/good/great deal" indicators
┌─────────────┐ ┌──────────────┐ ┌────────────────┐
│ React UI │────▶│ FastAPI API │────▶│ Agent Interface│
│ (Vite) │ │ + SQLite │ │ + Gemini AI │
└─────────────┘ └──────────────┘ └────────────────┘
Components:
- Frontend: React + Vite (port 5173)
- Backend: FastAPI + SQLAlchemy (port 8000)
- Database: SQLite (file-based)
- AI: Google Gemini API
- Memory: Agent memory for preferences and session summaries
- Python 3.10-3.12 (recommended)
- Python 3.13 works but may have dependency compatibility issues
- Python 3.10, 3.11, or 3.12 recommended for best compatibility
- Node.js 18+
- Google Gemini API Key - Get one at https://makersuite.google.com/app/apikey
git clone <repository-url>
cd Lookout
# Run the setup script (installs dependencies, creates venv, initializes DB)
./setup.shEdit .env and add your Gemini API key:
GEMINI_API_KEY=your_actual_api_key_here# Start both backend and frontend
./start.shThe application will be available at:
- Frontend: http://localhost:5173
- Backend API: http://localhost:8000
- API Docs: http://localhost:8000/docs
- Navigate to http://localhost:5173
- Click "Sign up" and create an account
- You'll be automatically logged in
- Click "New Session"
- Give it a title (e.g., "Find a used Miata")
- Select a category (cars, laptops, electronics, etc.)
- Add your global requirements (e.g., "manual transmission, hardtop, under 50k miles") so the agent keeps them in mind for every listing
- Click "+ Add Listing"
- Enter listing details:
- Title (required): e.g., "2014 Mazda Miata Club"
- URL: Link to the listing
- Price: Listing price
- Currency: USD, EUR, GBP, etc.
- Marketplace: Where you found it
- Description: Paste the listing description/details so the agent can read it
- The agent automatically evaluates each new listing once you click "Add"
- Type a message like "Which of these is the best deal?"
- The agent will:
- Analyze all listings
- Assign scores (0-100) and quality labels
- Provide detailed rationales
- Ask clarifying questions if needed
Each listing shows:
- Deal Quality Badge: Horrible/Poor/Fair/Good/Great deal
- Score Visualization: 0-100 score with progress bar
- Rationale: Detailed explanation of the score
- Quick Actions: View listing, remove from consideration
- Clarifications: Any outstanding questions about that listing with inline answer forms
- Hover over the listing title and click the ⟳ button to ask the agent to re-check just that item
- The listing’s score and rationale refresh after the agent responds
- When the agent needs more info about a listing, the question appears under that listing’s card. The agent can ask multiple questions at once (one specific detail per question).
- Type your answers directly in the inline forms, in any order. The session resumes automatically once all blocking questions are answered.
- Click the “Edit” button on a listing card to adjust title, URL, price, marketplace, or the pasted description
- Saving changes automatically reruns the evaluation so scores and rationales stay current
- Start the backend so the database is initialized (
./start_backend.shor./start.sh) - Run
./demo.sh(or./demo.sh path/to/your.json) from the repo root to populate sessions/listings defined indemo.json - The script inserts sample users/sessions/listings and automatically runs the agent on each listing so you can explore the UI immediately
cd backend
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Create .env file
cp ../.env.example .env
# Edit .env and add your GEMINI_API_KEY
# Run backend
uvicorn main:app --reloadcd frontend
# Install dependencies
npm install
# Run frontend
npm run devLookout/
├── backend/ # FastAPI backend
│ ├── agent/ # Agent Interface (Gemini AI)
│ │ ├── service.py # Main agent orchestrator
│ │ ├── gemini_client.py # Gemini API client
│ │ ├── memory.py # Agent memory management
│ │ ├── prompts.py # Prompt engineering
│ │ └── schemas.py # Request/response models
│ ├── routes/ # API endpoints
│ │ ├── auth_routes.py
│ │ ├── session_routes.py
│ │ ├── listing_routes.py
│ │ ├── message_routes.py
│ │ └── agent_routes.py
│ ├── models.py # Database models
│ ├── crud.py # Database operations
│ ├── database.py # DB configuration
│ ├── auth.py # Authentication
│ ├── config.py # Settings
│ ├── main.py # FastAPI app
│ └── requirements.txt
├── frontend/ # React frontend
│ ├── src/
│ │ ├── pages/ # Page components
│ │ ├── context/ # React contexts
│ │ ├── services/ # API services
│ │ ├── App.jsx # Main app component
│ │ └── App.css # Styles
│ ├── package.json
│ └── vite.config.js
├── docs/ # Documentation
│ ├── lookout_design.md # Complete design specification
│ └── lookout_preliminary_ui.png
├── claude/ # Claude Code configuration
│ └── tasks.md # Implementation task breakdown
├── setup.sh # One-time setup script
├── start.sh # Launch full stack
├── .env.example # Environment template
├── CLAUDE.md # Claude Code guidance
├── changelog.md # Implementation progress
└── README.md # This file
POST /api/auth/signup- Create accountPOST /api/auth/login- LoginPOST /api/auth/logout- LogoutGET /api/auth/me- Get current user
POST /api/sessions- Create sessionGET /api/sessions- List user's sessionsGET /api/sessions/{id}- Get sessionDELETE /api/sessions/{id}- Delete sessionGET /api/sessions/{id}/state- Get complete session state
POST /api/sessions/{id}/listings- Add listingGET /api/sessions/{id}/listings- Get listingsPATCH /api/sessions/{id}/listings/{listing_id}- Mark removed
POST /api/sessions/{id}/messages- Send message (triggers agent)GET /api/sessions/{id}/messages- Get chat history
Listings are scored 0-100 and mapped to quality labels:
| Score | Label | Color |
|---|---|---|
| 81-100 | Great deal | Green |
| 61-80 | Good deal | Light Green |
| 41-60 | Fair deal | Yellow |
| 21-40 | Poor deal | Orange |
| 0-20 | Horrible deal | Red |
The AI agent can:
- Evaluate Listings: Analyze price, condition, features, and market value
- Ask Questions: Request clarification about priorities (e.g., "Is mileage or price more important?")
- Learn Preferences: Remember your priorities across conversations
- Provide Context: Explain scores with detailed rationales
- Compare Options: Highlight trade-offs between listings
If port 8000 or 5173 is already in use:
# Find and kill the process
lsof -ti:8000 | xargs kill -9
lsof -ti:5173 | xargs kill -9- Verify your API key in
.envandbackend/.env - Check API quotas at https://makersuite.google.com
- Ensure
GEMINI_API_KEYis set correctly
# Reset the database
rm backend/data/lookout.db
# Restart the backend - it will recreate the DB
cd backend
source venv/bin/activate
uvicorn main:app --reloadcd frontend
rm -rf node_modules package-lock.json
npm install
npm run devPython 3.13 Compatibility: If you encounter dependency installation errors with Python 3.13:
# Use Python 3.10-3.12 instead (recommended)
# Install pyenv to manage Python versions:
brew install pyenv
pyenv install 3.12.0
pyenv local 3.12.0
# Then re-run setup
./setup.shbcrypt/passlib Errors:
The project requires bcrypt==4.1.2 for compatibility with passlib. This is already specified in requirements.txt.
cd backend
./start_backend.shcd frontend
./start_frontend.shVisit http://localhost:8000/docs for interactive API documentation (Swagger UI).
The project includes 95 comprehensive tests covering all major functionality:
Backend Tests (46 tests):
cd backend
source venv/bin/activate
pytest
# Run with verbose output
pytest -v
# Run specific test file
pytest tests/test_crud.py
# Run specific test class
pytest tests/test_crud.py::TestUserCRUD
# Run with coverage report
pytest --cov=. --cov-report=htmlBackend Test Coverage:
- 19 CRUD unit tests
- 13 API integration tests
- 14 agent interface tests
Frontend Tests (49 tests):
cd frontend
npm test
# Run with UI
npm test -- --ui
# Run specific test file
npm test -- api.test.jsFrontend Test Coverage:
- 14 API service tests
- 7 AuthContext tests
- 7 LoginPage tests
- 8 SignupPage tests
- 13 SessionsPage tests
Total: 95 tests across full stack ✅
The system maintains two types of memory:
- User Preferences: Category-specific preferences (e.g., budget range, important factors)
- Session Summaries: Session requirements, top listings, open questions
Memory is stored in the agent_memory table and managed by the Agent Interface.
When the agent needs clarification:
- Session status changes to
WAITING_FOR_CLARIFICATION - Question is highlighted in the UI
- User's next message is treated as the answer
- Session returns to
ACTIVEstate - Agent continues with the answer in context
See claude/tasks.md for the complete task breakdown and docs/lookout_design.md for the detailed design specification.
MIT License - see LICENSE file for details.
For issues or questions:
- Check
docs/lookout_design.mdfor architecture details - Review
changelog.mdfor implementation notes - Check the troubleshooting section above
Built with Claude Code 🤖
Generated with assistance from Claude Code (claude.ai/code)