fix(atc): resolve TypeScript errors in new files

- liveatc.vue: fix ~/ to ~~/ imports for shared dir, fix reactive type cast
- TransmissionCard.vue: import Transmission type from shared instead of local dupe
- route.post.ts: fix possibly-undefined candidates, remove unused ts-expect-error

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
itsrubberduck
2026-02-15 00:07:23 +01:00
parent c5e9e6e75b
commit cc3681bbe6
3 changed files with 15 additions and 34 deletions

View File

@@ -162,26 +162,7 @@
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
interface TransmissionDebug {
sttRaw?: string
llmRequest?: { currentPhase: string; currentInteraction: string; pilotSaid: string; candidates: { id: string; intent: string }[]; contextSent: unknown }
llmResponse?: { chosenInteraction: string; confidence: 'high' | 'medium' | 'low'; reason: string; tokensUsed: number; durationMs: number; model: string }
engineAction?: { templateUsed: string; variablesUpdated: Record<string, unknown>; handoff?: { from: string; to: string }; phaseChanged?: { from: string; to: string } }
telemetryTrigger?: { parameter: string; condition: string; value: unknown }
readbackResult?: { complete: boolean; missing?: string[] }
}
interface Transmission {
id: string
timestamp: Date
speaker: 'pilot' | 'atc' | 'system'
message: string
normalized?: string
phase: string
frequency: string
debug: TransmissionDebug
}
import type { Transmission, TransmissionDebug } from '~~/shared/atc/types'
const props = defineProps<{ transmission: Transmission }>()

View File

@@ -180,9 +180,9 @@
<script setup lang="ts">
import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue'
import { useAtcEngine } from '~/shared/atc/engine'
import { getPhaseOrder, getPhase } from '~/shared/atc/phases'
import type { Transmission, FlightPlan } from '~/shared/atc/types'
import { useAtcEngine } from '~~/shared/atc/engine'
import { getPhaseOrder, getPhase } from '~~/shared/atc/phases'
import type { Transmission, FlightPlan } from '~~/shared/atc/types'
// For radio effects (conditional import)
let applyRadioEffect: ((audioBuffer: AudioBuffer, ctx: AudioContext, level: number) => AudioBuffer) | null = null
@@ -248,8 +248,8 @@ const standbyUnit = computed(() => {
})
// ── Transmissions ──
const reversedTransmissions = computed(() =>
[...engine.state.transmissions].reverse()
const reversedTransmissions = computed<Transmission[]>(() =>
([...engine.state.transmissions] as Transmission[]).reverse()
)
const latestAtcTx = computed<Transmission | undefined>(() =>
@@ -337,7 +337,7 @@ async function handleRecordingComplete(payload: { audio: string; format: string
phase: engine.state.currentPhase,
frequency: engine.currentPhase.value?.frequency ?? '',
debug: {},
})
} as any)
} finally {
processing.value = false
}

View File

@@ -104,7 +104,7 @@ function heuristicReadbackCheck(
// Clearly good readback (>= 70% of values present)
if (ratio >= 0.7) {
const readbackOk = candidates.find((c) => c.intent.toLowerCase().includes('correct') || c.id.includes('ok'))
const chosen = readbackOk || candidates[0]
const chosen = readbackOk ?? candidates[0]!
return {
chosen: chosen.id,
reason: 'Heuristic: readback contains required values',
@@ -123,7 +123,7 @@ function heuristicReadbackCheck(
// Clearly bad readback (< 30% of values present)
if (ratio < 0.3 && valuesToCheck.length >= 2) {
const readbackBad = candidates.find((c) => c.intent.toLowerCase().includes('incorrect') || c.id.includes('bad'))
const chosen = readbackBad || candidates[0]
const chosen = readbackBad ?? candidates[0]!
return {
chosen: chosen.id,
reason: 'Heuristic: readback missing most required values',
@@ -160,10 +160,11 @@ export default defineEventHandler(async (event): Promise<RouteResponse> => {
// ── Fast path: single candidate → auto-select ──
if (body.candidates.length === 1) {
const single = body.candidates[0]!
return {
chosen: body.candidates[0].id,
chosen: single.id,
reason: 'Only one candidate available',
pilotIntent: body.candidates[0].intent,
pilotIntent: single.intent,
confidence: 'high',
tokensUsed: 0,
durationMs: Date.now() - startMs,
@@ -207,8 +208,7 @@ export default defineEventHandler(async (event): Promise<RouteResponse> => {
],
temperature: 0.1,
max_tokens: 150,
// @ts-expect-error -- reasoning_effort supported by OpenAI API but not yet in all type defs
reasoning_effort: 'low',
reasoning_effort: 'low' as any,
})
const durationMs = Date.now() - startMs
@@ -224,7 +224,7 @@ export default defineEventHandler(async (event): Promise<RouteResponse> => {
parsed.chosen === 'off_schema' || body.candidates.some((c) => c.id === parsed.chosen)
return {
chosen: validId ? parsed.chosen : body.candidates[0].id,
chosen: validId ? parsed.chosen : body.candidates[0]!.id,
reason: String(parsed.reason || 'LLM selected'),
pilotIntent: String(parsed.pilotIntent || body.pilotSaid),
confidence: validId ? validateConfidence(parsed.confidence) : 'low',
@@ -237,7 +237,7 @@ export default defineEventHandler(async (event): Promise<RouteResponse> => {
// Malformed JSON fallback
console.warn('[route.post] LLM returned malformed JSON, falling back to first candidate:', rawContent)
return {
chosen: body.candidates[0].id,
chosen: body.candidates[0]!.id,
reason: 'LLM response was malformed, defaulting to first candidate',
pilotIntent: body.pilotSaid,
confidence: 'low',