@openclaw/google-meet 2026.9.2 → 2026.9.4
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/{cli-Cwc266K3.js → cli-BCUxht2Q.js} +3 -3
- package/dist/{config-wBK8loBb.js → config-C-6enWkx.js} +2 -0
- package/dist/{create-Djmk2CQz.js → create-Cr6rg236.js} +1 -1
- package/dist/index.js +2 -2
- package/dist/{node-host-BXtXbsMa.js → node-host-DS-lLN37.js} +1 -1
- package/dist/{plugin-helpers-WF-JVJhh.js → plugin-helpers-RSH2DZTl.js} +2 -2
- package/dist/{plugin-registration-NIwMvP6X.js → plugin-registration-DLs9YDzZ.js} +6 -6
- package/dist/{runtime-0IuZTlpN.js → runtime-CXfjJvPN.js} +19 -341
- package/openclaw.plugin.json +1 -0
- package/package.json +4 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as resolveGoogleMeetTokenFromParams, c as buildGoogleMeetPreflightReport, d as fetchGoogleMeetSpace, f as fetchLatestGoogleMeetConferenceRecord, i as resolveArtifactQueryFromParams, l as createGoogleMeetSpace, m as listGoogleMeetCalendarEvents, n as fetchResolvedGoogleMeetAttendance, o as resolveMeetingFromParams, p as buildGoogleMeetCalendarDayWindow, s as resolveSpaceFromParams, t as fetchResolvedGoogleMeetArtifacts, u as endGoogleMeetActiveConference } from "./plugin-helpers-
|
|
2
|
-
import { i as resolveGoogleMeetGatewayOperationTimeoutMs } from "./config-
|
|
1
|
+
import { a as resolveGoogleMeetTokenFromParams, c as buildGoogleMeetPreflightReport, d as fetchGoogleMeetSpace, f as fetchLatestGoogleMeetConferenceRecord, i as resolveArtifactQueryFromParams, l as createGoogleMeetSpace, m as listGoogleMeetCalendarEvents, n as fetchResolvedGoogleMeetAttendance, o as resolveMeetingFromParams, p as buildGoogleMeetCalendarDayWindow, s as resolveSpaceFromParams, t as fetchResolvedGoogleMeetArtifacts, u as endGoogleMeetActiveConference } from "./plugin-helpers-RSH2DZTl.js";
|
|
2
|
+
import { i as resolveGoogleMeetGatewayOperationTimeoutMs } from "./config-C-6enWkx.js";
|
|
3
3
|
import { buildGoogleMeetAuthUrl, exchangeGoogleMeetAuthCode, resolveGoogleMeetAccessToken, waitForGoogleMeetAuthCode } from "./oauth-DgBscjXK.js";
|
|
4
|
-
import { n as hasCreateSpaceConfigInput, r as resolveCreateSpaceConfig } from "./create-
|
|
4
|
+
import { n as hasCreateSpaceConfigInput, r as resolveCreateSpaceConfig } from "./create-Cr6rg236.js";
|
|
5
5
|
import { clampTimerTimeoutMs, parseStrictNonNegativeInteger, parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
6
6
|
import { callGatewayFromCli, isGatewayClientRequestError, isGatewayTransportError } from "openclaw/plugin-sdk/gateway-runtime";
|
|
7
7
|
import { generateHexPkceVerifierChallenge } from "openclaw/plugin-sdk/provider-auth";
|
|
@@ -92,6 +92,7 @@ const DEFAULT_GOOGLE_MEET_CHROME_AUDIO_FORMAT = "pcm16-24khz";
|
|
|
92
92
|
const DEFAULT_GOOGLE_MEET_BARGE_IN_RMS_THRESHOLD = 650;
|
|
93
93
|
const DEFAULT_GOOGLE_MEET_BARGE_IN_PEAK_THRESHOLD = 2500;
|
|
94
94
|
const DEFAULT_GOOGLE_MEET_BARGE_IN_COOLDOWN_MS = 900;
|
|
95
|
+
const DEFAULT_GOOGLE_MEET_REALTIME_MODEL = void 0;
|
|
95
96
|
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.`;
|
|
96
97
|
const DEFAULT_GOOGLE_MEET_REALTIME_INTRO_MESSAGE = "Say exactly: I'm here and listening.";
|
|
97
98
|
const DEFAULT_GOOGLE_MEET_CONFIG = {
|
|
@@ -128,6 +129,7 @@ const DEFAULT_GOOGLE_MEET_CONFIG = {
|
|
|
128
129
|
strategy: "agent",
|
|
129
130
|
provider: "openai",
|
|
130
131
|
transcriptionProvider: "openai",
|
|
132
|
+
model: DEFAULT_GOOGLE_MEET_REALTIME_MODEL,
|
|
131
133
|
instructions: DEFAULT_GOOGLE_MEET_REALTIME_INSTRUCTIONS,
|
|
132
134
|
introMessage: DEFAULT_GOOGLE_MEET_REALTIME_INTRO_MESSAGE,
|
|
133
135
|
toolPolicy: "safe-read-only",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { h as __exportAll, l as createGoogleMeetSpace } from "./plugin-helpers-
|
|
1
|
+
import { h as __exportAll, l as createGoogleMeetSpace } from "./plugin-helpers-RSH2DZTl.js";
|
|
2
2
|
import { resolveGoogleMeetAccessToken } from "./oauth-DgBscjXK.js";
|
|
3
3
|
import { t as createMeetWithBrowserProxyOnNode } from "./chrome-create-PKAyxCiL.js";
|
|
4
4
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as GOOGLE_MEET_CLI_DESCRIPTOR } from "./cli-output-mode-BwH_6tH8.js";
|
|
2
2
|
import { n as GOOGLE_MEET_NODE_COMMAND } from "./google-meet-platform-constants-Bs5iAg3E.js";
|
|
3
|
-
import { r as resolveGoogleMeetConfig } from "./config-
|
|
4
|
-
import { a as createLazyGoogleMeetNodeInvokePolicy, c as loadGoogleMeetCliModule, d as normalizeMode, f as normalizeTransport, h as shouldJoinCreatedMeet, i as createGoogleMeetRuntimeAccessor, l as loadGoogleMeetNodeHostModule, m as sendGoogleMeetGatewayError, n as assertGoogleMeetAgentToolActionSupported, o as formatGoogleMeetGatewayError, p as resolveMeetingInput, r as callGoogleMeetGatewayFromTool, s as keepTrustedToolAgentId, t as asParamRecord, u as loadGoogleMeetPluginHelpers } from "./plugin-registration-
|
|
3
|
+
import { r as resolveGoogleMeetConfig } from "./config-C-6enWkx.js";
|
|
4
|
+
import { a as createLazyGoogleMeetNodeInvokePolicy, c as loadGoogleMeetCliModule, d as normalizeMode, f as normalizeTransport, h as shouldJoinCreatedMeet, i as createGoogleMeetRuntimeAccessor, l as loadGoogleMeetNodeHostModule, m as sendGoogleMeetGatewayError, n as assertGoogleMeetAgentToolActionSupported, o as formatGoogleMeetGatewayError, p as resolveMeetingInput, r as callGoogleMeetGatewayFromTool, s as keepTrustedToolAgentId, t as asParamRecord, u as loadGoogleMeetPluginHelpers } from "./plugin-registration-DLs9YDzZ.js";
|
|
5
5
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
6
6
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
7
|
import { jsonResult } from "openclaw/plugin-sdk/tool-results";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as GOOGLE_MEET_NODE_COMMAND } from "./google-meet-platform-constants-Bs5iAg3E.js";
|
|
2
|
-
import { n as DEFAULT_GOOGLE_MEET_AUDIO_OUTPUT_COMMAND, t as DEFAULT_GOOGLE_MEET_AUDIO_INPUT_COMMAND } from "./config-
|
|
2
|
+
import { n as DEFAULT_GOOGLE_MEET_AUDIO_OUTPUT_COMMAND, t as DEFAULT_GOOGLE_MEET_AUDIO_INPUT_COMMAND } from "./config-C-6enWkx.js";
|
|
3
3
|
import { t as GOOGLE_MEET_PLATFORM_ADAPTER } from "./google-meet-platform-adapter-C3J-iFRE.js";
|
|
4
4
|
import { MeetingPlatformAdapter } from "openclaw/plugin-sdk/meeting-runtime";
|
|
5
5
|
//#region extensions/google-meet/src/node-host.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as loadGoogleMeetCliModule, p as resolveMeetingInput } from "./plugin-registration-
|
|
1
|
+
import { c as loadGoogleMeetCliModule, p as resolveMeetingInput } from "./plugin-registration-DLs9YDzZ.js";
|
|
2
2
|
import { t as googleApiError } from "./google-api-errors-BDYXfKRa.js";
|
|
3
3
|
import { t as normalizeMeetUrl } from "./meet-url-BP2Jlvjs.js";
|
|
4
4
|
import { normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
@@ -773,7 +773,7 @@ var plugin_helpers_exports = /* @__PURE__ */ __exportAll({
|
|
|
773
773
|
resolveMeetingFromParams: () => resolveMeetingFromParams,
|
|
774
774
|
resolveSpaceFromParams: () => resolveSpaceFromParams
|
|
775
775
|
});
|
|
776
|
-
const loadGoogleMeetCreateModule = createLazyRuntimeModule(() => import("./create-
|
|
776
|
+
const loadGoogleMeetCreateModule = createLazyRuntimeModule(() => import("./create-Cr6rg236.js").then((n) => n.t));
|
|
777
777
|
async function createMeetFromParams(params) {
|
|
778
778
|
return (await loadGoogleMeetCreateModule()).createMeetFromParams(params);
|
|
779
779
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { i as isGoogleMeetBrowserManualActionError, n as GOOGLE_MEET_NODE_COMMAND } from "./google-meet-platform-constants-Bs5iAg3E.js";
|
|
2
|
-
import { i as resolveGoogleMeetGatewayOperationTimeoutMs } from "./config-
|
|
2
|
+
import { i as resolveGoogleMeetGatewayOperationTimeoutMs } from "./config-C-6enWkx.js";
|
|
3
3
|
import { asNonArrayRecord as asParamRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
4
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
5
5
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
6
6
|
//#region extensions/google-meet/src/plugin-registration.ts
|
|
7
|
-
const loadGoogleMeetPluginHelpers = createLazyRuntimeModule(() => import("./plugin-helpers-
|
|
8
|
-
const loadGoogleMeetCliModule = createLazyRuntimeModule(() => import("./cli-
|
|
9
|
-
const loadGoogleMeetNodeHostModule = createLazyRuntimeModule(() => import("./node-host-
|
|
10
|
-
const loadGoogleMeetRuntimeModule = createLazyRuntimeModule(() => import("./runtime-
|
|
7
|
+
const loadGoogleMeetPluginHelpers = createLazyRuntimeModule(() => import("./plugin-helpers-RSH2DZTl.js").then((n) => n.r));
|
|
8
|
+
const loadGoogleMeetCliModule = createLazyRuntimeModule(() => import("./cli-BCUxht2Q.js"));
|
|
9
|
+
const loadGoogleMeetNodeHostModule = createLazyRuntimeModule(() => import("./node-host-DS-lLN37.js"));
|
|
10
|
+
const loadGoogleMeetRuntimeModule = createLazyRuntimeModule(() => import("./runtime-CXfjJvPN.js"));
|
|
11
11
|
const loadGoogleMeetNodeInvokePolicyModule = createLazyRuntimeModule(() => import("./node-invoke-policy-B0gOlLJR.js"));
|
|
12
12
|
const loadGoogleMeetGatewayRuntimeModule = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/gateway-runtime"));
|
|
13
13
|
const loadGoogleMeetNodeInvokePolicy = async (config) => (await loadGoogleMeetNodeInvokePolicyModule()).createGoogleMeetChromeNodeInvokePolicy(config);
|
|
@@ -38,7 +38,7 @@ function googleMeetGatewayMethodForToolAction(action) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
function isGoogleMeetAgentToolActionUnsupportedOnHost(params) {
|
|
41
|
-
const platform =
|
|
41
|
+
const platform = googleMeetToolDeps.platform();
|
|
42
42
|
if (platform === "darwin" || platform === "linux") return false;
|
|
43
43
|
const action = params.raw.action;
|
|
44
44
|
if (action !== "join" && action !== "test_speech" && !(action === "create" && shouldJoinCreatedMeet(params.raw))) return false;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { n as GOOGLE_MEET_NODE_COMMAND } from "./google-meet-platform-constants-Bs5iAg3E.js";
|
|
1
|
+
import { n as GOOGLE_MEET_NODE_COMMAND, t as GOOGLE_MEET_BROWSER_NODE_ADAPTER } from "./google-meet-platform-constants-Bs5iAg3E.js";
|
|
2
2
|
import { t as normalizeMeetUrl } from "./meet-url-BP2Jlvjs.js";
|
|
3
3
|
import { c as callBrowserProxyOnNode, l as resolveChromeNode, u as resolveChromeNodeInfo } from "./chrome-create-PKAyxCiL.js";
|
|
4
4
|
import { n as normalizeDialInNumber, t as GOOGLE_MEET_PLATFORM_ADAPTER } from "./google-meet-platform-adapter-C3J-iFRE.js";
|
|
5
5
|
import { asOptionalRecord, asRecord, normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
6
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
7
|
-
import { addTimerTimeoutGraceMs } from "openclaw/plugin-sdk/number-runtime";
|
|
8
7
|
import { GatewayClient, startGatewayClientWhenEventLoopReady } from "openclaw/plugin-sdk/gateway-runtime";
|
|
9
8
|
import path from "node:path";
|
|
10
9
|
import { isBlockedHostnameOrIp } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
11
|
-
import { MeetingPlatformAdapter, MeetingSessionRuntime, addMeetingSetupCheck,
|
|
10
|
+
import { MeetingPlatformAdapter, MeetingSessionRuntime, addMeetingSetupCheck, createMeetingSession, createMeetingSetupStatus, createMeetingVoiceCallGateway, endMeetingVoiceCallGatewayCall, getMeetingVoiceCallGatewayCall, isMeetingVoiceCallMissingError, joinMeetingViaVoiceCallGateway, leaveMeetingWithBrowser, readMeetingTranscriptWithBrowser, recoverMeetingBrowserTab, resolveLocalMeetingBrowserRequest, speakMeetingViaVoiceCallGateway } from "openclaw/plugin-sdk/meeting-runtime";
|
|
12
11
|
import { resolveDefaultAgentId } from "openclaw/plugin-sdk/agent-runtime";
|
|
13
12
|
import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
|
|
14
13
|
import fs from "node:fs";
|
|
@@ -206,155 +205,28 @@ function addGoogleMeetSetupCheck(status, check) {
|
|
|
206
205
|
}
|
|
207
206
|
//#endregion
|
|
208
207
|
//#region extensions/google-meet/src/transports/chrome.ts
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
timeoutMs: params.timeoutMs,
|
|
223
|
-
run: async (argv, timeoutMs) => {
|
|
224
|
-
const result = await params.runtime.system.runCommandWithTimeout(argv, { timeoutMs });
|
|
225
|
-
return {
|
|
226
|
-
...result,
|
|
227
|
-
code: result.code ?? 1
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
return audio;
|
|
232
|
-
}
|
|
233
|
-
async function assertGoogleMeetAudioAvailable(params) {
|
|
234
|
-
await prepareGoogleMeetAudioRuntime(params);
|
|
235
|
-
}
|
|
208
|
+
const chromeTransport = MeetingPlatformAdapter.createChromeTransportWithExternalAudio({
|
|
209
|
+
browserNodeAdapter: GOOGLE_MEET_BROWSER_NODE_ADAPTER,
|
|
210
|
+
isRealtimeRouteReady: (mode, health) => !MeetingPlatformAdapter.isTalkBackMode(mode) || MeetingPlatformAdapter.isRealtimeRouteReady(mode, health),
|
|
211
|
+
isTalkBackMode: MeetingPlatformAdapter.isTalkBackMode,
|
|
212
|
+
meetingLabel: "Google Meet",
|
|
213
|
+
nodeCommandName: GOOGLE_MEET_NODE_COMMAND,
|
|
214
|
+
platform: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
215
|
+
preserveTrackedBrowserOnEngineFailure: false,
|
|
216
|
+
startupFailurePolicy: "owned",
|
|
217
|
+
runtime: MeetingPlatformAdapter.createChromeRuntimeBindings()
|
|
218
|
+
});
|
|
219
|
+
const assertGoogleMeetAudioAvailable = chromeTransport.assertAudioDeviceAvailable;
|
|
220
|
+
const launchChromeMeetOnNode = chromeTransport.launchOnNode;
|
|
236
221
|
async function launchChromeMeet(params) {
|
|
237
|
-
|
|
238
|
-
const checkRealtimeAudioPrerequisites = async () => {
|
|
239
|
-
if (!MeetingPlatformAdapter.isTalkBackMode(params.mode)) return;
|
|
240
|
-
audio = await prepareGoogleMeetAudioRuntime({
|
|
241
|
-
runtime: params.runtime,
|
|
242
|
-
config: params.config,
|
|
243
|
-
timeoutMs: Math.min(params.config.chrome.joinTimeoutMs, 1e4)
|
|
244
|
-
});
|
|
245
|
-
if (params.config.chrome.audioBridgeHealthCommand) {
|
|
246
|
-
const health = await params.runtime.system.runCommandWithTimeout(params.config.chrome.audioBridgeHealthCommand, { timeoutMs: params.config.chrome.joinTimeoutMs });
|
|
247
|
-
if (health.code !== 0) throw new Error(`Chrome audio bridge health check failed: ${health.stderr || health.stdout || health.code}`);
|
|
248
|
-
}
|
|
249
|
-
};
|
|
250
|
-
const startRealtimeAudioBridge = async () => {
|
|
251
|
-
if (!MeetingPlatformAdapter.isTalkBackMode(params.mode)) return;
|
|
252
|
-
if (params.config.chrome.audioBridgeCommand) {
|
|
253
|
-
if (params.mode === "agent") throw new Error("Chrome agent mode requires chrome.audioInputCommand and chrome.audioOutputCommand so OpenClaw can run STT and regular TTS directly.");
|
|
254
|
-
const bridge = await params.runtime.system.runCommandWithTimeout(params.config.chrome.audioBridgeCommand, { timeoutMs: params.config.chrome.joinTimeoutMs });
|
|
255
|
-
if (bridge.code !== 0) throw new Error(`failed to start Chrome audio bridge: ${bridge.stderr || bridge.stdout || bridge.code}`);
|
|
256
|
-
return { type: "external-command" };
|
|
257
|
-
}
|
|
258
|
-
if (!params.config.chrome.audioInputCommand || !params.config.chrome.audioOutputCommand) throw new Error("Chrome talk-back mode requires chrome.audioInputCommand and chrome.audioOutputCommand, or chrome.audioBridgeCommand for an external bridge.");
|
|
259
|
-
if (!audio) throw new Error("Google Meet audio backend was not prepared.");
|
|
260
|
-
const transport = createLocalMeetingRealtimeAudioTransport({
|
|
261
|
-
inputCommand: audio.inputCommand,
|
|
262
|
-
outputCommand: audio.outputCommand,
|
|
263
|
-
audioFormat: params.config.chrome.audioFormat,
|
|
264
|
-
bargeInInputCommand: params.config.chrome.bargeInInputCommand,
|
|
265
|
-
bargeInRmsThreshold: params.config.chrome.bargeInRmsThreshold,
|
|
266
|
-
bargeInPeakThreshold: params.config.chrome.bargeInPeakThreshold,
|
|
267
|
-
bargeInCooldownMs: params.config.chrome.bargeInCooldownMs,
|
|
268
|
-
logger: params.logger,
|
|
269
|
-
logScope: GOOGLE_MEET_PLATFORM_ADAPTER.logScope
|
|
270
|
-
});
|
|
271
|
-
const bindings = createMeetingRealtimeEngineBindings({
|
|
272
|
-
platform: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
273
|
-
...params
|
|
274
|
-
});
|
|
275
|
-
const engine = params.mode === "agent" ? await startMeetingAgentRealtimeEngine({
|
|
276
|
-
config: params.config,
|
|
277
|
-
fullConfig: params.fullConfig,
|
|
278
|
-
runtime: params.runtime,
|
|
279
|
-
platform: bindings.platform,
|
|
280
|
-
meetingSessionId: params.meetingSessionId,
|
|
281
|
-
requesterSessionKey: params.requesterSessionKey,
|
|
282
|
-
transport,
|
|
283
|
-
logger: params.logger,
|
|
284
|
-
consultAgent: bindings.consultAgent
|
|
285
|
-
}) : await startMeetingRealtimeEngine({
|
|
286
|
-
config: {
|
|
287
|
-
...params.config,
|
|
288
|
-
realtime: {
|
|
289
|
-
...params.config.realtime,
|
|
290
|
-
strategy: "bidi"
|
|
291
|
-
}
|
|
292
|
-
},
|
|
293
|
-
fullConfig: params.fullConfig,
|
|
294
|
-
runtime: params.runtime,
|
|
295
|
-
...bindings,
|
|
296
|
-
meetingSessionId: params.meetingSessionId,
|
|
297
|
-
requesterSessionKey: params.requesterSessionKey,
|
|
298
|
-
transport,
|
|
299
|
-
logger: params.logger
|
|
300
|
-
});
|
|
301
|
-
return {
|
|
302
|
-
type: "command-pair",
|
|
303
|
-
inputCommand: audio.inputCommand,
|
|
304
|
-
outputCommand: audio.outputCommand,
|
|
305
|
-
...engine
|
|
306
|
-
};
|
|
307
|
-
};
|
|
308
|
-
await checkRealtimeAudioPrerequisites();
|
|
309
|
-
if (!params.config.chrome.launch) {
|
|
310
|
-
const recovered = await recoverMeetingBrowserTab({
|
|
311
|
-
adapter: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
312
|
-
allowSessionAdoption: true,
|
|
313
|
-
autoJoin: params.config.chrome.autoJoin,
|
|
314
|
-
callBrowser: await resolveLocalMeetingBrowserRequest(params.runtime),
|
|
315
|
-
captureCaptions: shouldCaptureCaptions(params.mode, params.fullConfig),
|
|
316
|
-
config: params.config.chrome,
|
|
317
|
-
locationLabel: "in local Chrome",
|
|
318
|
-
meetingSessionId: params.meetingSessionId,
|
|
319
|
-
mode: params.mode,
|
|
320
|
-
requestedMeetingUrl: params.url,
|
|
321
|
-
trackedMeetingUrl: params.url,
|
|
322
|
-
trackedTargetId: void 0
|
|
323
|
-
});
|
|
324
|
-
const audioBridge = MeetingPlatformAdapter.isRealtimeRouteReady(params.mode, recovered.browser) ? await startRealtimeAudioBridge() : void 0;
|
|
325
|
-
return {
|
|
326
|
-
launched: false,
|
|
327
|
-
audioBackend: audio?.backend,
|
|
328
|
-
audioBridge,
|
|
329
|
-
browser: recovered.browser,
|
|
330
|
-
tab: recovered.targetId ? {
|
|
331
|
-
targetId: recovered.targetId,
|
|
332
|
-
openedByPlugin: false
|
|
333
|
-
} : void 0
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
const result = await openMeetingWithBrowser({
|
|
337
|
-
adapter: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
338
|
-
callBrowser: await resolveLocalMeetingBrowserRequest(params.runtime),
|
|
339
|
-
config: params.config.chrome,
|
|
340
|
-
session: {
|
|
341
|
-
captureCaptions: shouldCaptureCaptions(params.mode, params.fullConfig),
|
|
342
|
-
meetingSessionId: params.meetingSessionId,
|
|
343
|
-
mode: params.mode,
|
|
344
|
-
url: params.url
|
|
345
|
-
}
|
|
346
|
-
});
|
|
347
|
-
const audioBridge = MeetingPlatformAdapter.isRealtimeRouteReady(params.mode, result.browser) ? await startRealtimeAudioBridge() : void 0;
|
|
222
|
+
const result = await chromeTransport.launchInChrome(params);
|
|
348
223
|
return {
|
|
349
224
|
...result,
|
|
350
|
-
|
|
351
|
-
audioBridge
|
|
225
|
+
audioBridge: result.audioBridge
|
|
352
226
|
};
|
|
353
227
|
}
|
|
354
|
-
function
|
|
355
|
-
|
|
356
|
-
if (!value || typeof value !== "object") throw new Error("Google Meet node returned an invalid start result.");
|
|
357
|
-
return value;
|
|
228
|
+
function shouldCaptureCaptions(mode, fullConfig) {
|
|
229
|
+
return mode === "transcribe" || !fullConfig || resolveTranscriptsConfig(fullConfig.transcripts).enabled;
|
|
358
230
|
}
|
|
359
231
|
function chromeNodeBrowserRequest(runtime, nodeId) {
|
|
360
232
|
return async (request) => await callBrowserProxyOnNode({
|
|
@@ -396,51 +268,6 @@ async function readChromeMeetTranscript(params) {
|
|
|
396
268
|
timeoutMs: Math.min(Math.max(1e3, params.config.chrome.joinTimeoutMs), 1e4)
|
|
397
269
|
});
|
|
398
270
|
}
|
|
399
|
-
async function openMeetWithBrowserProxy(params) {
|
|
400
|
-
const callBrowser = async (request) => await callBrowserProxyOnNode({
|
|
401
|
-
runtime: params.runtime,
|
|
402
|
-
nodeId: params.nodeId,
|
|
403
|
-
method: request.method,
|
|
404
|
-
path: request.path,
|
|
405
|
-
body: request.body,
|
|
406
|
-
timeoutMs: request.timeoutMs
|
|
407
|
-
});
|
|
408
|
-
if (!params.config.chrome.launch) {
|
|
409
|
-
const recovered = await recoverMeetingBrowserTab({
|
|
410
|
-
adapter: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
411
|
-
allowSessionAdoption: true,
|
|
412
|
-
autoJoin: params.config.chrome.autoJoin,
|
|
413
|
-
callBrowser,
|
|
414
|
-
captureCaptions: params.captureCaptions,
|
|
415
|
-
config: params.config.chrome,
|
|
416
|
-
locationLabel: "on the selected Chrome node",
|
|
417
|
-
meetingSessionId: params.meetingSessionId,
|
|
418
|
-
mode: params.mode,
|
|
419
|
-
requestedMeetingUrl: params.url,
|
|
420
|
-
trackedMeetingUrl: params.url,
|
|
421
|
-
trackedTargetId: void 0
|
|
422
|
-
});
|
|
423
|
-
return {
|
|
424
|
-
launched: false,
|
|
425
|
-
browser: recovered.browser,
|
|
426
|
-
tab: recovered.targetId ? {
|
|
427
|
-
targetId: recovered.targetId,
|
|
428
|
-
openedByPlugin: false
|
|
429
|
-
} : void 0
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
return await openMeetingWithBrowser({
|
|
433
|
-
adapter: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
434
|
-
callBrowser,
|
|
435
|
-
config: params.config.chrome,
|
|
436
|
-
session: {
|
|
437
|
-
captureCaptions: params.captureCaptions,
|
|
438
|
-
mode: params.mode,
|
|
439
|
-
meetingSessionId: params.meetingSessionId,
|
|
440
|
-
url: params.url
|
|
441
|
-
}
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
271
|
async function recoverCurrentMeetTab(params) {
|
|
445
272
|
const node = params.transport === "chrome-node" ? { nodeId: await resolveChromeNode({
|
|
446
273
|
runtime: params.runtime,
|
|
@@ -465,155 +292,6 @@ async function recoverCurrentMeetTab(params) {
|
|
|
465
292
|
})
|
|
466
293
|
};
|
|
467
294
|
}
|
|
468
|
-
async function launchChromeMeetOnNode(params) {
|
|
469
|
-
const nodeId = await resolveChromeNode({
|
|
470
|
-
runtime: params.runtime,
|
|
471
|
-
requestedNode: params.config.chromeNode.node
|
|
472
|
-
});
|
|
473
|
-
try {
|
|
474
|
-
await params.runtime.nodes.invoke({
|
|
475
|
-
nodeId,
|
|
476
|
-
command: GOOGLE_MEET_NODE_COMMAND,
|
|
477
|
-
params: {
|
|
478
|
-
action: "stopByUrl",
|
|
479
|
-
url: params.url,
|
|
480
|
-
mode: params.mode
|
|
481
|
-
},
|
|
482
|
-
timeoutMs: 5e3
|
|
483
|
-
});
|
|
484
|
-
} catch (error) {
|
|
485
|
-
params.logger.debug?.(`[google-meet] node bridge cleanup before join ignored: ${error instanceof Error ? error.message : String(error)}`);
|
|
486
|
-
}
|
|
487
|
-
const setup = MeetingPlatformAdapter.isTalkBackMode(params.mode) ? parseNodeStartResult(await params.runtime.nodes.invoke({
|
|
488
|
-
nodeId,
|
|
489
|
-
command: GOOGLE_MEET_NODE_COMMAND,
|
|
490
|
-
params: {
|
|
491
|
-
action: "setup",
|
|
492
|
-
audioBackend: params.config.chrome.audioBackend,
|
|
493
|
-
audioFormat: params.config.chrome.audioFormat,
|
|
494
|
-
audioBufferBytes: params.config.chrome.audioBufferBytes,
|
|
495
|
-
...params.config.chrome.audioInputCommandOverride ? { audioInputCommand: params.config.chrome.audioInputCommandOverride } : {},
|
|
496
|
-
...params.config.chrome.audioOutputCommandOverride ? { audioOutputCommand: params.config.chrome.audioOutputCommandOverride } : {}
|
|
497
|
-
},
|
|
498
|
-
timeoutMs: 12e3
|
|
499
|
-
})) : void 0;
|
|
500
|
-
const browserControl = await openMeetWithBrowserProxy({
|
|
501
|
-
runtime: params.runtime,
|
|
502
|
-
nodeId,
|
|
503
|
-
config: params.config,
|
|
504
|
-
captureCaptions: shouldCaptureCaptions(params.mode, params.fullConfig),
|
|
505
|
-
mode: params.mode,
|
|
506
|
-
meetingSessionId: params.meetingSessionId,
|
|
507
|
-
url: params.url
|
|
508
|
-
});
|
|
509
|
-
if (MeetingPlatformAdapter.isTalkBackMode(params.mode) && !MeetingPlatformAdapter.isRealtimeRouteReady(params.mode, browserControl.browser)) return {
|
|
510
|
-
nodeId,
|
|
511
|
-
launched: browserControl.launched,
|
|
512
|
-
audioBackend: setup?.audioBackend,
|
|
513
|
-
browser: browserControl.browser,
|
|
514
|
-
tab: browserControl.tab
|
|
515
|
-
};
|
|
516
|
-
const result = parseNodeStartResult(await params.runtime.nodes.invoke({
|
|
517
|
-
nodeId,
|
|
518
|
-
command: GOOGLE_MEET_NODE_COMMAND,
|
|
519
|
-
params: {
|
|
520
|
-
action: "start",
|
|
521
|
-
url: params.url,
|
|
522
|
-
mode: params.mode,
|
|
523
|
-
launch: false,
|
|
524
|
-
browserProfile: params.config.chrome.browserProfile,
|
|
525
|
-
joinTimeoutMs: params.config.chrome.joinTimeoutMs,
|
|
526
|
-
audioBackend: params.config.chrome.audioBackend,
|
|
527
|
-
audioFormat: params.config.chrome.audioFormat,
|
|
528
|
-
audioBufferBytes: params.config.chrome.audioBufferBytes,
|
|
529
|
-
...params.config.chrome.audioInputCommandOverride ? { audioInputCommand: params.config.chrome.audioInputCommandOverride } : {},
|
|
530
|
-
...params.config.chrome.audioOutputCommandOverride ? { audioOutputCommand: params.config.chrome.audioOutputCommandOverride } : {},
|
|
531
|
-
audioBridgeCommand: params.config.chrome.audioBridgeCommand,
|
|
532
|
-
audioBridgeHealthCommand: params.config.chrome.audioBridgeHealthCommand
|
|
533
|
-
},
|
|
534
|
-
timeoutMs: addTimerTimeoutGraceMs(params.config.chrome.joinTimeoutMs) ?? 1
|
|
535
|
-
}));
|
|
536
|
-
if (result.audioBridge?.type === "node-command-pair") {
|
|
537
|
-
if (!result.bridgeId) throw new Error("Google Meet node did not return an audio bridge id.");
|
|
538
|
-
const transport = createNodeMeetingRealtimeAudioTransport({
|
|
539
|
-
runtime: params.runtime,
|
|
540
|
-
nodeId,
|
|
541
|
-
bridgeId: result.bridgeId,
|
|
542
|
-
audioFormat: params.config.chrome.audioFormat,
|
|
543
|
-
logger: params.logger,
|
|
544
|
-
commandName: GOOGLE_MEET_NODE_COMMAND,
|
|
545
|
-
logScope: GOOGLE_MEET_PLATFORM_ADAPTER.logScope,
|
|
546
|
-
logPrefix: params.mode === "agent" ? "node agent" : "node"
|
|
547
|
-
});
|
|
548
|
-
Reflect.set(transport, Symbol.for("openclaw.internal.meeting-node-output-generation.v1"), result.audioBridge.outputGeneration === true);
|
|
549
|
-
const bindings = createMeetingRealtimeEngineBindings({
|
|
550
|
-
platform: GOOGLE_MEET_PLATFORM_ADAPTER,
|
|
551
|
-
...params
|
|
552
|
-
});
|
|
553
|
-
const engine = params.mode === "agent" ? await startMeetingAgentRealtimeEngine({
|
|
554
|
-
config: params.config,
|
|
555
|
-
fullConfig: params.fullConfig,
|
|
556
|
-
runtime: params.runtime,
|
|
557
|
-
platform: bindings.platform,
|
|
558
|
-
meetingSessionId: params.meetingSessionId,
|
|
559
|
-
requesterSessionKey: params.requesterSessionKey,
|
|
560
|
-
logPrefix: "node",
|
|
561
|
-
transport,
|
|
562
|
-
logger: params.logger,
|
|
563
|
-
consultAgent: bindings.consultAgent
|
|
564
|
-
}) : await startMeetingRealtimeEngine({
|
|
565
|
-
config: {
|
|
566
|
-
...params.config,
|
|
567
|
-
realtime: {
|
|
568
|
-
...params.config.realtime,
|
|
569
|
-
strategy: "bidi"
|
|
570
|
-
}
|
|
571
|
-
},
|
|
572
|
-
fullConfig: params.fullConfig,
|
|
573
|
-
runtime: params.runtime,
|
|
574
|
-
...bindings,
|
|
575
|
-
meetingSessionId: params.meetingSessionId,
|
|
576
|
-
requesterSessionKey: params.requesterSessionKey,
|
|
577
|
-
logPrefix: "node",
|
|
578
|
-
talkSessionId: `google-meet:${params.meetingSessionId}:${result.bridgeId}:node-realtime`,
|
|
579
|
-
talkContext: {
|
|
580
|
-
nodeId,
|
|
581
|
-
bridgeId: result.bridgeId
|
|
582
|
-
},
|
|
583
|
-
transport,
|
|
584
|
-
logger: params.logger
|
|
585
|
-
});
|
|
586
|
-
const bridge = {
|
|
587
|
-
type: "node-command-pair",
|
|
588
|
-
nodeId,
|
|
589
|
-
bridgeId: result.bridgeId,
|
|
590
|
-
...engine
|
|
591
|
-
};
|
|
592
|
-
return {
|
|
593
|
-
nodeId,
|
|
594
|
-
launched: browserControl.launched || result.launched === true,
|
|
595
|
-
audioBackend: result.audioBackend ?? setup?.audioBackend,
|
|
596
|
-
audioBridge: bridge,
|
|
597
|
-
browser: browserControl.browser ?? result.browser,
|
|
598
|
-
tab: browserControl.tab
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
if (result.audioBridge?.type === "external-command") return {
|
|
602
|
-
nodeId,
|
|
603
|
-
launched: browserControl.launched || result.launched === true,
|
|
604
|
-
audioBackend: result.audioBackend ?? setup?.audioBackend,
|
|
605
|
-
audioBridge: { type: "external-command" },
|
|
606
|
-
browser: browserControl.browser ?? result.browser,
|
|
607
|
-
tab: browserControl.tab
|
|
608
|
-
};
|
|
609
|
-
return {
|
|
610
|
-
nodeId,
|
|
611
|
-
launched: browserControl.launched || result.launched === true,
|
|
612
|
-
audioBackend: result.audioBackend ?? setup?.audioBackend,
|
|
613
|
-
browser: browserControl.browser ?? result.browser,
|
|
614
|
-
tab: browserControl.tab
|
|
615
|
-
};
|
|
616
|
-
}
|
|
617
295
|
//#endregion
|
|
618
296
|
//#region extensions/google-meet/src/runtime-setup.ts
|
|
619
297
|
function collectChromeAudioCommands(config) {
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/google-meet",
|
|
3
|
-
"version": "2026.9.
|
|
3
|
+
"version": "2026.9.4",
|
|
4
4
|
"description": "OpenClaw Google Meet participant plugin for joining calls through Chrome or Twilio transports.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"typebox": "1.3.18"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"openclaw": ">=2026.9.
|
|
15
|
+
"openclaw": ">=2026.9.4"
|
|
16
16
|
},
|
|
17
17
|
"peerDependenciesMeta": {
|
|
18
18
|
"openclaw": {
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"minHostVersion": ">=2026.4.20"
|
|
30
30
|
},
|
|
31
31
|
"compat": {
|
|
32
|
-
"pluginApi": ">=2026.9.
|
|
32
|
+
"pluginApi": ">=2026.9.4"
|
|
33
33
|
},
|
|
34
34
|
"build": {
|
|
35
|
-
"openclawVersion": "2026.9.
|
|
35
|
+
"openclawVersion": "2026.9.4"
|
|
36
36
|
},
|
|
37
37
|
"release": {
|
|
38
38
|
"publishToClawHub": true,
|