fix(sessions): run the assigned recovery pass in the all-profiles view
`?all_profiles=1` passed `project_assigned_limit=False`, on the premise that its `visible_session_limit=None` first pass already returns every conversation. It does not: `_load_cli_sessions_uncached` maps `visible_session_limit is None` to CLI_VISIBLE_SESSION_LIMIT for the interactive pass, so that view truncates by recency exactly like the single-profile one. Only cron/webhook/kanban limits reach the reader as `limit=` directly, where None does mean unbounded. Net effect of the old value: in the "All profiles" sidebar a project-assigned CLI session older than the newest 20 interactive conversations was missing from /api/sessions while its project chip still claimed it — the #6659 bug itself, in the one view that shows every profile at once. Recovery pass 2 (the unassigned refill) still ran there, so the two passes disagreed as well. Pass PROJECT_ASSIGNED_CLI_LIMIT instead of None so the per-project bound and the PROJECT_ASSIGNED_CLI_SCAN_CEILING guard apply per profile, rather than issuing an unbounded assigned scan for every profile on the box.
This commit is contained in:
1 parent
7c984f7ab6
commit
bc1ee9d400
2 files changed
+52
-4
No files matched your search
@@ -738,3 +738,46 @@ def test_kanban_second_pass_still_projects_rows(fake_hermes_home, tmp_path):
|
||||
assert "kanban-old" in by_id
|
||||
# Upstream semantics: kanban rows get no chip from this helper.
|
||||
assert by_id["kanban-old"]["project_id"] is None
|
||||
|
||||
|
||||
# ── The all-profiles sidebar view runs the same recovery passes ───────────────
|
||||
|
||||
|
||||
def test_all_profiles_view_recovers_project_assigned_sessions(
|
||||
fake_hermes_home, tmp_path, monkeypatch
|
||||
):
|
||||
"""``?all_profiles=1`` truncates by recency too, so it needs both passes.
|
||||
|
||||
That path passes ``visible_session_limit=None``, which reads like
|
||||
"unbounded" but is mapped to ``CLI_VISIBLE_SESSION_LIMIT`` for the
|
||||
interactive pass — only the cron/webhook/kanban limits reach the reader as
|
||||
``limit=`` directly, where None really does mean unbounded. Skipping the
|
||||
assigned recovery pass here therefore lost exactly the sessions this
|
||||
regression is about, in the one view that shows every profile at once.
|
||||
"""
|
||||
monkeypatch.setattr(models, "CLI_VISIBLE_SESSION_LIMIT", 5)
|
||||
_register_projects(tmp_path, "project-123")
|
||||
|
||||
db_path = fake_hermes_home / "state.db"
|
||||
rows = [
|
||||
_session(f"recent-{index:02d}", BASE_TS + 100 + index)
|
||||
for index in range(25)
|
||||
]
|
||||
rows.append(_session("older-assigned", BASE_TS, project_id="project-123"))
|
||||
_write_state_db(db_path, rows)
|
||||
|
||||
# Enumerating real profiles shells out to the agent CLI; pin the one context.
|
||||
monkeypatch.setattr(
|
||||
models,
|
||||
"_all_profiles_cli_contexts",
|
||||
lambda: ([(fake_hermes_home, db_path, "default")], (("home", "default", 1),)),
|
||||
)
|
||||
|
||||
sessions = models.get_cli_sessions(all_profiles=True)
|
||||
by_id = {session["session_id"]: session for session in sessions}
|
||||
|
||||
assert "older-assigned" in by_id
|
||||
assert by_id["older-assigned"]["project_id"] == "project-123"
|
||||
assert [s["session_id"] for s in sessions].count("older-assigned") == 1
|
||||
# The unassigned window is still bounded — the recovery pass is additive.
|
||||
assert sum(1 for s in sessions if s["project_id"] is None) == 5
|
||||
Reference in new issue
Block a user