- CallerContextService: added invalidateCache(leadId) method
- CallerResolutionController: POST /api/caller/invalidate-context
endpoint — frontend calls after appointment mutations to bust
stale AI context cache
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The build() method previously fetched Lead and Appointments in parallel.
When the input patientId was empty (outbound dial, first-time linkage),
the appointments query was skipped even though the Lead record in the DB
had a valid patientId. Now fetches Lead first, reads its patientId, then
fetches appointments/calls/activities in parallel with the correct ID.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CallerContextService: fetches lead profile, appointments, call history,
activities in parallel. Caches in Redis (5 min TTL). Renders as
human-readable KB section — no UUIDs exposed to the LLM.
- Caller resolution controller: prewarms context cache on resolve
(fire-and-forget) so the AI stream has a cache hit.
- AI chat stream: injects caller context into system prompt KB instead
of raw Lead ID. LLM answers patient questions from context, no tool
calls needed for current caller data.
- Eliminates UUID hallucination: LLM never sees leadId or patientId,
can't pass wrong ID to wrong tool parameter.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>