fast-agent-mcp 0.2.42__py3-none-any.whl → 0.2.44__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.42.dist-info → fast_agent_mcp-0.2.44.dist-info}/METADATA +3 -2
- {fast_agent_mcp-0.2.42.dist-info → fast_agent_mcp-0.2.44.dist-info}/RECORD +31 -30
- mcp_agent/agents/base_agent.py +60 -22
- mcp_agent/config.py +2 -0
- mcp_agent/core/agent_app.py +15 -5
- mcp_agent/core/enhanced_prompt.py +87 -13
- mcp_agent/core/fastagent.py +9 -1
- mcp_agent/core/interactive_prompt.py +60 -1
- mcp_agent/core/usage_display.py +10 -3
- mcp_agent/llm/augmented_llm.py +4 -5
- mcp_agent/llm/augmented_llm_passthrough.py +15 -0
- mcp_agent/llm/providers/augmented_llm_anthropic.py +4 -3
- mcp_agent/llm/providers/augmented_llm_bedrock.py +3 -3
- mcp_agent/llm/providers/augmented_llm_google_native.py +4 -7
- mcp_agent/llm/providers/augmented_llm_openai.py +5 -8
- mcp_agent/llm/providers/augmented_llm_tensorzero.py +6 -7
- mcp_agent/llm/providers/google_converter.py +6 -9
- mcp_agent/llm/providers/multipart_converter_anthropic.py +5 -4
- mcp_agent/llm/providers/multipart_converter_openai.py +33 -0
- mcp_agent/llm/providers/multipart_converter_tensorzero.py +3 -2
- mcp_agent/logging/rich_progress.py +6 -2
- mcp_agent/logging/transport.py +30 -36
- mcp_agent/mcp/helpers/content_helpers.py +26 -11
- mcp_agent/mcp/interfaces.py +22 -2
- mcp_agent/mcp/mcp_aggregator.py +22 -3
- mcp_agent/mcp/prompt_message_multipart.py +2 -3
- mcp_agent/ui/console_display.py +353 -142
- mcp_agent/ui/console_display_legacy.py +401 -0
- {fast_agent_mcp-0.2.42.dist-info → fast_agent_mcp-0.2.44.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.2.42.dist-info → fast_agent_mcp-0.2.44.dist-info}/entry_points.txt +0 -0
- {fast_agent_mcp-0.2.42.dist-info → fast_agent_mcp-0.2.44.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fast-agent-mcp
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.44
|
|
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
|
|
@@ -218,7 +218,7 @@ Requires-Dist: deprecated>=1.2.18
|
|
|
218
218
|
Requires-Dist: email-validator>=2.2.0
|
|
219
219
|
Requires-Dist: fastapi>=0.115.6
|
|
220
220
|
Requires-Dist: google-genai
|
|
221
|
-
Requires-Dist: mcp==1.
|
|
221
|
+
Requires-Dist: mcp==1.12.0
|
|
222
222
|
Requires-Dist: openai>=1.93.0
|
|
223
223
|
Requires-Dist: opentelemetry-distro>=0.50b0
|
|
224
224
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.29.0
|
|
@@ -229,6 +229,7 @@ Requires-Dist: opentelemetry-instrumentation-openai>=0.40.14; python_version >=
|
|
|
229
229
|
Requires-Dist: prompt-toolkit>=3.0.50
|
|
230
230
|
Requires-Dist: pydantic-settings>=2.7.0
|
|
231
231
|
Requires-Dist: pydantic>=2.10.4
|
|
232
|
+
Requires-Dist: pyperclip>=1.9.0
|
|
232
233
|
Requires-Dist: pyyaml>=6.0.2
|
|
233
234
|
Requires-Dist: rich>=13.9.4
|
|
234
235
|
Requires-Dist: tensorzero>=2025.6.3
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
mcp_agent/__init__.py,sha256=18T0AG0W9sJhTY38O9GFFOzliDhxx9p87CvRyti9zbw,1620
|
|
2
2
|
mcp_agent/app.py,sha256=3mtHP1nRQcRaKhhxgTmCOv00alh70nT7UxNA8bN47QE,5560
|
|
3
|
-
mcp_agent/config.py,sha256=
|
|
3
|
+
mcp_agent/config.py,sha256=RjwgvR-Sys4JIzhNyEsaS_NarCe157RenJLOsioUtDk,18980
|
|
4
4
|
mcp_agent/console.py,sha256=Gjf2QLFumwG1Lav__c07X_kZxxEUSkzV-1_-YbAwcwo,813
|
|
5
5
|
mcp_agent/context.py,sha256=9s1F1-UfcI8rz9Yxm6EXHZ4cInuE_cOl_HFu8N8k3yc,7497
|
|
6
6
|
mcp_agent/context_dependent.py,sha256=QXfhw3RaQCKfscEEBRGuZ3sdMWqkgShz2jJ1ivGGX1I,1455
|
|
@@ -9,7 +9,7 @@ mcp_agent/mcp_server_registry.py,sha256=lmz-aES-l7Gbg4itDF0iCmpso_KD8bVazVKSVzjw
|
|
|
9
9
|
mcp_agent/progress_display.py,sha256=GeJU9VUt6qKsFVymG688hCMVCsAygG9ifiiEb5IcbN4,361
|
|
10
10
|
mcp_agent/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
mcp_agent/agents/agent.py,sha256=EAYlcP1qqI1D0_CS808I806z1048FBjZQxxpcCZPeIU,3154
|
|
12
|
-
mcp_agent/agents/base_agent.py,sha256=
|
|
12
|
+
mcp_agent/agents/base_agent.py,sha256=VCBWJ-l1zMQiBuONGzqcbqPUQfXK4oq-pBB5lJrMgQ0,32318
|
|
13
13
|
mcp_agent/agents/workflow/__init__.py,sha256=HloteEW6kalvgR0XewpiFAqaQlMPlPJYg5p3K33IUzI,25
|
|
14
14
|
mcp_agent/agents/workflow/chain_agent.py,sha256=eIlImirrSXkqBJmPuAJgOKis81Cl6lZEGM0-6IyaUV8,6105
|
|
15
15
|
mcp_agent/agents/workflow/evaluator_optimizer.py,sha256=ysUMGM2NzeCIutgr_vXH6kUPpZMw0cX4J_Wl1r8eT84,13296
|
|
@@ -30,19 +30,19 @@ mcp_agent/cli/commands/server_helpers.py,sha256=x5tD_qhf1W4D2li09sfOyfRWCOCa6lmp
|
|
|
30
30
|
mcp_agent/cli/commands/setup.py,sha256=eOEd4TL-b0DaDeSJMGOfNOsTEItoZ67W88eTP4aP-bo,6482
|
|
31
31
|
mcp_agent/cli/commands/url_parser.py,sha256=5VdtcHRHzi67YignStVbz7u-rcvNNErw9oJLAUFOtEY,5855
|
|
32
32
|
mcp_agent/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
|
-
mcp_agent/core/agent_app.py,sha256=
|
|
33
|
+
mcp_agent/core/agent_app.py,sha256=SolGwejEmv9XtsTsmiMkNKPia7RN1VcHXm6JoEo4hvQ,16187
|
|
34
34
|
mcp_agent/core/agent_types.py,sha256=7zVzAFWjvh5dDV3TuDwmO9LAWmDjYnZd3eeLH-wvvIQ,1705
|
|
35
35
|
mcp_agent/core/direct_decorators.py,sha256=sYoEA1EmdyAxTpQwUDUjQYWY73VviM-fBnV1Zv7KfeU,19047
|
|
36
36
|
mcp_agent/core/direct_factory.py,sha256=d_HvbAxyv2WrM07zyCpLXFVn7eArXk1LZmLKS49hzJo,19537
|
|
37
|
-
mcp_agent/core/enhanced_prompt.py,sha256=
|
|
37
|
+
mcp_agent/core/enhanced_prompt.py,sha256=e3FA0_70kw4HRxXCYQs5sO0qzvsM47pc6UG186okXtk,36324
|
|
38
38
|
mcp_agent/core/error_handling.py,sha256=xoyS2kLe0eG0bj2eSJCJ2odIhGUve2SbDR7jP-A-uRw,624
|
|
39
39
|
mcp_agent/core/exceptions.py,sha256=ENAD_qGG67foxy6vDkIvc-lgopIUQy6O7zvNPpPXaQg,2289
|
|
40
|
-
mcp_agent/core/fastagent.py,sha256=
|
|
41
|
-
mcp_agent/core/interactive_prompt.py,sha256=
|
|
40
|
+
mcp_agent/core/fastagent.py,sha256=qA64fwmJ6TVFEvmj6l-oTWPD28Js5zJvdDnPjH-agzQ,25117
|
|
41
|
+
mcp_agent/core/interactive_prompt.py,sha256=Gpwn7v7m3nw7fR_W7bs5XYArrny_xJK06DOURUwpzI4,32756
|
|
42
42
|
mcp_agent/core/mcp_content.py,sha256=2D7KHY9mG_vxoDwFLKvsPQV9VRIzHItM7V-jcEnACh8,8878
|
|
43
43
|
mcp_agent/core/prompt.py,sha256=qnintOUGEoDPYLI9bu9G2OlgVMCe5ZPUZilgMzydXhc,7919
|
|
44
44
|
mcp_agent/core/request_params.py,sha256=qmFWZXeYEJyYw2IwonyrTnZWxQG7qX6bKpOPcqETa60,1603
|
|
45
|
-
mcp_agent/core/usage_display.py,sha256=
|
|
45
|
+
mcp_agent/core/usage_display.py,sha256=CcCQbTm5ftMgkoBgr5NWzHmYFBK5cSU-FM8yiBOVzGA,7527
|
|
46
46
|
mcp_agent/core/validation.py,sha256=8D6d3mQanvzC2dXx5yc8-5bkoWEh9cxuT6-YSthSGFk,12676
|
|
47
47
|
mcp_agent/executor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
48
|
mcp_agent/executor/executor.py,sha256=E44p6d-o3OMRoP_dNs_cDnyti91LQ3P9eNU88mSi1kc,9462
|
|
@@ -56,8 +56,8 @@ mcp_agent/human_input/elicitation_state.py,sha256=Unl9uhEybUqACCUimnETdfUprJNpYD
|
|
|
56
56
|
mcp_agent/human_input/handler.py,sha256=s712Z5ssTCwjL9-VKoIdP5CtgMh43YvepynYisiWTTA,3144
|
|
57
57
|
mcp_agent/human_input/types.py,sha256=RtWBOVzy8vnYoQrc36jRLn8z8N3C4pDPMBN5vF6qM5Y,1476
|
|
58
58
|
mcp_agent/llm/__init__.py,sha256=d8zgwG-bRFuwiMNMYkywg_qytk4P8lawyld_meuUmHI,68
|
|
59
|
-
mcp_agent/llm/augmented_llm.py,sha256=
|
|
60
|
-
mcp_agent/llm/augmented_llm_passthrough.py,sha256
|
|
59
|
+
mcp_agent/llm/augmented_llm.py,sha256=FwH3nFwtqX9JJiwsHWvBCwDRooAMUhVM258-rUMheRI,27568
|
|
60
|
+
mcp_agent/llm/augmented_llm_passthrough.py,sha256=-Pu_cW5p7gKyc6E7OT7lG642RyAFkv-uj6U-JwKpOPE,9421
|
|
61
61
|
mcp_agent/llm/augmented_llm_playback.py,sha256=BQeBXRpO-xGAY9wIJxyde6xpHmZEdQPLd32frF8t3QQ,4916
|
|
62
62
|
mcp_agent/llm/augmented_llm_silent.py,sha256=IUnK_1Byy4D9TG0Pj46LFeNezgSTQ8d6MQIHWAImBwE,1846
|
|
63
63
|
mcp_agent/llm/augmented_llm_slow.py,sha256=DDSD8bL2flmQrVHZm-UDs7sR8aHRWkDOcOW-mX_GPok,2067
|
|
@@ -73,21 +73,21 @@ mcp_agent/llm/usage_tracking.py,sha256=rF6v8QQDam8QbvlP4jzHljKqvuNHExeYDLkUMI86c
|
|
|
73
73
|
mcp_agent/llm/providers/__init__.py,sha256=heVxtmuqFJOnjjxHz4bWSqTAxXoN1E8twC_gQ_yJpHk,265
|
|
74
74
|
mcp_agent/llm/providers/anthropic_utils.py,sha256=vYDN5G5jKMhD2CQg8veJYab7tvvzYkDMq8M1g_hUAQg,3275
|
|
75
75
|
mcp_agent/llm/providers/augmented_llm_aliyun.py,sha256=XylkJKZ9theSVUxJKOZkf1244hgzng4Ng4Dr209Qb-w,1101
|
|
76
|
-
mcp_agent/llm/providers/augmented_llm_anthropic.py,sha256=
|
|
76
|
+
mcp_agent/llm/providers/augmented_llm_anthropic.py,sha256=kmzJ_45eMerUkGZ7Mzy544SLpxcUbfOnAr0h_mHktcs,23980
|
|
77
77
|
mcp_agent/llm/providers/augmented_llm_azure.py,sha256=sBVWgY88F4OsdRSHl71BAT2p3XPvuZp844z1ubwcV7U,6098
|
|
78
|
-
mcp_agent/llm/providers/augmented_llm_bedrock.py,sha256=
|
|
78
|
+
mcp_agent/llm/providers/augmented_llm_bedrock.py,sha256=nfby1udL07zPTOLlN_tFxd1h0JRioo2oIW7v4iP4Bnk,82267
|
|
79
79
|
mcp_agent/llm/providers/augmented_llm_deepseek.py,sha256=zI9a90dwT4r6E1f_xp4K50Cj9sD7y7kNRgjo0s1pd5w,3804
|
|
80
80
|
mcp_agent/llm/providers/augmented_llm_generic.py,sha256=5Uq8ZBhcFuQTt7koP_5ykolREh2iWu8zKhNbh3pM9lQ,1210
|
|
81
|
-
mcp_agent/llm/providers/augmented_llm_google_native.py,sha256=
|
|
81
|
+
mcp_agent/llm/providers/augmented_llm_google_native.py,sha256=c6zczfs-Iw70j3OYELHJ4S7CRwAddkeXinex_yLMhmU,22194
|
|
82
82
|
mcp_agent/llm/providers/augmented_llm_google_oai.py,sha256=cO4dvjTl9ymqEurCOo5nP09ATfXVjgkuk1yZAlWpS1s,1137
|
|
83
|
-
mcp_agent/llm/providers/augmented_llm_openai.py,sha256=
|
|
83
|
+
mcp_agent/llm/providers/augmented_llm_openai.py,sha256=cxctddW9a-5Kv3yGSMBudQh_L7pc9yV5fEOhT7J8ho0,24169
|
|
84
84
|
mcp_agent/llm/providers/augmented_llm_openrouter.py,sha256=V_TlVKm92GHBxYIo6gpvH_6cAaIdppS25Tz6x5T7LW0,2341
|
|
85
|
-
mcp_agent/llm/providers/augmented_llm_tensorzero.py,sha256=
|
|
85
|
+
mcp_agent/llm/providers/augmented_llm_tensorzero.py,sha256=z4PtjW_TS6xBVQl-0nRqegvRdVZFQiRMfWYBSMEWkdY,20577
|
|
86
86
|
mcp_agent/llm/providers/augmented_llm_xai.py,sha256=fJiO9Vkgi32pEMijxMbqoKrPCCNJmR_3YEnX0UCqOVs,1332
|
|
87
|
-
mcp_agent/llm/providers/google_converter.py,sha256=
|
|
88
|
-
mcp_agent/llm/providers/multipart_converter_anthropic.py,sha256=
|
|
89
|
-
mcp_agent/llm/providers/multipart_converter_openai.py,sha256=
|
|
90
|
-
mcp_agent/llm/providers/multipart_converter_tensorzero.py,sha256=
|
|
87
|
+
mcp_agent/llm/providers/google_converter.py,sha256=xCUVw4W7lqBvJMgSKKdzW4Y00zmHBgCR6pOoWLYQQfw,16699
|
|
88
|
+
mcp_agent/llm/providers/multipart_converter_anthropic.py,sha256=QsgIwWJ14SNZsun3fKDQaUx5AYdk8X6UYeBgYlZgZN0,16607
|
|
89
|
+
mcp_agent/llm/providers/multipart_converter_openai.py,sha256=1zHlkMKY-16RL8qnrx7kI53IHmCiqASNvYsAdofSq_I,17000
|
|
90
|
+
mcp_agent/llm/providers/multipart_converter_tensorzero.py,sha256=Tr3DgogthxqTw04ajblwE8aB3Ft42X7aSXsMlm5FP4k,8619
|
|
91
91
|
mcp_agent/llm/providers/openai_multipart.py,sha256=qKBn7d3jSabnJmVgWweVzqh8q9mBqr09fsPmP92niAQ,6899
|
|
92
92
|
mcp_agent/llm/providers/openai_utils.py,sha256=T4bTCL9f7DsoS_zoKgQKv_FUv_4n98vgbvaUpdWZJr8,1875
|
|
93
93
|
mcp_agent/llm/providers/sampling_converter_anthropic.py,sha256=35WzBWkPklnuMlu5S6XsQIq0YL58NOy8Ja6A_l4m6eM,1612
|
|
@@ -97,27 +97,27 @@ mcp_agent/logging/events.py,sha256=dSJJfuCd59-ZyYTVcf0M4HQd6iXb5k50PSAeoq1CpH0,4
|
|
|
97
97
|
mcp_agent/logging/json_serializer.py,sha256=qkfxnR9ka6OgvwSpM2CggELbEtzzkApm0s_KYz11RDY,5791
|
|
98
98
|
mcp_agent/logging/listeners.py,sha256=_S4Jp5_KWp0kUfrx4BxDdNCeQK3MNT3Zi9AaolPri7A,6648
|
|
99
99
|
mcp_agent/logging/logger.py,sha256=v2_D5kWLSS9u4ueSU7q6cWF1oSmTVeAAtgnwR0LrbXI,11056
|
|
100
|
-
mcp_agent/logging/rich_progress.py,sha256=
|
|
101
|
-
mcp_agent/logging/transport.py,sha256=
|
|
100
|
+
mcp_agent/logging/rich_progress.py,sha256=uMAKDPO8TlhT7uTeJzOEwQPme8pu8qCADLNbsI1vV8g,5544
|
|
101
|
+
mcp_agent/logging/transport.py,sha256=_RVckOdcs_mXv6Jwz-MPe0vVTQEKsbejHdteyK5hBQA,16960
|
|
102
102
|
mcp_agent/mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
103
103
|
mcp_agent/mcp/common.py,sha256=MpSC0fLO21RcDz4VApah4C8_LisVGz7OXkR17Xw-9mY,431
|
|
104
104
|
mcp_agent/mcp/elicitation_factory.py,sha256=gY0gEsF8Jdg01nSsrVbbl62ZS1A725QgDRB6UDPCadc,3162
|
|
105
105
|
mcp_agent/mcp/elicitation_handlers.py,sha256=w2S4kBn05pIKdq2-X13MErinFg5jSElwFsoTuW3zFSs,6618
|
|
106
106
|
mcp_agent/mcp/gen_client.py,sha256=fAVwFVCgSamw4PwoWOV4wrK9TABx1S_zZv8BctRyF2k,3030
|
|
107
107
|
mcp_agent/mcp/hf_auth.py,sha256=7szw4rkwRyK3J-sUTcVZHdwoLIZqlYo8XolJnZdjOww,4571
|
|
108
|
-
mcp_agent/mcp/interfaces.py,sha256=
|
|
108
|
+
mcp_agent/mcp/interfaces.py,sha256=Zrb-O-TuExlWJxuP0bIN8ZV0UpIoz5Rw7x1Lj-BsbHc,7717
|
|
109
109
|
mcp_agent/mcp/logger_textio.py,sha256=vljC1BtNTCxBAda9ExqNB-FwVNUZIuJT3h1nWmCjMws,3172
|
|
110
110
|
mcp_agent/mcp/mcp_agent_client_session.py,sha256=nEHrSalG5z47BKGwE9ooOmlSTc4Gb7qdEut071Dwepo,8987
|
|
111
|
-
mcp_agent/mcp/mcp_aggregator.py,sha256=
|
|
111
|
+
mcp_agent/mcp/mcp_aggregator.py,sha256=D1xFBVVq_4Tn1Ka16SZTVB3qeU-FO5501ITHGXTuXs0,49730
|
|
112
112
|
mcp_agent/mcp/mcp_connection_manager.py,sha256=dJxjnv2IRzlFIxrbPFl39-pmGcZHgyeMXVlMfqpREhE,17974
|
|
113
113
|
mcp_agent/mcp/mime_utils.py,sha256=difepNR_gpb4MpMLkBRAoyhDk-AjXUHTiqKvT_VwS1o,1805
|
|
114
|
-
mcp_agent/mcp/prompt_message_multipart.py,sha256=
|
|
114
|
+
mcp_agent/mcp/prompt_message_multipart.py,sha256=XDlFODtOIepespQ23hvh37i3GF2L9Hju4AdNHijwe9k,4350
|
|
115
115
|
mcp_agent/mcp/prompt_render.py,sha256=k3v4BZDThGE2gGiOYVQtA6x8WTEdOuXIEnRafANhN1U,2996
|
|
116
116
|
mcp_agent/mcp/prompt_serialization.py,sha256=MQY6QxnhQTiq0oBDsyRzFtX8sBiovUjzUFX78As8q60,17974
|
|
117
117
|
mcp_agent/mcp/resource_utils.py,sha256=K4XY8bihmBMleRTZ2viMPiD2Y2HWxFnlgIJi6dd_PYE,6588
|
|
118
118
|
mcp_agent/mcp/sampling.py,sha256=PpUtLDvu9K3U8445z6m_esHeKstdSr-JBTyn9d8ppJM,6665
|
|
119
119
|
mcp_agent/mcp/helpers/__init__.py,sha256=sKqwlUR3jSsd9PVJKjXtxHgZA1YOdzPtsSW4xVey77Q,52
|
|
120
|
-
mcp_agent/mcp/helpers/content_helpers.py,sha256=
|
|
120
|
+
mcp_agent/mcp/helpers/content_helpers.py,sha256=_P5xfVpJg4F7lBM-v6-1Bjtvfgr9UfTQoW2FSxyxil4,4112
|
|
121
121
|
mcp_agent/mcp/helpers/server_config_helpers.py,sha256=MkyZB2ZzfsBNsqyGd0LfUOoXxhAMS28VF-f747cJJpY,978
|
|
122
122
|
mcp_agent/mcp/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
123
123
|
mcp_agent/mcp/prompts/__main__.py,sha256=gr1Tdz9fcK0EXjEuZg_BOnKUmvhYq5AH2lFZicVyNb0,237
|
|
@@ -160,9 +160,10 @@ mcp_agent/resources/examples/workflows/router.py,sha256=56FX7JhZ6ERafWGoVhspoalT
|
|
|
160
160
|
mcp_agent/resources/examples/workflows/short_story.md,sha256=XN9I2kzCcMmke3dE5F2lyRH5iFUZUQ8Sy-hS3rm_Wlc,1153
|
|
161
161
|
mcp_agent/resources/examples/workflows/short_story.txt,sha256=X3y_1AyhLFN2AKzCKvucJtDgAFIJfnlbsbGZO5bBWu0,1187
|
|
162
162
|
mcp_agent/tools/tool_definition.py,sha256=L3Pxl-uLEXqlVoo-bYuFTFALeI-2pIU44YgFhsTKEtM,398
|
|
163
|
-
mcp_agent/ui/console_display.py,sha256=
|
|
164
|
-
|
|
165
|
-
fast_agent_mcp-0.2.
|
|
166
|
-
fast_agent_mcp-0.2.
|
|
167
|
-
fast_agent_mcp-0.2.
|
|
168
|
-
fast_agent_mcp-0.2.
|
|
163
|
+
mcp_agent/ui/console_display.py,sha256=2G8hv4Ig70IHCHvw7FK-ksDcp9UHqbUYU-Y64_j0Nuk,25826
|
|
164
|
+
mcp_agent/ui/console_display_legacy.py,sha256=sm2v61-IPVafbF7uUaOyhO2tW_zgFWOjNS83IEWqGgI,14931
|
|
165
|
+
fast_agent_mcp-0.2.44.dist-info/METADATA,sha256=lvZvAbFvs2tbNpHi35Cbh_PgeyNtWFTnI8Fa8RHpXyQ,31044
|
|
166
|
+
fast_agent_mcp-0.2.44.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
167
|
+
fast_agent_mcp-0.2.44.dist-info/entry_points.txt,sha256=QaX5kLdI0VdMPRdPUF1nkG_WdLUTNjp_icW6e3EhNYU,232
|
|
168
|
+
fast_agent_mcp-0.2.44.dist-info/licenses/LICENSE,sha256=Gx1L3axA4PnuK4FxsbX87jQ1opoOkSFfHHSytW6wLUU,10935
|
|
169
|
+
fast_agent_mcp-0.2.44.dist-info/RECORD,,
|
mcp_agent/agents/base_agent.py
CHANGED
|
@@ -330,12 +330,12 @@ class BaseAgent(MCPAggregator, AgentProtocol):
|
|
|
330
330
|
def _matches_pattern(self, name: str, pattern: str, server_name: str) -> bool:
|
|
331
331
|
"""
|
|
332
332
|
Check if a name matches a pattern for a specific server.
|
|
333
|
-
|
|
333
|
+
|
|
334
334
|
Args:
|
|
335
335
|
name: The name to match (could be tool name, resource URI, or prompt name)
|
|
336
336
|
pattern: The pattern to match against (e.g., "add", "math*", "resource://math/*")
|
|
337
337
|
server_name: The server name (used for tool name prefixing)
|
|
338
|
-
|
|
338
|
+
|
|
339
339
|
Returns:
|
|
340
340
|
True if the name matches the pattern
|
|
341
341
|
"""
|
|
@@ -343,7 +343,7 @@ class BaseAgent(MCPAggregator, AgentProtocol):
|
|
|
343
343
|
if name.startswith(f"{server_name}-"):
|
|
344
344
|
full_pattern = f"{server_name}-{pattern}"
|
|
345
345
|
return fnmatch.fnmatch(name, full_pattern)
|
|
346
|
-
|
|
346
|
+
|
|
347
347
|
# For resources and prompts, match directly against the pattern
|
|
348
348
|
return fnmatch.fnmatch(name, pattern)
|
|
349
349
|
|
|
@@ -365,9 +365,9 @@ class BaseAgent(MCPAggregator, AgentProtocol):
|
|
|
365
365
|
filtered_tools = []
|
|
366
366
|
for tool in result.tools:
|
|
367
367
|
# Extract server name from tool name (e.g., "mathematics-add" -> "mathematics")
|
|
368
|
-
if
|
|
369
|
-
server_name = tool.name.split(
|
|
370
|
-
|
|
368
|
+
if "-" in tool.name:
|
|
369
|
+
server_name = tool.name.split("-", 1)[0]
|
|
370
|
+
|
|
371
371
|
# Check if this server has tool filters
|
|
372
372
|
if server_name in self.config.tools:
|
|
373
373
|
# Check if tool matches any pattern for this server
|
|
@@ -495,48 +495,70 @@ class BaseAgent(MCPAggregator, AgentProtocol):
|
|
|
495
495
|
|
|
496
496
|
async def apply_prompt(
|
|
497
497
|
self,
|
|
498
|
-
|
|
498
|
+
prompt: Union[str, GetPromptResult],
|
|
499
499
|
arguments: Dict[str, str] | None = None,
|
|
500
500
|
agent_name: str | None = None,
|
|
501
501
|
server_name: str | None = None,
|
|
502
|
+
as_template: bool = False,
|
|
502
503
|
) -> str:
|
|
503
504
|
"""
|
|
504
|
-
Apply an MCP Server Prompt by name and return the assistant's response.
|
|
505
|
+
Apply an MCP Server Prompt by name or GetPromptResult and return the assistant's response.
|
|
505
506
|
Will search all available servers for the prompt if not namespaced and no server_name provided.
|
|
506
507
|
|
|
507
508
|
If the last message in the prompt is from a user, this will automatically
|
|
508
509
|
generate an assistant response to ensure we always end with an assistant message.
|
|
509
510
|
|
|
510
511
|
Args:
|
|
511
|
-
|
|
512
|
+
prompt: The name of the prompt to apply OR a GetPromptResult object
|
|
512
513
|
arguments: Optional dictionary of string arguments to pass to the prompt template
|
|
513
514
|
agent_name: Optional agent name (ignored at this level, used by multi-agent apps)
|
|
514
515
|
server_name: Optional name of the server to get the prompt from
|
|
516
|
+
as_template: If True, store as persistent template (always included in context)
|
|
515
517
|
|
|
516
518
|
Returns:
|
|
517
519
|
The assistant's response or error message
|
|
518
520
|
"""
|
|
519
521
|
|
|
520
|
-
#
|
|
521
|
-
|
|
522
|
-
|
|
522
|
+
# Handle both string and GetPromptResult inputs
|
|
523
|
+
if isinstance(prompt, str):
|
|
524
|
+
prompt_name = prompt
|
|
525
|
+
# Get the prompt - this will search all servers if needed
|
|
526
|
+
self.logger.debug(f"Loading prompt '{prompt_name}'")
|
|
527
|
+
prompt_result: GetPromptResult = await self.get_prompt(
|
|
528
|
+
prompt_name, arguments, server_name
|
|
529
|
+
)
|
|
530
|
+
|
|
531
|
+
if not prompt_result or not prompt_result.messages:
|
|
532
|
+
error_msg = f"Prompt '{prompt_name}' could not be found or contains no messages"
|
|
533
|
+
self.logger.warning(error_msg)
|
|
534
|
+
return error_msg
|
|
523
535
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
536
|
+
# Get the display name (namespaced version)
|
|
537
|
+
namespaced_name = getattr(prompt_result, "namespaced_name", prompt_name)
|
|
538
|
+
else:
|
|
539
|
+
# prompt is a GetPromptResult object
|
|
540
|
+
prompt_result = prompt
|
|
541
|
+
if not prompt_result or not prompt_result.messages:
|
|
542
|
+
error_msg = "Provided GetPromptResult contains no messages"
|
|
543
|
+
self.logger.warning(error_msg)
|
|
544
|
+
return error_msg
|
|
545
|
+
|
|
546
|
+
# Use a reasonable display name
|
|
547
|
+
namespaced_name = getattr(prompt_result, "namespaced_name", "provided_prompt")
|
|
528
548
|
|
|
529
|
-
# Get the display name (namespaced version)
|
|
530
|
-
namespaced_name = getattr(prompt_result, "namespaced_name", prompt_name)
|
|
531
549
|
self.logger.debug(f"Using prompt '{namespaced_name}'")
|
|
532
550
|
|
|
533
551
|
# Convert prompt messages to multipart format using the safer method
|
|
534
552
|
multipart_messages = PromptMessageMultipart.from_get_prompt_result(prompt_result)
|
|
535
553
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
554
|
+
if as_template:
|
|
555
|
+
# Use apply_prompt_template to store as persistent prompt messages
|
|
556
|
+
return await self.apply_prompt_template(prompt_result, namespaced_name)
|
|
557
|
+
else:
|
|
558
|
+
# Always call generate to ensure LLM implementations can handle prompt templates
|
|
559
|
+
# This is critical for stateful LLMs like PlaybackLLM
|
|
560
|
+
response = await self.generate(multipart_messages, None)
|
|
561
|
+
return response.first_text()
|
|
540
562
|
|
|
541
563
|
async def get_embedded_resources(
|
|
542
564
|
self, resource_uri: str, server_name: str | None = None
|
|
@@ -636,6 +658,22 @@ class BaseAgent(MCPAggregator, AgentProtocol):
|
|
|
636
658
|
with self.tracer.start_as_current_span(f"Agent: '{self.name}' generate"):
|
|
637
659
|
return await self._llm.generate(multipart_messages, request_params)
|
|
638
660
|
|
|
661
|
+
async def apply_prompt_template(self, prompt_result: GetPromptResult, prompt_name: str) -> str:
|
|
662
|
+
"""
|
|
663
|
+
Apply a prompt template as persistent context that will be included in all future conversations.
|
|
664
|
+
Delegates to the attached LLM.
|
|
665
|
+
|
|
666
|
+
Args:
|
|
667
|
+
prompt_result: The GetPromptResult containing prompt messages
|
|
668
|
+
prompt_name: The name of the prompt being applied
|
|
669
|
+
|
|
670
|
+
Returns:
|
|
671
|
+
String representation of the assistant's response if generated
|
|
672
|
+
"""
|
|
673
|
+
assert self._llm
|
|
674
|
+
with self.tracer.start_as_current_span(f"Agent: '{self.name}' apply_prompt_template"):
|
|
675
|
+
return await self._llm.apply_prompt_template(prompt_result, prompt_name)
|
|
676
|
+
|
|
639
677
|
async def structured(
|
|
640
678
|
self,
|
|
641
679
|
multipart_messages: List[PromptMessageMultipart],
|
mcp_agent/config.py
CHANGED
|
@@ -319,6 +319,8 @@ class LoggerSettings(BaseModel):
|
|
|
319
319
|
"""Truncate display of long tool calls"""
|
|
320
320
|
enable_markup: bool = True
|
|
321
321
|
"""Enable markup in console output. Disable for outputs that may conflict with rich console formatting"""
|
|
322
|
+
use_legacy_display: bool = False
|
|
323
|
+
"""Use the legacy console display instead of the new style display"""
|
|
322
324
|
|
|
323
325
|
|
|
324
326
|
def find_fastagent_config_files(start_path: Path) -> Tuple[Optional[Path], Optional[Path]]:
|
mcp_agent/core/agent_app.py
CHANGED
|
@@ -5,7 +5,7 @@ Direct AgentApp implementation for interacting with agents without proxies.
|
|
|
5
5
|
from typing import Dict, List, Optional, Union
|
|
6
6
|
|
|
7
7
|
from deprecated import deprecated
|
|
8
|
-
from mcp.types import PromptMessage
|
|
8
|
+
from mcp.types import GetPromptResult, PromptMessage
|
|
9
9
|
from rich import print as rich_print
|
|
10
10
|
|
|
11
11
|
from mcp_agent.agents.agent import Agent
|
|
@@ -108,22 +108,26 @@ class AgentApp:
|
|
|
108
108
|
|
|
109
109
|
async def apply_prompt(
|
|
110
110
|
self,
|
|
111
|
-
|
|
111
|
+
prompt: Union[str, GetPromptResult],
|
|
112
112
|
arguments: Dict[str, str] | None = None,
|
|
113
113
|
agent_name: str | None = None,
|
|
114
|
+
as_template: bool = False,
|
|
114
115
|
) -> str:
|
|
115
116
|
"""
|
|
116
117
|
Apply a prompt template to an agent (default agent if not specified).
|
|
117
118
|
|
|
118
119
|
Args:
|
|
119
|
-
|
|
120
|
+
prompt: Name of the prompt template to apply OR a GetPromptResult object
|
|
120
121
|
arguments: Optional arguments for the prompt template
|
|
121
122
|
agent_name: Name of the agent to send to
|
|
123
|
+
as_template: If True, store as persistent template (always included in context)
|
|
122
124
|
|
|
123
125
|
Returns:
|
|
124
126
|
The agent's response as a string
|
|
125
127
|
"""
|
|
126
|
-
return await self._agent(agent_name).apply_prompt(
|
|
128
|
+
return await self._agent(agent_name).apply_prompt(
|
|
129
|
+
prompt, arguments, as_template=as_template
|
|
130
|
+
)
|
|
127
131
|
|
|
128
132
|
async def list_prompts(self, server_name: str | None = None, agent_name: str | None = None):
|
|
129
133
|
"""
|
|
@@ -235,7 +239,12 @@ class AgentApp:
|
|
|
235
239
|
"""
|
|
236
240
|
return await self.interactive(agent_name=agent_name, default_prompt=default_prompt)
|
|
237
241
|
|
|
238
|
-
async def interactive(
|
|
242
|
+
async def interactive(
|
|
243
|
+
self,
|
|
244
|
+
agent_name: str | None = None,
|
|
245
|
+
default_prompt: str = "",
|
|
246
|
+
pretty_print_parallel: bool = False,
|
|
247
|
+
) -> str:
|
|
239
248
|
"""
|
|
240
249
|
Interactive prompt for sending messages with advanced features.
|
|
241
250
|
|
|
@@ -283,6 +292,7 @@ class AgentApp:
|
|
|
283
292
|
agent = self._agents.get(agent_name)
|
|
284
293
|
if agent and agent.agent_type == AgentType.PARALLEL:
|
|
285
294
|
from mcp_agent.ui.console_display import ConsoleDisplay
|
|
295
|
+
|
|
286
296
|
display = ConsoleDisplay(config=None)
|
|
287
297
|
display.show_parallel_results(agent)
|
|
288
298
|
|
|
@@ -69,7 +69,9 @@ async def _display_agent_info_helper(agent_name: str, agent_provider: object) ->
|
|
|
69
69
|
)
|
|
70
70
|
|
|
71
71
|
resources_dict = await agent.list_resources()
|
|
72
|
-
resource_count =
|
|
72
|
+
resource_count = (
|
|
73
|
+
sum(len(resources) for resources in resources_dict.values()) if resources_dict else 0
|
|
74
|
+
)
|
|
73
75
|
|
|
74
76
|
prompts_dict = await agent.list_prompts()
|
|
75
77
|
prompt_count = sum(len(prompts) for prompts in prompts_dict.values()) if prompts_dict else 0
|
|
@@ -104,15 +106,35 @@ async def _display_agent_info_helper(agent_name: str, agent_provider: object) ->
|
|
|
104
106
|
else:
|
|
105
107
|
# For regular agents, only display if they have MCP servers attached
|
|
106
108
|
if server_count > 0:
|
|
107
|
-
#
|
|
109
|
+
# Build display parts in order: tools, prompts, resources (omit if count is 0)
|
|
110
|
+
display_parts = []
|
|
111
|
+
|
|
112
|
+
if tool_count > 0:
|
|
113
|
+
tool_word = "tool" if tool_count == 1 else "tools"
|
|
114
|
+
display_parts.append(f"{tool_count:,}[dim] {tool_word}[/dim]")
|
|
115
|
+
|
|
116
|
+
if prompt_count > 0:
|
|
117
|
+
prompt_word = "prompt" if prompt_count == 1 else "prompts"
|
|
118
|
+
display_parts.append(f"{prompt_count:,}[dim] {prompt_word}[/dim]")
|
|
119
|
+
|
|
120
|
+
if resource_count > 0:
|
|
121
|
+
resource_word = "resource" if resource_count == 1 else "resources"
|
|
122
|
+
display_parts.append(f"{resource_count:,}[dim] {resource_word}[/dim]")
|
|
123
|
+
|
|
124
|
+
# Always show server count
|
|
108
125
|
server_word = "Server" if server_count == 1 else "Servers"
|
|
109
|
-
|
|
110
|
-
resource_word = "resource" if resource_count == 1 else "resources"
|
|
111
|
-
prompt_word = "prompt" if prompt_count == 1 else "prompts"
|
|
126
|
+
server_text = f"{server_count:,}[dim] MCP {server_word}[/dim]"
|
|
112
127
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
128
|
+
if display_parts:
|
|
129
|
+
content = (
|
|
130
|
+
f"{server_text}[dim], [/dim]"
|
|
131
|
+
+ "[dim], [/dim]".join(display_parts)
|
|
132
|
+
+ "[dim] available[/dim]"
|
|
133
|
+
)
|
|
134
|
+
else:
|
|
135
|
+
content = f"{server_text}[dim] available[/dim]"
|
|
136
|
+
|
|
137
|
+
rich_print(f"[dim]Agent [/dim][blue]{agent_name}[/blue][dim]:[/dim] {content}")
|
|
116
138
|
|
|
117
139
|
# Mark as shown
|
|
118
140
|
_agent_info_shown.add(agent_name)
|
|
@@ -226,7 +248,9 @@ async def _display_child_agent_info(child_agent, prefix: str, agent_provider) ->
|
|
|
226
248
|
)
|
|
227
249
|
|
|
228
250
|
resources_dict = await child_agent.list_resources()
|
|
229
|
-
resource_count =
|
|
251
|
+
resource_count = (
|
|
252
|
+
sum(len(resources) for resources in resources_dict.values()) if resources_dict else 0
|
|
253
|
+
)
|
|
230
254
|
|
|
231
255
|
prompts_dict = await child_agent.list_prompts()
|
|
232
256
|
prompt_count = sum(len(prompts) for prompts in prompts_dict.values()) if prompts_dict else 0
|
|
@@ -270,6 +294,7 @@ class AgentCompleter(Completer):
|
|
|
270
294
|
"prompt": "List and select MCP prompts, or apply specific prompt (/prompt <name>)",
|
|
271
295
|
"agents": "List available agents",
|
|
272
296
|
"usage": "Show current usage statistics",
|
|
297
|
+
"markdown": "Show last assistant message without markdown formatting",
|
|
273
298
|
"help": "Show available commands",
|
|
274
299
|
"clear": "Clear the screen",
|
|
275
300
|
"STOP": "Stop this prompting session and move to next workflow step",
|
|
@@ -394,7 +419,7 @@ def get_text_from_editor(initial_text: str = "") -> str:
|
|
|
394
419
|
return edited_text.strip() # Added strip() to remove trailing newlines often added by editors
|
|
395
420
|
|
|
396
421
|
|
|
397
|
-
def create_keybindings(on_toggle_multiline=None, app=None):
|
|
422
|
+
def create_keybindings(on_toggle_multiline=None, app=None, agent_provider=None, agent_name=None):
|
|
398
423
|
"""Create custom key bindings."""
|
|
399
424
|
kb = KeyBindings()
|
|
400
425
|
|
|
@@ -459,6 +484,41 @@ def create_keybindings(on_toggle_multiline=None, app=None):
|
|
|
459
484
|
if event.app:
|
|
460
485
|
event.app.invalidate()
|
|
461
486
|
|
|
487
|
+
# Store reference to agent provider and agent name for clipboard functionality
|
|
488
|
+
kb.agent_provider = agent_provider
|
|
489
|
+
kb.current_agent_name = agent_name
|
|
490
|
+
|
|
491
|
+
@kb.add("c-y")
|
|
492
|
+
async def _(event) -> None:
|
|
493
|
+
"""Ctrl+Y: Copy last assistant response to clipboard."""
|
|
494
|
+
if kb.agent_provider and kb.current_agent_name:
|
|
495
|
+
try:
|
|
496
|
+
# Get the agent
|
|
497
|
+
if hasattr(kb.agent_provider, "_agent"):
|
|
498
|
+
agent = kb.agent_provider._agent(kb.current_agent_name)
|
|
499
|
+
else:
|
|
500
|
+
agent = kb.agent_provider
|
|
501
|
+
|
|
502
|
+
# Get message history
|
|
503
|
+
if hasattr(agent, "_llm") and agent._llm and agent._llm.message_history:
|
|
504
|
+
# Find last assistant message
|
|
505
|
+
for msg in reversed(agent._llm.message_history):
|
|
506
|
+
if msg.role == "assistant":
|
|
507
|
+
content = msg.last_text()
|
|
508
|
+
import pyperclip
|
|
509
|
+
|
|
510
|
+
pyperclip.copy(content)
|
|
511
|
+
rich_print("\n[green]✓ Copied to clipboard[/green]")
|
|
512
|
+
return
|
|
513
|
+
|
|
514
|
+
rich_print("\n[yellow]No assistant messages found[/yellow]")
|
|
515
|
+
else:
|
|
516
|
+
rich_print("\n[yellow]No message history available[/yellow]")
|
|
517
|
+
except Exception as e:
|
|
518
|
+
rich_print(f"\n[red]Error copying: {e}[/red]")
|
|
519
|
+
else:
|
|
520
|
+
rich_print("[yellow]Clipboard copy not available in this context[/yellow]")
|
|
521
|
+
|
|
462
522
|
return kb
|
|
463
523
|
|
|
464
524
|
|
|
@@ -523,6 +583,7 @@ async def get_enhanced_input(
|
|
|
523
583
|
shortcuts = [
|
|
524
584
|
("Ctrl+T", toggle_text),
|
|
525
585
|
("Ctrl+E", "External"),
|
|
586
|
+
("Ctrl+Y", "Copy"),
|
|
526
587
|
("Ctrl+L", "Clear"),
|
|
527
588
|
("↑/↓", "History"),
|
|
528
589
|
]
|
|
@@ -565,7 +626,12 @@ async def get_enhanced_input(
|
|
|
565
626
|
)
|
|
566
627
|
|
|
567
628
|
# Create key bindings with a reference to the app
|
|
568
|
-
bindings = create_keybindings(
|
|
629
|
+
bindings = create_keybindings(
|
|
630
|
+
on_toggle_multiline=on_multiline_toggle,
|
|
631
|
+
app=session.app,
|
|
632
|
+
agent_provider=agent_provider,
|
|
633
|
+
agent_name=agent_name,
|
|
634
|
+
)
|
|
569
635
|
session.app.key_bindings = bindings
|
|
570
636
|
|
|
571
637
|
# Create formatted prompt text
|
|
@@ -615,6 +681,8 @@ async def get_enhanced_input(
|
|
|
615
681
|
return "LIST_AGENTS"
|
|
616
682
|
elif cmd == "usage":
|
|
617
683
|
return "SHOW_USAGE"
|
|
684
|
+
elif cmd == "markdown":
|
|
685
|
+
return "MARKDOWN"
|
|
618
686
|
elif cmd == "prompt":
|
|
619
687
|
# Handle /prompt with no arguments as interactive mode
|
|
620
688
|
if len(cmd_parts) > 1:
|
|
@@ -788,16 +856,18 @@ async def handle_special_commands(command, agent_app=None):
|
|
|
788
856
|
rich_print(" /help - Show this help")
|
|
789
857
|
rich_print(" /clear - Clear screen")
|
|
790
858
|
rich_print(" /agents - List available agents")
|
|
791
|
-
rich_print(" /prompts - List and select MCP prompts")
|
|
792
859
|
rich_print(" /prompt <name> - Apply a specific prompt by name")
|
|
793
860
|
rich_print(" /usage - Show current usage statistics")
|
|
861
|
+
rich_print(" /markdown - Show last assistant message without markdown formatting")
|
|
794
862
|
rich_print(" @agent_name - Switch to agent")
|
|
795
863
|
rich_print(" STOP - Return control back to the workflow")
|
|
796
864
|
rich_print(" EXIT - Exit fast-agent, terminating any running workflows")
|
|
797
865
|
rich_print("\n[bold]Keyboard Shortcuts:[/bold]")
|
|
798
866
|
rich_print(" Enter - Submit (normal mode) / New line (multiline mode)")
|
|
799
|
-
rich_print(" Ctrl+Enter
|
|
867
|
+
rich_print(" Ctrl+Enter - Always submit (in any mode)")
|
|
800
868
|
rich_print(" Ctrl+T - Toggle multiline mode")
|
|
869
|
+
rich_print(" Ctrl+E - Edit in external editor")
|
|
870
|
+
rich_print(" Ctrl+Y - Copy last assistant response to clipboard")
|
|
801
871
|
rich_print(" Ctrl+L - Clear input")
|
|
802
872
|
rich_print(" Up/Down - Navigate history")
|
|
803
873
|
return True
|
|
@@ -823,6 +893,10 @@ async def handle_special_commands(command, agent_app=None):
|
|
|
823
893
|
# Return a dictionary to signal that usage should be shown
|
|
824
894
|
return {"show_usage": True}
|
|
825
895
|
|
|
896
|
+
elif command == "MARKDOWN":
|
|
897
|
+
# Return a dictionary to signal that markdown display should be shown
|
|
898
|
+
return {"show_markdown": True}
|
|
899
|
+
|
|
826
900
|
elif command == "SELECT_PROMPT" or (
|
|
827
901
|
isinstance(command, str) and command.startswith("SELECT_PROMPT:")
|
|
828
902
|
):
|
mcp_agent/core/fastagent.py
CHANGED
|
@@ -314,7 +314,7 @@ class FastAgent:
|
|
|
314
314
|
self.agents,
|
|
315
315
|
model_factory_func,
|
|
316
316
|
)
|
|
317
|
-
|
|
317
|
+
|
|
318
318
|
# Validate API keys after agent creation
|
|
319
319
|
validate_provider_keys_post_creation(active_agents)
|
|
320
320
|
|
|
@@ -435,6 +435,14 @@ class FastAgent:
|
|
|
435
435
|
raise SystemExit(1)
|
|
436
436
|
|
|
437
437
|
finally:
|
|
438
|
+
# Ensure progress display is stopped before showing usage summary
|
|
439
|
+
try:
|
|
440
|
+
from mcp_agent.progress_display import progress_display
|
|
441
|
+
|
|
442
|
+
progress_display.stop()
|
|
443
|
+
except: # noqa: E722
|
|
444
|
+
pass
|
|
445
|
+
|
|
438
446
|
# Print usage report before cleanup (show for user exits too)
|
|
439
447
|
if active_agents and not had_error:
|
|
440
448
|
self._print_usage_report(active_agents)
|