digitalkin 0.3.2.dev18__tar.gz → 0.3.2.dev20__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 (149) hide show
  1. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/PKG-INFO +1 -1
  2. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/pyproject.toml +1 -1
  3. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/__version__.py +1 -1
  4. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/grpc_servers/module_servicer.py +27 -2
  5. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/module/setup_types.py +141 -102
  6. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/modules/_base_module.py +1 -15
  7. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/utils/__init__.py +14 -0
  8. digitalkin-0.3.2.dev20/src/digitalkin/utils/conditional_schema.py +260 -0
  9. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/utils/schema_splitter.py +16 -1
  10. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin.egg-info/PKG-INFO +1 -1
  11. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin.egg-info/SOURCES.txt +1 -0
  12. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/LICENSE +0 -0
  13. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/README.md +0 -0
  14. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/base_server/__init__.py +0 -0
  15. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/base_server/mock/__init__.py +0 -0
  16. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/base_server/mock/mock_pb2.py +0 -0
  17. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
  18. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/base_server/server_async_insecure.py +0 -0
  19. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/base_server/server_async_secure.py +0 -0
  20. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/base_server/server_sync_insecure.py +0 -0
  21. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/base_server/server_sync_secure.py +0 -0
  22. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/modules/__init__.py +0 -0
  23. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/modules/archetype_with_tools_module.py +0 -0
  24. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/modules/cpu_intensive_module.py +0 -0
  25. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/modules/dynamic_setup_module.py +0 -0
  26. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/modules/minimal_llm_module.py +0 -0
  27. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/modules/text_transform_module.py +0 -0
  28. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
  29. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
  30. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
  31. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
  32. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
  33. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/monitoring/tests/test_metrics.py +0 -0
  34. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/services/filesystem_module.py +0 -0
  35. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/examples/services/storage_module.py +0 -0
  36. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/setup.cfg +0 -0
  37. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/__init__.py +0 -0
  38. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/__init__.py +0 -0
  39. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/common/__init__.py +0 -0
  40. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/common/factories.py +0 -0
  41. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/job_manager/__init__.py +0 -0
  42. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
  43. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
  44. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/job_manager/taskiq_broker.py +0 -0
  45. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/job_manager/taskiq_job_manager.py +0 -0
  46. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/task_manager/__init__.py +0 -0
  47. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
  48. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
  49. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
  50. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/task_manager/surrealdb_repository.py +0 -0
  51. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/task_manager/task_executor.py +0 -0
  52. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/core/task_manager/task_session.py +0 -0
  53. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/grpc_servers/__init__.py +0 -0
  54. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/grpc_servers/_base_server.py +0 -0
  55. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/grpc_servers/module_server.py +0 -0
  56. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
  57. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/grpc_servers/utils/exceptions.py +0 -0
  58. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +0 -0
  59. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +0 -0
  60. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
  61. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/logger.py +0 -0
  62. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/mixins/__init__.py +0 -0
  63. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/mixins/base_mixin.py +0 -0
  64. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/mixins/callback_mixin.py +0 -0
  65. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/mixins/chat_history_mixin.py +0 -0
  66. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/mixins/cost_mixin.py +0 -0
  67. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/mixins/file_history_mixin.py +0 -0
  68. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
  69. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/mixins/logger_mixin.py +0 -0
  70. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/mixins/storage_mixin.py +0 -0
  71. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/__init__.py +0 -0
  72. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/core/__init__.py +0 -0
  73. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/core/job_manager_models.py +0 -0
  74. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/core/task_monitor.py +0 -0
  75. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
  76. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/grpc_servers/models.py +0 -0
  77. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/grpc_servers/types.py +0 -0
  78. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/module/__init__.py +0 -0
  79. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/module/base_types.py +0 -0
  80. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/module/module.py +0 -0
  81. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/module/module_context.py +0 -0
  82. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/module/module_types.py +0 -0
  83. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/module/tool_cache.py +0 -0
  84. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/module/tool_reference.py +0 -0
  85. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/module/utility.py +0 -0
  86. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/services/__init__.py +0 -0
  87. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/services/cost.py +0 -0
  88. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/services/registry.py +0 -0
  89. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/models/services/storage.py +0 -0
  90. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/modules/__init__.py +0 -0
  91. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/modules/archetype_module.py +0 -0
  92. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/modules/tool_module.py +0 -0
  93. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/modules/trigger_handler.py +0 -0
  94. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/modules/triggers/__init__.py +0 -0
  95. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
  96. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
  97. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
  98. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/py.typed +0 -0
  99. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/__init__.py +0 -0
  100. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/agent/__init__.py +0 -0
  101. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/agent/agent_strategy.py +0 -0
  102. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/agent/default_agent.py +0 -0
  103. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/base_strategy.py +0 -0
  104. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/communication/__init__.py +0 -0
  105. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/communication/communication_strategy.py +0 -0
  106. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/communication/default_communication.py +0 -0
  107. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/communication/grpc_communication.py +0 -0
  108. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/cost/__init__.py +0 -0
  109. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/cost/cost_strategy.py +0 -0
  110. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/cost/default_cost.py +0 -0
  111. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/cost/grpc_cost.py +0 -0
  112. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/filesystem/__init__.py +0 -0
  113. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
  114. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/filesystem/filesystem_strategy.py +0 -0
  115. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/filesystem/grpc_filesystem.py +0 -0
  116. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/identity/__init__.py +0 -0
  117. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/identity/default_identity.py +0 -0
  118. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/identity/identity_strategy.py +0 -0
  119. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/registry/__init__.py +0 -0
  120. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/registry/default_registry.py +0 -0
  121. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/registry/exceptions.py +0 -0
  122. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/registry/grpc_registry.py +0 -0
  123. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/registry/registry_models.py +0 -0
  124. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/registry/registry_strategy.py +0 -0
  125. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/services_config.py +0 -0
  126. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/services_models.py +0 -0
  127. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/setup/__init__.py +0 -0
  128. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/setup/default_setup.py +0 -0
  129. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/setup/grpc_setup.py +0 -0
  130. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/setup/setup_strategy.py +0 -0
  131. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/snapshot/__init__.py +0 -0
  132. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/snapshot/default_snapshot.py +0 -0
  133. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/snapshot/snapshot_strategy.py +0 -0
  134. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/storage/__init__.py +0 -0
  135. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/storage/default_storage.py +0 -0
  136. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/storage/grpc_storage.py +0 -0
  137. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/storage/storage_strategy.py +0 -0
  138. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/user_profile/__init__.py +0 -0
  139. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/user_profile/default_user_profile.py +0 -0
  140. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/user_profile/grpc_user_profile.py +0 -0
  141. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/services/user_profile/user_profile_strategy.py +0 -0
  142. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/utils/arg_parser.py +0 -0
  143. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/utils/development_mode_action.py +0 -0
  144. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/utils/dynamic_schema.py +0 -0
  145. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/utils/llm_ready_schema.py +0 -0
  146. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin/utils/package_discover.py +0 -0
  147. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin.egg-info/dependency_links.txt +0 -0
  148. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin.egg-info/requires.txt +0 -0
  149. {digitalkin-0.3.2.dev18 → digitalkin-0.3.2.dev20}/src/digitalkin.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalkin
3
- Version: 0.3.2.dev18
3
+ Version: 0.3.2.dev20
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
@@ -12,7 +12,7 @@
12
12
 
13
13
  keywords = [ "digitalkin", "kin", "agent", "gprc", "sdk" ]
14
14
 
15
- version = "0.3.2.dev18"
15
+ version = "0.3.2.dev20"
16
16
  classifiers = [
17
17
  "Development Status :: 3 - Alpha",
18
18
  "Intended Audience :: Developers",
@@ -5,4 +5,4 @@ from importlib.metadata import PackageNotFoundError, version
5
5
  try:
6
6
  __version__ = version("digitalkin")
7
7
  except PackageNotFoundError:
8
- __version__ = "0.3.2.dev18"
8
+ __version__ = "0.3.2.dev20"
@@ -17,7 +17,7 @@ from digitalkin.core.job_manager.base_job_manager import BaseJobManager
17
17
  from digitalkin.grpc_servers.utils.exceptions import ServicerError
18
18
  from digitalkin.logger import logger
19
19
  from digitalkin.models.core.job_manager_models import JobManagerMode
20
- from digitalkin.models.module.module import ModuleStatus
20
+ from digitalkin.models.module.module import ModuleCodeModel, ModuleStatus
21
21
  from digitalkin.modules._base_module import BaseModule
22
22
  from digitalkin.services.registry import GrpcRegistry, RegistryStrategy
23
23
  from digitalkin.services.services_models import ServicesMode
@@ -159,7 +159,32 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
159
159
  return lifecycle_pb2.ConfigSetupModuleResponse(success=False)
160
160
 
161
161
  updated_setup_data = await self.job_manager.generate_config_setup_module_response(job_id)
162
- logger.info("Setup updated", extra={"job_id": job_id})
162
+ logger.info("Setup response received", extra={"job_id": job_id})
163
+
164
+ # Check if response is an error
165
+ if isinstance(updated_setup_data, ModuleCodeModel):
166
+ logger.error(
167
+ "Config setup failed",
168
+ extra={"job_id": job_id, "code": updated_setup_data.code, "message": updated_setup_data.message},
169
+ )
170
+ context.set_code(grpc.StatusCode.INTERNAL)
171
+ context.set_details(updated_setup_data.message or "Config setup failed")
172
+ return lifecycle_pb2.ConfigSetupModuleResponse(success=False)
173
+
174
+ if isinstance(updated_setup_data, dict) and "code" in updated_setup_data:
175
+ # ModuleCodeModel was serialized to dict
176
+ logger.error(
177
+ "Config setup failed",
178
+ extra={
179
+ "job_id": job_id,
180
+ "code": updated_setup_data["code"],
181
+ "message": updated_setup_data.get("message"),
182
+ },
183
+ )
184
+ context.set_code(grpc.StatusCode.INTERNAL)
185
+ context.set_details(updated_setup_data.get("message") or "Config setup failed")
186
+ return lifecycle_pb2.ConfigSetupModuleResponse(success=False)
187
+
163
188
  logger.debug("Updated setup data", extra={"job_id": job_id, "setup_data": updated_setup_data})
164
189
  setup_version.content = json_format.ParseDict(
165
190
  updated_setup_data,
@@ -29,65 +29,12 @@ SetupModelT = TypeVar("SetupModelT", bound="SetupModel")
29
29
  class SetupModel(BaseModel, Generic[SetupModelT]):
30
30
  """Base setup model with dynamic schema and tool cache support."""
31
31
 
32
+ model_config = ConfigDict(extra="allow")
32
33
  _clean_model_cache: ClassVar[dict[tuple[type, bool, bool], type]] = {}
33
-
34
- def __init_subclass__(cls, **kwargs: Any) -> None: # noqa: ANN401
35
- """Inject hidden companion fields for ToolReference annotations.
36
-
37
- Args:
38
- **kwargs: Keyword arguments passed to parent.
39
- """
40
- super().__init_subclass__(**kwargs)
41
- cls._inject_tool_cache_fields()
42
-
43
- @classmethod
44
- def _inject_tool_cache_fields(cls) -> None:
45
- """Inject hidden companion fields for ToolReference annotations."""
46
- annotations = getattr(cls, "__annotations__", {})
47
- new_annotations: dict[str, Any] = {}
48
-
49
- for field_name, annotation in annotations.items():
50
- if cls._is_tool_reference_annotation(annotation):
51
- cache_field_name = f"{field_name}_cache"
52
- if cache_field_name not in annotations:
53
- # Check if it's a list type
54
- origin = get_origin(annotation)
55
- if origin is list:
56
- new_annotations[cache_field_name] = list[ToolModuleInfo]
57
- setattr(
58
- cls,
59
- cache_field_name,
60
- Field(default_factory=list, json_schema_extra={"hidden": True}),
61
- )
62
- else:
63
- new_annotations[cache_field_name] = ToolModuleInfo | None
64
- setattr(
65
- cls,
66
- cache_field_name,
67
- Field(default=None, json_schema_extra={"hidden": True}),
68
- )
69
-
70
- if new_annotations:
71
- cls.__annotations__ = {**annotations, **new_annotations}
72
-
73
- @classmethod
74
- def _is_tool_reference_annotation(cls, annotation: object) -> bool:
75
- """Check if annotation is ToolReference or Optional[ToolReference].
76
-
77
- Args:
78
- annotation: Type annotation to check.
79
-
80
- Returns:
81
- True if annotation is or contains ToolReference.
82
- """
83
- origin = get_origin(annotation)
84
- if origin is typing.Union or origin is types.UnionType:
85
- return any(
86
- arg is ToolReference or (isinstance(arg, type) and issubclass(arg, ToolReference))
87
- for arg in get_args(annotation)
88
- if arg is not type(None)
89
- )
90
- return annotation is ToolReference or (isinstance(annotation, type) and issubclass(annotation, ToolReference))
34
+ resolved_tools: dict[str, ToolModuleInfo] = Field(
35
+ default_factory=dict,
36
+ json_schema_extra={"hidden": True},
37
+ )
91
38
 
92
39
  @classmethod
93
40
  async def get_clean_model(
@@ -285,7 +232,7 @@ class SetupModel(BaseModel, Generic[SetupModelT]):
285
232
  if not has_changes:
286
233
  return model_cls
287
234
 
288
- root_extra = cls.model_config.get("json_schema_extra", {})
235
+ root_extra = model_cls.model_config.get("json_schema_extra", {})
289
236
 
290
237
  return create_model(
291
238
  model_cls.__name__,
@@ -346,7 +293,12 @@ class SetupModel(BaseModel, Generic[SetupModelT]):
346
293
  communication: Communication service for module schemas.
347
294
  """
348
295
  logger.info("Starting resolve_tool_references")
349
- await self._resolve_tool_references_recursive(self, registry, communication)
296
+ await self._resolve_tool_references_recursive(
297
+ self,
298
+ registry,
299
+ communication,
300
+ self.resolved_tools,
301
+ )
350
302
  logger.info("Finished resolve_tool_references")
351
303
 
352
304
  @classmethod
@@ -355,6 +307,7 @@ class SetupModel(BaseModel, Generic[SetupModelT]):
355
307
  model_instance: BaseModel,
356
308
  registry: "RegistryStrategy",
357
309
  communication: "CommunicationStrategy",
310
+ resolved_tools: dict[str, ToolModuleInfo],
358
311
  ) -> None:
359
312
  """Recursively resolve ToolReference fields in a model.
360
313
 
@@ -362,11 +315,18 @@ class SetupModel(BaseModel, Generic[SetupModelT]):
362
315
  model_instance: Model instance to process.
363
316
  registry: Registry service for resolution.
364
317
  communication: Communication service for module schemas.
318
+ resolved_tools: Cache of already resolved tools.
365
319
  """
366
320
  for field_name, field_value in model_instance.__dict__.items():
367
321
  if field_value is None:
368
322
  continue
369
- await cls._resolve_field_value(field_name, field_value, registry, communication)
323
+ await cls._resolve_field_value(
324
+ field_name,
325
+ field_value,
326
+ registry,
327
+ communication,
328
+ resolved_tools,
329
+ )
370
330
 
371
331
  @classmethod
372
332
  async def _resolve_field_value(
@@ -375,6 +335,7 @@ class SetupModel(BaseModel, Generic[SetupModelT]):
375
335
  field_value: "BaseModel | ToolReference | list | dict",
376
336
  registry: "RegistryStrategy",
377
337
  communication: "CommunicationStrategy",
338
+ resolved_tools: dict[str, ToolModuleInfo],
378
339
  ) -> None:
379
340
  """Resolve a single field value based on its type.
380
341
 
@@ -383,15 +344,37 @@ class SetupModel(BaseModel, Generic[SetupModelT]):
383
344
  field_value: Value to process.
384
345
  registry: Registry service for resolution.
385
346
  communication: Communication service for module schemas.
347
+ resolved_tools: Cache of already resolved tools.
386
348
  """
387
349
  if isinstance(field_value, ToolReference):
388
- await cls._resolve_single_tool_reference(field_name, field_value, registry, communication)
350
+ await cls._resolve_single_tool_reference(
351
+ field_name,
352
+ field_value,
353
+ registry,
354
+ communication,
355
+ resolved_tools,
356
+ )
389
357
  elif isinstance(field_value, BaseModel):
390
- await cls._resolve_tool_references_recursive(field_value, registry, communication)
358
+ await cls._resolve_tool_references_recursive(
359
+ field_value,
360
+ registry,
361
+ communication,
362
+ resolved_tools,
363
+ )
391
364
  elif isinstance(field_value, list):
392
- await cls._resolve_list_items(field_value, registry, communication)
365
+ await cls._resolve_list_items(
366
+ field_value,
367
+ registry,
368
+ communication,
369
+ resolved_tools,
370
+ )
393
371
  elif isinstance(field_value, dict):
394
- await cls._resolve_dict_values(field_value, registry, communication)
372
+ await cls._resolve_dict_values(
373
+ field_value,
374
+ registry,
375
+ communication,
376
+ resolved_tools,
377
+ )
395
378
 
396
379
  @classmethod
397
380
  async def _resolve_single_tool_reference(
@@ -400,6 +383,7 @@ class SetupModel(BaseModel, Generic[SetupModelT]):
400
383
  tool_ref: ToolReference,
401
384
  registry: "RegistryStrategy",
402
385
  communication: "CommunicationStrategy",
386
+ resolved_tools: dict[str, ToolModuleInfo],
403
387
  ) -> None:
404
388
  """Resolve a single ToolReference.
405
389
 
@@ -408,17 +392,33 @@ class SetupModel(BaseModel, Generic[SetupModelT]):
408
392
  tool_ref: ToolReference to resolve.
409
393
  registry: Registry service for resolution.
410
394
  communication: Communication service for module schemas.
395
+ resolved_tools: Cache of already resolved tools.
411
396
  """
412
397
  logger.info("Resolving ToolReference '%s' with setup_id='%s'", field_name, tool_ref.config.setup_id)
398
+
399
+ slug = tool_ref.slug
400
+ if slug:
401
+ cached = resolved_tools.get(slug)
402
+ if cached:
403
+ tool_ref._cached_info = cached # noqa: SLF001
404
+ logger.info("ToolReference '%s' resolved from cache -> %s", field_name, cached)
405
+ return
406
+
413
407
  try:
414
- await tool_ref.resolve(registry, communication)
408
+ info = await tool_ref.resolve(registry, communication)
409
+ if info and info.setup_id:
410
+ resolved_tools[info.setup_id] = info
415
411
  logger.info("Resolved ToolReference '%s' -> %s", field_name, tool_ref.tool_module_info)
416
412
  except Exception:
417
413
  logger.exception("Failed to resolve ToolReference '%s'", field_name)
418
414
 
419
415
  @classmethod
420
416
  async def _resolve_list_items(
421
- cls, items: list, registry: "RegistryStrategy", communication: "CommunicationStrategy"
417
+ cls,
418
+ items: list,
419
+ registry: "RegistryStrategy",
420
+ communication: "CommunicationStrategy",
421
+ resolved_tools: dict[str, ToolModuleInfo],
422
422
  ) -> None:
423
423
  """Resolve ToolReference instances in a list.
424
424
 
@@ -426,16 +426,32 @@ class SetupModel(BaseModel, Generic[SetupModelT]):
426
426
  items: List of items to process.
427
427
  registry: Registry service for resolution.
428
428
  communication: Communication service for module schemas.
429
+ resolved_tools: Cache of already resolved tools.
429
430
  """
430
431
  for item in items:
431
432
  if isinstance(item, ToolReference):
432
- await cls._resolve_single_tool_reference("list_item", item, registry, communication)
433
+ await cls._resolve_single_tool_reference(
434
+ "list_item",
435
+ item,
436
+ registry,
437
+ communication,
438
+ resolved_tools,
439
+ )
433
440
  elif isinstance(item, BaseModel):
434
- await cls._resolve_tool_references_recursive(item, registry, communication)
441
+ await cls._resolve_tool_references_recursive(
442
+ item,
443
+ registry,
444
+ communication,
445
+ resolved_tools,
446
+ )
435
447
 
436
448
  @classmethod
437
449
  async def _resolve_dict_values(
438
- cls, mapping: dict, registry: "RegistryStrategy", communication: "CommunicationStrategy"
450
+ cls,
451
+ mapping: dict,
452
+ registry: "RegistryStrategy",
453
+ communication: "CommunicationStrategy",
454
+ resolved_tools: dict[str, ToolModuleInfo],
439
455
  ) -> None:
440
456
  """Resolve ToolReference instances in dict values.
441
457
 
@@ -443,63 +459,86 @@ class SetupModel(BaseModel, Generic[SetupModelT]):
443
459
  mapping: Dict to process.
444
460
  registry: Registry service for resolution.
445
461
  communication: Communication service for module schemas.
462
+ resolved_tools: Cache of already resolved tools.
446
463
  """
447
464
  for item in mapping.values():
448
465
  if isinstance(item, ToolReference):
449
- await cls._resolve_single_tool_reference("dict_value", item, registry, communication)
466
+ await cls._resolve_single_tool_reference(
467
+ "dict_value",
468
+ item,
469
+ registry,
470
+ communication,
471
+ resolved_tools,
472
+ )
450
473
  elif isinstance(item, BaseModel):
451
- await cls._resolve_tool_references_recursive(item, registry, communication)
474
+ await cls._resolve_tool_references_recursive(
475
+ item,
476
+ registry,
477
+ communication,
478
+ resolved_tools,
479
+ )
452
480
 
453
481
  def build_tool_cache(self) -> ToolCache:
454
- """Build tool cache from resolved ToolReferences, populating companion fields.
482
+ """Build tool cache from resolved ToolReferences.
455
483
 
456
484
  Returns:
457
485
  ToolCache with field names as keys and ToolModuleInfo as values.
458
486
  """
459
- logger.info("Building tool cache")
460
487
  cache = ToolCache()
461
488
  self._build_tool_cache_recursive(self, cache)
462
489
  logger.info("Tool cache built: %d entries", len(cache.entries))
463
490
  return cache
464
491
 
465
- def _build_tool_cache_recursive(self, model_instance: BaseModel, cache: ToolCache) -> None: # noqa: C901
466
- """Recursively build tool cache and populate companion fields.
492
+ def _build_tool_cache_recursive(self, model_instance: BaseModel, cache: ToolCache) -> None:
493
+ """Recursively build tool cache from ToolReferences.
467
494
 
468
495
  Args:
469
496
  model_instance: Model instance to process.
470
497
  cache: ToolCache to populate.
471
498
  """
472
- for field_name, field_value in model_instance.__dict__.items():
499
+ for field_value in model_instance.__dict__.values():
473
500
  if field_value is None:
474
501
  continue
475
502
  if isinstance(field_value, ToolReference):
476
- cache_field_name = f"{field_name}_cache"
477
-
478
- cached_info = getattr(model_instance, cache_field_name, None)
479
- module_info = field_value.tool_module_info or cached_info
503
+ module_info = self.resolved_tools.get(field_value.slug or "") or field_value.tool_module_info
480
504
  if module_info:
481
- if not cached_info:
482
- setattr(model_instance, cache_field_name, module_info)
505
+ self.resolved_tools[module_info.setup_id] = module_info
483
506
  cache.add(module_info.module_id, module_info)
484
- logger.debug("Added tool to cache: %s", module_info.module_id)
485
507
  elif isinstance(field_value, BaseModel):
486
508
  self._build_tool_cache_recursive(field_value, cache)
487
509
  elif isinstance(field_value, list):
488
- cache_field_name = f"{field_name}_cache"
489
- cached_infos = getattr(model_instance, cache_field_name, None) or []
490
- resolved_infos: list[ToolModuleInfo] = []
491
-
492
- for idx, item in enumerate(field_value):
493
- if isinstance(item, ToolReference):
494
- # Use resolved info or fallback to cached
495
- module_info = item.tool_module_info or (cached_infos[idx] if idx < len(cached_infos) else None)
496
- if module_info:
497
- resolved_infos.append(module_info)
498
- cache.add(module_info.module_id, module_info)
499
- logger.debug("Added tool to cache: %s", module_info.module_id)
500
- elif isinstance(item, BaseModel):
501
- self._build_tool_cache_recursive(item, cache)
502
-
503
- # Update companion field with resolved infos
504
- if resolved_infos:
505
- setattr(model_instance, cache_field_name, resolved_infos)
510
+ self._process_list_items(field_value, cache)
511
+ elif isinstance(field_value, dict):
512
+ self._process_dict_values(field_value, cache)
513
+
514
+ def _process_list_items(self, items: list, cache: ToolCache) -> None:
515
+ """Process list items for ToolReferences.
516
+
517
+ Args:
518
+ items: List to process.
519
+ cache: ToolCache to populate.
520
+ """
521
+ for item in items:
522
+ if isinstance(item, ToolReference):
523
+ module_info = self.resolved_tools.get(item.slug or "") or item.tool_module_info
524
+ if module_info:
525
+ self.resolved_tools[module_info.setup_id] = module_info
526
+ cache.add(module_info.module_id, module_info)
527
+ elif isinstance(item, BaseModel):
528
+ self._build_tool_cache_recursive(item, cache)
529
+
530
+ def _process_dict_values(self, mapping: dict, cache: ToolCache) -> None:
531
+ """Process dict values for ToolReferences.
532
+
533
+ Args:
534
+ mapping: Dict to process.
535
+ cache: ToolCache to populate.
536
+ """
537
+ for item in mapping.values():
538
+ if isinstance(item, ToolReference):
539
+ module_info = self.resolved_tools.get(item.slug or "") or item.tool_module_info
540
+ if module_info:
541
+ self.resolved_tools[module_info.setup_id] = module_info
542
+ cache.add(module_info.module_id, module_info)
543
+ elif isinstance(item, BaseModel):
544
+ self._build_tool_cache_recursive(item, cache)
@@ -556,21 +556,7 @@ class BaseModule( # noqa: PLR0904
556
556
  await self._resolve_tools(config_setup_data)
557
557
  updated_config = await self.run_config_setup(self.context, config_setup_data)
558
558
 
559
- # Build wrapper: original structure with updated content
560
- wrapper = config_setup_data.model_dump()
561
- wrapper["content"] = updated_config.model_dump()
562
-
563
- # Debug logging
564
- content = wrapper.get("content", {})
565
- logger.info(
566
- "Config setup wrapper: keys=%s, content_keys=%s, tools_cache=%s",
567
- list(wrapper.keys()),
568
- list(content.keys()) if isinstance(content, dict) else "N/A",
569
- content.get("tools_cache") if isinstance(content, dict) else "N/A",
570
- extra=self.context.session.current_ids(),
571
- )
572
-
573
- setup_model = await self.create_setup_model(wrapper)
559
+ setup_model = await self.create_setup_model(updated_config.model_dump())
574
560
  await callback(setup_model)
575
561
  self._status = ModuleStatus.STOPPING
576
562
  except Exception:
@@ -1,5 +1,12 @@
1
1
  """General utils folder."""
2
2
 
3
+ from digitalkin.utils.conditional_schema import (
4
+ Conditional,
5
+ ConditionalField,
6
+ ConditionalSchemaMixin,
7
+ get_conditional_metadata,
8
+ has_conditional,
9
+ )
3
10
  from digitalkin.utils.dynamic_schema import (
4
11
  DEFAULT_TIMEOUT,
5
12
  Dynamic,
@@ -14,13 +21,20 @@ from digitalkin.utils.dynamic_schema import (
14
21
  )
15
22
 
16
23
  __all__ = [
24
+ # Dynamic schema
17
25
  "DEFAULT_TIMEOUT",
26
+ # Conditional schema
27
+ "Conditional",
28
+ "ConditionalField",
29
+ "ConditionalSchemaMixin",
18
30
  "Dynamic",
19
31
  "DynamicField",
20
32
  "Fetcher",
21
33
  "ResolveResult",
34
+ "get_conditional_metadata",
22
35
  "get_dynamic_metadata",
23
36
  "get_fetchers",
37
+ "has_conditional",
24
38
  "has_dynamic",
25
39
  "resolve",
26
40
  "resolve_safe",