# negoT8

> Two AI agents negotiate on behalf of two humans. The first consumer implementation of agent-to-agent communication.

**Live Demo:** https://negot8-peach.vercel.app  
**GitHub:** https://github.com/iamanirbanbasak/negot8  
**Telegram Bots:** [@Anirban_negoT8_Bot](https://t.me/Anirban_negoT8_Bot) · [@Anirban_negoT82_Bot](https://t.me/Anirban_negoT82_Bot)

---

## What is negoT8?

negoT8 gives every user a personal AI agent on Telegram. When two people need to coordinate anything — schedule a meeting, split expenses, negotiate a freelance deal, plan a trip — their **agents talk to each other autonomously** and deliver a resolution. No arguments, no awkwardness, no back-and-forth.

Every resolved agreement is silently anchored on the **Polygon Amoy blockchain** as immutable proof. Users never see the word "blockchain" — they just get a `🔗 Verified` badge.

| Without negoT8 | With negoT8 |
|---|---|
| 12 messages to schedule a coffee | Agents check both calendars, confirm in seconds |
| Awkward bill-splitting conversation | Agents negotiate the split, send UPI link |
| Haggling over a freelance rate | Agents benchmark market rates, agree terms, generate PDF |
| No record of what was agreed | Agreement hash anchored on Polygon, verifiable forever |

---

## Table of Contents

1. [Architecture](#architecture)
2. [The 8 Coordination Features](#the-8-coordination-features)
3. [Agent System](#agent-system)
4. [Agent Personality System](#agent-personality-system)
5. [Blockchain and On-Chain Proof](#blockchain-and-on-chain-proof)
6. [Add-On Features](#add-on-features)
7. [Tech Stack](#tech-stack)
8. [Project Structure](#project-structure)
9. [Quick Start](#quick-start)
10. [Environment Variables](#environment-variables)
11. [API Reference](#api-reference)
12. [Dashboard](#dashboard)
13. [Database Schema](#database-schema)
14. [How a Negotiation Works](#how-a-negotiation-works)
15. [Running the Project](#running-the-project)
16. [Testing](#testing)
17. [Key Design Decisions](#key-design-decisions)
18. [Hackathon Demo Script](#hackathon-demo-script)

---

## Architecture

```
User A (Telegram)              User B (Telegram)
       |                              |
       v                              v
Personal Agent A              Personal Agent B
(extracts preferences)        (extracts preferences)
       |                              |
       v                              v
Negotiator Agent A  <--JSON-->  Negotiator Agent B
(makes proposals)    rounds     (counters / accepts)
       |                              |
       +----------+  +----------------+
                  |  |
                  v  v
             Resolution
          - Telegram message
          - Voice note (ElevenLabs)
          - UPI payment link
          - PDF contract
          - Blockchain proof (Polygon)
          - Live dashboard update
```

Every feature uses the same agent pipeline. What changes per feature is the preference schema, proposal format, available tools, and resolution template. The agent system is built once and plugged in.

---

## The 8 Coordination Features

### 1. Meeting Scheduling

Agents negotiate times, durations, and locations. If a user has not specified available times, the agent automatically queries their **Google Calendar** (OAuth) for real free slots.

Example:
```
User A: "I want to meet Priya for coffee this week. I'm free mornings."

Meeting Scheduled!
Thursday, March 6 at 10:00 AM · 1 hour
Blue Tokai, Bandra
Agents agreed in 2 rounds.
```

### 2. Expense Splitting

Handles bill splitting with exact arithmetic from the **Calculator tool** — the LLM never does arithmetic. Detects UPI IDs from natural language and auto-generates tap-to-pay links.

Example:
```
User A: "Split the Goa trip — hotel 12,000, fuel 3,500. My UPI is anirban@upi"

Expenses Settled!
Hotel: 6,000 each · Fuel: 1,750 each
Rahul owes you 7,750
[Tap to Pay via UPI]
```

### 3. Freelancer and Client Negotiation

Scope, budget, timeline, upfront percentage, and IP terms. Uses **Tavily AI search** to benchmark real market rates before negotiation. Detects budget shortfalls automatically.

### 4. Roommate Decisions

Shared living decisions — WiFi plans, chore schedules, shared purchases, house rules.

### 5. Group Trip Planning

Multi-constraint coordination across dates, budget, destination, accommodation type, and activities.

### 6. Marketplace Negotiation

Buy/sell haggling, automated. Agents negotiate price, payment method, and delivery terms.

### 7. Collaborative Decisions

Joint choices — restaurants, movies, activities, gifts. Uses **Tavily search** to find options that simultaneously match both parties' preferences.

### 8. Conflict Resolution

Disputes, disagreements, resource-sharing conflicts. Agents use an empathetic mediation approach to find creative win-wins.

### Generic (Catch-All)

Any coordination that does not fit the above 8 categories. The Personal Agent classifies it as `generic` and negotiation proceeds normally. No request is ever rejected.

---

## Agent System

All agents are powered by **Gemini 2.0 Flash** via the same `BaseAgent` wrapper.

### Personal Agent

Receives a raw Telegram message and extracts structured preferences:

```json
{
  "feature_type": "expenses",
  "goal": "Split Goa trip costs fairly",
  "constraints": [
    { "type": "budget", "value": "max 10000", "hard": true }
  ],
  "preferences": [
    { "type": "split_method", "value": "equal", "priority": "medium" }
  ],
  "relationship": "friend",
  "tone": "friendly",
  "raw_details": {
    "expenses": [{ "name": "hotel", "amount": 12000 }],
    "upi_id": "anirban@upi"
  }
}
```

### Negotiator Agent

The core bargaining brain. Makes proposals, evaluates counter-proposals, and decides when to accept, counter, or escalate. Hard constraints are **never violated** — a proposal that satisfies all hard constraints is always accepted regardless of the satisfaction score.

Each Negotiator response:

```json
{
  "action": "counter",
  "proposal": {
    "summary": "55-45 fuel split, 50-50 everything else",
    "details": { "fuel_split": "55-45", "hotel_split": "50-50" }
  },
  "satisfaction_score": 72,
  "reasoning": "Conceding on fuel; hotel 50-50 is non-negotiable",
  "concessions_made": ["accepted 55-45 fuel split"],
  "concessions_requested": ["50-50 hotel split"]
}
```

Decision logic:

| Condition | Action |
|---|---|
| All hard constraints met | ACCEPT (always, overrides score) |
| Satisfaction >= 70 | ACCEPT |
| Satisfaction 40-69 | COUNTER |
| Satisfaction < 40 and round >= 3 | ESCALATE — presents 2-3 options to humans |

Maximum 7 rounds before forced escalation.

### Matching Agent

Scores how well a freelancer or applicant fits an open contract (0-100). Evaluates budget alignment, skill match, timeline overlap, and gap-bridging potential. Used in the open contract marketplace.

### Base Agent

Shared Gemini wrapper inherited by all agents. Always returns a plain Python dict. If the model wraps its response in markdown or adds surrounding text, the wrapper extracts the first valid JSON block. Never raises on parse failure.

---

## Agent Personality System

Users set their agent's negotiation style once with `/personality`. It persists and modifies every future negotiation.

```
/personality
[Aggressive] [Empathetic] [Analytical] [People Pleaser] [Balanced]
```

The selection is injected directly into the Negotiator Agent's system prompt:

**Aggressive** — Opens with ambitious proposals far in the user's favour. Concedes slowly in small increments. Uses anchoring to pull the other side toward its position.

**Empathetic** — Acknowledges the other side's concerns in every proposal. Offers concessions proactively on things the other side values more. Focuses on expanding the pie rather than dividing it.

**Analytical** — Backs every proposal with Tavily-sourced market data. Only concedes when presented with contradicting data. Frames all arguments with numbers.

**People Pleaser** — Prioritises relationship over outcome. Accepts at satisfaction 55+ (normally 70+). Resolves in 3 rounds or fewer when possible.

**Balanced (default)** — Moderate concession rate, matches the other side's pace. Targets 70+ satisfaction for both parties.

---

## Blockchain and On-Chain Proof

Every resolved negotiation is silently anchored on **Polygon Amoy TestNet**. If the chain is unavailable, the product still works fully — blockchain is additive, never blocking.

### Smart Contract

`AgreementRegistry.sol` deployed on Polygon Amoy:

```solidity
contract AgreementRegistry {
    struct Agreement {
        bytes32 agreementHash;   // SHA-256 of the resolution JSON
        string  featureType;
        string  summary;
        uint256 timestamp;
        address registeredBy;
    }

    mapping(string => Agreement) public agreements;

    function registerAgreement(
        string calldata negotiationId,
        bytes32 agreementHash,
        string calldata featureType,
        string calldata summary
    ) external;

    function getAgreement(string calldata negotiationId)
        external view returns (Agreement memory);

    function totalAgreements() external view returns (uint256);
}
```

### On-Chain Flow

```
Resolution JSON
    --> SHA-256 hash
        --> Polygon Amoy transaction
            --> TxHash stored in SQLite
            --> PolygonScan link sent in Telegram
            --> Verified badge shown on Dashboard
```

### Graceful Fallback

```python
try:
    proof = await register_on_chain(resolution)
    verify_url = f"https://amoy.polygonscan.com/tx/{proof['tx_hash']}"
except Exception:
    verify_url = None  # resolution still delivered, just without the proof link
```

What users see in Telegram:
```
Agreement secured on Polygon · View proof: amoy.polygonscan.com/tx/0xabc...
```

---

## Add-On Features

### Voice Summaries (ElevenLabs)

After every resolution a Telegram voice note is sent summarising the outcome. Feature-specific templates:

| Feature | Template |
|---|---|
| Expenses | "Expenses settled! After N rounds, X owes Y Z rupees." |
| Scheduling | "Meeting scheduled for DATE at TIME at LOCATION. Agreed in N rounds." |
| Freelance | "Project agreed! SCOPE for BUDGET rupees. First milestone payment ready via UPI." |
| Marketplace | "Deal done! ITEM for PRICE rupees. Payment link is ready." |

Each user can configure a different ElevenLabs voice ID for their agent.

### UPI Payment Deep Links

Generated automatically for any money-related resolution:

```
https://upi.link/payee@upi?amount=8750.00&cu=INR&remarks=Goa+trip+expenses
```

Sent as a Telegram inline button. Opens GPay, PhonePe, Paytm — any UPI app — with all fields pre-filled.

### Real-Time Analytics Dashboard

Live data streamed via Socket.IO:

- Satisfaction score curve per round for both parties (Recharts line graph)
- Concession timeline — who gave what up and in which round
- Fairness score — single balanced-outcome metric
- Feature type breakdown across all negotiations

### PDF Deal Agreements

For Freelance and Marketplace resolutions, a formatted PDF is generated via `fpdf2` and sent through Telegram. Includes party details, agreed terms, negotiation stats, and the blockchain proof hash. Deleted from server after delivery.

### Google Calendar Integration

```
/connectcalendar
    --> OAuth URL sent to user
        --> User authorises in browser
            --> Token stored in DB
                --> Scheduling agent auto-fetches free slots for next 7 days
```

Falls back gracefully if the token expires or Calendar is not connected.

### Open Contract Marketplace

Users post open contracts with `/postcontract`. Others apply with `/apply`. The Matching Agent scores each applicant (0-100) before the poster selects who to negotiate with.

### Tavily AI Search

Agents use Tavily for real-world grounding during negotiations:

- Restaurant discovery for collaborative decisions
- Market rate benchmarking for freelance deals
- Price comparison for marketplace negotiations

---

## Tech Stack

### Backend

| Package | Version | Purpose |
|---|---|---|
| fastapi | 0.128.8 | REST API and Socket.IO server |
| python-telegram-bot | 22.5 | Telegram bot (async) |
| google-generativeai | 0.8.6 | Gemini 2.0 Flash — all agents |
| aiosqlite | 0.22.1 | Async SQLite |
| web3 | 7.14.1 | Polygon Amoy blockchain |
| elevenlabs | 2.37.0 | Voice TTS |
| tavily-python | 0.7.22 | AI web search |
| fpdf2 | 2.8.3 | PDF generation |
| httpx | 0.28.1 | Async HTTP client |
| pydantic | 2.12.5 | Data validation |
| APScheduler | 3.11.2 | Background jobs |

### Frontend

| Package | Version | Purpose |
|---|---|---|
| next | 16.1.6 | React framework (App Router) |
| react | 19.2.3 | UI |
| recharts | 3.7.0 | Analytics charts |
| socket.io-client | 4.8.3 | Real-time updates |
| tailwindcss | 4 | Styling |
| lucide-react | 0.575.0 | Icons |

### External Services

| Service | Purpose | Free Tier |
|---|---|---|
| Gemini 2.0 Flash | All AI agents | 15 RPM, 1M TPM/day |
| ElevenLabs | Voice TTS | ~60K chars on $20 credit |
| Tavily | AI web search | 1,000 searches/month |
| Polygon Amoy | On-chain agreement proof | Free TestNet |
| Google Calendar API | Free slot lookup | Free OAuth |

---

## Project Structure

```
negot8/
├── backend/
│   ├── api.py                     # FastAPI app + Socket.IO server
│   ├── config.py                  # Env vars, API keys, voice IDs
│   ├── database.py                # SQLite schema + all queries
│   ├── run.py                     # Starts bots + API together
│   ├── serve.py                   # API server only
│   │
│   ├── agents/
│   │   ├── base_agent.py          # Gemini wrapper, always returns a dict
│   │   ├── personal_agent.py      # Plain English to structured preferences JSON
│   │   ├── negotiator_agent.py    # Bargaining brain with personality injection
│   │   ├── matching_agent.py      # 0-100 applicant scorer for contract marketplace
│   │   └── negotiation.py         # Multi-round loop + analytics tracking
│   │
│   ├── features/
│   │   ├── base_feature.py        # Base class: get_context() + format_resolution()
│   │   ├── scheduling.py          # + Google Calendar free-slot fallback
│   │   ├── expenses.py            # + pre-calculated amounts via Calculator tool
│   │   ├── freelance.py           # + Tavily market rate benchmarking
│   │   ├── roommate.py
│   │   ├── trip.py
│   │   ├── marketplace.py
│   │   ├── collaborative.py       # + Tavily place search
│   │   ├── conflict.py
│   │   └── generic.py             # Catch-all for any coordination type
│   │
│   ├── blockchain_web3/
│   │   ├── blockchain.py          # Polygon Amoy: hash, register, graceful fallback
│   │   └── contract_abi.py        # AgreementRegistry ABI
│   │
│   ├── tools/
│   │   ├── tavily_search.py       # AI search wrapper
│   │   ├── calculator.py          # Safe arithmetic, no LLM approximations
│   │   ├── upi_generator.py       # UPI deep link generator
│   │   ├── google_calendar.py     # OAuth + free slot fetching
│   │   └── pdf_generator.py       # Deal agreement PDF via fpdf2
│   │
│   ├── voice/
│   │   └── elevenlabs_tts.py      # TTS with feature-specific templates
│   │
│   ├── personality/
│   │   └── profiles.py            # 5 negotiation personality prompt modifiers
│   │
│   ├── protocol/
│   │   └── messages.py            # Pydantic message schemas
│   │
│   └── telegram-bots/
│       └── bot.py                 # All Telegram commands + conversation flows
│
├── contracts/
│   ├── AgreementRegistry.sol      # Solidity smart contract
│   └── deploy.py                  # Deployment script
│
├── dashboard/                     # Next.js 16 frontend
│   ├── app/
│   │   ├── page.tsx               # Landing page
│   │   ├── dashboard/page.tsx     # Live negotiations overview
│   │   ├── negotiation/[id]/      # Per-negotiation detail + analytics
│   │   ├── analytics/page.tsx     # Global analytics charts
│   │   └── history/page.tsx       # All past negotiations
│   ├── components/
│   │   ├── Sidebar.tsx
│   │   ├── NegotiationTimeline.tsx
│   │   ├── SatisfactionChart.tsx
│   │   ├── ConcessionTimeline.tsx
│   │   ├── FairnessScore.tsx
│   │   └── ResolutionCard.tsx
│   └── lib/
│       ├── api.ts                 # All API calls
│       ├── socket.ts              # Socket.IO client
│       ├── types.ts               # TypeScript types
│       └── utils.ts               # Formatters and helpers
│
├── test/
│   ├── test_apis.py               # Verify Gemini, Tavily, ElevenLabs keys
│   ├── test_negotiation.py        # Full negotiation engine test
│   ├── test_personal_agent.py     # Preference extraction test
│   ├── test_tools.py              # Tavily, UPI, Calculator
│   └── test_pdf_generator.py      # PDF generation test
│
├── docs/                          # Architecture guides
├── requirements.txt
├── .env.example
└── SETUP.md
```

---

## Quick Start

Requirements: Python 3.11+, Node.js 18+

```bash
# Clone
git clone https://github.com/iamanirbanbasak/negot8.git
cd negot8

# Backend
python3 -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate
pip install -r requirements.txt

# Frontend
cd dashboard && npm install && cd ..

# Configure
cp .env.example .env
# Fill in all values — see Environment Variables below

# Init database
cd backend
python3 -c "import asyncio, database as db; asyncio.run(db.init_db())"

# Run backend (Terminal 1)
python3 run.py

# Run frontend (Terminal 2)
cd ../dashboard && npm run dev
```

- Backend API: http://localhost:8000
- Dashboard: http://localhost:3000
- Swagger docs: http://localhost:8000/docs

---

## Environment Variables

Copy `.env.example` to `.env` and fill in every value:

```
# Telegram — create bots via @BotFather
TELEGRAM_BOT_TOKEN_A=
TELEGRAM_BOT_TOKEN_B=
TELEGRAM_BOT_TOKEN_C=               # optional, for 3-party demos

# AI
GEMINI_API_KEY=                     # https://aistudio.google.com/apikey

# Search
TAVILY_API_KEY=                     # https://app.tavily.com (free, no credit card)

# Voice
ELEVENLABS_API_KEY=                 # https://elevenlabs.io

# Blockchain — Polygon Amoy TestNet only, never use real funds
POLYGON_RPC_URL=https://rpc-amoy.polygon.technology/
POLYGON_PRIVATE_KEY=                # TestNet wallet private key
AGREEMENT_CONTRACT_ADDRESS=         # from contracts/deploy.py output

# Google Calendar OAuth
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=http://localhost:8000/api/auth/google/callback

# App
DATABASE_PATH=negot8.db
NEXT_PUBLIC_API_URL=http://localhost:8000
```

Blockchain is optional. Without `POLYGON_PRIVATE_KEY`, agreements are mocked and everything still works.

Get free TestNet MATIC from https://faucet.polygon.technology

---

## API Reference

Full interactive docs at http://localhost:8000/docs

### REST Endpoints

| Method | Endpoint | Description |
|---|---|---|
| GET | /api/stats | Totals, success rate, average rounds |
| GET | /api/negotiations | List all negotiations |
| GET | /api/negotiations/{id} | Full detail — rounds, analytics, blockchain proof |
| GET | /api/negotiations/{id}/rounds | All round proposals for a negotiation |
| GET | /api/analytics/{id} | Computed analytics for one negotiation |
| GET | /api/users/{telegram_id} | User profile and personality |
| GET | /api/auth/google/callback | Google Calendar OAuth callback |
| GET | /api/verify/{negotiation_id} | Blockchain proof lookup |

### Socket.IO Events (Server to Client)

| Event | Payload |
|---|---|
| negotiation_started | {negotiation_id, feature_type, participants} |
| round_update | {negotiation_id, round_number, action, proposal, satisfaction} |
| negotiation_resolved | {negotiation_id, resolution, blockchain_proof} |

---

## Dashboard

Built with Next.js 16 App Router, Tailwind CSS, Recharts, and Socket.IO.

**Pages:**

- `/` — Landing page with animated hero and live stat counters
- `/dashboard` — Real-time feed of all active and recent negotiations
- `/negotiation/[id]` — Per-negotiation view: round proposals, satisfaction chart, concession timeline, blockchain proof badge
- `/analytics` — Global charts: satisfaction trends, feature distribution, resolution rates
- `/history` — Searchable history of all past negotiations

**Key components:**

- `SatisfactionChart` — Recharts line graph of satisfaction per round for both parties
- `ConcessionTimeline` — Who gave what up and in which round
- `FairnessScore` — Single metric for how balanced the outcome was
- `NegotiationTimeline` — Full round-by-round proposal cards with action badges

---

## Database Schema

SQLite (`negot8.db`), 6 tables:

```sql
CREATE TABLE users (
    telegram_id     INTEGER PRIMARY KEY,
    username        TEXT,
    display_name    TEXT,
    personality     TEXT DEFAULT 'balanced',
    voice_id        TEXT,
    calendar_token  TEXT
);

CREATE TABLE negotiations (
    id               TEXT PRIMARY KEY,
    feature_type     TEXT,
    status           TEXT,    -- pending | active | resolved | escalated
    resolution       TEXT,    -- JSON
    blockchain_txid  TEXT,
    blockchain_hash  TEXT,
    created_at       TIMESTAMP
);

CREATE TABLE participants (
    negotiation_id   TEXT REFERENCES negotiations(id),
    user_id          INTEGER,
    preferences      TEXT,    -- JSON
    personality_used TEXT,
    PRIMARY KEY (negotiation_id, user_id)
);

CREATE TABLE rounds (
    id               INTEGER PRIMARY KEY AUTOINCREMENT,
    negotiation_id   TEXT REFERENCES negotiations(id),
    round_number     INTEGER,
    proposer_id      INTEGER,
    proposal         TEXT,    -- full Negotiator Agent JSON response
    response_type    TEXT,    -- accept | counter | escalate
    satisfaction_a   REAL,
    satisfaction_b   REAL,
    concessions_made TEXT,
    created_at       TIMESTAMP
);

CREATE TABLE negotiation_analytics (
    negotiation_id        TEXT PRIMARY KEY,
    satisfaction_timeline TEXT,    -- [{round, score_a, score_b}, ...]
    concession_log        TEXT,
    fairness_score        REAL,
    computed_at           TIMESTAMP
);

CREATE TABLE tool_calls (
    id              INTEGER PRIMARY KEY AUTOINCREMENT,
    negotiation_id  TEXT,
    tool_name       TEXT,
    input           TEXT,
    output          TEXT,
    called_at       TIMESTAMP
);
```

---

## How a Negotiation Works

Complete walkthrough for an expense split:

```
1.  User A  ->  /coordinate @rahul
2.  Bot     ->  "Tell me what you need"
3.  User A  ->  "Split Goa trip. Hotel 12,000, fuel 3,500. My UPI anirban@upi"
4.  PersonalAgent extracts structured preferences JSON
5.  Bot notifies Rahul: "Anirban wants to coordinate expenses with you"
6.  Rahul   ->  /pending  ->  accepts
7.  Rahul   ->  "I drove the whole way, fuel should be 60-40 in my favour"
8.  PersonalAgent extracts Rahul's preferences
9.  NegotiatorAgent A opens: "50-50 everything"  (satisfaction: 90)
10. NegotiatorAgent B evaluates: satisfaction 45  ->  COUNTER "fuel 60-40"
11. NegotiatorAgent A evaluates: concedes to 55-45 fuel  ->  satisfaction 78  ->  proposes
12. NegotiatorAgent B evaluates: satisfaction 82  ->  ACCEPT
13. Resolution sent to both users:
      - Telegram breakdown message
      - UPI payment link
      - Voice note summary
      - Blockchain proof registered on Polygon Amoy
14. Dashboard updates in real time via Socket.IO
```

Negotiation loop (simplified):

```python
for round_num in range(1, max_rounds + 1):
    if round_num == 1:
        response = await negotiator_a.generate_initial_proposal(preferences_a)
    elif round_num % 2 == 0:
        response = await negotiator_b.evaluate_and_respond(
            current_proposal, preferences_b, round_num
        )
    else:
        response = await negotiator_a.evaluate_and_respond(
            current_proposal, preferences_a, round_num
        )

    if response["action"] == "accept":
        break   # resolve and deliver
    elif response["action"] == "escalate":
        break   # present 2-3 options to humans
```

---

## Running the Project

```bash
# Backend: API server + Telegram bots together
cd backend
python3 run.py

# Backend: API server only (no bots)
python3 serve.py

# Frontend
cd dashboard
npm run dev

# Deploy smart contract (one-time setup)
cd contracts
python3 deploy.py
# Copy the printed address to AGREEMENT_CONTRACT_ADDRESS in .env
```

---

## Testing

```bash
# Verify all API keys work
cd backend
python3 ../test/test_apis.py
```

Expected output:
```
Testing Gemini...      OK {"status": "ok"}
Testing Tavily...      OK 5 results returned
Testing ElevenLabs...  OK test_voice.mp3 saved (32,480 bytes)
```

```bash
# Full negotiation engine test (prints each round)
python3 ../test/test_negotiation.py

# Preference extraction test
python3 ../test/test_personal_agent.py

# Tool tests: Tavily, UPI, Calculator
python3 ../test/test_tools.py

# PDF generation test
python3 ../test/test_pdf_generator.py
```

---

## Key Design Decisions

**Telegram over a custom app** — zero friction, everyone already has it, no signup required.

**SQLite over Postgres** — zero ops overhead for a hackathon; the data scale does not require it.

**Gemini Flash over GPT-4** — the free tier is genuinely usable at 15 RPM and 1M tokens/day with reliable JSON mode, which matters for a time-constrained build.

**Polygon Amoy over Algorand** — Solidity is widely understood, `web3.py` with `ExtraDataToPOAMiddleware` is rock solid, and the TestNet is fast and free.

**Graceful blockchain fallback** — the product must never break because of the chain. Every blockchain call is wrapped in try/except. Blockchain is additive.

**Hard constraint priority over satisfaction scores** — a proposal that meets someone's stated minimum or maximum is always acceptable. This prevents agents from nonsensically countering an offer that already satisfies every hard requirement.

**Calculator tool for all arithmetic** — amounts are pre-computed and injected into the negotiation context. The LLM never does arithmetic; it only reasons about the pre-verified numbers.

---

## Hackathon Demo Script

**Scene 1 — Expense Split (30 seconds)**

> "Rahul and Anirban just got back from Goa. Priya tells her agent she thinks fuel should be split differently. Rahul's agent instantly receives the counter. Two rounds, eight seconds. Resolution delivered to both phones simultaneously. UPI link pre-filled and ready to tap."

**Scene 2 — Freelance Deal (1 minute)**

> "Two AI agents just negotiated a 75,000 rupee React project. Budget, scope, timeline, upfront percentage, IP terms — all settled autonomously. The deal is now on the Polygon blockchain. Here is the PolygonScan link — this agreement is verifiable forever without trusting us."

**Scene 3 — Personality Clash (30 seconds)**

> "Watch an Aggressive agent negotiate against an Empathetic one. Aggressive anchors at 1,500 per hour and concedes slowly. Empathetic finds a creative add-on — extra features for slightly higher budget — that both sides actually prefer. That is not a compromise. That is a win-win the humans would never have found themselves."

---

## License

MIT — see LICENSE for details.
