diff --git a/CLAUDE.md b/CLAUDE.md index dd85706..dbbc503 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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`