feat: add History page for browsing Hermes sessions (v0.5.5) (#370)
Features: - Add dedicated History page for browsing Hermes session history - Independent session state (does not interfere with active chat) - Auto-select first CLI session on page load - Filter out api_server and cron sources Components: - New HistoryView.vue with isolated state management - New HistoryMessageList.vue with session prop support - Filters empty content and tool messages without toolName Backend: - Add GET /api/hermes/sessions/hermes endpoint (excludes api_server) - Add GET /api/hermes/sessions/hermes/:id endpoint (404s for api_server) - Add fetchHermesSessions() and fetchHermesSession() API functions Cleanup: - Remove localStorage session caching - Simplify profile switching cache management - Clean up废弃 cache cleanup calls i18n: - Add "History" translation to all 8 locales - Add v0.5.5 changelog entries in all languages - 🎉 Happy Labor Day! Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -215,14 +215,13 @@ function isQuotaExceededError(error: unknown): boolean {
|
||||
|
||||
function recoverStorageQuota() {
|
||||
try {
|
||||
// 清理所有会话相关的旧缓存(已完全废弃)
|
||||
const prefixes = [
|
||||
`hermes_session_msgs_v1_${getProfileName()}_`,
|
||||
`hermes_in_flight_v1_${getProfileName()}_`,
|
||||
'hermes_sessions_cache_v1_',
|
||||
'hermes_session_msgs_v1_',
|
||||
'hermes_session_pins_v1_',
|
||||
'hermes_human_only_v1_',
|
||||
]
|
||||
if (getProfileName() === 'default') {
|
||||
prefixes.push('hermes_session_msgs_v1_')
|
||||
prefixes.push('hermes_in_flight_v1_')
|
||||
}
|
||||
const keysToRemove: string[] = []
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i)
|
||||
@@ -233,6 +232,9 @@ function recoverStorageQuota() {
|
||||
}
|
||||
}
|
||||
keysToRemove.forEach(key => removeItem(key))
|
||||
if (keysToRemove.length > 0) {
|
||||
console.log(`Recovered storage: cleared ${keysToRemove.length} old session cache entries`)
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
@@ -538,6 +540,17 @@ export const useChatStore = defineStore('chat', () => {
|
||||
if (s) s.messages.push(msg)
|
||||
}
|
||||
|
||||
function addOrUpdateSession(session: Session) {
|
||||
const existingIndex = sessions.value.findIndex(s => s.id === session.id)
|
||||
if (existingIndex !== -1) {
|
||||
// Update existing session
|
||||
sessions.value[existingIndex] = session
|
||||
} else {
|
||||
// Add new session
|
||||
sessions.value.push(session)
|
||||
}
|
||||
}
|
||||
|
||||
function updateMessage(sessionId: string, id: string, update: Partial<Message>) {
|
||||
const s = sessions.value.find(s => s.id === sessionId)
|
||||
if (!s) return
|
||||
@@ -1346,6 +1359,7 @@ export const useChatStore = defineStore('chat', () => {
|
||||
newChat,
|
||||
switchSession,
|
||||
switchSessionModel,
|
||||
addOrUpdateSession,
|
||||
clearProviderFromSessions,
|
||||
deleteSession,
|
||||
sendMessage,
|
||||
|
||||
@@ -24,6 +24,8 @@ export const useProfilesStore = defineStore('profiles', () => {
|
||||
activeProfileName.value = activeProfile.value.name
|
||||
localStorage.setItem(ACTIVE_PROFILE_STORAGE_KEY, activeProfile.value.name)
|
||||
}
|
||||
// 清理所有会话缓存(不再使用 localStorage 缓存)
|
||||
clearAllSessionCaches()
|
||||
} catch (err) {
|
||||
console.error('Failed to fetch profiles:', err)
|
||||
} finally {
|
||||
@@ -52,31 +54,15 @@ export const useProfilesStore = defineStore('profiles', () => {
|
||||
const ok = await profilesApi.deleteProfile(name)
|
||||
if (ok) {
|
||||
delete detailMap.value[name]
|
||||
// 清理该 profile 的 localStorage 缓存
|
||||
clearProfileCache(name)
|
||||
await fetchProfiles()
|
||||
}
|
||||
return ok
|
||||
}
|
||||
|
||||
// 清理指定 profile 的所有 localStorage 缓存(精确匹配缓存 key 前缀)
|
||||
function clearProfileCache(profileName: string) {
|
||||
const prefixes = [
|
||||
`hermes_sessions_cache_v1_${profileName}`,
|
||||
`hermes_session_msgs_v1_${profileName}_`,
|
||||
`hermes_in_flight_v1_${profileName}_`,
|
||||
`hermes_active_session_${profileName}`,
|
||||
`hermes_session_pins_v1_${profileName}`,
|
||||
`hermes_human_only_v1_${profileName}`,
|
||||
]
|
||||
const keysToRemove: string[] = []
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i)
|
||||
if (key && prefixes.some(p => key.startsWith(p))) {
|
||||
keysToRemove.push(key)
|
||||
}
|
||||
}
|
||||
keysToRemove.forEach(key => localStorage.removeItem(key))
|
||||
// 清理所有 profile 的会话缓存
|
||||
function clearAllSessionCaches() {
|
||||
// 注意:不再清理任何缓存,因为已经不再使用 localStorage 缓存会话数据
|
||||
// 所有会话数据都从服务器实时获取
|
||||
}
|
||||
|
||||
async function renameProfile(name: string, newName: string) {
|
||||
@@ -124,5 +110,6 @@ export const useProfilesStore = defineStore('profiles', () => {
|
||||
switchProfile,
|
||||
exportProfile,
|
||||
importProfile,
|
||||
clearAllSessionCaches,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user