massgen 0.0.3__py3-none-any.whl → 0.1.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.

Potentially problematic release.


This version of massgen might be problematic. Click here for more details.

Files changed (268) hide show
  1. massgen/__init__.py +142 -8
  2. massgen/adapters/__init__.py +29 -0
  3. massgen/adapters/ag2_adapter.py +483 -0
  4. massgen/adapters/base.py +183 -0
  5. massgen/adapters/tests/__init__.py +0 -0
  6. massgen/adapters/tests/test_ag2_adapter.py +439 -0
  7. massgen/adapters/tests/test_agent_adapter.py +128 -0
  8. massgen/adapters/utils/__init__.py +2 -0
  9. massgen/adapters/utils/ag2_utils.py +236 -0
  10. massgen/adapters/utils/tests/__init__.py +0 -0
  11. massgen/adapters/utils/tests/test_ag2_utils.py +138 -0
  12. massgen/agent_config.py +329 -55
  13. massgen/api_params_handler/__init__.py +10 -0
  14. massgen/api_params_handler/_api_params_handler_base.py +99 -0
  15. massgen/api_params_handler/_chat_completions_api_params_handler.py +176 -0
  16. massgen/api_params_handler/_claude_api_params_handler.py +113 -0
  17. massgen/api_params_handler/_response_api_params_handler.py +130 -0
  18. massgen/backend/__init__.py +39 -4
  19. massgen/backend/azure_openai.py +385 -0
  20. massgen/backend/base.py +341 -69
  21. massgen/backend/base_with_mcp.py +1102 -0
  22. massgen/backend/capabilities.py +386 -0
  23. massgen/backend/chat_completions.py +577 -130
  24. massgen/backend/claude.py +1033 -537
  25. massgen/backend/claude_code.py +1203 -0
  26. massgen/backend/cli_base.py +209 -0
  27. massgen/backend/docs/BACKEND_ARCHITECTURE.md +126 -0
  28. massgen/backend/{CLAUDE_API_RESEARCH.md → docs/CLAUDE_API_RESEARCH.md} +18 -18
  29. massgen/backend/{GEMINI_API_DOCUMENTATION.md → docs/GEMINI_API_DOCUMENTATION.md} +9 -9
  30. massgen/backend/docs/Gemini MCP Integration Analysis.md +1050 -0
  31. massgen/backend/docs/MCP_IMPLEMENTATION_CLAUDE_BACKEND.md +177 -0
  32. massgen/backend/docs/MCP_INTEGRATION_RESPONSE_BACKEND.md +352 -0
  33. massgen/backend/docs/OPENAI_GPT5_MODELS.md +211 -0
  34. massgen/backend/{OPENAI_RESPONSES_API_FORMAT.md → docs/OPENAI_RESPONSE_API_TOOL_CALLS.md} +3 -3
  35. massgen/backend/docs/OPENAI_response_streaming.md +20654 -0
  36. massgen/backend/docs/inference_backend.md +257 -0
  37. massgen/backend/docs/permissions_and_context_files.md +1085 -0
  38. massgen/backend/external.py +126 -0
  39. massgen/backend/gemini.py +1850 -241
  40. massgen/backend/grok.py +40 -156
  41. massgen/backend/inference.py +156 -0
  42. massgen/backend/lmstudio.py +171 -0
  43. massgen/backend/response.py +1095 -322
  44. massgen/chat_agent.py +131 -113
  45. massgen/cli.py +1560 -275
  46. massgen/config_builder.py +2396 -0
  47. massgen/configs/BACKEND_CONFIGURATION.md +458 -0
  48. massgen/configs/README.md +559 -216
  49. massgen/configs/ag2/ag2_case_study.yaml +27 -0
  50. massgen/configs/ag2/ag2_coder.yaml +34 -0
  51. massgen/configs/ag2/ag2_coder_case_study.yaml +36 -0
  52. massgen/configs/ag2/ag2_gemini.yaml +27 -0
  53. massgen/configs/ag2/ag2_groupchat.yaml +108 -0
  54. massgen/configs/ag2/ag2_groupchat_gpt.yaml +118 -0
  55. massgen/configs/ag2/ag2_single_agent.yaml +21 -0
  56. massgen/configs/basic/multi/fast_timeout_example.yaml +37 -0
  57. massgen/configs/basic/multi/gemini_4o_claude.yaml +31 -0
  58. massgen/configs/basic/multi/gemini_gpt5nano_claude.yaml +36 -0
  59. massgen/configs/{gemini_4o_claude.yaml → basic/multi/geminicode_4o_claude.yaml} +3 -3
  60. massgen/configs/basic/multi/geminicode_gpt5nano_claude.yaml +36 -0
  61. massgen/configs/basic/multi/glm_gemini_claude.yaml +25 -0
  62. massgen/configs/basic/multi/gpt4o_audio_generation.yaml +30 -0
  63. massgen/configs/basic/multi/gpt4o_image_generation.yaml +31 -0
  64. massgen/configs/basic/multi/gpt5nano_glm_qwen.yaml +26 -0
  65. massgen/configs/basic/multi/gpt5nano_image_understanding.yaml +26 -0
  66. massgen/configs/{three_agents_default.yaml → basic/multi/three_agents_default.yaml} +8 -4
  67. massgen/configs/basic/multi/three_agents_opensource.yaml +27 -0
  68. massgen/configs/basic/multi/three_agents_vllm.yaml +20 -0
  69. massgen/configs/basic/multi/two_agents_gemini.yaml +19 -0
  70. massgen/configs/{two_agents.yaml → basic/multi/two_agents_gpt5.yaml} +14 -6
  71. massgen/configs/basic/multi/two_agents_opensource_lmstudio.yaml +31 -0
  72. massgen/configs/basic/multi/two_qwen_vllm_sglang.yaml +28 -0
  73. massgen/configs/{single_agent.yaml → basic/single/single_agent.yaml} +1 -1
  74. massgen/configs/{single_flash2.5.yaml → basic/single/single_flash2.5.yaml} +1 -2
  75. massgen/configs/basic/single/single_gemini2.5pro.yaml +16 -0
  76. massgen/configs/basic/single/single_gpt4o_audio_generation.yaml +22 -0
  77. massgen/configs/basic/single/single_gpt4o_image_generation.yaml +22 -0
  78. massgen/configs/basic/single/single_gpt4o_video_generation.yaml +24 -0
  79. massgen/configs/basic/single/single_gpt5nano.yaml +20 -0
  80. massgen/configs/basic/single/single_gpt5nano_file_search.yaml +18 -0
  81. massgen/configs/basic/single/single_gpt5nano_image_understanding.yaml +17 -0
  82. massgen/configs/basic/single/single_gptoss120b.yaml +15 -0
  83. massgen/configs/basic/single/single_openrouter_audio_understanding.yaml +15 -0
  84. massgen/configs/basic/single/single_qwen_video_understanding.yaml +15 -0
  85. massgen/configs/debug/code_execution/command_filtering_blacklist.yaml +29 -0
  86. massgen/configs/debug/code_execution/command_filtering_whitelist.yaml +28 -0
  87. massgen/configs/debug/code_execution/docker_verification.yaml +29 -0
  88. massgen/configs/debug/skip_coordination_test.yaml +27 -0
  89. massgen/configs/debug/test_sdk_migration.yaml +17 -0
  90. massgen/configs/docs/DISCORD_MCP_SETUP.md +208 -0
  91. massgen/configs/docs/TWITTER_MCP_ENESCINAR_SETUP.md +82 -0
  92. massgen/configs/providers/azure/azure_openai_multi.yaml +21 -0
  93. massgen/configs/providers/azure/azure_openai_single.yaml +19 -0
  94. massgen/configs/providers/claude/claude.yaml +14 -0
  95. massgen/configs/providers/gemini/gemini_gpt5nano.yaml +28 -0
  96. massgen/configs/providers/local/lmstudio.yaml +11 -0
  97. massgen/configs/providers/openai/gpt5.yaml +46 -0
  98. massgen/configs/providers/openai/gpt5_nano.yaml +46 -0
  99. massgen/configs/providers/others/grok_single_agent.yaml +19 -0
  100. massgen/configs/providers/others/zai_coding_team.yaml +108 -0
  101. massgen/configs/providers/others/zai_glm45.yaml +12 -0
  102. massgen/configs/{creative_team.yaml → teams/creative/creative_team.yaml} +16 -6
  103. massgen/configs/{travel_planning.yaml → teams/creative/travel_planning.yaml} +16 -6
  104. massgen/configs/{news_analysis.yaml → teams/research/news_analysis.yaml} +16 -6
  105. massgen/configs/{research_team.yaml → teams/research/research_team.yaml} +15 -7
  106. massgen/configs/{technical_analysis.yaml → teams/research/technical_analysis.yaml} +16 -6
  107. massgen/configs/tools/code-execution/basic_command_execution.yaml +25 -0
  108. massgen/configs/tools/code-execution/code_execution_use_case_simple.yaml +41 -0
  109. massgen/configs/tools/code-execution/docker_claude_code.yaml +32 -0
  110. massgen/configs/tools/code-execution/docker_multi_agent.yaml +32 -0
  111. massgen/configs/tools/code-execution/docker_simple.yaml +29 -0
  112. massgen/configs/tools/code-execution/docker_with_resource_limits.yaml +32 -0
  113. massgen/configs/tools/code-execution/multi_agent_playwright_automation.yaml +57 -0
  114. massgen/configs/tools/filesystem/cc_gpt5_gemini_filesystem.yaml +34 -0
  115. massgen/configs/tools/filesystem/claude_code_context_sharing.yaml +68 -0
  116. massgen/configs/tools/filesystem/claude_code_flash2.5.yaml +43 -0
  117. massgen/configs/tools/filesystem/claude_code_flash2.5_gptoss.yaml +49 -0
  118. massgen/configs/tools/filesystem/claude_code_gpt5nano.yaml +31 -0
  119. massgen/configs/tools/filesystem/claude_code_single.yaml +40 -0
  120. massgen/configs/tools/filesystem/fs_permissions_test.yaml +87 -0
  121. massgen/configs/tools/filesystem/gemini_gemini_workspace_cleanup.yaml +54 -0
  122. massgen/configs/tools/filesystem/gemini_gpt5_filesystem_casestudy.yaml +30 -0
  123. massgen/configs/tools/filesystem/gemini_gpt5nano_file_context_path.yaml +43 -0
  124. massgen/configs/tools/filesystem/gemini_gpt5nano_protected_paths.yaml +45 -0
  125. massgen/configs/tools/filesystem/gpt5mini_cc_fs_context_path.yaml +31 -0
  126. massgen/configs/tools/filesystem/grok4_gpt5_gemini_filesystem.yaml +32 -0
  127. massgen/configs/tools/filesystem/multiturn/grok4_gpt5_claude_code_filesystem_multiturn.yaml +58 -0
  128. massgen/configs/tools/filesystem/multiturn/grok4_gpt5_gemini_filesystem_multiturn.yaml +58 -0
  129. massgen/configs/tools/filesystem/multiturn/two_claude_code_filesystem_multiturn.yaml +47 -0
  130. massgen/configs/tools/filesystem/multiturn/two_gemini_flash_filesystem_multiturn.yaml +48 -0
  131. massgen/configs/tools/mcp/claude_code_discord_mcp_example.yaml +27 -0
  132. massgen/configs/tools/mcp/claude_code_simple_mcp.yaml +35 -0
  133. massgen/configs/tools/mcp/claude_code_twitter_mcp_example.yaml +32 -0
  134. massgen/configs/tools/mcp/claude_mcp_example.yaml +24 -0
  135. massgen/configs/tools/mcp/claude_mcp_test.yaml +27 -0
  136. massgen/configs/tools/mcp/five_agents_travel_mcp_test.yaml +157 -0
  137. massgen/configs/tools/mcp/five_agents_weather_mcp_test.yaml +103 -0
  138. massgen/configs/tools/mcp/gemini_mcp_example.yaml +24 -0
  139. massgen/configs/tools/mcp/gemini_mcp_filesystem_test.yaml +23 -0
  140. massgen/configs/tools/mcp/gemini_mcp_filesystem_test_sharing.yaml +23 -0
  141. massgen/configs/tools/mcp/gemini_mcp_filesystem_test_single_agent.yaml +17 -0
  142. massgen/configs/tools/mcp/gemini_mcp_filesystem_test_with_claude_code.yaml +24 -0
  143. massgen/configs/tools/mcp/gemini_mcp_test.yaml +27 -0
  144. massgen/configs/tools/mcp/gemini_notion_mcp.yaml +52 -0
  145. massgen/configs/tools/mcp/gpt5_nano_mcp_example.yaml +24 -0
  146. massgen/configs/tools/mcp/gpt5_nano_mcp_test.yaml +27 -0
  147. massgen/configs/tools/mcp/gpt5mini_claude_code_discord_mcp_example.yaml +38 -0
  148. massgen/configs/tools/mcp/gpt_oss_mcp_example.yaml +25 -0
  149. massgen/configs/tools/mcp/gpt_oss_mcp_test.yaml +28 -0
  150. massgen/configs/tools/mcp/grok3_mini_mcp_example.yaml +24 -0
  151. massgen/configs/tools/mcp/grok3_mini_mcp_test.yaml +27 -0
  152. massgen/configs/tools/mcp/multimcp_gemini.yaml +111 -0
  153. massgen/configs/tools/mcp/qwen_api_mcp_example.yaml +25 -0
  154. massgen/configs/tools/mcp/qwen_api_mcp_test.yaml +28 -0
  155. massgen/configs/tools/mcp/qwen_local_mcp_example.yaml +24 -0
  156. massgen/configs/tools/mcp/qwen_local_mcp_test.yaml +27 -0
  157. massgen/configs/tools/planning/five_agents_discord_mcp_planning_mode.yaml +140 -0
  158. massgen/configs/tools/planning/five_agents_filesystem_mcp_planning_mode.yaml +151 -0
  159. massgen/configs/tools/planning/five_agents_notion_mcp_planning_mode.yaml +151 -0
  160. massgen/configs/tools/planning/five_agents_twitter_mcp_planning_mode.yaml +155 -0
  161. massgen/configs/tools/planning/gpt5_mini_case_study_mcp_planning_mode.yaml +73 -0
  162. massgen/configs/tools/web-search/claude_streamable_http_test.yaml +43 -0
  163. massgen/configs/tools/web-search/gemini_streamable_http_test.yaml +43 -0
  164. massgen/configs/tools/web-search/gpt5_mini_streamable_http_test.yaml +43 -0
  165. massgen/configs/tools/web-search/gpt_oss_streamable_http_test.yaml +44 -0
  166. massgen/configs/tools/web-search/grok3_mini_streamable_http_test.yaml +43 -0
  167. massgen/configs/tools/web-search/qwen_api_streamable_http_test.yaml +44 -0
  168. massgen/configs/tools/web-search/qwen_local_streamable_http_test.yaml +43 -0
  169. massgen/coordination_tracker.py +708 -0
  170. massgen/docker/README.md +462 -0
  171. massgen/filesystem_manager/__init__.py +21 -0
  172. massgen/filesystem_manager/_base.py +9 -0
  173. massgen/filesystem_manager/_code_execution_server.py +545 -0
  174. massgen/filesystem_manager/_docker_manager.py +477 -0
  175. massgen/filesystem_manager/_file_operation_tracker.py +248 -0
  176. massgen/filesystem_manager/_filesystem_manager.py +813 -0
  177. massgen/filesystem_manager/_path_permission_manager.py +1261 -0
  178. massgen/filesystem_manager/_workspace_tools_server.py +1815 -0
  179. massgen/formatter/__init__.py +10 -0
  180. massgen/formatter/_chat_completions_formatter.py +284 -0
  181. massgen/formatter/_claude_formatter.py +235 -0
  182. massgen/formatter/_formatter_base.py +156 -0
  183. massgen/formatter/_response_formatter.py +263 -0
  184. massgen/frontend/__init__.py +1 -2
  185. massgen/frontend/coordination_ui.py +471 -286
  186. massgen/frontend/displays/base_display.py +56 -11
  187. massgen/frontend/displays/create_coordination_table.py +1956 -0
  188. massgen/frontend/displays/rich_terminal_display.py +1259 -619
  189. massgen/frontend/displays/simple_display.py +9 -4
  190. massgen/frontend/displays/terminal_display.py +27 -68
  191. massgen/logger_config.py +681 -0
  192. massgen/mcp_tools/README.md +232 -0
  193. massgen/mcp_tools/__init__.py +105 -0
  194. massgen/mcp_tools/backend_utils.py +1035 -0
  195. massgen/mcp_tools/circuit_breaker.py +195 -0
  196. massgen/mcp_tools/client.py +894 -0
  197. massgen/mcp_tools/config_validator.py +138 -0
  198. massgen/mcp_tools/docs/circuit_breaker.md +646 -0
  199. massgen/mcp_tools/docs/client.md +950 -0
  200. massgen/mcp_tools/docs/config_validator.md +478 -0
  201. massgen/mcp_tools/docs/exceptions.md +1165 -0
  202. massgen/mcp_tools/docs/security.md +854 -0
  203. massgen/mcp_tools/exceptions.py +338 -0
  204. massgen/mcp_tools/hooks.py +212 -0
  205. massgen/mcp_tools/security.py +780 -0
  206. massgen/message_templates.py +342 -64
  207. massgen/orchestrator.py +1515 -241
  208. massgen/stream_chunk/__init__.py +35 -0
  209. massgen/stream_chunk/base.py +92 -0
  210. massgen/stream_chunk/multimodal.py +237 -0
  211. massgen/stream_chunk/text.py +162 -0
  212. massgen/tests/mcp_test_server.py +150 -0
  213. massgen/tests/multi_turn_conversation_design.md +0 -8
  214. massgen/tests/test_azure_openai_backend.py +156 -0
  215. massgen/tests/test_backend_capabilities.py +262 -0
  216. massgen/tests/test_backend_event_loop_all.py +179 -0
  217. massgen/tests/test_chat_completions_refactor.py +142 -0
  218. massgen/tests/test_claude_backend.py +15 -28
  219. massgen/tests/test_claude_code.py +268 -0
  220. massgen/tests/test_claude_code_context_sharing.py +233 -0
  221. massgen/tests/test_claude_code_orchestrator.py +175 -0
  222. massgen/tests/test_cli_backends.py +180 -0
  223. massgen/tests/test_code_execution.py +679 -0
  224. massgen/tests/test_external_agent_backend.py +134 -0
  225. massgen/tests/test_final_presentation_fallback.py +237 -0
  226. massgen/tests/test_gemini_planning_mode.py +351 -0
  227. massgen/tests/test_grok_backend.py +7 -10
  228. massgen/tests/test_http_mcp_server.py +42 -0
  229. massgen/tests/test_integration_simple.py +198 -0
  230. massgen/tests/test_mcp_blocking.py +125 -0
  231. massgen/tests/test_message_context_building.py +29 -47
  232. massgen/tests/test_orchestrator_final_presentation.py +48 -0
  233. massgen/tests/test_path_permission_manager.py +2087 -0
  234. massgen/tests/test_rich_terminal_display.py +14 -13
  235. massgen/tests/test_timeout.py +133 -0
  236. massgen/tests/test_v3_3agents.py +11 -12
  237. massgen/tests/test_v3_simple.py +8 -13
  238. massgen/tests/test_v3_three_agents.py +11 -18
  239. massgen/tests/test_v3_two_agents.py +8 -13
  240. massgen/token_manager/__init__.py +7 -0
  241. massgen/token_manager/token_manager.py +400 -0
  242. massgen/utils.py +52 -16
  243. massgen/v1/agent.py +45 -91
  244. massgen/v1/agents.py +18 -53
  245. massgen/v1/backends/gemini.py +50 -153
  246. massgen/v1/backends/grok.py +21 -54
  247. massgen/v1/backends/oai.py +39 -111
  248. massgen/v1/cli.py +36 -93
  249. massgen/v1/config.py +8 -12
  250. massgen/v1/logging.py +43 -127
  251. massgen/v1/main.py +18 -32
  252. massgen/v1/orchestrator.py +68 -209
  253. massgen/v1/streaming_display.py +62 -163
  254. massgen/v1/tools.py +8 -12
  255. massgen/v1/types.py +9 -23
  256. massgen/v1/utils.py +5 -23
  257. massgen-0.1.0.dist-info/METADATA +1245 -0
  258. massgen-0.1.0.dist-info/RECORD +273 -0
  259. massgen-0.1.0.dist-info/entry_points.txt +2 -0
  260. massgen/frontend/logging/__init__.py +0 -9
  261. massgen/frontend/logging/realtime_logger.py +0 -197
  262. massgen-0.0.3.dist-info/METADATA +0 -568
  263. massgen-0.0.3.dist-info/RECORD +0 -76
  264. massgen-0.0.3.dist-info/entry_points.txt +0 -2
  265. /massgen/backend/{Function calling openai responses.md → docs/Function calling openai responses.md} +0 -0
  266. {massgen-0.0.3.dist-info → massgen-0.1.0.dist-info}/WHEEL +0 -0
  267. {massgen-0.0.3.dist-info → massgen-0.1.0.dist-info}/licenses/LICENSE +0 -0
  268. {massgen-0.0.3.dist-info → massgen-0.1.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
2
3
  """
3
4
  Test script for MassGen Rich Terminal Display.
4
5
  Tests RichTerminalDisplay functionality with two-agent coordination.
@@ -13,11 +14,16 @@ from pathlib import Path
13
14
  project_root = Path(__file__).parent.parent.parent
14
15
  sys.path.insert(0, str(project_root))
15
16
 
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, coordinate_with_rich_ui
20
- from massgen.frontend.displays.rich_terminal_display import is_rich_available
17
+ from massgen.backend.response import ResponseBackend # noqa: E402
18
+ from massgen.chat_agent import SingleAgent # noqa: E402
19
+ from massgen.frontend.coordination_ui import ( # noqa: E402
20
+ CoordinationUI,
21
+ coordinate_with_rich_ui,
22
+ )
23
+ from massgen.frontend.displays.rich_terminal_display import ( # noqa: E402
24
+ is_rich_available,
25
+ )
26
+ from massgen.orchestrator import Orchestrator # noqa: E402
21
27
 
22
28
 
23
29
  async def test_rich_availability():
@@ -64,7 +70,7 @@ async def test_rich_display_basic():
64
70
  # Test theme configuration
65
71
  themes = ["dark", "light", "cyberpunk"]
66
72
  for theme in themes:
67
- themed_display = RichTerminalDisplay(agent_ids, theme=theme)
73
+ RichTerminalDisplay(agent_ids, theme=theme)
68
74
  print(f"✅ {theme.title()} theme created successfully")
69
75
 
70
76
  # Clean up
@@ -186,9 +192,7 @@ async def test_rich_convenience_function():
186
192
  system_message="You are a strategic thinker who focuses on long-term implications and strategic recommendations.",
187
193
  )
188
194
 
189
- orchestrator = Orchestrator(
190
- agents={"analyst": analyst, "strategist": strategist}
191
- )
195
+ orchestrator = Orchestrator(agents={"analyst": analyst, "strategist": strategist})
192
196
 
193
197
  print("🎯 Testing convenience function with light theme...")
194
198
 
@@ -231,13 +235,10 @@ async def test_rich_fallback():
231
235
 
232
236
  try:
233
237
  # Test UI creation with rich_terminal when Rich is available
234
- ui = CoordinationUI(display_type="rich_terminal")
238
+ CoordinationUI(display_type="rich_terminal")
235
239
 
236
240
  if is_rich_available():
237
241
  print("✅ Rich is available - RichTerminalDisplay should be used")
238
- from massgen.frontend.displays.rich_terminal_display import (
239
- RichTerminalDisplay,
240
- )
241
242
 
242
243
  # Note: We can't easily test the actual fallback without mocking
243
244
  print("📝 Note: Fallback logic tested through UI creation")
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Simple test script to verify timeout mechanisms work correctly.
5
+ This creates a fast timeout config and runs a test to demonstrate the timeout fallback.
6
+ """
7
+
8
+ import asyncio
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ from massgen.agent_config import AgentConfig, TimeoutConfig
13
+ from massgen.backend.claude_code import ClaudeCodeBackend
14
+ from massgen.chat_agent import SingleAgent
15
+ from massgen.orchestrator import Orchestrator
16
+
17
+ # Add massgen to Python path
18
+ sys.path.insert(0, str(Path(__file__).parent))
19
+
20
+
21
+ async def test_orchestrator_timeout():
22
+ """Test orchestrator-level timeout."""
23
+ print("\n🧪 Testing Orchestrator Timeout Mechanism")
24
+ print("=" * 50)
25
+
26
+ # Create very restrictive orchestrator timeout
27
+ timeout_config = TimeoutConfig(
28
+ orchestrator_timeout_seconds=10, # 10 seconds orchestrator (very short)
29
+ )
30
+
31
+ # Create agent config and set timeout
32
+ agent_config = AgentConfig.create_claude_code_config(model="claude-sonnet-4-20250514")
33
+ agent_config.timeout_config = timeout_config
34
+
35
+ # Claude code backend for testing
36
+ try:
37
+ backend = ClaudeCodeBackend()
38
+ agent = SingleAgent(backend=backend, system_message="You are a helpful assistant.")
39
+
40
+ # Create orchestrator with timeout-aware agents
41
+ agents = {"test_agent": agent}
42
+ orchestrator = Orchestrator(agents=agents, config=agent_config)
43
+
44
+ print(f"⏱️ Orchestrator timeout: {timeout_config.orchestrator_timeout_seconds}s")
45
+ print("📝 Testing with complex multi-agent coordination that should trigger orchestrator timeout...")
46
+
47
+ # Ask a question that requires complex coordination between multiple agents
48
+ question = (
49
+ "Please coordinate with multiple specialized agents to create a comprehensive business plan "
50
+ "for a tech startup, including market analysis, technical architecture, financial projections, "
51
+ "legal considerations, and detailed implementation timeline. Each section should be thoroughly "
52
+ "researched and cross-validated between agents."
53
+ )
54
+
55
+ print(f"\n❓ Question: {question[:100]}...")
56
+ print("\n🚀 Starting orchestrator coordination (should timeout quickly)...")
57
+
58
+ response_content = ""
59
+ timeout_detected = False
60
+
61
+ async for chunk in orchestrator.chat_simple(question):
62
+ if chunk.type == "content":
63
+ content = chunk.content
64
+ print(f"📝 {content}")
65
+ response_content += chunk.content
66
+ if "time limit exceeded" in content.lower() or "timeout" in content.lower():
67
+ timeout_detected = True
68
+ print(f"⚠️ ORCHESTRATOR TIMEOUT DETECTED: {content}")
69
+ elif chunk.type == "error":
70
+ if "time limit exceeded" in chunk.error.lower() or "timeout" in chunk.error.lower():
71
+ timeout_detected = True
72
+ print(f"⚠️ ORCHESTRATOR TIMEOUT DETECTED: {chunk.error}")
73
+ elif chunk.type == "done":
74
+ print("✅ Orchestrator coordination completed")
75
+ break
76
+
77
+ if timeout_detected:
78
+ print("\n🎯 SUCCESS: Orchestrator timeout mechanism triggered correctly!")
79
+ else:
80
+ print("\n🤔 No orchestrator timeout detected - either coordination completed fast or timeout didn't work")
81
+
82
+ print(f"\n📊 Final response length: {len(response_content)} characters")
83
+
84
+ except Exception as e:
85
+ print(f"❌ Orchestrator timeout test failed with error: {e}")
86
+ print("💡 Note: This test requires API keys to run with real backend")
87
+
88
+
89
+ def print_config_example():
90
+ """Print example configuration for users."""
91
+ print("\n📋 Example YAML Configuration with Timeout Settings:")
92
+ print("=" * 50)
93
+
94
+ example_config = """
95
+ # Conservative timeout settings to prevent runaway costs
96
+ timeout_settings:
97
+ orchestrator_timeout_seconds: 600 # 10 minutes max coordination
98
+
99
+ agents:
100
+ - id: "agent1"
101
+ backend:
102
+ type: "openai"
103
+ model: "gpt-4o-mini"
104
+ system_message: "You are a helpful assistant."
105
+ """
106
+
107
+ print(example_config)
108
+
109
+ print("\n🖥️ CLI Examples:")
110
+ print('python -m massgen.cli --config config.yaml --orchestrator-timeout 300 "Complex task"')
111
+
112
+
113
+ if __name__ == "__main__":
114
+ print("🔧 MassGen Timeout Mechanism Test")
115
+ print("=" * 60)
116
+
117
+ print_config_example()
118
+
119
+ print("\n🧪 Running timeout tests...")
120
+ print("Note: These tests require API keys to run with real backends")
121
+
122
+ try:
123
+ # Run orchestrator timeout test
124
+ asyncio.run(test_orchestrator_timeout())
125
+
126
+ print("\n✅ Timeout mechanism implementation completed!")
127
+ print("💡 The timeout system will prevent runaway token usage and provide graceful fallbacks.")
128
+
129
+ except KeyboardInterrupt:
130
+ print("\n⏹️ Tests interrupted by user")
131
+ except Exception as e:
132
+ print(f"\n❌ Tests failed: {e}")
133
+ print("💡 This is expected if you don't have API keys configured")
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
2
3
  """
3
4
  MassGen Example: Three Agent Coordination
4
5
 
5
- This example demonstrates three-agent coordination using the
6
- multi-region coordination UI. Three agents with different specialties work
6
+ This example demonstrates three-agent coordination using the
7
+ multi-region coordination UI. Three agents with different specialties work
7
8
  together on a question that benefits from multiple perspectives.
8
9
 
9
10
  Features:
@@ -16,20 +17,20 @@ Note: Requires OPENAI_API_KEY in environment.
16
17
  """
17
18
 
18
19
  import asyncio
19
- import sys
20
20
  import os
21
+ import sys
22
+
23
+ from massgen import Orchestrator, ResponseBackend, create_simple_agent
24
+ from massgen.frontend.coordination_ui import coordinate_with_terminal_ui
21
25
 
22
26
  # Add project root to path
23
27
  project_root = os.path.dirname(__file__)
24
28
  sys.path.insert(0, project_root)
25
29
 
26
- from massgen import create_simple_agent, ResponseBackend, Orchestrator
27
- from massgen.frontend.coordination_ui import coordinate_with_terminal_ui
28
-
29
30
 
30
31
  async def three_agent_example():
31
32
  """Demonstrate three agent coordination with multi-region UI."""
32
-
33
+
33
34
  print("🎯 MassGen: Three Agent Coordination")
34
35
  print("=" * 50)
35
36
 
@@ -65,9 +66,7 @@ async def three_agent_example():
65
66
  print(" • educator: Clear explanations")
66
67
 
67
68
  # Create orchestrator
68
- orchestrator = Orchestrator(
69
- agents={"scientist": scientist, "engineer": engineer, "educator": educator}
70
- )
69
+ orchestrator = Orchestrator(agents={"scientist": scientist, "engineer": engineer, "educator": educator})
71
70
  print("✅ orchestrator ready")
72
71
 
73
72
  # Question that benefits from multiple perspectives
@@ -83,14 +82,14 @@ async def three_agent_example():
83
82
  logging_enabled=False,
84
83
  )
85
84
 
86
- print(f"\n✅ Three agent coordination completed!")
85
+ print("\n✅ Three agent coordination completed!")
87
86
 
88
87
  # Show results
89
88
  orchestrator_status = orchestrator.get_status()
90
89
  selected_agent = orchestrator_status.get("selected_agent")
91
90
  vote_results = orchestrator_status.get("vote_results", {})
92
91
 
93
- print(f"\n📊 Results:")
92
+ print("\n📊 Results:")
94
93
  print(f"🏆 Selected agent: {selected_agent}")
95
94
  if vote_results.get("vote_counts"):
96
95
  for agent, votes in vote_results["vote_counts"].items():
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
2
3
  """
3
4
  Simple test script for MassGen basic functionality.
4
5
  Tests single agent and basic orchestrator functionality.
@@ -9,14 +10,14 @@ import os
9
10
  import sys
10
11
  from pathlib import Path
11
12
 
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
13
  from massgen.backend.response import ResponseBackend
17
14
  from massgen.chat_agent import SingleAgent
18
15
  from massgen.orchestrator import Orchestrator
19
16
 
17
+ # Add project root to path
18
+ project_root = Path(__file__).parent.parent.parent.parent
19
+ sys.path.insert(0, str(project_root))
20
+
20
21
 
21
22
  async def test_single_agent():
22
23
  """Test basic SingleAgent functionality."""
@@ -51,9 +52,7 @@ async def test_single_agent():
51
52
  elif chunk.type == "done":
52
53
  break
53
54
 
54
- print(
55
- f"\n✅ Single agent test completed. Response: '{response_content.strip()}'"
56
- )
55
+ print(f"\n✅ Single agent test completed. Response: '{response_content.strip()}'")
57
56
  return True
58
57
 
59
58
  except Exception as e:
@@ -83,9 +82,7 @@ async def test_orchestrator_single():
83
82
 
84
83
  print("📤 Testing orchestrator with single agent...")
85
84
 
86
- messages = [
87
- {"role": "user", "content": "Explain photosynthesis in one sentence."}
88
- ]
85
+ messages = [{"role": "user", "content": "Explain photosynthesis in one sentence."}]
89
86
  response_content = ""
90
87
 
91
88
  async for chunk in orchestrator.chat(messages):
@@ -98,9 +95,7 @@ async def test_orchestrator_single():
98
95
  elif chunk.type == "done":
99
96
  break
100
97
 
101
- print(
102
- f"\n✅ Orchestrator single agent test completed. Response length: {len(response_content)} chars"
103
- )
98
+ print(f"\n✅ Orchestrator single agent test completed. Response length: {len(response_content)} chars")
104
99
  return True
105
100
 
106
101
  except Exception as e:
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
2
3
  """
3
4
  Test script for MassGen three-agent coordination with terminal display.
4
5
  Tests orchestrator coordination between three agents with diverse expertise.
@@ -13,10 +14,10 @@ from pathlib import Path
13
14
  project_root = Path(__file__).parent.parent.parent.parent
14
15
  sys.path.insert(0, str(project_root))
15
16
 
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
17
+ from massgen.backend.response import ResponseBackend # noqa: E402
18
+ from massgen.chat_agent import SingleAgent # noqa: E402
19
+ from massgen.frontend.coordination_ui import CoordinationUI # noqa: E402
20
+ from massgen.orchestrator import Orchestrator # noqa: E402
20
21
 
21
22
 
22
23
  async def test_three_agents_coordination():
@@ -128,9 +129,7 @@ async def test_three_agents_simple():
128
129
  system_message="You are an evaluator. Focus on assessment and quality control.",
129
130
  )
130
131
 
131
- orchestrator = Orchestrator(
132
- agents={"planner": planner, "executor": executor, "evaluator": evaluator}
133
- )
132
+ orchestrator = Orchestrator(agents={"planner": planner, "executor": executor, "evaluator": evaluator})
134
133
 
135
134
  print("📤 Testing simple three-agent coordination...")
136
135
 
@@ -138,7 +137,7 @@ async def test_three_agents_simple():
138
137
  {
139
138
  "role": "user",
140
139
  "content": "How can we improve team productivity in a remote work environment?",
141
- }
140
+ },
142
141
  ]
143
142
 
144
143
  response_content = ""
@@ -152,9 +151,7 @@ async def test_three_agents_simple():
152
151
  elif chunk.type == "done":
153
152
  break
154
153
 
155
- print(
156
- f"\n✅ Simple test completed. Response length: {len(response_content)} characters"
157
- )
154
+ print(f"\n✅ Simple test completed. Response length: {len(response_content)} characters")
158
155
  return True
159
156
 
160
157
  except Exception as e:
@@ -194,9 +191,7 @@ async def test_three_agents_consensus():
194
191
  system_message="You are a skeptical viewpoint agent. Focus on potential challenges and risks.",
195
192
  )
196
193
 
197
- orchestrator = Orchestrator(
198
- agents={"optimist": optimist, "realist": realist, "skeptic": skeptic}
199
- )
194
+ orchestrator = Orchestrator(agents={"optimist": optimist, "realist": realist, "skeptic": skeptic})
200
195
 
201
196
  print("📤 Testing consensus building with diverse viewpoints...")
202
197
 
@@ -205,7 +200,7 @@ async def test_three_agents_consensus():
205
200
  {
206
201
  "role": "user",
207
202
  "content": "What is the future outlook for artificial intelligence in healthcare?",
208
- }
203
+ },
209
204
  ]
210
205
 
211
206
  response_content = ""
@@ -219,9 +214,7 @@ async def test_three_agents_consensus():
219
214
  elif chunk.type == "done":
220
215
  break
221
216
 
222
- print(
223
- f"\n✅ Consensus test completed. Response length: {len(response_content)} characters"
224
- )
217
+ print(f"\n✅ Consensus test completed. Response length: {len(response_content)} characters")
225
218
  return True
226
219
 
227
220
  except Exception as e:
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
2
3
  """
3
4
  Test script for MassGen two-agent coordination with terminal display.
4
5
  Tests orchestrator coordination between two agents with different expertise.
@@ -13,10 +14,10 @@ from pathlib import Path
13
14
  project_root = Path(__file__).parent.parent.parent.parent
14
15
  sys.path.insert(0, str(project_root))
15
16
 
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
17
+ from massgen.backend.response import ResponseBackend # noqa: E402
18
+ from massgen.chat_agent import SingleAgent # noqa: E402
19
+ from massgen.frontend.coordination_ui import CoordinationUI # noqa: E402
20
+ from massgen.orchestrator import Orchestrator # noqa: E402
20
21
 
21
22
 
22
23
  async def test_two_agents_coordination():
@@ -62,9 +63,7 @@ async def test_two_agents_coordination():
62
63
  print()
63
64
 
64
65
  # Test question that benefits from both perspectives
65
- test_question = (
66
- "How does photosynthesis work and why is it important for life on Earth?"
67
- )
66
+ test_question = "How does photosynthesis work and why is it important for life on Earth?"
68
67
 
69
68
  print(f"📝 Question: {test_question}")
70
69
  print("\n🎭 Starting two-agent coordination...")
@@ -117,9 +116,7 @@ async def test_two_agents_simple():
117
116
 
118
117
  print("📤 Testing simple coordination...")
119
118
 
120
- messages = [
121
- {"role": "user", "content": "What are the benefits of renewable energy?"}
122
- ]
119
+ messages = [{"role": "user", "content": "What are the benefits of renewable energy?"}]
123
120
 
124
121
  response_content = ""
125
122
  async for chunk in orchestrator.chat(messages):
@@ -132,9 +129,7 @@ async def test_two_agents_simple():
132
129
  elif chunk.type == "done":
133
130
  break
134
131
 
135
- print(
136
- f"\n✅ Simple test completed. Response length: {len(response_content)} characters"
137
- )
132
+ print(f"\n✅ Simple test completed. Response length: {len(response_content)} characters")
138
133
  return True
139
134
 
140
135
  except Exception as e:
@@ -0,0 +1,7 @@
1
+ # -*- coding: utf-8 -*-
2
+ from .token_manager import TokenCostCalculator, TokenUsage
3
+
4
+ __all__ = [
5
+ "TokenUsage",
6
+ "TokenCostCalculator",
7
+ ]