From b066690f7057e77fae35a3fc5efcbcf8aef56f8a Mon Sep 17 00:00:00 2001 From: imccyu Date: Fri, 25 Sep 2026 12:45:45 +0800 Subject: [PATCH] fix(web): default fresh work details to detailed --- .../settings-chrome/dialog-en.expected.md | 2 +- .../dialog-no-browser.expected.md | 2 +- .../settings-chrome/dialog.expected.md | 2 +- apps/web/tests/settings-chrome.e2e.ts | 17 ++++--- apps/web/tests/turn-tail-actions.e2e.ts | 4 +- packages/bundle/web-app/cordis.patch.yml | 2 + .../web-app/tests/chat-defaults.spec.ts | 51 +++++++++++++++++++ .../conversation-nodes/README.i18n.yaml | 4 +- .../src/client/conversation-nodes/README.md | 2 +- .../client/conversation-nodes/README.zh.md | 2 +- .../web/turn-tail-actions/running.expected.md | 4 +- 11 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 packages/bundle/web-app/tests/chat-defaults.spec.ts diff --git a/apps/web/tests/expected/settings-chrome/dialog-en.expected.md b/apps/web/tests/expected/settings-chrome/dialog-en.expected.md index e4ebda98ac..a31abbd9a6 100644 --- a/apps/web/tests/expected/settings-chrome/dialog-en.expected.md +++ b/apps/web/tests/expected/settings-chrome/dialog-en.expected.md @@ -19,7 +19,7 @@ - button "Increase font size" - button "Decrease font size" - text: px Work details Choose how much detail to show for tool calls - - button "Standard" + - button "Detailed" - text: Performance & usage Choose how much performance and usage information to show - button "Detailed" - text: Coding Tools Shows trajectory, code diffs, and Agent preset switching in new chats diff --git a/apps/web/tests/expected/settings-chrome/dialog-no-browser.expected.md b/apps/web/tests/expected/settings-chrome/dialog-no-browser.expected.md index e4ebda98ac..a31abbd9a6 100644 --- a/apps/web/tests/expected/settings-chrome/dialog-no-browser.expected.md +++ b/apps/web/tests/expected/settings-chrome/dialog-no-browser.expected.md @@ -19,7 +19,7 @@ - button "Increase font size" - button "Decrease font size" - text: px Work details Choose how much detail to show for tool calls - - button "Standard" + - button "Detailed" - text: Performance & usage Choose how much performance and usage information to show - button "Detailed" - text: Coding Tools Shows trajectory, code diffs, and Agent preset switching in new chats diff --git a/apps/web/tests/expected/settings-chrome/dialog.expected.md b/apps/web/tests/expected/settings-chrome/dialog.expected.md index 40d4ecf3d7..75c367d690 100644 --- a/apps/web/tests/expected/settings-chrome/dialog.expected.md +++ b/apps/web/tests/expected/settings-chrome/dialog.expected.md @@ -19,7 +19,7 @@ - button "增大字号" - button "减小字号" - text: px 工作步骤展示 选择希望看到多少工具调用细节 - - button "标准" + - button "详细" - text: 性能与用量 选择性能与用量信息展示的详细程度 - button "详细" - text: 代码工作工具 开启后显示轨迹、本轮代码差异,新对话中的 Agent 预设切换 diff --git a/apps/web/tests/settings-chrome.e2e.ts b/apps/web/tests/settings-chrome.e2e.ts index 54b5e5f6f8..705098e2d4 100644 --- a/apps/web/tests/settings-chrome.e2e.ts +++ b/apps/web/tests/settings-chrome.e2e.ts @@ -71,6 +71,10 @@ describe('web e2e: settings modal and General preferences', () => { await dialog.getByRole('button', { name: '工作区内修改' }).waitFor({ timeout: 10_000 }) await expect.poll(() => dialog.getByText('语言', { exact: true }).count(), { timeout: 5_000 }).toBe(1) await expect.poll(() => dialog.getByText('外观', { exact: true }).count(), { timeout: 5_000 }).toBe(1) + await dialog.getByText('工作步骤展示', { exact: true }).locator('../..') + .getByRole('button', { name: '详细', exact: true }).waitFor({ timeout: 10_000 }) + expect(await readFile(join(scaffold.harnessHome, 'profiles', 'scaffold', 'cordis.patch.yml'), 'utf8')) + .not.toContain('transcriptView:') const openDocument = dialog.getByRole('button', { name: '打开配置文件' }) await openDocument.waitFor({ timeout: 10_000 }) let openRequests = 0 @@ -569,7 +573,7 @@ describe('web e2e: settings modal and General preferences', () => { }, 90_000) it.each([ - ['compact', '简洁'], ['detailed', '详细'], ['verbose', '完全展开'], + ['compact', '简洁'], ['standard', '标准'], ['verbose', '完全展开'], ] as const)('persists the %s work-details mode across reload', async (mode, label) => { onTestFailed(() => saveFailureShot(page, 'web-e2e-settings-transcript-view')) await openSettings(page, 'zh') @@ -577,7 +581,7 @@ describe('web e2e: settings modal and General preferences', () => { await dialog.waitFor({ timeout: 10_000 }) await dialog.getByText('工作步骤展示', { exact: true }).waitFor({ timeout: 10_000 }) const details = dialog.getByText('工作步骤展示', { exact: true }).locator('../..') - await details.getByRole('button', { name: '标准', exact: true }).click() + await details.getByRole('button', { name: '详细', exact: true }).click() await page.getByRole('menuitem', { name: label, exact: true }).click() await details.getByRole('button', { name: label, exact: true }).waitFor({ timeout: 10_000 }) await expect.poll(async () => readFile(join(scaffold.harnessHome, 'profiles', 'scaffold', 'cordis.patch.yml'), 'utf8'), { timeout: 5_000 }) @@ -594,10 +598,10 @@ describe('web e2e: settings modal and General preferences', () => { await restoredDetails.getByRole('button', { name: label, exact: true }).waitFor({ timeout: 10_000 }) await restoredDetails.getByRole('button', { name: label, exact: true }).click() - await page.getByRole('menuitem', { name: '标准', exact: true }).click() - await restoredDetails.getByRole('button', { name: '标准', exact: true }).waitFor({ timeout: 10_000 }) + await page.getByRole('menuitem', { name: '详细', exact: true }).click() + await restoredDetails.getByRole('button', { name: '详细', exact: true }).waitFor({ timeout: 10_000 }) await expect.poll(async () => readFile(join(scaffold.harnessHome, 'profiles', 'scaffold', 'cordis.patch.yml'), 'utf8'), { timeout: 5_000 }) - .toContain('transcriptView: standard') + .toContain('transcriptView: detailed') await page.keyboard.press('Escape') expect(tripwire.pageErrors).toEqual([]) }, 90_000) @@ -807,7 +811,8 @@ describe('web e2e: settings modal and General preferences', () => { await withoutBrowser.goto(fresh.authenticatedUrl, { waitUntil: 'load' }) await openSettings(withoutBrowser, 'en') const dialog = withoutBrowser.getByRole('dialog', { name: 'Settings' }) - await dialog.getByRole('button', { name: 'Detailed', exact: true }).waitFor() + await dialog.getByText('Work details', { exact: true }).locator('../..') + .getByRole('button', { name: 'Detailed', exact: true }).waitFor() expect(await dialog.getByText('Open chat links in', { exact: true }).count()).toBe(0) const snapshot = await captureStableAria(withoutBrowser, '[role="dialog"]', fresh.workspaceCwd, versionCapture) await compareOrRefreshGolden(join(SNAPSHOT_DIR, 'dialog-no-browser.expected.md'), snapshot, MODE) diff --git a/apps/web/tests/turn-tail-actions.e2e.ts b/apps/web/tests/turn-tail-actions.e2e.ts index e00c958e26..d808a2fb34 100644 --- a/apps/web/tests/turn-tail-actions.e2e.ts +++ b/apps/web/tests/turn-tail-actions.e2e.ts @@ -244,7 +244,7 @@ describe('web e2e: assistant IconActions wait for the turn to end', () => { }, 60_000) it.skipIf(MODE === 'record').each([ - ['compact', 'Compact'], ['detailed', 'Detailed'], ['verbose', 'Verbose'], + ['compact', 'Compact'], ['standard', 'Standard'], ['verbose', 'Verbose'], ] as const)('applies whole-Turn presentation in %s mode', async (mode, label) => { await launch() onTestFailed(() => saveFailureShot(page, 'web-e2e-turn-process-setting')) @@ -259,7 +259,7 @@ describe('web e2e: assistant IconActions wait for the turn to end', () => { await openSettings(page, 'en') const dialog = page.getByRole('dialog', { name: 'Settings' }) await dialog.getByText('Work details', { exact: true }).locator('../..') - .getByRole('button', { name: 'Standard', exact: true }).click() + .getByRole('button', { name: 'Detailed', exact: true }).click() await page.getByRole('menuitem', { name: label, exact: true }).click() await page.keyboard.press('Escape') diff --git a/packages/bundle/web-app/cordis.patch.yml b/packages/bundle/web-app/cordis.patch.yml index 0659d73674..89266007c0 100644 --- a/packages/bundle/web-app/cordis.patch.yml +++ b/packages/bundle/web-app/cordis.patch.yml @@ -312,6 +312,8 @@ - id: ui-chat name: '@deepseek-ai/dsh-client-ui-chat' + config: + transcriptView: !!js "ctx.get('profileContext')?.name === 'desktop' ? 'standard' : 'detailed'" # Official occupants for the generic sidebar and conversation brand slots. - id: ui-brand-official diff --git a/packages/bundle/web-app/tests/chat-defaults.spec.ts b/packages/bundle/web-app/tests/chat-defaults.spec.ts new file mode 100644 index 0000000000..1c7458f878 --- /dev/null +++ b/packages/bundle/web-app/tests/chat-defaults.spec.ts @@ -0,0 +1,51 @@ +/** Profile work-details defaults and saved Chat overrides through the shipped Loader row. */ +import { fileURLToPath } from 'node:url' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import { applyEntryPatches, type PatchOptions } from '@deepseek-ai/cordis-plugin-include' +import { loadOverlayPatches } from '@deepseek-ai/dsh-app-boot' +import * as Chat from '@deepseek-ai/dsh-client-ui-chat' +import { expect, it, onTestFinished } from 'vitest' +import { plainConfig } from '../../../settings/settings/src/schema.ts' + +async function loadChat(profile: string | undefined, overrides: PatchOptions[] = []) { + const rows = loadOverlayPatches('chat-defaults', fileURLToPath(new URL('../cordis.patch.yml', import.meta.url))) + .flatMap(patch => patch.insert ?? []).filter(row => row.id === 'ui-chat') + expect(rows).toHaveLength(1) + expect(rows[0]!.name).toBe('@deepseek-ai/dsh-client-ui-chat') + const configured = applyEntryPatches(rows, overrides, (message) => { throw new Error(message) }) + const ctx = new Context() + onTestFinished(() => ctx.fiber.dispose()) + if (profile !== undefined) { + ctx.provide('profileContext', { + name: profile, dir: '/profile', patchPath: '/profile/cordis.patch.yml', installAnchor: '/profile/package.json', + cwd: '/workspace', home: '/home', startedBundles: [], overlays: [], telemetryDisabledEnv: undefined, + }) + } + ctx.baseUrl = 'file:///' + await ctx.plugin(Loader).await() + ctx.loader.builtins.chat = Chat + await ctx.loader.root.update([{ ...configured[0]!, name: 'cordis:chat' }]) + await ctx.loader.await() + return plainConfig(ctx.loader.resolve('ui-chat').fiber!.config) +} + +it.each([ + { profile: 'web', expected: 'detailed' }, + { profile: 'custom-web', expected: 'detailed' }, + { profile: undefined, expected: 'detailed' }, + { profile: 'desktop', expected: 'standard' }, +])('starts fresh $profile Chat settings in $expected', async ({ profile, expected }) => { + expect(await loadChat(profile)).toMatchObject({ + transcriptView: expected, performanceUsage: 'detailed', linkOpening: 'sidebar', + }) +}) + +it.each(['compact', 'standard', 'detailed', 'verbose', 'normal', 'expanded'])( + 'preserves the saved %s mode over Web and Desktop defaults', async (mode) => { + for (const profile of ['web', 'desktop']) { + expect(await loadChat(profile, [{ id: 'ui-chat', config: { transcriptView: mode } }])) + .toMatchObject({ transcriptView: mode }) + } + }, +) diff --git a/packages/client/ui-chat/src/client/conversation-nodes/README.i18n.yaml b/packages/client/ui-chat/src/client/conversation-nodes/README.i18n.yaml index 9ef9c65e93..6f59513c85 100644 --- a/packages/client/ui-chat/src/client/conversation-nodes/README.i18n.yaml +++ b/packages/client/ui-chat/src/client/conversation-nodes/README.i18n.yaml @@ -27,8 +27,8 @@ en: 8db4991626210708 zh: e18c8aa3cb434980 /chat-conversation-node-rules/display-modes: - en: b67a97af6578be4e - zh: 45511f59d45746fe + en: 34d9716168b411bc + zh: cfe3fef7af7f8d71 /chat-conversation-node-rules/display-modes/group-title-rules: en: a6d29a5ea3fd2362 zh: dbd07bf82cdd61b1 diff --git a/packages/client/ui-chat/src/client/conversation-nodes/README.md b/packages/client/ui-chat/src/client/conversation-nodes/README.md index d75b5b20e7..8dc2dc410f 100644 --- a/packages/client/ui-chat/src/client/conversation-nodes/README.md +++ b/packages/client/ui-chat/src/client/conversation-nodes/README.md @@ -108,7 +108,7 @@ Automatic collapse keeps the process open if hiding it would hide keyboard focus ## Display modes -Settings → General → Work details offers `compact`, `standard` (default), `detailed`, and `verbose`; its description is “Choose how much detail to show for tool calls”. Saved `normal` and `expanded` values read as `detailed`, without automatic write-back. Existing `detailed` remains `detailed`. Missing or invalid values, including the period before Host settings arrive, use `standard`; invalid values in other settings still fail validation. +Settings → General → Work details offers `compact`, `standard`, `detailed` (the default for fresh non-Desktop Web profiles), and `verbose`; its description is “Choose how much detail to show for tool calls”. Saved `normal` and `expanded` values read as `detailed`, without automatic write-back. Existing `detailed` remains `detailed`. Missing or invalid values, including the period before Host settings arrive, use `standard`; invalid values in other settings still fail validation. | Behavior | Compact | Standard | Detailed | Verbose | |---|---|---|---|---| diff --git a/packages/client/ui-chat/src/client/conversation-nodes/README.zh.md b/packages/client/ui-chat/src/client/conversation-nodes/README.zh.md index 9925f4b449..350ab61859 100644 --- a/packages/client/ui-chat/src/client/conversation-nodes/README.zh.md +++ b/packages/client/ui-chat/src/client/conversation-nodes/README.zh.md @@ -108,7 +108,7 @@ description: "Chat 过程分组与活动摘要的明细业务规则。" ## 展示模式 -设置 → 通用设置 → 工作步骤展示提供 `compact`、`standard`(默认)、`detailed` 和 `verbose`,说明为「选择希望看到多少工具调用细节」。旧值 `normal` 和 `expanded` 均读取为 `detailed`,不自动回写;已有 `detailed` 保持不变。未配置、无效值以及 Host 设置到达前均使用 `standard`;其他设置的无效值仍会校验失败。 +设置 → 通用设置 → 工作步骤展示提供 `compact`、`standard`、`detailed`(非 Desktop Web 全新配置的默认值)和 `verbose`,说明为「选择希望看到多少工具调用细节」。旧值 `normal` 和 `expanded` 均读取为 `detailed`,不自动回写;已有 `detailed` 保持不变。未配置、无效值以及 Host 设置到达前均使用 `standard`;其他设置的无效值仍会校验失败。 | 行为 | 简洁 | 标准 | 详细 | 完全展开 | |---|---|---|---|---| diff --git a/snapshots/web/turn-tail-actions/running.expected.md b/snapshots/web/turn-tail-actions/running.expected.md index 8a9f36aee9..05ccf0d37b 100644 --- a/snapshots/web/turn-tail-actions/running.expected.md +++ b/snapshots/web/turn-tail-actions/running.expected.md @@ -11,9 +11,9 @@ - tooltip "Copy" - status: Deep diving... - button "Deep diving for {{duration}}" [disabled] [expanded] -- button "Analysis completed" +- button "Think The user wants me to begin with \"Reading the workspace now.\" and call bash with \"echo alpha\" in the same message. Then after the tool result, reply with the single word DONE and stop." - paragraph: Reading the workspace now. -- button "Ran commands" +- button "Bash Print alpha to stdout" - paragraph: partial - textbox "Message or run a task, / commands, @ files or sessions" - button "Add files or run commands"