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
massgen/v1/streaming_display.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
"""
|
|
2
3
|
MassGen Streaming Display System
|
|
3
4
|
|
|
@@ -8,13 +9,13 @@ Provides real-time multi-region display for MassGen agents with:
|
|
|
8
9
|
"""
|
|
9
10
|
|
|
10
11
|
import os
|
|
11
|
-
import
|
|
12
|
+
import re
|
|
13
|
+
import sys
|
|
12
14
|
import threading
|
|
15
|
+
import time
|
|
13
16
|
import unicodedata
|
|
14
|
-
import sys
|
|
15
|
-
import re
|
|
16
|
-
from typing import Dict, List, Optional, Callable, Union
|
|
17
17
|
from datetime import datetime
|
|
18
|
+
from typing import Callable, Dict, List, Optional
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
class MultiRegionDisplay:
|
|
@@ -47,9 +48,7 @@ class MultiRegionDisplay:
|
|
|
47
48
|
self._agent_vote_targets: Dict[int, Optional[int]] = {}
|
|
48
49
|
self._agent_chat_rounds: Dict[int, int] = {}
|
|
49
50
|
self._agent_update_counts: Dict[int, int] = {} # Track update history count
|
|
50
|
-
self._agent_votes_cast: Dict[int, int] =
|
|
51
|
-
{}
|
|
52
|
-
) # Track number of votes cast by each agent
|
|
51
|
+
self._agent_votes_cast: Dict[int, int] = {} # Track number of votes cast by each agent
|
|
53
52
|
|
|
54
53
|
# Simplified, consistent border tracking
|
|
55
54
|
self._display_cache = None # Single cache object for all dimensions
|
|
@@ -72,7 +71,7 @@ class MultiRegionDisplay:
|
|
|
72
71
|
r"\][^\x07]*(?:\x07|\x1B\\)" # OSC sequences
|
|
73
72
|
r"|"
|
|
74
73
|
r"[PX^_][^\x1B]*\x1B\\" # Other escape sequences
|
|
75
|
-
r")"
|
|
74
|
+
r")",
|
|
76
75
|
)
|
|
77
76
|
|
|
78
77
|
# Initialize logging directory and files
|
|
@@ -83,7 +82,7 @@ class MultiRegionDisplay:
|
|
|
83
82
|
"""Get terminal width with conservative fallback."""
|
|
84
83
|
try:
|
|
85
84
|
return os.get_terminal_size().columns
|
|
86
|
-
except:
|
|
85
|
+
except OSError:
|
|
87
86
|
return 120 # Safe default
|
|
88
87
|
|
|
89
88
|
def _calculate_layout(self, num_agents: int):
|
|
@@ -93,7 +92,6 @@ class MultiRegionDisplay:
|
|
|
93
92
|
"""
|
|
94
93
|
# Invalidate cache if agent count changed or no cache exists
|
|
95
94
|
if self._display_cache is None or self._last_agent_count != num_agents:
|
|
96
|
-
|
|
97
95
|
terminal_width = self._get_terminal_width()
|
|
98
96
|
|
|
99
97
|
# More conservative calculation to prevent overflow
|
|
@@ -103,9 +101,7 @@ class MultiRegionDisplay:
|
|
|
103
101
|
safety_margin = 10 # Increased safety margin for terminal variations
|
|
104
102
|
|
|
105
103
|
available_width = terminal_width - border_chars - safety_margin
|
|
106
|
-
col_width = max(
|
|
107
|
-
25, available_width // num_agents
|
|
108
|
-
) # Minimum 25 chars per column
|
|
104
|
+
col_width = max(25, available_width // num_agents) # Minimum 25 chars per column
|
|
109
105
|
|
|
110
106
|
# Calculate actual total width used
|
|
111
107
|
total_width = (col_width * num_agents) + border_chars
|
|
@@ -236,9 +232,7 @@ class MultiRegionDisplay:
|
|
|
236
232
|
char_width = self._get_char_width(char)
|
|
237
233
|
|
|
238
234
|
# Check if we can fit this character
|
|
239
|
-
if
|
|
240
|
-
current_width + char_width > max_width - 1
|
|
241
|
-
): # Save space for ellipsis
|
|
235
|
+
if current_width + char_width > max_width - 1: # Save space for ellipsis
|
|
242
236
|
# Try to add ellipsis if possible
|
|
243
237
|
if current_width < max_width:
|
|
244
238
|
result += "…"
|
|
@@ -287,9 +281,7 @@ class MultiRegionDisplay:
|
|
|
287
281
|
for part in content_parts:
|
|
288
282
|
if self._get_display_width(part) != self._display_cache["col_width"]:
|
|
289
283
|
# Re-pad if width is incorrect
|
|
290
|
-
part = self._pad_to_width(
|
|
291
|
-
part, self._display_cache["col_width"], "left"
|
|
292
|
-
)
|
|
284
|
+
part = self._pad_to_width(part, self._display_cache["col_width"], "left")
|
|
293
285
|
validated_parts.append(part)
|
|
294
286
|
|
|
295
287
|
# Join content with borders: │content1│content2│content3│
|
|
@@ -377,9 +369,7 @@ class MultiRegionDisplay:
|
|
|
377
369
|
self._pending_update = True
|
|
378
370
|
|
|
379
371
|
# Schedule update after delay
|
|
380
|
-
self._update_timer = threading.Timer(
|
|
381
|
-
self._update_delay, self._execute_display_update
|
|
382
|
-
)
|
|
372
|
+
self._update_timer = threading.Timer(self._update_delay, self._execute_display_update)
|
|
383
373
|
self._update_timer.start()
|
|
384
374
|
|
|
385
375
|
def _execute_display_update(self):
|
|
@@ -391,9 +381,7 @@ class MultiRegionDisplay:
|
|
|
391
381
|
# Prevent concurrent updates
|
|
392
382
|
if self._display_updating:
|
|
393
383
|
# Reschedule if another update is in progress
|
|
394
|
-
self._update_timer = threading.Timer(
|
|
395
|
-
self._update_delay, self._execute_display_update
|
|
396
|
-
)
|
|
384
|
+
self._update_timer = threading.Timer(self._update_delay, self._execute_display_update)
|
|
397
385
|
self._update_timer.start()
|
|
398
386
|
return
|
|
399
387
|
|
|
@@ -435,9 +423,7 @@ class MultiRegionDisplay:
|
|
|
435
423
|
# Log status change with emoji
|
|
436
424
|
old_emoji = status_change_emoji.get(old_status, "❓")
|
|
437
425
|
new_emoji = status_change_emoji.get(status, "❓")
|
|
438
|
-
status_msg =
|
|
439
|
-
f"{old_emoji}→{new_emoji} Agent {agent_id}: {old_status} → {status}"
|
|
440
|
-
)
|
|
426
|
+
status_msg = f"{old_emoji}→{new_emoji} Agent {agent_id}: {old_status} → {status}"
|
|
441
427
|
self.add_system_message(status_msg)
|
|
442
428
|
|
|
443
429
|
def update_phase(self, old_phase: str, new_phase: str):
|
|
@@ -452,9 +438,7 @@ class MultiRegionDisplay:
|
|
|
452
438
|
with self._lock:
|
|
453
439
|
self.vote_distribution = vote_dist.copy()
|
|
454
440
|
|
|
455
|
-
def update_consensus_status(
|
|
456
|
-
self, representative_id: int, vote_dist: Dict[int, int]
|
|
457
|
-
):
|
|
441
|
+
def update_consensus_status(self, representative_id: int, vote_dist: Dict[int, int]):
|
|
458
442
|
"""Update when consensus is reached."""
|
|
459
443
|
with self._lock:
|
|
460
444
|
self.consensus_reached = True
|
|
@@ -513,26 +497,20 @@ class MultiRegionDisplay:
|
|
|
513
497
|
|
|
514
498
|
# Initialize system log file
|
|
515
499
|
with open(self.system_log_file, "w", encoding="utf-8") as f:
|
|
516
|
-
f.write(
|
|
517
|
-
f.write(
|
|
518
|
-
f"Session started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
|
|
519
|
-
)
|
|
500
|
+
f.write("MassGen System Messages Log\n")
|
|
501
|
+
f.write(f"Session started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
|
|
520
502
|
f.write("=" * 80 + "\n\n")
|
|
521
503
|
|
|
522
504
|
def _get_agent_log_file(self, agent_id: int) -> str:
|
|
523
505
|
"""Get or create the log file path for a specific agent."""
|
|
524
506
|
if agent_id not in self.agent_log_files:
|
|
525
507
|
# Use simple filename: agent_0.txt, agent_1.txt, etc.
|
|
526
|
-
self.agent_log_files[agent_id] = os.path.join(
|
|
527
|
-
self.session_logs_dir, f"agent_{agent_id}.txt"
|
|
528
|
-
)
|
|
508
|
+
self.agent_log_files[agent_id] = os.path.join(self.session_logs_dir, f"agent_{agent_id}.txt")
|
|
529
509
|
|
|
530
510
|
# Initialize agent log file
|
|
531
511
|
with open(self.agent_log_files[agent_id], "w", encoding="utf-8") as f:
|
|
532
512
|
f.write(f"MassGen Agent {agent_id} Output Log\n")
|
|
533
|
-
f.write(
|
|
534
|
-
f"Session started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
|
|
535
|
-
)
|
|
513
|
+
f.write(f"Session started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
|
|
536
514
|
f.write("=" * 80 + "\n\n")
|
|
537
515
|
|
|
538
516
|
return self.agent_log_files[agent_id]
|
|
@@ -631,14 +609,11 @@ class MultiRegionDisplay:
|
|
|
631
609
|
"""Handle terminal resize by resetting cached dimensions."""
|
|
632
610
|
try:
|
|
633
611
|
current_width = os.get_terminal_size().columns
|
|
634
|
-
if (
|
|
635
|
-
self._display_cache
|
|
636
|
-
and abs(current_width - self._display_cache["terminal_width"]) > 2
|
|
637
|
-
):
|
|
612
|
+
if self._display_cache and abs(current_width - self._display_cache["terminal_width"]) > 2:
|
|
638
613
|
# Even small changes should invalidate cache for border alignment
|
|
639
614
|
self._invalidate_display_cache()
|
|
640
615
|
return True
|
|
641
|
-
except:
|
|
616
|
+
except OSError:
|
|
642
617
|
# If we can't detect terminal size, invalidate cache to be safe
|
|
643
618
|
self._invalidate_display_cache()
|
|
644
619
|
return True
|
|
@@ -658,9 +633,7 @@ class MultiRegionDisplay:
|
|
|
658
633
|
# Write to system log
|
|
659
634
|
self._write_system_log(formatted_message + "\n")
|
|
660
635
|
|
|
661
|
-
def format_agent_notification(
|
|
662
|
-
self, agent_id: int, notification_type: str, content: str
|
|
663
|
-
):
|
|
636
|
+
def format_agent_notification(self, agent_id: int, notification_type: str, content: str):
|
|
664
637
|
"""Format agent notifications for display."""
|
|
665
638
|
notification_emoji = {
|
|
666
639
|
"update": "📢",
|
|
@@ -670,9 +643,7 @@ class MultiRegionDisplay:
|
|
|
670
643
|
}
|
|
671
644
|
|
|
672
645
|
emoji = notification_emoji.get(notification_type, "📨")
|
|
673
|
-
notification_msg =
|
|
674
|
-
f"{emoji} Agent {agent_id} received {notification_type} notification"
|
|
675
|
-
)
|
|
646
|
+
notification_msg = f"{emoji} Agent {agent_id} received {notification_type} notification"
|
|
676
647
|
self.add_system_message(notification_msg)
|
|
677
648
|
|
|
678
649
|
def _update_display_immediate(self):
|
|
@@ -699,9 +670,7 @@ class MultiRegionDisplay:
|
|
|
699
670
|
# Fallback to simple text output if display fails
|
|
700
671
|
print(f"Display error: {e}")
|
|
701
672
|
for agent_id in sorted(self.agent_outputs.keys()):
|
|
702
|
-
print(
|
|
703
|
-
f"Agent {agent_id}: {self.agent_outputs[agent_id][-100:]}"
|
|
704
|
-
) # Last 100 chars
|
|
673
|
+
print(f"Agent {agent_id}: {self.agent_outputs[agent_id][-100:]}") # Last 100 chars
|
|
705
674
|
return
|
|
706
675
|
|
|
707
676
|
# Split content into lines for each agent and limit to max_lines
|
|
@@ -723,7 +692,6 @@ class MultiRegionDisplay:
|
|
|
723
692
|
|
|
724
693
|
# ANSI color codes
|
|
725
694
|
BRIGHT_CYAN = "\033[96m"
|
|
726
|
-
BRIGHT_BLUE = "\033[94m"
|
|
727
695
|
BRIGHT_GREEN = "\033[92m"
|
|
728
696
|
BRIGHT_YELLOW = "\033[93m"
|
|
729
697
|
BRIGHT_MAGENTA = "\033[95m"
|
|
@@ -748,9 +716,7 @@ class MultiRegionDisplay:
|
|
|
748
716
|
|
|
749
717
|
# Subtitle line
|
|
750
718
|
subtitle_text = "🔬 Advanced Agent Collaboration Framework"
|
|
751
|
-
subtitle_line_content = self._pad_to_width(
|
|
752
|
-
subtitle_text, total_width - 2, "center"
|
|
753
|
-
)
|
|
719
|
+
subtitle_line_content = self._pad_to_width(subtitle_text, total_width - 2, "center")
|
|
754
720
|
subtitle_line = f"{BRIGHT_CYAN}║{BRIGHT_GREEN}{subtitle_line_content}{RESET}{BRIGHT_CYAN}║{RESET}"
|
|
755
721
|
print(subtitle_line)
|
|
756
722
|
|
|
@@ -798,7 +764,7 @@ class MultiRegionDisplay:
|
|
|
798
764
|
try:
|
|
799
765
|
header_line = self._create_bordered_line(header_parts, total_width)
|
|
800
766
|
print(header_line)
|
|
801
|
-
except Exception
|
|
767
|
+
except Exception:
|
|
802
768
|
# Fallback to simple border if formatting fails
|
|
803
769
|
print("─" * total_width)
|
|
804
770
|
|
|
@@ -812,19 +778,11 @@ class MultiRegionDisplay:
|
|
|
812
778
|
|
|
813
779
|
# Format state info with better handling of color codes (removed redundant status)
|
|
814
780
|
state_info = []
|
|
815
|
-
state_info.append(
|
|
816
|
-
|
|
817
|
-
)
|
|
818
|
-
state_info.append(
|
|
819
|
-
f"{BRIGHT_WHITE}#Updates:{RESET} {BRIGHT_MAGENTA}{update_count}{RESET}"
|
|
820
|
-
)
|
|
821
|
-
state_info.append(
|
|
822
|
-
f"{BRIGHT_WHITE}#Votes:{RESET} {BRIGHT_CYAN}{votes_cast}{RESET}"
|
|
823
|
-
)
|
|
781
|
+
state_info.append(f"{BRIGHT_WHITE}Round:{RESET} {BRIGHT_GREEN}{chat_round}{RESET}")
|
|
782
|
+
state_info.append(f"{BRIGHT_WHITE}#Updates:{RESET} {BRIGHT_MAGENTA}{update_count}{RESET}")
|
|
783
|
+
state_info.append(f"{BRIGHT_WHITE}#Votes:{RESET} {BRIGHT_CYAN}{votes_cast}{RESET}")
|
|
824
784
|
if vote_target:
|
|
825
|
-
state_info.append(
|
|
826
|
-
f"{BRIGHT_WHITE}Vote →{RESET} {BRIGHT_GREEN}{vote_target}{RESET}"
|
|
827
|
-
)
|
|
785
|
+
state_info.append(f"{BRIGHT_WHITE}Vote →{RESET} {BRIGHT_GREEN}{vote_target}{RESET}")
|
|
828
786
|
else:
|
|
829
787
|
state_info.append(f"{BRIGHT_WHITE}Vote →{RESET} None")
|
|
830
788
|
|
|
@@ -837,7 +795,7 @@ class MultiRegionDisplay:
|
|
|
837
795
|
try:
|
|
838
796
|
state_line = self._create_bordered_line(state_parts, total_width)
|
|
839
797
|
print(state_line)
|
|
840
|
-
except Exception
|
|
798
|
+
except Exception:
|
|
841
799
|
# Fallback to simple border if formatting fails
|
|
842
800
|
print("─" * total_width)
|
|
843
801
|
|
|
@@ -850,18 +808,12 @@ class MultiRegionDisplay:
|
|
|
850
808
|
answer_path = self.get_agent_answer_path_for_display(agent_id)
|
|
851
809
|
if answer_path:
|
|
852
810
|
# Shortened display path
|
|
853
|
-
display_path = (
|
|
854
|
-
answer_path.replace(os.getcwd() + "/", "")
|
|
855
|
-
if answer_path.startswith(os.getcwd())
|
|
856
|
-
else answer_path
|
|
857
|
-
)
|
|
811
|
+
display_path = answer_path.replace(os.getcwd() + "/", "") if answer_path.startswith(os.getcwd()) else answer_path
|
|
858
812
|
|
|
859
813
|
# Safe path truncation with better width handling
|
|
860
814
|
prefix = "📄 Answers: "
|
|
861
815
|
# More conservative calculation
|
|
862
|
-
max_path_len = max(
|
|
863
|
-
10, col_width - self._get_display_width(prefix) - 8
|
|
864
|
-
)
|
|
816
|
+
max_path_len = max(10, col_width - self._get_display_width(prefix) - 8)
|
|
865
817
|
if len(display_path) > max_path_len:
|
|
866
818
|
display_path = "..." + display_path[-(max_path_len - 3) :]
|
|
867
819
|
|
|
@@ -871,21 +823,13 @@ class MultiRegionDisplay:
|
|
|
871
823
|
# Fallback to log file path if answer path not available
|
|
872
824
|
log_path = self.get_agent_log_path_for_display(agent_id)
|
|
873
825
|
if log_path:
|
|
874
|
-
display_path = (
|
|
875
|
-
log_path.replace(os.getcwd() + "/", "")
|
|
876
|
-
if log_path.startswith(os.getcwd())
|
|
877
|
-
else log_path
|
|
878
|
-
)
|
|
826
|
+
display_path = log_path.replace(os.getcwd() + "/", "") if log_path.startswith(os.getcwd()) else log_path
|
|
879
827
|
prefix = "📁 Log: "
|
|
880
|
-
max_path_len = max(
|
|
881
|
-
10, col_width - self._get_display_width(prefix) - 8
|
|
882
|
-
)
|
|
828
|
+
max_path_len = max(10, col_width - self._get_display_width(prefix) - 8)
|
|
883
829
|
if len(display_path) > max_path_len:
|
|
884
830
|
display_path = "..." + display_path[-(max_path_len - 3) :]
|
|
885
831
|
link_text = f"{prefix}{UNDERLINE}{display_path}{RESET}"
|
|
886
|
-
link_content = self._pad_to_width(
|
|
887
|
-
link_text, col_width, "center"
|
|
888
|
-
)
|
|
832
|
+
link_content = self._pad_to_width(link_text, col_width, "center")
|
|
889
833
|
else:
|
|
890
834
|
link_content = self._pad_to_width("", col_width, "center")
|
|
891
835
|
link_parts.append(link_content)
|
|
@@ -894,7 +838,7 @@ class MultiRegionDisplay:
|
|
|
894
838
|
try:
|
|
895
839
|
log_line = self._create_bordered_line(link_parts, total_width)
|
|
896
840
|
print(log_line)
|
|
897
|
-
except Exception
|
|
841
|
+
except Exception:
|
|
898
842
|
# Fallback to simple border if formatting fails
|
|
899
843
|
print("─" * total_width)
|
|
900
844
|
|
|
@@ -915,11 +859,10 @@ class MultiRegionDisplay:
|
|
|
915
859
|
try:
|
|
916
860
|
content_line = self._create_bordered_line(content_parts, total_width)
|
|
917
861
|
print(content_line)
|
|
918
|
-
except Exception
|
|
862
|
+
except Exception:
|
|
919
863
|
# Fallback: print content without borders to maintain functionality
|
|
920
|
-
simple_line = " | ".join(content_parts)[: total_width - 4]
|
|
921
|
-
|
|
922
|
-
)
|
|
864
|
+
simple_line = " | ".join(content_parts)[: total_width - 4]
|
|
865
|
+
simple_line = simple_line + " " * max(0, total_width - 4 - len(simple_line))
|
|
923
866
|
print(f"│ {simple_line} │")
|
|
924
867
|
|
|
925
868
|
# System status section with exact width
|
|
@@ -927,37 +870,21 @@ class MultiRegionDisplay:
|
|
|
927
870
|
print(f"\n{border_line}")
|
|
928
871
|
|
|
929
872
|
# System state header
|
|
930
|
-
phase_color =
|
|
931
|
-
BRIGHT_YELLOW if self.current_phase == "collaboration" else BRIGHT_GREEN
|
|
932
|
-
)
|
|
873
|
+
phase_color = BRIGHT_YELLOW if self.current_phase == "collaboration" else BRIGHT_GREEN
|
|
933
874
|
consensus_color = BRIGHT_GREEN if self.consensus_reached else BRIGHT_RED
|
|
934
875
|
consensus_text = "✅ YES" if self.consensus_reached else "❌ NO"
|
|
935
876
|
|
|
936
877
|
system_state_info = []
|
|
937
|
-
system_state_info.append(
|
|
938
|
-
|
|
939
|
-
)
|
|
940
|
-
system_state_info.append(
|
|
941
|
-
f"{BRIGHT_WHITE}Consensus:{RESET} {consensus_color}{consensus_text}{RESET}"
|
|
942
|
-
)
|
|
943
|
-
system_state_info.append(
|
|
944
|
-
f"{BRIGHT_WHITE}Debate Rounds:{RESET} {BRIGHT_CYAN}{self.debate_rounds}{RESET}"
|
|
945
|
-
)
|
|
878
|
+
system_state_info.append(f"{BRIGHT_WHITE}Phase:{RESET} {phase_color}{self.current_phase.upper()}{RESET}")
|
|
879
|
+
system_state_info.append(f"{BRIGHT_WHITE}Consensus:{RESET} {consensus_color}{consensus_text}{RESET}")
|
|
880
|
+
system_state_info.append(f"{BRIGHT_WHITE}Debate Rounds:{RESET} {BRIGHT_CYAN}{self.debate_rounds}{RESET}")
|
|
946
881
|
if self.representative_agent_id:
|
|
947
|
-
system_state_info.append(
|
|
948
|
-
f"{BRIGHT_WHITE}Representative Agent:{RESET} {BRIGHT_GREEN}{self.representative_agent_id}{RESET}"
|
|
949
|
-
)
|
|
882
|
+
system_state_info.append(f"{BRIGHT_WHITE}Representative Agent:{RESET} {BRIGHT_GREEN}{self.representative_agent_id}{RESET}")
|
|
950
883
|
else:
|
|
951
|
-
system_state_info.append(
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
system_header_text = (
|
|
956
|
-
f"{BRIGHT_CYAN}📋 SYSTEM STATE{RESET} - {' | '.join(system_state_info)}"
|
|
957
|
-
)
|
|
958
|
-
system_header_line = self._create_system_bordered_line(
|
|
959
|
-
system_header_text, total_width
|
|
960
|
-
)
|
|
884
|
+
system_state_info.append(f"{BRIGHT_WHITE}Representative Agent:{RESET} None")
|
|
885
|
+
|
|
886
|
+
system_header_text = f"{BRIGHT_CYAN}📋 SYSTEM STATE{RESET} - {' | '.join(system_state_info)}"
|
|
887
|
+
system_header_line = self._create_system_bordered_line(system_header_text, total_width)
|
|
961
888
|
print(system_header_line)
|
|
962
889
|
|
|
963
890
|
# System log file link
|
|
@@ -965,24 +892,16 @@ class MultiRegionDisplay:
|
|
|
965
892
|
system_log_path = self.get_system_log_path_for_display()
|
|
966
893
|
if system_log_path:
|
|
967
894
|
UNDERLINE = "\033[4m"
|
|
968
|
-
display_path = (
|
|
969
|
-
system_log_path.replace(os.getcwd() + "/", "")
|
|
970
|
-
if system_log_path.startswith(os.getcwd())
|
|
971
|
-
else system_log_path
|
|
972
|
-
)
|
|
895
|
+
display_path = system_log_path.replace(os.getcwd() + "/", "") if system_log_path.startswith(os.getcwd()) else system_log_path
|
|
973
896
|
|
|
974
897
|
# Safe path truncation with consistent width handling
|
|
975
898
|
prefix = "📁 Log: "
|
|
976
|
-
max_path_len = max(
|
|
977
|
-
10, total_width - self._get_display_width(prefix) - 15
|
|
978
|
-
)
|
|
899
|
+
max_path_len = max(10, total_width - self._get_display_width(prefix) - 15)
|
|
979
900
|
if len(display_path) > max_path_len:
|
|
980
901
|
display_path = "..." + display_path[-(max_path_len - 3) :]
|
|
981
902
|
|
|
982
903
|
system_link_text = f"{prefix}{UNDERLINE}{display_path}{RESET}"
|
|
983
|
-
system_link_line = self._create_system_bordered_line(
|
|
984
|
-
system_link_text, total_width
|
|
985
|
-
)
|
|
904
|
+
system_link_line = self._create_system_bordered_line(system_link_text, total_width)
|
|
986
905
|
print(system_link_line)
|
|
987
906
|
|
|
988
907
|
print(border_line)
|
|
@@ -990,16 +909,12 @@ class MultiRegionDisplay:
|
|
|
990
909
|
# System messages with exact width and validation
|
|
991
910
|
if self.consensus_reached and self.representative_agent_id is not None:
|
|
992
911
|
consensus_msg = f"🎉 CONSENSUS REACHED! Representative: Agent {self.representative_agent_id}"
|
|
993
|
-
consensus_line = self._create_system_bordered_line(
|
|
994
|
-
consensus_msg, total_width
|
|
995
|
-
)
|
|
912
|
+
consensus_line = self._create_system_bordered_line(consensus_msg, total_width)
|
|
996
913
|
print(consensus_line)
|
|
997
914
|
|
|
998
915
|
# Vote distribution with validation
|
|
999
916
|
if self.vote_distribution:
|
|
1000
|
-
vote_msg = "📊 Vote Distribution: " + ", ".join(
|
|
1001
|
-
[f"Agent {k}→{v} votes" for k, v in self.vote_distribution.items()]
|
|
1002
|
-
)
|
|
917
|
+
vote_msg = "📊 Vote Distribution: " + ", ".join([f"Agent {k}→{v} votes" for k, v in self.vote_distribution.items()])
|
|
1003
918
|
|
|
1004
919
|
# Use the new safe wrapping method
|
|
1005
920
|
max_content_width = total_width - 2
|
|
@@ -1009,16 +924,12 @@ class MultiRegionDisplay:
|
|
|
1009
924
|
else:
|
|
1010
925
|
# Wrap vote distribution using safe method
|
|
1011
926
|
vote_header = "📊 Vote Distribution:"
|
|
1012
|
-
header_line = self._create_system_bordered_line(
|
|
1013
|
-
vote_header, total_width
|
|
1014
|
-
)
|
|
927
|
+
header_line = self._create_system_bordered_line(vote_header, total_width)
|
|
1015
928
|
print(header_line)
|
|
1016
929
|
|
|
1017
930
|
for agent_id, votes in self.vote_distribution.items():
|
|
1018
931
|
vote_detail = f" Agent {agent_id}: {votes} votes"
|
|
1019
|
-
detail_line = self._create_system_bordered_line(
|
|
1020
|
-
vote_detail, total_width
|
|
1021
|
-
)
|
|
932
|
+
detail_line = self._create_system_bordered_line(vote_detail, total_width)
|
|
1022
933
|
print(detail_line)
|
|
1023
934
|
|
|
1024
935
|
# Regular system messages with validation
|
|
@@ -1038,9 +949,7 @@ class MultiRegionDisplay:
|
|
|
1038
949
|
if self._get_display_width(test_line) > max_content_width:
|
|
1039
950
|
# Print current line if it has content
|
|
1040
951
|
if current_line.strip():
|
|
1041
|
-
line = self._create_system_bordered_line(
|
|
1042
|
-
current_line.strip(), total_width
|
|
1043
|
-
)
|
|
952
|
+
line = self._create_system_bordered_line(current_line.strip(), total_width)
|
|
1044
953
|
print(line)
|
|
1045
954
|
current_line = word
|
|
1046
955
|
else:
|
|
@@ -1048,9 +957,7 @@ class MultiRegionDisplay:
|
|
|
1048
957
|
|
|
1049
958
|
# Print final line if it has content
|
|
1050
959
|
if current_line.strip():
|
|
1051
|
-
line = self._create_system_bordered_line(
|
|
1052
|
-
current_line.strip(), total_width
|
|
1053
|
-
)
|
|
960
|
+
line = self._create_system_bordered_line(current_line.strip(), total_width)
|
|
1054
961
|
print(line)
|
|
1055
962
|
|
|
1056
963
|
# Final border
|
|
@@ -1077,9 +984,7 @@ class StreamingOrchestrator:
|
|
|
1077
984
|
save_logs: bool = True,
|
|
1078
985
|
answers_dir: Optional[str] = None,
|
|
1079
986
|
):
|
|
1080
|
-
self.display = MultiRegionDisplay(
|
|
1081
|
-
display_enabled, max_lines, save_logs, answers_dir
|
|
1082
|
-
)
|
|
987
|
+
self.display = MultiRegionDisplay(display_enabled, max_lines, save_logs, answers_dir)
|
|
1083
988
|
self.stream_callback = stream_callback
|
|
1084
989
|
|
|
1085
990
|
def stream_output(self, agent_id: int, content: str):
|
|
@@ -1111,9 +1016,7 @@ class StreamingOrchestrator:
|
|
|
1111
1016
|
self.display.update_vote_distribution(vote_dist)
|
|
1112
1017
|
self.display.force_update_display()
|
|
1113
1018
|
|
|
1114
|
-
def update_consensus_status(
|
|
1115
|
-
self, representative_id: int, vote_dist: Dict[int, int]
|
|
1116
|
-
):
|
|
1019
|
+
def update_consensus_status(self, representative_id: int, vote_dist: Dict[int, int]):
|
|
1117
1020
|
"""Update consensus status - immediate update for critical state changes."""
|
|
1118
1021
|
self.display.update_consensus_status(representative_id, vote_dist)
|
|
1119
1022
|
self.display.force_update_display()
|
|
@@ -1153,9 +1056,7 @@ class StreamingOrchestrator:
|
|
|
1153
1056
|
self.display.update_debate_rounds(rounds)
|
|
1154
1057
|
self.display.force_update_display()
|
|
1155
1058
|
|
|
1156
|
-
def format_agent_notification(
|
|
1157
|
-
self, agent_id: int, notification_type: str, content: str
|
|
1158
|
-
):
|
|
1059
|
+
def format_agent_notification(self, agent_id: int, notification_type: str, content: str):
|
|
1159
1060
|
"""Format agent notifications - immediate update for notifications."""
|
|
1160
1061
|
self.display.format_agent_notification(agent_id, notification_type, content)
|
|
1161
1062
|
self.display.force_update_display()
|
|
@@ -1185,6 +1086,4 @@ def create_streaming_display(
|
|
|
1185
1086
|
answers_dir: Optional[str] = None,
|
|
1186
1087
|
) -> StreamingOrchestrator:
|
|
1187
1088
|
"""Create a streaming orchestrator with display capabilities."""
|
|
1188
|
-
return StreamingOrchestrator(
|
|
1189
|
-
display_enabled, stream_callback, max_lines, save_logs, answers_dir
|
|
1190
|
-
)
|
|
1089
|
+
return StreamingOrchestrator(display_enabled, stream_callback, max_lines, save_logs, answers_dir)
|
massgen/v1/tools.py
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import ast
|
|
2
3
|
import json
|
|
3
|
-
import
|
|
4
|
+
import math
|
|
5
|
+
import operator
|
|
4
6
|
import subprocess
|
|
5
7
|
import sys
|
|
6
|
-
import
|
|
7
|
-
from dataclasses import dataclass
|
|
8
|
-
from datetime import datetime
|
|
9
|
-
from typing import Any, Union, Optional, Dict, List
|
|
10
|
-
import ast
|
|
11
|
-
import operator
|
|
12
|
-
import math
|
|
8
|
+
from typing import Any, Dict, Optional
|
|
13
9
|
|
|
14
10
|
# Global tool registry
|
|
15
11
|
register_tool = {}
|
|
@@ -51,7 +47,7 @@ def python_interpreter(code: str, timeout: Optional[int] = 10) -> Dict[str, Any]
|
|
|
51
47
|
"returncode": result.returncode,
|
|
52
48
|
"success": result.returncode == 0,
|
|
53
49
|
"error": None,
|
|
54
|
-
}
|
|
50
|
+
},
|
|
55
51
|
)
|
|
56
52
|
|
|
57
53
|
except subprocess.TimeoutExpired:
|
|
@@ -62,7 +58,7 @@ def python_interpreter(code: str, timeout: Optional[int] = 10) -> Dict[str, Any]
|
|
|
62
58
|
"returncode": -1,
|
|
63
59
|
"success": False,
|
|
64
60
|
"error": f"Code execution timed out after {timeout} seconds",
|
|
65
|
-
}
|
|
61
|
+
},
|
|
66
62
|
)
|
|
67
63
|
|
|
68
64
|
except Exception as e:
|
|
@@ -73,7 +69,7 @@ def python_interpreter(code: str, timeout: Optional[int] = 10) -> Dict[str, Any]
|
|
|
73
69
|
"returncode": -1,
|
|
74
70
|
"success": False,
|
|
75
71
|
"error": f"Failed to execute code: {str(e)}",
|
|
76
|
-
}
|
|
72
|
+
},
|
|
77
73
|
)
|
|
78
74
|
|
|
79
75
|
|
massgen/v1/types.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
"""
|
|
2
3
|
MassGen System Types
|
|
3
4
|
|
|
@@ -6,9 +7,8 @@ used throughout the MassGen framework.
|
|
|
6
7
|
"""
|
|
7
8
|
|
|
8
9
|
import time
|
|
9
|
-
from dataclasses import dataclass, field
|
|
10
|
+
from dataclasses import asdict, dataclass, field
|
|
10
11
|
from typing import Any, Dict, List, Optional
|
|
11
|
-
from abc import ABC, abstractmethod
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
@dataclass
|
|
@@ -62,9 +62,7 @@ class TaskInput:
|
|
|
62
62
|
"""Represents a task to be processed by the MassGen system."""
|
|
63
63
|
|
|
64
64
|
question: str
|
|
65
|
-
context: Dict[str, Any] = field(
|
|
66
|
-
default_factory=dict
|
|
67
|
-
) # may support more information in the future, like images
|
|
65
|
+
context: Dict[str, Any] = field(default_factory=dict) # may support more information in the future, like images
|
|
68
66
|
task_id: Optional[str] = None
|
|
69
67
|
|
|
70
68
|
|
|
@@ -91,19 +89,11 @@ class AgentState:
|
|
|
91
89
|
agent_id: int
|
|
92
90
|
status: str = "working" # "working", "voted", "failed"
|
|
93
91
|
curr_answer: str = "" # the latest answer of the agent's work
|
|
94
|
-
updated_answers: List[AnswerRecord] = field(
|
|
95
|
-
|
|
96
|
-
) # a list of answer records
|
|
97
|
-
curr_vote: Optional[VoteRecord] = (
|
|
98
|
-
None # Which agent's solution this agent voted for
|
|
99
|
-
)
|
|
92
|
+
updated_answers: List[AnswerRecord] = field(default_factory=list) # a list of answer records
|
|
93
|
+
curr_vote: Optional[VoteRecord] = None # Which agent's solution this agent voted for
|
|
100
94
|
cast_votes: List[VoteRecord] = field(default_factory=list) # a list of vote records
|
|
101
|
-
seen_updates_timestamps: Dict[int, float] = field(
|
|
102
|
-
|
|
103
|
-
) # agent_id -> last_seen_timestamp
|
|
104
|
-
chat_history: List[Dict[str, Any]] = field(
|
|
105
|
-
default_factory=list
|
|
106
|
-
) # a list of conversation records
|
|
95
|
+
seen_updates_timestamps: Dict[int, float] = field(default_factory=dict) # agent_id -> last_seen_timestamp
|
|
96
|
+
chat_history: List[Dict[str, Any]] = field(default_factory=list) # a list of conversation records
|
|
107
97
|
chat_round: int = 0 # the number of chat rounds the agent has participated in
|
|
108
98
|
execution_start_time: Optional[float] = None
|
|
109
99
|
execution_end_time: Optional[float] = None
|
|
@@ -211,9 +201,7 @@ class AgentConfig:
|
|
|
211
201
|
def __post_init__(self):
|
|
212
202
|
"""Validate agent configuration."""
|
|
213
203
|
if self.agent_type not in ["openai", "gemini", "grok"]:
|
|
214
|
-
raise ValueError(
|
|
215
|
-
f"Invalid agent_type: {self.agent_type}. Must be one of: openai, gemini, grok"
|
|
216
|
-
)
|
|
204
|
+
raise ValueError(f"Invalid agent_type: {self.agent_type}. Must be one of: openai, gemini, grok")
|
|
217
205
|
|
|
218
206
|
|
|
219
207
|
@dataclass
|
|
@@ -222,9 +210,7 @@ class MassConfig:
|
|
|
222
210
|
|
|
223
211
|
orchestrator: OrchestratorConfig = field(default_factory=OrchestratorConfig)
|
|
224
212
|
agents: List[AgentConfig] = field(default_factory=list)
|
|
225
|
-
streaming_display: StreamingDisplayConfig = field(
|
|
226
|
-
default_factory=StreamingDisplayConfig
|
|
227
|
-
)
|
|
213
|
+
streaming_display: StreamingDisplayConfig = field(default_factory=StreamingDisplayConfig)
|
|
228
214
|
logging: LoggingConfig = field(default_factory=LoggingConfig)
|
|
229
215
|
task: Optional[Dict[str, Any]] = None # Task-specific configuration
|
|
230
216
|
|