mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-07-09 17:19:02 +00:00
Revert "fix(core): skip auto-title generation when history has no user messag…" (#5200)
This reverts commit 99d4c1246e.
This commit is contained in:
parent
05d17cfd5a
commit
e5655b4bd7
3 changed files with 0 additions and 108 deletions
|
|
@ -549,61 +549,4 @@ describe('ChatRecordingService - auto-title trigger', () => {
|
|||
expect(chatRecordingService.getCurrentCustomTitle()).toBe('user-chosen');
|
||||
expect(chatRecordingService.getCurrentTitleSource()).toBe('manual');
|
||||
});
|
||||
|
||||
it('skips title generation when history has no user message', async () => {
|
||||
/**
|
||||
* This test verifies that auto-title is not triggered when the history
|
||||
* contains only model messages (e.g., initialization context) without
|
||||
* any user message. This prevents titles like "初始化项目上下文" when
|
||||
* the user hasn't sent any message yet.
|
||||
*/
|
||||
|
||||
// Simulate tryGenerateSessionTitle returning empty_history because
|
||||
// the history only has model messages (initialization context)
|
||||
tryGenerateSessionTitleMock.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
reason: 'empty_history',
|
||||
});
|
||||
|
||||
// Simulate the first assistant turn completing with initialization context
|
||||
chatRecordingService.recordAssistantTurn({
|
||||
model: 'qwen-plus',
|
||||
message: [{ text: '已加载项目上下文,准备就绪。' }],
|
||||
});
|
||||
|
||||
await flushMicrotasks();
|
||||
|
||||
// Verify: the mock was called and returned empty_history
|
||||
expect(tryGenerateSessionTitleMock).toHaveBeenCalledOnce();
|
||||
// Verify: NO title was generated because history had no user message
|
||||
const titleRecord = findCustomTitleRecord();
|
||||
expect(titleRecord).toBeUndefined();
|
||||
expect(chatRecordingService.getCurrentCustomTitle()).toBeUndefined();
|
||||
|
||||
// Now simulate user sends "你好" and gets a response
|
||||
vi.mocked(jsonl.writeLine).mockClear();
|
||||
tryGenerateSessionTitleMock.mockClear();
|
||||
|
||||
// This time, tryGenerateSessionTitle succeeds because history now has user message
|
||||
tryGenerateSessionTitleMock.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
title: '问候会话',
|
||||
modelUsed: 'qwen-turbo',
|
||||
});
|
||||
|
||||
chatRecordingService.recordAssistantTurn({
|
||||
model: 'qwen-plus',
|
||||
message: [{ text: '你好!有什么可以帮助你的?' }],
|
||||
});
|
||||
|
||||
await flushMicrotasks();
|
||||
|
||||
// Now the title should be generated based on the actual conversation
|
||||
const newTitleRecord = findCustomTitleRecord();
|
||||
expect(newTitleRecord).toBeDefined();
|
||||
expect(
|
||||
(newTitleRecord?.systemPayload as { customTitle?: string })?.customTitle,
|
||||
).toBe('问候会话');
|
||||
expect(chatRecordingService.getCurrentCustomTitle()).toBe('问候会话');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -75,39 +75,6 @@ describe('tryGenerateSessionTitle', () => {
|
|||
expect(outcome).toEqual({ ok: false, reason: 'empty_history' });
|
||||
});
|
||||
|
||||
it('returns {ok:false, reason:"empty_history"} when history has only startup prelude (no real user message)', async () => {
|
||||
// Guard: auto-title should not be generated based solely on the
|
||||
// initialization prelude — a role:'user' <system-reminder> message
|
||||
// seeded by getInitialChatHistory. Without the guard, the title model
|
||||
// would be called with only the startup context and produce a title
|
||||
// like "初始化项目上下文" instead of one based on the user's actual
|
||||
// first message.
|
||||
const { config, generateJson } = makeConfig({
|
||||
fastModel: 'qwen-turbo',
|
||||
history: [
|
||||
{
|
||||
role: 'user',
|
||||
parts: [
|
||||
{
|
||||
text: "<system-reminder>\nThis is the Qwen Code. We are setting up the context for our chat.\nToday's date is Monday, June 15, 2026.\nMy operating system is: linux\nI'm currently working in the directory: /home/me/project\n</system-reminder>",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
role: 'model',
|
||||
parts: [{ text: 'Got it! How can I help you today?' }],
|
||||
},
|
||||
],
|
||||
});
|
||||
const outcome = await tryGenerateSessionTitle(
|
||||
config,
|
||||
new AbortController().signal,
|
||||
);
|
||||
expect(outcome).toEqual({ ok: false, reason: 'empty_history' });
|
||||
// The title model must NOT be called — the guard should short-circuit.
|
||||
expect(generateJson).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('returns {ok:false, reason:"model_error"} when the LLM throws', async () => {
|
||||
const { config } = makeConfig({
|
||||
fastModel: 'qwen-turbo',
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
import type { Content } from '@google/genai';
|
||||
import type { Config } from '../config/config.js';
|
||||
import { createDebugLogger } from '../utils/debugLogger.js';
|
||||
import { isSystemReminderContent } from '../utils/environmentContext.js';
|
||||
import { runSideQuery } from '../utils/sideQuery.js';
|
||||
import { stripTerminalControlSequences } from '../utils/terminalSafe.js';
|
||||
import { SESSION_TITLE_MAX_LENGTH } from './sessionService.js';
|
||||
|
|
@ -117,23 +116,6 @@ export async function tryGenerateSessionTitle(
|
|||
const fullHistory = geminiClient.getHistoryShallow();
|
||||
if (fullHistory.length < 2) return { ok: false, reason: 'empty_history' };
|
||||
|
||||
// Guard: skip title generation if no real user message exists in history.
|
||||
// This prevents the title from being generated based solely on
|
||||
// initialization context (e.g., workspace loading, system prompts)
|
||||
// before the user has actually said anything. Without this guard, a
|
||||
// session that sends a prompt immediately after creation could get a
|
||||
// title like "初始化项目上下文" instead of one based on the user's
|
||||
// actual message.
|
||||
//
|
||||
// The startup prelude is a role:'user' message wrapping
|
||||
// <system-reminder> content (see getInitialChatHistory), so we must
|
||||
// exclude it via isSystemReminderContent to avoid misclassifying it
|
||||
// as a real user turn.
|
||||
const hasUserMessage = fullHistory.some(
|
||||
(msg) => msg.role === 'user' && !isSystemReminderContent(msg),
|
||||
);
|
||||
if (!hasUserMessage) return { ok: false, reason: 'empty_history' };
|
||||
|
||||
const dialog = filterToDialog(fullHistory);
|
||||
const recentHistory = takeRecentDialog(dialog, RECENT_MESSAGE_WINDOW);
|
||||
if (recentHistory.length === 0) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue