Skip to content

fix(voice-call): track Twilio streams after connect#90607

Merged
clawsweeper[bot] merged 1 commit into
openclaw:mainfrom
sahibzada-allahyar:fastino-81122-twilio-hold-music
Jun 6, 2026
Merged

fix(voice-call): track Twilio streams after connect#90607
clawsweeper[bot] merged 1 commit into
openclaw:mainfrom
sahibzada-allahyar:fastino-81122-twilio-hold-music

Conversation

@sahibzada-allahyar
Copy link
Copy Markdown
Contributor

@sahibzada-allahyar sahibzada-allahyar commented Jun 5, 2026

Fixes #81122.

What changed

  • Track a Twilio call as active only when the media stream actually connects via registerCallStream.
  • Stop marking a call active when TwiML is merely generated.
  • Update existing queue/cleanup tests to explicitly register connected streams.
  • Add regression coverage for the case where an inbound call receives stream TwiML but never opens a media stream.

Real behavior proof

Behavior addressed: Twilio inbound queueing no longer treats generated stream TwiML as an active media stream. If the first inbound call receives streaming TwiML but never opens a WebSocket media stream, a later inbound call receives streaming TwiML instead of being sent to hold-queue.

Real environment tested: macOS arm64 local OpenClaw checkout. Base proof used clean origin/main at 1a3ce7c2 with only the new regression-test diff applied in /private/tmp/openclaw-81122-before-9071. Fix proof used branch fastino-81122-twilio-hold-music at 22575a9f. Package manager was pnpm v11.2.2.

Exact steps or command run after the patch: Ran the Twilio provider command on the patched branch: pnpm test extensions/voice-call/src/providers/twilio.test.ts --reporter verbose. Also ran git diff --check, pnpm exec oxfmt --check extensions/voice-call/src/providers/twilio.ts extensions/voice-call/src/providers/twilio.test.ts, and pnpm exec oxlint extensions/voice-call/src/providers/twilio.ts extensions/voice-call/src/providers/twilio.test.ts --report-unused-disable-directives-severity error. For before evidence, I created a clean origin/main worktree and applied only the new regression-test diff, then ran the same Twilio provider command.

Evidence after fix: Copied terminal output and TwiML payload from the local OpenClaw provider path. Before fix, the second inbound call produced hold queue TwiML instead of a stream URL:

$ pnpm test extensions/voice-call/src/providers/twilio.test.ts --reporter verbose
FAIL |extension-voice-call| extensions/voice-call/src/providers/twilio.test.ts > TwilioProvider > does not block subsequent call when first call never opens a media stream
AssertionError: expected ... to contain wss://example.ngrok.app/voice/stream

Received:
<Response>
  <Say voice="alice">Please hold while we connect you.</Say>
  <Enqueue waitUrl="/voice/hold-music">hold-queue</Enqueue>
</Response>

Test Files 1 failed (1)
Tests 1 failed | 24 passed (25)

After fix, the same provider path returned streaming TwiML for the second inbound call; the regression checks for wss://example.ngrok.app/voice/stream, <Connect>, and no hold-queue payload:

$ pnpm test extensions/voice-call/src/providers/twilio.test.ts --reporter verbose
✓ |extension-voice-call| extensions/voice-call/src/providers/twilio.test.ts > TwilioProvider > does not block subsequent call when first call never opens a media stream 0ms
Test Files 1 passed (1)
Tests 25 passed (25)
[test] passed 1 Vitest shard in 7.98s

$ git diff --check
# passed with no output

$ pnpm exec oxfmt --check extensions/voice-call/src/providers/twilio.ts extensions/voice-call/src/providers/twilio.test.ts
All matched files use the correct format.

$ pnpm exec oxlint extensions/voice-call/src/providers/twilio.ts extensions/voice-call/src/providers/twilio.test.ts --report-unused-disable-directives-severity error
# passed with no output

Observed result after fix: Before the fix, the second inbound call was sent to hold-queue after the first call generated streaming TwiML but never registered a media stream. After the fix, the second inbound call receives streaming TwiML because no call is considered active until registerCallStream runs for a real media stream.

What was not tested: A live Twilio account was not exercised. The exercised behavior is the local Twilio provider TwiML decision path and stream-registration state transition that caused #81122.

Platforms tested

  • macOS arm64 local checkout

@openclaw-barnacle openclaw-barnacle Bot added channel: voice-call Channel integration: voice-call size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 5, 2026
@sahibzada-allahyar
Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Jun 5, 2026

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Jun 5, 2026

Codex review: passed. Reviewed June 5, 2026, 10:14 PM ET / 02:14 UTC.

Summary
The PR moves Twilio inbound active-stream tracking from TwiML generation to registerCallStream and updates provider tests for connected-stream and no-stream cases.

PR surface: Source -3, Tests +23. Total +20 across 2 files.

Reproducibility: yes. from source inspection and supplied before/after output: on current main, one inbound TwiML response adds activeStreamCalls, so a second inbound parse queues even when no media stream registered. I did not run tests in this read-only review.

Review metrics: none identified.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦞 diamond lobster
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Risk before merge

  • [P1] The supplied proof does not exercise a live Twilio account, so real carrier webhook timing remains a live-smoke gap rather than a code-level blocker.

Maintainer options:

  1. Decide the mitigation before merge
    Land the narrow provider-owned fix after required checks, keeping the queue active only for registered media streams and preserving the linked regression test.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P2] No repair job is needed; the existing PR is the landing vehicle once required checks and maintainer policy gates pass.

Security
Cleared: The diff only changes in-memory Twilio stream state and focused tests; I found no concrete security or supply-chain regression.

Review details

Best possible solution:

Land the narrow provider-owned fix after required checks, keeping the queue active only for registered media streams and preserving the linked regression test.

Do we have a high-confidence way to reproduce the issue?

Yes from source inspection and supplied before/after output: on current main, one inbound TwiML response adds activeStreamCalls, so a second inbound parse queues even when no media stream registered. I did not run tests in this read-only review.

Is this the best way to solve the issue?

Yes: moving active-stream state to registerCallStream is the narrowest owner-boundary fix because webhook.ts calls that method from the actual media-stream connection path. A TTL around TwiML generation would preserve a pending-call state that caused this failure and would add timer complexity.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 3a2f54e6a866.

Label changes

Label changes:

  • add rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • add status: 🚀 automerge armed: This PR is in ClawSweeper's automerge lane. Sufficient (terminal): The PR body supplies before/after terminal output from the local Twilio provider path showing the regression and fixed TwiML result; live Twilio was explicitly not tested.
  • remove rating: 🐚 platinum hermit: Current PR rating is rating: 🦞 diamond lobster, so this older rating label is no longer current.
  • remove status: 👀 ready for maintainer look: Current PR status label is status: 🚀 automerge armed.

Label justifications:

  • P1: The PR addresses a real Twilio voice-call workflow regression where later inbound callers can be routed to hold music after a failed/no-stream call.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 🚀 automerge armed: This PR is in ClawSweeper's automerge lane. Sufficient (terminal): The PR body supplies before/after terminal output from the local Twilio provider path showing the regression and fixed TwiML result; live Twilio was explicitly not tested.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body supplies before/after terminal output from the local Twilio provider path showing the regression and fixed TwiML result; live Twilio was explicitly not tested.
Evidence reviewed

PR surface:

Source -3, Tests +23. Total +20 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 1 4 -3
Tests 1 23 0 +23
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 24 4 +20

What I checked:

Likely related people:

  • Hershey Goldberger: Authored the call-waiting queue change that added activeStreamCalls and the original inbound queue tests. (role: introduced behavior; confidence: high; commits: dee7cda1ec51; files: extensions/voice-call/src/providers/twilio.ts, extensions/voice-call/src/providers/twilio.test.ts)
  • steipete: Committed the original call-waiting queue change and has multiple nearby voice-call webhook/provider lifecycle commits in the same area. (role: merger and adjacent owner; confidence: medium; commits: dee7cda1ec51, 9f691099dbd9; files: extensions/voice-call/src/providers/twilio.ts, extensions/voice-call/src/webhook.ts)
  • Ayaan Zaidi: Current main line blame for the Twilio provider and webhook files is carried through a recent repository-wide snapshot commit touching this area. (role: recent area contributor; confidence: medium; commits: 61d121f1caa2; files: extensions/voice-call/src/providers/twilio.ts, extensions/voice-call/src/webhook.ts)
  • Vincent Koc: The latest release baseline commit reintroduced the current Twilio provider/test files and is useful provenance for shipped behavior comparison. (role: release baseline contributor; confidence: medium; commits: 2e08f0f4221f; files: extensions/voice-call/src/providers/twilio.ts, extensions/voice-call/src/providers/twilio.test.ts, extensions/voice-call/src/providers/twilio/twiml-policy.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P1 High-priority user-facing bug, regression, or broken workflow. labels Jun 5, 2026
@Takhoffman
Copy link
Copy Markdown
Contributor

@clawsweeper automerge

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Jun 6, 2026

🦞✅
ClawSweeper merged this PR after the passing review.

Source: clawsweeper[bot]
Feedback: structured ClawSweeper verdict: pass (sha=22575a9f277d1fe4aa12e79484c3e9dfb11fd48f)
Merge status: merged by ClawSweeper automerge
Merged at: 2026-06-06T02:15:01Z
Merge commit: 9e29375cecab

What merged:

  • The PR moves Twilio inbound active-stream tracking from TwiML generation to registerCallStream and updates provider tests for connected-stream and no-stream cases.
  • PR surface: Source -3, Tests +23. Total +20 across 2 files.
  • Reproducibility: yes. from source inspection and supplied before/after output: on current main, one inbound ... nd inbound parse queues even when no media stream registered. I did not run tests in this read-only review.

Automerge notes:

  • No ClawSweeper repair was needed after automerge opt-in.

The automerge loop is complete.

Automerge progress:

  • 2026-06-06 02:06:58 UTC review queued 22575a9f277d (queued)
  • 2026-06-06 02:14:46 UTC review passed 22575a9f277d (structured ClawSweeper verdict: pass (sha=22575a9f277d1fe4aa12e79484c3e9dfb11fd...)
  • 2026-06-06 02:15:04 UTC merged 22575a9f277d (merged by ClawSweeper automerge)

@clawsweeper clawsweeper Bot added clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge clawsweeper:human-review Needs maintainer review before ClawSweeper can continue labels Jun 6, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Jun 6, 2026

🦞✅
ClawSweeper is pausing this repair loop for human review.

Source: clawsweeper[bot]
Reason: - No automated repair is needed; maintainers should review and land this P1 fix after required checks and any desired live Twilio smoke.; Cleared: No concrete security or supply-chain concern found; the diff only changes in-memory Twilio stream state handling and provider tests. (sha=22575a9f277d1fe4aa12e79484c3e9dfb11fd48f)

Why human review is needed:
This item has security-sensitive risk. ClawSweeper is pausing instead of making an autonomous change that could affect trust, credentials, permissions, or exposure.

What the maintainer can do as a next step:
If the maintainer accepts the current risk and wants ClawSweeper to continue merge gates, comment @clawsweeper approve. If the security-sensitive detail still needs changes, describe the safe path or push the fix, then comment @clawsweeper automerge. If the risk should not be automated, keep the PR paused for manual review or comment @clawsweeper stop.

I added clawsweeper:human-review and left the final call with a maintainer.

@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 🚀 automerge armed This PR is in ClawSweeper's automerge lane. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. clawsweeper:human-review Needs maintainer review before ClawSweeper can continue labels Jun 6, 2026
@clawsweeper clawsweeper Bot merged commit 9e29375 into openclaw:main Jun 6, 2026
258 of 275 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 6, 2026
Summary:
- The PR moves Twilio inbound active-stream tracking from TwiML generation to `registerCallStream` and updates provider tests for connected-stream and no-stream cases.
- PR surface: Source -3, Tests +23. Total +20 across 2 files.
- Reproducibility: yes. from source inspection and supplied before/after output: on current main, one inbound  ... nd inbound parse queues even when no media stream registered. I did not run tests in this read-only review.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head 22575a9.
- Required merge gates passed before the squash merge.

Prepared head SHA: 22575a9
Review: openclaw#90607 (comment)

Co-authored-by: Sahibzada Allahyar <[email protected]>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <[email protected]>
849261680 pushed a commit to 849261680/openclaw that referenced this pull request Jun 7, 2026
Summary:
- The PR moves Twilio inbound active-stream tracking from TwiML generation to `registerCallStream` and updates provider tests for connected-stream and no-stream cases.
- PR surface: Source -3, Tests +23. Total +20 across 2 files.
- Reproducibility: yes. from source inspection and supplied before/after output: on current main, one inbound  ... nd inbound parse queues even when no media stream registered. I did not run tests in this read-only review.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head 22575a9.
- Required merge gates passed before the squash merge.

Prepared head SHA: 22575a9
Review: openclaw#90607 (comment)

Co-authored-by: Sahibzada Allahyar <[email protected]>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: voice-call Channel integration: voice-call clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: XS status: 🚀 automerge armed This PR is in ClawSweeper's automerge lane.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Twilio voice-call can get stuck in hold music after failed/no-stream call

2 participants