Skip to content

Commit b3bc429

Browse files
wenshaoclaude
andauthored
feat: add contextual tips system with post-response context awareness (#2904)
* feat: add contextual tips system with post-response context awareness Add a context-aware tips system that proactively shows helpful tips based on session state. Post-response tips warn when context usage exceeds 80% or 95%, suggesting /compress. Startup tips rotate across sessions via LRU scheduling with cross-session persistence (~/.qwen/tip_history.json). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use value import for runtime values in useContextualTips Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address PR review feedback - Use lastSessionTimestamp instead of totalShown for cross-session LRU - Move getTipHistory singleton from Tips.tsx to services/tips/index.ts - Defer TipHistory.load() when hideTips is true (no side effects) - Use os.tmpdir() in tests for cross-platform portability - Add proper translations for de/ja/pt/ru locale files - Accept TipHistory | null in useContextualTips Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address Copilot review feedback - Validate tips field type in TipHistory.load() to handle corrupted JSON - Split approval-mode tip into platform-specific variants using ctx.platform - Add afterEach cleanup for temp files in all test suites - Guard useContextualTips against null tipHistory Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: import shared DEFAULT_TOKEN_LIMIT, harden tipHistory, set file permissions - Import DEFAULT_TOKEN_LIMIT from @qwen-code/qwen-code-core instead of hardcoding 1_048_576 in tipRegistry.ts and useContextualTips.ts - Add normalizeEntry() to defensively handle corrupted tip history entries - Write tip_history.json with mode 0o600 for privacy on multi-user systems Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove unused compressionThreshold from TipContext compressionThreshold was defined in TipContext but never used by any tip's isRelevant check. Remove it to avoid misleading consumers into thinking tips respect the user's compression settings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: sanitize sessionCount and getLastShown against corrupted tip history - Validate sessionCount is finite and non-negative in TipHistory.load() - Use normalizeEntry() in getLastShown() for corrupted lastSessionTimestamp Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add contextual tips user documentation Add docs/users/features/tips.md covering startup tips, post-response context warnings, tip history persistence, and the hideTips setting. Update settings.md description and register the new page in _meta.ts. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6af0f37 commit b3bc429

File tree

19 files changed

+1160
-92
lines changed

19 files changed

+1160
-92
lines changed

docs/users/configuration/settings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ Settings are organized into categories. All settings should be placed within the
100100
| `ui.customThemes` | object | Custom theme definitions. | `{}` |
101101
| `ui.statusLine` | object | Custom status line configuration. A shell command whose output is shown in the footer's left section. See [Status Line](../features/status-line). | `undefined` |
102102
| `ui.hideWindowTitle` | boolean | Hide the window title bar. | `false` |
103-
| `ui.hideTips` | boolean | Hide helpful tips in the UI. | `false` |
103+
| `ui.hideTips` | boolean | Hide all tips (startup and post-response) in the UI. See [Contextual Tips](../features/tips). | `false` |
104104
| `ui.hideBanner` | boolean | Hide the application banner. | `false` |
105105
| `ui.hideFooter` | boolean | Hide the footer from the UI. | `false` |
106106
| `ui.showMemoryUsage` | boolean | Display memory usage information in the UI. | `false` |

docs/users/features/_meta.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ export default {
1919
hooks: 'Hooks',
2020
'status-line': 'Status Line',
2121
'scheduled-tasks': 'Scheduled Tasks',
22+
tips: 'Contextual Tips',
2223
};

docs/users/features/tips.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Contextual Tips
2+
3+
Qwen Code includes a contextual tips system that helps you discover features and stay aware of session state.
4+
5+
## Startup Tips
6+
7+
Each time you launch Qwen Code, a tip is shown in the header area. Tips are selected by priority first, then rotated across sessions using LRU (least-recently-used) scheduling among tips of the same priority, so you see a different tip each time.
8+
9+
New users see onboarding-focused tips during their first sessions:
10+
11+
| Sessions | Example tips |
12+
| -------- | ---------------------------------------------------- |
13+
| < 5 | Slash commands (`/`), Tab autocomplete |
14+
| < 10 | `QWEN.md` project context, `--continue` / `--resume` |
15+
| < 15 | Shell commands with `!` prefix |
16+
17+
After that, tips rotate through general features like `/compress`, `/approval-mode`, `/insight`, `/btw`, and more.
18+
19+
## Post-Response Tips
20+
21+
During a conversation, Qwen Code monitors your context window usage and shows tips when action may be needed:
22+
23+
| Context usage | Condition | Tip |
24+
| ------------- | ------------------------------ | ------------------------------------------------- |
25+
| 50-80% | After a few prompts in session | Suggests `/compress` to free up context |
26+
| 80-95% || Warns context is getting full |
27+
| >= 95% || Urgent: run `/compress` now or `/new` to continue |
28+
29+
Post-response tips have per-tip cooldowns to avoid being repetitive.
30+
31+
## Tip History
32+
33+
Tip display history is persisted at `~/.qwen/tip_history.json`. This file tracks:
34+
35+
- Session count (used for new-user tip selection)
36+
- Which tips have been shown and when (used for LRU rotation and cooldown)
37+
38+
You can safely delete this file to reset tip history.
39+
40+
## Disabling Tips
41+
42+
To hide all tips (both startup and post-response), set `ui.hideTips` to `true` in `~/.qwen/settings.json`:
43+
44+
```json
45+
{
46+
"ui": {
47+
"hideTips": true
48+
}
49+
}
50+
```
51+
52+
You can also toggle this in the settings dialog via the `/settings` command.
53+
54+
Tips are also automatically hidden when screen reader mode is enabled.

packages/cli/src/i18n/locales/de.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,6 +1781,16 @@ export default {
17811781
'Sie können den Berechtigungsmodus schnell mit Tab oder /approval-mode wechseln.',
17821782
'Try /insight to generate personalized insights from your chat history.':
17831783
'Probieren Sie /insight, um personalisierte Erkenntnisse aus Ihrem Chatverlauf zu erstellen.',
1784+
'Add a QWEN.md file to give Qwen Code persistent project context.':
1785+
'Fügen Sie eine QWEN.md-Datei hinzu, um Qwen Code dauerhaften Projektkontext zu geben.',
1786+
'Use /btw to ask a quick side question without disrupting the conversation.':
1787+
'Verwenden Sie /btw, um eine kurze Nebenfrage zu stellen, ohne die Unterhaltung zu unterbrechen.',
1788+
'Context is almost full! Run /compress now or start /new to continue.':
1789+
'Der Kontext ist fast voll! Führen Sie jetzt /compress aus oder starten Sie /new, um fortzufahren.',
1790+
'Context is getting full. Use /compress to free up space.':
1791+
'Der Kontext füllt sich. Verwenden Sie /compress, um Platz freizugeben.',
1792+
'Long conversation? /compress summarizes history to free context.':
1793+
'Lange Unterhaltung? /compress fasst den Verlauf zusammen, um Kontext freizugeben.',
17841794

17851795
// ============================================================================
17861796
// Custom API Key Configuration

packages/cli/src/i18n/locales/en.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,16 @@ export default {
15571557
'You can switch permission mode quickly with Tab or /approval-mode.',
15581558
'Try /insight to generate personalized insights from your chat history.':
15591559
'Try /insight to generate personalized insights from your chat history.',
1560+
'Add a QWEN.md file to give Qwen Code persistent project context.':
1561+
'Add a QWEN.md file to give Qwen Code persistent project context.',
1562+
'Use /btw to ask a quick side question without disrupting the conversation.':
1563+
'Use /btw to ask a quick side question without disrupting the conversation.',
1564+
'Context is almost full! Run /compress now or start /new to continue.':
1565+
'Context is almost full! Run /compress now or start /new to continue.',
1566+
'Context is getting full. Use /compress to free up space.':
1567+
'Context is getting full. Use /compress to free up space.',
1568+
'Long conversation? /compress summarizes history to free context.':
1569+
'Long conversation? /compress summarizes history to free context.',
15601570

15611571
// ============================================================================
15621572
// Exit Screen / Stats

packages/cli/src/i18n/locales/ja.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,16 @@ export default {
11761176
'Tab または /approval-mode で権限モードをすばやく切り替えられます。',
11771177
'Try /insight to generate personalized insights from your chat history.':
11781178
'/insight でチャット履歴からパーソナライズされたインサイトを生成できます。',
1179+
'Add a QWEN.md file to give Qwen Code persistent project context.':
1180+
'QWEN.md ファイルを追加すると、Qwen Code に永続的なプロジェクトコンテキストを与えられます。',
1181+
'Use /btw to ask a quick side question without disrupting the conversation.':
1182+
'会話を中断せずに /btw でちょっとした横道の質問ができます。',
1183+
'Context is almost full! Run /compress now or start /new to continue.':
1184+
'コンテキストがもうすぐいっぱいです!今すぐ /compress を実行するか、/new を開始して続けてください。',
1185+
'Context is getting full. Use /compress to free up space.':
1186+
'コンテキストが埋まりつつあります。/compress を使って空きを増やしてください。',
1187+
'Long conversation? /compress summarizes history to free context.':
1188+
'会話が長くなりましたか? /compress は履歴を要約してコンテキストを空けます。',
11791189
'Tips for getting started:': '始めるためのヒント:',
11801190
'1. Ask questions, edit files, or run commands.':
11811191
'1. 質問したり、ファイルを編集したり、コマンドを実行したりできます',

packages/cli/src/i18n/locales/pt.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,16 @@ export default {
15141514
'Você pode alternar o modo de permissão rapidamente com Shift+Tab ou /approval-mode.',
15151515
'Try /insight to generate personalized insights from your chat history.':
15161516
'Experimente /insight para gerar insights personalizados do seu histórico de conversas.',
1517+
'Add a QWEN.md file to give Qwen Code persistent project context.':
1518+
'Adicione um arquivo QWEN.md para dar ao Qwen Code um contexto persistente do projeto.',
1519+
'Use /btw to ask a quick side question without disrupting the conversation.':
1520+
'Use /btw para fazer uma pergunta lateral rápida sem interromper a conversa.',
1521+
'Context is almost full! Run /compress now or start /new to continue.':
1522+
'O contexto está quase cheio! Execute /compress agora ou inicie /new para continuar.',
1523+
'Context is getting full. Use /compress to free up space.':
1524+
'O contexto está ficando cheio. Use /compress para liberar espaço.',
1525+
'Long conversation? /compress summarizes history to free context.':
1526+
'Conversa longa? /compress resume o histórico para liberar contexto.',
15171527

15181528
// ============================================================================
15191529
// Exit Screen / Stats

packages/cli/src/i18n/locales/ru.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,6 +1708,16 @@ export default {
17081708
'Вы можете быстро переключать режим разрешений с помощью Tab или /approval-mode.',
17091709
'Try /insight to generate personalized insights from your chat history.':
17101710
'Попробуйте /insight, чтобы получить персонализированные выводы из истории чатов.',
1711+
'Add a QWEN.md file to give Qwen Code persistent project context.':
1712+
'Добавьте файл QWEN.md, чтобы предоставить Qwen Code постоянный контекст проекта.',
1713+
'Use /btw to ask a quick side question without disrupting the conversation.':
1714+
'Используйте /btw, чтобы задать короткий побочный вопрос, не прерывая основной разговор.',
1715+
'Context is almost full! Run /compress now or start /new to continue.':
1716+
'Контекст почти заполнен! Выполните /compress сейчас или начните /new, чтобы продолжить.',
1717+
'Context is getting full. Use /compress to free up space.':
1718+
'Контекст заполняется. Используйте /compress, чтобы освободить место.',
1719+
'Long conversation? /compress summarizes history to free context.':
1720+
'Долгий разговор? /compress подведёт итог истории, чтобы освободить контекст.',
17111721

17121722
// ============================================================================
17131723
// Custom API Key Configuration

packages/cli/src/i18n/locales/zh.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,6 +1474,16 @@ export default {
14741474
'按 Tab 或输入 /approval-mode 可快速切换权限模式。',
14751475
'Try /insight to generate personalized insights from your chat history.':
14761476
'试试 /insight,从聊天记录中生成个性化洞察。',
1477+
'Add a QWEN.md file to give Qwen Code persistent project context.':
1478+
'添加 QWEN.md 文件,为 Qwen Code 提供持久的项目上下文。',
1479+
'Use /btw to ask a quick side question without disrupting the conversation.':
1480+
'用 /btw 快速问一个小问题,不会打断当前对话。',
1481+
'Context is almost full! Run /compress now or start /new to continue.':
1482+
'上下文即将用满!请立即执行 /compress 或使用 /new 开启新会话。',
1483+
'Context is getting full. Use /compress to free up space.':
1484+
'上下文空间不足,用 /compress 释放空间。',
1485+
'Long conversation? /compress summarizes history to free context.':
1486+
'对话太长?用 /compress 总结历史,释放上下文。',
14771487

14781488
// ============================================================================
14791489
// Exit Screen / Stats
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @license
3+
* Copyright 2025 Google LLC
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import { TipHistory } from './tipHistory.js';
8+
9+
export { TipHistory } from './tipHistory.js';
10+
export { selectTip } from './tipScheduler.js';
11+
export {
12+
tipRegistry,
13+
getContextUsagePercent,
14+
type ContextualTip,
15+
type TipContext,
16+
type TipTrigger,
17+
} from './tipRegistry.js';
18+
19+
/**
20+
* Shared TipHistory singleton for the session. Loaded once on first access
21+
* so both startup tips and post-response tips share the same state.
22+
*/
23+
let _tipHistory: TipHistory | null = null;
24+
export function getTipHistory(): TipHistory {
25+
if (!_tipHistory) {
26+
_tipHistory = TipHistory.load();
27+
}
28+
return _tipHistory;
29+
}

0 commit comments

Comments
 (0)