stigmergy 1.0.68 → 1.0.70
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.
- package/README.en.md +306 -300
- package/README.md +469 -301
- package/package.json +97 -81
- package/scripts/publish.js +268 -0
- package/scripts/simple-publish.js +59 -0
- package/src/index.js +12 -0
- package/test/enhanced-main-alignment.test.js +298 -0
- package/test/hook-system-integration-test.js +307 -0
- package/test/natural-language-skills-test.js +320 -0
- package/test/nl-integration-test.js +179 -0
- package/test/parameter-parsing-test.js +143 -0
- package/test/real-test.js +435 -0
- package/test/system-compatibility-test.js +447 -0
- package/test/tdd-fixes-test.js +211 -0
- package/test/third-party-skills-test.js +321 -0
- package/test/tool-selection-integration-test.js +157 -0
- package/test/unit/cli-scanner.test.js +291 -0
- package/test/unit/cross-cli-executor.test.js +399 -0
- package/src/adapters/claude/__init__.py +0 -13
- package/src/adapters/claude/claude_skills_integration.py +0 -609
- package/src/adapters/claude/hook_adapter.py +0 -663
- package/src/adapters/claude/install_claude_integration.py +0 -265
- package/src/adapters/claude/skills_hook_adapter.py +0 -841
- package/src/adapters/claude/standalone_claude_adapter.py +0 -384
- package/src/adapters/cline/__init__.py +0 -20
- package/src/adapters/cline/config.py +0 -108
- package/src/adapters/cline/install_cline_integration.py +0 -617
- package/src/adapters/cline/mcp_server.py +0 -713
- package/src/adapters/cline/standalone_cline_adapter.py +0 -459
- package/src/adapters/codebuddy/__init__.py +0 -13
- package/src/adapters/codebuddy/buddy_adapter.py +0 -1125
- package/src/adapters/codebuddy/install_codebuddy_integration.py +0 -279
- package/src/adapters/codebuddy/skills_hook_adapter.py +0 -672
- package/src/adapters/codebuddy/skills_integration.py +0 -395
- package/src/adapters/codebuddy/standalone_codebuddy_adapter.py +0 -403
- package/src/adapters/codex/__init__.py +0 -11
- package/src/adapters/codex/base.py +0 -46
- package/src/adapters/codex/install_codex_integration.py +0 -311
- package/src/adapters/codex/mcp_server.py +0 -493
- package/src/adapters/codex/natural_language_parser.py +0 -82
- package/src/adapters/codex/slash_command_adapter.py +0 -326
- package/src/adapters/codex/standalone_codex_adapter.py +0 -362
- package/src/adapters/copilot/__init__.py +0 -13
- package/src/adapters/copilot/install_copilot_integration.py +0 -564
- package/src/adapters/copilot/mcp_adapter.py +0 -772
- package/src/adapters/copilot/mcp_server.py +0 -168
- package/src/adapters/copilot/standalone_copilot_adapter.py +0 -114
- package/src/adapters/gemini/__init__.py +0 -13
- package/src/adapters/gemini/extension_adapter.py +0 -690
- package/src/adapters/gemini/install_gemini_integration.py +0 -257
- package/src/adapters/gemini/standalone_gemini_adapter.py +0 -366
- package/src/adapters/iflow/__init__.py +0 -7
- package/src/adapters/iflow/hook_adapter.py +0 -1038
- package/src/adapters/iflow/hook_installer.py +0 -536
- package/src/adapters/iflow/install_iflow_integration.py +0 -271
- package/src/adapters/iflow/official_hook_adapter.py +0 -1272
- package/src/adapters/iflow/standalone_iflow_adapter.py +0 -48
- package/src/adapters/iflow/workflow_adapter.py +0 -793
- package/src/adapters/qoder/hook_installer.py +0 -732
- package/src/adapters/qoder/install_qoder_integration.py +0 -265
- package/src/adapters/qoder/notification_hook_adapter.py +0 -863
- package/src/adapters/qoder/standalone_qoder_adapter.py +0 -48
- package/src/adapters/qwen/__init__.py +0 -17
- package/src/adapters/qwencode/__init__.py +0 -13
- package/src/adapters/qwencode/inheritance_adapter.py +0 -818
- package/src/adapters/qwencode/install_qwencode_integration.py +0 -276
- package/src/adapters/qwencode/standalone_qwencode_adapter.py +0 -399
- package/src/atomic_collaboration_handler.py +0 -461
- package/src/cli_collaboration_agent.py +0 -697
- package/src/collaboration/hooks.py +0 -315
- package/src/core/__init__.py +0 -21
- package/src/core/ai_environment_scanner.py +0 -331
- package/src/core/base_adapter.py +0 -220
- package/src/core/cli_hook_integration.py +0 -406
- package/src/core/cross_cli_executor.py +0 -713
- package/src/core/cross_cli_mapping.py +0 -1165
- package/src/core/cross_platform_encoding.py +0 -365
- package/src/core/cross_platform_safe_cli.py +0 -894
- package/src/core/direct_cli_executor.py +0 -805
- package/src/core/direct_cli_hook_system.py +0 -958
- package/src/core/enhanced_init_processor.py +0 -467
- package/src/core/graceful_cli_executor.py +0 -912
- package/src/core/md_enhancer.py +0 -342
- package/src/core/md_generator.py +0 -619
- package/src/core/models.py +0 -218
- package/src/core/parser.py +0 -108
- package/src/core/real_cli_hook_system.py +0 -852
- package/src/core/real_cross_cli_system.py +0 -925
- package/src/core/verified_cross_cli_system.py +0 -961
- package/src/deploy.js +0 -737
- package/src/enhanced-main.js +0 -626
- package/src/enhanced_deploy.js +0 -303
- package/src/enhanced_universal_cli_setup.py +0 -930
- package/src/kimi_wrapper.py +0 -104
- package/src/main.js +0 -1309
- package/src/shell_integration.py +0 -398
- package/src/simple-main.js +0 -315
- package/src/smart_router_creator.py +0 -323
- package/src/universal_cli_setup.py +0 -1289
- package/src/utils/__init__.py +0 -12
- package/src/utils/cli_detector.py +0 -445
- package/src/utils/file_utils.py +0 -246
|
@@ -1,461 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
"""
|
|
4
|
-
智能体协作系统 - 原子性背景管理器
|
|
5
|
-
实现多智能体安全协作,防止任务重复认领
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import json
|
|
9
|
-
import time
|
|
10
|
-
import threading
|
|
11
|
-
import subprocess
|
|
12
|
-
from pathlib import Path
|
|
13
|
-
from datetime import datetime
|
|
14
|
-
import tempfile
|
|
15
|
-
import os
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class AtomicFileHandler:
|
|
19
|
-
"""原子性文件处理器 - 确保并发安全"""
|
|
20
|
-
|
|
21
|
-
def __init__(self, file_path):
|
|
22
|
-
self.file_path = Path(file_path)
|
|
23
|
-
self.lock_path = self.file_path.with_suffix(self.file_path.suffix + '.lock')
|
|
24
|
-
self.lock = threading.Lock() # 内存锁,防止同一进程内的并发冲突
|
|
25
|
-
|
|
26
|
-
def atomic_read(self):
|
|
27
|
-
"""原子性读取文件"""
|
|
28
|
-
max_retries = 10
|
|
29
|
-
for attempt in range(max_retries):
|
|
30
|
-
try:
|
|
31
|
-
# 等待外部锁释放(通过文件的存在)
|
|
32
|
-
while self.lock_path.exists():
|
|
33
|
-
time.sleep(0.01)
|
|
34
|
-
|
|
35
|
-
# 检查文件是否存在
|
|
36
|
-
if not self.file_path.exists():
|
|
37
|
-
return None
|
|
38
|
-
|
|
39
|
-
with open(self.file_path, 'r', encoding='utf-8') as f:
|
|
40
|
-
return json.load(f)
|
|
41
|
-
except json.JSONDecodeError:
|
|
42
|
-
# 文件可能在写入过程中,等待重试
|
|
43
|
-
if attempt == max_retries - 1:
|
|
44
|
-
raise
|
|
45
|
-
time.sleep(0.01 * (attempt + 1))
|
|
46
|
-
except Exception as e:
|
|
47
|
-
if attempt == max_retries - 1:
|
|
48
|
-
raise
|
|
49
|
-
time.sleep(0.01 * (attempt + 1))
|
|
50
|
-
|
|
51
|
-
def atomic_write(self, data):
|
|
52
|
-
"""原子性写入文件"""
|
|
53
|
-
with self.lock: # 先获取内存锁
|
|
54
|
-
# 创建临时文件
|
|
55
|
-
temp_path = self.file_path.with_suffix(self.file_path.suffix + '.tmp')
|
|
56
|
-
|
|
57
|
-
try:
|
|
58
|
-
# 创建锁文件,表明正在进行写操作
|
|
59
|
-
self.lock_path.touch()
|
|
60
|
-
|
|
61
|
-
# 写入临时文件
|
|
62
|
-
with open(temp_path, 'w', encoding='utf-8') as f:
|
|
63
|
-
json.dump(data, f, ensure_ascii=False, indent=2)
|
|
64
|
-
|
|
65
|
-
# 原子性移动 - 在大多数系统上是原子操作
|
|
66
|
-
temp_path.replace(self.file_path)
|
|
67
|
-
|
|
68
|
-
return True
|
|
69
|
-
|
|
70
|
-
except Exception as e:
|
|
71
|
-
print(f"原子写入失败: {e}")
|
|
72
|
-
# 确保清理临时文件
|
|
73
|
-
if temp_path.exists():
|
|
74
|
-
try:
|
|
75
|
-
temp_path.unlink()
|
|
76
|
-
except:
|
|
77
|
-
pass
|
|
78
|
-
return False
|
|
79
|
-
finally:
|
|
80
|
-
# 无论成功与否,都要释放锁
|
|
81
|
-
if self.lock_path.exists():
|
|
82
|
-
try:
|
|
83
|
-
self.lock_path.unlink()
|
|
84
|
-
except:
|
|
85
|
-
pass
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
class SharedProjectContext:
|
|
89
|
-
"""共享项目背景管理器 - 实现Stigmergy机制"""
|
|
90
|
-
|
|
91
|
-
def __init__(self, project_path):
|
|
92
|
-
self.project_path = Path(project_path)
|
|
93
|
-
self.spec_file = self.project_path / "PROJECT_SPEC.json"
|
|
94
|
-
self.handler = AtomicFileHandler(self.spec_file)
|
|
95
|
-
|
|
96
|
-
# 确保项目背景文件存在
|
|
97
|
-
self._ensure_spec_exists()
|
|
98
|
-
|
|
99
|
-
def _ensure_spec_exists(self):
|
|
100
|
-
"""确保项目背景文件存在"""
|
|
101
|
-
if not self.spec_file.exists():
|
|
102
|
-
default_spec = {
|
|
103
|
-
"project_name": self.project_path.name,
|
|
104
|
-
"created_at": datetime.now().isoformat(),
|
|
105
|
-
"status": "active",
|
|
106
|
-
"tasks": {},
|
|
107
|
-
"collaboration_history": [],
|
|
108
|
-
"current_state": {
|
|
109
|
-
"active_task": None,
|
|
110
|
-
"completed_tasks": [],
|
|
111
|
-
"pending_tasks": [],
|
|
112
|
-
"assigned_tasks": {} # 活跃分配,用于防止重复认领
|
|
113
|
-
},
|
|
114
|
-
"last_updated": datetime.now().isoformat()
|
|
115
|
-
}
|
|
116
|
-
self.handler.atomic_write(default_spec)
|
|
117
|
-
|
|
118
|
-
def claim_available_task(self, agent_name):
|
|
119
|
-
"""智能体认领可用任务 - 原子性操作防止重复认领"""
|
|
120
|
-
max_retries = 5
|
|
121
|
-
|
|
122
|
-
for attempt in range(max_retries):
|
|
123
|
-
try:
|
|
124
|
-
# 读取最新状态
|
|
125
|
-
spec = self.handler.atomic_read()
|
|
126
|
-
if not spec:
|
|
127
|
-
return None, None
|
|
128
|
-
|
|
129
|
-
# 优先获取直接分配给此智能体的任务
|
|
130
|
-
for task_id, task in spec["tasks"].items():
|
|
131
|
-
if task.get("assigned_to") == agent_name and task["status"] == "pending":
|
|
132
|
-
# 尝试设置为进行中状态
|
|
133
|
-
if self._set_task_in_progress(spec, task_id, agent_name):
|
|
134
|
-
return task_id, task
|
|
135
|
-
|
|
136
|
-
# 然后获取未分配但可处理的任务
|
|
137
|
-
for task_id, task in spec["tasks"].items():
|
|
138
|
-
if (task["status"] == "pending" and
|
|
139
|
-
task.get("assigned_to") is None and
|
|
140
|
-
self._can_handle_task(task, agent_name)):
|
|
141
|
-
|
|
142
|
-
# 尝试认领此任务
|
|
143
|
-
if self._claim_task_for_agent(spec, task_id, agent_name):
|
|
144
|
-
# 记录协作日志
|
|
145
|
-
self._add_collaboration_log(
|
|
146
|
-
spec,
|
|
147
|
-
f"智能体 {agent_name} 认领任务 {task_id}: {task['description']}"
|
|
148
|
-
)
|
|
149
|
-
return task_id, task
|
|
150
|
-
|
|
151
|
-
# 没有任务可认领
|
|
152
|
-
return None, None
|
|
153
|
-
|
|
154
|
-
except Exception as e:
|
|
155
|
-
if attempt == max_retries - 1:
|
|
156
|
-
print(f"认领任务失败: {e}")
|
|
157
|
-
return None, None
|
|
158
|
-
time.sleep(0.01 * (attempt + 1))
|
|
159
|
-
|
|
160
|
-
return None, None
|
|
161
|
-
|
|
162
|
-
def _claim_task_for_agent(self, spec, task_id, agent_name):
|
|
163
|
-
"""认领任务 - 确保原子性"""
|
|
164
|
-
# 检查是否已被他人认领
|
|
165
|
-
current_task = spec["tasks"][task_id]
|
|
166
|
-
if current_task.get("assigned_to") is not None:
|
|
167
|
-
return False # 任务已被其他人认领
|
|
168
|
-
|
|
169
|
-
# 检查活跃分配列表(额外安全检查)
|
|
170
|
-
if task_id in spec["current_state"]["assigned_tasks"]:
|
|
171
|
-
return False # 任务已在活跃分配中
|
|
172
|
-
|
|
173
|
-
# 认领任务
|
|
174
|
-
spec["tasks"][task_id]["assigned_to"] = agent_name
|
|
175
|
-
spec["tasks"][task_id]["status"] = "in_progress"
|
|
176
|
-
spec["tasks"][task_id]["started_at"] = datetime.now().isoformat()
|
|
177
|
-
|
|
178
|
-
# 添加到活跃分配列表
|
|
179
|
-
spec["current_state"]["assigned_tasks"][task_id] = {
|
|
180
|
-
"claimed_by": agent_name,
|
|
181
|
-
"claimed_at": datetime.now().isoformat()
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
spec["last_updated"] = datetime.now().isoformat()
|
|
185
|
-
|
|
186
|
-
# 原子性写入
|
|
187
|
-
return self.handler.atomic_write(spec)
|
|
188
|
-
|
|
189
|
-
def _set_task_in_progress(self, spec, task_id, agent_name):
|
|
190
|
-
"""设置已分配任务为进行中状态"""
|
|
191
|
-
if spec["tasks"][task_id]["status"] == "in_progress":
|
|
192
|
-
return False # 任务已在处理中
|
|
193
|
-
|
|
194
|
-
spec["tasks"][task_id]["status"] = "in_progress"
|
|
195
|
-
spec["tasks"][task_id]["started_at"] = datetime.now().isoformat()
|
|
196
|
-
|
|
197
|
-
spec["current_state"]["active_task"] = task_id
|
|
198
|
-
spec["last_updated"] = datetime.now().isoformat()
|
|
199
|
-
|
|
200
|
-
return self.handler.atomic_write(spec)
|
|
201
|
-
|
|
202
|
-
def update_task_status(self, task_id, status, result=None, completed_by=None):
|
|
203
|
-
"""更新任务状态 - 原子性操作"""
|
|
204
|
-
max_retries = 5
|
|
205
|
-
|
|
206
|
-
for attempt in range(max_retries):
|
|
207
|
-
try:
|
|
208
|
-
spec = self.handler.atomic_read()
|
|
209
|
-
if not spec or task_id not in spec["tasks"]:
|
|
210
|
-
return False
|
|
211
|
-
|
|
212
|
-
old_status = spec["tasks"][task_id]["status"]
|
|
213
|
-
|
|
214
|
-
# 更新状态
|
|
215
|
-
spec["tasks"][task_id]["status"] = status
|
|
216
|
-
spec["tasks"][task_id]["result"] = result
|
|
217
|
-
spec["tasks"][task_id]["completed_by"] = completed_by
|
|
218
|
-
spec["tasks"][task_id]["completed_at"] = datetime.now().isoformat() if status == "completed" else None
|
|
219
|
-
|
|
220
|
-
# 更新全局状态
|
|
221
|
-
if status == "completed":
|
|
222
|
-
if task_id in spec["current_state"]["assigned_tasks"]:
|
|
223
|
-
del spec["current_state"]["assigned_tasks"][task_id]
|
|
224
|
-
spec["current_state"]["completed_tasks"].append(task_id)
|
|
225
|
-
if task_id in spec["current_state"]["pending_tasks"]:
|
|
226
|
-
spec["current_state"]["pending_tasks"].remove(task_id)
|
|
227
|
-
spec["current_state"]["active_task"] = None
|
|
228
|
-
elif status == "failed":
|
|
229
|
-
if task_id in spec["current_state"]["assigned_tasks"]:
|
|
230
|
-
del spec["current_state"]["assigned_tasks"][task_id]
|
|
231
|
-
spec["current_state"]["active_task"] = None
|
|
232
|
-
|
|
233
|
-
spec["last_updated"] = datetime.now().isoformat()
|
|
234
|
-
|
|
235
|
-
if self.handler.atomic_write(spec):
|
|
236
|
-
# 添加完成日志
|
|
237
|
-
if status == "completed":
|
|
238
|
-
self._add_collaboration_log(
|
|
239
|
-
spec,
|
|
240
|
-
f"任务 {task_id} 已由 {completed_by} 完成: {spec['tasks'][task_id]['description'][:100]}..."
|
|
241
|
-
)
|
|
242
|
-
elif status == "failed":
|
|
243
|
-
self._add_collaboration_log(
|
|
244
|
-
spec,
|
|
245
|
-
f"任务 {task_id} 执行失败: {result[:100] if result else 'Unknown error'}"
|
|
246
|
-
)
|
|
247
|
-
return True
|
|
248
|
-
else:
|
|
249
|
-
return False
|
|
250
|
-
|
|
251
|
-
except Exception as e:
|
|
252
|
-
if attempt == max_retries - 1:
|
|
253
|
-
print(f"更新任务状态失败: {e}")
|
|
254
|
-
return False
|
|
255
|
-
time.sleep(0.01 * (attempt + 1))
|
|
256
|
-
|
|
257
|
-
return False
|
|
258
|
-
|
|
259
|
-
def _can_handle_task(self, task, agent_name):
|
|
260
|
-
"""判断智能体是否能处理任务"""
|
|
261
|
-
task_desc = task["description"].lower()
|
|
262
|
-
|
|
263
|
-
# 根据智能体名称判断处理能力
|
|
264
|
-
agent_capabilities = {
|
|
265
|
-
"claude": ["analyze", "review", "explain", "logic", "reasoning", "debug"],
|
|
266
|
-
"gemini": ["translate", "document", "write", "story", "creative"],
|
|
267
|
-
"kimi": ["long", "research", "content", "analyze"],
|
|
268
|
-
"qwen": ["chinese", "中文", "translate", "chat", "dialogue"],
|
|
269
|
-
"codebuddy": ["code", "function", "program", "bug", "refactor", "optimize"],
|
|
270
|
-
"qodercli": ["generate", "create", "template", "scaffold"],
|
|
271
|
-
"iflow": ["workflow", "process", "automate", "task"],
|
|
272
|
-
"ollama": ["local", "offline", "private", "model"]
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
capabilities = agent_capabilities.get(agent_name.lower(), [])
|
|
276
|
-
return any(cap in task_desc for cap in capabilities)
|
|
277
|
-
|
|
278
|
-
def _add_collaboration_log(self, spec, message):
|
|
279
|
-
"""添加协作日志"""
|
|
280
|
-
log_entry = {
|
|
281
|
-
"timestamp": datetime.now().isoformat(),
|
|
282
|
-
"message": message,
|
|
283
|
-
"updated_at": datetime.now().isoformat()
|
|
284
|
-
}
|
|
285
|
-
spec["collaboration_history"].append(log_entry)
|
|
286
|
-
spec["last_updated"] = datetime.now().isoformat()
|
|
287
|
-
|
|
288
|
-
def create_task(self, task_type, description, assigned_to=None, priority="medium"):
|
|
289
|
-
"""创建新任务 - 确保原子性"""
|
|
290
|
-
task_id = f"{task_type}_{int(time.time())}_{len(self.handler.atomic_read()['tasks'])}"
|
|
291
|
-
|
|
292
|
-
max_retries = 5
|
|
293
|
-
for attempt in range(max_retries):
|
|
294
|
-
try:
|
|
295
|
-
spec = self.handler.atomic_read()
|
|
296
|
-
if not spec:
|
|
297
|
-
spec = {
|
|
298
|
-
"project_name": self.project_path.name,
|
|
299
|
-
"tasks": {},
|
|
300
|
-
"collaboration_history": [],
|
|
301
|
-
"current_state": {
|
|
302
|
-
"active_task": None,
|
|
303
|
-
"completed_tasks": [],
|
|
304
|
-
"pending_tasks": [],
|
|
305
|
-
"assigned_tasks": {}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
task = {
|
|
310
|
-
"id": task_id,
|
|
311
|
-
"type": task_type,
|
|
312
|
-
"description": description,
|
|
313
|
-
"assigned_to": assigned_to,
|
|
314
|
-
"status": "pending",
|
|
315
|
-
"priority": priority,
|
|
316
|
-
"created_at": datetime.now().isoformat(),
|
|
317
|
-
"result": None,
|
|
318
|
-
"completed_by": None,
|
|
319
|
-
"completed_at": None
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
spec["tasks"][task_id] = task
|
|
323
|
-
spec["current_state"]["pending_tasks"].append(task_id)
|
|
324
|
-
|
|
325
|
-
# 添加创建日志
|
|
326
|
-
self._add_collaboration_log(
|
|
327
|
-
spec,
|
|
328
|
-
f"创建任务 {task_id} ({task_type}): {description}"
|
|
329
|
-
)
|
|
330
|
-
|
|
331
|
-
if self.handler.atomic_write(spec):
|
|
332
|
-
return task_id
|
|
333
|
-
else:
|
|
334
|
-
time.sleep(0.01 * (attempt + 1))
|
|
335
|
-
|
|
336
|
-
except Exception as e:
|
|
337
|
-
if attempt == max_retries - 1:
|
|
338
|
-
print(f"创建任务失败: {e}")
|
|
339
|
-
return None
|
|
340
|
-
time.sleep(0.01 * (attempt + 1))
|
|
341
|
-
|
|
342
|
-
return None
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
class CLICollaborationAgent:
|
|
346
|
-
"""CLI协作智能体 - 基于共享背景的协作"""
|
|
347
|
-
|
|
348
|
-
def __init__(self, agent_name, project_path):
|
|
349
|
-
self.agent_name = agent_name
|
|
350
|
-
self.project_context = SharedProjectContext(project_path)
|
|
351
|
-
|
|
352
|
-
def work_on_context(self):
|
|
353
|
-
"""基于共享背景工作"""
|
|
354
|
-
# 尝试认领任务
|
|
355
|
-
task_id, task = self.project_context.claim_available_task(self.agent_name)
|
|
356
|
-
|
|
357
|
-
if not task_id:
|
|
358
|
-
return False # 没有可处理的任务
|
|
359
|
-
|
|
360
|
-
print(f"智能体 {self.agent_name} 开始处理任务 {task_id}")
|
|
361
|
-
|
|
362
|
-
# 执行任务
|
|
363
|
-
success, result = self._execute_task(task)
|
|
364
|
-
|
|
365
|
-
# 更新任务状态
|
|
366
|
-
if success:
|
|
367
|
-
self.project_context.update_task_status(task_id, "completed", result, self.agent_name)
|
|
368
|
-
print(f"智能体 {self.agent_name} 成功完成任务 {task_id}")
|
|
369
|
-
else:
|
|
370
|
-
self.project_context.update_task_status(task_id, "failed", result, self.agent_name)
|
|
371
|
-
print(f"智能体 {self.agent_name} 任务 {task_id} 执行失败")
|
|
372
|
-
|
|
373
|
-
return success
|
|
374
|
-
|
|
375
|
-
def _execute_task(self, task):
|
|
376
|
-
"""执行具体任务"""
|
|
377
|
-
# 这里实现具体的任务执行逻辑
|
|
378
|
-
# 根据任务类型调用相应的CLI工具
|
|
379
|
-
try:
|
|
380
|
-
# 这里是一个模拟执行
|
|
381
|
-
# 实际实现会根据任务类型调用对应的工具
|
|
382
|
-
import subprocess
|
|
383
|
-
result = subprocess.run(
|
|
384
|
-
["echo", f"Processed: {task['description']} by {self.agent_name}"],
|
|
385
|
-
capture_output=True,
|
|
386
|
-
text=True
|
|
387
|
-
)
|
|
388
|
-
return True, result.stdout
|
|
389
|
-
except Exception as e:
|
|
390
|
-
return False, f"执行失败: {e}"
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
def demo_concurrent_agents():
|
|
394
|
-
"""演示并发智能体协作"""
|
|
395
|
-
import threading
|
|
396
|
-
import random
|
|
397
|
-
|
|
398
|
-
# 创建项目目录
|
|
399
|
-
project_dir = Path("demo_concurrent_collaboration")
|
|
400
|
-
project_dir.mkdir(exist_ok=True)
|
|
401
|
-
|
|
402
|
-
# 创建一个共享背景管理器
|
|
403
|
-
context = SharedProjectContext(project_dir)
|
|
404
|
-
|
|
405
|
-
# 创建一些任务
|
|
406
|
-
context.create_task("coding", "编写计算器应用的加法功能", priority="high")
|
|
407
|
-
context.create_task("review", "审查登录功能的代码", priority="medium")
|
|
408
|
-
context.create_task("documentation", "为API生成使用文档", priority="low")
|
|
409
|
-
context.create_task("testing", "为订单处理系统生成单元测试", priority="high")
|
|
410
|
-
|
|
411
|
-
print("📝 创建了4个任务:")
|
|
412
|
-
spec = context.handler.atomic_read()
|
|
413
|
-
for task_id, task in spec["tasks"].items():
|
|
414
|
-
print(f" {task_id}: {task['description']} (status: {task['status']})")
|
|
415
|
-
|
|
416
|
-
# 模拟多个智能体并发工作
|
|
417
|
-
agents = ["claude", "gemini", "codebuddy", "qwen"]
|
|
418
|
-
|
|
419
|
-
def agent_worker(agent_name):
|
|
420
|
-
"""智能体工作线程"""
|
|
421
|
-
agent = CLICollaborationAgent(agent_name, project_dir)
|
|
422
|
-
|
|
423
|
-
# 工作多个轮次
|
|
424
|
-
for round_num in range(3): # 每个智能体循环工作3轮
|
|
425
|
-
success = agent.work_on_context()
|
|
426
|
-
if success:
|
|
427
|
-
time.sleep(random.uniform(0.1, 0.5)) # 随机延迟模拟工作时间
|
|
428
|
-
else:
|
|
429
|
-
# 没有任务可处理,延迟后再次尝试
|
|
430
|
-
time.sleep(0.2)
|
|
431
|
-
|
|
432
|
-
# 启动多个智能体线程
|
|
433
|
-
threads = []
|
|
434
|
-
for agent_name in agents:
|
|
435
|
-
thread = threading.Thread(target=agent_worker, args=(agent_name,))
|
|
436
|
-
thread.daemon = True
|
|
437
|
-
threads.append(thread)
|
|
438
|
-
thread.start()
|
|
439
|
-
print(f"🏃♂️ 启动智能体 {agent_name}")
|
|
440
|
-
|
|
441
|
-
# 等待所有线程完成
|
|
442
|
-
for thread in threads:
|
|
443
|
-
thread.join(timeout=10) # 10秒超时
|
|
444
|
-
|
|
445
|
-
print("\n📋 最终项目状态:")
|
|
446
|
-
final_spec = context.handler.atomic_read()
|
|
447
|
-
for task_id, task in final_spec["tasks"].items():
|
|
448
|
-
print(f" {task_id}: {task['status']} (assigned to: {task.get('assigned_to', 'none')})")
|
|
449
|
-
|
|
450
|
-
print(f" 协作历史记录: {len(final_spec['collaboration_history'])} 条")
|
|
451
|
-
|
|
452
|
-
# 清理演示目录
|
|
453
|
-
import shutil
|
|
454
|
-
shutil.rmtree(project_dir)
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
if __name__ == "__main__":
|
|
458
|
-
print("🎯 演示原子性协作机制防止任务重复认领")
|
|
459
|
-
print("="*60)
|
|
460
|
-
demo_concurrent_agents()
|
|
461
|
-
print("\n✅ 演示完成 - 并发认领已成功防範")
|