NVIDIA-NeMo/RL #4124 (needs
Gym #4128 and
Gym #3368). Old RL links pin c617a2c, the first reviewed head;
new RL links pin 2f3649d, the current head; Gym links pin 507d15c.
token_capture.selection_policy, picks which calls count: returned_history (the default: the calls in the agent's output) or all_captured (every call Gym recorded).Nine pages on this PR, one question each. This one: what the author's redesign changed in how calls become rows.
Gym already sent the whole forest at the first reviewed head. Its call list holds every call, discarded ones included, with parent links. That part did not change.
Two RL steps changed. First, which calls count: the new selection_policy setting (nemo_gym.py L1305).
Second, how those calls become rows, _plan_selected_calls. The old code walked the kept list top-down and required one straight line per tree.
The new code sorts the end calls and walks each one back to its root.
The rows below are the real output of each commit's _plan_selected_calls, run on the same four small graphs.
returned_history gives the same rows as the old code everywhere except case 3, where the old code failed. all_captured also trains the calls the agent discarded (c4, c2), with the same reward as the rest of the rollout.
One exception: a call that failed, that nothing continues, and that isn't the scored answer is left out (L1324).
The script is plan_old_vs_new.py: it pulls _plan_selected_calls out of each commit and runs it on Gym's own record types.
With forest_training off, RL still uses the older path, not the planner. All paths end in the same Gym function, verify_and_linearize, which takes one end call and walks back to the root.
They differ only in which calls count:
| Proposal | At 2f3649d |
|---|---|
| Gym always returns the whole forest | Yes, and it already did at the first reviewed head. The new head needs Gym #4128 (the close route and an admission field). That PR is public, but RL's Gym pin doesn't include it yet. |
| RL walks from each leaf back to the root | Yes. One row per end call, through the same walk as the path without forest training. A shared call trains once (loss off in later rows). |
| RL options for which paths to train: main path, whole tree, subagents | Mostly. returned_history is the main path the agent kept; all_captured is the whole tree. They are a fixed list (a Literal plus an if/elif), not a plug-in point.
The stacked #4285 adds main_chain, a different all, and custom functions under its own call_selection setting. |
| Simple agent and compaction use the same reassembler | Partly. With forest_training on, both go through the planner (case 1 gives one row). With it off, the older path still runs. |
| Subagents | Partly. all_captured skips the one-session check, so calls from several sessions train if Gym records them under the rollout. They all share one reward, and no agent roles are used. returned_history still raises on more than one session. |
all_captured sits inline in nemo_gym.py, while returned_history is a function in gym_selection.py.
The pending review asks for both to sit behind one lookup in gym_selection.py, so #4285's policies land as new entries under this setting instead of a second one (proposed, not in the PR).