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.
- massgen/__init__.py +142 -8
- massgen/adapters/__init__.py +29 -0
- massgen/adapters/ag2_adapter.py +483 -0
- massgen/adapters/base.py +183 -0
- massgen/adapters/tests/__init__.py +0 -0
- massgen/adapters/tests/test_ag2_adapter.py +439 -0
- massgen/adapters/tests/test_agent_adapter.py +128 -0
- massgen/adapters/utils/__init__.py +2 -0
- massgen/adapters/utils/ag2_utils.py +236 -0
- massgen/adapters/utils/tests/__init__.py +0 -0
- massgen/adapters/utils/tests/test_ag2_utils.py +138 -0
- massgen/agent_config.py +329 -55
- massgen/api_params_handler/__init__.py +10 -0
- massgen/api_params_handler/_api_params_handler_base.py +99 -0
- massgen/api_params_handler/_chat_completions_api_params_handler.py +176 -0
- massgen/api_params_handler/_claude_api_params_handler.py +113 -0
- massgen/api_params_handler/_response_api_params_handler.py +130 -0
- massgen/backend/__init__.py +39 -4
- massgen/backend/azure_openai.py +385 -0
- massgen/backend/base.py +341 -69
- massgen/backend/base_with_mcp.py +1102 -0
- massgen/backend/capabilities.py +386 -0
- massgen/backend/chat_completions.py +577 -130
- massgen/backend/claude.py +1033 -537
- massgen/backend/claude_code.py +1203 -0
- massgen/backend/cli_base.py +209 -0
- massgen/backend/docs/BACKEND_ARCHITECTURE.md +126 -0
- massgen/backend/{CLAUDE_API_RESEARCH.md → docs/CLAUDE_API_RESEARCH.md} +18 -18
- massgen/backend/{GEMINI_API_DOCUMENTATION.md → docs/GEMINI_API_DOCUMENTATION.md} +9 -9
- massgen/backend/docs/Gemini MCP Integration Analysis.md +1050 -0
- massgen/backend/docs/MCP_IMPLEMENTATION_CLAUDE_BACKEND.md +177 -0
- massgen/backend/docs/MCP_INTEGRATION_RESPONSE_BACKEND.md +352 -0
- massgen/backend/docs/OPENAI_GPT5_MODELS.md +211 -0
- massgen/backend/{OPENAI_RESPONSES_API_FORMAT.md → docs/OPENAI_RESPONSE_API_TOOL_CALLS.md} +3 -3
- massgen/backend/docs/OPENAI_response_streaming.md +20654 -0
- massgen/backend/docs/inference_backend.md +257 -0
- massgen/backend/docs/permissions_and_context_files.md +1085 -0
- massgen/backend/external.py +126 -0
- massgen/backend/gemini.py +1850 -241
- massgen/backend/grok.py +40 -156
- massgen/backend/inference.py +156 -0
- massgen/backend/lmstudio.py +171 -0
- massgen/backend/response.py +1095 -322
- massgen/chat_agent.py +131 -113
- massgen/cli.py +1560 -275
- massgen/config_builder.py +2396 -0
- massgen/configs/BACKEND_CONFIGURATION.md +458 -0
- massgen/configs/README.md +559 -216
- massgen/configs/ag2/ag2_case_study.yaml +27 -0
- massgen/configs/ag2/ag2_coder.yaml +34 -0
- massgen/configs/ag2/ag2_coder_case_study.yaml +36 -0
- massgen/configs/ag2/ag2_gemini.yaml +27 -0
- massgen/configs/ag2/ag2_groupchat.yaml +108 -0
- massgen/configs/ag2/ag2_groupchat_gpt.yaml +118 -0
- massgen/configs/ag2/ag2_single_agent.yaml +21 -0
- massgen/configs/basic/multi/fast_timeout_example.yaml +37 -0
- massgen/configs/basic/multi/gemini_4o_claude.yaml +31 -0
- massgen/configs/basic/multi/gemini_gpt5nano_claude.yaml +36 -0
- massgen/configs/{gemini_4o_claude.yaml → basic/multi/geminicode_4o_claude.yaml} +3 -3
- massgen/configs/basic/multi/geminicode_gpt5nano_claude.yaml +36 -0
- massgen/configs/basic/multi/glm_gemini_claude.yaml +25 -0
- massgen/configs/basic/multi/gpt4o_audio_generation.yaml +30 -0
- massgen/configs/basic/multi/gpt4o_image_generation.yaml +31 -0
- massgen/configs/basic/multi/gpt5nano_glm_qwen.yaml +26 -0
- massgen/configs/basic/multi/gpt5nano_image_understanding.yaml +26 -0
- massgen/configs/{three_agents_default.yaml → basic/multi/three_agents_default.yaml} +8 -4
- massgen/configs/basic/multi/three_agents_opensource.yaml +27 -0
- massgen/configs/basic/multi/three_agents_vllm.yaml +20 -0
- massgen/configs/basic/multi/two_agents_gemini.yaml +19 -0
- massgen/configs/{two_agents.yaml → basic/multi/two_agents_gpt5.yaml} +14 -6
- massgen/configs/basic/multi/two_agents_opensource_lmstudio.yaml +31 -0
- massgen/configs/basic/multi/two_qwen_vllm_sglang.yaml +28 -0
- massgen/configs/{single_agent.yaml → basic/single/single_agent.yaml} +1 -1
- massgen/configs/{single_flash2.5.yaml → basic/single/single_flash2.5.yaml} +1 -2
- massgen/configs/basic/single/single_gemini2.5pro.yaml +16 -0
- massgen/configs/basic/single/single_gpt4o_audio_generation.yaml +22 -0
- massgen/configs/basic/single/single_gpt4o_image_generation.yaml +22 -0
- massgen/configs/basic/single/single_gpt4o_video_generation.yaml +24 -0
- massgen/configs/basic/single/single_gpt5nano.yaml +20 -0
- massgen/configs/basic/single/single_gpt5nano_file_search.yaml +18 -0
- massgen/configs/basic/single/single_gpt5nano_image_understanding.yaml +17 -0
- massgen/configs/basic/single/single_gptoss120b.yaml +15 -0
- massgen/configs/basic/single/single_openrouter_audio_understanding.yaml +15 -0
- massgen/configs/basic/single/single_qwen_video_understanding.yaml +15 -0
- massgen/configs/debug/code_execution/command_filtering_blacklist.yaml +29 -0
- massgen/configs/debug/code_execution/command_filtering_whitelist.yaml +28 -0
- massgen/configs/debug/code_execution/docker_verification.yaml +29 -0
- massgen/configs/debug/skip_coordination_test.yaml +27 -0
- massgen/configs/debug/test_sdk_migration.yaml +17 -0
- massgen/configs/docs/DISCORD_MCP_SETUP.md +208 -0
- massgen/configs/docs/TWITTER_MCP_ENESCINAR_SETUP.md +82 -0
- massgen/configs/providers/azure/azure_openai_multi.yaml +21 -0
- massgen/configs/providers/azure/azure_openai_single.yaml +19 -0
- massgen/configs/providers/claude/claude.yaml +14 -0
- massgen/configs/providers/gemini/gemini_gpt5nano.yaml +28 -0
- massgen/configs/providers/local/lmstudio.yaml +11 -0
- massgen/configs/providers/openai/gpt5.yaml +46 -0
- massgen/configs/providers/openai/gpt5_nano.yaml +46 -0
- massgen/configs/providers/others/grok_single_agent.yaml +19 -0
- massgen/configs/providers/others/zai_coding_team.yaml +108 -0
- massgen/configs/providers/others/zai_glm45.yaml +12 -0
- massgen/configs/{creative_team.yaml → teams/creative/creative_team.yaml} +16 -6
- massgen/configs/{travel_planning.yaml → teams/creative/travel_planning.yaml} +16 -6
- massgen/configs/{news_analysis.yaml → teams/research/news_analysis.yaml} +16 -6
- massgen/configs/{research_team.yaml → teams/research/research_team.yaml} +15 -7
- massgen/configs/{technical_analysis.yaml → teams/research/technical_analysis.yaml} +16 -6
- massgen/configs/tools/code-execution/basic_command_execution.yaml +25 -0
- massgen/configs/tools/code-execution/code_execution_use_case_simple.yaml +41 -0
- massgen/configs/tools/code-execution/docker_claude_code.yaml +32 -0
- massgen/configs/tools/code-execution/docker_multi_agent.yaml +32 -0
- massgen/configs/tools/code-execution/docker_simple.yaml +29 -0
- massgen/configs/tools/code-execution/docker_with_resource_limits.yaml +32 -0
- massgen/configs/tools/code-execution/multi_agent_playwright_automation.yaml +57 -0
- massgen/configs/tools/filesystem/cc_gpt5_gemini_filesystem.yaml +34 -0
- massgen/configs/tools/filesystem/claude_code_context_sharing.yaml +68 -0
- massgen/configs/tools/filesystem/claude_code_flash2.5.yaml +43 -0
- massgen/configs/tools/filesystem/claude_code_flash2.5_gptoss.yaml +49 -0
- massgen/configs/tools/filesystem/claude_code_gpt5nano.yaml +31 -0
- massgen/configs/tools/filesystem/claude_code_single.yaml +40 -0
- massgen/configs/tools/filesystem/fs_permissions_test.yaml +87 -0
- massgen/configs/tools/filesystem/gemini_gemini_workspace_cleanup.yaml +54 -0
- massgen/configs/tools/filesystem/gemini_gpt5_filesystem_casestudy.yaml +30 -0
- massgen/configs/tools/filesystem/gemini_gpt5nano_file_context_path.yaml +43 -0
- massgen/configs/tools/filesystem/gemini_gpt5nano_protected_paths.yaml +45 -0
- massgen/configs/tools/filesystem/gpt5mini_cc_fs_context_path.yaml +31 -0
- massgen/configs/tools/filesystem/grok4_gpt5_gemini_filesystem.yaml +32 -0
- massgen/configs/tools/filesystem/multiturn/grok4_gpt5_claude_code_filesystem_multiturn.yaml +58 -0
- massgen/configs/tools/filesystem/multiturn/grok4_gpt5_gemini_filesystem_multiturn.yaml +58 -0
- massgen/configs/tools/filesystem/multiturn/two_claude_code_filesystem_multiturn.yaml +47 -0
- massgen/configs/tools/filesystem/multiturn/two_gemini_flash_filesystem_multiturn.yaml +48 -0
- massgen/configs/tools/mcp/claude_code_discord_mcp_example.yaml +27 -0
- massgen/configs/tools/mcp/claude_code_simple_mcp.yaml +35 -0
- massgen/configs/tools/mcp/claude_code_twitter_mcp_example.yaml +32 -0
- massgen/configs/tools/mcp/claude_mcp_example.yaml +24 -0
- massgen/configs/tools/mcp/claude_mcp_test.yaml +27 -0
- massgen/configs/tools/mcp/five_agents_travel_mcp_test.yaml +157 -0
- massgen/configs/tools/mcp/five_agents_weather_mcp_test.yaml +103 -0
- massgen/configs/tools/mcp/gemini_mcp_example.yaml +24 -0
- massgen/configs/tools/mcp/gemini_mcp_filesystem_test.yaml +23 -0
- massgen/configs/tools/mcp/gemini_mcp_filesystem_test_sharing.yaml +23 -0
- massgen/configs/tools/mcp/gemini_mcp_filesystem_test_single_agent.yaml +17 -0
- massgen/configs/tools/mcp/gemini_mcp_filesystem_test_with_claude_code.yaml +24 -0
- massgen/configs/tools/mcp/gemini_mcp_test.yaml +27 -0
- massgen/configs/tools/mcp/gemini_notion_mcp.yaml +52 -0
- massgen/configs/tools/mcp/gpt5_nano_mcp_example.yaml +24 -0
- massgen/configs/tools/mcp/gpt5_nano_mcp_test.yaml +27 -0
- massgen/configs/tools/mcp/gpt5mini_claude_code_discord_mcp_example.yaml +38 -0
- massgen/configs/tools/mcp/gpt_oss_mcp_example.yaml +25 -0
- massgen/configs/tools/mcp/gpt_oss_mcp_test.yaml +28 -0
- massgen/configs/tools/mcp/grok3_mini_mcp_example.yaml +24 -0
- massgen/configs/tools/mcp/grok3_mini_mcp_test.yaml +27 -0
- massgen/configs/tools/mcp/multimcp_gemini.yaml +111 -0
- massgen/configs/tools/mcp/qwen_api_mcp_example.yaml +25 -0
- massgen/configs/tools/mcp/qwen_api_mcp_test.yaml +28 -0
- massgen/configs/tools/mcp/qwen_local_mcp_example.yaml +24 -0
- massgen/configs/tools/mcp/qwen_local_mcp_test.yaml +27 -0
- massgen/configs/tools/planning/five_agents_discord_mcp_planning_mode.yaml +140 -0
- massgen/configs/tools/planning/five_agents_filesystem_mcp_planning_mode.yaml +151 -0
- massgen/configs/tools/planning/five_agents_notion_mcp_planning_mode.yaml +151 -0
- massgen/configs/tools/planning/five_agents_twitter_mcp_planning_mode.yaml +155 -0
- massgen/configs/tools/planning/gpt5_mini_case_study_mcp_planning_mode.yaml +73 -0
- massgen/configs/tools/web-search/claude_streamable_http_test.yaml +43 -0
- massgen/configs/tools/web-search/gemini_streamable_http_test.yaml +43 -0
- massgen/configs/tools/web-search/gpt5_mini_streamable_http_test.yaml +43 -0
- massgen/configs/tools/web-search/gpt_oss_streamable_http_test.yaml +44 -0
- massgen/configs/tools/web-search/grok3_mini_streamable_http_test.yaml +43 -0
- massgen/configs/tools/web-search/qwen_api_streamable_http_test.yaml +44 -0
- massgen/configs/tools/web-search/qwen_local_streamable_http_test.yaml +43 -0
- massgen/coordination_tracker.py +708 -0
- massgen/docker/README.md +462 -0
- massgen/filesystem_manager/__init__.py +21 -0
- massgen/filesystem_manager/_base.py +9 -0
- massgen/filesystem_manager/_code_execution_server.py +545 -0
- massgen/filesystem_manager/_docker_manager.py +477 -0
- massgen/filesystem_manager/_file_operation_tracker.py +248 -0
- massgen/filesystem_manager/_filesystem_manager.py +813 -0
- massgen/filesystem_manager/_path_permission_manager.py +1261 -0
- massgen/filesystem_manager/_workspace_tools_server.py +1815 -0
- massgen/formatter/__init__.py +10 -0
- massgen/formatter/_chat_completions_formatter.py +284 -0
- massgen/formatter/_claude_formatter.py +235 -0
- massgen/formatter/_formatter_base.py +156 -0
- massgen/formatter/_response_formatter.py +263 -0
- massgen/frontend/__init__.py +1 -2
- massgen/frontend/coordination_ui.py +471 -286
- massgen/frontend/displays/base_display.py +56 -11
- massgen/frontend/displays/create_coordination_table.py +1956 -0
- massgen/frontend/displays/rich_terminal_display.py +1259 -619
- massgen/frontend/displays/simple_display.py +9 -4
- massgen/frontend/displays/terminal_display.py +27 -68
- massgen/logger_config.py +681 -0
- massgen/mcp_tools/README.md +232 -0
- massgen/mcp_tools/__init__.py +105 -0
- massgen/mcp_tools/backend_utils.py +1035 -0
- massgen/mcp_tools/circuit_breaker.py +195 -0
- massgen/mcp_tools/client.py +894 -0
- massgen/mcp_tools/config_validator.py +138 -0
- massgen/mcp_tools/docs/circuit_breaker.md +646 -0
- massgen/mcp_tools/docs/client.md +950 -0
- massgen/mcp_tools/docs/config_validator.md +478 -0
- massgen/mcp_tools/docs/exceptions.md +1165 -0
- massgen/mcp_tools/docs/security.md +854 -0
- massgen/mcp_tools/exceptions.py +338 -0
- massgen/mcp_tools/hooks.py +212 -0
- massgen/mcp_tools/security.py +780 -0
- massgen/message_templates.py +342 -64
- massgen/orchestrator.py +1515 -241
- massgen/stream_chunk/__init__.py +35 -0
- massgen/stream_chunk/base.py +92 -0
- massgen/stream_chunk/multimodal.py +237 -0
- massgen/stream_chunk/text.py +162 -0
- massgen/tests/mcp_test_server.py +150 -0
- massgen/tests/multi_turn_conversation_design.md +0 -8
- massgen/tests/test_azure_openai_backend.py +156 -0
- massgen/tests/test_backend_capabilities.py +262 -0
- massgen/tests/test_backend_event_loop_all.py +179 -0
- massgen/tests/test_chat_completions_refactor.py +142 -0
- massgen/tests/test_claude_backend.py +15 -28
- massgen/tests/test_claude_code.py +268 -0
- massgen/tests/test_claude_code_context_sharing.py +233 -0
- massgen/tests/test_claude_code_orchestrator.py +175 -0
- massgen/tests/test_cli_backends.py +180 -0
- massgen/tests/test_code_execution.py +679 -0
- massgen/tests/test_external_agent_backend.py +134 -0
- massgen/tests/test_final_presentation_fallback.py +237 -0
- massgen/tests/test_gemini_planning_mode.py +351 -0
- massgen/tests/test_grok_backend.py +7 -10
- massgen/tests/test_http_mcp_server.py +42 -0
- massgen/tests/test_integration_simple.py +198 -0
- massgen/tests/test_mcp_blocking.py +125 -0
- massgen/tests/test_message_context_building.py +29 -47
- massgen/tests/test_orchestrator_final_presentation.py +48 -0
- massgen/tests/test_path_permission_manager.py +2087 -0
- massgen/tests/test_rich_terminal_display.py +14 -13
- massgen/tests/test_timeout.py +133 -0
- massgen/tests/test_v3_3agents.py +11 -12
- massgen/tests/test_v3_simple.py +8 -13
- massgen/tests/test_v3_three_agents.py +11 -18
- massgen/tests/test_v3_two_agents.py +8 -13
- massgen/token_manager/__init__.py +7 -0
- massgen/token_manager/token_manager.py +400 -0
- massgen/utils.py +52 -16
- massgen/v1/agent.py +45 -91
- massgen/v1/agents.py +18 -53
- massgen/v1/backends/gemini.py +50 -153
- massgen/v1/backends/grok.py +21 -54
- massgen/v1/backends/oai.py +39 -111
- massgen/v1/cli.py +36 -93
- massgen/v1/config.py +8 -12
- massgen/v1/logging.py +43 -127
- massgen/v1/main.py +18 -32
- massgen/v1/orchestrator.py +68 -209
- massgen/v1/streaming_display.py +62 -163
- massgen/v1/tools.py +8 -12
- massgen/v1/types.py +9 -23
- massgen/v1/utils.py +5 -23
- massgen-0.1.0.dist-info/METADATA +1245 -0
- massgen-0.1.0.dist-info/RECORD +273 -0
- massgen-0.1.0.dist-info/entry_points.txt +2 -0
- massgen/frontend/logging/__init__.py +0 -9
- massgen/frontend/logging/realtime_logger.py +0 -197
- massgen-0.0.3.dist-info/METADATA +0 -568
- massgen-0.0.3.dist-info/RECORD +0 -76
- massgen-0.0.3.dist-info/entry_points.txt +0 -2
- /massgen/backend/{Function calling openai responses.md → docs/Function calling openai responses.md} +0 -0
- {massgen-0.0.3.dist-info → massgen-0.1.0.dist-info}/WHEEL +0 -0
- {massgen-0.0.3.dist-info → massgen-0.1.0.dist-info}/licenses/LICENSE +0 -0
- {massgen-0.0.3.dist-info → massgen-0.1.0.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
"""
|
|
2
3
|
Simple Display for MassGen Coordination
|
|
3
4
|
|
|
@@ -5,6 +6,7 @@ Basic text output display for minimal use cases and debugging.
|
|
|
5
6
|
"""
|
|
6
7
|
|
|
7
8
|
from typing import Optional
|
|
9
|
+
|
|
8
10
|
from .base_display import BaseDisplay
|
|
9
11
|
|
|
10
12
|
|
|
@@ -25,9 +27,7 @@ class SimpleDisplay(BaseDisplay):
|
|
|
25
27
|
print(f"👥 Agents: {', '.join(self.agent_ids)}")
|
|
26
28
|
print("=" * 50)
|
|
27
29
|
|
|
28
|
-
def update_agent_content(
|
|
29
|
-
self, agent_id: str, content: str, content_type: str = "thinking"
|
|
30
|
-
):
|
|
30
|
+
def update_agent_content(self, agent_id: str, content: str, content_type: str = "thinking"):
|
|
31
31
|
"""Update content for a specific agent."""
|
|
32
32
|
if agent_id not in self.agent_ids:
|
|
33
33
|
return
|
|
@@ -79,10 +79,15 @@ class SimpleDisplay(BaseDisplay):
|
|
|
79
79
|
if self.show_events:
|
|
80
80
|
print(f"🎭 {event}")
|
|
81
81
|
|
|
82
|
-
def show_final_answer(self, answer: str):
|
|
82
|
+
def show_final_answer(self, answer: str, vote_results=None, selected_agent=None):
|
|
83
83
|
"""Display the final coordinated answer."""
|
|
84
84
|
print("\n" + "=" * 50)
|
|
85
85
|
print(f"🎯 FINAL ANSWER: {answer}")
|
|
86
|
+
if selected_agent:
|
|
87
|
+
print(f"✅ Selected by: {selected_agent}")
|
|
88
|
+
if vote_results:
|
|
89
|
+
vote_summary = ", ".join([f"{agent}: {votes}" for agent, votes in vote_results.items()])
|
|
90
|
+
print(f"🗳️ Vote results: {vote_summary}")
|
|
86
91
|
print("=" * 50)
|
|
87
92
|
|
|
88
93
|
def cleanup(self):
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
"""
|
|
2
3
|
Terminal Display for MassGen Coordination
|
|
3
4
|
|
|
@@ -6,6 +7,7 @@ Rich terminal interface with live updates, agent columns, and coordination event
|
|
|
6
7
|
|
|
7
8
|
import os
|
|
8
9
|
from typing import List, Optional
|
|
10
|
+
|
|
9
11
|
from .base_display import BaseDisplay
|
|
10
12
|
|
|
11
13
|
|
|
@@ -36,9 +38,7 @@ class TerminalDisplay(BaseDisplay):
|
|
|
36
38
|
self.col_width = (self.terminal_width - 3) // 2
|
|
37
39
|
self.separators = " │ "
|
|
38
40
|
else:
|
|
39
|
-
self.col_width = (
|
|
40
|
-
self.terminal_width - (self.num_agents - 1) * 3
|
|
41
|
-
) // self.num_agents
|
|
41
|
+
self.col_width = (self.terminal_width - (self.num_agents - 1) * 3) // self.num_agents
|
|
42
42
|
self.separators = " │ "
|
|
43
43
|
|
|
44
44
|
def _get_terminal_width(self) -> int:
|
|
@@ -57,7 +57,7 @@ class TerminalDisplay(BaseDisplay):
|
|
|
57
57
|
|
|
58
58
|
try:
|
|
59
59
|
os.system("clear" if os.name == "posix" else "cls")
|
|
60
|
-
except:
|
|
60
|
+
except Exception:
|
|
61
61
|
print("\033[2J\033[H", end="")
|
|
62
62
|
|
|
63
63
|
title = f"🚀 {'Multi' if self.num_agents > 2 else 'Two' if self.num_agents == 2 else 'Single'}-Agent Coordination Dashboard"
|
|
@@ -73,20 +73,12 @@ class TerminalDisplay(BaseDisplay):
|
|
|
73
73
|
for agent_id in self.agent_ids:
|
|
74
74
|
# Try to get backend info from orchestrator if available
|
|
75
75
|
backend_name = "Unknown"
|
|
76
|
-
if (
|
|
77
|
-
hasattr(self, "orchestrator")
|
|
78
|
-
and self.orchestrator
|
|
79
|
-
and hasattr(self.orchestrator, "agents")
|
|
80
|
-
):
|
|
76
|
+
if hasattr(self, "orchestrator") and self.orchestrator and hasattr(self.orchestrator, "agents"):
|
|
81
77
|
agent = self.orchestrator.agents.get(agent_id)
|
|
82
|
-
if (
|
|
83
|
-
agent
|
|
84
|
-
and hasattr(agent, "backend")
|
|
85
|
-
and hasattr(agent.backend, "get_provider_name")
|
|
86
|
-
):
|
|
78
|
+
if agent and hasattr(agent, "backend") and hasattr(agent.backend, "get_provider_name"):
|
|
87
79
|
try:
|
|
88
80
|
backend_name = agent.backend.get_provider_name()
|
|
89
|
-
except:
|
|
81
|
+
except Exception:
|
|
90
82
|
backend_name = "Unknown"
|
|
91
83
|
|
|
92
84
|
# Generic header format for any agent
|
|
@@ -103,9 +95,7 @@ class TerminalDisplay(BaseDisplay):
|
|
|
103
95
|
print("=" * self.terminal_width)
|
|
104
96
|
print()
|
|
105
97
|
|
|
106
|
-
def update_agent_content(
|
|
107
|
-
self, agent_id: str, content: str, content_type: str = "thinking"
|
|
108
|
-
):
|
|
98
|
+
def update_agent_content(self, agent_id: str, content: str, content_type: str = "thinking"):
|
|
109
99
|
"""Update content for a specific agent."""
|
|
110
100
|
if agent_id not in self.agent_ids:
|
|
111
101
|
return
|
|
@@ -142,10 +132,7 @@ class TerminalDisplay(BaseDisplay):
|
|
|
142
132
|
should_refresh = True # Always refresh for presentations
|
|
143
133
|
else:
|
|
144
134
|
# Thinking content - smart formatting based on content type
|
|
145
|
-
if
|
|
146
|
-
self.agent_outputs[agent_id]
|
|
147
|
-
and self.agent_outputs[agent_id][-1] == "⚡ Working..."
|
|
148
|
-
):
|
|
135
|
+
if self.agent_outputs[agent_id] and self.agent_outputs[agent_id][-1] == "⚡ Working...":
|
|
149
136
|
# Replace "Working..." with actual thinking
|
|
150
137
|
self.agent_outputs[agent_id][-1] = clean_content
|
|
151
138
|
should_refresh = True # Refresh when replacing "Working..."
|
|
@@ -235,9 +222,7 @@ class TerminalDisplay(BaseDisplay):
|
|
|
235
222
|
if old_status != "working" and status == "working":
|
|
236
223
|
agent_prefix = f"[{agent_id}] " if self.num_agents > 1 else ""
|
|
237
224
|
print(f"\n{agent_prefix}⚡ Working...")
|
|
238
|
-
if not self.agent_outputs[agent_id] or not self.agent_outputs[agent_id][
|
|
239
|
-
-1
|
|
240
|
-
].startswith("⚡"):
|
|
225
|
+
if not self.agent_outputs[agent_id] or not self.agent_outputs[agent_id][-1].startswith("⚡"):
|
|
241
226
|
self.agent_outputs[agent_id].append("⚡ Working...")
|
|
242
227
|
|
|
243
228
|
# Show status update in footer
|
|
@@ -248,17 +233,21 @@ class TerminalDisplay(BaseDisplay):
|
|
|
248
233
|
self.orchestrator_events.append(event)
|
|
249
234
|
self._refresh_display()
|
|
250
235
|
|
|
251
|
-
def show_final_answer(self, answer: str):
|
|
236
|
+
def show_final_answer(self, answer: str, vote_results=None, selected_agent=None):
|
|
252
237
|
"""Display the final coordinated answer prominently."""
|
|
253
|
-
print(
|
|
238
|
+
print("\n🎯 FINAL COORDINATED ANSWER:")
|
|
254
239
|
print("=" * 60)
|
|
255
240
|
print(f"📋 {answer}")
|
|
241
|
+
if selected_agent:
|
|
242
|
+
print(f"✅ Selected by: {selected_agent}")
|
|
243
|
+
if vote_results:
|
|
244
|
+
vote_summary = ", ".join([f"{agent}: {votes}" for agent, votes in vote_results.items()])
|
|
245
|
+
print(f"🗳️ Vote results: {vote_summary}")
|
|
256
246
|
print("=" * 60)
|
|
257
247
|
|
|
258
248
|
def cleanup(self):
|
|
259
249
|
"""Clean up display resources."""
|
|
260
250
|
# No special cleanup needed for terminal display
|
|
261
|
-
pass
|
|
262
251
|
|
|
263
252
|
def _refresh_display(self):
|
|
264
253
|
"""Refresh the entire display with proper columns."""
|
|
@@ -273,20 +262,12 @@ class TerminalDisplay(BaseDisplay):
|
|
|
273
262
|
print("\033[7;1H\033[0J", end="") # Move to line 7 and clear down
|
|
274
263
|
|
|
275
264
|
# Show agent outputs in columns with word wrapping
|
|
276
|
-
max_lines = (
|
|
277
|
-
max(len(self.agent_outputs[agent_id]) for agent_id in self.agent_ids)
|
|
278
|
-
if self.agent_outputs
|
|
279
|
-
else 0
|
|
280
|
-
)
|
|
265
|
+
max_lines = max(len(self.agent_outputs[agent_id]) for agent_id in self.agent_ids) if self.agent_outputs else 0
|
|
281
266
|
|
|
282
267
|
# For single agent, don't wrap - show full content
|
|
283
268
|
if self.num_agents == 1:
|
|
284
269
|
for i in range(max_lines):
|
|
285
|
-
line = (
|
|
286
|
-
self.agent_outputs[self.agent_ids[0]][i]
|
|
287
|
-
if i < len(self.agent_outputs[self.agent_ids[0]])
|
|
288
|
-
else ""
|
|
289
|
-
)
|
|
270
|
+
line = self.agent_outputs[self.agent_ids[0]][i] if i < len(self.agent_outputs[self.agent_ids[0]]) else ""
|
|
290
271
|
print(line)
|
|
291
272
|
else:
|
|
292
273
|
# For multiple agents, wrap long lines to fit columns
|
|
@@ -299,18 +280,14 @@ class TerminalDisplay(BaseDisplay):
|
|
|
299
280
|
words = line.split(" ")
|
|
300
281
|
current_line = ""
|
|
301
282
|
for word in words:
|
|
302
|
-
test_line = (
|
|
303
|
-
current_line + (" " if current_line else "") + word
|
|
304
|
-
)
|
|
283
|
+
test_line = current_line + (" " if current_line else "") + word
|
|
305
284
|
if len(test_line) > self.col_width - 2:
|
|
306
285
|
if current_line:
|
|
307
286
|
wrapped_outputs[agent_id].append(current_line)
|
|
308
287
|
current_line = word
|
|
309
288
|
else:
|
|
310
289
|
# Single word longer than column width - truncate gracefully
|
|
311
|
-
wrapped_outputs[agent_id].append(
|
|
312
|
-
word[: self.col_width - 2] + "…"
|
|
313
|
-
)
|
|
290
|
+
wrapped_outputs[agent_id].append(word[: self.col_width - 2] + "…")
|
|
314
291
|
current_line = ""
|
|
315
292
|
else:
|
|
316
293
|
current_line = test_line
|
|
@@ -320,19 +297,11 @@ class TerminalDisplay(BaseDisplay):
|
|
|
320
297
|
wrapped_outputs[agent_id].append(line)
|
|
321
298
|
|
|
322
299
|
# Display wrapped content
|
|
323
|
-
max_wrapped_lines = (
|
|
324
|
-
max(len(wrapped_outputs[agent_id]) for agent_id in self.agent_ids)
|
|
325
|
-
if wrapped_outputs
|
|
326
|
-
else 0
|
|
327
|
-
)
|
|
300
|
+
max_wrapped_lines = max(len(wrapped_outputs[agent_id]) for agent_id in self.agent_ids) if wrapped_outputs else 0
|
|
328
301
|
for i in range(max_wrapped_lines):
|
|
329
302
|
output_lines = []
|
|
330
303
|
for agent_id in self.agent_ids:
|
|
331
|
-
line = (
|
|
332
|
-
wrapped_outputs[agent_id][i]
|
|
333
|
-
if i < len(wrapped_outputs[agent_id])
|
|
334
|
-
else ""
|
|
335
|
-
)
|
|
304
|
+
line = wrapped_outputs[agent_id][i] if i < len(wrapped_outputs[agent_id]) else ""
|
|
336
305
|
output_lines.append(f"{line:<{self.col_width}}")
|
|
337
306
|
print(self.separators.join(output_lines))
|
|
338
307
|
|
|
@@ -344,25 +313,15 @@ class TerminalDisplay(BaseDisplay):
|
|
|
344
313
|
for agent_id in self.agent_ids:
|
|
345
314
|
# Get backend info same as in header
|
|
346
315
|
backend_name = "Unknown"
|
|
347
|
-
if (
|
|
348
|
-
hasattr(self, "orchestrator")
|
|
349
|
-
and self.orchestrator
|
|
350
|
-
and hasattr(self.orchestrator, "agents")
|
|
351
|
-
):
|
|
316
|
+
if hasattr(self, "orchestrator") and self.orchestrator and hasattr(self.orchestrator, "agents"):
|
|
352
317
|
agent = self.orchestrator.agents.get(agent_id)
|
|
353
|
-
if (
|
|
354
|
-
agent
|
|
355
|
-
and hasattr(agent, "backend")
|
|
356
|
-
and hasattr(agent.backend, "get_provider_name")
|
|
357
|
-
):
|
|
318
|
+
if agent and hasattr(agent, "backend") and hasattr(agent.backend, "get_provider_name"):
|
|
358
319
|
try:
|
|
359
320
|
backend_name = agent.backend.get_provider_name()
|
|
360
|
-
except:
|
|
321
|
+
except Exception:
|
|
361
322
|
backend_name = "Unknown"
|
|
362
323
|
|
|
363
|
-
status_text = (
|
|
364
|
-
f"{agent_id.upper()} ({backend_name}): {self.agent_status[agent_id]}"
|
|
365
|
-
)
|
|
324
|
+
status_text = f"{agent_id.upper()} ({backend_name}): {self.agent_status[agent_id]}"
|
|
366
325
|
status_lines.append(f"{status_text:^{self.col_width}}")
|
|
367
326
|
|
|
368
327
|
if self.num_agents == 1:
|