Skip to content

feat(FR-454): paginate and filter the session detail kernel list - #9521

Draft
yomybaby wants to merge 2 commits into
mainfrom
feat/FR-454-session-kernel-list-pagination
Draft

feat(FR-454): paginate and filter the session detail kernel list#9521
yomybaby wants to merge 2 commits into
mainfrom
feat/FR-454-session-kernel-list-pagination

Conversation

@yomybaby

@yomybaby yomybaby commented Sep 7, 2026

Copy link
Copy Markdown
Member

Resolves #3084 (FR-454)

The kernel table in the session detail panel rendered every kernel of a cluster session at once, ordered client-side, with its filter UI commented out — two TODOs said to wait for a query that supports filtering and pagination. Manager 26.2.0 added sessionKernelsV2(scope: SessionScope!, filter: KernelV2Filter, orderBy: [KernelV2OrderBy!], limit, offset), so that query now backs the tab.

What changed

  • ConnectedKernelListV2 (new) — runs its own useLazyLoadQuery against sessionKernelsV2 with:
    • offset-mode pagination (limit + offset). A Strawberry V2 connection rejects a mixed pagination mode at runtime, so first is deliberately not read off useBAIPaginationOptionState (.claude/rules/graphql-pagination.md).
    • server-side ordering from the table header — cluster hostname, cluster index, status — defaulting to CLUSTER_IDX ASC so the main kernel stays first, as the old client-side orderBy(['cluster_role', 'cluster_idx']) did.
    • a BAIGraphQLPropertyFilter over the properties KernelV2Filter actually exposes: kernel id and status. It has no agentId field, so the agent filter the old TODO asked for is not part of this PR.
  • ConnectedKernelList (legacy) — kept unchanged as the path for managers below 26.2.0; only its two now-obsolete TODOs and the commented-out filter block are removed.
  • SessionDetailContent — picks between the two behind the new session-kernels-v2 client capability (added to the existing 26.2.0 block in backend.ai-client), and forwards the panel's fetchKey so a session refresh refetches the kernel page.

Design decisions

  • KernelV2 rows are addressed by their Strawberry global id, so the kernel-id column and the container-log button decode it with safeDecodeUuid rather than a row_id field (there is none).
  • The container-log modal keeps its own complete kernel_nodes list, so its kernel picker still offers every kernel regardless of which table page is shown.
  • KernelV2 has no status_info counterpart, so the V2 status cell shows the status badge alone instead of the legacy BAIDoubleTag. This is the one behavioural difference between the two paths.
  • No new i18n keys — the filter reuses the existing kernel.KernelId / kernel.Status column labels.

Tests

  • New: react/src/components/ComputeSessionNodeItems/ConnectedKernelListV2.test.tsx (3 cases) — asserts the query sends limit/offset and no first/after/last/before, that the default orderBy is CLUSTER_IDX ASC, and that a row renders from the nested KernelV2 shape.
    cd react && pnpm exec vitest run src/components/ComputeSessionNodeItems/ConnectedKernelListV2.test.tsxTest Files 1 passed (1) / Tests 3 passed (3)
  • pnpm run relay — generated artifact committed.
  • No e2e run (needs a live cluster).

Verification

bash scripts/verify.sh

=== ALL PASS ===

Review notes

  • Open a cluster session (more than 10 kernels) → Kernels tab: the table now pages, and the page control reports the server count rather than the fetched array length.
  • Type a filter token (Status = RUNNING, or a kernel id) and click a sortable header (Hostname / Status) — both should round-trip to the server and reset to page 1.
  • Against a manager older than 26.2.0 the tab must fall back to the original unpaginated list (unset the session-kernels-v2 capability to simulate).

Checklist: (if applicable)

  • Documentation
  • Minium required manager version — 26.2.0 for the paginated path; older managers keep the legacy list
  • Specific setting for review (eg., KB link, endpoint or how to setup)
  • Minimum requirements to check during review — a cluster session with more kernels than one page
  • Test case(s) to demonstrate the difference of before/after — ConnectedKernelListV2.test.tsx

https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ

The kernel table in the session detail panel rendered every kernel of a
cluster session at once, sorted client-side, with the filter UI commented
out — the two TODOs said to wait for a query that supports filtering and
pagination. Manager 26.2.0 added `sessionKernelsV2(scope: SessionScope!,
filter: KernelV2Filter, orderBy: [KernelV2OrderBy!], limit, offset)`, so
that query now backs the tab.

`ConnectedKernelListV2` runs its own `useLazyLoadQuery` against it with
offset-mode pagination (`limit` + `offset` — a Strawberry V2 connection
rejects a mixed mode at runtime), server-side ordering driven by the
table header (cluster hostname / cluster index / status) and a
`BAIGraphQLPropertyFilter` over the properties `KernelV2Filter` actually
exposes: kernel id and status. `KernelV2` rows are addressed by their
Strawberry global id, so the kernel id column and the container-log
button decode it with `safeDecodeUuid`.

The legacy `kernel_nodes` path is kept for managers below 26.2.0 behind
the new `session-kernels-v2` client capability, and its two obsolete
TODOs are dropped. The container-log modal keeps its own complete kernel
list, so its kernel picker is unaffected by the table's paging.

`KernelV2` has no `status_info` counterpart, so the V2 status cell shows
the status badge alone rather than the legacy double tag.

Claude-Session: https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for react-coverage (./react)

Status Category Percentage Covered / Total
🔵 Lines 15.82% 5774 / 36488
🔵 Statements 13.28% 7046 / 53026
🔵 Functions 13.7% 889 / 6489
🔵 Branches 9.58% 4858 / 50703
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
react/src/components/SessionDetailContent.tsx 62.29% 36.26% 16.66% 64.21% 98-99, 127, 150, 154-160, 170, 172, 173, 183, 270, 279, 296, 300, 303, 322-329, 340-343, 437-748, 115-688
react/src/components/ComputeSessionNodeItems/ConnectedKernelList.tsx 0% 0% 0% 0% 38-175
react/src/components/ComputeSessionNodeItems/ConnectedKernelListV2.tsx 70.62% 45.18% 28.57% 88.29% 76, 84, 127, 129, 131, 134, 138, 143, 144, 159-164, 165, 167, 168, 176, 178, 179, 181, 183, 190, 192, 193, 195, 196, 204-206, 210, 212, 215, 221, 222, 223, 224, 226, 236, 239-241, 247-248, 249, 250, 258-259, 261, 262
Generated in workflow #757 for commit 62f7aae by the Vitest Coverage Report Action

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Three moderate runtime and state-management issues remain unresolved.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds server-side pagination, filtering, and ordering to session kernel details while retaining legacy-manager compatibility.

Changes:

  • Adds the sessionKernelsV2 kernel table and tests.
  • Selects the V2 path through a new client capability.
  • Removes obsolete legacy-table TODOs.

Unresolved issues:

  • Moderate: Combined filters fail on Managers 26.2–26.6 because sub-filters require 26.7.
  • Moderate: Clearing sorting removes the deterministic CLUSTER_IDX ASC fallback.
  • Moderate: Kernel-list state persists when navigating between sessions, potentially showing stale or empty results.
File summaries
File Description
react/src/components/SessionDetailContent.tsx Selects the legacy or V2 kernel list.
react/src/components/ComputeSessionNodeItems/ConnectedKernelListV2.tsx Implements the paginated, filtered V2 table.
react/src/components/ComputeSessionNodeItems/ConnectedKernelListV2.test.tsx Tests query variables and row rendering.
react/src/components/ComputeSessionNodeItems/ConnectedKernelList.tsx Removes obsolete commented code.
react/src/__generated__/ConnectedKernelListV2Query.graphql.ts Adds the generated Relay query artifact.
packages/backend.ai-client/src/client.ts Enables V2 kernels for Manager 26.2+.
Review details

Files not reviewed (1)

  • react/src/generated/ConnectedKernelListV2Query.graphql.ts: Generated file
  • Files reviewed: 5/6 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread react/src/components/ComputeSessionNodeItems/ConnectedKernelListV2.tsx Outdated
Comment thread react/src/components/SessionDetailContent.tsx
- Gate combined filter conditions on the `sub-filter` capability. Managers
  26.2-26.6 serve `sessionKernelsV2` but reject the AND/OR/NOT sub-filters
  `BAIGraphQLPropertyFilter` emits once two tokens are entered, so the filter
  runs in `singleCondition` mode there (same pattern as
  AdminRuntimeVariantPreset / ResourcePolicyPage).
- Restore `CLUSTER_IDX ASC` when sorting is cleared. `BAITable.onChangeOrder`
  emits `undefined` for the unsorted state; storing `null` sent no `orderBy`
  at all, leaving offset-paginated pages without a deterministic order.
- Remount `ConnectedKernelListV2` per session. The dependent/dependency links
  swap only the `sessionDetail` search param, so `SessionDetailContent` stays
  mounted with a new `row_id` and the list carried its filter, page and sort
  over to the next session.

Test updated with a `useSuspendedBackendaiClient` mock; 3/3 pass.
verify.sh: === ALL PASS ===

Claude-Session: https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The unsupported combined-filter path and unstable pagination ordering must be addressed.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Files not reviewed (1)

  • react/src/generated/ConnectedKernelListV2Query.graphql.ts: Generated file

Suppressed comments (1)

react/src/components/ComputeSessionNodeItems/ConnectedKernelListV2.tsx:201

  • singleCondition only keeps one token per property; it does not limit the filter to one overall token. With both Kernel ID and Status selected, powerSearchFiltersToGraphQLFilter() still reaches convertConditionsToGraphQLFilter() with two conditions and emits { AND: [...] } (BAIGraphQLPropertyFilter.tsx:655-683, 369-375), so managers 26.2–26.6 still reject this path. Please either make the filter emit one flat object for distinct properties when sub-filters are unavailable, or prevent a second property token entirely, and cover the ID+Status case with supports('sub-filter') === false.
        singleCondition={!supportsSubFilter}
  • Files reviewed: 5/6 changed files
  • Comments generated: 1
  • Review effort level: Balanced

{
scope: { sessionId },
filter: deferredFilter,
orderBy: convertToOrderBy<KernelV2OrderBy>(deferredOrder),
@yomybaby

yomybaby commented Sep 7, 2026

Copy link
Copy Markdown
Member Author

Ready-gate status: Copilot pass 2 (#pullrequestreview-5134172287) left two findings that I am not deciding on my own. The PR stays a draft.

  1. singleCondition does not fully cover the 26.2-26.6 case (Copilot's suppressed comment on ConnectedKernelListV2.tsx:201). It is right, and it corrects my "Fixed" reply on r3951527768: powerSearchFiltersToGraphQLFilter dedupes by filter.field (BAIGraphQLPropertyFilter.tsx:657-665), so one Kernel ID token plus one Status token is still two conditions and convertConditionsToGraphQLFilter emits { AND: [...] } (:369-375). Making it emit a flat multi-field object, or capping the token count outright, is a change to the shared BUI filter — and AdminRuntimeVariantPreset.tsx:166 and ResourcePolicyPage.tsx:131 use the identical singleCondition={!supportsSubFilter} pattern with multiple properties, so this looks repo-wide rather than specific to this PR. Needs a call on where the fix belongs.

  2. Tie-breaker on CLUSTER_IDX (r3951580762). Whether cluster_idx can repeat across cluster roles inside one session is a backend-data question I cannot settle from this diff, and appending a second orderBy entry changes the row order users see on every sort. Needs someone who knows the manager's kernel ordering.

Fixed and resolved in 62f7aae: the CLUSTER_IDX ASC fallback when sorting is cleared, and the per-session key on ConnectedKernelListV2. bash scripts/verify.sh -> === ALL PASS ===.

https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add filter and pagination option for kernel list in session detail panel

2 participants