Document call data capture, date validation, and hang-up grace pause

- New "Call Data Capture & Date Validation" section: the six captured fields
  (full name, phone confirm/alternate, office, reason, insurance log-only,
  validated preferred date/time), how each is logged, and the per-call calendar
  injection that drives date pushback.
- EndCallProcessor note: HANGUP_DELAY_SECS grace pause; Phase 1 gate result.
- .env reference: add HANGUP_DELAY_SECS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
tocmo0nlord
2026-06-25 03:01:49 +00:00
parent b8c71b15c2
commit 199d16c630

View File

@@ -36,8 +36,9 @@ The previous build at `/home/tocmo0nlord/avc-phone/` is a working foundation.
**`EndCallProcessor` in `bot.py`** — AVC-side call termination is fully implemented.
Watches LLM text stream for closing keywords ("goodbye"), waits for TTS to finish via
`BotStoppedSpeakingFrame`, then pushes `EndTaskFrame` upstream. `TwilioFrameSerializer`
with `auto_hang_up` drops the carrier leg. This is correct. Zero changes.
`BotStoppedSpeakingFrame`, pauses `HANGUP_DELAY_SECS` (default 4s) so the caller isn't
clipped, then pushes `EndTaskFrame` upstream. `TwilioFrameSerializer` with `auto_hang_up`
drops the carrier leg. Verified working in the Phase 1 gate (4/4 clean hang-ups).
**Mulaw 8kHz ↔ 16kHz conversion** — handled internally by `TwilioFrameSerializer`.
`PIPELINE_SAMPLE_RATE = 16000`, `WIRE_SAMPLE_RATE = 8000` are already set correctly.
@@ -206,6 +207,7 @@ STREAM_TOKEN=
# Call behaviour
AGENT_NAME=AVA
HANGUP_DELAY_SECS=4.0 # grace pause after the goodbye before dropping the carrier leg
ENABLE_TOOLS=
VAD_CONFIDENCE=0.5
VAD_MIN_VOLUME=0.3
@@ -223,6 +225,41 @@ AB_MODEL_B=
---
## Call Data Capture & Date Validation
What AVA collects on a booking call and how it's logged. Driven by the system prompt
(`bot.py`) plus a per-call calendar injection; persisted by the post-call extractor
(`extract.py``practice.py` → Odoo lead).
### The six captured fields
| Field | In-call behavior | Logged as |
|-------|------------------|-----------|
| Full name | Asks for last name if only a first is given | `patient_name` / lead `contact_name` |
| Phone | Reads back the caller-ID number; if the caller declines, uses the number they give | `callback_number` (+ `phone_confirmed`) |
| Office / city | Asks city/area; never names an office unprompted | folded into `reason` prefix |
| Reason | Captured from the conversation | `reason` |
| Insurance | **Log only** — asks the plan, never promises/confirms/denies coverage or treatment (even a listed plan); staff verify on callback | `insurance` (note: "log only — staff to verify") |
| Preferred date & time | Validated against the calendar (below); confirmed before booking | `preferred_time` + resolved `YYYY-MM-DD` |
### Date validation
Each call's system message is injected with an **authoritative 45-day calendar** (today +
each upcoming date with its weekday), recomputed per call since the server is long-running
(`_date_context()` in `bot.py`). AVA must check any date the caller names against it. On an
impossible or weekday/number-mismatched date it pushes back and offers the correct one, e.g.
> "Next month, Monday lands on the sixth — would you like to schedule that date?"
The extractor is also given today's date so it can resolve relative phrasing
("next month, Monday") to a concrete `YYYY-MM-DD`; the caller's own words are always kept too.
**Reliability note:** this is the local 8B model reasoning over injected facts — accurate in
testing but not guaranteed turn-to-turn. A deterministic date-resolver tool would harden it,
but in-call tools stay off for this model (it leaks JSON). Treat the resolved date as
staff-verifiable, not authoritative. Overlaps Phase 2 validation work.
---
## Model Configuration
### Current production model: `activeblue-avc:latest`