massgen 0.1.0a2__py3-none-any.whl → 0.1.1__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 +1 -1
- massgen/agent_config.py +17 -0
- massgen/api_params_handler/_api_params_handler_base.py +1 -0
- massgen/api_params_handler/_chat_completions_api_params_handler.py +8 -1
- massgen/api_params_handler/_claude_api_params_handler.py +8 -1
- massgen/api_params_handler/_gemini_api_params_handler.py +73 -0
- massgen/api_params_handler/_response_api_params_handler.py +8 -1
- massgen/backend/base.py +31 -0
- massgen/backend/{base_with_mcp.py → base_with_custom_tool_and_mcp.py} +282 -11
- massgen/backend/chat_completions.py +182 -92
- massgen/backend/claude.py +115 -18
- massgen/backend/claude_code.py +378 -14
- massgen/backend/docs/CLAUDE_API_RESEARCH.md +3 -3
- massgen/backend/gemini.py +1275 -1607
- massgen/backend/gemini_mcp_manager.py +545 -0
- massgen/backend/gemini_trackers.py +344 -0
- massgen/backend/gemini_utils.py +43 -0
- massgen/backend/response.py +129 -70
- massgen/cli.py +643 -132
- massgen/config_builder.py +381 -32
- massgen/configs/README.md +111 -80
- massgen/configs/basic/multi/three_agents_default.yaml +1 -1
- massgen/configs/basic/single/single_agent.yaml +1 -1
- massgen/configs/providers/openai/gpt5_nano.yaml +3 -3
- massgen/configs/tools/custom_tools/claude_code_custom_tool_example.yaml +32 -0
- massgen/configs/tools/custom_tools/claude_code_custom_tool_example_no_path.yaml +28 -0
- massgen/configs/tools/custom_tools/claude_code_custom_tool_with_mcp_example.yaml +40 -0
- massgen/configs/tools/custom_tools/claude_code_custom_tool_with_wrong_mcp_example.yaml +38 -0
- massgen/configs/tools/custom_tools/claude_code_wrong_custom_tool_with_mcp_example.yaml +38 -0
- massgen/configs/tools/custom_tools/claude_custom_tool_example.yaml +24 -0
- massgen/configs/tools/custom_tools/claude_custom_tool_example_no_path.yaml +22 -0
- massgen/configs/tools/custom_tools/claude_custom_tool_with_mcp_example.yaml +35 -0
- massgen/configs/tools/custom_tools/claude_custom_tool_with_wrong_mcp_example.yaml +33 -0
- massgen/configs/tools/custom_tools/claude_wrong_custom_tool_with_mcp_example.yaml +33 -0
- massgen/configs/tools/custom_tools/gemini_custom_tool_example.yaml +24 -0
- massgen/configs/tools/custom_tools/gemini_custom_tool_example_no_path.yaml +22 -0
- massgen/configs/tools/custom_tools/gemini_custom_tool_with_mcp_example.yaml +35 -0
- massgen/configs/tools/custom_tools/gemini_custom_tool_with_wrong_mcp_example.yaml +33 -0
- massgen/configs/tools/custom_tools/gemini_wrong_custom_tool_with_mcp_example.yaml +33 -0
- massgen/configs/tools/custom_tools/github_issue_market_analysis.yaml +94 -0
- massgen/configs/tools/custom_tools/gpt5_nano_custom_tool_example.yaml +24 -0
- massgen/configs/tools/custom_tools/gpt5_nano_custom_tool_example_no_path.yaml +22 -0
- massgen/configs/tools/custom_tools/gpt5_nano_custom_tool_with_mcp_example.yaml +35 -0
- massgen/configs/tools/custom_tools/gpt5_nano_custom_tool_with_wrong_mcp_example.yaml +33 -0
- massgen/configs/tools/custom_tools/gpt5_nano_wrong_custom_tool_with_mcp_example.yaml +33 -0
- massgen/configs/tools/custom_tools/gpt_oss_custom_tool_example.yaml +25 -0
- massgen/configs/tools/custom_tools/gpt_oss_custom_tool_example_no_path.yaml +23 -0
- massgen/configs/tools/custom_tools/gpt_oss_custom_tool_with_mcp_example.yaml +34 -0
- massgen/configs/tools/custom_tools/gpt_oss_custom_tool_with_wrong_mcp_example.yaml +34 -0
- massgen/configs/tools/custom_tools/gpt_oss_wrong_custom_tool_with_mcp_example.yaml +34 -0
- massgen/configs/tools/custom_tools/grok3_mini_custom_tool_example.yaml +24 -0
- massgen/configs/tools/custom_tools/grok3_mini_custom_tool_example_no_path.yaml +22 -0
- massgen/configs/tools/custom_tools/grok3_mini_custom_tool_with_mcp_example.yaml +35 -0
- massgen/configs/tools/custom_tools/grok3_mini_custom_tool_with_wrong_mcp_example.yaml +33 -0
- massgen/configs/tools/custom_tools/grok3_mini_wrong_custom_tool_with_mcp_example.yaml +33 -0
- massgen/configs/tools/custom_tools/qwen_api_custom_tool_example.yaml +25 -0
- massgen/configs/tools/custom_tools/qwen_api_custom_tool_example_no_path.yaml +23 -0
- massgen/configs/tools/custom_tools/qwen_api_custom_tool_with_mcp_example.yaml +36 -0
- massgen/configs/tools/custom_tools/qwen_api_custom_tool_with_wrong_mcp_example.yaml +34 -0
- massgen/configs/tools/custom_tools/qwen_api_wrong_custom_tool_with_mcp_example.yaml +34 -0
- massgen/configs/tools/custom_tools/qwen_local_custom_tool_example.yaml +24 -0
- massgen/configs/tools/custom_tools/qwen_local_custom_tool_example_no_path.yaml +22 -0
- massgen/configs/tools/custom_tools/qwen_local_custom_tool_with_mcp_example.yaml +35 -0
- massgen/configs/tools/custom_tools/qwen_local_custom_tool_with_wrong_mcp_example.yaml +33 -0
- massgen/configs/tools/custom_tools/qwen_local_wrong_custom_tool_with_mcp_example.yaml +33 -0
- massgen/configs/tools/filesystem/claude_code_context_sharing.yaml +1 -1
- massgen/configs/voting/gemini_gpt_voting_sensitivity.yaml +67 -0
- massgen/formatter/_chat_completions_formatter.py +104 -0
- massgen/formatter/_claude_formatter.py +120 -0
- massgen/formatter/_gemini_formatter.py +448 -0
- massgen/formatter/_response_formatter.py +88 -0
- massgen/frontend/coordination_ui.py +4 -2
- massgen/logger_config.py +35 -3
- massgen/message_templates.py +56 -6
- massgen/orchestrator.py +179 -10
- massgen/stream_chunk/base.py +3 -0
- massgen/tests/custom_tools_example.py +392 -0
- massgen/tests/mcp_test_server.py +17 -7
- massgen/tests/test_config_builder.py +423 -0
- massgen/tests/test_custom_tools.py +401 -0
- massgen/tests/test_tools.py +127 -0
- massgen/tool/README.md +935 -0
- massgen/tool/__init__.py +39 -0
- massgen/tool/_async_helpers.py +70 -0
- massgen/tool/_basic/__init__.py +8 -0
- massgen/tool/_basic/_two_num_tool.py +24 -0
- massgen/tool/_code_executors/__init__.py +10 -0
- massgen/tool/_code_executors/_python_executor.py +74 -0
- massgen/tool/_code_executors/_shell_executor.py +61 -0
- massgen/tool/_exceptions.py +39 -0
- massgen/tool/_file_handlers/__init__.py +10 -0
- massgen/tool/_file_handlers/_file_operations.py +218 -0
- massgen/tool/_manager.py +634 -0
- massgen/tool/_registered_tool.py +88 -0
- massgen/tool/_result.py +66 -0
- massgen/tool/_self_evolution/_github_issue_analyzer.py +369 -0
- massgen/tool/docs/builtin_tools.md +681 -0
- massgen/tool/docs/exceptions.md +794 -0
- massgen/tool/docs/execution_results.md +691 -0
- massgen/tool/docs/manager.md +887 -0
- massgen/tool/docs/workflow_toolkits.md +529 -0
- massgen/tool/workflow_toolkits/__init__.py +57 -0
- massgen/tool/workflow_toolkits/base.py +55 -0
- massgen/tool/workflow_toolkits/new_answer.py +126 -0
- massgen/tool/workflow_toolkits/vote.py +167 -0
- {massgen-0.1.0a2.dist-info → massgen-0.1.1.dist-info}/METADATA +89 -131
- {massgen-0.1.0a2.dist-info → massgen-0.1.1.dist-info}/RECORD +111 -36
- {massgen-0.1.0a2.dist-info → massgen-0.1.1.dist-info}/WHEEL +0 -0
- {massgen-0.1.0a2.dist-info → massgen-0.1.1.dist-info}/entry_points.txt +0 -0
- {massgen-0.1.0a2.dist-info → massgen-0.1.1.dist-info}/licenses/LICENSE +0 -0
- {massgen-0.1.0a2.dist-info → massgen-0.1.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
# Workflow Toolkits Documentation
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Workflow toolkits are specialized tools designed for multi-agent coordination in MassGen. They enable agents to submit new answers, vote on proposals, and participate in collaborative decision-making processes.
|
|
6
|
+
|
|
7
|
+
**What are Workflow Toolkits?**
|
|
8
|
+
Think of workflow toolkits as the communication system that allows agents to coordinate with each other. Just like team members in a meeting can propose ideas and vote on them, workflow toolkits give agents the ability to:
|
|
9
|
+
- Submit new answer proposals during coordination rounds
|
|
10
|
+
- Vote for which agent's answer should be used as the final result
|
|
11
|
+
- Coordinate their work toward a common goal
|
|
12
|
+
|
|
13
|
+
**Why do you need them?**
|
|
14
|
+
Multi-agent systems become much more powerful when agents can collaborate. Workflow toolkits enable:
|
|
15
|
+
- **Democratic Decision Making**: Agents vote on the best solution
|
|
16
|
+
- **Iterative Refinement**: Agents can revise their answers based on others' work
|
|
17
|
+
- **Consensus Building**: System converges on the best answer through collaboration
|
|
18
|
+
- **Specialization**: Different agents can focus on different aspects
|
|
19
|
+
|
|
20
|
+
## Architecture
|
|
21
|
+
|
|
22
|
+
```mermaid
|
|
23
|
+
graph TB
|
|
24
|
+
subgraph Agent Coordination
|
|
25
|
+
A1[Agent 1] -->|new_answer| H[Coordination Hub]
|
|
26
|
+
A2[Agent 2] -->|new_answer| H
|
|
27
|
+
A3[Agent 3] -->|new_answer| H
|
|
28
|
+
|
|
29
|
+
H -->|Context| A1
|
|
30
|
+
H -->|Context| A2
|
|
31
|
+
H -->|Context| A3
|
|
32
|
+
|
|
33
|
+
A1 -->|vote| V[Vote Collector]
|
|
34
|
+
A2 -->|vote| V
|
|
35
|
+
A3 -->|vote| V
|
|
36
|
+
|
|
37
|
+
V -->|Tally| W[Winner Selection]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
classDef agent fill:#e1f5fe,stroke:#0288d1,stroke-width:2px
|
|
41
|
+
classDef hub fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
|
|
42
|
+
classDef vote fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
|
|
43
|
+
|
|
44
|
+
class A1,A2,A3 agent
|
|
45
|
+
class H hub
|
|
46
|
+
class V,W vote
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## BaseToolkit
|
|
50
|
+
|
|
51
|
+
Base class for all workflow toolkits.
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from abc import ABC, abstractmethod
|
|
55
|
+
from enum import Enum
|
|
56
|
+
from typing import Any, Dict, List
|
|
57
|
+
|
|
58
|
+
class ToolType(Enum):
|
|
59
|
+
"""Types of tools available in the system."""
|
|
60
|
+
BUILTIN = "builtin"
|
|
61
|
+
WORKFLOW = "workflow"
|
|
62
|
+
MCP = "mcp"
|
|
63
|
+
|
|
64
|
+
class BaseToolkit(ABC):
|
|
65
|
+
"""Abstract base class for all toolkits."""
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
@abstractmethod
|
|
69
|
+
def toolkit_id(self) -> str:
|
|
70
|
+
"""Unique identifier for the toolkit."""
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
@abstractmethod
|
|
74
|
+
def toolkit_type(self) -> ToolType:
|
|
75
|
+
"""Type of the toolkit."""
|
|
76
|
+
|
|
77
|
+
@abstractmethod
|
|
78
|
+
def get_tools(self, config: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
79
|
+
"""Get tool definitions based on configuration."""
|
|
80
|
+
|
|
81
|
+
@abstractmethod
|
|
82
|
+
def is_enabled(self, config: Dict[str, Any]) -> bool:
|
|
83
|
+
"""Check if the toolkit is enabled."""
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## NewAnswerToolkit
|
|
87
|
+
|
|
88
|
+
**What it does**: Provides the `new_answer` tool that allows agents to submit updated answers during coordination rounds. This is how agents participate in the collaborative refinement process.
|
|
89
|
+
|
|
90
|
+
**Why use it**: Essential for multi-agent coordination. Agents need a way to submit their answers and see others' answers to collaborate effectively.
|
|
91
|
+
|
|
92
|
+
**Location**: `massgen.tool.workflow_toolkits.new_answer`
|
|
93
|
+
|
|
94
|
+
### Initialization
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from massgen.tool.workflow_toolkits import NewAnswerToolkit
|
|
98
|
+
|
|
99
|
+
toolkit = NewAnswerToolkit(template_overrides=None)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Parameters**:
|
|
103
|
+
- `template_overrides` (optional): Custom descriptions or schema modifications
|
|
104
|
+
|
|
105
|
+
### Methods
|
|
106
|
+
|
|
107
|
+
#### get_tools()
|
|
108
|
+
|
|
109
|
+
**What it does**: Generates tool definitions for the `new_answer` tool in the requested API format.
|
|
110
|
+
|
|
111
|
+
**Parameters**:
|
|
112
|
+
- `config` (required): Configuration dictionary with:
|
|
113
|
+
- `api_format`: Format to use ("chat_completions", "claude", "response")
|
|
114
|
+
- `enable_workflow_tools`: Whether workflow tools are enabled
|
|
115
|
+
|
|
116
|
+
**Returns**: List of tool definitions (empty if not enabled)
|
|
117
|
+
|
|
118
|
+
**Supported API Formats**:
|
|
119
|
+
|
|
120
|
+
1. **chat_completions**: OpenAI function calling format
|
|
121
|
+
2. **claude**: Anthropic Claude tool format
|
|
122
|
+
3. **response**: Google Gemini function declarations
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
# OpenAI format
|
|
126
|
+
tools = toolkit.get_tools({
|
|
127
|
+
"api_format": "chat_completions",
|
|
128
|
+
"enable_workflow_tools": True
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
# Claude format
|
|
132
|
+
tools = toolkit.get_tools({
|
|
133
|
+
"api_format": "claude",
|
|
134
|
+
"enable_workflow_tools": True
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
# Gemini format
|
|
138
|
+
tools = toolkit.get_tools({
|
|
139
|
+
"api_format": "response",
|
|
140
|
+
"enable_workflow_tools": True
|
|
141
|
+
})
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### is_enabled()
|
|
145
|
+
|
|
146
|
+
**What it does**: Checks if the toolkit should be active based on configuration.
|
|
147
|
+
|
|
148
|
+
**Returns**: Boolean indicating if toolkit is enabled
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
config = {
|
|
152
|
+
"api_format": "chat_completions",
|
|
153
|
+
"enable_workflow_tools": True
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if toolkit.is_enabled(config):
|
|
157
|
+
print("NewAnswerToolkit is active")
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Tool Schema
|
|
161
|
+
|
|
162
|
+
The `new_answer` tool accepts these parameters:
|
|
163
|
+
|
|
164
|
+
**Parameters**:
|
|
165
|
+
- `new_answer` (required): The agent's updated answer or analysis
|
|
166
|
+
|
|
167
|
+
**Example Tool Call**:
|
|
168
|
+
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"name": "new_answer",
|
|
172
|
+
"input": {
|
|
173
|
+
"new_answer": "Based on the analysis, the optimal solution is to use approach B because it has better performance characteristics and lower complexity. The data shows a 30% improvement in processing time compared to approach A.",
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Integration Example
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
from massgen.tool.workflow_toolkits import NewAnswerToolkit
|
|
182
|
+
|
|
183
|
+
# Create toolkit
|
|
184
|
+
new_answer_toolkit = NewAnswerToolkit()
|
|
185
|
+
|
|
186
|
+
# Get tool definitions
|
|
187
|
+
config = {
|
|
188
|
+
"api_format": "chat_completions",
|
|
189
|
+
"enable_workflow_tools": True
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
tools = new_answer_toolkit.get_tools(config)
|
|
193
|
+
|
|
194
|
+
# Use with agent
|
|
195
|
+
agent_tools.extend(tools)
|
|
196
|
+
|
|
197
|
+
# Agent can now call new_answer during coordination
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Usage Pattern
|
|
201
|
+
|
|
202
|
+
**Coordination Flow**:
|
|
203
|
+
|
|
204
|
+
1. **Initial Answer**: Agent submits first answer via `new_answer`
|
|
205
|
+
2. **See Others**: Agent receives context showing other agents' answers
|
|
206
|
+
3. **Refine**: Agent calls `new_answer` again with improved answer
|
|
207
|
+
4. **Iterate**: Process continues until convergence or max rounds
|
|
208
|
+
|
|
209
|
+
**Example Agent Behavior**:
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
# Round 1: Initial answer
|
|
213
|
+
await call_tool("new_answer", {
|
|
214
|
+
"new_answer": "Initial analysis suggests X",
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
# Round 2: After seeing other agents' work
|
|
218
|
+
await call_tool("new_answer", {
|
|
219
|
+
"new_answer": "Refined analysis: X is optimal because of Y and Z. Agent2's point about performance is valid.",
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
# Round 3: Final refinement
|
|
223
|
+
await call_tool("new_answer", {
|
|
224
|
+
"new_answer": "Final comprehensive answer incorporating all perspectives...",
|
|
225
|
+
})
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## VoteToolkit
|
|
229
|
+
|
|
230
|
+
**What it does**: Provides the `vote` tool that allows agents to vote for which agent's answer should be selected as the final result.
|
|
231
|
+
|
|
232
|
+
**Why use it**: Enables democratic decision-making in multi-agent systems. Instead of picking randomly, agents collectively decide on the best answer.
|
|
233
|
+
|
|
234
|
+
**Location**: `massgen.tool.workflow_toolkits.vote`
|
|
235
|
+
|
|
236
|
+
### Initialization
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
from massgen.tool.workflow_toolkits import VoteToolkit
|
|
240
|
+
|
|
241
|
+
toolkit = VoteToolkit(
|
|
242
|
+
valid_agent_ids=["agent1", "agent2", "agent3"],
|
|
243
|
+
template_overrides=None
|
|
244
|
+
)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Parameters**:
|
|
248
|
+
- `valid_agent_ids` (optional): List of valid agent IDs that can be voted for
|
|
249
|
+
- `template_overrides` (optional): Custom descriptions or schema modifications
|
|
250
|
+
|
|
251
|
+
### Methods
|
|
252
|
+
|
|
253
|
+
#### get_tools()
|
|
254
|
+
|
|
255
|
+
**What it does**: Generates tool definitions for the `vote` tool in the requested API format.
|
|
256
|
+
|
|
257
|
+
**Parameters**:
|
|
258
|
+
- `config` (required): Configuration dictionary (same format as NewAnswerToolkit)
|
|
259
|
+
|
|
260
|
+
**Returns**: List of tool definitions
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
tools = toolkit.get_tools({
|
|
264
|
+
"api_format": "chat_completions",
|
|
265
|
+
"enable_workflow_tools": True
|
|
266
|
+
})
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
#### is_enabled()
|
|
270
|
+
|
|
271
|
+
**What it does**: Checks if voting is enabled.
|
|
272
|
+
|
|
273
|
+
**Returns**: Boolean
|
|
274
|
+
|
|
275
|
+
### Tool Schema
|
|
276
|
+
|
|
277
|
+
The `vote` tool accepts these parameters:
|
|
278
|
+
|
|
279
|
+
**Parameters**:
|
|
280
|
+
- `agent_id` (required): ID of the agent to vote for
|
|
281
|
+
- `reason` (optional): Explanation for the vote
|
|
282
|
+
|
|
283
|
+
**Validation**:
|
|
284
|
+
- If `valid_agent_ids` is set, votes are validated against this list
|
|
285
|
+
- Invalid agent IDs are rejected
|
|
286
|
+
|
|
287
|
+
**Example Tool Call**:
|
|
288
|
+
|
|
289
|
+
```json
|
|
290
|
+
{
|
|
291
|
+
"name": "vote",
|
|
292
|
+
"input": {
|
|
293
|
+
"agent_id": "agent2",
|
|
294
|
+
"reason": "Agent2's answer is most comprehensive and addresses all aspects of the problem. The performance analysis is thorough and the solution is practical."
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Integration Example
|
|
300
|
+
|
|
301
|
+
```python
|
|
302
|
+
from massgen.tool.workflow_toolkits import VoteToolkit
|
|
303
|
+
|
|
304
|
+
# Create toolkit with valid agents
|
|
305
|
+
vote_toolkit = VoteToolkit(
|
|
306
|
+
valid_agent_ids=["researcher", "analyst", "expert"]
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
# Get tool definitions
|
|
310
|
+
config = {
|
|
311
|
+
"api_format": "chat_completions",
|
|
312
|
+
"enable_workflow_tools": True,
|
|
313
|
+
"valid_agent_ids": ["researcher", "analyst", "expert"]
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
tools = vote_toolkit.get_tools(config)
|
|
317
|
+
|
|
318
|
+
# Use with agent
|
|
319
|
+
agent_tools.extend(tools)
|
|
320
|
+
|
|
321
|
+
# Agent can now vote
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Voting Patterns
|
|
325
|
+
|
|
326
|
+
**Simple Voting**:
|
|
327
|
+
|
|
328
|
+
```python
|
|
329
|
+
# Agent votes for the best answer
|
|
330
|
+
await call_tool("vote", {
|
|
331
|
+
"agent_id": "expert",
|
|
332
|
+
"reason": "Expert provided the most detailed technical analysis"
|
|
333
|
+
})
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Helper Function
|
|
337
|
+
|
|
338
|
+
### get_workflow_tools()
|
|
339
|
+
|
|
340
|
+
**What it does**: Convenience function that returns tools from both NewAnswerToolkit and VoteToolkit.
|
|
341
|
+
|
|
342
|
+
**Why use it**: Simplifies setup when you need both toolkits.
|
|
343
|
+
|
|
344
|
+
**Location**: `massgen.tool.workflow_toolkits`
|
|
345
|
+
|
|
346
|
+
```python
|
|
347
|
+
from massgen.tool.workflow_toolkits import get_workflow_tools
|
|
348
|
+
|
|
349
|
+
tools = get_workflow_tools(
|
|
350
|
+
valid_agent_ids=["agent1", "agent2", "agent3"],
|
|
351
|
+
template_overrides=None,
|
|
352
|
+
api_format="chat_completions"
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
# Returns tools from both toolkits:
|
|
356
|
+
# - new_answer
|
|
357
|
+
# - vote
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**Parameters**:
|
|
361
|
+
- `valid_agent_ids` (optional): List of valid agent IDs for voting
|
|
362
|
+
- `template_overrides` (optional): Custom descriptions
|
|
363
|
+
- `api_format` (optional): API format to use (default: "chat_completions")
|
|
364
|
+
|
|
365
|
+
**Returns**: List of tool definitions from both toolkits
|
|
366
|
+
|
|
367
|
+
## Complete Integration Example
|
|
368
|
+
|
|
369
|
+
```python
|
|
370
|
+
from massgen.tool import ToolManager
|
|
371
|
+
from massgen.tool.workflow_toolkits import get_workflow_tools
|
|
372
|
+
|
|
373
|
+
# Set up tool manager
|
|
374
|
+
manager = ToolManager()
|
|
375
|
+
|
|
376
|
+
# Get workflow tools
|
|
377
|
+
workflow_tools = get_workflow_tools(
|
|
378
|
+
valid_agent_ids=["researcher", "analyst", "expert"],
|
|
379
|
+
api_format="chat_completions"
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
# Add to agent's tool list
|
|
383
|
+
agent_config = {
|
|
384
|
+
"tools": workflow_tools,
|
|
385
|
+
"enable_workflow_tools": True
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
# During coordination:
|
|
389
|
+
# 1. Agents submit answers via new_answer
|
|
390
|
+
# 2. System shares context between agents
|
|
391
|
+
# 3. Agents refine answers
|
|
392
|
+
# 4. Agents vote via vote
|
|
393
|
+
# 5. System selects winner based on votes
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
## Advanced Usage
|
|
397
|
+
|
|
398
|
+
### Custom Template Overrides
|
|
399
|
+
|
|
400
|
+
Override default descriptions or add custom fields:
|
|
401
|
+
|
|
402
|
+
```python
|
|
403
|
+
template_overrides = {
|
|
404
|
+
"new_answer": {
|
|
405
|
+
"description": "Submit your analysis with supporting evidence",
|
|
406
|
+
"parameters": {
|
|
407
|
+
"additional_field": {
|
|
408
|
+
"type": "string",
|
|
409
|
+
"description": "Custom field"
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
toolkit = NewAnswerToolkit(template_overrides=template_overrides)
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Dynamic Agent Lists
|
|
419
|
+
|
|
420
|
+
Update valid agents dynamically:
|
|
421
|
+
|
|
422
|
+
```python
|
|
423
|
+
# Initial setup
|
|
424
|
+
vote_toolkit = VoteToolkit(valid_agent_ids=["agent1", "agent2"])
|
|
425
|
+
|
|
426
|
+
# Update for new round (create new instance)
|
|
427
|
+
vote_toolkit = VoteToolkit(valid_agent_ids=["agent1", "agent2", "agent3"])
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Multi-Format Support
|
|
431
|
+
|
|
432
|
+
Generate tools for multiple API formats:
|
|
433
|
+
|
|
434
|
+
```python
|
|
435
|
+
new_answer_toolkit = NewAnswerToolkit()
|
|
436
|
+
|
|
437
|
+
# OpenAI agents
|
|
438
|
+
openai_tools = new_answer_toolkit.get_tools({
|
|
439
|
+
"api_format": "chat_completions",
|
|
440
|
+
"enable_workflow_tools": True
|
|
441
|
+
})
|
|
442
|
+
|
|
443
|
+
# Claude agents
|
|
444
|
+
claude_tools = new_answer_toolkit.get_tools({
|
|
445
|
+
"api_format": "claude",
|
|
446
|
+
"enable_workflow_tools": True
|
|
447
|
+
})
|
|
448
|
+
|
|
449
|
+
# Gemini agents
|
|
450
|
+
gemini_tools = new_answer_toolkit.get_tools({
|
|
451
|
+
"api_format": "response",
|
|
452
|
+
"enable_workflow_tools": True
|
|
453
|
+
})
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
## Best Practices
|
|
457
|
+
|
|
458
|
+
### NewAnswerToolkit
|
|
459
|
+
|
|
460
|
+
1. **Incremental Refinement**: Build on previous answers
|
|
461
|
+
2. **Reference Others**: Acknowledge other agents' contributions
|
|
462
|
+
|
|
463
|
+
### VoteToolkit
|
|
464
|
+
|
|
465
|
+
1. **Reasoned Votes**: Always include reasoning
|
|
466
|
+
2. **Objective Criteria**: Base votes on clear criteria
|
|
467
|
+
3. **Valid IDs**: Ensure agent IDs are correct
|
|
468
|
+
4. **Respectful Feedback**: Explain votes constructively
|
|
469
|
+
|
|
470
|
+
### General
|
|
471
|
+
|
|
472
|
+
1. **Enable Both**: Use NewAnswer and Vote together
|
|
473
|
+
2. **Validate Configuration**: Check `enable_workflow_tools` flag
|
|
474
|
+
3. **Handle Errors**: Gracefully handle tool call failures
|
|
475
|
+
4. **Monitor Usage**: Track coordination patterns
|
|
476
|
+
|
|
477
|
+
## Troubleshooting
|
|
478
|
+
|
|
479
|
+
### Tools Not Available
|
|
480
|
+
|
|
481
|
+
**Problem**: Workflow tools don't appear in agent's tool list
|
|
482
|
+
|
|
483
|
+
**Solutions**:
|
|
484
|
+
```python
|
|
485
|
+
# Check enable flag
|
|
486
|
+
config["enable_workflow_tools"] = True
|
|
487
|
+
|
|
488
|
+
# Verify toolkit is enabled
|
|
489
|
+
assert toolkit.is_enabled(config)
|
|
490
|
+
|
|
491
|
+
# Check API format
|
|
492
|
+
assert config["api_format"] in ["chat_completions", "claude", "response"]
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Invalid Agent ID
|
|
496
|
+
|
|
497
|
+
**Problem**: Vote rejected due to invalid agent ID
|
|
498
|
+
|
|
499
|
+
**Solutions**:
|
|
500
|
+
```python
|
|
501
|
+
# Check valid_agent_ids list
|
|
502
|
+
print(f"Valid agents: {config.get('valid_agent_ids', [])}")
|
|
503
|
+
|
|
504
|
+
# Ensure agent ID matches exactly
|
|
505
|
+
vote_toolkit = VoteToolkit(valid_agent_ids=["agent_1", "agent_2"])
|
|
506
|
+
# Use "agent_1" not "agent1" or "Agent_1"
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### Tool Schema Mismatch
|
|
510
|
+
|
|
511
|
+
**Problem**: Tool call fails due to schema mismatch
|
|
512
|
+
|
|
513
|
+
**Solutions**:
|
|
514
|
+
```python
|
|
515
|
+
# Verify tool schema
|
|
516
|
+
tools = toolkit.get_tools(config)
|
|
517
|
+
print(json.dumps(tools[0], indent=2))
|
|
518
|
+
|
|
519
|
+
# Check required parameters
|
|
520
|
+
# new_answer requires: new_answer, summary
|
|
521
|
+
# vote requires: agent_id
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
For more information, see:
|
|
527
|
+
- [ToolManager Documentation](manager.md)
|
|
528
|
+
- [ExecutionResult Documentation](execution_results.md)
|
|
529
|
+
- [Built-in Tools Guide](builtin_tools.md)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Workflow toolkits for MassGen coordination.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Dict, List, Optional
|
|
7
|
+
|
|
8
|
+
from .base import BaseToolkit, ToolType
|
|
9
|
+
from .new_answer import NewAnswerToolkit
|
|
10
|
+
from .vote import VoteToolkit
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"BaseToolkit",
|
|
14
|
+
"ToolType",
|
|
15
|
+
"NewAnswerToolkit",
|
|
16
|
+
"VoteToolkit",
|
|
17
|
+
"get_workflow_tools",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_workflow_tools(
|
|
22
|
+
valid_agent_ids: Optional[List[str]] = None,
|
|
23
|
+
template_overrides: Optional[Dict] = None,
|
|
24
|
+
api_format: str = "chat_completions",
|
|
25
|
+
) -> List[Dict]:
|
|
26
|
+
"""
|
|
27
|
+
Get workflow tool definitions with proper formatting.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
valid_agent_ids: List of valid agent IDs for voting
|
|
31
|
+
template_overrides: Optional template overrides
|
|
32
|
+
api_format: API format to use (chat_completions, claude, response)
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
List of tool definitions
|
|
36
|
+
"""
|
|
37
|
+
tools = []
|
|
38
|
+
|
|
39
|
+
# Create config for tools
|
|
40
|
+
config = {
|
|
41
|
+
"api_format": api_format,
|
|
42
|
+
"enable_workflow_tools": True,
|
|
43
|
+
"valid_agent_ids": valid_agent_ids,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# Get new_answer tool
|
|
47
|
+
new_answer_toolkit = NewAnswerToolkit(template_overrides=template_overrides)
|
|
48
|
+
tools.extend(new_answer_toolkit.get_tools(config))
|
|
49
|
+
|
|
50
|
+
# Get vote tool
|
|
51
|
+
vote_toolkit = VoteToolkit(
|
|
52
|
+
valid_agent_ids=valid_agent_ids,
|
|
53
|
+
template_overrides=template_overrides,
|
|
54
|
+
)
|
|
55
|
+
tools.extend(vote_toolkit.get_tools(config))
|
|
56
|
+
|
|
57
|
+
return tools
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Base classes for workflow toolkits.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from abc import ABC, abstractmethod
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from typing import Any, Dict, List
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ToolType(Enum):
|
|
12
|
+
"""Types of tools available in the system."""
|
|
13
|
+
|
|
14
|
+
BUILTIN = "builtin"
|
|
15
|
+
WORKFLOW = "workflow"
|
|
16
|
+
MCP = "mcp"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BaseToolkit(ABC):
|
|
20
|
+
"""Abstract base class for all toolkits."""
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
@abstractmethod
|
|
24
|
+
def toolkit_id(self) -> str:
|
|
25
|
+
"""Unique identifier for the toolkit."""
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
@abstractmethod
|
|
29
|
+
def toolkit_type(self) -> ToolType:
|
|
30
|
+
"""Type of the toolkit."""
|
|
31
|
+
|
|
32
|
+
@abstractmethod
|
|
33
|
+
def get_tools(self, config: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
34
|
+
"""
|
|
35
|
+
Get tool definitions based on configuration.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
config: Configuration dictionary containing parameters like
|
|
39
|
+
api_format, enable flags, etc.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
List of tool definitions in the appropriate format.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
@abstractmethod
|
|
46
|
+
def is_enabled(self, config: Dict[str, Any]) -> bool:
|
|
47
|
+
"""
|
|
48
|
+
Check if the toolkit is enabled based on configuration.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
config: Configuration dictionary.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
True if the toolkit is enabled, False otherwise.
|
|
55
|
+
"""
|