feat(hook): include response and stop_reason in Stop hook payload#2308
feat(hook): include response and stop_reason in Stop hook payload#2308AkaCoder404 wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c1a10da9aa
ℹ️ 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".
There was a problem hiding this comment.
Pull request overview
Enhances the Stop lifecycle hook payload with two new fields—response (the assistant's final natural-language text) and stop_reason ("no_tool_calls" / "tool_rejected")—so hook scripts can audit, gate, or analyze each turn's outcome. Both fields default to empty strings to preserve backward compatibility with existing hooks.
Changes:
events.stop()accepts and emits new optionalresponseandstop_reasonfields.KimiSoul.run()captures theTurnOutcomefrom_turn()and forwardsfinal_messagetext plusstop_reasoninto the Stop hook payload (empty for slash-command and Ralph-loop paths).- Adds a new test for the Stop hook payload and updates EN/ZH hook docs and changelogs.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/kimi_cli/hooks/events.py | Adds response and stop_reason keyword args to stop() payload builder. |
| src/kimi_cli/soul/kimisoul.py | Captures TurnOutcome from _turn() and threads response/stop_reason into Stop hook trigger. |
| tests/core/test_kimisoul_hooks.py | New test verifying Stop payload contains response and stop_reason. |
| docs/en/customization/hooks.md | Lists new response/stop_reason fields in Stop row. |
| docs/zh/customization/hooks.md | Localized doc update mirroring EN. |
| CHANGELOG.md | Adds Unreleased entry describing the new payload fields. |
| docs/en/release-notes/changelog.md | Synced English changelog entry. |
| docs/zh/release-notes/changelog.md | Synced Chinese changelog entry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 18b3e0eb1a
ℹ️ 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".
Related Issue
Resolve #2307
Description
This PR enhances the
Stophook payload with the agent's response text and stop reason, enabling post-turn auditing, conditional approval, and analytics.Changes
1.
src/kimi_cli/hooks/events.pyresponse(default"") andstop_reason(default"") parameters toevents.stop()2.
src/kimi_cli/soul/kimisoul.pyTurnOutcomereturned by_turn()turn_outcome.final_messagewhen availableresponseandstop_reasoninto theStophook payloadturn_outcome = Nonefor slash-command and Ralph-loop paths so the hook still fires safely3.
tests/core/test_kimisoul_hooks.pytest_stop_hook_includes_response_and_stop_reasonverifying the payload receives"The fix is complete."and"no_tool_calls"from a mockedTurnOutcome4. Documentation
docs/en/customization/hooks.mdanddocs/zh/customization/hooks.mdto list the newresponseandstop_reasonfields in theStoprowNew payload shape
{ "hook_event_name": "Stop", "session_id": "abc123", "cwd": "/path/to/project", "stop_hook_active": false, "stop_reason": "no_tool_calls", "response": "The fix is complete. I updated src/main.py..." }stop_reasonis"no_tool_calls"when the agent spoke naturally, or"tool_rejected"when a tool call was rejectedresponseis empty when the turn produced no natural-language output (e.g. pure tool rejection)Backwards compatibility
The new fields are optional and default to empty strings. Existing hooks that do not read them continue to work unchanged.
Checklist
make gen-changelogto update the changelog.