deep-agent-cli 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- app/__init__.py +0 -0
- app/core/LLM/__init__.py +3 -0
- app/core/LLM/anthropic_provider.py +10 -0
- app/core/LLM/factory.py +74 -0
- app/core/LLM/google_provider.py +19 -0
- app/core/LLM/ollama_provider.py +12 -0
- app/core/LLM/openai_provider.py +10 -0
- app/core/__init__.py +4 -0
- app/core/agent/__init__.py +3 -0
- app/core/agent/deep_agent.py +109 -0
- app/core/checkpoint/__init__.py +3 -0
- app/core/checkpoint/factory.py +54 -0
- app/service/ChatService.py +245 -0
- app/service/ConfigService.py +222 -0
- app/service/__init__.py +4 -0
- deep_agent_cli-1.0.0.dist-info/METADATA +225 -0
- deep_agent_cli-1.0.0.dist-info/RECORD +28 -0
- deep_agent_cli-1.0.0.dist-info/WHEEL +5 -0
- deep_agent_cli-1.0.0.dist-info/entry_points.txt +2 -0
- deep_agent_cli-1.0.0.dist-info/top_level.txt +3 -0
- main.py +32 -0
- ui/__init__.py +1 -0
- ui/controllers/ChatController.py +298 -0
- ui/controllers/__init__.py +1 -0
- ui/models/ChatModel.py +58 -0
- ui/models/__init__.py +1 -0
- ui/views/ChatView.py +237 -0
- ui/views/__init__.py +1 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Optional, Any
|
|
3
|
+
from app.core.LLM import LLMConfig
|
|
4
|
+
from app.core.checkpoint import CheckpointConfig
|
|
5
|
+
from app.core.agent import DeepAgentFactory, DeepAgentConfig
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ConfigService:
|
|
9
|
+
"""
|
|
10
|
+
Service quản lý cấu hình hệ thống bao gồm: api_key, model, provider và quản lý Agent.
|
|
11
|
+
Áp dụng mẫu thiết kế Singleton để đảm bảo trạng thái cấu hình là duy nhất trên toàn hệ thống.
|
|
12
|
+
"""
|
|
13
|
+
_instance = None
|
|
14
|
+
|
|
15
|
+
def __new__(cls, *args, **kwargs):
|
|
16
|
+
if not cls._instance:
|
|
17
|
+
cls._instance = super(ConfigService, cls).__new__(cls, *args, **kwargs)
|
|
18
|
+
cls._instance._initialized = False
|
|
19
|
+
return cls._instance
|
|
20
|
+
|
|
21
|
+
def __init__(self):
|
|
22
|
+
if self._initialized:
|
|
23
|
+
return
|
|
24
|
+
|
|
25
|
+
# Cấu hình mặc định ban đầu
|
|
26
|
+
self._provider = os.getenv("DEFAULT_PROVIDER", "google").lower()
|
|
27
|
+
self._model_name = os.getenv("DEFAULT_MODEL", "models/gemma-4-31b-it")
|
|
28
|
+
self._api_key = os.getenv("GOOGLE_API_KEY", "AIzaSyCaOPgONh0oro-wA9WeUY8QbanuxCSApTg")
|
|
29
|
+
self._temperature = 0.7
|
|
30
|
+
self._base_url = None
|
|
31
|
+
|
|
32
|
+
# Giữ nguyên đường dẫn tương đối gốc của dự án để đảm bảo tương thích ngược
|
|
33
|
+
config_path_env = os.getenv("CONFIG_PATH", "config/v0")
|
|
34
|
+
subagent_filename = "subagent.yml"
|
|
35
|
+
|
|
36
|
+
# Thử đường dẫn tương đối trước
|
|
37
|
+
candidate_path = os.path.join(config_path_env, subagent_filename)
|
|
38
|
+
if os.path.exists(candidate_path):
|
|
39
|
+
self._subagent_config_path = candidate_path
|
|
40
|
+
else:
|
|
41
|
+
# Fallback: tìm kiếm tương đối dựa trên thư mục cài đặt của package
|
|
42
|
+
# ConfigService.py nằm ở <package_root>/app/service/ConfigService.py
|
|
43
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
44
|
+
package_root = os.path.dirname(os.path.dirname(current_dir))
|
|
45
|
+
fallback_path = os.path.join(package_root, config_path_env, subagent_filename)
|
|
46
|
+
if os.path.exists(fallback_path):
|
|
47
|
+
self._subagent_config_path = fallback_path
|
|
48
|
+
else:
|
|
49
|
+
self._subagent_config_path = candidate_path
|
|
50
|
+
|
|
51
|
+
# Tương tự cho .env
|
|
52
|
+
if os.path.exists(".env"):
|
|
53
|
+
self._env_path = ".env"
|
|
54
|
+
else:
|
|
55
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
56
|
+
package_root = os.path.dirname(os.path.dirname(current_dir))
|
|
57
|
+
fallback_env = os.path.join(package_root, ".env")
|
|
58
|
+
if os.path.exists(fallback_env):
|
|
59
|
+
self._env_path = fallback_env
|
|
60
|
+
else:
|
|
61
|
+
self._env_path = ".env"
|
|
62
|
+
|
|
63
|
+
self._llm_config: Optional[LLMConfig] = None
|
|
64
|
+
self._checkpoint_config: Optional[CheckpointConfig] = CheckpointConfig(provider="inmemory")
|
|
65
|
+
self._agent = None
|
|
66
|
+
|
|
67
|
+
# Cập nhật và đồng bộ LLM Config & Agent lần đầu tiên
|
|
68
|
+
self._update_llm_config()
|
|
69
|
+
self._initialized = True
|
|
70
|
+
|
|
71
|
+
def _update_llm_config(self) -> None:
|
|
72
|
+
"""Cập nhật đối tượng LLMConfig từ các cấu hình hiện tại."""
|
|
73
|
+
self._llm_config = LLMConfig(
|
|
74
|
+
provider=self._provider,
|
|
75
|
+
model_name=self._model_name,
|
|
76
|
+
temperature=self._temperature,
|
|
77
|
+
api_key=self._api_key,
|
|
78
|
+
base_url=self._base_url
|
|
79
|
+
)
|
|
80
|
+
# Khởi tạo lại hoặc cập nhật agent tương ứng
|
|
81
|
+
self._recreate_agent()
|
|
82
|
+
|
|
83
|
+
def _recreate_agent(self) -> None:
|
|
84
|
+
"""
|
|
85
|
+
Khởi tạo lại DeepAgent khi có sự thay đổi trong cấu hình.
|
|
86
|
+
Áp dụng nguyên tắc chống lỗi (try-except) để bảo đảm hệ thống hoạt động ổn định.
|
|
87
|
+
"""
|
|
88
|
+
try:
|
|
89
|
+
agent_config = DeepAgentConfig(
|
|
90
|
+
subagent_config_path=self._subagent_config_path,
|
|
91
|
+
llm_config=self._llm_config,
|
|
92
|
+
checkpoint_config=self._checkpoint_config
|
|
93
|
+
)
|
|
94
|
+
# Khởi tạo agent mới qua DeepAgentFactory
|
|
95
|
+
self._agent = DeepAgentFactory.create_agent(agent_config)
|
|
96
|
+
except Exception as e:
|
|
97
|
+
# Sử dụng tiếng Việt không dấu để tránh UnicodeEncodeError trên Windows CP1252 console
|
|
98
|
+
print(f"[ConfigService Error] Khong the khoi tao lai Agent: {e}")
|
|
99
|
+
# Nếu khởi tạo lỗi, giữ nguyên agent cũ hoặc gán None để tránh lỗi logic tiếp theo
|
|
100
|
+
if self._agent is None:
|
|
101
|
+
self._agent = None
|
|
102
|
+
|
|
103
|
+
def _update_env_file(self, key: str, value: str) -> None:
|
|
104
|
+
"""
|
|
105
|
+
Cập nhật hoặc thêm mới một biến môi trường vào file .env một cách an toàn.
|
|
106
|
+
Đảm bảo không phá vỡ cấu trúc comment hoặc dòng trống nguyên bản.
|
|
107
|
+
"""
|
|
108
|
+
lines = []
|
|
109
|
+
key_found = False
|
|
110
|
+
|
|
111
|
+
# Đọc nội dung hiện tại của file .env nếu tồn tại
|
|
112
|
+
if os.path.exists(self._env_path):
|
|
113
|
+
try:
|
|
114
|
+
with open(self._env_path, "r", encoding="utf-8") as f:
|
|
115
|
+
lines = f.readlines()
|
|
116
|
+
except Exception as e:
|
|
117
|
+
print(f"[ConfigService Error] Khong the doc file .env: {e}")
|
|
118
|
+
return
|
|
119
|
+
|
|
120
|
+
new_lines = []
|
|
121
|
+
for line in lines:
|
|
122
|
+
stripped = line.strip()
|
|
123
|
+
# Bỏ qua các dòng trống hoặc comment
|
|
124
|
+
if not stripped or stripped.startswith("#"):
|
|
125
|
+
new_lines.append(line)
|
|
126
|
+
continue
|
|
127
|
+
|
|
128
|
+
if "=" in line:
|
|
129
|
+
line_key, line_value = stripped.split("=", 1)
|
|
130
|
+
if line_key.strip() == key:
|
|
131
|
+
new_lines.append(f"{key}={value}\n")
|
|
132
|
+
key_found = True
|
|
133
|
+
else:
|
|
134
|
+
new_lines.append(line)
|
|
135
|
+
else:
|
|
136
|
+
new_lines.append(line)
|
|
137
|
+
|
|
138
|
+
# Nếu chưa tìm thấy key để cập nhật, thêm mới vào cuối file
|
|
139
|
+
if not key_found:
|
|
140
|
+
# Đảm bảo có xuống dòng ở cuối file trước khi thêm dòng mới
|
|
141
|
+
if new_lines and not new_lines[-1].endswith("\n"):
|
|
142
|
+
new_lines[-1] = new_lines[-1] + "\n"
|
|
143
|
+
new_lines.append(f"{key}={value}\n")
|
|
144
|
+
|
|
145
|
+
# Ghi lại nội dung vào file .env
|
|
146
|
+
try:
|
|
147
|
+
with open(self._env_path, "w", encoding="utf-8") as f:
|
|
148
|
+
f.writelines(new_lines)
|
|
149
|
+
except Exception as e:
|
|
150
|
+
print(f"[ConfigService Error] Khong the cap nhat file .env: {e}")
|
|
151
|
+
|
|
152
|
+
def change_api_key(self, api_key: str) -> None:
|
|
153
|
+
"""
|
|
154
|
+
Thay đổi API Key của provider hiện tại và đồng bộ vào file .env cùng os.environ.
|
|
155
|
+
"""
|
|
156
|
+
self._api_key = api_key
|
|
157
|
+
# Cập nhật biến môi trường tương ứng để các provider của langchain có thể nhận diện
|
|
158
|
+
env_key = None
|
|
159
|
+
if self._provider == "google":
|
|
160
|
+
env_key = "GOOGLE_API_KEY"
|
|
161
|
+
elif self._provider == "openai":
|
|
162
|
+
env_key = "OPENAI_API_KEY"
|
|
163
|
+
elif self._provider == "anthropic":
|
|
164
|
+
env_key = "ANTHROPIC_API_KEY"
|
|
165
|
+
|
|
166
|
+
if env_key:
|
|
167
|
+
os.environ[env_key] = api_key
|
|
168
|
+
self._update_env_file(env_key, api_key)
|
|
169
|
+
|
|
170
|
+
self._update_llm_config()
|
|
171
|
+
|
|
172
|
+
def change_model(self, model_name: str) -> None:
|
|
173
|
+
"""
|
|
174
|
+
Thay đổi model cụ thể sử dụng trong agent và đồng bộ vào file .env cùng os.environ.
|
|
175
|
+
"""
|
|
176
|
+
self._model_name = model_name
|
|
177
|
+
os.environ["DEFAULT_MODEL"] = model_name
|
|
178
|
+
self._update_env_file("DEFAULT_MODEL", model_name)
|
|
179
|
+
self._update_llm_config()
|
|
180
|
+
|
|
181
|
+
def change_provider(self, provider: str) -> None:
|
|
182
|
+
"""
|
|
183
|
+
Thay đổi LLM provider và đồng bộ vào file .env cùng os.environ.
|
|
184
|
+
"""
|
|
185
|
+
self._provider = provider.lower()
|
|
186
|
+
os.environ["DEFAULT_PROVIDER"] = provider.lower()
|
|
187
|
+
self._update_env_file("DEFAULT_PROVIDER", provider.lower())
|
|
188
|
+
self._update_llm_config()
|
|
189
|
+
|
|
190
|
+
def change_temperature(self, temperature: float) -> None:
|
|
191
|
+
"""
|
|
192
|
+
Thay đổi độ sáng tạo (temperature) của model.
|
|
193
|
+
"""
|
|
194
|
+
self._temperature = temperature
|
|
195
|
+
self._update_llm_config()
|
|
196
|
+
|
|
197
|
+
def change_checkpoint_config(self, checkpoint_config: CheckpointConfig) -> None:
|
|
198
|
+
"""
|
|
199
|
+
Thay đổi cấu hình checkpoint lưu trữ của agent.
|
|
200
|
+
"""
|
|
201
|
+
self._checkpoint_config = checkpoint_config
|
|
202
|
+
self._recreate_agent()
|
|
203
|
+
|
|
204
|
+
def get_agent(self) -> Any:
|
|
205
|
+
"""
|
|
206
|
+
Trả về thực thể DeepAgent hiện tại đang được cấu hình.
|
|
207
|
+
"""
|
|
208
|
+
if self._agent is None:
|
|
209
|
+
self._recreate_agent()
|
|
210
|
+
return self._agent
|
|
211
|
+
|
|
212
|
+
def get_llm_config(self) -> LLMConfig:
|
|
213
|
+
"""
|
|
214
|
+
Lấy cấu hình LLM hiện tại.
|
|
215
|
+
"""
|
|
216
|
+
return self._llm_config
|
|
217
|
+
|
|
218
|
+
def get_checkpoint_config(self) -> Optional[CheckpointConfig]:
|
|
219
|
+
"""
|
|
220
|
+
Lấy cấu hình checkpoint hiện tại.
|
|
221
|
+
"""
|
|
222
|
+
return self._checkpoint_config
|
app/service/__init__.py
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: deep-agent-cli
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Hệ thống trợ lý lập trình tự trị tối tân trên giao diện CLI
|
|
5
|
+
Home-page: https://github.com/tonda/AiCodingAgents
|
|
6
|
+
Author: DeepMind Pair Programmer
|
|
7
|
+
Author-email: support@deepagent.cli
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Requires-Python: >=3.11
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
Requires-Dist: yaml~=0.2.5
|
|
17
|
+
Requires-Dist: pyyaml~=6.0.3
|
|
18
|
+
Requires-Dist: pydantic~=2.13.4
|
|
19
|
+
Requires-Dist: deepagents~=0.6.2
|
|
20
|
+
Requires-Dist: langgraph~=1.2.0
|
|
21
|
+
Requires-Dist: langchain-openai~=1.2.1
|
|
22
|
+
Requires-Dist: langchain-anthropic~=1.4.3
|
|
23
|
+
Requires-Dist: dotenv~=0.9.9
|
|
24
|
+
Requires-Dist: python-dotenv~=1.2.2
|
|
25
|
+
Requires-Dist: langchain-google-genai~=4.2.2
|
|
26
|
+
Requires-Dist: langchain-ollama~=1.1.0
|
|
27
|
+
Requires-Dist: langchain-core~=1.4.0
|
|
28
|
+
Requires-Dist: rich~=15.0.0
|
|
29
|
+
Dynamic: author
|
|
30
|
+
Dynamic: author-email
|
|
31
|
+
Dynamic: home-page
|
|
32
|
+
Dynamic: requires-python
|
|
33
|
+
|
|
34
|
+
# 🤖 AI Coding Agent (Deep Agent CLI)
|
|
35
|
+
|
|
36
|
+
Hệ thống trợ lý lập trình tự trị (Autonomous Coding Agent) chuyên nghiệp trên nền tảng giao diện dòng lệnh (CLI). Hệ thống được xây dựng trên mô hình kiến trúc MVC, áp dụng các nguyên tắc hướng đối tượng sâu sắc, thiết kế tối ưu hóa module và hỗ trợ tích hợp linh hoạt đa nền tảng LLM (Multi-Provider).
|
|
37
|
+
|
|
38
|
+
Hệ thống có khả năng tự động đọc hiểu mã nguồn, phân tích lỗi, refactor, viết code và tương tác với các công cụ hệ thống dưới sự kiểm soát an toàn của con người (Human-in-the-loop).
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 🎯 Các Tính Năng Nổi Bật
|
|
43
|
+
|
|
44
|
+
* **Multi-Provider Support (Tách biệt LLM Logic):** Không phụ thuộc vào bất kỳ nhà cung cấp LLM cụ thể nào. Mọi mô hình được chuẩn hóa qua `LLMFactory` (hỗ trợ **Google Gemini**, **OpenAI**, **Anthropic**, và các mô hình cục bộ qua **Ollama**).
|
|
45
|
+
* **Giao Diện CLI Premium (Thư viện Rich):** Trải nghiệm người dùng cao cấp với banner chào mừng, các bảng thông tin trực quan, hiển thị chi tiết các cuộc gọi công cụ (tool call), kết quả trả về dưới dạng bảng/panel màu sắc phong phú (phối màu kiểu HSL hài hòa), và kết xuất nội dung Markdown hoàn hảo.
|
|
46
|
+
* **Cơ chế Suy nghĩ và Stream thời gian thực:** Hiển thị trực tiếp luồng suy nghĩ của Agent (tách biệt với kết quả trả về) theo cơ chế truyền phát (stream) thời gian thực với màu sắc đặc trưng.
|
|
47
|
+
* **Human-in-the-loop (HIL) - Phê duyệt an toàn:** Tự động phát hiện và ngắt khi Agent gọi các công cụ nhạy cảm. Giao diện CLI hiển thị bảng yêu cầu phê duyệt tương tác trực quan cho phép người dùng **Cho phép (Approve)** hoặc **Từ chối (Reject)** kèm lời nhắn/lý do hướng dẫn cụ thể.
|
|
48
|
+
* **Quản lý cấu hình động:** Thay đổi trực tiếp LLM Provider, Model, API Key và độ sáng tạo (Temperature) ngay trên dòng lệnh thông qua các lệnh Slash (`/`). Cấu hình tự động đồng bộ hóa xuống tệp môi trường `.env`.
|
|
49
|
+
* **Lưu trữ Checkpoint thông minh:** Sử dụng `CheckpointFactory` để duy trì và khôi phục trạng thái hội thoại. Hỗ trợ lưu trữ tạm thời trong bộ nhớ (`MemorySaver`) và lưu trữ bền vững qua cơ sở dữ liệu (`SqliteSaver`).
|
|
50
|
+
* **Fault Tolerance (Chống lỗi toàn diện):** Sử dụng các khối bảo vệ `try-except` xung quanh tất cả các tương tác LLM và luồng thực thi Agent, đảm bảo CLI hoạt động liên tục, ổn định và không bị crash đột ngột khi xảy ra sự cố mạng hoặc lỗi nhà cung cấp.
|
|
51
|
+
* **Ngắt luồng bằng phím tắt:** Hỗ trợ ngắt luồng suy nghĩ hoặc thao tác đang chạy bất cứ lúc nào bằng phím tắt `Ctrl + C` một cách an toàn mà không làm sập ứng dụng.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 🏗️ Kiến Trúc Hệ Thống (Software Architecture)
|
|
56
|
+
|
|
57
|
+
Hệ thống được tổ chức chặt chẽ theo hai trục chính: **Kiến trúc Dịch vụ & Factory ở Backend** và **Mô hình MVC ở Frontend CLI**.
|
|
58
|
+
|
|
59
|
+
```mermaid
|
|
60
|
+
graph TD
|
|
61
|
+
subgraph UI (Mô hình MVC)
|
|
62
|
+
ChatView[ChatView - Giao diện Rich] <--> ChatController[ChatController - Điều phối]
|
|
63
|
+
ChatController <--> ChatModel[ChatModel - Trạng thái CLI]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
subgraph Services (Singleton Services)
|
|
67
|
+
ChatController <--> ChatService[ChatService - Quản lý hội thoại]
|
|
68
|
+
ChatController <--> ConfigService[ConfigService - Quản lý cấu hình]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
subgraph Core (Hệ thống cốt lõi)
|
|
72
|
+
ConfigService --> DeepAgentFactory[DeepAgentFactory]
|
|
73
|
+
DeepAgentFactory --> LLMFactory[LLMFactory - Tạo LLM]
|
|
74
|
+
DeepAgentFactory --> CheckpointFactory[CheckpointFactory - Lưu trạng thái]
|
|
75
|
+
DeepAgentFactory --> DeepAgent[DeepAgent - Thực thể Agent chính]
|
|
76
|
+
ChatService --> DeepAgent
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
LLMFactory --> OpenAI[OpenAI Provider]
|
|
80
|
+
LLMFactory --> Anthropic[Anthropic Provider]
|
|
81
|
+
LLMFactory --> Google[Google Provider]
|
|
82
|
+
LLMFactory --> Ollama[Ollama Provider]
|
|
83
|
+
|
|
84
|
+
CheckpointFactory --> Memory[InMemory Saver]
|
|
85
|
+
CheckpointFactory --> SQLite[SQLite Saver]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 1. Mô hình MVC của Giao Diện
|
|
89
|
+
* **`ChatModel` (Model):** Lưu giữ trạng thái hiện tại của phiên hội thoại (ID luồng hội thoại `thread_id`, trạng thái hoạt động, danh sách hành động chờ phê duyệt, lịch sử hội thoại CLI).
|
|
90
|
+
* **`ChatView` (View):** Chịu trách nhiệm render dữ liệu và tương tác ra màn hình console bằng thư viện `rich`. View hoàn toàn không chứa logic nghiệp vụ.
|
|
91
|
+
* **`ChatController` (Controller):** Đóng vai trò là cầu nối, bắt các sự kiện đầu vào từ người dùng, gọi các dịch vụ nghiệp vụ (Services) tương ứng để xử lý và cập nhật Model, từ đó ra lệnh cho View cập nhật giao diện hiển thị.
|
|
92
|
+
|
|
93
|
+
### 2. Các Dịch Vụ Nghiệp Vụ (Core Services)
|
|
94
|
+
* **`ConfigService` (Singleton):** Quản lý cấu hình hệ thống bao gồm Provider, Model, API Key, Temperature. Quản lý vòng đời khởi tạo của Agent. Tự động cập nhật các thay đổi vào file `.env` một cách an toàn mà không phá vỡ cấu trúc nguyên bản của file.
|
|
95
|
+
* **`ChatService` (Singleton):** Xử lý giao tiếp trực tiếp với Agent. Quản lý việc stream luồng suy nghĩ thông qua phương thức `agent.stream`, trích xuất các yêu cầu phê duyệt công cụ (interrupts), truyền phát kết quả và gửi quyết định phản hồi (resume) của người dùng trở lại Agent.
|
|
96
|
+
|
|
97
|
+
### 3. Các Lớp Khởi Tạo (Factories)
|
|
98
|
+
* **`LLMFactory`:** Cung cấp interface thống nhất để khởi tạo thực thể `BaseChatModel` của LangChain cho từng nhà cung cấp khác nhau qua kỹ thuật nạp chậm (Lazy Import) nhằm tối ưu tài nguyên.
|
|
99
|
+
* **`CheckpointFactory`:** Khởi tạo công cụ lưu trữ checkpoint trạng thái hội thoại (`MemorySaver` hoặc `SqliteSaver`) dựa trên cấu hình hệ thống.
|
|
100
|
+
* **`DeepAgentFactory`:** Đọc cấu hình prompts hệ thống (`config.yml`) và danh sách các subagent (`subagent.yml`) để lắp ráp hoàn chỉnh một thực thể `DeepAgent` tích hợp.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 📂 Cấu Trúc Thư Mục (Folder Structure)
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
AiCodingAgents/
|
|
108
|
+
├── app/
|
|
109
|
+
│ ├── core/
|
|
110
|
+
│ │ ├── agent/
|
|
111
|
+
│ │ │ ├── __init__.py
|
|
112
|
+
│ │ │ └── deep_agent.py # Lớp Factory chế tạo DeepAgent tự trị
|
|
113
|
+
│ │ ├── checkpoint/
|
|
114
|
+
│ │ │ ├── __init__.py
|
|
115
|
+
│ │ │ └── factory.py # Quản lý lưu trữ trạng thái (Memory/SQLite)
|
|
116
|
+
│ │ ├── LLM/
|
|
117
|
+
│ │ │ ├── __init__.py
|
|
118
|
+
│ │ │ ├── factory.py # Factory Pattern cho phép khởi tạo đa LLM
|
|
119
|
+
│ │ │ ├── google_provider.py # Thiết lập riêng cho mô hình Google
|
|
120
|
+
│ │ │ ├── openai_provider.py # Thiết lập riêng cho mô hình OpenAI
|
|
121
|
+
│ │ │ ├── anthropic_provider.py # Thiết lập riêng cho mô hình Anthropic
|
|
122
|
+
│ │ │ └── ollama_provider.py # Thiết lập riêng cho mô hình Ollama chạy Local
|
|
123
|
+
│ │ └── __init__.py
|
|
124
|
+
│ ├── service/
|
|
125
|
+
│ │ ├── __init__.py
|
|
126
|
+
│ │ ├── ChatService.py # Điều phối hội thoại, HIL và stream (Singleton)
|
|
127
|
+
│ │ └── ConfigService.py # Quản lý cấu hình hệ thống và file .env (Singleton)
|
|
128
|
+
│ └── __init__.py
|
|
129
|
+
├── config/
|
|
130
|
+
│ ├── sys-prompt/ # Thư mục lưu trữ prompts chi tiết
|
|
131
|
+
│ ├── v0/ # Cấu hình v0 (mặc định)
|
|
132
|
+
│ │ ├── config.yml # Chứa system prompt của Agent chính
|
|
133
|
+
│ │ └── subagent.yml # Định nghĩa các subagent hỗ trợ
|
|
134
|
+
│ └── v1/ # Cấu hình v1 nâng cao
|
|
135
|
+
│ ├── config.yml
|
|
136
|
+
│ └── subagent.yml
|
|
137
|
+
├── ui/
|
|
138
|
+
│ ├── controllers/
|
|
139
|
+
│ │ └── ChatController.py # Lớp điều phối sự kiện và CLI loop (Controller)
|
|
140
|
+
│ ├── models/
|
|
141
|
+
│ │ └── ChatModel.py # Lưu trữ trạng thái phiên hoạt động (Model)
|
|
142
|
+
│ ├── views/
|
|
143
|
+
│ │ └── ChatView.py # Hiển thị giao diện Rich ra console (View)
|
|
144
|
+
│ └── __init__.py
|
|
145
|
+
├── .env # Tệp cấu hình các biến môi trường
|
|
146
|
+
├── main.py # Điểm khởi chạy ứng dụng chính
|
|
147
|
+
├── GEMINI.md # Tài liệu hướng dẫn & Quy tắc của dự án
|
|
148
|
+
└── README.md # Hướng dẫn sử dụng này
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 🛠️ Hướng Dẫn Cài Đặt & Cấu Hình
|
|
154
|
+
|
|
155
|
+
### 1. Yêu Cầu Hệ Thống
|
|
156
|
+
* **Ngôn ngữ:** Python 3.11 trở lên
|
|
157
|
+
* **Hệ điều hành:** Hỗ trợ tốt trên cả Windows, macOS và Linux.
|
|
158
|
+
|
|
159
|
+
### 2. Cài Đặt Thư Viện
|
|
160
|
+
Hãy chắc chắn rằng bạn đã kích hoạt môi trường ảo (virtual environment) trước khi cài đặt các thư viện cần thiết:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
pip install -r requirements.txt
|
|
164
|
+
```
|
|
165
|
+
*(Nếu chưa có file requirements.txt, bạn cần cài đặt các thư viện lõi: `langchain`, `langgraph`, `rich`, `pydantic`, `pyyaml`, `python-dotenv` và các package của provider tương ứng như `langchain-google-genai`, `langchain-openai`, `langchain-anthropic`)*
|
|
166
|
+
|
|
167
|
+
### 3. Thiết Lập Biến Môi Trường
|
|
168
|
+
Tạo một file `.env` tại thư mục gốc của dự án với nội dung như sau:
|
|
169
|
+
|
|
170
|
+
```env
|
|
171
|
+
# Nhà cung cấp và Model mặc định khi khởi chạy
|
|
172
|
+
DEFAULT_PROVIDER=google
|
|
173
|
+
DEFAULT_MODEL=models/gemma-4-31b-it
|
|
174
|
+
CONFIG_PATH=config/v0
|
|
175
|
+
|
|
176
|
+
# Các khóa API nhà cung cấp (Thay thế bằng khóa thực tế của bạn)
|
|
177
|
+
GOOGLE_API_KEY=AIzaSy...
|
|
178
|
+
OPENAI_API_KEY=sk-...
|
|
179
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 🚀 Hướng Dẫn Sử Dụng
|
|
185
|
+
|
|
186
|
+
Khởi chạy ứng dụng trực tiếp bằng câu lệnh sau:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
python main.py
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 💡 Các Lệnh Điều Hướng CLI (Slash Commands)
|
|
193
|
+
Ngay trong khung chat của CLI, bạn có thể nhập các lệnh bắt đầu bằng ký tự gạch chéo `/` để điều khiển ứng dụng nhanh chóng:
|
|
194
|
+
|
|
195
|
+
| Lệnh | Chi tiết | Ví dụ |
|
|
196
|
+
| :--- | :--- | :--- |
|
|
197
|
+
| `/help` | Hiển thị bảng hướng dẫn các câu lệnh khả dụng. | `/help` |
|
|
198
|
+
| `/config` | Xem chi tiết cấu hình hiện tại (Provider, Model, Temp, Thread ID). | `/config` |
|
|
199
|
+
| `/provider <tên>` | Thay đổi LLM Provider (google, openai, anthropic, ollama). | `/provider openai` |
|
|
200
|
+
| `/model <tên>` | Thay đổi Model của provider hiện tại. | `/model gpt-4o` |
|
|
201
|
+
| `/apikey <khóa>` | Cập nhật API Key mới cho provider đang hoạt động. | `/apikey sk-xxxx...` |
|
|
202
|
+
| `/temp <số>` | Thiết lập lại độ sáng tạo Temperature (từ `0.0` đến `2.0`). | `/temp 0.5` |
|
|
203
|
+
| `/history` | Xem lại toàn bộ tiến trình lịch sử trò chuyện trong thread hiện tại. | `/history` |
|
|
204
|
+
| `/clear` | Xóa sạch màn hình console và in lại banner hệ thống. | `/clear` |
|
|
205
|
+
| `/exit` hoặc `/quit`| Thoát ứng dụng CLI an toàn. | `/exit` |
|
|
206
|
+
|
|
207
|
+
### 🛑 Trải Nghiệm Quy Trình Human-in-the-loop (HIL)
|
|
208
|
+
Khi Agent yêu cầu thực hiện hành động hệ thống bị ngắt (do cấu hình trong `subagent.yml` chỉ định các tool thuộc nhóm `interrupt_on`), CLI sẽ kích hoạt bảng quản lý phê duyệt:
|
|
209
|
+
|
|
210
|
+
1. Hệ thống hiển thị **Tên Công cụ**, **ID Yêu cầu** và chi tiết **Tham số truyền vào**.
|
|
211
|
+
2. Yêu cầu lựa chọn:
|
|
212
|
+
* Nhập `a` hoặc `approve` để **Đồng ý** cho phép công cụ thực thi.
|
|
213
|
+
* Nhập `r` hoặc `reject` để **Từ chối** không cho phép công cụ chạy.
|
|
214
|
+
3. Hệ thống sẽ hỏi thêm **Lời nhắn gửi cho Agent** (nếu Phê duyệt) hoặc **Lý do từ chối** (nếu Từ chối). Nội dung này sẽ được trả lại đầy đủ cho Agent để điều chỉnh hành vi suy nghĩ ở bước kế tiếp.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## 🧠 Nguyên Tắc Phát Triển & Mở Rộng Hệ Thống (Dành Cho Nhà Phát Triển)
|
|
219
|
+
|
|
220
|
+
Để đảm bảo hệ thống duy trì được tính nhất quán và kiến trúc chuẩn mực khi mở rộng:
|
|
221
|
+
|
|
222
|
+
1. **Thiết kế Hướng đối tượng (OOP):** Tất cả các thành phần logic mới phải được tổ chức trong các Class có trách nhiệm rõ ràng. Áp dụng chuẩn Design Pattern (Factory, Singleton, v.v.).
|
|
223
|
+
2. **Mở rộng LLM Provider:** Khi tích hợp một provider mới, hãy tạo một file cấu hình provider riêng biệt trong `app/core/LLM/` (ví dụ: `my_provider.py`) chứa hàm khởi tạo trả về đối tượng kế thừa từ `BaseChatModel`. Sau đó đăng ký provider mới trong `LLMFactory` tại `app/core/LLM/factory.py`. Không import hoặc khởi tạo trực tiếp mô hình ở ngoài Factory.
|
|
224
|
+
3. **Bảo vệ mã nguồn (Clean Code & Fault Tolerance):** Sử dụng các khối kiểm soát lỗi `try-except` khi giao tiếp với các module không ổn định hoặc các dịch vụ bên ngoài (LLM, File IO). Giữ nguyên các ghi chú, docstring gốc của mã nguồn khi refactor.
|
|
225
|
+
4. **Chỉnh sửa Giao diện CLI:** Khi muốn bổ sung tính năng giao diện, hãy tuân thủ mô hình MVC. Trạng thái lưu trữ tại `ChatModel`, logic render tại `ChatView` và luồng điều khiển xử lý tại `ChatController`. Đọc kỹ file mô tả hành vi của các service nếu có trước khi tích hợp API.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
main.py,sha256=6NM1QSuuIMah7oCBTjmaNo_9-lMiY3_7YEmrlmJQdwE,1022
|
|
2
|
+
app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
app/core/__init__.py,sha256=q6br3HCxpkaV3AiTIp0-KM5FqVMovYs39IQkoUWZ2eE,173
|
|
4
|
+
app/core/LLM/__init__.py,sha256=XqipXRcDtavnyAtgwl42R4kDf1I3_bRtIO94YdrawcA,97
|
|
5
|
+
app/core/LLM/anthropic_provider.py,sha256=xVrqL-gG9RO-2GhDEYq6iokj3IKM-TX_Zm9yXh99ur0,372
|
|
6
|
+
app/core/LLM/factory.py,sha256=OTN51fmr28xD77ijKPLxcPpVjB3AWV7jO_UyKEplQm4,3441
|
|
7
|
+
app/core/LLM/google_provider.py,sha256=OH827C10vL4wUyEEO6VI1aHneaJMu_gnOafPUyHRTIg,577
|
|
8
|
+
app/core/LLM/ollama_provider.py,sha256=hdjV24MLPc02N5D1wsDixspCXLq6dUteUZFzjiD0Fbk,389
|
|
9
|
+
app/core/LLM/openai_provider.py,sha256=Irivlf0C70BxzGY-X8WxTQ78E5rRD4tSmjCGO_ZV_as,347
|
|
10
|
+
app/core/agent/__init__.py,sha256=7P3P426_ojD4dzxFhlV9VPa_qbO_QtdYEcx0YwqH3bI,123
|
|
11
|
+
app/core/agent/deep_agent.py,sha256=6dSLUHVbzX_iHLF7zEZzLWZu3iX36eJ9mZzoNUUlDmY,4490
|
|
12
|
+
app/core/checkpoint/__init__.py,sha256=3cLz4qLKEUiVx02m88E13F_dCSNGE_fgrqI_JiwuYug,129
|
|
13
|
+
app/core/checkpoint/factory.py,sha256=Y5iLtEcptk0XsyZTnNH118sf3T6rTjKWt8BjbcJSMnk,2522
|
|
14
|
+
app/service/ChatService.py,sha256=dMUj6BUSlNqEJnE0nnIxFVyZV8x9sZYNYN9rLoS7D30,10464
|
|
15
|
+
app/service/ConfigService.py,sha256=CuBP5gJU2gd3QVO48nGM-b4VfC4hM7AP_nhihwT2gKY,9051
|
|
16
|
+
app/service/__init__.py,sha256=PCY68ZS9uaWIzmpmvMpMGniUW7Z3WYWTfkXEiR5mMP4,144
|
|
17
|
+
ui/__init__.py,sha256=0_rwkrEVTH3t7ZgLG9pCu7DjX1IDa_YzsNfzaUNjCB8,13
|
|
18
|
+
ui/controllers/ChatController.py,sha256=VljUd8Eqii5_SnCry1tIqV_OUtVAUCDcv2DlPj4urv8,14651
|
|
19
|
+
ui/controllers/__init__.py,sha256=puM2Ab9bUwamHZKo8_1HMnEA9ipUrqzZDvqGuY74Q7A,25
|
|
20
|
+
ui/models/ChatModel.py,sha256=o6hB2L6OaSKAF7bpK0ZBSzkeFpPxRJKzA_KgG5LomxE,2357
|
|
21
|
+
ui/models/__init__.py,sha256=Iva3eUHBSTMHaPPi1MpI2F5Qe1ST5LMFCybfYB6zD3A,20
|
|
22
|
+
ui/views/ChatView.py,sha256=fjdYeVchusipVcHupMmBzC8EmvgYfPTkc0Xi_QgkS9I,11029
|
|
23
|
+
ui/views/__init__.py,sha256=HJaT4RpdJoVAc0EZPBs2KIHW0FzKvv49wo919QWeOJ0,19
|
|
24
|
+
deep_agent_cli-1.0.0.dist-info/METADATA,sha256=F2PM3diUhnqMovkf-z0qEFdRRMrOsbkL451nxQQFCXY,15451
|
|
25
|
+
deep_agent_cli-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
26
|
+
deep_agent_cli-1.0.0.dist-info/entry_points.txt,sha256=NAsP1sNRKAaQU-KOraJasA2IrKjvQuN1M-vrvUZr8UA,45
|
|
27
|
+
deep_agent_cli-1.0.0.dist-info/top_level.txt,sha256=6O6DMJwoQoWgdF0pyEA3kgE8rGv405IQeOOUBSk5FuQ,12
|
|
28
|
+
deep_agent_cli-1.0.0.dist-info/RECORD,,
|
main.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import dotenv
|
|
4
|
+
|
|
5
|
+
# Bổ sung đường dẫn thư mục gốc vào PYTHONPATH để đảm bảo import chéo giữa ui và app hoạt động chính xác
|
|
6
|
+
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
|
7
|
+
|
|
8
|
+
from ui.models.ChatModel import ChatModel
|
|
9
|
+
from ui.views.ChatView import ChatView
|
|
10
|
+
from ui.controllers.ChatController import ChatController
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def main():
|
|
14
|
+
"""Điểm khởi chạy ứng dụng Chatbot CLI."""
|
|
15
|
+
try:
|
|
16
|
+
dotenv.load_dotenv()
|
|
17
|
+
# Khởi tạo mô hình MVC
|
|
18
|
+
model = ChatModel()
|
|
19
|
+
view = ChatView()
|
|
20
|
+
controller = ChatController(model, view)
|
|
21
|
+
# Bắt đầu vòng lặp chatbot
|
|
22
|
+
controller.start_chat_loop()
|
|
23
|
+
except KeyboardInterrupt:
|
|
24
|
+
print("\nỨng dụng dừng đột ngột bởi người dùng. Tạm biệt!")
|
|
25
|
+
sys.exit(0)
|
|
26
|
+
except Exception as e:
|
|
27
|
+
print(f"\n[Lỗi Khởi Động] Không thể chạy ứng dụng Chatbot CLI: {e}")
|
|
28
|
+
sys.exit(1)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
main()
|
ui/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Package ui
|