loom-kernel 2.15.0__tar.gz → 2.16.0__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.
Files changed (684) hide show
  1. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/CHANGELOG.md +56 -0
  2. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/PKG-INFO +6 -6
  3. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/pyproject.toml +5 -5
  4. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_errors.py +17 -4
  5. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_limits.py +49 -23
  6. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/provider.py +11 -15
  7. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/__init__.py +2 -0
  8. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_write_policy.py +31 -5
  9. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/__init__.py +2 -1
  10. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_reader.py +60 -19
  11. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_writer.py +4 -0
  12. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/_writer.py +4 -0
  13. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/compiler/__init__.py +9 -0
  14. loom_kernel-2.15.0/src/loom/etl/runner/filtering.py → loom_kernel-2.16.0/src/loom/etl/compiler/_filter.py +55 -12
  15. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/compiler/_plan.py +24 -1
  16. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/__init__.py +3 -0
  17. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/_from.py +10 -0
  18. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/__init__.py +7 -0
  19. loom_kernel-2.16.0/src/loom/etl/declarative/target/_errors.py +30 -0
  20. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_into.py +24 -6
  21. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_table.py +4 -0
  22. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/runner/core.py +2 -3
  23. loom_kernel-2.16.0/src/loom/etl/runner/errors.py +7 -0
  24. loom_kernel-2.16.0/src/loom/etl/runner/filtering.py +38 -0
  25. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/__init__.py +4 -0
  26. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/deploy/_yaml_etls.py +1 -1
  27. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/__init__.py +8 -0
  28. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_assemble.py +10 -2
  29. loom_kernel-2.15.0/src/loom/etl/runner/errors.py +0 -17
  30. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/.gitignore +0 -0
  31. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/LICENSE +0 -0
  32. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/README.md +0 -0
  33. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/__init__.py +0 -0
  34. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/__init__.py +0 -0
  35. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/_concurrency.py +0 -0
  36. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/_filters.py +0 -0
  37. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/_paths.py +0 -0
  38. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/_roles.py +0 -0
  39. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/_startup.py +0 -0
  40. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/_transport.py +0 -0
  41. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/_usecase.py +0 -0
  42. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/a2a/__init__.py +0 -0
  43. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/a2a/_binding.py +0 -0
  44. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/a2a/_handlers.py +0 -0
  45. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/a2a/_rpc.py +0 -0
  46. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/a2a/card.py +0 -0
  47. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/a2a/events.py +0 -0
  48. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/a2a/server.py +0 -0
  49. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/abc.py +0 -0
  50. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/bootstrap.py +0 -0
  51. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/__init__.py +0 -0
  52. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/_compiler.py +0 -0
  53. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/_fingerprint.py +0 -0
  54. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/_plan.py +0 -0
  55. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/__init__.py +0 -0
  56. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_capabilities.py +0 -0
  57. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_conversation.py +0 -0
  58. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_feedable.py +0 -0
  59. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_hook.py +0 -0
  60. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_instructions.py +0 -0
  61. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_limits.py +0 -0
  62. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_model_role.py +0 -0
  63. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_output.py +0 -0
  64. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_state.py +0 -0
  65. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/config.py +0 -0
  66. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/declarative/__init__.py +0 -0
  67. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/declarative/_envelope.py +0 -0
  68. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/declarative/_schema.py +0 -0
  69. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/declarative/_v1.py +0 -0
  70. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/declarative/schemas/agent-spec-v1.schema.json +0 -0
  71. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/describe.py +0 -0
  72. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/__init__.py +0 -0
  73. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/__init__.py +0 -0
  74. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_a2a.py +0 -0
  75. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_capabilities.py +0 -0
  76. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_engine.py +0 -0
  77. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_escape.py +0 -0
  78. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_events.py +0 -0
  79. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_guards.py +0 -0
  80. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_history.py +0 -0
  81. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_instructions.py +0 -0
  82. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_mcp.py +0 -0
  83. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_models.py +0 -0
  84. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_native.py +0 -0
  85. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_output.py +0 -0
  86. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_returns.py +0 -0
  87. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_schemas.py +0 -0
  88. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_spec.py +0 -0
  89. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/extras/__init__.py +0 -0
  90. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/extras/a2a.py +0 -0
  91. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/extras/handlebars.py +0 -0
  92. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/extras/mcp.py +0 -0
  93. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/extras/skills.py +0 -0
  94. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/__init__.py +0 -0
  95. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/_shared.py +0 -0
  96. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/anthropic.py +0 -0
  97. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/bedrock.py +0 -0
  98. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/gateway.py +0 -0
  99. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/openai.py +0 -0
  100. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/typesafe.py +0 -0
  101. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/errors.py +0 -0
  102. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/etl/__init__.py +0 -0
  103. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/etl/_batch.py +0 -0
  104. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/etl/_columns.py +0 -0
  105. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/etl/_frames.py +0 -0
  106. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/etl/_ledger.py +0 -0
  107. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/etl/_runner.py +0 -0
  108. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/etl/_validation.py +0 -0
  109. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/fastapi/__init__.py +0 -0
  110. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/fastapi/endpoints.py +0 -0
  111. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/fastapi/response.py +0 -0
  112. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/fastapi/streaming.py +0 -0
  113. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/inference.py +0 -0
  114. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/pricing.py +0 -0
  115. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/registry.py +0 -0
  116. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/remote_auth.py +0 -0
  117. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/runtime/__init__.py +0 -0
  118. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/runtime/_bounded.py +0 -0
  119. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/runtime/_chain.py +0 -0
  120. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/runtime/_conversation.py +0 -0
  121. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/runtime/_grants.py +0 -0
  122. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/runtime/_handle.py +0 -0
  123. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/runtime/_health.py +0 -0
  124. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/runtime/_hooks.py +0 -0
  125. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/runtime/_lifecycle.py +0 -0
  126. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/runtime/_limits.py +0 -0
  127. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/runtime/_mcp.py +0 -0
  128. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/validate/__init__.py +0 -0
  129. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/ai/validate/__main__.py +0 -0
  130. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/celery/__init__.py +0 -0
  131. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/celery/auto.py +0 -0
  132. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/celery/bootstrap.py +0 -0
  133. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/celery/config.py +0 -0
  134. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/celery/constants.py +0 -0
  135. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/celery/runner.py +0 -0
  136. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/celery/service.py +0 -0
  137. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/cli/__init__.py +0 -0
  138. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/cli/app.py +0 -0
  139. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/cli/schema.py +0 -0
  140. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/async_bridge.py +0 -0
  141. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/authz/__init__.py +0 -0
  142. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/authz/_decide.py +0 -0
  143. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/authz/_grants.py +0 -0
  144. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/authz/_roles.py +0 -0
  145. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/authz/_scope.py +0 -0
  146. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/authz/elevation.py +0 -0
  147. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/authz/product.py +0 -0
  148. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/backend/__init__.py +0 -0
  149. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/backend/core_model.py +0 -0
  150. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/backend/protocol.py +0 -0
  151. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/backend/scoped_ddl.py +0 -0
  152. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/backend/sqlalchemy.py +0 -0
  153. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/bootstrap/__init__.py +0 -0
  154. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
  155. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/bootstrap/kernel.py +0 -0
  156. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/__init__.py +0 -0
  157. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/_batching.py +0 -0
  158. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/_single_flight.py +0 -0
  159. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/abc/__init__.py +0 -0
  160. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/abc/backend.py +0 -0
  161. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/abc/config.py +0 -0
  162. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/abc/dependency.py +0 -0
  163. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/calls.py +0 -0
  164. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/codec.py +0 -0
  165. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/decorators.py +0 -0
  166. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/dependency.py +0 -0
  167. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/errors.py +0 -0
  168. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/gateway.py +0 -0
  169. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/keys.py +0 -0
  170. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/memory.py +0 -0
  171. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/repository.py +0 -0
  172. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/result_codec.py +0 -0
  173. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/serializer.py +0 -0
  174. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/cache/wiring.py +0 -0
  175. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/command/__init__.py +0 -0
  176. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/command/adapter.py +0 -0
  177. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/command/base.py +0 -0
  178. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/command/field.py +0 -0
  179. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/command/introspection.py +0 -0
  180. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/compiler.py +0 -0
  181. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/__init__.py +0 -0
  182. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/_boto3.py +0 -0
  183. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/_includes.py +0 -0
  184. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/_resolver_utils.py +0 -0
  185. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/binder.py +0 -0
  186. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/configurable.py +0 -0
  187. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/context.py +0 -0
  188. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/errors.py +0 -0
  189. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/keys.py +0 -0
  190. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/loader.py +0 -0
  191. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/model.py +0 -0
  192. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/observability.py +0 -0
  193. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/resolver.py +0 -0
  194. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/secrets.py +0 -0
  195. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/config/ssm.py +0 -0
  196. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/contracts/__init__.py +0 -0
  197. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/contracts/manifest.py +0 -0
  198. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/di/__init__.py +0 -0
  199. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/di/container.py +0 -0
  200. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/di/scope.py +0 -0
  201. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/discovery/__init__.py +0 -0
  202. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/discovery/_utils.py +0 -0
  203. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/discovery/base.py +0 -0
  204. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/discovery/interfaces.py +0 -0
  205. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/discovery/manifest.py +0 -0
  206. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/discovery/modules.py +0 -0
  207. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/engine/__init__.py +0 -0
  208. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/engine/compilable.py +0 -0
  209. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/engine/compiler.py +0 -0
  210. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/engine/events.py +0 -0
  211. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/engine/executor.py +0 -0
  212. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/engine/metrics.py +0 -0
  213. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/engine/plan.py +0 -0
  214. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/engine/post_commit.py +0 -0
  215. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/errors/__init__.py +0 -0
  216. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/errors/codes.py +0 -0
  217. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/errors/errors.py +0 -0
  218. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/expr/__init__.py +0 -0
  219. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/expr/eval.py +0 -0
  220. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/expr/nodes.py +0 -0
  221. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/expr/refs.py +0 -0
  222. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/identity/__init__.py +0 -0
  223. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/identity/context.py +0 -0
  224. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/identity/identity.py +0 -0
  225. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/identity/issuer.py +0 -0
  226. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/identity/wire.py +0 -0
  227. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/introspection/__init__.py +0 -0
  228. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/introspection/base.py +0 -0
  229. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/introspection/describe.py +0 -0
  230. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/job/__init__.py +0 -0
  231. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/job/callback.py +0 -0
  232. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/job/context.py +0 -0
  233. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/job/handle.py +0 -0
  234. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/job/job.py +0 -0
  235. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/job/service.py +0 -0
  236. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/locator.py +0 -0
  237. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/logger/__init__.py +0 -0
  238. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/logger/abc.py +0 -0
  239. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/logger/config.py +0 -0
  240. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/logger/registry.py +0 -0
  241. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/logger/structlogger.py +0 -0
  242. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/__init__.py +0 -0
  243. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/_loom_type.py +0 -0
  244. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/base.py +0 -0
  245. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/convert.py +0 -0
  246. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/enums.py +0 -0
  247. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/field.py +0 -0
  248. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/introspection.py +0 -0
  249. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/partition.py +0 -0
  250. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/privilege.py +0 -0
  251. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/projection.py +0 -0
  252. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/relation.py +0 -0
  253. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/scoped.py +0 -0
  254. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/struct.py +0 -0
  255. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/timestamped.py +0 -0
  256. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/types.py +0 -0
  257. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/model/types_postgres.py +0 -0
  258. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/observability/__init__.py +0 -0
  259. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/observability/config.py +0 -0
  260. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/observability/event.py +0 -0
  261. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/observability/observer/__init__.py +0 -0
  262. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/observability/observer/noop.py +0 -0
  263. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/observability/observer/otel.py +0 -0
  264. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/observability/observer/structlog.py +0 -0
  265. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/observability/otel_ids.py +0 -0
  266. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/observability/protocol.py +0 -0
  267. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/observability/runtime.py +0 -0
  268. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/observability/span.py +0 -0
  269. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/observability/topology.py +0 -0
  270. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/persistence/__init__.py +0 -0
  271. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/persistence/abc.py +0 -0
  272. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/persistence/none.py +0 -0
  273. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/persistence/registry.py +0 -0
  274. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/plugins/__init__.py +0 -0
  275. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/plugins/entrypoints.py +0 -0
  276. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/plugins/optional.py +0 -0
  277. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/projection/__init__.py +0 -0
  278. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/projection/loaders.py +0 -0
  279. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/projection/runtime.py +0 -0
  280. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/__init__.py +0 -0
  281. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/abc/__init__.py +0 -0
  282. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/abc/cursor.py +0 -0
  283. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/abc/errors.py +0 -0
  284. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/abc/query.py +0 -0
  285. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/abc/query_compiler.py +0 -0
  286. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/abc/repo_for.py +0 -0
  287. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/abc/repository.py +0 -0
  288. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/abc/session_scope.py +0 -0
  289. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/dynamodb/__init__.py +0 -0
  290. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/dynamodb/backend.py +0 -0
  291. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/dynamodb/registry.py +0 -0
  292. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/dynamodb/repository.py +0 -0
  293. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/dynamodb/uow.py +0 -0
  294. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/__init__.py +0 -0
  295. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/backend.py +0 -0
  296. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/ids.py +0 -0
  297. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/query_compiler.py +0 -0
  298. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/registry.py +0 -0
  299. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/repository.py +0 -0
  300. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/uow.py +0 -0
  301. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/values.py +0 -0
  302. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/mutation.py +0 -0
  303. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/registration.py +0 -0
  304. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/registry.py +0 -0
  305. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
  306. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/backend.py +0 -0
  307. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
  308. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
  309. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/migrations/__init__.py +0 -0
  310. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/migrations/env_template.py +0 -0
  311. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/migrations/hook.py +0 -0
  312. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/migrations/operations.py +0 -0
  313. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/migrations/runners.py +0 -0
  314. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
  315. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
  316. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
  317. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
  318. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
  319. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
  320. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
  321. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
  322. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
  323. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
  324. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
  325. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
  326. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
  327. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
  328. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/__init__.py +0 -0
  329. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/bootstrap.py +0 -0
  330. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/config.py +0 -0
  331. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/elevate.py +0 -0
  332. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/guard/0001.sql +0 -0
  333. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/guard/0002.sql +0 -0
  334. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/guard/preflight.sql +0 -0
  335. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/guard_manifest.py +0 -0
  336. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/integrity.py +0 -0
  337. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/partitions.py +0 -0
  338. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/provider.py +0 -0
  339. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/schema.py +0 -0
  340. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/sources.py +0 -0
  341. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/verify.py +0 -0
  342. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
  343. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/session_settings.py +0 -0
  344. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
  345. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
  346. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/response/__init__.py +0 -0
  347. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/response/base.py +0 -0
  348. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/routing/__init__.py +0 -0
  349. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/routing/ref.py +0 -0
  350. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/routing/resolver.py +0 -0
  351. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/runner.py +0 -0
  352. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/schema/__init__.py +0 -0
  353. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/schema/schema_mode.py +0 -0
  354. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/schema_names.py +0 -0
  355. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/sql/__init__.py +0 -0
  356. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/sql/abc/__init__.py +0 -0
  357. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/sql/abc/contracts.py +0 -0
  358. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/sql/abc/errors.py +0 -0
  359. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/sql/caller_bound.py +0 -0
  360. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/sql/clickhouse/__init__.py +0 -0
  361. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/sql/clickhouse/_client.py +0 -0
  362. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/sql/clickhouse/executor.py +0 -0
  363. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/sql/clickhouse/registry.py +0 -0
  364. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/sql/config.py +0 -0
  365. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/sql/roles.py +0 -0
  366. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/sql/service.py +0 -0
  367. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/symbols.py +0 -0
  368. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/tracing/__init__.py +0 -0
  369. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/tracing/context.py +0 -0
  370. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/transaction.py +0 -0
  371. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/transport/__init__.py +0 -0
  372. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/transport/adapter.py +0 -0
  373. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/uow/__init__.py +0 -0
  374. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/uow/abc.py +0 -0
  375. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/uow/context.py +0 -0
  376. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/__init__.py +0 -0
  377. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/_predicates.py +0 -0
  378. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/agent_markers.py +0 -0
  379. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/compute.py +0 -0
  380. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/constants.py +0 -0
  381. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/factory.py +0 -0
  382. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/field_ref.py +0 -0
  383. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/invoker.py +0 -0
  384. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/keys.py +0 -0
  385. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/markers.py +0 -0
  386. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/mcp_markers.py +0 -0
  387. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/registry.py +0 -0
  388. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/rule.py +0 -0
  389. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/core/use_case/use_case.py +0 -0
  390. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/__init__.py +0 -0
  391. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_format_registry.py +0 -0
  392. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
  393. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_historify/_common.py +0 -0
  394. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_historify/_log.py +0 -0
  395. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
  396. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
  397. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
  398. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_merge.py +0 -0
  399. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_path_template.py +0 -0
  400. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_predicate.py +0 -0
  401. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
  402. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
  403. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
  404. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
  405. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
  406. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_historify.py +0 -0
  407. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
  408. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_schema.py +0 -0
  409. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
  410. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_streaming.py +0 -0
  411. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/provider.py +0 -0
  412. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/__init__.py +0 -0
  413. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
  414. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/_historify.py +0 -0
  415. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/_reader.py +0 -0
  416. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/_schema.py +0 -0
  417. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
  418. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/provider.py +0 -0
  419. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/__init__.py +0 -0
  420. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
  421. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
  422. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
  423. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_options.py +0 -0
  424. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_paths.py +0 -0
  425. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_scope.py +0 -0
  426. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_store.py +0 -0
  427. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/compiler/_binding.py +0 -0
  428. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/compiler/_compiler.py +0 -0
  429. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/compiler/_errors.py +0 -0
  430. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/compiler/_validators.py +0 -0
  431. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/compiler/_validators_agents.py +0 -0
  432. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/compiler/_validators_config.py +0 -0
  433. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
  434. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/compiler/_validators_step.py +0 -0
  435. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/_format.py +0 -0
  436. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/_read_options.py +0 -0
  437. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/_utils.py +0 -0
  438. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/_with_agent.py +0 -0
  439. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/_write_options.py +0 -0
  440. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
  441. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/expr/_params.py +0 -0
  442. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
  443. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
  444. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
  445. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/__init__.py +0 -0
  446. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
  447. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/_from_config.py +0 -0
  448. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
  449. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
  450. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/_specs.py +0 -0
  451. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_client.py +0 -0
  452. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_file.py +0 -0
  453. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
  454. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
  455. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
  456. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
  457. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
  458. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
  459. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
  460. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_temp.py +0 -0
  461. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/executor/__init__.py +0 -0
  462. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/executor/_agents.py +0 -0
  463. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/executor/_dispatcher.py +0 -0
  464. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/executor/_executor.py +0 -0
  465. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/__init__.py +0 -0
  466. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/_registry.py +0 -0
  467. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/sources/__init__.py +0 -0
  468. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_clickhouse.py +0 -0
  469. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_dynamodb.py +0 -0
  470. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
  471. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
  472. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_mongo.py +0 -0
  473. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
  474. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
  475. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
  476. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_serialization.py +0 -0
  477. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/targets/__init__.py +0 -0
  478. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/io/targets/_clickhouse.py +0 -0
  479. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/lineage/__init__.py +0 -0
  480. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/lineage/_config.py +0 -0
  481. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/lineage/_observer.py +0 -0
  482. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/lineage/_records.py +0 -0
  483. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
  484. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
  485. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
  486. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
  487. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/maintenance/__init__.py +0 -0
  488. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/maintenance/_builder.py +0 -0
  489. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/maintenance/_ops.py +0 -0
  490. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/maintenance/_protocol.py +0 -0
  491. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/maintenance/_runner.py +0 -0
  492. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/maintenance/_step.py +0 -0
  493. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/maintenance/backends/__init__.py +0 -0
  494. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
  495. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/pipeline/__init__.py +0 -0
  496. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_generics.py +0 -0
  497. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_params.py +0 -0
  498. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
  499. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_process.py +0 -0
  500. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_sql.py +0 -0
  501. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_step.py +0 -0
  502. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_step_client.py +0 -0
  503. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
  504. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/runner/__init__.py +0 -0
  505. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/runner/_agents.py +0 -0
  506. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/runner/_providers.py +0 -0
  507. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/runner/_wiring.py +0 -0
  508. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/runner/config_loader.py +0 -0
  509. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/runtime/__init__.py +0 -0
  510. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/runtime/_config_values.py +0 -0
  511. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/runtime/contracts.py +0 -0
  512. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/schema/__init__.py +0 -0
  513. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/schema/_contract.py +0 -0
  514. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/schema/_schema.py +0 -0
  515. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/storage/__init__.py +0 -0
  516. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/storage/_config.py +0 -0
  517. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/storage/_file_locator.py +0 -0
  518. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/storage/_locator.py +0 -0
  519. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/storage/routing.py +0 -0
  520. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/testing/__init__.py +0 -0
  521. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/testing/_result.py +0 -0
  522. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/testing/_runners.py +0 -0
  523. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/testing/_scenario.py +0 -0
  524. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/testing/_stubs.py +0 -0
  525. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/etl/testing/spark.py +0 -0
  526. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/_async.py +0 -0
  527. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/_config.py +0 -0
  528. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/_ctx.py +0 -0
  529. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/_flow_yaml.py +0 -0
  530. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/_meta.py +0 -0
  531. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/_placeholders.py +0 -0
  532. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/_summary.py +0 -0
  533. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/deploy/__init__.py +0 -0
  534. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/deploy/_discovery.py +0 -0
  535. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/deploy/_schedule.py +0 -0
  536. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/deploy/entrypoint.py +0 -0
  537. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_backfill.py +0 -0
  538. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_backfill_body.py +0 -0
  539. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_body.py +0 -0
  540. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_common.py +0 -0
  541. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_factory.py +0 -0
  542. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_hooks.py +0 -0
  543. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_maintenance.py +0 -0
  544. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_params.py +0 -0
  545. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_run_name.py +0 -0
  546. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_runtime.py +0 -0
  547. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_signature.py +0 -0
  548. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/flow/_stages.py +0 -0
  549. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/manifest/__init__.py +0 -0
  550. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/manifest/_model.py +0 -0
  551. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/manifest/_s3.py +0 -0
  552. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/manifest/_store.py +0 -0
  553. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/notify/__init__.py +0 -0
  554. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/notify/_event.py +0 -0
  555. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/notify/_factory.py +0 -0
  556. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/notify/_port.py +0 -0
  557. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/notify/_slack.py +0 -0
  558. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/observer/__init__.py +0 -0
  559. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/observer/_flow.py +0 -0
  560. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/observer/_logging_bridge.py +0 -0
  561. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/observer/_manifest.py +0 -0
  562. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prefect/observer/_task_run.py +0 -0
  563. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prometheus/__init__.py +0 -0
  564. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prometheus/_instruments.py +0 -0
  565. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prometheus/adapter.py +0 -0
  566. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prometheus/kafka.py +0 -0
  567. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prometheus/lifecycle.py +0 -0
  568. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/prometheus/middleware.py +0 -0
  569. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/py.typed +0 -0
  570. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/__init__.py +0 -0
  571. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/_body.py +0 -0
  572. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/adapter.py +0 -0
  573. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/auth/__init__.py +0 -0
  574. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/auth/abc.py +0 -0
  575. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/auth/config.py +0 -0
  576. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/auth/jwt.py +0 -0
  577. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/auth/middleware.py +0 -0
  578. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/autocrud.py +0 -0
  579. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/compiler.py +0 -0
  580. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/config.py +0 -0
  581. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/constants.py +0 -0
  582. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/cors.py +0 -0
  583. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/errors.py +0 -0
  584. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/fastapi/__init__.py +0 -0
  585. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/fastapi/_errors.py +0 -0
  586. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/fastapi/_exclusions.py +0 -0
  587. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/fastapi/app.py +0 -0
  588. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/fastapi/auto.py +0 -0
  589. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/fastapi/health.py +0 -0
  590. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/fastapi/openapi.py +0 -0
  591. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/fastapi/response.py +0 -0
  592. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
  593. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/fastapi/sql.py +0 -0
  594. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/middleware.py +0 -0
  595. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/model.py +0 -0
  596. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/rest/rest_adapter.py +0 -0
  597. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/__init__.py +0 -0
  598. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/__init__.py +0 -0
  599. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_adapter.py +0 -0
  600. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_batch_spans.py +0 -0
  601. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
  602. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
  603. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
  604. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_errors.py +0 -0
  605. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_operators.py +0 -0
  606. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
  607. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
  608. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
  609. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
  610. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
  611. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
  612. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
  613. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
  614. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
  615. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
  616. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
  617. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
  618. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/runner.py +0 -0
  619. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/compiler/__init__.py +0 -0
  620. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/compiler/_bindings.py +0 -0
  621. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/compiler/_compiler.py +0 -0
  622. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/compiler/_errors.py +0 -0
  623. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/compiler/_plan.py +0 -0
  624. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/compiler/phases/build_plan.py +0 -0
  625. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/compiler/phases/validate.py +0 -0
  626. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/core/__init__.py +0 -0
  627. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/core/_errors.py +0 -0
  628. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/core/_exceptions.py +0 -0
  629. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/core/_message.py +0 -0
  630. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/core/_tracing.py +0 -0
  631. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/core/_typing.py +0 -0
  632. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/graph/__init__.py +0 -0
  633. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/graph/_flow.py +0 -0
  634. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/__init__.py +0 -0
  635. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_codec.py +0 -0
  636. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_config.py +0 -0
  637. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_errors.py +0 -0
  638. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
  639. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_message.py +0 -0
  640. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_record.py +0 -0
  641. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_wire.py +0 -0
  642. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
  643. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
  644. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
  645. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
  646. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/client/_retry.py +0 -0
  647. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
  648. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
  649. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
  650. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
  651. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/mongo/__init__.py +0 -0
  652. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
  653. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/mongo/_config.py +0 -0
  654. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/mongo/_event.py +0 -0
  655. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/mongo/_normalize.py +0 -0
  656. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/__init__.py +0 -0
  657. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_boundary.py +0 -0
  658. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_branches.py +0 -0
  659. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
  660. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
  661. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_decompose.py +0 -0
  662. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_expand_routes.py +0 -0
  663. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
  664. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_fork.py +0 -0
  665. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_helpers.py +0 -0
  666. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_mongo.py +0 -0
  667. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_protocols.py +0 -0
  668. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_router.py +0 -0
  669. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_shape.py +0 -0
  670. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_sink.py +0 -0
  671. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_step.py +0 -0
  672. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_table/__init__.py +0 -0
  673. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_table/common.py +0 -0
  674. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_table/config.py +0 -0
  675. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_with.py +0 -0
  676. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/nodes/refs.py +0 -0
  677. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/streaming/testing.py +0 -0
  678. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/testing/__init__.py +0 -0
  679. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/testing/agents.py +0 -0
  680. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/testing/golden.py +0 -0
  681. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/testing/http_harness.py +0 -0
  682. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/testing/in_memory.py +0 -0
  683. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/testing/repository_harness.py +0 -0
  684. {loom_kernel-2.15.0 → loom_kernel-2.16.0}/src/loom/testing/runner.py +0 -0
@@ -225,6 +225,11 @@
225
225
  downstream run inherits the placeholder text and resolves it against its own
226
226
  creation time. Without `trigger` the deployment is registered exactly as
227
227
  before.
228
+ - **prefect:** `FlowTrigger`, the decoded `trigger` block, is exported from
229
+ `loom.prefect` and `loom.prefect.flow`, and `check_inherited_params(trigger,
230
+ params_type, *, name)` from `loom.prefect.flow`, so CI can check that every
231
+ inherited parameter is a field declared `str`, `date` or `datetime` without
232
+ building the flow.
228
233
 
229
234
  ### etl
230
235
 
@@ -278,6 +283,36 @@
278
283
  `MISSING_CONFIG_PARAMS`, `CONFIG_ALIAS_CONFLICT` and
279
284
  `UNSUPPORTED_CONFIG_VALUE`. `ETLRunner`, `ETLRunner.from_config`,
280
285
  `ETLCompiler` and `ETLExecutor` take `agents=`. Polars only.
286
+ - **etl:** `loom.etl.compiler.filter_plan(plan, include)` returns the plan
287
+ `ETLRunner.run(..., include=...)` executes: a process name keeps the whole
288
+ process, a step name keeps that step, and a name that is neither raises
289
+ `InvalidStageError`, listing the unknown names sorted, so a deployment's
290
+ selection can be checked without running it. A bare string as `include`
291
+ raises `TypeError`. The runner now filters through it. `InvalidStageError`
292
+ is exported from `loom.etl.compiler` as well; it is the same class as
293
+ `loom.etl.runner.InvalidStageError` and `loom.etl.InvalidStageError`.
294
+ - **etl:** `iter_processes`, `iter_steps_in_process` and `iter_all_steps` are
295
+ exported from `loom.etl.compiler`. They flatten a compiled plan in
296
+ execution order, parallel groups in declaration order, so code that walks
297
+ a plan no longer reimplements them over the private `_plan` module.
298
+ - **etl:** `loom.etl.backends.polars.decode_json_columns(frame, json_columns)`
299
+ decodes JSON text columns exactly as the Polars reader does for a source
300
+ declared with `parse_json`, normalising fields whose JSON type changes
301
+ between rows, and returns a frame of the same kind, eager or lazy. The
302
+ reader decodes through it. `FromTable.json_columns` and
303
+ `FromFile.json_columns` expose the declarations it takes, so a test can
304
+ decode a seed as the step would receive it. Spark keeps its `from_json`
305
+ decoding, which has no normalisation to share.
306
+ - **etl:** `IntoTable(...).replace(allow_empty=False)` refuses to wipe a table
307
+ with an empty frame: the writer raises `EmptyReplaceError` (a `ValueError`,
308
+ exported from `loom.etl`, carrying `table_ref`) before it creates or writes
309
+ anything, so a dimension rebuilt from a read that came back empty keeps its
310
+ rows and the step fails. Polars checks the row count of the frame the
311
+ replace already collects, at no extra cost; Spark runs `isEmpty()`, one
312
+ job that stops at the first row, before the write recomputes the frame. On
313
+ Polars a `Null`-typed column still fails first, with `SchemaError`.
314
+ The default, `allow_empty=True`, keeps today's behaviour, and `ReplaceSpec`
315
+ gains the `allow_empty` field.
281
316
 
282
317
  ## ⚠ Behaviour changes
283
318
 
@@ -368,6 +403,14 @@
368
403
  which is harmless. The update is one attempt with a 10-second timeout; if
369
404
  it fails, the flow logs it at `ERROR` in the run's logs and goes on.
370
405
 
406
+ ### etl
407
+
408
+ - **etl:** the names of `loom.etl.runner.filtering` (`_filter_plan`,
409
+ `_filter_process`, `_collect_all_names`, `_map_pipeline_nodes`,
410
+ `_map_process_nodes`) are deprecated and removed in loom 3.0; each emits a
411
+ `DeprecationWarning` naming its replacement, `loom.etl.compiler.filter_plan`
412
+ or, for `_collect_all_names`, `iter_processes` and `iter_all_steps`.
413
+
371
414
  ## 🐛 Fixes
372
415
 
373
416
  ### core
@@ -430,6 +473,19 @@
430
473
 
431
474
  ### ai
432
475
 
476
+ - **ai:** a configured `ai.prices` rate prices runs again with pydantic-ai
477
+ 2.54. That release records a response's usage before the
478
+ `after_model_request` hook loom priced it in, so every run reported
479
+ `AgentUsage.cost=None`: `policies.max_usd` stopped binding, a reported cost
480
+ was summed instead of replaced, and the ETL budget ledger kept each run's
481
+ whole reservation. The price is now applied by a model wrapper as the model
482
+ returns each response, in both run modes, before any engine release records
483
+ it. The lock moves to pydantic-ai-slim 2.54.0, which sends `tool_choice:
484
+ auto` for a `tool` output with adaptive thinking, so Anthropic models reason
485
+ again (2.47 forced the tool). `UsageExtractionFailedWarning`, new in 2.52, is
486
+ classified `COST_NOT_MEASURABLE` like its siblings. Every `ai-*` extra now
487
+ declares `pydantic-ai-slim>=2.45`, the oldest release loom imports and passes
488
+ its agent suites with, and CI runs those suites against that floor.
433
489
  - **ai:** an MCP session that dies after it opened no longer fails every later
434
490
  call until the worker restarts. The worker holds one session per server for
435
491
  its whole life, and that holder kept the dead client from ever being
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: loom-kernel
3
- Version: 2.15.0
3
+ Version: 2.16.0
4
4
  Summary: Loom Python project
5
5
  License-File: LICENSE
6
6
  Classifier: Programming Language :: Python :: 3
@@ -22,17 +22,17 @@ Provides-Extra: ai-a2a
22
22
  Requires-Dist: a2a-sdk<2,>=1.1; extra == 'ai-a2a'
23
23
  Requires-Dist: fasta2a<1,>=0.6; extra == 'ai-a2a'
24
24
  Provides-Extra: ai-anthropic
25
- Requires-Dist: pydantic-ai-slim[anthropic]<3,>=2; extra == 'ai-anthropic'
25
+ Requires-Dist: pydantic-ai-slim[anthropic]<3,>=2.45; extra == 'ai-anthropic'
26
26
  Provides-Extra: ai-bedrock
27
- Requires-Dist: pydantic-ai-slim[bedrock]<3,>=2; extra == 'ai-bedrock'
27
+ Requires-Dist: pydantic-ai-slim[bedrock]<3,>=2.45; extra == 'ai-bedrock'
28
28
  Provides-Extra: ai-harness
29
29
  Requires-Dist: pydantic-ai-harness[skills]<1,>=0.28; extra == 'ai-harness'
30
30
  Provides-Extra: ai-openai
31
- Requires-Dist: pydantic-ai-slim[openai]<3,>=2; extra == 'ai-openai'
31
+ Requires-Dist: pydantic-ai-slim[openai]<3,>=2.45; extra == 'ai-openai'
32
32
  Provides-Extra: ai-pydantic
33
- Requires-Dist: pydantic-ai-slim<3,>=2; extra == 'ai-pydantic'
33
+ Requires-Dist: pydantic-ai-slim<3,>=2.45; extra == 'ai-pydantic'
34
34
  Provides-Extra: ai-templates
35
- Requires-Dist: pydantic-ai-slim[spec]<3,>=2; extra == 'ai-templates'
35
+ Requires-Dist: pydantic-ai-slim[spec]<3,>=2.45; extra == 'ai-templates'
36
36
  Provides-Extra: ai-typesafe
37
37
  Requires-Dist: pydantic-ai-slim[typesafe]<3,>=2.45; extra == 'ai-typesafe'
38
38
  Provides-Extra: cache
@@ -124,16 +124,16 @@ streaming = [
124
124
  "opentelemetry-exporter-otlp-proto-grpc>=1.27,<2.0",
125
125
  ]
126
126
  ai-pydantic = [
127
- "pydantic-ai-slim>=2,<3",
127
+ "pydantic-ai-slim>=2.45,<3",
128
128
  ]
129
129
  ai-bedrock = [
130
- "pydantic-ai-slim[bedrock]>=2,<3",
130
+ "pydantic-ai-slim[bedrock]>=2.45,<3",
131
131
  ]
132
132
  ai-openai = [
133
- "pydantic-ai-slim[openai]>=2,<3",
133
+ "pydantic-ai-slim[openai]>=2.45,<3",
134
134
  ]
135
135
  ai-anthropic = [
136
- "pydantic-ai-slim[anthropic]>=2,<3",
136
+ "pydantic-ai-slim[anthropic]>=2.45,<3",
137
137
  ]
138
138
  # TypeSafe's Jev: a decision model that fills a typed output from a state, no
139
139
  # text. Its model class first shipped in pydantic-ai 2.45.
@@ -144,7 +144,7 @@ ai-typesafe = [
144
144
  # the engine compiles a Handlebars template and renders it per request. An
145
145
  # artefact whose instructions are literal never reaches the import.
146
146
  ai-templates = [
147
- "pydantic-ai-slim[spec]>=2,<3",
147
+ "pydantic-ai-slim[spec]>=2.45,<3",
148
148
  ]
149
149
  ai-a2a = [
150
150
  "fasta2a>=0.6,<1",
@@ -16,6 +16,7 @@ from __future__ import annotations
16
16
  from collections.abc import Mapping
17
17
  from types import MappingProxyType
18
18
 
19
+ from pydantic_ai import exceptions as pydantic_ai_exceptions
19
20
  from pydantic_ai.exceptions import (
20
21
  CostCalculationFailedWarning,
21
22
  CostNotFoundWarning,
@@ -27,6 +28,19 @@ from pydantic_ai.exceptions import (
27
28
 
28
29
  from loom.ai.errors import AgentRunError, AgentRunErrorCode
29
30
 
31
+ _UNMEASURED_SPEND_WARNINGS: tuple[type[Warning], ...] = tuple(
32
+ warning
33
+ for warning in (
34
+ CostNotFoundWarning,
35
+ CostCalculationFailedWarning,
36
+ getattr(pydantic_ai_exceptions, "UsageExtractionFailedWarning", None),
37
+ )
38
+ if warning is not None
39
+ )
40
+ """pydantic-ai's bare ``Warning`` subclasses, all of them a spend the run could
41
+ not measure. ``UsageExtractionFailedWarning`` first ships in a pydantic-ai
42
+ release newer than the supported floor, so it is mapped only where it exists."""
43
+
30
44
  _STATUS_CODES: Mapping[int, AgentRunErrorCode] = MappingProxyType(
31
45
  {
32
46
  401: AgentRunErrorCode.UNAUTHORIZED,
@@ -49,13 +63,12 @@ _EXCEPTION_CODES: Mapping[type[Exception], AgentRunErrorCode] = MappingProxyType
49
63
  UnexpectedModelBehavior: AgentRunErrorCode.OUTPUT_SCHEMA_VIOLATION,
50
64
  ModelAPIError: AgentRunErrorCode.PROVIDER_UNAVAILABLE,
51
65
  TimeoutError: AgentRunErrorCode.RUN_TIMEOUT,
52
- # Both subclass ``Warning``, not ``UserWarning``; see "Spend caps" in
66
+ # They subclass ``Warning``, not ``UserWarning``; see "Spend caps" in
53
67
  # docs/ai/artifacts.md for why that makes this mapping load-bearing
54
68
  # under ``-W error``. ``test_pydantic_ai_errors.py`` walks every
55
69
  # ``pydantic_ai._warnings`` subclass of ``Warning`` that is not a
56
- # ``UserWarning`` and fails the day a third one is added here unmapped.
57
- CostNotFoundWarning: AgentRunErrorCode.COST_NOT_MEASURABLE,
58
- CostCalculationFailedWarning: AgentRunErrorCode.COST_NOT_MEASURABLE,
70
+ # ``UserWarning`` and fails the day a new one is left unmapped.
71
+ **dict.fromkeys(_UNMEASURED_SPEND_WARNINGS, AgentRunErrorCode.COST_NOT_MEASURABLE),
59
72
  }
60
73
  )
61
74
 
@@ -15,20 +15,24 @@ model's cost can be permanently unpriceable.
15
15
  from __future__ import annotations
16
16
 
17
17
  import logging
18
- from dataclasses import dataclass, replace
18
+ from collections.abc import AsyncIterator
19
+ from contextlib import asynccontextmanager
20
+ from dataclasses import replace
21
+ from decimal import Decimal
19
22
  from typing import Any
20
23
 
21
24
  from genai_prices import calc_price
22
25
  from pydantic_ai import RunContext
23
- from pydantic_ai.capabilities import AbstractCapability
24
- from pydantic_ai.messages import ModelResponse
25
- from pydantic_ai.models import ModelRequestContext
26
- from pydantic_ai.usage import RunUsage, UsageLimits
26
+ from pydantic_ai.messages import ModelMessage, ModelResponse
27
+ from pydantic_ai.models import Model, ModelRequestParameters, StreamedResponse
28
+ from pydantic_ai.models.wrapper import WrapperModel
29
+ from pydantic_ai.settings import ModelSettings
30
+ from pydantic_ai.usage import RequestUsage, RunUsage, UsageLimits
27
31
 
28
32
  from loom.ai.declarative import PolicySpec
29
33
  from loom.ai.pricing import ModelPrice
30
34
 
31
- __all__ = ["ConfiguredPrice", "is_priceable", "usage_limits", "warn_if_model_not_priceable"]
35
+ __all__ = ["PricedModel", "is_priceable", "usage_limits", "warn_if_model_not_priceable"]
32
36
 
33
37
  _logger = logging.getLogger(__name__)
34
38
 
@@ -59,36 +63,58 @@ def usage_limits(policies: PolicySpec) -> UsageLimits:
59
63
  )
60
64
 
61
65
 
62
- @dataclass
63
- class ConfiguredPrice(AbstractCapability[Any]):
64
- """Price every model response with the deployment's own rates.
66
+ class PricedModel(WrapperModel):
67
+ """Model whose every response is priced with the deployment's own rates.
65
68
 
66
- The cost is set before the response joins the run's usage, so the
67
- engine's ``cost_limit`` and loom's ``on_unpriced_spend`` both read it,
68
- and it replaces whatever genai-prices would have computed.
69
+ The cost is set on the response the wrapped model returns, before the
70
+ engine records it in the run's usage, so the engine's ``cost_limit`` and
71
+ loom's ``on_unpriced_spend`` both read it, whatever the engine version
72
+ does after the response leaves the model. It replaces any cost the model
73
+ reported and whatever genai-prices would have computed.
69
74
 
70
75
  Args:
71
- price: Rates of the model the plan is bound to.
76
+ wrapped: Model built for the plan's binding.
77
+ price: Rates of that model.
72
78
  """
73
79
 
74
- price: ModelPrice
80
+ def __init__(self, wrapped: Model, price: ModelPrice) -> None:
81
+ super().__init__(wrapped)
82
+ self.price = price
75
83
 
76
- async def after_model_request(
84
+ async def request(
77
85
  self,
78
- ctx: RunContext[Any],
79
- *,
80
- request_context: ModelRequestContext,
81
- response: ModelResponse,
86
+ messages: list[ModelMessage],
87
+ model_settings: ModelSettings | None,
88
+ model_request_parameters: ModelRequestParameters,
82
89
  ) -> ModelResponse:
83
- """Return *response* with its usage priced at :attr:`price`."""
84
- usage = response.usage
85
- cost = self.price.cost(
90
+ """Return the wrapped model's response with its usage priced at :attr:`price`."""
91
+ response = await super().request(messages, model_settings, model_request_parameters)
92
+ return replace(response, usage=replace(response.usage, cost=self._cost(response.usage)))
93
+
94
+ @asynccontextmanager
95
+ async def request_stream(
96
+ self,
97
+ messages: list[ModelMessage],
98
+ model_settings: ModelSettings | None,
99
+ model_request_parameters: ModelRequestParameters,
100
+ run_context: RunContext[Any] | None = None,
101
+ ) -> AsyncIterator[StreamedResponse]:
102
+ """Yield the wrapped model's stream, its usage priced at :attr:`price` once it closes."""
103
+ async with super().request_stream(
104
+ messages, model_settings, model_request_parameters, run_context
105
+ ) as stream:
106
+ try:
107
+ yield stream
108
+ finally:
109
+ stream.usage.cost = self._cost(stream.usage)
110
+
111
+ def _cost(self, usage: RequestUsage) -> Decimal:
112
+ return self.price.cost(
86
113
  input_tokens=usage.input_tokens,
87
114
  output_tokens=usage.output_tokens,
88
115
  cache_read_tokens=usage.cache_read_tokens,
89
116
  cache_write_tokens=usage.cache_write_tokens,
90
117
  )
91
- return replace(response, usage=replace(usage, cost=cost))
92
118
 
93
119
 
94
120
  def is_priceable(model_name: str, provider_name: str | None) -> bool:
@@ -19,7 +19,6 @@ from __future__ import annotations
19
19
  from typing import TYPE_CHECKING, Any, ClassVar
20
20
 
21
21
  from pydantic_ai import Agent, ModelRetry
22
- from pydantic_ai.capabilities import AbstractCapability
23
22
  from pydantic_ai.models import Model
24
23
 
25
24
  from loom.ai.abc import AgentEngine, DepsFactory, OutputCheck
@@ -36,7 +35,7 @@ from loom.ai.engines.pydantic_ai._instructions import (
36
35
  ensure_templating_available,
37
36
  )
38
37
  from loom.ai.engines.pydantic_ai._limits import (
39
- ConfiguredPrice,
38
+ PricedModel,
40
39
  is_priceable,
41
40
  usage_limits,
42
41
  warn_if_model_not_priceable,
@@ -164,13 +163,9 @@ class PydanticAIEngineProvider:
164
163
  if not isinstance(plan, AgentPlan):
165
164
  raise TypeError(f"expected an AgentPlan, got {type(plan).__name__}")
166
165
  ensure_templating_available(plan)
167
- model = self._resolve_model(plan.inference)
168
- if plan.price is None:
169
- warn_if_model_not_priceable(
170
- model.model_name, _provider_name(model), plan.policies, f"agent '{plan.name}'"
171
- )
166
+ model = _with_price(self._resolve_model(plan.inference), plan)
172
167
  toolsets = build_toolsets(plan, container, mcp=self._mcp)
173
- capabilities = _with_price(build_capabilities(plan, container), plan)
168
+ capabilities = build_capabilities(plan, container)
174
169
  if not plan.inference.streaming and any(
175
170
  capability.has_wrap_run_event_stream for capability in capabilities
176
171
  ):
@@ -270,13 +265,14 @@ def _provider_name(model: Model) -> str | None:
270
265
  return model.provider.name if model.provider is not None else None
271
266
 
272
267
 
273
- def _with_price(
274
- capabilities: tuple[AbstractCapability[Any], ...], plan: AgentPlan
275
- ) -> tuple[AbstractCapability[Any], ...]:
276
- """Append the plan's configured price, when it declares one, to *capabilities*."""
277
- if plan.price is None:
278
- return capabilities
279
- return (*capabilities, ConfiguredPrice(price=plan.price))
268
+ def _with_price(model: Model, plan: AgentPlan) -> Model:
269
+ """Price *model* with the plan's configured rates, or warn when it may stay unpriced."""
270
+ if plan.price is not None:
271
+ return PricedModel(model, plan.price)
272
+ warn_if_model_not_priceable(
273
+ model.model_name, _provider_name(model), plan.policies, f"agent '{plan.name}'"
274
+ )
275
+ return model
280
276
 
281
277
 
282
278
  def _register_output_check(agent: Agent[Any, Any], loom_type: LoomType, check: OutputCheck) -> None:
@@ -55,6 +55,7 @@ from loom.etl.declarative import (
55
55
  CsvReadOptions,
56
56
  CsvWriteOptions,
57
57
  DeletePolicy,
58
+ EmptyReplaceError,
58
59
  ExcelReadOptions,
59
60
  Format,
60
61
  FromConfig,
@@ -203,6 +204,7 @@ __all__ = [
203
204
  "HistorifyKeyConflictError",
204
205
  "HistorifyDateCollisionError",
205
206
  "HistorifyTemporalConflictError",
207
+ "EmptyReplaceError",
206
208
  # intermediates
207
209
  "CheckpointCleaner",
208
210
  "CheckpointScope",
@@ -15,6 +15,7 @@ from loom.core.logger import get_logger
15
15
  from loom.etl.declarative.target import (
16
16
  AppendSpec,
17
17
  ClientSpec,
18
+ EmptyReplaceError,
18
19
  FileSpec,
19
20
  ReplacePartitionsSpec,
20
21
  ReplaceSpec,
@@ -188,6 +189,7 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
188
189
  streaming: bool,
189
190
  create_partition_cols: tuple[str, ...] = (),
190
191
  require_physical_partitions: tuple[str, ...] | None = None,
192
+ allow_empty: bool = True,
191
193
  ) -> _PreparedWrite[WriteFrameT, PhysicalSchemaT] | None:
192
194
  """Run the shared policy up to the point where the write mode differs.
193
195
 
@@ -207,6 +209,10 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
207
209
  require_physical_partitions: Partition columns the existing table
208
210
  must physically carry, or ``None`` to
209
211
  skip that check.
212
+ allow_empty: When ``False``, raise
213
+ :class:`EmptyReplaceError` for a
214
+ frame with no rows, before the table
215
+ is created or written.
210
216
 
211
217
  Returns:
212
218
  The prepared write when the table already exists and the caller
@@ -220,7 +226,9 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
220
226
  schema_mode=schema_mode,
221
227
  missing_table_policy=self._missing_table_policy,
222
228
  )
223
- materialized = self._materialize_checked(frame, target, streaming)
229
+ materialized = self._materialize_checked(
230
+ frame, target, streaming, allow_empty=allow_empty
231
+ )
224
232
  self._create(
225
233
  materialized,
226
234
  target,
@@ -232,7 +240,7 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
232
240
  self._require_physical_partitions(target, require_physical_partitions)
233
241
  aligned = self._align(frame, existing, schema_mode)
234
242
  return _PreparedWrite(
235
- frame=self._materialize_checked(aligned, target, streaming),
243
+ frame=self._materialize_checked(aligned, target, streaming, allow_empty=allow_empty),
236
244
  existing_schema=existing,
237
245
  )
238
246
 
@@ -260,7 +268,11 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
260
268
  ) -> None:
261
269
  """Replace policy: check exists → create OR align → write."""
262
270
  prepared = self._prepare_write(
263
- frame, target, schema_mode=spec.schema_mode, streaming=streaming
271
+ frame,
272
+ target,
273
+ schema_mode=spec.schema_mode,
274
+ streaming=streaming,
275
+ allow_empty=spec.allow_empty,
264
276
  )
265
277
  if prepared is None:
266
278
  return
@@ -507,15 +519,29 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
507
519
  _ = frame
508
520
  return None
509
521
 
522
+ @abstractmethod
523
+ def _is_empty(self, frame: WriteFrameT) -> bool:
524
+ """Whether the materialised *frame* has no rows."""
525
+
510
526
  def _materialize_checked(
511
527
  self,
512
528
  frame: InputFrameT,
513
529
  target: ResolvedTarget,
514
530
  streaming: bool,
531
+ *,
532
+ allow_empty: bool = True,
515
533
  ) -> WriteFrameT:
516
- """Materialise *frame*, warning when the write carries no rows."""
534
+ """Materialise *frame*, warning when the write carries no rows.
535
+
536
+ Raises:
537
+ EmptyReplaceError: When *allow_empty* is ``False`` and the
538
+ materialised frame has no rows.
539
+ """
517
540
  materialized = self._materialize_for_write(frame, streaming)
518
- if self._row_count_if_cheap(materialized) == 0:
541
+ if not allow_empty:
542
+ if self._is_empty(materialized):
543
+ raise EmptyReplaceError(target.logical_ref.ref)
544
+ elif self._row_count_if_cheap(materialized) == 0:
519
545
  _log.warning("write_produced_no_rows", target=target.logical_ref.ref)
520
546
  return materialized
521
547
 
@@ -1,7 +1,7 @@
1
1
  """Polars backend for the Loom ETL framework."""
2
2
 
3
3
  from loom.etl.backends.polars._file_writer import PolarsFileWriter
4
- from loom.etl.backends.polars._reader import PolarsSourceReader
4
+ from loom.etl.backends.polars._reader import PolarsSourceReader, decode_json_columns
5
5
  from loom.etl.backends.polars._schema import PolarsPhysicalSchema, read_delta_physical_schema
6
6
  from loom.etl.backends.polars._writer import PolarsTargetWriter
7
7
 
@@ -10,5 +10,6 @@ __all__ = [
10
10
  "PolarsPhysicalSchema",
11
11
  "PolarsSourceReader",
12
12
  "PolarsTargetWriter",
13
+ "decode_json_columns",
13
14
  "read_delta_physical_schema",
14
15
  ]
@@ -5,8 +5,8 @@ from __future__ import annotations
5
5
  import functools
6
6
  import json
7
7
  import logging
8
- from collections.abc import Callable
9
- from typing import TYPE_CHECKING, Any
8
+ from collections.abc import Callable, Iterable
9
+ from typing import TYPE_CHECKING, Any, TypeVar
10
10
 
11
11
  if TYPE_CHECKING:
12
12
  from loom.etl.io.sources._clickhouse import ClickHouseSourceReader
@@ -23,6 +23,7 @@ from loom.etl.declarative.source import FileSourceSpec, SourceSpec, TableSourceS
23
23
  from loom.etl.declarative.source._specs import (
24
24
  ClickHouseSourceSpec,
25
25
  DynamoDbSourceSpec,
26
+ JsonColumnSpec,
26
27
  MongoSourceSpec,
27
28
  )
28
29
  from loom.etl.runtime.contracts import SourceReader
@@ -43,6 +44,8 @@ from ._predicate import predicate_to_polars
43
44
 
44
45
  _log = logging.getLogger(__name__)
45
46
 
47
+ _FrameT = TypeVar("_FrameT", pl.DataFrame, pl.LazyFrame)
48
+
46
49
 
47
50
  # ---------------------------------------------------------------------------
48
51
  # Polymorphic JSON normalization
@@ -124,6 +127,49 @@ def _normalize_json_string(json_str: str | None, *, loom_type: LoomType) -> str
124
127
  return json.dumps(result, ensure_ascii=False)
125
128
 
126
129
 
130
+ def decode_json_columns(frame: _FrameT, json_columns: Iterable[JsonColumnSpec]) -> _FrameT:
131
+ """Decode JSON string columns the way :class:`PolarsSourceReader` does at read time.
132
+
133
+ Each column named in *json_columns* holds JSON text and is replaced by the
134
+ value decoded into its declared :class:`~loom.etl.schema.LoomType`. Rows
135
+ are first normalised to that type, so a field that is a string in some rows
136
+ and an object in others decodes instead of raising
137
+ :exc:`polars.exceptions.ComputeError`. A null or unparseable value decodes
138
+ to null. Other columns pass through unchanged.
139
+
140
+ Use it to reproduce in a test what a step receives from a source declared
141
+ with ``parse_json``.
142
+
143
+ Args:
144
+ frame: Eager or lazy frame holding the JSON text columns.
145
+ json_columns: Column declarations, e.g. ``FromTable(...).json_columns``
146
+ or ``FromFile(...).json_columns``.
147
+
148
+ Returns:
149
+ A frame of the same kind as *frame*, or *frame* itself when
150
+ *json_columns* is empty.
151
+
152
+ Example::
153
+
154
+ from loom.etl.backends.polars import decode_json_columns
155
+
156
+ events = FromTable("raw.events").parse_json("payload", Payload)
157
+ decoded = decode_json_columns(raw_frame, events.json_columns)
158
+ """
159
+ exprs = [
160
+ pl.col(jc.column)
161
+ .map_elements(
162
+ functools.partial(_normalize_json_string, loom_type=jc.loom_type),
163
+ return_dtype=pl.String,
164
+ )
165
+ .str.json_decode(loom_type_to_polars(jc.loom_type))
166
+ for jc in json_columns
167
+ ]
168
+ if not exprs:
169
+ return frame
170
+ return frame.with_columns(exprs)
171
+
172
+
127
173
  class PolarsSourceReader(SourceReader):
128
174
  """Read table, file, and MongoDB sources using Polars."""
129
175
 
@@ -351,21 +397,10 @@ class PolarsSourceReader(SourceReader):
351
397
  Applies a per-row normalization pass before ``json_decode`` so that
352
398
  polymorphic fields (e.g. ``String`` in some rows, ``Object`` in others)
353
399
  are coerced to the declared :class:`~loom.etl.schema.LoomType` without
354
- raising :exc:`polars.exceptions.ComputeError`.
400
+ raising :exc:`polars.exceptions.ComputeError`. See
401
+ :func:`decode_json_columns`.
355
402
  """
356
- if not json_columns:
357
- return frame
358
-
359
- exprs = [
360
- pl.col(jc.column)
361
- .map_elements(
362
- functools.partial(_normalize_json_string, loom_type=jc.loom_type),
363
- return_dtype=pl.String,
364
- )
365
- .str.json_decode(loom_type_to_polars(jc.loom_type))
366
- for jc in json_columns
367
- ]
368
- return frame.with_columns(exprs)
403
+ return decode_json_columns(frame, json_columns)
369
404
 
370
405
 
371
406
  def _apply_source_schema(frame: pl.LazyFrame, schema: tuple[ColumnSchema, ...]) -> pl.LazyFrame:
@@ -374,8 +409,8 @@ def _apply_source_schema(frame: pl.LazyFrame, schema: tuple[ColumnSchema, ...])
374
409
 
375
410
 
376
411
  def _apply_json_decode(frame: pl.LazyFrame, json_columns: tuple[Any, ...]) -> pl.LazyFrame:
377
- """Compatibility helper used by tests."""
378
- return PolarsSourceReader._apply_json_decode(frame, json_columns)
412
+ """Compatibility alias of :func:`decode_json_columns`."""
413
+ return decode_json_columns(frame, json_columns)
379
414
 
380
415
 
381
416
  def execute_sql(frames: dict[str, pl.LazyFrame], query: str) -> pl.LazyFrame:
@@ -386,4 +421,10 @@ def execute_sql(frames: dict[str, pl.LazyFrame], query: str) -> pl.LazyFrame:
386
421
  return ctx.execute(query, eager=False)
387
422
 
388
423
 
389
- __all__ = ["PolarsSourceReader", "execute_sql", "_apply_source_schema", "_apply_json_decode"]
424
+ __all__ = [
425
+ "PolarsSourceReader",
426
+ "decode_json_columns",
427
+ "execute_sql",
428
+ "_apply_source_schema",
429
+ "_apply_json_decode",
430
+ ]
@@ -217,6 +217,10 @@ class PolarsTargetWriter(_WritePolicy[pl.LazyFrame, pl.DataFrame, PolarsPhysical
217
217
  """Rows in the collected frame."""
218
218
  return frame.height
219
219
 
220
+ def _is_empty(self, frame: pl.DataFrame) -> bool:
221
+ """Whether the collected frame has no rows."""
222
+ return frame.is_empty()
223
+
220
224
  def _materialize_for_write(self, frame: pl.LazyFrame, streaming: bool) -> pl.DataFrame:
221
225
  """Collect lazy frame to DataFrame before Delta write."""
222
226
  df = frame.collect(engine="streaming" if streaming else "auto")
@@ -143,6 +143,10 @@ class SparkTargetWriter(_WritePolicy[DataFrame, DataFrame, SparkPhysicalSchema])
143
143
  _ = streaming
144
144
  return frame
145
145
 
146
+ def _is_empty(self, frame: DataFrame) -> bool:
147
+ """Whether *frame* has no rows; runs one Spark job that stops at the first row."""
148
+ return frame.isEmpty()
149
+
146
150
  def _predicate_to_sql(self, predicate: Any, params: Any) -> str:
147
151
  """Convert predicate to SQL."""
148
152
  return predicate_to_sql(predicate, params)
@@ -2,6 +2,7 @@
2
2
 
3
3
  from loom.etl.compiler._compiler import ETLCompiler
4
4
  from loom.etl.compiler._errors import ETLCompilationError, ETLErrorCode
5
+ from loom.etl.compiler._filter import InvalidStageError, filter_plan
5
6
  from loom.etl.compiler._plan import (
6
7
  AgentBinding,
7
8
  ConfigValueBinding,
@@ -13,6 +14,9 @@ from loom.etl.compiler._plan import (
13
14
  StepPlan,
14
15
  TargetBinding,
15
16
  flatten_step_names,
17
+ iter_all_steps,
18
+ iter_processes,
19
+ iter_steps_in_process,
16
20
  )
17
21
  from loom.etl.compiler._validators import (
18
22
  StepCompilationContext,
@@ -31,6 +35,7 @@ __all__ = [
31
35
  "ETLCompiler",
32
36
  "ETLCompilationError",
33
37
  "ETLErrorCode",
38
+ "InvalidStageError",
34
39
  "StepPlan",
35
40
  "ProcessPlan",
36
41
  "PipelinePlan",
@@ -41,7 +46,11 @@ __all__ = [
41
46
  "ParallelStepGroup",
42
47
  "ParallelProcessGroup",
43
48
  "StepCompilationContext",
49
+ "filter_plan",
44
50
  "flatten_step_names",
51
+ "iter_all_steps",
52
+ "iter_processes",
53
+ "iter_steps_in_process",
45
54
  "validate_execute_signature",
46
55
  "validate_param_exprs",
47
56
  "validate_params_compat",