Lead-quality gate: require a name or location, not just a reason
A call produced a near-empty lead (name=None, location=None, only reason="check on my eyes"). Changed the extraction gate from "name OR reason" to "name OR location" — a bare reason with no name and no office isn't an actionable worklist card, so skip it. Verified: reason-only -> skip; name-only, location- only, both -> keep. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -86,6 +86,9 @@ Trade-off: half-duplex — the caller can't barge in mid-utterance (fine for sho
|
|||||||
**Post-call extraction (`extract.py`)** — single JSON-mode completion after call ends.
|
**Post-call extraction (`extract.py`)** — single JSON-mode completion after call ends.
|
||||||
Correctly uses `format: json`, uses verified Twilio caller-ID instead of trusting model
|
Correctly uses `format: json`, uses verified Twilio caller-ID instead of trusting model
|
||||||
output, falls back to JSONL if Odoo is unreachable. Keep it.
|
output, falls back to JSONL if Odoo is unreachable. Keep it.
|
||||||
|
**Lead-quality gate:** a lead is only written if a NAME or a LOCATION was captured — a bare
|
||||||
|
reason (e.g. "check on my eyes") with no name and no office is skipped (not worth a worklist
|
||||||
|
card). Captures full name, phone (confirmed/alternate), insurance, reason, and resolved date.
|
||||||
|
|
||||||
**Odoo integration (`odoo_client.py`)** — already uses `ODOO_API_KEY` for XML-RPC auth,
|
**Odoo integration (`odoo_client.py`)** — already uses `ODOO_API_KEY` for XML-RPC auth,
|
||||||
not password. Correct pattern. No changes.
|
not password. Correct pattern. No changes.
|
||||||
|
|||||||
10
extract.py
10
extract.py
@@ -80,12 +80,12 @@ async def extract_and_record(messages, ollama_url, model, call_sid=None, caller_
|
|||||||
logger.info("Post-call extraction: no appointment requested")
|
logger.info("Post-call extraction: no appointment requested")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Don't create near-empty cards from quick hang-ups: require at least a name or a
|
# Lead-quality gate: a usable lead needs a NAME or a LOCATION (so staff can act on it) —
|
||||||
# reason. A bare location + caller-ID isn't enough to be worth a worklist card.
|
# a bare reason like "check on my eyes" with no name and no office is not worth a card.
|
||||||
name = (data.get("patient_name") or "").strip()
|
name = (data.get("patient_name") or "").strip()
|
||||||
reason_raw = (data.get("reason") or "").strip()
|
location = (data.get("location") or "").strip()
|
||||||
if not name and not reason_raw:
|
if not name and not location:
|
||||||
logger.info("Post-call extraction: appointment intent but no name/reason captured — skipping card")
|
logger.info("Post-call extraction: appointment intent but no name/location captured — skipping card")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Callback number: default to the verified Twilio caller-ID. If the caller explicitly
|
# Callback number: default to the verified Twilio caller-ID. If the caller explicitly
|
||||||
|
|||||||
Reference in New Issue
Block a user