Skip to content

Feat/buffer travel future#2668

Draft
rafel-roboflow wants to merge 8 commits into
mainfrom
feat/buffer-travel-future
Draft

Feat/buffer travel future#2668
rafel-roboflow wants to merge 8 commits into
mainfrom
feat/buffer-travel-future

Conversation

@rafel-roboflow

@rafel-roboflow rafel-roboflow commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds a new workflow block Frame Delay (roboflow_core/frame_delay@v1) that returns a value produced on an earlier frame of the same video stream. You wire any workflow output (detections, numbers, strings, images, …) into it, set a negative offset, and it returns that value as it was |offset| frames ago — enabling cross-frame comparisons and temporal alignment on video streams.

Key points:

  • Per-video_identifier ring buffer keyed by frame_number; memory is bounded via eviction (|offset| + margin frames retained).
  • Outputs: output (the delayed value), is_available (whether the target frame was buffered yet), and reference_frame_number.
  • Past-only by design. offset must be <= 0; positive offsets are rejected both at manifest-validation time (literal ints) and at runtime (selector-provided values). True future look-ahead would require delaying the whole workflow output, which isn't possible on synchronous runtimes (WebRTC/webexec, single-image HTTP), so it is intentionally not offered.
  • Works in every execution context (no output delay is introduced), including the WebRTC/webexec video path.
  • Registered in the core steps loader. The legacy identifiers roboflow_core/time_travel@v1 / TimeTravel are kept as accepted aliases so any workflow saved under the earlier name keeps resolving to this block.

Related Issue(s): N/A

Type of Change

  • New feature (non-breaking change that adds functionality)

Testing

  • I have tested this change locally
  • I have added/updated tests for this change

Test details:

  • Unit tests (tests/workflows/unit_tests/core_steps/fusion/test_frame_delay.py): past-offset lookup returning the previous frame's value, default_value fallback before the buffer fills, zero-offset returning the current value, positive-offset rejection (both runtime run() and manifest validation), per-video_identifier state isolation, bounded-buffer eviction, and state persistence across run() calls.
  • Integration test (tests/workflows/integration_tests/execution/test_workflow_with_frame_delay.py): a multi-frame workflow with two past-offset steps (-1 and -2) driven by property_definition frame numbers (model-free), asserting the correct delayed values, is_available, and reference_frame_number across a frame sequence.
  • Manually validated on a live WebRTC preview via a dominant-color "now vs. N frames ago" demo workflow.

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code where necessary, particularly in hard-to-understand areas
  • My changes generate no new warnings or errors
  • I have updated the documentation accordingly (if applicable) — block ships with SHORT_DESCRIPTION/LONG_DESCRIPTION; no separate docs site changes.

Additional Context

  • Files changed (net vs main): frame_delay/__init__.py, frame_delay/v1.py, loader.py, and the two test files (5 files, +479).
  • Common use cases: change/trend detection against a past frame (-1, -5), aligning a slow/delayed signal to the frame it belongs to, or remembering a value N frames ago (e.g. the dominant color 10 frames earlier).
  • Limitation: block state lives in process memory keyed by video_identifier, so it degrades on stateless/multi-replica remote HTTP runtimes and resets on restart.

Add roboflow_core/time_travel@v1, a fusion block that returns a workflow
value (detections, numbers, strings, images, ...) from a different frame of
the same video stream at a relative offset (N-k past, N+k future), keyed per
video_identifier.

- Past offsets resolve immediately from a bounded per-video ring buffer and
  work in every execution context.
- Future look-ahead delays the whole workflow output via the InferencePipeline
  stream-pipeline emission mechanism. It is opt-in via TIME_TRAVEL_STREAM_LOOKAHEAD
  (default off) so synchronous consumers (WebRTC/webexec, HTTP, preview) keep
  receiving an immediate per-frame result and are never turned into a
  PipelinedWorkflowRunner unexpectedly.
- Generalize the InferencePipeline delayed-emission gate so any handler that
  opts into stream pipelining activates the drain/close path, not just RF-DETR.
@github-actions

Copy link
Copy Markdown
Contributor

👋 Thanks for the pull request! Here is how automated Claude review works here, so you spend credits (and reviewer time) wisely.

🚧 Right now this is a draft, so automated Claude review is paused — nothing is being spent yet. Mark it Ready for review to trigger it.

Warning

💸 The Claude reviewer bills in credits, not vibes

Automated review spins up a real agent that reads real code and spends real credits on every pass. It is glad to help — but it is not a rubber duck, a linter you poke in a loop, or a substitute for reading the contributing guide. Treat it like an expensive senior reviewer whose time you booked, and show up prepared.

Draft when unsure, Ready when you mean it:

  • 🌱 Not sure the PR is in good shape yet? Keep it (or set it back) as a draft — drafts pause review, so you can push and iterate without burning credits on a moving target.
  • 💪 Feel strong about the contents? Mark it Ready for review and the reviewer will take a look.

However you get there, arrive prepared:

  • 🧱 Bring a SOLID, thorough PR. Point your local agent at our skills/ to tune it to our guidelines first — or, if you are one of those fabled carbon-based contributors, read them yourself. A half-baked diff costs exactly the same to review as a finished one.
  • Resolve every comment before you re-request review. Re-requesting with threads still open means paying twice for the same conversation.
  • 🔁 Do not use CI review as an inner loop for a local agent. The reviewer is not a step-by-step debugger — do the unfolding locally and arrive with the answer, not the search.
  • 🙋 If something looks off, ask a human. One question to a maintainer is cheaper and faster than three rounds of agent re-review chasing a misread.

Reviews are not free. A draft costs nothing to review; a Ready PR is a promise that it is worth reviewing.

  • Prefer to skip automated review entirely? Add the skip-claude-review label.

@grzegorz-roboflow

Copy link
Copy Markdown
Collaborator

Nice! I like how the feature is encapsulated to just a single block! Well done @rafel-roboflow !

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.

2 participants