cks-runtime 0.1.2__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.
- cks_runtime/__init__.py +11 -0
- cks_runtime/adapters/__init__.py +0 -0
- cks_runtime/config.py +22 -0
- cks_runtime/core_api/__init__.py +0 -0
- cks_runtime/core_api/interfaces.py +78 -0
- cks_runtime/diagnostics/__init__.py +0 -0
- cks_runtime/diagnostics/aggregator.py +115 -0
- cks_runtime/diagnostics/diagnostic.py +68 -0
- cks_runtime/explainability/__init__.py +0 -0
- cks_runtime/explainability/explainability_manager.py +0 -0
- cks_runtime/runtime.py +85 -0
- cks_runtime/session/__init__.py +0 -0
- cks_runtime/session/session.py +72 -0
- cks_runtime/session/session_manager.py +98 -0
- cks_runtime/storage/__init__.py +0 -0
- cks_runtime/storage/exceptions.py +37 -0
- cks_runtime/storage/memory_storage.py +127 -0
- cks_runtime/storage/storage.py +90 -0
- cks_runtime/transaction/__init__.py +0 -0
- cks_runtime/transaction/transaction.py +149 -0
- cks_runtime/transaction/transaction_manager.py +125 -0
- cks_runtime/versioning/__init__.py +0 -0
- cks_runtime/versioning/version.py +44 -0
- cks_runtime/versioning/version_manager.py +81 -0
- cks_runtime-0.1.2.dist-info/METADATA +306 -0
- cks_runtime-0.1.2.dist-info/RECORD +29 -0
- cks_runtime-0.1.2.dist-info/WHEEL +5 -0
- cks_runtime-0.1.2.dist-info/licenses/LICENSE +21 -0
- cks_runtime-0.1.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""
|
|
2
|
+
In-memory Runtime Storage.
|
|
3
|
+
|
|
4
|
+
Reference implementation used by tests.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from copy import deepcopy
|
|
10
|
+
|
|
11
|
+
from cks_runtime.session.session import RuntimeSession
|
|
12
|
+
from cks_runtime.storage.exceptions import (
|
|
13
|
+
SessionNotFound,
|
|
14
|
+
VersionNotFound,
|
|
15
|
+
)
|
|
16
|
+
from cks_runtime.storage.storage import RuntimeStorage
|
|
17
|
+
from cks_runtime.versioning.version import RuntimeVersion
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class InMemoryStorage(RuntimeStorage):
|
|
21
|
+
"""
|
|
22
|
+
Reference Runtime Storage implementation.
|
|
23
|
+
|
|
24
|
+
Provides deterministic in-memory persistence for:
|
|
25
|
+
|
|
26
|
+
- Runtime Sessions;
|
|
27
|
+
- Runtime Versions.
|
|
28
|
+
|
|
29
|
+
Intended primarily for testing and as the
|
|
30
|
+
reference Runtime Storage implementation.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self) -> None:
|
|
34
|
+
self._sessions: dict[str, RuntimeSession] = {}
|
|
35
|
+
self._versions: dict[str, RuntimeVersion] = {}
|
|
36
|
+
|
|
37
|
+
def save_session(
|
|
38
|
+
self,
|
|
39
|
+
session: RuntimeSession,
|
|
40
|
+
) -> None:
|
|
41
|
+
"""
|
|
42
|
+
Persist a Runtime Session.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
self._sessions[
|
|
46
|
+
session.session_id
|
|
47
|
+
] = deepcopy(session)
|
|
48
|
+
|
|
49
|
+
def load_session(
|
|
50
|
+
self,
|
|
51
|
+
session_id: str,
|
|
52
|
+
) -> RuntimeSession:
|
|
53
|
+
"""
|
|
54
|
+
Restore a Runtime Session.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
session = self._sessions[
|
|
59
|
+
session_id
|
|
60
|
+
]
|
|
61
|
+
except KeyError as exc:
|
|
62
|
+
raise SessionNotFound(
|
|
63
|
+
session_id
|
|
64
|
+
) from exc
|
|
65
|
+
|
|
66
|
+
return deepcopy(session)
|
|
67
|
+
|
|
68
|
+
def save_version(
|
|
69
|
+
self,
|
|
70
|
+
version: RuntimeVersion,
|
|
71
|
+
) -> None:
|
|
72
|
+
"""
|
|
73
|
+
Persist a Runtime Version.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
self._versions[
|
|
77
|
+
version.version_id
|
|
78
|
+
] = deepcopy(version)
|
|
79
|
+
|
|
80
|
+
def load_version(
|
|
81
|
+
self,
|
|
82
|
+
version_id: str,
|
|
83
|
+
) -> RuntimeVersion:
|
|
84
|
+
"""
|
|
85
|
+
Restore a Runtime Version.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
version = self._versions[
|
|
90
|
+
version_id
|
|
91
|
+
]
|
|
92
|
+
except KeyError as exc:
|
|
93
|
+
raise VersionNotFound(
|
|
94
|
+
version_id
|
|
95
|
+
) from exc
|
|
96
|
+
|
|
97
|
+
return deepcopy(version)
|
|
98
|
+
|
|
99
|
+
def has_session(
|
|
100
|
+
self,
|
|
101
|
+
session_id: str,
|
|
102
|
+
) -> bool:
|
|
103
|
+
"""
|
|
104
|
+
Determine whether a Runtime Session exists.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
return session_id in self._sessions
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def has_version(
|
|
111
|
+
self,
|
|
112
|
+
version_id: str,
|
|
113
|
+
) -> bool:
|
|
114
|
+
"""
|
|
115
|
+
Determine whether a Runtime Version exists.
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
return version_id in self._versions
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def clear(self) -> None:
|
|
122
|
+
"""
|
|
123
|
+
Remove every persisted Runtime object.
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
self._sessions.clear()
|
|
127
|
+
self._versions.clear()
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Abstract Runtime Storage.
|
|
3
|
+
|
|
4
|
+
SPEC-006 Storage.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from abc import ABC
|
|
10
|
+
from abc import abstractmethod
|
|
11
|
+
|
|
12
|
+
from cks_runtime.session.session import RuntimeSession
|
|
13
|
+
from cks_runtime.versioning.version import RuntimeVersion
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class RuntimeStorage(ABC):
|
|
17
|
+
"""
|
|
18
|
+
Abstract Runtime Storage.
|
|
19
|
+
|
|
20
|
+
Storage persists Runtime operational state.
|
|
21
|
+
|
|
22
|
+
Storage never:
|
|
23
|
+
|
|
24
|
+
- owns Sessions;
|
|
25
|
+
- owns Transactions;
|
|
26
|
+
- interprets semantics.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
@abstractmethod
|
|
30
|
+
def save_session(
|
|
31
|
+
self,
|
|
32
|
+
session: RuntimeSession,
|
|
33
|
+
) -> None:
|
|
34
|
+
"""
|
|
35
|
+
Persist a Runtime Session.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
@abstractmethod
|
|
39
|
+
def load_session(
|
|
40
|
+
self,
|
|
41
|
+
session_id: str,
|
|
42
|
+
) -> RuntimeSession:
|
|
43
|
+
"""
|
|
44
|
+
Restore a Runtime Session.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
@abstractmethod
|
|
48
|
+
def has_session(
|
|
49
|
+
self,
|
|
50
|
+
session_id: str,
|
|
51
|
+
) -> bool:
|
|
52
|
+
"""
|
|
53
|
+
Check whether a Runtime Session exists.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
@abstractmethod
|
|
57
|
+
def save_version(
|
|
58
|
+
self,
|
|
59
|
+
version: RuntimeVersion,
|
|
60
|
+
) -> None:
|
|
61
|
+
"""
|
|
62
|
+
Persist a Runtime Version.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
@abstractmethod
|
|
66
|
+
def load_version(
|
|
67
|
+
self,
|
|
68
|
+
version_id: str,
|
|
69
|
+
) -> RuntimeVersion:
|
|
70
|
+
"""
|
|
71
|
+
Restore a Runtime Version.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
@abstractmethod
|
|
75
|
+
def has_version(
|
|
76
|
+
self,
|
|
77
|
+
version_id: str,
|
|
78
|
+
) -> bool:
|
|
79
|
+
"""
|
|
80
|
+
Check whether a Runtime Version exists.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
@abstractmethod
|
|
84
|
+
def clear(self) -> None:
|
|
85
|
+
"""
|
|
86
|
+
Remove every persisted object.
|
|
87
|
+
|
|
88
|
+
Intended primarily for testing and
|
|
89
|
+
deterministic reference implementations.
|
|
90
|
+
"""
|
|
File without changes
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Runtime Transaction model.
|
|
3
|
+
|
|
4
|
+
A Transaction is the exclusive mechanism through which
|
|
5
|
+
Runtime Session operational state may evolve.
|
|
6
|
+
|
|
7
|
+
Transactions coordinate execution.
|
|
8
|
+
They do not define semantic behaviour.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from enum import Enum
|
|
13
|
+
from typing import Any
|
|
14
|
+
from uuid import uuid4
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TransactionStatus(Enum):
|
|
18
|
+
"""
|
|
19
|
+
Canonical Runtime Transaction states.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
CREATED = "created"
|
|
23
|
+
EXECUTING = "executing"
|
|
24
|
+
VALIDATING = "validating"
|
|
25
|
+
COMMITTED = "committed"
|
|
26
|
+
ROLLED_BACK = "rolled_back"
|
|
27
|
+
ABORTED = "aborted"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class RuntimeTransaction:
|
|
32
|
+
"""
|
|
33
|
+
Represents one Runtime Transaction.
|
|
34
|
+
|
|
35
|
+
Ownership:
|
|
36
|
+
|
|
37
|
+
- exactly one Runtime Session owns a Transaction;
|
|
38
|
+
- Transaction modifies operational state only;
|
|
39
|
+
- semantic validation belongs to CKS Core.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
session: Any
|
|
43
|
+
|
|
44
|
+
transaction_id: str = field(
|
|
45
|
+
default_factory=lambda: str(uuid4())
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
operations: list[Any] = field(
|
|
49
|
+
default_factory=list
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
diagnostics: list[Any] = field(
|
|
53
|
+
default_factory=list
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
status: TransactionStatus = (
|
|
57
|
+
TransactionStatus.CREATED
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
def _ensure_not_completed(self) -> bool:
|
|
61
|
+
"""
|
|
62
|
+
Return False when the Transaction has
|
|
63
|
+
already reached a terminal state.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
return not self.completed
|
|
67
|
+
|
|
68
|
+
def add_operation(
|
|
69
|
+
self,
|
|
70
|
+
operation: Any,
|
|
71
|
+
) -> None:
|
|
72
|
+
"""
|
|
73
|
+
Register a Runtime operation.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
self.operations.append(operation)
|
|
77
|
+
|
|
78
|
+
def add_diagnostic(
|
|
79
|
+
self,
|
|
80
|
+
diagnostic: Any,
|
|
81
|
+
) -> None:
|
|
82
|
+
"""
|
|
83
|
+
Register a Runtime or Core diagnostic.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
self.diagnostics.append(diagnostic)
|
|
87
|
+
|
|
88
|
+
def mark_executing(self) -> None:
|
|
89
|
+
"""
|
|
90
|
+
Mark Transaction as executing.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
if not self._ensure_not_completed():
|
|
94
|
+
return
|
|
95
|
+
|
|
96
|
+
self.status = TransactionStatus.EXECUTING
|
|
97
|
+
|
|
98
|
+
def mark_validating(self) -> None:
|
|
99
|
+
"""
|
|
100
|
+
Mark Transaction as validating.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
if not self._ensure_not_completed():
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
self.status = TransactionStatus.VALIDATING
|
|
107
|
+
|
|
108
|
+
def commit(self) -> None:
|
|
109
|
+
"""
|
|
110
|
+
Complete Transaction successfully.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
if not self._ensure_not_completed():
|
|
114
|
+
return
|
|
115
|
+
|
|
116
|
+
self.status = TransactionStatus.COMMITTED
|
|
117
|
+
|
|
118
|
+
def rollback(self) -> None:
|
|
119
|
+
"""
|
|
120
|
+
Roll back pending operational changes.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
if not self._ensure_not_completed():
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
self.status = TransactionStatus.ROLLED_BACK
|
|
127
|
+
|
|
128
|
+
def abort(self) -> None:
|
|
129
|
+
"""
|
|
130
|
+
Abort Transaction execution.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
if not self._ensure_not_completed():
|
|
134
|
+
return
|
|
135
|
+
|
|
136
|
+
self.status = TransactionStatus.ABORTED
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def completed(self) -> bool:
|
|
140
|
+
"""
|
|
141
|
+
Whether the Transaction has reached
|
|
142
|
+
a terminal state.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
return self.status in {
|
|
146
|
+
TransactionStatus.COMMITTED,
|
|
147
|
+
TransactionStatus.ROLLED_BACK,
|
|
148
|
+
TransactionStatus.ABORTED,
|
|
149
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Runtime Transaction Manager.
|
|
3
|
+
|
|
4
|
+
Owns Transaction lifecycle.
|
|
5
|
+
|
|
6
|
+
Responsibilities:
|
|
7
|
+
|
|
8
|
+
- begin Transactions;
|
|
9
|
+
- retrieve Transactions;
|
|
10
|
+
- coordinate completion;
|
|
11
|
+
- preserve Session ownership.
|
|
12
|
+
|
|
13
|
+
Does not:
|
|
14
|
+
|
|
15
|
+
- perform semantic validation;
|
|
16
|
+
- create Versions;
|
|
17
|
+
- persist Runtime state;
|
|
18
|
+
- modify CKS Core behaviour.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
from .transaction import RuntimeTransaction
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class TransactionManager:
|
|
27
|
+
"""
|
|
28
|
+
Coordinates Runtime Transactions.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self) -> None:
|
|
32
|
+
self._transactions: dict[
|
|
33
|
+
str,
|
|
34
|
+
RuntimeTransaction
|
|
35
|
+
] = {}
|
|
36
|
+
|
|
37
|
+
def begin(
|
|
38
|
+
self,
|
|
39
|
+
session: Any,
|
|
40
|
+
) -> RuntimeTransaction:
|
|
41
|
+
"""
|
|
42
|
+
Begin a Transaction for a Session.
|
|
43
|
+
|
|
44
|
+
Exactly one active Transaction may exist
|
|
45
|
+
per Session.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
if session.active_transaction is not None:
|
|
49
|
+
raise RuntimeError(
|
|
50
|
+
"Session already has an active transaction."
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
transaction = RuntimeTransaction(
|
|
54
|
+
session=session
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
self._transactions[
|
|
58
|
+
transaction.transaction_id
|
|
59
|
+
] = transaction
|
|
60
|
+
|
|
61
|
+
session.active_transaction = transaction
|
|
62
|
+
|
|
63
|
+
return transaction
|
|
64
|
+
|
|
65
|
+
def retrieve(
|
|
66
|
+
self,
|
|
67
|
+
transaction_id: str,
|
|
68
|
+
) -> RuntimeTransaction | None:
|
|
69
|
+
"""
|
|
70
|
+
Retrieve a Transaction by identity.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
return self._transactions.get(
|
|
74
|
+
transaction_id
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def commit(
|
|
78
|
+
self,
|
|
79
|
+
transaction: RuntimeTransaction,
|
|
80
|
+
) -> None:
|
|
81
|
+
"""
|
|
82
|
+
Commit a Transaction.
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
transaction.commit()
|
|
86
|
+
|
|
87
|
+
transaction.session.active_transaction = None
|
|
88
|
+
|
|
89
|
+
def rollback(
|
|
90
|
+
self,
|
|
91
|
+
transaction: RuntimeTransaction,
|
|
92
|
+
) -> None:
|
|
93
|
+
"""
|
|
94
|
+
Roll back a Transaction.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
transaction.rollback()
|
|
98
|
+
|
|
99
|
+
transaction.session.active_transaction = None
|
|
100
|
+
|
|
101
|
+
def abort(
|
|
102
|
+
self,
|
|
103
|
+
transaction: RuntimeTransaction,
|
|
104
|
+
) -> None:
|
|
105
|
+
"""
|
|
106
|
+
Abort a Transaction.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
transaction.abort()
|
|
110
|
+
|
|
111
|
+
transaction.session.active_transaction = None
|
|
112
|
+
|
|
113
|
+
def list_transactions(
|
|
114
|
+
self,
|
|
115
|
+
) -> list[RuntimeTransaction]:
|
|
116
|
+
"""
|
|
117
|
+
Return known Transactions.
|
|
118
|
+
|
|
119
|
+
Primarily intended for Runtime
|
|
120
|
+
management and testing.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
return list(
|
|
124
|
+
self._transactions.values()
|
|
125
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Immutable Runtime Version.
|
|
3
|
+
|
|
4
|
+
A Runtime Version records the operational state of a
|
|
5
|
+
Runtime Session immediately following a committed Transaction.
|
|
6
|
+
|
|
7
|
+
Versions are immutable.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from dataclasses import dataclass, field
|
|
13
|
+
from datetime import datetime, UTC
|
|
14
|
+
from typing import Any
|
|
15
|
+
from uuid import uuid4
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True, slots=True)
|
|
19
|
+
class RuntimeVersion:
|
|
20
|
+
"""
|
|
21
|
+
Immutable Runtime Version.
|
|
22
|
+
|
|
23
|
+
Ownership:
|
|
24
|
+
|
|
25
|
+
- owned by exactly one Runtime Session;
|
|
26
|
+
- created from exactly one committed Transaction;
|
|
27
|
+
- records operational state only.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
session_id: str
|
|
31
|
+
|
|
32
|
+
transaction_id: str
|
|
33
|
+
|
|
34
|
+
knowledge_structure: Any
|
|
35
|
+
|
|
36
|
+
metadata: dict[str, Any]
|
|
37
|
+
|
|
38
|
+
version_id: str = field(
|
|
39
|
+
default_factory=lambda: str(uuid4())
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
created_at: datetime = field(
|
|
43
|
+
default_factory=lambda: datetime.now(UTC)
|
|
44
|
+
)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Runtime Version Manager.
|
|
3
|
+
|
|
4
|
+
Creates immutable Runtime Versions from the
|
|
5
|
+
current Runtime Session state.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from cks_runtime.session.session import RuntimeSession
|
|
11
|
+
from cks_runtime.versioning.version import RuntimeVersion
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class VersionManager:
|
|
15
|
+
"""
|
|
16
|
+
Coordinates Runtime Version creation.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def create(
|
|
20
|
+
self,
|
|
21
|
+
session: RuntimeSession,
|
|
22
|
+
) -> RuntimeVersion:
|
|
23
|
+
"""
|
|
24
|
+
Create a new Runtime Version.
|
|
25
|
+
|
|
26
|
+
The Version is appended to the owning
|
|
27
|
+
Session Version History.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
version = RuntimeVersion(
|
|
31
|
+
session_id=session.session_id,
|
|
32
|
+
transaction_id=(
|
|
33
|
+
session.active_transaction.transaction_id
|
|
34
|
+
if session.active_transaction is not None
|
|
35
|
+
else ""
|
|
36
|
+
),
|
|
37
|
+
knowledge_structure=session.knowledge_structure,
|
|
38
|
+
metadata=dict(session.metadata),
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
session.version_history.append(version)
|
|
42
|
+
|
|
43
|
+
return version
|
|
44
|
+
|
|
45
|
+
def latest(
|
|
46
|
+
self,
|
|
47
|
+
session: RuntimeSession,
|
|
48
|
+
) -> RuntimeVersion | None:
|
|
49
|
+
"""
|
|
50
|
+
Return the latest Runtime Version.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
if not session.version_history:
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
return session.version_history[-1]
|
|
57
|
+
|
|
58
|
+
def retrieve(
|
|
59
|
+
self,
|
|
60
|
+
session: RuntimeSession,
|
|
61
|
+
version_id: str,
|
|
62
|
+
) -> RuntimeVersion | None:
|
|
63
|
+
"""
|
|
64
|
+
Retrieve a Runtime Version by identifier.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
for version in session.version_history:
|
|
68
|
+
if version.version_id == version_id:
|
|
69
|
+
return version
|
|
70
|
+
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
def list_versions(
|
|
74
|
+
self,
|
|
75
|
+
session: RuntimeSession,
|
|
76
|
+
) -> tuple[RuntimeVersion, ...]:
|
|
77
|
+
"""
|
|
78
|
+
Return immutable Runtime Version history.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
return tuple(session.version_history)
|