Quote-Battle Agent is a facilities-maintenance quoting autopilot. Every quoting tool tells you what you should charge; this one also works out what the client is willing to pay, writes a justification they can say yes to, and then war-games how they'll push back — before you walk into the room. Thesis: AI preps the fight. You close it.

What it does

A work order comes in — often half-articulated ("walk-in fridge down, store losing cold chain"). Two-anchor pricing: a market going-rate floor × this client's willingness-to-pay ceiling, inferred from their own deal history — plus a client-facing justification.

🔶 Gate 1: a human approves / adjusts the price. Self-play battle rehearsal: a client agent attacks the price, a contractor agent defends it, turn by turn on screen — then distilled into a negotiation battle card.

🔶 Gate 2: the human keeps the lines worth keeping. Two memory loops: every outcome (won / lost + why) writes back to price the next quote; every kept play distills into a reusable playbook that briefs the next rehearsal.

The two approval gates aren't a UX afterthought — they're the architecture: the AI runs the rehearsal, a human makes every decision where money changes hands.

How it's built

Next.js, no agent framework — staged API calls with a human gate between stages (that round-trip is the thesis, in code). Qwen via the OpenAI-compatible DashScope endpoint, routed by task: qwen3.6-flash with thinking off where a human waits on streamed tokens (first token ~1.2s), qwen3.7-plus with thinking on for background playbook distillation. Native JSON mode + SSE streaming. PolarDB for PostgreSQL (Alibaba Cloud) holds history, frozen quote snapshots, and the playbook. Deployed on Alibaba Cloud Function Compute (custom Node.js runtime, us-west-1) — see the separate deployment-proof video.

Production-readiness (not a toy demo)

Frozen quotes: every quote is frozen to the DB — reopening returns the exact same price (measured drift without it: up to 18.8% on the same order). Tolerant streaming-JSON parser, fuzz-tested against 1,168 truncation points. Outcome write-back enforces three invariants; the "N deals, M won, why" line is computed from DB rows, never generated — the LLM is removed exactly where a wrong number would be a lie. npm run eval:pricing: 24/24 valid JSON, 24/24 prices inside the two anchors.

Data 100% synthetic — fictional clients, fictional prices. The problem is real; the data never was.

Built With

Share this project:

Updates