flock-core 0.5.0b28__py3-none-any.whl → 0.5.0b51__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 (469) hide show
  1. flock/__init__.py +12 -217
  2. flock/agent.py +678 -0
  3. flock/api/themes.py +71 -0
  4. flock/artifacts.py +79 -0
  5. flock/cli.py +75 -0
  6. flock/components.py +173 -0
  7. flock/dashboard/__init__.py +28 -0
  8. flock/dashboard/collector.py +283 -0
  9. flock/dashboard/events.py +182 -0
  10. flock/dashboard/launcher.py +230 -0
  11. flock/dashboard/service.py +537 -0
  12. flock/dashboard/websocket.py +235 -0
  13. flock/engines/__init__.py +6 -0
  14. flock/engines/dspy_engine.py +856 -0
  15. flock/examples.py +128 -0
  16. flock/frontend/README.md +678 -0
  17. flock/frontend/docs/DESIGN_SYSTEM.md +1980 -0
  18. flock/frontend/index.html +12 -0
  19. flock/frontend/package-lock.json +4347 -0
  20. flock/frontend/package.json +48 -0
  21. flock/frontend/src/App.tsx +79 -0
  22. flock/frontend/src/__tests__/e2e/critical-scenarios.test.tsx +587 -0
  23. flock/frontend/src/__tests__/integration/filtering-e2e.test.tsx +387 -0
  24. flock/frontend/src/__tests__/integration/graph-rendering.test.tsx +640 -0
  25. flock/frontend/src/__tests__/integration/indexeddb-persistence.test.tsx +699 -0
  26. flock/frontend/src/components/common/BuildInfo.tsx +39 -0
  27. flock/frontend/src/components/common/EmptyState.module.css +115 -0
  28. flock/frontend/src/components/common/EmptyState.tsx +128 -0
  29. flock/frontend/src/components/common/ErrorBoundary.module.css +169 -0
  30. flock/frontend/src/components/common/ErrorBoundary.tsx +118 -0
  31. flock/frontend/src/components/common/KeyboardShortcutsDialog.css +251 -0
  32. flock/frontend/src/components/common/KeyboardShortcutsDialog.tsx +151 -0
  33. flock/frontend/src/components/common/LoadingSpinner.module.css +97 -0
  34. flock/frontend/src/components/common/LoadingSpinner.tsx +29 -0
  35. flock/frontend/src/components/controls/PublishControl.css +547 -0
  36. flock/frontend/src/components/controls/PublishControl.test.tsx +543 -0
  37. flock/frontend/src/components/controls/PublishControl.tsx +432 -0
  38. flock/frontend/src/components/details/DetailWindowContainer.tsx +62 -0
  39. flock/frontend/src/components/details/LiveOutputTab.test.tsx +792 -0
  40. flock/frontend/src/components/details/LiveOutputTab.tsx +220 -0
  41. flock/frontend/src/components/details/MessageHistoryTab.tsx +299 -0
  42. flock/frontend/src/components/details/NodeDetailWindow.test.tsx +501 -0
  43. flock/frontend/src/components/details/NodeDetailWindow.tsx +218 -0
  44. flock/frontend/src/components/details/RunStatusTab.tsx +307 -0
  45. flock/frontend/src/components/details/tabs.test.tsx +1015 -0
  46. flock/frontend/src/components/filters/CorrelationIDFilter.module.css +102 -0
  47. flock/frontend/src/components/filters/CorrelationIDFilter.test.tsx +197 -0
  48. flock/frontend/src/components/filters/CorrelationIDFilter.tsx +121 -0
  49. flock/frontend/src/components/filters/FilterBar.module.css +29 -0
  50. flock/frontend/src/components/filters/FilterBar.test.tsx +133 -0
  51. flock/frontend/src/components/filters/FilterBar.tsx +33 -0
  52. flock/frontend/src/components/filters/FilterPills.module.css +79 -0
  53. flock/frontend/src/components/filters/FilterPills.test.tsx +173 -0
  54. flock/frontend/src/components/filters/FilterPills.tsx +67 -0
  55. flock/frontend/src/components/filters/TimeRangeFilter.module.css +91 -0
  56. flock/frontend/src/components/filters/TimeRangeFilter.test.tsx +154 -0
  57. flock/frontend/src/components/filters/TimeRangeFilter.tsx +105 -0
  58. flock/frontend/src/components/graph/AgentNode.test.tsx +75 -0
  59. flock/frontend/src/components/graph/AgentNode.tsx +322 -0
  60. flock/frontend/src/components/graph/GraphCanvas.tsx +406 -0
  61. flock/frontend/src/components/graph/MessageFlowEdge.tsx +128 -0
  62. flock/frontend/src/components/graph/MessageNode.test.tsx +62 -0
  63. flock/frontend/src/components/graph/MessageNode.tsx +116 -0
  64. flock/frontend/src/components/graph/MiniMap.tsx +47 -0
  65. flock/frontend/src/components/graph/TransformEdge.tsx +123 -0
  66. flock/frontend/src/components/layout/DashboardLayout.css +407 -0
  67. flock/frontend/src/components/layout/DashboardLayout.tsx +300 -0
  68. flock/frontend/src/components/layout/Header.module.css +88 -0
  69. flock/frontend/src/components/layout/Header.tsx +52 -0
  70. flock/frontend/src/components/modules/EventLogModule.test.tsx +401 -0
  71. flock/frontend/src/components/modules/EventLogModule.tsx +396 -0
  72. flock/frontend/src/components/modules/EventLogModuleWrapper.tsx +17 -0
  73. flock/frontend/src/components/modules/ModuleRegistry.test.ts +333 -0
  74. flock/frontend/src/components/modules/ModuleRegistry.ts +85 -0
  75. flock/frontend/src/components/modules/ModuleWindow.tsx +155 -0
  76. flock/frontend/src/components/modules/registerModules.ts +20 -0
  77. flock/frontend/src/components/settings/AdvancedSettings.tsx +175 -0
  78. flock/frontend/src/components/settings/AppearanceSettings.tsx +185 -0
  79. flock/frontend/src/components/settings/GraphSettings.tsx +110 -0
  80. flock/frontend/src/components/settings/SettingsPanel.css +327 -0
  81. flock/frontend/src/components/settings/SettingsPanel.tsx +131 -0
  82. flock/frontend/src/components/settings/ThemeSelector.tsx +298 -0
  83. flock/frontend/src/hooks/useKeyboardShortcuts.ts +148 -0
  84. flock/frontend/src/hooks/useModulePersistence.test.ts +442 -0
  85. flock/frontend/src/hooks/useModulePersistence.ts +154 -0
  86. flock/frontend/src/hooks/useModules.ts +139 -0
  87. flock/frontend/src/hooks/usePersistence.ts +139 -0
  88. flock/frontend/src/main.tsx +13 -0
  89. flock/frontend/src/services/api.ts +213 -0
  90. flock/frontend/src/services/indexeddb.test.ts +793 -0
  91. flock/frontend/src/services/indexeddb.ts +794 -0
  92. flock/frontend/src/services/layout.test.ts +437 -0
  93. flock/frontend/src/services/layout.ts +146 -0
  94. flock/frontend/src/services/themeApplicator.ts +140 -0
  95. flock/frontend/src/services/themeService.ts +77 -0
  96. flock/frontend/src/services/websocket.test.ts +595 -0
  97. flock/frontend/src/services/websocket.ts +685 -0
  98. flock/frontend/src/store/filterStore.test.ts +242 -0
  99. flock/frontend/src/store/filterStore.ts +103 -0
  100. flock/frontend/src/store/graphStore.test.ts +186 -0
  101. flock/frontend/src/store/graphStore.ts +414 -0
  102. flock/frontend/src/store/moduleStore.test.ts +253 -0
  103. flock/frontend/src/store/moduleStore.ts +57 -0
  104. flock/frontend/src/store/settingsStore.ts +188 -0
  105. flock/frontend/src/store/streamStore.ts +68 -0
  106. flock/frontend/src/store/uiStore.test.ts +54 -0
  107. flock/frontend/src/store/uiStore.ts +110 -0
  108. flock/frontend/src/store/wsStore.ts +34 -0
  109. flock/frontend/src/styles/index.css +15 -0
  110. flock/frontend/src/styles/scrollbar.css +47 -0
  111. flock/frontend/src/styles/variables.css +488 -0
  112. flock/frontend/src/test/setup.ts +1 -0
  113. flock/frontend/src/types/filters.ts +14 -0
  114. flock/frontend/src/types/graph.ts +55 -0
  115. flock/frontend/src/types/modules.ts +7 -0
  116. flock/frontend/src/types/theme.ts +55 -0
  117. flock/frontend/src/utils/mockData.ts +85 -0
  118. flock/frontend/src/utils/performance.ts +16 -0
  119. flock/frontend/src/utils/transforms.test.ts +860 -0
  120. flock/frontend/src/utils/transforms.ts +323 -0
  121. flock/frontend/src/vite-env.d.ts +17 -0
  122. flock/frontend/tsconfig.json +27 -0
  123. flock/frontend/tsconfig.node.json +11 -0
  124. flock/frontend/vite.config.ts +25 -0
  125. flock/frontend/vitest.config.ts +11 -0
  126. flock/{core/util → helper}/cli_helper.py +4 -3
  127. flock/{core/logging → logging}/__init__.py +2 -3
  128. flock/{core/logging → logging}/formatters/enum_builder.py +3 -4
  129. flock/{core/logging → logging}/formatters/theme_builder.py +19 -44
  130. flock/{core/logging → logging}/formatters/themed_formatter.py +69 -115
  131. flock/{core/logging → logging}/logging.py +77 -61
  132. flock/{core/logging → logging}/telemetry.py +20 -26
  133. flock/{core/logging → logging}/telemetry_exporter/base_exporter.py +2 -2
  134. flock/{core/logging → logging}/telemetry_exporter/file_exporter.py +6 -9
  135. flock/{core/logging → logging}/telemetry_exporter/sqlite_exporter.py +2 -3
  136. flock/{core/logging → logging}/trace_and_logged.py +20 -24
  137. flock/mcp/__init__.py +91 -0
  138. flock/{core/mcp/mcp_client.py → mcp/client.py} +103 -154
  139. flock/{core/mcp/mcp_config.py → mcp/config.py} +62 -117
  140. flock/mcp/manager.py +255 -0
  141. flock/mcp/servers/sse/__init__.py +1 -1
  142. flock/mcp/servers/sse/flock_sse_server.py +11 -53
  143. flock/mcp/servers/stdio/__init__.py +1 -1
  144. flock/mcp/servers/stdio/flock_stdio_server.py +8 -48
  145. flock/mcp/servers/streamable_http/flock_streamable_http_server.py +17 -62
  146. flock/mcp/servers/websockets/flock_websocket_server.py +7 -40
  147. flock/{core/mcp/flock_mcp_tool.py → mcp/tool.py} +16 -26
  148. flock/mcp/types/__init__.py +42 -0
  149. flock/{core/mcp → mcp}/types/callbacks.py +9 -15
  150. flock/{core/mcp → mcp}/types/factories.py +7 -6
  151. flock/{core/mcp → mcp}/types/handlers.py +13 -18
  152. flock/{core/mcp → mcp}/types/types.py +70 -74
  153. flock/{core/mcp → mcp}/util/helpers.py +1 -1
  154. flock/orchestrator.py +645 -0
  155. flock/registry.py +148 -0
  156. flock/runtime.py +262 -0
  157. flock/service.py +140 -0
  158. flock/store.py +69 -0
  159. flock/subscription.py +111 -0
  160. flock/themes/andromeda.toml +1 -1
  161. flock/themes/apple-system-colors.toml +1 -1
  162. flock/themes/arcoiris.toml +1 -1
  163. flock/themes/atomonelight.toml +1 -1
  164. flock/themes/ayu copy.toml +1 -1
  165. flock/themes/ayu-light.toml +1 -1
  166. flock/themes/belafonte-day.toml +1 -1
  167. flock/themes/belafonte-night.toml +1 -1
  168. flock/themes/blulocodark.toml +1 -1
  169. flock/themes/breeze.toml +1 -1
  170. flock/themes/broadcast.toml +1 -1
  171. flock/themes/brogrammer.toml +1 -1
  172. flock/themes/builtin-dark.toml +1 -1
  173. flock/themes/builtin-pastel-dark.toml +1 -1
  174. flock/themes/catppuccin-latte.toml +1 -1
  175. flock/themes/catppuccin-macchiato.toml +1 -1
  176. flock/themes/catppuccin-mocha.toml +1 -1
  177. flock/themes/cga.toml +1 -1
  178. flock/themes/chalk.toml +1 -1
  179. flock/themes/ciapre.toml +1 -1
  180. flock/themes/coffee-theme.toml +1 -1
  181. flock/themes/cyberpunkscarletprotocol.toml +1 -1
  182. flock/themes/dark+.toml +1 -1
  183. flock/themes/darkermatrix.toml +1 -1
  184. flock/themes/darkside.toml +1 -1
  185. flock/themes/desert.toml +1 -1
  186. flock/themes/django.toml +1 -1
  187. flock/themes/djangosmooth.toml +1 -1
  188. flock/themes/doomone.toml +1 -1
  189. flock/themes/dotgov.toml +1 -1
  190. flock/themes/dracula+.toml +1 -1
  191. flock/themes/duckbones.toml +1 -1
  192. flock/themes/encom.toml +1 -1
  193. flock/themes/espresso.toml +1 -1
  194. flock/themes/everblush.toml +1 -1
  195. flock/themes/fairyfloss.toml +1 -1
  196. flock/themes/fideloper.toml +1 -1
  197. flock/themes/fishtank.toml +1 -1
  198. flock/themes/flexoki-light.toml +1 -1
  199. flock/themes/floraverse.toml +1 -1
  200. flock/themes/framer.toml +1 -1
  201. flock/themes/galizur.toml +1 -1
  202. flock/themes/github.toml +1 -1
  203. flock/themes/grass.toml +1 -1
  204. flock/themes/grey-green.toml +1 -1
  205. flock/themes/gruvboxlight.toml +1 -1
  206. flock/themes/guezwhoz.toml +1 -1
  207. flock/themes/harper.toml +1 -1
  208. flock/themes/hax0r-blue.toml +1 -1
  209. flock/themes/hopscotch.256.toml +1 -1
  210. flock/themes/ic-green-ppl.toml +1 -1
  211. flock/themes/iceberg-dark.toml +1 -1
  212. flock/themes/japanesque.toml +1 -1
  213. flock/themes/jubi.toml +1 -1
  214. flock/themes/kibble.toml +1 -1
  215. flock/themes/kolorit.toml +1 -1
  216. flock/themes/kurokula.toml +1 -1
  217. flock/themes/materialdesigncolors.toml +1 -1
  218. flock/themes/matrix.toml +1 -1
  219. flock/themes/mellifluous.toml +1 -1
  220. flock/themes/midnight-in-mojave.toml +1 -1
  221. flock/themes/monokai-remastered.toml +1 -1
  222. flock/themes/monokai-soda.toml +1 -1
  223. flock/themes/neon.toml +1 -1
  224. flock/themes/neopolitan.toml +1 -1
  225. flock/themes/nord-light.toml +1 -1
  226. flock/themes/ocean.toml +1 -1
  227. flock/themes/onehalfdark.toml +1 -1
  228. flock/themes/onehalflight.toml +1 -1
  229. flock/themes/palenighthc.toml +1 -1
  230. flock/themes/paulmillr.toml +1 -1
  231. flock/themes/pencildark.toml +1 -1
  232. flock/themes/pnevma.toml +1 -1
  233. flock/themes/purple-rain.toml +1 -1
  234. flock/themes/purplepeter.toml +1 -1
  235. flock/themes/raycast-dark.toml +1 -1
  236. flock/themes/red-sands.toml +1 -1
  237. flock/themes/relaxed.toml +1 -1
  238. flock/themes/retro.toml +1 -1
  239. flock/themes/rose-pine.toml +1 -1
  240. flock/themes/royal.toml +1 -1
  241. flock/themes/ryuuko.toml +1 -1
  242. flock/themes/sakura.toml +1 -1
  243. flock/themes/scarlet-protocol.toml +1 -1
  244. flock/themes/seoulbones-dark.toml +1 -1
  245. flock/themes/shades-of-purple.toml +1 -1
  246. flock/themes/smyck.toml +1 -1
  247. flock/themes/softserver.toml +1 -1
  248. flock/themes/solarized-darcula.toml +1 -1
  249. flock/themes/square.toml +1 -1
  250. flock/themes/sugarplum.toml +1 -1
  251. flock/themes/thayer-bright.toml +1 -1
  252. flock/themes/tokyonight.toml +1 -1
  253. flock/themes/tomorrow.toml +1 -1
  254. flock/themes/ubuntu.toml +1 -1
  255. flock/themes/ultradark.toml +1 -1
  256. flock/themes/ultraviolent.toml +1 -1
  257. flock/themes/unikitty.toml +1 -1
  258. flock/themes/urple.toml +1 -1
  259. flock/themes/vesper.toml +1 -1
  260. flock/themes/vimbones.toml +1 -1
  261. flock/themes/wildcherry.toml +1 -1
  262. flock/themes/wilmersdorf.toml +1 -1
  263. flock/themes/wryan.toml +1 -1
  264. flock/themes/xcodedarkhc.toml +1 -1
  265. flock/themes/xcodelight.toml +1 -1
  266. flock/themes/zenbones-light.toml +1 -1
  267. flock/themes/zenwritten-dark.toml +1 -1
  268. flock/utilities.py +301 -0
  269. flock/{components/utility → utility}/output_utility_component.py +68 -53
  270. flock/visibility.py +107 -0
  271. flock_core-0.5.0b51.dist-info/METADATA +747 -0
  272. flock_core-0.5.0b51.dist-info/RECORD +508 -0
  273. flock_core-0.5.0b51.dist-info/entry_points.txt +2 -0
  274. {flock_core-0.5.0b28.dist-info → flock_core-0.5.0b51.dist-info}/licenses/LICENSE +1 -1
  275. flock/adapter/__init__.py +0 -14
  276. flock/adapter/azure_adapter.py +0 -68
  277. flock/adapter/chroma_adapter.py +0 -73
  278. flock/adapter/faiss_adapter.py +0 -97
  279. flock/adapter/pinecone_adapter.py +0 -51
  280. flock/adapter/vector_base.py +0 -47
  281. flock/cli/assets/release_notes.md +0 -140
  282. flock/cli/config.py +0 -8
  283. flock/cli/constants.py +0 -36
  284. flock/cli/create_agent.py +0 -1
  285. flock/cli/create_flock.py +0 -280
  286. flock/cli/execute_flock.py +0 -620
  287. flock/cli/load_agent.py +0 -1
  288. flock/cli/load_examples.py +0 -1
  289. flock/cli/load_flock.py +0 -192
  290. flock/cli/load_release_notes.py +0 -20
  291. flock/cli/loaded_flock_cli.py +0 -254
  292. flock/cli/manage_agents.py +0 -459
  293. flock/cli/registry_management.py +0 -889
  294. flock/cli/runner.py +0 -41
  295. flock/cli/settings.py +0 -857
  296. flock/cli/utils.py +0 -135
  297. flock/cli/view_results.py +0 -29
  298. flock/cli/yaml_editor.py +0 -396
  299. flock/components/__init__.py +0 -30
  300. flock/components/evaluation/__init__.py +0 -9
  301. flock/components/evaluation/declarative_evaluation_component.py +0 -606
  302. flock/components/routing/__init__.py +0 -15
  303. flock/components/routing/conditional_routing_component.py +0 -494
  304. flock/components/routing/default_routing_component.py +0 -103
  305. flock/components/routing/llm_routing_component.py +0 -206
  306. flock/components/utility/__init__.py +0 -22
  307. flock/components/utility/example_utility_component.py +0 -250
  308. flock/components/utility/feedback_utility_component.py +0 -206
  309. flock/components/utility/memory_utility_component.py +0 -550
  310. flock/components/utility/metrics_utility_component.py +0 -700
  311. flock/config.py +0 -61
  312. flock/core/__init__.py +0 -110
  313. flock/core/agent/__init__.py +0 -16
  314. flock/core/agent/default_agent.py +0 -216
  315. flock/core/agent/flock_agent_components.py +0 -104
  316. flock/core/agent/flock_agent_execution.py +0 -101
  317. flock/core/agent/flock_agent_integration.py +0 -260
  318. flock/core/agent/flock_agent_lifecycle.py +0 -186
  319. flock/core/agent/flock_agent_serialization.py +0 -381
  320. flock/core/api/__init__.py +0 -10
  321. flock/core/api/custom_endpoint.py +0 -45
  322. flock/core/api/endpoints.py +0 -254
  323. flock/core/api/main.py +0 -162
  324. flock/core/api/models.py +0 -97
  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/component/__init__.py +0 -15
  329. flock/core/component/agent_component_base.py +0 -309
  330. flock/core/component/evaluation_component.py +0 -62
  331. flock/core/component/routing_component.py +0 -74
  332. flock/core/component/utility_component.py +0 -69
  333. flock/core/config/flock_agent_config.py +0 -58
  334. flock/core/config/scheduled_agent_config.py +0 -40
  335. flock/core/context/context.py +0 -213
  336. flock/core/context/context_manager.py +0 -37
  337. flock/core/context/context_vars.py +0 -10
  338. flock/core/evaluation/utils.py +0 -396
  339. flock/core/execution/batch_executor.py +0 -369
  340. flock/core/execution/evaluation_executor.py +0 -438
  341. flock/core/execution/local_executor.py +0 -31
  342. flock/core/execution/opik_executor.py +0 -103
  343. flock/core/execution/temporal_executor.py +0 -164
  344. flock/core/flock.py +0 -634
  345. flock/core/flock_agent.py +0 -336
  346. flock/core/flock_factory.py +0 -613
  347. flock/core/flock_scheduler.py +0 -166
  348. flock/core/flock_server_manager.py +0 -136
  349. flock/core/interpreter/python_interpreter.py +0 -689
  350. flock/core/mcp/__init__.py +0 -1
  351. flock/core/mcp/flock_mcp_server.py +0 -680
  352. flock/core/mcp/mcp_client_manager.py +0 -201
  353. flock/core/mcp/types/__init__.py +0 -1
  354. flock/core/mixin/dspy_integration.py +0 -403
  355. flock/core/mixin/prompt_parser.py +0 -125
  356. flock/core/orchestration/__init__.py +0 -15
  357. flock/core/orchestration/flock_batch_processor.py +0 -94
  358. flock/core/orchestration/flock_evaluator.py +0 -113
  359. flock/core/orchestration/flock_execution.py +0 -295
  360. flock/core/orchestration/flock_initialization.py +0 -149
  361. flock/core/orchestration/flock_server_manager.py +0 -67
  362. flock/core/orchestration/flock_web_server.py +0 -117
  363. flock/core/registry/__init__.py +0 -45
  364. flock/core/registry/agent_registry.py +0 -69
  365. flock/core/registry/callable_registry.py +0 -139
  366. flock/core/registry/component_discovery.py +0 -142
  367. flock/core/registry/component_registry.py +0 -64
  368. flock/core/registry/config_mapping.py +0 -64
  369. flock/core/registry/decorators.py +0 -137
  370. flock/core/registry/registry_hub.py +0 -205
  371. flock/core/registry/server_registry.py +0 -57
  372. flock/core/registry/type_registry.py +0 -86
  373. flock/core/serialization/__init__.py +0 -13
  374. flock/core/serialization/callable_registry.py +0 -52
  375. flock/core/serialization/flock_serializer.py +0 -832
  376. flock/core/serialization/json_encoder.py +0 -41
  377. flock/core/serialization/secure_serializer.py +0 -175
  378. flock/core/serialization/serializable.py +0 -342
  379. flock/core/serialization/serialization_utils.py +0 -412
  380. flock/core/util/file_path_utils.py +0 -223
  381. flock/core/util/hydrator.py +0 -309
  382. flock/core/util/input_resolver.py +0 -164
  383. flock/core/util/loader.py +0 -59
  384. flock/core/util/splitter.py +0 -219
  385. flock/di.py +0 -27
  386. flock/platform/docker_tools.py +0 -49
  387. flock/platform/jaeger_install.py +0 -86
  388. flock/webapp/__init__.py +0 -1
  389. flock/webapp/app/__init__.py +0 -0
  390. flock/webapp/app/api/__init__.py +0 -0
  391. flock/webapp/app/api/agent_management.py +0 -241
  392. flock/webapp/app/api/execution.py +0 -709
  393. flock/webapp/app/api/flock_management.py +0 -129
  394. flock/webapp/app/api/registry_viewer.py +0 -30
  395. flock/webapp/app/chat.py +0 -665
  396. flock/webapp/app/config.py +0 -104
  397. flock/webapp/app/dependencies.py +0 -117
  398. flock/webapp/app/main.py +0 -1070
  399. flock/webapp/app/middleware.py +0 -113
  400. flock/webapp/app/models_ui.py +0 -7
  401. flock/webapp/app/services/__init__.py +0 -0
  402. flock/webapp/app/services/feedback_file_service.py +0 -363
  403. flock/webapp/app/services/flock_service.py +0 -337
  404. flock/webapp/app/services/sharing_models.py +0 -81
  405. flock/webapp/app/services/sharing_store.py +0 -762
  406. flock/webapp/app/templates/theme_mapper.html +0 -326
  407. flock/webapp/app/theme_mapper.py +0 -812
  408. flock/webapp/app/utils.py +0 -85
  409. flock/webapp/run.py +0 -215
  410. flock/webapp/static/css/chat.css +0 -301
  411. flock/webapp/static/css/components.css +0 -167
  412. flock/webapp/static/css/header.css +0 -39
  413. flock/webapp/static/css/layout.css +0 -46
  414. flock/webapp/static/css/sidebar.css +0 -127
  415. flock/webapp/static/css/two-pane.css +0 -48
  416. flock/webapp/templates/base.html +0 -200
  417. flock/webapp/templates/chat.html +0 -152
  418. flock/webapp/templates/chat_settings.html +0 -19
  419. flock/webapp/templates/flock_editor.html +0 -16
  420. flock/webapp/templates/index.html +0 -12
  421. flock/webapp/templates/partials/_agent_detail_form.html +0 -93
  422. flock/webapp/templates/partials/_agent_list.html +0 -18
  423. flock/webapp/templates/partials/_agent_manager_view.html +0 -51
  424. flock/webapp/templates/partials/_agent_tools_checklist.html +0 -14
  425. flock/webapp/templates/partials/_chat_container.html +0 -15
  426. flock/webapp/templates/partials/_chat_messages.html +0 -57
  427. flock/webapp/templates/partials/_chat_settings_form.html +0 -85
  428. flock/webapp/templates/partials/_create_flock_form.html +0 -50
  429. flock/webapp/templates/partials/_dashboard_flock_detail.html +0 -17
  430. flock/webapp/templates/partials/_dashboard_flock_file_list.html +0 -16
  431. flock/webapp/templates/partials/_dashboard_flock_properties_preview.html +0 -28
  432. flock/webapp/templates/partials/_dashboard_upload_flock_form.html +0 -16
  433. flock/webapp/templates/partials/_dynamic_input_form_content.html +0 -22
  434. flock/webapp/templates/partials/_env_vars_table.html +0 -23
  435. flock/webapp/templates/partials/_execution_form.html +0 -118
  436. flock/webapp/templates/partials/_execution_view_container.html +0 -28
  437. flock/webapp/templates/partials/_flock_file_list.html +0 -23
  438. flock/webapp/templates/partials/_flock_properties_form.html +0 -52
  439. flock/webapp/templates/partials/_flock_upload_form.html +0 -16
  440. flock/webapp/templates/partials/_header_flock_status.html +0 -5
  441. flock/webapp/templates/partials/_load_manager_view.html +0 -49
  442. flock/webapp/templates/partials/_registry_table.html +0 -25
  443. flock/webapp/templates/partials/_registry_viewer_content.html +0 -70
  444. flock/webapp/templates/partials/_results_display.html +0 -78
  445. flock/webapp/templates/partials/_settings_env_content.html +0 -9
  446. flock/webapp/templates/partials/_settings_theme_content.html +0 -14
  447. flock/webapp/templates/partials/_settings_view.html +0 -36
  448. flock/webapp/templates/partials/_share_chat_link_snippet.html +0 -11
  449. flock/webapp/templates/partials/_share_link_snippet.html +0 -35
  450. flock/webapp/templates/partials/_sidebar.html +0 -74
  451. flock/webapp/templates/partials/_streaming_results_container.html +0 -195
  452. flock/webapp/templates/partials/_structured_data_view.html +0 -40
  453. flock/webapp/templates/partials/_theme_preview.html +0 -36
  454. flock/webapp/templates/registry_viewer.html +0 -84
  455. flock/webapp/templates/shared_run_page.html +0 -140
  456. flock/workflow/__init__.py +0 -0
  457. flock/workflow/activities.py +0 -196
  458. flock/workflow/agent_activities.py +0 -24
  459. flock/workflow/agent_execution_activity.py +0 -202
  460. flock/workflow/flock_workflow.py +0 -214
  461. flock/workflow/temporal_config.py +0 -96
  462. flock/workflow/temporal_setup.py +0 -68
  463. flock_core-0.5.0b28.dist-info/METADATA +0 -274
  464. flock_core-0.5.0b28.dist-info/RECORD +0 -561
  465. flock_core-0.5.0b28.dist-info/entry_points.txt +0 -2
  466. /flock/{core/logging → logging}/formatters/themes.py +0 -0
  467. /flock/{core/logging → logging}/span_middleware/baggage_span_processor.py +0 -0
  468. /flock/{core/mcp → mcp}/util/__init__.py +0 -0
  469. {flock_core-0.5.0b28.dist-info → flock_core-0.5.0b51.dist-info}/WHEEL +0 -0
@@ -1,832 +0,0 @@
1
- # src/flock/core/serialization/flock_serializer.py
2
- """Handles serialization and deserialization logic for Flock instances."""
3
-
4
- import importlib
5
- import importlib.util
6
- import inspect
7
- import os
8
- import re
9
- import sys
10
- from dataclasses import is_dataclass
11
- from typing import TYPE_CHECKING, Any, Literal
12
-
13
- from pydantic import BaseModel, create_model
14
-
15
- from flock.core.logging.logging import get_logger
16
-
17
- # Need registry access
18
- from flock.core.registry import get_registry
19
- from flock.core.serialization.serialization_utils import (
20
- # Assuming this handles basic serialization needs
21
- extract_pydantic_models_from_type_string,
22
- )
23
-
24
- if TYPE_CHECKING:
25
- from flock.core.flock import Flock
26
-
27
-
28
- logger = get_logger("serialization.flock")
29
- registry = get_registry()
30
-
31
-
32
- class FlockSerializer:
33
- """Provides static methods for serializing and deserializing Flock instances."""
34
-
35
- @staticmethod
36
- def serialize(
37
- flock_instance: "Flock",
38
- path_type: Literal["absolute", "relative"] = "relative",
39
- ) -> dict[str, Any]:
40
- """Convert Flock instance to dictionary representation.
41
-
42
- Args:
43
- flock_instance: The Flock instance to serialize.
44
- path_type: How file paths should be formatted ('absolute' or 'relative').
45
- """
46
- logger.debug(
47
- f"Serializing Flock instance '{flock_instance.name}' to dict."
48
- )
49
- # Use Pydantic's dump for base fields defined in Flock's model
50
- data = flock_instance.model_dump(mode="json", exclude_none=True)
51
- logger.info(
52
- f"Serializing Flock '{flock_instance.name}' with {len(flock_instance._agents)} agents"
53
- )
54
-
55
- data["agents"] = {}
56
- data["mcp_servers"] = {}
57
- custom_types = {}
58
- components = {}
59
-
60
- for name, server_instance in flock_instance._servers.items():
61
- try:
62
- # Servers handle their own serialization via their to_dict method
63
- server_data = server_instance.to_dict(path_type=path_type)
64
- data["mcp_servers"][name] = server_data
65
-
66
- # --- Extract Component Information ---
67
-
68
- # Modules
69
- if "modules" in server_data:
70
- for module_name, module_data in server_data[
71
- "modules"
72
- ].items():
73
- if module_data and "type" in module_data:
74
- component_type = module_data["type"]
75
- if component_type not in components:
76
- logger.debug(
77
- f"Adding module component '{component_type}' from module '{module_name}' in server '{name}'"
78
- )
79
- components[component_type] = (
80
- FlockSerializer._get_component_definition(
81
- component_type, path_type
82
- )
83
- )
84
- except Exception as e:
85
- logger.error(
86
- f"Failed to serialize server '{name}' within Flock: {e}",
87
- exc_info=True,
88
- )
89
-
90
- for name, agent_instance in flock_instance._agents.items():
91
- try:
92
- logger.debug(f"Serializing agent '{name}'")
93
- # Agents handle their own serialization via their to_dict
94
- agent_data = (
95
- agent_instance.to_dict()
96
- ) # This now uses the agent's refined to_dict
97
- data["agents"][name] = agent_data
98
-
99
- # --- Extract Types from Agent Signatures ---
100
- input_types = []
101
- if agent_instance.input:
102
- input_types = FlockSerializer._extract_types_from_signature(
103
- agent_instance.input
104
- )
105
- if input_types:
106
- logger.debug(
107
- f"Found input types in agent '{name}': {input_types}"
108
- )
109
-
110
- output_types = []
111
- if agent_instance.output:
112
- output_types = (
113
- FlockSerializer._extract_types_from_signature(
114
- agent_instance.output
115
- )
116
- )
117
- if output_types:
118
- logger.debug(
119
- f"Found output types in agent '{name}': {output_types}"
120
- )
121
-
122
- all_types = set(input_types + output_types)
123
- if all_types:
124
- custom_types.update(
125
- FlockSerializer._get_type_definitions(list(all_types))
126
- )
127
-
128
- # --- Extract Component Information ---
129
- # Evaluator
130
- if (
131
- "evaluator" in agent_data
132
- and agent_data["evaluator"]
133
- and "type" in agent_data["evaluator"]
134
- ):
135
- component_type = agent_data["evaluator"]["type"]
136
- if component_type not in components:
137
- logger.debug(
138
- f"Adding evaluator component '{component_type}' from agent '{name}'"
139
- )
140
- components[component_type] = (
141
- FlockSerializer._get_component_definition(
142
- component_type, path_type
143
- )
144
- )
145
-
146
- # Modules
147
- if "modules" in agent_data:
148
- for module_name, module_data in agent_data[
149
- "modules"
150
- ].items():
151
- if module_data and "type" in module_data:
152
- component_type = module_data["type"]
153
- if component_type not in components:
154
- logger.debug(
155
- f"Adding module component '{component_type}' from module '{module_name}' in agent '{name}'"
156
- )
157
- components[component_type] = (
158
- FlockSerializer._get_component_definition(
159
- component_type, path_type
160
- )
161
- )
162
-
163
- # Router
164
- if (
165
- "handoff_router" in agent_data
166
- and agent_data["handoff_router"]
167
- and "type" in agent_data["handoff_router"]
168
- ):
169
- component_type = agent_data["handoff_router"]["type"]
170
- if component_type not in components:
171
- logger.debug(
172
- f"Adding router component '{component_type}' from agent '{name}'"
173
- )
174
- components[component_type] = (
175
- FlockSerializer._get_component_definition(
176
- component_type, path_type
177
- )
178
- )
179
-
180
- # Description (Callables)
181
- if agent_data.get("description_callable"):
182
- logger.debug(
183
- f"Adding description callable '{agent_data['description_callable']}' from agent '{name}'"
184
- )
185
- description_callable_name = agent_data[
186
- "description_callable"
187
- ]
188
- description_callable = agent_instance.description
189
- path_str = registry.get_callable_path_string(
190
- description_callable
191
- )
192
- if path_str:
193
- logger.debug(
194
- f"Adding description callable '{description_callable_name}' (from path '{path_str}') to components"
195
- )
196
- components[description_callable_name] = (
197
- FlockSerializer._get_callable_definition(
198
- path_str, description_callable_name, path_type
199
- )
200
- )
201
-
202
- if agent_data.get("input_callable"):
203
- logger.debug(
204
- f"Adding input callable '{agent_data['input_callable']}' from agent '{name}'"
205
- )
206
- input_callable_name = agent_data["input_callable"]
207
- input_callable = agent_instance.input
208
- path_str = registry.get_callable_path_string(
209
- input_callable
210
- )
211
- if path_str:
212
- logger.debug(
213
- f"Adding input callable '{input_callable_name}' (from path '{path_str}') to components"
214
- )
215
- components[input_callable_name] = (
216
- FlockSerializer._get_callable_definition(
217
- path_str, input_callable_name, path_type
218
- )
219
- )
220
-
221
- if agent_data.get("output_callable"):
222
- logger.debug(
223
- f"Adding output callable '{agent_data['output_callable']}' from agent '{name}'"
224
- )
225
- output_callable_name = agent_data["output_callable"]
226
- output_callable = agent_instance.output
227
- path_str = registry.get_callable_path_string(
228
- output_callable
229
- )
230
- if path_str:
231
- logger.debug(
232
- f"Adding output callable '{output_callable_name}' (from path '{path_str}') to components"
233
- )
234
- components[output_callable_name] = (
235
- FlockSerializer._get_callable_definition(
236
- path_str, output_callable_name, path_type
237
- )
238
- )
239
-
240
- # Tools (Callables)
241
- if agent_data.get("tools"):
242
- logger.debug(
243
- f"Extracting tool information from agent '{name}': {agent_data['tools']}"
244
- )
245
- tool_objs = (
246
- agent_instance.tools if agent_instance.tools else []
247
- )
248
- for i, tool_name in enumerate(agent_data["tools"]):
249
- if tool_name not in components and i < len(tool_objs):
250
- tool = tool_objs[i]
251
- if callable(tool) and not isinstance(tool, type):
252
- path_str = (
253
- registry.get_callable_path_string(tool)
254
- )
255
- if path_str:
256
- logger.debug(
257
- f"Adding tool '{tool_name}' (from path '{path_str}') to components"
258
- )
259
- components[tool_name] = (
260
- FlockSerializer._get_callable_definition(
261
- path_str, tool_name, path_type
262
- )
263
- )
264
-
265
- except Exception as e:
266
- logger.error(
267
- f"Failed to serialize agent '{name}' within Flock: {e}",
268
- exc_info=True,
269
- )
270
-
271
- if custom_types:
272
- logger.info(f"Adding {len(custom_types)} custom type definitions")
273
- data["types"] = custom_types
274
- if components:
275
- logger.info(
276
- f"Adding {len(components)} component/callable definitions"
277
- )
278
- data["components"] = components
279
-
280
- data["dependencies"] = FlockSerializer._get_dependencies()
281
- data["metadata"] = {
282
- "path_type": path_type,
283
- "flock_version": "0.4.0",
284
- } # Example version
285
-
286
- logger.debug(f"Flock '{flock_instance.name}' serialization complete.")
287
- return data
288
-
289
- @staticmethod
290
- def deserialize(cls: type["Flock"], data: dict[str, Any]) -> "Flock":
291
- """Create Flock instance from dictionary representation."""
292
- # Import concrete types needed for instantiation
293
- from flock.core.flock import Flock # Import the actual class
294
- from flock.core.flock_agent import FlockAgent as ConcreteFlockAgent
295
- from flock.core.mcp.flock_mcp_server import (
296
- FlockMCPServer as ConcreteFlockMCPServer,
297
- )
298
-
299
- logger.debug(
300
- f"Deserializing Flock from dict. Provided keys: {list(data.keys())}"
301
- )
302
-
303
- metadata = data.pop("metadata", {})
304
- path_type = metadata.get(
305
- "path_type", "relative"
306
- ) # Default to relative for loading flexibility
307
- logger.debug(
308
- f"Using path_type '{path_type}' from metadata for component loading"
309
- )
310
-
311
- if "types" in data:
312
- logger.info(f"Processing {len(data['types'])} type definitions")
313
- FlockSerializer._register_type_definitions(data.pop("types"))
314
-
315
- if "components" in data:
316
- logger.info(
317
- f"Processing {len(data['components'])} component/callable definitions"
318
- )
319
- FlockSerializer._register_component_definitions(
320
- data.pop("components"), path_type
321
- )
322
-
323
- if "dependencies" in data:
324
- logger.debug(f"Checking {len(data['dependencies'])} dependencies")
325
- FlockSerializer._check_dependencies(data.pop("dependencies"))
326
-
327
- agents_data = data.pop("agents", {})
328
- server_data = data.pop("mcp_servers", {})
329
- logger.info(f"Found {len(server_data)} servers to deserialize")
330
- logger.info(f"Found {len(agents_data)} agents to deserialize")
331
-
332
- try:
333
- # Pass only fields defined in Flock's Pydantic model to constructor
334
- init_data = {
335
- k: v for k, v in data.items() if k in Flock.model_fields
336
- }
337
- logger.debug(
338
- f"Creating Flock instance with fields: {list(init_data.keys())}"
339
- )
340
- flock_instance = cls(**init_data) # Use cls which is Flock
341
- except Exception as e:
342
- logger.error(
343
- f"Pydantic validation/init failed for Flock: {e}", exc_info=True
344
- )
345
- raise ValueError(
346
- f"Failed to initialize Flock from dict: {e}"
347
- ) from e
348
-
349
- # Deserialize and add server AFTER Flock instance exists and BEFORE Agents have been added
350
- for name, server_data in server_data.items():
351
- try:
352
- logger.debug(f"Deserializing server '{name}'")
353
- server_data.setdefault("name", name)
354
- server_instance = ConcreteFlockMCPServer.from_dict(server_data)
355
- flock_instance.add_server(server_instance)
356
- logger.debug(f"Successfully added server '{name}' to Flock")
357
- except Exception as e:
358
- logger.error(
359
- f"Failed to deserialize/add server '{name}': {e}",
360
- exc_info=True,
361
- )
362
-
363
- # Deserialize and add agents AFTER Flock instance exists
364
- for name, agent_data in agents_data.items():
365
- try:
366
- logger.debug(f"Deserializing agent '{name}'")
367
- agent_data.setdefault("name", name)
368
- agent_instance = ConcreteFlockAgent.from_dict(agent_data)
369
- flock_instance.add_agent(agent_instance)
370
- logger.debug(f"Successfully added agent '{name}' to Flock")
371
- except Exception as e:
372
- logger.error(
373
- f"Failed to deserialize/add agent '{name}': {e}",
374
- exc_info=True,
375
- )
376
-
377
- logger.info(
378
- f"Successfully deserialized Flock '{flock_instance.name}' with {len(flock_instance._agents)} agents"
379
- )
380
- return flock_instance
381
-
382
- # --- Helper methods moved from Flock ---
383
- # (Keep all the _extract..., _get..., _register..., _create... methods here)
384
- # Ensure they use FlockSerializer._... or are standalone functions called directly.
385
- # Make static if they don't need instance state (which they shouldn't here).
386
-
387
- @staticmethod
388
- def _extract_types_from_signature(signature: str) -> list[str]:
389
- """Extract type names from an input/output signature string."""
390
- if not signature:
391
- return []
392
- from flock.core.util.input_resolver import (
393
- split_top_level, # Import locally if needed
394
- )
395
-
396
- type_names = set()
397
- try:
398
- parts = split_top_level(signature)
399
- for part in parts:
400
- if ":" in part:
401
- type_str = part.split(":", 1)[1].split("|", 1)[0].strip()
402
- # Use the more robust extractor
403
- models = extract_pydantic_models_from_type_string(type_str)
404
- for model in models:
405
- type_names.add(model.__name__)
406
- except Exception as e:
407
- logger.warning(
408
- f"Could not fully parse types from signature '{signature}': {e}"
409
- )
410
- return list(type_names)
411
-
412
- @staticmethod
413
- def _get_type_definitions(type_names: list[str]) -> dict[str, Any]:
414
- """Get definitions for the specified custom types from the registry."""
415
- type_definitions = {}
416
- for type_name in type_names:
417
- try:
418
- type_obj = registry.get_type(
419
- type_name
420
- ) # Throws KeyError if not found
421
- type_def = FlockSerializer._extract_type_definition(
422
- type_name, type_obj
423
- )
424
- if type_def:
425
- type_definitions[type_name] = type_def
426
- except KeyError:
427
- logger.warning(
428
- f"Type '{type_name}' requested but not found in registry."
429
- )
430
- except Exception as e:
431
- logger.warning(
432
- f"Could not extract definition for type {type_name}: {e}"
433
- )
434
- return type_definitions
435
-
436
- @staticmethod
437
- def _extract_type_definition(
438
- type_name: str, type_obj: type
439
- ) -> dict[str, Any] | None:
440
- """Extract a definition for a custom type (Pydantic or Dataclass)."""
441
- # Definition includes module path and schema/fields
442
- module_path = getattr(type_obj, "__module__", "unknown")
443
- type_def = {"module_path": module_path}
444
- try:
445
- if issubclass(type_obj, BaseModel):
446
- type_def["type"] = "pydantic.BaseModel"
447
- schema = type_obj.model_json_schema()
448
- if "title" in schema and schema["title"] == type_name:
449
- del schema["title"]
450
- type_def["schema"] = schema
451
- return type_def
452
- elif is_dataclass(type_obj):
453
- type_def["type"] = "dataclass"
454
- fields = {}
455
- for field_name, field in getattr(
456
- type_obj, "__dataclass_fields__", {}
457
- ).items():
458
- # Attempt to get a string representation of the type
459
- try:
460
- type_repr = str(field.type)
461
- except Exception:
462
- type_repr = "unknown"
463
- fields[field_name] = {
464
- "type": type_repr,
465
- "default": str(field.default)
466
- if field.default is not inspect.Parameter.empty
467
- else None,
468
- }
469
- type_def["fields"] = fields
470
- return type_def
471
- else:
472
- logger.debug(
473
- f"Type '{type_name}' is not Pydantic or Dataclass, skipping detailed definition."
474
- )
475
- return (
476
- None # Don't include non-data types in the 'types' section
477
- )
478
- except Exception as e:
479
- logger.warning(f"Error extracting definition for {type_name}: {e}")
480
- return None
481
-
482
- @staticmethod
483
- def _get_component_definition(
484
- component_type_name: str, path_type: Literal["absolute", "relative"]
485
- ) -> dict[str, Any]:
486
- """Get definition for a component type from the registry."""
487
- component_def = {
488
- "type": "flock_component",
489
- "module_path": "unknown",
490
- "file_path": None,
491
- }
492
- try:
493
- component_class = registry.get_component(
494
- component_type_name
495
- ) # Raises KeyError if not found
496
- component_def["module_path"] = getattr(
497
- component_class, "__module__", "unknown"
498
- )
499
- component_def["description"] = (
500
- inspect.getdoc(component_class)
501
- or f"{component_type_name} component"
502
- )
503
-
504
- # Get file path
505
- try:
506
- file_path_abs = inspect.getfile(component_class)
507
- component_def["file_path"] = (
508
- os.path.relpath(file_path_abs)
509
- if path_type == "relative"
510
- else file_path_abs
511
- )
512
- except (TypeError, ValueError) as e:
513
- logger.debug(
514
- f"Could not determine file path for component {component_type_name}: {e}"
515
- )
516
-
517
- except KeyError:
518
- logger.warning(
519
- f"Component class '{component_type_name}' not found in registry."
520
- )
521
- component_def["description"] = (
522
- f"{component_type_name} component (class not found in registry)"
523
- )
524
- except Exception as e:
525
- logger.warning(
526
- f"Could not extract full definition for component {component_type_name}: {e}"
527
- )
528
- return component_def
529
-
530
- @staticmethod
531
- def _get_callable_definition(
532
- callable_path: str,
533
- func_name: str,
534
- path_type: Literal["absolute", "relative"],
535
- ) -> dict[str, Any]:
536
- """Get definition for a callable using its registry path."""
537
- callable_def = {
538
- "type": "flock_callable",
539
- "module_path": "unknown",
540
- "file_path": None,
541
- }
542
- try:
543
- func = registry.get_callable(
544
- callable_path
545
- ) # Raises KeyError if not found
546
- callable_def["module_path"] = getattr(func, "__module__", "unknown")
547
- callable_def["description"] = (
548
- inspect.getdoc(func) or f"Callable function {func_name}"
549
- )
550
- # Get file path
551
- try:
552
- file_path_abs = inspect.getfile(func)
553
- callable_def["file_path"] = (
554
- os.path.relpath(file_path_abs)
555
- if path_type == "relative"
556
- else file_path_abs
557
- )
558
- except (TypeError, ValueError) as e:
559
- logger.debug(
560
- f"Could not determine file path for callable {callable_path}: {e}"
561
- )
562
-
563
- except KeyError:
564
- logger.warning(
565
- f"Callable '{callable_path}' (for tool '{func_name}') not found in registry."
566
- )
567
- callable_def["description"] = (
568
- f"Callable {func_name} (function not found in registry)"
569
- )
570
- except Exception as e:
571
- logger.warning(
572
- f"Could not extract full definition for callable {callable_path}: {e}"
573
- )
574
- return callable_def
575
-
576
- @staticmethod
577
- def _get_dependencies() -> list[str]:
578
- """Get list of core dependencies required by Flock."""
579
- # Basic static list for now
580
- return [
581
- "pydantic>=2.0.0",
582
- "flock-core>=0.4.0",
583
- ] # Update version as needed
584
-
585
- @staticmethod
586
- def _register_type_definitions(type_defs: dict[str, Any]) -> None:
587
- """Register type definitions from serialized data."""
588
- # (Logic remains largely the same as original, ensure it uses FlockRegistry)
589
- for type_name, type_def in type_defs.items():
590
- logger.debug(f"Registering type definition for: {type_name}")
591
- # Prioritize direct import
592
- module_path = type_def.get("module_path")
593
- registered = False
594
- if module_path and module_path != "unknown":
595
- try:
596
- module = importlib.import_module(module_path)
597
- if hasattr(module, type_name):
598
- type_obj = getattr(module, type_name)
599
- registry.register_type(type_obj, type_name)
600
- logger.info(
601
- f"Registered type '{type_name}' from module '{module_path}'"
602
- )
603
- registered = True
604
- except ImportError:
605
- logger.debug(
606
- f"Could not import module {module_path} for type {type_name}"
607
- )
608
- except Exception as e:
609
- logger.warning(
610
- f"Error registering type {type_name} from module: {e}"
611
- )
612
-
613
- if registered:
614
- continue
615
-
616
- # Attempt dynamic creation if direct import failed or wasn't possible
617
- type_kind = type_def.get("type")
618
- if type_kind == "pydantic.BaseModel" and "schema" in type_def:
619
- FlockSerializer._create_pydantic_model(type_name, type_def)
620
- elif type_kind == "dataclass" and "fields" in type_def:
621
- FlockSerializer._create_dataclass(type_name, type_def)
622
- else:
623
- logger.warning(
624
- f"Cannot dynamically register type '{type_name}' with kind '{type_kind}'"
625
- )
626
-
627
- @staticmethod
628
- def _create_pydantic_model(
629
- type_name: str, type_def: dict[str, Any]
630
- ) -> None:
631
- """Dynamically create and register a Pydantic model from schema."""
632
- # (Logic remains the same, ensure it uses registry.register_type)
633
- schema = type_def.get("schema", {})
634
- try:
635
- fields = {}
636
- properties = schema.get("properties", {})
637
- required = schema.get("required", [])
638
- for field_name, field_schema in properties.items():
639
- field_type = FlockSerializer._get_type_from_schema(field_schema)
640
- default = ... if field_name in required else None
641
- fields[field_name] = (field_type, default)
642
-
643
- DynamicModel = create_model(type_name, **fields)
644
- registry.register_type(DynamicModel, type_name)
645
- logger.info(
646
- f"Dynamically created and registered Pydantic model: {type_name}"
647
- )
648
- except Exception as e:
649
- logger.error(f"Failed to create Pydantic model {type_name}: {e}")
650
-
651
- @staticmethod
652
- def _get_type_from_schema(field_schema: dict[str, Any]) -> Any:
653
- """Convert JSON schema type to Python type."""
654
- # (Logic remains the same)
655
- schema_type = field_schema.get("type")
656
- type_mapping = {
657
- "string": str,
658
- "integer": int,
659
- "number": float,
660
- "boolean": bool,
661
- "array": list,
662
- "object": dict,
663
- }
664
- if schema_type in type_mapping:
665
- return type_mapping[schema_type]
666
- if "enum" in field_schema:
667
- from typing import Literal
668
-
669
- return Literal[tuple(field_schema["enum"])] # type: ignore
670
- return Any
671
-
672
- @staticmethod
673
- def _create_dataclass(type_name: str, type_def: dict[str, Any]) -> None:
674
- """Dynamically create and register a dataclass."""
675
- # (Logic remains the same, ensure it uses registry.register_type)
676
- from dataclasses import make_dataclass
677
-
678
- fields_def = type_def.get("fields", {})
679
- try:
680
- fields = []
681
- for field_name, field_props in fields_def.items():
682
- # Safely map type strings to actual types
683
- field_type_str = field_props.get("type", "str")
684
- type_mapping = {
685
- "str": str,
686
- "int": int,
687
- "float": float,
688
- "bool": bool,
689
- "list": list,
690
- "dict": dict,
691
- "List": list,
692
- "Dict": dict,
693
- "Any": Any,
694
- }
695
- field_type = type_mapping.get(field_type_str, Any)
696
- fields.append((field_name, field_type))
697
-
698
- DynamicDataclass = make_dataclass(type_name, fields)
699
- registry.register_type(DynamicDataclass, type_name)
700
- logger.info(
701
- f"Dynamically created and registered dataclass: {type_name}"
702
- )
703
- except Exception as e:
704
- logger.error(f"Failed to create dataclass {type_name}: {e}")
705
-
706
- @staticmethod
707
- def _register_component_definitions(
708
- component_defs: dict[str, Any],
709
- path_type: Literal["absolute", "relative"],
710
- ) -> None:
711
- """Register component/callable definitions from serialized data."""
712
- # (Logic remains the same, ensure it uses registry.register_component/register_callable)
713
- # Key change: Ensure file_path is handled correctly based on path_type from metadata
714
- for name, comp_def in component_defs.items():
715
- logger.debug(
716
- f"Registering component/callable definition for: {name}"
717
- )
718
- kind = comp_def.get("type")
719
- module_path = comp_def.get("module_path")
720
- file_path = comp_def.get("file_path")
721
- registered = False
722
-
723
- # Resolve file path if relative
724
- if (
725
- path_type == "relative"
726
- and file_path
727
- and not os.path.isabs(file_path)
728
- ):
729
- abs_file_path = os.path.abspath(file_path)
730
- logger.debug(
731
- f"Resolved relative path '{file_path}' to absolute '{abs_file_path}'"
732
- )
733
- file_path = abs_file_path # Use absolute path for loading
734
-
735
- # 1. Try importing from module_path
736
- if module_path and module_path != "unknown":
737
- try:
738
- module = importlib.import_module(module_path)
739
- if hasattr(module, name):
740
- obj = getattr(module, name)
741
- if kind == "flock_callable" and callable(obj):
742
- registry.register_callable(
743
- obj, name
744
- ) # Register by simple name
745
- # Also register by full path if possible
746
- full_path = f"{module_path}.{name}"
747
- if full_path != name:
748
- registry.register_callable(obj, full_path)
749
- logger.info(
750
- f"Registered callable '{name}' from module '{module_path}'"
751
- )
752
- registered = True
753
- elif kind == "flock_component" and isinstance(
754
- obj, type
755
- ):
756
- registry.register_component(obj, name)
757
- logger.info(
758
- f"Registered component '{name}' from module '{module_path}'"
759
- )
760
- registered = True
761
- except (ImportError, AttributeError):
762
- logger.debug(
763
- f"Could not import '{name}' from module '{module_path}', trying file path."
764
- )
765
- except Exception as e:
766
- logger.warning(
767
- f"Error registering '{name}' from module '{module_path}': {e}"
768
- )
769
-
770
- if registered:
771
- continue
772
-
773
- # 2. Try importing from file_path if module import failed or wasn't possible
774
- if file_path and os.path.exists(file_path):
775
- logger.debug(
776
- f"Attempting to load '{name}' from file: {file_path}"
777
- )
778
- try:
779
- mod_name = f"flock_dynamic_{name}" # Unique module name
780
- spec = importlib.util.spec_from_file_location(
781
- mod_name, file_path
782
- )
783
- if spec and spec.loader:
784
- module = importlib.util.module_from_spec(spec)
785
- sys.modules[spec.name] = (
786
- module # Important for pickle/cloudpickle
787
- )
788
- spec.loader.exec_module(module)
789
- if hasattr(module, name):
790
- obj = getattr(module, name)
791
- if kind == "flock_callable" and callable(obj):
792
- registry.register_callable(obj, name)
793
- logger.info(
794
- f"Registered callable '{name}' from file '{file_path}'"
795
- )
796
- elif kind == "flock_component" and isinstance(
797
- obj, type
798
- ):
799
- registry.register_component(obj, name)
800
- logger.info(
801
- f"Registered component '{name}' from file '{file_path}'"
802
- )
803
- else:
804
- logger.warning(
805
- f"'{name}' not found in loaded file '{file_path}'"
806
- )
807
- else:
808
- logger.warning(
809
- f"Could not create import spec for file '{file_path}'"
810
- )
811
- except Exception as e:
812
- logger.error(
813
- f"Error loading '{name}' from file '{file_path}': {e}",
814
- exc_info=True,
815
- )
816
- elif not registered:
817
- logger.warning(
818
- f"Could not register '{name}'. No valid module or file path found."
819
- )
820
-
821
- @staticmethod
822
- def _check_dependencies(dependencies: list[str]) -> None:
823
- """Check if required dependencies are available (basic check)."""
824
- # (Logic remains the same)
825
- for dep in dependencies:
826
- match = re.match(r"([^>=<]+)", dep)
827
- if match:
828
- pkg_name = match.group(1).replace("-", "_")
829
- try:
830
- importlib.import_module(pkg_name)
831
- except ImportError:
832
- logger.warning(f"Dependency '{dep}' might be missing.")