Job Bundle Format
Documentation for Job Bundle Format.
Job Bundle Format
In MirrorNeuron, a Job Bundle is the standard deployment package for a multi-agent workflow. It defines the structure of the agent graph, the initial state, and any necessary executable payloads or static data required to run the job in an isolated execution sandbox.
Bundle Structure
A valid job bundle is a directory with the following structure:
my_job_bundle/
├── manifest.json
└── payloads/
├── worker_script.py
└── data.jsonmanifest.json: The declarative workflow definition. It maps out nodes (agents), edges (message routing), and execution policies.payloads/: A required directory containing all external static assets, shell scripts, Python code, and data files referenced by the executor nodes. The runtime resolves any relativesourcepaths in the manifest against this directory before uploading them to the OpenShell sandbox.
The manifest.json Schema
The manifest.json is a JSON document that defines the execution graph.
Top-level Fields
| Field | Type | Description |
|---|---|---|
manifest_version | String | Required. The version of the manifest format (e.g., "1.0"). |
graph_id | String | Required. A unique workflow id. |
job_name | String | Optional. A human-readable name for the job. Defaults to graph_id if missing. |
type | String | Optional. Set to "service" for workflows intended to run until manually stopped. Omit for default batch workflows. system and sysbatch are selected through scheduler policy. |
requiredContextEngine | Boolean | Optional. Set to true when the workflow requires the Context Engine. The runtime checks CONTEXT_ENGINE_ADDR or port 50052 and rejects the run before scheduling agents if the service is unavailable. Defaults to false. |
services | Array | Optional. Services registered by the job. See Services and Health Checks. |
required_services | Array | Optional. Services that must be healthy before job start. |
deployment | Object | Optional. Stable deployment key and metadata. See Deployments. |
schedule | Object | Optional. Periodic or delayed schedule declaration. See Schedules and Events. |
triggers | Array | Optional. Event-trigger schedule declarations. |
parameterized | Object | Optional. Dispatch payload and metadata declaration for scheduled or event-triggered runs. |
metadata | Object | Optional. Custom metadata tags for the job. |
entrypoints | Array | Required. A list of node_id strings where initial inputs will be injected to start the graph. |
initial_inputs | Object | Optional. A map where the keys are node_ids (from entrypoints) and values are arrays of message payloads to seed the job. |
nodes | Array | Required. The list of agent nodes that make up the workflow. |
edges | Array | Required. The list of message-routing edges between nodes. |
policies | Object | Optional. Job-level policies like recovery_mode. |
Nodes (Agents)
Each item in the nodes array defines an agent that will be supervised by the BEAM runtime.
| Field | Type | Description |
|---|---|---|
node_id | String | Required. Unique identifier for this node within the graph. |
agent_type | String | Required. The core runtime primitive. Typically "router", "executor", "aggregator", or "sensor". |
type | String | Optional. The behavioral template (e.g., "map", "reduce", "stream", "batch"). Defaults to "generic". |
role | String | Optional. A human-readable tag describing the agent's domain role (e.g., "researcher", "root_coordinator"). |
config | Object | Optional. Configuration specific to the agent_type and type (e.g., emit_type, pool, uploads). |
resources | Object | Optional. CPU, memory, disk, GPU, device, port, volume, and runtime-driver requirements. |
services | Array | Optional. Services registered by this specific agent. |
requires_services | Array | Optional. Node-scoped service requirements used during placement. |
policies | Object | Optional. Per-agent restart and reschedule overrides. |
Job Types
MirrorNeuron supports four Nomad-inspired job types:
| Type | How to declare | Behavior |
|---|---|---|
service | top-level "type": "service" or scheduler policy | Long-running and restarted/rescheduled by policy until stopped. |
batch | default top-level type | Runs to completion and retries within policy limits. |
system | policies.scheduler.job_type: "system" | Runs one copy on every eligible node. |
sysbatch | policies.scheduler.job_type: "sysbatch" | Runs one one-off copy on every eligible node. |
Example:
{
"policies": {
"scheduler": {
"job_type": "system",
"strategy": "spread"
}
}
}Restart And Reschedule Policies
Job-level policies live under policies.restart and policies.reschedule. Per-agent overrides live under nodes[].policies.restart and nodes[].policies.reschedule.
{
"policies": {
"recovery_mode": "cluster_recover",
"restart": {
"attempts": 3,
"interval_ms": 600000,
"delay_ms": 1000,
"delay_function": "exponential",
"max_delay_ms": 30000,
"mode": "fail"
},
"reschedule": {
"unlimited": true,
"delay_ms": 5000,
"delay_function": "exponential",
"max_delay_ms": 300000
}
}
}See Reliability Guide.
Resource Requirements
{
"resources": {
"cpu_cores": 2,
"memory_mb": 8192,
"devices": [
{
"kind": "gpu",
"driver": "cuda",
"min_memory_mb": 16000,
"count": 1
}
],
"ports": [
{
"label": "api",
"port": 8088,
"protocol": "http"
}
],
"volumes": [
{
"name": "models",
"source": "/mnt/models",
"target": "/models",
"mode": "ro",
"type": "host"
}
],
"runtime_driver": "host_local"
}
}Service Requirements
{
"required_services": [
{
"name": "ollama",
"origin": "external",
"address": "${config.ollama.host}",
"port": "${config.ollama.port}",
"checks": [
{
"type": "http",
"url": "${config.ollama.api_base}/api/tags",
"expected_status": 200
}
]
}
]
}See Services and Health Checks.
Deployment Policy
{
"deployment": {
"key": "agent-api"
},
"policies": {
"update": {
"strategy": "canary",
"canary": 1,
"max_parallel": 1,
"auto_promote": false,
"auto_revert": true
}
}
}See Deployments.
Schedule And Triggers
{
"schedule": {
"kind": "periodic",
"crons": ["0 2 * * *"],
"timezone": "America/New_York",
"prohibit_overlap": true,
"missed_policy": "skip"
},
"triggers": [
{
"name": "dataset-uploaded",
"event_type": "file_uploaded",
"filters": {
"path": {
"prefix": "/datasets/"
}
}
}
]
}See Schedules and Events.
Edges (Routing)
Edges dictate how messages flow between agents after a step completes.
| Field | Type | Description |
|---|---|---|
from_node | String | Required. The node_id of the sending agent. |
to_node | String | Required. The node_id of the receiving agent. |
message_type | String | Required. The event or message type that triggers this edge (e.g., "research_request"). |
The payloads/ Directory
Because MirrorNeuron strictly separates the control plane (BEAM orchestration) from the execution plane (OpenShell sandboxes), any code executed by an "executor" agent must be supplied through the payloads/ directory.
When you configure an executor node to run a script, you declare it in the config.uploads map. The source paths are evaluated relative to the payloads/ directory:
{
"node_id": "python_worker",
"agent_type": "executor",
"config": {
"uploads": [
{
"source": "process_data.py",
"target": "/sandbox/process_data.py"
}
],
"command": ["python3", "/sandbox/process_data.py"]
}
}In this example, the runtime will look for my_job_bundle/payloads/process_data.py and mount it into the OpenShell sandbox at /sandbox/process_data.py.
Blueprint-Scoped Python Dependencies
MirrorNeuron.Runner.HostLocal executor nodes can opt in to an isolated Python virtual environment with python_environment. Dependencies are cached by Python version, requirements contents, and inline package list, so repeated runs reuse the same environment while unrelated blueprints remain isolated.
{
"node_id": "video_worker",
"agent_type": "executor",
"config": {
"runner_module": "MirrorNeuron.Runner.HostLocal",
"upload_path": "person_detector",
"upload_as": "person_detector",
"workdir": "/sandbox/job/person_detector",
"command": ["python3", "scripts/analyze_door_camera_frame.py"],
"python_environment": {
"requirements": "person_detector/requirements.txt",
"packages": ["opencv-python-headless>=4.10,<5"]
}
}
}requirements must be a relative path inside payloads/. Inline packages are normal pip requirement strings. If both are provided, both are installed into the same cached environment. If neither is provided, no environment is created.
The core Docker image only includes generic Python virtualenv support. Blueprint-specific packages such as OpenCV, optimization solvers, browser tooling, and model libraries should be declared by the blueprint, not installed into core. Root-level blueprint requirements.txt files are not automatically installed; put runtime dependency files under payloads/ and reference them explicitly from the executor node.
Example Bundle
Here is a simple example of a complete manifest.json for a Map-Reduce style workflow.
{
"manifest_version": "1.0",
"graph_id": "document_summarizer",
"requiredContextEngine": false,
"entrypoints": ["dispatcher"],
"initial_inputs": {
"dispatcher": [
{"file": "doc1.txt"},
{"file": "doc2.txt"}
]
},
"nodes": [
{
"node_id": "dispatcher",
"agent_type": "router",
"type": "map",
"role": "root_coordinator",
"config": {
"emit_type": "summarize_request"
}
},
{
"node_id": "summarizer_worker",
"agent_type": "executor",
"type": "map",
"config": {
"pool": "default",
"uploads": [
{
"source": "summarize.py",
"target": "/app/summarize.py"
}
],
"command": ["python3", "/app/summarize.py"]
}
},
{
"node_id": "result_collector",
"agent_type": "aggregator",
"type": "reduce",
"config": {
"complete_on_message": true,
"terminal_sink": true,
"complete_run": true
}
}
],
"edges": [
{
"from_node": "dispatcher",
"to_node": "summarizer_worker",
"message_type": "summarize_request"
},
{
"from_node": "summarizer_worker",
"to_node": "result_collector",
"message_type": "summarize_request"
}
],
"policies": {
"recovery_mode": "local_restart"
}
}Loading and Running
You can validate and run a job bundle using the MirrorNeuron CLI:
# Validate the bundle structure and manifest constraints
mn blueprint validate path/to/my_job_bundle
# Execute the bundle in the cluster
mn blueprint run --folder path/to/my_job_bundleExpected validation output:
Job bundle at 'path/to/my_job_bundle' is valid.Before running a third-party bundle, review manifest.json, payloads/, runner, command, pass_env, and any OpenShell policy file. See Security Model.
Via the API (HTTP POST to /api/v1/jobs), the exact same manifest.json shape is accepted, with the payloads assumed to either already exist locally or omitted in pure-router workflows.