惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
H
Help Net Security
腾讯CDC
宝玉的分享
宝玉的分享
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LangChain Blog
爱范儿
爱范儿
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
MyScale Blog
MyScale Blog
Engineering at Meta
Engineering at Meta
N
Netflix TechBlog - Medium
D
Docker
V
V2EX
Last Week in AI
Last Week in AI
G
Google Developers Blog
IT之家
IT之家
C
Check Point Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 聂微东

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
fix(google-meet): reuse meet tabs across retries · opencl...
steipete · 2026-04-25 · via Recent Commits to openclaw:main

@@ -766,6 +766,128 @@ describe("google-meet plugin", () => {

766766

});

767767

});

768768769+

it("reuses active Meet sessions across URL query differences", async () => {

770+

const { methods, nodesInvoke } = setup(

771+

{

772+

defaultTransport: "chrome-node",

773+

defaultMode: "transcribe",

774+

},

775+

{

776+

nodesInvokeResult: {

777+

payload: {

778+

launched: true,

779+

browser: { inCall: true, micMuted: false },

780+

},

781+

},

782+

},

783+

);

784+

const handler = methods.get("googlemeet.join") as

785+

| ((ctx: {

786+

params: Record<string, unknown>;

787+

respond: ReturnType<typeof vi.fn>;

788+

}) => Promise<void>)

789+

| undefined;

790+

const first = vi.fn();

791+

const second = vi.fn();

792+793+

await handler?.({

794+

params: { url: "https://meet.google.com/abc-defg-hij?authuser=me@example.com" },

795+

respond: first,

796+

});

797+

await handler?.({

798+

params: { url: "https://meet.google.com/abc-defg-hij" },

799+

respond: second,

800+

});

801+802+

expect(

803+

nodesInvoke.mock.calls.filter(([call]) => call.command === "googlemeet.chrome"),

804+

).toHaveLength(1);

805+

expect(second.mock.calls[0]?.[1]).toMatchObject({

806+

session: {

807+

notes: expect.arrayContaining(["Reused existing active Meet session."]),

808+

},

809+

});

810+

});

811+812+

it("reuses existing Meet browser tabs across URL query differences", async () => {

813+

const { methods, nodesInvoke } = setup(

814+

{

815+

defaultTransport: "chrome-node",

816+

defaultMode: "transcribe",

817+

},

818+

{

819+

nodesInvokeHandler: async (params) => {

820+

if (params.command !== "browser.proxy") {

821+

return { payload: { launched: true } };

822+

}

823+

const proxy = params.params as {

824+

path?: string;

825+

body?: { targetId?: string; url?: string };

826+

};

827+

if (proxy.path === "/tabs") {

828+

return {

829+

payload: {

830+

result: {

831+

running: true,

832+

tabs: [

833+

{

834+

targetId: "existing-meet-tab",

835+

title: "Meet",

836+

url: "https://meet.google.com/abc-defg-hij?authuser=me@example.com",

837+

},

838+

],

839+

},

840+

},

841+

};

842+

}

843+

if (proxy.path === "/tabs/focus") {

844+

return { payload: { result: { ok: true } } };

845+

}

846+

if (proxy.path === "/act") {

847+

return {

848+

payload: {

849+

result: {

850+

result: JSON.stringify({

851+

inCall: true,

852+

title: "Meet",

853+

url: "https://meet.google.com/abc-defg-hij?authuser=me@example.com",

854+

}),

855+

},

856+

},

857+

};

858+

}

859+

throw new Error(`unexpected browser proxy path ${proxy.path}`);

860+

},

861+

},

862+

);

863+

const handler = methods.get("googlemeet.join") as

864+

| ((ctx: {

865+

params: Record<string, unknown>;

866+

respond: ReturnType<typeof vi.fn>;

867+

}) => Promise<void>)

868+

| undefined;

869+

const respond = vi.fn();

870+871+

await handler?.({

872+

params: { url: "https://meet.google.com/abc-defg-hij" },

873+

respond,

874+

});

875+876+

expect(nodesInvoke).toHaveBeenCalledWith(

877+

expect.objectContaining({

878+

params: expect.objectContaining({

879+

path: "/tabs/focus",

880+

body: { targetId: "existing-meet-tab" },

881+

}),

882+

}),

883+

);

884+

expect(nodesInvoke).not.toHaveBeenCalledWith(

885+

expect.objectContaining({

886+

params: expect.objectContaining({ path: "/tabs/open" }),

887+

}),

888+

);

889+

});

890+769891

it("exposes a test-speech action that joins the requested meeting", async () => {

770892

const { tools, nodesInvoke } = setup(

771893

{

@@ -1072,6 +1194,14 @@ describe("google-meet plugin", () => {

10721194

expect(bridge.triggerGreeting).not.toHaveBeenCalled();

10731195

handle.speak("Say exactly: hello from the meeting.");

10741196

expect(bridge.triggerGreeting).toHaveBeenLastCalledWith("Say exactly: hello from the meeting.");

1197+

expect(handle.getHealth()).toMatchObject({

1198+

providerConnected: true,

1199+

realtimeReady: true,

1200+

audioInputActive: true,

1201+

audioOutputActive: true,

1202+

lastInputBytes: 3,

1203+

lastOutputBytes: 2,

1204+

});

10751205

expect(callbacks).toMatchObject({

10761206

tools: [

10771207

expect.objectContaining({

@@ -1226,6 +1356,14 @@ describe("google-meet plugin", () => {

12261356

nodeId: "node-1",

12271357

bridgeId: "bridge-1",

12281358

});

1359+

expect(handle.getHealth()).toMatchObject({

1360+

providerConnected: true,

1361+

realtimeReady: true,

1362+

audioInputActive: true,

1363+

audioOutputActive: true,

1364+

lastInputBytes: 3,

1365+

lastOutputBytes: 3,

1366+

});

1229136712301368

await handle.stop();

12311369