From fe107d5256f33650da777d7f9c2fb15cc2b04991 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 3 May 2026 20:28:06 -0700 Subject: [PATCH] fix(google-meet): require voice call setup entry --- CHANGELOG.md | 1 + extensions/google-meet/index.test.ts | 35 ++++++++++++++++++++++++++++ extensions/google-meet/src/setup.ts | 3 ++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64baf0be4c8..1a42bcdf23c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ Docs: https://docs.openclaw.ai - Google Meet: split realtime provider config into agent-mode transcription and bidi-mode voice providers, and migrate legacy Gemini Live bidi configs with `doctor --fix`, so Gemini Live can back direct bidi fallback without breaking the default OpenClaw agent talk-back path. - Google Meet: expose `voiceCall.postDtmfSpeechDelayMs` in the plugin manifest schema and setup hints, so manifest-based config editing accepts the runtime-supported Twilio delay key. Thanks @vincentkoc. - Google Meet: keep explicit non-Google `realtime.provider` values as the transcription provider compatibility fallback when `realtime.transcriptionProvider` is unset. Thanks @vincentkoc. +- Google Meet: make Twilio setup status require an enabled `voice-call` plugin entry instead of treating a missing entry as ready. Thanks @vincentkoc. - Telegram: render shared interactive reply buttons in reply delivery so plugin approval messages show inline keyboards. (#76238) Thanks @keshavbotagent. - Agents/cli-runner: drop a saved `claude-cli` resume sessionId at preparation time when its on-disk transcript no longer exists in `~/.claude/projects/`, so a stale binding from a half-installed `update.run` cannot trap follow-up runs (auto-reply / Telegram direct) in a `claude --resume` timeout loop; the run starts fresh and the new sessionId is written back through the existing post-run flow. (#77030; refs #77011) Thanks @openperf. - Release validation: install the cross-OS TypeScript harness through Windows-safe Node/npm shims so native Windows package checks reach the OpenClaw smoke suites instead of exiting before artifact capture. Thanks @vincentkoc. diff --git a/extensions/google-meet/index.test.ts b/extensions/google-meet/index.test.ts index bf25c84084b..d80a5ddfa46 100644 --- a/extensions/google-meet/index.test.ts +++ b/extensions/google-meet/index.test.ts @@ -1868,6 +1868,41 @@ describe("google-meet plugin", () => { ); }); + it("reports missing voice-call plugin entry for explicit Twilio transport", async () => { + vi.stubEnv("TWILIO_ACCOUNT_SID", "AC123"); + vi.stubEnv("TWILIO_AUTH_TOKEN", "secret"); + vi.stubEnv("TWILIO_FROM_NUMBER", "+15550001234"); + const { tools } = setup( + { defaultTransport: "chrome" }, + { + fullConfig: { + plugins: { + allow: ["google-meet", "voice-call"], + entries: {}, + }, + }, + }, + ); + const tool = tools[0] as { + execute: ( + id: string, + params: unknown, + ) => Promise<{ details: { ok?: boolean; checks?: unknown[] } }>; + }; + + const result = await tool.execute("id", { action: "setup_status", transport: "twilio" }); + + expect(result.details.ok).toBe(false); + expect(result.details.checks).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: "twilio-voice-call-plugin", + ok: false, + }), + ]), + ); + }); + it("reports missing Twilio dial plan for explicit Twilio setup", async () => { vi.stubEnv("TWILIO_ACCOUNT_SID", "AC123"); vi.stubEnv("TWILIO_AUTH_TOKEN", "secret"); diff --git a/extensions/google-meet/src/setup.ts b/extensions/google-meet/src/setup.ts index 17958b4f361..704723b3653 100644 --- a/extensions/google-meet/src/setup.ts +++ b/extensions/google-meet/src/setup.ts @@ -225,7 +225,8 @@ export function getGoogleMeetSetupStatus( Object.hasOwn(pluginEntries, "voice-call")); if (shouldCheckTwilioDelegation) { const voiceCallAllowed = !Array.isArray(pluginAllow) || pluginAllow.includes("voice-call"); - const voiceCallEnabled = voiceCallEntry.enabled !== false; + const hasVoiceCallEntry = Object.hasOwn(pluginEntries, "voice-call"); + const voiceCallEnabled = hasVoiceCallEntry && voiceCallEntry.enabled !== false; checks.push({ id: "twilio-voice-call-plugin", ok: voiceCallAllowed && voiceCallEnabled,