Handle non-booking requests: take a message, log a callback note
A caller asking if their already-purchased frames were ready got railroaded through the booking script and hung up. AVA had no path for requests it can't do on the phone. - Prompt: classify intent first — question (answer it), can't-do request (take name + a one-line note, confirm callback number, promise a staff callback; never force booking questions), or booking (the ordered steps). - extract.py: request_type = appointment | callback | none. Callback gate needs a name or a request note. Records kind. - practice.py / odoo_client.py: callbacks write a "📞 Callback request" lead (name, callback number, what they need) instead of an appointment card. Verified the classifier: frames-status -> callback, booking -> appointment, pure question -> none. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
21
CLAUDE.md
21
CLAUDE.md
@@ -86,9 +86,11 @@ 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.
|
||||
Correctly uses `format: json`, uses verified Twilio caller-ID instead of trusting model
|
||||
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.
|
||||
**Classifies `request_type`:** `appointment` (booking), `callback` (a non-booking request staff
|
||||
must handle off-phone → "📞 Callback request" lead), or `none` (just a question / nothing).
|
||||
**Lead-quality gate:** appointment needs a NAME or LOCATION; callback needs a NAME or a request
|
||||
note — otherwise skipped (no near-empty cards). Appointments capture full name, phone
|
||||
(confirmed/alternate), insurance, reason, resolved date; callbacks capture name + what they need.
|
||||
|
||||
**Odoo integration (`odoo_client.py`)** — already uses `ODOO_API_KEY` for XML-RPC auth,
|
||||
not password. Correct pattern. No changes.
|
||||
@@ -276,8 +278,19 @@ AB_MODEL_B=
|
||||
## Call Workflow
|
||||
|
||||
AVA runs a directed script (system prompt in `bot.py`) — warm but direct, one short turn at a
|
||||
time, leading the call rather than waiting on the caller. Fixed order:
|
||||
time, leading the call rather than waiting on the caller.
|
||||
|
||||
**Intent first — three kinds of call:**
|
||||
- **Question** answerable from the practice facts → just answer it.
|
||||
- **Can't-do request** (existing order/purchase, frames/lenses/prescription/lab status, billing,
|
||||
account lookup, reach a person) → do NOT run the booking steps. Say it can't be looked up, take
|
||||
the caller's name + a one-line note of what they need, confirm the callback number, and promise
|
||||
a staff callback. Captured as a **callback note** lead in Odoo ("📞 Callback request — …"), NOT
|
||||
an appointment. (Added after a caller asking if their frames were ready got railroaded into the
|
||||
booking script and hung up.)
|
||||
- **Booking** → the ordered steps below.
|
||||
|
||||
Booking steps (fixed order):
|
||||
1. **Reason first** — find out what they're calling about (visit reason, or just a question → answer it).
|
||||
2. **Location** — ask city/area, confirm the matching office (don't offer others — see office rule).
|
||||
3. **Caller info** — full name (ask last name if only a first is given), then **address the caller
|
||||
|
||||
Reference in New Issue
Block a user