


























@@ -24,14 +24,15 @@ import {
2424import { handleGoogleMeetNodeHostCommand } from "./src/node-host.js";
2525import { startNodeRealtimeAudioBridge } from "./src/realtime-node.js";
2626import { startCommandRealtimeAudioBridge } from "./src/realtime.js";
27-import { normalizeMeetUrl } from "./src/runtime.js";
27+import { GoogleMeetRuntime, normalizeMeetUrl } from "./src/runtime.js";
2828import {
2929invokeGoogleMeetGatewayMethodForTest,
3030noopLogger,
3131setupGoogleMeetPlugin,
3232} from "./src/test-support/plugin-harness.js";
3333import { __testing as chromeTransportTesting } from "./src/transports/chrome.js";
3434import { buildMeetDtmfSequence, normalizeDialInNumber } from "./src/transports/twilio.js";
35+import type { GoogleMeetSession } from "./src/transports/types.js";
35363637const voiceCallMocks = vi.hoisted(() => ({
3738joinMeetViaVoiceCallGateway: vi.fn(async () => ({ callId: "call-1", dtmfSent: true })),
@@ -1837,6 +1838,39 @@ describe("google-meet plugin", () => {
18371838expect(result.details).toMatchObject({ createdSession: true });
18381839});
183918401841+it("does not start a second realtime response for test speech", async () => {
1842+const runtime = new GoogleMeetRuntime({
1843+config: resolveGoogleMeetConfig({}),
1844+fullConfig: {} as never,
1845+runtime: {} as never,
1846+logger: noopLogger,
1847+});
1848+const session: GoogleMeetSession = {
1849+id: "meet_1",
1850+url: "https://meet.google.com/abc-defg-hij",
1851+transport: "chrome",
1852+mode: "realtime",
1853+state: "active",
1854+createdAt: "2026-04-27T00:00:00.000Z",
1855+updatedAt: "2026-04-27T00:00:00.000Z",
1856+participantIdentity: "signed-in Google Chrome profile",
1857+realtime: { enabled: true, provider: "openai", toolPolicy: "safe-read-only" },
1858+chrome: { audioBackend: "blackhole-2ch", launched: true },
1859+notes: [],
1860+};
1861+const join = vi.spyOn(runtime, "join").mockResolvedValue({ session, spoken: true });
1862+const speak = vi.spyOn(runtime, "speak");
1863+1864+const result = await runtime.testSpeech({
1865+url: "https://meet.google.com/abc-defg-hij",
1866+message: "Say exactly: hello.",
1867+});
1868+1869+expect(join).toHaveBeenCalledWith(expect.objectContaining({ message: "Say exactly: hello." }));
1870+expect(speak).not.toHaveBeenCalled();
1871+expect(result.spoken).toBe(true);
1872+});
1873+18401874it("reports manual action when the browser profile needs Google login", async () => {
18411875const { tools } = setup(
18421876{
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。