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>
31 lines
962 B
TypeScript
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;
|