Files
cowork-local/docs/architecture/co4e-split-map.md
T
lamhv7andClaude Sonnet 5 0631abf85f feat(co4e): tách 6 widget UI khỏi ui/co4e_tab.py sang presentation/co4e/*
Lane N3 (Co4E Studio) — dùng bộ workflow refactor-god-file, mỗi bước có
characterization test trước khi tách, hậu kiểm ranh giới tầng sau mỗi bước:

- skills_list_panel.py / agent_list_panel.py — 2 khu vực sidebar
- co4e_canvas_widget.py + canvas_items.py + canvas_interaction_mixin.py —
  Co4ECanvas tách 3 file (vượt 400 dòng nếu đứng một mình)
- node_property_panel.py + node_property_actions_mixin.py +
  step_config_section.py — StepConfigPanel, cùng lý do
- co4e_run_control_widget.py — RunsPagePanel (trang Flow Status)
- co4e_chat_view.py — ChatPanel + _ChatInput + helper autocomplete
- palette_list.py — _PaletteList dời khỏi ui/co4e_tab.py, hết import ngược
  presentation -> ui (agent/skills panel giờ import top-level)

ui/co4e_tab.py giảm 2089 -> 1878 dòng, chỉ còn phần wiring + business logic
(Co4ERunManager/AgentWorker chưa đổi — nằm ngoài phạm vi này, xem docstring
presentation/co4e/co4e_tab.py). ui/co4e_canvas.py và ui/co4e_config_panel.py
còn lại là compat shim re-export, không đổi API cho bên gọi.

Thêm tests/test_co4e_integration.py — dựng thật Co4ETab qua build_co4e_tab(),
lái luồng qua nhiều panel trong cùng instance (thêm node, mở/gập chat, chuyển
trang Flow Status rồi quay lại không mất state canvas) — bắt lỗi wiring
xuyên-panel mà characterization test từng panel riêng không thấy được.

Đã xác minh: pytest 348 passed/1 skipped, tools/check_co4e.py sạch, không
file nào >400 dòng, domain/application không import PySide6, và so pixel
before/after (git worktree tại HEAD cũ) ra 0/1.125.000 pixel khác biệt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 18:43:42 +09:00

79 KiB

Bản đồ tách file Co4E (gộp từ 6 agent quét song song)

  • Tổng số symbol quét được (thô, tính cả trùng): 367
  • Tổng số dòng trong bản đồ cuối cùng (sau gộp trùng): 363
  • Số nhóm ký hiệu bị quét trùng bởi 2 agent (đã gộp làm 1 dòng): 4 (Co4ECanvas.dropEvent, Co4ETab._co4e_routed_provider, Co4ETab._config_expanded_w, Co4ETab._reload_sidebar)
  • Số ký hiệu có 2 định nghĩa thật ở 2 dòng khác nhau, giữ riêng và gắn cờ: 1 (Co4ETab.showEvent)
  • EXPECTED (tools/check_co4e.py) có 27 phần tử; kết quả đối chiếu: OK — cả 27 xuất hiện đúng 1 lần, có target cụ thể
  • Số note bắt đầu bằng khac tai lieu:: 0 (không có -> không có mục 'Chỗ thấy khác tài liệu' nào phát sinh từ tiêu chí này)

Ghi chú về gộp trùng (5 ký hiệu bị 2 agent cùng quét thấy)

Co4ETab._config_expanded_w

  • dòng 275-275, target agent gốc đề xuất = presentation/co4e/co4e_tab.py — cùng lý do với _config_collapsed
  • dòng 995-995, target agent gốc đề xuất = presentation/co4e/co4e_tab.py — gán trong nhánh collapse của _toggle_config; có thể đã khởi tạo trong init (ngoài phạm vi đọc).
  • Quyết định gộp: 1 dòng, target cuối = presentation/co4e/co4e_tab.py, dòng 275; 995

Co4ETab._reload_sidebar

  • dòng 689-700, target agent gốc đề xuất = presentation/co4e/co4e_tab.py — cắt ngang lát — cần agent gộp đối chiếu (method tiếp tục sau dòng 700); gọi co4e.list_workflows() (đọc đĩa) rồi dựng QListWidgetItem trực tiếp trong cùng hàm — trộn data-fetch và UI, nên tách phần đọc dữ liệu sang co4e_workflow_service.py
  • dòng 689-722, target agent gốc đề xuất = unsure — cắt ngang lát — cần agent gộp đối chiếu (bắt đầu trước dòng 701). Gộp refresh cả agent_list và skill_list trong cùng 1 hàm — nên tách thành _refresh_agents_list (agent_list_panel.py) và _refresh_skills_list (skills_list_panel.py) như plan.md yêu cầu; gọi co4e.list_custom_agents() (đĩa) và skills_mod.skill_prefix_for (đĩa).
  • Quyết định gộp: 1 dòng, target cuối = presentation/co4e/co4e_tab.py, dòng 689-722

Co4ETab.showEvent

  • dòng 973-975, target agent gốc đề xuất = presentation/co4e/co4e_tab.py — Qt override, gọi self._narrow_guard.attach() (đối tượng khởi tạo ngoài phạm vi đọc, <701).
  • dòng 1806-1809, target agent gốc đề xuất = presentation/co4e/co4e_tab.py — override Qt lifecycle method của chính QWidget container nên phải ở lại co4e_tab.py; gọi self._refresh_runs() (thuộc co4e_run_control_widget.py) — điểm nối giữa container và run-control widget.
  • Quyết định: đây là 2 định nghĩa method trùng tên thật sự tồn tại ở 2 vị trí khác nhau trong cùng class Co4ETab (khả năng cao là lỗi nguồn — định nghĩa sau đè định nghĩa trước, làm dòng logic ở định nghĩa trước thành dead code). Giữ nguyên 2 dòng riêng biệt trong bản đồ, KHÔNG gộp, và cần người quyết định giữ định nghĩa nào.

Co4ETab._co4e_routed_provider

  • dòng 1114-1114, target agent gốc đề xuất = presentation/co4e/co4e_chat_view.py — override provider cho lượt chat kế tiếp — dùng bởi _apply_co4e_routing (ngoài phạm vi đọc, >1400).
  • dòng 1853-1853, target agent gốc đề xuất = presentation/co4e/co4e_chat_view.py — gán None lần đầu tại đây (trong _apply_co4e_routing); đọc bằng getattr(self, '_co4e_routed_provider', None) ở _run_chat_turn dòng ~1922 — gợi ý có thể không được init trong init. Trạng thái routing theo từng lượt chat, dùng chung giữa chat-view và _start_canvas_run/manager.start.
  • Quyết định gộp: 1 dòng, target cuối = presentation/co4e/co4e_chat_view.py, dòng 1114; 1853

Co4ECanvas.dropEvent

  • dòng 683-700, target agent gốc đề xuất = presentation/co4e/co4e_canvas_widget.py — cắt ngang lát — cần agent gộp đối chiếu (thân try chưa đóng ở dòng 700, còn tiếp; xử lý JSON từ mimeData trong bộ nhớ, không phải file đĩa nên touches_disk_or_network=false)
  • dòng 683-701, target agent gốc đề xuất = presentation/co4e/co4e_canvas_widget.py — cắt ngang lát — cần agent gộp đối chiếu. Method dropEvent bắt đầu ở dòng 683 (ngoài khoảng được giao 701-791), chỉ dòng 701 (e.acceptProposedAction()) nằm trong lát này; dòng 702 là dòng trống cuối file. File ui/co4e_canvas.py chỉ có 702 dòng — không có nội dung nào khác trong khoảng 702-791 vì đã hết file. Xử lý drop từ sidebar (kind=='workflow' → add_workflow, ngược lại → add_palette_step) — logic thao tác node/canvas nên khớp nhóm _add_node/_connect_nodes trong bảng plan.md dòng 623 dù plan.md không liệt kê rõ dropEvent.
  • Quyết định gộp: 1 dòng, target cuối = presentation/co4e/co4e_canvas_widget.py, dòng 683-701

Bảng đầy đủ

symbol dòng file đích lý do có trong bảng cũ chưa chỗ nào thấy bảng cũ sai
Co4ETab._flow_outputs 245 application/workflows/co4e_workflow_service.py state per-flow outputs — ứng viên chuyển vào state machine thuần Python chua/khong ro -
Co4ETab._outputs_for 475-478 application/workflows/co4e_workflow_service.py truy cập dict state per-flow outputs, thuần Python chua/khong ro -
Co4ETab._duplicate_selected_workflow 1239-1246 application/workflows/co4e_workflow_service.py tương ứng _duplicate_flow() trong bảng plan.md dòng 616, nhưng tên hàm thực tế khác (_duplicate_selected_workflow). Gộp gọi service (co4e.duplicate_workflow, đĩa) với cập nhật UI (self._reload_sidebar(), self.status_message.emit) — cần tách; phần UI nên ở lại co4e_tab.py. co ate_flow() trong bảng plan.md dòng 616, nhưng tên hàm thực tế khác (_duplicate_selected_workflow). Gộp gọi service (co4e.duplicate_workflow, đĩa)
Co4ETab._rename_workflow 1273-1289 application/workflows/co4e_workflow_service.py mở QInputDialog (cần Qt) rồi gọi co4e.save_workflow (đĩa), đồng bộ self._wf.name/self.name_edit nếu flow đang mở là flow bị đổi tên — gộp UI dialog + service + trạng thái chia sẻ self._wf trong 1 hàm, nên tách. chua/khong ro -
Co4ETab._delete_selected_workflow 1291-1297 application/workflows/co4e_workflow_service.py tương ứng _delete_flow() trong bảng plan.md dòng 616; gọi co4e.delete_workflow (đĩa). co -
Co4ETab._save 1304-1309 application/workflows/co4e_workflow_service.py gộp _sync_wf_from_canvas (đọc canvas UI), lưu đĩa (co4e.save_workflow), và cập nhật UI (_reload_sidebar, status_message) — cần tách phần service khỏi phần UI khi chuyển sang co4e_workflow_service.py. chua/khong ro -
Co4ETab._autosave 1311-1314 application/workflows/co4e_workflow_service.py gọi self._sync_wf_from_canvas() (cần canvas) rồi co4e.get_workflow/save_workflow (đĩa). chua/khong ro -
Co4ETab._skill_map 1376-1382 application/workflows/co4e_workflow_service.py chuẩn bị nội dung skill (skills_mod.skill_prefix_for, đọc đĩa) để đưa vào lúc chạy flow/chat — không có trong bảng plan.md, tự xếp theo chức năng (dùng lúc run/build system prompt, không phải UI danh sách skill). co ọc đĩa) để đưa vào lúc chạy flow/chat — không có trong bảng plan.md, tự xếp theo chức năng (dùng lúc run/build system prompt, không phải UI danh sá
Co4ETab.ag_new_btn 550 presentation/co4e/agent_list_panel.py hiện định nghĩa trực tiếp trong Co4ETab._build_sidebar — ứng viên chuyển sang agent_list_panel.py tương tự cách skills đã tách chua/khong ro -
Co4ETab.agent_list 558 presentation/co4e/agent_list_panel.py cùng lý do với ag_new_btn chua/khong ro -
Co4ETab.ag_edit_btn 562 presentation/co4e/agent_list_panel.py cùng lý do với ag_new_btn chua/khong ro -
Co4ETab.ag_del_btn 563 presentation/co4e/agent_list_panel.py cùng lý do với ag_new_btn chua/khong ro -
Co4ETab._new_agent 1339-1340 presentation/co4e/agent_list_panel.py tương ứng _create_agent() trong bảng plan.md dòng 620 (tên hàm thực tế là _new_agent). co -
Co4ETab._edit_agent 1342-1350 presentation/co4e/agent_list_panel.py khớp _edit_agent() dòng 620 plan.md; gọi co4e.list_custom_agents() (đĩa). co -
Co4ETab._edit_agent_dialog 1352-1358 presentation/co4e/agent_list_panel.py mở Co4EAgentDialog rồi co4e.save_custom_agent (đĩa) và self._reload_sidebar() — trạng thái chia sẻ, liên quan tới cắt ngang lát ở _reload_sidebar. chua/khong ro -
Co4ETab._delete_agent 1360-1367 presentation/co4e/agent_list_panel.py khớp _delete_agent() dòng 620 plan.md; gọi co4e.delete_custom_agent (đĩa). co -
_status_color 43-50 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_NodeItem 59-210 presentation/co4e/co4e_canvas_widget.py class nội bộ gắn chặt với Co4ECanvas qua self.canvas backreference — nên đi cùng file với Co4ECanvas chua/khong ro -
_NodeItem.init 62-72 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_NodeItem.node 64 presentation/co4e/co4e_canvas_widget.py giữ tham chiếu domain Node — dữ liệu chia sẻ với core/co4e.py chua/khong ro -
_NodeItem.canvas 65 presentation/co4e/co4e_canvas_widget.py backreference tới Co4ECanvas cha — mọi event của _NodeItem đều gọi ngược lên canvas (add_step_below, begin_connect, delete_node, các signal) — điểm khớp nối chặt nhất trong file chua/khong ro -
_NodeItem.status 66 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_NodeItem._porting 67 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_NodeItem.boundingRect 74-76 presentation/co4e/co4e_canvas_widget.py trả QRectF như kiểu giá trị, logic thuần chua/khong ro -
_NodeItem._card_rect 78-79 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_NodeItem.paint 81-139 presentation/co4e/co4e_canvas_widget.py vẽ toàn bộ card: nền, header stripe, label, badge role, preview instructions/sub-agents, footer model/skills, 2 port — gộp nhiều việc nhưng vẫn dưới 80 dòng nên chưa bắt buộc tách thêm chua/khong ro -
_NodeItem._in_out_port 141-143 presentation/co4e/co4e_canvas_widget.py hình học thuần dùng QPointF như kiểu giá trị chua/khong ro -
_NodeItem.itemChange 145-156 presentation/co4e/co4e_canvas_widget.py ghi self.node.x/y rồi gọi self.canvas._reposition_edges() và emit self.canvas.graph_changed/node_selected — chạm trạng thái chia sẻ của canvas cha chua/khong ro -
_NodeItem.hoverMoveEvent 158-161 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_NodeItem.mousePressEvent 163-174 presentation/co4e/co4e_canvas_widget.py đọc/ghi self.canvas._connect_from, gọi canvas._finish_connect/begin_port_drag — trạng thái connect-mode chia sẻ với Co4ECanvas chua/khong ro -
_NodeItem.mouseMoveEvent 176-181 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_NodeItem.mouseReleaseEvent 183-189 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_NodeItem.mouseDoubleClickEvent 191-193 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_NodeItem.contextMenuEvent 195-207 presentation/co4e/co4e_canvas_widget.py gọi canvas.add_step_below/begin_connect/delete_node — trạng thái/hành vi thuộc canvas cha chua/khong ro -
_NodeItem.center 209-210 presentation/co4e/co4e_canvas_widget.py trả QPointF như kiểu giá trị chua/khong ro -
_EdgeItem 213-286 presentation/co4e/co4e_canvas_widget.py class nội bộ gắn chặt với Co4ECanvas qua self.canvas backreference chua/khong ro -
_EdgeItem.init 214-225 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_EdgeItem.edge 216 presentation/co4e/co4e_canvas_widget.py tham chiếu domain Edge — chia sẻ với core/co4e.py chua/khong ro -
_EdgeItem.canvas 217 presentation/co4e/co4e_canvas_widget.py backreference tới Co4ECanvas — contextMenuEvent gọi canvas.delete_edge chua/khong ro -
_EdgeItem._dst 218 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_EdgeItem._hover 224 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_EdgeItem._apply_pen 227-235 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_EdgeItem.update_path 237-239 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_EdgeItem.boundingRect 241-242 presentation/co4e/co4e_canvas_widget.py gọi super().boundingRect() phụ thuộc trạng thái path sống của item chua/khong ro -
_EdgeItem.shape 244-249 presentation/co4e/co4e_canvas_widget.py dùng QPainterPathStroker trên self.path() sống của item chua/khong ro -
_EdgeItem.hoverEnterEvent 251-255 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_EdgeItem.hoverLeaveEvent 257-261 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_EdgeItem.paint 263-279 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_EdgeItem.contextMenuEvent 281-286 presentation/co4e/co4e_canvas_widget.py gọi self.canvas.delete_edge(self.edge) chua/khong ro -
Co4ECanvas 289-700 presentation/co4e/co4e_canvas_widget.py cắt ngang lát — class tiếp tục sau dòng 700 (dropEvent chưa kết thúc, có thể còn method khác chưa đọc) — cần agent gộp đối chiếu với phần đọc dòng 701+ chua/khong ro -
Co4ECanvas.node_selected 290 presentation/co4e/co4e_canvas_widget.py Signal được node_property_panel.py (và co4e_tab.py) nối vào để nạp node được chọn — điểm chia sẻ giữa canvas và property panel chua/khong ro -
Co4ECanvas.node_activated 291 presentation/co4e/co4e_canvas_widget.py Signal double-click, có thể được co4e_tab.py nối để mở panel chỉnh sửa — cần kiểm nơi consume chua/khong ro -
Co4ECanvas.graph_changed 292 presentation/co4e/co4e_canvas_widget.py Signal báo graph đổi (autosave) — nhiều khả năng được co4e_tab.py/co4e_workflow_service.py nối để lưu flow, trạng thái chia sẻ xuyên lớp application chua/khong ro -
Co4ECanvas.init 296-315 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._scene 299 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._nodes 305 presentation/co4e/co4e_canvas_widget.py dict id->_NodeItem — trạng thái trung tâm được đọc/ghi bởi gần như mọi method của Co4ECanvas (add/delete/relayout/zoom/status/route edges) chua/khong ro -
Co4ECanvas._edges 306 presentation/co4e/co4e_canvas_widget.py list _EdgeItem — trạng thái trung tâm tương tự self._nodes chua/khong ro -
Co4ECanvas._connect_from 307 presentation/co4e/co4e_canvas_widget.py trạng thái connect-mode, cũng được _NodeItem.mousePressEvent đọc/ghi qua self.canvas chua/khong ro -
Co4ECanvas._zoom 308 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._panning 309 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._pan_start 310 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._overlay 311 presentation/co4e/co4e_canvas_widget.py widget zoom/fit overlay được co4e_tab.py hoặc co4e_canvas_widget.py truyền vào qua add_overlay() chua/khong ro -
Co4ECanvas._port_src 313 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._port_src_pt 314 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._temp_edge 315 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.add_overlay 318-323 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._place_overlay 325-330 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.resizeEvent 332-334 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.scrollContentsBy 336-341 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.showEvent 343-345 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.load 348-362 presentation/co4e/co4e_canvas_widget.py reset toàn bộ self._nodes/self._edges/self._connect_from/self._port_src/self._temp_edge — điểm nạp lại state từ flow, được co4e_tab.py hoặc co4e_workflow_service.py gọi khi mở flow chua/khong ro -
Co4ECanvas.nodes 364-365 presentation/co4e/co4e_canvas_widget.py chỉ đọc .node từ self._nodes, không gọi API Qt trực tiếp chua/khong ro -
Co4ECanvas.edges 367-368 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.add_node 371-382 presentation/co4e/co4e_canvas_widget.py ghi self._nodes, scene.addItem, emit graph_changed/node_selected — trạng thái chia sẻ với property panel qua node_selected chua/khong ro -
Co4ECanvas.add_step_below 384-390 presentation/co4e/co4e_canvas_widget.py orchestration thuần, ủy quyền cho add_node (bản thân không gọi trực tiếp API Qt) chua/khong ro -
Co4ECanvas._chain_tail 392-396 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.add_palette_step 398-400 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.begin_connect 402-403 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._finish_connect 405-409 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.begin_port_drag 412-419 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.update_port_drag 421-424 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.finish_port_drag 426-435 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._node_at 437-441 presentation/co4e/co4e_canvas_widget.py dùng self._scene.items(scene_pt) — cần scene đang sống chua/khong ro -
Co4ECanvas._make_edge 443-451 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._add_edge_item 453-456 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.delete_edge 458-463 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.delete_node 465-475 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.delete_selected 477-481 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._zoom_by 484-495 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.zoom_in 497-498 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.zoom_out 500-501 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.reset_zoom 503-505 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.wheelEvent 507-519 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.mousePressEvent 522-529 presentation/co4e/co4e_canvas_widget.py trùng tên với _NodeItem.mousePressEvent nhưng là override của Co4ECanvas (pan chuột giữa) — đừng nhầm khi gộp map chua/khong ro -
Co4ECanvas.mouseMoveEvent 531-540 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.mouseReleaseEvent 542-548 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.fit_view 550-558 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.relayout 560-578 presentation/co4e/co4e_canvas_widget.py phần tính waves/cols (compute_waves, defaultdict) là logic thuần, phần item.setPos() cần scene sống — có thể tách hàm tính toạ độ ra khỏi phần apply nếu muốn test thuần Python chua/khong ro -
Co4ECanvas.relayout_if_vertical 580-589 presentation/co4e/co4e_canvas_widget.py bản thân chỉ ra quyết định thuần dựa trên node.x, việc chạm Qt nằm trong relayout() được gọi chua/khong ro -
Co4ECanvas.add_workflow 591-610 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.update_node_status 612-616 presentation/co4e/co4e_canvas_widget.py được co4e_run_control_widget.py gọi khi step chạy/xong/lỗi — điểm nối giữa canvas và run control chua/khong ro -
Co4ECanvas.reset_statuses 618-621 presentation/co4e/co4e_canvas_widget.py được co4e_run_control_widget.py gọi khi bắt đầu run mới chua/khong ro -
Co4ECanvas.refresh_node 623-626 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas._node_rects 628-638 presentation/co4e/co4e_canvas_widget.py dựng QRectF như kiểu giá trị từ item.pos() — logic hình học thuần chua/khong ro -
Co4ECanvas._reposition_edges 640-649 presentation/co4e/co4e_canvas_widget.py gọi e.update_path (setPath) trên item sống, dùng hàm định tuyến _route từ canvas_geometry.py chua/khong ro -
Co4ECanvas.keyPressEvent 652-669 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.dragEnterEvent 671-675 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.dragMoveEvent 677-681 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ECanvas.dropEvent 683-701 presentation/co4e/co4e_canvas_widget.py [GỘP 2 lượt quét trùng ký hiệu] (dòng 683-700, target gốc=presentation/co4e/co4e_canvas_widget.py) cắt ngang lát — cần agent gộp đối chiếu (thân try chưa đóng ở dòng 700, còn tiếp; xử lý JSON từ mimeData trong bộ nhớ, không phải file đĩa nên touches_disk_or_network=false) || (dòng 683-701, target gốc=presentation/co4e/co4e_canvas_widget.py) cắt ngang lát — cần agent gộp đối chiếu. Method dropEvent bắt đầu ở dòng 683 (ngoài khoảng được giao 701-791), chỉ dòng 701 (e.acceptProposedAction()) nằm trong lát này; dòng 702 là dòng trống cuối file. File ui/co4e_canvas.py chỉ có 702 dòng — không có nội dung nào khác trong khoảng 702-791 vì đã hết file. Xử lý drop từ sidebar (kind=='workflow' → add_workflow, ngược lại → add_palette_step) — logic thao tác node/canvas nên khớp nhóm _add_node/_connect_nodes trong bảng plan.md dòng 623 dù plan.md không liệt kê rõ dropEvent. co nnect_nodes trong bảng plan.md dòng 623 dù plan.md không liệt kê rõ dropEvent.
Co4ETab.canvas 856 presentation/co4e/co4e_canvas_widget.py TRẠNG THÁI CHIA SẺ lớn nhất trong file — self.canvas được đọc/ghi ở gần như mọi nhóm chức năng khác (sync_wf_from_canvas, apply_workflow, node selection, run, add_blank_step...). chua/khong ro -
Co4ETab._build_canvas_overlay 1041-1062 presentation/co4e/co4e_canvas_widget.py dựng nút zoom/fit gắn vào self.canvas.add_overlay(bar); các slot gọi thẳng self.canvas.zoom_in/zoom_out/fit_view (thuộc nhóm 3.2.2.21-22 trong plan.md → co4e_canvas_widget.py). Có thể tranh cãi nên giữ ở co4e_tab.py (được gọi từ _build_center) — ghi lại để người soát quyết. co -
Co4ETab.zoom_in_btn 1054 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ETab.zoom_out_btn 1055 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
Co4ETab.fit_btn 1056 presentation/co4e/co4e_canvas_widget.py (không có ghi chú) chua/khong ro -
_skill_names 61-65 presentation/co4e/co4e_chat_view.py gọi skills_mod.list_skills()/builtin_skills() (đọc đĩa); dùng cho autocomplete /skill: trong _ChatInput — cũng liên quan skills_list_panel.py vì cùng nguồn dữ liệu chua/khong ro -
_agent_names 68-71 presentation/co4e/co4e_chat_view.py gọi co4e.list_custom_agents() (đọc đĩa); dùng cho autocomplete /agent: trong _ChatInput — cũng liên quan agent_list_panel.py vì cùng nguồn dữ liệu chua/khong ro -
_directive_token 122-134 presentation/co4e/co4e_chat_view.py logic regex thuần Python, test được không cần Qt chua/khong ro -
_ChatInput 137-226 presentation/co4e/co4e_chat_view.py khai báo 'submit = Signal()' ở dòng 141 là thuộc tính lớp (không phải self.) chua/khong ro -
_ChatInput.init 143-151 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
_ChatInput._popup 145 presentation/co4e/co4e_chat_view.py QListWidget popup autocomplete chua/khong ro -
_ChatInput._maybe_popup 153-178 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
_ChatInput._add_row 180-184 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
_ChatInput._accept 186-199 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
_ChatInput.focusOutEvent 201-204 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
_ChatInput.keyPressEvent 206-226 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
Co4ETab._chat_worker 236 presentation/co4e/co4e_chat_view.py AgentWorker của chat, hiện giữ trên Co4ETab chua/khong ro -
Co4ETab._build_chat 1064-1127 presentation/co4e/co4e_chat_view.py dài ~63 dòng, gộp: header 'Messages' + toggle, chat_stack (QStackedWidget chứa 1 ChatView/flow), input row + usage label + composer + routing toggle. Tạo self._flow_logs (Dict[str, ChatView]) — TRẠNG THÁI CHIA SẺ dùng bởi _ensure_flow_log/_active_log/chat_log/_apply_workflow (self._wf) — điểm dễ vỡ nhất khi tách file chat ra khỏi co4e_tab.py. chua/khong ro -
Co4ETab._chat_widget 1066 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
Co4ETab._mhdr 1072 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
Co4ETab.msgs_icon 1074 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
Co4ETab.msgs_title 1075 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
Co4ETab.chat_toggle_btn 1076 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
Co4ETab.chat_stack 1091 presentation/co4e/co4e_chat_view.py chuyển self.center_stack tương tự — dùng chung với self.center_stack (co4e_tab.py). chua/khong ro -
Co4ETab._flow_logs 1092 presentation/co4e/co4e_chat_view.py Dict[str, ChatView] keyed theo workflow id — TRẠNG THÁI CHIA SẺ chính của toàn bộ logic chat theo-flow; đọc/ghi bởi _ensure_flow_log, _active_log, chat_log, _apply_workflow, và các hàm chat khác ngoài phạm vi đọc (>1400). chua/khong ro -
Co4ETab.chat_input_row 1094 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
Co4ETab._usage_total_lbl 1099 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
Co4ETab.chat_input 1105 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
Co4ETab.chat_send_btn 1108 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
Co4ETab.co4e_routing_toggle 1113 presentation/co4e/co4e_chat_view.py RoutingToggle(self.ctx, 'co4e') — self.ctx là trạng thái chia sẻ của cả Co4ETab (khởi tạo ngoài phạm vi đọc). chua/khong ro -
Co4ETab._co4e_routed_provider 1114; 1853 presentation/co4e/co4e_chat_view.py [GỘP 2 lượt quét trùng ký hiệu] (dòng 1114-1114, target gốc=presentation/co4e/co4e_chat_view.py) override provider cho lượt chat kế tiếp — dùng bởi _apply_co4e_routing (ngoài phạm vi đọc, >1400). || (dòng 1853-1853, target gốc=presentation/co4e/co4e_chat_view.py) gán None lần đầu tại đây (trong _apply_co4e_routing); đọc bằng getattr(self, '_co4e_routed_provider', None) ở _run_chat_turn dòng ~1922 — gợi ý có thể không được init trong init. Trạng thái routing theo từng lượt chat, dùng chung giữa chat-view và _start_canvas_run/manager.start. chua/khong ro [GỘP 2 lượt quét trùng ký hiệu] (dòng 1114-1114, target gốc=presentation/co4e/co4e_chat_view.py) overr
Co4ETab._vsplit_sizes 1121 presentation/co4e/co4e_chat_view.py dùng bởi _toggle_messages để restore kích thước splitter — chia sẻ với self._vsplit (co4e_tab.py). chua/khong ro -
Co4ETab._msgs_collapsed 1122 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
Co4ETab._toggle_messages 1129-1161 presentation/co4e/co4e_chat_view.py thao tác self._vsplit (tạo ở co4e_tab.py/_build_center) — trạng thái chia sẻ giữa co4e_chat_view.py và co4e_tab.py. chua/khong ro -
Co4ETab._ensure_flow_log 1164-1173 presentation/co4e/co4e_chat_view.py đọc/ghi self._flow_logs — trạng thái chia sẻ chính của chat theo-flow. chua/khong ro -
Co4ETab._active_log 1175-1177 presentation/co4e/co4e_chat_view.py đọc self._wf — trạng thái chia sẻ với toàn bộ Co4ETab (canvas, sidebar, save/autosave, run control). chua/khong ro -
Co4ETab.chat_log 1180-1183 presentation/co4e/co4e_chat_view.py @property, chỉ đọc, uỷ nhiệm cho _active_log(). chua/khong ro -
Co4ETab._plan_bubble 1186-1187 presentation/co4e/co4e_chat_view.py @property getter, đọc self._active_log()._co4e_plan_bubble (thuộc tính gắn thêm vào từng instance ChatView). chua/khong ro -
Co4ETab._plan_bubble (setter) 1189-1191 presentation/co4e/co4e_chat_view.py @_plan_bubble.setter, ghi self._active_log()._co4e_plan_bubble. chua/khong ro -
Co4ETab._chat_send 1820-1846 presentation/co4e/co4e_chat_view.py self.chat_input.clear(), self._append_chat — thao tác widget; điều phối /agent /skill directive rồi gọi self._run_chat_turn (network qua provider, không trực tiếp trong hàm này) chua/khong ro -
Co4ETab._apply_co4e_routing 1848-1883 presentation/co4e/co4e_chat_view.py gọi confirm_switch (dialog Qt) khi mode=='manual' và self._append_chat khi có switch — cần widget sống. Gán self._co4e_routed_provider (xem attribute riêng). chua/khong ro -
Co4ETab._extract_agent_directive 1885-1891 presentation/co4e/co4e_chat_view.py regex thuần Python chua/khong ro -
Co4ETab._resolve_agent 1893-1901 presentation/co4e/co4e_chat_view.py tra cứu BUILTIN_AGENTS và co4e.list_custom_agents() (bộ nhớ/đĩa tùy triển khai list_custom_agents, không rõ trong khoảng đọc) — cross-reference với agent_list_panel.py (nguồn danh sách custom agent) chua/khong ro -
Co4ETab._run_chat_turn 1903-1974 presentation/co4e/co4e_chat_view.py 72 dòng, gộp: chuẩn bị prompt, tạo bubble stream, định nghĩa 4 closures nội bộ (job/on_event/done/failed) và khởi worker nền — nên tách các closures ra thành hàm riêng nếu dễ đọc hơn. Closure job() gọi run_cowork(provider,...) — network/AI call thật sự. Đọc/ghi self._chat_worker, self._co4e_routed_provider, self.chat_send_btn, self._wf; set log._co4e_plan_bubble=None (thuộc log là ChatView, không phải self). chua/khong ro -
Co4ETab._run_chat_turn.job 1917-1946 presentation/co4e/co4e_chat_view.py closure nội bộ của _run_chat_turn, chạy trong AgentWorker (thread nền); gọi run_cowork(provider,...) — network/AI call thật; dùng usage_tracker (đọc/ghi trạng thái tích lũy usage) chua/khong ro -
Co4ETab._run_chat_turn.on_event 1948-1954 presentation/co4e/co4e_chat_view.py closure nội bộ, cập nhật assistant.set_markdown và log.scroll_to_bottom (widget) chua/khong ro -
Co4ETab._run_chat_turn.done 1956-1962 presentation/co4e/co4e_chat_view.py closure nội bộ, gán self._chat_worker = None, thao tác widget assistant/log chua/khong ro -
Co4ETab._run_chat_turn.failed 1964-1967 presentation/co4e/co4e_chat_view.py closure nội bộ, gán self._chat_worker = None, gọi self._append_chat lỗi chua/khong ro -
Co4ETab._append_chat 1976-1991 presentation/co4e/co4e_chat_view.py nhận tham số log tùy chọn, mặc định self.chat_log — dùng bởi rất nhiều method ở cả run-control (qua tham số log truyền vào) và chat-view; điểm nối giữa hai nhóm. chua/khong ro -
Co4ETab._fmt_usage 1994-2001 presentation/co4e/co4e_chat_view.py format chuỗi thuần, đọc self.ctx.config.data — không chạm widget chua/khong ro -
Co4ETab._apply_usage 2003-2020 presentation/co4e/co4e_chat_view.py bub.add_usage(...) thao tác widget bubble; ghi self._flow_usage[wf_id] — trạng thái tổng usage theo flow, dùng chung với _refresh_usage_total chua/khong ro -
Co4ETab._refresh_usage_total 2022-2037 presentation/co4e/co4e_chat_view.py self._usage_total_lbl.setText — đọc self._wf, self._flow_usage chua/khong ro -
Co4ETab._append_diff 2039-2043 presentation/co4e/co4e_chat_view.py (không có ghi chú) chua/khong ro -
Co4ETab._append_plan 2045-2056 presentation/co4e/co4e_chat_view.py đọc/ghi log._co4e_plan_bubble (thuộc tính động trên đối tượng log/ChatView, không phải self) chua/khong ro -
_html_escape 2082-2083 presentation/co4e/co4e_chat_view.py hàm module-level (ngoài class Co4ETab), escape HTML thuần, dùng cho hiển thị chat chua/khong ro -
_PLAN_GLYPH 45-46 presentation/co4e/co4e_run_control_widget.py module-level dict glyph trạng thái dùng bởi _fmt_plan chua/khong ro -
_fmt_plan 49-58 presentation/co4e/co4e_run_control_widget.py helper thuần Python dùng bởi _render_plan() chua/khong ro -
Co4ETab.manager 238 presentation/co4e/co4e_run_control_widget.py Co4ERunManager — lõi run control, trạng thái chia sẻ với canvas (node status) và chat view (run_logs) chua/khong ro -
Co4ETab._flow_runs 243 presentation/co4e/co4e_run_control_widget.py map wf_id->run id, chia sẻ với _open_flow/_close_flow_tab (co4e_tab.py) và canvas chua/khong ro -
Co4ETab._run_logs 244 presentation/co4e/co4e_run_control_widget.py map run_id->ChatView, chia sẻ với co4e_chat_view.py chua/khong ro -
Co4ETab._flow_usage 248 presentation/co4e/co4e_run_control_widget.py usage token/cost theo flow, hiển thị ở Messages header chua/khong ro -
Co4ETab._manual_active 252 presentation/co4e/co4e_run_control_widget.py chia sẻ với _close_flow_tab (co4e_tab.py) — set lại self.run_btn khi đóng tab chua/khong ro -
Co4ETab._manual_order 253 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab._manual_idx 254 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab._cur_run_id 460-473 presentation/co4e/co4e_run_control_widget.py logic thuần Python, không gọi Qt trực tiếp chua/khong ro -
Co4ETab._update_run_btn 480-482 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab.runs_more_btn 586 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab.runs_side_list 594 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab._SIDE_RUNS 605 presentation/co4e/co4e_run_control_widget.py class-level constant, không phải self. chua/khong ro -
Co4ETab._refresh_side_runs 607-619 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab._on_side_run_clicked 621-629 presentation/co4e/co4e_run_control_widget.py chạm self.runs_table (định nghĩa ngoài khoảng đọc — thuộc trang Flow Status) chua/khong ro -
Co4ETab.mode_combo 828 presentation/co4e/co4e_run_control_widget.py combo chọn run mode auto/plan/manual — thuộc nhóm _set_run_mode() trong plan.md dù được dựng bên trong _build_center (co4e_tab.py); ranh giới tách file ở đây dễ vỡ. co -
Co4ETab.run_btn 833 presentation/co4e/co4e_run_control_widget.py nút Run — tương tự mode_combo, dựng trong _build_center nhưng thuộc nhóm run control; cũng bị _update_run_btn (<701), _on_run_clicked, _on_mode_changed đọc/ghi text. chua/khong ro -
Co4ETab.runs_btn 840 presentation/co4e/co4e_run_control_widget.py toggle chuyển sang trang Runs (self.center_stack) — chia sẻ state center_stack với co4e_tab.py. chua/khong ro -
Co4ETab._build_runs_page 873-932 presentation/co4e/co4e_run_control_widget.py dựng trang bảng Runs (theo dõi mọi run của mọi flow) — dùng self.manager (Co4ERunManager, sẽ thay bằng co4e_workflow_service) — trạng thái chia sẻ. chua/khong ro -
Co4ETab.runs_back_btn 882 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab.runs_title 887 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab.ws_folder_btn 892 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab.run_stop_btn 900 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab.run_rename_btn 905 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab.run_del_btn 909 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab.run_clear_btn 913 presentation/co4e/co4e_run_control_widget.py clicked gọi self.manager.clear_finished() — trạng thái chia sẻ self.manager. chua/khong ro -
Co4ETab.runs_table 921 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab._current_mode 1384-1385 presentation/co4e/co4e_run_control_widget.py đọc self.mode_combo — khớp nhóm _set_run_mode() dòng 624 plan.md. co -
Co4ETab._on_mode_changed 1387-1393 presentation/co4e/co4e_run_control_widget.py reset self._manual_active/_manual_order/_manual_idx (trạng thái chia sẻ với luồng manual step _manual_step/_manual_run_or_advance, ngoài phạm vi đọc >1400) và gọi self._cur_run_id() (chia sẻ với self.manager). chua/khong ro -
Co4ETab._on_run_clicked 1395-1400 presentation/co4e/co4e_run_control_widget.py cắt ngang lát — cần agent gộp đối chiếu (tiếp tục sau dòng 1400). Dùng self.manager.stop() và self._cur_run_id() — trạng thái chia sẻ với co4e_workflow_service tương lai. Khớp nhóm _run_flow()/_stop_flow() dòng 618 plan.md (dù đó là bản service, đây là UI handler nút Run). co -
Co4ETab.<method truoc dong 1401, ten chua xac dinh - co the la _on_run_clicked> 1401-1405 presentation/co4e/co4e_run_control_widget.py cắt ngang lát — cần agent gộp đối chiếu. Định nghĩa (def ...) nằm ở lát trước dòng 1401 nên tên chính xác không xác định được; đoạn thấy được chỉ dispatch theo self._current_mode() sang _manual_run_or_advance() hoặc _start_canvas_run() — thuộc nhóm Run/mode. chua/khong ro (def ...) nằm ở lát trước dòng 1401 nên tên chính xác không xác định được; đoạn thấy được chỉ dispatch theo self._current_mode() sang _manual_run_or
Co4ETab._start_canvas_run 1407-1424 presentation/co4e/co4e_run_control_widget.py gọi self.manager.start(...) — spawn chạy flow (dẫn tới gọi provider AI ở tầng khác); đọc/ghi self._wf, self._flow_runs, self._flow_runs[wf_id], self._run_logs, self.chat_log — trạng thái chia sẻ giữa run-control và chat-view. self.manager (Co4ERunManager) nên đổi sang application/workflows/co4e_workflow_service.py theo mapping. chua/khong ro -
Co4ETab._run_single 1426-1431 presentation/co4e/co4e_run_control_widget.py wrapper mỏng gọi _start_canvas_run; đọc self._wf.id chua/khong ro -
Co4ETab._run_from 1433-1437 presentation/co4e/co4e_run_control_widget.py wrapper mỏng gọi _start_canvas_run với self._downstream(node_id) chua/khong ro -
Co4ETab._downstream 1439-1450 presentation/co4e/co4e_run_control_widget.py thuật toán BFS thuần Python, chỉ đọc self.canvas.edges() làm input — test được với danh sách edge giả lập, không cần canvas thật chua/khong ro -
Co4ETab._manual_run_or_advance 1453-1466 presentation/co4e/co4e_run_control_widget.py gọi self.canvas.reset_statuses() và self._append_chat (self._append_chat thuộc nhóm chat-view) — cắt ngang giữa run-control và chat-view. Đọc/ghi self._manual_active, self._manual_order, self._manual_idx, self._wf, self._outputs_for(...), self._plan_bubble — trạng thái run thuần túy chia sẻ với _manual_step. chua/khong ro -
Co4ETab._manual_step 1468-1484 presentation/co4e/co4e_run_control_widget.py gọi self.manager.start(...) (network/AI qua provider) và self.run_btn.setText, self._append_chat (chat-view); đọc/ghi self._manual_idx, self._manual_order, self._wf, self._flow_runs, self._run_logs, self.chat_log — trạng thái chia sẻ rộng giữa run-control và chat-view. chua/khong ro -
Co4ETab._topo_order 1486-1491 presentation/co4e/co4e_run_control_widget.py đọc self.canvas.nodes()/edges() làm dữ liệu đầu vào, logic tính toán thuần túy (co4e.compute_waves) — test được với dữ liệu giả chua/khong ro -
Co4ETab._on_manager_event 1494-1550 presentation/co4e/co4e_run_control_widget.py method dài (57 dòng), gộp nhiều việc không liên quan: định tuyến sự kiện chạy theo từng flow (routing run_id -> log), cập nhật trạng thái node trên canvas, hiển thị bubble chat (assistant/diff/plan/tool-failed — thuộc co4e_chat_view.py), xử lý hoàn tất run (run_done/run_error), hiển thị popup thông báo, cập nhật status bar. Nên tách phần hiển thị chat (self._append_chat/_append_diff/_append_plan) sang co4e_chat_view.py, giữ phần routing/flow-completion ở co4e_run_control_widget.py. Đọc/ghi self._flow_runs, self._run_logs, self.chat_log, self.canvas, self._wf, self._outputs_for(...), self._manual_active, self._manual_idx — trạng thái chia sẻ rất rộng, điểm dễ vỡ nhất khi tách file. chua/khong ro -
Co4ETab._notify_run_finished 1552-1573 presentation/co4e/co4e_run_control_widget.py tạo QMessageBox không chặn; khởi tạo lazy self._run_popups (xem attribute riêng) chua/khong ro -
Co4ETab._run_popups 1560-1561 presentation/co4e/co4e_run_control_widget.py khởi tạo lazy (list rỗng) trong _notify_run_finished qua hasattr guard — không init trong init; giữ ref các QMessageBox non-blocking khỏi bị GC chua/khong ro -
Co4ETab._refresh_runs 1575-1616 presentation/co4e/co4e_run_control_widget.py render bảng runs_table + gọi self._refresh_side_runs() (sidebar) + cập nhật self.flow_bar.setTabText và self._sections['co4e.runs_tab'] — self._sections và self.flow_bar là trạng thái chia sẻ với co4e_tab.py (container/sidebar). chua/khong ro -
Co4ETab._stop_selected_run 1618-1624 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab._delete_selected_run 1626-1639 presentation/co4e/co4e_run_control_widget.py đọc/ghi self._flow_runs, self._run_logs — trạng thái chia sẻ với _on_manager_event/_start_canvas_run chua/khong ro -
Co4ETab._runs_context_menu 1641-1655 presentation/co4e/co4e_run_control_widget.py (không có ghi chú) chua/khong ro -
Co4ETab._open_run_output_folder 1704-1715 presentation/co4e/co4e_run_control_widget.py path.mkdir + open_location (spawn process); dùng bởi _runs_context_menu 'Open output' chua/khong ro -
Co4ETab._rename_selected_run 1717-1748 presentation/co4e/co4e_run_control_widget.py gọi co4e.save_workflow(wf) (ghi đĩa); đọc/ghi self._flows (list flow của sidebar/tab-bar), self.flow_bar, self.name_edit, self._wf — chạm nhiều trạng thái chia sẻ với co4e_tab.py container (tab bar + name edit thuộc header, không rõ nằm ở panel nào) — rủi ro vỡ cao khi tách. chua/khong ro -
Co4ETab._run_selected_in_background 1750-1760 presentation/co4e/co4e_run_control_widget.py gọi self.manager.start(...) (network/AI) và self._refresh_side_runs() (widget) chua/khong ro -
Co4ETab._wf_by_id 1762-1770 presentation/co4e/co4e_run_control_widget.py gọi co4e.get_workflow(wf_id) (đọc đĩa) và self._sync_wf_from_canvas() (không nằm trong khoảng đọc) — đọc self._wf; dùng chung bởi _rerun_run_item/_open_run_from_table (Runs tab) và có thể cả co4e_tab.py container chua/khong ro -
Co4ETab._rerun_run_item 1772-1783 presentation/co4e/co4e_run_control_widget.py gọi self.manager.start(...) (network/AI) chua/khong ro -
Co4ETab._open_run_from_table 1785-1804 presentation/co4e/co4e_run_control_widget.py gọi self._open_flow(wf) (không nằm trong khoảng đọc, theo plan.md thuộc co4e_tab.py) và self.canvas.update_node_status — nối Runs tab với việc mở flow trên canvas, điểm khớp nối giữa run-control và container/canvas. co -
_qcolor 2086-2088 presentation/co4e/co4e_run_control_widget.py hàm module-level (ngoài class Co4ETab), tạo QColor từ hex string — dùng kiểu giá trị QColor, không cần QApplication sống; dùng trong _refresh_runs để tô màu status chua/khong ro -
_EqualTabBar 74-94 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
_EqualTabBar._GAP 80 presentation/co4e/co4e_tab.py class-level constant, không phải self. chua/khong ro -
_EqualTabBar.tabSizeHint 82-90 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
_EqualTabBar.resizeEvent 92-94 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab 229-700 presentation/co4e/co4e_tab.py Lớp kéo dài quá dòng 700 (cắt ngang lát) — chỉ ghi nhận phần 229-700; 'status_message = Signal(str)' dòng 230 là thuộc tính lớp, không phải self. chua/khong ro -
Co4ETab.init 232-304 presentation/co4e/co4e_tab.py method 73 dòng, gộp: khởi state run/flow, dựng splitter 3 cột (sidebar/center/config), wiring canvas & config panel, gọi _reload_sidebar (đọc đĩa qua co4e.list_workflows) và _open_flow; chạm rất nhiều thuộc tính chia sẻ: self._wf, self._flows, self.manager, self._flow_runs, self._run_logs, self._flow_outputs, self._flow_usage, self.config, self.canvas (gán ở _build_center ngoài khoảng đọc này) chua/khong ro -
Co4ETab.ctx 234 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._wf 235 presentation/co4e/co4e_tab.py trạng thái chia sẻ — đọc/ghi bởi canvas, run control, chat view chua/khong ro -
Co4ETab._flows 257 presentation/co4e/co4e_tab.py danh sách flow đang mở dạng tab — trạng thái chia sẻ nhạy cảm (nêu rõ trong hướng dẫn đề bài) chua/khong ro -
Co4ETab._active_flow_idx 258 presentation/co4e/co4e_tab.py chỉ số tab đang active — chia sẻ giữa _open_flow, _on_flow_tab_changed, _reflect_active_run chua/khong ro -
Co4ETab._split 261 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._config_collapsed 274 presentation/co4e/co4e_tab.py trạng thái cho _toggle_config (định nghĩa dòng 989, ngoài khoảng đọc); plan.md xếp _toggle_config ở co4e_tab.py container co -
Co4ETab._config_expanded_w 275; 995 presentation/co4e/co4e_tab.py [GỘP 2 lượt quét trùng ký hiệu] (dòng 275-275, target gốc=presentation/co4e/co4e_tab.py) cùng lý do với _config_collapsed || (dòng 995-995, target gốc=presentation/co4e/co4e_tab.py) gán trong nhánh collapse của _toggle_config; có thể đã khởi tạo trong init (ngoài phạm vi đọc). chua/khong ro [GỘP 2 lượt quét trùng ký hiệu] (dòng 275-275, target gốc=presentation/co4e/co4e_tab.py) cùng lý do vớ
Co4ETab._narrow_guard 280 presentation/co4e/co4e_tab.py gắn với _apply_narrow_layout (dòng 977, ngoài khoảng đọc) chua/khong ro -
Co4ETab._open_flow 307-338 presentation/co4e/co4e_tab.py khớp plan.md: _open_flow() -> co4e_tab.py, gọi canvas; chạm self._flows, self.flow_bar (định nghĩa ngoài khoảng đọc), self.canvas co -
Co4ETab._close_other_flows 340-355 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._show_runs 357-367 presentation/co4e/co4e_tab.py chuyển đổi center_stack giữa flow editor và Runs table — liên quan Flow Status (run control) chua/khong ro -
Co4ETab._on_flow_tab_changed 369-385 presentation/co4e/co4e_tab.py chạm self.center_stack (định nghĩa ngoài khoảng đọc, ở _build_center) chua/khong ro -
Co4ETab._sync_runs_toggle 387-394 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._add_tab_close_button 396-406 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._close_flow_tab_button 408-412 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._close_flow_tab 414-442 presentation/co4e/co4e_tab.py chạm self._flow_runs/_run_logs/_manual_active/self.run_btn (chia sẻ với run control widget) chua/khong ro -
Co4ETab._sync_active_flow_tab_text 444-447 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._build_sidebar 485-603 presentation/co4e/co4e_tab.py >80 dòng (119 dòng) — gộp dựng 4 section (Workflows/Agents/Skills/Runs) + wiring nhiều nút bấm; nên tách theo section: Workflows giữ ở container, Agents nên chuyển agent_list_panel.py, Skills đã tách (chỉ còn wiring), Runs nên chuyển co4e_run_control_widget.py chua/khong ro -
Co4ETab._sections 493 presentation/co4e/co4e_tab.py trạng thái chia sẻ (nêu rõ trong hướng dẫn đề bài) — dùng bởi _fold_section, _sync_section_arrow chua/khong ro -
Co4ETab.sidebar 494 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab.side_split 498 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
_Col 503-511 presentation/co4e/co4e_tab.py adapter nội bộ định nghĩa bên trong _build_sidebar, chỉ dùng tại chỗ chua/khong ro -
_Col.init 506-507 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
_Col.addWidget 509-511 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab.wf_new_btn 516 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab.wf_list 527 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab.wf_edit_btn 534 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab.wf_dup_btn 535 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab.wf_del_btn 536 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab.wf_runbg_btn 543 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._skills_panel 575 presentation/co4e/co4e_tab.py instantiate SkillsListPanel đã tách; Co4ETab giữ wiring theo comment trong code (dòng 571-574) chua/khong ro -
Co4ETab.sk_manage_btn 576 presentation/co4e/co4e_tab.py cùng lý do với _skills_panel chua/khong ro -
Co4ETab.skill_list 578 presentation/co4e/co4e_tab.py cùng lý do với _skills_panel chua/khong ro -
Co4ETab._section 631-663 presentation/co4e/co4e_tab.py chạm self._sections (chia sẻ) — helper dựng section sidebar dùng chung chua/khong ro -
Co4ETab._fold_section 665-677 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._sync_section_arrow 679-681 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._icon_btn 683-687 presentation/co4e/co4e_tab.py helper dùng chung tạo nút icon, dùng bởi cả section Workflows và Agents chua/khong ro -
Co4ETab._reload_sidebar 689-722 presentation/co4e/co4e_tab.py [GỘP 2 lượt quét trùng ký hiệu] (dòng 689-700, target gốc=presentation/co4e/co4e_tab.py) cắt ngang lát — cần agent gộp đối chiếu (method tiếp tục sau dòng 700); gọi co4e.list_workflows() (đọc đĩa) rồi dựng QListWidgetItem trực tiếp trong cùng hàm — trộn data-fetch và UI, nên tách phần đọc dữ liệu sang co4e_workflow_service.py || (dòng 689-722, target gốc=unsure) cắt ngang lát — cần agent gộp đối chiếu (bắt đầu trước dòng 701). Gộp refresh cả agent_list và skill_list trong cùng 1 hàm — nên tách thành _refresh_agents_list (agent_list_panel.py) và _refresh_skills_list (skills_list_panel.py) như plan.md yêu cầu; gọi co4e.list_custom_agents() (đĩa) và skills_mod.skill_prefix_for (đĩa). co [GỘP 2 lượt quét trùng ký hiệu] (dòng 689-700, target gốc=presentation/co4e/co4e_tab.py) cắt ngang lát
Co4ETab._build_center 731-871 presentation/co4e/co4e_tab.py dài ~140 dòng, làm nhiều việc không liên quan: dựng flow tab bar (ẩn, không hiển thị cho user), dựng runs-page stack, toolbar flow (name_edit/save/save_tpl/mode_combo/run_btn/runs_btn), tạo canvas, gọi _build_canvas_overlay, tạo chat widget, splitter dọc self._vsplit. Nên tách nhỏ. Đọc self._wf.name (dòng 814) và tạo self.center_stack — TRẠNG THÁI CHIA SẺ dùng bởi _show_runs/_apply_workflow (ngoài phạm vi đọc). Khớp phần '_build_canvas()' trong bảng plan.md dòng 615. co -
Co4ETab.flow_bar 738 presentation/co4e/co4e_tab.py QTabBar bị ẩn (setVisible False dòng 802), chỉ dùng làm index nội bộ ánh xạ flow↔canvas — trạng thái chia sẻ với _on_flow_tab_changed/_close_flow_tab (định nghĩa <701, ngoài phạm vi đọc). chua/khong ro -
Co4ETab.flow_add_btn 764 presentation/co4e/co4e_tab.py ẩn (setVisible False), không hiển thị cho user hiện tại. chua/khong ro -
Co4ETab.flow_scroll 781 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab.center_stack 805 presentation/co4e/co4e_tab.py TRẠNG THÁI CHIA SẺ — chuyển đổi giữa trang Runs (co4e_run_control_widget) và trang flow editor; dùng bởi _show_runs (ngoài phạm vi đọc) và _apply_workflow. chua/khong ro -
Co4ETab.name_edit 814 presentation/co4e/co4e_tab.py khởi tạo từ self._wf.name — trạng thái chia sẻ; cũng bị _on_name_changed/_new_workflow đọc/ghi. chua/khong ro -
Co4ETab.add_step_btn 819 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab.save_btn 822 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab.save_tpl_btn 826 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._vsplit 863 presentation/co4e/co4e_tab.py splitter dọc canvas/chat — dùng chung với _toggle_messages (co4e_chat_view.py thao tác self._vsplit.setSizes) — trạng thái chia sẻ giữa co4e_tab.py và co4e_chat_view.py. chua/khong ro -
Co4ETab._NARROW 971 presentation/co4e/co4e_tab.py hằng class-level (không phải self.), ngưỡng chiều rộng dùng bởi _apply_narrow_layout. chua/khong ro -
Co4ETab.showEvent 973-975 presentation/co4e/co4e_tab.py Qt override, gọi self._narrow_guard.attach() (đối tượng khởi tạo ngoài phạm vi đọc, <701). [ANOMALY: cùng tên method định nghĩa 2 lần ở 2 dòng khác nhau trong cùng class -- có khả năng là lỗi nguồn (định nghĩa sau đè định nghĩa trước), không phải do quét trùng; giữ 2 dòng riêng, cần người quyết định định nghĩa nào còn hiệu lực] chua/khong ro ợng khởi tạo ngoài phạm vi đọc, <701). [ANOMALY: cùng tên method định nghĩa 2 lần ở 2 dòng khác nhau trong cùng class -- có khả
Co4ETab._apply_narrow_layout 977-987 presentation/co4e/co4e_tab.py so self._config_collapsed rồi gọi self._toggle_config() — trạng thái chia sẻ với node_property_panel wrap logic. chua/khong ro -
Co4ETab._toggle_config 989-1032 presentation/co4e/co4e_tab.py dài 44 dòng, gộp: ẩn/hiện self.config (widget thuộc node_property_panel.py), đổi icon, tính lại self._split.setSizes, gọi _refresh_min_width — thao tác trực tiếp self.config/self.config_container (node_property_panel.py) và self._split (co4e_tab.py) cùng lúc — ranh giới tách file dễ vỡ nhất ở đoạn này. Ghi self._config_expanded_w. chua/khong ro -
Co4ETab._refresh_min_width 1034-1039 presentation/co4e/co4e_tab.py thao tác trực tiếp self._split (QSplitter) và self.config_container — chia sẻ với _build_center/_wrap_config. chua/khong ro -
Co4ETab._apply_workflow 1194-1207 presentation/co4e/co4e_tab.py hàm điều phối trung tâm khi mở 1 flow: gán self._wf (TRẠNG THÁI CHIA SẺ dùng khắp mọi nhóm chức năng — canvas, chat_stack/_flow_logs, config panel, run button, usage total). Đây là điểm nối chính giữa các file sau khi tách — không nên tách nhỏ hơn nếu không rất cẩn thận. chua/khong ro -
Co4ETab._new_workflow 1209-1217 presentation/co4e/co4e_tab.py gọi self._open_flow(...) — khớp dòng plan.md '_open_flow() -> co4e_tab.py → gọi canvas'. co -
Co4ETab._selected_wf 1219-1225 presentation/co4e/co4e_tab.py đọc self.wf_list (sidebar, dựng ở _build_sidebar <701) rồi gọi co4e.get_workflow (đĩa). chua/khong ro -
Co4ETab._load_selected_workflow 1227-1230 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._edit_selected_workflow 1232-1237 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._wf_context_menu 1248-1271 presentation/co4e/co4e_tab.py dựng QMenu cho sidebar flows, điều phối gọi _edit_selected_workflow/_rename_workflow/_duplicate_selected_workflow/_run_selected_in_background/_delete_selected_workflow (một số nằm ngoài phạm vi đọc, dòng >1400). chua/khong ro -
Co4ETab._sync_wf_from_canvas 1299-1302 presentation/co4e/co4e_tab.py đọc self.canvas.nodes()/edges() và ghi self._wf.nodes/edges/name — cầu nối giữa co4e_canvas_widget.py và trạng thái self._wf chia sẻ; cân nhắc đặt cùng canvas nếu muốn canvas tự chịu trách nhiệm export dữ liệu. chua/khong ro -
Co4ETab._on_name_changed 1316-1318 presentation/co4e/co4e_tab.py ghi self._wf.name (trạng thái chia sẻ) rồi gọi self._sync_active_flow_tab_text() (định nghĩa dòng 444, ngoài phạm vi đọc). chua/khong ro -
Co4ETab._add_blank_step 1320-1322 presentation/co4e/co4e_tab.py nút 'Add' trên toolbar uỷ nhiệm sang self.canvas.add_palette_step — liên quan nhóm _add_node() trong plan.md (co4e_canvas_widget.py) nhưng bản thân handler chỉ là cầu nối từ toolbar. co -
Co4ETab.set_project 1658-1674 presentation/co4e/co4e_tab.py gọi load_project(project_id) (đọc đĩa) và self.manager.set_output_root/set_current_project (self.manager nên là co4e_workflow_service). Gán self._project_id, self._project_dir — không chắc là lần gán đầu tiên (có thể đã init ở init ngoài khoảng đọc). Không khớp rõ nhóm nào trong danh sách đích cho trước — xếp tạm vào co4e_tab.py vì đây là API binding cấp container gọi từ ngoài. chua/khong ro ể đã init ở init ngoài khoảng đọc). Không khớp rõ nhóm nào trong danh sách đích cho trước — xếp tạm vào co4e_tab.py vì đây là
Co4ETab._flow_output_root 1676-1686 presentation/co4e/co4e_tab.py helper dùng chung bởi cả chat (_out_dir) và run-control (_open_workspace_folder, _open_run_output_folder) — trạng thái/logic cắt ngang nhiều nhóm; đọc self._project_dir, self.ctx.config chua/khong ro -
Co4ETab._refresh_ws_folder_btn 1688-1693 presentation/co4e/co4e_tab.py (không có ghi chú) chua/khong ro -
Co4ETab._open_workspace_folder 1695-1702 presentation/co4e/co4e_tab.py root.mkdir + open_location (mở file explorer hệ điều hành — spawn process) chua/khong ro -
Co4ETab.showEvent 1806-1809 presentation/co4e/co4e_tab.py override Qt lifecycle method của chính QWidget container nên phải ở lại co4e_tab.py; gọi self._refresh_runs() (thuộc co4e_run_control_widget.py) — điểm nối giữa container và run-control widget. [ANOMALY: cùng tên method định nghĩa 2 lần ở 2 dòng khác nhau trong cùng class -- có khả năng là lỗi nguồn (định nghĩa sau đè định nghĩa trước), không phải do quét trùng; giữ 2 dòng riêng, cần người quyết định định nghĩa nào còn hiệu lực] chua/khong ro giữa container và run-control widget. [ANOMALY: cùng tên method định nghĩa 2 lần ở 2 dòng khác nhau trong cùng class -- có khả
Co4ETab._out_dir 1811-1817 presentation/co4e/co4e_tab.py d.mkdir(parents=True, exist_ok=True) — ghi đĩa; dùng chung bởi _run_chat_turn (chat) và tiềm năng bởi run-control; đọc self._wf.name, self._flow_output_root() chua/khong ro -
Co4ETab._retranslate 2059-2079 presentation/co4e/co4e_tab.py cập nhật text i18n cho rất nhiều widget thuộc nhiều nhóm khác nhau (sidebar buttons, runs_table, run control buttons) và gọi self._reload_sidebar()/self._refresh_runs() — thuộc container vì bao trùm toàn tab, dù có thể tách nhỏ theo từng panel sau này. chua/khong ro -
_SectionHeader 30-52 presentation/co4e/node_property_panel.py Widget nội bộ (header có thể click, thu/mở section) chỉ dùng bởi StepConfigPanel; không có trong bảng plan.md/function_list.md, xếp cùng chỗ với StepConfigPanel vì mô tả node_property_panel.py là 'Bọc StepConfigPanel' co section) chỉ dùng bởi StepConfigPanel; không có trong bảng plan.md/function_list.md, xếp cùng chỗ với StepConfigPanel vì mô tả node_property_panel
_SectionHeader.clicked 36 presentation/co4e/node_property_panel.py Signal Qt khai báo ở cấp class, không phải self.<tên> gán trong init chua/khong ro -
_SectionHeader.mousePressEvent 38-41 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
_SectionHeader.showEvent 43-52 presentation/co4e/node_property_panel.py recompute fontMetrics khi label thực sự hiển thị — cần widget đang sống, không test được nếu không có QApplication chua/khong ro -
_add_section 55-130 presentation/co4e/node_property_panel.py Hàm dựng UI khối section thu gọn/mở rộng (header + body animate) dùng riêng cho StepConfigPanel; chứa 2 closure nội bộ _on_finished và _toggle. Không có trong bảng cũ. co closure nội bộ _on_finished và _toggle. Không có trong bảng cũ.
_add_section._on_finished 103-112 presentation/co4e/node_property_panel.py closure lồng bên trong _add_section, không phải hàm top-level — chỉ tồn tại khi _add_section chạy chua/khong ro -
_add_section._toggle 114-127 presentation/co4e/node_property_panel.py closure lồng bên trong _add_section, gắn vào header.clicked chua/khong ro -
StepConfigPanel 133-528 presentation/co4e/node_property_panel.py cắt ngang lát — cần agent gộp đối chiếu (lớp còn tiếp tục sau dòng 528, chỉ đọc được 1-528). Bảng plan.md/function_list.md không liệt kê StepConfigPanel trực tiếp (chỉ có _build_config_panel() -> co4e_tab.py container); xếp theo mô tả node_property_panel.py 'Bọc StepConfigPanel, nối chọn node sang panel thuộc tính' trong danh sách đích được giao cho task này — người quyết cuối nên xác nhận lại. co -
StepConfigPanel.changed 134 presentation/co4e/node_property_panel.py Signal Qt: bất kỳ field nào đổi -> canvas repaint node + autosave; đây là điểm nối trạng thái chia sẻ với canvas/co4e_workflow_service, cần giữ tên/signature khi tách file chua/khong ro -
StepConfigPanel.run_node 135 presentation/co4e/node_property_panel.py Signal Qt 'chạy step này' — nối sang co4e_run_control_widget.py hoặc co4e_workflow_service.py chua/khong ro -
StepConfigPanel.run_from 136 presentation/co4e/node_property_panel.py Signal Qt 'chạy từ bước này' — nối sang co4e_run_control_widget.py chua/khong ro -
StepConfigPanel.delete_node 137 presentation/co4e/node_property_panel.py Signal Qt xoá step — nối sang co4e_canvas_widget.py để xoá node trên canvas chua/khong ro -
StepConfigPanel.init 139-313 presentation/co4e/node_property_panel.py >80 dòng (174 dòng) — gộp nhiều việc không liên quan: dựng section Cơ bản, section Model&Quyền, section Skills&Tệp, section Sub-agents (ẩn/hiện theo is_parallel), và dựng hàng nút footer Run/Run-from/Delete, cộng thêm cơ chế 'outer.addStretch(1)' vá lỗi layout. Nên tách thành các hàm _build_basic_section(), _build_model_section(), _build_skills_section(), _build_subagent_section(), _build_footer() riêng khi tách file. chua/khong ro -
StepConfigPanel.ctx 141 presentation/co4e/node_property_panel.py context được truyền từ ngoài vào, dùng cho _ai_draft/_load_models (gọi AI provider) — trạng thái chia sẻ với co4e_tab.py chua/khong ro -
StepConfigPanel._step 142 presentation/co4e/node_property_panel.py Step đang chỉnh sửa — trạng thái chia sẻ giữa load_step()/_on_edit()/mọi hành động subagent+attachment; do canvas gán vào qua load_step() chua/khong ro -
StepConfigPanel._node_id 143 presentation/co4e/node_property_panel.py id node đang chọn — dùng để emit run_node/run_from/delete_node; là cầu nối canvas <-> property panel chua/khong ro -
StepConfigPanel._loading 144 presentation/co4e/node_property_panel.py cờ chặn _on_edit() chạy lại trong lúc load_step() đang set giá trị field chua/khong ro -
StepConfigPanel.label_edit 159 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.role_edit 163 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.icon_edit 170 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.instructions_edit 175 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.gen_btn 178 presentation/co4e/node_property_panel.py nút 'AI draft' — enable chỉ khi có ctx chua/khong ro -
StepConfigPanel.context_edit 192 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.model_combo 201 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.load_models_btn 204 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.perm_combo 214 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.verify_chk 221 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.rounds_spin 223 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.skills_list 236 presentation/co4e/node_property_panel.py checklist skill của registry, gán checked theo step.skills chua/khong ro -
StepConfigPanel.attach_list 242 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.attach_add_btn 244 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.attach_del_btn 247 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel._parallel_card 263 presentation/co4e/node_property_panel.py card cả section Sub-agents; load_step() ẩn/hiện toàn bộ card này theo step.is_parallel chua/khong ro -
StepConfigPanel.sub_list 264 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.sub_add_btn 267 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
Co4ETab.config 268 presentation/co4e/node_property_panel.py StepConfigPanel + wiring changed/run_node/run_from/delete_node (dòng 268-273) — khớp vai trò mô tả cho node_property_panel.py chua/khong ro -
StepConfigPanel.sub_del_btn 270 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel.run_btn 283 presentation/co4e/node_property_panel.py click emit run_node(self._node_id) chua/khong ro -
StepConfigPanel.run_from_btn 287 presentation/co4e/node_property_panel.py click emit run_from(self._node_id) chua/khong ro -
StepConfigPanel.del_btn 290 presentation/co4e/node_property_panel.py click emit delete_node(self._node_id) chua/khong ro -
StepConfigPanel.load_step 316-354 presentation/co4e/node_property_panel.py Điểm nối chính giữa canvas (khi chọn node) và panel thuộc tính — nhận (node_id, step, skill_names) từ ngoài rồi ghi self._step/self._node_id; đây là API mà co4e_canvas_widget.py hoặc co4e_tab.py sẽ gọi khi chọn node chua/khong ro -
StepConfigPanel.clear_step 356-359 presentation/co4e/node_property_panel.py gọi khi bỏ chọn node — reset self._step/self._node_id chua/khong ro -
StepConfigPanel._on_edit 362-378 presentation/co4e/node_property_panel.py ghi ngược giá trị field UI vào self._step rồi emit changed() — canvas repaint + autosave phụ thuộc signal này, đổi tên/behavior ở đây ảnh hưởng cả canvas lẫn service lưu flow chua/khong ro -
StepConfigPanel._available_agent_names 380-390 presentation/co4e/node_property_panel.py staticmethod; gọi core.co4e.list_custom_agents() đọc file JSON trong AGENTS_DIR trên đĩa — logic thuần Python nhưng có I/O, có thể tách ra application layer nếu cần test không đụng đĩa chua/khong ro -
StepConfigPanel._add_subagent 392-408 presentation/co4e/node_property_panel.py dùng QInputDialog để chọn/nhập tên agent song song chua/khong ro -
StepConfigPanel._edit_subagent 410-428 presentation/co4e/node_property_panel.py double-click 1 dòng sub-agent để chọn lại agent khác chua/khong ro -
StepConfigPanel._del_subagent 430-437 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel._add_attachment 439-453 presentation/co4e/node_property_panel.py QFileDialog chỉ chọn đường dẫn hiển thị tên file, không tự đọc nội dung ở đây (nội dung được đọc lúc chạy step, ở nơi khác) chua/khong ro -
StepConfigPanel._del_attachment 455-462 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
StepConfigPanel._ai_draft 464-498 presentation/co4e/node_property_panel.py gọi generate_agent_prompt(ctx.build_active_provider(), ...) qua AgentWorker — gọi network tới AI provider, chạy nền rồi cập nhật UI ở callback done(); nếu tách sang service, phần gọi AI nên chuyển xuống application layer, phần còn lại (QInputDialog + set text) ở lại đây chua/khong ro -
StepConfigPanel._draft_worker 497 presentation/co4e/node_property_panel.py giữ tham chiếu AgentWorker (QThread-like) để không bị GC giữa lúc job async đang chạy chua/khong ro -
StepConfigPanel._load_models 500-528 presentation/co4e/node_property_panel.py gọi preview_ai.fetch_live_models(ctx) qua AgentWorker — network call tới provider để lấy danh sách model; cắt ngang lát — cần agent gộp đối chiếu vì dòng cuối trùng đúng biên đọc được giao (528), chưa chắc thân method đã hết ở đây chua/khong ro -
StepConfigPanel._model_worker 525 presentation/co4e/node_property_panel.py giữ tham chiếu AgentWorker của _load_models để không bị GC chua/khong ro -
Co4ETab._wrap_config 934-964 presentation/co4e/node_property_panel.py bọc self.config (StepConfigPanel) với header expand/collapse — khớp mô tả node_property_panel.py trong prompt. chua/khong ro -
Co4ETab.config_toggle_btn 946 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
Co4ETab.config_title 951 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
Co4ETab._cfg_vlayout 957 presentation/co4e/node_property_panel.py dùng lại trong _toggle_config (co4e_tab.py) — trạng thái chia sẻ. chua/khong ro -
Co4ETab._cfg_top_spacer 961 presentation/co4e/node_property_panel.py QSpacerItem — kiểu giá trị layout, không cần QApplication đang sống. chua/khong ro -
Co4ETab._cfg_bot_spacer 962 presentation/co4e/node_property_panel.py (không có ghi chú) chua/khong ro -
Co4ETab.config_container 963 presentation/co4e/node_property_panel.py dùng lại bởi _toggle_config (co4e_tab.py) — trạng thái chia sẻ giữa node_property_panel.py và co4e_tab.py. chua/khong ro -
Co4ETab._on_node_selected 1325-1331 presentation/co4e/node_property_panel.py khớp mô tả 'nối chọn node sang panel thuộc tính' trong prompt. Đọc self.canvas.nodes() và self.config, toggle self._config_collapsed (trạng thái chia sẻ với _toggle_config ở co4e_tab.py). chua/khong ro -
Co4ETab._on_config_changed 1333-1336 presentation/co4e/node_property_panel.py gọi self.canvas.refresh_node cho từng node rồi self._autosave() — cầu nối property panel ↔ canvas ↔ service lưu đĩa. chua/khong ro -
Co4ETab._manage_skills 1369-1373 presentation/co4e/skills_list_panel.py mở SkillsDialog rồi self._reload_sidebar() — không có tên tương ứng trực tiếp trong bảng plan.md, tự xếp theo mô tả skills_list_panel.py. co -
_PaletteList 97-119 unsure list kéo-thả dùng chung cho wf_list và agent_list, phát payload CO4E_MIME hiểu bởi canvas — không rõ nên đặt ở co4e_tab.py (nơi dùng) hay co4e_canvas_widget.py (định nghĩa giao thức CO4E_MIME) chua/khong ro -
_PaletteList.init 102-106 unsure cùng lý do với class _PaletteList chua/khong ro -
_PaletteList._payload_role 104 unsure cùng lý do với class _PaletteList chua/khong ro -
_PaletteList.startDrag 108-119 unsure cùng lý do với class _PaletteList; dùng CO4E_MIME từ co4e_canvas chua/khong ro -
Co4ETab._project_id 249 unsure project Workspace đang chọn, ảnh hưởng đường dẫn output flow — không chắc thuộc container hay run control chua/khong ro -
Co4ETab._project_dir 250 unsure cùng lý do với _project_id chua/khong ro -
Co4ETab._reflect_active_run 449-457 unsure cầu nối giữa self.manager (run control) và self.canvas (canvas widget) — không chắc nên đặt file nào chua/khong ro -
Co4ETab._palette_item 724-728 unsure staticmethod helper dùng chung để tạo QListWidgetItem cho cả agent_list, skill_list, và cả node palette sequential/parallel (thấy dùng ở dòng 701-704) — không rõ nên đặt ở agent_list_panel.py, skills_list_panel.py hay co4e_canvas_widget.py. chua/khong ro -

Chỗ thấy khác tài liệu — cần người quyết

Không có symbol nào có note bắt đầu bằng khac tai lieu: trong dữ liệu 367 symbol đầu vào. Mục này để trống theo đúng dữ liệu quét được — không tự bịa thêm mục.