Download packages/agent-core-v2/src/features/notify/notifyUserNudge.ts from SaylorTwift/kimi-code: direct link, hf CLI and curl.
- Browser
- Download file 3.24 kB
-
https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/agent-core-v2/src/features/notify/notifyUserNudge.ts
- Command line
-
hf download hf://SaylorTwift/kimi-code/packages/agent-core-v2/src/features/notify/notifyUserNudge.ts
-
curl -L -o notifyUserNudge.ts https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/agent-core-v2/src/features/notify/notifyUserNudge.ts
3.24 kB
| import type { ContextMessage } from '#/agent/contextMemory/types'; | |
| import { NOTIFY_USER_TOOL_NAME } from './tools/notify-user/notify-user'; | |
| export const NOTIFY_USER_NUDGE_VARIANT = 'notify_user_nudge'; | |
| export const NOTIFY_USER_NUDGE_THRESHOLD = 8; | |
| function startsNewTurn(message: ContextMessage): boolean { | |
| const origin = message.origin; | |
| if (origin === undefined) return false; | |
| switch (origin.kind) { | |
| case 'user': | |
| case 'cron_job': | |
| case 'cron_missed': | |
| case 'task': | |
| case 'retry': | |
| return true; | |
| case 'system_trigger': | |
| return origin.name !== 'stop_hook'; | |
| case 'skill_activation': | |
| return origin.trigger === 'user-slash'; | |
| case 'plugin_command': | |
| return true; | |
| default: | |
| return false; | |
| } | |
| } | |
| export function toolCallsSinceLastNotify(history: readonly ContextMessage[]): number { | |
| let count = 0; | |
| for (let index = history.length - 1; index >= 0; index -= 1) { | |
| const message = history[index]!; | |
| if (startsNewTurn(message)) break; | |
| if (message.role !== 'assistant') continue; | |
| if (message.toolCalls.some((call) => call.name === NOTIFY_USER_TOOL_NAME)) break; | |
| count += message.toolCalls.length; | |
| } | |
| return count; | |
| } | |
| export function toolCallsSincePosition( | |
| history: readonly ContextMessage[], | |
| position: number, | |
| ): number { | |
| let count = 0; | |
| for (const message of history.slice(position + 1)) { | |
| if (message.role !== 'assistant') continue; | |
| count += message.toolCalls.length; | |
| } | |
| return count; | |
| } | |
| export function lastMidResponsePosition(history: readonly ContextMessage[]): number { | |
| for (let index = history.length - 1; index >= 0; index -= 1) { | |
| const message = history[index]!; | |
| if (startsNewTurn(message)) break; | |
| if (message.role !== 'assistant') continue; | |
| if (message.toolCalls.some((call) => call.name === NOTIFY_USER_TOOL_NAME)) break; | |
| const hasVisibleText = message.content.some( | |
| (part) => part.type === 'text' && part.text.trim().length > 0, | |
| ); | |
| if (hasVisibleText) return index; | |
| } | |
| return -1; | |
| } | |
| export function shouldNudgeNotifyUser( | |
| streak: number, | |
| callsSinceLastNudge: number | null, | |
| ): boolean { | |
| if (streak < NOTIFY_USER_NUDGE_THRESHOLD) return false; | |
| return callsSinceLastNudge === null || callsSinceLastNudge >= NOTIFY_USER_NUDGE_THRESHOLD; | |
| } | |
| export function shouldNudgeMidResponse( | |
| midResponsePosition: number, | |
| lastInjectedAt: number | null, | |
| ): boolean { | |
| if (midResponsePosition < 0) return false; | |
| return lastInjectedAt === null || lastInjectedAt < midResponsePosition; | |
| } | |
| export function renderNotifyUserNudge(count: number): string { | |
| return `You have gone ${String(count)} tool calls without a NotifyUser update — the user has seen nothing in the meantime. Send one now: a structured, chat-style update (a well structured paragraph with a few bullet points, under ~1000 characters) covering what you have concluded so far and what you will do next, batched with your next tool calls.`; | |
| } | |
| export function renderMidResponseHint(): string { | |
| return 'You just sent a mid-turn text reply — easy for the user to miss between tool calls. Repost its substance as a NotifyUser update (a short intro plus a few bullet points), batched with your next tool calls, then continue.'; | |
| } | |