Skip to content

fix: UserPromptSubmit hook loses prompt when user_input is list[ContentPart] || fix: UserPromptSubmit hook loses prompt when user_input is list[ContentPart]#1832

Open
Hcaepllams wants to merge 1 commit intoMoonshotAI:mainfrom
Hcaepllams:fix/userpromptsubmit-hook-prompt
Open

Conversation

@Hcaepllams
Copy link
Copy Markdown

@Hcaepllams Hcaepllams commented Apr 10, 2026

Bug Description

The UserPromptSubmit hook always receives an empty prompt field, making it impossible for third-party hooks to capture the actual user input.

Root Cause

In src/kimi_cli/soul/kimisoul.py, the UserPromptSubmit hook preparation does:

text_input_for_hook = user_input if isinstance(user_input, str) else ""

However, in practice user_input is always passed as list[ContentPart]:
• Terminal shell mode: ui/shell/init.py passes user_input.content (typed as list[ContentPart] in prompt.py)
• Wire/ACP mode: the server also passes structured content parts
Because isinstance(user_input, str) is effectively never true, text_input_for_hook is always "", and events.user_prompt_submit(prompt=...) sends empty text to hooks.
Fix
Extract text from ContentPart items when user_input is a list:
if isinstance(user_input, str):
text_input_for_hook = user_input
else:
_parts: list[str] = []
for _part in user_input:
if getattr(_part, "type", None) == "text":
_parts.append(getattr(_part, "text", ""))
text_input_for_hook = "".join(_parts)
Impact
• Any UserPromptSubmit hook that logs, audits, or forwards the user's prompt to external services (e.g. Telegram, Slack) currently receives empty content.
• This affects all Kimi CLI users regardless of launch mode (terminal, VS Code extension, or ACP).
Checklist
• [x] Bug fix (non-breaking change which fixes an issue)
• [ ] New feature
• [ ] Breaking change
Prek checks
• make format-kimi-cli ✅
• make check-kimi-cli ✅


Bug Description

The UserPromptSubmit hook always receives an empty prompt field, making it impossible for third-party hooks to capture the actual user input.

Root Cause

In src/kimi_cli/soul/kimisoul.py, the UserPromptSubmit hook preparation does:

text_input_for_hook = user_input if isinstance(user_input, str) else ""

However, in practice user_input is always passed as list[ContentPart]:
• Terminal shell mode: ui/shell/init.py passes user_input.content (typed as list[ContentPart] in prompt.py)
• Wire/ACP mode: the server also passes structured content parts
Because isinstance(user_input, str) is effectively never true, text_input_for_hook is always "", and events.user_prompt_submit(prompt=...) sends empty text to hooks.
Fix
Extract text from ContentPart items when user_input is a list:
if isinstance(user_input, str):
text_input_for_hook = user_input
else:
_parts: list[str] = []
for _part in user_input:
if getattr(_part, "type", None) == "text":
_parts.append(getattr(_part, "text", ""))
text_input_for_hook = "".join(_parts)
Impact
• Any UserPromptSubmit hook that logs, audits, or forwards the user's prompt to external services (e.g. Telegram, Slack) currently receives empty content.
• This affects all Kimi CLI users regardless of launch mode (terminal, VS Code extension, or ACP).
Checklist
• [x] Bug fix (non-breaking change which fixes an issue)
• [ ] New feature
• [ ] Breaking change
Prek checks
• make format-kimi-cli ✅
• make check-kimi-cli ✅

…ntPart]

In terminal mode, Shell.run_soul_command passes user_input.content
(which is list[ContentPart]) to KimiSoul.run. The existing code only
handled the str case, causing the hook payload's 'prompt' to always be
empty. Extract text parts from ContentPart list so hooks can capture
the actual user input.
@github-actions github-actions bot changed the title fix: UserPromptSubmit hook loses prompt when user_input is list[ContentPart] fix: UserPromptSubmit hook loses prompt when user_input is list[ContentPart] || fix: UserPromptSubmit hook loses prompt when user_input is list[ContentPart] Apr 10, 2026
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 1 additional finding.

Open in Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant