mirror of
https://github.com/OpenSquawk/OpenSquawk
synced 2026-08-13 13:15:42 +08:00
Scenario picker & completion:
- Login → scenario selection screen with complete chains + individual phases
- Completion screen with "fly again / try opposite / back to scenarios"
- Scenario.airport ('dep'|'arr') drives which airport frequencies to fetch;
arrival scenarios (vfr-arrival, circuit-landing, taxi-in) use arr ICAO
Backend session integration:
- createSession forwards no_chain; response carries active_flow + session_complete
- Pass all six airport frequency variables to session so every chained flow
has the real airport values from creation
- fetchAirportFrequencies now runs before session creation so resolved
frequencies are included in backendVariables
Wrong-frequency check:
- airportFreqMap computed (from airportFrequencies, always up-to-date)
used as primary source in expectedFrequencyForState — immune to flow
snapshot switches
- setActiveFlow called when response.active_flow changes so local engine
cursor moves to the correct flow's states after a chain
- Wrong-freq ATC reply appended to communication log (offSchema entry)
Engine fixes (communicationsEngine.ts):
- patchVariables / patchFlags: write directly to the internal reactive
store, bypassing readonly(ref) which silently blocked all (vars as any)
.value[k] = v mutations
- appendLogEntry: push ATC speech (and wrong-freq replies) into comm log
- ATC controller_say_rendered appended to comm log after every transmission
65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
export interface RadioSessionResponse {
|
|
session_id: string
|
|
flow_slug: string
|
|
current_state: string
|
|
variables: Record<string, any>
|
|
flags: Record<string, boolean>
|
|
expected_pilot_template: string | null
|
|
}
|
|
|
|
export interface RadioTransmitResponse {
|
|
session_id: string
|
|
next_state_id: string
|
|
active_flow: string
|
|
controller_say_template: string | null
|
|
controller_say_rendered: string | null
|
|
expected_pilot_template: string | null
|
|
variables: Record<string, any>
|
|
flags: Record<string, boolean>
|
|
trace: Array<{ type: string; message: string }>
|
|
fallback_used: boolean
|
|
fallback_reason: string | null
|
|
auto_advanced_states?: string[]
|
|
/** True when the full chain is done — show the completion screen. */
|
|
session_complete?: boolean
|
|
}
|
|
|
|
export function useRadioBackend() {
|
|
const config = useRuntimeConfig()
|
|
|
|
function baseUrl(): string {
|
|
return (config.public.radioBackendUrl as string) || 'http://127.0.0.1:8000'
|
|
}
|
|
|
|
async function createSession(
|
|
flowSlug: string,
|
|
variables?: Record<string, any>,
|
|
noChain: boolean = false,
|
|
): Promise<RadioSessionResponse> {
|
|
return await $fetch<RadioSessionResponse>(`${baseUrl()}/api/radio/session`, {
|
|
method: 'POST',
|
|
body: { flow_slug: flowSlug, variables: variables ?? null, no_chain: noChain },
|
|
})
|
|
}
|
|
|
|
async function transmit(sessionId: string, pilotUtterance: string): Promise<RadioTransmitResponse> {
|
|
return await $fetch<RadioTransmitResponse>(
|
|
`${baseUrl()}/api/radio/session/${sessionId}/transmissions`,
|
|
{
|
|
method: 'POST',
|
|
body: { pilot_utterance: pilotUtterance },
|
|
},
|
|
)
|
|
}
|
|
|
|
async function deleteSession(sessionId: string): Promise<void> {
|
|
await $fetch(`${baseUrl()}/api/radio/session/${sessionId}`, { method: 'DELETE' })
|
|
}
|
|
|
|
async function fetchFlows(): Promise<any> {
|
|
return await $fetch(`${baseUrl()}/api/decision-flows/runtime`)
|
|
}
|
|
|
|
return { createSession, transmit, deleteSession, fetchFlows }
|
|
}
|