fix(vapi): subscribe to end-of-call-report so SMS dispatch can fire#28
Merged
ByteStreams-AI merged 1 commit intomainfrom May 5, 2026
Merged
fix(vapi): subscribe to end-of-call-report so SMS dispatch can fire#28ByteStreams-AI merged 1 commit intomainfrom
ByteStreams-AI merged 1 commit intomainfrom
Conversation
Live SQL pull from a fresh test call showed every voice_calls row
with ended_at=NULL and ended_reason=NULL. vapi_call_end never fired
on any call, which means the post-call SMS dispatch (and call-row
patching) was dead code from the moment we moved to dynamic
assistant config.
Root cause: Vapi assistants only deliver webhook events to the
serverUrl for message types listed in `serverMessages`. Static
dashboard-defined assistants typically have a default checklist;
dynamic assistants returned via assistant-request inherit only what
the response declares. Our response set `endCallFunctionEnabled`,
voice, transcriber, model, tools — but never `serverMessages`. So
Vapi delivered tool-calls (because tools have explicit server.url
configs) but nothing else.
Fix: declare the full subscription explicitly:
serverMessages: ['tool-calls', 'end-of-call-report',
'status-update', 'hang']
Once deployed, end-of-call-report flows to the dispatcher →
handleEndOfCallReport → vapi_call_end → SMS dispatch lights up.
Integration test updated to assert that end-of-call-report and
tool-calls are subscribed and endCallFunctionEnabled is true.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 tasks
ByteStreams-AI
added a commit
that referenced
this pull request
May 5, 2026
…ort (#29) PR #28 added serverMessages: ['tool-calls', 'end-of-call-report', 'status-update', 'hang'] which caused Vapi to reject the assistant config entirely with "Couldn't get assistant" on the next call. Vapi's enum validator rejected at least one of those values at runtime even though they're documented; the cheapest path is to ship only the value we actually need. Reduced to ['end-of-call-report']. tool-calls is delivered via the per-tool server.url config (not the assistant-level serverMessages field), and status-update / hang are not load-bearing for our pipeline. Re-add individually if a future need arises and verify each value is accepted before bundling more. Test assertion in voice.test.ts updated to reflect the minimal set + note the May 5 2026 regression in a comment. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 tasks
This was referenced May 5, 2026
ByteStreams-AI
added a commit
that referenced
this pull request
May 5, 2026
Two new docs to anchor the May 5, 2026 governance reset: - docs/project-status2.md: operational + governance snapshot. Captures why we're resetting (PR #28→#30 regression chain), what's working in cloud, what's broken (#32 voice path), the new governance rules, and the step-by-step path to stable production via #33 (staging) → #31 (prod branch) → #34 (umbrella checklist). - docs/git-policy.md: authoritative branching, commit, PR, merge, hotfix, migration, and rollback policy. Codifies the four governance rules: prod branch as deploy gate, user-only staging/commits, Issues-before-PRs, and every PR must reference an Issue. docs/project-status.md (milestone tracker) and AGENTS.md (repo conventions and follow-ups) stay as-is; these are additive.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Live SQL diagnosis surfaced the actual root cause behind every "didn't get the SMS" report in this session:
voice_callsrows from real calls hadended_at=NULLandended_reason=NULL.vapi_call_endnever fired on any call. The entire post-call SMS dispatch path was dead code from the moment we moved to dynamic assistant config.Root cause: Vapi assistants only deliver webhook events for message types declared in
serverMessages. Static dashboard-defined assistants come with a default checklist; dynamic assistants returned viaassistant-requestinherit only what the response declares. Our response setendCallFunctionEnabled, voice, transcriber, model, tools — but neverserverMessages. Vapi happily deliveredtool-calls(because tools have explicitserver.urlconfigs) butend-of-call-reportwas silently filtered out.That explains every previous failure mode in this branch:
vapi_call_endnever ran.Fix: declare the subscription list explicitly:
Integration test updated to assert
serverMessagesincludesend-of-call-reportandtool-calls, plusendCallFunctionEnabled === true.Test plan
pnpm ci:fast— 299/299ended_atshould be set,ended_reasonpopulated.sms_messagesrow exists withtwilio_status='sent'.🤖 Generated with Claude Code
Greptile Summary
Fixes a silent post-call SMS dispatch failure caused by Vapi not delivering
end-of-call-reportwebhooks to dynamically-configured assistants that never declaredserverMessages. The fix adds an explicitserverMessagessubscription list (tool-calls,end-of-call-report,status-update,hang) to thehandleAssistantRequestresponse; all four types are already handled in the existing routing switch. The integration test is updated to assert the two critical entries andendCallFunctionEnabled.Confidence Score: 5/5
Safe to merge — targeted one-field addition with a matching regression test and no side-effects on existing handlers.
The change is minimal and directly corrects a well-diagnosed root cause. The four
serverMessagesvalues exactly match the message types already handled in the routing switch, so no dead subscriptions are introduced. Test coverage for the critical field is now in place.No files require special attention.
Important Files Changed
serverMessagessubscription list to the dynamic assistant response so Vapi deliversend-of-call-reportwebhooks; all four declared message types are already handled in the routing switch.serverMessagescontaining bothend-of-call-reportandtool-calls, and forendCallFunctionEnabled === true.Reviews (1): Last reviewed commit: "fix(vapi): subscribe to end-of-call-repo..." | Re-trigger Greptile