diffusers-workflow 0.12.0__py3-none-any.whl → 0.13.0__py3-none-any.whl

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.
Files changed (53) hide show
  1. {diffusers_workflow-0.12.0.dist-info → diffusers_workflow-0.13.0.dist-info}/METADATA +28 -28
  2. {diffusers_workflow-0.12.0.dist-info → diffusers_workflow-0.13.0.dist-info}/RECORD +51 -51
  3. dw/disk_caches.py +61 -9
  4. dw/docs/ARCHITECTURE.md +2 -2
  5. dw/docs/DEPENDENCIES.md +2 -2
  6. dw/docs/MCP.md +1 -1
  7. dw/docs/QUANTIZATION.md +1 -1
  8. dw/docs/RELEASING.md +82 -0
  9. dw/docs/SERVER.md +11 -1
  10. dw/media.py +35 -0
  11. dw/media_frames.py +9 -0
  12. dw/pipeline_processors/components.py +1 -1
  13. dw/quantized_cache.py +36 -11
  14. dw/result.py +6 -0
  15. dw/server/api_models.py +11 -0
  16. dw/server/app.py +2 -0
  17. dw/server/deps.py +33 -1
  18. dw/server/jobs.py +28 -0
  19. dw/server/routes/assets.py +8 -0
  20. dw/server/routes/library.py +11 -0
  21. dw/server/routes/media.py +46 -28
  22. dw/server/routes/system.py +25 -17
  23. dw/server/ui/assets/{cssMode-n9saDHXf.js → cssMode-QzCkHHkC.js} +1 -1
  24. dw/server/ui/assets/{editor.api-DBE2zlnf.js → editor.api-LvRbw1iL.js} +1 -1
  25. dw/server/ui/assets/{freemarker2-BomqYelz.js → freemarker2-BFEReHqW.js} +1 -1
  26. dw/server/ui/assets/{handlebars-8Houv1UM.js → handlebars--qZ0WvL7.js} +1 -1
  27. dw/server/ui/assets/{html-DaY0zzOJ.js → html-Bs0VSJAA.js} +1 -1
  28. dw/server/ui/assets/{htmlMode-DP2rYJIT.js → htmlMode-DrsyYX5n.js} +1 -1
  29. dw/server/ui/assets/index-BgBhcVj3.js +54 -0
  30. dw/server/ui/assets/index-DSM5LA24.css +1 -0
  31. dw/server/ui/assets/{javascript-B5R3UPTQ.js → javascript-C3KR7rul.js} +1 -1
  32. dw/server/ui/assets/{jsonMode-DsuGIxoD.js → jsonMode-DEXt-mqp.js} +1 -1
  33. dw/server/ui/assets/{liquid-B2d5ZvOn.js → liquid-ByBJuq1e.js} +1 -1
  34. dw/server/ui/assets/{lspLanguageFeatures-ChdmQify.js → lspLanguageFeatures-6nDoG86-.js} +1 -1
  35. dw/server/ui/assets/{mdx-DIXDAORJ.js → mdx-BH2GyjV6.js} +1 -1
  36. dw/server/ui/assets/{monaco-BgG3yDUh.js → monaco-B6Bmfo5o.js} +4 -4
  37. dw/server/ui/assets/{python-CXHtns6L.js → python-C1sJMrAm.js} +1 -1
  38. dw/server/ui/assets/{razor-BSKKsa7H.js → razor-BdPZ4bvZ.js} +1 -1
  39. dw/server/ui/assets/{tsMode-DRjPuZ2P.js → tsMode-DW5i-ukN.js} +1 -1
  40. dw/server/ui/assets/{typescript-CBpoJtqE.js → typescript-C_QzKQY3.js} +1 -1
  41. dw/server/ui/assets/{workers-DUo4Mox_.js → workers-DHqaOvh8.js} +1 -1
  42. dw/server/ui/assets/{xml-B2gZoNmP.js → xml-D3UEcM_2.js} +1 -1
  43. dw/server/ui/assets/{yaml-CSvo_Woe.js → yaml-C0TnGcnd.js} +1 -1
  44. dw/server/ui/index.html +2 -2
  45. dw/tasks/cuts.py +5 -6
  46. dw_mcp/tools_catalog.py +11 -11
  47. dw_mcp/workspaces.py +35 -10
  48. dw/server/ui/assets/index-CZtjWH1q.css +0 -1
  49. dw/server/ui/assets/index-DGl2EK47.js +0 -48
  50. {diffusers_workflow-0.12.0.dist-info → diffusers_workflow-0.13.0.dist-info}/WHEEL +0 -0
  51. {diffusers_workflow-0.12.0.dist-info → diffusers_workflow-0.13.0.dist-info}/entry_points.txt +0 -0
  52. {diffusers_workflow-0.12.0.dist-info → diffusers_workflow-0.13.0.dist-info}/licenses/LICENSE +0 -0
  53. {diffusers_workflow-0.12.0.dist-info → diffusers_workflow-0.13.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diffusers-workflow
3
- Version: 0.12.0
3
+ Version: 0.13.0
4
4
  Summary: Declarative workflow engine and web UI for Hugging Face Diffusers
5
5
  Author: dkackman
6
6
  License: Apache-2.0
@@ -16,70 +16,70 @@ Classifier: Programming Language :: Python :: 3.14
16
16
  Requires-Python: >=3.10
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: torch>=2.13.0
20
- Requires-Dist: torchvision>=0.28.0
19
+ Requires-Dist: torch>=2.14.1
20
+ Requires-Dist: torchvision>=0.29.1
21
21
  Requires-Dist: diffusers>=0.40.0
22
- Requires-Dist: transformers!=5.17.0,>=5.16.1
23
- Requires-Dist: accelerate>=1.14.0
24
- Requires-Dist: peft>=0.20.0
22
+ Requires-Dist: transformers>=5.19.0
23
+ Requires-Dist: accelerate>=1.15.0
24
+ Requires-Dist: peft>=0.21.2
25
25
  Requires-Dist: safetensors>=0.8.0
26
- Requires-Dist: huggingface-hub>=1.29.0
26
+ Requires-Dist: huggingface-hub>=1.33.0
27
27
  Requires-Dist: sentencepiece>=0.2.2
28
- Requires-Dist: protobuf>=7.36.0
28
+ Requires-Dist: protobuf>=7.36.2
29
29
  Requires-Dist: ftfy>=6.3.1
30
30
  Requires-Dist: torchsde>=0.2.6
31
31
  Requires-Dist: torchao>=0.18.0
32
32
  Requires-Dist: optimum-quanto>=0.2.7
33
- Requires-Dist: sdnq>=0.2.5
33
+ Requires-Dist: sdnq>=0.2.8
34
34
  Requires-Dist: gguf>=0.19.0
35
35
  Requires-Dist: bitsandbytes>=0.50.2; sys_platform == "linux"
36
36
  Requires-Dist: controlnet-aux>=0.0.10
37
37
  Requires-Dist: opencv-python-headless>=5.0.0.93
38
38
  Requires-Dist: kornia>=0.8.3
39
- Requires-Dist: kernels>=0.17.0
39
+ Requires-Dist: kernels>=0.17.2
40
40
  Requires-Dist: spandrel>=0.4.2
41
41
  Requires-Dist: facexlib>=0.3.0
42
- Requires-Dist: numpy>=2.5.2
42
+ Requires-Dist: numpy>=2.5.4
43
43
  Requires-Dist: Pillow>=12.3.0
44
44
  Requires-Dist: piexif>=1.1.3
45
- Requires-Dist: imageio>=2.37.4
45
+ Requires-Dist: imageio>=2.38.1
46
46
  Requires-Dist: imageio-ffmpeg>=0.6.0
47
- Requires-Dist: av>=18.1.0
47
+ Requires-Dist: av>=19.0.1
48
48
  Requires-Dist: soundfile>=0.14.0
49
- Requires-Dist: matplotlib>=3.11.1
49
+ Requires-Dist: matplotlib>=3.11.2
50
50
  Requires-Dist: pyloudnorm>=0.2.0
51
51
  Requires-Dist: scipy>=1.18.1
52
- Requires-Dist: speechbrain>=1.0.3
52
+ Requires-Dist: speechbrain>=1.1.1
53
53
  Requires-Dist: demucs>=4.1.0
54
54
  Requires-Dist: qrcode>=8.2
55
55
  Requires-Dist: requests>=2.34.2
56
- Requires-Dist: aiohttp>=3.14.3
56
+ Requires-Dist: aiohttp>=3.14.5
57
57
  Requires-Dist: beautifulsoup4>=4.15.0
58
58
  Requires-Dist: jsonschema>=4.26.0
59
- Requires-Dist: concurrent-log-handler>=0.9.29
60
- Requires-Dist: python-dotenv>=1.2.3
59
+ Requires-Dist: concurrent-log-handler>=0.9.30
60
+ Requires-Dist: python-dotenv>=1.2.4
61
61
  Requires-Dist: packaging>=26.3
62
- Requires-Dist: filelock>=3.12
62
+ Requires-Dist: filelock>=4.1.1
63
63
  Requires-Dist: httpx>=0.28.1
64
64
  Provides-Extra: server
65
- Requires-Dist: fastapi>=0.141.1; extra == "server"
66
- Requires-Dist: uvicorn[standard]>=0.52.4; extra == "server"
65
+ Requires-Dist: fastapi>=0.143.0; extra == "server"
66
+ Requires-Dist: uvicorn[standard]>=0.54.0; extra == "server"
67
67
  Provides-Extra: mcp
68
- Requires-Dist: mcp>=2.1.1; extra == "mcp"
68
+ Requires-Dist: mcp>=2.3.0; extra == "mcp"
69
69
  Provides-Extra: dev
70
70
  Requires-Dist: pytest>=9.1.1; extra == "dev"
71
71
  Requires-Dist: pytest-cov>=7.1.0; extra == "dev"
72
72
  Requires-Dist: pytest-xdist>=3.8.0; extra == "dev"
73
73
  Requires-Dist: pytest-timeout>=2.4.0; extra == "dev"
74
- Requires-Dist: pytest-mock>=3.15.1; extra == "dev"
74
+ Requires-Dist: pytest-mock>=3.16.0; extra == "dev"
75
75
  Requires-Dist: pytest-asyncio>=1.4.0; extra == "dev"
76
76
  Requires-Dist: httpx>=0.28.1; extra == "dev"
77
- Requires-Dist: ruff>=0.15.0; extra == "dev"
77
+ Requires-Dist: ruff>=0.17.0; extra == "dev"
78
78
  Requires-Dist: build; extra == "dev"
79
- Requires-Dist: mcp>=2.1.1; extra == "dev"
80
- Requires-Dist: pylint>=3.3; extra == "dev"
79
+ Requires-Dist: mcp>=2.3.0; extra == "dev"
80
+ Requires-Dist: pylint>=4.1.3; extra == "dev"
81
81
  Requires-Dist: import-linter>=2.15; extra == "dev"
82
- Requires-Dist: networkx>=3.0; extra == "dev"
82
+ Requires-Dist: networkx>=3.7; extra == "dev"
83
83
  Requires-Dist: pygount>=3.2; extra == "dev"
84
84
  Dynamic: license-file
85
85
 
@@ -148,7 +148,7 @@ family that knows which workflow fits a request and the rules that bite:
148
148
  ```
149
149
 
150
150
  Most of the shipped workflows (Flux, LTX-2, MiniMax...) use **gated** models.
151
- Request access on the model's Hugging Face page, then `huggingface-cli login`
151
+ Request access on the model's Hugging Face page, then `hf auth login`
152
152
  once; without it the run fails partway through with a 401/403 from the Hub.
153
153
 
154
154
  > **GPU on another machine?** Start the engine there with `--mcp` and connect
@@ -1,4 +1,4 @@
1
- diffusers_workflow-0.12.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1
+ diffusers_workflow-0.13.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
2
2
  dw/__init__.py,sha256=YKwvXdngbW8iY6xFcfVwDCeiD_oFyCdWb-rRVUogp0Y,19969
3
3
  dw/adapter_compatibility.py,sha256=MzNfxK-yOBrn6Mp90m_i_QY-N4zz4C0ZCvKIByUpXAw,10674
4
4
  dw/argument_media.py,sha256=fIsvlDRCuTz_DPH4MXFxBZiKTQfgR1vY0-wTU5P9p-I,15145
@@ -11,7 +11,7 @@ dw/cache_blocks.json,sha256=m7mJV7Pwv5LnwzW-2Daa71W3yKh6x7VdxFS7ShEiUG4,1633
11
11
  dw/cache_blocks.py,sha256=A_S9pID6jqgheRg2DFFmIPLiS7XJUNT44eXk3W01SSg,5719
12
12
  dw/content_types.py,sha256=27B8wo6gWRtqKGm3JE7KTHc9QubpKysqYaco9-1O7Ew,7248
13
13
  dw/devices.py,sha256=JCEqgAvVLQe5V4OYLmyCIoMVHeBH4jUL8CPtuJdNzmM,9560
14
- dw/disk_caches.py,sha256=L_QoJ5-1_XS2CGq8wII5zL939wBGua5ZlRE3AEfxVyw,17007
14
+ dw/disk_caches.py,sha256=ulu3HW5Yb1KKI9RRZSrw8HgVAtsE4L07oAhpXZJwz8A,19072
15
15
  dw/dissolve_frame_errors.py,sha256=r4SofR0SeheFILEANpmT4QX6CRT2bPqsaXubZIu3yDA,4675
16
16
  dw/download_watch.py,sha256=x0RGfJy7t_ZQJ4FD3GcGcdJd-bjmllLLVCXKYhFE9JI,12656
17
17
  dw/dsp.py,sha256=grwEB6xS1nH6H-ACgqz39CZnSRxGYf6lVhTAJYBw0uI,43148
@@ -31,8 +31,8 @@ dw/log_setup.py,sha256=ATwSO0CCDtgEA-VoPsS8HVeuDwL2jBg--4QXSZwecQs,1478
31
31
  dw/lora_catalog.py,sha256=B6RRgdyY0NSCyAwMVoDS3_wxyqF9i3Q3JjEx-hCMVAI,4893
32
32
  dw/lora_catalog_schema.json,sha256=i-oh9JR8DbKoNxZ2ufnyPaTaNT8hpeY_I6I3Zrhrl_w,2120
33
33
  dw/lora_hub.py,sha256=Px2cV9yAQsKve6WZuvuQCOfgLWjJ1bJx0uDbxeK2kmQ,8500
34
- dw/media.py,sha256=FvFZYMPPYFR5Y2S8svjTusN--HBrnFHSCUQMmAtQWtk,46095
35
- dw/media_frames.py,sha256=2WLLU4Z1NgN4rTxSVDHDs5VZVQqbHXMtOz-ekvonoAA,12789
34
+ dw/media.py,sha256=bsW4cR6b4vX0fZWeqQVqh-Xceq-B9RZVnGtgDI2j5IE,47719
35
+ dw/media_frames.py,sha256=8IKxRz0ySR4xgZHSaw5oG-9MgCu-87HSsZl-P-aQKtw,13133
36
36
  dw/media_types.py,sha256=GFnWr8Eq6jU1Y-wccXDKFO5MX-oePAjj8RsE23wvsp8,9770
37
37
  dw/outbound.py,sha256=Noaerzmzz-n23JGe9ciMuvo8QQZO-SBOK_gyFXB22Do,20508
38
38
  dw/output_extraction.py,sha256=m_uppccZeGPF2lb8UQLCrLHH1PQxmSniB8fuT5TMm_E,10341
@@ -44,12 +44,12 @@ dw/probe_paths.py,sha256=iJgy4G256zELyzi4Aol4_qifejjZsUtdeEEDWryAB0o,2683
44
44
  dw/prompt_schema.json,sha256=5e7NWgce28cf-YWEWwyDjQQ90ki0BcI4tczTyr_d8lQ,1934
45
45
  dw/prompt_weighting.py,sha256=ttA_EUnkqmvHujRxP5Dgfm4hsemupQaNDiidpxsvMgc,13063
46
46
  dw/prompts.py,sha256=J2HmqCeEGDXzd4IrqLfFCS3GZcJIdsaaVpjnupg_QpI,5755
47
- dw/quantized_cache.py,sha256=gX4tnhiehPW6GcYKxlhYdMIy4fgM0wtfOJSAsYsUMLw,32775
47
+ dw/quantized_cache.py,sha256=urJARJshB48Z3tCZJuVqDwKULS0VyQYZZKiFqwyaDPo,33738
48
48
  dw/realize.py,sha256=PY0Trgt58YAOd0ZWudedhrNUgzggKPoP8hRn9x2gvYk,11095
49
49
  dw/reference_limits.py,sha256=X41iOHiULqU5mXGM0jZKL5DnP5bUydd3wNvUFxUlEnU,7718
50
50
  dw/reference_names.py,sha256=y7z-n3TRHp8jMhUx6aSs4qXzC2EnA5sCYAg3vYKhG0Y,4737
51
51
  dw/references.py,sha256=40GoPYeAzqwOKscD8-ljOjdvwdtmeQWr2ctSw35O4Y0,7589
52
- dw/result.py,sha256=7MR6S92LAPSR481hDfTRSqTSliZE61cUMB_gp6Vw8Nk,39532
52
+ dw/result.py,sha256=g5PkdvHRlzHvW6-1HiWKMKPIN_OpauqCmP5pGGAyOkU,39821
53
53
  dw/run.py,sha256=irH-b_QvbFa0X1F_9M2iX1uxNI74K5vnQCE9MiPaK1I,9316
54
54
  dw/runs.py,sha256=4cqsXuXiSUzEJ4SkJawCy0KEQiqjRWz_W80OD-O32Zg,36798
55
55
  dw/scalar_result_validation.py,sha256=JQvkmjxU4KCMbl1j2UTOkMwgreWeXRfrI44aRsONVPg,5187
@@ -92,19 +92,19 @@ dw/community_pipelines/pipeline_flux_rf_inversion.py,sha256=XjLO58h5wQn16qP8wEIZ
92
92
  dw/community_pipelines/pipeline_ltx2_refine.py,sha256=kvDBeiaDvt_BX2AjbN6nnYN0EZsEvMzvSC6WzorA_48,6619
93
93
  dw/docs/ACCELERATION.md,sha256=ufPukCOnmYCbt3xMn71MzhuDNHdUC7oQuPajF2NhVAA,21314
94
94
  dw/docs/AGENT_LOOP.md,sha256=rMb_c_r2ucsB7djwtQdp9_VVRagvhevWo-Iep7emmS8,4729
95
- dw/docs/ARCHITECTURE.md,sha256=QlGdhAyAL8hfuP5DMQ--3IiWXAVtPBrCzyg-D9_P5mE,63644
96
- dw/docs/DEPENDENCIES.md,sha256=FKkPm98UeXYBcf26MUpaXkOeoeu3ADyMsC3oP3B4bn4,4455
95
+ dw/docs/ARCHITECTURE.md,sha256=C_djEQ0896iGaRILjsvqlWFxBh7PlWf92ZT2tL2Wpz0,64097
96
+ dw/docs/DEPENDENCIES.md,sha256=1Vawp_Yr_l0IDF3IizBkTKHAvR9v3aL7TXJiLJI0NTM,4439
97
97
  dw/docs/IP_ADAPTER.md,sha256=AAHaUIfbnOojHfT0noIeypbhdYPluR7sbZeVn5FpbjU,3730
98
98
  dw/docs/LORAS.md,sha256=iIdMH50hnZtspzG6fXkCkm5-wVmEncb2SvX8SfZyLik,7093
99
- dw/docs/MCP.md,sha256=XJxnUCLkN2yABUAGjsXMd91kp665oftYXen-udWoDME,58090
99
+ dw/docs/MCP.md,sha256=HStINngL7Jx75kY52jLA34h0XXr7vY4lhf3at2t9TQ0,58246
100
100
  dw/docs/PROMPT_WEIGHTING.md,sha256=Pvr25d3yvS8SlnYwX9qc61VvTa8yFMxK_1zMLvrEigI,3031
101
- dw/docs/QUANTIZATION.md,sha256=lS1yheh2FfMq6uYa3qqJuNz_AQBXtDb0s-3WqgqAnys,11830
101
+ dw/docs/QUANTIZATION.md,sha256=rnAAUmfgsP4PbMd2J33Qa6t4DcnCxkUE_pJnqEJ-WOs,11941
102
102
  dw/docs/RECIPES_24GB.md,sha256=Xu0JNK-PkTnoK0of_0CbjFn-oteVWg2OHNkJ8wLFifE,18867
103
- dw/docs/RELEASING.md,sha256=WAR92Ny4s2Ihg1vVvwu4mIotguV4VnCwK2YAnD7dePI,57857
103
+ dw/docs/RELEASING.md,sha256=RiacfazCbeVEeT0rY2p_CKoc0WzzsrVDcOTe6d0_-NA,61906
104
104
  dw/docs/REMOTE.md,sha256=rlqqi10Hm6LVwwu106_LTVlN2oBU0jKdnjupNffrGSE,6793
105
105
  dw/docs/SECURITY.md,sha256=n0ZBL7O3oE9sOCG41h66bhOkkVzz1NLhsKKJh6aU6t8,21205
106
106
  dw/docs/SECURITY_QUICKREF.md,sha256=-xZNIV6j1oWcoy5B-oHKqh3ko2zJgB2fuNMiDV4f1zY,3537
107
- dw/docs/SERVER.md,sha256=xvepATz7bGToe8n72rywUCTn0o74yCsZ5wSFNA0GEFE,60661
107
+ dw/docs/SERVER.md,sha256=Vv7EC-j5eqy1jw-GqQvzRAQJUc92wM8PGWE3TAUWaYE,61373
108
108
  dw/docs/TASKS.md,sha256=amDKRkNUGc25AmZO5ZJ9d-ixQDsfVbQfys5LdAITQdQ,178224
109
109
  dw/docs/TESTING.md,sha256=D4zmQp0iVmREM9J1tq4RxTmmIxvxsp5dRtuRGovP96s,3973
110
110
  dw/docs/WORKER_GUIDE.md,sha256=t-RjdZ-7reBUfQypxfk_Qm4aPESMAGi7Wn-0Ri5S3Z8,2814
@@ -112,7 +112,7 @@ dw/docs/WORKFLOW_GUIDE.md,sha256=wbEvT96wUmOqTDdO0d_nsqzt5o9UjwyBa1D0uUpGodo,149
112
112
  dw/docs/WORKSPACES.md,sha256=PBAuB4zSdPDkkNf8n2D2fc79qClBILpOnzx-CB63FWo,16672
113
113
  dw/pipeline_processors/adapters.py,sha256=2i9XIbxeDfHWsB5RD4oUbExdg9WJnLTy4VFO8s8lcPE,9705
114
114
  dw/pipeline_processors/chain.py,sha256=2KscX3jQttJL6NmEfiQquPGmBjYIGPOaueHbDv0OUHw,41721
115
- dw/pipeline_processors/components.py,sha256=40KNMM_XY2-HXRHevFADcdSy9-Kqdiw6tOAegmBonFs,38718
115
+ dw/pipeline_processors/components.py,sha256=JWbv0z2VEm4BNkUOhMQ76eLv7Ori4MVuKre8I8_so-A,38710
116
116
  dw/pipeline_processors/config_objects.py,sha256=nQYKx00544UzJFlEZ-th45b-8sav1hz3tKJaaBDNJns,10911
117
117
  dw/pipeline_processors/h3_guide_steps.py,sha256=wsaV7jFqcoZAEfjjyKYAMust3XgotqMkftlA-Ov5WrE,21580
118
118
  dw/pipeline_processors/h3_guides.py,sha256=DAhNOzOUD9i33Iopd-9nG3H5jaJPbDnEtqkP8-_GJDk,12445
@@ -125,12 +125,12 @@ dw/pipeline_processors/progress.py,sha256=uSKPsMug1AZqDoaFXsF5sRcJNiNLzbBuX3C3H3
125
125
  dw/pipeline_processors/remote.py,sha256=eZl6fPEKUrd1ieFgX94QNKAR4ziPH9JXTV_Hse4VsqY,2450
126
126
  dw/server/__init__.py,sha256=NGXV8LM6oYUZhEwWSDo3ihBvmzrC71az3Wc2gkGodcM,153
127
127
  dw/server/admission.py,sha256=B_zJ5KdCFWSD-PrPGOhCTHlDmUXt9i8vF8QyjyEJhyg,21924
128
- dw/server/api_models.py,sha256=2U8Bnt6UHAzT9IE5jphJYPARKWF0YbdTGUp0pjmORCE,28226
129
- dw/server/app.py,sha256=j3YlSj08aLWobTkWCZo9QloRNzlqs-cL3ybA1Uyb3nE,10467
128
+ dw/server/api_models.py,sha256=SV5ybl99t9iTcIz2o37S_4sd2iL9Y8FqrMfrkytDqk0,28588
129
+ dw/server/app.py,sha256=cU8yzJ6MXIERC5k4RwqHFlLjPNwuxe4meuwenLR0fpQ,10565
130
130
  dw/server/assess.py,sha256=9lxusAW6pEIgyXeGDnNLrpJmQrTg_9_2qNRNXqSLa9Q,7480
131
131
  dw/server/catalog.py,sha256=B3uR6G_hADm3nKh9RPf5H5IevIkiVXSgExdAbPCU1X8,17998
132
132
  dw/server/catalog_shape.py,sha256=jyuPVQZmgvKXJ__8xgpS2LMo22bChyps19EGEntAoW4,18602
133
- dw/server/deps.py,sha256=3NzDidgCm-oiqdmVP1v5HnYaWQsCV1t8ynowV-Dq_QU,12325
133
+ dw/server/deps.py,sha256=eYFlLXQlPLRAWR-tsUIQP6Bds201rt4xAvRMXnmlg2k,13662
134
134
  dw/server/enhancers.py,sha256=ZHfnFmTTD31f8uIA6VUEOjne6ThoXe5vX31kKRf3-hs,5006
135
135
  dw/server/exports.py,sha256=25RvcK7W_50LMI5xv86vyCpRz4yunmbZaDQJX4ldz5c,16410
136
136
  dw/server/guides.py,sha256=fxXbvnFqA8GUzeVbpEpEpg8FstGH6VItevC0n4H93iQ,11986
@@ -139,7 +139,7 @@ dw/server/inline_media.py,sha256=SxCOSLrF7kIthZe_W4DMsdGjFR1UK7Rjeh-wELXEQ5s,459
139
139
  dw/server/job_history.py,sha256=Y_LACySKsLHs_OCJnimBuwx6qLkXA0A1k51J3kSJBOI,23179
140
140
  dw/server/job_record.py,sha256=6iWaHmtfV_RAY0gNS7I5yNjmcCZjOmvKjf6SEYVGpGY,14233
141
141
  dw/server/job_results.py,sha256=NyjD3GmO7B13CZd1pCBzc8l6CBOfDW4T1WgzR4yd8UM,8123
142
- dw/server/jobs.py,sha256=zZjbulY-zicPFTqi1qR8fIBqxLdlRzJ0X7z7BIiq7NQ,40221
142
+ dw/server/jobs.py,sha256=8kk9Rvf7LQo5J70QH0zVBILU1V-NK8BamSIa4gi9AfM,41228
143
143
  dw/server/mcp_mount.py,sha256=XIjfqBzELFKesfHVmdFj69RHSTzr7aF4Ph1Bfz4oPeE,3620
144
144
  dw/server/netinfo.py,sha256=_oo0NfnesQR0n8MlxGt15tTgLutaqNOYyYYuUIBdRB0,4941
145
145
  dw/server/observed_cost.py,sha256=qAZOZ0Ocv7w6nXv5fQa375XhTCZLb5gy3CxJf1wOk4o,18275
@@ -149,15 +149,15 @@ dw/server/sysinfo.py,sha256=WiQeSpMNiIDOadcpYiyYTQSPQgPZc7qPvLSXx2WQHLA,2221
149
149
  dw/server/updater.py,sha256=gX61zcCzIJhPRryz8KcRQkfHPw_qFrG2sZE5OeZQnIk,8428
150
150
  dw/server/worker_memory.py,sha256=5lLV5GItg7Rl5L0JQ3nLc5k3VRH_2jMihQv5gxdBHuY,9606
151
151
  dw/server/routes/__init__.py,sha256=Z6hnzGs1jdXuY_1C74t09_e1QDYWOxWbCnyjo6_qKB0,1943
152
- dw/server/routes/assets.py,sha256=LLk-AFmj7VRi_siiW23jquxya4NVyjJrKoQJqKa0jk4,19106
152
+ dw/server/routes/assets.py,sha256=X8hyqjY17Rzj30PU2QVXD7mlEFBJE5X6NkEute0HaRA,19446
153
153
  dw/server/routes/files.py,sha256=6c7ySIPe7o8HSc8Z7M2b1fKWonQdkC8S_TPAVppCxOo,7125
154
154
  dw/server/routes/gallery.py,sha256=pwE1qsizXpqL-kMieM6UbXAgAHOpdQ1V3MR53510PsU,15107
155
155
  dw/server/routes/jobs.py,sha256=i_PcD6i0CWuh6yA0ACGgv_nLQgDQQQPHITE8KpIBCe0,39008
156
- dw/server/routes/library.py,sha256=I8XTm9P_gE80ACmw_E0euJwXEdHenctYhs4U-iGT4g8,29815
156
+ dw/server/routes/library.py,sha256=azretMmMY4gsibXheXAeR5i7q0WVXRm6d8zUu6sPfLc,30298
157
157
  dw/server/routes/loras.py,sha256=OVxlXutJs1ThSsTC3R31pg44sUaV9iH8PhY0Xy9UyVQ,9289
158
- dw/server/routes/media.py,sha256=jpUE4RfyKWsaxbXg-cALrUC8eM84Rz6pjUEN5OmriIs,26501
159
- dw/server/routes/system.py,sha256=04OKFRIsJ1ORda7rvdwFm2gHFJfaWhhZW9XTXrFDbik,21080
160
- dw/server/ui/index.html,sha256=FEs3e7YnKBB9rkldH1mMBJgVKAILDPTms_OCx8Q3wJs,826
158
+ dw/server/routes/media.py,sha256=QHhZcZcRf3znnUoczjzgFT2uMHs_sw1OXLM90v2XrRw,27009
159
+ dw/server/routes/system.py,sha256=G3bPLxN4mj3FdtQkq6yndrJ8Nmi-gJP3KJW6do1rkvI,21435
160
+ dw/server/ui/index.html,sha256=2LLmDxdqNnRUltPX1SesOYKU12X3LCHcS1EKwKcpWeQ,826
161
161
  dw/server/ui/assets/abap-08VXUWAP.js,sha256=v_s2iGszAEBUjgmnxo-oLx1BQTQAjswxiNzZ24fNZ3o,11690
162
162
  dw/server/ui/assets/apex-BWPQTe0t.js,sha256=eUu2JicJ0pjmMYETgWVVuzFEJeyxEfievljL436Mt3Q,3469
163
163
  dw/server/ui/assets/azcli-Bc_sGQ0U.js,sha256=LDRk2Ih2wJsTBkEl5yiESmbLMeMCGuNGu5aDZxaZzRA,707
@@ -172,44 +172,44 @@ dw/server/ui/assets/csharp-BKxtCVv1.js,sha256=tcK0xVr_gQziNy8CVDw-kMQEwehIe9ND34
172
172
  dw/server/ui/assets/csp-bTuwJoIa.js,sha256=pUYDwODPsXKr4shrxhfRg0_WRY3TLT8f5omX7nYPw7Y,1278
173
173
  dw/server/ui/assets/css-DIMkf-bt.js,sha256=Nhs17Txzlhf5DumZtrz-bnBHwdMMUt9YQBxQSG9f2OQ,4361
174
174
  dw/server/ui/assets/css.worker-C6lDtRpF.js,sha256=ft-SA2IfNjCmj4OcQzAbBRB2HdcczVU36dvuGSI_uaA,1078254
175
- dw/server/ui/assets/cssMode-n9saDHXf.js,sha256=e68lXJG63iO4c8ZQHs144XlW5dDz5MeNERLUSwwTu8o,2952
175
+ dw/server/ui/assets/cssMode-QzCkHHkC.js,sha256=YK6vlVGcXhH8EWzabgK0Irkg4KM7ZejgFyp0JQBKTeY,2952
176
176
  dw/server/ui/assets/cypher-CVaqCwHa.js,sha256=AYGtVhyMHJdRbOwpGLEfAPAyHAdwXc3J0D_mjN4oLVg,3048
177
177
  dw/server/ui/assets/dart-onAF5SnQ.js,sha256=QWSf47NMFu2yUd9XFSGEuisDrfcp-gvscx9WznuMY2w,3931
178
178
  dw/server/ui/assets/dockerfile-DZFCIeNp.js,sha256=hIFKl4QSK6zsn49CP3KacmKpiovwWnTZleepql5VAHo,1728
179
179
  dw/server/ui/assets/ecl-D05T4iGw.js,sha256=8dy8B-9clhaDibzPszzXjx7c9Zj0t2pUw19rgIOlAkM,4623
180
180
  dw/server/ui/assets/editor-DjpsE8to.css,sha256=eXqoXVVwoOu7BHCT9Y6a3BOUUHhJVCWycTMHPlsVqdo,99095
181
- dw/server/ui/assets/editor.api-DBE2zlnf.js,sha256=BZTb4CvdmqbMTQpR26ccxRz-g5nCRdVyzBid5brfMS4,2735707
181
+ dw/server/ui/assets/editor.api-LvRbw1iL.js,sha256=MNNe8aB6RfWwNUthG2IEALM_qi9ajF8Z-3yjj44lgiQ,2735707
182
182
  dw/server/ui/assets/editor.worker-BmdWdrHZ.js,sha256=Ih2vJ17lgC5GJ1KP9ltE1UyLran3eG7m51K9mfkfofE,303777
183
183
  dw/server/ui/assets/elixir-6RTg0lbw.js,sha256=_AM20WhJvweAHmfSKZJwEaIeLg71t8jkSUJgRVz5P0w,10116
184
184
  dw/server/ui/assets/flow9-C5_-GSwl.js,sha256=kUYiOodGRTZ6qJ5xielY8Ku5yBXlsEOb9kxSY4Fajb0,1669
185
- dw/server/ui/assets/freemarker2-BomqYelz.js,sha256=_vI9WvxRLvlglbBwbG-BXc4bLniNiUdl7PXnB2vymg8,15548
185
+ dw/server/ui/assets/freemarker2-BFEReHqW.js,sha256=xgzgiB4FBJPjOYBXT1QtmCQKLpIuGGqfBui9JomyY-E,15548
186
186
  dw/server/ui/assets/fsharp-C8Ef5oNN.js,sha256=UTeoJ7rvyxEcL_h0e74Hkkyfnqjz1KegentufCX2nkU,2651
187
187
  dw/server/ui/assets/go-C-y9NEjX.js,sha256=yiNuAvOl-CJdg1l7tlsDbqjKrl95VJ6jchO7KXm8sIU,2350
188
188
  dw/server/ui/assets/graphql-fmXr3nnJ.js,sha256=pm47jqz4rUAXQDgl98x5ePvvxf0fgOpsBE-AWYSMUYY,2119
189
- dw/server/ui/assets/handlebars-8Houv1UM.js,sha256=EP2iMweDdz9jKCe_9bA_gScVOgYWdT1s4paq2u7TxF4,6284
189
+ dw/server/ui/assets/handlebars--qZ0WvL7.js,sha256=NTD9YDXVC4LHHMKuv96S2QF5RAUUfZYs9V-fVyBV6HQ,6284
190
190
  dw/server/ui/assets/hcl-CpzslTdj.js,sha256=FTELtvUdJnCIa6x3jYwjNRaXvSqDk7_x4SlTYehMmdI,3449
191
- dw/server/ui/assets/html-DaY0zzOJ.js,sha256=IceBJSLvtrS0ee8_tkimoy_LZAOb4PP6wt-QiePiGh4,4516
191
+ dw/server/ui/assets/html-Bs0VSJAA.js,sha256=gDZLR2N19SQYx86q_pllkSuNBi4Yocg2ETyN22xbSL0,4516
192
192
  dw/server/ui/assets/html.worker-C5yZDBHz.js,sha256=4Kkoa_A4TNCicFnuUnxjWUnhuTl1Mn4XhuWx5B3E4w4,743387
193
- dw/server/ui/assets/htmlMode-DP2rYJIT.js,sha256=kRpS8Fz-ZOIjFTFTXHuxCvMBHy5HiB927TZzOx5JWZI,3406
194
- dw/server/ui/assets/index-CZtjWH1q.css,sha256=BseS6wJf1xzABs9R_E1Ptra6tqr2AJKcMrhHOI2x2-0,76122
195
- dw/server/ui/assets/index-DGl2EK47.js,sha256=T0M3j6EnVtqDOXomxQJ4Dwi9j2ntO1ZchAsXRGpyrOE,459766
193
+ dw/server/ui/assets/htmlMode-DrsyYX5n.js,sha256=F7Lh4Ym7RbLL2UXSAKbJCkoV6YuO1FOM-cVCUqDXqSE,3406
194
+ dw/server/ui/assets/index-BgBhcVj3.js,sha256=Vzp6o-cRkZjvCcvVZ5KYVRmQ_jd6XUXDaefey_MetH4,478152
195
+ dw/server/ui/assets/index-DSM5LA24.css,sha256=XJ_mDFWKegq3pida9dRSu9soSlHQckt0vPWPTfiPSok,78575
196
196
  dw/server/ui/assets/ini-sBoK_t0W.js,sha256=6QF6Fp68pxwu26PuYuAa5XlpwDMMopXB8gHj4XgppU4,960
197
197
  dw/server/ui/assets/java-BEtHBSE6.js,sha256=d9OpHur1TgBPjsMh5iCK_s6-JDUjIUa0H2gTU3OACVM,2906
198
- dw/server/ui/assets/javascript-B5R3UPTQ.js,sha256=SsZJCdZDY9IgzsKKGs7Vryc2CxTPnKn6d2QLdrmosXU,688
198
+ dw/server/ui/assets/javascript-C3KR7rul.js,sha256=ySsxj5PRH1nH_4orsMzJiF9UYNrg8mTFy3oN0FVQMSI,688
199
199
  dw/server/ui/assets/json.worker-DdeUAmHa.js,sha256=Gihf5S5n4Xv_Ipc_FoW6p492ZrLcyFk22r-RcK-GTlA,433137
200
- dw/server/ui/assets/jsonMode-DsuGIxoD.js,sha256=xx65sDi-66Du0OiHVlK0llilwuWhC6BoJzeaLkrga8c,12178
200
+ dw/server/ui/assets/jsonMode-DEXt-mqp.js,sha256=kfUodtJY0vypfEOkdu6uewZ8NE1jp6LGyL8CVM_riHU,12178
201
201
  dw/server/ui/assets/julia-Bri6UV-V.js,sha256=GgHfKwkibx83YYASauJxey9COaeCnDC0-FO9DI5h1ww,6505
202
202
  dw/server/ui/assets/kotlin-BOotOW0E.js,sha256=y9kKjKTUCkkgIf0XZrn0aW0M28yZaabvrArNjMhi9kM,3041
203
203
  dw/server/ui/assets/less-B9JPFI3C.js,sha256=RK-lDgNqYLUdnolGcFtj5W5Nhdj2rhAQjegLMStkLbw,3749
204
204
  dw/server/ui/assets/lexon-CfSJPG6W.js,sha256=3wceYal1Tl_3oIKlurT29e46CCwlH0DYXRxHyki6aAc,2288
205
- dw/server/ui/assets/liquid-B2d5ZvOn.js,sha256=ztj1v6Zm_4uPySGxNltzFwx1puA9ejeDTlr31nh6Wtk,3344
206
- dw/server/ui/assets/lspLanguageFeatures-ChdmQify.js,sha256=Y72G4wSLuNRHkHAHfN5WxJ9tz4MI7_Pg6siETxusbwQ,28224
205
+ dw/server/ui/assets/liquid-ByBJuq1e.js,sha256=7ZF3wg-IEqK-Rk7HiLr7UzG1_SOfw5LwZFCu4XT37EY,3344
206
+ dw/server/ui/assets/lspLanguageFeatures-6nDoG86-.js,sha256=CEL0QChlxCbfOexpebNFdUcCHJavV2YZyquqaX_uxJo,28224
207
207
  dw/server/ui/assets/lua-CsQS60Ue.js,sha256=T68zBfv8YbWQOUMOoKDHlS6ZLXQbvUoVzIqjfdKaN80,1982
208
208
  dw/server/ui/assets/m3-D-oSqn_W.js,sha256=wiQpsc-ejuU-Nd_N1EEku70GvFxCKR2enx_4FMaLERU,2520
209
209
  dw/server/ui/assets/markdown-Cimd5fb3.js,sha256=Yh5RI0xP6paio6bg3VkVHxwCFtfLSpYzYe4pqjAseXc,3639
210
- dw/server/ui/assets/mdx-DIXDAORJ.js,sha256=JasH_a_JestYGCqgP7WnXa5aJ1o4CVmIrKSfTwDjd1I,4319
210
+ dw/server/ui/assets/mdx-BH2GyjV6.js,sha256=LN8n6930Q5oECqxSnuDnqrvFezNjNtp9_jYdGuF_tR0,4319
211
211
  dw/server/ui/assets/mips-CIPQ_RoX.js,sha256=Mf9nhH4UiNv4cOxx9GbzZEwcanALyeX1nqZyeDVwn-8,2325
212
- dw/server/ui/assets/monaco-BgG3yDUh.js,sha256=-tPGN66E881AHHbYDLc3RPl6o-RMEUG6MP1Ogc1dHx8,1296590
212
+ dw/server/ui/assets/monaco-B6Bmfo5o.js,sha256=6lfM05HipLDtx9mQgDzJ8xKPbynOJ30_u3PGhk3wJBQ,1296590
213
213
  dw/server/ui/assets/monaco-n7clI0si.css,sha256=_s5n5INJJjzoqAk04ZYXP99EFmWEMeL6k0BatkMtehw,86925
214
214
  dw/server/ui/assets/msdax-DauUninz.js,sha256=x-Ec1FvZQfNyIBufG3aF-nbhjtWWCb4trNEl2w7mORU,4270
215
215
  dw/server/ui/assets/mysql-SOo6toE5.js,sha256=s0175vipA9oId7yWxl-u4jDQp6cAD1LlzIlQ94knUzE,9659
@@ -225,10 +225,10 @@ dw/server/ui/assets/powerquery-D3hlyOfw.js,sha256=h7-yZyeDYpf8Vz7I-o-AdOXL673EDo
225
225
  dw/server/ui/assets/powershell-DmHpPYUd.js,sha256=fS-k4myYtbJ7I-nT4AOE2xWBU6BC4yBTsO8utRI2kYA,3057
226
226
  dw/server/ui/assets/protobuf-C531GsRP.js,sha256=CE2QZMYH5tuK5qacJhFCN5Egq0ldACCn8ZMy7drCA_A,8897
227
227
  dw/server/ui/assets/pug-Z5eAx3Zn.js,sha256=3W_Q5pw42PShvXTeZmdid5YpzS29ZEKItG3NbMZkZIY,4468
228
- dw/server/ui/assets/python-CXHtns6L.js,sha256=ghbUsXmtjdxFmH-hYn4MFbPijetAs87UtFbXFzIs8QI,3455
228
+ dw/server/ui/assets/python-C1sJMrAm.js,sha256=nfFgkSFRtGO3LSIz7qTphVInXha9nODLrGLtukYP4YE,3455
229
229
  dw/server/ui/assets/qsharp-DkqhCAOL.js,sha256=72cTeKiuU6qRxzI9j4KVb-r2y5u7Yj9O-DppqJMrsw8,2722
230
230
  dw/server/ui/assets/r-BwWrilGY.js,sha256=kjvwR-197La6WrPfRntvc5VS4GcVs7SVUIcq5brgDh4,2836
231
- dw/server/ui/assets/razor-BSKKsa7H.js,sha256=fLcucbocu3aJGx6QX8OdhQyEMwue0QuNJ84nk3rt8gM,8113
231
+ dw/server/ui/assets/razor-BdPZ4bvZ.js,sha256=rZdZMglNYfMd7_aIp5sLxuR1rAY0W0sp7Wo9Ewnbsj0,8113
232
232
  dw/server/ui/assets/redis-ClamHrr6.js,sha256=P6KIG5bJRWvmyPzG14QO5RZJlmj49pzn-p4hDqSFQ5M,3032
233
233
  dw/server/ui/assets/redshift-DT7zqm-g.js,sha256=PmLS8mPeeCIWu-NLw1SMU7nZp94WvW7aqKAG7TbJv3c,10331
234
234
  dw/server/ui/assets/restructuredtext-BYgofb2h.js,sha256=UmiK7-mgglvXYqrOt4NCdx4oKNNoHilj1XfmVkRw7mA,3744
@@ -248,15 +248,15 @@ dw/server/ui/assets/swift-Bxkupp3x.js,sha256=PAoUaoj9w0C1Q8tOfBsDefytIxzaJLYxXo8
248
248
  dw/server/ui/assets/systemverilog-Bz4Y3fRF.js,sha256=N8BJdmDPdAS3YSLf9-c6WjpeHiC8AUiPFC0b83QRu84,6850
249
249
  dw/server/ui/assets/tcl-DISqw1ZD.js,sha256=tGDwrjRxtiwzHBQVX4aYHPx2tvnzyCbsk3MouRN8nGI,3271
250
250
  dw/server/ui/assets/ts.worker-DGGa2mF8.js,sha256=Eo0Wf0gtl2BDSbqkCqvF4LtrJA8iMe9U-cKzQ3RM8kY,6928036
251
- dw/server/ui/assets/tsMode-DRjPuZ2P.js,sha256=stGt2g65vXHBJUcvsnaN0VduGPrMQeVeEC3Amjmh4-A,21847
251
+ dw/server/ui/assets/tsMode-DW5i-ukN.js,sha256=SHpT17bB1Vr0Mgj4X65lY2rTAzAulIqC6ZoHWx2pTas,21847
252
252
  dw/server/ui/assets/twig-De2hgUGE.js,sha256=7UK-mZY0t2AOG2upJFdhUfk_hN4jQxNO37xW_pXsYRk,5781
253
- dw/server/ui/assets/typescript-CBpoJtqE.js,sha256=_lT6DurDta2R7pypsy5aXn8Ry0g--oCIYOrnV2Hg6Vg,4675
253
+ dw/server/ui/assets/typescript-C_QzKQY3.js,sha256=T-pvuR6OoySQJCnwpBquogfYCebl_SwcrgHyWgxQc9Q,4675
254
254
  dw/server/ui/assets/typespec-B8J7ngcE.js,sha256=4SiWGtYCn-n7DAFoQw3hFbXpXOEzUIVgPrFnMxeDL0A,2625
255
255
  dw/server/ui/assets/vb-DV3o63ZY.js,sha256=g6FxShoSupLTGxKrGHUt31pO6FoCrY9npMMQpnSqtsM,5300
256
256
  dw/server/ui/assets/wgsl-DpFanUEy.js,sha256=M1uSecn4lmt1G3mQyTCdxT4mfHC4g3AjJAw7cuUwAg4,7182
257
- dw/server/ui/assets/workers-DUo4Mox_.js,sha256=2Aal3_CAIcvbncVDM9KRN9fkuZ4Je9OpuXmDbovaKr0,1249
258
- dw/server/ui/assets/xml-B2gZoNmP.js,sha256=UJiX-BOEorVj77vQP8MAbaTPHRnX6bJmZV5YY4ITQEI,1923
259
- dw/server/ui/assets/yaml-CSvo_Woe.js,sha256=wsmSOyrRZCvvHMdDf2Xp69iZPzA00jfr9dk5ColgyQQ,3543
257
+ dw/server/ui/assets/workers-DHqaOvh8.js,sha256=iv0CjV3QoMph6T5KZ8cJIcMlj5WxxR5pJYEPc0y15I0,1249
258
+ dw/server/ui/assets/xml-D3UEcM_2.js,sha256=DBlGU6BbqQpxFUxQz9Dhwjpc8WtUK715ToLtiK83afE,1923
259
+ dw/server/ui/assets/yaml-C0TnGcnd.js,sha256=cTPUYRqdrNuvnayrISH1XUghXzTfQ2vBkA9LQ7JmsPU,3543
260
260
  dw/tasks/assess.py,sha256=fgz2x3P6-9z9gusMgfws9kWqeVF9XkeabEwTzifSBQY,33654
261
261
  dw/tasks/audio_dynamics.py,sha256=-dhNkBM3CkWGLbbd5fUExbWCb4FyLJp3mYkqIO4OeIg,18060
262
262
  dw/tasks/audio_handlers.py,sha256=0hLa6olH2x01mQO5ev9yUBDd5BZbeHoZWGzkac_ut8c,8799
@@ -267,7 +267,7 @@ dw/tasks/beats.py,sha256=Eix0e-vXVhNkQCaeNPuE9m18S5jbY0Ikt6Vuz-QvWJ8,12603
267
267
  dw/tasks/borders.py,sha256=ZFnvODeLnF4nMMogOAZKEKHPMM7qebW1A4GaZFyDKmI,4253
268
268
  dw/tasks/compose_text.py,sha256=7N-9ti5XfhwECZIXzx7IgTbmm2Kt8GmcR8yK5mbEXEY,3127
269
269
  dw/tasks/concat_videos.py,sha256=Auyt-QW1ENbxGWQ7u2r-Y1tm2CH_V-7Hsi8Sj80_ooY,17506
270
- dw/tasks/cuts.py,sha256=KYaII_xQLfGwsrx5xAYdIPxYRLMnPtujEB3isyntjYo,45103
270
+ dw/tasks/cuts.py,sha256=d1NZMZSqbRw9th3FurqeHAna9wGzPxSGRXt4-Cl5B4I,45054
271
271
  dw/tasks/depth_estimator.py,sha256=uVsMueg6pZy-1NA_uY5PRMezl9jyUbSYmyQaV8o8sHY,1704
272
272
  dw/tasks/diffusion_upscale.py,sha256=7kSkXaQZ9Ng93xizAksmOZbXgGVPCgDN8PgLqOlCOiA,3416
273
273
  dw/tasks/dissolve_videos.py,sha256=GT1sDXSUo1IfG78GmS3dRRTDwVQPRz0Jk7QRlGl3fD0,12923
@@ -331,12 +331,12 @@ dw_mcp/models.py,sha256=uzsUY-CgiaP1LZLbdLnVRVXFSK2kcXs_tNquRKM6d9w,4220
331
331
  dw_mcp/prompts.py,sha256=6gVgr6PJKwqvMDEXhMqMkZ5Y2EQ2YxESZFSdS-boCvA,4156
332
332
  dw_mcp/server.py,sha256=TW58QKdg1hvlgnptp8Of-_oNpAIwzKXEahqf6hYngXM,7736
333
333
  dw_mcp/tools_authoring.py,sha256=_LrlHTwXVxb6I_8a7F11cby2rEBZ8didDX_5dvT4u-M,12321
334
- dw_mcp/tools_catalog.py,sha256=_yuEjff26dpj7pYmCecvdIQY1o9ICfWp3yer7no5fbw,21993
334
+ dw_mcp/tools_catalog.py,sha256=Sv52C9BPhbubEETHnYN_6Kut4gnPrGEh3tTlbScWNDs,21960
335
335
  dw_mcp/tools_jobs.py,sha256=Hk7MNtd-GA-he6VIepOJHkLnHD594IEMNuriqj88MEk,12015
336
336
  dw_mcp/tools_media.py,sha256=YovyYnkRzhAjIQ54Sl12c-lOy9Jq5vrQWVRxd015ehU,16909
337
- dw_mcp/workspaces.py,sha256=rWNLpINgVBvQ62dxOD6KraCahV3j-7Q-sO4ZNOgXbuE,9626
338
- diffusers_workflow-0.12.0.dist-info/METADATA,sha256=qGmM2S7jd7sfsVdx-Kyy672Oy67BZvaPN8CqLBiXsQg,14939
339
- diffusers_workflow-0.12.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
340
- diffusers_workflow-0.12.0.dist-info/entry_points.txt,sha256=Dem_AOzV-Kcpr9AASlSvJ-S5sn3f6TQu6ABb6BbApho,148
341
- diffusers_workflow-0.12.0.dist-info/top_level.txt,sha256=o-uFAN_oUOrhXfMKO39HsMs2r19L9LykxoVKj2S9q7U,10
342
- diffusers_workflow-0.12.0.dist-info/RECORD,,
337
+ dw_mcp/workspaces.py,sha256=KR4f4i8zl9EKYluQmTrYhcoOFuoqtWgp6PavaSgW8Lw,10248
338
+ diffusers_workflow-0.13.0.dist-info/METADATA,sha256=1Ttcp8B7a-crKmwSCXRZY5ONUP-WdYn6t2yBpmpnGiQ,14925
339
+ diffusers_workflow-0.13.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
340
+ diffusers_workflow-0.13.0.dist-info/entry_points.txt,sha256=Dem_AOzV-Kcpr9AASlSvJ-S5sn3f6TQu6ABb6BbApho,148
341
+ diffusers_workflow-0.13.0.dist-info/top_level.txt,sha256=o-uFAN_oUOrhXfMKO39HsMs2r19L9LykxoVKj2S9q7U,10
342
+ diffusers_workflow-0.13.0.dist-info/RECORD,,
dw/disk_caches.py CHANGED
@@ -33,7 +33,11 @@ refused, until someone marks it by hand.
33
33
  is renamed into one `<root>/.clearing-<pid>-<rand>/` directory, which is then
34
34
  deleted. A writer racing the clear finds an empty cache and rebuilds; it never
35
35
  reads a half-deleted tree. An entry delete moves the one entry the same way. The
36
- routes refuse while a job is running or queued.
36
+ routes refuse while a job is running or queued, and hold the job queue still
37
+ (`JobManager.hold_dispatch`) while they work, so a job submitted meanwhile waits
38
+ instead of starting into a root being emptied. A staging directory a killed
39
+ server left behind is removed at `mark_roots()` and at the next clear, and is
40
+ never counted by a scan. `scan_all()` reuses its answer for a few seconds.
37
41
 
38
42
  **An entry id must have a cache key's shape** (`quantized_cache.is_key`, 64
39
43
  lowercase hex) before any path is built from it.
@@ -45,6 +49,7 @@ import os
45
49
  import secrets
46
50
  import shutil
47
51
  import threading
52
+ import time
48
53
  from dataclasses import dataclass
49
54
  from typing import Callable
50
55
 
@@ -65,6 +70,12 @@ _MARKER_TEXT = (
65
70
  _clear_lock = threading.Lock()
66
71
 
67
72
 
73
+ # How long scan_all's answer is reused. A scan stat()s every file of every
74
+ # cache, and get_server_info asks on each call (#840)
75
+ _SCAN_TTL = 5.0
76
+ _scan_memo = None # (monotonic time, scan_all's result)
77
+
78
+
68
79
  class UnknownCache(ValueError):
69
80
  pass
70
81
 
@@ -210,9 +221,28 @@ def _write_marker(root):
210
221
  f.write(_MARKER_TEXT)
211
222
 
212
223
 
213
- def mark_root(cache):
224
+ def _sweep_staging(root):
225
+ """Delete the `.clearing-*` directories a clear that died mid-delete left
226
+ in `root`. Only called where no clear can be running: server start, or
227
+ inside `_clear_lock`."""
228
+ try:
229
+ leftovers = [
230
+ entry.path
231
+ for entry in _children(root)
232
+ if entry.name.startswith(_CLEARING_PREFIX)
233
+ and entry.is_dir(follow_symlinks=False)
234
+ ]
235
+ except OSError:
236
+ return
237
+ for path in leftovers:
238
+ shutil.rmtree(path, ignore_errors=True)
239
+ logger.info(f"Removed the leftover {path} from an interrupted clear")
240
+
241
+
242
+ def mark_root(cache, quiet=False):
214
243
  """Mark one cache's root as dw's to clear, if the rule allows it.
215
- Returns whether the root carries the marker afterwards."""
244
+ Returns whether the root carries the marker afterwards. `quiet` logs the
245
+ refusal at DEBUG: only the startup pass says it at INFO (#841)."""
216
246
  root = cache.root()
217
247
  if os.path.islink(root) or (os.path.exists(root) and not os.path.isdir(root)):
218
248
  return False
@@ -223,9 +253,10 @@ def mark_root(cache):
223
253
  if _has_marker(root):
224
254
  return True
225
255
  if _children(root) and root != cache.default_root():
226
- logger.info(
256
+ logger.log(
257
+ logging.DEBUG if quiet else logging.INFO,
227
258
  f"The {cache.name} cache at {root} was not created by dw and "
228
- f"has no {MARKER} marker, so it can't be cleared from the server"
259
+ f"has no {MARKER} marker, so it can't be cleared from the server",
229
260
  )
230
261
  return False
231
262
  _write_marker(root)
@@ -237,7 +268,8 @@ def mark_roots():
237
268
  once at server start; a root it can't write is left unclearable."""
238
269
  for cache in CACHES.values():
239
270
  try:
240
- mark_root(cache)
271
+ if mark_root(cache):
272
+ _sweep_staging(cache.root())
241
273
  except (OSError, SecurityError) as e:
242
274
  logger.warning(f"Could not mark the {cache.name} cache: {e}")
243
275
 
@@ -255,6 +287,9 @@ def _walk(top):
255
287
  continue
256
288
  with entries:
257
289
  for entry in entries:
290
+ if directory == top and entry.name.startswith(_CLEARING_PREFIX):
291
+ # A clear's staging directory is on its way out
292
+ continue
258
293
  try:
259
294
  if entry.is_dir(follow_symlinks=False):
260
295
  stack.append(entry.path)
@@ -295,7 +330,7 @@ def _reason(cache):
295
330
  root = cache.root()
296
331
  if os.path.isdir(root) and not _has_marker(root):
297
332
  try:
298
- mark_root(cache)
333
+ mark_root(cache, quiet=True)
299
334
  except (OSError, SecurityError) as e:
300
335
  logger.warning(f"Could not mark the {cache.name} cache: {e}")
301
336
  return _not_clearable_reason(root)
@@ -340,7 +375,7 @@ def scan(cache):
340
375
  def _entry_fields(path):
341
376
  """What an entry's `entry.json` says of it, or None when it can't be
342
377
  read. `component` falls back to the subfolder - the component's name in
343
- a diffusers repo - since entry.json doesn't record it."""
378
+ a diffusers repo - for entries written before entry.json recorded it."""
344
379
  try:
345
380
  entry = quantized_cache.read_entry(path)
346
381
  except (OSError, ValueError):
@@ -385,7 +420,20 @@ def scan_entries(root):
385
420
 
386
421
 
387
422
  def scan_all():
388
- return [scan(cache) for cache in CACHES.values()]
423
+ """Every cache as plain data, reused for `_SCAN_TTL` seconds; a clear or
424
+ entry delete drops the reused answer."""
425
+ global _scan_memo
426
+ memo = _scan_memo
427
+ if memo is not None and time.monotonic() - memo[0] < _SCAN_TTL:
428
+ return memo[1]
429
+ result = [scan(cache) for cache in CACHES.values()]
430
+ _scan_memo = (time.monotonic(), result)
431
+ return result
432
+
433
+
434
+ def _forget_scans():
435
+ global _scan_memo
436
+ _scan_memo = None
389
437
 
390
438
 
391
439
  def entry_cache(name, entry):
@@ -441,10 +489,12 @@ def delete_entry(name, entry):
441
489
  if reason:
442
490
  raise NotClearable(f"The {name} cache at {root} can't be changed: {reason}")
443
491
  root = validate_path(root)
492
+ _sweep_staging(root)
444
493
  path = quantized_cache.entry_path(root, entry)
445
494
  if os.path.islink(path) or not os.path.isdir(path):
446
495
  raise UnknownEntry(f"The {name} cache has no entry {entry}")
447
496
  freed, files = _stage_out(root, [path])
497
+ _forget_scans()
448
498
  logger.info(f"Deleted {name} cache entry {entry} ({freed} bytes, {files} files)")
449
499
  return {"freed": freed, "files": files}
450
500
 
@@ -462,10 +512,12 @@ def clear(name):
462
512
  if reason:
463
513
  raise NotClearable(f"The {name} cache at {root} can't be cleared: {reason}")
464
514
  root = validate_path(root)
515
+ _sweep_staging(root)
465
516
  # A link is left alone: validate_path resolves it, so the rename
466
517
  # would move its target, not the link
467
518
  freed, files = _stage_out(
468
519
  root, [entry.path for entry in _children(root) if not entry.is_symlink()]
469
520
  )
521
+ _forget_scans()
470
522
  logger.info(f"Cleared the {name} cache at {root} ({freed} bytes, {files} files)")
471
523
  return {"freed": freed, "files": files}
dw/docs/ARCHITECTURE.md CHANGED
@@ -150,10 +150,10 @@ one to open.
150
150
  | App factory | `dw/server/app.py`: `create_app` | `create_app` builds the JobManager and `app.state`, installs the middleware and registers the routes, and all state lives in the JobManager. | — |
151
151
  | Routers | `dw/server/routes/*.py`, `dw/server/routes/__init__.py`: `ROUTERS`, `include_routers`, `include_file_routes` | Routers register in `ROUTERS` order, because a greedy `{name:path}` route must come after its specific siblings. The files router comes later, after `/mcp`. | `tests/test_server_downloads.py::test_download_workflow_sets_content_disposition_attachment` |
152
152
  | Job queue | `dw/server/jobs.py`: `JobManager`; `dw/server/job_results.py`: `consume_results` | A dispatcher thread hands queued jobs, in queue order, to the pool's workers (`Worker pool dispatch`); each worker runs one job at a time, and `consume_results` folds that worker's replies into the job, naming files relative to the job's own `output_dir`. A job carries its own `output_dir`, `asset_dir` and `workflow_dir`, so it stays in its workspace. | `tests/test_server_workspaces.py::TestRunning::test_rerun_stays_in_the_workspace_it_ran_in` (FIFO: —) |
153
- | Worker pool dispatch | `dw/server/jobs.py`: `JobManager._next_dispatch`; `dw/server/pool.py`: `WorkerSlot`, `check_fits`, `largest_ceiling_gb`; `dw/vram_estimate.py`: `required_vram_gb`; `dw/server/admission.py`: `pool_capacity` | `--devices` runs one worker per card; a queued job goes to a free card that fits what it needs, a job that fits no free card keeps its place while a smaller one behind it takes the card, a job bigger than every card is refused at submit, and cancel or a crash touches only the worker running that job. On a backend no `cost` entry describes, a declared `vram_estimate` is held at admission to the pool's largest card, so a job the first card cannot hold is not refused when a larger card can hold it. | `tests/test_worker_pool.py::TestConcurrency::test_two_workers_run_two_jobs_at_once`, `tests/test_worker_pool.py::TestBackfill::test_a_job_too_big_for_the_free_card_waits_while_a_smaller_one_takes_it`, `tests/test_worker_pool.py::TestFitAtSubmit::test_a_job_too_big_for_every_card_is_refused_naming_the_largest`, `tests/test_worker_pool.py::TestCancel::test_cancel_reaches_the_worker_running_the_job`, `tests/test_worker_pool.py::TestCrashIsolation::test_a_crashed_worker_fails_only_its_own_job`, `tests/test_worker_pool.py::TestOomRanking::test_the_later_started_worker_is_ranked_first`, `tests/test_worker_pool.py::TestFitAtSubmit::test_a_job_only_the_larger_card_holds_is_admitted` |
153
+ | Worker pool dispatch | `dw/server/jobs.py`: `JobManager._next_dispatch`; `dw/server/pool.py`: `WorkerSlot`, `check_fits`, `largest_ceiling_gb`; `dw/vram_estimate.py`: `required_vram_gb`; `dw/server/admission.py`: `pool_capacity` | `--devices` runs one worker per card; a queued job goes to a free card that fits what it needs (none starts while a cache clear holds dispatch, `dw disk caches`), a job that fits no free card keeps its place while a smaller one behind it takes the card, a job bigger than every card is refused at submit, and cancel or a crash touches only the worker running that job. On a backend no `cost` entry describes, a declared `vram_estimate` is held at admission to the pool's largest card, so a job the first card cannot hold is not refused when a larger card can hold it. | `tests/test_worker_pool.py::TestConcurrency::test_two_workers_run_two_jobs_at_once`, `tests/test_worker_pool.py::TestBackfill::test_a_job_too_big_for_the_free_card_waits_while_a_smaller_one_takes_it`, `tests/test_worker_pool.py::TestFitAtSubmit::test_a_job_too_big_for_every_card_is_refused_naming_the_largest`, `tests/test_worker_pool.py::TestCancel::test_cancel_reaches_the_worker_running_the_job`, `tests/test_worker_pool.py::TestCrashIsolation::test_a_crashed_worker_fails_only_its_own_job`, `tests/test_worker_pool.py::TestOomRanking::test_the_later_started_worker_is_ranked_first`, `tests/test_worker_pool.py::TestFitAtSubmit::test_a_job_only_the_larger_card_holds_is_admitted` |
154
154
  | Card affinity | `dw/server/pool.py`: `choose_slot`; `dw/server/jobs.py`: `JobManager.route`; `dw/worker_protocol.py`: `workflow_identity` | Among the free cards a job fits it goes to the rerun's original card, else the card whose worker last ran its workflow identity (`workflow_identity`, the one rule the worker caches by too), else one with no worker running, else the first in `--devices` order; a cache probe and `plan.estimate` (`priced_for`) ask about the card `route` names, and memory is read and cleared per card. | `tests/test_worker_pool.py::TestIdentityAffinity::test_a_second_run_lands_on_the_card_that_ran_the_workflow_first`, `tests/test_worker_pool.py::TestRerunAffinity::test_a_rerun_lands_on_the_original_card_when_it_is_free`, `tests/test_worker_pool.py::TestProbeRouting::test_the_probe_goes_to_the_worker_the_job_would_be_routed_to`, `tests/test_worker_pool.py::TestMemoryPerCard::test_a_named_card_running_a_job_is_refused_though_the_other_is_idle` |
155
155
  | Per-card memory and cache | `dw/server/worker_memory.py`: `memory_status`, `clear_memory`, `probe_cache` | Each card keeps its own last memory reading; an idle card's worker is asked live, a busy one answers with the run's last report and says why it is not live, and a clear leaves a card running a job alone. Every request takes the card's lock with a bounded wait, and a card's lock is never taken while the JobManager's lock is held. | `tests/test_worker_pool.py::TestMemoryPerCard::test_a_named_card_running_a_job_is_refused_though_the_other_is_idle`, `tests/test_worker_pool.py::TestProbeRouting::test_the_probe_goes_to_the_worker_the_job_would_be_routed_to`, `tests/test_server.py::test_memory_says_why_a_reading_is_not_the_worker_s` |
156
- | dw disk caches | `dw/disk_caches.py` | Members `inductor`, `triton`, `quantized`. Clear only a root carrying the `.dw-cache` marker, never while a job is running or queued (`quantized` also not during a model download); an entry delete takes only a 64-hex id, checked before any path is built; clear renames into `.clearing-*` then deletes. | `tests/test_disk_caches.py` |
156
+ | dw disk caches | `dw/disk_caches.py`; `dw/server/jobs.py`: `JobManager.hold_dispatch`; `dw/server/routes/system.py`: `clear_cache`, `delete_cache_entry` | Members `inductor`, `triton`, `quantized`. Clear only a root carrying the `.dw-cache` marker, never while a job is running or queued (`quantized` also not during a model download); an entry delete takes only a 64-hex id, checked before any path is built; clear renames into `.clearing-*` then deletes. The busy check and the dispatch hold are one step in `JobManager.hold_dispatch`, kept for the whole clear or entry delete: a job submitted meanwhile is accepted but stays queued until it ends. | `tests/test_disk_caches.py`, `tests/test_disk_caches.py::test_job_submitted_during_a_clear_waits_for_it` |
157
157
  | Job-to-run link | `dw/server/job_record.py`, `dw/server/jobs.py`: `JobManager.realized` | A job records `run_id`, `run_dir` and `run_version`, and `JobManager.realized` reads that run's `workflow.json`, confined to the output root. | `tests/test_server_jobs.py::test_realized_reads_the_file_the_run_wrote`, `tests/test_server_jobs.py::test_realized_refuses_a_run_dir_that_escapes_the_output_root` |
158
158
  | Job history | `dw/server/job_history.py`: `JobHistory` | Finished jobs persist in `jobs.sqlite`, in WAL mode, so the Jobs view survives a restart. | `tests/test_server.py::test_job_history_survives_restart_and_reruns`, `tests/test_job_history_wal.py::test_the_jobs_database_uses_wal_mode` |
159
159
  | HTTP security | `dw/server/http_security.py`: `install_middleware`, `query_token_ok` | Every API route needs the token, and only a route marked `query_token_ok` takes it as `?token=`. | `tests/test_security_auth.py::TestTheTokenGate::test_every_api_spelling_needs_the_token`, `tests/test_security_auth.py::TestTheTokenGate::test_the_query_token_is_refused_where_it_is_not_allowed` |
dw/docs/DEPENDENCIES.md CHANGED
@@ -76,10 +76,10 @@ bash ./install.sh
76
76
 
77
77
  ## Troubleshooting
78
78
 
79
- **Hugging Face authentication (401/403 downloading a model):** Most workflows under `workflows/` (Flux, LTX-2, MiniMax...) point at **gated** models on the Hub — repos that require the owner to approve your account before you can download them. A run against one of these fails with an actionable error naming the repo and `huggingface-cli login` (mapped from the Hub's 401/403 in `load_component()`, `dw/pipeline_processors/components.py`) — request access on the model's page (e.g. [black-forest-labs/FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev)) and then log in once, locally:
79
+ **Hugging Face authentication (401/403 downloading a model):** Most workflows under `workflows/` (Flux, LTX-2, MiniMax...) point at **gated** models on the Hub — repos that require the owner to approve your account before you can download them. A run against one of these fails with an actionable error naming the repo and `hf auth login` (mapped from the Hub's 401/403 in `load_component()`, `dw/pipeline_processors/components.py`) — request access on the model's page (e.g. [black-forest-labs/FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev)) and then log in once, locally:
80
80
 
81
81
  ```bash
82
- huggingface-cli login
82
+ hf auth login
83
83
  ```
84
84
 
85
85
  `workflows/templates/text-to-image.json` uses an ungated model and needs no login - start there if you just want to confirm the install works.
dw/docs/MCP.md CHANGED
@@ -229,7 +229,7 @@ when no single workflow covers it.
229
229
  | `list_models()` | — | List what the Hugging Face model cache holds, largest first |
230
230
  | `get_memory()` | `device` | Get VRAM and RAM statistics: `workers` has one reading per card (the top level repeats the first card's), and `device` (`cuda:1`) asks for that card alone. `gpu_*` is the card; `host_memory_rss_mb` / `host_memory_peak_rss_mb` are the worker process's resident and high-water host memory, beside the machine's `host_memory_total_mb` / `host_memory_available_mb`; on Linux `host_memory_rss_anon_mb` / `host_memory_rss_file_mb` split the resident figure into memory the worker owns and mapped-file pages (memory-mapped checkpoint weights) the kernel can drop, so a loader that maps rather than copies raises the resident and peak figures without raising committed memory (#709) - read both, since an offloading workflow keeps its weights in host RAM and the card says little about what it holds (a host field is absent, not null, where the platform cannot measure it). `host_pinned_reserved_mb` / `host_pinned_allocated_mb`, when present, are torch's pinned-host cache - the staging buffers group offloading moves weights through, part of `host_memory_rss_mb` and invisible in every `gpu_*` figure, which is what a worker holding GB after releasing every model is usually holding (#98). `live: true` means `info` was measured now and is the worker's own memory; only live readings are comparable with each other. `live: false` with `info: null` (and `stale: false`) means nothing has been measured because nothing is resident; `live: false` with a populated `info` is a cached earlier reading, with `reason` (`job_running`, `worker_stopped`, `worker_busy`, `worker_unreachable`) and `age_seconds` - one cached while a job loads a model understates what is resident, so ask again when the card is idle rather than comparing it with a live figure |
231
231
  | `get_health()` | — | Check that the server is alive, and which machine answered: `version`, `device`, whether any model process is resident (`worker_alive`), and the queue depth. The engine runs one job per GPU: `workers` has one entry per card - `device`, `name`, `vram_gb`, `alive`, its own `current_job`, and the worker's `host_memory_rss_mb` while it runs - and the top-level `current_job` is the longest-running job. `worker_alive: false` is the normal idle state on a server that has not run a job since startup or the last memory clear - not a fault - the on-demand worker starts with the next job (#206) |
232
- | `get_server_info()` | — | What this installation can do and where it keeps things: `device` (the accelerator a run will use), `version`, the `workspace` this session is working in and the workflow/asset/output/prompt `directories` of *that* workspace, the bind address and port, whether a token is required, and whether MCP is mounted. Check the device before authoring - a CUDA-only choice (bitsandbytes, `torch.compile`, flash attention) is not available on an `mps` or `cpu` server. `runtime` (#222) reports the Python version, torch version and the CUDA version torch was built against, the NVIDIA driver version (when `nvidia-smi` is reachable), and the installed versions of diffusers, transformers, accelerate, bitsandbytes, peft, safetensors and sentencepiece (`null` for one not installed) - for diagnosing an environment mismatch between boxes without shelling in. `caches` lists dw's disk caches (`inductor`, `triton`, `quantized`), each with `name`, `bytes`, `files`, `enabled`, `clearable` and `disk_free`, plus `entry_count` for a cache with entries (no entry listing over MCP); it is omitted when the server has no `/api/caches`. There is no MCP tool to clear one - that is `DELETE /api/caches/{name}` or `.../entries/{entry}` ([SERVER.md](SERVER.md)) |
232
+ | `get_server_info()` | — | What this installation can do and where it keeps things: `device` (the accelerator a run will use), `version`, the `workspace` this session is working in and the workflow/asset/output/prompt `directories` of *that* workspace, the bind address and port, whether a token is required, and whether MCP is mounted. Check the device before authoring - a CUDA-only choice (bitsandbytes, `torch.compile`, flash attention) is not available on an `mps` or `cpu` server. `runtime` (#222) reports the Python version, torch version and the CUDA version torch was built against, the NVIDIA driver version (when `nvidia-smi` is reachable), and the installed versions of diffusers, transformers, accelerate, bitsandbytes, peft, safetensors and sentencepiece (`null` for one not installed) - for diagnosing an environment mismatch between boxes without shelling in. `caches` lists dw's disk caches (`inductor`, `triton`, `quantized`), each with `name`, `bytes`, `files`, `enabled`, `clearable` and `disk_free`, plus `entry_count` for a cache with entries, and `cache_entries=true` lists them (`id`, `model`, `subfolder`, `component`, `bytes`, `files`, `unreadable`, `created`, `last_hit`; the quantizer and dtype are not in `/api/caches`); it is omitted when the server has no `/api/caches`. There is no MCP tool to clear one - that is `DELETE /api/caches/{name}` or `.../entries/{entry}` ([SERVER.md](SERVER.md)) |
233
233
  | `list_jobs(limit=20, status=None, workspace=None)` | optional `limit` (newest N), `status` (one state or a comma-separated set of `queued`, `running`, `succeeded`, `failed`, `cancelled`), `workspace` | List queued, running and recent jobs, **newest first**. Bounded by default: the unbounded listing was over a client's tool-result limit on a server with a few months of history, which made it a tool that could not be called at all. `total` says how many matched and `truncated`/`next` say so when the answer was cut - raise `limit` or narrow with `status`. Without `workspace`, a named workspace lists its own jobs and the default one lists every job the server holds |
234
234
  | `list_gallery(limit=50, subfolder=None, only_orphans=False, workspace=None, folder=None, version=None)` | `limit`, `subfolder`, `only_orphans`, `workspace`, `folder`, `version` | List generated output files, newest first. A name is `<workflow>/<run id>/<file>`, where `<file>` may sit in the subfolder the step chose (`final/episode.mp4`); each entry carries `folder` (the workflow) and `subfolder` (by convention `final` or `intermediate`, `''` when the step chose none, any path the workflow wrote otherwise), and `subfolder="final"` lists only deliverables. Each entry carries `run_id` and `version` - that run's ordinal among the workflow's runs, which is how one of several runs that wrote the same basename is named to a person: the web UI labels the same file `v5`. The number is assigned when the run opens and never renumbered, so deleting a run leaves a gap rather than sliding the rest down (a failed run, or a rerun that reused every step, leaves one too - it took a number and may have nothing to list), and it is `null` under the flat output layout, which has no runs. `folder` with `version` lists that one run's files, and `output:<folder>/v5/<file>` names one in a workflow; every other tool takes `name`. Each entry also carries a ready-made `url`, already scoped to the workspace that made it - a hand-built `/outputs/<name>` URL 404s for anything but the default workspace. `only_orphans=True` inverts the call: instead of files, it returns run directories with no media anywhere under them (`runs`, each `{name, mtime}`) - a run whose output was deleted before `delete_output` could remove it by name, or one that failed before writing anything; `subfolder` does not apply in this mode, and `name` is exactly what `delete_output` accepts (#170). `workspace` names the workspace for this one call without switching the session to it - the same pin `run_workflow` takes, so a job run into another workspace stays reachable from the session that queued it |
235
235
  | `get_gallery_metadata(name, envelope=False, workspace=None, interval_seconds=None)` | `name`, `workspace` | Get the metadata embedded in a generated file — or, when `name` is an `asset:` reference, what an *input* asset holds (`source` says which; `job` is null for an asset). Reading an input's duration, frame count, fps and sample rate before a run is how a caller learns the `total_frames`, `fps` and `sample_rate` a workflow expects it to supply: the exact workflow and arguments that produced it, and, for audio/video, a `media` block (duration, rate, channels, fps, size, peak/mean dBFS) and `findings` - each level problem the server measured against `dw/audio_qc.py`'s thresholds (`full_scale`, `near_silent`), with the fix. Only an image (PNG/JPEG/WebP) embeds `metadata` this way — it is always null for audio and video, and `next` then points at `get_job_workflow(job_id)` when `job` is known, or says a kept asset carries no provenance at all when it isn't. `envelope=true` adds `media.envelope` — `rms_dbfs` and `peak_dbfs` one entry per second, or per `interval_seconds` (default 1.0, 0.05 to 3600; 0.1 places a vocal onset; a finer-than-default width that would need over 2400 bins is refused with the interval that fits) — which is what locates something in a track rather than measuring the whole of it. `media.shots` is set on an output joined from shots: one `{name, start_frame, num_frames, start_sample, num_samples}` per shot, as the join measured them (see the run manifest in docs/WORKFLOW_GUIDE.md), else null. `workspace` names the workspace for this one call without switching the session to it - the same pin `run_workflow` takes, so a job run into another workspace stays reachable from the session that queued it |
dw/docs/QUANTIZATION.md CHANGED
@@ -172,7 +172,7 @@ The variables are read by the server and inherited by its workers, so set them i
172
172
  - **Why a `miss`** (its `reason`): `no_entry` (nothing saved under the key yet), `incomplete_snapshot` (the snapshot isn't all on disk, so no lookup was made), or `load_failed: <exception type>: <first line of its message>` (the entry didn't load and was deleted; the save that follows replaces it)
173
173
  - **Concurrent workers**: two workers saving the same key leave one entry; the other reports `saved` ("already saved by another worker"). A corrupt entry is deleted and quantized fresh
174
174
  - **What a hit holds**: the whole component as quantized. The save comes before pruning (`truncate_layers`, `remove_modules`), `sdnq_optimize`, LoRAs and offload, which all still apply after a hit
175
- - **At server start** (only when on): a sweep deletes leftover `*.tmp-*` directories and entries built against other package versions or with an unreadable `entry.json`, and logs the count and bytes freed. It then logs the root, bytes in use and free space, warning when free space is below the floor plus the largest entry already cached
175
+ - **At server start** (only when on): a sweep deletes leftover `*.tmp-*` directories and entries built against other package versions, keyed under another `KEY_VERSION` (how the key's inputs are derived; one made before the field records none), or with an unreadable `entry.json`, and logs the count and bytes freed. It then logs the root, bytes in use and free space, warning when free space is below the floor plus the largest entry already cached
176
176
  - **Clearing**: there is no other eviction. Use the server page's Caches panel (the whole cache, or one entry from its expandable table), or `DELETE /api/caches/quantized` / `DELETE /api/caches/quantized/entries/{id}`. `GET /api/caches` lists the entries (model, subfolder, size, created, last hit) and `low_disk` (free space under the floor). Clearing is refused while a job is running or queued, and while a model download is active; an off cache still lists and clears what is on disk
177
177
  - **Event**: a `quantized_cache` job event, `{component, result: hit|miss|saved|skipped, reason?, seconds, bytes}`. A `miss`'s `seconds` is the time of the whole `load_components` batch, shared by the components it loaded; on the per-component path it is that one component's load
178
178