MoonshotAI / MoonshotAI/kimi-code

Client-side defects: post-compaction render stall, queued prompt silently dropped, completed turn never rendered (wire-level forensics)

Open
#3,464 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

Client-side defects: post-compaction render stall, queued prompt silently dropped, completed turn never rendered (wire-level forensics)

Environment

  • kimi-code 0.39.1, Windows 11
  • Both clients affected: interactive TUI (Bug A cases 1–2) and web UI (kimi web, Bug A case 3, Bug B)
  • Evidence basis: full wire.jsonl (agent-side event stream) + .kimi-code/server/events/session_*.jsonl (server-side persistent event journal), line-anchored. Local archives available on request.

Bug A — "Requesting..." hang around auto-compaction (3 cases, 3 distinct shapes)

Auto-compaction event chain in wire (the only compaction signal a client can observe):
full_compaction.begin(source=auto)llm.request(turnStep=undefined) (summary generation) → context.apply_compaction + token_counting.rebasedfull_compaction.complete. Compaction produces no turn boundary; the turn continues with injected system reminders and the next step.

Case A1 — render-layer stall while agent loop is healthy (2026-09-01, TUI)
  • Compaction 11:50:05Z → 11:51:09Z (63 s summary). First post-compaction llm.request sent 19 ms after full_compaction.complete; the following 13 steps were all answered normally (4–26 s/step).
  • During this healthy progress the TUI displayed "请求中..." (requesting) with no visible progress; user aborted at 19:54:55 local; resend immediately recovered.
  • Conclusion: requests WERE sent and answered; the client's render layer froze. Not a request-scheduling bug.
Case A2 — queued prompt silently dropped (2026-09-01, TUI; NOT compaction-related)
  • A cron-fired turn occupied the session for ~18 min (long-running tool). The user's prompt was accepted (prompt.accepted 13:13:22Z) and queued as turn 18, but never produced turn.prompt / user-message append / llm.request.
  • When the user aborted the active turn, the queued turn was cancelled with it (turn.cancel target=queued, 13:13:32Z). From the user's perspective the sent instruction vanished.
  • Conclusion: queue-management defect — aborting the active turn silently cancels a queued prompt. (The user merged this with a separate compaction 12 min later in their report.)
Case A3 — llm.request unanswered for 100 s after compaction (2026-09-02, web UI)
  • Compaction 04:01:37Z → 04:02:50Z; post-compaction steps 5.12/5.13 answered normally.
  • llm.request turnStep=5.14 sent 04:03:06.518Z — no response event for 100+ s until user abort at 04:07:00Z (new prompt sent meanwhile stayed queued). Resend recovered immediately.
  • Conclusion: agent↔provider transport stall (request left the agent; response never arrived). Temporal proximity to compaction (2 steps) but no causal chain established.
  • Related: undo was rejected with 40911 Nothing to undo: would cross a compaction boundary (Request ID 01M1G4S1JQ7NMF33839RJAJEEA). Server-side boundary semantics work as designed, but the UX implication (undo silently unavailable across auto-compactions) is worth reconsidering.

Bug B — web UI never rendered a completed turn (2026-09-02)

  • Server journal proves business-layer completion: seq 237 turn.step.completed (finishReason=end_turn, output 777 tokens, 03:11:43.790Z), seq 238 turn.ended (completed), seq 239 work_changed(busy=false), seq 240 prompt.completed. Full 1046-char reply text exists in agent wire.
  • The browser never rendered any of it; turns 0 and 2 rendered fine. Session log: zero warn/error.
  • Frame-level delivery is unverifiable by design: reply rendering relies solely on volatile assistant.delta frames, which are never persisted and never replayed (verified: 0 volatile entries across ~90 server journals; no ws/frame/connection event types among the 52 journal envelope types; none of the 8 log surfaces record WS frames).
  • Protocol-level gap: cursors replay covers only persistent events. A client that misses volatile deltas (dead connection, lost subscription) can only repair via REST transcript / /snapshot — the official web client appears to have no such reconciliation, so a missed turn stays invisible until manual reload.

Suggestions

  1. Client-side reconciliation at turn.ended: if streaming gaps were observed (offset discontinuity) or no deltas were seen for a completed turn, re-pull transcript/snapshot before finalizing.
  2. Stream liveness watchdog: busy state with no events for N seconds → proactive snapshot poll.
  3. Queue management: aborting the active turn should not silently cancel queued prompts (or at least surface them as cancelled to the user).
  4. Investigate the render-layer stall (A1): agent loop healthy while TUI shows no progress.
  5. Undo UX: communicate that auto-compaction creates an undo boundary before the user hits 40911.
  6. Diagnostics: consider optional WS frame logging (the existing /export web_log bundle is a good precedent for client-side capture).

Evidence index (local, available on request)

  • Case A1: wire.jsonl lines 2639–2763 (compaction 2639–2644; cancel 2755; resend 2763)
  • Case A2: lines 3599–3891 (accepted 3879; queued-cancel 3881; interrupted tool.result 3883)
  • Case A3: lines 779–827 (compaction 779–784; unanswered request 812; undo error text pasted by user 822/824/825)
  • Bug B: server journal seq 237–240 (03:11:43Z); agent wire lines 429–431

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the client handling of volatile assistant.delta frames, turn.ended, and the REST transcript or /snapshot reconciliation path, using the wire.jsonl and server session journals as evidence. Compare the TUI and web UI behavior for the queued prompt, post-compaction stall, and completed-turn cases. Done means the affected turns remain visible or are clearly reported after cancellation, compaction, missed frames, and completion.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, cli, frontend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.