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,126 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Lambda Calculus runtime executor.
|
|
3
|
+
|
|
4
|
+
Executes λ-calculus operations (α-β-η conversions) on MCard-stored terms.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from clm.layer0.model.card import MCard
|
|
10
|
+
|
|
11
|
+
from .base import RuntimeExecutor, register_runtime
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@register_runtime("lambda")
|
|
15
|
+
class LambdaRuntimeExecutor(RuntimeExecutor):
|
|
16
|
+
"""Lambda Calculus runtime executor.
|
|
17
|
+
|
|
18
|
+
Executes λ-calculus operations (α-β-η conversions) on MCard-stored terms.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, collection=None):
|
|
22
|
+
super().__init__()
|
|
23
|
+
self.collection = collection
|
|
24
|
+
self._lambda_runtime = None
|
|
25
|
+
|
|
26
|
+
def _get_runtime(self):
|
|
27
|
+
"""Lazy initialization of LambdaRuntime."""
|
|
28
|
+
if self._lambda_runtime is None:
|
|
29
|
+
from clm.layer1.protocols import get_store
|
|
30
|
+
from clm.layer1.runtimes.factory import get_external_executor
|
|
31
|
+
|
|
32
|
+
if self.collection is None:
|
|
33
|
+
self.collection = get_store(":memory:")
|
|
34
|
+
|
|
35
|
+
lambda_cls = get_external_executor("lambda")
|
|
36
|
+
if lambda_cls is not None:
|
|
37
|
+
self._lambda_runtime = lambda_cls(self.collection)
|
|
38
|
+
return self._lambda_runtime
|
|
39
|
+
|
|
40
|
+
def execute(self, impl: dict[str, Any], target: MCard, ctx: dict[str, Any]) -> Any:
|
|
41
|
+
"""Execute Lambda Calculus operation."""
|
|
42
|
+
runtime = self._get_runtime()
|
|
43
|
+
|
|
44
|
+
# Build context from concrete implementation and context
|
|
45
|
+
# Prioritize ctx override, then 'process', then 'action', then 'operation'
|
|
46
|
+
operation = ctx.get(
|
|
47
|
+
"operation",
|
|
48
|
+
impl.get("process", impl.get("action", impl.get("operation", "normalize"))),
|
|
49
|
+
)
|
|
50
|
+
strategy = ctx.get("strategy", impl.get("strategy", "normal"))
|
|
51
|
+
max_steps = ctx.get(
|
|
52
|
+
"max_steps",
|
|
53
|
+
ctx.get("maxSteps", impl.get("max_steps", impl.get("maxSteps", 100))),
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Get expression from context or target
|
|
57
|
+
expression = ctx.get("expression")
|
|
58
|
+
if not expression:
|
|
59
|
+
# Try to get from balanced input arguments
|
|
60
|
+
balanced = ctx.get("balanced", {})
|
|
61
|
+
input_args = balanced.get("input_arguments", {})
|
|
62
|
+
expression = input_args.get("expression") or input_args.get("numeral")
|
|
63
|
+
|
|
64
|
+
if not expression or expression == "dummy_target":
|
|
65
|
+
# Check if target content looks like a Lambda expression
|
|
66
|
+
target_content = target.get_content().decode("utf-8", errors="ignore")
|
|
67
|
+
if target_content and ("λ" in target_content or "\\" in target_content):
|
|
68
|
+
expression = target_content
|
|
69
|
+
elif operation in (
|
|
70
|
+
"check-readiness",
|
|
71
|
+
"num-add",
|
|
72
|
+
"num-sub",
|
|
73
|
+
"num-mul",
|
|
74
|
+
"num-div",
|
|
75
|
+
"http-request",
|
|
76
|
+
):
|
|
77
|
+
expression = "builtin" # Placeholder
|
|
78
|
+
else:
|
|
79
|
+
return "Error: No Lambda expression provided"
|
|
80
|
+
|
|
81
|
+
# Execute through LambdaRuntime
|
|
82
|
+
# Create a full context by merging ctx and any other needed fields
|
|
83
|
+
full_ctx = ctx.copy()
|
|
84
|
+
full_ctx["expression"] = expression
|
|
85
|
+
|
|
86
|
+
# Get io_effects from context (override) or concrete implementation config
|
|
87
|
+
io_effects = impl.get("io_effects", {}).copy()
|
|
88
|
+
if isinstance(ctx.get("io_effects"), dict):
|
|
89
|
+
io_effects.update(ctx.get("io_effects"))
|
|
90
|
+
|
|
91
|
+
result = runtime.execute(
|
|
92
|
+
expression,
|
|
93
|
+
full_ctx,
|
|
94
|
+
{
|
|
95
|
+
"operation": operation,
|
|
96
|
+
"strategy": strategy,
|
|
97
|
+
"max_steps": max_steps,
|
|
98
|
+
"io_effects": io_effects,
|
|
99
|
+
},
|
|
100
|
+
"",
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
if result.success:
|
|
104
|
+
# Return appropriate result based on operation
|
|
105
|
+
if result.pretty_print:
|
|
106
|
+
return result.pretty_print
|
|
107
|
+
elif result.is_closed is not None:
|
|
108
|
+
return result.is_closed
|
|
109
|
+
elif result.free_variables is not None:
|
|
110
|
+
return result.free_variables
|
|
111
|
+
else:
|
|
112
|
+
return result.term_hash
|
|
113
|
+
else:
|
|
114
|
+
return f"Error: {result.error}"
|
|
115
|
+
|
|
116
|
+
def validate_environment(self) -> bool:
|
|
117
|
+
"""Lambda runtime is always available (pure Python)."""
|
|
118
|
+
return True
|
|
119
|
+
|
|
120
|
+
def get_runtime_status(self) -> dict[str, Any]:
|
|
121
|
+
return {
|
|
122
|
+
"available": True,
|
|
123
|
+
"version": "1.0.0",
|
|
124
|
+
"command": "lambda",
|
|
125
|
+
"details": "Lambda Calculus α-β-η converter",
|
|
126
|
+
}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Python runtime executor.
|
|
3
|
+
|
|
4
|
+
Executes Python code directly in-process with sandboxing.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import functools
|
|
8
|
+
import importlib
|
|
9
|
+
from collections.abc import Callable
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from clm.layer0.model.card import MCard
|
|
13
|
+
|
|
14
|
+
from .base import RUNTIME_CONFIG, RuntimeExecutor, register_runtime
|
|
15
|
+
|
|
16
|
+
# Module URI prefix for dynamic module imports
|
|
17
|
+
MODULE_URI_PREFIX = "module://"
|
|
18
|
+
|
|
19
|
+
# Import sandbox configuration
|
|
20
|
+
try:
|
|
21
|
+
from clm.cross_cutting.config.settings import settings as _settings
|
|
22
|
+
|
|
23
|
+
ALLOWED_IMPORTS = _settings.ptr.allowed_imports
|
|
24
|
+
SAFE_BUILTINS = _settings.ptr.safe_builtins
|
|
25
|
+
except ImportError:
|
|
26
|
+
ALLOWED_IMPORTS = {}
|
|
27
|
+
SAFE_BUILTINS = set()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@register_runtime("python")
|
|
31
|
+
class PythonRuntime(RuntimeExecutor):
|
|
32
|
+
"""Python runtime executor - executes Python code directly in-process."""
|
|
33
|
+
|
|
34
|
+
# Operation handlers mapping
|
|
35
|
+
OPERATIONS: dict[str, Callable] = {}
|
|
36
|
+
|
|
37
|
+
# Operation handlers mapping
|
|
38
|
+
OPERATIONS: dict[str, Callable] = {}
|
|
39
|
+
|
|
40
|
+
def __init__(self):
|
|
41
|
+
super().__init__()
|
|
42
|
+
# Import operations from the extracted operations module
|
|
43
|
+
from ..operations import DEFAULT_OPERATIONS
|
|
44
|
+
|
|
45
|
+
# Register built-in operations from module
|
|
46
|
+
self.OPERATIONS = DEFAULT_OPERATIONS.copy()
|
|
47
|
+
|
|
48
|
+
# Add custom operation handler (requires self reference for sandboxing)
|
|
49
|
+
self.OPERATIONS["custom"] = self._op_custom
|
|
50
|
+
|
|
51
|
+
def execute(
|
|
52
|
+
self, concrete_impl: dict[str, Any], target: MCard, context: dict[str, Any]
|
|
53
|
+
) -> Any:
|
|
54
|
+
# Check for module:// syntax first
|
|
55
|
+
code_file = concrete_impl.get("code_file", "")
|
|
56
|
+
if code_file.startswith(MODULE_URI_PREFIX):
|
|
57
|
+
return self._execute_module_logic(code_file, concrete_impl, target, context)
|
|
58
|
+
|
|
59
|
+
# Determine operation robustly without letting dicts/lists cause key errors
|
|
60
|
+
operation = concrete_impl.get("operation")
|
|
61
|
+
if not operation:
|
|
62
|
+
operation = concrete_impl.get("builtin")
|
|
63
|
+
if not operation:
|
|
64
|
+
op_cand = concrete_impl.get("process")
|
|
65
|
+
if isinstance(op_cand, str):
|
|
66
|
+
operation = op_cand
|
|
67
|
+
else:
|
|
68
|
+
op_cand = concrete_impl.get("action")
|
|
69
|
+
if isinstance(op_cand, str):
|
|
70
|
+
operation = op_cand
|
|
71
|
+
|
|
72
|
+
if not operation:
|
|
73
|
+
# Auto-detect custom operation if code or process-script is present
|
|
74
|
+
has_proc_script = False
|
|
75
|
+
proc = concrete_impl.get("process")
|
|
76
|
+
if isinstance(proc, dict) and "script" in proc:
|
|
77
|
+
has_proc_script = True
|
|
78
|
+
elif isinstance(proc, list):
|
|
79
|
+
for p in proc:
|
|
80
|
+
if (
|
|
81
|
+
isinstance(p, dict)
|
|
82
|
+
and p.get("type") == "python"
|
|
83
|
+
and "script" in p
|
|
84
|
+
):
|
|
85
|
+
has_proc_script = True
|
|
86
|
+
break
|
|
87
|
+
|
|
88
|
+
if (
|
|
89
|
+
"code_file" in concrete_impl
|
|
90
|
+
or "code" in concrete_impl
|
|
91
|
+
or has_proc_script
|
|
92
|
+
):
|
|
93
|
+
operation = "custom"
|
|
94
|
+
else:
|
|
95
|
+
operation = "identity"
|
|
96
|
+
|
|
97
|
+
handler = self.OPERATIONS.get(operation)
|
|
98
|
+
|
|
99
|
+
if handler:
|
|
100
|
+
return handler(concrete_impl, target, context)
|
|
101
|
+
|
|
102
|
+
# Fallback to custom operation if custom script/code is provided, even with a custom operation name
|
|
103
|
+
has_proc_script = False
|
|
104
|
+
proc = concrete_impl.get("process")
|
|
105
|
+
if isinstance(proc, dict) and "script" in proc:
|
|
106
|
+
has_proc_script = True
|
|
107
|
+
elif isinstance(proc, list):
|
|
108
|
+
for p in proc:
|
|
109
|
+
if isinstance(p, dict) and p.get("type") == "python" and "script" in p:
|
|
110
|
+
has_proc_script = True
|
|
111
|
+
break
|
|
112
|
+
|
|
113
|
+
if "code_file" in concrete_impl or "code" in concrete_impl or has_proc_script:
|
|
114
|
+
return self._op_custom(concrete_impl, target, context)
|
|
115
|
+
|
|
116
|
+
return f"Executed {operation} on {target.hash}"
|
|
117
|
+
|
|
118
|
+
# ─── Custom Operation ──────────────────────────────────────────────────────
|
|
119
|
+
|
|
120
|
+
def _op_custom(self, impl: dict, target: MCard, ctx: dict) -> Any:
|
|
121
|
+
code_file = impl.get("code_file", "")
|
|
122
|
+
if code_file.startswith(MODULE_URI_PREFIX):
|
|
123
|
+
return self._execute_module_logic(code_file, impl, target, ctx)
|
|
124
|
+
|
|
125
|
+
code = impl.get("code", "")
|
|
126
|
+
if not code:
|
|
127
|
+
proc = impl.get("process")
|
|
128
|
+
if isinstance(proc, dict):
|
|
129
|
+
code = proc.get("script", "")
|
|
130
|
+
elif isinstance(proc, list):
|
|
131
|
+
for p in proc:
|
|
132
|
+
if isinstance(p, dict) and p.get("type") == "python":
|
|
133
|
+
code = p.get("script", "")
|
|
134
|
+
break
|
|
135
|
+
if not code:
|
|
136
|
+
return "Error: No code provided"
|
|
137
|
+
|
|
138
|
+
return self._exec_sandboxed(code, impl, target, ctx)
|
|
139
|
+
|
|
140
|
+
# ─── Sandboxed Execution ───────────────────────────────────────────────────
|
|
141
|
+
|
|
142
|
+
def _make_safe_import(self) -> Callable:
|
|
143
|
+
"""Create a safe import function."""
|
|
144
|
+
|
|
145
|
+
def safe_import(name, _globals=None, _locals=None, _fromlist=(), _level=0):
|
|
146
|
+
if name in ALLOWED_IMPORTS:
|
|
147
|
+
return importlib.import_module(name)
|
|
148
|
+
raise ImportError(f"Import of '{name}' is not allowed")
|
|
149
|
+
|
|
150
|
+
return safe_import
|
|
151
|
+
|
|
152
|
+
def _make_namespace(self, target: MCard, context: dict) -> dict:
|
|
153
|
+
"""Create a sandboxed namespace for code execution."""
|
|
154
|
+
import builtins as builtins_module
|
|
155
|
+
import math
|
|
156
|
+
|
|
157
|
+
# Build safe builtins dict from the builtins module
|
|
158
|
+
safe_builtins = {}
|
|
159
|
+
for name in SAFE_BUILTINS:
|
|
160
|
+
if hasattr(builtins_module, name):
|
|
161
|
+
safe_builtins[name] = getattr(builtins_module, name)
|
|
162
|
+
|
|
163
|
+
safe_builtins["__import__"] = self._make_safe_import()
|
|
164
|
+
safe_builtins["__build_class__"] = builtins_module.__build_class__
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
"__builtins__": safe_builtins,
|
|
168
|
+
"target": target.get_content(),
|
|
169
|
+
"context": context,
|
|
170
|
+
"result": None,
|
|
171
|
+
"math": math,
|
|
172
|
+
"__name__": "__clm_runtime__",
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@staticmethod
|
|
176
|
+
@functools.lru_cache(maxsize=1024)
|
|
177
|
+
def _compile_code(code: str) -> Any:
|
|
178
|
+
"""Compile Python code with an LRU cache to prevent memory leaks."""
|
|
179
|
+
return compile(code, "<string>", "exec")
|
|
180
|
+
|
|
181
|
+
def _exec_sandboxed(self, code: str, impl: dict, target: MCard, ctx: dict) -> Any:
|
|
182
|
+
"""Execute code in a sandboxed namespace with compilation caching."""
|
|
183
|
+
namespace = self._make_namespace(target, ctx)
|
|
184
|
+
|
|
185
|
+
try:
|
|
186
|
+
compiled_code = self._compile_code(code)
|
|
187
|
+
exec(compiled_code, namespace) # nosec B102
|
|
188
|
+
|
|
189
|
+
entry_point = impl.get("entry_point")
|
|
190
|
+
if entry_point:
|
|
191
|
+
return self._call_entry_point(namespace, entry_point, impl, target, ctx)
|
|
192
|
+
return namespace.get("result")
|
|
193
|
+
except Exception as e:
|
|
194
|
+
return f"Error executing Python code: {e}"
|
|
195
|
+
|
|
196
|
+
def _call_entry_point(
|
|
197
|
+
self, ns: dict, entry: str, impl: dict, target: MCard, ctx: dict
|
|
198
|
+
) -> Any:
|
|
199
|
+
"""Call a function defined in namespace."""
|
|
200
|
+
if entry not in ns or not callable(ns[entry]):
|
|
201
|
+
return f"Error: Entry point '{entry}' not found or not callable. Keys: {list(ns.keys())}"
|
|
202
|
+
|
|
203
|
+
func = ns[entry]
|
|
204
|
+
arg = self._prepare_argument(impl, target, ctx)
|
|
205
|
+
return func(arg)
|
|
206
|
+
|
|
207
|
+
def _prepare_argument(self, impl: dict, target: MCard, ctx: dict) -> Any:
|
|
208
|
+
"""Prepare argument for entry point function."""
|
|
209
|
+
inputs_def = impl.get("implementation", {}).get("inputs", {})
|
|
210
|
+
|
|
211
|
+
# If context has operation or params keys, the entry point likely expects context
|
|
212
|
+
if ctx.get("operation") or ctx.get("params") or ctx.get("op"):
|
|
213
|
+
combined = ctx.copy()
|
|
214
|
+
content = target.get_content()
|
|
215
|
+
if isinstance(content, bytes):
|
|
216
|
+
try:
|
|
217
|
+
content = content.decode("utf-8")
|
|
218
|
+
except (UnicodeDecodeError, AttributeError):
|
|
219
|
+
pass
|
|
220
|
+
combined["value"] = content
|
|
221
|
+
combined["__input_content__"] = content
|
|
222
|
+
return combined
|
|
223
|
+
|
|
224
|
+
if not inputs_def:
|
|
225
|
+
return target.get_content()
|
|
226
|
+
|
|
227
|
+
input_name = list(inputs_def.keys())[0]
|
|
228
|
+
input_type = inputs_def[input_name]
|
|
229
|
+
|
|
230
|
+
if input_name == "context":
|
|
231
|
+
return ctx
|
|
232
|
+
|
|
233
|
+
raw = target.get_content()
|
|
234
|
+
converters = {
|
|
235
|
+
"float": lambda: float(raw.decode("utf-8")),
|
|
236
|
+
"int": lambda: int(raw.decode("utf-8")),
|
|
237
|
+
"str": lambda: raw.decode("utf-8"),
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
try:
|
|
241
|
+
return converters.get(input_type, lambda: raw)()
|
|
242
|
+
except (ValueError, TypeError, UnicodeDecodeError):
|
|
243
|
+
return raw
|
|
244
|
+
|
|
245
|
+
# ─── Module Logic ──────────────────────────────────────────────────────────
|
|
246
|
+
|
|
247
|
+
def _execute_module_logic(
|
|
248
|
+
self, uri: str, impl: dict, target: MCard, ctx: dict
|
|
249
|
+
) -> Any:
|
|
250
|
+
"""Execute logic imported from a Python module."""
|
|
251
|
+
path = uri.replace(MODULE_URI_PREFIX, "")
|
|
252
|
+
module_name, func_name = (
|
|
253
|
+
path.split(":", 1)
|
|
254
|
+
if ":" in path
|
|
255
|
+
else (path, impl.get("entry_point", "logic"))
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
try:
|
|
259
|
+
module = importlib.import_module(module_name)
|
|
260
|
+
func = getattr(module, func_name)
|
|
261
|
+
if not callable(func):
|
|
262
|
+
return f"Error: {func_name} in {module_name} is not callable"
|
|
263
|
+
|
|
264
|
+
arg = (
|
|
265
|
+
target.get_content().decode("utf-8")
|
|
266
|
+
if hasattr(target, "get_content")
|
|
267
|
+
else target
|
|
268
|
+
)
|
|
269
|
+
return func(arg)
|
|
270
|
+
except ImportError as e:
|
|
271
|
+
return f"Error importing module {module_name}: {e}"
|
|
272
|
+
except AttributeError:
|
|
273
|
+
return f"Error: Function {func_name} not found in {module_name}"
|
|
274
|
+
except (ValueError, TypeError, RuntimeError, OSError) as e:
|
|
275
|
+
return f"Error executing module logic: {e}"
|
|
276
|
+
|
|
277
|
+
def validate_environment(self) -> bool:
|
|
278
|
+
return True
|
|
279
|
+
|
|
280
|
+
def get_runtime_status(self) -> dict[str, Any]:
|
|
281
|
+
import sys
|
|
282
|
+
|
|
283
|
+
return {
|
|
284
|
+
"available": True,
|
|
285
|
+
"version": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
|
|
286
|
+
"command": RUNTIME_CONFIG.get("python", {}).get("command", "python3"),
|
|
287
|
+
"details": f"Python {sys.version}",
|
|
288
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Python Native Sandbox Evaluator
|
|
3
|
+
|
|
4
|
+
Invoked by the Meta Circular Evaluator to execute Python dynamically.
|
|
5
|
+
Expects input as JSON on stdin.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import sys
|
|
10
|
+
import traceback
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def main():
|
|
14
|
+
try:
|
|
15
|
+
input_data = sys.stdin.read()
|
|
16
|
+
payload = json.loads(input_data)
|
|
17
|
+
|
|
18
|
+
target = payload.get("target")
|
|
19
|
+
context = payload.get("context", {})
|
|
20
|
+
code = payload.get("code", "")
|
|
21
|
+
|
|
22
|
+
# Execute securely in a restricted dictionary namespace
|
|
23
|
+
safe_globals = context.copy()
|
|
24
|
+
|
|
25
|
+
# Pass the target variable inside for script evaluation
|
|
26
|
+
safe_globals["target"] = target
|
|
27
|
+
safe_globals["context"] = context
|
|
28
|
+
|
|
29
|
+
exec(code, safe_globals)
|
|
30
|
+
|
|
31
|
+
# Scripts must place their output into `result` variable
|
|
32
|
+
output = safe_globals.get("result", None)
|
|
33
|
+
|
|
34
|
+
print(json.dumps(output))
|
|
35
|
+
except Exception as e:
|
|
36
|
+
print(f"Compilation error: {e}\\n{traceback.format_exc()}")
|
|
37
|
+
sys.exit(1)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
main()
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Script-based runtimes (Lean, R, Julia).
|
|
3
|
+
|
|
4
|
+
These runtimes execute script files via interpreter subprocess.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from clm.cross_cutting.config.config_constants import PTR_LEAN_VALIDATE_TIMEOUT_SECS
|
|
12
|
+
from clm.layer0.model.card import MCard
|
|
13
|
+
|
|
14
|
+
from .base import (
|
|
15
|
+
JULIA_TIMEOUT,
|
|
16
|
+
LEAN_TIMEOUT,
|
|
17
|
+
R_TIMEOUT,
|
|
18
|
+
RUNTIME_CONFIG,
|
|
19
|
+
SubprocessRuntime,
|
|
20
|
+
register_runtime,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ScriptRuntime(SubprocessRuntime):
|
|
25
|
+
"""Base class for runtimes that execute script files."""
|
|
26
|
+
|
|
27
|
+
file_key = "code_file"
|
|
28
|
+
run_args: list[str] = []
|
|
29
|
+
|
|
30
|
+
def execute(self, impl: dict[str, Any], target: MCard, ctx: dict[str, Any]) -> Any:
|
|
31
|
+
code_file = impl.get(self.file_key)
|
|
32
|
+
if not code_file:
|
|
33
|
+
return f"Error: No {self.runtime_name} code file provided"
|
|
34
|
+
|
|
35
|
+
# Normalize command to list
|
|
36
|
+
base_cmd = self.command if isinstance(self.command, list) else [self.command]
|
|
37
|
+
|
|
38
|
+
cmd = base_cmd + self.run_args + [code_file, json.dumps(ctx)]
|
|
39
|
+
return self._run_subprocess(cmd, target, ctx, self.timeout)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@register_runtime("lean")
|
|
43
|
+
class LeanRuntime(ScriptRuntime):
|
|
44
|
+
"""Lean 4 runtime executor."""
|
|
45
|
+
|
|
46
|
+
runtime_name = "Lean"
|
|
47
|
+
run_args = ["--run"]
|
|
48
|
+
timeout = LEAN_TIMEOUT
|
|
49
|
+
|
|
50
|
+
def __init__(self):
|
|
51
|
+
super().__init__()
|
|
52
|
+
# Dynamic check for elan to support specific toolchains (e.g. v4.25.2)
|
|
53
|
+
# Matches JS implementation in mcard-js/src/ptr/node/runtimes/lean.ts
|
|
54
|
+
elan_path = Path.home() / ".elan" / "bin" / "elan"
|
|
55
|
+
|
|
56
|
+
# Check explicit environment variable first
|
|
57
|
+
env_lean_cmd = RUNTIME_CONFIG.get("lean", {}).get("command")
|
|
58
|
+
|
|
59
|
+
if env_lean_cmd and env_lean_cmd != "lean":
|
|
60
|
+
# Use configured command if it's specific
|
|
61
|
+
self.command = env_lean_cmd
|
|
62
|
+
elif elan_path.exists():
|
|
63
|
+
# Use elan to ensure we use the same version as JS tests
|
|
64
|
+
# 'elan run' avoids downloading 'stable' if we pin to v4.25.2 match JS
|
|
65
|
+
self.command = [str(elan_path), "run", "leanprover/lean4:v4.25.2", "lean"]
|
|
66
|
+
else:
|
|
67
|
+
# Fallback to system lean (subject to lean-toolchain file)
|
|
68
|
+
self.command = "lean"
|
|
69
|
+
|
|
70
|
+
def validate_environment(self) -> bool:
|
|
71
|
+
# Lean 4 takes longer to initialize, use extended timeout
|
|
72
|
+
return self._check_command(
|
|
73
|
+
self.command, self.version_flag, timeout=PTR_LEAN_VALIDATE_TIMEOUT_SECS
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
def execute(self, impl: dict[str, Any], target: MCard, ctx: dict[str, Any]) -> Any:
|
|
77
|
+
"""Execute Lean script, passing input as the argument."""
|
|
78
|
+
code_file = impl.get(self.file_key)
|
|
79
|
+
if not code_file:
|
|
80
|
+
return f"Error: No {self.runtime_name} code file provided"
|
|
81
|
+
|
|
82
|
+
# Determine what to pass as the argument:
|
|
83
|
+
# 1. If context has 'op', 'a', 'b' keys (polyglot mode), use context as JSON
|
|
84
|
+
# 2. Otherwise, use target content (standalone CLM mode)
|
|
85
|
+
if ctx and ("op" in ctx or "a" in ctx or "n" in ctx):
|
|
86
|
+
# Polyglot/advanced mode - context contains the actual input data
|
|
87
|
+
input_data = json.dumps(ctx)
|
|
88
|
+
else:
|
|
89
|
+
# Standalone CLM mode - target content is the JSON input
|
|
90
|
+
input_data = target.get_content().decode("utf-8", errors="ignore")
|
|
91
|
+
|
|
92
|
+
# Normalize command to list
|
|
93
|
+
base_cmd = self.command if isinstance(self.command, list) else [self.command]
|
|
94
|
+
|
|
95
|
+
cmd = base_cmd + self.run_args + [code_file, input_data]
|
|
96
|
+
return self._run_subprocess(cmd, target, ctx, self.timeout)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@register_runtime("r")
|
|
100
|
+
class RRuntime(ScriptRuntime):
|
|
101
|
+
"""R runtime executor."""
|
|
102
|
+
|
|
103
|
+
runtime_name = "R"
|
|
104
|
+
command = RUNTIME_CONFIG.get("r", {}).get("command") or "Rscript"
|
|
105
|
+
timeout = R_TIMEOUT
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@register_runtime("julia")
|
|
109
|
+
class JuliaRuntime(ScriptRuntime):
|
|
110
|
+
"""Julia runtime executor."""
|
|
111
|
+
|
|
112
|
+
runtime_name = "Julia"
|
|
113
|
+
command = RUNTIME_CONFIG.get("julia", {}).get("command") or "julia"
|
|
114
|
+
timeout = JULIA_TIMEOUT
|