File size: 2,817 Bytes
e5faeaf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | import { useState } from 'react'
import { X, Download } from 'lucide-react'
import { useAgentStore } from '../store/agentStore'
export default function ExportDialog({ onClose }) {
const [includeErrors, setIncludeErrors] = useState(true)
const messages = useAgentStore((state) => state.messages)
const handleExport = () => {
const rows = messages
.filter((m) => includeErrors || !(typeof m.content === 'string' && m.content.startsWith('⚠️')))
.map((m) => {
const row = { role: m.role, content: m.content || '' }
if (m.tool_call_id) row.tool_call_id = m.tool_call_id
if (m.name) row.name = m.name
if (m.tool_calls?.length) {
row.tool_calls = m.tool_calls.map((c) => ({
id: c.id,
type: c.type,
function: { name: c.function?.name, arguments: c.function?.arguments },
}))
}
return row
})
const dataStr = JSON.stringify(
{
timestamp: new Date().toISOString(),
source: 'Agent Studio (Agent 頁)',
messages: rows,
},
null,
2,
)
const blob = new Blob([dataStr], { type: 'application/json' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = `agent-conversation-${new Date().toISOString().slice(0, 10)}.json`
a.click()
URL.revokeObjectURL(url)
onClose()
}
const isEmpty = messages.length === 0
return (
<div className="fixed inset-0 bg-black/80 flex items-center justify-center z-50">
<div className="bg-panel p-8 rounded-3xl w-full max-w-md border border-edge">
<div className="flex justify-between items-center mb-6">
<h3 className="text-2xl font-bold">匯出對話</h3>
<button onClick={onClose} className="text-muted hover:text-ink">
<X className="w-5 h-5" />
</button>
</div>
<div className="space-y-5">
<p className="text-sm text-muted">
共 {messages.length} 則訊息(只匯出 Agent 頁,聊天頁是獨立對話)。
</p>
<label className="flex items-center gap-3 text-sm">
<input
type="checkbox"
checked={includeErrors}
onChange={(e) => setIncludeErrors(e.target.checked)}
className="w-4 h-4"
/>
包含錯誤訊息(⚠️ 開頭的內容)
</label>
<button
onClick={handleExport}
disabled={isEmpty}
className="w-full flex items-center justify-center gap-2 bg-purple-600 py-3 rounded-2xl font-medium disabled:opacity-40"
>
<Download className="w-4 h-4" /> 下載 JSON
</button>
</div>
</div>
</div>
)
}
|