MoonshotAI / MoonshotAI/kimi-code
Expose stable product turn identity to UserPromptSubmit hooks
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 1.2k
- Avg merge
- 11h 53m
- Merged PRs (30d)
- 350
Description
Kimi hook request: expose stable product turn identity to UserPromptSubmit
Summary
UserPromptSubmit has no stable product-level event identifier. A hook cannot
distinguish a reconstructed callback from a genuine second identical user
submission, so idempotent pre-answer context injection is impossible.
Affected build
- Kimi Desktop: 3.2.5
- bundled
@moonshot-ai/agent-core: 0.15.7 - current upstream
mainalso callsapplyUserPromptHook(turnId, ...)but
passes onlyinputData: { prompt: input }.
Current payload
The hook engine emits the base session/cwd fields plus the structured prompt:
{
"hook_event_name": "UserPromptSubmit",
"session_id": "kernel-session",
"cwd": "/workspace",
"prompt": [{"type": "text", "text": "..."}]
}
The kernel session_id is not the accepted Desktop send identity and may
change when Kimi reconstructs a worker/session.
Reproduction
Using Kimi Desktop's authenticated local control.v1 lane, create one isolated
conversation and submit one unique synthetic prompt with agentSwarm:false.
Count only invocations of one installed UserPromptSubmit hook; do not read
message content. In the observed WORKER_FAILED path, one accepted product turn
caused four hook invocations, including after a clean Desktop relaunch.
Time-window/content hashing is not a correct repair: a later replay can arrive
after the window, while a genuine identical user submission inside the window
is falsely suppressed.
Requested contract
Propagate the already-existing product coordinates into the hook payload:
{
"conversation_key": "product-conversation-id",
"turn_id": "product-turn-id"
}
The pair must remain stable for every reconstruction/retry of one accepted
product turn, and a new genuine submission must receive a new pair. Please
document its uniqueness and replay semantics.
Why both fields
The numeric agent-core turnId is session-scoped. Kimi Desktop's product
dispatcher already keeps product conversationKey and product turnId
separate from kernelSessionId; the conservative idempotency key is therefore
the pair (conversation_key, turn_id).
Privacy and compatibility
- This is additive snake-case hook input and does not change existing output
semantics. - Hooks can hash the pair and need not persist either identifier or prompt text.
- Existing hooks ignoring unknown fields remain compatible.
- A delivery ID acknowledged atomically by Kimi would be even stronger; an
external marker alone can guarantee at-most-once admission, not transactional
end-to-end exactly-once consumption.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Trace the UserPromptSubmit path from the hook engine and the applyUserPromptHook(turnId, ...) call into the product dispatcher. Verify where conversationKey, product turnId, and kernelSessionId are available, then propagate the first two in snake_case and document replay and uniqueness semantics. Done means retries share the pair while a new submission receives a new pair, without changing existing fields.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, cli
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100