Repository navigation
feat(mcp): wire server tools to FlowWorker and implement download/recording in daemon - #228
Conversation
1. Fix Playwright chrome channel validation in `browser_manager.py`: - `is_chrome_available()` was returning True for system Chromium, causing Playwright to request `channel="chrome"` which expects real Google Chrome. - Replaced with a strict check against Playwright's actual expected Chrome paths so it falls back to bundled Chromium correctly. 2. Fix image generation settings selector in `ui_automation.py`: - `GEN_SETTINGS_BUTTON_SELECTORS` lacked the `aria-haspopup='menu'` attribute and missed the `crop_original` icon. - Without it, the selector failed to find the panel after switching to image mode, leaving Flow's default generation count (2) active while the CLI only expected 1. 3. Warn on silent extra image generation in `client.py`: - If Flow generates more images than requested (e.g. 2 instead of 1 due to the settings panel miss), `_drive_image_generation` silently discarded the extras. - A warning is now logged showing the extra media IDs, alerting users to the extra credit consumption while preserving the single-image API contract.
…ording in daemon - Wired MCP image/video generation tool placeholders to actual FlowWorker execution path via new `_run_generation_task` helper. - Hooked up `OperationRecorder` and file download logic in `FlowWorker.process_task` to ensure generated assets are saved locally and recorded to SQLite. - Refactored `FlowWorker` to reuse its active `DataStore` connection with `OperationRecorder` instead of creating new instances. - Added support for profile pinning via `--profile` / `GFLOW_CLI_PROFILE` env var in MCP command. - Refactored Chrome cookie snapshot decryption to avoid KeyError on Linux/macOS by only passing Local State path on Windows and handling keyring connection errors. - Added 9 new integration tests for the wired MCP tools flow and updated worker mocks/tests to conform to the database schema.
…ffroliva-develop # Conflicts: # src/gflow_cli/api/client.py # src/gflow_cli/api/transports/ui_automation.py # src/gflow_cli/browser_manager.py
* **ui_automation.py**: Kept the clean `GEN_SETTINGS_BUTTON_SELECTORS = MODE_SWITCH_TRIGGER_SELECTORS` alias from the `develop` branch to eliminate duplicate button selectors. * **client.py**: Maintained the module-level `logger.warning`, kept detailed docstrings/hints, and removed obsolete local logger imports and instantiations. * **browser_manager.py**: Preserved enhanced docstrings, strict Linux Chromium path resolutions (`/opt/google/chrome/chrome`), and the correct logic returning `True` over `bool(env_override)`.
|
Thanks for the contribution. This PR has been marked as an external contribution and routed for maintainer review. Before merge, please make sure:
GitHub Copilot code review may be requested as an advisory first pass, but maintainer approval is still required. |
…prove worker error handling MCP Tools Updates: - gflow_generate_image: Added 'reference_images' parameter, classifying as local paths vs UUIDs and mapping to 'i2i' mode when present. - gflow_generate_video: Renamed 'image_path' to 'initial_frame' and 'end_image' to 'end_frame', mapped them cleanly to the daemon payload. Added 'reference_images' for 'r2v' mode. - Added strict mutually exclusive validation checking that 'reference_images' cannot be used alongside 'initial_frame' or 'end_frame'. - Fixed line-length formatting issues and strict type hints in tools.py. Worker Daemon Updates: - Explicitly fail tasks and log reasons if video generation tasks return un-succeeded statuses from the Flow API (via FlowWorker).
ffroliva
left a comment
There was a problem hiding this comment.
Council review — changes requested 🔴
Thanks for this, @C1ph3r404 — wiring the MCP tools to the real FlowWorker queue (instead of the old status:"pending" stubs) is genuinely useful work, and the core wiring is correct: task-type dispatch and payload keys line up in both directions, security is clean (no injection/traversal, output paths go through validate_job_id()), and the MCP↔CLI flag naming actually improved. The blockers below are mostly mechanical — happy to help once they're addressed.
Must-fix (blocking)
- CI is red because the new video tests use an incomplete fake.
FakeVideoStatus/_FakeVideoStatus(tests/worker/test_daemon.py:29,tests/mcp/test_tools_wired.py) only setmedia_id+status="completed", but production callsresult.status.succeeded— a property on the realVideoStatusthat returnsstatus == "MEDIA_GENERATION_STATUS_SUCCESSFUL". The fake has nosucceeded, so the worker raises, the task is markedfailed, and the test assertsfailed == completed. The production code is correct; the test fixtures are wrong. Please construct the realVideoStatus(or mirrorsucceeded/failure_reasons/error_messageand use theMEDIA_GENERATION_STATUS_SUCCESSFULstring). You did this correctly for the image fakes — same treatment for video. - Unclosed DB connection in the new fixtures. The
temp_dbfixturesreturn storewith no teardown →ResourceWarning: unclosed sqlite3.Connectionin CI. Useyield store+store.close(). - A recording error can mark a successful, credit-spent video as
failed. Inworker/daemon.py,record_completed_video(...)runs inside thetrywhoseexceptre-raises — but it executes after the Veo credit is spent. A DB hiccup then flips a real success tofailed. Recording/DB errors after a successful generation should warn, not fail the task (same principle as our exit-16 data-store handling). i2vmust requireinitial_frame. Inmcp/tools.py,initial_frameis optional and only validated when present, though the docstring says it's "required for i2v". Calling i2v with no frame sendsstart_image=None, which routes to the text-to-video endpoint and burns a credit on the wrong call. Please enforce it formode="i2v".docs/MCP.mdis now stale. Lines 48-49 still showgflow_generate_image(...)withoutreference_imagesandgflow_generate_video(prompt, initial_frame_path, ...)(old name, missingend_frame/mode). Our docs are a living spec — please update them in this PR.- Heads-up on
auth/cookies.py. Your_get_chrome_cookies3change touches the exact function an in-flight macOS cookie investigation (#222) depends on. No textual conflict, but it changes the macOSkey_filehandling and adds aKeyError→PermissionErrormapping that affects which failures fall back to the headless reader. Could you split the cookie/--profilechanges into a separate PR? It keeps this one scoped to "MCP wiring" and avoids entangling the #222 debugging.
Worth adding (not blocking)
- Real coverage for the headline behavior. Download and recording are fully
AsyncMock'd, so "download/recording in daemon" isn't actually exercised — a test asserting a file is written and an asset/DB row recorded would lock it in. - Extract the ~150-line
process_taskinto_process_image_task/_process_video_task, and factor the path-validation block that's copy-pasted 4× inmcp/tools.py. - Please rebase onto current
develop— this branch was cut before some merged work, so the diff re-presents changes that are already in.
(On testing strategy: we won't ask an external PR to run live-credit e2e — but constructing the real domain dataclasses in tests, as in must-fix #1, is exactly what catches this class of bug.)
…iva#228) Maintainer follow-up to @C1ph3r404's MCP->FlowWorker wiring, addressing the PR ffroliva#228 council review. - CI-RED: tests hand-rolled a fake VideoStatus missing `.succeeded`, so completed videos flipped to "failed". Use the real VideoStatus/VideoResult. - worker: apply tool_specs so the MCP `tools` parameter actually expands the prompt (it was packed into the payload but never applied -> silent no-op). - daemon: post-success video recording warns instead of failing a credit-spent task. - mcp/tools: require initial_frame for i2v and reference_images for r2v at the tool boundary; treat any non-"completed" status as failure. - cleanup: close temp_db fixtures (no ResourceWarning); dedupe image-path validation into a shared helper; flatten _run_generation_task DataStore lifecycle (no nested store / double-close). - docs/MCP.md: correct stale tool signatures. - merged origin/develop (picks up ffroliva#223); cookies.py KeyError->PermissionError mapping now covered by tests.
|
Hi @C1ph3r404 — thanks for this, the wiring is solid! To land it without a round-trip, I (maintainer) have pushed follow-up commits to your branch ( What changed on top of your work:
Full suite green locally (1918 passed). Thanks again for the contribution! 🙏 |
The #228 boundary guards pushed gflow_generate_image/video over the cognitive- complexity threshold and duplicated the bad-parameter error literal. Extract: - `_BAD_PARAM_TYPE` constant + `_bad_param()` builder (fixes S1192 duplicated literal) - `_resolve_image_references()` and `_build_video_media_inputs()` helpers, moving the mode/mutual-exclusion/path validation out of the tool functions (fixes S3776 cognitive complexity on both) Adds unit tests for the extracted helpers plus the #230 `_preread_flow_session_cookies` capture path (D4 council gap) and the video `tool_specs` expansion branch — lifting new-code coverage back over 80%. Behavior-preserving; 38 affected tests green, pyright src 0 errors.
…iva#228) Maintainer follow-up to @C1ph3r404's MCP->FlowWorker wiring, addressing the PR ffroliva#228 council review. - CI-RED: tests hand-rolled a fake VideoStatus missing `.succeeded`, so completed videos flipped to "failed". Use the real VideoStatus/VideoResult. - worker: apply tool_specs so the MCP `tools` parameter actually expands the prompt (it was packed into the payload but never applied -> silent no-op). - daemon: post-success video recording warns instead of failing a credit-spent task. - mcp/tools: require initial_frame for i2v and reference_images for r2v at the tool boundary; treat any non-"completed" status as failure. - cleanup: close temp_db fixtures (no ResourceWarning); dedupe image-path validation into a shared helper; flatten _run_generation_task DataStore lifecycle (no nested store / double-close). - docs/MCP.md: correct stale tool signatures. - merged origin/develop (picks up ffroliva#223); cookies.py KeyError->PermissionError mapping now covered by tests.
feat(mcp): wire server tools to FlowWorker and implement download/recording in daemon
The ffroliva#228 boundary guards pushed gflow_generate_image/video over the cognitive- complexity threshold and duplicated the bad-parameter error literal. Extract: - `_BAD_PARAM_TYPE` constant + `_bad_param()` builder (fixes S1192 duplicated literal) - `_resolve_image_references()` and `_build_video_media_inputs()` helpers, moving the mode/mutual-exclusion/path validation out of the tool functions (fixes S3776 cognitive complexity on both) Adds unit tests for the extracted helpers plus the ffroliva#230 `_preread_flow_session_cookies` capture path (D4 council gap) and the video `tool_specs` expansion branch — lifting new-code coverage back over 80%. Behavior-preserving; 38 affected tests green, pyright src 0 errors.
Summary
_run_generation_taskhelper.OperationRecorderand file download logic inFlowWorker.process_taskto ensure generated assets are saved locally and recorded to SQLite.FlowWorkerto reuse its activeDataStoreconnection withOperationRecorderinstead of creating new instances.--profile/GFLOW_CLI_PROFILEenv var in MCP command.Validation
-
uv run python scripts/ci/check_doc_links.pyuv run ruff check src testsuv run pyright srcuv run pytest tests/worker/test_daemon.py tests/mcp/test_tools_wired.py -v(and full suite validation withuv run python -m pytest -q --cov=gflow_cli)