digitalkin 0.2.25rc1__py3-none-any.whl → 0.3.0__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/_base_server.py +1 -1
- digitalkin/grpc_servers/module_server.py +26 -42
- digitalkin/grpc_servers/module_servicer.py +30 -24
- digitalkin/grpc_servers/utils/grpc_client_wrapper.py +3 -3
- digitalkin/grpc_servers/utils/models.py +1 -1
- digitalkin/logger.py +60 -23
- 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 +5 -5
- 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 +105 -74
- 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 +225 -0
- digitalkin/modules/job_manager/task_manager.py +391 -0
- digitalkin/modules/job_manager/task_session.py +276 -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/storage/grpc_storage.py +1 -1
- {digitalkin-0.2.25rc1.dist-info → digitalkin-0.3.0.dist-info}/METADATA +18 -18
- {digitalkin-0.2.25rc1.dist-info → digitalkin-0.3.0.dist-info}/RECORD +39 -26
- {digitalkin-0.2.25rc1.dist-info → digitalkin-0.3.0.dist-info}/WHEEL +0 -0
- {digitalkin-0.2.25rc1.dist-info → digitalkin-0.3.0.dist-info}/licenses/LICENSE +0 -0
- {digitalkin-0.2.25rc1.dist-info → digitalkin-0.3.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""Context mixins providing ergonomic access to service strategies.
|
|
2
|
+
|
|
3
|
+
This module provides mixins that wrap service strategy calls with cleaner APIs,
|
|
4
|
+
following Django/FastAPI patterns where context is passed explicitly to each method.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from digitalkin.mixins.logger_mixin import LoggerMixin
|
|
8
|
+
from digitalkin.mixins.storage_mixin import StorageMixin
|
|
9
|
+
from digitalkin.models.module.module_context import ModuleContext
|
|
10
|
+
from digitalkin.models.services.storage import FileHistory, FileModel
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class FileHistoryMixin(StorageMixin, LoggerMixin):
|
|
14
|
+
"""Mixin providing File history operations through storage strategy.
|
|
15
|
+
|
|
16
|
+
This mixin provides a higher-level API for managing File history,
|
|
17
|
+
using the storage strategy as the underlying persistence mechanism.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
file_history_front: FileHistory = FileHistory(files=[])
|
|
21
|
+
FILE_HISTORY_COLLECTION = "file_history"
|
|
22
|
+
FILE_HISTORY_RECORD_ID = "full_file_history"
|
|
23
|
+
|
|
24
|
+
def _get_history_key(self, context: ModuleContext) -> str:
|
|
25
|
+
"""Get session-specific history key.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
context: Module context containing session information
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Unique history key for the current session
|
|
32
|
+
"""
|
|
33
|
+
mission_id = getattr(context.session, "mission_id", None) or "default"
|
|
34
|
+
return f"{self.FILE_HISTORY_RECORD_ID}_{mission_id}"
|
|
35
|
+
|
|
36
|
+
def load_file_history(self, context: ModuleContext) -> FileHistory:
|
|
37
|
+
"""Load File history for the current session.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
context: Module context containing storage strategy
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
File history object, empty if none exists or loading fails
|
|
44
|
+
"""
|
|
45
|
+
history_key = self._get_history_key(context)
|
|
46
|
+
|
|
47
|
+
if self.file_history_front is None:
|
|
48
|
+
try:
|
|
49
|
+
record = self.read_storage(
|
|
50
|
+
context,
|
|
51
|
+
self.FILE_HISTORY_COLLECTION,
|
|
52
|
+
history_key,
|
|
53
|
+
)
|
|
54
|
+
if record and record.data:
|
|
55
|
+
return FileHistory.model_validate(record.data)
|
|
56
|
+
except Exception as e:
|
|
57
|
+
self.log_warning(context, f"Failed to load File history: {e}")
|
|
58
|
+
return self.file_history_front
|
|
59
|
+
|
|
60
|
+
def append_files_history(self, context: ModuleContext, files: list[FileModel]) -> None:
|
|
61
|
+
"""Append a message to File history.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
context: Module context containing storage strategy
|
|
65
|
+
role: Message role (user, assistant, system)
|
|
66
|
+
files: list of files model
|
|
67
|
+
|
|
68
|
+
Raises:
|
|
69
|
+
StorageServiceError: If history update fails
|
|
70
|
+
"""
|
|
71
|
+
history_key = self._get_history_key(context)
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
if not self.file_history_front.files:
|
|
75
|
+
self.file_history_front = self.load_file_history(context)
|
|
76
|
+
self.file_history_front.files.extend(files)
|
|
77
|
+
except Exception as e:
|
|
78
|
+
self.log_error(context, f"Failed to append message to File history: {e}")
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
self.log_debug(context, f"Updating File history for session: {history_key}")
|
|
82
|
+
self.update_storage(
|
|
83
|
+
context,
|
|
84
|
+
self.FILE_HISTORY_COLLECTION,
|
|
85
|
+
history_key,
|
|
86
|
+
self.file_history_front.model_dump(),
|
|
87
|
+
)
|
|
88
|
+
except Exception as e:
|
|
89
|
+
self.log_error(context, f"Updating File history for session: {history_key} with error: {e}")
|
|
90
|
+
|
|
91
|
+
# Create new record
|
|
92
|
+
self.log_debug(context, f"Creating new File history for session: {history_key}")
|
|
93
|
+
self.store_storage(
|
|
94
|
+
context,
|
|
95
|
+
self.FILE_HISTORY_COLLECTION,
|
|
96
|
+
history_key,
|
|
97
|
+
self.file_history_front.model_dump(),
|
|
98
|
+
data_type="OUTPUT",
|
|
99
|
+
)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Filesystem Mixin to ease filesystem use."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from digitalkin.models.module.module_context import ModuleContext
|
|
6
|
+
from digitalkin.services.filesystem.filesystem_strategy import FilesystemRecord
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FilesystemMixin:
|
|
10
|
+
"""Mixin providing filesystem operations through the filesystem strategy.
|
|
11
|
+
|
|
12
|
+
This mixin wraps filesystem strategy calls to provide a cleaner API
|
|
13
|
+
for file operations in trigger handlers.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def upload_files(context: ModuleContext, files: list[Any]) -> tuple[list[FilesystemRecord], int, int]:
|
|
18
|
+
"""Upload files using the filesystem strategy.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
context: Module context containing the filesystem strategy
|
|
22
|
+
files: List of files to upload
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Tuple of (all_files, succeeded_files, failed_files)
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
FilesystemServiceError: If upload operation fails
|
|
29
|
+
"""
|
|
30
|
+
return context.filesystem.upload_files(files)
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def get_file(context: ModuleContext, file_id: str) -> tuple[FilesystemRecord, bytes | None]:
|
|
34
|
+
"""Retrieve a file by ID with the content.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
context: Module context containing the filesystem strategy
|
|
38
|
+
file_id: Unique identifier for the file
|
|
39
|
+
include_content: Whether to include file content in response
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
File object with metadata and optionally content
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
FilesystemServiceError: If file retrieval fails
|
|
46
|
+
"""
|
|
47
|
+
return context.filesystem.get_file(file_id, include_content=True)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Logger Mixin to ease and merge every logs."""
|
|
2
|
+
|
|
3
|
+
from digitalkin.models.module.module_context import ModuleContext
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class LoggerMixin:
|
|
7
|
+
"""Mixin providing callback operations through the callbacks strategy.
|
|
8
|
+
|
|
9
|
+
This mixin wraps callback strategy calls to provide a cleaner API
|
|
10
|
+
for logging and messaging in trigger handlers.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
@staticmethod
|
|
14
|
+
def log_debug(context: ModuleContext, message: str) -> None:
|
|
15
|
+
"""Log debug message using the callbacks strategy.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
context: Module context containing the callbacks strategy
|
|
19
|
+
message: Debug message to log
|
|
20
|
+
*args: Positional arguments for message formatting
|
|
21
|
+
**kwargs: Keyword arguments for logger
|
|
22
|
+
"""
|
|
23
|
+
return context.callbacks.logger.debug(message)
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def log_info(context: ModuleContext, message: str) -> None:
|
|
27
|
+
"""Log info message using the callbacks strategy.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
context: Module context containing the callbacks strategy
|
|
31
|
+
message: Info message to log
|
|
32
|
+
*args: Positional arguments for message formatting
|
|
33
|
+
**kwargs: Keyword arguments for logger
|
|
34
|
+
"""
|
|
35
|
+
return context.callbacks.logger.info(message)
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def log_warning(context: ModuleContext, message: str) -> None:
|
|
39
|
+
"""Log warning message using the callbacks strategy.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
context: Module context containing the callbacks strategy
|
|
43
|
+
message: Warning message to log
|
|
44
|
+
*args: Positional arguments for message formatting
|
|
45
|
+
**kwargs: Keyword arguments for logger
|
|
46
|
+
"""
|
|
47
|
+
return context.callbacks.logger.warning(message)
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def log_error(context: ModuleContext, message: str) -> None:
|
|
51
|
+
"""Log error message using the callbacks strategy.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
context: Module context containing the callbacks strategy
|
|
55
|
+
message: Error message to log
|
|
56
|
+
*args: Positional arguments for message formatting
|
|
57
|
+
**kwargs: Keyword arguments for logger
|
|
58
|
+
"""
|
|
59
|
+
return context.callbacks.logger.error(message)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""Storage Mixin to ease storage access in Triggers."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Literal
|
|
4
|
+
|
|
5
|
+
from digitalkin.models.module.module_context import ModuleContext
|
|
6
|
+
from digitalkin.services.storage.storage_strategy import StorageRecord
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class StorageMixin:
|
|
10
|
+
"""Mixin providing storage operations through the storage strategy.
|
|
11
|
+
|
|
12
|
+
This mixin wraps storage strategy calls to provide a cleaner API
|
|
13
|
+
for trigger handlers.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def store_storage(
|
|
18
|
+
context: ModuleContext,
|
|
19
|
+
collection: str,
|
|
20
|
+
record_id: str | None,
|
|
21
|
+
data: dict[str, Any],
|
|
22
|
+
data_type: Literal["OUTPUT", "VIEW", "LOGS", "OTHER"] = "OUTPUT",
|
|
23
|
+
) -> StorageRecord:
|
|
24
|
+
"""Store data using the storage strategy.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
context: Module context containing the storage strategy
|
|
28
|
+
collection: Collection name for the data
|
|
29
|
+
record_id: Optional record identifier
|
|
30
|
+
data: Data to store
|
|
31
|
+
data_type: Type of data being stored
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
Result from the storage strategy
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
StorageServiceError: If storage operation fails
|
|
38
|
+
"""
|
|
39
|
+
return context.storage.store(collection, record_id, data, data_type=data_type)
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def read_storage(context: ModuleContext, collection: str, record_id: str) -> StorageRecord | None:
|
|
43
|
+
"""Read data from storage.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
context: Module context containing the storage strategy
|
|
47
|
+
collection: Collection name
|
|
48
|
+
record_id: Record identifier
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
Retrieved data
|
|
52
|
+
|
|
53
|
+
Raises:
|
|
54
|
+
StorageServiceError: If read operation fails
|
|
55
|
+
"""
|
|
56
|
+
return context.storage.read(collection, record_id)
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def update_storage(
|
|
60
|
+
context: ModuleContext,
|
|
61
|
+
collection: str,
|
|
62
|
+
record_id: str,
|
|
63
|
+
data: dict[str, Any],
|
|
64
|
+
) -> StorageRecord | None:
|
|
65
|
+
"""Update existing data in storage.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
context: Module context containing the storage strategy
|
|
69
|
+
collection: Collection name
|
|
70
|
+
record_id: Record identifier
|
|
71
|
+
data: Updated data
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
Result from the storage strategy
|
|
75
|
+
|
|
76
|
+
Raises:
|
|
77
|
+
StorageServiceError: If update operation fails
|
|
78
|
+
"""
|
|
79
|
+
return context.storage.update(collection, record_id, data)
|
|
@@ -5,6 +5,7 @@ from digitalkin.models.module.module_context import ModuleContext
|
|
|
5
5
|
from digitalkin.models.module.module_types import (
|
|
6
6
|
DataModel,
|
|
7
7
|
DataTrigger,
|
|
8
|
+
DataTriggerT,
|
|
8
9
|
InputModelT,
|
|
9
10
|
OutputModelT,
|
|
10
11
|
SecretModelT,
|
|
@@ -15,6 +16,7 @@ from digitalkin.models.module.module_types import (
|
|
|
15
16
|
__all__ = [
|
|
16
17
|
"DataModel",
|
|
17
18
|
"DataTrigger",
|
|
19
|
+
"DataTriggerT",
|
|
18
20
|
"InputModelT",
|
|
19
21
|
"Module",
|
|
20
22
|
"ModuleContext",
|
|
@@ -2,7 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
from enum import Enum, auto
|
|
4
4
|
|
|
5
|
-
from pydantic import BaseModel
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ModuleCodeModel(BaseModel):
|
|
9
|
+
"""typed error/code model."""
|
|
10
|
+
|
|
11
|
+
code: str = Field(...)
|
|
12
|
+
message: str | None = Field(default=None)
|
|
13
|
+
short_description: str | None = Field(default=None)
|
|
6
14
|
|
|
7
15
|
|
|
8
16
|
class ModuleStatus(Enum):
|
|
@@ -1,24 +1,108 @@
|
|
|
1
1
|
"""Define the module context used in the triggers."""
|
|
2
2
|
|
|
3
3
|
from types import SimpleNamespace
|
|
4
|
+
from typing import Any
|
|
4
5
|
|
|
6
|
+
from digitalkin.services.agent.agent_strategy import AgentStrategy
|
|
5
7
|
from digitalkin.services.cost.cost_strategy import CostStrategy
|
|
6
8
|
from digitalkin.services.filesystem.filesystem_strategy import FilesystemStrategy
|
|
9
|
+
from digitalkin.services.identity.identity_strategy import IdentityStrategy
|
|
10
|
+
from digitalkin.services.registry.registry_strategy import RegistryStrategy
|
|
11
|
+
from digitalkin.services.snapshot.snapshot_strategy import SnapshotStrategy
|
|
7
12
|
from digitalkin.services.storage.storage_strategy import StorageStrategy
|
|
8
13
|
|
|
9
14
|
|
|
10
|
-
class
|
|
11
|
-
"""
|
|
15
|
+
class Session(SimpleNamespace):
|
|
16
|
+
"""Session data container with mandatory setup_id and mission_id."""
|
|
17
|
+
|
|
18
|
+
mission_id: str
|
|
19
|
+
setup_version_id: str
|
|
20
|
+
|
|
21
|
+
def __init__(self, mission_id: str, setup_version_id: str, **kwargs: dict[str, Any]) -> None:
|
|
22
|
+
"""Init Module Session.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
mission_id: current mission_id.
|
|
26
|
+
setup_version_id: used setup config.
|
|
27
|
+
kwargs: user defined session variables.
|
|
28
|
+
|
|
29
|
+
Raises:
|
|
30
|
+
ValueError: If mandatory args are missing
|
|
31
|
+
"""
|
|
32
|
+
if not setup_version_id:
|
|
33
|
+
msg = "setup_version_id is mandatory and cannot be empty"
|
|
34
|
+
raise ValueError(msg)
|
|
35
|
+
if not mission_id:
|
|
36
|
+
msg = "mission_id is mandatory and cannot be empty"
|
|
37
|
+
raise ValueError(msg)
|
|
38
|
+
|
|
39
|
+
self.mission_id = mission_id
|
|
40
|
+
self.setup_version_id = setup_version_id
|
|
41
|
+
|
|
42
|
+
super().__init__(**kwargs)
|
|
12
43
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
storage (StorageStrategy): The strategy for handling storage operations.
|
|
44
|
+
|
|
45
|
+
class ModuleContext:
|
|
46
|
+
"""ModuleContext provides a container for strategies and resources used by a module.
|
|
17
47
|
|
|
18
48
|
This context object is designed to be passed to module components, providing them with
|
|
19
49
|
access to shared strategies and resources. Additional attributes may be set dynamically.
|
|
20
50
|
"""
|
|
21
51
|
|
|
52
|
+
# services list
|
|
53
|
+
agent: AgentStrategy
|
|
22
54
|
cost: CostStrategy
|
|
23
55
|
filesystem: FilesystemStrategy
|
|
56
|
+
identity: IdentityStrategy
|
|
57
|
+
registry: RegistryStrategy
|
|
58
|
+
snapshot: SnapshotStrategy
|
|
24
59
|
storage: StorageStrategy
|
|
60
|
+
|
|
61
|
+
session: Session
|
|
62
|
+
callbacks: SimpleNamespace
|
|
63
|
+
metadata: SimpleNamespace
|
|
64
|
+
helpers: SimpleNamespace
|
|
65
|
+
state: SimpleNamespace = SimpleNamespace()
|
|
66
|
+
|
|
67
|
+
def __init__( # noqa: PLR0913, PLR0917
|
|
68
|
+
self,
|
|
69
|
+
agent: AgentStrategy,
|
|
70
|
+
cost: CostStrategy,
|
|
71
|
+
filesystem: FilesystemStrategy,
|
|
72
|
+
identity: IdentityStrategy,
|
|
73
|
+
registry: RegistryStrategy,
|
|
74
|
+
snapshot: SnapshotStrategy,
|
|
75
|
+
storage: StorageStrategy,
|
|
76
|
+
session: dict[str, Any],
|
|
77
|
+
metadata: dict[str, Any] = {},
|
|
78
|
+
helpers: dict[str, Any] = {},
|
|
79
|
+
callbacks: dict[str, Any] = {},
|
|
80
|
+
) -> None:
|
|
81
|
+
"""Register mandatory services, session, metadata and callbacks.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
agent: AgentStrategy.
|
|
85
|
+
cost: CostStrategy.
|
|
86
|
+
filesystem: FilesystemStrategy.
|
|
87
|
+
identity: IdentityStrategy.
|
|
88
|
+
registry: RegistryStrategy.
|
|
89
|
+
snapshot: SnapshotStrategy.
|
|
90
|
+
storage: StorageStrategy.
|
|
91
|
+
metadata: dict defining differents Module metadata.
|
|
92
|
+
helpers: dict different user defined helpers.
|
|
93
|
+
session: dict referring the session IDs or informations.
|
|
94
|
+
callbacks: Functions allowing user to agent interaction.
|
|
95
|
+
"""
|
|
96
|
+
# Core services
|
|
97
|
+
self.agent = agent
|
|
98
|
+
self.cost = cost
|
|
99
|
+
self.filesystem = filesystem
|
|
100
|
+
self.identity = identity
|
|
101
|
+
self.registry = registry
|
|
102
|
+
self.snapshot = snapshot
|
|
103
|
+
self.storage = storage
|
|
104
|
+
|
|
105
|
+
self.metadata = SimpleNamespace(**metadata)
|
|
106
|
+
self.session = Session(**session)
|
|
107
|
+
self.helpers = SimpleNamespace(**helpers)
|
|
108
|
+
self.callbacks = SimpleNamespace(**callbacks)
|
|
@@ -9,9 +9,9 @@ from digitalkin.logger import logger
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class DataTrigger(BaseModel):
|
|
12
|
-
"""Defines the root input model exposing the protocol.
|
|
12
|
+
"""Defines the root input/output model exposing the protocol.
|
|
13
13
|
|
|
14
|
-
The mandatory protocol is important to define the module beahvior following the user or agent input.
|
|
14
|
+
The mandatory protocol is important to define the module beahvior following the user or agent input/output.
|
|
15
15
|
|
|
16
16
|
Example:
|
|
17
17
|
class MyInput(DataModel):
|
|
@@ -31,9 +31,9 @@ DataTriggerT = TypeVar("DataTriggerT", bound=DataTrigger)
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class DataModel(BaseModel, Generic[DataTriggerT]):
|
|
34
|
-
"""Base definition of input model showing mandatory root fields.
|
|
34
|
+
"""Base definition of input/output model showing mandatory root fields.
|
|
35
35
|
|
|
36
|
-
The Model define the Module Input, usually referring to multiple input type defined by an union.
|
|
36
|
+
The Model define the Module Input/output, usually referring to multiple input/output type defined by an union.
|
|
37
37
|
|
|
38
38
|
Example:
|
|
39
39
|
class ModuleInput(DataModel):
|
|
@@ -102,4 +102,4 @@ class SetupModel(BaseModel):
|
|
|
102
102
|
__config__=ConfigDict(arbitrary_types_allowed=True),
|
|
103
103
|
**clean_fields,
|
|
104
104
|
)
|
|
105
|
-
return cast("type[SetupModelT]", m)
|
|
105
|
+
return cast("type[SetupModelT]", m) # type: ignore
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TaskStatus(Enum):
|
|
11
|
+
"""."""
|
|
12
|
+
|
|
13
|
+
PENDING = "pending"
|
|
14
|
+
RUNNING = "running"
|
|
15
|
+
CANCELLED = "cancelled"
|
|
16
|
+
COMPLETED = "completed"
|
|
17
|
+
FAILED = "failed"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SignalType(Enum):
|
|
21
|
+
"""."""
|
|
22
|
+
|
|
23
|
+
START = "start"
|
|
24
|
+
STOP = "stop"
|
|
25
|
+
CANCEL = "cancel"
|
|
26
|
+
PAUSE = "pause"
|
|
27
|
+
RESUME = "resume"
|
|
28
|
+
STATUS = "status"
|
|
29
|
+
|
|
30
|
+
ACK_CANCEL = "ack_cancel"
|
|
31
|
+
ACK_PAUSE = "ack_pause"
|
|
32
|
+
ACK_RESUME = "ack_resume"
|
|
33
|
+
ACK_STATUS = "ack_status"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class SignalMessage(BaseModel):
|
|
37
|
+
"""."""
|
|
38
|
+
|
|
39
|
+
task_id: str = Field(..., description="Unique identifier for the task")
|
|
40
|
+
status: TaskStatus = Field(..., description="Current status of the task")
|
|
41
|
+
action: SignalType = Field(..., description="Type of signal action")
|
|
42
|
+
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
|
43
|
+
payload: dict[str, Any] = Field(default={}, description="Optional payload for the signal")
|
|
44
|
+
model_config = {"use_enum_values": True}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class HeartbeatMessage(BaseModel):
|
|
48
|
+
"""."""
|
|
49
|
+
|
|
50
|
+
task_id: str = Field(..., description="Unique identifier for the task")
|
|
51
|
+
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
|
@@ -1,10 +1,44 @@
|
|
|
1
1
|
"""Storage model."""
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from typing import Any
|
|
4
5
|
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
5
7
|
|
|
6
|
-
class StorageModel(BaseModel):
|
|
7
|
-
"""Storage model."""
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
class BaseRole(str, Enum):
|
|
10
|
+
"""Officially supported Role Enum for chat messages."""
|
|
11
|
+
|
|
12
|
+
ASSISTANT = "assistant"
|
|
13
|
+
HUMAN = "human"
|
|
14
|
+
SYSTEM = "system"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
Role = BaseRole | str
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class BaseMessage(BaseModel):
|
|
21
|
+
"""Base Model representing a simple message in the chat history."""
|
|
22
|
+
|
|
23
|
+
role: Role = Field(..., description="Role of the message sender")
|
|
24
|
+
content: Any = Field(..., description="The content of the message | preferably a BaseModel.")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ChatHistory(BaseModel):
|
|
28
|
+
"""Storage chat history model for the OpenAI Archetype module."""
|
|
29
|
+
|
|
30
|
+
messages: list[BaseMessage] = Field(..., description="List of messages in the chat history")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class FileModel(BaseModel):
|
|
34
|
+
"""File model."""
|
|
35
|
+
|
|
36
|
+
file_id: str = Field(..., description="ID of the file")
|
|
37
|
+
name: str = Field(..., description="Name of the file")
|
|
38
|
+
metadata: dict[str, Any] = Field(..., description="Metadata of the file")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class FileHistory(BaseModel):
|
|
42
|
+
"""File history model."""
|
|
43
|
+
|
|
44
|
+
files: list[FileModel] = Field(..., description="List of files")
|