fix(sessions): return archived pins from the sidebar back-fill
The include_pinned query reused the listing WHERE, including archived = 0. The sidebar lists with include_archived=False, so a pinned row stamped archived never back-filled. Rebuild that query without the archived constraint and keep the other filters. The stale sweep already skips pins.
This commit is contained in:
@@ -1267,7 +1267,9 @@ class SessionSessionsMixin:
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""List sessions with preview and ``last_active`` in one query. ``order_by_last_active`` sorts
|
||||
by the chain TIP via a recursive CTE (the only path honouring ``id_query`` / ``search_query``);
|
||||
``include_pinned`` back-fills pins the page missed, still obeying the other filters."""
|
||||
``include_pinned`` back-fills pins the page missed, still obeying the other
|
||||
filters except archived: a pin is an explicit keep, so a pinned row stamped
|
||||
archived must still return."""
|
||||
self.flush_token_counts() # rows carry token/cost totals
|
||||
where_clauses, params = _session_filter_where(
|
||||
exclude_children=not include_children, source=source, sources=sources, session_key=session_key,
|
||||
@@ -1281,7 +1283,6 @@ class SessionSessionsMixin:
|
||||
if not include_hidden and not archived_only:
|
||||
where_clauses.append("s.hidden = 0")
|
||||
where_sql = _where_sql(where_clauses)
|
||||
base_where_params = list(params) # pinned back-fill reuses the WHERE before LIMIT/OFFSET
|
||||
# Shared projection head of the three list queries (whitespace is part of the SQL text).
|
||||
select_head = (
|
||||
f"SELECT {self._compact_session_cols() if compact_rows else 's.*'}"
|
||||
@@ -1342,17 +1343,27 @@ class SessionSessionsMixin:
|
||||
params.extend([limit, offset])
|
||||
sessions = [self._list_row(row) for row in self._read_all(query, params)]
|
||||
# Pinned back-fill runs BEFORE compression projection so a back-filled root
|
||||
# projects to its tip like any other row.
|
||||
# projects to its tip like any other row. Do not inherit the archived
|
||||
# constraint: the sidebar lists with include_archived=False, and a pin
|
||||
# must stay reachable even when that row is also archived.
|
||||
if include_pinned:
|
||||
seen_ids = {s["id"] for s in sessions}
|
||||
pinned_where = f"{where_sql} AND s.pinned = 1" if where_sql else "WHERE s.pinned = 1"
|
||||
pinned_clauses, pinned_params = _session_filter_where(
|
||||
exclude_children=not include_children, source=source, sources=sources,
|
||||
session_key=session_key, exclude_sources=exclude_sources, cwd_prefix=cwd_prefix,
|
||||
min_message_count=min_message_count, archived_only=False, include_archived=True,
|
||||
)
|
||||
if not include_hidden and not archived_only:
|
||||
pinned_clauses.append("s.hidden = 0")
|
||||
pinned_clauses.append("s.pinned = 1")
|
||||
pinned_where = _where_sql(pinned_clauses)
|
||||
pinned_query = f"""
|
||||
{select_head}{_sql_session_last_active("s")} AS last_active
|
||||
{from_sessions}
|
||||
{pinned_where}
|
||||
ORDER BY s.started_at DESC
|
||||
"""
|
||||
for row in self._read_all(pinned_query, base_where_params):
|
||||
for row in self._read_all(pinned_query, pinned_params):
|
||||
s = self._list_row(row)
|
||||
if s["id"] not in seen_ids:
|
||||
seen_ids.add(s["id"])
|
||||
|
||||
Reference in New Issue
Block a user