Repository navigation
fix(image): upload a local --ref into a project once, then mention it (#772) - #1098
Conversation
…#772) On flow.google.com every image i2i uploaded its --ref file again, so a loop over one character image filled the project's library with copies. The upload is now recorded in the catalog; a later run in the same project with the same file (same path, same bytes) mentions the recorded image in place. A recorded image deleted from the project since is uploaded again, recorded, and the generation retried once (nothing is submitted before the miss). Shared by the CLI and the MCP worker. Labs keeps its editor-dialog filename dedup (#334): the transport answers None there and the path is left alone.
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 49 minutes. View limit details
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Reference lookup, upload, and retry src/gflow_cli/services/reference_uploads.py, src/gflow_cli/api/client.py, tests/services/test_reference_uploads.py |
The shared service checks the catalog for a matching file and project, attempts in-place upload when reuse is unavailable, and records successful uploads. If generation reports a reused image missing, it re-uploads the reference and retries once. Unit tests cover reuse, changed file bytes, fallback, and retry behavior. |
CLI and worker integration src/gflow_cli/cli_image.py, src/gflow_cli/worker/daemon.py, tests/cli/test_cli_image.py |
CLI and worker image generation use the shared reuse service. The worker retains its single-image and batch-generation paths. |
Behavior coverage and documentation tests/features/local_ref_uploaded_once.feature, tests/e2e/test_local_ref_uploaded_once_bdd.py, CHANGELOG.md, docs/REFERENCE_STRATEGIES.md, docs/USAGE.md, website/docs/USAGE.md |
End-to-end scenarios cover CLI and MCP reuse and re-upload when the project image is missing. The changelog and usage documentation describe project-scoped reuse on flow.google.com. |
Priority:
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix · Severity of issue fixed: Medium
Sequence Diagram(s)
sequenceDiagram
participant CLI
participant generate_reusing_uploads
participant OperationRecorder
participant FlowApiClient
participant GenerationCallback
CLI->>generate_reusing_uploads: Submit request and project context
generate_reusing_uploads->>OperationRecorder: Resolve matching seed image
generate_reusing_uploads->>FlowApiClient: Attempt in-place upload when reuse is unavailable
generate_reusing_uploads->>GenerationCallback: Generate with transformed request
GenerationCallback-->>generate_reusing_uploads: Return generated images
generate_reusing_uploads->>FlowApiClient: Re-upload reused reference if generation reports it missing
generate_reusing_uploads->>GenerationCallback: Retry generation once
Possibly related issues
- Issue 997: This change retries generation when a reused image is missing, but it does not change the migrated composer’s caret placement described in the issue.
Merge Risk: 
Minimal · up to c949d
-
Local references retain a working upload path when reuse is unavailable, and a missing reused image receives one fresh-upload retry. No issue identified here prevents merging after normal checks.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed-
Full details: Linked Issues check
-
Explanation
Issue
#772requires reuse for repeated local--refcalls in the same project onflow.google.com, or explicit documentation of the limitation.generate_reusing_uploadsmatches the resolved path and SHA-256, checks the current project, mentions a recorded image in place, and records new uploads. CLI and MCP paths use the helper. The service tests and live CLI/MCP scenarios cover reuse, project and byte changes, and recovery after deletion. The documentation states the behavior and its newest-record limitation.
Full details: Out of Scope Changes check
-
Explanation
The changes stay within the stated scope. The shared helper supports the CLI and MCP flows named in the PR. Client changes enable in-place upload behavior. Tests, documentation, changelog updates, and e2e coverage support the reuse objective. Labs retains its existing path-based deduplication route.
gflow runcross-run reuse remains explicitly outside this change, and no unrelated change is demonstrated.
-
Full details: Docstring Coverage
-
Explanation
Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 42 functions across 7 files. (5 skipped: 5 unsupported.)
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches: 💡 1
-
📝 Generate docstrings: 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.
Council review: - the retry fires only when the ReferenceNotFoundError names a media id this run reused; a missing character or an out-of-order chip re-raises at once, with no duplicate upload - a file the upload check refuses keeps its pre-#772 route - the file size is checked before it is hashed - a live e2e scenario for a recorded image the project no longer holds - docs/USAGE.md describes the flow.google.com reuse; #334 -> issue #314
# Conflicts: # CHANGELOG.md
# Conflicts: # CHANGELOG.md
Summary
On flow.google.com,
gflow image i2i --ref <file>uploaded the file again on every call. The reporter's 122-prompt loop left 122 copies of one character image in the project's library. Labs avoids this by searching the picker for the file name (#334); the migrated composer has no such search.Fix, at the shared layer (CLI and MCP): new
services/reference_uploads.generate_reusing_uploads.--ref, look up the catalog: if this profile already recorded this file (resolved path and sha256) as an image in this project, with a caption, mention that image in place (ImageRef(in_project=True), the image batch: intra-batch references (ref / reference_entity "batch:N") are parsed and never applied (#317) #913/flow.google.com: image i2i --ref <uuid> of an image already in the target project is refused (exit 36) instead of referenced in place #995 path).client.upload_reference_in_place, the same toolbar uploadgflow runuses, image batch: intra-batch references (ref / reference_entity "batch:N") are parsed and never applied (#317) #913) and record it (record_upload_image), so the next run finds it.ReferenceNotFoundErrorbefore anything is submitted. The file is then uploaded again and recorded, and the generation retried once, so the next run reuses the fresh copy.Nonethere (no in-place upload), and the path stays onref_pathsfor the editor dialog's own dedup.upload_reference_in_placeisupload_referencewithout the REST fallback, which 401s on labs (#15/#39);upload_referencenow calls it.Wired into
cli_imagei2i andworker/daemon(MCPgflow_generate_image). One known limit, markedshortcut:in the code: only the newest catalog record of a file is checked, so a file copied to project A, then B, then used again in A uploads once more.Evidence
Live e2e (denon82, flow.google.com), new
tests/e2e/test_local_ref_uploaded_once_bdd.py, both scenarios pass:1 passed(151 s). The firsti2iuploads (migrated.reference_uploaded). The second, in the same project with the same file, emitsreference_uploads.reusedwith the first run's media id,migrated.existing_references_attachedwith exactly that id, and no upload event. The submit guard passed.gflow_generate_image(wait=True)after a CLI first run):1 passed(99 s), same assertions, statuscompleted, one image on disk.GFLOW_CLI_LOG_LEVEL=INFO, and the labs skip now needs positive evidence). 0 Veo credits.Offline:
tests/services/test_reference_uploads.py, 6 tests, written first and seen failing (module missing):Full offline suite:
5484 passed, 29 skipped. pyright0 errors. ruff, format and all 5scripts/cigates green.Council review (2 reviewers, both YELLOW) → addressed in
2a8213e6ReferenceNotFoundErrornames a media id this run reused. Any other pre-submit miss (a character, an out-of-order chip) re-raises at once, with no duplicate upload. New test:test_an_unrelated_miss_is_not_retried_with_a_new_upload.reference_uploads.recorded_image_gone, then onemigrated.reference_uploaded; the new copy is recorded and the submit guard passed. Cost: 2 more images.validate_image_filerefuses keeps its pre-image i2i reference dedup (#314/#334) does not appear to apply on the migrated flow.google.com host #772 route (labs dialog / composer upload), instead of a bareValueError.MAX_IMAGE_BYTESbefore it is hashed.docs/USAGE.md(the main--refdescription) covers the flow.google.com reuse;#334(the PR) →#314(the issue). The labs wording in the CHANGELOG is corrected: a file already recorded in the project is referenced in place on labs too.ReferenceNotFoundErrorraise site is before submit on both hosts.Not covered
gflow run(batch) already uploads once per run (image batch: intra-batch references (ref / reference_entity "batch:N") are parsed and never applied (#317) #913). It does not yet reuse across runs; that would be the same helper, left for a follow-up.Closes #772
Summary by CodeRabbit