Files
f9f6bc01fd
CI / test (push) Canceled after 0s
Feature/delta team/epic r04 (#7)
## Summary

epic r04 - begin refactor

## Change Type

- [x] Cowork feature
- [ ] Bug fix
- [ ] Core AI contribution
- [ ] Test / hardening
- [ ] Performance
- [ ] Documentation

## Related Work

Cowork Task:

Core Repo: http://34.143.229.138/gitea-admin/fsg-ai-core-assets

Core AI Issue:

Core Task:

Related PR:

## Scope

What is intentionally included?

What is intentionally NOT included?

## Validation

- [ ] Unit tests
- [ ] Integration tests
- [ ] Manual verification
- [ ] Regression check

Commands / evidence:

## Security Impact

Permission / credential / network / customer data impact:

## Compatibility

- [ ] No breaking change
- [ ] Breaking change documented

## Reviewer Notes

Anything Cowork reviewers should pay attention to.

---------

Co-authored-by: Anh Tran Nguyen Minh <anhtnm1@fpt.com>
Co-authored-by: Huong Le Thi Thien <huongltt35@fpt.com>
Co-authored-by: Nam Pham Dinh Thanh <nampdt@fpt.com>
Co-authored-by: Vu Dam Tuan <vudt15@fpt.com>
Co-authored-by: Hiep Ha Van <hiephv3@fpt.com>
Co-authored-by: Lam Hoang Van <lamhv7@fpt.com>
Reviewed-on: #7
Co-authored-by: Duy Le Huu <duylh19@fpt.com>
2026-08-31 05:15:13 +00:00

129 lines
5.5 KiB
Python

"""Các nhóm cấu hình đọc thẳng từ dict — tách khỏi ``json_config_repository.py``.
Mỗi thành viên ở đây chỉ làm đúng một việc: đặt tên cho một khoá trong file
cấu hình và nói rõ giá trị mặc định khi khoá đó chưa có. Không có hành vi nào
đáng bàn, nhưng có đến hơn hai mươi cái — để chung với phần có logic thật
(trộn mặc định, kho bí mật, di trú schema, ghi nguyên tử) thì phần ấy bị chìm.
Dùng ``setdefault`` chứ không ``get``: bên gọi sửa thẳng vào dict trả về
(``cfg.routing["switch_mode"] = ...``) rồi mới ``save()``, nên cái trả về phải
là dict THẬT nằm trong ``data``, không phải một bản sao rồi bị vứt đi.
Mixin chứ không phải lớp riêng: 29 file đang gọi ``ctx.config.<tên>`` thẳng,
nên tách thành ``ctx.config.sections.<tên>`` sẽ là đổi API công khai — việc
này chỉ chia file, không chia bề mặt.
"""
from __future__ import annotations
import copy
from typing import Any, Dict
class ConfigSectionsMixin:
"""Phần truy cập nhóm cấu hình của :class:`JsonConfigRepository`.
Chỉ trông vào hai thứ của lớp chủ: ``self.data`` (dict cấu hình đã trộn
mặc định) và ``self.save()``. Không tự đứng một mình được — và cũng không
cần, vì không có ai khác dùng.
"""
@property
def code(self) -> Dict[str, Any]:
"""Nhóm ``code``: thiết lập của agent lập trình (thư mục làm việc, model)."""
return self.data["code"]
@property
def teams(self) -> Dict[str, Any]:
"""Nhóm ``teams``: thiết lập tích hợp Microsoft Teams."""
return self.data["teams"]
@property
def history(self) -> Dict[str, Any]:
"""Nhóm ``history``: lưu lịch sử hội thoại (bật/tắt, giới hạn)."""
return self.data["history"]
@property
def codebase_memory(self) -> Dict[str, Any]:
"""Nhóm ``codebase_memory``: bộ nhớ mã nguồn cho agent lập trình."""
return self.data["codebase_memory"]
@property
def cowork(self) -> Dict[str, Any]:
"""Nhóm ``cowork``: thiết lập màn Cowork (thư mục kết quả, model mặc định)."""
return self.data["cowork"]
@property
def mcp_servers(self) -> list:
"""Danh sách máy chủ MCP đã khai báo; rỗng nếu chưa có cái nào."""
return self.data.setdefault("mcp_servers", [])
@property
def structure(self) -> Dict[str, Any]:
"""Nhóm ``structure``: trần số node/cạnh khi vẽ đồ thị GraphRAG.
Mặc định 400/400 — vượt ngưỡng đó thì đồ thị vừa vẽ chậm vừa rối, không
còn đọc được nữa.
"""
return self.data.setdefault("structure", {"max_nodes": 400, "max_edges": 400})
@property
def monitoring_visibility(self) -> Dict[str, bool]:
"""Nhóm ``monitoring_visibility``: tab nào của màn Giám sát được hiện.
Lấy bản sao sâu của mặc định khi khoá chưa có, để người dùng tắt một tab
không vô tình sửa luôn bộ mặc định dùng chung.
"""
return self.data.setdefault(
"monitoring_visibility",
copy.deepcopy(self._defaults["monitoring_visibility"]))
@property
def ext_connectors(self) -> Dict[str, list]:
"""Connector (MCP) gom theo nhóm CAD/CAE/MS365/Other."""
d = self.data.setdefault(
"ext_connectors", {"cad": [], "cae": [], "ms365": [], "other": []})
for cat in ("cad", "cae", "ms365", "other"):
d.setdefault(cat, [])
return d
# ---- công tắc tổng cho connector -------------------------------------
@property
def connect_external(self) -> bool:
"""Tắt cái này là agent không nối tới connector ngoài nào cả. Mặc định
BẬT để cấu hình đang chạy không đổi hành vi."""
return bool(self.data.setdefault("tools", {}).get("connect_external", True))
def set_connect_external(self, enabled: bool) -> None:
"""Bật/tắt công tắc tổng cho connector ngoài, ghi đĩa ngay."""
self.data.setdefault("tools", {})["connect_external"] = bool(enabled)
self.save()
# ---- những thứ đã gieo sẵn -------------------------------------------
@property
def seeded_library_skills(self) -> list:
"""Slug của skill thư viện đã gieo — để cái người dùng xoá đi không bị
lặng lẽ gieo lại."""
return list(self.data.setdefault("seeded_library_skills", []))
@seeded_library_skills.setter
def seeded_library_skills(self, slugs) -> None:
"""Ghi lại danh sách slug đã gieo, bỏ trùng và giữ nguyên thứ tự."""
self.data["seeded_library_skills"] = list(dict.fromkeys(slugs or []))
@property
def seeded_builtin_flows(self) -> list:
"""Id của flow Co4E dựng sẵn đã gieo (cùng quy tắc tôn trọng việc người
dùng đã xoá như seeded_library_skills)."""
return list(self.data.setdefault("seeded_builtin_flows", []))
@seeded_builtin_flows.setter
def seeded_builtin_flows(self, ids) -> None:
"""Ghi lại danh sách id flow đã gieo, bỏ trùng và giữ nguyên thứ tự."""
self.data["seeded_builtin_flows"] = list(dict.fromkeys(ids or []))
__all__ = ["ConfigSectionsMixin"]