Skip to content

feat(voice): in-browser ElevenLabs widget + APP 8 modal + KB content packs#205

Merged
CleanExpo merged 1 commit intomainfrom
feat/voice-widget-and-kb-content
Apr 26, 2026
Merged

feat(voice): in-browser ElevenLabs widget + APP 8 modal + KB content packs#205
CleanExpo merged 1 commit intomainfrom
feat/voice-widget-and-kb-content

Conversation

@CleanExpo
Copy link
Copy Markdown
Owner

Summary

Ships the production voice surface for Olivia (contractor onboarding) and Sarah/Tannika (claims intake) — without requiring a Twilio account. Both agents are already published live in the ElevenLabs dashboard; this PR adds the website-side surface.

What's new

Components

  • `` — three-phase widget (idle → APP 8 consent → live or declined). Lazy-loads the EL convai-widget-embed script only after consent grant. Decline / silent / Esc never triggers script load.
  • `` — APP 8 consent gate with the canonical `CONSENT_UTTERANCE` wording, version-pinned. Tailwind only, no Radix dep.

API

  • `POST /api/voice/widget-consent` — logs to `compliance_events` ledger. `consentMethod: 'web_widget'` added to the union. IP fingerprinted (SHA-256) per privacy.md §6. Returns 200 even when compliance writer is off — never blocks UX.

Wiring

  • `/contractor/apply` mounts ``
  • `/claim` mounts ``
  • Both gated behind `NEXT_PUBLIC_VOICE_WIDGET_ENABLED` (default off — zero impact when off, returns null, no script tag, no fetch).

Knowledge base content packs

`docs/voice-knowledge-base/` — 7 markdown files designed for manual upload to EL Convai → Knowledge Base:

File Agent
`olivia-nrpg-overview.md` Olivia
`olivia-onboarding-process.md` Olivia
`olivia-applicant-requirements.md` Olivia
`olivia-service-categories.md` Olivia
`olivia-faq.md` Olivia
`sarah-claim-process.md` Sarah
`sarah-faq.md` Sarah

All KB content is PUBLIC class per privacy.md §1 — no rates, no contractor identities, no client PII, no internal SOPs.

Why widget instead of Twilio

Phill is not signed up to Twilio. The widget approach:

  • Costs nothing extra (already paying for EL voice usage)
  • Works in any modern browser via mic permission prompt
  • APP 8 consent runs as a React modal, identical wording to the TwiML version
  • Validates the entire prompt + voice + consent path with real users immediately
  • Twilio scaffolding remains in repo for future use; layer phone numbers on top later

Activation

```

Vercel project settings → environment → production

NEXT_PUBLIC_VOICE_WIDGET_ENABLED=true
```

Then redeploy. Rollback = flip the env var to false (no code change, no redeploy).

Manual deploy step (one-time, post-merge)

Upload the 7 KB markdown files to ElevenLabs Convai → Agents → Knowledge Base for Olivia and Tannika. See `docs/voice-knowledge-base/README.md` for the click-by-click instructions.

Test plan

  • CI typecheck + lint pass
  • Set `NEXT_PUBLIC_VOICE_WIDGET_ENABLED=true` in Vercel preview, click "Talk to Olivia" → consent modal → Yes → widget loads → talk
  • Same on /claim with Sarah
  • Click Decline → no EL script tag in Network panel; fallback shows "Continue to the form"
  • With `COMPLIANCE_EVENTS_ENABLED=true` → row in compliance_events with `consentMethod='web_widget'`
  • Upload the 7 KB markdown files; verify each agent retrieves from KB rather than paraphrasing

Out of scope

  • Twilio inbound number (Phill not signed up)
  • Voice-call audio recording / retention (browser widget doesn't record by default; that's an EL agent setting)
  • Persistent VoiceCall + CallTranscript Prisma models (tracked in domain-models.md Known drift)

🤖 Generated with Claude Code

… + KB packs

Ships the production voice surface for Olivia (contractor onboarding)
and Sarah/Tannika (claims intake) WITHOUT requiring a Twilio account.
Both agents are already created + published live in the ElevenLabs
dashboard — this PR adds the website-side surface so callers can
talk to them in-browser.

## What's new

- <VoiceWidget agent="olivia|sarah" /> three-phase widget: idle →
  APP 8 consent → live (or declined). Lazy-loads the EL widget
  script ONLY after consent grant.
- <VoiceConsentModal> APP 8 cross-border-disclosure gate with the
  canonical CONSENT_UTTERANCE wording, version-pinned.
- POST /api/voice/widget-consent logs consent to compliance_events
  with consentMethod='web_widget'. Never blocks UX on logging.
- /contractor/apply mounts Olivia widget; /claim mounts Sarah widget.
  Both gated behind NEXT_PUBLIC_VOICE_WIDGET_ENABLED (default off).
- VOICE_WIDGET added to feature-flags.ts registry.
- 7 markdown KB content packs in docs/voice-knowledge-base/ for
  manual upload to EL Convai > Knowledge Base.

## Why widget instead of Twilio

Phill is not signed up to Twilio. The widget approach:
- Costs nothing extra (already paying for EL voice)
- Works in any modern browser via mic permission
- APP 8 consent runs as a React modal, identical wording to TwiML
- Twilio scaffolding remains in repo for future use

## Activation

Set NEXT_PUBLIC_VOICE_WIDGET_ENABLED=true in Vercel project settings,
redeploy. To roll back: flip env var to false.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bolt-new-by-stackblitz
Copy link
Copy Markdown

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 26, 2026

Warning

Rate limit exceeded

@CleanExpo has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 22 minutes and 30 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 22 minutes and 30 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f424ac92-7a1c-4fe6-b605-443ec94ed76a

📥 Commits

Reviewing files that changed from the base of the PR and between 2c9ea41 and dac2b78.

📒 Files selected for processing (17)
  • .env.example
  • MEMORY.md
  • app/api/voice/widget-consent/route.ts
  • app/claim/ClaimFormClient.tsx
  • app/contractor/apply/ApplyClient.tsx
  • docs/voice-knowledge-base/README.md
  • docs/voice-knowledge-base/olivia-applicant-requirements.md
  • docs/voice-knowledge-base/olivia-faq.md
  • docs/voice-knowledge-base/olivia-nrpg-overview.md
  • docs/voice-knowledge-base/olivia-onboarding-process.md
  • docs/voice-knowledge-base/olivia-service-categories.md
  • docs/voice-knowledge-base/sarah-claim-process.md
  • docs/voice-knowledge-base/sarah-faq.md
  • src/components/voice/VoiceConsentModal.tsx
  • src/components/voice/VoiceWidget.tsx
  • src/lib/compliance/events.ts
  • src/lib/feature-flags.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/voice-widget-and-kb-content

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@CleanExpo CleanExpo merged commit fcfc64c into main Apr 26, 2026
8 of 11 checks passed
@CleanExpo CleanExpo deleted the feat/voice-widget-and-kb-content branch April 26, 2026 10:28
@github-actions
Copy link
Copy Markdown

✅ DR Managed Agent CI/CD Pipeline — PASSED

Duration: 0.0s

Managed Agent CI/CD pipeline skipped — ANTHROPIC_API_KEY not configured. Manual review required before merging.

Full pipeline output
Add ANTHROPIC_API_KEY (with Anthropic Managed Agents Research Preview access) as a GitHub Actions secret to enable automated pipeline review.

Powered by Anthropic Managed Agents (Research Preview)

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 26, 2026

❌ Smoke tests FAILED — do not merge

Preview URL: https://disaster-recovery-pd1y3q1fi-unite-group.vercel.app
Test run: View report

Download the artifact smoke-test-report from the Actions run for the full Playwright HTML report.

CleanExpo added a commit that referenced this pull request Apr 26, 2026
#207)

Adds 15 characterisation tests covering compliance event writer and
observability primitives, taking the project from 15 to ~30 vitest
tests (DR-791, halfway to the 40-test goal).

Compliance (10 tests in events.test.ts):
- ENABLED-path write behaviour with isolated module re-imports
- entityIdentifier (raw email PII) is SHA-256 hashed before persist
- breach_suspected + data_deletion_request event types resolve
- amountCents + amountCurrency optional fields surface in the call
- occurredAt falls back to a current Date when not provided
- consentMethod 'web_widget' (PR #205) recognised; type-level
  exhaustiveness probe on ComplianceConsentMethod and
  ComplianceEventType via @ts-expect-error.

Observability (5 tests in new observability.test.ts):
- requestLogger returns info/warn/error + string requestId
- requestId is unique per call when no header is supplied
- bound context (requestId + route) lands in the structured log line
- captureException tolerates Error/string/undefined/object/null/number
- captureException does not crash with PII-shaped extras (redaction
  is a separate, layered concern per .claude/rules/privacy.md §3).

Prisma is mocked via vi.mock — no real DB calls. No new runtime deps.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant