digitalkin 0.2.17__tar.gz → 0.2.19__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.2.17 → digitalkin-0.2.19}/PKG-INFO +12 -12
- {digitalkin-0.2.17 → digitalkin-0.2.19}/pyproject.toml +12 -12
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/__version__.py +1 -1
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/grpc_servers/module_servicer.py +7 -7
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/models/module/__init__.py +6 -6
- digitalkin-0.2.19/src/digitalkin/models/module/module_types.py +105 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/modules/_base_module.py +54 -45
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/modules/archetype_module.py +0 -2
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/modules/job_manager/base_job_manager.py +2 -5
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/modules/job_manager/single_job_manager.py +7 -7
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/modules/job_manager/taskiq_broker.py +0 -2
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/modules/job_manager/taskiq_job_manager.py +3 -5
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/modules/tool_module.py +1 -2
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/filesystem/default_filesystem.py +7 -6
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/filesystem/filesystem_strategy.py +2 -1
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/filesystem/grpc_filesystem.py +2 -1
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/storage/grpc_storage.py +4 -4
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/utils/package_discover.py +2 -2
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin.egg-info/PKG-INFO +12 -12
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin.egg-info/requires.txt +11 -11
- digitalkin-0.2.17/src/digitalkin/models/module/module_types.py +0 -43
- {digitalkin-0.2.17 → digitalkin-0.2.19}/LICENSE +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/README.md +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/base_server/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/base_server/mock/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/base_server/mock/mock_pb2.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/base_server/server_async_insecure.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/base_server/server_async_secure.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/base_server/server_sync_insecure.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/base_server/server_sync_secure.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/modules/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/modules/cpu_intensive_module.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/modules/minimal_llm_module.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/modules/text_transform_module.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/services/filesystem_module.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/examples/services/storage_module.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/setup.cfg +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/grpc_servers/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/grpc_servers/_base_server.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/grpc_servers/module_server.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/grpc_servers/registry_server.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/grpc_servers/registry_servicer.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/grpc_servers/utils/exceptions.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/grpc_servers/utils/factory.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/grpc_servers/utils/models.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/grpc_servers/utils/types.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/logger.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/models/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/models/module/module.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/models/module/module_context.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/models/services/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/models/services/cost.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/models/services/storage.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/modules/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/modules/job_manager/job_manager_models.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/modules/trigger_handler.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/py.typed +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/agent/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/agent/agent_strategy.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/agent/default_agent.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/base_strategy.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/cost/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/cost/cost_strategy.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/cost/default_cost.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/cost/grpc_cost.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/filesystem/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/identity/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/identity/default_identity.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/identity/identity_strategy.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/registry/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/registry/default_registry.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/registry/registry_strategy.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/services_config.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/services_models.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/setup/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/setup/default_setup.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/setup/grpc_setup.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/setup/setup_strategy.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/snapshot/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/snapshot/default_snapshot.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/snapshot/snapshot_strategy.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/storage/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/storage/default_storage.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/services/storage/storage_strategy.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/utils/__init__.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/utils/arg_parser.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/utils/development_mode_action.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/utils/llm_ready_schema.py +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin.egg-info/SOURCES.txt +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin.egg-info/dependency_links.txt +0 -0
- {digitalkin-0.2.17 → digitalkin-0.2.19}/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.2.
|
|
3
|
+
Version: 0.2.19
|
|
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,36 @@ 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.
|
|
455
|
+
Requires-Dist: digitalkin-proto>=0.1.16
|
|
456
456
|
Requires-Dist: grpcio-health-checking>=1.71.0
|
|
457
457
|
Requires-Dist: grpcio-reflection>=1.71.0
|
|
458
458
|
Requires-Dist: grpcio-status>=1.71.0
|
|
459
459
|
Requires-Dist: pydantic>=2.11.5
|
|
460
460
|
Provides-Extra: dev
|
|
461
|
-
Requires-Dist: typos>=1.
|
|
462
|
-
Requires-Dist: ruff>=0.
|
|
463
|
-
Requires-Dist: mypy>=1.
|
|
464
|
-
Requires-Dist: pyright>=1.1.
|
|
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
465
|
Requires-Dist: pre-commit>=4.2.0; extra == "dev"
|
|
466
466
|
Requires-Dist: bump2version>=1.0.1; extra == "dev"
|
|
467
467
|
Requires-Dist: build>=1.2.2; extra == "dev"
|
|
468
468
|
Requires-Dist: twine>=6.1.0; extra == "dev"
|
|
469
|
-
Requires-Dist: cryptography>=45.0.
|
|
469
|
+
Requires-Dist: cryptography>=45.0.5; extra == "dev"
|
|
470
470
|
Provides-Extra: examples
|
|
471
471
|
Requires-Dist: openai>=1.75.0; extra == "examples"
|
|
472
472
|
Provides-Extra: tests
|
|
473
|
-
Requires-Dist: freezegun>=1.5.
|
|
473
|
+
Requires-Dist: freezegun>=1.5.3; extra == "tests"
|
|
474
474
|
Requires-Dist: hdrhistogram>=0.10.3; extra == "tests"
|
|
475
475
|
Requires-Dist: grpcio-testing>=1.71.0; extra == "tests"
|
|
476
476
|
Requires-Dist: psutil>=7.0.0; extra == "tests"
|
|
477
477
|
Requires-Dist: pytest>=8.4.0; extra == "tests"
|
|
478
|
-
Requires-Dist: pytest-asyncio>=1.
|
|
478
|
+
Requires-Dist: pytest-asyncio>=1.1.0; extra == "tests"
|
|
479
479
|
Requires-Dist: pytest-cov>=6.1.0; extra == "tests"
|
|
480
480
|
Provides-Extra: taskiq
|
|
481
481
|
Requires-Dist: rstream>=0.30.0; extra == "taskiq"
|
|
482
|
-
Requires-Dist: taskiq-aio-pika>=0.4.
|
|
483
|
-
Requires-Dist: taskiq-redis>=1.0
|
|
484
|
-
Requires-Dist: taskiq[reload]>=0.11.
|
|
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"
|
|
485
485
|
Dynamic: license-file
|
|
486
486
|
|
|
487
487
|
# DigitalKin Python SDK
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
keywords = [ "digitalkin", "kin", "agent", "gprc", "sdk" ]
|
|
14
14
|
# Version of the package automatically updated by bump2version (that is why it is separated)
|
|
15
|
-
version = "0.2.
|
|
15
|
+
version = "0.2.19"
|
|
16
16
|
|
|
17
17
|
classifiers = [
|
|
18
18
|
"Development Status :: 3 - Alpha",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
]
|
|
30
30
|
|
|
31
31
|
dependencies = [
|
|
32
|
-
"digitalkin-proto>=0.1.
|
|
32
|
+
"digitalkin-proto>=0.1.16",
|
|
33
33
|
"grpcio-health-checking>=1.71.0",
|
|
34
34
|
"grpcio-reflection>=1.71.0",
|
|
35
35
|
"grpcio-status>=1.71.0",
|
|
@@ -38,31 +38,31 @@
|
|
|
38
38
|
|
|
39
39
|
[project.optional-dependencies]
|
|
40
40
|
dev = [
|
|
41
|
-
"typos>=1.
|
|
42
|
-
"ruff>=0.
|
|
43
|
-
"mypy>=1.
|
|
44
|
-
"pyright>=1.1.
|
|
41
|
+
"typos>=1.34.0",
|
|
42
|
+
"ruff>=0.12.5",
|
|
43
|
+
"mypy>=1.17.0",
|
|
44
|
+
"pyright>=1.1.403",
|
|
45
45
|
"pre-commit>=4.2.0",
|
|
46
46
|
"bump2version>=1.0.1",
|
|
47
47
|
"build>=1.2.2",
|
|
48
48
|
"twine>=6.1.0",
|
|
49
|
-
"cryptography>=45.0.
|
|
49
|
+
"cryptography>=45.0.5",
|
|
50
50
|
]
|
|
51
51
|
examples = [ "openai>=1.75.0" ]
|
|
52
52
|
tests = [
|
|
53
|
-
"freezegun>=1.5.
|
|
53
|
+
"freezegun>=1.5.3",
|
|
54
54
|
"hdrhistogram>=0.10.3",
|
|
55
55
|
"grpcio-testing>=1.71.0",
|
|
56
56
|
"psutil>=7.0.0",
|
|
57
57
|
"pytest>=8.4.0",
|
|
58
|
-
"pytest-asyncio>=1.
|
|
58
|
+
"pytest-asyncio>=1.1.0",
|
|
59
59
|
"pytest-cov>=6.1.0",
|
|
60
60
|
]
|
|
61
61
|
taskiq = [
|
|
62
62
|
"rstream>=0.30.0",
|
|
63
|
-
"taskiq-aio-pika>=0.4.
|
|
64
|
-
"taskiq-redis>=1.0
|
|
65
|
-
"taskiq[reload]>=0.11.
|
|
63
|
+
"taskiq-aio-pika>=0.4.3",
|
|
64
|
+
"taskiq-redis>=1.1.0",
|
|
65
|
+
"taskiq[reload]>=0.11.18",
|
|
66
66
|
]
|
|
67
67
|
|
|
68
68
|
[project.urls]
|
|
@@ -105,7 +105,8 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
105
105
|
setup_version = request.setup_version
|
|
106
106
|
config_setup_data = self.module_class.create_config_setup_model(json_format.MessageToDict(request.content))
|
|
107
107
|
setup_version_data = self.module_class.create_setup_model(
|
|
108
|
-
json_format.MessageToDict(request.setup_version.content)
|
|
108
|
+
json_format.MessageToDict(request.setup_version.content),
|
|
109
|
+
config_fields=True,
|
|
109
110
|
)
|
|
110
111
|
|
|
111
112
|
if not setup_version_data:
|
|
@@ -119,7 +120,6 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
119
120
|
# create a task to run the module in background
|
|
120
121
|
job_id = await self.job_manager.create_config_setup_instance_job(
|
|
121
122
|
config_setup_data,
|
|
122
|
-
setup_version_data,
|
|
123
123
|
request.mission_id,
|
|
124
124
|
setup_version.id,
|
|
125
125
|
)
|
|
@@ -333,7 +333,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
333
333
|
except NotImplementedError as e:
|
|
334
334
|
logger.warning(e)
|
|
335
335
|
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
336
|
-
context.set_details(e)
|
|
336
|
+
context.set_details(str(e))
|
|
337
337
|
return information_pb2.GetModuleInputResponse()
|
|
338
338
|
|
|
339
339
|
return information_pb2.GetModuleInputResponse(
|
|
@@ -369,7 +369,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
369
369
|
except NotImplementedError as e:
|
|
370
370
|
logger.warning(e)
|
|
371
371
|
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
372
|
-
context.set_details(e)
|
|
372
|
+
context.set_details(str(e))
|
|
373
373
|
return information_pb2.GetModuleOutputResponse()
|
|
374
374
|
|
|
375
375
|
return information_pb2.GetModuleOutputResponse(
|
|
@@ -405,7 +405,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
405
405
|
except NotImplementedError as e:
|
|
406
406
|
logger.warning(e)
|
|
407
407
|
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
408
|
-
context.set_details(e)
|
|
408
|
+
context.set_details(str(e))
|
|
409
409
|
return information_pb2.GetModuleSetupResponse()
|
|
410
410
|
|
|
411
411
|
return information_pb2.GetModuleSetupResponse(
|
|
@@ -441,7 +441,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
441
441
|
except NotImplementedError as e:
|
|
442
442
|
logger.warning(e)
|
|
443
443
|
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
444
|
-
context.set_details(e)
|
|
444
|
+
context.set_details(str(e))
|
|
445
445
|
return information_pb2.GetModuleSecretResponse()
|
|
446
446
|
|
|
447
447
|
return information_pb2.GetModuleSecretResponse(
|
|
@@ -477,7 +477,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
477
477
|
except NotImplementedError as e:
|
|
478
478
|
logger.warning(e)
|
|
479
479
|
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
480
|
-
context.set_details(e)
|
|
480
|
+
context.set_details(str(e))
|
|
481
481
|
return information_pb2.GetConfigSetupModuleResponse()
|
|
482
482
|
|
|
483
483
|
return information_pb2.GetConfigSetupModuleResponse(
|
|
@@ -3,24 +3,24 @@
|
|
|
3
3
|
from digitalkin.models.module.module import Module, ModuleStatus
|
|
4
4
|
from digitalkin.models.module.module_context import ModuleContext
|
|
5
5
|
from digitalkin.models.module.module_types import (
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
DataModel,
|
|
7
|
+
DataTrigger,
|
|
8
8
|
InputModelT,
|
|
9
|
-
InputTrigger,
|
|
10
9
|
OutputModelT,
|
|
11
10
|
SecretModelT,
|
|
11
|
+
SetupModel,
|
|
12
12
|
SetupModelT,
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
__all__ = [
|
|
16
|
-
"
|
|
17
|
-
"
|
|
16
|
+
"DataModel",
|
|
17
|
+
"DataTrigger",
|
|
18
18
|
"InputModelT",
|
|
19
|
-
"InputTrigger",
|
|
20
19
|
"Module",
|
|
21
20
|
"ModuleContext",
|
|
22
21
|
"ModuleStatus",
|
|
23
22
|
"OutputModelT",
|
|
24
23
|
"SecretModelT",
|
|
24
|
+
"SetupModel",
|
|
25
25
|
"SetupModelT",
|
|
26
26
|
]
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Types for module models."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
|
+
from typing import Any, ClassVar, Generic, TypeVar, cast
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field, create_model
|
|
7
|
+
|
|
8
|
+
from digitalkin.logger import logger
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DataTrigger(BaseModel):
|
|
12
|
+
"""Defines the root input model exposing the protocol.
|
|
13
|
+
|
|
14
|
+
The mandatory protocol is important to define the module beahvior following the user or agent input.
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
class MyInput(DataModel):
|
|
18
|
+
root: DataTrigger
|
|
19
|
+
user_define_data: Any
|
|
20
|
+
|
|
21
|
+
# Usage
|
|
22
|
+
my_input = MyInput(root=DataTrigger(protocol="message"))
|
|
23
|
+
print(my_input.root.protocol) # Output: message
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
protocol: ClassVar[str]
|
|
27
|
+
created_at: str = datetime.now(tz=timezone.utc).isoformat()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
DataTriggerT = TypeVar("DataTriggerT", bound=DataTrigger)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class DataModel(BaseModel, Generic[DataTriggerT]):
|
|
34
|
+
"""Base definition of input model showing mandatory root fields.
|
|
35
|
+
|
|
36
|
+
The Model define the Module Input, usually referring to multiple input type defined by an union.
|
|
37
|
+
|
|
38
|
+
Example:
|
|
39
|
+
class ModuleInput(DataModel):
|
|
40
|
+
root: FileInput | MessageInput
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
root: DataTriggerT
|
|
44
|
+
annotations: dict[str, str] = Field(
|
|
45
|
+
default={},
|
|
46
|
+
title="Annotations",
|
|
47
|
+
description="Additional metadata or annotations related to the output. ex {'role': 'user'}",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
InputModelT = TypeVar("InputModelT", bound=DataModel)
|
|
52
|
+
OutputModelT = TypeVar("OutputModelT", bound=DataModel)
|
|
53
|
+
SecretModelT = TypeVar("SecretModelT", bound=BaseModel)
|
|
54
|
+
SetupModelT = TypeVar("SetupModelT", bound="SetupModel")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class SetupModel(BaseModel):
|
|
58
|
+
"""Base definition of setup model showing mandatory root fields.
|
|
59
|
+
|
|
60
|
+
Optionally, the setup model can define a config option in json_schema_extra to be used to initialize the Kin.
|
|
61
|
+
|
|
62
|
+
Example:
|
|
63
|
+
class MySetup(SetupModel):
|
|
64
|
+
name: str = Field()
|
|
65
|
+
number: int = Field(..., json_schema_extra={"config": True})
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
def get_clean_model(cls, *, config_fields: bool, hidden_fields: bool) -> type[SetupModelT]: # type: ignore
|
|
70
|
+
"""Dynamically builds and returns a new BaseModel subclass.
|
|
71
|
+
|
|
72
|
+
containing only those fields where json_schema_extra["config"] == True.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Type[BaseModel]: A new BaseModel subclass with the filtered fields.
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
ValueError: If both config_fields and hidden_fields are set to True.
|
|
79
|
+
"""
|
|
80
|
+
clean_fields: dict[str, Any] = {}
|
|
81
|
+
for name, field_info in cls.model_fields.items():
|
|
82
|
+
extra = getattr(field_info, "json_schema_extra", {}) or {}
|
|
83
|
+
is_config = bool(extra.get("config", False))
|
|
84
|
+
is_hidden = bool(extra.get("hidden", False))
|
|
85
|
+
|
|
86
|
+
# Skip config unless explicitly included
|
|
87
|
+
if is_config and not config_fields:
|
|
88
|
+
logger.debug("Skipping '%s' (config-only)", name)
|
|
89
|
+
continue
|
|
90
|
+
|
|
91
|
+
# Skip hidden unless explicitly included
|
|
92
|
+
if is_hidden and not hidden_fields:
|
|
93
|
+
logger.debug("Skipping '%s' (hidden-only)", name)
|
|
94
|
+
continue
|
|
95
|
+
|
|
96
|
+
clean_fields[name] = (field_info.annotation, field_info)
|
|
97
|
+
|
|
98
|
+
# Dynamically create a model e.g. "SetupModel"
|
|
99
|
+
m = create_model(
|
|
100
|
+
f"{cls.__name__}",
|
|
101
|
+
__base__=BaseModel,
|
|
102
|
+
__config__=ConfigDict(arbitrary_types_allowed=True),
|
|
103
|
+
**clean_fields,
|
|
104
|
+
)
|
|
105
|
+
return cast("type[SetupModelT]", m)
|
|
@@ -9,10 +9,8 @@ from typing import Any, ClassVar, Generic
|
|
|
9
9
|
|
|
10
10
|
from pydantic import BaseModel
|
|
11
11
|
|
|
12
|
-
from digitalkin.grpc_servers.utils.exceptions import OptionalFeatureNotImplementedError
|
|
13
12
|
from digitalkin.logger import logger
|
|
14
13
|
from digitalkin.models.module import (
|
|
15
|
-
ConfigSetupModelT,
|
|
16
14
|
InputModelT,
|
|
17
15
|
ModuleStatus,
|
|
18
16
|
OutputModelT,
|
|
@@ -33,11 +31,11 @@ from digitalkin.utils.llm_ready_schema import llm_ready_schema
|
|
|
33
31
|
from digitalkin.utils.package_discover import ModuleDiscoverer
|
|
34
32
|
|
|
35
33
|
|
|
36
|
-
class
|
|
34
|
+
class ModuleCodeModel(BaseModel):
|
|
37
35
|
"""typed error/code model."""
|
|
38
36
|
|
|
39
37
|
code: str
|
|
40
|
-
|
|
38
|
+
message: str
|
|
41
39
|
short_description: str
|
|
42
40
|
|
|
43
41
|
|
|
@@ -48,7 +46,6 @@ class BaseModule( # noqa: PLR0904
|
|
|
48
46
|
OutputModelT,
|
|
49
47
|
SetupModelT,
|
|
50
48
|
SecretModelT,
|
|
51
|
-
ConfigSetupModelT,
|
|
52
49
|
],
|
|
53
50
|
):
|
|
54
51
|
"""BaseModule is the abstract base for all modules in the DigitalKin SDK."""
|
|
@@ -56,10 +53,10 @@ class BaseModule( # noqa: PLR0904
|
|
|
56
53
|
name: str
|
|
57
54
|
description: str
|
|
58
55
|
|
|
59
|
-
|
|
56
|
+
setup_format: type[SetupModelT]
|
|
57
|
+
|
|
60
58
|
input_format: type[InputModelT]
|
|
61
59
|
output_format: type[OutputModelT]
|
|
62
|
-
setup_format: type[SetupModelT]
|
|
63
60
|
secret_format: type[SecretModelT]
|
|
64
61
|
metadata: ClassVar[dict[str, Any]]
|
|
65
62
|
|
|
@@ -172,20 +169,22 @@ class BaseModule( # noqa: PLR0904
|
|
|
172
169
|
def get_config_setup_format(cls, *, llm_format: bool) -> str:
|
|
173
170
|
"""Gets the JSON schema of the config setup format model.
|
|
174
171
|
|
|
172
|
+
The config setup format is used only to initialize the module with configuration data.
|
|
173
|
+
The setup format is used to initialize an run the module with setup data.
|
|
174
|
+
|
|
175
175
|
Raises:
|
|
176
|
-
|
|
176
|
+
NotImplementedError: If the `setup_format` is not defined.
|
|
177
177
|
|
|
178
178
|
Returns:
|
|
179
179
|
The JSON schema of the config setup format as a string.
|
|
180
180
|
"""
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if config_setup_format is not None:
|
|
181
|
+
if cls.setup_format is not None:
|
|
182
|
+
setup_format = cls.setup_format.get_clean_model(config_fields=True, hidden_fields=False)
|
|
184
183
|
if llm_format:
|
|
185
|
-
return json.dumps(llm_ready_schema(
|
|
186
|
-
return json.dumps(
|
|
184
|
+
return json.dumps(llm_ready_schema(setup_format), indent=2)
|
|
185
|
+
return json.dumps(setup_format.model_json_schema(), indent=2)
|
|
187
186
|
msg = "'%s' class does not define an 'config_setup_format'."
|
|
188
|
-
raise
|
|
187
|
+
raise NotImplementedError(msg)
|
|
189
188
|
|
|
190
189
|
@classmethod
|
|
191
190
|
def get_setup_format(cls, *, llm_format: bool) -> str:
|
|
@@ -198,14 +197,15 @@ class BaseModule( # noqa: PLR0904
|
|
|
198
197
|
The JSON schema of the setup format as a string.
|
|
199
198
|
"""
|
|
200
199
|
if cls.setup_format is not None:
|
|
200
|
+
setup_format = cls.setup_format.get_clean_model(config_fields=False, hidden_fields=True)
|
|
201
201
|
if llm_format:
|
|
202
|
-
return json.dumps(llm_ready_schema(
|
|
203
|
-
return json.dumps(
|
|
202
|
+
return json.dumps(llm_ready_schema(setup_format), indent=2)
|
|
203
|
+
return json.dumps(setup_format.model_json_schema(), indent=2)
|
|
204
204
|
msg = "'%s' class does not define an 'setup_format'."
|
|
205
205
|
raise NotImplementedError(msg)
|
|
206
206
|
|
|
207
207
|
@classmethod
|
|
208
|
-
def create_config_setup_model(cls, config_setup_data: dict[str, Any]) ->
|
|
208
|
+
def create_config_setup_model(cls, config_setup_data: dict[str, Any]) -> SetupModelT:
|
|
209
209
|
"""Create the setup model from the setup data.
|
|
210
210
|
|
|
211
211
|
Args:
|
|
@@ -214,7 +214,7 @@ class BaseModule( # noqa: PLR0904
|
|
|
214
214
|
Returns:
|
|
215
215
|
The setup model.
|
|
216
216
|
"""
|
|
217
|
-
return cls.
|
|
217
|
+
return cls.setup_format(**config_setup_data)
|
|
218
218
|
|
|
219
219
|
@classmethod
|
|
220
220
|
def create_input_model(cls, input_data: dict[str, Any]) -> InputModelT:
|
|
@@ -229,16 +229,17 @@ class BaseModule( # noqa: PLR0904
|
|
|
229
229
|
return cls.input_format(**input_data)
|
|
230
230
|
|
|
231
231
|
@classmethod
|
|
232
|
-
def create_setup_model(cls, setup_data: dict[str, Any]) -> SetupModelT:
|
|
232
|
+
def create_setup_model(cls, setup_data: dict[str, Any], *, config_fields: bool = False) -> SetupModelT:
|
|
233
233
|
"""Create the setup model from the setup data.
|
|
234
234
|
|
|
235
235
|
Args:
|
|
236
236
|
setup_data: The setup data to create the model from.
|
|
237
|
+
config_fields: If True, include only fields with json_schema_extra["config"] == True.
|
|
237
238
|
|
|
238
239
|
Returns:
|
|
239
240
|
The setup model.
|
|
240
241
|
"""
|
|
241
|
-
return cls.setup_format(**setup_data)
|
|
242
|
+
return cls.setup_format.get_clean_model(config_fields=config_fields, hidden_fields=True)(**setup_data)
|
|
242
243
|
|
|
243
244
|
@classmethod
|
|
244
245
|
def create_secret_model(cls, secret_data: dict[str, Any]) -> SecretModelT:
|
|
@@ -290,20 +291,20 @@ class BaseModule( # noqa: PLR0904
|
|
|
290
291
|
"""
|
|
291
292
|
return cls.triggers_discoverer.register_trigger(handler_cls)
|
|
292
293
|
|
|
293
|
-
|
|
294
|
-
async def run_config_setup(
|
|
295
|
-
self,
|
|
296
|
-
config_setup_data: ConfigSetupModelT,
|
|
297
|
-
setup_data: SetupModelT,
|
|
298
|
-
callback: Callable,
|
|
299
|
-
) -> None:
|
|
294
|
+
async def run_config_setup(self, config_setup_data: SetupModelT) -> SetupModelT: # noqa: PLR6301
|
|
300
295
|
"""Run config setup the module.
|
|
301
296
|
|
|
302
|
-
|
|
303
|
-
|
|
297
|
+
The config setup is used to initialize the setup with configuration data.
|
|
298
|
+
This method is typically used to set up the module with necessary configuration before running it,
|
|
299
|
+
especially for processing data like files.
|
|
300
|
+
The function needs to save the setup in the storage.
|
|
301
|
+
The module will be initialize with the setup and not the config setup.
|
|
302
|
+
This method is optional, the config setup and setup can be the same.
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
The updated setup model after running the config setup.
|
|
304
306
|
"""
|
|
305
|
-
|
|
306
|
-
raise OptionalFeatureNotImplementedError(msg)
|
|
307
|
+
return config_setup_data
|
|
307
308
|
|
|
308
309
|
@abstractmethod
|
|
309
310
|
async def initialize(self, setup_data: SetupModelT) -> None:
|
|
@@ -364,9 +365,9 @@ class BaseModule( # noqa: PLR0904
|
|
|
364
365
|
asyncio.CancelledError: If the module is cancelled
|
|
365
366
|
"""
|
|
366
367
|
try:
|
|
367
|
-
logger.
|
|
368
|
+
logger.info("Starting module %s", self.name)
|
|
368
369
|
await self.run(input_data, setup_data, callback)
|
|
369
|
-
logger.
|
|
370
|
+
logger.info("Module %s finished", self.name)
|
|
370
371
|
except asyncio.CancelledError:
|
|
371
372
|
self._status = ModuleStatus.CANCELLED
|
|
372
373
|
logger.error(f"Module {self.name} cancelled")
|
|
@@ -374,7 +375,7 @@ class BaseModule( # noqa: PLR0904
|
|
|
374
375
|
self._status = ModuleStatus.FAILED
|
|
375
376
|
logger.exception("Error inside module %s", self.name)
|
|
376
377
|
else:
|
|
377
|
-
self._status = ModuleStatus.
|
|
378
|
+
self._status = ModuleStatus.STOPPING
|
|
378
379
|
finally:
|
|
379
380
|
await self.stop()
|
|
380
381
|
|
|
@@ -382,22 +383,22 @@ class BaseModule( # noqa: PLR0904
|
|
|
382
383
|
self,
|
|
383
384
|
input_data: InputModelT,
|
|
384
385
|
setup_data: SetupModelT,
|
|
385
|
-
callback: Callable[[OutputModelT |
|
|
386
|
+
callback: Callable[[OutputModelT | ModuleCodeModel], Coroutine[Any, Any, None]],
|
|
386
387
|
done_callback: Callable | None = None,
|
|
387
388
|
) -> None:
|
|
388
389
|
"""Start the module."""
|
|
389
390
|
try:
|
|
390
|
-
logger.
|
|
391
|
+
logger.debug("Inititalize module")
|
|
391
392
|
await self.initialize(setup_data=setup_data)
|
|
392
393
|
except Exception as e:
|
|
393
394
|
self._status = ModuleStatus.FAILED
|
|
394
395
|
short_description = "Error initializing module"
|
|
395
396
|
logger.exception("%s: %s", short_description, e)
|
|
396
397
|
await callback(
|
|
397
|
-
|
|
398
|
+
ModuleCodeModel(
|
|
398
399
|
code=str(self._status),
|
|
399
400
|
short_description=short_description,
|
|
400
|
-
|
|
401
|
+
message=str(e),
|
|
401
402
|
)
|
|
402
403
|
)
|
|
403
404
|
if done_callback is not None:
|
|
@@ -406,9 +407,9 @@ class BaseModule( # noqa: PLR0904
|
|
|
406
407
|
return
|
|
407
408
|
|
|
408
409
|
try:
|
|
409
|
-
logger.
|
|
410
|
+
logger.debug("Init the discovered input handlers.")
|
|
410
411
|
self.triggers_discoverer.init_handlers(self.context)
|
|
411
|
-
logger.
|
|
412
|
+
logger.debug("Run lifecycle")
|
|
412
413
|
self._status = ModuleStatus.RUNNING
|
|
413
414
|
self._task = asyncio.create_task(
|
|
414
415
|
self._run_lifecycle(input_data, setup_data, callback),
|
|
@@ -422,7 +423,8 @@ class BaseModule( # noqa: PLR0904
|
|
|
422
423
|
|
|
423
424
|
async def stop(self) -> None:
|
|
424
425
|
"""Stop the module."""
|
|
425
|
-
|
|
426
|
+
logger.info("Stopping module %s with status %s", self.name, self._status)
|
|
427
|
+
if self._status not in {ModuleStatus.RUNNING, ModuleStatus.STOPPING}:
|
|
426
428
|
return
|
|
427
429
|
|
|
428
430
|
try:
|
|
@@ -431,22 +433,29 @@ class BaseModule( # noqa: PLR0904
|
|
|
431
433
|
self._task.cancel()
|
|
432
434
|
with contextlib.suppress(asyncio.CancelledError):
|
|
433
435
|
await self._task
|
|
436
|
+
logger.debug("Module %s stopped", self.name)
|
|
434
437
|
await self.cleanup()
|
|
438
|
+
self._status = ModuleStatus.STOPPED
|
|
439
|
+
logger.debug("Module %s cleaned", self.name)
|
|
435
440
|
except Exception:
|
|
436
441
|
self._status = ModuleStatus.FAILED
|
|
437
442
|
logger.exception("Error stopping module")
|
|
438
443
|
|
|
439
444
|
async def start_config_setup(
|
|
440
445
|
self,
|
|
441
|
-
config_setup_data:
|
|
442
|
-
|
|
443
|
-
callback: Callable[[OutputModelT | ModuleErrorModel], Coroutine[Any, Any, None]],
|
|
446
|
+
config_setup_data: SetupModelT,
|
|
447
|
+
callback: Callable[[SetupModelT | ModuleCodeModel], Coroutine[Any, Any, None]],
|
|
444
448
|
) -> None:
|
|
445
449
|
"""Start the module."""
|
|
446
450
|
try:
|
|
447
451
|
logger.info("Run Config Setup lifecycle")
|
|
448
452
|
self._status = ModuleStatus.RUNNING
|
|
449
|
-
await self.run_config_setup(config_setup_data
|
|
453
|
+
content = await self.run_config_setup(config_setup_data)
|
|
454
|
+
|
|
455
|
+
wrapper = config_setup_data.model_dump()
|
|
456
|
+
wrapper["content"] = content.model_dump()
|
|
457
|
+
await callback(self.create_setup_model(wrapper))
|
|
458
|
+
self._status = ModuleStatus.STOPPING
|
|
450
459
|
except Exception:
|
|
451
460
|
self._status = ModuleStatus.FAILED
|
|
452
461
|
logger.exception("Error during module lifecyle")
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
from abc import ABC
|
|
4
4
|
|
|
5
5
|
from digitalkin.models.module import InputModelT, OutputModelT, SecretModelT, SetupModelT
|
|
6
|
-
from digitalkin.models.module.module_types import ConfigSetupModelT
|
|
7
6
|
from digitalkin.modules._base_module import BaseModule
|
|
8
7
|
|
|
9
8
|
|
|
@@ -13,7 +12,6 @@ class ArchetypeModule(
|
|
|
13
12
|
OutputModelT,
|
|
14
13
|
SetupModelT,
|
|
15
14
|
SecretModelT,
|
|
16
|
-
ConfigSetupModelT,
|
|
17
15
|
],
|
|
18
16
|
ABC,
|
|
19
17
|
):
|
{digitalkin-0.2.17 → digitalkin-0.2.19}/src/digitalkin/modules/job_manager/base_job_manager.py
RENAMED
|
@@ -7,13 +7,12 @@ from typing import Any, Generic
|
|
|
7
7
|
|
|
8
8
|
from digitalkin.models import ModuleStatus
|
|
9
9
|
from digitalkin.models.module import InputModelT, OutputModelT, SetupModelT
|
|
10
|
-
from digitalkin.models.module.module_types import ConfigSetupModelT
|
|
11
10
|
from digitalkin.modules._base_module import BaseModule
|
|
12
11
|
from digitalkin.services.services_config import ServicesConfig
|
|
13
12
|
from digitalkin.services.services_models import ServicesMode
|
|
14
13
|
|
|
15
14
|
|
|
16
|
-
class BaseJobManager(abc.ABC, Generic[InputModelT, SetupModelT
|
|
15
|
+
class BaseJobManager(abc.ABC, Generic[InputModelT, SetupModelT]):
|
|
17
16
|
"""Abstract base class for managing background module jobs."""
|
|
18
17
|
|
|
19
18
|
async def _start(self) -> None:
|
|
@@ -120,8 +119,7 @@ class BaseJobManager(abc.ABC, Generic[InputModelT, SetupModelT, ConfigSetupModel
|
|
|
120
119
|
@abc.abstractmethod
|
|
121
120
|
async def create_config_setup_instance_job(
|
|
122
121
|
self,
|
|
123
|
-
config_setup_data:
|
|
124
|
-
setup_data: SetupModelT,
|
|
122
|
+
config_setup_data: SetupModelT,
|
|
125
123
|
mission_id: str,
|
|
126
124
|
setup_version_id: str,
|
|
127
125
|
) -> str:
|
|
@@ -132,7 +130,6 @@ class BaseJobManager(abc.ABC, Generic[InputModelT, SetupModelT, ConfigSetupModel
|
|
|
132
130
|
|
|
133
131
|
Args:
|
|
134
132
|
config_setup_data: The input data required to start the job.
|
|
135
|
-
setup_data: The setup configuration for the module.
|
|
136
133
|
mission_id: The mission ID associated with the job.
|
|
137
134
|
setup_version_id: The setup ID.
|
|
138
135
|
|