htmlgen-mcp 0.3.2__py3-none-any.whl → 0.3.4__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.
Potentially problematic release.
This version of htmlgen-mcp might be problematic. Click here for more details.
- htmlgen_mcp/agents/quick_generator.py +481 -63
- htmlgen_mcp/agents/smart_web_agent.py +707 -235
- htmlgen_mcp/agents/web_tools/__init__.py +41 -41
- htmlgen_mcp/agents/web_tools/css.py +148 -0
- htmlgen_mcp/agents/web_tools/js.py +12 -10
- htmlgen_mcp/agents/web_tools/navigation.py +2 -0
- htmlgen_mcp/agents/web_tools/project.py +0 -4
- htmlgen_mcp/config.py +5 -5
- htmlgen_mcp/nas_storage.py +356 -0
- htmlgen_mcp/progress_tools.py +194 -0
- htmlgen_mcp/progress_tracker.py +378 -0
- htmlgen_mcp/web_agent_server.py +16 -28
- {htmlgen_mcp-0.3.2.dist-info → htmlgen_mcp-0.3.4.dist-info}/METADATA +1 -1
- {htmlgen_mcp-0.3.2.dist-info → htmlgen_mcp-0.3.4.dist-info}/RECORD +17 -16
- htmlgen_mcp/agents/cluster_state.py +0 -414
- htmlgen_mcp/agents/cluster_storage.py +0 -341
- {htmlgen_mcp-0.3.2.dist-info → htmlgen_mcp-0.3.4.dist-info}/WHEEL +0 -0
- {htmlgen_mcp-0.3.2.dist-info → htmlgen_mcp-0.3.4.dist-info}/entry_points.txt +0 -0
- {htmlgen_mcp-0.3.2.dist-info → htmlgen_mcp-0.3.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
"""进度跟踪模块 - 支持集群环境下的任务进度查询"""
|
|
2
|
+
import json
|
|
3
|
+
import time
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Dict, List, Optional, Any
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
import hashlib
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ProgressTracker:
|
|
12
|
+
"""任务进度跟踪器 - 支持分布式环境"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, nas_base_path: str = "/app/mcp-servers/mcp-servers/html_agent"):
|
|
15
|
+
"""
|
|
16
|
+
初始化进度跟踪器
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
nas_base_path: NAS 基础路径
|
|
20
|
+
"""
|
|
21
|
+
self.nas_base = Path(nas_base_path)
|
|
22
|
+
self.progress_dir = self.nas_base / "mcp_data" / "make_web" / "progress"
|
|
23
|
+
self.progress_dir.mkdir(parents=True, exist_ok=True)
|
|
24
|
+
|
|
25
|
+
def create_task(self, task_type: str, description: str) -> str:
|
|
26
|
+
"""
|
|
27
|
+
创建新任务并返回任务 ID
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
task_type: 任务类型 (plan_site, execute_plan, etc.)
|
|
31
|
+
description: 任务描述
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
任务 ID
|
|
35
|
+
"""
|
|
36
|
+
# 生成唯一任务 ID
|
|
37
|
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
|
|
38
|
+
node_id = os.environ.get("NODE_ID", "node0")
|
|
39
|
+
random_suffix = hashlib.md5(f"{timestamp}{description}".encode()).hexdigest()[:8]
|
|
40
|
+
task_id = f"{task_type}_{node_id}_{timestamp}_{random_suffix}"
|
|
41
|
+
|
|
42
|
+
# 创建任务记录
|
|
43
|
+
task_info = {
|
|
44
|
+
"task_id": task_id,
|
|
45
|
+
"task_type": task_type,
|
|
46
|
+
"description": description,
|
|
47
|
+
"status": "pending",
|
|
48
|
+
"progress": 0,
|
|
49
|
+
"created_at": datetime.now().isoformat(),
|
|
50
|
+
"node_id": node_id,
|
|
51
|
+
"events": [],
|
|
52
|
+
"current_step": None,
|
|
53
|
+
"total_steps": None
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
self._save_task_info(task_id, task_info)
|
|
57
|
+
return task_id
|
|
58
|
+
|
|
59
|
+
def update_progress(
|
|
60
|
+
self,
|
|
61
|
+
task_id: str,
|
|
62
|
+
progress: int,
|
|
63
|
+
status: str = "running",
|
|
64
|
+
message: str = None,
|
|
65
|
+
current_step: int = None,
|
|
66
|
+
total_steps: int = None,
|
|
67
|
+
data: Dict[str, Any] = None
|
|
68
|
+
) -> None:
|
|
69
|
+
"""
|
|
70
|
+
更新任务进度
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
task_id: 任务 ID
|
|
74
|
+
progress: 进度百分比 (0-100)
|
|
75
|
+
status: 任务状态 (pending/running/completed/failed)
|
|
76
|
+
message: 进度消息
|
|
77
|
+
current_step: 当前步骤
|
|
78
|
+
total_steps: 总步骤数
|
|
79
|
+
data: 附加数据
|
|
80
|
+
"""
|
|
81
|
+
task_info = self._load_task_info(task_id)
|
|
82
|
+
if not task_info:
|
|
83
|
+
task_info = {"task_id": task_id, "events": []}
|
|
84
|
+
|
|
85
|
+
# 更新基本信息
|
|
86
|
+
task_info["progress"] = progress
|
|
87
|
+
task_info["status"] = status
|
|
88
|
+
task_info["updated_at"] = datetime.now().isoformat()
|
|
89
|
+
|
|
90
|
+
if current_step is not None:
|
|
91
|
+
task_info["current_step"] = current_step
|
|
92
|
+
if total_steps is not None:
|
|
93
|
+
task_info["total_steps"] = total_steps
|
|
94
|
+
|
|
95
|
+
# 添加事件记录
|
|
96
|
+
event = {
|
|
97
|
+
"timestamp": datetime.now().isoformat(),
|
|
98
|
+
"progress": progress,
|
|
99
|
+
"status": status,
|
|
100
|
+
"message": message
|
|
101
|
+
}
|
|
102
|
+
if data:
|
|
103
|
+
event["data"] = data
|
|
104
|
+
|
|
105
|
+
task_info["events"].append(event)
|
|
106
|
+
|
|
107
|
+
# 保存更新
|
|
108
|
+
self._save_task_info(task_id, task_info)
|
|
109
|
+
|
|
110
|
+
# 同时写入流式日志(用于实时查询)
|
|
111
|
+
self._append_progress_log(task_id, event)
|
|
112
|
+
|
|
113
|
+
def get_task_progress(self, task_id: str) -> Optional[Dict[str, Any]]:
|
|
114
|
+
"""
|
|
115
|
+
获取任务进度
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
task_id: 任务 ID
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
任务进度信息
|
|
122
|
+
"""
|
|
123
|
+
return self._load_task_info(task_id)
|
|
124
|
+
|
|
125
|
+
def get_task_events(
|
|
126
|
+
self,
|
|
127
|
+
task_id: str,
|
|
128
|
+
since_timestamp: Optional[str] = None
|
|
129
|
+
) -> List[Dict[str, Any]]:
|
|
130
|
+
"""
|
|
131
|
+
获取任务事件(支持增量查询)
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
task_id: 任务 ID
|
|
135
|
+
since_timestamp: 从此时间戳之后的事件
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
事件列表
|
|
139
|
+
"""
|
|
140
|
+
task_info = self._load_task_info(task_id)
|
|
141
|
+
if not task_info:
|
|
142
|
+
return []
|
|
143
|
+
|
|
144
|
+
events = task_info.get("events", [])
|
|
145
|
+
|
|
146
|
+
if since_timestamp:
|
|
147
|
+
# 过滤出指定时间后的事件
|
|
148
|
+
events = [
|
|
149
|
+
e for e in events
|
|
150
|
+
if e.get("timestamp", "") > since_timestamp
|
|
151
|
+
]
|
|
152
|
+
|
|
153
|
+
return events
|
|
154
|
+
|
|
155
|
+
def list_tasks(
|
|
156
|
+
self,
|
|
157
|
+
task_type: Optional[str] = None,
|
|
158
|
+
status: Optional[str] = None,
|
|
159
|
+
limit: int = 20
|
|
160
|
+
) -> List[Dict[str, Any]]:
|
|
161
|
+
"""
|
|
162
|
+
列出任务列表
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
task_type: 筛选任务类型
|
|
166
|
+
status: 筛选任务状态
|
|
167
|
+
limit: 返回数量限制
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
任务列表
|
|
171
|
+
"""
|
|
172
|
+
tasks = []
|
|
173
|
+
|
|
174
|
+
# 扫描所有任务文件
|
|
175
|
+
for task_file in self.progress_dir.glob("*.json"):
|
|
176
|
+
if task_file.name.endswith("_log.json"):
|
|
177
|
+
continue # 跳过日志文件
|
|
178
|
+
|
|
179
|
+
try:
|
|
180
|
+
with open(task_file, 'r', encoding='utf-8') as f:
|
|
181
|
+
task_info = json.load(f)
|
|
182
|
+
|
|
183
|
+
# 应用过滤条件
|
|
184
|
+
if task_type and task_info.get("task_type") != task_type:
|
|
185
|
+
continue
|
|
186
|
+
if status and task_info.get("status") != status:
|
|
187
|
+
continue
|
|
188
|
+
|
|
189
|
+
# 精简信息,不包含完整事件列表
|
|
190
|
+
summary = {
|
|
191
|
+
"task_id": task_info.get("task_id"),
|
|
192
|
+
"task_type": task_info.get("task_type"),
|
|
193
|
+
"description": task_info.get("description"),
|
|
194
|
+
"status": task_info.get("status"),
|
|
195
|
+
"progress": task_info.get("progress"),
|
|
196
|
+
"created_at": task_info.get("created_at"),
|
|
197
|
+
"updated_at": task_info.get("updated_at"),
|
|
198
|
+
"current_step": task_info.get("current_step"),
|
|
199
|
+
"total_steps": task_info.get("total_steps")
|
|
200
|
+
}
|
|
201
|
+
tasks.append(summary)
|
|
202
|
+
|
|
203
|
+
except Exception:
|
|
204
|
+
continue
|
|
205
|
+
|
|
206
|
+
# 按创建时间倒序排序
|
|
207
|
+
tasks.sort(key=lambda x: x.get("created_at", ""), reverse=True)
|
|
208
|
+
|
|
209
|
+
return tasks[:limit]
|
|
210
|
+
|
|
211
|
+
def get_realtime_progress(self, task_id: str) -> Dict[str, Any]:
|
|
212
|
+
"""
|
|
213
|
+
获取实时进度(用于 SSE 流式传输)
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
task_id: 任务 ID
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
实时进度信息
|
|
220
|
+
"""
|
|
221
|
+
task_info = self._load_task_info(task_id)
|
|
222
|
+
if not task_info:
|
|
223
|
+
return {
|
|
224
|
+
"task_id": task_id,
|
|
225
|
+
"status": "not_found",
|
|
226
|
+
"progress": 0
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
# 计算详细进度
|
|
230
|
+
progress_detail = {
|
|
231
|
+
"task_id": task_id,
|
|
232
|
+
"status": task_info.get("status", "unknown"),
|
|
233
|
+
"progress": task_info.get("progress", 0),
|
|
234
|
+
"current_step": task_info.get("current_step"),
|
|
235
|
+
"total_steps": task_info.get("total_steps"),
|
|
236
|
+
"message": None
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
# 获取最新消息
|
|
240
|
+
events = task_info.get("events", [])
|
|
241
|
+
if events:
|
|
242
|
+
latest_event = events[-1]
|
|
243
|
+
progress_detail["message"] = latest_event.get("message")
|
|
244
|
+
progress_detail["last_update"] = latest_event.get("timestamp")
|
|
245
|
+
|
|
246
|
+
# 如果有步骤信息,计算步骤进度
|
|
247
|
+
if progress_detail["current_step"] and progress_detail["total_steps"]:
|
|
248
|
+
step_progress = (progress_detail["current_step"] / progress_detail["total_steps"]) * 100
|
|
249
|
+
progress_detail["step_progress"] = round(step_progress, 1)
|
|
250
|
+
|
|
251
|
+
return progress_detail
|
|
252
|
+
|
|
253
|
+
def _save_task_info(self, task_id: str, task_info: Dict[str, Any]) -> None:
|
|
254
|
+
"""保存任务信息到 NAS"""
|
|
255
|
+
task_file = self.progress_dir / f"{task_id}.json"
|
|
256
|
+
|
|
257
|
+
# 原子性写入(先写临时文件,再重命名)
|
|
258
|
+
temp_file = task_file.with_suffix('.tmp')
|
|
259
|
+
with open(temp_file, 'w', encoding='utf-8') as f:
|
|
260
|
+
json.dump(task_info, f, ensure_ascii=False, indent=2)
|
|
261
|
+
|
|
262
|
+
# 重命名(原子操作)
|
|
263
|
+
temp_file.replace(task_file)
|
|
264
|
+
|
|
265
|
+
def _load_task_info(self, task_id: str) -> Optional[Dict[str, Any]]:
|
|
266
|
+
"""从 NAS 加载任务信息"""
|
|
267
|
+
task_file = self.progress_dir / f"{task_id}.json"
|
|
268
|
+
|
|
269
|
+
if not task_file.exists():
|
|
270
|
+
return None
|
|
271
|
+
|
|
272
|
+
try:
|
|
273
|
+
with open(task_file, 'r', encoding='utf-8') as f:
|
|
274
|
+
return json.load(f)
|
|
275
|
+
except Exception:
|
|
276
|
+
return None
|
|
277
|
+
|
|
278
|
+
def _append_progress_log(self, task_id: str, event: Dict[str, Any]) -> None:
|
|
279
|
+
"""追加进度日志(用于流式查询)"""
|
|
280
|
+
log_file = self.progress_dir / f"{task_id}_log.jsonl"
|
|
281
|
+
|
|
282
|
+
try:
|
|
283
|
+
with open(log_file, 'a', encoding='utf-8') as f:
|
|
284
|
+
f.write(json.dumps(event, ensure_ascii=False))
|
|
285
|
+
f.write('\n')
|
|
286
|
+
except Exception:
|
|
287
|
+
pass
|
|
288
|
+
|
|
289
|
+
def cleanup_old_tasks(self, days_to_keep: int = 7) -> int:
|
|
290
|
+
"""
|
|
291
|
+
清理旧任务
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
days_to_keep: 保留天数
|
|
295
|
+
|
|
296
|
+
Returns:
|
|
297
|
+
清理的任务数量
|
|
298
|
+
"""
|
|
299
|
+
cleaned = 0
|
|
300
|
+
cutoff_time = time.time() - (days_to_keep * 24 * 3600)
|
|
301
|
+
|
|
302
|
+
for task_file in self.progress_dir.glob("*.json"):
|
|
303
|
+
try:
|
|
304
|
+
# 检查文件修改时间
|
|
305
|
+
if task_file.stat().st_mtime < cutoff_time:
|
|
306
|
+
task_file.unlink()
|
|
307
|
+
|
|
308
|
+
# 同时删除对应的日志文件
|
|
309
|
+
log_file = task_file.with_suffix('.jsonl')
|
|
310
|
+
if log_file.exists():
|
|
311
|
+
log_file.unlink()
|
|
312
|
+
|
|
313
|
+
cleaned += 1
|
|
314
|
+
except Exception:
|
|
315
|
+
continue
|
|
316
|
+
|
|
317
|
+
return cleaned
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
# 全局进度跟踪器实例
|
|
321
|
+
_progress_tracker: Optional[ProgressTracker] = None
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def get_progress_tracker() -> ProgressTracker:
|
|
325
|
+
"""获取进度跟踪器实例(单例)"""
|
|
326
|
+
global _progress_tracker
|
|
327
|
+
if _progress_tracker is None:
|
|
328
|
+
nas_path = os.environ.get(
|
|
329
|
+
"NAS_STORAGE_PATH",
|
|
330
|
+
"/app/mcp-servers/mcp-servers/html_agent"
|
|
331
|
+
)
|
|
332
|
+
_progress_tracker = ProgressTracker(nas_path)
|
|
333
|
+
return _progress_tracker
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
# 便捷函数
|
|
337
|
+
def track_task(task_type: str, description: str):
|
|
338
|
+
"""
|
|
339
|
+
任务跟踪装饰器
|
|
340
|
+
|
|
341
|
+
使用方式:
|
|
342
|
+
@track_task("plan_site", "生成网站计划")
|
|
343
|
+
async def plan_site(description: str):
|
|
344
|
+
...
|
|
345
|
+
"""
|
|
346
|
+
def decorator(func):
|
|
347
|
+
async def wrapper(*args, **kwargs):
|
|
348
|
+
tracker = get_progress_tracker()
|
|
349
|
+
task_id = tracker.create_task(task_type, description)
|
|
350
|
+
|
|
351
|
+
try:
|
|
352
|
+
# 标记任务开始
|
|
353
|
+
tracker.update_progress(task_id, 0, "running", "任务开始执行")
|
|
354
|
+
|
|
355
|
+
# 执行任务
|
|
356
|
+
result = await func(*args, **kwargs)
|
|
357
|
+
|
|
358
|
+
# 标记任务完成
|
|
359
|
+
tracker.update_progress(task_id, 100, "completed", "任务执行成功")
|
|
360
|
+
|
|
361
|
+
# 在结果中添加任务 ID
|
|
362
|
+
if isinstance(result, dict):
|
|
363
|
+
result["task_id"] = task_id
|
|
364
|
+
|
|
365
|
+
return result
|
|
366
|
+
|
|
367
|
+
except Exception as e:
|
|
368
|
+
# 标记任务失败
|
|
369
|
+
tracker.update_progress(
|
|
370
|
+
task_id,
|
|
371
|
+
tracker.get_task_progress(task_id).get("progress", 0),
|
|
372
|
+
"failed",
|
|
373
|
+
f"任务执行失败: {str(e)}"
|
|
374
|
+
)
|
|
375
|
+
raise
|
|
376
|
+
|
|
377
|
+
return wrapper
|
|
378
|
+
return decorator
|
htmlgen_mcp/web_agent_server.py
CHANGED
|
@@ -31,9 +31,13 @@ import uuid
|
|
|
31
31
|
from pathlib import Path
|
|
32
32
|
|
|
33
33
|
from htmlgen_mcp.agents.smart_web_agent import SmartWebAgent
|
|
34
|
+
from htmlgen_mcp.nas_storage import get_nas_storage
|
|
35
|
+
from datetime import datetime
|
|
34
36
|
|
|
37
|
+
# 使用 NAS 作为默认存储路径
|
|
38
|
+
NAS_PATH = os.environ.get("NAS_STORAGE_PATH", "/app/mcp-servers/mcp-servers/html_agent")
|
|
35
39
|
DEFAULT_PROJECT_ROOT = os.path.abspath(
|
|
36
|
-
os.environ.get("WEB_AGENT_PROJECT_ROOT",
|
|
40
|
+
os.environ.get("WEB_AGENT_PROJECT_ROOT", f"{NAS_PATH}/projects")
|
|
37
41
|
)
|
|
38
42
|
DEFAULT_MODEL = os.environ.get("WEB_AGENT_MODEL", "qwen3-coder-plus-2025-09-23")
|
|
39
43
|
DEFAULT_BASE_URL = os.environ.get(
|
|
@@ -42,45 +46,26 @@ DEFAULT_BASE_URL = os.environ.get(
|
|
|
42
46
|
|
|
43
47
|
mcp = FastMCP("smart-web-agent")
|
|
44
48
|
|
|
45
|
-
# MCP
|
|
46
|
-
DEFAULT_MCP_STORAGE = Path.home() / ".mcp"
|
|
49
|
+
# MCP 服务持久化目录:使用 NAS 路径以便集群共享
|
|
47
50
|
MCP_SERVICE_NAME = os.environ.get("MCP_SERVICE_NAME", "make_web")
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
env_dir = os.environ.get("MCP_DATA_DIR")
|
|
53
|
-
if env_dir:
|
|
54
|
-
path = Path(env_dir)
|
|
55
|
-
path.mkdir(parents=True, exist_ok=True)
|
|
56
|
-
return path
|
|
57
|
-
|
|
58
|
-
shared_dir = Path(DEFAULT_PROJECT_ROOT) / ".mcp_state"
|
|
59
|
-
try:
|
|
60
|
-
shared_dir.mkdir(parents=True, exist_ok=True)
|
|
61
|
-
return shared_dir
|
|
62
|
-
except Exception:
|
|
63
|
-
fallback = DEFAULT_MCP_STORAGE / MCP_SERVICE_NAME
|
|
64
|
-
fallback.mkdir(parents=True, exist_ok=True)
|
|
65
|
-
print(
|
|
66
|
-
f"⚠️ 无法在 {shared_dir} 创建 MCP 数据目录,改用 {fallback}",
|
|
67
|
-
file=sys.stderr,
|
|
68
|
-
)
|
|
69
|
-
return fallback
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
MCP_DATA_ROOT = _resolve_mcp_data_root()
|
|
51
|
+
MCP_DATA_ROOT = Path(
|
|
52
|
+
os.environ.get("MCP_DATA_DIR", f"{NAS_PATH}/mcp_data/{MCP_SERVICE_NAME}")
|
|
53
|
+
)
|
|
54
|
+
MCP_DATA_ROOT.mkdir(parents=True, exist_ok=True)
|
|
73
55
|
|
|
74
56
|
# 简单的缓存:记录最近一次生成的计划,避免“create_simple_site → execute_plan”时需手动传递
|
|
75
57
|
PLAN_CACHE_DIR = MCP_DATA_ROOT / "plan_cache"
|
|
76
58
|
PLAN_CACHE_DIR.mkdir(exist_ok=True)
|
|
77
59
|
|
|
60
|
+
# 进度日志目录,存储每个任务的实时进度
|
|
78
61
|
PROGRESS_LOG_DIR = MCP_DATA_ROOT / "progress_logs"
|
|
79
62
|
PROGRESS_LOG_DIR.mkdir(exist_ok=True)
|
|
80
63
|
|
|
64
|
+
# 任务状态目录,每个任务一个 JSON 文件
|
|
81
65
|
JOB_STATE_DIR = MCP_DATA_ROOT / "jobs" / "state"
|
|
82
66
|
JOB_STATE_DIR.mkdir(parents=True, exist_ok=True)
|
|
83
67
|
|
|
68
|
+
# 上下文缓存目录
|
|
84
69
|
CONTEXT_CACHE_DIR = MCP_DATA_ROOT / "context_cache"
|
|
85
70
|
CONTEXT_CACHE_DIR.mkdir(exist_ok=True)
|
|
86
71
|
|
|
@@ -189,6 +174,7 @@ def _build_agent(
|
|
|
189
174
|
show_code: bool = False,
|
|
190
175
|
verbose: bool = False,
|
|
191
176
|
save_output: bool = False,
|
|
177
|
+
force_single_page: bool = True,
|
|
192
178
|
) -> SmartWebAgent:
|
|
193
179
|
return SmartWebAgent(
|
|
194
180
|
project_directory=project_directory,
|
|
@@ -196,6 +182,7 @@ def _build_agent(
|
|
|
196
182
|
show_code=show_code,
|
|
197
183
|
verbose=verbose,
|
|
198
184
|
save_output=save_output,
|
|
185
|
+
force_single_page=force_single_page,
|
|
199
186
|
)
|
|
200
187
|
|
|
201
188
|
|
|
@@ -764,6 +751,7 @@ async def create_simple_site(
|
|
|
764
751
|
model=used_model,
|
|
765
752
|
show_code=False,
|
|
766
753
|
verbose=False,
|
|
754
|
+
force_single_page=True,
|
|
767
755
|
)
|
|
768
756
|
|
|
769
757
|
# 构建针对简单网站的提示,包含上下文和图片要求
|
|
@@ -1,33 +1,34 @@
|
|
|
1
1
|
htmlgen_mcp/__init__.py,sha256=8jambwGFxu8RNWes1BUEGDHErV-LcvDaABWqNja9GW0,114
|
|
2
|
-
htmlgen_mcp/config.py,sha256=
|
|
2
|
+
htmlgen_mcp/config.py,sha256=Xd9naNKP1LfgOfOSXf2QbzKfrmByWvYsNP1OumDH25E,11249
|
|
3
|
+
htmlgen_mcp/nas_storage.py,sha256=HpgROy53vrYiBiXsUJO56GCoYZdyYR15iVvOBqyp7Yc,11292
|
|
4
|
+
htmlgen_mcp/progress_tools.py,sha256=SOScPSr3hEv4rvGzqvwUcomEFiPhhNxJ7CbWURlFpBs,5067
|
|
5
|
+
htmlgen_mcp/progress_tracker.py,sha256=2TVduWNJJH08EQ7Vf9EpiwPjtp61JX7muSCdbGHZAfM,12210
|
|
3
6
|
htmlgen_mcp/sse_optimizations.py,sha256=_UTpgLtxgNAiiEkO5lPihOi1-eEQk6R4ejNParufrrc,6932
|
|
4
|
-
htmlgen_mcp/web_agent_server.py,sha256=
|
|
7
|
+
htmlgen_mcp/web_agent_server.py,sha256=_0t-HJBmqF2vGF5aVfsV1LQQGzmW0E95ocwBQn5jBNQ,47848
|
|
5
8
|
htmlgen_mcp/agents/__init__.py,sha256=Xydfjzw9s9O6I5Ixx6EmsTdXu26136NDPUAqt9B1hzE,121
|
|
6
9
|
htmlgen_mcp/agents/ai_content_generator.py,sha256=tWGC9cY6Wp7MB1P9J7uCv8LUdiS02rgS6vxaNHD7KQk,10311
|
|
7
|
-
htmlgen_mcp/agents/
|
|
8
|
-
htmlgen_mcp/agents/
|
|
9
|
-
htmlgen_mcp/agents/
|
|
10
|
-
htmlgen_mcp/agents/smart_web_agent.py,sha256=gIlHqE2Zvf8IwXQCBVSzteYN0u7C6e3n5D7jCDlbR-8,99054
|
|
11
|
-
htmlgen_mcp/agents/web_tools/__init__.py,sha256=2Km6T6tMkjMFKoEWkrsSuLUyr_yfHq78_V_oreqQOMc,2472
|
|
10
|
+
htmlgen_mcp/agents/quick_generator.py,sha256=2wV4PCRugV0suTedLDV91_etHy_2Fiw4J0MraT7MQjw,34201
|
|
11
|
+
htmlgen_mcp/agents/smart_web_agent.py,sha256=i651WqD54BhM6WfabutTyBY3VwshkFaYPDJ4H-yapQI,126830
|
|
12
|
+
htmlgen_mcp/agents/web_tools/__init__.py,sha256=oqH9p3C6UHn2yOzBgbHZK3D_rCoWQmQxM-jI4YLTseg,2649
|
|
12
13
|
htmlgen_mcp/agents/web_tools/bootstrap.py,sha256=QOoR38GhrK2JHow2P86fHgV9r6UFGDikwT0w6Qq4yh0,1909
|
|
13
14
|
htmlgen_mcp/agents/web_tools/browser.py,sha256=0Z84BtvBSXplpIDySw_ICH6RZPe9PtSYP8WGm4GJp0M,870
|
|
14
15
|
htmlgen_mcp/agents/web_tools/colors.py,sha256=GyoDWJiJPMTXRrYiJ8c0-ur25jDOZuq5nNSPDA38yEI,5242
|
|
15
|
-
htmlgen_mcp/agents/web_tools/css.py,sha256=
|
|
16
|
+
htmlgen_mcp/agents/web_tools/css.py,sha256=_JlOjowjtqYm8LQ5dcl1A3f_DxBtLdQJMCk3oxM1BKI,41084
|
|
16
17
|
htmlgen_mcp/agents/web_tools/edgeone_deploy.py,sha256=DAc0ISqu8swGG9MEU2o8ONc7PDGsQ2MOakcSi2phxfk,20113
|
|
17
18
|
htmlgen_mcp/agents/web_tools/html_templates.py,sha256=kbs0slN5kIXstlMbqgLBQxMOVQtlap2lwLYg-3GBR4s,79659
|
|
18
19
|
htmlgen_mcp/agents/web_tools/html_templates_improved.py,sha256=i9XWv4Cqm94Ud7lqkOHgYHazhZDacrSPpamI9F1fw8g,25221
|
|
19
20
|
htmlgen_mcp/agents/web_tools/images.py,sha256=miFp8-77SLlvBDBBbR6LYDfYGVzO0GmcZz06CQC16Gc,27617
|
|
20
21
|
htmlgen_mcp/agents/web_tools/images_fixed.py,sha256=2L1m4TKTx253Eigb_OSg89mOIjfzwBXfeyDJ7hsh3tw,7567
|
|
21
|
-
htmlgen_mcp/agents/web_tools/js.py,sha256=
|
|
22
|
-
htmlgen_mcp/agents/web_tools/navigation.py,sha256=
|
|
23
|
-
htmlgen_mcp/agents/web_tools/project.py,sha256=
|
|
22
|
+
htmlgen_mcp/agents/web_tools/js.py,sha256=DFS5kj65qU6tEZcwS4Hxr2_JqVncLwNdtdPoMU8-oEU,9468
|
|
23
|
+
htmlgen_mcp/agents/web_tools/navigation.py,sha256=7ABTqRHsQ2IOeT-RN1b9uVCxGm8IFkLZQA1CFuevPEE,19935
|
|
24
|
+
htmlgen_mcp/agents/web_tools/project.py,sha256=9iw09yAIpWO5l9TCz5FPtr8k5TPbF32BfnYJW-P5w3w,841
|
|
24
25
|
htmlgen_mcp/agents/web_tools/simple_builder.py,sha256=nfxrr0F_wlaq4k7_No3_33stnBlxhyjFFGQBxxPtGTM,10658
|
|
25
26
|
htmlgen_mcp/agents/web_tools/simple_css.py,sha256=kj9X3sHHhj1wGwBVL20j6w2qIHXRdxfBXoldnabxKsk,8278
|
|
26
27
|
htmlgen_mcp/agents/web_tools/simple_js.py,sha256=xMiuF-u-h_IIkUONZIa4Xf8vKB5mcXxwQf5b_BIcpoE,12174
|
|
27
28
|
htmlgen_mcp/agents/web_tools/simple_templates.py,sha256=-Rs-SsWpGZT2hiwa3jZNVDHOMZOo1vV2pWbmBdR30os,6471
|
|
28
29
|
htmlgen_mcp/agents/web_tools/validation.py,sha256=bNA6aWXrCSi7sPqQw5bBR3XF69gRf85D5jSMi996CtI,2069
|
|
29
|
-
htmlgen_mcp-0.3.
|
|
30
|
-
htmlgen_mcp-0.3.
|
|
31
|
-
htmlgen_mcp-0.3.
|
|
32
|
-
htmlgen_mcp-0.3.
|
|
33
|
-
htmlgen_mcp-0.3.
|
|
30
|
+
htmlgen_mcp-0.3.4.dist-info/METADATA,sha256=UIbhoxesfWZpcwkrDDehZ5FlHmFN2Kv3gj3zkdF8SEs,5161
|
|
31
|
+
htmlgen_mcp-0.3.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
32
|
+
htmlgen_mcp-0.3.4.dist-info/entry_points.txt,sha256=w7ufTQJobIxT3FYI24yKsCEwEQvBOWhNjckUd9Amu_k,66
|
|
33
|
+
htmlgen_mcp-0.3.4.dist-info/top_level.txt,sha256=KnglzX4ekV8SQkHTsJg2_nTBXz2TxaYLdvoMMovHLNk,12
|
|
34
|
+
htmlgen_mcp-0.3.4.dist-info/RECORD,,
|