fast-agent-mcp 0.3.14__py3-none-any.whl → 0.3.16__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 +2 -0
- fast_agent/agents/agent_types.py +5 -0
- fast_agent/agents/llm_agent.py +52 -4
- fast_agent/agents/llm_decorator.py +6 -0
- fast_agent/agents/mcp_agent.py +137 -13
- fast_agent/agents/tool_agent.py +33 -19
- fast_agent/agents/workflow/router_agent.py +2 -1
- fast_agent/cli/__main__.py +35 -0
- fast_agent/cli/commands/check_config.py +90 -2
- fast_agent/cli/commands/go.py +100 -36
- fast_agent/cli/constants.py +13 -1
- fast_agent/cli/main.py +1 -0
- fast_agent/config.py +41 -12
- fast_agent/constants.py +8 -0
- fast_agent/context.py +24 -15
- fast_agent/core/direct_decorators.py +9 -0
- fast_agent/core/fastagent.py +115 -2
- fast_agent/core/logging/listeners.py +8 -0
- fast_agent/core/validation.py +31 -33
- fast_agent/human_input/form_fields.py +4 -1
- fast_agent/interfaces.py +12 -1
- fast_agent/llm/fastagent_llm.py +76 -0
- fast_agent/llm/memory.py +26 -1
- fast_agent/llm/model_database.py +2 -2
- fast_agent/llm/model_factory.py +4 -1
- fast_agent/llm/provider/anthropic/llm_anthropic.py +112 -0
- fast_agent/llm/provider/openai/llm_openai.py +184 -18
- fast_agent/llm/provider/openai/responses.py +133 -0
- fast_agent/mcp/prompt_message_extended.py +2 -2
- fast_agent/resources/setup/agent.py +2 -0
- fast_agent/resources/setup/fastagent.config.yaml +11 -4
- fast_agent/skills/__init__.py +9 -0
- fast_agent/skills/registry.py +200 -0
- fast_agent/tools/shell_runtime.py +404 -0
- fast_agent/ui/console_display.py +925 -73
- fast_agent/ui/elicitation_form.py +98 -24
- fast_agent/ui/elicitation_style.py +2 -2
- fast_agent/ui/enhanced_prompt.py +128 -26
- fast_agent/ui/history_display.py +20 -5
- fast_agent/ui/interactive_prompt.py +108 -3
- fast_agent/ui/markdown_truncator.py +942 -0
- fast_agent/ui/mcp_display.py +2 -2
- fast_agent/ui/plain_text_truncator.py +68 -0
- fast_agent/ui/streaming_buffer.py +449 -0
- {fast_agent_mcp-0.3.14.dist-info → fast_agent_mcp-0.3.16.dist-info}/METADATA +9 -7
- {fast_agent_mcp-0.3.14.dist-info → fast_agent_mcp-0.3.16.dist-info}/RECORD +49 -42
- {fast_agent_mcp-0.3.14.dist-info → fast_agent_mcp-0.3.16.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.3.14.dist-info → fast_agent_mcp-0.3.16.dist-info}/entry_points.txt +0 -0
- {fast_agent_mcp-0.3.14.dist-info → fast_agent_mcp-0.3.16.dist-info}/licenses/LICENSE +0 -0
|
@@ -14,6 +14,7 @@ Usage:
|
|
|
14
14
|
)
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
|
+
from pathlib import Path
|
|
17
18
|
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, List, Optional, Union, cast
|
|
18
19
|
|
|
19
20
|
if TYPE_CHECKING:
|
|
@@ -169,6 +170,9 @@ class InteractivePrompt:
|
|
|
169
170
|
# Handle tools list display
|
|
170
171
|
await self._list_tools(prompt_provider, agent)
|
|
171
172
|
continue
|
|
173
|
+
elif "list_skills" in command_dict:
|
|
174
|
+
await self._list_skills(prompt_provider, agent)
|
|
175
|
+
continue
|
|
172
176
|
elif "show_usage" in command_dict:
|
|
173
177
|
# Handle usage display
|
|
174
178
|
await self._show_usage(prompt_provider, agent)
|
|
@@ -189,6 +193,41 @@ class InteractivePrompt:
|
|
|
189
193
|
usage = getattr(agent_obj, "usage_accumulator", None)
|
|
190
194
|
display_history_overview(target_agent, history, usage)
|
|
191
195
|
continue
|
|
196
|
+
elif "clear_last" in command_dict:
|
|
197
|
+
clear_info = command_dict.get("clear_last")
|
|
198
|
+
clear_agent = (
|
|
199
|
+
clear_info.get("agent") if isinstance(clear_info, dict) else None
|
|
200
|
+
)
|
|
201
|
+
target_agent = clear_agent or agent
|
|
202
|
+
try:
|
|
203
|
+
agent_obj = prompt_provider._agent(target_agent)
|
|
204
|
+
except Exception:
|
|
205
|
+
rich_print(f"[red]Unable to load agent '{target_agent}'[/red]")
|
|
206
|
+
continue
|
|
207
|
+
|
|
208
|
+
removed_message = None
|
|
209
|
+
pop_callable = getattr(agent_obj, "pop_last_message", None)
|
|
210
|
+
if callable(pop_callable):
|
|
211
|
+
removed_message = pop_callable()
|
|
212
|
+
else:
|
|
213
|
+
history = getattr(agent_obj, "message_history", [])
|
|
214
|
+
if history:
|
|
215
|
+
try:
|
|
216
|
+
removed_message = history.pop()
|
|
217
|
+
except Exception:
|
|
218
|
+
removed_message = None
|
|
219
|
+
|
|
220
|
+
if removed_message:
|
|
221
|
+
role = getattr(removed_message, "role", "message")
|
|
222
|
+
role_display = role.capitalize() if isinstance(role, str) else "Message"
|
|
223
|
+
rich_print(
|
|
224
|
+
f"[green]Removed last {role_display} for agent '{target_agent}'.[/green]"
|
|
225
|
+
)
|
|
226
|
+
else:
|
|
227
|
+
rich_print(
|
|
228
|
+
f"[yellow]No messages to remove for agent '{target_agent}'.[/yellow]"
|
|
229
|
+
)
|
|
230
|
+
continue
|
|
192
231
|
elif "clear_history" in command_dict:
|
|
193
232
|
clear_info = command_dict.get("clear_history")
|
|
194
233
|
clear_agent = (
|
|
@@ -857,19 +896,21 @@ class InteractivePrompt:
|
|
|
857
896
|
rich_print()
|
|
858
897
|
|
|
859
898
|
# Display tools using clean compact format
|
|
860
|
-
|
|
899
|
+
index = 1
|
|
900
|
+
for tool in tools_result.tools:
|
|
861
901
|
# Main line: [ 1] tool_name Title
|
|
862
902
|
from rich.text import Text
|
|
863
903
|
|
|
904
|
+
meta = getattr(tool, "meta", {}) or {}
|
|
905
|
+
|
|
864
906
|
tool_line = Text()
|
|
865
|
-
tool_line.append(f"[{
|
|
907
|
+
tool_line.append(f"[{index:2}] ", style="dim cyan")
|
|
866
908
|
tool_line.append(tool.name, style="bright_blue bold")
|
|
867
909
|
|
|
868
910
|
# Add title if available
|
|
869
911
|
if tool.title and tool.title.strip():
|
|
870
912
|
tool_line.append(f" {tool.title}", style="default")
|
|
871
913
|
|
|
872
|
-
meta = getattr(tool, "meta", {}) or {}
|
|
873
914
|
if meta.get("openai/skybridgeEnabled"):
|
|
874
915
|
tool_line.append(" (skybridge)", style="cyan")
|
|
875
916
|
|
|
@@ -932,13 +973,77 @@ class InteractivePrompt:
|
|
|
932
973
|
rich_print(f" [dim magenta]template:[/dim magenta] {template}")
|
|
933
974
|
|
|
934
975
|
rich_print() # Space between tools
|
|
976
|
+
index += 1
|
|
935
977
|
|
|
978
|
+
if index == 1:
|
|
979
|
+
rich_print("[yellow]No MCP tools available for this agent[/yellow]")
|
|
936
980
|
except Exception as e:
|
|
937
981
|
import traceback
|
|
938
982
|
|
|
939
983
|
rich_print(f"[red]Error listing tools: {e}[/red]")
|
|
940
984
|
rich_print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
941
985
|
|
|
986
|
+
async def _list_skills(self, prompt_provider: "AgentApp", agent_name: str) -> None:
|
|
987
|
+
"""List available local skills for an agent."""
|
|
988
|
+
|
|
989
|
+
try:
|
|
990
|
+
assert hasattr(prompt_provider, "_agent"), (
|
|
991
|
+
"Interactive prompt expects an AgentApp with _agent()"
|
|
992
|
+
)
|
|
993
|
+
agent = prompt_provider._agent(agent_name)
|
|
994
|
+
|
|
995
|
+
rich_print(f"\n[bold]Skills for agent [cyan]{agent_name}[/cyan]:[/bold]")
|
|
996
|
+
|
|
997
|
+
skill_manifests = getattr(agent, "_skill_manifests", None)
|
|
998
|
+
manifests = list(skill_manifests) if skill_manifests else []
|
|
999
|
+
|
|
1000
|
+
if not manifests:
|
|
1001
|
+
rich_print("[yellow]No skills available for this agent[/yellow]")
|
|
1002
|
+
return
|
|
1003
|
+
|
|
1004
|
+
rich_print()
|
|
1005
|
+
|
|
1006
|
+
for index, manifest in enumerate(manifests, 1):
|
|
1007
|
+
from rich.text import Text
|
|
1008
|
+
|
|
1009
|
+
name = getattr(manifest, "name", "")
|
|
1010
|
+
description = getattr(manifest, "description", "")
|
|
1011
|
+
path = Path(getattr(manifest, "path", Path()))
|
|
1012
|
+
|
|
1013
|
+
tool_line = Text()
|
|
1014
|
+
tool_line.append(f"[{index:2}] ", style="dim cyan")
|
|
1015
|
+
tool_line.append(name, style="bright_blue bold")
|
|
1016
|
+
rich_print(tool_line)
|
|
1017
|
+
|
|
1018
|
+
if description:
|
|
1019
|
+
import textwrap
|
|
1020
|
+
|
|
1021
|
+
wrapped_lines = textwrap.wrap(
|
|
1022
|
+
description.strip(), width=72, subsequent_indent=" "
|
|
1023
|
+
)
|
|
1024
|
+
for line in wrapped_lines:
|
|
1025
|
+
if line.startswith(" "):
|
|
1026
|
+
rich_print(f" [white]{line[5:]}[/white]")
|
|
1027
|
+
else:
|
|
1028
|
+
rich_print(f" [white]{line}[/white]")
|
|
1029
|
+
|
|
1030
|
+
source_path = path if path else Path(".")
|
|
1031
|
+
if source_path.is_file():
|
|
1032
|
+
source_path = source_path.parent
|
|
1033
|
+
try:
|
|
1034
|
+
display_path = source_path.relative_to(Path.cwd())
|
|
1035
|
+
except ValueError:
|
|
1036
|
+
display_path = source_path
|
|
1037
|
+
|
|
1038
|
+
rich_print(f" [dim green]source:[/dim green] {display_path}")
|
|
1039
|
+
rich_print()
|
|
1040
|
+
|
|
1041
|
+
except Exception as exc: # noqa: BLE001
|
|
1042
|
+
import traceback
|
|
1043
|
+
|
|
1044
|
+
rich_print(f"[red]Error listing skills: {exc}[/red]")
|
|
1045
|
+
rich_print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
1046
|
+
|
|
942
1047
|
async def _show_usage(self, prompt_provider: "AgentApp", agent_name: str) -> None:
|
|
943
1048
|
"""
|
|
944
1049
|
Show usage statistics for the current agent(s) in a colorful table format.
|