diff --git a/modules/personalization_manager.py b/modules/personalization_manager.py index 0e12fd0..25bd697 100644 --- a/modules/personalization_manager.py +++ b/modules/personalization_manager.py @@ -28,6 +28,7 @@ DEFAULT_PERSONALIZATION_CONFIG: Dict[str, Any] = { "enabled": False, "self_identify": "", "user_name": "", + "use_custom_names": False, "profession": "", "tone": "", "considerations": [], @@ -190,6 +191,12 @@ def sanitize_personalization_payload( else: base["enhanced_tool_display"] = bool(base.get("enhanced_tool_display", True)) + # 使用自定义称呼 + if "use_custom_names" in data: + base["use_custom_names"] = bool(data.get("use_custom_names")) + else: + base["use_custom_names"] = bool(base.get("use_custom_names")) + return base diff --git a/static/src/app/methods/ui.ts b/static/src/app/methods/ui.ts index 04cb8d0..d673de5 100644 --- a/static/src/app/methods/ui.ts +++ b/static/src/app/methods/ui.ts @@ -1,6 +1,7 @@ // @ts-nocheck import { usePolicyStore } from '../../stores/policy'; import { useModelStore } from '../../stores/model'; +import { usePersonalizationStore } from '../../stores/personalization'; import { initializeLegacySocket } from '../../composables/useLegacySocket'; import { renderMarkdown as renderMarkdownHelper } from '../../composables/useMarkdownRenderer'; import { @@ -1109,6 +1110,14 @@ export const uiMethods = { await policyStore.fetchPolicy(); this.applyPolicyUiLocks(); + // 加载个性化设置 + const personalizationStore = usePersonalizationStore(); + if (!personalizationStore.loaded && !personalizationStore.loading) { + personalizationStore.fetchPersonalization().catch(err => { + console.warn('加载个性化设置失败:', err); + }); + } + const focusPromise = this.focusFetchFiles(); const todoPromise = this.fileFetchTodoList(); let treePromise: Promise | null = null; diff --git a/static/src/components/chat/ChatArea.vue b/static/src/components/chat/ChatArea.vue index e4bfd3a..ee5dd2a 100644 --- a/static/src/components/chat/ChatArea.vue +++ b/static/src/components/chat/ChatArea.vue @@ -5,7 +5,7 @@
- 用户 + {{ userName }}
{{ msg.content }}
@@ -26,7 +26,7 @@
- AI Assistant + {{ aiAssistantName }}
{ const enabled = personalization.experiments.stackedBlocksEnabled; return enabled !== false; }); +const aiAssistantName = computed(() => { + if (!personalization.form.use_custom_names) { + return 'AI Assistant'; + } + return personalization.form.self_identify || 'AI Assistant'; +}); +const userName = computed(() => { + if (!personalization.form.use_custom_names) { + return '用户'; + } + return personalization.form.user_name || '用户'; +}); const filteredMessages = computed(() => (props.messages || []).filter(m => !(m && m.metadata && m.metadata.system_injected_image) && m.role !== 'system') ); diff --git a/static/src/components/personalization/PersonalizationDrawer.vue b/static/src/components/personalization/PersonalizationDrawer.vue index 28fb5e9..ef57583 100644 --- a/static/src/components/personalization/PersonalizationDrawer.vue +++ b/static/src/components/personalization/PersonalizationDrawer.vue @@ -382,6 +382,29 @@
+
+
+ 使用自定义称呼 +

开启后,对话区域将使用您在"个性化设置"中配置的自称和称呼。关闭则显示默认的"AI Assistant"和"用户"。

+
+ +
增强工具显示 diff --git a/static/src/composables/useScrollControl.ts b/static/src/composables/useScrollControl.ts index 2791c1d..374f7f3 100644 --- a/static/src/composables/useScrollControl.ts +++ b/static/src/composables/useScrollControl.ts @@ -110,16 +110,12 @@ export function toggleScrollLock(ctx: ScrollContext) { /** * 在页面初始化/刷新后同步滚动锁定的默认状态: - * 仅当存在输出(流式中或有未完成工具)时才保持锁定,否则自动解锁。 + * 始终保持锁定状态,不再根据输出状态自动解锁。 */ export function normalizeScrollLock(ctx: ScrollContext) { - const active = - (typeof ctx.isOutputActive === 'function' ? ctx.isOutputActive() : false) || - !!ctx.streamingMessage || - (typeof ctx.hasPendingToolActions === 'function' ? ctx.hasPendingToolActions() : false); - - if (!active && ctx.autoScrollEnabled) { - ctx.chatSetScrollState?.({ autoScrollEnabled: false, userScrolling: false }); + // 确保滚动锁定始终启用 + if (!ctx.autoScrollEnabled) { + ctx.chatSetScrollState?.({ autoScrollEnabled: true, userScrolling: false }); } } diff --git a/static/src/stores/personalization.ts b/static/src/stores/personalization.ts index 11b8e1c..b1ed19b 100644 --- a/static/src/stores/personalization.ts +++ b/static/src/stores/personalization.ts @@ -11,6 +11,7 @@ interface PersonalForm { enabled_skills: string[]; self_identify: string; user_name: string; + use_custom_names: boolean; profession: string; tone: string; considerations: string[]; @@ -67,6 +68,7 @@ const defaultForm = (): PersonalForm => ({ enabled_skills: [], self_identify: '', user_name: '', + use_custom_names: false, profession: '', tone: '', considerations: [], @@ -201,6 +203,7 @@ export const usePersonalizationStore = defineStore('personalization', { : [], self_identify: data.self_identify || '', user_name: data.user_name || '', + use_custom_names: !!data.use_custom_names, profession: data.profession || '', tone: data.tone || '', considerations: Array.isArray(data.considerations) ? [...data.considerations] : [], diff --git a/static/src/styles/components/overlays/_overlays.scss b/static/src/styles/components/overlays/_overlays.scss index a096a2c..191336a 100644 --- a/static/src/styles/components/overlays/_overlays.scss +++ b/static/src/styles/components/overlays/_overlays.scss @@ -3362,6 +3362,10 @@ body[data-theme='dark'] { filter: brightness(0) invert(1); } + .scroll-lock-toggle.locked .scroll-lock-btn svg { + stroke: #ffffff; + } + /* 左侧面板头部(文件/待办事项/子智能体标签栏) */ .sidebar-header { background: #1a1a1a;