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,221 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Layer 1: Dual-Tier Neural Runtime (DV-373-04).
|
|
3
|
+
|
|
4
|
+
Implements the Galois Adjunction between System 1 (Jev-Native Fast Discrete Projection)
|
|
5
|
+
and System 2 (Autoregressive Deliberative LLM):
|
|
6
|
+
System 1 ⊣ System 2
|
|
7
|
+
|
|
8
|
+
Features:
|
|
9
|
+
- System 1: Single-pass linear projection π_τ: X -> (U_τ x [0, 1]) over discrete variants.
|
|
10
|
+
Latency <= 70ms, zero output token costs, 0% type errors by construction.
|
|
11
|
+
- RLCD Calibrated Meet Gate: Admissible(d) = d ∧ 1_{P(d | x) >= 1 - ε}.
|
|
12
|
+
- System 2: Deliberative LLM synthesis with V_pre / V_post verification and Z4 rollback.
|
|
13
|
+
- Automatic escalation: P < 1 - ε collapses to ⊥_uncertainty, deterministically invoking System 2.
|
|
14
|
+
- Emits immutable InferenceMCard instances to the CAS.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import time
|
|
20
|
+
import uuid
|
|
21
|
+
from dataclasses import dataclass, field
|
|
22
|
+
from typing import Any, Callable
|
|
23
|
+
|
|
24
|
+
from clm.cross_cutting.domain_models import MCard
|
|
25
|
+
from clm.layer1.savepoint_guard import VCardMeetViolation
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class DiscreteDecision:
|
|
30
|
+
"""Represents a discrete typed decision produced by System 1 or System 2."""
|
|
31
|
+
|
|
32
|
+
variant: str
|
|
33
|
+
probability: float
|
|
34
|
+
admissible: bool
|
|
35
|
+
tier: str # "system1" | "system2"
|
|
36
|
+
latency_ms: float
|
|
37
|
+
metadata: dict[str, Any] = field(default_factory=dict)
|
|
38
|
+
|
|
39
|
+
def to_dict(self) -> dict[str, Any]:
|
|
40
|
+
return {
|
|
41
|
+
"variant": self.variant,
|
|
42
|
+
"probability": round(self.probability, 4),
|
|
43
|
+
"admissible": self.admissible,
|
|
44
|
+
"tier": self.tier,
|
|
45
|
+
"latency_ms": round(self.latency_ms, 2),
|
|
46
|
+
"metadata": self.metadata,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class System1RuntimeAdapter:
|
|
51
|
+
"""
|
|
52
|
+
Jev-Native Machine-Level System 1 Runtime Adapter.
|
|
53
|
+
Performs fast, discrete linear projection onto discrete sub-lattices.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def __init__(
|
|
57
|
+
self,
|
|
58
|
+
variants: list[str],
|
|
59
|
+
epsilon: float = 0.05,
|
|
60
|
+
decision_head: Callable[[Any], tuple[str, float]] | None = None,
|
|
61
|
+
) -> None:
|
|
62
|
+
"""
|
|
63
|
+
Args:
|
|
64
|
+
variants: Allowed discrete decision variants (e.g. ['APPROVE', 'REJECT', 'ESCALATE'])
|
|
65
|
+
epsilon: RLCD uncertainty tolerance threshold. 1 - epsilon is the acceptance bar.
|
|
66
|
+
decision_head: Optional custom linear projection head.
|
|
67
|
+
"""
|
|
68
|
+
self.variants = variants
|
|
69
|
+
self.epsilon = epsilon
|
|
70
|
+
self.acceptance_bar = 1.0 - epsilon
|
|
71
|
+
self.decision_head = decision_head or self._default_projection
|
|
72
|
+
|
|
73
|
+
def _default_projection(self, input_features: Any) -> tuple[str, float]:
|
|
74
|
+
"""Default fast projection simulation (sub-millisecond)."""
|
|
75
|
+
if isinstance(input_features, dict) and "forced_variant" in input_features:
|
|
76
|
+
return input_features["forced_variant"], float(input_features.get("forced_prob", 0.99))
|
|
77
|
+
if self.variants:
|
|
78
|
+
return self.variants[0], 0.98
|
|
79
|
+
return "UNKNOWN", 0.5
|
|
80
|
+
|
|
81
|
+
def evaluate(self, input_features: Any) -> DiscreteDecision:
|
|
82
|
+
"""
|
|
83
|
+
Executes single-pass linear projection under RLCD Calibrated Meet Gate:
|
|
84
|
+
Admissible(d) = d ∧ 1_{P(d | x) >= 1 - ε}
|
|
85
|
+
"""
|
|
86
|
+
start_time = time.perf_counter()
|
|
87
|
+
variant, prob = self.decision_head(input_features)
|
|
88
|
+
latency_ms = (time.perf_counter() - start_time) * 1000.0
|
|
89
|
+
|
|
90
|
+
# Enforce MISU: variant must belong to allowed lattice
|
|
91
|
+
if variant not in self.variants:
|
|
92
|
+
admissible = False
|
|
93
|
+
else:
|
|
94
|
+
admissible = prob >= self.acceptance_bar
|
|
95
|
+
|
|
96
|
+
return DiscreteDecision(
|
|
97
|
+
variant=variant,
|
|
98
|
+
probability=prob,
|
|
99
|
+
admissible=admissible,
|
|
100
|
+
tier="system1",
|
|
101
|
+
latency_ms=latency_ms,
|
|
102
|
+
metadata={"epsilon": self.epsilon, "acceptance_bar": self.acceptance_bar},
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class System2RuntimeAdapter:
|
|
107
|
+
"""
|
|
108
|
+
Autoregressive Deliberative LLM Runtime Adapter (System 2).
|
|
109
|
+
Absorbs mcard/ptr/core/llm/ providers with VCard pre/post validation.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
def __init__(
|
|
113
|
+
self,
|
|
114
|
+
llm_client: Callable[[str, dict[str, Any]], str] | None = None,
|
|
115
|
+
max_tokens: int = 4096,
|
|
116
|
+
) -> None:
|
|
117
|
+
self.llm_client = llm_client or self._default_mock_llm
|
|
118
|
+
self.max_tokens = max_tokens
|
|
119
|
+
|
|
120
|
+
def _default_mock_llm(self, prompt: str, ctx: dict[str, Any]) -> str:
|
|
121
|
+
"""Default deterministic mock synthesizer."""
|
|
122
|
+
target_variant = ctx.get("fallback_variant", "APPROVE")
|
|
123
|
+
return f'{{"decision": "{target_variant}", "rationale": "Deliberated by System 2"}}'
|
|
124
|
+
|
|
125
|
+
def evaluate(
|
|
126
|
+
self,
|
|
127
|
+
prompt: str,
|
|
128
|
+
context: dict[str, Any] | None = None,
|
|
129
|
+
allowed_variants: list[str] | None = None,
|
|
130
|
+
) -> DiscreteDecision:
|
|
131
|
+
"""
|
|
132
|
+
Executes deliberative System 2 reasoning wrapped in V_pre and V_post checks.
|
|
133
|
+
"""
|
|
134
|
+
start_time = time.perf_counter()
|
|
135
|
+
ctx = context or {}
|
|
136
|
+
|
|
137
|
+
# V_pre: Validate prompt length and token limits
|
|
138
|
+
if not prompt or len(prompt) > self.max_tokens * 10:
|
|
139
|
+
raise VCardMeetViolation(f"System 2 V_pre failed: prompt size exceeds limit ({len(prompt)} chars)")
|
|
140
|
+
|
|
141
|
+
# Deliberative synthesis
|
|
142
|
+
raw_output = self.llm_client(prompt, ctx)
|
|
143
|
+
latency_ms = (time.perf_counter() - start_time) * 1000.0
|
|
144
|
+
|
|
145
|
+
# V_post: Validate output conforms to schema
|
|
146
|
+
import json
|
|
147
|
+
try:
|
|
148
|
+
parsed = json.loads(raw_output)
|
|
149
|
+
variant = parsed.get("decision", "UNKNOWN")
|
|
150
|
+
rationale = parsed.get("rationale", "")
|
|
151
|
+
except Exception:
|
|
152
|
+
variant = raw_output.strip()
|
|
153
|
+
rationale = "Raw string response"
|
|
154
|
+
|
|
155
|
+
variants = allowed_variants or []
|
|
156
|
+
admissible = variant in variants if variants else True
|
|
157
|
+
|
|
158
|
+
if not admissible:
|
|
159
|
+
raise VCardMeetViolation(
|
|
160
|
+
f"System 2 V_post failed: variant '{variant}' not in allowed variants {variants}"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
return DiscreteDecision(
|
|
164
|
+
variant=variant,
|
|
165
|
+
probability=1.0, # System 2 deliberative verdict treated as discrete deterministic
|
|
166
|
+
admissible=True,
|
|
167
|
+
tier="system2",
|
|
168
|
+
latency_ms=latency_ms,
|
|
169
|
+
metadata={"rationale": rationale, "prompt_length": len(prompt)},
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class DualTierNeuralCoordinator:
|
|
174
|
+
"""
|
|
175
|
+
Galois Adjoint Coordinator between System 1 (Fast Jev) and System 2 (Deliberative LLM).
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
def __init__(
|
|
179
|
+
self,
|
|
180
|
+
system1: System1RuntimeAdapter,
|
|
181
|
+
system2: System2RuntimeAdapter | None = None,
|
|
182
|
+
) -> None:
|
|
183
|
+
self.system1 = system1
|
|
184
|
+
self.system2 = system2 or System2RuntimeAdapter()
|
|
185
|
+
|
|
186
|
+
def decide(
|
|
187
|
+
self,
|
|
188
|
+
features: Any,
|
|
189
|
+
prompt_fallback: str = "Synthesize decision",
|
|
190
|
+
context: dict[str, Any] | None = None,
|
|
191
|
+
) -> tuple[DiscreteDecision, MCard]:
|
|
192
|
+
"""
|
|
193
|
+
Evaluates System 1 first. If admissible, returns immediately.
|
|
194
|
+
If System 1 collapses to ⊥_uncertainty, cleanly hands off to System 2.
|
|
195
|
+
Emits an immutable InferenceMCard to the Sovereign Triad CAS.
|
|
196
|
+
"""
|
|
197
|
+
s1_decision = self.system1.evaluate(features)
|
|
198
|
+
|
|
199
|
+
if s1_decision.admissible:
|
|
200
|
+
final_decision = s1_decision
|
|
201
|
+
else:
|
|
202
|
+
# Deterministic escalation to System 2 via Galois adjoint
|
|
203
|
+
final_decision = self.system2.evaluate(
|
|
204
|
+
prompt=prompt_fallback,
|
|
205
|
+
context=context,
|
|
206
|
+
allowed_variants=self.system1.variants,
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
# Emit immutable InferenceMCard
|
|
210
|
+
inference_payload = {
|
|
211
|
+
"schema_archetype": "InferenceMCard",
|
|
212
|
+
"decision": final_decision.to_dict(),
|
|
213
|
+
"timestamp_iso": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
|
214
|
+
"id": f"inf_{uuid.uuid4().hex[:12]}",
|
|
215
|
+
}
|
|
216
|
+
mcard = MCard.create(
|
|
217
|
+
uri=f"inference:{final_decision.variant}",
|
|
218
|
+
payload=inference_payload,
|
|
219
|
+
author="did:key:z6MkhaXgBZDvotDkL5257faiz48Z8x28xhr554x4tp4MaEBx",
|
|
220
|
+
)
|
|
221
|
+
return final_decision, mcard
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""Operations Module for Python Runtime (Layer 1 Petri / Algebraic Strata).
|
|
2
|
+
========================================================================
|
|
3
|
+
|
|
4
|
+
Normative Reference:
|
|
5
|
+
docs/spec/40-behavior/baldwin_monadic_pcard_algebra.md § 0 (Baldwin Modularity Algebra)
|
|
6
|
+
docs/spec/20-architecture/card-triad-architecture.md § 1.1 (PCard & Dynamic Operators)
|
|
7
|
+
|
|
8
|
+
Invariants:
|
|
9
|
+
INV-02: Function-Number Duality (Function ≅ Number†).
|
|
10
|
+
INV-388-01: Syntactic Closure (preserves abstract_spec, concrete_impl, balanced_exp).
|
|
11
|
+
INV-388-02: Semantic Closure (produces valid morphisms in Poly(X)).
|
|
12
|
+
|
|
13
|
+
Implements the 6 Baldwin Modularity Operators:
|
|
14
|
+
- split, substitute, augment, exclude, invert, port.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from .augment import op_augment, op_insert, op_load_file
|
|
18
|
+
from .base import ExampleRunnerMixin, Operation, OperationRegistry
|
|
19
|
+
from .builtins import (
|
|
20
|
+
op_arithmetic,
|
|
21
|
+
op_fetch_url,
|
|
22
|
+
op_identity,
|
|
23
|
+
op_invoke_library,
|
|
24
|
+
op_postcondition_witness,
|
|
25
|
+
op_precondition_witness,
|
|
26
|
+
op_session_record,
|
|
27
|
+
op_string,
|
|
28
|
+
op_transform,
|
|
29
|
+
)
|
|
30
|
+
from .dispatch import (
|
|
31
|
+
BALDWIN_OPERATIONS,
|
|
32
|
+
BaldwinOperationDispatcher,
|
|
33
|
+
dispatch_baldwin_operation,
|
|
34
|
+
get_baldwin_registry,
|
|
35
|
+
register_baldwin_operations,
|
|
36
|
+
verify_semantic_closure,
|
|
37
|
+
verify_syntactic_closure,
|
|
38
|
+
)
|
|
39
|
+
from .exclude import op_exclude
|
|
40
|
+
from .handle import (
|
|
41
|
+
op_handle_prune,
|
|
42
|
+
op_handle_version,
|
|
43
|
+
)
|
|
44
|
+
from .identity import op_provision_genesis_ca, op_provision_genesis_eoa
|
|
45
|
+
from .invert import op_invert
|
|
46
|
+
from .loader import op_loader
|
|
47
|
+
from .port import op_port
|
|
48
|
+
from .services import (
|
|
49
|
+
op_static_server,
|
|
50
|
+
op_websocket_server,
|
|
51
|
+
)
|
|
52
|
+
from .split import op_split
|
|
53
|
+
from .substitute import op_substitute
|
|
54
|
+
|
|
55
|
+
# Default operation registry with all built-in and Baldwin operations
|
|
56
|
+
DEFAULT_OPERATIONS = {
|
|
57
|
+
"identity": op_identity,
|
|
58
|
+
"transform": op_transform,
|
|
59
|
+
"arithmetic": op_arithmetic,
|
|
60
|
+
"string_op": op_string,
|
|
61
|
+
"fetch_url": op_fetch_url,
|
|
62
|
+
"loader": op_loader,
|
|
63
|
+
"ingest_files": op_loader,
|
|
64
|
+
"load_files": op_loader,
|
|
65
|
+
"session_record": op_session_record,
|
|
66
|
+
"static_server": op_static_server,
|
|
67
|
+
"websocket_server": op_websocket_server,
|
|
68
|
+
"handle_version": op_handle_version,
|
|
69
|
+
"handle_prune": op_handle_prune,
|
|
70
|
+
"load_file": op_load_file,
|
|
71
|
+
"insert": op_insert,
|
|
72
|
+
"provision_genesis_eoa": op_provision_genesis_eoa,
|
|
73
|
+
"provision_genesis_ca": op_provision_genesis_ca,
|
|
74
|
+
"precondition_witness": op_precondition_witness,
|
|
75
|
+
"postcondition_witness": op_postcondition_witness,
|
|
76
|
+
"invoke_library": op_invoke_library,
|
|
77
|
+
# Baldwin Modularity Operators (Sprint 388)
|
|
78
|
+
"split": op_split,
|
|
79
|
+
"substitute": op_substitute,
|
|
80
|
+
"augment": op_augment,
|
|
81
|
+
"exclude": op_exclude,
|
|
82
|
+
"invert": op_invert,
|
|
83
|
+
"port": op_port,
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
__all__ = [
|
|
87
|
+
"Operation",
|
|
88
|
+
"OperationRegistry",
|
|
89
|
+
"ExampleRunnerMixin",
|
|
90
|
+
"DEFAULT_OPERATIONS",
|
|
91
|
+
"BALDWIN_OPERATIONS",
|
|
92
|
+
"op_identity",
|
|
93
|
+
"op_transform",
|
|
94
|
+
"op_arithmetic",
|
|
95
|
+
"op_string",
|
|
96
|
+
"op_fetch_url",
|
|
97
|
+
"op_session_record",
|
|
98
|
+
"op_static_server",
|
|
99
|
+
"op_websocket_server",
|
|
100
|
+
"op_loader",
|
|
101
|
+
"op_handle_version",
|
|
102
|
+
"op_handle_prune",
|
|
103
|
+
"op_load_file",
|
|
104
|
+
"op_insert",
|
|
105
|
+
"op_provision_genesis_eoa",
|
|
106
|
+
"op_provision_genesis_ca",
|
|
107
|
+
"op_precondition_witness",
|
|
108
|
+
"op_postcondition_witness",
|
|
109
|
+
"op_invoke_library",
|
|
110
|
+
# Baldwin Modularity Operators
|
|
111
|
+
"op_split",
|
|
112
|
+
"op_substitute",
|
|
113
|
+
"op_augment",
|
|
114
|
+
"op_exclude",
|
|
115
|
+
"op_invert",
|
|
116
|
+
"op_port",
|
|
117
|
+
"dispatch_baldwin_operation",
|
|
118
|
+
"BaldwinOperationDispatcher",
|
|
119
|
+
"register_baldwin_operations",
|
|
120
|
+
"get_baldwin_registry",
|
|
121
|
+
"verify_syntactic_closure",
|
|
122
|
+
"verify_semantic_closure",
|
|
123
|
+
]
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Augment operations for reading CLM files and inserting MCards.
|
|
3
|
+
|
|
4
|
+
These are native operations registered with the PythonRuntime's
|
|
5
|
+
DEFAULT_OPERATIONS registry. They implement the two atomic phases
|
|
6
|
+
of the "augment" operator:
|
|
7
|
+
|
|
8
|
+
1. load_file — Read a file from the filesystem and return its content (text or binary).
|
|
9
|
+
2. insert — Insert content into a CardCollection as an MCard
|
|
10
|
+
and register it under a named handle.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
from clm.layer0.model.card import MCard
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def op_load_file(impl: dict, target: MCard, ctx: dict) -> Any:
|
|
21
|
+
"""Read a file from the filesystem and return its content (text or binary).
|
|
22
|
+
|
|
23
|
+
Context params:
|
|
24
|
+
file_path: Path to the file to read (required).
|
|
25
|
+
"""
|
|
26
|
+
file_path = ctx.get("file_path", ctx.get("clm_file_path", ""))
|
|
27
|
+
if not file_path or not str(file_path).strip():
|
|
28
|
+
return {"success": False, "error": "No file_path provided in context."}
|
|
29
|
+
|
|
30
|
+
p = Path(str(file_path).strip()).resolve()
|
|
31
|
+
if not p.exists():
|
|
32
|
+
return {"success": False, "error": f"File not found: {p}"}
|
|
33
|
+
|
|
34
|
+
with open(p, "rb") as f:
|
|
35
|
+
content = f.read()
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
content = content.decode("utf-8")
|
|
39
|
+
except UnicodeDecodeError:
|
|
40
|
+
pass # Keep as bytes for binary files
|
|
41
|
+
|
|
42
|
+
return {"success": True, "content": content}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def op_insert(impl: dict, target: MCard, ctx: dict) -> Any:
|
|
46
|
+
"""Insert content into a CardCollection as an MCard and register a handle.
|
|
47
|
+
|
|
48
|
+
Context params:
|
|
49
|
+
__input_content__: Raw content or VCard JSON string/bytes to insert.
|
|
50
|
+
target_db: Database path (default: meta_functionality.db).
|
|
51
|
+
handle_name: Handle to register (default: clm_reserved_words.yaml).
|
|
52
|
+
"""
|
|
53
|
+
from clm.layer1.protocols import get_store
|
|
54
|
+
|
|
55
|
+
raw_input = ctx.get("__input_content__", "")
|
|
56
|
+
if not raw_input and target:
|
|
57
|
+
raw_input = target.get_content()
|
|
58
|
+
|
|
59
|
+
content = raw_input
|
|
60
|
+
|
|
61
|
+
if isinstance(raw_input, bytes):
|
|
62
|
+
try:
|
|
63
|
+
decoded = raw_input.decode("utf-8")
|
|
64
|
+
vcard_data = json.loads(decoded)
|
|
65
|
+
execution_result = vcard_data.get("execution_result", decoded)
|
|
66
|
+
if isinstance(execution_result, dict):
|
|
67
|
+
content = execution_result.get("content", str(execution_result))
|
|
68
|
+
else:
|
|
69
|
+
content = execution_result
|
|
70
|
+
except (UnicodeDecodeError, json.JSONDecodeError, TypeError, AttributeError):
|
|
71
|
+
content = raw_input
|
|
72
|
+
else:
|
|
73
|
+
# Try to extract execution_result from VCard JSON envelope
|
|
74
|
+
try:
|
|
75
|
+
vcard_data = json.loads(raw_input)
|
|
76
|
+
execution_result = vcard_data.get("execution_result", raw_input)
|
|
77
|
+
if isinstance(execution_result, dict):
|
|
78
|
+
content = execution_result.get("content", str(execution_result))
|
|
79
|
+
else:
|
|
80
|
+
content = execution_result
|
|
81
|
+
except (json.JSONDecodeError, TypeError, AttributeError):
|
|
82
|
+
content = raw_input
|
|
83
|
+
|
|
84
|
+
target_db = ctx.get("target_db", "meta_functionality.db")
|
|
85
|
+
handle_name = ctx.get("handle_name", "clm_reserved_words.yaml")
|
|
86
|
+
|
|
87
|
+
mcard_obj = MCard(content)
|
|
88
|
+
db_path = Path.cwd() / target_db
|
|
89
|
+
collection = get_store(str(db_path))
|
|
90
|
+
collection.add(mcard_obj)
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
collection.update_handle(handle_name, mcard_obj)
|
|
94
|
+
status = "Updated"
|
|
95
|
+
except Exception:
|
|
96
|
+
try:
|
|
97
|
+
collection.add_with_handle(mcard_obj, handle_name)
|
|
98
|
+
status = "Created"
|
|
99
|
+
except Exception as e:
|
|
100
|
+
status = f"Failed to register handle: {e}"
|
|
101
|
+
|
|
102
|
+
return {"success": True, "status": status, "hash": mcard_obj.hash}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def op_augment(impl: dict[str, Any], target: MCard, ctx: dict[str, Any]) -> dict[str, Any]:
|
|
106
|
+
"""Execute the Baldwin Augment (+) operation.
|
|
107
|
+
|
|
108
|
+
Additive Extension: A -> A ⊕ E.
|
|
109
|
+
Adds a new facet, metadata, or extension step without disturbing existing invariants,
|
|
110
|
+
preserving triadic syntactic closure.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
impl: Configuration dict for augment:
|
|
114
|
+
facet (str): Name of the facet or extension.
|
|
115
|
+
extension (dict): Additional attributes or execution step.
|
|
116
|
+
target: Target MCard to augment.
|
|
117
|
+
ctx: Execution context.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
Dict containing the augmented manifest, new MCard, and closure proof.
|
|
121
|
+
"""
|
|
122
|
+
import copy
|
|
123
|
+
|
|
124
|
+
import yaml
|
|
125
|
+
|
|
126
|
+
from clm.layer1.operations.split import _parse_manifest, ensure_triadic_closure
|
|
127
|
+
|
|
128
|
+
manifest = _parse_manifest(target)
|
|
129
|
+
facet = impl.get("facet", ctx.get("facet", "extension"))
|
|
130
|
+
extension = impl.get("extension", ctx.get("extension", {"augmented": True}))
|
|
131
|
+
|
|
132
|
+
updated = copy.deepcopy(manifest)
|
|
133
|
+
if isinstance(updated.get(facet), dict) and isinstance(extension, dict):
|
|
134
|
+
updated[facet].update(extension)
|
|
135
|
+
elif isinstance(updated.get(facet), list) and isinstance(extension, list):
|
|
136
|
+
updated[facet].extend(extension)
|
|
137
|
+
else:
|
|
138
|
+
updated[facet] = extension
|
|
139
|
+
|
|
140
|
+
final_manifest = ensure_triadic_closure(updated)
|
|
141
|
+
yaml_content = yaml.dump(final_manifest, default_flow_style=False)
|
|
142
|
+
new_card = MCard(yaml_content)
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
"success": True,
|
|
146
|
+
"operator": "augment",
|
|
147
|
+
"facet": facet,
|
|
148
|
+
"syntactic_closure": True,
|
|
149
|
+
"manifest": final_manifest,
|
|
150
|
+
"hash": new_card.hash,
|
|
151
|
+
"content": yaml_content,
|
|
152
|
+
"mcard": new_card,
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
__all__ = ["op_load_file", "op_insert", "op_augment"]
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base classes and protocols for operations.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from collections.abc import Callable
|
|
6
|
+
from typing import Any, Protocol, runtime_checkable
|
|
7
|
+
|
|
8
|
+
from clm.layer0.model.card import MCard
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@runtime_checkable
|
|
12
|
+
class Operation(Protocol):
|
|
13
|
+
"""Protocol for operation callables.
|
|
14
|
+
|
|
15
|
+
All operations must be callable with signature:
|
|
16
|
+
(impl: Dict, target: MCard, ctx: Dict) -> Any
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __call__(self, impl: dict[str, Any], target: MCard, ctx: dict[str, Any]) -> Any:
|
|
20
|
+
"""Execute the operation.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
impl: Concrete implementation configuration from CLM
|
|
24
|
+
target: The target MCard
|
|
25
|
+
ctx: Execution context
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Operation result (type depends on operation)
|
|
29
|
+
"""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class OperationRegistry:
|
|
34
|
+
"""Registry for operation handlers.
|
|
35
|
+
|
|
36
|
+
Provides a centralized place to register and retrieve operations.
|
|
37
|
+
Supports dynamic registration for extending with custom operations.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(self):
|
|
41
|
+
self._operations: dict[str, Callable] = {}
|
|
42
|
+
|
|
43
|
+
def register(self, name: str, handler: Callable) -> None:
|
|
44
|
+
"""Register an operation handler."""
|
|
45
|
+
self._operations[name] = handler
|
|
46
|
+
|
|
47
|
+
def register_many(self, operations: dict[str, Callable]) -> None:
|
|
48
|
+
"""Register multiple operation handlers at once."""
|
|
49
|
+
self._operations.update(operations)
|
|
50
|
+
|
|
51
|
+
def get(self, name: str) -> Callable | None:
|
|
52
|
+
"""Get an operation handler by name."""
|
|
53
|
+
return self._operations.get(name)
|
|
54
|
+
|
|
55
|
+
def has(self, name: str) -> bool:
|
|
56
|
+
"""Check if an operation is registered."""
|
|
57
|
+
return name in self._operations
|
|
58
|
+
|
|
59
|
+
def list_operations(self) -> list:
|
|
60
|
+
"""List all registered operation names."""
|
|
61
|
+
return list(self._operations.keys())
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class ExampleRunnerMixin:
|
|
65
|
+
"""Mixin providing generic example running capability.
|
|
66
|
+
|
|
67
|
+
Reduces code duplication in operations that need to run
|
|
68
|
+
batches of examples and aggregate results.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
@staticmethod
|
|
72
|
+
def run_examples(
|
|
73
|
+
examples: list,
|
|
74
|
+
executor: Callable[[dict], dict[str, Any]],
|
|
75
|
+
validator: Callable[[dict[str, Any], dict[str, Any]], bool],
|
|
76
|
+
) -> dict[str, Any]:
|
|
77
|
+
"""Run examples through an executor and validate results.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
examples: List of example dicts with 'input' and optionally 'expected_output'
|
|
81
|
+
executor: Function that takes input_data and returns result dict
|
|
82
|
+
validator: Function that takes (result, expected) and returns bool
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
Aggregated result with 'success' and 'results' keys
|
|
86
|
+
"""
|
|
87
|
+
results = []
|
|
88
|
+
for example in examples:
|
|
89
|
+
input_data = example.get("input", example)
|
|
90
|
+
|
|
91
|
+
# Execute
|
|
92
|
+
try:
|
|
93
|
+
result = executor(input_data)
|
|
94
|
+
except Exception as e:
|
|
95
|
+
result = {"success": False, "error": str(e)}
|
|
96
|
+
|
|
97
|
+
result["example_name"] = example.get("name", "unnamed")
|
|
98
|
+
|
|
99
|
+
# Validate against expected if provided
|
|
100
|
+
expected = example.get("expected_output", {})
|
|
101
|
+
if expected:
|
|
102
|
+
result["passed"] = validator(result, expected)
|
|
103
|
+
else:
|
|
104
|
+
result["passed"] = result.get("success", False)
|
|
105
|
+
|
|
106
|
+
results.append(result)
|
|
107
|
+
|
|
108
|
+
all_passed = all(r.get("passed", False) for r in results)
|
|
109
|
+
return {"success": all_passed, "results": results}
|