Skip to content

feat(hooks): remind users to start new sessions - #257

Closed
lurkacai0831 wants to merge 2 commits into
Tencent:mainfrom
lurkacai0831:feat/turn-limit-hint
Closed

feat(hooks): remind users to start new sessions#257
lurkacai0831 wants to merge 2 commits into
Tencent:mainfrom
lurkacai0831:feat/turn-limit-hint

Conversation

@lurkacai0831

Copy link
Copy Markdown

Summary

Adds a turn-limit hint that nudges users to start a new session once a conversation reaches a configurable threshold. A prompt-submit handler counts human turns and schedules a user-visible reminder delivered by a stop handler after the assistant's current response completes.

  • Default threshold: 20 turns (TEAMAI_TURN_LIMIT).
  • Reminder repeats every 3 turns after the first crossing.
  • Kill switch: TEAMAI_TURN_HINT_DISABLED=1.
  • Users can mute the current session by replying with phrases like "关闭轮次提醒" or "disable turn hint".

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature causing existing behavior to change)
  • Documentation only
  • Refactor / internal cleanup

Test Plan

  • npx tsc --noEmit passes
  • npx vitest run passes for affected test files
  • Added/updated tests for the change
npx vitest run src/__tests__/turn-limit-hint.test.ts src/__tests__/hook-dispatch.test.ts src/__tests__/hook-handlers.test.ts

Related Issues

Closes #227

Notes for Reviewers

  • Visible delivery is implemented on the stop hook rather than prompt-submit because prompt-submit's additionalContext is not reliably surfaced to users. The counter records state on prompt-submit; the reminder is rendered after the assistant finishes its current turn.
  • The pending-reminder flag is only cleared via onAccepted when the dispatcher actually selects the handler's output, avoiding lost reminders when a higher-priority stop handler wins.

@lurkacai0831

Copy link
Copy Markdown
Author

已提交 PR #257 实现该功能。\n\n主要实现:\n- 在 上计数用户轮次\n- 在 上输出可见提醒\n- 默认阈值 20,支持 覆盖\n- 支持 永久关闭\n- 支持回复 "关闭轮次提醒" / "disable turn hint" 静默当前会话

@lurkacai0831

lurkacai0831 commented Jul 28, 2026

Copy link
Copy Markdown
Author

本地验证截图:当会话达到轮次阈值后,Stop hook 输出如下提示:

[teamai:turn-limit-hint] 当前会话已进行较多轮对话。

长会话会累积大量上下文,可能降低响应质量并增加成本。
建议在完成当前任务后,开启新的会话继续后续工作。
如不需要此提醒,请回复"关闭轮次提醒"静默当前会话,或设置环境变量 TEAMAI_TURN_HINT_DISABLED=1 永久关闭。
Clipboard_Screenshot_1785239858

@jeff-r2026

Copy link
Copy Markdown
Collaborator

Reviewed the diff and ran the PR branch locally — tsc --noEmit clean and all 70 tests across the three affected files pass. The design is solid; the onAccepted deferred-acknowledgement mechanism (keeping a pending hint queued when a higher-priority Stop handler wins the output race) is well thought out and well tested.

A few non-blocking suggestions:

1. isTurnHintDisabled() is effectively dead code
The helper is exported and tested, but both handlers inline process.env.TEAMAI_TURN_HINT_DISABLED === '1' (hook-handlers.ts:323,341) instead of calling it. Suggest routing both through the helper so the kill-switch semantics live in one place.

2. session-id derivation is inconsistent with the other Stop handlers
turn-limit-counter / turn-limit-hint use deriveSessionId(stdin) while votes-sync / contribute-check use deriveSessionId(stdin, { includeCwd: true }). They're internally consistent so it works, but when session_id is missing and it falls back to pid-${ppid}, two different project dirs under the same parent shell would share one turn counter. The other handlers pass includeCwd precisely to avoid this — worth aligning.

3. (very minor) mute keyword uses substring match
isMuteSignal uses includes, so a prompt like "how do I disable turn hint feature?" would also mute the session. Acceptable edge case — just flagging it as a design trade-off.

None of these block merge; #1 is the one I'd fix to keep the helper and actual usage in sync.

- Use isTurnHintDisabled() helper in both handlers

- Derive session id with includeCwd to align with other stop handlers
@lurkacai0831

lurkacai0831 commented Jul 29, 2026

Copy link
Copy Markdown
Author

@jeff-r2026 Thanks for the review. Updated per your suggestions:\n\n1. Both handlers now use the isTurnHintDisabled() helper instead of inlining the env check.\n2. Changed deriveSessionId(stdin) to deriveSessionId(stdin, { includeCwd: true }) to align with votes-sync / contribute-check, preventing different project directories under the same shell from sharing the turn counter.\n\nLocal verification: npx tsc --noEmit passes and all 70 relevant unit tests pass.

@jeff-r2026 jeff-r2026 closed this Jul 30, 2026
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.

[feat] Hint the user to start a new session after N conversation turns

2 participants