fix(web): relay-connected microphone destinations authorize speech requests#31778

open2
main
fix/issue-31767
opened17h agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 30m ago

Problem

Choosing a relay-connected environment under Voice settings → "Send microphone audio to" fails with "No relay authorization service is available for the environment request." The web and desktop clients ran every environment speech request (status, models, stream ticket, model download/select/remove, transcript cleanup) in lib/runtime, which has no RemoteEnvironmentAuthorization. For a DPoP (relay) connection, executeAuthenticatedEnvironmentHttpRequest rejects the request locally, before anything is sent.

Reproduced on c52df24d28 by running getEnvironmentSpeechStatus, getEnvironmentSpeechModels and getEnvironmentSpeechStreamUrl through the web runtime with a relay DPoP connection: each failed with that error and made 0 fetches. The same runtime with a direct bearer connection did send its request.

Change

Web speech requests now run in the connection runtime's context, the same way mobile's runSpeech already does. apps/web/src/speech/runEnvironmentSpeech.ts reads the connectionAtomRuntime context from appAtomRegistry and runs the effect in it, passing run options (abort signals) through. Every speech call site in VoiceSettingsPanel.tsx, useEnvironmentSpeechInput.ts and browserVoiceInput.ts uses it. Relay requests now get the shared RemoteEnvironmentAuthorization and DPoP signer, and primary and bearer environments behave as before. lib/runtime is unchanged.

Scope and approval

Fixes pingdotgg/t3code#31767

Verification

  • New browser test loads the models of a relay-connected destination in VoiceSettingsPanel.browser.test.tsx renders Voice settings with a relay (DPoP) destination. It asserts that no error toast appears, that the status request carries the relay DPoP authorization, and that the model list loads.
    • With the three implementation files reverted to c52df24d28, it fails with the reported error:
      1× loads the models of a relay-connected destination
      2AssertionError: expected "add" to not be called at all, but actually been called 1 times
      3 "description": "No relay authorization service is available for the environment request.",
      4 Tests 1 failed | 10 passed (11)
    • At b234d74d07, VoiceSettingsPanel.browser.test.tsx and useEnvironmentSpeechInput.browser.test.tsx both pass: Tests 31 passed (31).
  • vp run check:changed passes: format, lint, knip, typecheck, tests and the React compiler check.
  • There is no layout change, so no screenshots. The visible difference is that the error toast is replaced by the loaded model list.
  • Not checked: a live round trip against a real relay-connected environment on desktop, which needs a signed-in T3 Connect session. The test stubs the connection runtime's authorization service, so the real relay authorization path is not exercised end to end.

AI-assisted; verified with the tests and tools listed above.

Checks

24 successful · 11 skipped
All checks passed
b234d74

Added 2 commits

  • test(web): reproduce relay voice destination missing authorization (#31767)5ec88fb
  • fix(web): relay-connected microphone destinations authorize speech requestsb234d74
Synced from GitHub

Approvability

Verdict: Approved at b234d74

Macroscope's review found this PR approvable — Speech requests now use the connection runtime’s authorization services, enabling existing relay-connected microphone destinations. Destination selection, consent checks, and transport safeguards remain unchanged.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Explain Change →

Walkthrough

Environment speech requests now run with connection runtime context through runEnvironmentSpeech. The settings panel, voice input hook, and browser voice input platform use the helper for their speech operations.

Changes: Environment speech execution

Layer / File(s)Summary
Add context-aware speech runner
apps/web/src/speech/runEnvironmentSpeech.ts
The new helper obtains connection runtime context and provides it to an environment speech effect before running the effect as a promise.
Route voice input effects through the helper
apps/web/src/speech/useEnvironmentSpeechInput.ts, apps/web/src/speech/browserVoiceInput.ts, apps/web/src/speech/useEnvironmentSpeechInput.browser.test.tsx
The hook and browser input platform use the helper for speech status, transcription, model, and stream requests. The hook test mocks the helper directly.
Route settings requests through the helper
apps/web/src/components/settings/VoiceSettingsPanel.tsx, apps/web/src/components/settings/VoiceSettingsPanel.browser.test.tsx
The settings panel uses the helper for status, catalog, hardware, timeout, and model requests. A relay-destination test checks the authorized token, model display, and absence of a notification.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related PRs

Suggested labels: size:M

Suggested reviewers: t3dotgg

Merge Risk: External image Minimal · up to b234d

The reported relay behavior has test coverage, and no actionable merge-blocking issue is established. A live desktop relay round trip remains untested.

Pre-merge checks: Passed 4

Check nameStatusExplanation
Title checkPassedThe title clearly identifies the relay speech authorization fix.
Description checkPassedThe description covers the problem, fix, linked issue, and verification results. It omits before/after screenshots and the AI model and harness. It does not establish whether the linked issue was tria…
Linked Issues checkPassed[#31767] Speech requests now use the connection runtime context, which provides relay authorization and the DPoP signer. The Voice settings browser test checks that a relay destination loads models wi…
Out of Scope Changes checkPassed[#31767] The helper, speech call-site changes, and browser tests support relay authorization for speech requests. The changes are within the issue scope.
Full details: Description check

Explanation

The description covers the problem, fix, linked issue, and verification results. It omits before/after screenshots and the AI model and harness. It does not establish whether the linked issue was triaged.

Full details: Linked Issues check

Explanation

[#31767] Speech requests now use the connection runtime context, which provides relay authorization and the DPoP signer. The Voice settings browser test checks that a relay destination loads models without an error and sends the authorized DPoP token. The test stubs the authorization service; a live relay was not tested.

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
CcoderabbitaiBotreviewed17h ago
Synced from GitHub
External image Additional comments: 1

apps/web/src/speech/useEnvironmentSpeechInput.browser.test.tsx: 1

91-91: External image Trivial · Maintainability & Code Quality · Low value

External image Unverified finding Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Test mocks an internal collaborator.

The test replaces ./runEnvironmentSpeech with Effect.runPromise. This removes the connection-runtime context path from this test. A regression in runEnvironmentSpeech would not fail here. The change is small and the relay path has coverage in VoiceSettingsPanel.browser.test.tsx, so this is acceptable. Keep the runEnvironmentSpeech helper covered by that relay test.

Based on learnings: tests should not mock internal collaborators, and mocking is reserved for system boundaries.

Source: Learnings

External image Review info

External image Run configuration

External image Commits

Reviewing files that changed from the base of the PR and between c52df24d285a072ad9c3f7ab5b3656c0be1cb0f5 and b234d74d070ae5bcc6e050221573835e3488a7a8.

External image Files selected for processing: 6

  • apps/web/src/components/settings/VoiceSettingsPanel.browser.test.tsx
  • apps/web/src/components/settings/VoiceSettingsPanel.tsx
  • apps/web/src/speech/browserVoiceInput.ts
  • apps/web/src/speech/runEnvironmentSpeech.ts
  • apps/web/src/speech/useEnvironmentSpeechInput.browser.test.tsx
  • apps/web/src/speech/useEnvironmentSpeechInput.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.

Synced from GitHub

Can we get this merged, having a hard time with transcriptions lately