flock-core 0.5.0b28__py3-none-any.whl → 0.5.56b0__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 (359) 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.56b0.dist-info/METADATA +747 -0
  162. flock_core-0.5.56b0.dist-info/RECORD +398 -0
  163. flock_core-0.5.56b0.dist-info/entry_points.txt +2 -0
  164. {flock_core-0.5.0b28.dist-info → flock_core-0.5.56b0.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 -22
  197. flock/components/utility/example_utility_component.py +0 -250
  198. flock/components/utility/feedback_utility_component.py +0 -206
  199. flock/components/utility/memory_utility_component.py +0 -550
  200. flock/components/utility/metrics_utility_component.py +0 -700
  201. flock/config.py +0 -61
  202. flock/core/__init__.py +0 -110
  203. flock/core/agent/__init__.py +0 -16
  204. flock/core/agent/default_agent.py +0 -216
  205. flock/core/agent/flock_agent_components.py +0 -104
  206. flock/core/agent/flock_agent_execution.py +0 -101
  207. flock/core/agent/flock_agent_integration.py +0 -260
  208. flock/core/agent/flock_agent_lifecycle.py +0 -186
  209. flock/core/agent/flock_agent_serialization.py +0 -381
  210. flock/core/api/__init__.py +0 -10
  211. flock/core/api/custom_endpoint.py +0 -45
  212. flock/core/api/endpoints.py +0 -254
  213. flock/core/api/main.py +0 -162
  214. flock/core/api/models.py +0 -97
  215. flock/core/api/run_store.py +0 -224
  216. flock/core/api/runner.py +0 -44
  217. flock/core/api/service.py +0 -214
  218. flock/core/component/__init__.py +0 -15
  219. flock/core/component/agent_component_base.py +0 -309
  220. flock/core/component/evaluation_component.py +0 -62
  221. flock/core/component/routing_component.py +0 -74
  222. flock/core/component/utility_component.py +0 -69
  223. flock/core/config/flock_agent_config.py +0 -58
  224. flock/core/config/scheduled_agent_config.py +0 -40
  225. flock/core/context/context.py +0 -213
  226. flock/core/context/context_manager.py +0 -37
  227. flock/core/context/context_vars.py +0 -10
  228. flock/core/evaluation/utils.py +0 -396
  229. flock/core/execution/batch_executor.py +0 -369
  230. flock/core/execution/evaluation_executor.py +0 -438
  231. flock/core/execution/local_executor.py +0 -31
  232. flock/core/execution/opik_executor.py +0 -103
  233. flock/core/execution/temporal_executor.py +0 -164
  234. flock/core/flock.py +0 -634
  235. flock/core/flock_agent.py +0 -336
  236. flock/core/flock_factory.py +0 -613
  237. flock/core/flock_scheduler.py +0 -166
  238. flock/core/flock_server_manager.py +0 -136
  239. flock/core/interpreter/python_interpreter.py +0 -689
  240. flock/core/mcp/__init__.py +0 -1
  241. flock/core/mcp/flock_mcp_server.py +0 -680
  242. flock/core/mcp/mcp_client_manager.py +0 -201
  243. flock/core/mcp/types/__init__.py +0 -1
  244. flock/core/mixin/dspy_integration.py +0 -403
  245. flock/core/mixin/prompt_parser.py +0 -125
  246. flock/core/orchestration/__init__.py +0 -15
  247. flock/core/orchestration/flock_batch_processor.py +0 -94
  248. flock/core/orchestration/flock_evaluator.py +0 -113
  249. flock/core/orchestration/flock_execution.py +0 -295
  250. flock/core/orchestration/flock_initialization.py +0 -149
  251. flock/core/orchestration/flock_server_manager.py +0 -67
  252. flock/core/orchestration/flock_web_server.py +0 -117
  253. flock/core/registry/__init__.py +0 -45
  254. flock/core/registry/agent_registry.py +0 -69
  255. flock/core/registry/callable_registry.py +0 -139
  256. flock/core/registry/component_discovery.py +0 -142
  257. flock/core/registry/component_registry.py +0 -64
  258. flock/core/registry/config_mapping.py +0 -64
  259. flock/core/registry/decorators.py +0 -137
  260. flock/core/registry/registry_hub.py +0 -205
  261. flock/core/registry/server_registry.py +0 -57
  262. flock/core/registry/type_registry.py +0 -86
  263. flock/core/serialization/__init__.py +0 -13
  264. flock/core/serialization/callable_registry.py +0 -52
  265. flock/core/serialization/flock_serializer.py +0 -832
  266. flock/core/serialization/json_encoder.py +0 -41
  267. flock/core/serialization/secure_serializer.py +0 -175
  268. flock/core/serialization/serializable.py +0 -342
  269. flock/core/serialization/serialization_utils.py +0 -412
  270. flock/core/util/file_path_utils.py +0 -223
  271. flock/core/util/hydrator.py +0 -309
  272. flock/core/util/input_resolver.py +0 -164
  273. flock/core/util/loader.py +0 -59
  274. flock/core/util/splitter.py +0 -219
  275. flock/di.py +0 -27
  276. flock/platform/docker_tools.py +0 -49
  277. flock/platform/jaeger_install.py +0 -86
  278. flock/webapp/__init__.py +0 -1
  279. flock/webapp/app/__init__.py +0 -0
  280. flock/webapp/app/api/__init__.py +0 -0
  281. flock/webapp/app/api/agent_management.py +0 -241
  282. flock/webapp/app/api/execution.py +0 -709
  283. flock/webapp/app/api/flock_management.py +0 -129
  284. flock/webapp/app/api/registry_viewer.py +0 -30
  285. flock/webapp/app/chat.py +0 -665
  286. flock/webapp/app/config.py +0 -104
  287. flock/webapp/app/dependencies.py +0 -117
  288. flock/webapp/app/main.py +0 -1070
  289. flock/webapp/app/middleware.py +0 -113
  290. flock/webapp/app/models_ui.py +0 -7
  291. flock/webapp/app/services/__init__.py +0 -0
  292. flock/webapp/app/services/feedback_file_service.py +0 -363
  293. flock/webapp/app/services/flock_service.py +0 -337
  294. flock/webapp/app/services/sharing_models.py +0 -81
  295. flock/webapp/app/services/sharing_store.py +0 -762
  296. flock/webapp/app/templates/theme_mapper.html +0 -326
  297. flock/webapp/app/theme_mapper.py +0 -812
  298. flock/webapp/app/utils.py +0 -85
  299. flock/webapp/run.py +0 -215
  300. flock/webapp/static/css/chat.css +0 -301
  301. flock/webapp/static/css/components.css +0 -167
  302. flock/webapp/static/css/header.css +0 -39
  303. flock/webapp/static/css/layout.css +0 -46
  304. flock/webapp/static/css/sidebar.css +0 -127
  305. flock/webapp/static/css/two-pane.css +0 -48
  306. flock/webapp/templates/base.html +0 -200
  307. flock/webapp/templates/chat.html +0 -152
  308. flock/webapp/templates/chat_settings.html +0 -19
  309. flock/webapp/templates/flock_editor.html +0 -16
  310. flock/webapp/templates/index.html +0 -12
  311. flock/webapp/templates/partials/_agent_detail_form.html +0 -93
  312. flock/webapp/templates/partials/_agent_list.html +0 -18
  313. flock/webapp/templates/partials/_agent_manager_view.html +0 -51
  314. flock/webapp/templates/partials/_agent_tools_checklist.html +0 -14
  315. flock/webapp/templates/partials/_chat_container.html +0 -15
  316. flock/webapp/templates/partials/_chat_messages.html +0 -57
  317. flock/webapp/templates/partials/_chat_settings_form.html +0 -85
  318. flock/webapp/templates/partials/_create_flock_form.html +0 -50
  319. flock/webapp/templates/partials/_dashboard_flock_detail.html +0 -17
  320. flock/webapp/templates/partials/_dashboard_flock_file_list.html +0 -16
  321. flock/webapp/templates/partials/_dashboard_flock_properties_preview.html +0 -28
  322. flock/webapp/templates/partials/_dashboard_upload_flock_form.html +0 -16
  323. flock/webapp/templates/partials/_dynamic_input_form_content.html +0 -22
  324. flock/webapp/templates/partials/_env_vars_table.html +0 -23
  325. flock/webapp/templates/partials/_execution_form.html +0 -118
  326. flock/webapp/templates/partials/_execution_view_container.html +0 -28
  327. flock/webapp/templates/partials/_flock_file_list.html +0 -23
  328. flock/webapp/templates/partials/_flock_properties_form.html +0 -52
  329. flock/webapp/templates/partials/_flock_upload_form.html +0 -16
  330. flock/webapp/templates/partials/_header_flock_status.html +0 -5
  331. flock/webapp/templates/partials/_load_manager_view.html +0 -49
  332. flock/webapp/templates/partials/_registry_table.html +0 -25
  333. flock/webapp/templates/partials/_registry_viewer_content.html +0 -70
  334. flock/webapp/templates/partials/_results_display.html +0 -78
  335. flock/webapp/templates/partials/_settings_env_content.html +0 -9
  336. flock/webapp/templates/partials/_settings_theme_content.html +0 -14
  337. flock/webapp/templates/partials/_settings_view.html +0 -36
  338. flock/webapp/templates/partials/_share_chat_link_snippet.html +0 -11
  339. flock/webapp/templates/partials/_share_link_snippet.html +0 -35
  340. flock/webapp/templates/partials/_sidebar.html +0 -74
  341. flock/webapp/templates/partials/_streaming_results_container.html +0 -195
  342. flock/webapp/templates/partials/_structured_data_view.html +0 -40
  343. flock/webapp/templates/partials/_theme_preview.html +0 -36
  344. flock/webapp/templates/registry_viewer.html +0 -84
  345. flock/webapp/templates/shared_run_page.html +0 -140
  346. flock/workflow/__init__.py +0 -0
  347. flock/workflow/activities.py +0 -196
  348. flock/workflow/agent_activities.py +0 -24
  349. flock/workflow/agent_execution_activity.py +0 -202
  350. flock/workflow/flock_workflow.py +0 -214
  351. flock/workflow/temporal_config.py +0 -96
  352. flock/workflow/temporal_setup.py +0 -68
  353. flock_core-0.5.0b28.dist-info/METADATA +0 -274
  354. flock_core-0.5.0b28.dist-info/RECORD +0 -561
  355. flock_core-0.5.0b28.dist-info/entry_points.txt +0 -2
  356. /flock/{core/logging → logging}/formatters/themes.py +0 -0
  357. /flock/{core/logging → logging}/span_middleware/baggage_span_processor.py +0 -0
  358. /flock/{core/mcp → mcp}/util/__init__.py +0 -0
  359. {flock_core-0.5.0b28.dist-info → flock_core-0.5.56b0.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