fast-agent-mcp 0.2.49__py3-none-any.whl → 0.2.51__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.49.dist-info → fast_agent_mcp-0.2.51.dist-info}/METADATA +4 -4
- {fast_agent_mcp-0.2.49.dist-info → fast_agent_mcp-0.2.51.dist-info}/RECORD +38 -21
- mcp_agent/cli/commands/quickstart.py +107 -0
- mcp_agent/event_progress.py +18 -0
- mcp_agent/llm/model_database.py +39 -1
- mcp_agent/llm/model_factory.py +5 -3
- mcp_agent/llm/providers/augmented_llm_aliyun.py +7 -8
- mcp_agent/llm/providers/augmented_llm_deepseek.py +7 -8
- mcp_agent/llm/providers/augmented_llm_groq.py +80 -7
- mcp_agent/llm/providers/augmented_llm_openai.py +18 -7
- mcp_agent/llm/providers/augmented_llm_openrouter.py +10 -15
- mcp_agent/llm/providers/augmented_llm_tensorzero_openai.py +127 -0
- mcp_agent/llm/providers/augmented_llm_xai.py +8 -8
- mcp_agent/llm/providers/google_converter.py +4 -0
- mcp_agent/logging/rich_progress.py +30 -7
- mcp_agent/mcp/helpers/content_helpers.py +29 -0
- mcp_agent/mcp/mcp_aggregator.py +32 -1
- mcp_agent/resources/examples/tensorzero/.env.sample +2 -0
- mcp_agent/resources/examples/tensorzero/Makefile +31 -0
- mcp_agent/resources/examples/tensorzero/README.md +55 -0
- mcp_agent/resources/examples/tensorzero/agent.py +35 -0
- mcp_agent/resources/examples/tensorzero/demo_images/clam.jpg +0 -0
- mcp_agent/resources/examples/tensorzero/demo_images/crab.png +0 -0
- mcp_agent/resources/examples/tensorzero/demo_images/shrimp.png +0 -0
- mcp_agent/resources/examples/tensorzero/docker-compose.yml +105 -0
- mcp_agent/resources/examples/tensorzero/fastagent.config.yaml +19 -0
- mcp_agent/resources/examples/tensorzero/image_demo.py +67 -0
- mcp_agent/resources/examples/tensorzero/mcp_server/Dockerfile +25 -0
- mcp_agent/resources/examples/tensorzero/mcp_server/entrypoint.sh +35 -0
- mcp_agent/resources/examples/tensorzero/mcp_server/mcp_server.py +31 -0
- mcp_agent/resources/examples/tensorzero/mcp_server/pyproject.toml +11 -0
- mcp_agent/resources/examples/tensorzero/simple_agent.py +25 -0
- mcp_agent/resources/examples/tensorzero/tensorzero_config/system_schema.json +29 -0
- mcp_agent/resources/examples/tensorzero/tensorzero_config/system_template.minijinja +11 -0
- mcp_agent/resources/examples/tensorzero/tensorzero_config/tensorzero.toml +35 -0
- mcp_agent/llm/providers/augmented_llm_tensorzero.py +0 -441
- mcp_agent/llm/providers/multipart_converter_tensorzero.py +0 -201
- {fast_agent_mcp-0.2.49.dist-info → fast_agent_mcp-0.2.51.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.2.49.dist-info → fast_agent_mcp-0.2.51.dist-info}/entry_points.txt +0 -0
- {fast_agent_mcp-0.2.49.dist-info → fast_agent_mcp-0.2.51.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.51
|
|
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
|
|
@@ -208,8 +208,8 @@ License-File: LICENSE
|
|
|
208
208
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
209
209
|
Classifier: Operating System :: OS Independent
|
|
210
210
|
Classifier: Programming Language :: Python :: 3
|
|
211
|
-
Requires-Python: >=3.
|
|
212
|
-
Requires-Dist: a2a-sdk>=0.
|
|
211
|
+
Requires-Python: >=3.13
|
|
212
|
+
Requires-Dist: a2a-sdk>=0.3.0
|
|
213
213
|
Requires-Dist: aiohttp>=3.11.13
|
|
214
214
|
Requires-Dist: anthropic>=0.59.0
|
|
215
215
|
Requires-Dist: azure-identity>=1.14.0
|
|
@@ -232,7 +232,7 @@ Requires-Dist: pydantic>=2.10.4
|
|
|
232
232
|
Requires-Dist: pyperclip>=1.9.0
|
|
233
233
|
Requires-Dist: pyyaml>=6.0.2
|
|
234
234
|
Requires-Dist: rich>=14.1.0
|
|
235
|
-
Requires-Dist: tensorzero>=2025.
|
|
235
|
+
Requires-Dist: tensorzero>=2025.7.5
|
|
236
236
|
Requires-Dist: typer>=0.15.1
|
|
237
237
|
Provides-Extra: azure
|
|
238
238
|
Requires-Dist: azure-identity>=1.14.0; extra == 'azure'
|
|
@@ -4,7 +4,7 @@ mcp_agent/config.py,sha256=uwfZIdnO4NpYF90uQjOvwhgh4GqYnVfkqCahhN5jZHc,19248
|
|
|
4
4
|
mcp_agent/console.py,sha256=Gjf2QLFumwG1Lav__c07X_kZxxEUSkzV-1_-YbAwcwo,813
|
|
5
5
|
mcp_agent/context.py,sha256=lzz_Fyf9lz9BBAUt1bRVBlyyHjLkyeuyIziAi4qXYUk,7639
|
|
6
6
|
mcp_agent/context_dependent.py,sha256=QXfhw3RaQCKfscEEBRGuZ3sdMWqkgShz2jJ1ivGGX1I,1455
|
|
7
|
-
mcp_agent/event_progress.py,sha256=
|
|
7
|
+
mcp_agent/event_progress.py,sha256=EdozJ6a13Ur_zMMbPx-1pKwsLEbHF0bwCEcErhxLCew,4513
|
|
8
8
|
mcp_agent/mcp_server_registry.py,sha256=lmz-aES-l7Gbg4itDF0iCmpso_KD8bVazVKSVzjwNE4,12398
|
|
9
9
|
mcp_agent/progress_display.py,sha256=GeJU9VUt6qKsFVymG688hCMVCsAygG9ifiiEb5IcbN4,361
|
|
10
10
|
mcp_agent/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -27,7 +27,7 @@ mcp_agent/cli/main.py,sha256=Oo13X7LB0Cf7JrkilQXz8Eqi_48cE0Rr2qqDUOQifEQ,3175
|
|
|
27
27
|
mcp_agent/cli/terminal.py,sha256=GRwD-RGW7saIz2IOWZn5vD6JjiArscELBThm1GTFkuI,1065
|
|
28
28
|
mcp_agent/cli/commands/check_config.py,sha256=15YK0mtDQbVopnMm3HBjOeY2-00FUHj6tt8RvaemKmI,21081
|
|
29
29
|
mcp_agent/cli/commands/go.py,sha256=SHFJlO3SeZzAWvx_Gz72zXKA8n7XfaZ49W6UNS5mbV4,14668
|
|
30
|
-
mcp_agent/cli/commands/quickstart.py,sha256=
|
|
30
|
+
mcp_agent/cli/commands/quickstart.py,sha256=hwIr1F9zGRSQGf7kwvmirMIK7Qke2s6W95inZ-a2SMQ,21171
|
|
31
31
|
mcp_agent/cli/commands/server_helpers.py,sha256=x5tD_qhf1W4D2li09sfOyfRWCOCa6lmpumYAPsEfIQs,3649
|
|
32
32
|
mcp_agent/cli/commands/setup.py,sha256=eOEd4TL-b0DaDeSJMGOfNOsTEItoZ67W88eTP4aP-bo,6482
|
|
33
33
|
mcp_agent/cli/commands/url_parser.py,sha256=5VdtcHRHzi67YignStVbz7u-rcvNNErw9oJLAUFOtEY,5855
|
|
@@ -67,8 +67,8 @@ mcp_agent/llm/augmented_llm_playback.py,sha256=rLzgai496e2RlxqQp_Bp0U-Y1FF1SGsWl
|
|
|
67
67
|
mcp_agent/llm/augmented_llm_silent.py,sha256=IUnK_1Byy4D9TG0Pj46LFeNezgSTQ8d6MQIHWAImBwE,1846
|
|
68
68
|
mcp_agent/llm/augmented_llm_slow.py,sha256=DDSD8bL2flmQrVHZm-UDs7sR8aHRWkDOcOW-mX_GPok,2067
|
|
69
69
|
mcp_agent/llm/memory.py,sha256=pTOaTDV3EA3X68yKwEtUAu7s0xGIQQ_cKBhfYUnfR0w,8614
|
|
70
|
-
mcp_agent/llm/model_database.py,sha256=
|
|
71
|
-
mcp_agent/llm/model_factory.py,sha256=
|
|
70
|
+
mcp_agent/llm/model_database.py,sha256=ehNiw_d5y4f1t_ySJSigxN1NxikXEXFXbkO5E0gLX9M,10943
|
|
71
|
+
mcp_agent/llm/model_factory.py,sha256=dIVs0RBhVy31-8nAjXdnWSIUJmW5UKnQym_oeQNuNiU,11906
|
|
72
72
|
mcp_agent/llm/prompt_utils.py,sha256=yWQHykoK13QRF7evHUKxVF0SpVLN-Bsft0Yixzvn0g0,4825
|
|
73
73
|
mcp_agent/llm/provider_key_manager.py,sha256=LSWIgcXlrUS4sfBvQBCya82qC6NcXQPYLtDHwHNOXR4,3394
|
|
74
74
|
mcp_agent/llm/provider_types.py,sha256=LfuVuFjcM_lMED0lkrNfKK8s8Fs1vbxugQsrcBE2CIY,1119
|
|
@@ -77,23 +77,22 @@ mcp_agent/llm/sampling_format_converter.py,sha256=xGz4odHpOcP7--eFaJaFtUR8eR9jxZ
|
|
|
77
77
|
mcp_agent/llm/usage_tracking.py,sha256=rF6v8QQDam8QbvlP4jzHljKqvuNHExeYDLkUMI86czY,16073
|
|
78
78
|
mcp_agent/llm/providers/__init__.py,sha256=heVxtmuqFJOnjjxHz4bWSqTAxXoN1E8twC_gQ_yJpHk,265
|
|
79
79
|
mcp_agent/llm/providers/anthropic_utils.py,sha256=vYDN5G5jKMhD2CQg8veJYab7tvvzYkDMq8M1g_hUAQg,3275
|
|
80
|
-
mcp_agent/llm/providers/augmented_llm_aliyun.py,sha256=
|
|
80
|
+
mcp_agent/llm/providers/augmented_llm_aliyun.py,sha256=JlRfhohIQQlo5RgM1B2t4ITLC9dok8LQNKLf0BK8Ai8,1158
|
|
81
81
|
mcp_agent/llm/providers/augmented_llm_anthropic.py,sha256=U8znA9HSCOx4FlhIjl-J29nbYc8Y-T6BXevtXuDafio,30352
|
|
82
82
|
mcp_agent/llm/providers/augmented_llm_azure.py,sha256=Xoo6dFst6L9SaGKurqptwwTUzr-sYsolZ-AFb_79puc,6098
|
|
83
83
|
mcp_agent/llm/providers/augmented_llm_bedrock.py,sha256=nfby1udL07zPTOLlN_tFxd1h0JRioo2oIW7v4iP4Bnk,82267
|
|
84
|
-
mcp_agent/llm/providers/augmented_llm_deepseek.py,sha256=
|
|
84
|
+
mcp_agent/llm/providers/augmented_llm_deepseek.py,sha256=vphkYMFyukaejBw8SkCN-MqcG9qsfXJfWKZYYtspqPY,3877
|
|
85
85
|
mcp_agent/llm/providers/augmented_llm_generic.py,sha256=5Uq8ZBhcFuQTt7koP_5ykolREh2iWu8zKhNbh3pM9lQ,1210
|
|
86
86
|
mcp_agent/llm/providers/augmented_llm_google_native.py,sha256=c6zczfs-Iw70j3OYELHJ4S7CRwAddkeXinex_yLMhmU,22194
|
|
87
87
|
mcp_agent/llm/providers/augmented_llm_google_oai.py,sha256=g_g46h-YuxqbRZiO_dVo5zO2OkX1yx7nb6xDaQbOvWs,1137
|
|
88
|
-
mcp_agent/llm/providers/augmented_llm_groq.py,sha256=
|
|
89
|
-
mcp_agent/llm/providers/augmented_llm_openai.py,sha256=
|
|
90
|
-
mcp_agent/llm/providers/augmented_llm_openrouter.py,sha256=
|
|
91
|
-
mcp_agent/llm/providers/
|
|
92
|
-
mcp_agent/llm/providers/augmented_llm_xai.py,sha256=
|
|
93
|
-
mcp_agent/llm/providers/google_converter.py,sha256=
|
|
88
|
+
mcp_agent/llm/providers/augmented_llm_groq.py,sha256=5pqWgOoEJpvL230rJekBNlmBzUegbgwYitArlXgAmY0,4424
|
|
89
|
+
mcp_agent/llm/providers/augmented_llm_openai.py,sha256=ncFlItw4DKKWFQ1czePye2Hpo_qzL22Yanc3aaOUuHA,25343
|
|
90
|
+
mcp_agent/llm/providers/augmented_llm_openrouter.py,sha256=m3wS83fabBOmaZJH9gQ9sFw_2TB4xTb44WCOPB-2NJ4,2001
|
|
91
|
+
mcp_agent/llm/providers/augmented_llm_tensorzero_openai.py,sha256=D53Fry2AfBLOB5z9hM19U6_HMJeVNTpiBCAJb11ulNg,5503
|
|
92
|
+
mcp_agent/llm/providers/augmented_llm_xai.py,sha256=MhlX91IUNynQ_NDknx4EQJLwg-NbR8lcHS1P4JuLOnA,1433
|
|
93
|
+
mcp_agent/llm/providers/google_converter.py,sha256=YmSfkkZR2YzR5DZduGaOW0v7BtjjindCIiuS8zOJ1VA,16941
|
|
94
94
|
mcp_agent/llm/providers/multipart_converter_anthropic.py,sha256=QsgIwWJ14SNZsun3fKDQaUx5AYdk8X6UYeBgYlZgZN0,16607
|
|
95
95
|
mcp_agent/llm/providers/multipart_converter_openai.py,sha256=8vBwX7PB62mV6pe4VvAj9YxzX1Dp1RJMZK1NWOMnioY,17998
|
|
96
|
-
mcp_agent/llm/providers/multipart_converter_tensorzero.py,sha256=Tr3DgogthxqTw04ajblwE8aB3Ft42X7aSXsMlm5FP4k,8619
|
|
97
96
|
mcp_agent/llm/providers/openai_multipart.py,sha256=qKBn7d3jSabnJmVgWweVzqh8q9mBqr09fsPmP92niAQ,6899
|
|
98
97
|
mcp_agent/llm/providers/openai_utils.py,sha256=T4bTCL9f7DsoS_zoKgQKv_FUv_4n98vgbvaUpdWZJr8,1875
|
|
99
98
|
mcp_agent/llm/providers/sampling_converter_anthropic.py,sha256=35WzBWkPklnuMlu5S6XsQIq0YL58NOy8Ja6A_l4m6eM,1612
|
|
@@ -103,7 +102,7 @@ mcp_agent/logging/events.py,sha256=dSJJfuCd59-ZyYTVcf0M4HQd6iXb5k50PSAeoq1CpH0,4
|
|
|
103
102
|
mcp_agent/logging/json_serializer.py,sha256=qkfxnR9ka6OgvwSpM2CggELbEtzzkApm0s_KYz11RDY,5791
|
|
104
103
|
mcp_agent/logging/listeners.py,sha256=_S4Jp5_KWp0kUfrx4BxDdNCeQK3MNT3Zi9AaolPri7A,6648
|
|
105
104
|
mcp_agent/logging/logger.py,sha256=v2_D5kWLSS9u4ueSU7q6cWF1oSmTVeAAtgnwR0LrbXI,11056
|
|
106
|
-
mcp_agent/logging/rich_progress.py,sha256=
|
|
105
|
+
mcp_agent/logging/rich_progress.py,sha256=_AMW_ODPs1RXmQ6aTu9je4hmwcCGi3lUmrVAhytq1C4,7462
|
|
107
106
|
mcp_agent/logging/transport.py,sha256=_RVckOdcs_mXv6Jwz-MPe0vVTQEKsbejHdteyK5hBQA,16960
|
|
108
107
|
mcp_agent/mcp/__init__.py,sha256=yxtzSmWBNqRf_nJckqgzYoozyGKja05FvSRLLus_7eM,1100
|
|
109
108
|
mcp_agent/mcp/common.py,sha256=MpSC0fLO21RcDz4VApah4C8_LisVGz7OXkR17Xw-9mY,431
|
|
@@ -114,7 +113,7 @@ mcp_agent/mcp/hf_auth.py,sha256=7szw4rkwRyK3J-sUTcVZHdwoLIZqlYo8XolJnZdjOww,4571
|
|
|
114
113
|
mcp_agent/mcp/interfaces.py,sha256=pe8WKvu3dnNnPWmrkDlu15xdkhuRDAjLUMn2vIE0Mj8,7963
|
|
115
114
|
mcp_agent/mcp/logger_textio.py,sha256=vljC1BtNTCxBAda9ExqNB-FwVNUZIuJT3h1nWmCjMws,3172
|
|
116
115
|
mcp_agent/mcp/mcp_agent_client_session.py,sha256=ssRgxMOzyCPyAr25AeRBz3Xr-08OBdmsJf8A-ofc3bY,9115
|
|
117
|
-
mcp_agent/mcp/mcp_aggregator.py,sha256=
|
|
116
|
+
mcp_agent/mcp/mcp_aggregator.py,sha256=3L_UDxg7nz_Cp1hHVxxCrhDybxg-Bg2QH8e0F8x1_W4,51377
|
|
118
117
|
mcp_agent/mcp/mcp_connection_manager.py,sha256=dJxjnv2IRzlFIxrbPFl39-pmGcZHgyeMXVlMfqpREhE,17974
|
|
119
118
|
mcp_agent/mcp/mime_utils.py,sha256=difepNR_gpb4MpMLkBRAoyhDk-AjXUHTiqKvT_VwS1o,1805
|
|
120
119
|
mcp_agent/mcp/prompt_message_multipart.py,sha256=XDlFODtOIepespQ23hvh37i3GF2L9Hju4AdNHijwe9k,4350
|
|
@@ -123,7 +122,7 @@ mcp_agent/mcp/prompt_serialization.py,sha256=MQY6QxnhQTiq0oBDsyRzFtX8sBiovUjzUFX
|
|
|
123
122
|
mcp_agent/mcp/resource_utils.py,sha256=K4XY8bihmBMleRTZ2viMPiD2Y2HWxFnlgIJi6dd_PYE,6588
|
|
124
123
|
mcp_agent/mcp/sampling.py,sha256=PpUtLDvu9K3U8445z6m_esHeKstdSr-JBTyn9d8ppJM,6665
|
|
125
124
|
mcp_agent/mcp/helpers/__init__.py,sha256=jJP_yVlewL0hePTX_k_MAnUmOzxpr0Tr_rXYZYeE2WY,456
|
|
126
|
-
mcp_agent/mcp/helpers/content_helpers.py,sha256=
|
|
125
|
+
mcp_agent/mcp/helpers/content_helpers.py,sha256=zrM0cUu9U-C9dRPszOZ6vxh0fquQhFODeDEXaC2TkBg,5173
|
|
127
126
|
mcp_agent/mcp/helpers/server_config_helpers.py,sha256=MkyZB2ZzfsBNsqyGd0LfUOoXxhAMS28VF-f747cJJpY,978
|
|
128
127
|
mcp_agent/mcp/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
129
128
|
mcp_agent/mcp/prompts/__main__.py,sha256=gr1Tdz9fcK0EXjEuZg_BOnKUmvhYq5AH2lFZicVyNb0,237
|
|
@@ -155,6 +154,24 @@ mcp_agent/resources/examples/researcher/fastagent.config.yaml,sha256=TbVMHQCKcyt
|
|
|
155
154
|
mcp_agent/resources/examples/researcher/researcher-eval.py,sha256=CR9m4lyoXijS1whvsBDuk6IA-RmNc6iOYbtloETkITY,1833
|
|
156
155
|
mcp_agent/resources/examples/researcher/researcher-imp.py,sha256=oJxSVnLbZfIn71QbQR1E6j_m_UBrOOGP4SVljXErHLQ,7879
|
|
157
156
|
mcp_agent/resources/examples/researcher/researcher.py,sha256=SZfExi-FfwYETzGt2O3caS3L5E6EemV3IUrJHyzZqHI,1333
|
|
157
|
+
mcp_agent/resources/examples/tensorzero/.env.sample,sha256=khV_apbP4XprpNuIaeVicnHaVHEkwIdWGyZCvW1OLDc,35
|
|
158
|
+
mcp_agent/resources/examples/tensorzero/Makefile,sha256=BOvcJvPBAJN2MDh8brLsy2leHGwuT_bBjPzakOsUSCU,427
|
|
159
|
+
mcp_agent/resources/examples/tensorzero/README.md,sha256=xsA1qWjg2mI240jlbeFYWjYm_pQLsGeQiPiSlEtayeQ,2126
|
|
160
|
+
mcp_agent/resources/examples/tensorzero/agent.py,sha256=8x_W-_LHbwC_onXWZfDIbVQe2PX6qEZ5JRjwIWGOEr4,1272
|
|
161
|
+
mcp_agent/resources/examples/tensorzero/docker-compose.yml,sha256=YgmWgoHHDDTGeqRlU8Z21mLdEqo48IoKZsnlXaDZkrc,2851
|
|
162
|
+
mcp_agent/resources/examples/tensorzero/fastagent.config.yaml,sha256=3uJJ9p-0evDG48zr2QneektO4fe_h4uRPh1dyWfe7-k,355
|
|
163
|
+
mcp_agent/resources/examples/tensorzero/image_demo.py,sha256=BVdCMg1o8r9A9cgKEPmEO84CBeBOxz9zNF9yBxyYCp4,2122
|
|
164
|
+
mcp_agent/resources/examples/tensorzero/simple_agent.py,sha256=BjbD6k9C5zNJl_vAzKKIVSyghYuOsF-LOzqxMTnEOJ4,858
|
|
165
|
+
mcp_agent/resources/examples/tensorzero/demo_images/clam.jpg,sha256=K1NWrhz5QMfgjZfDMMIVctWwbwTyJSsPHLDaUMbcn18,22231
|
|
166
|
+
mcp_agent/resources/examples/tensorzero/demo_images/crab.png,sha256=W7R3bSKKDmZCjxJEmFk0pBXVhXXhfPGM1gIiVuv_eu4,58413
|
|
167
|
+
mcp_agent/resources/examples/tensorzero/demo_images/shrimp.png,sha256=2r3c6yHE25MpVRDTTwxjAGs1ShJ2UI-qxJqbxa-9ew4,7806
|
|
168
|
+
mcp_agent/resources/examples/tensorzero/mcp_server/Dockerfile,sha256=pujKW5xDY5q0PvIYsn8Wsh9Tz2F3sVuKTJc3o8lgt4M,681
|
|
169
|
+
mcp_agent/resources/examples/tensorzero/mcp_server/entrypoint.sh,sha256=yLUXZKd4mF2k_ZFAd6125ZstLmrtksePpfgCNdewSyU,1123
|
|
170
|
+
mcp_agent/resources/examples/tensorzero/mcp_server/mcp_server.py,sha256=8Wr6VzNFihri3mv9wLo37i5Ly1VWL4s4jSnfiRG7Ez0,933
|
|
171
|
+
mcp_agent/resources/examples/tensorzero/mcp_server/pyproject.toml,sha256=3AppZ_HbIEmRGg_phGuEOq-Q63CY_IIsrIBr658ka9U,228
|
|
172
|
+
mcp_agent/resources/examples/tensorzero/tensorzero_config/system_schema.json,sha256=q81vtb8eyX1gU0qOhT_BFNo7nI2Lg2o-D_Bvp8watEI,626
|
|
173
|
+
mcp_agent/resources/examples/tensorzero/tensorzero_config/system_template.minijinja,sha256=_Ekz9YuE76pkmwtcMNJeDlih2U5vPRgFB5wFojAVde8,501
|
|
174
|
+
mcp_agent/resources/examples/tensorzero/tensorzero_config/tensorzero.toml,sha256=wYDKzHyX0A2x42d1vF5a72ot304iTP8_i5Y1rzAcCEA,890
|
|
158
175
|
mcp_agent/resources/examples/workflows/chaining.py,sha256=tY0kA0U8s2rceAO4ogZFtpQEkiUWcrYnYDgHu_-4G50,889
|
|
159
176
|
mcp_agent/resources/examples/workflows/evaluator.py,sha256=XJXrk5r1hrJzfZAMtQ7WIggy6qPttMJG1yqxYELO7C4,3101
|
|
160
177
|
mcp_agent/resources/examples/workflows/fastagent.config.yaml,sha256=qaxk-p7Pl7JepdL3a7BTl0CIp4LHCXies7pFdVWS9xk,783
|
|
@@ -168,8 +185,8 @@ mcp_agent/resources/examples/workflows/short_story.txt,sha256=X3y_1AyhLFN2AKzCKv
|
|
|
168
185
|
mcp_agent/tools/tool_definition.py,sha256=L3Pxl-uLEXqlVoo-bYuFTFALeI-2pIU44YgFhsTKEtM,398
|
|
169
186
|
mcp_agent/ui/console_display.py,sha256=XXrHr950wSBSedEKUaaGkXjOzuFpQYzUKKiyaZ58Mps,28280
|
|
170
187
|
mcp_agent/ui/console_display_legacy.py,sha256=sm2v61-IPVafbF7uUaOyhO2tW_zgFWOjNS83IEWqGgI,14931
|
|
171
|
-
fast_agent_mcp-0.2.
|
|
172
|
-
fast_agent_mcp-0.2.
|
|
173
|
-
fast_agent_mcp-0.2.
|
|
174
|
-
fast_agent_mcp-0.2.
|
|
175
|
-
fast_agent_mcp-0.2.
|
|
188
|
+
fast_agent_mcp-0.2.51.dist-info/METADATA,sha256=6gg7Cc2qW7R5rVOUtSyhlrbBtZyTEOisFsdU00tohUk,31048
|
|
189
|
+
fast_agent_mcp-0.2.51.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
190
|
+
fast_agent_mcp-0.2.51.dist-info/entry_points.txt,sha256=QaX5kLdI0VdMPRdPUF1nkG_WdLUTNjp_icW6e3EhNYU,232
|
|
191
|
+
fast_agent_mcp-0.2.51.dist-info/licenses/LICENSE,sha256=Gx1L3axA4PnuK4FxsbX87jQ1opoOkSFfHHSytW6wLUU,10935
|
|
192
|
+
fast_agent_mcp-0.2.51.dist-info/RECORD,,
|
|
@@ -76,6 +76,25 @@ EXAMPLE_TYPES = {
|
|
|
76
76
|
],
|
|
77
77
|
"create_subdir": True,
|
|
78
78
|
},
|
|
79
|
+
"tensorzero": {
|
|
80
|
+
"description": "A complete example showcasing the TensorZero integration.\n"
|
|
81
|
+
"Includes the T0 Gateway, an MCP server, an interactive agent, and \n"
|
|
82
|
+
"multi-modal functionality.",
|
|
83
|
+
"files": [
|
|
84
|
+
".env.sample",
|
|
85
|
+
"Makefile",
|
|
86
|
+
"README.md",
|
|
87
|
+
"agent.py",
|
|
88
|
+
"docker-compose.yml",
|
|
89
|
+
"fastagent.config.yaml",
|
|
90
|
+
"image_demo.py",
|
|
91
|
+
"simple_agent.py",
|
|
92
|
+
"mcp_server/",
|
|
93
|
+
"demo_images/",
|
|
94
|
+
"tensorzero_config/"
|
|
95
|
+
],
|
|
96
|
+
"create_subdir": True,
|
|
97
|
+
},
|
|
79
98
|
}
|
|
80
99
|
|
|
81
100
|
|
|
@@ -225,6 +244,27 @@ def copy_example_files(example_type: str, target_dir: Path, force: bool = False)
|
|
|
225
244
|
return created
|
|
226
245
|
|
|
227
246
|
|
|
247
|
+
def copy_project_template(source_dir: Path, dest_dir: Path, console: Console, force: bool = False):
|
|
248
|
+
"""
|
|
249
|
+
Recursively copies a project template directory.
|
|
250
|
+
This is a helper to handle project-based quickstarts like TensorZero.
|
|
251
|
+
"""
|
|
252
|
+
if dest_dir.exists():
|
|
253
|
+
if force:
|
|
254
|
+
console.print(f"[yellow]--force specified. Removing existing directory: {dest_dir}[/yellow]")
|
|
255
|
+
shutil.rmtree(dest_dir)
|
|
256
|
+
else:
|
|
257
|
+
console.print(f"[bold yellow]Directory '{dest_dir.name}' already exists.[/bold yellow] Use --force to overwrite.")
|
|
258
|
+
return False
|
|
259
|
+
|
|
260
|
+
try:
|
|
261
|
+
shutil.copytree(source_dir, dest_dir)
|
|
262
|
+
return True
|
|
263
|
+
except Exception as e:
|
|
264
|
+
console.print(f"[red]Error copying project template: {e}[/red]")
|
|
265
|
+
return False
|
|
266
|
+
|
|
267
|
+
|
|
228
268
|
def show_overview() -> None:
|
|
229
269
|
"""Display an overview of available examples in a nicely formatted table."""
|
|
230
270
|
console.print("\n[bold cyan]fast-agent quickstarts[/bold cyan]")
|
|
@@ -397,6 +437,73 @@ def _show_completion_message(example_type: str, created: list[str]) -> None:
|
|
|
397
437
|
console.print("\n[yellow]No files were created.[/yellow]")
|
|
398
438
|
|
|
399
439
|
|
|
440
|
+
@app.command(name="tensorzero", help="Create the TensorZero integration example project.")
|
|
441
|
+
def tensorzero(
|
|
442
|
+
directory: Path = typer.Argument(
|
|
443
|
+
Path("."),
|
|
444
|
+
help="Directory where the 'tensorzero' project folder will be created.",
|
|
445
|
+
),
|
|
446
|
+
force: bool = typer.Option(False, "--force", "-f", help="Force overwrite if project directory exists"),
|
|
447
|
+
):
|
|
448
|
+
"""Create the TensorZero project example."""
|
|
449
|
+
console.print("[bold green]Setting up the TensorZero quickstart example...[/bold green]")
|
|
450
|
+
|
|
451
|
+
dest_project_dir = directory.resolve() / "tensorzero"
|
|
452
|
+
|
|
453
|
+
# --- Find Source Directory ---
|
|
454
|
+
from importlib.resources import files
|
|
455
|
+
try:
|
|
456
|
+
# This path MUST match the "to" path from hatch_build.py
|
|
457
|
+
source_dir = files("mcp_agent").joinpath("resources").joinpath("examples").joinpath("tensorzero")
|
|
458
|
+
if not source_dir.is_dir():
|
|
459
|
+
raise FileNotFoundError # Fallback to dev mode if resource isn't a dir
|
|
460
|
+
except (ImportError, ModuleNotFoundError, FileNotFoundError):
|
|
461
|
+
console.print("[yellow]Package resources not found. Falling back to development mode.[/yellow]")
|
|
462
|
+
# This path is relative to the project root in a development environment
|
|
463
|
+
source_dir = Path(__file__).parent.parent.parent.parent / "examples" / "tensorzero"
|
|
464
|
+
|
|
465
|
+
if not source_dir.exists() or not source_dir.is_dir():
|
|
466
|
+
console.print(f"[red]Error: Source project directory not found at '{source_dir}'[/red]")
|
|
467
|
+
raise typer.Exit(1)
|
|
468
|
+
|
|
469
|
+
console.print(f"Source directory: [dim]{source_dir}[/dim]")
|
|
470
|
+
console.print(f"Destination: [dim]{dest_project_dir}[/dim]")
|
|
471
|
+
|
|
472
|
+
# --- Copy Project and Show Message ---
|
|
473
|
+
if copy_project_template(source_dir, dest_project_dir, console, force):
|
|
474
|
+
console.print(
|
|
475
|
+
f"\n[bold green]✅ Success![/bold green] Your TensorZero project has been created in: [cyan]{dest_project_dir}[/cyan]"
|
|
476
|
+
)
|
|
477
|
+
console.print("\n[bold yellow]Next Steps:[/bold yellow]")
|
|
478
|
+
console.print("\n1. [bold]Navigate to your new project directory:[/bold]")
|
|
479
|
+
console.print(f" [cyan]cd {dest_project_dir.relative_to(Path.cwd())}[/cyan]")
|
|
480
|
+
|
|
481
|
+
console.print("\n2. [bold]Set up your API keys:[/bold]")
|
|
482
|
+
console.print(" [cyan]cp .env.sample .env[/cyan]")
|
|
483
|
+
console.print(
|
|
484
|
+
" [dim]Then, open the new '.env' file and add your OpenAI or Anthropic API key.[/dim]"
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
console.print("\n3. [bold]Start the required services (TensorZero Gateway & MCP Server):[/bold]")
|
|
488
|
+
console.print(" [cyan]docker compose up --build -d[/cyan]")
|
|
489
|
+
console.print(
|
|
490
|
+
" [dim](This builds and starts the necessary containers in the background)[/dim]"
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
console.print("\n4. [bold]Run the interactive agent:[/bold]")
|
|
494
|
+
console.print(" [cyan]make agent[/cyan] (or `uv run agent.py`)")
|
|
495
|
+
console.print("\nEnjoy exploring the TensorZero integration with fast-agent! ✨")
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
@app.command(name="t0", help="Alias for the TensorZero quickstart.", hidden=True)
|
|
499
|
+
def t0_alias(
|
|
500
|
+
directory: Path = typer.Argument(Path("."), help="Directory for the 'tensorzero' project folder."),
|
|
501
|
+
force: bool = typer.Option(False, "--force", "-f", help="Force overwrite"),
|
|
502
|
+
):
|
|
503
|
+
"""Alias for the `tensorzero` command."""
|
|
504
|
+
tensorzero(directory, force)
|
|
505
|
+
|
|
506
|
+
|
|
400
507
|
@app.callback(invoke_without_command=True)
|
|
401
508
|
def main(ctx: typer.Context) -> None:
|
|
402
509
|
"""Quickstart applications for fast-agent."""
|
mcp_agent/event_progress.py
CHANGED
|
@@ -20,6 +20,7 @@ class ProgressAction(str, Enum):
|
|
|
20
20
|
PLANNING = "Planning"
|
|
21
21
|
READY = "Ready"
|
|
22
22
|
CALLING_TOOL = "Calling Tool"
|
|
23
|
+
TOOL_PROGRESS = "Tool Progress"
|
|
23
24
|
UPDATED = "Updated"
|
|
24
25
|
FINISHED = "Finished"
|
|
25
26
|
SHUTDOWN = "Shutdown"
|
|
@@ -35,6 +36,8 @@ class ProgressEvent(BaseModel):
|
|
|
35
36
|
details: Optional[str] = None
|
|
36
37
|
agent_name: Optional[str] = None
|
|
37
38
|
streaming_tokens: Optional[str] = None # Special field for streaming token count
|
|
39
|
+
progress: Optional[float] = None # Current progress value
|
|
40
|
+
total: Optional[float] = None # Total value for progress calculation
|
|
38
41
|
|
|
39
42
|
def __str__(self) -> str:
|
|
40
43
|
"""Format the progress event for display."""
|
|
@@ -86,6 +89,12 @@ def convert_log_event(event: Event) -> Optional[ProgressEvent]:
|
|
|
86
89
|
details = f"{server_name} ({tool_name})"
|
|
87
90
|
else:
|
|
88
91
|
details = f"{server_name}"
|
|
92
|
+
|
|
93
|
+
# For TOOL_PROGRESS, use progress message if available, otherwise keep default
|
|
94
|
+
if progress_action == ProgressAction.TOOL_PROGRESS:
|
|
95
|
+
progress_message = event_data.get("details", "")
|
|
96
|
+
if progress_message: # Only override if message is non-empty
|
|
97
|
+
details = progress_message
|
|
89
98
|
|
|
90
99
|
elif "augmented_llm" in namespace:
|
|
91
100
|
model = event_data.get("model", "")
|
|
@@ -104,10 +113,19 @@ def convert_log_event(event: Event) -> Optional[ProgressEvent]:
|
|
|
104
113
|
if progress_action == ProgressAction.STREAMING:
|
|
105
114
|
streaming_tokens = event_data.get("details", "")
|
|
106
115
|
|
|
116
|
+
# Extract progress data for TOOL_PROGRESS actions
|
|
117
|
+
progress = None
|
|
118
|
+
total = None
|
|
119
|
+
if progress_action == ProgressAction.TOOL_PROGRESS:
|
|
120
|
+
progress = event_data.get("progress")
|
|
121
|
+
total = event_data.get("total")
|
|
122
|
+
|
|
107
123
|
return ProgressEvent(
|
|
108
124
|
action=ProgressAction(progress_action),
|
|
109
125
|
target=target or "unknown",
|
|
110
126
|
details=details,
|
|
111
127
|
agent_name=event_data.get("agent_name"),
|
|
112
128
|
streaming_tokens=streaming_tokens,
|
|
129
|
+
progress=progress,
|
|
130
|
+
total=total,
|
|
113
131
|
)
|
mcp_agent/llm/model_database.py
CHANGED
|
@@ -22,6 +22,12 @@ class ModelParameters(BaseModel):
|
|
|
22
22
|
tokenizes: List[str]
|
|
23
23
|
"""List of supported content types for tokenization"""
|
|
24
24
|
|
|
25
|
+
json_mode: None | str = "schema"
|
|
26
|
+
"""Structured output style. 'schema', 'object' or None for unsupported """
|
|
27
|
+
|
|
28
|
+
reasoning: None | str = None
|
|
29
|
+
"""Reasoning output style. 'tags' if enclosed in <thinking> tags, 'none' if not used"""
|
|
30
|
+
|
|
25
31
|
|
|
26
32
|
class ModelDatabase:
|
|
27
33
|
"""Centralized model configuration database"""
|
|
@@ -87,6 +93,13 @@ class ModelDatabase:
|
|
|
87
93
|
QWEN_STANDARD = ModelParameters(
|
|
88
94
|
context_window=32000, max_output_tokens=8192, tokenizes=QWEN_MULTIMODAL
|
|
89
95
|
)
|
|
96
|
+
QWEN3_REASONER = ModelParameters(
|
|
97
|
+
context_window=131072,
|
|
98
|
+
max_output_tokens=16384,
|
|
99
|
+
tokenizes=TEXT_ONLY,
|
|
100
|
+
json_mode="object",
|
|
101
|
+
reasoning="tags",
|
|
102
|
+
)
|
|
90
103
|
|
|
91
104
|
FAST_AGENT_STANDARD = ModelParameters(
|
|
92
105
|
context_window=1000000, max_output_tokens=100000, tokenizes=TEXT_ONLY
|
|
@@ -107,7 +120,9 @@ class ModelDatabase:
|
|
|
107
120
|
OPENAI_O3_MINI_SERIES = ModelParameters(
|
|
108
121
|
context_window=200000, max_output_tokens=100000, tokenizes=TEXT_ONLY
|
|
109
122
|
)
|
|
110
|
-
|
|
123
|
+
OPENAI_GPT_OSS_SERIES = ModelParameters(
|
|
124
|
+
context_window=131072, max_output_tokens=32766, tokenizes=TEXT_ONLY, json_mode="object"
|
|
125
|
+
)
|
|
111
126
|
# TODO update to 32000
|
|
112
127
|
ANTHROPIC_OPUS_4_VERSIONED = ModelParameters(
|
|
113
128
|
context_window=200000, max_output_tokens=32000, tokenizes=ANTHROPIC_MULTIMODAL
|
|
@@ -125,6 +140,13 @@ class ModelDatabase:
|
|
|
125
140
|
context_window=65536, max_output_tokens=32768, tokenizes=TEXT_ONLY
|
|
126
141
|
)
|
|
127
142
|
|
|
143
|
+
DEEPSEEK_DISTILL = ModelParameters(
|
|
144
|
+
context_window=131072,
|
|
145
|
+
max_output_tokens=131072,
|
|
146
|
+
tokenizes=TEXT_ONLY,
|
|
147
|
+
json_mode="object",
|
|
148
|
+
reasoning="tags",
|
|
149
|
+
)
|
|
128
150
|
GEMINI_2_5_PRO = ModelParameters(
|
|
129
151
|
context_window=2097152, max_output_tokens=8192, tokenizes=GOOGLE_MULTIMODAL
|
|
130
152
|
)
|
|
@@ -214,6 +236,10 @@ class ModelDatabase:
|
|
|
214
236
|
"grok-3-fast": GROK_3,
|
|
215
237
|
"grok-3-mini-fast": GROK_3,
|
|
216
238
|
"moonshotai/kimi-k2-instruct": KIMI_MOONSHOT,
|
|
239
|
+
"qwen/qwen3-32b": QWEN3_REASONER,
|
|
240
|
+
"deepseek-r1-distill-llama-70b": DEEPSEEK_DISTILL,
|
|
241
|
+
"openai/gpt-oss-120b": OPENAI_GPT_OSS_SERIES,
|
|
242
|
+
"openai/gpt-oss-20b": OPENAI_GPT_OSS_SERIES,
|
|
217
243
|
}
|
|
218
244
|
|
|
219
245
|
@classmethod
|
|
@@ -239,6 +265,18 @@ class ModelDatabase:
|
|
|
239
265
|
params = cls.get_model_params(model)
|
|
240
266
|
return params.tokenizes if params else None
|
|
241
267
|
|
|
268
|
+
@classmethod
|
|
269
|
+
def get_json_mode(cls, model: str) -> str | None:
|
|
270
|
+
"""Get supported json mode (structured output) for a model"""
|
|
271
|
+
params = cls.get_model_params(model)
|
|
272
|
+
return params.json_mode if params else None
|
|
273
|
+
|
|
274
|
+
@classmethod
|
|
275
|
+
def get_reasoning(cls, model: str) -> str | None:
|
|
276
|
+
"""Get supported reasoning output style for a model"""
|
|
277
|
+
params = cls.get_model_params(model)
|
|
278
|
+
return params.reasoning if params else None
|
|
279
|
+
|
|
242
280
|
@classmethod
|
|
243
281
|
def get_default_max_tokens(cls, model: str) -> int:
|
|
244
282
|
"""Get default max_tokens for RequestParams based on model"""
|
mcp_agent/llm/model_factory.py
CHANGED
|
@@ -22,7 +22,7 @@ from mcp_agent.llm.providers.augmented_llm_google_oai import GoogleOaiAugmentedL
|
|
|
22
22
|
from mcp_agent.llm.providers.augmented_llm_groq import GroqAugmentedLLM
|
|
23
23
|
from mcp_agent.llm.providers.augmented_llm_openai import OpenAIAugmentedLLM
|
|
24
24
|
from mcp_agent.llm.providers.augmented_llm_openrouter import OpenRouterAugmentedLLM
|
|
25
|
-
from mcp_agent.llm.providers.
|
|
25
|
+
from mcp_agent.llm.providers.augmented_llm_tensorzero_openai import TensorZeroOpenAIAugmentedLLM
|
|
26
26
|
from mcp_agent.llm.providers.augmented_llm_xai import XAIAugmentedLLM
|
|
27
27
|
from mcp_agent.mcp.interfaces import AugmentedLLMProtocol
|
|
28
28
|
|
|
@@ -39,7 +39,7 @@ LLMClass = Union[
|
|
|
39
39
|
Type[SlowLLM],
|
|
40
40
|
Type[DeepSeekAugmentedLLM],
|
|
41
41
|
Type[OpenRouterAugmentedLLM],
|
|
42
|
-
Type[
|
|
42
|
+
Type[TensorZeroOpenAIAugmentedLLM],
|
|
43
43
|
Type[GoogleNativeAugmentedLLM],
|
|
44
44
|
Type[GenericAugmentedLLM],
|
|
45
45
|
Type[AzureOpenAIAugmentedLLM],
|
|
@@ -144,6 +144,8 @@ class ModelFactory:
|
|
|
144
144
|
"gemini25": "gemini-2.5-flash-preview-05-20",
|
|
145
145
|
"gemini25pro": "gemini-2.5-pro-preview-05-06",
|
|
146
146
|
"kimi": "groq.moonshotai/kimi-k2-instruct",
|
|
147
|
+
"gpt-oss": "groq.openai/gpt-oss-120b",
|
|
148
|
+
"gpt-oss-20b": "groq.openai/gpt-oss-20b",
|
|
147
149
|
}
|
|
148
150
|
|
|
149
151
|
# Mapping of providers to their LLM classes
|
|
@@ -157,7 +159,7 @@ class ModelFactory:
|
|
|
157
159
|
Provider.GOOGLE: GoogleNativeAugmentedLLM,
|
|
158
160
|
Provider.XAI: XAIAugmentedLLM,
|
|
159
161
|
Provider.OPENROUTER: OpenRouterAugmentedLLM,
|
|
160
|
-
Provider.TENSORZERO:
|
|
162
|
+
Provider.TENSORZERO: TensorZeroOpenAIAugmentedLLM,
|
|
161
163
|
Provider.AZURE: AzureOpenAIAugmentedLLM,
|
|
162
164
|
Provider.ALIYUN: AliyunAugmentedLLM,
|
|
163
165
|
Provider.BEDROCK: BedrockAugmentedLLM,
|
|
@@ -12,15 +12,14 @@ class AliyunAugmentedLLM(OpenAIAugmentedLLM):
|
|
|
12
12
|
|
|
13
13
|
def _initialize_default_params(self, kwargs: dict) -> RequestParams:
|
|
14
14
|
"""Initialize Aliyun-specific default parameters"""
|
|
15
|
+
# Get base defaults from parent (includes ModelDatabase lookup)
|
|
16
|
+
base_params = super()._initialize_default_params(kwargs)
|
|
17
|
+
|
|
18
|
+
# Override with Aliyun-specific settings
|
|
15
19
|
chosen_model = kwargs.get("model", DEFAULT_QWEN_MODEL)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
systemPrompt=self.instruction,
|
|
20
|
-
parallel_tool_calls=True,
|
|
21
|
-
max_iterations=20,
|
|
22
|
-
use_history=True,
|
|
23
|
-
)
|
|
20
|
+
base_params.model = chosen_model
|
|
21
|
+
|
|
22
|
+
return base_params
|
|
24
23
|
|
|
25
24
|
def _base_url(self) -> str:
|
|
26
25
|
base_url = None
|
|
@@ -22,15 +22,14 @@ class DeepSeekAugmentedLLM(OpenAIAugmentedLLM):
|
|
|
22
22
|
|
|
23
23
|
def _initialize_default_params(self, kwargs: dict) -> RequestParams:
|
|
24
24
|
"""Initialize Deepseek-specific default parameters"""
|
|
25
|
+
# Get base defaults from parent (includes ModelDatabase lookup)
|
|
26
|
+
base_params = super()._initialize_default_params(kwargs)
|
|
27
|
+
|
|
28
|
+
# Override with Deepseek-specific settings
|
|
25
29
|
chosen_model = kwargs.get("model", DEFAULT_DEEPSEEK_MODEL)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
systemPrompt=self.instruction,
|
|
30
|
-
parallel_tool_calls=True,
|
|
31
|
-
max_iterations=20,
|
|
32
|
-
use_history=True,
|
|
33
|
-
)
|
|
30
|
+
base_params.model = chosen_model
|
|
31
|
+
|
|
32
|
+
return base_params
|
|
34
33
|
|
|
35
34
|
def _base_url(self) -> str:
|
|
36
35
|
base_url = None
|
|
@@ -1,9 +1,22 @@
|
|
|
1
|
+
from typing import List, Tuple, Type, cast
|
|
2
|
+
|
|
3
|
+
from pydantic_core import from_json
|
|
4
|
+
|
|
1
5
|
from mcp_agent.core.request_params import RequestParams
|
|
6
|
+
from mcp_agent.llm.model_database import ModelDatabase
|
|
2
7
|
from mcp_agent.llm.provider_types import Provider
|
|
3
8
|
from mcp_agent.llm.providers.augmented_llm_openai import OpenAIAugmentedLLM
|
|
9
|
+
from mcp_agent.logging.logger import get_logger
|
|
10
|
+
from mcp_agent.mcp.helpers.content_helpers import get_text, split_thinking_content
|
|
11
|
+
from mcp_agent.mcp.interfaces import ModelT
|
|
12
|
+
from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
|
|
4
13
|
|
|
5
14
|
GROQ_BASE_URL = "https://api.groq.com/openai/v1"
|
|
6
|
-
DEFAULT_GROQ_MODEL = ""
|
|
15
|
+
DEFAULT_GROQ_MODEL = "moonshotai/kimi-k2-instruct"
|
|
16
|
+
|
|
17
|
+
### There is some big refactorings to be had quite easily here now:
|
|
18
|
+
### - combining the structured output type handling
|
|
19
|
+
### - deduplicating between this and the deepseek llm
|
|
7
20
|
|
|
8
21
|
|
|
9
22
|
class GroqAugmentedLLM(OpenAIAugmentedLLM):
|
|
@@ -12,15 +25,75 @@ class GroqAugmentedLLM(OpenAIAugmentedLLM):
|
|
|
12
25
|
|
|
13
26
|
def _initialize_default_params(self, kwargs: dict) -> RequestParams:
|
|
14
27
|
"""Initialize Groq default parameters"""
|
|
28
|
+
# Get base defaults from parent (includes ModelDatabase lookup)
|
|
29
|
+
base_params = super()._initialize_default_params(kwargs)
|
|
30
|
+
|
|
31
|
+
# Override with Groq-specific settings
|
|
15
32
|
chosen_model = kwargs.get("model", DEFAULT_GROQ_MODEL)
|
|
33
|
+
base_params.model = chosen_model
|
|
34
|
+
base_params.parallel_tool_calls = False
|
|
35
|
+
|
|
36
|
+
return base_params
|
|
37
|
+
|
|
38
|
+
async def _apply_prompt_provider_specific_structured(
|
|
39
|
+
self,
|
|
40
|
+
multipart_messages: List[PromptMessageMultipart],
|
|
41
|
+
model: Type[ModelT],
|
|
42
|
+
request_params: RequestParams | None = None,
|
|
43
|
+
) -> Tuple[ModelT | None, PromptMessageMultipart]: # noqa: F821
|
|
44
|
+
request_params = self.get_request_params(request_params)
|
|
45
|
+
|
|
46
|
+
assert self.default_request_params
|
|
47
|
+
llm_model = self.default_request_params.model or DEFAULT_GROQ_MODEL
|
|
48
|
+
json_mode: str | None = ModelDatabase.get_json_mode(llm_model)
|
|
49
|
+
if "json_object" == json_mode:
|
|
50
|
+
request_params.response_format = {"type": "json_object"}
|
|
51
|
+
|
|
52
|
+
# Get the full schema and extract just the properties
|
|
53
|
+
full_schema = model.model_json_schema()
|
|
54
|
+
properties = full_schema.get("properties", {})
|
|
55
|
+
required_fields = full_schema.get("required", [])
|
|
56
|
+
|
|
57
|
+
# Create a cleaner format description
|
|
58
|
+
format_description = "{\n"
|
|
59
|
+
for field_name, field_info in properties.items():
|
|
60
|
+
field_type = field_info.get("type", "string")
|
|
61
|
+
description = field_info.get("description", "")
|
|
62
|
+
format_description += f' "{field_name}": "{field_type}"'
|
|
63
|
+
if description:
|
|
64
|
+
format_description += f" // {description}"
|
|
65
|
+
if field_name in required_fields:
|
|
66
|
+
format_description += " // REQUIRED"
|
|
67
|
+
format_description += "\n"
|
|
68
|
+
format_description += "}"
|
|
69
|
+
|
|
70
|
+
multipart_messages[-1].add_text(
|
|
71
|
+
f"""YOU MUST RESPOND WITH A JSON OBJECT IN EXACTLY THIS FORMAT:
|
|
72
|
+
{format_description}
|
|
73
|
+
|
|
74
|
+
IMPORTANT RULES:
|
|
75
|
+
- Respond ONLY with the JSON object, no other text
|
|
76
|
+
- Do NOT include "properties" or "schema" wrappers
|
|
77
|
+
- Do NOT use code fences or markdown
|
|
78
|
+
- The response must be valid JSON that matches the format above
|
|
79
|
+
- All required fields must be included"""
|
|
80
|
+
)
|
|
16
81
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
systemPrompt=self.instruction,
|
|
20
|
-
parallel_tool_calls=False,
|
|
21
|
-
max_iterations=20,
|
|
22
|
-
use_history=True,
|
|
82
|
+
result: PromptMessageMultipart = await self._apply_prompt_provider_specific(
|
|
83
|
+
multipart_messages, request_params
|
|
23
84
|
)
|
|
85
|
+
reasoning_mode: str | None = ModelDatabase.get_reasoning(llm_model)
|
|
86
|
+
try:
|
|
87
|
+
text = get_text(result.content[-1]) or ""
|
|
88
|
+
if "tags" == reasoning_mode:
|
|
89
|
+
_, text = split_thinking_content(text)
|
|
90
|
+
json_data = from_json(text, allow_partial=True)
|
|
91
|
+
validated_model = model.model_validate(json_data)
|
|
92
|
+
return cast("ModelT", validated_model), result
|
|
93
|
+
except ValueError as e:
|
|
94
|
+
logger = get_logger(__name__)
|
|
95
|
+
logger.warning(f"Failed to parse structured response: {str(e)}")
|
|
96
|
+
return None, result
|
|
24
97
|
|
|
25
98
|
def _base_url(self) -> str:
|
|
26
99
|
base_url = None
|