digitalkin 1.0.5.dev4__tar.gz → 1.0.5.dev5__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 (272) hide show
  1. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/PKG-INFO +2 -2
  2. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/redis_demo/client.py +52 -155
  3. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/pyproject.toml +2 -2
  4. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/__version__.py +1 -1
  5. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/action.py +19 -11
  6. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/base.py +22 -0
  7. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/services/action.py +10 -10
  8. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/services/kit.py +1 -1
  9. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/redis/redis_signal.py +2 -2
  10. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/gateway_servicer.py +69 -75
  11. digitalkin-1.0.5.dev5/src/digitalkin/grpc_servers/interceptors/validation.py +81 -0
  12. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/m2m_call_registry.py +3 -3
  13. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/module_server.py +39 -31
  14. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/module_servicer.py +130 -140
  15. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +43 -1
  16. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/module_context.py +2 -0
  17. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/tool_cache.py +1 -0
  18. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/services/registry.py +13 -9
  19. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/gateway.py +2 -2
  20. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/_base_module.py +55 -1
  21. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/communication/communication_strategy.py +6 -1
  22. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/communication/default_communication.py +7 -6
  23. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/communication/exceptions.py +4 -0
  24. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/communication/grpc_communication.py +36 -29
  25. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/cost/cost_strategy.py +1 -1
  26. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/cost/default_cost.py +17 -24
  27. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/cost/grpc_cost.py +115 -66
  28. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/filesystem/filesystem_strategy.py +2 -2
  29. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/filesystem/grpc_filesystem.py +127 -81
  30. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/registry/__init__.py +0 -2
  31. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/registry/default_registry.py +2 -22
  32. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/registry/grpc_registry.py +111 -125
  33. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/registry/registry_strategy.py +2 -6
  34. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/secret/grpc_secret.py +7 -5
  35. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/setup/default_setup.py +189 -46
  36. digitalkin-1.0.5.dev5/src/digitalkin/services/setup/grpc_setup.py +604 -0
  37. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/setup/setup_strategy.py +89 -18
  38. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/storage/default_storage.py +2 -5
  39. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/storage/grpc_storage.py +112 -62
  40. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/storage/storage_strategy.py +18 -16
  41. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/user_profile/default_user_profile.py +9 -3
  42. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/user_profile/grpc_user_profile.py +18 -12
  43. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/user_profile/user_profile_strategy.py +7 -3
  44. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/setup_content_validator.py +24 -0
  45. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin.egg-info/PKG-INFO +2 -2
  46. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin.egg-info/SOURCES.txt +1 -1
  47. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin.egg-info/requires.txt +1 -1
  48. digitalkin-1.0.5.dev4/src/digitalkin/services/registry/registry_models.py +0 -15
  49. digitalkin-1.0.5.dev4/src/digitalkin/services/setup/grpc_setup.py +0 -406
  50. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/LICENSE +0 -0
  51. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/README.md +0 -0
  52. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/base_server/__init__.py +0 -0
  53. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/base_server/mock/__init__.py +0 -0
  54. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/base_server/mock/mock_pb2.py +0 -0
  55. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
  56. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/base_server/server_async_insecure.py +0 -0
  57. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/base_server/server_async_secure.py +0 -0
  58. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/base_server/server_sync_insecure.py +0 -0
  59. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/base_server/server_sync_secure.py +0 -0
  60. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/bench_module/__init__.py +0 -0
  61. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/bench_module/echo_module.py +0 -0
  62. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/bench_module/models/__init__.py +0 -0
  63. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/bench_module/models/input.py +0 -0
  64. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/bench_module/models/output.py +0 -0
  65. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/bench_module/models/secret.py +0 -0
  66. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/bench_module/models/setup.py +0 -0
  67. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/bench_module/server.py +0 -0
  68. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/bench_module/triggers/__init__.py +0 -0
  69. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/bench_module/triggers/message_trigger.py +0 -0
  70. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/modules/__init__.py +0 -0
  71. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/modules/archetype_with_tools_module.py +0 -0
  72. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/modules/cpu_intensive_module.py +0 -0
  73. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/modules/dynamic_setup_module.py +0 -0
  74. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/modules/minimal_llm_module.py +0 -0
  75. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/modules/text_transform_module.py +0 -0
  76. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
  77. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
  78. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
  79. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
  80. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
  81. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/monitoring/tests/test_metrics.py +0 -0
  82. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/redis_demo/echo_module.py +0 -0
  83. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/redis_demo/models/__init__.py +0 -0
  84. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/redis_demo/models/input.py +0 -0
  85. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/redis_demo/models/output.py +0 -0
  86. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/redis_demo/models/secret.py +0 -0
  87. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/redis_demo/models/setup.py +0 -0
  88. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/redis_demo/server.py +0 -0
  89. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/redis_demo/triggers/__init__.py +0 -0
  90. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/redis_demo/triggers/message_trigger.py +0 -0
  91. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/services/filesystem_module.py +0 -0
  92. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/examples/services/storage_module.py +0 -0
  93. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/setup.cfg +0 -0
  94. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/__init__.py +0 -0
  95. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/__init__.py +0 -0
  96. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/__init__.py +0 -0
  97. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/agno_adapter.py +0 -0
  98. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/agui_tools.py +0 -0
  99. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/hitl.py +0 -0
  100. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/models.py +0 -0
  101. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/module_toolkit.py +0 -0
  102. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/__init__.py +0 -0
  103. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/base.py +0 -0
  104. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/chat_history.py +0 -0
  105. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/defaults.py +0 -0
  106. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/__init__.py +0 -0
  107. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/kins/__init__.py +0 -0
  108. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/kins/action.py +0 -0
  109. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/kins/kit.py +0 -0
  110. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/loader/__init__.py +0 -0
  111. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/loader/action.py +0 -0
  112. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/loader/kit.py +0 -0
  113. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/services/__init__.py +0 -0
  114. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/tools/__init__.py +0 -0
  115. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/tools/action.py +0 -0
  116. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/tools/kit.py +0 -0
  117. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/user_profile.py +0 -0
  118. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/__init__.py +0 -0
  119. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/common/__init__.py +0 -0
  120. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/common/factories.py +0 -0
  121. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/exceptions.py +0 -0
  122. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/job_manager/__init__.py +0 -0
  123. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
  124. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
  125. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/profiling/__init__.py +0 -0
  126. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/profiling/step_timer.py +0 -0
  127. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/profiling/task_profiler.py +0 -0
  128. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/resilience/__init__.py +0 -0
  129. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/resilience/bulkhead.py +0 -0
  130. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
  131. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/__init__.py +0 -0
  132. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
  133. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
  134. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/module_runner.py +0 -0
  135. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
  136. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/redis/proto_streams.py +0 -0
  137. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/redis/redis_client.py +0 -0
  138. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +0 -0
  139. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
  140. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/task_executor.py +0 -0
  141. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/task_session.py +0 -0
  142. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/exceptions.py +0 -0
  143. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/__init__.py +0 -0
  144. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/_base_server.py +0 -0
  145. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/exceptions.py +0 -0
  146. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
  147. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/interceptors/permission.py +0 -0
  148. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/interceptors/request_ids.py +0 -0
  149. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/stream_registry.py +0 -0
  150. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/stream_session.py +0 -0
  151. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
  152. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +0 -0
  153. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +0 -0
  154. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
  155. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
  156. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/logger.py +0 -0
  157. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/__init__.py +0 -0
  158. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/agui_mixin.py +0 -0
  159. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/base_mixin.py +0 -0
  160. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/cost_mixin.py +0 -0
  161. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/file_history_mixin.py +0 -0
  162. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
  163. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/logger_mixin.py +0 -0
  164. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/storage_mixin.py +0 -0
  165. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/__init__.py +0 -0
  166. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/core/__init__.py +0 -0
  167. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/core/job_manager_models.py +0 -0
  168. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/core/redis.py +0 -0
  169. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/core/task_monitor.py +0 -0
  170. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/events/__init__.py +0 -0
  171. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/events/agent_events.py +0 -0
  172. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
  173. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
  174. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
  175. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/grpc_servers/models.py +0 -0
  176. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/grpc_servers/stream_error_codes.py +0 -0
  177. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/grpc_servers/types.py +0 -0
  178. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/__init__.py +0 -0
  179. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/ag_ui.py +0 -0
  180. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/base_types.py +0 -0
  181. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/knowledge_files.py +0 -0
  182. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/loaded_tools.py +0 -0
  183. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/module.py +0 -0
  184. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/module_types.py +0 -0
  185. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/request_metadata.py +0 -0
  186. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/select_schema.py +0 -0
  187. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/setup_types.py +0 -0
  188. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/tool_reference.py +0 -0
  189. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/utility.py +0 -0
  190. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/services/__init__.py +0 -0
  191. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/services/cost.py +0 -0
  192. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/services/filesystem.py +0 -0
  193. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/services/services.py +0 -0
  194. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/services/storage.py +0 -0
  195. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/__init__.py +0 -0
  196. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/certificate.py +0 -0
  197. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/client/__init__.py +0 -0
  198. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/client/channel.py +0 -0
  199. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/client/circuit_breaker.py +0 -0
  200. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/client/client.py +0 -0
  201. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/client/grpc.py +0 -0
  202. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/log.py +0 -0
  203. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/module.py +0 -0
  204. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/profiling.py +0 -0
  205. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/queue.py +0 -0
  206. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/redis.py +0 -0
  207. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/registry.py +0 -0
  208. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/resilience.py +0 -0
  209. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/server/__init__.py +0 -0
  210. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/server/channel.py +0 -0
  211. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/server/grpc.py +0 -0
  212. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/server/server.py +0 -0
  213. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/server/servicer.py +0 -0
  214. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/task_manager.py +0 -0
  215. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/utils/__init__.py +0 -0
  216. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/utils/channel.py +0 -0
  217. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/utils/__init__.py +0 -0
  218. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
  219. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/__init__.py +0 -0
  220. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/archetype_module.py +0 -0
  221. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/tool_module.py +0 -0
  222. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/trigger_handler.py +0 -0
  223. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/triggers/__init__.py +0 -0
  224. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
  225. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
  226. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
  227. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/py.typed +0 -0
  228. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/__init__.py +0 -0
  229. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/base_strategy.py +0 -0
  230. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/communication/__init__.py +0 -0
  231. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/cost/__init__.py +0 -0
  232. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/cost/exceptions.py +0 -0
  233. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/filesystem/__init__.py +0 -0
  234. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
  235. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/filesystem/exceptions.py +0 -0
  236. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/identity/__init__.py +0 -0
  237. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/identity/default_identity.py +0 -0
  238. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/identity/identity_strategy.py +0 -0
  239. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/registry/exceptions.py +0 -0
  240. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/secret/__init__.py +0 -0
  241. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/secret/default_secret.py +0 -0
  242. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/secret/exceptions.py +0 -0
  243. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/secret/secret_strategy.py +0 -0
  244. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/services_config.py +0 -0
  245. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/services_models.py +0 -0
  246. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/setup/__init__.py +0 -0
  247. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/setup/exceptions.py +0 -0
  248. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/storage/__init__.py +0 -0
  249. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/storage/exceptions.py +0 -0
  250. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/task_manager/__init__.py +0 -0
  251. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
  252. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/task_manager/exceptions.py +0 -0
  253. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
  254. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
  255. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/user_profile/__init__.py +0 -0
  256. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/services/user_profile/exceptions.py +0 -0
  257. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/__init__.py +0 -0
  258. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/arg_parser.py +0 -0
  259. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/conditional_schema.py +0 -0
  260. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/development_mode_action.py +0 -0
  261. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/dynamic_schema.py +0 -0
  262. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/env_manager.py +0 -0
  263. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/env_template.py +0 -0
  264. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/exceptions.py +0 -0
  265. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/json_structure.py +0 -0
  266. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/llm_ready_schema.py +0 -0
  267. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/package_discover.py +0 -0
  268. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/proto_utils.py +0 -0
  269. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/schema_splitter.py +0 -0
  270. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin.egg-info/dependency_links.txt +0 -0
  271. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/src/digitalkin.egg-info/top_level.txt +0 -0
  272. {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev5}/tests/test_exceptions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalkin
3
- Version: 1.0.5.dev4
3
+ Version: 1.0.5.dev5
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
@@ -453,7 +453,7 @@ Requires-Python: >=3.10
453
453
  Description-Content-Type: text/markdown
454
454
  License-File: LICENSE
455
455
  Requires-Dist: ag-ui-protocol==0.1.21.dev1787220377
456
- Requires-Dist: agentic-mesh-protocol==1.0.2
456
+ Requires-Dist: agentic-mesh-protocol==1.2.0
457
457
  Requires-Dist: agno<3,>=2.8.0
458
458
  Requires-Dist: anyio>=4.13.0
459
459
  Requires-Dist: grpcio-health-checking==1.82.1
@@ -2,11 +2,10 @@
2
2
  """Demo client for the Gateway gRPC service with per-endpoint testing.
3
3
 
4
4
  Subcommands:
5
- full Full pipeline: StartStream → ConsumeStream → SendSignal
5
+ full Full pipeline: StartStream → Stream → SendSignal
6
6
  start StartStream only (unary)
7
- consume ConsumeStream on existing task (requires --task-id)
8
- produce StartStream + ProduceStream (act as Module A)
9
- signal SendSignal on existing task (requires --task-id)
7
+ consume Stream on existing task (requires --task-id)
8
+ signal SendSignal(cancel) on existing task (requires --task-id)
10
9
  inspect Dump Redis keys for a task (no gRPC)
11
10
 
12
11
  Usage:
@@ -14,8 +13,7 @@ Usage:
14
13
  python client.py full --prompt "Test" --setup '{"uppercase": true, "repeat": 5}'
15
14
  python client.py start --prompt "Hello"
16
15
  python client.py consume --task-id <uuid>
17
- python client.py produce --task-id <uuid> --chunks 3
18
- python client.py signal --task-id <uuid> --action cancel
16
+ python client.py signal --task-id <uuid>
19
17
  python client.py inspect --task-id <uuid>
20
18
  """
21
19
 
@@ -34,7 +32,7 @@ import grpc
34
32
  import redis.asyncio as aioredis
35
33
  from google.protobuf import json_format, struct_pb2
36
34
 
37
- from agentic_mesh_protocol.gateway.v1 import gateway_pb2, gateway_service_pb2_grpc
35
+ from agentic_mesh_protocol.gateway.v1 import gateway_dto_pb2, gateway_messages_pb2, gateway_service_pb2_grpc
38
36
 
39
37
  # ── ANSI colors ─────────────────────────────────────────────────────
40
38
 
@@ -291,29 +289,18 @@ def _print_diff_report(tracker: RedisTracker, task_id: str) -> None:
291
289
  async def cmd_start(
292
290
  stub: gateway_service_pb2_grpc.GatewayServiceStub,
293
291
  task_id: str,
294
- prompt: str,
295
- setup: dict[str, Any] | None,
296
292
  ) -> bool:
297
293
  """StartStream — create a task session.
298
294
 
299
295
  Returns:
300
296
  True if accepted.
301
297
  """
302
- input_struct = struct_pb2.Struct()
303
- payload: dict[str, Any] = {
304
- "root": {"protocol": "message", "text": prompt},
305
- }
306
- if setup:
307
- payload["setup"] = setup
308
- input_struct.update(payload)
309
-
310
298
  t0 = time.monotonic()
311
299
  resp = await stub.StartStream(
312
- gateway_pb2.StartStreamRequest(
300
+ gateway_dto_pb2.StartStreamRequest(
313
301
  task_id=task_id,
314
- input=input_struct,
315
- setup_id="demo-setup",
316
- mission_id="demo-mission",
302
+ setup_id="setups:demo",
303
+ mission_id="missions:demo",
317
304
  ),
318
305
  )
319
306
  elapsed = (time.monotonic() - t0) * 1000
@@ -327,112 +314,58 @@ async def cmd_start(
327
314
  async def cmd_consume(
328
315
  stub: gateway_service_pb2_grpc.GatewayServiceStub,
329
316
  task_id: str,
317
+ prompt: str,
318
+ setup: dict[str, Any] | None,
330
319
  verbose: bool,
331
320
  ) -> list[dict[str, Any]]:
332
- """ConsumeStream — read module output from Redis.
321
+ """Stream — send the query, then read module output until ``stream.end``.
333
322
 
334
323
  Returns:
335
324
  List of received items.
336
325
  """
337
326
  received: list[dict[str, Any]] = []
327
+ query: dict[str, Any] = {"root": {"protocol": "message", "text": prompt}}
328
+ if setup:
329
+ query["setup"] = setup
330
+ query_struct = struct_pb2.Struct()
331
+ query_struct.update(query)
338
332
 
339
333
  async def _requests() -> AsyncGenerator:
340
- yield gateway_pb2.ConsumeStreamRequest(
341
- init=gateway_pb2.ConsumeStreamInit(task_id=task_id, from_seq=0),
342
- )
334
+ yield gateway_messages_pb2.StreamRequest(task_id=task_id, from_seq=0, data=query_struct)
343
335
 
344
336
  t0 = time.monotonic()
345
- resp_stream = stub.ConsumeStream(_requests())
346
- async for resp in resp_stream:
347
- elapsed = (time.monotonic() - t0) * 1000
348
- payload_type = resp.WhichOneof("payload")
349
-
350
- if payload_type == "output":
351
- data_dict = json_format.MessageToDict(resp.output.data)
352
- text = data_dict.get("root", {}).get("text", data_dict.get("root", {}).get("protocol", ""))
353
- received.append({"seq": resp.output.seq, "text": text})
354
- print(f" {GREEN}seq={resp.output.seq:>2}{RESET} {text}") # noqa: T201
355
- if verbose:
356
- print(f" {DIM}{json.dumps(data_dict, ensure_ascii=False)}{RESET}") # noqa: T201
357
-
358
- elif payload_type == "status":
359
- state_name = gateway_pb2.StreamState.Name(resp.status.state)
360
- received.append({"status": state_name})
361
- color = GREEN if "COMPLETED" in state_name else YELLOW
362
- print(f" {color}status: {state_name}{RESET} ({elapsed:.1f}ms total)") # noqa: T201
363
- break
364
-
365
- elif payload_type == "error":
366
- received.append({"error": resp.error.message})
367
- print(f" {RED}error: code={resp.error.code} msg={resp.error.message}{RESET}") # noqa: T201
337
+ async for resp in stub.Stream(_requests()):
338
+ root = json_format.MessageToDict(resp.data).get("root", {})
339
+ protocol = root.get("protocol", "")
340
+ if protocol == "stream.error":
341
+ received.append({"seq": resp.seq, "error": root.get("message", "")})
342
+ print(f" {RED}error: code={root.get('code')} msg={root.get('message')}{RESET}") # noqa: T201
343
+ continue
344
+ if protocol == "stream.end":
345
+ received.append({"seq": resp.seq, "status": "stream.end"})
346
+ print(f" {GREEN}stream.end{RESET} ({(time.monotonic() - t0) * 1000:.1f}ms total)") # noqa: T201
368
347
  break
369
-
370
- elif payload_type == "heartbeat":
371
- if verbose:
372
- print(f" {DIM}heartbeat{RESET}") # noqa: T201
348
+ text = root.get("text", protocol)
349
+ received.append({"seq": resp.seq, "text": text})
350
+ print(f" {GREEN}seq={resp.seq:>2}{RESET} {text}") # noqa: T201
351
+ if verbose:
352
+ print(f" {DIM}{json.dumps(root, ensure_ascii=False)}{RESET}") # noqa: T201
373
353
 
374
354
  return received
375
355
 
376
356
 
377
- async def cmd_produce(
378
- stub: gateway_service_pb2_grpc.GatewayServiceStub,
379
- task_id: str,
380
- prompt: str,
381
- num_chunks: int,
382
- ) -> int:
383
- """ProduceStream — act as Module A, push output chunks.
384
-
385
- Returns:
386
- Number of server responses.
387
- """
388
- async def _requests() -> AsyncGenerator:
389
- yield gateway_pb2.ProduceStreamRequest(
390
- init=gateway_pb2.ProduceStreamInit(task_id=task_id),
391
- )
392
- for i in range(num_chunks):
393
- data = struct_pb2.Struct()
394
- data.update({
395
- "root": {
396
- "protocol": "message",
397
- "text": f"[{i + 1}/{num_chunks}] {prompt}",
398
- },
399
- })
400
- yield gateway_pb2.ProduceStreamRequest(
401
- output=gateway_pb2.ProduceStreamOutput(task_id=task_id, data=data),
402
- )
403
- await asyncio.sleep(0.05)
404
-
405
- t0 = time.monotonic()
406
- resp_stream = stub.ProduceStream(_requests())
407
- count = 0
408
- async for resp in resp_stream:
409
- count += 1
410
- payload = resp.WhichOneof("payload")
411
- print(f" response #{count}: {payload}") # noqa: T201
412
-
413
- elapsed = (time.monotonic() - t0) * 1000
414
- print(f" {DIM}stream closed ({count} responses, {elapsed:.1f}ms){RESET}") # noqa: T201
415
- return count
416
-
417
-
418
357
  async def cmd_signal(
419
358
  stub: gateway_service_pb2_grpc.GatewayServiceStub,
420
359
  task_id: str,
421
- action: str,
422
360
  ) -> bool:
423
- """SendSignal — send a control signal.
361
+ """SendSignal — cancel a running task.
424
362
 
425
363
  Returns:
426
364
  True if accepted.
427
365
  """
428
- action_enum = (
429
- gateway_pb2.SIGNAL_ACTION_CANCEL if action == "cancel"
430
- else gateway_pb2.SIGNAL_ACTION_PAUSE
431
- )
432
-
433
366
  t0 = time.monotonic()
434
367
  resp = await stub.SendSignal(
435
- gateway_pb2.ClientSignalRequest(task_id=task_id, action=action_enum),
368
+ gateway_dto_pb2.SendSignalRequest(cancel=gateway_messages_pb2.CancelSignal(task_id=task_id)),
436
369
  )
437
370
  elapsed = (time.monotonic() - t0) * 1000
438
371
 
@@ -447,7 +380,7 @@ async def cmd_signal(
447
380
 
448
381
 
449
382
  async def run_full(args: argparse.Namespace) -> None:
450
- """Full pipeline: StartStream → ConsumeStream → SendSignal."""
383
+ """Full pipeline: StartStream → Stream → SendSignal."""
451
384
  task_id = args.task_id or str(uuid.uuid4())
452
385
  setup = json.loads(args.setup) if args.setup else None
453
386
  tracker = RedisTracker(args.redis) if args.verbose else None
@@ -467,7 +400,7 @@ async def run_full(args: argparse.Namespace) -> None:
467
400
 
468
401
  # 1. StartStream
469
402
  print(f"\n{BOLD}[1] StartStream{RESET}") # noqa: T201
470
- accepted = await cmd_start(stub, task_id, args.prompt, setup)
403
+ accepted = await cmd_start(stub, task_id)
471
404
  if not accepted:
472
405
  print(f" {RED}Server rejected the task — aborting.{RESET}") # noqa: T201
473
406
  return
@@ -476,18 +409,17 @@ async def run_full(args: argparse.Namespace) -> None:
476
409
  await asyncio.sleep(0.1)
477
410
  await tracker.snapshot("StartStream", task_id)
478
411
 
479
- # 2. ConsumeStream — wait for module output
480
- print(f"\n{BOLD}[2] ConsumeStream{RESET}") # noqa: T201
481
- await asyncio.sleep(0.2) # let module start
482
- received = await cmd_consume(stub, task_id, args.verbose)
412
+ # 2. Stream — send the query, read module output
413
+ print(f"\n{BOLD}[2] Stream{RESET}") # noqa: T201
414
+ received = await cmd_consume(stub, task_id, args.prompt, setup, args.verbose)
483
415
 
484
416
  if tracker:
485
417
  await asyncio.sleep(0.1)
486
- await tracker.snapshot("ConsumeStream", task_id)
418
+ await tracker.snapshot("Stream", task_id)
487
419
 
488
420
  # 3. SendSignal
489
421
  print(f"\n{BOLD}[3] SendSignal (cancel){RESET}") # noqa: T201
490
- await cmd_signal(stub, task_id, "cancel")
422
+ await cmd_signal(stub, task_id)
491
423
 
492
424
  if tracker:
493
425
  await asyncio.sleep(0.1)
@@ -513,61 +445,39 @@ async def run_full(args: argparse.Namespace) -> None:
513
445
  async def run_start(args: argparse.Namespace) -> None:
514
446
  """StartStream only."""
515
447
  task_id = args.task_id or str(uuid.uuid4())
516
- setup = json.loads(args.setup) if args.setup else None
517
448
 
518
449
  print(f"\n{BOLD}[StartStream]{RESET} gateway={args.gateway} task_id={task_id}") # noqa: T201
519
450
 
520
451
  async with grpc.aio.insecure_channel(args.gateway, options=GRPC_OPTIONS) as channel:
521
452
  stub = gateway_service_pb2_grpc.GatewayServiceStub(channel)
522
- await cmd_start(stub, task_id, args.prompt, setup)
453
+ await cmd_start(stub, task_id)
523
454
 
524
455
 
525
456
  async def run_consume(args: argparse.Namespace) -> None:
526
- """ConsumeStream on existing task."""
457
+ """Stream on existing task."""
527
458
  if not args.task_id:
528
459
  print(f"{RED}--task-id is required for consume{RESET}") # noqa: T201
529
460
  sys.exit(1)
530
461
 
531
- print(f"\n{BOLD}[ConsumeStream]{RESET} gateway={args.gateway} task_id={args.task_id}") # noqa: T201
532
-
533
- async with grpc.aio.insecure_channel(args.gateway, options=GRPC_OPTIONS) as channel:
534
- stub = gateway_service_pb2_grpc.GatewayServiceStub(channel)
535
- await cmd_consume(stub, args.task_id, args.verbose)
536
-
537
-
538
- async def run_produce(args: argparse.Namespace) -> None:
539
- """StartStream + ProduceStream (act as Module A)."""
540
- task_id = args.task_id or str(uuid.uuid4())
541
462
  setup = json.loads(args.setup) if args.setup else None
542
-
543
- print(f"\n{BOLD}[Produce]{RESET} gateway={args.gateway} task_id={task_id}") # noqa: T201
463
+ print(f"\n{BOLD}[Stream]{RESET} gateway={args.gateway} task_id={args.task_id}") # noqa: T201
544
464
 
545
465
  async with grpc.aio.insecure_channel(args.gateway, options=GRPC_OPTIONS) as channel:
546
466
  stub = gateway_service_pb2_grpc.GatewayServiceStub(channel)
547
-
548
- # StartStream first (registers the session)
549
- print(f"\n {BOLD}StartStream{RESET}") # noqa: T201
550
- accepted = await cmd_start(stub, task_id, args.prompt, setup)
551
- if not accepted:
552
- print(f" {RED}Rejected{RESET}") # noqa: T201
553
- return
554
-
555
- # ProduceStream (act as Module A)
556
- print(f"\n {BOLD}ProduceStream ({args.chunks} chunks){RESET}") # noqa: T201
557
- await cmd_produce(stub, task_id, args.prompt, args.chunks)
467
+ await cmd_consume(stub, args.task_id, args.prompt, setup, args.verbose)
558
468
 
559
469
 
560
470
  async def run_signal(args: argparse.Namespace) -> None:
561
- """SendSignal on existing task."""
471
+ """SendSignal(cancel) on existing task."""
562
472
  if not args.task_id:
563
473
  print(f"{RED}--task-id is required for signal{RESET}") # noqa: T201
564
474
  sys.exit(1)
565
475
 
566
- print(f"\n{BOLD}[SendSignal]{RESET} gateway={args.gateway} task_id={args.task_id} action={args.action}") # noqa: T201
476
+ print(f"\n{BOLD}[SendSignal]{RESET} gateway={args.gateway} task_id={args.task_id} signal=cancel") # noqa: T201
567
477
 
568
478
  async with grpc.aio.insecure_channel(args.gateway, options=GRPC_OPTIONS) as channel:
569
479
  stub = gateway_service_pb2_grpc.GatewayServiceStub(channel)
570
- await cmd_signal(stub, args.task_id, args.action)
480
+ await cmd_signal(stub, args.task_id)
571
481
 
572
482
 
573
483
  async def run_inspect(args: argparse.Namespace) -> None:
@@ -613,8 +523,7 @@ examples:
613
523
  %(prog)s full --prompt "Test" --setup '{"uppercase": true, "repeat": 5}'
614
524
  %(prog)s start --prompt "Hello"
615
525
  %(prog)s consume --task-id <uuid>
616
- %(prog)s produce --chunks 5 --prompt "Manual"
617
- %(prog)s signal --task-id <uuid> --action cancel
526
+ %(prog)s signal --task-id <uuid>
618
527
  %(prog)s inspect --task-id <uuid>
619
528
  """,
620
529
  )
@@ -631,21 +540,16 @@ examples:
631
540
  sub = p.add_subparsers(dest="command", help="Endpoint to test")
632
541
 
633
542
  # full (default)
634
- sub.add_parser("full", help="Full pipeline: StartStream -> ConsumeStream -> SendSignal")
543
+ sub.add_parser("full", help="Full pipeline: StartStream -> Stream -> SendSignal")
635
544
 
636
545
  # start
637
546
  sub.add_parser("start", help="StartStream only (unary)")
638
547
 
639
548
  # consume
640
- sub.add_parser("consume", help="ConsumeStream on existing task (requires --task-id)")
641
-
642
- # produce
643
- sp_produce = sub.add_parser("produce", help="StartStream + ProduceStream (act as Module A)")
644
- sp_produce.add_argument("--chunks", type=int, default=3, help="Number of chunks to produce (default: 3)")
549
+ sub.add_parser("consume", help="Stream on existing task (requires --task-id)")
645
550
 
646
551
  # signal
647
- sp_signal = sub.add_parser("signal", help="SendSignal on existing task (requires --task-id)")
648
- sp_signal.add_argument("--action", choices=["cancel", "pause"], default="cancel", help="Signal action (default: cancel)")
552
+ sub.add_parser("signal", help="SendSignal(cancel) on existing task (requires --task-id)")
649
553
 
650
554
  # inspect
651
555
  sub.add_parser("inspect", help="Dump Redis keys for a task (no gRPC)")
@@ -662,17 +566,10 @@ async def main() -> None:
662
566
  if not args.command:
663
567
  args.command = "full"
664
568
 
665
- # Set defaults for subcommand-specific args
666
- if not hasattr(args, "chunks"):
667
- args.chunks = 3
668
- if not hasattr(args, "action"):
669
- args.action = "cancel"
670
-
671
569
  handlers = {
672
570
  "full": run_full,
673
571
  "start": run_start,
674
572
  "consume": run_consume,
675
- "produce": run_produce,
676
573
  "signal": run_signal,
677
574
  "inspect": run_inspect,
678
575
  }
@@ -31,7 +31,7 @@
31
31
  # which is how a nested run's output is attributed to its author. Pinned exactly
32
32
  # because it is a dated prerelease; move to >=0.1.21 once that ships stable.
33
33
  "ag-ui-protocol==0.1.21.dev1787220377",
34
- "agentic-mesh-protocol==1.0.2",
34
+ "agentic-mesh-protocol==1.2.0",
35
35
  "agno>=2.8.0,<3",
36
36
  "anyio>=4.13.0",
37
37
  "grpcio-health-checking==1.82.1",
@@ -41,7 +41,7 @@
41
41
  "pydantic>=2.12.4",
42
42
  "redis[hiredis]>=7.4.0,<9",
43
43
  ]
44
- version = "1.0.5.dev4"
44
+ version = "1.0.5.dev5"
45
45
 
46
46
  [project.optional-dependencies]
47
47
  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.5.dev4"
8
+ __version__ = "1.0.5.dev5"
@@ -16,6 +16,7 @@ from pydantic import Field
16
16
  from digitalkin.community.agno.toolkits.registry.base import RegistryAction
17
17
  from digitalkin.logger import logger
18
18
  from digitalkin.models.services.registry import (
19
+ RegistryModuleType,
19
20
  RegistrySetupStatus,
20
21
  RegistrySortBy,
21
22
  RegistryVisibility,
@@ -36,7 +37,7 @@ class GetAction(RegistryAction):
36
37
  """Read the setup (always its current version), refusing a foreign object type.
37
38
 
38
39
  Returns:
39
- The setup with its current version, status and visibility.
40
+ The setup with its current version, status and visibility, and a service's key map.
40
41
  """
41
42
  return await ctx.ensure_kind(self.setup_id)
42
43
 
@@ -55,7 +56,6 @@ class SearchAction(RegistryAction):
55
56
  this manager's own kind. Filters combine with AND; within one filter the values are OR'd.
56
57
  """
57
58
 
58
- _DOC_PREVIEW_CHARS: ClassVar[int] = 300
59
59
  # The service ceiling itself (storage and registry both cap a page at 100), so the toolkit
60
60
  # no longer imposes a tighter one of its own.
61
61
  _MAX_RESULTS: ClassVar[int] = 100
@@ -125,14 +125,16 @@ class SearchAction(RegistryAction):
125
125
  # would both contradict ``total_returned`` and, at exactly ``cap`` rows, promise an empty
126
126
  # next page.
127
127
  truncated = len(usable) > cap
128
- rows = [self._row(setup) for setup in usable[:cap]]
128
+ rows = [self._row(setup, ctx.module_type) for setup in usable[:cap]]
129
129
  return {"total_returned": len(rows), "truncated": truncated, "offset": self.offset, "setups": rows}
130
130
 
131
- def _row(self, setup: SetupSummary) -> dict[str, Any]:
131
+ @staticmethod
132
+ def _row(setup: SetupSummary, module_type: RegistryModuleType) -> dict[str, Any]:
132
133
  """Trim one search hit to the fields a caller can act on.
133
134
 
134
135
  Args:
135
136
  setup: The summary returned by the registry.
137
+ module_type: The manager's object type; only services render a structure map.
136
138
 
137
139
  Returns:
138
140
  The rendered row.
@@ -147,11 +149,16 @@ class SearchAction(RegistryAction):
147
149
  "tags": setup.tags,
148
150
  "visibility": setup.visibility.value if setup.visibility else None,
149
151
  "status": setup.status.value if setup.status else None,
150
- "description": (setup.documentation or "")[: self._DOC_PREVIEW_CHARS],
152
+ "documentation": setup.documentation or None,
151
153
  }
152
- # Only service setups carry a map. Omitting the key rather than rendering an empty
153
- # one keeps the feature out of the tools and kins surfaces entirely.
154
- if setup.structure:
154
+ # Only service setups carry a map, so tools and kins rows never show one. A service row
155
+ # always does, {} included: a caller iterating rows must not meet a missing key.
156
+ if module_type == RegistryModuleType.SERVICE:
157
+ if not setup.structure:
158
+ logger.info(
159
+ "[VALIDATE STRUCTROW] service row rendered with an empty structure: setup_id=%s",
160
+ setup.setup_id,
161
+ ) # TODO(validate): remove after prod validation
155
162
  row["structure"] = setup.structure
156
163
  return row
157
164
 
@@ -182,9 +189,10 @@ class UpdateAction(RegistryAction):
182
189
  )
183
190
  documentation: str | None = Field(
184
191
  default=None,
185
- description="Free text describing what this instance is for, indexed by ``search``. "
186
- "Omit to keep the text the instance already has; pass a string to replace it, or an "
187
- "empty string to clear it.",
192
+ max_length=300,
193
+ description="Free text describing what this instance is for, indexed by ``search``, at "
194
+ "most 300 characters. Omit to keep the text the instance already has; pass a string to "
195
+ "replace it, or an empty string to clear it.",
188
196
  )
189
197
 
190
198
  def _type_payload(self) -> dict[str, Any]: # ruff: ignore[no-self-use]
@@ -158,6 +158,20 @@ class RegistryActionCtx(BaseActionCtx):
158
158
  raise ValueError(msg)
159
159
  return setup
160
160
 
161
+ async def structure_of(self, setup_id: str) -> dict[str, str]:
162
+ """Read a setup's stored key map from the registry search.
163
+
164
+ Like every search, it follows the index, which may briefly lag right after a write.
165
+
166
+ Args:
167
+ setup_id: The setup whose map to read.
168
+
169
+ Returns:
170
+ The map, or ``{}`` when the search summary carries none.
171
+ """
172
+ found = await self.registry.search_setups(setup_ids=[setup_id], module_types=[self.module_type], limit=1)
173
+ return found[0].structure if found else {}
174
+
161
175
 
162
176
  class RegistryAction(BaseAction[RegistryActionCtx], ABC):
163
177
  """Base for the discriminated registry actions shared across the three CRUD managers.
@@ -364,6 +378,14 @@ class RegistryObjectToolKit(DkToolkit):
364
378
  visibility = data.get("visibility")
365
379
  if isinstance(visibility, str) and visibility.startswith("VISIBILITY_"):
366
380
  data["visibility"] = visibility.removeprefix("VISIBILITY_").lower()
381
+ # A None map means the version carries none, as on every tools and kins read.
382
+ # Rendering it would put the feature on their surface.
383
+ version = data.get("current_setup_version")
384
+ if isinstance(version, dict) and "structure" in version and version["structure"] is None:
385
+ logger.info(
386
+ "[VALIDATE STRUCTREAD] uncarried structure omitted: setup_id=%s", data.get("id")
387
+ ) # TODO(validate): remove after prod validation
388
+ del version["structure"]
367
389
  return data
368
390
  if isinstance(value, ProtoMessage):
369
391
  return ProtoUtils.proto_to_dict(value)
@@ -51,9 +51,10 @@ class CreateServiceAction(RegistryAction):
51
51
  )
52
52
  documentation: str = Field(
53
53
  default="",
54
- description="Free text describing what this service is for and when to use it. It is "
55
- "what ``search`` matches on and previews back, so a service created without it is "
56
- "findable only by name.",
54
+ max_length=300,
55
+ description="Free text describing what this service is for and when to use it, at most "
56
+ "300 characters. It is what ``search`` matches on and returns, so a service created "
57
+ "without it is findable only by name.",
57
58
  )
58
59
  structure: dict[str, str] = Field(
59
60
  ...,
@@ -101,8 +102,7 @@ class StructureServiceAction(RegistryAction):
101
102
  The key map, or an empty dict when the setup carries none.
102
103
  """
103
104
  await ctx.ensure_kind(self.setup_id)
104
- found = await ctx.registry.search_setups(setup_ids=[self.setup_id], module_types=[ctx.module_type], limit=1)
105
- return found[0].structure if found else {}
105
+ return await ctx.structure_of(self.setup_id)
106
106
 
107
107
 
108
108
  class LoadServiceAction(RegistryAction):
@@ -114,8 +114,8 @@ class LoadServiceAction(RegistryAction):
114
114
  default=None,
115
115
  description="One key path copied verbatim from the service's structure map, to read just "
116
116
  "that part of the configuration. Copy it, do not compose it: a key the configuration "
117
- "does not have is not an error, it returns the whole document. Omit the key to load "
118
- "everything deliberately, when the configuration is small or genuinely needed in full.",
117
+ "does not have fails with not found. Omit the key to load everything deliberately, "
118
+ "when the configuration is small or genuinely needed in full.",
119
119
  )
120
120
 
121
121
  async def execute(self, ctx: RegistryActionCtx) -> Any:
@@ -125,11 +125,11 @@ class LoadServiceAction(RegistryAction):
125
125
  internal configuration — the most dangerous type-confusion, since the response
126
126
  carries no field the caller could use to notice it read the wrong kind. The read
127
127
  itself passes ``key`` to the setup service, so the narrowing happens where the
128
- document lives; a key the configuration does not have returns the whole document
129
- rather than an error, which is what the wire does.
128
+ document lives; a key the configuration does not have is refused as not found,
129
+ which is what the wire does.
130
130
 
131
131
  Returns:
132
- ``{key: value}`` for a key that resolves, otherwise the whole configuration.
132
+ The part of the configuration ``key`` names, or the whole configuration without one.
133
133
  """
134
134
  await ctx.ensure_kind(self.setup_id)
135
135
  setup = await ctx.setup.get_setup({"setup_id": self.setup_id, "structure_key": self.key or ""})
@@ -44,7 +44,7 @@ class ServicesManager(RegistryObjectToolKit):
44
44
  "result with a 'structure' map of key path -> what lives there ('structure' fetches "
45
45
  "the same map for an id you already hold), then 'load' with a key copied verbatim "
46
46
  "from it returns just that part. Copy the key, never invent one: a key the "
47
- "configuration does not have quietly returns everything. Load without a key only when "
47
+ "configuration does not have fails with not found. Load without a key only when "
48
48
  "the whole document is genuinely needed. On create and update you write that map "
49
49
  "yourself, describing what "
50
50
  "each key is for — it is how other agents find their way around the configuration."
@@ -94,7 +94,7 @@ class SharedRedisListener:
94
94
  self._cache_invalidator: CacheInvalidator | None = None
95
95
 
96
96
  def set_cache_invalidator(self, handler: CacheInvalidator) -> None:
97
- """Register the ``(action_name, setup_id)`` handler invoked for ``invalidate_*`` signals."""
97
+ """Register the ``(scope_name, setup_id)`` handler invoked for ``invalidate_<scope>`` signals."""
98
98
  self._cache_invalidator = handler
99
99
 
100
100
  async def start(self) -> None:
@@ -186,7 +186,7 @@ class SharedRedisListener:
186
186
  )
187
187
  if self._cache_invalidator is not None:
188
188
  inv_task: asyncio.Task[None] = asyncio.create_task(
189
- self._cache_invalidator(action.upper(), setup_id),
189
+ self._cache_invalidator(action.removeprefix("invalidate_").upper(), setup_id),
190
190
  name=f"invalidate_{action}",
191
191
  )
192
192
  inv_task.add_done_callback(log_unhandled)