diffusers-workflow 0.4.0a10__tar.gz → 0.4.0b1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {diffusers_workflow-0.4.0a10/diffusers_workflow.egg-info → diffusers_workflow-0.4.0b1}/PKG-INFO +20 -5
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/README.md +19 -4
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1/diffusers_workflow.egg-info}/PKG-INFO +20 -5
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/diffusers_workflow.egg-info/SOURCES.txt +42 -22
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/__init__.py +14 -2
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/events.py +22 -1
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/pipeline_processors/chain.py +14 -7
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/pipeline_processors/pipeline.py +50 -4
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/previous_results.py +5 -3
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/repl.py +18 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/repl_commands.py +4 -1
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/result.py +40 -1
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/run.py +14 -0
- diffusers_workflow-0.4.0b1/dw/schema.py +43 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/security.py +181 -0
- diffusers_workflow-0.4.0b1/dw/serve.py +170 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/app.py +579 -50
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/jobs.py +100 -11
- diffusers_workflow-0.4.0b1/dw/server/mcp_mount.py +91 -0
- diffusers_workflow-0.4.0b1/dw/server/netinfo.py +124 -0
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/cssMode-DBf-T_da.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/cssMode-DIA5LESv.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/editor.api-B0D5Ygq7.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/editor.api-CuOF-U_A.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/freemarker2-Br8g4G1T.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/freemarker2-xMcLxHzc.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/handlebars-BKo1TaOF.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/handlebars-Dbt47IUh.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/html-Bis1seyM.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/html-C4QoqgED.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/htmlMode-D2SOD2MF.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/htmlMode-BQ_x-rQl.js +1 -1
- diffusers_workflow-0.4.0b1/dw/server/ui/assets/index-BCNGRglb.css +1 -0
- diffusers_workflow-0.4.0b1/dw/server/ui/assets/index-C14JKFhY.js +28 -0
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/javascript-CkEbVb78.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/javascript-yDlADdyl.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/jsonMode-dVJbYwxg.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/jsonMode-X4znCY4b.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/liquid-Btak-6uF.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/liquid-CAaCQzwu.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/lspLanguageFeatures-BfeZZQbb.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/lspLanguageFeatures-CTJIGm94.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/mdx-D9KXK7-s.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/mdx-ByHLng1y.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/monaco-ZMCk_MWf.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/monaco-LJZc6TiS.js +4 -4
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/python-0FnO4xGM.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/python-BCT_lvfW.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/razor-B6PMzeY4.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/razor-Bw9oTolL.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/tsMode-nxyvZH1t.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/tsMode-BGvHTpYz.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/typescript-BhBe8aGf.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/typescript-mwKKpQXP.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/workers-ChAf-t8A.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/workers-BOhWN9wu.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/xml-z2r9dHSO.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/xml-DuQ6E6P7.js +1 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/yaml-DrcHrz7f.js → diffusers_workflow-0.4.0b1/dw/server/ui/assets/yaml-D7o22x0f.js +1 -1
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/index.html +2 -2
- diffusers_workflow-0.4.0b1/dw/server/updater.py +192 -0
- diffusers_workflow-0.4.0b1/dw/step_cache.py +260 -0
- diffusers_workflow-0.4.0b1/dw/tasks/audio_utils.py +579 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/concat_videos.py +44 -12
- diffusers_workflow-0.4.0b1/dw/tasks/dissolve_videos.py +138 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/gather.py +27 -9
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/image_utils.py +65 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/interpolate_frames.py +13 -3
- diffusers_workflow-0.4.0b1/dw/tasks/stabilize.py +121 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/task.py +99 -10
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/video_utils.py +137 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/type_helpers.py +12 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/validate.py +13 -1
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/variables.py +92 -38
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/worker.py +8 -2
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/workflow.py +222 -61
- diffusers_workflow-0.4.0b1/dw/workflows/h3_context_ir.json +57 -0
- diffusers_workflow-0.4.0b1/dw_mcp/__main__.py +122 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw_mcp/catalog.py +9 -1
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw_mcp/client.py +71 -2
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw_mcp/diagnose.py +50 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw_mcp/media.py +53 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw_mcp/server.py +48 -1
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/pyproject.toml +4 -1
- diffusers_workflow-0.4.0b1/tests/test_audio_utils.py +469 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_chain.py +28 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_cli.py +18 -1
- diffusers_workflow-0.4.0b1/tests/test_concat_videos.py +309 -0
- diffusers_workflow-0.4.0b1/tests/test_dissolve_videos.py +97 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_gather.py +96 -8
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_interpolate_frames.py +19 -4
- diffusers_workflow-0.4.0b1/tests/test_jobs_reused.py +53 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_mcp_catalog.py +1 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_mcp_client.py +39 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_mcp_diagnose.py +82 -0
- diffusers_workflow-0.4.0b1/tests/test_mcp_main.py +138 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_mcp_media.py +182 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_mcp_server.py +30 -0
- diffusers_workflow-0.4.0b1/tests/test_mix_audio.py +53 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_modular_pipeline.py +88 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_phase_events.py +77 -1
- diffusers_workflow-0.4.0b1/tests/test_recenter_crop.py +72 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_result.py +23 -0
- diffusers_workflow-0.4.0b1/tests/test_result_output_naming.py +34 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_security.py +40 -0
- diffusers_workflow-0.4.0b1/tests/test_serve_main.py +84 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_server.py +793 -13
- diffusers_workflow-0.4.0b1/tests/test_server_downloads.py +123 -0
- diffusers_workflow-0.4.0b1/tests/test_server_info.py +177 -0
- diffusers_workflow-0.4.0b1/tests/test_server_mcp.py +174 -0
- diffusers_workflow-0.4.0b1/tests/test_stabilize.py +110 -0
- diffusers_workflow-0.4.0b1/tests/test_step_cache.py +349 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_task.py +56 -0
- diffusers_workflow-0.4.0b1/tests/test_updater.py +126 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_variables.py +61 -15
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_video_utils.py +96 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_worker_execute.py +25 -1
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_workflow.py +118 -0
- diffusers_workflow-0.4.0b1/tests/test_workflow_step_cache.py +610 -0
- diffusers_workflow-0.4.0b1/tests/test_workflow_trust.py +237 -0
- diffusers_workflow-0.4.0a10/dw/schema.py +0 -24
- diffusers_workflow-0.4.0a10/dw/serve.py +0 -90
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/index-D7eWnTCB.css +0 -1
- diffusers_workflow-0.4.0a10/dw/server/ui/assets/index-JyFxgIR9.js +0 -20
- diffusers_workflow-0.4.0a10/dw/server/updater.py +0 -119
- diffusers_workflow-0.4.0a10/dw/tasks/audio_utils.py +0 -266
- diffusers_workflow-0.4.0a10/dw/workflows/h3_context_ir.json +0 -57
- diffusers_workflow-0.4.0a10/dw_mcp/__main__.py +0 -39
- diffusers_workflow-0.4.0a10/tests/test_audio_utils.py +0 -194
- diffusers_workflow-0.4.0a10/tests/test_concat_videos.py +0 -133
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/LICENSE +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/MANIFEST.in +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/diffusers_workflow.egg-info/dependency_links.txt +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/diffusers_workflow.egg-info/entry_points.txt +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/diffusers_workflow.egg-info/requires.txt +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/diffusers_workflow.egg-info/top_level.txt +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/arguments.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/cache_blocks.json +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/cache_blocks.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/community_pipelines/pipeline_flux_rf_inversion.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/hub_cache.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/introspection.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/log_setup.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/pipeline_processors/config_objects.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/pipeline_processors/remote.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/prompt_schema.json +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/prompt_weighting.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/prompts.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/repl_worker.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/__init__.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/enhancers.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/abap-08VXUWAP.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/apex-BWPQTe0t.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/azcli-Bc_sGQ0U.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/bat-i0X4ZdIN.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/bicep-B5-_aFwp.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/cameligo-DMUM7wLl.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/clojure-Cm7r79vr.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/codicon-Brq4_Ui5.ttf +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/coffee-Ba7i2nA0.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/cpp-C7h46wYY.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/csharp-BKxtCVv1.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/csp-bTuwJoIa.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/css-DIMkf-bt.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/css.worker-B3ciXF_0.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/cypher-CVaqCwHa.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/dart-onAF5SnQ.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/dockerfile-DZFCIeNp.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/ecl-D05T4iGw.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/editor-jjEx9u7D.css +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/editor.worker-q-txB4vs.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/elixir-6RTg0lbw.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/flow9-C5_-GSwl.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/fsharp-C8Ef5oNN.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/go-C-y9NEjX.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/graphql-fmXr3nnJ.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/hcl-CpzslTdj.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/html.worker-C93Ht9o9.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/ini-sBoK_t0W.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/java-BEtHBSE6.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/json.worker-B2V3pomh.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/julia-Bri6UV-V.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/kotlin-BOotOW0E.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/less-B9JPFI3C.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/lexon-CfSJPG6W.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/lua-CsQS60Ue.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/m3-D-oSqn_W.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/markdown-Cimd5fb3.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/mips-CIPQ_RoX.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/monaco--ixms01u.css +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/msdax-DauUninz.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/mysql-SOo6toE5.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/objective-c-FvmIjYaQ.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/pascal-DrH0SRf2.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/pascaligo-D-ptJ9y-.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/perl-oz_6vUea.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/pgsql-DTj74zXo.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/php-nr791fC2.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/pla-CopQ2nXW.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/postiats-43DmfD33.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/powerquery-D3hlyOfw.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/powershell-DmHpPYUd.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/protobuf-C531GsRP.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/pug-Z5eAx3Zn.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/qsharp-DkqhCAOL.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/r-BwWrilGY.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/redis-ClamHrr6.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/redshift-DT7zqm-g.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/restructuredtext-BYgofb2h.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/ruby-DezsRK8O.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/rust-DdL9SqIa.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/sb-CcwsVR0C.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/scala-DHpiXF5c.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/scheme-BeGwcela.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/scss-gp-XZpBa.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/shell-CC2rA5mh.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/solidity-BEEn4gHE.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/sophia-CRfGWb83.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/sparql-D_Lu-MrJ.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/sql-NEE52Syq.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/st-DbInun42.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/swift-Bxkupp3x.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/systemverilog-Bz4Y3fRF.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/tcl-DISqw1ZD.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/ts.worker-D7T1-Ig5.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/twig-De2hgUGE.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/typespec-B8J7ngcE.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/vb-DV3o63ZY.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/server/ui/assets/wgsl-DpFanUEy.js +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/settings.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/step.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/background_remover.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/borders.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/depth_estimator.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/diffusion_upscale.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/format_messages.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/image_to_text.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/model_cache.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/pair_audio.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/qr_code.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/restore_faces.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/rife_model.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/segment.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/tensor_image.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/text_generation.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/text_sections.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/upscale.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/tasks/zoe_depth.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/teacache.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/teacache_models.json +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/test.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/workflow_schema.json +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/workflows/augment_prompt.json +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/workflows/describe_image.json +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/workflows/test.json +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw_mcp/__init__.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw_mcp/authoring.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw_mcp/models.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw_mcp/prompts.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/setup.cfg +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_argument_updates.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_arguments.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_borders.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_cache_blocks.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_component_pruning.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_config_objects.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_configuration_schema.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_depth_estimator.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_device.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_device_helpers.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_device_portability.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_diffusion_upscale.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_docs_links.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_events.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_examples.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_hub_cache.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_image_to_text.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_image_utils.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_integration.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_introspection.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_list_images.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_mcp_authoring.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_mcp_models.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_mcp_prompts.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_model_cache.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_offload_placement.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_pair_audio.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_pipeline_caching.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_pipeline_components.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_previous_results.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_prompt_parser.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_prompt_weighting.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_prompts.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_repl_commands.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_repl_ergonomics.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_repl_hierarchical.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_repl_reorganization.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_repl_worker.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_resize_bucket.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_scheduler_config.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_schema.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_segment.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_step.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_strip_exif_and_watermark.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_task_discovery.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_teacache.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_tensor_image.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_text_generation.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_text_sections.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_type_helpers.py +0 -0
- {diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/tests/test_worker.py +0 -0
{diffusers_workflow-0.4.0a10/diffusers_workflow.egg-info → diffusers_workflow-0.4.0b1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: diffusers-workflow
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.0b1
|
|
4
4
|
Summary: Declarative workflow engine and web UI for Hugging Face Diffusers
|
|
5
5
|
Author: dkackman
|
|
6
6
|
License: Apache-2.0
|
|
@@ -79,6 +79,8 @@ Dynamic: license-file
|
|
|
79
79
|
|
|
80
80
|
A declarative workflow engine and web UI for the [Hugging Face Diffusers library](https://github.com/huggingface/diffusers). Define image/video generation pipelines in JSON — with full access to the configuration diffusers exposes — and run them from the command line, an interactive REPL, or a browser.
|
|
81
81
|
|
|
82
|
+
A workflow JSON file is portable and easy to hand off — but that same flexibility means loading one can execute arbitrary Python (dynamic imports are how it reaches any diffusers pipeline or quantization backend without a bespoke adapter for each). Treat a workflow file from someone else the way you'd treat a `.py` script: see [Trust model](docs/SECURITY.md#trust-model) before running one you didn't write.
|
|
83
|
+
|
|
82
84
|
**Python 3.10-3.14 | CUDA (NVIDIA) | MPS (Apple Silicon) | CPU**
|
|
83
85
|
|
|
84
86
|
<picture>
|
|
@@ -89,10 +91,11 @@ A declarative workflow engine and web UI for the [Hugging Face Diffusers library
|
|
|
89
91
|
## Features
|
|
90
92
|
|
|
91
93
|
- **Web UI** — browse and run workflows, edit them in introspection-driven forms, watch jobs stream live progress, manage generated output and the models on disk. `python -m dw.serve` and open a browser. See [Server & Web UI](docs/SERVER.md).
|
|
92
|
-
- **MCP server** — a
|
|
94
|
+
- **MCP server** — a tool surface that lets an MCP client (Claude Code first) author, validate, save, run and diagnose workflows against a running `dw.serve`: `dw-mcp` over stdio, or mounted at `/mcp` by `dw.serve --mcp` for a client on another machine. See [MCP Server](docs/MCP.md) and [Remote GPU server](docs/REMOTE.md).
|
|
95
|
+
- **Step-output caching** — a step whose resolved arguments and seed are unchanged since the last run in the same process reuses its cached result instead of re-executing. This applies to any `Workflow.run` — REPL iteration and a re-run of a server-submitted job alike, so re-running a fixed-seed workflow from the UI finishes instantly and writes no new output files. The cache holds the most recent 50 steps and is dropped by `memory clear`
|
|
93
96
|
- **Declarative JSON workflows** with variable substitution and cross-step data flow
|
|
94
97
|
- **Multi-step pipelines** — chain text-to-image, image-to-video, inpainting, ControlNet
|
|
95
|
-
- **Reproducible by construction** — outputs embed their full workflow definition and seed; any image in the gallery reopens as the exact workflow that made it
|
|
98
|
+
- **Reproducible by construction** — outputs embed their full workflow definition and seed; any image in the gallery reopens as the exact workflow that made it (see [Trust model](docs/SECURITY.md#trust-model) before reopening one someone else sent you). A rerun never overwrites a prior output — a name collision gets an incrementing suffix instead
|
|
96
99
|
- **Long-video chaining** — run a video pipeline once per segment and stitch the segments into one clip, with audio-driven length and frame-to-frame continuity
|
|
97
100
|
- **Quantization** — BitsAndBytes, TorchAO, GGUF, SDNQ, optimum-quanto
|
|
98
101
|
- **Inference acceleration** — TeaCache, FirstBlockCache, FasterCache, MagCache, TaylorSeerCache
|
|
@@ -153,15 +156,26 @@ Jobs queue, stream progress live (per denoising step), cancel cooperatively, and
|
|
|
153
156
|
|
|
154
157
|
### Run a Workflow
|
|
155
158
|
|
|
159
|
+
`workflows/sd15.json` is the smallest, fastest starting point — a small, ungated model and a literal prompt, so the first run needs no Hugging Face login and downloads only a few GB:
|
|
160
|
+
|
|
156
161
|
```bash
|
|
162
|
+
python -m dw.run workflows/sd15.json
|
|
163
|
+
python -m dw.run workflows/sd15.json prompt="a cat" num_images_per_prompt=4
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Most of the workflows under `workflows/` (Flux, LTX-2, MiniMax...) use **gated** Hugging Face models — the repo owner has to approve your account before you can download them. Before running one of those, request access on the model's Hugging Face page (e.g. [black-forest-labs/FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev)) and log in locally:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
huggingface-cli login
|
|
157
170
|
python -m dw.run workflows/flux/FluxDev.json
|
|
158
|
-
python -m dw.run workflows/flux/FluxDev.json prompt="a cat" num_images_per_prompt=4
|
|
159
171
|
```
|
|
160
172
|
|
|
173
|
+
Without this, the run fails partway through with an HTTP 401/403 from the Hub.
|
|
174
|
+
|
|
161
175
|
### Validate a Workflow
|
|
162
176
|
|
|
163
177
|
```bash
|
|
164
|
-
python -m dw.validate workflows/
|
|
178
|
+
python -m dw.validate workflows/sd15.json
|
|
165
179
|
```
|
|
166
180
|
|
|
167
181
|
### Interactive REPL
|
|
@@ -329,6 +343,7 @@ See [workflows/](workflows/) for more workflow files.
|
|
|
329
343
|
|
|
330
344
|
- [Server & Web UI](docs/SERVER.md) — The web UI, jobs API, and introspection service
|
|
331
345
|
- [MCP Server](docs/MCP.md) — Tool surface for MCP clients (Claude Code, Claude Desktop)
|
|
346
|
+
- [Remote GPU server](docs/REMOTE.md) — Using the server, UI and MCP from another machine
|
|
332
347
|
- [Workflow Guide](docs/WORKFLOW_GUIDE.md) — JSON structure, variables, steps, data flow
|
|
333
348
|
- [Quantization](docs/QUANTIZATION.md) — BitsAndBytes, TorchAO, GGUF, SDNQ
|
|
334
349
|
- [Inference Acceleration](docs/ACCELERATION.md) — torch.compile, FirstBlockCache, MagCache, TaylorSeer, TeaCache
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
A declarative workflow engine and web UI for the [Hugging Face Diffusers library](https://github.com/huggingface/diffusers). Define image/video generation pipelines in JSON — with full access to the configuration diffusers exposes — and run them from the command line, an interactive REPL, or a browser.
|
|
6
6
|
|
|
7
|
+
A workflow JSON file is portable and easy to hand off — but that same flexibility means loading one can execute arbitrary Python (dynamic imports are how it reaches any diffusers pipeline or quantization backend without a bespoke adapter for each). Treat a workflow file from someone else the way you'd treat a `.py` script: see [Trust model](docs/SECURITY.md#trust-model) before running one you didn't write.
|
|
8
|
+
|
|
7
9
|
**Python 3.10-3.14 | CUDA (NVIDIA) | MPS (Apple Silicon) | CPU**
|
|
8
10
|
|
|
9
11
|
<picture>
|
|
@@ -14,10 +16,11 @@ A declarative workflow engine and web UI for the [Hugging Face Diffusers library
|
|
|
14
16
|
## Features
|
|
15
17
|
|
|
16
18
|
- **Web UI** — browse and run workflows, edit them in introspection-driven forms, watch jobs stream live progress, manage generated output and the models on disk. `python -m dw.serve` and open a browser. See [Server & Web UI](docs/SERVER.md).
|
|
17
|
-
- **MCP server** — a
|
|
19
|
+
- **MCP server** — a tool surface that lets an MCP client (Claude Code first) author, validate, save, run and diagnose workflows against a running `dw.serve`: `dw-mcp` over stdio, or mounted at `/mcp` by `dw.serve --mcp` for a client on another machine. See [MCP Server](docs/MCP.md) and [Remote GPU server](docs/REMOTE.md).
|
|
20
|
+
- **Step-output caching** — a step whose resolved arguments and seed are unchanged since the last run in the same process reuses its cached result instead of re-executing. This applies to any `Workflow.run` — REPL iteration and a re-run of a server-submitted job alike, so re-running a fixed-seed workflow from the UI finishes instantly and writes no new output files. The cache holds the most recent 50 steps and is dropped by `memory clear`
|
|
18
21
|
- **Declarative JSON workflows** with variable substitution and cross-step data flow
|
|
19
22
|
- **Multi-step pipelines** — chain text-to-image, image-to-video, inpainting, ControlNet
|
|
20
|
-
- **Reproducible by construction** — outputs embed their full workflow definition and seed; any image in the gallery reopens as the exact workflow that made it
|
|
23
|
+
- **Reproducible by construction** — outputs embed their full workflow definition and seed; any image in the gallery reopens as the exact workflow that made it (see [Trust model](docs/SECURITY.md#trust-model) before reopening one someone else sent you). A rerun never overwrites a prior output — a name collision gets an incrementing suffix instead
|
|
21
24
|
- **Long-video chaining** — run a video pipeline once per segment and stitch the segments into one clip, with audio-driven length and frame-to-frame continuity
|
|
22
25
|
- **Quantization** — BitsAndBytes, TorchAO, GGUF, SDNQ, optimum-quanto
|
|
23
26
|
- **Inference acceleration** — TeaCache, FirstBlockCache, FasterCache, MagCache, TaylorSeerCache
|
|
@@ -78,15 +81,26 @@ Jobs queue, stream progress live (per denoising step), cancel cooperatively, and
|
|
|
78
81
|
|
|
79
82
|
### Run a Workflow
|
|
80
83
|
|
|
84
|
+
`workflows/sd15.json` is the smallest, fastest starting point — a small, ungated model and a literal prompt, so the first run needs no Hugging Face login and downloads only a few GB:
|
|
85
|
+
|
|
81
86
|
```bash
|
|
87
|
+
python -m dw.run workflows/sd15.json
|
|
88
|
+
python -m dw.run workflows/sd15.json prompt="a cat" num_images_per_prompt=4
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Most of the workflows under `workflows/` (Flux, LTX-2, MiniMax...) use **gated** Hugging Face models — the repo owner has to approve your account before you can download them. Before running one of those, request access on the model's Hugging Face page (e.g. [black-forest-labs/FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev)) and log in locally:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
huggingface-cli login
|
|
82
95
|
python -m dw.run workflows/flux/FluxDev.json
|
|
83
|
-
python -m dw.run workflows/flux/FluxDev.json prompt="a cat" num_images_per_prompt=4
|
|
84
96
|
```
|
|
85
97
|
|
|
98
|
+
Without this, the run fails partway through with an HTTP 401/403 from the Hub.
|
|
99
|
+
|
|
86
100
|
### Validate a Workflow
|
|
87
101
|
|
|
88
102
|
```bash
|
|
89
|
-
python -m dw.validate workflows/
|
|
103
|
+
python -m dw.validate workflows/sd15.json
|
|
90
104
|
```
|
|
91
105
|
|
|
92
106
|
### Interactive REPL
|
|
@@ -254,6 +268,7 @@ See [workflows/](workflows/) for more workflow files.
|
|
|
254
268
|
|
|
255
269
|
- [Server & Web UI](docs/SERVER.md) — The web UI, jobs API, and introspection service
|
|
256
270
|
- [MCP Server](docs/MCP.md) — Tool surface for MCP clients (Claude Code, Claude Desktop)
|
|
271
|
+
- [Remote GPU server](docs/REMOTE.md) — Using the server, UI and MCP from another machine
|
|
257
272
|
- [Workflow Guide](docs/WORKFLOW_GUIDE.md) — JSON structure, variables, steps, data flow
|
|
258
273
|
- [Quantization](docs/QUANTIZATION.md) — BitsAndBytes, TorchAO, GGUF, SDNQ
|
|
259
274
|
- [Inference Acceleration](docs/ACCELERATION.md) — torch.compile, FirstBlockCache, MagCache, TaylorSeer, TeaCache
|
{diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1/diffusers_workflow.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: diffusers-workflow
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.0b1
|
|
4
4
|
Summary: Declarative workflow engine and web UI for Hugging Face Diffusers
|
|
5
5
|
Author: dkackman
|
|
6
6
|
License: Apache-2.0
|
|
@@ -79,6 +79,8 @@ Dynamic: license-file
|
|
|
79
79
|
|
|
80
80
|
A declarative workflow engine and web UI for the [Hugging Face Diffusers library](https://github.com/huggingface/diffusers). Define image/video generation pipelines in JSON — with full access to the configuration diffusers exposes — and run them from the command line, an interactive REPL, or a browser.
|
|
81
81
|
|
|
82
|
+
A workflow JSON file is portable and easy to hand off — but that same flexibility means loading one can execute arbitrary Python (dynamic imports are how it reaches any diffusers pipeline or quantization backend without a bespoke adapter for each). Treat a workflow file from someone else the way you'd treat a `.py` script: see [Trust model](docs/SECURITY.md#trust-model) before running one you didn't write.
|
|
83
|
+
|
|
82
84
|
**Python 3.10-3.14 | CUDA (NVIDIA) | MPS (Apple Silicon) | CPU**
|
|
83
85
|
|
|
84
86
|
<picture>
|
|
@@ -89,10 +91,11 @@ A declarative workflow engine and web UI for the [Hugging Face Diffusers library
|
|
|
89
91
|
## Features
|
|
90
92
|
|
|
91
93
|
- **Web UI** — browse and run workflows, edit them in introspection-driven forms, watch jobs stream live progress, manage generated output and the models on disk. `python -m dw.serve` and open a browser. See [Server & Web UI](docs/SERVER.md).
|
|
92
|
-
- **MCP server** — a
|
|
94
|
+
- **MCP server** — a tool surface that lets an MCP client (Claude Code first) author, validate, save, run and diagnose workflows against a running `dw.serve`: `dw-mcp` over stdio, or mounted at `/mcp` by `dw.serve --mcp` for a client on another machine. See [MCP Server](docs/MCP.md) and [Remote GPU server](docs/REMOTE.md).
|
|
95
|
+
- **Step-output caching** — a step whose resolved arguments and seed are unchanged since the last run in the same process reuses its cached result instead of re-executing. This applies to any `Workflow.run` — REPL iteration and a re-run of a server-submitted job alike, so re-running a fixed-seed workflow from the UI finishes instantly and writes no new output files. The cache holds the most recent 50 steps and is dropped by `memory clear`
|
|
93
96
|
- **Declarative JSON workflows** with variable substitution and cross-step data flow
|
|
94
97
|
- **Multi-step pipelines** — chain text-to-image, image-to-video, inpainting, ControlNet
|
|
95
|
-
- **Reproducible by construction** — outputs embed their full workflow definition and seed; any image in the gallery reopens as the exact workflow that made it
|
|
98
|
+
- **Reproducible by construction** — outputs embed their full workflow definition and seed; any image in the gallery reopens as the exact workflow that made it (see [Trust model](docs/SECURITY.md#trust-model) before reopening one someone else sent you). A rerun never overwrites a prior output — a name collision gets an incrementing suffix instead
|
|
96
99
|
- **Long-video chaining** — run a video pipeline once per segment and stitch the segments into one clip, with audio-driven length and frame-to-frame continuity
|
|
97
100
|
- **Quantization** — BitsAndBytes, TorchAO, GGUF, SDNQ, optimum-quanto
|
|
98
101
|
- **Inference acceleration** — TeaCache, FirstBlockCache, FasterCache, MagCache, TaylorSeerCache
|
|
@@ -153,15 +156,26 @@ Jobs queue, stream progress live (per denoising step), cancel cooperatively, and
|
|
|
153
156
|
|
|
154
157
|
### Run a Workflow
|
|
155
158
|
|
|
159
|
+
`workflows/sd15.json` is the smallest, fastest starting point — a small, ungated model and a literal prompt, so the first run needs no Hugging Face login and downloads only a few GB:
|
|
160
|
+
|
|
156
161
|
```bash
|
|
162
|
+
python -m dw.run workflows/sd15.json
|
|
163
|
+
python -m dw.run workflows/sd15.json prompt="a cat" num_images_per_prompt=4
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Most of the workflows under `workflows/` (Flux, LTX-2, MiniMax...) use **gated** Hugging Face models — the repo owner has to approve your account before you can download them. Before running one of those, request access on the model's Hugging Face page (e.g. [black-forest-labs/FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev)) and log in locally:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
huggingface-cli login
|
|
157
170
|
python -m dw.run workflows/flux/FluxDev.json
|
|
158
|
-
python -m dw.run workflows/flux/FluxDev.json prompt="a cat" num_images_per_prompt=4
|
|
159
171
|
```
|
|
160
172
|
|
|
173
|
+
Without this, the run fails partway through with an HTTP 401/403 from the Hub.
|
|
174
|
+
|
|
161
175
|
### Validate a Workflow
|
|
162
176
|
|
|
163
177
|
```bash
|
|
164
|
-
python -m dw.validate workflows/
|
|
178
|
+
python -m dw.validate workflows/sd15.json
|
|
165
179
|
```
|
|
166
180
|
|
|
167
181
|
### Interactive REPL
|
|
@@ -329,6 +343,7 @@ See [workflows/](workflows/) for more workflow files.
|
|
|
329
343
|
|
|
330
344
|
- [Server & Web UI](docs/SERVER.md) — The web UI, jobs API, and introspection service
|
|
331
345
|
- [MCP Server](docs/MCP.md) — Tool surface for MCP clients (Claude Code, Claude Desktop)
|
|
346
|
+
- [Remote GPU server](docs/REMOTE.md) — Using the server, UI and MCP from another machine
|
|
332
347
|
- [Workflow Guide](docs/WORKFLOW_GUIDE.md) — JSON structure, variables, steps, data flow
|
|
333
348
|
- [Quantization](docs/QUANTIZATION.md) — BitsAndBytes, TorchAO, GGUF, SDNQ
|
|
334
349
|
- [Inference Acceleration](docs/ACCELERATION.md) — torch.compile, FirstBlockCache, MagCache, TaylorSeer, TeaCache
|
{diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/diffusers_workflow.egg-info/SOURCES.txt
RENAMED
|
@@ -30,6 +30,7 @@ dw/security.py
|
|
|
30
30
|
dw/serve.py
|
|
31
31
|
dw/settings.py
|
|
32
32
|
dw/step.py
|
|
33
|
+
dw/step_cache.py
|
|
33
34
|
dw/teacache.py
|
|
34
35
|
dw/teacache_models.json
|
|
35
36
|
dw/test.py
|
|
@@ -48,6 +49,8 @@ dw/server/__init__.py
|
|
|
48
49
|
dw/server/app.py
|
|
49
50
|
dw/server/enhancers.py
|
|
50
51
|
dw/server/jobs.py
|
|
52
|
+
dw/server/mcp_mount.py
|
|
53
|
+
dw/server/netinfo.py
|
|
51
54
|
dw/server/updater.py
|
|
52
55
|
dw/server/ui/index.html
|
|
53
56
|
dw/server/ui/assets/abap-08VXUWAP.js
|
|
@@ -64,45 +67,45 @@ dw/server/ui/assets/csharp-BKxtCVv1.js
|
|
|
64
67
|
dw/server/ui/assets/csp-bTuwJoIa.js
|
|
65
68
|
dw/server/ui/assets/css-DIMkf-bt.js
|
|
66
69
|
dw/server/ui/assets/css.worker-B3ciXF_0.js
|
|
67
|
-
dw/server/ui/assets/cssMode-
|
|
70
|
+
dw/server/ui/assets/cssMode-DIA5LESv.js
|
|
68
71
|
dw/server/ui/assets/cypher-CVaqCwHa.js
|
|
69
72
|
dw/server/ui/assets/dart-onAF5SnQ.js
|
|
70
73
|
dw/server/ui/assets/dockerfile-DZFCIeNp.js
|
|
71
74
|
dw/server/ui/assets/ecl-D05T4iGw.js
|
|
72
75
|
dw/server/ui/assets/editor-jjEx9u7D.css
|
|
73
|
-
dw/server/ui/assets/editor.api-
|
|
76
|
+
dw/server/ui/assets/editor.api-CuOF-U_A.js
|
|
74
77
|
dw/server/ui/assets/editor.worker-q-txB4vs.js
|
|
75
78
|
dw/server/ui/assets/elixir-6RTg0lbw.js
|
|
76
79
|
dw/server/ui/assets/flow9-C5_-GSwl.js
|
|
77
|
-
dw/server/ui/assets/freemarker2-
|
|
80
|
+
dw/server/ui/assets/freemarker2-xMcLxHzc.js
|
|
78
81
|
dw/server/ui/assets/fsharp-C8Ef5oNN.js
|
|
79
82
|
dw/server/ui/assets/go-C-y9NEjX.js
|
|
80
83
|
dw/server/ui/assets/graphql-fmXr3nnJ.js
|
|
81
|
-
dw/server/ui/assets/handlebars-
|
|
84
|
+
dw/server/ui/assets/handlebars-Dbt47IUh.js
|
|
82
85
|
dw/server/ui/assets/hcl-CpzslTdj.js
|
|
83
|
-
dw/server/ui/assets/html-
|
|
86
|
+
dw/server/ui/assets/html-C4QoqgED.js
|
|
84
87
|
dw/server/ui/assets/html.worker-C93Ht9o9.js
|
|
85
|
-
dw/server/ui/assets/htmlMode-
|
|
86
|
-
dw/server/ui/assets/index-
|
|
87
|
-
dw/server/ui/assets/index-
|
|
88
|
+
dw/server/ui/assets/htmlMode-BQ_x-rQl.js
|
|
89
|
+
dw/server/ui/assets/index-BCNGRglb.css
|
|
90
|
+
dw/server/ui/assets/index-C14JKFhY.js
|
|
88
91
|
dw/server/ui/assets/ini-sBoK_t0W.js
|
|
89
92
|
dw/server/ui/assets/java-BEtHBSE6.js
|
|
90
|
-
dw/server/ui/assets/javascript-
|
|
93
|
+
dw/server/ui/assets/javascript-yDlADdyl.js
|
|
91
94
|
dw/server/ui/assets/json.worker-B2V3pomh.js
|
|
92
|
-
dw/server/ui/assets/jsonMode-
|
|
95
|
+
dw/server/ui/assets/jsonMode-X4znCY4b.js
|
|
93
96
|
dw/server/ui/assets/julia-Bri6UV-V.js
|
|
94
97
|
dw/server/ui/assets/kotlin-BOotOW0E.js
|
|
95
98
|
dw/server/ui/assets/less-B9JPFI3C.js
|
|
96
99
|
dw/server/ui/assets/lexon-CfSJPG6W.js
|
|
97
|
-
dw/server/ui/assets/liquid-
|
|
98
|
-
dw/server/ui/assets/lspLanguageFeatures-
|
|
100
|
+
dw/server/ui/assets/liquid-CAaCQzwu.js
|
|
101
|
+
dw/server/ui/assets/lspLanguageFeatures-CTJIGm94.js
|
|
99
102
|
dw/server/ui/assets/lua-CsQS60Ue.js
|
|
100
103
|
dw/server/ui/assets/m3-D-oSqn_W.js
|
|
101
104
|
dw/server/ui/assets/markdown-Cimd5fb3.js
|
|
102
|
-
dw/server/ui/assets/mdx-
|
|
105
|
+
dw/server/ui/assets/mdx-ByHLng1y.js
|
|
103
106
|
dw/server/ui/assets/mips-CIPQ_RoX.js
|
|
104
107
|
dw/server/ui/assets/monaco--ixms01u.css
|
|
105
|
-
dw/server/ui/assets/monaco-
|
|
108
|
+
dw/server/ui/assets/monaco-LJZc6TiS.js
|
|
106
109
|
dw/server/ui/assets/msdax-DauUninz.js
|
|
107
110
|
dw/server/ui/assets/mysql-SOo6toE5.js
|
|
108
111
|
dw/server/ui/assets/objective-c-FvmIjYaQ.js
|
|
@@ -117,10 +120,10 @@ dw/server/ui/assets/powerquery-D3hlyOfw.js
|
|
|
117
120
|
dw/server/ui/assets/powershell-DmHpPYUd.js
|
|
118
121
|
dw/server/ui/assets/protobuf-C531GsRP.js
|
|
119
122
|
dw/server/ui/assets/pug-Z5eAx3Zn.js
|
|
120
|
-
dw/server/ui/assets/python-
|
|
123
|
+
dw/server/ui/assets/python-BCT_lvfW.js
|
|
121
124
|
dw/server/ui/assets/qsharp-DkqhCAOL.js
|
|
122
125
|
dw/server/ui/assets/r-BwWrilGY.js
|
|
123
|
-
dw/server/ui/assets/razor-
|
|
126
|
+
dw/server/ui/assets/razor-Bw9oTolL.js
|
|
124
127
|
dw/server/ui/assets/redis-ClamHrr6.js
|
|
125
128
|
dw/server/ui/assets/redshift-DT7zqm-g.js
|
|
126
129
|
dw/server/ui/assets/restructuredtext-BYgofb2h.js
|
|
@@ -140,21 +143,22 @@ dw/server/ui/assets/swift-Bxkupp3x.js
|
|
|
140
143
|
dw/server/ui/assets/systemverilog-Bz4Y3fRF.js
|
|
141
144
|
dw/server/ui/assets/tcl-DISqw1ZD.js
|
|
142
145
|
dw/server/ui/assets/ts.worker-D7T1-Ig5.js
|
|
143
|
-
dw/server/ui/assets/tsMode-
|
|
146
|
+
dw/server/ui/assets/tsMode-BGvHTpYz.js
|
|
144
147
|
dw/server/ui/assets/twig-De2hgUGE.js
|
|
145
|
-
dw/server/ui/assets/typescript-
|
|
148
|
+
dw/server/ui/assets/typescript-mwKKpQXP.js
|
|
146
149
|
dw/server/ui/assets/typespec-B8J7ngcE.js
|
|
147
150
|
dw/server/ui/assets/vb-DV3o63ZY.js
|
|
148
151
|
dw/server/ui/assets/wgsl-DpFanUEy.js
|
|
149
|
-
dw/server/ui/assets/workers-
|
|
150
|
-
dw/server/ui/assets/xml-
|
|
151
|
-
dw/server/ui/assets/yaml-
|
|
152
|
+
dw/server/ui/assets/workers-BOhWN9wu.js
|
|
153
|
+
dw/server/ui/assets/xml-DuQ6E6P7.js
|
|
154
|
+
dw/server/ui/assets/yaml-D7o22x0f.js
|
|
152
155
|
dw/tasks/audio_utils.py
|
|
153
156
|
dw/tasks/background_remover.py
|
|
154
157
|
dw/tasks/borders.py
|
|
155
158
|
dw/tasks/concat_videos.py
|
|
156
159
|
dw/tasks/depth_estimator.py
|
|
157
160
|
dw/tasks/diffusion_upscale.py
|
|
161
|
+
dw/tasks/dissolve_videos.py
|
|
158
162
|
dw/tasks/format_messages.py
|
|
159
163
|
dw/tasks/gather.py
|
|
160
164
|
dw/tasks/image_to_text.py
|
|
@@ -166,6 +170,7 @@ dw/tasks/qr_code.py
|
|
|
166
170
|
dw/tasks/restore_faces.py
|
|
167
171
|
dw/tasks/rife_model.py
|
|
168
172
|
dw/tasks/segment.py
|
|
173
|
+
dw/tasks/stabilize.py
|
|
169
174
|
dw/tasks/task.py
|
|
170
175
|
dw/tasks/tensor_image.py
|
|
171
176
|
dw/tasks/text_generation.py
|
|
@@ -203,6 +208,7 @@ tests/test_device.py
|
|
|
203
208
|
tests/test_device_helpers.py
|
|
204
209
|
tests/test_device_portability.py
|
|
205
210
|
tests/test_diffusion_upscale.py
|
|
211
|
+
tests/test_dissolve_videos.py
|
|
206
212
|
tests/test_docs_links.py
|
|
207
213
|
tests/test_events.py
|
|
208
214
|
tests/test_examples.py
|
|
@@ -213,15 +219,18 @@ tests/test_image_utils.py
|
|
|
213
219
|
tests/test_integration.py
|
|
214
220
|
tests/test_interpolate_frames.py
|
|
215
221
|
tests/test_introspection.py
|
|
222
|
+
tests/test_jobs_reused.py
|
|
216
223
|
tests/test_list_images.py
|
|
217
224
|
tests/test_mcp_authoring.py
|
|
218
225
|
tests/test_mcp_catalog.py
|
|
219
226
|
tests/test_mcp_client.py
|
|
220
227
|
tests/test_mcp_diagnose.py
|
|
228
|
+
tests/test_mcp_main.py
|
|
221
229
|
tests/test_mcp_media.py
|
|
222
230
|
tests/test_mcp_models.py
|
|
223
231
|
tests/test_mcp_prompts.py
|
|
224
232
|
tests/test_mcp_server.py
|
|
233
|
+
tests/test_mix_audio.py
|
|
225
234
|
tests/test_model_cache.py
|
|
226
235
|
tests/test_modular_pipeline.py
|
|
227
236
|
tests/test_offload_placement.py
|
|
@@ -233,6 +242,7 @@ tests/test_previous_results.py
|
|
|
233
242
|
tests/test_prompt_parser.py
|
|
234
243
|
tests/test_prompt_weighting.py
|
|
235
244
|
tests/test_prompts.py
|
|
245
|
+
tests/test_recenter_crop.py
|
|
236
246
|
tests/test_repl_commands.py
|
|
237
247
|
tests/test_repl_ergonomics.py
|
|
238
248
|
tests/test_repl_hierarchical.py
|
|
@@ -240,12 +250,19 @@ tests/test_repl_reorganization.py
|
|
|
240
250
|
tests/test_repl_worker.py
|
|
241
251
|
tests/test_resize_bucket.py
|
|
242
252
|
tests/test_result.py
|
|
253
|
+
tests/test_result_output_naming.py
|
|
243
254
|
tests/test_scheduler_config.py
|
|
244
255
|
tests/test_schema.py
|
|
245
256
|
tests/test_security.py
|
|
246
257
|
tests/test_segment.py
|
|
258
|
+
tests/test_serve_main.py
|
|
247
259
|
tests/test_server.py
|
|
260
|
+
tests/test_server_downloads.py
|
|
261
|
+
tests/test_server_info.py
|
|
262
|
+
tests/test_server_mcp.py
|
|
263
|
+
tests/test_stabilize.py
|
|
248
264
|
tests/test_step.py
|
|
265
|
+
tests/test_step_cache.py
|
|
249
266
|
tests/test_strip_exif_and_watermark.py
|
|
250
267
|
tests/test_task.py
|
|
251
268
|
tests/test_task_discovery.py
|
|
@@ -254,8 +271,11 @@ tests/test_tensor_image.py
|
|
|
254
271
|
tests/test_text_generation.py
|
|
255
272
|
tests/test_text_sections.py
|
|
256
273
|
tests/test_type_helpers.py
|
|
274
|
+
tests/test_updater.py
|
|
257
275
|
tests/test_variables.py
|
|
258
276
|
tests/test_video_utils.py
|
|
259
277
|
tests/test_worker.py
|
|
260
278
|
tests/test_worker_execute.py
|
|
261
|
-
tests/test_workflow.py
|
|
279
|
+
tests/test_workflow.py
|
|
280
|
+
tests/test_workflow_step_cache.py
|
|
281
|
+
tests/test_workflow_trust.py
|
|
@@ -29,8 +29,20 @@ warnings.filterwarnings("ignore", category=FutureWarning)
|
|
|
29
29
|
warnings.filterwarnings("ignore", category=UserWarning)
|
|
30
30
|
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
|
31
31
|
|
|
32
|
-
#
|
|
33
|
-
#
|
|
32
|
+
# Eager (but guarded) import of torch. This module's own top-level code needs
|
|
33
|
+
# torch's exceptions/types unconditionally to detect its absence gracefully
|
|
34
|
+
# (see _TORCH_AVAILABLE below) rather than deferring the try/except to first
|
|
35
|
+
# use everywhere torch is touched. It would be nice for a torch-free path like
|
|
36
|
+
# `python -m dw.validate` (pure JSON schema validation) to skip this multi-
|
|
37
|
+
# second import, but that isn't achievable by changing dw/__init__.py alone:
|
|
38
|
+
# dw/validate.py imports dw/workflow.py, which does its own unconditional
|
|
39
|
+
# `import torch` at module scope (Workflow.run() uses torch.Generator() for
|
|
40
|
+
# seeding) - so torch loads regardless of what this module does. Making the
|
|
41
|
+
# import here lazy without also restructuring dw/workflow.py's random-seed
|
|
42
|
+
# handling would just move the cost around, not remove it, and touching
|
|
43
|
+
# dw/workflow.py's import structure is a larger, riskier change than this
|
|
44
|
+
# fix pass is meant to make. Left eager on purpose; see the audit notes for
|
|
45
|
+
# why a real fix needs to start in dw/workflow.py, not here.
|
|
34
46
|
try:
|
|
35
47
|
import torch
|
|
36
48
|
import diffusers
|
|
@@ -27,6 +27,10 @@ class RunContext:
|
|
|
27
27
|
def __init__(self, on_event=None):
|
|
28
28
|
self._on_event = on_event
|
|
29
29
|
self._cancel = threading.Event()
|
|
30
|
+
# The most recent phase this run reported (see emit_phase/PHASES) -
|
|
31
|
+
# cancel() reads it to tell a client whether the cancel takes effect
|
|
32
|
+
# right away or has to wait out an in-flight, non-interruptible phase
|
|
33
|
+
self._current_phase = None
|
|
30
34
|
# Pipeline cache keys this run resolved - the worker evicts entries a
|
|
31
35
|
# run no longer touches, so an edited workflow drops stale models
|
|
32
36
|
self.touched_pipelines = set()
|
|
@@ -40,8 +44,18 @@ class RunContext:
|
|
|
40
44
|
# A broken sink must not kill a run that is otherwise fine
|
|
41
45
|
logger.warning(f"Progress event sink failed on '{event_type}': {e}")
|
|
42
46
|
|
|
47
|
+
def note_phase(self, phase):
|
|
48
|
+
"""Record the run's latest phase - called by emit_phase, read by
|
|
49
|
+
cancel() to judge whether the current phase can be interrupted."""
|
|
50
|
+
self._current_phase = phase
|
|
51
|
+
|
|
43
52
|
def cancel(self):
|
|
44
53
|
self._cancel.set()
|
|
54
|
+
if self._current_phase in NON_INTERRUPTIBLE_PHASES:
|
|
55
|
+
# A model load or a task step has no checkpoint to catch this
|
|
56
|
+
# flag until it finishes - say so, or the client sees the cancel
|
|
57
|
+
# request go silent for however long that takes
|
|
58
|
+
self.emit("cancel_pending", phase=self._current_phase)
|
|
45
59
|
|
|
46
60
|
@property
|
|
47
61
|
def cancelled(self):
|
|
@@ -82,6 +96,11 @@ def deactivate_context(token):
|
|
|
82
96
|
# the run is waiting on, not what any one library is doing internally
|
|
83
97
|
PHASES = ("loading", "cached", "generating", "decoding", "saving", "task")
|
|
84
98
|
|
|
99
|
+
# Phases with no checkpoint of their own: nothing inside a from_pretrained()
|
|
100
|
+
# call or a task handler consults the cancel flag, so a cancel requested
|
|
101
|
+
# during one of these can only take effect once the phase finishes on its own
|
|
102
|
+
NON_INTERRUPTIBLE_PHASES = ("loading", "task")
|
|
103
|
+
|
|
85
104
|
|
|
86
105
|
def emit_phase(phase, detail=None):
|
|
87
106
|
"""Report a coarse phase change on the active run.
|
|
@@ -92,4 +111,6 @@ def emit_phase(phase, detail=None):
|
|
|
92
111
|
enough (a handful per step) to carry a free-text detail alongside, which
|
|
93
112
|
is what makes 'loading' readable as 'which model'.
|
|
94
113
|
"""
|
|
95
|
-
|
|
114
|
+
context = get_context()
|
|
115
|
+
context.note_phase(phase)
|
|
116
|
+
context.emit("phase", phase=phase, detail=detail)
|
|
@@ -35,8 +35,7 @@ import torch
|
|
|
35
35
|
from diffusers.utils import encode_video, is_av_available
|
|
36
36
|
|
|
37
37
|
from .. import empty_device_cache
|
|
38
|
-
from ..result import AudioVideo, get_artifact_list
|
|
39
|
-
from ..security import validate_output_path
|
|
38
|
+
from ..result import AudioVideo, get_artifact_list, output_file_path
|
|
40
39
|
from ..tasks.audio_utils import (
|
|
41
40
|
as_channels_samples,
|
|
42
41
|
equal_power_crossfade_join,
|
|
@@ -165,6 +164,11 @@ class SegmentedFrames:
|
|
|
165
164
|
self.paths = list(paths)
|
|
166
165
|
self.total_frames = total_frames
|
|
167
166
|
self.keep_files = keep_files
|
|
167
|
+
# True once cleanup() has actually removed the files (not when
|
|
168
|
+
# keep_files skipped that) - a cached Result pointing at a cleaned-up
|
|
169
|
+
# SegmentedFrames must not be served to a later miss, since the files
|
|
170
|
+
# a replay would open are gone. See Result.retainable.
|
|
171
|
+
self.cleaned = False
|
|
168
172
|
|
|
169
173
|
def __len__(self):
|
|
170
174
|
"""Chunk count - one per segment file."""
|
|
@@ -191,6 +195,7 @@ class SegmentedFrames:
|
|
|
191
195
|
os.remove(path)
|
|
192
196
|
except FileNotFoundError:
|
|
193
197
|
pass
|
|
198
|
+
self.cleaned = True
|
|
194
199
|
|
|
195
200
|
|
|
196
201
|
class SegmentSpill:
|
|
@@ -240,12 +245,14 @@ class SegmentSpill:
|
|
|
240
245
|
chain leaves fully playable segments
|
|
241
246
|
sample_rate: Sample rate of that audio
|
|
242
247
|
"""
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
+
# A crashed or completed chain leaves segment files behind on disk,
|
|
249
|
+
# ready to salvage - and the per-wrapper iteration counter (base_name)
|
|
250
|
+
# restarts at 0 in a fresh process, so a rerun must dedupe through the
|
|
251
|
+
# same '-N' convention every other output goes through rather than
|
|
252
|
+
# silently overwriting them.
|
|
253
|
+
path = output_file_path(
|
|
248
254
|
self.output_dir,
|
|
255
|
+
f"{self.base_name}.segment-{len(self.paths):03d}.mp4",
|
|
249
256
|
)
|
|
250
257
|
|
|
251
258
|
audio_track = None
|
{diffusers_workflow-0.4.0a10 → diffusers_workflow-0.4.0b1}/dw/pipeline_processors/pipeline.py
RENAMED
|
@@ -16,6 +16,10 @@ from .remote import remote_text_encoder
|
|
|
16
16
|
from ..cache_blocks import register_cache_blocks
|
|
17
17
|
from ..teacache import teacache_context
|
|
18
18
|
from ..type_helpers import has_method
|
|
19
|
+
from ..security import (
|
|
20
|
+
require_trusted_from_pretrained_arguments,
|
|
21
|
+
require_trusted_pre_load_modules,
|
|
22
|
+
)
|
|
19
23
|
from .. import empty_device_cache, get_device_type, resolve_device
|
|
20
24
|
from diffusers import attention_backend
|
|
21
25
|
|
|
@@ -23,6 +27,7 @@ from diffusers import attention_backend
|
|
|
23
27
|
# imported where they are used - at module scope they add seconds to every startup
|
|
24
28
|
|
|
25
29
|
from ..events import WorkflowCancelled, emit_phase, get_context
|
|
30
|
+
from huggingface_hub.errors import HfHubHTTPError
|
|
26
31
|
|
|
27
32
|
logger = logging.getLogger("dw")
|
|
28
33
|
|
|
@@ -224,8 +229,12 @@ class Pipeline:
|
|
|
224
229
|
logger.debug(f"Loading pipeline: {self.name}")
|
|
225
230
|
|
|
226
231
|
# Import modules that need to register with diffusers/transformers before loading
|
|
227
|
-
# (e.g., sdnq registers its quantization method on import)
|
|
228
|
-
|
|
232
|
+
# (e.g., sdnq registers its quantization method on import). This runs
|
|
233
|
+
# arbitrary python at import time, so an untrusted workflow is refused
|
|
234
|
+
# here unless --trust-workflows was passed - see docs/SECURITY.md
|
|
235
|
+
pre_load_modules = self.configuration.get("pre_load_modules", [])
|
|
236
|
+
require_trusted_pre_load_modules(pre_load_modules)
|
|
237
|
+
for module_name in pre_load_modules:
|
|
229
238
|
logger.info(f"Pre-loading module: {module_name}")
|
|
230
239
|
importlib.import_module(module_name)
|
|
231
240
|
|
|
@@ -1509,6 +1518,10 @@ def load_component(
|
|
|
1509
1518
|
component_type = configuration["component_type"]
|
|
1510
1519
|
component = None
|
|
1511
1520
|
|
|
1521
|
+
# Refused before anything reaches the Hub: an untrusted workflow must not
|
|
1522
|
+
# be able to have diffusers fetch and run code on its behalf
|
|
1523
|
+
require_trusted_from_pretrained_arguments(from_pretrained_arguments, component_name)
|
|
1524
|
+
|
|
1512
1525
|
# A standard pipeline takes a component as a constructor argument. A modular one
|
|
1513
1526
|
# cannot: it is built from the component specs in its own index and given the
|
|
1514
1527
|
# objects afterwards, which is also what keeps load_components() from pulling a
|
|
@@ -1537,6 +1550,7 @@ def load_component(
|
|
|
1537
1550
|
f"Consider changing torch_dtype from float16 to float32 for {component_name} "
|
|
1538
1551
|
)
|
|
1539
1552
|
|
|
1553
|
+
model_name = None
|
|
1540
1554
|
try:
|
|
1541
1555
|
with loading_device(configuration):
|
|
1542
1556
|
# Load from model name
|
|
@@ -1600,12 +1614,44 @@ def load_component(
|
|
|
1600
1614
|
)
|
|
1601
1615
|
|
|
1602
1616
|
except Exception as e:
|
|
1603
|
-
#
|
|
1604
|
-
#
|
|
1617
|
+
# 401/403 from the Hub means the account behind whatever token (or
|
|
1618
|
+
# lack of one) HfApi is using cannot read this repo - almost always
|
|
1619
|
+
# a gated model the user has not requested access to, or has not
|
|
1620
|
+
# logged in for. A whole-pipeline load raises the HfHubHTTPError
|
|
1621
|
+
# itself; a per-component load gets it wrapped in an EnvironmentError
|
|
1622
|
+
# by diffusers' _get_model_file / transformers' cached_file, so the
|
|
1623
|
+
# cause chain is searched. Every other error (a real outage, a bad
|
|
1624
|
+
# repo id) is logged once with its traceback and re-raised unchanged
|
|
1625
|
+
if _hub_auth_status(e) is not None:
|
|
1626
|
+
repo = model_name or component_name
|
|
1627
|
+
logger.error(
|
|
1628
|
+
f"Hugging Face authentication required loading {component_name} "
|
|
1629
|
+
f"({repo}): {e}",
|
|
1630
|
+
exc_info=True,
|
|
1631
|
+
)
|
|
1632
|
+
raise RuntimeError(
|
|
1633
|
+
f"Model '{repo}' requires Hugging Face authentication - run "
|
|
1634
|
+
f"'huggingface-cli login', or request access at "
|
|
1635
|
+
f"https://huggingface.co/{repo}"
|
|
1636
|
+
) from e
|
|
1605
1637
|
logger.error(f"{type(e).__name__} loading {component_name}: {e}", exc_info=True)
|
|
1606
1638
|
raise
|
|
1607
1639
|
|
|
1608
1640
|
|
|
1641
|
+
def _hub_auth_status(error):
|
|
1642
|
+
"""The 401/403 status an exception (or anything in its cause/context
|
|
1643
|
+
chain) carries from the Hub, else None."""
|
|
1644
|
+
seen = set()
|
|
1645
|
+
while error is not None and id(error) not in seen:
|
|
1646
|
+
seen.add(id(error))
|
|
1647
|
+
if isinstance(error, HfHubHTTPError):
|
|
1648
|
+
status = getattr(getattr(error, "response", None), "status_code", None)
|
|
1649
|
+
if status in (401, 403):
|
|
1650
|
+
return status
|
|
1651
|
+
error = error.__cause__ or error.__context__
|
|
1652
|
+
return None
|
|
1653
|
+
|
|
1654
|
+
|
|
1609
1655
|
def apply_sdnq_optimizations(pipeline, component_names):
|
|
1610
1656
|
"""Apply SDNQ quantized matmul optimization to pipeline components.
|
|
1611
1657
|
|
|
@@ -6,6 +6,7 @@ from .arguments import (
|
|
|
6
6
|
PREVIOUS_RESULT_PREFIX,
|
|
7
7
|
build_objects,
|
|
8
8
|
)
|
|
9
|
+
from .step_cache import reference_resolves_to
|
|
9
10
|
|
|
10
11
|
logger = logging.getLogger("dw")
|
|
11
12
|
|
|
@@ -126,13 +127,14 @@ def get_previous_results(previous_results, previous_result_name):
|
|
|
126
127
|
f"Previous result '{previous_result_name}' not found. Available results: {list(previous_results.keys())}"
|
|
127
128
|
)
|
|
128
129
|
|
|
129
|
-
# Find the longest known step name
|
|
130
|
-
#
|
|
130
|
+
# Find the longest known step name the reference resolves to, and treat
|
|
131
|
+
# the remainder as the property name. The exact-match case returned
|
|
132
|
+
# above, so every name reaching here is a strict '<name>.' prefix.
|
|
131
133
|
result_name = max(
|
|
132
134
|
(
|
|
133
135
|
name
|
|
134
136
|
for name in previous_results
|
|
135
|
-
if previous_result_name
|
|
137
|
+
if reference_resolves_to(previous_result_name, name)
|
|
136
138
|
),
|
|
137
139
|
key=len,
|
|
138
140
|
default=None,
|