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
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Test script to verify MCP tool blocking in planning mode.
5
+ """
6
+
7
+ import asyncio
8
+ import os
9
+ import sys
10
+
11
+ from massgen.agent_config import AgentConfig
12
+ from massgen.backend.response import ResponseBackend
13
+
14
+ # Add the project root to sys.path to import massgen
15
+ sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", ".."))
16
+
17
+
18
+ async def test_mcp_blocking():
19
+ """Test that planning mode blocks MCP tool execution in the response backend."""
20
+
21
+ print("🧪 Testing MCP Tool Blocking in Planning Mode...")
22
+ print("=" * 50)
23
+
24
+ # Create agent config
25
+ agent_config = AgentConfig(
26
+ backend_params={
27
+ "backend_type": "response",
28
+ "model": "gpt-4",
29
+ "api_key": "dummy-key",
30
+ },
31
+ )
32
+
33
+ # Create backend instance
34
+ backend = ResponseBackend(config=agent_config)
35
+
36
+ # Test 1: Planning mode flag functionality
37
+ print("\n1. Testing planning mode flag...")
38
+ assert not backend.is_planning_mode_enabled(), "Planning mode should be disabled by default"
39
+ print("✅ Planning mode disabled by default")
40
+
41
+ backend.set_planning_mode(True)
42
+ assert backend.is_planning_mode_enabled(), "Planning mode should be enabled"
43
+ print("✅ Planning mode can be enabled")
44
+
45
+ backend.set_planning_mode(False)
46
+ assert not backend.is_planning_mode_enabled(), "Planning mode should be disabled"
47
+ print("✅ Planning mode can be disabled")
48
+
49
+ # Test 2: Check MCP blocking logic in response backend
50
+ print("\n2. Testing MCP tool execution blocking...")
51
+
52
+ # Simulate the logic that would happen in the MCP execution loop
53
+ backend.set_planning_mode(True)
54
+
55
+ # Check if planning mode blocks execution (simulating the condition in response.py)
56
+ if backend.is_planning_mode_enabled():
57
+ print("✅ MCP tools would be blocked in planning mode")
58
+ # This simulates the planning_mode_blocked status returned
59
+ mcp_status = "planning_mode_blocked"
60
+ else:
61
+ print("❌ MCP tools would NOT be blocked")
62
+ mcp_status = "executed"
63
+
64
+ assert mcp_status == "planning_mode_blocked", "MCP tools should be blocked in planning mode"
65
+ print("✅ MCP tool blocking logic works correctly")
66
+
67
+ # Test 3: Verify execution is allowed when planning mode is disabled
68
+ print("\n3. Testing MCP tool execution when planning mode disabled...")
69
+ backend.set_planning_mode(False)
70
+
71
+ if backend.is_planning_mode_enabled():
72
+ mcp_status = "planning_mode_blocked"
73
+ else:
74
+ mcp_status = "would_execute"
75
+
76
+ assert mcp_status == "would_execute", "MCP tools should execute when planning mode is disabled"
77
+ print("✅ MCP tools would execute when planning mode is disabled")
78
+
79
+ print("\n🎉 All MCP blocking tests passed!")
80
+ print("✅ Backend-level planning mode implementation is working correctly")
81
+ return True
82
+
83
+
84
+ async def test_backend_inheritance():
85
+ """Test that all backend types inherit planning mode functionality."""
86
+
87
+ print("\n🧪 Testing Backend Inheritance...")
88
+ print("=" * 30)
89
+
90
+ # Test ResponseBackend
91
+ from massgen.backend.response import ResponseBackend
92
+
93
+ response_config = AgentConfig(backend_params={"backend_type": "response", "model": "gpt-4", "api_key": "dummy"})
94
+ response_backend = ResponseBackend(config=response_config)
95
+
96
+ # Check that methods exist
97
+ assert hasattr(response_backend, "set_planning_mode"), "ResponseBackend should have set_planning_mode"
98
+ assert hasattr(response_backend, "is_planning_mode_enabled"), "ResponseBackend should have is_planning_mode_enabled"
99
+ print("✅ ResponseBackend has planning mode methods")
100
+
101
+ # Test Gemini backend
102
+ try:
103
+ from massgen.backend.gemini import GeminiBackend
104
+
105
+ gemini_config = AgentConfig(backend_params={"backend_type": "gemini", "model": "gemini-1.5-pro", "api_key": "dummy"})
106
+ gemini_backend = GeminiBackend(config=gemini_config)
107
+
108
+ assert hasattr(gemini_backend, "set_planning_mode"), "GeminiBackend should have set_planning_mode"
109
+ assert hasattr(gemini_backend, "is_planning_mode_enabled"), "GeminiBackend should have is_planning_mode_enabled"
110
+ print("✅ GeminiBackend has planning mode methods")
111
+ except Exception as e:
112
+ print(f"⚠️ Could not test GeminiBackend: {e}")
113
+
114
+ print("✅ Backend inheritance working correctly")
115
+
116
+
117
+ if __name__ == "__main__":
118
+
119
+ async def main():
120
+ success1 = await test_mcp_blocking()
121
+ await test_backend_inheritance()
122
+ return success1
123
+
124
+ success = asyncio.run(main())
125
+ sys.exit(0 if success else 1)
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
2
3
  """
3
4
  Test script to examine how conversation context is built for LLM input.
4
5
  Shows the exact message templates and context structure without making API calls.
@@ -6,13 +7,13 @@ Shows the exact message templates and context structure without making API calls
6
7
 
7
8
  import sys
8
9
  from pathlib import Path
9
- from typing import Dict, List, Any
10
+ from typing import Any, Dict
10
11
 
11
12
  # Add project root to path
12
13
  project_root = Path(__file__).parent.parent.parent.parent
13
14
  sys.path.insert(0, str(project_root))
14
15
 
15
- from massgen.message_templates import MessageTemplates
16
+ from massgen.message_templates import MessageTemplates # noqa: E402
16
17
 
17
18
 
18
19
  def print_message_structure(title: str, conversation: Dict[str, Any]):
@@ -28,13 +29,13 @@ def print_message_structure(title: str, conversation: Dict[str, Any]):
28
29
  print(system_msg)
29
30
 
30
31
  # User message
31
- print(f"\n📨 USER MESSAGE:")
32
+ print("\n📨 USER MESSAGE:")
32
33
  print("-" * 40)
33
34
  user_msg = conversation["user_message"]
34
35
  print(user_msg)
35
36
 
36
37
  # Tools
37
- print(f"\n🔧 TOOLS PROVIDED:")
38
+ print("\n🔧 TOOLS PROVIDED:")
38
39
  print("-" * 40)
39
40
  tools = conversation.get("tools", [])
40
41
  for i, tool in enumerate(tools, 1):
@@ -42,7 +43,7 @@ def print_message_structure(title: str, conversation: Dict[str, Any]):
42
43
  tool_desc = tool.get("function", {}).get("description", "No description")
43
44
  print(f"{i}. {tool_name}: {tool_desc}")
44
45
 
45
- print(f"\n📊 STATISTICS:")
46
+ print("\n📊 STATISTICS:")
46
47
  print(f" System message length: {len(system_msg)} chars")
47
48
  print(f" User message length: {len(user_msg)} chars")
48
49
  print(f" Tools provided: {len(tools)}")
@@ -70,22 +71,18 @@ def test_turn1_context():
70
71
  user_msg = conversation["user_message"]
71
72
  has_history = "CONVERSATION_HISTORY" in user_msg
72
73
  has_original = "ORIGINAL MESSAGE" in user_msg
73
- has_answers = (
74
- "CURRENT ANSWERS" in user_msg and "no answers available yet" in user_msg
75
- )
74
+ has_answers = "CURRENT ANSWERS" in user_msg and "no answers available yet" in user_msg
76
75
 
77
- print(f"\n✅ VALIDATION:")
76
+ print("\n✅ VALIDATION:")
78
77
  print(f" Contains conversation history section: {has_history}")
79
78
  print(f" Contains original message section: {has_original}")
80
79
  print(f" Contains empty answers section: {has_answers}")
81
- print(
82
- f" System message mentions context: {'conversation' in conversation['system_message'].lower()}"
83
- )
80
+ print(f" System message mentions context: {'conversation' in conversation['system_message'].lower()}")
84
81
 
85
82
 
86
83
  def test_turn2_context():
87
84
  """Test context building for the second turn (with history)."""
88
- print(f"\n🔷 TURN 2 CONTEXT BUILDING")
85
+ print("\n🔷 TURN 2 CONTEXT BUILDING")
89
86
  print("Scenario: User asks follow-up, with previous exchange in history")
90
87
 
91
88
  templates = MessageTemplates()
@@ -95,7 +92,11 @@ def test_turn2_context():
95
92
  {"role": "user", "content": "What are the main benefits of renewable energy?"},
96
93
  {
97
94
  "role": "assistant",
98
- "content": "Renewable energy offers several key benefits including environmental sustainability, economic advantages, and energy security. It reduces greenhouse gas emissions, creates jobs, and decreases dependence on fossil fuel imports.",
95
+ "content": (
96
+ "Renewable energy offers several key benefits including environmental "
97
+ "sustainability, economic advantages, and energy security. It reduces "
98
+ "greenhouse gas emissions, creates jobs, and decreases dependence on fossil fuel imports."
99
+ ),
99
100
  },
100
101
  ]
101
102
 
@@ -103,9 +104,7 @@ def test_turn2_context():
103
104
  conversation = templates.build_conversation_with_context(
104
105
  current_task="What about the challenges and limitations?",
105
106
  conversation_history=conversation_history,
106
- agent_summaries={
107
- "researcher": "Key benefits include environmental and economic advantages."
108
- },
107
+ agent_summaries={"researcher": "Key benefits include environmental and economic advantages."},
109
108
  valid_agent_ids=["researcher"],
110
109
  )
111
110
 
@@ -113,27 +112,20 @@ def test_turn2_context():
113
112
 
114
113
  # Verify structure
115
114
  user_msg = conversation["user_message"]
116
- has_history = (
117
- "CONVERSATION_HISTORY" in user_msg
118
- and "User: What are the main benefits" in user_msg
119
- )
120
- has_original = (
121
- "ORIGINAL MESSAGE" in user_msg and "challenges and limitations" in user_msg
122
- )
115
+ has_history = "CONVERSATION_HISTORY" in user_msg and "User: What are the main benefits" in user_msg
116
+ has_original = "ORIGINAL MESSAGE" in user_msg and "challenges and limitations" in user_msg
123
117
  has_answers = "CURRENT ANSWERS" in user_msg and "researcher" in user_msg
124
118
 
125
- print(f"\n✅ VALIDATION:")
119
+ print("\n✅ VALIDATION:")
126
120
  print(f" Contains conversation history: {has_history}")
127
121
  print(f" Contains current question: {has_original}")
128
122
  print(f" Contains agent answers: {has_answers}")
129
- print(
130
- f" System message is context-aware: {'conversation' in conversation['system_message'].lower()}"
131
- )
123
+ print(f" System message is context-aware: {'conversation' in conversation['system_message'].lower()}")
132
124
 
133
125
 
134
126
  def test_turn3_context():
135
127
  """Test context building for the third turn (extended history)."""
136
- print(f"\n🔷 TURN 3 CONTEXT BUILDING")
128
+ print("\n🔷 TURN 3 CONTEXT BUILDING")
137
129
  print("Scenario: User asks third question, with extended conversation history")
138
130
 
139
131
  templates = MessageTemplates()
@@ -167,17 +159,11 @@ def test_turn3_context():
167
159
 
168
160
  # Verify structure
169
161
  user_msg = conversation["user_message"]
170
- has_full_history = (
171
- "CONVERSATION_HISTORY" in user_msg and user_msg.count("User:") >= 2
172
- )
162
+ has_full_history = "CONVERSATION_HISTORY" in user_msg and user_msg.count("User:") >= 2
173
163
  has_original = "ORIGINAL MESSAGE" in user_msg and "governments support" in user_msg
174
- has_multiple_answers = (
175
- "CURRENT ANSWERS" in user_msg
176
- and "researcher" in user_msg
177
- and "analyst" in user_msg
178
- )
164
+ has_multiple_answers = "CURRENT ANSWERS" in user_msg and "researcher" in user_msg and "analyst" in user_msg
179
165
 
180
- print(f"\n✅ VALIDATION:")
166
+ print("\n✅ VALIDATION:")
181
167
  print(f" Contains full conversation history: {has_full_history}")
182
168
  print(f" Contains current question: {has_original}")
183
169
  print(f" Contains multiple agent answers: {has_multiple_answers}")
@@ -186,7 +172,7 @@ def test_turn3_context():
186
172
 
187
173
  def test_context_comparison():
188
174
  """Compare context building across different turns."""
189
- print(f"\n🔍 CONTEXT COMPARISON ACROSS TURNS")
175
+ print("\n🔍 CONTEXT COMPARISON ACROSS TURNS")
190
176
  print("=" * 80)
191
177
 
192
178
  templates = MessageTemplates()
@@ -209,9 +195,7 @@ def test_context_comparison():
209
195
  conv2 = templates.build_conversation_with_context(
210
196
  current_task="How efficient is it?",
211
197
  conversation_history=history,
212
- agent_summaries={
213
- "expert": "Solar energy harnesses sunlight for power generation."
214
- },
198
+ agent_summaries={"expert": "Solar energy harnesses sunlight for power generation."},
215
199
  )
216
200
 
217
201
  # Turn 3: Extended history
@@ -241,12 +225,10 @@ def test_context_comparison():
241
225
  print(f" Turn 2 (with history): {len(conv2['user_message']):,} chars")
242
226
  print(f" Turn 3 (extended): {len(conv3['user_message']):,} chars")
243
227
 
244
- print(f"\n📈 CONTEXT ELEMENTS:")
228
+ print("\n📈 CONTEXT ELEMENTS:")
245
229
  elements = ["CONVERSATION_HISTORY", "ORIGINAL MESSAGE", "CURRENT ANSWERS"]
246
230
 
247
- for i, (conv, turn) in enumerate(
248
- [(conv1, "Turn 1"), (conv2, "Turn 2"), (conv3, "Turn 3")], 1
249
- ):
231
+ for i, (conv, turn) in enumerate([(conv1, "Turn 1"), (conv2, "Turn 2"), (conv3, "Turn 3")], 1):
250
232
  user_msg = conv["user_message"]
251
233
  print(f"\n {turn}:")
252
234
  for element in elements:
@@ -274,7 +256,7 @@ def main():
274
256
  test_turn3_context()
275
257
  test_context_comparison()
276
258
 
277
- print(f"\n🎉 ALL CONTEXT BUILDING TESTS COMPLETED")
259
+ print("\n🎉 ALL CONTEXT BUILDING TESTS COMPLETED")
278
260
  print("=" * 80)
279
261
  print("✅ Message templates properly build conversation context")
280
262
  print("✅ Context grows appropriately with conversation history")
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Simple tests for orchestrator's get_final_presentation method shape and imports.
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ import pytest
9
+
10
+ # Ensure project root is on sys.path
11
+ PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
12
+ if PROJECT_ROOT not in sys.path:
13
+ sys.path.insert(0, PROJECT_ROOT)
14
+
15
+
16
+ def test_orchestrator_import():
17
+ from massgen.orchestrator import Orchestrator
18
+
19
+ assert Orchestrator is not None
20
+
21
+
22
+ def test_get_final_presentation_method():
23
+ from massgen.orchestrator import Orchestrator
24
+ import inspect
25
+
26
+ assert hasattr(Orchestrator, "get_final_presentation")
27
+ sig = inspect.signature(Orchestrator.get_final_presentation)
28
+ assert list(sig.parameters.keys()) == ["self", "selected_agent_id", "vote_results"]
29
+
30
+
31
+ def test_stream_chunk_import():
32
+ from massgen.backend.base import StreamChunk
33
+
34
+ assert StreamChunk is not None
35
+
36
+
37
+ def test_message_templates_import():
38
+ from massgen.message_templates import MessageTemplates
39
+
40
+ assert MessageTemplates is not None
41
+
42
+
43
+ @pytest.mark.asyncio
44
+ async def test_orchestrator_initialization():
45
+ from massgen.orchestrator import Orchestrator
46
+
47
+ orchestrator = Orchestrator(agents={})
48
+ assert orchestrator is not None