Figure composer
Load figure-style with this skill. The sidecar provides pure geometry,
composition, task-building, and review-schema helpers. It does not call models,
delegate Agents, resolve artifacts, or inspect images from Python.
Inputs
Require a one-sentence claim, target width in millimetres, and concrete
project-relative or absolute data paths. Never use artifact ids as paths. For an
existing figure, inspect the real image with view_image and write the outline
yourself; pixels cannot reveal the source data path.
Workflow
- Build an outline matching
figure_outline_schema(). Put real paths indata_path; usenullfor schematics. - Make panel
athe conceptual hook and panelbthe primary evidence. Use a 12-column grid and one row per sub-claim. - Build one instruction per panel with
panel_task(...). - If
delegate_tasksis advertised, submit the independent panel tasks as one batch. Grant each task the minimum advertised capabilities needed, normallyvisualizationplusproject_read. Require a concrete PNG filename in each output schema. If delegation is unavailable, render the panels sequentially withpython. - Compose returned paths with
compose_figure(...). Do not pass placeholder markers to the composer. - Save the
compose_crops(...)boxes with figure-style'ssave_panel_crops(composite_path, compose_crops(outline)), then callview_imageon the composite and every crop. Fix seams, clipped labels, aliases, empty space, and misplaced panel letters before review. The crops are inspection debris, not products: they live in.cache/figure-style/, never beside the composite or under the output figures directory, and get deleted once the composite passes. - Build one reviewer instruction with
composite_review_task(...). Delegate it withimage_inspection,project_read, andreasoningwhen those capability ids are advertised; otherwise perform the review in the current Agent. - Apply outline revisions and regenerate only affected panels. Stop after three rounds or when there are no blockers and at most two major findings.
Outline example
json{ "claim": "Treatment restores the disease-associated trajectory.", "width_mm": 180, "ncol": 12, "row_heights_mm": [42, 60], "panels": [ { "letter": "a", "role": "schematic", "row": 0, "col": 0, "colspan": 12, "chart_family": "study schematic", "message": "The experiment tests trajectory rescue.", "data_path": null, "ask": "Show cohorts, treatment, sampling, and comparison." }, { "letter": "b", "role": "primary", "row": 1, "col": 0, "colspan": 12, "chart_family": "trajectory plot", "message": "Treatment moves cells toward the healthy trajectory.", "data_path": "results/trajectory.csv", "ask": "Plot disease, treated, and healthy cells with confidence bands." } ] }
Boundaries
- Use
delegate_tasksonly as an explicit Wisp tool; never call delegation frompython. - Use
view_imageonly on a concrete local image file. - Keep data preparation in normal project files. Use
run_in_contextonly when a deterministic render or preprocessing job is long enough to require a persisted Run; Agent delegation itself is not a Run. - Save the accepted composite to a stable project path and report that path.


