hooks: deliver kimi-code handoff via UserPromptSubmit

Kimi Code fires SessionStart but discards the hook's stdout/result
(kimi-code v0.28.1, packages/agent-core/src/session/index.ts), so the
session-start hook consumed pending handoffs into the void. Move the
/handoff fetch to user-prompt-submit (stdout is injected as a user
message before the turn), with the native sessionId forwarded as
session_id and managed_run already appended by ai_memory_marker_qs.
This commit is contained in:
Lucas Oliveira
2026-07-22 21:03:44 -03:00
parent e4767f402c
commit e2f5af92da
4 changed files with 30 additions and 9 deletions
+4 -1
View File
@@ -1,3 +1,6 @@
# Kimi Code discards SessionStart hook stdout (v0.28.1,
# packages/agent-core/src/session/index.ts), so the handoff is fetched
# by user-prompt-submit.ps1 instead. This hook only captures the event.
. "$PSScriptRoot\..\lib\ai-memory-hook.ps1"
Invoke-AiMemoryHook -Event "session-start" -Agent "kimi-code" -FetchHandoff
Invoke-AiMemoryHook -Event "session-start" -Agent "kimi-code"
exit 0
+8 -6
View File
@@ -1,10 +1,13 @@
#!/bin/sh
# kimi-code SessionStart hook.
# 1. Forwards the event JSON to the ai-memory server (fire-and-forget).
# 2. Synchronously fetches any pending cross-agent handoff and prints
# it to stdout — kimi-code appends exit-0 hook stdout to the agent's
# context, so the resuming agent sees prior context with no human
# in the loop.
# Forwards the event JSON to the ai-memory server (fire-and-forget).
#
# No handoff fetch here: Kimi Code fires SessionStart but DISCARDS the
# hook's stdout/result (kimi-code v0.28.1,
# packages/agent-core/src/session/index.ts), so a handoff consumed here
# would be lost. The handoff is delivered by user-prompt-submit.sh —
# Kimi Code injects UserPromptSubmit stdout as a user message before
# the turn.
#
_lib_dir="$(dirname "$0")"
[ -f "$_lib_dir/_lib.sh" ] || _lib_dir="$_lib_dir/.."
@@ -17,5 +20,4 @@ QS=$(ai_memory_marker_qs "$CWD")
printf '%s' "$PAYLOAD" \
| ai_memory_post_hook "$SERVER/hook?event=session-start&agent=kimi-code${QS}" >/dev/null 2>&1 || true
ai_memory_get_handoff "$SERVER/handoff?agent=kimi-code${QS}" 2>/dev/null || true
exit 0
+4 -1
View File
@@ -1,3 +1,6 @@
# Kimi Code injects UserPromptSubmit hook stdout as a user message
# (origin hook_result) before the turn, so the pending handoff is
# fetched here. Empty stdout injects nothing.
. "$PSScriptRoot\..\lib\ai-memory-hook.ps1"
Invoke-AiMemoryHook -Event "user-prompt" -Agent "kimi-code"
Invoke-AiMemoryHook -Event "user-prompt" -Agent "kimi-code" -FetchHandoff
exit 0
+14 -1
View File
@@ -1,6 +1,13 @@
#!/bin/sh
# kimi-code user-prompt hook.
# Forwards the event JSON to the ai-memory server, fire-and-forget.
# 1. Forwards the event JSON to the ai-memory server (fire-and-forget).
# 2. Synchronously fetches any pending cross-agent handoff and prints
# it to stdout — kimi-code injects UserPromptSubmit hook stdout as a
# user message (origin hook_result) before the turn, so the agent
# sees prior context with no human in the loop. SessionStart cannot
# deliver it: kimi-code discards SessionStart hook stdout (v0.28.1,
# packages/agent-core/src/session/index.ts). Empty stdout injects
# nothing, so print only when a handoff exists.
_lib_dir="$(dirname "$0")"
[ -f "$_lib_dir/_lib.sh" ] || _lib_dir="$_lib_dir/.."
. "$_lib_dir/_lib.sh"
@@ -9,7 +16,13 @@ SERVER="${AI_MEMORY_HOOK_URL:-http://127.0.0.1:49374}"
PAYLOAD=$(cat)
CWD=$(ai_memory_extract_cwd "$PAYLOAD")
QS=$(ai_memory_marker_qs "$CWD")
SESSION_ID=$(ai_memory_extract_session_id "$PAYLOAD")
SESSION_QS=""
[ -n "$SESSION_ID" ] && SESSION_QS="&session_id=$(ai_memory_url_encode "$SESSION_ID")"
printf '%s' "$PAYLOAD" \
| ai_memory_post_hook "$SERVER/hook?event=user-prompt&agent=kimi-code${QS}" >/dev/null 2>&1 || true
HANDOFF=$(ai_memory_get_handoff "$SERVER/handoff?agent=kimi-code${QS}${SESSION_QS}" 2>/dev/null || true)
[ -n "$HANDOFF" ] && printf '%s\n' "$HANDOFF"
exit 0