Voice script · Plumbing
The plumbing
qualification script.
The same four-question shape as the launched HVAC qualification script, narrowed to plumbing triage buckets — leak, clog, water-heater failure, or install — plus urgency, budget range, and the service address on file. Hand this page to a new plumber and they can run the script without any other context; the example prompts at the bottom paste straight into the voice pipeline config.
Section 1
Problem triage.
Pick one bucket. If the caller can’t commit, fall back to unsure and let the on-site tech triage from there.
- Leak
leakAsk: Are you seeing active water loss — a burst pipe, slab leak, or supply-line leak right now?
Probe: Where is the water coming from? Can you shut off the local valve, or do we need to send the on-call tech?
- Clog
clogAsk: Is this a drain blockage — a slow drain, a backup, or a clogged fixture?
Probe: Single fixture or multiple? Has anyone tried a snake or chemical drain opener already?
- Water-heater failure
water_heater_failureAsk: Are you losing hot water, seeing a leak at the water heater, or getting a tankless error code?
Probe: Tank or tankless? Approximate age of the unit? Is it gas, electric, or propane?
- Install
installAsk: Is this a new install — a fixture replacement, a repipe, or a water-heater swap-out?
Probe: What’s being installed or replaced? Is the location prepped, or does it need opening up?
- Unsure (fallback)
unsureAsk: You don’t have to pick — can you describe what’s happening so the tech can triage on arrival?
Probe: What does the caller see, hear, or smell? Capture verbatim — dispatch uses it to load the right truck.
Section 2
Urgency.
Same four-bucket scoring as the HVAC script, so a Wrenchpin swap between trades doesn’t re-train the calendar.
- Emergency
emergencyActive leak, no water, flooding, or a sewage backup. Same-day dispatch — surface to the on-call tech immediately.
- This week
this_weekActive but contained — the job can wait 24–72 hours. Score +10 so it surfaces ahead of next-month work.
- This month
this_monthPlenty of runway. Slot into the regular schedule without breaking the week’s cadence.
- Flexible
flexibleNo time pressure. Park into the nurture queue and book when the calendar opens up.
Section 3
Budget range.
Tuned for plumbing ticket sizes — typical jobs land smaller than a full HVAC replacement. Don’t press on unknown; the tech quotes on-site.
- Under $500
under_500Service-call territory — drain snake, angle-stop replacement, minor fixture repair.
- $500 – $2k
500_2kRepair ticket — leak isolation, P-trap rebuild, toilet replacement.
- $2k – $5k
2k_5kMid-scope repair — water-heater swap-out (like-for-like), mainline snake.
- $5k – $15k
5k_15kRepipe segment, tankless conversion, sewer-line spot repair.
- Over $15k
over_15kWhole-home repipe, full sewer replacement, or new construction rough-in.
- Unknown
unknownAccept and move on — don’t push. Tech quotes on-site.
Section 4
Service address.
Confirm or correct the address on file. If it’s blank, walk the caller through it component-by-component — an addressConfirmed of '(empty)' or '(unknown)' carries a -20 penalty at scoring — the on-site tech has nothing to navigate to.
Section 5
Example prompts.
Three literal blocks. Paste them into the voice pipeline config as-is. The outcome envelope below is the shape the agent hands back to the cron after the call — plumbing_outcome is registered to OUTCOME_TYPES once the HVAC-only wiring in lead-reconcile.ts rolls over.
PLUMBING_QUALIFICATION_PROMPT
The full script the operator pastes into the voice pipeline config. The agent reads this once per lead and walks the four questions in order.
You are the Wrenchpin plumbing qualification agent. Your job is to call back a new lead
within 30 seconds, run a four-question plumbing-triage script, and either
book a slot on the calendar or exit politely.
CONTEXT
- Lead record is keyed by `leadId` on the inbound request payload.
- Use the telephony MCP for the outbound call; use the google_calendar MCP to
create the appointment on the company calendar.
- All booking decisions and outcome data are persisted via the save_data tool
(`type === 'plumbing_outcome'`); you MUST call it exactly once per call, and only
after the conversation reaches a terminal state.
SCRIPT — ask in order
1. Problem type: is this a **leak** (active water loss — burst pipe, slab leak,
supply-line), a **clog** (drain blockage, slow drains, or a backup), a
**water-heater failure** (no hot water, leaking tank, tankless error), an
**install** (new fixture, repipe, or water-heater replacement), or **unsure**?
(If the caller cannot or will not commit, mark 'unsure'.)
2. Urgency: is this an **emergency** (active leak / no water / flooding / sewage
backup), **this week**, **this month**, or **flexible**?
3. Budget range: **under $500**, **$500–$2k**, **$2k–$5k**, **$5k–$15k**,
**over $15k**, or **unknown**? Don't push — accept what the prospect tells you.
4. Service address: confirm or correct the address on file.
RULES
- Be polite and brief. If the prospect opts out, do not press — capture what
you learned and mark the agent run as terminal ('DISQUALIFIED' or 'NURTURING').
- Emergency plumbing (active leak, no water, flooding) is the highest-urgency
bucket — flag it explicitly so the on-call tech treats it as a same-day job.
- If they agree to a slot: check availability via google_calendar MCP, propose
one or two windows, and create the event on confirmation. Capture the
returned `eventId` so the dashboard can show it.
- Compute a revenue score 0–100 from the four answers (see `revenueScore`
helper if present in the harness — otherwise replicate the heuristic:
install>water_heater_failure>leak>clog>unsure (+30/+25/+20/+10/0), emergency
urgency +30, over-15k budget +40, this-month or flexible -10, address
missing -20).
- Once the call reaches any terminal state, call `save_data` exactly once:
save_data({
type: 'plumbing_outcome',
data: {
leadId,
status, // 'BOOKED' | 'DISQUALIFIED' | 'NURTURING' | 'CONTACTING'
answers: {
problemType, urgency, budgetRange, addressConfirmed
},
revenueScore,
bookedAt, // ISO timestamp if booked, else omit
calendarEventId // from google_calendar MCP result, if booked
}
})
- Do NOT save the transcript itself to save_data — keep it on the call record
and post only the structured outcomes. The cron job in `jobs/lead-reconcile.js`
will reconcile outcomes handed back via `/api/leads/<leadId>/outcome` using
the same `type: 'plumbing_outcome'` envelope if the agent saved through that
channel.
CLOSING
- Terminal states that aren't 'BOOKED' should still emit an outcome so the
dashboard knows the lead was worked. A lead left in 'NEW' with no outcome
is a bug — re-engage or disqualify.save_data envelope
The literal save_data(...) envelope the agent calls exactly once on a terminal call — status, the four answers, revenueScore, and optional bookedAt / calendarEventId.
save_data({
type: 'plumbing_outcome',
data: {
leadId,
status, // 'BOOKED' | 'DISQUALIFIED' | 'NURTURING' | 'CONTACTING'
answers: {
problemType, // 'leak' | 'clog' | 'water_heater_failure' | 'install' | 'unsure'
urgency, // 'emergency' | 'this_week' | 'this_month' | 'flexible'
budgetRange, // 'under_500' | '500_2k' | '2k_5k' | '5k_15k' | 'over_15k' | 'unknown'
addressConfirmed // string — confirmed/corrected address on file
},
revenueScore, // 0–100 — derived from the four answers
bookedAt, // ISO timestamp if booked, else omit
calendarEventId // from google_calendar MCP result, if booked
}
})PLUMBING_CALENDAR_BOOKING_PROMPT
A tighter booking-only shortcut the GoogleCalendarDispatcher runs when the agent platform asks for a quick calendar slot-create during qualification.
Use the google_calendar MCP to create a single calendar event
for the plumbing qualification slot just confirmed. Return ONLY the new event id.