ai-agent-router 0.1.21 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +2 -2
- package/.next/fallback-build-manifest.json +2 -2
- package/.next/server/app/_global-error.html +2 -2
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/gateway/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/gateway/models/route.js.nft.json +1 -1
- package/.next/server/app/api/gateway/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/apply/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/available-models/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/save/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/status/route.js.nft.json +1 -1
- package/.next/server/app/api/ide/claude/test/route.js.nft.json +1 -1
- package/.next/server/app/api/logs/route.js.nft.json +1 -1
- package/.next/server/app/api/models/route.js.nft.json +1 -1
- package/.next/server/app/api/providers/route.js.nft.json +1 -1
- package/.next/server/app/api/providers/test/route.js.nft.json +1 -1
- package/.next/server/app/api/service/force-stop/route.js.nft.json +1 -1
- package/.next/server/app/api/service/start/route.js.nft.json +1 -1
- package/.next/server/app/api/service/status/route.js.nft.json +1 -1
- package/.next/server/app/api/service/stop/route.js.nft.json +1 -1
- package/.next/server/app/ide.html +1 -1
- package/.next/server/app/ide.rsc +1 -1
- package/.next/server/app/ide.segments/_full.segment.rsc +1 -1
- package/.next/server/app/ide.segments/_head.segment.rsc +1 -1
- package/.next/server/app/ide.segments/_index.segment.rsc +1 -1
- package/.next/server/app/ide.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/ide.segments/ide/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/ide.segments/ide.segment.rsc +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +1 -1
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +1 -1
- package/.next/server/app/logs.rsc +2 -2
- package/.next/server/app/logs.segments/_full.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/logs.segments/_index.segment.rsc +1 -1
- package/.next/server/app/logs.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs.segment.rsc +1 -1
- package/.next/server/app/models.html +1 -1
- package/.next/server/app/models.rsc +1 -1
- package/.next/server/app/models.segments/_full.segment.rsc +1 -1
- package/.next/server/app/models.segments/_head.segment.rsc +1 -1
- package/.next/server/app/models.segments/_index.segment.rsc +1 -1
- package/.next/server/app/models.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/models.segments/models/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/models.segments/models.segment.rsc +1 -1
- package/.next/server/app/providers.html +1 -1
- package/.next/server/app/providers.rsc +1 -1
- package/.next/server/app/providers.segments/_full.segment.rsc +1 -1
- package/.next/server/app/providers.segments/_head.segment.rsc +1 -1
- package/.next/server/app/providers.segments/_index.segment.rsc +1 -1
- package/.next/server/app/providers.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/providers.segments/providers/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/providers.segments/providers.segment.rsc +1 -1
- package/.next/server/chunks/[root-of-the-server]__1480f018._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1480f018._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__1909f3aa._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1909f3aa._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__1d4b7fc5._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1d4b7fc5._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__372ef2bf._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__372ef2bf._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__3aaf963c._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__3aaf963c._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__6ce199d2._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__6ce199d2._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__772134c6._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__772134c6._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__7b77f523._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__7b77f523._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__c1b4b601._.js +18 -18
- package/.next/server/chunks/[root-of-the-server]__c1b4b601._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__ccfc7f1d._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__ccfc7f1d._.js.map +1 -1
- package/.next/server/chunks/ssr/src_app_logs_page_tsx_7b7b7b83._.js +1 -1
- package/.next/server/chunks/ssr/src_app_logs_page_tsx_7b7b7b83._.js.map +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +2 -2
- package/.next/static/chunks/{81c904164fe81379.js → b6b258e8582e47c4.js} +1 -1
- package/README.md +100 -111
- package/dist/src/app/api/gateway/[...path]/route.js +1 -1
- package/dist/src/app/api/gateway/route.js +1 -1
- package/dist/src/app/api/logs/route.js +2 -2
- package/dist/src/app/api/models/route.js +5 -5
- package/dist/src/app/api/providers/route.js +4 -4
- package/dist/src/app/api/providers/test/route.js +1 -1
- package/dist/src/app/api/service/start/route.js +1 -1
- package/dist/src/app/api/service/status/route.js +1 -1
- package/dist/src/app/api/service/stop/route.js +1 -1
- package/dist/src/app/logs/page.js +13 -1
- package/dist/src/cli/index.js +218 -20
- package/dist/src/db/database.js +35 -1
- package/dist/src/db/queries.js +6 -6
- package/dist/src/server/logger.js +22 -4
- package/package.json +2 -1
- package/src/app/api/gateway/[...path]/route.ts +1 -1
- package/src/app/api/gateway/route.ts +1 -1
- package/src/app/api/logs/route.ts +2 -2
- package/src/app/api/models/route.ts +5 -5
- package/src/app/api/providers/route.ts +4 -4
- package/src/app/api/providers/test/route.ts +1 -1
- package/src/app/api/service/start/route.ts +1 -1
- package/src/app/api/service/status/route.ts +1 -1
- package/src/app/api/service/stop/route.ts +1 -1
- package/src/app/logs/page.tsx +15 -5
- package/src/cli/index.ts +228 -25
- package/src/db/database.ts +34 -4
- package/src/db/queries.ts +6 -6
- package/src/server/logger.ts +19 -4
- /package/.next/static/{PkfqdzwOZgX-UhSNUuhdp → ryTeHAYUvjT1bYolc-x9Z}/_buildManifest.js +0 -0
- /package/.next/static/{PkfqdzwOZgX-UhSNUuhdp → ryTeHAYUvjT1bYolc-x9Z}/_clientMiddlewareManifest.json +0 -0
- /package/.next/static/{PkfqdzwOZgX-UhSNUuhdp → ryTeHAYUvjT1bYolc-x9Z}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app/logs/page.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport Nav from '../components/Nav';\nimport { useToast } from '../components/ToastProvider';\nimport ConfirmDialog from '../components/ConfirmDialog';\n\ninterface RequestLog {\n id: number;\n model_id: number;\n model_name?: string;\n provider_name?: string;\n request_method: string;\n request_path: string;\n request_headers: string;\n request_query: string;\n request_body: string;\n response_status: number;\n response_body: string;\n response_time_ms: number;\n created_at: string;\n}\n\nexport default function LogsPage() {\n const [logs, setLogs] = useState<RequestLog[]>([]);\n const [selectedLog, setSelectedLog] = useState<RequestLog | null>(null);\n const [loading, setLoading] = useState(true);\n const [page, setPage] = useState(0);\n const [total, setTotal] = useState(0);\n const [selectedIds, setSelectedIds] = useState<number[]>([]);\n const [selectAll, setSelectAll] = useState(false);\n const [confirmDialog, setConfirmDialog] = useState<{ open: boolean; title: string; message: string; onConfirm: () => void } | null>(null);\n const [searchQuery, setSearchQuery] = useState('');\n const [searchInput, setSearchInput] = useState('');\n const limit = 50;\n const { showToast } = useToast();\n\n const copyToClipboard = async (text: string) => {\n try {\n await navigator.clipboard.writeText(text);\n showToast('已复制到剪贴板', 'success');\n } catch {\n showToast('复制失败,请手动复制', 'error');\n }\n };\n\n const handleDeleteSelected = async () => {\n if (selectedIds.length === 0) return;\n setConfirmDialog({\n open: true,\n title: '删除确认',\n message: `确定要删除选中的 ${selectedIds.length} 条日志吗?`,\n onConfirm: async () => {\n try {\n const res = await fetch(`/api/logs?ids=${selectedIds.join(',')}`, { method: 'DELETE' });\n const data = await res.json();\n if (res.ok) {\n setSelectedIds([]);\n setSelectAll(false);\n loadLogs();\n showToast('删除成功', 'success');\n setConfirmDialog(null);\n } else {\n showToast('删除失败:' + (data.error || '未知错误'), 'error');\n }\n } catch (error) {\n console.error('Failed to delete logs:', error);\n showToast('删除失败', 'error');\n }\n },\n });\n };\n\n const handleClearAll = async () => {\n setConfirmDialog({\n open: true,\n title: '清空日志',\n message: '确定要清空所有日志吗?此操作不可恢复!',\n onConfirm: async () => {\n try {\n const res = await fetch('/api/logs?clear_all=true', { method: 'DELETE' });\n const data = await res.json();\n if (res.ok) {\n setPage(0);\n setSelectedIds([]);\n setSelectAll(false);\n loadLogs();\n showToast('清空成功', 'success');\n setConfirmDialog(null);\n } else {\n showToast('清空失败:' + (data.error || '未知错误'), 'error');\n }\n } catch (error) {\n console.error('Failed to clear logs:', error);\n showToast('清空失败', 'error');\n }\n },\n });\n };\n\n const handleSelectAll = (checked: boolean) => {\n setSelectAll(checked);\n setSelectedIds(checked ? logs.map(log => log.id) : []);\n };\n\n const handleSelectLog = (id: number, checked: boolean) => {\n if (checked) {\n setSelectedIds([...selectedIds, id]);\n } else {\n setSelectedIds(selectedIds.filter(sid => sid !== id));\n setSelectAll(false);\n }\n };\n\n const loadLogs = async (search?: string) => {\n try {\n setLoading(true);\n const params = new URLSearchParams({\n limit: limit.toString(),\n offset: (page * limit).toString(),\n });\n if (search) {\n params.set('search', search);\n }\n const res = await fetch(`/api/logs?${params.toString()}`);\n const data = await res.json();\n setLogs(data.logs || []);\n setTotal(data.total || 0);\n } catch (error) {\n console.error('Failed to load logs:', error);\n showToast('加载日志失败', 'error');\n } finally {\n setLoading(false);\n }\n };\n\n // 手动触发搜索\n const handleSearch = () => {\n setSearchQuery(searchInput);\n setPage(0);\n loadLogs(searchInput);\n };\n\n // 清除搜索\n const clearSearch = () => {\n setSearchInput('');\n if (searchQuery) {\n setSearchQuery('');\n setPage(0);\n loadLogs();\n }\n };\n\n // 键盘搜索支持\n const handleKeyPress = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n handleSearch();\n }\n };\n\n useEffect(() => {\n loadLogs();\n }, [page, limit]);\n\n const formatJSONSimple = (jsonString: string): string => {\n return typeof jsonString === 'string' ? jsonString : JSON.stringify(jsonString);\n }\n\n const formatRespon = (str: string): string => {\n if (isStreamingResponse(str)) {\n return formatSSEStream(str);\n }\n return formatJSONSimple(str);\n }\n\n const formatSSEStream = (responseBody: any): string => {\n if (!responseBody) return '';\n\n let sseData: string;\n try {\n sseData = JSON.parse(responseBody);\n } catch {\n sseData = responseBody;\n }\n\n if (!sseData.includes('data:') || !sseData.includes('\\n\\n')) {\n try {\n const parsed = JSON.parse(sseData);\n return JSON.stringify(parsed);\n } catch {\n return String(sseData);\n }\n }\n\n const chunks = sseData.split('\\n\\n').filter(chunk => chunk.trim());\n const formattedChunks: string[] = [];\n\n for (const chunk of chunks) {\n let content = chunk.trim();\n let tmp = content.split(\"\\n\").map((line) => {\n return line.startsWith(\"data: \") ? line.substring(6) : line;\n });\n content = tmp.join(\"\\n\");\n if (content === 'data: [DONE]' || content === '[DONE]') {\n formattedChunks.push(content);\n } else {\n // event: content_block_stop\n // data: {\"type\": \"content_block_stop\", \"index\": 0}\n formattedChunks.push(content);\n }\n }\n return formattedChunks.join('\\n\\n');\n };\n\n // 检测是否为流式响应\n const isStreamingResponse = (responseBody: any): boolean => {\n if (!responseBody) return false;\n const bodyStr = responseBody;\n // OpenAI格式: data: {...}\\n\\ndata: {...}\\n\\n\n // Anthropic格式: event: xxx\\ndata: {...}\\n\\nevent: xxx\\ndata: {...}\\n\\n\n const hasDataMarkers = bodyStr.includes('data:');\n const hasNewlinePairs = bodyStr.includes('\\n\\n');\n const hasEventMarkers = bodyStr.includes('event:');\n return (hasDataMarkers || hasNewlinePairs) || hasEventMarkers;\n };\n\n const parseModelFromRequest = (query: string, body: string): string | null => {\n try {\n const parsedQuery = query ? JSON.parse(query) : {};\n const parsedBody = body ? JSON.parse(body) : {};\n\n const model = parsedBody.model || parsedQuery.model;\n\n // 处理可能为数组的情况(如 message 格式)\n if (Array.isArray(model)) {\n const lastMessage = model[model.length - 1];\n if (lastMessage && typeof lastMessage === 'object' && 'model' in lastMessage) {\n return lastMessage.model;\n }\n }\n\n return typeof model === 'string' ? model : null;\n } catch {\n return null;\n }\n };\n\n const getStatusColor = (status: number) => {\n if (status >= 200 && status < 300) return 'text-green-600';\n if (status >= 400 && status < 500) return 'text-yellow-600';\n if (status >= 500) return 'text-red-600';\n return 'text-gray-600';\n };\n\n if (loading) {\n return (\n <>\n <Nav />\n <div className=\"min-h-screen flex items-center justify-center\">\n <div className=\"text-lg\">加载中...</div>\n </div>\n </>\n );\n }\n\n return (\n <>\n <Nav />\n <main className=\"max-w-6xl mx-auto py-6 sm:px-6 lg:px-8\">\n <div className=\"px-4 py-4 sm:px-0\">\n <div className=\"mb-5 flex items-center justify-between\">\n <div>\n <h1 className=\"text-lg font-bold text-slate-800\">请求日志</h1>\n <p className=\"text-xs text-slate-500 mt-1\">查看所有 API 请求记录和响应详情</p>\n </div>\n <div className=\"flex gap-2 items-center\">\n {/* 搜索框 */}\n <div className=\"relative group\">\n <input\n type=\"text\"\n placeholder=\"搜索日志...\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n onKeyPress={handleKeyPress}\n className=\"w-64 pl-9 pr-20 py-1.5 text-xs border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-emerald-500/30 focus:border-emerald-500 transition-all\"\n />\n <svg\n className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n {/* 操作按钮 */}\n <div className=\"absolute right-2 top-1/2 -translate-y-1/2 flex items-center gap-1\">\n {searchInput ? (\n <>\n <button\n onClick={handleSearch}\n className=\"p-0.5 text-emerald-500 hover:text-emerald-600 hover:bg-emerald-50 rounded transition-colors\"\n title=\"确认搜索\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n </button>\n <button\n onClick={clearSearch}\n className=\"p-0.5 text-slate-400 hover:text-rose-500 hover:bg-rose-50 rounded transition-colors\"\n title=\"清除搜索\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </>\n ) : null}\n </div>\n </div>\n {selectedIds.length > 0 && (\n <button\n onClick={handleDeleteSelected}\n className=\"px-3 py-1.5 bg-rose-600 hover:bg-rose-700 text-white text-xs font-semibold rounded-lg border border-rose-200 transition-all duration-300\"\n >\n 删除选中 ({selectedIds.length})\n </button>\n )}\n <button\n onClick={handleClearAll}\n className=\"px-3 py-1.5 bg-slate-600 hover:bg-slate-700 text-white text-xs font-semibold rounded-lg border border-slate-200 transition-all duration-300\"\n >\n 清空所有\n </button>\n </div>\n </div>\n\n <div className=\"bg-white/70 backdrop-blur-sm shadow-md rounded-2xl border border-emerald-100/50 overflow-hidden\">\n <table className=\"min-w-full divide-y divide-slate-100\">\n <thead className=\"bg-emerald-50/30\">\n <tr>\n <th className=\"px-4 py-3.5 w-10\">\n <input\n type=\"checkbox\"\n checked={selectAll && logs.length > 0}\n onChange={(e) => handleSelectAll(e.target.checked)}\n className=\"w-4 h-4 rounded border-slate-300 text-emerald-600 focus:ring-emerald-500\"\n />\n </th>\n <th className=\"px-4 py-2.5 text-left text-xs font-semibold text-slate-600 uppercase tracking-wider\">\n 时间\n </th>\n <th className=\"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider\">\n 模型\n </th>\n <th className=\"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider\">\n 方法\n </th>\n <th className=\"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider\">\n 路径\n </th>\n <th className=\"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider\">\n 状态\n </th>\n <th className=\"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider\">\n 响应时间\n </th>\n <th className=\"px-6 py-3.5 text-right text-xs font-semibold text-gray-700 uppercase tracking-wider\">\n 操作\n </th>\n </tr>\n </thead>\n <tbody className=\"bg-white divide-y divide-slate-100\">\n {logs.length === 0 ? (\n <tr>\n <td colSpan={8} className=\"px-4 py-12 text-center\">\n <div className=\"text-slate-400\">\n <svg className=\"mx-auto h-10 w-10 mb-3 text-slate-300\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5} d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>\n <p className=\"text-xs text-slate-500\">\n {searchQuery ? '未找到匹配的日志' : '暂无日志记录'}\n </p>\n {searchQuery && (\n <button\n onClick={() => {\n setSearchInput('');\n setSearchQuery('');\n }}\n className=\"mt-2 text-xs text-emerald-600 hover:text-emerald-700\"\n >\n 清除搜索\n </button>\n )}\n </div>\n </td>\n </tr>\n ) : (\n logs.map((log) => {\n const parsedModel = parseModelFromRequest(log.request_query, log.request_body);\n const displayModel = parsedModel || log.model_name || 'Gateway';\n\n return (\n <tr key={log.id} className=\"hover:bg-emerald-50/20 transition-colors duration-300\">\n <td className=\"px-4 py-3\">\n <input\n type=\"checkbox\"\n checked={selectedIds.includes(log.id)}\n onChange={(e) => handleSelectLog(log.id, e.target.checked)}\n className=\"w-4 h-4 rounded border-slate-300 text-emerald-600 focus:ring-emerald-500\"\n onClick={(e) => e.stopPropagation()}\n />\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <div className=\"text-xs text-slate-600\">\n {/* 使用本地时区显示时间 */}\n {new Date(log.created_at + 'Z').toLocaleString('zh-CN')}\n </div>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <div className=\"text-xs\">\n <div className=\"font-medium text-slate-800\">{displayModel}</div>\n {log.provider_name && (\n <div className=\"text-[10px] text-slate-500\">{log.provider_name}</div>\n )}\n </div>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <span className={`px-2 py-0.5 inline-flex text-xs leading-4 font-semibold rounded-lg border ${log.request_method === 'GET' ? 'bg-sky-50 text-sky-700 border-sky-200/50' :\n log.request_method === 'POST' ? 'bg-emerald-50 text-emerald-700 border-emerald-200/50' :\n 'bg-slate-50 text-slate-600 border-slate-200/50'\n }`}>\n {log.request_method}\n </span>\n </td>\n <td className=\"px-4 py-3\">\n <div className=\"text-xs text-slate-600 font-mono max-w-xs truncate\">\n {log.request_path}\n </div>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <span className={`px-2 py-0.5 inline-flex text-xs leading-4 font-semibold rounded-full border ${log.response_status >= 200 && log.response_status < 300 ? 'bg-emerald-100/80 text-emerald-700 border-emerald-200/50' :\n log.response_status >= 400 && log.response_status < 500 ? 'bg-amber-100/80 text-amber-700 border-amber-200/50' :\n log.response_status >= 500 ? 'bg-rose-100/80 text-rose-700 border-rose-200/50' :\n 'bg-slate-100/80 text-slate-600 border-slate-200/50'\n }`}>\n {log.response_status}\n </span>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <div className=\"text-xs text-slate-600\">\n {log.response_time_ms}ms\n </div>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap text-right text-xs font-medium\">\n <button\n onClick={() => setSelectedLog(log)}\n className=\"text-emerald-600 hover:text-emerald-700 font-medium transition-colors duration-300\"\n >\n 查看详情\n </button>\n </td>\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n <div className=\"mt-5 flex items-center justify-between\">\n <div className=\"text-xs text-slate-600\">\n {searchQuery ? (\n <span>\n 搜索 \"<span className=\"font-semibold text-slate-800\">{searchQuery}</span>\"\n 找到 <span className=\"font-semibold text-slate-800\">{total}</span> 条结果\n </span>\n ) : (\n <span>共 <span className=\"font-semibold text-slate-800\">{total}</span> 条记录</span>\n )}\n </div>\n <div className=\"flex space-x-2\">\n <button\n onClick={() => setPage(Math.max(0, page - 1))}\n disabled={page === 0}\n className=\"px-3 py-1.5 border border-slate-200 rounded-lg text-xs font-medium text-slate-600 bg-white hover:bg-slate-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-300\"\n >\n 上一页\n </button>\n <button\n onClick={() => setPage(page + 1)}\n disabled={(page + 1) * limit >= total}\n className=\"px-3 py-1.5 border border-slate-200 rounded-lg text-xs font-medium text-slate-600 bg-white hover:bg-slate-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-300\"\n >\n 下一页\n </button>\n </div>\n </div>\n </div>\n </main>\n\n {selectedLog && (\n <div className=\"fixed z-50 inset-0 overflow-y-auto\">\n <div className=\"flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0\">\n <div className=\"fixed inset-0 bg-slate-900/40 backdrop-blur-sm transition-opacity\" onClick={() => setSelectedLog(null)}></div>\n <div className=\"inline-block align-bottom bg-white rounded-2xl text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-3xl sm:w-full border border-emerald-100/50\">\n <div className=\"bg-white px-6 pt-5 pb-4 sm:p-6\">\n <div className=\"mb-5\">\n <h3 className=\"text-base font-bold text-slate-800 mb-1\">\n 请求详情\n </h3>\n <p className=\"text-xs text-slate-500\">查看完整的请求和响应信息</p>\n </div>\n <div className=\"space-y-4 max-h-[60vh] overflow-y-auto\">\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"text-xs font-semibold text-slate-700\">请求头</h4>\n <button\n onClick={() => copyToClipboard(formatJSONSimple(selectedLog.request_headers))}\n className=\"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors\"\n >\n 复制\n </button>\n </div>\n <pre className=\"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700\">\n {formatJSONSimple(selectedLog.request_headers)}\n </pre>\n </div>\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"text-xs font-semibold text-slate-700\">请求 Query</h4>\n <button\n onClick={() => copyToClipboard(formatJSONSimple(selectedLog.request_query))}\n className=\"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors\"\n >\n 复制\n </button>\n </div>\n <pre className=\"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700\">\n {formatJSONSimple(selectedLog.request_query)}\n </pre>\n </div>\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"text-xs font-semibold text-slate-700\">请求 Body</h4>\n <button\n onClick={() => copyToClipboard(formatJSONSimple(selectedLog.request_body))}\n className=\"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors\"\n >\n 复制\n </button>\n </div>\n <pre className=\"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700\">\n {formatJSONSimple(selectedLog.request_body)}\n </pre>\n </div>\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"text-xs font-semibold text-slate-700\">响应 Body</h4>\n <div className=\"flex items-center gap-2\">\n {selectedLog && isStreamingResponse(selectedLog.response_body) && (\n <span className=\"px-2 py-0.5 text-xs bg-indigo-100 text-indigo-700 rounded-full border border-indigo-200\">\n 流式响应\n </span>\n )}\n <button\n onClick={() => copyToClipboard(formatRespon(selectedLog.response_body))}\n className=\"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors\"\n >\n 复制\n </button>\n </div>\n </div>\n <div className=\"bg-slate-50/80 border border-slate-200 rounded-xl p-3 max-h-96 overflow-auto\">\n {(\n <pre className=\"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700\">\n {formatRespon(selectedLog.response_body)}\n </pre>\n )}\n </div>\n </div>\n </div>\n <div className=\"mt-5 flex justify-end\">\n <button\n type=\"button\"\n onClick={() => setSelectedLog(null)}\n className=\"px-4 py-1.5 border border-slate-200 rounded-lg text-xs font-semibold text-slate-600 bg-white hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-slate-400/30 transition-all duration-300\"\n >\n 关闭\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n )}\n\n {confirmDialog && (\n <ConfirmDialog\n open={confirmDialog.open}\n title={confirmDialog.title}\n message={confirmDialog.message}\n onConfirm={confirmDialog.onConfirm}\n onCancel={() => setConfirmDialog(null)}\n type=\"danger\"\n />\n )}\n </>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/app/logs/page.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport Nav from '../components/Nav';\nimport { useToast } from '../components/ToastProvider';\nimport ConfirmDialog from '../components/ConfirmDialog';\n\ninterface RequestLog {\n id: number;\n model_id: number | null;\n model_name?: string | null;\n provider_name?: string | null;\n request_method: string;\n request_path: string;\n request_headers: string;\n request_query: string;\n request_body: string;\n response_status: number;\n response_body: string;\n response_time_ms: number;\n created_at: string;\n}\n\n/** 将服务端返回的 created_at 格式化为本地显示。无时区后缀时按 UTC 解析再转本地,避免差 8 小时。 */\nfunction formatCreatedAt(createdAt: string): string {\n if (!createdAt || typeof createdAt !== 'string') return '';\n const s = createdAt.trim();\n if (!s) return '';\n const hasTz = /[Z+-]\\d{2}:?\\d{2}$/.test(s);\n const iso = hasTz ? s : s.replace(' ', 'T') + 'Z';\n const date = new Date(iso);\n return Number.isNaN(date.getTime()) ? s : date.toLocaleString('zh-CN');\n}\n\nexport default function LogsPage() {\n const [logs, setLogs] = useState<RequestLog[]>([]);\n const [selectedLog, setSelectedLog] = useState<RequestLog | null>(null);\n const [loading, setLoading] = useState(true);\n const [page, setPage] = useState(0);\n const [total, setTotal] = useState(0);\n const [selectedIds, setSelectedIds] = useState<number[]>([]);\n const [selectAll, setSelectAll] = useState(false);\n const [confirmDialog, setConfirmDialog] = useState<{ open: boolean; title: string; message: string; onConfirm: () => void } | null>(null);\n const [searchQuery, setSearchQuery] = useState('');\n const [searchInput, setSearchInput] = useState('');\n const limit = 50;\n const { showToast } = useToast();\n\n const copyToClipboard = async (text: string) => {\n try {\n await navigator.clipboard.writeText(text);\n showToast('已复制到剪贴板', 'success');\n } catch {\n showToast('复制失败,请手动复制', 'error');\n }\n };\n\n const handleDeleteSelected = async () => {\n if (selectedIds.length === 0) return;\n setConfirmDialog({\n open: true,\n title: '删除确认',\n message: `确定要删除选中的 ${selectedIds.length} 条日志吗?`,\n onConfirm: async () => {\n try {\n const res = await fetch(`/api/logs?ids=${selectedIds.join(',')}`, { method: 'DELETE' });\n const data = await res.json();\n if (res.ok) {\n setSelectedIds([]);\n setSelectAll(false);\n loadLogs();\n showToast('删除成功', 'success');\n setConfirmDialog(null);\n } else {\n showToast('删除失败:' + (data.error || '未知错误'), 'error');\n }\n } catch (error) {\n console.error('Failed to delete logs:', error);\n showToast('删除失败', 'error');\n }\n },\n });\n };\n\n const handleClearAll = async () => {\n setConfirmDialog({\n open: true,\n title: '清空日志',\n message: '确定要清空所有日志吗?此操作不可恢复!',\n onConfirm: async () => {\n try {\n const res = await fetch('/api/logs?clear_all=true', { method: 'DELETE' });\n const data = await res.json();\n if (res.ok) {\n setPage(0);\n setSelectedIds([]);\n setSelectAll(false);\n loadLogs();\n showToast('清空成功', 'success');\n setConfirmDialog(null);\n } else {\n showToast('清空失败:' + (data.error || '未知错误'), 'error');\n }\n } catch (error) {\n console.error('Failed to clear logs:', error);\n showToast('清空失败', 'error');\n }\n },\n });\n };\n\n const handleSelectAll = (checked: boolean) => {\n setSelectAll(checked);\n setSelectedIds(checked ? logs.map(log => log.id) : []);\n };\n\n const handleSelectLog = (id: number, checked: boolean) => {\n if (checked) {\n setSelectedIds([...selectedIds, id]);\n } else {\n setSelectedIds(selectedIds.filter(sid => sid !== id));\n setSelectAll(false);\n }\n };\n\n const loadLogs = async (search?: string) => {\n try {\n setLoading(true);\n const params = new URLSearchParams({\n limit: limit.toString(),\n offset: (page * limit).toString(),\n });\n if (search) {\n params.set('search', search);\n }\n const res = await fetch(`/api/logs?${params.toString()}`);\n const data = await res.json();\n setLogs(data.logs || []);\n setTotal(data.total || 0);\n } catch (error) {\n console.error('Failed to load logs:', error);\n showToast('加载日志失败', 'error');\n } finally {\n setLoading(false);\n }\n };\n\n // 手动触发搜索\n const handleSearch = () => {\n setSearchQuery(searchInput);\n setPage(0);\n loadLogs(searchInput);\n };\n\n // 清除搜索\n const clearSearch = () => {\n setSearchInput('');\n if (searchQuery) {\n setSearchQuery('');\n setPage(0);\n loadLogs();\n }\n };\n\n // 键盘搜索支持\n const handleKeyPress = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n handleSearch();\n }\n };\n\n useEffect(() => {\n loadLogs();\n }, [page, limit]);\n\n const formatJSONSimple = (jsonString: string): string => {\n return typeof jsonString === 'string' ? jsonString : JSON.stringify(jsonString);\n }\n\n const formatRespon = (str: string): string => {\n if (isStreamingResponse(str)) {\n return formatSSEStream(str);\n }\n return formatJSONSimple(str);\n }\n\n const formatSSEStream = (responseBody: any): string => {\n if (!responseBody) return '';\n\n let sseData: string;\n try {\n sseData = JSON.parse(responseBody);\n } catch {\n sseData = responseBody;\n }\n\n if (!sseData.includes('data:') || !sseData.includes('\\n\\n')) {\n try {\n const parsed = JSON.parse(sseData);\n return JSON.stringify(parsed);\n } catch {\n return String(sseData);\n }\n }\n\n const chunks = sseData.split('\\n\\n').filter(chunk => chunk.trim());\n const formattedChunks: string[] = [];\n\n for (const chunk of chunks) {\n let content = chunk.trim();\n let tmp = content.split(\"\\n\").map((line) => {\n return line.startsWith(\"data: \") ? line.substring(6) : line;\n });\n content = tmp.join(\"\\n\");\n if (content === 'data: [DONE]' || content === '[DONE]') {\n formattedChunks.push(content);\n } else {\n // event: content_block_stop\n // data: {\"type\": \"content_block_stop\", \"index\": 0}\n formattedChunks.push(content);\n }\n }\n return formattedChunks.join('\\n\\n');\n };\n\n // 检测是否为流式响应\n const isStreamingResponse = (responseBody: any): boolean => {\n if (!responseBody) return false;\n const bodyStr = responseBody;\n // OpenAI格式: data: {...}\\n\\ndata: {...}\\n\\n\n // Anthropic格式: event: xxx\\ndata: {...}\\n\\nevent: xxx\\ndata: {...}\\n\\n\n const hasDataMarkers = bodyStr.includes('data:');\n const hasNewlinePairs = bodyStr.includes('\\n\\n');\n const hasEventMarkers = bodyStr.includes('event:');\n return (hasDataMarkers || hasNewlinePairs) || hasEventMarkers;\n };\n\n const parseModelFromRequest = (query: string, body: string): string | null => {\n try {\n const parsedQuery = query ? JSON.parse(query) : {};\n const parsedBody = body ? JSON.parse(body) : {};\n\n const model = parsedBody.model || parsedQuery.model;\n\n // 处理可能为数组的情况(如 message 格式)\n if (Array.isArray(model)) {\n const lastMessage = model[model.length - 1];\n if (lastMessage && typeof lastMessage === 'object' && 'model' in lastMessage) {\n return lastMessage.model;\n }\n }\n\n return typeof model === 'string' ? model : null;\n } catch {\n return null;\n }\n };\n\n const getStatusColor = (status: number) => {\n if (status >= 200 && status < 300) return 'text-green-600';\n if (status >= 400 && status < 500) return 'text-yellow-600';\n if (status >= 500) return 'text-red-600';\n return 'text-gray-600';\n };\n\n if (loading) {\n return (\n <>\n <Nav />\n <div className=\"min-h-screen flex items-center justify-center\">\n <div className=\"text-lg\">加载中...</div>\n </div>\n </>\n );\n }\n\n return (\n <>\n <Nav />\n <main className=\"max-w-6xl mx-auto py-6 sm:px-6 lg:px-8\">\n <div className=\"px-4 py-4 sm:px-0\">\n <div className=\"mb-5 flex items-center justify-between\">\n <div>\n <h1 className=\"text-lg font-bold text-slate-800\">请求日志</h1>\n <p className=\"text-xs text-slate-500 mt-1\">查看所有 API 请求记录和响应详情</p>\n </div>\n <div className=\"flex gap-2 items-center\">\n {/* 搜索框 */}\n <div className=\"relative group\">\n <input\n type=\"text\"\n placeholder=\"搜索日志...\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n onKeyPress={handleKeyPress}\n className=\"w-64 pl-9 pr-20 py-1.5 text-xs border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-emerald-500/30 focus:border-emerald-500 transition-all\"\n />\n <svg\n className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n {/* 操作按钮 */}\n <div className=\"absolute right-2 top-1/2 -translate-y-1/2 flex items-center gap-1\">\n {searchInput ? (\n <>\n <button\n onClick={handleSearch}\n className=\"p-0.5 text-emerald-500 hover:text-emerald-600 hover:bg-emerald-50 rounded transition-colors\"\n title=\"确认搜索\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n </button>\n <button\n onClick={clearSearch}\n className=\"p-0.5 text-slate-400 hover:text-rose-500 hover:bg-rose-50 rounded transition-colors\"\n title=\"清除搜索\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </>\n ) : null}\n </div>\n </div>\n {selectedIds.length > 0 && (\n <button\n onClick={handleDeleteSelected}\n className=\"px-3 py-1.5 bg-rose-600 hover:bg-rose-700 text-white text-xs font-semibold rounded-lg border border-rose-200 transition-all duration-300\"\n >\n 删除选中 ({selectedIds.length})\n </button>\n )}\n <button\n onClick={handleClearAll}\n className=\"px-3 py-1.5 bg-slate-600 hover:bg-slate-700 text-white text-xs font-semibold rounded-lg border border-slate-200 transition-all duration-300\"\n >\n 清空所有\n </button>\n </div>\n </div>\n\n <div className=\"bg-white/70 backdrop-blur-sm shadow-md rounded-2xl border border-emerald-100/50 overflow-hidden\">\n <table className=\"min-w-full divide-y divide-slate-100\">\n <thead className=\"bg-emerald-50/30\">\n <tr>\n <th className=\"px-4 py-3.5 w-10\">\n <input\n type=\"checkbox\"\n checked={selectAll && logs.length > 0}\n onChange={(e) => handleSelectAll(e.target.checked)}\n className=\"w-4 h-4 rounded border-slate-300 text-emerald-600 focus:ring-emerald-500\"\n />\n </th>\n <th className=\"px-4 py-2.5 text-left text-xs font-semibold text-slate-600 uppercase tracking-wider\">\n 时间\n </th>\n <th className=\"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider\">\n 模型\n </th>\n <th className=\"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider\">\n 方法\n </th>\n <th className=\"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider\">\n 路径\n </th>\n <th className=\"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider\">\n 状态\n </th>\n <th className=\"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider\">\n 响应时间\n </th>\n <th className=\"px-6 py-3.5 text-right text-xs font-semibold text-gray-700 uppercase tracking-wider\">\n 操作\n </th>\n </tr>\n </thead>\n <tbody className=\"bg-white divide-y divide-slate-100\">\n {logs.length === 0 ? (\n <tr>\n <td colSpan={8} className=\"px-4 py-12 text-center\">\n <div className=\"text-slate-400\">\n <svg className=\"mx-auto h-10 w-10 mb-3 text-slate-300\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5} d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>\n <p className=\"text-xs text-slate-500\">\n {searchQuery ? '未找到匹配的日志' : '暂无日志记录'}\n </p>\n {searchQuery && (\n <button\n onClick={() => {\n setSearchInput('');\n setSearchQuery('');\n }}\n className=\"mt-2 text-xs text-emerald-600 hover:text-emerald-700\"\n >\n 清除搜索\n </button>\n )}\n </div>\n </td>\n </tr>\n ) : (\n logs.map((log) => {\n const parsedModel = parseModelFromRequest(log.request_query, log.request_body);\n const displayModel = parsedModel || log.model_name || 'Gateway';\n\n return (\n <tr key={log.id} className=\"hover:bg-emerald-50/20 transition-colors duration-300\">\n <td className=\"px-4 py-3\">\n <input\n type=\"checkbox\"\n checked={selectedIds.includes(log.id)}\n onChange={(e) => handleSelectLog(log.id, e.target.checked)}\n className=\"w-4 h-4 rounded border-slate-300 text-emerald-600 focus:ring-emerald-500\"\n onClick={(e) => e.stopPropagation()}\n />\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <div className=\"text-xs text-slate-600\">\n {formatCreatedAt(log.created_at)}\n </div>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <div className=\"text-xs\">\n <div className=\"font-medium text-slate-800\">{displayModel}</div>\n {log.provider_name && (\n <div className=\"text-[10px] text-slate-500\">{log.provider_name}</div>\n )}\n </div>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <span className={`px-2 py-0.5 inline-flex text-xs leading-4 font-semibold rounded-lg border ${log.request_method === 'GET' ? 'bg-sky-50 text-sky-700 border-sky-200/50' :\n log.request_method === 'POST' ? 'bg-emerald-50 text-emerald-700 border-emerald-200/50' :\n 'bg-slate-50 text-slate-600 border-slate-200/50'\n }`}>\n {log.request_method}\n </span>\n </td>\n <td className=\"px-4 py-3\">\n <div className=\"text-xs text-slate-600 font-mono max-w-xs truncate\">\n {log.request_path}\n </div>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <span className={`px-2 py-0.5 inline-flex text-xs leading-4 font-semibold rounded-full border ${log.response_status >= 200 && log.response_status < 300 ? 'bg-emerald-100/80 text-emerald-700 border-emerald-200/50' :\n log.response_status >= 400 && log.response_status < 500 ? 'bg-amber-100/80 text-amber-700 border-amber-200/50' :\n log.response_status >= 500 ? 'bg-rose-100/80 text-rose-700 border-rose-200/50' :\n 'bg-slate-100/80 text-slate-600 border-slate-200/50'\n }`}>\n {log.response_status}\n </span>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <div className=\"text-xs text-slate-600\">\n {log.response_time_ms}ms\n </div>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap text-right text-xs font-medium\">\n <button\n onClick={() => setSelectedLog(log)}\n className=\"text-emerald-600 hover:text-emerald-700 font-medium transition-colors duration-300\"\n >\n 查看详情\n </button>\n </td>\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n <div className=\"mt-5 flex items-center justify-between\">\n <div className=\"text-xs text-slate-600\">\n {searchQuery ? (\n <span>\n 搜索 \"<span className=\"font-semibold text-slate-800\">{searchQuery}</span>\"\n 找到 <span className=\"font-semibold text-slate-800\">{total}</span> 条结果\n </span>\n ) : (\n <span>共 <span className=\"font-semibold text-slate-800\">{total}</span> 条记录</span>\n )}\n </div>\n <div className=\"flex space-x-2\">\n <button\n onClick={() => setPage(Math.max(0, page - 1))}\n disabled={page === 0}\n className=\"px-3 py-1.5 border border-slate-200 rounded-lg text-xs font-medium text-slate-600 bg-white hover:bg-slate-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-300\"\n >\n 上一页\n </button>\n <button\n onClick={() => setPage(page + 1)}\n disabled={(page + 1) * limit >= total}\n className=\"px-3 py-1.5 border border-slate-200 rounded-lg text-xs font-medium text-slate-600 bg-white hover:bg-slate-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-300\"\n >\n 下一页\n </button>\n </div>\n </div>\n </div>\n </main>\n\n {selectedLog && (\n <div className=\"fixed z-50 inset-0 overflow-y-auto\">\n <div className=\"flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0\">\n <div className=\"fixed inset-0 bg-slate-900/40 backdrop-blur-sm transition-opacity\" onClick={() => setSelectedLog(null)}></div>\n <div className=\"inline-block align-bottom bg-white rounded-2xl text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-3xl sm:w-full border border-emerald-100/50\">\n <div className=\"bg-white px-6 pt-5 pb-4 sm:p-6\">\n <div className=\"mb-5\">\n <h3 className=\"text-base font-bold text-slate-800 mb-1\">\n 请求详情\n </h3>\n <p className=\"text-xs text-slate-500\">查看完整的请求和响应信息</p>\n </div>\n <div className=\"space-y-4 max-h-[60vh] overflow-y-auto\">\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"text-xs font-semibold text-slate-700\">请求头</h4>\n <button\n onClick={() => copyToClipboard(formatJSONSimple(selectedLog.request_headers))}\n className=\"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors\"\n >\n 复制\n </button>\n </div>\n <pre className=\"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700\">\n {formatJSONSimple(selectedLog.request_headers)}\n </pre>\n </div>\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"text-xs font-semibold text-slate-700\">请求 Query</h4>\n <button\n onClick={() => copyToClipboard(formatJSONSimple(selectedLog.request_query))}\n className=\"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors\"\n >\n 复制\n </button>\n </div>\n <pre className=\"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700\">\n {formatJSONSimple(selectedLog.request_query)}\n </pre>\n </div>\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"text-xs font-semibold text-slate-700\">请求 Body</h4>\n <button\n onClick={() => copyToClipboard(formatJSONSimple(selectedLog.request_body))}\n className=\"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors\"\n >\n 复制\n </button>\n </div>\n <pre className=\"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700\">\n {formatJSONSimple(selectedLog.request_body)}\n </pre>\n </div>\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"text-xs font-semibold text-slate-700\">响应 Body</h4>\n <div className=\"flex items-center gap-2\">\n {selectedLog && isStreamingResponse(selectedLog.response_body) && (\n <span className=\"px-2 py-0.5 text-xs bg-indigo-100 text-indigo-700 rounded-full border border-indigo-200\">\n 流式响应\n </span>\n )}\n <button\n onClick={() => copyToClipboard(formatRespon(selectedLog.response_body))}\n className=\"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors\"\n >\n 复制\n </button>\n </div>\n </div>\n <div className=\"bg-slate-50/80 border border-slate-200 rounded-xl p-3 max-h-96 overflow-auto\">\n {(\n <pre className=\"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700\">\n {formatRespon(selectedLog.response_body)}\n </pre>\n )}\n </div>\n </div>\n </div>\n <div className=\"mt-5 flex justify-end\">\n <button\n type=\"button\"\n onClick={() => setSelectedLog(null)}\n className=\"px-4 py-1.5 border border-slate-200 rounded-lg text-xs font-semibold text-slate-600 bg-white hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-slate-400/30 transition-all duration-300\"\n >\n 关闭\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n )}\n\n {confirmDialog && (\n <ConfirmDialog\n open={confirmDialog.open}\n title={confirmDialog.title}\n message={confirmDialog.message}\n onConfirm={confirmDialog.onConfirm}\n onCancel={() => setConfirmDialog(null)}\n type=\"danger\"\n />\n )}\n </>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><!--
|
|
1
|
+
<!DOCTYPE html><!--ryTeHAYUvjT1bYolc_x9Z--><html lang="zh-CN"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/6418ca50028376b7.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/6e0dee5b6681763c.js"/><script src="/_next/static/chunks/f2f58a7e93290fbb.js" async=""></script><script src="/_next/static/chunks/a7f539bf6487f4ff.js" async=""></script><script src="/_next/static/chunks/turbopack-fdb839c72e10c2ea.js" async=""></script><script src="/_next/static/chunks/75f76753fd97c8fd.js" async=""></script><script src="/_next/static/chunks/d2be314c3ece3fbe.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>AAR - AI Agent Router</title><meta name="description" content="Unified API gateway for managing multiple AI model providers"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/6e0dee5b6681763c.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[97100,[\"/_next/static/chunks/75f76753fd97c8fd.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"ToastProvider\"]\n3:I[39756,[\"/_next/static/chunks/75f76753fd97c8fd.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"default\"]\n4:I[37457,[\"/_next/static/chunks/75f76753fd97c8fd.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"default\"]\n5:I[97367,[\"/_next/static/chunks/75f76753fd97c8fd.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"OutletBoundary\"]\n6:\"$Sreact.suspense\"\n8:I[97367,[\"/_next/static/chunks/75f76753fd97c8fd.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"ViewportBoundary\"]\na:I[97367,[\"/_next/static/chunks/75f76753fd97c8fd.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"MetadataBoundary\"]\nc:I[68027,[\"/_next/static/chunks/75f76753fd97c8fd.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"default\"]\n:HL[\"/_next/static/chunks/6418ca50028376b7.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"ryTeHAYUvjT1bYolc-x9Z\",\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/6418ca50028376b7.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/75f76753fd97c8fd.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/d2be314c3ece3fbe.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"zh-CN\",\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L5\",null,{\"children\":[\"$\",\"$6\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@7\"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$6\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"7:null\nb:[[\"$\",\"title\",\"0\",{\"children\":\"AAR - AI Agent Router\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Unified API gateway for managing multiple AI model providers\"}]]\n"])</script></body></html>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<!DOCTYPE html><!--
|
|
2
|
-
@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/6e0dee5b6681763c.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"ViewportBoundary\"]\n9:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"MetadataBoundary\"]\nb:I[68027,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"
|
|
1
|
+
<!DOCTYPE html><!--ryTeHAYUvjT1bYolc_x9Z--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/6e0dee5b6681763c.js"/><script src="/_next/static/chunks/f2f58a7e93290fbb.js" async=""></script><script src="/_next/static/chunks/a7f539bf6487f4ff.js" async=""></script><script src="/_next/static/chunks/turbopack-fdb839c72e10c2ea.js" async=""></script><script src="/_next/static/chunks/ff1a16fafef87110.js" async=""></script><script src="/_next/static/chunks/d2be314c3ece3fbe.js" async=""></script><title>500: Internal Server Error.</title><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
|
|
2
|
+
@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/6e0dee5b6681763c.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"ViewportBoundary\"]\n9:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"MetadataBoundary\"]\nb:I[68027,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/d2be314c3ece3fbe.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"ryTeHAYUvjT1bYolc-x9Z\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/ff1a16fafef87110.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/d2be314c3ece3fbe.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\na:[]\n"])</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,33525,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"warnOnce",{enumerable:!0,get:function(){return s}});let s=e=>{}},98183,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var s={assign:function(){return i},searchParamsToUrlQuery:function(){return l},urlQueryToSearchParams:function(){return o}};for(var n in s)Object.defineProperty(r,n,{enumerable:!0,get:s[n]});function l(e){let t={};for(let[r,s]of e.entries()){let e=t[r];void 0===e?t[r]=s:Array.isArray(e)?e.push(s):t[r]=[e,s]}return t}function a(e){return"string"==typeof e?e:("number"!=typeof e||isNaN(e))&&"boolean"!=typeof e?"":String(e)}function o(e){let t=new URLSearchParams;for(let[r,s]of Object.entries(e))if(Array.isArray(s))for(let e of s)t.append(r,a(e));else t.set(r,a(s));return t}function i(e,...t){for(let r of t){for(let t of r.keys())e.delete(t);for(let[t,s]of r.entries())e.append(t,s)}return e}},95057,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var s={formatUrl:function(){return o},formatWithValidation:function(){return c},urlObjectKeys:function(){return i}};for(var n in s)Object.defineProperty(r,n,{enumerable:!0,get:s[n]});let l=e.r(90809)._(e.r(98183)),a=/https?|ftp|gopher|file/;function o(e){let{auth:t,hostname:r}=e,s=e.protocol||"",n=e.pathname||"",o=e.hash||"",i=e.query||"",c=!1;t=t?encodeURIComponent(t).replace(/%3A/i,":")+"@":"",e.host?c=t+e.host:r&&(c=t+(~r.indexOf(":")?`[${r}]`:r),e.port&&(c+=":"+e.port)),i&&"object"==typeof i&&(i=String(l.urlQueryToSearchParams(i)));let d=e.search||i&&`?${i}`||"";return s&&!s.endsWith(":")&&(s+=":"),e.slashes||(!s||a.test(s))&&!1!==c?(c="//"+(c||""),n&&"/"!==n[0]&&(n="/"+n)):c||(c=""),o&&"#"!==o[0]&&(o="#"+o),d&&"?"!==d[0]&&(d="?"+d),n=n.replace(/[?#]/g,encodeURIComponent),d=d.replace("#","%23"),`${s}${c}${n}${d}${o}`}let i=["auth","hash","host","hostname","href","path","pathname","port","protocol","query","search","slashes"];function c(e){return o(e)}},18581,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"useMergedRef",{enumerable:!0,get:function(){return n}});let s=e.r(71645);function n(e,t){let r=(0,s.useRef)(null),n=(0,s.useRef)(null);return(0,s.useCallback)(s=>{if(null===s){let e=r.current;e&&(r.current=null,e());let t=n.current;t&&(n.current=null,t())}else e&&(r.current=l(e,s)),t&&(n.current=l(t,s))},[e,t])}function l(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let r=e(t);return"function"==typeof r?r:()=>e(null)}}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},18967,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var s={DecodeError:function(){return b},MiddlewareNotFoundError:function(){return v},MissingStaticPage:function(){return j},NormalizeError:function(){return g},PageNotFoundError:function(){return y},SP:function(){return p},ST:function(){return h},WEB_VITALS:function(){return l},execOnce:function(){return a},getDisplayName:function(){return u},getLocationOrigin:function(){return c},getURL:function(){return d},isAbsoluteUrl:function(){return i},isResSent:function(){return x},loadGetInitialProps:function(){return f},normalizeRepeatedSlashes:function(){return m},stringifyError:function(){return N}};for(var n in s)Object.defineProperty(r,n,{enumerable:!0,get:s[n]});let l=["CLS","FCP","FID","INP","LCP","TTFB"];function a(e){let t,r=!1;return(...s)=>(r||(r=!0,t=e(...s)),t)}let o=/^[a-zA-Z][a-zA-Z\d+\-.]*?:/,i=e=>o.test(e);function c(){let{protocol:e,hostname:t,port:r}=window.location;return`${e}//${t}${r?":"+r:""}`}function d(){let{href:e}=window.location,t=c();return e.substring(t.length)}function u(e){return"string"==typeof e?e:e.displayName||e.name||"Unknown"}function x(e){return e.finished||e.headersSent}function m(e){let t=e.split("?");return t[0].replace(/\\/g,"/").replace(/\/\/+/g,"/")+(t[1]?`?${t.slice(1).join("?")}`:"")}async function f(e,t){let r=t.res||t.ctx&&t.ctx.res;if(!e.getInitialProps)return t.ctx&&t.Component?{pageProps:await f(t.Component,t.ctx)}:{};let s=await e.getInitialProps(t);if(r&&x(r))return s;if(!s)throw Object.defineProperty(Error(`"${u(e)}.getInitialProps()" should resolve to an object. But found "${s}" instead.`),"__NEXT_ERROR_CODE",{value:"E394",enumerable:!1,configurable:!0});return s}let p="u">typeof performance,h=p&&["mark","measure","getEntriesByName"].every(e=>"function"==typeof performance[e]);class b extends Error{}class g extends Error{}class y extends Error{constructor(e){super(),this.code="ENOENT",this.name="PageNotFoundError",this.message=`Cannot find module for page: ${e}`}}class j extends Error{constructor(e,t){super(),this.message=`Failed to load static file for page: ${e} ${t}`}}class v extends Error{constructor(){super(),this.code="ENOENT",this.message="Cannot find the middleware module"}}function N(e){return JSON.stringify({message:e.message,stack:e.stack})}},73668,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"isLocalURL",{enumerable:!0,get:function(){return l}});let s=e.r(18967),n=e.r(52817);function l(e){if(!(0,s.isAbsoluteUrl)(e))return!0;try{let t=(0,s.getLocationOrigin)(),r=new URL(e,t);return r.origin===t&&(0,n.hasBasePath)(r.pathname)}catch(e){return!1}}},84508,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"errorOnce",{enumerable:!0,get:function(){return s}});let s=e=>{}},22016,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var s={default:function(){return b},useLinkStatus:function(){return y}};for(var n in s)Object.defineProperty(r,n,{enumerable:!0,get:s[n]});let l=e.r(90809),a=e.r(43476),o=l._(e.r(71645)),i=e.r(95057),c=e.r(8372),d=e.r(18581),u=e.r(18967),x=e.r(5550);e.r(33525);let m=e.r(91949),f=e.r(73668),p=e.r(9396);function h(e){return"string"==typeof e?e:(0,i.formatUrl)(e)}function b(t){var r;let s,n,l,[i,b]=(0,o.useOptimistic)(m.IDLE_LINK_STATUS),y=(0,o.useRef)(null),{href:j,as:v,children:N,prefetch:w=null,passHref:k,replace:_,shallow:C,scroll:P,onClick:S,onMouseEnter:E,onTouchStart:O,legacyBehavior:T=!1,onNavigate:L,ref:R,unstable_dynamicOnHover:M,...A}=t;s=N,T&&("string"==typeof s||"number"==typeof s)&&(s=(0,a.jsx)("a",{children:s}));let $=o.default.useContext(c.AppRouterContext),I=!1!==w,U=!1!==w?null===(r=w)||"auto"===r?p.FetchStrategy.PPR:p.FetchStrategy.Full:p.FetchStrategy.PPR,{href:F,as:q}=o.default.useMemo(()=>{let e=h(j);return{href:e,as:v?h(v):e}},[j,v]);if(T){if(s?.$$typeof===Symbol.for("react.lazy"))throw Object.defineProperty(Error("`<Link legacyBehavior>` received a direct child that is either a Server Component, or JSX that was loaded with React.lazy(). This is not supported. Either remove legacyBehavior, or make the direct child a Client Component that renders the Link's `<a>` tag."),"__NEXT_ERROR_CODE",{value:"E863",enumerable:!1,configurable:!0});n=o.default.Children.only(s)}let B=T?n&&"object"==typeof n&&n.ref:R,D=o.default.useCallback(e=>(null!==$&&(y.current=(0,m.mountLinkInstance)(e,F,$,U,I,b)),()=>{y.current&&((0,m.unmountLinkForCurrentNavigation)(y.current),y.current=null),(0,m.unmountPrefetchableInstance)(e)}),[I,F,$,U,b]),z={ref:(0,d.useMergedRef)(D,B),onClick(t){T||"function"!=typeof S||S(t),T&&n.props&&"function"==typeof n.props.onClick&&n.props.onClick(t),!$||t.defaultPrevented||function(t,r,s,n,l,a,i){if("u">typeof window){let c,{nodeName:d}=t.currentTarget;if("A"===d.toUpperCase()&&((c=t.currentTarget.getAttribute("target"))&&"_self"!==c||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||t.nativeEvent&&2===t.nativeEvent.which)||t.currentTarget.hasAttribute("download"))return;if(!(0,f.isLocalURL)(r)){l&&(t.preventDefault(),location.replace(r));return}if(t.preventDefault(),i){let e=!1;if(i({preventDefault:()=>{e=!0}}),e)return}let{dispatchNavigateAction:u}=e.r(99781);o.default.startTransition(()=>{u(s||r,l?"replace":"push",a??!0,n.current)})}}(t,F,q,y,_,P,L)},onMouseEnter(e){T||"function"!=typeof E||E(e),T&&n.props&&"function"==typeof n.props.onMouseEnter&&n.props.onMouseEnter(e),$&&I&&(0,m.onNavigationIntent)(e.currentTarget,!0===M)},onTouchStart:function(e){T||"function"!=typeof O||O(e),T&&n.props&&"function"==typeof n.props.onTouchStart&&n.props.onTouchStart(e),$&&I&&(0,m.onNavigationIntent)(e.currentTarget,!0===M)}};return(0,u.isAbsoluteUrl)(q)?z.href=q:T&&!k&&("a"!==n.type||"href"in n.props)||(z.href=(0,x.addBasePath)(q)),l=T?o.default.cloneElement(n,z):(0,a.jsx)("a",{...A,...z,children:s}),(0,a.jsx)(g.Provider,{value:i,children:l})}e.r(84508);let g=(0,o.createContext)(m.IDLE_LINK_STATUS),y=()=>(0,o.useContext)(g);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},18566,(e,t,r)=>{t.exports=e.r(76562)},19739,e=>{"use strict";var t=e.i(43476),r=e.i(22016),s=e.i(18566);function n(){let e=(0,s.usePathname)();return(0,t.jsx)("nav",{className:"bg-white/70 backdrop-blur-xl border-b border-emerald-100/30 sticky top-0 z-50",children:(0,t.jsx)("div",{className:"max-w-7xl mx-auto px-6 sm:px-8 lg:px-10",children:(0,t.jsx)("div",{className:"flex items-center justify-between h-16",children:(0,t.jsxs)("div",{className:"flex items-center space-x-12",children:[(0,t.jsxs)(r.default,{href:"/",className:"flex flex-col group transition-all duration-300",children:[(0,t.jsx)("span",{className:"text-xl font-bold text-emerald-700 group-hover:text-emerald-600 transition-colors duration-300 leading-none",children:"AAR"}),(0,t.jsx)("span",{className:"text-[9px] font-medium text-slate-400 tracking-wider uppercase mt-0.5 leading-none",children:"AI Agent Router"})]}),(0,t.jsx)("div",{className:"hidden sm:flex sm:items-center",children:[{href:"/",label:"配置"},{href:"/ide",label:"IDE"},{href:"/providers",label:"供应商"},{href:"/models",label:"模型"},{href:"/logs",label:"日志"}].map(s=>{let n=e===s.href;return(0,t.jsxs)(r.default,{href:s.href,className:"relative inline-flex items-center justify-center w-[68px] h-9 text-xs font-medium transition-colors duration-300 group",style:{minWidth:"68px",maxWidth:"68px"},children:[(0,t.jsx)("span",{className:`absolute inset-0 flex items-center justify-center transition-colors duration-300 ${n?"text-emerald-700 font-semibold":"text-slate-500 group-hover:text-slate-700"}`,children:s.label}),(0,t.jsx)("span",{className:`absolute inset-0 rounded-lg transition-all duration-300 ${n?"bg-emerald-50/60":"bg-transparent group-hover:bg-slate-50/40"}`})]},s.href)})})]})})})})}e.s(["default",()=>n])},88066,e=>{"use strict";var t=e.i(43476);function r({open:e,title:r,message:s,onConfirm:n,onCancel:l,confirmText:a="确认",cancelText:o="取消",type:i="info"}){return e?(0,t.jsx)("div",{className:"fixed z-50 inset-0 overflow-y-auto",children:(0,t.jsxs)("div",{className:"flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,t.jsx)("div",{className:"fixed inset-0 bg-slate-900/40 backdrop-blur-sm transition-opacity",onClick:l}),(0,t.jsx)("div",{className:"inline-block align-bottom bg-white rounded-2xl text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-sm sm:w-full border border-emerald-100/50",children:(0,t.jsxs)("div",{className:"bg-white px-5 pt-5 pb-4 sm:p-6",children:[(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)("h3",{className:"text-base font-bold text-slate-800 mb-1",children:r}),(0,t.jsx)("p",{className:"text-xs text-slate-600",children:s})]}),(0,t.jsxs)("div",{className:"flex items-center justify-end space-x-2",children:[(0,t.jsx)("button",{type:"button",onClick:l,className:"px-3.5 py-1.5 border border-slate-200 rounded-lg text-xs font-semibold text-slate-600 bg-white hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-slate-400/30 transition-all duration-300",children:o}),(0,t.jsx)("button",{type:"button",onClick:n,className:`px-4 py-1.5 border border-transparent rounded-lg text-xs font-semibold text-white focus:outline-none focus:ring-2 focus:ring-offset-1 transition-all duration-300 ${{danger:"bg-rose-500 hover:bg-rose-600 focus:ring-rose-500/50",warning:"bg-amber-500 hover:bg-amber-600 focus:ring-amber-500/50",info:"bg-emerald-600 hover:bg-emerald-700 focus:ring-emerald-500/50"}[i]}`,children:a})]})]})})]})}):null}e.s(["default",()=>r])},94785,e=>{"use strict";var t=e.i(43476),r=e.i(71645),s=e.i(19739),n=e.i(97100),l=e.i(88066);function a(){let[e,a]=(0,r.useState)([]),[o,i]=(0,r.useState)(null),[c,d]=(0,r.useState)(!0),[u,x]=(0,r.useState)(0),[m,f]=(0,r.useState)(0),[p,h]=(0,r.useState)([]),[b,g]=(0,r.useState)(!1),[y,j]=(0,r.useState)(null),[v,N]=(0,r.useState)(""),[w,k]=(0,r.useState)(""),{showToast:_}=(0,n.useToast)(),C=async e=>{try{await navigator.clipboard.writeText(e),_("已复制到剪贴板","success")}catch{_("复制失败,请手动复制","error")}},P=async()=>{0!==p.length&&j({open:!0,title:"删除确认",message:`确定要删除选中的 ${p.length} 条日志吗?`,onConfirm:async()=>{try{let e=await fetch(`/api/logs?ids=${p.join(",")}`,{method:"DELETE"}),t=await e.json();e.ok?(h([]),g(!1),E(),_("删除成功","success"),j(null)):_("删除失败:"+(t.error||"未知错误"),"error")}catch(e){console.error("Failed to delete logs:",e),_("删除失败","error")}}})},S=async()=>{j({open:!0,title:"清空日志",message:"确定要清空所有日志吗?此操作不可恢复!",onConfirm:async()=>{try{let e=await fetch("/api/logs?clear_all=true",{method:"DELETE"}),t=await e.json();e.ok?(x(0),h([]),g(!1),E(),_("清空成功","success"),j(null)):_("清空失败:"+(t.error||"未知错误"),"error")}catch(e){console.error("Failed to clear logs:",e),_("清空失败","error")}}})},E=async e=>{try{d(!0);let t=new URLSearchParams({limit:"50",offset:(50*u).toString()});e&&t.set("search",e);let r=await fetch(`/api/logs?${t.toString()}`),s=await r.json();a(s.logs||[]),f(s.total||0)}catch(e){console.error("Failed to load logs:",e),_("加载日志失败","error")}finally{d(!1)}},O=()=>{N(w),x(0),E(w)};(0,r.useEffect)(()=>{E()},[u,50]);let T=e=>"string"==typeof e?e:JSON.stringify(e),L=e=>M(e)?R(e):T(e),R=e=>{let t;if(!e)return"";try{t=JSON.parse(e)}catch{t=e}if(!t.includes("data:")||!t.includes("\n\n"))try{let e=JSON.parse(t);return JSON.stringify(e)}catch{return String(t)}let r=t.split("\n\n").filter(e=>e.trim()),s=[];for(let e of r){let t=e.trim();t=t.split("\n").map(e=>e.startsWith("data: ")?e.substring(6):e).join("\n"),s.push(t)}return s.join("\n\n")},M=e=>{if(!e)return!1;let t=e.includes("data:"),r=e.includes("\n\n"),s=e.includes("event:");return t||r||s};return c?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.default,{}),(0,t.jsx)("div",{className:"min-h-screen flex items-center justify-center",children:(0,t.jsx)("div",{className:"text-lg",children:"加载中..."})})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.default,{}),(0,t.jsx)("main",{className:"max-w-6xl mx-auto py-6 sm:px-6 lg:px-8",children:(0,t.jsxs)("div",{className:"px-4 py-4 sm:px-0",children:[(0,t.jsxs)("div",{className:"mb-5 flex items-center justify-between",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h1",{className:"text-lg font-bold text-slate-800",children:"请求日志"}),(0,t.jsx)("p",{className:"text-xs text-slate-500 mt-1",children:"查看所有 API 请求记录和响应详情"})]}),(0,t.jsxs)("div",{className:"flex gap-2 items-center",children:[(0,t.jsxs)("div",{className:"relative group",children:[(0,t.jsx)("input",{type:"text",placeholder:"搜索日志...",value:w,onChange:e=>k(e.target.value),onKeyPress:e=>{"Enter"===e.key&&O()},className:"w-64 pl-9 pr-20 py-1.5 text-xs border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-emerald-500/30 focus:border-emerald-500 transition-all"}),(0,t.jsx)("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),(0,t.jsx)("div",{className:"absolute right-2 top-1/2 -translate-y-1/2 flex items-center gap-1",children:w?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{onClick:O,className:"p-0.5 text-emerald-500 hover:text-emerald-600 hover:bg-emerald-50 rounded transition-colors",title:"确认搜索",children:(0,t.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})}),(0,t.jsx)("button",{onClick:()=>{k(""),v&&(N(""),x(0),E())},className:"p-0.5 text-slate-400 hover:text-rose-500 hover:bg-rose-50 rounded transition-colors",title:"清除搜索",children:(0,t.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}):null})]}),p.length>0&&(0,t.jsxs)("button",{onClick:P,className:"px-3 py-1.5 bg-rose-600 hover:bg-rose-700 text-white text-xs font-semibold rounded-lg border border-rose-200 transition-all duration-300",children:["删除选中 (",p.length,")"]}),(0,t.jsx)("button",{onClick:S,className:"px-3 py-1.5 bg-slate-600 hover:bg-slate-700 text-white text-xs font-semibold rounded-lg border border-slate-200 transition-all duration-300",children:"清空所有"})]})]}),(0,t.jsx)("div",{className:"bg-white/70 backdrop-blur-sm shadow-md rounded-2xl border border-emerald-100/50 overflow-hidden",children:(0,t.jsxs)("table",{className:"min-w-full divide-y divide-slate-100",children:[(0,t.jsx)("thead",{className:"bg-emerald-50/30",children:(0,t.jsxs)("tr",{children:[(0,t.jsx)("th",{className:"px-4 py-3.5 w-10",children:(0,t.jsx)("input",{type:"checkbox",checked:b&&e.length>0,onChange:t=>{var r;g(r=t.target.checked),h(r?e.map(e=>e.id):[])},className:"w-4 h-4 rounded border-slate-300 text-emerald-600 focus:ring-emerald-500"})}),(0,t.jsx)("th",{className:"px-4 py-2.5 text-left text-xs font-semibold text-slate-600 uppercase tracking-wider",children:"时间"}),(0,t.jsx)("th",{className:"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider",children:"模型"}),(0,t.jsx)("th",{className:"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider",children:"方法"}),(0,t.jsx)("th",{className:"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider",children:"路径"}),(0,t.jsx)("th",{className:"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider",children:"状态"}),(0,t.jsx)("th",{className:"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider",children:"响应时间"}),(0,t.jsx)("th",{className:"px-6 py-3.5 text-right text-xs font-semibold text-gray-700 uppercase tracking-wider",children:"操作"})]})}),(0,t.jsx)("tbody",{className:"bg-white divide-y divide-slate-100",children:0===e.length?(0,t.jsx)("tr",{children:(0,t.jsx)("td",{colSpan:8,className:"px-4 py-12 text-center",children:(0,t.jsxs)("div",{className:"text-slate-400",children:[(0,t.jsx)("svg",{className:"mx-auto h-10 w-10 mb-3 text-slate-300",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),(0,t.jsx)("p",{className:"text-xs text-slate-500",children:v?"未找到匹配的日志":"暂无日志记录"}),v&&(0,t.jsx)("button",{onClick:()=>{k(""),N("")},className:"mt-2 text-xs text-emerald-600 hover:text-emerald-700",children:"清除搜索"})]})})}):e.map(e=>{let r=((e,t)=>{try{let r=e?JSON.parse(e):{},s=(t?JSON.parse(t):{}).model||r.model;if(Array.isArray(s)){let e=s[s.length-1];if(e&&"object"==typeof e&&"model"in e)return e.model}return"string"==typeof s?s:null}catch{return null}})(e.request_query,e.request_body)||e.model_name||"Gateway";return(0,t.jsxs)("tr",{className:"hover:bg-emerald-50/20 transition-colors duration-300",children:[(0,t.jsx)("td",{className:"px-4 py-3",children:(0,t.jsx)("input",{type:"checkbox",checked:p.includes(e.id),onChange:t=>{var r;return r=e.id,void(t.target.checked?h([...p,r]):(h(p.filter(e=>e!==r)),g(!1)))},className:"w-4 h-4 rounded border-slate-300 text-emerald-600 focus:ring-emerald-500",onClick:e=>e.stopPropagation()})}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap",children:(0,t.jsx)("div",{className:"text-xs text-slate-600",children:new Date(e.created_at+"Z").toLocaleString("zh-CN")})}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"text-xs",children:[(0,t.jsx)("div",{className:"font-medium text-slate-800",children:r}),e.provider_name&&(0,t.jsx)("div",{className:"text-[10px] text-slate-500",children:e.provider_name})]})}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap",children:(0,t.jsx)("span",{className:`px-2 py-0.5 inline-flex text-xs leading-4 font-semibold rounded-lg border ${"GET"===e.request_method?"bg-sky-50 text-sky-700 border-sky-200/50":"POST"===e.request_method?"bg-emerald-50 text-emerald-700 border-emerald-200/50":"bg-slate-50 text-slate-600 border-slate-200/50"}`,children:e.request_method})}),(0,t.jsx)("td",{className:"px-4 py-3",children:(0,t.jsx)("div",{className:"text-xs text-slate-600 font-mono max-w-xs truncate",children:e.request_path})}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap",children:(0,t.jsx)("span",{className:`px-2 py-0.5 inline-flex text-xs leading-4 font-semibold rounded-full border ${e.response_status>=200&&e.response_status<300?"bg-emerald-100/80 text-emerald-700 border-emerald-200/50":e.response_status>=400&&e.response_status<500?"bg-amber-100/80 text-amber-700 border-amber-200/50":e.response_status>=500?"bg-rose-100/80 text-rose-700 border-rose-200/50":"bg-slate-100/80 text-slate-600 border-slate-200/50"}`,children:e.response_status})}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"text-xs text-slate-600",children:[e.response_time_ms,"ms"]})}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-right text-xs font-medium",children:(0,t.jsx)("button",{onClick:()=>i(e),className:"text-emerald-600 hover:text-emerald-700 font-medium transition-colors duration-300",children:"查看详情"})})]},e.id)})})]})}),(0,t.jsxs)("div",{className:"mt-5 flex items-center justify-between",children:[(0,t.jsx)("div",{className:"text-xs text-slate-600",children:v?(0,t.jsxs)("span",{children:['搜索 "',(0,t.jsx)("span",{className:"font-semibold text-slate-800",children:v}),'" 找到 ',(0,t.jsx)("span",{className:"font-semibold text-slate-800",children:m})," 条结果"]}):(0,t.jsxs)("span",{children:["共 ",(0,t.jsx)("span",{className:"font-semibold text-slate-800",children:m})," 条记录"]})}),(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:()=>x(Math.max(0,u-1)),disabled:0===u,className:"px-3 py-1.5 border border-slate-200 rounded-lg text-xs font-medium text-slate-600 bg-white hover:bg-slate-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-300",children:"上一页"}),(0,t.jsx)("button",{onClick:()=>x(u+1),disabled:(u+1)*50>=m,className:"px-3 py-1.5 border border-slate-200 rounded-lg text-xs font-medium text-slate-600 bg-white hover:bg-slate-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-300",children:"下一页"})]})]})]})}),o&&(0,t.jsx)("div",{className:"fixed z-50 inset-0 overflow-y-auto",children:(0,t.jsxs)("div",{className:"flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,t.jsx)("div",{className:"fixed inset-0 bg-slate-900/40 backdrop-blur-sm transition-opacity",onClick:()=>i(null)}),(0,t.jsx)("div",{className:"inline-block align-bottom bg-white rounded-2xl text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-3xl sm:w-full border border-emerald-100/50",children:(0,t.jsxs)("div",{className:"bg-white px-6 pt-5 pb-4 sm:p-6",children:[(0,t.jsxs)("div",{className:"mb-5",children:[(0,t.jsx)("h3",{className:"text-base font-bold text-slate-800 mb-1",children:"请求详情"}),(0,t.jsx)("p",{className:"text-xs text-slate-500",children:"查看完整的请求和响应信息"})]}),(0,t.jsxs)("div",{className:"space-y-4 max-h-[60vh] overflow-y-auto",children:[(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,t.jsx)("h4",{className:"text-xs font-semibold text-slate-700",children:"请求头"}),(0,t.jsx)("button",{onClick:()=>C(T(o.request_headers)),className:"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors",children:"复制"})]}),(0,t.jsx)("pre",{className:"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700",children:T(o.request_headers)})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,t.jsx)("h4",{className:"text-xs font-semibold text-slate-700",children:"请求 Query"}),(0,t.jsx)("button",{onClick:()=>C(T(o.request_query)),className:"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors",children:"复制"})]}),(0,t.jsx)("pre",{className:"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700",children:T(o.request_query)})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,t.jsx)("h4",{className:"text-xs font-semibold text-slate-700",children:"请求 Body"}),(0,t.jsx)("button",{onClick:()=>C(T(o.request_body)),className:"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors",children:"复制"})]}),(0,t.jsx)("pre",{className:"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700",children:T(o.request_body)})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,t.jsx)("h4",{className:"text-xs font-semibold text-slate-700",children:"响应 Body"}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[o&&M(o.response_body)&&(0,t.jsx)("span",{className:"px-2 py-0.5 text-xs bg-indigo-100 text-indigo-700 rounded-full border border-indigo-200",children:"流式响应"}),(0,t.jsx)("button",{onClick:()=>C(L(o.response_body)),className:"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors",children:"复制"})]})]}),(0,t.jsx)("div",{className:"bg-slate-50/80 border border-slate-200 rounded-xl p-3 max-h-96 overflow-auto",children:(0,t.jsx)("pre",{className:"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700",children:L(o.response_body)})})]})]}),(0,t.jsx)("div",{className:"mt-5 flex justify-end",children:(0,t.jsx)("button",{type:"button",onClick:()=>i(null),className:"px-4 py-1.5 border border-slate-200 rounded-lg text-xs font-semibold text-slate-600 bg-white hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-slate-400/30 transition-all duration-300",children:"关闭"})})]})})]})}),y&&(0,t.jsx)(l.default,{open:y.open,title:y.title,message:y.message,onConfirm:y.onConfirm,onCancel:()=>j(null),type:"danger"})]})}e.s(["default",()=>a])}]);
|
|
1
|
+
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,33525,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"warnOnce",{enumerable:!0,get:function(){return s}});let s=e=>{}},98183,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var s={assign:function(){return i},searchParamsToUrlQuery:function(){return l},urlQueryToSearchParams:function(){return o}};for(var n in s)Object.defineProperty(r,n,{enumerable:!0,get:s[n]});function l(e){let t={};for(let[r,s]of e.entries()){let e=t[r];void 0===e?t[r]=s:Array.isArray(e)?e.push(s):t[r]=[e,s]}return t}function a(e){return"string"==typeof e?e:("number"!=typeof e||isNaN(e))&&"boolean"!=typeof e?"":String(e)}function o(e){let t=new URLSearchParams;for(let[r,s]of Object.entries(e))if(Array.isArray(s))for(let e of s)t.append(r,a(e));else t.set(r,a(s));return t}function i(e,...t){for(let r of t){for(let t of r.keys())e.delete(t);for(let[t,s]of r.entries())e.append(t,s)}return e}},95057,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var s={formatUrl:function(){return o},formatWithValidation:function(){return c},urlObjectKeys:function(){return i}};for(var n in s)Object.defineProperty(r,n,{enumerable:!0,get:s[n]});let l=e.r(90809)._(e.r(98183)),a=/https?|ftp|gopher|file/;function o(e){let{auth:t,hostname:r}=e,s=e.protocol||"",n=e.pathname||"",o=e.hash||"",i=e.query||"",c=!1;t=t?encodeURIComponent(t).replace(/%3A/i,":")+"@":"",e.host?c=t+e.host:r&&(c=t+(~r.indexOf(":")?`[${r}]`:r),e.port&&(c+=":"+e.port)),i&&"object"==typeof i&&(i=String(l.urlQueryToSearchParams(i)));let d=e.search||i&&`?${i}`||"";return s&&!s.endsWith(":")&&(s+=":"),e.slashes||(!s||a.test(s))&&!1!==c?(c="//"+(c||""),n&&"/"!==n[0]&&(n="/"+n)):c||(c=""),o&&"#"!==o[0]&&(o="#"+o),d&&"?"!==d[0]&&(d="?"+d),n=n.replace(/[?#]/g,encodeURIComponent),d=d.replace("#","%23"),`${s}${c}${n}${d}${o}`}let i=["auth","hash","host","hostname","href","path","pathname","port","protocol","query","search","slashes"];function c(e){return o(e)}},18581,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"useMergedRef",{enumerable:!0,get:function(){return n}});let s=e.r(71645);function n(e,t){let r=(0,s.useRef)(null),n=(0,s.useRef)(null);return(0,s.useCallback)(s=>{if(null===s){let e=r.current;e&&(r.current=null,e());let t=n.current;t&&(n.current=null,t())}else e&&(r.current=l(e,s)),t&&(n.current=l(t,s))},[e,t])}function l(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let r=e(t);return"function"==typeof r?r:()=>e(null)}}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},18967,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var s={DecodeError:function(){return b},MiddlewareNotFoundError:function(){return v},MissingStaticPage:function(){return j},NormalizeError:function(){return g},PageNotFoundError:function(){return y},SP:function(){return p},ST:function(){return h},WEB_VITALS:function(){return l},execOnce:function(){return a},getDisplayName:function(){return u},getLocationOrigin:function(){return c},getURL:function(){return d},isAbsoluteUrl:function(){return i},isResSent:function(){return x},loadGetInitialProps:function(){return f},normalizeRepeatedSlashes:function(){return m},stringifyError:function(){return N}};for(var n in s)Object.defineProperty(r,n,{enumerable:!0,get:s[n]});let l=["CLS","FCP","FID","INP","LCP","TTFB"];function a(e){let t,r=!1;return(...s)=>(r||(r=!0,t=e(...s)),t)}let o=/^[a-zA-Z][a-zA-Z\d+\-.]*?:/,i=e=>o.test(e);function c(){let{protocol:e,hostname:t,port:r}=window.location;return`${e}//${t}${r?":"+r:""}`}function d(){let{href:e}=window.location,t=c();return e.substring(t.length)}function u(e){return"string"==typeof e?e:e.displayName||e.name||"Unknown"}function x(e){return e.finished||e.headersSent}function m(e){let t=e.split("?");return t[0].replace(/\\/g,"/").replace(/\/\/+/g,"/")+(t[1]?`?${t.slice(1).join("?")}`:"")}async function f(e,t){let r=t.res||t.ctx&&t.ctx.res;if(!e.getInitialProps)return t.ctx&&t.Component?{pageProps:await f(t.Component,t.ctx)}:{};let s=await e.getInitialProps(t);if(r&&x(r))return s;if(!s)throw Object.defineProperty(Error(`"${u(e)}.getInitialProps()" should resolve to an object. But found "${s}" instead.`),"__NEXT_ERROR_CODE",{value:"E394",enumerable:!1,configurable:!0});return s}let p="u">typeof performance,h=p&&["mark","measure","getEntriesByName"].every(e=>"function"==typeof performance[e]);class b extends Error{}class g extends Error{}class y extends Error{constructor(e){super(),this.code="ENOENT",this.name="PageNotFoundError",this.message=`Cannot find module for page: ${e}`}}class j extends Error{constructor(e,t){super(),this.message=`Failed to load static file for page: ${e} ${t}`}}class v extends Error{constructor(){super(),this.code="ENOENT",this.message="Cannot find the middleware module"}}function N(e){return JSON.stringify({message:e.message,stack:e.stack})}},73668,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"isLocalURL",{enumerable:!0,get:function(){return l}});let s=e.r(18967),n=e.r(52817);function l(e){if(!(0,s.isAbsoluteUrl)(e))return!0;try{let t=(0,s.getLocationOrigin)(),r=new URL(e,t);return r.origin===t&&(0,n.hasBasePath)(r.pathname)}catch(e){return!1}}},84508,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"errorOnce",{enumerable:!0,get:function(){return s}});let s=e=>{}},22016,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var s={default:function(){return b},useLinkStatus:function(){return y}};for(var n in s)Object.defineProperty(r,n,{enumerable:!0,get:s[n]});let l=e.r(90809),a=e.r(43476),o=l._(e.r(71645)),i=e.r(95057),c=e.r(8372),d=e.r(18581),u=e.r(18967),x=e.r(5550);e.r(33525);let m=e.r(91949),f=e.r(73668),p=e.r(9396);function h(e){return"string"==typeof e?e:(0,i.formatUrl)(e)}function b(t){var r;let s,n,l,[i,b]=(0,o.useOptimistic)(m.IDLE_LINK_STATUS),y=(0,o.useRef)(null),{href:j,as:v,children:N,prefetch:w=null,passHref:k,replace:_,shallow:C,scroll:P,onClick:S,onMouseEnter:E,onTouchStart:O,legacyBehavior:T=!1,onNavigate:L,ref:R,unstable_dynamicOnHover:M,...$}=t;s=N,T&&("string"==typeof s||"number"==typeof s)&&(s=(0,a.jsx)("a",{children:s}));let A=o.default.useContext(c.AppRouterContext),I=!1!==w,U=!1!==w?null===(r=w)||"auto"===r?p.FetchStrategy.PPR:p.FetchStrategy.Full:p.FetchStrategy.PPR,{href:F,as:q}=o.default.useMemo(()=>{let e=h(j);return{href:e,as:v?h(v):e}},[j,v]);if(T){if(s?.$$typeof===Symbol.for("react.lazy"))throw Object.defineProperty(Error("`<Link legacyBehavior>` received a direct child that is either a Server Component, or JSX that was loaded with React.lazy(). This is not supported. Either remove legacyBehavior, or make the direct child a Client Component that renders the Link's `<a>` tag."),"__NEXT_ERROR_CODE",{value:"E863",enumerable:!1,configurable:!0});n=o.default.Children.only(s)}let B=T?n&&"object"==typeof n&&n.ref:R,D=o.default.useCallback(e=>(null!==A&&(y.current=(0,m.mountLinkInstance)(e,F,A,U,I,b)),()=>{y.current&&((0,m.unmountLinkForCurrentNavigation)(y.current),y.current=null),(0,m.unmountPrefetchableInstance)(e)}),[I,F,A,U,b]),z={ref:(0,d.useMergedRef)(D,B),onClick(t){T||"function"!=typeof S||S(t),T&&n.props&&"function"==typeof n.props.onClick&&n.props.onClick(t),!A||t.defaultPrevented||function(t,r,s,n,l,a,i){if("u">typeof window){let c,{nodeName:d}=t.currentTarget;if("A"===d.toUpperCase()&&((c=t.currentTarget.getAttribute("target"))&&"_self"!==c||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||t.nativeEvent&&2===t.nativeEvent.which)||t.currentTarget.hasAttribute("download"))return;if(!(0,f.isLocalURL)(r)){l&&(t.preventDefault(),location.replace(r));return}if(t.preventDefault(),i){let e=!1;if(i({preventDefault:()=>{e=!0}}),e)return}let{dispatchNavigateAction:u}=e.r(99781);o.default.startTransition(()=>{u(s||r,l?"replace":"push",a??!0,n.current)})}}(t,F,q,y,_,P,L)},onMouseEnter(e){T||"function"!=typeof E||E(e),T&&n.props&&"function"==typeof n.props.onMouseEnter&&n.props.onMouseEnter(e),A&&I&&(0,m.onNavigationIntent)(e.currentTarget,!0===M)},onTouchStart:function(e){T||"function"!=typeof O||O(e),T&&n.props&&"function"==typeof n.props.onTouchStart&&n.props.onTouchStart(e),A&&I&&(0,m.onNavigationIntent)(e.currentTarget,!0===M)}};return(0,u.isAbsoluteUrl)(q)?z.href=q:T&&!k&&("a"!==n.type||"href"in n.props)||(z.href=(0,x.addBasePath)(q)),l=T?o.default.cloneElement(n,z):(0,a.jsx)("a",{...$,...z,children:s}),(0,a.jsx)(g.Provider,{value:i,children:l})}e.r(84508);let g=(0,o.createContext)(m.IDLE_LINK_STATUS),y=()=>(0,o.useContext)(g);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},18566,(e,t,r)=>{t.exports=e.r(76562)},19739,e=>{"use strict";var t=e.i(43476),r=e.i(22016),s=e.i(18566);function n(){let e=(0,s.usePathname)();return(0,t.jsx)("nav",{className:"bg-white/70 backdrop-blur-xl border-b border-emerald-100/30 sticky top-0 z-50",children:(0,t.jsx)("div",{className:"max-w-7xl mx-auto px-6 sm:px-8 lg:px-10",children:(0,t.jsx)("div",{className:"flex items-center justify-between h-16",children:(0,t.jsxs)("div",{className:"flex items-center space-x-12",children:[(0,t.jsxs)(r.default,{href:"/",className:"flex flex-col group transition-all duration-300",children:[(0,t.jsx)("span",{className:"text-xl font-bold text-emerald-700 group-hover:text-emerald-600 transition-colors duration-300 leading-none",children:"AAR"}),(0,t.jsx)("span",{className:"text-[9px] font-medium text-slate-400 tracking-wider uppercase mt-0.5 leading-none",children:"AI Agent Router"})]}),(0,t.jsx)("div",{className:"hidden sm:flex sm:items-center",children:[{href:"/",label:"配置"},{href:"/ide",label:"IDE"},{href:"/providers",label:"供应商"},{href:"/models",label:"模型"},{href:"/logs",label:"日志"}].map(s=>{let n=e===s.href;return(0,t.jsxs)(r.default,{href:s.href,className:"relative inline-flex items-center justify-center w-[68px] h-9 text-xs font-medium transition-colors duration-300 group",style:{minWidth:"68px",maxWidth:"68px"},children:[(0,t.jsx)("span",{className:`absolute inset-0 flex items-center justify-center transition-colors duration-300 ${n?"text-emerald-700 font-semibold":"text-slate-500 group-hover:text-slate-700"}`,children:s.label}),(0,t.jsx)("span",{className:`absolute inset-0 rounded-lg transition-all duration-300 ${n?"bg-emerald-50/60":"bg-transparent group-hover:bg-slate-50/40"}`})]},s.href)})})]})})})})}e.s(["default",()=>n])},88066,e=>{"use strict";var t=e.i(43476);function r({open:e,title:r,message:s,onConfirm:n,onCancel:l,confirmText:a="确认",cancelText:o="取消",type:i="info"}){return e?(0,t.jsx)("div",{className:"fixed z-50 inset-0 overflow-y-auto",children:(0,t.jsxs)("div",{className:"flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,t.jsx)("div",{className:"fixed inset-0 bg-slate-900/40 backdrop-blur-sm transition-opacity",onClick:l}),(0,t.jsx)("div",{className:"inline-block align-bottom bg-white rounded-2xl text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-sm sm:w-full border border-emerald-100/50",children:(0,t.jsxs)("div",{className:"bg-white px-5 pt-5 pb-4 sm:p-6",children:[(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)("h3",{className:"text-base font-bold text-slate-800 mb-1",children:r}),(0,t.jsx)("p",{className:"text-xs text-slate-600",children:s})]}),(0,t.jsxs)("div",{className:"flex items-center justify-end space-x-2",children:[(0,t.jsx)("button",{type:"button",onClick:l,className:"px-3.5 py-1.5 border border-slate-200 rounded-lg text-xs font-semibold text-slate-600 bg-white hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-slate-400/30 transition-all duration-300",children:o}),(0,t.jsx)("button",{type:"button",onClick:n,className:`px-4 py-1.5 border border-transparent rounded-lg text-xs font-semibold text-white focus:outline-none focus:ring-2 focus:ring-offset-1 transition-all duration-300 ${{danger:"bg-rose-500 hover:bg-rose-600 focus:ring-rose-500/50",warning:"bg-amber-500 hover:bg-amber-600 focus:ring-amber-500/50",info:"bg-emerald-600 hover:bg-emerald-700 focus:ring-emerald-500/50"}[i]}`,children:a})]})]})})]})}):null}e.s(["default",()=>r])},94785,e=>{"use strict";var t=e.i(43476),r=e.i(71645),s=e.i(19739),n=e.i(97100),l=e.i(88066);function a(){let[e,a]=(0,r.useState)([]),[o,i]=(0,r.useState)(null),[c,d]=(0,r.useState)(!0),[u,x]=(0,r.useState)(0),[m,f]=(0,r.useState)(0),[p,h]=(0,r.useState)([]),[b,g]=(0,r.useState)(!1),[y,j]=(0,r.useState)(null),[v,N]=(0,r.useState)(""),[w,k]=(0,r.useState)(""),{showToast:_}=(0,n.useToast)(),C=async e=>{try{await navigator.clipboard.writeText(e),_("已复制到剪贴板","success")}catch{_("复制失败,请手动复制","error")}},P=async()=>{0!==p.length&&j({open:!0,title:"删除确认",message:`确定要删除选中的 ${p.length} 条日志吗?`,onConfirm:async()=>{try{let e=await fetch(`/api/logs?ids=${p.join(",")}`,{method:"DELETE"}),t=await e.json();e.ok?(h([]),g(!1),E(),_("删除成功","success"),j(null)):_("删除失败:"+(t.error||"未知错误"),"error")}catch(e){console.error("Failed to delete logs:",e),_("删除失败","error")}}})},S=async()=>{j({open:!0,title:"清空日志",message:"确定要清空所有日志吗?此操作不可恢复!",onConfirm:async()=>{try{let e=await fetch("/api/logs?clear_all=true",{method:"DELETE"}),t=await e.json();e.ok?(x(0),h([]),g(!1),E(),_("清空成功","success"),j(null)):_("清空失败:"+(t.error||"未知错误"),"error")}catch(e){console.error("Failed to clear logs:",e),_("清空失败","error")}}})},E=async e=>{try{d(!0);let t=new URLSearchParams({limit:"50",offset:(50*u).toString()});e&&t.set("search",e);let r=await fetch(`/api/logs?${t.toString()}`),s=await r.json();a(s.logs||[]),f(s.total||0)}catch(e){console.error("Failed to load logs:",e),_("加载日志失败","error")}finally{d(!1)}},O=()=>{N(w),x(0),E(w)};(0,r.useEffect)(()=>{E()},[u,50]);let T=e=>"string"==typeof e?e:JSON.stringify(e),L=e=>M(e)?R(e):T(e),R=e=>{let t;if(!e)return"";try{t=JSON.parse(e)}catch{t=e}if(!t.includes("data:")||!t.includes("\n\n"))try{let e=JSON.parse(t);return JSON.stringify(e)}catch{return String(t)}let r=t.split("\n\n").filter(e=>e.trim()),s=[];for(let e of r){let t=e.trim();t=t.split("\n").map(e=>e.startsWith("data: ")?e.substring(6):e).join("\n"),s.push(t)}return s.join("\n\n")},M=e=>{if(!e)return!1;let t=e.includes("data:"),r=e.includes("\n\n"),s=e.includes("event:");return t||r||s};return c?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.default,{}),(0,t.jsx)("div",{className:"min-h-screen flex items-center justify-center",children:(0,t.jsx)("div",{className:"text-lg",children:"加载中..."})})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.default,{}),(0,t.jsx)("main",{className:"max-w-6xl mx-auto py-6 sm:px-6 lg:px-8",children:(0,t.jsxs)("div",{className:"px-4 py-4 sm:px-0",children:[(0,t.jsxs)("div",{className:"mb-5 flex items-center justify-between",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h1",{className:"text-lg font-bold text-slate-800",children:"请求日志"}),(0,t.jsx)("p",{className:"text-xs text-slate-500 mt-1",children:"查看所有 API 请求记录和响应详情"})]}),(0,t.jsxs)("div",{className:"flex gap-2 items-center",children:[(0,t.jsxs)("div",{className:"relative group",children:[(0,t.jsx)("input",{type:"text",placeholder:"搜索日志...",value:w,onChange:e=>k(e.target.value),onKeyPress:e=>{"Enter"===e.key&&O()},className:"w-64 pl-9 pr-20 py-1.5 text-xs border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-emerald-500/30 focus:border-emerald-500 transition-all"}),(0,t.jsx)("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),(0,t.jsx)("div",{className:"absolute right-2 top-1/2 -translate-y-1/2 flex items-center gap-1",children:w?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{onClick:O,className:"p-0.5 text-emerald-500 hover:text-emerald-600 hover:bg-emerald-50 rounded transition-colors",title:"确认搜索",children:(0,t.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})}),(0,t.jsx)("button",{onClick:()=>{k(""),v&&(N(""),x(0),E())},className:"p-0.5 text-slate-400 hover:text-rose-500 hover:bg-rose-50 rounded transition-colors",title:"清除搜索",children:(0,t.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}):null})]}),p.length>0&&(0,t.jsxs)("button",{onClick:P,className:"px-3 py-1.5 bg-rose-600 hover:bg-rose-700 text-white text-xs font-semibold rounded-lg border border-rose-200 transition-all duration-300",children:["删除选中 (",p.length,")"]}),(0,t.jsx)("button",{onClick:S,className:"px-3 py-1.5 bg-slate-600 hover:bg-slate-700 text-white text-xs font-semibold rounded-lg border border-slate-200 transition-all duration-300",children:"清空所有"})]})]}),(0,t.jsx)("div",{className:"bg-white/70 backdrop-blur-sm shadow-md rounded-2xl border border-emerald-100/50 overflow-hidden",children:(0,t.jsxs)("table",{className:"min-w-full divide-y divide-slate-100",children:[(0,t.jsx)("thead",{className:"bg-emerald-50/30",children:(0,t.jsxs)("tr",{children:[(0,t.jsx)("th",{className:"px-4 py-3.5 w-10",children:(0,t.jsx)("input",{type:"checkbox",checked:b&&e.length>0,onChange:t=>{var r;g(r=t.target.checked),h(r?e.map(e=>e.id):[])},className:"w-4 h-4 rounded border-slate-300 text-emerald-600 focus:ring-emerald-500"})}),(0,t.jsx)("th",{className:"px-4 py-2.5 text-left text-xs font-semibold text-slate-600 uppercase tracking-wider",children:"时间"}),(0,t.jsx)("th",{className:"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider",children:"模型"}),(0,t.jsx)("th",{className:"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider",children:"方法"}),(0,t.jsx)("th",{className:"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider",children:"路径"}),(0,t.jsx)("th",{className:"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider",children:"状态"}),(0,t.jsx)("th",{className:"px-6 py-3.5 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider",children:"响应时间"}),(0,t.jsx)("th",{className:"px-6 py-3.5 text-right text-xs font-semibold text-gray-700 uppercase tracking-wider",children:"操作"})]})}),(0,t.jsx)("tbody",{className:"bg-white divide-y divide-slate-100",children:0===e.length?(0,t.jsx)("tr",{children:(0,t.jsx)("td",{colSpan:8,className:"px-4 py-12 text-center",children:(0,t.jsxs)("div",{className:"text-slate-400",children:[(0,t.jsx)("svg",{className:"mx-auto h-10 w-10 mb-3 text-slate-300",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),(0,t.jsx)("p",{className:"text-xs text-slate-500",children:v?"未找到匹配的日志":"暂无日志记录"}),v&&(0,t.jsx)("button",{onClick:()=>{k(""),N("")},className:"mt-2 text-xs text-emerald-600 hover:text-emerald-700",children:"清除搜索"})]})})}):e.map(e=>{let r=((e,t)=>{try{let r=e?JSON.parse(e):{},s=(t?JSON.parse(t):{}).model||r.model;if(Array.isArray(s)){let e=s[s.length-1];if(e&&"object"==typeof e&&"model"in e)return e.model}return"string"==typeof s?s:null}catch{return null}})(e.request_query,e.request_body)||e.model_name||"Gateway";return(0,t.jsxs)("tr",{className:"hover:bg-emerald-50/20 transition-colors duration-300",children:[(0,t.jsx)("td",{className:"px-4 py-3",children:(0,t.jsx)("input",{type:"checkbox",checked:p.includes(e.id),onChange:t=>{var r;return r=e.id,void(t.target.checked?h([...p,r]):(h(p.filter(e=>e!==r)),g(!1)))},className:"w-4 h-4 rounded border-slate-300 text-emerald-600 focus:ring-emerald-500",onClick:e=>e.stopPropagation()})}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap",children:(0,t.jsx)("div",{className:"text-xs text-slate-600",children:function(e){if(!e||"string"!=typeof e)return"";let t=e.trim();if(!t)return"";let r=new Date(/[Z+-]\d{2}:?\d{2}$/.test(t)?t:t.replace(" ","T")+"Z");return Number.isNaN(r.getTime())?t:r.toLocaleString("zh-CN")}(e.created_at)})}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"text-xs",children:[(0,t.jsx)("div",{className:"font-medium text-slate-800",children:r}),e.provider_name&&(0,t.jsx)("div",{className:"text-[10px] text-slate-500",children:e.provider_name})]})}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap",children:(0,t.jsx)("span",{className:`px-2 py-0.5 inline-flex text-xs leading-4 font-semibold rounded-lg border ${"GET"===e.request_method?"bg-sky-50 text-sky-700 border-sky-200/50":"POST"===e.request_method?"bg-emerald-50 text-emerald-700 border-emerald-200/50":"bg-slate-50 text-slate-600 border-slate-200/50"}`,children:e.request_method})}),(0,t.jsx)("td",{className:"px-4 py-3",children:(0,t.jsx)("div",{className:"text-xs text-slate-600 font-mono max-w-xs truncate",children:e.request_path})}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap",children:(0,t.jsx)("span",{className:`px-2 py-0.5 inline-flex text-xs leading-4 font-semibold rounded-full border ${e.response_status>=200&&e.response_status<300?"bg-emerald-100/80 text-emerald-700 border-emerald-200/50":e.response_status>=400&&e.response_status<500?"bg-amber-100/80 text-amber-700 border-amber-200/50":e.response_status>=500?"bg-rose-100/80 text-rose-700 border-rose-200/50":"bg-slate-100/80 text-slate-600 border-slate-200/50"}`,children:e.response_status})}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"text-xs text-slate-600",children:[e.response_time_ms,"ms"]})}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-right text-xs font-medium",children:(0,t.jsx)("button",{onClick:()=>i(e),className:"text-emerald-600 hover:text-emerald-700 font-medium transition-colors duration-300",children:"查看详情"})})]},e.id)})})]})}),(0,t.jsxs)("div",{className:"mt-5 flex items-center justify-between",children:[(0,t.jsx)("div",{className:"text-xs text-slate-600",children:v?(0,t.jsxs)("span",{children:['搜索 "',(0,t.jsx)("span",{className:"font-semibold text-slate-800",children:v}),'" 找到 ',(0,t.jsx)("span",{className:"font-semibold text-slate-800",children:m})," 条结果"]}):(0,t.jsxs)("span",{children:["共 ",(0,t.jsx)("span",{className:"font-semibold text-slate-800",children:m})," 条记录"]})}),(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:()=>x(Math.max(0,u-1)),disabled:0===u,className:"px-3 py-1.5 border border-slate-200 rounded-lg text-xs font-medium text-slate-600 bg-white hover:bg-slate-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-300",children:"上一页"}),(0,t.jsx)("button",{onClick:()=>x(u+1),disabled:(u+1)*50>=m,className:"px-3 py-1.5 border border-slate-200 rounded-lg text-xs font-medium text-slate-600 bg-white hover:bg-slate-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-300",children:"下一页"})]})]})]})}),o&&(0,t.jsx)("div",{className:"fixed z-50 inset-0 overflow-y-auto",children:(0,t.jsxs)("div",{className:"flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,t.jsx)("div",{className:"fixed inset-0 bg-slate-900/40 backdrop-blur-sm transition-opacity",onClick:()=>i(null)}),(0,t.jsx)("div",{className:"inline-block align-bottom bg-white rounded-2xl text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-3xl sm:w-full border border-emerald-100/50",children:(0,t.jsxs)("div",{className:"bg-white px-6 pt-5 pb-4 sm:p-6",children:[(0,t.jsxs)("div",{className:"mb-5",children:[(0,t.jsx)("h3",{className:"text-base font-bold text-slate-800 mb-1",children:"请求详情"}),(0,t.jsx)("p",{className:"text-xs text-slate-500",children:"查看完整的请求和响应信息"})]}),(0,t.jsxs)("div",{className:"space-y-4 max-h-[60vh] overflow-y-auto",children:[(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,t.jsx)("h4",{className:"text-xs font-semibold text-slate-700",children:"请求头"}),(0,t.jsx)("button",{onClick:()=>C(T(o.request_headers)),className:"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors",children:"复制"})]}),(0,t.jsx)("pre",{className:"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700",children:T(o.request_headers)})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,t.jsx)("h4",{className:"text-xs font-semibold text-slate-700",children:"请求 Query"}),(0,t.jsx)("button",{onClick:()=>C(T(o.request_query)),className:"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors",children:"复制"})]}),(0,t.jsx)("pre",{className:"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700",children:T(o.request_query)})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,t.jsx)("h4",{className:"text-xs font-semibold text-slate-700",children:"请求 Body"}),(0,t.jsx)("button",{onClick:()=>C(T(o.request_body)),className:"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors",children:"复制"})]}),(0,t.jsx)("pre",{className:"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700",children:T(o.request_body)})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,t.jsx)("h4",{className:"text-xs font-semibold text-slate-700",children:"响应 Body"}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[o&&M(o.response_body)&&(0,t.jsx)("span",{className:"px-2 py-0.5 text-xs bg-indigo-100 text-indigo-700 rounded-full border border-indigo-200",children:"流式响应"}),(0,t.jsx)("button",{onClick:()=>C(L(o.response_body)),className:"px-2 py-0.5 text-xs text-emerald-600 hover:text-emerald-700 font-medium transition-colors",children:"复制"})]})]}),(0,t.jsx)("div",{className:"bg-slate-50/80 border border-slate-200 rounded-xl p-3 max-h-96 overflow-auto",children:(0,t.jsx)("pre",{className:"bg-slate-50/80 border border-slate-200 p-3 rounded-xl text-[10px] overflow-x-auto font-mono text-slate-700",children:L(o.response_body)})})]})]}),(0,t.jsx)("div",{className:"mt-5 flex justify-end",children:(0,t.jsx)("button",{type:"button",onClick:()=>i(null),className:"px-4 py-1.5 border border-slate-200 rounded-lg text-xs font-semibold text-slate-600 bg-white hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-slate-400/30 transition-all duration-300",children:"关闭"})})]})})]})}),y&&(0,t.jsx)(l.default,{open:y.open,title:y.title,message:y.message,onConfirm:y.onConfirm,onCancel:()=>j(null),type:"danger"})]})}e.s(["default",()=>a])}]);
|