massgen 0.1.0a3__py3-none-any.whl → 0.1.2__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 (120) hide show
  1. massgen/__init__.py +1 -1
  2. massgen/agent_config.py +17 -0
  3. massgen/api_params_handler/_api_params_handler_base.py +1 -0
  4. massgen/api_params_handler/_chat_completions_api_params_handler.py +15 -2
  5. massgen/api_params_handler/_claude_api_params_handler.py +8 -1
  6. massgen/api_params_handler/_gemini_api_params_handler.py +73 -0
  7. massgen/api_params_handler/_response_api_params_handler.py +8 -1
  8. massgen/backend/base.py +83 -0
  9. massgen/backend/{base_with_mcp.py → base_with_custom_tool_and_mcp.py} +286 -15
  10. massgen/backend/capabilities.py +6 -6
  11. massgen/backend/chat_completions.py +200 -103
  12. massgen/backend/claude.py +115 -18
  13. massgen/backend/claude_code.py +378 -14
  14. massgen/backend/docs/CLAUDE_API_RESEARCH.md +3 -3
  15. massgen/backend/gemini.py +1333 -1629
  16. massgen/backend/gemini_mcp_manager.py +545 -0
  17. massgen/backend/gemini_trackers.py +344 -0
  18. massgen/backend/gemini_utils.py +43 -0
  19. massgen/backend/grok.py +39 -6
  20. massgen/backend/response.py +147 -81
  21. massgen/cli.py +605 -110
  22. massgen/config_builder.py +376 -27
  23. massgen/configs/README.md +123 -80
  24. massgen/configs/basic/multi/three_agents_default.yaml +3 -3
  25. massgen/configs/basic/single/single_agent.yaml +1 -1
  26. massgen/configs/providers/openai/gpt5_nano.yaml +3 -3
  27. massgen/configs/tools/custom_tools/claude_code_custom_tool_example.yaml +32 -0
  28. massgen/configs/tools/custom_tools/claude_code_custom_tool_example_no_path.yaml +28 -0
  29. massgen/configs/tools/custom_tools/claude_code_custom_tool_with_mcp_example.yaml +40 -0
  30. massgen/configs/tools/custom_tools/claude_code_custom_tool_with_wrong_mcp_example.yaml +38 -0
  31. massgen/configs/tools/custom_tools/claude_code_wrong_custom_tool_with_mcp_example.yaml +38 -0
  32. massgen/configs/tools/custom_tools/claude_custom_tool_example.yaml +24 -0
  33. massgen/configs/tools/custom_tools/claude_custom_tool_example_no_path.yaml +22 -0
  34. massgen/configs/tools/custom_tools/claude_custom_tool_with_mcp_example.yaml +35 -0
  35. massgen/configs/tools/custom_tools/claude_custom_tool_with_wrong_mcp_example.yaml +33 -0
  36. massgen/configs/tools/custom_tools/claude_wrong_custom_tool_with_mcp_example.yaml +33 -0
  37. massgen/configs/tools/custom_tools/gemini_custom_tool_example.yaml +24 -0
  38. massgen/configs/tools/custom_tools/gemini_custom_tool_example_no_path.yaml +22 -0
  39. massgen/configs/tools/custom_tools/gemini_custom_tool_with_mcp_example.yaml +35 -0
  40. massgen/configs/tools/custom_tools/gemini_custom_tool_with_wrong_mcp_example.yaml +33 -0
  41. massgen/configs/tools/custom_tools/gemini_wrong_custom_tool_with_mcp_example.yaml +33 -0
  42. massgen/configs/tools/custom_tools/github_issue_market_analysis.yaml +94 -0
  43. massgen/configs/tools/custom_tools/gpt5_nano_custom_tool_example.yaml +24 -0
  44. massgen/configs/tools/custom_tools/gpt5_nano_custom_tool_example_no_path.yaml +22 -0
  45. massgen/configs/tools/custom_tools/gpt5_nano_custom_tool_with_mcp_example.yaml +35 -0
  46. massgen/configs/tools/custom_tools/gpt5_nano_custom_tool_with_wrong_mcp_example.yaml +33 -0
  47. massgen/configs/tools/custom_tools/gpt5_nano_wrong_custom_tool_with_mcp_example.yaml +33 -0
  48. massgen/configs/tools/custom_tools/gpt_oss_custom_tool_example.yaml +25 -0
  49. massgen/configs/tools/custom_tools/gpt_oss_custom_tool_example_no_path.yaml +23 -0
  50. massgen/configs/tools/custom_tools/gpt_oss_custom_tool_with_mcp_example.yaml +34 -0
  51. massgen/configs/tools/custom_tools/gpt_oss_custom_tool_with_wrong_mcp_example.yaml +34 -0
  52. massgen/configs/tools/custom_tools/gpt_oss_wrong_custom_tool_with_mcp_example.yaml +34 -0
  53. massgen/configs/tools/custom_tools/grok3_mini_custom_tool_example.yaml +24 -0
  54. massgen/configs/tools/custom_tools/grok3_mini_custom_tool_example_no_path.yaml +22 -0
  55. massgen/configs/tools/custom_tools/grok3_mini_custom_tool_with_mcp_example.yaml +35 -0
  56. massgen/configs/tools/custom_tools/grok3_mini_custom_tool_with_wrong_mcp_example.yaml +33 -0
  57. massgen/configs/tools/custom_tools/grok3_mini_wrong_custom_tool_with_mcp_example.yaml +33 -0
  58. massgen/configs/tools/custom_tools/qwen_api_custom_tool_example.yaml +25 -0
  59. massgen/configs/tools/custom_tools/qwen_api_custom_tool_example_no_path.yaml +23 -0
  60. massgen/configs/tools/custom_tools/qwen_api_custom_tool_with_mcp_example.yaml +36 -0
  61. massgen/configs/tools/custom_tools/qwen_api_custom_tool_with_wrong_mcp_example.yaml +34 -0
  62. massgen/configs/tools/custom_tools/qwen_api_wrong_custom_tool_with_mcp_example.yaml +34 -0
  63. massgen/configs/tools/custom_tools/qwen_local_custom_tool_example.yaml +24 -0
  64. massgen/configs/tools/custom_tools/qwen_local_custom_tool_example_no_path.yaml +22 -0
  65. massgen/configs/tools/custom_tools/qwen_local_custom_tool_with_mcp_example.yaml +35 -0
  66. massgen/configs/tools/custom_tools/qwen_local_custom_tool_with_wrong_mcp_example.yaml +33 -0
  67. massgen/configs/tools/custom_tools/qwen_local_wrong_custom_tool_with_mcp_example.yaml +33 -0
  68. massgen/configs/tools/filesystem/claude_code_context_sharing.yaml +1 -1
  69. massgen/configs/tools/planning/five_agents_discord_mcp_planning_mode.yaml +7 -29
  70. massgen/configs/tools/planning/five_agents_filesystem_mcp_planning_mode.yaml +5 -6
  71. massgen/configs/tools/planning/five_agents_notion_mcp_planning_mode.yaml +4 -4
  72. massgen/configs/tools/planning/five_agents_twitter_mcp_planning_mode.yaml +4 -4
  73. massgen/configs/tools/planning/gpt5_mini_case_study_mcp_planning_mode.yaml +2 -2
  74. massgen/configs/voting/gemini_gpt_voting_sensitivity.yaml +67 -0
  75. massgen/formatter/_chat_completions_formatter.py +104 -0
  76. massgen/formatter/_claude_formatter.py +120 -0
  77. massgen/formatter/_gemini_formatter.py +448 -0
  78. massgen/formatter/_response_formatter.py +88 -0
  79. massgen/frontend/coordination_ui.py +4 -2
  80. massgen/logger_config.py +35 -3
  81. massgen/message_templates.py +56 -6
  82. massgen/orchestrator.py +512 -16
  83. massgen/stream_chunk/base.py +3 -0
  84. massgen/tests/custom_tools_example.py +392 -0
  85. massgen/tests/mcp_test_server.py +17 -7
  86. massgen/tests/test_config_builder.py +423 -0
  87. massgen/tests/test_custom_tools.py +401 -0
  88. massgen/tests/test_intelligent_planning_mode.py +643 -0
  89. massgen/tests/test_tools.py +127 -0
  90. massgen/token_manager/token_manager.py +13 -4
  91. massgen/tool/README.md +935 -0
  92. massgen/tool/__init__.py +39 -0
  93. massgen/tool/_async_helpers.py +70 -0
  94. massgen/tool/_basic/__init__.py +8 -0
  95. massgen/tool/_basic/_two_num_tool.py +24 -0
  96. massgen/tool/_code_executors/__init__.py +10 -0
  97. massgen/tool/_code_executors/_python_executor.py +74 -0
  98. massgen/tool/_code_executors/_shell_executor.py +61 -0
  99. massgen/tool/_exceptions.py +39 -0
  100. massgen/tool/_file_handlers/__init__.py +10 -0
  101. massgen/tool/_file_handlers/_file_operations.py +218 -0
  102. massgen/tool/_manager.py +634 -0
  103. massgen/tool/_registered_tool.py +88 -0
  104. massgen/tool/_result.py +66 -0
  105. massgen/tool/_self_evolution/_github_issue_analyzer.py +369 -0
  106. massgen/tool/docs/builtin_tools.md +681 -0
  107. massgen/tool/docs/exceptions.md +794 -0
  108. massgen/tool/docs/execution_results.md +691 -0
  109. massgen/tool/docs/manager.md +887 -0
  110. massgen/tool/docs/workflow_toolkits.md +529 -0
  111. massgen/tool/workflow_toolkits/__init__.py +57 -0
  112. massgen/tool/workflow_toolkits/base.py +55 -0
  113. massgen/tool/workflow_toolkits/new_answer.py +126 -0
  114. massgen/tool/workflow_toolkits/vote.py +167 -0
  115. {massgen-0.1.0a3.dist-info → massgen-0.1.2.dist-info}/METADATA +87 -129
  116. {massgen-0.1.0a3.dist-info → massgen-0.1.2.dist-info}/RECORD +120 -44
  117. {massgen-0.1.0a3.dist-info → massgen-0.1.2.dist-info}/WHEEL +0 -0
  118. {massgen-0.1.0a3.dist-info → massgen-0.1.2.dist-info}/entry_points.txt +0 -0
  119. {massgen-0.1.0a3.dist-info → massgen-0.1.2.dist-info}/licenses/LICENSE +0 -0
  120. {massgen-0.1.0a3.dist-info → massgen-0.1.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,126 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ New Answer toolkit for MassGen workflow coordination.
4
+ """
5
+
6
+ from typing import Any, Dict, List, Optional
7
+
8
+ from .base import BaseToolkit, ToolType
9
+
10
+
11
+ class NewAnswerToolkit(BaseToolkit):
12
+ """New Answer toolkit for agent coordination workflows."""
13
+
14
+ def __init__(self, template_overrides: Optional[Dict[str, Any]] = None):
15
+ """
16
+ Initialize the New Answer toolkit.
17
+
18
+ Args:
19
+ template_overrides: Optional template overrides for customization
20
+ """
21
+ self._template_overrides = template_overrides or {}
22
+
23
+ @property
24
+ def toolkit_id(self) -> str:
25
+ """Unique identifier for new answer toolkit."""
26
+ return "new_answer"
27
+
28
+ @property
29
+ def toolkit_type(self) -> ToolType:
30
+ """Type of this toolkit."""
31
+ return ToolType.WORKFLOW
32
+
33
+ def is_enabled(self, config: Dict[str, Any]) -> bool:
34
+ """
35
+ Check if new answer is enabled in configuration.
36
+
37
+ Args:
38
+ config: Configuration dictionary.
39
+
40
+ Returns:
41
+ True if workflow tools are enabled or not explicitly disabled.
42
+ """
43
+ # Enable by default for workflow, unless explicitly disabled
44
+ return config.get("enable_workflow_tools", True)
45
+
46
+ def get_tools(self, config: Dict[str, Any]) -> List[Dict[str, Any]]:
47
+ """
48
+ Get new answer tool definition based on API format.
49
+
50
+ Args:
51
+ config: Configuration including api_format.
52
+
53
+ Returns:
54
+ List containing the new answer tool definition.
55
+ """
56
+ # Check for template override
57
+ if "new_answer_tool" in self._template_overrides:
58
+ override = self._template_overrides["new_answer_tool"]
59
+ if callable(override):
60
+ return [override()]
61
+ return [override]
62
+
63
+ api_format = config.get("api_format", "chat_completions")
64
+
65
+ if api_format == "claude":
66
+ # Claude native format
67
+ return [
68
+ {
69
+ "name": "new_answer",
70
+ "description": "Submit a new and improved answer",
71
+ "input_schema": {
72
+ "type": "object",
73
+ "properties": {
74
+ "content": {
75
+ "type": "string",
76
+ "description": "Your improved answer. If any builtin tools like search or code execution were used, mention how they are used here.",
77
+ },
78
+ },
79
+ "required": ["content"],
80
+ },
81
+ },
82
+ ]
83
+
84
+ elif api_format == "response":
85
+ # Response API format (OpenAI-style but simpler)
86
+ return [
87
+ {
88
+ "type": "function",
89
+ "function": {
90
+ "name": "new_answer",
91
+ "description": "Submit a new and improved answer",
92
+ "parameters": {
93
+ "type": "object",
94
+ "properties": {
95
+ "content": {
96
+ "type": "string",
97
+ "description": "Your improved answer. If any builtin tools like search or code execution were used, mention how they are used here.",
98
+ },
99
+ },
100
+ "required": ["content"],
101
+ },
102
+ },
103
+ },
104
+ ]
105
+
106
+ else:
107
+ # Default Chat Completions format
108
+ return [
109
+ {
110
+ "type": "function",
111
+ "function": {
112
+ "name": "new_answer",
113
+ "description": "Submit a new and improved answer",
114
+ "parameters": {
115
+ "type": "object",
116
+ "properties": {
117
+ "content": {
118
+ "type": "string",
119
+ "description": "Your improved answer. If any builtin tools like search or code execution were used, mention how they are used here.",
120
+ },
121
+ },
122
+ "required": ["content"],
123
+ },
124
+ },
125
+ },
126
+ ]
@@ -0,0 +1,167 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Vote toolkit for MassGen workflow coordination.
4
+ """
5
+
6
+ from typing import Any, Dict, List, Optional
7
+
8
+ from .base import BaseToolkit, ToolType
9
+
10
+
11
+ class VoteToolkit(BaseToolkit):
12
+ """Vote toolkit for agent coordination workflows."""
13
+
14
+ def __init__(self, valid_agent_ids: Optional[List[str]] = None, template_overrides: Optional[Dict[str, Any]] = None):
15
+ """
16
+ Initialize the Vote toolkit.
17
+
18
+ Args:
19
+ valid_agent_ids: List of valid agent IDs for voting
20
+ template_overrides: Optional template overrides for customization
21
+ """
22
+ self.valid_agent_ids = valid_agent_ids
23
+ self._template_overrides = template_overrides or {}
24
+
25
+ @property
26
+ def toolkit_id(self) -> str:
27
+ """Unique identifier for vote toolkit."""
28
+ return "vote"
29
+
30
+ @property
31
+ def toolkit_type(self) -> ToolType:
32
+ """Type of this toolkit."""
33
+ return ToolType.WORKFLOW
34
+
35
+ def is_enabled(self, config: Dict[str, Any]) -> bool:
36
+ """
37
+ Check if vote is enabled in configuration.
38
+
39
+ Args:
40
+ config: Configuration dictionary.
41
+
42
+ Returns:
43
+ True if workflow tools are enabled or not explicitly disabled.
44
+ """
45
+ # Enable by default for workflow, unless explicitly disabled
46
+ return config.get("enable_workflow_tools", True)
47
+
48
+ def set_valid_agent_ids(self, agent_ids: List[str]):
49
+ """
50
+ Update the valid agent IDs for voting.
51
+
52
+ Args:
53
+ agent_ids: List of valid agent IDs
54
+ """
55
+ self.valid_agent_ids = agent_ids
56
+
57
+ def get_tools(self, config: Dict[str, Any]) -> List[Dict[str, Any]]:
58
+ """
59
+ Get vote tool definition based on API format.
60
+
61
+ Args:
62
+ config: Configuration including api_format and potentially valid_agent_ids.
63
+
64
+ Returns:
65
+ List containing the vote tool definition.
66
+ """
67
+ # Check for template override
68
+ if "vote_tool" in self._template_overrides:
69
+ override = self._template_overrides["vote_tool"]
70
+ if callable(override):
71
+ return [override(self.valid_agent_ids)]
72
+ return [override]
73
+
74
+ # Get valid agent IDs from config if not set
75
+ valid_ids = config.get("valid_agent_ids", self.valid_agent_ids)
76
+
77
+ api_format = config.get("api_format", "chat_completions")
78
+
79
+ if api_format == "claude":
80
+ # Claude native format
81
+ tool_def = {
82
+ "name": "vote",
83
+ "description": "Vote for the best agent to present final answer",
84
+ "input_schema": {
85
+ "type": "object",
86
+ "properties": {
87
+ "agent_id": {
88
+ "type": "string",
89
+ "description": "Anonymous agent ID to vote for (e.g., 'agent1', 'agent2')",
90
+ },
91
+ "reason": {
92
+ "type": "string",
93
+ "description": "Brief reason why this agent has the best answer",
94
+ },
95
+ },
96
+ "required": ["agent_id", "reason"],
97
+ },
98
+ }
99
+
100
+ # Add enum constraint for valid agent IDs
101
+ if valid_ids:
102
+ anon_agent_ids = [f"agent{i}" for i in range(1, len(valid_ids) + 1)]
103
+ tool_def["input_schema"]["properties"]["agent_id"]["enum"] = anon_agent_ids
104
+
105
+ return [tool_def]
106
+
107
+ elif api_format == "response":
108
+ # Response API format
109
+ tool_def = {
110
+ "type": "function",
111
+ "function": {
112
+ "name": "vote",
113
+ "description": "Vote for the best agent to present final answer",
114
+ "parameters": {
115
+ "type": "object",
116
+ "properties": {
117
+ "agent_id": {
118
+ "type": "string",
119
+ "description": "Anonymous agent ID to vote for (e.g., 'agent1', 'agent2')",
120
+ },
121
+ "reason": {
122
+ "type": "string",
123
+ "description": "Brief reason why this agent has the best answer",
124
+ },
125
+ },
126
+ "required": ["agent_id", "reason"],
127
+ },
128
+ },
129
+ }
130
+
131
+ # Add enum constraint for valid agent IDs
132
+ if valid_ids:
133
+ anon_agent_ids = [f"agent{i}" for i in range(1, len(valid_ids) + 1)]
134
+ tool_def["function"]["parameters"]["properties"]["agent_id"]["enum"] = anon_agent_ids
135
+
136
+ return [tool_def]
137
+
138
+ else:
139
+ # Default Chat Completions format
140
+ tool_def = {
141
+ "type": "function",
142
+ "function": {
143
+ "name": "vote",
144
+ "description": "Vote for the best agent to present final answer",
145
+ "parameters": {
146
+ "type": "object",
147
+ "properties": {
148
+ "agent_id": {
149
+ "type": "string",
150
+ "description": "Anonymous agent ID to vote for (e.g., 'agent1', 'agent2')",
151
+ },
152
+ "reason": {
153
+ "type": "string",
154
+ "description": "Brief reason why this agent has the best answer",
155
+ },
156
+ },
157
+ "required": ["agent_id", "reason"],
158
+ },
159
+ },
160
+ }
161
+
162
+ # Add enum constraint for valid agent IDs
163
+ if valid_ids:
164
+ anon_agent_ids = [f"agent{i}" for i in range(1, len(valid_ids) + 1)]
165
+ tool_def["function"]["parameters"]["properties"]["agent_id"]["enum"] = anon_agent_ids
166
+
167
+ return [tool_def]