feat(dashboard): lazy routes, Needs-you strip, URL state, exact numbers

- Workspace, SettingsHub, SessionDetail and the Workflow sub-tab are lazy
  (main bundle 2,166 kB -> ~920 kB), wrapped in RouteErrorBoundary: a stale
  chunk after a self-update reloads once (vite:preloadError too), any other
  error shows a Reload panel instead of a blank page.
- Live refresh: lib/throttle.ts + hooks/useLiveRefresh.ts replace trailing
  debounces that froze under a steady event stream; refresh skips hidden
  tabs and refetches after a WebSocket reconnect. Monitor loads only while
  shown, with one batched GET /api/agents?session_ids= instead of N+1; a
  failing endpoint is an inline error, not a blank Dashboard.
- NeedsYouStrip on Monitor and above Analytics. Tabs, filters, page, sort
  and search live in the URL (Dashboard, Sessions, Activity, SessionDetail).
- Sessions: tool / workspace / date-range filters, CSV/JSON export
  (formula-neutralised), focusable row links, Open in workspace (the dead
  /run links are gone), stale responses dropped, error + Retry.
- Fixes: "NaNs" durations, 30/7-day charts skipping idle days, weekday
  labels west of UTC (now averages), cache hit rate denominator, billable
  tokens vs cache reads, exact tool-call counts, "To" date = end of day,
  invalid ?from= no longer throws, recent list no longer shrinks to 15,
  stable message keys, transcript switch races.
- Light-theme-unreadable bg-black code panels and dark-only DAG fills use
  tokens; status configs and chart colours use theme tokens; Health tab
  and other literals translated.
- Server (additive): GET /api/agents?session_ids=, GET /api/sessions
  awaiting=1&from=&to=, stats tool_call_count/distinct_tool_count, event
  rows carry session/agent labels.
This commit is contained in:
2026-10-05 13:22:04 +07:00
parent 8fb703c6db
commit 03f1673fce
63 changed files with 3879 additions and 1662 deletions
+9 -2
View File
@@ -1,10 +1,17 @@
{
"title": "Activity Feed",
"subtitle": "Real-time stream of all agent events",
"paused": "(paused - {{count}} buffered)",
"paused": "(paused — {{count}} new)",
"resume": "Resume",
"pause": "Pause",
"noActivity": "No activity yet",
"noActivityDesc": "Events will stream here in real-time as Claude Code agents work.",
"viewSession": "Session"
"viewSession": "Session",
"exportCsv": "CSV",
"exportJson": "JSON",
"failedLoad": "Failed to load events",
"newEvents_one": "{{count}} new event — back to the latest",
"newEvents_other": "{{count}} new events — back to the latest",
"firstPage": "First page",
"lastPage": "Last page"
}
+4 -1
View File
@@ -50,5 +50,8 @@
"noSessionTrendData": "No session trend data yet.",
"last7Days": "Last 7 days",
"less": "Less",
"more": "More"
"more": "More",
"tokensExCacheReads": "Tokens (excl. cache reads)",
"cacheReadsSub": "+{{reads}} cache reads · {{pct}}% hit rate",
"avgPerWeekday30d": "Average per weekday, last 30 days"
}
+90 -1
View File
@@ -18,5 +18,94 @@
"failedConnect": "Failed to connect to server",
"failedLoad": "Failed to load data",
"activeTrend": " active",
"totalTrend": " in active sessions"
"totalTrend": " in active sessions",
"tabs": {
"label": "Dashboard views",
"analytics": "Analytics",
"monitor": "Monitor",
"health": "Health"
},
"collapseSubagents": "Collapse subagents",
"expandSubagents": "Expand subagents",
"needsYou": {
"title": "Needs you",
"since": "waiting {{ago}}"
},
"health": {
"runtime": "Runtime",
"cores_one": "{{count}} core",
"cores_other": "{{count}} cores",
"uptime": "Uptime",
"cpu": "CPU (1/5/15m)",
"nodeRss": "Node RSS",
"hostMemory": "Host Memory",
"hostMemoryTip": "Host Memory: {{pct}}% used\n{{used}} / {{total}}",
"heap": "V8 Heap",
"heapTip": "V8 Heap: {{pct}}% used\n{{used}} / {{limit}} limit\nAllocated: {{allocated}}\nExternal: {{external}}",
"storage": "Storage",
"writeVelocityTip": "Write velocity (events):\n5 min: {{m5}}\n15 min: {{m15}}\n1 hr: {{h1}}",
"database": "Database",
"recordsTip": "Record distribution\n\nSessions: {{sessions}} ({{sessPct}}%)\nAgents: {{agents}} ({{agentPct}}%)\nEvents: {{events}} ({{eventPct}}%)\n\nTotal: {{total}} records",
"total": "total",
"sessions": "Sessions",
"agents": "Agents",
"events": "Events",
"score": "Health Score",
"formula": "Formula",
"formulaTip": "Composite index formula:\n0.4 × Success rate ({{success}}%)\n+ 0.25 × Cache hit ({{cache}}%)\n+ 0.25 × (100 − Error rate) ({{noError}}%)\n+ 0.10 × (100 − Heap%) ({{noHeap}}%)\n= {{score}}",
"scoreTip": "Score: {{score}} / 100\n\n• Success rate (40%): {{success}}%\n• Cache hit (25%): {{cache}}%\n• Error avoidance (25%): {{noError}}%\n• Memory health (10%): {{noHeap}}%",
"cache": "Cache",
"cacheTip": "Cache hit rate: {{pct}}%\nHits: {{hits}}\nMisses: {{misses}}",
"errors": "Errors",
"errorsTip": "Error rate: {{pct}}%\n<5% = healthy, 5–15% = warning, >15% = critical",
"compact": "Compact",
"compactTip": "Transcript compactions: {{count}}\nReduces the context window by summarizing turns.",
"saved": "Saved",
"savedTip": "Tokens recovered: {{tokens}}\nFreed by compaction.",
"tokenUsage": "Token Usage",
"totalSuffix": "{{value}} total",
"modelTip": "{{model}}\nInput: {{input}}\nOutput: {{output}}\nCache read: {{cacheRead}}\nShare: {{pct}}%",
"noModelData": "No model data",
"concurrency": "Concurrency",
"intervals_one": "{{count}} interval",
"intervals_other": "{{count}} intervals",
"concurrencyTip": "Peak: {{peak}} parallel sessions\nActive intervals: {{active}}\nAvg: {{avg}}",
"noConcurrencyData": "No concurrency data",
"peak": "Peak",
"peakTip": "Peak: {{count}} sessions running simultaneously.",
"active": "Active",
"activeTip": "{{active}} of {{total}} intervals have active sessions.",
"avg": "Avg",
"avgTip": "Average concurrency across all intervals.",
"toolUsage": "Tool Usage",
"top": "top {{count}}",
"invocationsTip_one": "{{tool}}: {{formatted}} invocation",
"invocationsTip_other": "{{tool}}: {{formatted}} invocations",
"noToolData": "No tool data yet",
"subagentEffectiveness": "Subagent Effectiveness",
"defaultType": "default",
"effectivenessTip": "{{type}}\nSuccess: {{pct}}%\nTotal: {{total}} · OK: {{ok}} · Errors: {{errors}}",
"noSubagentData": "No subagent data yet",
"integration": "Integration",
"hooksActive": "Active",
"hookTip": "Path: {{path}}\nStatus: {{status}}",
"connected": "Connected",
"disconnected": "Disconnected",
"noHooks": "No project hooks registered",
"wsTip": "WebSocket connections: {{count}}\nProtocol: RFC 6455",
"wsActive": "WebSocket active",
"connections_one": "{{count}} connection",
"connections_other": "{{count}} connections",
"platform": "Platform",
"journalMode": "Journal mode",
"synchronous": "Synchronous",
"autoVacuum": "Auto-vacuum",
"foreignKeys": "Foreign keys",
"busyTimeout": "Busy timeout"
},
"errorBoundary": {
"title": "Something went wrong",
"body": "This page failed to load. Reloading usually fixes it — for example after the dashboard was updated.",
"reload": "Reload"
}
}
+111 -1
View File
@@ -37,7 +37,14 @@
"noEvents": "No events recorded.",
"conversation": "Conversation",
"timeline": "Timeline ({{shown}}/{{total}})",
"transcriptNotFound": "Conversation transcript not found for this agent. The transcript file may be missing or not yet linked."
"transcriptNotFound": "Conversation transcript not found for this agent. The transcript file may be missing or not yet linked.",
"back": "Back",
"collapseSubagents": "Collapse subagents",
"expandSubagents": "Expand subagents",
"dashboardRun": {
"title": "A dashboard pane is running this session",
"body": "Open its workspace pane to send follow-ups, watch the output or stop it."
}
},
"remoteSourceBadgeTitle": "Collected from a remote machine",
"toolBadgeTitle": "Recorded by {{tool}}",
@@ -46,5 +53,108 @@
"inWorkspace": "Open in its workspace",
"copyId": "Copy session ID",
"copyFolder": "Copy folder path"
},
"exportCsv": "CSV",
"exportJson": "JSON",
"filterDirectory": "Filter by directory",
"allDirectories": "All directories",
"sortLabel": "Sort sessions",
"sortTimeDesc": "Sort by time (newest)",
"sortTimeAsc": "Sort by time (oldest)",
"sortDurationDesc": "Sort by duration (longest)",
"sortDurationAsc": "Sort by duration (shortest)",
"sortPriceDesc": "Sort by price (highest)",
"sortPriceAsc": "Sort by price (lowest)",
"descending": "Descending",
"ascending": "Ascending",
"filterTool": "Filter by AI tool",
"allTools": "All AI tools",
"filterWorkspace": "Filter by workspace",
"allWorkspaces": "All workspaces",
"dateFrom": "From",
"dateTo": "To",
"clearFilters": "Clear filters",
"failedList": "Failed to load sessions",
"tableRegion": "Sessions table",
"openInWorkspace": "Open in workspace",
"openInWorkspaceTitle": "A dashboard pane is running this session — open it",
"datePicker": {
"placeholder": "Select date & time",
"clear": "Clear date",
"prevMonth": "Previous month",
"nextMonth": "Next month",
"time": "Time"
},
"conversation": {
"failedLoad": "Failed to load transcript",
"transcript": "Transcript",
"messages_one": "{{count}} message",
"messages_other": "{{count}} messages",
"refresh": "Refresh conversation",
"loadingHistory": "Loading history…",
"scrollForOlder": "Scroll up for older messages",
"loading": "Loading conversation…",
"empty": "No conversation records found.",
"emptyBody": "This session's metadata was imported, but its transcript file is no longer on disk. Claude Code automatically deletes inactive session transcripts after a retention period (cleanupPeriodDays, default 30 days), so older conversations may already be gone. Sessions imported from now on are snapshotted and kept even after Claude Code prunes the originals.",
"newMessages": "New messages",
"systemReminder": "System reminder",
"persistedOutput": "Persisted output",
"taskNotification": "Task notification",
"thinking": "Thinking",
"chars_one": "{{formatted}} char",
"chars_other": "{{formatted}} chars",
"sender": {
"user": "User",
"assistant": "Assistant",
"orchestrator": "Main agent",
"system": "System",
"tool": "Tool"
},
"lines_one": "{{count}} line",
"lines_other": "{{count}} lines",
"copyCode": "Copy code",
"copy": "Copy",
"tool": {
"inputTruncated": "Input (truncated)",
"command": "Command",
"newFile": "New file",
"replaceAll": "replace all",
"removed": "Removed",
"added": "Added",
"pattern": "Pattern",
"path": "Path",
"glob": "Glob",
"input": "Input",
"empty": "empty",
"error": "Error",
"output": "Output",
"statusError": "error",
"statusOk": "ok",
"statusPending": "pending"
}
},
"overview": {
"agent": "Agent",
"running": "running",
"events": "Events",
"perMin": "{{rate}}/min",
"toolCalls": "Tool calls",
"unique": "{{count}} unique",
"subagents": "Subagents",
"plusMain_one": "+{{count}} main",
"plusMain_other": "+{{count}} main",
"compactions": "Compactions",
"errors": "Errors",
"duration": "Duration",
"topTools": "Top tools",
"distinctTotal": "{{count}} total",
"noToolCalls": "No tool calls yet.",
"contextCompaction": "Context Compaction",
"runs_one": "{{count}} run",
"runs_other": "{{count}} runs",
"noSubagents": "No subagents in this session.",
"tokenFlow": "Token flow",
"total": "{{value}} total",
"eventMix": "Event mix"
}
}
+15 -2
View File
@@ -204,6 +204,15 @@
"outcomeAbandoned": "Sessions that stopped without a clean Stop event and without explicit errors - usually closed mid-flight.",
"outcomeFallback": "The terminal status of sessions in scope, computed from the last hook event observed for each session."
}
},
"legendItems": {
"sessions": "Sessions",
"mainAgent": "Main agent",
"subagentTypes": "Subagent types",
"compactions": "Compactions",
"completed": "Completed",
"error": "Error",
"abandoned": "Abandoned"
}
},
"drillIn": {
@@ -230,7 +239,9 @@
"noEvents": "No events recorded for this session.",
"showingOf": "Showing 100 of {{total}} events",
"sessionInfo": " session(s) - active {{from}}%-{{to}}% of session",
"sortedByCompaction": " session(s) (sorted by compaction count)"
"sortedByCompaction": " session(s) (sorted by compaction count)",
"openSession": "Open session",
"openInWorkspace": "Open in workspace"
},
"lanes": {
"title": "Workspace Pipeline Pass Rates",
@@ -316,5 +327,7 @@
"sessions_one": "{{count}} session",
"sessions_other": "{{count}} sessions",
"pluginBreakdown": "{{skills}} skill(s) used · {{skillCalls}} skill call(s) · {{mcpCalls}} MCP tool call(s)"
}
},
"selectedNode": "Selected:",
"clearSelection": "Clear selection"
}
+9 -2
View File
@@ -1,10 +1,17 @@
{
"title": "Luồng hoạt động",
"subtitle": "Luồng thời gian thực của mọi sự kiện Agent",
"paused": "(đã tạm dừng - {{count}} mục đệm)",
"paused": "(đã tạm dừng — {{count}} sự kiện mới)",
"resume": "Tiếp tục",
"pause": "Tạm dừng",
"noActivity": "Chưa có hoạt động",
"noActivityDesc": "Sự kiện sẽ được phát trực tiếp tại đây khi các Agent Claude Code làm việc.",
"viewSession": "Phiên"
"viewSession": "Phiên",
"exportCsv": "CSV",
"exportJson": "JSON",
"failedLoad": "Không thể tải sự kiện",
"newEvents_one": "{{count}} sự kiện mới — về mới nhất",
"newEvents_other": "{{count}} sự kiện mới — về mới nhất",
"firstPage": "Trang đầu",
"lastPage": "Trang cuối"
}
+4 -1
View File
@@ -50,5 +50,8 @@
"noSessionTrendData": "Chưa có dữ liệu xu hướng phiên.",
"last7Days": "7 ngày gần nhất",
"less": "Ít",
"more": "Nhiều"
"more": "Nhiều",
"tokensExCacheReads": "Token (trừ đọc cache)",
"cacheReadsSub": "+{{reads}} token đọc cache · tỉ lệ trúng {{pct}}%",
"avgPerWeekday30d": "Trung bình theo thứ trong tuần, 30 ngày qua"
}
+90 -1
View File
@@ -18,5 +18,94 @@
"failedConnect": "Không thể kết nối máy chủ",
"failedLoad": "Không thể tải dữ liệu",
"activeTrend": " đang hoạt động",
"totalTrend": " trong phiên hoạt động"
"totalTrend": " trong phiên hoạt động",
"tabs": {
"label": "Các chế độ xem tổng quan",
"analytics": "Phân tích",
"monitor": "Giám sát",
"health": "Sức khỏe hệ thống"
},
"collapseSubagents": "Thu gọn subagent",
"expandSubagents": "Mở rộng subagent",
"needsYou": {
"title": "Cần bạn xử lý",
"since": "đang chờ {{ago}}"
},
"health": {
"runtime": "Môi trường chạy",
"cores_one": "{{count}} lõi",
"cores_other": "{{count}} lõi",
"uptime": "Thời gian chạy",
"cpu": "CPU (1/5/15 phút)",
"nodeRss": "Bộ nhớ Node (RSS)",
"hostMemory": "Bộ nhớ máy",
"hostMemoryTip": "Bộ nhớ máy: đã dùng {{pct}}%\n{{used}} / {{total}}",
"heap": "Heap V8",
"heapTip": "Heap V8: đã dùng {{pct}}%\n{{used}} / giới hạn {{limit}}\nĐã cấp phát: {{allocated}}\nNgoài heap: {{external}}",
"storage": "Lưu trữ",
"writeVelocityTip": "Tốc độ ghi (sự kiện):\n5 phút: {{m5}}\n15 phút: {{m15}}\n1 giờ: {{h1}}",
"database": "Cơ sở dữ liệu",
"recordsTip": "Phân bố bản ghi\n\nPhiên: {{sessions}} ({{sessPct}}%)\nAgent: {{agents}} ({{agentPct}}%)\nSự kiện: {{events}} ({{eventPct}}%)\n\nTổng: {{total}} bản ghi",
"total": "tổng",
"sessions": "Phiên",
"agents": "Agent",
"events": "Sự kiện",
"score": "Điểm sức khỏe",
"formula": "Công thức",
"formulaTip": "Công thức chỉ số tổng hợp:\n0.4 × Tỉ lệ thành công ({{success}}%)\n+ 0.25 × Trúng cache ({{cache}}%)\n+ 0.25 × (100 − Tỉ lệ lỗi) ({{noError}}%)\n+ 0.10 × (100 − Heap%) ({{noHeap}}%)\n= {{score}}",
"scoreTip": "Điểm: {{score}} / 100\n\n• Tỉ lệ thành công (40%): {{success}}%\n• Trúng cache (25%): {{cache}}%\n• Tránh lỗi (25%): {{noError}}%\n• Sức khỏe bộ nhớ (10%): {{noHeap}}%",
"cache": "Cache",
"cacheTip": "Tỉ lệ trúng cache: {{pct}}%\nTrúng: {{hits}}\nTrượt: {{misses}}",
"errors": "Lỗi",
"errorsTip": "Tỉ lệ lỗi: {{pct}}%\n<5% = tốt, 5–15% = cảnh báo, >15% = nghiêm trọng",
"compact": "Nén",
"compactTip": "Số lần nén transcript: {{count}}\nThu gọn cửa sổ ngữ cảnh bằng cách tóm tắt các lượt.",
"saved": "Tiết kiệm",
"savedTip": "Token thu hồi: {{tokens}}\nĐược giải phóng nhờ nén.",
"tokenUsage": "Sử dụng token",
"totalSuffix": "tổng {{value}}",
"modelTip": "{{model}}\nĐầu vào: {{input}}\nĐầu ra: {{output}}\nĐọc cache: {{cacheRead}}\nTỉ trọng: {{pct}}%",
"noModelData": "Chưa có dữ liệu mô hình",
"concurrency": "Đồng thời",
"intervals_one": "{{count}} khoảng",
"intervals_other": "{{count}} khoảng",
"concurrencyTip": "Đỉnh: {{peak}} phiên song song\nKhoảng có hoạt động: {{active}}\nTrung bình: {{avg}}",
"noConcurrencyData": "Chưa có dữ liệu đồng thời",
"peak": "Đỉnh",
"peakTip": "Đỉnh: {{count}} phiên chạy cùng lúc.",
"active": "Hoạt động",
"activeTip": "{{active}} trên {{total}} khoảng có phiên hoạt động.",
"avg": "TB",
"avgTip": "Mức đồng thời trung bình trên mọi khoảng.",
"toolUsage": "Sử dụng công cụ",
"top": "top {{count}}",
"invocationsTip_one": "{{tool}}: {{formatted}} lần gọi",
"invocationsTip_other": "{{tool}}: {{formatted}} lần gọi",
"noToolData": "Chưa có dữ liệu công cụ",
"subagentEffectiveness": "Hiệu quả subagent",
"defaultType": "mặc định",
"effectivenessTip": "{{type}}\nThành công: {{pct}}%\nTổng: {{total}} · OK: {{ok}} · Lỗi: {{errors}}",
"noSubagentData": "Chưa có dữ liệu subagent",
"integration": "Tích hợp",
"hooksActive": "Đang hoạt động",
"hookTip": "Đường dẫn: {{path}}\nTrạng thái: {{status}}",
"connected": "Đã kết nối",
"disconnected": "Mất kết nối",
"noHooks": "Chưa đăng ký hook dự án nào",
"wsTip": "Kết nối WebSocket: {{count}}\nGiao thức: RFC 6455",
"wsActive": "WebSocket đang hoạt động",
"connections_one": "{{count}} kết nối",
"connections_other": "{{count}} kết nối",
"platform": "Nền tảng",
"journalMode": "Chế độ journal",
"synchronous": "Đồng bộ",
"autoVacuum": "Tự dọn dẹp",
"foreignKeys": "Khóa ngoại",
"busyTimeout": "Thời gian chờ khóa"
},
"errorBoundary": {
"title": "Đã xảy ra lỗi",
"body": "Không thể tải trang này. Tải lại thường sẽ khắc phục — ví dụ sau khi dashboard vừa được cập nhật.",
"reload": "Tải lại"
}
}
+112 -1
View File
@@ -37,7 +37,14 @@
"noEvents": "Chưa có sự kiện được ghi nhận.",
"conversation": "Hội thoại",
"timeline": "Dòng thời gian ({{shown}}/{{total}})",
"transcriptNotFound": "Không tìm thấy bản ghi hội thoại cho agent này. Tệp transcript có thể bị thiếu hoặc chưa được liên kết."
"transcriptNotFound": "Không tìm thấy bản ghi hội thoại cho agent này. Tệp transcript có thể bị thiếu hoặc chưa được liên kết.",
"back": "Quay lại",
"collapseSubagents": "Thu gọn subagent",
"expandSubagents": "Mở rộng subagent",
"dashboardRun": {
"title": "Một pane trên dashboard đang chạy phiên này",
"body": "Mở pane trong workspace để gửi tiếp, xem đầu ra hoặc dừng nó."
}
},
"toolBadgeTitle": "Ghi lại bởi {{tool}}",
"menu": {
@@ -45,5 +52,109 @@
"inWorkspace": "Mở trong workspace của nó",
"copyId": "Sao chép ID session",
"copyFolder": "Sao chép đường dẫn thư mục"
},
"exportCsv": "CSV",
"exportJson": "JSON",
"filterDirectory": "Lọc theo thư mục",
"allDirectories": "Tất cả thư mục",
"sortLabel": "Sắp xếp phiên",
"sortTimeDesc": "Theo thời gian (mới nhất)",
"sortTimeAsc": "Theo thời gian (cũ nhất)",
"sortDurationDesc": "Theo thời lượng (dài nhất)",
"sortDurationAsc": "Theo thời lượng (ngắn nhất)",
"sortPriceDesc": "Theo chi phí (cao nhất)",
"sortPriceAsc": "Theo chi phí (thấp nhất)",
"descending": "Giảm dần",
"ascending": "Tăng dần",
"filterTool": "Lọc theo công cụ AI",
"allTools": "Mọi công cụ AI",
"filterWorkspace": "Lọc theo workspace",
"allWorkspaces": "Mọi workspace",
"dateFrom": "Từ",
"dateTo": "Đến",
"clearFilters": "Xóa bộ lọc",
"failedList": "Không thể tải danh sách phiên",
"tableRegion": "Bảng phiên",
"openInWorkspace": "Mở trong workspace",
"openInWorkspaceTitle": "Một pane trên dashboard đang chạy phiên này — mở nó",
"remoteSourceBadgeTitle": "Được thu thập từ máy từ xa",
"datePicker": {
"placeholder": "Chọn ngày và giờ",
"clear": "Xóa ngày",
"prevMonth": "Tháng trước",
"nextMonth": "Tháng sau",
"time": "Giờ"
},
"conversation": {
"failedLoad": "Không thể tải transcript",
"transcript": "Transcript",
"messages_one": "{{count}} tin nhắn",
"messages_other": "{{count}} tin nhắn",
"refresh": "Làm mới hội thoại",
"loadingHistory": "Đang tải lịch sử…",
"scrollForOlder": "Cuộn lên để xem tin nhắn cũ hơn",
"loading": "Đang tải hội thoại…",
"empty": "Không tìm thấy bản ghi hội thoại.",
"emptyBody": "Siêu dữ liệu của phiên này đã được nhập, nhưng tệp transcript không còn trên đĩa. Claude Code tự động xóa transcript của phiên không hoạt động sau một thời gian lưu giữ (cleanupPeriodDays, mặc định 30 ngày), nên các hội thoại cũ có thể đã mất. Các phiên được nhập từ nay sẽ được chụp lại và giữ nguyên ngay cả khi Claude Code xóa bản gốc.",
"newMessages": "Tin nhắn mới",
"systemReminder": "Nhắc nhở hệ thống",
"persistedOutput": "Đầu ra đã lưu",
"taskNotification": "Thông báo tác vụ",
"thinking": "Suy nghĩ",
"chars_one": "{{formatted}} ký tự",
"chars_other": "{{formatted}} ký tự",
"sender": {
"user": "Người dùng",
"assistant": "Trợ lý",
"orchestrator": "Agent chính",
"system": "Hệ thống",
"tool": "Công cụ"
},
"lines_one": "{{count}} dòng",
"lines_other": "{{count}} dòng",
"copyCode": "Sao chép mã",
"copy": "Sao chép",
"tool": {
"inputTruncated": "Đầu vào (bị cắt bớt)",
"command": "Lệnh",
"newFile": "Tệp mới",
"replaceAll": "thay tất cả",
"removed": "Đã xóa",
"added": "Đã thêm",
"pattern": "Mẫu",
"path": "Đường dẫn",
"glob": "Glob",
"input": "Đầu vào",
"empty": "trống",
"error": "Lỗi",
"output": "Đầu ra",
"statusError": "lỗi",
"statusOk": "ok",
"statusPending": "đang chờ"
}
},
"overview": {
"agent": "Agent",
"running": "đang chạy",
"events": "Sự kiện",
"perMin": "{{rate}}/phút",
"toolCalls": "Lần gọi công cụ",
"unique": "{{count}} loại",
"subagents": "Subagent",
"plusMain_one": "+{{count}} chính",
"plusMain_other": "+{{count}} chính",
"compactions": "Lần nén",
"errors": "Lỗi",
"duration": "Thời lượng",
"topTools": "Công cụ dùng nhiều",
"distinctTotal": "tổng {{count}}",
"noToolCalls": "Chưa có lần gọi công cụ nào.",
"contextCompaction": "Nén ngữ cảnh",
"runs_one": "{{count}} lần chạy",
"runs_other": "{{count}} lần chạy",
"noSubagents": "Phiên này không có subagent.",
"tokenFlow": "Luồng token",
"total": "tổng {{value}}",
"eventMix": "Cơ cấu sự kiện"
}
}
+15 -2
View File
@@ -204,6 +204,15 @@
"outcomeAbandoned": "Phiên dừng mà không có Stop sạch và cũng không có lỗi rõ ràng - thường là đóng giữa chừng.",
"outcomeFallback": "Trạng thái cuối của các phiên trong phạm vi, được tính từ sự kiện hook cuối quan sát được."
}
},
"legendItems": {
"sessions": "Phiên",
"mainAgent": "Agent chính",
"subagentTypes": "Loại subagent",
"compactions": "Lần nén",
"completed": "Hoàn thành",
"error": "Lỗi",
"abandoned": "Bị bỏ dở"
}
},
"drillIn": {
@@ -230,7 +239,9 @@
"noEvents": "Không có sự kiện cho phiên này.",
"showingOf": "Đang hiển thị 100 / {{total}} sự kiện",
"sessionInfo": " phiên - hoạt động {{from}}%-{{to}} thời lượng phiên",
"sortedByCompaction": " phiên (sắp theo số lần nén ngữ cảnh)"
"sortedByCompaction": " phiên (sắp theo số lần nén ngữ cảnh)",
"openSession": "Mở phiên",
"openInWorkspace": "Mở trong workspace"
},
"lanes": {
"title": "Tỉ lệ pass các node pipeline",
@@ -316,5 +327,7 @@
"sessions_one": "{{count}} phiên",
"sessions_other": "{{count}} phiên",
"pluginBreakdown": "{{skills}} skill được dùng · {{skillCalls}} lần gọi skill · {{mcpCalls}} lần gọi tool MCP"
}
},
"selectedNode": "Đang chọn:",
"clearSelection": "Bỏ chọn"
}