fast-agent-mcp 0.0.12__py3-none-any.whl → 0.0.14__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.0.12.dist-info → fast_agent_mcp-0.0.14.dist-info}/METADATA +194 -11
- {fast_agent_mcp-0.0.12.dist-info → fast_agent_mcp-0.0.14.dist-info}/RECORD +21 -23
- mcp_agent/agents/agent.py +48 -8
- mcp_agent/cli/commands/bootstrap.py +2 -1
- mcp_agent/cli/commands/setup.py +1 -1
- mcp_agent/cli/main.py +3 -3
- mcp_agent/core/enhanced_prompt.py +59 -16
- mcp_agent/core/exceptions.py +24 -0
- mcp_agent/core/fastagent.py +262 -34
- mcp_agent/human_input/handler.py +43 -18
- mcp_agent/mcp/mcp_connection_manager.py +14 -12
- mcp_agent/resources/examples/workflows/chaining.py +18 -4
- mcp_agent/resources/examples/workflows/evaluator.py +2 -2
- mcp_agent/resources/examples/workflows/fastagent.config.yaml +24 -0
- mcp_agent/resources/examples/workflows/orchestrator.py +3 -2
- mcp_agent/resources/examples/workflows/parallel.py +2 -1
- mcp_agent/workflows/llm/augmented_llm.py +3 -0
- mcp_agent/workflows/llm/model_factory.py +7 -4
- mcp_agent/resources/examples/mcp_researcher/researcher.py +0 -38
- mcp_agent/resources/examples/workflows/agent.py +0 -17
- mcp_agent/resources/examples/workflows/fastagent.py +0 -22
- {fast_agent_mcp-0.0.12.dist-info → fast_agent_mcp-0.0.14.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.0.12.dist-info → fast_agent_mcp-0.0.14.dist-info}/entry_points.txt +0 -0
- {fast_agent_mcp-0.0.12.dist-info → fast_agent_mcp-0.0.14.dist-info}/licenses/LICENSE +0 -0
|
@@ -13,6 +13,8 @@ from prompt_toolkit.filters import Condition
|
|
|
13
13
|
from pygments.lexers.python import PythonLexer
|
|
14
14
|
from rich import print as rich_print
|
|
15
15
|
|
|
16
|
+
from mcp_agent.core.exceptions import PromptExitError
|
|
17
|
+
|
|
16
18
|
# Map of agent names to their history
|
|
17
19
|
agent_histories = {}
|
|
18
20
|
|
|
@@ -29,9 +31,25 @@ agent_messages_shown = set()
|
|
|
29
31
|
class AgentCompleter(Completer):
|
|
30
32
|
"""Provide completion for agent names and common commands."""
|
|
31
33
|
|
|
32
|
-
def __init__(
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
agents: List[str],
|
|
37
|
+
commands: List[str] = None,
|
|
38
|
+
agent_types: dict = None,
|
|
39
|
+
is_human_input: bool = False,
|
|
40
|
+
):
|
|
33
41
|
self.agents = agents
|
|
34
|
-
|
|
42
|
+
# Map commands to their descriptions for better completion hints
|
|
43
|
+
self.commands = {
|
|
44
|
+
"help": "Show available commands",
|
|
45
|
+
"clear": "Clear the screen",
|
|
46
|
+
"agents": "List available agents",
|
|
47
|
+
"STOP": "Stop this prompting session and move to next workflow step",
|
|
48
|
+
"EXIT": "Exit FastAgent, terminating any running workflows",
|
|
49
|
+
**(commands or {}), # Allow custom commands to be passed in
|
|
50
|
+
}
|
|
51
|
+
if is_human_input:
|
|
52
|
+
self.commands.pop("agents")
|
|
35
53
|
self.agent_types = agent_types or {}
|
|
36
54
|
|
|
37
55
|
def get_completions(self, document, complete_event):
|
|
@@ -41,13 +59,13 @@ class AgentCompleter(Completer):
|
|
|
41
59
|
# Complete commands
|
|
42
60
|
if text.startswith("/"):
|
|
43
61
|
cmd = text[1:]
|
|
44
|
-
for command in self.commands:
|
|
62
|
+
for command, description in self.commands.items():
|
|
45
63
|
if command.lower().startswith(cmd):
|
|
46
64
|
yield Completion(
|
|
47
65
|
command,
|
|
48
66
|
start_position=-len(cmd),
|
|
49
67
|
display=command,
|
|
50
|
-
display_meta=
|
|
68
|
+
display_meta=description,
|
|
51
69
|
)
|
|
52
70
|
|
|
53
71
|
# Complete agent names for agent-related commands
|
|
@@ -62,6 +80,7 @@ class AgentCompleter(Completer):
|
|
|
62
80
|
start_position=-len(agent_name),
|
|
63
81
|
display=agent,
|
|
64
82
|
display_meta=agent_type,
|
|
83
|
+
style="bg:ansiblack fg:ansiblue",
|
|
65
84
|
)
|
|
66
85
|
|
|
67
86
|
|
|
@@ -79,9 +98,10 @@ def create_keybindings(on_toggle_multiline=None, app=None):
|
|
|
79
98
|
"""Enter: insert newline when in multiline mode."""
|
|
80
99
|
event.current_buffer.insert_text("\n")
|
|
81
100
|
|
|
82
|
-
|
|
101
|
+
# Use c-j (Ctrl+J) as an alternative to represent Ctrl+Enter in multiline mode
|
|
102
|
+
@kb.add("c-j", filter=Condition(lambda: in_multiline_mode))
|
|
83
103
|
def _(event):
|
|
84
|
-
"""
|
|
104
|
+
"""Ctrl+J (equivalent to Ctrl+Enter): Submit in multiline mode."""
|
|
85
105
|
event.current_buffer.validate_and_handle()
|
|
86
106
|
|
|
87
107
|
@kb.add("c-t")
|
|
@@ -105,7 +125,7 @@ def create_keybindings(on_toggle_multiline=None, app=None):
|
|
|
105
125
|
|
|
106
126
|
@kb.add("c-l")
|
|
107
127
|
def _(event):
|
|
108
|
-
"""Ctrl+L: Clear input."""
|
|
128
|
+
"""Ctrl+L: Clear the input buffer."""
|
|
109
129
|
event.current_buffer.text = ""
|
|
110
130
|
|
|
111
131
|
return kb
|
|
@@ -120,6 +140,8 @@ async def get_enhanced_input(
|
|
|
120
140
|
available_agent_names: List[str] = None,
|
|
121
141
|
syntax: str = None,
|
|
122
142
|
agent_types: dict = None,
|
|
143
|
+
is_human_input: bool = False,
|
|
144
|
+
toolbar_color: str = "ansiblue",
|
|
123
145
|
) -> str:
|
|
124
146
|
"""
|
|
125
147
|
Enhanced input with advanced prompt_toolkit features.
|
|
@@ -133,6 +155,8 @@ async def get_enhanced_input(
|
|
|
133
155
|
available_agent_names: List of agent names for auto-completion
|
|
134
156
|
syntax: Syntax highlighting (e.g., 'python', 'sql')
|
|
135
157
|
agent_types: Dictionary mapping agent names to their types for display
|
|
158
|
+
is_human_input: Whether this is a human input request (disables agent selection features)
|
|
159
|
+
toolbar_color: Color to use for the agent name in the toolbar (default: "ansiblue")
|
|
136
160
|
|
|
137
161
|
Returns:
|
|
138
162
|
User input string
|
|
@@ -167,16 +191,20 @@ async def get_enhanced_input(
|
|
|
167
191
|
|
|
168
192
|
shortcuts = [
|
|
169
193
|
("Ctrl+T", toggle_text),
|
|
170
|
-
("Alt+Enter", "Submit" if in_multiline_mode else ""),
|
|
171
194
|
("Ctrl+L", "Clear"),
|
|
172
195
|
("↑/↓", "History"),
|
|
173
196
|
]
|
|
197
|
+
|
|
198
|
+
newline = (
|
|
199
|
+
"Ctrl+<Enter>:Submit" if in_multiline_mode else "<Enter>:Submit"
|
|
200
|
+
)
|
|
201
|
+
|
|
174
202
|
# Only show relevant shortcuts based on mode
|
|
175
203
|
shortcuts = [(k, v) for k, v in shortcuts if v]
|
|
176
204
|
|
|
177
205
|
shortcut_text = " | ".join(f"{key}:{action}" for key, action in shortcuts)
|
|
178
206
|
return HTML(
|
|
179
|
-
f" <
|
|
207
|
+
f" <{toolbar_color}> {agent_name} </{toolbar_color}> | <b>Mode:</b> <{mode_style}> {mode_text} </{mode_style}> {newline} | {shortcut_text}"
|
|
180
208
|
)
|
|
181
209
|
|
|
182
210
|
# Create session with history and completions
|
|
@@ -185,12 +213,13 @@ async def get_enhanced_input(
|
|
|
185
213
|
completer=AgentCompleter(
|
|
186
214
|
agents=list(available_agents) if available_agents else [],
|
|
187
215
|
agent_types=agent_types or {},
|
|
216
|
+
is_human_input=is_human_input,
|
|
188
217
|
),
|
|
189
218
|
complete_while_typing=True,
|
|
190
219
|
lexer=PygmentsLexer(PythonLexer) if syntax == "python" else None,
|
|
191
220
|
multiline=Condition(lambda: in_multiline_mode),
|
|
192
221
|
complete_in_thread=True,
|
|
193
|
-
mouse_support=
|
|
222
|
+
mouse_support=False,
|
|
194
223
|
bottom_toolbar=get_toolbar, # Pass the function here
|
|
195
224
|
)
|
|
196
225
|
|
|
@@ -220,9 +249,14 @@ async def get_enhanced_input(
|
|
|
220
249
|
|
|
221
250
|
# Mention available features but only on first usage for this agent
|
|
222
251
|
if agent_name not in agent_messages_shown:
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
252
|
+
if is_human_input:
|
|
253
|
+
rich_print(
|
|
254
|
+
"[dim]Tip: Type /help for commands. Ctrl+T toggles multiline mode. Ctrl+Enter to submit in multiline mode.[/dim]"
|
|
255
|
+
)
|
|
256
|
+
else:
|
|
257
|
+
rich_print(
|
|
258
|
+
"[dim]Tip: Type /help for commands, @Agent to switch agent. Ctrl+T toggles multiline mode. [/dim]"
|
|
259
|
+
)
|
|
226
260
|
agent_messages_shown.add(agent_name)
|
|
227
261
|
|
|
228
262
|
# Process special commands
|
|
@@ -236,6 +270,10 @@ async def get_enhanced_input(
|
|
|
236
270
|
return "CLEAR"
|
|
237
271
|
elif cmd == "agents":
|
|
238
272
|
return "LIST_AGENTS"
|
|
273
|
+
elif cmd == "exit":
|
|
274
|
+
return "EXIT"
|
|
275
|
+
elif cmd == "stop":
|
|
276
|
+
return "STOP"
|
|
239
277
|
|
|
240
278
|
# Agent switching
|
|
241
279
|
if text and text.startswith("@"):
|
|
@@ -272,16 +310,18 @@ async def handle_special_commands(command, agent_app=None):
|
|
|
272
310
|
rich_print(" /clear - Clear screen")
|
|
273
311
|
rich_print(" /agents - List available agents")
|
|
274
312
|
rich_print(" @agent_name - Switch to agent")
|
|
275
|
-
rich_print(" STOP -
|
|
313
|
+
rich_print(" STOP - Return control back to the workflow")
|
|
314
|
+
rich_print(
|
|
315
|
+
" EXIT - Exit FastAgent, terminating any running workflows"
|
|
316
|
+
)
|
|
276
317
|
rich_print("\n[bold]Keyboard Shortcuts:[/bold]")
|
|
277
318
|
rich_print(
|
|
278
319
|
" Enter - Submit (normal mode) / New line (multiline mode)"
|
|
279
320
|
)
|
|
280
|
-
rich_print("
|
|
321
|
+
rich_print(" Ctrl+Enter - Always submit (even in multiline mode)")
|
|
281
322
|
rich_print(" Ctrl+T - Toggle multiline mode")
|
|
282
323
|
rich_print(" Ctrl+L - Clear input")
|
|
283
324
|
rich_print(" Up/Down - Navigate history")
|
|
284
|
-
rich_print(" F1 - Show help")
|
|
285
325
|
return True
|
|
286
326
|
|
|
287
327
|
elif command == "CLEAR":
|
|
@@ -289,6 +329,9 @@ async def handle_special_commands(command, agent_app=None):
|
|
|
289
329
|
print("\033c", end="")
|
|
290
330
|
return True
|
|
291
331
|
|
|
332
|
+
elif command == "EXIT":
|
|
333
|
+
raise PromptExitError("User requested to exit FastAgent session")
|
|
334
|
+
|
|
292
335
|
elif command == "LIST_AGENTS":
|
|
293
336
|
if available_agents:
|
|
294
337
|
rich_print("\n[bold]Available Agents:[/bold]")
|
mcp_agent/core/exceptions.py
CHANGED
|
@@ -45,3 +45,27 @@ class ServerInitializationError(FastAgentError):
|
|
|
45
45
|
|
|
46
46
|
def __init__(self, message: str, details: str = ""):
|
|
47
47
|
super().__init__(message, details)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ModelConfigError(FastAgentError):
|
|
51
|
+
"""Raised when there are issues with LLM model configuration
|
|
52
|
+
Example: Unknown model name in model specification string
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def __init__(self, message: str, details: str = ""):
|
|
56
|
+
super().__init__(message, details)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class CircularDependencyError(FastAgentError):
|
|
60
|
+
"""Raised when we detect a Circular Dependency in the workflow"""
|
|
61
|
+
|
|
62
|
+
def __init__(self, message: str, details: str = ""):
|
|
63
|
+
super().__init__(message, details)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class PromptExitError(FastAgentError):
|
|
67
|
+
"""Raised from enhanced_prompt when the user requests hard exits"""
|
|
68
|
+
|
|
69
|
+
# TODO an exception for flow control :(
|
|
70
|
+
def __init__(self, message: str, details: str = ""):
|
|
71
|
+
super().__init__(message, details)
|