digitalkin 0.3.2.dev2__py3-none-any.whl → 0.3.2.dev4__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/core/job_manager/single_job_manager.py +28 -9
- digitalkin/core/task_manager/task_session.py +60 -98
- digitalkin/grpc_servers/module_servicer.py +40 -7
- digitalkin/models/core/task_monitor.py +4 -0
- digitalkin/models/module/__init__.py +10 -2
- digitalkin/models/module/base_types.py +61 -0
- digitalkin/models/module/module_context.py +38 -1
- digitalkin/models/module/module_types.py +28 -392
- digitalkin/models/module/setup_types.py +573 -0
- digitalkin/models/module/tool_cache.py +230 -0
- digitalkin/models/module/tool_reference.py +120 -0
- digitalkin/models/module/utility.py +22 -1
- digitalkin/modules/_base_module.py +34 -3
- digitalkin/modules/triggers/__init__.py +0 -4
- digitalkin/services/user_profile/user_profile_strategy.py +0 -15
- {digitalkin-0.3.2.dev2.dist-info → digitalkin-0.3.2.dev4.dist-info}/METADATA +1 -1
- {digitalkin-0.3.2.dev2.dist-info → digitalkin-0.3.2.dev4.dist-info}/RECORD +21 -17
- {digitalkin-0.3.2.dev2.dist-info → digitalkin-0.3.2.dev4.dist-info}/WHEEL +0 -0
- {digitalkin-0.3.2.dev2.dist-info → digitalkin-0.3.2.dev4.dist-info}/licenses/LICENSE +0 -0
- {digitalkin-0.3.2.dev2.dist-info → digitalkin-0.3.2.dev4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"""Tool cache for managing resolved tool references.
|
|
2
|
+
|
|
3
|
+
The ToolCache is a registry that stores resolved ModuleInfo by slug.
|
|
4
|
+
It is populated during run_config_setup and validated during initialize.
|
|
5
|
+
LLMs check the cache before calling the registry for tool discovery.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
from pydantic import BaseModel, Field
|
|
13
|
+
|
|
14
|
+
from digitalkin.logger import logger
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from digitalkin.models.services.registry import ModuleInfo
|
|
18
|
+
from digitalkin.services.registry import RegistryStrategy
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ToolCacheEntry(BaseModel):
|
|
22
|
+
"""Single entry in the tool cache."""
|
|
23
|
+
|
|
24
|
+
slug: str = Field(description="Unique identifier/slug for this tool")
|
|
25
|
+
module_id: str = Field(description="Resolved module ID")
|
|
26
|
+
module_info: ModuleInfo = Field(description="Full module information")
|
|
27
|
+
is_valid: bool = Field(default=True, description="Whether this entry is still valid")
|
|
28
|
+
|
|
29
|
+
model_config = {"arbitrary_types_allowed": True}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ToolCache(BaseModel):
|
|
33
|
+
"""Registry cache for resolved tools.
|
|
34
|
+
|
|
35
|
+
Stores tool references by slug during run_config_setup and provides
|
|
36
|
+
lookup methods for LLMs during execution. Tools must be checked
|
|
37
|
+
against the cache before calling the registry.
|
|
38
|
+
|
|
39
|
+
Flow:
|
|
40
|
+
1. run_config_setup: Registry called, results cached by slug
|
|
41
|
+
2. initialize: Cache validated (tools still available)
|
|
42
|
+
3. Runtime: LLM checks cache first, then registry if not found
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
entries: dict[str, ToolCacheEntry] = Field(default_factory=dict)
|
|
46
|
+
|
|
47
|
+
def add(self, slug: str, module_info: ModuleInfo) -> None:
|
|
48
|
+
"""Add a tool to the cache.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
slug: Unique identifier for this tool.
|
|
52
|
+
module_info: Resolved module information.
|
|
53
|
+
"""
|
|
54
|
+
self.entries[slug] = ToolCacheEntry(
|
|
55
|
+
slug=slug,
|
|
56
|
+
module_id=module_info.module_id,
|
|
57
|
+
module_info=module_info,
|
|
58
|
+
is_valid=True,
|
|
59
|
+
)
|
|
60
|
+
logger.debug("Tool cached", extra={"slug": slug, "module_id": module_info.module_id})
|
|
61
|
+
|
|
62
|
+
def get(self, slug: str) -> ModuleInfo | None:
|
|
63
|
+
"""Get a tool from the cache by slug.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
slug: The tool slug to look up.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
ModuleInfo if found and valid, None otherwise.
|
|
70
|
+
"""
|
|
71
|
+
entry = self.entries.get(slug)
|
|
72
|
+
if entry and entry.is_valid:
|
|
73
|
+
return entry.module_info
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
def contains(self, slug: str) -> bool:
|
|
77
|
+
"""Check if a tool exists in the cache.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
slug: The tool slug to check.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
True if tool exists and is valid.
|
|
84
|
+
"""
|
|
85
|
+
entry = self.entries.get(slug)
|
|
86
|
+
return entry is not None and entry.is_valid
|
|
87
|
+
|
|
88
|
+
def invalidate(self, slug: str) -> None:
|
|
89
|
+
"""Mark a tool as invalid.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
slug: The tool slug to invalidate.
|
|
93
|
+
"""
|
|
94
|
+
if slug in self.entries:
|
|
95
|
+
self.entries[slug].is_valid = False
|
|
96
|
+
logger.debug("Tool invalidated", extra={"slug": slug})
|
|
97
|
+
|
|
98
|
+
def remove(self, slug: str) -> None:
|
|
99
|
+
"""Remove a tool from the cache.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
slug: The tool slug to remove.
|
|
103
|
+
"""
|
|
104
|
+
if slug in self.entries:
|
|
105
|
+
del self.entries[slug]
|
|
106
|
+
logger.debug("Tool removed from cache", extra={"slug": slug})
|
|
107
|
+
|
|
108
|
+
def clear(self) -> None:
|
|
109
|
+
"""Clear all entries from the cache."""
|
|
110
|
+
self.entries.clear()
|
|
111
|
+
|
|
112
|
+
def check_and_get(
|
|
113
|
+
self,
|
|
114
|
+
slug: str,
|
|
115
|
+
registry: RegistryStrategy | None = None,
|
|
116
|
+
) -> ModuleInfo | None:
|
|
117
|
+
"""Check cache first, then optionally query registry.
|
|
118
|
+
|
|
119
|
+
This is the primary method for LLMs to discover tools. It:
|
|
120
|
+
1. Checks if the tool is in cache (fast path)
|
|
121
|
+
2. If not in cache and registry provided, queries registry
|
|
122
|
+
3. If found via registry, caches the result
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
slug: The tool slug to look up.
|
|
126
|
+
registry: Optional registry to query if not in cache.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
ModuleInfo if found, None otherwise.
|
|
130
|
+
"""
|
|
131
|
+
# Fast path: check cache
|
|
132
|
+
cached = self.get(slug)
|
|
133
|
+
if cached:
|
|
134
|
+
logger.debug("Tool cache hit", extra={"slug": slug})
|
|
135
|
+
return cached
|
|
136
|
+
|
|
137
|
+
# Not in cache - try registry if available
|
|
138
|
+
if registry:
|
|
139
|
+
logger.debug("Tool cache miss, querying registry", extra={"slug": slug})
|
|
140
|
+
try:
|
|
141
|
+
# Try by ID first (slug might be module_id)
|
|
142
|
+
info = registry.discover_by_id(slug)
|
|
143
|
+
if info:
|
|
144
|
+
self.add(slug, info)
|
|
145
|
+
return info
|
|
146
|
+
|
|
147
|
+
# Try by tag search
|
|
148
|
+
results = registry.search(name=slug, module_type="tool", organization_id=None)
|
|
149
|
+
if results:
|
|
150
|
+
info = results[0]
|
|
151
|
+
self.add(slug, info)
|
|
152
|
+
return info
|
|
153
|
+
except Exception:
|
|
154
|
+
logger.exception("Registry lookup failed", extra={"slug": slug})
|
|
155
|
+
|
|
156
|
+
return None
|
|
157
|
+
|
|
158
|
+
def validate(self, registry: RegistryStrategy) -> list[str]:
|
|
159
|
+
"""Validate all cached tools are still available.
|
|
160
|
+
|
|
161
|
+
Checks each cached tool against the registry and marks
|
|
162
|
+
invalid entries. Returns list of invalid slugs.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
registry: Registry to validate against.
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
List of slugs that are no longer valid.
|
|
169
|
+
"""
|
|
170
|
+
invalid: list[str] = []
|
|
171
|
+
for slug, entry in self.entries.items():
|
|
172
|
+
if not entry.is_valid:
|
|
173
|
+
continue
|
|
174
|
+
try:
|
|
175
|
+
info = registry.discover_by_id(entry.module_id)
|
|
176
|
+
if not info:
|
|
177
|
+
entry.is_valid = False
|
|
178
|
+
invalid.append(slug)
|
|
179
|
+
logger.warning("Tool no longer available", extra={"slug": slug, "module_id": entry.module_id})
|
|
180
|
+
except Exception:
|
|
181
|
+
entry.is_valid = False
|
|
182
|
+
invalid.append(slug)
|
|
183
|
+
logger.exception("Tool validation failed", extra={"slug": slug})
|
|
184
|
+
return invalid
|
|
185
|
+
|
|
186
|
+
def list_slugs(self) -> list[str]:
|
|
187
|
+
"""Get list of all valid tool slugs.
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
List of valid tool slugs.
|
|
191
|
+
"""
|
|
192
|
+
return [slug for slug, entry in self.entries.items() if entry.is_valid]
|
|
193
|
+
|
|
194
|
+
def to_dict(self) -> dict[str, dict]:
|
|
195
|
+
"""Serialize cache to dict for storage.
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
Dict representation of cache entries.
|
|
199
|
+
"""
|
|
200
|
+
return {
|
|
201
|
+
slug: {
|
|
202
|
+
"slug": entry.slug,
|
|
203
|
+
"module_id": entry.module_id,
|
|
204
|
+
"is_valid": entry.is_valid,
|
|
205
|
+
"module_info": entry.module_info.model_dump(),
|
|
206
|
+
}
|
|
207
|
+
for slug, entry in self.entries.items()
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
@classmethod
|
|
211
|
+
def from_dict(cls, data: dict[str, dict]) -> ToolCache:
|
|
212
|
+
"""Deserialize cache from dict.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
data: Dict representation of cache entries.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
ToolCache instance.
|
|
219
|
+
"""
|
|
220
|
+
from digitalkin.models.services.registry import ModuleInfo # noqa: PLC0415
|
|
221
|
+
|
|
222
|
+
cache = cls()
|
|
223
|
+
for slug, entry_data in data.items():
|
|
224
|
+
cache.entries[slug] = ToolCacheEntry(
|
|
225
|
+
slug=entry_data["slug"],
|
|
226
|
+
module_id=entry_data["module_id"],
|
|
227
|
+
module_info=ModuleInfo(**entry_data["module_info"]),
|
|
228
|
+
is_valid=entry_data.get("is_valid", True),
|
|
229
|
+
)
|
|
230
|
+
return cache
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""Tool reference types for archetype module configuration."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field, PrivateAttr, model_validator
|
|
7
|
+
|
|
8
|
+
from digitalkin.models.services.registry import ModuleInfo
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from digitalkin.services.registry import RegistryStrategy
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ToolSelectionMode(str, Enum):
|
|
15
|
+
"""Mode for tool selection in archetype setup."""
|
|
16
|
+
|
|
17
|
+
FIXED = "fixed"
|
|
18
|
+
TAG = "tag"
|
|
19
|
+
DISCOVERABLE = "discoverable"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ToolReferenceConfig(BaseModel):
|
|
23
|
+
"""Configuration for how a tool should be selected."""
|
|
24
|
+
|
|
25
|
+
mode: ToolSelectionMode = Field(default=ToolSelectionMode.FIXED)
|
|
26
|
+
slug: str | None = Field(default=None, description="Unique slug for cache lookup")
|
|
27
|
+
fixed_id: str | None = Field(default=None, description="Module ID for FIXED mode")
|
|
28
|
+
tag: str | None = Field(default=None, description="Search tag for TAG mode")
|
|
29
|
+
organization_id: str | None = Field(default=None, description="Filter by organization")
|
|
30
|
+
|
|
31
|
+
@model_validator(mode="after")
|
|
32
|
+
def validate_config(self) -> "ToolReferenceConfig":
|
|
33
|
+
"""Validate configuration based on mode.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
Self if validation passes.
|
|
37
|
+
|
|
38
|
+
Raises:
|
|
39
|
+
ValueError: If required field is missing for the mode.
|
|
40
|
+
"""
|
|
41
|
+
if self.mode == ToolSelectionMode.FIXED and not self.fixed_id:
|
|
42
|
+
msg = "fixed_id required when mode is FIXED"
|
|
43
|
+
raise ValueError(msg)
|
|
44
|
+
if self.mode == ToolSelectionMode.TAG and not self.tag:
|
|
45
|
+
msg = "tag required when mode is TAG"
|
|
46
|
+
raise ValueError(msg)
|
|
47
|
+
return self
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ToolReference(BaseModel):
|
|
51
|
+
"""Reference to a tool module for archetype configuration.
|
|
52
|
+
|
|
53
|
+
Frontend sets config, backend resolves to actual ModuleInfo.
|
|
54
|
+
The resolved module_id is persisted in selected_module_id for
|
|
55
|
+
subsequent StartModule calls without re-resolution.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
config: ToolReferenceConfig
|
|
59
|
+
selected_module_id: str | None = Field(default=None, description="Resolved module ID after resolution")
|
|
60
|
+
_cached_info: ModuleInfo | None = PrivateAttr(default=None)
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def slug(self) -> str | None:
|
|
64
|
+
"""Get the slug for cache lookup.
|
|
65
|
+
|
|
66
|
+
Returns config.slug if set, otherwise falls back to fixed_id or tag.
|
|
67
|
+
"""
|
|
68
|
+
if self.config.slug:
|
|
69
|
+
return self.config.slug
|
|
70
|
+
if self.config.mode == ToolSelectionMode.FIXED and self.config.fixed_id:
|
|
71
|
+
return self.config.fixed_id
|
|
72
|
+
if self.config.mode == ToolSelectionMode.TAG and self.config.tag:
|
|
73
|
+
return self.config.tag
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def module_info(self) -> ModuleInfo | None:
|
|
78
|
+
"""Get cached ModuleInfo if resolved."""
|
|
79
|
+
return self._cached_info
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def is_resolved(self) -> bool:
|
|
83
|
+
"""Check if this reference has been resolved."""
|
|
84
|
+
return self._cached_info is not None or self.selected_module_id is not None
|
|
85
|
+
|
|
86
|
+
def resolve(self, registry: "RegistryStrategy") -> ModuleInfo | None:
|
|
87
|
+
"""Resolve this reference using the provided registry.
|
|
88
|
+
|
|
89
|
+
For FIXED mode, looks up by fixed_id.
|
|
90
|
+
For TAG mode, searches by tag and takes first result.
|
|
91
|
+
For DISCOVERABLE mode, returns None (LLM handles at runtime).
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
registry: Registry service to use for resolution.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
ModuleInfo if resolved, None if not resolvable or DISCOVERABLE mode.
|
|
98
|
+
"""
|
|
99
|
+
if self.config.mode == ToolSelectionMode.DISCOVERABLE:
|
|
100
|
+
return None
|
|
101
|
+
|
|
102
|
+
if self.config.mode == ToolSelectionMode.FIXED and self.config.fixed_id:
|
|
103
|
+
info = registry.discover_by_id(self.config.fixed_id)
|
|
104
|
+
if info:
|
|
105
|
+
self._cached_info = info
|
|
106
|
+
self.selected_module_id = self.config.fixed_id
|
|
107
|
+
return info
|
|
108
|
+
|
|
109
|
+
if self.config.mode == ToolSelectionMode.TAG and self.config.tag:
|
|
110
|
+
results = registry.search(
|
|
111
|
+
name=self.config.tag,
|
|
112
|
+
module_type="tool",
|
|
113
|
+
organization_id=self.config.organization_id,
|
|
114
|
+
)
|
|
115
|
+
if results:
|
|
116
|
+
self._cached_info = results[0]
|
|
117
|
+
self.selected_module_id = results[0].module_id
|
|
118
|
+
return results[0]
|
|
119
|
+
|
|
120
|
+
return None
|
|
@@ -4,11 +4,12 @@ These protocols are automatically available to all modules and don't need to be
|
|
|
4
4
|
explicitly included in module output unions.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
from datetime import datetime, timezone
|
|
7
8
|
from typing import Any, ClassVar, Literal
|
|
8
9
|
|
|
9
10
|
from pydantic import BaseModel, Field
|
|
10
11
|
|
|
11
|
-
from digitalkin.models.module.
|
|
12
|
+
from digitalkin.models.module.base_types import DataTrigger
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class UtilityProtocol(DataTrigger):
|
|
@@ -27,6 +28,26 @@ class EndOfStreamOutput(UtilityProtocol):
|
|
|
27
28
|
protocol: Literal["end_of_stream"] = "end_of_stream" # type: ignore
|
|
28
29
|
|
|
29
30
|
|
|
31
|
+
class ModuleStartInfoOutput(UtilityProtocol):
|
|
32
|
+
"""Output sent when module starts with execution context.
|
|
33
|
+
|
|
34
|
+
This protocol is sent as the first message when a module starts,
|
|
35
|
+
providing the client with essential execution context information.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
protocol: Literal["module_start_info"] = "module_start_info" # type: ignore
|
|
39
|
+
job_id: str = Field(..., description="Unique job identifier")
|
|
40
|
+
mission_id: str = Field(..., description="Mission identifier")
|
|
41
|
+
setup_id: str = Field(..., description="Setup identifier")
|
|
42
|
+
setup_version_id: str = Field(..., description="Setup version identifier")
|
|
43
|
+
module_id: str = Field(..., description="Module identifier")
|
|
44
|
+
module_name: str = Field(..., description="Human-readable module name")
|
|
45
|
+
started_at: str = Field(
|
|
46
|
+
default_factory=lambda: datetime.now(tz=timezone.utc).isoformat(),
|
|
47
|
+
description="ISO timestamp when module started",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
30
51
|
class HealthcheckPingInput(UtilityProtocol):
|
|
31
52
|
"""Input for healthcheck ping request."""
|
|
32
53
|
|
|
@@ -18,7 +18,7 @@ from digitalkin.models.module.module_types import (
|
|
|
18
18
|
SecretModelT,
|
|
19
19
|
SetupModelT,
|
|
20
20
|
)
|
|
21
|
-
from digitalkin.models.module.utility import EndOfStreamOutput
|
|
21
|
+
from digitalkin.models.module.utility import EndOfStreamOutput, ModuleStartInfoOutput
|
|
22
22
|
from digitalkin.models.services.storage import BaseRole
|
|
23
23
|
from digitalkin.modules.trigger_handler import TriggerHandler
|
|
24
24
|
from digitalkin.services.services_config import ServicesConfig, ServicesStrategy
|
|
@@ -76,6 +76,7 @@ class BaseModule( # noqa: PLR0904
|
|
|
76
76
|
registry: RegistryStrategy
|
|
77
77
|
snapshot: SnapshotStrategy
|
|
78
78
|
storage: StorageStrategy
|
|
79
|
+
user_profile: UserProfileStrategy
|
|
79
80
|
"""
|
|
80
81
|
logger.debug("Service initialisation: %s", self.services_config_strategies.keys())
|
|
81
82
|
return {
|
|
@@ -446,7 +447,37 @@ class BaseModule( # noqa: PLR0904
|
|
|
446
447
|
"""Start the module."""
|
|
447
448
|
try:
|
|
448
449
|
self.context.callbacks.send_message = callback
|
|
449
|
-
|
|
450
|
+
|
|
451
|
+
# Use tool cache from setup_data if available (populated during run_config_setup)
|
|
452
|
+
# Tool cache is optional - modules can work without it
|
|
453
|
+
if hasattr(setup_data, "tool_cache") and setup_data.tool_cache is not None:
|
|
454
|
+
self.context.tool_cache = setup_data.tool_cache
|
|
455
|
+
|
|
456
|
+
# Validate tool cache - ensure all cached tools are still available
|
|
457
|
+
if self.context.registry and hasattr(setup_data, "validate_tool_cache"):
|
|
458
|
+
invalid_tools = setup_data.validate_tool_cache(self.context.registry)
|
|
459
|
+
if invalid_tools:
|
|
460
|
+
logger.warning(
|
|
461
|
+
"Some cached tools are no longer available",
|
|
462
|
+
extra={"invalid_tools": invalid_tools},
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
# Send module start info as first message
|
|
466
|
+
await callback(
|
|
467
|
+
DataModel(
|
|
468
|
+
root=ModuleStartInfoOutput(
|
|
469
|
+
job_id=self.context.session.job_id,
|
|
470
|
+
mission_id=self.context.session.mission_id,
|
|
471
|
+
setup_id=self.context.session.setup_id,
|
|
472
|
+
setup_version_id=self.context.session.setup_version_id,
|
|
473
|
+
module_id=self.get_module_id(),
|
|
474
|
+
module_name=self.name,
|
|
475
|
+
),
|
|
476
|
+
annotations={"role": BaseRole.SYSTEM},
|
|
477
|
+
)
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
logger.info("Initialize module %s", self.context.session.job_id)
|
|
450
481
|
await self.initialize(self.context, setup_data)
|
|
451
482
|
except Exception as e:
|
|
452
483
|
self._status = ModuleStatus.FAILED
|
|
@@ -467,7 +498,7 @@ class BaseModule( # noqa: PLR0904
|
|
|
467
498
|
try:
|
|
468
499
|
logger.debug("Init the discovered input handlers.")
|
|
469
500
|
self.triggers_discoverer.init_handlers(self.context)
|
|
470
|
-
logger.debug(
|
|
501
|
+
logger.debug("Run lifecycle %s", self.context.session.job_id)
|
|
471
502
|
await self._run_lifecycle(input_data, setup_data)
|
|
472
503
|
except Exception:
|
|
473
504
|
self._status = ModuleStatus.FAILED
|
|
@@ -6,7 +6,3 @@ They provide standard functionality available to all modules.
|
|
|
6
6
|
Note: These are internal triggers. External code should not import them directly.
|
|
7
7
|
Use UtilityRegistry.get_builtin_triggers() to access the trigger classes.
|
|
8
8
|
"""
|
|
9
|
-
|
|
10
|
-
# No public exports - all triggers are internal
|
|
11
|
-
# Access via: UtilityRegistry.get_builtin_triggers()
|
|
12
|
-
__all__: list[str] = []
|
|
@@ -13,21 +13,6 @@ class UserProfileServiceError(Exception):
|
|
|
13
13
|
class UserProfileStrategy(BaseStrategy, ABC):
|
|
14
14
|
"""Abstract base class for UserProfile strategies."""
|
|
15
15
|
|
|
16
|
-
def __init__(
|
|
17
|
-
self,
|
|
18
|
-
mission_id: str,
|
|
19
|
-
setup_id: str,
|
|
20
|
-
setup_version_id: str,
|
|
21
|
-
) -> None:
|
|
22
|
-
"""Initialize the strategy.
|
|
23
|
-
|
|
24
|
-
Args:
|
|
25
|
-
mission_id: The ID of the mission this strategy is associated with
|
|
26
|
-
setup_id: The ID of the setup
|
|
27
|
-
setup_version_id: The ID of the setup version this strategy is associated with
|
|
28
|
-
"""
|
|
29
|
-
super().__init__(mission_id, setup_id, setup_version_id)
|
|
30
|
-
|
|
31
16
|
@abstractmethod
|
|
32
17
|
def get_user_profile(self) -> dict[str, Any]:
|
|
33
18
|
"""Get user profile data.
|
|
@@ -7,7 +7,7 @@ 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=k7ywgivs-7wcYmxpZLVkbYfyQZo7NuQeNm6D2K0VbkI,195
|
|
11
11
|
digitalkin/logger.py,sha256=8ze_tjt2G6mDTuQcsf7-UTXWP3UHZ7LZVSs_iqF4rX4,4685
|
|
12
12
|
digitalkin/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
digitalkin/core/__init__.py,sha256=FJRcJ-B1Viyn-38L8XpOpZ8KOnf1I7PCDOAmKXLQhqc,71
|
|
@@ -15,7 +15,7 @@ digitalkin/core/common/__init__.py,sha256=Gh2eJAJRnrUE93jSEfG7r0nb01Xh1kSkNL6nEp
|
|
|
15
15
|
digitalkin/core/common/factories.py,sha256=mV6SmXXrZxzIQ7DLdDtPdjapSDZt5Ua-nBIDsozs_Vk,5047
|
|
16
16
|
digitalkin/core/job_manager/__init__.py,sha256=gGtgQpE6vbBHxAj1SYMbcpj45Q6x8IcsqnyQPfyZZ-8,25
|
|
17
17
|
digitalkin/core/job_manager/base_job_manager.py,sha256=fRnoR74uduImGYOKj4kZ5bo0xv9hrXSCUuq0NHfDpPE,10089
|
|
18
|
-
digitalkin/core/job_manager/single_job_manager.py,sha256
|
|
18
|
+
digitalkin/core/job_manager/single_job_manager.py,sha256=xOgl8HNUpfd_OPmoJpUt8hJznxDTeUzFpEFBRgEYzp4,14464
|
|
19
19
|
digitalkin/core/job_manager/taskiq_broker.py,sha256=ORGg2QSLDaWiCqie8ZGkbcDq7LDuWWSx7hg-SoUv99E,11544
|
|
20
20
|
digitalkin/core/job_manager/taskiq_job_manager.py,sha256=d23iylsc2RUvoE95VxZWa5Kb_yqptMOF63l7MDtuZtk,21264
|
|
21
21
|
digitalkin/core/task_manager/__init__.py,sha256=k9i-qIoee_1yXogyQolaVFDUQBIZU3ENbYKtjrCNmTQ,31
|
|
@@ -24,11 +24,11 @@ digitalkin/core/task_manager/local_task_manager.py,sha256=Z1gv4dCGD32LBSfMZJ4dGy
|
|
|
24
24
|
digitalkin/core/task_manager/remote_task_manager.py,sha256=zgccmnwwtB0nyeIZlL5Ji8SY1J89z_vjA4JD9ur7HzY,3082
|
|
25
25
|
digitalkin/core/task_manager/surrealdb_repository.py,sha256=a22FblutOYbtWtoh0SEqNIm_f6it3XkRReyBBLqy6Qk,9874
|
|
26
26
|
digitalkin/core/task_manager/task_executor.py,sha256=8xh5_1zuRAaGZIH_gWyNsA4T7YYaF0sl51dLS8a6aAk,10981
|
|
27
|
-
digitalkin/core/task_manager/task_session.py,sha256=
|
|
27
|
+
digitalkin/core/task_manager/task_session.py,sha256=5jw21bT_SPXUzWE7tk6YG62EXqlRJcrSakFXDFDRy28,12730
|
|
28
28
|
digitalkin/grpc_servers/__init__.py,sha256=ZIRMJ1Lcas8yQ106GCup6hn2UBOsx1sNk8ap0lpEDnY,72
|
|
29
29
|
digitalkin/grpc_servers/_base_server.py,sha256=ZVeCDwI7w7fFbPTXPkeJb_SOuLfd2T7za3T4oCu2UWY,18680
|
|
30
30
|
digitalkin/grpc_servers/module_server.py,sha256=7jO6Bz4pxno0AjRFercZMwgOFW7dutywynoCCht3dnQ,7858
|
|
31
|
-
digitalkin/grpc_servers/module_servicer.py,sha256=
|
|
31
|
+
digitalkin/grpc_servers/module_servicer.py,sha256=a5qVOd0beAwXlFAch9VfLNR8PdaYj_fF2O8rXcwInSU,21087
|
|
32
32
|
digitalkin/grpc_servers/utils/__init__.py,sha256=ZnAIb_F8z4NhtPypqkdmzgRSzolKnJTk3oZx5GfWH5Y,38
|
|
33
33
|
digitalkin/grpc_servers/utils/exceptions.py,sha256=LtaDtlqXCeT6iqApogs4pbtezotOVeg4fhnFzGBvFsY,692
|
|
34
34
|
digitalkin/grpc_servers/utils/grpc_client_wrapper.py,sha256=ElGvp6evY5q-EBmDVyQZaDJktfShtMsptMmq16jfgxA,3285
|
|
@@ -46,25 +46,29 @@ digitalkin/mixins/storage_mixin.py,sha256=ptZ4a2bydIa48q0V9e395vWHTu7yw4A6rI4jwK
|
|
|
46
46
|
digitalkin/models/__init__.py,sha256=xK0YGXsHI4ghGzIURRhIRYYM3sxbnOsk9UeMXdl5l-o,170
|
|
47
47
|
digitalkin/models/core/__init__.py,sha256=jOMDmPX0uSfGA9zUi0u_kOvYJ46VdIssoIhVYvNSeew,19
|
|
48
48
|
digitalkin/models/core/job_manager_models.py,sha256=wvf2dzRzAu0-zzzAXQe6XTC36cNA10sXRLt2p_TFqjk,1003
|
|
49
|
-
digitalkin/models/core/task_monitor.py,sha256=
|
|
49
|
+
digitalkin/models/core/task_monitor.py,sha256=CW-jydSgXMV464W0pqfar0HpgqlSxqdujmC-f8p9EQc,2639
|
|
50
50
|
digitalkin/models/grpc_servers/__init__.py,sha256=0tA71nPSXgRrh9DoLvx-TSwZXdYIRUEItoadpTL1cTo,42
|
|
51
51
|
digitalkin/models/grpc_servers/models.py,sha256=unV1Wo0u3Efm7ddgYyYZZYUC_W6F0S5BQYH3xsOmXjw,8965
|
|
52
52
|
digitalkin/models/grpc_servers/types.py,sha256=rQ78s4nAet2jy-NIDj_PUWriT0kuGHr_w6ELjmjgBao,539
|
|
53
|
-
digitalkin/models/module/__init__.py,sha256=
|
|
53
|
+
digitalkin/models/module/__init__.py,sha256=N55wan3rAUVPEGLIDjXoFM_-DYY_zxvbQOZHzNDfwoY,751
|
|
54
|
+
digitalkin/models/module/base_types.py,sha256=oIylVNqo0idTFj4dRgCt7P19daNZ-AlvgCPpL9TJvto,1850
|
|
54
55
|
digitalkin/models/module/module.py,sha256=k0W8vfJJFth8XdDzkHm32SyTuSf3h2qF0hSrxAfGF1s,956
|
|
55
|
-
digitalkin/models/module/module_context.py,sha256=
|
|
56
|
-
digitalkin/models/module/module_types.py,sha256=
|
|
57
|
-
digitalkin/models/module/
|
|
56
|
+
digitalkin/models/module/module_context.py,sha256=cnk5OpgevgqkmD_gU5KWSBzZ2vsNFUyN8rEzW0TNI-s,6354
|
|
57
|
+
digitalkin/models/module/module_types.py,sha256=C9azCNBk76xMa-Mww8_6AiwQR8MLAsEyUOvBYxytovI,739
|
|
58
|
+
digitalkin/models/module/setup_types.py,sha256=e9CG8x75Mkh7dDIQ66UWU99VcWmyk-JAqHCpUtcgyns,21323
|
|
59
|
+
digitalkin/models/module/tool_cache.py,sha256=H8k2ue9m61oNHGMDgF9i3e4FxfFQoNW1iIZqoWyZNOc,7523
|
|
60
|
+
digitalkin/models/module/tool_reference.py,sha256=A4EewKMlfhdI2hW7F3kgPc6_UinUrN-hhOweM0KzSa0,4302
|
|
61
|
+
digitalkin/models/module/utility.py,sha256=gnbYfWpXGbomUI0fWf7T-Qm_VvT-LXDv1OuA9zObwVg,5589
|
|
58
62
|
digitalkin/models/services/__init__.py,sha256=jhfVw6egq0OcHmos_fypH9XFehbHTBw09wluVFVFEyw,226
|
|
59
63
|
digitalkin/models/services/cost.py,sha256=9PXvd5RrIk9vCrRjcUGQ9ZyAokEbwLg4s0RfnE-aLP4,1616
|
|
60
64
|
digitalkin/models/services/registry.py,sha256=0qMAIi52ovofZ4XTV7UkI4i7sR5C3_VFLp-kw9AjQ24,829
|
|
61
65
|
digitalkin/models/services/storage.py,sha256=wp7F-AvTsU46ujGPcguqM5kUKRZx4399D4EGAAJt2zs,1143
|
|
62
66
|
digitalkin/modules/__init__.py,sha256=vTQk8DWopxQSJ17BjE5dNhq247Rou55iQLJdBxoPUmo,296
|
|
63
|
-
digitalkin/modules/_base_module.py,sha256=
|
|
67
|
+
digitalkin/modules/_base_module.py,sha256=0bbiPOcLSiKqjrVYaWdmc72jbpaPa8dOzozEcQO0zMg,21285
|
|
64
68
|
digitalkin/modules/archetype_module.py,sha256=XC9tl1Yr6QlbPn_x0eov6UUZwQgwW--BYPPMYVJH_NU,505
|
|
65
69
|
digitalkin/modules/tool_module.py,sha256=GBis7bKCkvWFCYLRvaS9oZVmLBBve1w8BhVnKOU2sCc,506
|
|
66
70
|
digitalkin/modules/trigger_handler.py,sha256=qPNMi-8NHqscOxciHeaXtpwjXApT3YzjMF23zQAjaZY,1770
|
|
67
|
-
digitalkin/modules/triggers/__init__.py,sha256=
|
|
71
|
+
digitalkin/modules/triggers/__init__.py,sha256=OKzUWqlnm9wzAAvztPocSK36i69giWEQnxn0hbdfCsM,323
|
|
68
72
|
digitalkin/modules/triggers/healthcheck_ping_trigger.py,sha256=fQjfOB_NMPocISXAT8rlk896_pXIY8v0op0JhZNv_G0,1558
|
|
69
73
|
digitalkin/modules/triggers/healthcheck_services_trigger.py,sha256=TpPw5XTnw3Bt9VCoFXQ_V-SIAR8LMoJmDGiyegWW6To,2286
|
|
70
74
|
digitalkin/modules/triggers/healthcheck_status_trigger.py,sha256=rozWQWvO7a2ZTg8BjFCyEWeAai5vdbi7BBwu0vR5jv8,1768
|
|
@@ -110,14 +114,14 @@ digitalkin/services/storage/storage_strategy.py,sha256=sERF5tIJnzpb1iNqTXic9xRkG
|
|
|
110
114
|
digitalkin/services/user_profile/__init__.py,sha256=RKEZCsgCHS7fmswhWgUoQd6vZ_1pYnRqERoF8fmu7jw,434
|
|
111
115
|
digitalkin/services/user_profile/default_user_profile.py,sha256=46DH_VBCHKXJVyagVcc8kH5sLwRK54Fe_0ahqYJ1maA,1847
|
|
112
116
|
digitalkin/services/user_profile/grpc_user_profile.py,sha256=xDiUC5Ceofa6QtGPmqJV3ik5j8HDHc1zxtpia49rlRw,2780
|
|
113
|
-
digitalkin/services/user_profile/user_profile_strategy.py,sha256=
|
|
117
|
+
digitalkin/services/user_profile/user_profile_strategy.py,sha256=CH8kT__1MUwA21k5djjmB5ZZ6pYg57OWbe_7owBCgwU,681
|
|
114
118
|
digitalkin/utils/__init__.py,sha256=gDoEk5CP8tiBmIq-38aPhIMlnDUiqRrduuVXhpSPQnc,541
|
|
115
119
|
digitalkin/utils/arg_parser.py,sha256=wzscRlE1Qp1gGl-lAJlkkwnbU1O2oezj6BwK_BZFBIk,3158
|
|
116
120
|
digitalkin/utils/development_mode_action.py,sha256=2hznh0ajW_4ZTysfoc0Y49161f_PQPATRgNk8NAn1_o,1623
|
|
117
121
|
digitalkin/utils/dynamic_schema.py,sha256=5-B3dBGlCYYv6uRJkgudtc0ZpBOTYxl0yKedDGsteZQ,15184
|
|
118
122
|
digitalkin/utils/llm_ready_schema.py,sha256=JjMug_lrQllqFoanaC091VgOqwAd-_YzcpqFlS7p778,2375
|
|
119
123
|
digitalkin/utils/package_discover.py,sha256=sa6Zp5Kape1Zr4iYiNrnZxiHDnqM06ODk6yfWHom53w,13465
|
|
120
|
-
digitalkin-0.3.2.
|
|
124
|
+
digitalkin-0.3.2.dev4.dist-info/licenses/LICENSE,sha256=Ies4HFv2r2hzDRakJYxk3Y60uDFLiG-orIgeTpstnIo,20327
|
|
121
125
|
modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
122
126
|
modules/cpu_intensive_module.py,sha256=GZlirQDZdYuXrI46sv1q4RNAHZjL4EptHVQTvgK9zz8,8363
|
|
123
127
|
modules/dynamic_setup_module.py,sha256=tKvUWZdlYZkfAgKR0mLuFcLiFGKpVgpsz10LeJ6B2QI,11410
|
|
@@ -125,7 +129,7 @@ modules/minimal_llm_module.py,sha256=N9aIzZQI-miyH4AB4xTmGHpMvdSLnYyXNOD4Z3YFzis
|
|
|
125
129
|
modules/text_transform_module.py,sha256=MfhI_Ki1U6qk379ne6oazNEu4PhO4R3cRezEcr0nGPw,7251
|
|
126
130
|
services/filesystem_module.py,sha256=U4dgqtuDadaXz8PJ1d_uQ_1EPncBqudAQCLUICF9yL4,7421
|
|
127
131
|
services/storage_module.py,sha256=Wz2MzLvqs2D_bnBBgtnujYcAKK2V2KFMk8K21RoepSE,6972
|
|
128
|
-
digitalkin-0.3.2.
|
|
129
|
-
digitalkin-0.3.2.
|
|
130
|
-
digitalkin-0.3.2.
|
|
131
|
-
digitalkin-0.3.2.
|
|
132
|
+
digitalkin-0.3.2.dev4.dist-info/METADATA,sha256=9owo2Dtpnwbm4Rjkx9iXA_rKkzstywsbhe8hU9Mn8pY,29724
|
|
133
|
+
digitalkin-0.3.2.dev4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
134
|
+
digitalkin-0.3.2.dev4.dist-info/top_level.txt,sha256=gcjqlyrZuLjIyxrOIavCQM_olpr6ND5kPKkZd2j0xGo,40
|
|
135
|
+
digitalkin-0.3.2.dev4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|