loom-kernel 2.18.0__tar.gz → 2.20.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.
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/CHANGELOG.md +240 -11
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/PKG-INFO +1 -1
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/_fingerprint.py +3 -13
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/_plan.py +18 -10
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/config.py +18 -2
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_limits.py +1 -1
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/errors.py +18 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/etl/_batch.py +35 -13
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/etl/_columns.py +44 -15
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/etl/_frames.py +9 -9
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/etl/_ledger.py +0 -12
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/etl/_runner.py +8 -4
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/etl/_validation.py +27 -10
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/pricing.py +3 -2
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/backend/core_model.py +2 -1
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/backend/sqlalchemy.py +43 -8
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/repository.py +64 -36
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/errors/errors.py +9 -7
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/__init__.py +2 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/introspection.py +14 -5
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/abc/cursor.py +32 -8
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/dynamodb/repository.py +17 -2
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/mongo/repository.py +17 -4
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/mixins.py +82 -36
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +21 -9
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +22 -11
- loom_kernel-2.20.0/src/loom/etl/_uri.py +20 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_write_policy.py +44 -16
- loom_kernel-2.20.0/src/loom/etl/backends/polars/_frame.py +15 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/polars/_historify.py +4 -5
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/polars/_reader.py +4 -23
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/polars/_schema.py +43 -1
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/polars/_writer.py +3 -3
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/spark/_writer.py +44 -3
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/checkpoint/_backends/_polars.py +2 -2
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/checkpoint/_cleaners.py +0 -11
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/compiler/_errors.py +11 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/compiler/_filter.py +4 -4
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/compiler/_validators_agents.py +4 -14
- loom_kernel-2.20.0/src/loom/etl/declarative/_with_agent.py +109 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_errors.py +2 -2
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_into.py +4 -2
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_table.py +4 -5
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/executor/_dispatcher.py +15 -20
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/maintenance/_builder.py +4 -2
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/maintenance/_ops.py +5 -3
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/runner/_wiring.py +2 -2
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/runner/config_loader.py +2 -2
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/storage/_config.py +7 -5
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/deploy/_discovery.py +51 -15
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/notify/__init__.py +4 -2
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/notify/_factory.py +13 -0
- loom_kernel-2.20.0/src/loom/prefect/notify/_format.py +40 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/notify/_slack.py +8 -32
- loom_kernel-2.20.0/src/loom/prefect/notify/_sns.py +78 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/observer/_logging_bridge.py +9 -6
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/autocrud.py +30 -6
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/fastapi/auto.py +8 -9
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/testing/in_memory.py +22 -1
- loom_kernel-2.18.0/src/loom/etl/declarative/_with_agent.py +0 -70
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/.gitignore +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/LICENSE +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/README.md +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/pyproject.toml +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/_concurrency.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/_filters.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/_paths.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/_roles.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/_startup.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/_transport.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/_usecase.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/a2a/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/a2a/_binding.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/a2a/_handlers.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/a2a/_rpc.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/a2a/card.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/a2a/events.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/a2a/server.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/abc.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/bootstrap.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/_compiler.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/phases/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/phases/_capabilities.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/phases/_conversation.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/phases/_feedable.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/phases/_hook.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/phases/_instructions.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/phases/_limits.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/phases/_model_role.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/phases/_output.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/compiler/phases/_state.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/declarative/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/declarative/_envelope.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/declarative/_schema.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/declarative/_v1.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/declarative/schemas/agent-spec-v1.schema.json +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/describe.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_a2a.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_capabilities.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_engine.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_escape.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_events.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_guards.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_history.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_instructions.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_mcp.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_models.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_native.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_output.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_returns.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_schemas.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/_spec.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/extras/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/extras/a2a.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/extras/handlebars.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/extras/mcp.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/extras/skills.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/provider.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/providers/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/providers/_shared.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/providers/anthropic.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/providers/bedrock.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/providers/gateway.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/providers/openai.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/engines/pydantic_ai/providers/typesafe.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/etl/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/fastapi/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/fastapi/endpoints.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/fastapi/response.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/fastapi/streaming.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/inference.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/registry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/remote_auth.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/runtime/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/runtime/_bounded.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/runtime/_chain.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/runtime/_conversation.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/runtime/_grants.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/runtime/_handle.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/runtime/_health.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/runtime/_hooks.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/runtime/_lifecycle.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/runtime/_limits.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/runtime/_mcp.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/validate/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/ai/validate/__main__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/celery/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/celery/auto.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/celery/bootstrap.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/celery/config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/celery/constants.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/celery/runner.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/celery/service.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/cli/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/cli/app.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/cli/schema.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/async_bridge.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/authz/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/authz/_decide.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/authz/_grants.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/authz/_roles.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/authz/_scope.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/authz/elevation.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/authz/product.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/backend/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/backend/protocol.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/backend/scoped_ddl.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/bootstrap/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/bootstrap/kernel.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/_batching.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/_single_flight.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/abc/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/abc/backend.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/abc/config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/abc/dependency.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/calls.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/codec.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/decorators.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/dependency.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/gateway.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/keys.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/memory.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/result_codec.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/serializer.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/cache/wiring.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/command/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/command/adapter.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/command/base.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/command/field.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/command/introspection.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/compiler.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/_boto3.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/_includes.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/_resolver_utils.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/binder.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/configurable.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/context.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/keys.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/loader.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/model.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/observability.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/resolver.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/secrets.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/config/ssm.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/contracts/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/contracts/manifest.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/di/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/di/container.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/di/scope.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/discovery/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/discovery/_utils.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/discovery/base.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/discovery/interfaces.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/discovery/manifest.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/discovery/modules.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/engine/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/engine/compilable.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/engine/compiler.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/engine/events.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/engine/executor.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/engine/metrics.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/engine/plan.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/engine/post_commit.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/errors/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/errors/codes.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/expr/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/expr/eval.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/expr/nodes.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/expr/refs.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/identity/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/identity/context.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/identity/identity.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/identity/issuer.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/identity/wire.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/introspection/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/introspection/base.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/introspection/describe.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/job/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/job/callback.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/job/context.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/job/handle.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/job/job.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/job/service.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/locator.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/logger/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/logger/abc.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/logger/config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/logger/registry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/logger/structlogger.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/_loom_type.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/base.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/convert.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/enums.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/field.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/partition.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/privilege.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/projection.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/relation.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/scoped.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/struct.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/timestamped.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/types.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/model/types_postgres.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/observability/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/observability/config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/observability/event.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/observability/observer/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/observability/observer/noop.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/observability/observer/otel.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/observability/observer/structlog.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/observability/otel_ids.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/observability/protocol.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/observability/runtime.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/observability/span.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/observability/topology.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/persistence/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/persistence/abc.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/persistence/none.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/persistence/registry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/plugins/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/plugins/entrypoints.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/plugins/optional.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/projection/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/projection/loaders.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/projection/runtime.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/abc/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/abc/errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/abc/query.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/abc/query_compiler.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/abc/repo_for.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/abc/repository.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/abc/session_scope.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/dynamodb/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/dynamodb/backend.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/dynamodb/registry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/dynamodb/uow.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/mongo/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/mongo/backend.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/mongo/ids.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/mongo/query_compiler.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/mongo/registry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/mongo/uow.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/mongo/values.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/mutation.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/registration.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/registry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/backend.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/migrations/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/migrations/env_template.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/migrations/hook.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/migrations/operations.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/migrations/runners.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/bootstrap.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/elevate.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/guard/0001.sql +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/guard/0002.sql +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/guard/preflight.sql +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/guard_manifest.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/integrity.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/partitions.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/provider.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/schema.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/sources.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/rls/verify.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/session_settings.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/response/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/response/base.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/routing/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/routing/ref.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/routing/resolver.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/runner.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/schema/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/schema/schema_mode.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/schema_names.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/sql/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/sql/abc/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/sql/abc/contracts.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/sql/abc/errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/sql/caller_bound.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/sql/clickhouse/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/sql/clickhouse/_client.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/sql/clickhouse/executor.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/sql/clickhouse/registry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/sql/config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/sql/roles.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/sql/service.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/symbols.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/tracing/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/tracing/context.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/transaction.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/transport/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/transport/adapter.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/uow/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/uow/abc.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/uow/context.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/_predicates.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/agent_markers.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/compute.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/constants.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/factory.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/field_ref.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/invoker.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/keys.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/markers.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/mcp_markers.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/registry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/rule.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/core/use_case/use_case.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_format_registry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_historify/_common.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_historify/_log.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_merge.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_path_template.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_predicate.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/polars/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/polars/_streaming.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/polars/provider.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/spark/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/spark/_historify.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/spark/_reader.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/spark/_schema.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/backends/spark/provider.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/checkpoint/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/checkpoint/_options.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/checkpoint/_paths.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/checkpoint/_scope.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/checkpoint/_store.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/compiler/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/compiler/_binding.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/compiler/_compiler.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/compiler/_plan.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/compiler/_validators.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/compiler/_validators_config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/compiler/_validators_step.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/_format.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/_read_options.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/_utils.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/_write_options.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/expr/_params.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/source/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/source/_from.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/source/_from_config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/source/_specs.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_client.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_file.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/declarative/target/_temp.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/executor/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/executor/_agents.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/executor/_executor.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/_registry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/sources/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/sources/_clickhouse.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/sources/_dynamodb.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/sources/_mongo.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/sources/_serialization.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/targets/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/io/targets/_clickhouse.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/lineage/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/lineage/_config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/lineage/_observer.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/lineage/_records.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/maintenance/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/maintenance/_protocol.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/maintenance/_runner.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/maintenance/_step.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/maintenance/backends/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/pipeline/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/pipeline/_generics.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/pipeline/_params.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/pipeline/_process.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/pipeline/_sql.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/pipeline/_step.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/pipeline/_step_client.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/runner/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/runner/_agents.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/runner/_providers.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/runner/core.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/runner/errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/runner/filtering.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/runtime/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/runtime/_config_values.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/runtime/contracts.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/schema/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/schema/_contract.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/schema/_schema.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/storage/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/storage/_file_locator.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/storage/_locator.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/storage/routing.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/testing/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/testing/_result.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/testing/_runners.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/testing/_scenario.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/testing/_stubs.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/etl/testing/spark.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/_async.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/_config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/_ctx.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/_flow_yaml.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/_meta.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/_placeholders.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/_summary.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/deploy/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/deploy/_schedule.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/deploy/_yaml_etls.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/deploy/entrypoint.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_assemble.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_backfill.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_backfill_body.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_body.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_common.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_factory.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_hooks.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_maintenance.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_params.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_run_name.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_runtime.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_signature.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/flow/_stages.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/manifest/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/manifest/_model.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/manifest/_s3.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/manifest/_store.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/notify/_event.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/notify/_port.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/observer/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/observer/_flow.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/observer/_manifest.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prefect/observer/_task_run.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prometheus/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prometheus/_instruments.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prometheus/adapter.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prometheus/kafka.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prometheus/lifecycle.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/prometheus/middleware.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/py.typed +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/_body.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/adapter.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/auth/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/auth/abc.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/auth/config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/auth/jwt.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/auth/middleware.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/compiler.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/constants.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/cors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/fastapi/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/fastapi/_errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/fastapi/_exclusions.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/fastapi/app.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/fastapi/health.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/fastapi/openapi.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/fastapi/response.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/fastapi/sql.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/middleware.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/model.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/rest/rest_adapter.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/_adapter.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/_batch_spans.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/_errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/_operators.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/bytewax/runner.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/compiler/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/compiler/_bindings.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/compiler/_compiler.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/compiler/_errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/compiler/_plan.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/compiler/phases/build_plan.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/compiler/phases/validate.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/core/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/core/_errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/core/_exceptions.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/core/_message.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/core/_tracing.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/core/_typing.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/graph/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/graph/_flow.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/_codec.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/_config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/_errors.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/_message.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/_record.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/_wire.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/client/_retry.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/mongo/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/mongo/_config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/mongo/_event.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/mongo/_normalize.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_boundary.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_branches.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_decompose.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_expand_routes.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_fork.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_helpers.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_mongo.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_protocols.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_router.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_shape.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_sink.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_step.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_table/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_table/common.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_table/config.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/_with.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/nodes/refs.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/streaming/testing.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/testing/__init__.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/testing/agents.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/testing/golden.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/testing/http_harness.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/testing/repository_harness.py +0 -0
- {loom_kernel-2.18.0 → loom_kernel-2.20.0}/src/loom/testing/runner.py +0 -0
|
@@ -90,6 +90,9 @@
|
|
|
90
90
|
|
|
91
91
|
### ai
|
|
92
92
|
|
|
93
|
+
- **ai:** `AiConfig` logs a warning for every key of `ai.prices` that no
|
|
94
|
+
binding of `ai.models` names, a price no run is priced with (a misspelt
|
|
95
|
+
model id, for instance).
|
|
93
96
|
- **ai:** `provider: typesafe` binds TypeSafe's Jev, a decision model that
|
|
94
97
|
fills a typed output from the state it is given and never writes text, so a
|
|
95
98
|
role whose answer is a choice or a verdict can run on it. Extra
|
|
@@ -153,12 +156,14 @@
|
|
|
153
156
|
assembles an unentered `AgentRuntime` from an `ai:` section: engine,
|
|
154
157
|
artifacts under `root`, compilation. `create_app` now builds its runtime
|
|
155
158
|
through it. `AgentRuntime.plans` exposes the compiled plans.
|
|
156
|
-
- **ai:** `AgentPlan.fingerprint`, a stable sha256 of
|
|
157
|
-
agent's answers: compiled instructions,
|
|
158
|
-
import path),
|
|
159
|
-
capability
|
|
160
|
-
the
|
|
161
|
-
|
|
159
|
+
- **ai:** `AgentPlan.fingerprint`, a stable sha256 of the declared facts
|
|
160
|
+
that decide an agent's answers: `spec_version`, compiled instructions,
|
|
161
|
+
output schema, output check (by import path), the kind and declared facts
|
|
162
|
+
of every capability (including the `include`/`exclude` filters of `mcp`
|
|
163
|
+
and `a2a`) and the bound provider, model, `output_mode` and `options`; not
|
|
164
|
+
the policies, the content of the skills, tools or use cases a capability
|
|
165
|
+
names, the name, metadata, price, where a capability is served from,
|
|
166
|
+
region, endpoint, credentials or `streaming`.
|
|
162
167
|
- **ai:** `loom.ai.etl.PolarsAgentRunner` runs an agent over a Polars frame
|
|
163
168
|
for ETL steps (see `etl`): a runtime of its own per call that also sees the
|
|
164
169
|
caller's context variables, concurrency that waits instead of refusing, one
|
|
@@ -250,6 +255,14 @@
|
|
|
250
255
|
attribute name (the flow name with `-` replaced by `_`), as the worker
|
|
251
256
|
imports it, and raises `ValueError` otherwise; a module not yet imported is
|
|
252
257
|
imported from that file. Any other object raises `TypeError`.
|
|
258
|
+
- **prefect:** a flow can notify an AWS SNS topic. The `notifications` list
|
|
259
|
+
takes `kind: sns` with `topic_arn` and the same `on_failure` (default
|
|
260
|
+
`true`) and `on_completion` (default `false`) filters as `kind: slack`; an
|
|
261
|
+
empty `topic_arn` skips the entry. Matching terminal states are published
|
|
262
|
+
through boto3 (`prefect` extra) in the topic's region with subject
|
|
263
|
+
`[<state>] <flow>` and a plain-text message with the run details, the end of
|
|
264
|
+
the error message and the Prefect link. A failed publish is logged and does
|
|
265
|
+
not fail the run. `SnsNotifier` is exported from `loom.prefect.notify`.
|
|
253
266
|
|
|
254
267
|
### etl
|
|
255
268
|
|
|
@@ -333,11 +346,14 @@
|
|
|
333
346
|
exported from `loom.etl`, carrying `table_ref`) before it creates or writes
|
|
334
347
|
anything, so a dimension rebuilt from a read that came back empty keeps its
|
|
335
348
|
rows and the step fails. Polars checks the row count of the frame the
|
|
336
|
-
replace already collects, at no extra cost
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
349
|
+
replace already collects, at no extra cost. Spark computes the frame once
|
|
350
|
+
with `localCheckpoint(eager=True)`, checks that result with `isEmpty()`,
|
|
351
|
+
writes it and then frees its blocks, as described under Fixes; a Spark
|
|
352
|
+
Connect DataFrame, which has no `localCheckpoint()` in pyspark 3.5, is
|
|
353
|
+
persisted, counted, written and unpersisted instead. On Polars a
|
|
354
|
+
`Null`-typed column still fails first, with `SchemaError`. On Spark a
|
|
355
|
+
streaming DataFrame, whose rows cannot be counted before the write, raises
|
|
356
|
+
`ValueError` and the table is left as it was.
|
|
341
357
|
The default, `allow_empty=True`, keeps today's behaviour, and `ReplaceSpec`
|
|
342
358
|
gains the `allow_empty` field.
|
|
343
359
|
- **etl:** `MaintenanceSpec`, `VacuumSpec`, `CompactSpec` and `ZOrderSpec` are
|
|
@@ -359,6 +375,34 @@
|
|
|
359
375
|
|
|
360
376
|
### core
|
|
361
377
|
|
|
378
|
+
- **core:** on a model with a composite primary key, the SQLAlchemy
|
|
379
|
+
repository's `get_by_id`, `exists`, `update` and `delete` take the key as a
|
|
380
|
+
tuple of every key value in declaration order (`repo.get_by_id((account_id,
|
|
381
|
+
entry_id))`) and raise `ValueError` for anything else, a scalar included,
|
|
382
|
+
instead of matching the first key column. A `Load` step and a cached
|
|
383
|
+
repository's `get_by_id`, `update` and `delete` pass the id unchanged, so a
|
|
384
|
+
scalar id raises there too; a cached `@cache_query(scope="entity")` read
|
|
385
|
+
takes the tuple as its first argument and raises `TypeError` for anything
|
|
386
|
+
else. A cursor token issued for such a model before this release is refused with
|
|
387
|
+
`UnsupportedQuery`, `400 unsupported_query`; clients restart from the first
|
|
388
|
+
page. `decode_cursor` takes `id_count`, the number of key columns, and
|
|
389
|
+
`get_id_attributes` returns every key column name.
|
|
390
|
+
|
|
391
|
+
- **core:** `compile_all` raises `ValueError` for a model with a composite
|
|
392
|
+
primary key that declares a relation or a projection whose loader runs
|
|
393
|
+
`load_many`, naming the model, its key and those fields. The backend loads
|
|
394
|
+
them by the first key column only, so a many-to-one relation attached
|
|
395
|
+
another owner's row and a one-to-many relation grouped children by that
|
|
396
|
+
column; load them by hand until they are matched by the full key.
|
|
397
|
+
|
|
398
|
+
- **core:** the `RepositoryMongo`, `RepositoryDynamoDB` and
|
|
399
|
+
`loom.testing.InMemoryRepository` constructors raise `ConfigError` for a
|
|
400
|
+
model with a composite primary key, naming the model and its key. Each
|
|
401
|
+
keys an item by one field (Mongo's `_id` and the DynamoDB partition key by
|
|
402
|
+
the first key column, the in-memory store by its `id_field`), so a second
|
|
403
|
+
row sharing that field's value raised `Conflict` on Mongo and DynamoDB and
|
|
404
|
+
replaced the first row in memory.
|
|
405
|
+
|
|
362
406
|
- **core:** the miss path of a cached `@cache_query`/`@cache_call` read,
|
|
363
407
|
`McpHandle.call` and `CacheGateway.get_value`/`multi_get_values` now raise
|
|
364
408
|
`BoundaryValidationError` — a `ValueError` — on a stale or malformed cached
|
|
@@ -370,6 +414,51 @@
|
|
|
370
414
|
|
|
371
415
|
### ai
|
|
372
416
|
|
|
417
|
+
- **ai:** `AgentPlan.fingerprint`, and so the ETL `agent_version` column,
|
|
418
|
+
changes once for every existing agent. It no longer covers any policy, so
|
|
419
|
+
changing `retries`, a timeout, `max_iterations`, `max_tool_calls`,
|
|
420
|
+
`max_requests`, a token cap, `max_usd`, `on_unpriced_spend` or
|
|
421
|
+
`max_history_bytes` keeps it; and it now covers the `include`/`exclude`
|
|
422
|
+
filters of `mcp` and `a2a` capabilities, so changing a filter changes it.
|
|
423
|
+
A step that keeps `agent_version` in its upsert keys and its anti-join
|
|
424
|
+
re-runs, and pays for, every row of the anti-join window on its next
|
|
425
|
+
execution after the upgrade.
|
|
426
|
+
- **ai:** in `PolarsAgentRunner.map`, a field of a pydantic output whose type
|
|
427
|
+
is another pydantic model is now a `Struct` column of that model's fields,
|
|
428
|
+
named by alias, instead of a `String` holding its JSON. Writing it into a
|
|
429
|
+
Delta table created before fails with `SchemaError` naming the column (see
|
|
430
|
+
the `etl` entry on casts between text and nested types). To keep writing to
|
|
431
|
+
that table, rewrite it once with the column decoded through the model,
|
|
432
|
+
`pl.Series(name, [None if c is None else Model.model_validate_json(c).model_dump(by_alias=True) for c in frame[name]], dtype=<the Struct type>)`,
|
|
433
|
+
and `schema=SchemaMode.OVERWRITE` (delta-rs `schema_mode="overwrite"`).
|
|
434
|
+
`pl.col(name).str.json_decode(<the Struct type>)` fails with
|
|
435
|
+
`ComputeError` when the model has a `date` field (Polars 1.39.3).
|
|
436
|
+
- **ai:** in `PolarsAgentRunner.map`, a `String` column holding a value's JSON
|
|
437
|
+
now holds the JSON of a string too: `"5"` is written `"\"5\""` and `5` is
|
|
438
|
+
written `5`, where both were `5`. This covers a field typed as a union of
|
|
439
|
+
several types, `Any` or a `Literal` mixing value types whose answer is a
|
|
440
|
+
string. A `UUID`, `time`, `timedelta` or `bytes` field keeps its plain text
|
|
441
|
+
(`P1D` is written `P1D`). Rows written before hold the raw string and rows
|
|
442
|
+
written after hold its JSON encoding. A cell alone does not always tell
|
|
443
|
+
them apart (an old `5` may have been the string `"5"`), but `agent_version`
|
|
444
|
+
does: every agent's fingerprint changes with this release, so the old rows
|
|
445
|
+
carry the old version. Re-run the old rows of such a field, or rewrite each
|
|
446
|
+
old cell whose answer was a string as the JSON encoding of its text.
|
|
447
|
+
- **ai:** the `agent_cost_usd` column `PolarsAgentRunner.map` writes is
|
|
448
|
+
`Decimal(38, 12)` instead of `Float64`, carrying `AgentUsage.cost` without a
|
|
449
|
+
float conversion, rounded half to even to 12 decimal places. Writing into a
|
|
450
|
+
Delta table created before does not fail: an append, upsert or replace with
|
|
451
|
+
`SchemaMode.STRICT` or `EVOLVE` casts the column back to the table's
|
|
452
|
+
`Float64`. To keep the decimal, rewrite the table once with the column cast
|
|
453
|
+
to `pl.Decimal(38, 12)` and `schema=SchemaMode.OVERWRITE` (delta-rs
|
|
454
|
+
`schema_mode="overwrite"`); the costs already stored keep the precision of
|
|
455
|
+
the float they were written as.
|
|
456
|
+
- **ai:** an `ai:` section with `max_concurrent_runs` below 1 fails to load
|
|
457
|
+
with `MAX_CONCURRENT_RUNS_INVALID`, naming the key and the minimum. Before,
|
|
458
|
+
it loaded; with `0` the runtime refused every run with `TOO_MANY_RUNS` and
|
|
459
|
+
`PolarsAgentRunner.map` on a frame with a prompt waited on a semaphore of
|
|
460
|
+
zero slots and did not return, and a negative value failed when the runtime
|
|
461
|
+
was built.
|
|
373
462
|
- **ai:** `load_specs`, and so `ai.specs`, refuses a glob that leaves the
|
|
374
463
|
root it resolves against — a `..` segment, an absolute pattern or a match
|
|
375
464
|
that resolves outside the root through a symlink — with
|
|
@@ -396,6 +485,10 @@
|
|
|
396
485
|
|
|
397
486
|
### rest
|
|
398
487
|
|
|
488
|
+
- **rest:** auto-CRUD mounts no `/{id}` route (get, update, delete) for a
|
|
489
|
+
model with a composite primary key, since one path segment cannot carry the
|
|
490
|
+
key; naming one of them in `include` raises `ValueError` when the routes are
|
|
491
|
+
built. Those routes matched the first key column only.
|
|
399
492
|
- **rest:** a JSON object body that fails `Command` validation now answers
|
|
400
493
|
`422 boundary_validation` with a `violations` list (`{field, message}`
|
|
401
494
|
pairs, `field` being the wire name the client sent, the same shape
|
|
@@ -446,14 +539,41 @@
|
|
|
446
539
|
- **prefect:** the private `_deploy_single(flow, meta, work_pool, env)` of
|
|
447
540
|
`loom.prefect.deploy._discovery` now takes `(flow, meta, plan)`; callers
|
|
448
541
|
migrate to the public `deploy_flow(flow, env=..., work_pool=...)`.
|
|
542
|
+
- **prefect:** `discover_and_deploy_etls(flows_package=...)` checks every
|
|
543
|
+
flow of the package, its work pool and that its module exposes it under its
|
|
544
|
+
attribute name as `deploy_flow` does, before it registers the first
|
|
545
|
+
deployment. A flow without a work pool for the environment, one its module
|
|
546
|
+
exposes under another attribute name, or one whose source file cannot be
|
|
547
|
+
imported raises `ValueError` and no deployment of the package is
|
|
548
|
+
registered. Flows used to be registered one by one: a flow without a work
|
|
549
|
+
pool raised after the flows before it were registered, and a flow exposed
|
|
550
|
+
under another name or not importable from its source file was registered
|
|
551
|
+
with an entrypoint the worker cannot import.
|
|
449
552
|
|
|
450
553
|
### etl
|
|
451
554
|
|
|
555
|
+
- **etl:** a `WithAgent` compiled by a runner whose config has no `ai:`
|
|
556
|
+
section fails with the new code `AGENT_RUNNER_NOT_CONFIGURED` instead of
|
|
557
|
+
`AGENT_NOT_FOUND`, which now means only that no artifact declares the name.
|
|
452
558
|
- **etl:** the names of `loom.etl.runner.filtering` (`_filter_plan`,
|
|
453
559
|
`_filter_process`, `_collect_all_names`, `_map_pipeline_nodes`,
|
|
454
560
|
`_map_process_nodes`) are deprecated and removed in loom 3.0; each emits a
|
|
455
561
|
`DeprecationWarning` naming its replacement, `loom.etl.compiler.filter_plan`
|
|
456
562
|
or, for `_collect_all_names`, `iter_processes` and `iter_all_steps`.
|
|
563
|
+
- **etl:** the Polars writer refuses, under `SchemaMode.STRICT` and
|
|
564
|
+
`EVOLVE`, a frame column that is a `Struct` or `List` where the Delta table
|
|
565
|
+
has `String`, or `String` where the table has a `Struct` or `List`, at any
|
|
566
|
+
depth of a `Struct` or `List`, with `SchemaError` naming the column and
|
|
567
|
+
both types; nothing is written. The check is by dtype, so an all-null
|
|
568
|
+
`String` column written into a `List` column is refused too. Before, a
|
|
569
|
+
`Struct` was cast to its Polars display text (`{1.0}` for a `Float64`
|
|
570
|
+
field) and a `String` to a `List` wrapped or nulled each value, both
|
|
571
|
+
written without an error; a `List` to `String` and a `String` to `Struct`
|
|
572
|
+
failed inside Polars. The Spark writer does not refuse these casts: it
|
|
573
|
+
writes a `Struct` or `List` into a `String` column as text (`{1.0}`,
|
|
574
|
+
`[1]`). To change the column's type,
|
|
575
|
+
rewrite the table once with the column converted and
|
|
576
|
+
`schema=SchemaMode.OVERWRITE` (delta-rs `schema_mode="overwrite"`).
|
|
457
577
|
- **etl:** `InvalidStageError` names what it reports: its message reads
|
|
458
578
|
`Unknown step or process names: [...]` instead of `No steps or processes
|
|
459
579
|
match include=[...]`, the constructor's parameter is `unknown`, and the
|
|
@@ -461,11 +581,48 @@
|
|
|
461
581
|
unchanged; `InvalidStageError(include=...)` still works, emits a
|
|
462
582
|
`DeprecationWarning` and is removed in loom 3.0. The error survives pickle
|
|
463
583
|
with its `unknown` names, so it crosses process boundaries intact.
|
|
584
|
+
- **etl:** `ThreadDispatcher` runs each task in a copy of the caller's
|
|
585
|
+
context, as `asyncio.to_thread` does, so a step of a parallel group sees
|
|
586
|
+
the `ContextVar` values of the run that dispatched it (the Prefect flow run
|
|
587
|
+
among them) and its OpenTelemetry context. A parallel group's step spans
|
|
588
|
+
therefore nest under their process span instead of starting a trace of
|
|
589
|
+
their own. `ParallelDispatcher` lists running each task in a copy of the
|
|
590
|
+
caller's context among the requirements on an implementation.
|
|
591
|
+
- **etl:** `WithAgent(max_usd=...)` keeps the budget as a `Decimal`. An
|
|
592
|
+
`int`, or another `numbers.Integral` such as `numpy.int64`, is converted
|
|
593
|
+
exactly. A `float` emits a `DeprecationWarning`, is converted through its
|
|
594
|
+
`str()` (`0.1` becomes `Decimal("0.1")`) and is removed in loom 3.0. A
|
|
595
|
+
`bool`, accepted before, and any other type, such as `str`, raise
|
|
596
|
+
`TypeError`. `NaN`, `sNaN` and `Infinity`, as a `Decimal` or a `float`,
|
|
597
|
+
raise `ValueError`, like zero and a negative amount; a `Decimal` `NaN` or
|
|
598
|
+
`sNaN` used to raise `decimal.InvalidOperation`, and a `Decimal`
|
|
599
|
+
`Infinity`, a `float` `inf` and a `float` `nan` were accepted.
|
|
464
600
|
|
|
465
601
|
## 🐛 Fixes
|
|
466
602
|
|
|
467
603
|
### core
|
|
468
604
|
|
|
605
|
+
- **core:** cursor pagination and the by-id operations of the SQLAlchemy
|
|
606
|
+
repository use the full primary key of a model whose key is composite, such
|
|
607
|
+
as a `RowScoped` model keyed by its boundary column and its own id. They
|
|
608
|
+
used only the first key column: a cursor walk ordered and compared on it
|
|
609
|
+
alone and skipped the rows sharing that column's value with the last row of
|
|
610
|
+
each page, and `get_by_id`, `exists`, `update` and `delete` matched that
|
|
611
|
+
column only. The cursor now orders and compares on
|
|
612
|
+
every key column after the sort keys and carries every key value in the
|
|
613
|
+
token; offset pages and `list_paginated` order by every key column too.
|
|
614
|
+
Tokens of single-column keys are unchanged. A cached repository over such a
|
|
615
|
+
model keyed its entries by the first key column too, so a warm
|
|
616
|
+
`list_paginated` or first cursor page served the rows sharing a first key
|
|
617
|
+
value as copies of one of them; it now caches and reloads every row by its
|
|
618
|
+
full key, one `get_by_id` per missing row.
|
|
619
|
+
|
|
620
|
+
- **core:** a `MANY_TO_MANY` relation joins the target table on the column
|
|
621
|
+
the secondary table's foreign key references. It joined on the target
|
|
622
|
+
model's first key column, so a target with a composite key, or whose link
|
|
623
|
+
references a unique non-key column, loaded the rows whose first key column
|
|
624
|
+
held the linked value instead of the linked rows.
|
|
625
|
+
|
|
469
626
|
- **core:** the RLS guard refuses, in the same statement, a drop outside the
|
|
470
627
|
hatch that breaks its invariants. `DROP POLICY` or `DROP TRIGGER
|
|
471
628
|
loom_deny_owner_dml` on a scoped table used to commit, because drops are not
|
|
@@ -491,6 +648,42 @@
|
|
|
491
648
|
|
|
492
649
|
### etl
|
|
493
650
|
|
|
651
|
+
- **etl:** `replace(allow_empty=False)` on Spark writes the rows it checked.
|
|
652
|
+
The writer ran `DataFrame.isEmpty()` and then let the write compute the
|
|
653
|
+
frame again, so a source that changed in between, or a nondeterministic
|
|
654
|
+
plan, could still replace the table with no rows. The frame is now
|
|
655
|
+
computed once with `localCheckpoint(eager=True)`, and the check and the
|
|
656
|
+
write both read that result. Those rows are kept in executor storage, not
|
|
657
|
+
in reliable storage: losing an executor before the write ends fails the
|
|
658
|
+
write instead of recomputing the frame. Once the write ends, whether it
|
|
659
|
+
succeeded or failed, and when the check refuses the frame, the writer
|
|
660
|
+
unpersists the checkpointed RDD, so its blocks do not stay on the executors
|
|
661
|
+
for the rest of the session. A Spark Connect DataFrame has no
|
|
662
|
+
`localCheckpoint()` in pyspark 3.5: it is persisted with `MEMORY_AND_DISK`,
|
|
663
|
+
counted, written and unpersisted. That is weaker: Spark recomputes a cached
|
|
664
|
+
block it loses, so the write may read rows other than the ones counted.
|
|
665
|
+
Persisting and unpersisting go through Spark's shared cache manager, which
|
|
666
|
+
matches cached data by plan, so a frame with a plan equivalent to the
|
|
667
|
+
written frame's, cached before the write, is unpersisted too. Freeing the
|
|
668
|
+
rows is best effort: a failure is logged as a warning and never replaces
|
|
669
|
+
the outcome of the write, its error or `EmptyReplaceError`. The write
|
|
670
|
+
policy's `_is_empty` hook becomes `_pin_rows`, which returns the frame to
|
|
671
|
+
write along with whether it is empty, and gains `_release_pinned`, which
|
|
672
|
+
frees what `_pin_rows` kept and must not raise.
|
|
673
|
+
- **etl:** the Polars checkpoint store memory-maps only a local checkpoint.
|
|
674
|
+
It recognised cloud URIs by a lower-case prefix list without `r2://`, so a
|
|
675
|
+
checkpoint under `r2://` or an upper-case scheme such as `S3://` was read
|
|
676
|
+
with `memory_map=True`; it now uses the scheme set of
|
|
677
|
+
`loom.etl._uri`, compared case-insensitively.
|
|
678
|
+
- **etl:** documentation states what the writers do. `replace(streaming=...)`
|
|
679
|
+
and `ReplaceSpec.streaming` claimed a streaming Arrow write on Polars; no
|
|
680
|
+
backend reads the flag for a full replace, and the collect engine follows
|
|
681
|
+
the step's `streaming` attribute. `vacuum(full=True)` warns, in the guide
|
|
682
|
+
and in `VacuumSpec`, `MaintainTable.vacuum` and `MaintenanceVacuumConfig`,
|
|
683
|
+
that it deletes every unreferenced file under the table directory older
|
|
684
|
+
than the retention, whoever wrote it. The pipelines page states that
|
|
685
|
+
`replace_where` with an empty frame deletes the rows matching its
|
|
686
|
+
predicate.
|
|
494
687
|
- **etl:** `upsert` and `update` on the Polars backend write with the route's
|
|
495
688
|
`writer` and `commit` settings. The delta-rs MERGE received neither, so the
|
|
496
689
|
Parquet files it rewrote came out with delta-rs defaults (SNAPPY, row groups
|
|
@@ -534,6 +727,20 @@
|
|
|
534
727
|
|
|
535
728
|
### ai
|
|
536
729
|
|
|
730
|
+
- **ai:** `PolarsAgentRunner.map` runs at most `ai.max_concurrent_runs`
|
|
731
|
+
worker tasks, which take the rows in order, instead of creating one task
|
|
732
|
+
per row up front; the order of the output rows is unchanged. A run
|
|
733
|
+
cancelled while the batch was not raises a `RuntimeError` naming how many
|
|
734
|
+
rows were left without an outcome and the first of them, where the run's
|
|
735
|
+
`asyncio.CancelledError` reached the caller.
|
|
736
|
+
- **ai:** `PolarsAgentRunner.validate` reports an output with a field no
|
|
737
|
+
column can hold (a union of two models, for instance) as
|
|
738
|
+
`OUTPUT_MISMATCH` instead of raising its `TypeError`, and checks the output
|
|
739
|
+
columns before asking whether the model is priced.
|
|
740
|
+
- **ai:** an agent output type that contains itself, directly
|
|
741
|
+
(`children: list[Node]`) or through another type, no longer makes
|
|
742
|
+
`PolarsAgentRunner.validate` and `map` fail with `RecursionError`: the
|
|
743
|
+
repeated struct or pydantic model is a `String` column holding its JSON.
|
|
537
744
|
- **ai:** a configured `ai.prices` rate prices runs again with pydantic-ai
|
|
538
745
|
2.54. That release records a response's usage before the
|
|
539
746
|
`after_model_request` hook loom priced it in, so every run reported
|
|
@@ -573,6 +780,22 @@
|
|
|
573
780
|
`SERVICE_UNAVAILABLE`, which `HttpErrorMapper` maps to `503`. Any other
|
|
574
781
|
exception from the authenticator, and the `401` refusal, are unchanged.
|
|
575
782
|
|
|
783
|
+
### prefect
|
|
784
|
+
|
|
785
|
+
- **prefect:** every log line the bridge sends carries the run's
|
|
786
|
+
`flow_run_id`, and a step's line its `task_run_id` as well. A step's lines
|
|
787
|
+
went out with `task_run_id` only, so a reader scoping a run's logs by flow
|
|
788
|
+
run, such as Prefect's flow run view, missed every step line; a step of a
|
|
789
|
+
parallel group now keeps the flow run too, through `ThreadDispatcher`'s
|
|
790
|
+
context copy. A line emitted inside a step with no flow run bound omits
|
|
791
|
+
`flow_run_id` instead of sending `null`.
|
|
792
|
+
- **prefect:** `deploy_flow` refuses a flow built from a YAML declaration
|
|
793
|
+
with a `TypeError` naming `discover_and_deploy_etls(config=...)`, which
|
|
794
|
+
deploys it, instead of the entrypoint module's `ConfigError`. When the flow
|
|
795
|
+
module's `__getattr__` raises anything but `AttributeError` while the flow
|
|
796
|
+
is looked up, `deploy_flow` raises its documented `ValueError`, chained to
|
|
797
|
+
that exception.
|
|
798
|
+
|
|
576
799
|
## ♻️ Refactor
|
|
577
800
|
|
|
578
801
|
### etl
|
|
@@ -591,6 +814,12 @@
|
|
|
591
814
|
spec type than the protocol it is dispatched through; it now accepts the
|
|
592
815
|
protocol's type and refuses a spec of another kind with a `TypeError`,
|
|
593
816
|
which the registry's dispatch by kind already made unreachable.
|
|
817
|
+
- **etl:** `PolarsSourceReader` decodes JSON columns through
|
|
818
|
+
`decode_json_columns`; the private `_apply_json_decode` staticmethod and
|
|
819
|
+
module function of `loom.etl.backends.polars._reader` are removed.
|
|
820
|
+
- **etl:** the private `_is_cloud_path` of `loom.etl.checkpoint._cleaners`
|
|
821
|
+
moves, with the same scheme set, to `loom.etl._uri.is_cloud_path`,
|
|
822
|
+
and the Polars backend defines its frame type variable once.
|
|
594
823
|
|
|
595
824
|
# 🚀 Release 2.1.2 ([#238](https://github.com/the-reacher-data/loom-py/pull/238))
|
|
596
825
|
|
|
@@ -18,32 +18,22 @@ _CAPABILITY_NAMES: Final[Mapping[str, tuple[str, ...]]] = MappingProxyType(
|
|
|
18
18
|
{
|
|
19
19
|
"usecase": ("keys",),
|
|
20
20
|
"sql": ("connection",),
|
|
21
|
-
"mcp": ("server",),
|
|
21
|
+
"mcp": ("server", "include", "exclude"),
|
|
22
22
|
"skills": ("library", "names"),
|
|
23
23
|
"python": ("factory_ref",),
|
|
24
|
-
"a2a": ("agent",),
|
|
24
|
+
"a2a": ("agent", "include", "exclude"),
|
|
25
25
|
"native": ("tool",),
|
|
26
26
|
}
|
|
27
27
|
)
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
def plan_fingerprint(plan: AgentPlan) -> str:
|
|
31
|
-
"""Return the sha256
|
|
32
|
-
|
|
33
|
-
Args:
|
|
34
|
-
plan: Compiled plan.
|
|
35
|
-
|
|
36
|
-
Returns:
|
|
37
|
-
Hex digest over the instructions, output schema and check, policies,
|
|
38
|
-
format version, the kind and name of every capability and the model
|
|
39
|
-
binding, without the deployment details.
|
|
40
|
-
"""
|
|
31
|
+
"""Return the sha256 behind :attr:`AgentPlan.fingerprint`, which states what it covers."""
|
|
41
32
|
facts = {
|
|
42
33
|
"spec_version": plan.spec_version,
|
|
43
34
|
"instructions": [[block.text, block.template] for block in plan.instructions],
|
|
44
35
|
"output_schema": plan.output.schema,
|
|
45
36
|
"output_check": _reference(plan.output_check),
|
|
46
|
-
"policies": plan.policies,
|
|
47
37
|
"capabilities": [_capability(capability) for capability in plan.capabilities],
|
|
48
38
|
"provider": plan.inference.provider,
|
|
49
39
|
"model": plan.inference.model,
|
|
@@ -408,16 +408,24 @@ class AgentPlan(LoomFrozenStruct, frozen=True, kw_only=True):
|
|
|
408
408
|
|
|
409
409
|
@property
|
|
410
410
|
def fingerprint(self) -> str:
|
|
411
|
-
"""Stable sha256 of
|
|
412
|
-
|
|
413
|
-
Covers the
|
|
414
|
-
|
|
415
|
-
capability
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
411
|
+
"""Stable sha256 of the declared facts that decide this agent's answers.
|
|
412
|
+
|
|
413
|
+
Covers the format version, the instructions as compiled, the output
|
|
414
|
+
schema, the output check, the kind and declared facts of every
|
|
415
|
+
capability (use case keys, SQL connection, MCP server, skill library
|
|
416
|
+
and names, Python factory reference, A2A agent, native tool, and the
|
|
417
|
+
``include``/``exclude`` filters of MCP and A2A) and the bound
|
|
418
|
+
provider, model, output mode and options. It covers what the plan
|
|
419
|
+
declares, not the content of the skills, tools or use cases it names:
|
|
420
|
+
editing a skill's text or a tool's code keeps the fingerprint. Leaves
|
|
421
|
+
out the name, description, metadata, provenance, configured price,
|
|
422
|
+
every policy (each bounds a run and fails it past that bound;
|
|
423
|
+
``max_history_bytes`` also withholds from the hook a history above
|
|
424
|
+
it; none decides the content of an accepted answer), where a
|
|
425
|
+
capability is served from (URL, directory, credentials, timeouts) and
|
|
426
|
+
the binding's region, endpoint, credentials and streaming flag. The
|
|
427
|
+
output check enters by its import path, so editing the check's body
|
|
428
|
+
keeps the fingerprint.
|
|
421
429
|
"""
|
|
422
430
|
return plan_fingerprint(self)
|
|
423
431
|
|
|
@@ -28,6 +28,7 @@ from loom.ai.errors import (
|
|
|
28
28
|
endpoint_auth_missing,
|
|
29
29
|
inference_target_incomplete,
|
|
30
30
|
max_agent_depth_invalid,
|
|
31
|
+
max_concurrent_runs_invalid,
|
|
31
32
|
mcp_auth_conflict,
|
|
32
33
|
mcp_auth_strategy_unknown,
|
|
33
34
|
mcp_credentials_inline,
|
|
@@ -343,7 +344,8 @@ class AiConfig(LoomFrozenStruct, frozen=True, kw_only=True):
|
|
|
343
344
|
prices: Prices keyed by vendor model id (``InferenceTarget.model``).
|
|
344
345
|
A plan bound to a listed model is priced with these rates rather
|
|
345
346
|
than the engine's own, which is what keeps ``policies.max_usd``
|
|
346
|
-
enforceable for a model the engine cannot price.
|
|
347
|
+
enforceable for a model the engine cannot price. A key no
|
|
348
|
+
binding of ``models`` names is logged as a warning.
|
|
347
349
|
skills_root: Filesystem root bare skill library names resolve against.
|
|
348
350
|
mcp_servers: Named remote MCP servers artifacts refer to by name.
|
|
349
351
|
a2a_agents: Named remote A2A agents artifacts refer to by name.
|
|
@@ -361,7 +363,8 @@ class AiConfig(LoomFrozenStruct, frozen=True, kw_only=True):
|
|
|
361
363
|
that did open and whose tool listing times out still fails
|
|
362
364
|
start-up, and no client becomes lazy — one that never opened is
|
|
363
365
|
not reconnected later.
|
|
364
|
-
max_concurrent_runs: Per-worker run limit (FR-033a)
|
|
366
|
+
max_concurrent_runs: Per-worker run limit (FR-033a); below 1 the
|
|
367
|
+
config fails with ``MAX_CONCURRENT_RUNS_INVALID``.
|
|
365
368
|
max_prompt_bytes: Enforced while reading the request body, against
|
|
366
369
|
the ``prompt`` field alone (FR-015).
|
|
367
370
|
max_state_bytes: Enforced while reading the request body, against the
|
|
@@ -422,8 +425,21 @@ class AiConfig(LoomFrozenStruct, frozen=True, kw_only=True):
|
|
|
422
425
|
issues.append(remote_clients_unknown(self.remote_clients, _REMOTE_CLIENTS_MODES))
|
|
423
426
|
if self.max_agent_depth < 1:
|
|
424
427
|
issues.append(max_agent_depth_invalid(self.max_agent_depth))
|
|
428
|
+
if self.max_concurrent_runs < 1:
|
|
429
|
+
issues.append(max_concurrent_runs_invalid(self.max_concurrent_runs))
|
|
425
430
|
if issues:
|
|
426
431
|
raise AgentCompilationError(issues)
|
|
432
|
+
_warn_unused_prices(self.prices, self.models)
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
def _warn_unused_prices(
|
|
436
|
+
prices: Mapping[str, ModelPrice], models: Mapping[str, InferenceTarget]
|
|
437
|
+
) -> None:
|
|
438
|
+
bound = {target.model for target in models.values()}
|
|
439
|
+
for model in sorted(prices.keys() - bound):
|
|
440
|
+
_logger.warning(
|
|
441
|
+
"ai.prices[%r] names no model of ai.models; no run is priced with it", model
|
|
442
|
+
)
|
|
427
443
|
|
|
428
444
|
|
|
429
445
|
_UrlIssue = Callable[[str, str, str], AgentCompilationIssue]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Spend caps projected onto the engine's own ``UsageLimits
|
|
1
|
+
"""Spend caps projected onto the engine's own ``UsageLimits``, and the pricing of its responses.
|
|
2
2
|
|
|
3
3
|
``PolicySpec`` carries five caps (FR-040), four of them optional and one,
|
|
4
4
|
``max_requests``, always set to a default; :func:`usage_limits` projects all
|
|
@@ -155,6 +155,7 @@ class AgentErrorCode(StrEnum):
|
|
|
155
155
|
AGENT_SPECS_ESCAPE_ROOT = "AGENT_SPECS_ESCAPE_ROOT"
|
|
156
156
|
REMOTE_CLIENTS_UNKNOWN = "REMOTE_CLIENTS_UNKNOWN"
|
|
157
157
|
MAX_AGENT_DEPTH_INVALID = "MAX_AGENT_DEPTH_INVALID"
|
|
158
|
+
MAX_CONCURRENT_RUNS_INVALID = "MAX_CONCURRENT_RUNS_INVALID"
|
|
158
159
|
|
|
159
160
|
# Use-case agent markers (model-as-actor)
|
|
160
161
|
AGENT_MARKER_UNKNOWN = "AGENT_MARKER_UNKNOWN"
|
|
@@ -1317,6 +1318,23 @@ def max_agent_depth_invalid(value: int) -> AgentCompilationIssue:
|
|
|
1317
1318
|
)
|
|
1318
1319
|
|
|
1319
1320
|
|
|
1321
|
+
def max_concurrent_runs_invalid(value: int) -> AgentCompilationIssue:
|
|
1322
|
+
"""The run limit admits no run.
|
|
1323
|
+
|
|
1324
|
+
Args:
|
|
1325
|
+
value: The rejected value of ``ai.max_concurrent_runs``.
|
|
1326
|
+
"""
|
|
1327
|
+
return AgentCompilationIssue(
|
|
1328
|
+
code=AgentErrorCode.MAX_CONCURRENT_RUNS_INVALID,
|
|
1329
|
+
message=(
|
|
1330
|
+
f"ai.max_concurrent_runs: {value} is below the minimum of 1; a worker "
|
|
1331
|
+
"with no run slot refuses every run and an ETL batch answers no row"
|
|
1332
|
+
),
|
|
1333
|
+
component="ai",
|
|
1334
|
+
field="ai.max_concurrent_runs",
|
|
1335
|
+
)
|
|
1336
|
+
|
|
1337
|
+
|
|
1320
1338
|
# ---------------------------------------------------------------------------
|
|
1321
1339
|
# Compatibility factories
|
|
1322
1340
|
# ---------------------------------------------------------------------------
|
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import logging
|
|
7
|
-
from collections.abc import Callable, Mapping, Sequence
|
|
7
|
+
from collections.abc import Callable, Iterator, Mapping, Sequence
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
from decimal import Decimal
|
|
10
10
|
from typing import Any, Final
|
|
@@ -58,21 +58,43 @@ class Batch:
|
|
|
58
58
|
to_builtins: Callable[[Any], Mapping[str, Any]]
|
|
59
59
|
|
|
60
60
|
async def answer_all(self, prompts: Sequence[str | None]) -> list[RowOutcome]:
|
|
61
|
-
"""Enter the runtime, answer every prompt in order, and close it in the same task.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return list(await asyncio.gather(*(self._answer(p, slots, identity) for p in prompts)))
|
|
61
|
+
"""Enter the runtime, answer every prompt in order, and close it in the same task.
|
|
62
|
+
|
|
63
|
+
*limit* workers take the prompts in order from one shared iterator, so
|
|
64
|
+
the batch creates at most *limit* tasks whatever the number of rows.
|
|
66
65
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
Raises:
|
|
67
|
+
RuntimeError: A run was cancelled while the batch was not, so its
|
|
68
|
+
worker stopped and left rows without an outcome.
|
|
69
|
+
"""
|
|
70
|
+
identity = Identity(subject=f"etl:{self.name}")
|
|
71
|
+
outcomes: list[RowOutcome | None] = [None] * len(prompts)
|
|
72
|
+
pending = iter(enumerate(prompts))
|
|
73
|
+
async with self.runtime, asyncio.TaskGroup() as workers:
|
|
74
|
+
for _ in range(min(self.limit, len(prompts))):
|
|
75
|
+
workers.create_task(self._work(pending, outcomes, identity))
|
|
76
|
+
if None in outcomes:
|
|
77
|
+
raise RuntimeError(
|
|
78
|
+
f"agent {self.name!r} left {outcomes.count(None)} row(s) without an outcome, the "
|
|
79
|
+
f"first row {outcomes.index(None)}: a run was cancelled while the batch was not"
|
|
80
|
+
)
|
|
81
|
+
return [outcome for outcome in outcomes if outcome is not None]
|
|
82
|
+
|
|
83
|
+
async def _work(
|
|
84
|
+
self,
|
|
85
|
+
pending: Iterator[tuple[int, str | None]],
|
|
86
|
+
outcomes: list[RowOutcome | None],
|
|
87
|
+
identity: Identity,
|
|
88
|
+
) -> None:
|
|
89
|
+
for row, prompt in pending:
|
|
90
|
+
outcomes[row] = await self._answer(prompt, identity)
|
|
91
|
+
|
|
92
|
+
async def _answer(self, prompt: str | None, identity: Identity) -> RowOutcome:
|
|
70
93
|
if prompt is None:
|
|
71
94
|
return RowOutcome(output=None, error=PROMPT_MISSING, usage=None)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return await self._run(prompt, identity)
|
|
95
|
+
if not self.ledger.reserve(self.reservation):
|
|
96
|
+
return RowOutcome(output=None, error=BUDGET_EXHAUSTED, usage=None)
|
|
97
|
+
return await self._run(prompt, identity)
|
|
76
98
|
|
|
77
99
|
async def _run(self, prompt: str, identity: Identity) -> RowOutcome:
|
|
78
100
|
usage: AgentUsage | None = None
|