chore: checkpoint current performance and UI changes

This commit is contained in:
thanhnv
2026-09-16 00:05:34 +09:00
parent cbae2604db
commit 7607f44030
10 changed files with 205 additions and 43 deletions
+17 -4
View File
@@ -115,10 +115,23 @@ class ChatAgentsMixin:
if err:
self.status_message.emit(tr("chatpanel.agent_list_error", err=err))
w = AgentWorker(job)
w.finished_ok.connect(done)
self._agent_worker = w
w.start()
# Model discovery can involve a provider/network request. Constructing
# the chat panel during startup must not wait for it; schedule it after
# the first event-loop turn so the initial shell can paint immediately.
from PySide6.QtCore import QTimer
if getattr(self, "_agent_refresh_pending", False):
return
self._agent_refresh_pending = True
def start_worker() -> None:
self._agent_refresh_pending = False
w = AgentWorker(job)
w.finished_ok.connect(done)
self._agent_worker = w
w.start()
QTimer.singleShot(0, start_worker)
def _populate_agents(self, models, keep: str) -> None:
"""Đổ danh sách vào bộ chọn Agent.
+11 -2
View File
@@ -51,6 +51,8 @@ class MessageBubble(QFrame):
super().__init__()
self.role = role
self._text = ""
self._stream_pending = False
self._render_count = 0
self._collapsible = collapsible
self._title = title
self._head = None
@@ -164,12 +166,20 @@ class MessageBubble(QFrame):
def append_delta(self, delta: str) -> None:
"""Nối thêm một mẩu văn bản đang phát dần từ model rồi vẽ lại dạng markdown."""
self._text += delta
self.set_markdown(self._text)
if not self._stream_pending:
self._stream_pending = True
QTimer.singleShot(40, self.flush_stream)
def flush_stream(self) -> None:
if self._stream_pending:
self._stream_pending = False
self.set_markdown(self._text)
def set_markdown(self, text: str) -> None:
"""Đặt toàn bộ nội dung, hiển thị dạng markdown, rồi co giãn lại chiều cao."""
self._text = text
self.body.setMarkdown(text)
self._render_count += 1
self._autosize()
if self._collapsible:
self._update_head()
@@ -393,4 +403,3 @@ class ChatView(QScrollArea):
ChatHistoryWidget = ChatView
__all__ = ["ChatView", "ChatHistoryWidget", "MessageBubble"]
+8 -6
View File
@@ -19,6 +19,7 @@ from PySide6.QtWidgets import QHBoxLayout, QLabel, QTabWidget, QVBoxLayout, QWid
from ...core import audit_log
from ...i18n import on_language_changed, tr
from ...state import AppContext
from ...performance import span
from .tabs.action_logs_tab import ActionLogsTab
from .tabs.agent_status_tab import AgentStatusTab
from .tabs.mcp_tab import McpTab
@@ -282,12 +283,13 @@ class MonitoringTab(QWidget):
"""
start = date.today() - timedelta(days=_LOG_WINDOW_DAYS)
shared_dir = self.ctx.config.shared_dir
if shared_dir:
from ...core import telemetry_shared
shared_events = telemetry_shared.load_shared_audit_events(shared_dir, start=start)
if shared_events:
return shared_events
return audit_log.load_events(start=start)
with span("monitoring.load_events", window_days=_LOG_WINDOW_DAYS):
if shared_dir:
from ...core import telemetry_shared
shared_events = telemetry_shared.load_shared_audit_events(shared_dir, start=start)
if shared_events:
return shared_events
return audit_log.load_events(start=start)
def _apply_events_to_event_tabs(self, events: List[dict]) -> None:
"""Filters the ALREADY-LOADED event list (see ``_load_events`` — one
+2 -5
View File
@@ -32,9 +32,7 @@ from .rail_metrics import _NAV_MIN_WIDTH
from .tray_manager import TrayManager
from ...state import AppContext
from ...core.task_scheduler import TaskScheduler
from ...ui.cowork_tab import CoworkTab
from ...ui.sidebar import HistorySidebar
from ..graph.structure_graph_view import StructureGraphView
from ...ui.workspace_tab import WorkspaceTab
@@ -111,10 +109,9 @@ class MainWindow(NavRailMixin, RailProjectMixin, TopBarMixin,
# Workspace screen (per selected project). GraphRAG's heavy
# QtWebEngine is still built lazily on first display
# (StructureGraphView._ensure_web).
from ...ui.cowork_tab import CoworkTab
self.cowork = CoworkTab(ctx)
self.structure = StructureGraphView(ctx)
self.structure.status_message.connect(self.statusBar().showMessage)
self.cowork.output_changed.connect(self.structure.schedule_rescan)
self.structure = None
self.cowork.status_message.connect(self.statusBar().showMessage)
# Refresh History (list + running markers + current highlight) whenever a
# conversation is created/updated or a turn finishes.
+10 -2
View File
@@ -42,7 +42,14 @@ class SessionEventsMixin:
self.sidebar.refresh()
self._refresh_rail_recents() # the rail shortcut follows the panel
QTimer.singleShot(0, _do)
# Coalesce bursts from turn/tool/history signals into one sidebar read.
timer = getattr(self, "_history_refresh_timer", None)
if timer is None:
timer = QTimer(self)
timer.setSingleShot(True)
timer.timeout.connect(_do)
self._history_refresh_timer = timer
timer.start(0)
def _on_scheduled_task_done(self, task_id: str, ok: bool) -> None:
"""Desktop notification for a finished scheduled task (toast always,
tray balloon when the window isn't focused), then refresh History —
@@ -106,4 +113,5 @@ class SessionEventsMixin:
"""Project được tạo/sửa/xoá: gom nhóm lại cột lịch sử và cập nhật nhãn thư mục."""
self.sidebar.refresh() # History regroups by project
self.cowork._apply_output_folder_label() # project may have been renamed
self.structure._refresh_project_combo() # GraphRAG's project lock list follows too
if getattr(self, "structure", None) is not None:
self.structure._refresh_project_combo() # GraphRAG's project lock list follows too