diff --git a/hooks/useRoom.ts b/hooks/useRoom.ts index 25e023a88..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 usesSandboxConcurrentStartup = Boolean(appConfig.sandboxId) && usesManagedRoomInput; + 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 (usesSandboxConcurrentStartup) { + if (usesConcurrentManagedStartup) { const [localInputResult, dispatchResult] = await Promise.allSettled([ startLocalInputOrCancelDispatch(), dispatchAgentSession(), @@ -299,7 +301,7 @@ export function useRoom(appConfig: AppConfig) { ]); } - if (!usesSandboxConcurrentStartup) { + if (!usesConcurrentManagedStartup) { await dispatchAgentSession(); } setIsSessionActive(true); diff --git a/tests/browser-room-session.test.mjs b/tests/browser-room-session.test.mjs index f94dba1b5..e19d1ab0c 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), @@ -146,7 +146,7 @@ test('sandbox browser starts media and dispatch concurrently without changing lo ); assert.match( useRoomSource, - /usesSandboxConcurrentStartup = Boolean\(appConfig\.sandboxId\) && usesManagedRoomInput/ + /usesConcurrentManagedStartup =\s*browserSourceClient\.enabled \|\|\s*\(Boolean\(appConfig\.sandboxId\) && appConfig\.usesServerRoomInput\)/ ); assert.match( useRoomSource, diff --git a/tests/session-start-dispatch.test.mjs b/tests/session-start-dispatch.test.mjs index eba6d783f..a3fe9d830 100644 --- a/tests/session-start-dispatch.test.mjs +++ b/tests/session-start-dispatch.test.mjs @@ -217,6 +217,28 @@ 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 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\)/ + ); +}); + 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');