Skip to content

feat: accept the temporal score computed on the device - #723

Open
MateoLostanlen wants to merge 5 commits into
mainfrom
feat/engine-temporal-score
Open

MateoLostanlen wants to merge 5 commits into
mainfrom
feat/engine-temporal-score

Conversation

@MateoLostanlen

@MateoLostanlen MateoLostanlen commented Oct 22, 2026 •

Copy link
Copy Markdown
Member
  • The engine can now run the temporal smoke model on the Pi (feat(engine): temporal validation of alerts on the Pi pyro-engine#415) and sends its probabilities with each detection. The API keeps its own model for devices that cannot.
  • POST /detections takes an optional temporal_model_scores form field: a list of probabilities (0 to 1, max 3 decimals), one per bbox in the same order, like the crops. Each matched or created sequence receives the score of its own bbox, stored with engine as provenance in the existing temporal_api_version column, so no migration.
  • The validation worker applies TEMPORAL_MODEL_THRESHOLD to a device score instead of calling the temporal API. Above the threshold the sequence is validated as today (triangulation, notifications). Below it the sequence stays in the DB unvalidated and waits for the next frame, with no 10-frame window since the device scores a sliding window. The risk gate still applies first.
  • A frame without scores on a device-scored sequence resets it, so the API scores it itself when the device fails open.
  • pyroclient.create_detection gains the matching optional temporal_model_scores parameter.

Known limitation: a sequence already window_exhausted by the API model is not revived when the device later starts sending scores.

The engine may run the temporal smoke model itself and send its score with
the detection. Store it on the touched sequences with 'engine' as provenance
so the validation worker knows the sequence was already scored.
When the stored score came from the engine, apply the threshold to it
instead of calling the temporal API. No frame window: the engine scores a
sliding window and sends a fresh score with every frame, so a sequence below
threshold waits for the next one. The risk gate still applies.
A scored sequence that receives an unscored frame means the device's temporal
service failed open. Drop the stale device verdict so the worker falls back
to scoring the sequence itself.
Comment thread src/app/models.py
TERMINAL_VALIDATION_STATUSES = (WINDOW_EXHAUSTED, VALIDATION_FAILED)
# sequences.temporal_api_version value for a score computed on the device and sent with the
# detection: the worker applies the threshold to it instead of calling the model.
TEMPORAL_SCORE_SOURCE_ENGINE = "engine"
@codecov

codecov Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.10345% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.68%. Comparing base (219cfac) to head (658cc6a).

Files with missing lines Patch % Lines
client/pyroclient/client.py 85.71% 1 Missing ⚠️
src/app/api/api_v1/endpoints/detections.py 92.30% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #723      +/-   ##
==========================================
- Coverage   94.70%   94.68%   -0.02%     
==========================================
  Files          60       60              
  Lines        3266     3292      +26     
==========================================
+ Hits         3093     3117      +24     
- Misses        173      175       +2     
Flag Coverage Δ
backend 94.85% <95.45%> (-0.01%) ⬇️
client 91.03% <85.71%> (-0.27%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The device scores each tracked object separately, so the detection route
now takes temporal_model_scores, a list aligned with bboxes like the crops,
and each matched or created sequence receives the score of its own bbox
instead of one score shared by every sequence of the request.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants