mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-05-29 04:10:00 +08:00
feat(hermes): add display skin config
This commit is contained in:
@@ -3345,6 +3345,7 @@ const HERMES_DISPLAY_BUSY_INPUT_MODES = new Set(['interrupt', 'queue', 'steer'])
|
||||
const HERMES_DISPLAY_BACKGROUND_PROCESS_NOTIFICATIONS = new Set(['off', 'result', 'error', 'all'])
|
||||
const HERMES_DISPLAY_FINAL_RESPONSE_MARKDOWN_VALUES = new Set(['render', 'strip', 'raw'])
|
||||
const HERMES_DISPLAY_LANGUAGE_VALUES = new Set(['en', 'zh', 'zh-hant', 'ja', 'de', 'es', 'fr', 'tr', 'uk', 'af', 'ko', 'it', 'ga', 'pt', 'ru', 'hu'])
|
||||
const HERMES_DISPLAY_SKINS = new Set(['default', 'ares', 'mono', 'slate', 'daylight', 'warm-lightmode', 'poseidon', 'sisyphus', 'charizard'])
|
||||
const HERMES_RUNTIME_FOOTER_FIELDS = new Set(['model', 'context_pct', 'cwd', 'duration', 'tokens', 'cost'])
|
||||
const HERMES_HOOK_EVENTS = new Set([
|
||||
'pre_tool_call',
|
||||
@@ -3624,6 +3625,13 @@ function normalizeHermesDisplayLanguage(value, strict = false) {
|
||||
return 'en'
|
||||
}
|
||||
|
||||
function normalizeHermesDisplaySkin(value, strict = false) {
|
||||
const skin = String(value ?? '').trim().toLowerCase() || 'default'
|
||||
if (HERMES_DISPLAY_SKINS.has(skin)) return skin
|
||||
if (strict) throw new Error('display.skin 必须是内置皮肤 default、ares、mono、slate、daylight、warm-lightmode、poseidon、sisyphus 或 charizard')
|
||||
return 'default'
|
||||
}
|
||||
|
||||
function normalizeHermesRuntimeFooterFields(value, strict = false) {
|
||||
const items = Array.isArray(value)
|
||||
? value
|
||||
@@ -3660,6 +3668,8 @@ export function buildHermesDisplayConfigValues(config = {}) {
|
||||
? display.runtime_footer
|
||||
: {}
|
||||
return {
|
||||
displayCompact: readHermesBool(display.compact, false),
|
||||
displaySkin: normalizeHermesDisplaySkin(display.skin, false),
|
||||
displayToolProgress: normalizeHermesDisplayToolProgress(display.tool_progress, false),
|
||||
displayToolProgressCommand: readHermesBool(display.tool_progress_command, false),
|
||||
displayInterimAssistantMessages: readHermesBool(display.interim_assistant_messages, true),
|
||||
@@ -3688,6 +3698,8 @@ export function mergeHermesDisplayConfig(config = {}, form = {}) {
|
||||
? mergeConfigsPreservingFields(display.runtime_footer, {})
|
||||
: {}
|
||||
|
||||
display.compact = formHermesBool(form, 'displayCompact', currentValues.displayCompact)
|
||||
display.skin = normalizeHermesDisplaySkin(Object.hasOwn(form, 'displaySkin') ? form.displaySkin : currentValues.displaySkin, true)
|
||||
display.tool_progress = normalizeHermesDisplayToolProgress(Object.hasOwn(form, 'displayToolProgress') ? form.displayToolProgress : currentValues.displayToolProgress, true, 'display.tool_progress')
|
||||
display.tool_progress_command = formHermesBool(form, 'displayToolProgressCommand', currentValues.displayToolProgressCommand)
|
||||
display.interim_assistant_messages = formHermesBool(form, 'displayInterimAssistantMessages', currentValues.displayInterimAssistantMessages)
|
||||
|
||||
@@ -5651,6 +5651,17 @@ const HERMES_DISPLAY_LANGUAGE_VALUES: &[&str] = &[
|
||||
const HERMES_DISPLAY_BUSY_INPUT_MODES: &[&str] = &["interrupt", "queue", "steer"];
|
||||
const HERMES_DISPLAY_BACKGROUND_PROCESS_NOTIFICATIONS: &[&str] = &["off", "result", "error", "all"];
|
||||
const HERMES_DISPLAY_FINAL_RESPONSE_MARKDOWN_VALUES: &[&str] = &["render", "strip", "raw"];
|
||||
const HERMES_DISPLAY_SKINS: &[&str] = &[
|
||||
"default",
|
||||
"ares",
|
||||
"mono",
|
||||
"slate",
|
||||
"daylight",
|
||||
"warm-lightmode",
|
||||
"poseidon",
|
||||
"sisyphus",
|
||||
"charizard",
|
||||
];
|
||||
|
||||
const HERMES_RUNTIME_FOOTER_FIELDS: &[&str] =
|
||||
&["model", "context_pct", "cwd", "duration", "tokens", "cost"];
|
||||
@@ -5674,6 +5685,22 @@ fn normalize_hermes_display_language(
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_hermes_display_skin(value: Option<String>, strict: bool) -> Result<String, String> {
|
||||
let skin = value.unwrap_or_default().trim().to_ascii_lowercase();
|
||||
let skin = if skin.is_empty() {
|
||||
"default".to_string()
|
||||
} else {
|
||||
skin
|
||||
};
|
||||
if HERMES_DISPLAY_SKINS.contains(&skin.as_str()) {
|
||||
Ok(skin)
|
||||
} else if strict {
|
||||
Err("display.skin 必须是内置皮肤 default、ares、mono、slate、daylight、warm-lightmode、poseidon、sisyphus 或 charizard".to_string())
|
||||
} else {
|
||||
Ok("default".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_hermes_display_resume(value: Option<String>, strict: bool) -> Result<String, String> {
|
||||
let mode = value.unwrap_or_default().trim().to_ascii_lowercase();
|
||||
let mode = if mode.is_empty() {
|
||||
@@ -5841,6 +5868,11 @@ fn build_hermes_display_config_values(config: &serde_yaml::Value) -> Value {
|
||||
});
|
||||
|
||||
serde_json::json!({
|
||||
"displayCompact": display.and_then(|map| yaml_bool_field(map, "compact")).unwrap_or(false),
|
||||
"displaySkin": normalize_hermes_display_skin(
|
||||
display.and_then(|map| yaml_string_field(map, "skin")),
|
||||
false,
|
||||
).unwrap_or_else(|_| "default".to_string()),
|
||||
"displayToolProgress": normalize_hermes_display_tool_progress(
|
||||
display.and_then(|map| yaml_string_field(map, "tool_progress")),
|
||||
false,
|
||||
@@ -5919,6 +5951,21 @@ fn merge_hermes_display_config(config: &mut serde_yaml::Value, form: &Value) ->
|
||||
)?;
|
||||
|
||||
let display = yaml_child_object(ensure_yaml_object(config)?, "display")?;
|
||||
display.insert(
|
||||
yaml_key("compact"),
|
||||
serde_yaml::Value::Bool(
|
||||
form_bool(form, "displayCompact")
|
||||
.unwrap_or_else(|| current["displayCompact"].as_bool().unwrap_or(false)),
|
||||
),
|
||||
);
|
||||
display.insert(
|
||||
yaml_key("skin"),
|
||||
serde_yaml::Value::String(normalize_hermes_display_skin(
|
||||
form_string(form, "displaySkin")
|
||||
.or_else(|| current["displaySkin"].as_str().map(ToString::to_string)),
|
||||
true,
|
||||
)?),
|
||||
);
|
||||
display.insert(
|
||||
yaml_key("tool_progress"),
|
||||
serde_yaml::Value::String(tool_progress),
|
||||
@@ -17785,6 +17832,8 @@ mod hermes_display_config_tests {
|
||||
let config: serde_yaml::Value = serde_yaml::from_str("{}").unwrap();
|
||||
let values = build_hermes_display_config_values(&config);
|
||||
assert_eq!(values["displayToolProgress"], "all");
|
||||
assert_eq!(values["displayCompact"], false);
|
||||
assert_eq!(values["displaySkin"], "default");
|
||||
assert_eq!(values["displayToolProgressCommand"], false);
|
||||
assert_eq!(values["displayInterimAssistantMessages"], true);
|
||||
assert_eq!(values["displayRuntimeFooterEnabled"], false);
|
||||
@@ -17810,6 +17859,8 @@ mod hermes_display_config_tests {
|
||||
r#"
|
||||
display:
|
||||
tool_progress: VERBOSE
|
||||
compact: true
|
||||
skin: MONO
|
||||
tool_progress_command: true
|
||||
interim_assistant_messages: false
|
||||
runtime_footer:
|
||||
@@ -17833,6 +17884,8 @@ display:
|
||||
.unwrap();
|
||||
let values = build_hermes_display_config_values(&config);
|
||||
assert_eq!(values["displayToolProgress"], "verbose");
|
||||
assert_eq!(values["displayCompact"], true);
|
||||
assert_eq!(values["displaySkin"], "mono");
|
||||
assert_eq!(values["displayToolProgressCommand"], true);
|
||||
assert_eq!(values["displayInterimAssistantMessages"], false);
|
||||
assert_eq!(values["displayRuntimeFooterEnabled"], true);
|
||||
@@ -17876,6 +17929,8 @@ memory:
|
||||
&mut config,
|
||||
&json!({
|
||||
"displayToolProgress": "off",
|
||||
"displayCompact": true,
|
||||
"displaySkin": "slate",
|
||||
"displayToolProgressCommand": true,
|
||||
"displayInterimAssistantMessages": false,
|
||||
"displayRuntimeFooterEnabled": true,
|
||||
@@ -17896,7 +17951,8 @@ memory:
|
||||
|
||||
assert_eq!(config["model"]["provider"].as_str(), Some("anthropic"));
|
||||
assert_eq!(config["memory"]["memory_enabled"].as_bool(), Some(true));
|
||||
assert_eq!(config["display"]["skin"].as_str(), Some("midnight"));
|
||||
assert_eq!(config["display"]["compact"].as_bool(), Some(true));
|
||||
assert_eq!(config["display"]["skin"].as_str(), Some("slate"));
|
||||
assert_eq!(
|
||||
config["display"]["platforms"]["telegram"]["tool_progress"].as_str(),
|
||||
Some("new")
|
||||
@@ -17967,6 +18023,10 @@ memory:
|
||||
.unwrap_err();
|
||||
assert!(err.contains("display.tool_progress"));
|
||||
|
||||
let err = merge_hermes_display_config(&mut config, &json!({ "displaySkin": "unknown" }))
|
||||
.unwrap_err();
|
||||
assert!(err.contains("display.skin"));
|
||||
|
||||
let err =
|
||||
merge_hermes_display_config(&mut config, &json!({ "displayResumeDisplay": "compact" }))
|
||||
.unwrap_err();
|
||||
|
||||
@@ -136,6 +136,8 @@ const SECURITY_DEFAULTS = {
|
||||
|
||||
const DISPLAY_DEFAULTS = {
|
||||
displayToolProgress: 'all',
|
||||
displayCompact: false,
|
||||
displaySkin: 'default',
|
||||
displayToolProgressCommand: false,
|
||||
displayInterimAssistantMessages: true,
|
||||
displayRuntimeFooterEnabled: false,
|
||||
@@ -265,6 +267,7 @@ const UNAUTHORIZED_DM_BEHAVIORS = ['pair', 'ignore']
|
||||
const IMAGE_INPUT_MODES = ['auto', 'native', 'text']
|
||||
const REASONING_EFFORTS = ['xhigh', 'high', 'medium', 'low', 'minimal', 'none']
|
||||
const DISPLAY_TOOL_PROGRESS_VALUES = ['off', 'new', 'all', 'verbose']
|
||||
const DISPLAY_SKINS = ['default', 'ares', 'mono', 'slate', 'daylight', 'warm-lightmode', 'poseidon', 'sisyphus', 'charizard']
|
||||
const DISPLAY_LANGUAGE_VALUES = ['en', 'zh', 'zh-hant', 'ja', 'de', 'es', 'fr', 'tr', 'uk', 'af', 'ko', 'it', 'ga', 'pt', 'ru', 'hu']
|
||||
const DISPLAY_RESUME_VALUES = ['full', 'minimal']
|
||||
const DISPLAY_BUSY_INPUT_MODES = ['interrupt', 'queue', 'steer']
|
||||
@@ -1243,6 +1246,12 @@ export function render() {
|
||||
${DISPLAY_TOOL_PROGRESS_VALUES.map(mode => option(`engine.hermesDisplayConfigToolProgress_${mode}`, mode, displayValues.displayToolProgress)).join('')}
|
||||
</select>
|
||||
</label>
|
||||
<label class="hm-field">
|
||||
<span class="hm-field-label">${t('engine.hermesDisplayConfigSkin')}</span>
|
||||
<select id="hm-display-skin" class="hm-input" ${disabled ? 'disabled' : ''}>
|
||||
${DISPLAY_SKINS.map(mode => option(`engine.hermesDisplayConfigSkin_${mode}`, mode, displayValues.displaySkin)).join('')}
|
||||
</select>
|
||||
</label>
|
||||
<label class="hm-field">
|
||||
<span class="hm-field-label">${t('engine.hermesDisplayConfigLanguage')}</span>
|
||||
<select id="hm-display-language" class="hm-input" ${disabled ? 'disabled' : ''}>
|
||||
@@ -1283,6 +1292,10 @@ export function render() {
|
||||
</label>
|
||||
</div>
|
||||
<div class="hm-config-check-grid">
|
||||
<label class="hm-channel-check">
|
||||
<input id="hm-display-compact" type="checkbox" ${displayValues.displayCompact ? 'checked' : ''} ${disabled ? 'disabled' : ''}>
|
||||
<span>${t('engine.hermesDisplayConfigCompact')}</span>
|
||||
</label>
|
||||
<label class="hm-channel-check">
|
||||
<input id="hm-display-tool-progress-command" type="checkbox" ${displayValues.displayToolProgressCommand ? 'checked' : ''} ${disabled ? 'disabled' : ''}>
|
||||
<span>${t('engine.hermesDisplayConfigToolProgressCommand')}</span>
|
||||
@@ -3159,6 +3172,8 @@ export function render() {
|
||||
async function saveDisplayConfig() {
|
||||
const form = {
|
||||
displayToolProgress: el.querySelector('#hm-display-tool-progress')?.value || 'all',
|
||||
displayCompact: !!el.querySelector('#hm-display-compact')?.checked,
|
||||
displaySkin: el.querySelector('#hm-display-skin')?.value || 'default',
|
||||
displayToolProgressCommand: !!el.querySelector('#hm-display-tool-progress-command')?.checked,
|
||||
displayInterimAssistantMessages: !!el.querySelector('#hm-display-interim-assistant-messages')?.checked,
|
||||
displayRuntimeFooterEnabled: !!el.querySelector('#hm-display-runtime-footer-enabled')?.checked,
|
||||
|
||||
@@ -919,7 +919,7 @@ export default {
|
||||
hermesUnauthorizedDmConfigBehavior_ignore: _('静默忽略', 'Silently ignore', '靜默忽略'),
|
||||
hermesUnauthorizedDmConfigFootnote: _('pair 是默认值,会拒绝访问但在私信中回复一次性配对码;ignore 会静默丢弃陌生私信。平台级覆盖仍可在渠道配置或 raw YAML 中单独设置。', 'pair is the default: Hermes denies access but replies with a one-time pairing code in DMs. ignore silently drops unknown DMs. Platform-level overrides can still be set in channel settings or raw YAML.', 'pair 是預設值,會拒絕存取但在私訊中回覆一次性配對碼;ignore 會靜默丟棄陌生私訊。平台級覆蓋仍可在頻道設定或 raw YAML 中單獨設定。'),
|
||||
hermesDisplayConfigTitle: _('全局显示与可靠性', 'Global display and reliability', '全域顯示與可靠性'),
|
||||
hermesDisplayConfigDesc: _('控制消息平台和 CLI 的默认进度展示、最终回复 Markdown、时间戳、完成提醒、终端输出恢复、忙时输入、后台进程通知、静态提示语言、运行信息页脚,以及文件写入失败校验。', 'Control default progress display, final-response Markdown, timestamps, completion bell, terminal output recovery, busy input handling, background process notifications, static prompt language, runtime footer, and failed file-mutation verification for messaging platforms and CLI.', '控制訊息平台和 CLI 的預設進度顯示、最終回覆 Markdown、時間戳、完成提醒、終端輸出恢復、忙時輸入、背景程序通知、靜態提示語言、執行資訊頁腳,以及檔案寫入失敗校驗。'),
|
||||
hermesDisplayConfigDesc: _('控制消息平台和 CLI 的默认进度展示、横幅紧凑模式、显示皮肤、最终回复 Markdown、时间戳、完成提醒、终端输出恢复、忙时输入、后台进程通知、静态提示语言、运行信息页脚,以及文件写入失败校验。', 'Control default progress display, compact banner mode, display skin, final-response Markdown, timestamps, completion bell, terminal output recovery, busy input handling, background process notifications, static prompt language, runtime footer, and failed file-mutation verification for messaging platforms and CLI.', '控制訊息平台和 CLI 的預設進度顯示、橫幅緊湊模式、顯示皮膚、最終回覆 Markdown、時間戳、完成提醒、終端輸出恢復、忙時輸入、背景程序通知、靜態提示語言、執行資訊頁腳,以及檔案寫入失敗校驗。'),
|
||||
hermesDisplayConfigStatusReady: _('结构化配置', 'structured settings', '結構化設定'),
|
||||
hermesDisplayConfigSave: _('保存显示设置', 'Save display settings', '儲存顯示設定'),
|
||||
hermesDisplayConfigSaveSuccess: _('显示与可靠性配置已保存,建议重启 Hermes Gateway 生效', 'Display and reliability settings saved. Restart Hermes Gateway to take effect.', '顯示與可靠性設定已儲存,建議重啟 Hermes Gateway 生效'),
|
||||
@@ -930,6 +930,17 @@ export default {
|
||||
hermesDisplayConfigToolProgress_new: _('工具变化时显示', 'Only when tool changes', '工具變化時顯示'),
|
||||
hermesDisplayConfigToolProgress_all: _('显示每次工具调用', 'Show every tool call', '顯示每次工具呼叫'),
|
||||
hermesDisplayConfigToolProgress_verbose: _('详细显示参数和结果', 'Verbose args and results', '詳細顯示參數與結果'),
|
||||
hermesDisplayConfigCompact: _('使用紧凑启动横幅', 'Use compact startup banner', '使用緊湊啟動橫幅'),
|
||||
hermesDisplayConfigSkin: _('CLI 显示皮肤', 'CLI display skin', 'CLI 顯示皮膚'),
|
||||
hermesDisplayConfigSkin_default: _('默认', 'Default', '預設'),
|
||||
hermesDisplayConfigSkin_ares: _('Ares', 'Ares', 'Ares'),
|
||||
hermesDisplayConfigSkin_mono: _('Mono', 'Mono', 'Mono'),
|
||||
hermesDisplayConfigSkin_slate: _('Slate', 'Slate', 'Slate'),
|
||||
hermesDisplayConfigSkin_daylight: _('Daylight', 'Daylight', 'Daylight'),
|
||||
'hermesDisplayConfigSkin_warm-lightmode': _('Warm Lightmode', 'Warm Lightmode', 'Warm Lightmode'),
|
||||
hermesDisplayConfigSkin_poseidon: _('Poseidon', 'Poseidon', 'Poseidon'),
|
||||
hermesDisplayConfigSkin_sisyphus: _('Sisyphus', 'Sisyphus', 'Sisyphus'),
|
||||
hermesDisplayConfigSkin_charizard: _('Charizard', 'Charizard', 'Charizard'),
|
||||
hermesDisplayConfigToolProgressCommand: _('在消息平台启用 /verbose 命令', 'Enable /verbose on messaging platforms', '在訊息平台啟用 /verbose 命令'),
|
||||
hermesDisplayConfigInterimAssistantMessages: _('发送中途状态消息', 'Send interim assistant updates', '傳送中途狀態訊息'),
|
||||
hermesDisplayConfigRuntimeFooterEnabled: _('在最终回复追加运行信息', 'Append runtime footer to final replies', '在最終回覆追加執行資訊'),
|
||||
@@ -972,7 +983,7 @@ export default {
|
||||
hermesDisplayConfigBellOnComplete: _('任务完成时播放提示音', 'Play bell when runs complete', '任務完成時播放提示音'),
|
||||
hermesDisplayConfigPersistentOutput: _('保留终端输出用于恢复显示', 'Keep terminal output for display recovery', '保留終端輸出用於恢復顯示'),
|
||||
hermesDisplayConfigPersistentOutputMaxLines: _('保留输出最大行数', 'Max retained output lines', '保留輸出最大行數'),
|
||||
hermesDisplayConfigFootnote: _('这里写入全局 display 配置;平台级覆盖仍在渠道页管理。忙时输入控制长跑期间新消息如何处理,后台进程通知控制 messaging watcher 噪音。最终回复 Markdown、时间戳、完成铃声和持久输出影响 CLI 可读性与终端重绘恢复。display.streaming 是 CLI-only,本面板不会把它误写成 Gateway 全局流式设置。运行信息字段支持 model、context_pct、cwd、duration、tokens、cost。', 'This writes global display settings; per-platform overrides remain in channel settings. Busy input controls how new messages are handled during long runs, and background process notifications tune messaging watcher noise. Final-response Markdown, timestamps, completion bell, and persistent output affect CLI readability and terminal redraw recovery. display.streaming is CLI-only, so this panel does not write it as a global Gateway streaming setting. Runtime footer fields support model, context_pct, cwd, duration, tokens, and cost.', '這裡寫入全域 display 設定;平台級覆蓋仍在頻道頁管理。忙時輸入控制長跑期間新訊息如何處理,背景程序通知控制 messaging watcher 噪音。最終回覆 Markdown、時間戳、完成鈴聲和持久輸出會影響 CLI 可讀性與終端重繪恢復。display.streaming 是 CLI-only,本面板不會把它誤寫成 Gateway 全域串流設定。執行資訊欄位支援 model、context_pct、cwd、duration、tokens、cost。'),
|
||||
hermesDisplayConfigFootnote: _('这里写入全局 display 配置;平台级覆盖仍在渠道页管理。紧凑横幅和显示皮肤影响 CLI 启动展示。忙时输入控制长跑期间新消息如何处理,后台进程通知控制 messaging watcher 噪音。最终回复 Markdown、时间戳、完成铃声和持久输出影响 CLI 可读性与终端重绘恢复。display.streaming 是 CLI-only,本面板不会把它误写成 Gateway 全局流式设置。运行信息字段支持 model、context_pct、cwd、duration、tokens、cost。', 'This writes global display settings; per-platform overrides remain in channel settings. Compact banner and display skin affect CLI startup presentation. Busy input controls how new messages are handled during long runs, and background process notifications tune messaging watcher noise. Final-response Markdown, timestamps, completion bell, and persistent output affect CLI readability and terminal redraw recovery. display.streaming is CLI-only, so this panel does not write it as a global Gateway streaming setting. Runtime footer fields support model, context_pct, cwd, duration, tokens, and cost.', '這裡寫入全域 display 設定;平台級覆蓋仍在頻道頁管理。緊湊橫幅和顯示皮膚會影響 CLI 啟動展示。忙時輸入控制長跑期間新訊息如何處理,背景程序通知控制 messaging watcher 噪音。最終回覆 Markdown、時間戳、完成鈴聲和持久輸出會影響 CLI 可讀性與終端重繪恢復。display.streaming 是 CLI-only,本面板不會把它誤寫成 Gateway 全域串流設定。執行資訊欄位支援 model、context_pct、cwd、duration、tokens、cost。'),
|
||||
hermesHumanDelayConfigTitle: _('响应节奏', 'Response pacing', '回應節奏'),
|
||||
hermesHumanDelayConfigDesc: _('控制消息平台回复分块之间的等待时间,降低刷屏或模拟更自然发送节奏。', 'Control the wait time between reply chunks on messaging platforms to reduce flooding or mimic a more natural sending rhythm.', '控制訊息平台回覆分塊之間的等待時間,降低刷屏或模擬更自然的傳送節奏。'),
|
||||
hermesHumanDelayConfigStatusReady: _('结构化配置', 'structured settings', '結構化設定'),
|
||||
|
||||
@@ -162,6 +162,8 @@ test('Hermes 配置页会暴露全局显示与可靠性结构化配置字段', (
|
||||
for (const id of [
|
||||
'hm-display-save',
|
||||
'hm-display-tool-progress',
|
||||
'hm-display-compact',
|
||||
'hm-display-skin',
|
||||
'hm-display-tool-progress-command',
|
||||
'hm-display-interim-assistant-messages',
|
||||
'hm-display-runtime-footer-enabled',
|
||||
|
||||
@@ -11,6 +11,8 @@ test('Hermes 显示配置读取会提供上游默认值', () => {
|
||||
|
||||
assert.deepEqual(values, {
|
||||
displayToolProgress: 'all',
|
||||
displayCompact: false,
|
||||
displaySkin: 'default',
|
||||
displayToolProgressCommand: false,
|
||||
displayInterimAssistantMessages: true,
|
||||
displayRuntimeFooterEnabled: false,
|
||||
@@ -32,6 +34,8 @@ test('Hermes 显示配置读取会规范化已有字段', () => {
|
||||
const values = buildHermesDisplayConfigValues({
|
||||
display: {
|
||||
tool_progress: 'VERBOSE',
|
||||
compact: true,
|
||||
skin: 'MONO',
|
||||
tool_progress_command: true,
|
||||
interim_assistant_messages: false,
|
||||
runtime_footer: {
|
||||
@@ -52,6 +56,8 @@ test('Hermes 显示配置读取会规范化已有字段', () => {
|
||||
})
|
||||
|
||||
assert.equal(values.displayToolProgress, 'verbose')
|
||||
assert.equal(values.displayCompact, true)
|
||||
assert.equal(values.displaySkin, 'mono')
|
||||
assert.equal(values.displayToolProgressCommand, true)
|
||||
assert.equal(values.displayInterimAssistantMessages, false)
|
||||
assert.equal(values.displayRuntimeFooterEnabled, true)
|
||||
@@ -84,6 +90,8 @@ test('Hermes 显示配置保存会保留未知 YAML 并写入 display', () => {
|
||||
memory: { memory_enabled: true },
|
||||
}, {
|
||||
displayToolProgress: 'off',
|
||||
displayCompact: true,
|
||||
displaySkin: 'slate',
|
||||
displayToolProgressCommand: 'true',
|
||||
displayInterimAssistantMessages: false,
|
||||
displayRuntimeFooterEnabled: true,
|
||||
@@ -102,7 +110,8 @@ test('Hermes 显示配置保存会保留未知 YAML 并写入 display', () => {
|
||||
|
||||
assert.deepEqual(next.model, { provider: 'anthropic' })
|
||||
assert.deepEqual(next.memory, { memory_enabled: true })
|
||||
assert.equal(next.display.skin, 'midnight')
|
||||
assert.equal(next.display.compact, true)
|
||||
assert.equal(next.display.skin, 'slate')
|
||||
assert.deepEqual(next.display.platforms.telegram, { tool_progress: 'new' })
|
||||
assert.equal(next.display.tool_progress, 'off')
|
||||
assert.equal(next.display.tool_progress_command, true)
|
||||
@@ -127,6 +136,10 @@ test('Hermes 显示配置保存会拒绝非法枚举和页脚字段', () => {
|
||||
() => mergeHermesDisplayConfig({}, { displayToolProgress: 'everything' }),
|
||||
/display\.tool_progress/,
|
||||
)
|
||||
assert.throws(
|
||||
() => mergeHermesDisplayConfig({}, { displaySkin: 'unknown' }),
|
||||
/display\.skin/,
|
||||
)
|
||||
assert.throws(
|
||||
() => mergeHermesDisplayConfig({}, { displayResumeDisplay: 'compact' }),
|
||||
/display\.resume_display/,
|
||||
|
||||
Reference in New Issue
Block a user