Add pddl-visualizer plugin (v0.1.0)#59
Draft
omereliy wants to merge 2 commits into
Draft
Conversation
New Tier 1 (pure-pip) plugin that renders a PDDL state or trajectory to an image via a domain-independent predicate-graph: objects are nodes, unary predicates become node properties, binary predicates become labelled edges, n-ary predicates become predicate-nodes, and numeric fluents become annotations. Consumes the grounded predicate-string state/trajectory that pddl-parser and pddl-validator already emit, so it does no PDDL parsing or simulation itself. - MCP server with two tools: render_state (PNG/SVG) and render_trajectory (animated GIF or filmstrip PNG, with a shared per-frame layout and highlighting of facts added at each step). - Rendering stack: networkx + matplotlib (Agg) + Pillow. No Docker, no graphviz/system binaries. - Axis limits are fitted to the true rendered extents of nodes and labels so long peripheral labels never clip; trajectory frames share one unioned data window so node positions stay pixel-stable across frames. - verify.py: 18 smoke/regression tests. Registered in both marketplace catalogs and the MCP protocol test; documented in README and CLAUDE.md.
Surfaced while rendering a 16-object, 30-step barman plan: - render_trajectory GIF held every frame's matplotlib figure open at once (warned past 20 figures, wasted memory). Rewrite to a two-pass measure-then-render so only one figure is open at a time while still sharing one data window across frames for pixel-stable node positions. - Wrap long titles (verbose grounded action names) and enable constrained_layout for filmstrips so per-panel titles no longer collide. Adds a regression test asserting a 24-frame trajectory leaks no figures and never triggers the open-figure warning. verify.py: 19 tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new
pddl-visualizerplugin (v0.1.0) that renders a PDDL state or trajectory to an image, using a domain-independent predicate-graph. It consumes the grounded predicate-string state/trajectory thatpddl-parserandpddl-validatoralready emit, so it does no PDDL parsing or simulation itself — it's a pure render function.Tier 1 (pure pip), no Docker, no system binaries (networkx + matplotlib + Pillow; deliberately not graphviz/
dot).Mapping (any domain, zero config)
(handempty)(clear a)a(on a b)a → blabelledon(connected x y z)(= (fuel t) 5)fuel=5annotation on nodet(or side panel)Tools
render_state(state, output_path?, layout?, fmt?, title?)→ PNG/SVG.render_trajectory(trajectory, output_path?, fmt?, layout?, highlight_changes?, frame_seconds?)→ animated GIF or filmstrip PNG. Eatsget_trajectory's output dict directly; node layout is shared across frames and facts added at each step are highlighted.Rendering quality
Axis limits are fitted to the true rendered extents of nodes + labels, so long peripheral labels never clip on any layout. Trajectory frames/panels share one unioned data window, so node positions stay pixel-stable across frames.
Verification
plugins/pddl-visualizer/tests/verify.py: 18 smoke/regression tests (both tools, all input forms + layouts, GIF/filmstrip, a no-clip regression guard, the shared-window math, FastMCP arg-error wrapper)..claude-plugin/marketplace.jsonand.cursor-plugin/marketplace.json; added to the shared MCP protocol test; documented inREADME.mdand rootCLAUDE.md.tests/static_checks.py,tests/mcp_protocol_test.py, andinstall_marketplace.shauto-discovery all pass.