Repository navigation
bug(models): /gentle:models shows global assignments instead of the pinned profile routing #2276
Description
Before submitting
- I searched open and closed issues and did not find a report of this problem.
- I reviewed this report and removed credentials, tokens, private paths, hostnames, and other sensitive data.
The submitting agent performed these checks.
Problem
With a pinned profile, /gentle:models can name that profile in its header while its role rows display saved global routing instead of the effective pinned routing. Working assignments therefore appear missing or different.
The initial observation came from another user's Discord livestream, not from our local interactive session. The affected user, @j0k3rdev, identified the pin as the factor causing confusion during the Discord livestream. The isolated simulation described below was performed separately by the reporting agent, not by @j0k3rdev. The supplied screenshot shows Current profile: gemini-full (pinned), several roles with model=inherit, and review-refuter/review-validator with Pi persisted default model. Agents reportedly launch with the assigned models. Removing the pin has not been independently verified as a fix. The livestream installation versions are unknown.
Steps to reproduce
Synthetic reproduction against the inspected gentle-pi 4.2.0 implementation:
- Prepare empty saved global routing, or assign a worker a synthetic saved/model value.
- Prepare a named profile assigning that role a different model and pin it to a test repository.
- Invoke the /gentle:models handler and inspect its role labels.
- Resolve effective routing for that repository.
- Compare otherwise identical pinned and unpinned scenarios.
An isolated stdin simulation exercised extracted implementation functions handleModelsCommand, renderAgentLabel, routingDefaultLabel, pinnedEffectiveModelConfig, readEffectiveModelConfig, and readReviewerModelConfig, with configuration boundaries mocked. Four empty/explicit saved-routing and absent/present pin combinations passed. Reviewer session-binding precedence was also checked. No provider calls or real configuration changes were made.
This is a synthetic functional reproduction, not a real interactive TUI or end-to-end launch reproduction.
Expected and actual behavior
Expected: make the displayed configuration authority clear. If this panel intentionally edits global routing while a pinned profile governs execution, distinguish those global assignments from the pinned effective models. The pinned-profile header should not make the displayed global rows look like that profile's effective assignments.
Actual:
- Empty saved routing: the panel shows inherit / Pi persisted default model with or without the pin, although effective routing changes to the pinned models.
- Explicit saved routing: the panel shows saved/model while effective routing uses the different pinned model.
This does NOT demonstrate broken execution or lost assignments. The global-edit semantics may be intentional; the bug report concerns confusing presentation when the displayed and effective routing authorities differ.
Source evidence in the inspected package:
- extensions/gentle-ai.ts:3524-3526 opens the panel with saved routing.
- Lines 3449-3455 and 2719-2727 render inherit/persisted-default labels for absent entries.
- Lines 2301-2318 resolve effective pinned routing; reviewer session bindings take precedence over the pin.
- Lines 3508-3512 and 3803 already warn that global changes do not govern pinned repository subagents.
Related, not confirmed exact duplicates: #1012 concerns sparse canonical routing hiding effective materialized assignments; #897 concerns resolved model identity in the Agents UI.
Verification limits: the focused tests/gentle-ai.test.ts invocation and tests/runtime-harness.mjs each exited 1 before assertions in an isolated package copy because @earendil-works/pi-coding-agent was missing. No dependencies were installed or test commands retried. The separate extracted-function simulation exited 0. Full TUI behavior and actual model launches remain unverified.
gentle-pi version
4.2.0 (locally inspected package and simulation; livestream user's version unknown)
Pi version
1.2.0 (local environment; livestream user's version unknown)
Operating system
Windows (WSL)
Relevant logs or error output (optional)
Existing isolated test runners: exit 1 before functional assertions
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@earendil-works/pi-coding-agent'
Separate extracted-function simulation: exit 0
PASS: 4 display/routing scenarios; session binding outranks pin. No provider calls; boundaries mocked.
Activity
carlosmoradev commentedon Oct 15, 2026
Great catch and very precise reproduction, @Denver2828.
Confirming the diagnosis:
/gentle:modelsdeliberately edits the saved global routing (models.json), whichucan capture into the current profile. At launch time,pinnedEffectiveModelConfig(cwd)correctly outranks global routing, so subagents do launch with the pinned profile.The confusion observed on stream is purely a presentation mismatch in
SddModelPanel.renderAgentList:Current profile: <name> (pinned)(so the user knows whatuwill update).Current assignments:, which naturally makes anyone read them as the assignments of that pinned profile. When global config is empty or different, showinginheritmakes it look like the pin was lost or ignored.A surgical fix is to make the authority explicit on that section header:
Global assignments (subagents in this repo resolve pinned profile):Global assignments:This preserves the exact 15 rows of list chrome (
AGENT_LIST_CHROME_ROWS = 15) without list layout shifts or height truncation on narrow terminals, while eliminating the ambiguity.I have a focused test and this exact fix verified locally against
b011e52d8(124/124 tests pass). Happy to open the PR whenever maintainers approve the issue scope.efirvida commentedon Oct 21, 2026
Adding a session-profile case and a behavioral request beyond the presentation-only fix discussed above: when a session uses profile B while the globally active profile is A,
/gentle:modelsshould display and edit the agent models of B, rather than modifying global routing that this session does not consume. A clearer global-assignment heading would help, but would not fulfill this request.Static code inspection at commit
15eb11a9dfff37336a187d4d31f67b0aeb3d3c93found:handleModelsCommand, lines 3675–3705 initializes agent rows from saved global routing. The selected profile contributes the orchestrator entry, not that profile's agent routing.resolveCurrentProfileTargetselects repository pin, otherwise globalactive, with no session-binding lookup.updateCurrentProfileFromSavedRouting, lines 3848–3900 snapshots global effective routing and resolves the pin/active target again foru. Consequently, changing only the displayed rows would leave the write destination inconsistent with the requested session behavior.resolveSessionProfile, lines 143–166 already defines the effective precedence: explicit session binding, then frozen inherited profile, then shared defaults. Its associated label/routing helpers are a candidate for keeping this panel aligned with session resolution, rather than introducing another precedence rule./gentle:profilesalso has a nearby binding-aware precedent inextensions/gentle-ai.ts, lines 5231–5254.Suggested regression coverage: session binding B versus global A; session binding B versus repository pin A; and a frozen inherited profile after shared defaults change. Assert the displayed label and agent assignments, the update destination, and that unrelated global routing/profile A remains unchanged. Existing models tests around
tests/gentle-ai.test.ts:3130–3190cover active/pinned targets; the binding-aware profiles-panel test around:4150–4174is a useful starting point.This was code/test inspection only, not an interactive TUI reproduction or a test run. One implementation decision to make explicit is how saving updates the session's routing snapshot as well as its named stored profile, so subsequent agent launches actually consume the edit. If effective-session editing is outside this issue's intended presentation-only scope, this can be tracked separately and linked here.
barbatdev commentedon Oct 30, 2026
This one is resolved by the way the screens landed, closing it out. Since #2588, /gentle:models and /gentle:profiles are one screen: profiles as tabs, the routing table for the shown profile with the orchestrator first, and the three buttons deciding where it applies. The session's launch profile is marked with the filled circle and the table shows its routing instead of the global one, with the per-row launch marks from #2604. There is no second editor left to worry about, and editing a session profile means editing its tab and pressing use again, so the silent copy into the global routing this issue worried about cannot happen. Thanks for the report, it drove the visibility the session layer needed in both screens.