Skip to content

Restore native 1080p export on migrated Flow API - #40

Open
Bl0ck154 wants to merge 3 commits into
crisng95:mainfrom
Bl0ck154:feature/migrated-1080-export
Open

Bl0ck154 wants to merge 3 commits into
crisng95:mainfrom
Bl0ck154:feature/migrated-1080-export

Conversation

@Bl0ck154

@Bl0ck154 Bl0ck154 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Restores Flow's native Full HD export on the migrated flow.google.com batchexecute transport.

The new frontend exposes high-resolution download as RPC p0UkFb. This PR captures that wire contract, submits veo_3_1_upsampler_1080p, and resolves the resulting <media-id>_upsampled output through the existing migrated as29s media lookup.

What changes

  • add p0UkFb request builder/parser to flow_batch.py
  • make FlowClient.upscale_video() work on USE_BATCH_RPC=1
  • expose explicit POST /api/flow/export-video with quality: "1080p" as the default
  • expose POST /api/flow/check-export-status
  • keep /upscale-video / /check-upscale-status as low-level compatibility surfaces
  • poll migrated upscale media through as29s, not the dead labs.google REST/tRPC path
  • document 1080p as a download/export quality choice rather than an internal implementation detail

Live verification

Verified end-to-end against the current migrated Flow UI/account:

  1. Generated a real 720p video through the migrated API.
  2. Submitted p0UkFb with veo_3_1_upsampler_1080p.
  3. Flow returned <source-media-id>_upsampled.
  4. Polled the output through as29s.
  5. Downloaded the signed MP4 and checked it with ffprobe.

Result: 1080×1920, H.264, 24 fps, 8.000 s.

The Flow UI currently presents this as 720p original size → 1080p high-resolution download. 4K is plan-gated and was disabled on the verified account, so this PR only claims live verification for 1080p.

Validation

  • 88 passed across test_flow_batch.py, test_flow_client_batch.py, and test_upscale_polling.py
  • MV3 extension cold-start regression test passes
  • git diff --check clean

The branch is based directly on current upstream main (ce37f4b) and intentionally excludes fork-specific browser/session fallback code.

@crisng95 crisng95 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for this — restoring native 1080p export is genuinely wanted, and half of this PR is exactly the shape we want new Flow surfaces to take. I'd like to land it, but with the polling half pointed somewhere else. Details below, with the reasoning, so this doesn't read as a drive-by.

Keep as-is — this half is the pattern

agent/services/flow_batch.py: RPC_UPSCALE = "p0UkFb", upscale_request(), read_upscaled_media_id(), and calling it through self._batch_payload(...) in FlowClient.

That's the right decomposition: the wire format lives in one module as a pure function, and the transport stays in FlowClient. It's the same shape #41 used for Omni text-to-video, and it's why #41 survived the migration intact. Nothing to change here.

Please redirect — agent/services/upscale_polling.py

upscale_polling.py is a copy of agent/services/omni_flash.py:169-220. Comparing them on main:

this PR omni_flash.py on main
_normalize_workflow() _normalize_workflow() — same body, minus the project_id branch
extract_upscale_workflows() extract_omni_workflows() — identical
annotate_upscale_polling() _annotate_polling() — identical apart from the mode string
_fetch_media_url() _fetch_media_url() — byte-identical in the tRPC branch, same URL, same params

This isn't a nitpick about tidiness. That block is already duplicated once (omni_flash vs the REST methods in flow_client), and that duplication is precisely why the September migration only got applied to one of the two copies — Omni frame/reference generation has been returning UNSUPPORTED_ON_BATCH ever since, because the fix landed next to it rather than on it. A third copy makes the next endpoint change three times the work.

We're extracting a shared agent/services/flow_poll.py (normalize_workflow / extract_workflows / annotate_polling / check_workflow_status) for exactly this. Two options, your call:

  • You own it. Add flow_poll.py in this PR and have upscale be its first consumer. It's your code being promoted, and it lands with the feature that motivated it.
  • We land it first, you rebase onto it and import. Slower for you, no writing involved.

Either is fine — say which and we'll sequence around it.

Please redirect — agent/api/upscale_status.py

/check-export-status would be the third endpoint doing one poll pass:

  • POST /api/flow/check-status — already branches on body.workflows (agent/api/flow.py:297)
  • POST /api/flow/check-omni-status (agent/api/flow.py:320) — structurally identical to that branch, one indent level apart
  • POST /api/flow/check-export-status — this PR

We're collapsing the first two behind /check-status with the other kept as a deprecated shim. Could export polling go through /check-status with a mode discriminator instead of a new route? Same handler, one less thing for callers to learn.

Minor

upscale_polling._fetch_media_url calls client._send(...). That's a private of another module, and it's the reason omni_flash is hard to migrate today — it reaches into five FlowClient privates (_send, _build_url, _client_context, _batch_project_id, _batch_payload), so any transport change has to be replayed by hand in both places. Going through a public method keeps upscale out of that trap.

Practical note

GitHub currently reports this branch as CONFLICTING against main (#41, #44 and the #43 revert all landed since you opened it), so a rebase is needed regardless — which makes this the cheapest moment to change direction rather than an expensive one.

Happy to pair on the flow_poll.py extraction if that's useful. And to be explicit: the flow_batch.py work here is good and is staying.

@Bl0ck154
Bl0ck154 force-pushed the feature/migrated-1080-export branch from 6884a69 to a7a7dd9 Compare September 17, 2026 08:05
@Bl0ck154

Copy link
Copy Markdown
Contributor Author

Addressed the requested changes and rebased onto current main (including #42). The export wire work remains in flow_batch/FlowClient, but the duplicate upscale poller and separate /check-export-status router are gone. Added shared agent/services/flow_poll.py, moved media/project transport behind public FlowClient methods, and native export now polls through existing POST /api/flow/check-status with mode=export. Existing Omni polling was migrated to the same shared helpers. Focused flow_batch + flow_client + flow_poll + Omni suite: 153 passed; git diff --check clean. GitHub now reports the branch CLEAN/MERGEABLE.

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