Spaces:
Sleeping
Sleeping
Zhen Ye Claude Opus 4.6 commited on
Commit ·
28965e8
1
Parent(s): d737b59
refactor: remove remaining dead HEL/threat code remnants
Browse filesStrip leftover HEL fields (aim, baseRange, pkill, dwellAccum, etc.)
from main.js, tracker.js, physics.js, state.js, video.js. Remove dead
UI elements (btnRecompute, chipPolicy, chipBeam, chipHz, dwell bar)
from index.html. Update schema/parser ASSESS_THREAT → EVALUATE.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- frontend/index.html +1 -16
- frontend/js/core/physics.js +0 -39
- frontend/js/core/state.js +1 -6
- frontend/js/core/tracker.js +0 -14
- frontend/js/core/video.js +0 -3
- frontend/js/main.js +1 -31
- frontend/style.css +2 -2
- utils/mission_parser.py +2 -2
- utils/schemas.py +4 -4
frontend/index.html
CHANGED
|
@@ -150,7 +150,6 @@
|
|
| 150 |
<div class="btnrow" style="margin-top:10px">
|
| 151 |
<button id="btnReason" class="btn">Detect</button>
|
| 152 |
<button id="btnCancelReason" class="btn danger" style="display: none;">Cancel</button>
|
| 153 |
-
<button id="btnRecompute" class="btn secondary">Reanalyze</button>
|
| 154 |
<button id="btnClear" class="btn secondary">Clear</button>
|
| 155 |
</div>
|
| 156 |
|
|
@@ -175,7 +174,7 @@
|
|
| 175 |
</div>
|
| 176 |
</div>
|
| 177 |
|
| 178 |
-
<!--
|
| 179 |
<div class="panel panel-chat" id="chatPanel">
|
| 180 |
<h3>
|
| 181 |
<span>Mission Analyst</span>
|
|
@@ -233,24 +232,10 @@
|
|
| 233 |
</div>
|
| 234 |
|
| 235 |
<div class="strip mt-md">
|
| 236 |
-
<span class="chip" id="chipPolicy">POLICY:AUTO</span>
|
| 237 |
<span class="chip" id="chipTracks">TRACKS:0</span>
|
| 238 |
-
<span class="chip" id="chipBeam">MODE:AUTO</span>
|
| 239 |
-
<span class="chip" id="chipHz">DET:6Hz</span>
|
| 240 |
<span class="chip" id="chipFeed" title="Toggle raw vs HF-processed feed (if available)">FEED:RAW</span>
|
| 241 |
<span class="chip" id="chipDepth" title="Toggle depth view (if available)" style="display:none">VIEW:DEFAULT</span>
|
| 242 |
</div>
|
| 243 |
-
|
| 244 |
-
<div class="mt-md">
|
| 245 |
-
<div class="row"><label>Active track progress (selected)</label><small class="mini"
|
| 246 |
-
id="dwellText">—</small>
|
| 247 |
-
</div>
|
| 248 |
-
<div class="bar">
|
| 249 |
-
<div id="dwellBar"></div>
|
| 250 |
-
</div>
|
| 251 |
-
</div>
|
| 252 |
-
|
| 253 |
-
<div class="hint mt-md">Manual selection: choose "Manual" in Policy, then click a target in the video.</div>
|
| 254 |
</div>
|
| 255 |
|
| 256 |
<div class="engage-right">
|
|
|
|
| 150 |
<div class="btnrow" style="margin-top:10px">
|
| 151 |
<button id="btnReason" class="btn">Detect</button>
|
| 152 |
<button id="btnCancelReason" class="btn danger" style="display: none;">Cancel</button>
|
|
|
|
| 153 |
<button id="btnClear" class="btn secondary">Clear</button>
|
| 154 |
</div>
|
| 155 |
|
|
|
|
| 174 |
</div>
|
| 175 |
</div>
|
| 176 |
|
| 177 |
+
<!-- Mission Analyst Chat Panel -->
|
| 178 |
<div class="panel panel-chat" id="chatPanel">
|
| 179 |
<h3>
|
| 180 |
<span>Mission Analyst</span>
|
|
|
|
| 232 |
</div>
|
| 233 |
|
| 234 |
<div class="strip mt-md">
|
|
|
|
| 235 |
<span class="chip" id="chipTracks">TRACKS:0</span>
|
|
|
|
|
|
|
| 236 |
<span class="chip" id="chipFeed" title="Toggle raw vs HF-processed feed (if available)">FEED:RAW</span>
|
| 237 |
<span class="chip" id="chipDepth" title="Toggle depth view (if available)" style="display:none">VIEW:DEFAULT</span>
|
| 238 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 239 |
</div>
|
| 240 |
|
| 241 |
<div class="engage-right">
|
frontend/js/core/physics.js
CHANGED
|
@@ -16,42 +16,3 @@ APP.core.physics.defaultAimpoint = function (label) {
|
|
| 16 |
}
|
| 17 |
return { relx: 0.50, rely: 0.55, label: "center_mass" };
|
| 18 |
};
|
| 19 |
-
|
| 20 |
-
APP.core.physics.aimpointByLabel = function (label) {
|
| 21 |
-
const l = String(label || "").toLowerCase();
|
| 22 |
-
if (l.includes("engine") || l.includes("fuel")) return { relx: 0.64, rely: 0.58, label: label };
|
| 23 |
-
if (l.includes("wing")) return { relx: 0.42, rely: 0.52, label: label };
|
| 24 |
-
if (l.includes("nose") || l.includes("sensor")) return { relx: 0.28, rely: 0.48, label: label };
|
| 25 |
-
if (l.includes("rotor")) return { relx: 0.52, rely: 0.42, label: label };
|
| 26 |
-
return { relx: 0.50, rely: 0.55, label: label || "center_mass" };
|
| 27 |
-
};
|
| 28 |
-
|
| 29 |
-
APP.core.physics.getKnobs = function () {
|
| 30 |
-
const { $ } = APP.core.utils;
|
| 31 |
-
const helPower = $("#helPower");
|
| 32 |
-
const helAperture = $("#helAperture");
|
| 33 |
-
const helM2 = $("#helM2");
|
| 34 |
-
const helJitter = $("#helJitter");
|
| 35 |
-
const helDuty = $("#helDuty");
|
| 36 |
-
const helMode = $("#helMode");
|
| 37 |
-
const atmVis = $("#atmVis");
|
| 38 |
-
const atmCn2 = $("#atmCn2");
|
| 39 |
-
const seaSpray = $("#seaSpray");
|
| 40 |
-
const aoQ = $("#aoQ");
|
| 41 |
-
const rangeBase = $("#rangeBase");
|
| 42 |
-
|
| 43 |
-
if (!helPower) return {};
|
| 44 |
-
|
| 45 |
-
const PkW = +helPower.value;
|
| 46 |
-
const aperture = +helAperture.value;
|
| 47 |
-
const M2 = +helM2.value;
|
| 48 |
-
const jitter_urad = +helJitter.value;
|
| 49 |
-
const duty = (+helDuty.value) / 100;
|
| 50 |
-
const mode = helMode ? helMode.value : "cw";
|
| 51 |
-
const vis_km = +atmVis.value;
|
| 52 |
-
const cn2 = +atmCn2.value;
|
| 53 |
-
const spray = +seaSpray.value;
|
| 54 |
-
const ao = +aoQ.value;
|
| 55 |
-
const baseRange = +rangeBase.value;
|
| 56 |
-
return { PkW, aperture, M2, jitter_urad, duty, mode, vis_km, cn2, spray, ao, baseRange };
|
| 57 |
-
};
|
|
|
|
| 16 |
}
|
| 17 |
return { relx: 0.50, rely: 0.55, label: "center_mass" };
|
| 18 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
frontend/js/core/state.js
CHANGED
|
@@ -32,9 +32,7 @@ APP.core.state = {
|
|
| 32 |
summary: null,
|
| 33 |
busy: false,
|
| 34 |
lastError: null,
|
| 35 |
-
|
| 36 |
-
missionSpec: null,
|
| 37 |
-
plan: null
|
| 38 |
},
|
| 39 |
|
| 40 |
detector: {
|
|
@@ -55,7 +53,6 @@ APP.core.state = {
|
|
| 55 |
lastHFSync: 0,
|
| 56 |
running: false,
|
| 57 |
selectedTrackId: null,
|
| 58 |
-
beamOn: false,
|
| 59 |
lastFrameTime: 0,
|
| 60 |
frameCount: 0,
|
| 61 |
_lastCardRenderFrame: 0, // Frame count at last card render
|
|
@@ -72,8 +69,6 @@ APP.core.state = {
|
|
| 72 |
detections: [], // from Tab 1
|
| 73 |
selectedId: null,
|
| 74 |
|
| 75 |
-
intelBusy: false,
|
| 76 |
-
|
| 77 |
ui: {
|
| 78 |
cursorMode: "on",
|
| 79 |
agentCursor: { x: 0.65, y: 0.28, vx: 0, vy: 0, visible: false, target: null, mode: "idle", t0: 0 }
|
|
|
|
| 32 |
summary: null,
|
| 33 |
busy: false,
|
| 34 |
lastError: null,
|
| 35 |
+
missionSpec: null
|
|
|
|
|
|
|
| 36 |
},
|
| 37 |
|
| 38 |
detector: {
|
|
|
|
| 53 |
lastHFSync: 0,
|
| 54 |
running: false,
|
| 55 |
selectedTrackId: null,
|
|
|
|
| 56 |
lastFrameTime: 0,
|
| 57 |
frameCount: 0,
|
| 58 |
_lastCardRenderFrame: 0, // Frame count at last card render
|
|
|
|
| 69 |
detections: [], // from Tab 1
|
| 70 |
selectedId: null,
|
| 71 |
|
|
|
|
|
|
|
| 72 |
ui: {
|
| 73 |
cursorMode: "on",
|
| 74 |
agentCursor: { x: 0.65, y: 0.28, vx: 0, vy: 0, visible: false, target: null, mode: "idle", t0: 0 }
|
frontend/js/core/tracker.js
CHANGED
|
@@ -4,11 +4,9 @@ APP.core.tracker.matchAndUpdateTracks = function (dets, dtSec) {
|
|
| 4 |
const { state } = APP.core;
|
| 5 |
const { CONFIG } = APP.core;
|
| 6 |
const { normBBox, lerp, now, $ } = APP.core.utils;
|
| 7 |
-
const { defaultAimpoint } = APP.core.physics;
|
| 8 |
const { log } = APP.ui.logging;
|
| 9 |
|
| 10 |
const videoEngage = $("#videoEngage");
|
| 11 |
-
const rangeBase = $("#rangeBase"); // Fixed Selector
|
| 12 |
|
| 13 |
if (!videoEngage) return;
|
| 14 |
|
|
@@ -115,32 +113,20 @@ APP.core.tracker.matchAndUpdateTracks = function (dets, dtSec) {
|
|
| 115 |
if (a < (w * h) * 0.0005) continue;
|
| 116 |
|
| 117 |
const newId = `T${String(state.tracker.nextId++).padStart(2, "0")}`;
|
| 118 |
-
const ap = defaultAimpoint(detObjs[i].label);
|
| 119 |
tracks.push({
|
| 120 |
id: newId,
|
| 121 |
label: detObjs[i].label,
|
| 122 |
bbox: { ...detObjs[i].bbox },
|
| 123 |
score: detObjs[i].score,
|
| 124 |
-
aimRel: { relx: ap.relx, rely: ap.rely, label: ap.label },
|
| 125 |
-
baseAreaFrac: (detObjs[i].bbox.w * detObjs[i].bbox.h) / (w * h),
|
| 126 |
-
baseRange_m: rangeBase ? +rangeBase.value : 1000,
|
| 127 |
-
baseDwell_s: 5.5,
|
| 128 |
-
reqP_kW: 42,
|
| 129 |
depth_rel: detObjs[i].depth_rel,
|
| 130 |
depth_est_m: detObjs[i].depth_est_m,
|
| 131 |
depth_valid: detObjs[i].depth_valid,
|
| 132 |
-
|
| 133 |
-
// Satisfaction reasoning
|
| 134 |
satisfies: null,
|
| 135 |
reason: null,
|
| 136 |
-
|
| 137 |
-
// Track state
|
| 138 |
lastSeen: now(),
|
| 139 |
vx: 0, vy: 0,
|
| 140 |
-
dwellAccum: 0,
|
| 141 |
killed: false,
|
| 142 |
state: "TRACK",
|
| 143 |
-
assessT: 0
|
| 144 |
});
|
| 145 |
log(`New track created: ${newId} (${detObjs[i].label})`, "t");
|
| 146 |
}
|
|
|
|
| 4 |
const { state } = APP.core;
|
| 5 |
const { CONFIG } = APP.core;
|
| 6 |
const { normBBox, lerp, now, $ } = APP.core.utils;
|
|
|
|
| 7 |
const { log } = APP.ui.logging;
|
| 8 |
|
| 9 |
const videoEngage = $("#videoEngage");
|
|
|
|
| 10 |
|
| 11 |
if (!videoEngage) return;
|
| 12 |
|
|
|
|
| 113 |
if (a < (w * h) * 0.0005) continue;
|
| 114 |
|
| 115 |
const newId = `T${String(state.tracker.nextId++).padStart(2, "0")}`;
|
|
|
|
| 116 |
tracks.push({
|
| 117 |
id: newId,
|
| 118 |
label: detObjs[i].label,
|
| 119 |
bbox: { ...detObjs[i].bbox },
|
| 120 |
score: detObjs[i].score,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
depth_rel: detObjs[i].depth_rel,
|
| 122 |
depth_est_m: detObjs[i].depth_est_m,
|
| 123 |
depth_valid: detObjs[i].depth_valid,
|
|
|
|
|
|
|
| 124 |
satisfies: null,
|
| 125 |
reason: null,
|
|
|
|
|
|
|
| 126 |
lastSeen: now(),
|
| 127 |
vx: 0, vy: 0,
|
|
|
|
| 128 |
killed: false,
|
| 129 |
state: "TRACK",
|
|
|
|
| 130 |
});
|
| 131 |
log(`New track created: ${newId} (${detObjs[i].label})`, "t");
|
| 132 |
}
|
frontend/js/core/video.js
CHANGED
|
@@ -106,8 +106,6 @@ APP.core.video.unloadVideo = async function (options = {}) {
|
|
| 106 |
state.useDepthFeed = false;
|
| 107 |
state.useFrameDepthView = false;
|
| 108 |
|
| 109 |
-
state.hf.missionId = null;
|
| 110 |
-
state.hf.plan = null;
|
| 111 |
state.hf.processedUrl = null;
|
| 112 |
state.hf.processedBlob = null;
|
| 113 |
state.hf.depthVideoUrl = null;
|
|
@@ -148,7 +146,6 @@ APP.core.video.unloadVideo = async function (options = {}) {
|
|
| 148 |
state.tracker.nextId = 1;
|
| 149 |
state.tracker.running = false;
|
| 150 |
state.tracker.selectedTrackId = null;
|
| 151 |
-
state.tracker.beamOn = false;
|
| 152 |
|
| 153 |
// Clear video elements
|
| 154 |
const videoHidden = $("#videoHidden");
|
|
|
|
| 106 |
state.useDepthFeed = false;
|
| 107 |
state.useFrameDepthView = false;
|
| 108 |
|
|
|
|
|
|
|
| 109 |
state.hf.processedUrl = null;
|
| 110 |
state.hf.processedBlob = null;
|
| 111 |
state.hf.depthVideoUrl = null;
|
|
|
|
| 146 |
state.tracker.nextId = 1;
|
| 147 |
state.tracker.running = false;
|
| 148 |
state.tracker.selectedTrackId = null;
|
|
|
|
| 149 |
|
| 150 |
// Clear video elements
|
| 151 |
const videoHidden = $("#videoHidden");
|
frontend/js/main.js
CHANGED
|
@@ -15,7 +15,6 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 15 |
const { renderFrameTrackList } = APP.ui.cards;
|
| 16 |
const { tickAgentCursor, moveCursorToRect } = APP.ui.cursor;
|
| 17 |
const { matchAndUpdateTracks, predictTracks } = APP.core.tracker;
|
| 18 |
-
const { defaultAimpoint } = APP.core.physics;
|
| 19 |
|
| 20 |
// DOM Elements
|
| 21 |
const videoEngage = $("#videoEngage");
|
|
@@ -23,7 +22,6 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 23 |
const videoFile = $("#videoFile");
|
| 24 |
const btnReason = $("#btnReason");
|
| 25 |
const btnCancelReason = $("#btnCancelReason");
|
| 26 |
-
const btnRecompute = $("#btnRecompute");
|
| 27 |
const btnClear = $("#btnClear");
|
| 28 |
const btnEject = $("#btnEject");
|
| 29 |
const btnEngage = $("#btnEngage");
|
|
@@ -139,16 +137,6 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 139 |
btnCancelReason.addEventListener("click", cancelReasoning);
|
| 140 |
}
|
| 141 |
|
| 142 |
-
// Recompute HEL button
|
| 143 |
-
if (btnRecompute) {
|
| 144 |
-
btnRecompute.addEventListener("click", async () => {
|
| 145 |
-
if (!state.hasReasoned) return;
|
| 146 |
-
renderFrameOverlay();
|
| 147 |
-
|
| 148 |
-
log("Parameters recomputed.", "g");
|
| 149 |
-
});
|
| 150 |
-
}
|
| 151 |
-
|
| 152 |
// Clear button
|
| 153 |
if (btnClear) {
|
| 154 |
btnClear.addEventListener("click", () => {
|
|
@@ -521,12 +509,10 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 521 |
function processFirstFrameDetections(dets) {
|
| 522 |
state.detections = dets.map((d, i) => {
|
| 523 |
const id = d.track_id || `T${String(i + 1).padStart(2, "0")}`;
|
| 524 |
-
const ap = defaultAimpoint(d.label || d.class);
|
| 525 |
const bbox = d.bbox
|
| 526 |
? { x: d.bbox[0], y: d.bbox[1], w: d.bbox[2] - d.bbox[0], h: d.bbox[3] - d.bbox[1] }
|
| 527 |
: { x: 0, y: 0, w: 10, h: 10 };
|
| 528 |
|
| 529 |
-
// Build features from universal schema via canonical mapping
|
| 530 |
let features = APP.core.gptMapping.buildFeatures(d.gpt_raw);
|
| 531 |
|
| 532 |
return {
|
|
@@ -534,14 +520,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 534 |
label: d.label || d.class,
|
| 535 |
score: d.score || 0.5,
|
| 536 |
bbox,
|
| 537 |
-
aim: { ...ap },
|
| 538 |
features,
|
| 539 |
-
baseRange_m: null,
|
| 540 |
-
baseAreaFrac: (bbox.w * bbox.h) / (state.frame.w * state.frame.h),
|
| 541 |
-
baseDwell_s: 5.0,
|
| 542 |
-
reqP_kW: 40,
|
| 543 |
-
maxP_kW: 0,
|
| 544 |
-
pkill: 0,
|
| 545 |
// Depth fields
|
| 546 |
depth_est_m: (d.depth_est_m !== undefined && d.depth_est_m !== null) ? d.depth_est_m : null,
|
| 547 |
depth_rel: (d.depth_rel !== undefined && d.depth_rel !== null) ? d.depth_rel : null,
|
|
@@ -566,30 +545,21 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 566 |
}
|
| 567 |
|
| 568 |
function seedTracksFromTab1() {
|
| 569 |
-
const rangeBase = $("#rangeBase");
|
| 570 |
state.tracker.tracks = state.detections.map(d => ({
|
| 571 |
id: d.id,
|
| 572 |
label: d.label,
|
| 573 |
bbox: { ...d.bbox },
|
| 574 |
score: d.score,
|
| 575 |
-
aimRel: d.aim ? { relx: d.aim.relx, rely: d.aim.rely, label: d.aim.label } : { relx: 0.5, rely: 0.5, label: "center_mass" },
|
| 576 |
-
baseAreaFrac: d.baseAreaFrac || ((d.bbox.w * d.bbox.h) / (state.frame.w * state.frame.h)),
|
| 577 |
-
baseRange_m: d.baseRange_m || (rangeBase ? +rangeBase.value : 1500),
|
| 578 |
-
baseDwell_s: d.baseDwell_s || 4.0,
|
| 579 |
-
reqP_kW: d.reqP_kW || 35,
|
| 580 |
depth_rel: d.depth_rel,
|
| 581 |
depth_est_m: d.depth_est_m,
|
| 582 |
depth_valid: d.depth_valid,
|
| 583 |
-
lastDepthBbox: d.depth_valid ? { ...d.bbox } : null,
|
| 584 |
satisfies: d.satisfies,
|
| 585 |
reason: d.reason,
|
| 586 |
lastSeen: APP.core.utils.now(),
|
| 587 |
vx: 0,
|
| 588 |
vy: 0,
|
| 589 |
-
dwellAccum: 0,
|
| 590 |
killed: false,
|
| 591 |
-
state: "TRACK"
|
| 592 |
-
assessT: 0
|
| 593 |
}));
|
| 594 |
state.tracker.nextId = state.detections.length + 1;
|
| 595 |
log(`Seeded ${state.tracker.tracks.length} tracks from Tab 1 detections.`, "t");
|
|
|
|
| 15 |
const { renderFrameTrackList } = APP.ui.cards;
|
| 16 |
const { tickAgentCursor, moveCursorToRect } = APP.ui.cursor;
|
| 17 |
const { matchAndUpdateTracks, predictTracks } = APP.core.tracker;
|
|
|
|
| 18 |
|
| 19 |
// DOM Elements
|
| 20 |
const videoEngage = $("#videoEngage");
|
|
|
|
| 22 |
const videoFile = $("#videoFile");
|
| 23 |
const btnReason = $("#btnReason");
|
| 24 |
const btnCancelReason = $("#btnCancelReason");
|
|
|
|
| 25 |
const btnClear = $("#btnClear");
|
| 26 |
const btnEject = $("#btnEject");
|
| 27 |
const btnEngage = $("#btnEngage");
|
|
|
|
| 137 |
btnCancelReason.addEventListener("click", cancelReasoning);
|
| 138 |
}
|
| 139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
// Clear button
|
| 141 |
if (btnClear) {
|
| 142 |
btnClear.addEventListener("click", () => {
|
|
|
|
| 509 |
function processFirstFrameDetections(dets) {
|
| 510 |
state.detections = dets.map((d, i) => {
|
| 511 |
const id = d.track_id || `T${String(i + 1).padStart(2, "0")}`;
|
|
|
|
| 512 |
const bbox = d.bbox
|
| 513 |
? { x: d.bbox[0], y: d.bbox[1], w: d.bbox[2] - d.bbox[0], h: d.bbox[3] - d.bbox[1] }
|
| 514 |
: { x: 0, y: 0, w: 10, h: 10 };
|
| 515 |
|
|
|
|
| 516 |
let features = APP.core.gptMapping.buildFeatures(d.gpt_raw);
|
| 517 |
|
| 518 |
return {
|
|
|
|
| 520 |
label: d.label || d.class,
|
| 521 |
score: d.score || 0.5,
|
| 522 |
bbox,
|
|
|
|
| 523 |
features,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 524 |
// Depth fields
|
| 525 |
depth_est_m: (d.depth_est_m !== undefined && d.depth_est_m !== null) ? d.depth_est_m : null,
|
| 526 |
depth_rel: (d.depth_rel !== undefined && d.depth_rel !== null) ? d.depth_rel : null,
|
|
|
|
| 545 |
}
|
| 546 |
|
| 547 |
function seedTracksFromTab1() {
|
|
|
|
| 548 |
state.tracker.tracks = state.detections.map(d => ({
|
| 549 |
id: d.id,
|
| 550 |
label: d.label,
|
| 551 |
bbox: { ...d.bbox },
|
| 552 |
score: d.score,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 553 |
depth_rel: d.depth_rel,
|
| 554 |
depth_est_m: d.depth_est_m,
|
| 555 |
depth_valid: d.depth_valid,
|
|
|
|
| 556 |
satisfies: d.satisfies,
|
| 557 |
reason: d.reason,
|
| 558 |
lastSeen: APP.core.utils.now(),
|
| 559 |
vx: 0,
|
| 560 |
vy: 0,
|
|
|
|
| 561 |
killed: false,
|
| 562 |
+
state: "TRACK"
|
|
|
|
| 563 |
}));
|
| 564 |
state.tracker.nextId = state.detections.length + 1;
|
| 565 |
log(`Seeded ${state.tracker.tracks.length} tracks from Tab 1 detections.`, "t");
|
frontend/style.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
/* =========================================
|
| 2 |
-
|
| 3 |
========================================= */
|
| 4 |
|
| 5 |
:root {
|
|
@@ -1023,7 +1023,7 @@ input[type="number"]:focus {
|
|
| 1023 |
}
|
| 1024 |
|
| 1025 |
/* =========================================
|
| 1026 |
-
|
| 1027 |
========================================= */
|
| 1028 |
|
| 1029 |
.panel-chat {
|
|
|
|
| 1 |
/* =========================================
|
| 2 |
+
Mission Console Design System
|
| 3 |
========================================= */
|
| 4 |
|
| 5 |
:root {
|
|
|
|
| 1023 |
}
|
| 1024 |
|
| 1025 |
/* =========================================
|
| 1026 |
+
Mission Analyst Chat Panel
|
| 1027 |
========================================= */
|
| 1028 |
|
| 1029 |
.panel-chat {
|
utils/mission_parser.py
CHANGED
|
@@ -155,7 +155,7 @@ _SYSTEM_PROMPT = (
|
|
| 155 |
" - 'detect', 'find', 'locate', 'spot', 'search for' -> DETECT\n"
|
| 156 |
" - 'classify', 'identify', 'determine type of' -> CLASSIFY\n"
|
| 157 |
" - 'track', 'follow', 'monitor movement of' -> TRACK\n"
|
| 158 |
-
" - 'assess
|
| 159 |
" - 'monitor', 'watch', 'observe', 'surveil' -> MONITOR\n"
|
| 160 |
" - If no verb present (bare class list), default to DETECT.\n\n"
|
| 161 |
"4. DOMAIN — Infer from contextual clues:\n"
|
|
@@ -316,7 +316,7 @@ def _validate_and_build(
|
|
| 316 |
parse_warnings = llm_output.get("parse_warnings", [])
|
| 317 |
|
| 318 |
# Validate enum values
|
| 319 |
-
valid_intents = {"DETECT", "CLASSIFY", "TRACK", "
|
| 320 |
if mission_intent not in valid_intents:
|
| 321 |
mission_intent = "DETECT"
|
| 322 |
parse_warnings.append(f"Invalid mission_intent '{llm_output.get('mission_intent')}', defaulted to DETECT.")
|
|
|
|
| 155 |
" - 'detect', 'find', 'locate', 'spot', 'search for' -> DETECT\n"
|
| 156 |
" - 'classify', 'identify', 'determine type of' -> CLASSIFY\n"
|
| 157 |
" - 'track', 'follow', 'monitor movement of' -> TRACK\n"
|
| 158 |
+
" - 'assess', 'evaluate', 'check', 'verify' -> EVALUATE\n"
|
| 159 |
" - 'monitor', 'watch', 'observe', 'surveil' -> MONITOR\n"
|
| 160 |
" - If no verb present (bare class list), default to DETECT.\n\n"
|
| 161 |
"4. DOMAIN — Infer from contextual clues:\n"
|
|
|
|
| 316 |
parse_warnings = llm_output.get("parse_warnings", [])
|
| 317 |
|
| 318 |
# Validate enum values
|
| 319 |
+
valid_intents = {"DETECT", "CLASSIFY", "TRACK", "EVALUATE", "MONITOR"}
|
| 320 |
if mission_intent not in valid_intents:
|
| 321 |
mission_intent = "DETECT"
|
| 322 |
parse_warnings.append(f"Invalid mission_intent '{llm_output.get('mission_intent')}', defaulted to DETECT.")
|
utils/schemas.py
CHANGED
|
@@ -26,11 +26,11 @@ class MissionSpecification(BaseModel):
|
|
| 26 |
"""Structured representation of operator intent.
|
| 27 |
|
| 28 |
Created once from raw mission text at the API boundary (app.py).
|
| 29 |
-
Forwarded to: detector (object_classes), GPT
|
| 30 |
relevance gate (relevance_criteria only — INV-13).
|
| 31 |
|
| 32 |
INVARIANT INV-13: context_phrases are forwarded to LLM reasoning layers
|
| 33 |
-
(GPT
|
| 34 |
They must NEVER be used in evaluate_relevance(), prioritization,
|
| 35 |
or any deterministic filtering/sorting logic.
|
| 36 |
"""
|
|
@@ -42,11 +42,11 @@ class MissionSpecification(BaseModel):
|
|
| 42 |
"These become detector queries. Must be nouns, not adjectives or verbs."
|
| 43 |
)
|
| 44 |
mission_intent: Literal[
|
| 45 |
-
"DETECT", "CLASSIFY", "TRACK", "
|
| 46 |
] = Field(
|
| 47 |
...,
|
| 48 |
description="Operator purpose. DETECT=find objects, CLASSIFY=identify type, "
|
| 49 |
-
"TRACK=follow over time,
|
| 50 |
)
|
| 51 |
domain: Literal[
|
| 52 |
"NAVAL", "GROUND", "AERIAL", "URBAN", "GENERIC"
|
|
|
|
| 26 |
"""Structured representation of operator intent.
|
| 27 |
|
| 28 |
Created once from raw mission text at the API boundary (app.py).
|
| 29 |
+
Forwarded to: detector (object_classes), GPT satisfaction reasoning (full spec),
|
| 30 |
relevance gate (relevance_criteria only — INV-13).
|
| 31 |
|
| 32 |
INVARIANT INV-13: context_phrases are forwarded to LLM reasoning layers
|
| 33 |
+
(GPT satisfaction evaluation) as situational context ONLY.
|
| 34 |
They must NEVER be used in evaluate_relevance(), prioritization,
|
| 35 |
or any deterministic filtering/sorting logic.
|
| 36 |
"""
|
|
|
|
| 42 |
"These become detector queries. Must be nouns, not adjectives or verbs."
|
| 43 |
)
|
| 44 |
mission_intent: Literal[
|
| 45 |
+
"DETECT", "CLASSIFY", "TRACK", "EVALUATE", "MONITOR"
|
| 46 |
] = Field(
|
| 47 |
...,
|
| 48 |
description="Operator purpose. DETECT=find objects, CLASSIFY=identify type, "
|
| 49 |
+
"TRACK=follow over time, EVALUATE=assess per-object conditions, MONITOR=passive watch."
|
| 50 |
)
|
| 51 |
domain: Literal[
|
| 52 |
"NAVAL", "GROUND", "AERIAL", "URBAN", "GENERIC"
|