fix(qa): resolve DF-002 through DF-011 from QA defect tracking sheet
Batch of fixes for defects tracked in "Task Tracking Template.xlsx" (sheet Defect Management), verified against the sheet's Root Cause/Cach xu ly columns before this commit: - DF-002: Co4E node status not reflected after tab switch + missing edit-lock on running/done nodes (node_property_panel.py, co4e_runs.py, co4e_workflow_crud.py, co4e_canvas_widget.py, co4e_flow_tabs.py, canvas_items.py) - DF-003: hide the run.bat console window unless the app exits with an error (run.bat, scripts/console_visibility.ps1 - new) - DF-004: floating Help Assistant icon covering the Send button after a window resize (presentation/shell/main_window.py) - DF-005: "block network" toggle didn't stop ICMP/raw-socket tools like ping (infrastructure/filesystem/command_tools.py, security/command_risk_classifier.py) - DF-006: Monitoring "gay nang khi log lon" - root cause was re-reading the ENTIRE audit log history every 3s tick, not missing pagination; bounded to a 30-day window (presentation/monitoring/monitoring_tab.py) AND added the "So dong/trang" page-size control the ticket also asked for (presentation/monitoring/shared/event_table.py, shared/filter_scaffold.py, tabs/action_logs_tab.py, tabs/mcp_tab.py, tabs/security_events_tab.py, i18n/agents_admin_tab.py) - DF-007: support choosing a OneDrive/SharePoint folder as a project's working directory via Microsoft Graph, downloaded as a local mirror with manual sync (core/projects.py, core/ms365_graph.py, core/cloud_workspace_sync.py - new, ui/ms365_signin_dialog.py - new, ui/cloud_folder_picker_dialog.py - new, i18n/cloud_workspace.py - new, ui/workspace_tab.py) - DF-008: AI-edit instruction box was a fixed-height single-line QLineEdit; replaced with an auto-expanding, Enter-to-send/Shift+Enter-newline input (presentation/folder/ai_file_editor_dialog.py) - DF-011: run_command failed with WinError 267 for a project whose per-turn output directory had never been created (application/conversations/core_runtime_adapter.py) DF-009 (AI-edit Apply/Discard buttons easy to miss) and DF-010 (AI reply language - dev-confirmed not a bug) are intentionally NOT part of this commit: DF-009 has no code fix yet (still "Assigned" in the sheet, only a UX recommendation was recorded), DF-010 was rejected as expected behavior. Tests: tests/test_cloud_workspace_sync.py, tests/test_ms365_cloud_dialogs.py, tests/test_ai_file_editor_input.py, tests/test_monitoring_page_size.py (all new, all passing). Full suite: 896 passed, 13 known-and-documented failures unrelated to this change (an existing core/audit_log.py bug, this checkout not being a git repo before now, and a repo/subprocess folder-naming mismatch affecting ~66 characterization tests) - see the sheet's DF-006 Evidence column for details.
This commit is contained in:
@@ -196,6 +196,40 @@ def write_onedrive_file(token: str, path: str, content: str) -> dict:
|
||||
return resp.json()
|
||||
|
||||
|
||||
# Graph's "simple upload" (a single PUT to .../content) is documented to only
|
||||
# support items up to 4 MiB; anything larger needs a chunked "upload session"
|
||||
# (createUploadSession + PUT-per-range), which this module does not implement
|
||||
# (see DF-007 cloud workspace picker — v1 explicitly skips large files rather
|
||||
# than silently truncating or corrupting them).
|
||||
MAX_SIMPLE_UPLOAD_BYTES = 4 * 1024 * 1024
|
||||
|
||||
|
||||
def _check_upload_size(data: bytes) -> None:
|
||||
if len(data) > MAX_SIMPLE_UPLOAD_BYTES:
|
||||
raise Ms365GraphError(
|
||||
f"File too large for simple upload ({len(data)} bytes > "
|
||||
f"{MAX_SIMPLE_UPLOAD_BYTES} bytes) — chunked upload sessions are not "
|
||||
"implemented yet."
|
||||
)
|
||||
|
||||
|
||||
def download_onedrive_file_bytes(token: str, path: str) -> bytes:
|
||||
"""Đọc RAW BYTES một tệp OneDrive (không ép UTF-8/không cắt) — dùng cho
|
||||
mirror thư mục cloud xuống local, khác với :func:`read_onedrive_file` vốn
|
||||
chỉ dành cho việc đọc nội dung văn bản vào ngữ cảnh chat."""
|
||||
resp = _request("GET", f"/me/drive/root:/{_path_segment(path)}:/content", token)
|
||||
return resp.content
|
||||
|
||||
|
||||
def upload_onedrive_file_bytes(token: str, path: str, data: bytes) -> dict:
|
||||
"""Ghi RAW BYTES vào một tệp OneDrive (tạo mới hoặc ghi đè). Xem
|
||||
:data:`MAX_SIMPLE_UPLOAD_BYTES`."""
|
||||
_check_upload_size(data)
|
||||
resp = _request("PUT", f"/me/drive/root:/{_path_segment(path)}:/content", token,
|
||||
data=data, headers={"Content-Type": "application/octet-stream"})
|
||||
return resp.json()
|
||||
|
||||
|
||||
def _encode_share_url(url: str) -> str:
|
||||
"""Encode a OneDrive/SharePoint sharing URL into Graph's ``u!<base64url>``
|
||||
share-id form (see Microsoft's 'Get access to shared items' docs)."""
|
||||
@@ -229,6 +263,24 @@ def list_sharepoint_files(token: str, site_id: str, path: str = "") -> List[dict
|
||||
return resp.json().get("value", [])
|
||||
|
||||
|
||||
def download_sharepoint_file_bytes(token: str, site_id: str, path: str) -> bytes:
|
||||
"""Đọc RAW BYTES một tệp trong thư viện tài liệu SharePoint — xem
|
||||
:func:`download_onedrive_file_bytes`."""
|
||||
resp = _request(
|
||||
"GET", f"/sites/{quote(site_id)}/drive/root:/{_path_segment(path)}:/content", token)
|
||||
return resp.content
|
||||
|
||||
|
||||
def upload_sharepoint_file_bytes(token: str, site_id: str, path: str, data: bytes) -> dict:
|
||||
"""Ghi RAW BYTES vào một tệp trong thư viện tài liệu SharePoint. Xem
|
||||
:data:`MAX_SIMPLE_UPLOAD_BYTES`."""
|
||||
_check_upload_size(data)
|
||||
resp = _request(
|
||||
"PUT", f"/sites/{quote(site_id)}/drive/root:/{_path_segment(path)}:/content", token,
|
||||
data=data, headers={"Content-Type": "application/octet-stream"})
|
||||
return resp.json()
|
||||
|
||||
|
||||
# ---- Teams meeting transcripts ------------------------------------------
|
||||
def find_online_meeting(token: str, join_url: str) -> List[dict]:
|
||||
"""Tìm cuộc họp online theo link tham gia."""
|
||||
|
||||
Reference in New Issue
Block a user