Repository navigation
Update dependency jupyddl to v2.5.0 - #16
Open
renovate[bot] wants to merge 1 commit into
Open
renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
|
Tick the box to add this pull request to the merge queue (same as
|
renovate
Bot
force-pushed
the
renovate/jupyddl-2.x
branch
from
November 7, 2026 15:18
ce9dc6a to
1bb8ba4
Compare
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.
This PR contains the following updates:
==2.3.0→==2.5.0Release Notes
openplan-labs/PythonPDDL (jupyddl)
v2.5.0Compare Source
Added
titles are Conventional Commits (a
pr-titlecheck enforces it), and oneach merge
release.ymltakes the largest bump the PR's title and commitsask for —
fix→ patch,feat→ minor,feat!→ major — bumps the versioneverywhere, dates this changelog, commits and tags
main, and publishes toPyPI. No release PR and nothing to approve. A
release:*label overridesthe bump. See
.docs/RELEASING.md..docs/PUBLISHING.mdsays why andwhere we mean to publish jupyddl as citable research software — a Zenodo DOI
per release, a JOSS paper, ICAPS workshops for the research results — with a
readiness checklist, the paper outline, the AI-usage disclosure JOSS requires
and how contributors can be considered for authorship. The README states the
project's aim (a framework to build on and to explain algorithms with) and
its Cite section says which version the 2021 preprint describes.
declaring
jupyddl.planners,jupyddl.heuristicsorjupyddl.generatorsentry points; once it is installed,
jupyddl solve -s <its planner>workswithout anyone importing it. Discovery is lazy (the CLI runs it before
building its parser, the library only when asked for a name it does not
know), a built-in name always wins, a plugin that fails to import is skipped
with a warning, and
JUPYDDL_NO_PLUGINS=1turns it off.jupyddl pluginslists what was found.
.docs/EXTENDING.md, a guide to building on the framework: a heuristic,a planner from a priority function, a planner from scratch with the full
budget/observer contract, a generator, how to test the guarantees you claim,
and how to ship it all as a plugin. Every example runs in the test suite, so
the guide cannot drift from the API.
best_firstaccepts a tuple priority for tie-breaking(
lambda g, h: (g + h, h)); observers are given its first element asf.pull-request template, a Propose an algorithm issue template, and an
"Adding an algorithm" section in
CONTRIBUTING.md.Changed
CI now runs on pull requests, including from forks.
testsandbuildwere
on: [push], which never fires for a fork, so an outside contributor'sPR showed no checks at all. They now run on every pull request and on pushes
to
main.Documentation lives in one place:
.docs/. It was spread over threedirectories —
docs/for the contributor files and the README charts,promo/for the videos and screenshots,.docs/for the research notes —with no rule saying which took what, so every new file was a guess. The
research notes, the release runbook and every image, video and measurement
cache are now under
.docs/, with binaries in.docs/assets/. This alsomatches
pymapf, the sibling project.Paths quoted in the released sections below are the ones that were correct
at the time.
promo/rl-data.jsonis now.docs/assets/rl-data.json, anddocs/images/is now.docs/assets/.CONTRIBUTING.mdandCODE_OF_CONDUCT.mdmoved to.github/rather than.docs/: GitHub only recognises those two files in the repository root,.github/ordocs/, so filing them under.docs/would have silentlydropped the contributing link on the issue and pull-request forms.
Fixed
Wrong answers from the task model and the heuristics. Each of these returned a
plan, a cost or a value without complaint, and
validate_planaccepted theplans because it replays them through the same model. They are now pinned by
tests/test_semantics.pyon tiny tasks whose right answer is obvious.a derived fact left it true, and
(not <derived>)held from the initial stateon. Axioms are now recomputed from scratch after every step, and a negated
derived fact is maintained with them. Negating a derived predicate inside
another rule needs stratification and is now refused by name.
(not (at a))and(at a)could hold together, and awhenthat re-added adeleted atom did the same. For complement facts the delete now wins.
(total-cost)metric an action with no cost effectnow costs 0, as in IPC planners, rather than 1 — on pegsol and sokoban the
"optimal" planners were optimising the wrong objective. A cost inside
whenwas charged whether or not the condition held; it is now refused, as is a
negative cost.
(distance a c)fora road that does not exist cost nothing. Conditions and effects reading one
now fail, as PDDL 2.1 specifies.
blindwas not admissible when any action is free, which every PDDL 3compilation introduces, so
astar+blindcould return a costlier plan.h1/h2/hmcrashed on every numeric or timed task, and LM-cutcrashed on an empty goal, which made the default
solve()crash too.lmcutandh2claimed admissibility on tasks with conditional effects,where they can overestimate. The instance flag now says so.
solve_task(task, "astar")usedhff, which is not admissible, so thedefault A* was not optimal. Optimal planners now default to
lmcut.-H nonealso fell through to
hff; it now meansblind.make_heuristic(LMCutHeuristic, task)returned the class unbuilt, and theplanner then crashed calling it on a state. Classes and partials are now built.
PYTHONHASHSEED. Fact ids followed string hashing,so LM-cut broke ties differently in every process: gripper with
astar/lmcutexpanded 1725, 1758 or 1760 nodes and returned different plans. Ids are now
assigned in sorted order, so a benchmark reproduces.
iddfs,idastarandehcignored their budget, so--time-limit 0.5on blocksworld12 ran for minutes.
beampolled once per layer andbnbkeptevaluating LM-cut on every sibling after the budget fired; both now stop at
once. A new contract test runs every planner where the budget is the only
thing that stops it.
iddfs,bnb), and abnbplan found under one as optimal. Hitting the cap now setstruncated,as does a search deeper than Python's recursion limit.
bfsandiddfswere listed as optimal. They minimise plan length;on errands they return cost 16 where 10 is optimal. They are no longer in
OPTIMAL_PLANNERS, and the workbench no longer badges them.search, smeared every repaint on a narrow terminal (lines were never clipped
to its width), and logged ten times too often when not on a terminal.
idastar,ehc,hcandbeamwithout a heuristic raise a clearValueErrorinstead of aTypeErrorfrom deep inside the search;MultiObserveraccepts positional arguments like the base class; theSearchObserverdocstring no longer claims hooks are called defensively.bad input, 3 stopped by a budget, 4 a plan that failed validation. Before,
unsolvable, out-of-budget and a crash all exited 1. Bad input — a missing
file, a parse error, an unknown planner — is one line on stderr instead of a
traceback (
JUPYDDL_DEBUG=1brings the traceback back).--versionexists.jupyddl demoandjupyddl benchmark demosnever finished: neither tooka budget, and
demo's blind runs on blocksworld12 do not end. Both now stopeach search after 10 s by default;
animateanddemoaccept--max-expansionsand--time-limitlikesolve.benchmarkchecks--planners,--heuristicand--metricbefore runningrather than reporting
nosuch 0/13, and every chart option checks for thevizextra before searching instead of failing (or silently writingnothing) afterwards.
Axis limits cannot be NaN or Inf) andcoloured the wavefront NaN; in the workbench, an infinite
horfmade theprogress message invalid JSON and aborted the run.
__observe-1#1) anddisjunct tags; it now records the plan the user reads.
.github/entirely while atest checks
CONTRIBUTING.mdis there. Only.github/workflows/is leftout now.
buildrunstwine check --strict, likereleasedoes.blackis pinned to one major version in both the dev extra and theformatworkflow, which installed whatever was newest; Renovate now pinsthird-party actions to commit digests.
scoring level with the successor the plan took counted as a correct ranking,
so a model that outputs a constant scored 1.000 — and checkpoint selection,
which reads top-1, could prefer a collapsed epoch.
Corpus.splitalso gavethe held-out side no ranking groups, so the "held out" top-1
jupyddl learnprinted was measured over training instances. A tie with
ksiblings nowearns
1/(k+1), a sibling identical to the chosen successor in features andstep cost is not recorded at all, and selection and the reported top-1 use
the held-out groups. The published figures came from the old rule; see the
dated corrections in
.docs/learned-heuristics.mdand.docs/rl-for-search.md.splittreatedX#dagger1as an instance apart fromX; it now groups onthe name before the
#.summarise_transferaveraged each heuristic over the runs it solved, soone that solved only the easy instance looked many times better than one that
solved both. An unsolved run is now charged twice the budget, as
search_costcharges it, and plan cost compares only instances everyconfiguration with any coverage solved. The imitation-only blocksworld mean
the docs quote as 366 is 6 329 under that rule.
another without. A network whose input width is not the feature vector's,
a ragged row, a
sizesfield that does not describe the weights, anon-finite value or a non-positive scale is now a
ValueErroron load.MLP.set_flatchecks the length before writing anything, instead of leavinga wrong-length vector half-applied.
not. Complement facts now key onthe predicate they negate (
not-sampled), so rovers and workshop get a slotper negated predicate. A model trained on a domain with negative
preconditions before this sees different features now; retrain it.
train()with a pure ranking objective and no ranking groups returned itsrandom initialisation as a trained model; it now raises.
learn_heuristicspent a generator passed as
sizeson its first read, recording[]andraising under
cem_iterations; size arguments are now read once, on entry.gripperandworkshopignored their seed. Twenty seeds gave oneinstance, so a split by seed held out copies of training instances, and the
RL stage's tuning and validation sets were the same problems. The seed now
decides which room each ball and the robot start in (every ball still has to
change rooms), and how far along the pipeline each part starts. Every
generated gripper and workshop instance changes;
demos/workshopis the onein which every part starts raw, and
generateno longer reproduces it.blocksworldcompared tower lists in order and skipped the check for two blocks, where 75
of the first 200 seeds came out trivial;
random-stripscould draw a goalthat already held. Both now re-draw only in that case, so every instance that
was not trivial is byte-identical to before.
arguments —
wastarat weights 1 and 5 summarised as one entry with twicethe instances — and recorded
("gbfs", None)as heuristic""although itran
hff. Rows carry aconfiglabel with the arguments(
wastar/hff(weight=5.0), also a new CSV column), whichsummarizeand thedashboard group on; a repeated config is suffixed
#2; andheuristiciswhat
solve_taskactually ran, worked out by the newjupyddl.api.resolve_heuristic.Wrong answers from the PDDL front end. The parser and the PDDL 3 compilations
handed the grounder a different problem from the one written, so plans
validated — against the wrong problem. Each case is now pinned by
tests/test_frontend_semantics.py.beat a delete, so
(at start (busy)) (at end (not (busy)))ended with(busy)true. The at-end effects now apply after the at-start ones and win aconflict, and over-all and at-end conditions are checked in the state after
the at-start effects rather than before them.
alwaysis checked in thatstate too; the other trajectory constraints are refused when a durative
action has at-start effects, because their monitors cannot see it.
sometime-aftercould not be met by the final state. An obligationrecorded by the last action's monitor could never be discharged, so the
plan
[t, r]was reported unsolvable; the goal now accepts the responseholding at the end.
forallaround a trajectory constraint moved inside it:(forall (?x) (sometime (lit ?x)))meant one moment with every?xlit atonce. It is now one constraint per object. A soft constraint under
forallcrashed with an
AttributeError; it is refused by name like the others.forallkept its free variable and could neverbe satisfied; it is now one preference per object. Under
not,or,implyor
existsa preference silently made the goal false; it is now an error.at-most-onceandsometime-aftermonitors ignored the states literalsfired in, a literal could fire after the preferences had been paid out, and
a plan could end before a literal that was already due had fired.
comparisons; they are now compiled as everywhere else. Assigning one object
fluent's value to another took the function's name for an object; it is
refused.
rather than nothing, a metric without
(total-cost)still charged foractions,
maximizewas silently minimised, and(total-time)charged aninstantaneous action 1.
maximize, any metric other than(total-cost)or(total-time)plus weighted(is-violated p)terms, and a metric pricing apreference the goal does not declare are now refused.
ground()edited the domain it was given, so a second problem groundedagainst the same parsed domain inherited the first one's synthetic actions
and lost the domain's own constraints.
:preconditongave an action with noprecondition and
(:goals ...)a problem with an empty goal; unknown keysand sections and a missing
:goalare now errors that name them. Malformedinput —
(?x -),(when (q)),(:goal)— raised a bareIndexError; it isa
PDDLError, and an unbalanced parenthesis names its line.nan,inforinfinitywere read as numbers.(increase (total-cost) (road-length ?a ?b))was refused although:action-costsis listed as native. A cost over static functions is nowevaluated when grounding, so the IPC
transportdomains load.:fluentsnow implies
:object-fluents, and:ucpop,:domain-axiomsand:safety-constraintsare refused by name rather than as unknown flags.v2.4.0Compare Source
Added
jupyddl.learnshipped in 2.3.0 withits results only in
.docs/and a video, which meant the published site saidnothing about the biggest addition in the release. The view carries the
measured run: imitation against
hffandgoalcount, the per-instancespread behind the mean, the logistics loss and why the feature space causes
it, and the three claims that turned out to be wrong. Its numbers are built
from
promo/rl-data.json— the same cache the RL video renders from — sothe page and the video cannot drift apart, and a test pins them together.
Fixed
<main>washidden until Pyodide reported ready, so every page of prose, the requirement
matrix and the new Research view sat behind a full-screen spinner waiting for
a runtime none of them use. The shell now renders immediately from the
committed bundle, the boot notice is a status bar rather than a splash
screen, and only the controls that actually run a planner stay disabled until
the interpreter arrives.
Changed
3.9 reached end of life in October 2025;
requires-pythonmoved to matchwhat is actually tested.
pddl-examplessubmodule advances to a corpus that now grows on its own:it imports fresh domains from planning.domains daily.
openplan-labs.Removed
single-maintainer project does not produce, and its reviewer-assign rule
pinged an inactive account; every recent pull request was merged by hand.
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.