Files
prop-ai-hr/mobile-uni/src/services/realtime-browser-engine.d.ts
T
adminandClaude Opus 5 5cf7ce5847 feat(practice): run realtime practice on App-Plus through renderjs
App-Plus has no WebRTC or getUserMedia in the logic layer, so realtime
practice was H5-only and the native entry had to advertise a record-then-
transcribe downgrade.

Move the media/WebRTC engine into `realtime-browser-engine.js` and drive it
from `RealtimePracticeAppBridge.vue`, whose renderjs script runs inside the
system WebView where those APIs do exist. The logic layer keeps the
authenticated calls: SDP exchange and `search_knowledge` tool invocation stay
server-proxied, so the access token is never handed to the view layer. Both
sides talk over the renderjs bridge only in session payloads the server
already assembled.

Verified against a real App build (`app-renderjs.js` holds RTCPeerConnection
and getUserMedia; `app-service.js` holds the SDP endpoint, renderjs side has
zero hits). Microphone permission, live transcription, remote playback,
foreground/background switching and disconnect fallback still require Android
and iOS device verification.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 23:58:10 +08:00

31 lines
962 B
TypeScript

export type RealtimeBrowserStatus =
| 'idle'
| 'connecting'
| 'connected'
| 'listening'
| 'speaking'
| 'calling-tool';
export interface RealtimeBrowserCallbacks {
onStatus: (status: RealtimeBrowserStatus) => void;
onTraineeTranscript: (text: string) => void;
onCustomerTranscript: (text: string) => void;
onAudioPlaybackBlocked: (blocked: boolean) => void;
onToolCall: (callId: string, name: string, argsJson: string) => Promise<string>;
onTerminated: () => void;
onError: (message: string) => void;
}
export interface RealtimeBrowserEngine {
start: (sessionUpdate: Record<string, unknown>, sessionId?: string) => Promise<void>;
stop: () => void;
resumeAudio: () => Promise<boolean>;
}
export const isRealtimeBrowserSupported: () => boolean;
export const createRealtimeBrowserEngine: (
callbacks: RealtimeBrowserCallbacks,
exchangeSdp: (offerSdp: string, sessionId?: string) => Promise<string>
) => RealtimeBrowserEngine;