flock-core 0.5.0b27__py3-none-any.whl → 0.5.0b50__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 flock-core might be problematic. Click here for more details.

Files changed (357) hide show
  1. flock/__init__.py +12 -217
  2. flock/agent.py +678 -0
  3. flock/api/themes.py +71 -0
  4. flock/artifacts.py +79 -0
  5. flock/cli.py +75 -0
  6. flock/components.py +173 -0
  7. flock/dashboard/__init__.py +28 -0
  8. flock/dashboard/collector.py +283 -0
  9. flock/dashboard/events.py +182 -0
  10. flock/dashboard/launcher.py +230 -0
  11. flock/dashboard/service.py +537 -0
  12. flock/dashboard/websocket.py +235 -0
  13. flock/engines/__init__.py +6 -0
  14. flock/engines/dspy_engine.py +856 -0
  15. flock/examples.py +128 -0
  16. flock/{core/util → helper}/cli_helper.py +4 -3
  17. flock/{core/logging → logging}/__init__.py +2 -3
  18. flock/{core/logging → logging}/formatters/enum_builder.py +3 -4
  19. flock/{core/logging → logging}/formatters/theme_builder.py +19 -44
  20. flock/{core/logging → logging}/formatters/themed_formatter.py +69 -115
  21. flock/{core/logging → logging}/logging.py +77 -61
  22. flock/{core/logging → logging}/telemetry.py +20 -26
  23. flock/{core/logging → logging}/telemetry_exporter/base_exporter.py +2 -2
  24. flock/{core/logging → logging}/telemetry_exporter/file_exporter.py +6 -9
  25. flock/{core/logging → logging}/telemetry_exporter/sqlite_exporter.py +2 -3
  26. flock/{core/logging → logging}/trace_and_logged.py +20 -24
  27. flock/mcp/__init__.py +91 -0
  28. flock/{core/mcp/mcp_client.py → mcp/client.py} +103 -154
  29. flock/{core/mcp/mcp_config.py → mcp/config.py} +62 -117
  30. flock/mcp/manager.py +255 -0
  31. flock/mcp/servers/sse/__init__.py +1 -1
  32. flock/mcp/servers/sse/flock_sse_server.py +11 -53
  33. flock/mcp/servers/stdio/__init__.py +1 -1
  34. flock/mcp/servers/stdio/flock_stdio_server.py +8 -48
  35. flock/mcp/servers/streamable_http/flock_streamable_http_server.py +17 -62
  36. flock/mcp/servers/websockets/flock_websocket_server.py +7 -40
  37. flock/{core/mcp/flock_mcp_tool.py → mcp/tool.py} +16 -26
  38. flock/mcp/types/__init__.py +42 -0
  39. flock/{core/mcp → mcp}/types/callbacks.py +9 -15
  40. flock/{core/mcp → mcp}/types/factories.py +7 -6
  41. flock/{core/mcp → mcp}/types/handlers.py +13 -18
  42. flock/{core/mcp → mcp}/types/types.py +70 -74
  43. flock/{core/mcp → mcp}/util/helpers.py +1 -1
  44. flock/orchestrator.py +645 -0
  45. flock/registry.py +148 -0
  46. flock/runtime.py +262 -0
  47. flock/service.py +140 -0
  48. flock/store.py +69 -0
  49. flock/subscription.py +111 -0
  50. flock/themes/andromeda.toml +1 -1
  51. flock/themes/apple-system-colors.toml +1 -1
  52. flock/themes/arcoiris.toml +1 -1
  53. flock/themes/atomonelight.toml +1 -1
  54. flock/themes/ayu copy.toml +1 -1
  55. flock/themes/ayu-light.toml +1 -1
  56. flock/themes/belafonte-day.toml +1 -1
  57. flock/themes/belafonte-night.toml +1 -1
  58. flock/themes/blulocodark.toml +1 -1
  59. flock/themes/breeze.toml +1 -1
  60. flock/themes/broadcast.toml +1 -1
  61. flock/themes/brogrammer.toml +1 -1
  62. flock/themes/builtin-dark.toml +1 -1
  63. flock/themes/builtin-pastel-dark.toml +1 -1
  64. flock/themes/catppuccin-latte.toml +1 -1
  65. flock/themes/catppuccin-macchiato.toml +1 -1
  66. flock/themes/catppuccin-mocha.toml +1 -1
  67. flock/themes/cga.toml +1 -1
  68. flock/themes/chalk.toml +1 -1
  69. flock/themes/ciapre.toml +1 -1
  70. flock/themes/coffee-theme.toml +1 -1
  71. flock/themes/cyberpunkscarletprotocol.toml +1 -1
  72. flock/themes/dark+.toml +1 -1
  73. flock/themes/darkermatrix.toml +1 -1
  74. flock/themes/darkside.toml +1 -1
  75. flock/themes/desert.toml +1 -1
  76. flock/themes/django.toml +1 -1
  77. flock/themes/djangosmooth.toml +1 -1
  78. flock/themes/doomone.toml +1 -1
  79. flock/themes/dotgov.toml +1 -1
  80. flock/themes/dracula+.toml +1 -1
  81. flock/themes/duckbones.toml +1 -1
  82. flock/themes/encom.toml +1 -1
  83. flock/themes/espresso.toml +1 -1
  84. flock/themes/everblush.toml +1 -1
  85. flock/themes/fairyfloss.toml +1 -1
  86. flock/themes/fideloper.toml +1 -1
  87. flock/themes/fishtank.toml +1 -1
  88. flock/themes/flexoki-light.toml +1 -1
  89. flock/themes/floraverse.toml +1 -1
  90. flock/themes/framer.toml +1 -1
  91. flock/themes/galizur.toml +1 -1
  92. flock/themes/github.toml +1 -1
  93. flock/themes/grass.toml +1 -1
  94. flock/themes/grey-green.toml +1 -1
  95. flock/themes/gruvboxlight.toml +1 -1
  96. flock/themes/guezwhoz.toml +1 -1
  97. flock/themes/harper.toml +1 -1
  98. flock/themes/hax0r-blue.toml +1 -1
  99. flock/themes/hopscotch.256.toml +1 -1
  100. flock/themes/ic-green-ppl.toml +1 -1
  101. flock/themes/iceberg-dark.toml +1 -1
  102. flock/themes/japanesque.toml +1 -1
  103. flock/themes/jubi.toml +1 -1
  104. flock/themes/kibble.toml +1 -1
  105. flock/themes/kolorit.toml +1 -1
  106. flock/themes/kurokula.toml +1 -1
  107. flock/themes/materialdesigncolors.toml +1 -1
  108. flock/themes/matrix.toml +1 -1
  109. flock/themes/mellifluous.toml +1 -1
  110. flock/themes/midnight-in-mojave.toml +1 -1
  111. flock/themes/monokai-remastered.toml +1 -1
  112. flock/themes/monokai-soda.toml +1 -1
  113. flock/themes/neon.toml +1 -1
  114. flock/themes/neopolitan.toml +1 -1
  115. flock/themes/nord-light.toml +1 -1
  116. flock/themes/ocean.toml +1 -1
  117. flock/themes/onehalfdark.toml +1 -1
  118. flock/themes/onehalflight.toml +1 -1
  119. flock/themes/palenighthc.toml +1 -1
  120. flock/themes/paulmillr.toml +1 -1
  121. flock/themes/pencildark.toml +1 -1
  122. flock/themes/pnevma.toml +1 -1
  123. flock/themes/purple-rain.toml +1 -1
  124. flock/themes/purplepeter.toml +1 -1
  125. flock/themes/raycast-dark.toml +1 -1
  126. flock/themes/red-sands.toml +1 -1
  127. flock/themes/relaxed.toml +1 -1
  128. flock/themes/retro.toml +1 -1
  129. flock/themes/rose-pine.toml +1 -1
  130. flock/themes/royal.toml +1 -1
  131. flock/themes/ryuuko.toml +1 -1
  132. flock/themes/sakura.toml +1 -1
  133. flock/themes/scarlet-protocol.toml +1 -1
  134. flock/themes/seoulbones-dark.toml +1 -1
  135. flock/themes/shades-of-purple.toml +1 -1
  136. flock/themes/smyck.toml +1 -1
  137. flock/themes/softserver.toml +1 -1
  138. flock/themes/solarized-darcula.toml +1 -1
  139. flock/themes/square.toml +1 -1
  140. flock/themes/sugarplum.toml +1 -1
  141. flock/themes/thayer-bright.toml +1 -1
  142. flock/themes/tokyonight.toml +1 -1
  143. flock/themes/tomorrow.toml +1 -1
  144. flock/themes/ubuntu.toml +1 -1
  145. flock/themes/ultradark.toml +1 -1
  146. flock/themes/ultraviolent.toml +1 -1
  147. flock/themes/unikitty.toml +1 -1
  148. flock/themes/urple.toml +1 -1
  149. flock/themes/vesper.toml +1 -1
  150. flock/themes/vimbones.toml +1 -1
  151. flock/themes/wildcherry.toml +1 -1
  152. flock/themes/wilmersdorf.toml +1 -1
  153. flock/themes/wryan.toml +1 -1
  154. flock/themes/xcodedarkhc.toml +1 -1
  155. flock/themes/xcodelight.toml +1 -1
  156. flock/themes/zenbones-light.toml +1 -1
  157. flock/themes/zenwritten-dark.toml +1 -1
  158. flock/utilities.py +301 -0
  159. flock/{components/utility → utility}/output_utility_component.py +68 -53
  160. flock/visibility.py +107 -0
  161. flock_core-0.5.0b50.dist-info/METADATA +747 -0
  162. flock_core-0.5.0b50.dist-info/RECORD +398 -0
  163. flock_core-0.5.0b50.dist-info/entry_points.txt +2 -0
  164. {flock_core-0.5.0b27.dist-info → flock_core-0.5.0b50.dist-info}/licenses/LICENSE +1 -1
  165. flock/adapter/__init__.py +0 -14
  166. flock/adapter/azure_adapter.py +0 -68
  167. flock/adapter/chroma_adapter.py +0 -73
  168. flock/adapter/faiss_adapter.py +0 -97
  169. flock/adapter/pinecone_adapter.py +0 -51
  170. flock/adapter/vector_base.py +0 -47
  171. flock/cli/assets/release_notes.md +0 -140
  172. flock/cli/config.py +0 -8
  173. flock/cli/constants.py +0 -36
  174. flock/cli/create_agent.py +0 -1
  175. flock/cli/create_flock.py +0 -280
  176. flock/cli/execute_flock.py +0 -620
  177. flock/cli/load_agent.py +0 -1
  178. flock/cli/load_examples.py +0 -1
  179. flock/cli/load_flock.py +0 -192
  180. flock/cli/load_release_notes.py +0 -20
  181. flock/cli/loaded_flock_cli.py +0 -254
  182. flock/cli/manage_agents.py +0 -459
  183. flock/cli/registry_management.py +0 -889
  184. flock/cli/runner.py +0 -41
  185. flock/cli/settings.py +0 -857
  186. flock/cli/utils.py +0 -135
  187. flock/cli/view_results.py +0 -29
  188. flock/cli/yaml_editor.py +0 -396
  189. flock/components/__init__.py +0 -30
  190. flock/components/evaluation/__init__.py +0 -9
  191. flock/components/evaluation/declarative_evaluation_component.py +0 -606
  192. flock/components/routing/__init__.py +0 -15
  193. flock/components/routing/conditional_routing_component.py +0 -494
  194. flock/components/routing/default_routing_component.py +0 -103
  195. flock/components/routing/llm_routing_component.py +0 -206
  196. flock/components/utility/__init__.py +0 -15
  197. flock/components/utility/memory_utility_component.py +0 -550
  198. flock/components/utility/metrics_utility_component.py +0 -700
  199. flock/config.py +0 -61
  200. flock/core/__init__.py +0 -110
  201. flock/core/agent/__init__.py +0 -16
  202. flock/core/agent/default_agent.py +0 -180
  203. flock/core/agent/flock_agent_components.py +0 -104
  204. flock/core/agent/flock_agent_execution.py +0 -101
  205. flock/core/agent/flock_agent_integration.py +0 -260
  206. flock/core/agent/flock_agent_lifecycle.py +0 -186
  207. flock/core/agent/flock_agent_serialization.py +0 -381
  208. flock/core/api/__init__.py +0 -10
  209. flock/core/api/custom_endpoint.py +0 -45
  210. flock/core/api/endpoints.py +0 -254
  211. flock/core/api/main.py +0 -162
  212. flock/core/api/models.py +0 -97
  213. flock/core/api/run_store.py +0 -224
  214. flock/core/api/runner.py +0 -44
  215. flock/core/api/service.py +0 -214
  216. flock/core/component/__init__.py +0 -15
  217. flock/core/component/agent_component_base.py +0 -309
  218. flock/core/component/evaluation_component.py +0 -62
  219. flock/core/component/routing_component.py +0 -74
  220. flock/core/component/utility_component.py +0 -69
  221. flock/core/config/flock_agent_config.py +0 -58
  222. flock/core/config/scheduled_agent_config.py +0 -40
  223. flock/core/context/context.py +0 -213
  224. flock/core/context/context_manager.py +0 -37
  225. flock/core/context/context_vars.py +0 -10
  226. flock/core/evaluation/utils.py +0 -396
  227. flock/core/execution/batch_executor.py +0 -369
  228. flock/core/execution/evaluation_executor.py +0 -438
  229. flock/core/execution/local_executor.py +0 -31
  230. flock/core/execution/opik_executor.py +0 -103
  231. flock/core/execution/temporal_executor.py +0 -164
  232. flock/core/flock.py +0 -634
  233. flock/core/flock_agent.py +0 -336
  234. flock/core/flock_factory.py +0 -551
  235. flock/core/flock_scheduler.py +0 -166
  236. flock/core/flock_server_manager.py +0 -136
  237. flock/core/interpreter/python_interpreter.py +0 -689
  238. flock/core/mcp/__init__.py +0 -1
  239. flock/core/mcp/flock_mcp_server.py +0 -680
  240. flock/core/mcp/mcp_client_manager.py +0 -201
  241. flock/core/mcp/types/__init__.py +0 -1
  242. flock/core/mixin/dspy_integration.py +0 -403
  243. flock/core/mixin/prompt_parser.py +0 -125
  244. flock/core/orchestration/__init__.py +0 -15
  245. flock/core/orchestration/flock_batch_processor.py +0 -94
  246. flock/core/orchestration/flock_evaluator.py +0 -113
  247. flock/core/orchestration/flock_execution.py +0 -295
  248. flock/core/orchestration/flock_initialization.py +0 -149
  249. flock/core/orchestration/flock_server_manager.py +0 -67
  250. flock/core/orchestration/flock_web_server.py +0 -117
  251. flock/core/registry/__init__.py +0 -45
  252. flock/core/registry/agent_registry.py +0 -69
  253. flock/core/registry/callable_registry.py +0 -139
  254. flock/core/registry/component_discovery.py +0 -142
  255. flock/core/registry/component_registry.py +0 -64
  256. flock/core/registry/config_mapping.py +0 -64
  257. flock/core/registry/decorators.py +0 -137
  258. flock/core/registry/registry_hub.py +0 -205
  259. flock/core/registry/server_registry.py +0 -57
  260. flock/core/registry/type_registry.py +0 -86
  261. flock/core/serialization/__init__.py +0 -13
  262. flock/core/serialization/callable_registry.py +0 -52
  263. flock/core/serialization/flock_serializer.py +0 -832
  264. flock/core/serialization/json_encoder.py +0 -41
  265. flock/core/serialization/secure_serializer.py +0 -175
  266. flock/core/serialization/serializable.py +0 -342
  267. flock/core/serialization/serialization_utils.py +0 -412
  268. flock/core/util/file_path_utils.py +0 -223
  269. flock/core/util/hydrator.py +0 -309
  270. flock/core/util/input_resolver.py +0 -164
  271. flock/core/util/loader.py +0 -59
  272. flock/core/util/splitter.py +0 -219
  273. flock/di.py +0 -27
  274. flock/platform/docker_tools.py +0 -49
  275. flock/platform/jaeger_install.py +0 -86
  276. flock/webapp/__init__.py +0 -1
  277. flock/webapp/app/__init__.py +0 -0
  278. flock/webapp/app/api/__init__.py +0 -0
  279. flock/webapp/app/api/agent_management.py +0 -241
  280. flock/webapp/app/api/execution.py +0 -709
  281. flock/webapp/app/api/flock_management.py +0 -129
  282. flock/webapp/app/api/registry_viewer.py +0 -30
  283. flock/webapp/app/chat.py +0 -665
  284. flock/webapp/app/config.py +0 -104
  285. flock/webapp/app/dependencies.py +0 -117
  286. flock/webapp/app/main.py +0 -1070
  287. flock/webapp/app/middleware.py +0 -113
  288. flock/webapp/app/models_ui.py +0 -7
  289. flock/webapp/app/services/__init__.py +0 -0
  290. flock/webapp/app/services/feedback_file_service.py +0 -363
  291. flock/webapp/app/services/flock_service.py +0 -337
  292. flock/webapp/app/services/sharing_models.py +0 -81
  293. flock/webapp/app/services/sharing_store.py +0 -598
  294. flock/webapp/app/templates/theme_mapper.html +0 -326
  295. flock/webapp/app/theme_mapper.py +0 -812
  296. flock/webapp/app/utils.py +0 -85
  297. flock/webapp/run.py +0 -215
  298. flock/webapp/static/css/chat.css +0 -301
  299. flock/webapp/static/css/components.css +0 -167
  300. flock/webapp/static/css/header.css +0 -39
  301. flock/webapp/static/css/layout.css +0 -46
  302. flock/webapp/static/css/sidebar.css +0 -127
  303. flock/webapp/static/css/two-pane.css +0 -48
  304. flock/webapp/templates/base.html +0 -200
  305. flock/webapp/templates/chat.html +0 -152
  306. flock/webapp/templates/chat_settings.html +0 -19
  307. flock/webapp/templates/flock_editor.html +0 -16
  308. flock/webapp/templates/index.html +0 -12
  309. flock/webapp/templates/partials/_agent_detail_form.html +0 -93
  310. flock/webapp/templates/partials/_agent_list.html +0 -18
  311. flock/webapp/templates/partials/_agent_manager_view.html +0 -51
  312. flock/webapp/templates/partials/_agent_tools_checklist.html +0 -14
  313. flock/webapp/templates/partials/_chat_container.html +0 -15
  314. flock/webapp/templates/partials/_chat_messages.html +0 -57
  315. flock/webapp/templates/partials/_chat_settings_form.html +0 -85
  316. flock/webapp/templates/partials/_create_flock_form.html +0 -50
  317. flock/webapp/templates/partials/_dashboard_flock_detail.html +0 -17
  318. flock/webapp/templates/partials/_dashboard_flock_file_list.html +0 -16
  319. flock/webapp/templates/partials/_dashboard_flock_properties_preview.html +0 -28
  320. flock/webapp/templates/partials/_dashboard_upload_flock_form.html +0 -16
  321. flock/webapp/templates/partials/_dynamic_input_form_content.html +0 -22
  322. flock/webapp/templates/partials/_env_vars_table.html +0 -23
  323. flock/webapp/templates/partials/_execution_form.html +0 -118
  324. flock/webapp/templates/partials/_execution_view_container.html +0 -28
  325. flock/webapp/templates/partials/_flock_file_list.html +0 -23
  326. flock/webapp/templates/partials/_flock_properties_form.html +0 -52
  327. flock/webapp/templates/partials/_flock_upload_form.html +0 -16
  328. flock/webapp/templates/partials/_header_flock_status.html +0 -5
  329. flock/webapp/templates/partials/_load_manager_view.html +0 -49
  330. flock/webapp/templates/partials/_registry_table.html +0 -25
  331. flock/webapp/templates/partials/_registry_viewer_content.html +0 -70
  332. flock/webapp/templates/partials/_results_display.html +0 -78
  333. flock/webapp/templates/partials/_settings_env_content.html +0 -9
  334. flock/webapp/templates/partials/_settings_theme_content.html +0 -14
  335. flock/webapp/templates/partials/_settings_view.html +0 -36
  336. flock/webapp/templates/partials/_share_chat_link_snippet.html +0 -11
  337. flock/webapp/templates/partials/_share_link_snippet.html +0 -35
  338. flock/webapp/templates/partials/_sidebar.html +0 -74
  339. flock/webapp/templates/partials/_streaming_results_container.html +0 -195
  340. flock/webapp/templates/partials/_structured_data_view.html +0 -40
  341. flock/webapp/templates/partials/_theme_preview.html +0 -36
  342. flock/webapp/templates/registry_viewer.html +0 -84
  343. flock/webapp/templates/shared_run_page.html +0 -140
  344. flock/workflow/__init__.py +0 -0
  345. flock/workflow/activities.py +0 -196
  346. flock/workflow/agent_activities.py +0 -24
  347. flock/workflow/agent_execution_activity.py +0 -202
  348. flock/workflow/flock_workflow.py +0 -214
  349. flock/workflow/temporal_config.py +0 -96
  350. flock/workflow/temporal_setup.py +0 -68
  351. flock_core-0.5.0b27.dist-info/METADATA +0 -274
  352. flock_core-0.5.0b27.dist-info/RECORD +0 -559
  353. flock_core-0.5.0b27.dist-info/entry_points.txt +0 -2
  354. /flock/{core/logging → logging}/formatters/themes.py +0 -0
  355. /flock/{core/logging → logging}/span_middleware/baggage_span_processor.py +0 -0
  356. /flock/{core/mcp → mcp}/util/__init__.py +0 -0
  357. {flock_core-0.5.0b27.dist-info → flock_core-0.5.0b50.dist-info}/WHEEL +0 -0
@@ -11,16 +11,13 @@ from contextlib import (
11
11
  )
12
12
  from datetime import timedelta
13
13
  from typing import (
14
+ TYPE_CHECKING,
14
15
  Any,
15
16
  )
16
17
 
17
18
  import httpx
18
19
  from anyio import ClosedResourceError
19
- from anyio.streams.memory import (
20
- MemoryObjectReceiveStream,
21
- MemoryObjectSendStream,
22
- )
23
- from cachetools import TTLCache, cached
20
+ from cachetools import TTLCache
24
21
  from mcp import (
25
22
  ClientSession,
26
23
  InitializeResult,
@@ -36,16 +33,10 @@ from pydantic import (
36
33
  Field,
37
34
  )
38
35
 
39
- from flock.core.logging.logging import get_logger
40
- from flock.core.mcp.flock_mcp_tool import FlockMCPTool
41
- from flock.core.mcp.mcp_config import FlockMCPConfiguration
42
- from flock.core.mcp.types.factories import (
43
- default_flock_mcp_list_roots_callback_factory,
44
- default_flock_mcp_logging_callback_factory,
45
- default_flock_mcp_message_handler_callback_factory,
46
- default_flock_mcp_sampling_callback_factory,
47
- )
48
- from flock.core.mcp.types.types import (
36
+ from flock.logging.logging import get_logger
37
+ from flock.mcp.config import FlockMCPConfiguration
38
+ from flock.mcp.tool import FlockMCPTool
39
+ from flock.mcp.types import (
49
40
  FlockListRootsMCPCallback,
50
41
  FlockLoggingMCPCallback,
51
42
  FlockMessageHandlerMCPCallback,
@@ -53,7 +44,21 @@ from flock.core.mcp.types.types import (
53
44
  MCPRoot,
54
45
  ServerParameters,
55
46
  )
56
- from flock.core.mcp.util.helpers import cache_key_generator
47
+ from flock.mcp.types.factories import (
48
+ default_flock_mcp_list_roots_callback_factory,
49
+ default_flock_mcp_logging_callback_factory,
50
+ default_flock_mcp_message_handler_callback_factory,
51
+ default_flock_mcp_sampling_callback_factory,
52
+ )
53
+ from flock.mcp.util.helpers import cache_key_generator
54
+
55
+
56
+ if TYPE_CHECKING:
57
+ from anyio.streams.memory import (
58
+ MemoryObjectReceiveStream,
59
+ MemoryObjectSendStream,
60
+ )
61
+
57
62
 
58
63
  logger = get_logger("mcp.client")
59
64
  tracer = trace.get_tracer(__name__)
@@ -71,9 +76,7 @@ class FlockMCPClient(BaseModel, ABC):
71
76
  """
72
77
 
73
78
  # --- Properties ---
74
- config: FlockMCPConfiguration = Field(
75
- ..., description="The config for this client instance."
76
- )
79
+ config: FlockMCPConfiguration = Field(..., description="The config for this client instance.")
77
80
 
78
81
  tool_cache: TTLCache | None = Field(
79
82
  default=None,
@@ -154,9 +157,7 @@ class FlockMCPClient(BaseModel, ABC):
154
157
  def __getattr__(self, name: str):
155
158
  # return an async function that auto-reconnects, then calls through.
156
159
  async def _method(*args, **kwargs):
157
- with tracer.start_as_current_span(
158
- "session_proxy.__getattr__"
159
- ) as span:
160
+ with tracer.start_as_current_span("session_proxy.__getattr__") as span:
160
161
  client = self._client
161
162
  cfg = client.config
162
163
  max_tries = cfg.connection_config.max_retries or 1
@@ -170,18 +171,14 @@ class FlockMCPClient(BaseModel, ABC):
170
171
  await client._ensure_connected()
171
172
  try:
172
173
  # delegate the real session
173
- return await getattr(client.client_session, name)(
174
- *args, **kwargs
175
- )
174
+ return await getattr(client.client_session, name)(*args, **kwargs)
176
175
  except McpError as e:
177
176
  # only retry on a transport timeout
178
177
  if e.error.code == httpx.codes.REQUEST_TIMEOUT:
179
178
  kind = "timeout"
180
179
  else:
181
180
  # application-level MCP error -> give up immediately
182
- logger.error(
183
- f"MCP error in session.{name}: {e.error}"
184
- )
181
+ logger.exception(f"MCP error in session.{name}: {e.error}")
185
182
  return None
186
183
  except (BrokenPipeError, ClosedResourceError) as e:
187
184
  kind = type(e).__name__
@@ -199,9 +196,7 @@ class FlockMCPClient(BaseModel, ABC):
199
196
  try:
200
197
  await client.disconnect()
201
198
  except Exception as e:
202
- logger.warning(
203
- f"Error tearing down stale session: {e}"
204
- )
199
+ logger.warning(f"Error tearing down stale session: {e}")
205
200
  span.record_exception(e)
206
201
  return None
207
202
 
@@ -213,13 +208,14 @@ class FlockMCPClient(BaseModel, ABC):
213
208
  await client.disconnect()
214
209
  await client._connect()
215
210
  except Exception as e:
216
- logger.error(f"Reconnect failed: {e}")
211
+ logger.exception(f"Reconnect failed: {e}")
217
212
  span.record_exception(e)
218
213
 
219
214
  # Exponential backoff + 10% jitter
220
215
  delay = base_delay ** (2 ** (attempt - 1))
221
216
  delay += random.uniform(0, delay * 0.1)
222
217
  await asyncio.sleep(delay)
218
+ return None
223
219
 
224
220
  return _method
225
221
 
@@ -262,10 +258,7 @@ class FlockMCPClient(BaseModel, ABC):
262
258
  )
263
259
 
264
260
  # Check if roots are specified in the config:
265
- if (
266
- not self.current_roots
267
- and self.config.connection_config.mount_points
268
- ):
261
+ if not self.current_roots and self.config.connection_config.mount_points:
269
262
  # That means that the roots are set in the config
270
263
  self.current_roots = self.config.connection_config.mount_points
271
264
 
@@ -296,55 +289,39 @@ class FlockMCPClient(BaseModel, ABC):
296
289
  # set up callbacks
297
290
  if not self.logging_callback:
298
291
  if not self.config.callback_config.logging_callback:
299
- self.logging_callback = (
300
- default_flock_mcp_logging_callback_factory(
301
- associated_client=self,
302
- logger=logger,
303
- )
292
+ self.logging_callback = default_flock_mcp_logging_callback_factory(
293
+ associated_client=self,
294
+ logger=logger,
304
295
  )
305
296
  else:
306
- self.logging_callback = (
307
- self.config.callback_config.logging_callback
308
- )
297
+ self.logging_callback = self.config.callback_config.logging_callback
309
298
 
310
299
  if not self.message_handler:
311
300
  if not self.config.callback_config.message_handler:
312
- self.message_handler = (
313
- default_flock_mcp_message_handler_callback_factory(
314
- associated_client=self,
315
- logger=logger,
316
- )
301
+ self.message_handler = default_flock_mcp_message_handler_callback_factory(
302
+ associated_client=self,
303
+ logger=logger,
317
304
  )
318
305
  else:
319
- self.message_handler = (
320
- self.config.callback_config.message_handler
321
- )
306
+ self.message_handler = self.config.callback_config.message_handler
322
307
 
323
308
  if not self.list_roots_callback:
324
309
  if not self.config.callback_config.list_roots_callback:
325
- self.list_roots_callback = (
326
- default_flock_mcp_list_roots_callback_factory(
327
- associated_client=self,
328
- logger=logger,
329
- )
310
+ self.list_roots_callback = default_flock_mcp_list_roots_callback_factory(
311
+ associated_client=self,
312
+ logger=logger,
330
313
  )
331
314
  else:
332
- self.list_roots_callback = (
333
- self.config.callback_config.list_roots_callback
334
- )
315
+ self.list_roots_callback = self.config.callback_config.list_roots_callback
335
316
 
336
317
  if not self.sampling_callback:
337
318
  if not self.config.callback_config.sampling_callback:
338
- self.sampling_callback = (
339
- default_flock_mcp_sampling_callback_factory(
340
- associated_client=self,
341
- logger=logger,
342
- )
319
+ self.sampling_callback = default_flock_mcp_sampling_callback_factory(
320
+ associated_client=self,
321
+ logger=logger,
343
322
  )
344
323
  else:
345
- self.sampling_callback = (
346
- self.config.callback_config.sampling_callback
347
- )
324
+ self.sampling_callback = self.config.callback_config.sampling_callback
348
325
 
349
326
  @property
350
327
  def session(self) -> _SessionProxy:
@@ -377,58 +354,57 @@ class FlockMCPClient(BaseModel, ABC):
377
354
  ) -> list[FlockMCPTool]:
378
355
  """Gets a list of available tools from the server."""
379
356
 
380
- @cached(cache=self.tool_cache, key=cache_key_generator)
381
- async def _get_tools_cached(
382
- agent_id: str,
383
- run_id: str,
384
- ) -> list[FlockMCPTool]:
385
- if not self.config.feature_config.tools_enabled:
386
- return []
387
-
388
- async def _get_tools_internal() -> list[FlockMCPTool]:
389
- # TODO: Crash
390
- response: ListToolsResult = await self.session.list_tools()
391
- flock_tools = []
392
-
393
- for tool in response.tools:
394
- converted_tool = FlockMCPTool.from_mcp_tool(
395
- tool,
396
- agent_id=agent_id,
397
- run_id=run_id,
398
- )
399
- if converted_tool:
400
- flock_tools.append(converted_tool)
401
- return flock_tools
357
+ cache_key = cache_key_generator(agent_id, run_id)
402
358
 
403
- return await _get_tools_internal()
359
+ # Check cache first
360
+ if cache_key in self.tool_cache:
361
+ return self.tool_cache[cache_key]
404
362
 
405
- return await _get_tools_cached(agent_id=agent_id, run_id=run_id)
363
+ if not self.config.feature_config.tools_enabled:
364
+ result = []
365
+ self.tool_cache[cache_key] = result
366
+ return result
367
+
368
+ async def _get_tools_internal() -> list[FlockMCPTool]:
369
+ # TODO: Crash
370
+ response: ListToolsResult = await self.session.list_tools()
371
+ flock_tools = []
372
+
373
+ for tool in response.tools:
374
+ converted_tool = FlockMCPTool.from_mcp_tool(
375
+ tool,
376
+ agent_id=agent_id,
377
+ run_id=run_id,
378
+ )
379
+ if converted_tool:
380
+ flock_tools.append(converted_tool)
381
+ return flock_tools
382
+
383
+ result = await _get_tools_internal()
384
+ self.tool_cache[cache_key] = result
385
+ return result
406
386
 
407
387
  async def call_tool(
408
388
  self, agent_id: str, run_id: str, name: str, arguments: dict[str, Any]
409
389
  ) -> CallToolResult:
410
390
  """Call a tool via the MCP Protocol on the client's server."""
411
391
 
412
- @cached(cache=self.tool_result_cache, key=cache_key_generator)
413
- async def _call_tool_cached(
414
- agent_id: str, run_id: str, name: str, arguments: dict[str, Any]
415
- ) -> CallToolResult:
416
- async def _call_tool_internal(
417
- name: str, arguments: dict[str, Any]
418
- ) -> CallToolResult:
419
- logger.debug(
420
- f"Calling tool '{name}' with arguments {arguments}"
421
- )
422
- return await self.session.call_tool(
423
- name=name,
424
- arguments=arguments,
425
- )
392
+ cache_key = cache_key_generator(agent_id, run_id, name, arguments)
426
393
 
427
- return await _call_tool_internal(name=name, arguments=arguments)
394
+ # Check cache first
395
+ if cache_key in self.tool_result_cache:
396
+ return self.tool_result_cache[cache_key]
428
397
 
429
- return await _call_tool_cached(
430
- agent_id=agent_id, run_id=run_id, name=name, arguments=arguments
431
- )
398
+ async def _call_tool_internal(name: str, arguments: dict[str, Any]) -> CallToolResult:
399
+ logger.debug(f"Calling tool '{name}' with arguments {arguments}")
400
+ return await self.session.call_tool(
401
+ name=name,
402
+ arguments=arguments,
403
+ )
404
+
405
+ result = await _call_tool_internal(name=name, arguments=arguments)
406
+ self.tool_result_cache[cache_key] = result
407
+ return result
432
408
 
433
409
  async def get_server_name(self) -> str:
434
410
  """Return the server_name.
@@ -465,33 +441,23 @@ class FlockMCPClient(BaseModel, ABC):
465
441
  async with self.lock:
466
442
  if self.tool_cache:
467
443
  self.tool_cache.clear()
468
- logger.debug(
469
- f"Invalidated tool_cache for server '{self.config.name}'"
470
- )
444
+ logger.debug(f"Invalidated tool_cache for server '{self.config.name}'")
471
445
 
472
446
  async def invalidate_resource_list_cache(self) -> None:
473
447
  """Invalidate the entries in the resource list cache."""
474
- logger.debug(
475
- f"Invalidating resource_list_cache for server '{self.config.name}'"
476
- )
448
+ logger.debug(f"Invalidating resource_list_cache for server '{self.config.name}'")
477
449
  async with self.lock:
478
450
  if self.resource_list_cache:
479
451
  self.resource_list_cache.clear()
480
- logger.debug(
481
- f"Invalidated resource_list_cache for server '{self.config.name}'"
482
- )
452
+ logger.debug(f"Invalidated resource_list_cache for server '{self.config.name}'")
483
453
 
484
454
  async def invalidate_resource_contents_cache(self) -> None:
485
455
  """Invalidate the entries in the resource contents cache."""
486
- logger.debug(
487
- f"Invalidating resource_contents_cache for server '{self.config.name}'."
488
- )
456
+ logger.debug(f"Invalidating resource_contents_cache for server '{self.config.name}'.")
489
457
  async with self.lock:
490
458
  if self.resource_contents_cache:
491
459
  self.resource_contents_cache.clear()
492
- logger.debug(
493
- f"Invalidated resource_contents_cache for server '{self.config.name}'"
494
- )
460
+ logger.debug(f"Invalidated resource_contents_cache for server '{self.config.name}'")
495
461
 
496
462
  async def invalidate_resource_contents_cache_entry(self, key: str) -> None:
497
463
  """Invalidate a single entry in the resource contents cache."""
@@ -531,8 +497,7 @@ class FlockMCPClient(BaseModel, ABC):
531
497
  await cm.__aexit__(None, None, None)
532
498
  except Exception as e:
533
499
  logger.debug(
534
- f"Suppressed transport-ctx exit error "
535
- f"for server '{self.config.name}': {e!r}"
500
+ f"Suppressed transport-ctx exit error for server '{self.config.name}': {e!r}"
536
501
  )
537
502
 
538
503
  async def _create_session(self) -> None:
@@ -548,42 +513,29 @@ class FlockMCPClient(BaseModel, ABC):
548
513
  server_params = self.config.connection_config.connection_parameters
549
514
 
550
515
  # Single Hook
551
- transport_ctx = await self.create_transport(
552
- server_params, self.additional_params
553
- )
516
+ transport_ctx = await self.create_transport(server_params, self.additional_params)
554
517
  safe_transport = self._safe_transport_ctx(transport_ctx)
555
518
  result = await stack.enter_async_context(safe_transport)
556
519
 
557
520
  # support old (read, write) or new (read, write, get_sesssion_id_callback)
558
521
  read: MemoryObjectReceiveStream | None = None
559
522
  write: MemoryObjectSendStream | None = None
560
- get_session_id_callback: GetSessionIdCallback | None = None
561
523
  if isinstance(result, tuple) and len(result) == 2:
562
524
  # old type
563
525
  read, write = result
564
- get_session_id_callback = None
565
526
  elif isinstance(result, tuple) and len(result) == 3:
566
527
  # new type
567
- read, write, get_session_id_callback = result
528
+ read, write, _get_session_id_callback = result
568
529
  else:
569
- raise RuntimeError(
570
- f"create_transport returned unexpected tuple of {result}"
571
- )
530
+ raise RuntimeError(f"create_transport returned unexpected tuple of {result}")
572
531
 
573
532
  if read is None or write is None:
574
- raise RuntimeError(
575
- f"create_transport did not create any read or write streams."
576
- )
533
+ raise RuntimeError("create_transport did not create any read or write streams.")
577
534
 
578
535
  read_timeout = self.config.connection_config.read_timeout_seconds
579
536
 
580
- if (
581
- self.additional_params
582
- and "read_timeout_seconds" in self.additional_params
583
- ):
584
- read_timeout = self.additional_params.get(
585
- "read_timeout_seconds", read_timeout
586
- )
537
+ if self.additional_params and "read_timeout_seconds" in self.additional_params:
538
+ read_timeout = self.additional_params.get("read_timeout_seconds", read_timeout)
587
539
 
588
540
  timeout_seconds = (
589
541
  read_timeout
@@ -622,11 +574,10 @@ class FlockMCPClient(BaseModel, ABC):
622
574
  )
623
575
  return self.client_session
624
576
 
625
- else:
626
- logger.debug(
627
- f"Client Session for Server '{self.config.name}' does not exist yet. Connecting..."
628
- )
629
- await self._create_session()
577
+ logger.debug(
578
+ f"Client Session for Server '{self.config.name}' does not exist yet. Connecting..."
579
+ )
580
+ await self._create_session()
630
581
 
631
582
  if not self.connected_server_capabilities:
632
583
  # This means we never asked the server to initialize the connection.
@@ -636,9 +587,7 @@ class FlockMCPClient(BaseModel, ABC):
636
587
  async def _perform_initial_handshake(self) -> None:
637
588
  """Tell the server who we are, what capabilities we have, and what roots we're interested in."""
638
589
  # 1) do the LSP-style initialize handshake
639
- logger.debug(
640
- f"Performing intialize handshake with server '{self.config.name}'"
641
- )
590
+ logger.debug(f"Performing intialize handshake with server '{self.config.name}'")
642
591
  init: InitializeResult = await self.client_session.initialize()
643
592
 
644
593
  self.connected_server_capabilities = init