Add session export/import as JSON

Sessions can now be downloaded as a JSON file containing the session
metadata and every message with its tags, and re-imported as a new
session from that same format.

GET /chat/sessions/{id}/export streams the session as a file download.
POST /chat/sessions/import validates the roles, then recreates the
session under a fresh UUID so importing never collides with an existing
session. The sidebar gets a per-row download button and an import button
that feeds a hidden file input.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 01:22:08 +09:00
co-authored by Claude Opus 5
parent 1ad8b130c7
commit ef588d99d8
4 changed files with 192 additions and 5 deletions
+33
View File
@@ -63,6 +63,39 @@ export async function deleteSession(sessionId: string): Promise<void> {
await fetch(`${BASE}/chat/sessions/${sessionId}`, { method: 'DELETE' })
}
export function exportSession(sessionId: string): void {
const a = document.createElement('a')
a.href = `${BASE}/chat/sessions/${sessionId}/export`
a.download = `session_${sessionId}.json`
document.body.appendChild(a)
a.click()
a.remove()
}
export interface ImportPayload {
session?: {
title?: string | null
model?: string | null
created_at?: string | null
updated_at?: string | null
}
messages: {
role: string
content: string
created_at?: string | null
tags?: string[]
}[]
}
export async function importSession(payload: ImportPayload): Promise<SessionInfo> {
const res = await fetch(`${BASE}/chat/sessions/import`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
})
return parseJson<SessionInfo>(res, 'インポート')
}
export async function fetchLogs(params: {
session_id?: string
status?: 'ok' | 'error'