fast-agent-mcp 0.2.45__py3-none-any.whl → 0.2.47__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fast-agent-mcp might be problematic. Click here for more details.

Files changed (35) hide show
  1. {fast_agent_mcp-0.2.45.dist-info → fast_agent_mcp-0.2.47.dist-info}/METADATA +13 -13
  2. {fast_agent_mcp-0.2.45.dist-info → fast_agent_mcp-0.2.47.dist-info}/RECORD +35 -30
  3. mcp_agent/__init__.py +40 -0
  4. mcp_agent/agents/workflow/iterative_planner.py +572 -0
  5. mcp_agent/agents/workflow/orchestrator_agent.py +3 -3
  6. mcp_agent/agents/workflow/orchestrator_models.py +6 -6
  7. mcp_agent/cli/commands/go.py +25 -4
  8. mcp_agent/core/__init__.py +26 -0
  9. mcp_agent/core/agent_types.py +1 -0
  10. mcp_agent/core/direct_decorators.py +168 -16
  11. mcp_agent/core/direct_factory.py +42 -15
  12. mcp_agent/core/fastagent.py +4 -0
  13. mcp_agent/core/mermaid_utils.py +170 -0
  14. mcp_agent/human_input/__init__.py +50 -0
  15. mcp_agent/human_input/form_fields.py +252 -0
  16. mcp_agent/human_input/simple_form.py +111 -0
  17. mcp_agent/llm/augmented_llm.py +11 -2
  18. mcp_agent/llm/augmented_llm_playback.py +5 -3
  19. mcp_agent/llm/model_database.py +2 -7
  20. mcp_agent/llm/providers/augmented_llm_aliyun.py +1 -1
  21. mcp_agent/llm/providers/augmented_llm_anthropic.py +1 -1
  22. mcp_agent/llm/providers/augmented_llm_deepseek.py +4 -2
  23. mcp_agent/llm/providers/augmented_llm_google_oai.py +1 -1
  24. mcp_agent/llm/providers/augmented_llm_openrouter.py +1 -1
  25. mcp_agent/llm/providers/augmented_llm_tensorzero.py +1 -1
  26. mcp_agent/llm/providers/augmented_llm_xai.py +1 -1
  27. mcp_agent/mcp/__init__.py +50 -0
  28. mcp_agent/mcp/helpers/__init__.py +23 -1
  29. mcp_agent/mcp/interfaces.py +13 -2
  30. mcp_agent/py.typed +0 -0
  31. mcp_agent/resources/examples/workflows/orchestrator.py +5 -2
  32. mcp_agent/ui/console_display.py +104 -39
  33. {fast_agent_mcp-0.2.45.dist-info → fast_agent_mcp-0.2.47.dist-info}/WHEEL +0 -0
  34. {fast_agent_mcp-0.2.45.dist-info → fast_agent_mcp-0.2.47.dist-info}/entry_points.txt +0 -0
  35. {fast_agent_mcp-0.2.45.dist-info → fast_agent_mcp-0.2.47.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,50 @@
1
+ """Human input modules for forms and elicitation."""
2
+
3
+ # Export the simple form API
4
+ # Export field types and schema builder
5
+ from mcp_agent.human_input.form_fields import (
6
+ BooleanField,
7
+ EnumField,
8
+ FormSchema,
9
+ IntegerField,
10
+ NumberField,
11
+ # Field classes
12
+ StringField,
13
+ boolean,
14
+ choice,
15
+ date,
16
+ datetime,
17
+ email,
18
+ integer,
19
+ number,
20
+ # Convenience functions
21
+ string,
22
+ url,
23
+ )
24
+ from mcp_agent.human_input.simple_form import ask, ask_sync, form, form_sync
25
+
26
+ __all__ = [
27
+ # Form functions
28
+ "form",
29
+ "form_sync",
30
+ "ask",
31
+ "ask_sync",
32
+ # Schema builder
33
+ "FormSchema",
34
+ # Field classes
35
+ "StringField",
36
+ "IntegerField",
37
+ "NumberField",
38
+ "BooleanField",
39
+ "EnumField",
40
+ # Field convenience functions
41
+ "string",
42
+ "email",
43
+ "url",
44
+ "date",
45
+ "datetime",
46
+ "integer",
47
+ "number",
48
+ "boolean",
49
+ "choice",
50
+ ]
@@ -0,0 +1,252 @@
1
+ """High-level field types for elicitation forms with default support."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any, Dict, List, Optional, Union
5
+
6
+
7
+ @dataclass
8
+ class StringField:
9
+ """String field with validation and default support."""
10
+
11
+ title: Optional[str] = None
12
+ description: Optional[str] = None
13
+ default: Optional[str] = None
14
+ min_length: Optional[int] = None
15
+ max_length: Optional[int] = None
16
+ format: Optional[str] = None # email, uri, date, date-time
17
+
18
+ def to_schema(self) -> Dict[str, Any]:
19
+ """Convert to MCP elicitation schema format."""
20
+ schema: Dict[str, Any] = {"type": "string"}
21
+
22
+ if self.title:
23
+ schema["title"] = self.title
24
+ if self.description:
25
+ schema["description"] = self.description
26
+ if self.default is not None:
27
+ schema["default"] = self.default
28
+ if self.min_length is not None:
29
+ schema["minLength"] = self.min_length
30
+ if self.max_length is not None:
31
+ schema["maxLength"] = self.max_length
32
+ if self.format:
33
+ schema["format"] = self.format
34
+
35
+ return schema
36
+
37
+
38
+ @dataclass
39
+ class IntegerField:
40
+ """Integer field with validation and default support."""
41
+
42
+ title: Optional[str] = None
43
+ description: Optional[str] = None
44
+ default: Optional[int] = None
45
+ minimum: Optional[int] = None
46
+ maximum: Optional[int] = None
47
+
48
+ def to_schema(self) -> Dict[str, Any]:
49
+ """Convert to MCP elicitation schema format."""
50
+ schema: Dict[str, Any] = {"type": "integer"}
51
+
52
+ if self.title:
53
+ schema["title"] = self.title
54
+ if self.description:
55
+ schema["description"] = self.description
56
+ if self.default is not None:
57
+ schema["default"] = self.default
58
+ if self.minimum is not None:
59
+ schema["minimum"] = self.minimum
60
+ if self.maximum is not None:
61
+ schema["maximum"] = self.maximum
62
+
63
+ return schema
64
+
65
+
66
+ @dataclass
67
+ class NumberField:
68
+ """Number (float) field with validation and default support."""
69
+
70
+ title: Optional[str] = None
71
+ description: Optional[str] = None
72
+ default: Optional[float] = None
73
+ minimum: Optional[float] = None
74
+ maximum: Optional[float] = None
75
+
76
+ def to_schema(self) -> Dict[str, Any]:
77
+ """Convert to MCP elicitation schema format."""
78
+ schema: Dict[str, Any] = {"type": "number"}
79
+
80
+ if self.title:
81
+ schema["title"] = self.title
82
+ if self.description:
83
+ schema["description"] = self.description
84
+ if self.default is not None:
85
+ schema["default"] = self.default
86
+ if self.minimum is not None:
87
+ schema["minimum"] = self.minimum
88
+ if self.maximum is not None:
89
+ schema["maximum"] = self.maximum
90
+
91
+ return schema
92
+
93
+
94
+ @dataclass
95
+ class BooleanField:
96
+ """Boolean field with default support."""
97
+
98
+ title: Optional[str] = None
99
+ description: Optional[str] = None
100
+ default: Optional[bool] = None
101
+
102
+ def to_schema(self) -> Dict[str, Any]:
103
+ """Convert to MCP elicitation schema format."""
104
+ schema: Dict[str, Any] = {"type": "boolean"}
105
+
106
+ if self.title:
107
+ schema["title"] = self.title
108
+ if self.description:
109
+ schema["description"] = self.description
110
+ if self.default is not None:
111
+ schema["default"] = self.default
112
+
113
+ return schema
114
+
115
+
116
+ @dataclass
117
+ class EnumField:
118
+ """Enum/choice field with default support."""
119
+
120
+ choices: List[str]
121
+ choice_names: Optional[List[str]] = None # Human-readable names
122
+ title: Optional[str] = None
123
+ description: Optional[str] = None
124
+ default: Optional[str] = None
125
+
126
+ def to_schema(self) -> Dict[str, Any]:
127
+ """Convert to MCP elicitation schema format."""
128
+ schema: Dict[str, Any] = {"type": "string", "enum": self.choices}
129
+
130
+ if self.title:
131
+ schema["title"] = self.title
132
+ if self.description:
133
+ schema["description"] = self.description
134
+ if self.default is not None:
135
+ schema["default"] = self.default
136
+ if self.choice_names:
137
+ schema["enumNames"] = self.choice_names
138
+
139
+ return schema
140
+
141
+
142
+ # Field type union
143
+ FieldType = Union[StringField, IntegerField, NumberField, BooleanField, EnumField]
144
+
145
+
146
+ class FormSchema:
147
+ """High-level form schema builder."""
148
+
149
+ def __init__(self, **fields: FieldType):
150
+ """Create a form schema with named fields."""
151
+ self.fields = fields
152
+ self._required_fields: List[str] = []
153
+
154
+ def required(self, *field_names: str) -> "FormSchema":
155
+ """Mark fields as required."""
156
+ self._required_fields.extend(field_names)
157
+ return self
158
+
159
+ def to_schema(self) -> Dict[str, Any]:
160
+ """Convert to MCP ElicitRequestedSchema format."""
161
+ properties = {}
162
+
163
+ for field_name, field in self.fields.items():
164
+ properties[field_name] = field.to_schema()
165
+
166
+ schema: Dict[str, Any] = {"type": "object", "properties": properties}
167
+
168
+ if self._required_fields:
169
+ schema["required"] = self._required_fields
170
+
171
+ return schema
172
+
173
+
174
+ # Convenience functions for creating fields
175
+ def string(
176
+ title: Optional[str] = None,
177
+ description: Optional[str] = None,
178
+ default: Optional[str] = None,
179
+ min_length: Optional[int] = None,
180
+ max_length: Optional[int] = None,
181
+ format: Optional[str] = None,
182
+ ) -> StringField:
183
+ """Create a string field."""
184
+ return StringField(title, description, default, min_length, max_length, format)
185
+
186
+
187
+ def email(
188
+ title: Optional[str] = None, description: Optional[str] = None, default: Optional[str] = None
189
+ ) -> StringField:
190
+ """Create an email field."""
191
+ return StringField(title, description, default, format="email")
192
+
193
+
194
+ def url(
195
+ title: Optional[str] = None, description: Optional[str] = None, default: Optional[str] = None
196
+ ) -> StringField:
197
+ """Create a URL field."""
198
+ return StringField(title, description, default, format="uri")
199
+
200
+
201
+ def date(
202
+ title: Optional[str] = None, description: Optional[str] = None, default: Optional[str] = None
203
+ ) -> StringField:
204
+ """Create a date field."""
205
+ return StringField(title, description, default, format="date")
206
+
207
+
208
+ def datetime(
209
+ title: Optional[str] = None, description: Optional[str] = None, default: Optional[str] = None
210
+ ) -> StringField:
211
+ """Create a datetime field."""
212
+ return StringField(title, description, default, format="date-time")
213
+
214
+
215
+ def integer(
216
+ title: Optional[str] = None,
217
+ description: Optional[str] = None,
218
+ default: Optional[int] = None,
219
+ minimum: Optional[int] = None,
220
+ maximum: Optional[int] = None,
221
+ ) -> IntegerField:
222
+ """Create an integer field."""
223
+ return IntegerField(title, description, default, minimum, maximum)
224
+
225
+
226
+ def number(
227
+ title: Optional[str] = None,
228
+ description: Optional[str] = None,
229
+ default: Optional[float] = None,
230
+ minimum: Optional[float] = None,
231
+ maximum: Optional[float] = None,
232
+ ) -> NumberField:
233
+ """Create a number field."""
234
+ return NumberField(title, description, default, minimum, maximum)
235
+
236
+
237
+ def boolean(
238
+ title: Optional[str] = None, description: Optional[str] = None, default: Optional[bool] = None
239
+ ) -> BooleanField:
240
+ """Create a boolean field."""
241
+ return BooleanField(title, description, default)
242
+
243
+
244
+ def choice(
245
+ choices: List[str],
246
+ choice_names: Optional[List[str]] = None,
247
+ title: Optional[str] = None,
248
+ description: Optional[str] = None,
249
+ default: Optional[str] = None,
250
+ ) -> EnumField:
251
+ """Create a choice/enum field."""
252
+ return EnumField(choices, choice_names, title, description, default)
@@ -0,0 +1,111 @@
1
+ """Simple form API for elicitation schemas without MCP wrappers."""
2
+
3
+ import asyncio
4
+ from typing import Any, Dict, Optional, Union
5
+
6
+ from mcp.types import ElicitRequestedSchema
7
+
8
+ from mcp_agent.human_input.elicitation_form import show_simple_elicitation_form
9
+ from mcp_agent.human_input.form_fields import FormSchema
10
+
11
+
12
+ async def form(
13
+ schema: Union[FormSchema, ElicitRequestedSchema, Dict[str, Any]],
14
+ message: str = "Please fill out the form",
15
+ title: str = "Form Input",
16
+ ) -> Optional[Dict[str, Any]]:
17
+ """
18
+ Simple form API that presents an elicitation form and returns results.
19
+
20
+ Args:
21
+ schema: FormSchema, ElicitRequestedSchema, or dict schema
22
+ message: Message to display to the user
23
+ title: Title for the form (used as agent_name)
24
+
25
+ Returns:
26
+ Dict with form data if accepted, None if cancelled/declined
27
+
28
+ Example:
29
+ from mcp_agent.human_input.form_fields import FormSchema, string, email, integer
30
+
31
+ schema = FormSchema(
32
+ name=string("Name", "Your full name", min_length=2),
33
+ email=email("Email", "Your email address"),
34
+ age=integer("Age", "Your age", minimum=0, maximum=120)
35
+ ).required("name", "email")
36
+
37
+ result = await form(schema, "Please enter your information")
38
+ if result:
39
+ print(f"Name: {result['name']}, Email: {result['email']}")
40
+ """
41
+ # Convert schema to ElicitRequestedSchema format
42
+ if isinstance(schema, FormSchema):
43
+ elicit_schema = schema.to_schema()
44
+ elif isinstance(schema, dict):
45
+ elicit_schema = schema
46
+ else:
47
+ elicit_schema = schema
48
+
49
+ # Show the form
50
+ action, result = await show_simple_elicitation_form(
51
+ schema=elicit_schema, message=message, agent_name=title, server_name="SimpleForm"
52
+ )
53
+
54
+ # Return results based on action
55
+ if action == "accept":
56
+ return result
57
+ else:
58
+ return None
59
+
60
+
61
+ def form_sync(
62
+ schema: Union[FormSchema, ElicitRequestedSchema, Dict[str, Any]],
63
+ message: str = "Please fill out the form",
64
+ title: str = "Form Input",
65
+ ) -> Optional[Dict[str, Any]]:
66
+ """
67
+ Synchronous wrapper for the form function.
68
+
69
+ Args:
70
+ schema: FormSchema, ElicitRequestedSchema, or dict schema
71
+ message: Message to display to the user
72
+ title: Title for the form (used as agent_name)
73
+
74
+ Returns:
75
+ Dict with form data if accepted, None if cancelled/declined
76
+ """
77
+ return asyncio.run(form(schema, message, title))
78
+
79
+
80
+ # Convenience function with a shorter name
81
+ async def ask(
82
+ schema: Union[FormSchema, ElicitRequestedSchema, Dict[str, Any]],
83
+ message: str = "Please provide the requested information",
84
+ ) -> Optional[Dict[str, Any]]:
85
+ """
86
+ Short alias for form() function.
87
+
88
+ Example:
89
+ from mcp_agent.human_input.form_fields import FormSchema, string, email
90
+
91
+ schema = FormSchema(
92
+ name=string("Name", "Your name"),
93
+ email=email("Email", "Your email")
94
+ ).required("name")
95
+
96
+ result = await ask(schema, "What's your info?")
97
+ """
98
+ return await form(schema, message)
99
+
100
+
101
+ def ask_sync(
102
+ schema: Union[FormSchema, ElicitRequestedSchema, Dict[str, Any]],
103
+ message: str = "Please provide the requested information",
104
+ ) -> Optional[Dict[str, Any]]:
105
+ """
106
+ Synchronous version of ask().
107
+
108
+ Example:
109
+ result = ask_sync(schema, "What's your info?")
110
+ """
111
+ return form_sync(schema, message)
@@ -9,6 +9,7 @@ from typing import (
9
9
  Tuple,
10
10
  Type,
11
11
  TypeVar,
12
+ Union,
12
13
  cast,
13
14
  )
14
15
 
@@ -203,7 +204,7 @@ class AugmentedLLM(ContextDependent, AugmentedLLMProtocol, Generic[MessageParamT
203
204
 
204
205
  async def generate(
205
206
  self,
206
- multipart_messages: List[PromptMessageMultipart],
207
+ multipart_messages: List[Union[PromptMessageMultipart, PromptMessage]],
207
208
  request_params: RequestParams | None = None,
208
209
  ) -> PromptMessageMultipart:
209
210
  """
@@ -212,6 +213,10 @@ class AugmentedLLM(ContextDependent, AugmentedLLMProtocol, Generic[MessageParamT
212
213
  # note - check changes here are mirrored in structured(). i've thought hard about
213
214
  # a strategy to reduce duplication etc, but aiming for simple but imperfect for the moment
214
215
 
216
+ # Convert PromptMessage to PromptMessageMultipart if needed
217
+ if multipart_messages and isinstance(multipart_messages[0], PromptMessage):
218
+ multipart_messages = PromptMessageMultipart.to_multipart(multipart_messages)
219
+
215
220
  # TODO -- create a "fast-agent" control role rather than magic strings
216
221
 
217
222
  if multipart_messages[-1].first_text().startswith("***SAVE_HISTORY"):
@@ -259,12 +264,16 @@ class AugmentedLLM(ContextDependent, AugmentedLLMProtocol, Generic[MessageParamT
259
264
 
260
265
  async def structured(
261
266
  self,
262
- multipart_messages: List[PromptMessageMultipart],
267
+ multipart_messages: List[Union[PromptMessageMultipart, PromptMessage]],
263
268
  model: Type[ModelT],
264
269
  request_params: RequestParams | None = None,
265
270
  ) -> Tuple[ModelT | None, PromptMessageMultipart]:
266
271
  """Return a structured response from the LLM using the provided messages."""
267
272
 
273
+ # Convert PromptMessage to PromptMessageMultipart if needed
274
+ if multipart_messages and isinstance(multipart_messages[0], PromptMessage):
275
+ multipart_messages = PromptMessageMultipart.to_multipart(multipart_messages)
276
+
268
277
  self._precall(multipart_messages)
269
278
  result, assistant_response = await self._apply_prompt_provider_specific_structured(
270
279
  multipart_messages, model, request_params
@@ -1,4 +1,6 @@
1
- from typing import Any, List, Type
1
+ from typing import Any, List, Type, Union
2
+
3
+ from mcp.types import PromptMessage
2
4
 
3
5
  from mcp_agent.core.exceptions import ModelConfigError
4
6
  from mcp_agent.core.prompt import Prompt
@@ -51,7 +53,7 @@ class PlaybackLLM(PassthroughLLM):
51
53
 
52
54
  async def generate(
53
55
  self,
54
- multipart_messages: List[PromptMessageMultipart],
56
+ multipart_messages: List[Union[PromptMessageMultipart, PromptMessage]],
55
57
  request_params: RequestParams | None = None,
56
58
  ) -> PromptMessageMultipart:
57
59
  """
@@ -106,7 +108,7 @@ class PlaybackLLM(PassthroughLLM):
106
108
 
107
109
  async def structured(
108
110
  self,
109
- multipart_messages: List[PromptMessageMultipart],
111
+ multipart_messages: List[Union[PromptMessageMultipart, PromptMessage]],
110
112
  model: Type[ModelT],
111
113
  request_params: RequestParams | None = None,
112
114
  ) -> tuple[ModelT | None, PromptMessageMultipart]:
@@ -130,15 +130,11 @@ class ModelDatabase:
130
130
  )
131
131
 
132
132
  # FIXME: xAI has not documented the max output tokens for Grok 4. Using Grok 3 as a placeholder. Will need to update when available (if ever)
133
- GROK_4 = ModelParameters(
134
- context_window=256000, max_output_tokens=16385, tokenizes=XAI_VISION
135
- )
133
+ GROK_4 = ModelParameters(context_window=256000, max_output_tokens=16385, tokenizes=XAI_VISION)
136
134
 
137
135
  # Source for Grok 3 max output: https://www.reddit.com/r/grok/comments/1j7209p/exploring_grok_3_beta_output_capacity_a_simple/
138
136
  # xAI does not document Grok 3 max output tokens, using the above source as a reference.
139
- GROK_3 = ModelParameters(
140
- context_window=131072, max_output_tokens=16385, tokenizes=TEXT_ONLY
141
- )
137
+ GROK_3 = ModelParameters(context_window=131072, max_output_tokens=16385, tokenizes=TEXT_ONLY)
142
138
 
143
139
  # Model configuration database
144
140
  MODELS: Dict[str, ModelParameters] = {
@@ -193,7 +189,6 @@ class ModelDatabase:
193
189
  "claude-3-7-sonnet": ANTHROPIC_37_SERIES,
194
190
  "claude-3-7-sonnet-20250219": ANTHROPIC_37_SERIES,
195
191
  "claude-3-7-sonnet-latest": ANTHROPIC_37_SERIES,
196
- "claude-sonnet-4": ANTHROPIC_SONNET_4_VERSIONED,
197
192
  "claude-sonnet-4-0": ANTHROPIC_SONNET_4_VERSIONED,
198
193
  "claude-sonnet-4-20250514": ANTHROPIC_SONNET_4_VERSIONED,
199
194
  "claude-opus-4": ANTHROPIC_OPUS_4_VERSIONED,
@@ -18,7 +18,7 @@ class AliyunAugmentedLLM(OpenAIAugmentedLLM):
18
18
  model=chosen_model,
19
19
  systemPrompt=self.instruction,
20
20
  parallel_tool_calls=True,
21
- max_iterations=10,
21
+ max_iterations=20,
22
22
  use_history=True,
23
23
  )
24
24
 
@@ -46,7 +46,7 @@ from mcp_agent.llm.augmented_llm import (
46
46
  )
47
47
  from mcp_agent.logging.logger import get_logger
48
48
 
49
- DEFAULT_ANTHROPIC_MODEL = "claude-3-7-sonnet-latest"
49
+ DEFAULT_ANTHROPIC_MODEL = "claude-sonnet-4-0"
50
50
 
51
51
 
52
52
  class AnthropicAugmentedLLM(AugmentedLLM[MessageParam, Message]):
@@ -28,7 +28,7 @@ class DeepSeekAugmentedLLM(OpenAIAugmentedLLM):
28
28
  model=chosen_model,
29
29
  systemPrompt=self.instruction,
30
30
  parallel_tool_calls=True,
31
- max_iterations=10,
31
+ max_iterations=20,
32
32
  use_history=True,
33
33
  )
34
34
 
@@ -85,7 +85,9 @@ class DeepSeekAugmentedLLM(OpenAIAugmentedLLM):
85
85
  return self._structured_from_multipart(result, model)
86
86
 
87
87
  @classmethod
88
- def convert_message_to_message_param(cls, message: ChatCompletionMessage, **kwargs) -> ChatCompletionAssistantMessageParam:
88
+ def convert_message_to_message_param(
89
+ cls, message: ChatCompletionMessage, **kwargs
90
+ ) -> ChatCompletionAssistantMessageParam:
89
91
  """Convert a response object to an input parameter object to allow LLM calls to be chained."""
90
92
  if hasattr(message, "reasoning_content"):
91
93
  message = copy(message)
@@ -18,7 +18,7 @@ class GoogleOaiAugmentedLLM(OpenAIAugmentedLLM):
18
18
  model=chosen_model,
19
19
  systemPrompt=self.instruction,
20
20
  parallel_tool_calls=False,
21
- max_iterations=10,
21
+ max_iterations=20,
22
22
  use_history=True,
23
23
  )
24
24
 
@@ -32,7 +32,7 @@ class OpenRouterAugmentedLLM(OpenAIAugmentedLLM):
32
32
  model=chosen_model, # Will be validated by base class
33
33
  systemPrompt=self.instruction,
34
34
  parallel_tool_calls=True, # Default based on OpenAI provider
35
- max_iterations=10, # Default based on OpenAI provider
35
+ max_iterations=20, # Default based on OpenAI provider
36
36
  use_history=True, # Default based on OpenAI provider
37
37
  )
38
38
 
@@ -92,7 +92,7 @@ class TensorZeroAugmentedLLM(AugmentedLLM[Dict[str, Any], Any]):
92
92
  systemPrompt=self.instruction,
93
93
  maxTokens=4096,
94
94
  use_history=True,
95
- max_iterations=10, # Max iterations for tool use loop
95
+ max_iterations=20, # Max iterations for tool use loop
96
96
  parallel_tool_calls=True,
97
97
  )
98
98
 
@@ -22,7 +22,7 @@ class XAIAugmentedLLM(OpenAIAugmentedLLM):
22
22
  model=chosen_model,
23
23
  systemPrompt=self.instruction,
24
24
  parallel_tool_calls=False,
25
- max_iterations=10,
25
+ max_iterations=20,
26
26
  use_history=True,
27
27
  )
28
28
 
mcp_agent/mcp/__init__.py CHANGED
@@ -0,0 +1,50 @@
1
+ """
2
+ MCP (Model Context Protocol) integration components.
3
+ """
4
+
5
+ from mcp.types import PromptMessage
6
+
7
+ from .helpers import (
8
+ get_image_data,
9
+ get_resource_text,
10
+ get_resource_uri,
11
+ get_text,
12
+ is_image_content,
13
+ is_resource_content,
14
+ is_resource_link,
15
+ is_text_content,
16
+ )
17
+ from .interfaces import (
18
+ AgentProtocol,
19
+ AugmentedLLMProtocol,
20
+ MCPConnectionManagerProtocol,
21
+ ModelFactoryClassProtocol,
22
+ ModelT,
23
+ ServerConnection,
24
+ ServerRegistryProtocol,
25
+ )
26
+ from .prompt_message_multipart import PromptMessageMultipart
27
+
28
+ __all__ = [
29
+ # Types from mcp.types
30
+ "PromptMessage",
31
+ # Multipart message handling
32
+ "PromptMessageMultipart",
33
+ # Protocol interfaces
34
+ "AugmentedLLMProtocol",
35
+ "AgentProtocol",
36
+ "MCPConnectionManagerProtocol",
37
+ "ServerRegistryProtocol",
38
+ "ServerConnection",
39
+ "ModelFactoryClassProtocol",
40
+ "ModelT",
41
+ # Helper functions
42
+ "get_text",
43
+ "get_image_data",
44
+ "get_resource_uri",
45
+ "is_text_content",
46
+ "is_image_content",
47
+ "is_resource_content",
48
+ "is_resource_link",
49
+ "get_resource_text",
50
+ ]
@@ -1,3 +1,25 @@
1
1
  """
2
2
  Helper modules for working with MCP content.
3
- """
3
+ """
4
+
5
+ from .content_helpers import (
6
+ get_image_data,
7
+ get_resource_text,
8
+ get_resource_uri,
9
+ get_text,
10
+ is_image_content,
11
+ is_resource_content,
12
+ is_resource_link,
13
+ is_text_content,
14
+ )
15
+
16
+ __all__ = [
17
+ "get_text",
18
+ "get_image_data",
19
+ "get_resource_uri",
20
+ "is_text_content",
21
+ "is_image_content",
22
+ "is_resource_content",
23
+ "is_resource_link",
24
+ "get_resource_text",
25
+ ]