Skip to content

feat(pi-tui): add opt-in render profiler#1462

Open
liruifengv wants to merge 1 commit into
mainfrom
experiment/windows-render-stutter
Open

feat(pi-tui): add opt-in render profiler#1462
liruifengv wants to merge 1 commit into
mainfrom
experiment/windows-render-stutter

Conversation

@liruifengv

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue. This PR adds the diagnostic instrumentation described below; it is a precursor to a fix rather than the fix itself.

Problem

On Windows, the kimi-code TUI can make the desktop feel laggy while streaming output — for instance, opening File Explorer or switching windows stutters. Today we have no visibility into per-frame render cost or stdout write behavior, so the root cause is being guessed. Windows ConPTY / Windows Terminal stdout writes are substantially more expensive than Unix pseudoterminals, and the renderer does not yet react to that cost.

What changed

Adds an opt-in render profiler to pi-tui, gated behind the PI_TUI_RENDER_PROFILE environment variable. It is disabled by default and near-zero overhead when off. When enabled it writes newline-delimited JSON to ~/.pi/agent/pi-render-profile.jsonl (or a custom path via the env value), recording for every frame:

  • each stdout write: duration, byte size, and whether the stream signalled backpressure (write returning false);
  • each render frame: build time, rendered line count, viewport height, whether it was a full redraw, and the event-loop lag since the previous frame.

The profiler buffers records and flushes asynchronously during the render loop, with a synchronous flush on shutdown, so the instrumentation does not add blocking I/O to the hot path. Unit tests and a changeset are included.

This is instrumentation only and changes no default behavior. The captured data is meant to drive the follow-up fix (likely backpressure-based frame dropping and/or render throttling for unfocused windows) once measured on Windows.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

Record per-frame render cost and stdout write timing behind the PI_TUI_RENDER_PROFILE env flag to help diagnose terminal render stutter, especially on Windows. Disabled by default.
@changeset-bot

changeset-bot Bot commented Jul 7, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 26811f5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/pi-tui Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 7, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@26811f5
npx https://pkg.pr.new/@moonshot-ai/kimi-code@26811f5

commit: 26811f5

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

Copy link
Copy Markdown

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: 26811f5068

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

if (this.pending.length === 0) return;
const chunk = this.pending.join("");
this.pending = [];
fs.promises.appendFile(this.filePath, chunk).catch(() => {});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Flush in-flight profiler writes before exit

When a profiling run reaches 100 records, this drops the chunk from pending and starts a fire-and-forget appendFile; close() only sync-flushes the current pending array, while the normal Kimi shutdown path calls TUI.stop() and then process.exit() from apps/kimi-code/src/cli/run-shell.ts. In sessions long enough to cross the threshold, records already handed to this async write can therefore be lost or written out of order before the process exits, which makes the opt-in profile incomplete exactly for the long render-stutter captures it is meant to diagnose.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant