Skip to content

feat(api): explicit ?compute_trigger=true flag for time-to-detection#51

Merged
Chouffe merged 7 commits into
mainfrom
arthur/api-compute-trigger
Jun 12, 2026
Merged

feat(api): explicit ?compute_trigger=true flag for time-to-detection#51
Chouffe merged 7 commits into
mainfrom
arthur/api-compute-trigger

Conversation

@Chouffe

@Chouffe Chouffe commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Closes #26.

Summary

  • Adds an explicit compute_trigger query param to POST /predict (default false). The default serving path is unchanged — no first-crossing search, no trigger fields, byte-identical response (guarded by the exact-shape asserts in test_predict_default / test_predict_verbose).
  • ?compute_trigger=true threads the flag through ModelRunner.predict_predict_syncmodel.predict (core already supported it since perf: make trigger_search eval-only via compute_trigger gate (closes #23) #25) and adds a top-level trigger_frame_index. An explicit null means "searched, no crossing" — same convention as probability.
  • With verbose=true it also fills details.decision.trigger_tube_id and per-tube details.tubes[].first_crossing_frame, which core already emits and the mapper previously dropped.
  • Serialization relies on the route's existing response_model_exclude_unset=True: the new DTO fields stay unset (omitted) unless the flag is on.

Design spec: docs/specs/2026-06-11-api-compute-trigger-design.md. The ticket's predict_sequence step is obsolete — that function was refactored away; the runner calls model.predict directly.

Request / response examples

Request body is unchanged in all cases:

POST /predict?compute_trigger=true
Content-Type: application/json

{
  "frames": ["cam12/adf_2023-05-23T17-18-01.jpg", "cam12/adf_2023-05-23T17-18-31.jpg"],
  "bucket": "frames"
}

Default (POST /predict) — unchanged, fast path:

{
  "is_smoke": true,
  "probability": 0.98,
  "version": {"api": "0.3.0", "model": "1.2.0"}
}

POST /predict?compute_trigger=true — runs the first-crossing search, adds the top-level TTD field:

{
  "is_smoke": true,
  "probability": 0.98,
  "trigger_frame_index": 3,
  "version": {"api": "0.3.0", "model": "1.2.0"}
}

"trigger_frame_index": null means the search ran and nothing crossed (e.g. a negative decision).

POST /predict?compute_trigger=true&verbose=true — also fills the trigger fields inside details:

{
  "is_smoke": true,
  "probability": 0.98,
  "trigger_frame_index": 3,
  "version": {"api": "0.3.0", "model": "1.2.0"},
  "details": {
    "decision": {
      "aggregation": "max_logit",
      "threshold": 0.5,
      "threshold_overridden": false,
      "packaged_threshold": null,
      "trigger_tube_id": 7
    },
    "preprocessing": {
      "num_frames_input": 30,
      "num_truncated": 0,
      "padded_frame_indices": [],
      "num_tube_candidates": 2,
      "num_tubes_outside_roi": 0
    },
    "tubes": [
      {
        "tube_id": 7,
        "start_frame": 2,
        "end_frame": 12,
        "logit": 3.4,
        "probability": 0.98,
        "first_crossing_frame": 3,
        "entries": [
          {"frame_idx": 2, "bbox": [0.41, 0.55, 0.04, 0.03], "is_gap": false, "confidence": 0.8}
        ]
      }
    ]
  }
}

POST /predict?verbose=true (without the flag) — details as today, still no trigger fields.

Test plan

  • api: make lint clean, make test → 132 passed, 1 skipped
  • New tests: runner forwarding (2), DTO gating incl. null semantics and verbose-without-flag (5), route behavior for all param combinations (3)

@Chouffe Chouffe requested a review from MateoLostanlen June 11, 2026 16:15

@MateoLostanlen MateoLostanlen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good, thanks

@Chouffe Chouffe merged commit e72263c into main Jun 12, 2026
5 checks passed
Chouffe added a commit that referenced this pull request Jun 12, 2026
The merge of #47 with the compute_trigger flag (#51) left the
supplied-detections fast path dropping the flag: ?compute_trigger=true
with caller-supplied boxes would silently skip the first-crossing
search. Thread it through and pin the composition with a test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API: add explicit ?compute_trigger=true flag for time-to-detection

2 participants