nodmix 2026.5.25
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/CHANGELOG.md +11573 -0
- package/LICENSE +21 -0
- package/README.md +486 -0
- package/docs/.i18n/README.md +81 -0
- package/docs/.i18n/ar-navigation.json +18 -0
- package/docs/.i18n/de-navigation.json +18 -0
- package/docs/.i18n/es-navigation.json +18 -0
- package/docs/.i18n/fr-navigation.json +18 -0
- package/docs/.i18n/glossary.ar.json +78 -0
- package/docs/.i18n/glossary.de.json +78 -0
- package/docs/.i18n/glossary.es.json +78 -0
- package/docs/.i18n/glossary.fa.json +78 -0
- package/docs/.i18n/glossary.fr.json +78 -0
- package/docs/.i18n/glossary.id.json +78 -0
- package/docs/.i18n/glossary.it.json +78 -0
- package/docs/.i18n/glossary.ja-JP.json +98 -0
- package/docs/.i18n/glossary.ko.json +78 -0
- package/docs/.i18n/glossary.nl.json +78 -0
- package/docs/.i18n/glossary.pl.json +78 -0
- package/docs/.i18n/glossary.pt-BR.json +78 -0
- package/docs/.i18n/glossary.th.json +78 -0
- package/docs/.i18n/glossary.tr.json +78 -0
- package/docs/.i18n/glossary.uk.json +78 -0
- package/docs/.i18n/glossary.vi.json +78 -0
- package/docs/.i18n/glossary.zh-CN.json +1002 -0
- package/docs/.i18n/glossary.zh-TW.json +78 -0
- package/docs/.i18n/id-navigation.json +18 -0
- package/docs/.i18n/it-navigation.json +18 -0
- package/docs/.i18n/ja-navigation.json +18 -0
- package/docs/.i18n/ko-navigation.json +18 -0
- package/docs/.i18n/pl-navigation.json +18 -0
- package/docs/.i18n/pt-BR-navigation.json +18 -0
- package/docs/.i18n/tr-navigation.json +18 -0
- package/docs/.i18n/translation-workflow.md +111 -0
- package/docs/.i18n/zh-Hans-navigation.json +542 -0
- package/docs/AGENTS.md +36 -0
- package/docs/announcements/bluebubbles-imessage.md +79 -0
- package/docs/assets/install-script.svg +1 -0
- package/docs/assets/macos-onboarding/01-macos-warning.jpeg +0 -0
- package/docs/assets/macos-onboarding/02-local-networks.jpeg +0 -0
- package/docs/assets/macos-onboarding/03-security-notice.png +0 -0
- package/docs/assets/macos-onboarding/04-choose-gateway.png +0 -0
- package/docs/assets/macos-onboarding/05-permissions.png +0 -0
- package/docs/assets/openclaw-logo-text-dark.png +0 -0
- package/docs/assets/openclaw-logo-text-dark.svg +418 -0
- package/docs/assets/openclaw-logo-text.png +0 -0
- package/docs/assets/openclaw-logo-text.svg +418 -0
- package/docs/assets/pixel-lobster.svg +60 -0
- package/docs/assets/pr/quick-settings-browser-tools.png +0 -0
- package/docs/assets/showcase/agents-ui.jpg +0 -0
- package/docs/assets/showcase/bambu-cli.png +0 -0
- package/docs/assets/showcase/codexmonitor.png +0 -0
- package/docs/assets/showcase/gohome-grafana.png +0 -0
- package/docs/assets/showcase/ios-testflight.jpg +0 -0
- package/docs/assets/showcase/oura-health.png +0 -0
- package/docs/assets/showcase/padel-cli.svg +11 -0
- package/docs/assets/showcase/padel-screenshot.jpg +0 -0
- package/docs/assets/showcase/papla-tts.jpg +0 -0
- package/docs/assets/showcase/pr-review-telegram.jpg +0 -0
- package/docs/assets/showcase/roborock-screenshot.jpg +0 -0
- package/docs/assets/showcase/roborock-status.svg +13 -0
- package/docs/assets/showcase/roof-camera-sky.jpg +0 -0
- package/docs/assets/showcase/snag.png +0 -0
- package/docs/assets/showcase/tesco-shop.jpg +0 -0
- package/docs/assets/showcase/wienerlinien.png +0 -0
- package/docs/assets/showcase/wine-cellar-skill.jpg +0 -0
- package/docs/assets/showcase/winix-air-purifier.jpg +0 -0
- package/docs/assets/showcase/xuezh-pronunciation.jpeg +0 -0
- package/docs/assets/sponsors/blacksmith-light.svg +14 -0
- package/docs/assets/sponsors/blacksmith.svg +14 -0
- package/docs/assets/sponsors/convex-light.svg +16 -0
- package/docs/assets/sponsors/convex.svg +16 -0
- package/docs/assets/sponsors/github-light.svg +3 -0
- package/docs/assets/sponsors/github.svg +3 -0
- package/docs/assets/sponsors/nvidia-dark.svg +9 -0
- package/docs/assets/sponsors/nvidia.svg +9 -0
- package/docs/assets/sponsors/openai-light.svg +3 -0
- package/docs/assets/sponsors/openai.svg +3 -0
- package/docs/assets/sponsors/vercel-light.svg +5 -0
- package/docs/assets/sponsors/vercel.svg +5 -0
- package/docs/auth-credential-semantics.md +124 -0
- package/docs/automation/auth-monitoring.md +11 -0
- package/docs/automation/clawflow.md +12 -0
- package/docs/automation/cron-jobs.md +500 -0
- package/docs/automation/cron-vs-heartbeat.md +11 -0
- package/docs/automation/gmail-pubsub.md +11 -0
- package/docs/automation/hooks.md +365 -0
- package/docs/automation/index.md +135 -0
- package/docs/automation/poll.md +12 -0
- package/docs/automation/standing-orders.md +250 -0
- package/docs/automation/taskflow.md +155 -0
- package/docs/automation/tasks.md +374 -0
- package/docs/automation/troubleshooting.md +12 -0
- package/docs/automation/webhook.md +12 -0
- package/docs/brave-search.md +11 -0
- package/docs/channels/access-groups.md +201 -0
- package/docs/channels/ambient-room-events.md +214 -0
- package/docs/channels/bot-loop-protection.md +131 -0
- package/docs/channels/broadcast-groups.md +472 -0
- package/docs/channels/channel-routing.md +162 -0
- package/docs/channels/clickclack.md +138 -0
- package/docs/channels/discord.md +1762 -0
- package/docs/channels/feishu.md +502 -0
- package/docs/channels/googlechat.md +284 -0
- package/docs/channels/group-messages.md +95 -0
- package/docs/channels/groups.md +519 -0
- package/docs/channels/imessage-from-bluebubbles.md +259 -0
- package/docs/channels/imessage.md +813 -0
- package/docs/channels/index.md +64 -0
- package/docs/channels/irc.md +253 -0
- package/docs/channels/line.md +243 -0
- package/docs/channels/location.md +71 -0
- package/docs/channels/matrix-migration.md +370 -0
- package/docs/channels/matrix-presentation.md +77 -0
- package/docs/channels/matrix-push-rules.md +150 -0
- package/docs/channels/matrix.md +921 -0
- package/docs/channels/mattermost.md +542 -0
- package/docs/channels/msteams.md +1042 -0
- package/docs/channels/nextcloud-talk.md +176 -0
- package/docs/channels/nostr.md +253 -0
- package/docs/channels/pairing.md +214 -0
- package/docs/channels/qqbot.md +309 -0
- package/docs/channels/signal.md +400 -0
- package/docs/channels/slack.md +1564 -0
- package/docs/channels/synology-chat.md +187 -0
- package/docs/channels/telegram.md +1107 -0
- package/docs/channels/tlon.md +296 -0
- package/docs/channels/troubleshooting.md +161 -0
- package/docs/channels/twitch.md +431 -0
- package/docs/channels/wechat.md +171 -0
- package/docs/channels/whatsapp.md +739 -0
- package/docs/channels/yuanbao.md +416 -0
- package/docs/channels/zalo.md +253 -0
- package/docs/channels/zalouser.md +199 -0
- package/docs/ci.md +612 -0
- package/docs/clawhub/publishing.md +96 -0
- package/docs/cli/acp.md +370 -0
- package/docs/cli/agent.md +103 -0
- package/docs/cli/agents.md +232 -0
- package/docs/cli/approvals.md +190 -0
- package/docs/cli/backup.md +97 -0
- package/docs/cli/browser.md +307 -0
- package/docs/cli/channels.md +154 -0
- package/docs/cli/clawbot.md +25 -0
- package/docs/cli/commitments.md +90 -0
- package/docs/cli/completion.md +39 -0
- package/docs/cli/config.md +504 -0
- package/docs/cli/configure.md +77 -0
- package/docs/cli/crestodian.md +332 -0
- package/docs/cli/cron.md +281 -0
- package/docs/cli/daemon.md +67 -0
- package/docs/cli/dashboard.md +33 -0
- package/docs/cli/devices.md +204 -0
- package/docs/cli/directory.md +68 -0
- package/docs/cli/dns.md +53 -0
- package/docs/cli/docs.md +73 -0
- package/docs/cli/doctor.md +237 -0
- package/docs/cli/flows.md +52 -0
- package/docs/cli/gateway.md +567 -0
- package/docs/cli/health.md +43 -0
- package/docs/cli/hooks.md +345 -0
- package/docs/cli/index.md +396 -0
- package/docs/cli/infer.md +364 -0
- package/docs/cli/logs.md +65 -0
- package/docs/cli/mcp.md +529 -0
- package/docs/cli/memory.md +183 -0
- package/docs/cli/message.md +317 -0
- package/docs/cli/migrate.md +290 -0
- package/docs/cli/models.md +224 -0
- package/docs/cli/node.md +177 -0
- package/docs/cli/nodes.md +76 -0
- package/docs/cli/onboard.md +245 -0
- package/docs/cli/pairing.md +77 -0
- package/docs/cli/path.md +502 -0
- package/docs/cli/plugins.md +454 -0
- package/docs/cli/policy.md +418 -0
- package/docs/cli/proxy.md +89 -0
- package/docs/cli/qr.md +56 -0
- package/docs/cli/reset.md +39 -0
- package/docs/cli/sandbox.md +208 -0
- package/docs/cli/secrets.md +202 -0
- package/docs/cli/security.md +124 -0
- package/docs/cli/sessions.md +164 -0
- package/docs/cli/setup.md +59 -0
- package/docs/cli/skills.md +102 -0
- package/docs/cli/status.md +45 -0
- package/docs/cli/system.md +89 -0
- package/docs/cli/tasks.md +111 -0
- package/docs/cli/tui.md +89 -0
- package/docs/cli/uninstall.md +44 -0
- package/docs/cli/update.md +242 -0
- package/docs/cli/voicecall.md +204 -0
- package/docs/cli/webhooks.md +117 -0
- package/docs/cli/wiki.md +256 -0
- package/docs/concepts/active-memory.md +856 -0
- package/docs/concepts/agent-loop.md +185 -0
- package/docs/concepts/agent-runtimes.md +243 -0
- package/docs/concepts/agent-workspace.md +230 -0
- package/docs/concepts/agent.md +136 -0
- package/docs/concepts/architecture.md +154 -0
- package/docs/concepts/channel-docking.md +145 -0
- package/docs/concepts/commitments.md +150 -0
- package/docs/concepts/compaction.md +203 -0
- package/docs/concepts/context-engine.md +306 -0
- package/docs/concepts/context.md +199 -0
- package/docs/concepts/delegate-architecture.md +319 -0
- package/docs/concepts/dreaming.md +261 -0
- package/docs/concepts/experimental-features.md +108 -0
- package/docs/concepts/features.md +91 -0
- package/docs/concepts/mantis-slack-desktop-runbook.md +202 -0
- package/docs/concepts/mantis.md +740 -0
- package/docs/concepts/markdown-formatting.md +139 -0
- package/docs/concepts/memory-builtin.md +146 -0
- package/docs/concepts/memory-honcho.md +144 -0
- package/docs/concepts/memory-qmd.md +271 -0
- package/docs/concepts/memory-search.md +166 -0
- package/docs/concepts/memory.md +258 -0
- package/docs/concepts/message-lifecycle-refactor.md +1128 -0
- package/docs/concepts/messages.md +214 -0
- package/docs/concepts/model-failover.md +385 -0
- package/docs/concepts/model-providers.md +715 -0
- package/docs/concepts/models.md +370 -0
- package/docs/concepts/multi-agent.md +619 -0
- package/docs/concepts/oauth.md +198 -0
- package/docs/concepts/openclaw-sdk.md +323 -0
- package/docs/concepts/parallel-specialist-lanes.md +127 -0
- package/docs/concepts/personal-agent-benchmark-pack.md +74 -0
- package/docs/concepts/presence.md +117 -0
- package/docs/concepts/progress-drafts.md +362 -0
- package/docs/concepts/qa-e2e-automation.md +820 -0
- package/docs/concepts/qa-matrix.md +139 -0
- package/docs/concepts/queue-steering.md +90 -0
- package/docs/concepts/queue.md +122 -0
- package/docs/concepts/retry.md +86 -0
- package/docs/concepts/session-pruning.md +104 -0
- package/docs/concepts/session-tool.md +190 -0
- package/docs/concepts/session.md +164 -0
- package/docs/concepts/soul.md +116 -0
- package/docs/concepts/streaming.md +251 -0
- package/docs/concepts/system-prompt.md +310 -0
- package/docs/concepts/timezone.md +47 -0
- package/docs/concepts/typebox.md +309 -0
- package/docs/concepts/typing-indicators.md +88 -0
- package/docs/concepts/usage-tracking.md +66 -0
- package/docs/date-time.md +126 -0
- package/docs/debug/node-issue.md +90 -0
- package/docs/diagnostics/flags.md +138 -0
- package/docs/docs.json +1832 -0
- package/docs/gateway/authentication.md +239 -0
- package/docs/gateway/background-process.md +147 -0
- package/docs/gateway/bonjour.md +303 -0
- package/docs/gateway/bridge-protocol.md +94 -0
- package/docs/gateway/cli-backends.md +420 -0
- package/docs/gateway/config-agents.md +1514 -0
- package/docs/gateway/config-channels.md +945 -0
- package/docs/gateway/config-tools.md +769 -0
- package/docs/gateway/configuration-examples.md +705 -0
- package/docs/gateway/configuration-reference.md +1393 -0
- package/docs/gateway/configuration.md +737 -0
- package/docs/gateway/diagnostics.md +213 -0
- package/docs/gateway/discovery.md +154 -0
- package/docs/gateway/doctor.md +574 -0
- package/docs/gateway/gateway-lock.md +37 -0
- package/docs/gateway/health.md +73 -0
- package/docs/gateway/heartbeat.md +493 -0
- package/docs/gateway/index.md +383 -0
- package/docs/gateway/local-model-services.md +205 -0
- package/docs/gateway/local-models.md +355 -0
- package/docs/gateway/logging.md +149 -0
- package/docs/gateway/multiple-gateways.md +178 -0
- package/docs/gateway/network-model.md +15 -0
- package/docs/gateway/openai-http-api.md +350 -0
- package/docs/gateway/openresponses-http-api.md +347 -0
- package/docs/gateway/openshell.md +316 -0
- package/docs/gateway/opentelemetry.md +404 -0
- package/docs/gateway/operator-scopes.md +111 -0
- package/docs/gateway/pairing.md +207 -0
- package/docs/gateway/prometheus.md +230 -0
- package/docs/gateway/protocol.md +803 -0
- package/docs/gateway/remote-gateway-readme.md +169 -0
- package/docs/gateway/remote.md +280 -0
- package/docs/gateway/sandbox-vs-tool-policy-vs-elevated.md +146 -0
- package/docs/gateway/sandboxing.md +545 -0
- package/docs/gateway/secrets-plan-contract.md +114 -0
- package/docs/gateway/secrets.md +609 -0
- package/docs/gateway/security/audit-checks.md +127 -0
- package/docs/gateway/security/index.md +1326 -0
- package/docs/gateway/security/secure-file-operations.md +76 -0
- package/docs/gateway/tailscale.md +156 -0
- package/docs/gateway/tools-invoke-http-api.md +169 -0
- package/docs/gateway/troubleshooting.md +772 -0
- package/docs/gateway/trusted-proxy-auth.md +451 -0
- package/docs/help/debugging.md +344 -0
- package/docs/help/environment.md +214 -0
- package/docs/help/faq-first-run.md +867 -0
- package/docs/help/faq-models.md +553 -0
- package/docs/help/faq.md +1975 -0
- package/docs/help/gpt55-codex-agentic-parity-maintainers.md +196 -0
- package/docs/help/gpt55-codex-agentic-parity.md +230 -0
- package/docs/help/index.md +39 -0
- package/docs/help/scripts.md +56 -0
- package/docs/help/testing-live.md +580 -0
- package/docs/help/testing-updates-plugins.md +291 -0
- package/docs/help/testing.md +928 -0
- package/docs/help/troubleshooting.md +424 -0
- package/docs/images/configure-model-picker-unsearchable.png +0 -0
- package/docs/images/feishu-get-group-id.png +0 -0
- package/docs/images/groups-flow.svg +52 -0
- package/docs/images/mobile-ui-screenshot.png +0 -0
- package/docs/index.md +196 -0
- package/docs/install/ansible.md +233 -0
- package/docs/install/azure.md +315 -0
- package/docs/install/bun.md +59 -0
- package/docs/install/clawdock.md +112 -0
- package/docs/install/development-channels.md +135 -0
- package/docs/install/digitalocean.md +174 -0
- package/docs/install/docker-vm-runtime.md +154 -0
- package/docs/install/docker.md +562 -0
- package/docs/install/exe-dev.md +201 -0
- package/docs/install/fly.md +524 -0
- package/docs/install/gcp.md +418 -0
- package/docs/install/hetzner.md +285 -0
- package/docs/install/hostinger.md +98 -0
- package/docs/install/index.md +221 -0
- package/docs/install/installer.md +455 -0
- package/docs/install/kubernetes.md +196 -0
- package/docs/install/macos-vm.md +281 -0
- package/docs/install/migrating-claude.md +165 -0
- package/docs/install/migrating-hermes.md +177 -0
- package/docs/install/migrating.md +137 -0
- package/docs/install/nix.md +112 -0
- package/docs/install/node.md +142 -0
- package/docs/install/northflank.mdx +44 -0
- package/docs/install/oracle.md +218 -0
- package/docs/install/podman.md +210 -0
- package/docs/install/railway.mdx +92 -0
- package/docs/install/raspberry-pi.md +234 -0
- package/docs/install/render.mdx +167 -0
- package/docs/install/uninstall.md +131 -0
- package/docs/install/updating.md +280 -0
- package/docs/logging.md +318 -0
- package/docs/nav-tabs-underline.js +100 -0
- package/docs/network.md +72 -0
- package/docs/nodes/audio.md +215 -0
- package/docs/nodes/camera.md +166 -0
- package/docs/nodes/images.md +77 -0
- package/docs/nodes/index.md +439 -0
- package/docs/nodes/location-command.md +102 -0
- package/docs/nodes/media-understanding.md +469 -0
- package/docs/nodes/talk.md +154 -0
- package/docs/nodes/troubleshooting.md +123 -0
- package/docs/nodes/voicewake.md +93 -0
- package/docs/perplexity.md +11 -0
- package/docs/pi-dev.md +82 -0
- package/docs/pi.md +573 -0
- package/docs/plan/codex-context-engine-harness.md +624 -0
- package/docs/plan/ui-channels.md +284 -0
- package/docs/platforms/android.md +285 -0
- package/docs/platforms/digitalocean.md +12 -0
- package/docs/platforms/index.md +60 -0
- package/docs/platforms/ios.md +283 -0
- package/docs/platforms/linux.md +141 -0
- package/docs/platforms/mac/bundled-gateway.md +79 -0
- package/docs/platforms/mac/canvas.md +128 -0
- package/docs/platforms/mac/child-process.md +72 -0
- package/docs/platforms/mac/dev-setup.md +112 -0
- package/docs/platforms/mac/health.md +39 -0
- package/docs/platforms/mac/icon.md +36 -0
- package/docs/platforms/mac/logging.md +62 -0
- package/docs/platforms/mac/menu-bar.md +93 -0
- package/docs/platforms/mac/peekaboo.md +92 -0
- package/docs/platforms/mac/permissions.md +53 -0
- package/docs/platforms/mac/remote.md +123 -0
- package/docs/platforms/mac/signing.md +52 -0
- package/docs/platforms/mac/skills.md +43 -0
- package/docs/platforms/mac/voice-overlay.md +66 -0
- package/docs/platforms/mac/voicewake.md +73 -0
- package/docs/platforms/mac/webchat.md +54 -0
- package/docs/platforms/mac/xpc.md +66 -0
- package/docs/platforms/macos.md +226 -0
- package/docs/platforms/oracle.md +12 -0
- package/docs/platforms/raspberry-pi.md +13 -0
- package/docs/platforms/windows.md +286 -0
- package/docs/plugins/adding-capabilities.md +133 -0
- package/docs/plugins/admin-http-rpc.md +216 -0
- package/docs/plugins/agent-tools.md +13 -0
- package/docs/plugins/architecture-internals.md +1195 -0
- package/docs/plugins/architecture.md +481 -0
- package/docs/plugins/building-extensions.md +13 -0
- package/docs/plugins/building-plugins.md +330 -0
- package/docs/plugins/bundles.md +310 -0
- package/docs/plugins/cli-backend-plugins.md +310 -0
- package/docs/plugins/codex-computer-use.md +293 -0
- package/docs/plugins/codex-harness-reference.md +409 -0
- package/docs/plugins/codex-harness-runtime.md +247 -0
- package/docs/plugins/codex-harness.md +746 -0
- package/docs/plugins/codex-native-plugins.md +276 -0
- package/docs/plugins/community.md +77 -0
- package/docs/plugins/compatibility.md +164 -0
- package/docs/plugins/dependency-resolution.md +143 -0
- package/docs/plugins/google-meet.md +1737 -0
- package/docs/plugins/hooks.md +459 -0
- package/docs/plugins/install-overrides.md +80 -0
- package/docs/plugins/manage-plugins.md +210 -0
- package/docs/plugins/manifest.md +1359 -0
- package/docs/plugins/memory-lancedb.md +385 -0
- package/docs/plugins/memory-wiki.md +529 -0
- package/docs/plugins/message-presentation.md +473 -0
- package/docs/plugins/oc-path.md +166 -0
- package/docs/plugins/plugin-inventory.md +182 -0
- package/docs/plugins/reference/acpx.md +23 -0
- package/docs/plugins/reference/admin-http-rpc.md +23 -0
- package/docs/plugins/reference/alibaba.md +23 -0
- package/docs/plugins/reference/amazon-bedrock-mantle.md +23 -0
- package/docs/plugins/reference/amazon-bedrock.md +23 -0
- package/docs/plugins/reference/anthropic-vertex.md +19 -0
- package/docs/plugins/reference/anthropic.md +23 -0
- package/docs/plugins/reference/arcee.md +23 -0
- package/docs/plugins/reference/azure-speech.md +23 -0
- package/docs/plugins/reference/bonjour.md +19 -0
- package/docs/plugins/reference/brave.md +23 -0
- package/docs/plugins/reference/browser.md +23 -0
- package/docs/plugins/reference/byteplus.md +19 -0
- package/docs/plugins/reference/canvas.md +19 -0
- package/docs/plugins/reference/cerebras.md +23 -0
- package/docs/plugins/reference/chutes.md +23 -0
- package/docs/plugins/reference/clickclack.md +23 -0
- package/docs/plugins/reference/cloudflare-ai-gateway.md +23 -0
- package/docs/plugins/reference/codex.md +23 -0
- package/docs/plugins/reference/comfy.md +23 -0
- package/docs/plugins/reference/copilot-proxy.md +19 -0
- package/docs/plugins/reference/deepgram.md +23 -0
- package/docs/plugins/reference/deepinfra.md +23 -0
- package/docs/plugins/reference/deepseek.md +23 -0
- package/docs/plugins/reference/diagnostics-otel.md +19 -0
- package/docs/plugins/reference/diagnostics-prometheus.md +19 -0
- package/docs/plugins/reference/diffs.md +19 -0
- package/docs/plugins/reference/discord.md +23 -0
- package/docs/plugins/reference/document-extract.md +23 -0
- package/docs/plugins/reference/duckduckgo.md +23 -0
- package/docs/plugins/reference/elevenlabs.md +23 -0
- package/docs/plugins/reference/exa.md +23 -0
- package/docs/plugins/reference/fal.md +23 -0
- package/docs/plugins/reference/feishu.md +23 -0
- package/docs/plugins/reference/file-transfer.md +19 -0
- package/docs/plugins/reference/firecrawl.md +23 -0
- package/docs/plugins/reference/fireworks.md +23 -0
- package/docs/plugins/reference/github-copilot.md +23 -0
- package/docs/plugins/reference/google-meet.md +23 -0
- package/docs/plugins/reference/google.md +23 -0
- package/docs/plugins/reference/googlechat.md +23 -0
- package/docs/plugins/reference/gradium.md +23 -0
- package/docs/plugins/reference/groq.md +23 -0
- package/docs/plugins/reference/huggingface.md +23 -0
- package/docs/plugins/reference/imessage.md +23 -0
- package/docs/plugins/reference/inworld.md +23 -0
- package/docs/plugins/reference/irc.md +23 -0
- package/docs/plugins/reference/kilocode.md +23 -0
- package/docs/plugins/reference/kimi.md +23 -0
- package/docs/plugins/reference/line.md +23 -0
- package/docs/plugins/reference/litellm.md +23 -0
- package/docs/plugins/reference/llm-task.md +19 -0
- package/docs/plugins/reference/lmstudio.md +23 -0
- package/docs/plugins/reference/lobster.md +19 -0
- package/docs/plugins/reference/matrix.md +23 -0
- package/docs/plugins/reference/mattermost.md +23 -0
- package/docs/plugins/reference/memory-core.md +19 -0
- package/docs/plugins/reference/memory-lancedb.md +23 -0
- package/docs/plugins/reference/memory-wiki.md +23 -0
- package/docs/plugins/reference/microsoft-foundry.md +19 -0
- package/docs/plugins/reference/microsoft.md +19 -0
- package/docs/plugins/reference/migrate-claude.md +19 -0
- package/docs/plugins/reference/migrate-hermes.md +19 -0
- package/docs/plugins/reference/minimax.md +23 -0
- package/docs/plugins/reference/mistral.md +23 -0
- package/docs/plugins/reference/moonshot.md +23 -0
- package/docs/plugins/reference/msteams.md +23 -0
- package/docs/plugins/reference/nextcloud-talk.md +23 -0
- package/docs/plugins/reference/nostr.md +23 -0
- package/docs/plugins/reference/nvidia.md +23 -0
- package/docs/plugins/reference/oc-path.md +23 -0
- package/docs/plugins/reference/ollama.md +23 -0
- package/docs/plugins/reference/open-prose.md +19 -0
- package/docs/plugins/reference/openai.md +23 -0
- package/docs/plugins/reference/opencode-go.md +23 -0
- package/docs/plugins/reference/opencode.md +23 -0
- package/docs/plugins/reference/openrouter.md +23 -0
- package/docs/plugins/reference/openshell.md +19 -0
- package/docs/plugins/reference/perplexity.md +23 -0
- package/docs/plugins/reference/policy.md +23 -0
- package/docs/plugins/reference/qa-channel.md +23 -0
- package/docs/plugins/reference/qa-lab.md +19 -0
- package/docs/plugins/reference/qa-matrix.md +19 -0
- package/docs/plugins/reference/qianfan.md +23 -0
- package/docs/plugins/reference/qqbot.md +23 -0
- package/docs/plugins/reference/qwen.md +23 -0
- package/docs/plugins/reference/runway.md +23 -0
- package/docs/plugins/reference/searxng.md +19 -0
- package/docs/plugins/reference/senseaudio.md +23 -0
- package/docs/plugins/reference/sglang.md +23 -0
- package/docs/plugins/reference/signal.md +23 -0
- package/docs/plugins/reference/skill-workshop.md +23 -0
- package/docs/plugins/reference/slack.md +23 -0
- package/docs/plugins/reference/stepfun.md +23 -0
- package/docs/plugins/reference/synology-chat.md +23 -0
- package/docs/plugins/reference/synthetic.md +23 -0
- package/docs/plugins/reference/tavily.md +23 -0
- package/docs/plugins/reference/telegram.md +23 -0
- package/docs/plugins/reference/tencent.md +23 -0
- package/docs/plugins/reference/tlon.md +23 -0
- package/docs/plugins/reference/together.md +23 -0
- package/docs/plugins/reference/tokenjuice.md +23 -0
- package/docs/plugins/reference/tts-local-cli.md +19 -0
- package/docs/plugins/reference/twitch.md +23 -0
- package/docs/plugins/reference/venice.md +23 -0
- package/docs/plugins/reference/vercel-ai-gateway.md +23 -0
- package/docs/plugins/reference/vllm.md +23 -0
- package/docs/plugins/reference/voice-call.md +23 -0
- package/docs/plugins/reference/volcengine.md +23 -0
- package/docs/plugins/reference/voyage.md +19 -0
- package/docs/plugins/reference/vydra.md +23 -0
- package/docs/plugins/reference/web-readability.md +19 -0
- package/docs/plugins/reference/webhooks.md +23 -0
- package/docs/plugins/reference/whatsapp.md +23 -0
- package/docs/plugins/reference/xai.md +23 -0
- package/docs/plugins/reference/xiaomi.md +23 -0
- package/docs/plugins/reference/zai.md +23 -0
- package/docs/plugins/reference/zalo.md +23 -0
- package/docs/plugins/reference/zalouser.md +24 -0
- package/docs/plugins/reference.md +138 -0
- package/docs/plugins/sdk-agent-harness.md +339 -0
- package/docs/plugins/sdk-channel-ingress.md +137 -0
- package/docs/plugins/sdk-channel-message.md +458 -0
- package/docs/plugins/sdk-channel-plugins.md +762 -0
- package/docs/plugins/sdk-channel-turn.md +580 -0
- package/docs/plugins/sdk-entrypoints.md +333 -0
- package/docs/plugins/sdk-migration.md +949 -0
- package/docs/plugins/sdk-overview.md +501 -0
- package/docs/plugins/sdk-provider-plugins.md +807 -0
- package/docs/plugins/sdk-runtime.md +676 -0
- package/docs/plugins/sdk-setup.md +550 -0
- package/docs/plugins/sdk-subpaths.md +396 -0
- package/docs/plugins/sdk-testing.md +401 -0
- package/docs/plugins/skill-workshop.md +713 -0
- package/docs/plugins/tool-plugins.md +411 -0
- package/docs/plugins/voice-call.md +943 -0
- package/docs/plugins/webhooks.md +192 -0
- package/docs/plugins/zalouser.md +86 -0
- package/docs/prose.md +137 -0
- package/docs/providers/alibaba.md +158 -0
- package/docs/providers/anthropic.md +344 -0
- package/docs/providers/arcee.md +144 -0
- package/docs/providers/azure-speech.md +119 -0
- package/docs/providers/bedrock-mantle.md +211 -0
- package/docs/providers/bedrock.md +414 -0
- package/docs/providers/cerebras.md +130 -0
- package/docs/providers/chutes.md +153 -0
- package/docs/providers/claude-max-api-proxy.md +188 -0
- package/docs/providers/cloudflare-ai-gateway.md +119 -0
- package/docs/providers/comfy.md +362 -0
- package/docs/providers/deepgram.md +184 -0
- package/docs/providers/deepinfra.md +87 -0
- package/docs/providers/deepseek.md +146 -0
- package/docs/providers/ds4.md +309 -0
- package/docs/providers/elevenlabs.md +130 -0
- package/docs/providers/fal.md +204 -0
- package/docs/providers/fireworks.md +144 -0
- package/docs/providers/github-copilot.md +225 -0
- package/docs/providers/glm.md +137 -0
- package/docs/providers/google.md +472 -0
- package/docs/providers/gradium.md +123 -0
- package/docs/providers/groq.md +180 -0
- package/docs/providers/huggingface.md +235 -0
- package/docs/providers/index.md +102 -0
- package/docs/providers/inferrs.md +272 -0
- package/docs/providers/inworld.md +120 -0
- package/docs/providers/kilocode.md +135 -0
- package/docs/providers/litellm.md +234 -0
- package/docs/providers/lmstudio.md +224 -0
- package/docs/providers/minimax.md +505 -0
- package/docs/providers/mistral.md +235 -0
- package/docs/providers/models.md +65 -0
- package/docs/providers/moonshot.md +413 -0
- package/docs/providers/nvidia.md +140 -0
- package/docs/providers/ollama.md +1180 -0
- package/docs/providers/openai.md +1057 -0
- package/docs/providers/opencode-go.md +123 -0
- package/docs/providers/opencode.md +149 -0
- package/docs/providers/openrouter.md +349 -0
- package/docs/providers/perplexity-provider.md +123 -0
- package/docs/providers/qianfan.md +132 -0
- package/docs/providers/qwen.md +332 -0
- package/docs/providers/runway.md +103 -0
- package/docs/providers/senseaudio.md +68 -0
- package/docs/providers/sglang.md +161 -0
- package/docs/providers/stepfun.md +229 -0
- package/docs/providers/synthetic.md +154 -0
- package/docs/providers/tencent.md +130 -0
- package/docs/providers/together.md +141 -0
- package/docs/providers/venice.md +315 -0
- package/docs/providers/vercel-ai-gateway.md +128 -0
- package/docs/providers/vllm.md +383 -0
- package/docs/providers/volcengine.md +199 -0
- package/docs/providers/vydra.md +180 -0
- package/docs/providers/xai.md +560 -0
- package/docs/providers/xiaomi.md +188 -0
- package/docs/providers/zai.md +203 -0
- package/docs/refactor/access.md +9 -0
- package/docs/refactor/acp.md +298 -0
- package/docs/refactor/canvas.md +131 -0
- package/docs/refactor/ingress-core.md +341 -0
- package/docs/reference/AGENTS.default.md +129 -0
- package/docs/reference/RELEASING.md +767 -0
- package/docs/reference/api-usage-costs.md +202 -0
- package/docs/reference/application-modernization-plan.md +208 -0
- package/docs/reference/code-mode.md +757 -0
- package/docs/reference/credits.md +33 -0
- package/docs/reference/device-models.md +50 -0
- package/docs/reference/full-release-validation.md +202 -0
- package/docs/reference/memory-config.md +630 -0
- package/docs/reference/openclaw-sdk-api-design.md +390 -0
- package/docs/reference/prompt-caching.md +358 -0
- package/docs/reference/rich-output-protocol.md +79 -0
- package/docs/reference/rpc.md +43 -0
- package/docs/reference/secretref-credential-surface.md +159 -0
- package/docs/reference/secretref-user-supplied-credentials-matrix.json +663 -0
- package/docs/reference/session-management-compaction.md +461 -0
- package/docs/reference/templates/AGENTS.dev.md +89 -0
- package/docs/reference/templates/AGENTS.md +225 -0
- package/docs/reference/templates/BOOT.md +16 -0
- package/docs/reference/templates/BOOTSTRAP.md +66 -0
- package/docs/reference/templates/HEARTBEAT.md +16 -0
- package/docs/reference/templates/IDENTITY.dev.md +52 -0
- package/docs/reference/templates/IDENTITY.md +34 -0
- package/docs/reference/templates/SOUL.dev.md +82 -0
- package/docs/reference/templates/SOUL.md +49 -0
- package/docs/reference/templates/TOOLS.dev.md +29 -0
- package/docs/reference/templates/TOOLS.md +51 -0
- package/docs/reference/templates/USER.dev.md +23 -0
- package/docs/reference/templates/USER.md +28 -0
- package/docs/reference/test.md +239 -0
- package/docs/reference/token-use.md +233 -0
- package/docs/reference/transcript-hygiene.md +214 -0
- package/docs/reference/wizard.md +252 -0
- package/docs/security/CONTRIBUTING-THREAT-MODEL.md +101 -0
- package/docs/security/THREAT-MODEL-ATLAS.md +611 -0
- package/docs/security/formal-verification.md +170 -0
- package/docs/security/incident-response.md +59 -0
- package/docs/security/network-proxy.md +268 -0
- package/docs/snippets/plugin-publish/minimal-openclaw.plugin.json +12 -0
- package/docs/snippets/plugin-publish/minimal-package.json +16 -0
- package/docs/start/bootstrapping.md +49 -0
- package/docs/start/docs-directory.md +69 -0
- package/docs/start/getting-started.md +152 -0
- package/docs/start/hubs.md +201 -0
- package/docs/start/lore.md +223 -0
- package/docs/start/onboarding-overview.md +72 -0
- package/docs/start/onboarding.md +95 -0
- package/docs/start/openclaw.md +244 -0
- package/docs/start/quickstart.md +25 -0
- package/docs/start/setup.md +178 -0
- package/docs/start/showcase.md +383 -0
- package/docs/start/wizard-cli-automation.md +232 -0
- package/docs/start/wizard-cli-reference.md +331 -0
- package/docs/start/wizard.md +141 -0
- package/docs/style.css +184 -0
- package/docs/superpowers/specs/2026-04-22-tweakcn-custom-theme-import-design.md +316 -0
- package/docs/tools/acp-agents-setup.md +352 -0
- package/docs/tools/acp-agents.md +847 -0
- package/docs/tools/agent-send.md +112 -0
- package/docs/tools/apply-patch.md +64 -0
- package/docs/tools/brave-search.md +139 -0
- package/docs/tools/browser-control.md +391 -0
- package/docs/tools/browser-linux-troubleshooting.md +173 -0
- package/docs/tools/browser-login.md +77 -0
- package/docs/tools/browser-wsl2-windows-remote-cdp-troubleshooting.md +219 -0
- package/docs/tools/browser.md +769 -0
- package/docs/tools/btw.md +159 -0
- package/docs/tools/capability-cookbook.md +12 -0
- package/docs/tools/clawhub.md +5 -0
- package/docs/tools/code-execution.md +173 -0
- package/docs/tools/creating-skills.md +120 -0
- package/docs/tools/diffs.md +506 -0
- package/docs/tools/duckduckgo-search.md +109 -0
- package/docs/tools/elevated.md +128 -0
- package/docs/tools/exa-search.md +152 -0
- package/docs/tools/exec-approvals-advanced.md +360 -0
- package/docs/tools/exec-approvals.md +474 -0
- package/docs/tools/exec.md +282 -0
- package/docs/tools/firecrawl.md +155 -0
- package/docs/tools/gemini-search.md +114 -0
- package/docs/tools/grok-search.md +113 -0
- package/docs/tools/image-generation.md +433 -0
- package/docs/tools/index.md +178 -0
- package/docs/tools/kimi-search.md +105 -0
- package/docs/tools/llm-task.md +137 -0
- package/docs/tools/lobster.md +365 -0
- package/docs/tools/loop-detection.md +154 -0
- package/docs/tools/media-overview.md +157 -0
- package/docs/tools/minimax-search.md +102 -0
- package/docs/tools/multi-agent-sandbox-tools.md +409 -0
- package/docs/tools/music-generation.md +371 -0
- package/docs/tools/ollama-search.md +153 -0
- package/docs/tools/pdf.md +195 -0
- package/docs/tools/perplexity-search.md +220 -0
- package/docs/tools/plugin.md +327 -0
- package/docs/tools/reactions.md +100 -0
- package/docs/tools/searxng-search.md +141 -0
- package/docs/tools/skills-config.md +195 -0
- package/docs/tools/skills.md +535 -0
- package/docs/tools/slash-commands.md +488 -0
- package/docs/tools/steer.md +84 -0
- package/docs/tools/subagents.md +650 -0
- package/docs/tools/tavily.md +162 -0
- package/docs/tools/thinking.md +140 -0
- package/docs/tools/tokenjuice.md +81 -0
- package/docs/tools/tool-search.md +269 -0
- package/docs/tools/trajectory.md +229 -0
- package/docs/tools/tts.md +1004 -0
- package/docs/tools/video-generation.md +552 -0
- package/docs/tools/web-fetch.md +195 -0
- package/docs/tools/web.md +459 -0
- package/docs/tts.md +11 -0
- package/docs/vps.md +139 -0
- package/docs/web/control-ui.md +503 -0
- package/docs/web/dashboard.md +107 -0
- package/docs/web/index.md +133 -0
- package/docs/web/tui.md +246 -0
- package/docs/web/webchat.md +99 -0
- package/docs/whatsapp-openclaw-ai-zh.jpg +0 -0
- package/docs/whatsapp-openclaw.jpg +0 -0
- package/nodmix.mjs +487 -0
- package/package.json +1852 -0
- package/patches/.gitkeep +0 -0
- package/patches/@agentclientprotocol__claude-agent-acp@0.36.1.patch +41 -0
- package/pnpm-workspace.yaml +63 -0
- package/scripts/crabbox-wrapper.mjs +353 -0
- package/scripts/lib/official-external-channel-catalog.json +559 -0
- package/scripts/lib/official-external-plugin-catalog.json +192 -0
- package/scripts/lib/official-external-provider-catalog.json +117 -0
- package/scripts/lib/package-dist-imports.mjs +171 -0
- package/scripts/npm-runner.mjs +91 -0
- package/scripts/postinstall-bundled-plugins.mjs +978 -0
- package/scripts/preinstall-package-manager-warning.mjs +64 -0
- package/scripts/windows-cmd-helpers.mjs +20 -0
- package/skills/1password/SKILL.md +70 -0
- package/skills/1password/references/cli-examples.md +29 -0
- package/skills/1password/references/get-started.md +17 -0
- package/skills/apple-notes/SKILL.md +77 -0
- package/skills/apple-reminders/SKILL.md +118 -0
- package/skills/bear-notes/SKILL.md +107 -0
- package/skills/blogwatcher/SKILL.md +69 -0
- package/skills/blucli/SKILL.md +47 -0
- package/skills/camsnap/SKILL.md +45 -0
- package/skills/canvas/SKILL.md +78 -0
- package/skills/clawhub/SKILL.md +77 -0
- package/skills/coding-agent/SKILL.md +149 -0
- package/skills/diagram-maker/SKILL.md +53 -0
- package/skills/diagram-maker/references/excalidraw-patterns.md +85 -0
- package/skills/diagram-maker/references/svg-template.md +112 -0
- package/skills/discord/SKILL.md +136 -0
- package/skills/eightctl/SKILL.md +50 -0
- package/skills/gemini/SKILL.md +47 -0
- package/skills/gh-issues/SKILL.md +213 -0
- package/skills/gifgrep/SKILL.md +85 -0
- package/skills/github/SKILL.md +84 -0
- package/skills/gog/SKILL.md +116 -0
- package/skills/goplaces/SKILL.md +52 -0
- package/skills/healthcheck/SKILL.md +105 -0
- package/skills/himalaya/SKILL.md +80 -0
- package/skills/himalaya/references/configuration.md +184 -0
- package/skills/himalaya/references/message-composition.md +199 -0
- package/skills/imsg/SKILL.md +122 -0
- package/skills/mcporter/SKILL.md +61 -0
- package/skills/meme-maker/SKILL.md +42 -0
- package/skills/meme-maker/references/templates.json +358 -0
- package/skills/meme-maker/scripts/meme.mjs +398 -0
- package/skills/model-usage/SKILL.md +69 -0
- package/skills/model-usage/references/codexbar-cli.md +33 -0
- package/skills/model-usage/scripts/model_usage.py +319 -0
- package/skills/model-usage/scripts/test_model_usage.py +40 -0
- package/skills/nano-pdf/SKILL.md +38 -0
- package/skills/node-connect/SKILL.md +142 -0
- package/skills/node-inspect-debugger/SKILL.md +85 -0
- package/skills/notion/SKILL.md +150 -0
- package/skills/obsidian/SKILL.md +119 -0
- package/skills/openai-whisper/SKILL.md +38 -0
- package/skills/openai-whisper-api/SKILL.md +71 -0
- package/skills/openai-whisper-api/scripts/transcribe.sh +154 -0
- package/skills/openhue/SKILL.md +112 -0
- package/skills/oracle/SKILL.md +126 -0
- package/skills/ordercli/SKILL.md +78 -0
- package/skills/peekaboo/SKILL.md +190 -0
- package/skills/pyproject.toml +10 -0
- package/skills/python-debugpy/SKILL.md +73 -0
- package/skills/sag/SKILL.md +87 -0
- package/skills/session-logs/SKILL.md +151 -0
- package/skills/sherpa-onnx-tts/SKILL.md +109 -0
- package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +178 -0
- package/skills/skill-creator/SKILL.md +78 -0
- package/skills/skill-creator/license.txt +202 -0
- package/skills/skill-creator/scripts/init_skill.py +378 -0
- package/skills/skill-creator/scripts/package_skill.py +139 -0
- package/skills/skill-creator/scripts/quick_validate.py +169 -0
- package/skills/skill-creator/scripts/test_package_skill.py +161 -0
- package/skills/skill-creator/scripts/test_quick_validate.py +116 -0
- package/skills/slack/SKILL.md +78 -0
- package/skills/songsee/SKILL.md +49 -0
- package/skills/sonoscli/SKILL.md +65 -0
- package/skills/spike/SKILL.md +51 -0
- package/skills/spotify-player/SKILL.md +64 -0
- package/skills/summarize/SKILL.md +87 -0
- package/skills/taskflow/SKILL.md +149 -0
- package/skills/taskflow/examples/inbox-triage.lobster +33 -0
- package/skills/taskflow/examples/pr-intake.lobster +32 -0
- package/skills/taskflow-inbox-triage/SKILL.md +119 -0
- package/skills/things-mac/SKILL.md +86 -0
- package/skills/tmux/SKILL.md +91 -0
- package/skills/tmux/scripts/find-sessions.sh +112 -0
- package/skills/tmux/scripts/wait-for-text.sh +83 -0
- package/skills/trello/SKILL.md +108 -0
- package/skills/video-frames/SKILL.md +46 -0
- package/skills/video-frames/scripts/frame.sh +81 -0
- package/skills/voice-call/SKILL.md +45 -0
- package/skills/wacli/SKILL.md +72 -0
- package/skills/weather/SKILL.md +64 -0
- package/skills/xurl/SKILL.md +120 -0
|
@@ -0,0 +1,1737 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Google Meet plugin: join explicit Meet URLs through Chrome or Twilio with agent talk-back defaults"
|
|
3
|
+
read_when:
|
|
4
|
+
- You want an Nodmix agent to join a Google Meet call
|
|
5
|
+
- You want an Nodmix agent to create a new Google Meet call
|
|
6
|
+
- You are configuring Chrome, Chrome node, or Twilio as a Google Meet transport
|
|
7
|
+
title: "Google Meet plugin"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Google Meet participant support for Nodmix — the plugin is explicit by design:
|
|
11
|
+
|
|
12
|
+
- It only joins an explicit `https://meet.google.com/...` URL.
|
|
13
|
+
- It can create a new Meet space through the Google Meet API, then join the
|
|
14
|
+
returned URL.
|
|
15
|
+
- `agent` is the default talk-back mode: realtime transcription listens, the
|
|
16
|
+
configured Nodmix agent answers, and regular Nodmix TTS speaks into Meet.
|
|
17
|
+
- `bidi` remains available as the fallback direct realtime voice model mode.
|
|
18
|
+
- Agents choose the join behavior with `mode`: use `agent` for live
|
|
19
|
+
listen/talk-back, `bidi` for direct realtime voice fallback, or `transcribe`
|
|
20
|
+
to join/control the browser without the talk-back bridge.
|
|
21
|
+
- Auth starts as personal Google OAuth or an already signed-in Chrome profile.
|
|
22
|
+
- There is no automatic consent announcement.
|
|
23
|
+
- The default Chrome audio backend is `BlackHole 2ch`.
|
|
24
|
+
- Chrome can run locally or on a paired node host.
|
|
25
|
+
- Twilio accepts a dial-in number plus optional PIN or DTMF sequence; it
|
|
26
|
+
cannot dial a Meet URL directly.
|
|
27
|
+
- The CLI command is `googlemeet`; `meet` is reserved for broader agent
|
|
28
|
+
teleconference workflows.
|
|
29
|
+
|
|
30
|
+
## Quick start
|
|
31
|
+
|
|
32
|
+
Install the local audio dependencies and configure a realtime transcription
|
|
33
|
+
provider plus regular Nodmix TTS. OpenAI is the default transcription
|
|
34
|
+
provider; Google Gemini Live also works as a separate `bidi` voice fallback with
|
|
35
|
+
`realtime.voiceProvider: "google"`:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
brew install blackhole-2ch sox
|
|
39
|
+
export OPENAI_API_KEY=sk-...
|
|
40
|
+
# only needed when realtime.voiceProvider is "google" for bidi mode
|
|
41
|
+
export GEMINI_API_KEY=...
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`blackhole-2ch` installs the `BlackHole 2ch` virtual audio device. Homebrew's
|
|
45
|
+
installer requires a reboot before macOS exposes the device:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
sudo reboot
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
After reboot, verify both pieces:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
system_profiler SPAudioDataType | grep -i BlackHole
|
|
55
|
+
command -v sox
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Enable the plugin:
|
|
59
|
+
|
|
60
|
+
```json5
|
|
61
|
+
{
|
|
62
|
+
plugins: {
|
|
63
|
+
entries: {
|
|
64
|
+
"google-meet": {
|
|
65
|
+
enabled: true,
|
|
66
|
+
config: {},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Check setup:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
nodmix googlemeet setup
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The setup output is meant to be agent-readable and mode-aware. It reports Chrome
|
|
80
|
+
profile, node pinning, and, for realtime Chrome joins, the BlackHole/SoX audio
|
|
81
|
+
bridge and delayed realtime intro checks. For observe-only joins, check the same
|
|
82
|
+
transport with `--mode transcribe`; that mode skips realtime audio prerequisites
|
|
83
|
+
because it does not listen through or speak through the bridge:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
nodmix googlemeet setup --transport chrome-node --mode transcribe
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
When Twilio delegation is configured, setup also reports whether the
|
|
90
|
+
`voice-call` plugin, Twilio credentials, and public webhook exposure are ready.
|
|
91
|
+
Treat any `ok: false` check as a blocker for the checked transport and mode
|
|
92
|
+
before asking an agent to join. Use `nodmix googlemeet setup --json` for
|
|
93
|
+
scripts or machine-readable output. Use `--transport chrome`,
|
|
94
|
+
`--transport chrome-node`, or `--transport twilio` to preflight a specific
|
|
95
|
+
transport before an agent tries it.
|
|
96
|
+
|
|
97
|
+
For Twilio, always preflight the transport explicitly when the default transport
|
|
98
|
+
is Chrome:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
nodmix googlemeet setup --transport twilio
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
That catches missing `voice-call` wiring, Twilio credentials, or unreachable
|
|
105
|
+
webhook exposure before the agent tries to dial the meeting.
|
|
106
|
+
|
|
107
|
+
Join a meeting:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
nodmix googlemeet join https://meet.google.com/abc-defg-hij
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Or let an agent join through the `google_meet` tool:
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"action": "join",
|
|
118
|
+
"url": "https://meet.google.com/abc-defg-hij",
|
|
119
|
+
"transport": "chrome-node",
|
|
120
|
+
"mode": "agent"
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The agent-facing `google_meet` tool stays available on non-macOS hosts for
|
|
125
|
+
artifact, calendar, setup, transcribe, Twilio, and `chrome-node` flows. Local
|
|
126
|
+
Chrome talk-back actions are blocked there because the bundled Chrome audio path
|
|
127
|
+
currently depends on macOS `BlackHole 2ch`. On Linux, use `mode: "transcribe"`,
|
|
128
|
+
Twilio dial-in, or a macOS `chrome-node` host for Chrome talk-back
|
|
129
|
+
participation.
|
|
130
|
+
|
|
131
|
+
Create a new meeting and join it:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
nodmix googlemeet create --transport chrome-node --mode agent
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
For API-created rooms, use Google Meet `SpaceConfig.accessType` when you want
|
|
138
|
+
the room's no-knock policy to be explicit instead of inherited from the Google
|
|
139
|
+
account defaults:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
nodmix googlemeet create --access-type OPEN --transport chrome-node --mode agent
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`OPEN` lets anyone with the Meet URL join without knocking. `TRUSTED` lets the
|
|
146
|
+
host organization's trusted users, invited external users, and dial-in users
|
|
147
|
+
join without knocking. `RESTRICTED` limits no-knock entry to invitees. These
|
|
148
|
+
settings only apply to the official Google Meet API creation path, so OAuth
|
|
149
|
+
credentials must be configured.
|
|
150
|
+
|
|
151
|
+
If you authenticated Google Meet before this option was available, rerun
|
|
152
|
+
`nodmix googlemeet auth login --json` after adding the
|
|
153
|
+
`meetings.space.settings` scope to your Google OAuth consent screen.
|
|
154
|
+
|
|
155
|
+
Create only the URL without joining:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
nodmix googlemeet create --no-join
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
`googlemeet create` has two paths:
|
|
162
|
+
|
|
163
|
+
- API create: used when Google Meet OAuth credentials are configured. This is
|
|
164
|
+
the most deterministic path and does not depend on browser UI state.
|
|
165
|
+
- Browser fallback: used when OAuth credentials are absent. Nodmix uses the
|
|
166
|
+
pinned Chrome node, opens `https://meet.google.com/new`, waits for Google to
|
|
167
|
+
redirect to a real meeting-code URL, then returns that URL. This path requires
|
|
168
|
+
the Nodmix Chrome profile on the node to already be signed in to Google.
|
|
169
|
+
Browser automation handles Meet's own first-run microphone prompt; that prompt
|
|
170
|
+
is not treated as a Google login failure.
|
|
171
|
+
Join and create flows also try to reuse an existing Meet tab before opening a
|
|
172
|
+
new one. Matching ignores harmless URL query strings such as `authuser`, so an
|
|
173
|
+
agent retry should focus the already-open meeting instead of creating a second
|
|
174
|
+
Chrome tab.
|
|
175
|
+
|
|
176
|
+
The command/tool output includes a `source` field (`api` or `browser`) so agents
|
|
177
|
+
can explain which path was used. `create` joins the new meeting by default and
|
|
178
|
+
returns `joined: true` plus the join session. To only mint the URL, use
|
|
179
|
+
`create --no-join` on the CLI or pass `"join": false` to the tool.
|
|
180
|
+
|
|
181
|
+
Or tell an agent: "Create a Google Meet, join it with the agent talk-back mode,
|
|
182
|
+
and send me the link." The agent should call `google_meet` with
|
|
183
|
+
`action: "create"` and then share the returned `meetingUri`.
|
|
184
|
+
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"action": "create",
|
|
188
|
+
"transport": "chrome-node",
|
|
189
|
+
"mode": "agent"
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
For an observe-only/browser-control join, set `"mode": "transcribe"`. That does
|
|
194
|
+
not start the duplex realtime voice bridge, does not require BlackHole or SoX,
|
|
195
|
+
and will not talk back into the meeting. Chrome joins in this mode also avoid
|
|
196
|
+
Nodmix's microphone/camera permission grant and avoid the Meet **Use
|
|
197
|
+
microphone** path. If Meet shows an audio-choice interstitial, automation tries
|
|
198
|
+
the no-microphone path and otherwise reports a manual action instead of opening
|
|
199
|
+
the local microphone. In transcribe mode, managed Chrome transports also install
|
|
200
|
+
a best-effort Meet caption observer. `googlemeet status --json` and
|
|
201
|
+
`googlemeet doctor` surface `captioning`, `captionsEnabledAttempted`,
|
|
202
|
+
`transcriptLines`, `lastCaptionAt`, `lastCaptionSpeaker`, `lastCaptionText`,
|
|
203
|
+
and a short `recentTranscript` tail so operators can tell whether the browser
|
|
204
|
+
joined the call and whether Meet captions are producing text.
|
|
205
|
+
Use `nodmix googlemeet test-listen <meet-url> --transport chrome-node` when
|
|
206
|
+
you need a yes/no probe: it joins in transcribe mode, waits for fresh caption or
|
|
207
|
+
transcript movement, and returns `listenVerified`, `listenTimedOut`, manual
|
|
208
|
+
action fields, and the latest caption health.
|
|
209
|
+
|
|
210
|
+
During realtime sessions, `google_meet` status includes browser and audio bridge
|
|
211
|
+
health such as `inCall`, `manualActionRequired`, `providerConnected`,
|
|
212
|
+
`realtimeReady`, `audioInputActive`, `audioOutputActive`, last input/output
|
|
213
|
+
timestamps, byte counters, and bridge closed state. If a safe Meet page prompt
|
|
214
|
+
appears, browser automation handles it when it can. Login, host admission, and
|
|
215
|
+
browser/OS permission prompts are reported as manual action with a reason and
|
|
216
|
+
message for the agent to relay. Managed Chrome sessions only emit the intro or
|
|
217
|
+
test phrase after browser health reports `inCall: true`; otherwise status reports
|
|
218
|
+
`speechReady: false` and the speech attempt is blocked instead of pretending the
|
|
219
|
+
agent spoke into the meeting.
|
|
220
|
+
|
|
221
|
+
Local Chrome joins through the signed-in Nodmix browser profile. Realtime mode
|
|
222
|
+
requires `BlackHole 2ch` for the microphone/speaker path used by Nodmix. For
|
|
223
|
+
clean duplex audio, use separate virtual devices or a Loopback-style graph; a
|
|
224
|
+
single BlackHole device is enough for a first smoke test but can echo.
|
|
225
|
+
|
|
226
|
+
### Local gateway + Parallels Chrome
|
|
227
|
+
|
|
228
|
+
You do **not** need a full Nodmix Gateway or model API key inside a macOS VM
|
|
229
|
+
just to make the VM own Chrome. Run the Gateway and agent locally, then run a
|
|
230
|
+
node host in the VM. Enable the bundled plugin on the VM once so the node
|
|
231
|
+
advertises the Chrome command:
|
|
232
|
+
|
|
233
|
+
What runs where:
|
|
234
|
+
|
|
235
|
+
- Gateway host: Nodmix Gateway, agent workspace, model/API keys, realtime
|
|
236
|
+
provider, and the Google Meet plugin config.
|
|
237
|
+
- Parallels macOS VM: Nodmix CLI/node host, Google Chrome, SoX, BlackHole 2ch,
|
|
238
|
+
and a Chrome profile signed in to Google.
|
|
239
|
+
- Not needed in the VM: Gateway service, agent config, OpenAI/GPT key, or model
|
|
240
|
+
provider setup.
|
|
241
|
+
|
|
242
|
+
Install the VM dependencies:
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
brew install blackhole-2ch sox
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Reboot the VM after installing BlackHole so macOS exposes `BlackHole 2ch`:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
sudo reboot
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
After reboot, verify the VM can see the audio device and SoX commands:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
system_profiler SPAudioDataType | grep -i BlackHole
|
|
258
|
+
command -v sox
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Install or update Nodmix in the VM, then enable the bundled plugin there:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
nodmix plugins enable google-meet
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Start the node host in the VM:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
nodmix node run --host <gateway-host> --port 18789 --display-name parallels-macos
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
If `<gateway-host>` is a LAN IP and you are not using TLS, the node refuses the
|
|
274
|
+
plaintext WebSocket unless you opt in for that trusted private network:
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
NODMIX_ALLOW_INSECURE_PRIVATE_WS=1 \
|
|
278
|
+
nodmix node run --host <gateway-lan-ip> --port 18789 --display-name parallels-macos
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Use the same environment variable when installing the node as a LaunchAgent:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
NODMIX_ALLOW_INSECURE_PRIVATE_WS=1 \
|
|
285
|
+
nodmix node install --host <gateway-lan-ip> --port 18789 --display-name parallels-macos --force
|
|
286
|
+
nodmix node restart
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
`NODMIX_ALLOW_INSECURE_PRIVATE_WS=1` is process environment, not an
|
|
290
|
+
`nodmix.json` setting. `nodmix node install` stores it in the LaunchAgent
|
|
291
|
+
environment when it is present on the install command.
|
|
292
|
+
|
|
293
|
+
Approve the node from the Gateway host:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
nodmix devices list
|
|
297
|
+
nodmix devices approve <requestId>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Confirm the Gateway sees the node and that it advertises both `googlemeet.chrome`
|
|
301
|
+
and browser capability/`browser.proxy`:
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
nodmix nodes status
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Route Meet through that node on the Gateway host:
|
|
308
|
+
|
|
309
|
+
```json5
|
|
310
|
+
{
|
|
311
|
+
gateway: {
|
|
312
|
+
nodes: {
|
|
313
|
+
allowCommands: ["googlemeet.chrome", "browser.proxy"],
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
plugins: {
|
|
317
|
+
entries: {
|
|
318
|
+
"google-meet": {
|
|
319
|
+
enabled: true,
|
|
320
|
+
config: {
|
|
321
|
+
defaultTransport: "chrome-node",
|
|
322
|
+
chrome: {
|
|
323
|
+
guestName: "Nodmix Agent",
|
|
324
|
+
autoJoin: true,
|
|
325
|
+
reuseExistingTab: true,
|
|
326
|
+
},
|
|
327
|
+
chromeNode: {
|
|
328
|
+
node: "parallels-macos",
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Now join normally from the Gateway host:
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
nodmix googlemeet join https://meet.google.com/abc-defg-hij
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
or ask the agent to use the `google_meet` tool with `transport: "chrome-node"`.
|
|
344
|
+
|
|
345
|
+
For a one-command smoke test that creates or reuses a session, speaks a known
|
|
346
|
+
phrase, and prints session health:
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
nodmix googlemeet test-speech https://meet.google.com/abc-defg-hij
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
During realtime join, Nodmix browser automation fills the guest name, clicks
|
|
353
|
+
Join/Ask to join, and accepts Meet's first-run "Use microphone" choice when that
|
|
354
|
+
prompt appears. During observe-only join or browser-only meeting creation, it
|
|
355
|
+
continues past the same prompt without microphone when that choice is available.
|
|
356
|
+
If the browser profile is not signed in, Meet is waiting for host admission,
|
|
357
|
+
Chrome needs microphone/camera permission for a realtime join, or Meet is stuck
|
|
358
|
+
on a prompt automation could not resolve, the join/test-speech result reports
|
|
359
|
+
`manualActionRequired: true` with `manualActionReason` and
|
|
360
|
+
`manualActionMessage`. Agents should stop retrying the join, report that exact
|
|
361
|
+
message plus the current `browserUrl`/`browserTitle`, and retry only after the
|
|
362
|
+
manual browser action is complete.
|
|
363
|
+
|
|
364
|
+
If `chromeNode.node` is omitted, Nodmix auto-selects only when exactly one
|
|
365
|
+
connected node advertises both `googlemeet.chrome` and browser control. If
|
|
366
|
+
several capable nodes are connected, set `chromeNode.node` to the node id,
|
|
367
|
+
display name, or remote IP.
|
|
368
|
+
|
|
369
|
+
Common failure checks:
|
|
370
|
+
|
|
371
|
+
- `Configured Google Meet node ... is not usable: offline`: the pinned node is
|
|
372
|
+
known to the Gateway but unavailable. Agents should treat that node as
|
|
373
|
+
diagnostic state, not as a usable Chrome host, and report the setup blocker
|
|
374
|
+
instead of falling back to another transport unless the user asked for that.
|
|
375
|
+
- `No connected Google Meet-capable node`: start `nodmix node run` in the VM,
|
|
376
|
+
approve pairing, and make sure `nodmix plugins enable google-meet` and
|
|
377
|
+
`nodmix plugins enable browser` were run in the VM. Also confirm the
|
|
378
|
+
Gateway host allows both node commands with
|
|
379
|
+
`gateway.nodes.allowCommands: ["googlemeet.chrome", "browser.proxy"]`.
|
|
380
|
+
- `BlackHole 2ch audio device not found`: install `blackhole-2ch` on the host
|
|
381
|
+
being checked and reboot before using local Chrome audio.
|
|
382
|
+
- `BlackHole 2ch audio device not found on the node`: install `blackhole-2ch`
|
|
383
|
+
in the VM and reboot the VM.
|
|
384
|
+
- Chrome opens but cannot join: sign in to the browser profile inside the VM, or
|
|
385
|
+
keep `chrome.guestName` set for guest join. Guest auto-join uses Nodmix
|
|
386
|
+
browser automation through the node browser proxy; make sure the node browser
|
|
387
|
+
config points at the profile you want, for example
|
|
388
|
+
`browser.defaultProfile: "user"` or a named existing-session profile.
|
|
389
|
+
- Duplicate Meet tabs: leave `chrome.reuseExistingTab: true` enabled. Nodmix
|
|
390
|
+
activates an existing tab for the same Meet URL before opening a new one, and
|
|
391
|
+
browser meeting creation reuses an in-progress `https://meet.google.com/new`
|
|
392
|
+
or Google account prompt tab before opening another one.
|
|
393
|
+
- No audio: in Meet, route microphone/speaker through the virtual audio device
|
|
394
|
+
path used by Nodmix; use separate virtual devices or Loopback-style routing
|
|
395
|
+
for clean duplex audio.
|
|
396
|
+
|
|
397
|
+
## Install notes
|
|
398
|
+
|
|
399
|
+
The Chrome talk-back default uses two external tools:
|
|
400
|
+
|
|
401
|
+
- `sox`: command-line audio utility. The plugin uses explicit CoreAudio
|
|
402
|
+
device commands for the default 24 kHz PCM16 audio bridge.
|
|
403
|
+
- `blackhole-2ch`: macOS virtual audio driver. It creates the `BlackHole 2ch`
|
|
404
|
+
audio device that Chrome/Meet can route through.
|
|
405
|
+
|
|
406
|
+
Nodmix does not bundle or redistribute either package. The docs ask users to
|
|
407
|
+
install them as host dependencies through Homebrew. SoX is licensed as
|
|
408
|
+
`LGPL-2.0-only AND GPL-2.0-only`; BlackHole is GPL-3.0. If you build an
|
|
409
|
+
installer or appliance that bundles BlackHole with Nodmix, review BlackHole's
|
|
410
|
+
upstream licensing terms or get a separate license from Existential Audio.
|
|
411
|
+
|
|
412
|
+
## Transports
|
|
413
|
+
|
|
414
|
+
### Chrome
|
|
415
|
+
|
|
416
|
+
Chrome transport opens the Meet URL through Nodmix browser control and joins
|
|
417
|
+
as the signed-in Nodmix browser profile. On macOS, the plugin checks for
|
|
418
|
+
`BlackHole 2ch` before launch. If configured, it also runs an audio bridge
|
|
419
|
+
health command and startup command before opening Chrome. Use `chrome` when
|
|
420
|
+
Chrome/audio live on the Gateway host; use `chrome-node` when Chrome/audio live
|
|
421
|
+
on a paired node such as a Parallels macOS VM. For local Chrome, choose the
|
|
422
|
+
profile with `browser.defaultProfile`; `chrome.browserProfile` is passed to
|
|
423
|
+
`chrome-node` hosts.
|
|
424
|
+
|
|
425
|
+
```bash
|
|
426
|
+
nodmix googlemeet join https://meet.google.com/abc-defg-hij --transport chrome
|
|
427
|
+
nodmix googlemeet join https://meet.google.com/abc-defg-hij --transport chrome-node
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Route Chrome microphone and speaker audio through the local Nodmix audio
|
|
431
|
+
bridge. If `BlackHole 2ch` is not installed, the join fails with a setup error
|
|
432
|
+
instead of silently joining without an audio path.
|
|
433
|
+
|
|
434
|
+
### Twilio
|
|
435
|
+
|
|
436
|
+
Twilio transport is a strict dial plan delegated to the Voice Call plugin. It
|
|
437
|
+
does not parse Meet pages for phone numbers.
|
|
438
|
+
|
|
439
|
+
Use this when Chrome participation is not available or you want a phone dial-in
|
|
440
|
+
fallback. Google Meet must expose a phone dial-in number and PIN for the
|
|
441
|
+
meeting; Nodmix does not discover those from the Meet page.
|
|
442
|
+
|
|
443
|
+
Enable the Voice Call plugin on the Gateway host, not on the Chrome node:
|
|
444
|
+
|
|
445
|
+
```json5
|
|
446
|
+
{
|
|
447
|
+
plugins: {
|
|
448
|
+
allow: ["google-meet", "voice-call", "google"],
|
|
449
|
+
entries: {
|
|
450
|
+
"google-meet": {
|
|
451
|
+
enabled: true,
|
|
452
|
+
config: {
|
|
453
|
+
defaultTransport: "chrome-node",
|
|
454
|
+
// or set "twilio" if Twilio should be the default
|
|
455
|
+
},
|
|
456
|
+
},
|
|
457
|
+
"voice-call": {
|
|
458
|
+
enabled: true,
|
|
459
|
+
config: {
|
|
460
|
+
provider: "twilio",
|
|
461
|
+
inboundPolicy: "allowlist",
|
|
462
|
+
realtime: {
|
|
463
|
+
enabled: true,
|
|
464
|
+
provider: "google",
|
|
465
|
+
instructions: "Join this Google Meet as an Nodmix agent. Be brief.",
|
|
466
|
+
toolPolicy: "safe-read-only",
|
|
467
|
+
providers: {
|
|
468
|
+
google: {
|
|
469
|
+
silenceDurationMs: 500,
|
|
470
|
+
startSensitivity: "high",
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
google: {
|
|
477
|
+
enabled: true,
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
Provide Twilio credentials through environment or config. Environment keeps
|
|
485
|
+
secrets out of `nodmix.json`:
|
|
486
|
+
|
|
487
|
+
```bash
|
|
488
|
+
export TWILIO_ACCOUNT_SID=AC...
|
|
489
|
+
export TWILIO_AUTH_TOKEN=...
|
|
490
|
+
export TWILIO_FROM_NUMBER=+15550001234
|
|
491
|
+
export GEMINI_API_KEY=...
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
Use `realtime.provider: "openai"` with the OpenAI provider plugin and
|
|
495
|
+
`OPENAI_API_KEY` instead if that is your realtime voice provider.
|
|
496
|
+
|
|
497
|
+
Restart or reload the Gateway after enabling `voice-call`; plugin config changes
|
|
498
|
+
do not appear in an already running Gateway process until it reloads.
|
|
499
|
+
|
|
500
|
+
Then verify:
|
|
501
|
+
|
|
502
|
+
```bash
|
|
503
|
+
nodmix config validate
|
|
504
|
+
nodmix plugins list | grep -E 'google-meet|voice-call'
|
|
505
|
+
nodmix googlemeet setup
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
When Twilio delegation is wired, `googlemeet setup` includes successful
|
|
509
|
+
`twilio-voice-call-plugin`, `twilio-voice-call-credentials`, and
|
|
510
|
+
`twilio-voice-call-webhook` checks.
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
nodmix googlemeet join https://meet.google.com/abc-defg-hij \
|
|
514
|
+
--transport twilio \
|
|
515
|
+
--dial-in-number +15551234567 \
|
|
516
|
+
--pin 123456
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
Use `--dtmf-sequence` when the meeting needs a custom sequence:
|
|
520
|
+
|
|
521
|
+
```bash
|
|
522
|
+
nodmix googlemeet join https://meet.google.com/abc-defg-hij \
|
|
523
|
+
--transport twilio \
|
|
524
|
+
--dial-in-number +15551234567 \
|
|
525
|
+
--dtmf-sequence ww123456#
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
## OAuth and preflight
|
|
529
|
+
|
|
530
|
+
OAuth is optional for creating a Meet link because `googlemeet create` can fall
|
|
531
|
+
back to browser automation. Configure OAuth when you want official API create,
|
|
532
|
+
space resolution, or Meet Media API preflight checks.
|
|
533
|
+
|
|
534
|
+
Google Meet API access uses user OAuth: create a Google Cloud OAuth client,
|
|
535
|
+
request the required scopes, authorize a Google account, then store the
|
|
536
|
+
resulting refresh token in the Google Meet plugin config or provide the
|
|
537
|
+
`NODMIX_GOOGLE_MEET_*` environment variables.
|
|
538
|
+
|
|
539
|
+
OAuth does not replace the Chrome join path. Chrome and Chrome-node transports
|
|
540
|
+
still join through a signed-in Chrome profile, BlackHole/SoX, and a connected
|
|
541
|
+
node when you use browser participation. OAuth is only for the official Google
|
|
542
|
+
Meet API path: create meeting spaces, resolve spaces, and run Meet Media API
|
|
543
|
+
preflight checks.
|
|
544
|
+
|
|
545
|
+
### Create Google credentials
|
|
546
|
+
|
|
547
|
+
In Google Cloud Console:
|
|
548
|
+
|
|
549
|
+
1. Create or select a Google Cloud project.
|
|
550
|
+
2. Enable **Google Meet REST API** for that project.
|
|
551
|
+
3. Configure the OAuth consent screen.
|
|
552
|
+
- **Internal** is simplest for a Google Workspace organization.
|
|
553
|
+
- **External** works for personal/test setups; while the app is in Testing,
|
|
554
|
+
add each Google account that will authorize the app as a test user.
|
|
555
|
+
4. Add the scopes Nodmix requests:
|
|
556
|
+
- `https://www.googleapis.com/auth/meetings.space.created`
|
|
557
|
+
- `https://www.googleapis.com/auth/meetings.space.readonly`
|
|
558
|
+
- `https://www.googleapis.com/auth/meetings.space.settings`
|
|
559
|
+
- `https://www.googleapis.com/auth/meetings.conference.media.readonly`
|
|
560
|
+
5. Create an OAuth client ID.
|
|
561
|
+
- Application type: **Web application**.
|
|
562
|
+
- Authorized redirect URI:
|
|
563
|
+
|
|
564
|
+
```text
|
|
565
|
+
http://localhost:8085/oauth2callback
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
6. Copy the client ID and client secret.
|
|
569
|
+
|
|
570
|
+
`meetings.space.created` is required by Google Meet `spaces.create`.
|
|
571
|
+
`meetings.space.readonly` lets Nodmix resolve Meet URLs/codes to spaces.
|
|
572
|
+
`meetings.space.settings` lets Nodmix pass `SpaceConfig` settings such as
|
|
573
|
+
`accessType` during API room creation.
|
|
574
|
+
`meetings.conference.media.readonly` is for Meet Media API preflight and media
|
|
575
|
+
work; Google may require Developer Preview enrollment for actual Media API use.
|
|
576
|
+
If you only need browser-based Chrome joins, skip OAuth entirely.
|
|
577
|
+
|
|
578
|
+
### Mint the refresh token
|
|
579
|
+
|
|
580
|
+
Configure `oauth.clientId` and optionally `oauth.clientSecret`, or pass them as
|
|
581
|
+
environment variables, then run:
|
|
582
|
+
|
|
583
|
+
```bash
|
|
584
|
+
nodmix googlemeet auth login --json
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
The command prints an `oauth` config block with a refresh token. It uses PKCE,
|
|
588
|
+
localhost callback on `http://localhost:8085/oauth2callback`, and a manual
|
|
589
|
+
copy/paste flow with `--manual`.
|
|
590
|
+
|
|
591
|
+
Examples:
|
|
592
|
+
|
|
593
|
+
```bash
|
|
594
|
+
NODMIX_GOOGLE_MEET_CLIENT_ID="your-client-id" \
|
|
595
|
+
NODMIX_GOOGLE_MEET_CLIENT_SECRET="your-client-secret" \
|
|
596
|
+
nodmix googlemeet auth login --json
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
Use manual mode when the browser cannot reach the local callback:
|
|
600
|
+
|
|
601
|
+
```bash
|
|
602
|
+
NODMIX_GOOGLE_MEET_CLIENT_ID="your-client-id" \
|
|
603
|
+
NODMIX_GOOGLE_MEET_CLIENT_SECRET="your-client-secret" \
|
|
604
|
+
nodmix googlemeet auth login --json --manual
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
The JSON output includes:
|
|
608
|
+
|
|
609
|
+
```json
|
|
610
|
+
{
|
|
611
|
+
"oauth": {
|
|
612
|
+
"clientId": "your-client-id",
|
|
613
|
+
"clientSecret": "your-client-secret",
|
|
614
|
+
"refreshToken": "refresh-token",
|
|
615
|
+
"accessToken": "access-token",
|
|
616
|
+
"expiresAt": 1770000000000
|
|
617
|
+
},
|
|
618
|
+
"scope": "..."
|
|
619
|
+
}
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
Store the `oauth` object under the Google Meet plugin config:
|
|
623
|
+
|
|
624
|
+
```json5
|
|
625
|
+
{
|
|
626
|
+
plugins: {
|
|
627
|
+
entries: {
|
|
628
|
+
"google-meet": {
|
|
629
|
+
enabled: true,
|
|
630
|
+
config: {
|
|
631
|
+
oauth: {
|
|
632
|
+
clientId: "your-client-id",
|
|
633
|
+
clientSecret: "your-client-secret",
|
|
634
|
+
refreshToken: "refresh-token",
|
|
635
|
+
},
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
},
|
|
639
|
+
},
|
|
640
|
+
}
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
Prefer environment variables when you do not want the refresh token in config.
|
|
644
|
+
If both config and environment values are present, the plugin resolves config
|
|
645
|
+
first and then environment fallback.
|
|
646
|
+
|
|
647
|
+
The OAuth consent includes Meet space creation, Meet space read access, and Meet
|
|
648
|
+
conference media read access. If you authenticated before meeting creation
|
|
649
|
+
support existed, rerun `nodmix googlemeet auth login --json` so the refresh
|
|
650
|
+
token has the `meetings.space.created` scope.
|
|
651
|
+
|
|
652
|
+
### Verify OAuth with doctor
|
|
653
|
+
|
|
654
|
+
Run the OAuth doctor when you want a fast, non-secret health check:
|
|
655
|
+
|
|
656
|
+
```bash
|
|
657
|
+
nodmix googlemeet doctor --oauth --json
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
This does not load the Chrome runtime or require a connected Chrome node. It
|
|
661
|
+
checks that OAuth config exists and that the refresh token can mint an access
|
|
662
|
+
token. The JSON report includes only status fields such as `ok`, `configured`,
|
|
663
|
+
`tokenSource`, `expiresAt`, and check messages; it does not print the access
|
|
664
|
+
token, refresh token, or client secret.
|
|
665
|
+
|
|
666
|
+
Common results:
|
|
667
|
+
|
|
668
|
+
| Check | Meaning |
|
|
669
|
+
| -------------------- | --------------------------------------------------------------------------------------- |
|
|
670
|
+
| `oauth-config` | `oauth.clientId` plus `oauth.refreshToken`, or a cached access token, is present. |
|
|
671
|
+
| `oauth-token` | The cached access token is still valid, or the refresh token minted a new access token. |
|
|
672
|
+
| `meet-spaces-get` | Optional `--meeting` check resolved an existing Meet space. |
|
|
673
|
+
| `meet-spaces-create` | Optional `--create-space` check created a new Meet space. |
|
|
674
|
+
|
|
675
|
+
To prove Google Meet API enablement and `spaces.create` scope as well, run the
|
|
676
|
+
side-effecting create check:
|
|
677
|
+
|
|
678
|
+
```bash
|
|
679
|
+
nodmix googlemeet doctor --oauth --create-space --json
|
|
680
|
+
nodmix googlemeet create --no-join --json
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
`--create-space` creates a throwaway Meet URL. Use it when you need to confirm
|
|
684
|
+
that the Google Cloud project has the Meet API enabled and that the authorized
|
|
685
|
+
account has the `meetings.space.created` scope.
|
|
686
|
+
|
|
687
|
+
To prove read access for an existing meeting space:
|
|
688
|
+
|
|
689
|
+
```bash
|
|
690
|
+
nodmix googlemeet doctor --oauth --meeting https://meet.google.com/abc-defg-hij --json
|
|
691
|
+
nodmix googlemeet resolve-space --meeting https://meet.google.com/abc-defg-hij
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
`doctor --oauth --meeting` and `resolve-space` prove read access to an existing
|
|
695
|
+
space that the authorized Google account can access. A `403` from these checks
|
|
696
|
+
usually means the Google Meet REST API is disabled, the consented refresh token
|
|
697
|
+
is missing the required scope, or the Google account cannot access that Meet
|
|
698
|
+
space. A refresh-token error means rerun `nodmix googlemeet auth login
|
|
699
|
+
--json` and store the new `oauth` block.
|
|
700
|
+
|
|
701
|
+
No OAuth credentials are needed for the browser fallback. In that mode, Google
|
|
702
|
+
auth comes from the signed-in Chrome profile on the selected node, not from
|
|
703
|
+
Nodmix config.
|
|
704
|
+
|
|
705
|
+
These environment variables are accepted as fallbacks:
|
|
706
|
+
|
|
707
|
+
- `NODMIX_GOOGLE_MEET_CLIENT_ID` or `GOOGLE_MEET_CLIENT_ID`
|
|
708
|
+
- `NODMIX_GOOGLE_MEET_CLIENT_SECRET` or `GOOGLE_MEET_CLIENT_SECRET`
|
|
709
|
+
- `NODMIX_GOOGLE_MEET_REFRESH_TOKEN` or `GOOGLE_MEET_REFRESH_TOKEN`
|
|
710
|
+
- `NODMIX_GOOGLE_MEET_ACCESS_TOKEN` or `GOOGLE_MEET_ACCESS_TOKEN`
|
|
711
|
+
- `NODMIX_GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT` or
|
|
712
|
+
`GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT`
|
|
713
|
+
- `NODMIX_GOOGLE_MEET_DEFAULT_MEETING` or `GOOGLE_MEET_DEFAULT_MEETING`
|
|
714
|
+
- `NODMIX_GOOGLE_MEET_PREVIEW_ACK` or `GOOGLE_MEET_PREVIEW_ACK`
|
|
715
|
+
|
|
716
|
+
Resolve a Meet URL, code, or `spaces/{id}` through `spaces.get`:
|
|
717
|
+
|
|
718
|
+
```bash
|
|
719
|
+
nodmix googlemeet resolve-space --meeting https://meet.google.com/abc-defg-hij
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
Run preflight before media work:
|
|
723
|
+
|
|
724
|
+
```bash
|
|
725
|
+
nodmix googlemeet preflight --meeting https://meet.google.com/abc-defg-hij
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
List meeting artifacts and attendance after Meet has created conference records:
|
|
729
|
+
|
|
730
|
+
```bash
|
|
731
|
+
nodmix googlemeet artifacts --meeting https://meet.google.com/abc-defg-hij
|
|
732
|
+
nodmix googlemeet attendance --meeting https://meet.google.com/abc-defg-hij
|
|
733
|
+
nodmix googlemeet export --meeting https://meet.google.com/abc-defg-hij --output ./meet-export
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
With `--meeting`, `artifacts` and `attendance` use the latest conference record
|
|
737
|
+
by default. Pass `--all-conference-records` when you want every retained record
|
|
738
|
+
for that meeting.
|
|
739
|
+
|
|
740
|
+
Calendar lookup can resolve the meeting URL from Google Calendar before reading
|
|
741
|
+
Meet artifacts:
|
|
742
|
+
|
|
743
|
+
```bash
|
|
744
|
+
nodmix googlemeet latest --today
|
|
745
|
+
nodmix googlemeet calendar-events --today --json
|
|
746
|
+
nodmix googlemeet artifacts --event "Weekly sync"
|
|
747
|
+
nodmix googlemeet attendance --today --format csv --output attendance.csv
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
`--today` searches today's `primary` calendar for a Calendar event with a
|
|
751
|
+
Google Meet link. Use `--event <query>` to search matching event text, and
|
|
752
|
+
`--calendar <id>` for a non-primary calendar. Calendar lookup requires a fresh
|
|
753
|
+
OAuth login that includes the Calendar events readonly scope.
|
|
754
|
+
`calendar-events` previews the matching Meet events and marks the event that
|
|
755
|
+
`latest`, `artifacts`, `attendance`, or `export` will choose.
|
|
756
|
+
|
|
757
|
+
If you already know the conference record id, address it directly:
|
|
758
|
+
|
|
759
|
+
```bash
|
|
760
|
+
nodmix googlemeet latest --meeting https://meet.google.com/abc-defg-hij
|
|
761
|
+
nodmix googlemeet artifacts --conference-record conferenceRecords/abc123 --json
|
|
762
|
+
nodmix googlemeet attendance --conference-record conferenceRecords/abc123 --json
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
End an active conference for an API-created space when you want to close the
|
|
766
|
+
room after the call:
|
|
767
|
+
|
|
768
|
+
```bash
|
|
769
|
+
nodmix googlemeet end-active-conference https://meet.google.com/abc-defg-hij
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
This calls Google Meet `spaces.endActiveConference` and requires OAuth with the
|
|
773
|
+
`meetings.space.created` scope for a space the authorized account can manage.
|
|
774
|
+
Nodmix accepts a Meet URL, meeting code, or `spaces/{id}` input and resolves it
|
|
775
|
+
to the API space resource before ending the active conference.
|
|
776
|
+
It is separate from `googlemeet leave`: `leave` stops Nodmix's local/session
|
|
777
|
+
participation, while `end-active-conference` asks Google Meet to end the active
|
|
778
|
+
conference for the space.
|
|
779
|
+
|
|
780
|
+
Write a readable report:
|
|
781
|
+
|
|
782
|
+
```bash
|
|
783
|
+
nodmix googlemeet artifacts --conference-record conferenceRecords/abc123 \
|
|
784
|
+
--format markdown --output meet-artifacts.md
|
|
785
|
+
nodmix googlemeet attendance --conference-record conferenceRecords/abc123 \
|
|
786
|
+
--format markdown --output meet-attendance.md
|
|
787
|
+
nodmix googlemeet attendance --conference-record conferenceRecords/abc123 \
|
|
788
|
+
--format csv --output meet-attendance.csv
|
|
789
|
+
nodmix googlemeet export --conference-record conferenceRecords/abc123 \
|
|
790
|
+
--include-doc-bodies --zip --output meet-export
|
|
791
|
+
nodmix googlemeet export --conference-record conferenceRecords/abc123 \
|
|
792
|
+
--include-doc-bodies --dry-run
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
`artifacts` returns conference record metadata plus participant, recording,
|
|
796
|
+
transcript, structured transcript-entry, and smart-note resource metadata when
|
|
797
|
+
Google exposes it for the meeting. Use `--no-transcript-entries` to skip
|
|
798
|
+
entry lookup for large meetings. `attendance` expands participants into
|
|
799
|
+
participant-session rows with first/last seen times, total session duration,
|
|
800
|
+
late/early-leave flags, and duplicate participant resources merged by signed-in
|
|
801
|
+
user or display name. Pass `--no-merge-duplicates` to keep raw participant
|
|
802
|
+
resources separate, `--late-after-minutes` to tune late detection, and
|
|
803
|
+
`--early-before-minutes` to tune early-leave detection.
|
|
804
|
+
|
|
805
|
+
`export` writes a folder containing `summary.md`, `attendance.csv`,
|
|
806
|
+
`transcript.md`, `artifacts.json`, `attendance.json`, and `manifest.json`.
|
|
807
|
+
`manifest.json` records the chosen input, export options, conference records,
|
|
808
|
+
output files, counts, token source, Calendar event when one was used, and any
|
|
809
|
+
partial retrieval warnings. Pass `--zip` to also write a portable archive next
|
|
810
|
+
to the folder. Pass `--include-doc-bodies` to export linked transcript and
|
|
811
|
+
smart-note Google Docs text through Google Drive `files.export`; this requires a
|
|
812
|
+
fresh OAuth login that includes the Drive Meet readonly scope. Without
|
|
813
|
+
`--include-doc-bodies`, exports include Meet metadata and structured transcript
|
|
814
|
+
entries only. If Google returns a partial artifact failure, such as a smart-note
|
|
815
|
+
listing, transcript-entry, or Drive document-body error, the summary and
|
|
816
|
+
manifest keep the warning instead of failing the whole export.
|
|
817
|
+
Use `--dry-run` to fetch the same artifact/attendance data and print the
|
|
818
|
+
manifest JSON without creating the folder or ZIP. That is useful before writing
|
|
819
|
+
a large export or when an agent only needs counts, selected records, and
|
|
820
|
+
warnings.
|
|
821
|
+
|
|
822
|
+
Agents can also create the same bundle through the `google_meet` tool:
|
|
823
|
+
|
|
824
|
+
```json
|
|
825
|
+
{
|
|
826
|
+
"action": "export",
|
|
827
|
+
"conferenceRecord": "conferenceRecords/abc123",
|
|
828
|
+
"includeDocumentBodies": true,
|
|
829
|
+
"outputDir": "meet-export",
|
|
830
|
+
"zip": true
|
|
831
|
+
}
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
Set `"dryRun": true` to return only the export manifest and skip file writes.
|
|
835
|
+
|
|
836
|
+
Agents can also create an API-backed room with an explicit access policy:
|
|
837
|
+
|
|
838
|
+
```json
|
|
839
|
+
{
|
|
840
|
+
"action": "create",
|
|
841
|
+
"transport": "chrome-node",
|
|
842
|
+
"mode": "agent",
|
|
843
|
+
"accessType": "OPEN"
|
|
844
|
+
}
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
And they can end the active conference for a known room:
|
|
848
|
+
|
|
849
|
+
```json
|
|
850
|
+
{
|
|
851
|
+
"action": "end_active_conference",
|
|
852
|
+
"meeting": "https://meet.google.com/abc-defg-hij"
|
|
853
|
+
}
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
For listen-first validation, agents should use `test_listen` before claiming the
|
|
857
|
+
meeting is useful:
|
|
858
|
+
|
|
859
|
+
```json
|
|
860
|
+
{
|
|
861
|
+
"action": "test_listen",
|
|
862
|
+
"url": "https://meet.google.com/abc-defg-hij",
|
|
863
|
+
"transport": "chrome-node",
|
|
864
|
+
"timeoutMs": 30000
|
|
865
|
+
}
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
Run the guarded live smoke against a real retained meeting:
|
|
869
|
+
|
|
870
|
+
```bash
|
|
871
|
+
NODMIX_LIVE_TEST=1 \
|
|
872
|
+
NODMIX_GOOGLE_MEET_LIVE_MEETING=https://meet.google.com/abc-defg-hij \
|
|
873
|
+
pnpm test:live -- extensions/google-meet/google-meet.live.test.ts
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
Run the live listen-first browser probe against a meeting where someone will
|
|
877
|
+
speak with Meet captions available:
|
|
878
|
+
|
|
879
|
+
```bash
|
|
880
|
+
nodmix googlemeet setup --transport chrome-node --mode transcribe
|
|
881
|
+
nodmix googlemeet test-listen https://meet.google.com/abc-defg-hij --transport chrome-node --timeout-ms 30000
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
Live smoke environment:
|
|
885
|
+
|
|
886
|
+
- `NODMIX_LIVE_TEST=1` enables guarded live tests.
|
|
887
|
+
- `NODMIX_GOOGLE_MEET_LIVE_MEETING` points at a retained Meet URL, code, or
|
|
888
|
+
`spaces/{id}`.
|
|
889
|
+
- `NODMIX_GOOGLE_MEET_CLIENT_ID` or `GOOGLE_MEET_CLIENT_ID` provides the OAuth
|
|
890
|
+
client id.
|
|
891
|
+
- `NODMIX_GOOGLE_MEET_REFRESH_TOKEN` or `GOOGLE_MEET_REFRESH_TOKEN` provides
|
|
892
|
+
the refresh token.
|
|
893
|
+
- Optional: `NODMIX_GOOGLE_MEET_CLIENT_SECRET`,
|
|
894
|
+
`NODMIX_GOOGLE_MEET_ACCESS_TOKEN`, and
|
|
895
|
+
`NODMIX_GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT` use the same fallback names
|
|
896
|
+
without the `NODMIX_` prefix.
|
|
897
|
+
|
|
898
|
+
The base artifact/attendance live smoke needs
|
|
899
|
+
`https://www.googleapis.com/auth/meetings.space.readonly` and
|
|
900
|
+
`https://www.googleapis.com/auth/meetings.conference.media.readonly`. Calendar
|
|
901
|
+
lookup needs `https://www.googleapis.com/auth/calendar.events.readonly`. Drive
|
|
902
|
+
document-body export needs
|
|
903
|
+
`https://www.googleapis.com/auth/drive.meet.readonly`.
|
|
904
|
+
|
|
905
|
+
Create a fresh Meet space:
|
|
906
|
+
|
|
907
|
+
```bash
|
|
908
|
+
nodmix googlemeet create
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
The command prints the new `meeting uri`, source, and join session. With OAuth
|
|
912
|
+
credentials it uses the official Google Meet API. Without OAuth credentials it
|
|
913
|
+
uses the pinned Chrome node's signed-in browser profile as a fallback. Agents can
|
|
914
|
+
use the `google_meet` tool with `action: "create"` to create and join in one
|
|
915
|
+
step. For URL-only creation, pass `"join": false`.
|
|
916
|
+
|
|
917
|
+
Example JSON output from the browser fallback:
|
|
918
|
+
|
|
919
|
+
```json
|
|
920
|
+
{
|
|
921
|
+
"source": "browser",
|
|
922
|
+
"meetingUri": "https://meet.google.com/abc-defg-hij",
|
|
923
|
+
"joined": true,
|
|
924
|
+
"browser": {
|
|
925
|
+
"nodeId": "ba0f4e4bc...",
|
|
926
|
+
"targetId": "tab-1"
|
|
927
|
+
},
|
|
928
|
+
"join": {
|
|
929
|
+
"session": {
|
|
930
|
+
"id": "meet_...",
|
|
931
|
+
"url": "https://meet.google.com/abc-defg-hij"
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
```
|
|
936
|
+
|
|
937
|
+
If the browser fallback hits Google login or a Meet permission blocker before it
|
|
938
|
+
can create the URL, the Gateway method returns a failed response and the
|
|
939
|
+
`google_meet` tool returns structured details instead of a plain string:
|
|
940
|
+
|
|
941
|
+
```json
|
|
942
|
+
{
|
|
943
|
+
"source": "browser",
|
|
944
|
+
"error": "google-login-required: Sign in to Google in the Nodmix browser profile, then retry meeting creation.",
|
|
945
|
+
"manualActionRequired": true,
|
|
946
|
+
"manualActionReason": "google-login-required",
|
|
947
|
+
"manualActionMessage": "Sign in to Google in the Nodmix browser profile, then retry meeting creation.",
|
|
948
|
+
"browser": {
|
|
949
|
+
"nodeId": "ba0f4e4bc...",
|
|
950
|
+
"targetId": "tab-1",
|
|
951
|
+
"browserUrl": "https://accounts.google.com/signin",
|
|
952
|
+
"browserTitle": "Sign in - Google Accounts"
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
When an agent sees `manualActionRequired: true`, it should report the
|
|
958
|
+
`manualActionMessage` plus the browser node/tab context and stop opening new
|
|
959
|
+
Meet tabs until the operator completes the browser step.
|
|
960
|
+
|
|
961
|
+
Example JSON output from API create:
|
|
962
|
+
|
|
963
|
+
```json
|
|
964
|
+
{
|
|
965
|
+
"source": "api",
|
|
966
|
+
"meetingUri": "https://meet.google.com/abc-defg-hij",
|
|
967
|
+
"joined": true,
|
|
968
|
+
"space": {
|
|
969
|
+
"name": "spaces/abc-defg-hij",
|
|
970
|
+
"meetingCode": "abc-defg-hij",
|
|
971
|
+
"meetingUri": "https://meet.google.com/abc-defg-hij"
|
|
972
|
+
},
|
|
973
|
+
"join": {
|
|
974
|
+
"session": {
|
|
975
|
+
"id": "meet_...",
|
|
976
|
+
"url": "https://meet.google.com/abc-defg-hij"
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
Creating a Meet joins by default. The Chrome or Chrome-node transport still
|
|
983
|
+
needs a signed-in Google Chrome profile to join through the browser. If the
|
|
984
|
+
profile is signed out, Nodmix reports `manualActionRequired: true` or a
|
|
985
|
+
browser fallback error and asks the operator to finish Google login before
|
|
986
|
+
retrying.
|
|
987
|
+
|
|
988
|
+
Set `preview.enrollmentAcknowledged: true` only after confirming your Cloud
|
|
989
|
+
project, OAuth principal, and meeting participants are enrolled in the Google
|
|
990
|
+
Workspace Developer Preview Program for Meet media APIs.
|
|
991
|
+
|
|
992
|
+
## Config
|
|
993
|
+
|
|
994
|
+
The common Chrome agent path only needs the plugin enabled, BlackHole, SoX, a
|
|
995
|
+
realtime transcription provider key, and a configured Nodmix TTS provider.
|
|
996
|
+
OpenAI is the default transcription provider; set `realtime.voiceProvider` to
|
|
997
|
+
`"google"` and `realtime.model` to use Google Gemini Live for `bidi` mode
|
|
998
|
+
without changing the default agent-mode transcription provider:
|
|
999
|
+
|
|
1000
|
+
```bash
|
|
1001
|
+
brew install blackhole-2ch sox
|
|
1002
|
+
export OPENAI_API_KEY=sk-...
|
|
1003
|
+
# or
|
|
1004
|
+
export GEMINI_API_KEY=...
|
|
1005
|
+
```
|
|
1006
|
+
|
|
1007
|
+
Set the plugin config under `plugins.entries.google-meet.config`:
|
|
1008
|
+
|
|
1009
|
+
```json5
|
|
1010
|
+
{
|
|
1011
|
+
plugins: {
|
|
1012
|
+
entries: {
|
|
1013
|
+
"google-meet": {
|
|
1014
|
+
enabled: true,
|
|
1015
|
+
config: {},
|
|
1016
|
+
},
|
|
1017
|
+
},
|
|
1018
|
+
},
|
|
1019
|
+
}
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
Defaults:
|
|
1023
|
+
|
|
1024
|
+
- `defaultTransport: "chrome"`
|
|
1025
|
+
- `defaultMode: "agent"` (`"realtime"` is accepted only as a legacy
|
|
1026
|
+
compatibility alias for `"agent"`; new tool calls should say `"agent"`)
|
|
1027
|
+
- `chromeNode.node`: optional node id/name/IP for `chrome-node`
|
|
1028
|
+
- `chrome.audioBackend: "blackhole-2ch"`
|
|
1029
|
+
- `chrome.guestName: "Nodmix Agent"`: name used on the signed-out Meet guest
|
|
1030
|
+
screen
|
|
1031
|
+
- `chrome.autoJoin: true`: best-effort guest-name fill and Join Now click
|
|
1032
|
+
through Nodmix browser automation on `chrome-node`
|
|
1033
|
+
- `chrome.reuseExistingTab: true`: activate an existing Meet tab instead of
|
|
1034
|
+
opening duplicates
|
|
1035
|
+
- `chrome.waitForInCallMs: 20000`: wait for the Meet tab to report in-call
|
|
1036
|
+
before the talk-back intro is triggered
|
|
1037
|
+
- `chrome.audioFormat: "pcm16-24khz"`: command-pair audio format. Use
|
|
1038
|
+
`"g711-ulaw-8khz"` only for legacy/custom command pairs that still emit
|
|
1039
|
+
telephony audio.
|
|
1040
|
+
- `chrome.audioBufferBytes: 4096`: SoX processing buffer for generated Chrome
|
|
1041
|
+
command-pair audio commands. This is half of SoX's default 8192-byte buffer,
|
|
1042
|
+
reducing default pipe latency while leaving room to raise it on busy hosts.
|
|
1043
|
+
Values below SoX's minimum are clamped to 17 bytes.
|
|
1044
|
+
- `chrome.audioInputCommand`: SoX command reading from CoreAudio `BlackHole 2ch`
|
|
1045
|
+
and writing audio in `chrome.audioFormat`
|
|
1046
|
+
- `chrome.audioOutputCommand`: SoX command reading audio in `chrome.audioFormat`
|
|
1047
|
+
and writing to CoreAudio `BlackHole 2ch`
|
|
1048
|
+
- `chrome.bargeInInputCommand`: optional local microphone command that writes
|
|
1049
|
+
signed 16-bit little-endian mono PCM for human barge-in detection while
|
|
1050
|
+
assistant playback is active. This currently applies to the Gateway-hosted
|
|
1051
|
+
`chrome` command-pair bridge.
|
|
1052
|
+
- `chrome.bargeInRmsThreshold: 650`: RMS level that counts as a human
|
|
1053
|
+
interruption on `chrome.bargeInInputCommand`
|
|
1054
|
+
- `chrome.bargeInPeakThreshold: 2500`: peak level that counts as a human
|
|
1055
|
+
interruption on `chrome.bargeInInputCommand`
|
|
1056
|
+
- `chrome.bargeInCooldownMs: 900`: minimum delay between repeated human
|
|
1057
|
+
interruption clears
|
|
1058
|
+
- `mode: "agent"`: default talk-back mode. Participant speech is transcribed by
|
|
1059
|
+
the configured realtime transcription provider, sent to the configured
|
|
1060
|
+
Nodmix agent in a per-meeting sub-agent session, and spoken back through the
|
|
1061
|
+
normal Nodmix TTS runtime.
|
|
1062
|
+
- `mode: "bidi"`: fallback direct bidirectional realtime model mode. The
|
|
1063
|
+
realtime voice provider answers participant speech directly and may call
|
|
1064
|
+
`nodmix_agent_consult` for deeper/tool-backed answers.
|
|
1065
|
+
- `mode: "transcribe"`: observe-only mode without the talk-back bridge.
|
|
1066
|
+
- `realtime.provider: "openai"`: compatibility fallback used when the scoped
|
|
1067
|
+
provider fields below are unset.
|
|
1068
|
+
- `realtime.transcriptionProvider: "openai"`: provider id used by `agent` mode
|
|
1069
|
+
for realtime transcription.
|
|
1070
|
+
- `realtime.voiceProvider`: provider id used by `bidi` mode for direct realtime
|
|
1071
|
+
voice. Set this to `"google"` to use Gemini Live while keeping agent-mode
|
|
1072
|
+
transcription on OpenAI.
|
|
1073
|
+
- `realtime.toolPolicy: "safe-read-only"`
|
|
1074
|
+
- `realtime.instructions`: brief spoken replies, with
|
|
1075
|
+
`nodmix_agent_consult` for deeper answers
|
|
1076
|
+
- `realtime.introMessage`: short spoken readiness check when the realtime bridge
|
|
1077
|
+
connects; set it to `""` to join silently
|
|
1078
|
+
- `realtime.agentId`: optional Nodmix agent id for
|
|
1079
|
+
`nodmix_agent_consult`; defaults to `main`
|
|
1080
|
+
|
|
1081
|
+
Optional overrides:
|
|
1082
|
+
|
|
1083
|
+
```json5
|
|
1084
|
+
{
|
|
1085
|
+
defaults: {
|
|
1086
|
+
meeting: "https://meet.google.com/abc-defg-hij",
|
|
1087
|
+
},
|
|
1088
|
+
browser: {
|
|
1089
|
+
defaultProfile: "nodmix",
|
|
1090
|
+
},
|
|
1091
|
+
chrome: {
|
|
1092
|
+
guestName: "Nodmix Agent",
|
|
1093
|
+
waitForInCallMs: 30000,
|
|
1094
|
+
bargeInInputCommand: [
|
|
1095
|
+
"sox",
|
|
1096
|
+
"-q",
|
|
1097
|
+
"-t",
|
|
1098
|
+
"coreaudio",
|
|
1099
|
+
"External Microphone",
|
|
1100
|
+
"-r",
|
|
1101
|
+
"24000",
|
|
1102
|
+
"-c",
|
|
1103
|
+
"1",
|
|
1104
|
+
"-b",
|
|
1105
|
+
"16",
|
|
1106
|
+
"-e",
|
|
1107
|
+
"signed-integer",
|
|
1108
|
+
"-t",
|
|
1109
|
+
"raw",
|
|
1110
|
+
"-",
|
|
1111
|
+
],
|
|
1112
|
+
},
|
|
1113
|
+
chromeNode: {
|
|
1114
|
+
node: "parallels-macos",
|
|
1115
|
+
},
|
|
1116
|
+
defaultMode: "agent",
|
|
1117
|
+
realtime: {
|
|
1118
|
+
provider: "openai",
|
|
1119
|
+
transcriptionProvider: "openai",
|
|
1120
|
+
voiceProvider: "google",
|
|
1121
|
+
model: "gemini-2.5-flash-native-audio-preview-12-2025",
|
|
1122
|
+
agentId: "jay",
|
|
1123
|
+
toolPolicy: "owner",
|
|
1124
|
+
introMessage: "Say exactly: I'm here.",
|
|
1125
|
+
providers: {
|
|
1126
|
+
google: {
|
|
1127
|
+
voice: "Kore",
|
|
1128
|
+
},
|
|
1129
|
+
},
|
|
1130
|
+
},
|
|
1131
|
+
}
|
|
1132
|
+
```
|
|
1133
|
+
|
|
1134
|
+
ElevenLabs for both agent-mode listening and speaking:
|
|
1135
|
+
|
|
1136
|
+
```json5
|
|
1137
|
+
{
|
|
1138
|
+
messages: {
|
|
1139
|
+
tts: {
|
|
1140
|
+
provider: "elevenlabs",
|
|
1141
|
+
providers: {
|
|
1142
|
+
elevenlabs: {
|
|
1143
|
+
modelId: "eleven_v3",
|
|
1144
|
+
voiceId: "pMsXgVXv3BLzUgSXRplE",
|
|
1145
|
+
},
|
|
1146
|
+
},
|
|
1147
|
+
},
|
|
1148
|
+
},
|
|
1149
|
+
plugins: {
|
|
1150
|
+
entries: {
|
|
1151
|
+
"google-meet": {
|
|
1152
|
+
config: {
|
|
1153
|
+
realtime: {
|
|
1154
|
+
transcriptionProvider: "elevenlabs",
|
|
1155
|
+
providers: {
|
|
1156
|
+
elevenlabs: {
|
|
1157
|
+
modelId: "scribe_v2_realtime",
|
|
1158
|
+
audioFormat: "ulaw_8000",
|
|
1159
|
+
sampleRate: 8000,
|
|
1160
|
+
commitStrategy: "vad",
|
|
1161
|
+
},
|
|
1162
|
+
},
|
|
1163
|
+
},
|
|
1164
|
+
},
|
|
1165
|
+
},
|
|
1166
|
+
},
|
|
1167
|
+
},
|
|
1168
|
+
}
|
|
1169
|
+
```
|
|
1170
|
+
|
|
1171
|
+
The persistent Meet voice comes from
|
|
1172
|
+
`messages.tts.providers.elevenlabs.voiceId`. Agent replies can also use
|
|
1173
|
+
per-reply `[[tts:voiceId=... model=eleven_v3]]` directives when TTS model
|
|
1174
|
+
overrides are enabled, but config is the deterministic default for meetings.
|
|
1175
|
+
On join, the logs should show `transcriptionProvider=elevenlabs` and each
|
|
1176
|
+
spoken reply should log `provider=elevenlabs model=eleven_v3 voice=<voiceId>`.
|
|
1177
|
+
|
|
1178
|
+
Twilio-only config:
|
|
1179
|
+
|
|
1180
|
+
```json5
|
|
1181
|
+
{
|
|
1182
|
+
defaultTransport: "twilio",
|
|
1183
|
+
twilio: {
|
|
1184
|
+
defaultDialInNumber: "+15551234567",
|
|
1185
|
+
defaultPin: "123456",
|
|
1186
|
+
},
|
|
1187
|
+
voiceCall: {
|
|
1188
|
+
gatewayUrl: "ws://127.0.0.1:18789",
|
|
1189
|
+
},
|
|
1190
|
+
}
|
|
1191
|
+
```
|
|
1192
|
+
|
|
1193
|
+
`voiceCall.enabled` defaults to `true`; with Twilio transport it delegates the
|
|
1194
|
+
actual PSTN call, DTMF, and intro greeting to the Voice Call plugin. Voice Call
|
|
1195
|
+
plays the DTMF sequence before opening the realtime media stream, then uses the
|
|
1196
|
+
saved intro text as the initial realtime greeting. If `voice-call` is not
|
|
1197
|
+
enabled, Google Meet can still validate and record the dial plan, but it cannot
|
|
1198
|
+
place the Twilio call.
|
|
1199
|
+
|
|
1200
|
+
## Tool
|
|
1201
|
+
|
|
1202
|
+
Agents can use the `google_meet` tool:
|
|
1203
|
+
|
|
1204
|
+
```json
|
|
1205
|
+
{
|
|
1206
|
+
"action": "join",
|
|
1207
|
+
"url": "https://meet.google.com/abc-defg-hij",
|
|
1208
|
+
"transport": "chrome-node",
|
|
1209
|
+
"mode": "agent"
|
|
1210
|
+
}
|
|
1211
|
+
```
|
|
1212
|
+
|
|
1213
|
+
Use `transport: "chrome"` when Chrome runs on the Gateway host. Use
|
|
1214
|
+
`transport: "chrome-node"` when Chrome runs on a paired node such as a Parallels
|
|
1215
|
+
VM. In both cases the model providers and `nodmix_agent_consult` run on the
|
|
1216
|
+
Gateway host, so model credentials stay there. With the default `mode: "agent"`,
|
|
1217
|
+
the realtime transcription provider handles listening, the configured Nodmix
|
|
1218
|
+
agent produces the answer, and regular Nodmix TTS speaks it into Meet. Use
|
|
1219
|
+
`mode: "bidi"` when you want the realtime voice model to answer directly.
|
|
1220
|
+
Raw `mode: "realtime"` remains accepted as a legacy compatibility alias for
|
|
1221
|
+
`mode: "agent"`, but it is no longer advertised in the agent tool schema.
|
|
1222
|
+
Agent-mode logs include the resolved transcription provider/model at bridge
|
|
1223
|
+
startup and the TTS provider, model, voice, output format, and sample rate after
|
|
1224
|
+
each synthesized reply.
|
|
1225
|
+
|
|
1226
|
+
Use `action: "status"` to list active sessions or inspect a session ID. Use
|
|
1227
|
+
`action: "speak"` with `sessionId` and `message` to make the realtime agent
|
|
1228
|
+
speak immediately. Use `action: "test_speech"` to create or reuse the session,
|
|
1229
|
+
trigger a known phrase, and return `inCall` health when the Chrome host can
|
|
1230
|
+
report it. `test_speech` always forces `mode: "agent"` and fails if asked to
|
|
1231
|
+
run in `mode: "transcribe"` because observe-only sessions intentionally cannot
|
|
1232
|
+
emit speech. Its `speechOutputVerified` result is based on realtime audio output
|
|
1233
|
+
bytes increasing during this test call, so a reused session with older audio
|
|
1234
|
+
does not count as a fresh successful speech check. Use `action: "leave"` to mark
|
|
1235
|
+
a session ended.
|
|
1236
|
+
|
|
1237
|
+
`status` includes Chrome health when available:
|
|
1238
|
+
|
|
1239
|
+
- `inCall`: Chrome appears to be inside the Meet call
|
|
1240
|
+
- `micMuted`: best-effort Meet microphone state
|
|
1241
|
+
- `manualActionRequired` / `manualActionReason` / `manualActionMessage`: the
|
|
1242
|
+
browser profile needs manual login, Meet host admission, permissions, or
|
|
1243
|
+
browser-control repair before speech can work
|
|
1244
|
+
- `speechReady` / `speechBlockedReason` / `speechBlockedMessage`: whether
|
|
1245
|
+
managed Chrome speech is allowed now. `speechReady: false` means Nodmix did
|
|
1246
|
+
not send the intro/test phrase into the audio bridge.
|
|
1247
|
+
- `providerConnected` / `realtimeReady`: realtime voice bridge state
|
|
1248
|
+
- `lastInputAt` / `lastOutputAt`: last audio seen from or sent to the bridge
|
|
1249
|
+
- `audioOutputRouted` / `audioOutputDeviceLabel`: whether the Meet tab's media
|
|
1250
|
+
output was actively routed to the BlackHole device used by the bridge
|
|
1251
|
+
- `lastSuppressedInputAt` / `suppressedInputBytes`: loopback input ignored while
|
|
1252
|
+
assistant playback is active
|
|
1253
|
+
|
|
1254
|
+
```json
|
|
1255
|
+
{
|
|
1256
|
+
"action": "speak",
|
|
1257
|
+
"sessionId": "meet_...",
|
|
1258
|
+
"message": "Say exactly: I'm here and listening."
|
|
1259
|
+
}
|
|
1260
|
+
```
|
|
1261
|
+
|
|
1262
|
+
## Agent and bidi modes
|
|
1263
|
+
|
|
1264
|
+
Chrome `agent` mode is optimized for "my agent is in the meeting" behavior. The
|
|
1265
|
+
realtime transcription provider hears the meeting audio, final participant
|
|
1266
|
+
transcripts are routed through the configured Nodmix agent, and the answer is
|
|
1267
|
+
spoken through the normal Nodmix TTS runtime. Set `mode: "bidi"` when you want
|
|
1268
|
+
the realtime voice model to answer directly.
|
|
1269
|
+
Nearby final transcript fragments are coalesced before the consult so one spoken
|
|
1270
|
+
turn does not produce several stale partial answers. Realtime input is also
|
|
1271
|
+
suppressed while queued assistant audio is still playing,
|
|
1272
|
+
and recent assistant-like transcript echoes are ignored before the agent consult
|
|
1273
|
+
so BlackHole loopback does not make the agent answer its own speech.
|
|
1274
|
+
|
|
1275
|
+
| Mode | Who decides the answer | Speech output path | Use when |
|
|
1276
|
+
| ------- | ----------------------------- | -------------------------------------- | ----------------------------------------------------- |
|
|
1277
|
+
| `agent` | The configured Nodmix agent | Normal Nodmix TTS runtime | You want "my agent is in the meeting" behavior |
|
|
1278
|
+
| `bidi` | The realtime voice model | Realtime voice provider audio response | You want the lowest-latency conversational voice loop |
|
|
1279
|
+
|
|
1280
|
+
In `bidi` mode, when the realtime model needs deeper reasoning, current
|
|
1281
|
+
information, or normal Nodmix tools, it can call `nodmix_agent_consult`.
|
|
1282
|
+
|
|
1283
|
+
The consult tool runs the regular Nodmix agent behind the scenes with recent
|
|
1284
|
+
meeting transcript context and returns a concise spoken answer. In `agent` mode,
|
|
1285
|
+
Nodmix sends that answer directly to the TTS runtime; in `bidi` mode, the
|
|
1286
|
+
realtime voice model can speak the consult result back into the meeting. It uses
|
|
1287
|
+
the same shared consult machinery as Voice Call.
|
|
1288
|
+
|
|
1289
|
+
By default, consults run against the `main` agent. Set `realtime.agentId` when a
|
|
1290
|
+
Meet lane should consult a dedicated Nodmix agent workspace, model defaults,
|
|
1291
|
+
tool policy, memory, and session history.
|
|
1292
|
+
|
|
1293
|
+
Agent-mode consults use a per-meeting `agent:<id>:subagent:google-meet:<session>`
|
|
1294
|
+
session key so follow-up questions keep meeting context while inheriting normal
|
|
1295
|
+
agent policy from the configured agent.
|
|
1296
|
+
|
|
1297
|
+
`realtime.toolPolicy` controls the consult run:
|
|
1298
|
+
|
|
1299
|
+
- `safe-read-only`: expose the consult tool and limit the regular agent to
|
|
1300
|
+
`read`, `web_search`, `web_fetch`, `x_search`, `memory_search`, and
|
|
1301
|
+
`memory_get`.
|
|
1302
|
+
- `owner`: expose the consult tool and let the regular agent use the normal
|
|
1303
|
+
agent tool policy.
|
|
1304
|
+
- `none`: do not expose the consult tool to the realtime voice model.
|
|
1305
|
+
|
|
1306
|
+
The consult session key is scoped per Meet session, so follow-up consult calls
|
|
1307
|
+
can reuse prior consult context during the same meeting.
|
|
1308
|
+
|
|
1309
|
+
To force a spoken readiness check after Chrome has fully joined the call:
|
|
1310
|
+
|
|
1311
|
+
```bash
|
|
1312
|
+
nodmix googlemeet speak meet_... "Say exactly: I'm here and listening."
|
|
1313
|
+
```
|
|
1314
|
+
|
|
1315
|
+
For the full join-and-speak smoke:
|
|
1316
|
+
|
|
1317
|
+
```bash
|
|
1318
|
+
nodmix googlemeet test-speech https://meet.google.com/abc-defg-hij \
|
|
1319
|
+
--transport chrome-node \
|
|
1320
|
+
--message "Say exactly: I'm here and listening."
|
|
1321
|
+
```
|
|
1322
|
+
|
|
1323
|
+
## Live test checklist
|
|
1324
|
+
|
|
1325
|
+
Use this sequence before handing a meeting to an unattended agent:
|
|
1326
|
+
|
|
1327
|
+
```bash
|
|
1328
|
+
nodmix googlemeet setup
|
|
1329
|
+
nodmix nodes status
|
|
1330
|
+
nodmix googlemeet test-speech https://meet.google.com/abc-defg-hij \
|
|
1331
|
+
--transport chrome-node \
|
|
1332
|
+
--message "Say exactly: Google Meet speech test complete."
|
|
1333
|
+
```
|
|
1334
|
+
|
|
1335
|
+
Expected Chrome-node state:
|
|
1336
|
+
|
|
1337
|
+
- `googlemeet setup` is all green.
|
|
1338
|
+
- `googlemeet setup` includes `chrome-node-connected` when Chrome-node is the
|
|
1339
|
+
default transport or a node is pinned.
|
|
1340
|
+
- `nodes status` shows the selected node connected.
|
|
1341
|
+
- The selected node advertises both `googlemeet.chrome` and `browser.proxy`.
|
|
1342
|
+
- The Meet tab joins the call and `test-speech` returns Chrome health with
|
|
1343
|
+
`inCall: true`.
|
|
1344
|
+
|
|
1345
|
+
For a remote Chrome host such as a Parallels macOS VM, this is the shortest
|
|
1346
|
+
safe check after updating the Gateway or the VM:
|
|
1347
|
+
|
|
1348
|
+
```bash
|
|
1349
|
+
nodmix googlemeet setup
|
|
1350
|
+
nodmix nodes status --connected
|
|
1351
|
+
nodmix nodes invoke \
|
|
1352
|
+
--node parallels-macos \
|
|
1353
|
+
--command googlemeet.chrome \
|
|
1354
|
+
--params '{"action":"setup"}'
|
|
1355
|
+
```
|
|
1356
|
+
|
|
1357
|
+
That proves the Gateway plugin is loaded, the VM node is connected with the
|
|
1358
|
+
current token, and the Meet audio bridge is available before an agent opens a
|
|
1359
|
+
real meeting tab.
|
|
1360
|
+
|
|
1361
|
+
For a Twilio smoke, use a meeting that exposes phone dial-in details:
|
|
1362
|
+
|
|
1363
|
+
```bash
|
|
1364
|
+
nodmix googlemeet setup
|
|
1365
|
+
nodmix googlemeet join https://meet.google.com/abc-defg-hij \
|
|
1366
|
+
--transport twilio \
|
|
1367
|
+
--dial-in-number +15551234567 \
|
|
1368
|
+
--pin 123456
|
|
1369
|
+
```
|
|
1370
|
+
|
|
1371
|
+
Expected Twilio state:
|
|
1372
|
+
|
|
1373
|
+
- `googlemeet setup` includes green `twilio-voice-call-plugin`,
|
|
1374
|
+
`twilio-voice-call-credentials`, and `twilio-voice-call-webhook` checks.
|
|
1375
|
+
- `voicecall` is available in the CLI after Gateway reload.
|
|
1376
|
+
- The returned session has `transport: "twilio"` and a `twilio.voiceCallId`.
|
|
1377
|
+
- `nodmix logs --follow` shows DTMF TwiML served before realtime TwiML, then a
|
|
1378
|
+
realtime bridge with the initial greeting queued.
|
|
1379
|
+
- `googlemeet leave <sessionId>` hangs up the delegated voice call.
|
|
1380
|
+
|
|
1381
|
+
## Troubleshooting
|
|
1382
|
+
|
|
1383
|
+
### Agent cannot see the Google Meet tool
|
|
1384
|
+
|
|
1385
|
+
Confirm the plugin is enabled in the Gateway config and reload the Gateway:
|
|
1386
|
+
|
|
1387
|
+
```bash
|
|
1388
|
+
nodmix plugins list | grep google-meet
|
|
1389
|
+
nodmix googlemeet setup
|
|
1390
|
+
```
|
|
1391
|
+
|
|
1392
|
+
If you just edited `plugins.entries.google-meet`, restart or reload the Gateway.
|
|
1393
|
+
The running agent only sees plugin tools registered by the current Gateway
|
|
1394
|
+
process.
|
|
1395
|
+
|
|
1396
|
+
On non-macOS Gateway hosts, the agent-facing `google_meet` tool stays visible,
|
|
1397
|
+
but local Chrome talk-back actions are blocked before they hit the audio bridge.
|
|
1398
|
+
Local Chrome talk-back audio currently depends on macOS `BlackHole 2ch`, so
|
|
1399
|
+
Linux agents should use `mode: "transcribe"`, Twilio dial-in, or a macOS
|
|
1400
|
+
`chrome-node` host instead of the default local Chrome agent path.
|
|
1401
|
+
|
|
1402
|
+
### No connected Google Meet-capable node
|
|
1403
|
+
|
|
1404
|
+
On the node host, run:
|
|
1405
|
+
|
|
1406
|
+
```bash
|
|
1407
|
+
nodmix plugins enable google-meet
|
|
1408
|
+
nodmix plugins enable browser
|
|
1409
|
+
NODMIX_ALLOW_INSECURE_PRIVATE_WS=1 \
|
|
1410
|
+
nodmix node run --host <gateway-lan-ip> --port 18789 --display-name parallels-macos
|
|
1411
|
+
```
|
|
1412
|
+
|
|
1413
|
+
On the Gateway host, approve the node and verify commands:
|
|
1414
|
+
|
|
1415
|
+
```bash
|
|
1416
|
+
nodmix devices list
|
|
1417
|
+
nodmix devices approve <requestId>
|
|
1418
|
+
nodmix nodes status
|
|
1419
|
+
```
|
|
1420
|
+
|
|
1421
|
+
The node must be connected and list `googlemeet.chrome` plus `browser.proxy`.
|
|
1422
|
+
The Gateway config must allow those node commands:
|
|
1423
|
+
|
|
1424
|
+
```json5
|
|
1425
|
+
{
|
|
1426
|
+
gateway: {
|
|
1427
|
+
nodes: {
|
|
1428
|
+
allowCommands: ["browser.proxy", "googlemeet.chrome"],
|
|
1429
|
+
},
|
|
1430
|
+
},
|
|
1431
|
+
}
|
|
1432
|
+
```
|
|
1433
|
+
|
|
1434
|
+
If `googlemeet setup` fails `chrome-node-connected` or the Gateway log reports
|
|
1435
|
+
`gateway token mismatch`, reinstall or restart the node with the current Gateway
|
|
1436
|
+
token. For a LAN Gateway this usually means:
|
|
1437
|
+
|
|
1438
|
+
```bash
|
|
1439
|
+
NODMIX_ALLOW_INSECURE_PRIVATE_WS=1 \
|
|
1440
|
+
nodmix node install \
|
|
1441
|
+
--host <gateway-lan-ip> \
|
|
1442
|
+
--port 18789 \
|
|
1443
|
+
--display-name parallels-macos \
|
|
1444
|
+
--force
|
|
1445
|
+
```
|
|
1446
|
+
|
|
1447
|
+
Then reload the node service and re-run:
|
|
1448
|
+
|
|
1449
|
+
```bash
|
|
1450
|
+
nodmix googlemeet setup
|
|
1451
|
+
nodmix nodes status --connected
|
|
1452
|
+
```
|
|
1453
|
+
|
|
1454
|
+
### Browser opens but agent cannot join
|
|
1455
|
+
|
|
1456
|
+
Run `googlemeet test-listen` for observe-only joins or `googlemeet test-speech`
|
|
1457
|
+
for realtime joins, then inspect the returned Chrome health. If either probe
|
|
1458
|
+
reports `manualActionRequired: true`, show `manualActionMessage` to the operator
|
|
1459
|
+
and stop retrying until the browser action is complete.
|
|
1460
|
+
|
|
1461
|
+
Common manual actions:
|
|
1462
|
+
|
|
1463
|
+
- Sign in to the Chrome profile.
|
|
1464
|
+
- Admit the guest from the Meet host account.
|
|
1465
|
+
- Grant Chrome microphone/camera permissions when Chrome's native permission
|
|
1466
|
+
prompt appears.
|
|
1467
|
+
- Close or repair a stuck Meet permission dialog.
|
|
1468
|
+
|
|
1469
|
+
Do not report "not signed in" just because Meet shows "Do you want people to
|
|
1470
|
+
hear you in the meeting?" That is Meet's audio-choice interstitial; Nodmix
|
|
1471
|
+
clicks **Use microphone** through browser automation when available and keeps
|
|
1472
|
+
waiting for the real meeting state. For create-only browser fallback, Nodmix
|
|
1473
|
+
may click **Continue without microphone** because creating the URL does not need
|
|
1474
|
+
the realtime audio path.
|
|
1475
|
+
|
|
1476
|
+
### Meeting creation fails
|
|
1477
|
+
|
|
1478
|
+
`googlemeet create` first uses the Google Meet API `spaces.create` endpoint
|
|
1479
|
+
when OAuth credentials are configured. Without OAuth credentials it falls back
|
|
1480
|
+
to the pinned Chrome node browser. Confirm:
|
|
1481
|
+
|
|
1482
|
+
- For API creation: `oauth.clientId` and `oauth.refreshToken` are configured,
|
|
1483
|
+
or matching `NODMIX_GOOGLE_MEET_*` environment variables are present.
|
|
1484
|
+
- For API creation: the refresh token was minted after create support was
|
|
1485
|
+
added. Older tokens may be missing the `meetings.space.created` scope; rerun
|
|
1486
|
+
`nodmix googlemeet auth login --json` and update plugin config.
|
|
1487
|
+
- For browser fallback: `defaultTransport: "chrome-node"` and
|
|
1488
|
+
`chromeNode.node` point at a connected node with `browser.proxy` and
|
|
1489
|
+
`googlemeet.chrome`.
|
|
1490
|
+
- For browser fallback: the Nodmix Chrome profile on that node is signed in
|
|
1491
|
+
to Google and can open `https://meet.google.com/new`.
|
|
1492
|
+
- For browser fallback: retries reuse an existing `https://meet.google.com/new`
|
|
1493
|
+
or Google account prompt tab before opening a new tab. If an agent times out,
|
|
1494
|
+
retry the tool call rather than manually opening another Meet tab.
|
|
1495
|
+
- For browser fallback: if the tool returns `manualActionRequired: true`, use
|
|
1496
|
+
the returned `browser.nodeId`, `browser.targetId`, `browserUrl`, and
|
|
1497
|
+
`manualActionMessage` to guide the operator. Do not retry in a loop until that
|
|
1498
|
+
action is complete.
|
|
1499
|
+
- For browser fallback: if Meet shows "Do you want people to hear you in the
|
|
1500
|
+
meeting?", leave the tab open. Nodmix should click **Use microphone** or, for
|
|
1501
|
+
create-only fallback, **Continue without microphone** through browser
|
|
1502
|
+
automation and continue waiting for the generated Meet URL. If it cannot, the
|
|
1503
|
+
error should mention `meet-audio-choice-required`, not `google-login-required`.
|
|
1504
|
+
|
|
1505
|
+
### Agent joins but does not talk
|
|
1506
|
+
|
|
1507
|
+
Check the realtime path:
|
|
1508
|
+
|
|
1509
|
+
```bash
|
|
1510
|
+
nodmix googlemeet setup
|
|
1511
|
+
nodmix googlemeet doctor
|
|
1512
|
+
```
|
|
1513
|
+
|
|
1514
|
+
Use `mode: "agent"` for the normal STT -> Nodmix agent -> TTS talk-back path,
|
|
1515
|
+
or `mode: "bidi"` for the direct realtime voice fallback. `mode: "transcribe"`
|
|
1516
|
+
intentionally does not start the talk-back bridge. For observe-only debugging,
|
|
1517
|
+
run `nodmix googlemeet status --json <session-id>` after participants speak
|
|
1518
|
+
and check `captioning`, `transcriptLines`, and `lastCaptionText`. If `inCall` is
|
|
1519
|
+
true but `transcriptLines` stays at `0`, Meet captions may be disabled, no one
|
|
1520
|
+
has spoken since the observer was installed, the Meet UI changed, or live
|
|
1521
|
+
captions are unavailable for the meeting language/account.
|
|
1522
|
+
|
|
1523
|
+
`googlemeet test-speech` always checks the realtime path and reports whether
|
|
1524
|
+
bridge output bytes were observed for that invocation. If `speechOutputVerified` is false and
|
|
1525
|
+
`speechOutputTimedOut` is true, the realtime provider may have accepted the
|
|
1526
|
+
utterance but Nodmix did not see new output bytes reach the Chrome audio
|
|
1527
|
+
bridge.
|
|
1528
|
+
|
|
1529
|
+
Also verify:
|
|
1530
|
+
|
|
1531
|
+
- A realtime provider key is available on the Gateway host, such as
|
|
1532
|
+
`OPENAI_API_KEY` or `GEMINI_API_KEY`.
|
|
1533
|
+
- `BlackHole 2ch` is visible on the Chrome host.
|
|
1534
|
+
- `sox` exists on the Chrome host.
|
|
1535
|
+
- Meet microphone and speaker are routed through the virtual audio path used by
|
|
1536
|
+
Nodmix. `doctor` should show `meet output routed: yes` for local Chrome
|
|
1537
|
+
realtime joins.
|
|
1538
|
+
|
|
1539
|
+
`googlemeet doctor [session-id]` prints the session, node, in-call state,
|
|
1540
|
+
manual action reason, realtime provider connection, `realtimeReady`, audio
|
|
1541
|
+
input/output activity, last audio timestamps, byte counters, and browser URL.
|
|
1542
|
+
Use `googlemeet status [session-id] --json` when you need the raw JSON. Use
|
|
1543
|
+
`googlemeet doctor --oauth` when you need to verify Google Meet OAuth refresh
|
|
1544
|
+
without exposing tokens; add `--meeting` or `--create-space` when you need a
|
|
1545
|
+
Google Meet API proof as well.
|
|
1546
|
+
|
|
1547
|
+
If an agent timed out and you can see a Meet tab already open, inspect that tab
|
|
1548
|
+
without opening another one:
|
|
1549
|
+
|
|
1550
|
+
```bash
|
|
1551
|
+
nodmix googlemeet recover-tab
|
|
1552
|
+
nodmix googlemeet recover-tab https://meet.google.com/abc-defg-hij
|
|
1553
|
+
```
|
|
1554
|
+
|
|
1555
|
+
The equivalent tool action is `recover_current_tab`. It focuses and inspects an
|
|
1556
|
+
existing Meet tab for the selected transport. With `chrome`, it uses local
|
|
1557
|
+
browser control through the Gateway; with `chrome-node`, it uses the configured
|
|
1558
|
+
Chrome node. It does not open a new tab or create a new session; it reports the
|
|
1559
|
+
current blocker, such as login, admission, permissions, or audio-choice state.
|
|
1560
|
+
The CLI command talks to the configured Gateway, so the Gateway must be running;
|
|
1561
|
+
`chrome-node` also requires the Chrome node to be connected.
|
|
1562
|
+
|
|
1563
|
+
### Twilio setup checks fail
|
|
1564
|
+
|
|
1565
|
+
`twilio-voice-call-plugin` fails when `voice-call` is not allowed or not enabled.
|
|
1566
|
+
Add it to `plugins.allow`, enable `plugins.entries.voice-call`, and reload the
|
|
1567
|
+
Gateway.
|
|
1568
|
+
|
|
1569
|
+
`twilio-voice-call-credentials` fails when the Twilio backend is missing account
|
|
1570
|
+
SID, auth token, or caller number. Set these on the Gateway host:
|
|
1571
|
+
|
|
1572
|
+
```bash
|
|
1573
|
+
export TWILIO_ACCOUNT_SID=AC...
|
|
1574
|
+
export TWILIO_AUTH_TOKEN=...
|
|
1575
|
+
export TWILIO_FROM_NUMBER=+15550001234
|
|
1576
|
+
```
|
|
1577
|
+
|
|
1578
|
+
`twilio-voice-call-webhook` fails when `voice-call` has no public webhook
|
|
1579
|
+
exposure, or when `publicUrl` points at loopback or private network space.
|
|
1580
|
+
Set `plugins.entries.voice-call.config.publicUrl` to the public provider URL or
|
|
1581
|
+
configure a `voice-call` tunnel/Tailscale exposure.
|
|
1582
|
+
|
|
1583
|
+
Loopback and private URLs are not valid for carrier callbacks. Do not use
|
|
1584
|
+
`localhost`, `127.0.0.1`, `0.0.0.0`, `10.x`, `172.16.x`-`172.31.x`,
|
|
1585
|
+
`192.168.x`, `169.254.x`, `fc00::/7`, or `fd00::/8` as `publicUrl`.
|
|
1586
|
+
|
|
1587
|
+
For a stable public URL:
|
|
1588
|
+
|
|
1589
|
+
```json5
|
|
1590
|
+
{
|
|
1591
|
+
plugins: {
|
|
1592
|
+
entries: {
|
|
1593
|
+
"voice-call": {
|
|
1594
|
+
enabled: true,
|
|
1595
|
+
config: {
|
|
1596
|
+
provider: "twilio",
|
|
1597
|
+
fromNumber: "+15550001234",
|
|
1598
|
+
publicUrl: "https://voice.example.com/voice/webhook",
|
|
1599
|
+
},
|
|
1600
|
+
},
|
|
1601
|
+
},
|
|
1602
|
+
},
|
|
1603
|
+
}
|
|
1604
|
+
```
|
|
1605
|
+
|
|
1606
|
+
For local development, use a tunnel or Tailscale exposure instead of a private
|
|
1607
|
+
host URL:
|
|
1608
|
+
|
|
1609
|
+
```json5
|
|
1610
|
+
{
|
|
1611
|
+
plugins: {
|
|
1612
|
+
entries: {
|
|
1613
|
+
"voice-call": {
|
|
1614
|
+
config: {
|
|
1615
|
+
tunnel: { provider: "ngrok" },
|
|
1616
|
+
// or
|
|
1617
|
+
tailscale: { mode: "funnel", path: "/voice/webhook" },
|
|
1618
|
+
},
|
|
1619
|
+
},
|
|
1620
|
+
},
|
|
1621
|
+
},
|
|
1622
|
+
}
|
|
1623
|
+
```
|
|
1624
|
+
|
|
1625
|
+
Then restart or reload the Gateway and run:
|
|
1626
|
+
|
|
1627
|
+
```bash
|
|
1628
|
+
nodmix googlemeet setup --transport twilio
|
|
1629
|
+
nodmix voicecall setup
|
|
1630
|
+
nodmix voicecall smoke
|
|
1631
|
+
```
|
|
1632
|
+
|
|
1633
|
+
`voicecall smoke` is readiness-only by default. To dry-run a specific number:
|
|
1634
|
+
|
|
1635
|
+
```bash
|
|
1636
|
+
nodmix voicecall smoke --to "+15555550123"
|
|
1637
|
+
```
|
|
1638
|
+
|
|
1639
|
+
Only add `--yes` when you intentionally want to place a live outbound notify
|
|
1640
|
+
call:
|
|
1641
|
+
|
|
1642
|
+
```bash
|
|
1643
|
+
nodmix voicecall smoke --to "+15555550123" --yes
|
|
1644
|
+
```
|
|
1645
|
+
|
|
1646
|
+
### Twilio call starts but never enters the meeting
|
|
1647
|
+
|
|
1648
|
+
Confirm the Meet event exposes phone dial-in details. Pass the exact dial-in
|
|
1649
|
+
number and PIN or a custom DTMF sequence:
|
|
1650
|
+
|
|
1651
|
+
```bash
|
|
1652
|
+
nodmix googlemeet join https://meet.google.com/abc-defg-hij \
|
|
1653
|
+
--transport twilio \
|
|
1654
|
+
--dial-in-number +15551234567 \
|
|
1655
|
+
--dtmf-sequence ww123456#
|
|
1656
|
+
```
|
|
1657
|
+
|
|
1658
|
+
Use leading `w` or commas in `--dtmf-sequence` if the provider needs a pause
|
|
1659
|
+
before entering the PIN.
|
|
1660
|
+
|
|
1661
|
+
If the phone call is created but the Meet roster never shows the dial-in
|
|
1662
|
+
participant:
|
|
1663
|
+
|
|
1664
|
+
- Run `nodmix googlemeet doctor <session-id>` to confirm the delegated Twilio
|
|
1665
|
+
call ID, whether DTMF was queued, and whether the intro greeting was requested.
|
|
1666
|
+
- Run `nodmix voicecall status --call-id <id>` and confirm the call is still
|
|
1667
|
+
active.
|
|
1668
|
+
- Run `nodmix voicecall tail` and check that Twilio webhooks are arriving at
|
|
1669
|
+
the Gateway.
|
|
1670
|
+
- Run `nodmix logs --follow` and look for the Twilio Meet sequence: Google
|
|
1671
|
+
Meet delegates the join, Voice Call stores and serves pre-connect DTMF TwiML,
|
|
1672
|
+
Voice Call serves realtime TwiML for the Twilio call, then Google Meet requests
|
|
1673
|
+
intro speech with `voicecall.speak`.
|
|
1674
|
+
- Re-run `nodmix googlemeet setup --transport twilio`; a green setup check is
|
|
1675
|
+
required but does not prove the meeting PIN sequence is correct.
|
|
1676
|
+
- Confirm the dial-in number belongs to the same Meet invitation and region as
|
|
1677
|
+
the PIN.
|
|
1678
|
+
- Increase `voiceCall.dtmfDelayMs` from the 12-second default if Meet answers
|
|
1679
|
+
slowly or the call transcript still shows the prompt asking for a PIN after
|
|
1680
|
+
pre-connect DTMF was sent.
|
|
1681
|
+
- If the participant joins but you do not hear the greeting, check
|
|
1682
|
+
`nodmix logs --follow` for the post-DTMF `voicecall.speak` request and
|
|
1683
|
+
either media-stream TTS playback or the Twilio `<Say>` fallback. If the call
|
|
1684
|
+
transcript still contains "enter the meeting PIN", the phone leg has not joined
|
|
1685
|
+
the Meet room yet, so meeting participants will not hear speech.
|
|
1686
|
+
|
|
1687
|
+
If webhooks do not arrive, debug the Voice Call plugin first: the provider must
|
|
1688
|
+
reach `plugins.entries.voice-call.config.publicUrl` or the configured tunnel.
|
|
1689
|
+
See [Voice call troubleshooting](/plugins/voice-call#troubleshooting).
|
|
1690
|
+
|
|
1691
|
+
## Notes
|
|
1692
|
+
|
|
1693
|
+
Google Meet's official media API is receive-oriented, so speaking into a Meet
|
|
1694
|
+
call still needs a participant path. This plugin keeps that boundary visible:
|
|
1695
|
+
Chrome handles browser participation and local audio routing; Twilio handles
|
|
1696
|
+
phone dial-in participation.
|
|
1697
|
+
|
|
1698
|
+
Chrome talk-back modes need `BlackHole 2ch` plus either:
|
|
1699
|
+
|
|
1700
|
+
- `chrome.audioInputCommand` plus `chrome.audioOutputCommand`: Nodmix owns the
|
|
1701
|
+
bridge and pipes audio in `chrome.audioFormat` between those commands and the
|
|
1702
|
+
selected provider. Agent mode uses realtime transcription plus regular TTS;
|
|
1703
|
+
bidi mode uses the realtime voice provider. The default Chrome path is 24 kHz
|
|
1704
|
+
PCM16 with `chrome.audioBufferBytes: 4096`; 8 kHz G.711 mu-law remains
|
|
1705
|
+
available for legacy command pairs.
|
|
1706
|
+
- `chrome.audioBridgeCommand`: an external bridge command owns the whole local
|
|
1707
|
+
audio path and must exit after starting or validating its daemon. This is only
|
|
1708
|
+
valid for `bidi` because `agent` mode needs direct command-pair access for TTS.
|
|
1709
|
+
|
|
1710
|
+
When an agent calls the `google_meet` tool in agent mode, the meeting consultant
|
|
1711
|
+
session forks the caller's current transcript before answering participant
|
|
1712
|
+
speech. The Meet session still stays separate (`agent:<agentId>:subagent:google-meet:<sessionId>`)
|
|
1713
|
+
so meeting follow-ups do not mutate the caller transcript directly.
|
|
1714
|
+
|
|
1715
|
+
For clean duplex audio, route Meet output and Meet microphone through separate
|
|
1716
|
+
virtual devices or a Loopback-style virtual device graph. A single shared
|
|
1717
|
+
BlackHole device can echo other participants back into the call.
|
|
1718
|
+
|
|
1719
|
+
With the command-pair Chrome bridge, `chrome.bargeInInputCommand` can listen to a
|
|
1720
|
+
separate local microphone and clear assistant playback when the human starts
|
|
1721
|
+
talking. This keeps human speech ahead of assistant output even when the shared
|
|
1722
|
+
BlackHole loopback input is temporarily suppressed during assistant playback.
|
|
1723
|
+
Like `chrome.audioInputCommand` and `chrome.audioOutputCommand`, it is an
|
|
1724
|
+
operator-configured local command. Use an explicit trusted command path or
|
|
1725
|
+
argument list, and do not point it at scripts from untrusted locations.
|
|
1726
|
+
|
|
1727
|
+
`googlemeet speak` triggers the active talk-back audio bridge for a Chrome
|
|
1728
|
+
session. `googlemeet leave` stops that bridge. For Twilio sessions delegated
|
|
1729
|
+
through the Voice Call plugin, `leave` also hangs up the underlying voice call.
|
|
1730
|
+
Use `googlemeet end-active-conference` when you also want to close the active
|
|
1731
|
+
Google Meet conference for an API-managed space.
|
|
1732
|
+
|
|
1733
|
+
## Related
|
|
1734
|
+
|
|
1735
|
+
- [Voice call plugin](/plugins/voice-call)
|
|
1736
|
+
- [Talk mode](/nodes/talk)
|
|
1737
|
+
- [Building plugins](/plugins/building-plugins)
|