digitalkin 0.2.26__tar.gz → 0.3.2.dev8__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 (167) hide show
  1. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/PKG-INFO +11 -30
  2. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/base_server/server_async_insecure.py +6 -5
  3. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/base_server/server_async_secure.py +6 -5
  4. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/base_server/server_sync_insecure.py +5 -4
  5. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/base_server/server_sync_secure.py +5 -4
  6. digitalkin-0.3.2.dev8/examples/modules/archetype_with_tools_module.py +244 -0
  7. digitalkin-0.3.2.dev8/examples/modules/dynamic_setup_module.py +338 -0
  8. digitalkin-0.3.2.dev8/examples/monitoring/digitalkin_observability/__init__.py +46 -0
  9. digitalkin-0.3.2.dev8/examples/monitoring/digitalkin_observability/http_server.py +150 -0
  10. digitalkin-0.3.2.dev8/examples/monitoring/digitalkin_observability/interceptors.py +176 -0
  11. digitalkin-0.3.2.dev8/examples/monitoring/digitalkin_observability/metrics.py +201 -0
  12. digitalkin-0.3.2.dev8/examples/monitoring/digitalkin_observability/prometheus.py +137 -0
  13. digitalkin-0.3.2.dev8/examples/monitoring/tests/test_metrics.py +172 -0
  14. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/services/filesystem_module.py +7 -5
  15. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/services/storage_module.py +4 -2
  16. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/pyproject.toml +79 -35
  17. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/__version__.py +1 -1
  18. digitalkin-0.3.2.dev8/src/digitalkin/core/__init__.py +1 -0
  19. digitalkin-0.3.2.dev8/src/digitalkin/core/common/__init__.py +9 -0
  20. digitalkin-0.3.2.dev8/src/digitalkin/core/common/factories.py +156 -0
  21. digitalkin-0.3.2.dev8/src/digitalkin/core/job_manager/__init__.py +1 -0
  22. {digitalkin-0.2.26/src/digitalkin/modules → digitalkin-0.3.2.dev8/src/digitalkin/core}/job_manager/base_job_manager.py +138 -32
  23. digitalkin-0.3.2.dev8/src/digitalkin/core/job_manager/single_job_manager.py +373 -0
  24. {digitalkin-0.2.26/src/digitalkin/modules → digitalkin-0.3.2.dev8/src/digitalkin/core}/job_manager/taskiq_broker.py +121 -26
  25. digitalkin-0.3.2.dev8/src/digitalkin/core/job_manager/taskiq_job_manager.py +541 -0
  26. digitalkin-0.3.2.dev8/src/digitalkin/core/task_manager/__init__.py +1 -0
  27. digitalkin-0.3.2.dev8/src/digitalkin/core/task_manager/base_task_manager.py +539 -0
  28. digitalkin-0.3.2.dev8/src/digitalkin/core/task_manager/local_task_manager.py +108 -0
  29. digitalkin-0.3.2.dev8/src/digitalkin/core/task_manager/remote_task_manager.py +87 -0
  30. digitalkin-0.3.2.dev8/src/digitalkin/core/task_manager/surrealdb_repository.py +266 -0
  31. digitalkin-0.3.2.dev8/src/digitalkin/core/task_manager/task_executor.py +249 -0
  32. digitalkin-0.3.2.dev8/src/digitalkin/core/task_manager/task_session.py +368 -0
  33. digitalkin-0.3.2.dev8/src/digitalkin/grpc_servers/__init__.py +1 -0
  34. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/grpc_servers/_base_server.py +2 -2
  35. digitalkin-0.3.2.dev8/src/digitalkin/grpc_servers/module_server.py +208 -0
  36. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/grpc_servers/module_servicer.py +79 -43
  37. digitalkin-0.3.2.dev8/src/digitalkin/grpc_servers/utils/__init__.py +1 -0
  38. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/grpc_servers/utils/exceptions.py +0 -8
  39. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +23 -7
  40. digitalkin-0.3.2.dev8/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +53 -0
  41. digitalkin-0.3.2.dev8/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +100 -0
  42. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/logger.py +1 -9
  43. digitalkin-0.3.2.dev8/src/digitalkin/mixins/__init__.py +19 -0
  44. digitalkin-0.3.2.dev8/src/digitalkin/mixins/base_mixin.py +10 -0
  45. digitalkin-0.3.2.dev8/src/digitalkin/mixins/callback_mixin.py +24 -0
  46. digitalkin-0.3.2.dev8/src/digitalkin/mixins/chat_history_mixin.py +110 -0
  47. digitalkin-0.3.2.dev8/src/digitalkin/mixins/cost_mixin.py +76 -0
  48. digitalkin-0.3.2.dev8/src/digitalkin/mixins/file_history_mixin.py +93 -0
  49. digitalkin-0.3.2.dev8/src/digitalkin/mixins/filesystem_mixin.py +46 -0
  50. digitalkin-0.3.2.dev8/src/digitalkin/mixins/logger_mixin.py +51 -0
  51. digitalkin-0.3.2.dev8/src/digitalkin/mixins/storage_mixin.py +79 -0
  52. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/models/__init__.py +1 -1
  53. digitalkin-0.3.2.dev8/src/digitalkin/models/core/__init__.py +1 -0
  54. {digitalkin-0.2.26/src/digitalkin/modules/job_manager → digitalkin-0.3.2.dev8/src/digitalkin/models/core}/job_manager_models.py +3 -11
  55. digitalkin-0.3.2.dev8/src/digitalkin/models/core/task_monitor.py +74 -0
  56. digitalkin-0.3.2.dev8/src/digitalkin/models/grpc_servers/__init__.py +1 -0
  57. {digitalkin-0.2.26/src/digitalkin/grpc_servers/utils → digitalkin-0.3.2.dev8/src/digitalkin/models/grpc_servers}/models.py +5 -5
  58. digitalkin-0.3.2.dev8/src/digitalkin/models/module/__init__.py +33 -0
  59. digitalkin-0.3.2.dev8/src/digitalkin/models/module/base_types.py +61 -0
  60. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/models/module/module.py +9 -1
  61. digitalkin-0.3.2.dev8/src/digitalkin/models/module/module_context.py +300 -0
  62. digitalkin-0.3.2.dev8/src/digitalkin/models/module/module_types.py +29 -0
  63. digitalkin-0.3.2.dev8/src/digitalkin/models/module/setup_types.py +484 -0
  64. digitalkin-0.3.2.dev8/src/digitalkin/models/module/tool_cache.py +68 -0
  65. digitalkin-0.3.2.dev8/src/digitalkin/models/module/tool_reference.py +117 -0
  66. digitalkin-0.3.2.dev8/src/digitalkin/models/module/utility.py +167 -0
  67. digitalkin-0.3.2.dev8/src/digitalkin/models/services/__init__.py +10 -0
  68. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/models/services/cost.py +1 -0
  69. digitalkin-0.3.2.dev8/src/digitalkin/models/services/registry.py +35 -0
  70. digitalkin-0.3.2.dev8/src/digitalkin/models/services/storage.py +44 -0
  71. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/modules/__init__.py +5 -1
  72. digitalkin-0.3.2.dev8/src/digitalkin/modules/_base_module.py +570 -0
  73. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/modules/archetype_module.py +6 -1
  74. digitalkin-0.3.2.dev8/src/digitalkin/modules/tool_module.py +23 -0
  75. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/modules/trigger_handler.py +7 -6
  76. digitalkin-0.3.2.dev8/src/digitalkin/modules/triggers/__init__.py +8 -0
  77. digitalkin-0.3.2.dev8/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +45 -0
  78. digitalkin-0.3.2.dev8/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +63 -0
  79. digitalkin-0.3.2.dev8/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +52 -0
  80. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/__init__.py +4 -0
  81. digitalkin-0.3.2.dev8/src/digitalkin/services/communication/__init__.py +7 -0
  82. digitalkin-0.3.2.dev8/src/digitalkin/services/communication/communication_strategy.py +76 -0
  83. digitalkin-0.3.2.dev8/src/digitalkin/services/communication/default_communication.py +101 -0
  84. digitalkin-0.3.2.dev8/src/digitalkin/services/communication/grpc_communication.py +234 -0
  85. digitalkin-0.3.2.dev8/src/digitalkin/services/cost/__init__.py +14 -0
  86. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/cost/grpc_cost.py +9 -42
  87. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/filesystem/default_filesystem.py +0 -2
  88. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/filesystem/grpc_filesystem.py +10 -39
  89. digitalkin-0.3.2.dev8/src/digitalkin/services/registry/__init__.py +27 -0
  90. digitalkin-0.3.2.dev8/src/digitalkin/services/registry/default_registry.py +141 -0
  91. digitalkin-0.3.2.dev8/src/digitalkin/services/registry/exceptions.py +47 -0
  92. digitalkin-0.3.2.dev8/src/digitalkin/services/registry/grpc_registry.py +306 -0
  93. digitalkin-0.3.2.dev8/src/digitalkin/services/registry/registry_models.py +15 -0
  94. digitalkin-0.3.2.dev8/src/digitalkin/services/registry/registry_strategy.py +98 -0
  95. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/services_config.py +25 -3
  96. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/services_models.py +5 -1
  97. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/setup/default_setup.py +6 -7
  98. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/setup/grpc_setup.py +52 -15
  99. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/storage/grpc_storage.py +4 -4
  100. digitalkin-0.3.2.dev8/src/digitalkin/services/user_profile/__init__.py +12 -0
  101. digitalkin-0.3.2.dev8/src/digitalkin/services/user_profile/default_user_profile.py +55 -0
  102. digitalkin-0.3.2.dev8/src/digitalkin/services/user_profile/grpc_user_profile.py +69 -0
  103. digitalkin-0.3.2.dev8/src/digitalkin/services/user_profile/user_profile_strategy.py +25 -0
  104. digitalkin-0.3.2.dev8/src/digitalkin/utils/__init__.py +29 -0
  105. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/utils/arg_parser.py +1 -1
  106. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/utils/development_mode_action.py +2 -2
  107. digitalkin-0.3.2.dev8/src/digitalkin/utils/dynamic_schema.py +483 -0
  108. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/utils/package_discover.py +1 -2
  109. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin.egg-info/PKG-INFO +11 -30
  110. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin.egg-info/SOURCES.txt +63 -10
  111. digitalkin-0.3.2.dev8/src/digitalkin.egg-info/requires.txt +12 -0
  112. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin.egg-info/top_level.txt +1 -0
  113. digitalkin-0.2.26/src/digitalkin/grpc_servers/__init__.py +0 -19
  114. digitalkin-0.2.26/src/digitalkin/grpc_servers/module_server.py +0 -284
  115. digitalkin-0.2.26/src/digitalkin/grpc_servers/registry_server.py +0 -65
  116. digitalkin-0.2.26/src/digitalkin/grpc_servers/registry_servicer.py +0 -456
  117. digitalkin-0.2.26/src/digitalkin/grpc_servers/utils/factory.py +0 -180
  118. digitalkin-0.2.26/src/digitalkin/models/module/__init__.py +0 -26
  119. digitalkin-0.2.26/src/digitalkin/models/module/module_context.py +0 -24
  120. digitalkin-0.2.26/src/digitalkin/models/module/module_types.py +0 -105
  121. digitalkin-0.2.26/src/digitalkin/models/services/__init__.py +0 -1
  122. digitalkin-0.2.26/src/digitalkin/models/services/storage.py +0 -10
  123. digitalkin-0.2.26/src/digitalkin/modules/_base_module.py +0 -529
  124. digitalkin-0.2.26/src/digitalkin/modules/job_manager/single_job_manager.py +0 -294
  125. digitalkin-0.2.26/src/digitalkin/modules/job_manager/taskiq_job_manager.py +0 -290
  126. digitalkin-0.2.26/src/digitalkin/modules/tool_module.py +0 -10
  127. digitalkin-0.2.26/src/digitalkin/services/cost/__init__.py +0 -7
  128. digitalkin-0.2.26/src/digitalkin/services/registry/__init__.py +0 -6
  129. digitalkin-0.2.26/src/digitalkin/services/registry/default_registry.py +0 -10
  130. digitalkin-0.2.26/src/digitalkin/services/registry/registry_strategy.py +0 -14
  131. digitalkin-0.2.26/src/digitalkin/utils/__init__.py +0 -1
  132. digitalkin-0.2.26/src/digitalkin.egg-info/requires.txt +0 -34
  133. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/LICENSE +0 -0
  134. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/README.md +0 -0
  135. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/base_server/__init__.py +0 -0
  136. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/base_server/mock/__init__.py +0 -0
  137. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/base_server/mock/mock_pb2.py +0 -0
  138. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
  139. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/modules/__init__.py +0 -0
  140. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/modules/cpu_intensive_module.py +1 -1
  141. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/modules/minimal_llm_module.py +1 -1
  142. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/examples/modules/text_transform_module.py +1 -1
  143. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/setup.cfg +0 -0
  144. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/__init__.py +0 -0
  145. {digitalkin-0.2.26/src/digitalkin/grpc_servers/utils → digitalkin-0.3.2.dev8/src/digitalkin/models/grpc_servers}/types.py +0 -0
  146. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/py.typed +0 -0
  147. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/agent/__init__.py +0 -0
  148. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/agent/agent_strategy.py +0 -0
  149. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/agent/default_agent.py +0 -0
  150. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/base_strategy.py +0 -0
  151. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/cost/cost_strategy.py +0 -0
  152. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/cost/default_cost.py +0 -0
  153. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/filesystem/__init__.py +0 -0
  154. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/filesystem/filesystem_strategy.py +0 -0
  155. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/identity/__init__.py +0 -0
  156. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/identity/default_identity.py +0 -0
  157. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/identity/identity_strategy.py +0 -0
  158. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/setup/__init__.py +0 -0
  159. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/setup/setup_strategy.py +0 -0
  160. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/snapshot/__init__.py +0 -0
  161. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/snapshot/default_snapshot.py +0 -0
  162. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/snapshot/snapshot_strategy.py +0 -0
  163. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/storage/__init__.py +0 -0
  164. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/storage/default_storage.py +0 -0
  165. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/services/storage/storage_strategy.py +0 -0
  166. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin/utils/llm_ready_schema.py +0 -0
  167. {digitalkin-0.2.26 → digitalkin-0.3.2.dev8}/src/digitalkin.egg-info/dependency_links.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalkin
3
- Version: 0.2.26
3
+ Version: 0.3.2.dev8
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
@@ -452,36 +452,17 @@ Classifier: License :: Other/Proprietary License
452
452
  Requires-Python: >=3.10
453
453
  Description-Content-Type: text/markdown
454
454
  License-File: LICENSE
455
- Requires-Dist: digitalkin-proto>=0.1.16
456
- Requires-Dist: grpcio-health-checking>=1.71.0
457
- Requires-Dist: grpcio-reflection>=1.71.0
458
- Requires-Dist: grpcio-status>=1.71.0
459
- Requires-Dist: pydantic>=2.11.5
460
- Provides-Extra: dev
461
- Requires-Dist: typos>=1.34.0; extra == "dev"
462
- Requires-Dist: ruff>=0.12.5; extra == "dev"
463
- Requires-Dist: mypy>=1.17.0; extra == "dev"
464
- Requires-Dist: pyright>=1.1.403; extra == "dev"
465
- Requires-Dist: pre-commit>=4.3.0; extra == "dev"
466
- Requires-Dist: bump2version>=1.0.1; extra == "dev"
467
- Requires-Dist: build>=1.3.0; extra == "dev"
468
- Requires-Dist: twine>=6.1.0; extra == "dev"
469
- Requires-Dist: cryptography>=45.0.5; extra == "dev"
470
- Provides-Extra: examples
471
- Requires-Dist: openai>=1.75.0; extra == "examples"
472
- Provides-Extra: tests
473
- Requires-Dist: freezegun>=1.5.3; extra == "tests"
474
- Requires-Dist: hdrhistogram>=0.10.3; extra == "tests"
475
- Requires-Dist: grpcio-testing>=1.71.0; extra == "tests"
476
- Requires-Dist: psutil>=7.0.0; extra == "tests"
477
- Requires-Dist: pytest>=8.4.0; extra == "tests"
478
- Requires-Dist: pytest-asyncio>=1.1.0; extra == "tests"
479
- Requires-Dist: pytest-cov>=6.1.0; extra == "tests"
455
+ Requires-Dist: agentic-mesh-protocol==0.2.1.dev0
456
+ Requires-Dist: grpcio-health-checking>=1.76.0
457
+ Requires-Dist: grpcio-reflection>=1.76.0
458
+ Requires-Dist: grpcio-status>=1.76.0
459
+ Requires-Dist: pydantic>=2.12.5
460
+ Requires-Dist: surrealdb>=1.0.7
480
461
  Provides-Extra: taskiq
481
- Requires-Dist: rstream>=0.30.0; extra == "taskiq"
482
- Requires-Dist: taskiq-aio-pika>=0.4.3; extra == "taskiq"
483
- Requires-Dist: taskiq-redis>=1.1.0; extra == "taskiq"
484
- Requires-Dist: taskiq[reload]>=0.11.18; extra == "taskiq"
462
+ Requires-Dist: rstream>=0.40.0; extra == "taskiq"
463
+ Requires-Dist: taskiq-aio-pika>=0.5.0; extra == "taskiq"
464
+ Requires-Dist: taskiq-redis>=1.2.0; extra == "taskiq"
465
+ Requires-Dist: taskiq[reload]>=0.12.1; extra == "taskiq"
485
466
  Dynamic: license-file
486
467
 
487
468
  # DigitalKin Python SDK
@@ -9,8 +9,9 @@ from pathlib import Path
9
9
  # Add parent directory to path to enable imports
10
10
  sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
11
11
 
12
- from digitalkin.grpc_servers._base_server import BaseServer
13
12
  from digitalkin.grpc_servers.utils.models import SecurityMode, ServerConfig, ServerMode
13
+
14
+ from digitalkin.grpc_servers._base_server import BaseServer
14
15
  from examples.base_server.mock.mock_pb2 import DESCRIPTOR, HelloReply # type: ignore
15
16
  from examples.base_server.mock.mock_pb2_grpc import (
16
17
  Greeter,
@@ -30,7 +31,7 @@ class AsyncGreeterImpl(Greeter):
30
31
 
31
32
  async def SayHello(self, request, context): # noqa: N802
32
33
  """Asynchronous implementation of SayHello method."""
33
- logger.info(f"Received request object: {request}")
34
+ logger.info("Received request object: %s", request)
34
35
  logger.info(f"Request attributes: {vars(request)}")
35
36
  logger.info(f"Received request with name: {request.name}")
36
37
 
@@ -40,7 +41,7 @@ class AsyncGreeterImpl(Greeter):
40
41
  name = "unknown"
41
42
  # Check context metadata
42
43
  for key, value in context.invocation_metadata():
43
- logger.info(f"Metadata: {key}={value}")
44
+ logger.info("Metadata: %s=%s", key, value)
44
45
  if key.lower() == "name":
45
46
  name = value
46
47
 
@@ -97,7 +98,7 @@ async def main_async() -> int:
97
98
  # as the KeyboardInterrupt usually breaks out of asyncio.run()
98
99
  logger.info("Server stopping due to keyboard interrupt...")
99
100
  except Exception as e:
100
- logger.exception(f"Error running server: {e}")
101
+ logger.exception("Error running server: %s", e)
101
102
  return 1
102
103
  finally:
103
104
  # Clean up resources if server was started
@@ -116,7 +117,7 @@ def main():
116
117
  logger.info("Server stopped by keyboard interrupt")
117
118
  return 0 # Clean exit
118
119
  except Exception as e:
119
- logger.exception(f"Fatal error: {e}")
120
+ logger.exception("Fatal error: %s", e)
120
121
  return 1
121
122
 
122
123
 
@@ -9,13 +9,14 @@ from pathlib import Path
9
9
  # Add parent directory to path to enable imports
10
10
  sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
11
11
 
12
- from digitalkin.grpc_servers._base_server import BaseServer
13
12
  from digitalkin.grpc_servers.utils.models import (
14
13
  SecurityMode,
15
14
  ServerConfig,
16
15
  ServerCredentials,
17
16
  ServerMode,
18
17
  )
18
+
19
+ from digitalkin.grpc_servers._base_server import BaseServer
19
20
  from examples.base_server.mock.mock_pb2 import DESCRIPTOR, HelloReply # type: ignore
20
21
  from examples.base_server.mock.mock_pb2_grpc import (
21
22
  Greeter,
@@ -35,7 +36,7 @@ class AsyncGreeterImpl(Greeter):
35
36
 
36
37
  async def SayHello(self, request, context): # noqa: N802
37
38
  """Asynchronous implementation of SayHello method."""
38
- logger.info(f"Received request object: {request}")
39
+ logger.info("Received request object: %s", request)
39
40
  logger.info(f"Request attributes: {vars(request)}")
40
41
  logger.info(f"Received request with name: {request.name}")
41
42
 
@@ -45,7 +46,7 @@ class AsyncGreeterImpl(Greeter):
45
46
  name = "unknown"
46
47
  # Check context metadata
47
48
  for key, value in context.invocation_metadata():
48
- logger.info(f"Metadata: {key}={value}")
49
+ logger.info("Metadata: %s=%s", key, value)
49
50
  if key.lower() == "name":
50
51
  name = value
51
52
 
@@ -115,7 +116,7 @@ async def main_async() -> int:
115
116
  # as the KeyboardInterrupt usually breaks out of asyncio.run()
116
117
  logger.info("Server stopping due to keyboard interrupt...")
117
118
  except Exception as e:
118
- logger.exception(f"Error running server: {e}")
119
+ logger.exception("Error running server: %s", e)
119
120
  return 1
120
121
  finally:
121
122
  # Clean up resources if server was started
@@ -134,7 +135,7 @@ def main():
134
135
  logger.info("Server stopped by keyboard interrupt")
135
136
  return 0 # Clean exit
136
137
  except Exception as e:
137
- logger.exception(f"Fatal error: {e}")
138
+ logger.exception("Fatal error: %s", e)
138
139
  return 1
139
140
 
140
141
 
@@ -8,8 +8,9 @@ from pathlib import Path
8
8
  # Add parent directory to path to enable imports
9
9
  sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
10
10
 
11
- from digitalkin.grpc_servers._base_server import BaseServer
12
11
  from digitalkin.grpc_servers.utils.models import SecurityMode, ServerConfig, ServerMode
12
+
13
+ from digitalkin.grpc_servers._base_server import BaseServer
13
14
  from examples.base_server.mock.mock_pb2 import DESCRIPTOR, HelloReply # type: ignore
14
15
  from examples.base_server.mock.mock_pb2_grpc import (
15
16
  Greeter,
@@ -29,7 +30,7 @@ class SyncGreeterServicer(Greeter):
29
30
 
30
31
  def SayHello(self, request, context): # noqa: N802
31
32
  """Implementation of SayHello method."""
32
- logger.info(f"Received request object: {request}")
33
+ logger.info("Received request object: %s", request)
33
34
  logger.info(f"Request attributes: {vars(request)}")
34
35
  logger.info(f"Received request with name: {request.name}")
35
36
 
@@ -39,7 +40,7 @@ class SyncGreeterServicer(Greeter):
39
40
  name = "unknown"
40
41
  # Check context metadata
41
42
  for key, value in context.invocation_metadata():
42
- logger.info(f"Metadata: {key}={value}")
43
+ logger.info("Metadata: %s=%s", key, value)
43
44
  if key.lower() == "name":
44
45
  name = value
45
46
 
@@ -92,7 +93,7 @@ def main() -> int:
92
93
  server.stop()
93
94
 
94
95
  except Exception as e:
95
- logger.exception(f"Error running server: {e}")
96
+ logger.exception("Error running server: %s", e)
96
97
  return 1
97
98
 
98
99
  return 0
@@ -8,13 +8,14 @@ from pathlib import Path
8
8
  # Add parent directory to path to enable imports
9
9
  sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
10
10
 
11
- from digitalkin.grpc_servers._base_server import BaseServer
12
11
  from digitalkin.grpc_servers.utils.models import (
13
12
  SecurityMode,
14
13
  ServerConfig,
15
14
  ServerCredentials,
16
15
  ServerMode,
17
16
  )
17
+
18
+ from digitalkin.grpc_servers._base_server import BaseServer
18
19
  from examples.base_server.mock.mock_pb2 import DESCRIPTOR, HelloReply # type: ignore
19
20
  from examples.base_server.mock.mock_pb2_grpc import (
20
21
  Greeter,
@@ -34,7 +35,7 @@ class SyncGreeterServicer(Greeter):
34
35
 
35
36
  def SayHello(self, request, context): # noqa: N802
36
37
  """Implementation of SayHello method."""
37
- logger.info(f"Received request object: {request}")
38
+ logger.info("Received request object: %s", request)
38
39
  logger.info(f"Request attributes: {vars(request)}")
39
40
  logger.info(f"Received request with name: {request.name}")
40
41
 
@@ -44,7 +45,7 @@ class SyncGreeterServicer(Greeter):
44
45
  name = "unknown"
45
46
  # Check context metadata
46
47
  for key, value in context.invocation_metadata():
47
- logger.info(f"Metadata: {key}={value}")
48
+ logger.info("Metadata: %s=%s", key, value)
48
49
  if key.lower() == "name":
49
50
  name = value
50
51
 
@@ -111,7 +112,7 @@ def main() -> int:
111
112
  server.stop()
112
113
 
113
114
  except Exception as e:
114
- logger.exception(f"Error running server: {e}")
115
+ logger.exception("Error running server: %s", e)
115
116
  return 1
116
117
 
117
118
  return 0
@@ -0,0 +1,244 @@
1
+ """Example archetype module with tool cache integration."""
2
+
3
+ import logging
4
+ from typing import Any, ClassVar, Literal
5
+
6
+ from pydantic import BaseModel, Field
7
+
8
+ from digitalkin.models.grpc_servers.models import ClientConfig, SecurityMode, ServerMode
9
+ from digitalkin.models.module.module_context import ModuleContext
10
+ from digitalkin.models.module.setup_types import SetupModel
11
+ from digitalkin.models.module.tool_reference import (
12
+ ToolReference,
13
+ ToolReferenceConfig,
14
+ ToolSelectionMode,
15
+ )
16
+ from digitalkin.modules._base_module import BaseModule # noqa: PLC2701
17
+ from digitalkin.services.services_models import ServicesStrategy
18
+
19
+ logging.basicConfig(
20
+ level=logging.DEBUG,
21
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
22
+ )
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ class MessageInputPayload(BaseModel):
27
+ """Message input payload."""
28
+
29
+ payload_type: Literal["message"] = "message"
30
+ user_prompt: str
31
+
32
+
33
+ class ArchetypeInput(BaseModel):
34
+ """Archetype input."""
35
+
36
+ payload: MessageInputPayload = Field(discriminator="payload_type")
37
+
38
+
39
+ class MessageOutputPayload(BaseModel):
40
+ """Message output payload."""
41
+
42
+ payload_type: Literal["message"] = "message"
43
+ response: str
44
+ tools_used: list[str] = Field(default_factory=list)
45
+
46
+
47
+ class ArchetypeOutput(BaseModel):
48
+ """Archetype output."""
49
+
50
+ payload: MessageOutputPayload = Field(discriminator="payload_type")
51
+
52
+
53
+ class ArchetypeSetup(SetupModel):
54
+ """Setup with tool references resolved during config setup."""
55
+
56
+ model_name: str = Field(
57
+ default="gpt-4",
58
+ json_schema_extra={"config": True},
59
+ )
60
+ temperature: float = Field(
61
+ default=0.7,
62
+ json_schema_extra={"config": True},
63
+ )
64
+
65
+ search_tool: ToolReference = Field(
66
+ default_factory=lambda: ToolReference(
67
+ config=ToolReferenceConfig(
68
+ mode=ToolSelectionMode.FIXED,
69
+ module_id="search-tool-v1",
70
+ )
71
+ ),
72
+ json_schema_extra={"config": True},
73
+ )
74
+
75
+ calculator_tool: ToolReference = Field(
76
+ default_factory=lambda: ToolReference(
77
+ config=ToolReferenceConfig(
78
+ mode=ToolSelectionMode.TAG,
79
+ tag="math-calculator",
80
+ )
81
+ ),
82
+ json_schema_extra={"config": True},
83
+ )
84
+
85
+ dynamic_tool: ToolReference = Field(
86
+ default_factory=lambda: ToolReference(
87
+ config=ToolReferenceConfig(
88
+ mode=ToolSelectionMode.DISCOVERABLE,
89
+ )
90
+ ),
91
+ json_schema_extra={"config": True},
92
+ )
93
+
94
+ system_prompt: str = Field(
95
+ default="You are a helpful assistant with access to tools.",
96
+ json_schema_extra={"hidden": True},
97
+ )
98
+
99
+
100
+ class ArchetypeConfigSetup(BaseModel):
101
+ """Config setup model."""
102
+
103
+ additional_instructions: str | None = None
104
+
105
+
106
+ class ArchetypeSecret(BaseModel):
107
+ """Secrets model."""
108
+
109
+
110
+ client_config = ClientConfig(
111
+ host="[::]",
112
+ port=50152,
113
+ mode=ServerMode.ASYNC,
114
+ security=SecurityMode.INSECURE,
115
+ credentials=None,
116
+ )
117
+
118
+
119
+ class ArchetypeWithToolsModule(
120
+ BaseModule[
121
+ ArchetypeInput,
122
+ ArchetypeOutput,
123
+ ArchetypeSetup,
124
+ ArchetypeSecret,
125
+ ]
126
+ ):
127
+ """Archetype module demonstrating tool cache usage."""
128
+
129
+ name = "ArchetypeWithToolsModule"
130
+ description = "Archetype with tool cache integration"
131
+
132
+ config_setup_format = ArchetypeConfigSetup
133
+ input_format = ArchetypeInput
134
+ output_format = ArchetypeOutput
135
+ setup_format = ArchetypeSetup
136
+ secret_format = ArchetypeSecret
137
+
138
+ metadata: ClassVar[dict[str, Any]] = {
139
+ "name": "ArchetypeWithToolsModule",
140
+ "version": "1.0.0",
141
+ "tags": ["archetype", "tools"],
142
+ }
143
+
144
+ services_config_strategies: ClassVar[dict[str, ServicesStrategy | None]] = {}
145
+ services_config_params: ClassVar[dict[str, dict[str, Any | None] | None]] = {
146
+ "registry": {
147
+ "config": {},
148
+ "client_config": client_config,
149
+ },
150
+ }
151
+
152
+ async def run_config_setup(
153
+ self,
154
+ context: ModuleContext, # noqa: ARG002
155
+ config_setup_data: ArchetypeSetup,
156
+ ) -> ArchetypeSetup:
157
+ """Custom config setup logic, runs in parallel with tool resolution.
158
+
159
+ Args:
160
+ context: Module context with services.
161
+ config_setup_data: Setup data being configured.
162
+
163
+ Returns:
164
+ Configured setup data.
165
+ """
166
+ logger.info("Running config setup for %s", self.name)
167
+ return config_setup_data
168
+
169
+ async def initialize(self, context: ModuleContext, setup_data: ArchetypeSetup) -> None: # noqa: ARG002
170
+ """Initialize module.
171
+
172
+ Args:
173
+ context: Module context with services and tool cache.
174
+ setup_data: Setup data for the module.
175
+ """
176
+ logger.info("Initializing %s", self.name)
177
+ if context.tool_cache:
178
+ logger.info("Available tools: %s", context.tool_cache.list_tools())
179
+
180
+ async def run(
181
+ self,
182
+ input_data: ArchetypeInput,
183
+ setup_data: ArchetypeSetup, # noqa: ARG002
184
+ ) -> None:
185
+ """Run module with tool cache lookups and call_module_by_id.
186
+
187
+ Args:
188
+ input_data: Input data to process.
189
+ setup_data: Setup configuration.
190
+ """
191
+ logger.info("Running %s", self.name)
192
+
193
+ tools_used: list[str] = []
194
+ tool_results: list[str] = []
195
+
196
+ # Get search tool from cache and call via call_module_by_id
197
+ search_info = self.context.tool_cache.get("search_tool")
198
+ if search_info:
199
+ tools_used.append(f"search:{search_info.module_id}")
200
+ async for response in self.context.call_module_by_id(
201
+ module_id=search_info.module_id,
202
+ input_data={"query": input_data.payload.user_prompt},
203
+ setup_id=self.context.session.setup_id,
204
+ mission_id=self.context.session.mission_id,
205
+ ):
206
+ tool_results.append(f"search_result: {response}")
207
+
208
+ # Get calculator tool from cache
209
+ calc_info = self.context.tool_cache.get("calculator_tool")
210
+ if calc_info:
211
+ tools_used.append(f"calculator:{calc_info.module_id}")
212
+ async for response in self.context.call_module_by_id(
213
+ module_id=calc_info.module_id,
214
+ input_data={"expression": "2 + 2"},
215
+ setup_id=self.context.session.setup_id,
216
+ mission_id=self.context.session.mission_id,
217
+ ):
218
+ tool_results.append(f"calc_result: {response}")
219
+
220
+ # Dynamic discovery via registry fallback for tools not in cache
221
+ dynamic_info = self.context.tool_cache.get(
222
+ "some_dynamic_tool",
223
+ registry=self.context.registry,
224
+ )
225
+ if dynamic_info:
226
+ tools_used.append(f"dynamic:{dynamic_info.module_id}")
227
+ async for response in self.context.call_module_by_id(
228
+ module_id=dynamic_info.module_id,
229
+ input_data={"prompt": input_data.payload.user_prompt},
230
+ setup_id=self.context.session.setup_id,
231
+ mission_id=self.context.session.mission_id,
232
+ ):
233
+ tool_results.append(f"dynamic_result: {response}")
234
+
235
+ response = MessageOutputPayload(
236
+ response=f"Processed: {input_data.payload.user_prompt} | Results: {len(tool_results)}",
237
+ tools_used=tools_used,
238
+ )
239
+
240
+ await self.context.callbacks.send_message(ArchetypeOutput(payload=response))
241
+
242
+ async def cleanup(self) -> None:
243
+ """Clean up resources."""
244
+ logger.info("Cleaning up %s", self.name)