clm-kernel 0.0.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.
- clm/__init__.py +230 -0
- clm/__main__.py +25 -0
- clm/cross_cutting/__init__.py +50 -0
- clm/cross_cutting/_test_runner.py +36 -0
- clm/cross_cutting/async_utils.py +25 -0
- clm/cross_cutting/cel_builder.py +123 -0
- clm/cross_cutting/cel_converter.py +697 -0
- clm/cross_cutting/cel_engine.py +252 -0
- clm/cross_cutting/cel_ops.py +72 -0
- clm/cross_cutting/cel_ops_db.py +157 -0
- clm/cross_cutting/cel_ops_files.py +99 -0
- clm/cross_cutting/cel_ops_state.py +71 -0
- clm/cross_cutting/cel_ops_strings.py +64 -0
- clm/cross_cutting/cel_resolver.py +63 -0
- clm/cross_cutting/cel_slices.py +56 -0
- clm/cross_cutting/cel_store.py +330 -0
- clm/cross_cutting/clm_logger.py +140 -0
- clm/cross_cutting/config/__init__.py +155 -0
- clm/cross_cutting/config/config_constants.py +392 -0
- clm/cross_cutting/config/env_parameters.py +90 -0
- clm/cross_cutting/config/logging.py +378 -0
- clm/cross_cutting/config/settings.py +504 -0
- clm/cross_cutting/context.py +5 -0
- clm/cross_cutting/domain_models.py +55 -0
- clm/cross_cutting/domain_types.py +61 -0
- clm/cross_cutting/effects.py +67 -0
- clm/cross_cutting/errors.py +153 -0
- clm/cross_cutting/governance.py +331 -0
- clm/cross_cutting/guards.py +41 -0
- clm/cross_cutting/mcard.py +321 -0
- clm/cross_cutting/native.py +185 -0
- clm/cross_cutting/observability.py +289 -0
- clm/cross_cutting/pcard.py +434 -0
- clm/cross_cutting/registry.py +71 -0
- clm/cross_cutting/resources.py +84 -0
- clm/cross_cutting/secrets.py +44 -0
- clm/cross_cutting/subprocess_utils.py +118 -0
- clm/cross_cutting/telemetry.py +164 -0
- clm/cross_cutting/testing/__init__.py +8 -0
- clm/cross_cutting/testing/comparator.py +187 -0
- clm/cross_cutting/testing/datasets.py +87 -0
- clm/cross_cutting/timeutil.py +20 -0
- clm/cross_cutting/types/new_type_check.py +0 -0
- clm/cross_cutting/utils/__init__.py +1 -0
- clm/cross_cutting/utils/url_safety.py +50 -0
- clm/cross_cutting/vcard.py +560 -0
- clm/cross_cutting/writer.py +118 -0
- clm/layer0/README.md +50 -0
- clm/layer0/__init__.py +223 -0
- clm/layer0/algebra.py +60 -0
- clm/layer0/algebra_baldwin.py +133 -0
- clm/layer0/algebra_baldwin_generators.py +36 -0
- clm/layer0/algebra_equivalence.py +262 -0
- clm/layer0/algebra_ingest.py +306 -0
- clm/layer0/algebra_manifest_io.py +156 -0
- clm/layer0/assembler.py +481 -0
- clm/layer0/cel/__init__.py +23 -0
- clm/layer0/cel_eval.py +491 -0
- clm/layer0/codec.py +106 -0
- clm/layer0/context.py +122 -0
- clm/layer0/db.py +160 -0
- clm/layer0/exceptions.py +73 -0
- clm/layer0/fibration.py +106 -0
- clm/layer0/gates.py +50 -0
- clm/layer0/hash.py +80 -0
- clm/layer0/loader.py +826 -0
- clm/layer0/math_utils.py +163 -0
- clm/layer0/mcard.py +96 -0
- clm/layer0/model/__init__.py +0 -0
- clm/layer0/model/action.py +223 -0
- clm/layer0/model/card.py +280 -0
- clm/layer0/model/card_triad.py +427 -0
- clm/layer0/model/compatibility.py +60 -0
- clm/layer0/model/dictionary.py +46 -0
- clm/layer0/model/dots.py +331 -0
- clm/layer0/model/event_producer.py +88 -0
- clm/layer0/model/g_time.py +89 -0
- clm/layer0/model/handle.py +163 -0
- clm/layer0/model/hash/__init__.py +6 -0
- clm/layer0/model/hash/algorithms/__init__.py +3 -0
- clm/layer0/model/hash/algorithms/custom_hash.py +7 -0
- clm/layer0/model/hash/algorithms/local_sha256.py +178 -0
- clm/layer0/model/hash/constants.py +53 -0
- clm/layer0/model/hash/enums.py +60 -0
- clm/layer0/model/hash/validator.py +307 -0
- clm/layer0/model/interpreter.py +275 -0
- clm/layer0/model/pagination.py +45 -0
- clm/layer0/model/pcard.py +716 -0
- clm/layer0/model/schema.py +44 -0
- clm/layer0/model/utils/__init__.py +1 -0
- clm/layer0/model/utils/content_analyzer.py +152 -0
- clm/layer0/model/validators/__init__.py +1 -0
- clm/layer0/model/validators/base_validator.py +44 -0
- clm/layer0/model/validators/binary_validator.py +66 -0
- clm/layer0/model/validators/text_validator.py +82 -0
- clm/layer0/model/validators/validation_registry.py +49 -0
- clm/layer0/model/vcard.py +823 -0
- clm/layer0/model/vcard_ext/__init__.py +39 -0
- clm/layer0/model/vcard_ext/core.py +60 -0
- clm/layer0/model/vcard_ext/network.py +23 -0
- clm/layer0/model/vcard_ext/observability.py +63 -0
- clm/layer0/model/vcard_ext/storage.py +60 -0
- clm/layer0/model/vcard_ext/vendors.py +211 -0
- clm/layer0/model/vcard_sandwich.py +119 -0
- clm/layer0/model/vcard_vocabulary.py +463 -0
- clm/layer0/model/workflow.py +274 -0
- clm/layer0/narrative.py +431 -0
- clm/layer0/ontology/collection.py +125 -0
- clm/layer0/parser.py +429 -0
- clm/layer0/relations.py +73 -0
- clm/layer0/rule_evaluator.py +251 -0
- clm/layer0/schema/__init__.py +38 -0
- clm/layer0/schema/ddl.py +97 -0
- clm/layer0/templates/abstract.yaml +99 -0
- clm/layer0/templates/balanced.yaml +253 -0
- clm/layer0/templates/concrete.yaml +172 -0
- clm/layer0/type_registry.py +223 -0
- clm/layer0/types.py +204 -0
- clm/layer0/utils.py +886 -0
- clm/layer0/verifier_core.py +262 -0
- clm/layer1/__init__.py +31 -0
- clm/layer1/action_dispatcher.py +275 -0
- clm/layer1/adapter_registry.py +233 -0
- clm/layer1/algebra_baldwin_generators.py +192 -0
- clm/layer1/arrow_compiler.py +525 -0
- clm/layer1/batch_processor.py +152 -0
- clm/layer1/cel/__init__.py +27 -0
- clm/layer1/cel/builder.py +173 -0
- clm/layer1/engine.py +759 -0
- clm/layer1/engine_async.py +89 -0
- clm/layer1/eval_callback.py +49 -0
- clm/layer1/gate_composer.py +229 -0
- clm/layer1/hoare_sandwich.py +298 -0
- clm/layer1/identity_guard.py +348 -0
- clm/layer1/matrix.py +138 -0
- clm/layer1/neural_runtime.py +221 -0
- clm/layer1/operations/__init__.py +123 -0
- clm/layer1/operations/augment.py +156 -0
- clm/layer1/operations/base.py +109 -0
- clm/layer1/operations/builtins.py +338 -0
- clm/layer1/operations/dispatch.py +144 -0
- clm/layer1/operations/exclude.py +107 -0
- clm/layer1/operations/handle.py +197 -0
- clm/layer1/operations/identity.py +139 -0
- clm/layer1/operations/invert.py +66 -0
- clm/layer1/operations/loader.py +116 -0
- clm/layer1/operations/manipulators/__init__.py +23 -0
- clm/layer1/operations/manipulators/document.py +211 -0
- clm/layer1/operations/manipulators/media.py +134 -0
- clm/layer1/operations/manipulators/structured.py +159 -0
- clm/layer1/operations/manipulators/tabular.py +334 -0
- clm/layer1/operations/port.py +65 -0
- clm/layer1/operations/services.py +529 -0
- clm/layer1/operations/split.py +117 -0
- clm/layer1/operations/substitute.py +75 -0
- clm/layer1/petri.py +1052 -0
- clm/layer1/pocketflow_orchestrator.py +408 -0
- clm/layer1/pocketflow_scheduler.py +519 -0
- clm/layer1/protocols.py +197 -0
- clm/layer1/runtime_adapter.py +718 -0
- clm/layer1/runtimes/__init__.py +71 -0
- clm/layer1/runtimes/_generated_assertions.py +125 -0
- clm/layer1/runtimes/_generated_types.py +42 -0
- clm/layer1/runtimes/base.py +265 -0
- clm/layer1/runtimes/binary.py +101 -0
- clm/layer1/runtimes/factory.py +203 -0
- clm/layer1/runtimes/javascript.py +321 -0
- clm/layer1/runtimes/javascript_runtime.js +33 -0
- clm/layer1/runtimes/js_scripts/isomorphism.mjs +22 -0
- clm/layer1/runtimes/js_scripts/loader.mjs +52 -0
- clm/layer1/runtimes/lambda_calc.py +126 -0
- clm/layer1/runtimes/python.py +288 -0
- clm/layer1/runtimes/python_runtime.py +41 -0
- clm/layer1/runtimes/script.py +114 -0
- clm/layer1/sandbox.py +334 -0
- clm/layer1/savepoint_guard.py +136 -0
- clm/layer1/sparse_net.py +122 -0
- clm/layer1/spec_tester.py +165 -0
- clm/layer1/store.py +295 -0
- clm/layer1/test_runner.py +498 -0
- clm/layer1/type_inspector.py +166 -0
- clm/layer1/verifier.py +772 -0
- clm/layer1/vm.py +91 -0
- clm/layer2/__init__.py +78 -0
- clm/layer2/card_collection.py +678 -0
- clm/layer2/classifier.py +479 -0
- clm/layer2/engine/__init__.py +1 -0
- clm/layer2/engine/abstract_sql_engine.py +320 -0
- clm/layer2/engine/base.py +193 -0
- clm/layer2/engine/duckdb_engine.py +576 -0
- clm/layer2/engine/sqlite_engine.py +518 -0
- clm/layer2/fiber/__init__.py +31 -0
- clm/layer2/fiber/context.py +89 -0
- clm/layer2/fiber/disposable.py +163 -0
- clm/layer2/fiber/fiber.py +125 -0
- clm/layer2/fiber/hoare.py +191 -0
- clm/layer2/file_io.py +376 -0
- clm/layer2/file_registrar.py +77 -0
- clm/layer2/ingest.py +202 -0
- clm/layer2/lineage.py +322 -0
- clm/layer2/mcard_fs.py +262 -0
- clm/layer2/merkle.py +11 -0
- clm/layer2/mime.py +244 -0
- clm/layer2/mime_detector.py +245 -0
- clm/layer2/private_collection.py +118 -0
- clm/layer2/shared_store.py +11 -0
- clm/layer2/storage/__init__.py +190 -0
- clm/layer2/storage/db_bitemporal.py +141 -0
- clm/layer2/storage/db_driver.py +331 -0
- clm/layer2/storage/db_hyperlinks.py +214 -0
- clm/layer2/storage/db_pool.py +139 -0
- clm/layer2/storage/db_repository.py +229 -0
- clm/layer2/storage/savepoint.py +78 -0
- clm/layer2/storage/sqlite_wal.py +74 -0
- clm/layer2/tridb.py +245 -0
- clm/layer2/vcard_receipt.py +71 -0
- clm/layer2/vfs.py +17 -0
- clm/layer3/__init__.py +141 -0
- clm/layer3/agency/__init__.py +19 -0
- clm/layer3/agency/config.py +220 -0
- clm/layer3/agency/providers/__init__.py +15 -0
- clm/layer3/agency/providers/base.py +91 -0
- clm/layer3/agency/providers/mlc_llm.py +169 -0
- clm/layer3/agency/providers/ollama.py +203 -0
- clm/layer3/agency/router.py +71 -0
- clm/layer3/agency/runtime.py +524 -0
- clm/layer3/gateway.py +353 -0
- clm/layer3/open_interpreter_adapter.py +159 -0
- clm/layer3/rag/__init__.py +70 -0
- clm/layer3/rag/cli.py +228 -0
- clm/layer3/rag/config.py +153 -0
- clm/layer3/rag/embeddings/__init__.py +16 -0
- clm/layer3/rag/embeddings/base.py +79 -0
- clm/layer3/rag/embeddings/ollama.py +211 -0
- clm/layer3/rag/embeddings/vision.py +290 -0
- clm/layer3/rag/engine.py +276 -0
- clm/layer3/rag/graph/__init__.py +22 -0
- clm/layer3/rag/graph/community.py +198 -0
- clm/layer3/rag/graph/engine.py +433 -0
- clm/layer3/rag/graph/extractor.py +255 -0
- clm/layer3/rag/graph/schema.py +115 -0
- clm/layer3/rag/graph/store.py +641 -0
- clm/layer3/rag/indexer.py +333 -0
- clm/layer3/rag/llm_providers.json +52 -0
- clm/layer3/rag/semantic_versioning.py +313 -0
- clm/layer3/rag/vector/__init__.py +28 -0
- clm/layer3/rag/vector/handle_vector_store.py +749 -0
- clm/layer3/rag/vector/schema.py +151 -0
- clm/layer3/rag/vector/store.py +632 -0
- clm/layer3/reticulum/__init__.py +55 -0
- clm/layer3/reticulum/bridge.py +74 -0
- clm/layer3/reticulum/daemon.py +88 -0
- clm/layer3/reticulum/discovery.py +164 -0
- clm/layer3/reticulum/identity.py +107 -0
- clm/layer3/reticulum/media.py +148 -0
- clm/layer3/reticulum/transport.py +133 -0
- clm/layer3/satori/__init__.py +209 -0
- clm/layer3/satori/alpha_conversion.py +168 -0
- clm/layer3/satori/beta_reduction.py +359 -0
- clm/layer3/satori/continuation.py +38 -0
- clm/layer3/satori/eta_conversion.py +205 -0
- clm/layer3/satori/free_variables.py +163 -0
- clm/layer3/satori/io_effects.py +370 -0
- clm/layer3/satori/lambda_runtime.py +726 -0
- clm/layer3/satori/lambda_term.py +230 -0
- clm/layer3/satori/sheaf_audit.py +261 -0
- clm/layer3/satori/speech_act.py +279 -0
- clm/layer4/README.md +9 -0
- clm/layer4/__init__.py +67 -0
- clm/layer4/_sovereign_executor.py +580 -0
- clm/layer4/action_commands.py +719 -0
- clm/layer4/api.py +236 -0
- clm/layer4/bootstrap/__init__.py +13 -0
- clm/layer4/bootstrap/bootstrapper.py +118 -0
- clm/layer4/bootstrap/cleanup.py +44 -0
- clm/layer4/bootstrap/clm_hooks.py +49 -0
- clm/layer4/bootstrap/genesis.py +77 -0
- clm/layer4/bootstrap/injection.py +125 -0
- clm/layer4/cli.py +549 -0
- clm/layer4/collection_manager.py +553 -0
- clm/layer4/commands/__init__.py +81 -0
- clm/layer4/commands/action_cmd.py +42 -0
- clm/layer4/commands/check_cmd.py +82 -0
- clm/layer4/commands/envelope.py +73 -0
- clm/layer4/commands/evaluate_cmd.py +224 -0
- clm/layer4/commands/mcard_cmd.py +24 -0
- clm/layer4/commands/petri_cmd.py +92 -0
- clm/layer4/commands/tridb_cmd.py +319 -0
- clm/layer4/commands/version_cmd.py +27 -0
- clm/layer4/diff_commands.py +167 -0
- clm/layer4/eoa_sponsor.py +232 -0
- clm/layer4/events.py +69 -0
- clm/layer4/flux_gateway.py +133 -0
- clm/layer4/gateway.py +91 -0
- clm/layer4/loader.py +307 -0
- clm/layer4/mcard_commands.py +166 -0
- clm/layer4/membrane.py +273 -0
- clm/layer4/navigation.py +50 -0
- clm/layer4/protocol/protocol_entry_python.py +108 -0
- clm/layer4/protocol/python_sync.py +126 -0
- clm/layer4/runner.py +150 -0
- clm/layer4/satori.py +262 -0
- clm/layer4/server/python_sync_client.py +150 -0
- clm/layer4/server/python_sync_server.py +139 -0
- clm/layer4/server/service_api.py +315 -0
- clm/layer4/server/start_servers.py +107 -0
- clm/layer4/server/stop_servers.py +24 -0
- clm/layer4/simulated_optimization_fix.py +0 -0
- clm/layer4/storage.py +463 -0
- clm/layer4/tridb_admin.py +268 -0
- clm/layer4/websocket/test_ws_client.py +104 -0
- clm/layer4/websocket/test_ws_server.py +138 -0
- clm/layer4/websocket/ws_server_local.py +160 -0
- clm/layer5/__init__.py +51 -0
- clm/layer5/async_batch_writer.py +133 -0
- clm/layer5/learning.py +276 -0
- clm/layer5/telemetry_hook.py +107 -0
- clm/layer5/type_lattice.py +238 -0
- clm/py.typed +0 -0
- clm/schemas/__init__.py +652 -0
- clm/schemas/abstract_face_schema.yaml +77 -0
- clm/schemas/cel_schema.yaml +416 -0
- clm/schemas/lifecycle/__init__.py +45 -0
- clm/schemas/lifecycle/models.py +123 -0
- clm/schemas/lifecycle/service.py +364 -0
- clm/schemas/mcard_schema.sql +192 -0
- clm/schemas/mcard_vector_schema.sql +283 -0
- clm/schemas/mlp-context-v1.json +91 -0
- clm_kernel-0.0.0.dist-info/METADATA +121 -0
- clm_kernel-0.0.0.dist-info/RECORD +333 -0
- clm_kernel-0.0.0.dist-info/WHEEL +4 -0
- clm_kernel-0.0.0.dist-info/entry_points.txt +3 -0
- clm_kernel-0.0.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Runtimes Module for PTR
|
|
3
|
+
========================
|
|
4
|
+
|
|
5
|
+
This module provides modular runtime executor implementations.
|
|
6
|
+
|
|
7
|
+
Organization:
|
|
8
|
+
- base.py: Core abstractions (RuntimeExecutor, SubprocessRuntime, enums)
|
|
9
|
+
- python.py: PythonRuntime (in-process Python execution)
|
|
10
|
+
- javascript.py: JavaScriptRuntime (Node.js/Deno execution)
|
|
11
|
+
- binary.py: BinaryRuntime, RustRuntime, CRuntime
|
|
12
|
+
- script.py: ScriptRuntime, LeanRuntime, RRuntime, JuliaRuntime
|
|
13
|
+
- lambda_calc.py: LambdaRuntimeExecutor
|
|
14
|
+
- factory.py: RuntimeFactory
|
|
15
|
+
|
|
16
|
+
For backward compatibility, the main runtime.py re-exports all classes.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from .base import (
|
|
20
|
+
DEFAULT_TIMEOUT,
|
|
21
|
+
JULIA_TIMEOUT,
|
|
22
|
+
LEAN_TIMEOUT,
|
|
23
|
+
R_TIMEOUT,
|
|
24
|
+
RUNTIME_CONFIG,
|
|
25
|
+
BoundaryType,
|
|
26
|
+
RuntimeExecutor,
|
|
27
|
+
RuntimeType,
|
|
28
|
+
SubprocessRuntime,
|
|
29
|
+
)
|
|
30
|
+
from .binary import BinaryRuntime, CRuntime, RustRuntime
|
|
31
|
+
from .factory import RuntimeFactory
|
|
32
|
+
from .javascript import JavaScriptRuntime
|
|
33
|
+
from .lambda_calc import LambdaRuntimeExecutor
|
|
34
|
+
from .python import PythonRuntime
|
|
35
|
+
from .script import JuliaRuntime, LeanRuntime, RRuntime, ScriptRuntime
|
|
36
|
+
|
|
37
|
+
__all__ = [
|
|
38
|
+
# Enums
|
|
39
|
+
"RuntimeType",
|
|
40
|
+
"BoundaryType",
|
|
41
|
+
# Base classes
|
|
42
|
+
"RuntimeExecutor",
|
|
43
|
+
"SubprocessRuntime",
|
|
44
|
+
# Configuration
|
|
45
|
+
"DEFAULT_TIMEOUT",
|
|
46
|
+
"LEAN_TIMEOUT",
|
|
47
|
+
"JULIA_TIMEOUT",
|
|
48
|
+
"R_TIMEOUT",
|
|
49
|
+
"RUNTIME_CONFIG",
|
|
50
|
+
# Runtime implementations
|
|
51
|
+
"PythonRuntime",
|
|
52
|
+
"JavaScriptRuntime",
|
|
53
|
+
"BinaryRuntime",
|
|
54
|
+
"RustRuntime",
|
|
55
|
+
"CRuntime",
|
|
56
|
+
"ScriptRuntime",
|
|
57
|
+
"LeanRuntime",
|
|
58
|
+
"RRuntime",
|
|
59
|
+
"JuliaRuntime",
|
|
60
|
+
"LambdaRuntimeExecutor",
|
|
61
|
+
# Factory
|
|
62
|
+
"RuntimeFactory",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
# Register RuntimeFactory with Layer 0 loader (Dependency Inversion for INV-383-02)
|
|
66
|
+
try:
|
|
67
|
+
from clm.layer0.loader import register_runtime_factory
|
|
68
|
+
|
|
69
|
+
register_runtime_factory(RuntimeFactory)
|
|
70
|
+
except ImportError:
|
|
71
|
+
pass
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# AUTO-GENERATED FILE — DO NOT EDIT
|
|
2
|
+
# Generated by scripts/generate_constants.py
|
|
3
|
+
# Source: schema/assertion_types.json (single source of truth)
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Auto-generated CLM assertion validators.
|
|
7
|
+
|
|
8
|
+
These functions implement the cross-language assertion contracts
|
|
9
|
+
defined in schema/assertion_types.json, ensuring identical validation
|
|
10
|
+
behavior in both Python and TypeScript.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def assert_result(actual: Any, expected: Any) -> bool:
|
|
18
|
+
"""Exact deep-equality match (assertion_types.json: result)."""
|
|
19
|
+
if isinstance(expected, dict) and isinstance(actual, dict):
|
|
20
|
+
return all(
|
|
21
|
+
k in actual and assert_result(actual[k], v) for k, v in expected.items()
|
|
22
|
+
)
|
|
23
|
+
if isinstance(expected, list) and isinstance(actual, list):
|
|
24
|
+
return len(expected) == len(actual) and all(
|
|
25
|
+
assert_result(a, e) for a, e in zip(actual, expected, strict=False)
|
|
26
|
+
)
|
|
27
|
+
if isinstance(expected, int | float) and isinstance(actual, int | float):
|
|
28
|
+
return abs(expected - actual) < 1e-6
|
|
29
|
+
return expected == actual
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def assert_result_contains(actual: Any, substring: str) -> bool:
|
|
33
|
+
"""Substring match, case-insensitive (assertion_types.json: result_contains)."""
|
|
34
|
+
actual_str = json.dumps(actual) if not isinstance(actual, str) else actual
|
|
35
|
+
return substring.lower() in actual_str.lower()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def assert_result_type(actual: Any, expected_type: str) -> bool:
|
|
39
|
+
"""Type check (assertion_types.json: result_type)."""
|
|
40
|
+
type_map: dict[str, type | tuple[type, ...]] = {
|
|
41
|
+
"object": dict,
|
|
42
|
+
"string": str,
|
|
43
|
+
"number": (int, float),
|
|
44
|
+
"array": list,
|
|
45
|
+
"boolean": bool,
|
|
46
|
+
}
|
|
47
|
+
expected_cls = type_map.get(expected_type)
|
|
48
|
+
if expected_cls is None:
|
|
49
|
+
return False
|
|
50
|
+
return isinstance(actual, expected_cls)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def assert_schema(actual: Any, schema: dict) -> bool:
|
|
54
|
+
"""Structural validation (assertion_types.json: schema).
|
|
55
|
+
|
|
56
|
+
Validates that actual matches the given schema structure:
|
|
57
|
+
- type: expected type
|
|
58
|
+
- required: list of required keys
|
|
59
|
+
- properties: nested schemas for object properties
|
|
60
|
+
- minLength/maxLength: for strings/arrays
|
|
61
|
+
- min/max: for numbers
|
|
62
|
+
- enum: list of allowed values
|
|
63
|
+
- items: schema for array items
|
|
64
|
+
"""
|
|
65
|
+
if not isinstance(schema, dict):
|
|
66
|
+
return True
|
|
67
|
+
|
|
68
|
+
# Type check
|
|
69
|
+
if "type" in schema:
|
|
70
|
+
if not assert_result_type(actual, schema["type"]):
|
|
71
|
+
return False
|
|
72
|
+
|
|
73
|
+
# Required keys
|
|
74
|
+
if "required" in schema and isinstance(actual, dict):
|
|
75
|
+
for key in schema["required"]:
|
|
76
|
+
if key not in actual:
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
# Properties
|
|
80
|
+
if "properties" in schema and isinstance(actual, dict):
|
|
81
|
+
for key, sub_schema in schema["properties"].items():
|
|
82
|
+
if key in actual:
|
|
83
|
+
if not assert_schema(actual[key], sub_schema):
|
|
84
|
+
return False
|
|
85
|
+
|
|
86
|
+
# Length checks (strings/arrays)
|
|
87
|
+
if "minLength" in schema and hasattr(actual, "__len__"):
|
|
88
|
+
if len(actual) < schema["minLength"]:
|
|
89
|
+
return False
|
|
90
|
+
if "maxLength" in schema and hasattr(actual, "__len__"):
|
|
91
|
+
if len(actual) > schema["maxLength"]:
|
|
92
|
+
return False
|
|
93
|
+
if "length" in schema and hasattr(actual, "__len__"):
|
|
94
|
+
if len(actual) != schema["length"]:
|
|
95
|
+
return False
|
|
96
|
+
|
|
97
|
+
# Numeric range
|
|
98
|
+
if "min" in schema and isinstance(actual, int | float):
|
|
99
|
+
if actual < schema["min"]:
|
|
100
|
+
return False
|
|
101
|
+
if "max" in schema and isinstance(actual, int | float):
|
|
102
|
+
if actual > schema["max"]:
|
|
103
|
+
return False
|
|
104
|
+
|
|
105
|
+
# Enum
|
|
106
|
+
if "enum" in schema:
|
|
107
|
+
if actual not in schema["enum"]:
|
|
108
|
+
return False
|
|
109
|
+
|
|
110
|
+
# Array items
|
|
111
|
+
if "items" in schema and isinstance(actual, list):
|
|
112
|
+
for item in actual:
|
|
113
|
+
if not assert_schema(item, schema["items"]):
|
|
114
|
+
return False
|
|
115
|
+
|
|
116
|
+
return True
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
# Map assertion type names to validator functions
|
|
120
|
+
ASSERTION_VALIDATORS = {
|
|
121
|
+
"result": assert_result,
|
|
122
|
+
"result_contains": assert_result_contains,
|
|
123
|
+
"result_type": assert_result_type,
|
|
124
|
+
"schema": assert_schema,
|
|
125
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# AUTO-GENERATED FILE — DO NOT EDIT
|
|
2
|
+
# Generated by scripts/generate_constants.py
|
|
3
|
+
# Source: schema/runtime_types.json (single source of truth)
|
|
4
|
+
|
|
5
|
+
"""Auto-generated runtime type constants from schema/runtime_types.json."""
|
|
6
|
+
|
|
7
|
+
from enum import Enum
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class RuntimeType(Enum):
|
|
11
|
+
"""Supported runtime types (auto-generated from schema/runtime_types.json)."""
|
|
12
|
+
|
|
13
|
+
PYTHON = "python"
|
|
14
|
+
JAVASCRIPT = "javascript"
|
|
15
|
+
RUST = "rust"
|
|
16
|
+
C = "c"
|
|
17
|
+
WASM = "wasm"
|
|
18
|
+
LEAN = "lean"
|
|
19
|
+
R = "r"
|
|
20
|
+
JULIA = "julia"
|
|
21
|
+
LLM = "llm"
|
|
22
|
+
LAMBDA = "lambda"
|
|
23
|
+
NETWORK = "network"
|
|
24
|
+
LOADER = "loader"
|
|
25
|
+
COLLECTION_LOADER = "collection_loader"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
RUNTIME_ALIASES: dict[str, str] = {
|
|
29
|
+
"node": "javascript",
|
|
30
|
+
"js": "javascript",
|
|
31
|
+
"py": "python",
|
|
32
|
+
"ts": "javascript",
|
|
33
|
+
}
|
|
34
|
+
"""Maps shorthand names to canonical runtime IDs."""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def resolve_runtime_alias(name: str) -> str:
|
|
38
|
+
"""Resolve a runtime name through shared aliases.
|
|
39
|
+
|
|
40
|
+
E.g., 'node' -> 'javascript', 'py' -> 'python'.
|
|
41
|
+
"""
|
|
42
|
+
return RUNTIME_ALIASES.get(name.lower(), name.lower())
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base classes for runtime executors.
|
|
3
|
+
|
|
4
|
+
This module provides the core abstractions for runtime execution:
|
|
5
|
+
- RuntimeType: Enum of supported runtimes
|
|
6
|
+
- BoundaryType: Enum for intrinsic/extrinsic execution
|
|
7
|
+
- RuntimeExecutor: Abstract base class for all runtimes
|
|
8
|
+
- SubprocessRuntime: Base class for runtimes that execute via subprocess
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
import subprocess
|
|
13
|
+
from abc import ABC, abstractmethod
|
|
14
|
+
from enum import Enum
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
18
|
+
# Configuration Constants
|
|
19
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
20
|
+
from clm.cross_cutting.config.config_constants import (
|
|
21
|
+
PTR_COMMAND_CHECK_TIMEOUT_SECS,
|
|
22
|
+
PTR_DEFAULT_TIMEOUT_SECS,
|
|
23
|
+
PTR_JULIA_TIMEOUT_SECS,
|
|
24
|
+
PTR_LEAN_TIMEOUT_SECS,
|
|
25
|
+
PTR_R_TIMEOUT_SECS,
|
|
26
|
+
)
|
|
27
|
+
from clm.layer0.model.card import MCard
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
from clm.cross_cutting.config.settings import settings as _settings
|
|
31
|
+
|
|
32
|
+
DEFAULT_TIMEOUT = _settings.ptr.default_timeout
|
|
33
|
+
LEAN_TIMEOUT = _settings.ptr.lean_timeout
|
|
34
|
+
JULIA_TIMEOUT = _settings.ptr.julia_timeout
|
|
35
|
+
R_TIMEOUT = _settings.ptr.r_timeout
|
|
36
|
+
except ImportError:
|
|
37
|
+
DEFAULT_TIMEOUT = PTR_DEFAULT_TIMEOUT_SECS
|
|
38
|
+
LEAN_TIMEOUT = PTR_LEAN_TIMEOUT_SECS
|
|
39
|
+
JULIA_TIMEOUT = PTR_JULIA_TIMEOUT_SECS
|
|
40
|
+
R_TIMEOUT = PTR_R_TIMEOUT_SECS
|
|
41
|
+
|
|
42
|
+
# Global Runtime Registry
|
|
43
|
+
RUNTIME_REGISTRY = {}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def register_runtime(runtime_id: str):
|
|
47
|
+
"""Decorator to register a runtime executor in the global registry."""
|
|
48
|
+
|
|
49
|
+
def wrapper(cls):
|
|
50
|
+
RUNTIME_REGISTRY[runtime_id] = cls
|
|
51
|
+
return cls
|
|
52
|
+
|
|
53
|
+
return wrapper
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
57
|
+
# Runtime Types (shared source of truth: schema/runtime_types.json)
|
|
58
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _load_shared_runtime_types() -> tuple[list[str], dict[str, str], dict]:
|
|
62
|
+
"""Load runtime type IDs, aliases, and explicit configs from the shared JSON registry.
|
|
63
|
+
|
|
64
|
+
Returns (runtime_ids, aliases, runtime_configs) tuple.
|
|
65
|
+
Falls back to empty collections if file is not found.
|
|
66
|
+
"""
|
|
67
|
+
import json
|
|
68
|
+
from pathlib import Path
|
|
69
|
+
|
|
70
|
+
module_dir = Path(__file__).resolve().parent
|
|
71
|
+
# Calculate project root: runtimes -> core -> ptr -> mcard -> project root
|
|
72
|
+
project_root = module_dir.parents[3]
|
|
73
|
+
schema_path = project_root / "schema" / "runtime_types.json"
|
|
74
|
+
|
|
75
|
+
if schema_path.exists():
|
|
76
|
+
try:
|
|
77
|
+
with open(schema_path, encoding="utf-8") as f:
|
|
78
|
+
data = json.load(f)
|
|
79
|
+
ids = [r["id"] for r in data.get("runtimes", [])]
|
|
80
|
+
aliases = data.get("aliases", {})
|
|
81
|
+
|
|
82
|
+
# Build runtime config
|
|
83
|
+
configs = {}
|
|
84
|
+
for r in data.get("runtimes", []):
|
|
85
|
+
configs[r["id"]] = {
|
|
86
|
+
"command": r.get("command"),
|
|
87
|
+
"version_flag": r.get("version_flag", "--version"),
|
|
88
|
+
"run_flag": r.get("run_flag"),
|
|
89
|
+
"eval_flag": r.get("eval_flag"),
|
|
90
|
+
}
|
|
91
|
+
return ids, aliases, configs
|
|
92
|
+
except Exception as e:
|
|
93
|
+
logging.warning("Failed to load runtime_types.json: %s", e)
|
|
94
|
+
return [], {}, {}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# Load shared data at import time
|
|
98
|
+
_SHARED_RUNTIME_IDS, SHARED_ALIASES, RUNTIME_CONFIG = _load_shared_runtime_types()
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class RuntimeType(Enum):
|
|
102
|
+
"""Supported runtime types.
|
|
103
|
+
|
|
104
|
+
IDs are aligned with schema/runtime_types.json (single source of truth).
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
PYTHON = "python"
|
|
108
|
+
JAVASCRIPT = "javascript"
|
|
109
|
+
RUST = "rust"
|
|
110
|
+
C = "c"
|
|
111
|
+
WASM = "wasm"
|
|
112
|
+
LEAN = "lean"
|
|
113
|
+
R = "r"
|
|
114
|
+
JULIA = "julia"
|
|
115
|
+
LLM = "llm"
|
|
116
|
+
LAMBDA = "lambda"
|
|
117
|
+
LOADER = "loader"
|
|
118
|
+
COLLECTION_LOADER = "collection_loader"
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def resolve_runtime_alias(name: str) -> str:
|
|
122
|
+
"""Resolve a runtime name through shared aliases.
|
|
123
|
+
|
|
124
|
+
E.g., 'node' -> 'javascript', 'py' -> 'python', 'js' -> 'javascript'.
|
|
125
|
+
Returns the canonical runtime ID.
|
|
126
|
+
"""
|
|
127
|
+
return SHARED_ALIASES.get(name.lower(), name.lower())
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class BoundaryType(Enum):
|
|
131
|
+
"""CLM execution boundary type.
|
|
132
|
+
|
|
133
|
+
Determines how a CLM is executed relative to the caller:
|
|
134
|
+
|
|
135
|
+
INTRINSIC: Process runs within the same execution context (same process).
|
|
136
|
+
Best for lightweight, trusted operations. No serialization overhead.
|
|
137
|
+
|
|
138
|
+
EXTRINSIC: Process runs in a separate process/container/network.
|
|
139
|
+
Required for untrusted code, language isolation, or distributed execution.
|
|
140
|
+
Requires serialization/deserialization of inputs and outputs.
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
INTRINSIC = "intrinsic"
|
|
144
|
+
EXTRINSIC = "extrinsic"
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
148
|
+
# Base Executor Classes
|
|
149
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class RuntimeExecutor(ABC):
|
|
153
|
+
"""Abstract base class for runtime executors.
|
|
154
|
+
|
|
155
|
+
Each executor manages a specific runtime environment (Python, JavaScript, etc.)
|
|
156
|
+
and can operate in either intrinsic or extrinsic boundary mode.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
# Default boundary type for this runtime
|
|
160
|
+
boundary_type: BoundaryType = BoundaryType.INTRINSIC
|
|
161
|
+
|
|
162
|
+
def __init__(self):
|
|
163
|
+
self.logger = logging.getLogger(self.__class__.__name__)
|
|
164
|
+
|
|
165
|
+
@abstractmethod
|
|
166
|
+
def execute(
|
|
167
|
+
self, concrete_impl: dict[str, Any], target: MCard, context: dict[str, Any]
|
|
168
|
+
) -> Any:
|
|
169
|
+
"""Execute the operation in the runtime environment."""
|
|
170
|
+
pass
|
|
171
|
+
|
|
172
|
+
@abstractmethod
|
|
173
|
+
def validate_environment(self) -> bool:
|
|
174
|
+
"""Check if runtime environment is available."""
|
|
175
|
+
pass
|
|
176
|
+
|
|
177
|
+
def get_boundary_type(self) -> BoundaryType:
|
|
178
|
+
"""Get the boundary type for this runtime.
|
|
179
|
+
|
|
180
|
+
Override in subclasses to provide dynamic boundary determination.
|
|
181
|
+
"""
|
|
182
|
+
return self.boundary_type
|
|
183
|
+
|
|
184
|
+
def is_intrinsic(self) -> bool:
|
|
185
|
+
"""Check if this runtime operates within the same process."""
|
|
186
|
+
return self.get_boundary_type() == BoundaryType.INTRINSIC
|
|
187
|
+
|
|
188
|
+
def is_extrinsic(self) -> bool:
|
|
189
|
+
"""Check if this runtime operates in a separate process."""
|
|
190
|
+
return self.get_boundary_type() == BoundaryType.EXTRINSIC
|
|
191
|
+
|
|
192
|
+
def get_runtime_status(self) -> dict[str, Any]:
|
|
193
|
+
"""Get detailed status information about this runtime."""
|
|
194
|
+
return {
|
|
195
|
+
"available": self.validate_environment(),
|
|
196
|
+
"version": None,
|
|
197
|
+
"command": self.__class__.__name__.replace("Runtime", "").lower(),
|
|
198
|
+
"details": "",
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class SubprocessRuntime(RuntimeExecutor):
|
|
203
|
+
"""
|
|
204
|
+
Base class for runtimes that execute via subprocess.
|
|
205
|
+
Reduces duplication across Rust/C/Lean/R/Julia.
|
|
206
|
+
|
|
207
|
+
Note: Subprocess runtimes are EXTRINSIC - they run in separate processes.
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
# Subprocess runtimes are extrinsic by default
|
|
211
|
+
boundary_type: BoundaryType = BoundaryType.EXTRINSIC
|
|
212
|
+
|
|
213
|
+
runtime_name: str = ""
|
|
214
|
+
command: str | None = None
|
|
215
|
+
version_flag: str = "--version"
|
|
216
|
+
timeout: int = DEFAULT_TIMEOUT
|
|
217
|
+
|
|
218
|
+
def _run_subprocess(
|
|
219
|
+
self,
|
|
220
|
+
cmd: list[str],
|
|
221
|
+
target: MCard,
|
|
222
|
+
context: dict,
|
|
223
|
+
timeout: int | None = None,
|
|
224
|
+
) -> str:
|
|
225
|
+
"""Execute subprocess and return output or error string."""
|
|
226
|
+
try:
|
|
227
|
+
result = subprocess.run(
|
|
228
|
+
cmd,
|
|
229
|
+
input=target.get_content(),
|
|
230
|
+
capture_output=True,
|
|
231
|
+
timeout=timeout or self.timeout,
|
|
232
|
+
)
|
|
233
|
+
if result.returncode != 0:
|
|
234
|
+
return f"Error: {self.runtime_name} execution failed: {result.stderr.decode()}"
|
|
235
|
+
return result.stdout.decode("utf-8")
|
|
236
|
+
except subprocess.TimeoutExpired:
|
|
237
|
+
return f"Error: {self.runtime_name} execution timed out"
|
|
238
|
+
except (OSError, subprocess.SubprocessError) as e:
|
|
239
|
+
return f"Error executing {self.runtime_name}: {e}"
|
|
240
|
+
|
|
241
|
+
def _check_command(
|
|
242
|
+
self, cmd: Any, flag: str, timeout: int = PTR_COMMAND_CHECK_TIMEOUT_SECS
|
|
243
|
+
) -> bool:
|
|
244
|
+
"""Check if a command is available."""
|
|
245
|
+
try:
|
|
246
|
+
if isinstance(cmd, list):
|
|
247
|
+
args = cmd + [flag]
|
|
248
|
+
else:
|
|
249
|
+
args = [cmd, flag]
|
|
250
|
+
|
|
251
|
+
result = subprocess.run(args, capture_output=True, timeout=timeout)
|
|
252
|
+
if result.returncode != 0:
|
|
253
|
+
self.logger.debug(
|
|
254
|
+
f"Command check failed for {args}: {result.stderr.decode()}"
|
|
255
|
+
)
|
|
256
|
+
return False
|
|
257
|
+
return True
|
|
258
|
+
except (OSError, subprocess.SubprocessError) as e:
|
|
259
|
+
self.logger.debug(f"Exception checking command {cmd}: {e}")
|
|
260
|
+
return False
|
|
261
|
+
|
|
262
|
+
def validate_environment(self) -> bool:
|
|
263
|
+
if not self.command:
|
|
264
|
+
return True # No command needed (e.g., compiled binaries)
|
|
265
|
+
return self._check_command(self.command, self.version_flag)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Binary-based runtimes (Rust, C).
|
|
3
|
+
|
|
4
|
+
These runtimes execute compiled binaries via subprocess.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from clm.layer0.model.card import MCard
|
|
11
|
+
|
|
12
|
+
from .base import RUNTIME_CONFIG, SubprocessRuntime, register_runtime
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BinaryRuntime(SubprocessRuntime):
|
|
16
|
+
"""Base class for runtimes that execute compiled binaries."""
|
|
17
|
+
|
|
18
|
+
def execute(self, impl: dict[str, Any], target: MCard, ctx: dict[str, Any]) -> Any:
|
|
19
|
+
binary_path = impl.get("binary_path")
|
|
20
|
+
if not binary_path:
|
|
21
|
+
return f"Error: No {self.runtime_name} binary path provided"
|
|
22
|
+
return self._run_subprocess([binary_path, json.dumps(ctx)], target, ctx)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@register_runtime("rust")
|
|
26
|
+
@register_runtime("wasm")
|
|
27
|
+
class RustRuntime(BinaryRuntime):
|
|
28
|
+
"""Rust runtime executor - executes via compiled binary or WASM."""
|
|
29
|
+
|
|
30
|
+
runtime_name = "Rust"
|
|
31
|
+
command = RUNTIME_CONFIG.get("rust", {}).get("command")
|
|
32
|
+
|
|
33
|
+
def execute(self, impl: dict[str, Any], target: MCard, ctx: dict[str, Any]) -> Any:
|
|
34
|
+
wasm_module = impl.get("wasm_module")
|
|
35
|
+
if wasm_module:
|
|
36
|
+
return self._execute_wasm(wasm_module, target, ctx)
|
|
37
|
+
return super().execute(impl, target, ctx)
|
|
38
|
+
|
|
39
|
+
def _execute_wasm(self, wasm_path: str, target: MCard, ctx: dict) -> Any:
|
|
40
|
+
"""Execute WASM module using wasmtime."""
|
|
41
|
+
try:
|
|
42
|
+
import os
|
|
43
|
+
import tempfile
|
|
44
|
+
|
|
45
|
+
from wasmtime import Linker, Module, Store, WasiConfig
|
|
46
|
+
|
|
47
|
+
store = Store()
|
|
48
|
+
wasi = WasiConfig()
|
|
49
|
+
wasi.inherit_stdout()
|
|
50
|
+
wasi.inherit_stderr()
|
|
51
|
+
wasi.argv = ["program_name", json.dumps(ctx)]
|
|
52
|
+
|
|
53
|
+
# Create temp files for stdin/stdout
|
|
54
|
+
with tempfile.NamedTemporaryFile(mode="w+", delete=False) as tmp_in:
|
|
55
|
+
tmp_in.write(target.get_content().decode("utf-8"))
|
|
56
|
+
in_path = tmp_in.name
|
|
57
|
+
|
|
58
|
+
with tempfile.NamedTemporaryFile(mode="w+", delete=False) as tmp_out:
|
|
59
|
+
out_path = tmp_out.name
|
|
60
|
+
|
|
61
|
+
wasi.stdin_file = in_path
|
|
62
|
+
wasi.stdout_file = out_path
|
|
63
|
+
store.set_wasi(wasi)
|
|
64
|
+
|
|
65
|
+
linker = Linker(store.engine)
|
|
66
|
+
linker.define_wasi()
|
|
67
|
+
|
|
68
|
+
module = Module.from_file(store.engine, wasm_path)
|
|
69
|
+
instance = linker.instantiate(store, module)
|
|
70
|
+
instance.exports(store)["_start"](store)
|
|
71
|
+
|
|
72
|
+
with open(out_path) as f:
|
|
73
|
+
output = f.read()
|
|
74
|
+
|
|
75
|
+
os.unlink(in_path)
|
|
76
|
+
os.unlink(out_path)
|
|
77
|
+
return output
|
|
78
|
+
|
|
79
|
+
except ImportError as e:
|
|
80
|
+
return f"Error: wasmtime python library not installed or load failed: {e}"
|
|
81
|
+
except (OSError, RuntimeError, ValueError) as e:
|
|
82
|
+
return f"Error executing WASM: {e}"
|
|
83
|
+
|
|
84
|
+
def validate_environment(self) -> bool:
|
|
85
|
+
rust_ok = self._check_command("rustc", "--version")
|
|
86
|
+
wasm_ok = False
|
|
87
|
+
try:
|
|
88
|
+
import importlib.util
|
|
89
|
+
|
|
90
|
+
wasm_ok = importlib.util.find_spec("wasmtime") is not None
|
|
91
|
+
except ImportError:
|
|
92
|
+
pass
|
|
93
|
+
return rust_ok or wasm_ok
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@register_runtime("c")
|
|
97
|
+
class CRuntime(BinaryRuntime):
|
|
98
|
+
"""C runtime executor - executes via compiled binary."""
|
|
99
|
+
|
|
100
|
+
runtime_name = "C"
|
|
101
|
+
command = None # No compiler check needed
|