MoonshotAI / MoonshotAI/kimi-cli

feat(hooks): mid-turn streaming hook (MessageDisplay) for live reply consumers

Open
#2,511 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
11.4k
Forks
1.3k
Avg merge
9h 47m
Merged PRs (30d)
2

Description

Summary

The Hooks system (Beta) currently has no way to observe the assistant reply while it streams. Stop fires once at the end of the turn and carries no reply text, so external consumers that want to react to the reply as it's written — live narration/TTS, incremental logging, progress UIs — can only act after the turn ends.

Proposal

Add a fire-and-forget MessageDisplay hook event that fires repeatedly as the reply streams, before Stop:

{
  "hook_event_name": "MessageDisplay",
  "session_id": "...",
  "cwd": "...",
  "message_id": "stable id for the whole streamed message",
  "displayed_text": "the CUMULATIVE text streamed so far (not a delta)",
  "is_final": "true on the last firing for this message"
}
  • Debounced (~200ms, leading-edge per chunk); the final firing is unconditional, so the reply's tail is never dropped waiting on the window.
  • Cumulative payloads: hook scripts never reassemble chunks; slow hooks skip intermediate snapshots losslessly (at most one mid-stream execution in flight; newer payloads replace the queued one).
  • is_final never queues behind a stale delivery and always arrives before Stop; the turn waits up to 5s for the final delivery (bounded, so a slow hook can't stall a turn or a headless run).
  • Cancellation suppresses is_final; tool-call-only messages fire nothing; each model call in a tool-using turn gets its own message_id.
  • Fires on every surface (shell, print/headless, ACP, wire, web) since all share the same streaming path in KimiSoul._step.

Prior art

This mirrors the MessageDisplay hook contributed to Qwen Code (a gemini-cli fork): feat(hooks): add MessageDisplay hook for mid-turn streaming (fixes QwenLM/qwen-code#6488) — cumulative displayed_text, is_final, ~200ms debounce, coalesced delivery, bounded final drain. The design held up through review there; a port would preserve its semantics on kimi-cli's hook engine.

Happy to send a PR implementing this.

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 at the shared streaming path in KimiSoul._step and inspect kimi-cli's hook engine, comparing its behavior with the referenced Qwen Code MessageDisplay implementation. Done means cumulative debounced MessageDisplay events work across every listed surface, handle cancellation and tool calls as specified, deliver the final event before Stop, and respect the bounded wait.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.