Introduction to building runners
This page sets the scene for building your own node templates. After reading it you should know what a HEAT feature package looks like, which components you must supply, and how they fit together inside a running cluster. The next page, Developing runners, walks through writing a runner with the Python runtime and registering it with a manifest.
The big picture
| Concept | Analogy | Purpose in HEAT |
|---|---|---|
| Runner | Expert | A container image that knows how to do one or more things. |
| Node Template | Skill | Declares what the thing is (input/output shape, configuration schema). |
| Session Template | Plan | A DAG that orchestrates when the thing is executed. Used per session. |
| Manifest (.heat) | Resume | Registers your experts & skills with the cluster so the system can use them. |
Minimum ingredients for a new feature
- Runner image - package your logic and include the
heat-runtimePython library. - Node templates - generic, idempotent task declarations that reference a runner type.
- HEAT manifest - single JSON file (
*.heat) that lists your runners, node templates, and high-level feature metadata. - Registration step - upload the manifest via the API or HEAT Control Centre (formerly Cluster Manager). HEAT persists the definitions and starts scheduling.
Once a manifest is registered you can iterate on session templates without rebuilding images. Tweak node configuration only.
Anatomy of a .heat manifest
Below is a trimmed skeleton. The full schema is linked from the $schema property. Use it as a starting point and validate locally before upload.
{
"$schema": "https://heatcommon.blob.core.windows.net/schema/heat-manifest/v1.json",
"manifestVersion": "1.0.0",
"name": "my-feature",
"description": "Enriches VR telemetry with AI driven tagging",
"owner": "simulation-team@company.io",
"website": "https://example.com",
"createdAt": "2025-05-07T10:30:00Z",
"feature": {
"internalName": "myFeature",
"displayName": "AI Tagging",
"icon": "bolt",
"isEnabled": true,
"ownershipType": "ThirdParty",
"description": "Adds semantic tags to raw simulation data."
},
"runnerTypes": [
{
"name": "ai-tagger",
"containerImage": "registry.example.com/ai-tagger:1.0.0",
"cpuLimit": "2",
"memoryLimit": "4Gi",
"description": "Tags events using an ML model",
"enabled": true,
"featureInternalName": "myFeature"
}
],
"nodeTemplates": [
{
"name": "tag-events",
"type": "Processing",
"acceptsMultipleInputs": false,
"requiresConfiguration": true,
"configurationSchema": { "type": "object", "properties": {"model": {"type":"string"}} },
"featureInternalName": "myFeature",
"supportedRunners": ["ai-tagger"],
"hasNonJsonArtifacts": false
}
]
}The example assumes a runner built with the HEAT runtime, published at registry.example.com/ai-tagger:1.0.0, that needs at most 2 CPU cores and 4 GB of memory. It also registers a node template called tag-events that the runner supports.
The manifest only tells HEAT that these concepts exist. Your runner must implement the node templates it declares. Here the ai-tagger image must support the tag-events node template, because HEAT provisions that runner whenever a node with that template needs processing.
Runtime behaviour
Tasks are created in HEAT when the state of a session’s graph changes. Node processing will generally result in an artifact (output data) known as the Node Output, which means downstream nodes (children) will require work to ensure they have reprocessed with the latest data. This piece of work exists as a task within HEAT, which contains the output at the point of task creation. Updating a node therefore may generate tasks.
Here runner pod is your code running in the cluster with the HEAT runtime. The scheduler ensures your code is provisioned and running as a pod within the cluster when tasks exist.
- The Runner Pod starts and continuously polls the Task API for work that matches the node templates it advertises.
- For each task it receives, the runner processes inputs, respects the provided configuration, and posts a JSON/binary result.
- HEAT updates state, potentially enqueuing downstream tasks. Idempotence is critical - each task must succeed when replayed with identical inputs.
Typical folder layout
A typical feature project might consist of your heat manifest, dependencies and then containerisation pieces to describe how to build your image. A runner is a containerised application, where the entry-point would typically be executing your python application and triggering the runtime.
my-feature/
├── my-feature.heat # manifest
├── docker-compose.yml # for building the docker image
├── Dockerfile # for building the docker image
├── requirements.txt # dependencies (ie. heat runtime)
└── src/
└── main.py # your source codeRelated
- Developing runners: build the Python entry point and package the image.
- Session templates: reference your node templates inside a graph.
- Features: upload and manage
.heatmanifests in Control Centre.
A field-by-field manifest reference and a session-template walkthrough for this example are not available today. Use the manifest skeleton above and the schema linked from its $schema property.