hanzo-mcp 0.7.6__py3-none-any.whl → 0.8.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 hanzo-mcp might be problematic. Click here for more details.
- hanzo_mcp/__init__.py +7 -1
- hanzo_mcp/__main__.py +1 -1
- hanzo_mcp/analytics/__init__.py +2 -2
- hanzo_mcp/analytics/posthog_analytics.py +76 -82
- hanzo_mcp/cli.py +31 -36
- hanzo_mcp/cli_enhanced.py +94 -72
- hanzo_mcp/cli_plugin.py +27 -17
- hanzo_mcp/config/__init__.py +2 -2
- hanzo_mcp/config/settings.py +112 -88
- hanzo_mcp/config/tool_config.py +32 -34
- hanzo_mcp/dev_server.py +66 -67
- hanzo_mcp/prompts/__init__.py +94 -12
- hanzo_mcp/prompts/enhanced_prompts.py +809 -0
- hanzo_mcp/prompts/example_custom_prompt.py +6 -5
- hanzo_mcp/prompts/project_todo_reminder.py +0 -1
- hanzo_mcp/prompts/tool_explorer.py +10 -7
- hanzo_mcp/server.py +17 -21
- hanzo_mcp/server_enhanced.py +15 -22
- hanzo_mcp/tools/__init__.py +56 -28
- hanzo_mcp/tools/agent/__init__.py +16 -19
- hanzo_mcp/tools/agent/agent.py +82 -65
- hanzo_mcp/tools/agent/agent_tool.py +152 -122
- hanzo_mcp/tools/agent/agent_tool_v1_deprecated.py +66 -62
- hanzo_mcp/tools/agent/clarification_protocol.py +55 -50
- hanzo_mcp/tools/agent/clarification_tool.py +11 -10
- hanzo_mcp/tools/agent/claude_cli_tool.py +21 -20
- hanzo_mcp/tools/agent/claude_desktop_auth.py +130 -144
- hanzo_mcp/tools/agent/cli_agent_base.py +59 -53
- hanzo_mcp/tools/agent/code_auth.py +102 -107
- hanzo_mcp/tools/agent/code_auth_tool.py +28 -27
- hanzo_mcp/tools/agent/codex_cli_tool.py +20 -19
- hanzo_mcp/tools/agent/critic_tool.py +86 -73
- hanzo_mcp/tools/agent/gemini_cli_tool.py +21 -20
- hanzo_mcp/tools/agent/grok_cli_tool.py +21 -20
- hanzo_mcp/tools/agent/iching_tool.py +404 -139
- hanzo_mcp/tools/agent/network_tool.py +89 -73
- hanzo_mcp/tools/agent/prompt.py +2 -1
- hanzo_mcp/tools/agent/review_tool.py +101 -98
- hanzo_mcp/tools/agent/swarm_alias.py +87 -0
- hanzo_mcp/tools/agent/swarm_tool.py +246 -161
- hanzo_mcp/tools/agent/swarm_tool_v1_deprecated.py +134 -92
- hanzo_mcp/tools/agent/tool_adapter.py +21 -11
- hanzo_mcp/tools/common/__init__.py +1 -1
- hanzo_mcp/tools/common/base.py +3 -5
- hanzo_mcp/tools/common/batch_tool.py +46 -39
- hanzo_mcp/tools/common/config_tool.py +120 -84
- hanzo_mcp/tools/common/context.py +1 -5
- hanzo_mcp/tools/common/context_fix.py +5 -3
- hanzo_mcp/tools/common/critic_tool.py +4 -8
- hanzo_mcp/tools/common/decorators.py +58 -56
- hanzo_mcp/tools/common/enhanced_base.py +29 -32
- hanzo_mcp/tools/common/fastmcp_pagination.py +91 -94
- hanzo_mcp/tools/common/forgiving_edit.py +91 -87
- hanzo_mcp/tools/common/mode.py +15 -17
- hanzo_mcp/tools/common/mode_loader.py +27 -24
- hanzo_mcp/tools/common/paginated_base.py +61 -53
- hanzo_mcp/tools/common/paginated_response.py +72 -79
- hanzo_mcp/tools/common/pagination.py +50 -53
- hanzo_mcp/tools/common/permissions.py +4 -4
- hanzo_mcp/tools/common/personality.py +186 -138
- hanzo_mcp/tools/common/plugin_loader.py +54 -54
- hanzo_mcp/tools/common/stats.py +65 -47
- hanzo_mcp/tools/common/test_helpers.py +31 -0
- hanzo_mcp/tools/common/thinking_tool.py +4 -8
- hanzo_mcp/tools/common/tool_disable.py +17 -12
- hanzo_mcp/tools/common/tool_enable.py +13 -14
- hanzo_mcp/tools/common/tool_list.py +36 -28
- hanzo_mcp/tools/common/truncate.py +23 -23
- hanzo_mcp/tools/config/__init__.py +4 -4
- hanzo_mcp/tools/config/config_tool.py +42 -29
- hanzo_mcp/tools/config/index_config.py +37 -34
- hanzo_mcp/tools/config/mode_tool.py +175 -55
- hanzo_mcp/tools/database/__init__.py +15 -12
- hanzo_mcp/tools/database/database_manager.py +77 -75
- hanzo_mcp/tools/database/graph.py +137 -91
- hanzo_mcp/tools/database/graph_add.py +30 -18
- hanzo_mcp/tools/database/graph_query.py +178 -102
- hanzo_mcp/tools/database/graph_remove.py +33 -28
- hanzo_mcp/tools/database/graph_search.py +97 -75
- hanzo_mcp/tools/database/graph_stats.py +91 -59
- hanzo_mcp/tools/database/sql.py +107 -79
- hanzo_mcp/tools/database/sql_query.py +30 -24
- hanzo_mcp/tools/database/sql_search.py +29 -25
- hanzo_mcp/tools/database/sql_stats.py +47 -35
- hanzo_mcp/tools/editor/neovim_command.py +25 -28
- hanzo_mcp/tools/editor/neovim_edit.py +21 -23
- hanzo_mcp/tools/editor/neovim_session.py +60 -54
- hanzo_mcp/tools/filesystem/__init__.py +31 -30
- hanzo_mcp/tools/filesystem/ast_multi_edit.py +329 -249
- hanzo_mcp/tools/filesystem/ast_tool.py +4 -4
- hanzo_mcp/tools/filesystem/base.py +1 -1
- hanzo_mcp/tools/filesystem/batch_search.py +316 -224
- hanzo_mcp/tools/filesystem/content_replace.py +4 -4
- hanzo_mcp/tools/filesystem/diff.py +71 -59
- hanzo_mcp/tools/filesystem/directory_tree.py +7 -7
- hanzo_mcp/tools/filesystem/directory_tree_paginated.py +49 -37
- hanzo_mcp/tools/filesystem/edit.py +4 -4
- hanzo_mcp/tools/filesystem/find.py +173 -80
- hanzo_mcp/tools/filesystem/find_files.py +73 -52
- hanzo_mcp/tools/filesystem/git_search.py +157 -104
- hanzo_mcp/tools/filesystem/grep.py +8 -8
- hanzo_mcp/tools/filesystem/multi_edit.py +4 -8
- hanzo_mcp/tools/filesystem/read.py +12 -10
- hanzo_mcp/tools/filesystem/rules_tool.py +59 -43
- hanzo_mcp/tools/filesystem/search_tool.py +263 -207
- hanzo_mcp/tools/filesystem/symbols_tool.py +94 -54
- hanzo_mcp/tools/filesystem/tree.py +35 -33
- hanzo_mcp/tools/filesystem/unix_aliases.py +13 -18
- hanzo_mcp/tools/filesystem/watch.py +37 -36
- hanzo_mcp/tools/filesystem/write.py +4 -8
- hanzo_mcp/tools/jupyter/__init__.py +4 -4
- hanzo_mcp/tools/jupyter/base.py +4 -5
- hanzo_mcp/tools/jupyter/jupyter.py +67 -47
- hanzo_mcp/tools/jupyter/notebook_edit.py +4 -4
- hanzo_mcp/tools/jupyter/notebook_read.py +4 -7
- hanzo_mcp/tools/llm/__init__.py +5 -7
- hanzo_mcp/tools/llm/consensus_tool.py +72 -52
- hanzo_mcp/tools/llm/llm_manage.py +101 -60
- hanzo_mcp/tools/llm/llm_tool.py +226 -166
- hanzo_mcp/tools/llm/provider_tools.py +25 -26
- hanzo_mcp/tools/lsp/__init__.py +1 -1
- hanzo_mcp/tools/lsp/lsp_tool.py +228 -143
- hanzo_mcp/tools/mcp/__init__.py +2 -3
- hanzo_mcp/tools/mcp/mcp_add.py +27 -25
- hanzo_mcp/tools/mcp/mcp_remove.py +7 -8
- hanzo_mcp/tools/mcp/mcp_stats.py +23 -22
- hanzo_mcp/tools/mcp/mcp_tool.py +129 -98
- hanzo_mcp/tools/memory/__init__.py +39 -21
- hanzo_mcp/tools/memory/knowledge_tools.py +124 -99
- hanzo_mcp/tools/memory/memory_tools.py +90 -108
- hanzo_mcp/tools/search/__init__.py +7 -2
- hanzo_mcp/tools/search/find_tool.py +297 -212
- hanzo_mcp/tools/search/unified_search.py +366 -314
- hanzo_mcp/tools/shell/__init__.py +8 -7
- hanzo_mcp/tools/shell/auto_background.py +56 -49
- hanzo_mcp/tools/shell/base.py +1 -1
- hanzo_mcp/tools/shell/base_process.py +75 -75
- hanzo_mcp/tools/shell/bash_session.py +2 -2
- hanzo_mcp/tools/shell/bash_session_executor.py +4 -4
- hanzo_mcp/tools/shell/bash_tool.py +24 -31
- hanzo_mcp/tools/shell/command_executor.py +12 -12
- hanzo_mcp/tools/shell/logs.py +43 -33
- hanzo_mcp/tools/shell/npx.py +13 -13
- hanzo_mcp/tools/shell/npx_background.py +24 -21
- hanzo_mcp/tools/shell/npx_tool.py +18 -22
- hanzo_mcp/tools/shell/open.py +19 -21
- hanzo_mcp/tools/shell/pkill.py +31 -26
- hanzo_mcp/tools/shell/process_tool.py +32 -32
- hanzo_mcp/tools/shell/processes.py +57 -58
- hanzo_mcp/tools/shell/run_background.py +24 -25
- hanzo_mcp/tools/shell/run_command.py +5 -5
- hanzo_mcp/tools/shell/run_command_windows.py +5 -5
- hanzo_mcp/tools/shell/session_storage.py +3 -3
- hanzo_mcp/tools/shell/streaming_command.py +141 -126
- hanzo_mcp/tools/shell/uvx.py +24 -25
- hanzo_mcp/tools/shell/uvx_background.py +35 -33
- hanzo_mcp/tools/shell/uvx_tool.py +18 -22
- hanzo_mcp/tools/todo/__init__.py +6 -2
- hanzo_mcp/tools/todo/todo.py +50 -37
- hanzo_mcp/tools/todo/todo_read.py +5 -8
- hanzo_mcp/tools/todo/todo_write.py +5 -7
- hanzo_mcp/tools/vector/__init__.py +40 -28
- hanzo_mcp/tools/vector/ast_analyzer.py +176 -143
- hanzo_mcp/tools/vector/git_ingester.py +170 -179
- hanzo_mcp/tools/vector/index_tool.py +96 -44
- hanzo_mcp/tools/vector/infinity_store.py +283 -228
- hanzo_mcp/tools/vector/mock_infinity.py +39 -40
- hanzo_mcp/tools/vector/project_manager.py +88 -78
- hanzo_mcp/tools/vector/vector.py +59 -42
- hanzo_mcp/tools/vector/vector_index.py +30 -27
- hanzo_mcp/tools/vector/vector_search.py +64 -45
- hanzo_mcp/types.py +6 -4
- {hanzo_mcp-0.7.6.dist-info → hanzo_mcp-0.8.0.dist-info}/METADATA +1 -1
- hanzo_mcp-0.8.0.dist-info/RECORD +185 -0
- hanzo_mcp-0.7.6.dist-info/RECORD +0 -182
- {hanzo_mcp-0.7.6.dist-info → hanzo_mcp-0.8.0.dist-info}/WHEEL +0 -0
- {hanzo_mcp-0.7.6.dist-info → hanzo_mcp-0.8.0.dist-info}/entry_points.txt +0 -0
- {hanzo_mcp-0.7.6.dist-info → hanzo_mcp-0.8.0.dist-info}/top_level.txt +0 -0
hanzo_mcp/tools/agent/agent.py
CHANGED
|
@@ -4,42 +4,46 @@ This module provides the AgentTool for delegating tasks to sub-agents,
|
|
|
4
4
|
supporting both one-off and long-running RPC modes, including A2A communication.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
import asyncio
|
|
8
|
-
import json
|
|
9
7
|
import re
|
|
8
|
+
import json
|
|
10
9
|
import time
|
|
11
10
|
import uuid
|
|
12
|
-
|
|
13
|
-
from collections.abc import Iterable
|
|
11
|
+
import asyncio
|
|
14
12
|
|
|
15
13
|
# Import litellm with warnings suppressed
|
|
16
14
|
import warnings
|
|
15
|
+
from typing import (
|
|
16
|
+
Any,
|
|
17
|
+
Dict,
|
|
18
|
+
List,
|
|
19
|
+
Unpack,
|
|
20
|
+
Optional,
|
|
21
|
+
Annotated,
|
|
22
|
+
TypedDict,
|
|
23
|
+
final,
|
|
24
|
+
override,
|
|
25
|
+
)
|
|
26
|
+
|
|
17
27
|
with warnings.catch_warnings():
|
|
18
28
|
warnings.simplefilter("ignore", DeprecationWarning)
|
|
19
|
-
import litellm
|
|
20
|
-
from mcp.server.fastmcp import Context as MCPContext
|
|
21
|
-
from openai.types.chat import ChatCompletionMessageParam, ChatCompletionToolParam
|
|
22
29
|
from pydantic import Field
|
|
30
|
+
from openai.types.chat import ChatCompletionMessageParam
|
|
31
|
+
from mcp.server.fastmcp import Context as MCPContext
|
|
23
32
|
|
|
33
|
+
from hanzo_mcp.tools.jupyter import get_read_only_jupyter_tools
|
|
34
|
+
from hanzo_mcp.tools.filesystem import get_read_only_filesystem_tools
|
|
35
|
+
from hanzo_mcp.tools.common.base import BaseTool
|
|
24
36
|
from hanzo_mcp.tools.agent.prompt import (
|
|
25
|
-
get_allowed_agent_tools,
|
|
26
37
|
get_default_model,
|
|
27
|
-
get_model_parameters,
|
|
28
38
|
get_system_prompt,
|
|
39
|
+
get_allowed_agent_tools,
|
|
29
40
|
)
|
|
30
|
-
from hanzo_mcp.tools.agent.tool_adapter import (
|
|
31
|
-
convert_tools_to_openai_functions,
|
|
32
|
-
)
|
|
33
|
-
from hanzo_mcp.tools.common.base import BaseTool
|
|
34
|
-
from hanzo_mcp.tools.common.batch_tool import BatchTool
|
|
35
41
|
from hanzo_mcp.tools.common.context import (
|
|
36
42
|
ToolContext,
|
|
37
43
|
create_tool_context,
|
|
38
44
|
)
|
|
45
|
+
from hanzo_mcp.tools.common.batch_tool import BatchTool
|
|
39
46
|
from hanzo_mcp.tools.common.permissions import PermissionManager
|
|
40
|
-
from hanzo_mcp.tools.filesystem import get_read_only_filesystem_tools
|
|
41
|
-
from hanzo_mcp.tools.jupyter import get_read_only_jupyter_tools
|
|
42
|
-
|
|
43
47
|
|
|
44
48
|
# Parameter types
|
|
45
49
|
Action = Annotated[
|
|
@@ -101,6 +105,7 @@ Model = Annotated[
|
|
|
101
105
|
|
|
102
106
|
class AgentParams(TypedDict, total=False):
|
|
103
107
|
"""Parameters for agent tool."""
|
|
108
|
+
|
|
104
109
|
action: str
|
|
105
110
|
prompts: Optional[str | List[str]]
|
|
106
111
|
mode: str
|
|
@@ -112,8 +117,10 @@ class AgentParams(TypedDict, total=False):
|
|
|
112
117
|
|
|
113
118
|
class RPCAgent:
|
|
114
119
|
"""Long-running RPC agent."""
|
|
115
|
-
|
|
116
|
-
def __init__(
|
|
120
|
+
|
|
121
|
+
def __init__(
|
|
122
|
+
self, agent_id: str, model: str, system_prompt: str, tools: List[BaseTool]
|
|
123
|
+
):
|
|
117
124
|
self.agent_id = agent_id
|
|
118
125
|
self.model = model
|
|
119
126
|
self.system_prompt = system_prompt
|
|
@@ -124,12 +131,14 @@ class RPCAgent:
|
|
|
124
131
|
self.created_at = time.time()
|
|
125
132
|
self.last_used = time.time()
|
|
126
133
|
self.call_count = 0
|
|
127
|
-
|
|
128
|
-
async def call_method(
|
|
134
|
+
|
|
135
|
+
async def call_method(
|
|
136
|
+
self, method: str, args: Dict[str, Any], tool_ctx: ToolContext
|
|
137
|
+
) -> str:
|
|
129
138
|
"""Call a method on the RPC agent."""
|
|
130
139
|
self.last_used = time.time()
|
|
131
140
|
self.call_count += 1
|
|
132
|
-
|
|
141
|
+
|
|
133
142
|
# Build prompt based on method
|
|
134
143
|
if method == "search":
|
|
135
144
|
prompt = f"Search for: {args.get('query', 'unknown')}"
|
|
@@ -140,22 +149,22 @@ class RPCAgent:
|
|
|
140
149
|
else:
|
|
141
150
|
# Generic method call
|
|
142
151
|
prompt = f"Method: {method}, Args: {json.dumps(args)}"
|
|
143
|
-
|
|
152
|
+
|
|
144
153
|
# Add to conversation
|
|
145
154
|
self.messages.append({"role": "user", "content": prompt})
|
|
146
|
-
|
|
155
|
+
|
|
147
156
|
# Get response
|
|
148
157
|
# (simplified - would integrate with full agent execution logic)
|
|
149
158
|
response = f"Executed {method} with args {args}"
|
|
150
159
|
self.messages.append({"role": "assistant", "content": response})
|
|
151
|
-
|
|
160
|
+
|
|
152
161
|
return response
|
|
153
162
|
|
|
154
163
|
|
|
155
164
|
@final
|
|
156
165
|
class AgentTool(BaseTool):
|
|
157
166
|
"""Unified agent tool with one-off and RPC modes."""
|
|
158
|
-
|
|
167
|
+
|
|
159
168
|
def __init__(
|
|
160
169
|
self,
|
|
161
170
|
permission_manager: PermissionManager,
|
|
@@ -174,10 +183,10 @@ class AgentTool(BaseTool):
|
|
|
174
183
|
self.max_tokens_override = max_tokens
|
|
175
184
|
self.max_iterations = max_iterations
|
|
176
185
|
self.max_tool_uses = max_tool_uses
|
|
177
|
-
|
|
186
|
+
|
|
178
187
|
# RPC agent registry
|
|
179
188
|
self._rpc_agents: Dict[str, RPCAgent] = {}
|
|
180
|
-
|
|
189
|
+
|
|
181
190
|
# Available tools
|
|
182
191
|
self.available_tools: list[BaseTool] = []
|
|
183
192
|
self.available_tools.extend(
|
|
@@ -201,8 +210,8 @@ class AgentTool(BaseTool):
|
|
|
201
210
|
def description(self) -> str:
|
|
202
211
|
"""Get the tool description."""
|
|
203
212
|
tools = [t.name for t in self.available_tools]
|
|
204
|
-
|
|
205
|
-
return f"""AI agents with tools: {
|
|
213
|
+
|
|
214
|
+
return f"""AI agents with tools: {", ".join(tools)}. Actions: run (default), start, call, stop, list.
|
|
206
215
|
|
|
207
216
|
Usage:
|
|
208
217
|
agent "Search for config files in /project"
|
|
@@ -223,10 +232,10 @@ Modes:
|
|
|
223
232
|
"""Execute agent operation."""
|
|
224
233
|
tool_ctx = create_tool_context(ctx)
|
|
225
234
|
await tool_ctx.set_tool_info(self.name)
|
|
226
|
-
|
|
235
|
+
|
|
227
236
|
# Extract action
|
|
228
237
|
action = params.get("action", "run")
|
|
229
|
-
|
|
238
|
+
|
|
230
239
|
# Route to appropriate handler
|
|
231
240
|
if action == "run":
|
|
232
241
|
return await self._handle_run(params, tool_ctx)
|
|
@@ -246,30 +255,34 @@ Modes:
|
|
|
246
255
|
prompts = params.get("prompts")
|
|
247
256
|
if not prompts:
|
|
248
257
|
return "Error: prompts required for run action"
|
|
249
|
-
|
|
258
|
+
|
|
250
259
|
# Convert to list
|
|
251
260
|
if isinstance(prompts, str):
|
|
252
261
|
prompt_list = [prompts]
|
|
253
262
|
else:
|
|
254
263
|
prompt_list = prompts
|
|
255
|
-
|
|
264
|
+
|
|
256
265
|
# Validate prompts
|
|
257
266
|
for prompt in prompt_list:
|
|
258
267
|
if not self._validate_prompt(prompt):
|
|
259
268
|
return f"Error: Prompt must contain absolute paths starting with /: {prompt[:50]}..."
|
|
260
|
-
|
|
269
|
+
|
|
261
270
|
# Execute agents
|
|
262
271
|
start_time = time.time()
|
|
263
|
-
|
|
272
|
+
|
|
264
273
|
if len(prompt_list) == 1:
|
|
265
274
|
await tool_ctx.info("Launching agent")
|
|
266
|
-
result = await self._execute_agent(
|
|
275
|
+
result = await self._execute_agent(
|
|
276
|
+
prompt_list[0], params.get("model"), tool_ctx
|
|
277
|
+
)
|
|
267
278
|
else:
|
|
268
279
|
await tool_ctx.info(f"Launching {len(prompt_list)} agents in parallel")
|
|
269
|
-
result = await self._execute_multiple_agents(
|
|
270
|
-
|
|
280
|
+
result = await self._execute_multiple_agents(
|
|
281
|
+
prompt_list, params.get("model"), tool_ctx
|
|
282
|
+
)
|
|
283
|
+
|
|
271
284
|
execution_time = time.time() - start_time
|
|
272
|
-
|
|
285
|
+
|
|
273
286
|
return f"""Agent execution completed in {execution_time:.2f} seconds.
|
|
274
287
|
|
|
275
288
|
AGENT RESPONSE:
|
|
@@ -280,31 +293,31 @@ AGENT RESPONSE:
|
|
|
280
293
|
mode = params.get("mode", "oneoff")
|
|
281
294
|
if mode != "rpc":
|
|
282
295
|
return "Error: start action only valid for rpc mode"
|
|
283
|
-
|
|
296
|
+
|
|
284
297
|
# Generate agent ID
|
|
285
298
|
agent_id = str(uuid.uuid4())[:8]
|
|
286
|
-
|
|
299
|
+
|
|
287
300
|
# Get model
|
|
288
301
|
model = params.get("model") or get_default_model(self.model_override)
|
|
289
|
-
|
|
302
|
+
|
|
290
303
|
# Get available tools
|
|
291
304
|
agent_tools = get_allowed_agent_tools(
|
|
292
305
|
self.available_tools,
|
|
293
306
|
self.permission_manager,
|
|
294
307
|
)
|
|
295
|
-
|
|
308
|
+
|
|
296
309
|
# Create system prompt
|
|
297
310
|
system_prompt = get_system_prompt(
|
|
298
311
|
agent_tools,
|
|
299
312
|
self.permission_manager,
|
|
300
313
|
)
|
|
301
|
-
|
|
314
|
+
|
|
302
315
|
# Create RPC agent
|
|
303
316
|
agent = RPCAgent(agent_id, model, system_prompt, agent_tools)
|
|
304
317
|
self._rpc_agents[agent_id] = agent
|
|
305
|
-
|
|
318
|
+
|
|
306
319
|
await tool_ctx.info(f"Started RPC agent {agent_id} with model {model}")
|
|
307
|
-
|
|
320
|
+
|
|
308
321
|
return f"""Started RPC agent:
|
|
309
322
|
- ID: {agent_id}
|
|
310
323
|
- Model: {model}
|
|
@@ -317,20 +330,20 @@ Use 'agent --action call --agent-id {agent_id} --method <method> --args <args>'
|
|
|
317
330
|
agent_id = params.get("agent_id")
|
|
318
331
|
if not agent_id:
|
|
319
332
|
return "Error: agent_id required for call action"
|
|
320
|
-
|
|
333
|
+
|
|
321
334
|
if agent_id not in self._rpc_agents:
|
|
322
335
|
return f"Error: Agent {agent_id} not found. Use 'agent --action list' to see active agents."
|
|
323
|
-
|
|
336
|
+
|
|
324
337
|
method = params.get("method")
|
|
325
338
|
if not method:
|
|
326
339
|
return "Error: method required for call action"
|
|
327
|
-
|
|
340
|
+
|
|
328
341
|
args = params.get("args", {})
|
|
329
|
-
|
|
342
|
+
|
|
330
343
|
# Call agent method
|
|
331
344
|
agent = self._rpc_agents[agent_id]
|
|
332
345
|
await tool_ctx.info(f"Calling {method} on agent {agent_id}")
|
|
333
|
-
|
|
346
|
+
|
|
334
347
|
try:
|
|
335
348
|
result = await agent.call_method(method, args, tool_ctx)
|
|
336
349
|
return f"Agent {agent_id} response:\n{result}"
|
|
@@ -343,13 +356,13 @@ Use 'agent --action call --agent-id {agent_id} --method <method> --args <args>'
|
|
|
343
356
|
agent_id = params.get("agent_id")
|
|
344
357
|
if not agent_id:
|
|
345
358
|
return "Error: agent_id required for stop action"
|
|
346
|
-
|
|
359
|
+
|
|
347
360
|
if agent_id not in self._rpc_agents:
|
|
348
361
|
return f"Error: Agent {agent_id} not found"
|
|
349
|
-
|
|
362
|
+
|
|
350
363
|
agent = self._rpc_agents.pop(agent_id)
|
|
351
364
|
await tool_ctx.info(f"Stopped agent {agent_id}")
|
|
352
|
-
|
|
365
|
+
|
|
353
366
|
return f"""Stopped agent {agent_id}:
|
|
354
367
|
- Runtime: {time.time() - agent.created_at:.2f} seconds
|
|
355
368
|
- Calls: {agent.call_count}"""
|
|
@@ -358,7 +371,7 @@ Use 'agent --action call --agent-id {agent_id} --method <method> --args <args>'
|
|
|
358
371
|
"""List active RPC agents."""
|
|
359
372
|
if not self._rpc_agents:
|
|
360
373
|
return "No active RPC agents"
|
|
361
|
-
|
|
374
|
+
|
|
362
375
|
output = ["=== Active RPC Agents ==="]
|
|
363
376
|
for agent_id, agent in self._rpc_agents.items():
|
|
364
377
|
runtime = time.time() - agent.created_at
|
|
@@ -368,7 +381,7 @@ Use 'agent --action call --agent-id {agent_id} --method <method> --args <args>'
|
|
|
368
381
|
output.append(f" Runtime: {runtime:.2f}s")
|
|
369
382
|
output.append(f" Idle: {idle:.2f}s")
|
|
370
383
|
output.append(f" Calls: {agent.call_count}")
|
|
371
|
-
|
|
384
|
+
|
|
372
385
|
return "\n".join(output)
|
|
373
386
|
|
|
374
387
|
def _validate_prompt(self, prompt: str) -> bool:
|
|
@@ -376,30 +389,34 @@ Use 'agent --action call --agent-id {agent_id} --method <method> --args <args>'
|
|
|
376
389
|
absolute_path_pattern = r"/(?:[^/\s]+/)*[^/\s]+"
|
|
377
390
|
return bool(re.search(absolute_path_pattern, prompt))
|
|
378
391
|
|
|
379
|
-
async def _execute_agent(
|
|
392
|
+
async def _execute_agent(
|
|
393
|
+
self, prompt: str, model: Optional[str], tool_ctx: ToolContext
|
|
394
|
+
) -> str:
|
|
380
395
|
"""Execute a single agent (simplified - would use full logic from agent_tool.py)."""
|
|
381
396
|
# This would integrate the full agent execution logic from agent_tool.py
|
|
382
397
|
# For now, return a placeholder
|
|
383
398
|
return f"Executed agent with prompt: {prompt[:100]}..."
|
|
384
399
|
|
|
385
|
-
async def _execute_multiple_agents(
|
|
400
|
+
async def _execute_multiple_agents(
|
|
401
|
+
self, prompts: List[str], model: Optional[str], tool_ctx: ToolContext
|
|
402
|
+
) -> str:
|
|
386
403
|
"""Execute multiple agents in parallel."""
|
|
387
404
|
tasks = []
|
|
388
405
|
for prompt in prompts:
|
|
389
406
|
task = self._execute_agent(prompt, model, tool_ctx)
|
|
390
407
|
tasks.append(task)
|
|
391
|
-
|
|
408
|
+
|
|
392
409
|
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
393
|
-
|
|
410
|
+
|
|
394
411
|
formatted_results = []
|
|
395
412
|
for i, result in enumerate(results):
|
|
396
413
|
if isinstance(result, Exception):
|
|
397
|
-
formatted_results.append(f"Agent {i+1} Error:\n{str(result)}")
|
|
414
|
+
formatted_results.append(f"Agent {i + 1} Error:\n{str(result)}")
|
|
398
415
|
else:
|
|
399
|
-
formatted_results.append(f"Agent {i+1} Result:\n{result}")
|
|
400
|
-
|
|
416
|
+
formatted_results.append(f"Agent {i + 1} Result:\n{result}")
|
|
417
|
+
|
|
401
418
|
return "\n\n---\n\n".join(formatted_results)
|
|
402
419
|
|
|
403
420
|
def register(self, mcp_server) -> None:
|
|
404
421
|
"""Register this tool with the MCP server."""
|
|
405
|
-
pass
|
|
422
|
+
pass
|