digitalkin 1.0.2.dev1__tar.gz → 1.0.2.dev2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/PKG-INFO +2 -2
  2. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/pyproject.toml +2 -2
  3. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/__version__.py +1 -1
  4. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/toolkits/registry.py +44 -11
  5. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/module_servicer.py +14 -4
  6. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/module/module_context.py +25 -0
  7. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/services/registry.py +1 -0
  8. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/filesystem/grpc_filesystem.py +29 -22
  9. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/registry/default_registry.py +2 -2
  10. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/registry/grpc_registry.py +2 -2
  11. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/registry/registry_strategy.py +42 -2
  12. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/storage/grpc_storage.py +25 -6
  13. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin.egg-info/PKG-INFO +2 -2
  14. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin.egg-info/requires.txt +1 -1
  15. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/LICENSE +0 -0
  16. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/README.md +0 -0
  17. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/base_server/__init__.py +0 -0
  18. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/base_server/mock/__init__.py +0 -0
  19. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/base_server/mock/mock_pb2.py +0 -0
  20. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
  21. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/base_server/server_async_insecure.py +0 -0
  22. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/base_server/server_async_secure.py +0 -0
  23. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/base_server/server_sync_insecure.py +0 -0
  24. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/base_server/server_sync_secure.py +0 -0
  25. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/bench_module/__init__.py +0 -0
  26. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/bench_module/echo_module.py +0 -0
  27. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/bench_module/models/__init__.py +0 -0
  28. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/bench_module/models/input.py +0 -0
  29. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/bench_module/models/output.py +0 -0
  30. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/bench_module/models/secret.py +0 -0
  31. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/bench_module/models/setup.py +0 -0
  32. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/bench_module/server.py +0 -0
  33. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/bench_module/triggers/__init__.py +0 -0
  34. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/bench_module/triggers/message_trigger.py +0 -0
  35. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/modules/__init__.py +0 -0
  36. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/modules/archetype_with_tools_module.py +0 -0
  37. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/modules/cpu_intensive_module.py +0 -0
  38. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/modules/dynamic_setup_module.py +0 -0
  39. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/modules/minimal_llm_module.py +0 -0
  40. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/modules/text_transform_module.py +0 -0
  41. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
  42. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
  43. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
  44. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
  45. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
  46. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/monitoring/tests/test_metrics.py +0 -0
  47. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/redis_demo/client.py +0 -0
  48. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/redis_demo/echo_module.py +0 -0
  49. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/redis_demo/models/__init__.py +0 -0
  50. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/redis_demo/models/input.py +0 -0
  51. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/redis_demo/models/output.py +0 -0
  52. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/redis_demo/models/secret.py +0 -0
  53. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/redis_demo/models/setup.py +0 -0
  54. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/redis_demo/server.py +0 -0
  55. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/redis_demo/triggers/__init__.py +0 -0
  56. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/redis_demo/triggers/message_trigger.py +0 -0
  57. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/services/filesystem_module.py +0 -0
  58. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/examples/services/storage_module.py +0 -0
  59. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/setup.cfg +0 -0
  60. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/__init__.py +0 -0
  61. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/__init__.py +0 -0
  62. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/__init__.py +0 -0
  63. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/agno_adapter.py +0 -0
  64. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/agui_tools.py +0 -0
  65. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/hitl.py +0 -0
  66. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/models.py +0 -0
  67. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/module_toolkit.py +0 -0
  68. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/toolkits/__init__.py +0 -0
  69. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/toolkits/base.py +0 -0
  70. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/toolkits/chat_history.py +0 -0
  71. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/toolkits/defaults.py +0 -0
  72. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/toolkits/setup.py +0 -0
  73. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/toolkits/tool_loader.py +0 -0
  74. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/community/agno/toolkits/user_profile.py +0 -0
  75. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/__init__.py +0 -0
  76. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/common/__init__.py +0 -0
  77. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/common/factories.py +0 -0
  78. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/exceptions.py +0 -0
  79. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/job_manager/__init__.py +0 -0
  80. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
  81. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
  82. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/profiling/__init__.py +0 -0
  83. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/profiling/step_timer.py +0 -0
  84. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/profiling/task_profiler.py +0 -0
  85. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/resilience/__init__.py +0 -0
  86. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/resilience/bulkhead.py +0 -0
  87. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
  88. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/__init__.py +0 -0
  89. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
  90. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
  91. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/module_runner.py +0 -0
  92. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
  93. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/redis/proto_streams.py +0 -0
  94. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/redis/redis_client.py +0 -0
  95. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +0 -0
  96. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/redis/redis_signal.py +0 -0
  97. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/redis/redis_state.py +0 -0
  98. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
  99. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/task_executor.py +0 -0
  100. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/core/task_manager/task_session.py +0 -0
  101. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/exceptions.py +0 -0
  102. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/__init__.py +0 -0
  103. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/_base_server.py +0 -0
  104. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/exceptions.py +0 -0
  105. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/gateway_servicer.py +0 -0
  106. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
  107. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/interceptors/permission.py +0 -0
  108. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/interceptors/request_ids.py +0 -0
  109. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/m2m_call_registry.py +0 -0
  110. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/module_server.py +0 -0
  111. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/stream_registry.py +0 -0
  112. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/stream_session.py +0 -0
  113. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
  114. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +0 -0
  115. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +0 -0
  116. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +0 -0
  117. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
  118. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
  119. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/logger.py +0 -0
  120. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/mixins/__init__.py +0 -0
  121. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/mixins/agui_mixin.py +0 -0
  122. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/mixins/base_mixin.py +0 -0
  123. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/mixins/cost_mixin.py +0 -0
  124. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/mixins/file_history_mixin.py +0 -0
  125. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
  126. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/mixins/logger_mixin.py +0 -0
  127. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/mixins/storage_mixin.py +0 -0
  128. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/__init__.py +0 -0
  129. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/core/__init__.py +0 -0
  130. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/core/job_manager_models.py +0 -0
  131. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/core/redis.py +0 -0
  132. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/core/task_monitor.py +0 -0
  133. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/events/__init__.py +0 -0
  134. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/events/agent_events.py +0 -0
  135. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
  136. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
  137. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
  138. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/grpc_servers/models.py +0 -0
  139. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/grpc_servers/stream_error_codes.py +0 -0
  140. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/grpc_servers/types.py +0 -0
  141. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/module/__init__.py +0 -0
  142. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/module/ag_ui.py +0 -0
  143. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/module/base_types.py +0 -0
  144. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/module/module.py +0 -0
  145. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/module/module_types.py +0 -0
  146. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/module/request_metadata.py +0 -0
  147. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/module/select_schema.py +0 -0
  148. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/module/setup_types.py +0 -0
  149. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/module/tool_cache.py +0 -0
  150. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/module/tool_reference.py +0 -0
  151. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/module/utility.py +0 -0
  152. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/services/__init__.py +0 -0
  153. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/services/cost.py +0 -0
  154. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/services/services.py +0 -0
  155. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/services/storage.py +0 -0
  156. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/__init__.py +0 -0
  157. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/gateway.py +0 -0
  158. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/grpc_client.py +0 -0
  159. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/log.py +0 -0
  160. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/module.py +0 -0
  161. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/profiling.py +0 -0
  162. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/queue.py +0 -0
  163. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/redis.py +0 -0
  164. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/registry.py +0 -0
  165. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/resilience.py +0 -0
  166. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/server/__init__.py +0 -0
  167. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/server/channel.py +0 -0
  168. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/server/grpc.py +0 -0
  169. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/server/server.py +0 -0
  170. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/server/servicer.py +0 -0
  171. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/task_manager.py +0 -0
  172. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/utils/__init__.py +0 -0
  173. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/settings/utils/channel.py +0 -0
  174. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/utils/__init__.py +0 -0
  175. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
  176. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/modules/__init__.py +0 -0
  177. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/modules/_base_module.py +0 -0
  178. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/modules/archetype_module.py +0 -0
  179. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/modules/tool_module.py +0 -0
  180. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/modules/trigger_handler.py +0 -0
  181. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/modules/triggers/__init__.py +0 -0
  182. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
  183. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
  184. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
  185. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/py.typed +0 -0
  186. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/__init__.py +0 -0
  187. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/base_strategy.py +0 -0
  188. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/communication/__init__.py +0 -0
  189. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/communication/communication_strategy.py +0 -0
  190. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/communication/default_communication.py +0 -0
  191. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/communication/exceptions.py +0 -0
  192. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/communication/grpc_communication.py +0 -0
  193. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/cost/__init__.py +0 -0
  194. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/cost/cost_strategy.py +0 -0
  195. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/cost/default_cost.py +0 -0
  196. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/cost/exceptions.py +0 -0
  197. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/cost/grpc_cost.py +0 -0
  198. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/filesystem/__init__.py +0 -0
  199. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
  200. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/filesystem/exceptions.py +0 -0
  201. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/filesystem/filesystem_strategy.py +0 -0
  202. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/identity/__init__.py +0 -0
  203. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/identity/default_identity.py +0 -0
  204. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/identity/identity_strategy.py +0 -0
  205. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/registry/__init__.py +0 -0
  206. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/registry/exceptions.py +0 -0
  207. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/registry/registry_models.py +0 -0
  208. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/secret/__init__.py +0 -0
  209. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/secret/default_secret.py +0 -0
  210. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/secret/exceptions.py +0 -0
  211. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/secret/grpc_secret.py +0 -0
  212. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/secret/secret_strategy.py +0 -0
  213. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/services_config.py +0 -0
  214. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/services_models.py +0 -0
  215. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/setup/__init__.py +0 -0
  216. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/setup/default_setup.py +0 -0
  217. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/setup/exceptions.py +0 -0
  218. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/setup/grpc_setup.py +0 -0
  219. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/setup/setup_strategy.py +0 -0
  220. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/storage/__init__.py +0 -0
  221. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/storage/default_storage.py +0 -0
  222. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/storage/exceptions.py +0 -0
  223. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/storage/storage_strategy.py +0 -0
  224. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/task_manager/__init__.py +0 -0
  225. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
  226. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/task_manager/exceptions.py +0 -0
  227. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
  228. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
  229. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/user_profile/__init__.py +0 -0
  230. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/user_profile/default_user_profile.py +0 -0
  231. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/user_profile/exceptions.py +0 -0
  232. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/user_profile/grpc_user_profile.py +0 -0
  233. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/services/user_profile/user_profile_strategy.py +0 -0
  234. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/utils/__init__.py +0 -0
  235. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/utils/arg_parser.py +0 -0
  236. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/utils/conditional_schema.py +0 -0
  237. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/utils/development_mode_action.py +0 -0
  238. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/utils/dynamic_schema.py +0 -0
  239. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/utils/exceptions.py +0 -0
  240. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/utils/llm_ready_schema.py +0 -0
  241. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/utils/package_discover.py +0 -0
  242. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/utils/proto_utils.py +0 -0
  243. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin/utils/schema_splitter.py +0 -0
  244. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin.egg-info/SOURCES.txt +0 -0
  245. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin.egg-info/dependency_links.txt +0 -0
  246. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/src/digitalkin.egg-info/top_level.txt +0 -0
  247. {digitalkin-1.0.2.dev1 → digitalkin-1.0.2.dev2}/tests/test_exceptions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalkin
3
- Version: 1.0.2.dev1
3
+ Version: 1.0.2.dev2
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.18
456
- Requires-Dist: agentic-mesh-protocol==1.0.1.dev3
456
+ Requires-Dist: agentic-mesh-protocol==1.0.1.dev4
457
457
  Requires-Dist: anyio>=4.13.0
458
458
  Requires-Dist: grpcio-health-checking==1.82.1
459
459
  Requires-Dist: grpcio-reflection==1.82.1
@@ -28,7 +28,7 @@
28
28
 
29
29
  dependencies = [
30
30
  "ag-ui-protocol>=0.1.18",
31
- "agentic-mesh-protocol==1.0.1.dev3",
31
+ "agentic-mesh-protocol==1.0.1.dev4",
32
32
  "anyio>=4.13.0",
33
33
  "grpcio-health-checking==1.82.1",
34
34
  "grpcio-reflection==1.82.1",
@@ -37,7 +37,7 @@
37
37
  "pydantic>=2.12.4",
38
38
  "redis[hiredis]>=7.4.0,<9",
39
39
  ]
40
- version = "1.0.2.dev1"
40
+ version = "1.0.2.dev2"
41
41
 
42
42
  [project.optional-dependencies]
43
43
  agno = [ "agno>=2.6" ]
@@ -5,4 +5,4 @@ from importlib.metadata import PackageNotFoundError, version
5
5
  try:
6
6
  __version__ = version("digitalkin")
7
7
  except PackageNotFoundError:
8
- __version__ = "1.0.2.dev1"
8
+ __version__ = "1.0.2.dev2"
@@ -37,7 +37,7 @@ class RegistryTools(DkToolkit):
37
37
  self._registry = registry
38
38
  super().__init__(
39
39
  name="registry_tools",
40
- tools=[self.search_setups, self.search_modules],
40
+ tools=[self.search_setups, self.search_modules, self.get_service_setup],
41
41
  context=context,
42
42
  )
43
43
 
@@ -49,10 +49,10 @@ class RegistryTools(DkToolkit):
49
49
  kind: The requested kind filter.
50
50
 
51
51
  Returns:
52
- Error message when ``kind`` is neither 'tool' nor 'kin', else None.
52
+ Error message when ``kind`` is not 'tool', 'kin' or 'service', else None.
53
53
  """
54
- if kind is not None and kind not in {"tool", "kin"}:
55
- return f"invalid kind '{kind}'; use 'tool' or 'kin'"
54
+ if kind is not None and kind not in {"tool", "kin", "service"}:
55
+ return f"invalid kind '{kind}'; use 'tool', 'kin' or 'service'"
56
56
  return None
57
57
 
58
58
  def _clamp(self, limit: int) -> int:
@@ -67,16 +67,16 @@ class RegistryTools(DkToolkit):
67
67
  return min(max(limit, 1), self._MAX_RESULTS)
68
68
 
69
69
  async def search_setups(
70
- self, query: str | None = None, kind: Literal["tool", "kin"] | None = None, limit: int = 10
70
+ self, query: str | None = None, kind: Literal["tool", "kin", "service"] | None = None, limit: int = 10
71
71
  ) -> str:
72
- """Search ready-to-use setups (configured agent/tool instances you can actually invoke).
72
+ """Search ready-to-use setups (configured agent/tool/service instances you can actually invoke).
73
73
 
74
74
  A setup is an installed, configured instance of a module — the thing you can
75
- call. Use this to discover which tools or agents (kins) are available.
75
+ call. Use this to discover which tools, agents (kins) or services are available.
76
76
 
77
77
  Args:
78
78
  query: Free text matched against setup name and documentation. Omit to list all.
79
- kind: Optional filter: "tool" (invocable tools) or "kin" (agents).
79
+ kind: Optional filter: "tool" (invocable tools), "kin" (agents) or "service".
80
80
  limit: Max results (default 10, max 25).
81
81
 
82
82
  Returns:
@@ -90,7 +90,13 @@ class RegistryTools(DkToolkit):
90
90
  try:
91
91
  setups = await self._registry.search_setups(
92
92
  query=query,
93
- module_types=[RegistryModuleType.ARCHETYPE if kind == "kin" else RegistryModuleType.TOOL_MODULE]
93
+ module_types=[
94
+ {
95
+ "tool": RegistryModuleType.TOOL_MODULE,
96
+ "kin": RegistryModuleType.ARCHETYPE,
97
+ "service": RegistryModuleType.SERVICE,
98
+ }[kind]
99
+ ]
94
100
  if kind
95
101
  else None,
96
102
  statuses=[RegistrySetupStatus.READY, RegistrySetupStatus.CONFIGURATION_SUCCEEDED],
@@ -122,8 +128,33 @@ class RegistryTools(DkToolkit):
122
128
  tool="search_setups",
123
129
  )
124
130
 
131
+ async def get_service_setup(self, setup_id: str) -> str:
132
+ """Fetch a service's configuration content (a JSON document) by setup id.
133
+
134
+ Use after discovering a service via ``search_setups`` and the user accepted it:
135
+ pass the proposed setup's ``setup_id`` to read the service content. Always
136
+ returns the latest version.
137
+
138
+ Args:
139
+ setup_id: The service setup id (from a ``search_setups`` result).
140
+
141
+ Returns:
142
+ The canonical envelope; ``output`` = the service configuration JSON object.
143
+ """
144
+ try:
145
+ content = await self._registry.get_service_setup(setup_id)
146
+ except PermissionDeniedError:
147
+ return self._fail("permission denied: get_service_setup", tool="get_service_setup")
148
+ except RegistryServiceError as error:
149
+ logger.warning("RegistryTools: service setup fetch failed: %s", error)
150
+ return self._fail(self._UNAVAILABLE, tool="get_service_setup")
151
+
152
+ if content is None:
153
+ return self._fail(f"service setup '{setup_id}' not found or has no content", tool="get_service_setup")
154
+ return self._ok(content, tool="get_service_setup")
155
+
125
156
  async def search_modules(
126
- self, query: str | None = None, kind: Literal["tool", "kin"] | None = None, limit: int = 10
157
+ self, query: str | None = None, kind: Literal["tool", "kin", "service"] | None = None, limit: int = 10
127
158
  ) -> str:
128
159
  """Search the module catalog (module TYPES, not configured instances).
129
160
 
@@ -133,7 +164,7 @@ class RegistryTools(DkToolkit):
133
164
 
134
165
  Args:
135
166
  query: Free text matched against module names. Omit to list all.
136
- kind: Optional filter: "tool" or "kin" (agents/archetypes).
167
+ kind: Optional filter: "tool", "kin" (agents/archetypes) or "service".
137
168
  limit: Max results (default 10, max 25).
138
169
 
139
170
  Returns:
@@ -148,6 +179,8 @@ class RegistryTools(DkToolkit):
148
179
  pending = self._registry.search_tools(name=query, limit=cap)
149
180
  elif kind == "kin":
150
181
  pending = self._registry.search_kins(name=query, limit=cap)
182
+ elif kind == "service":
183
+ pending = self._registry.search_services(name=query, limit=cap)
151
184
  else:
152
185
  pending = self._registry.search(name=query, limit=cap)
153
186
  try:
@@ -137,6 +137,8 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
137
137
 
138
138
  def invalidate_tool_cache(self) -> None:
139
139
  """Clear tool cache. Next request re-resolves tool definitions."""
140
+ if self._tool_cache_by_setup:
141
+ logger.info("tool cache invalidated, dropped setups: %s", list(self._tool_cache_by_setup))
140
142
  self._tool_cache_by_setup.clear()
141
143
 
142
144
  def get_tool_cache(self, setup_id: str) -> Any | None:
@@ -154,6 +156,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
154
156
  value, expires_at = entry
155
157
  if time.monotonic() >= expires_at:
156
158
  self._tool_cache_by_setup.pop(setup_id, None)
159
+ logger.debug("tool cache expired for setup '%s'", setup_id)
157
160
  return None
158
161
  return value
159
162
 
@@ -167,10 +170,14 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
167
170
  if len(self._tool_cache_by_setup) >= get_module_servicer_settings().setup_cache_max:
168
171
  oldest_key = next(iter(self._tool_cache_by_setup))
169
172
  del self._tool_cache_by_setup[oldest_key]
170
- self._tool_cache_by_setup[setup_id] = (
171
- value,
172
- time.monotonic() + get_gateway_settings().queue.toolkit_cache_ttl_s,
173
- )
173
+ logger.warning(
174
+ "tool cache full (%d), evicting setup '%s'",
175
+ get_module_servicer_settings().setup_cache_max,
176
+ oldest_key,
177
+ )
178
+ ttl_s = get_gateway_settings().queue.toolkit_cache_ttl_s
179
+ self._tool_cache_by_setup[setup_id] = (value, time.monotonic() + ttl_s)
180
+ logger.debug("tool cache set for setup '%s' (ttl %.0fs)", setup_id, ttl_s)
174
181
 
175
182
  async def get_or_build_tool_cache(
176
183
  self,
@@ -188,9 +195,11 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
188
195
  """
189
196
  cached = self.get_tool_cache(setup_id)
190
197
  if cached is not None:
198
+ logger.debug("tool cache hit for setup '%s'", setup_id)
191
199
  return cached
192
200
  inflight = self._tool_cache_inflight.get(setup_id)
193
201
  if inflight is not None:
202
+ logger.debug("tool cache build in flight for setup '%s', awaiting", setup_id)
194
203
  return await inflight
195
204
  loop = asyncio.get_event_loop()
196
205
  fut: asyncio.Future[Any] = loop.create_future()
@@ -205,6 +214,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
205
214
  # ``module_servicer.py:367``) clears the entry.
206
215
  if value is not None:
207
216
  self.set_tool_cache(setup_id, value)
217
+ logger.info("tool cache built for setup '%s'", setup_id)
208
218
  fut.set_result(value)
209
219
  except Exception as exc:
210
220
  fut.set_exception(exc)
@@ -350,18 +350,43 @@ class ModuleContext:
350
350
  """
351
351
  setup = await self.registry.get_setup(setup_id)
352
352
  if setup is None or not setup.module_id:
353
+ logger.warning(
354
+ "resolve_tool: setup '%s' not found or has no module", setup_id, extra=self.session.current_ids()
355
+ )
353
356
  return None
354
357
  cached = self.tool_cache.entries.get(setup_id)
355
358
  if cached is not None:
359
+ logger.debug(
360
+ "resolve_tool: cache hit for setup '%s' (authz re-checked)", setup_id, extra=self.session.current_ids()
361
+ )
356
362
  return cached
357
363
  try:
358
364
  info = await self.registry.discover_by_id(setup.module_id)
359
365
  except RegistryModuleNotFoundError:
366
+ logger.warning(
367
+ "resolve_tool: module '%s' for setup '%s' not found in registry",
368
+ setup.module_id,
369
+ setup_id,
370
+ extra=self.session.current_ids(),
371
+ )
360
372
  return None
361
373
  if info is None:
374
+ logger.warning(
375
+ "resolve_tool: module '%s' for setup '%s' not found in registry",
376
+ setup.module_id,
377
+ setup_id,
378
+ extra=self.session.current_ids(),
379
+ )
362
380
  return None
363
381
  tool_info = await ToolModuleInfo.from_module_info(info, setup_id, setup.name, self.communication)
364
382
  self.tool_cache.add(tool_info)
383
+ logger.info(
384
+ "resolve_tool: resolved setup '%s' -> module '%s' (%d tools), cached",
385
+ setup_id,
386
+ setup.module_id,
387
+ len(tool_info.tools),
388
+ extra=self.session.current_ids(),
389
+ )
365
390
  return tool_info
366
391
 
367
392
  @staticmethod
@@ -21,6 +21,7 @@ class RegistryModuleType(str, Enum):
21
21
  UNSPECIFIED = "unspecified"
22
22
  ARCHETYPE = "archetype"
23
23
  TOOL_MODULE = "tool_module"
24
+ SERVICE = "service"
24
25
 
25
26
 
26
27
  class ModuleInfo(BaseModel):
@@ -79,6 +79,29 @@ class GrpcFilesystem(FilesystemStrategy, GrpcClientWrapper, GrpcErrorHandlerMixi
79
79
  content=file.content,
80
80
  )
81
81
 
82
+ @staticmethod
83
+ def _context_enum(context: str) -> filesystem_pb2.ContextFile:
84
+ """Map a scope literal to the wire's context-kind enum.
85
+
86
+ Since dev4 the request carries only the kind; the concrete id is resolved
87
+ server-side from the x-mission-id / x-setup-id task metadata stamped by
88
+ ``RequestIdClientInterceptor``.
89
+
90
+ Args:
91
+ context: The scope literal ("mission" or "setup").
92
+
93
+ Returns:
94
+ The matching ``ContextFile`` enum value, ``CONTEXT_UNSPECIFIED`` otherwise.
95
+ """
96
+ # TODO(validate): remove after prod validation
97
+ # [VALIDATE CTXENUM] server resolves the concrete id from metadata
98
+ match context:
99
+ case "setup":
100
+ return filesystem_pb2.CONTEXT_SETUP
101
+ case "mission":
102
+ return filesystem_pb2.CONTEXT_MISSIONS
103
+ return filesystem_pb2.CONTEXT_UNSPECIFIED
104
+
82
105
  def _filter_to_proto(self, filters: FileFilter) -> filesystem_pb2.FileFilter:
83
106
  """Convert a FileFilter to a FileFilter proto message.
84
107
 
@@ -88,19 +111,13 @@ class GrpcFilesystem(FilesystemStrategy, GrpcClientWrapper, GrpcErrorHandlerMixi
88
111
  Returns:
89
112
  filesystem_pb2.FileFilter: The converted FileFilter proto message
90
113
  """
91
- context_id = "unknown"
92
- match filters.context:
93
- case "setup":
94
- context_id = self.setup_id
95
- case "mission":
96
- context_id = self.mission_id
97
114
  return filesystem_pb2.FileFilter(
98
115
  **filters.model_dump(exclude={"file_types", "status", "context"}),
99
116
  file_types=[self._file_type_to_enum(file_type) for file_type in filters.file_types]
100
117
  if filters.file_types
101
118
  else None,
102
119
  status=self._file_status_to_enum(filters.status) if filters.status else None,
103
- context=context_id,
120
+ context=self._context_enum(filters.context),
104
121
  )
105
122
 
106
123
  def __init__(
@@ -152,7 +169,7 @@ class GrpcFilesystem(FilesystemStrategy, GrpcClientWrapper, GrpcErrorHandlerMixi
152
169
  metadata_struct.update(file.metadata)
153
170
  upload_files.append(
154
171
  filesystem_pb2.UploadFileData(
155
- context=self.mission_id,
172
+ context=filesystem_pb2.CONTEXT_MISSIONS,
156
173
  name=file.name,
157
174
  file_type=self._file_type_to_enum(file.file_type),
158
175
  content_type=file.content_type or "application/octet-stream",
@@ -188,15 +205,10 @@ class GrpcFilesystem(FilesystemStrategy, GrpcClientWrapper, GrpcErrorHandlerMixi
188
205
  Raises:
189
206
  FilesystemServiceError: If there is an error retrieving the file
190
207
  """
191
- match context:
192
- case "setup":
193
- context_id = self.setup_id
194
- case "mission":
195
- context_id = self.mission_id
196
208
  logger.debug("debug:get_file file_id=%s context=%s", file_id, context)
197
209
  async with self.handle_grpc_errors("GetFile", FilesystemServiceError):
198
210
  request = filesystem_pb2.GetFileRequest(
199
- context=context_id,
211
+ context=self._context_enum(context),
200
212
  file_id=file_id,
201
213
  include_content=include_content,
202
214
  )
@@ -244,7 +256,7 @@ class GrpcFilesystem(FilesystemStrategy, GrpcClientWrapper, GrpcErrorHandlerMixi
244
256
  """
245
257
  async with self.handle_grpc_errors("UpdateFile", FilesystemServiceError):
246
258
  request = filesystem_pb2.UpdateFileRequest(
247
- context=self.mission_id,
259
+ context=filesystem_pb2.CONTEXT_MISSIONS,
248
260
  file_id=file_id,
249
261
  content=content,
250
262
  file_type=self._file_type_to_enum(file_type) if file_type else None,
@@ -279,7 +291,7 @@ class GrpcFilesystem(FilesystemStrategy, GrpcClientWrapper, GrpcErrorHandlerMixi
279
291
  logger.debug("debug:delete_files permanent=%s force=%s", permanent, force)
280
292
  async with self.handle_grpc_errors("DeleteFiles", FilesystemServiceError):
281
293
  request = filesystem_pb2.DeleteFilesRequest(
282
- context=self.mission_id,
294
+ context=filesystem_pb2.CONTEXT_MISSIONS,
283
295
  filters=self._filter_to_proto(filters),
284
296
  permanent=permanent,
285
297
  force=force,
@@ -309,14 +321,9 @@ class GrpcFilesystem(FilesystemStrategy, GrpcClientWrapper, GrpcErrorHandlerMixi
309
321
  Returns:
310
322
  tuple[list[FilesystemRecord], int]: List of files and total count
311
323
  """
312
- match filters.context:
313
- case "setup":
314
- context_id = self.setup_id
315
- case "mission":
316
- context_id = self.mission_id
317
324
  async with self.handle_grpc_errors("GetFiles", FilesystemServiceError):
318
325
  request = filesystem_pb2.GetFilesRequest(
319
- context=context_id,
326
+ context=self._context_enum(filters.context),
320
327
  filters=self._filter_to_proto(filters),
321
328
  include_content=include_content,
322
329
  list_size=list_size,
@@ -63,7 +63,7 @@ class DefaultRegistry(RegistryStrategy):
63
63
 
64
64
  Args:
65
65
  name: Case-insensitive free text matched against module name AND documentation.
66
- module_type: Filter by type (archetype, tool_module).
66
+ module_type: Filter by type (archetype, tool_module, service).
67
67
  limit: Max results (1-100).
68
68
  offset: Pagination offset.
69
69
 
@@ -221,7 +221,7 @@ class DefaultRegistry(RegistryStrategy):
221
221
  query: Case-insensitive free text matched against setup name AND documentation.
222
222
  setup_ids: Restrict to these setup ids.
223
223
  module_ids: Restrict to setups backed by these modules.
224
- module_types: Filter by backing module type (tool_module, archetype).
224
+ module_types: Filter by backing module type (tool_module, archetype, service).
225
225
  statuses: Filter by setup status. None = no filter.
226
226
  visibilities: Filter by visibility.
227
227
  limit: Max results (1-100).
@@ -213,7 +213,7 @@ class GrpcRegistry(RegistryStrategy, GrpcClientWrapper, GrpcErrorHandlerMixin):
213
213
 
214
214
  Args:
215
215
  name: Case-insensitive free text matched against module name AND documentation.
216
- module_type: Filter by type (archetype, tool_module).
216
+ module_type: Filter by type (archetype, tool_module, service).
217
217
  limit: Max results (1-100).
218
218
  offset: Pagination offset.
219
219
 
@@ -495,7 +495,7 @@ class GrpcRegistry(RegistryStrategy, GrpcClientWrapper, GrpcErrorHandlerMixin):
495
495
  query: Case-insensitive free text matched against setup name AND documentation.
496
496
  setup_ids: Restrict to these setup ids.
497
497
  module_ids: Restrict to setups backed by these modules.
498
- module_types: Filter by backing module type (tool_module, archetype).
498
+ module_types: Filter by backing module type (tool_module, archetype, service).
499
499
  statuses: Filter by setup status. None = no filter; agent-facing callers
500
500
  should pass READY/CONFIGURATION_SUCCEEDED for invocable setups.
501
501
  visibilities: Filter by visibility.
@@ -51,7 +51,7 @@ class RegistryStrategy(BaseStrategy, ABC):
51
51
 
52
52
  Args:
53
53
  name: Case-insensitive free text matched against module name AND documentation.
54
- module_type: Filter by type (archetype, tool_module).
54
+ module_type: Filter by type (archetype, tool_module, service).
55
55
  limit: Max results (1-100).
56
56
  offset: Pagination offset.
57
57
 
@@ -107,6 +107,29 @@ class RegistryStrategy(BaseStrategy, ABC):
107
107
  offset=offset,
108
108
  )
109
109
 
110
+ async def search_services(
111
+ self,
112
+ name: str | None = None,
113
+ limit: int = 20,
114
+ offset: int = 0,
115
+ ) -> list[ModuleInfo]:
116
+ """Service registry view: modules of type SERVICE.
117
+
118
+ Args:
119
+ name: Case-insensitive free text matched against module name AND documentation.
120
+ limit: Max results (1-100).
121
+ offset: Pagination offset.
122
+
123
+ Returns:
124
+ List of matching service modules.
125
+ """
126
+ return await self.search(
127
+ name=name,
128
+ module_type=RegistryModuleType.SERVICE.value,
129
+ limit=limit,
130
+ offset=offset,
131
+ )
132
+
110
133
  @abstractmethod
111
134
  async def search_setups(
112
135
  self,
@@ -125,7 +148,7 @@ class RegistryStrategy(BaseStrategy, ABC):
125
148
  query: Case-insensitive free text matched against setup name AND documentation.
126
149
  setup_ids: Restrict to these setup ids.
127
150
  module_ids: Restrict to setups backed by these modules.
128
- module_types: Filter by backing module type (tool_module, archetype).
151
+ module_types: Filter by backing module type (tool_module, archetype, service).
129
152
  statuses: Filter by setup status. None = no filter; agent-facing callers
130
153
  should pass READY/CONFIGURATION_SUCCEEDED for invocable setups.
131
154
  visibilities: Filter by visibility.
@@ -190,6 +213,23 @@ class RegistryStrategy(BaseStrategy, ABC):
190
213
  """Get setup info."""
191
214
  ...
192
215
 
216
+ async def get_service_setup(self, setup_id: str) -> dict[str, Any] | None:
217
+ """Fetch a service setup's setup_version content JSON.
218
+
219
+ The id comes from chat-driven discovery (``search_setups`` + user acceptance),
220
+ not from configuration. Goes through ``get_setup`` on every call — the registry
221
+ stays the permission gate; nothing cached. Content always reflects the latest
222
+ setup version.
223
+
224
+ Args:
225
+ setup_id: The discovered service setup id.
226
+
227
+ Returns:
228
+ The setup_version content, or None when the setup is missing or has no content.
229
+ """
230
+ setup = await self.get_setup(setup_id)
231
+ return setup.config if setup else None
232
+
193
233
  async def wait_for_ready(self, timeout: float = 1.0) -> bool: # noqa: PLR6301
194
234
  """Check if the registry backend is reachable.
195
235
 
@@ -38,6 +38,25 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
38
38
  """
39
39
  return isinstance(error.__cause__, CircuitOpenError)
40
40
 
41
+ def _context_enum(self, context: str) -> data_pb2.ContextStorage:
42
+ """Map a resolved context id-string to the wire's context-kind enum.
43
+
44
+ Since dev4 the request carries only the kind; the concrete id is resolved
45
+ server-side from the x-mission-id / x-setup-id task metadata stamped by
46
+ ``RequestIdClientInterceptor``.
47
+
48
+ Args:
49
+ context: The resolved context id (``self.mission_id`` or ``self.setup_version_id``).
50
+
51
+ Returns:
52
+ ``CONTEXT_SETUP_VERSIONS`` for the setup-version scope, else ``CONTEXT_MISSIONS``.
53
+ """
54
+ # TODO(validate): remove after prod validation
55
+ # [VALIDATE CTXENUM] server resolves the concrete id (incl. setup->current version) from metadata
56
+ if context == self.setup_version_id or context.startswith("setup_versions:"):
57
+ return data_pb2.CONTEXT_SETUP_VERSIONS
58
+ return data_pb2.CONTEXT_MISSIONS
59
+
41
60
  def _build_record_from_proto(self, proto: data_pb2.StorageRecord) -> StorageRecord:
42
61
  """Convert a protobuf StorageRecord message into our Pydantic model.
43
62
 
@@ -113,7 +132,7 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
113
132
  data_struct.update(record.data.model_dump())
114
133
  req = data_pb2.StoreRecordRequest(
115
134
  data=data_struct,
116
- context=record.context,
135
+ context=self._context_enum(record.context),
117
136
  collection=record.collection,
118
137
  record_id=record.record_id,
119
138
  data_type=record.data_type.name,
@@ -143,7 +162,7 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
143
162
  logger.debug("debug:_read context=%s collection=%s id=%s", context, collection, record_id)
144
163
  try:
145
164
  req = data_pb2.ReadRecordRequest(
146
- context=context,
165
+ context=self._context_enum(context),
147
166
  collection=collection,
148
167
  record_id=record_id,
149
168
  )
@@ -187,7 +206,7 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
187
206
  struct.update(data.model_dump())
188
207
  req = data_pb2.UpdateRecordRequest(
189
208
  data=struct,
190
- context=context,
209
+ context=self._context_enum(context),
191
210
  collection=collection,
192
211
  record_id=record_id,
193
212
  )
@@ -216,7 +235,7 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
216
235
  logger.debug("debug:_remove context=%s collection=%s id=%s", context, collection, record_id)
217
236
  try:
218
237
  req = data_pb2.RemoveRecordRequest(
219
- context=context,
238
+ context=self._context_enum(context),
220
239
  collection=collection,
221
240
  record_id=record_id,
222
241
  )
@@ -245,7 +264,7 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
245
264
  logger.debug("debug:_list context=%s collection=%s", context, collection)
246
265
  try:
247
266
  req = data_pb2.ListRecordsRequest(
248
- context=context,
267
+ context=self._context_enum(context),
249
268
  collection=collection,
250
269
  )
251
270
  resp = await self.exec_grpc_query("ListRecords", req)
@@ -273,7 +292,7 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
273
292
  """
274
293
  try:
275
294
  req = data_pb2.RemoveCollectionRequest(
276
- context=context,
295
+ context=self._context_enum(context),
277
296
  collection=collection,
278
297
  )
279
298
  await self.exec_grpc_query("RemoveCollection", req)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalkin
3
- Version: 1.0.2.dev1
3
+ Version: 1.0.2.dev2
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.18
456
- Requires-Dist: agentic-mesh-protocol==1.0.1.dev3
456
+ Requires-Dist: agentic-mesh-protocol==1.0.1.dev4
457
457
  Requires-Dist: anyio>=4.13.0
458
458
  Requires-Dist: grpcio-health-checking==1.82.1
459
459
  Requires-Dist: grpcio-reflection==1.82.1
@@ -1,5 +1,5 @@
1
1
  ag-ui-protocol>=0.1.18
2
- agentic-mesh-protocol==1.0.1.dev3
2
+ agentic-mesh-protocol==1.0.1.dev4
3
3
  anyio>=4.13.0
4
4
  grpcio-health-checking==1.82.1
5
5
  grpcio-reflection==1.82.1
File without changes