digitalkin 0.3.2a2__tar.gz → 0.3.2.dev3__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.
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/PKG-INFO +9 -9
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/pyproject.toml +108 -108
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/__version__.py +1 -1
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/job_manager/single_job_manager.py +29 -65
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/job_manager/taskiq_job_manager.py +4 -8
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/task_manager/base_task_manager.py +1 -3
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/task_manager/surrealdb_repository.py +0 -6
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/task_manager/task_executor.py +10 -27
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/task_manager/task_session.py +1 -61
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/grpc_servers/module_server.py +43 -26
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/grpc_servers/module_servicer.py +14 -92
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +4 -14
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +4 -13
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/core/task_monitor.py +1 -19
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/grpc_servers/models.py +8 -95
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/module/__init__.py +4 -12
- digitalkin-0.3.2.dev3/src/digitalkin/models/module/module_context.py +167 -0
- digitalkin-0.3.2.dev3/src/digitalkin/models/module/setup_types.py +463 -0
- digitalkin-0.3.2.dev3/src/digitalkin/models/module/tool_reference.py +105 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/services/cost.py +1 -22
- digitalkin-0.3.2.dev3/src/digitalkin/models/services/registry.py +42 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/modules/_base_module.py +66 -118
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/communication/communication_strategy.py +3 -14
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/communication/default_communication.py +0 -3
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/communication/grpc_communication.py +17 -58
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/cost/cost_strategy.py +14 -36
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/cost/default_cost.py +1 -61
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/cost/grpc_cost.py +1 -97
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/filesystem/grpc_filesystem.py +1 -8
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/registry/__init__.py +1 -1
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/registry/default_registry.py +1 -22
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/registry/grpc_registry.py +1 -77
- digitalkin-0.3.2.dev3/src/digitalkin/services/registry/registry_models.py +43 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/registry/registry_strategy.py +1 -19
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/services_config.py +4 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/utils/__init__.py +3 -15
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/utils/dynamic_schema.py +0 -4
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin.egg-info/PKG-INFO +9 -9
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin.egg-info/SOURCES.txt +1 -11
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin.egg-info/requires.txt +2 -2
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin.egg-info/top_level.txt +0 -1
- digitalkin-0.3.2a2/examples/modules/archetype_with_tools_module.py +0 -232
- digitalkin-0.3.2a2/examples/monitoring/digitalkin_observability/__init__.py +0 -46
- digitalkin-0.3.2a2/examples/monitoring/digitalkin_observability/http_server.py +0 -150
- digitalkin-0.3.2a2/examples/monitoring/digitalkin_observability/interceptors.py +0 -176
- digitalkin-0.3.2a2/examples/monitoring/digitalkin_observability/metrics.py +0 -201
- digitalkin-0.3.2a2/examples/monitoring/digitalkin_observability/prometheus.py +0 -137
- digitalkin-0.3.2a2/examples/monitoring/tests/test_metrics.py +0 -172
- digitalkin-0.3.2a2/src/digitalkin/models/module/module_context.py +0 -406
- digitalkin-0.3.2a2/src/digitalkin/models/module/setup_types.py +0 -547
- digitalkin-0.3.2a2/src/digitalkin/models/module/tool_cache.py +0 -230
- digitalkin-0.3.2a2/src/digitalkin/models/module/tool_reference.py +0 -160
- digitalkin-0.3.2a2/src/digitalkin/models/services/registry.py +0 -77
- digitalkin-0.3.2a2/src/digitalkin/services/registry/registry_models.py +0 -15
- digitalkin-0.3.2a2/src/digitalkin/utils/conditional_schema.py +0 -260
- digitalkin-0.3.2a2/src/digitalkin/utils/schema_splitter.py +0 -290
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/LICENSE +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/README.md +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/base_server/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/base_server/mock/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/base_server/mock/mock_pb2.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/base_server/server_async_insecure.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/base_server/server_async_secure.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/base_server/server_sync_insecure.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/base_server/server_sync_secure.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/modules/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/modules/cpu_intensive_module.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/modules/dynamic_setup_module.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/modules/minimal_llm_module.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/modules/text_transform_module.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/services/filesystem_module.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/examples/services/storage_module.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/setup.cfg +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/common/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/common/factories.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/job_manager/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/job_manager/taskiq_broker.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/task_manager/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/grpc_servers/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/grpc_servers/_base_server.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/grpc_servers/utils/exceptions.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/logger.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/mixins/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/mixins/base_mixin.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/mixins/callback_mixin.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/mixins/chat_history_mixin.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/mixins/cost_mixin.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/mixins/file_history_mixin.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/mixins/logger_mixin.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/mixins/storage_mixin.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/core/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/core/job_manager_models.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/grpc_servers/types.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/module/base_types.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/module/module.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/module/module_types.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/module/utility.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/services/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/models/services/storage.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/modules/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/modules/archetype_module.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/modules/tool_module.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/modules/trigger_handler.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/modules/triggers/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/py.typed +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/agent/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/agent/agent_strategy.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/agent/default_agent.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/base_strategy.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/communication/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/cost/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/filesystem/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/filesystem/filesystem_strategy.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/identity/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/identity/default_identity.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/identity/identity_strategy.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/registry/exceptions.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/services_models.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/setup/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/setup/default_setup.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/setup/grpc_setup.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/setup/setup_strategy.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/snapshot/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/snapshot/default_snapshot.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/snapshot/snapshot_strategy.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/storage/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/storage/default_storage.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/storage/grpc_storage.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/storage/storage_strategy.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/user_profile/__init__.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/user_profile/default_user_profile.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/user_profile/grpc_user_profile.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/services/user_profile/user_profile_strategy.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/utils/arg_parser.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/utils/development_mode_action.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/utils/llm_ready_schema.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/utils/package_discover.py +0 -0
- {digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/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.3.
|
|
3
|
+
Version: 0.3.2.dev3
|
|
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
|
|
@@ -434,32 +434,32 @@ License: Attribution-NonCommercial-ShareAlike 4.0 International
|
|
|
434
434
|
Creative Commons may be contacted at creativecommons.org.
|
|
435
435
|
https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
436
436
|
|
|
437
|
-
Project-URL: Documentation, https://github.com/DigitalKin-ai/digitalkin
|
|
438
437
|
Project-URL: Homepage, https://github.com/DigitalKin-ai/digitalkin
|
|
438
|
+
Project-URL: Documentation, https://github.com/DigitalKin-ai/digitalkin
|
|
439
439
|
Project-URL: Issues, https://github.com/DigitalKin-ai/digitalkin/issues
|
|
440
|
-
Keywords: agent,
|
|
440
|
+
Keywords: digitalkin,kin,agent,gprc,sdk
|
|
441
441
|
Classifier: Development Status :: 3 - Alpha
|
|
442
442
|
Classifier: Intended Audience :: Developers
|
|
443
|
-
Classifier: License :: Other/Proprietary License
|
|
444
443
|
Classifier: Operating System :: OS Independent
|
|
445
|
-
Classifier:
|
|
444
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
445
|
+
Classifier: Programming Language :: Python
|
|
446
446
|
Classifier: Programming Language :: Python :: 3.10
|
|
447
447
|
Classifier: Programming Language :: Python :: 3.11
|
|
448
448
|
Classifier: Programming Language :: Python :: 3.12
|
|
449
449
|
Classifier: Programming Language :: Python :: 3.13
|
|
450
|
-
Classifier: Programming Language :: Python
|
|
451
|
-
Classifier:
|
|
450
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
451
|
+
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: agentic-mesh-protocol==0.2.1.
|
|
455
|
+
Requires-Dist: agentic-mesh-protocol==0.2.1.dev0
|
|
456
456
|
Requires-Dist: grpcio-health-checking>=1.76.0
|
|
457
457
|
Requires-Dist: grpcio-reflection>=1.76.0
|
|
458
458
|
Requires-Dist: grpcio-status>=1.76.0
|
|
459
459
|
Requires-Dist: pydantic>=2.12.5
|
|
460
460
|
Requires-Dist: surrealdb>=1.0.7
|
|
461
461
|
Provides-Extra: taskiq
|
|
462
|
-
Requires-Dist: rstream>=0.40.
|
|
462
|
+
Requires-Dist: rstream>=0.40.0; extra == "taskiq"
|
|
463
463
|
Requires-Dist: taskiq-aio-pika>=0.5.0; extra == "taskiq"
|
|
464
464
|
Requires-Dist: taskiq-redis>=1.2.0; extra == "taskiq"
|
|
465
465
|
Requires-Dist: taskiq[reload]>=0.12.1; extra == "taskiq"
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
build-backend = "setuptools.build_meta"
|
|
3
2
|
requires = [ "setuptools >= 75.8.2", "wheel" ]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
|
|
7
|
-
description = "SDK to build kin used in DigitalKin"
|
|
8
|
-
license = { file = "LICENSE" }
|
|
9
7
|
name = "digitalkin"
|
|
8
|
+
description = "SDK to build kin used in DigitalKin"
|
|
10
9
|
readme = "README.md"
|
|
11
10
|
requires-python = ">=3.10"
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
12
|
|
|
13
|
-
keywords = [ "
|
|
13
|
+
keywords = [ "digitalkin", "kin", "agent", "gprc", "sdk" ]
|
|
14
14
|
|
|
15
|
+
version = "0.3.2.dev3"
|
|
15
16
|
classifiers = [
|
|
16
17
|
"Development Status :: 3 - Alpha",
|
|
17
18
|
"Intended Audience :: Developers",
|
|
18
|
-
"License :: Other/Proprietary License",
|
|
19
19
|
"Operating System :: OS Independent",
|
|
20
|
-
"
|
|
20
|
+
"Topic :: Software Development :: Libraries",
|
|
21
|
+
"Programming Language :: Python",
|
|
21
22
|
"Programming Language :: Python :: 3.10",
|
|
22
23
|
"Programming Language :: Python :: 3.11",
|
|
23
24
|
"Programming Language :: Python :: 3.12",
|
|
24
25
|
"Programming Language :: Python :: 3.13",
|
|
25
|
-
"Programming Language :: Python",
|
|
26
|
-
"
|
|
26
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
27
|
+
"License :: Other/Proprietary License",
|
|
27
28
|
]
|
|
28
|
-
version = "0.3.2.a2"
|
|
29
29
|
|
|
30
30
|
dependencies = [
|
|
31
|
-
"agentic-mesh-protocol==0.2.1.
|
|
31
|
+
"agentic-mesh-protocol==0.2.1.dev0",
|
|
32
32
|
"grpcio-health-checking>=1.76.0",
|
|
33
33
|
"grpcio-reflection>=1.76.0",
|
|
34
34
|
"grpcio-status>=1.76.0",
|
|
@@ -38,81 +38,81 @@
|
|
|
38
38
|
|
|
39
39
|
[project.optional-dependencies]
|
|
40
40
|
taskiq = [
|
|
41
|
-
"rstream>=0.40.
|
|
41
|
+
"rstream>=0.40.0",
|
|
42
42
|
"taskiq-aio-pika>=0.5.0",
|
|
43
43
|
"taskiq-redis>=1.2.0",
|
|
44
44
|
"taskiq[reload]>=0.12.1",
|
|
45
45
|
]
|
|
46
46
|
|
|
47
47
|
[project.urls]
|
|
48
|
-
Documentation = "https://github.com/DigitalKin-ai/digitalkin"
|
|
49
48
|
Homepage = "https://github.com/DigitalKin-ai/digitalkin"
|
|
49
|
+
Documentation = "https://github.com/DigitalKin-ai/digitalkin"
|
|
50
50
|
Issues = "https://github.com/DigitalKin-ai/digitalkin/issues"
|
|
51
51
|
|
|
52
52
|
[[project.authors]]
|
|
53
|
-
email = "contact@digitalkin.ai"
|
|
54
53
|
name = "DigitalKin.ai"
|
|
54
|
+
email = "contact@digitalkin.ai"
|
|
55
55
|
|
|
56
56
|
[dependency-groups]
|
|
57
|
+
dev = [
|
|
58
|
+
"typos>=1.40.0",
|
|
59
|
+
"ruff>=0.14.9",
|
|
60
|
+
"mypy>=1.19.1",
|
|
61
|
+
"pyright>=1.1.407",
|
|
62
|
+
"pre-commit>=4.5.0",
|
|
63
|
+
"bump-my-version>=1.2.5",
|
|
64
|
+
"build>=1.3.0",
|
|
65
|
+
"twine>=6.2.0",
|
|
66
|
+
"cryptography>=46.0.3",
|
|
67
|
+
]
|
|
57
68
|
tests = [
|
|
58
69
|
"freezegun>=1.5.5",
|
|
59
|
-
"grpcio-testing>=1.76.0",
|
|
60
70
|
"hdrhistogram>=0.10.3",
|
|
71
|
+
"grpcio-testing>=1.76.0",
|
|
61
72
|
"psutil>=7.1.3",
|
|
73
|
+
"pytest>=9.0.2",
|
|
62
74
|
"pytest-asyncio>=1.3.0",
|
|
63
75
|
"pytest-cov>=7.0.0",
|
|
64
|
-
"pytest-html==4.
|
|
76
|
+
"pytest-html==4.1.1",
|
|
65
77
|
"pytest-json-report==1.5.0",
|
|
66
78
|
"pytest-timeout>=2.4.0",
|
|
67
|
-
"pytest>=9.0.2",
|
|
68
|
-
]
|
|
69
|
-
dev = [
|
|
70
|
-
"build>=1.3.0",
|
|
71
|
-
"bump-my-version>=1.2.5",
|
|
72
|
-
"cryptography>=46.0.4",
|
|
73
|
-
"mypy>=1.19.1",
|
|
74
|
-
"pre-commit>=4.5.1",
|
|
75
|
-
"pyright>=1.1.407",
|
|
76
|
-
"ruff>=0.14.14",
|
|
77
|
-
"twine>=6.2.0",
|
|
78
|
-
"typos>=1.42.3",
|
|
79
79
|
]
|
|
80
80
|
docs = [
|
|
81
|
-
"
|
|
81
|
+
"mike>=2.1.3",
|
|
82
82
|
"markdown-callouts>=0.4.0",
|
|
83
83
|
"markdown-exec>=1.12.1",
|
|
84
|
-
"
|
|
84
|
+
"mkdocs>=1.6.1",
|
|
85
|
+
"mkdocs-coverage>=2.0.0",
|
|
86
|
+
"mkdocs-llmstxt>=0.5.0",
|
|
87
|
+
"mkdocs-redirects>=1.2.2",
|
|
88
|
+
"mkdocstrings>=1.0.0",
|
|
89
|
+
"griffe-inherited-docstrings>=1.1.2",
|
|
85
90
|
"mkdocs-autorefs>=1.4.3",
|
|
86
91
|
"mkdocs-awesome-pages-plugin>=2.10.1",
|
|
87
|
-
"mkdocs-coverage>=2.0.0",
|
|
88
92
|
"mkdocs-git-committers-plugin-2>=2.5.0",
|
|
89
|
-
"mkdocs-git-revision-date-localized-plugin>=1.5.
|
|
93
|
+
"mkdocs-git-revision-date-localized-plugin>=1.5.0",
|
|
90
94
|
"mkdocs-glightbox>=0.5.2",
|
|
91
|
-
"mkdocs-include-markdown-plugin>=7.2.
|
|
95
|
+
"mkdocs-include-markdown-plugin>=7.2.0",
|
|
92
96
|
"mkdocs-literate-nav>=0.6.2",
|
|
93
|
-
"mkdocs-llmstxt>=0.5.0",
|
|
94
97
|
"mkdocs-material[imaging]>=9.7.0",
|
|
95
98
|
"mkdocs-minify-plugin>=0.8.0",
|
|
96
|
-
"mkdocs-open-in-new-tab>=1.0.8",
|
|
97
|
-
"mkdocs-redirects>=1.2.2",
|
|
98
99
|
"mkdocs-section-index>=0.3.10",
|
|
99
|
-
"mkdocs>=1.6.1",
|
|
100
100
|
"mkdocstrings-python>=2.0.1",
|
|
101
|
-
"
|
|
101
|
+
"mkdocs-open-in-new-tab>=1.0.8",
|
|
102
102
|
"tomli>=2.3.0",
|
|
103
103
|
]
|
|
104
104
|
[tool.setuptools]
|
|
105
105
|
package-dir = { "" = "src" }
|
|
106
106
|
|
|
107
107
|
[tool.setuptools.packages.find]
|
|
108
|
-
where = [ "
|
|
109
|
-
[tool.ruff]
|
|
108
|
+
where = [ "src", "examples" ]
|
|
110
109
|
|
|
111
|
-
|
|
112
|
-
line-length = 120
|
|
113
|
-
show-fixes = true
|
|
110
|
+
[tool.ruff]
|
|
114
111
|
src = [ "src" ]
|
|
115
112
|
target-version = "py310"
|
|
113
|
+
line-length = 120
|
|
114
|
+
indent-width = 4
|
|
115
|
+
show-fixes = true
|
|
116
116
|
unsafe-fixes = true
|
|
117
117
|
# Enable preview features.
|
|
118
118
|
exclude = [
|
|
@@ -135,59 +135,59 @@
|
|
|
135
135
|
"buck-out",
|
|
136
136
|
"build",
|
|
137
137
|
"dist",
|
|
138
|
-
"
|
|
139
|
-
"
|
|
138
|
+
"node_modules",
|
|
139
|
+
"venv",
|
|
140
140
|
"factory.py",
|
|
141
141
|
"generate_certificates.py",
|
|
142
|
-
"
|
|
142
|
+
"examples/*",
|
|
143
143
|
"tests/*",
|
|
144
|
-
"
|
|
144
|
+
"docs/*",
|
|
145
145
|
]
|
|
146
146
|
preview = true
|
|
147
147
|
|
|
148
148
|
[tool.ruff.lint]
|
|
149
149
|
select = [
|
|
150
|
-
"A", # flake8-builtins
|
|
151
150
|
"ANN", # flake8-annotations
|
|
152
|
-
"ARG", # flake8-unused-arguments
|
|
153
151
|
"ASYNC", # flake8-async
|
|
154
|
-
"
|
|
155
|
-
"
|
|
152
|
+
"S", # flake8-bandit
|
|
153
|
+
"FBT", # flake8-boolean-trap
|
|
154
|
+
"A", # flake8-builtins
|
|
156
155
|
"COM", # flake8-commas
|
|
157
|
-
"
|
|
158
|
-
"DOC", # pydoclint
|
|
156
|
+
"C4", # flake8-comprehensions
|
|
159
157
|
"DTZ", # flake8-datetimez
|
|
160
|
-
"E", # pycodestyle-errors
|
|
161
158
|
"EM", # flake8-errmsg
|
|
162
|
-
"ERA", # eradicate
|
|
163
|
-
"F", # pyflakes
|
|
164
|
-
"FBT", # flake8-boolean-trap
|
|
165
|
-
"FLY", # flynt
|
|
166
|
-
"FURB", # Refurb
|
|
167
|
-
"G", # flake8-logging-format
|
|
168
|
-
"I", # isort
|
|
169
|
-
"ICN", # flake8-import-conventions
|
|
170
159
|
"ISC", # flake8-implicit-str-concat
|
|
160
|
+
"ICN", # flake8-import-conventions
|
|
161
|
+
"G", # flake8-logging-format
|
|
171
162
|
"LOG", # flake8-logging
|
|
172
|
-
"N", # pep8-naming
|
|
173
|
-
"PERF", # Perflint
|
|
174
163
|
"PIE", # flake8-pie
|
|
175
|
-
"
|
|
176
|
-
"PL", # Pylint
|
|
177
|
-
"PT", # flake8-pytest-style
|
|
164
|
+
"T20", # flake8-print
|
|
178
165
|
"PYI", # flake8-pyi
|
|
166
|
+
"PT", # flake8-pytest-style
|
|
179
167
|
"Q", # flake8-quotes
|
|
180
|
-
"RET", # flake8-return
|
|
181
168
|
"RSE", # flake8-raise
|
|
182
|
-
"
|
|
183
|
-
"S", # flake8-bandit
|
|
184
|
-
"SIM", # flake8-simplify
|
|
169
|
+
"RET", # flake8-return
|
|
185
170
|
"SLF", # flake8-self
|
|
186
|
-
"
|
|
171
|
+
"SIM", # flake8-simplify
|
|
187
172
|
"TC", # flake8-type-checking
|
|
173
|
+
"ARG", # flake8-unused-arguments
|
|
174
|
+
"FLY", # flynt
|
|
175
|
+
"C90", # mccabe (complex-structure)
|
|
176
|
+
"PL", # Pylint
|
|
188
177
|
"TRY", # tryceratops
|
|
189
|
-
"
|
|
178
|
+
"PERF", # Perflint
|
|
179
|
+
"E", # pycodestyle-errors
|
|
190
180
|
"W", # pycodestyle-warnings
|
|
181
|
+
"F", # pyflakes
|
|
182
|
+
"I", # isort
|
|
183
|
+
"D", # pydocstyle
|
|
184
|
+
"UP", # pyupgrade
|
|
185
|
+
"N", # pep8-naming
|
|
186
|
+
"ERA", # eradicate
|
|
187
|
+
"RUF", # Ruff-specific rules
|
|
188
|
+
"DOC", # pydoclint
|
|
189
|
+
"FURB", # Refurb
|
|
190
|
+
"PL", # Pylint
|
|
191
191
|
]
|
|
192
192
|
|
|
193
193
|
ignore = [
|
|
@@ -203,66 +203,66 @@
|
|
|
203
203
|
|
|
204
204
|
[tool.ruff.lint.per-file-ignores]
|
|
205
205
|
"tests/**/*.py" = [
|
|
206
|
+
"S101",
|
|
207
|
+
"SLF001",
|
|
208
|
+
"PLC2701",
|
|
209
|
+
"PLR6301",
|
|
210
|
+
"TRY002",
|
|
211
|
+
"FBT001",
|
|
212
|
+
"FBT002",
|
|
206
213
|
"ANN001",
|
|
207
|
-
"ANN002",
|
|
208
214
|
"ANN003",
|
|
209
|
-
"
|
|
210
|
-
"ANN401",
|
|
211
|
-
"ARG001",
|
|
215
|
+
"ANN002",
|
|
212
216
|
"ARG002",
|
|
213
|
-
"
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"
|
|
217
|
+
"PLR0914",
|
|
218
|
+
"PLR2004",
|
|
219
|
+
"PLR0915",
|
|
220
|
+
"PLR1702",
|
|
221
|
+
"D417",
|
|
222
|
+
"ARG001",
|
|
217
223
|
"D103",
|
|
224
|
+
"D102",
|
|
225
|
+
"D101",
|
|
218
226
|
"D107",
|
|
219
|
-
"
|
|
227
|
+
"N802",
|
|
220
228
|
"DOC201",
|
|
221
229
|
"DOC501",
|
|
222
|
-
"E501",
|
|
223
|
-
"ERA001",
|
|
224
|
-
"FBT001",
|
|
225
|
-
"FBT002",
|
|
226
|
-
"G004",
|
|
227
|
-
"N802",
|
|
228
230
|
"PERF203",
|
|
229
|
-
"
|
|
231
|
+
"C901",
|
|
230
232
|
"PLR0911",
|
|
233
|
+
"G004",
|
|
234
|
+
"ERA001",
|
|
235
|
+
"E501",
|
|
236
|
+
"ANN401",
|
|
231
237
|
"PLR0912",
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
"PLR1702",
|
|
235
|
-
"PLR2004",
|
|
236
|
-
"PLR6301",
|
|
237
|
-
"S101",
|
|
238
|
-
"SLF001",
|
|
239
|
-
"TRY002",
|
|
238
|
+
"ANN201",
|
|
239
|
+
"D100",
|
|
240
240
|
]
|
|
241
241
|
|
|
242
242
|
[tool.ruff.lint.pylint]
|
|
243
243
|
max-args = 10
|
|
244
244
|
|
|
245
245
|
[tool.ruff.format]
|
|
246
|
-
|
|
246
|
+
quote-style = "double"
|
|
247
247
|
indent-style = "space"
|
|
248
248
|
line-ending = "auto"
|
|
249
|
-
|
|
249
|
+
docstring-code-format = true
|
|
250
250
|
skip-magic-trailing-comma = false
|
|
251
251
|
|
|
252
252
|
[tool.pyright]
|
|
253
|
-
exclude = [ "**/.venv", "**/__pycache__" ]
|
|
254
253
|
include = [ "src" ]
|
|
254
|
+
exclude = [ "**/.venv", "**/__pycache__" ]
|
|
255
255
|
|
|
256
256
|
[tool.mypy]
|
|
257
|
+
exclude = [ "tests", "examples" ]
|
|
257
258
|
|
|
258
|
-
exclude = [ "examples", "tests" ]
|
|
259
259
|
[tool.pytest.ini_options]
|
|
260
|
-
|
|
261
|
-
asyncio_mode = "auto"
|
|
262
|
-
python_files = "test_*.py"
|
|
263
260
|
testpaths = [ "tests" ]
|
|
264
|
-
|
|
265
|
-
|
|
261
|
+
python_files = "test_*.py"
|
|
262
|
+
asyncio_mode = "auto"
|
|
263
|
+
|
|
264
|
+
log_cli = false
|
|
265
|
+
log_level = "ERROR"
|
|
266
266
|
|
|
267
267
|
# Default timeout for tests (in seconds)
|
|
268
268
|
timeout = 10
|
|
@@ -270,10 +270,10 @@
|
|
|
270
270
|
|
|
271
271
|
# Custom markers
|
|
272
272
|
markers = [
|
|
273
|
-
"edge_case: marks tests for boundary conditions and edge cases",
|
|
274
|
-
"grpc: marks tests for gRPC service functionality",
|
|
275
273
|
"integration: marks tests that require real SurrealDB connection (deselect with '-m \"not integration\"')",
|
|
276
|
-
"
|
|
274
|
+
"grpc: marks tests for gRPC service functionality",
|
|
277
275
|
"smoke: marks critical path tests that should always pass",
|
|
276
|
+
"edge_case: marks tests for boundary conditions and edge cases",
|
|
278
277
|
"validation: marks tests for input validation and schema checking",
|
|
278
|
+
"regression: marks tests for previously fixed bugs",
|
|
279
279
|
]
|
{digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/job_manager/single_job_manager.py
RENAMED
|
@@ -5,7 +5,7 @@ import datetime
|
|
|
5
5
|
import uuid
|
|
6
6
|
from collections.abc import AsyncGenerator, AsyncIterator
|
|
7
7
|
from contextlib import asynccontextmanager
|
|
8
|
-
from typing import
|
|
8
|
+
from typing import Any
|
|
9
9
|
|
|
10
10
|
import grpc
|
|
11
11
|
|
|
@@ -13,9 +13,6 @@ from digitalkin.core.common import ConnectionFactory, ModuleFactory
|
|
|
13
13
|
from digitalkin.core.job_manager.base_job_manager import BaseJobManager
|
|
14
14
|
from digitalkin.core.task_manager.local_task_manager import LocalTaskManager
|
|
15
15
|
from digitalkin.core.task_manager.task_session import TaskSession
|
|
16
|
-
|
|
17
|
-
if TYPE_CHECKING:
|
|
18
|
-
from digitalkin.core.task_manager.surrealdb_repository import SurrealDBConnection
|
|
19
16
|
from digitalkin.logger import logger
|
|
20
17
|
from digitalkin.models.core.task_monitor import TaskStatus
|
|
21
18
|
from digitalkin.models.module.base_types import InputModelT, OutputModelT, SetupModelT
|
|
@@ -32,6 +29,10 @@ class SingleJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
32
29
|
to handle their output data.
|
|
33
30
|
"""
|
|
34
31
|
|
|
32
|
+
async def start(self) -> None:
|
|
33
|
+
"""Start manager."""
|
|
34
|
+
self.channel = await ConnectionFactory.create_surreal_connection("task_manager", datetime.timedelta(seconds=5))
|
|
35
|
+
|
|
35
36
|
def __init__(
|
|
36
37
|
self,
|
|
37
38
|
module_class: type[BaseModule],
|
|
@@ -54,11 +55,6 @@ class SingleJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
54
55
|
super().__init__(module_class, services_mode, task_manager)
|
|
55
56
|
|
|
56
57
|
self._lock = asyncio.Lock()
|
|
57
|
-
self.channel: SurrealDBConnection | None = None
|
|
58
|
-
|
|
59
|
-
async def start(self) -> None:
|
|
60
|
-
"""Start manager."""
|
|
61
|
-
self.channel = await ConnectionFactory.create_surreal_connection("task_manager", datetime.timedelta(seconds=5))
|
|
62
58
|
|
|
63
59
|
async def generate_config_setup_module_response(self, job_id: str) -> SetupModelT | ModuleCodeModel:
|
|
64
60
|
"""Generate a stream consumer for a module's output data.
|
|
@@ -117,14 +113,11 @@ class SingleJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
117
113
|
str: The unique identifier (job ID) of the created job.
|
|
118
114
|
|
|
119
115
|
Raises:
|
|
120
|
-
RuntimeError: If start() was not called before creating jobs.
|
|
121
116
|
Exception: If the module fails to start.
|
|
122
117
|
"""
|
|
123
118
|
job_id = str(uuid.uuid4())
|
|
119
|
+
# TODO: Ensure the job_id is unique.
|
|
124
120
|
module = ModuleFactory.create_module_instance(self.module_class, job_id, mission_id, setup_id, setup_version_id)
|
|
125
|
-
if self.channel is None:
|
|
126
|
-
msg = "JobManager.start() must be called before creating jobs"
|
|
127
|
-
raise RuntimeError(msg)
|
|
128
121
|
self.tasks_sessions[job_id] = TaskSession(job_id, mission_id, self.channel, module)
|
|
129
122
|
|
|
130
123
|
try:
|
|
@@ -144,33 +137,13 @@ class SingleJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
144
137
|
async def add_to_queue(self, job_id: str, output_data: OutputModelT | ModuleCodeModel) -> None:
|
|
145
138
|
"""Add output data to the queue for a specific job.
|
|
146
139
|
|
|
147
|
-
|
|
148
|
-
drops the oldest message to make room for the new one.
|
|
149
|
-
Rejects writes after stream is closed to prevent message loss.
|
|
140
|
+
This method is used as a callback to handle output data generated by a module job.
|
|
150
141
|
|
|
151
142
|
Args:
|
|
152
143
|
job_id: The unique identifier of the job.
|
|
153
144
|
output_data: The output data produced by the job.
|
|
154
145
|
"""
|
|
155
|
-
|
|
156
|
-
if session is None:
|
|
157
|
-
logger.warning("Queue write rejected - session not found", extra={"job_id": job_id})
|
|
158
|
-
return
|
|
159
|
-
|
|
160
|
-
if session.stream_closed:
|
|
161
|
-
logger.debug("Queue write rejected - stream closed", extra={"job_id": job_id})
|
|
162
|
-
return
|
|
163
|
-
|
|
164
|
-
try:
|
|
165
|
-
await asyncio.wait_for(session.queue.put(output_data.model_dump()), timeout=5.0)
|
|
166
|
-
except asyncio.TimeoutError:
|
|
167
|
-
logger.warning("Queue full, dropping oldest message", extra={"job_id": job_id})
|
|
168
|
-
try:
|
|
169
|
-
session.queue.get_nowait()
|
|
170
|
-
session.queue.task_done()
|
|
171
|
-
except asyncio.QueueEmpty:
|
|
172
|
-
pass
|
|
173
|
-
session.queue.put_nowait(output_data.model_dump())
|
|
146
|
+
await self.tasks_sessions[job_id].queue.put(output_data.model_dump())
|
|
174
147
|
|
|
175
148
|
@asynccontextmanager # type: ignore
|
|
176
149
|
async def generate_stream_consumer(self, job_id: str) -> AsyncIterator[AsyncGenerator[dict[str, Any], None]]: # type: ignore
|
|
@@ -207,39 +180,42 @@ class SingleJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
207
180
|
logger.debug("Session: %s with Module %s", job_id, session.module)
|
|
208
181
|
|
|
209
182
|
async def _stream() -> AsyncGenerator[dict[str, Any], Any]:
|
|
210
|
-
"""Stream output data from the module with
|
|
183
|
+
"""Stream output data from the module with simple blocking pattern.
|
|
211
184
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
185
|
+
This implementation uses a simple one-item-at-a-time pattern optimized
|
|
186
|
+
for local execution where we have direct access to session status:
|
|
187
|
+
1. Block waiting for each item
|
|
188
|
+
2. Check termination conditions after each item
|
|
189
|
+
3. Clean shutdown when task completes
|
|
190
|
+
|
|
191
|
+
This pattern provides:
|
|
192
|
+
- Immediate termination when task completes
|
|
193
|
+
- Direct session status monitoring
|
|
194
|
+
- Simple, predictable behavior for local tasks
|
|
215
195
|
|
|
216
196
|
Yields:
|
|
217
197
|
dict: Output data generated by the module.
|
|
218
198
|
"""
|
|
219
199
|
while True:
|
|
220
|
-
if
|
|
221
|
-
|
|
222
|
-
break
|
|
223
|
-
|
|
224
|
-
try:
|
|
225
|
-
msg = await asyncio.wait_for(session.queue.get(), timeout=1.0)
|
|
226
|
-
except asyncio.TimeoutError:
|
|
227
|
-
continue
|
|
228
|
-
|
|
200
|
+
# Block for next item - if queue is empty but producer not finished yet
|
|
201
|
+
msg = await session.queue.get()
|
|
229
202
|
try:
|
|
230
203
|
yield msg
|
|
231
204
|
finally:
|
|
205
|
+
# Always mark task as done, even if consumer raises exception
|
|
232
206
|
session.queue.task_done()
|
|
233
207
|
|
|
208
|
+
# Check termination conditions after each message
|
|
209
|
+
# This allows immediate shutdown when the task completes
|
|
234
210
|
if (
|
|
235
|
-
session.
|
|
236
|
-
or session.is_cancelled.is_set()
|
|
211
|
+
session.is_cancelled.is_set()
|
|
237
212
|
or (session.status is TaskStatus.COMPLETED and session.queue.empty())
|
|
238
213
|
or session.status is TaskStatus.FAILED
|
|
239
214
|
):
|
|
240
215
|
logger.debug(
|
|
241
|
-
"Stream ending for job %s: status=%s, queue_empty=%s",
|
|
216
|
+
"Stream ending for job %s: cancelled=%s, status=%s, queue_empty=%s",
|
|
242
217
|
job_id,
|
|
218
|
+
session.is_cancelled.is_set(),
|
|
243
219
|
session.status,
|
|
244
220
|
session.queue.empty(),
|
|
245
221
|
)
|
|
@@ -286,18 +262,6 @@ class SingleJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
286
262
|
logger.info("Managed task started: '%s'", job_id, extra={"task_id": job_id})
|
|
287
263
|
return job_id
|
|
288
264
|
|
|
289
|
-
async def clean_session(self, task_id: str, mission_id: str) -> bool:
|
|
290
|
-
"""Clean a task's session.
|
|
291
|
-
|
|
292
|
-
Args:
|
|
293
|
-
task_id: Unique identifier for the task.
|
|
294
|
-
mission_id: Mission identifier.
|
|
295
|
-
|
|
296
|
-
Returns:
|
|
297
|
-
bool: True if the task was successfully cleaned, False otherwise.
|
|
298
|
-
"""
|
|
299
|
-
return await self._task_manager.clean_session(task_id, mission_id)
|
|
300
|
-
|
|
301
265
|
async def stop_module(self, job_id: str) -> bool:
|
|
302
266
|
"""Stop a running module job.
|
|
303
267
|
|
|
@@ -323,7 +287,7 @@ class SingleJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
323
287
|
await self.cancel_task(job_id, session.mission_id)
|
|
324
288
|
logger.debug(
|
|
325
289
|
"Module stopped successfully",
|
|
326
|
-
extra={"job_id": job_id, "mission_id": session.mission_id},
|
|
290
|
+
extra={"job_id": job_id, "mission_id": session.mission_id, "module_name": session.module.name},
|
|
327
291
|
)
|
|
328
292
|
except Exception:
|
|
329
293
|
logger.exception("Error stopping module", extra={"job_id": job_id})
|
|
@@ -373,7 +337,7 @@ class SingleJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
373
337
|
await asyncio.gather(*stop_tasks, return_exceptions=True)
|
|
374
338
|
|
|
375
339
|
# Close SurrealDB connection after stopping all modules
|
|
376
|
-
if self
|
|
340
|
+
if hasattr(self, "channel"):
|
|
377
341
|
try:
|
|
378
342
|
await self.channel.close()
|
|
379
343
|
logger.info("SingleJobManager: SurrealDB connection closed")
|
{digitalkin-0.3.2a2 → digitalkin-0.3.2.dev3}/src/digitalkin/core/job_manager/taskiq_job_manager.py
RENAMED
|
@@ -22,7 +22,6 @@ from digitalkin.core.common import ConnectionFactory, QueueFactory
|
|
|
22
22
|
from digitalkin.core.job_manager.base_job_manager import BaseJobManager
|
|
23
23
|
from digitalkin.core.job_manager.taskiq_broker import STREAM, STREAM_RETENTION, TASKIQ_BROKER, cleanup_global_resources
|
|
24
24
|
from digitalkin.core.task_manager.remote_task_manager import RemoteTaskManager
|
|
25
|
-
from digitalkin.core.task_manager.surrealdb_repository import SurrealDBConnection
|
|
26
25
|
from digitalkin.logger import logger
|
|
27
26
|
from digitalkin.models.core.task_monitor import TaskStatus
|
|
28
27
|
from digitalkin.models.module.module_types import InputModelT, OutputModelT, SetupModelT
|
|
@@ -37,7 +36,6 @@ class TaskiqJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
37
36
|
"""Taskiq job manager for running modules in Taskiq tasks."""
|
|
38
37
|
|
|
39
38
|
services_mode: ServicesMode
|
|
40
|
-
channel: SurrealDBConnection | None
|
|
41
39
|
|
|
42
40
|
@staticmethod
|
|
43
41
|
def _define_consumer() -> Consumer:
|
|
@@ -115,7 +113,7 @@ class TaskiqJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
115
113
|
async def _stop(self) -> None:
|
|
116
114
|
"""Stop the TaskiqJobManager and clean up all resources."""
|
|
117
115
|
# Close SurrealDB connection
|
|
118
|
-
if self
|
|
116
|
+
if hasattr(self, "channel"):
|
|
119
117
|
try:
|
|
120
118
|
await self.channel.close()
|
|
121
119
|
logger.info("TaskiqJobManager: SurrealDB connection closed")
|
|
@@ -130,9 +128,8 @@ class TaskiqJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
130
128
|
await self.stream_consumer_task
|
|
131
129
|
|
|
132
130
|
# Clean up job queues
|
|
133
|
-
queue_count = len(self.job_queues)
|
|
134
131
|
self.job_queues.clear()
|
|
135
|
-
logger.info("TaskiqJobManager: Cleared %d job queues",
|
|
132
|
+
logger.info("TaskiqJobManager: Cleared %d job queues", len(self.job_queues))
|
|
136
133
|
|
|
137
134
|
# Call global cleanup for producer and broker
|
|
138
135
|
await cleanup_global_resources()
|
|
@@ -164,7 +161,6 @@ class TaskiqJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
164
161
|
self.job_queues: dict[str, asyncio.Queue] = {}
|
|
165
162
|
self.max_queue_size = 1000
|
|
166
163
|
self.stream_timeout = stream_timeout
|
|
167
|
-
self.channel = None
|
|
168
164
|
|
|
169
165
|
async def generate_config_setup_module_response(self, job_id: str) -> SetupModelT:
|
|
170
166
|
"""Generate a stream consumer for a module's output data.
|
|
@@ -433,7 +429,7 @@ class TaskiqJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
433
429
|
return TaskStatus.FAILED
|
|
434
430
|
|
|
435
431
|
# Safety check: if channel not initialized (start() wasn't called), return FAILED
|
|
436
|
-
if self.channel is None:
|
|
432
|
+
if not hasattr(self, "channel") or self.channel is None:
|
|
437
433
|
logger.warning("Job %s status check failed - channel not initialized", job_id)
|
|
438
434
|
return TaskStatus.FAILED
|
|
439
435
|
|
|
@@ -525,7 +521,7 @@ class TaskiqJobManager(BaseJobManager[InputModelT, OutputModelT, SetupModelT]):
|
|
|
525
521
|
for job_id in self.tasks_sessions:
|
|
526
522
|
try:
|
|
527
523
|
status = await self.get_module_status(job_id)
|
|
528
|
-
task_record = await self.channel.select_by_task_id("tasks", job_id)
|
|
524
|
+
task_record = await self.channel.select_by_task_id("tasks", job_id)
|
|
529
525
|
|
|
530
526
|
modules_info[job_id] = {
|
|
531
527
|
"name": self.module_class.__name__,
|