diffusers-workflow 0.4.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 (260) hide show
  1. diffusers_workflow-0.4.0.dist-info/METADATA +318 -0
  2. diffusers_workflow-0.4.0.dist-info/RECORD +260 -0
  3. diffusers_workflow-0.4.0.dist-info/WHEEL +5 -0
  4. diffusers_workflow-0.4.0.dist-info/entry_points.txt +7 -0
  5. diffusers_workflow-0.4.0.dist-info/licenses/LICENSE +201 -0
  6. diffusers_workflow-0.4.0.dist-info/top_level.txt +2 -0
  7. dw/__init__.py +440 -0
  8. dw/adapter_compatibility.py +226 -0
  9. dw/arguments.py +1231 -0
  10. dw/assessment_rules.py +159 -0
  11. dw/assets.py +130 -0
  12. dw/cache_blocks.json +16 -0
  13. dw/cache_blocks.py +146 -0
  14. dw/community_pipelines/pipeline_flux_rf_inversion.py +1184 -0
  15. dw/content_types.py +150 -0
  16. dw/dissolve_frame_errors.py +121 -0
  17. dw/docs/ACCELERATION.md +352 -0
  18. dw/docs/AGENT_LOOP.md +95 -0
  19. dw/docs/DEPENDENCIES.md +91 -0
  20. dw/docs/IP_ADAPTER.md +109 -0
  21. dw/docs/LORAS.md +131 -0
  22. dw/docs/MCP.md +517 -0
  23. dw/docs/PROMPT_WEIGHTING.md +78 -0
  24. dw/docs/QUANTIZATION.md +230 -0
  25. dw/docs/RECIPES_24GB.md +201 -0
  26. dw/docs/RELEASING.md +195 -0
  27. dw/docs/REMOTE.md +140 -0
  28. dw/docs/REPL_COMMANDS.md +121 -0
  29. dw/docs/REPL_WORKER_GUIDE.md +51 -0
  30. dw/docs/SECURITY.md +272 -0
  31. dw/docs/SECURITY_QUICKREF.md +112 -0
  32. dw/docs/SERVER.md +679 -0
  33. dw/docs/TASKS.md +1741 -0
  34. dw/docs/TESTING.md +71 -0
  35. dw/docs/WORKFLOW_GUIDE.md +2038 -0
  36. dw/docs/WORKSPACES.md +316 -0
  37. dw/download_watch.py +335 -0
  38. dw/elision.py +306 -0
  39. dw/events.py +275 -0
  40. dw/for_each.py +409 -0
  41. dw/host_memory.py +258 -0
  42. dw/host_memory_projection.py +230 -0
  43. dw/hub_cache.py +432 -0
  44. dw/introspection.py +1228 -0
  45. dw/kernel_availability.py +208 -0
  46. dw/locations.py +599 -0
  47. dw/log_setup.py +45 -0
  48. dw/loudness.py +82 -0
  49. dw/media_audio.py +217 -0
  50. dw/media_frames.py +367 -0
  51. dw/media_info.py +297 -0
  52. dw/pipeline_processors/chain.py +821 -0
  53. dw/pipeline_processors/config_objects.py +237 -0
  54. dw/pipeline_processors/pipeline.py +2297 -0
  55. dw/pipeline_processors/remote.py +46 -0
  56. dw/plan.py +920 -0
  57. dw/previous_results.py +411 -0
  58. dw/probe_paths.py +59 -0
  59. dw/prompt_schema.json +48 -0
  60. dw/prompt_weighting.py +378 -0
  61. dw/prompts.py +159 -0
  62. dw/realize.py +250 -0
  63. dw/reference_limits.py +215 -0
  64. dw/reference_names.py +125 -0
  65. dw/repl.py +338 -0
  66. dw/repl_commands.py +836 -0
  67. dw/repl_worker.py +159 -0
  68. dw/result.py +1720 -0
  69. dw/result_fps.py +82 -0
  70. dw/run.py +162 -0
  71. dw/runs.py +768 -0
  72. dw/scalar_result_validation.py +97 -0
  73. dw/schema.py +283 -0
  74. dw/security.py +1038 -0
  75. dw/select_validation.py +115 -0
  76. dw/serve.py +277 -0
  77. dw/server/__init__.py +2 -0
  78. dw/server/app.py +4586 -0
  79. dw/server/assess.py +132 -0
  80. dw/server/catalog_shape.py +487 -0
  81. dw/server/enhancers.py +129 -0
  82. dw/server/exports.py +480 -0
  83. dw/server/guides.py +257 -0
  84. dw/server/jobs.py +1561 -0
  85. dw/server/mcp_mount.py +95 -0
  86. dw/server/netinfo.py +124 -0
  87. dw/server/observed_cost.py +379 -0
  88. dw/server/sysinfo.py +71 -0
  89. dw/server/ui/assets/abap-08VXUWAP.js +1 -0
  90. dw/server/ui/assets/apex-BWPQTe0t.js +1 -0
  91. dw/server/ui/assets/azcli-Bc_sGQ0U.js +1 -0
  92. dw/server/ui/assets/bat-i0X4ZdIN.js +1 -0
  93. dw/server/ui/assets/bicep-B5-_aFwp.js +2 -0
  94. dw/server/ui/assets/cameligo-DMUM7wLl.js +1 -0
  95. dw/server/ui/assets/clojure-Cm7r79vr.js +1 -0
  96. dw/server/ui/assets/codicon-Brq4_Ui5.ttf +0 -0
  97. dw/server/ui/assets/coffee-Ba7i2nA0.js +1 -0
  98. dw/server/ui/assets/cpp-C7h46wYY.js +1 -0
  99. dw/server/ui/assets/csharp-BKxtCVv1.js +1 -0
  100. dw/server/ui/assets/csp-bTuwJoIa.js +1 -0
  101. dw/server/ui/assets/css-DIMkf-bt.js +3 -0
  102. dw/server/ui/assets/css.worker-B3ciXF_0.js +93 -0
  103. dw/server/ui/assets/cssMode-CPznxfY8.js +1 -0
  104. dw/server/ui/assets/cypher-CVaqCwHa.js +1 -0
  105. dw/server/ui/assets/dart-onAF5SnQ.js +1 -0
  106. dw/server/ui/assets/dockerfile-DZFCIeNp.js +1 -0
  107. dw/server/ui/assets/ecl-D05T4iGw.js +1 -0
  108. dw/server/ui/assets/editor-jjEx9u7D.css +1 -0
  109. dw/server/ui/assets/editor.api-CpWcotrd.js +847 -0
  110. dw/server/ui/assets/editor.worker-q-txB4vs.js +30 -0
  111. dw/server/ui/assets/elixir-6RTg0lbw.js +1 -0
  112. dw/server/ui/assets/flow9-C5_-GSwl.js +1 -0
  113. dw/server/ui/assets/freemarker2-CXtRM8N4.js +3 -0
  114. dw/server/ui/assets/fsharp-C8Ef5oNN.js +1 -0
  115. dw/server/ui/assets/go-C-y9NEjX.js +1 -0
  116. dw/server/ui/assets/graphql-fmXr3nnJ.js +1 -0
  117. dw/server/ui/assets/handlebars-N7x-6NMY.js +1 -0
  118. dw/server/ui/assets/hcl-CpzslTdj.js +1 -0
  119. dw/server/ui/assets/html-PhsdjHSr.js +1 -0
  120. dw/server/ui/assets/html.worker-C93Ht9o9.js +506 -0
  121. dw/server/ui/assets/htmlMode-Dgj0SEok.js +1 -0
  122. dw/server/ui/assets/index-3Vw6WAPW.css +1 -0
  123. dw/server/ui/assets/index-DgrYhQd9.js +43 -0
  124. dw/server/ui/assets/ini-sBoK_t0W.js +1 -0
  125. dw/server/ui/assets/java-BEtHBSE6.js +1 -0
  126. dw/server/ui/assets/javascript-BJqN9Qhv.js +1 -0
  127. dw/server/ui/assets/json.worker-B2V3pomh.js +62 -0
  128. dw/server/ui/assets/jsonMode-DbM4SWSv.js +7 -0
  129. dw/server/ui/assets/julia-Bri6UV-V.js +1 -0
  130. dw/server/ui/assets/kotlin-BOotOW0E.js +1 -0
  131. dw/server/ui/assets/less-B9JPFI3C.js +2 -0
  132. dw/server/ui/assets/lexon-CfSJPG6W.js +1 -0
  133. dw/server/ui/assets/liquid-BWr8lEc4.js +1 -0
  134. dw/server/ui/assets/lspLanguageFeatures-C1iGuDyZ.js +4 -0
  135. dw/server/ui/assets/lua-CsQS60Ue.js +1 -0
  136. dw/server/ui/assets/m3-D-oSqn_W.js +1 -0
  137. dw/server/ui/assets/markdown-Cimd5fb3.js +1 -0
  138. dw/server/ui/assets/mdx-DAdMi_0p.js +1 -0
  139. dw/server/ui/assets/mips-CIPQ_RoX.js +1 -0
  140. dw/server/ui/assets/monaco--ixms01u.css +1 -0
  141. dw/server/ui/assets/monaco-BGCeEqaw.js +56 -0
  142. dw/server/ui/assets/msdax-DauUninz.js +1 -0
  143. dw/server/ui/assets/mysql-SOo6toE5.js +1 -0
  144. dw/server/ui/assets/objective-c-FvmIjYaQ.js +1 -0
  145. dw/server/ui/assets/pascal-DrH0SRf2.js +1 -0
  146. dw/server/ui/assets/pascaligo-D-ptJ9y-.js +1 -0
  147. dw/server/ui/assets/perl-oz_6vUea.js +1 -0
  148. dw/server/ui/assets/pgsql-DTj74zXo.js +1 -0
  149. dw/server/ui/assets/php-nr791fC2.js +1 -0
  150. dw/server/ui/assets/pla-CopQ2nXW.js +1 -0
  151. dw/server/ui/assets/postiats-43DmfD33.js +1 -0
  152. dw/server/ui/assets/powerquery-D3hlyOfw.js +1 -0
  153. dw/server/ui/assets/powershell-DmHpPYUd.js +1 -0
  154. dw/server/ui/assets/protobuf-C531GsRP.js +2 -0
  155. dw/server/ui/assets/pug-Z5eAx3Zn.js +1 -0
  156. dw/server/ui/assets/python-Bcn70HdC.js +1 -0
  157. dw/server/ui/assets/qsharp-DkqhCAOL.js +1 -0
  158. dw/server/ui/assets/r-BwWrilGY.js +1 -0
  159. dw/server/ui/assets/razor-D1HmNnby.js +1 -0
  160. dw/server/ui/assets/redis-ClamHrr6.js +1 -0
  161. dw/server/ui/assets/redshift-DT7zqm-g.js +1 -0
  162. dw/server/ui/assets/restructuredtext-BYgofb2h.js +1 -0
  163. dw/server/ui/assets/ruby-DezsRK8O.js +1 -0
  164. dw/server/ui/assets/rust-DdL9SqIa.js +1 -0
  165. dw/server/ui/assets/sb-CcwsVR0C.js +1 -0
  166. dw/server/ui/assets/scala-DHpiXF5c.js +1 -0
  167. dw/server/ui/assets/scheme-BeGwcela.js +1 -0
  168. dw/server/ui/assets/scss-gp-XZpBa.js +3 -0
  169. dw/server/ui/assets/shell-CC2rA5mh.js +1 -0
  170. dw/server/ui/assets/solidity-BEEn4gHE.js +1 -0
  171. dw/server/ui/assets/sophia-CRfGWb83.js +1 -0
  172. dw/server/ui/assets/sparql-D_Lu-MrJ.js +1 -0
  173. dw/server/ui/assets/sql-NEE52Syq.js +1 -0
  174. dw/server/ui/assets/st-DbInun42.js +1 -0
  175. dw/server/ui/assets/swift-Bxkupp3x.js +1 -0
  176. dw/server/ui/assets/systemverilog-Bz4Y3fRF.js +1 -0
  177. dw/server/ui/assets/tcl-DISqw1ZD.js +1 -0
  178. dw/server/ui/assets/ts.worker-D7T1-Ig5.js +67738 -0
  179. dw/server/ui/assets/tsMode-D6u0XmOW.js +11 -0
  180. dw/server/ui/assets/twig-De2hgUGE.js +1 -0
  181. dw/server/ui/assets/typescript-BU6v-LMV.js +1 -0
  182. dw/server/ui/assets/typespec-B8J7ngcE.js +1 -0
  183. dw/server/ui/assets/vb-DV3o63ZY.js +1 -0
  184. dw/server/ui/assets/wgsl-DpFanUEy.js +298 -0
  185. dw/server/ui/assets/workers-Cn7cTUKr.js +1 -0
  186. dw/server/ui/assets/xml--0LP2Lwk.js +1 -0
  187. dw/server/ui/assets/yaml-mpBg9jnt.js +1 -0
  188. dw/server/ui/index.html +17 -0
  189. dw/server/updater.py +192 -0
  190. dw/settings.py +98 -0
  191. dw/shot_span_preflight.py +116 -0
  192. dw/shots.py +359 -0
  193. dw/slice_preflight.py +148 -0
  194. dw/step.py +187 -0
  195. dw/step_cache.py +442 -0
  196. dw/subfolders.py +107 -0
  197. dw/task_domains.py +307 -0
  198. dw/tasks/assess.py +826 -0
  199. dw/tasks/audio_transcription.py +88 -0
  200. dw/tasks/audio_utils.py +1862 -0
  201. dw/tasks/background_remover.py +43 -0
  202. dw/tasks/borders.py +113 -0
  203. dw/tasks/compose_text.py +74 -0
  204. dw/tasks/concat_videos.py +300 -0
  205. dw/tasks/depth_estimator.py +54 -0
  206. dw/tasks/diffusion_upscale.py +109 -0
  207. dw/tasks/dissolve_videos.py +342 -0
  208. dw/tasks/format_messages.py +24 -0
  209. dw/tasks/gather.py +173 -0
  210. dw/tasks/grade.py +97 -0
  211. dw/tasks/image_to_text.py +43 -0
  212. dw/tasks/image_utils.py +764 -0
  213. dw/tasks/interpolate_frames.py +252 -0
  214. dw/tasks/judge.py +68 -0
  215. dw/tasks/model_cache.py +55 -0
  216. dw/tasks/pair_audio.py +268 -0
  217. dw/tasks/qr_code.py +19 -0
  218. dw/tasks/restore_faces.py +175 -0
  219. dw/tasks/rife_model.py +192 -0
  220. dw/tasks/segment.py +121 -0
  221. dw/tasks/select.py +111 -0
  222. dw/tasks/speech_generation.py +228 -0
  223. dw/tasks/stabilize.py +129 -0
  224. dw/tasks/task.py +920 -0
  225. dw/tasks/tensor_image.py +57 -0
  226. dw/tasks/text_generation.py +169 -0
  227. dw/tasks/text_sections.py +80 -0
  228. dw/tasks/upscale.py +203 -0
  229. dw/tasks/video_utils.py +624 -0
  230. dw/tasks/zoe_depth.py +71 -0
  231. dw/teacache.py +381 -0
  232. dw/teacache_models.json +99 -0
  233. dw/test.py +29 -0
  234. dw/type_helpers.py +231 -0
  235. dw/validate.py +68 -0
  236. dw/variable_constraints.py +444 -0
  237. dw/variables.py +443 -0
  238. dw/video_extensions.py +141 -0
  239. dw/vram_estimate.py +116 -0
  240. dw/worker.py +764 -0
  241. dw/workflow.py +2007 -0
  242. dw/workflow_schema.json +1346 -0
  243. dw/workflow_sources.py +383 -0
  244. dw/workflows/h3_context_ir.json +57 -0
  245. dw/workflows/test.json +31 -0
  246. dw/workspace.py +730 -0
  247. dw_mcp/__init__.py +6 -0
  248. dw_mcp/__main__.py +133 -0
  249. dw_mcp/assets.py +336 -0
  250. dw_mcp/authoring.py +114 -0
  251. dw_mcp/catalog.py +360 -0
  252. dw_mcp/client.py +486 -0
  253. dw_mcp/diagnose.py +371 -0
  254. dw_mcp/exports.py +84 -0
  255. dw_mcp/guides.py +35 -0
  256. dw_mcp/media.py +638 -0
  257. dw_mcp/models.py +97 -0
  258. dw_mcp/prompts.py +104 -0
  259. dw_mcp/server.py +1343 -0
  260. dw_mcp/workspaces.py +212 -0
@@ -0,0 +1,208 @@
1
+ """An 'attn_processor_type' backed by a Hub kernel that this box cannot run.
2
+
3
+ `LTX2VideoVaeNeighborhoodNattenProcessor` (LTX-2.5's diffusion decoder)
4
+ fetches its `na3d` kernel from `shi-labs/natten` through the `kernels`
5
+ package in `__init__` - no forward pass, no `__call__`, just construction.
6
+ When the installed torch is newer than every published natten build variant
7
+ (torch 2.14, natten's newest wheel built for 2.13), that `__init__` raises
8
+ `FileNotFoundError` - and by the time anything constructs the processor, the
9
+ pipeline has already loaded its transformer and text encoder onto the GPU.
10
+ `validate_workflow` reported this workflow clean and `run_workflow` paid
11
+ ~88s of loading to learn what construction alone would have said in under
12
+ two seconds (#178).
13
+
14
+ The processor class is resolved exactly as `dw/pipeline_processors/pipeline.py`
15
+ resolves it at run time - `load_type_from_name`, then a zero-argument
16
+ construction, since every 'attn_processor_type' site (the top-level
17
+ `unet`/`transformer` blocks and the generic per-component
18
+ `set_attn_processor`) constructs it that way. Not every attention processor
19
+ depends on a Hub kernel, so this only probes ones whose `__init__` calls
20
+ `kernels.get_kernel` - a source-level check rather than a natten-specific
21
+ name, so a future diffusers processor with the same Hub-fetch shape is
22
+ caught without a new entry here. A processor that constructs cleanly, or
23
+ whose source can't be inspected, is left alone: this check exists to move a
24
+ real, cheap, side-effect-free construction failure earlier, not to guess at
25
+ one.
26
+ """
27
+
28
+ import functools
29
+ import inspect
30
+
31
+ from .for_each import MEMBER_SEPARATOR, render_path
32
+ from .type_helpers import load_type_from_name
33
+
34
+ ATTN_PROCESSOR_KEY = "attn_processor_type"
35
+ _UNRESOLVED_PREFIXES = ("variable:", "item:")
36
+ KERNEL_FAULT_MARKER = "cannot be used on this machine"
37
+
38
+
39
+ def is_kernel_availability_fault(message):
40
+ """Whether a validation error's text is this check's, not the author's.
41
+
42
+ A template naming a Hub-kernel-backed processor is only ever as valid as
43
+ the box running the check - one box's torch build satisfies natten and
44
+ another's doesn't, so a failure here says nothing about the workflow
45
+ itself (dw/kernel_availability.py, #178). Callers that need to tell "this
46
+ box can't satisfy a real dependency" apart from "the workflow is wrong"
47
+ - such as tests/test_examples.py, which otherwise expects every shipped
48
+ template to validate on whatever machine runs the suite - match on this
49
+ rather than re-deriving the message.
50
+ """
51
+ return KERNEL_FAULT_MARKER in message
52
+
53
+
54
+ def _attn_processor_locations(configuration):
55
+ """Yield (path_suffix, value) for every 'attn_processor_type' string in
56
+ one step's pipeline configuration - the top-level 'unet'/'transformer'
57
+ blocks and any 'components' entry, matching every site
58
+ dw/pipeline_processors/pipeline.py constructs one from.
59
+ """
60
+ if not isinstance(configuration, dict):
61
+ return
62
+
63
+ for block_name in ("unet", "transformer"):
64
+ block = configuration.get(block_name)
65
+ if isinstance(block, dict) and ATTN_PROCESSOR_KEY in block:
66
+ yield (block_name, ATTN_PROCESSOR_KEY), block[ATTN_PROCESSOR_KEY]
67
+
68
+ components = configuration.get("components")
69
+ if isinstance(components, dict):
70
+ for component_name, component_configuration in components.items():
71
+ if (
72
+ isinstance(component_configuration, dict)
73
+ and ATTN_PROCESSOR_KEY in component_configuration
74
+ ):
75
+ yield (
76
+ ("components", component_name, ATTN_PROCESSOR_KEY),
77
+ component_configuration[ATTN_PROCESSOR_KEY],
78
+ )
79
+
80
+
81
+ def _requires_remote_kernel(attn_processor_class):
82
+ """Whether constructing this class fetches a kernel from the Hub -
83
+ a source-level check so a future processor with the same shape as
84
+ natten's is caught without naming it here.
85
+ """
86
+ try:
87
+ source = inspect.getsource(attn_processor_class.__init__)
88
+ except (OSError, TypeError):
89
+ return False
90
+ return "get_kernel(" in source
91
+
92
+
93
+ class _KernelFault(Exception):
94
+ """Carries a fault message out of `_fault_for_name` without letting
95
+ `lru_cache` memoize it - see that function's docstring."""
96
+
97
+
98
+ @functools.lru_cache(maxsize=None)
99
+ def _fault_for_name(value):
100
+ """The answer for one type name, memoized - except a fault.
101
+
102
+ Which class a name resolves to, and whether that class *requires* a
103
+ remote kernel, are per-process constants, so a clean `None` answer is
104
+ cached. Whether *this* construction attempt succeeds is not: the
105
+ construction is a Hub kernel fetch, which can fail transiently (network,
106
+ rate limit, cold cache), and caching that failure would pin every
107
+ validate/submit/rerun in the process to "broken" until the process
108
+ restarts, even once the transient condition clears. `lru_cache` never
109
+ memoizes a call that raises, so a fault is raised as `_KernelFault`
110
+ rather than returned - `kernel_availability_fault` catches it. The cost
111
+ of not caching a fault is one more fetch on the next call, which is
112
+ cheap next to being wrong for a process's whole lifetime.
113
+ """
114
+ try:
115
+ attn_processor_class = load_type_from_name(value)
116
+ except Exception:
117
+ return None
118
+
119
+ if not _requires_remote_kernel(attn_processor_class):
120
+ return None
121
+
122
+ try:
123
+ attn_processor_class()
124
+ except Exception as e:
125
+ raise _KernelFault(f"'{value}' {KERNEL_FAULT_MARKER}: {e}") from e
126
+ return None
127
+
128
+
129
+ def kernel_availability_fault(value):
130
+ """Why constructing this 'attn_processor_type' value will fail, or None.
131
+
132
+ `value` is the dotted or bare type name as written in the workflow.
133
+ A name that fails to resolve at all is not this check's job - that is
134
+ an ordinary '_type' load failure at run time. A processor that doesn't
135
+ depend on a remote kernel is never constructed here, since a processor
136
+ with real side effects in `__init__` should not be instantiated just to
137
+ validate it.
138
+
139
+ A clean answer is memoized once per process per name: validate, submit
140
+ and rerun all ask, and a for_each asks once per member (`_fault_for_name`).
141
+ A fault is not memoized, and so is re-probed on every call - see
142
+ `_fault_for_name`.
143
+ """
144
+ if not isinstance(value, str) or value.startswith(_UNRESOLVED_PREFIXES):
145
+ return None
146
+ try:
147
+ return _fault_for_name(value)
148
+ except _KernelFault as fault:
149
+ return str(fault)
150
+
151
+
152
+ def kernel_availability_errors(workflow_definition, source_indices=None):
153
+ """Every 'attn_processor_type' whose Hub kernel this machine can't
154
+ satisfy, as [{path, message}] - reported before any model loads rather
155
+ than discovered inside one (#178).
156
+
157
+ The definition handed here has already been substituted and expanded,
158
+ so every value in it is literal; a 'variable:' or 'item:' still spelled
159
+ out is left alone. `source_indices`, when given, is the source step
160
+ index of each step - a 'for_each' group turns one written step into
161
+ several, and the path an error carries has to be one the author can
162
+ find in the file they wrote; the member is named in the message.
163
+ """
164
+ steps = workflow_definition.get("steps")
165
+ if not isinstance(steps, list):
166
+ return []
167
+
168
+ errors = []
169
+ for index, step in enumerate(steps):
170
+ if not isinstance(step, dict):
171
+ continue
172
+ pipeline = step.get("pipeline")
173
+ if not isinstance(pipeline, dict):
174
+ continue
175
+ configuration = pipeline.get("configuration")
176
+
177
+ for path_suffix, value in _attn_processor_locations(configuration):
178
+ fault = kernel_availability_fault(value)
179
+ if fault is None:
180
+ continue
181
+
182
+ source = (
183
+ source_indices[index]
184
+ if source_indices is not None and index < len(source_indices)
185
+ else index
186
+ )
187
+ name = step.get("name")
188
+ where = (
189
+ f" in member '{name}'"
190
+ if isinstance(name, str) and MEMBER_SEPARATOR in name
191
+ else ""
192
+ )
193
+ errors.append(
194
+ {
195
+ "path": render_path(
196
+ ("steps", source, "pipeline", "configuration") + path_suffix
197
+ ),
198
+ "message": f"{fault}{where}",
199
+ }
200
+ )
201
+ return errors
202
+
203
+
204
+ __all__ = [
205
+ "is_kernel_availability_fault",
206
+ "kernel_availability_errors",
207
+ "kernel_availability_fault",
208
+ ]