diff --git a/app/pages/classroom.vue b/app/pages/classroom.vue index ea9fe90..7863576 100644 --- a/app/pages/classroom.vue +++ b/app/pages/classroom.vue @@ -1487,6 +1487,7 @@ import { import {DEFAULT_AIRLINE_TELEPHONY, normalizeRadioPhrase, normalizeMetarPhrase} from '~~/shared/utils/radioSpeech' import {denormalizeSpokenAtc, looksLikeCallsignKey, normalizeForMatch} from '~~/shared/utils/sttMatch' import {useBugReport} from '~/composables/useBugReport' +import {postWithLocalFallback, useLocalSpeechBridge} from '~/composables/useLocalSpeechBridge' import BugReportDialog from '~/components/BugReportDialog.vue' definePageMeta({middleware: ['require-auth', 'require-classroom-intro']}) @@ -2850,6 +2851,7 @@ const promptReplayCount = ref(0) const replaySpeedHintSeen = ref(false) const api = useApi() +const {localUrl} = useLocalSpeechBridge() const isClient = typeof window !== 'undefined' const auth = useAuthStore() @@ -4327,7 +4329,11 @@ async function requestSayAudio(cacheKey: string, payload: Record { - const response: any = await api.post('/api/atc/say', payload) + const response: any = await postWithLocalFallback( + localUrl('/api/atc/say'), + payload, + () => api.post('/api/atc/say', payload), + ) const audioData = response?.audio if (!audioData?.base64) { throw new Error('Missing audio data') diff --git a/docs/plans/2026-07-29-classroom-local-bridge.md b/docs/plans/2026-07-29-classroom-local-bridge.md new file mode 100644 index 0000000..dc2ccb6 --- /dev/null +++ b/docs/plans/2026-07-29-classroom-local-bridge.md @@ -0,0 +1,90 @@ +# Classroom Local Speech Bridge Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Make classroom mode's instructor TTS use a locally running Speech Bridge when one is reachable, falling back to the existing cloud `/api/atc/say` path otherwise — same behavior live-atc already has. + +**Architecture:** Reuse the existing `app/composables/useLocalSpeechBridge.ts` composable unchanged. Wire its `useLocalSpeechBridge()` probe and `postWithLocalFallback()` helper into classroom's single TTS call site (`requestSayAudio` in `app/pages/classroom.vue`), mirroring exactly how `app/composables/useRadioSpeech.ts` already does it for live-atc. + +**Tech Stack:** Vue 3 `