diffusers-workflow 0.4.0a8__tar.gz → 0.4.0a12__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.0a8/diffusers_workflow.egg-info → diffusers_workflow-0.4.0a12}/PKG-INFO +23 -4
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/README.md +18 -3
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12/diffusers_workflow.egg-info}/PKG-INFO +23 -4
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/diffusers_workflow.egg-info/SOURCES.txt +47 -22
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/diffusers_workflow.egg-info/entry_points.txt +1 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/diffusers_workflow.egg-info/requires.txt +5 -0
- diffusers_workflow-0.4.0a12/diffusers_workflow.egg-info/top_level.txt +2 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/__init__.py +89 -2
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/events.py +38 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/hub_cache.py +5 -2
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/introspection.py +76 -15
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/pipeline_processors/chain.py +5 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/pipeline_processors/config_objects.py +4 -2
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/pipeline_processors/pipeline.py +125 -15
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/previous_results.py +13 -8
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/repl.py +18 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/result.py +20 -2
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/run.py +19 -1
- diffusers_workflow-0.4.0a12/dw/schema.py +43 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/security.py +187 -4
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/serve.py +49 -1
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/app.py +457 -46
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/jobs.py +79 -5
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/cssMode-4JQhrTTm.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/cssMode-CRm5Fmld.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/editor.api-B_68laXH.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/editor.api-CArwgKCZ.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/freemarker2-C4IxK8gs.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/freemarker2-B42MpbWP.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/handlebars-BArDGhF4.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/handlebars-BhleeD_A.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/html-8yKFx0-x.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/html-Bi_v7qEe.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/htmlMode-BwXG6XFP.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/htmlMode-c39yjrZR.js +1 -1
- diffusers_workflow-0.4.0a12/dw/server/ui/assets/index-CKHZ9ZUD.css +1 -0
- diffusers_workflow-0.4.0a12/dw/server/ui/assets/index-Do_ZJ3yS.js +23 -0
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/javascript-B3mqpFQQ.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/javascript-BTuzJzdO.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/jsonMode-C1m5Z8Ha.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/jsonMode-DY2FmMCP.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/liquid-Cs5oVPJ1.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/liquid-iXwDEnQP.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/lspLanguageFeatures-CnroSKaf.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/lspLanguageFeatures-CVXyTq9V.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/mdx-BGAIyUWE.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/mdx-QE70XlV0.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/monaco-ab9gu2Wi.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/monaco-CzCru1EC.js +4 -4
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/python-XsfASqaE.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/python-DxHS-kHp.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/razor-C-1xVmcy.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/razor-CT5Qrhwg.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/tsMode-BDa9GeVq.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/tsMode-qXdDdnF1.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/typescript-VE9GZNZf.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/typescript-BWfJagji.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/workers-C_2pIPh_.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/workers-C9vxrwoC.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/xml-BJp06vju.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/xml-DhJEwsDK.js +1 -1
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/yaml-EI9SS79i.js → diffusers_workflow-0.4.0a12/dw/server/ui/assets/yaml-CiixMxAq.js +1 -1
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/index.html +2 -2
- diffusers_workflow-0.4.0a12/dw/server/updater.py +192 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/step.py +41 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/task.py +7 -2
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/text_generation.py +15 -2
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/type_helpers.py +12 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/validate.py +13 -1
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/variables.py +92 -38
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/workflow.py +61 -7
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/workflow_schema.json +2 -2
- diffusers_workflow-0.4.0a12/dw_mcp/__init__.py +6 -0
- diffusers_workflow-0.4.0a12/dw_mcp/__main__.py +47 -0
- diffusers_workflow-0.4.0a12/dw_mcp/authoring.py +37 -0
- diffusers_workflow-0.4.0a12/dw_mcp/catalog.py +83 -0
- diffusers_workflow-0.4.0a12/dw_mcp/client.py +213 -0
- diffusers_workflow-0.4.0a12/dw_mcp/diagnose.py +139 -0
- diffusers_workflow-0.4.0a12/dw_mcp/media.py +133 -0
- diffusers_workflow-0.4.0a12/dw_mcp/models.py +97 -0
- diffusers_workflow-0.4.0a12/dw_mcp/prompts.py +91 -0
- diffusers_workflow-0.4.0a12/dw_mcp/server.py +403 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/pyproject.toml +4 -1
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_arguments.py +3 -2
- diffusers_workflow-0.4.0a12/tests/test_cli.py +198 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_config_objects.py +10 -2
- diffusers_workflow-0.4.0a12/tests/test_device.py +150 -0
- diffusers_workflow-0.4.0a12/tests/test_device_portability.py +116 -0
- diffusers_workflow-0.4.0a12/tests/test_mcp_authoring.py +156 -0
- diffusers_workflow-0.4.0a12/tests/test_mcp_catalog.py +118 -0
- diffusers_workflow-0.4.0a12/tests/test_mcp_client.py +409 -0
- diffusers_workflow-0.4.0a12/tests/test_mcp_diagnose.py +334 -0
- diffusers_workflow-0.4.0a12/tests/test_mcp_media.py +377 -0
- diffusers_workflow-0.4.0a12/tests/test_mcp_models.py +187 -0
- diffusers_workflow-0.4.0a12/tests/test_mcp_prompts.py +267 -0
- diffusers_workflow-0.4.0a12/tests/test_mcp_server.py +740 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_modular_pipeline.py +97 -2
- diffusers_workflow-0.4.0a12/tests/test_offload_placement.py +105 -0
- diffusers_workflow-0.4.0a12/tests/test_phase_events.py +303 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_pipeline_components.py +33 -1
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_previous_results.py +48 -0
- diffusers_workflow-0.4.0a12/tests/test_repl_worker.py +77 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_result.py +35 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_security.py +57 -0
- diffusers_workflow-0.4.0a12/tests/test_server.py +2284 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_step.py +82 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_task.py +1 -1
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_task_discovery.py +43 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_text_generation.py +38 -0
- diffusers_workflow-0.4.0a12/tests/test_updater.py +126 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_variables.py +61 -15
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_workflow.py +96 -0
- diffusers_workflow-0.4.0a12/tests/test_workflow_trust.py +237 -0
- diffusers_workflow-0.4.0a8/diffusers_workflow.egg-info/top_level.txt +0 -1
- diffusers_workflow-0.4.0a8/dw/schema.py +0 -24
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/index-BY3Mtj4M.js +0 -17
- diffusers_workflow-0.4.0a8/dw/server/ui/assets/index-Bug26k2P.css +0 -1
- diffusers_workflow-0.4.0a8/dw/server/updater.py +0 -119
- diffusers_workflow-0.4.0a8/tests/test_device.py +0 -59
- diffusers_workflow-0.4.0a8/tests/test_server.py +0 -1109
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/LICENSE +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/MANIFEST.in +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/diffusers_workflow.egg-info/dependency_links.txt +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/arguments.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/cache_blocks.json +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/cache_blocks.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/community_pipelines/pipeline_flux_rf_inversion.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/log_setup.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/pipeline_processors/remote.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/prompt_schema.json +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/prompt_weighting.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/prompts.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/repl_commands.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/repl_worker.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/__init__.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/enhancers.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/abap-08VXUWAP.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/apex-BWPQTe0t.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/azcli-Bc_sGQ0U.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/bat-i0X4ZdIN.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/bicep-B5-_aFwp.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/cameligo-DMUM7wLl.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/clojure-Cm7r79vr.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/codicon-Brq4_Ui5.ttf +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/coffee-Ba7i2nA0.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/cpp-C7h46wYY.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/csharp-BKxtCVv1.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/csp-bTuwJoIa.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/css-DIMkf-bt.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/css.worker-B3ciXF_0.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/cypher-CVaqCwHa.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/dart-onAF5SnQ.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/dockerfile-DZFCIeNp.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/ecl-D05T4iGw.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/editor-jjEx9u7D.css +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/editor.worker-q-txB4vs.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/elixir-6RTg0lbw.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/flow9-C5_-GSwl.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/fsharp-C8Ef5oNN.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/go-C-y9NEjX.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/graphql-fmXr3nnJ.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/hcl-CpzslTdj.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/html.worker-C93Ht9o9.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/ini-sBoK_t0W.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/java-BEtHBSE6.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/json.worker-B2V3pomh.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/julia-Bri6UV-V.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/kotlin-BOotOW0E.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/less-B9JPFI3C.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/lexon-CfSJPG6W.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/lua-CsQS60Ue.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/m3-D-oSqn_W.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/markdown-Cimd5fb3.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/mips-CIPQ_RoX.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/monaco--ixms01u.css +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/msdax-DauUninz.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/mysql-SOo6toE5.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/objective-c-FvmIjYaQ.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/pascal-DrH0SRf2.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/pascaligo-D-ptJ9y-.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/perl-oz_6vUea.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/pgsql-DTj74zXo.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/php-nr791fC2.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/pla-CopQ2nXW.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/postiats-43DmfD33.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/powerquery-D3hlyOfw.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/powershell-DmHpPYUd.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/protobuf-C531GsRP.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/pug-Z5eAx3Zn.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/qsharp-DkqhCAOL.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/r-BwWrilGY.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/redis-ClamHrr6.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/redshift-DT7zqm-g.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/restructuredtext-BYgofb2h.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/ruby-DezsRK8O.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/rust-DdL9SqIa.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/sb-CcwsVR0C.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/scala-DHpiXF5c.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/scheme-BeGwcela.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/scss-gp-XZpBa.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/shell-CC2rA5mh.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/solidity-BEEn4gHE.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/sophia-CRfGWb83.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/sparql-D_Lu-MrJ.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/sql-NEE52Syq.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/st-DbInun42.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/swift-Bxkupp3x.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/systemverilog-Bz4Y3fRF.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/tcl-DISqw1ZD.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/ts.worker-D7T1-Ig5.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/twig-De2hgUGE.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/typespec-B8J7ngcE.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/vb-DV3o63ZY.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/server/ui/assets/wgsl-DpFanUEy.js +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/settings.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/audio_utils.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/background_remover.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/borders.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/concat_videos.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/depth_estimator.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/diffusion_upscale.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/format_messages.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/gather.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/image_to_text.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/image_utils.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/interpolate_frames.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/model_cache.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/pair_audio.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/qr_code.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/restore_faces.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/rife_model.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/segment.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/tensor_image.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/text_sections.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/upscale.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/video_utils.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/tasks/zoe_depth.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/teacache.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/teacache_models.json +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/test.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/worker.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/workflows/augment_prompt.json +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/workflows/describe_image.json +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/workflows/h3_context_ir.json +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/dw/workflows/test.json +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/setup.cfg +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_argument_updates.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_audio_utils.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_borders.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_cache_blocks.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_chain.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_component_pruning.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_concat_videos.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_configuration_schema.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_depth_estimator.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_device_helpers.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_diffusion_upscale.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_docs_links.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_events.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_examples.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_gather.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_hub_cache.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_image_to_text.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_image_utils.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_integration.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_interpolate_frames.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_introspection.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_list_images.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_model_cache.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_pair_audio.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_pipeline_caching.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_prompt_parser.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_prompt_weighting.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_prompts.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_repl_commands.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_repl_ergonomics.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_repl_hierarchical.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_repl_reorganization.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_resize_bucket.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_scheduler_config.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_schema.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_segment.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_strip_exif_and_watermark.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_teacache.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_tensor_image.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_text_sections.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_type_helpers.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_video_utils.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_worker.py +0 -0
- {diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/tests/test_worker_execute.py +0 -0
{diffusers_workflow-0.4.0a8/diffusers_workflow.egg-info → diffusers_workflow-0.4.0a12}/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.0a12
|
|
4
4
|
Summary: Declarative workflow engine and web UI for Hugging Face Diffusers
|
|
5
5
|
Author: dkackman
|
|
6
6
|
License: Apache-2.0
|
|
@@ -57,6 +57,9 @@ Requires-Dist: packaging>=26.3
|
|
|
57
57
|
Provides-Extra: server
|
|
58
58
|
Requires-Dist: fastapi>=0.141.1; extra == "server"
|
|
59
59
|
Requires-Dist: uvicorn[standard]>=0.52.4; extra == "server"
|
|
60
|
+
Provides-Extra: mcp
|
|
61
|
+
Requires-Dist: mcp>=2.1.1; extra == "mcp"
|
|
62
|
+
Requires-Dist: httpx>=0.28.1; extra == "mcp"
|
|
60
63
|
Provides-Extra: dev
|
|
61
64
|
Requires-Dist: pytest>=9.1.1; extra == "dev"
|
|
62
65
|
Requires-Dist: pytest-cov>=7.1.0; extra == "dev"
|
|
@@ -67,6 +70,7 @@ Requires-Dist: pytest-asyncio>=1.4.0; extra == "dev"
|
|
|
67
70
|
Requires-Dist: httpx>=0.28.1; extra == "dev"
|
|
68
71
|
Requires-Dist: black>=26.5.1; extra == "dev"
|
|
69
72
|
Requires-Dist: build; extra == "dev"
|
|
73
|
+
Requires-Dist: mcp>=2.1.1; extra == "dev"
|
|
70
74
|
Dynamic: license-file
|
|
71
75
|
|
|
72
76
|
[](https://github.com/dkackman/diffusers-workflow/actions/workflows/github-code-scanning/codeql)
|
|
@@ -75,6 +79,8 @@ Dynamic: license-file
|
|
|
75
79
|
|
|
76
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.
|
|
77
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
|
+
|
|
78
84
|
**Python 3.10-3.14 | CUDA (NVIDIA) | MPS (Apple Silicon) | CPU**
|
|
79
85
|
|
|
80
86
|
<picture>
|
|
@@ -85,9 +91,10 @@ A declarative workflow engine and web UI for the [Hugging Face Diffusers library
|
|
|
85
91
|
## Features
|
|
86
92
|
|
|
87
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).
|
|
94
|
+
- **MCP server** — a stdio server that lets an MCP client (Claude Code first) author, validate, save, run and diagnose workflows against a running `dw.serve`. `dw-mcp`. See [MCP Server](docs/MCP.md).
|
|
88
95
|
- **Declarative JSON workflows** with variable substitution and cross-step data flow
|
|
89
96
|
- **Multi-step pipelines** — chain text-to-image, image-to-video, inpainting, ControlNet
|
|
90
|
-
- **Reproducible by construction** — outputs embed their full workflow definition and seed; any image in the gallery reopens as the exact workflow that made it
|
|
97
|
+
- **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)
|
|
91
98
|
- **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
|
|
92
99
|
- **Quantization** — BitsAndBytes, TorchAO, GGUF, SDNQ, optimum-quanto
|
|
93
100
|
- **Inference acceleration** — TeaCache, FirstBlockCache, FasterCache, MagCache, TaylorSeerCache
|
|
@@ -148,15 +155,26 @@ Jobs queue, stream progress live (per denoising step), cancel cooperatively, and
|
|
|
148
155
|
|
|
149
156
|
### Run a Workflow
|
|
150
157
|
|
|
158
|
+
`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:
|
|
159
|
+
|
|
151
160
|
```bash
|
|
161
|
+
python -m dw.run workflows/sd15.json
|
|
162
|
+
python -m dw.run workflows/sd15.json prompt="a cat" num_images_per_prompt=4
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
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:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
huggingface-cli login
|
|
152
169
|
python -m dw.run workflows/flux/FluxDev.json
|
|
153
|
-
python -m dw.run workflows/flux/FluxDev.json prompt="a cat" num_images_per_prompt=4
|
|
154
170
|
```
|
|
155
171
|
|
|
172
|
+
Without this, the run fails partway through with an HTTP 401/403 from the Hub.
|
|
173
|
+
|
|
156
174
|
### Validate a Workflow
|
|
157
175
|
|
|
158
176
|
```bash
|
|
159
|
-
python -m dw.validate workflows/
|
|
177
|
+
python -m dw.validate workflows/sd15.json
|
|
160
178
|
```
|
|
161
179
|
|
|
162
180
|
### Interactive REPL
|
|
@@ -323,6 +341,7 @@ See [workflows/](workflows/) for more workflow files.
|
|
|
323
341
|
### Guides
|
|
324
342
|
|
|
325
343
|
- [Server & Web UI](docs/SERVER.md) — The web UI, jobs API, and introspection service
|
|
344
|
+
- [MCP Server](docs/MCP.md) — Tool surface for MCP clients (Claude Code, Claude Desktop)
|
|
326
345
|
- [Workflow Guide](docs/WORKFLOW_GUIDE.md) — JSON structure, variables, steps, data flow
|
|
327
346
|
- [Quantization](docs/QUANTIZATION.md) — BitsAndBytes, TorchAO, GGUF, SDNQ
|
|
328
347
|
- [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,9 +16,10 @@ 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).
|
|
19
|
+
- **MCP server** — a stdio server that lets an MCP client (Claude Code first) author, validate, save, run and diagnose workflows against a running `dw.serve`. `dw-mcp`. See [MCP Server](docs/MCP.md).
|
|
17
20
|
- **Declarative JSON workflows** with variable substitution and cross-step data flow
|
|
18
21
|
- **Multi-step pipelines** — chain text-to-image, image-to-video, inpainting, ControlNet
|
|
19
|
-
- **Reproducible by construction** — outputs embed their full workflow definition and seed; any image in the gallery reopens as the exact workflow that made it
|
|
22
|
+
- **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)
|
|
20
23
|
- **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
|
|
21
24
|
- **Quantization** — BitsAndBytes, TorchAO, GGUF, SDNQ, optimum-quanto
|
|
22
25
|
- **Inference acceleration** — TeaCache, FirstBlockCache, FasterCache, MagCache, TaylorSeerCache
|
|
@@ -77,15 +80,26 @@ Jobs queue, stream progress live (per denoising step), cancel cooperatively, and
|
|
|
77
80
|
|
|
78
81
|
### Run a Workflow
|
|
79
82
|
|
|
83
|
+
`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:
|
|
84
|
+
|
|
80
85
|
```bash
|
|
86
|
+
python -m dw.run workflows/sd15.json
|
|
87
|
+
python -m dw.run workflows/sd15.json prompt="a cat" num_images_per_prompt=4
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
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:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
huggingface-cli login
|
|
81
94
|
python -m dw.run workflows/flux/FluxDev.json
|
|
82
|
-
python -m dw.run workflows/flux/FluxDev.json prompt="a cat" num_images_per_prompt=4
|
|
83
95
|
```
|
|
84
96
|
|
|
97
|
+
Without this, the run fails partway through with an HTTP 401/403 from the Hub.
|
|
98
|
+
|
|
85
99
|
### Validate a Workflow
|
|
86
100
|
|
|
87
101
|
```bash
|
|
88
|
-
python -m dw.validate workflows/
|
|
102
|
+
python -m dw.validate workflows/sd15.json
|
|
89
103
|
```
|
|
90
104
|
|
|
91
105
|
### Interactive REPL
|
|
@@ -252,6 +266,7 @@ See [workflows/](workflows/) for more workflow files.
|
|
|
252
266
|
### Guides
|
|
253
267
|
|
|
254
268
|
- [Server & Web UI](docs/SERVER.md) — The web UI, jobs API, and introspection service
|
|
269
|
+
- [MCP Server](docs/MCP.md) — Tool surface for MCP clients (Claude Code, Claude Desktop)
|
|
255
270
|
- [Workflow Guide](docs/WORKFLOW_GUIDE.md) — JSON structure, variables, steps, data flow
|
|
256
271
|
- [Quantization](docs/QUANTIZATION.md) — BitsAndBytes, TorchAO, GGUF, SDNQ
|
|
257
272
|
- [Inference Acceleration](docs/ACCELERATION.md) — torch.compile, FirstBlockCache, MagCache, TaylorSeer, TeaCache
|
{diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12/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.0a12
|
|
4
4
|
Summary: Declarative workflow engine and web UI for Hugging Face Diffusers
|
|
5
5
|
Author: dkackman
|
|
6
6
|
License: Apache-2.0
|
|
@@ -57,6 +57,9 @@ Requires-Dist: packaging>=26.3
|
|
|
57
57
|
Provides-Extra: server
|
|
58
58
|
Requires-Dist: fastapi>=0.141.1; extra == "server"
|
|
59
59
|
Requires-Dist: uvicorn[standard]>=0.52.4; extra == "server"
|
|
60
|
+
Provides-Extra: mcp
|
|
61
|
+
Requires-Dist: mcp>=2.1.1; extra == "mcp"
|
|
62
|
+
Requires-Dist: httpx>=0.28.1; extra == "mcp"
|
|
60
63
|
Provides-Extra: dev
|
|
61
64
|
Requires-Dist: pytest>=9.1.1; extra == "dev"
|
|
62
65
|
Requires-Dist: pytest-cov>=7.1.0; extra == "dev"
|
|
@@ -67,6 +70,7 @@ Requires-Dist: pytest-asyncio>=1.4.0; extra == "dev"
|
|
|
67
70
|
Requires-Dist: httpx>=0.28.1; extra == "dev"
|
|
68
71
|
Requires-Dist: black>=26.5.1; extra == "dev"
|
|
69
72
|
Requires-Dist: build; extra == "dev"
|
|
73
|
+
Requires-Dist: mcp>=2.1.1; extra == "dev"
|
|
70
74
|
Dynamic: license-file
|
|
71
75
|
|
|
72
76
|
[](https://github.com/dkackman/diffusers-workflow/actions/workflows/github-code-scanning/codeql)
|
|
@@ -75,6 +79,8 @@ Dynamic: license-file
|
|
|
75
79
|
|
|
76
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.
|
|
77
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
|
+
|
|
78
84
|
**Python 3.10-3.14 | CUDA (NVIDIA) | MPS (Apple Silicon) | CPU**
|
|
79
85
|
|
|
80
86
|
<picture>
|
|
@@ -85,9 +91,10 @@ A declarative workflow engine and web UI for the [Hugging Face Diffusers library
|
|
|
85
91
|
## Features
|
|
86
92
|
|
|
87
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).
|
|
94
|
+
- **MCP server** — a stdio server that lets an MCP client (Claude Code first) author, validate, save, run and diagnose workflows against a running `dw.serve`. `dw-mcp`. See [MCP Server](docs/MCP.md).
|
|
88
95
|
- **Declarative JSON workflows** with variable substitution and cross-step data flow
|
|
89
96
|
- **Multi-step pipelines** — chain text-to-image, image-to-video, inpainting, ControlNet
|
|
90
|
-
- **Reproducible by construction** — outputs embed their full workflow definition and seed; any image in the gallery reopens as the exact workflow that made it
|
|
97
|
+
- **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)
|
|
91
98
|
- **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
|
|
92
99
|
- **Quantization** — BitsAndBytes, TorchAO, GGUF, SDNQ, optimum-quanto
|
|
93
100
|
- **Inference acceleration** — TeaCache, FirstBlockCache, FasterCache, MagCache, TaylorSeerCache
|
|
@@ -148,15 +155,26 @@ Jobs queue, stream progress live (per denoising step), cancel cooperatively, and
|
|
|
148
155
|
|
|
149
156
|
### Run a Workflow
|
|
150
157
|
|
|
158
|
+
`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:
|
|
159
|
+
|
|
151
160
|
```bash
|
|
161
|
+
python -m dw.run workflows/sd15.json
|
|
162
|
+
python -m dw.run workflows/sd15.json prompt="a cat" num_images_per_prompt=4
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
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:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
huggingface-cli login
|
|
152
169
|
python -m dw.run workflows/flux/FluxDev.json
|
|
153
|
-
python -m dw.run workflows/flux/FluxDev.json prompt="a cat" num_images_per_prompt=4
|
|
154
170
|
```
|
|
155
171
|
|
|
172
|
+
Without this, the run fails partway through with an HTTP 401/403 from the Hub.
|
|
173
|
+
|
|
156
174
|
### Validate a Workflow
|
|
157
175
|
|
|
158
176
|
```bash
|
|
159
|
-
python -m dw.validate workflows/
|
|
177
|
+
python -m dw.validate workflows/sd15.json
|
|
160
178
|
```
|
|
161
179
|
|
|
162
180
|
### Interactive REPL
|
|
@@ -323,6 +341,7 @@ See [workflows/](workflows/) for more workflow files.
|
|
|
323
341
|
### Guides
|
|
324
342
|
|
|
325
343
|
- [Server & Web UI](docs/SERVER.md) — The web UI, jobs API, and introspection service
|
|
344
|
+
- [MCP Server](docs/MCP.md) — Tool surface for MCP clients (Claude Code, Claude Desktop)
|
|
326
345
|
- [Workflow Guide](docs/WORKFLOW_GUIDE.md) — JSON structure, variables, steps, data flow
|
|
327
346
|
- [Quantization](docs/QUANTIZATION.md) — BitsAndBytes, TorchAO, GGUF, SDNQ
|
|
328
347
|
- [Inference Acceleration](docs/ACCELERATION.md) — torch.compile, FirstBlockCache, MagCache, TaylorSeer, TeaCache
|
{diffusers_workflow-0.4.0a8 → diffusers_workflow-0.4.0a12}/diffusers_workflow.egg-info/SOURCES.txt
RENAMED
|
@@ -64,45 +64,45 @@ dw/server/ui/assets/csharp-BKxtCVv1.js
|
|
|
64
64
|
dw/server/ui/assets/csp-bTuwJoIa.js
|
|
65
65
|
dw/server/ui/assets/css-DIMkf-bt.js
|
|
66
66
|
dw/server/ui/assets/css.worker-B3ciXF_0.js
|
|
67
|
-
dw/server/ui/assets/cssMode-
|
|
67
|
+
dw/server/ui/assets/cssMode-CRm5Fmld.js
|
|
68
68
|
dw/server/ui/assets/cypher-CVaqCwHa.js
|
|
69
69
|
dw/server/ui/assets/dart-onAF5SnQ.js
|
|
70
70
|
dw/server/ui/assets/dockerfile-DZFCIeNp.js
|
|
71
71
|
dw/server/ui/assets/ecl-D05T4iGw.js
|
|
72
72
|
dw/server/ui/assets/editor-jjEx9u7D.css
|
|
73
|
-
dw/server/ui/assets/editor.api-
|
|
73
|
+
dw/server/ui/assets/editor.api-CArwgKCZ.js
|
|
74
74
|
dw/server/ui/assets/editor.worker-q-txB4vs.js
|
|
75
75
|
dw/server/ui/assets/elixir-6RTg0lbw.js
|
|
76
76
|
dw/server/ui/assets/flow9-C5_-GSwl.js
|
|
77
|
-
dw/server/ui/assets/freemarker2-
|
|
77
|
+
dw/server/ui/assets/freemarker2-B42MpbWP.js
|
|
78
78
|
dw/server/ui/assets/fsharp-C8Ef5oNN.js
|
|
79
79
|
dw/server/ui/assets/go-C-y9NEjX.js
|
|
80
80
|
dw/server/ui/assets/graphql-fmXr3nnJ.js
|
|
81
|
-
dw/server/ui/assets/handlebars-
|
|
81
|
+
dw/server/ui/assets/handlebars-BhleeD_A.js
|
|
82
82
|
dw/server/ui/assets/hcl-CpzslTdj.js
|
|
83
|
-
dw/server/ui/assets/html-
|
|
83
|
+
dw/server/ui/assets/html-Bi_v7qEe.js
|
|
84
84
|
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-
|
|
85
|
+
dw/server/ui/assets/htmlMode-c39yjrZR.js
|
|
86
|
+
dw/server/ui/assets/index-CKHZ9ZUD.css
|
|
87
|
+
dw/server/ui/assets/index-Do_ZJ3yS.js
|
|
88
88
|
dw/server/ui/assets/ini-sBoK_t0W.js
|
|
89
89
|
dw/server/ui/assets/java-BEtHBSE6.js
|
|
90
|
-
dw/server/ui/assets/javascript-
|
|
90
|
+
dw/server/ui/assets/javascript-BTuzJzdO.js
|
|
91
91
|
dw/server/ui/assets/json.worker-B2V3pomh.js
|
|
92
|
-
dw/server/ui/assets/jsonMode-
|
|
92
|
+
dw/server/ui/assets/jsonMode-DY2FmMCP.js
|
|
93
93
|
dw/server/ui/assets/julia-Bri6UV-V.js
|
|
94
94
|
dw/server/ui/assets/kotlin-BOotOW0E.js
|
|
95
95
|
dw/server/ui/assets/less-B9JPFI3C.js
|
|
96
96
|
dw/server/ui/assets/lexon-CfSJPG6W.js
|
|
97
|
-
dw/server/ui/assets/liquid-
|
|
98
|
-
dw/server/ui/assets/lspLanguageFeatures-
|
|
97
|
+
dw/server/ui/assets/liquid-iXwDEnQP.js
|
|
98
|
+
dw/server/ui/assets/lspLanguageFeatures-CVXyTq9V.js
|
|
99
99
|
dw/server/ui/assets/lua-CsQS60Ue.js
|
|
100
100
|
dw/server/ui/assets/m3-D-oSqn_W.js
|
|
101
101
|
dw/server/ui/assets/markdown-Cimd5fb3.js
|
|
102
|
-
dw/server/ui/assets/mdx-
|
|
102
|
+
dw/server/ui/assets/mdx-QE70XlV0.js
|
|
103
103
|
dw/server/ui/assets/mips-CIPQ_RoX.js
|
|
104
104
|
dw/server/ui/assets/monaco--ixms01u.css
|
|
105
|
-
dw/server/ui/assets/monaco-
|
|
105
|
+
dw/server/ui/assets/monaco-CzCru1EC.js
|
|
106
106
|
dw/server/ui/assets/msdax-DauUninz.js
|
|
107
107
|
dw/server/ui/assets/mysql-SOo6toE5.js
|
|
108
108
|
dw/server/ui/assets/objective-c-FvmIjYaQ.js
|
|
@@ -117,10 +117,10 @@ dw/server/ui/assets/powerquery-D3hlyOfw.js
|
|
|
117
117
|
dw/server/ui/assets/powershell-DmHpPYUd.js
|
|
118
118
|
dw/server/ui/assets/protobuf-C531GsRP.js
|
|
119
119
|
dw/server/ui/assets/pug-Z5eAx3Zn.js
|
|
120
|
-
dw/server/ui/assets/python-
|
|
120
|
+
dw/server/ui/assets/python-DxHS-kHp.js
|
|
121
121
|
dw/server/ui/assets/qsharp-DkqhCAOL.js
|
|
122
122
|
dw/server/ui/assets/r-BwWrilGY.js
|
|
123
|
-
dw/server/ui/assets/razor-
|
|
123
|
+
dw/server/ui/assets/razor-CT5Qrhwg.js
|
|
124
124
|
dw/server/ui/assets/redis-ClamHrr6.js
|
|
125
125
|
dw/server/ui/assets/redshift-DT7zqm-g.js
|
|
126
126
|
dw/server/ui/assets/restructuredtext-BYgofb2h.js
|
|
@@ -140,15 +140,15 @@ dw/server/ui/assets/swift-Bxkupp3x.js
|
|
|
140
140
|
dw/server/ui/assets/systemverilog-Bz4Y3fRF.js
|
|
141
141
|
dw/server/ui/assets/tcl-DISqw1ZD.js
|
|
142
142
|
dw/server/ui/assets/ts.worker-D7T1-Ig5.js
|
|
143
|
-
dw/server/ui/assets/tsMode-
|
|
143
|
+
dw/server/ui/assets/tsMode-qXdDdnF1.js
|
|
144
144
|
dw/server/ui/assets/twig-De2hgUGE.js
|
|
145
|
-
dw/server/ui/assets/typescript-
|
|
145
|
+
dw/server/ui/assets/typescript-BWfJagji.js
|
|
146
146
|
dw/server/ui/assets/typespec-B8J7ngcE.js
|
|
147
147
|
dw/server/ui/assets/vb-DV3o63ZY.js
|
|
148
148
|
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-
|
|
149
|
+
dw/server/ui/assets/workers-C9vxrwoC.js
|
|
150
|
+
dw/server/ui/assets/xml-DhJEwsDK.js
|
|
151
|
+
dw/server/ui/assets/yaml-CiixMxAq.js
|
|
152
152
|
dw/tasks/audio_utils.py
|
|
153
153
|
dw/tasks/background_remover.py
|
|
154
154
|
dw/tasks/borders.py
|
|
@@ -177,12 +177,23 @@ dw/workflows/augment_prompt.json
|
|
|
177
177
|
dw/workflows/describe_image.json
|
|
178
178
|
dw/workflows/h3_context_ir.json
|
|
179
179
|
dw/workflows/test.json
|
|
180
|
+
dw_mcp/__init__.py
|
|
181
|
+
dw_mcp/__main__.py
|
|
182
|
+
dw_mcp/authoring.py
|
|
183
|
+
dw_mcp/catalog.py
|
|
184
|
+
dw_mcp/client.py
|
|
185
|
+
dw_mcp/diagnose.py
|
|
186
|
+
dw_mcp/media.py
|
|
187
|
+
dw_mcp/models.py
|
|
188
|
+
dw_mcp/prompts.py
|
|
189
|
+
dw_mcp/server.py
|
|
180
190
|
tests/test_argument_updates.py
|
|
181
191
|
tests/test_arguments.py
|
|
182
192
|
tests/test_audio_utils.py
|
|
183
193
|
tests/test_borders.py
|
|
184
194
|
tests/test_cache_blocks.py
|
|
185
195
|
tests/test_chain.py
|
|
196
|
+
tests/test_cli.py
|
|
186
197
|
tests/test_component_pruning.py
|
|
187
198
|
tests/test_concat_videos.py
|
|
188
199
|
tests/test_config_objects.py
|
|
@@ -190,6 +201,7 @@ tests/test_configuration_schema.py
|
|
|
190
201
|
tests/test_depth_estimator.py
|
|
191
202
|
tests/test_device.py
|
|
192
203
|
tests/test_device_helpers.py
|
|
204
|
+
tests/test_device_portability.py
|
|
193
205
|
tests/test_diffusion_upscale.py
|
|
194
206
|
tests/test_docs_links.py
|
|
195
207
|
tests/test_events.py
|
|
@@ -202,9 +214,19 @@ tests/test_integration.py
|
|
|
202
214
|
tests/test_interpolate_frames.py
|
|
203
215
|
tests/test_introspection.py
|
|
204
216
|
tests/test_list_images.py
|
|
217
|
+
tests/test_mcp_authoring.py
|
|
218
|
+
tests/test_mcp_catalog.py
|
|
219
|
+
tests/test_mcp_client.py
|
|
220
|
+
tests/test_mcp_diagnose.py
|
|
221
|
+
tests/test_mcp_media.py
|
|
222
|
+
tests/test_mcp_models.py
|
|
223
|
+
tests/test_mcp_prompts.py
|
|
224
|
+
tests/test_mcp_server.py
|
|
205
225
|
tests/test_model_cache.py
|
|
206
226
|
tests/test_modular_pipeline.py
|
|
227
|
+
tests/test_offload_placement.py
|
|
207
228
|
tests/test_pair_audio.py
|
|
229
|
+
tests/test_phase_events.py
|
|
208
230
|
tests/test_pipeline_caching.py
|
|
209
231
|
tests/test_pipeline_components.py
|
|
210
232
|
tests/test_previous_results.py
|
|
@@ -215,6 +237,7 @@ tests/test_repl_commands.py
|
|
|
215
237
|
tests/test_repl_ergonomics.py
|
|
216
238
|
tests/test_repl_hierarchical.py
|
|
217
239
|
tests/test_repl_reorganization.py
|
|
240
|
+
tests/test_repl_worker.py
|
|
218
241
|
tests/test_resize_bucket.py
|
|
219
242
|
tests/test_result.py
|
|
220
243
|
tests/test_scheduler_config.py
|
|
@@ -231,8 +254,10 @@ tests/test_tensor_image.py
|
|
|
231
254
|
tests/test_text_generation.py
|
|
232
255
|
tests/test_text_sections.py
|
|
233
256
|
tests/test_type_helpers.py
|
|
257
|
+
tests/test_updater.py
|
|
234
258
|
tests/test_variables.py
|
|
235
259
|
tests/test_video_utils.py
|
|
236
260
|
tests/test_worker.py
|
|
237
261
|
tests/test_worker_execute.py
|
|
238
|
-
tests/test_workflow.py
|
|
262
|
+
tests/test_workflow.py
|
|
263
|
+
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
|
|
@@ -138,6 +150,81 @@ def get_device_type(device=None):
|
|
|
138
150
|
return torch.device(device if device is not None else get_device()).type
|
|
139
151
|
|
|
140
152
|
|
|
153
|
+
def backend_available(device_type):
|
|
154
|
+
"""
|
|
155
|
+
Whether this machine can actually run on a backend.
|
|
156
|
+
|
|
157
|
+
Only the backends dw knows how to probe get an answer. An unrecognized one is
|
|
158
|
+
reported available rather than guessed at, so a device torch understands and dw
|
|
159
|
+
does not is left alone instead of being rewritten.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
device_type: Backend name ('cuda', 'mps', 'cpu', ...)
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
bool: Whether the backend is usable here
|
|
166
|
+
"""
|
|
167
|
+
if not _TORCH_AVAILABLE:
|
|
168
|
+
return device_type == "cpu"
|
|
169
|
+
|
|
170
|
+
if device_type == "cpu":
|
|
171
|
+
return True
|
|
172
|
+
|
|
173
|
+
if device_type == "cuda":
|
|
174
|
+
return torch.cuda.is_available()
|
|
175
|
+
|
|
176
|
+
if device_type == "mps":
|
|
177
|
+
return hasattr(torch.backends, "mps") and torch.backends.mps.is_available()
|
|
178
|
+
|
|
179
|
+
is_available = getattr(getattr(torch, device_type, None), "is_available", None)
|
|
180
|
+
return bool(is_available()) if callable(is_available) else True
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def resolve_device(requested):
|
|
184
|
+
"""
|
|
185
|
+
Translate a device a workflow asked for into one this machine has.
|
|
186
|
+
|
|
187
|
+
A device named in a workflow is nearly always the author saying 'the accelerator'
|
|
188
|
+
rather than 'specifically NVIDIA', so a workflow written on a CUDA box runs on a
|
|
189
|
+
Mac and back again. The backend is what gets translated - an index is left alone
|
|
190
|
+
when the backend matches, since 'cuda:1' on a single-GPU CUDA box is a genuine
|
|
191
|
+
mistake and not a portability problem. A CPU device is never rewritten: pinning a
|
|
192
|
+
step to the CPU is how a GPU-specific problem gets ruled out.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
requested: Device identifier from a workflow, or None for no override
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
The device to use, or None if None was passed
|
|
199
|
+
"""
|
|
200
|
+
if requested is None or not _TORCH_AVAILABLE:
|
|
201
|
+
return requested
|
|
202
|
+
|
|
203
|
+
try:
|
|
204
|
+
device = torch.device(requested)
|
|
205
|
+
except (RuntimeError, TypeError, ValueError):
|
|
206
|
+
# Not a device torch understands - let the failure surface where it is used
|
|
207
|
+
return requested
|
|
208
|
+
|
|
209
|
+
if device.type == "cpu" or backend_available(device.type):
|
|
210
|
+
return requested
|
|
211
|
+
|
|
212
|
+
target = get_device()
|
|
213
|
+
if device.index is not None:
|
|
214
|
+
logging.warning(
|
|
215
|
+
f"Workflow asks for '{requested}', which this machine has no {device.type} "
|
|
216
|
+
f"backend for - running on {target}. The device index is dropped, so a "
|
|
217
|
+
"workflow that meant to spread work across accelerators will not."
|
|
218
|
+
)
|
|
219
|
+
else:
|
|
220
|
+
logging.warning(
|
|
221
|
+
f"Workflow asks for '{requested}', which this machine has no {device.type} "
|
|
222
|
+
f"backend for - running on {target}"
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
return target
|
|
226
|
+
|
|
227
|
+
|
|
141
228
|
def get_autocast_device_type():
|
|
142
229
|
"""
|
|
143
230
|
Get the device type to use for torch.autocast.
|
|
@@ -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):
|
|
@@ -76,3 +90,27 @@ def activate_context(context):
|
|
|
76
90
|
|
|
77
91
|
def deactivate_context(token):
|
|
78
92
|
_active_context.reset(token)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# The coarse states a run passes through. Small on purpose: a phase says what
|
|
96
|
+
# the run is waiting on, not what any one library is doing internally
|
|
97
|
+
PHASES = ("loading", "cached", "generating", "decoding", "saving", "task")
|
|
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
|
+
|
|
104
|
+
|
|
105
|
+
def emit_phase(phase, detail=None):
|
|
106
|
+
"""Report a coarse phase change on the active run.
|
|
107
|
+
|
|
108
|
+
A step spends most of its wall clock outside the denoise loop - pulling
|
|
109
|
+
weights, decoding latents, encoding video - and a step counter says
|
|
110
|
+
nothing about any of that. These are the rest of the story. They are rare
|
|
111
|
+
enough (a handful per step) to carry a free-text detail alongside, which
|
|
112
|
+
is what makes 'loading' readable as 'which model'.
|
|
113
|
+
"""
|
|
114
|
+
context = get_context()
|
|
115
|
+
context.note_phase(phase)
|
|
116
|
+
context.emit("phase", phase=phase, detail=detail)
|
|
@@ -150,6 +150,7 @@ class DownloadManager:
|
|
|
150
150
|
except HFValidationError as e:
|
|
151
151
|
raise ValueError(str(e))
|
|
152
152
|
|
|
153
|
+
cancel_event = threading.Event()
|
|
153
154
|
with self._lock:
|
|
154
155
|
for entry in self._downloads.values():
|
|
155
156
|
if entry["repo_id"] == repo_id and entry["status"] == "downloading":
|
|
@@ -163,12 +164,14 @@ class DownloadManager:
|
|
|
163
164
|
"error": None,
|
|
164
165
|
"started_at": time.time(),
|
|
165
166
|
"finished_at": None,
|
|
167
|
+
# Set before the entry is published: cancel() reaches for this
|
|
168
|
+
# the moment the id is visible, and assigning it after the
|
|
169
|
+
# lock left a window where cancelling raised KeyError
|
|
170
|
+
"_cancel": cancel_event,
|
|
166
171
|
}
|
|
167
172
|
self._downloads[entry["id"]] = entry
|
|
168
173
|
self._prune()
|
|
169
174
|
|
|
170
|
-
cancel_event = threading.Event()
|
|
171
|
-
entry["_cancel"] = cancel_event
|
|
172
175
|
thread = threading.Thread(
|
|
173
176
|
target=self._run, args=(entry, cancel_event), daemon=True
|
|
174
177
|
)
|