fast-agent-mcp 0.2.20__py3-none-any.whl → 0.2.22__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.20.dist-info → fast_agent_mcp-0.2.22.dist-info}/METADATA +9 -7
- {fast_agent_mcp-0.2.20.dist-info → fast_agent_mcp-0.2.22.dist-info}/RECORD +20 -18
- mcp_agent/cli/commands/go.py +49 -11
- mcp_agent/config.py +13 -0
- mcp_agent/core/request_params.py +6 -1
- mcp_agent/event_progress.py +1 -1
- mcp_agent/llm/augmented_llm.py +3 -9
- mcp_agent/llm/model_factory.py +8 -0
- mcp_agent/llm/provider_types.py +1 -0
- mcp_agent/llm/providers/augmented_llm_anthropic.py +1 -0
- mcp_agent/llm/providers/augmented_llm_openai.py +14 -1
- mcp_agent/llm/providers/augmented_llm_tensorzero.py +442 -0
- mcp_agent/llm/providers/multipart_converter_tensorzero.py +200 -0
- mcp_agent/mcp/mcp_agent_client_session.py +5 -1
- mcp_agent/mcp/mcp_aggregator.py +22 -17
- mcp_agent/mcp/mcp_connection_manager.py +46 -4
- mcp_agent/mcp/prompts/prompt_server.py +12 -1
- {fast_agent_mcp-0.2.20.dist-info → fast_agent_mcp-0.2.22.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.2.20.dist-info → fast_agent_mcp-0.2.22.dist-info}/entry_points.txt +0 -0
- {fast_agent_mcp-0.2.20.dist-info → fast_agent_mcp-0.2.22.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.22
|
4
4
|
Summary: Define, Prompt and Test MCP enabled Agents and Workflows
|
5
5
|
Author-email: Shaun Smith <fastagent@llmindset.co.uk>, Sarmad Qadri <sarmad@lastmileai.dev>
|
6
6
|
License: Apache License
|
@@ -213,7 +213,7 @@ Requires-Dist: a2a-types>=0.1.0
|
|
213
213
|
Requires-Dist: aiohttp>=3.11.13
|
214
214
|
Requires-Dist: anthropic>=0.49.0
|
215
215
|
Requires-Dist: fastapi>=0.115.6
|
216
|
-
Requires-Dist: mcp
|
216
|
+
Requires-Dist: mcp>=1.8.0
|
217
217
|
Requires-Dist: openai>=1.63.2
|
218
218
|
Requires-Dist: opentelemetry-distro>=0.50b0
|
219
219
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.29.0
|
@@ -224,6 +224,7 @@ Requires-Dist: pydantic-settings>=2.7.0
|
|
224
224
|
Requires-Dist: pydantic>=2.10.4
|
225
225
|
Requires-Dist: pyyaml>=6.0.2
|
226
226
|
Requires-Dist: rich>=13.9.4
|
227
|
+
Requires-Dist: tensorzero>=2025.4.7
|
227
228
|
Requires-Dist: typer>=0.15.1
|
228
229
|
Provides-Extra: dev
|
229
230
|
Requires-Dist: anthropic>=0.42.0; extra == 'dev'
|
@@ -260,6 +261,7 @@ The simple declarative syntax lets you concentrate on composing your Prompts and
|
|
260
261
|
`fast-agent` is multi-modal, supporting Images and PDFs for both Anthropic and OpenAI endpoints via Prompts, Resources and MCP Tool Call results. The inclusion of passthrough and playback LLMs enable rapid development and test of Python glue-code for your applications.
|
261
262
|
|
262
263
|
> [!IMPORTANT]
|
264
|
+
>
|
263
265
|
> `fast-agent` The fast-agent documentation repo is here: https://github.com/evalstate/fast-agent-docs. Please feel free to submit PRs for documentation, experience reports or other content you think others may find helpful. All help and feedback warmly received.
|
264
266
|
|
265
267
|
### Agent Application Development
|
@@ -277,12 +279,12 @@ Simple model selection makes testing Model <-> MCP Server interaction painless.
|
|
277
279
|
Start by installing the [uv package manager](https://docs.astral.sh/uv/) for Python. Then:
|
278
280
|
|
279
281
|
```bash
|
280
|
-
uv pip install fast-agent-mcp
|
282
|
+
uv pip install fast-agent-mcp # install fast-agent!
|
281
283
|
|
282
|
-
fast-agent setup
|
283
|
-
uv run agent.py
|
284
|
-
uv run agent.py --model=o3-mini.low
|
285
|
-
fast-agent quickstart workflow
|
284
|
+
uv run fast-agent setup # create an example agent and config files
|
285
|
+
uv run agent.py # run your first agent
|
286
|
+
uv run agent.py --model=o3-mini.low # specify a model
|
287
|
+
uv run fast-agent quickstart workflow # create "building effective agents" examples
|
286
288
|
```
|
287
289
|
|
288
290
|
Other quickstart examples include a Researcher Agent (with Evaluator-Optimizer workflow) and Data Analysis Agent (similar to the ChatGPT experience), demonstrating MCP Roots support.
|
@@ -1,10 +1,10 @@
|
|
1
1
|
mcp_agent/__init__.py,sha256=18T0AG0W9sJhTY38O9GFFOzliDhxx9p87CvRyti9zbw,1620
|
2
2
|
mcp_agent/app.py,sha256=WRsiUdwy_9IAnaGRDwuLm7pzgQpt2wgsg10vBOpfcwM,5539
|
3
|
-
mcp_agent/config.py,sha256=
|
3
|
+
mcp_agent/config.py,sha256=ZC4SiIVbxVn7-hUfv3RFj6fNrXxvci6gmUNCGM7vzs8,12624
|
4
4
|
mcp_agent/console.py,sha256=Gjf2QLFumwG1Lav__c07X_kZxxEUSkzV-1_-YbAwcwo,813
|
5
5
|
mcp_agent/context.py,sha256=Kb3s_0MolHx7AeTs1NVcY3ly-xFBd35o8LT7Srpx9is,7334
|
6
6
|
mcp_agent/context_dependent.py,sha256=QXfhw3RaQCKfscEEBRGuZ3sdMWqkgShz2jJ1ivGGX1I,1455
|
7
|
-
mcp_agent/event_progress.py,sha256=
|
7
|
+
mcp_agent/event_progress.py,sha256=b1VKlQQF2AgPMb6XHjlJAVoPdx8GuxRTUk2g-4lBNm0,2749
|
8
8
|
mcp_agent/mcp_server_registry.py,sha256=jUmCdfcpTitXm1-3TxpWsdRWY_8phdKNYgXwB16ZSVU,10100
|
9
9
|
mcp_agent/progress_display.py,sha256=GeJU9VUt6qKsFVymG688hCMVCsAygG9ifiiEb5IcbN4,361
|
10
10
|
mcp_agent/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -23,7 +23,7 @@ mcp_agent/cli/__main__.py,sha256=AVZ7tQFhU_sDOGuUGJq8ujgKtcxsYJBJwHbVaaiRDlI,166
|
|
23
23
|
mcp_agent/cli/main.py,sha256=XjrgXMBaPKkVqAFo8T9LJz6Tp1-ivrKDOuNYWke99YA,3090
|
24
24
|
mcp_agent/cli/terminal.py,sha256=GRwD-RGW7saIz2IOWZn5vD6JjiArscELBThm1GTFkuI,1065
|
25
25
|
mcp_agent/cli/commands/check_config.py,sha256=9Ryxo_fLInm3YKdYv46yLrAJgnQtMisGreu6Kkriw2g,16677
|
26
|
-
mcp_agent/cli/commands/go.py,sha256=
|
26
|
+
mcp_agent/cli/commands/go.py,sha256=2UY8TSDwhh_-p-WYXrZz3pEv3-2eTdBl5Lxy3JyJV0E,6057
|
27
27
|
mcp_agent/cli/commands/quickstart.py,sha256=SM3CHMzDgvTxIpKjFuX9BrS_N1vRoXNBDaO90aWx1Rk,14586
|
28
28
|
mcp_agent/cli/commands/setup.py,sha256=eOEd4TL-b0DaDeSJMGOfNOsTEItoZ67W88eTP4aP-bo,6482
|
29
29
|
mcp_agent/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -38,7 +38,7 @@ mcp_agent/core/fastagent.py,sha256=WEEGz2WBAddDGNeWJwqwFIPLiQnLjaNxZLoMR0peyyU,2
|
|
38
38
|
mcp_agent/core/interactive_prompt.py,sha256=w3VyRzW4hzn0xhWZRwo_qRRAD5WVSrJYe8QDe1XZ55Y,24252
|
39
39
|
mcp_agent/core/mcp_content.py,sha256=2D7KHY9mG_vxoDwFLKvsPQV9VRIzHItM7V-jcEnACh8,8878
|
40
40
|
mcp_agent/core/prompt.py,sha256=qnintOUGEoDPYLI9bu9G2OlgVMCe5ZPUZilgMzydXhc,7919
|
41
|
-
mcp_agent/core/request_params.py,sha256=
|
41
|
+
mcp_agent/core/request_params.py,sha256=vRfAz9T6Ir-0oeJ4qEdO62LDOzoLwBuuXcBcdh6WPZ8,1576
|
42
42
|
mcp_agent/core/validation.py,sha256=RIBKFlh0GJg4rTcFQXoXp8A0sK1HpsCigKcYSK3gFaY,12090
|
43
43
|
mcp_agent/executor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
44
44
|
mcp_agent/executor/executor.py,sha256=E44p6d-o3OMRoP_dNs_cDnyti91LQ3P9eNU88mSi1kc,9462
|
@@ -48,26 +48,28 @@ mcp_agent/human_input/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
48
48
|
mcp_agent/human_input/handler.py,sha256=s712Z5ssTCwjL9-VKoIdP5CtgMh43YvepynYisiWTTA,3144
|
49
49
|
mcp_agent/human_input/types.py,sha256=RtWBOVzy8vnYoQrc36jRLn8z8N3C4pDPMBN5vF6qM5Y,1476
|
50
50
|
mcp_agent/llm/__init__.py,sha256=d8zgwG-bRFuwiMNMYkywg_qytk4P8lawyld_meuUmHI,68
|
51
|
-
mcp_agent/llm/augmented_llm.py,sha256=
|
51
|
+
mcp_agent/llm/augmented_llm.py,sha256=CqtSGo_QrHE73tz_DHMd0wdt2F41gwuUu5Bue51FNm4,24199
|
52
52
|
mcp_agent/llm/augmented_llm_passthrough.py,sha256=zHcctNpwg4EFJvD1x9Eg443SVX-uyzFphLikwF_yVE0,6288
|
53
53
|
mcp_agent/llm/augmented_llm_playback.py,sha256=6L_RWIK__R67oZK7u3Xt3hWy1T2LnHXIO-efqgP3tPw,4177
|
54
54
|
mcp_agent/llm/memory.py,sha256=HQ_c1QemOUjrkY6Z2omE6BG5fXga7y4jN7KCMOuGjPs,3345
|
55
|
-
mcp_agent/llm/model_factory.py,sha256=
|
55
|
+
mcp_agent/llm/model_factory.py,sha256=h3NJSa0yPa9iiLojEqBhIm9wgEBB46ZBibe44MnskHM,8089
|
56
56
|
mcp_agent/llm/prompt_utils.py,sha256=yWQHykoK13QRF7evHUKxVF0SpVLN-Bsft0Yixzvn0g0,4825
|
57
57
|
mcp_agent/llm/provider_key_manager.py,sha256=-K_FuibN6hdSnweT32lB8mKTfCARnbja6zYYs0ErTKg,2802
|
58
|
-
mcp_agent/llm/provider_types.py,sha256=
|
58
|
+
mcp_agent/llm/provider_types.py,sha256=oWwXTlyr6hIzU_QLJ5T-UwxZGo5e4Pjwtahz2cr1PHg,364
|
59
59
|
mcp_agent/llm/sampling_converter.py,sha256=C7wPBlmT0eD90XWabC22zkxsrVHKCrjwIwg6cG628cI,2926
|
60
60
|
mcp_agent/llm/sampling_format_converter.py,sha256=xGz4odHpOcP7--eFaJaFtUR8eR9jxZS7MnLH6J7n0EU,1263
|
61
61
|
mcp_agent/llm/providers/__init__.py,sha256=heVxtmuqFJOnjjxHz4bWSqTAxXoN1E8twC_gQ_yJpHk,265
|
62
62
|
mcp_agent/llm/providers/anthropic_utils.py,sha256=vYDN5G5jKMhD2CQg8veJYab7tvvzYkDMq8M1g_hUAQg,3275
|
63
|
-
mcp_agent/llm/providers/augmented_llm_anthropic.py,sha256=
|
63
|
+
mcp_agent/llm/providers/augmented_llm_anthropic.py,sha256=gK_IvllVBNJUUrSfpgFpdhM-d4liCt0MLq7d2lXS7RI,15510
|
64
64
|
mcp_agent/llm/providers/augmented_llm_deepseek.py,sha256=NiZK5nv91ZS2VgVFXpbsFNFYLsLcppcbo_RstlRMd7I,1145
|
65
65
|
mcp_agent/llm/providers/augmented_llm_generic.py,sha256=5Uq8ZBhcFuQTt7koP_5ykolREh2iWu8zKhNbh3pM9lQ,1210
|
66
66
|
mcp_agent/llm/providers/augmented_llm_google.py,sha256=N0a2fphVtkvNYxKQpEX6J4tlO1C_mRw4sw3LBXnrOeI,1130
|
67
|
-
mcp_agent/llm/providers/augmented_llm_openai.py,sha256=
|
67
|
+
mcp_agent/llm/providers/augmented_llm_openai.py,sha256=0C7BOB7i3xo0HsMCTagRSQ8Hsywb-31mot26OfohzCU,14478
|
68
68
|
mcp_agent/llm/providers/augmented_llm_openrouter.py,sha256=V_TlVKm92GHBxYIo6gpvH_6cAaIdppS25Tz6x5T7LW0,2341
|
69
|
+
mcp_agent/llm/providers/augmented_llm_tensorzero.py,sha256=Mol_Wzj_ZtccW-LMw0oFwWUt1m1yfofloay9QYNP23c,20729
|
69
70
|
mcp_agent/llm/providers/multipart_converter_anthropic.py,sha256=t5lHYGfFUacJldnrVtMNW-8gEMoto8Y7hJkDrnyZR-Y,16650
|
70
71
|
mcp_agent/llm/providers/multipart_converter_openai.py,sha256=XPIulWntNpZWNGWrc240StPzok2RqrDAV7OigDwQ1uU,15850
|
72
|
+
mcp_agent/llm/providers/multipart_converter_tensorzero.py,sha256=BFTdyVk42HZskDAuTHicfDTUJq89d1fz8C9nAOuHxlE,8646
|
71
73
|
mcp_agent/llm/providers/openai_multipart.py,sha256=qKBn7d3jSabnJmVgWweVzqh8q9mBqr09fsPmP92niAQ,6899
|
72
74
|
mcp_agent/llm/providers/openai_utils.py,sha256=T4bTCL9f7DsoS_zoKgQKv_FUv_4n98vgbvaUpdWZJr8,1875
|
73
75
|
mcp_agent/llm/providers/sampling_converter_anthropic.py,sha256=35WzBWkPklnuMlu5S6XsQIq0YL58NOy8Ja6A_l4m6eM,1612
|
@@ -83,9 +85,9 @@ mcp_agent/mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
83
85
|
mcp_agent/mcp/gen_client.py,sha256=fAVwFVCgSamw4PwoWOV4wrK9TABx1S_zZv8BctRyF2k,3030
|
84
86
|
mcp_agent/mcp/interfaces.py,sha256=PAou8znAl2HgtvfCpLQOZFbKra9F72OcVRfBJbboNX8,6965
|
85
87
|
mcp_agent/mcp/logger_textio.py,sha256=vljC1BtNTCxBAda9ExqNB-FwVNUZIuJT3h1nWmCjMws,3172
|
86
|
-
mcp_agent/mcp/mcp_agent_client_session.py,sha256=
|
87
|
-
mcp_agent/mcp/mcp_aggregator.py,sha256=
|
88
|
-
mcp_agent/mcp/mcp_connection_manager.py,sha256=
|
88
|
+
mcp_agent/mcp/mcp_agent_client_session.py,sha256=Ng7epBXq8BEA_3m1GX5LqwafgNUAMSzBugwN6N0VUWQ,4364
|
89
|
+
mcp_agent/mcp/mcp_aggregator.py,sha256=lVSt0yp0CnaYjcHCWmluwBeFgl8JXHYEZk0MzXgrQzA,40110
|
90
|
+
mcp_agent/mcp/mcp_connection_manager.py,sha256=6jtjclh4YNJZsNwYnSWmQ6cPzapAwsRUxir1c_gVNfM,16051
|
89
91
|
mcp_agent/mcp/mime_utils.py,sha256=difepNR_gpb4MpMLkBRAoyhDk-AjXUHTiqKvT_VwS1o,1805
|
90
92
|
mcp_agent/mcp/prompt_message_multipart.py,sha256=BDwRdNwyWHb2q2bccDb2iR2VlORqVvkvoG3xYzcMpCE,4403
|
91
93
|
mcp_agent/mcp/prompt_render.py,sha256=k3v4BZDThGE2gGiOYVQtA6x8WTEdOuXIEnRafANhN1U,2996
|
@@ -99,7 +101,7 @@ mcp_agent/mcp/prompts/__main__.py,sha256=gr1Tdz9fcK0EXjEuZg_BOnKUmvhYq5AH2lFZicV
|
|
99
101
|
mcp_agent/mcp/prompts/prompt_constants.py,sha256=Q9W0t3rOXl2LHIG9wcghApUV2QZ1iICuo7SwVwHUf3c,566
|
100
102
|
mcp_agent/mcp/prompts/prompt_helpers.py,sha256=Joqo2t09pTKDP-Wge3G-ozPEHikzjaqwV6GVk8hNR50,7534
|
101
103
|
mcp_agent/mcp/prompts/prompt_load.py,sha256=Zo0FogqWFEG5FtF1d9ZH-RWsCSSMsi5FIEQHpJD8N7M,5404
|
102
|
-
mcp_agent/mcp/prompts/prompt_server.py,sha256=
|
104
|
+
mcp_agent/mcp/prompts/prompt_server.py,sha256=DbuDcYCMbsbqwBeebpNGInAQ4-DP1Jjp49y8uZ-0XlY,18872
|
103
105
|
mcp_agent/mcp/prompts/prompt_template.py,sha256=EejiqGkau8OizORNyKTUwUjrPof5V-hH1H_MBQoQfXw,15732
|
104
106
|
mcp_agent/mcp_server/__init__.py,sha256=zBU51ITHIEPScd9nRafnhEddsWqXRPAAvHhkrbRI2_4,155
|
105
107
|
mcp_agent/mcp_server/agent_server.py,sha256=s-nI0uTNWx4nYDDM_5GmuY5x6ZeFkymfNoCSuwuBRd8,19891
|
@@ -143,8 +145,8 @@ mcp_agent/resources/examples/workflows/parallel.py,sha256=DQ5vY5-h8Qa5QHcYjsWXhZ
|
|
143
145
|
mcp_agent/resources/examples/workflows/router.py,sha256=E4x_-c3l4YW9w1i4ARcDtkdeqIdbWEGfsMzwLYpdbVc,1677
|
144
146
|
mcp_agent/resources/examples/workflows/short_story.txt,sha256=X3y_1AyhLFN2AKzCKvucJtDgAFIJfnlbsbGZO5bBWu0,1187
|
145
147
|
mcp_agent/ui/console_display.py,sha256=TVGDtJ37hc6UG0ei9g7ZPZZfFNeS1MYozt-Mx8HsPCk,9752
|
146
|
-
fast_agent_mcp-0.2.
|
147
|
-
fast_agent_mcp-0.2.
|
148
|
-
fast_agent_mcp-0.2.
|
149
|
-
fast_agent_mcp-0.2.
|
150
|
-
fast_agent_mcp-0.2.
|
148
|
+
fast_agent_mcp-0.2.22.dist-info/METADATA,sha256=HbiOG6NhC3IEfEyBsUDQnihh2LbU4CEZEe19X4Y7VTQ,30194
|
149
|
+
fast_agent_mcp-0.2.22.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
150
|
+
fast_agent_mcp-0.2.22.dist-info/entry_points.txt,sha256=bRniFM5zk3Kix5z7scX0gf9VnmGQ2Cz_Q1Gh7Ir4W00,186
|
151
|
+
fast_agent_mcp-0.2.22.dist-info/licenses/LICENSE,sha256=cN3FxDURL9XuzE5mhK9L2paZo82LTfjwCYVT7e3j0e4,10939
|
152
|
+
fast_agent_mcp-0.2.22.dist-info/RECORD,,
|
mcp_agent/cli/commands/go.py
CHANGED
@@ -18,8 +18,13 @@ async def _run_agent(
|
|
18
18
|
config_path: Optional[str] = None,
|
19
19
|
server_list: Optional[List[str]] = None,
|
20
20
|
model: Optional[str] = None,
|
21
|
+
message: Optional[str] = None,
|
22
|
+
prompt_file: Optional[str] = None
|
21
23
|
) -> None:
|
22
24
|
"""Async implementation to run an interactive agent."""
|
25
|
+
from pathlib import Path
|
26
|
+
|
27
|
+
from mcp_agent.mcp.prompts.prompt_load import load_prompt_multipart
|
23
28
|
|
24
29
|
# Create the FastAgent instance with CLI arg parsing enabled
|
25
30
|
# It will automatically parse args like --model, --quiet, etc.
|
@@ -27,6 +32,7 @@ async def _run_agent(
|
|
27
32
|
"name": name,
|
28
33
|
"config_path": config_path,
|
29
34
|
"ignore_unknown_args": True,
|
35
|
+
"parse_cli_args": False, # Don't parse CLI args, we're handling it ourselves
|
30
36
|
}
|
31
37
|
|
32
38
|
fast = FastAgent(**fast_kwargs)
|
@@ -38,10 +44,26 @@ async def _run_agent(
|
|
38
44
|
if model:
|
39
45
|
agent_kwargs["model"] = model
|
40
46
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
47
|
+
# Handle prompt file and message options
|
48
|
+
if message or prompt_file:
|
49
|
+
@fast.agent(**agent_kwargs)
|
50
|
+
async def cli_agent():
|
51
|
+
async with fast.run() as agent:
|
52
|
+
if message:
|
53
|
+
response = await agent.send(message)
|
54
|
+
# Print the response and exit
|
55
|
+
print(response)
|
56
|
+
elif prompt_file:
|
57
|
+
prompt = load_prompt_multipart(Path(prompt_file))
|
58
|
+
response = await agent.generate(prompt)
|
59
|
+
# Print the response text and exit
|
60
|
+
print(response.last_text())
|
61
|
+
else:
|
62
|
+
# Standard interactive mode
|
63
|
+
@fast.agent(**agent_kwargs)
|
64
|
+
async def cli_agent():
|
65
|
+
async with fast.run() as agent:
|
66
|
+
await agent.interactive()
|
45
67
|
|
46
68
|
# Run the agent
|
47
69
|
await cli_agent()
|
@@ -51,7 +73,9 @@ def run_async_agent(
|
|
51
73
|
instruction: str,
|
52
74
|
config_path: Optional[str] = None,
|
53
75
|
servers: Optional[str] = None,
|
54
|
-
model: Optional[str] = None
|
76
|
+
model: Optional[str] = None,
|
77
|
+
message: Optional[str] = None,
|
78
|
+
prompt_file: Optional[str] = None
|
55
79
|
):
|
56
80
|
"""Run the async agent function with proper loop handling."""
|
57
81
|
server_list = servers.split(',') if servers else None
|
@@ -75,7 +99,9 @@ def run_async_agent(
|
|
75
99
|
instruction=instruction,
|
76
100
|
config_path=config_path,
|
77
101
|
server_list=server_list,
|
78
|
-
model=model
|
102
|
+
model=model,
|
103
|
+
message=message,
|
104
|
+
prompt_file=prompt_file
|
79
105
|
))
|
80
106
|
finally:
|
81
107
|
try:
|
@@ -108,26 +134,38 @@ def go(
|
|
108
134
|
model: Optional[str] = typer.Option(
|
109
135
|
None, "--model", help="Override the default model (e.g., haiku, sonnet, gpt-4)"
|
110
136
|
),
|
137
|
+
message: Optional[str] = typer.Option(
|
138
|
+
None, "--message", "-m", help="Message to send to the agent (skips interactive mode)"
|
139
|
+
),
|
140
|
+
prompt_file: Optional[str] = typer.Option(
|
141
|
+
None, "--prompt-file", "-p", help="Path to a prompt file to use (either text or JSON)"
|
142
|
+
),
|
111
143
|
) -> None:
|
112
144
|
"""
|
113
145
|
Run an interactive agent directly from the command line.
|
114
146
|
|
115
|
-
|
147
|
+
Examples:
|
116
148
|
fast-agent go --model=haiku --instruction="You are a coding assistant" --servers=fetch,filesystem
|
149
|
+
fast-agent go --message="What is the weather today?" --model=haiku
|
150
|
+
fast-agent go --prompt-file=my-prompt.txt --model=haiku
|
117
151
|
|
118
152
|
This will start an interactive session with the agent, using the specified model
|
119
153
|
and instruction. It will use the default configuration from fastagent.config.yaml
|
120
154
|
unless --config-path is specified.
|
121
155
|
|
122
156
|
Common options:
|
123
|
-
--model
|
124
|
-
--quiet
|
125
|
-
--servers
|
157
|
+
--model Override the default model (e.g., --model=haiku)
|
158
|
+
--quiet Disable progress display and logging
|
159
|
+
--servers Comma-separated list of server names to enable from config
|
160
|
+
--message, -m Send a single message and exit
|
161
|
+
--prompt-file, -p Use a prompt file instead of interactive mode
|
126
162
|
"""
|
127
163
|
run_async_agent(
|
128
164
|
name=name,
|
129
165
|
instruction=instruction,
|
130
166
|
config_path=config_path,
|
131
167
|
servers=servers,
|
132
|
-
model=model
|
168
|
+
model=model,
|
169
|
+
message=message,
|
170
|
+
prompt_file=prompt_file
|
133
171
|
)
|
mcp_agent/config.py
CHANGED
@@ -198,6 +198,16 @@ class OpenTelemetrySettings(BaseModel):
|
|
198
198
|
"""Sample rate for tracing (1.0 = sample everything)"""
|
199
199
|
|
200
200
|
|
201
|
+
class TensorZeroSettings(BaseModel):
|
202
|
+
"""
|
203
|
+
Settings for using TensorZero via its OpenAI-compatible API.
|
204
|
+
"""
|
205
|
+
|
206
|
+
base_url: Optional[str] = None
|
207
|
+
api_key: Optional[str] = None
|
208
|
+
model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)
|
209
|
+
|
210
|
+
|
201
211
|
class LoggerSettings(BaseModel):
|
202
212
|
"""
|
203
213
|
Logger settings for the fast-agent application.
|
@@ -287,6 +297,9 @@ class Settings(BaseSettings):
|
|
287
297
|
generic: GenericSettings | None = None
|
288
298
|
"""Settings for using Generic models in the fast-agent application"""
|
289
299
|
|
300
|
+
tensorzero: Optional[TensorZeroSettings] = None
|
301
|
+
"""Settings for using TensorZero inference gateway"""
|
302
|
+
|
290
303
|
logger: LoggerSettings | None = LoggerSettings()
|
291
304
|
"""Logger settings for the fast-agent application"""
|
292
305
|
|
mcp_agent/core/request_params.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
Request parameters definitions for LLM interactions.
|
3
3
|
"""
|
4
4
|
|
5
|
-
from typing import Any, List
|
5
|
+
from typing import Any, Dict, List
|
6
6
|
|
7
7
|
from mcp import SamplingMessage
|
8
8
|
from mcp.types import CreateMessageRequestParams
|
@@ -48,3 +48,8 @@ class RequestParams(CreateMessageRequestParams):
|
|
48
48
|
"""
|
49
49
|
Override response format for structured calls. Prefer sending pydantic model - only use in exceptional circumstances
|
50
50
|
"""
|
51
|
+
|
52
|
+
template_vars: Dict[str, Any] = Field(default_factory=dict)
|
53
|
+
"""
|
54
|
+
Optional dictionary of template variables for dynamic templates. Currently only works for TensorZero inference backend
|
55
|
+
"""
|
mcp_agent/event_progress.py
CHANGED
mcp_agent/llm/augmented_llm.py
CHANGED
@@ -76,20 +76,14 @@ def deep_merge(dict1: Dict[Any, Any], dict2: Dict[Any, Any]) -> Dict[Any, Any]:
|
|
76
76
|
Dict: The updated `dict1`.
|
77
77
|
"""
|
78
78
|
for key in dict2:
|
79
|
-
if (
|
80
|
-
key in dict1
|
81
|
-
and isinstance(dict1[key], dict)
|
82
|
-
and isinstance(dict2[key], dict)
|
83
|
-
):
|
79
|
+
if key in dict1 and isinstance(dict1[key], dict) and isinstance(dict2[key], dict):
|
84
80
|
deep_merge(dict1[key], dict2[key])
|
85
81
|
else:
|
86
82
|
dict1[key] = dict2[key]
|
87
83
|
return dict1
|
88
84
|
|
89
85
|
|
90
|
-
class AugmentedLLM(
|
91
|
-
ContextDependent, AugmentedLLMProtocol, Generic[MessageParamT, MessageT]
|
92
|
-
):
|
86
|
+
class AugmentedLLM(ContextDependent, AugmentedLLMProtocol, Generic[MessageParamT, MessageT]):
|
93
87
|
# Common parameter names used across providers
|
94
88
|
PARAM_MESSAGES = "messages"
|
95
89
|
PARAM_MODEL = "model"
|
@@ -100,7 +94,7 @@ class AugmentedLLM(
|
|
100
94
|
PARAM_METADATA = "metadata"
|
101
95
|
PARAM_USE_HISTORY = "use_history"
|
102
96
|
PARAM_MAX_ITERATIONS = "max_iterations"
|
103
|
-
|
97
|
+
PARAM_TEMPLATE_VARS = "template_vars"
|
104
98
|
# Base set of fields that should always be excluded
|
105
99
|
BASE_EXCLUDE_FIELDS = {PARAM_METADATA}
|
106
100
|
|
mcp_agent/llm/model_factory.py
CHANGED
@@ -15,6 +15,7 @@ from mcp_agent.llm.providers.augmented_llm_generic import GenericAugmentedLLM
|
|
15
15
|
from mcp_agent.llm.providers.augmented_llm_google import GoogleAugmentedLLM
|
16
16
|
from mcp_agent.llm.providers.augmented_llm_openai import OpenAIAugmentedLLM
|
17
17
|
from mcp_agent.llm.providers.augmented_llm_openrouter import OpenRouterAugmentedLLM
|
18
|
+
from mcp_agent.llm.providers.augmented_llm_tensorzero import TensorZeroAugmentedLLM
|
18
19
|
from mcp_agent.mcp.interfaces import AugmentedLLMProtocol
|
19
20
|
|
20
21
|
# from mcp_agent.workflows.llm.augmented_llm_deepseek import DeekSeekAugmentedLLM
|
@@ -28,6 +29,7 @@ LLMClass = Union[
|
|
28
29
|
Type[PlaybackLLM],
|
29
30
|
Type[DeepSeekAugmentedLLM],
|
30
31
|
Type[OpenRouterAugmentedLLM],
|
32
|
+
Type[TensorZeroAugmentedLLM],
|
31
33
|
]
|
32
34
|
|
33
35
|
|
@@ -110,6 +112,7 @@ class ModelFactory:
|
|
110
112
|
Provider.GENERIC: GenericAugmentedLLM,
|
111
113
|
Provider.GOOGLE: GoogleAugmentedLLM, # type: ignore
|
112
114
|
Provider.OPENROUTER: OpenRouterAugmentedLLM,
|
115
|
+
Provider.TENSORZERO: TensorZeroAugmentedLLM,
|
113
116
|
}
|
114
117
|
|
115
118
|
# Mapping of special model names to their specific LLM classes
|
@@ -142,6 +145,11 @@ class ModelFactory:
|
|
142
145
|
provider = Provider(potential_provider)
|
143
146
|
model_parts = model_parts[1:]
|
144
147
|
|
148
|
+
if provider == Provider.TENSORZERO and not model_parts:
|
149
|
+
raise ModelConfigError(
|
150
|
+
f"TensorZero provider requires a function name after the provider "
|
151
|
+
f"(e.g., tensorzero.my-function), got: {model_string}"
|
152
|
+
)
|
145
153
|
# Join remaining parts as model name
|
146
154
|
model_name = ".".join(model_parts)
|
147
155
|
|
mcp_agent/llm/provider_types.py
CHANGED
@@ -62,6 +62,7 @@ class AnthropicAugmentedLLM(AugmentedLLM[MessageParam, Message]):
|
|
62
62
|
AugmentedLLM.PARAM_USE_HISTORY,
|
63
63
|
AugmentedLLM.PARAM_MAX_ITERATIONS,
|
64
64
|
AugmentedLLM.PARAM_PARALLEL_TOOL_CALLS,
|
65
|
+
AugmentedLLM.PARAM_TEMPLATE_VARS,
|
65
66
|
}
|
66
67
|
|
67
68
|
def __init__(self, *args, **kwargs) -> None:
|
@@ -56,6 +56,7 @@ class OpenAIAugmentedLLM(AugmentedLLM[ChatCompletionMessageParam, ChatCompletion
|
|
56
56
|
AugmentedLLM.PARAM_PARALLEL_TOOL_CALLS,
|
57
57
|
AugmentedLLM.PARAM_USE_HISTORY,
|
58
58
|
AugmentedLLM.PARAM_MAX_ITERATIONS,
|
59
|
+
AugmentedLLM.PARAM_TEMPLATE_VARS,
|
59
60
|
}
|
60
61
|
|
61
62
|
def __init__(self, provider: Provider = Provider.OPENAI, *args, **kwargs) -> None:
|
@@ -143,7 +144,7 @@ class OpenAIAugmentedLLM(AugmentedLLM[ChatCompletionMessageParam, ChatCompletion
|
|
143
144
|
function={
|
144
145
|
"name": tool.name,
|
145
146
|
"description": tool.description if tool.description else "",
|
146
|
-
"parameters": tool.inputSchema,
|
147
|
+
"parameters": self.adjust_schema(tool.inputSchema),
|
147
148
|
},
|
148
149
|
)
|
149
150
|
for tool in response.tools
|
@@ -350,3 +351,15 @@ class OpenAIAugmentedLLM(AugmentedLLM[ChatCompletionMessageParam, ChatCompletion
|
|
350
351
|
base_args, request_params, self.OPENAI_EXCLUDE_FIELDS.union(self.BASE_EXCLUDE_FIELDS)
|
351
352
|
)
|
352
353
|
return arguments
|
354
|
+
|
355
|
+
def adjust_schema(self, inputSchema: Dict) -> Dict:
|
356
|
+
# return inputSchema
|
357
|
+
if not Provider.OPENAI == self.provider:
|
358
|
+
return inputSchema
|
359
|
+
|
360
|
+
if "properties" in inputSchema:
|
361
|
+
return inputSchema
|
362
|
+
|
363
|
+
result = inputSchema.copy()
|
364
|
+
result["properties"] = {}
|
365
|
+
return result
|