Skip to content

fix(voice-call): preserve per-call agent routing#77763

Merged
steipete merged 3 commits into
openclaw:mainfrom
quangtran88:feat/per-agent-voice-call-routing
Jul 8, 2026
Merged

fix(voice-call): preserve per-call agent routing#77763
steipete merged 3 commits into
openclaw:mainfrom
quangtran88:feat/per-agent-voice-call-routing

Conversation

@quangtran88

@quangtran88 quangtran88 commented May 5, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes per-agent routing for Google Meet and direct Voice Call sessions. Multi-agent installations previously lost the invoking agent at tool and Gateway boundaries, so calls could speak, transcribe, or consult as the configured default agent instead of the caller's agent.

Closes #77753.

Why This Change Was Made

Agent identity is now resolved once when a call is created and frozen on its CallRecord. Response generation, realtime instructions, realtime consults, Google Meet transports, and Voice Call actions all consume that same canonical identity.

Google Meet uses a constrained trusted in-process Gateway runtime for per-agent dispatch. External callers cannot spoof agentId; explicit remote Gateway URLs remain authoritative; ambiguous non-default-agent remote or standalone routing fails closed instead of silently falling back to the wrong agent.

User Impact

  • Concurrent users hear and consult with the agent that initiated each call.
  • Google Meet Chrome, Chrome-node, and Voice Call transports preserve the same agent for the full session.
  • Existing main-agent and explicitly configured remote Gateway behavior remains supported.
  • Misconfigured non-default-agent routing returns an actionable error rather than leaking another agent's context.

Evidence

Thanks @quangtran88 for the report and original implementation.

@openclaw-barnacle openclaw-barnacle Bot added channel: voice-call Channel integration: voice-call plugin: google-meet size: L triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 5, 2026
@clawsweeper

clawsweeper Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 8, 2026, 1:59 AM ET / 05:59 UTC.

Summary
The branch adds a trusted plugin runtime Gateway helper and threads call-level agent identity through Google Meet, Voice Call call records, response generation, realtime paths, tests, and docs.

PR surface: Source +226, Tests +491, Docs +27. Total +744 across 37 files.

Reproducibility: yes. Source inspection of current main shows Google Meet and Voice Call drop the initiating agent before call creation and downstream response/realtime paths resolve the agent from Voice Call config defaults.

Review metrics: 3 noteworthy metrics.

  • Public plugin runtime surface: 1 namespace added: api.runtime.gateway. A new documented plugin-facing runtime helper affects SDK compatibility and trusted-plugin security review before merge.
  • Persisted Voice Call state: 1 optional field added: CallRecord.agentId. Persisted call records and legacy stored calls need explicit upgrade understanding even when the field is optional.
  • Fail-closed routing behavior: 1 non-default external-Gateway path changed. Google Meet per-agent routing now fails closed when plugin provenance cannot be authenticated through an explicit Gateway URL.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #77753
Summary: This PR is the active candidate fix for the canonical Google Meet and Voice Call per-agent routing bug; adjacent realtime voice customization and outbound ownership-hardening items remain distinct.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof from a real setup is added.

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

Rank-up moves:

  • [P1] Add redacted current-head live output, logs, terminal recording, or a recording proving two initiating agents route to distinct Voice Call or Google Meet identities.
  • Replace the stale/cancelled hosted proof link with current-head proof artifacts.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR provides Testbox tests, check/build output, autoreview, and a proof workflow, but no real Voice Call or Google Meet run showing after-fix per-agent routing; contributors should add redacted live output/logs/recording and update the PR body to trigger re-review.

Risk before merge

  • [P1] The proof supplied is tests/check/build/autoreview rather than a real current-head Voice Call or Google Meet run showing two initiating agents route to distinct call identities.
  • [P1] The new api.runtime.gateway surface changes the trusted plugin-to-Gateway security boundary; tests look sound, but maintainers still need to own that contract.
  • [P1] CallRecord.agentId and trusted voicecall.start.agentId alter persisted call state and fail-closed behavior for non-default-agent routing through explicit external Gateway URLs, so mixed-version or external-Gateway deployments need upgrade awareness.

Maintainer options:

  1. Require current-head live routing proof (recommended)
    Before merge, require redacted proof that two different initiating agents keep separate Voice Call or Google Meet ownership through the real runtime path.
  2. Accept scoped Gateway API risk
    Maintainers may proceed if they intentionally accept the new trusted plugin Gateway runtime surface and fail-closed upgrade behavior based on the current implementation and tests.
  3. Pause if proof or API ownership is unavailable
    If live proof or API ownership cannot be provided, pause this PR and keep the canonical bug open until a narrower replacement is ready.

Next step before merge

  • [P1] No automated code repair is indicated; the remaining action is current-head real behavior proof and maintainer acceptance of compatibility/security merge risk.

Maintainer decision needed

  • Question: Should this PR wait for current-head real Voice Call or Google Meet proof, or should maintainers explicitly override the proof gate based on Testbox evidence and the scoped Gateway implementation?
  • Rationale: The code review found no discrete patch blocker, but ClawSweeper's external-PR proof gate is not satisfied and the PR changes a compatibility/security-sensitive plugin runtime surface.
  • Likely owner: steipete — steipete authored the current maintainer pass and current PR commits across the affected Voice Call, Google Meet, Gateway, and plugin runtime surfaces.
  • Options:
    • Require live routing proof (recommended): Require redacted current-head live output, logs, terminal recording, or a short recording proving two initiating agents keep separate Voice Call or Google Meet identities before merge.
    • Override proof gate: A maintainer may explicitly accept Testbox-only proof and own the new trusted Gateway runtime contract without further contributor evidence.
    • Pause this PR: If proof cannot be produced and the Gateway API direction is not ready, keep the linked issue open and pause or replace this branch.

Security
Cleared: No concrete security regression found; the new Gateway trust seam is scope-derived, limited to bundled/trusted official plugins, and covered by no-admin-inheritance plus arbitrary-plugin rejection tests.

Review details

Best possible solution:

Land only after redacted current-head real behavior proof demonstrates distinct per-agent Voice Call or Google Meet routing and maintainers accept the scoped Gateway runtime API.

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

Yes. Source inspection of current main shows Google Meet and Voice Call drop the initiating agent before call creation and downstream response/realtime paths resolve the agent from Voice Call config defaults.

Is this the best way to solve the issue?

Yes for code direction. Freezing the agent on call creation and deriving trusted Gateway identity from plugin runtime scope is the maintainable owner-boundary fix, but real behavior proof and maintainer acceptance of the merge risks remain.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 8cbcc41ccbb9.

Label changes

Label justifications:

  • P1: The linked bug breaks real multi-agent Google Meet and Voice Call workflows by routing calls to the wrong agent identity.
  • merge-risk: 🚨 compatibility: The PR changes plugin runtime API, persisted Voice Call record shape, trusted Gateway params, and fail-closed behavior for non-default external routing.
  • merge-risk: 🚨 security-boundary: The PR creates a trusted plugin-to-Gateway dispatch path where plugin identity controls whether per-call agent routing fields are accepted.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR provides Testbox tests, check/build output, autoreview, and a proof workflow, but no real Voice Call or Google Meet run showing after-fix per-agent routing; contributors should add redacted live output/logs/recording and update the PR body to trigger re-review.
Evidence reviewed

PR surface:

Source +226, Tests +491, Docs +27. Total +744 across 37 files.

View PR surface stats
Area Files Added Removed Net
Source 22 405 179 +226
Tests 13 517 26 +491
Docs 2 28 1 +27
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 37 950 206 +744

What I checked:

  • Repository policy applied: Root AGENTS.md plus scoped docs, extensions, plugin SDK, plugins, and gateway policies were read; their plugin-boundary, SDK-surface, proof, and merge-risk guidance affected this review. (AGENTS.md:1, 8cbcc41ccbb9)
  • Current main source reproduction: Current main delegates Google Meet Twilio calls to voicecall.start without an agentId, voicecall.start does not parse one, and response generation falls back to voiceConfig.agentId/main. (extensions/google-meet/src/voice-call-gateway.ts:101, 8cbcc41ccbb9)
  • PR routing implementation: The PR adds CallRecord.agentId, accepts trusted voicecall.start agent routing, and stores the normalized per-call agent on outbound call records. (extensions/voice-call/src/types.ts:165, 78134f03f502)
  • Trusted Gateway boundary tests: PR tests cover scoped trusted plugin Gateway identity, operator.write-only dispatch, structured errors, and rejection of arbitrary plugin Gateway dispatch. (src/gateway/server-plugins.test.ts:924, 78134f03f502)
  • Changed proof is mock/test-only: The PR body and maintainer comment cite Testbox tests/check/build/autoreview, while the linked hosted proof run is cancelled and for an older SHA rather than the current head. (78134f03f502)
  • Canonical linked issue remains open: Live GitHub data shows the PR closes the still-open canonical per-agent Voice Call/Google Meet routing bug, so this PR is the candidate fix rather than cleanup-close material.

Likely related people:

  • steipete: Current PR commits and recent main history touch Google Meet Voice Call handoff, Voice Call runtime, Gateway helper docs, and plugin runtime surfaces. (role: recent area contributor and current PR maintainer pass author; confidence: high; commits: 4d1c586322e4, c4bcc0cdb1bb, 6a4069dead0f; files: extensions/google-meet/src/voice-call-gateway.ts, extensions/voice-call/index.ts, src/gateway/server-plugins.ts)
  • scoootscooob: Recent history shows realtime Meet voice-agent work on the same Google Meet and Voice Call realtime routing area. (role: adjacent realtime voice contributor; confidence: medium; commits: 79dd65e20889; files: extensions/google-meet/src/runtime.ts, extensions/voice-call/src/runtime.ts, extensions/voice-call/src/webhook/realtime-handler.ts)
  • mushuiyu886: The merged canonical Voice Call session-key ownership work overlaps with this PR's call/session ownership surface. (role: recent adjacent session-state contributor; confidence: medium; commits: 65fec9d787e3; files: extensions/voice-call/src/types.ts, extensions/voice-call/src/runtime.ts, extensions/voice-call/src/manager/events.ts)
  • lanzhi-lee: Recent main history shows related in-process Gateway dispatch work in the same core Gateway plugin runtime area. (role: gateway dispatch contributor; confidence: medium; commits: 58bab0c2761e; files: src/gateway/server-plugins.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.
Review history (2 earlier review cycles)
  • reviewed 2026-07-03T21:00:40.180Z sha ce03055 :: needs real behavior proof before merge. :: [P1] Bind gateway owner identity to runtime scope | [P2] Preserve the Voice Call start timeout
  • reviewed 2026-07-07T15:27:06.051Z sha c4bcc0c :: needs real behavior proof before merge. :: none

@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts size: XL gateway Gateway runtime proof: supplied External PR includes structured after-fix real behavior proof. and removed size: L triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 5, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 6, 2026
@openclaw-barnacle openclaw-barnacle Bot added channel: line Channel integration: line and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. labels May 7, 2026
@quangtran88
quangtran88 force-pushed the feat/per-agent-voice-call-routing branch from c0f6a9c to 989bedb Compare May 7, 2026 17:02
@openclaw-barnacle openclaw-barnacle Bot removed the channel: line Channel integration: line label May 7, 2026
@quangtran88
quangtran88 force-pushed the feat/per-agent-voice-call-routing branch from 989bedb to ce03055 Compare May 8, 2026 02:10
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label May 31, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. labels May 31, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 1, 2026
@clawsweeper clawsweeper Bot removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 18, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 18, 2026
@steipete
steipete force-pushed the feat/per-agent-voice-call-routing branch from ce03055 to 4d1c586 Compare July 7, 2026 15:11
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation plugin: file-transfer and removed scripts Repository scripts labels Jul 7, 2026
@steipete steipete changed the title feat(google-meet,voice-call): route voice calls to calling agent fix(voice-call): preserve per-call agent routing Jul 7, 2026
@steipete

steipete commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Land-ready maintainer pass completed and merged.

What changed:

  • freezes the effective agent on every inbound/outbound Voice Call record;
  • uses that frozen identity for classic responses, realtime instructions, and realtime consults;
  • threads the invoking agent through Google Meet join/create/test-speech and Chrome/Chrome-node/Voice Call transports;
  • adds a constrained trusted plugin Gateway seam, rejects external agent spoofing, preserves structured errors, and fails closed where non-default routing cannot be trusted;
  • documents the routing contract while preserving contributor attribution in the landed commit.

Exact proof on Blacksmith Testbox:

  • corepack pnpm test src/gateway/server-plugins.test.ts src/plugins/registry.runtime-config.test.ts extensions/google-meet/index.test.ts extensions/google-meet/index.create.test.ts extensions/google-meet/src/voice-call-gateway.test.ts extensions/voice-call/index.test.ts extensions/voice-call/src/realtime-agent-context.test.ts extensions/voice-call/src/runtime.test.ts extensions/voice-call/src/webhook/realtime-handler.test.ts — 323 passed.
  • OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1 OPENCLAW_CHANGED_LANES_RAW_SYNC=1 corepack pnpm check:changed — passed in 11m31s.
  • corepack pnpm build — passed in 1m59s.
  • Fresh structured autoreview — no accepted/actionable findings; patch correct, confidence 0.90.

Hosted exact-head proof for 78134f03f502e37f938987ca7ea04bfa5450acb5: 115 successful jobs, no failures: https://github.com/openclaw/openclaw/actions/runs/28920709136

Live Google Meet proof gap: the configured OAuth doctor reached Google and returned invalid_grant, so authenticated room creation/join could not be exercised. The existing Chrome bridge exposed no logged-in tab, so there was no approved browser fallback. No routing-specific live failure was observed; the blocker is the saved OAuth grant and browser availability.

Landed as 19f7b72a74731438f15aafbfc7c84593f6151dfc.

Thanks @quangtran88 for the report and initial implementation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. labels Jul 7, 2026
@steipete
steipete merged commit 19f7b72 into openclaw:main Jul 8, 2026
218 checks passed
@steipete

steipete commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 8, 2026
* fix(voice-call): preserve per-call agent routing

Co-authored-by: Tran Quang <[email protected]>

* chore: keep release notes in PR metadata

---------

Co-authored-by: Peter Steinberger <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
* fix(voice-call): preserve per-call agent routing

Co-authored-by: Tran Quang <[email protected]>

* chore: keep release notes in PR metadata

---------

Co-authored-by: Peter Steinberger <[email protected]>
Co-authored-by: Peter Steinberger <[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 docs Improvements or additions to documentation gateway Gateway runtime merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P1 High-priority user-facing bug, regression, or broken workflow. plugin: file-transfer plugin: google-meet proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: google_meet & voice_call route every call to single configured agent in multi-agent deployments

2 participants