feat(personalization): 简略消息显示改为持久化到配置文件
原来「简略消息显示」只存浏览器 localStorage(experiments),换设备/清缓存即丢。 现迁移到后端 personalization.json,与主题/默认隐藏工作区一致即时保存: - 后端新增 compact_message_display 字段(默认 full)及清洗(仅 full/brief, 容错大小写空格,非法回退 full) - store: PersonalForm 加字段;setCompactMessageDisplay 写 form + 即时 POST; 加载时同步进旧 experiments 镜像,并一次性迁移本地遗留 brief 回写配置文件 - 抽屉下拉与 ChatArea 改读 form.compact_message_display,experiments 作兜底 - 保留 localStorage 镜像保证向后兼容,老用户首次加载自动迁移偏好 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9399d3f41e
commit
9be775d346
@ -91,6 +91,7 @@ DEFAULT_PERSONALIZATION_CONFIG: Dict[str, Any] = {
|
|||||||
"deep_compress_behavior": "continue", # 手动压缩行为:continue-注入并触发请求 / wait-仅插入等待用户
|
"deep_compress_behavior": "continue", # 手动压缩行为:continue-注入并触发请求 / wait-仅插入等待用户
|
||||||
"silent_tool_disable": True, # 禁用工具时不向模型插入提示(默认开启)
|
"silent_tool_disable": True, # 禁用工具时不向模型插入提示(默认开启)
|
||||||
"enhanced_tool_display": True, # 增强工具显示
|
"enhanced_tool_display": True, # 增强工具显示
|
||||||
|
"compact_message_display": "full", # 简略消息显示:full-完整原始内容 / brief-一行概要
|
||||||
"show_git_status_bar": True, # 是否显示输入栏上方 Git 状态栏
|
"show_git_status_bar": True, # 是否显示输入栏上方 Git 状态栏
|
||||||
"versioning_restore_mode": "overwrite", # 版本回溯模式固定为 overwrite
|
"versioning_restore_mode": "overwrite", # 版本回溯模式固定为 overwrite
|
||||||
"agents_md_auto_inject": False, # AGENTS.md 自动注入开关
|
"agents_md_auto_inject": False, # AGENTS.md 自动注入开关
|
||||||
@ -414,6 +415,13 @@ def sanitize_personalization_payload(
|
|||||||
else:
|
else:
|
||||||
base["enhanced_tool_display"] = bool(base.get("enhanced_tool_display", True))
|
base["enhanced_tool_display"] = bool(base.get("enhanced_tool_display", True))
|
||||||
|
|
||||||
|
# 简略消息显示:full(完整原始内容)/ brief(一行概要)
|
||||||
|
compact_msg = data.get("compact_message_display", base.get("compact_message_display"))
|
||||||
|
if isinstance(compact_msg, str) and compact_msg.strip().lower() in ("full", "brief"):
|
||||||
|
base["compact_message_display"] = compact_msg.strip().lower()
|
||||||
|
else:
|
||||||
|
base["compact_message_display"] = "full"
|
||||||
|
|
||||||
# Git 状态栏显示开关
|
# Git 状态栏显示开关
|
||||||
if "show_git_status_bar" in data:
|
if "show_git_status_bar" in data:
|
||||||
base["show_git_status_bar"] = bool(data.get("show_git_status_bar"))
|
base["show_git_status_bar"] = bool(data.get("show_git_status_bar"))
|
||||||
|
|||||||
@ -634,7 +634,11 @@ const blockDisplayMode = computed(() => {
|
|||||||
return personalization.experiments.blockDisplayMode || 'stacked';
|
return personalization.experiments.blockDisplayMode || 'stacked';
|
||||||
});
|
});
|
||||||
const compactMessageDisplay = computed(() => {
|
const compactMessageDisplay = computed(() => {
|
||||||
return personalization.experiments.compactMessageDisplay || 'full';
|
return (
|
||||||
|
personalization.form.compact_message_display ||
|
||||||
|
personalization.experiments.compactMessageDisplay ||
|
||||||
|
'full'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
const stackedBlocksEnabled = computed(() => {
|
const stackedBlocksEnabled = computed(() => {
|
||||||
// 堆叠模式和极简模式都使用堆叠布局
|
// 堆叠模式和极简模式都使用堆叠布局
|
||||||
|
|||||||
@ -1779,7 +1779,9 @@ const blockDisplayLabel = computed(() => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const currentCompactMessageDisplay = computed(() => experiments.value.compactMessageDisplay);
|
const currentCompactMessageDisplay = computed(
|
||||||
|
() => form.value.compact_message_display || 'full'
|
||||||
|
);
|
||||||
|
|
||||||
const compactMessageDisplayLabel = computed(() => {
|
const compactMessageDisplayLabel = computed(() => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -21,6 +21,7 @@ interface PersonalForm {
|
|||||||
skill_strict_run_command_background_enabled: boolean;
|
skill_strict_run_command_background_enabled: boolean;
|
||||||
silent_tool_disable: boolean;
|
silent_tool_disable: boolean;
|
||||||
enhanced_tool_display: boolean;
|
enhanced_tool_display: boolean;
|
||||||
|
compact_message_display: CompactMessageDisplay;
|
||||||
show_git_status_bar: boolean;
|
show_git_status_bar: boolean;
|
||||||
enhanced_tool_display_categories: string[];
|
enhanced_tool_display_categories: string[];
|
||||||
enabled_skills: string[];
|
enabled_skills: string[];
|
||||||
@ -116,6 +117,7 @@ const defaultForm = (): PersonalForm => ({
|
|||||||
skill_strict_run_command_background_enabled: false,
|
skill_strict_run_command_background_enabled: false,
|
||||||
silent_tool_disable: false,
|
silent_tool_disable: false,
|
||||||
enhanced_tool_display: true,
|
enhanced_tool_display: true,
|
||||||
|
compact_message_display: 'full',
|
||||||
show_git_status_bar: true,
|
show_git_status_bar: true,
|
||||||
enhanced_tool_display_categories: [],
|
enhanced_tool_display_categories: [],
|
||||||
enabled_skills: [],
|
enabled_skills: [],
|
||||||
@ -295,6 +297,7 @@ export const usePersonalizationStore = defineStore('personalization', {
|
|||||||
!!data.skill_strict_run_command_background_enabled,
|
!!data.skill_strict_run_command_background_enabled,
|
||||||
silent_tool_disable: !!data.silent_tool_disable,
|
silent_tool_disable: !!data.silent_tool_disable,
|
||||||
enhanced_tool_display: data.enhanced_tool_display !== false,
|
enhanced_tool_display: data.enhanced_tool_display !== false,
|
||||||
|
compact_message_display: data.compact_message_display === 'brief' ? 'brief' : 'full',
|
||||||
show_git_status_bar: data.show_git_status_bar !== false,
|
show_git_status_bar: data.show_git_status_bar !== false,
|
||||||
enhanced_tool_display_categories: Array.isArray(data.enhanced_tool_display_categories)
|
enhanced_tool_display_categories: Array.isArray(data.enhanced_tool_display_categories)
|
||||||
? data.enhanced_tool_display_categories.filter((item: unknown) => typeof item === 'string')
|
? data.enhanced_tool_display_categories.filter((item: unknown) => typeof item === 'string')
|
||||||
@ -381,6 +384,18 @@ export const usePersonalizationStore = defineStore('personalization', {
|
|||||||
if (this.form.default_hide_workspace) {
|
if (this.form.default_hide_workspace) {
|
||||||
useUiStore().setWorkspaceCollapsed(true);
|
useUiStore().setWorkspaceCollapsed(true);
|
||||||
}
|
}
|
||||||
|
// 简略消息显示:以配置文件为准,同步到旧版 localStorage 镜像供 ChatArea 读取。
|
||||||
|
// 一次性迁移:后端仍为默认 full,但本地缓存遗留 brief(旧版纯前端记录)时,回写到配置文件。
|
||||||
|
const cachedCompact = this.experiments.compactMessageDisplay;
|
||||||
|
if (this.form.compact_message_display === 'full' && cachedCompact === 'brief') {
|
||||||
|
this.form = { ...this.form, compact_message_display: 'brief' };
|
||||||
|
void this.persistCompactMessageDisplay('brief');
|
||||||
|
}
|
||||||
|
this.experiments = {
|
||||||
|
...this.experiments,
|
||||||
|
compactMessageDisplay: this.form.compact_message_display
|
||||||
|
};
|
||||||
|
this.persistExperiments();
|
||||||
this.clearFeedback();
|
this.clearFeedback();
|
||||||
},
|
},
|
||||||
applyTheme(theme: 'classic' | 'light' | 'dark') {
|
applyTheme(theme: 'classic' | 'light' | 'dark') {
|
||||||
@ -791,11 +806,35 @@ export const usePersonalizationStore = defineStore('personalization', {
|
|||||||
this.persistExperiments();
|
this.persistExperiments();
|
||||||
},
|
},
|
||||||
setCompactMessageDisplay(mode: CompactMessageDisplay) {
|
setCompactMessageDisplay(mode: CompactMessageDisplay) {
|
||||||
|
const target: CompactMessageDisplay = mode === 'brief' ? 'brief' : 'full';
|
||||||
|
this.form = {
|
||||||
|
...this.form,
|
||||||
|
compact_message_display: target
|
||||||
|
};
|
||||||
|
// 同步旧版 localStorage 镜像,保持兼容并避免迁移逻辑回写旧值
|
||||||
this.experiments = {
|
this.experiments = {
|
||||||
...this.experiments,
|
...this.experiments,
|
||||||
compactMessageDisplay: mode
|
compactMessageDisplay: target
|
||||||
};
|
};
|
||||||
this.persistExperiments();
|
this.persistExperiments();
|
||||||
|
this.clearFeedback();
|
||||||
|
// 持久化到后端配置文件(即时保存,参照主题/默认隐藏工作区)
|
||||||
|
void this.persistCompactMessageDisplay(target);
|
||||||
|
},
|
||||||
|
async persistCompactMessageDisplay(mode: CompactMessageDisplay) {
|
||||||
|
try {
|
||||||
|
const resp = await fetch('/api/personalization', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ compact_message_display: mode })
|
||||||
|
});
|
||||||
|
const result = await resp.json();
|
||||||
|
if (!resp.ok || !result.success) {
|
||||||
|
console.warn('保存简略消息显示失败:', result?.error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('保存简略消息显示失败:', error);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setCommunicationStyle(style: 'default' | 'human_like') {
|
setCommunicationStyle(style: 'default' | 'human_like') {
|
||||||
this.form = {
|
this.form = {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user