fast-agent-mcp 0.2.45__py3-none-any.whl → 0.2.47__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.45.dist-info → fast_agent_mcp-0.2.47.dist-info}/METADATA +13 -13
- {fast_agent_mcp-0.2.45.dist-info → fast_agent_mcp-0.2.47.dist-info}/RECORD +35 -30
- mcp_agent/__init__.py +40 -0
- mcp_agent/agents/workflow/iterative_planner.py +572 -0
- mcp_agent/agents/workflow/orchestrator_agent.py +3 -3
- mcp_agent/agents/workflow/orchestrator_models.py +6 -6
- mcp_agent/cli/commands/go.py +25 -4
- mcp_agent/core/__init__.py +26 -0
- mcp_agent/core/agent_types.py +1 -0
- mcp_agent/core/direct_decorators.py +168 -16
- mcp_agent/core/direct_factory.py +42 -15
- mcp_agent/core/fastagent.py +4 -0
- mcp_agent/core/mermaid_utils.py +170 -0
- mcp_agent/human_input/__init__.py +50 -0
- mcp_agent/human_input/form_fields.py +252 -0
- mcp_agent/human_input/simple_form.py +111 -0
- mcp_agent/llm/augmented_llm.py +11 -2
- mcp_agent/llm/augmented_llm_playback.py +5 -3
- mcp_agent/llm/model_database.py +2 -7
- mcp_agent/llm/providers/augmented_llm_aliyun.py +1 -1
- mcp_agent/llm/providers/augmented_llm_anthropic.py +1 -1
- mcp_agent/llm/providers/augmented_llm_deepseek.py +4 -2
- mcp_agent/llm/providers/augmented_llm_google_oai.py +1 -1
- mcp_agent/llm/providers/augmented_llm_openrouter.py +1 -1
- mcp_agent/llm/providers/augmented_llm_tensorzero.py +1 -1
- mcp_agent/llm/providers/augmented_llm_xai.py +1 -1
- mcp_agent/mcp/__init__.py +50 -0
- mcp_agent/mcp/helpers/__init__.py +23 -1
- mcp_agent/mcp/interfaces.py +13 -2
- mcp_agent/py.typed +0 -0
- mcp_agent/resources/examples/workflows/orchestrator.py +5 -2
- mcp_agent/ui/console_display.py +104 -39
- {fast_agent_mcp-0.2.45.dist-info → fast_agent_mcp-0.2.47.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.2.45.dist-info → fast_agent_mcp-0.2.47.dist-info}/entry_points.txt +0 -0
- {fast_agent_mcp-0.2.45.dist-info → fast_agent_mcp-0.2.47.dist-info}/licenses/LICENSE +0 -0
mcp_agent/mcp/interfaces.py
CHANGED
|
@@ -36,6 +36,17 @@ if TYPE_CHECKING:
|
|
|
36
36
|
from mcp_agent.llm.usage_tracking import UsageAccumulator
|
|
37
37
|
|
|
38
38
|
|
|
39
|
+
__all__ = [
|
|
40
|
+
"MCPConnectionManagerProtocol",
|
|
41
|
+
"ServerRegistryProtocol",
|
|
42
|
+
"ServerConnection",
|
|
43
|
+
"AugmentedLLMProtocol",
|
|
44
|
+
"AgentProtocol",
|
|
45
|
+
"ModelFactoryClassProtocol",
|
|
46
|
+
"ModelT",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
|
|
39
50
|
@runtime_checkable
|
|
40
51
|
class MCPConnectionManagerProtocol(Protocol):
|
|
41
52
|
"""Protocol for MCPConnectionManager functionality needed by ServerRegistry."""
|
|
@@ -101,7 +112,7 @@ class AugmentedLLMProtocol(Protocol):
|
|
|
101
112
|
|
|
102
113
|
async def structured(
|
|
103
114
|
self,
|
|
104
|
-
multipart_messages: List[PromptMessageMultipart],
|
|
115
|
+
multipart_messages: List[Union[PromptMessageMultipart, PromptMessage]],
|
|
105
116
|
model: Type[ModelT],
|
|
106
117
|
request_params: RequestParams | None = None,
|
|
107
118
|
) -> Tuple[ModelT | None, PromptMessageMultipart]:
|
|
@@ -110,7 +121,7 @@ class AugmentedLLMProtocol(Protocol):
|
|
|
110
121
|
|
|
111
122
|
async def generate(
|
|
112
123
|
self,
|
|
113
|
-
multipart_messages: List[PromptMessageMultipart],
|
|
124
|
+
multipart_messages: List[Union[PromptMessageMultipart, PromptMessage]],
|
|
114
125
|
request_params: RequestParams | None = None,
|
|
115
126
|
) -> PromptMessageMultipart:
|
|
116
127
|
"""
|
mcp_agent/py.typed
ADDED
|
File without changes
|
|
@@ -43,8 +43,11 @@ fast = FastAgent("Orchestrator-Workers")
|
|
|
43
43
|
model="gpt-4.1",
|
|
44
44
|
)
|
|
45
45
|
# Define the orchestrator to coordinate the other agents
|
|
46
|
-
@fast.
|
|
47
|
-
name="orchestrate",
|
|
46
|
+
@fast.iterative_planner(
|
|
47
|
+
name="orchestrate",
|
|
48
|
+
agents=["finder", "writer", "proofreader"],
|
|
49
|
+
model="sonnet",
|
|
50
|
+
plan_iterations=5,
|
|
48
51
|
)
|
|
49
52
|
async def main() -> None:
|
|
50
53
|
async with fast.run() as agent:
|
mcp_agent/ui/console_display.py
CHANGED
|
@@ -7,6 +7,11 @@ from rich.panel import Panel
|
|
|
7
7
|
from rich.text import Text
|
|
8
8
|
|
|
9
9
|
from mcp_agent import console
|
|
10
|
+
from mcp_agent.core.mermaid_utils import (
|
|
11
|
+
create_mermaid_live_link,
|
|
12
|
+
detect_diagram_type,
|
|
13
|
+
extract_mermaid_diagrams,
|
|
14
|
+
)
|
|
10
15
|
from mcp_agent.mcp.common import SEP
|
|
11
16
|
from mcp_agent.mcp.mcp_aggregator import MCPAggregator
|
|
12
17
|
|
|
@@ -158,29 +163,29 @@ class ConsoleDisplay:
|
|
|
158
163
|
content = content[:360] + "..."
|
|
159
164
|
console.console.print(content, style="dim", markup=self._markup)
|
|
160
165
|
|
|
161
|
-
# Bottom separator with tool list
|
|
166
|
+
# Bottom separator with tool list using pipe separators (matching server style)
|
|
162
167
|
console.console.print()
|
|
168
|
+
|
|
169
|
+
# Use existing tool list formatting with pipe separators
|
|
163
170
|
if display_tool_list and len(display_tool_list) > 0:
|
|
164
|
-
# Truncate tool list if needed (leave space for "
|
|
171
|
+
# Truncate tool list if needed (leave space for "─| " prefix and " |" suffix)
|
|
165
172
|
max_tool_width = console.console.size.width - 10 # Reserve space for separators
|
|
166
173
|
truncated_tool_list = self._truncate_list_if_needed(display_tool_list, max_tool_width)
|
|
167
|
-
tool_width = truncated_tool_list.cell_len
|
|
168
|
-
|
|
169
|
-
# Calculate how much space is left for separator line on the right
|
|
170
|
-
total_width = console.console.size.width
|
|
171
|
-
remaining_width = max(0, total_width - tool_width - 2) # -2 for "─ " prefix
|
|
172
|
-
right_sep = "─" * remaining_width if remaining_width > 0 else ""
|
|
173
|
-
|
|
174
|
-
# Create the separator line: ─ [tools] ────────
|
|
175
|
-
combined = Text()
|
|
176
|
-
combined.append("─ ", style="dim")
|
|
177
|
-
combined.append_text(truncated_tool_list)
|
|
178
|
-
combined.append(right_sep, style="dim")
|
|
179
174
|
|
|
180
|
-
|
|
175
|
+
# Create the separator line: ─| [tools] |──────
|
|
176
|
+
line1 = Text()
|
|
177
|
+
line1.append("─| ", style="dim")
|
|
178
|
+
line1.append_text(truncated_tool_list)
|
|
179
|
+
line1.append(" |", style="dim")
|
|
180
|
+
remaining = console.console.size.width - line1.cell_len
|
|
181
|
+
if remaining > 0:
|
|
182
|
+
line1.append("─" * remaining, style="dim")
|
|
181
183
|
else:
|
|
182
|
-
#
|
|
183
|
-
|
|
184
|
+
# No tools - continuous bar
|
|
185
|
+
line1 = Text()
|
|
186
|
+
line1.append("─" * console.console.size.width, style="dim")
|
|
187
|
+
|
|
188
|
+
console.console.print(line1, markup=self._markup)
|
|
184
189
|
console.console.print()
|
|
185
190
|
|
|
186
191
|
async def show_tool_update(self, aggregator: MCPAggregator | None, updated_server: str) -> None:
|
|
@@ -224,6 +229,8 @@ class ConsoleDisplay:
|
|
|
224
229
|
def _format_tool_list(self, available_tools, selected_tool_name):
|
|
225
230
|
"""Format the list of available tools, highlighting the selected one."""
|
|
226
231
|
display_tool_list = Text()
|
|
232
|
+
matching_tools = []
|
|
233
|
+
|
|
227
234
|
for display_tool in available_tools:
|
|
228
235
|
# Handle both OpenAI and Anthropic tool formats
|
|
229
236
|
if isinstance(display_tool, dict):
|
|
@@ -248,9 +255,15 @@ class ConsoleDisplay:
|
|
|
248
255
|
)
|
|
249
256
|
|
|
250
257
|
if selected_tool_name.split(SEP)[0] == parts[0]:
|
|
251
|
-
style = "magenta" if tool_call_name == selected_tool_name else "dim white"
|
|
252
258
|
shortened_name = parts[1] if len(parts[1]) <= 12 else parts[1][:11] + "…"
|
|
253
|
-
|
|
259
|
+
matching_tools.append((shortened_name, tool_call_name))
|
|
260
|
+
|
|
261
|
+
# Format with pipe separators instead of brackets
|
|
262
|
+
for i, (shortened_name, tool_call_name) in enumerate(matching_tools):
|
|
263
|
+
if i > 0:
|
|
264
|
+
display_tool_list.append(" | ", style="dim")
|
|
265
|
+
style = "magenta" if tool_call_name == selected_tool_name else "dim"
|
|
266
|
+
display_tool_list.append(shortened_name, style)
|
|
254
267
|
|
|
255
268
|
return display_tool_list
|
|
256
269
|
|
|
@@ -379,31 +392,83 @@ class ConsoleDisplay:
|
|
|
379
392
|
# Handle Rich Text objects directly
|
|
380
393
|
console.console.print(message_text, markup=self._markup)
|
|
381
394
|
|
|
382
|
-
# Bottom separator with server list
|
|
395
|
+
# Bottom separator with server list and diagrams
|
|
383
396
|
console.console.print()
|
|
397
|
+
|
|
398
|
+
# Check for mermaid diagrams in the message content
|
|
399
|
+
diagrams = []
|
|
400
|
+
if isinstance(message_text, str):
|
|
401
|
+
diagrams = extract_mermaid_diagrams(message_text)
|
|
402
|
+
|
|
403
|
+
# Create server list with pipe separators (no "mcp:" prefix)
|
|
404
|
+
server_content = Text()
|
|
384
405
|
if display_server_list and len(display_server_list) > 0:
|
|
385
|
-
#
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
406
|
+
# Convert the existing server list to pipe-separated format
|
|
407
|
+
servers = []
|
|
408
|
+
if aggregator:
|
|
409
|
+
for server_name in await aggregator.list_servers():
|
|
410
|
+
servers.append(server_name)
|
|
411
|
+
|
|
412
|
+
# Create pipe-separated server list
|
|
413
|
+
for i, server_name in enumerate(servers):
|
|
414
|
+
if i > 0:
|
|
415
|
+
server_content.append(" | ", style="dim")
|
|
416
|
+
# Highlight active server, dim inactive ones
|
|
417
|
+
mcp_server_name = (
|
|
418
|
+
highlight_namespaced_tool.split(SEP)[0]
|
|
419
|
+
if SEP in highlight_namespaced_tool
|
|
420
|
+
else highlight_namespaced_tool
|
|
421
|
+
)
|
|
422
|
+
style = "bright_green" if server_name == mcp_server_name else "dim"
|
|
423
|
+
server_content.append(server_name, style)
|
|
424
|
+
|
|
425
|
+
# Create main separator line
|
|
426
|
+
line1 = Text()
|
|
427
|
+
if server_content.cell_len > 0:
|
|
428
|
+
line1.append("─| ", style="dim")
|
|
429
|
+
line1.append_text(server_content)
|
|
430
|
+
line1.append(" |", style="dim")
|
|
431
|
+
remaining = console.console.size.width - line1.cell_len
|
|
432
|
+
if remaining > 0:
|
|
433
|
+
line1.append("─" * remaining, style="dim")
|
|
434
|
+
else:
|
|
435
|
+
# No servers - continuous bar (no break)
|
|
436
|
+
line1.append("─" * console.console.size.width, style="dim")
|
|
391
437
|
|
|
392
|
-
|
|
393
|
-
total_width = console.console.size.width
|
|
394
|
-
remaining_width = max(0, total_width - server_width - 2) # -2 for "─ " prefix
|
|
395
|
-
right_sep = "─" * remaining_width if remaining_width > 0 else ""
|
|
438
|
+
console.console.print(line1, markup=self._markup)
|
|
396
439
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
440
|
+
# Add diagram links in panel if any diagrams found
|
|
441
|
+
if diagrams:
|
|
442
|
+
diagram_content = Text()
|
|
443
|
+
# Add bullet at the beginning
|
|
444
|
+
diagram_content.append("● ", style="dim")
|
|
445
|
+
|
|
446
|
+
for i, diagram in enumerate(diagrams, 1):
|
|
447
|
+
if i > 1:
|
|
448
|
+
diagram_content.append(" • ", style="dim")
|
|
449
|
+
|
|
450
|
+
# Generate URL
|
|
451
|
+
url = create_mermaid_live_link(diagram.content)
|
|
452
|
+
|
|
453
|
+
# Format: "1 - Title" or "1 - Flowchart" or "Diagram 1"
|
|
454
|
+
if diagram.title:
|
|
455
|
+
diagram_content.append(
|
|
456
|
+
f"{i} - {diagram.title}", style=f"bright_blue link {url}"
|
|
457
|
+
)
|
|
458
|
+
else:
|
|
459
|
+
# Try to detect diagram type, fallback to "Diagram N"
|
|
460
|
+
diagram_type = detect_diagram_type(diagram.content)
|
|
461
|
+
if diagram_type != "Diagram":
|
|
462
|
+
diagram_content.append(
|
|
463
|
+
f"{i} - {diagram_type}", style=f"bright_blue link {url}"
|
|
464
|
+
)
|
|
465
|
+
else:
|
|
466
|
+
diagram_content.append(f"Diagram {i}", style=f"bright_blue link {url}")
|
|
467
|
+
|
|
468
|
+
# Display diagrams on a simple new line (more space efficient)
|
|
469
|
+
console.console.print()
|
|
470
|
+
console.console.print(diagram_content, markup=self._markup)
|
|
402
471
|
|
|
403
|
-
console.console.print(combined, markup=self._markup)
|
|
404
|
-
else:
|
|
405
|
-
# Full separator if no servers
|
|
406
|
-
console.console.print("─" * console.console.size.width, style="dim")
|
|
407
472
|
console.console.print()
|
|
408
473
|
|
|
409
474
|
def show_user_message(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|