style: apply current runtime formatter to voice integration

This commit is contained in:
Bilawal Sidhu committed 2026-09-15 10:54:32 -05:00
1 parent 3385e6b713
commit d1a72a35af
4 files changed
+414 -249

No files matched your search

+71 -14
View File
@@ -29,14 +29,54 @@ import { pointInRing } from './naturalEarthRegions.js';
/** Layers the engine understands, with the fields queries may reference. */
export const ANALYST_LAYERS = {
flights: { numeric: ['altitudeM', 'speedMps', 'verticalRateMps'], text: ['callsign', 'icao24', 'originCountry', 'operator', 'routeOrigin', 'routeDestination', 'aircraftClass'], flags: ['military', 'onGround'] },
military: { numeric: ['altitudeM', 'speedMps', 'verticalRateMps'], text: ['callsign', 'icao24', 'originCountry', 'operator', 'aircraftClass'], flags: ['military', 'onGround'] },
'ais-live-vessels': { numeric: ['speedKts', 'courseDeg'], text: ['name', 'mmsi', 'shipType', 'destination', 'navStatus'], flags: [] },
'local-firms': { numeric: ['frp'], text: ['confidence', 'satellite'], flags: [] },
earthquakes: { numeric: ['magnitude', 'depthKm'], text: ['place'], flags: [] },
satellites: { numeric: ['altitudeM', 'speedMps'], text: ['name', 'noradId', 'satelliteClass', 'group'], flags: [] },
'local-datacenters': { numeric: [], text: ['name', 'operator', 'capacity'], flags: [] },
'local-dams': { numeric: [], text: ['name', 'operator', 'river', 'output'], flags: [] },
flights: {
numeric: ['altitudeM', 'speedMps', 'verticalRateMps'],
text: [
'callsign',
'icao24',
'originCountry',
'operator',
'routeOrigin',
'routeDestination',
'aircraftClass',
],
flags: ['military', 'onGround'],
},
military: {
numeric: ['altitudeM', 'speedMps', 'verticalRateMps'],
text: ['callsign', 'icao24', 'originCountry', 'operator', 'aircraftClass'],
flags: ['military', 'onGround'],
},
'ais-live-vessels': {
numeric: ['speedKts', 'courseDeg'],
text: ['name', 'mmsi', 'shipType', 'destination', 'navStatus'],
flags: [],
},
'local-firms': {
numeric: ['frp'],
text: ['confidence', 'satellite'],
flags: [],
},
earthquakes: {
numeric: ['magnitude', 'depthKm'],
text: ['place'],
flags: [],
},
satellites: {
numeric: ['altitudeM', 'speedMps'],
text: ['name', 'noradId', 'satelliteClass', 'group'],
flags: [],
},
'local-datacenters': {
numeric: [],
text: ['name', 'operator', 'capacity'],
flags: [],
},
'local-dams': {
numeric: [],
text: ['name', 'operator', 'river', 'output'],
flags: [],
},
};
const EARTH_R_KM = 6371;
@@ -131,7 +171,7 @@ export function createAnalystEngine(providers) {
async function query(spec = {}) {
const layers =
spec.followUp && lastResult
? null // follow-up: re-filter the remembered set, no re-snapshot
? null // follow-up: re-filter the remembered set, no re-snapshot
: Array.isArray(spec.layers) && spec.layers.length
? spec.layers
: ['flights'];
@@ -161,7 +201,20 @@ export function createAnalystEngine(providers) {
const rows = providers.getRecords(key) || [];
const snapshot = providers.getLayerSnapshot?.(key);
if (snapshot) queriedSnapshots.push(snapshot);
layersQueried.push({ layerKey: key, records: rows.length, ...(snapshot ? { feedState: snapshot.feedState, source: snapshot.source, lastUpdate: snapshot.lastUpdate, enabled: snapshot.enabled, error: snapshot.error } : {}), ...providers.getRecordCoverage?.(key, rows) });
layersQueried.push({
layerKey: key,
records: rows.length,
...(snapshot
? {
feedState: snapshot.feedState,
source: snapshot.source,
lastUpdate: snapshot.lastUpdate,
enabled: snapshot.enabled,
error: snapshot.error,
}
: {}),
...providers.getRecordCoverage?.(key, rows),
});
for (const row of rows) records.push({ layerKey: key, ...row });
}
}
@@ -206,8 +259,8 @@ export function createAnalystEngine(providers) {
// nothing in the payload to show which.
const subjectCenter =
Number.isFinite(subject?.lat) && Number.isFinite(subject?.lon)
? { lat: subject.lat, lon: subject.lon }
: null;
? { lat: subject.lat, lon: subject.lon }
: null;
const center = explicitCenter ||
subjectCenter || { lat: view.lat, lon: view.lon };
resolvedScope = { center, km: Number(scope.km) || 100 };
@@ -273,9 +326,13 @@ export function createAnalystEngine(providers) {
coverage: {
layersQueried,
scope: scopeNote,
...(queriedSnapshots.length ? { feedProvenance: feedProvenanceEnvelope(queriedSnapshots) } : {}),
...(queriedSnapshots.length
? { feedProvenance: feedProvenanceEnvelope(queriedSnapshots) }
: {}),
followUp: Boolean(spec.followUp && lastResult),
note: layersQueried.some((layer) => layer.basis === 'bounded-loaded-records')
note: layersQueried.some(
(layer) => layer.basis === 'bounded-loaded-records',
)
? 'Counts and ranks cover the bounded examined loaded records only; omitted records may change the nearest item or count. Satellite distance is ground distance, not slant range.'
: 'client-side data only — answers cover what the enabled layers currently hold',
},
+25 -8
View File
@@ -24,7 +24,12 @@ import {
geoidHeight,
} from './data/geoid.js';
import { getBasemapLabelContext } from './voice/gevActions.js';
import { hudSummaryMatchesProvenance, hudSummaryLayerContext, hudTelemetryProvenanceTag, isHudSummaryUnconfigured } from './hudSummaryResponse.js';
import {
hudSummaryMatchesProvenance,
hudSummaryLayerContext,
hudTelemetryProvenanceTag,
isHudSummaryUnconfigured,
} from './hudSummaryResponse.js';
/** Color palettes keyed by shader mode; applied as CSS custom properties. */
const HUD_COLORS = {
@@ -641,15 +646,17 @@ export class IntelHUD {
const altDisplayM = Number.isFinite(m.altMslM) ? m.altMslM : m.altM;
const altTag =
altDisplayM >= 1000
? `${(altDisplayM / 1000).toFixed(1)}KM`
: `${Math.round(altDisplayM)}M`;
? `${(altDisplayM / 1000).toFixed(1)}KM`
: `${Math.round(altDisplayM)}M`;
const winTag = window
? `${Math.max(1, Math.round(window.widthKm))}x${Math.max(1, Math.round(window.heightKm))}KM`
: 'N/A';
// NEAR the nearest catalogued POI at metro range; otherwise the lat/lon sector.
const localityTag = composeLocalityTag(nearest, m.latDeg, m.lonDeg);
const provenance = hudTelemetryProvenanceTag(this._dataManager?.getAll?.() || []);
const provenance = hudTelemetryProvenanceTag(
this._dataManager?.getAll?.() || [],
);
const line = `${modeLabel} ${band} ${localityTag} | ${region} | ALT ${altTag} | WINDOW ${winTag} | SUN ${m.sunEl.toFixed(0)}° | ONA ${m.ona.toFixed(0)}° | ${localTag}`;
return provenance ? `${line} | ${provenance}` : line;
}
@@ -736,7 +743,12 @@ export class IntelHUD {
if (!response.ok || !data?.summary) {
throw new Error(data?.error || `HTTP ${response.status}`);
}
this._setSummaryText(hudSummaryMatchesProvenance(data.summary, context.feedProvenance) ? data.summary : fallbackText, animate);
this._setSummaryText(
hudSummaryMatchesProvenance(data.summary, context.feedProvenance)
? data.summary
: fallbackText,
animate,
);
} catch (error) {
if (error?.name !== 'AbortError') {
console.warn('[HUD] AI summary unavailable:', error);
@@ -770,8 +782,8 @@ export class IntelHUD {
const enabledLayers =
this._dataManager
?.getAll?.()
?.filter((layer) => layer.enabled)
.map((layer) => layer.name) || [];
?.filter((layer) => layer.enabled)
.map((layer) => layer.name) || [];
return {
placeLabels: labels.placeLabels,
streetLabels: labels.streetLabels,
@@ -907,7 +919,12 @@ export class IntelHUD {
this._dataManager = dataManager || null;
if (typeof this._dataManager?.subscribe === 'function') {
this._dataManagerUnsubscribe = this._dataManager.subscribe((change) => {
if (['visibility', 'refresh-transition', 'refresh-cancelled'].includes(change?.type)) this._markSummaryDirty();
if (
['visibility', 'refresh-transition', 'refresh-cancelled'].includes(
change?.type,
)
)
this._markSummaryDirty();
});
}
this._markSummaryDirty();
+9 -4
View File
@@ -30,8 +30,8 @@ export function keylessHudSummaryResponse(apiKey) {
export function isHudSummaryUnconfigured(status, data) {
const keys =
data !== null && typeof data === 'object' && !Array.isArray(data)
? Object.keys(data)
: [];
? Object.keys(data)
: [];
return (
keys.length === 4 &&
status === 200 &&
@@ -93,7 +93,9 @@ export function hudTelemetryProvenanceTag(layers = [], options) {
const envelope = feedProvenanceEnvelope(snapshots, options);
if (!envelope.overall || envelope.overall === 'nominal') return null;
const names = envelope.layers
.filter((s) => s.feedState && s.feedState !== 'nominal' && s.feedState !== 'off')
.filter(
(s) => s.feedState && s.feedState !== 'nominal' && s.feedState !== 'off',
)
.map((s) => String(s.name || s.id || 'LAYER').toUpperCase())
.slice(0, 2);
return `${envelope.overall.toUpperCase()}${names.length ? ` ${names.join('/')}` : ''}`;
@@ -103,5 +105,8 @@ export function hudTelemetryProvenanceTag(layers = [], options) {
export function hudSummaryMatchesProvenance(summary, provenance) {
const state = provenance?.overall;
if (!state || state === 'nominal' || state === 'off') return true;
return String(summary || '').toUpperCase().split(/\W+/).includes(String(state).toUpperCase());
return String(summary || '')
.toUpperCase()
.split(/\W+/)
.includes(String(state).toUpperCase());
}
+309 -223
View File
@@ -1,4 +1,8 @@
import { layerSnapshot, layerSnapshots, feedProvenanceEnvelope } from '../data/layerSnapshot.js';
import {
layerSnapshot,
layerSnapshots,
feedProvenanceEnvelope,
} from '../data/layerSnapshot.js';
import { readLayerLifecycleSummary } from './layerSummary.js';
export { readLayerLifecycleSummary } from './layerSummary.js';
import { defaultGeospatial } from '../search/defaults.js';
@@ -300,7 +304,7 @@ function cachesFor(service) {
service.signal?.addEventListener(
'abort',
() => {
for (const cache of Object.values(caches)) cache.clear();
for (const cache of Object.values(caches)) cache.clear();
},
{ once: true },
);
@@ -519,16 +523,16 @@ export function createGevActionRunner({
...(args.locationQuery ? { query: args.locationQuery } : {}),
...(hasCoordinates
? {
latitude: Number(args.latitude),
longitude: Number(args.longitude),
latitude: Number(args.latitude),
longitude: Number(args.longitude),
}
: {}),
};
const layer = await runGevAction(
'set_layer_visibility',
{
layerId,
enabled: true,
layerId,
enabled: true,
},
runOptions,
);
@@ -712,10 +716,10 @@ export function createGevActionRunner({
}
const cancellationState = () =>
withContextModeVocabulary(
typeof styleManager.getContextModeState === 'function'
? styleManager.getContextModeState()
: {},
);
typeof styleManager.getContextModeState === 'function'
? styleManager.getContextModeState()
: {},
);
if (!current()) {
return {
ok: false,
@@ -731,8 +735,8 @@ export function createGevActionRunner({
const result = await styleManager.setContextMode(
mode === 'off' ? null : mode,
{
signal: runOptions.signal,
isCurrent: runOptions.isCurrent,
signal: runOptions.signal,
isCurrent: runOptions.isCurrent,
},
);
if (!current() && result?.ok !== true) {
@@ -803,8 +807,8 @@ export function createGevActionRunner({
rollbackTarget = styleManager.getAircraftTrackingTarget?.() || null;
const contextState =
typeof styleManager.getContextModeState === 'function'
? styleManager.getContextModeState()
: {};
? styleManager.getContextModeState()
: {};
priorContextMode = contextState?.mode || null;
const contactsReady =
contextState?.mode === 'flights' &&
@@ -824,8 +828,8 @@ export function createGevActionRunner({
if (contextResult?.ok !== true || !current()) {
const contextRollback = contextChangedForEntry
? await styleManager.setContextMode(priorContextMode, {
claimVisualAuthority: false,
})
claimVisualAuthority: false,
})
: null;
return {
ok: false,
@@ -873,12 +877,12 @@ export function createGevActionRunner({
const contextRollback = await styleManager.setContextMode(
priorContextMode,
{
// Undoing this action's own precondition — still choreography.
claimVisualAuthority: false,
// Undoing this action's own precondition — still choreography.
claimVisualAuthority: false,
...(current()
? {
signal: runOptions.signal,
isCurrent: runOptions.isCurrent,
signal: runOptions.signal,
isCurrent: runOptions.isCurrent,
}
: {}),
},
@@ -896,8 +900,8 @@ export function createGevActionRunner({
setPanelOpen(styleManager, 'data-panel', true);
const focusedLayer =
layerId && dataManager.layers.has(layerId)
? focusDataLayerRow(layerId)
: null;
? focusDataLayerRow(layerId)
: null;
return {
ok: true,
action: 'show_data_layers_menu',
@@ -907,10 +911,10 @@ export function createGevActionRunner({
.getAll()
.filter((layer) => layer.showInTogglePanel !== false)
.map((layer) => ({
id: layer.id,
name: layer.name,
enabled: layer.enabled,
count: layer.stats?.count || 0,
id: layer.id,
name: layer.name,
enabled: layer.enabled,
count: layer.stats?.count || 0,
})),
};
}
@@ -924,16 +928,16 @@ export function createGevActionRunner({
typeof styleManager?.runImmediateLocationNavigation === 'function'
? (navigate) =>
styleManager.runImmediateLocationNavigation(navigate)
: null,
: null,
beginDeferred:
typeof styleManager?.beginDeferredLocationNavigation === 'function'
? () => styleManager.beginDeferredLocationNavigation()
: null,
? () => styleManager.beginDeferredLocationNavigation()
: null,
reassertDeferred:
typeof styleManager?.reassertDeferredLocationNavigation === 'function'
? (generation) =>
styleManager.reassertDeferredLocationNavigation(generation)
: null,
: null,
onStart: () => {
if (typeof styleManager?.beginLocationNavigation === 'function') {
styleManager.beginLocationNavigation();
@@ -1180,8 +1184,8 @@ function sanitizeAnnotationSpec(spec) {
out.points = out.points
.slice(0, MAX_ROUTE_POINTS)
.map((p) =>
p && typeof p === 'object' && typeof p.target === 'string'
? { ...p, target: clampStr(p.target, MAX_TARGET_LEN) }
p && typeof p === 'object' && typeof p.target === 'string'
? { ...p, target: clampStr(p.target, MAX_TARGET_LEN) }
: p,
);
}
@@ -1644,8 +1648,8 @@ export async function controlRadio(
// viewport's nearest station.
const action =
requestedAction === 'play' && hasSelectionCriteria
? 'select'
: requestedAction;
? 'select'
: requestedAction;
const readRadioLifecycle = () =>
readLayerLifecycleSummary(dataManager, 'radio');
@@ -1666,11 +1670,11 @@ export async function controlRadio(
const intentSummary = () =>
lastIntentOutcome
? {
phase: lastIntentOutcome.phase,
cancellationReason: lastIntentOutcome.cancellationReason || null,
successorIntentEpoch: lastIntentOutcome.successorIntentEpoch ?? null,
successorEnabled: lastIntentOutcome.successorEnabled ?? null,
successorOrigin: lastIntentOutcome.successorOrigin ?? null,
phase: lastIntentOutcome.phase,
cancellationReason: lastIntentOutcome.cancellationReason || null,
successorIntentEpoch: lastIntentOutcome.successorIntentEpoch ?? null,
successorEnabled: lastIntentOutcome.successorEnabled ?? null,
successorOrigin: lastIntentOutcome.successorOrigin ?? null,
}
: {};
@@ -1832,7 +1836,7 @@ export async function controlRadio(
{ volume: volumePct / 100 },
{ origin: 'voice' },
)
: radio.setVolume(volumePct / 100);
: radio.setVolume(volumePct / 100);
if (volumeApplied === false) {
return {
ok: false,
@@ -1970,12 +1974,12 @@ export async function controlRadio(
if (!radioActionIsCurrent(options)) return cancelled(summarize);
const station = radio.selectRequestedStation?.(
{
categoryId: String(args.category || 'all'),
anchor: location ? { lat: location.lat, lon: location.lon } : null,
country: normalizedCountry.empty
? String(location?.country || '')
: normalizedCountry.code,
stationQuery: String(args.stationQuery || ''),
categoryId: String(args.category || 'all'),
anchor: location ? { lat: location.lat, lon: location.lon } : null,
country: normalizedCountry.empty
? String(location?.country || '')
: normalizedCountry.code,
stationQuery: String(args.stationQuery || ''),
},
{ autoplay: false },
);
@@ -2097,23 +2101,23 @@ async function trackEntity(viewer, dataManager, styleManager, args = {}) {
'fire',
'track_entity',
() => {
flyToLandmark(viewer, strongest.latitude, strongest.longitude, {
flyToLandmark(viewer, strongest.latitude, strongest.longitude, {
range: 14000,
pitch: -50,
heading: 0,
buildingHeight: 0,
duration: 2.2,
});
return {
});
return {
ok: true,
action: 'track_entity',
kind: 'fire',
layerId: 'local-firms',
label: strongest.label || 'Strongest fire',
label: strongest.label || 'Strongest fire',
latitude: strongest.latitude,
longitude: strongest.longitude,
frp: strongest.frp ?? null,
};
frp: strongest.frp ?? null,
};
},
);
}
@@ -2152,39 +2156,39 @@ async function trackEntity(viewer, dataManager, styleManager, args = {}) {
family.kind,
'track_entity',
() => {
let trackedOk = false;
if (family.kind === 'vessel') {
trackedOk = !!module.selectById?.(found.mmsi);
flyToLandmark(viewer, found.latitude, found.longitude, {
let trackedOk = false;
if (family.kind === 'vessel') {
trackedOk = !!module.selectById?.(found.mmsi);
flyToLandmark(viewer, found.latitude, found.longitude, {
range: 6000,
pitch: -45,
heading: 0,
buildingHeight: 0,
duration: 2.0,
});
} else if (family.kind === 'satellite') {
trackedOk = !!module.trackById?.(found.noradId, { origin: 'voice' });
} else {
trackedOk = !!module.trackById?.(found.icao24, { origin: 'voice' });
}
});
} else if (family.kind === 'satellite') {
trackedOk = !!module.trackById?.(found.noradId, { origin: 'voice' });
} else {
trackedOk = !!module.trackById?.(found.icao24, { origin: 'voice' });
}
return {
ok: trackedOk,
action: 'track_entity',
layerId: family.layerId,
kind: family.kind,
// Aircraft follow the flight layers' label convention (callsign →
// registration → icao24) so the spoken name matches what the UI shows;
// `registration` is absent on vessels/satellites and simply falls
// through to their own name/id links.
label: formatTrackedEntityLabel(found, query),
latitude: found.latitude ?? null,
longitude: found.longitude ?? null,
return {
ok: trackedOk,
action: 'track_entity',
layerId: family.layerId,
kind: family.kind,
// Aircraft follow the flight layers' label convention (callsign →
// registration → icao24) so the spoken name matches what the UI shows;
// `registration` is absent on vessels/satellites and simply falls
// through to their own name/id links.
label: formatTrackedEntityLabel(found, query),
latitude: found.latitude ?? null,
longitude: found.longitude ?? null,
altitudeM: Number.isFinite(found.altitudeM)
? Math.round(found.altitudeM)
: null,
error: trackedOk ? null : 'Match found but tracking failed',
};
error: trackedOk ? null : 'Match found but tracking failed',
};
},
);
}
@@ -2337,40 +2341,40 @@ async function frameOverhead(viewer, dataManager, styleManager, args = {}) {
'frame',
'frame_overhead',
() => {
viewer.camera.flyToBoundingSphere(sphere, {
duration: 2.0,
viewer.camera.flyToBoundingSphere(sphere, {
duration: 2.0,
offset: new Cesium.HeadingPitchRange(
viewer.camera.heading,
pitch,
sphere.radius * 2.4,
),
});
});
let detectionEnabled = false;
try {
const detectionState = styleManager?.getDetectionState?.();
if (detectionState?.detectionMode === 'OFF') {
const detectionResult = styleManager.setDetection({ mode: 'dense' });
detectionEnabled = detectionResult?.ok === true;
} else if (detectionState) {
detectionEnabled = true;
let detectionEnabled = false;
try {
const detectionState = styleManager?.getDetectionState?.();
if (detectionState?.detectionMode === 'OFF') {
const detectionResult = styleManager.setDetection({ mode: 'dense' });
detectionEnabled = detectionResult?.ok === true;
} else if (detectionState) {
detectionEnabled = true;
}
} catch {
// detection facade unavailable; framing still succeeded
}
} catch {
// detection facade unavailable; framing still succeeded
}
return {
ok: true,
action: 'frame_overhead',
layerId,
radiusKm: Math.round(radiusKm),
count: entries.length,
detectionEnabled,
nearest: entries.slice(0, 5).map((entry) => ({
id: entry.id || entry.icao24 || entry.mmsi || null,
label: entry.label || entry.callsign || entry.name || null,
})),
};
return {
ok: true,
action: 'frame_overhead',
layerId,
radiusKm: Math.round(radiusKm),
count: entries.length,
detectionEnabled,
nearest: entries.slice(0, 5).map((entry) => ({
id: entry.id || entry.icao24 || entry.mmsi || null,
label: entry.label || entry.callsign || entry.name || null,
})),
};
},
);
}
@@ -2491,8 +2495,8 @@ export async function getBasemapLabelContext(
]).slice(0, 16),
nearbyPlaceLabels: uniqueStrings(
(nearbyPlaces || []).flatMap((nearbyPlace) => [
nearbyPlace.name,
nearbyPlace.address,
nearbyPlace.name,
nearbyPlace.address,
]),
).slice(0, 24),
};
@@ -2661,7 +2665,8 @@ function nextIssPass(viewer, dataManager, args) {
peakElevationDeg: Math.round(pass.maxElevDeg),
riseDirection: compassDir(pass.riseAzDeg),
visible: typeof pass.visible === 'boolean' ? pass.visible : null,
visibilityNote: 'Geometric illumination estimate only; weather, brightness and orbital-element age affect actual visibility.',
visibilityNote:
'Geometric illumination estimate only; weather, brightness and orbital-element age affect actual visibility.',
setIso: new Date(pass.setMs).toISOString(),
peakIso: new Date(pass.maxElevMs).toISOString(),
};
@@ -2669,22 +2674,55 @@ function nextIssPass(viewer, dataManager, args) {
function nextSatellitePass(viewer, dataManager, args) {
const layer = dataManager?.layers?.get('satellites')?.module;
const identity = layer?.resolveSatelliteForPass?.(args.target) || { status: 'not-found' };
if (identity.status !== 'ok') return {
ok: false, action: 'next_satellite_pass', ...identity,
error: identity.status === 'ambiguous' ? 'Several loaded satellites match. Choose a NORAD ID from candidates.' : 'No loaded satellite matches. Enable satellites and use an exact name or NORAD ID.',
const identity = layer?.resolveSatelliteForPass?.(args.target) || {
status: 'not-found',
};
if (identity.status !== 'ok')
return {
ok: false,
action: 'next_satellite_pass',
...identity,
error:
identity.status === 'ambiguous'
? 'Several loaded satellites match. Choose a NORAD ID from candidates.'
: 'No loaded satellite matches. Enable satellites and use an exact name or NORAD ID.',
};
// Reuse the legacy location fallback and result formatting, substituting only
// this explicitly resolved catalog identity and the optional visibility filter.
const adapter = { layers: new Map([['satellites', { module: {
getNextIssPass: (options) => layer.getNextSatellitePass(identity.noradId, { ...options, requireVisible: args.visibleOnly === true }),
} }]]) };
const adapter = {
layers: new Map([
[
'satellites',
{
module: {
getNextIssPass: (options) =>
layer.getNextSatellitePass(identity.noradId, {
...options,
requireVisible: args.visibleOnly === true,
}),
},
},
],
]),
};
const result = nextIssPass(viewer, adapter, args);
if (result.error) {
result.error = result.error.replace(/ISS/g, identity.name || String(identity.noradId));
if (args.visibleOnly === true) result.error += ' Search required estimated illumination under a dark sky.';
result.error = result.error.replace(
/ISS/g,
identity.name || String(identity.noradId),
);
if (args.visibleOnly === true)
result.error +=
' Search required estimated illumination under a dark sky.';
}
return { ...result, action: 'next_satellite_pass', noradId: identity.noradId, name: identity.name, visibleOnly: args.visibleOnly === true, horizonHours: 24 };
return {
...result,
action: 'next_satellite_pass',
noradId: identity.noradId,
name: identity.name,
visibleOnly: args.visibleOnly === true,
horizonHours: 24,
};
}
function normalizePanelId(value) {
@@ -2716,21 +2754,21 @@ function normalizeCockpitNavigationHints(rawAction) {
const targetLayer =
raw.includes('vessel') || raw.includes('ship') || raw.includes('ais')
? 'ais-live-vessels'
? 'ais-live-vessels'
: raw.includes('installation') ||
raw.includes('facility') ||
raw.includes('base')
? 'military-installations'
: raw.includes('military')
? 'military'
: null;
? 'military-installations'
: raw.includes('military')
? 'military'
: null;
const aircraftClass =
raw.includes('helicopter') ||
raw.includes('helo') ||
raw.includes('chopper')
? 'helicopter'
: null;
? 'helicopter'
: null;
return {
targetLayer,
@@ -2839,10 +2877,10 @@ async function flyToRequestedLocation(
placeSearch = unavailablePlaceSearch,
searchNavigation = searchAndFlyTo,
signal,
onStart = null,
runImmediate = null,
beginDeferred = null,
reassertDeferred = null,
onStart = null,
runImmediate = null,
beginDeferred = null,
reassertDeferred = null,
} = {},
) {
const requestedRangeM = Number(args.rangeM);
@@ -2865,11 +2903,11 @@ async function flyToRequestedLocation(
? new Promise((resolve) => {
settleArrival = resolve;
})
: null;
: null;
const arrivalHooks = arrival
? {
onComplete: () => settleArrival?.('arrived'),
onCancel: () => settleArrival?.('cancelled'),
onComplete: () => settleArrival?.('arrived'),
onCancel: () => settleArrival?.('cancelled'),
}
: {};
const afterArrival = async (result, label) => {
@@ -2884,12 +2922,12 @@ async function flyToRequestedLocation(
if (locationId) {
const result = immediate(() =>
flyToPresetLocation(viewer, locationId, {
...(rangeM || args.viewMode === 'close'
? { range: rangeM || 250 }
: { viewMode: 'overview' }),
duration: 2.2,
onStart: immediateOnStart,
...arrivalHooks,
...(rangeM || args.viewMode === 'close'
? { range: rangeM || 250 }
: { viewMode: 'overview' }),
duration: 2.2,
onStart: immediateOnStart,
...arrivalHooks,
}),
);
if (result === false)
@@ -2914,13 +2952,13 @@ async function flyToRequestedLocation(
if (Number.isFinite(latitude) && Number.isFinite(longitude)) {
const result = immediate(() =>
flyToLandmark(viewer, latitude, longitude, {
range: rangeM || 250,
pitch: -35,
heading: 0,
buildingHeight: 0,
duration: 2.2,
onStart: immediateOnStart,
...arrivalHooks,
range: rangeM || 250,
pitch: -35,
heading: 0,
buildingHeight: 0,
duration: 2.2,
onStart: immediateOnStart,
...arrivalHooks,
}),
);
if (result === false)
@@ -2946,10 +2984,10 @@ async function flyToRequestedLocation(
if (poiMatch) {
const result = immediate(() =>
flyToPOI(viewer, poiMatch.cityId, poiMatch.index, {
duration: 2.2,
onStart: immediateOnStart,
...arrivalHooks,
...(rangeM ? { range: rangeM } : {}),
duration: 2.2,
onStart: immediateOnStart,
...arrivalHooks,
...(rangeM ? { range: rangeM } : {}),
}),
);
const poi = CITY_POIS[poiMatch.cityId]?.pois?.[poiMatch.index];
@@ -3029,19 +3067,19 @@ function getCurrentViewState(
style: styleManager.activeStyle || 'normal',
context:
typeof styleManager.getContextModeState === 'function'
? {
...withContextModeVocabulary(styleManager.getContextModeState()),
// The numbers on the operator's Contacts panel, so a window/count
// question can be answered from what they are looking at.
? {
...withContextModeVocabulary(styleManager.getContextModeState()),
// The numbers on the operator's Contacts panel, so a window/count
// question can be answered from what they are looking at.
...(activeContactsWindow(dataManager)
? { contactsWindow: activeContactsWindow(dataManager) }
: {}),
}
: null,
}
: null,
cockpit:
typeof styleManager.getCockpitState === 'function'
? styleManager.getCockpitState()
: null,
? styleManager.getCockpitState()
: null,
controls:
typeof styleManager.getControlState === 'function'
? styleManager.getControlState()
@@ -3058,7 +3096,9 @@ function getCurrentViewState(
source: layerSnapshot(layer).source,
lastUpdate: layerSnapshot(layer).lastUpdate,
})),
feedProvenance: feedProvenanceEnvelope(layerSnapshots(dataManager.getAll()).filter((layer) => layer.enabled)),
feedProvenance: feedProvenanceEnvelope(
layerSnapshots(dataManager.getAll()).filter((layer) => layer.enabled),
),
};
}
@@ -3092,7 +3132,7 @@ async function getEntityContext(
limit,
target: viewTarget,
})
: [];
: [];
const scene = await scenePromise;
if ((scope === 'selected' || scope === 'auto') && selected) {
@@ -3178,14 +3218,14 @@ function aircraftProximityWindowForQuery(dataManager, args, result) {
items: items
.slice(0, Math.round(clampNumber(args.limit, 1, 50, 12)))
.map((item) => ({
layerKey: item.layerKey,
id: item.id,
...(item.icao24 ? { icao24: item.icao24 } : {}),
...(item.callsign ? { callsign: item.callsign } : {}),
layerKey: item.layerKey,
id: item.id,
...(item.icao24 ? { icao24: item.icao24 } : {}),
...(item.callsign ? { callsign: item.callsign } : {}),
...(Number.isFinite(item.distance)
? { distanceKm: Math.round(item.distance / 100) / 10 }
: {}),
})),
})),
summary: { count },
coverage: {
layersQueried: result?.coverage?.layersQueried || [],
@@ -3283,15 +3323,15 @@ function visibleEntityContexts(
insertNearestRecord(
nearbyRecords,
{
record,
distanceScore: target
record,
distanceScore: target
? approximateCoordinateDistanceSq(
targetLat,
targetLon,
record.latitude,
record.longitude,
)
: 0,
: 0,
},
VISIBLE_ENTITY_SHORTLIST,
);
@@ -3448,16 +3488,16 @@ async function getBasemapContext(
const cachedNearbyPlaces =
shouldFetchNearbyPlaces(cameraHeightM) &&
nearbyPlacesCache.has(nearbyCacheKey)
? nearbyPlacesCache.get(nearbyCacheKey)
: null;
? nearbyPlacesCache.get(nearbyCacheKey)
: null;
const placePromise =
shouldReverseGeocode(cameraHeightM) && !cachedPlace
? reverseGeocode(latitude, longitude, service)
: Promise.resolve(cachedPlace);
? reverseGeocode(latitude, longitude, service)
: Promise.resolve(cachedPlace);
const nearbyPlacesPromise =
shouldFetchNearbyPlaces(cameraHeightM) && !cachedNearbyPlaces
? fetchNearbyPlaces(latitude, longitude, cameraHeightM, service)
: Promise.resolve(cachedNearbyPlaces);
? fetchNearbyPlaces(latitude, longitude, cameraHeightM, service)
: Promise.resolve(cachedNearbyPlaces);
const [viewportPlaces, resolvedPlace, resolvedNearbyPlaces] =
await Promise.all([
resolveWithin(
@@ -3465,13 +3505,13 @@ async function getBasemapContext(
BASEMAP_CONTEXT_WAIT_MS,
cachedViewportPlaces,
),
resolveWithin(placePromise, BASEMAP_CONTEXT_WAIT_MS, cachedPlace),
resolveWithin(placePromise, BASEMAP_CONTEXT_WAIT_MS, cachedPlace),
resolveWithin(
nearbyPlacesPromise,
BASEMAP_CONTEXT_WAIT_MS,
cachedNearbyPlaces,
),
]);
]);
const place = resolvedPlace || fallbackPlace;
const nearbyPlaces = resolvedNearbyPlaces || [];
return {
@@ -3516,12 +3556,12 @@ function nearbyKnownLandmarks(latitude, longitude, cameraHeightM) {
if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) return [];
const maxDistanceKm =
cameraHeightM <= 5000
? 2
: cameraHeightM <= 50000
? 10
: cameraHeightM <= 250000
? 35
: 0;
? 2
: cameraHeightM <= 50000
? 10
: cameraHeightM <= 250000
? 35
: 0;
if (maxDistanceKm <= 0) return [];
const matches = [];
@@ -3752,9 +3792,9 @@ function inferCountry(latitude, longitude) {
];
const region = regions.find(
(item) =>
latitude >= item.south &&
latitude <= item.north &&
longitude >= item.west &&
latitude >= item.south &&
latitude <= item.north &&
longitude >= item.west &&
longitude <= item.east,
);
return region?.name || null;
@@ -3802,18 +3842,18 @@ async function reverseGeocodeViewportSamples(samples, cameraHeightM, service) {
sample.longitude,
service,
);
if (!place) return null;
return {
latitude: sample.latitude,
longitude: sample.longitude,
formattedAddress: place.formattedAddress,
locality: place.locality,
region: place.region,
country: place.country,
types: place.types,
labels: place.labels,
streetLabels: place.streetLabels,
};
if (!place) return null;
return {
latitude: sample.latitude,
longitude: sample.longitude,
formattedAddress: place.formattedAddress,
locality: place.locality,
region: place.region,
country: place.country,
types: place.types,
labels: place.labels,
streetLabels: place.streetLabels,
};
}),
)
).filter(Boolean);
@@ -3834,21 +3874,21 @@ function viewportPlacesFromCache(samples, cameraHeightM, service) {
const place = reverseGeocodeCache.get(
reverseGeocodeKey(sample.latitude, sample.longitude, service),
);
if (!place) return [];
if (!place) return [];
return [
{
latitude: sample.latitude,
longitude: sample.longitude,
formattedAddress: place.formattedAddress,
locality: place.locality,
region: place.region,
country: place.country,
types: place.types,
labels: place.labels,
streetLabels: place.streetLabels,
latitude: sample.latitude,
longitude: sample.longitude,
formattedAddress: place.formattedAddress,
locality: place.locality,
region: place.region,
country: place.country,
types: place.types,
labels: place.labels,
streetLabels: place.streetLabels,
},
];
});
});
return summarizeViewportPlaces(places);
}
@@ -4008,12 +4048,12 @@ function summarizeEntity(viewer, entity, { includeProperties = false } = {}) {
const tags = props.tags || {};
const label = cleanText(
props.name ||
tags.name ||
tags['name:en'] ||
tags.official_name ||
tags.operator ||
props.operator ||
entity.name ||
tags.name ||
tags['name:en'] ||
tags.official_name ||
tags.operator ||
props.operator ||
entity.name ||
layerTitle(layerId),
);
const position =
@@ -4073,8 +4113,8 @@ function unwrapProperties(value) {
for (const [key, entry] of Object.entries(value)) {
out[key] =
entry && typeof entry.getValue === 'function'
? unwrapProperties(entry.getValue(Cesium.JulianDate.now()))
: unwrapProperties(entry);
? unwrapProperties(entry.getValue(Cesium.JulianDate.now()))
: unwrapProperties(entry);
}
return out;
}
@@ -4189,10 +4229,15 @@ function analystProviders(
const row = dataManager.getAll?.().find((layer) => layer.id === layerKey);
if (row) return layerSnapshot(row);
const module = dataManager.layers?.get(layerKey)?.module;
return layerSnapshot({ id: layerKey, enabled: dataManager.isEnabled?.(layerKey), stats: module?.getStats?.() || {} });
return layerSnapshot({
id: layerKey,
enabled: dataManager.isEnabled?.(layerKey),
stats: module?.getStats?.() || {},
});
},
getRecordCoverage(layerKey, rows) {
if (!['satellites', 'local-datacenters', 'local-dams'].includes(layerKey)) return null;
if (!['satellites', 'local-datacenters', 'local-dams'].includes(layerKey))
return null;
const module = dataManager.layers.get(layerKey)?.module;
const loaded = module?.getStats?.().count;
return {
@@ -4271,7 +4316,36 @@ async function runAnalystQuery(
// model burned the turn on retries (owner field session 2026-08-21, 23:48).
const items = result.items.map((r) => {
const compact = { layerKey: r.layerKey, id: r.id };
for (const k of ['icao24', 'mmsi', 'registration', 'label', 'callsign', 'name', 'altitudeM', 'speedMps', 'speedKts', 'frp', 'magnitude', 'shipType', 'destination', 'operator', 'routeOrigin', 'routeDestination', 'aircraftClass', 'military', 'onGround', 'distanceKm', 'confidence', 'place', 'noradId', 'satelliteClass', 'group', 'river', 'output', 'capacity']) {
for (const k of [
'icao24',
'mmsi',
'registration',
'label',
'callsign',
'name',
'altitudeM',
'speedMps',
'speedKts',
'frp',
'magnitude',
'shipType',
'destination',
'operator',
'routeOrigin',
'routeDestination',
'aircraftClass',
'military',
'onGround',
'distanceKm',
'confidence',
'place',
'noradId',
'satelliteClass',
'group',
'river',
'output',
'capacity',
]) {
if (r[k] !== null && r[k] !== undefined) compact[k] = r[k];
}
return compact;
@@ -4305,10 +4379,22 @@ async function runAnalystQuery(
// differ. The generic record/scope engine still owns explicit regions and
// arbitrary points — only "how many aircraft around <this contact>" is
// unified, because that is the question the panel is already answering.
const entityWindow = aircraftProximityWindowForQuery(dataManager, args, result);
const entityWindow = aircraftProximityWindowForQuery(
dataManager,
args,
result,
);
if (entityWindow) {
const provenance = feedProvenanceEnvelope(layerSnapshots(dataManager.getAll?.() || []).filter((layer) => layer.enabled && ['flights', 'military'].includes(layer.id)));
return { ...entityWindow, feedProvenance: provenance, feedState: provenance.overall };
const provenance = feedProvenanceEnvelope(
layerSnapshots(dataManager.getAll?.() || []).filter(
(layer) => layer.enabled && ['flights', 'military'].includes(layer.id),
),
);
return {
...entityWindow,
feedProvenance: provenance,
feedState: provenance.overall,
};
}
const contactsWindow = activeContactsWindow(dataManager);
@@ -4336,7 +4422,7 @@ async function runAnalystQuery(
`${contactsWindow.radiusKm} km of ${contactsWindow.centeredOn}, and that is the answer to a bare ` +
`"how many aircraft are nearby". This query measured something else — ${result.count} ${result.scopeLabel}. ` +
'Give this one only if the operator asked about that specific area, and name both scopes if you give both.'
: null;
: null;
return {
ok: true,
action: 'analyst_query',
@@ -4356,10 +4442,10 @@ async function runAnalystQuery(
// missed inside a nested shape.
...(contactsWindow && aircraftQueried
? {
contactsWindow,
contactsWindowCount: windowAircraft,
contactsWindowSubject: contactsWindow.centeredOn || null,
}
contactsWindow,
contactsWindowCount: windowAircraft,
contactsWindowSubject: contactsWindow.centeredOn || null,
}
: {}),
...(countsReconciliation ? { countsReconciliation } : {}),
};