fast-agent-mcp 0.3.6__py3-none-any.whl → 0.3.7__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/__init__.py +9 -1
- fast_agent/agents/agent_types.py +11 -11
- fast_agent/agents/llm_agent.py +61 -39
- fast_agent/agents/llm_decorator.py +355 -6
- fast_agent/agents/mcp_agent.py +85 -62
- fast_agent/agents/tool_agent.py +50 -4
- fast_agent/cli/commands/go.py +3 -3
- fast_agent/constants.py +2 -0
- fast_agent/core/agent_app.py +2 -0
- fast_agent/core/direct_factory.py +39 -120
- fast_agent/core/fastagent.py +2 -2
- fast_agent/history/history_exporter.py +3 -3
- fast_agent/llm/fastagent_llm.py +3 -3
- fast_agent/llm/provider/openai/llm_openai.py +57 -8
- fast_agent/mcp/__init__.py +1 -2
- fast_agent/mcp/mcp_aggregator.py +6 -3
- fast_agent/mcp/prompt_message_extended.py +2 -0
- fast_agent/mcp/prompt_serialization.py +124 -39
- fast_agent/mcp/prompts/prompt_load.py +34 -32
- fast_agent/mcp/prompts/prompt_server.py +26 -11
- fast_agent/resources/setup/fastagent.config.yaml +2 -2
- fast_agent/types/__init__.py +3 -1
- fast_agent/ui/enhanced_prompt.py +111 -64
- fast_agent/ui/interactive_prompt.py +13 -41
- fast_agent/ui/rich_progress.py +12 -8
- {fast_agent_mcp-0.3.6.dist-info → fast_agent_mcp-0.3.7.dist-info}/METADATA +3 -3
- {fast_agent_mcp-0.3.6.dist-info → fast_agent_mcp-0.3.7.dist-info}/RECORD +30 -30
- {fast_agent_mcp-0.3.6.dist-info → fast_agent_mcp-0.3.7.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.3.6.dist-info → fast_agent_mcp-0.3.7.dist-info}/entry_points.txt +0 -0
- {fast_agent_mcp-0.3.6.dist-info → fast_agent_mcp-0.3.7.dist-info}/licenses/LICENSE +0 -0
fast_agent/ui/enhanced_prompt.py
CHANGED
|
@@ -3,12 +3,13 @@ Enhanced prompt functionality with advanced prompt_toolkit features.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
+
import json
|
|
6
7
|
import os
|
|
7
8
|
import shlex
|
|
8
9
|
import subprocess
|
|
9
10
|
import tempfile
|
|
10
11
|
from importlib.metadata import version
|
|
11
|
-
from typing import List, Optional
|
|
12
|
+
from typing import TYPE_CHECKING, List, Optional
|
|
12
13
|
|
|
13
14
|
from prompt_toolkit import PromptSession
|
|
14
15
|
from prompt_toolkit.completion import Completer, Completion, WordCompleter
|
|
@@ -20,9 +21,13 @@ from prompt_toolkit.styles import Style
|
|
|
20
21
|
from rich import print as rich_print
|
|
21
22
|
|
|
22
23
|
from fast_agent.agents.agent_types import AgentType
|
|
24
|
+
from fast_agent.constants import FAST_AGENT_ERROR_CHANNEL, FAST_AGENT_REMOVED_METADATA_CHANNEL
|
|
23
25
|
from fast_agent.core.exceptions import PromptExitError
|
|
24
26
|
from fast_agent.llm.model_info import get_model_info
|
|
25
27
|
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
from fast_agent.core.agent_app import AgentApp
|
|
30
|
+
|
|
26
31
|
# Get the application version
|
|
27
32
|
try:
|
|
28
33
|
app_version = version("fast-agent-mcp")
|
|
@@ -38,6 +43,30 @@ available_agents = set()
|
|
|
38
43
|
# Keep track of multi-line mode state
|
|
39
44
|
in_multiline_mode = False
|
|
40
45
|
|
|
46
|
+
|
|
47
|
+
def _extract_alert_flags_from_meta(blocks) -> set[str]:
|
|
48
|
+
flags: set[str] = set()
|
|
49
|
+
for block in blocks or []:
|
|
50
|
+
text = getattr(block, "text", None)
|
|
51
|
+
if not text:
|
|
52
|
+
continue
|
|
53
|
+
try:
|
|
54
|
+
payload = json.loads(text)
|
|
55
|
+
except (TypeError, ValueError):
|
|
56
|
+
continue
|
|
57
|
+
if payload.get("type") != "fast-agent-removed":
|
|
58
|
+
continue
|
|
59
|
+
category = payload.get("category")
|
|
60
|
+
match category:
|
|
61
|
+
case "text":
|
|
62
|
+
flags.add("T")
|
|
63
|
+
case "document":
|
|
64
|
+
flags.add("D")
|
|
65
|
+
case "vision":
|
|
66
|
+
flags.add("V")
|
|
67
|
+
return flags
|
|
68
|
+
|
|
69
|
+
|
|
41
70
|
# Track whether help text has been shown globally
|
|
42
71
|
help_message_shown = False
|
|
43
72
|
|
|
@@ -45,20 +74,17 @@ help_message_shown = False
|
|
|
45
74
|
_agent_info_shown = set()
|
|
46
75
|
|
|
47
76
|
|
|
48
|
-
async def _display_agent_info_helper(agent_name: str, agent_provider:
|
|
77
|
+
async def _display_agent_info_helper(agent_name: str, agent_provider: "AgentApp | None") -> None:
|
|
49
78
|
"""Helper function to display agent information."""
|
|
50
79
|
# Only show once per agent
|
|
51
80
|
if agent_name in _agent_info_shown:
|
|
52
81
|
return
|
|
53
82
|
|
|
54
83
|
try:
|
|
55
|
-
# Get agent info
|
|
56
|
-
if
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
else:
|
|
60
|
-
# This is a single agent
|
|
61
|
-
agent = agent_provider
|
|
84
|
+
# Get agent info from AgentApp
|
|
85
|
+
if agent_provider is None:
|
|
86
|
+
return
|
|
87
|
+
agent = agent_provider._agent(agent_name)
|
|
62
88
|
|
|
63
89
|
# Get counts TODO -- add this to the type library or adjust the way aggregator/reporting works
|
|
64
90
|
server_count = 0
|
|
@@ -148,7 +174,9 @@ async def _display_agent_info_helper(agent_name: str, agent_provider: object) ->
|
|
|
148
174
|
pass
|
|
149
175
|
|
|
150
176
|
|
|
151
|
-
async def _display_all_agents_with_hierarchy(
|
|
177
|
+
async def _display_all_agents_with_hierarchy(
|
|
178
|
+
available_agents: List[str], agent_provider: "AgentApp | None"
|
|
179
|
+
) -> None:
|
|
152
180
|
"""Display all agents with tree structure for workflow agents."""
|
|
153
181
|
# Track which agents are children to avoid displaying them twice
|
|
154
182
|
child_agents = set()
|
|
@@ -156,10 +184,9 @@ async def _display_all_agents_with_hierarchy(available_agents: List[str], agent_
|
|
|
156
184
|
# First pass: identify all child agents
|
|
157
185
|
for agent_name in available_agents:
|
|
158
186
|
try:
|
|
159
|
-
if
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
agent = agent_provider
|
|
187
|
+
if agent_provider is None:
|
|
188
|
+
continue
|
|
189
|
+
agent = agent_provider._agent(agent_name)
|
|
163
190
|
|
|
164
191
|
if agent.agent_type == AgentType.PARALLEL:
|
|
165
192
|
if hasattr(agent, "fan_out_agents") and agent.fan_out_agents:
|
|
@@ -184,10 +211,9 @@ async def _display_all_agents_with_hierarchy(available_agents: List[str], agent_
|
|
|
184
211
|
continue
|
|
185
212
|
|
|
186
213
|
try:
|
|
187
|
-
if
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
agent = agent_provider
|
|
214
|
+
if agent_provider is None:
|
|
215
|
+
continue
|
|
216
|
+
agent = agent_provider._agent(agent_name)
|
|
191
217
|
|
|
192
218
|
# Display parent agent
|
|
193
219
|
await _display_agent_info_helper(agent_name, agent_provider)
|
|
@@ -202,7 +228,7 @@ async def _display_all_agents_with_hierarchy(available_agents: List[str], agent_
|
|
|
202
228
|
continue
|
|
203
229
|
|
|
204
230
|
|
|
205
|
-
async def _display_parallel_children(parallel_agent, agent_provider) -> None:
|
|
231
|
+
async def _display_parallel_children(parallel_agent, agent_provider: "AgentApp | None") -> None:
|
|
206
232
|
"""Display child agents of a parallel agent in tree format."""
|
|
207
233
|
children = []
|
|
208
234
|
|
|
@@ -222,7 +248,7 @@ async def _display_parallel_children(parallel_agent, agent_provider) -> None:
|
|
|
222
248
|
await _display_child_agent_info(child_agent, prefix, agent_provider)
|
|
223
249
|
|
|
224
250
|
|
|
225
|
-
async def _display_router_children(router_agent, agent_provider) -> None:
|
|
251
|
+
async def _display_router_children(router_agent, agent_provider: "AgentApp | None") -> None:
|
|
226
252
|
"""Display child agents of a router agent in tree format."""
|
|
227
253
|
children = []
|
|
228
254
|
|
|
@@ -239,7 +265,9 @@ async def _display_router_children(router_agent, agent_provider) -> None:
|
|
|
239
265
|
await _display_child_agent_info(child_agent, prefix, agent_provider)
|
|
240
266
|
|
|
241
267
|
|
|
242
|
-
async def _display_child_agent_info(
|
|
268
|
+
async def _display_child_agent_info(
|
|
269
|
+
child_agent, prefix: str, agent_provider: "AgentApp | None"
|
|
270
|
+
) -> None:
|
|
243
271
|
"""Display info for a child agent with tree prefix."""
|
|
244
272
|
try:
|
|
245
273
|
# Get counts for child agent
|
|
@@ -425,7 +453,9 @@ def get_text_from_editor(initial_text: str = "") -> str:
|
|
|
425
453
|
return edited_text.strip() # Added strip() to remove trailing newlines often added by editors
|
|
426
454
|
|
|
427
455
|
|
|
428
|
-
def create_keybindings(
|
|
456
|
+
def create_keybindings(
|
|
457
|
+
on_toggle_multiline=None, app=None, agent_provider: "AgentApp | None" = None, agent_name=None
|
|
458
|
+
):
|
|
429
459
|
"""Create custom key bindings."""
|
|
430
460
|
kb = KeyBindings()
|
|
431
461
|
|
|
@@ -504,30 +534,20 @@ def create_keybindings(on_toggle_multiline=None, app=None, agent_provider=None,
|
|
|
504
534
|
"""Ctrl+Y: Copy last assistant response to clipboard."""
|
|
505
535
|
if kb.agent_provider and kb.current_agent_name:
|
|
506
536
|
try:
|
|
507
|
-
# Get the agent
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
import pyperclip
|
|
520
|
-
|
|
521
|
-
pyperclip.copy(content)
|
|
522
|
-
rich_print("\n[green]✓ Copied to clipboard[/green]")
|
|
523
|
-
return
|
|
524
|
-
|
|
525
|
-
else:
|
|
526
|
-
pass
|
|
537
|
+
# Get the agent from AgentApp
|
|
538
|
+
agent = kb.agent_provider._agent(kb.current_agent_name)
|
|
539
|
+
|
|
540
|
+
# Find last assistant message
|
|
541
|
+
for msg in reversed(agent.message_history):
|
|
542
|
+
if msg.role == "assistant":
|
|
543
|
+
content = msg.last_text()
|
|
544
|
+
import pyperclip
|
|
545
|
+
|
|
546
|
+
pyperclip.copy(content)
|
|
547
|
+
rich_print("\n[green]✓ Copied to clipboard[/green]")
|
|
548
|
+
return
|
|
527
549
|
except Exception:
|
|
528
550
|
pass
|
|
529
|
-
else:
|
|
530
|
-
pass
|
|
531
551
|
|
|
532
552
|
return kb
|
|
533
553
|
|
|
@@ -542,7 +562,7 @@ async def get_enhanced_input(
|
|
|
542
562
|
agent_types: dict[str, AgentType] = None,
|
|
543
563
|
is_human_input: bool = False,
|
|
544
564
|
toolbar_color: str = "ansiblue",
|
|
545
|
-
agent_provider:
|
|
565
|
+
agent_provider: "AgentApp | None" = None,
|
|
546
566
|
) -> str:
|
|
547
567
|
"""
|
|
548
568
|
Enhanced input with advanced prompt_toolkit features.
|
|
@@ -557,7 +577,7 @@ async def get_enhanced_input(
|
|
|
557
577
|
agent_types: Dictionary mapping agent names to their types for display
|
|
558
578
|
is_human_input: Whether this is a human input request (disables agent selection features)
|
|
559
579
|
toolbar_color: Color to use for the agent name in the toolbar (default: "ansiblue")
|
|
560
|
-
agent_provider: Optional
|
|
580
|
+
agent_provider: Optional AgentApp for displaying agent info
|
|
561
581
|
|
|
562
582
|
Returns:
|
|
563
583
|
User input string
|
|
@@ -598,18 +618,22 @@ async def get_enhanced_input(
|
|
|
598
618
|
|
|
599
619
|
shortcut_text = " | ".join(f"{key}:{action}" for key, action in shortcuts)
|
|
600
620
|
|
|
601
|
-
# Resolve model name and TDV from the current agent if available
|
|
621
|
+
# Resolve model name, turn counter, and TDV from the current agent if available
|
|
602
622
|
model_display = None
|
|
603
623
|
tdv_segment = None
|
|
624
|
+
turn_count = 0
|
|
604
625
|
try:
|
|
605
|
-
|
|
606
|
-
agent_provider._agent(agent_name)
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
626
|
+
if agent_provider:
|
|
627
|
+
agent = agent_provider._agent(agent_name)
|
|
628
|
+
|
|
629
|
+
# Get turn count from message history
|
|
630
|
+
for message in agent.message_history:
|
|
631
|
+
if message.role == "user":
|
|
632
|
+
turn_count += 1
|
|
633
|
+
|
|
634
|
+
# Get model name from LLM
|
|
635
|
+
if agent.llm and agent.llm.model_name:
|
|
636
|
+
model_name = agent.llm.model_name
|
|
613
637
|
# Truncate model name to max 25 characters with ellipsis
|
|
614
638
|
max_len = 25
|
|
615
639
|
if len(model_name) > max_len:
|
|
@@ -619,20 +643,35 @@ async def get_enhanced_input(
|
|
|
619
643
|
model_display = model_name
|
|
620
644
|
|
|
621
645
|
# Build TDV capability segment based on model database
|
|
622
|
-
info = get_model_info(
|
|
646
|
+
info = get_model_info(agent)
|
|
623
647
|
# Default to text-only if info resolution fails for any reason
|
|
624
648
|
t, d, v = (True, False, False)
|
|
625
649
|
if info:
|
|
626
650
|
t, d, v = info.tdv_flags
|
|
627
651
|
|
|
652
|
+
# Check for alert flags in user messages
|
|
653
|
+
alert_flags: set[str] = set()
|
|
654
|
+
error_seen = False
|
|
655
|
+
for message in agent.message_history:
|
|
656
|
+
if message.channels:
|
|
657
|
+
if message.channels.get(FAST_AGENT_ERROR_CHANNEL):
|
|
658
|
+
error_seen = True
|
|
659
|
+
if message.role == "user" and message.channels:
|
|
660
|
+
meta_blocks = message.channels.get(FAST_AGENT_REMOVED_METADATA_CHANNEL, [])
|
|
661
|
+
alert_flags.update(_extract_alert_flags_from_meta(meta_blocks))
|
|
662
|
+
|
|
663
|
+
if error_seen and not alert_flags:
|
|
664
|
+
alert_flags.add("T")
|
|
665
|
+
|
|
628
666
|
def _style_flag(letter: str, supported: bool) -> str:
|
|
629
667
|
# Enabled uses the same color as NORMAL mode (ansigreen), disabled is dim
|
|
668
|
+
if letter in alert_flags:
|
|
669
|
+
return f"<style fg='ansired' bg='ansiblack'>{letter}</style>"
|
|
670
|
+
|
|
630
671
|
enabled_color = "ansigreen"
|
|
631
|
-
|
|
632
|
-
f"<style fg='{enabled_color}' bg='ansiblack'>{letter}</style>"
|
|
633
|
-
|
|
634
|
-
else f"<style fg='ansiblack' bg='ansiwhite'>{letter}</style>"
|
|
635
|
-
)
|
|
672
|
+
if supported:
|
|
673
|
+
return f"<style fg='{enabled_color}' bg='ansiblack'>{letter}</style>"
|
|
674
|
+
return f"<style fg='ansiblack' bg='ansiwhite'>{letter}</style>"
|
|
636
675
|
|
|
637
676
|
tdv_segment = f"{_style_flag('T', t)}{_style_flag('D', d)}{_style_flag('V', v)}"
|
|
638
677
|
except Exception:
|
|
@@ -640,7 +679,7 @@ async def get_enhanced_input(
|
|
|
640
679
|
model_display = None
|
|
641
680
|
tdv_segment = None
|
|
642
681
|
|
|
643
|
-
# Build dynamic middle segments: model (in green) and optional shortcuts
|
|
682
|
+
# Build dynamic middle segments: model (in green), turn counter, and optional shortcuts
|
|
644
683
|
middle_segments = []
|
|
645
684
|
if model_display:
|
|
646
685
|
# Model chip + inline TDV flags
|
|
@@ -650,6 +689,10 @@ async def get_enhanced_input(
|
|
|
650
689
|
)
|
|
651
690
|
else:
|
|
652
691
|
middle_segments.append(f"<style bg='ansigreen'>{model_display}</style>")
|
|
692
|
+
|
|
693
|
+
# Add turn counter (formatted as 3 digits)
|
|
694
|
+
middle_segments.append(f"{turn_count:03d}")
|
|
695
|
+
|
|
653
696
|
if shortcut_text:
|
|
654
697
|
middle_segments.append(shortcut_text)
|
|
655
698
|
middle = " | ".join(middle_segments)
|
|
@@ -761,7 +804,9 @@ async def get_enhanced_input(
|
|
|
761
804
|
elif cmd in ("save_history", "save"):
|
|
762
805
|
# Return a structured action for the interactive loop to handle
|
|
763
806
|
# Prefer programmatic saving via HistoryExporter; fall back to magic-string there if needed
|
|
764
|
-
filename =
|
|
807
|
+
filename = (
|
|
808
|
+
cmd_parts[1].strip() if len(cmd_parts) > 1 and cmd_parts[1].strip() else None
|
|
809
|
+
)
|
|
765
810
|
return {"save_history": True, "filename": filename}
|
|
766
811
|
elif cmd == "prompt":
|
|
767
812
|
# Handle /prompt with no arguments as interactive mode
|
|
@@ -941,7 +986,9 @@ async def handle_special_commands(command, agent_app=None):
|
|
|
941
986
|
rich_print(" /usage - Show current usage statistics")
|
|
942
987
|
rich_print(" /markdown - Show last assistant message without markdown formatting")
|
|
943
988
|
rich_print(" /save_history <filename> - Save current chat history to a file")
|
|
944
|
-
rich_print(
|
|
989
|
+
rich_print(
|
|
990
|
+
" [dim]Tip: Use a .json extension for MCP-compatible JSON; any other extension saves Markdown.[/dim]"
|
|
991
|
+
)
|
|
945
992
|
rich_print(" @agent_name - Switch to agent")
|
|
946
993
|
rich_print(" STOP - Return control back to the workflow")
|
|
947
994
|
rich_print(" EXIT - Exit fast-agent, terminating any running workflows")
|
|
@@ -14,14 +14,16 @@ Usage:
|
|
|
14
14
|
)
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
|
-
from typing import Awaitable, Callable, Dict, List,
|
|
17
|
+
from typing import TYPE_CHECKING, Awaitable, Callable, Dict, List, Optional, Union
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from fast_agent.core.agent_app import AgentApp
|
|
18
21
|
|
|
19
22
|
from mcp.types import Prompt, PromptMessage
|
|
20
23
|
from rich import print as rich_print
|
|
21
24
|
|
|
22
25
|
from fast_agent.agents.agent_types import AgentType
|
|
23
26
|
from fast_agent.history.history_exporter import HistoryExporter
|
|
24
|
-
from fast_agent.interfaces import AgentProtocol
|
|
25
27
|
from fast_agent.mcp.mcp_aggregator import SEP
|
|
26
28
|
from fast_agent.types import PromptMessageExtended
|
|
27
29
|
from fast_agent.ui.enhanced_prompt import (
|
|
@@ -41,36 +43,6 @@ SendFunc = Callable[[Union[str, PromptMessage, PromptMessageExtended], str], Awa
|
|
|
41
43
|
AgentGetter = Callable[[str], Optional[object]]
|
|
42
44
|
|
|
43
45
|
|
|
44
|
-
class PromptProvider(Protocol):
|
|
45
|
-
"""Protocol for objects that can provide prompt functionality."""
|
|
46
|
-
|
|
47
|
-
async def list_prompts(
|
|
48
|
-
self, namespace: Optional[str] = None, agent_name: Optional[str] = None
|
|
49
|
-
) -> Mapping[str, List[Prompt]]:
|
|
50
|
-
"""List available prompts."""
|
|
51
|
-
...
|
|
52
|
-
|
|
53
|
-
async def apply_prompt(
|
|
54
|
-
self,
|
|
55
|
-
prompt_name: str,
|
|
56
|
-
prompt_title: Optional[str] = None,
|
|
57
|
-
arguments: Optional[Dict[str, str]] = None,
|
|
58
|
-
agent_name: Optional[str] = None,
|
|
59
|
-
as_template: bool = False,
|
|
60
|
-
**kwargs,
|
|
61
|
-
) -> str:
|
|
62
|
-
"""Apply a prompt."""
|
|
63
|
-
...
|
|
64
|
-
|
|
65
|
-
def _agent(self, agent_name: str) -> AgentProtocol:
|
|
66
|
-
"""Return the concrete agent by name (AgentApp provides this)."""
|
|
67
|
-
...
|
|
68
|
-
|
|
69
|
-
def _show_turn_usage(self, agent_name: str) -> None:
|
|
70
|
-
"""Display usage for a given agent after a turn."""
|
|
71
|
-
...
|
|
72
|
-
|
|
73
|
-
|
|
74
46
|
class InteractivePrompt:
|
|
75
47
|
"""
|
|
76
48
|
Provides interactive prompt functionality that works with any agent implementation.
|
|
@@ -91,7 +63,7 @@ class InteractivePrompt:
|
|
|
91
63
|
send_func: SendFunc,
|
|
92
64
|
default_agent: str,
|
|
93
65
|
available_agents: List[str],
|
|
94
|
-
prompt_provider:
|
|
66
|
+
prompt_provider: "AgentApp",
|
|
95
67
|
default: str = "",
|
|
96
68
|
) -> str:
|
|
97
69
|
"""
|
|
@@ -101,7 +73,7 @@ class InteractivePrompt:
|
|
|
101
73
|
send_func: Function to send messages to agents
|
|
102
74
|
default_agent: Name of the default agent to use
|
|
103
75
|
available_agents: List of available agent names
|
|
104
|
-
prompt_provider:
|
|
76
|
+
prompt_provider: AgentApp instance for accessing agents and prompts
|
|
105
77
|
default: Default message to use when user presses enter
|
|
106
78
|
|
|
107
79
|
Returns:
|
|
@@ -290,7 +262,7 @@ class InteractivePrompt:
|
|
|
290
262
|
rich_print()
|
|
291
263
|
|
|
292
264
|
async def _get_all_prompts(
|
|
293
|
-
self, prompt_provider:
|
|
265
|
+
self, prompt_provider: "AgentApp", agent_name: Optional[str] = None
|
|
294
266
|
):
|
|
295
267
|
"""
|
|
296
268
|
Get a list of all available prompts.
|
|
@@ -370,7 +342,7 @@ class InteractivePrompt:
|
|
|
370
342
|
rich_print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
371
343
|
return []
|
|
372
344
|
|
|
373
|
-
async def _list_prompts(self, prompt_provider:
|
|
345
|
+
async def _list_prompts(self, prompt_provider: "AgentApp", agent_name: str) -> None:
|
|
374
346
|
"""
|
|
375
347
|
List available prompts for an agent.
|
|
376
348
|
|
|
@@ -474,7 +446,7 @@ class InteractivePrompt:
|
|
|
474
446
|
|
|
475
447
|
async def _select_prompt(
|
|
476
448
|
self,
|
|
477
|
-
prompt_provider:
|
|
449
|
+
prompt_provider: "AgentApp",
|
|
478
450
|
agent_name: str,
|
|
479
451
|
requested_name: Optional[str] = None,
|
|
480
452
|
send_func: Optional[SendFunc] = None,
|
|
@@ -808,7 +780,7 @@ class InteractivePrompt:
|
|
|
808
780
|
rich_print(f"[red]Error selecting or applying prompt: {e}[/red]")
|
|
809
781
|
rich_print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
810
782
|
|
|
811
|
-
async def _list_tools(self, prompt_provider:
|
|
783
|
+
async def _list_tools(self, prompt_provider: "AgentApp", agent_name: str) -> None:
|
|
812
784
|
"""
|
|
813
785
|
List available tools for an agent.
|
|
814
786
|
|
|
@@ -908,7 +880,7 @@ class InteractivePrompt:
|
|
|
908
880
|
rich_print(f"[red]Error listing tools: {e}[/red]")
|
|
909
881
|
rich_print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
910
882
|
|
|
911
|
-
async def _show_usage(self, prompt_provider:
|
|
883
|
+
async def _show_usage(self, prompt_provider: "AgentApp", agent_name: str) -> None:
|
|
912
884
|
"""
|
|
913
885
|
Show usage statistics for the current agent(s) in a colorful table format.
|
|
914
886
|
|
|
@@ -930,7 +902,7 @@ class InteractivePrompt:
|
|
|
930
902
|
except Exception as e:
|
|
931
903
|
rich_print(f"[red]Error showing usage: {e}[/red]")
|
|
932
904
|
|
|
933
|
-
async def _show_system(self, prompt_provider:
|
|
905
|
+
async def _show_system(self, prompt_provider: "AgentApp", agent_name: str) -> None:
|
|
934
906
|
"""
|
|
935
907
|
Show the current system prompt for the agent.
|
|
936
908
|
|
|
@@ -980,7 +952,7 @@ class InteractivePrompt:
|
|
|
980
952
|
rich_print(f"[red]Error showing system prompt: {e}[/red]")
|
|
981
953
|
rich_print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
982
954
|
|
|
983
|
-
async def _show_markdown(self, prompt_provider:
|
|
955
|
+
async def _show_markdown(self, prompt_provider: "AgentApp", agent_name: str) -> None:
|
|
984
956
|
"""
|
|
985
957
|
Show the last assistant message without markdown formatting.
|
|
986
958
|
|
fast_agent/ui/rich_progress.py
CHANGED
|
@@ -98,8 +98,9 @@ class RichProgressDisplay:
|
|
|
98
98
|
task_id = self._progress.add_task(
|
|
99
99
|
"",
|
|
100
100
|
total=None,
|
|
101
|
-
target=
|
|
102
|
-
details=
|
|
101
|
+
target=event.target or task_name,
|
|
102
|
+
details=event.details or "",
|
|
103
|
+
task_name=task_name,
|
|
103
104
|
)
|
|
104
105
|
self._taskmap[task_name] = task_id
|
|
105
106
|
else:
|
|
@@ -136,11 +137,9 @@ class RichProgressDisplay:
|
|
|
136
137
|
# Update basic task information
|
|
137
138
|
update_kwargs: dict[str, object] = {
|
|
138
139
|
"description": description,
|
|
139
|
-
"
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
"task_name": task_name,
|
|
143
|
-
},
|
|
140
|
+
"target": event.target or task_name, # Use task_name as fallback for target
|
|
141
|
+
"details": event.details or "",
|
|
142
|
+
"task_name": task_name,
|
|
144
143
|
}
|
|
145
144
|
|
|
146
145
|
# For TOOL_PROGRESS events, update progress if available
|
|
@@ -149,8 +148,9 @@ class RichProgressDisplay:
|
|
|
149
148
|
update_kwargs["completed"] = event.progress
|
|
150
149
|
update_kwargs["total"] = event.total
|
|
151
150
|
else:
|
|
152
|
-
# If no total,
|
|
151
|
+
# If no total, reset to indeterminate but keep other fields
|
|
153
152
|
self._progress.reset(task_id)
|
|
153
|
+
# Still need to update after reset to apply the fields
|
|
154
154
|
|
|
155
155
|
self._progress.update(task_id, **update_kwargs)
|
|
156
156
|
|
|
@@ -165,7 +165,9 @@ class RichProgressDisplay:
|
|
|
165
165
|
task_id,
|
|
166
166
|
completed=100,
|
|
167
167
|
total=100,
|
|
168
|
+
target=event.target or task_name,
|
|
168
169
|
details=f" / Elapsed Time {time.strftime('%H:%M:%S', time.gmtime(self._progress.tasks[task_id].elapsed))}",
|
|
170
|
+
task_name=task_name,
|
|
169
171
|
)
|
|
170
172
|
for task in self._progress.tasks:
|
|
171
173
|
if task.id != task_id:
|
|
@@ -175,7 +177,9 @@ class RichProgressDisplay:
|
|
|
175
177
|
task_id,
|
|
176
178
|
completed=100,
|
|
177
179
|
total=100,
|
|
180
|
+
target=event.target or task_name,
|
|
178
181
|
details=f" / {event.details}",
|
|
182
|
+
task_name=task_name,
|
|
179
183
|
)
|
|
180
184
|
for task in self._progress.tasks:
|
|
181
185
|
if task.id != task_id:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fast-agent-mcp
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.7
|
|
4
4
|
Summary: Define, Prompt and Test MCP enabled Agents and Workflows
|
|
5
5
|
Author-email: Shaun Smith <fastagent@llmindset.co.uk>
|
|
6
6
|
License: Apache License
|
|
@@ -211,7 +211,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
211
211
|
Requires-Python: >=3.13.5
|
|
212
212
|
Requires-Dist: a2a-sdk>=0.3.0
|
|
213
213
|
Requires-Dist: aiohttp>=3.11.13
|
|
214
|
-
Requires-Dist: anthropic>=0.
|
|
214
|
+
Requires-Dist: anthropic>=0.68.0
|
|
215
215
|
Requires-Dist: azure-identity>=1.14.0
|
|
216
216
|
Requires-Dist: boto3>=1.35.0
|
|
217
217
|
Requires-Dist: deprecated>=1.2.18
|
|
@@ -220,7 +220,7 @@ Requires-Dist: fastapi>=0.115.6
|
|
|
220
220
|
Requires-Dist: google-genai>=1.33.0
|
|
221
221
|
Requires-Dist: keyring>=24.3.1
|
|
222
222
|
Requires-Dist: mcp==1.14.0
|
|
223
|
-
Requires-Dist: openai>=1.
|
|
223
|
+
Requires-Dist: openai>=1.108.0
|
|
224
224
|
Requires-Dist: opentelemetry-distro>=0.55b0
|
|
225
225
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.7.0
|
|
226
226
|
Requires-Dist: opentelemetry-instrumentation-anthropic>=0.43.1; python_version >= '3.10' and python_version < '4.0'
|