massgen 0.0.3__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 massgen might be problematic. Click here for more details.
- massgen/__init__.py +94 -0
- massgen/agent_config.py +507 -0
- massgen/backend/CLAUDE_API_RESEARCH.md +266 -0
- massgen/backend/Function calling openai responses.md +1161 -0
- massgen/backend/GEMINI_API_DOCUMENTATION.md +410 -0
- massgen/backend/OPENAI_RESPONSES_API_FORMAT.md +65 -0
- massgen/backend/__init__.py +25 -0
- massgen/backend/base.py +180 -0
- massgen/backend/chat_completions.py +228 -0
- massgen/backend/claude.py +661 -0
- massgen/backend/gemini.py +652 -0
- massgen/backend/grok.py +187 -0
- massgen/backend/response.py +397 -0
- massgen/chat_agent.py +440 -0
- massgen/cli.py +686 -0
- massgen/configs/README.md +293 -0
- massgen/configs/creative_team.yaml +53 -0
- massgen/configs/gemini_4o_claude.yaml +31 -0
- massgen/configs/news_analysis.yaml +51 -0
- massgen/configs/research_team.yaml +51 -0
- massgen/configs/single_agent.yaml +18 -0
- massgen/configs/single_flash2.5.yaml +44 -0
- massgen/configs/technical_analysis.yaml +51 -0
- massgen/configs/three_agents_default.yaml +31 -0
- massgen/configs/travel_planning.yaml +51 -0
- massgen/configs/two_agents.yaml +39 -0
- massgen/frontend/__init__.py +20 -0
- massgen/frontend/coordination_ui.py +945 -0
- massgen/frontend/displays/__init__.py +24 -0
- massgen/frontend/displays/base_display.py +83 -0
- massgen/frontend/displays/rich_terminal_display.py +3497 -0
- massgen/frontend/displays/simple_display.py +93 -0
- massgen/frontend/displays/terminal_display.py +381 -0
- massgen/frontend/logging/__init__.py +9 -0
- massgen/frontend/logging/realtime_logger.py +197 -0
- massgen/message_templates.py +431 -0
- massgen/orchestrator.py +1222 -0
- massgen/tests/__init__.py +10 -0
- massgen/tests/multi_turn_conversation_design.md +214 -0
- massgen/tests/multiturn_llm_input_analysis.md +189 -0
- massgen/tests/test_case_studies.md +113 -0
- massgen/tests/test_claude_backend.py +310 -0
- massgen/tests/test_grok_backend.py +160 -0
- massgen/tests/test_message_context_building.py +293 -0
- massgen/tests/test_rich_terminal_display.py +378 -0
- massgen/tests/test_v3_3agents.py +117 -0
- massgen/tests/test_v3_simple.py +216 -0
- massgen/tests/test_v3_three_agents.py +272 -0
- massgen/tests/test_v3_two_agents.py +176 -0
- massgen/utils.py +79 -0
- massgen/v1/README.md +330 -0
- massgen/v1/__init__.py +91 -0
- massgen/v1/agent.py +605 -0
- massgen/v1/agents.py +330 -0
- massgen/v1/backends/gemini.py +584 -0
- massgen/v1/backends/grok.py +410 -0
- massgen/v1/backends/oai.py +571 -0
- massgen/v1/cli.py +351 -0
- massgen/v1/config.py +169 -0
- massgen/v1/examples/fast-4o-mini-config.yaml +44 -0
- massgen/v1/examples/fast_config.yaml +44 -0
- massgen/v1/examples/production.yaml +70 -0
- massgen/v1/examples/single_agent.yaml +39 -0
- massgen/v1/logging.py +974 -0
- massgen/v1/main.py +368 -0
- massgen/v1/orchestrator.py +1138 -0
- massgen/v1/streaming_display.py +1190 -0
- massgen/v1/tools.py +160 -0
- massgen/v1/types.py +245 -0
- massgen/v1/utils.py +199 -0
- massgen-0.0.3.dist-info/METADATA +568 -0
- massgen-0.0.3.dist-info/RECORD +76 -0
- massgen-0.0.3.dist-info/WHEEL +5 -0
- massgen-0.0.3.dist-info/entry_points.txt +2 -0
- massgen-0.0.3.dist-info/licenses/LICENSE +204 -0
- massgen-0.0.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
MassGen Example: Three Agent Coordination
|
|
4
|
+
|
|
5
|
+
This example demonstrates three-agent coordination using the
|
|
6
|
+
multi-region coordination UI. Three agents with different specialties work
|
|
7
|
+
together on a question that benefits from multiple perspectives.
|
|
8
|
+
|
|
9
|
+
Features:
|
|
10
|
+
- Three agents with distinct specialties
|
|
11
|
+
- Multi-region terminal display
|
|
12
|
+
- Real coordination with voting and consensus
|
|
13
|
+
- Cost-effective with gpt-4o-mini model
|
|
14
|
+
|
|
15
|
+
Note: Requires OPENAI_API_KEY in environment.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import asyncio
|
|
19
|
+
import sys
|
|
20
|
+
import os
|
|
21
|
+
|
|
22
|
+
# Add project root to path
|
|
23
|
+
project_root = os.path.dirname(__file__)
|
|
24
|
+
sys.path.insert(0, project_root)
|
|
25
|
+
|
|
26
|
+
from massgen import create_simple_agent, ResponseBackend, Orchestrator
|
|
27
|
+
from massgen.frontend.coordination_ui import coordinate_with_terminal_ui
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
async def three_agent_example():
|
|
31
|
+
"""Demonstrate three agent coordination with multi-region UI."""
|
|
32
|
+
|
|
33
|
+
print("šÆ MassGen: Three Agent Coordination")
|
|
34
|
+
print("=" * 50)
|
|
35
|
+
|
|
36
|
+
# Check API key
|
|
37
|
+
if not os.getenv("OPENAI_API_KEY"):
|
|
38
|
+
print("ā OPENAI_API_KEY not found")
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
print("ā
OpenAI API key found")
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
# Create backend
|
|
45
|
+
backend = ResponseBackend(model="gpt-4o-mini")
|
|
46
|
+
print("ā
OpenAI backend created")
|
|
47
|
+
|
|
48
|
+
# Create three agents with different specialties
|
|
49
|
+
scientist = create_simple_agent(
|
|
50
|
+
backend=backend,
|
|
51
|
+
system_message="You are a scientist who focuses on scientific accuracy and evidence-based explanations.",
|
|
52
|
+
)
|
|
53
|
+
engineer = create_simple_agent(
|
|
54
|
+
backend=backend,
|
|
55
|
+
system_message="You are an engineer who focuses on practical applications and real-world implementation.",
|
|
56
|
+
)
|
|
57
|
+
educator = create_simple_agent(
|
|
58
|
+
backend=backend,
|
|
59
|
+
system_message="You are an educator who focuses on clear, accessible explanations for learning.",
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
print("ā
Created 3 agents:")
|
|
63
|
+
print(" ⢠scientist: Scientific accuracy")
|
|
64
|
+
print(" ⢠engineer: Practical applications")
|
|
65
|
+
print(" ⢠educator: Clear explanations")
|
|
66
|
+
|
|
67
|
+
# Create orchestrator
|
|
68
|
+
orchestrator = Orchestrator(
|
|
69
|
+
agents={"scientist": scientist, "engineer": engineer, "educator": educator}
|
|
70
|
+
)
|
|
71
|
+
print("ā
orchestrator ready")
|
|
72
|
+
|
|
73
|
+
# Question that benefits from multiple perspectives
|
|
74
|
+
question = "How does solar energy work and why is it important?"
|
|
75
|
+
print(f"\nš¬ Question: {question}")
|
|
76
|
+
print("š Starting three-agent coordination...\n")
|
|
77
|
+
|
|
78
|
+
# Use coordination UI
|
|
79
|
+
result = await coordinate_with_terminal_ui(
|
|
80
|
+
orchestrator,
|
|
81
|
+
question,
|
|
82
|
+
enable_final_presentation=True,
|
|
83
|
+
logging_enabled=False,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
print(f"\nā
Three agent coordination completed!")
|
|
87
|
+
|
|
88
|
+
# Show results
|
|
89
|
+
orchestrator_status = orchestrator.get_status()
|
|
90
|
+
selected_agent = orchestrator_status.get("selected_agent")
|
|
91
|
+
vote_results = orchestrator_status.get("vote_results", {})
|
|
92
|
+
|
|
93
|
+
print(f"\nš Results:")
|
|
94
|
+
print(f"š Selected agent: {selected_agent}")
|
|
95
|
+
if vote_results.get("vote_counts"):
|
|
96
|
+
for agent, votes in vote_results["vote_counts"].items():
|
|
97
|
+
print(f"š³ļø {agent}: {votes} vote(s)")
|
|
98
|
+
|
|
99
|
+
return result
|
|
100
|
+
|
|
101
|
+
except Exception as e:
|
|
102
|
+
print(f"ā Failed: {e}")
|
|
103
|
+
import traceback
|
|
104
|
+
|
|
105
|
+
traceback.print_exc()
|
|
106
|
+
return None
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
if __name__ == "__main__":
|
|
110
|
+
result = asyncio.run(three_agent_example())
|
|
111
|
+
if result:
|
|
112
|
+
print("\nš Three agent coordination successful!")
|
|
113
|
+
print("š” Demonstrated multi-agent collaboration with diverse expertise")
|
|
114
|
+
else:
|
|
115
|
+
print("\nā ļø Check error above")
|
|
116
|
+
|
|
117
|
+
print("\nš Three agent example completed!")
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Simple test script for MassGen basic functionality.
|
|
4
|
+
Tests single agent and basic orchestrator functionality.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
# Add project root to path
|
|
13
|
+
project_root = Path(__file__).parent.parent.parent.parent
|
|
14
|
+
sys.path.insert(0, str(project_root))
|
|
15
|
+
|
|
16
|
+
from massgen.backend.response import ResponseBackend
|
|
17
|
+
from massgen.chat_agent import SingleAgent
|
|
18
|
+
from massgen.orchestrator import Orchestrator
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
async def test_single_agent():
|
|
22
|
+
"""Test basic SingleAgent functionality."""
|
|
23
|
+
print("š§Ŗ Testing SingleAgent Basic Functionality")
|
|
24
|
+
print("-" * 50)
|
|
25
|
+
|
|
26
|
+
api_key = os.getenv("OPENAI_API_KEY")
|
|
27
|
+
if not api_key:
|
|
28
|
+
print("ā OPENAI_API_KEY not found - skipping single agent test")
|
|
29
|
+
return False
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
backend = ResponseBackend(api_key=api_key)
|
|
33
|
+
agent = SingleAgent(
|
|
34
|
+
backend=backend,
|
|
35
|
+
agent_id="test_agent",
|
|
36
|
+
system_message="You are a helpful assistant. Provide brief, accurate answers.",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
print("š¤ Testing single agent response...")
|
|
40
|
+
|
|
41
|
+
messages = [{"role": "user", "content": "What is 2+2?"}]
|
|
42
|
+
response_content = ""
|
|
43
|
+
|
|
44
|
+
async for chunk in agent.chat(messages):
|
|
45
|
+
if chunk.type == "content" and chunk.content:
|
|
46
|
+
response_content += chunk.content
|
|
47
|
+
print(chunk.content, end="", flush=True)
|
|
48
|
+
elif chunk.type == "error":
|
|
49
|
+
print(f"\nā Error: {chunk.error}")
|
|
50
|
+
return False
|
|
51
|
+
elif chunk.type == "done":
|
|
52
|
+
break
|
|
53
|
+
|
|
54
|
+
print(
|
|
55
|
+
f"\nā
Single agent test completed. Response: '{response_content.strip()}'"
|
|
56
|
+
)
|
|
57
|
+
return True
|
|
58
|
+
|
|
59
|
+
except Exception as e:
|
|
60
|
+
print(f"ā Single agent test failed: {e}")
|
|
61
|
+
return False
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
async def test_orchestrator_single():
|
|
65
|
+
"""Test orchestrator with single agent."""
|
|
66
|
+
print("\nš§Ŗ Testing Orchestrator with Single Agent")
|
|
67
|
+
print("-" * 50)
|
|
68
|
+
|
|
69
|
+
api_key = os.getenv("OPENAI_API_KEY")
|
|
70
|
+
if not api_key:
|
|
71
|
+
print("ā OPENAI_API_KEY not found - skipping orchestrator test")
|
|
72
|
+
return False
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
backend = ResponseBackend(api_key=api_key)
|
|
76
|
+
agent = SingleAgent(
|
|
77
|
+
backend=backend,
|
|
78
|
+
agent_id="solo_agent",
|
|
79
|
+
system_message="You are a knowledgeable assistant.",
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
orchestrator = Orchestrator(agents={"solo": agent})
|
|
83
|
+
|
|
84
|
+
print("š¤ Testing orchestrator with single agent...")
|
|
85
|
+
|
|
86
|
+
messages = [
|
|
87
|
+
{"role": "user", "content": "Explain photosynthesis in one sentence."}
|
|
88
|
+
]
|
|
89
|
+
response_content = ""
|
|
90
|
+
|
|
91
|
+
async for chunk in orchestrator.chat(messages):
|
|
92
|
+
if chunk.type == "content" and chunk.content:
|
|
93
|
+
response_content += chunk.content
|
|
94
|
+
print(chunk.content, end="", flush=True)
|
|
95
|
+
elif chunk.type == "error":
|
|
96
|
+
print(f"\nā Error: {chunk.error}")
|
|
97
|
+
return False
|
|
98
|
+
elif chunk.type == "done":
|
|
99
|
+
break
|
|
100
|
+
|
|
101
|
+
print(
|
|
102
|
+
f"\nā
Orchestrator single agent test completed. Response length: {len(response_content)} chars"
|
|
103
|
+
)
|
|
104
|
+
return True
|
|
105
|
+
|
|
106
|
+
except Exception as e:
|
|
107
|
+
print(f"ā Orchestrator single agent test failed: {e}")
|
|
108
|
+
return False
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
async def test_agent_status():
|
|
112
|
+
"""Test agent status functionality."""
|
|
113
|
+
print("\nš§Ŗ Testing Agent Status")
|
|
114
|
+
print("-" * 50)
|
|
115
|
+
|
|
116
|
+
api_key = os.getenv("OPENAI_API_KEY")
|
|
117
|
+
if not api_key:
|
|
118
|
+
print("ā OPENAI_API_KEY not found - skipping status test")
|
|
119
|
+
return False
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
backend = ResponseBackend(api_key=api_key)
|
|
123
|
+
agent = SingleAgent(
|
|
124
|
+
backend=backend,
|
|
125
|
+
agent_id="status_test_agent",
|
|
126
|
+
system_message="Test agent for status checking.",
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# Test initial status
|
|
130
|
+
status = agent.get_status()
|
|
131
|
+
print(f"š Agent Status: {status}")
|
|
132
|
+
|
|
133
|
+
if status.get("agent_id") == "status_test_agent":
|
|
134
|
+
print("ā
Agent status test passed")
|
|
135
|
+
return True
|
|
136
|
+
else:
|
|
137
|
+
print("ā Agent status test failed - incorrect ID")
|
|
138
|
+
return False
|
|
139
|
+
|
|
140
|
+
except Exception as e:
|
|
141
|
+
print(f"ā Agent status test failed: {e}")
|
|
142
|
+
return False
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
async def test_conversation_history():
|
|
146
|
+
"""Test conversation history management."""
|
|
147
|
+
print("\nš§Ŗ Testing Conversation History")
|
|
148
|
+
print("-" * 50)
|
|
149
|
+
|
|
150
|
+
api_key = os.getenv("OPENAI_API_KEY")
|
|
151
|
+
if not api_key:
|
|
152
|
+
print("ā OPENAI_API_KEY not found - skipping history test")
|
|
153
|
+
return False
|
|
154
|
+
|
|
155
|
+
try:
|
|
156
|
+
backend = ResponseBackend(api_key=api_key)
|
|
157
|
+
agent = SingleAgent(
|
|
158
|
+
backend=backend,
|
|
159
|
+
agent_id="history_agent",
|
|
160
|
+
system_message="You are a test agent.",
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Initial history should contain system message
|
|
164
|
+
initial_history = agent.get_conversation_history()
|
|
165
|
+
print(f"š Initial history length: {len(initial_history)}")
|
|
166
|
+
|
|
167
|
+
# Add a message
|
|
168
|
+
messages = [{"role": "user", "content": "Hello"}]
|
|
169
|
+
async for chunk in agent.chat(messages):
|
|
170
|
+
if chunk.type == "done":
|
|
171
|
+
break
|
|
172
|
+
|
|
173
|
+
# Check updated history
|
|
174
|
+
updated_history = agent.get_conversation_history()
|
|
175
|
+
print(f"š Updated history length: {len(updated_history)}")
|
|
176
|
+
|
|
177
|
+
if len(updated_history) > len(initial_history):
|
|
178
|
+
print("ā
Conversation history test passed")
|
|
179
|
+
return True
|
|
180
|
+
else:
|
|
181
|
+
print("ā Conversation history test failed - no history update")
|
|
182
|
+
return False
|
|
183
|
+
|
|
184
|
+
except Exception as e:
|
|
185
|
+
print(f"ā Conversation history test failed: {e}")
|
|
186
|
+
return False
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
async def main():
|
|
190
|
+
"""Run all simple functionality tests."""
|
|
191
|
+
print("š MassGen - Simple Functionality Test Suite")
|
|
192
|
+
print("=" * 60)
|
|
193
|
+
|
|
194
|
+
results = []
|
|
195
|
+
|
|
196
|
+
# Run all tests
|
|
197
|
+
results.append(await test_single_agent())
|
|
198
|
+
results.append(await test_orchestrator_single())
|
|
199
|
+
results.append(await test_agent_status())
|
|
200
|
+
results.append(await test_conversation_history())
|
|
201
|
+
|
|
202
|
+
# Summary
|
|
203
|
+
print("\n" + "=" * 60)
|
|
204
|
+
print("š Test Results:")
|
|
205
|
+
print(f"ā
Passed: {sum(results)}")
|
|
206
|
+
print(f"ā Failed: {len(results) - sum(results)}")
|
|
207
|
+
|
|
208
|
+
if all(results):
|
|
209
|
+
print("š All simple functionality tests passed!")
|
|
210
|
+
print("ā
MassGen basic functionality is working correctly")
|
|
211
|
+
else:
|
|
212
|
+
print("ā ļø Some tests failed - check API key and configuration")
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
if __name__ == "__main__":
|
|
216
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Test script for MassGen three-agent coordination with terminal display.
|
|
4
|
+
Tests orchestrator coordination between three agents with diverse expertise.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
# Add project root to path
|
|
13
|
+
project_root = Path(__file__).parent.parent.parent.parent
|
|
14
|
+
sys.path.insert(0, str(project_root))
|
|
15
|
+
|
|
16
|
+
from massgen.backend.response import ResponseBackend
|
|
17
|
+
from massgen.chat_agent import SingleAgent
|
|
18
|
+
from massgen.orchestrator import Orchestrator
|
|
19
|
+
from massgen.frontend.coordination_ui import CoordinationUI
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
async def test_three_agents_coordination():
|
|
23
|
+
"""Test three-agent coordination with diverse expertise areas."""
|
|
24
|
+
print("š MassGen - Three Agents Coordination Test")
|
|
25
|
+
print("=" * 60)
|
|
26
|
+
|
|
27
|
+
# Check if API key is available
|
|
28
|
+
api_key = os.getenv("OPENAI_API_KEY")
|
|
29
|
+
if not api_key:
|
|
30
|
+
print("ā OPENAI_API_KEY not found in environment variables")
|
|
31
|
+
print("ā ļø Set OPENAI_API_KEY to test three-agent coordination")
|
|
32
|
+
return False
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
# Create backend
|
|
36
|
+
backend = ResponseBackend(api_key=api_key)
|
|
37
|
+
|
|
38
|
+
# Create three agents with different expertise
|
|
39
|
+
researcher = SingleAgent(
|
|
40
|
+
backend=backend,
|
|
41
|
+
agent_id="researcher",
|
|
42
|
+
system_message="You are a thorough researcher who excels at gathering comprehensive information and identifying key facts. Focus on accuracy and completeness.",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
analyst = SingleAgent(
|
|
46
|
+
backend=backend,
|
|
47
|
+
agent_id="analyst",
|
|
48
|
+
system_message="You are a critical analyst who specializes in evaluating information, identifying patterns, and drawing insights. Focus on analysis and interpretation.",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
communicator = SingleAgent(
|
|
52
|
+
backend=backend,
|
|
53
|
+
agent_id="communicator",
|
|
54
|
+
system_message="You are a skilled communicator who excels at synthesizing complex information into clear, engaging presentations. Focus on clarity and accessibility.",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Create orchestrator with three agents
|
|
58
|
+
agents = {
|
|
59
|
+
"researcher": researcher,
|
|
60
|
+
"analyst": analyst,
|
|
61
|
+
"communicator": communicator,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
orchestrator = Orchestrator(agents=agents)
|
|
65
|
+
|
|
66
|
+
# Create UI for coordination display
|
|
67
|
+
ui = CoordinationUI(display_type="terminal", logging_enabled=True)
|
|
68
|
+
|
|
69
|
+
print("š„ Created three-agent system:")
|
|
70
|
+
print(" š Researcher - Comprehensive information gathering")
|
|
71
|
+
print(" š Analyst - Critical analysis and pattern recognition")
|
|
72
|
+
print(" š¬ Communicator - Clear synthesis and presentation")
|
|
73
|
+
print()
|
|
74
|
+
|
|
75
|
+
# Test question that benefits from all three perspectives
|
|
76
|
+
test_question = "What are the main challenges and opportunities in developing sustainable cities, and what strategies show the most promise?"
|
|
77
|
+
|
|
78
|
+
print(f"š Question: {test_question}")
|
|
79
|
+
print("\nš Starting three-agent coordination...")
|
|
80
|
+
print("=" * 60)
|
|
81
|
+
|
|
82
|
+
# Coordinate with UI (returns final response)
|
|
83
|
+
final_response = await ui.coordinate(orchestrator, test_question)
|
|
84
|
+
|
|
85
|
+
print("\n" + "=" * 60)
|
|
86
|
+
print("ā
Three-agent coordination completed successfully!")
|
|
87
|
+
print(f"š Final response length: {len(final_response)} characters")
|
|
88
|
+
|
|
89
|
+
return True
|
|
90
|
+
|
|
91
|
+
except Exception as e:
|
|
92
|
+
print(f"ā Three-agent coordination test failed: {e}")
|
|
93
|
+
import traceback
|
|
94
|
+
|
|
95
|
+
traceback.print_exc()
|
|
96
|
+
return False
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
async def test_three_agents_simple():
|
|
100
|
+
"""Simple three-agent test without UI for basic functionality verification."""
|
|
101
|
+
print("\nš§Ŗ Simple Three-Agent Test (No UI)")
|
|
102
|
+
print("-" * 40)
|
|
103
|
+
|
|
104
|
+
api_key = os.getenv("OPENAI_API_KEY")
|
|
105
|
+
if not api_key:
|
|
106
|
+
print("ā OPENAI_API_KEY not found - skipping simple test")
|
|
107
|
+
return False
|
|
108
|
+
|
|
109
|
+
try:
|
|
110
|
+
backend = ResponseBackend(api_key=api_key)
|
|
111
|
+
|
|
112
|
+
# Create minimal agents with different roles
|
|
113
|
+
planner = SingleAgent(
|
|
114
|
+
backend=backend,
|
|
115
|
+
agent_id="planner",
|
|
116
|
+
system_message="You are a strategic planner. Focus on planning and organization.",
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
executor = SingleAgent(
|
|
120
|
+
backend=backend,
|
|
121
|
+
agent_id="executor",
|
|
122
|
+
system_message="You are an executor. Focus on implementation and practical steps.",
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
evaluator = SingleAgent(
|
|
126
|
+
backend=backend,
|
|
127
|
+
agent_id="evaluator",
|
|
128
|
+
system_message="You are an evaluator. Focus on assessment and quality control.",
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
orchestrator = Orchestrator(
|
|
132
|
+
agents={"planner": planner, "executor": executor, "evaluator": evaluator}
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
print("š¤ Testing simple three-agent coordination...")
|
|
136
|
+
|
|
137
|
+
messages = [
|
|
138
|
+
{
|
|
139
|
+
"role": "user",
|
|
140
|
+
"content": "How can we improve team productivity in a remote work environment?",
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
response_content = ""
|
|
145
|
+
async for chunk in orchestrator.chat(messages):
|
|
146
|
+
if chunk.type == "content" and chunk.content:
|
|
147
|
+
response_content += chunk.content
|
|
148
|
+
print(chunk.content, end="", flush=True)
|
|
149
|
+
elif chunk.type == "error":
|
|
150
|
+
print(f"\nā Error: {chunk.error}")
|
|
151
|
+
return False
|
|
152
|
+
elif chunk.type == "done":
|
|
153
|
+
break
|
|
154
|
+
|
|
155
|
+
print(
|
|
156
|
+
f"\nā
Simple test completed. Response length: {len(response_content)} characters"
|
|
157
|
+
)
|
|
158
|
+
return True
|
|
159
|
+
|
|
160
|
+
except Exception as e:
|
|
161
|
+
print(f"ā Simple three-agent test failed: {e}")
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
async def test_three_agents_consensus():
|
|
166
|
+
"""Test consensus building with three agents having different viewpoints."""
|
|
167
|
+
print("\nš¤ Three-Agent Consensus Test")
|
|
168
|
+
print("-" * 40)
|
|
169
|
+
|
|
170
|
+
api_key = os.getenv("OPENAI_API_KEY")
|
|
171
|
+
if not api_key:
|
|
172
|
+
print("ā OPENAI_API_KEY not found - skipping consensus test")
|
|
173
|
+
return False
|
|
174
|
+
|
|
175
|
+
try:
|
|
176
|
+
backend = ResponseBackend(api_key=api_key)
|
|
177
|
+
|
|
178
|
+
# Create agents with potentially different perspectives
|
|
179
|
+
optimist = SingleAgent(
|
|
180
|
+
backend=backend,
|
|
181
|
+
agent_id="optimist",
|
|
182
|
+
system_message="You are an optimistic viewpoint agent. Focus on opportunities and positive outcomes.",
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
realist = SingleAgent(
|
|
186
|
+
backend=backend,
|
|
187
|
+
agent_id="realist",
|
|
188
|
+
system_message="You are a realistic viewpoint agent. Focus on practical considerations and balanced perspectives.",
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
skeptic = SingleAgent(
|
|
192
|
+
backend=backend,
|
|
193
|
+
agent_id="skeptic",
|
|
194
|
+
system_message="You are a skeptical viewpoint agent. Focus on potential challenges and risks.",
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
orchestrator = Orchestrator(
|
|
198
|
+
agents={"optimist": optimist, "realist": realist, "skeptic": skeptic}
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
print("š¤ Testing consensus building with diverse viewpoints...")
|
|
202
|
+
|
|
203
|
+
# Question that might generate different perspectives
|
|
204
|
+
messages = [
|
|
205
|
+
{
|
|
206
|
+
"role": "user",
|
|
207
|
+
"content": "What is the future outlook for artificial intelligence in healthcare?",
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
|
|
211
|
+
response_content = ""
|
|
212
|
+
async for chunk in orchestrator.chat(messages):
|
|
213
|
+
if chunk.type == "content" and chunk.content:
|
|
214
|
+
response_content += chunk.content
|
|
215
|
+
print(chunk.content, end="", flush=True)
|
|
216
|
+
elif chunk.type == "error":
|
|
217
|
+
print(f"\nā Error: {chunk.error}")
|
|
218
|
+
return False
|
|
219
|
+
elif chunk.type == "done":
|
|
220
|
+
break
|
|
221
|
+
|
|
222
|
+
print(
|
|
223
|
+
f"\nā
Consensus test completed. Response length: {len(response_content)} characters"
|
|
224
|
+
)
|
|
225
|
+
return True
|
|
226
|
+
|
|
227
|
+
except Exception as e:
|
|
228
|
+
print(f"ā Consensus test failed: {e}")
|
|
229
|
+
return False
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
async def main():
|
|
233
|
+
"""Run three-agent coordination tests."""
|
|
234
|
+
print("š MassGen - Three Agents Test Suite")
|
|
235
|
+
print("=" * 60)
|
|
236
|
+
|
|
237
|
+
results = []
|
|
238
|
+
|
|
239
|
+
# Run simple test first
|
|
240
|
+
results.append(await test_three_agents_simple())
|
|
241
|
+
|
|
242
|
+
# Run consensus test
|
|
243
|
+
if results[0]:
|
|
244
|
+
results.append(await test_three_agents_consensus())
|
|
245
|
+
else:
|
|
246
|
+
print("ā ļø Skipping consensus test due to simple test failure")
|
|
247
|
+
results.append(False)
|
|
248
|
+
|
|
249
|
+
# Run full coordination test (most complex)
|
|
250
|
+
if sum(results) >= 1: # Run if at least one previous test passes
|
|
251
|
+
results.append(await test_three_agents_coordination())
|
|
252
|
+
else:
|
|
253
|
+
print("ā ļø Skipping full coordination test due to previous failures")
|
|
254
|
+
results.append(False)
|
|
255
|
+
|
|
256
|
+
# Summary
|
|
257
|
+
print("\n" + "=" * 60)
|
|
258
|
+
print("š Test Results:")
|
|
259
|
+
print(f"ā
Passed: {sum(results)}")
|
|
260
|
+
print(f"ā Failed: {len(results) - sum(results)}")
|
|
261
|
+
|
|
262
|
+
if all(results):
|
|
263
|
+
print("š All three-agent tests passed!")
|
|
264
|
+
print("ā
Three-agent coordination is working correctly")
|
|
265
|
+
elif sum(results) >= 2:
|
|
266
|
+
print("ā
Most three-agent tests passed - system is functional")
|
|
267
|
+
else:
|
|
268
|
+
print("ā ļø Multiple tests failed - check API key and network connection")
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
if __name__ == "__main__":
|
|
272
|
+
asyncio.run(main())
|