onec-interactive-runtime-core 0.1.19__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.
Files changed (87) hide show
  1. onec_interactive_runtime_core-0.1.19.dist-info/METADATA +12 -0
  2. onec_interactive_runtime_core-0.1.19.dist-info/RECORD +87 -0
  3. onec_interactive_runtime_core-0.1.19.dist-info/WHEEL +4 -0
  4. onec_interactive_runtime_core-0.1.19.dist-info/licenses/COPYRIGHT +9 -0
  5. onec_interactive_runtime_core-0.1.19.dist-info/licenses/LICENSE +232 -0
  6. onec_interactive_runtime_core-0.1.19.dist-info/licenses/THIRD_PARTY_NOTICES.txt +32 -0
  7. onec_runtime/AGENTS.md +7 -0
  8. onec_runtime/__init__.py +3 -0
  9. onec_runtime/artifacts.py +59 -0
  10. onec_runtime/bootstrap.py +310 -0
  11. onec_runtime/breakpoint_workspace.py +249 -0
  12. onec_runtime/bsl/__init__.py +139 -0
  13. onec_runtime/bsl/diagnostics.py +1046 -0
  14. onec_runtime/bsl/full_ast_worker_projection.py +522 -0
  15. onec_runtime/bsl/generated_semantic_parser.py +6322 -0
  16. onec_runtime/bsl/lexer.py +164 -0
  17. onec_runtime/bsl/module_catalog.py +420 -0
  18. onec_runtime/bsl/module_delta.py +1079 -0
  19. onec_runtime/bsl/module_universe.py +1877 -0
  20. onec_runtime/bsl/notebook_cells.py +232 -0
  21. onec_runtime/bsl/notebook_method_globals.py +74 -0
  22. onec_runtime/bsl/notebook_methods.py +175 -0
  23. onec_runtime/bsl/parser_artifact_identity.py +119 -0
  24. onec_runtime/bsl/parser_target.py +388 -0
  25. onec_runtime/bsl/preprocessor.py +16 -0
  26. onec_runtime/bsl/semantic_lowering.py +1539 -0
  27. onec_runtime/bsl/source_maps.py +2411 -0
  28. onec_runtime/bsl/worker_dependency_resolver.py +289 -0
  29. onec_runtime/bsl/worker_preprocessor.py +247 -0
  30. onec_runtime/bsl/worker_projection_model.py +137 -0
  31. onec_runtime/bsl/worker_reload_source_map.py +1697 -0
  32. onec_runtime/capture.py +113 -0
  33. onec_runtime/capture_source.py +453 -0
  34. onec_runtime/compact_table.py +376 -0
  35. onec_runtime/compact_table_backend.py +500 -0
  36. onec_runtime/config.py +198 -0
  37. onec_runtime/configurator_agent.py +520 -0
  38. onec_runtime/controller_worker.py +400 -0
  39. onec_runtime/credentials.py +18 -0
  40. onec_runtime/epf_container.py +196 -0
  41. onec_runtime/errors.py +205 -0
  42. onec_runtime/experiment.py +130 -0
  43. onec_runtime/extension_bundle.py +944 -0
  44. onec_runtime/extension_lifecycle.py +402 -0
  45. onec_runtime/extension_state.py +222 -0
  46. onec_runtime/fault_injection.py +30 -0
  47. onec_runtime/kernel.py +179 -0
  48. onec_runtime/lease.py +123 -0
  49. onec_runtime/observation.py +287 -0
  50. onec_runtime/performance_profile.py +245 -0
  51. onec_runtime/privacy.py +263 -0
  52. onec_runtime/processes.py +265 -0
  53. onec_runtime/prototype_runtime.py +2644 -0
  54. onec_runtime/rdbg/__init__.py +1 -0
  55. onec_runtime/rdbg/models.py +130 -0
  56. onec_runtime/rdbg/reconnect.py +59 -0
  57. onec_runtime/rdbg/session.py +913 -0
  58. onec_runtime/rdbg/transport.py +138 -0
  59. onec_runtime/rdbg/xml_codec.py +980 -0
  60. onec_runtime/recovery.py +106 -0
  61. onec_runtime/recovery_journal.py +79 -0
  62. onec_runtime/resources/extension/OnecInteractiveRuntime.cfe +0 -0
  63. onec_runtime/resources/extension/extension-manifest.json +108 -0
  64. onec_runtime/runtime_api.py +5272 -0
  65. onec_runtime/runtime_contracts.py +196 -0
  66. onec_runtime/server_worker.py +2034 -0
  67. onec_runtime/session.py +2123 -0
  68. onec_runtime/startup_diagnostics.py +45 -0
  69. onec_runtime/stop_routing.py +65 -0
  70. onec_runtime/supervised_processes.py +232 -0
  71. onec_runtime/supervised_runtime.py +512 -0
  72. onec_runtime/supervisor.py +363 -0
  73. onec_runtime/supervisor_model.py +148 -0
  74. onec_runtime/supervisor_protocol.py +77 -0
  75. onec_runtime/table_materialization.py +471 -0
  76. onec_runtime/table_transfer_backend.py +203 -0
  77. onec_runtime/table_value.py +311 -0
  78. onec_runtime/toolchain.py +730 -0
  79. onec_runtime/value_materialization.py +432 -0
  80. onec_runtime/value_transfer_backend.py +199 -0
  81. onec_runtime/worker_breakpoints.py +1431 -0
  82. onec_runtime/worker_epf.py +313 -0
  83. onec_runtime/worker_epf_template.py +53 -0
  84. onec_runtime/worker_stage_protocol.py +516 -0
  85. onec_runtime/worker_universe.py +3772 -0
  86. onec_runtime_build/__init__.py +1 -0
  87. onec_runtime_build/parser_target_development.py +116 -0
@@ -0,0 +1,313 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import replace
4
+ from hashlib import sha256
5
+ from pathlib import Path
6
+ from tempfile import NamedTemporaryFile
7
+ from uuid import UUID, uuid5
8
+
9
+ from onec_runtime.bsl.source_maps import (
10
+ MappedSource,
11
+ MappingRelation,
12
+ SourceArtifactKind,
13
+ SourceArtifactRef,
14
+ SourceMap,
15
+ SourceMapSegment,
16
+ SourceSpan,
17
+ SourceTransformBuilder,
18
+ SourceUnitRef,
19
+ _NORMALIZED_WORKER_AUTHORITY,
20
+ _observe_text_work,
21
+ _validated_mapped_text_hash,
22
+ source_sha256,
23
+ )
24
+ from onec_runtime.epf_container import (
25
+ EpfContainerError,
26
+ build_container,
27
+ raw_deflate,
28
+ raw_inflate,
29
+ read_container,
30
+ )
31
+ from onec_runtime.worker_epf_template import (
32
+ WORKER_COPYINFO,
33
+ WORKER_FILE_UUID,
34
+ WORKER_METADATA,
35
+ WORKER_MODULE_INFO,
36
+ WORKER_MODULE_STREAM,
37
+ WORKER_ROOT,
38
+ WORKER_STREAM_NAMES,
39
+ WORKER_VERSION,
40
+ )
41
+
42
+
43
+ _VERSION_NAMESPACE = UUID("42ff273a-cb53-4fd5-a844-34b27d69edb0")
44
+
45
+
46
+ def prepare_worker_module_source(source: MappedSource) -> MappedSource:
47
+ """Map a Worker projection to the exact normalized EPF object module text."""
48
+ if not isinstance(source, MappedSource):
49
+ raise ValueError("Worker module source must be a MappedSource")
50
+ _normalize_source(source.text)
51
+ source = _without_worker_generation_identity(source)
52
+ builder = SourceTransformBuilder(
53
+ source,
54
+ _normalized_parent_authority=_NORMALIZED_WORKER_AUTHORITY,
55
+ )
56
+ cursor = 0
57
+ index = 0
58
+ while index < len(source.text):
59
+ if source.text[index] != "\r":
60
+ index += 1
61
+ continue
62
+ if cursor < index:
63
+ builder.copy(SourceSpan(cursor, index))
64
+ end = index + 2 if source.text.startswith("\r\n", index) else index + 1
65
+ parent = next(
66
+ segment
67
+ for segment in source.source_map.segments
68
+ if segment.generated.start <= index < segment.generated.end
69
+ )
70
+ if end == index + 2 and parent.generated.end == index + 1:
71
+ cursor = index + 1
72
+ index = cursor
73
+ continue
74
+ region = (
75
+ parent.synthetic_region
76
+ if parent.relation is MappingRelation.DERIVED
77
+ and parent.synthetic_region is not None
78
+ else "worker_module_line_ending"
79
+ )
80
+ builder.derived("\n", SourceSpan(index, end), region)
81
+ cursor = end
82
+ index = end
83
+ if cursor < len(source.text):
84
+ builder.copy(SourceSpan(cursor, len(source.text)))
85
+ return builder.build(
86
+ SourceArtifactKind.WORKER_MODULE,
87
+ _normalized_worker_authority=_NORMALIZED_WORKER_AUTHORITY,
88
+ )
89
+
90
+
91
+ def _without_worker_generation_identity(source: MappedSource) -> MappedSource:
92
+ artifact = _without_generation_artifact_identity(source.artifact)
93
+ source_map = _without_generation_map_identity(source.source_map)
94
+ lineage = tuple(
95
+ _without_generation_map_identity(item)
96
+ for item in source.lineage
97
+ )
98
+ try:
99
+ source.local_source_map
100
+ except ValueError:
101
+ local = None
102
+ else:
103
+ local = lineage[-1]
104
+ if (
105
+ artifact == source.artifact
106
+ and source_map == source.source_map
107
+ and lineage == source.lineage
108
+ ):
109
+ return source
110
+ return MappedSource(
111
+ source.text,
112
+ artifact,
113
+ source_map,
114
+ lineage,
115
+ local,
116
+ )
117
+
118
+
119
+ def _without_generation_artifact_identity(
120
+ artifact: SourceArtifactRef,
121
+ ) -> SourceArtifactRef:
122
+ if artifact.worker_generation is None and artifact.worker_manifest_sha256 is None:
123
+ return artifact
124
+ return replace(
125
+ artifact,
126
+ worker_generation=None,
127
+ worker_manifest_sha256=None,
128
+ )
129
+
130
+
131
+ def _without_generation_map_identity(source_map: SourceMap) -> SourceMap:
132
+ def clean_reference(
133
+ reference: SourceArtifactRef | SourceUnitRef | None,
134
+ ) -> SourceArtifactRef | SourceUnitRef | None:
135
+ return (
136
+ _without_generation_artifact_identity(reference)
137
+ if isinstance(reference, SourceArtifactRef)
138
+ else reference
139
+ )
140
+
141
+ return SourceMap(
142
+ _without_generation_artifact_identity(source_map.generated),
143
+ tuple(
144
+ replace(
145
+ segment,
146
+ origin_ref=clean_reference(segment.origin_ref),
147
+ anchor_ref=clean_reference(segment.anchor_ref),
148
+ )
149
+ for segment in source_map.segments
150
+ ),
151
+ )
152
+
153
+
154
+ def _synthetic_worker_module_source(
155
+ source: str,
156
+ *,
157
+ normalize: bool = True,
158
+ ) -> MappedSource:
159
+ """Private compatibility adapter for legacy source-only Worker callers."""
160
+ normalized = _normalize_source(source) if normalize else source
161
+ if not normalize:
162
+ if not normalized.strip():
163
+ raise ValueError("Worker source is empty")
164
+ if "\x00" in normalized:
165
+ raise ValueError("Worker source contains a NUL character")
166
+ crlf_count = normalized.count("\r\n")
167
+ bare_lf_count = normalized.count("\n") - crlf_count
168
+ bare_cr_count = normalized.count("\r") - crlf_count
169
+ kinds = sum(count > 0 for count in (crlf_count, bare_lf_count, bare_cr_count))
170
+ line_ending_kind = (
171
+ "mixed"
172
+ if kinds > 1
173
+ else "crlf"
174
+ if crlf_count
175
+ else "lf"
176
+ if bare_lf_count
177
+ else "cr"
178
+ if bare_cr_count
179
+ else "none"
180
+ )
181
+ artifact = SourceArtifactRef(
182
+ SourceArtifactKind.WORKER_MODULE,
183
+ source_sha256(normalized),
184
+ len(normalized),
185
+ line_ending_kind,
186
+ )
187
+ source_map = SourceMap(
188
+ artifact,
189
+ (
190
+ SourceMapSegment(
191
+ SourceSpan(0, len(normalized)),
192
+ None,
193
+ None,
194
+ MappingRelation.SYNTHETIC,
195
+ "legacy_worker_source",
196
+ ),
197
+ ),
198
+ )
199
+ return MappedSource(normalized, artifact, source_map)
200
+
201
+
202
+ def build_worker_epf(source: str | MappedSource, output_path: Path) -> Path:
203
+ if isinstance(source, MappedSource):
204
+ normalized = source.text
205
+ source_hash = _validated_mapped_text_hash(source)
206
+ _observe_text_work("packaging_normalized_authority", len(normalized))
207
+ else:
208
+ _observe_text_work("packaging_normalize", len(source))
209
+ normalized = _normalize_source(source)
210
+ _observe_text_work("packaging_hash", len(normalized))
211
+ source_hash = sha256(normalized.encode("utf-8")).hexdigest()
212
+ nested_module = build_container(
213
+ {
214
+ "info": _encode_brace_text(WORKER_MODULE_INFO),
215
+ "text": _encode_source(normalized, observe=True),
216
+ }
217
+ )
218
+ streams = {
219
+ WORKER_FILE_UUID: _encode_brace_text(WORKER_METADATA),
220
+ WORKER_MODULE_STREAM: nested_module,
221
+ "copyinfo": _encode_brace_text(WORKER_COPYINFO),
222
+ "root": _encode_brace_text(WORKER_ROOT),
223
+ "version": _encode_brace_text(WORKER_VERSION),
224
+ "versions": _encode_brace_text(_versions(source_hash)),
225
+ }
226
+ artifact = build_container(
227
+ {name: raw_deflate(payload) for name, payload in streams.items()}
228
+ )
229
+ recovered = read_worker_source(artifact)
230
+ _observe_text_work("packaging_verify", len(recovered))
231
+ if recovered != normalized:
232
+ raise EpfContainerError("Generated Worker failed source self-verification")
233
+
234
+ output_path = output_path.resolve()
235
+ output_path.parent.mkdir(parents=True, exist_ok=True)
236
+ temporary: Path | None = None
237
+ try:
238
+ with NamedTemporaryFile(
239
+ mode="wb",
240
+ dir=output_path.parent,
241
+ prefix=f".{output_path.name}.",
242
+ suffix=".tmp",
243
+ delete=False,
244
+ ) as stream:
245
+ stream.write(artifact)
246
+ temporary = Path(stream.name)
247
+ temporary.replace(output_path)
248
+ finally:
249
+ if temporary is not None:
250
+ temporary.unlink(missing_ok=True)
251
+ return output_path
252
+
253
+
254
+ def read_worker_source(payload_or_path: bytes | Path) -> str:
255
+ payload = (
256
+ payload_or_path
257
+ if isinstance(payload_or_path, bytes)
258
+ else payload_or_path.read_bytes()
259
+ )
260
+ streams = read_container(payload)
261
+ if tuple(streams) != WORKER_STREAM_NAMES:
262
+ raise EpfContainerError("EPF is not the supported runtime Worker")
263
+ try:
264
+ nested = read_container(raw_inflate(streams[WORKER_MODULE_STREAM]))
265
+ except KeyError as error:
266
+ raise EpfContainerError("Worker object module stream is missing") from error
267
+ if tuple(nested) != ("info", "text"):
268
+ raise EpfContainerError("Worker object module container is invalid")
269
+ try:
270
+ info = nested["info"].decode("utf-8-sig")
271
+ source = nested["text"].decode("utf-8-sig")
272
+ except UnicodeDecodeError as error:
273
+ raise EpfContainerError("Worker object module is not UTF-8") from error
274
+ if _normalize_newlines(info) != WORKER_MODULE_INFO:
275
+ raise EpfContainerError("Worker object module metadata is invalid")
276
+ return _normalize_newlines(source)
277
+
278
+
279
+ def _normalize_source(source: str) -> str:
280
+ normalized = _normalize_newlines(source)
281
+ if not normalized.strip():
282
+ raise ValueError("Worker source is empty")
283
+ if "\x00" in normalized:
284
+ raise ValueError("Worker source contains a NUL character")
285
+ return normalized
286
+
287
+
288
+ def _normalize_newlines(value: str) -> str:
289
+ return value.replace("\r\n", "\n").replace("\r", "\n")
290
+
291
+
292
+ def _encode_source(source: str, *, observe: bool = False) -> bytes:
293
+ if observe:
294
+ _observe_text_work("packaging_encode", len(source))
295
+ return source.replace("\n", "\r\n").encode("utf-8-sig")
296
+
297
+
298
+ def _encode_brace_text(value: str) -> bytes:
299
+ return _encode_source(_normalize_newlines(value))
300
+
301
+
302
+ def _versions(source_hash: str) -> str:
303
+ version_names = ("", *WORKER_STREAM_NAMES)
304
+ items: list[str] = ["1", str(len(version_names))]
305
+ for name in version_names:
306
+ rendered_name = f'"{name}"' if name else '""'
307
+ items.extend(
308
+ (
309
+ rendered_name,
310
+ str(uuid5(_VERSION_NAMESPACE, f"{source_hash}:{name}")),
311
+ )
312
+ )
313
+ return "{" + ",".join(items) + "}"
@@ -0,0 +1,53 @@
1
+ from __future__ import annotations
2
+
3
+ """Readable fixed metadata for the one-object-module runtime Worker."""
4
+
5
+
6
+ WORKER_FILE_UUID = "2a00a4fa-8ea9-4dc4-9de1-472044c40101"
7
+ WORKER_OBJECT_UUID = "2a00a4fa-8ea9-4dc4-9de1-472044c40102"
8
+ WORKER_MODULE_STREAM = f"{WORKER_OBJECT_UUID}.0"
9
+
10
+ WORKER_METADATA = """{1,
11
+ {2a00a4fa-8ea9-4dc4-9de1-472044c40101},1,
12
+ {c3831ec8-d8d5-4f93-8a22-f9bfae07327f,
13
+ {1,
14
+ {4,2a00a4fa-8ea9-4dc4-9de1-472044c40103,2a00a4fa-8ea9-4dc4-9de1-472044c40104,
15
+ {0,
16
+ {3,
17
+ {1,0,2a00a4fa-8ea9-4dc4-9de1-472044c40102},"Worker",
18
+ {1,"ru","Runtime Worker"},"",0,0,00000000-0000-0000-0000-000000000000,0}
19
+ },00000000-0000-0000-0000-000000000000,"",00000000-0000-0000-0000-000000000000},4,
20
+ {2bcef0d1-0981-11d6-b9b8-0050bae0a95d,0},
21
+ {3daea016-69b7-4ed4-9453-127911372fe6,0},
22
+ {d5b0e5ed-256d-401c-9c36-f630cafd8a62,0},
23
+ {ec6bb5e5-b7a8-4d75-bec9-658107a699cf,0}
24
+ }
25
+ }
26
+ }"""
27
+
28
+ WORKER_COPYINFO = """{4,
29
+ {0},
30
+ {0},
31
+ {0},
32
+ {0,0},
33
+ {0}
34
+ }"""
35
+
36
+ WORKER_ROOT = "{2,2a00a4fa-8ea9-4dc4-9de1-472044c40101,}"
37
+
38
+ WORKER_VERSION = """{
39
+ {216,0,
40
+ {80327,0}
41
+ }
42
+ }"""
43
+
44
+ WORKER_MODULE_INFO = '{3,1,0,"",0}'
45
+
46
+ WORKER_STREAM_NAMES = (
47
+ WORKER_FILE_UUID,
48
+ WORKER_MODULE_STREAM,
49
+ "copyinfo",
50
+ "root",
51
+ "version",
52
+ "versions",
53
+ )