Problem
Currently the Stop hook payload only carries a minimal set of metadata (e.g. aborted). For external memory systems that want to observe and learn from a completed turn, this is insufficient: they can see that the agent stopped, but not what was said during the turn.
Without the assistant reply, a memory hook cannot store the full user/assistant exchange. It must rely on:
- Earlier hooks such as
UserPromptSubmit (which only sees the user message), or
- Asking the model to explicitly call memory tools, which is unreliable and adds latency.
How other agent CLIs solve this
We surveyed the hook/event designs of several popular agent CLIs in the ecosystem:
Claude Code
- Stop hook receives
transcript_path pointing to a JSONL transcript file.
- Hooks can read the transcript to extract recent user/assistant messages.
- Source:
plugins/plugin-dev/skills/hook-development/SKILL.md
OpenAI Codex
- Stop hook receives
last_assistant_message inline, plus transcript_path to the rollout JSONL.
- There is also a legacy
AfterAgent hook that passes recent user messages inline.
- Source:
codex-rs/hooks/src/schema.rs, codex-rs/hooks/schema/generated/stop.command.input.schema.json
OpenCode
- No direct
Stop hook, but plugins can listen to:
chat.message for each new user turn,
event for durable assistant/tool/text events,
experimental.chat.messages.transform to read the full message list before the LLM call.
- Source:
packages/plugin/src/index.ts, packages/opencode/src/plugin/index.ts
kimi-cli (previous generation)
- Stop hook only receives
stop_hook_active, similar to the current kimi-code behavior.
- Conversation is available only by reading session files from disk.
- Source:
src/kimi_cli/hooks/events.py, src/kimi_cli/wire/types.py
Why PR #1299 is the right fix
PR #1299 (#1299) extends the Stop hook inputData with a messages array containing the recent user/assistant messages, with non-text content parts filtered out for JSON safety.
This brings kimi-code in line with the ecosystem:
- Codex provides
last_assistant_message + transcript path.
- Claude Code provides transcript path.
- kimi-code would provide the recent messages inline, which is the most hook-friendly approach and avoids requiring filesystem access or parsing JSONL transcripts.
Benefits
- External memory systems can learn from full turns. A memory hook can store user preferences, decisions, and facts from both the user prompt and the assistant reply.
- Backward compatible. Existing Stop hooks that ignore
messages continue to work unchanged.
- No extra model/tool calls needed. The hook receives the context deterministically at the end of each turn.
- Aligns with user expectations. Developers coming from Claude Code or Codex expect lifecycle hooks to expose enough context to build memory, logging, and observability integrations.
Request
Please review and consider merging PR #1299. The implementation is minimal, tested, and includes documentation and a changeset.
cc @wbxl2000 @liruifengv @RealKai42 — would love your feedback on this.
Problem
Currently the
Stophook payload only carries a minimal set of metadata (e.g.aborted). For external memory systems that want to observe and learn from a completed turn, this is insufficient: they can see that the agent stopped, but not what was said during the turn.Without the assistant reply, a memory hook cannot store the full user/assistant exchange. It must rely on:
UserPromptSubmit(which only sees the user message), orHow other agent CLIs solve this
We surveyed the hook/event designs of several popular agent CLIs in the ecosystem:
Claude Code
transcript_pathpointing to a JSONL transcript file.plugins/plugin-dev/skills/hook-development/SKILL.mdOpenAI Codex
last_assistant_messageinline, plustranscript_pathto the rollout JSONL.AfterAgenthook that passes recent user messages inline.codex-rs/hooks/src/schema.rs,codex-rs/hooks/schema/generated/stop.command.input.schema.jsonOpenCode
Stophook, but plugins can listen to:chat.messagefor each new user turn,eventfor durable assistant/tool/text events,experimental.chat.messages.transformto read the full message list before the LLM call.packages/plugin/src/index.ts,packages/opencode/src/plugin/index.tskimi-cli (previous generation)
stop_hook_active, similar to the current kimi-code behavior.src/kimi_cli/hooks/events.py,src/kimi_cli/wire/types.pyWhy PR #1299 is the right fix
PR #1299 (#1299) extends the Stop hook inputData with a
messagesarray containing the recent user/assistant messages, with non-text content parts filtered out for JSON safety.This brings kimi-code in line with the ecosystem:
last_assistant_message+ transcript path.Benefits
messagescontinue to work unchanged.Request
Please review and consider merging PR #1299. The implementation is minimal, tested, and includes documentation and a changeset.
cc @wbxl2000 @liruifengv @RealKai42 — would love your feedback on this.