hermes-agent/apps/desktop/src/lib/session-export.ts

57 lines
1.7 KiB
TypeScript

import type { SessionInfo } from '@/hermes'
import { getSessionMessages } from '@/hermes'
import { translateNow } from '@/i18n'
import { notify, notifyError } from '@/store/notifications'
interface ExportSessionParams {
sessionId: string
title?: string | null
session?: SessionInfo
}
function sanitizeFilenamePart(value: string) {
return value
.trim()
.toLowerCase()
.replace(/[^a-z0-9._-]+/g, '-')
.replace(/^-+|-+$/g, '')
.slice(0, 48)
}
function sessionExportFilename(sessionId: string, title?: string | null) {
const titlePart = title ? sanitizeFilenamePart(title) : ''
const idPart = sanitizeFilenamePart(sessionId).slice(0, 8) || 'session'
return `${titlePart || 'session'}-${idPart}.json`
}
export async function exportSession(sessionId: string, params: Omit<ExportSessionParams, 'sessionId'> = {}) {
if (!sessionId) {
return
}
try {
const { messages } = await getSessionMessages(sessionId)
const payload = {
exported_at: new Date().toISOString(),
session_id: sessionId,
title: params.title ?? null,
session: params.session ?? null,
message_count: messages.length,
messages
}
const blob = new Blob([JSON.stringify(payload, null, 2)], { type: 'application/json' })
const downloadUrl = URL.createObjectURL(blob)
const anchor = document.createElement('a')
anchor.href = downloadUrl
anchor.download = sessionExportFilename(sessionId, params.title)
anchor.click()
URL.revokeObjectURL(downloadUrl)
notify({ kind: 'success', message: translateNow('desktop.sessionExported'), durationMs: 2_000 })
} catch (err) {
notifyError(err, translateNow('desktop.sessionExportFailed'))
}
}