Skip to content

fix(terminal): keep slow clients connected under heavy output#107348

Merged
steipete merged 2 commits into
mainfrom
codex/terminal-output-backpressure
Jul 14, 2026
Merged

fix(terminal): keep slow clients connected under heavy output#107348
steipete merged 2 commits into
mainfrom
codex/terminal-output-backpressure

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Related: #107214

What Problem This Solves

Fixes an issue where operators using the embedded terminal could be disconnected as slow consumers when a shell produced sustained output, while every small PTY chunk also incurred its own WebSocket frame.

Why This Change Was Made

Terminal output now coalesces for up to 4 ms or 64 KiB, with immediate delivery for small keystroke echoes. Local PTYs pause when the owning socket crosses a high buffered-byte watermark and resume below a lower watermark, with periodic state reassertion; node-relay terminals retain their existing node-host progress backpressure.

User Impact

Embedded terminals remain responsive during interactive input and tolerate sustained output without eagerly closing the operator connection. Release note: fixed embedded-terminal disconnects under heavy output by batching frames and applying PTY backpressure.

Evidence

  • node scripts/run-vitest.mjs src/gateway/terminal: 171 tests passed on Blacksmith Testbox tbx_01kxfysrtfdbvtmfn6msc7dq0e.
  • node scripts/run-vitest.mjs src/gateway/gateway-misc.test.ts: 43 tests passed on the same Testbox.
  • pnpm build: passed on the same Testbox against the final changed content.
  • pnpm check:changed: conflict, LOC-ratchet, attribution, dependency, formatting, and export guards passed; the Plugin SDK baseline hash mismatch reproduces unchanged from origin/main in an isolated archive.
  • Mandatory autoreview: clean, no accepted or actionable findings.

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: L maintainer Maintainer-authored PR labels Jul 14, 2026
@steipete
steipete requested a review from a team as a code owner July 14, 2026 10:00
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord channel: telegram Channel integration: telegram app: web-ui App: web-ui cli CLI command changes scripts Repository scripts agents Agent runtime and tooling channel: twitch Channel integration: twitch size: XL and removed size: L labels Jul 14, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 867e11a054

ℹ️ 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".

}
}
return cmd.parent?.opts?.() as BrowserParentOpts;
return cmd.optsWithGlobals<BrowserParentOpts>();

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.

P2 Badge Keep child --url out of gateway options

Commander v15's optsWithGlobals() returns merged local and global option values (its source notes that globals overwrite locals), so when the user does not pass a browser-level gateway --url, any child command that defines its own --url now appears in parent.url. For example, openclaw browser cookies set ... --url https://example.com and openclaw browser wait --url '**/ready' pass that page/cookie URL through callBrowserRequest as the Gateway WebSocket URL instead of leaving it undefined for the configured gateway, causing those commands to connect to the wrong endpoint; this helper should keep returning only the browser command's Gateway options or otherwise filter child-local collisions.

Useful? React with 👍 / 👎.

@openclaw-barnacle openclaw-barnacle Bot added channel: msteams Channel integration: msteams app: ios App: ios app: macos App: macos labels Jul 14, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fac6f53670

ℹ️ 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".

httpServer.once("listening", onListening);
httpServer.once("error", onError);
const httpServer = await new Promise<Server>((resolve, reject) => {
const server = expressApp.listen(port, (err) => (err ? reject(err) : resolve(server)));

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.

P2 Badge Restore the listen-time error listener

When the Teams webhook port is already in use or bind fails, http.Server.listen reports that through the server's error event, not by passing an argument to the listen callback (the callback is invoked with zero args on success). Because this Promise only waits for the callback and the httpServer.on("error") handler is attached after the await, startup bind errors are emitted with no listener, so the monitor can crash or hang instead of rejecting/logging as the previous once("error") path did.

Useful? React with 👍 / 👎.

@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations channel: feishu Channel integration: feishu plugin: google-meet fleet labels Jul 14, 2026
@github-actions github-actions Bot added the dependencies-changed PR changes dependency-related files label Jul 14, 2026
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Dependency graph guard cleared

This PR no longer has blocked dependency graph changes. A future dependency graph change requires a fresh /allow-dependencies-change comment after the guard blocks that new head SHA.

  • Current SHA: d20337ace4f14512a8e914872f20e091943f223d

@openclaw-barnacle openclaw-barnacle Bot added dependencies-changed PR changes dependency-related files size: L and removed channel: msteams Channel integration: msteams channel: signal Channel integration: signal channel: telegram Channel integration: telegram channel: zalo Channel integration: zalo app: ios App: ios app: macos App: macos app: web-ui App: web-ui extensions: memory-core Extension: memory-core cli CLI command changes scripts Repository scripts commands Command implementations agents Agent runtime and tooling channel: feishu Channel integration: feishu channel: twitch Channel integration: twitch extensions: anthropic extensions: qa-lab extensions: codex plugin: google-meet extensions: diffs fleet channel: reef Channel integration: reef size: XL labels Jul 14, 2026
@github-actions github-actions Bot removed the dependencies-changed PR changes dependency-related files label Jul 14, 2026
@steipete
steipete merged commit 9c03b23 into main Jul 14, 2026
131 of 140 checks passed
@steipete
steipete deleted the codex/terminal-output-backpressure branch July 14, 2026 11:28
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 15, 2026
…aw#107348)

* fix(terminal): coalesce output and throttle slow clients

* fix(terminal): satisfy lint and deadcode gates
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime maintainer Maintainer-authored PR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant