Skip to content

[codex] fix(gateway): bound sessions list responses#77123

Merged
steipete merged 1 commit intomainfrom
codex/bound-sessions-list
May 4, 2026
Merged

[codex] fix(gateway): bound sessions list responses#77123
steipete merged 1 commit intomainfrom
codex/bound-sessions-list

Conversation

@steipete
Copy link
Copy Markdown
Contributor

@steipete steipete commented May 4, 2026

Summary

This bounds the default Gateway sessions.list response so callers that omit limit no longer force the Gateway to build every matching session row in one request.

Changes:

  • apply a default 100-row cap to listSessionsFromStore / listSessionsFromStoreAsync
  • return totalCount, limitApplied, and hasMore metadata so clients can show when more rows exist
  • keep internal session resolution unbounded where full-store semantics are required
  • document the bounded RPC behavior and add regression coverage for default and explicit limits

Fixes #77062.

Why

#77062 reports Slack-heavy, long-lived installs where sessions.list / dashboard loading could take tens of seconds and saturate the shared Gateway process. Recent main already made row construction lighter, but the bare RPC path still treated an omitted limit as unbounded.

That left any caller using plain sessions.list able to enumerate and enrich every selected row, which is the failure class behind the Slack Socket Mode degradation: expensive dashboard/session work can monopolize the same event loop that channel transports depend on.

Behavior Change

Callers that need a larger window can still pass an explicit positive limit. Default calls now receive the newest 100 matching rows plus metadata indicating whether more rows exist:

  • count: number of rows returned
  • totalCount: number of matching rows before the cap
  • limitApplied: effective row limit
  • hasMore: whether the response was truncated

This intentionally does not add pagination yet; it establishes the safety bound and response shape needed for follow-up UI/API pagination work.

Verification

  • pnpm test src/gateway/session-utils.test.ts src/gateway/server.sessions.list-changed.test.ts
  • pnpm exec oxfmt --check --threads=1 src/shared/session-types.ts src/gateway/session-utils.ts src/gateway/session-utils.test.ts src/gateway/protocol/schema/sessions.ts src/tui/tui-backend.ts docs/cli/sessions.md CHANGELOG.md
  • pnpm exec oxlint --deny-warnings src/shared/session-types.ts src/gateway/session-utils.ts src/gateway/session-utils.test.ts src/gateway/protocol/schema/sessions.ts src/tui/tui-backend.ts
  • git diff --check
  • Testbox pnpm check:changed on tbx_01kqrq3nn2v7qb4bwrsmw37g5h, run https://github.com/openclaw/openclaw/actions/runs/25302557993
  • Clean rebase onto current origin/main; rebase sanity: git status, git diff --check, and unchanged diff stat

Current PR head: 9213fbd3105372dc1e3275b1e760606e1cd1c918.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation app: web-ui App: web-ui gateway Gateway runtime size: S maintainer Maintainer-authored PR labels May 4, 2026
@steipete steipete force-pushed the codex/bound-sessions-list branch from a2b4710 to a6081ac Compare May 4, 2026 05:27
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 4, 2026

Codex review: found issues before merge.

Summary
The PR adds a default 100-row cap plus truncation metadata to session list helpers/RPC docs/types, with tests and a changelog entry for the Slack-heavy sessions.list regression.

Reproducibility: yes. for the review finding: source inspection shows sessions.resolve calls listSessionsFromStore without a limit when spawnedBy is present, and the PR makes that helper return only 100 rows by default. I did not execute tests because this was a read-only review.

Next step before merge
The PR is draft, maintainer-labeled, and changes public Gateway response semantics while carrying a source-reproducible correctness blocker that should be revised under maintainer review.

Security
Cleared: The diff touches Gateway session-list logic, docs, types, and tests; I found no new secret handling, dependency, CI, package, or code-download surface.

Review findings

  • [P2] Preserve spawnedBy resolution outside the default window — src/gateway/session-utils.ts:2005
Review details

Best possible solution:

Keep the bounded RPC behavior, but scope the default cap to actual list surfaces while preserving exact session resolution and adding a regression test for an older spawnedBy child outside the default window.

Do we have a high-confidence way to reproduce the issue?

Yes for the review finding: source inspection shows sessions.resolve calls listSessionsFromStore without a limit when spawnedBy is present, and the PR makes that helper return only 100 rows by default. I did not execute tests because this was a read-only review.

Is this the best way to solve the issue?

No: bounding bare Gateway sessions.list is a reasonable fix direction, but applying the cap inside the shared helper changes internal exact-key resolution. A safer approach is to pass the default only from list RPC/UI surfaces or make the internal visibility check use unbounded filtered entries.

Full review comments:

  • [P2] Preserve spawnedBy resolution outside the default window — src/gateway/session-utils.ts:2005
    This default cap also applies to sessions.resolve because isResolvedSessionKeyVisible calls listSessionsFromStore without a limit and then checks whether the exact key is present. With more than 100 visible children for a spawnedBy parent, resolving an older but valid child key now returns No session found; keep the RPC cap out of this internal visibility path or pass an explicit unbounded mode there.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.86

Acceptance criteria:

  • pnpm test src/gateway/session-utils.test.ts src/gateway/sessions-resolve.test.ts src/gateway/server.sessions.list-changed.test.ts

What I checked:

Likely related people:

  • steipete: Recent current-main commits touched session-list performance and exact session lookup paths, including fix(gateway): cache session list thinking enrichment, perf(gateway): avoid extra session-list store work, and fix: speed up exact session lookups. (role: recent maintainer; confidence: high; commits: 18bd7b60e4fe, 43de6ae72508, 0ea28ddb165d; files: src/gateway/session-utils.ts, src/gateway/server-methods/sessions.ts, src/gateway/sessions-resolve.ts)
  • vincentkoc: Current blame and GitHub path history show substantial recent work on session-list hot paths, including top-N selection, bounded transcript usage, preview hydration caps, and lightweight row behavior. (role: recent adjacent owner; confidence: high; commits: 973e240bb347, 694598822f19, ecf6cbf75d3d; files: src/gateway/session-utils.ts, src/gateway/server-methods/sessions.ts, src/gateway/server.sessions.list-changed.test.ts)
  • BunsDev: Recent Control UI session latency work reduced redundant session reloads and is adjacent to the dashboard/session-list performance surface named by the linked regression. (role: adjacent UI maintainer; confidence: medium; commits: 05c9492bff0f, 4532e5d85803; files: ui/src/ui/controllers/sessions.ts, ui/src/ui/app-chat.ts, src/gateway/server.sessions.list-changed.test.ts)

Remaining risk / open question:

  • The chosen default window size and truncation semantics are a public Gateway API behavior change and should get maintainer sign-off.
  • I did not run tests or a large Slack-heavy performance replay because this review was required to keep the checkout read-only.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 8f75a4ebdf2a.

@steipete steipete force-pushed the codex/bound-sessions-list branch from a6081ac to 7389a23 Compare May 4, 2026 05:39
@steipete steipete marked this pull request as ready for review May 4, 2026 05:39
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7389a23c1d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

store,
opts,
now,
rowContext: hasSpawnedByFilter ? getRowContext() : undefined,
defaultLimit: SESSIONS_LIST_DEFAULT_LIMIT,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Scope the default sessions limit to RPC entrypoints only

Applying SESSIONS_LIST_DEFAULT_LIMIT inside listSessionsFromStore changes behavior for all internal callers, not just sessions.list. sessions.resolve relies on this helper in isResolvedSessionKeyVisible (with spawnedBy and no explicit limit) to confirm whether an exact key is visible; once there are more than 100 matching sessions, older valid keys are truncated out and incorrectly return No session found. This turns a performance guard into a correctness regression for large long-lived subagent trees.

Useful? React with 👍 / 👎.

@steipete steipete force-pushed the codex/bound-sessions-list branch from 7389a23 to 9213fbd Compare May 4, 2026 05:46
@steipete steipete merged commit a224810 into main May 4, 2026
109 of 114 checks passed
@steipete steipete deleted the codex/bound-sessions-list branch May 4, 2026 05:51
@steipete
Copy link
Copy Markdown
Contributor Author

steipete commented May 4, 2026

Landed via squash merge.

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

Labels

app: web-ui App: web-ui docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression since 2026.4.29: Slack-heavy session lists can saturate gateway via sessions.list

1 participant