fast-agent-mcp 0.2.35__py3-none-any.whl → 0.2.37__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 fast-agent-mcp might be problematic. Click here for more details.
- {fast_agent_mcp-0.2.35.dist-info → fast_agent_mcp-0.2.37.dist-info}/METADATA +15 -12
- {fast_agent_mcp-0.2.35.dist-info → fast_agent_mcp-0.2.37.dist-info}/RECORD +55 -56
- {fast_agent_mcp-0.2.35.dist-info → fast_agent_mcp-0.2.37.dist-info}/licenses/LICENSE +1 -1
- mcp_agent/agents/base_agent.py +2 -2
- mcp_agent/agents/workflow/router_agent.py +1 -1
- mcp_agent/cli/commands/quickstart.py +59 -5
- mcp_agent/config.py +10 -0
- mcp_agent/context.py +1 -4
- mcp_agent/core/agent_types.py +7 -6
- mcp_agent/core/direct_decorators.py +14 -0
- mcp_agent/core/direct_factory.py +1 -0
- mcp_agent/core/enhanced_prompt.py +73 -13
- mcp_agent/core/fastagent.py +23 -2
- mcp_agent/core/interactive_prompt.py +118 -8
- mcp_agent/human_input/elicitation_form.py +723 -0
- mcp_agent/human_input/elicitation_forms.py +59 -0
- mcp_agent/human_input/elicitation_handler.py +88 -0
- mcp_agent/human_input/elicitation_state.py +34 -0
- mcp_agent/llm/augmented_llm.py +31 -0
- mcp_agent/llm/providers/augmented_llm_anthropic.py +11 -23
- mcp_agent/llm/providers/augmented_llm_azure.py +4 -4
- mcp_agent/llm/providers/augmented_llm_google_native.py +4 -2
- mcp_agent/llm/providers/augmented_llm_openai.py +195 -12
- mcp_agent/llm/providers/multipart_converter_openai.py +4 -3
- mcp_agent/mcp/elicitation_factory.py +84 -0
- mcp_agent/mcp/elicitation_handlers.py +155 -0
- mcp_agent/mcp/helpers/content_helpers.py +27 -0
- mcp_agent/mcp/helpers/server_config_helpers.py +10 -8
- mcp_agent/mcp/interfaces.py +1 -1
- mcp_agent/mcp/mcp_agent_client_session.py +44 -1
- mcp_agent/mcp/mcp_aggregator.py +56 -11
- mcp_agent/mcp/mcp_connection_manager.py +30 -18
- mcp_agent/mcp_server/agent_server.py +2 -0
- mcp_agent/mcp_server_registry.py +16 -8
- mcp_agent/resources/examples/data-analysis/analysis.py +1 -2
- mcp_agent/resources/examples/mcp/elicitations/README.md +157 -0
- mcp_agent/resources/examples/mcp/elicitations/elicitation_account_server.py +88 -0
- mcp_agent/resources/examples/mcp/elicitations/elicitation_forms_server.py +232 -0
- mcp_agent/resources/examples/mcp/elicitations/elicitation_game_server.py +164 -0
- mcp_agent/resources/examples/mcp/elicitations/fastagent.config.yaml +35 -0
- mcp_agent/resources/examples/mcp/elicitations/fastagent.secrets.yaml.example +17 -0
- mcp_agent/resources/examples/mcp/elicitations/forms_demo.py +111 -0
- mcp_agent/resources/examples/mcp/elicitations/game_character.py +65 -0
- mcp_agent/resources/examples/mcp/elicitations/game_character_handler.py +256 -0
- mcp_agent/resources/examples/{prompting/agent.py → mcp/elicitations/tool_call.py} +4 -5
- mcp_agent/resources/examples/mcp/state-transfer/agent_two.py +1 -1
- mcp_agent/resources/examples/mcp/state-transfer/fastagent.config.yaml +1 -1
- mcp_agent/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +1 -0
- mcp_agent/resources/examples/workflows/evaluator.py +1 -1
- mcp_agent/resources/examples/workflows/graded_report.md +89 -0
- mcp_agent/resources/examples/workflows/orchestrator.py +7 -9
- mcp_agent/resources/examples/workflows/parallel.py +0 -2
- mcp_agent/resources/examples/workflows/short_story.md +13 -0
- mcp_agent/resources/examples/in_dev/agent_build.py +0 -84
- mcp_agent/resources/examples/in_dev/css-LICENSE.txt +0 -21
- mcp_agent/resources/examples/in_dev/slides.py +0 -110
- mcp_agent/resources/examples/internal/agent.py +0 -20
- mcp_agent/resources/examples/internal/fastagent.config.yaml +0 -66
- mcp_agent/resources/examples/internal/history_transfer.py +0 -35
- mcp_agent/resources/examples/internal/job.py +0 -84
- mcp_agent/resources/examples/internal/prompt_category.py +0 -21
- mcp_agent/resources/examples/internal/prompt_sizing.py +0 -51
- mcp_agent/resources/examples/internal/simple.txt +0 -2
- mcp_agent/resources/examples/internal/sizer.py +0 -20
- mcp_agent/resources/examples/internal/social.py +0 -67
- mcp_agent/resources/examples/prompting/__init__.py +0 -3
- mcp_agent/resources/examples/prompting/delimited_prompt.txt +0 -14
- mcp_agent/resources/examples/prompting/fastagent.config.yaml +0 -43
- mcp_agent/resources/examples/prompting/image_server.py +0 -52
- mcp_agent/resources/examples/prompting/prompt1.txt +0 -6
- mcp_agent/resources/examples/prompting/work_with_image.py +0 -19
- {fast_agent_mcp-0.2.35.dist-info → fast_agent_mcp-0.2.37.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.2.35.dist-info → fast_agent_mcp-0.2.37.dist-info}/entry_points.txt +0 -0
|
@@ -40,6 +40,59 @@ in_multiline_mode = False
|
|
|
40
40
|
# Track whether help text has been shown globally
|
|
41
41
|
help_message_shown = False
|
|
42
42
|
|
|
43
|
+
# Track which agents have shown their info
|
|
44
|
+
_agent_info_shown = set()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
async def _display_agent_info_helper(agent_name: str, agent_provider: object) -> None:
|
|
48
|
+
"""Helper function to display agent information."""
|
|
49
|
+
# Only show once per agent
|
|
50
|
+
if agent_name in _agent_info_shown:
|
|
51
|
+
return
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
# Get agent info
|
|
55
|
+
if hasattr(agent_provider, "_agent"):
|
|
56
|
+
# This is an AgentApp - get the specific agent
|
|
57
|
+
agent = agent_provider._agent(agent_name)
|
|
58
|
+
else:
|
|
59
|
+
# This is a single agent
|
|
60
|
+
agent = agent_provider
|
|
61
|
+
|
|
62
|
+
# Get counts
|
|
63
|
+
servers = await agent.list_servers()
|
|
64
|
+
server_count = len(servers) if servers else 0
|
|
65
|
+
|
|
66
|
+
tools_result = await agent.list_tools()
|
|
67
|
+
tool_count = (
|
|
68
|
+
len(tools_result.tools) if tools_result and hasattr(tools_result, "tools") else 0
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
prompts_dict = await agent.list_prompts()
|
|
72
|
+
prompt_count = sum(len(prompts) for prompts in prompts_dict.values()) if prompts_dict else 0
|
|
73
|
+
|
|
74
|
+
# Display with proper pluralization and subdued formatting
|
|
75
|
+
if server_count == 0:
|
|
76
|
+
rich_print(
|
|
77
|
+
f"[dim]Agent [/dim][blue]{agent_name}[/blue][dim]: No MCP Servers attached[/dim]"
|
|
78
|
+
)
|
|
79
|
+
else:
|
|
80
|
+
# Pluralization helpers
|
|
81
|
+
server_word = "Server" if server_count == 1 else "Servers"
|
|
82
|
+
tool_word = "tool" if tool_count == 1 else "tools"
|
|
83
|
+
prompt_word = "prompt" if prompt_count == 1 else "prompts"
|
|
84
|
+
|
|
85
|
+
rich_print(
|
|
86
|
+
f"[dim]Agent [/dim][blue]{agent_name}[/blue][dim]:[/dim] {server_count:,}[dim] MCP {server_word}, [/dim]{tool_count:,}[dim] {tool_word}, [/dim]{prompt_count:,}[dim] {prompt_word} available[/dim]"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# Mark as shown
|
|
90
|
+
_agent_info_shown.add(agent_name)
|
|
91
|
+
|
|
92
|
+
except Exception:
|
|
93
|
+
# Silently ignore errors to not disrupt the user experience
|
|
94
|
+
pass
|
|
95
|
+
|
|
43
96
|
|
|
44
97
|
class AgentCompleter(Completer):
|
|
45
98
|
"""Provide completion for agent names and common commands."""
|
|
@@ -54,11 +107,11 @@ class AgentCompleter(Completer):
|
|
|
54
107
|
self.agents = agents
|
|
55
108
|
# Map commands to their descriptions for better completion hints
|
|
56
109
|
self.commands = {
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"prompt": "Apply a specific prompt by name (/prompt <name>)", # New command
|
|
110
|
+
"tools": "List and call MCP tools",
|
|
111
|
+
"prompt": "List and select MCP prompts, or apply specific prompt (/prompt <name>)",
|
|
60
112
|
"agents": "List available agents",
|
|
61
113
|
"usage": "Show current usage statistics",
|
|
114
|
+
"help": "Show available commands",
|
|
62
115
|
"clear": "Clear the screen",
|
|
63
116
|
"STOP": "Stop this prompting session and move to next workflow step",
|
|
64
117
|
"EXIT": "Exit fast-agent, terminating any running workflows",
|
|
@@ -66,8 +119,8 @@ class AgentCompleter(Completer):
|
|
|
66
119
|
}
|
|
67
120
|
if is_human_input:
|
|
68
121
|
self.commands.pop("agents")
|
|
69
|
-
self.commands.pop("prompts") # Remove prompts command in human input mode
|
|
70
122
|
self.commands.pop("prompt", None) # Remove prompt command in human input mode
|
|
123
|
+
self.commands.pop("tools", None) # Remove tools command in human input mode
|
|
71
124
|
self.commands.pop("usage", None) # Remove usage command in human input mode
|
|
72
125
|
self.agent_types = agent_types or {}
|
|
73
126
|
|
|
@@ -260,6 +313,7 @@ async def get_enhanced_input(
|
|
|
260
313
|
agent_types: dict[str, AgentType] = None,
|
|
261
314
|
is_human_input: bool = False,
|
|
262
315
|
toolbar_color: str = "ansiblue",
|
|
316
|
+
agent_provider: object = None,
|
|
263
317
|
) -> str:
|
|
264
318
|
"""
|
|
265
319
|
Enhanced input with advanced prompt_toolkit features.
|
|
@@ -274,6 +328,7 @@ async def get_enhanced_input(
|
|
|
274
328
|
agent_types: Dictionary mapping agent names to their types for display
|
|
275
329
|
is_human_input: Whether this is a human input request (disables agent selection features)
|
|
276
330
|
toolbar_color: Color to use for the agent name in the toolbar (default: "ansiblue")
|
|
331
|
+
agent_provider: Optional agent provider for displaying agent info
|
|
277
332
|
|
|
278
333
|
Returns:
|
|
279
334
|
User input string
|
|
@@ -300,14 +355,15 @@ async def get_enhanced_input(
|
|
|
300
355
|
if in_multiline_mode:
|
|
301
356
|
mode_style = "ansired" # More noticeable for multiline mode
|
|
302
357
|
mode_text = "MULTILINE"
|
|
303
|
-
toggle_text = "Normal
|
|
358
|
+
toggle_text = "Normal"
|
|
304
359
|
else:
|
|
305
360
|
mode_style = "ansigreen"
|
|
306
361
|
mode_text = "NORMAL"
|
|
307
|
-
toggle_text = "Multiline
|
|
362
|
+
toggle_text = "Multiline"
|
|
308
363
|
|
|
309
364
|
shortcuts = [
|
|
310
365
|
("Ctrl+T", toggle_text),
|
|
366
|
+
("Ctrl+E", "External"),
|
|
311
367
|
("Ctrl+L", "Clear"),
|
|
312
368
|
("↑/↓", "History"),
|
|
313
369
|
]
|
|
@@ -373,8 +429,13 @@ async def get_enhanced_input(
|
|
|
373
429
|
rich_print("[dim]Type /help for commands. Ctrl+T toggles multiline mode.[/dim]")
|
|
374
430
|
else:
|
|
375
431
|
rich_print(
|
|
376
|
-
"[dim]Type /help for commands, @agent to switch agent. Ctrl+T toggles multiline mode.[/dim]"
|
|
432
|
+
"[dim]Type /help for commands, @agent to switch agent. Ctrl+T toggles multiline mode.[/dim]\n"
|
|
377
433
|
)
|
|
434
|
+
|
|
435
|
+
# Display agent info right after help text if agent_provider is available
|
|
436
|
+
if agent_provider and not is_human_input:
|
|
437
|
+
await _display_agent_info_helper(agent_name, agent_provider)
|
|
438
|
+
|
|
378
439
|
rich_print()
|
|
379
440
|
help_message_shown = True
|
|
380
441
|
|
|
@@ -394,12 +455,8 @@ async def get_enhanced_input(
|
|
|
394
455
|
return "LIST_AGENTS"
|
|
395
456
|
elif cmd == "usage":
|
|
396
457
|
return "SHOW_USAGE"
|
|
397
|
-
elif cmd == "prompts":
|
|
398
|
-
# Return a dictionary with select_prompt action instead of a string
|
|
399
|
-
# This way it will match what the command handler expects
|
|
400
|
-
return {"select_prompt": True, "prompt_name": None}
|
|
401
458
|
elif cmd == "prompt":
|
|
402
|
-
# Handle /prompt with no arguments
|
|
459
|
+
# Handle /prompt with no arguments as interactive mode
|
|
403
460
|
if len(cmd_parts) > 1:
|
|
404
461
|
# Direct prompt selection with name or number
|
|
405
462
|
prompt_arg = cmd_parts[1].strip()
|
|
@@ -409,8 +466,11 @@ async def get_enhanced_input(
|
|
|
409
466
|
else:
|
|
410
467
|
return f"SELECT_PROMPT:{prompt_arg}"
|
|
411
468
|
else:
|
|
412
|
-
# If /prompt is used without arguments,
|
|
469
|
+
# If /prompt is used without arguments, show interactive selection
|
|
413
470
|
return {"select_prompt": True, "prompt_name": None}
|
|
471
|
+
elif cmd == "tools":
|
|
472
|
+
# Return a dictionary with list_tools action
|
|
473
|
+
return {"list_tools": True}
|
|
414
474
|
elif cmd == "exit":
|
|
415
475
|
return "EXIT"
|
|
416
476
|
elif cmd.lower() == "stop":
|
mcp_agent/core/fastagent.py
CHANGED
|
@@ -81,7 +81,8 @@ class FastAgent:
|
|
|
81
81
|
name: str,
|
|
82
82
|
config_path: str | None = None,
|
|
83
83
|
ignore_unknown_args: bool = False,
|
|
84
|
-
parse_cli_args: bool = True,
|
|
84
|
+
parse_cli_args: bool = True,
|
|
85
|
+
quiet: bool = False, # Add quiet parameter
|
|
85
86
|
) -> None:
|
|
86
87
|
"""
|
|
87
88
|
Initialize the fast-agent application.
|
|
@@ -94,8 +95,10 @@ class FastAgent:
|
|
|
94
95
|
parse_cli_args: If True, parse command line arguments using argparse.
|
|
95
96
|
Set to False when embedding FastAgent in another framework
|
|
96
97
|
(like FastAPI/Uvicorn) that handles its own arguments.
|
|
98
|
+
quiet: If True, disable progress display, tool and message logging for cleaner output
|
|
97
99
|
"""
|
|
98
100
|
self.args = argparse.Namespace() # Initialize args always
|
|
101
|
+
self._programmatic_quiet = quiet # Store the programmatic quiet setting
|
|
99
102
|
|
|
100
103
|
# --- Wrap argument parsing logic ---
|
|
101
104
|
if parse_cli_args:
|
|
@@ -173,6 +176,10 @@ class FastAgent:
|
|
|
173
176
|
sys.exit(0)
|
|
174
177
|
# --- End of wrapped logic ---
|
|
175
178
|
|
|
179
|
+
# Apply programmatic quiet setting (overrides CLI if both are set)
|
|
180
|
+
if self._programmatic_quiet:
|
|
181
|
+
self.args.quiet = True
|
|
182
|
+
|
|
176
183
|
self.name = name
|
|
177
184
|
self.config_path = config_path
|
|
178
185
|
|
|
@@ -180,12 +187,26 @@ class FastAgent:
|
|
|
180
187
|
# Load configuration directly for this instance
|
|
181
188
|
self._load_config()
|
|
182
189
|
|
|
190
|
+
# Apply programmatic quiet mode to config before creating app
|
|
191
|
+
if self._programmatic_quiet and hasattr(self, "config"):
|
|
192
|
+
if "logger" not in self.config:
|
|
193
|
+
self.config["logger"] = {}
|
|
194
|
+
self.config["logger"]["progress_display"] = False
|
|
195
|
+
self.config["logger"]["show_chat"] = False
|
|
196
|
+
self.config["logger"]["show_tools"] = False
|
|
197
|
+
|
|
183
198
|
# Create the app with our local settings
|
|
184
199
|
self.app = MCPApp(
|
|
185
200
|
name=name,
|
|
186
201
|
settings=config.Settings(**self.config) if hasattr(self, "config") else None,
|
|
187
202
|
)
|
|
188
203
|
|
|
204
|
+
# Stop progress display immediately if quiet mode is requested
|
|
205
|
+
if self._programmatic_quiet:
|
|
206
|
+
from mcp_agent.progress_display import progress_display
|
|
207
|
+
|
|
208
|
+
progress_display.stop()
|
|
209
|
+
|
|
189
210
|
except yaml.parser.ParserError as e:
|
|
190
211
|
handle_error(
|
|
191
212
|
e,
|
|
@@ -486,7 +507,7 @@ class FastAgent:
|
|
|
486
507
|
|
|
487
508
|
async def start_server(
|
|
488
509
|
self,
|
|
489
|
-
transport: str = "
|
|
510
|
+
transport: str = "http",
|
|
490
511
|
host: str = "0.0.0.0",
|
|
491
512
|
port: int = 8000,
|
|
492
513
|
server_name: Optional[str] = None,
|
|
@@ -23,6 +23,7 @@ from rich.table import Table
|
|
|
23
23
|
|
|
24
24
|
from mcp_agent.core.agent_types import AgentType
|
|
25
25
|
from mcp_agent.core.enhanced_prompt import (
|
|
26
|
+
_display_agent_info_helper,
|
|
26
27
|
get_argument_input,
|
|
27
28
|
get_enhanced_input,
|
|
28
29
|
get_selection_input,
|
|
@@ -121,6 +122,7 @@ class InteractivePrompt:
|
|
|
121
122
|
multiline=False, # Default to single-line mode
|
|
122
123
|
available_agent_names=available_agents,
|
|
123
124
|
agent_types=self.agent_types, # Pass agent types for display
|
|
125
|
+
agent_provider=prompt_provider, # Pass agent provider for info display
|
|
124
126
|
)
|
|
125
127
|
|
|
126
128
|
# Handle special commands - pass "True" to enable agent switching
|
|
@@ -132,6 +134,9 @@ class InteractivePrompt:
|
|
|
132
134
|
new_agent = command_result["switch_agent"]
|
|
133
135
|
if new_agent in available_agents_set:
|
|
134
136
|
agent = new_agent
|
|
137
|
+
# Display new agent info immediately when switching
|
|
138
|
+
rich_print() # Add spacing
|
|
139
|
+
await _display_agent_info_helper(agent, prompt_provider)
|
|
135
140
|
continue
|
|
136
141
|
else:
|
|
137
142
|
rich_print(f"[red]Agent '{new_agent}' not found[/red]")
|
|
@@ -174,6 +179,10 @@ class InteractivePrompt:
|
|
|
174
179
|
# Use the name-based selection
|
|
175
180
|
await self._select_prompt(prompt_provider, agent, prompt_name)
|
|
176
181
|
continue
|
|
182
|
+
elif "list_tools" in command_result and prompt_provider:
|
|
183
|
+
# Handle tools list display
|
|
184
|
+
await self._list_tools(prompt_provider, agent)
|
|
185
|
+
continue
|
|
177
186
|
elif "show_usage" in command_result:
|
|
178
187
|
# Handle usage display
|
|
179
188
|
await self._show_usage(prompt_provider, agent)
|
|
@@ -333,13 +342,17 @@ class InteractivePrompt:
|
|
|
333
342
|
rich_print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
334
343
|
|
|
335
344
|
async def _select_prompt(
|
|
336
|
-
self,
|
|
345
|
+
self,
|
|
346
|
+
prompt_provider: PromptProvider,
|
|
347
|
+
agent_name: str,
|
|
348
|
+
requested_name: Optional[str] = None,
|
|
349
|
+
send_func: Optional[SendFunc] = None,
|
|
337
350
|
) -> None:
|
|
338
351
|
"""
|
|
339
352
|
Select and apply a prompt.
|
|
340
353
|
|
|
341
354
|
Args:
|
|
342
|
-
prompt_provider: Provider that implements list_prompts and
|
|
355
|
+
prompt_provider: Provider that implements list_prompts and get_prompt
|
|
343
356
|
agent_name: Name of the agent
|
|
344
357
|
requested_name: Optional name of the prompt to apply
|
|
345
358
|
"""
|
|
@@ -569,12 +582,54 @@ class InteractivePrompt:
|
|
|
569
582
|
if arg_value:
|
|
570
583
|
arg_values[arg_name] = arg_value
|
|
571
584
|
|
|
572
|
-
# Apply the prompt
|
|
585
|
+
# Apply the prompt using generate() for proper progress display
|
|
573
586
|
namespaced_name = selected_prompt["namespaced_name"]
|
|
574
587
|
rich_print(f"\n[bold]Applying prompt [cyan]{namespaced_name}[/cyan]...[/bold]")
|
|
575
588
|
|
|
576
|
-
#
|
|
577
|
-
|
|
589
|
+
# Get the agent directly for generate() call
|
|
590
|
+
if hasattr(prompt_provider, "_agent"):
|
|
591
|
+
# This is an AgentApp - get the specific agent
|
|
592
|
+
agent = prompt_provider._agent(agent_name)
|
|
593
|
+
else:
|
|
594
|
+
# This is a single agent
|
|
595
|
+
agent = prompt_provider
|
|
596
|
+
|
|
597
|
+
try:
|
|
598
|
+
# Use agent.apply_prompt() which handles everything properly:
|
|
599
|
+
# - get_prompt() to fetch template
|
|
600
|
+
# - convert to multipart
|
|
601
|
+
# - call generate() for progress display
|
|
602
|
+
# - return response text
|
|
603
|
+
# Response display is handled by the agent's show_ methods, don't print it here
|
|
604
|
+
|
|
605
|
+
# Fetch the prompt first (without progress display)
|
|
606
|
+
prompt_result = await agent.get_prompt(namespaced_name, arg_values)
|
|
607
|
+
|
|
608
|
+
if not prompt_result or not prompt_result.messages:
|
|
609
|
+
rich_print(
|
|
610
|
+
f"[red]Prompt '{namespaced_name}' could not be found or contains no messages[/red]"
|
|
611
|
+
)
|
|
612
|
+
return
|
|
613
|
+
|
|
614
|
+
# Convert to multipart format
|
|
615
|
+
from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
|
|
616
|
+
|
|
617
|
+
multipart_messages = PromptMessageMultipart.from_get_prompt_result(prompt_result)
|
|
618
|
+
|
|
619
|
+
# Now start progress display for the actual generation
|
|
620
|
+
progress_display.resume()
|
|
621
|
+
try:
|
|
622
|
+
await agent.generate(multipart_messages, None)
|
|
623
|
+
finally:
|
|
624
|
+
# Pause again for the next UI interaction
|
|
625
|
+
progress_display.pause()
|
|
626
|
+
|
|
627
|
+
# Show usage info after the turn (same as send_wrapper does)
|
|
628
|
+
if hasattr(prompt_provider, "_show_turn_usage"):
|
|
629
|
+
prompt_provider._show_turn_usage(agent_name)
|
|
630
|
+
|
|
631
|
+
except Exception as e:
|
|
632
|
+
rich_print(f"[red]Error applying prompt: {e}[/red]")
|
|
578
633
|
|
|
579
634
|
except Exception as e:
|
|
580
635
|
import traceback
|
|
@@ -582,6 +637,61 @@ class InteractivePrompt:
|
|
|
582
637
|
rich_print(f"[red]Error selecting or applying prompt: {e}[/red]")
|
|
583
638
|
rich_print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
584
639
|
|
|
640
|
+
async def _list_tools(self, prompt_provider: PromptProvider, agent_name: str) -> None:
|
|
641
|
+
"""
|
|
642
|
+
List available tools for an agent.
|
|
643
|
+
|
|
644
|
+
Args:
|
|
645
|
+
prompt_provider: Provider that implements list_tools
|
|
646
|
+
agent_name: Name of the agent
|
|
647
|
+
"""
|
|
648
|
+
console = Console()
|
|
649
|
+
|
|
650
|
+
try:
|
|
651
|
+
# Get agent to list tools from
|
|
652
|
+
if hasattr(prompt_provider, "_agent"):
|
|
653
|
+
# This is an AgentApp - get the specific agent
|
|
654
|
+
agent = prompt_provider._agent(agent_name)
|
|
655
|
+
else:
|
|
656
|
+
# This is a single agent
|
|
657
|
+
agent = prompt_provider
|
|
658
|
+
|
|
659
|
+
rich_print(f"\n[bold]Fetching tools for agent [cyan]{agent_name}[/cyan]...[/bold]")
|
|
660
|
+
|
|
661
|
+
# Get tools using list_tools
|
|
662
|
+
tools_result = await agent.list_tools()
|
|
663
|
+
|
|
664
|
+
if not tools_result or not hasattr(tools_result, "tools") or not tools_result.tools:
|
|
665
|
+
rich_print("[yellow]No tools available for this agent[/yellow]")
|
|
666
|
+
return
|
|
667
|
+
|
|
668
|
+
# Create a table for better display
|
|
669
|
+
table = Table(title="Available MCP Tools")
|
|
670
|
+
table.add_column("#", justify="right", style="cyan")
|
|
671
|
+
table.add_column("Tool Name", style="bright_blue")
|
|
672
|
+
table.add_column("Description")
|
|
673
|
+
|
|
674
|
+
# Add tools to table
|
|
675
|
+
for i, tool in enumerate(tools_result.tools):
|
|
676
|
+
table.add_row(
|
|
677
|
+
str(i + 1),
|
|
678
|
+
tool.name,
|
|
679
|
+
getattr(tool, "description", "No description") or "No description",
|
|
680
|
+
)
|
|
681
|
+
|
|
682
|
+
console.print(table)
|
|
683
|
+
|
|
684
|
+
# Add usage instructions
|
|
685
|
+
rich_print("\n[bold]Usage:[/bold]")
|
|
686
|
+
rich_print(" • Tools are automatically available in your conversation")
|
|
687
|
+
rich_print(" • Just ask the agent to use a tool by name or description")
|
|
688
|
+
|
|
689
|
+
except Exception as e:
|
|
690
|
+
import traceback
|
|
691
|
+
|
|
692
|
+
rich_print(f"[red]Error listing tools: {e}[/red]")
|
|
693
|
+
rich_print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
694
|
+
|
|
585
695
|
async def _show_usage(self, prompt_provider: PromptProvider, agent_name: str) -> None:
|
|
586
696
|
"""
|
|
587
697
|
Show usage statistics for the current agent(s) in a colorful table format.
|
|
@@ -593,13 +703,13 @@ class InteractivePrompt:
|
|
|
593
703
|
try:
|
|
594
704
|
# Collect all agents from the prompt provider
|
|
595
705
|
agents_to_show = collect_agents_from_provider(prompt_provider, agent_name)
|
|
596
|
-
|
|
706
|
+
|
|
597
707
|
if not agents_to_show:
|
|
598
708
|
rich_print("[yellow]No usage data available[/yellow]")
|
|
599
709
|
return
|
|
600
|
-
|
|
710
|
+
|
|
601
711
|
# Use the shared display utility
|
|
602
712
|
display_usage_report(agents_to_show, show_if_progress_disabled=True)
|
|
603
|
-
|
|
713
|
+
|
|
604
714
|
except Exception as e:
|
|
605
715
|
rich_print(f"[red]Error showing usage: {e}[/red]")
|