feat(routines): let add_exercise_with_sets record a rep range - #17
Open
wromansky wants to merge 2 commits into
Open
feat(routines): let add_exercise_with_sets record a rep range#17wromansky wants to merge 2 commits into
wromansky wants to merge 2 commits into
Conversation
A planned set could only carry a single rep number, so "3 x 8-12" was stored as 8 and the top of the range lived nowhere. That is fine until the trainee's progression rule depends on it: "add weight once you beat the top of the range" has nothing to beat, and a coach quoting a range in conversation leaves the routine disagreeing with what the trainee was told. max_reps is optional and writes the max_repetitions config that CONFIG_KINDS already defines for set_slot_entry_config, so this only reaches an existing capability from the high-level authoring call. A max_reps below reps is refused before the slot is created, rather than written and left for someone to notice later: reps is the bottom of the range, and a top beneath it is a caller mistake, not a plan. Equal values are allowed — a fixed prescription is a range of one.
This was referenced Aug 31, 2026
The tool table documents each signature explicitly, so a new parameter leaves it stale. PR wger-project#7 exists because this table drifted once already.
wromansky
marked this pull request as ready for review
September 1, 2026 19:31
This was referenced Sep 1, 2026
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.
The problem
add_exercise_with_setstakes a singlerepsnumber. A plan that means "3 × 8-12" has to be written as8, and the top of the range is lost.That is tolerable when the range is decoration. It stops being tolerable when the trainee's progression depends on it. A common double-progression rule is:
With no stored top, the middle branch is undecidable — there is nothing to beat — and the rule silently degenerates into "hold forever." A coach quoting "8-12" in conversation also leaves the routine disagreeing with what the trainee was told, which is exactly the kind of drift the plan is supposed to prevent.
I hit this driving the server with an LLM client: it quoted rep ranges in chat and wrote single numbers to wger, because that is all the tool accepts.
The change
add_exercise_with_setsgains an optionalmax_reps.max_repetitionsconfig — themax_repskind already exists inCONFIG_KINDSand is already reachable throughset_slot_entry_config. This change only reaches that existing capability from the high-level authoring call, so there is no new endpoint, model or dependency.max_repsbelowrepsis refused before the slot is created, so an invalid range writes nothing rather than leaving a half-built slot for someone to find later.repsis the bottom of the range; a top beneath it is a caller mistake, not a plan.list_slot_entry_configsalready returns every config kind by default, somax_repetitionscomes back out the same way it went in.Tests
Four new cases in
tests/test_weight_units_and_rir.py:max_repsrecords the top alongside the bottommax_repsbelowrepsis refused and writes nothing (assertsslot_createwas never called)max_repsequal torepsis acceptedFull suite: 251 passed.
ruff checkandruff format --checkclean on the touched files.Note
One of four open drafts in this area: #16 (weight unit follows the trainee's profile), #18 (unit names instead of ids), #19 (
log_set'sexercise_iddocstring) and this one. Checked withgit merge-treeagainst the current heads: #18 and #19 conflict with this branch only in the## Unreleasedblock ofCHANGELOG.md. #16 conflicts insrc/wger_mcp/tools/routines.pyas well — both PRs edit the sameunit = as_weight_unit(...)statement inadd_exercise_with_sets, #16 to source the default from the trainee's profile and this one to add themax_repsrange check. The resolution is mechanical (keep both), but it is a real code conflict, not just a changelog one.One thing for whoever lands these second: three of this PR's tests call
_mock_creationwithout passingweight_unit. Once #16 lands, they rely on its version of_mock_creationmocking/userprofile/. If that mock is dropped while resolving the conflict, those tests quietly start making real outbound requests and assert through the fallback path instead of the one they name.