fix: restore Hermes session history listing (#716)
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hermes-web-ui",
|
||||
"version": "0.5.21",
|
||||
"version": "0.5.22",
|
||||
"description": "Self-hosted AI chat dashboard for Hermes Agent — multi-model web UI with multi-platform integration",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -5,6 +5,13 @@ export interface ChangelogEntry {
|
||||
}
|
||||
|
||||
export const changelog: ChangelogEntry[] = [
|
||||
{
|
||||
version: '0.5.22',
|
||||
date: '2026-05-14',
|
||||
changes: [
|
||||
'changelog.new_0_5_22_1',
|
||||
],
|
||||
},
|
||||
{
|
||||
version: '0.5.21',
|
||||
date: '2026-05-14',
|
||||
|
||||
@@ -853,6 +853,7 @@ jobTriggered: 'Job ausgelost',
|
||||
new_0_5_18_7: 'Docker single-container deployment with docker-compose and gateway startup fixes',
|
||||
new_0_5_18_8: 'Fix plugins page HERMES_HOME fallback warning for non-default profiles',
|
||||
new_0_5_18_9: 'Fix gateway stability across dev restarts and improve Windows compatibility',
|
||||
new_0_5_22_1: 'Fix Hermes session list API reading the Web UI local session store instead of the Hermes profile database',
|
||||
new_0_5_13_1: 'Nachrichtenwarteschlange für sequenzielle Run-Verarbeitung hinzugefügt, um gleichzeitige Konflikte zu vermeiden',
|
||||
new_0_5_13_2: 'Zwei-Ebenen-Skills-Verzeichnisstruktur mit Sonstige-Kategorie für flache Skills unterstützt',
|
||||
new_0_5_13_3: 'Temporäre Sitzungen (eph_*) beim Start-Sync filtern, um interne Sitzungen nicht zu importieren',
|
||||
|
||||
@@ -1129,6 +1129,7 @@ export default {
|
||||
new_0_5_18_7: 'Docker single-container deployment with docker-compose and gateway startup fixes',
|
||||
new_0_5_18_8: 'Fix plugins page HERMES_HOME fallback warning for non-default profiles',
|
||||
new_0_5_18_9: 'Fix gateway stability across dev restarts and improve Windows compatibility',
|
||||
new_0_5_22_1: 'Fix Hermes session list API reading the Web UI local session store instead of the Hermes profile database',
|
||||
|
||||
new_0_5_13_1: 'Add message queue for sequential run processing to prevent concurrent request conflicts',
|
||||
new_0_5_13_2: 'Support two-level skills directory structure with misc category for flat skills',
|
||||
|
||||
@@ -849,6 +849,7 @@ jobTriggered: 'Job ejecutado',
|
||||
new_0_5_18_7: 'Docker single-container deployment with docker-compose and gateway startup fixes',
|
||||
new_0_5_18_8: 'Fix plugins page HERMES_HOME fallback warning for non-default profiles',
|
||||
new_0_5_18_9: 'Fix gateway stability across dev restarts and improve Windows compatibility',
|
||||
new_0_5_22_1: 'Fix Hermes session list API reading the Web UI local session store instead of the Hermes profile database',
|
||||
new_0_5_13_1: 'Cola de mensajes para procesamiento secuencial de ejecuciones, evitando conflictos concurrentes',
|
||||
new_0_5_13_2: 'Soporte para estructura de directorios de skills de dos niveles con categoría misc',
|
||||
new_0_5_13_3: 'Filtrar sesiones efímeras (eph_*) durante la sincronización de inicio',
|
||||
|
||||
@@ -848,6 +848,7 @@ jobTriggered: 'Job declenche',
|
||||
new_0_5_18_7: 'Docker single-container deployment with docker-compose and gateway startup fixes',
|
||||
new_0_5_18_8: 'Fix plugins page HERMES_HOME fallback warning for non-default profiles',
|
||||
new_0_5_18_9: 'Fix gateway stability across dev restarts and improve Windows compatibility',
|
||||
new_0_5_22_1: 'Fix Hermes session list API reading the Web UI local session store instead of the Hermes profile database',
|
||||
new_0_5_13_1: 'File d\'attente de messages pour le traitement séquentiel des exécutions, évitant les conflits concurrents',
|
||||
new_0_5_13_2: 'Prise en charge de la structure de répertoire de skills à deux niveaux avec catégorie divers',
|
||||
new_0_5_13_3: 'Filtrer les sessions éphémères (eph_*) lors de la synchronisation au démarrage',
|
||||
|
||||
@@ -849,6 +849,7 @@ export default {
|
||||
new_0_5_18_7: 'Docker single-container deployment with docker-compose and gateway startup fixes',
|
||||
new_0_5_18_8: 'Fix plugins page HERMES_HOME fallback warning for non-default profiles',
|
||||
new_0_5_18_9: 'Fix gateway stability across dev restarts and improve Windows compatibility',
|
||||
new_0_5_22_1: 'Fix Hermes session list API reading the Web UI local session store instead of the Hermes profile database',
|
||||
new_0_5_13_1: 'メッセージキューによる順次実行処理で同時リクエストの競合を防止',
|
||||
new_0_5_13_2: '2階層スキルディレクトリ構造をサポート、フラットスキルは「その他」カテゴリに分類',
|
||||
new_0_5_13_3: '起動同期時に一時セッション(eph_*)をフィルタリング',
|
||||
|
||||
@@ -849,6 +849,7 @@ export default {
|
||||
new_0_5_18_7: 'Docker single-container deployment with docker-compose and gateway startup fixes',
|
||||
new_0_5_18_8: 'Fix plugins page HERMES_HOME fallback warning for non-default profiles',
|
||||
new_0_5_18_9: 'Fix gateway stability across dev restarts and improve Windows compatibility',
|
||||
new_0_5_22_1: 'Fix Hermes session list API reading the Web UI local session store instead of the Hermes profile database',
|
||||
new_0_5_13_1: '메시지 큐를 통한 순차 실행 처리로 동시 요청 충돌 방지',
|
||||
new_0_5_13_2: '2단계 스킬 디렉토리 구조 지원, 플랫 스킬은 기타 카테고리로 분류',
|
||||
new_0_5_13_3: '시작 동기화 시 임시 세션(eph_*) 필터링',
|
||||
|
||||
@@ -849,6 +849,7 @@ jobTriggered: 'Job acionado',
|
||||
new_0_5_18_7: 'Docker single-container deployment with docker-compose and gateway startup fixes',
|
||||
new_0_5_18_8: 'Fix plugins page HERMES_HOME fallback warning for non-default profiles',
|
||||
new_0_5_18_9: 'Fix gateway stability across dev restarts and improve Windows compatibility',
|
||||
new_0_5_22_1: 'Fix Hermes session list API reading the Web UI local session store instead of the Hermes profile database',
|
||||
new_0_5_13_1: 'Fila de mensagens para processamento sequencial de execuções, evitando conflitos concorrentes',
|
||||
new_0_5_13_2: 'Suporte à estrutura de diretório de skills de dois níveis com categoria diversos',
|
||||
new_0_5_13_3: 'Filtrar sessões efêmeras (eph_*) durante a sincronização na inicialização',
|
||||
|
||||
@@ -1131,6 +1131,7 @@ export default {
|
||||
new_0_5_18_7: 'Docker single-container deployment with docker-compose and gateway startup fixes',
|
||||
new_0_5_18_8: 'Fix plugins page HERMES_HOME fallback warning for non-default profiles',
|
||||
new_0_5_18_9: 'Fix gateway stability across dev restarts and improve Windows compatibility',
|
||||
new_0_5_22_1: '修復 Hermes 會話列表介面錯誤讀取 Web UI 本地會話庫的問題',
|
||||
new_0_5_13_1: '新增訊息佇列,順序處理執行請求,避免並發衝突',
|
||||
new_0_5_13_2: '支援二級 Skills 目錄結構,扁平化 Skill 歸入「雜項」分類',
|
||||
new_0_5_13_3: '啟動同步時過濾暫時工作階段(eph_*),避免匯入內部工作階段',
|
||||
|
||||
@@ -1131,6 +1131,7 @@ export default {
|
||||
new_0_5_18_7: 'Docker 单容器部署,更新 docker-compose 配置并修复 gateway 启动问题',
|
||||
new_0_5_18_8: '修复插件页面非默认 profile 下 HERMES_HOME fallback 警告',
|
||||
new_0_5_18_9: '修复 dev 模式重启时网关稳定性,改善 Windows 兼容性',
|
||||
new_0_5_22_1: '修复 Hermes 会话列表接口错误读取 Web UI 本地会话库的问题',
|
||||
|
||||
new_0_5_13_1: '新增消息队列,顺序处理运行请求,避免并发冲突',
|
||||
new_0_5_13_2: '支持二级 Skills 目录结构,扁平化 Skill 归入"杂项"分类',
|
||||
|
||||
@@ -114,7 +114,7 @@ export async function listHermesSessions(ctx: any) {
|
||||
const profile = getActiveProfileName()
|
||||
const effectiveLimit = limit && limit > 0 ? limit : 2000
|
||||
|
||||
const allSessions = localListSessions(profile, source, effectiveLimit)
|
||||
const allSessions = await listSessionSummaries(source, effectiveLimit, profile)
|
||||
ctx.body = { sessions: filterPendingDeletedSessions(allSessions.filter(s => s.source !== 'api_server')) }
|
||||
}
|
||||
|
||||
|
||||
@@ -86,18 +86,19 @@ function normalizeNullableString(value: unknown): string | null {
|
||||
return String(value)
|
||||
}
|
||||
|
||||
function titleFromPreview(preview: string): string | null {
|
||||
if (!preview) return null
|
||||
return preview.length > 40 ? `${preview.slice(0, 40)}...` : preview
|
||||
}
|
||||
|
||||
function mapRow(row: Record<string, unknown>): HermesSessionRow {
|
||||
const startedAt = normalizeNumber(row.started_at)
|
||||
const rawTitle = normalizeNullableString(row.title)
|
||||
const preview = String(row.preview || '')
|
||||
// Fallback: when no explicit title, use first user message as title (same as CLI path)
|
||||
const title = rawTitle || (preview ? (preview.length > 40 ? preview.slice(0, 40) + '...' : preview) : null)
|
||||
return {
|
||||
id: String(row.id || ''),
|
||||
source: String(row.source || ''),
|
||||
user_id: normalizeNullableString(row.user_id),
|
||||
model: String(row.model || ''),
|
||||
title,
|
||||
title: normalizeNullableString(row.title),
|
||||
started_at: startedAt,
|
||||
ended_at: normalizeNullableNumber(row.ended_at),
|
||||
end_reason: normalizeNullableString(row.end_reason),
|
||||
@@ -373,12 +374,13 @@ function latestSessionInChain(chain: HermesSessionInternalRow[]): HermesSessionI
|
||||
|
||||
function projectSessionSummary(root: HermesSessionInternalRow, chain: HermesSessionInternalRow[]): HermesSessionRow {
|
||||
const latest = latestSessionInChain(chain)
|
||||
const firstPreview = chain.map(session => session.preview).find(Boolean) || root.preview
|
||||
const { parent_session_id: _parentSessionId, ...rootRow } = root
|
||||
return {
|
||||
...rootRow,
|
||||
id: latest.id,
|
||||
model: latest.model || root.model,
|
||||
title: latest.title || root.title,
|
||||
title: latest.title || root.title || titleFromPreview(firstPreview),
|
||||
ended_at: latest.ended_at,
|
||||
end_reason: latest.end_reason,
|
||||
message_count: latest.message_count,
|
||||
@@ -392,7 +394,7 @@ function projectSessionSummary(root: HermesSessionInternalRow, chain: HermesSess
|
||||
estimated_cost_usd: latest.estimated_cost_usd,
|
||||
actual_cost_usd: latest.actual_cost_usd,
|
||||
cost_status: latest.cost_status,
|
||||
preview: latest.preview || root.preview,
|
||||
preview: latest.preview || root.preview || firstPreview || '',
|
||||
last_active: latest.last_active || root.last_active,
|
||||
}
|
||||
}
|
||||
@@ -543,7 +545,7 @@ function aggregateSessionDetail(
|
||||
...rootRow,
|
||||
id: requestedSessionId,
|
||||
source: latest.source || root.source,
|
||||
title: latest.title || root.title || (firstPreview ? (firstPreview.length > 40 ? `${firstPreview.slice(0, 40)}...` : firstPreview) : null),
|
||||
title: latest.title || root.title || titleFromPreview(firstPreview),
|
||||
preview: latest.preview || root.preview || firstPreview || '',
|
||||
model: latest.model || root.model,
|
||||
ended_at: latest.ended_at,
|
||||
|
||||
Reference in New Issue
Block a user