From 83f1070a11e913079622537653e540cefd345c39 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Tue, 30 Jun 2026 22:52:32 -0400 Subject: [PATCH] =?UTF-8?q?fix(agent):=20bound=20video=20GPU=20work=20?= =?UTF-8?q?=E2=80=94=20early-exit=20the=20frame=20loop=20at=20max=5Fregion?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Image 81602 turned out to be a 156 MB mp4, not a huge still: the agent samples up to 64 frames × ~32 regions/frame → ~2000 regions (the 413) and 64 frames of detect+CCIP+embed (the 38s). The MAX_REGIONS backstop (#171) only truncated the SUBMIT — the GPU work was already spent. Break out of the frame loop once accumulated regions reach max_regions, so a long video costs ~a few frames of GPU (~2-3s), not all 64 (~38s). The whole-image 'embed' task is unaffected (it mean-pools all frames and returns before this loop). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa --- agent/fc_agent/app.py | 2 +- agent/fc_agent/worker.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/agent/fc_agent/app.py b/agent/fc_agent/app.py index dda9591..ee67b7b 100644 --- a/agent/fc_agent/app.py +++ b/agent/fc_agent/app.py @@ -15,7 +15,7 @@ from .worker import Worker # Bump on every agent change. The page embeds this and /status reports it; the UI # warns to reload when they differ — so a stale browser-cached page can't be # mistaken for "the new image didn't deploy". (Belt-and-braces with no-store.) -VERSION = "2026-06-30.9 · region-caps + active-reset" +VERSION = "2026-06-30.10 · video region early-exit" logbuf.install() cfg = Config.from_env() diff --git a/agent/fc_agent/worker.py b/agent/fc_agent/worker.py index 2016ac7..2441491 100644 --- a/agent/fc_agent/worker.py +++ b/agent/fc_agent/worker.py @@ -559,6 +559,12 @@ class Worker: tmpl["siglip_embedding"] = vec tmpl["embedding_version"] = embed_version regions.append(tmpl) + # Stop once we have enough: a long video (image 81602 = a 156 MB + # mp4, 64 sampled frames × ~32 regions) would otherwise burn ~38s + # of GPU across every frame before the submit is even truncated. + # Bounds the WORK, not just the POST body. + if len(regions) >= self.cfg.max_regions: + break self._record("gpu", time.monotonic() - _t_gpu) # Backstop: never submit an unbounded pile of regions (a pathological # image / long video). Keep the highest-scoring max_regions so the