digitalkin 0.2.26__py3-none-any.whl → 0.3.0.dev1__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_server.py +27 -44
- digitalkin/grpc_servers/module_servicer.py +27 -22
- digitalkin/grpc_servers/utils/models.py +1 -1
- digitalkin/logger.py +1 -9
- digitalkin/mixins/__init__.py +19 -0
- digitalkin/mixins/base_mixin.py +10 -0
- digitalkin/mixins/callback_mixin.py +24 -0
- digitalkin/mixins/chat_history_mixin.py +108 -0
- digitalkin/mixins/cost_mixin.py +76 -0
- digitalkin/mixins/file_history_mixin.py +99 -0
- digitalkin/mixins/filesystem_mixin.py +47 -0
- digitalkin/mixins/logger_mixin.py +59 -0
- digitalkin/mixins/storage_mixin.py +79 -0
- digitalkin/models/module/__init__.py +2 -0
- digitalkin/models/module/module.py +9 -1
- digitalkin/models/module/module_context.py +90 -6
- digitalkin/models/module/module_types.py +6 -6
- digitalkin/models/module/task_monitor.py +51 -0
- digitalkin/models/services/__init__.py +9 -0
- digitalkin/models/services/storage.py +39 -5
- digitalkin/modules/_base_module.py +47 -68
- digitalkin/modules/job_manager/base_job_manager.py +12 -8
- digitalkin/modules/job_manager/single_job_manager.py +84 -78
- digitalkin/modules/job_manager/surrealdb_repository.py +228 -0
- digitalkin/modules/job_manager/task_manager.py +389 -0
- digitalkin/modules/job_manager/task_session.py +275 -0
- digitalkin/modules/job_manager/taskiq_job_manager.py +2 -2
- digitalkin/modules/tool_module.py +10 -2
- digitalkin/modules/trigger_handler.py +7 -6
- digitalkin/services/cost/__init__.py +9 -2
- digitalkin/services/filesystem/default_filesystem.py +0 -2
- digitalkin/services/storage/grpc_storage.py +1 -1
- {digitalkin-0.2.26.dist-info → digitalkin-0.3.0.dev1.dist-info}/METADATA +20 -19
- {digitalkin-0.2.26.dist-info → digitalkin-0.3.0.dev1.dist-info}/RECORD +38 -25
- {digitalkin-0.2.26.dist-info → digitalkin-0.3.0.dev1.dist-info}/WHEEL +0 -0
- {digitalkin-0.2.26.dist-info → digitalkin-0.3.0.dev1.dist-info}/licenses/LICENSE +0 -0
- {digitalkin-0.2.26.dist-info → digitalkin-0.3.0.dev1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"""."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import datetime
|
|
5
|
+
from collections.abc import AsyncGenerator
|
|
6
|
+
|
|
7
|
+
from digitalkin.logger import logger
|
|
8
|
+
from digitalkin.models.module.task_monitor import HeartbeatMessage, SignalMessage, SignalType, TaskStatus
|
|
9
|
+
from digitalkin.modules._base_module import BaseModule
|
|
10
|
+
from digitalkin.modules.job_manager.surrealdb_repository import SurrealDBConnection
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TaskSession:
|
|
14
|
+
"""Task Session with lifecycle management.
|
|
15
|
+
|
|
16
|
+
The Session defined the whole lifecycle of a task as an epheneral context.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
db: SurrealDBConnection
|
|
20
|
+
module: BaseModule
|
|
21
|
+
|
|
22
|
+
status: TaskStatus
|
|
23
|
+
signal_queue: AsyncGenerator | None
|
|
24
|
+
|
|
25
|
+
task_id: str
|
|
26
|
+
signal_record_id: str | None
|
|
27
|
+
heartbeat_record_id: str | None
|
|
28
|
+
|
|
29
|
+
started_at: datetime.datetime | None
|
|
30
|
+
completed_at: datetime.datetime | None
|
|
31
|
+
|
|
32
|
+
is_cancelled: asyncio.Event
|
|
33
|
+
_paused: asyncio.Event
|
|
34
|
+
_heartbeat_interval: datetime.timedelta
|
|
35
|
+
_last_heartbeat: datetime.datetime
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
task_id: str,
|
|
40
|
+
db: SurrealDBConnection,
|
|
41
|
+
module: BaseModule,
|
|
42
|
+
heartbeat_interval: datetime.timedelta = datetime.timedelta(seconds=2),
|
|
43
|
+
) -> None:
|
|
44
|
+
"""."""
|
|
45
|
+
self.db = db
|
|
46
|
+
self.module = module
|
|
47
|
+
|
|
48
|
+
self.status = TaskStatus.PENDING
|
|
49
|
+
self.queue: asyncio.Queue = asyncio.Queue()
|
|
50
|
+
|
|
51
|
+
self.task_id = task_id
|
|
52
|
+
self.heartbeat = None
|
|
53
|
+
self.started_at = None
|
|
54
|
+
self.completed_at = None
|
|
55
|
+
|
|
56
|
+
self.signal_record_id = None
|
|
57
|
+
self.heartbeat_record_id = None
|
|
58
|
+
|
|
59
|
+
self.is_cancelled = asyncio.Event()
|
|
60
|
+
self._paused = asyncio.Event()
|
|
61
|
+
self._heartbeat_interval = heartbeat_interval
|
|
62
|
+
|
|
63
|
+
logger.info(
|
|
64
|
+
"TaskContext initialized for task: '%s'",
|
|
65
|
+
task_id,
|
|
66
|
+
extra={"task_id": task_id, "heartbeat_interval": heartbeat_interval},
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def cancelled(self) -> bool:
|
|
71
|
+
"""."""
|
|
72
|
+
return self.is_cancelled.is_set()
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def paused(self) -> bool:
|
|
76
|
+
"""."""
|
|
77
|
+
return self._paused.is_set()
|
|
78
|
+
|
|
79
|
+
async def send_heartbeat(self) -> bool:
|
|
80
|
+
"""Rate-limited heartbeat with connection resilience.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
bool: True if heartbeat was successful, False otherwise
|
|
84
|
+
"""
|
|
85
|
+
heartbeat = HeartbeatMessage(
|
|
86
|
+
task_id=self.task_id,
|
|
87
|
+
timestamp=datetime.datetime.now(datetime.timezone.utc),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
if self.heartbeat_record_id is None:
|
|
91
|
+
try:
|
|
92
|
+
success = await self.db.create("heartbeats", heartbeat.model_dump())
|
|
93
|
+
if "code" not in success:
|
|
94
|
+
self.heartbeat_record_id = success.get("id") # type: ignore
|
|
95
|
+
self._last_heartbeat = heartbeat.timestamp
|
|
96
|
+
return True
|
|
97
|
+
except Exception as e:
|
|
98
|
+
logger.error(
|
|
99
|
+
"Heartbeat exception for task: '%s'",
|
|
100
|
+
self.task_id,
|
|
101
|
+
extra={"task_id": self.task_id, "error": str(e)},
|
|
102
|
+
exc_info=True,
|
|
103
|
+
)
|
|
104
|
+
logger.error(
|
|
105
|
+
"Initial heartbeat failed for task: '%s'",
|
|
106
|
+
self.task_id,
|
|
107
|
+
extra={"task_id": self.task_id},
|
|
108
|
+
)
|
|
109
|
+
return False
|
|
110
|
+
|
|
111
|
+
if (heartbeat.timestamp - self._last_heartbeat) < self._heartbeat_interval:
|
|
112
|
+
logger.debug(
|
|
113
|
+
"Heartbeat skipped due to rate limiting for task: '%s' | delta=%s",
|
|
114
|
+
self.task_id,
|
|
115
|
+
heartbeat.timestamp - self._last_heartbeat,
|
|
116
|
+
)
|
|
117
|
+
return True
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
success = await self.db.merge("heartbeats", self.heartbeat_record_id, heartbeat.model_dump())
|
|
121
|
+
if "code" not in success:
|
|
122
|
+
self._last_heartbeat = heartbeat.timestamp
|
|
123
|
+
return True
|
|
124
|
+
except Exception as e:
|
|
125
|
+
logger.error(
|
|
126
|
+
"Heartbeat exception for task: '%s'",
|
|
127
|
+
self.task_id,
|
|
128
|
+
extra={"task_id": self.task_id, "error": str(e)},
|
|
129
|
+
exc_info=True,
|
|
130
|
+
)
|
|
131
|
+
logger.warning(
|
|
132
|
+
"Heartbeat failed for task: '%s'",
|
|
133
|
+
self.task_id,
|
|
134
|
+
extra={"task_id": self.task_id},
|
|
135
|
+
)
|
|
136
|
+
return False
|
|
137
|
+
|
|
138
|
+
async def generate_heartbeats(self) -> None:
|
|
139
|
+
"""Periodic heartbeat generator with cancellation support."""
|
|
140
|
+
logger.debug("Heartbeat started")
|
|
141
|
+
while not self.cancelled:
|
|
142
|
+
logger.debug(f"Heartbeat tick for task: '{self.task_id}' | {self.cancelled=}")
|
|
143
|
+
success = await self.send_heartbeat()
|
|
144
|
+
if not success:
|
|
145
|
+
logger.error("Heartbeat failed, cancelling task: '%s'", self.task_id, extra={"task_id": self.task_id})
|
|
146
|
+
await self._handle_cancel()
|
|
147
|
+
break
|
|
148
|
+
await asyncio.sleep(self._heartbeat_interval.total_seconds())
|
|
149
|
+
|
|
150
|
+
async def wait_if_paused(self) -> None:
|
|
151
|
+
"""Block execution if task is paused."""
|
|
152
|
+
if self._paused.is_set():
|
|
153
|
+
logger.info("Task paused, waiting for resume: '%s'", self.task_id, extra={"task_id": self.task_id})
|
|
154
|
+
await self._paused.wait()
|
|
155
|
+
|
|
156
|
+
async def listen_signals(self) -> None: # noqa: C901
|
|
157
|
+
"""Enhanced signal listener with comprehensive handling.
|
|
158
|
+
|
|
159
|
+
Raises:
|
|
160
|
+
CancelledError: Asyncio when task cancelling
|
|
161
|
+
"""
|
|
162
|
+
logger.info("Signal listener started for task: '%s'", self.task_id, extra={"task_id": self.task_id})
|
|
163
|
+
if self.signal_record_id is None:
|
|
164
|
+
self.signal_record_id = (await self.db.select_by_task_id("tasks", self.task_id)).get("id")
|
|
165
|
+
|
|
166
|
+
live_id, live_signals = await self.db.start_live("tasks")
|
|
167
|
+
try:
|
|
168
|
+
async for signal in live_signals:
|
|
169
|
+
logger.debug("Signal received for task '%s': %s", self.task_id, signal)
|
|
170
|
+
if self.cancelled:
|
|
171
|
+
break
|
|
172
|
+
|
|
173
|
+
if signal is None or signal["id"] == self.signal_record_id or "payload" not in signal:
|
|
174
|
+
continue
|
|
175
|
+
|
|
176
|
+
if signal["action"] == "cancel":
|
|
177
|
+
await self._handle_cancel()
|
|
178
|
+
elif signal["action"] == "pause":
|
|
179
|
+
await self._handle_pause()
|
|
180
|
+
elif signal["action"] == "resume":
|
|
181
|
+
await self._handle_resume()
|
|
182
|
+
elif signal["action"] == "status":
|
|
183
|
+
await self._handle_status_request()
|
|
184
|
+
|
|
185
|
+
except asyncio.CancelledError:
|
|
186
|
+
logger.debug("Signal listener cancelled for task: '%s'", self.task_id, extra={"task_id": self.task_id})
|
|
187
|
+
raise
|
|
188
|
+
except Exception as e:
|
|
189
|
+
logger.error(
|
|
190
|
+
"Signal listener fatal error for task: '%s'",
|
|
191
|
+
self.task_id,
|
|
192
|
+
extra={"task_id": self.task_id, "error": str(e)},
|
|
193
|
+
exc_info=True,
|
|
194
|
+
)
|
|
195
|
+
finally:
|
|
196
|
+
await self.db.stop_live(live_id)
|
|
197
|
+
logger.info("Signal listener stopped for task: '%s'", self.task_id, extra={"task_id": self.task_id})
|
|
198
|
+
|
|
199
|
+
async def _handle_cancel(self) -> None:
|
|
200
|
+
"""Idempotent cancellation with acknowledgment."""
|
|
201
|
+
logger.debug("Handle cancel called")
|
|
202
|
+
if self.is_cancelled.is_set():
|
|
203
|
+
logger.debug(
|
|
204
|
+
"Cancel signal ignored - task already cancelled: '%s'", self.task_id, extra={"task_id": self.task_id}
|
|
205
|
+
)
|
|
206
|
+
return
|
|
207
|
+
|
|
208
|
+
logger.info("Cancelling task: '%s'", self.task_id, extra={"task_id": self.task_id})
|
|
209
|
+
|
|
210
|
+
self.status = TaskStatus.CANCELLED
|
|
211
|
+
self.is_cancelled.set()
|
|
212
|
+
|
|
213
|
+
# Resume if paused so cancellation can proceed
|
|
214
|
+
if self._paused.is_set():
|
|
215
|
+
self._paused.set()
|
|
216
|
+
|
|
217
|
+
await self.db.update(
|
|
218
|
+
"tasks",
|
|
219
|
+
self.signal_record_id, # type: ignore
|
|
220
|
+
SignalMessage(
|
|
221
|
+
task_id=self.task_id,
|
|
222
|
+
action=SignalType.ACK_CANCEL,
|
|
223
|
+
status=self.status,
|
|
224
|
+
).model_dump(),
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
async def _handle_pause(self) -> None:
|
|
228
|
+
"""Pause task execution."""
|
|
229
|
+
if not self._paused.is_set():
|
|
230
|
+
logger.info("Pausing task: '%s'", self.task_id, extra={"task_id": self.task_id})
|
|
231
|
+
self._paused.set()
|
|
232
|
+
|
|
233
|
+
await self.db.update(
|
|
234
|
+
"tasks",
|
|
235
|
+
self.signal_record_id, # type: ignore
|
|
236
|
+
SignalMessage(
|
|
237
|
+
task_id=self.task_id,
|
|
238
|
+
action=SignalType.ACK_PAUSE,
|
|
239
|
+
status=self.status,
|
|
240
|
+
).model_dump(),
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
async def _handle_resume(self) -> None:
|
|
244
|
+
"""Resume paused task."""
|
|
245
|
+
if self._paused.is_set():
|
|
246
|
+
logger.info("Resuming task: '%s'", self.task_id, extra={"task_id": self.task_id})
|
|
247
|
+
self._paused.clear()
|
|
248
|
+
|
|
249
|
+
await self.db.update(
|
|
250
|
+
"tasks",
|
|
251
|
+
self.signal_record_id, # type: ignore
|
|
252
|
+
SignalMessage(
|
|
253
|
+
task_id=self.task_id,
|
|
254
|
+
action=SignalType.ACK_RESUME,
|
|
255
|
+
status=self.status,
|
|
256
|
+
).model_dump(),
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
async def _handle_status_request(self) -> None:
|
|
260
|
+
"""Send current task status."""
|
|
261
|
+
await self.db.update(
|
|
262
|
+
"tasks",
|
|
263
|
+
self.signal_record_id, # type: ignore
|
|
264
|
+
SignalMessage(
|
|
265
|
+
action=SignalType.ACK_STATUS,
|
|
266
|
+
task_id=self.task_id,
|
|
267
|
+
status=self.status,
|
|
268
|
+
).model_dump(),
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
logger.debug(
|
|
272
|
+
"Status report sent for task: '%s'",
|
|
273
|
+
self.task_id,
|
|
274
|
+
extra={"task_id": self.task_id},
|
|
275
|
+
)
|
|
@@ -19,7 +19,7 @@ from rstream import Consumer, ConsumerOffsetSpecification, MessageContext, Offse
|
|
|
19
19
|
|
|
20
20
|
from digitalkin.logger import logger
|
|
21
21
|
from digitalkin.models.module import InputModelT, SetupModelT
|
|
22
|
-
from digitalkin.models.module.
|
|
22
|
+
from digitalkin.models.module.task_monitor import TaskStatus
|
|
23
23
|
from digitalkin.modules._base_module import BaseModule
|
|
24
24
|
from digitalkin.modules.job_manager.base_job_manager import BaseJobManager
|
|
25
25
|
from digitalkin.modules.job_manager.taskiq_broker import STREAM, STREAM_RETENTION, TASKIQ_BROKER
|
|
@@ -279,7 +279,7 @@ class TaskiqJobManager(BaseJobManager, Generic[InputModelT, SetupModelT]):
|
|
|
279
279
|
msg = "stop_all_modules not implemented in TaskiqJobManager"
|
|
280
280
|
raise NotImplementedError(msg)
|
|
281
281
|
|
|
282
|
-
async def get_module_status(self, job_id: str) ->
|
|
282
|
+
async def get_module_status(self, job_id: str) -> TaskStatus:
|
|
283
283
|
"""Query a module status."""
|
|
284
284
|
msg = "get_module_status not implemented in TaskiqJobManager"
|
|
285
285
|
raise NotImplementedError(msg)
|
|
@@ -3,8 +3,16 @@
|
|
|
3
3
|
from abc import ABC
|
|
4
4
|
|
|
5
5
|
from digitalkin.models.module import InputModelT, OutputModelT, SecretModelT, SetupModelT
|
|
6
|
-
from digitalkin.modules._base_module import BaseModule
|
|
6
|
+
from digitalkin.modules._base_module import BaseModule # type: ignore
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class ToolModule(
|
|
9
|
+
class ToolModule(
|
|
10
|
+
BaseModule[
|
|
11
|
+
InputModelT,
|
|
12
|
+
OutputModelT,
|
|
13
|
+
SetupModelT,
|
|
14
|
+
SecretModelT,
|
|
15
|
+
],
|
|
16
|
+
ABC,
|
|
17
|
+
):
|
|
10
18
|
"""ToolModule extends BaseModule to implement specific module types."""
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"""Definition of the Trigger type."""
|
|
2
2
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
|
-
from
|
|
5
|
-
from typing import Any, ClassVar, Generic
|
|
4
|
+
from typing import ClassVar, Generic
|
|
6
5
|
|
|
6
|
+
from digitalkin.mixins import BaseMixin
|
|
7
|
+
from digitalkin.models.module.module_context import ModuleContext
|
|
7
8
|
from digitalkin.models.module.module_types import InputModelT, OutputModelT, SetupModelT
|
|
8
|
-
from digitalkin.modules._base_module import ModuleContext
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class TriggerHandler(ABC, Generic[InputModelT, SetupModelT, OutputModelT]):
|
|
11
|
+
class TriggerHandler(ABC, BaseMixin, Generic[InputModelT, SetupModelT, OutputModelT]):
|
|
12
12
|
"""Base class for all input-trigger handlers.
|
|
13
13
|
|
|
14
14
|
Each handler declares:
|
|
@@ -28,7 +28,6 @@ class TriggerHandler(ABC, Generic[InputModelT, SetupModelT, OutputModelT]):
|
|
|
28
28
|
self,
|
|
29
29
|
input_data: InputModelT,
|
|
30
30
|
setup_data: SetupModelT,
|
|
31
|
-
callback: Callable[[Any], Coroutine[Any, Any, None]],
|
|
32
31
|
context: ModuleContext,
|
|
33
32
|
) -> None:
|
|
34
33
|
"""Asynchronously processes the input data specific to Handler and streams results via the provided callback.
|
|
@@ -36,12 +35,14 @@ class TriggerHandler(ABC, Generic[InputModelT, SetupModelT, OutputModelT]):
|
|
|
36
35
|
Args:
|
|
37
36
|
input_data (InputModelT): The input data to be processed by the handler.
|
|
38
37
|
setup_data (SetupModelT): The setup or configuration data required for processing.
|
|
39
|
-
callback (Callable[[Any], Coroutine[Any, Any, None]]): callback that stream results.
|
|
40
38
|
context (ModuleContext): The context object containing module-specific information and resources.
|
|
41
39
|
|
|
42
40
|
Returns:
|
|
43
41
|
Any: The result of the processing, if applicable.
|
|
44
42
|
|
|
45
43
|
Note:
|
|
44
|
+
self.send_message: : callback used to stream results.
|
|
45
|
+
(Callable[[OutputMdodelT], Coroutine[Any, Any, None]])
|
|
46
|
+
|
|
46
47
|
The callback must be awaited to ensure results are streamed correctly during processing.
|
|
47
48
|
"""
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
"""This module is responsible for handling the cost services."""
|
|
2
2
|
|
|
3
|
-
from digitalkin.services.cost.cost_strategy import CostStrategy
|
|
3
|
+
from digitalkin.services.cost.cost_strategy import CostConfig, CostData, CostStrategy, CostType
|
|
4
4
|
from digitalkin.services.cost.default_cost import DefaultCost
|
|
5
5
|
from digitalkin.services.cost.grpc_cost import GrpcCost
|
|
6
6
|
|
|
7
|
-
__all__ = [
|
|
7
|
+
__all__ = [
|
|
8
|
+
"CostConfig",
|
|
9
|
+
"CostData",
|
|
10
|
+
"CostStrategy",
|
|
11
|
+
"CostType",
|
|
12
|
+
"DefaultCost",
|
|
13
|
+
"GrpcCost",
|
|
14
|
+
]
|
|
@@ -198,8 +198,6 @@ class DefaultFilesystem(FilesystemStrategy):
|
|
|
198
198
|
end_idx = start_idx + list_size
|
|
199
199
|
paginated_files = filtered_files[start_idx:end_idx]
|
|
200
200
|
|
|
201
|
-
logger.critical(f"{filters=} | {paginated_files=}")
|
|
202
|
-
|
|
203
201
|
if include_content:
|
|
204
202
|
for file in paginated_files:
|
|
205
203
|
file.content = Path(file.storage_uri).read_bytes()
|
|
@@ -128,7 +128,7 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
128
128
|
resp = self.exec_grpc_query("UpdateRecord", req)
|
|
129
129
|
return self._build_record_from_proto(resp.stored_data)
|
|
130
130
|
except Exception:
|
|
131
|
-
logger.
|
|
131
|
+
logger.warning("gRPC UpdateRecord failed for %s:%s", collection, record_id)
|
|
132
132
|
return None
|
|
133
133
|
|
|
134
134
|
def _remove(self, collection: str, record_id: str) -> bool:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: digitalkin
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0.dev1
|
|
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
|
|
@@ -456,32 +456,33 @@ 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
|
-
Requires-Dist: pydantic>=2.
|
|
459
|
+
Requires-Dist: pydantic>=2.12.1
|
|
460
|
+
Requires-Dist: surrealdb>=1.0.6
|
|
461
|
+
Provides-Extra: taskiq
|
|
462
|
+
Requires-Dist: rstream>=0.31.0; extra == "taskiq"
|
|
463
|
+
Requires-Dist: taskiq-aio-pika>=0.4.3; extra == "taskiq"
|
|
464
|
+
Requires-Dist: taskiq-redis>=1.1.2; extra == "taskiq"
|
|
465
|
+
Requires-Dist: taskiq[reload]>=0.11.18; extra == "taskiq"
|
|
460
466
|
Provides-Extra: dev
|
|
461
|
-
Requires-Dist: typos>=1.
|
|
462
|
-
Requires-Dist: ruff>=0.
|
|
463
|
-
Requires-Dist: mypy>=1.
|
|
464
|
-
Requires-Dist: pyright>=1.1.
|
|
467
|
+
Requires-Dist: typos>=1.38.0; extra == "dev"
|
|
468
|
+
Requires-Dist: ruff>=0.13.3; extra == "dev"
|
|
469
|
+
Requires-Dist: mypy>=1.18.2; extra == "dev"
|
|
470
|
+
Requires-Dist: pyright>=1.1.406; extra == "dev"
|
|
465
471
|
Requires-Dist: pre-commit>=4.3.0; extra == "dev"
|
|
466
|
-
Requires-Dist:
|
|
472
|
+
Requires-Dist: bump-my-version>=1.2.4; extra == "dev"
|
|
467
473
|
Requires-Dist: build>=1.3.0; extra == "dev"
|
|
468
|
-
Requires-Dist: twine>=6.
|
|
469
|
-
Requires-Dist: cryptography>=
|
|
470
|
-
Provides-Extra: examples
|
|
471
|
-
Requires-Dist: openai>=1.75.0; extra == "examples"
|
|
474
|
+
Requires-Dist: twine>=6.2.0; extra == "dev"
|
|
475
|
+
Requires-Dist: cryptography>=46.0.2; extra == "dev"
|
|
472
476
|
Provides-Extra: tests
|
|
473
477
|
Requires-Dist: freezegun>=1.5.3; extra == "tests"
|
|
474
478
|
Requires-Dist: hdrhistogram>=0.10.3; extra == "tests"
|
|
475
479
|
Requires-Dist: grpcio-testing>=1.71.0; extra == "tests"
|
|
476
480
|
Requires-Dist: psutil>=7.0.0; extra == "tests"
|
|
477
|
-
Requires-Dist: pytest>=8.4.
|
|
478
|
-
Requires-Dist: pytest-asyncio>=1.
|
|
479
|
-
Requires-Dist: pytest-cov>=
|
|
480
|
-
|
|
481
|
-
Requires-Dist:
|
|
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"
|
|
481
|
+
Requires-Dist: pytest>=8.4.2; extra == "tests"
|
|
482
|
+
Requires-Dist: pytest-asyncio>=1.2.0; extra == "tests"
|
|
483
|
+
Requires-Dist: pytest-cov>=7.0.0; extra == "tests"
|
|
484
|
+
Requires-Dist: pytest-html==4.1.1; extra == "tests"
|
|
485
|
+
Requires-Dist: pytest-json-report==1.5.0; extra == "tests"
|
|
485
486
|
Dynamic: license-file
|
|
486
487
|
|
|
487
488
|
# DigitalKin Python SDK
|
|
@@ -7,38 +7,51 @@ 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=
|
|
11
|
-
digitalkin/logger.py,sha256=
|
|
10
|
+
digitalkin/__version__.py,sha256=TouYEd0hGF2qSimjErQ5O3uouXtxL5suh2P6BxRWN2c,195
|
|
11
|
+
digitalkin/logger.py,sha256=8ze_tjt2G6mDTuQcsf7-UTXWP3UHZ7LZVSs_iqF4rX4,4685
|
|
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=32yrMCFAFE7FmdDL1WbuUlDuxRkaUJ_P7Dc-3_b40qs,18678
|
|
15
|
-
digitalkin/grpc_servers/module_server.py,sha256=
|
|
16
|
-
digitalkin/grpc_servers/module_servicer.py,sha256=
|
|
15
|
+
digitalkin/grpc_servers/module_server.py,sha256=bi1XreL5zaPxbaDfsFN7-qtEbo0sKFNeyyLJjWdYMck,10212
|
|
16
|
+
digitalkin/grpc_servers/module_servicer.py,sha256=Df2mQYrGngGYHC6fPV3Othc5hCR2g8IuLxJx9IhzDAc,19345
|
|
17
17
|
digitalkin/grpc_servers/registry_server.py,sha256=StY18DKYoPKQIU1SIzgito6D4_QA1aMVddZ8O2WGlHY,2223
|
|
18
18
|
digitalkin/grpc_servers/registry_servicer.py,sha256=dqsKGHZ0LnaIvGt4ipaAuigd37sbJBndT4MAT029GsY,16471
|
|
19
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=Vtt05KdePSFHq8FZUJ-bJo8l_d5vu7gdOv5UBtsgScg,2752
|
|
22
|
-
digitalkin/grpc_servers/utils/models.py,sha256=
|
|
22
|
+
digitalkin/grpc_servers/utils/models.py,sha256=ZQ1Gk4zmLRX_ueuwFOwXgtyG9OEPSzFa_91I_CXZmZ0,8957
|
|
23
23
|
digitalkin/grpc_servers/utils/types.py,sha256=rQ78s4nAet2jy-NIDj_PUWriT0kuGHr_w6ELjmjgBao,539
|
|
24
|
+
digitalkin/mixins/__init__.py,sha256=d6ljaoyJZJT9XxOrXZG5FVNvbLURb3_CZrkp4GPZWYM,590
|
|
25
|
+
digitalkin/mixins/base_mixin.py,sha256=uLkg6MbDtVc9DysjdfNIGKahxQLnnjuL3DYpuyNLbk8,486
|
|
26
|
+
digitalkin/mixins/callback_mixin.py,sha256=90nHm9-pbKT14GAy3CB3fsBtpYu5IH0woOQdNLM2e_Y,836
|
|
27
|
+
digitalkin/mixins/chat_history_mixin.py,sha256=cGLJb1KWY1WgC5akV6WQfk2a0blN-RQmU5TDs_ppUGM,4111
|
|
28
|
+
digitalkin/mixins/cost_mixin.py,sha256=nFqhLsRHdXAt3GOH6qI8sqX9KW3leTPW3gaclensBVw,2274
|
|
29
|
+
digitalkin/mixins/file_history_mixin.py,sha256=4rDpm-TVcD9ihZGPuqr73y1_4FnUzBlWUSoje-pQIIU,3759
|
|
30
|
+
digitalkin/mixins/filesystem_mixin.py,sha256=myCUmocdumG7XSN1acnn4hw1e1QbkngbnBtQtrVZQHU,1604
|
|
31
|
+
digitalkin/mixins/logger_mixin.py,sha256=FdVIlPXOQ7eo8DUlMmsygO9L8bis-Jhj_zw83RiE6wo,2150
|
|
32
|
+
digitalkin/mixins/storage_mixin.py,sha256=ptZ4a2bydIa48q0V9e395vWHTu7yw4A6rI4jwKY6gwI,2392
|
|
24
33
|
digitalkin/models/__init__.py,sha256=hDHtUfswaNh8wo4NZaBItg9JqC0uNSRqXArNWSrGynY,163
|
|
25
|
-
digitalkin/models/module/__init__.py,sha256=
|
|
26
|
-
digitalkin/models/module/module.py,sha256=
|
|
27
|
-
digitalkin/models/module/module_context.py,sha256=
|
|
28
|
-
digitalkin/models/module/module_types.py,sha256=
|
|
29
|
-
digitalkin/models/
|
|
34
|
+
digitalkin/models/module/__init__.py,sha256=nFPHp0JcAZq9ISkcSu1y2zeNyXH3V4j10oMjHzMBYBU,599
|
|
35
|
+
digitalkin/models/module/module.py,sha256=k0W8vfJJFth8XdDzkHm32SyTuSf3h2qF0hSrxAfGF1s,956
|
|
36
|
+
digitalkin/models/module/module_context.py,sha256=nhZ_Pw9lWcq5B2PPy-Rf3N0S7MXz9Ehh5Nb-4tEOmmM,3764
|
|
37
|
+
digitalkin/models/module/module_types.py,sha256=kkOst1OWeQVzLdf0P8JBlZqf2LLWj14-bQHyYvwUN8Y,3562
|
|
38
|
+
digitalkin/models/module/task_monitor.py,sha256=sEzpfmTg1cXC1ieD72YL3zwkSE6D5CIHWRi2CgK3GeQ,1288
|
|
39
|
+
digitalkin/models/services/__init__.py,sha256=jhfVw6egq0OcHmos_fypH9XFehbHTBw09wluVFVFEyw,226
|
|
30
40
|
digitalkin/models/services/cost.py,sha256=QTEuFD6xz62nob0z4ksE-INJWcZ-iFiuNW5mvXhpFes,1599
|
|
31
|
-
digitalkin/models/services/storage.py,sha256=
|
|
41
|
+
digitalkin/models/services/storage.py,sha256=k0lQUfTY9qP-PPxC1piuOhw-DfH7ao-yNvykRDJWdko,1145
|
|
32
42
|
digitalkin/modules/__init__.py,sha256=VwVbKok81NGyPIBZgEj_SR-59G8tTlSb4eBJI9W6Vx4,281
|
|
33
|
-
digitalkin/modules/_base_module.py,sha256=
|
|
43
|
+
digitalkin/modules/_base_module.py,sha256=y_Pw2twqlAcsJlUUa-8QKdITSrZv6KpiwVw2X7mNads,18392
|
|
34
44
|
digitalkin/modules/archetype_module.py,sha256=lOe3yYufwfylZR_VGy1w-zqdqVaMI_JANfKkbH9eODE,471
|
|
35
|
-
digitalkin/modules/tool_module.py,sha256=
|
|
36
|
-
digitalkin/modules/trigger_handler.py,sha256=
|
|
37
|
-
digitalkin/modules/job_manager/base_job_manager.py,sha256=
|
|
45
|
+
digitalkin/modules/tool_module.py,sha256=rLJfdYMWddiUgPLBDGG_UcHnRCHEeaqX6Fdp4DOUaCs,472
|
|
46
|
+
digitalkin/modules/trigger_handler.py,sha256=qPNMi-8NHqscOxciHeaXtpwjXApT3YzjMF23zQAjaZY,1770
|
|
47
|
+
digitalkin/modules/job_manager/base_job_manager.py,sha256=iDv9caispLmM7mqPgG_g7oaACMvNW7i7MTzBeSlmNp0,6355
|
|
38
48
|
digitalkin/modules/job_manager/job_manager_models.py,sha256=onHy-DfInLZQveniMIWIKwTKSQjojz500JvHB54x93c,1129
|
|
39
|
-
digitalkin/modules/job_manager/single_job_manager.py,sha256=
|
|
49
|
+
digitalkin/modules/job_manager/single_job_manager.py,sha256=rJ6ppgXQkLu2X4NF2oicWf3rutYN4Qtfey3EM7ONfKM,11155
|
|
50
|
+
digitalkin/modules/job_manager/surrealdb_repository.py,sha256=qGDDEEV80vKVUe4r2yvTqTNfKrQoiZjeFok01rn_eaE,7798
|
|
51
|
+
digitalkin/modules/job_manager/task_manager.py,sha256=Z_luiGdHg6jnNSslf9Dl8m9w6PIBtgrOHZXfyikBVwY,14336
|
|
52
|
+
digitalkin/modules/job_manager/task_session.py,sha256=KpBoOH2ND7UQauRok7pGsNfybH-rQDIwvdtg07ZFz40,9573
|
|
40
53
|
digitalkin/modules/job_manager/taskiq_broker.py,sha256=4q3U03SNlb1ypup0VOa73KHLKJ9peuZUPCR5eFLMNAk,7498
|
|
41
|
-
digitalkin/modules/job_manager/taskiq_job_manager.py,sha256=
|
|
54
|
+
digitalkin/modules/job_manager/taskiq_job_manager.py,sha256=NHSGsqqKCWQQqx0FqM3c4tf011vFlqX1npHkcv0kEOU,10249
|
|
42
55
|
digitalkin/services/__init__.py,sha256=LqGk_5DJy8Bzz62ajIq9jCeYNKQUIgtSCpafZk15FLc,910
|
|
43
56
|
digitalkin/services/base_strategy.py,sha256=yA9KUJGRKuuaxA6l3GcMv8zKfWoIsW03UxJT80Yea2I,766
|
|
44
57
|
digitalkin/services/services_config.py,sha256=JnyzZcG7OYBelwgn-wdVgY2n3yFTEkwLPHRZB8Tjw10,7468
|
|
@@ -46,12 +59,12 @@ digitalkin/services/services_models.py,sha256=5zXkWcfKnXGwQi9sN4OAL3XrgqOcmsTl8a
|
|
|
46
59
|
digitalkin/services/agent/__init__.py,sha256=vJc8JN0pdtA8ecypLBeHrwAUIW6H2C8NyW-dk24rTpk,244
|
|
47
60
|
digitalkin/services/agent/agent_strategy.py,sha256=42Q9RciHX6tg3CgDQkbrlIx4h_TX0WIuSpLmCjitVmA,492
|
|
48
61
|
digitalkin/services/agent/default_agent.py,sha256=4N_E_eQxJGOx1KVUUg5jNOje-3ncMxF3ePB-uDuGrJc,345
|
|
49
|
-
digitalkin/services/cost/__init__.py,sha256=
|
|
62
|
+
digitalkin/services/cost/__init__.py,sha256=sD_a5LrnLluASOC5m5vgIqjaco-MzZJd6XhillIBHr0,400
|
|
50
63
|
digitalkin/services/cost/cost_strategy.py,sha256=MpPX33P_S5b2by6F4zT-rcyeRuh2V4NYPZe05VpDOGQ,2649
|
|
51
64
|
digitalkin/services/cost/default_cost.py,sha256=XE7kNFde8NmbulU9m1lc3mi-vHFkbaJf0XHUc0D4UHE,3945
|
|
52
65
|
digitalkin/services/cost/grpc_cost.py,sha256=cGtb0atPXSEEOrNIWee-o3ScfNRSAFXJGDu0vcWT6zg,6295
|
|
53
66
|
digitalkin/services/filesystem/__init__.py,sha256=BhwMl_BUvM0d65fmglkp0SVwn3RfYiUOKJgIMnOCaGM,381
|
|
54
|
-
digitalkin/services/filesystem/default_filesystem.py,sha256=
|
|
67
|
+
digitalkin/services/filesystem/default_filesystem.py,sha256=WQbU-Bsi9r-28VqhKbrplce3otzjSKS-5iqKEpGWdQU,15117
|
|
55
68
|
digitalkin/services/filesystem/filesystem_strategy.py,sha256=zibVLvX_IBQ-kgh-KYzHdszDeiHFPEAZszu_k99x1GQ,9487
|
|
56
69
|
digitalkin/services/filesystem/grpc_filesystem.py,sha256=ilxTFjelmf8_bVSs3xLlsyWFHVlSJf27c4j8H7R1Rkw,12987
|
|
57
70
|
digitalkin/services/identity/__init__.py,sha256=InkeyLgFYYwItx8mePA8HpfacOMWZwwuc0G4pWtKq9s,270
|
|
@@ -69,21 +82,21 @@ digitalkin/services/snapshot/default_snapshot.py,sha256=Mb8QwWRsHh9I_tN0ln_ZiFa1
|
|
|
69
82
|
digitalkin/services/snapshot/snapshot_strategy.py,sha256=B1TU3V_k9A-OdqBkdyc41-ihnrW5Btcwd1KyQdHT46A,898
|
|
70
83
|
digitalkin/services/storage/__init__.py,sha256=T-ocYLLphudkQgzvG47jBOm5GQsRFRIGA88y7Ur4akg,341
|
|
71
84
|
digitalkin/services/storage/default_storage.py,sha256=D8e-UYUkb2GvDEHMWcN3EkcIKXWA8DrsaQsXVjoXAYQ,7975
|
|
72
|
-
digitalkin/services/storage/grpc_storage.py,sha256=
|
|
85
|
+
digitalkin/services/storage/grpc_storage.py,sha256=7RPeqkjG4JdW1lhjGpKx1qF5fp_LE-sST7fp5oT6uD0,7204
|
|
73
86
|
digitalkin/services/storage/storage_strategy.py,sha256=sERF5tIJnzpb1iNqTXic9xRkGaXMifo6kb709ubB-Yo,8848
|
|
74
87
|
digitalkin/utils/__init__.py,sha256=sJnY-ZUgsjMfojAjONC1VN14mhgIDnzyOlGkw21rRnM,28
|
|
75
88
|
digitalkin/utils/arg_parser.py,sha256=nvjI1pKDY1HfS0oGcMQPtdTQcggXLtpxXMbnMxNEKRU,3109
|
|
76
89
|
digitalkin/utils/development_mode_action.py,sha256=TqRuAF_A7bDD4twRB4PnZcRoNeaiAnEdxM5kvy4aoaA,1511
|
|
77
90
|
digitalkin/utils/llm_ready_schema.py,sha256=JjMug_lrQllqFoanaC091VgOqwAd-_YzcpqFlS7p778,2375
|
|
78
91
|
digitalkin/utils/package_discover.py,sha256=3e9-6Vf3yAAv2VkHHVK4QVqHJBxQqg3d8uuDTsXph24,13471
|
|
79
|
-
digitalkin-0.
|
|
92
|
+
digitalkin-0.3.0.dev1.dist-info/licenses/LICENSE,sha256=Ies4HFv2r2hzDRakJYxk3Y60uDFLiG-orIgeTpstnIo,20327
|
|
80
93
|
modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
81
94
|
modules/cpu_intensive_module.py,sha256=ejB9XPnFfA0uCuFUQbM3fy5UYfqqAlF36rv_P5Ri8ho,8363
|
|
82
95
|
modules/minimal_llm_module.py,sha256=Ijld__ZnhzfLwpXD1XVkLZ7jyKZKyOFZczOpiPttJZc,11216
|
|
83
96
|
modules/text_transform_module.py,sha256=bwPSnEUthZQyfLwcTLo52iAxItAoknkLh8Y3m5aywaY,7251
|
|
84
97
|
services/filesystem_module.py,sha256=71Mcja8jCQqiqFHPdsIXplFIHTvgkxRhp0TRXuCfgkk,7430
|
|
85
98
|
services/storage_module.py,sha256=ybTMqmvGaTrR8PqJ4FU0cwxaDjT36TskVrGoetTGmno,6955
|
|
86
|
-
digitalkin-0.
|
|
87
|
-
digitalkin-0.
|
|
88
|
-
digitalkin-0.
|
|
89
|
-
digitalkin-0.
|
|
99
|
+
digitalkin-0.3.0.dev1.dist-info/METADATA,sha256=1slDz-MhzogLJEErQ7zxlqIo5IneECx-NxLzGOJdXUg,30653
|
|
100
|
+
digitalkin-0.3.0.dev1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
101
|
+
digitalkin-0.3.0.dev1.dist-info/top_level.txt,sha256=gcjqlyrZuLjIyxrOIavCQM_olpr6ND5kPKkZd2j0xGo,40
|
|
102
|
+
digitalkin-0.3.0.dev1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|