Zhen Ye Claude Opus 4.6 commited on
Commit
28965e8
·
1 Parent(s): d737b59

refactor: remove remaining dead HEL/threat code remnants

Browse files

Strip 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 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
- <!-- Threat Chat Panel -->
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
- missionId: null,
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
- LaserPerception Design System
3
  ========================================= */
4
 
5
  :root {
@@ -1023,7 +1023,7 @@ input[type="number"]:focus {
1023
  }
1024
 
1025
  /* =========================================
1026
- Threat Chat Panel
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 threat', 'evaluate danger', 'threat assessment' -> ASSESS_THREAT\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,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", "ASSESS_THREAT", "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.")
 
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 (full spec), chat (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 threat assessment, threat chat) as situational context ONLY.
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", "ASSESS_THREAT", "MONITOR"
46
  ] = Field(
47
  ...,
48
  description="Operator purpose. DETECT=find objects, CLASSIFY=identify type, "
49
- "TRACK=follow over time, ASSESS_THREAT=evaluate danger, MONITOR=passive watch."
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"