From 63eafdf54aab45c41390d1f05f74f3ef0b6b39cc Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 28 Aug 2026 17:45:24 +0800 Subject: [PATCH 1/4] fix: dispatch local browser sessions concurrently --- hooks/useRoom.ts | 6 +++--- tests/session-start-dispatch.test.mjs | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/hooks/useRoom.ts b/hooks/useRoom.ts index 25e023a88..0de19d556 100644 --- a/hooks/useRoom.ts +++ b/hooks/useRoom.ts @@ -253,7 +253,7 @@ export function useRoom(appConfig: AppConfig) { } }; const usesManagedRoomInput = browserSourceClient.enabled || appConfig.usesServerRoomInput; - const usesSandboxConcurrentStartup = Boolean(appConfig.sandboxId) && usesManagedRoomInput; + const usesConcurrentBrowserStartup = browserSourceClient.enabled; try { await waitForAgentSessionStop(); @@ -266,7 +266,7 @@ export function useRoom(appConfig: AppConfig) { recordFrontendObservability(FRONTEND_EVENTS.ROOM_CONNECT_FINISHED); recordFrontendObservability(FRONTEND_EVENTS.ROOM_CONNECTED); connectedRoomName = room.name; - if (usesSandboxConcurrentStartup) { + if (usesConcurrentBrowserStartup) { const [localInputResult, dispatchResult] = await Promise.allSettled([ startLocalInputOrCancelDispatch(), dispatchAgentSession(), @@ -299,7 +299,7 @@ export function useRoom(appConfig: AppConfig) { ]); } - if (!usesSandboxConcurrentStartup) { + if (!usesConcurrentBrowserStartup) { await dispatchAgentSession(); } setIsSessionActive(true); diff --git a/tests/session-start-dispatch.test.mjs b/tests/session-start-dispatch.test.mjs index eba6d783f..04c931342 100644 --- a/tests/session-start-dispatch.test.mjs +++ b/tests/session-start-dispatch.test.mjs @@ -217,6 +217,20 @@ test('start call dispatches the agent with a cancellable room session id', async assert.doesNotMatch(useRoomSource, /requestAgentSessionDispatch\(\s*room\.name,/); }); +test('browser input starts capture and agent dispatch concurrently outside sandbox', async () => { + const useRoomSource = await readFile(new URL('../hooks/useRoom.ts', import.meta.url), 'utf8'); + + assert.match( + useRoomSource, + /const usesConcurrentBrowserStartup = browserSourceClient\.enabled;/ + ); + assert.match( + useRoomSource, + /if \(usesConcurrentBrowserStartup\) \{[\s\S]*?Promise\.allSettled\(\[[\s\S]*?startLocalInputOrCancelDispatch\(\),[\s\S]*?dispatchAgentSession\(\),/ + ); + assert.doesNotMatch(useRoomSource, /Boolean\(appConfig\.sandboxId\) && usesManagedRoomInput/); +}); + test('connection details request uses the same canonical session id as dispatch', async () => { const useRoomSource = await readFile(new URL('../hooks/useRoom.ts', import.meta.url), 'utf8'); From 22aa6acc1d261496e3f84d1980b31bdb86a1ac8d Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 28 Aug 2026 17:51:50 +0800 Subject: [PATCH 2/4] style: satisfy frontend lint --- tests/session-start-dispatch.test.mjs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/session-start-dispatch.test.mjs b/tests/session-start-dispatch.test.mjs index 04c931342..3f9bc4d8b 100644 --- a/tests/session-start-dispatch.test.mjs +++ b/tests/session-start-dispatch.test.mjs @@ -220,10 +220,7 @@ test('start call dispatches the agent with a cancellable room session id', async test('browser input starts capture and agent dispatch concurrently outside sandbox', async () => { const useRoomSource = await readFile(new URL('../hooks/useRoom.ts', import.meta.url), 'utf8'); - assert.match( - useRoomSource, - /const usesConcurrentBrowserStartup = browserSourceClient\.enabled;/ - ); + assert.match(useRoomSource, /const usesConcurrentBrowserStartup = browserSourceClient\.enabled;/); assert.match( useRoomSource, /if \(usesConcurrentBrowserStartup\) \{[\s\S]*?Promise\.allSettled\(\[[\s\S]*?startLocalInputOrCancelDispatch\(\),[\s\S]*?dispatchAgentSession\(\),/ From 62ab3a6a7446412de3bc54190b48df09552f7a64 Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 28 Aug 2026 17:56:27 +0800 Subject: [PATCH 3/4] test: align browser startup regression --- tests/browser-room-session.test.mjs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/browser-room-session.test.mjs b/tests/browser-room-session.test.mjs index f94dba1b5..900daa1ab 100644 --- a/tests/browser-room-session.test.mjs +++ b/tests/browser-room-session.test.mjs @@ -133,7 +133,7 @@ test('ending a voice session clears the reusable session id', async () => { assert.doesNotMatch(useRoomSource, /if \(appConfig\.usesBrowserRawMediaInput\)/); }); -test('sandbox browser starts media and dispatch concurrently without changing local order', async () => { +test('browser input starts media and dispatch concurrently', async () => { const useRoomSource = await readFile(new URL('../hooks/useRoom.ts', import.meta.url), 'utf8'); const browserSourceSource = await readFile( new URL('../hooks/useBrowserSourceClient.ts', import.meta.url), @@ -144,10 +144,7 @@ test('sandbox browser starts media and dispatch concurrently without changing lo useRoomSource, /await room\.connect[\s\S]*connectedRoomName = room\.name;[\s\S]*await Promise\.allSettled\(\[[\s\S]*startLocalInputOrCancelDispatch\(\),[\s\S]*dispatchAgentSession\(\),[\s\S]*\]\)/ ); - assert.match( - useRoomSource, - /usesSandboxConcurrentStartup = Boolean\(appConfig\.sandboxId\) && usesManagedRoomInput/ - ); + assert.match(useRoomSource, /usesConcurrentBrowserStartup = browserSourceClient\.enabled/); assert.match( useRoomSource, /const startLocalInputOrCancelDispatch = async \(\) => \{[\s\S]*await startLocalInput\(\);[\s\S]*catch \(error\) \{[\s\S]*cancelAgentSessionStart\(sessionId\);[\s\S]*throw error;/ From 064f18daaa2d672e0573173f7fd3fb672827a07f Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 28 Aug 2026 20:19:56 +0800 Subject: [PATCH 4/4] fix: preserve managed sandbox startup ordering --- hooks/useRoom.ts | 8 +++++--- tests/browser-room-session.test.mjs | 5 ++++- tests/session-start-dispatch.test.mjs | 17 ++++++++++++++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/hooks/useRoom.ts b/hooks/useRoom.ts index 0de19d556..86f82ff45 100644 --- a/hooks/useRoom.ts +++ b/hooks/useRoom.ts @@ -253,7 +253,9 @@ export function useRoom(appConfig: AppConfig) { } }; const usesManagedRoomInput = browserSourceClient.enabled || appConfig.usesServerRoomInput; - const usesConcurrentBrowserStartup = browserSourceClient.enabled; + const usesConcurrentManagedStartup = + browserSourceClient.enabled || + (Boolean(appConfig.sandboxId) && appConfig.usesServerRoomInput); try { await waitForAgentSessionStop(); @@ -266,7 +268,7 @@ export function useRoom(appConfig: AppConfig) { recordFrontendObservability(FRONTEND_EVENTS.ROOM_CONNECT_FINISHED); recordFrontendObservability(FRONTEND_EVENTS.ROOM_CONNECTED); connectedRoomName = room.name; - if (usesConcurrentBrowserStartup) { + if (usesConcurrentManagedStartup) { const [localInputResult, dispatchResult] = await Promise.allSettled([ startLocalInputOrCancelDispatch(), dispatchAgentSession(), @@ -299,7 +301,7 @@ export function useRoom(appConfig: AppConfig) { ]); } - if (!usesConcurrentBrowserStartup) { + if (!usesConcurrentManagedStartup) { await dispatchAgentSession(); } setIsSessionActive(true); diff --git a/tests/browser-room-session.test.mjs b/tests/browser-room-session.test.mjs index 900daa1ab..e19d1ab0c 100644 --- a/tests/browser-room-session.test.mjs +++ b/tests/browser-room-session.test.mjs @@ -144,7 +144,10 @@ test('browser input starts media and dispatch concurrently', async () => { useRoomSource, /await room\.connect[\s\S]*connectedRoomName = room\.name;[\s\S]*await Promise\.allSettled\(\[[\s\S]*startLocalInputOrCancelDispatch\(\),[\s\S]*dispatchAgentSession\(\),[\s\S]*\]\)/ ); - assert.match(useRoomSource, /usesConcurrentBrowserStartup = browserSourceClient\.enabled/); + assert.match( + useRoomSource, + /usesConcurrentManagedStartup =\s*browserSourceClient\.enabled \|\|\s*\(Boolean\(appConfig\.sandboxId\) && appConfig\.usesServerRoomInput\)/ + ); assert.match( useRoomSource, /const startLocalInputOrCancelDispatch = async \(\) => \{[\s\S]*await startLocalInput\(\);[\s\S]*catch \(error\) \{[\s\S]*cancelAgentSessionStart\(sessionId\);[\s\S]*throw error;/ diff --git a/tests/session-start-dispatch.test.mjs b/tests/session-start-dispatch.test.mjs index 3f9bc4d8b..a3fe9d830 100644 --- a/tests/session-start-dispatch.test.mjs +++ b/tests/session-start-dispatch.test.mjs @@ -220,12 +220,23 @@ test('start call dispatches the agent with a cancellable room session id', async test('browser input starts capture and agent dispatch concurrently outside sandbox', async () => { const useRoomSource = await readFile(new URL('../hooks/useRoom.ts', import.meta.url), 'utf8'); - assert.match(useRoomSource, /const usesConcurrentBrowserStartup = browserSourceClient\.enabled;/); assert.match( useRoomSource, - /if \(usesConcurrentBrowserStartup\) \{[\s\S]*?Promise\.allSettled\(\[[\s\S]*?startLocalInputOrCancelDispatch\(\),[\s\S]*?dispatchAgentSession\(\),/ + /const usesConcurrentManagedStartup =\s*browserSourceClient\.enabled \|\|/ + ); + assert.match( + useRoomSource, + /if \(usesConcurrentManagedStartup\) \{[\s\S]*?Promise\.allSettled\(\[[\s\S]*?startLocalInputOrCancelDispatch\(\),[\s\S]*?dispatchAgentSession\(\),/ + ); +}); + +test('sandbox server-managed input keeps concurrent dispatch startup', async () => { + const useRoomSource = await readFile(new URL('../hooks/useRoom.ts', import.meta.url), 'utf8'); + + assert.match( + useRoomSource, + /usesConcurrentManagedStartup =\s*browserSourceClient\.enabled \|\|\s*\(Boolean\(appConfig\.sandboxId\) && appConfig\.usesServerRoomInput\)/ ); - assert.doesNotMatch(useRoomSource, /Boolean\(appConfig\.sandboxId\) && usesManagedRoomInput/); }); test('connection details request uses the same canonical session id as dispatch', async () => {