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:
@@ -1,6 +1,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import { fetchSessions, fetchMessages, deleteSession, streamChat, type SessionInfo, type Source } from '../api/client'
|
||||
import { fetchSessions, fetchMessages, deleteSession, exportSession, importSession, streamChat, type SessionInfo, type Source, type ImportPayload } from '../api/client'
|
||||
|
||||
export interface Message {
|
||||
role: 'user' | 'assistant'
|
||||
@@ -69,6 +69,32 @@ export const useChatStore = defineStore('chat', () => {
|
||||
await loadSessions()
|
||||
}
|
||||
|
||||
function downloadSessionLog(sessionId: string): void {
|
||||
exportSession(sessionId)
|
||||
}
|
||||
|
||||
async function importSessionFromFile(file: File): Promise<void> {
|
||||
let payload: ImportPayload
|
||||
try {
|
||||
const parsed = JSON.parse(await file.text())
|
||||
if (!Array.isArray(parsed?.messages)) {
|
||||
throw new Error('messages 配列が見つかりません')
|
||||
}
|
||||
payload = parsed as ImportPayload
|
||||
} catch (e) {
|
||||
pushToast(`インポート失敗: JSONの読み込みに失敗しました (${e instanceof Error ? e.message : e})`)
|
||||
return
|
||||
}
|
||||
try {
|
||||
const session = await importSession(payload)
|
||||
await loadSessions()
|
||||
await selectSession(session.id)
|
||||
pushToast(`「${session.title}」をインポートしました`)
|
||||
} catch (e) {
|
||||
pushToast(`インポート失敗: ${e instanceof Error ? e.message : e}`)
|
||||
}
|
||||
}
|
||||
|
||||
function sendMessage(text: string): void {
|
||||
if (isStreaming.value || !text.trim()) return
|
||||
|
||||
@@ -137,6 +163,8 @@ export const useChatStore = defineStore('chat', () => {
|
||||
loadSessions,
|
||||
selectSession,
|
||||
removeSession,
|
||||
downloadSessionLog,
|
||||
importSessionFromFile,
|
||||
sendMessage,
|
||||
retryMessage,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user