digitalkin 1.0.0.dev12__tar.gz → 1.0.0.dev14__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 (237) hide show
  1. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/PKG-INFO +1 -1
  2. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/pyproject.toml +1 -1
  3. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/__version__.py +1 -1
  4. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/common/factories.py +4 -10
  5. digitalkin-1.0.0.dev14/src/digitalkin/core/exceptions.py +33 -0
  6. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/base_task_manager.py +11 -7
  7. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/local_task_manager.py +6 -10
  8. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/redis/redis_client.py +10 -3
  9. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/remote_task_manager.py +6 -10
  10. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/task_session.py +37 -33
  11. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/gateway_servicer.py +11 -1
  12. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/module_server.py +4 -4
  13. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +6 -0
  14. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/logger.py +5 -0
  15. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/mixins/cost_mixin.py +1 -1
  16. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/module/tool_cache.py +3 -5
  17. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/modules/_base_module.py +4 -4
  18. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/storage/grpc_storage.py +11 -10
  19. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin.egg-info/PKG-INFO +1 -1
  20. digitalkin-1.0.0.dev12/src/digitalkin/core/exceptions.py +0 -16
  21. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/LICENSE +0 -0
  22. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/README.md +0 -0
  23. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/base_server/__init__.py +0 -0
  24. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/base_server/mock/__init__.py +0 -0
  25. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/base_server/mock/mock_pb2.py +0 -0
  26. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
  27. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/base_server/server_async_insecure.py +0 -0
  28. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/base_server/server_async_secure.py +0 -0
  29. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/base_server/server_sync_insecure.py +0 -0
  30. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/base_server/server_sync_secure.py +0 -0
  31. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/bench_module/__init__.py +0 -0
  32. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/bench_module/echo_module.py +0 -0
  33. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/bench_module/models/__init__.py +0 -0
  34. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/bench_module/models/input.py +0 -0
  35. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/bench_module/models/output.py +0 -0
  36. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/bench_module/models/secret.py +0 -0
  37. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/bench_module/models/setup.py +0 -0
  38. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/bench_module/server.py +0 -0
  39. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/bench_module/triggers/__init__.py +0 -0
  40. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/bench_module/triggers/message_trigger.py +0 -0
  41. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/modules/__init__.py +0 -0
  42. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/modules/archetype_with_tools_module.py +0 -0
  43. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/modules/cpu_intensive_module.py +0 -0
  44. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/modules/dynamic_setup_module.py +0 -0
  45. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/modules/minimal_llm_module.py +0 -0
  46. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/modules/text_transform_module.py +0 -0
  47. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
  48. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
  49. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
  50. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
  51. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
  52. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/monitoring/tests/test_metrics.py +0 -0
  53. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/redis_demo/client.py +0 -0
  54. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/redis_demo/echo_module.py +0 -0
  55. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/redis_demo/models/__init__.py +0 -0
  56. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/redis_demo/models/input.py +0 -0
  57. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/redis_demo/models/output.py +0 -0
  58. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/redis_demo/models/secret.py +0 -0
  59. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/redis_demo/models/setup.py +0 -0
  60. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/redis_demo/server.py +0 -0
  61. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/redis_demo/triggers/__init__.py +0 -0
  62. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/redis_demo/triggers/message_trigger.py +0 -0
  63. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/services/filesystem_module.py +0 -0
  64. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/examples/services/storage_module.py +0 -0
  65. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/setup.cfg +0 -0
  66. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/__init__.py +0 -0
  67. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/community/__init__.py +0 -0
  68. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/community/agno/__init__.py +0 -0
  69. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/community/agno/agno_adapter.py +0 -0
  70. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/community/agno/agui_tools.py +0 -0
  71. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/community/agno/hitl.py +0 -0
  72. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/community/agno/models.py +0 -0
  73. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/__init__.py +0 -0
  74. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/common/__init__.py +0 -0
  75. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/job_manager/__init__.py +0 -0
  76. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
  77. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
  78. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/profiling/__init__.py +0 -0
  79. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/profiling/step_timer.py +0 -0
  80. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/profiling/task_profiler.py +0 -0
  81. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/resilience/__init__.py +0 -0
  82. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/resilience/bulkhead.py +0 -0
  83. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
  84. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/__init__.py +0 -0
  85. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/module_runner.py +0 -0
  86. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
  87. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/redis/instrumented.py +0 -0
  88. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/redis/proto_streams.py +0 -0
  89. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/redis/redis_checkpoint.py +0 -0
  90. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +0 -0
  91. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/redis/redis_signal.py +0 -0
  92. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/redis/redis_state.py +0 -0
  93. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/redis/redis_streams.py +0 -0
  94. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/redis/shadow.py +0 -0
  95. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/core/task_manager/task_executor.py +0 -0
  96. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/exceptions.py +0 -0
  97. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/__init__.py +0 -0
  98. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/_base_server.py +0 -0
  99. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/exceptions.py +0 -0
  100. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
  101. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/interceptors/circuit_breaker_interceptor.py +0 -0
  102. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/m2m_call_registry.py +0 -0
  103. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/module_servicer.py +0 -0
  104. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/stream_registry.py +0 -0
  105. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/stream_session.py +0 -0
  106. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
  107. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +0 -0
  108. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +0 -0
  109. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
  110. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
  111. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/mixins/__init__.py +0 -0
  112. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/mixins/agui_mixin.py +0 -0
  113. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/mixins/base_mixin.py +0 -0
  114. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/mixins/file_history_mixin.py +0 -0
  115. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
  116. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/mixins/logger_mixin.py +0 -0
  117. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/mixins/storage_mixin.py +0 -0
  118. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/__init__.py +0 -0
  119. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/core/__init__.py +0 -0
  120. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/core/job_manager_models.py +0 -0
  121. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/core/redis.py +0 -0
  122. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/core/task_monitor.py +0 -0
  123. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/events/__init__.py +0 -0
  124. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/events/agent_events.py +0 -0
  125. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
  126. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
  127. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
  128. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/grpc_servers/models.py +0 -0
  129. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/grpc_servers/stream_error_codes.py +0 -0
  130. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/grpc_servers/types.py +0 -0
  131. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/module/__init__.py +0 -0
  132. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/module/ag_ui.py +0 -0
  133. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/module/base_types.py +0 -0
  134. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/module/module.py +0 -0
  135. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/module/module_context.py +0 -0
  136. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/module/module_types.py +0 -0
  137. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/module/request_metadata.py +0 -0
  138. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/module/select_schema.py +0 -0
  139. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/module/setup_types.py +0 -0
  140. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/module/tool_reference.py +0 -0
  141. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/module/utility.py +0 -0
  142. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/services/__init__.py +0 -0
  143. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/services/cost.py +0 -0
  144. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/services/registry.py +0 -0
  145. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/services/services.py +0 -0
  146. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/services/storage.py +0 -0
  147. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/__init__.py +0 -0
  148. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/consumer.py +0 -0
  149. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/gateway.py +0 -0
  150. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/grpc_client.py +0 -0
  151. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/log.py +0 -0
  152. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/module.py +0 -0
  153. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/profiling.py +0 -0
  154. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/queue.py +0 -0
  155. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/redis.py +0 -0
  156. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/resilience.py +0 -0
  157. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/server/__init__.py +0 -0
  158. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/server/channel.py +0 -0
  159. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/server/grpc.py +0 -0
  160. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/server/server.py +0 -0
  161. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/server/servicer.py +0 -0
  162. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/task_manager.py +0 -0
  163. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/utils/__init__.py +0 -0
  164. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/settings/utils/channel.py +0 -0
  165. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/utils/__init__.py +0 -0
  166. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
  167. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/modules/__init__.py +0 -0
  168. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/modules/archetype_module.py +0 -0
  169. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/modules/tool_module.py +0 -0
  170. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/modules/trigger_handler.py +0 -0
  171. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/modules/triggers/__init__.py +0 -0
  172. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
  173. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
  174. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
  175. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/py.typed +0 -0
  176. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/__init__.py +0 -0
  177. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/base_strategy.py +0 -0
  178. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/communication/__init__.py +0 -0
  179. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/communication/communication_strategy.py +0 -0
  180. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/communication/default_communication.py +0 -0
  181. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/communication/exceptions.py +0 -0
  182. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/communication/grpc_communication.py +0 -0
  183. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/cost/__init__.py +0 -0
  184. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/cost/cost_strategy.py +0 -0
  185. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/cost/default_cost.py +0 -0
  186. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/cost/exceptions.py +0 -0
  187. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/cost/grpc_cost.py +0 -0
  188. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/filesystem/__init__.py +0 -0
  189. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
  190. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/filesystem/exceptions.py +0 -0
  191. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/filesystem/filesystem_strategy.py +0 -0
  192. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/filesystem/grpc_filesystem.py +0 -0
  193. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/identity/__init__.py +0 -0
  194. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/identity/default_identity.py +0 -0
  195. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/identity/identity_strategy.py +0 -0
  196. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/registry/__init__.py +0 -0
  197. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/registry/default_registry.py +0 -0
  198. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/registry/exceptions.py +0 -0
  199. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/registry/grpc_registry.py +0 -0
  200. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/registry/registry_models.py +0 -0
  201. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/registry/registry_strategy.py +0 -0
  202. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/services_config.py +0 -0
  203. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/services_models.py +0 -0
  204. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/setup/__init__.py +0 -0
  205. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/setup/default_setup.py +0 -0
  206. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/setup/exceptions.py +0 -0
  207. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/setup/grpc_setup.py +0 -0
  208. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/setup/setup_strategy.py +0 -0
  209. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/storage/__init__.py +0 -0
  210. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/storage/default_storage.py +0 -0
  211. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/storage/exceptions.py +0 -0
  212. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/storage/storage_strategy.py +0 -0
  213. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/task_manager/__init__.py +0 -0
  214. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
  215. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/task_manager/exceptions.py +0 -0
  216. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
  217. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
  218. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/user_profile/__init__.py +0 -0
  219. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/user_profile/default_user_profile.py +0 -0
  220. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/user_profile/exceptions.py +0 -0
  221. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/user_profile/grpc_user_profile.py +0 -0
  222. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/services/user_profile/user_profile_strategy.py +0 -0
  223. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/utils/__init__.py +0 -0
  224. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/utils/arg_parser.py +0 -0
  225. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/utils/conditional_schema.py +0 -0
  226. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/utils/development_mode_action.py +0 -0
  227. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/utils/dynamic_schema.py +0 -0
  228. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/utils/exceptions.py +0 -0
  229. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/utils/llm_ready_schema.py +0 -0
  230. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/utils/package_discover.py +0 -0
  231. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/utils/proto_utils.py +0 -0
  232. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin/utils/schema_splitter.py +0 -0
  233. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin.egg-info/SOURCES.txt +0 -0
  234. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin.egg-info/dependency_links.txt +0 -0
  235. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin.egg-info/requires.txt +0 -0
  236. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/src/digitalkin.egg-info/top_level.txt +0 -0
  237. {digitalkin-1.0.0.dev12 → digitalkin-1.0.0.dev14}/tests/test_exceptions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalkin
3
- Version: 1.0.0.dev12
3
+ Version: 1.0.0.dev14
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-settings>=2.14.1",
38
38
  "redis[hiredis]>=7.4.0,<8",
39
39
  ]
40
- version = "1.0.0.dev12"
40
+ version = "1.0.0.dev14"
41
41
 
42
42
  [project.optional-dependencies]
43
43
  performance = [ "uvloop>=0.21" ]
@@ -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.0.dev12"
8
+ __version__ = "1.0.0.dev14"
@@ -64,16 +64,10 @@ class ModuleFactory:
64
64
  raise ValueError(msg)
65
65
 
66
66
  logger.debug(
67
- "Creating module instance: %s for job: %s",
67
+ "Creating module instance: %s (setup_version_id=%s)",
68
68
  module_class.__name__,
69
- job_id,
70
- extra={
71
- "module_class": module_class.__name__,
72
- "job_id": job_id,
73
- "mission_id": mission_id,
74
- "setup_id": setup_id,
75
- "setup_version_id": setup_version_id,
76
- },
69
+ setup_version_id,
70
+ extra={"job_id": job_id, "mission_id": mission_id, "setup_id": setup_id},
77
71
  )
78
72
 
79
73
  return module_class(
@@ -116,5 +110,5 @@ class QueueFactory:
116
110
  msg = "maxsize must be >= 0"
117
111
  raise ValueError(msg)
118
112
 
119
- logger.debug("Creating bounded queue with maxsize: %d", maxsize, extra={"maxsize": maxsize})
113
+ logger.debug("Creating bounded queue with maxsize: %d", maxsize)
120
114
  return asyncio.Queue(maxsize=maxsize)
@@ -0,0 +1,33 @@
1
+ """Exceptions for the DigitalKin core package."""
2
+
3
+
4
+ class BackpressureTimeoutError(Exception):
5
+ """Producer's XADD throttled past the backpressure timeout.
6
+
7
+ Throttled past :data:`GatewayBackpressureSettings.backpressure_timeout_s`.
8
+ Caller (typically the module's ``_on_output`` callback) must surface
9
+ this as ``stream.error(code=BACKPRESSURE_TIMEOUT)`` via the
10
+ ``_emit_fatal_to_redis`` path so the consumer sees a typed sentinel
11
+ instead of a silent stall.
12
+ """
13
+
14
+
15
+ class BulkheadFullError(Exception):
16
+ """Raised when a bulkhead semaphore cannot be acquired within timeout."""
17
+
18
+
19
+ class RedisUnreachableError(Exception):
20
+ """Raised at gateway boot when Redis ping fails.
21
+
22
+ Redis is a required dependency for gateway operation (stream persistence,
23
+ pub/sub signals). Failing fast at boot is preferable to lazy first-request
24
+ failures that surface as opaque task errors.
25
+ """
26
+
27
+ def __init__(self, masked_url: str) -> None:
28
+ """Initialize the error with a (masked) Redis URL for context.
29
+
30
+ Args:
31
+ masked_url: Redis connection URL with credentials masked.
32
+ """
33
+ super().__init__(f"Redis ping failed at gateway boot ({masked_url})")
@@ -103,14 +103,11 @@ class BaseTaskManager(ABC):
103
103
  if get_task_manager_settings().max_queued_tasks > 0:
104
104
  self._system_gate.release()
105
105
  logger.info(
106
- "Task cleaned up (%d remaining)",
106
+ "Task cleaned up (%d remaining) final_status=%s cancellation_reason=%s",
107
107
  len(self.tasks_sessions),
108
- extra={
109
- "mission_id": mission_id,
110
- "task_id": task_id,
111
- "final_status": final_status,
112
- "cancellation_reason": cancellation_reason,
113
- },
108
+ final_status,
109
+ cancellation_reason,
110
+ extra={"mission_id": mission_id, "task_id": task_id},
114
111
  )
115
112
 
116
113
  async def _validate_task_creation(self, task_id: str, mission_id: str, coro: Coroutine[Any, Any, None]) -> None:
@@ -302,6 +299,13 @@ class BaseTaskManager(ABC):
302
299
  )
303
300
 
304
301
  session = self.tasks_sessions[task_id]
302
+ if session.signal_service is None:
303
+ logger.warning(
304
+ "Cannot send signal - task has no signal_service (config-setup session?): '%s'",
305
+ task_id,
306
+ extra={"mission_id": mission_id, "task_id": task_id, "signal_type": signal_type},
307
+ )
308
+ return False
305
309
  await session.signal_service.send_signal(
306
310
  task_id,
307
311
  SignalMessage(
@@ -76,26 +76,22 @@ class LocalTaskManager(BaseTaskManager):
76
76
  self.tasks[task_id] = supervisor_task
77
77
 
78
78
  logger.info(
79
- "Local task created and started: '%s'",
79
+ "Local task created and started: '%s' (total_tasks=%d)",
80
80
  task_id,
81
- extra={
82
- "mission_id": mission_id,
83
- "task_id": task_id,
84
- "total_tasks": len(self.tasks),
85
- },
81
+ len(self.tasks),
82
+ extra={"mission_id": mission_id, "task_id": task_id},
86
83
  )
87
84
 
88
- except Exception as e:
85
+ except Exception:
89
86
  coro.close()
90
87
  # Release the slot if cleanup won't (session never registered).
91
88
  if task_id not in self.tasks_sessions:
92
89
  self._task_slot.release()
93
90
  else:
94
91
  await self._cleanup_task(task_id, mission_id=mission_id)
95
- logger.error(
92
+ logger.exception(
96
93
  "Failed to create local task: '%s'",
97
94
  task_id,
98
- extra={"mission_id": mission_id, "task_id": task_id, "error": str(e)},
99
- exc_info=True,
95
+ extra={"mission_id": mission_id, "task_id": task_id},
100
96
  )
101
97
  raise
@@ -69,17 +69,24 @@ class RedisClient: # noqa: PLR0904
69
69
  )
70
70
 
71
71
  async def verify(self) -> bool:
72
- """Verify Redis is reachable by sending a PING.
72
+ """Verify Redis is reachable by pinging both pools.
73
+
74
+ Pings ``_client`` and ``_blocking_client`` concurrently so the first
75
+ XADD and first XREAD don't each pay DNS+TCP+AUTH on cold pools.
73
76
 
74
77
  Timeout comes from ``RedisPoolSettings.health_check_timeout`` (env
75
78
  ``DIGITALKIN_REDIS_HEALTH_CHECK_TIMEOUT``).
76
79
 
77
80
  Returns:
78
- True if Redis responded, False if unreachable.
81
+ True if both pools responded, False if either is unreachable.
79
82
  """
80
83
  try:
81
84
  timeout = get_redis_settings().pool.health_check_timeout
82
- return await asyncio.wait_for(self._client.ping(), timeout=timeout) # type: ignore[arg-type]
85
+ results = await asyncio.gather(
86
+ asyncio.wait_for(self._client.ping(), timeout=timeout), # type: ignore[arg-type]
87
+ asyncio.wait_for(self._blocking_client.ping(), timeout=timeout), # type: ignore[arg-type]
88
+ )
89
+ return all(results)
83
90
  except Exception:
84
91
  logger.warning("Redis health check failed for %s", GatewayValidator.mask_redis_url(self.url), exc_info=True)
85
92
  return False
@@ -57,26 +57,22 @@ class RemoteTaskManager(BaseTaskManager):
57
57
  coro.close()
58
58
 
59
59
  logger.info(
60
- "Remote task registered: '%s'",
60
+ "Remote task registered: '%s' (total_sessions=%d)",
61
61
  task_id,
62
- extra={
63
- "mission_id": mission_id,
64
- "task_id": task_id,
65
- "total_sessions": len(self.tasks_sessions),
66
- },
62
+ len(self.tasks_sessions),
63
+ extra={"mission_id": mission_id, "task_id": task_id},
67
64
  )
68
65
 
69
- except Exception as e:
66
+ except Exception:
70
67
  coro.close()
71
68
  # Release semaphore if session was never registered (cleanup won't release it)
72
69
  if task_id not in self.tasks_sessions:
73
70
  self._task_slot.release()
74
71
  else:
75
72
  await self._cleanup_task(task_id, mission_id=mission_id)
76
- logger.error(
73
+ logger.exception(
77
74
  "Failed to register remote task: '%s'",
78
75
  task_id,
79
- extra={"mission_id": mission_id, "task_id": task_id, "error": str(e)},
80
- exc_info=True,
76
+ extra={"mission_id": mission_id, "task_id": task_id},
81
77
  )
82
78
  raise
@@ -26,7 +26,7 @@ if TYPE_CHECKING:
26
26
  class TaskSession:
27
27
  """Ephemeral lifecycle context for one task, optionally persisted to Redis."""
28
28
 
29
- signal_service: TaskManagerStrategy
29
+ signal_service: TaskManagerStrategy | None
30
30
  module: BaseModule
31
31
 
32
32
  _status: str
@@ -69,7 +69,9 @@ class TaskSession:
69
69
  queue_maxsize: Maximum size for the queue (0 = unlimited)
70
70
  state_manager: Optional Redis state manager for persistent status tracking
71
71
  """
72
- assert module.context.task_manager is not None # noqa: S101 TaskSession requires it; set before run
72
+ # signal_service is None for config-setup TaskSessions (no signals to dispatch); see
73
+ # SingleJobManager.create_config_setup_instance_job. Real-task sessions get it wired
74
+ # by preload_instance setting context.task_manager before _create_session runs.
73
75
  self.signal_service = module.context.task_manager
74
76
  self.module = module
75
77
  self._state_manager = state_manager
@@ -185,21 +187,22 @@ class TaskSession:
185
187
 
186
188
  ack_t0 = time.perf_counter_ns()
187
189
  ack_ok = False
188
- try:
189
- await self.signal_service.send_signal(
190
- self.task_id,
191
- SignalMessage(
192
- task_id=self.task_id,
193
- mission_id=self.mission_id,
194
- setup_id=self.setup_id,
195
- setup_version_id=self.setup_version_id,
196
- action=SignalType.ACK_CANCEL,
197
- cancellation_reason=reason,
198
- ).model_dump(exclude_none=True),
199
- )
200
- ack_ok = True
201
- except Exception:
202
- logger.warning("Cancel ack failed (best-effort)", extra=self.session_ids)
190
+ if self.signal_service is not None:
191
+ try:
192
+ await self.signal_service.send_signal(
193
+ self.task_id,
194
+ SignalMessage(
195
+ task_id=self.task_id,
196
+ mission_id=self.mission_id,
197
+ setup_id=self.setup_id,
198
+ setup_version_id=self.setup_version_id,
199
+ action=SignalType.ACK_CANCEL,
200
+ cancellation_reason=reason,
201
+ ).model_dump(exclude_none=True),
202
+ )
203
+ ack_ok = True
204
+ except Exception:
205
+ logger.warning("Cancel ack failed (best-effort)", extra=self.session_ids)
203
206
  ack_ns = time.perf_counter_ns() - ack_t0
204
207
 
205
208
  pub_ns = self.last_signal_published_ns
@@ -239,21 +242,22 @@ class TaskSession:
239
242
 
240
243
  ack_t0 = time.perf_counter_ns()
241
244
  ack_ok = False
242
- try:
243
- await self.signal_service.send_signal(
244
- self.task_id,
245
- SignalMessage(
246
- task_id=self.task_id,
247
- mission_id=self.mission_id,
248
- setup_id=self.setup_id,
249
- setup_version_id=self.setup_version_id,
250
- action=SignalType.ACK_STOP,
251
- cancellation_reason=CancellationReason.SIGNAL_SERVICE_STOP,
252
- ).model_dump(exclude_none=True),
253
- )
254
- ack_ok = True
255
- except Exception:
256
- logger.warning("Stop ack failed (best-effort)", extra=self.session_ids)
245
+ if self.signal_service is not None:
246
+ try:
247
+ await self.signal_service.send_signal(
248
+ self.task_id,
249
+ SignalMessage(
250
+ task_id=self.task_id,
251
+ mission_id=self.mission_id,
252
+ setup_id=self.setup_id,
253
+ setup_version_id=self.setup_version_id,
254
+ action=SignalType.ACK_STOP,
255
+ cancellation_reason=CancellationReason.SIGNAL_SERVICE_STOP,
256
+ ).model_dump(exclude_none=True),
257
+ )
258
+ ack_ok = True
259
+ except Exception:
260
+ logger.warning("Stop ack failed (best-effort)", extra=self.session_ids)
257
261
  ack_ns = time.perf_counter_ns() - ack_t0
258
262
 
259
263
  pub_ns = self.last_signal_published_ns
@@ -280,7 +284,7 @@ class TaskSession:
280
284
  return
281
285
  self._cleanup_done = True
282
286
 
283
- logger.debug("Cleanup: draining queue", extra={"task_id": self.task_id, "queue_size": self.queue.qsize()})
287
+ logger.debug("Cleanup: draining queue (queue_size=%d)", self.queue.qsize(), extra=ids)
284
288
  try:
285
289
  while not self.queue.empty():
286
290
  self.queue.get_nowait()
@@ -15,6 +15,7 @@ from google.protobuf import struct_pb2
15
15
  from grpc._cython.cygrpc import UsageError as _GrpcUsageError # noqa: PLC2701
16
16
  from redis.exceptions import RedisError
17
17
 
18
+ from digitalkin.core.exceptions import RedisUnreachableError
18
19
  from digitalkin.core.profiling.step_timer import StepTimer
19
20
  from digitalkin.core.task_manager.redis.proto_streams import ProtoStreamReader
20
21
  from digitalkin.core.task_manager.redis.redis_signal import SharedRedisListener
@@ -131,7 +132,16 @@ class GatewayServicer:
131
132
  return task
132
133
 
133
134
  async def start(self) -> None:
134
- """Start the M2M call-registry TTL sweeper and PSUBSCRIBE the signal listener."""
135
+ """Start the M2M call-registry TTL sweeper and PSUBSCRIBE the signal listener.
136
+
137
+ Pre-warms both Redis pools so the first XADD and first XREAD don't pay
138
+ DNS+TCP+AUTH on cold connections.
139
+
140
+ Raises:
141
+ RedisUnreachableError: Redis ping failed; gateway cannot serve traffic.
142
+ """
143
+ if not await self._redis_client.verify():
144
+ raise RedisUnreachableError(GatewayValidator.mask_redis_url(self._redis_client.url))
135
145
  await self._m2m.start()
136
146
  listener = SharedRedisListener.singleton_or_none()
137
147
  if listener is not None:
@@ -246,11 +246,11 @@ class ModuleServer(BaseServer):
246
246
  advertise_address = get_server_settings().channel.advertise_host or get_server_settings().channel.host
247
247
 
248
248
  logger.info(
249
- "Registering module with registry at %s:%d version=%s",
249
+ "Registering module with registry at %s:%d version=%s module_id=%s",
250
250
  advertise_address,
251
251
  get_server_settings().channel.port,
252
252
  version,
253
- extra={"module_id": module_id},
253
+ module_id,
254
254
  )
255
255
 
256
256
  result = await self.registry.register(
@@ -265,10 +265,10 @@ class ModuleServer(BaseServer):
265
265
  raise RuntimeError(msg)
266
266
 
267
267
  logger.info(
268
- "Module registered successfully at %s:%d",
268
+ "Module registered successfully at %s:%d module_id=%s",
269
269
  advertise_address,
270
270
  get_server_settings().channel.port,
271
- extra={"module_id": result.module_id},
271
+ result.module_id,
272
272
  )
273
273
 
274
274
  async def start_async(self) -> None:
@@ -243,6 +243,12 @@ class GrpcClientWrapper:
243
243
  except grpc.RpcError as e:
244
244
  last_error = e
245
245
  if e.code() not in self._RETRYABLE_CODES or attempt == max_retries:
246
+ logger.warning(
247
+ "circuit-breaker tick: %s.%s [%s]",
248
+ self.service_name,
249
+ query_endpoint,
250
+ e.code().name,
251
+ )
246
252
  cb.record_failure()
247
253
  break
248
254
  logger.warning(
@@ -235,3 +235,8 @@ logger = LoggerFactory.setup_logger(
235
235
  "digitalkin",
236
236
  level=LoggerFactory.LEVEL_NAMES.get(get_logging_settings().level.upper(), logging.INFO),
237
237
  )
238
+
239
+ # Backwards-compatible re-exports for downstream that imported these directly
240
+ # (e.g. ``archetype_ada/logger.py``). Aliases to the staticmethods, identical behaviour.
241
+ setup_logger = LoggerFactory.setup_logger
242
+ add_file_handler = LoggerFactory.add_file_handler
@@ -28,7 +28,7 @@ class CostMixin:
28
28
  try:
29
29
  await context.cost.add(name, cost_config_name, quantity)
30
30
  except Exception:
31
- logger.error("Failed to add cost '%s' (config=%s), continuing", name, cost_config_name, exc_info=True)
31
+ logger.exception("Failed to add cost '%s' (config=%s), continuing", name, cost_config_name)
32
32
 
33
33
  @staticmethod
34
34
  async def get_cost(context: ModuleContext, name: str) -> list[CostData]:
@@ -205,11 +205,9 @@ class ToolCache(BaseModel):
205
205
  )
206
206
  self.entries[setup_id] = tool_module_info
207
207
  logger.debug(
208
- "Tool cached",
209
- extra={
210
- "setup_id": setup_id,
211
- "module_id": tool_module_info.module_id,
212
- },
208
+ "Tool cached: module_id=%s",
209
+ tool_module_info.module_id,
210
+ extra={"setup_id": setup_id},
213
211
  )
214
212
 
215
213
  def get(
@@ -560,7 +560,7 @@ class BaseModule( # Module SDK base class requires many public methods # noqa:
560
560
  )
561
561
  )
562
562
  except Exception:
563
- logger.exception("Failed to send error callback")
563
+ logger.exception("Failed to send error callback", extra=self.context.session.current_ids())
564
564
  else:
565
565
  self._status = ModuleStatus.STOPPING
566
566
 
@@ -627,7 +627,7 @@ class BaseModule( # Module SDK base class requires many public methods # noqa:
627
627
  self._status = ModuleStatus.FAILED
628
628
  short_description = "Error initializing module"
629
629
  error_detail = f"{type(e).__name__}: {e}" if str(e) else type(e).__name__
630
- logger.exception("%s: %s", short_description, error_detail)
630
+ logger.exception("%s: %s", short_description, error_detail, extra=self.context.session.current_ids())
631
631
  await callback(
632
632
  ModuleCodeModel(
633
633
  code="Error",
@@ -645,7 +645,7 @@ class BaseModule( # Module SDK base class requires many public methods # noqa:
645
645
  timer.mark("run_lifecycle")
646
646
  except Exception:
647
647
  self._status = ModuleStatus.FAILED
648
- logger.exception("Error during module lifecyle")
648
+ logger.exception("Error during module lifecycle", extra=self.context.session.current_ids())
649
649
  finally:
650
650
  timer.log("module.start", task_id=self.context.session.current_ids().get("job_id", ""))
651
651
  await self.stop()
@@ -691,7 +691,7 @@ class BaseModule( # Module SDK base class requires many public methods # noqa:
691
691
  )
692
692
  except Exception:
693
693
  self._status = ModuleStatus.FAILED
694
- logger.exception("Error stopping module")
694
+ logger.exception("Error stopping module", extra=self.context.session.current_ids())
695
695
 
696
696
  async def _resolve_tools(self, config_setup_data: SetupModelT) -> None:
697
697
  """Resolve tool references and build cache.
@@ -105,8 +105,8 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
105
105
  )
106
106
  resp = await self.exec_grpc_query("ReadRecord", req)
107
107
  return self._build_record_from_proto(resp.stored_data)
108
- except Exception:
109
- logger.debug("gRPC ReadRecord failed for %s:%s", collection, record_id)
108
+ except Exception as e:
109
+ logger.info("gRPC ReadRecord failed for %s:%s: %s", collection, record_id, e)
110
110
  return None
111
111
 
112
112
  async def _update(
@@ -137,8 +137,8 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
137
137
  )
138
138
  resp = await self.exec_grpc_query("UpdateRecord", req)
139
139
  return self._build_record_from_proto(resp.stored_data)
140
- except Exception:
141
- logger.warning("gRPC UpdateRecord failed for %s:%s", collection, record_id)
140
+ except Exception as e:
141
+ logger.warning("gRPC UpdateRecord failed for %s:%s: %s", collection, record_id, e)
142
142
  return None
143
143
 
144
144
  async def _remove(self, collection: str, record_id: str) -> bool:
@@ -159,11 +159,12 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
159
159
  record_id=record_id,
160
160
  )
161
161
  await self.exec_grpc_query("RemoveRecord", req)
162
- except Exception:
162
+ except Exception as e:
163
163
  logger.warning(
164
- "gRPC RemoveRecord failed for %s:%s",
164
+ "gRPC RemoveRecord failed for %s:%s: %s",
165
165
  collection,
166
166
  record_id,
167
+ e,
167
168
  )
168
169
  return False
169
170
  return True
@@ -185,8 +186,8 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
185
186
  )
186
187
  resp = await self.exec_grpc_query("ListRecords", req)
187
188
  return [self._build_record_from_proto(r) for r in resp.records]
188
- except Exception:
189
- logger.warning("gRPC ListRecords failed for %s", collection)
189
+ except Exception as e:
190
+ logger.warning("gRPC ListRecords failed for %s: %s", collection, e)
190
191
  return []
191
192
 
192
193
  async def _remove_collection(self, collection: str) -> bool:
@@ -204,8 +205,8 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
204
205
  collection=collection,
205
206
  )
206
207
  await self.exec_grpc_query("RemoveCollection", req)
207
- except Exception:
208
- logger.warning("gRPC RemoveCollection failed for %s", collection)
208
+ except Exception as e:
209
+ logger.warning("gRPC RemoveCollection failed for %s: %s", collection, e)
209
210
  return False
210
211
  return True
211
212
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalkin
3
- Version: 1.0.0.dev12
3
+ Version: 1.0.0.dev14
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
@@ -1,16 +0,0 @@
1
- """Exceptions for the DigitalKin core package."""
2
-
3
-
4
- class BackpressureTimeoutError(Exception):
5
- """Producer's XADD throttled past the backpressure timeout.
6
-
7
- Throttled past :data:`GatewayBackpressureSettings.backpressure_timeout_s`.
8
- Caller (typically the module's ``_on_output`` callback) must surface
9
- this as ``stream.error(code=BACKPRESSURE_TIMEOUT)`` via the
10
- ``_emit_fatal_to_redis`` path so the consumer sees a typed sentinel
11
- instead of a silent stall.
12
- """
13
-
14
-
15
- class BulkheadFullError(Exception):
16
- """Raised when a bulkhead semaphore cannot be acquired within timeout."""