fast-agent-mcp 0.4.7__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 (261) hide show
  1. fast_agent/__init__.py +183 -0
  2. fast_agent/acp/__init__.py +19 -0
  3. fast_agent/acp/acp_aware_mixin.py +304 -0
  4. fast_agent/acp/acp_context.py +437 -0
  5. fast_agent/acp/content_conversion.py +136 -0
  6. fast_agent/acp/filesystem_runtime.py +427 -0
  7. fast_agent/acp/permission_store.py +269 -0
  8. fast_agent/acp/server/__init__.py +5 -0
  9. fast_agent/acp/server/agent_acp_server.py +1472 -0
  10. fast_agent/acp/slash_commands.py +1050 -0
  11. fast_agent/acp/terminal_runtime.py +408 -0
  12. fast_agent/acp/tool_permission_adapter.py +125 -0
  13. fast_agent/acp/tool_permissions.py +474 -0
  14. fast_agent/acp/tool_progress.py +814 -0
  15. fast_agent/agents/__init__.py +85 -0
  16. fast_agent/agents/agent_types.py +64 -0
  17. fast_agent/agents/llm_agent.py +350 -0
  18. fast_agent/agents/llm_decorator.py +1139 -0
  19. fast_agent/agents/mcp_agent.py +1337 -0
  20. fast_agent/agents/tool_agent.py +271 -0
  21. fast_agent/agents/workflow/agents_as_tools_agent.py +849 -0
  22. fast_agent/agents/workflow/chain_agent.py +212 -0
  23. fast_agent/agents/workflow/evaluator_optimizer.py +380 -0
  24. fast_agent/agents/workflow/iterative_planner.py +652 -0
  25. fast_agent/agents/workflow/maker_agent.py +379 -0
  26. fast_agent/agents/workflow/orchestrator_models.py +218 -0
  27. fast_agent/agents/workflow/orchestrator_prompts.py +248 -0
  28. fast_agent/agents/workflow/parallel_agent.py +250 -0
  29. fast_agent/agents/workflow/router_agent.py +353 -0
  30. fast_agent/cli/__init__.py +0 -0
  31. fast_agent/cli/__main__.py +73 -0
  32. fast_agent/cli/commands/acp.py +159 -0
  33. fast_agent/cli/commands/auth.py +404 -0
  34. fast_agent/cli/commands/check_config.py +783 -0
  35. fast_agent/cli/commands/go.py +514 -0
  36. fast_agent/cli/commands/quickstart.py +557 -0
  37. fast_agent/cli/commands/serve.py +143 -0
  38. fast_agent/cli/commands/server_helpers.py +114 -0
  39. fast_agent/cli/commands/setup.py +174 -0
  40. fast_agent/cli/commands/url_parser.py +190 -0
  41. fast_agent/cli/constants.py +40 -0
  42. fast_agent/cli/main.py +115 -0
  43. fast_agent/cli/terminal.py +24 -0
  44. fast_agent/config.py +798 -0
  45. fast_agent/constants.py +41 -0
  46. fast_agent/context.py +279 -0
  47. fast_agent/context_dependent.py +50 -0
  48. fast_agent/core/__init__.py +92 -0
  49. fast_agent/core/agent_app.py +448 -0
  50. fast_agent/core/core_app.py +137 -0
  51. fast_agent/core/direct_decorators.py +784 -0
  52. fast_agent/core/direct_factory.py +620 -0
  53. fast_agent/core/error_handling.py +27 -0
  54. fast_agent/core/exceptions.py +90 -0
  55. fast_agent/core/executor/__init__.py +0 -0
  56. fast_agent/core/executor/executor.py +280 -0
  57. fast_agent/core/executor/task_registry.py +32 -0
  58. fast_agent/core/executor/workflow_signal.py +324 -0
  59. fast_agent/core/fastagent.py +1186 -0
  60. fast_agent/core/logging/__init__.py +5 -0
  61. fast_agent/core/logging/events.py +138 -0
  62. fast_agent/core/logging/json_serializer.py +164 -0
  63. fast_agent/core/logging/listeners.py +309 -0
  64. fast_agent/core/logging/logger.py +278 -0
  65. fast_agent/core/logging/transport.py +481 -0
  66. fast_agent/core/prompt.py +9 -0
  67. fast_agent/core/prompt_templates.py +183 -0
  68. fast_agent/core/validation.py +326 -0
  69. fast_agent/event_progress.py +62 -0
  70. fast_agent/history/history_exporter.py +49 -0
  71. fast_agent/human_input/__init__.py +47 -0
  72. fast_agent/human_input/elicitation_handler.py +123 -0
  73. fast_agent/human_input/elicitation_state.py +33 -0
  74. fast_agent/human_input/form_elements.py +59 -0
  75. fast_agent/human_input/form_fields.py +256 -0
  76. fast_agent/human_input/simple_form.py +113 -0
  77. fast_agent/human_input/types.py +40 -0
  78. fast_agent/interfaces.py +310 -0
  79. fast_agent/llm/__init__.py +9 -0
  80. fast_agent/llm/cancellation.py +22 -0
  81. fast_agent/llm/fastagent_llm.py +931 -0
  82. fast_agent/llm/internal/passthrough.py +161 -0
  83. fast_agent/llm/internal/playback.py +129 -0
  84. fast_agent/llm/internal/silent.py +41 -0
  85. fast_agent/llm/internal/slow.py +38 -0
  86. fast_agent/llm/memory.py +275 -0
  87. fast_agent/llm/model_database.py +490 -0
  88. fast_agent/llm/model_factory.py +388 -0
  89. fast_agent/llm/model_info.py +102 -0
  90. fast_agent/llm/prompt_utils.py +155 -0
  91. fast_agent/llm/provider/anthropic/anthropic_utils.py +84 -0
  92. fast_agent/llm/provider/anthropic/cache_planner.py +56 -0
  93. fast_agent/llm/provider/anthropic/llm_anthropic.py +796 -0
  94. fast_agent/llm/provider/anthropic/multipart_converter_anthropic.py +462 -0
  95. fast_agent/llm/provider/bedrock/bedrock_utils.py +218 -0
  96. fast_agent/llm/provider/bedrock/llm_bedrock.py +2207 -0
  97. fast_agent/llm/provider/bedrock/multipart_converter_bedrock.py +84 -0
  98. fast_agent/llm/provider/google/google_converter.py +466 -0
  99. fast_agent/llm/provider/google/llm_google_native.py +681 -0
  100. fast_agent/llm/provider/openai/llm_aliyun.py +31 -0
  101. fast_agent/llm/provider/openai/llm_azure.py +143 -0
  102. fast_agent/llm/provider/openai/llm_deepseek.py +76 -0
  103. fast_agent/llm/provider/openai/llm_generic.py +35 -0
  104. fast_agent/llm/provider/openai/llm_google_oai.py +32 -0
  105. fast_agent/llm/provider/openai/llm_groq.py +42 -0
  106. fast_agent/llm/provider/openai/llm_huggingface.py +85 -0
  107. fast_agent/llm/provider/openai/llm_openai.py +1195 -0
  108. fast_agent/llm/provider/openai/llm_openai_compatible.py +138 -0
  109. fast_agent/llm/provider/openai/llm_openrouter.py +45 -0
  110. fast_agent/llm/provider/openai/llm_tensorzero_openai.py +128 -0
  111. fast_agent/llm/provider/openai/llm_xai.py +38 -0
  112. fast_agent/llm/provider/openai/multipart_converter_openai.py +561 -0
  113. fast_agent/llm/provider/openai/openai_multipart.py +169 -0
  114. fast_agent/llm/provider/openai/openai_utils.py +67 -0
  115. fast_agent/llm/provider/openai/responses.py +133 -0
  116. fast_agent/llm/provider_key_manager.py +139 -0
  117. fast_agent/llm/provider_types.py +34 -0
  118. fast_agent/llm/request_params.py +61 -0
  119. fast_agent/llm/sampling_converter.py +98 -0
  120. fast_agent/llm/stream_types.py +9 -0
  121. fast_agent/llm/usage_tracking.py +445 -0
  122. fast_agent/mcp/__init__.py +56 -0
  123. fast_agent/mcp/common.py +26 -0
  124. fast_agent/mcp/elicitation_factory.py +84 -0
  125. fast_agent/mcp/elicitation_handlers.py +164 -0
  126. fast_agent/mcp/gen_client.py +83 -0
  127. fast_agent/mcp/helpers/__init__.py +36 -0
  128. fast_agent/mcp/helpers/content_helpers.py +352 -0
  129. fast_agent/mcp/helpers/server_config_helpers.py +25 -0
  130. fast_agent/mcp/hf_auth.py +147 -0
  131. fast_agent/mcp/interfaces.py +92 -0
  132. fast_agent/mcp/logger_textio.py +108 -0
  133. fast_agent/mcp/mcp_agent_client_session.py +411 -0
  134. fast_agent/mcp/mcp_aggregator.py +2175 -0
  135. fast_agent/mcp/mcp_connection_manager.py +723 -0
  136. fast_agent/mcp/mcp_content.py +262 -0
  137. fast_agent/mcp/mime_utils.py +108 -0
  138. fast_agent/mcp/oauth_client.py +509 -0
  139. fast_agent/mcp/prompt.py +159 -0
  140. fast_agent/mcp/prompt_message_extended.py +155 -0
  141. fast_agent/mcp/prompt_render.py +84 -0
  142. fast_agent/mcp/prompt_serialization.py +580 -0
  143. fast_agent/mcp/prompts/__init__.py +0 -0
  144. fast_agent/mcp/prompts/__main__.py +7 -0
  145. fast_agent/mcp/prompts/prompt_constants.py +18 -0
  146. fast_agent/mcp/prompts/prompt_helpers.py +238 -0
  147. fast_agent/mcp/prompts/prompt_load.py +186 -0
  148. fast_agent/mcp/prompts/prompt_server.py +552 -0
  149. fast_agent/mcp/prompts/prompt_template.py +438 -0
  150. fast_agent/mcp/resource_utils.py +215 -0
  151. fast_agent/mcp/sampling.py +200 -0
  152. fast_agent/mcp/server/__init__.py +4 -0
  153. fast_agent/mcp/server/agent_server.py +613 -0
  154. fast_agent/mcp/skybridge.py +44 -0
  155. fast_agent/mcp/sse_tracking.py +287 -0
  156. fast_agent/mcp/stdio_tracking_simple.py +59 -0
  157. fast_agent/mcp/streamable_http_tracking.py +309 -0
  158. fast_agent/mcp/tool_execution_handler.py +137 -0
  159. fast_agent/mcp/tool_permission_handler.py +88 -0
  160. fast_agent/mcp/transport_tracking.py +634 -0
  161. fast_agent/mcp/types.py +24 -0
  162. fast_agent/mcp/ui_agent.py +48 -0
  163. fast_agent/mcp/ui_mixin.py +209 -0
  164. fast_agent/mcp_server_registry.py +89 -0
  165. fast_agent/py.typed +0 -0
  166. fast_agent/resources/examples/data-analysis/analysis-campaign.py +189 -0
  167. fast_agent/resources/examples/data-analysis/analysis.py +68 -0
  168. fast_agent/resources/examples/data-analysis/fastagent.config.yaml +41 -0
  169. fast_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +1471 -0
  170. fast_agent/resources/examples/mcp/elicitations/elicitation_account_server.py +88 -0
  171. fast_agent/resources/examples/mcp/elicitations/elicitation_forms_server.py +297 -0
  172. fast_agent/resources/examples/mcp/elicitations/elicitation_game_server.py +164 -0
  173. fast_agent/resources/examples/mcp/elicitations/fastagent.config.yaml +35 -0
  174. fast_agent/resources/examples/mcp/elicitations/fastagent.secrets.yaml.example +17 -0
  175. fast_agent/resources/examples/mcp/elicitations/forms_demo.py +107 -0
  176. fast_agent/resources/examples/mcp/elicitations/game_character.py +65 -0
  177. fast_agent/resources/examples/mcp/elicitations/game_character_handler.py +256 -0
  178. fast_agent/resources/examples/mcp/elicitations/tool_call.py +21 -0
  179. fast_agent/resources/examples/mcp/state-transfer/agent_one.py +18 -0
  180. fast_agent/resources/examples/mcp/state-transfer/agent_two.py +18 -0
  181. fast_agent/resources/examples/mcp/state-transfer/fastagent.config.yaml +27 -0
  182. fast_agent/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +15 -0
  183. fast_agent/resources/examples/researcher/fastagent.config.yaml +61 -0
  184. fast_agent/resources/examples/researcher/researcher-eval.py +53 -0
  185. fast_agent/resources/examples/researcher/researcher-imp.py +189 -0
  186. fast_agent/resources/examples/researcher/researcher.py +36 -0
  187. fast_agent/resources/examples/tensorzero/.env.sample +2 -0
  188. fast_agent/resources/examples/tensorzero/Makefile +31 -0
  189. fast_agent/resources/examples/tensorzero/README.md +56 -0
  190. fast_agent/resources/examples/tensorzero/agent.py +35 -0
  191. fast_agent/resources/examples/tensorzero/demo_images/clam.jpg +0 -0
  192. fast_agent/resources/examples/tensorzero/demo_images/crab.png +0 -0
  193. fast_agent/resources/examples/tensorzero/demo_images/shrimp.png +0 -0
  194. fast_agent/resources/examples/tensorzero/docker-compose.yml +105 -0
  195. fast_agent/resources/examples/tensorzero/fastagent.config.yaml +19 -0
  196. fast_agent/resources/examples/tensorzero/image_demo.py +67 -0
  197. fast_agent/resources/examples/tensorzero/mcp_server/Dockerfile +25 -0
  198. fast_agent/resources/examples/tensorzero/mcp_server/entrypoint.sh +35 -0
  199. fast_agent/resources/examples/tensorzero/mcp_server/mcp_server.py +31 -0
  200. fast_agent/resources/examples/tensorzero/mcp_server/pyproject.toml +11 -0
  201. fast_agent/resources/examples/tensorzero/simple_agent.py +25 -0
  202. fast_agent/resources/examples/tensorzero/tensorzero_config/system_schema.json +29 -0
  203. fast_agent/resources/examples/tensorzero/tensorzero_config/system_template.minijinja +11 -0
  204. fast_agent/resources/examples/tensorzero/tensorzero_config/tensorzero.toml +35 -0
  205. fast_agent/resources/examples/workflows/agents_as_tools_extended.py +73 -0
  206. fast_agent/resources/examples/workflows/agents_as_tools_simple.py +50 -0
  207. fast_agent/resources/examples/workflows/chaining.py +37 -0
  208. fast_agent/resources/examples/workflows/evaluator.py +77 -0
  209. fast_agent/resources/examples/workflows/fastagent.config.yaml +26 -0
  210. fast_agent/resources/examples/workflows/graded_report.md +89 -0
  211. fast_agent/resources/examples/workflows/human_input.py +28 -0
  212. fast_agent/resources/examples/workflows/maker.py +156 -0
  213. fast_agent/resources/examples/workflows/orchestrator.py +70 -0
  214. fast_agent/resources/examples/workflows/parallel.py +56 -0
  215. fast_agent/resources/examples/workflows/router.py +69 -0
  216. fast_agent/resources/examples/workflows/short_story.md +13 -0
  217. fast_agent/resources/examples/workflows/short_story.txt +19 -0
  218. fast_agent/resources/setup/.gitignore +30 -0
  219. fast_agent/resources/setup/agent.py +28 -0
  220. fast_agent/resources/setup/fastagent.config.yaml +65 -0
  221. fast_agent/resources/setup/fastagent.secrets.yaml.example +38 -0
  222. fast_agent/resources/setup/pyproject.toml.tmpl +23 -0
  223. fast_agent/skills/__init__.py +9 -0
  224. fast_agent/skills/registry.py +235 -0
  225. fast_agent/tools/elicitation.py +369 -0
  226. fast_agent/tools/shell_runtime.py +402 -0
  227. fast_agent/types/__init__.py +59 -0
  228. fast_agent/types/conversation_summary.py +294 -0
  229. fast_agent/types/llm_stop_reason.py +78 -0
  230. fast_agent/types/message_search.py +249 -0
  231. fast_agent/ui/__init__.py +38 -0
  232. fast_agent/ui/console.py +59 -0
  233. fast_agent/ui/console_display.py +1080 -0
  234. fast_agent/ui/elicitation_form.py +946 -0
  235. fast_agent/ui/elicitation_style.py +59 -0
  236. fast_agent/ui/enhanced_prompt.py +1400 -0
  237. fast_agent/ui/history_display.py +734 -0
  238. fast_agent/ui/interactive_prompt.py +1199 -0
  239. fast_agent/ui/markdown_helpers.py +104 -0
  240. fast_agent/ui/markdown_truncator.py +1004 -0
  241. fast_agent/ui/mcp_display.py +857 -0
  242. fast_agent/ui/mcp_ui_utils.py +235 -0
  243. fast_agent/ui/mermaid_utils.py +169 -0
  244. fast_agent/ui/message_primitives.py +50 -0
  245. fast_agent/ui/notification_tracker.py +205 -0
  246. fast_agent/ui/plain_text_truncator.py +68 -0
  247. fast_agent/ui/progress_display.py +10 -0
  248. fast_agent/ui/rich_progress.py +195 -0
  249. fast_agent/ui/streaming.py +774 -0
  250. fast_agent/ui/streaming_buffer.py +449 -0
  251. fast_agent/ui/tool_display.py +422 -0
  252. fast_agent/ui/usage_display.py +204 -0
  253. fast_agent/utils/__init__.py +5 -0
  254. fast_agent/utils/reasoning_stream_parser.py +77 -0
  255. fast_agent/utils/time.py +22 -0
  256. fast_agent/workflow_telemetry.py +261 -0
  257. fast_agent_mcp-0.4.7.dist-info/METADATA +788 -0
  258. fast_agent_mcp-0.4.7.dist-info/RECORD +261 -0
  259. fast_agent_mcp-0.4.7.dist-info/WHEEL +4 -0
  260. fast_agent_mcp-0.4.7.dist-info/entry_points.txt +7 -0
  261. fast_agent_mcp-0.4.7.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,278 @@
1
+ """
2
+ Logger module for the MCP Agent, which provides:
3
+ - Local + optional remote event transport
4
+ - Async event bus
5
+ - OpenTelemetry tracing decorators (for distributed tracing)
6
+ - Automatic injection of trace_id/span_id into events
7
+ - Developer-friendly Logger that can be used anywhere
8
+ """
9
+
10
+ import asyncio
11
+ import logging
12
+ import threading
13
+ import time
14
+ from contextlib import asynccontextmanager, contextmanager
15
+ from typing import Any
16
+
17
+ from fast_agent.core.logging.events import Event, EventContext, EventFilter, EventType
18
+ from fast_agent.core.logging.listeners import (
19
+ BatchingListener,
20
+ LoggingListener,
21
+ ProgressListener,
22
+ )
23
+ from fast_agent.core.logging.transport import AsyncEventBus, EventTransport
24
+
25
+
26
+ class Logger:
27
+ """
28
+ Developer-friendly logger that sends events to the AsyncEventBus.
29
+ - `type` is a broad category (INFO, ERROR, etc.).
30
+ - `name` can be a custom domain-specific event name, e.g. "ORDER_PLACED".
31
+ """
32
+
33
+ def __init__(self, namespace: str) -> None:
34
+ self.namespace = namespace
35
+ self.event_bus = AsyncEventBus.get()
36
+
37
+ def _ensure_event_loop(self):
38
+ """Ensure we have an event loop we can use."""
39
+ try:
40
+ return asyncio.get_running_loop()
41
+ except RuntimeError:
42
+ # If no loop is running, create a new one
43
+ loop = asyncio.new_event_loop()
44
+ asyncio.set_event_loop(loop)
45
+ return loop
46
+
47
+ def _emit_event(self, event: Event) -> None:
48
+ """Emit an event by running it in the event loop."""
49
+ loop = self._ensure_event_loop()
50
+ if loop.is_running():
51
+ # If we're in a thread with a running loop, schedule the coroutine
52
+ asyncio.create_task(self.event_bus.emit(event))
53
+ else:
54
+ # If no loop is running, run it until the emit completes
55
+ loop.run_until_complete(self.event_bus.emit(event))
56
+
57
+ def event(
58
+ self,
59
+ etype: EventType,
60
+ ename: str | None,
61
+ message: str,
62
+ context: EventContext | None,
63
+ data: dict,
64
+ ) -> None:
65
+ """Create and emit an event."""
66
+ evt = Event(
67
+ type=etype,
68
+ name=ename,
69
+ namespace=self.namespace,
70
+ message=message,
71
+ context=context,
72
+ data=data,
73
+ )
74
+ self._emit_event(evt)
75
+
76
+ def debug(
77
+ self,
78
+ message: str,
79
+ name: str | None = None,
80
+ context: EventContext | None = None,
81
+ **data,
82
+ ) -> None:
83
+ """Log a debug message."""
84
+ self.event("debug", name, message, context, data)
85
+
86
+ def info(
87
+ self,
88
+ message: str,
89
+ name: str | None = None,
90
+ context: EventContext | None = None,
91
+ **data,
92
+ ) -> None:
93
+ """Log an info message."""
94
+ self.event("info", name, message, context, data)
95
+
96
+ def warning(
97
+ self,
98
+ message: str,
99
+ name: str | None = None,
100
+ context: EventContext | None = None,
101
+ **data,
102
+ ) -> None:
103
+ """Log a warning message."""
104
+ self.event("warning", name, message, context, data)
105
+
106
+ def error(
107
+ self,
108
+ message: str,
109
+ name: str | None = None,
110
+ context: EventContext | None = None,
111
+ **data,
112
+ ) -> None:
113
+ """Log an error message."""
114
+ self.event("error", name, message, context, data)
115
+
116
+ def progress(
117
+ self,
118
+ message: str,
119
+ name: str | None = None,
120
+ percentage: float | None = None,
121
+ context: EventContext | None = None,
122
+ **data,
123
+ ) -> None:
124
+ """Log a progress message."""
125
+ merged_data = dict(percentage=percentage, **data)
126
+ self.event("progress", name, message, context, merged_data)
127
+
128
+
129
+ @contextmanager
130
+ def event_context(
131
+ logger: Logger,
132
+ message: str,
133
+ event_type: EventType = "info",
134
+ name: str | None = None,
135
+ **data,
136
+ ):
137
+ """
138
+ Times a synchronous block, logs an event after completion.
139
+ Because logger methods are async, we schedule the final log.
140
+ """
141
+ start_time = time.time()
142
+ try:
143
+ yield
144
+ finally:
145
+ duration = time.time() - start_time
146
+
147
+ logger.event(
148
+ event_type,
149
+ name,
150
+ f"{message} finished in {duration:.3f}s",
151
+ None,
152
+ {"duration": duration, **data},
153
+ )
154
+
155
+
156
+ # TODO: saqadri - check if we need this
157
+ @asynccontextmanager
158
+ async def async_event_context(
159
+ logger: Logger,
160
+ message: str,
161
+ event_type: EventType = "info",
162
+ name: str | None = None,
163
+ **data,
164
+ ):
165
+ """
166
+ Times an asynchronous block, logs an event after completion.
167
+ Because logger methods are async, we schedule the final log.
168
+ """
169
+ start_time = time.time()
170
+ try:
171
+ yield
172
+ finally:
173
+ duration = time.time() - start_time
174
+ logger.event(
175
+ event_type,
176
+ name,
177
+ f"{message} finished in {duration:.3f}s",
178
+ None,
179
+ {"duration": duration, **data},
180
+ )
181
+
182
+
183
+ class LoggingConfig:
184
+ """Global configuration for the logging system."""
185
+
186
+ _initialized = False
187
+
188
+ @classmethod
189
+ async def configure(
190
+ cls,
191
+ event_filter: EventFilter | None = None,
192
+ transport: EventTransport | None = None,
193
+ batch_size: int = 100,
194
+ flush_interval: float = 2.0,
195
+ **kwargs: Any,
196
+ ) -> None:
197
+ """
198
+ Configure the logging system.
199
+
200
+ Args:
201
+ event_filter: Default filter for all loggers
202
+ transport: Transport for sending events to external systems
203
+ batch_size: Default batch size for batching listener
204
+ flush_interval: Default flush interval for batching listener
205
+ **kwargs: Additional configuration options
206
+ """
207
+ if cls._initialized:
208
+ return
209
+
210
+ # Suppress boto3/botocore logging to prevent flooding
211
+ logging.getLogger("boto3").setLevel(logging.WARNING)
212
+ logging.getLogger("botocore").setLevel(logging.WARNING)
213
+ logging.getLogger("urllib3").setLevel(logging.WARNING)
214
+ logging.getLogger("s3transfer").setLevel(logging.WARNING)
215
+
216
+ bus = AsyncEventBus.get(transport=transport)
217
+
218
+ # Add standard listeners
219
+ if "logging" not in bus.listeners:
220
+ bus.add_listener("logging", LoggingListener(event_filter=event_filter))
221
+
222
+ # Only add progress listener if enabled in settings
223
+ if "progress" not in bus.listeners and kwargs.get("progress_display", True):
224
+ bus.add_listener("progress", ProgressListener())
225
+
226
+ if "batching" not in bus.listeners:
227
+ bus.add_listener(
228
+ "batching",
229
+ BatchingListener(
230
+ event_filter=event_filter,
231
+ batch_size=batch_size,
232
+ flush_interval=flush_interval,
233
+ ),
234
+ )
235
+
236
+ await bus.start()
237
+ cls._initialized = True
238
+
239
+ @classmethod
240
+ async def shutdown(cls) -> None:
241
+ """Shutdown the logging system gracefully."""
242
+ if not cls._initialized:
243
+ return
244
+ bus = AsyncEventBus.get()
245
+ await bus.stop()
246
+ cls._initialized = False
247
+
248
+ @classmethod
249
+ @asynccontextmanager
250
+ async def managed(cls, **config_kwargs):
251
+ """Context manager for the logging system lifecycle."""
252
+ try:
253
+ await cls.configure(**config_kwargs)
254
+ yield
255
+ finally:
256
+ await cls.shutdown()
257
+
258
+
259
+ _logger_lock = threading.Lock()
260
+ _loggers: dict[str, Logger] = {}
261
+
262
+
263
+ def get_logger(namespace: str) -> Logger:
264
+ """
265
+ Get a logger instance for a given namespace.
266
+ Creates a new logger if one doesn't exist for this namespace.
267
+
268
+ Args:
269
+ namespace: The namespace for the logger (e.g. "agent.helper", "workflow.demo")
270
+
271
+ Returns:
272
+ A Logger instance for the given namespace
273
+ """
274
+
275
+ with _logger_lock:
276
+ if namespace not in _loggers:
277
+ _loggers[namespace] = Logger(namespace)
278
+ return _loggers[namespace]