fast-agent-mcp 0.1.12__py3-none-any.whl → 0.2.0__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.
Files changed (169) hide show
  1. {fast_agent_mcp-0.1.12.dist-info → fast_agent_mcp-0.2.0.dist-info}/METADATA +3 -4
  2. fast_agent_mcp-0.2.0.dist-info/RECORD +123 -0
  3. mcp_agent/__init__.py +75 -0
  4. mcp_agent/agents/agent.py +61 -415
  5. mcp_agent/agents/base_agent.py +522 -0
  6. mcp_agent/agents/workflow/__init__.py +1 -0
  7. mcp_agent/agents/workflow/chain_agent.py +173 -0
  8. mcp_agent/agents/workflow/evaluator_optimizer.py +362 -0
  9. mcp_agent/agents/workflow/orchestrator_agent.py +591 -0
  10. mcp_agent/{workflows/orchestrator → agents/workflow}/orchestrator_models.py +11 -21
  11. mcp_agent/agents/workflow/parallel_agent.py +182 -0
  12. mcp_agent/agents/workflow/router_agent.py +307 -0
  13. mcp_agent/app.py +15 -19
  14. mcp_agent/cli/commands/bootstrap.py +19 -38
  15. mcp_agent/cli/commands/config.py +4 -4
  16. mcp_agent/cli/commands/setup.py +7 -14
  17. mcp_agent/cli/main.py +7 -10
  18. mcp_agent/cli/terminal.py +3 -3
  19. mcp_agent/config.py +25 -40
  20. mcp_agent/context.py +12 -21
  21. mcp_agent/context_dependent.py +3 -5
  22. mcp_agent/core/agent_types.py +10 -7
  23. mcp_agent/core/direct_agent_app.py +179 -0
  24. mcp_agent/core/direct_decorators.py +443 -0
  25. mcp_agent/core/direct_factory.py +476 -0
  26. mcp_agent/core/enhanced_prompt.py +23 -55
  27. mcp_agent/core/exceptions.py +8 -8
  28. mcp_agent/core/fastagent.py +145 -371
  29. mcp_agent/core/interactive_prompt.py +424 -0
  30. mcp_agent/core/mcp_content.py +17 -17
  31. mcp_agent/core/prompt.py +6 -9
  32. mcp_agent/core/request_params.py +6 -3
  33. mcp_agent/core/validation.py +92 -18
  34. mcp_agent/executor/decorator_registry.py +9 -17
  35. mcp_agent/executor/executor.py +8 -17
  36. mcp_agent/executor/task_registry.py +2 -4
  37. mcp_agent/executor/temporal.py +19 -41
  38. mcp_agent/executor/workflow.py +3 -5
  39. mcp_agent/executor/workflow_signal.py +15 -21
  40. mcp_agent/human_input/handler.py +4 -7
  41. mcp_agent/human_input/types.py +2 -3
  42. mcp_agent/llm/__init__.py +2 -0
  43. mcp_agent/llm/augmented_llm.py +450 -0
  44. mcp_agent/llm/augmented_llm_passthrough.py +162 -0
  45. mcp_agent/llm/augmented_llm_playback.py +83 -0
  46. mcp_agent/llm/memory.py +103 -0
  47. mcp_agent/{workflows/llm → llm}/model_factory.py +22 -16
  48. mcp_agent/{workflows/llm → llm}/prompt_utils.py +1 -3
  49. mcp_agent/llm/providers/__init__.py +8 -0
  50. mcp_agent/{workflows/llm → llm/providers}/anthropic_utils.py +8 -25
  51. mcp_agent/{workflows/llm → llm/providers}/augmented_llm_anthropic.py +56 -194
  52. mcp_agent/llm/providers/augmented_llm_deepseek.py +53 -0
  53. mcp_agent/{workflows/llm → llm/providers}/augmented_llm_openai.py +99 -190
  54. mcp_agent/{workflows/llm → llm}/providers/multipart_converter_anthropic.py +72 -71
  55. mcp_agent/{workflows/llm → llm}/providers/multipart_converter_openai.py +65 -71
  56. mcp_agent/{workflows/llm → llm}/providers/openai_multipart.py +16 -44
  57. mcp_agent/{workflows/llm → llm/providers}/openai_utils.py +4 -4
  58. mcp_agent/{workflows/llm → llm}/providers/sampling_converter_anthropic.py +9 -11
  59. mcp_agent/{workflows/llm → llm}/providers/sampling_converter_openai.py +8 -12
  60. mcp_agent/{workflows/llm → llm}/sampling_converter.py +3 -31
  61. mcp_agent/llm/sampling_format_converter.py +37 -0
  62. mcp_agent/logging/events.py +1 -5
  63. mcp_agent/logging/json_serializer.py +7 -6
  64. mcp_agent/logging/listeners.py +20 -23
  65. mcp_agent/logging/logger.py +17 -19
  66. mcp_agent/logging/rich_progress.py +10 -8
  67. mcp_agent/logging/tracing.py +4 -6
  68. mcp_agent/logging/transport.py +22 -22
  69. mcp_agent/mcp/gen_client.py +1 -3
  70. mcp_agent/mcp/interfaces.py +117 -110
  71. mcp_agent/mcp/logger_textio.py +97 -0
  72. mcp_agent/mcp/mcp_agent_client_session.py +7 -7
  73. mcp_agent/mcp/mcp_agent_server.py +8 -8
  74. mcp_agent/mcp/mcp_aggregator.py +102 -143
  75. mcp_agent/mcp/mcp_connection_manager.py +20 -27
  76. mcp_agent/mcp/prompt_message_multipart.py +68 -16
  77. mcp_agent/mcp/prompt_render.py +77 -0
  78. mcp_agent/mcp/prompt_serialization.py +30 -48
  79. mcp_agent/mcp/prompts/prompt_constants.py +18 -0
  80. mcp_agent/mcp/prompts/prompt_helpers.py +327 -0
  81. mcp_agent/mcp/prompts/prompt_load.py +109 -0
  82. mcp_agent/mcp/prompts/prompt_server.py +155 -195
  83. mcp_agent/mcp/prompts/prompt_template.py +35 -66
  84. mcp_agent/mcp/resource_utils.py +7 -14
  85. mcp_agent/mcp/sampling.py +17 -17
  86. mcp_agent/mcp_server/agent_server.py +13 -17
  87. mcp_agent/mcp_server_registry.py +13 -22
  88. mcp_agent/resources/examples/{workflows → in_dev}/agent_build.py +3 -2
  89. mcp_agent/resources/examples/in_dev/slides.py +110 -0
  90. mcp_agent/resources/examples/internal/agent.py +6 -3
  91. mcp_agent/resources/examples/internal/fastagent.config.yaml +8 -2
  92. mcp_agent/resources/examples/internal/job.py +2 -1
  93. mcp_agent/resources/examples/internal/prompt_category.py +1 -1
  94. mcp_agent/resources/examples/internal/prompt_sizing.py +3 -5
  95. mcp_agent/resources/examples/internal/sizer.py +2 -1
  96. mcp_agent/resources/examples/internal/social.py +2 -1
  97. mcp_agent/resources/examples/prompting/agent.py +2 -1
  98. mcp_agent/resources/examples/prompting/image_server.py +4 -8
  99. mcp_agent/resources/examples/prompting/work_with_image.py +19 -0
  100. mcp_agent/ui/console_display.py +16 -20
  101. fast_agent_mcp-0.1.12.dist-info/RECORD +0 -161
  102. mcp_agent/core/agent_app.py +0 -646
  103. mcp_agent/core/agent_utils.py +0 -71
  104. mcp_agent/core/decorators.py +0 -455
  105. mcp_agent/core/factory.py +0 -463
  106. mcp_agent/core/proxies.py +0 -269
  107. mcp_agent/core/types.py +0 -24
  108. mcp_agent/eval/__init__.py +0 -0
  109. mcp_agent/mcp/stdio.py +0 -111
  110. mcp_agent/resources/examples/data-analysis/analysis-campaign.py +0 -188
  111. mcp_agent/resources/examples/data-analysis/analysis.py +0 -65
  112. mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -41
  113. mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -1471
  114. mcp_agent/resources/examples/mcp_researcher/researcher-eval.py +0 -53
  115. mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -66
  116. mcp_agent/resources/examples/researcher/researcher-eval.py +0 -53
  117. mcp_agent/resources/examples/researcher/researcher-imp.py +0 -190
  118. mcp_agent/resources/examples/researcher/researcher.py +0 -38
  119. mcp_agent/resources/examples/workflows/chaining.py +0 -44
  120. mcp_agent/resources/examples/workflows/evaluator.py +0 -78
  121. mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -24
  122. mcp_agent/resources/examples/workflows/human_input.py +0 -25
  123. mcp_agent/resources/examples/workflows/orchestrator.py +0 -73
  124. mcp_agent/resources/examples/workflows/parallel.py +0 -78
  125. mcp_agent/resources/examples/workflows/router.py +0 -53
  126. mcp_agent/resources/examples/workflows/sse.py +0 -23
  127. mcp_agent/telemetry/__init__.py +0 -0
  128. mcp_agent/telemetry/usage_tracking.py +0 -18
  129. mcp_agent/workflows/__init__.py +0 -0
  130. mcp_agent/workflows/embedding/__init__.py +0 -0
  131. mcp_agent/workflows/embedding/embedding_base.py +0 -61
  132. mcp_agent/workflows/embedding/embedding_cohere.py +0 -49
  133. mcp_agent/workflows/embedding/embedding_openai.py +0 -46
  134. mcp_agent/workflows/evaluator_optimizer/__init__.py +0 -0
  135. mcp_agent/workflows/evaluator_optimizer/evaluator_optimizer.py +0 -481
  136. mcp_agent/workflows/intent_classifier/__init__.py +0 -0
  137. mcp_agent/workflows/intent_classifier/intent_classifier_base.py +0 -120
  138. mcp_agent/workflows/intent_classifier/intent_classifier_embedding.py +0 -134
  139. mcp_agent/workflows/intent_classifier/intent_classifier_embedding_cohere.py +0 -45
  140. mcp_agent/workflows/intent_classifier/intent_classifier_embedding_openai.py +0 -45
  141. mcp_agent/workflows/intent_classifier/intent_classifier_llm.py +0 -161
  142. mcp_agent/workflows/intent_classifier/intent_classifier_llm_anthropic.py +0 -60
  143. mcp_agent/workflows/intent_classifier/intent_classifier_llm_openai.py +0 -60
  144. mcp_agent/workflows/llm/__init__.py +0 -0
  145. mcp_agent/workflows/llm/augmented_llm.py +0 -753
  146. mcp_agent/workflows/llm/augmented_llm_passthrough.py +0 -241
  147. mcp_agent/workflows/llm/augmented_llm_playback.py +0 -109
  148. mcp_agent/workflows/llm/providers/__init__.py +0 -8
  149. mcp_agent/workflows/llm/sampling_format_converter.py +0 -22
  150. mcp_agent/workflows/orchestrator/__init__.py +0 -0
  151. mcp_agent/workflows/orchestrator/orchestrator.py +0 -578
  152. mcp_agent/workflows/parallel/__init__.py +0 -0
  153. mcp_agent/workflows/parallel/fan_in.py +0 -350
  154. mcp_agent/workflows/parallel/fan_out.py +0 -187
  155. mcp_agent/workflows/parallel/parallel_llm.py +0 -166
  156. mcp_agent/workflows/router/__init__.py +0 -0
  157. mcp_agent/workflows/router/router_base.py +0 -368
  158. mcp_agent/workflows/router/router_embedding.py +0 -240
  159. mcp_agent/workflows/router/router_embedding_cohere.py +0 -59
  160. mcp_agent/workflows/router/router_embedding_openai.py +0 -59
  161. mcp_agent/workflows/router/router_llm.py +0 -320
  162. mcp_agent/workflows/swarm/__init__.py +0 -0
  163. mcp_agent/workflows/swarm/swarm.py +0 -320
  164. mcp_agent/workflows/swarm/swarm_anthropic.py +0 -42
  165. mcp_agent/workflows/swarm/swarm_openai.py +0 -41
  166. {fast_agent_mcp-0.1.12.dist-info → fast_agent_mcp-0.2.0.dist-info}/WHEEL +0 -0
  167. {fast_agent_mcp-0.1.12.dist-info → fast_agent_mcp-0.2.0.dist-info}/entry_points.txt +0 -0
  168. {fast_agent_mcp-0.1.12.dist-info → fast_agent_mcp-0.2.0.dist-info}/licenses/LICENSE +0 -0
  169. /mcp_agent/{workflows/orchestrator → agents/workflow}/orchestrator_prompts.py +0 -0
@@ -1,29 +1,25 @@
1
- from typing import Dict, Any
2
-
3
- from openai.types.chat import (
4
- ChatCompletionMessage,
5
- )
1
+ from typing import Any, Dict
6
2
 
7
3
  from mcp.types import (
8
4
  PromptMessage,
9
5
  )
10
-
11
- from mcp_agent.workflows.llm.sampling_format_converter import (
12
- SamplingFormatConverter,
6
+ from openai.types.chat import (
7
+ ChatCompletionMessage,
13
8
  )
14
9
 
10
+ from mcp_agent.llm.sampling_format_converter import (
11
+ ProviderFormatConverter,
12
+ )
15
13
  from mcp_agent.logging.logger import get_logger
16
14
 
17
15
  _logger = get_logger(__name__)
18
16
 
19
17
 
20
- class OpenAISamplingConverter(
21
- SamplingFormatConverter[Dict[str, Any], ChatCompletionMessage]
22
- ):
18
+ class OpenAISamplingConverter(ProviderFormatConverter[Dict[str, Any], ChatCompletionMessage]):
23
19
  @classmethod
24
20
  def from_prompt_message(cls, message: PromptMessage) -> Dict[str, Any]:
25
21
  """Convert an MCP PromptMessage to an OpenAI message dict."""
26
- from mcp_agent.workflows.llm.providers.multipart_converter_openai import (
22
+ from mcp_agent.llm.providers.multipart_converter_openai import (
27
23
  OpenAIConverter,
28
24
  )
29
25
 
@@ -9,12 +9,11 @@ from mcp.types import (
9
9
  CreateMessageRequestParams,
10
10
  CreateMessageResult,
11
11
  SamplingMessage,
12
- StopReason,
13
12
  TextContent,
14
13
  )
15
14
 
16
- from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
17
15
  from mcp_agent.mcp.interfaces import RequestParams
16
+ from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
18
17
 
19
18
 
20
19
  class SamplingConverter:
@@ -63,31 +62,7 @@ class SamplingConverter:
63
62
  )
64
63
 
65
64
  @staticmethod
66
- def create_message_result(
67
- response: str, model: str, stop_reason: StopReason = "endTurn"
68
- ) -> CreateMessageResult:
69
- """
70
- Create a CreateMessageResult from an LLM response.
71
-
72
- Args:
73
- response: Text response from the LLM
74
- model: Model identifier
75
- stop_reason: Reason generation stopped
76
-
77
- Returns:
78
- CreateMessageResult suitable for returning to MCP
79
- """
80
- return CreateMessageResult(
81
- role="assistant",
82
- content=TextContent(type="text", text=response),
83
- model=model,
84
- stopReason=stop_reason,
85
- )
86
-
87
- @staticmethod
88
- def error_result(
89
- error_message: str, model: Optional[str] = None
90
- ) -> CreateMessageResult:
65
+ def error_result(error_message: str, model: Optional[str] = None) -> CreateMessageResult:
91
66
  """
92
67
  Create an error result.
93
68
 
@@ -118,7 +93,4 @@ class SamplingConverter:
118
93
  Returns:
119
94
  List of PromptMessageMultipart objects, each with a single content item
120
95
  """
121
- return [
122
- SamplingConverter.sampling_message_to_prompt_message(msg)
123
- for msg in messages
124
- ]
96
+ return [SamplingConverter.sampling_message_to_prompt_message(msg) for msg in messages]
@@ -0,0 +1,37 @@
1
+ from typing import Generic, List, Protocol, TypeVar
2
+
3
+ from mcp.types import PromptMessage
4
+
5
+ from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
6
+
7
+ # Define covariant type variables
8
+ MessageParamT_co = TypeVar("MessageParamT_co", covariant=True)
9
+ MessageT_co = TypeVar("MessageT_co", covariant=True)
10
+
11
+
12
+ class ProviderFormatConverter(Protocol, Generic[MessageParamT_co, MessageT_co]):
13
+ """Conversions between LLM provider and MCP types"""
14
+
15
+ @classmethod
16
+ def from_prompt_message(cls, message: PromptMessage) -> MessageParamT_co:
17
+ """Convert an MCP PromptMessage to a provider-specific message parameter."""
18
+ ...
19
+
20
+ @classmethod
21
+ def from_mutlipart_prompts(
22
+ cls, messages: List[PromptMessageMultipart]
23
+ ) -> List[MessageParamT_co]:
24
+ """Convert a list of PromptMessageMultiparts to a list of provider-specific implementations"""
25
+ ...
26
+
27
+
28
+ class BasicFormatConverter(ProviderFormatConverter[PromptMessage, PromptMessage]):
29
+ @classmethod
30
+ def from_prompt_message(cls, message: PromptMessage) -> PromptMessage:
31
+ return message
32
+
33
+ @classmethod
34
+ def from_multipart_prompts(
35
+ cls, messages: List[PromptMessageMultipart]
36
+ ) -> List[PromptMessageMultipart]:
37
+ return messages
@@ -4,7 +4,6 @@ Events and event filters for the logger module for the MCP Agent
4
4
 
5
5
  import logging
6
6
  import random
7
-
8
7
  from datetime import datetime
9
8
  from typing import (
10
9
  Any,
@@ -15,7 +14,6 @@ from typing import (
15
14
 
16
15
  from pydantic import BaseModel, ConfigDict, Field
17
16
 
18
-
19
17
  EventType = Literal["debug", "info", "warning", "error", "progress"]
20
18
  """Broad categories for events (severity or role)."""
21
19
 
@@ -86,9 +84,7 @@ class EventFilter(BaseModel):
86
84
  return False
87
85
 
88
86
  # 3) Filter by namespace prefix
89
- if self.namespaces and not any(
90
- event.namespace.startswith(ns) for ns in self.namespaces
91
- ):
87
+ if self.namespaces and not any(event.namespace.startswith(ns) for ns in self.namespaces):
92
88
  return False
93
89
 
94
90
  # 4) Minimum severity
@@ -1,13 +1,14 @@
1
+ import dataclasses
2
+ import inspect
1
3
  import os
2
4
  import warnings
3
- from typing import Any, Dict, Iterable, Set
4
- from datetime import datetime, date
5
+ from datetime import date, datetime
5
6
  from decimal import Decimal
7
+ from enum import Enum
6
8
  from pathlib import Path
9
+ from typing import Any, Dict, Iterable, Set
7
10
  from uuid import UUID
8
- from enum import Enum
9
- import dataclasses
10
- import inspect
11
+
11
12
  import httpx
12
13
 
13
14
  from mcp_agent.logging import logger
@@ -34,7 +35,7 @@ class JSONSerializer:
34
35
  "refresh_token",
35
36
  }
36
37
 
37
- def __init__(self):
38
+ def __init__(self) -> None:
38
39
  # Set of already processed objects to prevent infinite recursion
39
40
  self._processed_objects: Set[int] = set()
40
41
  # Check if secrets should be logged in full
@@ -5,12 +5,11 @@ Listeners for the logger module of MCP Agent.
5
5
  import asyncio
6
6
  import logging
7
7
  import time
8
-
9
8
  from abc import ABC, abstractmethod
10
9
  from typing import Dict, List
11
10
 
12
- from mcp_agent.logging.events import Event, EventFilter, EventType
13
11
  from mcp_agent.event_progress import convert_log_event
12
+ from mcp_agent.logging.events import Event, EventFilter, EventType
14
13
 
15
14
 
16
15
  class EventListener(ABC):
@@ -27,11 +26,11 @@ class LifecycleAwareListener(EventListener):
27
26
  The event bus calls these at bus start/stop time.
28
27
  """
29
28
 
30
- async def start(self):
29
+ async def start(self) -> None:
31
30
  """Start an event listener, usually when the event bus is set up."""
32
31
  pass
33
32
 
34
- async def stop(self):
33
+ async def stop(self) -> None:
35
34
  """Stop an event listener, usually when the event bus is shutting down."""
36
35
  pass
37
36
 
@@ -42,7 +41,7 @@ class FilteredListener(LifecycleAwareListener):
42
41
  Subclasses override _handle_matched_event().
43
42
  """
44
43
 
45
- def __init__(self, event_filter: EventFilter | None = None):
44
+ def __init__(self, event_filter: EventFilter | None = None) -> None:
46
45
  """
47
46
  Initialize the listener.
48
47
  Args:
@@ -50,11 +49,11 @@ class FilteredListener(LifecycleAwareListener):
50
49
  """
51
50
  self.filter = event_filter
52
51
 
53
- async def handle_event(self, event):
52
+ async def handle_event(self, event) -> None:
54
53
  if not self.filter or self.filter.matches(event):
55
54
  await self.handle_matched_event(event)
56
55
 
57
- async def handle_matched_event(self, event: Event):
56
+ async def handle_matched_event(self, event: Event) -> None:
58
57
  """Process an event that matches the filter."""
59
58
  pass
60
59
 
@@ -68,7 +67,7 @@ class LoggingListener(FilteredListener):
68
67
  self,
69
68
  event_filter: EventFilter | None = None,
70
69
  logger: logging.Logger | None = None,
71
- ):
70
+ ) -> None:
72
71
  """
73
72
  Initialize the listener.
74
73
  Args:
@@ -77,7 +76,7 @@ class LoggingListener(FilteredListener):
77
76
  super().__init__(event_filter=event_filter)
78
77
  self.logger = logger or logging.getLogger("mcp_agent")
79
78
 
80
- async def handle_matched_event(self, event):
79
+ async def handle_matched_event(self, event) -> None:
81
80
  level_map: Dict[EventType, int] = {
82
81
  "debug": logging.DEBUG,
83
82
  "info": logging.INFO,
@@ -113,7 +112,7 @@ class ProgressListener(LifecycleAwareListener):
113
112
  FilteredListener, we get events before any filtering occurs.
114
113
  """
115
114
 
116
- def __init__(self, display=None):
115
+ def __init__(self, display=None) -> None:
117
116
  """Initialize the progress listener.
118
117
  Args:
119
118
  display: Optional display handler. If None, the shared progress_display will be used.
@@ -122,15 +121,15 @@ class ProgressListener(LifecycleAwareListener):
122
121
 
123
122
  self.display = display or progress_display
124
123
 
125
- async def start(self):
124
+ async def start(self) -> None:
126
125
  """Start the progress display."""
127
126
  self.display.start()
128
127
 
129
- async def stop(self):
128
+ async def stop(self) -> None:
130
129
  """Stop the progress display."""
131
130
  self.display.stop()
132
131
 
133
- async def handle_event(self, event: Event):
132
+ async def handle_event(self, event: Event) -> None:
134
133
  """Process an incoming event and display progress if relevant."""
135
134
 
136
135
  if event.data:
@@ -150,7 +149,7 @@ class BatchingListener(FilteredListener):
150
149
  event_filter: EventFilter | None = None,
151
150
  batch_size: int = 5,
152
151
  flush_interval: float = 2.0,
153
- ):
152
+ ) -> None:
154
153
  """
155
154
  Initialize the listener.
156
155
  Args:
@@ -165,12 +164,12 @@ class BatchingListener(FilteredListener):
165
164
  self._flush_task: asyncio.Task | None = None # Task for periodic flush loop
166
165
  self._stop_event = None # Event to signal flush task to stop
167
166
 
168
- async def start(self, loop=None):
167
+ async def start(self, loop=None) -> None:
169
168
  """Spawn a periodic flush loop."""
170
169
  self._stop_event = asyncio.Event()
171
170
  self._flush_task = asyncio.create_task(self._periodic_flush())
172
171
 
173
- async def stop(self):
172
+ async def stop(self) -> None:
174
173
  """Stop flush loop and flush any remaining events."""
175
174
  if self._stop_event:
176
175
  self._stop_event.set()
@@ -181,13 +180,11 @@ class BatchingListener(FilteredListener):
181
180
  self._flush_task = None
182
181
  await self.flush()
183
182
 
184
- async def _periodic_flush(self):
183
+ async def _periodic_flush(self) -> None:
185
184
  try:
186
185
  while not self._stop_event.is_set():
187
186
  try:
188
- await asyncio.wait_for(
189
- self._stop_event.wait(), timeout=self.flush_interval
190
- )
187
+ await asyncio.wait_for(self._stop_event.wait(), timeout=self.flush_interval)
191
188
  except asyncio.TimeoutError:
192
189
  await self.flush()
193
190
  # except asyncio.CancelledError:
@@ -195,12 +192,12 @@ class BatchingListener(FilteredListener):
195
192
  finally:
196
193
  await self.flush() # Final flush
197
194
 
198
- async def handle_matched_event(self, event):
195
+ async def handle_matched_event(self, event) -> None:
199
196
  self.batch.append(event)
200
197
  if len(self.batch) >= self.batch_size:
201
198
  await self.flush()
202
199
 
203
- async def flush(self):
200
+ async def flush(self) -> None:
204
201
  """Flush the current batch of events."""
205
202
  if not self.batch:
206
203
  return
@@ -209,5 +206,5 @@ class BatchingListener(FilteredListener):
209
206
  self.last_flush = time.time()
210
207
  await self._process_batch(to_process)
211
208
 
212
- async def _process_batch(self, events: List[Event]):
209
+ async def _process_batch(self, events: List[Event]) -> None:
213
210
  pass
@@ -10,10 +10,8 @@ Logger module for the MCP Agent, which provides:
10
10
  import asyncio
11
11
  import threading
12
12
  import time
13
-
14
- from typing import Any, Dict
15
-
16
13
  from contextlib import asynccontextmanager, contextmanager
14
+ from typing import Any, Dict
17
15
 
18
16
  from mcp_agent.logging.events import Event, EventContext, EventFilter, EventType
19
17
  from mcp_agent.logging.listeners import (
@@ -31,7 +29,7 @@ class Logger:
31
29
  - `name` can be a custom domain-specific event name, e.g. "ORDER_PLACED".
32
30
  """
33
31
 
34
- def __init__(self, namespace: str):
32
+ def __init__(self, namespace: str) -> None:
35
33
  self.namespace = namespace
36
34
  self.event_bus = AsyncEventBus.get()
37
35
 
@@ -45,7 +43,7 @@ class Logger:
45
43
  asyncio.set_event_loop(loop)
46
44
  return loop
47
45
 
48
- def _emit_event(self, event: Event):
46
+ def _emit_event(self, event: Event) -> None:
49
47
  """Emit an event by running it in the event loop."""
50
48
  loop = self._ensure_event_loop()
51
49
  if loop.is_running():
@@ -62,7 +60,7 @@ class Logger:
62
60
  message: str,
63
61
  context: EventContext | None,
64
62
  data: dict,
65
- ):
63
+ ) -> None:
66
64
  """Create and emit an event."""
67
65
  evt = Event(
68
66
  type=etype,
@@ -78,9 +76,9 @@ class Logger:
78
76
  self,
79
77
  message: str,
80
78
  name: str | None = None,
81
- context: EventContext = None,
79
+ context: EventContext | None = None,
82
80
  **data,
83
- ):
81
+ ) -> None:
84
82
  """Log a debug message."""
85
83
  self.event("debug", name, message, context, data)
86
84
 
@@ -88,9 +86,9 @@ class Logger:
88
86
  self,
89
87
  message: str,
90
88
  name: str | None = None,
91
- context: EventContext = None,
89
+ context: EventContext | None = None,
92
90
  **data,
93
- ):
91
+ ) -> None:
94
92
  """Log an info message."""
95
93
  self.event("info", name, message, context, data)
96
94
 
@@ -98,9 +96,9 @@ class Logger:
98
96
  self,
99
97
  message: str,
100
98
  name: str | None = None,
101
- context: EventContext = None,
99
+ context: EventContext | None = None,
102
100
  **data,
103
- ):
101
+ ) -> None:
104
102
  """Log a warning message."""
105
103
  self.event("warning", name, message, context, data)
106
104
 
@@ -108,9 +106,9 @@ class Logger:
108
106
  self,
109
107
  message: str,
110
108
  name: str | None = None,
111
- context: EventContext = None,
109
+ context: EventContext | None = None,
112
110
  **data,
113
- ):
111
+ ) -> None:
114
112
  """Log an error message."""
115
113
  self.event("error", name, message, context, data)
116
114
 
@@ -118,10 +116,10 @@ class Logger:
118
116
  self,
119
117
  message: str,
120
118
  name: str | None = None,
121
- percentage: float = None,
122
- context: EventContext = None,
119
+ percentage: float | None = None,
120
+ context: EventContext | None = None,
123
121
  **data,
124
- ):
122
+ ) -> None:
125
123
  """Log a progress message."""
126
124
  merged_data = dict(percentage=percentage, **data)
127
125
  self.event("progress", name, message, context, merged_data)
@@ -194,7 +192,7 @@ class LoggingConfig:
194
192
  batch_size: int = 100,
195
193
  flush_interval: float = 2.0,
196
194
  **kwargs: Any,
197
- ):
195
+ ) -> None:
198
196
  """
199
197
  Configure the logging system.
200
198
 
@@ -232,7 +230,7 @@ class LoggingConfig:
232
230
  cls._initialized = True
233
231
 
234
232
  @classmethod
235
- async def shutdown(cls):
233
+ async def shutdown(cls) -> None:
236
234
  """Shutdown the logging system gracefully."""
237
235
  if not cls._initialized:
238
236
  return
@@ -1,18 +1,20 @@
1
1
  """Rich-based progress display for MCP Agent."""
2
2
 
3
3
  import time
4
+ from contextlib import contextmanager
4
5
  from typing import Optional
6
+
5
7
  from rich.console import Console
6
- from mcp_agent.console import console as default_console
7
- from mcp_agent.event_progress import ProgressEvent, ProgressAction
8
8
  from rich.progress import Progress, SpinnerColumn, TextColumn
9
- from contextlib import contextmanager
9
+
10
+ from mcp_agent.console import console as default_console
11
+ from mcp_agent.event_progress import ProgressAction, ProgressEvent
10
12
 
11
13
 
12
14
  class RichProgressDisplay:
13
15
  """Rich-based display for progress events."""
14
16
 
15
- def __init__(self, console: Optional[Console] = None):
17
+ def __init__(self, console: Optional[Console] = None) -> None:
16
18
  """Initialize the progress display."""
17
19
  self.console = console or default_console
18
20
  self._taskmap = {}
@@ -29,16 +31,16 @@ class RichProgressDisplay:
29
31
  )
30
32
  self._paused = False
31
33
 
32
- def start(self):
34
+ def start(self) -> None:
33
35
  """start"""
34
36
 
35
37
  self._progress.start()
36
38
 
37
- def stop(self):
39
+ def stop(self) -> None:
38
40
  """stop"""
39
41
  self._progress.stop()
40
42
 
41
- def pause(self):
43
+ def pause(self) -> None:
42
44
  """Pause the progress display."""
43
45
  if not self._paused:
44
46
  self._paused = True
@@ -47,7 +49,7 @@ class RichProgressDisplay:
47
49
  task.visible = False
48
50
  self._progress.stop()
49
51
 
50
- def resume(self):
52
+ def resume(self) -> None:
51
53
  """Resume the progress display."""
52
54
  if self._paused:
53
55
  for task in self._progress.tasks:
@@ -5,16 +5,14 @@ for the Logger module for MCP Agent
5
5
 
6
6
  import asyncio
7
7
  import functools
8
- from typing import Any, Dict, Callable, Optional, Tuple, TYPE_CHECKING
8
+ from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Tuple
9
9
 
10
10
  from opentelemetry import trace
11
11
  from opentelemetry.context import Context as OtelContext
12
12
  from opentelemetry.propagate import extract as otel_extract
13
- from opentelemetry.trace import set_span_in_context
13
+ from opentelemetry.trace import SpanKind, Status, StatusCode, set_span_in_context
14
14
  from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
15
15
 
16
- from opentelemetry.trace import SpanKind, Status, StatusCode
17
-
18
16
  from mcp_agent.context_dependent import ContextDependent
19
17
 
20
18
  if TYPE_CHECKING:
@@ -27,7 +25,7 @@ class TelemetryManager(ContextDependent):
27
25
  Decorator usage: @telemetry.traced("SomeSpanName")
28
26
  """
29
27
 
30
- def __init__(self, context: Optional["Context"] = None, **kwargs):
28
+ def __init__(self, context: Optional["Context"] = None, **kwargs) -> None:
31
29
  # If needed, configure resources, exporters, etc.
32
30
  # E.g.: from opentelemetry.sdk.trace import TracerProvider
33
31
  # trace.set_tracer_provider(TracerProvider(...))
@@ -88,7 +86,7 @@ class TelemetryManager(ContextDependent):
88
86
 
89
87
  return decorator
90
88
 
91
- def _record_args(self, span, args, kwargs):
89
+ def _record_args(self, span, args, kwargs) -> None:
92
90
  """Optionally record primitive args as span attributes."""
93
91
  for i, arg in enumerate(args):
94
92
  if isinstance(arg, (str, int, float, bool)):