Skip to content

fix(app): reserve chat request slots during MCP discovery - #62564

Open
mlimarenko wants to merge 1 commit into
anomalyco:devfrom
mlimarenko:queue-mcp-slots
Open

mlimarenko wants to merge 1 commit into
anomalyco:devfrom
mlimarenko:queue-mcp-slots

Conversation

@mlimarenko

@mlimarenko mlimarenko commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Issue for this PR

Closes #53049

Type of change

  • Bug fix

What does this PR do?

Classifies /api/command, /api/mcp and their nested routes through the existing slow-request share in request-queue-machine.ts. The queue keeps four slots and at most two slow requests, so a session read can start while MCP or command catalogs are still waiting on server startup or discovery. Current priorities, concurrency limits, deadlines, cancellation and retry behaviour are unchanged.

This is the current-dev port of #53050, which the automated age/reaction cleanup closed on 2026-11-04. That closure was not a review result. Base: 21bf6b493b76efcf3769ade999f05163760d61af.

How did you verify your code works?

  • bun test --config /dev/null ./src/runtime/server/request-queue-machine.test.ts ./src/runtime/server/request-queue.test.ts from packages/app: 22 passed, 0 failed, 82 assertions. The transport case holds two catalogs and asserts a session read is dispatched before the third catalog.
  • bun run typecheck in packages/app: no type errors in 2,332 files.
  • bun run lint:changed: 0 problems in the 3 changed files.
  • Native pre-push lint && typecheck gate passed.
  • The exact-head upstream workflows on the previous head were action_required for fork runs, not failed tests. Full CI on this head is not claimed green while GitHub requires maintainer approval.

Not claimed: a full Desktop reproduction of the intermittent timeout. This is a queue-classification change with a loopback/transport regression, not a root-cause proof of every slow request.

Screenshots / recordings

No visual control changed.

Visual

<svg xmlns="http://www.w3.org/2000/svg" width="240" height="72" viewBox="0 0 240 72">
  <style>@media(prefers-reduced-motion:no-preference){.chat{animation:pass 2s infinite}}@keyframes pass{0%,100%{opacity:.5}50%{opacity:1}}</style>
  <g fill="none" stroke="currentColor"><rect x="8" y="12" width="48" height="48" rx="6"/><rect x="66" y="12" width="48" height="48" rx="6"/><rect x="124" y="12" width="108" height="48" rx="6" class="chat"/></g>
  <g fill="currentColor" font-family="sans-serif" font-size="10" text-anchor="middle"><text x="32" y="40">MCP</text><text x="90" y="40">MCP</text><text x="178" y="40">Chat can continue</text></g>
</svg>

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Added by the opencode bot (AI-generated).

Related: #59526

@opencodejr opencodejr Bot 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.

Looks good. I reproduced #53049 with the issue's queue script. On the base, four held /api/command, /api/mcp or /api/mcp/resource requests took all 4 slots and the session message read was never sent. With this change, catalogs hold 2 slots and the session read is sent and finishes for all three paths. The request-queue tests pass (22/22) and tsc -b in packages/app is clean.

The prefix match only covers the three GET catalog endpoints. MCP add, remove, connect and disconnect live under /api/experimental/mcp/..., so they aren't capped.

Public API is unchanged: this only affects the app's client-side request queue.

Related: #59526

This branch has not been deployed

No deployments
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.

V2: MCP discovery can starve chat reads in the client request queue

2 participants