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
flock/core/flock.py DELETED
@@ -1,1003 +0,0 @@
1
- # src/flock/core/flock.py
2
- """High-level orchestrator for managing and executing agents within the Flock framework."""
3
-
4
- from __future__ import annotations # Ensure forward references work
5
-
6
- import asyncio
7
- import contextvars
8
- import os
9
- import uuid
10
- from collections.abc import Awaitable, Callable, Sequence
11
- from concurrent.futures import ThreadPoolExecutor
12
- from pathlib import Path
13
- from typing import (
14
- TYPE_CHECKING,
15
- Any,
16
- Literal,
17
- TypeVar,
18
- )
19
-
20
- # Third-party imports
21
- from box import Box
22
- from temporalio import workflow
23
-
24
- from flock.core.flock_server_manager import FlockServerManager
25
- from flock.core.mcp.flock_mcp_server import FlockMCPServerBase
26
-
27
- with workflow.unsafe.imports_passed_through():
28
- from datasets import Dataset # type: ignore
29
-
30
- # Assuming run_local_workflow is correctly placed and importable
31
- from flock.core.execution.local_executor import (
32
- run_local_workflow,
33
- )
34
-
35
- import opik
36
- from opentelemetry import trace
37
- from opentelemetry.baggage import get_baggage, set_baggage
38
- from opik.integrations.dspy.callback import OpikCallback
39
- from pandas import DataFrame # type: ignore
40
- from pydantic import BaseModel, Field
41
-
42
- # Flock core components & utilities
43
- from flock.config import DEFAULT_MODEL, TELEMETRY
44
- from flock.core.api.custom_endpoint import (
45
- FlockEndpoint, # Keep for type hinting custom_endpoints
46
- )
47
- from flock.core.context.context import FlockContext
48
- from flock.core.context.context_manager import initialize_context
49
-
50
- # Assuming run_temporal_workflow is correctly placed and importable
51
- from flock.core.execution.temporal_executor import run_temporal_workflow
52
- from flock.core.flock_evaluator import FlockEvaluator # For type hint
53
- from flock.core.logging.logging import get_logger
54
- from flock.core.serialization.serializable import Serializable
55
- from flock.core.util.cli_helper import init_console
56
- from flock.workflow.temporal_config import TemporalWorkflowConfig
57
-
58
- # Import FlockAgent using TYPE_CHECKING to avoid circular import at runtime
59
- if TYPE_CHECKING:
60
- # These imports are only for type hints
61
- from flock.core.flock_agent import FlockAgent
62
-
63
-
64
- # Registry
65
- from flock.core.flock_registry import get_registry
66
-
67
- try:
68
- import pandas as pd # type: ignore
69
-
70
- PANDAS_AVAILABLE = True
71
- except ImportError:
72
- pd = None # type: ignore
73
- PANDAS_AVAILABLE = False
74
-
75
- logger = get_logger("flock.api")
76
- TELEMETRY.setup_tracing() # Setup OpenTelemetry
77
- tracer = trace.get_tracer(__name__)
78
- FlockRegistry = get_registry() # Get the registry instance
79
-
80
- # Define TypeVar for generic class methods like from_dict
81
- T = TypeVar("T", bound="Flock")
82
- _R = TypeVar("_R")
83
-
84
-
85
- class Flock(BaseModel, Serializable):
86
- """Orchestrator for managing and executing agent systems.
87
-
88
- Manages agent definitions, context, and execution flow (local or Temporal).
89
- Relies on FlockSerializer for serialization/deserialization logic.
90
- Inherits from Pydantic BaseModel and Serializable.
91
- """
92
-
93
- name: str | None = Field(
94
- default_factory=lambda: f"flock_{uuid.uuid4().hex[:8]}",
95
- description="A unique identifier for this Flock instance.",
96
- )
97
- model: str | None = Field(
98
- default=DEFAULT_MODEL,
99
- description="Default model identifier for agents if not specified otherwise.",
100
- )
101
- description: str | None = Field(
102
- default=None,
103
- description="A brief description of the purpose of this Flock configuration.",
104
- )
105
- enable_temporal: bool = Field(
106
- default=False,
107
- description="If True, execute workflows via Temporal; otherwise, run locally.",
108
- )
109
- enable_opik: bool = Field(
110
- default=False,
111
- description="If True, enable Opik for cost tracking and model management.",
112
- )
113
- show_flock_banner: bool = Field(
114
- default=True,
115
- description="If True, show the Flock banner on console interactions.",
116
- )
117
- # --- Temporal Configuration (Optional) ---
118
- temporal_config: TemporalWorkflowConfig | None = Field(
119
- default=None,
120
- description="Optional Temporal settings specific to the workflow execution for this Flock.",
121
- )
122
- # --- Temporal Dev/Test Setting ---
123
- temporal_start_in_process_worker: bool = Field(
124
- default=True,
125
- description="If True (default) and enable_temporal=True, start a temporary in-process worker for development/testing convenience. Set to False when using dedicated workers.",
126
- )
127
-
128
- benchmark_agent_name: str | None = Field(
129
- default=None,
130
- description="The name of the agent to use for the benchmark.",
131
- )
132
- benchmark_eval_field: str | None = Field(
133
- default=None,
134
- description="The output field to use for the benchmark.",
135
- )
136
- benchmark_input_field: str | None = Field(
137
- default=None,
138
- description="The input field to use for the benchmark.",
139
- )
140
- # Internal agent storage - not part of the Pydantic model for direct serialization
141
- # Marked with underscore to indicate it's managed internally and accessed via property
142
- _agents: dict[str, FlockAgent]
143
- _start_agent_name: str | None = None # For potential pre-configuration
144
- _start_input: dict = {} # For potential pre-configuration
145
-
146
- # Internal server storage - not part of the Pydantic model for direct serialization
147
- _servers: dict[str, FlockMCPServerBase]
148
-
149
- # Async context-manager for startup and teardown of servers
150
- # Not part of the pydantic model
151
- _mgr: FlockServerManager
152
-
153
- # Pydantic v2 model config
154
- model_config = {
155
- "arbitrary_types_allowed": True,
156
- # Assuming FlockRegistry type might not be serializable by default
157
- "ignored_types": (type(FlockRegistry),),
158
- }
159
-
160
- def _run_sync(self, coro: Awaitable[_R]) -> _R:
161
- """Execute *coro* synchronously.
162
-
163
- * If no loop is running → ``asyncio.run``.
164
- * Otherwise run ``asyncio.run`` inside a fresh thread **with**
165
- context-vars propagation.
166
- """
167
- try:
168
- asyncio.get_running_loop()
169
- except RuntimeError: # no loop → simple
170
- return asyncio.run(coro)
171
-
172
- # A loop is already running – Jupyter / ASGI / etc.
173
- ctx = contextvars.copy_context() # propagate baggage
174
- with ThreadPoolExecutor(max_workers=1) as pool:
175
- future = pool.submit(ctx.run, asyncio.run, coro)
176
- try:
177
- return future.result()
178
- finally:
179
- if not future.done():
180
- future.cancel()
181
-
182
-
183
- def _patch_litellm_proxy_imports(self) -> None:
184
- """Stub litellm proxy_server to avoid optional proxy deps when not used.
185
-
186
- Some litellm versions import `litellm.proxy.proxy_server` during standard logging
187
- to read `general_settings`, which pulls in optional dependencies like `apscheduler`.
188
- We provide a stub so imports succeed but cold storage remains disabled.
189
- """
190
- try:
191
- import sys
192
- import types
193
-
194
- if "litellm.proxy.proxy_server" not in sys.modules:
195
- stub = types.ModuleType("litellm.proxy.proxy_server")
196
- # Minimal surface that cold_storage_handler accesses
197
- setattr(stub, "general_settings", {})
198
- sys.modules["litellm.proxy.proxy_server"] = stub
199
- except Exception as e:
200
- # Safe to ignore; worst case litellm will log a warning
201
- logger.debug(f"Failed to stub litellm proxy_server: {e}")
202
-
203
- def __init__(
204
- self,
205
- name: str | None = None,
206
- model: str | None = DEFAULT_MODEL,
207
- description: str | None = None,
208
- show_flock_banner: bool = True,
209
- enable_temporal: bool = False,
210
- enable_opik: bool = False,
211
- agents: list[FlockAgent] | None = None,
212
- servers: list[FlockMCPServerBase] | None = None,
213
- temporal_config: TemporalWorkflowConfig | None = None,
214
- temporal_start_in_process_worker: bool = True,
215
- **kwargs,
216
- ):
217
- """Initialize the Flock orchestrator."""
218
- # Use provided name or generate default BEFORE super init if needed elsewhere
219
- effective_name = name or f"flock_{uuid.uuid4().hex[:8]}"
220
-
221
- # Initialize Pydantic fields
222
- super().__init__(
223
- name=effective_name,
224
- model=model,
225
- description=description,
226
- enable_temporal=enable_temporal,
227
- enable_opik=enable_opik,
228
- show_flock_banner=show_flock_banner,
229
- temporal_config=temporal_config,
230
- temporal_start_in_process_worker=temporal_start_in_process_worker,
231
- **kwargs,
232
- )
233
-
234
- # Initialize runtime attributes AFTER super().__init__()
235
- self._agents = {}
236
- self._servers = {}
237
- self._start_agent_name = None
238
- self._start_input = {}
239
- self._mgr = FlockServerManager()
240
-
241
- self._patch_litellm_proxy_imports()
242
-
243
- # Register passed servers
244
- # (need to be registered first so that agents can retrieve them from the registry)
245
- # This will also add them to the managed list of self._mgr
246
- if servers:
247
- from flock.core.mcp.flock_mcp_server import (
248
- FlockMCPServerBase as ConcreteFlockMCPServer,
249
- )
250
-
251
- for server in servers:
252
- if isinstance(server, ConcreteFlockMCPServer):
253
- self.add_server(server)
254
- else:
255
- logger.warning(
256
- f"Item provided in 'servers' list is not a FlockMCPServer: {type(server)}"
257
- )
258
-
259
- # Register passed agents
260
- if agents:
261
- from flock.core.flock_agent import (
262
- FlockAgent as ConcreteFlockAgent, # Local import
263
- )
264
-
265
- for agent in agents:
266
- if isinstance(agent, ConcreteFlockAgent):
267
- self.add_agent(agent)
268
- else:
269
- logger.warning(
270
- f"Item provided in 'agents' list is not a FlockAgent: {type(agent)}"
271
- )
272
-
273
- # Initialize console if needed for banner
274
- if self.show_flock_banner: # Check instance attribute
275
- init_console(clear_screen=True, show_banner=self.show_flock_banner)
276
-
277
- # Set Temporal debug environment variable
278
- self._set_temporal_debug_flag()
279
-
280
- # Ensure session ID exists in baggage
281
- self._ensure_session_id()
282
-
283
- FlockRegistry.discover_and_register_components()
284
-
285
- if self.enable_opik:
286
- import dspy
287
-
288
- opik.configure(use_local=True, automatic_approvals=True)
289
- opik_callback = OpikCallback(project_name=self.name, log_graph=True)
290
- dspy.settings.configure(
291
- callbacks=[opik_callback],
292
- )
293
-
294
- logger.info(
295
- "Flock instance initialized",
296
- name=self.name,
297
- model=self.model,
298
- enable_temporal=self.enable_temporal,
299
- )
300
-
301
- def prepare_benchmark(
302
- self,
303
- agent: FlockAgent | str | None = None,
304
- input_field: str | None = None,
305
- eval_field: str | None = None,
306
- ):
307
- """Prepare a benchmark for the Flock instance."""
308
- from flock.core.flock_agent import FlockAgent as ConcreteFlockAgent
309
-
310
- logger.info(
311
- f"Preparing benchmark for Flock instance '{self.name}' with agent '{agent}'."
312
- )
313
-
314
- name = agent.name if isinstance(agent, ConcreteFlockAgent) else agent
315
-
316
- if self._agents.get(name) is None:
317
- raise ValueError(
318
- f"Agent '{name}' not found in Flock instance '{self.name}'."
319
- )
320
-
321
- self.benchmark_agent_name = name
322
- self.benchmark_eval_field = eval_field
323
- self.benchmark_input_field = input_field
324
-
325
- def inspect(self):
326
- """Inspect the Flock instance."""
327
- logger.info(
328
- f"Inspecting Flock instance '{self.name}' with start agent '{self.benchmark_agent_name}' and input '{input}'."
329
- )
330
-
331
- async def run(input: dict[str, Any]) -> dict[str, Any]:
332
- """Inspect the Flock instance."""
333
- logger.info(
334
- f"Inspecting Flock instance '{self.name}' with start agent '{self.benchmark_agent_name}' and input '{input}'."
335
- )
336
- msg_content = input.get("messages")[0].get("content")
337
-
338
- agent_input = {self.benchmark_input_field: msg_content}
339
-
340
- result = await self.run_async(
341
- start_agent=self.benchmark_agent_name,
342
- input=agent_input,
343
- box_result=False,
344
- )
345
-
346
- agent_output = result.get(
347
- self.benchmark_eval_field, "No answer found"
348
- )
349
-
350
- return {
351
- "output": agent_output,
352
- }
353
-
354
- return run
355
-
356
- def _set_temporal_debug_flag(self):
357
- """Set or remove LOCAL_DEBUG env var based on enable_temporal."""
358
- if not self.enable_temporal:
359
- if "LOCAL_DEBUG" not in os.environ:
360
- os.environ["LOCAL_DEBUG"] = "1"
361
- logger.debug(
362
- "Set LOCAL_DEBUG environment variable for local execution."
363
- )
364
- elif "LOCAL_DEBUG" in os.environ:
365
- del os.environ["LOCAL_DEBUG"]
366
- logger.debug(
367
- "Removed LOCAL_DEBUG environment variable for Temporal execution."
368
- )
369
-
370
- def _ensure_session_id(self):
371
- """Ensure a session_id exists in the OpenTelemetry baggage."""
372
- session_id = get_baggage("session_id")
373
- if not session_id:
374
- session_id = str(uuid.uuid4())
375
- set_baggage("session_id", session_id)
376
- logger.debug(f"Generated new session_id: {session_id}")
377
-
378
- def add_server(self, server: FlockMCPServerBase) -> FlockMCPServerBase:
379
- """Adds a server instance to this Flock configuration and registry as well as set it up to be managed by self._mgr."""
380
- from flock.core.mcp.flock_mcp_server import (
381
- FlockMCPServerBase as ConcreteFlockMCPServer,
382
- )
383
-
384
- if not isinstance(server, ConcreteFlockMCPServer):
385
- raise TypeError("Provided object is not a FlockMCPServer instance.")
386
- if not server.config.name:
387
- raise ValueError("Server must have a name.")
388
-
389
- if server.config.name in self.servers:
390
- raise ValueError(
391
- f"Server with this name already exists. Name: '{server.config.name}'"
392
- )
393
-
394
- self._servers[server.config.name] = server
395
- FlockRegistry.register_server(server) # Register globally.
396
-
397
- # Make sure that the server is also added to
398
- # the server_list managed by FlockServerManager
399
- if not self._mgr:
400
- self._mgr = FlockServerManager()
401
-
402
- # Prepare server to be managed by the FlockServerManager
403
- logger.info(f"Adding server '{server.config.name}' to managed list.")
404
- self._mgr.add_server_sync(server=server)
405
- logger.info(f"Server '{server.config.name}' is now on managed list.")
406
-
407
- logger.info(
408
- f"Server '{server.config.name}' added to Flock '{self.name}'"
409
- )
410
- return server
411
-
412
- def add_agent(self, agent: FlockAgent) -> FlockAgent:
413
- """Adds an agent instance to this Flock configuration and registry.
414
-
415
- This also registers all servers attached to the agent, if they have not been registered
416
- beforehand.
417
- """
418
- from flock.core.flock_agent import FlockAgent as ConcreteFlockAgent
419
-
420
- if not isinstance(agent, ConcreteFlockAgent):
421
- raise TypeError("Provided object is not a FlockAgent instance.")
422
- if not agent.name:
423
- raise ValueError("Agent must have a name.")
424
-
425
- if agent.name in self._agents:
426
- # Allow re-adding the same instance, but raise error for different instance with same name
427
- if self._agents[agent.name] is not agent:
428
- raise ValueError(
429
- f"Agent with name '{agent.name}' already exists with a different instance."
430
- )
431
- else:
432
- logger.debug(
433
- f"Agent '{agent.name}' is already added. Skipping."
434
- )
435
- return agent # Return existing agent
436
-
437
- self._agents[agent.name] = agent
438
- FlockRegistry.register_agent(agent) # Register globally
439
-
440
- # Set default model if agent doesn't have one
441
- if agent.model is None:
442
- if self.model:
443
- agent.set_model(self.model)
444
- logger.debug(
445
- f"Agent '{agent.name}' using Flock default model: {self.model}"
446
- )
447
- else:
448
- logger.warning(
449
- f"Agent '{agent.name}' has no model and Flock default model is not set."
450
- )
451
-
452
- logger.info(f"Agent '{agent.name}' added to Flock '{self.name}'.")
453
- return agent
454
-
455
- @property
456
- def agents(self) -> dict[str, FlockAgent]:
457
- """Returns the dictionary of agents managed by this Flock instance."""
458
- return self._agents
459
-
460
- @property
461
- def servers(self) -> dict[str, FlockMCPServerBase]:
462
- """Returns the dictionary of servers managed by this Flock instance."""
463
- return self._servers
464
-
465
- def run(
466
- self,
467
- start_agent: FlockAgent | str | None = None,
468
- input: dict | None = None,
469
- context: FlockContext | None = None,
470
- run_id: str = "",
471
- box_result: bool = True,
472
- agents: list[FlockAgent] | None = None,
473
- servers: list[FlockMCPServerBase] | None = None,
474
- memo: dict[str, Any] | None = None,
475
- *,
476
- use_production_tools: bool = False,
477
- ) -> Box | dict:
478
- return self._run_sync(
479
- self.run_async(
480
- start_agent=start_agent,
481
- input=input,
482
- context=context,
483
- run_id=run_id,
484
- box_result=box_result,
485
- agents=agents,
486
- servers=servers,
487
- memo=memo,
488
- use_production_tools=use_production_tools,
489
- )
490
- )
491
-
492
- async def run_async(
493
- self,
494
- start_agent: FlockAgent | str | None = None,
495
- input: dict | None = None,
496
- context: FlockContext | None = None,
497
- run_id: str = "",
498
- box_result: bool = True,
499
- agents: list[FlockAgent] | None = None,
500
- servers: list[FlockMCPServerBase] | None = None,
501
- memo: dict[str, Any] | None = None,
502
- *,
503
- use_production_tools: bool = False,
504
- ) -> Box | dict:
505
- """Entry point for running an agent system asynchronously."""
506
- # Import here to allow forward reference resolution
507
- from flock.core.flock_agent import FlockAgent as ConcreteFlockAgent
508
- from flock.core.mcp.flock_mcp_server import (
509
- FlockMCPServerBase as ConcreteFlockServer,
510
- )
511
-
512
- with tracer.start_as_current_span("flock.run_async") as span:
513
- # Add passed servers so that agents have access to them.
514
- if servers:
515
- for server_obj in servers:
516
- if isinstance(server_obj, ConcreteFlockServer):
517
- self.add_server(server=server_obj)
518
- else:
519
- logger.warning(
520
- f"Item in 'servers' list is not a FlockMCPServer: {type(server_obj)}"
521
- )
522
-
523
- # Add passed agents
524
- if agents:
525
- for agent_obj in agents:
526
- if isinstance(agent_obj, ConcreteFlockAgent):
527
- self.add_agent(agent_obj)
528
- else:
529
- logger.warning(
530
- f"Item in 'agents' list is not a FlockAgent: {type(agent_obj)}"
531
- )
532
-
533
- # Determine starting agent name
534
- start_agent_name: str | None = None
535
- if isinstance(start_agent, ConcreteFlockAgent):
536
- start_agent_name = start_agent.name
537
- if (
538
- start_agent_name not in self._agents
539
- ): # Add if not already present
540
- self.add_agent(start_agent)
541
- elif isinstance(start_agent, str):
542
- start_agent_name = start_agent
543
- else: # start_agent is None
544
- start_agent_name = self._start_agent_name
545
-
546
- # Default to first agent if only one exists and none specified
547
- if not start_agent_name and len(self._agents) == 1:
548
- start_agent_name = next(iter(self._agents.keys()))
549
- elif not start_agent_name:
550
- raise ValueError(
551
- "No start_agent specified and multiple/no agents exist in the Flock instance."
552
- )
553
-
554
- # Check if start_agent is in agents
555
- if start_agent_name not in self._agents:
556
- # Try loading from registry if not found locally yet
557
- reg_agent = FlockRegistry.get_agent(start_agent_name)
558
- if reg_agent:
559
- self.add_agent(reg_agent)
560
- logger.info(
561
- f"Loaded start agent '{start_agent_name}' from registry."
562
- )
563
- else:
564
- raise ValueError(
565
- f"Start agent '{start_agent_name}' not found locally or in registry."
566
- )
567
-
568
- run_input = input if input is not None else self._start_input
569
- effective_run_id = run_id or f"flockrun_{uuid.uuid4().hex[:8]}"
570
-
571
- span.set_attribute("start_agent", start_agent_name)
572
- span.set_attribute("input", str(run_input))
573
- span.set_attribute("run_id", effective_run_id)
574
- span.set_attribute("enable_temporal", self.enable_temporal)
575
- logger.info(
576
- f"Initiating Flock run '{self.name}'. Start Agent: '{start_agent_name}'. Temporal: {self.enable_temporal}."
577
- )
578
-
579
- try:
580
- resolved_start_agent = self._agents.get(start_agent_name)
581
- if not resolved_start_agent: # Should have been handled by now
582
- raise ValueError(
583
- f"Start agent '{start_agent_name}' not found after checks."
584
- )
585
-
586
- run_context = context if context else FlockContext()
587
- set_baggage("run_id", effective_run_id) # Set for OpenTelemetry
588
-
589
- initialize_context(
590
- run_context,
591
- start_agent_name,
592
- run_input,
593
- effective_run_id,
594
- not self.enable_temporal, # local_debug is inverse of enable_temporal
595
- self.model or resolved_start_agent.model or DEFAULT_MODEL,
596
- use_production_tools,
597
- )
598
- # Add agent definitions to context for routing/serialization within workflow
599
- for agent_name_iter, agent_instance_iter in self.agents.items():
600
- agent_dict_repr = (
601
- agent_instance_iter.to_dict()
602
- ) # Agents handle their own serialization
603
- run_context.add_agent_definition(
604
- agent_type=type(agent_instance_iter),
605
- agent_name=agent_name_iter,
606
- agent_data=agent_dict_repr,
607
- )
608
-
609
- # Add temporal config to context if enabled
610
- if self.enable_temporal and self.temporal_config:
611
- run_context.set_variable(
612
- "flock.temporal_workflow_config",
613
- self.temporal_config.model_dump(mode="json"),
614
- )
615
-
616
- # At this point, initial setup is done
617
- # and flock is ready to execute it's agent_workflow.
618
- # Befor that happens, the ServerManager needs to
619
- # get the Servers up and running (Populate pools, build connections, start scripts, etc.)
620
- async with self._mgr:
621
- # Enter the manager's async context,
622
- # running it's __aenter__ method and starting all registered servers
623
- # after this block ends, self._mgr's __aexit__ will be called
624
- # all servers will be torn down.
625
- logger.info(
626
- f"Entering managed server context. Servers starting up."
627
- )
628
-
629
- logger.info(
630
- "Starting agent execution",
631
- agent=start_agent_name,
632
- enable_temporal=self.enable_temporal,
633
- )
634
-
635
- # Execute workflow
636
- if not self.enable_temporal:
637
- result = await run_local_workflow(
638
- run_context,
639
- box_result=False, # Boxing handled below
640
- )
641
- else:
642
- result = await run_temporal_workflow(
643
- self, # Pass the Flock instance
644
- run_context,
645
- box_result=False, # Boxing handled below
646
- memo=memo,
647
- )
648
-
649
- span.set_attribute("result.type", str(type(result)))
650
- result_str = str(result)
651
- span.set_attribute(
652
- "result.preview",
653
- result_str[:1000]
654
- + ("..." if len(result_str) > 1000 else ""),
655
- )
656
-
657
- if box_result:
658
- try:
659
- logger.debug("Boxing final result.")
660
- return Box(result)
661
- except ImportError:
662
- logger.warning(
663
- "Box library not installed, returning raw dict."
664
- )
665
- return result
666
- else:
667
- return result
668
-
669
- # The context of self._mgr ends here, meaning, that servers will
670
- # be cleaned up and shut down.
671
-
672
- except Exception as e:
673
- logger.error(
674
- f"Flock run '{self.name}' failed: {e}", exc_info=True
675
- )
676
- span.record_exception(e)
677
- span.set_status(trace.Status(trace.StatusCode.ERROR, str(e)))
678
- # Return a consistent error structure
679
- error_output = {
680
- "error": str(e),
681
- "details": f"Flock run '{self.name}' failed.",
682
- "run_id": effective_run_id,
683
- "start_agent": start_agent_name,
684
- }
685
- return Box(error_output) if box_result else error_output
686
-
687
- # --- Batch Processing (Delegation) ---
688
- async def run_batch_async(
689
- self,
690
- start_agent: FlockAgent | str,
691
- batch_inputs: list[dict[str, Any]] | DataFrame | str,
692
- input_mapping: dict[str, str] | None = None,
693
- static_inputs: dict[str, Any] | None = None,
694
- parallel: bool = True,
695
- max_workers: int = 5,
696
- use_temporal: bool | None = None,
697
- box_results: bool = True,
698
- return_errors: bool = False,
699
- silent_mode: bool = False,
700
- write_to_csv: str | None = None,
701
- hide_columns: list[str] | None = None,
702
- delimiter: str = ",",
703
- ) -> list[Box | dict | None | Exception]:
704
- """Runs the specified agent/workflow for each item in a batch asynchronously (delegated)."""
705
- # Import processor locally
706
- from flock.core.execution.batch_executor import BatchProcessor
707
-
708
- processor = BatchProcessor(self) # Pass self
709
- return await processor.run_batch_async(
710
- start_agent=start_agent,
711
- batch_inputs=batch_inputs,
712
- input_mapping=input_mapping,
713
- static_inputs=static_inputs,
714
- parallel=parallel,
715
- max_workers=max_workers,
716
- use_temporal=use_temporal,
717
- box_results=box_results,
718
- return_errors=return_errors,
719
- silent_mode=silent_mode,
720
- write_to_csv=write_to_csv,
721
- hide_columns=hide_columns,
722
- delimiter=delimiter,
723
- )
724
-
725
- def run_batch(
726
- self,
727
- start_agent: FlockAgent | str,
728
- batch_inputs: list[dict[str, Any]] | DataFrame | str,
729
- input_mapping: dict[str, str] | None = None,
730
- static_inputs: dict[str, Any] | None = None,
731
- parallel: bool = True,
732
- max_workers: int = 5,
733
- use_temporal: bool | None = None,
734
- box_results: bool = True,
735
- return_errors: bool = False,
736
- silent_mode: bool = False,
737
- write_to_csv: str | None = None,
738
- hide_columns: list[str] | None = None,
739
- delimiter: str = ",",
740
- ) -> list[Box | dict | None | Exception]:
741
- return self._run_sync(
742
- self.run_batch_async(
743
- start_agent=start_agent,
744
- batch_inputs=batch_inputs,
745
- input_mapping=input_mapping,
746
- static_inputs=static_inputs,
747
- parallel=parallel,
748
- max_workers=max_workers,
749
- use_temporal=use_temporal,
750
- box_results=box_results,
751
- return_errors=return_errors,
752
- silent_mode=silent_mode,
753
- write_to_csv=write_to_csv,
754
- hide_columns=hide_columns,
755
- delimiter=delimiter,
756
- )
757
- )
758
-
759
- # --- Evaluation (Delegation) ---
760
- async def evaluate_async(
761
- self,
762
- dataset: str | Path | list[dict[str, Any]] | DataFrame | Dataset, # type: ignore
763
- start_agent: FlockAgent | str,
764
- input_mapping: dict[str, str],
765
- answer_mapping: dict[str, str],
766
- metrics: list[
767
- str
768
- | Callable[[Any, Any], bool | float | dict[str, Any]]
769
- | FlockAgent # Type hint only
770
- | FlockEvaluator # Type hint only
771
- ],
772
- metric_configs: dict[str, dict[str, Any]] | None = None,
773
- static_inputs: dict[str, Any] | None = None,
774
- parallel: bool = True,
775
- max_workers: int = 5,
776
- use_temporal: bool | None = None,
777
- error_handling: Literal["raise", "skip", "log"] = "log",
778
- output_file: str | Path | None = None,
779
- return_dataframe: bool = True,
780
- silent_mode: bool = False,
781
- metadata_columns: list[str] | None = None,
782
- ) -> DataFrame | list[dict[str, Any]]: # type: ignore
783
- """Evaluates the Flock's performance against a dataset (delegated)."""
784
- # Import processor locally
785
- from flock.core.execution.evaluation_executor import (
786
- EvaluationExecutor,
787
- )
788
-
789
- processor = EvaluationExecutor(self) # Pass self
790
- return await processor.evaluate_async(
791
- dataset=dataset,
792
- start_agent=start_agent,
793
- input_mapping=input_mapping,
794
- answer_mapping=answer_mapping,
795
- metrics=metrics,
796
- metric_configs=metric_configs,
797
- static_inputs=static_inputs,
798
- parallel=parallel,
799
- max_workers=max_workers,
800
- use_temporal=use_temporal,
801
- error_handling=error_handling,
802
- output_file=output_file,
803
- return_dataframe=return_dataframe,
804
- silent_mode=silent_mode,
805
- metadata_columns=metadata_columns,
806
- )
807
-
808
- def evaluate(
809
- self,
810
- dataset: str | Path | list[dict[str, Any]] | DataFrame | Dataset, # type: ignore
811
- start_agent: FlockAgent | str,
812
- input_mapping: dict[str, str],
813
- answer_mapping: dict[str, str],
814
- metrics: list[
815
- str
816
- | Callable[[Any, Any], bool | float | dict[str, Any]]
817
- | FlockAgent # Type hint only
818
- | FlockEvaluator # Type hint only
819
- ],
820
- metric_configs: dict[str, dict[str, Any]] | None = None,
821
- static_inputs: dict[str, Any] | None = None,
822
- parallel: bool = True,
823
- max_workers: int = 5,
824
- use_temporal: bool | None = None,
825
- error_handling: Literal["raise", "skip", "log"] = "log",
826
- output_file: str | Path | None = None,
827
- return_dataframe: bool = True,
828
- silent_mode: bool = False,
829
- metadata_columns: list[str] | None = None,
830
- ) -> DataFrame | list[dict[str, Any]]: # type: ignore
831
- return self._run_sync(
832
- self.evaluate_async(
833
- dataset=dataset,
834
- start_agent=start_agent,
835
- input_mapping=input_mapping,
836
- answer_mapping=answer_mapping,
837
- metrics=metrics,
838
- metric_configs=metric_configs,
839
- static_inputs=static_inputs,
840
- parallel=parallel,
841
- max_workers=max_workers,
842
- use_temporal=use_temporal,
843
- error_handling=error_handling,
844
- output_file=output_file,
845
- return_dataframe=return_dataframe,
846
- silent_mode=silent_mode,
847
- metadata_columns=metadata_columns,
848
- )
849
- )
850
-
851
- # --- Server & CLI Starters (Delegation) ---
852
- def start_api(
853
- self,
854
- host: str = "127.0.0.1",
855
- port: int = 8344,
856
- server_name: str = "Flock Server",
857
- create_ui: bool = True, # Default to True for the integrated experience
858
- ui_theme: str | None = None,
859
- custom_endpoints: Sequence[FlockEndpoint]
860
- | dict[tuple[str, list[str] | None], Callable[..., Any]]
861
- | None = None,
862
- ) -> None:
863
- """Starts a unified REST API server and/or Web UI for this Flock instance."""
864
- import warnings
865
-
866
- warnings.warn(
867
- "start_api() is deprecated and will be removed in a future release. "
868
- "Use serve() instead.",
869
- DeprecationWarning,
870
- stacklevel=2,
871
- )
872
- # Delegate to the new serve() method (create_ui maps to ui)
873
- return self.serve(
874
- host=host,
875
- port=port,
876
- server_name=server_name,
877
- ui=create_ui,
878
- ui_theme=ui_theme,
879
- custom_endpoints=custom_endpoints,
880
- )
881
-
882
- # ------------------------------------------------------------------
883
- # New preferred method name
884
- # ------------------------------------------------------------------
885
-
886
- def serve(
887
- self,
888
- host: str = "127.0.0.1",
889
- port: int = 8344,
890
- server_name: str = "Flock Server",
891
- ui: bool = True,
892
- chat: bool = False,
893
- chat_agent: str | None = None, # Reserved for future real agent chat
894
- chat_message_key: str = "message",
895
- chat_history_key: str = "history",
896
- chat_response_key: str = "response",
897
- ui_theme: str | None = None,
898
- custom_endpoints: Sequence[FlockEndpoint]
899
- | dict[tuple[str, list[str] | None], Callable[..., Any]]
900
- | None = None,
901
- ) -> None:
902
- """Launch an HTTP server that exposes the core REST API and, optionally, the
903
- browser-based UI.
904
-
905
- Args:
906
- host: Bind address for the server (default "127.0.0.1").
907
- port: TCP port to listen on (default 8344).
908
- server_name: Title shown in the OpenAPI docs / logs.
909
- ui: If True (default) the Pico/HTMX web UI routes are included. If False
910
- only the JSON API groups (core & custom) are served.
911
- chat: If True, enable chat routes.
912
- chat_agent: Name of the agent to use for chat.
913
- chat_message_key: Key for chat message in input.
914
- chat_history_key: Key for chat history in input.
915
- chat_response_key: Key for chat response in output.
916
- ui_theme: Optional UI theme name or "random".
917
- custom_endpoints: Additional API routes to add, either as a list of
918
- FlockEndpoint objects or the legacy dict format.
919
- """
920
- try:
921
- from flock.webapp.run import start_unified_server
922
- except ImportError:
923
- logger.error(
924
- "Web application components not found (flock.webapp.run). "
925
- "Cannot start HTTP server. Ensure webapp dependencies are installed."
926
- )
927
- return
928
-
929
- logger.info(
930
- f"Attempting to start server for Flock '{self.name}' on {host}:{port}. UI enabled: {ui}"
931
- )
932
-
933
- start_unified_server(
934
- flock_instance=self,
935
- host=host,
936
- port=port,
937
- server_title=server_name,
938
- enable_ui_routes=ui,
939
- enable_chat_routes=chat,
940
- ui_theme=ui_theme,
941
- custom_endpoints=custom_endpoints,
942
- )
943
-
944
- def start_cli(
945
- self,
946
- start_agent: FlockAgent
947
- | str
948
- | None = None, # Added start_agent to match method signature in file_26
949
- server_name: str = "Flock CLI",
950
- show_results: bool = False,
951
- edit_mode: bool = False,
952
- ) -> None:
953
- """Starts an interactive CLI for this Flock instance."""
954
- # Import runner locally
955
- try:
956
- from flock.cli.runner import start_flock_cli
957
- except ImportError:
958
- logger.error(
959
- "CLI components not found. Cannot start CLI. "
960
- "Ensure CLI dependencies are installed."
961
- )
962
- return
963
-
964
- # The start_flock_cli function in file_50 doesn't take start_agent
965
- # but the original docs for start_cli did.
966
- # For now, I'll pass it through, assuming start_flock_cli will be updated or ignore it.
967
- # If start_agent is crucial here, start_flock_cli needs to handle it.
968
- logger.info(f"Starting CLI for Flock '{self.name}'...")
969
- start_flock_cli(
970
- flock=self, # Pass the Flock instance
971
- # start_agent=start_agent, # This argument is not in the definition of start_flock_cli in file_50
972
- server_name=server_name,
973
- show_results=show_results,
974
- edit_mode=edit_mode,
975
- )
976
-
977
- # --- Serialization Delegation Methods ---
978
- def to_dict(self, path_type: str = "relative") -> dict[str, Any]:
979
- """Serialize Flock instance to dictionary using FlockSerializer."""
980
- from flock.core.serialization.flock_serializer import FlockSerializer
981
-
982
- return FlockSerializer.serialize(self, path_type=path_type)
983
-
984
- @classmethod
985
- def from_dict(cls: type[T], data: dict[str, Any]) -> T:
986
- """Deserialize Flock instance from dictionary using FlockSerializer."""
987
- from flock.core.serialization.flock_serializer import FlockSerializer
988
-
989
- return FlockSerializer.deserialize(cls, data)
990
-
991
- # --- Static Method Loader (Delegates to loader module) ---
992
- @staticmethod
993
- def load_from_file(file_path: str) -> Flock: # Ensure return type is Flock
994
- """Load a Flock instance from various file formats (delegates to loader)."""
995
- from flock.core.util.loader import load_flock_from_file
996
-
997
- loaded_flock = load_flock_from_file(file_path)
998
- # Ensure the loaded object is indeed a Flock instance
999
- if not isinstance(loaded_flock, Flock):
1000
- raise TypeError(
1001
- f"Loaded object from {file_path} is not a Flock instance, but {type(loaded_flock)}"
1002
- )
1003
- return loaded_flock