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,702 +0,0 @@
1
- # src/flock/core/flock_registry.py
2
- """Centralized registry for managing Agents, Callables, Types, and Component Classes
3
- within the Flock framework to support dynamic lookup and serialization.
4
- """
5
-
6
- from __future__ import annotations # Add this at the very top
7
-
8
- import builtins
9
- import importlib
10
- import inspect
11
- import os
12
- import pkgutil
13
- import sys
14
- from collections.abc import Callable, Mapping, Sequence
15
- from dataclasses import is_dataclass
16
- from typing import ( # Add TYPE_CHECKING
17
- TYPE_CHECKING,
18
- Any,
19
- Literal,
20
- Optional,
21
- TypeVar,
22
- Union,
23
- overload,
24
- )
25
-
26
- from pydantic import BaseModel
27
-
28
- if TYPE_CHECKING:
29
- from flock.core.flock_agent import (
30
- FlockAgent, # Import only for type checking
31
- )
32
- from flock.core.flock_evaluator import FlockEvaluator
33
- from flock.core.flock_module import FlockModule
34
- from flock.core.flock_router import FlockRouter
35
- from flock.core.mcp.flock_mcp_server import FlockMCPServerBase
36
-
37
- COMPONENT_BASE_TYPES = (FlockModule, FlockEvaluator, FlockRouter)
38
-
39
- IS_COMPONENT_CHECK_ENABLED = True
40
- else:
41
- # Define dummy types or skip check if not type checking
42
- FlockAgent = Any # Or define a dummy class
43
- COMPONENT_BASE_TYPES = ()
44
- IS_COMPONENT_CHECK_ENABLED = False
45
-
46
- # Fallback if core types aren't available during setup
47
- from flock.core.flock_module import FlockModuleConfig
48
- from flock.core.logging.logging import get_logger
49
-
50
- logger = get_logger("registry")
51
- T = TypeVar("T")
52
- ClassType = TypeVar("ClassType", bound=type)
53
- FuncType = TypeVar("FuncType", bound=Callable)
54
- ConfigType = TypeVar("ConfigType", bound=BaseModel)
55
- _COMPONENT_CONFIG_MAP: dict[type[BaseModel], type[any]] = {}
56
-
57
-
58
- class FlockRegistry:
59
- """Singleton registry for Agents, Callables (functions/methods) and MCP Servers.
60
-
61
- Types (Pydantic/Dataclasses used in signatures), and Component Classes
62
- (Modules, Evaluators, Routers).
63
- """
64
-
65
- _instance = None
66
-
67
- _agents: dict[str, FlockAgent]
68
- _servers: dict[str, FlockMCPServerBase]
69
- _callables: dict[str, Callable]
70
- _types: dict[str, type]
71
- _components: dict[str, type] # For Module, Evaluator, Router classes
72
-
73
- def __new__(cls):
74
- if cls._instance is None:
75
- cls._instance = super().__new__(cls)
76
- cls._instance._initialize()
77
- # logger.info("FlockRegistry instance created.")
78
- return cls._instance
79
-
80
- def _initialize(self):
81
- """Initialize the internal dictionaries."""
82
- self._agents = {}
83
- self._servers = {}
84
- self._callables = {}
85
- self._types = {}
86
- self._components = {}
87
- # logger.debug("FlockRegistry initialized internal stores.")
88
- # Auto-register core Python types
89
- self._register_core_types()
90
-
91
- def _register_core_types(self):
92
- """Registers common built-in and typing types."""
93
- core_types = [
94
- str,
95
- int,
96
- float,
97
- bool,
98
- list,
99
- dict,
100
- tuple,
101
- set,
102
- Any,
103
- Mapping,
104
- Sequence,
105
- TypeVar,
106
- Literal,
107
- Optional,
108
- Union, # Common typing generics
109
- ]
110
- for t in core_types:
111
- try:
112
- self.register_type(t)
113
- except Exception as e:
114
- logger.error(f"Failed to auto-register core type {t}: {e}")
115
-
116
- @staticmethod
117
- def register_config_component_pair(
118
- config_cls: type[ConfigType], component_cls: type[ClassType]
119
- ):
120
- """Explicitly registers the mapping between a config and component class."""
121
- from flock.core.flock_evaluator import (
122
- FlockEvaluatorConfig,
123
- )
124
- from flock.core.flock_router import FlockRouterConfig
125
-
126
- if not issubclass(
127
- config_cls,
128
- FlockModuleConfig | FlockRouterConfig | FlockEvaluatorConfig,
129
- ):
130
- logger.warning(
131
- f"Config class {config_cls.__name__} does not inherit from a standard Flock config base."
132
- )
133
- # Add more checks if needed (e.g., component_cls inherits from Module/Router/Evaluator)
134
-
135
- if (
136
- config_cls in _COMPONENT_CONFIG_MAP
137
- and _COMPONENT_CONFIG_MAP[config_cls] != component_cls
138
- ):
139
- logger.warning(
140
- f"Config class {config_cls.__name__} already mapped to {_COMPONENT_CONFIG_MAP[config_cls].__name__}. Overwriting with {component_cls.__name__}."
141
- )
142
-
143
- _COMPONENT_CONFIG_MAP[config_cls] = component_cls
144
- logger.debug(
145
- f"Registered config mapping: {config_cls.__name__} -> {component_cls.__name__}"
146
- )
147
-
148
- @staticmethod
149
- def get_component_class_for_config(
150
- config_cls: type[ConfigType],
151
- ) -> type[ClassType] | None:
152
- """Looks up the Component Class associated with a Config Class."""
153
- return _COMPONENT_CONFIG_MAP.get(config_cls)
154
-
155
- # --- Path String Generation ---
156
- @staticmethod
157
- def _get_path_string(obj: Callable | type) -> str | None:
158
- """Generates a unique path string 'module.ClassName' or 'module.function_name'."""
159
- try:
160
- module = obj.__module__
161
- name = obj.__name__
162
- if module == "builtins":
163
- return name
164
- # Check if it's nested (basic check, might not cover all edge cases)
165
- if "." in name and hasattr(sys.modules[module], name.split(".")[0]):
166
- # Likely a nested class/method - serialization might need custom handling or pickle
167
- logger.warning(
168
- f"Object {name} appears nested in {module}. Path string might be ambiguous."
169
- )
170
- return f"{module}.{name}"
171
- except AttributeError:
172
- logger.warning(f"Could not determine module/name for object: {obj}")
173
- return None
174
-
175
- # --- Server Registration ---
176
- def register_server(self, server: FlockMCPServerBase) -> None:
177
- """Registers a flock mcp server by its name."""
178
- if not hasattr(server.config, "name") or not server.config.name:
179
- logger.error(
180
- "Attempted to register a server without a valid 'name' attribute."
181
- )
182
- return
183
- if (
184
- server.config.name in self._servers
185
- and self._servers[server.config.name] != server
186
- ):
187
- logger.warning(
188
- f"Server '{server.config.name}' already registered. Overwriting."
189
- )
190
- self._servers[server.config.name] = server
191
- logger.debug(f"Registered server: {server.config.name}")
192
-
193
- def get_server(self, name: str) -> FlockMCPServerBase | None:
194
- """Retrieves a registered FlockMCPServer instance by name."""
195
- server = self._servers.get(name)
196
- if not server:
197
- logger.warning(f"Server '{name}' not found in registry.")
198
- return server
199
-
200
- def get_all_server_names(self) -> list[str]:
201
- """Returns a list of names for all registered servers."""
202
- return list(self._servers.keys())
203
-
204
- # --- Agent Registration ---
205
- def register_agent(self, agent: FlockAgent, *, force: bool = False) -> None:
206
- """Registers a FlockAgent instance by its name.
207
-
208
- Args:
209
- agent: The agent instance to register.
210
- force: If True, allow overwriting an existing **different** agent registered under the same name.
211
- If False and a conflicting registration exists, a ValueError is raised.
212
- """
213
- if not hasattr(agent, "name") or not agent.name:
214
- logger.error(
215
- "Attempted to register an agent without a valid 'name' attribute."
216
- )
217
- return
218
-
219
- if agent.name in self._agents and self._agents[agent.name] is not agent:
220
- # Same agent already registered → silently ignore; different instance → error/force.
221
- if not force:
222
- raise ValueError(
223
- f"Agent '{agent.name}' already registered with a different instance. "
224
- "Pass force=True to overwrite the existing registration."
225
- )
226
- logger.warning(
227
- f"Overwriting existing agent '{agent.name}' registration due to force=True."
228
- )
229
-
230
- self._agents[agent.name] = agent
231
- logger.debug(f"Registered agent: {agent.name}")
232
-
233
- def get_agent(self, name: str) -> FlockAgent | None:
234
- """Retrieves a registered FlockAgent instance by name."""
235
- agent = self._agents.get(name)
236
- if not agent:
237
- logger.warning(f"Agent '{name}' not found in registry.")
238
- return agent
239
-
240
- def get_all_agent_names(self) -> list[str]:
241
- """Returns a list of names of all registered agents."""
242
- return list(self._agents.keys())
243
-
244
- # --- Callable Registration ---
245
- def register_callable(
246
- self, func: Callable, name: str | None = None
247
- ) -> str | None:
248
- """Registers a callable (function/method). Returns its path string identifier."""
249
- path_str = name or self._get_path_string(func)
250
- if path_str:
251
- if (
252
- path_str in self._callables
253
- and self._callables[path_str] != func
254
- ):
255
- logger.warning(
256
- f"Callable '{path_str}' already registered with a different function. Overwriting."
257
- )
258
- self._callables[path_str] = func
259
- logger.debug(f"Registered callable: '{path_str}' ({func.__name__})")
260
- return path_str
261
- logger.warning(
262
- f"Could not register callable {func.__name__}: Unable to determine path string"
263
- )
264
- return None
265
-
266
- def get_callable(self, name_or_path: str) -> Callable:
267
- """Retrieves a callable by its registered name or full path string.
268
- Attempts dynamic import if not found directly. Prioritizes exact match,
269
- then searches for matches ending with '.{name}'.
270
- """
271
- # 1. Try exact match first (covers full paths and simple names if registered that way)
272
- if name_or_path in self._callables:
273
- logger.debug(
274
- f"Found callable '{name_or_path}' directly in registry."
275
- )
276
- return self._callables[name_or_path]
277
-
278
- # 2. If not found, and it looks like a simple name, search registered paths
279
- if "." not in name_or_path:
280
- matches = []
281
- for path_str, func in self._callables.items():
282
- # Check if path ends with ".{simple_name}" or exactly matches simple_name
283
- if path_str == name_or_path or path_str.endswith(
284
- f".{name_or_path}"
285
- ):
286
- matches.append(func)
287
-
288
- if len(matches) == 1:
289
- logger.debug(
290
- f"Found unique callable for simple name '{name_or_path}' via path '{self.get_callable_path_string(matches[0])}'."
291
- )
292
- return matches[0]
293
- elif len(matches) > 1:
294
- # Ambiguous simple name - require full path
295
- found_paths = [
296
- self.get_callable_path_string(f) for f in matches
297
- ]
298
- logger.error(
299
- f"Ambiguous callable name '{name_or_path}'. Found matches: {found_paths}. Use full path string for lookup."
300
- )
301
- raise KeyError(
302
- f"Ambiguous callable name '{name_or_path}'. Use full path string."
303
- )
304
- # else: Not found by simple name search in registry, proceed to dynamic import
305
-
306
- # 3. Attempt dynamic import if it looks like a full path
307
- if "." in name_or_path:
308
- logger.debug(
309
- f"Callable '{name_or_path}' not in registry cache, attempting dynamic import."
310
- )
311
- try:
312
- module_name, func_name = name_or_path.rsplit(".", 1)
313
- module = importlib.import_module(module_name)
314
- func = getattr(module, func_name)
315
- if callable(func):
316
- self.register_callable(
317
- func, name_or_path
318
- ) # Cache dynamically imported
319
- logger.info(
320
- f"Successfully imported and registered module callable '{name_or_path}'"
321
- )
322
- return func
323
- else:
324
- raise TypeError(
325
- f"Dynamically imported object '{name_or_path}' is not callable."
326
- )
327
- except (ImportError, AttributeError, TypeError) as e:
328
- logger.error(
329
- f"Failed to dynamically load/find callable '{name_or_path}': {e}",
330
- exc_info=False,
331
- )
332
- # Fall through to raise KeyError
333
- # 4. Handle built-ins if not found yet (might be redundant if simple name check worked)
334
- elif name_or_path in builtins.__dict__:
335
- func = builtins.__dict__[name_or_path]
336
- if callable(func):
337
- self.register_callable(func, name_or_path) # Cache it
338
- logger.info(
339
- f"Found and registered built-in callable '{name_or_path}'"
340
- )
341
- return func
342
-
343
- # 5. Final failure
344
- logger.error(
345
- f"Callable '{name_or_path}' not found in registry or via import."
346
- )
347
- raise KeyError(f"Callable '{name_or_path}' not found.")
348
-
349
- def get_callable_path_string(self, func: Callable) -> str | None:
350
- """Gets the path string for a callable, registering it if necessary."""
351
- # First try to find by direct identity
352
- for path_str, registered_func in self._callables.items():
353
- if func == registered_func:
354
- logger.debug(
355
- f"Found existing path string for callable: '{path_str}'"
356
- )
357
- return path_str
358
-
359
- # If not found by identity, generate path, register, and return
360
- path_str = self.register_callable(func)
361
- if path_str:
362
- logger.debug(
363
- f"Generated and registered new path string for callable: '{path_str}'"
364
- )
365
- else:
366
- logger.warning(
367
- f"Failed to generate path string for callable {func.__name__}"
368
- )
369
-
370
- return path_str
371
-
372
- # --- Type Registration ---
373
- def register_type(
374
- self, type_obj: type, name: str | None = None
375
- ) -> str | None:
376
- """Registers a class/type (Pydantic, Dataclass, etc.) used in signatures."""
377
- type_name = name or type_obj.__name__
378
- if type_name:
379
- if type_name in self._types and self._types[type_name] != type_obj:
380
- logger.warning(
381
- f"Type '{type_name}' already registered. Overwriting."
382
- )
383
- self._types[type_name] = type_obj
384
- logger.debug(f"Registered type: {type_name}")
385
- return type_name
386
- return None
387
-
388
- def get_type(self, type_name: str) -> type:
389
- """Retrieves a registered type by its name."""
390
- if type_name in self._types:
391
- return self._types[type_name]
392
- else:
393
- # Consider adding dynamic import attempts for types if needed,
394
- # but explicit registration is generally safer for types.
395
- logger.warning(f"Type '{type_name}' not found in registry. Will attempt to build it from builtins.")
396
- raise KeyError(
397
- f"Type '{type_name}' not found. Ensure it is registered."
398
- )
399
-
400
- # --- Component Class Registration ---
401
- def register_component(
402
- self, component_class: type, name: str | None = None
403
- ) -> str | None:
404
- """Registers a component class (Module, Evaluator, Router)."""
405
- type_name = name or component_class.__name__
406
- if type_name:
407
- # Optional: Add check if it's a subclass of expected bases
408
- # if COMPONENT_BASE_TYPES and not issubclass(component_class, COMPONENT_BASE_TYPES):
409
- # logger.warning(f"Registering class '{type_name}' which is not a standard Flock component type.")
410
- if (
411
- type_name in self._components
412
- and self._components[type_name] != component_class
413
- ):
414
- logger.warning(
415
- f"Component class '{type_name}' already registered. Overwriting."
416
- )
417
- self._components[type_name] = component_class
418
- logger.debug(f"Registered component class: {type_name}")
419
- return type_name
420
- return None
421
-
422
- def get_component(self, type_name: str) -> type:
423
- """Retrieves a component class by its type name."""
424
- if type_name in self._components:
425
- return self._components[type_name]
426
- else:
427
- # Dynamic import attempts similar to get_callable could be added here if desired,
428
- # targeting likely module locations based on type_name conventions.
429
- logger.error(
430
- f"Component class '{type_name}' not found in registry."
431
- )
432
- raise KeyError(
433
- f"Component class '{type_name}' not found. Ensure it is registered."
434
- )
435
-
436
- def get_component_type_name(self, component_class: type) -> str | None:
437
- """Gets the type name for a component class, registering it if necessary."""
438
- for type_name, registered_class in self._components.items():
439
- if component_class == registered_class:
440
- return type_name
441
- # If not found, register using class name and return
442
- return self.register_component(component_class)
443
-
444
- # --- Auto-Registration ---
445
- def register_module_components(self, module_or_path: Any) -> None:
446
- """Scans a module (object or path string) and automatically registers.
447
-
448
- - Functions as callables.
449
- - Pydantic Models and Dataclasses as types.
450
- - Subclasses of FlockModule, FlockEvaluator, FlockRouter as components.
451
- """
452
- try:
453
- if isinstance(module_or_path, str):
454
- module = importlib.import_module(module_or_path)
455
- elif inspect.ismodule(module_or_path):
456
- module = module_or_path
457
- else:
458
- logger.error(
459
- f"Invalid input for auto-registration: {module_or_path}. Must be module object or path string."
460
- )
461
- return
462
-
463
- logger.info(
464
- f"Auto-registering components from module: {module.__name__}"
465
- )
466
- registered_count = {"callable": 0, "type": 0, "component": 0}
467
-
468
- for name, obj in inspect.getmembers(module):
469
- if name.startswith("_"):
470
- continue # Skip private/internal
471
-
472
- # Register Functions as Callables
473
- if (
474
- inspect.isfunction(obj)
475
- and obj.__module__ == module.__name__
476
- ):
477
- if self.register_callable(obj):
478
- registered_count["callable"] += 1
479
-
480
- # Register Classes (Types and Components)
481
- elif inspect.isclass(obj) and obj.__module__ == module.__name__:
482
- is_component = False
483
- # Register as Component if subclass of base types
484
- if (
485
- COMPONENT_BASE_TYPES
486
- and issubclass(obj, COMPONENT_BASE_TYPES)
487
- and self.register_component(obj)
488
- ):
489
- registered_count["component"] += 1
490
- is_component = True # Mark as component
491
-
492
- # Register as Type if Pydantic Model or Dataclass
493
- # A component can also be a type used in signatures
494
- base_model_or_dataclass = isinstance(obj, type) and (
495
- issubclass(obj, BaseModel) or is_dataclass(obj)
496
- )
497
- if (
498
- base_model_or_dataclass
499
- and self.register_type(obj)
500
- and not is_component
501
- ):
502
- # Only increment type count if it wasn't already counted as component
503
- registered_count["type"] += 1
504
-
505
- logger.info(
506
- f"Auto-registration summary for {module.__name__}: "
507
- f"{registered_count['callable']} callables, "
508
- f"{registered_count['type']} types, "
509
- f"{registered_count['component']} components."
510
- )
511
-
512
- except Exception as e:
513
- logger.error(
514
- f"Error during auto-registration for {module_or_path}: {e}",
515
- exc_info=True,
516
- )
517
-
518
-
519
- # --- Initialize Singleton ---
520
- _registry_instance = FlockRegistry()
521
-
522
-
523
- # --- Convenience Access ---
524
- # Provide a function to easily get the singleton instance
525
- def get_registry() -> FlockRegistry:
526
- """Returns the singleton FlockRegistry instance."""
527
- return _registry_instance
528
-
529
-
530
- # Type hinting for decorators to preserve signature
531
- @overload
532
- def flock_component(cls: ClassType) -> ClassType: ... # Basic registration
533
-
534
-
535
- @overload
536
- def flock_component(
537
- *, name: str | None = None, config_class: type[ConfigType] | None = None
538
- ) -> Callable[[ClassType], ClassType]: ... # With options
539
-
540
-
541
- def flock_component(
542
- cls: ClassType | None = None,
543
- *,
544
- name: str | None = None,
545
- config_class: type[ConfigType] | None = None,
546
- ) -> Any:
547
- """Decorator to register a Flock Component class and optionally link its config class."""
548
- registry = get_registry()
549
-
550
- def decorator(inner_cls: ClassType) -> ClassType:
551
- if not inspect.isclass(inner_cls):
552
- raise TypeError("@flock_component can only decorate classes.")
553
-
554
- component_name = name or inner_cls.__name__
555
- registry.register_component(
556
- inner_cls, name=component_name
557
- ) # Register component by name
558
-
559
- # If config_class is provided, register the mapping
560
- if config_class:
561
- FlockRegistry.register_config_component_pair(
562
- config_class, inner_cls
563
- )
564
-
565
- return inner_cls
566
-
567
- if cls is None:
568
- # Called as @flock_component(name="...", config_class=...)
569
- return decorator
570
- else:
571
- # Called as @flock_component
572
- return decorator(cls)
573
-
574
-
575
- # Type hinting for decorators
576
- @overload
577
- def flock_tool(func: FuncType) -> FuncType: ...
578
-
579
-
580
- @overload
581
- def flock_tool(
582
- *, name: str | None = None
583
- ) -> Callable[[FuncType], FuncType]: ...
584
-
585
-
586
- def flock_tool(func: FuncType | None = None, *, name: str | None = None) -> Any:
587
- """Decorator to register a callable function/method as a Tool (or general callable).
588
-
589
- Usage:
590
- @flock_tool
591
- def my_web_search(query: str): ...
592
-
593
- @flock_tool(name="utils.calculate_pi")
594
- def compute_pi(): ...
595
- """
596
- registry = get_registry()
597
-
598
- def decorator(inner_func: FuncType) -> FuncType:
599
- if not callable(inner_func):
600
- raise TypeError("@flock_tool can only decorate callables.")
601
- # Let registry handle default name generation if None
602
- registry.register_callable(inner_func, name=name)
603
- return inner_func
604
-
605
- if func is None:
606
- # Called as @flock_tool(name="...")
607
- return decorator
608
- else:
609
- # Called as @flock_tool
610
- return decorator(func)
611
-
612
-
613
- # Alias for clarity if desired
614
- flock_callable = flock_tool
615
-
616
-
617
- @overload
618
- def flock_type(cls: ClassType) -> ClassType: ...
619
-
620
-
621
- @overload
622
- def flock_type(
623
- *, name: str | None = None
624
- ) -> Callable[[ClassType], ClassType]: ...
625
-
626
-
627
- def flock_type(cls: ClassType | None = None, *, name: str | None = None) -> Any:
628
- """Decorator to register a Type (Pydantic Model, Dataclass) used in signatures.
629
-
630
- Usage:
631
- @flock_type
632
- class MyDataModel(BaseModel): ...
633
-
634
- @flock_type(name="UserInput")
635
- @dataclass
636
- class UserQuery: ...
637
- """
638
- registry = get_registry()
639
-
640
- def decorator(inner_cls: ClassType) -> ClassType:
641
- if not inspect.isclass(inner_cls):
642
- raise TypeError("@flock_type can only decorate classes.")
643
- type_name = name or inner_cls.__name__
644
- registry.register_type(inner_cls, name=type_name)
645
- return inner_cls
646
-
647
- if cls is None:
648
- # Called as @flock_type(name="...")
649
- return decorator
650
- else:
651
- # Called as @flock_type
652
- return decorator(cls)
653
-
654
-
655
- # --- Auto-register known core components and tools ---
656
- def _auto_register_by_path(self):
657
- # List of base packages to scan for components and tools
658
- packages_to_scan = [
659
- "flock.tools",
660
- "flock.evaluators",
661
- "flock.modules",
662
- "flock.routers",
663
- ]
664
-
665
- for package_name in packages_to_scan:
666
- try:
667
- package_spec = importlib.util.find_spec(package_name)
668
- if package_spec and package_spec.origin:
669
- package_path_list = [os.path.dirname(package_spec.origin)]
670
- logger.info(f"Recursively scanning for modules in package: {package_name} (path: {package_path_list[0]})")
671
-
672
- # Use walk_packages to recursively find all modules
673
- for module_loader, module_name, is_pkg in pkgutil.walk_packages(
674
- path=package_path_list,
675
- prefix=package_name + ".", # Ensures module_name is fully qualified
676
- onerror=lambda name: logger.warning(f"Error importing module {name} during scan.")
677
- ):
678
- if not is_pkg and not module_name.split('.')[-1].startswith("_"):
679
- # We are interested in actual modules, not sub-packages themselves for registration
680
- # And also skip modules starting with underscore (e.g. __main__.py)
681
- try:
682
- logger.debug(f"Attempting to auto-register components from module: {module_name}")
683
- _registry_instance.register_module_components(module_name)
684
- except ImportError as e:
685
- logger.warning(
686
- f"Could not auto-register from {module_name}: Module not found or import error: {e}"
687
- )
688
- except Exception as e: # Catch other potential errors during registration
689
- logger.error(
690
- f"Unexpected error during auto-registration of {module_name}: {e}",
691
- exc_info=True
692
- )
693
- else:
694
- logger.warning(f"Could not find package spec for '{package_name}' to auto-register components/tools.")
695
- except Exception as e:
696
- logger.error(f"Error while trying to dynamically register from '{package_name}': {e}", exc_info=True)
697
-
698
- # Bootstrapping the registry
699
- # _auto_register_by_path() # Commented out or removed
700
-
701
- # Make the registration function public and rename it
702
- FlockRegistry.discover_and_register_components = _auto_register_by_path