digitalkin 1.0.2.dev4__tar.gz → 1.0.2.dev6__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 (247) hide show
  1. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/PKG-INFO +1 -1
  2. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/pyproject.toml +1 -1
  3. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/__version__.py +1 -1
  4. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/_base_server.py +11 -4
  5. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/mixins/storage_mixin.py +3 -2
  6. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/services/registry.py +5 -1
  7. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/services/storage.py +23 -0
  8. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/storage/default_storage.py +28 -9
  9. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/storage/grpc_storage.py +46 -24
  10. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/storage/storage_strategy.py +107 -56
  11. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin.egg-info/PKG-INFO +1 -1
  12. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/LICENSE +0 -0
  13. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/README.md +0 -0
  14. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/base_server/__init__.py +0 -0
  15. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/base_server/mock/__init__.py +0 -0
  16. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/base_server/mock/mock_pb2.py +0 -0
  17. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
  18. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/base_server/server_async_insecure.py +0 -0
  19. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/base_server/server_async_secure.py +0 -0
  20. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/base_server/server_sync_insecure.py +0 -0
  21. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/base_server/server_sync_secure.py +0 -0
  22. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/bench_module/__init__.py +0 -0
  23. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/bench_module/echo_module.py +0 -0
  24. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/bench_module/models/__init__.py +0 -0
  25. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/bench_module/models/input.py +0 -0
  26. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/bench_module/models/output.py +0 -0
  27. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/bench_module/models/secret.py +0 -0
  28. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/bench_module/models/setup.py +0 -0
  29. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/bench_module/server.py +0 -0
  30. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/bench_module/triggers/__init__.py +0 -0
  31. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/bench_module/triggers/message_trigger.py +0 -0
  32. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/modules/__init__.py +0 -0
  33. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/modules/archetype_with_tools_module.py +0 -0
  34. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/modules/cpu_intensive_module.py +0 -0
  35. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/modules/dynamic_setup_module.py +0 -0
  36. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/modules/minimal_llm_module.py +0 -0
  37. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/modules/text_transform_module.py +0 -0
  38. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
  39. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
  40. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
  41. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
  42. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
  43. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/monitoring/tests/test_metrics.py +0 -0
  44. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/redis_demo/client.py +0 -0
  45. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/redis_demo/echo_module.py +0 -0
  46. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/redis_demo/models/__init__.py +0 -0
  47. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/redis_demo/models/input.py +0 -0
  48. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/redis_demo/models/output.py +0 -0
  49. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/redis_demo/models/secret.py +0 -0
  50. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/redis_demo/models/setup.py +0 -0
  51. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/redis_demo/server.py +0 -0
  52. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/redis_demo/triggers/__init__.py +0 -0
  53. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/redis_demo/triggers/message_trigger.py +0 -0
  54. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/services/filesystem_module.py +0 -0
  55. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/examples/services/storage_module.py +0 -0
  56. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/setup.cfg +0 -0
  57. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/__init__.py +0 -0
  58. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/__init__.py +0 -0
  59. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/__init__.py +0 -0
  60. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/agno_adapter.py +0 -0
  61. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/agui_tools.py +0 -0
  62. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/hitl.py +0 -0
  63. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/models.py +0 -0
  64. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/module_toolkit.py +0 -0
  65. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/toolkits/__init__.py +0 -0
  66. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/toolkits/base.py +0 -0
  67. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/toolkits/chat_history.py +0 -0
  68. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/toolkits/defaults.py +0 -0
  69. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/toolkits/registry.py +0 -0
  70. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/toolkits/setup.py +0 -0
  71. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/toolkits/tool_loader.py +0 -0
  72. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/community/agno/toolkits/user_profile.py +0 -0
  73. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/__init__.py +0 -0
  74. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/common/__init__.py +0 -0
  75. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/common/factories.py +0 -0
  76. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/exceptions.py +0 -0
  77. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/job_manager/__init__.py +0 -0
  78. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
  79. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
  80. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/profiling/__init__.py +0 -0
  81. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/profiling/step_timer.py +0 -0
  82. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/profiling/task_profiler.py +0 -0
  83. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/resilience/__init__.py +0 -0
  84. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/resilience/bulkhead.py +0 -0
  85. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
  86. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/__init__.py +0 -0
  87. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
  88. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
  89. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/module_runner.py +0 -0
  90. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
  91. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/redis/proto_streams.py +0 -0
  92. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/redis/redis_client.py +0 -0
  93. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +0 -0
  94. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/redis/redis_signal.py +0 -0
  95. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/redis/redis_state.py +0 -0
  96. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
  97. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/task_executor.py +0 -0
  98. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/core/task_manager/task_session.py +0 -0
  99. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/exceptions.py +0 -0
  100. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/__init__.py +0 -0
  101. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/exceptions.py +0 -0
  102. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/gateway_servicer.py +0 -0
  103. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
  104. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/interceptors/permission.py +0 -0
  105. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/interceptors/request_ids.py +0 -0
  106. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/m2m_call_registry.py +0 -0
  107. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/module_server.py +0 -0
  108. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/module_servicer.py +0 -0
  109. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/stream_registry.py +0 -0
  110. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/stream_session.py +0 -0
  111. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
  112. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +0 -0
  113. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +0 -0
  114. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +0 -0
  115. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
  116. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
  117. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/logger.py +0 -0
  118. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/mixins/__init__.py +0 -0
  119. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/mixins/agui_mixin.py +0 -0
  120. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/mixins/base_mixin.py +0 -0
  121. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/mixins/cost_mixin.py +0 -0
  122. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/mixins/file_history_mixin.py +0 -0
  123. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
  124. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/mixins/logger_mixin.py +0 -0
  125. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/__init__.py +0 -0
  126. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/core/__init__.py +0 -0
  127. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/core/job_manager_models.py +0 -0
  128. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/core/redis.py +0 -0
  129. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/core/task_monitor.py +0 -0
  130. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/events/__init__.py +0 -0
  131. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/events/agent_events.py +0 -0
  132. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
  133. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
  134. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
  135. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/grpc_servers/models.py +0 -0
  136. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/grpc_servers/stream_error_codes.py +0 -0
  137. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/grpc_servers/types.py +0 -0
  138. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/module/__init__.py +0 -0
  139. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/module/ag_ui.py +0 -0
  140. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/module/base_types.py +0 -0
  141. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/module/module.py +0 -0
  142. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/module/module_context.py +0 -0
  143. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/module/module_types.py +0 -0
  144. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/module/request_metadata.py +0 -0
  145. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/module/select_schema.py +0 -0
  146. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/module/setup_types.py +0 -0
  147. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/module/tool_cache.py +0 -0
  148. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/module/tool_reference.py +0 -0
  149. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/module/utility.py +0 -0
  150. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/services/__init__.py +0 -0
  151. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/services/cost.py +0 -0
  152. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/services/services.py +0 -0
  153. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/__init__.py +0 -0
  154. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/gateway.py +0 -0
  155. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/grpc_client.py +0 -0
  156. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/log.py +0 -0
  157. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/module.py +0 -0
  158. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/profiling.py +0 -0
  159. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/queue.py +0 -0
  160. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/redis.py +0 -0
  161. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/registry.py +0 -0
  162. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/resilience.py +0 -0
  163. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/server/__init__.py +0 -0
  164. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/server/channel.py +0 -0
  165. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/server/grpc.py +0 -0
  166. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/server/server.py +0 -0
  167. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/server/servicer.py +0 -0
  168. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/task_manager.py +0 -0
  169. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/utils/__init__.py +0 -0
  170. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/settings/utils/channel.py +0 -0
  171. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/utils/__init__.py +0 -0
  172. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
  173. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/modules/__init__.py +0 -0
  174. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/modules/_base_module.py +0 -0
  175. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/modules/archetype_module.py +0 -0
  176. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/modules/tool_module.py +0 -0
  177. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/modules/trigger_handler.py +0 -0
  178. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/modules/triggers/__init__.py +0 -0
  179. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
  180. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
  181. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
  182. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/py.typed +0 -0
  183. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/__init__.py +0 -0
  184. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/base_strategy.py +0 -0
  185. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/communication/__init__.py +0 -0
  186. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/communication/communication_strategy.py +0 -0
  187. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/communication/default_communication.py +0 -0
  188. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/communication/exceptions.py +0 -0
  189. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/communication/grpc_communication.py +0 -0
  190. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/cost/__init__.py +0 -0
  191. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/cost/cost_strategy.py +0 -0
  192. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/cost/default_cost.py +0 -0
  193. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/cost/exceptions.py +0 -0
  194. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/cost/grpc_cost.py +0 -0
  195. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/filesystem/__init__.py +0 -0
  196. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
  197. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/filesystem/exceptions.py +0 -0
  198. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/filesystem/filesystem_strategy.py +0 -0
  199. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/filesystem/grpc_filesystem.py +0 -0
  200. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/identity/__init__.py +0 -0
  201. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/identity/default_identity.py +0 -0
  202. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/identity/identity_strategy.py +0 -0
  203. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/registry/__init__.py +0 -0
  204. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/registry/default_registry.py +0 -0
  205. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/registry/exceptions.py +0 -0
  206. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/registry/grpc_registry.py +0 -0
  207. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/registry/registry_models.py +0 -0
  208. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/registry/registry_strategy.py +0 -0
  209. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/secret/__init__.py +0 -0
  210. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/secret/default_secret.py +0 -0
  211. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/secret/exceptions.py +0 -0
  212. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/secret/grpc_secret.py +0 -0
  213. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/secret/secret_strategy.py +0 -0
  214. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/services_config.py +0 -0
  215. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/services_models.py +0 -0
  216. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/setup/__init__.py +0 -0
  217. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/setup/default_setup.py +0 -0
  218. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/setup/exceptions.py +0 -0
  219. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/setup/grpc_setup.py +0 -0
  220. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/setup/setup_strategy.py +0 -0
  221. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/storage/__init__.py +0 -0
  222. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/storage/exceptions.py +0 -0
  223. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/task_manager/__init__.py +0 -0
  224. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
  225. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/task_manager/exceptions.py +0 -0
  226. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
  227. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
  228. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/user_profile/__init__.py +0 -0
  229. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/user_profile/default_user_profile.py +0 -0
  230. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/user_profile/exceptions.py +0 -0
  231. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/user_profile/grpc_user_profile.py +0 -0
  232. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/services/user_profile/user_profile_strategy.py +0 -0
  233. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/utils/__init__.py +0 -0
  234. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/utils/arg_parser.py +0 -0
  235. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/utils/conditional_schema.py +0 -0
  236. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/utils/development_mode_action.py +0 -0
  237. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/utils/dynamic_schema.py +0 -0
  238. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/utils/exceptions.py +0 -0
  239. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/utils/llm_ready_schema.py +0 -0
  240. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/utils/package_discover.py +0 -0
  241. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/utils/proto_utils.py +0 -0
  242. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin/utils/schema_splitter.py +0 -0
  243. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin.egg-info/SOURCES.txt +0 -0
  244. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin.egg-info/dependency_links.txt +0 -0
  245. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin.egg-info/requires.txt +0 -0
  246. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/src/digitalkin.egg-info/top_level.txt +0 -0
  247. {digitalkin-1.0.2.dev4 → digitalkin-1.0.2.dev6}/tests/test_exceptions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalkin
3
- Version: 1.0.2.dev4
3
+ Version: 1.0.2.dev6
4
4
  Summary: SDK to build kin used in DigitalKin
5
5
  Author-email: "DigitalKin.ai" <contact@digitalkin.ai>
6
6
  License: Attribution-NonCommercial-ShareAlike 4.0 International
@@ -37,7 +37,7 @@
37
37
  "pydantic>=2.12.4",
38
38
  "redis[hiredis]>=7.4.0,<9",
39
39
  ]
40
- version = "1.0.2.dev4"
40
+ version = "1.0.2.dev6"
41
41
 
42
42
  [project.optional-dependencies]
43
43
  agno = [ "agno>=2.6" ]
@@ -5,4 +5,4 @@ from importlib.metadata import PackageNotFoundError, version
5
5
  try:
6
6
  __version__ = version("digitalkin")
7
7
  except PackageNotFoundError:
8
- __version__ = "1.0.2.dev4"
8
+ __version__ = "1.0.2.dev6"
@@ -3,6 +3,7 @@
3
3
  import abc
4
4
  import asyncio
5
5
  import os
6
+ import sys
6
7
 
7
8
  from digitalkin.models.settings.profiling import get_profiling_settings
8
9
 
@@ -196,10 +197,16 @@ class BaseServer(abc.ABC):
196
197
  try: # noqa: PLW0717
197
198
  grpc_compression = get_server_settings().grpc.compression.to_grpc()
198
199
 
199
- try:
200
- cpu_count = len(os.sched_getaffinity(0))
201
- logger.info("vCPU count: %d", cpu_count)
202
- except (AttributeError, OSError):
200
+ # sched_getaffinity is Linux-only; the sys.platform guard lets mypy skip
201
+ # it as unreachable on other platforms without a type: ignore.
202
+ if sys.platform == "linux":
203
+ try:
204
+ cpu_count = len(os.sched_getaffinity(0))
205
+ logger.info("vCPU count: %d", cpu_count)
206
+ except OSError:
207
+ cpu_count = os.cpu_count() or 1
208
+ logger.info("CPU count: %d", cpu_count)
209
+ else:
203
210
  cpu_count = os.cpu_count() or 1
204
211
  logger.info("CPU count: %d", cpu_count)
205
212
 
@@ -3,6 +3,7 @@
3
3
  from typing import Any, Literal
4
4
 
5
5
  from digitalkin.models.module.module_context import ModuleContext
6
+ from digitalkin.models.services.storage import DataType
6
7
  from digitalkin.services.storage.storage_strategy import StorageRecord
7
8
 
8
9
 
@@ -36,7 +37,7 @@ class StorageMixin:
36
37
  Raises:
37
38
  StorageServiceError: If storage operation fails
38
39
  """
39
- return await context.storage.store(collection, record_id, data, data_type=data_type)
40
+ return await context.storage.store(collection, record_id, data, data_type=DataType[data_type])
40
41
 
41
42
  @staticmethod
42
43
  async def read_storage(context: ModuleContext, collection: str, record_id: str) -> StorageRecord | None:
@@ -101,4 +102,4 @@ class StorageMixin:
101
102
  Raises:
102
103
  StorageServiceError: If upsert operation fails
103
104
  """
104
- return await context.storage.upsert(collection, record_id, data, data_type=data_type)
105
+ return await context.storage.upsert(collection, record_id, data, data_type=DataType[data_type])
@@ -18,7 +18,11 @@ class RegistryModuleStatus(str, Enum):
18
18
 
19
19
 
20
20
  class RegistryModuleType(str, Enum):
21
- """Module type in the registry."""
21
+ """Module type in the registry.
22
+
23
+ Member names mirror the proto ``ModuleType`` enum (minus the ``MODULE_TYPE_``
24
+ prefix): they are looked up by name from the wire value, so they must match.
25
+ """
22
26
 
23
27
  UNSPECIFIED = "unspecified"
24
28
  ARCHETYPE = "archetype"
@@ -51,3 +51,26 @@ class DataType(Enum):
51
51
  VIEW = "VIEW"
52
52
  LOGS = "LOGS"
53
53
  OTHER = "OTHER"
54
+
55
+
56
+ class ContextStorage(Enum):
57
+ """Enum defining the context of data in storage."""
58
+
59
+ UNSPECIFIED = "unspecified"
60
+ MISSIONS = "missions"
61
+ SETUP_VERSIONS = "setup_versions"
62
+ USERS = "users"
63
+ ORGANIZATIONS = "organizations"
64
+
65
+
66
+ class Visibility(Enum):
67
+ """Read-access scope of a record, mirroring the storage proto by integer value.
68
+
69
+ Ownership (who may edit) stays keyed on the record context; this only governs
70
+ who may read. UNSPECIFIED lets the storage service apply its server-side default.
71
+ """
72
+
73
+ UNSPECIFIED = 0
74
+ PUBLIC = 1
75
+ PRIVATE = 2
76
+ INTERNAL = 3
@@ -9,7 +9,7 @@ from typing import Any
9
9
  from pydantic import BaseModel
10
10
 
11
11
  from digitalkin.logger import logger
12
- from digitalkin.models.services.storage import DataType
12
+ from digitalkin.models.services.storage import DataType, Visibility
13
13
  from digitalkin.services.storage.storage_strategy import (
14
14
  StorageRecord,
15
15
  StorageStrategy,
@@ -67,6 +67,7 @@ class DefaultStorage(StorageStrategy):
67
67
  record_id=rd["record_id"],
68
68
  data=data_model,
69
69
  data_type=DataType[rd["data_type"]],
70
+ visibility=Visibility[rd["visibility"]] if rd.get("visibility") else Visibility.UNSPECIFIED,
70
71
  creation_date=datetime.datetime.fromisoformat(rd["creation_date"])
71
72
  if rd.get("creation_date")
72
73
  else None,
@@ -97,6 +98,7 @@ class DefaultStorage(StorageStrategy):
97
98
  "collection": record.collection,
98
99
  "record_id": record.record_id,
99
100
  "data_type": record.data_type.name,
101
+ "visibility": record.visibility.name,
100
102
  "data": record.data.model_dump(),
101
103
  "creation_date": record.creation_date.isoformat() if record.creation_date else None,
102
104
  "update_date": record.update_date.isoformat() if record.update_date else None,
@@ -141,21 +143,29 @@ class DefaultStorage(StorageStrategy):
141
143
  Args:
142
144
  collection: The unique name to retrieve data for
143
145
  record_id: The unique ID of the record
144
- context: Owner context scoping the lookup.
146
+ context: Resolved owner context scoping the lookup.
145
147
 
146
148
  Returns:
147
149
  StorageRecord: The corresponding record
148
150
  """
149
151
  return self.storage.get(self._key(context, collection, record_id))
150
152
 
151
- async def _update(self, collection: str, record_id: str, data: BaseModel, context: str) -> StorageRecord | None:
153
+ async def _update(
154
+ self,
155
+ collection: str,
156
+ record_id: str,
157
+ data: BaseModel,
158
+ context: str,
159
+ visibility: Visibility = Visibility.UNSPECIFIED,
160
+ ) -> StorageRecord | None:
152
161
  """Update a record in the database scoped to a specific context.
153
162
 
154
163
  Args:
155
164
  collection: The unique name to retrieve data for
156
165
  record_id: The unique ID of the record
157
166
  data: The data to modify
158
- context: Owner context scoping the update.
167
+ context: Resolved owner context scoping the update.
168
+ visibility: New read-access scope; UNSPECIFIED leaves it unchanged.
159
169
 
160
170
  Returns:
161
171
  StorageRecord: The modified record
@@ -165,6 +175,8 @@ class DefaultStorage(StorageStrategy):
165
175
  if not rec:
166
176
  return None
167
177
  rec.data = data
178
+ if visibility is not Visibility.UNSPECIFIED:
179
+ rec.visibility = visibility
168
180
  rec.update_date = datetime.datetime.now(datetime.timezone.utc)
169
181
  self._save_to_file()
170
182
  logger.debug("Modified %s", key)
@@ -176,7 +188,7 @@ class DefaultStorage(StorageStrategy):
176
188
  Args:
177
189
  collection: The unique name to retrieve data for
178
190
  record_id: The unique ID of the record
179
- context: Owner context scoping the deletion.
191
+ context: Resolved owner context scoping the deletion.
180
192
 
181
193
  Returns:
182
194
  bool: True if the record was removed, False otherwise
@@ -189,25 +201,32 @@ class DefaultStorage(StorageStrategy):
189
201
  logger.debug("Removed %s", key)
190
202
  return True
191
203
 
192
- async def _list(self, collection: str, context: str) -> list[StorageRecord]:
204
+ async def _list(
205
+ self, collection: str, context: str, visibilities: list[Visibility] | None = None
206
+ ) -> list[StorageRecord]:
193
207
  """List records in a collection scoped to a specific context.
194
208
 
195
209
  Args:
196
210
  collection: The unique name to retrieve data for
197
- context: Owner context scoping the listing.
211
+ context: Resolved owner context scoping the listing.
212
+ visibilities: Optional read-access scopes to filter by (None = no filter).
198
213
 
199
214
  Returns:
200
215
  A list of storage records
201
216
  """
202
217
  prefix = f"{context}|{collection}:"
203
- return [r for k, r in self.storage.items() if k.startswith(prefix)]
218
+ records = [r for k, r in self.storage.items() if k.startswith(prefix)]
219
+ if visibilities:
220
+ allowed = set(visibilities)
221
+ records = [r for r in records if r.visibility in allowed]
222
+ return records
204
223
 
205
224
  async def _remove_collection(self, collection: str, context: str) -> bool:
206
225
  """Wipe a collection scoped to a specific context.
207
226
 
208
227
  Args:
209
228
  collection: The unique name to retrieve data for
210
- context: Owner context scoping the wipe.
229
+ context: Resolved owner context scoping the wipe.
211
230
 
212
231
  Returns:
213
232
  bool: True if the collection was removed, False otherwise
@@ -1,5 +1,7 @@
1
1
  """This module implements the default storage strategy."""
2
2
 
3
+ from typing import cast
4
+
3
5
  from agentic_mesh_protocol.storage.v1 import data_pb2, storage_service_pb2_grpc
4
6
  from google.protobuf.struct_pb2 import Struct
5
7
  from pydantic import BaseModel
@@ -8,7 +10,7 @@ from digitalkin.grpc_servers.exceptions import CircuitOpenError, PermissionDenie
8
10
  from digitalkin.grpc_servers.utils.grpc_client_wrapper import GrpcClientWrapper
9
11
  from digitalkin.logger import logger
10
12
  from digitalkin.models.grpc_servers.models import ClientConfig
11
- from digitalkin.models.services.storage import DataType
13
+ from digitalkin.models.services.storage import DataType, Visibility
12
14
  from digitalkin.services.storage.exceptions import StorageServiceError
13
15
  from digitalkin.services.storage.storage_strategy import (
14
16
  StorageRecord,
@@ -39,22 +41,27 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
39
41
  return isinstance(error.__cause__, CircuitOpenError)
40
42
 
41
43
  def _context_enum(self, context: str) -> data_pb2.ContextStorage:
42
- """Map a resolved context id-string to the wire's context-kind enum.
44
+ """Map a resolved context string to the wire's context-kind enum.
43
45
 
44
46
  Since dev4 the request carries only the kind; the concrete id is resolved
45
- server-side from the x-mission-id / x-setup-id task metadata stamped by
46
- ``RequestIdClientInterceptor``.
47
+ server-side from the request metadata stamped by ``RequestIdClientInterceptor``.
48
+ USERS/ORGANIZATIONS are read-only cross-owner scopes whose id is resolved
49
+ server-side from the x-user-id / x-organization-id metadata.
47
50
 
48
51
  Args:
49
- context: The resolved context id (``self.mission_id`` or ``self.setup_version_id``).
52
+ context: The resolved context string from ``_resolve_context``.
50
53
 
51
54
  Returns:
52
- ``CONTEXT_SETUP_VERSIONS`` for the setup-version scope, else ``CONTEXT_MISSIONS``.
55
+ The matching ``CONTEXT_*`` wire enum.
53
56
  """
54
57
  # TODO(validate): remove after prod validation
55
58
  # [VALIDATE CTXENUM] server resolves the concrete id (incl. setup->current version) from metadata
56
59
  if context == self.setup_version_id or context.startswith("setup_versions:"):
57
60
  return data_pb2.CONTEXT_SETUP_VERSIONS
61
+ if context.startswith("users:"):
62
+ return data_pb2.CONTEXT_USERS
63
+ if context.startswith("organizations:"):
64
+ return data_pb2.CONTEXT_ORGANIZATIONS
58
65
  return data_pb2.CONTEXT_MISSIONS
59
66
 
60
67
  def _build_record_from_proto(self, proto: data_pb2.StorageRecord) -> StorageRecord:
@@ -74,6 +81,7 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
74
81
  coll = proto.collection
75
82
  rid = proto.record_id
76
83
  dtype = DataType[data_pb2.DataType.Name(proto.data_type)]
84
+ visibility = Visibility(proto.visibility)
77
85
 
78
86
  # Selective deserialization: only the nested Struct payload
79
87
  payload = ProtoUtils.proto_to_dict(proto.data) if proto.HasField("data") else {}
@@ -89,6 +97,7 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
89
97
  record_id=rid,
90
98
  data=validated,
91
99
  data_type=dtype,
100
+ visibility=visibility,
92
101
  creation_date=creation_date,
93
102
  update_date=update_date,
94
103
  )
@@ -127,16 +136,17 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
127
136
  StorageServiceError: If there is an error while storing the record
128
137
  """
129
138
  logger.debug("debug:_store collection=%s id=%s", record.collection, record.record_id)
139
+ data_struct = Struct()
140
+ data_struct.update(record.data.model_dump())
141
+ req = data_pb2.StoreRecordRequest(
142
+ data=data_struct,
143
+ context=self._context_enum(record.context),
144
+ collection=record.collection,
145
+ record_id=record.record_id,
146
+ data_type=record.data_type.name,
147
+ visibility=cast("data_pb2.Visibility", record.visibility.value),
148
+ )
130
149
  try:
131
- data_struct = Struct()
132
- data_struct.update(record.data.model_dump())
133
- req = data_pb2.StoreRecordRequest(
134
- data=data_struct,
135
- context=self._context_enum(record.context),
136
- collection=record.collection,
137
- record_id=record.record_id,
138
- data_type=record.data_type.name,
139
- )
140
150
  resp = await self.exec_grpc_query("StoreRecord", req)
141
151
  return self._build_record_from_proto(resp.stored_data)
142
152
  except PermissionDeniedError:
@@ -185,12 +195,19 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
185
195
  logger.warning("Invalid record data for %s:%s in ReadRecord", collection, record_id, exc_info=True)
186
196
  return None
187
197
 
198
+ try:
199
+ return self._build_record_from_proto(resp.stored_data)
200
+ except Exception:
201
+ logger.warning("Invalid record data for %s:%s in ReadRecord", collection, record_id, exc_info=True)
202
+ return None
203
+
188
204
  async def _update(
189
205
  self,
190
206
  collection: str,
191
207
  record_id: str,
192
208
  data: BaseModel,
193
209
  context: str,
210
+ visibility: Visibility = Visibility.UNSPECIFIED,
194
211
  ) -> StorageRecord | None:
195
212
  """Overwrite a document via gRPC scoped to a specific context.
196
213
 
@@ -201,15 +218,16 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
201
218
  PermissionDeniedError: If the service rejects the call with PERMISSION_DENIED.
202
219
  """
203
220
  logger.debug("debug:_update context=%s collection=%s id=%s", context, collection, record_id)
221
+ struct = Struct()
222
+ struct.update(data.model_dump())
223
+ req = data_pb2.UpdateRecordRequest(
224
+ data=struct,
225
+ context=self._context_enum(context),
226
+ collection=collection,
227
+ record_id=record_id,
228
+ visibility=cast("data_pb2.Visibility", visibility.value),
229
+ )
204
230
  try:
205
- struct = Struct()
206
- struct.update(data.model_dump())
207
- req = data_pb2.UpdateRecordRequest(
208
- data=struct,
209
- context=self._context_enum(context),
210
- collection=collection,
211
- record_id=record_id,
212
- )
213
231
  resp = await self.exec_grpc_query("UpdateRecord", req)
214
232
  return self._build_record_from_proto(resp.stored_data)
215
233
  except PermissionDeniedError:
@@ -252,7 +270,9 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
252
270
  return False
253
271
  return True
254
272
 
255
- async def _list(self, collection: str, context: str) -> list[StorageRecord]:
273
+ async def _list(
274
+ self, collection: str, context: str, visibilities: list[Visibility] | None = None
275
+ ) -> list[StorageRecord]:
256
276
  """List all documents in a collection via gRPC scoped to a specific context.
257
277
 
258
278
  Returns:
@@ -267,6 +287,8 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
267
287
  context=self._context_enum(context),
268
288
  collection=collection,
269
289
  )
290
+ if visibilities:
291
+ req.visibilities.extend(cast("data_pb2.Visibility", v.value) for v in visibilities)
270
292
  resp = await self.exec_grpc_query("ListRecords", req)
271
293
  except PermissionDeniedError:
272
294
  # TODO(validate): remove after prod validation