toga-ai 1.0.396 → 1.0.397
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: session
|
|
3
|
+
slug: bdr-vapi-golive
|
|
4
|
+
title: BDR VAPI go-live day 2 — loop verified live, four funnel features shipped
|
|
5
|
+
author: tcox
|
|
6
|
+
repos: [bdr, ai-bdr, worker2]
|
|
7
|
+
framework: "2.0"
|
|
8
|
+
client: shared
|
|
9
|
+
status: active
|
|
10
|
+
created: 2026-07-21
|
|
11
|
+
updated: 2026-07-21
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Session: bdr-vapi-golive
|
|
15
|
+
**Date:** 2026-07-21 (continues 2026-07-20-bdr-vapi-golive-tcox)
|
|
16
|
+
**Project/Repo:** bdr + worker2 (2.0)
|
|
17
|
+
**Task:** Verify the AI-BDR call loop end-to-end live on the real campaign and finish the BDR funnel for go-live (enrichment, fast dial, anonymous guard, real share).
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## What WORKED
|
|
22
|
+
- **Full call loop verified live on campaign 2** using Rohan's existing-campaign approach: flip ALL campaign-2 contacts `isOkayToCall=0` (tester included), extend `Campaigns.dateEnd`, then the tester's UI Call Now submit re-arms ONLY them (`isOkayToCall=1` + `dtNextContactRequested`). Call arrived from the healthcare number +1 (331) 244-5958 (campaign 2's `c_fromPhoneNumberIdentifier` maps there); webhook write-back confirmed (dtEnded set, dtNext cleared).
|
|
23
|
+
- **Scheduled-call path + CST conversion verified**: an 11:30 slot dialed at 11:30:50 (attempt 183).
|
|
24
|
+
- **Outcome mapping verified**: "call me back..." conversation wrote `c_callOutcome=CALLBACK_SCHEDULED`, `c_actionToTake=SCHEDULE_CALLBACK`, sentiment, qualification score.
|
|
25
|
+
- **Enrichment shipped and live-proven** (bdr: src/server/hubspot.ts, toga.ts, leadSink.ts, app/page.tsx): HubSpot jobtitle/company/industry → Contacts.title/doingBusinessAs/industry (the three no-fallback dialer fields), city/state/website → callContext keys. Contact 248 got title=INTERN, doingBusinessAs="Agilant Solutions, Inc." on its first funnel pass and the Vapi opener used them. Committed by tcox this morning (with the phone-prefill fallback).
|
|
26
|
+
- **Fast dial built** (src/server/workerDialer.ts + callbackService.ts, env TOGA_WORKER_URL): Call Now triggers the worker's `Ai/Bdr/Vapi/InitiateOutboundCall` with the primary phone-row uuid — seconds instead of the 0-60s cron wait; best-effort with cron fallback; scheduled calls excluded. NOT yet live-tested.
|
|
27
|
+
- **Anonymous-visit guard built** (CallNow.tsx, Schedule.tsx, content schema/default): no lead ref → submit disabled + notice, matching info's "Missing contact reference" (replaces silent fake success).
|
|
28
|
+
- **Share button made real** (src/lib/shareMailto.ts, CallSummary.tsx): Send opens the visitor's mail client via mailto: with recipient/subject/summary body. BDR suite 131 tests green, tsc + eslint clean.
|
|
29
|
+
- **Parity audit (info → BDR)**: everything ported; enrichment was net-new in BOTH repos; visit route intentionally dropped; TOGA_PUBLIC_TOKEN_URL and NEXT_PUBLIC_ENV are dead even in info.
|
|
30
|
+
- **Vapi API diagnostics work** with the bearer const at worker2/Worker/Ai/Bdr/Vapi.php:6 (GET /call/{id} endedReason, GET /assistant/{id} config).
|
|
31
|
+
- /capture published 4 doc updates (web-funnel-app, safe-call-loop-testing, vapi-webhook-handler, vapi-integration).
|
|
32
|
+
|
|
33
|
+
## What did NOT work — DO NOT RETRY THESE
|
|
34
|
+
- **Answering the test call silently** → 8 seconds of mutual silence, Vapi `endedReason=customer-ended-call`, empty transcript. The healthcare assistant uses `firstMessageMode=assistant-waits-for-user` (deliberate: first-phoneme timing for voicemail/iPhone screening). **Testers must say "Hello?" first.**
|
|
35
|
+
- **Telling the assistant "call me back in ten minutes"** → structured output stored `c_callbackTime="in ten minutes"` (spelled-out number); worker2 `convertDateTime` (Worker/Vapi.php ~L609) returns null (PHP parses "10 minutes" but not "ten minutes") → `actionScheduleCallback` aborts after error_log "Cannot parse callbackTime" → `dtNextContactRequested` never set, **the promised callback silently never happens**. Open HIGH bug; until fixed, spoken-word callback times are dropped.
|
|
36
|
+
- **The dbchanges2 test-campaign migration** (withdrawn, PR to close unmerged): its INSERT...SELECT missed `c_fromPhoneNumberIdentifier`, which `buildVapiPayload` hard-requires (throws) — the SQL-created campaign would have failed at call time. Raw SQL campaign creation is the wrong vehicle; `_Worker_Ai_Bdr_ZoomInfo::SetupCampaign` is the sanctioned creator.
|
|
37
|
+
- **Vapi API auth with worker2 Config [vapi] api_secret** → `unauthorized`. The working credential is the const at Worker/Ai/Bdr/Vapi.php:6 (itself a security finding — rotate + move to config; value not recorded here).
|
|
38
|
+
- **BDR API client reading /contact-attempts** → 403 (EZ-1). Blocks real call summaries + live call status until the backend grants read ACL.
|
|
39
|
+
|
|
40
|
+
## Not tried yet (candidates for next session)
|
|
41
|
+
- **Fast-dial live test** — restart the dev server (TOGA_WORKER_URL loads at startup), submit Call Now, phone should ring in seconds. First live use of the worker's direct-action endpoint as a product feature.
|
|
42
|
+
- **Self-heal changed-number live test** — Call Now with a different owned number; dialer should ring the new number.
|
|
43
|
+
- **Real summary + live call status** — blocked on the ContactAttempts ACL grant (read-only: uuid, contactId, dtStarted, dtEnded, c_callSummary, c_callOutcome for BDR API client ead1d6ad-04a5-41f9-9a87-669d66ad49a2). One grant unlocks: real summary card content, real Copy/Share body, live status timer.
|
|
44
|
+
- **Callback-time parse fix** (worker2 + Vapi schema): constrain schema callbackTime format AND normalize spelled-out numbers in convertDateTime.
|
|
45
|
+
- **Booking path live test** (Cal.com — campaign 2's eventIdentifier is real).
|
|
46
|
+
- **Restore SQL** = business go-live switch for the ~70 prospects: `UPDATE Contacts c INNER JOIN Campaigns_Contacts cc ON cc.contactId=c.id SET c.isOkayToCall=1 WHERE cc.campaignId=2 AND c.id NOT IN (120,132,134,146,155);` — **never restore those 5 ids (pre-existing DNC)**.
|
|
47
|
+
|
|
48
|
+
## Current file state
|
|
49
|
+
| File | Status | Notes |
|
|
50
|
+
|------|--------|-------|
|
|
51
|
+
| BDR enrichment + prefill (hubspot/toga/leadSink/page + tests) | committed by tcox (BDR-Phase-2), merge state to _dev-sandbox unverified | live-proven on contact 248 |
|
|
52
|
+
| BDR fast-dial + anon guard + share (workerDialer, callbackService, CallNow, Schedule, schema, default, shareMailto, CallSummary, .env.example + 3 test files) | UNCOMMITTED in C:\WWW\BDR | 131 tests green; suggested msg: "feat: fast dial, anonymous submit guard, real share via mailto" |
|
|
53
|
+
| BDR/.env.local | TOGA_WORKER_URL added (local only) | dev server restart needed to load |
|
|
54
|
+
| dbchanges2 feature/ai-bdr-test-campaign (e99a367) | pushed; PR must be CLOSED UNMERGED | superseded + buggy (see above) |
|
|
55
|
+
| Prod Client_True data | campaign 2 dateEnd=2026-07-28; all campaign-2 contacts isOkayToCall=0 EXCEPT 248 | restore = go-live switch; exclude ids 120/132/134/146/155 |
|
|
56
|
+
| Team knowledge | 4 docs updated + pushed today | web-funnel-app, safe-call-loop-testing, vapi-webhook-handler, vapi-integration |
|
|
57
|
+
|
|
58
|
+
## Decisions made
|
|
59
|
+
- **Existing campaign + flip-everyone over a new test campaign** (Rohan): zero campaign-config risk, the UI submit is the only re-arm, and the real Cal.com event stays testable. Rejected: SetupCampaign-created test campaign (viable, kept as Approach B in the runbook), raw SQL (buggy + wrong vehicle).
|
|
60
|
+
- **Share via mailto:, not server-side send**: server-sending client-supplied text through TOGA infra is a spam relay; the visitor's own mail client is honest and zero-backend. Real summary content deferred to the ACL grant.
|
|
61
|
+
- **Fast dial is best-effort**: absorbed failures + cron fallback + in-progress dedupe; env-gated (TOGA_WORKER_URL) so deploys without the var behave exactly as before.
|
|
62
|
+
- **Anonymous submits blocked with notice** (matches info) per tcox's directive that anything diverging from info needs correcting.
|
|
63
|
+
|
|
64
|
+
## Blockers
|
|
65
|
+
- **Amplify app still doesn't exist** (ClickUp 868kdf4tj, Jeff) — 7 env vars now: the 5 server-side + NEXT_PUBLIC_GA_MEASUREMENT_ID + TOGA_WORKER_URL.
|
|
66
|
+
- **ContactAttempts ACL grant** (backend, DB config only) — gates real summaries + live status.
|
|
67
|
+
- **Business decision on the restore SQL** (resumes cold-calling ~70 prospects).
|
|
68
|
+
|
|
69
|
+
## Exact next step
|
|
70
|
+
> In `C:\WWW\BDR`: commit the uncommitted batch ("feat: fast dial, anonymous submit guard, real share via mailto"), push to BDR-Phase-2, merge to _dev-sandbox. Then restart the dev server (`npm run dev`) and submit Call Now — the phone should ring within seconds (fast-dial's first live test). If it takes ~a minute instead, check the dev console for a `[workerDialer]` warning: that means the worker's direct-action endpoint rejected the trigger and the cron fallback placed the call.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
_Saved by /session-save on 2026-07-21_
|
package/package.json
CHANGED