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:
@@ -160,6 +160,26 @@ export async function list(ctx: any) {
|
||||
ctx.body = { sessions: filterPendingDeletedSessions(sessions) }
|
||||
}
|
||||
|
||||
/**
|
||||
* List Hermes sessions only (exclude api_server source)
|
||||
* GET /api/hermes/sessions/hermes?source=&limit=
|
||||
*/
|
||||
export async function listHermesSessions(ctx: any) {
|
||||
const source = (ctx.query.source as string) || undefined
|
||||
const limit = ctx.query.limit ? parseInt(ctx.query.limit as string, 10) : undefined
|
||||
|
||||
try {
|
||||
const sessions = await listSessionSummaries(source, limit && limit > 0 ? limit : 2000)
|
||||
ctx.body = { sessions: filterPendingDeletedSessions(sessions.filter(s => s.source !== 'api_server' && s.source !== 'cron')) }
|
||||
return
|
||||
} catch (err) {
|
||||
logger.warn(err, 'Hermes Session DB: summary query failed, falling back to CLI')
|
||||
}
|
||||
|
||||
const sessions = await hermesCli.listSessions(source, limit)
|
||||
ctx.body = { sessions: filterPendingDeletedSessions(sessions.filter(s => s.source !== 'api_server')) }
|
||||
}
|
||||
|
||||
export async function search(ctx: any) {
|
||||
if (useLocalSessionStore()) {
|
||||
const q = typeof ctx.query.q === 'string' ? ctx.query.q : ''
|
||||
@@ -207,6 +227,27 @@ export async function get(ctx: any) {
|
||||
ctx.body = { session }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Hermes session detail only (exclude api_server source)
|
||||
* GET /api/hermes/sessions/hermes/:id
|
||||
*/
|
||||
export async function getHermesSession(ctx: any) {
|
||||
|
||||
const session = await hermesCli.getSession(ctx.params.id)
|
||||
if (!session) {
|
||||
ctx.status = 404
|
||||
ctx.body = { error: 'Session not found' }
|
||||
return
|
||||
}
|
||||
// Filter out api_server sessions
|
||||
if (session.source === 'api_server') {
|
||||
ctx.status = 404
|
||||
ctx.body = { error: 'Session not found' }
|
||||
return
|
||||
}
|
||||
ctx.body = { session }
|
||||
}
|
||||
|
||||
export async function remove(ctx: any) {
|
||||
if (useLocalSessionStore()) {
|
||||
const sessionId = ctx.params.id
|
||||
|
||||
@@ -7,6 +7,8 @@ sessionRoutes.get('/api/hermes/sessions/conversations', ctrl.listConversations)
|
||||
sessionRoutes.get('/api/hermes/sessions/conversations/:id/messages', ctrl.getConversationMessages)
|
||||
sessionRoutes.get('/api/hermes/sessions/conversations/:id/messages/paginated', ctrl.getConversationMessagesPaginated)
|
||||
sessionRoutes.get('/api/hermes/sessions', ctrl.list)
|
||||
sessionRoutes.get('/api/hermes/sessions/hermes', ctrl.listHermesSessions)
|
||||
sessionRoutes.get('/api/hermes/sessions/hermes/:id', ctrl.getHermesSession)
|
||||
sessionRoutes.get('/api/hermes/search/sessions', ctrl.search)
|
||||
sessionRoutes.get('/api/hermes/sessions/search', ctrl.search)
|
||||
sessionRoutes.get('/api/hermes/sessions/usage', ctrl.usageBatch)
|
||||
|
||||
Reference in New Issue
Block a user