Skip to content

Translation: change language output during call#136

Merged
tleyden merged 2 commits into
mainfrom
translation_switch_directions
May 14, 2026
Merged

Translation: change language output during call#136
tleyden merged 2 commits into
mainfrom
translation_switch_directions

Conversation

@tleyden
Copy link
Copy Markdown
Owner

@tleyden tleyden commented May 13, 2026

Since #133 isn't working yet, this workaround will allow people to have bidirectional conversations by taking turns and manually switching languages.

Summary by CodeRabbit

  • New Features
    • You can now change the translation output language while a translation session is active. Switch your output language in real-time without interrupting or restarting your session, giving you greater flexibility to adapt to changing communication needs as they arise.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

📝 Walkthrough

Walkthrough

This PR adds the capability to change translation output language while a session is active. The native iOS implementation sends language updates via the Realtime API, the TypeScript bridge exposes this functionality to JavaScript, and the UI component is simplified by removing session-state guards from language selection.

Changes

Runtime language update for active translation sessions

Layer / File(s) Summary
iOS native updateOutputLanguage implementation
modules/vm-webrtc/ios/OpenAIWebRTCTranslatorClient.swift, modules/vm-webrtc/ios/WebRTCTranslatorModule.swift
OpenAIWebRTCTranslatorClient.updateOutputLanguage(_:) trims and validates the language, then sends a session.update event to the Realtime API with audio.output.language set. WebRTCTranslatorModule bridges the call onto the MainActor and forwards to the primary client.
JavaScript native module bridge
modules/vm-webrtc/src/VmWebrtcTranslatorModule.ts
VmWebrtcTranslatorModule class declares updateOutputLanguage(language: string) method, and an exported wrapper function validates native module availability, logs the language, and calls through to the native implementation.
Language picker component refactoring
components/realtime/LanguagePickerRow.tsx
LanguagePickerRow removes the isSessionActive prop and its associated disabled-state styling (langChipDisabled). Featured language and "More…" button handlers now unconditionally call onSelectLanguage(lang.code) and onOpenModal() respectively.
RealtimeTranslation language handler integration
app/RealtimeTranslation.tsx
handleSelectLanguage now imports and calls updateOutputLanguage(code) when isSessionActive is true, with try/catch error handling and warning on failure. Hook dependencies updated to track isSessionActive.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • tleyden/arty#128: Earlier PR that introduced the realtime translation feature; this PR extends it with runtime language switching capability.

Poem

🐰 Language flows like streams in spring,
Changing course mid-song to sing,
From swift native calls so deep,
Through bridges we no longer keep,
The picker now just picks with glee! 🌍

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Translation: change language output during call' accurately and concisely summarizes the main change: enabling users to switch the translation output language while a call is active.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch translation_switch_directions

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

OSSF Scorecard (PR vs base)

  • Base score: 4.4
  • PR score: 4.4
  • Change: 0.00 (unchanged)

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@modules/vm-webrtc/ios/OpenAIWebRTCTranslatorClient.swift`:
- Around line 146-149: Capture and check the Bool returned by sendEvent(...) for
the "session.update" call in OpenAIWebRTCTranslatorClient (currently invoked
with the session payload containing ["audio": ["output": ["language":
trimmed]]]); if the result is false, emit an explicit error log using the
existing logger (e.g., processLogger.error or the class's logger) that includes
operation-specific context such as "session.update", the role/caller (if
available at the call site), and the trimmed language value, and then take an
appropriate local action (e.g., return/fail fast or notify caller) to avoid
silent state desync.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 95c631ee-77ed-4bec-9c69-6e1f8a75f8a4

📥 Commits

Reviewing files that changed from the base of the PR and between 3b1a0b7 and 153f04d.

📒 Files selected for processing (5)
  • app/RealtimeTranslation.tsx
  • components/realtime/LanguagePickerRow.tsx
  • modules/vm-webrtc/ios/OpenAIWebRTCTranslatorClient.swift
  • modules/vm-webrtc/ios/WebRTCTranslatorModule.swift
  • modules/vm-webrtc/src/VmWebrtcTranslatorModule.ts

Comment on lines +146 to +149
_ = sendEvent([
"type": "session.update",
"session": ["audio": ["output": ["language": trimmed]]]
])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify sendEvent signature/return type and current call patterns
rg -n 'func\s+sendEvent\s*\(' modules/vm-webrtc/ios -C3
rg -n '_ = sendEvent\(' modules/vm-webrtc/ios -C2

Repository: tleyden/arty

Length of output: 2610


🏁 Script executed:

cat -n modules/vm-webrtc/ios/WebRtcClientHelpers.swift | sed -n '647,680p'

Repository: tleyden/arty

Length of output: 1807


🏁 Script executed:

# Check if there are any places where sendEvent result IS used
rg 'sendEvent\(' modules/vm-webrtc/ios -B2 -A2 | grep -v '_ = sendEvent'

Repository: tleyden/arty

Length of output: 7087


Add explicit failure handling for session.update with call-site context.

sendEvent() returns a Bool indicating success, but line 146 ignores it via _ =. Although sendEvent() logs internally, it lacks the operation-specific context (role, language) needed for observability. Similar critical operations elsewhere in the codebase (e.g., function call outputs, response.create in OpenAIWebRTCClient.swift) explicitly check the result and log context—this language update should follow the same pattern to prevent silent state desync.

Suggested fix
-        _ = sendEvent([
+        let didSend = sendEvent([
             "type": "session.update",
             "session": ["audio": ["output": ["language": trimmed]]]
         ])
+        if !didSend {
+            logger.log(
+                "[VmWebrtc][Translator] Failed to send language update",
+                attributes: logAttributes(for: .warn, metadata: ["role": role, "language": trimmed])
+            )
+        }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modules/vm-webrtc/ios/OpenAIWebRTCTranslatorClient.swift` around lines 146 -
149, Capture and check the Bool returned by sendEvent(...) for the
"session.update" call in OpenAIWebRTCTranslatorClient (currently invoked with
the session payload containing ["audio": ["output": ["language": trimmed]]]); if
the result is false, emit an explicit error log using the existing logger (e.g.,
processLogger.error or the class's logger) that includes operation-specific
context such as "session.update", the role/caller (if available at the call
site), and the trimmed language value, and then take an appropriate local action
(e.g., return/fail fast or notify caller) to avoid silent state desync.

@tleyden tleyden merged commit c085c8d into main May 14, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant