agi-framework 0.2.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.
- agents/__init__.py +19 -0
- agents/base_agent.py +311 -0
- agents/crew.py +362 -0
- agi_framework-0.2.0.dist-info/LICENSE +21 -0
- agi_framework-0.2.0.dist-info/METADATA +576 -0
- agi_framework-0.2.0.dist-info/RECORD +42 -0
- agi_framework-0.2.0.dist-info/WHEEL +5 -0
- agi_framework-0.2.0.dist-info/entry_points.txt +3 -0
- agi_framework-0.2.0.dist-info/top_level.txt +14 -0
- algorithms/__init__.py +5 -0
- algorithms/advanced_algorithms.py +328 -0
- algorithms/core_algorithms.py +329 -0
- core/__init__.py +5 -0
- core/agent_executor.py +335 -0
- core/agi_engine.py +346 -0
- core/self_improvement_engine.py +434 -0
- data/__init__.py +21 -0
- data/data_pipeline.py +360 -0
- evaluation/__init__.py +35 -0
- evaluation/benchmark_runner.py +310 -0
- evaluation/benchmarks.py +463 -0
- evaluation/metrics.py +307 -0
- experiments/__init__.py +1 -0
- experiments/eval_example.py +169 -0
- experiments/train_example.py +125 -0
- infrastructure/__init__.py +34 -0
- infrastructure/advanced_infrastructure.py +449 -0
- infrastructure/distributed_training.py +357 -0
- infrastructure/observability.py +432 -0
- memory/__init__.py +11 -0
- memory/hybrid_memory.py +352 -0
- models/__init__.py +1 -0
- reasoning/__init__.py +16 -0
- reasoning/reasoning_patterns.py +386 -0
- tests/__init__.py +1 -0
- tests/test_integration.py +366 -0
- tools/__init__.py +1 -0
- training/__init__.py +21 -0
- training/advanced_training.py +395 -0
- training/training_systems.py +336 -0
- utils/__init__.py +29 -0
- utils/helpers.py +233 -0
agents/__init__.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Agent framework modules"""
|
|
2
|
+
from base_agent import BaseAgent, SpecializedAgent, ResearcherAgent, PlannerAgent, ExecutorAgent, CriticAgent, MonitorAgent, AgentConfig, AgentMessage
|
|
3
|
+
from crew import Crew, CrewBuilder, CommunicationPattern, CrewConfig
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"BaseAgent",
|
|
7
|
+
"SpecializedAgent",
|
|
8
|
+
"ResearcherAgent",
|
|
9
|
+
"PlannerAgent",
|
|
10
|
+
"ExecutorAgent",
|
|
11
|
+
"CriticAgent",
|
|
12
|
+
"MonitorAgent",
|
|
13
|
+
"AgentConfig",
|
|
14
|
+
"AgentMessage",
|
|
15
|
+
"Crew",
|
|
16
|
+
"CrewBuilder",
|
|
17
|
+
"CommunicationPattern",
|
|
18
|
+
"CrewConfig"
|
|
19
|
+
]
|
agents/base_agent.py
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Agent Framework: Base Agent and Agent Execution
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, List, Any, Optional, Callable
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
import logging
|
|
9
|
+
import json
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class AgentConfig:
|
|
16
|
+
"""Agent configuration"""
|
|
17
|
+
name: str
|
|
18
|
+
role: str = "general"
|
|
19
|
+
reasoning_pattern: str = "cot" # cot, react, tot, got
|
|
20
|
+
memory_enabled: bool = True
|
|
21
|
+
self_improvement_enabled: bool = True
|
|
22
|
+
max_iterations: int = 10
|
|
23
|
+
timeout: int = 300 # seconds
|
|
24
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class AgentMessage:
|
|
29
|
+
"""Message in agent communication"""
|
|
30
|
+
sender: str
|
|
31
|
+
recipient: str
|
|
32
|
+
content: str
|
|
33
|
+
message_type: str = "task" # task, result, feedback, query
|
|
34
|
+
timestamp: datetime = field(default_factory=datetime.now)
|
|
35
|
+
parent_id: Optional[str] = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class BaseAgent:
|
|
39
|
+
"""Base Agent class with reasoning and memory"""
|
|
40
|
+
|
|
41
|
+
def __init__(self, config: AgentConfig):
|
|
42
|
+
self.config = config
|
|
43
|
+
self.name = config.name
|
|
44
|
+
self.role = config.role
|
|
45
|
+
self.reasoning_pattern = config.reasoning_pattern
|
|
46
|
+
|
|
47
|
+
self.memory = {}
|
|
48
|
+
self.execution_history: List[Dict[str, Any]] = []
|
|
49
|
+
self.task_queue: List[Dict[str, Any]] = []
|
|
50
|
+
self.message_history: List[AgentMessage] = []
|
|
51
|
+
|
|
52
|
+
logger.info(f"Initialized agent: {self.name} (role: {self.role})")
|
|
53
|
+
|
|
54
|
+
def process_task(self, task: Dict[str, Any]) -> Dict[str, Any]:
|
|
55
|
+
"""Process a task"""
|
|
56
|
+
logger.info(f"[{self.name}] Processing task: {task.get('description', 'Unknown')}")
|
|
57
|
+
|
|
58
|
+
execution_log = {
|
|
59
|
+
'agent': self.name,
|
|
60
|
+
'task': task,
|
|
61
|
+
'start_time': datetime.now(),
|
|
62
|
+
'steps': []
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Step 1: Reason
|
|
66
|
+
reasoning_step = {
|
|
67
|
+
'phase': 'reasoning',
|
|
68
|
+
'pattern': self.reasoning_pattern,
|
|
69
|
+
'input': task.get('input', '')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if self.reasoning_pattern == 'cot':
|
|
73
|
+
reasoning_step['output'] = f"Reasoning through: {task.get('description')}"
|
|
74
|
+
elif self.reasoning_pattern == 'react':
|
|
75
|
+
reasoning_step['output'] = f"Plan and act on: {task.get('description')}"
|
|
76
|
+
else:
|
|
77
|
+
reasoning_step['output'] = f"Analyzing: {task.get('description')}"
|
|
78
|
+
|
|
79
|
+
execution_log['steps'].append(reasoning_step)
|
|
80
|
+
|
|
81
|
+
# Step 2: Act
|
|
82
|
+
action_step = {
|
|
83
|
+
'phase': 'action',
|
|
84
|
+
'action_type': task.get('action', 'generic'),
|
|
85
|
+
'result': f"Executed {task.get('action', 'action')}"
|
|
86
|
+
}
|
|
87
|
+
execution_log['steps'].append(action_step)
|
|
88
|
+
|
|
89
|
+
# Step 3: Reflect (if enabled)
|
|
90
|
+
if self.config.self_improvement_enabled:
|
|
91
|
+
reflection_step = {
|
|
92
|
+
'phase': 'reflection',
|
|
93
|
+
'feedback': f"Task progress: {action_step['result']}"
|
|
94
|
+
}
|
|
95
|
+
execution_log['steps'].append(reflection_step)
|
|
96
|
+
|
|
97
|
+
execution_log['end_time'] = datetime.now()
|
|
98
|
+
execution_log['success'] = True
|
|
99
|
+
|
|
100
|
+
self.execution_history.append(execution_log)
|
|
101
|
+
|
|
102
|
+
result = {
|
|
103
|
+
'agent': self.name,
|
|
104
|
+
'success': True,
|
|
105
|
+
'result': action_step['result'],
|
|
106
|
+
'execution_log': execution_log
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
logger.info(f"[{self.name}] Task completed successfully")
|
|
110
|
+
return result
|
|
111
|
+
|
|
112
|
+
def send_message(self, recipient: str, content: str, message_type: str = "task") -> AgentMessage:
|
|
113
|
+
"""Send message to another agent"""
|
|
114
|
+
message = AgentMessage(
|
|
115
|
+
sender=self.name,
|
|
116
|
+
recipient=recipient,
|
|
117
|
+
content=content,
|
|
118
|
+
message_type=message_type
|
|
119
|
+
)
|
|
120
|
+
self.message_history.append(message)
|
|
121
|
+
logger.debug(f"[{self.name}] Message sent to {recipient}: {message_type}")
|
|
122
|
+
return message
|
|
123
|
+
|
|
124
|
+
def receive_message(self, message: AgentMessage):
|
|
125
|
+
"""Receive message from another agent"""
|
|
126
|
+
self.message_history.append(message)
|
|
127
|
+
logger.debug(f"[{self.name}] Message received from {message.sender}")
|
|
128
|
+
|
|
129
|
+
def get_status(self) -> Dict[str, Any]:
|
|
130
|
+
"""Get agent status"""
|
|
131
|
+
return {
|
|
132
|
+
'name': self.name,
|
|
133
|
+
'role': self.role,
|
|
134
|
+
'reasoning_pattern': self.reasoning_pattern,
|
|
135
|
+
'tasks_executed': len(self.execution_history),
|
|
136
|
+
'messages_sent': len([m for m in self.message_history if m.sender == self.name]),
|
|
137
|
+
'messages_received': len([m for m in self.message_history if m.recipient == self.name]),
|
|
138
|
+
'timestamp': datetime.now()
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class SpecializedAgent(BaseAgent):
|
|
143
|
+
"""Specialized agent with specific role"""
|
|
144
|
+
|
|
145
|
+
def __init__(self, config: AgentConfig, specialization: str):
|
|
146
|
+
super().__init__(config)
|
|
147
|
+
self.specialization = specialization
|
|
148
|
+
logger.info(f"[{self.name}] Specialized as: {specialization}")
|
|
149
|
+
|
|
150
|
+
def process_task(self, task: Dict[str, Any]) -> Dict[str, Any]:
|
|
151
|
+
"""Process task with specialization"""
|
|
152
|
+
logger.info(f"[{self.name}:{self.specialization}] Processing task")
|
|
153
|
+
|
|
154
|
+
# Add specialization context
|
|
155
|
+
task_with_spec = {**task, 'specialization_context': self.specialization}
|
|
156
|
+
|
|
157
|
+
result = super().process_task(task_with_spec)
|
|
158
|
+
result['specialization'] = self.specialization
|
|
159
|
+
|
|
160
|
+
return result
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class ResearcherAgent(SpecializedAgent):
|
|
164
|
+
"""Agent specialized in research"""
|
|
165
|
+
|
|
166
|
+
def __init__(self, name: str = "Researcher"):
|
|
167
|
+
config = AgentConfig(
|
|
168
|
+
name=name,
|
|
169
|
+
role="research",
|
|
170
|
+
reasoning_pattern="cot"
|
|
171
|
+
)
|
|
172
|
+
super().__init__(config, "research")
|
|
173
|
+
|
|
174
|
+
def research(self, topic: str) -> Dict[str, Any]:
|
|
175
|
+
"""Conduct research on a topic"""
|
|
176
|
+
task = {
|
|
177
|
+
'description': f'Research topic: {topic}',
|
|
178
|
+
'action': 'research',
|
|
179
|
+
'input': topic
|
|
180
|
+
}
|
|
181
|
+
return self.process_task(task)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class PlannerAgent(SpecializedAgent):
|
|
185
|
+
"""Agent specialized in planning"""
|
|
186
|
+
|
|
187
|
+
def __init__(self, name: str = "Planner"):
|
|
188
|
+
config = AgentConfig(
|
|
189
|
+
name=name,
|
|
190
|
+
role="planning",
|
|
191
|
+
reasoning_pattern="tot"
|
|
192
|
+
)
|
|
193
|
+
super().__init__(config, "planning")
|
|
194
|
+
|
|
195
|
+
def plan(self, objective: str) -> Dict[str, Any]:
|
|
196
|
+
"""Create a plan"""
|
|
197
|
+
task = {
|
|
198
|
+
'description': f'Create plan for: {objective}',
|
|
199
|
+
'action': 'plan',
|
|
200
|
+
'input': objective
|
|
201
|
+
}
|
|
202
|
+
return self.process_task(task)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class ExecutorAgent(SpecializedAgent):
|
|
206
|
+
"""Agent specialized in execution"""
|
|
207
|
+
|
|
208
|
+
def __init__(self, name: str = "Executor"):
|
|
209
|
+
config = AgentConfig(
|
|
210
|
+
name=name,
|
|
211
|
+
role="execution",
|
|
212
|
+
reasoning_pattern="react"
|
|
213
|
+
)
|
|
214
|
+
super().__init__(config, "execution")
|
|
215
|
+
|
|
216
|
+
def execute(self, plan: str) -> Dict[str, Any]:
|
|
217
|
+
"""Execute a plan"""
|
|
218
|
+
task = {
|
|
219
|
+
'description': f'Execute plan: {plan}',
|
|
220
|
+
'action': 'execute',
|
|
221
|
+
'input': plan
|
|
222
|
+
}
|
|
223
|
+
return self.process_task(task)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
class CriticAgent(SpecializedAgent):
|
|
227
|
+
"""Agent specialized in critique and feedback"""
|
|
228
|
+
|
|
229
|
+
def __init__(self, name: str = "Critic"):
|
|
230
|
+
config = AgentConfig(
|
|
231
|
+
name=name,
|
|
232
|
+
role="critique",
|
|
233
|
+
reasoning_pattern="cot"
|
|
234
|
+
)
|
|
235
|
+
super().__init__(config, "critique")
|
|
236
|
+
|
|
237
|
+
def critique(self, work: str) -> Dict[str, Any]:
|
|
238
|
+
"""Critique work"""
|
|
239
|
+
task = {
|
|
240
|
+
'description': f'Critique: {work}',
|
|
241
|
+
'action': 'critique',
|
|
242
|
+
'input': work
|
|
243
|
+
}
|
|
244
|
+
result = self.process_task(task)
|
|
245
|
+
|
|
246
|
+
# Add critique feedback
|
|
247
|
+
result['critique_feedback'] = {
|
|
248
|
+
'strengths': ['Well-structured', 'Clear reasoning'],
|
|
249
|
+
'weaknesses': ['Could be more detailed'],
|
|
250
|
+
'suggestions': ['Add more context', 'Consider edge cases']
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return result
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class MonitorAgent(SpecializedAgent):
|
|
257
|
+
"""Agent specialized in monitoring and oversight"""
|
|
258
|
+
|
|
259
|
+
def __init__(self, name: str = "Monitor"):
|
|
260
|
+
config = AgentConfig(
|
|
261
|
+
name=name,
|
|
262
|
+
role="monitoring",
|
|
263
|
+
reasoning_pattern="cot"
|
|
264
|
+
)
|
|
265
|
+
super().__init__(config, "monitoring")
|
|
266
|
+
|
|
267
|
+
def monitor(self, agents: List[BaseAgent]) -> Dict[str, Any]:
|
|
268
|
+
"""Monitor team of agents"""
|
|
269
|
+
monitoring_report = {
|
|
270
|
+
'timestamp': datetime.now(),
|
|
271
|
+
'agents_monitored': len(agents),
|
|
272
|
+
'agent_statuses': []
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
for agent in agents:
|
|
276
|
+
status = agent.get_status()
|
|
277
|
+
monitoring_report['agent_statuses'].append(status)
|
|
278
|
+
|
|
279
|
+
return monitoring_report
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
if __name__ == "__main__":
|
|
283
|
+
# Example: Create different agents
|
|
284
|
+
researcher = ResearcherAgent("Dr. Smith")
|
|
285
|
+
planner = PlannerAgent("Strategic Planner")
|
|
286
|
+
executor = ExecutorAgent("Action Taker")
|
|
287
|
+
critic = CriticAgent("Quality Assurance")
|
|
288
|
+
|
|
289
|
+
print("=== Agent Communication Example ===\n")
|
|
290
|
+
|
|
291
|
+
# Research phase
|
|
292
|
+
research_result = researcher.research("Advanced AI techniques")
|
|
293
|
+
print(f"[Research] {researcher.name}: {research_result['result']}")
|
|
294
|
+
|
|
295
|
+
# Planning phase
|
|
296
|
+
plan_result = planner.plan(research_result['result'])
|
|
297
|
+
print(f"[Planning] {planner.name}: {plan_result['result']}")
|
|
298
|
+
|
|
299
|
+
# Execution phase
|
|
300
|
+
exec_result = executor.execute(plan_result['result'])
|
|
301
|
+
print(f"[Execution] {executor.name}: {exec_result['result']}")
|
|
302
|
+
|
|
303
|
+
# Critique phase
|
|
304
|
+
critique_result = critic.critique(exec_result['result'])
|
|
305
|
+
print(f"[Critique] {critic.name}: {critique_result['result']}")
|
|
306
|
+
|
|
307
|
+
# Get statuses
|
|
308
|
+
print("\n=== Agent Statuses ===")
|
|
309
|
+
for agent in [researcher, planner, executor, critic]:
|
|
310
|
+
status = agent.get_status()
|
|
311
|
+
print(f"{agent.name}: executed {status['tasks_executed']} tasks")
|
agents/crew.py
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Multi-Agent Crew Orchestration
|
|
3
|
+
Supervisor-based team coordination
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Dict, List, Any, Optional
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from enum import Enum
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
import logging
|
|
11
|
+
import json
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CommunicationPattern(Enum):
|
|
17
|
+
"""Communication patterns for agent cooperation"""
|
|
18
|
+
SEQUENTIAL = "sequential"
|
|
19
|
+
PARALLEL = "parallel"
|
|
20
|
+
HIERARCHICAL = "hierarchical"
|
|
21
|
+
DEBATE = "debate" # Multi-agent critique
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class CrewConfig:
|
|
26
|
+
"""Configuration for agent crew"""
|
|
27
|
+
name: str
|
|
28
|
+
communication_pattern: CommunicationPattern = CommunicationPattern.HIERARCHICAL
|
|
29
|
+
max_iterations: int = 3
|
|
30
|
+
enable_reflection: bool = True
|
|
31
|
+
enable_tool_sharing: bool = True
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Crew:
|
|
35
|
+
"""Team of cooperative agents supervised by a central controller"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, config: CrewConfig):
|
|
38
|
+
self.config = config
|
|
39
|
+
self.name = config.name
|
|
40
|
+
self.agents: Dict[str, Any] = {}
|
|
41
|
+
self.supervisor = None
|
|
42
|
+
self.message_queue: List[Dict[str, Any]] = []
|
|
43
|
+
self.execution_log: List[Dict[str, Any]] = []
|
|
44
|
+
self.state: Dict[str, Any] = {}
|
|
45
|
+
|
|
46
|
+
logger.info(f"Initialized Crew: {self.name} (pattern: {config.communication_pattern.value})")
|
|
47
|
+
|
|
48
|
+
def add_agent(self, agent_name: str, agent: Any, role: Optional[str] = None):
|
|
49
|
+
"""Add agent to crew"""
|
|
50
|
+
self.agents[agent_name] = {
|
|
51
|
+
'agent': agent,
|
|
52
|
+
'role': role or agent.role,
|
|
53
|
+
'status': 'idle',
|
|
54
|
+
'assigned_tasks': []
|
|
55
|
+
}
|
|
56
|
+
logger.info(f"Added agent: {agent_name} (role: {role})")
|
|
57
|
+
|
|
58
|
+
def set_supervisor(self, supervisor_agent: Any):
|
|
59
|
+
"""Set supervisor agent"""
|
|
60
|
+
self.supervisor = supervisor_agent
|
|
61
|
+
logger.info(f"Supervisor set: {supervisor_agent.name}")
|
|
62
|
+
|
|
63
|
+
def execute_task(self, task: Dict[str, Any]) -> Dict[str, Any]:
|
|
64
|
+
"""Execute task with crew"""
|
|
65
|
+
logger.info(f"[Crew:{self.name}] Executing task: {task.get('description', 'Unknown')}")
|
|
66
|
+
|
|
67
|
+
execution = {
|
|
68
|
+
'task': task,
|
|
69
|
+
'start_time': datetime.now(),
|
|
70
|
+
'crew_name': self.name,
|
|
71
|
+
'communication_pattern': self.config.communication_pattern.value,
|
|
72
|
+
'phases': []
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if self.config.communication_pattern == CommunicationPattern.SEQUENTIAL:
|
|
76
|
+
execution['phases'] = self._execute_sequential(task)
|
|
77
|
+
|
|
78
|
+
elif self.config.communication_pattern == CommunicationPattern.HIERARCHICAL:
|
|
79
|
+
execution['phases'] = self._execute_hierarchical(task)
|
|
80
|
+
|
|
81
|
+
elif self.config.communication_pattern == CommunicationPattern.PARALLEL:
|
|
82
|
+
execution['phases'] = self._execute_parallel(task)
|
|
83
|
+
|
|
84
|
+
elif self.config.communication_pattern == CommunicationPattern.DEBATE:
|
|
85
|
+
execution['phases'] = self._execute_debate(task)
|
|
86
|
+
|
|
87
|
+
execution['end_time'] = datetime.now()
|
|
88
|
+
execution['success'] = True
|
|
89
|
+
|
|
90
|
+
self.execution_log.append(execution)
|
|
91
|
+
logger.info(f"[Crew:{self.name}] Task completed")
|
|
92
|
+
|
|
93
|
+
return execution
|
|
94
|
+
|
|
95
|
+
def _execute_sequential(self, task: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
96
|
+
"""Execute sequentially: each agent passes result to next"""
|
|
97
|
+
phases = []
|
|
98
|
+
current_input = task.get('input', '')
|
|
99
|
+
|
|
100
|
+
for agent_name, agent_info in self.agents.items():
|
|
101
|
+
phase = {
|
|
102
|
+
'agent': agent_name,
|
|
103
|
+
'role': agent_info['role'],
|
|
104
|
+
'input': current_input,
|
|
105
|
+
'position': len(phases)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# Simulate execution
|
|
109
|
+
result = f"Output from {agent_name} on: {current_input[:30]}"
|
|
110
|
+
phase['output'] = result
|
|
111
|
+
phase['success'] = True
|
|
112
|
+
|
|
113
|
+
phases.append(phase)
|
|
114
|
+
current_input = result # Chain result to next agent
|
|
115
|
+
|
|
116
|
+
logger.debug(f"Sequential phase: {agent_name} completed")
|
|
117
|
+
|
|
118
|
+
return phases
|
|
119
|
+
|
|
120
|
+
def _execute_hierarchical(self, task: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
121
|
+
"""Execute hierarchically: supervisor delegates to agents"""
|
|
122
|
+
phases = []
|
|
123
|
+
|
|
124
|
+
if not self.supervisor:
|
|
125
|
+
logger.warning("No supervisor available for hierarchical execution")
|
|
126
|
+
return phases
|
|
127
|
+
|
|
128
|
+
# Phase 1: Supervisor analysis
|
|
129
|
+
supervisor_phase = {
|
|
130
|
+
'agent': self.supervisor.name,
|
|
131
|
+
'phase_type': 'analysis',
|
|
132
|
+
'action': 'Analyze task and create plan'
|
|
133
|
+
}
|
|
134
|
+
phases.append(supervisor_phase)
|
|
135
|
+
|
|
136
|
+
# Phase 2: Distribute to agents
|
|
137
|
+
num_agents = len(self.agents)
|
|
138
|
+
for idx, (agent_name, agent_info) in enumerate(self.agents.items()):
|
|
139
|
+
agent_phase = {
|
|
140
|
+
'agent': agent_name,
|
|
141
|
+
'role': agent_info['role'],
|
|
142
|
+
'phase_type': 'execution',
|
|
143
|
+
'subtask': f"Subtask {idx+1}/{num_agents}",
|
|
144
|
+
'result': f"Completed by {agent_name}"
|
|
145
|
+
}
|
|
146
|
+
phases.append(agent_phase)
|
|
147
|
+
logger.debug(f"Hierarchical delegation: {agent_name}")
|
|
148
|
+
|
|
149
|
+
# Phase 3: Supervisor synthesis
|
|
150
|
+
synthesis_phase = {
|
|
151
|
+
'agent': self.supervisor.name,
|
|
152
|
+
'phase_type': 'synthesis',
|
|
153
|
+
'action': 'Aggregate results and finalize'
|
|
154
|
+
}
|
|
155
|
+
phases.append(synthesis_phase)
|
|
156
|
+
|
|
157
|
+
return phases
|
|
158
|
+
|
|
159
|
+
def _execute_parallel(self, task: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
160
|
+
"""Execute in parallel: all agents work independently"""
|
|
161
|
+
phases = []
|
|
162
|
+
|
|
163
|
+
parallel_phase = {
|
|
164
|
+
'type': 'parallel_execution',
|
|
165
|
+
'agents': [],
|
|
166
|
+
'start_time': datetime.now()
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
for agent_name, agent_info in self.agents.items():
|
|
170
|
+
agent_task = {
|
|
171
|
+
'agent': agent_name,
|
|
172
|
+
'role': agent_info['role'],
|
|
173
|
+
'assigned_task': f"{agent_name}'s subtask"
|
|
174
|
+
}
|
|
175
|
+
parallel_phase['agents'].append(agent_task)
|
|
176
|
+
logger.debug(f"Parallel task: {agent_name}")
|
|
177
|
+
|
|
178
|
+
parallel_phase['end_time'] = datetime.now()
|
|
179
|
+
phases.append(parallel_phase)
|
|
180
|
+
|
|
181
|
+
return phases
|
|
182
|
+
|
|
183
|
+
def _execute_debate(self, task: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
184
|
+
"""Execute with debate: agents critique each other's outputs"""
|
|
185
|
+
phases = []
|
|
186
|
+
|
|
187
|
+
# Round 1: Initial proposals
|
|
188
|
+
round1 = {
|
|
189
|
+
'round': 1,
|
|
190
|
+
'type': 'initial_proposals',
|
|
191
|
+
'proposals': []
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
for agent_name, agent_info in self.agents.items():
|
|
195
|
+
proposal = {
|
|
196
|
+
'agent': agent_name,
|
|
197
|
+
'proposal': f"Proposal from {agent_name}",
|
|
198
|
+
'confidence': 0.6 + (len(round1['proposals']) * 0.1)
|
|
199
|
+
}
|
|
200
|
+
round1['proposals'].append(proposal)
|
|
201
|
+
|
|
202
|
+
phases.append(round1)
|
|
203
|
+
|
|
204
|
+
# Round 2: Critique
|
|
205
|
+
round2 = {
|
|
206
|
+
'round': 2,
|
|
207
|
+
'type': 'critique',
|
|
208
|
+
'critiques': []
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
for i, proposal in enumerate(round1['proposals']):
|
|
212
|
+
critique = {
|
|
213
|
+
'proposal_author': proposal['agent'],
|
|
214
|
+
'critique_by': list(self.agents.keys())[(i+1) % len(self.agents)],
|
|
215
|
+
'feedback': f"Feedback on {proposal['agent']}'s proposal"
|
|
216
|
+
}
|
|
217
|
+
round2['critiques'].append(critique)
|
|
218
|
+
|
|
219
|
+
phases.append(round2)
|
|
220
|
+
|
|
221
|
+
# Round 3: Final agreement
|
|
222
|
+
round3 = {
|
|
223
|
+
'round': 3,
|
|
224
|
+
'type': 'agreement',
|
|
225
|
+
'consensus': f"Consensus reached after debate"
|
|
226
|
+
}
|
|
227
|
+
phases.append(round3)
|
|
228
|
+
|
|
229
|
+
logger.debug("Debate execution completed")
|
|
230
|
+
return phases
|
|
231
|
+
|
|
232
|
+
def get_crew_status(self) -> Dict[str, Any]:
|
|
233
|
+
"""Get overall crew status"""
|
|
234
|
+
status = {
|
|
235
|
+
'crew_name': self.name,
|
|
236
|
+
'num_agents': len(self.agents),
|
|
237
|
+
'communication_pattern': self.config.communication_pattern.value,
|
|
238
|
+
'agents': {},
|
|
239
|
+
'total_tasks_executed': len(self.execution_log),
|
|
240
|
+
'has_supervisor': self.supervisor is not None,
|
|
241
|
+
'timestamp': datetime.now()
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
for agent_name, agent_info in self.agents.items():
|
|
245
|
+
status['agents'][agent_name] = {
|
|
246
|
+
'role': agent_info['role'],
|
|
247
|
+
'status': agent_info['status'],
|
|
248
|
+
'tasks_assigned': len(agent_info['assigned_tasks'])
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return status
|
|
252
|
+
|
|
253
|
+
def save_execution_log(self, filepath: str):
|
|
254
|
+
"""Save crew execution log"""
|
|
255
|
+
with open(filepath, 'w') as f:
|
|
256
|
+
json.dump(self.execution_log, f, indent=2, default=str)
|
|
257
|
+
logger.info(f"Execution log saved to {filepath}")
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class CrewBuilder:
|
|
261
|
+
"""Builder for constructing crews"""
|
|
262
|
+
|
|
263
|
+
def __init__(self, crew_name: str, pattern: CommunicationPattern = CommunicationPattern.HIERARCHICAL):
|
|
264
|
+
self.config = CrewConfig(
|
|
265
|
+
name=crew_name,
|
|
266
|
+
communication_pattern=pattern
|
|
267
|
+
)
|
|
268
|
+
self.agents_to_add: List[tuple] = []
|
|
269
|
+
self.supervisor_agent = None
|
|
270
|
+
|
|
271
|
+
def add_agent(self, agent: Any, role: Optional[str] = None):
|
|
272
|
+
"""Add agent to builder"""
|
|
273
|
+
self.agents_to_add.append((agent.name, agent, role))
|
|
274
|
+
return self
|
|
275
|
+
|
|
276
|
+
def set_supervisor(self, supervisor_agent: Any):
|
|
277
|
+
"""Set supervisor"""
|
|
278
|
+
self.supervisor_agent = supervisor_agent
|
|
279
|
+
return self
|
|
280
|
+
|
|
281
|
+
def build(self) -> Crew:
|
|
282
|
+
"""Build crew"""
|
|
283
|
+
crew = Crew(self.config)
|
|
284
|
+
|
|
285
|
+
for agent_name, agent, role in self.agents_to_add:
|
|
286
|
+
crew.add_agent(agent_name, agent, role)
|
|
287
|
+
|
|
288
|
+
if self.supervisor_agent:
|
|
289
|
+
crew.set_supervisor(self.supervisor_agent)
|
|
290
|
+
|
|
291
|
+
logger.info(f"Crew built: {self.config.name} with {len(self.agents_to_add)} agents")
|
|
292
|
+
return crew
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
# Example crew configurations
|
|
296
|
+
def create_research_crew() -> Crew:
|
|
297
|
+
"""Create a research crew"""
|
|
298
|
+
from agents.base_agent import ResearcherAgent, CriticAgent, PlannerAgent
|
|
299
|
+
|
|
300
|
+
builder = CrewBuilder(
|
|
301
|
+
"Research Team",
|
|
302
|
+
CommunicationPattern.HIERARCHICAL
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
researcher = ResearcherAgent("Senior Researcher")
|
|
306
|
+
critic = CriticAgent("Quality Advisor")
|
|
307
|
+
planner = PlannerAgent("Research Planner")
|
|
308
|
+
|
|
309
|
+
builder.add_agent(researcher, "research")
|
|
310
|
+
builder.add_agent(planner, "planning")
|
|
311
|
+
builder.add_agent(critic, "critique")
|
|
312
|
+
builder.set_supervisor(planner)
|
|
313
|
+
|
|
314
|
+
return builder.build()
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def create_execution_crew() -> Crew:
|
|
318
|
+
"""Create an execution crew"""
|
|
319
|
+
from agents.base_agent import PlannerAgent, ExecutorAgent, MonitorAgent
|
|
320
|
+
|
|
321
|
+
builder = CrewBuilder(
|
|
322
|
+
"Execution Team",
|
|
323
|
+
CommunicationPattern.SEQUENTIAL
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
planner = PlannerAgent("Execution Planner")
|
|
327
|
+
executor = ExecutorAgent("Task Executor")
|
|
328
|
+
monitor = MonitorAgent("Execution Monitor")
|
|
329
|
+
|
|
330
|
+
builder.add_agent(planner, "planning")
|
|
331
|
+
builder.add_agent(executor, "execution")
|
|
332
|
+
builder.add_agent(monitor, "monitoring")
|
|
333
|
+
builder.set_supervisor(planner)
|
|
334
|
+
|
|
335
|
+
return builder.build()
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
if __name__ == "__main__":
|
|
339
|
+
# Test different crew patterns
|
|
340
|
+
print("=== Hierarchical Crew ===")
|
|
341
|
+
|
|
342
|
+
from agents.base_agent import ResearcherAgent, PlannerAgent, ExecutorAgent, CriticAgent
|
|
343
|
+
|
|
344
|
+
builder = CrewBuilder("Test Crew", CommunicationPattern.HIERARCHICAL)
|
|
345
|
+
builder.add_agent(ResearcherAgent("R1"), "research")
|
|
346
|
+
builder.add_agent(PlannerAgent("P1"), "planning")
|
|
347
|
+
builder.add_agent(ExecutorAgent("E1"), "execution")
|
|
348
|
+
builder.add_agent(CriticAgent("C1"), "critique")
|
|
349
|
+
|
|
350
|
+
supervisor = PlannerAgent("Supervisor")
|
|
351
|
+
builder.set_supervisor(supervisor)
|
|
352
|
+
|
|
353
|
+
crew = builder.build()
|
|
354
|
+
|
|
355
|
+
task = {
|
|
356
|
+
'description': 'Solve complex problem',
|
|
357
|
+
'input': 'Given problem statement'
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
result = crew.execute_task(task)
|
|
361
|
+
print(f"Crew Status: {crew.get_crew_status()['num_agents']} agents")
|
|
362
|
+
print(f"Execution Phases: {len(result['phases'])} phases")
|