flock-core 0.4.543__py3-none-any.whl → 0.5.0__py3-none-any.whl

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

Potentially problematic release.


This version of flock-core might be problematic. Click here for more details.

Files changed (501) hide show
  1. flock/__init__.py +12 -217
  2. flock/agent.py +1079 -0
  3. flock/api/themes.py +71 -0
  4. flock/artifacts.py +86 -0
  5. flock/cli.py +147 -0
  6. flock/components.py +189 -0
  7. flock/dashboard/__init__.py +30 -0
  8. flock/dashboard/collector.py +559 -0
  9. flock/dashboard/events.py +188 -0
  10. flock/dashboard/graph_builder.py +563 -0
  11. flock/dashboard/launcher.py +235 -0
  12. flock/dashboard/models/graph.py +156 -0
  13. flock/dashboard/service.py +991 -0
  14. flock/dashboard/static_v2/assets/index-DFRnI_mt.js +111 -0
  15. flock/dashboard/static_v2/assets/index-fPLNdmp1.css +1 -0
  16. flock/dashboard/static_v2/index.html +13 -0
  17. flock/dashboard/websocket.py +246 -0
  18. flock/engines/__init__.py +6 -0
  19. flock/engines/dspy_engine.py +932 -0
  20. flock/examples.py +131 -0
  21. flock/frontend/README.md +778 -0
  22. flock/frontend/docs/DESIGN_SYSTEM.md +1980 -0
  23. flock/frontend/index.html +12 -0
  24. flock/frontend/package-lock.json +4337 -0
  25. flock/frontend/package.json +48 -0
  26. flock/frontend/src/App.tsx +139 -0
  27. flock/frontend/src/__tests__/integration/graph-snapshot.test.tsx +647 -0
  28. flock/frontend/src/__tests__/integration/indexeddb-persistence.test.tsx +699 -0
  29. flock/frontend/src/components/common/BuildInfo.tsx +39 -0
  30. flock/frontend/src/components/common/EmptyState.module.css +115 -0
  31. flock/frontend/src/components/common/EmptyState.tsx +128 -0
  32. flock/frontend/src/components/common/ErrorBoundary.module.css +169 -0
  33. flock/frontend/src/components/common/ErrorBoundary.tsx +118 -0
  34. flock/frontend/src/components/common/KeyboardShortcutsDialog.css +251 -0
  35. flock/frontend/src/components/common/KeyboardShortcutsDialog.tsx +151 -0
  36. flock/frontend/src/components/common/LoadingSpinner.module.css +97 -0
  37. flock/frontend/src/components/common/LoadingSpinner.tsx +29 -0
  38. flock/frontend/src/components/controls/PublishControl.css +547 -0
  39. flock/frontend/src/components/controls/PublishControl.test.tsx +543 -0
  40. flock/frontend/src/components/controls/PublishControl.tsx +432 -0
  41. flock/frontend/src/components/details/DetailWindowContainer.tsx +58 -0
  42. flock/frontend/src/components/details/LiveOutputTab.test.tsx +792 -0
  43. flock/frontend/src/components/details/LiveOutputTab.tsx +220 -0
  44. flock/frontend/src/components/details/MessageDetailWindow.tsx +439 -0
  45. flock/frontend/src/components/details/MessageHistoryTab.tsx +374 -0
  46. flock/frontend/src/components/details/NodeDetailWindow.test.tsx +501 -0
  47. flock/frontend/src/components/details/NodeDetailWindow.tsx +218 -0
  48. flock/frontend/src/components/details/RunStatusTab.tsx +348 -0
  49. flock/frontend/src/components/details/tabs.test.tsx +1015 -0
  50. flock/frontend/src/components/filters/ArtifactTypeFilter.tsx +21 -0
  51. flock/frontend/src/components/filters/CorrelationIDFilter.module.css +102 -0
  52. flock/frontend/src/components/filters/CorrelationIDFilter.test.tsx +197 -0
  53. flock/frontend/src/components/filters/CorrelationIDFilter.tsx +121 -0
  54. flock/frontend/src/components/filters/FilterFlyout.module.css +104 -0
  55. flock/frontend/src/components/filters/FilterFlyout.tsx +80 -0
  56. flock/frontend/src/components/filters/FilterPills.module.css +220 -0
  57. flock/frontend/src/components/filters/FilterPills.test.tsx +189 -0
  58. flock/frontend/src/components/filters/FilterPills.tsx +143 -0
  59. flock/frontend/src/components/filters/ProducerFilter.tsx +21 -0
  60. flock/frontend/src/components/filters/SavedFiltersControl.module.css +60 -0
  61. flock/frontend/src/components/filters/SavedFiltersControl.test.tsx +158 -0
  62. flock/frontend/src/components/filters/SavedFiltersControl.tsx +159 -0
  63. flock/frontend/src/components/filters/TagFilter.tsx +21 -0
  64. flock/frontend/src/components/filters/TimeRangeFilter.module.css +115 -0
  65. flock/frontend/src/components/filters/TimeRangeFilter.test.tsx +154 -0
  66. flock/frontend/src/components/filters/TimeRangeFilter.tsx +110 -0
  67. flock/frontend/src/components/filters/VisibilityFilter.tsx +21 -0
  68. flock/frontend/src/components/graph/AgentNode.test.tsx +77 -0
  69. flock/frontend/src/components/graph/AgentNode.tsx +324 -0
  70. flock/frontend/src/components/graph/GraphCanvas.tsx +613 -0
  71. flock/frontend/src/components/graph/MessageFlowEdge.tsx +128 -0
  72. flock/frontend/src/components/graph/MessageNode.test.tsx +64 -0
  73. flock/frontend/src/components/graph/MessageNode.tsx +129 -0
  74. flock/frontend/src/components/graph/MiniMap.tsx +47 -0
  75. flock/frontend/src/components/graph/TransformEdge.tsx +123 -0
  76. flock/frontend/src/components/layout/DashboardLayout.css +420 -0
  77. flock/frontend/src/components/layout/DashboardLayout.tsx +287 -0
  78. flock/frontend/src/components/layout/Header.module.css +88 -0
  79. flock/frontend/src/components/layout/Header.tsx +52 -0
  80. flock/frontend/src/components/modules/HistoricalArtifactsModule.module.css +288 -0
  81. flock/frontend/src/components/modules/HistoricalArtifactsModule.tsx +450 -0
  82. flock/frontend/src/components/modules/HistoricalArtifactsModuleWrapper.tsx +13 -0
  83. flock/frontend/src/components/modules/JsonAttributeRenderer.tsx +140 -0
  84. flock/frontend/src/components/modules/ModuleRegistry.test.ts +333 -0
  85. flock/frontend/src/components/modules/ModuleRegistry.ts +93 -0
  86. flock/frontend/src/components/modules/ModuleWindow.tsx +223 -0
  87. flock/frontend/src/components/modules/TraceModuleJaeger.tsx +1971 -0
  88. flock/frontend/src/components/modules/TraceModuleJaegerWrapper.tsx +13 -0
  89. flock/frontend/src/components/modules/registerModules.ts +29 -0
  90. flock/frontend/src/components/settings/AdvancedSettings.tsx +175 -0
  91. flock/frontend/src/components/settings/AppearanceSettings.tsx +185 -0
  92. flock/frontend/src/components/settings/GraphSettings.tsx +110 -0
  93. flock/frontend/src/components/settings/MultiSelect.tsx +235 -0
  94. flock/frontend/src/components/settings/SettingsPanel.css +327 -0
  95. flock/frontend/src/components/settings/SettingsPanel.tsx +131 -0
  96. flock/frontend/src/components/settings/ThemeSelector.tsx +298 -0
  97. flock/frontend/src/components/settings/TracingSettings.tsx +404 -0
  98. flock/frontend/src/hooks/useKeyboardShortcuts.ts +148 -0
  99. flock/frontend/src/hooks/useModulePersistence.test.ts +442 -0
  100. flock/frontend/src/hooks/useModulePersistence.ts +154 -0
  101. flock/frontend/src/hooks/useModules.ts +157 -0
  102. flock/frontend/src/hooks/usePersistence.ts +141 -0
  103. flock/frontend/src/main.tsx +13 -0
  104. flock/frontend/src/services/api.ts +337 -0
  105. flock/frontend/src/services/graphService.test.ts +330 -0
  106. flock/frontend/src/services/graphService.ts +75 -0
  107. flock/frontend/src/services/indexeddb.test.ts +793 -0
  108. flock/frontend/src/services/indexeddb.ts +848 -0
  109. flock/frontend/src/services/layout.test.ts +437 -0
  110. flock/frontend/src/services/layout.ts +357 -0
  111. flock/frontend/src/services/themeApplicator.ts +140 -0
  112. flock/frontend/src/services/themeService.ts +77 -0
  113. flock/frontend/src/services/websocket.ts +650 -0
  114. flock/frontend/src/store/filterStore.test.ts +250 -0
  115. flock/frontend/src/store/filterStore.ts +272 -0
  116. flock/frontend/src/store/graphStore.test.ts +570 -0
  117. flock/frontend/src/store/graphStore.ts +462 -0
  118. flock/frontend/src/store/moduleStore.test.ts +253 -0
  119. flock/frontend/src/store/moduleStore.ts +75 -0
  120. flock/frontend/src/store/settingsStore.ts +188 -0
  121. flock/frontend/src/store/streamStore.ts +68 -0
  122. flock/frontend/src/store/uiStore.test.ts +54 -0
  123. flock/frontend/src/store/uiStore.ts +122 -0
  124. flock/frontend/src/store/wsStore.ts +34 -0
  125. flock/frontend/src/styles/index.css +15 -0
  126. flock/frontend/src/styles/scrollbar.css +47 -0
  127. flock/frontend/src/styles/variables.css +488 -0
  128. flock/frontend/src/test/setup.ts +1 -0
  129. flock/frontend/src/types/filters.ts +47 -0
  130. flock/frontend/src/types/graph.ts +95 -0
  131. flock/frontend/src/types/modules.ts +10 -0
  132. flock/frontend/src/types/theme.ts +55 -0
  133. flock/frontend/src/utils/artifacts.ts +24 -0
  134. flock/frontend/src/utils/mockData.ts +98 -0
  135. flock/frontend/src/utils/performance.ts +16 -0
  136. flock/frontend/src/vite-env.d.ts +17 -0
  137. flock/frontend/tsconfig.json +27 -0
  138. flock/frontend/tsconfig.node.json +11 -0
  139. flock/frontend/vite.config.ts +25 -0
  140. flock/frontend/vitest.config.ts +11 -0
  141. flock/{core/util → helper}/cli_helper.py +9 -5
  142. flock/{core/logging → logging}/__init__.py +2 -3
  143. flock/logging/auto_trace.py +159 -0
  144. flock/{core/logging → logging}/formatters/enum_builder.py +3 -4
  145. flock/{core/logging → logging}/formatters/theme_builder.py +19 -44
  146. flock/{core/logging → logging}/formatters/themed_formatter.py +69 -107
  147. flock/{core/logging → logging}/logging.py +78 -61
  148. flock/{core/logging → logging}/telemetry.py +66 -26
  149. flock/{core/logging → logging}/telemetry_exporter/base_exporter.py +2 -2
  150. flock/logging/telemetry_exporter/duckdb_exporter.py +216 -0
  151. flock/{core/logging → logging}/telemetry_exporter/file_exporter.py +13 -10
  152. flock/{core/logging → logging}/telemetry_exporter/sqlite_exporter.py +2 -3
  153. flock/logging/trace_and_logged.py +304 -0
  154. flock/mcp/__init__.py +91 -0
  155. flock/{core/mcp/mcp_client.py → mcp/client.py} +131 -158
  156. flock/{core/mcp/mcp_config.py → mcp/config.py} +86 -132
  157. flock/mcp/manager.py +286 -0
  158. flock/mcp/servers/sse/__init__.py +1 -1
  159. flock/mcp/servers/sse/flock_sse_server.py +16 -58
  160. flock/mcp/servers/stdio/__init__.py +1 -1
  161. flock/mcp/servers/stdio/flock_stdio_server.py +13 -53
  162. flock/mcp/servers/streamable_http/flock_streamable_http_server.py +22 -67
  163. flock/mcp/servers/websockets/flock_websocket_server.py +12 -45
  164. flock/{core/mcp/flock_mcp_tool_base.py → mcp/tool.py} +24 -78
  165. flock/mcp/types/__init__.py +42 -0
  166. flock/{core/mcp → mcp}/types/callbacks.py +12 -15
  167. flock/{core/mcp → mcp}/types/factories.py +7 -6
  168. flock/{core/mcp → mcp}/types/handlers.py +13 -18
  169. flock/{core/mcp → mcp}/types/types.py +70 -74
  170. flock/{core/mcp → mcp}/util/helpers.py +3 -3
  171. flock/orchestrator.py +970 -0
  172. flock/registry.py +148 -0
  173. flock/runtime.py +262 -0
  174. flock/service.py +277 -0
  175. flock/store.py +1214 -0
  176. flock/subscription.py +111 -0
  177. flock/themes/andromeda.toml +1 -1
  178. flock/themes/apple-system-colors.toml +1 -1
  179. flock/themes/arcoiris.toml +1 -1
  180. flock/themes/atomonelight.toml +1 -1
  181. flock/themes/ayu copy.toml +1 -1
  182. flock/themes/ayu-light.toml +1 -1
  183. flock/themes/belafonte-day.toml +1 -1
  184. flock/themes/belafonte-night.toml +1 -1
  185. flock/themes/blulocodark.toml +1 -1
  186. flock/themes/breeze.toml +1 -1
  187. flock/themes/broadcast.toml +1 -1
  188. flock/themes/brogrammer.toml +1 -1
  189. flock/themes/builtin-dark.toml +1 -1
  190. flock/themes/builtin-pastel-dark.toml +1 -1
  191. flock/themes/catppuccin-latte.toml +1 -1
  192. flock/themes/catppuccin-macchiato.toml +1 -1
  193. flock/themes/catppuccin-mocha.toml +1 -1
  194. flock/themes/cga.toml +1 -1
  195. flock/themes/chalk.toml +1 -1
  196. flock/themes/ciapre.toml +1 -1
  197. flock/themes/coffee-theme.toml +1 -1
  198. flock/themes/cyberpunkscarletprotocol.toml +1 -1
  199. flock/themes/dark+.toml +1 -1
  200. flock/themes/darkermatrix.toml +1 -1
  201. flock/themes/darkmatrix.toml +2 -2
  202. flock/themes/darkside.toml +1 -1
  203. flock/themes/deep.toml +2 -2
  204. flock/themes/desert.toml +1 -1
  205. flock/themes/django.toml +1 -1
  206. flock/themes/djangosmooth.toml +1 -1
  207. flock/themes/doomone.toml +1 -1
  208. flock/themes/dotgov.toml +1 -1
  209. flock/themes/dracula+.toml +1 -1
  210. flock/themes/duckbones.toml +1 -1
  211. flock/themes/encom.toml +1 -1
  212. flock/themes/espresso.toml +1 -1
  213. flock/themes/everblush.toml +1 -1
  214. flock/themes/fairyfloss.toml +1 -1
  215. flock/themes/fideloper.toml +1 -1
  216. flock/themes/fishtank.toml +1 -1
  217. flock/themes/flexoki-light.toml +1 -1
  218. flock/themes/floraverse.toml +1 -1
  219. flock/themes/framer.toml +1 -1
  220. flock/themes/galizur.toml +1 -1
  221. flock/themes/github.toml +1 -1
  222. flock/themes/grass.toml +1 -1
  223. flock/themes/grey-green.toml +1 -1
  224. flock/themes/gruvboxlight.toml +1 -1
  225. flock/themes/guezwhoz.toml +1 -1
  226. flock/themes/harper.toml +1 -1
  227. flock/themes/hax0r-blue.toml +1 -1
  228. flock/themes/hopscotch.256.toml +1 -1
  229. flock/themes/ic-green-ppl.toml +1 -1
  230. flock/themes/iceberg-dark.toml +1 -1
  231. flock/themes/japanesque.toml +1 -1
  232. flock/themes/jubi.toml +1 -1
  233. flock/themes/kibble.toml +1 -1
  234. flock/themes/kolorit.toml +1 -1
  235. flock/themes/kurokula.toml +1 -1
  236. flock/themes/materialdesigncolors.toml +1 -1
  237. flock/themes/matrix.toml +1 -1
  238. flock/themes/mellifluous.toml +1 -1
  239. flock/themes/midnight-in-mojave.toml +1 -1
  240. flock/themes/monokai-remastered.toml +1 -1
  241. flock/themes/monokai-soda.toml +1 -1
  242. flock/themes/neon.toml +1 -1
  243. flock/themes/neopolitan.toml +5 -5
  244. flock/themes/nord-light.toml +1 -1
  245. flock/themes/ocean.toml +1 -1
  246. flock/themes/onehalfdark.toml +1 -1
  247. flock/themes/onehalflight.toml +1 -1
  248. flock/themes/palenighthc.toml +1 -1
  249. flock/themes/paulmillr.toml +1 -1
  250. flock/themes/pencildark.toml +1 -1
  251. flock/themes/pnevma.toml +1 -1
  252. flock/themes/purple-rain.toml +1 -1
  253. flock/themes/purplepeter.toml +1 -1
  254. flock/themes/raycast-dark.toml +1 -1
  255. flock/themes/red-sands.toml +1 -1
  256. flock/themes/relaxed.toml +1 -1
  257. flock/themes/retro.toml +1 -1
  258. flock/themes/rose-pine.toml +1 -1
  259. flock/themes/royal.toml +1 -1
  260. flock/themes/ryuuko.toml +1 -1
  261. flock/themes/sakura.toml +1 -1
  262. flock/themes/scarlet-protocol.toml +1 -1
  263. flock/themes/seoulbones-dark.toml +1 -1
  264. flock/themes/shades-of-purple.toml +1 -1
  265. flock/themes/smyck.toml +1 -1
  266. flock/themes/softserver.toml +1 -1
  267. flock/themes/solarized-darcula.toml +1 -1
  268. flock/themes/square.toml +1 -1
  269. flock/themes/sugarplum.toml +1 -1
  270. flock/themes/thayer-bright.toml +1 -1
  271. flock/themes/tokyonight.toml +1 -1
  272. flock/themes/tomorrow.toml +1 -1
  273. flock/themes/ubuntu.toml +1 -1
  274. flock/themes/ultradark.toml +1 -1
  275. flock/themes/ultraviolent.toml +1 -1
  276. flock/themes/unikitty.toml +1 -1
  277. flock/themes/urple.toml +1 -1
  278. flock/themes/vesper.toml +1 -1
  279. flock/themes/vimbones.toml +1 -1
  280. flock/themes/wildcherry.toml +1 -1
  281. flock/themes/wilmersdorf.toml +1 -1
  282. flock/themes/wryan.toml +1 -1
  283. flock/themes/xcodedarkhc.toml +1 -1
  284. flock/themes/xcodelight.toml +1 -1
  285. flock/themes/zenbones-light.toml +1 -1
  286. flock/themes/zenwritten-dark.toml +1 -1
  287. flock/utilities.py +301 -0
  288. flock/utility/output_utility_component.py +226 -0
  289. flock/visibility.py +107 -0
  290. flock_core-0.5.0.dist-info/METADATA +964 -0
  291. flock_core-0.5.0.dist-info/RECORD +525 -0
  292. flock_core-0.5.0.dist-info/entry_points.txt +2 -0
  293. {flock_core-0.4.543.dist-info → flock_core-0.5.0.dist-info}/licenses/LICENSE +1 -1
  294. flock/adapter/__init__.py +0 -14
  295. flock/adapter/azure_adapter.py +0 -68
  296. flock/adapter/chroma_adapter.py +0 -73
  297. flock/adapter/faiss_adapter.py +0 -97
  298. flock/adapter/pinecone_adapter.py +0 -51
  299. flock/adapter/vector_base.py +0 -47
  300. flock/cli/assets/release_notes.md +0 -140
  301. flock/cli/config.py +0 -8
  302. flock/cli/constants.py +0 -36
  303. flock/cli/create_agent.py +0 -1
  304. flock/cli/create_flock.py +0 -280
  305. flock/cli/execute_flock.py +0 -620
  306. flock/cli/load_agent.py +0 -1
  307. flock/cli/load_examples.py +0 -1
  308. flock/cli/load_flock.py +0 -192
  309. flock/cli/load_release_notes.py +0 -20
  310. flock/cli/loaded_flock_cli.py +0 -254
  311. flock/cli/manage_agents.py +0 -459
  312. flock/cli/registry_management.py +0 -889
  313. flock/cli/runner.py +0 -41
  314. flock/cli/settings.py +0 -857
  315. flock/cli/utils.py +0 -135
  316. flock/cli/view_results.py +0 -29
  317. flock/cli/yaml_editor.py +0 -396
  318. flock/config.py +0 -56
  319. flock/core/__init__.py +0 -44
  320. flock/core/api/__init__.py +0 -10
  321. flock/core/api/custom_endpoint.py +0 -45
  322. flock/core/api/endpoints.py +0 -262
  323. flock/core/api/main.py +0 -162
  324. flock/core/api/models.py +0 -101
  325. flock/core/api/run_store.py +0 -224
  326. flock/core/api/runner.py +0 -44
  327. flock/core/api/service.py +0 -214
  328. flock/core/config/flock_agent_config.py +0 -11
  329. flock/core/config/scheduled_agent_config.py +0 -40
  330. flock/core/context/context.py +0 -214
  331. flock/core/context/context_manager.py +0 -40
  332. flock/core/context/context_vars.py +0 -11
  333. flock/core/evaluation/utils.py +0 -395
  334. flock/core/execution/batch_executor.py +0 -369
  335. flock/core/execution/evaluation_executor.py +0 -438
  336. flock/core/execution/local_executor.py +0 -31
  337. flock/core/execution/opik_executor.py +0 -103
  338. flock/core/execution/temporal_executor.py +0 -166
  339. flock/core/flock.py +0 -1003
  340. flock/core/flock_agent.py +0 -1258
  341. flock/core/flock_evaluator.py +0 -60
  342. flock/core/flock_factory.py +0 -513
  343. flock/core/flock_module.py +0 -207
  344. flock/core/flock_registry.py +0 -702
  345. flock/core/flock_router.py +0 -83
  346. flock/core/flock_scheduler.py +0 -166
  347. flock/core/flock_server_manager.py +0 -136
  348. flock/core/interpreter/python_interpreter.py +0 -689
  349. flock/core/logging/live_capture.py +0 -137
  350. flock/core/logging/trace_and_logged.py +0 -59
  351. flock/core/mcp/__init__.py +0 -1
  352. flock/core/mcp/flock_mcp_server.py +0 -640
  353. flock/core/mcp/mcp_client_manager.py +0 -201
  354. flock/core/mcp/types/__init__.py +0 -1
  355. flock/core/mixin/dspy_integration.py +0 -445
  356. flock/core/mixin/prompt_parser.py +0 -125
  357. flock/core/serialization/__init__.py +0 -13
  358. flock/core/serialization/callable_registry.py +0 -52
  359. flock/core/serialization/flock_serializer.py +0 -854
  360. flock/core/serialization/json_encoder.py +0 -41
  361. flock/core/serialization/secure_serializer.py +0 -175
  362. flock/core/serialization/serializable.py +0 -342
  363. flock/core/serialization/serialization_utils.py +0 -409
  364. flock/core/util/file_path_utils.py +0 -223
  365. flock/core/util/hydrator.py +0 -309
  366. flock/core/util/input_resolver.py +0 -141
  367. flock/core/util/loader.py +0 -59
  368. flock/core/util/splitter.py +0 -219
  369. flock/di.py +0 -41
  370. flock/evaluators/__init__.py +0 -1
  371. flock/evaluators/declarative/__init__.py +0 -1
  372. flock/evaluators/declarative/declarative_evaluator.py +0 -217
  373. flock/evaluators/memory/memory_evaluator.py +0 -90
  374. flock/evaluators/test/test_case_evaluator.py +0 -38
  375. flock/evaluators/zep/zep_evaluator.py +0 -59
  376. flock/modules/__init__.py +0 -1
  377. flock/modules/assertion/__init__.py +0 -1
  378. flock/modules/assertion/assertion_module.py +0 -286
  379. flock/modules/callback/__init__.py +0 -1
  380. flock/modules/callback/callback_module.py +0 -91
  381. flock/modules/enterprise_memory/README.md +0 -99
  382. flock/modules/enterprise_memory/enterprise_memory_module.py +0 -526
  383. flock/modules/mem0/__init__.py +0 -1
  384. flock/modules/mem0/mem0_module.py +0 -126
  385. flock/modules/mem0_async/__init__.py +0 -1
  386. flock/modules/mem0_async/async_mem0_module.py +0 -126
  387. flock/modules/memory/__init__.py +0 -1
  388. flock/modules/memory/memory_module.py +0 -429
  389. flock/modules/memory/memory_parser.py +0 -125
  390. flock/modules/memory/memory_storage.py +0 -736
  391. flock/modules/output/__init__.py +0 -1
  392. flock/modules/output/output_module.py +0 -196
  393. flock/modules/performance/__init__.py +0 -1
  394. flock/modules/performance/metrics_module.py +0 -678
  395. flock/modules/zep/__init__.py +0 -1
  396. flock/modules/zep/zep_module.py +0 -192
  397. flock/platform/docker_tools.py +0 -49
  398. flock/platform/jaeger_install.py +0 -86
  399. flock/routers/__init__.py +0 -1
  400. flock/routers/agent/__init__.py +0 -1
  401. flock/routers/agent/agent_router.py +0 -236
  402. flock/routers/agent/handoff_agent.py +0 -58
  403. flock/routers/conditional/conditional_router.py +0 -486
  404. flock/routers/default/__init__.py +0 -1
  405. flock/routers/default/default_router.py +0 -80
  406. flock/routers/feedback/feedback_router.py +0 -114
  407. flock/routers/list_generator/list_generator_router.py +0 -166
  408. flock/routers/llm/__init__.py +0 -1
  409. flock/routers/llm/llm_router.py +0 -365
  410. flock/tools/__init__.py +0 -0
  411. flock/tools/azure_tools.py +0 -781
  412. flock/tools/code_tools.py +0 -167
  413. flock/tools/file_tools.py +0 -149
  414. flock/tools/github_tools.py +0 -157
  415. flock/tools/markdown_tools.py +0 -205
  416. flock/tools/system_tools.py +0 -9
  417. flock/tools/text_tools.py +0 -810
  418. flock/tools/web_tools.py +0 -92
  419. flock/tools/zendesk_tools.py +0 -501
  420. flock/webapp/__init__.py +0 -1
  421. flock/webapp/app/__init__.py +0 -0
  422. flock/webapp/app/api/__init__.py +0 -0
  423. flock/webapp/app/api/agent_management.py +0 -237
  424. flock/webapp/app/api/execution.py +0 -503
  425. flock/webapp/app/api/flock_management.py +0 -125
  426. flock/webapp/app/api/registry_viewer.py +0 -29
  427. flock/webapp/app/chat.py +0 -662
  428. flock/webapp/app/config.py +0 -104
  429. flock/webapp/app/dependencies.py +0 -117
  430. flock/webapp/app/main.py +0 -1086
  431. flock/webapp/app/middleware.py +0 -113
  432. flock/webapp/app/models_ui.py +0 -7
  433. flock/webapp/app/services/__init__.py +0 -0
  434. flock/webapp/app/services/feedback_file_service.py +0 -363
  435. flock/webapp/app/services/flock_service.py +0 -345
  436. flock/webapp/app/services/sharing_models.py +0 -81
  437. flock/webapp/app/services/sharing_store.py +0 -597
  438. flock/webapp/app/templates/theme_mapper.html +0 -326
  439. flock/webapp/app/theme_mapper.py +0 -811
  440. flock/webapp/app/utils.py +0 -85
  441. flock/webapp/run.py +0 -219
  442. flock/webapp/static/css/chat.css +0 -301
  443. flock/webapp/static/css/components.css +0 -167
  444. flock/webapp/static/css/header.css +0 -39
  445. flock/webapp/static/css/layout.css +0 -281
  446. flock/webapp/static/css/sidebar.css +0 -127
  447. flock/webapp/static/css/two-pane.css +0 -48
  448. flock/webapp/templates/base.html +0 -389
  449. flock/webapp/templates/chat.html +0 -152
  450. flock/webapp/templates/chat_settings.html +0 -19
  451. flock/webapp/templates/flock_editor.html +0 -16
  452. flock/webapp/templates/index.html +0 -12
  453. flock/webapp/templates/partials/_agent_detail_form.html +0 -93
  454. flock/webapp/templates/partials/_agent_list.html +0 -18
  455. flock/webapp/templates/partials/_agent_manager_view.html +0 -51
  456. flock/webapp/templates/partials/_agent_tools_checklist.html +0 -14
  457. flock/webapp/templates/partials/_chat_container.html +0 -15
  458. flock/webapp/templates/partials/_chat_messages.html +0 -57
  459. flock/webapp/templates/partials/_chat_settings_form.html +0 -85
  460. flock/webapp/templates/partials/_create_flock_form.html +0 -50
  461. flock/webapp/templates/partials/_dashboard_flock_detail.html +0 -17
  462. flock/webapp/templates/partials/_dashboard_flock_file_list.html +0 -16
  463. flock/webapp/templates/partials/_dashboard_flock_properties_preview.html +0 -28
  464. flock/webapp/templates/partials/_dashboard_upload_flock_form.html +0 -16
  465. flock/webapp/templates/partials/_dynamic_input_form_content.html +0 -22
  466. flock/webapp/templates/partials/_env_vars_table.html +0 -23
  467. flock/webapp/templates/partials/_execution_form.html +0 -127
  468. flock/webapp/templates/partials/_execution_view_container.html +0 -28
  469. flock/webapp/templates/partials/_flock_file_list.html +0 -23
  470. flock/webapp/templates/partials/_flock_properties_form.html +0 -52
  471. flock/webapp/templates/partials/_flock_upload_form.html +0 -16
  472. flock/webapp/templates/partials/_header_flock_status.html +0 -5
  473. flock/webapp/templates/partials/_live_logs.html +0 -13
  474. flock/webapp/templates/partials/_load_manager_view.html +0 -49
  475. flock/webapp/templates/partials/_registry_table.html +0 -25
  476. flock/webapp/templates/partials/_registry_viewer_content.html +0 -70
  477. flock/webapp/templates/partials/_results_display.html +0 -78
  478. flock/webapp/templates/partials/_settings_env_content.html +0 -9
  479. flock/webapp/templates/partials/_settings_theme_content.html +0 -14
  480. flock/webapp/templates/partials/_settings_view.html +0 -36
  481. flock/webapp/templates/partials/_share_chat_link_snippet.html +0 -11
  482. flock/webapp/templates/partials/_share_link_snippet.html +0 -35
  483. flock/webapp/templates/partials/_sidebar.html +0 -74
  484. flock/webapp/templates/partials/_structured_data_view.html +0 -40
  485. flock/webapp/templates/partials/_theme_preview.html +0 -36
  486. flock/webapp/templates/registry_viewer.html +0 -84
  487. flock/webapp/templates/shared_run_page.html +0 -140
  488. flock/workflow/__init__.py +0 -0
  489. flock/workflow/activities.py +0 -237
  490. flock/workflow/agent_activities.py +0 -24
  491. flock/workflow/agent_execution_activity.py +0 -240
  492. flock/workflow/flock_workflow.py +0 -225
  493. flock/workflow/temporal_config.py +0 -96
  494. flock/workflow/temporal_setup.py +0 -60
  495. flock_core-0.4.543.dist-info/METADATA +0 -676
  496. flock_core-0.4.543.dist-info/RECORD +0 -572
  497. flock_core-0.4.543.dist-info/entry_points.txt +0 -2
  498. /flock/{core/logging → logging}/formatters/themes.py +0 -0
  499. /flock/{core/logging → logging}/span_middleware/baggage_span_processor.py +0 -0
  500. /flock/{core/mcp → mcp}/util/__init__.py +0 -0
  501. {flock_core-0.4.543.dist-info → flock_core-0.5.0.dist-info}/WHEEL +0 -0
@@ -1,201 +0,0 @@
1
- """Manages a pool of connections for a particular server."""
2
-
3
- import copy
4
- from abc import ABC, abstractmethod
5
- from asyncio import Lock
6
- from typing import Any, Generic, TypeVar
7
-
8
- from opentelemetry import trace
9
- from pydantic import (
10
- BaseModel,
11
- ConfigDict,
12
- Field,
13
- )
14
-
15
- from flock.core.logging.logging import get_logger
16
- from flock.core.mcp.flock_mcp_tool_base import FlockMCPToolBase
17
- from flock.core.mcp.mcp_client import (
18
- FlockMCPClientBase,
19
- )
20
- from flock.core.mcp.mcp_config import FlockMCPConfigurationBase
21
-
22
- logger = get_logger("mcp.client_manager")
23
- tracer = trace.get_tracer(__name__)
24
-
25
- TClient = TypeVar("TClient", bound="FlockMCPClientBase")
26
-
27
-
28
- class FlockMCPClientManagerBase(BaseModel, ABC, Generic[TClient]):
29
- """Handles a Pool of MCPClients of type TClient."""
30
-
31
- client_config: FlockMCPConfigurationBase = Field(
32
- ..., description="Configuration for clients."
33
- )
34
-
35
- lock: Lock = Field(
36
- default_factory=Lock,
37
- description="Lock for mutex access.",
38
- exclude=True,
39
- )
40
-
41
- clients: dict[str, dict[str, FlockMCPClientBase]] = Field(
42
- default_factory=dict,
43
- exclude=True,
44
- description="Internal Store for the clients.",
45
- )
46
-
47
- # --- Pydantic v2 Configuratioin ---
48
- model_config = ConfigDict(
49
- arbitrary_types_allowed=True,
50
- )
51
-
52
- @abstractmethod
53
- async def make_client(
54
- self,
55
- additional_params: dict[str, Any] | None = None,
56
- ) -> type[TClient]:
57
- """Instantiate-but don't connect yet-a fresh client of the concrete subtype."""
58
- # default implementation
59
- pass
60
-
61
- async def get_client(
62
- self,
63
- agent_id: str,
64
- run_id: str,
65
- additional_params: dict[str, Any] | None = None,
66
- ) -> type[TClient]:
67
- """Provides a client from the pool."""
68
- # Attempt to get a client from the client store.
69
- # clients are stored like this: agent_id -> run_id -> client
70
- with tracer.start_as_current_span("client_manager.get_client") as span:
71
- span.set_attribute("agent_id", agent_id)
72
- span.set_attribute("run_id", run_id)
73
- async with self.lock:
74
- try:
75
- logger.debug(
76
- f"Attempting to get client for server '{self.client_config.name}'"
77
- )
78
- refresh = False
79
- if additional_params:
80
- refresh = bool(
81
- additional_params.get("refresh_client", False)
82
- )
83
- client = None
84
- run_clients = self.clients.get(agent_id, None)
85
- if run_clients is None or refresh:
86
- # This means, that across all runs, no agent has ever needed a client.
87
- # This also means that we need to create a client.
88
- client = await self.make_client(
89
- additional_params=copy.deepcopy(additional_params)
90
- )
91
- # Insert the freshly created client
92
- self.clients[agent_id] = {}
93
- self.clients[agent_id][run_id] = client
94
-
95
- else:
96
- # This means there is at least one entry for the agent_id available
97
- # Now, all we need to do is check if the run_id matches the entrie's run_id
98
- client = run_clients.get(run_id, None)
99
- if client is None or refresh:
100
- # Means no client here with the respective run_id
101
- client = await self.make_client(
102
- additional_params=copy.deepcopy(
103
- additional_params
104
- )
105
- )
106
- # Insert the freshly created client.
107
- self.clients[agent_id][run_id] = client
108
-
109
- return client
110
- except Exception as e:
111
- # Log the exception and raise it so it becomes visible downstream
112
- logger.error(
113
- f"Unexpected Exception ocurred while trying to get client for server '{self.client_config.name}' with agent_id: {agent_id} and run_id: {run_id}: {e}"
114
- )
115
- span.record_exception(e)
116
- raise e
117
-
118
- async def call_tool(
119
- self,
120
- agent_id: str,
121
- run_id: str,
122
- name: str,
123
- arguments: dict[str, Any],
124
- additional_params: dict[str, Any] | None = None,
125
- ) -> Any:
126
- """Call a tool."""
127
- with tracer.start_as_current_span("client_manager.call_tool") as span:
128
- span.set_attribute("agent_id", agent_id)
129
- span.set_attribute("run_id", run_id)
130
- span.set_attribute("tool_name", name)
131
- span.set_attribute("arguments", str(arguments))
132
- try:
133
- client = await self.get_client(
134
- agent_id=agent_id,
135
- run_id=run_id,
136
- additional_params=additional_params,
137
- )
138
- result = await client.call_tool(
139
- agent_id=agent_id,
140
- run_id=run_id,
141
- name=name,
142
- arguments=arguments,
143
- )
144
- return result
145
- except Exception as e:
146
- logger.error(
147
- f"Exception occurred while trying to call tool {name} on server '{self.client_config.name}': {e}"
148
- )
149
- span.record_exception(e)
150
- return None
151
-
152
- async def get_tools(
153
- self,
154
- agent_id: str,
155
- run_id: str,
156
- additional_params: dict[str, Any] | None = None,
157
- ) -> list[FlockMCPToolBase]:
158
- """Retrieves a list of tools for the agents to act on."""
159
- with tracer.start_as_current_span("client_manager.get_tools") as span:
160
- span.set_attribute("agent_id", agent_id)
161
- span.set_attribute("run_id", run_id)
162
- try:
163
- client = await self.get_client(
164
- agent_id=agent_id,
165
- run_id=run_id,
166
- additional_params=additional_params,
167
- )
168
- tools: list[FlockMCPToolBase] = await client.get_tools(
169
- agent_id=agent_id, run_id=run_id
170
- )
171
- return tools
172
- except Exception as e:
173
- logger.error(
174
- f"Exception occurred while trying to retrieve Tools for server '{self.client_config.name}' with agent_id: {agent_id} and run_id: {run_id}: {e}"
175
- )
176
- span.record_exception(e)
177
- return []
178
-
179
- async def close_all(self) -> None:
180
- """Closes all connections in the pool and cancels background tasks."""
181
- with tracer.start_as_current_span("client_manager.close_all") as span:
182
- async with self.lock:
183
- for agent_id, run_dict in self.clients.items():
184
- logger.debug(
185
- f"Shutting down all clients for agent_id: {agent_id}"
186
- )
187
- for run_id, client in run_dict.items():
188
- logger.debug(
189
- f"Shutting down client for agent_id {agent_id} and run_id {run_id}"
190
- )
191
- try:
192
- await client.disconnect()
193
- except Exception as e:
194
- logger.error(
195
- f"Error when trying to disconnect client for server '{self.client_config.name}': {e}"
196
- )
197
- span.record_exception(e)
198
- self.clients = {} # Let the GC take care of the rest.
199
- logger.info(
200
- f"All clients disconnected for server '{self.client_config.name}'"
201
- )
@@ -1 +0,0 @@
1
- """MCP Types package."""
@@ -1,445 +0,0 @@
1
- # src/flock/core/mixin/dspy_integration.py
2
- """Mixin class for integrating with the dspy library."""
3
-
4
- import ast
5
- import re # Import re for parsing
6
- import typing
7
- from typing import Any, Literal
8
-
9
- from dspy import Tool
10
-
11
- from flock.core.logging.logging import get_logger
12
- from flock.core.util.splitter import split_top_level
13
-
14
- # Import split_top_level (assuming it's moved or copied appropriately)
15
- # Option 1: If moved to a shared util
16
- # from flock.core.util.parsing_utils import split_top_level
17
- # Option 2: If kept within this file (as in previous example)
18
- # Define split_top_level here or ensure it's imported
19
-
20
- logger = get_logger("mixin.dspy")
21
-
22
- # Type definition for agent type override
23
- AgentType = Literal["ReAct", "Completion", "ChainOfThought"] | None
24
-
25
-
26
- # Helper function to resolve type strings (can be static or module-level)
27
- def _resolve_type_string(type_str: str) -> type:
28
- """Resolves a type string into a Python type object.
29
- Handles built-ins, registered types, and common typing generics like
30
- List, Dict, Optional, Union, Literal.
31
- """
32
- # Import registry here to avoid circular imports
33
- from flock.core.flock_registry import get_registry
34
-
35
- FlockRegistry = get_registry()
36
-
37
- type_str = type_str.strip()
38
- logger.debug(f"Attempting to resolve type string: '{type_str}'")
39
-
40
- # 1. Check built-ins and registered types directly
41
- try:
42
- # This covers str, int, bool, Any, and types registered by name
43
- resolved_type = FlockRegistry.get_type(type_str)
44
- logger.debug(f"Resolved '{type_str}' via registry to: {resolved_type}")
45
- return resolved_type
46
- except KeyError:
47
- logger.debug(
48
- f"'{type_str}' not found directly in registry, attempting generic parsing."
49
- )
50
- pass # Not found, continue parsing generics
51
-
52
- # 2. Handle typing generics (List, Dict, Optional, Union, Literal)
53
- # Use regex to match pattern like Generic[InnerType1, InnerType2, ...]
54
- generic_match = re.fullmatch(r"(\w+)\s*\[(.*)\]", type_str)
55
- if generic_match:
56
- base_name = generic_match.group(1).strip()
57
- args_str = generic_match.group(2).strip()
58
- logger.debug(
59
- f"Detected generic pattern: Base='{base_name}', Args='{args_str}'"
60
- )
61
-
62
- try:
63
- # Get the base generic type (e.g., list, dict, Optional) from registry/builtins
64
- BaseType = FlockRegistry.get_type(
65
- base_name
66
- ) # Expects List, Dict etc. to be registered
67
- logger.debug(
68
- f"Resolved base generic type '{base_name}' to: {BaseType}"
69
- )
70
-
71
- # Special handling for Literal
72
- if BaseType is typing.Literal:
73
- # Split literal values, remove quotes, strip whitespace
74
- def parse_literal_args(args_str: str) -> tuple[str, ...]:
75
- try:
76
- return tuple(ast.literal_eval(f"[{args_str}]"))
77
- except (SyntaxError, ValueError) as exc:
78
- raise ValueError(
79
- f"Cannot parse {args_str!r} as literals"
80
- ) from exc
81
-
82
- literal_args = parse_literal_args(args_str)
83
- logger.debug(
84
- f"Parsing Literal arguments: {args_str} -> {literal_args}"
85
- )
86
- resolved_type = typing.Literal[literal_args] # type: ignore
87
- logger.debug(f"Constructed Literal type: {resolved_type}")
88
- return resolved_type
89
-
90
- # Recursively resolve arguments for other generics
91
- logger.debug(f"Splitting generic arguments: '{args_str}'")
92
- arg_strs = split_top_level(args_str)
93
- logger.debug(f"Split arguments: {arg_strs}")
94
- if not arg_strs:
95
- raise ValueError("Generic type has no arguments.")
96
-
97
- resolved_arg_types = tuple(
98
- _resolve_type_string(arg) for arg in arg_strs
99
- )
100
- logger.debug(f"Resolved generic arguments: {resolved_arg_types}")
101
-
102
- # Construct the generic type hint
103
- if BaseType is typing.Optional:
104
- if len(resolved_arg_types) != 1:
105
- raise ValueError("Optional requires exactly one argument.")
106
- # type: ignore
107
- resolved_type = typing.Union[resolved_arg_types[0], type(None)]
108
- logger.debug(
109
- f"Constructed Optional type as Union: {resolved_type}"
110
- )
111
- return resolved_type
112
- elif BaseType is typing.Union:
113
- if not resolved_arg_types:
114
- raise ValueError("Union requires at least one argument.")
115
- # type: ignore
116
- resolved_type = typing.Union[resolved_arg_types]
117
- logger.debug(f"Constructed Union type: {resolved_type}")
118
- return resolved_type
119
- elif hasattr(
120
- BaseType, "__getitem__"
121
- ): # Check if subscriptable (like list, dict, List, Dict)
122
- resolved_type = BaseType[resolved_arg_types] # type: ignore
123
- logger.debug(
124
- f"Constructed subscripted generic type: {resolved_type}"
125
- )
126
- return resolved_type
127
- else:
128
- # Base type found but cannot be subscripted
129
- logger.warning(
130
- f"Base type '{base_name}' found but is not a standard subscriptable generic. Returning base type."
131
- )
132
- return BaseType
133
-
134
- except (KeyError, ValueError, IndexError, TypeError) as e:
135
- logger.warning(
136
- f"Failed to parse generic type '{type_str}': {e}. Falling back."
137
- )
138
- # Fall through to raise KeyError below if base type itself wasn't found or parsing failed
139
-
140
- # 3. If not resolved by now, raise error
141
- logger.error(f"Type string '{type_str}' could not be resolved.")
142
- raise KeyError(f"Type '{type_str}' could not be resolved.")
143
-
144
-
145
- class DSPyIntegrationMixin:
146
- """Mixin class for integrating with the dspy library."""
147
-
148
- def create_dspy_signature_class(
149
- self, agent_name, description_spec, fields_spec
150
- ) -> Any:
151
- """Creates a dynamic DSPy Signature class from string specifications,
152
- resolving types using the FlockRegistry.
153
- """
154
- try:
155
- import dspy
156
- except ImportError:
157
- logger.error(
158
- "DSPy library is not installed. Cannot create DSPy signature. "
159
- "Install with: pip install dspy-ai"
160
- )
161
- raise ImportError("DSPy is required for this functionality.")
162
-
163
- base_class = dspy.Signature
164
- class_dict = {"__doc__": description_spec, "__annotations__": {}}
165
-
166
- if "->" in fields_spec:
167
- inputs_spec, outputs_spec = fields_spec.split("->", 1)
168
- else:
169
- inputs_spec, outputs_spec = (
170
- fields_spec,
171
- "",
172
- ) # Assume only inputs if no '->'
173
-
174
- def parse_field(field_str):
175
- """Parses 'name: type_str | description' using _resolve_type_string."""
176
- field_str = field_str.strip()
177
- if not field_str:
178
- return None
179
-
180
- parts = field_str.split("|", 1)
181
- main_part = parts[0].strip()
182
- desc = parts[1].strip() if len(parts) > 1 else None
183
-
184
- if ":" in main_part:
185
- name, type_str = [s.strip() for s in main_part.split(":", 1)]
186
- else:
187
- name = main_part
188
- type_str = "str" # Default type
189
-
190
- try:
191
- field_type = _resolve_type_string(type_str)
192
- except Exception as e: # Catch resolution errors
193
- logger.error(
194
- f"Failed to resolve type '{type_str}' for field '{name}': {e}. Defaulting to str."
195
- )
196
- field_type = str
197
-
198
- return name, field_type, desc
199
-
200
- def process_fields(fields_string, field_kind):
201
- """Process fields and add to class_dict."""
202
- if not fields_string or not fields_string.strip():
203
- return
204
-
205
- split_fields = split_top_level(fields_string)
206
- for field in split_fields:
207
- if field.strip():
208
- parsed = parse_field(field)
209
- if not parsed:
210
- continue
211
- name, field_type, desc = parsed
212
- class_dict["__annotations__"][name] = (
213
- field_type # Use resolved type
214
- )
215
-
216
- FieldClass = (
217
- dspy.InputField
218
- if field_kind == "input"
219
- else dspy.OutputField
220
- )
221
- # DSPy Fields use 'desc' for description
222
- class_dict[name] = (
223
- FieldClass(desc=desc)
224
- if desc is not None
225
- else FieldClass()
226
- )
227
-
228
- try:
229
- process_fields(inputs_spec, "input")
230
- process_fields(outputs_spec, "output")
231
- except Exception as e:
232
- logger.error(
233
- f"Error processing fields for DSPy signature '{agent_name}': {e}",
234
- exc_info=True,
235
- )
236
- raise ValueError(
237
- f"Could not process fields for signature: {e}"
238
- ) from e
239
-
240
- # Create and return the dynamic class
241
- try:
242
- DynamicSignature = type(
243
- "dspy_" + agent_name, (base_class,), class_dict
244
- )
245
- logger.info(
246
- f"Successfully created DSPy Signature: {DynamicSignature.__name__} "
247
- f"with fields: {DynamicSignature.__annotations__}"
248
- )
249
- return DynamicSignature
250
- except Exception as e:
251
- logger.error(
252
- f"Failed to create dynamic type 'dspy_{agent_name}': {e}",
253
- exc_info=True,
254
- )
255
- raise TypeError(f"Could not create DSPy signature type: {e}") from e
256
-
257
- def _configure_language_model(
258
- self,
259
- model: str | None,
260
- use_cache: bool,
261
- temperature: float,
262
- max_tokens: int,
263
- ) -> None:
264
- """Initialize and configure the language model using dspy."""
265
- if model is None:
266
- logger.warning(
267
- "No model specified for DSPy configuration. Using DSPy default."
268
- )
269
- # Rely on DSPy's global default or raise error if none configured
270
- # import dspy
271
- # if dspy.settings.lm is None:
272
- # raise ValueError("No model specified for agent and no global DSPy LM configured.")
273
- return
274
-
275
- try:
276
- import dspy
277
- except ImportError:
278
- logger.error(
279
- "DSPy library is not installed. Cannot configure language model."
280
- )
281
- return # Or raise
282
-
283
- try:
284
- # Ensure 'cache' parameter is handled correctly (might not exist on dspy.LM directly)
285
- # DSPy handles caching globally or via specific optimizers typically.
286
- # We'll configure the LM without explicit cache control here.
287
- lm_instance = dspy.LM(
288
- model=model,
289
- temperature=temperature,
290
- max_tokens=max_tokens,
291
- cache=use_cache,
292
- # Add other relevant parameters if needed, e.g., API keys via dspy.settings
293
- )
294
- dspy.settings.configure(lm=lm_instance)
295
- logger.info(
296
- f"DSPy LM configured with model: {model}, temp: {temperature}, max_tokens: {max_tokens}"
297
- )
298
- # Note: DSPy caching is usually configured globally, e.g., dspy.settings.configure(cache=...)
299
- # or handled by optimizers. Setting `cache=use_cache` on dspy.LM might not be standard.
300
- except Exception as e:
301
- logger.error(
302
- f"Failed to configure DSPy language model '{model}': {e}",
303
- exc_info=True,
304
- )
305
- # We need to raise this exception, otherwise Flock will trundle on until it needs dspy.settings.lm and can't find it.
306
- raise
307
-
308
- def _select_task(
309
- self,
310
- signature: Any,
311
- override_evaluator_type: AgentType,
312
- max_tool_calls: int = 10,
313
- tools: list[Any] | None = None,
314
- mcp_tools: list[Any] | None = None,
315
- kwargs: dict[str, Any] = {},
316
- ) -> Any:
317
- """Select and instantiate the appropriate DSPy Program/Module."""
318
- try:
319
- import dspy
320
- except ImportError:
321
- logger.error(
322
- "DSPy library is not installed. Cannot select DSPy task."
323
- )
324
- raise ImportError("DSPy is required for this functionality.")
325
-
326
- processed_tools = []
327
- if tools:
328
- for tool in tools:
329
- if callable(tool): # Basic check
330
- processed_tools.append(tool)
331
- # Could add more sophisticated tool wrapping/validation here if needed
332
- else:
333
- logger.warning(
334
- f"Item '{tool}' in tools list is not callable, skipping."
335
- )
336
-
337
- processed_mcp_tools = []
338
- if mcp_tools:
339
- for mcp_tool in mcp_tools:
340
- if isinstance(mcp_tool, Tool): # Basic check
341
- processed_mcp_tools.append(mcp_tool)
342
- else:
343
- logger.warning(
344
- f"Item '{mcp_tool}' is not a dspy.primitives.Tool, skipping."
345
- )
346
-
347
- dspy_program = None
348
- selected_type = override_evaluator_type
349
-
350
- # Determine type if not overridden
351
- if not selected_type:
352
- selected_type = (
353
- "ReAct" if processed_tools or processed_mcp_tools else "Predict"
354
- ) # Default logic
355
-
356
- logger.debug(
357
- f"Selecting DSPy program type: {selected_type} (Tools provided: {bool(processed_tools)}) (MCP Tools: {bool(processed_mcp_tools)}"
358
- )
359
-
360
- # Merge list of native tools and processed tools.
361
- # This makes mcp tools appear as native code functions to the llm of the agent.
362
- merged_tools = []
363
-
364
- if processed_tools:
365
- merged_tools = merged_tools + processed_tools
366
-
367
- if processed_mcp_tools:
368
- merged_tools = merged_tools + processed_mcp_tools
369
-
370
- try:
371
- if selected_type == "ChainOfThought":
372
- dspy_program = dspy.ChainOfThought(signature, **kwargs)
373
- elif selected_type == "ReAct":
374
- if not kwargs:
375
- kwargs = {"max_iters": max_tool_calls}
376
- dspy_program = dspy.ReAct(
377
- signature, tools=merged_tools or [], **kwargs
378
- )
379
- elif selected_type == "Predict": # Default or explicitly Completion
380
- dspy_program = dspy.Predict(signature)
381
- else: # Fallback or handle unknown type
382
- logger.warning(
383
- f"Unknown or unsupported agent_type_override '{selected_type}'. Defaulting to dspy.Predict."
384
- )
385
- dspy_program = dspy.Predict(signature)
386
-
387
- logger.info(
388
- f"Instantiated DSPy program: {type(dspy_program).__name__}"
389
- )
390
- return dspy_program
391
- except Exception as e:
392
- logger.error(
393
- f"Failed to instantiate DSPy program of type '{selected_type}': {e}",
394
- exc_info=True,
395
- )
396
- raise RuntimeError(f"Could not create DSPy program: {e}") from e
397
-
398
- def _process_result(
399
- self, result: Any, inputs: dict[str, Any]
400
- ) -> tuple[dict[str, Any], float, list]:
401
- """Convert the DSPy result object to a dictionary."""
402
- import dspy
403
-
404
- if result is None:
405
- logger.warning("DSPy program returned None result.")
406
- return {}
407
- try:
408
- # DSPy Prediction objects often behave like dicts or have .keys() / items()
409
- if hasattr(result, "items") and callable(result.items):
410
- output_dict = dict(result.items())
411
- elif hasattr(result, "__dict__"): # Fallback for other object types
412
- output_dict = {
413
- k: v
414
- for k, v in result.__dict__.items()
415
- if not k.startswith("_")
416
- }
417
- else:
418
- # If it's already a dict (less common for DSPy results directly)
419
- if isinstance(result, dict):
420
- output_dict = result
421
- else: # Final fallback
422
- logger.warning(
423
- f"Could not reliably convert DSPy result of type {type(result)} to dict. Returning as is."
424
- )
425
- output_dict = {"raw_result": result}
426
-
427
- logger.debug(f"Processed DSPy result to dict: {output_dict}")
428
- # Optionally merge inputs back if desired (can make result dict large)
429
- final_result = {**inputs, **output_dict}
430
-
431
- lm = dspy.settings.get("lm")
432
- cost = sum([x["cost"] for x in lm.history if x["cost"] is not None])
433
- lm_history = lm.history
434
-
435
- return final_result, cost, lm_history
436
-
437
- except Exception as conv_error:
438
- logger.error(
439
- f"Failed to process DSPy result into dictionary: {conv_error}",
440
- exc_info=True,
441
- )
442
- return {
443
- "error": "Failed to process result",
444
- "raw_result": str(result),
445
- }