Skip to content

perf(tui): avoid redundant rebuilds in Agent and Read groups #1511

Description

@NarwhalChen

What version of Kimi Code is running?

0.23.3 on main at b89fc1a4

Which open platform/subscription were you using?

Not applicable. This was found during AI-assisted TUI rendering code review, not from a live model session.

Which model were you using?

Not applicable.

What platform is your computer?

Darwin 25.0.0 arm64 arm

What issue are you seeing?

AgentGroupComponent and ReadGroupComponent appear to do redundant rebuild/render-request work when a grouped tool call is attached.

This was found by AI-assisted code review / perf audit rather than by a visible UI regression. I do not have evidence of terminal flicker or user-visible lag, because TUI.requestRender() coalesces actual render scheduling when renderRequested is already set. The issue is that the grouped components still do extra component-level refresh work.

The relevant path is:

  • AgentGroupComponent.attach() calls tc.setSnapshotListener(...), and ToolCallComponent.setSnapshotListener() immediately invokes the callback.
  • That callback enters scheduleRender() / flushRender().
  • attach() then calls flushRender() again directly.
  • flushRender() calls this.invalidate().
  • The overridden invalidate() calls this.flushRender() again.

The same pattern exists in ReadGroupComponent.

What steps can reproduce the bug?

From the repo root, run this instrumentation repro for AgentGroupComponent:

pnpm exec tsx --tsconfig ./apps/kimi-code/tsconfig.dev.json --import ./build/register-raw-text-loader.mjs -e "import { AgentGroupComponent } from './apps/kimi-code/src/tui/components/messages/agent-group.ts'; import { ToolCallComponent } from './apps/kimi-code/src/tui/components/messages/tool-call.ts'; let renders = 0; const ui = { terminal: { rows: 40 }, requestRender() { renders += 1; } }; const group = new AgentGroupComponent(ui); const tc = new ToolCallComponent({ id: 'call_agent_1', name: 'Agent', args: { description: 'inspect project' } }, undefined, ui); tc.onSubagentSpawned({ agentId: 'sub_call_agent_1', agentName: 'reviewer', runInBackground: false }); renders = 0; group.attach('call_agent_1', tc); console.log(JSON.stringify({ rendersAfterAttach: renders })); group.dispose(); tc.dispose();"

Actual output:

{"rendersAfterAttach":4}

The same repro shape for ReadGroupComponent also reports 4 render requests after a single attach().

What is the expected behavior?

A single group attach/status refresh should rebuild the grouped component once and issue at most one render request from the component-level refresh path.

Actual terminal rendering may still be coalesced by TUI.requestRender(), but the grouped component should avoid the redundant flushRender -> invalidate -> flushRender path and the immediate listener callback plus explicit attach flush duplication.

Additional information

This is a low-severity performance/cleanup issue, not a confirmed user-visible rendering bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions