Extension playbook¶
Where ThunderGraph Model is designed to be extended safely—and where you should not hook in without treating the change as a library contribution.
Supported extension surfaces¶
Execution (tg_model.execution)¶
Application code (default): Prefer instantiate(SomeSystem) or SomeSystem.instantiate() to get a ConfiguredModel, then ConfiguredModel.evaluate(inputs={slot: Quantity, …}). Compilation is lazy (cached on the model), validation runs per the evaluate policy (default: on), and each call uses a fresh RunContext unless you pass run_context= for tests or custom runners. Input keys should be ValueSlot handles from that model (or the slot’s stable_id string for scripts).
Extensions, tools, async, and debugging (explicit pipeline): Call compile_graph, validate_graph, Evaluator, and RunContext directly when you need Evaluator.evaluate_async, to reuse one context across steps, to inspect the graph or handlers, or to mirror low-level behavior in tests. Do not fork the evaluator unless you are fixing a bug in the library.
RunContext remains the per-run mutable state carrier; the façade builds one for you on each evaluate by default.
External compute (tg_model.integrations)¶
Implement
ExternalCompute(sync) orAsyncExternalCompute(async withevaluate_async).Optionally implement
ValidatableExternalCompute.validate_bindingsovalidate_graph(..., configured_model=cm)can check units before evaluation.Wire with
ExternalComputeBindingandattribute(..., computed_by=...); uselink_external_routeswhen returning multiple outputs.
Analysis (tg_model.analysis)¶
Use
sweep,compare_variants,dependency_impactas tools over existingConfiguredModel/DependencyGraph/RunResultinstances. New analysis is usually new functions in this package or in your product code, not a plugin API.
What is not a stable extension API¶
Internal graph construction (
graph_compiler, dependency node kinds) — treat as library internals unless you are contributing totg_model.Private helpers (
_*modules, ad hoc compiler passes) — may change without notice.Subclassing
Evaluator,ConfiguredModel, orDependencyGraph— not supported; open an issue or PR if you need a seam.
Practical workflow¶
Model your domain with
System/Part/Requirementanddefine.Keep the root
Systemstructural; move executable logic into owned parts or requirement packages.Run scenarios with
ConfiguredModel.evaluatein product code and notebooks unless you need the explicit pipeline (see Execution above).For tool-backed values,
ExternalComputeBinding+validate_graphwhen possible (the façade runs validation before evaluation by default; explicit callers runvalidate_graphaftercompile_graph).Add tests under
tests/unit/ortests/integration/that mirror your usage (see Testing).If you need behavior that cannot be expressed with declarations and external compute, document the gap and consider a focused PR to
tg_modelrather than monkey-patching.
References¶
End-user narrative: Quickstart (Concrete Example) (recommended
evaluatepath vs explicit pipeline).Requirement authoring (leaf vs package, migration): Concept: Requirements — parameter / attribute / constraint (DEFAULT), FAQ.
Execution Pipeline (Compile -> Instantiate -> Graph -> Evaluate)
API: API Reference