Files
clawpanel/tests/hermes-display-config.test.js
2026-05-27 06:59:16 +08:00

279 lines
10 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import {
buildHermesDisplayConfigValues,
mergeHermesDisplayConfig,
} from '../scripts/dev-api.js'
test('Hermes 显示配置读取会提供上游默认值', () => {
const values = buildHermesDisplayConfigValues({})
assert.deepEqual(values, {
displayToolProgress: 'all',
displayCompact: false,
displaySkin: 'default',
displayToolPrefix: '┊',
displayShowReasoning: false,
displayToolPreviewLength: 0,
displayCleanupProgress: false,
displayToolProgressCommand: false,
displayInterimAssistantMessages: true,
displayRuntimeFooterEnabled: false,
displayRuntimeFooterFields: 'model\ncontext_pct\ncwd',
displayFileMutationVerifier: true,
displayShowCost: false,
dashboardShowTokenAnalytics: false,
displayLanguage: 'en',
displayResumeDisplay: 'full',
displayBusyInputMode: 'interrupt',
displayBackgroundProcessNotifications: 'all',
displayFinalResponseMarkdown: 'strip',
displayTimestamps: false,
displayBellOnComplete: false,
displayPersistentOutput: true,
displayPersistentOutputMaxLines: 200,
displayInlineDiffs: true,
displayTuiAutoResumeRecent: false,
displayTuiStatusIndicator: 'kaomoji',
displayUserMessagePreviewFirstLines: 2,
displayUserMessagePreviewLastLines: 2,
displayEphemeralSystemTtl: 0,
displayCopyShortcut: 'auto',
})
})
test('Hermes 显示配置读取会规范化已有字段', () => {
const values = buildHermesDisplayConfigValues({
display: {
tool_progress: 'VERBOSE',
compact: true,
skin: 'MONO',
tool_prefix: '╎',
show_reasoning: true,
tool_preview_length: 80,
cleanup_progress: true,
tool_progress_command: true,
interim_assistant_messages: false,
runtime_footer: {
enabled: true,
fields: ['model', 'duration', 'cost'],
},
file_mutation_verifier: false,
show_cost: true,
language: 'ZH',
resume_display: 'minimal',
busy_input_mode: 'QUEUE',
background_process_notifications: 'ERROR',
final_response_markdown: 'RAW',
timestamps: true,
bell_on_complete: true,
persistent_output: false,
persistent_output_max_lines: 80,
inline_diffs: false,
tui_auto_resume_recent: true,
tui_status_indicator: 'EMOJI',
user_message_preview: {
first_lines: 3,
last_lines: 1,
},
ephemeral_system_ttl: 120,
copy_shortcut: 'CTRL_SHIFT_C',
},
dashboard: {
show_token_analytics: true,
},
})
assert.equal(values.displayToolProgress, 'verbose')
assert.equal(values.displayCompact, true)
assert.equal(values.displaySkin, 'mono')
assert.equal(values.displayToolPrefix, '╎')
assert.equal(values.displayShowReasoning, true)
assert.equal(values.displayToolPreviewLength, 80)
assert.equal(values.displayCleanupProgress, true)
assert.equal(values.displayToolProgressCommand, true)
assert.equal(values.displayInterimAssistantMessages, false)
assert.equal(values.displayRuntimeFooterEnabled, true)
assert.equal(values.displayRuntimeFooterFields, 'model\nduration\ncost')
assert.equal(values.displayFileMutationVerifier, false)
assert.equal(values.displayShowCost, true)
assert.equal(values.dashboardShowTokenAnalytics, true)
assert.equal(values.displayLanguage, 'zh')
assert.equal(values.displayResumeDisplay, 'minimal')
assert.equal(values.displayBusyInputMode, 'queue')
assert.equal(values.displayBackgroundProcessNotifications, 'error')
assert.equal(values.displayFinalResponseMarkdown, 'raw')
assert.equal(values.displayTimestamps, true)
assert.equal(values.displayBellOnComplete, true)
assert.equal(values.displayPersistentOutput, false)
assert.equal(values.displayPersistentOutputMaxLines, 80)
assert.equal(values.displayInlineDiffs, false)
assert.equal(values.displayTuiAutoResumeRecent, true)
assert.equal(values.displayTuiStatusIndicator, 'emoji')
assert.equal(values.displayUserMessagePreviewFirstLines, 3)
assert.equal(values.displayUserMessagePreviewLastLines, 1)
assert.equal(values.displayEphemeralSystemTtl, 120)
assert.equal(values.displayCopyShortcut, 'ctrl_shift_c')
})
test('Hermes 显示配置保存会保留未知 YAML 并写入 display', () => {
const next = mergeHermesDisplayConfig({
model: { provider: 'anthropic' },
display: {
skin: 'midnight',
runtime_footer: {
enabled: false,
custom_flag: 'keep-footer',
},
user_message_preview: {
custom_flag: 'keep-preview',
},
platforms: {
telegram: { tool_progress: 'new' },
},
custom_flag: 'keep-display',
},
dashboard: {
custom_flag: 'keep-dashboard',
},
memory: { memory_enabled: true },
}, {
displayToolProgress: 'off',
displayCompact: true,
displaySkin: 'slate',
displayToolPrefix: '│',
displayShowReasoning: true,
displayToolPreviewLength: 120,
displayCleanupProgress: true,
displayToolProgressCommand: 'true',
displayInterimAssistantMessages: false,
displayRuntimeFooterEnabled: true,
displayRuntimeFooterFields: 'model\ncontext_pct\nduration',
displayFileMutationVerifier: true,
displayShowCost: true,
dashboardShowTokenAnalytics: true,
displayLanguage: 'zh-hant',
displayResumeDisplay: 'minimal',
displayBusyInputMode: 'steer',
displayBackgroundProcessNotifications: 'result',
displayFinalResponseMarkdown: 'render',
displayTimestamps: true,
displayBellOnComplete: true,
displayPersistentOutput: false,
displayPersistentOutputMaxLines: 120,
displayInlineDiffs: false,
displayTuiAutoResumeRecent: true,
displayTuiStatusIndicator: 'ascii',
displayUserMessagePreviewFirstLines: 4,
displayUserMessagePreviewLastLines: 0,
displayEphemeralSystemTtl: 360,
displayCopyShortcut: 'disabled',
})
assert.deepEqual(next.model, { provider: 'anthropic' })
assert.deepEqual(next.memory, { memory_enabled: true })
assert.equal(next.dashboard.custom_flag, 'keep-dashboard')
assert.equal(next.dashboard.show_token_analytics, true)
assert.equal(next.display.compact, true)
assert.equal(next.display.skin, 'slate')
assert.equal(next.display.tool_prefix, '│')
assert.equal(next.display.show_reasoning, true)
assert.equal(next.display.tool_preview_length, 120)
assert.equal(next.display.cleanup_progress, true)
assert.deepEqual(next.display.platforms.telegram, { tool_progress: 'new' })
assert.equal(next.display.tool_progress, 'off')
assert.equal(next.display.tool_progress_command, true)
assert.equal(next.display.interim_assistant_messages, false)
assert.equal(next.display.runtime_footer.enabled, true)
assert.deepEqual(next.display.runtime_footer.fields, ['model', 'context_pct', 'duration'])
assert.equal(next.display.runtime_footer.custom_flag, 'keep-footer')
assert.equal(next.display.file_mutation_verifier, true)
assert.equal(next.display.show_cost, true)
assert.equal(next.display.language, 'zh-hant')
assert.equal(next.display.resume_display, 'minimal')
assert.equal(next.display.busy_input_mode, 'steer')
assert.equal(next.display.background_process_notifications, 'result')
assert.equal(next.display.final_response_markdown, 'render')
assert.equal(next.display.timestamps, true)
assert.equal(next.display.bell_on_complete, true)
assert.equal(next.display.persistent_output, false)
assert.equal(next.display.persistent_output_max_lines, 120)
assert.equal(next.display.inline_diffs, false)
assert.equal(next.display.tui_auto_resume_recent, true)
assert.equal(next.display.tui_status_indicator, 'ascii')
assert.equal(next.display.user_message_preview.first_lines, 4)
assert.equal(next.display.user_message_preview.last_lines, 0)
assert.equal(next.display.user_message_preview.custom_flag, 'keep-preview')
assert.equal(next.display.ephemeral_system_ttl, 360)
assert.equal(next.display.copy_shortcut, 'disabled')
assert.equal(next.display.custom_flag, 'keep-display')
})
test('Hermes 显示配置保存会拒绝非法枚举和页脚字段', () => {
assert.throws(
() => mergeHermesDisplayConfig({}, { displayToolProgress: 'everything' }),
/display\.tool_progress/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displaySkin: 'unknown' }),
/display\.skin/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayToolPrefix: 'too-long-prefix' }),
/display\.tool_prefix/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayResumeDisplay: 'compact' }),
/display\.resume_display/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayLanguage: 'cn' }),
/display\.language/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayRuntimeFooterFields: 'model\npassword' }),
/display\.runtime_footer\.fields/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayBusyInputMode: 'replace' }),
/display\.busy_input_mode/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayBackgroundProcessNotifications: 'silent' }),
/display\.background_process_notifications/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayFinalResponseMarkdown: 'html' }),
/display\.final_response_markdown/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayPersistentOutputMaxLines: '-1' }),
/display\.persistent_output_max_lines/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayToolPreviewLength: '200001' }),
/display\.tool_preview_length/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayTuiStatusIndicator: 'rainbow' }),
/display\.tui_status_indicator/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayCopyShortcut: 'cmd_c' }),
/display\.copy_shortcut/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayUserMessagePreviewFirstLines: '0' }),
/display\.user_message_preview\.first_lines/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayUserMessagePreviewLastLines: '101' }),
/display\.user_message_preview\.last_lines/,
)
assert.throws(
() => mergeHermesDisplayConfig({}, { displayEphemeralSystemTtl: '86401' }),
/display\.ephemeral_system_ttl/,
)
})