@openclaw/google-meet 2026.5.3 → 2026.5.4-beta.1

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.
@@ -1,7 +1,7 @@
1
1
  import { d as createGoogleMeetSpace, f as endGoogleMeetActiveConference, g as fetchLatestGoogleMeetConferenceRecord, h as fetchGoogleMeetSpace, m as fetchGoogleMeetAttendance, p as fetchGoogleMeetArtifacts, u as buildGoogleMeetPreflightReport } from "./chrome-create-B0wV2zaj.js";
2
2
  import { n as findGoogleMeetCalendarEvent, r as listGoogleMeetCalendarEvents, t as buildGoogleMeetCalendarDayWindow } from "./calendar-6EQiwLUb.js";
3
3
  import { buildGoogleMeetAuthUrl, createGoogleMeetOAuthState, createGoogleMeetPkce, exchangeGoogleMeetAuthCode, resolveGoogleMeetAccessToken, waitForGoogleMeetAuthCode } from "./oauth-BJwzuzT-.js";
4
- import { hasCreateSpaceConfigInput, resolveCreateSpaceConfig } from "./create-0ye_2zVk.js";
4
+ import { hasCreateSpaceConfigInput, resolveCreateSpaceConfig } from "./create-mHH3keLH.js";
5
5
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
6
6
  import { callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
7
7
  import path from "node:path";
@@ -118,7 +118,9 @@ function writeDoctorStatus(status) {
118
118
  if (!session.chrome) continue;
119
119
  writeStdoutLine("node: %s", session.chrome?.nodeId ?? "local/none");
120
120
  writeStdoutLine("audio bridge: %s", session.chrome?.audioBridge?.type ?? "none");
121
- writeStdoutLine("provider: %s", session.chrome?.audioBridge?.provider ?? session.realtime.provider ?? "n/a");
121
+ const bridgeProvider = session.chrome?.audioBridge?.provider ?? session.realtime.transcriptionProvider ?? session.realtime.provider ?? "n/a";
122
+ writeStdoutLine(session.mode === "agent" ? "transcription provider: %s" : "provider: %s", bridgeProvider);
123
+ if (session.realtime.enabled) writeStdoutLine("talk-back mode: %s", session.realtime.strategy ?? session.mode);
122
124
  writeStdoutLine("in call: %s", formatBoolean(health?.inCall));
123
125
  writeStdoutLine("lobby waiting: %s", formatBoolean(health?.lobbyWaiting));
124
126
  writeStdoutLine("captioning: %s", formatBoolean(health?.captioning));
@@ -138,6 +140,11 @@ function writeDoctorStatus(status) {
138
140
  writeStdoutLine("realtime ready: %s", formatBoolean(health?.realtimeReady));
139
141
  writeStdoutLine("audio input active: %s", formatBoolean(health?.audioInputActive));
140
142
  writeStdoutLine("audio output active: %s", formatBoolean(health?.audioOutputActive));
143
+ writeStdoutLine("meet output routed: %s", formatBoolean(health?.audioOutputRouted));
144
+ if (health?.audioOutputDeviceLabel || health?.audioOutputRouteError) {
145
+ writeStdoutLine("meet output device: %s", formatOptional(health.audioOutputDeviceLabel));
146
+ writeStdoutLine("meet output route error: %s", formatOptional(health.audioOutputRouteError));
147
+ }
141
148
  writeStdoutLine("last input: %s (%s bytes)", formatOptional(health?.lastInputAt), health?.lastInputBytes ?? 0);
142
149
  writeStdoutLine("last output: %s (%s bytes)", formatOptional(health?.lastOutputAt), health?.lastOutputBytes ?? 0);
143
150
  writeStdoutLine("bridge closed: %s", formatBoolean(health?.bridgeClosed));
@@ -862,7 +869,7 @@ function registerGoogleMeetCli(params) {
862
869
  if (!options.json) writeStdoutLine("Paste this into plugins.entries.google-meet.config:");
863
870
  writeStdoutJson(payload);
864
871
  });
865
- root.command("create").description("Create a new Google Meet space and print its meeting URL").option("--access-token <token>", "Access token override").option("--refresh-token <token>", "Refresh token override").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds").option("--access-type <type>", "Google Meet SpaceConfig accessType for API create: OPEN, TRUSTED, or RESTRICTED").option("--entry-point-access <type>", "Google Meet SpaceConfig entryPointAccess for API create: ALL or CREATOR_APP_ONLY").option("--no-join", "Only create the meeting URL; do not join it").option("--transport <transport>", "Join transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Join mode: realtime for live talk-back, transcribe for observe/control").option("--message <text>", "Realtime speech to trigger after join").option("--dial-in-number <phone>", "Meet dial-in number for Twilio transport").option("--pin <pin>", "Meet phone PIN; # is appended if omitted").option("--dtmf-sequence <sequence>", "Explicit Twilio DTMF sequence").option("--json", "Print JSON output", false).action(async (options) => {
872
+ root.command("create").description("Create a new Google Meet space and print its meeting URL").option("--access-token <token>", "Access token override").option("--refresh-token <token>", "Refresh token override").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds").option("--access-type <type>", "Google Meet SpaceConfig accessType for API create: OPEN, TRUSTED, or RESTRICTED").option("--entry-point-access <type>", "Google Meet SpaceConfig entryPointAccess for API create: ALL or CREATOR_APP_ONLY").option("--no-join", "Only create the meeting URL; do not join it").option("--transport <transport>", "Join transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Join mode: agent, bidi, or transcribe").option("--message <text>", "Realtime speech to trigger after join").option("--dial-in-number <phone>", "Meet dial-in number for Twilio transport").option("--pin <pin>", "Meet phone PIN; # is appended if omitted").option("--dtmf-sequence <sequence>", "Explicit Twilio DTMF sequence").option("--json", "Print JSON output", false).action(async (options) => {
866
873
  if (options.join !== false) {
867
874
  const delegated = await callGoogleMeetGateway({
868
875
  callGateway,
@@ -970,7 +977,7 @@ function registerGoogleMeetCli(params) {
970
977
  writeStdoutLine("ended: yes");
971
978
  writeStdoutLine("token source: %s", token.refreshed ? "refresh-token" : "cached-access-token");
972
979
  });
973
- root.command("join").argument("[url]", "Explicit https://meet.google.com/... URL").option("--transport <transport>", "Transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Mode: realtime for live talk-back, transcribe to join without the realtime voice bridge").option("--message <text>", "Realtime speech to trigger after join").option("--dial-in-number <phone>", "Meet dial-in number for Twilio transport").option("--pin <pin>", "Meet phone PIN; # is appended if omitted").option("--dtmf-sequence <sequence>", "Explicit Twilio DTMF sequence").action(async (url, options) => {
980
+ root.command("join").argument("[url]", "Explicit https://meet.google.com/... URL").option("--transport <transport>", "Transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Mode: agent, bidi, or transcribe").option("--message <text>", "Realtime speech to trigger after join").option("--dial-in-number <phone>", "Meet dial-in number for Twilio transport").option("--pin <pin>", "Meet phone PIN; # is appended if omitted").option("--dtmf-sequence <sequence>", "Explicit Twilio DTMF sequence").action(async (url, options) => {
974
981
  const payload = {
975
982
  url: resolveMeetingInput(params.config, url),
976
983
  transport: options.transport,
@@ -993,7 +1000,7 @@ function registerGoogleMeetCli(params) {
993
1000
  }
994
1001
  writeStdoutJson((await (await params.ensureRuntime()).join(payload)).session);
995
1002
  });
996
- root.command("test-speech").argument("[url]", "Explicit https://meet.google.com/... URL").option("--transport <transport>", "Transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Mode: realtime for live talk-back, transcribe to join without the realtime voice bridge").option("--message <text>", "Realtime speech to trigger", "Say exactly: Google Meet speech test complete.").action(async (url, options) => {
1003
+ root.command("test-speech").argument("[url]", "Explicit https://meet.google.com/... URL").option("--transport <transport>", "Transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Mode: agent, bidi, or transcribe").option("--message <text>", "Realtime speech to trigger", "Say exactly: Google Meet speech test complete.").action(async (url, options) => {
997
1004
  const payload = {
998
1005
  url: resolveMeetingInput(params.config, url),
999
1006
  transport: options.transport,
@@ -1332,7 +1339,7 @@ function registerGoogleMeetCli(params) {
1332
1339
  }
1333
1340
  writeRecoverCurrentTabResult(result);
1334
1341
  });
1335
- root.command("setup").description("Show Google Meet transport setup status").option("--transport <transport>", "Transport to check: chrome, chrome-node, or twilio").option("--mode <mode>", "Mode to check: realtime or transcribe").option("--json", "Print JSON output", false).action(async (options) => {
1342
+ root.command("setup").description("Show Google Meet transport setup status").option("--transport <transport>", "Transport to check: chrome, chrome-node, or twilio").option("--mode <mode>", "Mode to check: agent, bidi, or transcribe").option("--json", "Print JSON output", false).action(async (options) => {
1336
1343
  const status = await (await params.ensureRuntime()).setupStatus({
1337
1344
  transport: options.transport,
1338
1345
  mode: options.mode
@@ -6,7 +6,8 @@ function normalizeTransport(value) {
6
6
  return value === "chrome" || value === "chrome-node" || value === "twilio" ? value : void 0;
7
7
  }
8
8
  function normalizeMode(value) {
9
- return value === "realtime" || value === "transcribe" ? value : void 0;
9
+ if (value === "realtime") return "agent";
10
+ return value === "agent" || value === "bidi" || value === "transcribe" ? value : void 0;
10
11
  }
11
12
  function normalizeGoogleMeetAccessType(value) {
12
13
  const normalized = normalizeOptionalString(value)?.toUpperCase().replaceAll("-", "_");
@@ -93,7 +94,8 @@ async function createAndJoinMeetFromParams(params) {
93
94
  dialInNumber: normalizeOptionalString(params.raw.dialInNumber),
94
95
  pin: normalizeOptionalString(params.raw.pin),
95
96
  dtmfSequence: normalizeOptionalString(params.raw.dtmfSequence),
96
- message: normalizeOptionalString(params.raw.message)
97
+ message: normalizeOptionalString(params.raw.message),
98
+ requesterSessionKey: normalizeOptionalString(params.raw.requesterSessionKey)
97
99
  });
98
100
  return {
99
101
  ...created,
@@ -0,0 +1,56 @@
1
+ //#region extensions/google-meet/src/config-compat.ts
2
+ function asRecord(value) {
3
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
4
+ }
5
+ function normalizeProviderId(value) {
6
+ return typeof value === "string" && value.trim() ? value.trim().toLowerCase() : void 0;
7
+ }
8
+ function hasOwn(record, key) {
9
+ return Object.prototype.hasOwnProperty.call(record, key);
10
+ }
11
+ function hasLegacyGoogleRealtimeProvider(value) {
12
+ const realtime = asRecord(value);
13
+ if (!realtime || normalizeProviderId(realtime.provider) !== "google") return false;
14
+ return !hasOwn(realtime, "voiceProvider") || !hasOwn(realtime, "transcriptionProvider");
15
+ }
16
+ const legacyConfigRules = [{
17
+ path: [
18
+ "plugins",
19
+ "entries",
20
+ "google-meet",
21
+ "config",
22
+ "realtime"
23
+ ],
24
+ message: "plugins.entries.google-meet.config.realtime.provider=\"google\" is legacy for Gemini Live bidi mode; use realtime.voiceProvider=\"google\" and realtime.transcriptionProvider=\"openai\". Run \"openclaw doctor --fix\".",
25
+ match: hasLegacyGoogleRealtimeProvider
26
+ }];
27
+ function migrateGoogleMeetLegacyRealtimeProvider(config) {
28
+ const rawRealtime = asRecord(asRecord(asRecord(config.plugins?.entries?.["google-meet"])?.config)?.realtime);
29
+ if (!rawRealtime || !hasLegacyGoogleRealtimeProvider(rawRealtime)) return null;
30
+ const nextConfig = structuredClone(config);
31
+ const nextPlugins = asRecord(nextConfig.plugins) ?? {};
32
+ nextConfig.plugins = nextPlugins;
33
+ const nextEntries = asRecord(nextPlugins.entries) ?? {};
34
+ nextPlugins.entries = nextEntries;
35
+ const nextEntry = asRecord(nextEntries["google-meet"]) ?? {};
36
+ nextEntries["google-meet"] = nextEntry;
37
+ const nextPluginConfig = asRecord(nextEntry.config) ?? {};
38
+ nextEntry.config = nextPluginConfig;
39
+ const nextRealtime = asRecord(nextPluginConfig.realtime) ?? {};
40
+ nextPluginConfig.realtime = nextRealtime;
41
+ nextRealtime.provider = "openai";
42
+ if (!hasOwn(nextRealtime, "transcriptionProvider")) nextRealtime.transcriptionProvider = "openai";
43
+ if (!hasOwn(nextRealtime, "voiceProvider")) nextRealtime.voiceProvider = "google";
44
+ return {
45
+ config: nextConfig,
46
+ changes: ["Moved Google Meet legacy realtime.provider=\"google\" intent to realtime.voiceProvider=\"google\" and realtime.transcriptionProvider=\"openai\"."]
47
+ };
48
+ }
49
+ function normalizeCompatibilityConfig({ cfg }) {
50
+ return migrateGoogleMeetLegacyRealtimeProvider(cfg) ?? {
51
+ config: cfg,
52
+ changes: []
53
+ };
54
+ }
55
+ //#endregion
56
+ export { legacyConfigRules, normalizeCompatibilityConfig };