digitalkin 0.2.13__py3-none-any.whl → 0.2.15__py3-none-any.whl
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/__version__.py +1 -1
- digitalkin/grpc_servers/module_servicer.py +93 -1
- digitalkin/grpc_servers/utils/exceptions.py +4 -0
- digitalkin/models/module/__init__.py +2 -1
- digitalkin/models/module/module_types.py +1 -0
- digitalkin/modules/_base_module.py +80 -2
- digitalkin/modules/archetype_module.py +11 -1
- digitalkin/modules/job_manager/base_job_manager.py +45 -3
- digitalkin/modules/job_manager/single_job_manager.py +70 -3
- digitalkin/modules/job_manager/taskiq_broker.py +42 -1
- digitalkin/modules/job_manager/taskiq_job_manager.py +90 -17
- digitalkin/modules/tool_module.py +2 -1
- digitalkin/modules/trigger_module.py +3 -1
- digitalkin/services/filesystem/default_filesystem.py +327 -130
- digitalkin/services/filesystem/filesystem_strategy.py +169 -34
- digitalkin/services/filesystem/grpc_filesystem.py +225 -117
- digitalkin/services/setup/grpc_setup.py +1 -0
- {digitalkin-0.2.13.dist-info → digitalkin-0.2.15.dist-info}/METADATA +14 -14
- {digitalkin-0.2.13.dist-info → digitalkin-0.2.15.dist-info}/RECORD +27 -26
- {digitalkin-0.2.13.dist-info → digitalkin-0.2.15.dist-info}/WHEEL +1 -1
- {digitalkin-0.2.13.dist-info → digitalkin-0.2.15.dist-info}/top_level.txt +1 -0
- modules/cpu_intensive_module.py +11 -2
- modules/minimal_llm_module.py +41 -3
- modules/text_transform_module.py +0 -1
- services/filesystem_module.py +198 -0
- {modules → services}/storage_module.py +20 -7
- {digitalkin-0.2.13.dist-info → digitalkin-0.2.15.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: digitalkin
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.15
|
|
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.15
|
|
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
|
-
Requires-Dist: pydantic>=2.11.
|
|
459
|
+
Requires-Dist: pydantic>=2.11.5
|
|
460
460
|
Provides-Extra: dev
|
|
461
|
-
Requires-Dist: typos>=1.
|
|
462
|
-
Requires-Dist: ruff>=0.11.
|
|
463
|
-
Requires-Dist: mypy>=1.
|
|
464
|
-
Requires-Dist: pyright>=1.1.
|
|
461
|
+
Requires-Dist: typos>=1.33.1; extra == "dev"
|
|
462
|
+
Requires-Dist: ruff>=0.11.13; extra == "dev"
|
|
463
|
+
Requires-Dist: mypy>=1.16.0; extra == "dev"
|
|
464
|
+
Requires-Dist: pyright>=1.1.401; 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>=
|
|
470
|
-
Requires-Dist: taskiq[reload]>=0.11.17; extra == "dev"
|
|
469
|
+
Requires-Dist: cryptography>=45.0.4; extra == "dev"
|
|
471
470
|
Provides-Extra: examples
|
|
472
471
|
Requires-Dist: openai>=1.75.0; extra == "examples"
|
|
473
472
|
Provides-Extra: tests
|
|
474
|
-
Requires-Dist: freezegun>=1.5.
|
|
473
|
+
Requires-Dist: freezegun>=1.5.2; extra == "tests"
|
|
475
474
|
Requires-Dist: hdrhistogram>=0.10.3; extra == "tests"
|
|
476
475
|
Requires-Dist: grpcio-testing>=1.71.0; extra == "tests"
|
|
477
476
|
Requires-Dist: psutil>=7.0.0; extra == "tests"
|
|
478
|
-
Requires-Dist: pytest>=8.
|
|
479
|
-
Requires-Dist: pytest-asyncio>=0.
|
|
477
|
+
Requires-Dist: pytest>=8.4.0; extra == "tests"
|
|
478
|
+
Requires-Dist: pytest-asyncio>=1.0.0; extra == "tests"
|
|
480
479
|
Requires-Dist: pytest-cov>=6.1.0; extra == "tests"
|
|
481
480
|
Provides-Extra: taskiq
|
|
482
|
-
Requires-Dist: rstream>=0.
|
|
481
|
+
Requires-Dist: rstream>=0.30.0; extra == "taskiq"
|
|
483
482
|
Requires-Dist: taskiq-aio-pika>=0.4.2; extra == "taskiq"
|
|
484
|
-
Requires-Dist: taskiq-redis>=1.0.
|
|
483
|
+
Requires-Dist: taskiq-redis>=1.0.9; extra == "taskiq"
|
|
484
|
+
Requires-Dist: taskiq[reload]>=0.11.17; extra == "taskiq"
|
|
485
485
|
Dynamic: license-file
|
|
486
486
|
|
|
487
487
|
# DigitalKin Python SDK
|
|
@@ -7,37 +7,37 @@ base_server/mock/__init__.py,sha256=YZFT-F1l_TpvJYuIPX-7kTeE1CfOjhx9YmNRXVoi-jQ,
|
|
|
7
7
|
base_server/mock/mock_pb2.py,sha256=sETakcS3PAAm4E-hTCV1jIVaQTPEAIoVVHupB8Z_k7Y,1843
|
|
8
8
|
base_server/mock/mock_pb2_grpc.py,sha256=BbOT70H6q3laKgkHfOx1QdfmCS_HxCY4wCOX84YAdG4,3180
|
|
9
9
|
digitalkin/__init__.py,sha256=7LLBAba0th-3SGqcpqFO-lopWdUkVLKzLZiMtB-mW3M,162
|
|
10
|
-
digitalkin/__version__.py,sha256=
|
|
10
|
+
digitalkin/__version__.py,sha256=GxhXo6zJ5Xxw-pyzgpQ5JGuE2pD4yvOoWCyz8hiyjwU,191
|
|
11
11
|
digitalkin/logger.py,sha256=cFbIAZHOFx3nddOssRNYLXyqUPzR4CgDR_c-5wmB-og,1685
|
|
12
12
|
digitalkin/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
digitalkin/grpc_servers/__init__.py,sha256=0cJBlwipSmFdXkyH3T0i6OJ1WpAtNsZgYX7JaSnkbtg,804
|
|
14
14
|
digitalkin/grpc_servers/_base_server.py,sha256=NXnnZPjJqUDWoumhEbb7EOEWB7d8XYwpQs-l97NTe4k,18647
|
|
15
15
|
digitalkin/grpc_servers/module_server.py,sha256=tc4n8fu7bcMkwCI3CKkAKR4cZqyP_JTEW0lGtqsc5hs,10283
|
|
16
|
-
digitalkin/grpc_servers/module_servicer.py,sha256=
|
|
16
|
+
digitalkin/grpc_servers/module_servicer.py,sha256=DZ1c_3XAXt-m5I6-CGqmrQ8TAFrYCUQj8R5rqMDKeQc,18383
|
|
17
17
|
digitalkin/grpc_servers/registry_server.py,sha256=StY18DKYoPKQIU1SIzgito6D4_QA1aMVddZ8O2WGlHY,2223
|
|
18
18
|
digitalkin/grpc_servers/registry_servicer.py,sha256=dqsKGHZ0LnaIvGt4ipaAuigd37sbJBndT4MAT029GsY,16471
|
|
19
|
-
digitalkin/grpc_servers/utils/exceptions.py,sha256=
|
|
19
|
+
digitalkin/grpc_servers/utils/exceptions.py,sha256=SyOgvjggaUECYmSiqy8KJLHwHVt5IClSTxslHM-IZzI,931
|
|
20
20
|
digitalkin/grpc_servers/utils/factory.py,sha256=jm6rFjiqmtSv7BIHNAOxsG9xXtSvWpx9TfzSQiX97MQ,5899
|
|
21
21
|
digitalkin/grpc_servers/utils/grpc_client_wrapper.py,sha256=GXRqCTCufwWd8sVMoClnl-JpeBjgmdlSCD0a3YMU9D0,2594
|
|
22
22
|
digitalkin/grpc_servers/utils/models.py,sha256=80F5oHiv8MOqMoDZJBXmJSRoVYJRyhaVcijQ2LinAig,8428
|
|
23
23
|
digitalkin/grpc_servers/utils/types.py,sha256=rQ78s4nAet2jy-NIDj_PUWriT0kuGHr_w6ELjmjgBao,539
|
|
24
24
|
digitalkin/models/__init__.py,sha256=hDHtUfswaNh8wo4NZaBItg9JqC0uNSRqXArNWSrGynY,163
|
|
25
|
-
digitalkin/models/module/__init__.py,sha256=
|
|
25
|
+
digitalkin/models/module/__init__.py,sha256=iQJgq3OVvxoY6gkNCVdVz5bSGgLCy0TMY5H1FFxs-0Q,389
|
|
26
26
|
digitalkin/models/module/module.py,sha256=NWOwCeD_NH0NL89AF_NJ0SwE7G1n-HTcRalodLCDmpM,749
|
|
27
|
-
digitalkin/models/module/module_types.py,sha256=
|
|
27
|
+
digitalkin/models/module/module_types.py,sha256=rlT6prjBN-h1sLKstSwjxWXiyFgtxEn1mjOSLgfI6uA,385
|
|
28
28
|
digitalkin/models/services/__init__.py,sha256=HsW7MUGFPvH7Ri28WN4BHHBfEQk5dzU_9FOWAc-0lSE,56
|
|
29
29
|
digitalkin/models/services/cost.py,sha256=QTEuFD6xz62nob0z4ksE-INJWcZ-iFiuNW5mvXhpFes,1599
|
|
30
30
|
digitalkin/models/services/storage.py,sha256=cYTVIriGKiprF9OerhSxmc_jM6fUTVwmeon1yQCinkE,143
|
|
31
31
|
digitalkin/modules/__init__.py,sha256=ppYARmhvdVi55ofC0QZerIempSlcJYDeCXhcl4qXObw,278
|
|
32
|
-
digitalkin/modules/_base_module.py,sha256=
|
|
33
|
-
digitalkin/modules/archetype_module.py,sha256=
|
|
34
|
-
digitalkin/modules/tool_module.py,sha256=
|
|
35
|
-
digitalkin/modules/trigger_module.py,sha256=
|
|
36
|
-
digitalkin/modules/job_manager/base_job_manager.py,sha256=
|
|
32
|
+
digitalkin/modules/_base_module.py,sha256=wFnGGN97RNu3TJMdgMktOKdYPWmJL9WnwR120bPRXQg,12922
|
|
33
|
+
digitalkin/modules/archetype_module.py,sha256=7rleVOkZfFR7TQeaq6oZXLBuRWixKsUJMOr9HfDV0T8,566
|
|
34
|
+
digitalkin/modules/tool_module.py,sha256=7eWem70dEJiyoCtkGIJP4Ak2G8MzSruOjrByQMqW9-I,508
|
|
35
|
+
digitalkin/modules/trigger_module.py,sha256=FNiJmG3nTG1nDqKC1XdJI8PmFNZNPs1_QrH6RX7ev2Y,475
|
|
36
|
+
digitalkin/modules/job_manager/base_job_manager.py,sha256=Ku_MT7Cuf1R_qJU7SV-yHkzUhhMtmDOa8t5DyetvMxw,6177
|
|
37
37
|
digitalkin/modules/job_manager/job_manager_models.py,sha256=onHy-DfInLZQveniMIWIKwTKSQjojz500JvHB54x93c,1129
|
|
38
|
-
digitalkin/modules/job_manager/single_job_manager.py,sha256=
|
|
39
|
-
digitalkin/modules/job_manager/taskiq_broker.py,sha256=
|
|
40
|
-
digitalkin/modules/job_manager/taskiq_job_manager.py,sha256=
|
|
38
|
+
digitalkin/modules/job_manager/single_job_manager.py,sha256=DkQV3-E9XqgmuC6hoYKolTX2iv9lUJ8BSCde3zk1OU8,10264
|
|
39
|
+
digitalkin/modules/job_manager/taskiq_broker.py,sha256=sMXIgheOBshMiBUWUKph_5rxBHkip4rKusrrxFoa7uY,7379
|
|
40
|
+
digitalkin/modules/job_manager/taskiq_job_manager.py,sha256=evcE3o51DPWzW2y4ri6DFQZNZbFJXyvFb65SibExJH8,10152
|
|
41
41
|
digitalkin/services/__init__.py,sha256=LqGk_5DJy8Bzz62ajIq9jCeYNKQUIgtSCpafZk15FLc,910
|
|
42
42
|
digitalkin/services/base_strategy.py,sha256=QAQnJw1BbqcYMSzwlFyhHP5juBH2WKrZzWxqDr_sDHI,638
|
|
43
43
|
digitalkin/services/services_config.py,sha256=4hc7-rHgSigoS3SuV0V9FReD2Dz7XoMXcD6iMBP2KKM,7391
|
|
@@ -50,9 +50,9 @@ digitalkin/services/cost/cost_strategy.py,sha256=VhHeqi9WnE1yoDBBVp5qmqwIt5tTZHU
|
|
|
50
50
|
digitalkin/services/cost/default_cost.py,sha256=mEd0VL_tMcGU41q0f9MFeBYeKZBenv0mIHuwgXlQ7uQ,3869
|
|
51
51
|
digitalkin/services/cost/grpc_cost.py,sha256=p_5mG72N7e4bxwBOD9DNokvLtinBILiqCfllmkqpmhw,6253
|
|
52
52
|
digitalkin/services/filesystem/__init__.py,sha256=BhwMl_BUvM0d65fmglkp0SVwn3RfYiUOKJgIMnOCaGM,381
|
|
53
|
-
digitalkin/services/filesystem/default_filesystem.py,sha256=
|
|
54
|
-
digitalkin/services/filesystem/filesystem_strategy.py,sha256=
|
|
55
|
-
digitalkin/services/filesystem/grpc_filesystem.py,sha256=
|
|
53
|
+
digitalkin/services/filesystem/default_filesystem.py,sha256=RATQqhdlujaTZNGbYtIstUSVSoahioghdzXFvv1X11Y,14771
|
|
54
|
+
digitalkin/services/filesystem/filesystem_strategy.py,sha256=CJTjCz0eDikeTSFlL_YMwdHpIPxBSO9Yx3fDTgfYSTM,8405
|
|
55
|
+
digitalkin/services/filesystem/grpc_filesystem.py,sha256=9Zw6SUbQNDV7B4rwgU5qG0b1v-2qBFElfLnjnpZ8qhA,12331
|
|
56
56
|
digitalkin/services/identity/__init__.py,sha256=InkeyLgFYYwItx8mePA8HpfacOMWZwwuc0G4pWtKq9s,270
|
|
57
57
|
digitalkin/services/identity/default_identity.py,sha256=Y2auZHrGSZTIN5D8HyjLvLcNbYFM1CNUE23x7p5VIGw,386
|
|
58
58
|
digitalkin/services/identity/identity_strategy.py,sha256=skappBbds1_qa0Gr24FGrNX1N0_OYhYT1Lh7dUaAirE,429
|
|
@@ -61,7 +61,7 @@ digitalkin/services/registry/default_registry.py,sha256=VnWkF6nHpFxUKuUbZLPqzXqd
|
|
|
61
61
|
digitalkin/services/registry/registry_strategy.py,sha256=uBXgZIv25jeXbeVO8vWvlNPxxNYu7_KiCw2PoE6AWr8,423
|
|
62
62
|
digitalkin/services/setup/__init__.py,sha256=t6xcvEWqTbcRZstBFK9cESEqaZKvpW14VtYygxIqfYQ,65
|
|
63
63
|
digitalkin/services/setup/default_setup.py,sha256=9VM3KwsuQcFQQ08RoOHWOE_-9BsRW0YGRtDWYTbQGdA,8246
|
|
64
|
-
digitalkin/services/setup/grpc_setup.py,sha256=
|
|
64
|
+
digitalkin/services/setup/grpc_setup.py,sha256=qjdED3HYZtpgeYYpiIwBWwPgB1NtoAuKmB5unNNRnVQ,12480
|
|
65
65
|
digitalkin/services/setup/setup_strategy.py,sha256=ZnJ_HwWCkHCPrqKekSD5L9y3p8wMwfjQ8sj2hLZq6go,4004
|
|
66
66
|
digitalkin/services/snapshot/__init__.py,sha256=Uzlnzo0CYlSpVsdiI37hW7xQk8hu3YA1fOI6O6MSzB0,270
|
|
67
67
|
digitalkin/services/snapshot/default_snapshot.py,sha256=Mb8QwWRsHh9I_tN0ln_ZiFa1QCZxOVWmuVLemQOTWpc,1058
|
|
@@ -74,13 +74,14 @@ digitalkin/utils/__init__.py,sha256=sJnY-ZUgsjMfojAjONC1VN14mhgIDnzyOlGkw21rRnM,
|
|
|
74
74
|
digitalkin/utils/arg_parser.py,sha256=nvjI1pKDY1HfS0oGcMQPtdTQcggXLtpxXMbnMxNEKRU,3109
|
|
75
75
|
digitalkin/utils/development_mode_action.py,sha256=TqRuAF_A7bDD4twRB4PnZcRoNeaiAnEdxM5kvy4aoaA,1511
|
|
76
76
|
digitalkin/utils/llm_ready_schema.py,sha256=JjMug_lrQllqFoanaC091VgOqwAd-_YzcpqFlS7p778,2375
|
|
77
|
-
digitalkin-0.2.
|
|
77
|
+
digitalkin-0.2.15.dist-info/licenses/LICENSE,sha256=Ies4HFv2r2hzDRakJYxk3Y60uDFLiG-orIgeTpstnIo,20327
|
|
78
78
|
modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
|
-
modules/cpu_intensive_module.py,sha256=
|
|
80
|
-
modules/minimal_llm_module.py,sha256=
|
|
81
|
-
modules/
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
digitalkin-0.2.
|
|
85
|
-
digitalkin-0.2.
|
|
86
|
-
digitalkin-0.2.
|
|
79
|
+
modules/cpu_intensive_module.py,sha256=ejB9XPnFfA0uCuFUQbM3fy5UYfqqAlF36rv_P5Ri8ho,8363
|
|
80
|
+
modules/minimal_llm_module.py,sha256=Ijld__ZnhzfLwpXD1XVkLZ7jyKZKyOFZczOpiPttJZc,11216
|
|
81
|
+
modules/text_transform_module.py,sha256=bwPSnEUthZQyfLwcTLo52iAxItAoknkLh8Y3m5aywaY,7251
|
|
82
|
+
services/filesystem_module.py,sha256=71Mcja8jCQqiqFHPdsIXplFIHTvgkxRhp0TRXuCfgkk,7430
|
|
83
|
+
services/storage_module.py,sha256=ybTMqmvGaTrR8PqJ4FU0cwxaDjT36TskVrGoetTGmno,6955
|
|
84
|
+
digitalkin-0.2.15.dist-info/METADATA,sha256=c9lkB9hRvwrBAGVvaQ-n7EQME-w-qt21ER2lutKgWbg,30580
|
|
85
|
+
digitalkin-0.2.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
86
|
+
digitalkin-0.2.15.dist-info/top_level.txt,sha256=gcjqlyrZuLjIyxrOIavCQM_olpr6ND5kPKkZd2j0xGo,40
|
|
87
|
+
digitalkin-0.2.15.dist-info/RECORD,,
|
modules/cpu_intensive_module.py
CHANGED
|
@@ -127,6 +127,16 @@ class CPUOutput(BaseModel):
|
|
|
127
127
|
)
|
|
128
128
|
|
|
129
129
|
|
|
130
|
+
class CPUConfigSetup(BaseModel):
|
|
131
|
+
"""Config Setup model definining data that will be pre-computed for each setup and module instance."""
|
|
132
|
+
|
|
133
|
+
files: list[str] = Field(
|
|
134
|
+
...,
|
|
135
|
+
title="Files to embed",
|
|
136
|
+
description="List of files to embed in the setup lifecycle.",
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
|
|
130
140
|
class CPUSetup(BaseModel):
|
|
131
141
|
"""Setup model defining module configuration parameters."""
|
|
132
142
|
|
|
@@ -175,7 +185,7 @@ client_config = ClientConfig(
|
|
|
175
185
|
)
|
|
176
186
|
|
|
177
187
|
|
|
178
|
-
class CPUIntensiveModule(BaseModule[CPUInput, CPUOutput, CPUSetup, CPUToolSecret]):
|
|
188
|
+
class CPUIntensiveModule(BaseModule[CPUInput, CPUOutput, CPUSetup, CPUToolSecret, None]):
|
|
179
189
|
"""A CPU endpoint tool module module."""
|
|
180
190
|
|
|
181
191
|
name = "CPUIntensiveModule"
|
|
@@ -202,7 +212,6 @@ class CPUIntensiveModule(BaseModule[CPUInput, CPUOutput, CPUSetup, CPUToolSecret
|
|
|
202
212
|
"client_config": client_config,
|
|
203
213
|
},
|
|
204
214
|
"filesystem": {
|
|
205
|
-
"config": {},
|
|
206
215
|
"client_config": client_config,
|
|
207
216
|
},
|
|
208
217
|
"cost": {
|
modules/minimal_llm_module.py
CHANGED
|
@@ -11,7 +11,6 @@ from pydantic import BaseModel, Field
|
|
|
11
11
|
from digitalkin.grpc_servers.utils.models import ClientConfig, SecurityMode, ServerMode
|
|
12
12
|
from digitalkin.modules._base_module import BaseModule
|
|
13
13
|
from digitalkin.services.services_models import ServicesStrategy
|
|
14
|
-
from digitalkin.services.setup.setup_strategy import SetupData
|
|
15
14
|
|
|
16
15
|
# Configure logging with clear formatting
|
|
17
16
|
logging.basicConfig(
|
|
@@ -154,6 +153,16 @@ class OpenAISetup(BaseModel):
|
|
|
154
153
|
)
|
|
155
154
|
|
|
156
155
|
|
|
156
|
+
class OpenAIConfigSetup(BaseModel):
|
|
157
|
+
"""Setup model defining module configuration parameters."""
|
|
158
|
+
|
|
159
|
+
rag_files: list[bytes] = Field(
|
|
160
|
+
...,
|
|
161
|
+
title="RAG Files",
|
|
162
|
+
description="Files used for retrieval-augmented generation (RAG) with the OpenAI module.",
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
|
|
157
166
|
class OpenAIToolSecret(BaseModel):
|
|
158
167
|
"""Secret model defining module configuration parameters."""
|
|
159
168
|
|
|
@@ -167,13 +176,22 @@ client_config = ClientConfig(
|
|
|
167
176
|
)
|
|
168
177
|
|
|
169
178
|
|
|
170
|
-
class OpenAIToolModule(
|
|
179
|
+
class OpenAIToolModule(
|
|
180
|
+
BaseModule[
|
|
181
|
+
OpenAIInput,
|
|
182
|
+
OpenAIOutput,
|
|
183
|
+
OpenAISetup,
|
|
184
|
+
OpenAIToolSecret,
|
|
185
|
+
OpenAIConfigSetup,
|
|
186
|
+
]
|
|
187
|
+
):
|
|
171
188
|
"""A openAI endpoint tool module module."""
|
|
172
189
|
|
|
173
190
|
name = "OpenAIToolModule"
|
|
174
191
|
description = "A module that interacts with OpenAI API to process text"
|
|
175
192
|
|
|
176
193
|
# Define the schema formats for the module
|
|
194
|
+
config_setup_format = OpenAIConfigSetup
|
|
177
195
|
input_format = OpenAIInput
|
|
178
196
|
output_format = OpenAIOutput
|
|
179
197
|
setup_format = OpenAISetup
|
|
@@ -205,7 +223,27 @@ class OpenAIToolModule(BaseModule[OpenAIInput, OpenAIOutput, OpenAISetup, OpenAI
|
|
|
205
223
|
},
|
|
206
224
|
}
|
|
207
225
|
|
|
208
|
-
async def
|
|
226
|
+
async def run_config_setup(
|
|
227
|
+
self,
|
|
228
|
+
config_setup_data: OpenAIConfigSetup,
|
|
229
|
+
setup_data: OpenAISetup,
|
|
230
|
+
callback: Callable,
|
|
231
|
+
) -> None:
|
|
232
|
+
"""Configure the module with additional setup data.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
config_setup_data: Additional configuration content.
|
|
236
|
+
setup_data: Initial setup data for the module.
|
|
237
|
+
callback: Function to send output data back to the client.
|
|
238
|
+
"""
|
|
239
|
+
logger.info("Configuring OpenAIToolModule with additional setup data. %s", config_setup_data)
|
|
240
|
+
|
|
241
|
+
# Here you can process config_content and update setup_data as needed
|
|
242
|
+
# For now, we just return the original setup_data
|
|
243
|
+
setup_data.developer_prompt = "| + |".join(f.decode("utf-8") for f in config_setup_data.rag_files)
|
|
244
|
+
await callback(setup_data)
|
|
245
|
+
|
|
246
|
+
async def initialize(self, setup_data: OpenAISetup) -> None:
|
|
209
247
|
"""Initialize the module capabilities.
|
|
210
248
|
|
|
211
249
|
This method is called when the module is loaded by the server.
|
modules/text_transform_module.py
CHANGED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"""Example module implementation to test ArchetypeModule functionality."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import datetime
|
|
5
|
+
from collections.abc import Callable
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
from digitalkin.logger import logger
|
|
11
|
+
from digitalkin.models.module import ModuleStatus
|
|
12
|
+
from digitalkin.modules.archetype_module import ArchetypeModule
|
|
13
|
+
from digitalkin.services.services_config import ServicesConfig
|
|
14
|
+
from digitalkin.services.services_models import ServicesMode
|
|
15
|
+
from digitalkin.services.filesystem.filesystem_strategy import FilesystemRecord, FileFilter, UploadFileData
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ExampleInput(BaseModel):
|
|
19
|
+
"""Input model for example module."""
|
|
20
|
+
|
|
21
|
+
message: str = Field(description="Message to process")
|
|
22
|
+
number: int = Field(description="Number to process")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ExampleOutput(BaseModel):
|
|
26
|
+
"""Output model for example module."""
|
|
27
|
+
|
|
28
|
+
processed_message: str = Field(description="The processed message")
|
|
29
|
+
processed_number: int = Field(description="The processed number")
|
|
30
|
+
timestamp: datetime.datetime = Field(description="When the processing was done")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ExampleSetup(BaseModel):
|
|
34
|
+
"""Setup model for example module."""
|
|
35
|
+
|
|
36
|
+
processing_mode: str = Field(description="Mode to process data in", default="default")
|
|
37
|
+
multiply_factor: int = Field(description="Factor to multiply number by", default=1)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ExampleSecret(BaseModel):
|
|
41
|
+
"""Secret model for example module."""
|
|
42
|
+
|
|
43
|
+
api_key: str = Field(description="API key for external service")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ExampleStorage(BaseModel):
|
|
47
|
+
"""Secret model for example module."""
|
|
48
|
+
|
|
49
|
+
test_key: str = Field(description="Test value for storage")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ExampleModule(ArchetypeModule[ExampleInput, ExampleOutput, ExampleSetup, ExampleSecret, None]):
|
|
53
|
+
"""Example module that demonstrates ArchetypeModule functionality."""
|
|
54
|
+
|
|
55
|
+
name = "ExampleModule"
|
|
56
|
+
description = "An example module for testing purposes"
|
|
57
|
+
input_format = ExampleInput
|
|
58
|
+
output_format = ExampleOutput
|
|
59
|
+
setup_format = ExampleSetup
|
|
60
|
+
secret_format = ExampleSecret
|
|
61
|
+
metadata = {"name": "ExampleModule", "description": "A module for testing ArchetypeModule functionality"}
|
|
62
|
+
|
|
63
|
+
# Define services_config_params with default values
|
|
64
|
+
services_config_strategies = {}
|
|
65
|
+
services_config_params = {"cost": {"config": {}}, "storage": {"config": {}}} # Filesystem has no config but it's enabled
|
|
66
|
+
|
|
67
|
+
def __init__(self, job_id: str, mission_id: str, setup_version_id: str) -> None:
|
|
68
|
+
"""Initialize the example module.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
job_id: Unique identifier for the job
|
|
72
|
+
name: Optional name for the module
|
|
73
|
+
"""
|
|
74
|
+
# Initialize services configuration using the class attribute before the instance is created
|
|
75
|
+
self.services_config = ServicesConfig(
|
|
76
|
+
services_config_strategies=self.services_config_strategies,
|
|
77
|
+
services_config_params=self.services_config_params,
|
|
78
|
+
mode=ServicesMode.LOCAL,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
super().__init__(job_id, mission_id, setup_version_id)
|
|
82
|
+
|
|
83
|
+
async def initialize(self, setup_data: ExampleSetup) -> None:
|
|
84
|
+
"""Initialize the module.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
setup_data: Setup data for the module
|
|
88
|
+
"""
|
|
89
|
+
logger.info("Initializing ExampleModule with setup data: %s", setup_data)
|
|
90
|
+
self.setup = self.setup_format.model_validate(setup_data)
|
|
91
|
+
logger.info("Initialization complete, using processing mode: [%s]", self.setup.processing_mode)
|
|
92
|
+
|
|
93
|
+
async def run(
|
|
94
|
+
self,
|
|
95
|
+
input_data: dict[str, Any],
|
|
96
|
+
setup_data: ExampleSetup,
|
|
97
|
+
callback: Callable,
|
|
98
|
+
) -> None:
|
|
99
|
+
"""Run the module.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
input_data: Input data for the module
|
|
103
|
+
setup_data: Setup data for the module
|
|
104
|
+
callback: Callback function to report progress
|
|
105
|
+
"""
|
|
106
|
+
# Validate the input data
|
|
107
|
+
input_model = self.input_format.model_validate(input_data)
|
|
108
|
+
logger.info("Running with input data: %s", input_model)
|
|
109
|
+
|
|
110
|
+
# Process the data
|
|
111
|
+
processed_message = f"Processed: {input_model.message}"
|
|
112
|
+
processed_number = input_model.number * self.setup.multiply_factor
|
|
113
|
+
|
|
114
|
+
# Create output model
|
|
115
|
+
file = UploadFileData(
|
|
116
|
+
content=b"%s\n%s" % (processed_message.encode(), str(processed_number).encode()),
|
|
117
|
+
name="example_output.txt",
|
|
118
|
+
file_type="text/plain",
|
|
119
|
+
content_type="text/plain",
|
|
120
|
+
metadata={"example_key": "example_value"},
|
|
121
|
+
replace_if_exists=True,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
records, uploaded, failed = self.filesystem.upload_files(files=[file])
|
|
125
|
+
for record in records:
|
|
126
|
+
logger.info("Uploaded file: %s, uploaded: %d, failed: %d", record, uploaded, failed)
|
|
127
|
+
logger.info("Stored file with ID: %s", record.id)
|
|
128
|
+
callback(record.model_dump())
|
|
129
|
+
# Call the callback with the output data
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
# Wait a bit to simulate processing time
|
|
133
|
+
await asyncio.sleep(1)
|
|
134
|
+
|
|
135
|
+
async def run_config_setup(
|
|
136
|
+
self,
|
|
137
|
+
setup_data: ExampleSetup,
|
|
138
|
+
) -> None:
|
|
139
|
+
"""Run the configuration setup for the module.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
setup_data: Setup data for the module
|
|
143
|
+
"""
|
|
144
|
+
logger.info("Running config setup with data: %s", setup_data)
|
|
145
|
+
# Here we could implement any additional configuration logic if needed
|
|
146
|
+
|
|
147
|
+
async def cleanup(self) -> None:
|
|
148
|
+
"""Clean up the module."""
|
|
149
|
+
logger.info("Cleaning up ExampleModule")
|
|
150
|
+
# Nothing to clean up in this example
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
async def test_module() -> None:
|
|
154
|
+
"""Test the example module."""
|
|
155
|
+
# Create the module
|
|
156
|
+
module = ExampleModule(job_id="test-job-123", mission_id="test-mission-123", setup_version_id="test-setup-123")
|
|
157
|
+
|
|
158
|
+
# Define input and setup data
|
|
159
|
+
input_data = ExampleInput(message="Hello, world!", number=42)
|
|
160
|
+
|
|
161
|
+
setup_data = ExampleSetup(processing_mode="test", multiply_factor=10)
|
|
162
|
+
|
|
163
|
+
# Define a callback function
|
|
164
|
+
def callback(result) -> None:
|
|
165
|
+
logger.info(f"callback {result}")
|
|
166
|
+
|
|
167
|
+
# Start the module
|
|
168
|
+
await module.start(input_data, setup_data, callback)
|
|
169
|
+
|
|
170
|
+
# Wait for the module to complete
|
|
171
|
+
while module.status not in {ModuleStatus.STOPPED, ModuleStatus.FAILED}:
|
|
172
|
+
await asyncio.sleep(0.5)
|
|
173
|
+
|
|
174
|
+
# Check the storage
|
|
175
|
+
if module.status == ModuleStatus.STOPPED:
|
|
176
|
+
files, nb_results = module.filesystem.get_files(
|
|
177
|
+
filters=FileFilter(name="example_output.txt", context="test-mission-123"),
|
|
178
|
+
)
|
|
179
|
+
for file in files:
|
|
180
|
+
module.filesystem.update_file(file.id, file_type="updated")
|
|
181
|
+
# module.filesystem.delete_files(filters=FileFilter(name="example_output.txt", context="test-mission-123"), permanent=True)
|
|
182
|
+
|
|
183
|
+
logger.info("Retrieved file: %s with ID: %s", file.name, file.id)
|
|
184
|
+
try:
|
|
185
|
+
file_record = module.filesystem.get_file(file_id=file.id, include_content=True)
|
|
186
|
+
if file_record:
|
|
187
|
+
logger.info("File ID: %s", file_record.id)
|
|
188
|
+
logger.info("File name: %s", file_record.name)
|
|
189
|
+
logger.info("File type: %s", file_record.file_type)
|
|
190
|
+
logger.info("File status: %s", file_record.status)
|
|
191
|
+
logger.info("File content: %s", file_record.content.decode())
|
|
192
|
+
except Exception:
|
|
193
|
+
logger.error("No file retrieved")
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
if __name__ == "__main__":
|
|
197
|
+
# Run the module test
|
|
198
|
+
asyncio.run(test_module())
|
|
@@ -51,7 +51,7 @@ class ExampleStorage(BaseModel):
|
|
|
51
51
|
test_key: str = Field(description="Test value for storage")
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
class ExampleModule(ArchetypeModule[ExampleInput, ExampleOutput, ExampleSetup, ExampleSecret]):
|
|
54
|
+
class ExampleModule(ArchetypeModule[ExampleInput, ExampleOutput, ExampleSetup, ExampleSecret, None]):
|
|
55
55
|
"""Example module that demonstrates ArchetypeModule functionality."""
|
|
56
56
|
|
|
57
57
|
name = "ExampleModule"
|
|
@@ -64,14 +64,15 @@ class ExampleModule(ArchetypeModule[ExampleInput, ExampleOutput, ExampleSetup, E
|
|
|
64
64
|
|
|
65
65
|
# Define services_config_params with default values
|
|
66
66
|
services_config_strategies = {}
|
|
67
|
-
services_config_params = {"storage": {"config": {"example": ExampleOutput}},
|
|
67
|
+
services_config_params = {"storage": {"config": {"example": ExampleOutput}},"cost": {"config":{}}}
|
|
68
68
|
|
|
69
|
-
def __init__(self, job_id: str, mission_id: str) -> None:
|
|
69
|
+
def __init__(self, job_id: str, mission_id: str, setup_version_id: str) -> None:
|
|
70
70
|
"""Initialize the example module.
|
|
71
71
|
|
|
72
72
|
Args:
|
|
73
73
|
job_id: Unique identifier for the job
|
|
74
|
-
|
|
74
|
+
mission_id: Unique identifier for the mission
|
|
75
|
+
setup_version_id: Unique identifier for the setup version
|
|
75
76
|
"""
|
|
76
77
|
# Initialize services configuration using the class attribute before the instance is created
|
|
77
78
|
self.services_config = ServicesConfig(
|
|
@@ -80,7 +81,7 @@ class ExampleModule(ArchetypeModule[ExampleInput, ExampleOutput, ExampleSetup, E
|
|
|
80
81
|
mode=ServicesMode.LOCAL,
|
|
81
82
|
)
|
|
82
83
|
|
|
83
|
-
super().__init__(job_id, mission_id)
|
|
84
|
+
super().__init__(job_id, mission_id, setup_version_id)
|
|
84
85
|
|
|
85
86
|
async def initialize(self, setup_data: ExampleSetup) -> None:
|
|
86
87
|
"""Initialize the module.
|
|
@@ -92,6 +93,18 @@ class ExampleModule(ArchetypeModule[ExampleInput, ExampleOutput, ExampleSetup, E
|
|
|
92
93
|
self.setup = self.setup_format.model_validate(setup_data)
|
|
93
94
|
logger.info("Initialization complete, using processing mode: [%s]", self.setup.processing_mode)
|
|
94
95
|
|
|
96
|
+
async def run_config_setup(
|
|
97
|
+
self,
|
|
98
|
+
setup_data: ExampleSetup,
|
|
99
|
+
) -> None:
|
|
100
|
+
"""Run the configuration setup for the module.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
setup_data: Setup data for the module
|
|
104
|
+
"""
|
|
105
|
+
logger.info("Running config setup with data: %s", setup_data)
|
|
106
|
+
# Here we could implement any additional configuration logic if needed
|
|
107
|
+
|
|
95
108
|
async def run(
|
|
96
109
|
self,
|
|
97
110
|
input_data: dict[str, Any],
|
|
@@ -142,7 +155,7 @@ class ExampleModule(ArchetypeModule[ExampleInput, ExampleOutput, ExampleSetup, E
|
|
|
142
155
|
async def test_module() -> None:
|
|
143
156
|
"""Test the example module."""
|
|
144
157
|
# Create the module
|
|
145
|
-
module = ExampleModule(job_id="test-job-123", mission_id="test-mission-123")
|
|
158
|
+
module = ExampleModule(job_id="test-job-123", mission_id="test-mission-123", setup_version_id="test-setup-123")
|
|
146
159
|
|
|
147
160
|
# Define input and setup data
|
|
148
161
|
input_data = ExampleInput(message="Hello, world!", number=42)
|
|
@@ -171,7 +184,7 @@ async def test_module() -> None:
|
|
|
171
184
|
def test_storage_directly() -> None:
|
|
172
185
|
"""Test the storage service directly."""
|
|
173
186
|
# Initialize storage service
|
|
174
|
-
storage = ServicesConfig().storage(mission_id="test-mission", config={"example": ExampleStorage})
|
|
187
|
+
storage = ServicesConfig().storage(mission_id="test-mission",setup_version_id="test-setup-123", config={"example": ExampleStorage})
|
|
175
188
|
|
|
176
189
|
# Create a test record
|
|
177
190
|
storage.store("example", "test_table", {"test_key": "test_value"}, "OUTPUT")
|
|
File without changes
|