Commit Graph
16 Commits
Author SHA1 Message Date
GiteadandClaude Sonnet 5 79ac6aaa31 feat: migrate SMS/voice to Telnyx (TeXML), keep browser dial pad on Twilio
Twilio now handles only the in-browser dial pad (Access Token + browser-Device
outbound TwiML); Telnyx takes over SMS, inbound voicemail, the AI voice
conversation loop, and staff-triggered outbound calls via TeXML. Adds
TelnyxSettings model, Communication.provider discriminator, new comms/routes
modules, and a real Telnyx Settings page.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 15:39:43 -04:00
GiteadandClaude Fable 5 ff79cd1643 fix: earliest patient record wins when duplicates share a phone (inbound SMS/voice)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 23:11:55 -04:00
ffandClaude Sonnet 5 0cd095330a fix: AI recall-call flow, speech-to-text time parsing, and stale conversation state
- Reset conversation stage to a fresh start on every new voice call
  (recall and reminder alike), and on every hangup/timeout/goodbye,
  so an abandoned or completed call never leaves a patient stuck
  mid-flow for their next call or text.
- Add a staleness check to the SMS flow: after a long idle gap,
  check whether the patient's reply still reads as a continuation
  before resuming the stored stage, falling back to a friendly
  "it's been a while" re-greeting when unsure.
- Fix parseTime() to handle Twilio's speech-to-text output, which
  renders "pm"/"am" with periods and often drops the colon in a
  spoken time (e.g. "100 p.m." -> 1:00 PM) — this was silently
  failing and causing the AI to loop asking for a time it had
  already been given.
- Extend the voice Gather timeout so the AI doesn't hang up on a
  patient who just needs a few seconds to respond.
- Reword the recall-call opening line and rework the post-"yes"
  prompt to ask for day and time together.
- Fix rclone WebDAV server to serve only the backups folder instead
  of the entire backend app directory (was exposing .env and source).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 09:35:48 -04:00
ff 55ce52f276 fix: patient language field silently dropped by stale browser-side validation schema
packages/db/usedSchemas/browser.ts (the browser-resolved copy of the Patient
zod schema, kept separate from the Node copy since it can't import
Prisma-generated code) was missing several fields added to the real schema
over time — preferredLanguage, gender, insuranceProvider, insuranceId,
groupNumber, policyHolder, and the PLAN_NOT_ACCEPTED status. Since the schema
isn't strict, those fields were silently stripped from every patient
create/update in the browser with no validation error, so edits to them
never reached the server.

Also fixes the AI call greeting always playing in English regardless of the
patient's preferred language — the greeting text was a single hardcoded
string, unlike every later turn in the conversation which already branched
by language.
2026-08-05 21:40:53 -04:00
ffandClaude Sonnet 5 cef928be97 feat: add AI recall calling — books existing patients for routine cleanings
Adds a new recall conversation flow (recall-graph.ts) triggered from the
Patient Connection "AI Call" button: offers an existing patient a routine
exam & cleaning, classifies their yes/no reply, then books directly onto
the schedule (Column A, 30-minute slots, real conflict checking against
office hours and existing appointments) instead of only capturing a
preference for staff to follow up on.

Also adds a "Voice call" label in the message thread to distinguish call
transcripts from SMS, and updates the Call Templates settings UI with an
editable recall greeting.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-02 23:13:09 -04:00
ffandClaude Sonnet 5 06dc63c53e feat: unify AI voice calls with SMS conversation rules, add Call Templates
AI phone calls now route through the same routePatientTurn() rule engine
as SMS (office-hours checks, slot-conflict checks, MassHealth eligibility,
staff escalation) instead of a freeform LLM chat, and speak in the
patient's preferred language (English/Spanish). Adds a separate "Call
Templates" settings section so spoken wording can be customized
independently from SMS wording.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 23:39:31 -04:00
ffandClaude Sonnet 5 089e94ba88 feat: add AI-driven phone calls to patient connection
Adds an "AI Call" option alongside Call/SMS/Chat that places an outbound
call where Lisa converses live with the patient via Twilio speech
gather + TTS, using the same conversational AI as chat. Includes a
separate, user-editable Call Template (Settings > AI Chat/Call Settings)
so the call greeting can be customized independently of SMS templates.

Also fixes the outbound-call webhook URL to always use the fixed public
Twilio hostname (CLOUDFLARE_HOST) instead of deriving it from the
triggering request, since staff-browser requests arrive over the
LAN-only hostname, which Twilio can never reach.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 20:14:09 -04:00
ffandClaude Sonnet 4.6 4899ab8368 feat: multi-provider AI support with per-provider model selection
- Add llm-factory.ts: unified LLM provider abstraction (Google/Claude/OpenAI)
- Install @langchain/anthropic and @langchain/openai packages
- resolveAiProvider picks active provider from DB settings (Claude > OpenAI > Google)
- All AI graphs (reminder, new-patient, reschedule, internal-chat) now accept provider+model params
- Add claudeAiModel, openAiModel, googleAiModel columns to ai_settings table
- New PUT /api/ai/provider-model route to save selected model per provider
- UI model dropdowns for Claude (Haiku/Sonnet/Opus), OpenAI (GPT-5.x series), Google (Gemini 2.5/3.x)
- Google AI section also gets model selector alongside existing API key field

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 09:34:11 -04:00
ffandClaude Sonnet 4.6 ddcc49b72c feat: add in-browser dial pad with Twilio Voice SDK
- New DialPad component on Patient Connection page: clickable keypad,
  call/hangup/mute buttons, duration timer, keyboard input support
- Backend: POST /api/twilio/voice-token issues Access Token for browser
  Device; POST /api/twilio/webhook/voice-browser is the TwiML webhook
  Twilio calls to bridge the browser to the patient's phone
- TwiML App SID field added to Twilio Settings (stored in templates JSON)
- README: one-time Twilio Console setup instructions for the dial pad

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 22:24:53 -04:00
GiteadandClaude Sonnet 4.6 c71624f7e7 feat: enhance new-patient AI chat flow with full scheduling and eligibility
- Add 3-message intro (self-intro → empathetic ack → new/existing question) via single TwiML response to guarantee delivery order
- Detect reschedule intent from first message; look up existing appointment date
- New patient flow: ask insurance type → MassHealth consent → member ID + DOB → Selenium eligibility check
- Post-eligibility: active → ask appointment date/time with office-hours validation; inactive → ask other insurance or collect contact info
- Date/time collection mirrors reschedule flow: check office day open, ask time, validate against office hours
- Auto-create appointment in schedule for known patients on confirmation; use first available staff member
- Add openPhoneReply toggle (Settings → AI Chat) to respond to any number at any time
- Add 5-minute inactivity timeout: reset conversation to initial stage and clear pending state
- Normalize MassHealth DOB to zero-padded MM/DD/YYYY before Selenium submission
- Expand isExistingPatient classifier to recognize "old patient", "old", "previous", "prior"
- Existing patient confirmation message now acknowledges patient type before asking about insurance

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:00:56 -04:00
GiteadandClaude Sonnet 4.6 131733564e feat: reschedule-by-office batch SMS, AI follow-up toggle, date-shortcut fix, combined flow diagram
- Add Reschedule for Column button on schedule page with AI follow-up toggle (default on)
- Add POST /api/twilio/send-reschedule-batch — sends Reschedule by Office template, starts AI reschedule conversation per patient
- Add {officePhone} (office call-in number) and {twilioPhone} (SMS number) variable replacement in both batch endpoints
- Fix broken variable names in Reschedule by Office template ({office phone number) → {officePhone}, {Twilio phone number} → {twilioPhone})
- Fix reschedule-graph: when patient replies with date in same message as YES/NO (e.g. "ok, 5/18"), AI now checks day open and asks for time instead of asking "what day and time?"
- Fix twilio-webhooks: same date-shortcut logic for reminder flow — "no, 5/18" skips "when to reschedule?" and goes straight to day check
- Update LangGraph SVG: rename to Reminder & Reschedule Flow, combine both entry points (Reminder SMS + Reschedule SMS) into one diagram with date-shortcut annotations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 00:36:38 -04:00
GiteadandClaude Sonnet 4.6 1ff843bc79 feat: AI SMS reminder flow with two-message intro, smart reschedule with availability checks
- Reminder flow: send AI self-introduction as message 1 (Twilio REST API), intent response as message 2 (TwiML) so intro always arrives first
- LangGraph reminder graph: classify yes/no/other from patient reply; 'no' now asks 'When would you like to reschedule?' directly
- Reschedule flow: new asked_reschedule_datetime stage replaces multi-step ASAP/next-week flow
  - Date-only reply (e.g. '5/18'): ask for time separately, then confirm
  - Date+time reply (e.g. '5/18 at 10am'): go straight to confirmation
  - new asked_reschedule_time_for_date and asked_reschedule_confirm_datetime stages
- Date/time parsing: regex handles M/D and am/pm formats first; falls back to Gemini for natural language
- Day-level office hours check: if requested day is closed (e.g. Sunday), reply 'Our office is closed on [date]. Choose another day?'
- Time-level office hours check: if requested time is outside working hours (e.g. 12pm during lunch), reply with actual hours (e.g. '9:00 am – 12:00 pm and 1:00 pm – 5:00 pm')
- Slot availability check: verifies no conflicting appointment for same staff member
- After appointment confirmed: patient thank-you reply triggers warm closing with upcoming appointment time
- Schedule page: office hours summary bar above grid showing today's configured hours with link to settings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:01:23 -04:00
GiteadandClaude Sonnet 4.6 112529155c feat: persist AI conversation state in DB and fix LangGraph flow bugs
- Replace in-memory Maps in aiHandoffStore with DB-backed async functions
  using new patient_conversation table (stage + aiHandoff per patient)
- Add afterHoursEnabled to ai_settings table (persists across restarts)
- Fix runtime crash in reschedule-graph: mon/tue/wed variables were out
  of scope in the next-week fallback branch (ReferenceError)
- Wire rescheduleGreeting and generalFallback chat templates through to
  LangGraph nodes so user-configured messages take effect
- Add otherNode to reminder-graph to handle unclassified patient replies
  (e.g. "I want another appointment") and route to booking flow
- Fetch chatTemplates once per webhook request instead of per stage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 15:23:55 -04:00
GiteadandClaude Sonnet 4.6 9908e5b5fd feat: AI chat system with LangGraph, multi-step patient flows, and appointment rescheduling
- Add floating chat window Hand-off to AI toggle (per-patient) and after-hours AI toggle (global)
- Add LangGraph-powered appointment reminder flow: AI introduces itself, classifies YES/NO, handles confirmation with appointment date/time
- Add multi-step rescheduling flow: ASAP vs next week, tomorrow offer, Mon/Tue/Wed picker, morning/afternoon time slot — automatically updates appointment in DB
- Add new patient / after-hours flow: new vs existing patient, dental insurance check, MassHealth Selenium eligibility check (auto-uses saved member ID + DOB for existing patients), self-pay fallback
- Add AI Chat Settings page (Settings → Advanced) with editable greeting templates and LangGraph flow diagrams for both reminder and new-patient flows
- Add Schedule a New Patient template option in chat window, starts new-patient conversation flow
- Add GET/PUT endpoints for AI handoff, after-hours handoff, and AI chat templates
- Add multilingual support (7 languages) across all AI reply nodes with LLM generation and hardcoded fallbacks
- Add pending reschedule in-memory store and conversation stage tracking across all flows

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 23:21:06 -04:00
GiteadandClaude Sonnet 4.6 79e20b693d feat: improve backup management, settings UI, and Twilio webhooks
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 00:52:42 -04:00
Gitead 5689269690 feat: add Twilio SMS/call integration with settings, templates, and conversation history 2026-05-02 20:18:58 -04:00