The _summary Convention
When a job completes, the Marqov dashboard displays its result. You can control what appears as summary cards at the top of the job detail page by including a _summary key in the result dict.
How It Works
The dashboard component (WorkflowExecutionDashboard) checks for a _summary field in the job result. If present, it renders each key-value pair as a card:
- Keys become card titles (displayed as small muted text)
- Values become card content (displayed as large bold text)
Cards are laid out in a responsive grid: 2 columns on mobile, 4 columns on desktop.
Returning _summary
The _summary dict must be a top-level key in the result returned by your main() function. Values must be strings.
async def main(client, params):
dispatch = my_workflow(**params)
result = await dispatch.run(client)
return {
"result": result,
"_summary": {
"Energy": f"{result['energy']:.4f} Ha",
"Error": f"{result['error']:.4f} Ha",
"Iterations": str(result["iterations"]),
"Backend": params.get("backend", "local"),
},
}This renders four cards on the dashboard:
+------------------+------------------+------------------+------------------+
| Energy | Error | Iterations | Backend |
| -1.8512 Ha | 0.0023 Ha | 15 | sv1 |
+------------------+------------------+------------------+------------------+Requirements
- Use the
main(client, params)entry point strategy. The auto-detected single-workflow strategy does not give you a place to attach_summaryto the result. - All values in the
_summarydict must be strings. The dashboard renders them as-is. - The
_summarykey is passed through alongsideresultand_workflow_metadatain the enriched result format.
Example: Without vs With _summary
Without _summary
The job result is stored but the dashboard only shows the raw JSON output and the workflow execution graph. Users have to dig into the result to find key metrics.
async def main(client, params):
dispatch = bell_experiment(params)
result = await dispatch.run(client)
return {"result": result}With _summary
Key metrics are highlighted as cards at the top of the job page, making results scannable at a glance.
async def main(client, params):
dispatch = bell_experiment(params)
result = await dispatch.run(client)
counts = result.get("counts", {})
total = sum(counts.values())
return {
"result": result,
"_summary": {
"Shots": str(total),
"State |00>": f"{counts.get('00', 0)} ({counts.get('00', 0) / total * 100:.1f}%)",
"State |11>": f"{counts.get('11', 0)} ({counts.get('11', 0) / total * 100:.1f}%)",
"Fidelity": f"{(counts.get('00', 0) + counts.get('11', 0)) / total * 100:.1f}%",
},
}VQE Example
async def main(client, params):
best_energy = float("inf")
best_theta = 0.0
for i in range(params.get("max_iterations", 20)):
theta = optimize(best_theta)
dispatch = vqe_step(theta, params)
result = await dispatch.run(client)
if result["energy"] < best_energy:
best_energy = result["energy"]
best_theta = theta
return {
"result": {
"energy": best_energy,
"theta": best_theta,
},
"_summary": {
"Ground State Energy": f"{best_energy:.6f} Ha",
"Optimal Theta": f"{best_theta:.4f} rad",
"Iterations": str(params.get("max_iterations", 20)),
"Chemical Accuracy": "Yes" if abs(best_energy - (-1.8512)) < 0.0016 else "No",
},
}Tips
- Keep the number of summary cards to 4-6 for a clean layout.
- Format numbers with appropriate precision (
.4ffor energies,.1ffor percentages). - Include units in the value string (e.g., “Ha”, “rad”, “ms”).
- Use the summary for the most important metrics; put detailed data in
result.