fast-agent-mcp 0.2.26__py3-none-any.whl → 0.2.28__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.
- {fast_agent_mcp-0.2.26.dist-info → fast_agent_mcp-0.2.28.dist-info}/METADATA +4 -2
- {fast_agent_mcp-0.2.26.dist-info → fast_agent_mcp-0.2.28.dist-info}/RECORD +25 -20
- mcp_agent/agents/agent.py +1 -17
- mcp_agent/agents/base_agent.py +2 -0
- mcp_agent/config.py +3 -0
- mcp_agent/context.py +2 -0
- mcp_agent/core/agent_app.py +7 -2
- mcp_agent/core/interactive_prompt.py +58 -51
- mcp_agent/llm/augmented_llm_slow.py +42 -0
- mcp_agent/llm/model_factory.py +83 -40
- mcp_agent/llm/provider_types.py +4 -3
- mcp_agent/llm/providers/augmented_llm_google_native.py +459 -0
- mcp_agent/llm/providers/{augmented_llm_google.py → augmented_llm_google_oai.py} +2 -2
- mcp_agent/llm/providers/google_converter.py +361 -0
- mcp_agent/mcp/helpers/server_config_helpers.py +23 -0
- mcp_agent/mcp/mcp_agent_client_session.py +69 -24
- mcp_agent/mcp/mcp_aggregator.py +18 -3
- mcp_agent/mcp/mcp_connection_manager.py +6 -5
- mcp_agent/mcp/prompts/prompt_server.py +12 -4
- mcp_agent/mcp/sampling.py +40 -10
- mcp_agent/mcp_server_registry.py +15 -4
- mcp_agent/tools/tool_definition.py +14 -0
- {fast_agent_mcp-0.2.26.dist-info → fast_agent_mcp-0.2.28.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.2.26.dist-info → fast_agent_mcp-0.2.28.dist-info}/entry_points.txt +0 -0
- {fast_agent_mcp-0.2.26.dist-info → fast_agent_mcp-0.2.28.dist-info}/licenses/LICENSE +0 -0
mcp_agent/llm/model_factory.py
CHANGED
@@ -8,12 +8,14 @@ from mcp_agent.core.exceptions import ModelConfigError
|
|
8
8
|
from mcp_agent.core.request_params import RequestParams
|
9
9
|
from mcp_agent.llm.augmented_llm_passthrough import PassthroughLLM
|
10
10
|
from mcp_agent.llm.augmented_llm_playback import PlaybackLLM
|
11
|
+
from mcp_agent.llm.augmented_llm_slow import SlowLLM
|
11
12
|
from mcp_agent.llm.provider_types import Provider
|
12
13
|
from mcp_agent.llm.providers.augmented_llm_anthropic import AnthropicAugmentedLLM
|
13
14
|
from mcp_agent.llm.providers.augmented_llm_azure import AzureOpenAIAugmentedLLM
|
14
15
|
from mcp_agent.llm.providers.augmented_llm_deepseek import DeepSeekAugmentedLLM
|
15
16
|
from mcp_agent.llm.providers.augmented_llm_generic import GenericAugmentedLLM
|
16
|
-
from mcp_agent.llm.providers.
|
17
|
+
from mcp_agent.llm.providers.augmented_llm_google_native import GoogleNativeAugmentedLLM
|
18
|
+
from mcp_agent.llm.providers.augmented_llm_google_oai import GoogleOaiAugmentedLLM
|
17
19
|
from mcp_agent.llm.providers.augmented_llm_openai import OpenAIAugmentedLLM
|
18
20
|
from mcp_agent.llm.providers.augmented_llm_openrouter import OpenRouterAugmentedLLM
|
19
21
|
from mcp_agent.llm.providers.augmented_llm_tensorzero import TensorZeroAugmentedLLM
|
@@ -28,9 +30,13 @@ LLMClass = Union[
|
|
28
30
|
Type[OpenAIAugmentedLLM],
|
29
31
|
Type[PassthroughLLM],
|
30
32
|
Type[PlaybackLLM],
|
33
|
+
Type[SlowLLM],
|
31
34
|
Type[DeepSeekAugmentedLLM],
|
32
35
|
Type[OpenRouterAugmentedLLM],
|
33
36
|
Type[TensorZeroAugmentedLLM],
|
37
|
+
Type[GoogleNativeAugmentedLLM],
|
38
|
+
Type[GenericAugmentedLLM],
|
39
|
+
Type[AzureOpenAIAugmentedLLM],
|
34
40
|
]
|
35
41
|
|
36
42
|
|
@@ -60,13 +66,16 @@ class ModelFactory:
|
|
60
66
|
"high": ReasoningEffort.HIGH,
|
61
67
|
}
|
62
68
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
69
|
+
"""
|
70
|
+
TODO -- add context window size information for display/management
|
71
|
+
TODO -- add audio supporting got-4o-audio-preview
|
72
|
+
TODO -- bring model parameter configuration here
|
73
|
+
Mapping of model names to their default providers
|
74
|
+
"""
|
67
75
|
DEFAULT_PROVIDERS = {
|
68
76
|
"passthrough": Provider.FAST_AGENT,
|
69
77
|
"playback": Provider.FAST_AGENT,
|
78
|
+
"slow": Provider.FAST_AGENT,
|
70
79
|
"gpt-4o": Provider.OPENAI,
|
71
80
|
"gpt-4o-mini": Provider.OPENAI,
|
72
81
|
"gpt-4.1": Provider.OPENAI,
|
@@ -86,22 +95,33 @@ class ModelFactory:
|
|
86
95
|
"claude-3-7-sonnet-latest": Provider.ANTHROPIC,
|
87
96
|
"claude-3-opus-20240229": Provider.ANTHROPIC,
|
88
97
|
"claude-3-opus-latest": Provider.ANTHROPIC,
|
98
|
+
"claude-opus-4-0": Provider.ANTHROPIC,
|
99
|
+
"claude-opus-4-20250514": Provider.ANTHROPIC,
|
100
|
+
"claude-sonnet-4-20250514": Provider.ANTHROPIC,
|
101
|
+
"claude-sonnet-4-0": Provider.ANTHROPIC,
|
89
102
|
"deepseek-chat": Provider.DEEPSEEK,
|
90
|
-
|
103
|
+
"gemini-2.0-flash": Provider.GOOGLE,
|
104
|
+
"gemini-2.5-flash-preview-05-20": Provider.GOOGLE,
|
105
|
+
"gemini-2.5-pro-preview-05-06": Provider.GOOGLE,
|
91
106
|
}
|
92
107
|
|
93
108
|
MODEL_ALIASES = {
|
94
|
-
"sonnet": "claude-
|
109
|
+
"sonnet": "claude-sonnet-4-0",
|
110
|
+
"sonnet4": "claude-sonnet-4-0",
|
95
111
|
"sonnet35": "claude-3-5-sonnet-latest",
|
96
112
|
"sonnet37": "claude-3-7-sonnet-latest",
|
97
|
-
"claude": "claude-
|
113
|
+
"claude": "claude-sonnet-4-0",
|
98
114
|
"haiku": "claude-3-5-haiku-latest",
|
99
115
|
"haiku3": "claude-3-haiku-20240307",
|
100
116
|
"haiku35": "claude-3-5-haiku-latest",
|
101
|
-
"opus": "claude-
|
117
|
+
"opus": "claude-opus-4-0",
|
118
|
+
"opus4": "claude-opus-4-0",
|
102
119
|
"opus3": "claude-3-opus-latest",
|
103
120
|
"deepseekv3": "deepseek-chat",
|
104
121
|
"deepseek": "deepseek-chat",
|
122
|
+
"gemini2": "gemini-2.0-flash",
|
123
|
+
"gemini25": "gemini-2.5-flash-preview-05-20",
|
124
|
+
"gemini25pro": "gemini-2.5-pro-preview-05-06",
|
105
125
|
}
|
106
126
|
|
107
127
|
# Mapping of providers to their LLM classes
|
@@ -111,7 +131,8 @@ class ModelFactory:
|
|
111
131
|
Provider.FAST_AGENT: PassthroughLLM,
|
112
132
|
Provider.DEEPSEEK: DeepSeekAugmentedLLM,
|
113
133
|
Provider.GENERIC: GenericAugmentedLLM,
|
114
|
-
Provider.
|
134
|
+
Provider.GOOGLE_OAI: GoogleOaiAugmentedLLM,
|
135
|
+
Provider.GOOGLE: GoogleNativeAugmentedLLM,
|
115
136
|
Provider.OPENROUTER: OpenRouterAugmentedLLM,
|
116
137
|
Provider.TENSORZERO: TensorZeroAugmentedLLM,
|
117
138
|
Provider.AZURE: AzureOpenAIAugmentedLLM,
|
@@ -121,48 +142,66 @@ class ModelFactory:
|
|
121
142
|
# This overrides the provider-based class selection
|
122
143
|
MODEL_SPECIFIC_CLASSES: Dict[str, LLMClass] = {
|
123
144
|
"playback": PlaybackLLM,
|
145
|
+
"slow": SlowLLM,
|
124
146
|
}
|
125
147
|
|
126
148
|
@classmethod
|
127
149
|
def parse_model_string(cls, model_string: str) -> ModelConfig:
|
128
150
|
"""Parse a model string into a ModelConfig object"""
|
129
|
-
# Check if model string is an alias
|
130
151
|
model_string = cls.MODEL_ALIASES.get(model_string, model_string)
|
131
152
|
parts = model_string.split(".")
|
132
153
|
|
133
|
-
#
|
134
|
-
model_parts = parts.copy()
|
154
|
+
model_name_str = model_string # Default full string as model name initially
|
135
155
|
provider = None
|
136
156
|
reasoning_effort = None
|
157
|
+
parts_for_provider_model = []
|
137
158
|
|
138
|
-
# Check
|
159
|
+
# Check for reasoning effort first (last part)
|
139
160
|
if len(parts) > 1 and parts[-1].lower() in cls.EFFORT_MAP:
|
140
161
|
reasoning_effort = cls.EFFORT_MAP[parts[-1].lower()]
|
141
|
-
|
162
|
+
# Remove effort from parts list for provider/model name determination
|
163
|
+
parts_for_provider_model = parts[:-1]
|
164
|
+
else:
|
165
|
+
parts_for_provider_model = parts[:]
|
166
|
+
|
167
|
+
# Try to match longest possible provider string
|
168
|
+
identified_provider_parts = 0 # How many parts belong to the provider string
|
169
|
+
|
170
|
+
if len(parts_for_provider_model) >= 2:
|
171
|
+
potential_provider_str = f"{parts_for_provider_model[0]}.{parts_for_provider_model[1]}"
|
172
|
+
if any(p.value == potential_provider_str for p in Provider):
|
173
|
+
provider = Provider(potential_provider_str)
|
174
|
+
identified_provider_parts = 2
|
175
|
+
|
176
|
+
if provider is None and len(parts_for_provider_model) >= 1:
|
177
|
+
potential_provider_str = parts_for_provider_model[0]
|
178
|
+
if any(p.value == potential_provider_str for p in Provider):
|
179
|
+
provider = Provider(potential_provider_str)
|
180
|
+
identified_provider_parts = 1
|
181
|
+
|
182
|
+
# Construct model_name from remaining parts
|
183
|
+
if identified_provider_parts > 0:
|
184
|
+
model_name_str = ".".join(parts_for_provider_model[identified_provider_parts:])
|
185
|
+
else:
|
186
|
+
# If no provider prefix was matched, the whole string (after effort removal) is the model name
|
187
|
+
model_name_str = ".".join(parts_for_provider_model)
|
142
188
|
|
143
|
-
#
|
144
|
-
if
|
145
|
-
|
146
|
-
if
|
147
|
-
|
148
|
-
|
189
|
+
# If provider still None, try to get from DEFAULT_PROVIDERS using the model_name_str
|
190
|
+
if provider is None:
|
191
|
+
provider = cls.DEFAULT_PROVIDERS.get(model_name_str)
|
192
|
+
if provider is None:
|
193
|
+
raise ModelConfigError(
|
194
|
+
f"Unknown model or provider for: {model_string}. Model name parsed as '{model_name_str}'"
|
195
|
+
)
|
149
196
|
|
150
|
-
if provider == Provider.TENSORZERO and not
|
197
|
+
if provider == Provider.TENSORZERO and not model_name_str:
|
151
198
|
raise ModelConfigError(
|
152
199
|
f"TensorZero provider requires a function name after the provider "
|
153
200
|
f"(e.g., tensorzero.my-function), got: {model_string}"
|
154
201
|
)
|
155
|
-
# Join remaining parts as model name
|
156
|
-
model_name = ".".join(model_parts)
|
157
|
-
|
158
|
-
# If no provider was found in the string, look it up in defaults
|
159
|
-
if provider is None:
|
160
|
-
provider = cls.DEFAULT_PROVIDERS.get(model_name)
|
161
|
-
if provider is None:
|
162
|
-
raise ModelConfigError(f"Unknown model: {model_name}")
|
163
202
|
|
164
203
|
return ModelConfig(
|
165
|
-
provider=provider, model_name=
|
204
|
+
provider=provider, model_name=model_name_str, reasoning_effort=reasoning_effort
|
166
205
|
)
|
167
206
|
|
168
207
|
@classmethod
|
@@ -179,33 +218,37 @@ class ModelFactory:
|
|
179
218
|
Returns:
|
180
219
|
A callable that takes an agent parameter and returns an LLM instance
|
181
220
|
"""
|
182
|
-
# Parse configuration up front
|
183
221
|
config = cls.parse_model_string(model_string)
|
222
|
+
|
223
|
+
# Ensure provider is valid before trying to access PROVIDER_CLASSES with it
|
224
|
+
if (
|
225
|
+
config.provider not in cls.PROVIDER_CLASSES
|
226
|
+
and config.model_name not in cls.MODEL_SPECIFIC_CLASSES
|
227
|
+
):
|
228
|
+
# This check is important if a provider (like old GOOGLE) is commented out from PROVIDER_CLASSES
|
229
|
+
raise ModelConfigError(
|
230
|
+
f"Provider '{config.provider}' not configured in PROVIDER_CLASSES and model '{config.model_name}' not in MODEL_SPECIFIC_CLASSES."
|
231
|
+
)
|
232
|
+
|
184
233
|
if config.model_name in cls.MODEL_SPECIFIC_CLASSES:
|
185
234
|
llm_class = cls.MODEL_SPECIFIC_CLASSES[config.model_name]
|
186
235
|
else:
|
236
|
+
# This line is now safer due to the check above
|
187
237
|
llm_class = cls.PROVIDER_CLASSES[config.provider]
|
188
238
|
|
189
|
-
# Create a factory function matching the updated attach_llm protocol
|
190
239
|
def factory(
|
191
240
|
agent: Agent, request_params: Optional[RequestParams] = None, **kwargs
|
192
241
|
) -> AugmentedLLMProtocol:
|
193
|
-
# Create base params with parsed model name
|
194
242
|
base_params = RequestParams()
|
195
|
-
base_params.model = config.model_name
|
196
|
-
|
197
|
-
# Add reasoning effort if available
|
243
|
+
base_params.model = config.model_name
|
198
244
|
if config.reasoning_effort:
|
199
245
|
kwargs["reasoning_effort"] = config.reasoning_effort.value
|
200
|
-
|
201
|
-
# Forward all arguments to LLM constructor
|
202
246
|
llm_args = {
|
203
247
|
"agent": agent,
|
204
248
|
"model": config.model_name,
|
205
249
|
"request_params": request_params,
|
206
250
|
**kwargs,
|
207
251
|
}
|
208
|
-
|
209
252
|
llm: AugmentedLLMProtocol = llm_class(**llm_args)
|
210
253
|
return llm
|
211
254
|
|
mcp_agent/llm/provider_types.py
CHANGED
@@ -9,11 +9,12 @@ class Provider(Enum):
|
|
9
9
|
"""Supported LLM providers"""
|
10
10
|
|
11
11
|
ANTHROPIC = "anthropic"
|
12
|
-
OPENAI = "openai"
|
13
|
-
FAST_AGENT = "fast-agent"
|
14
|
-
GOOGLE = "google"
|
15
12
|
DEEPSEEK = "deepseek"
|
13
|
+
FAST_AGENT = "fast-agent"
|
16
14
|
GENERIC = "generic"
|
15
|
+
GOOGLE_OAI = "googleoai" # For Google through OpenAI libraries
|
16
|
+
GOOGLE = "google" # For Google GenAI native library
|
17
|
+
OPENAI = "openai"
|
17
18
|
OPENROUTER = "openrouter"
|
18
19
|
TENSORZERO = "tensorzero" # For TensorZero Gateway
|
19
20
|
AZURE = "azure" # Azure OpenAI Service
|