corvic-engine 0.3.0rc46__tar.gz → 0.3.0rc48__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/Cargo.lock +6 -6
  2. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/Cargo.toml +1 -1
  3. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/PKG-INFO +1 -1
  4. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/pyproject.toml +2 -2
  5. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_agent.py +35 -1
  6. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_base_model.py +2 -1
  7. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_feature_view.py +3 -1
  8. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_proto_orm_convert.py +52 -3
  9. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_resource.py +1 -2
  10. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/orm/__init__.py +4 -12
  11. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/pa_scalar/_to_value.py +47 -2
  12. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/pa_scalar/_types.py +2 -0
  13. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system/__init__.py +0 -2
  14. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system/storage.py +50 -74
  15. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system_sqlite/client.py +0 -1
  16. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system_sqlite/staging.py +11 -6
  17. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/table/table.py +17 -13
  18. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/LICENSE +0 -0
  19. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/README.md +0 -0
  20. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/Cargo.toml +0 -0
  21. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/buf/validate/expression_pb2.py +0 -0
  22. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/buf/validate/expression_pb2.pyi +0 -0
  23. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/buf/validate/expression_pb2_grpc.py +0 -0
  24. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/buf/validate/expression_pb2_grpc.pyi +0 -0
  25. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/buf/validate/priv/private_pb2.py +0 -0
  26. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/buf/validate/priv/private_pb2.pyi +0 -0
  27. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/buf/validate/priv/private_pb2_grpc.py +0 -0
  28. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/buf/validate/priv/private_pb2_grpc.pyi +0 -0
  29. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/buf/validate/validate_pb2.py +0 -0
  30. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/buf/validate/validate_pb2.pyi +0 -0
  31. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/buf/validate/validate_pb2_grpc.py +0 -0
  32. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/buf/validate/validate_pb2_grpc.pyi +0 -0
  33. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/context/__init__.py +0 -0
  34. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/context/py.typed +0 -0
  35. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/embed/__init__.py +0 -0
  36. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/embed/node2vec.py +0 -0
  37. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/embed/py.typed +0 -0
  38. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/embedding_metric/__init__.py +0 -0
  39. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/embedding_metric/embeddings.py +0 -0
  40. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/embedding_metric/py.typed +0 -0
  41. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/engine/__init__.py +0 -0
  42. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/engine/_native.pyi +0 -0
  43. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/engine/py.typed +0 -0
  44. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/__init__.py +0 -0
  45. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_completion_model.py +0 -0
  46. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_defaults.py +0 -0
  47. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_errors.py +0 -0
  48. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_feature_type.py +0 -0
  49. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_pipeline.py +0 -0
  50. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_room.py +0 -0
  51. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_source.py +0 -0
  52. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/_space.py +0 -0
  53. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/model/py.typed +0 -0
  54. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/__init__.py +0 -0
  55. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/_schema.py +0 -0
  56. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/_transformations.py +0 -0
  57. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/aggregation.py +0 -0
  58. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/encoders.py +0 -0
  59. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/errors.py +0 -0
  60. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/feature_types.py +0 -0
  61. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/ops.py +0 -0
  62. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/py.typed +0 -0
  63. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/row_filters/__init__.py +0 -0
  64. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/row_filters/_jsonlogic.py +0 -0
  65. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/row_filters/_row_filters.py +0 -0
  66. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/op_graph/sample_strategy.py +0 -0
  67. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/orm/_proto_columns.py +0 -0
  68. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/orm/base.py +0 -0
  69. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/orm/errors.py +0 -0
  70. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/orm/func/__init__.py +0 -0
  71. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/orm/func/utc_func.py +0 -0
  72. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/orm/func/uuid_func.py +0 -0
  73. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/orm/ids.py +0 -0
  74. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/orm/keys.py +0 -0
  75. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/orm/mixins.py +0 -0
  76. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/orm/py.typed +0 -0
  77. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/pa_scalar/__init__.py +0 -0
  78. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/pa_scalar/_const.py +0 -0
  79. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/pa_scalar/_from_value.py +0 -0
  80. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/pa_scalar/_temporal.py +0 -0
  81. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/pa_scalar/py.typed +0 -0
  82. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/proto_wrapper/__init__.py +0 -0
  83. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/proto_wrapper/_errors.py +0 -0
  84. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/proto_wrapper/_wrappers.py +0 -0
  85. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/proto_wrapper/py.typed +0 -0
  86. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/result/__init__.py +0 -0
  87. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/result/py.typed +0 -0
  88. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/sql/__init__.py +0 -0
  89. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/sql/parse_ops.py +0 -0
  90. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/sql/py.typed +0 -0
  91. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system/_dimension_reduction.py +0 -0
  92. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system/_embedder.py +0 -0
  93. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system/_image_embedder.py +0 -0
  94. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system/_planner.py +0 -0
  95. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system/_text_embedder.py +0 -0
  96. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system/client.py +0 -0
  97. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system/in_memory_executor.py +0 -0
  98. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system/op_graph_executor.py +0 -0
  99. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system/py.typed +0 -0
  100. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system/staging.py +0 -0
  101. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system_sqlite/__init__.py +0 -0
  102. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system_sqlite/fs_blob_store.py +0 -0
  103. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system_sqlite/py.typed +0 -0
  104. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/system_sqlite/rdbms_blob_store.py +0 -0
  105. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/table/__init__.py +0 -0
  106. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/table/py.typed +0 -0
  107. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/version/__init__.py +0 -0
  108. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/version/py.typed +0 -0
  109. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/well_known_types/__init__.py +0 -0
  110. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic/well_known_types/py.typed +0 -0
  111. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/__init__.py +0 -0
  112. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/algorithm/__init__.py +0 -0
  113. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/algorithm/graph/__init__.py +0 -0
  114. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/algorithm/graph/v1/__init__.py +0 -0
  115. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/algorithm/graph/v1/graph_pb2.py +0 -0
  116. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/algorithm/graph/v1/graph_pb2.pyi +0 -0
  117. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/algorithm/graph/v1/graph_pb2_grpc.py +0 -0
  118. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/algorithm/graph/v1/graph_pb2_grpc.pyi +0 -0
  119. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/chat/__init__.py +0 -0
  120. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/chat/v1/__init__.py +0 -0
  121. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/chat/v1/service_pb2.py +0 -0
  122. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/chat/v1/service_pb2.pyi +0 -0
  123. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/chat/v1/service_pb2_grpc.py +0 -0
  124. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/chat/v1/service_pb2_grpc.pyi +0 -0
  125. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/completion/__init__.py +0 -0
  126. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/completion/v1/__init__.py +0 -0
  127. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/completion/v1/service_pb2.py +0 -0
  128. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/completion/v1/service_pb2.pyi +0 -0
  129. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/completion/v1/service_pb2_grpc.py +0 -0
  130. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/completion/v1/service_pb2_grpc.pyi +0 -0
  131. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/config/__init__.py +0 -0
  132. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/config/v1/__init__.py +0 -0
  133. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/config/v1/settings_pb2.py +0 -0
  134. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/config/v1/settings_pb2.pyi +0 -0
  135. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/config/v1/settings_pb2_grpc.py +0 -0
  136. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/config/v1/settings_pb2_grpc.pyi +0 -0
  137. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/embedding/__init__.py +0 -0
  138. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/embedding/v1/__init__.py +0 -0
  139. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/embedding/v1/models_pb2.py +0 -0
  140. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/embedding/v1/models_pb2.pyi +0 -0
  141. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/embedding/v1/models_pb2_grpc.py +0 -0
  142. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/embedding/v1/models_pb2_grpc.pyi +0 -0
  143. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/__init__.py +0 -0
  144. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v1/__init__.py +0 -0
  145. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v1/experiment_pb2.py +0 -0
  146. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v1/experiment_pb2.pyi +0 -0
  147. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v1/experiment_pb2_grpc.py +0 -0
  148. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v1/experiment_pb2_grpc.pyi +0 -0
  149. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v1/space_pb2.py +0 -0
  150. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v1/space_pb2.pyi +0 -0
  151. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v1/space_pb2_grpc.py +0 -0
  152. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v1/space_pb2_grpc.pyi +0 -0
  153. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v2/__init__.py +0 -0
  154. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v2/feature_view_pb2.py +0 -0
  155. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v2/feature_view_pb2.pyi +0 -0
  156. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v2/feature_view_pb2_grpc.py +0 -0
  157. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v2/feature_view_pb2_grpc.pyi +0 -0
  158. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v2/space_pb2.py +0 -0
  159. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v2/space_pb2.pyi +0 -0
  160. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v2/space_pb2_grpc.py +0 -0
  161. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/feature/v2/space_pb2_grpc.pyi +0 -0
  162. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/__init__.py +0 -0
  163. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v1/__init__.py +0 -0
  164. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v1/service_pb2.py +0 -0
  165. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v1/service_pb2.pyi +0 -0
  166. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v1/service_pb2_grpc.py +0 -0
  167. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v1/service_pb2_grpc.pyi +0 -0
  168. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/__init__.py +0 -0
  169. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/pipeline_pb2.py +0 -0
  170. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/pipeline_pb2.pyi +0 -0
  171. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/pipeline_pb2_grpc.py +0 -0
  172. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/pipeline_pb2_grpc.pyi +0 -0
  173. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/quick_mode_pb2.py +0 -0
  174. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/quick_mode_pb2.pyi +0 -0
  175. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/quick_mode_pb2_grpc.py +0 -0
  176. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/quick_mode_pb2_grpc.pyi +0 -0
  177. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/resource_pb2.py +0 -0
  178. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/resource_pb2.pyi +0 -0
  179. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/resource_pb2_grpc.py +0 -0
  180. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/resource_pb2_grpc.pyi +0 -0
  181. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/room_pb2.py +0 -0
  182. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/room_pb2.pyi +0 -0
  183. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/room_pb2_grpc.py +0 -0
  184. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/room_pb2_grpc.pyi +0 -0
  185. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/source_pb2.py +0 -0
  186. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/source_pb2.pyi +0 -0
  187. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/source_pb2_grpc.py +0 -0
  188. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/source_pb2_grpc.pyi +0 -0
  189. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/table_pb2.py +0 -0
  190. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/table_pb2.pyi +0 -0
  191. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/table_pb2_grpc.py +0 -0
  192. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/ingest/v2/table_pb2_grpc.pyi +0 -0
  193. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/model/__init__.py +0 -0
  194. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/model/v1alpha/__init__.py +0 -0
  195. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/model/v1alpha/models_pb2.py +0 -0
  196. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/model/v1alpha/models_pb2.pyi +0 -0
  197. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/model/v1alpha/models_pb2_grpc.py +0 -0
  198. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/model/v1alpha/models_pb2_grpc.pyi +0 -0
  199. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/__init__.py +0 -0
  200. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/__init__.py +0 -0
  201. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/agent_pb2.py +0 -0
  202. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/agent_pb2.pyi +0 -0
  203. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/agent_pb2_grpc.py +0 -0
  204. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/agent_pb2_grpc.pyi +0 -0
  205. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/common_pb2.py +0 -0
  206. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/common_pb2.pyi +0 -0
  207. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/common_pb2_grpc.py +0 -0
  208. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/common_pb2_grpc.pyi +0 -0
  209. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/completion_model_pb2.py +0 -0
  210. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/completion_model_pb2.pyi +0 -0
  211. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/completion_model_pb2_grpc.py +0 -0
  212. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/completion_model_pb2_grpc.pyi +0 -0
  213. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/feature_view_pb2.py +0 -0
  214. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/feature_view_pb2.pyi +0 -0
  215. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/feature_view_pb2_grpc.py +0 -0
  216. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/feature_view_pb2_grpc.pyi +0 -0
  217. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/pipeline_pb2.py +0 -0
  218. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/pipeline_pb2.pyi +0 -0
  219. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/pipeline_pb2_grpc.py +0 -0
  220. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/pipeline_pb2_grpc.pyi +0 -0
  221. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/space_pb2.py +0 -0
  222. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/space_pb2.pyi +0 -0
  223. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/space_pb2_grpc.py +0 -0
  224. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/space_pb2_grpc.pyi +0 -0
  225. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/table_pb2.py +0 -0
  226. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/table_pb2.pyi +0 -0
  227. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/table_pb2_grpc.py +0 -0
  228. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/orm/v1/table_pb2_grpc.pyi +0 -0
  229. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/platform/__init__.py +0 -0
  230. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/platform/v1/__init__.py +0 -0
  231. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/platform/v1/platform_pb2.py +0 -0
  232. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/platform/v1/platform_pb2.pyi +0 -0
  233. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/platform/v1/platform_pb2_grpc.py +0 -0
  234. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/platform/v1/platform_pb2_grpc.pyi +0 -0
  235. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/query/__init__.py +0 -0
  236. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/query/v1/__init__.py +0 -0
  237. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/query/v1/query_pb2.py +0 -0
  238. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/query/v1/query_pb2.pyi +0 -0
  239. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/query/v1/query_pb2_grpc.py +0 -0
  240. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/query/v1/query_pb2_grpc.pyi +0 -0
  241. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/status/__init__.py +0 -0
  242. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/status/v1/__init__.py +0 -0
  243. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/status/v1/event_pb2.py +0 -0
  244. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/status/v1/event_pb2.pyi +0 -0
  245. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/status/v1/event_pb2_grpc.py +0 -0
  246. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/status/v1/event_pb2_grpc.pyi +0 -0
  247. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/status/v1/service_pb2.py +0 -0
  248. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/status/v1/service_pb2.pyi +0 -0
  249. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/status/v1/service_pb2_grpc.py +0 -0
  250. {corvic_engine-0.3.0rc46 → corvic_engine-0.3.0rc48}/python/corvic_generated/status/v1/service_pb2_grpc.pyi +0 -0
@@ -22,7 +22,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
22
22
 
23
23
  [[package]]
24
24
  name = "corvic-engine"
25
- version = "0.3.0-rc.46"
25
+ version = "0.3.0-rc.48"
26
26
  dependencies = [
27
27
  "numpy",
28
28
  "pyo3",
@@ -63,7 +63,7 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
63
63
 
64
64
  [[package]]
65
65
  name = "engine-walk"
66
- version = "0.3.0-rc.46"
66
+ version = "0.3.0-rc.48"
67
67
  dependencies = [
68
68
  "version_check",
69
69
  ]
@@ -335,9 +335,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
335
335
 
336
336
  [[package]]
337
337
  name = "smallvec"
338
- version = "1.13.2"
338
+ version = "1.14.0"
339
339
  source = "registry+https://github.com/rust-lang/crates.io-index"
340
- checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
340
+ checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
341
341
 
342
342
  [[package]]
343
343
  name = "syn"
@@ -368,9 +368,9 @@ dependencies = [
368
368
 
369
369
  [[package]]
370
370
  name = "unicode-ident"
371
- version = "1.0.16"
371
+ version = "1.0.17"
372
372
  source = "registry+https://github.com/rust-lang/crates.io-index"
373
- checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
373
+ checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe"
374
374
 
375
375
  [[package]]
376
376
  name = "unindent"
@@ -3,7 +3,7 @@ resolver = "2"
3
3
  members = ["python"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.3.0-rc.46"
6
+ version = "0.3.0-rc.48"
7
7
  edition = "2021"
8
8
  publish = false
9
9
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: corvic-engine
3
- Version: 0.3.0rc46
3
+ Version: 0.3.0rc48
4
4
  Classifier: Environment :: Console
5
5
  Classifier: License :: Other/Proprietary License
6
6
  Classifier: Programming Language :: Python :: Implementation :: CPython
@@ -20,7 +20,7 @@ authors = [
20
20
  ]
21
21
  readme = "README.md"
22
22
  description = "Seamless embedding generation and retrieval."
23
- version = "0.3.0-rc.46" # sync this with tool.poetry.version below
23
+ version = "0.3.0-rc.48" # sync this with tool.poetry.version below
24
24
 
25
25
  # TODO(ddn): Pull dependencies from tool.poetry.dependencies. We use maturin as
26
26
  # the build system but poetry for the development environment.
@@ -74,7 +74,7 @@ packages = [
74
74
  ]
75
75
  description = ""
76
76
  authors = []
77
- version = "0.3.0-rc.46"
77
+ version = "0.3.0-rc.48"
78
78
 
79
79
  [tool.poetry.scripts]
80
80
  check = "corvic_check.cli:main"
@@ -3,7 +3,8 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import copy
6
- from collections.abc import Sequence
6
+ import datetime
7
+ from collections.abc import Iterable, Sequence
7
8
  from typing import TypeAlias
8
9
 
9
10
  from sqlalchemy import orm as sa_orm
@@ -95,6 +96,39 @@ class Agent(BaseModel[AgentID, models_pb2.Agent, orm.Agent]):
95
96
  ),
96
97
  )
97
98
 
99
+ @classmethod
100
+ def from_proto(
101
+ cls, proto: models_pb2.Agent, client: system.Client | None = None
102
+ ) -> Agent:
103
+ client = client or Defaults.get_default_client()
104
+ return cls(client, proto)
105
+
106
+ @classmethod
107
+ def list(
108
+ cls,
109
+ *,
110
+ limit: int | None = None,
111
+ room_id: RoomID | None = None,
112
+ created_before: datetime.datetime | None = None,
113
+ client: system.Client | None = None,
114
+ ids: Iterable[AgentID] | None = None,
115
+ existing_session: sa_orm.Session | None = None,
116
+ ) -> Ok[list[Agent]] | NotFoundError | InvalidArgumentError:
117
+ """List agent models."""
118
+ client = client or Defaults.get_default_client()
119
+ match cls.list_as_proto(
120
+ client,
121
+ limit=limit,
122
+ room_id=room_id,
123
+ created_before=created_before,
124
+ ids=ids,
125
+ existing_session=existing_session,
126
+ ):
127
+ case NotFoundError() | InvalidArgumentError() as err:
128
+ return err
129
+ case Ok(protos):
130
+ return Ok([cls.from_proto(proto, client) for proto in protos])
131
+
98
132
  @property
99
133
  def name(self) -> str:
100
134
  return self.proto_self.name
@@ -206,7 +206,8 @@ class BaseModel(Generic[ID, _ProtoObj, OrmObj], UsesOrmID[ID, _ProtoObj]):
206
206
  try:
207
207
  _ = self.proto_to_orm(self.proto_self, session).unwrap_or_raise()
208
208
  session.flush()
209
- except sa.exc.DatabaseError as err:
209
+ # TODO(thunt): Possibly separate out DatabaseError into a precondition error
210
+ except (sa.exc.DatabaseError, sa.exc.StatementError) as err:
210
211
  return InvalidArgumentError.from_(err)
211
212
  return Ok(None)
212
213
 
@@ -340,7 +340,9 @@ class Relationship:
340
340
 
341
341
  result = self.joined_table().select(result_columns)
342
342
 
343
- for batch in result.to_polars().unwrap_or_raise():
343
+ for batch in result.to_polars(
344
+ room_id=self.start_source.room_id
345
+ ).unwrap_or_raise():
344
346
  for row in batch.rows(named=True):
345
347
  yield (row[result_columns[0]], row[result_columns[1]])
346
348
 
@@ -386,6 +386,37 @@ def source_proto_to_orm(
386
386
  return Ok(_add_orm_to_session(orm_obj, proto_obj.org_id, session))
387
387
 
388
388
 
389
+ def _update_agent_associations(
390
+ agent: orm.Agent,
391
+ session: sa_orm.Session,
392
+ ) -> list[orm.SpaceID]:
393
+ associated_space_ids = list[orm.SpaceID]()
394
+ agent_id = agent.id
395
+ agent_parameters = agent.parameters
396
+ if not agent_id or not agent_parameters:
397
+ return associated_space_ids
398
+ for (
399
+ raw_space_id,
400
+ instruction,
401
+ ) in agent_parameters.orchestrator_parameters.space_instructions.items():
402
+ space_id = orm.SpaceID(raw_space_id)
403
+ space_run_id = (
404
+ orm.SpaceRunID(instruction.space_run_id)
405
+ if instruction.space_run_id
406
+ else None
407
+ )
408
+ associated_space_ids.append(space_id)
409
+ session.merge(
410
+ orm.AgentSpaceAssociation(
411
+ room_id=agent.room_id,
412
+ agent_id=agent_id,
413
+ space_id=space_id,
414
+ space_run_id=space_run_id,
415
+ )
416
+ )
417
+ return associated_space_ids
418
+
419
+
389
420
  def agent_proto_to_orm(
390
421
  proto_obj: models_pb2.Agent, session: sa_orm.Session
391
422
  ) -> Ok[orm.Agent] | orm.InvalidORMIdentifierError | InvalidArgumentError:
@@ -403,7 +434,18 @@ def agent_proto_to_orm(
403
434
  parameters=proto_obj.agent_parameters,
404
435
  room_id=room_id,
405
436
  )
406
- return Ok(_add_orm_to_session(orm_obj, proto_obj.org_id, session))
437
+ agent = _add_orm_to_session(orm_obj, proto_obj.org_id, session)
438
+ session.flush()
439
+
440
+ if not agent.id:
441
+ return InvalidArgumentError("failed to add agent to session")
442
+ associated_space_ids = _update_agent_associations(agent, session)
443
+ session.execute(
444
+ sa.delete(orm.AgentSpaceAssociation)
445
+ .where(orm.AgentSpaceAssociation.agent_id == agent.id)
446
+ .where(orm.AgentSpaceAssociation.space_id.not_in(associated_space_ids))
447
+ )
448
+ return Ok(agent)
407
449
 
408
450
 
409
451
  def space_proto_to_orm(
@@ -650,6 +692,11 @@ def resource_delete_orms(
650
692
  def agent_delete_orms(
651
693
  ids: Sequence[orm.AgentID], session: orm.Session
652
694
  ) -> Ok[None] | InvalidArgumentError:
695
+ session.execute(
696
+ sa.delete(orm.AgentSpaceAssociation).where(
697
+ orm.AgentSpaceAssociation.agent_id.in_(ids)
698
+ )
699
+ )
653
700
  session.execute(sa.delete(orm.Agent).where(orm.Agent.id.in_(ids)))
654
701
  return Ok(None)
655
702
 
@@ -718,12 +765,14 @@ def room_delete_orms(
718
765
  ids: Sequence[orm.RoomID], session: orm.Session
719
766
  ) -> Ok[None] | InvalidArgumentError:
720
767
  source_refs = list(
721
- session.scalars(sa.select(orm.Source).where(orm.Source.room_id == ids).limit(1))
768
+ session.scalars(
769
+ sa.select(orm.Source).where(orm.Source.room_id.in_(ids)).limit(1)
770
+ )
722
771
  )
723
772
  if source_refs:
724
773
  return InvalidArgumentError("cannot delete a room that still has sources")
725
774
 
726
- session.execute(sa.delete(orm.Room).where(orm.Room.id == ids))
775
+ session.execute(sa.delete(orm.Room).where(orm.Room.id.in_(ids)))
727
776
  return Ok(None)
728
777
 
729
778
 
@@ -4,7 +4,6 @@ from __future__ import annotations
4
4
 
5
5
  import copy
6
6
  import datetime
7
- import uuid
8
7
  from collections.abc import Iterable, Sequence
9
8
  from typing import TypeAlias
10
9
 
@@ -219,8 +218,8 @@ class Resource(BaseModel[ResourceID, models_pb2.Resource, orm.Resource]):
219
218
  ) -> Self:
220
219
  client = client or Defaults.get_default_client()
221
220
  room_id = room_id or Defaults.get_default_room_id(client)
222
- blob = client.storage_manager.tabular.blob(f"polars_dataframe/{uuid.uuid4()}")
223
221
 
222
+ blob = client.storage_manager.make_tabular_blob(room_id, "anonymous_tables")
224
223
  with blob.open(mode="wb") as stream:
225
224
  data_frame.write_parquet(stream)
226
225
 
@@ -286,14 +286,6 @@ class Space(BelongsToOrgMixin, BelongsToRoomMixin, Base):
286
286
  viewonly=True,
287
287
  )
288
288
 
289
- agent_associations: sa_orm.Mapped[list[AgentSpaceAssociation]] = (
290
- sa_orm.relationship(
291
- init=False,
292
- viewonly=True,
293
- default_factory=list,
294
- )
295
- )
296
-
297
289
  @property
298
290
  def space_key(self):
299
291
  return self.name
@@ -359,15 +351,15 @@ class Agent(SoftDeleteMixin, BelongsToOrgMixin, BelongsToRoomMixin, Base):
359
351
  class AgentSpaceAssociation(BelongsToOrgMixin, BelongsToRoomMixin, Base):
360
352
  __tablename__ = "agent_space_association"
361
353
 
354
+ space_run_id: sa_orm.Mapped[SpaceRunID | None] = sa_orm.mapped_column(
355
+ ForeignKey(SpaceRun).make()
356
+ )
362
357
  agent_id: sa_orm.Mapped[AgentID] = primary_key_foreign_column(
363
- ForeignKey(Agent).make()
358
+ ForeignKey(Agent).make(ondelete="CASCADE")
364
359
  )
365
360
  space_id: sa_orm.Mapped[SpaceID] = primary_key_foreign_column(
366
361
  ForeignKey(Space).make()
367
362
  )
368
- space: sa_orm.Mapped[Space] = sa_orm.relationship(
369
- back_populates="agent_associations", init=False, viewonly=True
370
- )
371
363
 
372
364
 
373
365
  class CompletionModel(SoftDeleteMixin, BelongsToOrgMixin, Base):
@@ -1,11 +1,13 @@
1
1
  import base64
2
2
  import datetime
3
3
  import decimal
4
+ import math
4
5
  from collections.abc import Callable, Iterable, Mapping
5
- from typing import Final, TypeAlias, cast
6
+ from typing import Any, Final, TypeAlias, cast
6
7
 
7
8
  import pyarrow as pa
8
9
  from google.protobuf import struct_pb2
10
+ from pyarrow.lib import ArrowException
9
11
 
10
12
  from corvic.pa_scalar._temporal import (
11
13
  MonthDayNanoFrac,
@@ -118,11 +120,17 @@ def _visit_uint64(
118
120
  return struct_pb2.Value(string_value=str(value))
119
121
 
120
122
 
123
+ def _is_invalid_float(value: float):
124
+ return math.isnan(value) or math.isinf(value)
125
+
126
+
121
127
  def _visit_float16(
122
128
  value: _PyValue,
123
129
  dtype: pa.DataType,
124
130
  ) -> struct_pb2.Value:
125
131
  value = cast(float, value)
132
+ if _is_invalid_float(value):
133
+ return _visit_null(value, pa.null())
126
134
  return struct_pb2.Value(number_value=value)
127
135
 
128
136
 
@@ -131,6 +139,8 @@ def _visit_float32(
131
139
  dtype: pa.DataType,
132
140
  ) -> struct_pb2.Value:
133
141
  value = cast(float, value)
142
+ if _is_invalid_float(value):
143
+ return _visit_null(value, pa.null())
134
144
  return struct_pb2.Value(number_value=value)
135
145
 
136
146
 
@@ -139,6 +149,8 @@ def _visit_float64(
139
149
  dtype: pa.DataType,
140
150
  ) -> struct_pb2.Value:
141
151
  value = cast(float, value)
152
+ if _is_invalid_float(value):
153
+ return _visit_null(value, pa.null())
142
154
  return struct_pb2.Value(number_value=value)
143
155
 
144
156
 
@@ -412,6 +424,8 @@ def to_value(
412
424
  case int():
413
425
  return struct_pb2.Value(string_value=str(scalar))
414
426
  case float():
427
+ if _is_invalid_float(scalar):
428
+ return to_value(None)
415
429
  return struct_pb2.Value(number_value=scalar)
416
430
  case str():
417
431
  return struct_pb2.Value(string_value=scalar)
@@ -424,6 +438,36 @@ def to_value(
424
438
  return _visit(value, scalar.type)
425
439
 
426
440
 
441
+ def _to_py(scalar: Scalar) -> Any:
442
+ try:
443
+ # This scalar might have malformed binary data that's incorrectly typed
444
+ # as string (e.g. non-utf-8 strings), so skip it
445
+ scalar.validate(full=True)
446
+ return scalar.as_py()
447
+ except ArrowException:
448
+ # To create examples that hit this code path, one needs to create a
449
+ # pyarrow.BinaryArray and then cast it to a StringArray but also supply
450
+ # a CastOptions with allow_invalid_utf8 set to True.
451
+ # TODO(aneesh): also check pa.types.is_dictionary
452
+ if (
453
+ pa.types.is_list(scalar.type)
454
+ or pa.types.is_large_list(scalar.type)
455
+ or pa.types.is_fixed_size_list(scalar.type)
456
+ ):
457
+ lscalar = cast(pa.ListScalar[Any], scalar)
458
+ return [_to_py(v) for v in lscalar.values] # noqa: PD011 # type: ignore[unknownMemberType]
459
+ if pa.types.is_map(scalar.type):
460
+ mscalar = cast(pa.MapScalar[Any, Any], scalar)
461
+ return {
462
+ res["key"]: res["value"]
463
+ for res in [_to_py(v) for v in mscalar.values] # noqa: PD011 # type: ignore[unknownMemberType]
464
+ }
465
+ if pa.types.is_struct(scalar.type):
466
+ sscalar = cast(pa.StructScalar, scalar)
467
+ return {k: _to_py(sscalar[k]) for k in sscalar}
468
+ return None
469
+
470
+
427
471
  def batch_to_structs(
428
472
  batch: pa.RecordBatch,
429
473
  ) -> list[struct_pb2.Struct]:
@@ -432,7 +476,8 @@ def batch_to_structs(
432
476
  field_by_name = {field.name: field for field in schema}
433
477
 
434
478
  ret: list[struct_pb2.Struct] = []
435
- for row in batch.to_pylist():
479
+ for pa_row in batch.to_struct_array():
480
+ row = _to_py(cast(Scalar, pa_row))
436
481
  fields = {
437
482
  col_name: _visit(v, field_by_name[col_name].type)
438
483
  for col_name, v in row.items()
@@ -39,3 +39,5 @@ class Scalar(Protocol):
39
39
  def equals(self, other: Any) -> bool: ...
40
40
 
41
41
  def as_py(self) -> Any: ...
42
+
43
+ def validate(self, *, full: bool = False) -> bool | None: ...
@@ -48,7 +48,6 @@ from corvic.system.storage import (
48
48
  Blob,
49
49
  BlobClient,
50
50
  Bucket,
51
- DataKindManager,
52
51
  DataMisplacedError,
53
52
  StorageManager,
54
53
  )
@@ -71,7 +70,6 @@ __all__ = [
71
70
  "Clip",
72
71
  "ClipText",
73
72
  "DEFAULT_VECTOR_COLUMN_NAMES_TO_SIZES",
74
- "DataKindManager",
75
73
  "DataMisplacedError",
76
74
  "DimensionReducer",
77
75
  "EmbedTextContext",
@@ -6,11 +6,12 @@ import contextlib
6
6
  import io
7
7
  import uuid
8
8
  from collections.abc import Iterator
9
- from typing import Any, Literal
9
+ from typing import Any, Final, Literal
10
10
 
11
11
  from typing_extensions import Protocol
12
12
 
13
- from corvic.result import Error, Ok
13
+ from corvic import orm
14
+ from corvic.result import Error
14
15
 
15
16
 
16
17
  class DataMisplacedError(Error):
@@ -105,60 +106,16 @@ class Bucket(Protocol):
105
106
  def list_blobs(self, prefix: str | None = None) -> Iterator[Blob]: ...
106
107
 
107
108
 
108
- class DataKindManager:
109
- """Manages the names of blobs that corvic stores for a particular data kind.
110
-
111
- Kinds are managed by the NamespaceManager
112
- """
113
-
114
- def __init__(self, storage_manager: StorageManager, prefix: str):
115
- if prefix.endswith("/"):
116
- raise ValueError("prefix should not end with a path separator (/)")
117
- self._namespace_manager = storage_manager
118
- self._prefix = prefix
119
-
120
- @property
121
- def prefix(self):
122
- return self._prefix
123
-
124
- def make_anonymous_table_url(self):
125
- return self.blob(f"anonymous_tables/{uuid.uuid4()}.parquet").url
126
-
127
- def blob(self, blob_name: str):
128
- return self._namespace_manager.bucket.blob(f"{self.prefix}/{blob_name}")
129
-
130
- def _blob_from_url(self, url: str) -> Ok[Blob] | DataMisplacedError:
131
- blob = self._namespace_manager.blob_from_url(url)
132
- if self._namespace_manager.bucket.name != blob.bucket.name:
133
- return DataMisplacedError(
134
- "data stored at a different bucket than expected",
135
- url=url,
136
- expected_bucket=self._namespace_manager.bucket.name,
137
- )
138
- if not blob.name.startswith(self._prefix):
139
- return DataMisplacedError(
140
- "data stored at a different prefix than expected",
141
- url=url,
142
- expected_prefix=self._prefix,
143
- )
144
- return Ok(blob)
145
-
146
- def blob_name_from_url(self, url: str) -> Ok[str] | DataMisplacedError:
147
- def _to_name(blob: Blob) -> str:
148
- return blob.name.removeprefix(self._prefix + "/")
149
-
150
- return self._blob_from_url(url=url).map(_to_name)
151
-
152
-
153
109
  class StorageManager:
154
110
  """Manages the names of blobs that corvic stores."""
155
111
 
156
112
  _blob_client: BlobClient
157
113
  _bucket_name: str
158
- _unstructured_manager: DataKindManager
159
- _tabular_manager: DataKindManager
160
- _space_run_manager: DataKindManager
161
- _vector_manager: DataKindManager
114
+
115
+ unstructured_prefix: Final[str]
116
+ tabular_prefix: Final[str]
117
+ vector_prefix: Final[str]
118
+ bucket: Final[Bucket]
162
119
 
163
120
  def __init__(
164
121
  self,
@@ -167,36 +124,55 @@ class StorageManager:
167
124
  bucket_name: str,
168
125
  unstructured_prefix: str,
169
126
  tabular_prefix: str,
170
- space_run_prefix: str,
171
127
  vector_prefix: str,
172
128
  ):
173
129
  self._blob_client = blob_client
174
130
  self._bucket_name = bucket_name
175
131
 
176
- self._unstructured_manager = DataKindManager(self, unstructured_prefix)
177
- self._tabular_manager = DataKindManager(self, tabular_prefix)
178
- self._space_run_manager = DataKindManager(self, space_run_prefix)
179
- self._vector_manager = DataKindManager(self, vector_prefix)
180
-
181
- def blob_from_url(self, url: str):
182
- return self._blob_client.blob_from_url(url)
132
+ if unstructured_prefix.endswith("/") or tabular_prefix.endswith("/"):
133
+ raise ValueError("prefix should not end with a path separator (/)")
183
134
 
184
- @property
185
- def bucket(self) -> Bucket:
186
- return self._blob_client.bucket(self._bucket_name)
135
+ self.unstructured_prefix = unstructured_prefix
136
+ self.tabular_prefix = tabular_prefix
137
+ self.vector_prefix = vector_prefix
187
138
 
188
- @property
189
- def tabular(self):
190
- return self._tabular_manager
139
+ self.bucket = self._blob_client.bucket(self._bucket_name)
191
140
 
192
- @property
193
- def unstructured(self):
194
- return self._unstructured_manager
141
+ @staticmethod
142
+ def _render_room_id(room_id: orm.RoomID) -> str:
143
+ return f"{int(str(room_id)):016}"
195
144
 
196
- @property
197
- def space_run(self):
198
- return self._space_run_manager
145
+ def blob_from_url(self, url: str):
146
+ return self._blob_client.blob_from_url(url)
199
147
 
200
- @property
201
- def vector(self):
202
- return self._vector_manager
148
+ def make_tabular_blob(self, room_id: orm.RoomID, suffix: str | None = None) -> Blob:
149
+ if suffix:
150
+ name = f"{self._render_room_id(room_id)}/{uuid.uuid4()}/{suffix}"
151
+ else:
152
+ name = f"{self._render_room_id(room_id)}/{uuid.uuid4()}"
153
+ return self.bucket.blob(f"{self.tabular_prefix}/{name}")
154
+
155
+ def make_unstructured_blob(
156
+ self, room_id: orm.RoomID, suffix: str | None = None
157
+ ) -> Blob:
158
+ if suffix:
159
+ name = f"{self._render_room_id(room_id)}/{uuid.uuid4()}/{suffix}"
160
+ else:
161
+ name = f"{self._render_room_id(room_id)}/{uuid.uuid4()}"
162
+ return self.bucket.blob(f"{self.unstructured_prefix}/{name}")
163
+
164
+ def make_vector_blob(self, room_id: orm.RoomID, suffix: str | None = None) -> Blob:
165
+ if suffix:
166
+ name = f"{self._render_room_id(room_id)}/{uuid.uuid4()}/{suffix}"
167
+ else:
168
+ name = f"{self._render_room_id(room_id)}/{uuid.uuid4()}"
169
+ return self.bucket.blob(f"{self.vector_prefix}/{name}")
170
+
171
+ def get_tabular_blob_from_blob_name(self, blob_name: str) -> Blob:
172
+ return self.bucket.blob(f"{self.tabular_prefix}/{blob_name}")
173
+
174
+ def get_unstructured_blob_from_blob_name(self, blob_name: str) -> Blob:
175
+ return self.bucket.blob(f"{self.unstructured_prefix}/{blob_name}")
176
+
177
+ def get_vector_blob_from_blob_name(self, blob_name: str) -> Blob:
178
+ return self.bucket.blob(f"{self.vector_prefix}/{blob_name}")
@@ -135,7 +135,6 @@ class Client(corvic.system.Client):
135
135
  bucket_name=bucket.name,
136
136
  unstructured_prefix="unstructured_data",
137
137
  tabular_prefix="tabular_data",
138
- space_run_prefix="experiment_run_data",
139
138
  vector_prefix="vectors",
140
139
  )
141
140
  corvic.orm.Base.metadata.create_all(self._sa_engine)
@@ -15,7 +15,6 @@ import sqlglot.expressions
15
15
  from corvic.op_graph import Schema
16
16
  from corvic.result import InternalError, Ok
17
17
  from corvic.system import (
18
- DataKindManager,
19
18
  StagingDB,
20
19
  StorageManager,
21
20
  TableSliceArgs,
@@ -255,17 +254,18 @@ class DuckDBStaging(StagingDB):
255
254
 
256
255
  def _update_blobs_for_prefix(
257
256
  self,
258
- manager: DataKindManager,
259
257
  next_count: dict[str, int | None],
258
+ prefix: str,
260
259
  transform_table: Callable[[str, pa.Table], None] | None = None,
261
260
  ):
262
261
  bucket = self._storage_manager.bucket
263
262
  blobs = bucket.list_blobs()
264
- prefix = manager.prefix
265
263
  table_blobs = [
266
264
  (
267
265
  blob,
268
- manager.blob_name_from_url(url=blob.url).unwrap_or_raise(),
266
+ self._storage_manager.blob_from_url(blob.url).name.removeprefix(
267
+ prefix + "/"
268
+ ),
269
269
  )
270
270
  for blob in blobs
271
271
  if blob.name.startswith(prefix)
@@ -289,9 +289,14 @@ class DuckDBStaging(StagingDB):
289
289
  As a side-effect, update _table_counts.
290
290
  """
291
291
  next_count: dict[str, int | None] = {}
292
- self._update_blobs_for_prefix(self._storage_manager.tabular, next_count)
293
292
  self._update_blobs_for_prefix(
294
- self._storage_manager.vector, next_count, self._add_vector_indexes
293
+ next_count,
294
+ self._storage_manager.tabular_prefix,
295
+ )
296
+ self._update_blobs_for_prefix(
297
+ next_count,
298
+ self._storage_manager.vector_prefix,
299
+ self._add_vector_indexes,
295
300
  )
296
301
  self._table_counts = next_count
297
302