mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-25 17:54:34 +08:00
fix(settings): allow memory as the default session tab (#494)
This commit is contained in:
1 parent
7b791785b7
commit
0edc64d99a
13 files changed
+117
-18
No files matched your search
@@ -138,7 +138,17 @@ export function writeConfigField(section: string, key: string, value: string | n
|
||||
if (!existing[section] || typeof existing[section] !== 'object') {
|
||||
existing[section] = {}
|
||||
}
|
||||
existing[section][key] = value
|
||||
if (section === 'ui' && key === 'default_session_tab') {
|
||||
if (value === 'memory') {
|
||||
existing.ui.default_session_tab = 'overview'
|
||||
existing.ui.default_session_tab_override = 'memory'
|
||||
} else {
|
||||
existing.ui.default_session_tab = value
|
||||
delete existing.ui.default_session_tab_override
|
||||
}
|
||||
} else {
|
||||
existing[section][key] = value
|
||||
}
|
||||
|
||||
const lines: string[] = []
|
||||
for (const [sec, entries] of Object.entries(existing)) {
|
||||
|
||||
@@ -14,8 +14,44 @@ test('normalizes the released overview preference to insights', () => {
|
||||
assert.equal(config.ui.default_session_tab, 'insights')
|
||||
})
|
||||
|
||||
test('accepts memory as a session landing tab', () => {
|
||||
const config = configSchema.parse({
|
||||
ui: {
|
||||
default_session_tab: 'overview',
|
||||
default_session_tab_override: 'memory',
|
||||
},
|
||||
})
|
||||
|
||||
assert.equal(config.ui.default_session_tab, 'memory')
|
||||
})
|
||||
|
||||
test('accepts canonical memory input and its parsed output', () => {
|
||||
const config = configSchema.parse({ ui: { default_session_tab: 'memory' } })
|
||||
|
||||
assert.equal(config.ui.default_session_tab, 'memory')
|
||||
assert.equal(configSchema.parse(config).ui.default_session_tab, 'memory')
|
||||
})
|
||||
|
||||
test('prefers a later legacy session tab change over the memory override', () => {
|
||||
const config = configSchema.parse({
|
||||
ui: {
|
||||
default_session_tab: 'ai-chat',
|
||||
default_session_tab_override: 'memory',
|
||||
},
|
||||
})
|
||||
|
||||
assert.equal(config.ui.default_session_tab, 'ai-chat')
|
||||
})
|
||||
|
||||
test('does not reinterpret a historical overview preference as memory', () => {
|
||||
const config = configSchema.parse({ ui: { default_session_tab: 'overview' } })
|
||||
|
||||
assert.equal(config.ui.default_session_tab, 'insights')
|
||||
})
|
||||
|
||||
test('rejects unknown session landing tabs', () => {
|
||||
assert.throws(() => configSchema.parse({ ui: { default_session_tab: 'unknown' } }))
|
||||
assert.throws(() => configSchema.parse({ ui: { default_session_tab_override: 'unknown' } }))
|
||||
})
|
||||
|
||||
test('defaults Windows close behavior to running in the background', () => {
|
||||
|
||||
@@ -30,14 +30,25 @@ export const localeConfigSchema = z.object({
|
||||
lang: z.string().default(''),
|
||||
})
|
||||
|
||||
export const uiConfigSchema = z.object({
|
||||
default_session_tab: z.preprocess(
|
||||
(value) => (value === 'overview' ? 'insights' : value),
|
||||
z.enum(['insights', 'ai-chat']).default('insights')
|
||||
),
|
||||
session_gap_threshold: z.number().int().min(60).max(86400).default(1800),
|
||||
summary_strategy: z.enum(['brief', 'standard']).default('standard'),
|
||||
})
|
||||
const defaultSessionTabSchema = z.preprocess(
|
||||
(value) => (value === 'overview' ? 'insights' : value),
|
||||
z.enum(['insights', 'ai-chat', 'memory']).default('insights')
|
||||
)
|
||||
|
||||
export const uiConfigSchema = z
|
||||
.object({
|
||||
default_session_tab: z.unknown().optional(),
|
||||
default_session_tab_override: z.literal('memory').optional(),
|
||||
session_gap_threshold: z.number().int().min(60).max(86400).default(1800),
|
||||
summary_strategy: z.enum(['brief', 'standard']).default('standard'),
|
||||
})
|
||||
.transform(({ default_session_tab_override, ...config }) => ({
|
||||
...config,
|
||||
default_session_tab:
|
||||
default_session_tab_override && config.default_session_tab === 'overview'
|
||||
? default_session_tab_override
|
||||
: defaultSessionTabSchema.parse(config.default_session_tab),
|
||||
}))
|
||||
|
||||
export const cliConfigSchema = z.object({
|
||||
/** Allow --raw output that bypasses privacy preprocessing (user-side opt-in). */
|
||||
|
||||
@@ -3,9 +3,12 @@ import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync, mkdirSync
|
||||
import { join } from 'node:path'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { after, beforeEach, describe, it } from 'node:test'
|
||||
import { parse as parseToml } from 'smol-toml'
|
||||
import { z } from 'zod'
|
||||
|
||||
const tempHome = mkdtempSync(join(tmpdir(), 'chatlab-config-set-'))
|
||||
process.env.HOME = tempHome
|
||||
process.env.USERPROFILE = tempHome
|
||||
|
||||
const [{ setConfigField, ConfigSetError }, { loadConfig }] = await Promise.all([
|
||||
import('./set-config-field'),
|
||||
@@ -69,6 +72,38 @@ describe('setConfigField', () => {
|
||||
assert.equal(loadConfig().desktop.close_behavior, 'background')
|
||||
})
|
||||
|
||||
it('persists memory without breaking the v0.37.5 UI config schema', () => {
|
||||
setConfigField('ui.default_session_tab', 'memory')
|
||||
|
||||
assert.equal(loadConfig().ui.default_session_tab, 'memory')
|
||||
|
||||
const saved = parseToml(readFileSync(configToml, 'utf-8')) as { ui: Record<string, unknown> }
|
||||
const releasedUiConfigSchema = z.object({
|
||||
default_session_tab: z.preprocess(
|
||||
(value) => (value === 'overview' ? 'insights' : value),
|
||||
z.enum(['insights', 'ai-chat']).default('insights')
|
||||
),
|
||||
session_gap_threshold: z.number().int().min(60).max(86400).default(1800),
|
||||
summary_strategy: z.enum(['brief', 'standard']).default('standard'),
|
||||
})
|
||||
assert.equal(releasedUiConfigSchema.parse(saved.ui).default_session_tab, 'insights')
|
||||
})
|
||||
|
||||
it('honors a later session tab write from a v0.37.5 client', () => {
|
||||
setConfigField('ui.default_session_tab', 'memory')
|
||||
|
||||
let content = readFileSync(configToml, 'utf-8').replace(
|
||||
'default_session_tab = "overview"',
|
||||
'default_session_tab = "ai-chat"'
|
||||
)
|
||||
writeFileSync(configToml, content, 'utf-8')
|
||||
assert.equal(loadConfig().ui.default_session_tab, 'ai-chat')
|
||||
|
||||
content = content.replace('default_session_tab = "ai-chat"', 'default_session_tab = "insights"')
|
||||
writeFileSync(configToml, content, 'utf-8')
|
||||
assert.equal(loadConfig().ui.default_session_tab, 'insights')
|
||||
})
|
||||
|
||||
it('writes boolean value and round-trips via loadConfig', () => {
|
||||
const result = setConfigField('cli.allow_raw', 'true')
|
||||
assert.deepEqual(result, { section: 'cli', key: 'allow_raw', value: true })
|
||||
|
||||
@@ -1420,7 +1420,7 @@ export interface Preferences {
|
||||
}
|
||||
|
||||
export interface UiConfig {
|
||||
default_session_tab: 'insights' | 'ai-chat'
|
||||
default_session_tab: 'insights' | 'ai-chat' | 'memory'
|
||||
session_gap_threshold: number
|
||||
summary_strategy?: 'brief' | 'standard'
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { availableLocales, type LocaleType } from '@/i18n'
|
||||
import NetworkSettingsSection from './NetworkSettingsSection.vue'
|
||||
import UITabs from '@/components/UI/Tabs.vue'
|
||||
import { usePlatformService } from '@/services'
|
||||
import { IS_ELECTRON } from '@/utils/platform'
|
||||
import { IS_ELECTRON, IS_WEB_WASM } from '@/utils/platform'
|
||||
import { INSIGHT_CARD_THEMES, type InsightCardThemeId } from '@/utils/insight-card-theme'
|
||||
import type { DesktopCloseBehavior } from '@openchatlab/shared-types'
|
||||
|
||||
@@ -155,6 +155,7 @@ const currentLocale = computed({
|
||||
const defaultTabOptions = computed(() => [
|
||||
{ label: t('settings.basic.defaultTab.insights'), value: 'insights' },
|
||||
{ label: t('settings.basic.defaultTab.aiChat'), value: 'ai-chat' },
|
||||
...(!IS_WEB_WASM ? [{ label: t('settings.basic.defaultTab.memory'), value: 'memory' }] : []),
|
||||
])
|
||||
|
||||
// Tools panel position options
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
"defaultTab": {
|
||||
"description": "Default page when entering a chat conversation",
|
||||
"insights": "Insights",
|
||||
"aiChat": "AI Chat"
|
||||
"aiChat": "AI Chat",
|
||||
"memory": "Memory"
|
||||
},
|
||||
"autoLaunch": {
|
||||
"openAtLogin": "Launch at Login",
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
"defaultTab": {
|
||||
"description": "チャットに入った時に表示するページ",
|
||||
"insights": "インサイト",
|
||||
"aiChat": "AI チャット"
|
||||
"aiChat": "AI チャット",
|
||||
"memory": "メモリー"
|
||||
},
|
||||
"autoLaunch": {
|
||||
"openAtLogin": "ログイン時に自動起動",
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
"defaultTab": {
|
||||
"description": "进入聊天对话后默认显示的页面",
|
||||
"insights": "洞察",
|
||||
"aiChat": "AI 对话"
|
||||
"aiChat": "AI 对话",
|
||||
"memory": "记忆"
|
||||
},
|
||||
"autoLaunch": {
|
||||
"openAtLogin": "开机自启动",
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
"defaultTab": {
|
||||
"description": "進入聊天對話後預設顯示的頁面",
|
||||
"insights": "洞察",
|
||||
"aiChat": "AI 對話"
|
||||
"aiChat": "AI 對話",
|
||||
"memory": "記憶"
|
||||
},
|
||||
"autoLaunch": {
|
||||
"openAtLogin": "開機自動啟動",
|
||||
|
||||
@@ -85,7 +85,8 @@ const {
|
||||
router,
|
||||
currentSessionId,
|
||||
selectSession: sessionStore.selectSession,
|
||||
defaultTab: settingsStore.defaultSessionTab,
|
||||
defaultTab:
|
||||
IS_WEB_WASM && settingsStore.defaultSessionTab === 'memory' ? 'insights' : settingsStore.defaultSessionTab,
|
||||
validTabIds: tabs.map((tab) => tab.id),
|
||||
})
|
||||
|
||||
|
||||
@@ -80,7 +80,8 @@ const {
|
||||
router,
|
||||
currentSessionId,
|
||||
selectSession: sessionStore.selectSession,
|
||||
defaultTab: settingsStore.defaultSessionTab,
|
||||
defaultTab:
|
||||
IS_WEB_WASM && settingsStore.defaultSessionTab === 'memory' ? 'insights' : settingsStore.defaultSessionTab,
|
||||
validTabIds: tabs.map((tab) => tab.id),
|
||||
})
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ export const useSettingsStore = defineStore(
|
||||
() => {
|
||||
const locale = ref<LocaleType>(getLocale())
|
||||
|
||||
const defaultSessionTab = ref<'insights' | 'ai-chat'>('insights')
|
||||
const defaultSessionTab = ref<'insights' | 'ai-chat' | 'memory'>('insights')
|
||||
|
||||
const insightCardTheme = ref<InsightCardThemeId>(DEFAULT_INSIGHT_CARD_THEME)
|
||||
|
||||
|
||||
Reference in new issue
Block a user