@openclaw/google-meet 2026.5.28 → 2026.5.31-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.
package/dist/index.js CHANGED
@@ -1,13 +1,14 @@
1
- import { a as isSameMeetUrlForReuse, c as resolveChromeNode, f as endGoogleMeetActiveConference, g as fetchLatestGoogleMeetConferenceRecord, h as fetchGoogleMeetSpace, i as callBrowserProxyOnNode, l as resolveChromeNodeInfo, m as fetchGoogleMeetAttendance, n as isGoogleMeetBrowserManualActionError, o as normalizeMeetUrlForReuse, p as fetchGoogleMeetArtifacts, r as asBrowserTabs, s as readBrowserTab, t as createMeetWithBrowserProxyOnNode, u as buildGoogleMeetPreflightReport } from "./chrome-create-B3zyjf5f.js";
2
- import { n as findGoogleMeetCalendarEvent, r as listGoogleMeetCalendarEvents, t as buildGoogleMeetCalendarDayWindow } from "./calendar-IxWkFtfn.js";
1
+ import { a as isSameMeetUrlForReuse, c as resolveChromeNode, f as endGoogleMeetActiveConference, g as fetchLatestGoogleMeetConferenceRecord, h as fetchGoogleMeetSpace, i as callBrowserProxyOnNode, l as resolveChromeNodeInfo, m as fetchGoogleMeetAttendance, n as isGoogleMeetBrowserManualActionError, o as normalizeMeetUrlForReuse, p as fetchGoogleMeetArtifacts, r as asBrowserTabs, s as readBrowserTab, t as createMeetWithBrowserProxyOnNode, u as buildGoogleMeetPreflightReport } from "./chrome-create-By4DuikO.js";
2
+ import { a as buildGoogleMeetCalendarDayWindow, i as resolveGoogleMeetGatewayOperationTimeoutMs, n as DEFAULT_GOOGLE_MEET_AUDIO_OUTPUT_COMMAND, o as findGoogleMeetCalendarEvent, r as resolveGoogleMeetConfig, s as listGoogleMeetCalendarEvents, t as DEFAULT_GOOGLE_MEET_AUDIO_INPUT_COMMAND } from "./config-Co24FcXM.js";
3
3
  import { optionalPositiveIntegerSchema, readPositiveIntegerParam } from "openclaw/plugin-sdk/channel-actions";
4
4
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
5
5
  import { ErrorCodes, GatewayClient, callGatewayFromCli, errorShape, startGatewayClientWhenEventLoopReady } from "openclaw/plugin-sdk/gateway-runtime";
6
6
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
7
- import { asRecord, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalTrimmedStringList, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
7
+ import { asRecord, normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { Type } from "typebox";
9
9
  import { isBlockedHostnameOrIp } from "openclaw/plugin-sdk/ssrf-runtime";
10
- import { REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME, REALTIME_VOICE_AUDIO_FORMAT_G711_ULAW_8KHZ, REALTIME_VOICE_AUDIO_FORMAT_PCM16_24KHZ, buildRealtimeVoiceAgentConsultWorkingResponse, consultRealtimeVoiceAgent, convertPcmToMulaw8k, createRealtimeVoiceAgentTalkbackQueue, createRealtimeVoiceBridgeSession, createRealtimeVoiceOutputActivityTracker, createTalkSessionController, extendRealtimeVoiceOutputEchoSuppression, getRealtimeVoiceBridgeEventHealth, getRealtimeVoiceTranscriptHealth, isLikelyRealtimeVoiceAssistantEchoTranscript, mulawToPcm, recordRealtimeVoiceBridgeEvent, recordRealtimeVoiceTranscript, recordTalkObservabilityEvent, resamplePcm, resolveConfiguredRealtimeVoiceProvider, resolveRealtimeVoiceAgentConsultToolPolicy, resolveRealtimeVoiceAgentConsultTools, resolveRealtimeVoiceAgentConsultToolsAllow } from "openclaw/plugin-sdk/realtime-voice";
10
+ import { addTimerTimeoutGraceMs } from "openclaw/plugin-sdk/number-runtime";
11
+ import { REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME, REALTIME_VOICE_AUDIO_FORMAT_G711_ULAW_8KHZ, REALTIME_VOICE_AUDIO_FORMAT_PCM16_24KHZ, buildRealtimeVoiceAgentConsultWorkingResponse, consultRealtimeVoiceAgent, convertPcmToMulaw8k, createRealtimeVoiceAgentTalkbackQueue, createRealtimeVoiceBridgeSession, createRealtimeVoiceOutputActivityTracker, createTalkSessionController, extendRealtimeVoiceOutputEchoSuppression, getRealtimeVoiceBridgeEventHealth, getRealtimeVoiceTranscriptHealth, isLikelyRealtimeVoiceAssistantEchoTranscript, mulawToPcm, recordRealtimeVoiceBridgeEvent, recordRealtimeVoiceTranscript, recordTalkObservabilityEvent, resamplePcm, resolveConfiguredRealtimeVoiceProvider, resolveRealtimeVoiceAgentConsultTools, resolveRealtimeVoiceAgentConsultToolsAllow } from "openclaw/plugin-sdk/realtime-voice";
11
12
  import { spawn, spawnSync } from "node:child_process";
12
13
  import { randomUUID } from "node:crypto";
13
14
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
@@ -17,328 +18,6 @@ import os from "node:os";
17
18
  import path from "node:path";
18
19
  import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
19
20
  import { getRealtimeTranscriptionProvider, listRealtimeTranscriptionProviders } from "openclaw/plugin-sdk/realtime-transcription";
20
- //#region extensions/google-meet/src/config.ts
21
- const SOX_DEFAULT_BUFFER_BYTES = 8192;
22
- const SOX_MIN_BUFFER_BYTES = 17;
23
- const DEFAULT_GOOGLE_MEET_AUDIO_BUFFER_BYTES = SOX_DEFAULT_BUFFER_BYTES / 2;
24
- const PLAIN_DECIMAL_NUMBER_RE = /^\d+(?:\.\d+)?$/;
25
- function withSoxBuffer(command, bufferBytes) {
26
- return [
27
- command[0] ?? "sox",
28
- "-q",
29
- "--buffer",
30
- String(bufferBytes),
31
- ...command.slice(2)
32
- ];
33
- }
34
- const DEFAULT_GOOGLE_MEET_AUDIO_INPUT_COMMAND_BASE = [
35
- "sox",
36
- "-q",
37
- "-t",
38
- "coreaudio",
39
- "BlackHole 2ch",
40
- "-t",
41
- "raw",
42
- "-r",
43
- "24000",
44
- "-c",
45
- "1",
46
- "-e",
47
- "signed-integer",
48
- "-b",
49
- "16",
50
- "-L",
51
- "-"
52
- ];
53
- const DEFAULT_GOOGLE_MEET_AUDIO_OUTPUT_COMMAND_BASE = [
54
- "sox",
55
- "-q",
56
- "-t",
57
- "raw",
58
- "-r",
59
- "24000",
60
- "-c",
61
- "1",
62
- "-e",
63
- "signed-integer",
64
- "-b",
65
- "16",
66
- "-L",
67
- "-",
68
- "-t",
69
- "coreaudio",
70
- "BlackHole 2ch"
71
- ];
72
- const LEGACY_GOOGLE_MEET_AUDIO_INPUT_COMMAND_BASE = [
73
- "rec",
74
- "-q",
75
- "-t",
76
- "raw",
77
- "-r",
78
- "8000",
79
- "-c",
80
- "1",
81
- "-e",
82
- "mu-law",
83
- "-b",
84
- "8",
85
- "-"
86
- ];
87
- const LEGACY_GOOGLE_MEET_AUDIO_OUTPUT_COMMAND_BASE = [
88
- "play",
89
- "-q",
90
- "-t",
91
- "raw",
92
- "-r",
93
- "8000",
94
- "-c",
95
- "1",
96
- "-e",
97
- "mu-law",
98
- "-b",
99
- "8",
100
- "-"
101
- ];
102
- const DEFAULT_GOOGLE_MEET_AUDIO_INPUT_COMMAND = withSoxBuffer(DEFAULT_GOOGLE_MEET_AUDIO_INPUT_COMMAND_BASE, DEFAULT_GOOGLE_MEET_AUDIO_BUFFER_BYTES);
103
- const DEFAULT_GOOGLE_MEET_AUDIO_OUTPUT_COMMAND = withSoxBuffer(DEFAULT_GOOGLE_MEET_AUDIO_OUTPUT_COMMAND_BASE, DEFAULT_GOOGLE_MEET_AUDIO_BUFFER_BYTES);
104
- const DEFAULT_GOOGLE_MEET_CHROME_AUDIO_FORMAT = "pcm16-24khz";
105
- const DEFAULT_GOOGLE_MEET_BARGE_IN_RMS_THRESHOLD = 650;
106
- const DEFAULT_GOOGLE_MEET_BARGE_IN_PEAK_THRESHOLD = 2500;
107
- const DEFAULT_GOOGLE_MEET_BARGE_IN_COOLDOWN_MS = 900;
108
- const DEFAULT_GOOGLE_MEET_REALTIME_INSTRUCTIONS = `You are joining a private Google Meet as an OpenClaw voice transport. Keep spoken replies brief and natural. In agent mode, wait for OpenClaw consult results and speak them exactly. In bidi mode, answer directly and call ${REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME} for deeper reasoning, current information, or tools.`;
109
- const DEFAULT_GOOGLE_MEET_REALTIME_INTRO_MESSAGE = "Say exactly: I'm here and listening.";
110
- const DEFAULT_GOOGLE_MEET_CONFIG = {
111
- enabled: true,
112
- defaults: {},
113
- preview: { enrollmentAcknowledged: false },
114
- defaultTransport: "chrome",
115
- defaultMode: "agent",
116
- chrome: {
117
- audioBackend: "blackhole-2ch",
118
- audioFormat: DEFAULT_GOOGLE_MEET_CHROME_AUDIO_FORMAT,
119
- audioBufferBytes: DEFAULT_GOOGLE_MEET_AUDIO_BUFFER_BYTES,
120
- launch: true,
121
- guestName: "OpenClaw Agent",
122
- reuseExistingTab: true,
123
- autoJoin: true,
124
- joinTimeoutMs: 3e4,
125
- waitForInCallMs: 2e4,
126
- audioInputCommand: [...DEFAULT_GOOGLE_MEET_AUDIO_INPUT_COMMAND],
127
- audioOutputCommand: [...DEFAULT_GOOGLE_MEET_AUDIO_OUTPUT_COMMAND],
128
- bargeInRmsThreshold: DEFAULT_GOOGLE_MEET_BARGE_IN_RMS_THRESHOLD,
129
- bargeInPeakThreshold: DEFAULT_GOOGLE_MEET_BARGE_IN_PEAK_THRESHOLD,
130
- bargeInCooldownMs: DEFAULT_GOOGLE_MEET_BARGE_IN_COOLDOWN_MS
131
- },
132
- chromeNode: {},
133
- twilio: {},
134
- voiceCall: {
135
- enabled: true,
136
- requestTimeoutMs: 3e4,
137
- dtmfDelayMs: 12e3,
138
- postDtmfSpeechDelayMs: 5e3
139
- },
140
- realtime: {
141
- strategy: "agent",
142
- provider: "openai",
143
- transcriptionProvider: "openai",
144
- instructions: DEFAULT_GOOGLE_MEET_REALTIME_INSTRUCTIONS,
145
- introMessage: DEFAULT_GOOGLE_MEET_REALTIME_INTRO_MESSAGE,
146
- toolPolicy: "safe-read-only",
147
- providers: {}
148
- },
149
- oauth: {},
150
- auth: { provider: "google-oauth" }
151
- };
152
- const GOOGLE_MEET_CLIENT_ID_KEYS = ["OPENCLAW_GOOGLE_MEET_CLIENT_ID", "GOOGLE_MEET_CLIENT_ID"];
153
- const GOOGLE_MEET_CLIENT_SECRET_KEYS = ["OPENCLAW_GOOGLE_MEET_CLIENT_SECRET", "GOOGLE_MEET_CLIENT_SECRET"];
154
- const GOOGLE_MEET_REFRESH_TOKEN_KEYS = ["OPENCLAW_GOOGLE_MEET_REFRESH_TOKEN", "GOOGLE_MEET_REFRESH_TOKEN"];
155
- const GOOGLE_MEET_ACCESS_TOKEN_KEYS = ["OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN", "GOOGLE_MEET_ACCESS_TOKEN"];
156
- const GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT_KEYS = ["OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT", "GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT"];
157
- const GOOGLE_MEET_DEFAULT_MEETING_KEYS = ["OPENCLAW_GOOGLE_MEET_DEFAULT_MEETING", "GOOGLE_MEET_DEFAULT_MEETING"];
158
- const GOOGLE_MEET_PREVIEW_ACK_KEYS = ["OPENCLAW_GOOGLE_MEET_PREVIEW_ACK", "GOOGLE_MEET_PREVIEW_ACK"];
159
- function resolveBoolean(value, fallback) {
160
- return typeof value === "boolean" ? value : fallback;
161
- }
162
- function resolveNumber(value, fallback) {
163
- return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : fallback;
164
- }
165
- function resolveOptionalNumber(value) {
166
- if (typeof value === "number" && Number.isFinite(value)) return value;
167
- if (typeof value === "string" && value.trim()) {
168
- const trimmed = value.trim();
169
- const parsed = PLAIN_DECIMAL_NUMBER_RE.test(trimmed) ? Number(trimmed) : NaN;
170
- return Number.isFinite(parsed) ? parsed : void 0;
171
- }
172
- }
173
- function readEnvString(env, keys) {
174
- for (const key of keys) {
175
- const value = normalizeOptionalString(env[key]);
176
- if (value) return value;
177
- }
178
- }
179
- function normalizeStringAllowEmpty(value) {
180
- return typeof value === "string" ? value.trim() : void 0;
181
- }
182
- function readEnvBoolean(env, keys) {
183
- const normalized = normalizeOptionalLowercaseString(readEnvString(env, keys));
184
- if (!normalized) return;
185
- if ([
186
- "1",
187
- "true",
188
- "yes",
189
- "on"
190
- ].includes(normalized)) return true;
191
- if ([
192
- "0",
193
- "false",
194
- "no",
195
- "off"
196
- ].includes(normalized)) return false;
197
- }
198
- function readEnvNumber(env, keys) {
199
- return resolveOptionalNumber(readEnvString(env, keys));
200
- }
201
- function resolveStringArray(value) {
202
- return normalizeOptionalTrimmedStringList(value);
203
- }
204
- function resolveProvidersConfig(value) {
205
- const raw = asRecord(value);
206
- const providers = {};
207
- for (const [key, entry] of Object.entries(raw)) {
208
- const providerId = normalizeOptionalLowercaseString(key);
209
- if (!providerId) continue;
210
- providers[providerId] = asRecord(entry);
211
- }
212
- return providers;
213
- }
214
- function resolveTransport$1(value, fallback) {
215
- const normalized = normalizeOptionalLowercaseString(value);
216
- return normalized === "chrome" || normalized === "chrome-node" || normalized === "twilio" ? normalized : fallback;
217
- }
218
- function resolveMode$1(value, fallback) {
219
- const normalized = normalizeOptionalLowercaseString(value);
220
- if (normalized === "realtime") return "agent";
221
- return normalized === "agent" || normalized === "bidi" || normalized === "transcribe" ? normalized : fallback;
222
- }
223
- function resolveRealtimeStrategy(value, fallback) {
224
- const normalized = normalizeOptionalLowercaseString(value);
225
- return normalized === "agent" || normalized === "bidi" ? normalized : fallback;
226
- }
227
- function resolveChromeAudioFormat(value) {
228
- switch (normalizeOptionalString(value)?.toLowerCase().replaceAll("_", "-")) {
229
- case "pcm16-24khz":
230
- case "pcm16-24k":
231
- case "pcm24":
232
- case "pcm": return "pcm16-24khz";
233
- case "g711-ulaw-8khz":
234
- case "g711-ulaw-8k":
235
- case "g711-ulaw":
236
- case "mulaw":
237
- case "mu-law": return "g711-ulaw-8khz";
238
- default: return;
239
- }
240
- }
241
- function resolveAudioBufferBytes(value, fallback) {
242
- const number = resolveNumber(value, fallback);
243
- if (!Number.isFinite(number) || number <= 0) return fallback;
244
- return Math.max(SOX_MIN_BUFFER_BYTES, Math.trunc(number));
245
- }
246
- function defaultAudioInputCommand(format, bufferBytes) {
247
- return withSoxBuffer(format === "g711-ulaw-8khz" ? LEGACY_GOOGLE_MEET_AUDIO_INPUT_COMMAND_BASE : DEFAULT_GOOGLE_MEET_AUDIO_INPUT_COMMAND_BASE, bufferBytes);
248
- }
249
- function defaultAudioOutputCommand(format, bufferBytes) {
250
- return withSoxBuffer(format === "g711-ulaw-8khz" ? LEGACY_GOOGLE_MEET_AUDIO_OUTPUT_COMMAND_BASE : DEFAULT_GOOGLE_MEET_AUDIO_OUTPUT_COMMAND_BASE, bufferBytes);
251
- }
252
- function resolveGoogleMeetConfig(input) {
253
- return resolveGoogleMeetConfigWithEnv(input);
254
- }
255
- function resolveGoogleMeetConfigWithEnv(input, env = process.env) {
256
- const raw = asRecord(input);
257
- const defaults = asRecord(raw.defaults);
258
- const preview = asRecord(raw.preview);
259
- const chrome = asRecord(raw.chrome);
260
- const configuredAudioInputCommand = resolveStringArray(chrome.audioInputCommand);
261
- const configuredAudioOutputCommand = resolveStringArray(chrome.audioOutputCommand);
262
- const hasCustomAudioCommand = configuredAudioInputCommand !== void 0 || configuredAudioOutputCommand !== void 0;
263
- const audioFormat = resolveChromeAudioFormat(chrome.audioFormat) ?? (hasCustomAudioCommand ? "g711-ulaw-8khz" : DEFAULT_GOOGLE_MEET_CONFIG.chrome.audioFormat);
264
- const audioBufferBytes = resolveAudioBufferBytes(chrome.audioBufferBytes, DEFAULT_GOOGLE_MEET_CONFIG.chrome.audioBufferBytes);
265
- const chromeNode = asRecord(raw.chromeNode);
266
- const twilio = asRecord(raw.twilio);
267
- const voiceCall = asRecord(raw.voiceCall);
268
- const realtime = asRecord(raw.realtime);
269
- const realtimeProvider = normalizeOptionalString(realtime.provider);
270
- const resolvedRealtimeProvider = realtimeProvider ?? DEFAULT_GOOGLE_MEET_CONFIG.realtime.provider;
271
- const oauth = asRecord(raw.oauth);
272
- const auth = asRecord(raw.auth);
273
- return {
274
- enabled: resolveBoolean(raw.enabled, DEFAULT_GOOGLE_MEET_CONFIG.enabled),
275
- defaults: { meeting: normalizeOptionalString(defaults.meeting) ?? readEnvString(env, GOOGLE_MEET_DEFAULT_MEETING_KEYS) },
276
- preview: { enrollmentAcknowledged: resolveBoolean(preview.enrollmentAcknowledged, readEnvBoolean(env, GOOGLE_MEET_PREVIEW_ACK_KEYS) ?? DEFAULT_GOOGLE_MEET_CONFIG.preview.enrollmentAcknowledged) },
277
- defaultTransport: resolveTransport$1(raw.defaultTransport, DEFAULT_GOOGLE_MEET_CONFIG.defaultTransport),
278
- defaultMode: resolveMode$1(raw.defaultMode, DEFAULT_GOOGLE_MEET_CONFIG.defaultMode),
279
- chrome: {
280
- audioBackend: "blackhole-2ch",
281
- audioFormat,
282
- audioBufferBytes,
283
- launch: resolveBoolean(chrome.launch, DEFAULT_GOOGLE_MEET_CONFIG.chrome.launch),
284
- browserProfile: normalizeOptionalString(chrome.browserProfile),
285
- guestName: normalizeOptionalString(chrome.guestName) ?? DEFAULT_GOOGLE_MEET_CONFIG.chrome.guestName,
286
- reuseExistingTab: resolveBoolean(chrome.reuseExistingTab, DEFAULT_GOOGLE_MEET_CONFIG.chrome.reuseExistingTab),
287
- autoJoin: resolveBoolean(chrome.autoJoin, DEFAULT_GOOGLE_MEET_CONFIG.chrome.autoJoin),
288
- joinTimeoutMs: resolveNumber(chrome.joinTimeoutMs, DEFAULT_GOOGLE_MEET_CONFIG.chrome.joinTimeoutMs),
289
- waitForInCallMs: resolveNumber(chrome.waitForInCallMs, DEFAULT_GOOGLE_MEET_CONFIG.chrome.waitForInCallMs),
290
- audioInputCommand: configuredAudioInputCommand ?? defaultAudioInputCommand(audioFormat, audioBufferBytes),
291
- audioOutputCommand: configuredAudioOutputCommand ?? defaultAudioOutputCommand(audioFormat, audioBufferBytes),
292
- bargeInInputCommand: resolveStringArray(chrome.bargeInInputCommand),
293
- bargeInRmsThreshold: resolveNumber(chrome.bargeInRmsThreshold, DEFAULT_GOOGLE_MEET_CONFIG.chrome.bargeInRmsThreshold),
294
- bargeInPeakThreshold: resolveNumber(chrome.bargeInPeakThreshold, DEFAULT_GOOGLE_MEET_CONFIG.chrome.bargeInPeakThreshold),
295
- bargeInCooldownMs: resolveNumber(chrome.bargeInCooldownMs, DEFAULT_GOOGLE_MEET_CONFIG.chrome.bargeInCooldownMs),
296
- audioBridgeCommand: resolveStringArray(chrome.audioBridgeCommand),
297
- audioBridgeHealthCommand: resolveStringArray(chrome.audioBridgeHealthCommand)
298
- },
299
- chromeNode: { node: normalizeOptionalString(chromeNode.node) },
300
- twilio: {
301
- defaultDialInNumber: normalizeOptionalString(twilio.defaultDialInNumber),
302
- defaultPin: normalizeOptionalString(twilio.defaultPin),
303
- defaultDtmfSequence: normalizeOptionalString(twilio.defaultDtmfSequence)
304
- },
305
- voiceCall: {
306
- enabled: resolveBoolean(voiceCall.enabled, DEFAULT_GOOGLE_MEET_CONFIG.voiceCall.enabled),
307
- gatewayUrl: normalizeOptionalString(voiceCall.gatewayUrl),
308
- token: normalizeOptionalString(voiceCall.token),
309
- requestTimeoutMs: resolveNumber(voiceCall.requestTimeoutMs, DEFAULT_GOOGLE_MEET_CONFIG.voiceCall.requestTimeoutMs),
310
- dtmfDelayMs: resolveNumber(voiceCall.dtmfDelayMs, DEFAULT_GOOGLE_MEET_CONFIG.voiceCall.dtmfDelayMs),
311
- postDtmfSpeechDelayMs: resolveNumber(voiceCall.postDtmfSpeechDelayMs, DEFAULT_GOOGLE_MEET_CONFIG.voiceCall.postDtmfSpeechDelayMs),
312
- introMessage: normalizeOptionalString(voiceCall.introMessage)
313
- },
314
- realtime: {
315
- strategy: resolveRealtimeStrategy(realtime.strategy, DEFAULT_GOOGLE_MEET_CONFIG.realtime.strategy),
316
- provider: resolvedRealtimeProvider,
317
- transcriptionProvider: normalizeOptionalString(realtime.transcriptionProvider) ?? (realtimeProvider && realtimeProvider !== "google" ? resolvedRealtimeProvider : DEFAULT_GOOGLE_MEET_CONFIG.realtime.transcriptionProvider),
318
- voiceProvider: normalizeOptionalString(realtime.voiceProvider),
319
- model: normalizeOptionalString(realtime.model) ?? DEFAULT_GOOGLE_MEET_CONFIG.realtime.model,
320
- instructions: normalizeOptionalString(realtime.instructions) ?? DEFAULT_GOOGLE_MEET_CONFIG.realtime.instructions,
321
- introMessage: normalizeStringAllowEmpty(realtime.introMessage) ?? DEFAULT_GOOGLE_MEET_CONFIG.realtime.introMessage,
322
- agentId: normalizeOptionalString(realtime.agentId),
323
- toolPolicy: resolveRealtimeVoiceAgentConsultToolPolicy(realtime.toolPolicy, DEFAULT_GOOGLE_MEET_CONFIG.realtime.toolPolicy),
324
- providers: resolveProvidersConfig(realtime.providers)
325
- },
326
- oauth: {
327
- clientId: normalizeOptionalString(oauth.clientId) ?? normalizeOptionalString(auth.clientId) ?? readEnvString(env, GOOGLE_MEET_CLIENT_ID_KEYS),
328
- clientSecret: normalizeOptionalString(oauth.clientSecret) ?? normalizeOptionalString(auth.clientSecret) ?? readEnvString(env, GOOGLE_MEET_CLIENT_SECRET_KEYS),
329
- refreshToken: normalizeOptionalString(oauth.refreshToken) ?? readEnvString(env, GOOGLE_MEET_REFRESH_TOKEN_KEYS),
330
- accessToken: normalizeOptionalString(oauth.accessToken) ?? readEnvString(env, GOOGLE_MEET_ACCESS_TOKEN_KEYS),
331
- expiresAt: resolveOptionalNumber(oauth.expiresAt) ?? readEnvNumber(env, GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT_KEYS)
332
- },
333
- auth: {
334
- provider: "google-oauth",
335
- clientId: normalizeOptionalString(auth.clientId),
336
- clientSecret: normalizeOptionalString(auth.clientSecret),
337
- tokenPath: normalizeOptionalString(auth.tokenPath)
338
- }
339
- };
340
- }
341
- //#endregion
342
21
  //#region extensions/google-meet/src/transports/chrome-audio-device.ts
343
22
  const GOOGLE_MEET_SYSTEM_PROFILER_COMMAND = "/usr/sbin/system_profiler";
344
23
  function outputMentionsBlackHole2ch(output) {
@@ -1076,7 +755,7 @@ function alawByteToLinear(value) {
1076
755
  const sign = aLaw & 128;
1077
756
  const exponent = (aLaw & 112) >> 4;
1078
757
  const mantissa = aLaw & 15;
1079
- let sample = exponent === 0 ? (mantissa << 4) + 8 : (mantissa << 4) + 264 << exponent - 1;
758
+ const sample = exponent === 0 ? (mantissa << 4) + 8 : (mantissa << 4) + 264 << exponent - 1;
1080
759
  return sign ? sample : -sample;
1081
760
  }
1082
761
  function resolveGoogleMeetRealtimeProvider(params) {
@@ -1204,7 +883,6 @@ async function startCommandAgentAudioBridge(params) {
1204
883
  let lastSuppressedInputAt;
1205
884
  let suppressInputUntil = 0;
1206
885
  let lastOutputPlayableUntilMs = 0;
1207
- let agentTalkback;
1208
886
  let ttsQueue = Promise.resolve();
1209
887
  const transcript = [];
1210
888
  const resolved = resolveGoogleMeetRealtimeTranscriptionProvider({
@@ -1362,7 +1040,7 @@ async function startCommandAgentAudioBridge(params) {
1362
1040
  params.logger.warn(`[google-meet] agent TTS failed: ${formatErrorMessage(error)}`);
1363
1041
  });
1364
1042
  };
1365
- agentTalkback = createRealtimeVoiceAgentTalkbackQueue({
1043
+ const agentTalkback = createRealtimeVoiceAgentTalkbackQueue({
1366
1044
  debounceMs: 900,
1367
1045
  isStopped: () => stopped,
1368
1046
  logger: params.logger,
@@ -1516,7 +1194,6 @@ async function startCommandRealtimeAudioBridge(params) {
1516
1194
  let suppressInputUntil = 0;
1517
1195
  let lastOutputPlayableUntilMs = 0;
1518
1196
  let bargeInInputProcess;
1519
- let agentTalkback;
1520
1197
  const suppressInputForOutput = (audio) => {
1521
1198
  const suppression = recordGoogleMeetOutputActivity({
1522
1199
  tracker: outputActivity,
@@ -1695,7 +1372,7 @@ async function startCommandRealtimeAudioBridge(params) {
1695
1372
  type: "session.started",
1696
1373
  payload: { meetingSessionId: params.meetingSessionId }
1697
1374
  });
1698
- agentTalkback = createRealtimeVoiceAgentTalkbackQueue({
1375
+ const agentTalkback = createRealtimeVoiceAgentTalkbackQueue({
1699
1376
  debounceMs: 900,
1700
1377
  isStopped: () => stopped,
1701
1378
  logger: params.logger,
@@ -1930,20 +1607,73 @@ function normalizeGoogleMeetTtsPromptText(text) {
1930
1607
  if (sayExactly) return sayExactly.replace(/^["']|["']$/g, "").trim() || trimmed;
1931
1608
  return trimmed;
1932
1609
  }
1610
+ function startGoogleMeetNodeAudioInputLoop(params) {
1611
+ let lastInputAt;
1612
+ let lastInputBytes = 0;
1613
+ let suppressedInputBytes = 0;
1614
+ let lastSuppressedInputAt;
1615
+ let consecutiveInputErrors = 0;
1616
+ let lastInputError;
1617
+ (async () => {
1618
+ for (;;) {
1619
+ if (params.isStopped()) break;
1620
+ try {
1621
+ const raw = await params.runtime.nodes.invoke({
1622
+ nodeId: params.nodeId,
1623
+ command: "googlemeet.chrome",
1624
+ params: {
1625
+ action: "pullAudio",
1626
+ bridgeId: params.bridgeId,
1627
+ timeoutMs: 250
1628
+ },
1629
+ timeoutMs: 2e3
1630
+ });
1631
+ const result = asRecord$1(asRecord$1(raw).payload ?? raw);
1632
+ consecutiveInputErrors = 0;
1633
+ lastInputError = void 0;
1634
+ const base64 = readString(result.base64);
1635
+ if (base64) {
1636
+ const audio = Buffer.from(base64, "base64");
1637
+ if (params.isInputSuppressed()) {
1638
+ lastSuppressedInputAt = (/* @__PURE__ */ new Date()).toISOString();
1639
+ suppressedInputBytes += audio.byteLength;
1640
+ continue;
1641
+ }
1642
+ lastInputAt = (/* @__PURE__ */ new Date()).toISOString();
1643
+ lastInputBytes += audio.byteLength;
1644
+ params.onAudio(audio);
1645
+ }
1646
+ if (result.closed === true) await params.stop();
1647
+ } catch (error) {
1648
+ if (!params.isStopped()) {
1649
+ const message = formatErrorMessage(error);
1650
+ consecutiveInputErrors += 1;
1651
+ lastInputError = message;
1652
+ params.logger.warn(`[google-meet] ${params.logPrefix} audio input failed (${consecutiveInputErrors}/5): ${message}`);
1653
+ if (consecutiveInputErrors >= 5 || /unknown bridgeId|bridge is not open/i.test(message)) await params.stop();
1654
+ else await new Promise((resolve) => setTimeout(resolve, 250));
1655
+ }
1656
+ }
1657
+ }
1658
+ })();
1659
+ return { getHealth: () => ({
1660
+ audioInputActive: lastInputBytes > 0,
1661
+ lastInputAt,
1662
+ lastSuppressedInputAt,
1663
+ lastInputBytes,
1664
+ suppressedInputBytes,
1665
+ consecutiveInputErrors,
1666
+ lastInputError
1667
+ }) };
1668
+ }
1933
1669
  async function startNodeAgentAudioBridge(params) {
1934
1670
  let stopped = false;
1935
1671
  let sttSession = null;
1936
1672
  let realtimeReady = false;
1937
- let lastInputAt;
1938
1673
  let lastOutputAt;
1939
- let lastInputBytes = 0;
1940
1674
  const outputActivity = createRealtimeVoiceOutputActivityTracker();
1941
- let suppressedInputBytes = 0;
1942
- let lastSuppressedInputAt;
1943
1675
  let suppressInputUntil = 0;
1944
1676
  let lastOutputPlayableUntilMs = 0;
1945
- let consecutiveInputErrors = 0;
1946
- let lastInputError;
1947
1677
  const resolved = resolveGoogleMeetRealtimeTranscriptionProvider({
1948
1678
  config: params.config,
1949
1679
  fullConfig: params.fullConfig,
@@ -1955,7 +1685,6 @@ async function startNodeAgentAudioBridge(params) {
1955
1685
  audioFormat: params.config.chrome.audioFormat
1956
1686
  }));
1957
1687
  const transcript = [];
1958
- let agentTalkback;
1959
1688
  let ttsQueue = Promise.resolve();
1960
1689
  const stop = async () => {
1961
1690
  if (stopped) return;
@@ -2021,7 +1750,7 @@ async function startNodeAgentAudioBridge(params) {
2021
1750
  params.logger.warn(`[google-meet] node agent TTS failed: ${formatErrorMessage(error)}`);
2022
1751
  });
2023
1752
  };
2024
- agentTalkback = createRealtimeVoiceAgentTalkbackQueue({
1753
+ const agentTalkback = createRealtimeVoiceAgentTalkbackQueue({
2025
1754
  debounceMs: 900,
2026
1755
  isStopped: () => stopped,
2027
1756
  logger: params.logger,
@@ -2067,48 +1796,19 @@ async function startNodeAgentAudioBridge(params) {
2067
1796
  });
2068
1797
  await sttSession.connect();
2069
1798
  realtimeReady = true;
2070
- (async () => {
2071
- for (;;) {
2072
- if (stopped) break;
2073
- try {
2074
- const raw = await params.runtime.nodes.invoke({
2075
- nodeId: params.nodeId,
2076
- command: "googlemeet.chrome",
2077
- params: {
2078
- action: "pullAudio",
2079
- bridgeId: params.bridgeId,
2080
- timeoutMs: 250
2081
- },
2082
- timeoutMs: 2e3
2083
- });
2084
- const result = asRecord$1(asRecord$1(raw).payload ?? raw);
2085
- consecutiveInputErrors = 0;
2086
- lastInputError = void 0;
2087
- const base64 = readString(result.base64);
2088
- if (base64) {
2089
- const audio = Buffer.from(base64, "base64");
2090
- if (Date.now() < suppressInputUntil) {
2091
- lastSuppressedInputAt = (/* @__PURE__ */ new Date()).toISOString();
2092
- suppressedInputBytes += audio.byteLength;
2093
- continue;
2094
- }
2095
- lastInputAt = (/* @__PURE__ */ new Date()).toISOString();
2096
- lastInputBytes += audio.byteLength;
2097
- sttSession?.sendAudio(convertGoogleMeetBridgeAudioForStt(audio, params.config));
2098
- }
2099
- if (result.closed === true) await stop();
2100
- } catch (error) {
2101
- if (!stopped) {
2102
- const message = formatErrorMessage(error);
2103
- consecutiveInputErrors += 1;
2104
- lastInputError = message;
2105
- params.logger.warn(`[google-meet] node agent audio input failed (${consecutiveInputErrors}/5): ${message}`);
2106
- if (consecutiveInputErrors >= 5 || /unknown bridgeId|bridge is not open/i.test(message)) await stop();
2107
- else await new Promise((resolve) => setTimeout(resolve, 250));
2108
- }
2109
- }
1799
+ const audioInputLoop = startGoogleMeetNodeAudioInputLoop({
1800
+ runtime: params.runtime,
1801
+ nodeId: params.nodeId,
1802
+ bridgeId: params.bridgeId,
1803
+ logger: params.logger,
1804
+ logPrefix: "node agent",
1805
+ isStopped: () => stopped,
1806
+ stop,
1807
+ isInputSuppressed: () => Date.now() < suppressInputUntil,
1808
+ onAudio: (audio) => {
1809
+ sttSession?.sendAudio(convertGoogleMeetBridgeAudioForStt(audio, params.config));
2110
1810
  }
2111
- })();
1811
+ });
2112
1812
  return {
2113
1813
  type: "node-command-pair",
2114
1814
  providerId: resolved.provider.id,
@@ -2118,17 +1818,11 @@ async function startNodeAgentAudioBridge(params) {
2118
1818
  getHealth: () => ({
2119
1819
  providerConnected: sttSession?.isConnected() ?? false,
2120
1820
  realtimeReady,
2121
- audioInputActive: lastInputBytes > 0,
1821
+ ...audioInputLoop.getHealth(),
2122
1822
  audioOutputActive: outputActivity.isActive(),
2123
- lastInputAt,
2124
1823
  lastOutputAt,
2125
- lastSuppressedInputAt,
2126
- lastInputBytes,
2127
1824
  lastOutputBytes: outputActivity.snapshot().sinkAudioBytes,
2128
- suppressedInputBytes,
2129
1825
  ...getGoogleMeetRealtimeTranscriptHealth(transcript),
2130
- consecutiveInputErrors,
2131
- lastInputError,
2132
1826
  bridgeClosed: stopped
2133
1827
  }),
2134
1828
  stop
@@ -2138,17 +1832,11 @@ async function startNodeRealtimeAudioBridge(params) {
2138
1832
  let stopped = false;
2139
1833
  let bridge = null;
2140
1834
  let realtimeReady = false;
2141
- let lastInputAt;
2142
1835
  let lastOutputAt;
2143
1836
  let lastClearAt;
2144
- let lastInputBytes = 0;
2145
1837
  const outputActivity = createRealtimeVoiceOutputActivityTracker();
2146
- let suppressedInputBytes = 0;
2147
- let lastSuppressedInputAt;
2148
1838
  let suppressInputUntil = 0;
2149
1839
  let lastOutputPlayableUntilMs = 0;
2150
- let consecutiveInputErrors = 0;
2151
- let lastInputError;
2152
1840
  let clearCount = 0;
2153
1841
  const resolved = resolveGoogleMeetRealtimeProvider({
2154
1842
  config: params.config,
@@ -2208,8 +1896,7 @@ async function startNodeRealtimeAudioBridge(params) {
2208
1896
  fallbackModel: params.config.realtime.model,
2209
1897
  audioFormat: params.config.chrome.audioFormat
2210
1898
  }));
2211
- let agentTalkback;
2212
- agentTalkback = createRealtimeVoiceAgentTalkbackQueue({
1899
+ const agentTalkback = createRealtimeVoiceAgentTalkbackQueue({
2213
1900
  debounceMs: 900,
2214
1901
  isStopped: () => stopped,
2215
1902
  logger: params.logger,
@@ -2442,53 +2129,24 @@ async function startNodeRealtimeAudioBridge(params) {
2442
2129
  }
2443
2130
  });
2444
2131
  await bridge.connect();
2445
- (async () => {
2446
- for (;;) {
2447
- if (stopped) break;
2448
- try {
2449
- const raw = await params.runtime.nodes.invoke({
2450
- nodeId: params.nodeId,
2451
- command: "googlemeet.chrome",
2452
- params: {
2453
- action: "pullAudio",
2454
- bridgeId: params.bridgeId,
2455
- timeoutMs: 250
2456
- },
2457
- timeoutMs: 2e3
2458
- });
2459
- const result = asRecord$1(asRecord$1(raw).payload ?? raw);
2460
- consecutiveInputErrors = 0;
2461
- lastInputError = void 0;
2462
- const base64 = readString(result.base64);
2463
- if (base64) {
2464
- const audio = Buffer.from(base64, "base64");
2465
- if (Date.now() < suppressInputUntil) {
2466
- lastSuppressedInputAt = (/* @__PURE__ */ new Date()).toISOString();
2467
- suppressedInputBytes += audio.byteLength;
2468
- continue;
2469
- }
2470
- lastInputAt = (/* @__PURE__ */ new Date()).toISOString();
2471
- lastInputBytes += audio.byteLength;
2472
- emitTalkEvent({
2473
- type: "input.audio.delta",
2474
- turnId: ensureTalkTurn(),
2475
- payload: { byteLength: audio.byteLength }
2476
- });
2477
- bridge?.sendAudio(audio);
2478
- }
2479
- if (result.closed === true) await stop();
2480
- } catch (error) {
2481
- if (!stopped) {
2482
- const message = formatErrorMessage(error);
2483
- consecutiveInputErrors += 1;
2484
- lastInputError = message;
2485
- params.logger.warn(`[google-meet] node audio input failed (${consecutiveInputErrors}/5): ${message}`);
2486
- if (consecutiveInputErrors >= 5 || /unknown bridgeId|bridge is not open/i.test(message)) await stop();
2487
- else await new Promise((resolve) => setTimeout(resolve, 250));
2488
- }
2489
- }
2132
+ const audioInputLoop = startGoogleMeetNodeAudioInputLoop({
2133
+ runtime: params.runtime,
2134
+ nodeId: params.nodeId,
2135
+ bridgeId: params.bridgeId,
2136
+ logger: params.logger,
2137
+ logPrefix: "node",
2138
+ isStopped: () => stopped,
2139
+ stop,
2140
+ isInputSuppressed: () => Date.now() < suppressInputUntil,
2141
+ onAudio: (audio) => {
2142
+ emitTalkEvent({
2143
+ type: "input.audio.delta",
2144
+ turnId: ensureTalkTurn(),
2145
+ payload: { byteLength: audio.byteLength }
2146
+ });
2147
+ bridge?.sendAudio(audio);
2490
2148
  }
2491
- })();
2149
+ });
2492
2150
  return {
2493
2151
  type: "node-command-pair",
2494
2152
  providerId: resolved.provider.id,
@@ -2500,20 +2158,14 @@ async function startNodeRealtimeAudioBridge(params) {
2500
2158
  getHealth: () => ({
2501
2159
  providerConnected: bridge?.bridge.isConnected() ?? false,
2502
2160
  realtimeReady,
2503
- audioInputActive: lastInputBytes > 0,
2161
+ ...audioInputLoop.getHealth(),
2504
2162
  audioOutputActive: outputActivity.isActive(),
2505
- lastInputAt,
2506
2163
  lastOutputAt,
2507
- lastSuppressedInputAt,
2508
2164
  lastClearAt,
2509
- lastInputBytes,
2510
2165
  lastOutputBytes: outputActivity.snapshot().sinkAudioBytes,
2511
- suppressedInputBytes,
2512
2166
  ...getGoogleMeetRealtimeTranscriptHealth(transcript),
2513
2167
  ...getGoogleMeetRealtimeEventHealth(realtimeEvents),
2514
2168
  recentTalkEvents: summarizeGoogleMeetTalkEvents(recentTalkEvents),
2515
- consecutiveInputErrors,
2516
- lastInputError,
2517
2169
  clearCount,
2518
2170
  bridgeClosed: stopped
2519
2171
  }),
@@ -2650,7 +2302,7 @@ function parseMeetBrowserStatus(result) {
2650
2302
  async function callLocalBrowserRequest(params) {
2651
2303
  return await chromeTransportDeps.callGatewayFromCli("browser.request", {
2652
2304
  json: true,
2653
- timeout: String(params.timeoutMs + 5e3)
2305
+ timeout: String(resolveBrowserGatewayTimeoutMs(params.timeoutMs))
2654
2306
  }, {
2655
2307
  method: params.method,
2656
2308
  path: params.path,
@@ -2658,6 +2310,9 @@ async function callLocalBrowserRequest(params) {
2658
2310
  timeoutMs: params.timeoutMs
2659
2311
  }, { progress: false });
2660
2312
  }
2313
+ function resolveBrowserGatewayTimeoutMs(timeoutMs) {
2314
+ return addTimerTimeoutGraceMs(timeoutMs) ?? 1;
2315
+ }
2661
2316
  function mergeBrowserNotes(browser, notes) {
2662
2317
  if (!browser || notes.length === 0) return browser;
2663
2318
  return {
@@ -3214,7 +2869,7 @@ async function launchChromeMeetOnNode(params) {
3214
2869
  audioBridgeCommand: params.config.chrome.audioBridgeCommand,
3215
2870
  audioBridgeHealthCommand: params.config.chrome.audioBridgeHealthCommand
3216
2871
  },
3217
- timeoutMs: params.config.chrome.joinTimeoutMs + 5e3
2872
+ timeoutMs: addTimerTimeoutGraceMs(params.config.chrome.joinTimeoutMs) ?? 1
3218
2873
  }));
3219
2874
  if (result.audioBridge?.type === "node-command-pair") {
3220
2875
  if (!result.bridgeId) throw new Error("Google Meet node did not return an audio bridge id.");
@@ -4082,6 +3737,16 @@ var GoogleMeetRuntime = class {
4082
3737
  };
4083
3738
  //#endregion
4084
3739
  //#region extensions/google-meet/index.ts
3740
+ let googleMeetCreateModulePromise = null;
3741
+ let googleMeetCliModulePromise = null;
3742
+ const loadGoogleMeetCreateModule = async () => {
3743
+ googleMeetCreateModulePromise ??= import("./create-BzkoPzD2.js");
3744
+ return await googleMeetCreateModulePromise;
3745
+ };
3746
+ const loadGoogleMeetCliModule = async () => {
3747
+ googleMeetCliModulePromise ??= import("./cli-DURm3Y-K.js");
3748
+ return await googleMeetCliModulePromise;
3749
+ };
4085
3750
  const googleMeetConfigSchema = {
4086
3751
  parse(value) {
4087
3752
  return resolveGoogleMeetConfig(value);
@@ -4404,7 +4069,8 @@ const testing = {
4404
4069
  setPlatformForTests(next) {
4405
4070
  googleMeetToolDeps.platform = next ?? (() => process.platform);
4406
4071
  },
4407
- isGoogleMeetAgentToolActionUnsupportedOnHost
4072
+ isGoogleMeetAgentToolActionUnsupportedOnHost,
4073
+ resolveGoogleMeetGatewayOperationTimeoutMs
4408
4074
  };
4409
4075
  function googleMeetGatewayMethodForToolAction(action) {
4410
4076
  switch (action) {
@@ -4428,9 +4094,6 @@ function assertGoogleMeetAgentToolActionSupported(params) {
4428
4094
  if (!isGoogleMeetAgentToolActionUnsupportedOnHost(params)) return;
4429
4095
  throw new Error("Google Meet local Chrome talk-back audio is macOS-only. On this host, use mode: transcribe, transport: twilio, or transport: chrome-node backed by a macOS node.");
4430
4096
  }
4431
- function resolveGoogleMeetToolGatewayTimeoutMs(config) {
4432
- return Math.max(6e4, config.chrome.joinTimeoutMs + 3e4, config.voiceCall.requestTimeoutMs + 1e4);
4433
- }
4434
4097
  function readGatewayErrorDetails(err) {
4435
4098
  if (!err || typeof err !== "object" || !("details" in err)) return;
4436
4099
  return err.details;
@@ -4439,7 +4102,7 @@ async function callGoogleMeetGatewayFromTool(params) {
4439
4102
  try {
4440
4103
  return await googleMeetToolDeps.callGatewayFromCli(googleMeetGatewayMethodForToolAction(params.action), {
4441
4104
  json: true,
4442
- timeout: String(resolveGoogleMeetToolGatewayTimeoutMs(params.config))
4105
+ timeout: String(resolveGoogleMeetGatewayOperationTimeoutMs(params.config))
4443
4106
  }, params.raw, { progress: false });
4444
4107
  } catch (err) {
4445
4108
  const details = readGatewayErrorDetails(err);
@@ -4448,13 +4111,13 @@ async function callGoogleMeetGatewayFromTool(params) {
4448
4111
  }
4449
4112
  }
4450
4113
  async function createMeetFromParams(params) {
4451
- return (await import("./create-OMWgK9on.js")).createMeetFromParams(params);
4114
+ return (await loadGoogleMeetCreateModule()).createMeetFromParams(params);
4452
4115
  }
4453
4116
  async function createAndJoinMeetFromParams(params) {
4454
- return (await import("./create-OMWgK9on.js")).createAndJoinMeetFromParams(params);
4117
+ return (await loadGoogleMeetCreateModule()).createAndJoinMeetFromParams(params);
4455
4118
  }
4456
4119
  async function resolveGoogleMeetTokenFromParams(config, raw) {
4457
- const { resolveGoogleMeetAccessToken } = await import("./oauth-B3tz8JcD.js");
4120
+ const { resolveGoogleMeetAccessToken } = await import("./oauth--J53aI66.js");
4458
4121
  return resolveGoogleMeetAccessToken({
4459
4122
  clientId: normalizeOptionalString(raw.clientId) ?? config.oauth.clientId,
4460
4123
  clientSecret: normalizeOptionalString(raw.clientSecret) ?? config.oauth.clientSecret,
@@ -4543,7 +4206,7 @@ async function exportGoogleMeetBundleFromParams(config, raw) {
4543
4206
  lateAfterMinutes: resolved.lateAfterMinutes,
4544
4207
  earlyBeforeMinutes: resolved.earlyBeforeMinutes
4545
4208
  })]);
4546
- const { buildGoogleMeetExportManifest, googleMeetExportFileNames, writeMeetExportBundle } = await import("./cli-Cc7dWaK8.js");
4209
+ const { buildGoogleMeetExportManifest, googleMeetExportFileNames, writeMeetExportBundle } = await loadGoogleMeetCliModule();
4547
4210
  const calendarId = normalizeOptionalString(raw.calendarId);
4548
4211
  const request = {
4549
4212
  ...resolved.meeting ? { meeting: resolved.meeting } : {},
@@ -4959,7 +4622,7 @@ var google_meet_default = definePluginEntry({
4959
4622
  handle: handleGoogleMeetNodeHostCommand
4960
4623
  });
4961
4624
  api.registerCli(async ({ program }) => {
4962
- const { registerGoogleMeetCli } = await import("./cli-Cc7dWaK8.js");
4625
+ const { registerGoogleMeetCli } = await loadGoogleMeetCliModule();
4963
4626
  registerGoogleMeetCli({
4964
4627
  program,
4965
4628
  config,