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,854 +0,0 @@
1
- # src/flock/core/serialization/flock_serializer.py
2
- """Handles serialization and deserialization logic for Flock instances."""
3
-
4
- import builtins
5
- import importlib
6
- import importlib.util
7
- import inspect
8
- import os
9
- import re
10
- import sys
11
- from dataclasses import is_dataclass
12
- from typing import TYPE_CHECKING, Any, Literal
13
-
14
- from pydantic import BaseModel, create_model
15
-
16
- # Need registry access
17
- from flock.core.flock_registry import get_registry
18
- from flock.core.logging.logging import get_logger
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
- FlockRegistry = 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 = FlockRegistry.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 = FlockRegistry.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 = FlockRegistry.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
- FlockRegistry.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
- production_tool_names = agent_data.get("production_tools")
266
- if production_tool_names:
267
- logger.debug(
268
- f"Extracting production tool information from agent '{name}': {production_tool_names}"
269
- )
270
- prod_tool_objs = (
271
- agent_instance.production_tools
272
- if agent_instance.production_tools
273
- else []
274
- )
275
- for i, tool_name in enumerate(production_tool_names):
276
- if tool_name not in components and i < len(prod_tool_objs):
277
- tool = prod_tool_objs[i]
278
- if callable(tool) and not isinstance(tool, type):
279
- path_str = (
280
- FlockRegistry.get_callable_path_string(tool)
281
- )
282
- if path_str:
283
- logger.debug(
284
- f"Adding production tool '{tool_name}' (from path '{path_str}') to components"
285
- )
286
- components[tool_name] = (
287
- FlockSerializer._get_callable_definition(
288
- path_str, tool_name, path_type
289
- )
290
- )
291
- except Exception as e:
292
- logger.error(
293
- f"Failed to serialize agent '{name}' within Flock: {e}",
294
- exc_info=True,
295
- )
296
-
297
- if custom_types:
298
- logger.info(f"Adding {len(custom_types)} custom type definitions")
299
- data["types"] = custom_types
300
- if components:
301
- logger.info(
302
- f"Adding {len(components)} component/callable definitions"
303
- )
304
- data["components"] = components
305
-
306
- data["dependencies"] = FlockSerializer._get_dependencies()
307
- data["metadata"] = {
308
- "path_type": path_type,
309
- "flock_version": "0.4.0",
310
- } # Example version
311
-
312
- logger.debug(f"Flock '{flock_instance.name}' serialization complete.")
313
- return data
314
-
315
- @staticmethod
316
- def deserialize(cls: type["Flock"], data: dict[str, Any]) -> "Flock":
317
- """Create Flock instance from dictionary representation."""
318
- # Import concrete types needed for instantiation
319
- from flock.core.flock import Flock # Import the actual class
320
- from flock.core.flock_agent import FlockAgent as ConcreteFlockAgent
321
- from flock.core.mcp.flock_mcp_server import (
322
- FlockMCPServerBase as ConcreteFlockMCPServer,
323
- )
324
-
325
- logger.debug(
326
- f"Deserializing Flock from dict. Provided keys: {list(data.keys())}"
327
- )
328
-
329
- metadata = data.pop("metadata", {})
330
- path_type = metadata.get(
331
- "path_type", "relative"
332
- ) # Default to relative for loading flexibility
333
- logger.debug(
334
- f"Using path_type '{path_type}' from metadata for component loading"
335
- )
336
-
337
- if "types" in data:
338
- logger.info(f"Processing {len(data['types'])} type definitions")
339
- FlockSerializer._register_type_definitions(data.pop("types"))
340
-
341
- if "components" in data:
342
- logger.info(
343
- f"Processing {len(data['components'])} component/callable definitions"
344
- )
345
- FlockSerializer._register_component_definitions(
346
- data.pop("components"), path_type
347
- )
348
-
349
- if "dependencies" in data:
350
- logger.debug(f"Checking {len(data['dependencies'])} dependencies")
351
- FlockSerializer._check_dependencies(data.pop("dependencies"))
352
-
353
- agents_data = data.pop("agents", {})
354
- server_data = data.pop("mcp_servers", {})
355
- logger.info(f"Found {len(server_data)} servers to deserialize")
356
- logger.info(f"Found {len(agents_data)} agents to deserialize")
357
-
358
- try:
359
- # Pass only fields defined in Flock's Pydantic model to constructor
360
- init_data = {
361
- k: v for k, v in data.items() if k in Flock.model_fields
362
- }
363
- logger.debug(
364
- f"Creating Flock instance with fields: {list(init_data.keys())}"
365
- )
366
- flock_instance = cls(**init_data) # Use cls which is Flock
367
- except Exception as e:
368
- logger.error(
369
- f"Pydantic validation/init failed for Flock: {e}", exc_info=True
370
- )
371
- raise ValueError(
372
- f"Failed to initialize Flock from dict: {e}"
373
- ) from e
374
-
375
- # Deserialize and add server AFTER Flock instance exists and BEFORE Agents have been added
376
- for name, server_data in server_data.items():
377
- try:
378
- logger.debug(f"Deserializing server '{name}'")
379
- server_data.setdefault("name", name)
380
- server_instance = ConcreteFlockMCPServer.from_dict(server_data)
381
- flock_instance.add_server(server_instance)
382
- logger.debug(f"Successfully added server '{name}' to Flock")
383
- except Exception as e:
384
- logger.error(
385
- f"Failed to deserialize/add server '{name}': {e}",
386
- exc_info=True,
387
- )
388
-
389
- # Deserialize and add agents AFTER Flock instance exists
390
- for name, agent_data in agents_data.items():
391
- try:
392
- logger.debug(f"Deserializing agent '{name}'")
393
- agent_data.setdefault("name", name)
394
- agent_instance = ConcreteFlockAgent.from_dict(agent_data)
395
- flock_instance.add_agent(agent_instance)
396
- logger.debug(f"Successfully added agent '{name}' to Flock")
397
- except Exception as e:
398
- logger.error(
399
- f"Failed to deserialize/add agent '{name}': {e}",
400
- exc_info=True,
401
- )
402
-
403
- logger.info(
404
- f"Successfully deserialized Flock '{flock_instance.name}' with {len(flock_instance._agents)} agents"
405
- )
406
- return flock_instance
407
-
408
- # --- Helper methods moved from Flock ---
409
- # (Keep all the _extract..., _get..., _register..., _create... methods here)
410
- # Ensure they use FlockSerializer._... or are standalone functions called directly.
411
- # Make static if they don't need instance state (which they shouldn't here).
412
-
413
- @staticmethod
414
- def _extract_types_from_signature(signature: str) -> list[str]:
415
- """Extract type names from an input/output signature string."""
416
- if not signature:
417
- return []
418
- from flock.core.util.input_resolver import (
419
- split_top_level, # Import locally if needed
420
- )
421
-
422
- type_names = set()
423
- try:
424
- parts = split_top_level(signature)
425
- for part in parts:
426
- if ":" in part:
427
- type_str = part.split(":", 1)[1].split("|", 1)[0].strip()
428
- # Use the more robust extractor
429
- models = extract_pydantic_models_from_type_string(type_str)
430
- for model in models:
431
- type_names.add(model.__name__)
432
- except Exception as e:
433
- logger.warning(
434
- f"Could not fully parse types from signature '{signature}': {e}"
435
- )
436
- return list(type_names)
437
-
438
- @staticmethod
439
- def _get_type_definitions(type_names: list[str]) -> dict[str, Any]:
440
- """Get definitions for the specified custom types from the registry."""
441
- type_definitions = {}
442
- for type_name in type_names:
443
- try:
444
- type_obj = FlockRegistry.get_type(
445
- type_name
446
- ) # Throws KeyError if not found
447
- type_def = FlockSerializer._extract_type_definition(
448
- type_name, type_obj
449
- )
450
- if type_def:
451
- type_definitions[type_name] = type_def
452
- except KeyError:
453
- logger.warning(
454
- f"Type '{type_name}' requested but not found in registry."
455
- )
456
- except Exception as e:
457
- logger.warning(
458
- f"Could not extract definition for type {type_name}: {e}"
459
- )
460
- return type_definitions
461
-
462
- @staticmethod
463
- def _extract_type_definition(
464
- type_name: str, type_obj: type
465
- ) -> dict[str, Any] | None:
466
- """Extract a definition for a custom type (Pydantic or Dataclass)."""
467
- # Definition includes module path and schema/fields
468
- module_path = getattr(type_obj, "__module__", "unknown")
469
- type_def = {"module_path": module_path}
470
- try:
471
- if issubclass(type_obj, BaseModel):
472
- type_def["type"] = "pydantic.BaseModel"
473
- schema = type_obj.model_json_schema()
474
- if "title" in schema and schema["title"] == type_name:
475
- del schema["title"]
476
- type_def["schema"] = schema
477
- return type_def
478
- elif is_dataclass(type_obj):
479
- type_def["type"] = "dataclass"
480
- fields = {}
481
- for field_name, field in getattr(
482
- type_obj, "__dataclass_fields__", {}
483
- ).items():
484
- # Attempt to get a string representation of the type
485
- try:
486
- type_repr = str(field.type)
487
- except Exception:
488
- type_repr = "unknown"
489
- fields[field_name] = {
490
- "type": type_repr,
491
- "default": str(field.default)
492
- if field.default is not inspect.Parameter.empty
493
- else None,
494
- }
495
- type_def["fields"] = fields
496
- return type_def
497
- else:
498
- logger.debug(
499
- f"Type '{type_name}' is not Pydantic or Dataclass, skipping detailed definition."
500
- )
501
- return (
502
- None # Don't include non-data types in the 'types' section
503
- )
504
- except Exception as e:
505
- logger.warning(f"Error extracting definition for {type_name}: {e}")
506
- return None
507
-
508
- @staticmethod
509
- def _get_component_definition(
510
- component_type_name: str, path_type: Literal["absolute", "relative"]
511
- ) -> dict[str, Any]:
512
- """Get definition for a component type from the registry."""
513
- component_def = {
514
- "type": "flock_component",
515
- "module_path": "unknown",
516
- "file_path": None,
517
- }
518
- try:
519
- component_class = FlockRegistry.get_component(
520
- component_type_name
521
- ) # Raises KeyError if not found
522
- component_def["module_path"] = getattr(
523
- component_class, "__module__", "unknown"
524
- )
525
- component_def["description"] = (
526
- inspect.getdoc(component_class)
527
- or f"{component_type_name} component"
528
- )
529
-
530
- # Get file path
531
- try:
532
- file_path_abs = inspect.getfile(component_class)
533
- component_def["file_path"] = (
534
- os.path.relpath(file_path_abs)
535
- if path_type == "relative"
536
- else file_path_abs
537
- )
538
- except (TypeError, ValueError) as e:
539
- logger.debug(
540
- f"Could not determine file path for component {component_type_name}: {e}"
541
- )
542
-
543
- except KeyError:
544
- logger.warning(
545
- f"Component class '{component_type_name}' not found in registry."
546
- )
547
- component_def["description"] = (
548
- f"{component_type_name} component (class not found in registry)"
549
- )
550
- except Exception as e:
551
- logger.warning(
552
- f"Could not extract full definition for component {component_type_name}: {e}"
553
- )
554
- return component_def
555
-
556
- @staticmethod
557
- def _get_callable_definition(
558
- callable_path: str,
559
- func_name: str,
560
- path_type: Literal["absolute", "relative"],
561
- ) -> dict[str, Any]:
562
- """Get definition for a callable using its registry path."""
563
- callable_def = {
564
- "type": "flock_callable",
565
- "module_path": "unknown",
566
- "file_path": None,
567
- }
568
- try:
569
- func = FlockRegistry.get_callable(
570
- callable_path
571
- ) # Raises KeyError if not found
572
- callable_def["module_path"] = getattr(func, "__module__", "unknown")
573
- callable_def["description"] = (
574
- inspect.getdoc(func) or f"Callable function {func_name}"
575
- )
576
- # Get file path
577
- try:
578
- file_path_abs = inspect.getfile(func)
579
- callable_def["file_path"] = (
580
- os.path.relpath(file_path_abs)
581
- if path_type == "relative"
582
- else file_path_abs
583
- )
584
- except (TypeError, ValueError) as e:
585
- logger.debug(
586
- f"Could not determine file path for callable {callable_path}: {e}"
587
- )
588
-
589
- except KeyError:
590
- logger.warning(
591
- f"Callable '{callable_path}' (for tool '{func_name}') not found in registry."
592
- )
593
- callable_def["description"] = (
594
- f"Callable {func_name} (function not found in registry)"
595
- )
596
- except Exception as e:
597
- logger.warning(
598
- f"Could not extract full definition for callable {callable_path}: {e}"
599
- )
600
- return callable_def
601
-
602
- @staticmethod
603
- def _get_dependencies() -> list[str]:
604
- """Get list of core dependencies required by Flock."""
605
- # Basic static list for now
606
- return [
607
- "pydantic>=2.0.0",
608
- "flock-core>=0.4.0",
609
- ] # Update version as needed
610
-
611
- @staticmethod
612
- def _register_type_definitions(type_defs: dict[str, Any]) -> None:
613
- """Register type definitions from serialized data."""
614
- # (Logic remains largely the same as original, ensure it uses FlockRegistry)
615
- for type_name, type_def in type_defs.items():
616
- logger.debug(f"Registering type definition for: {type_name}")
617
- # Prioritize direct import
618
- module_path = type_def.get("module_path")
619
- registered = False
620
- if module_path and module_path != "unknown":
621
- try:
622
- module = importlib.import_module(module_path)
623
- if hasattr(module, type_name):
624
- type_obj = getattr(module, type_name)
625
- FlockRegistry.register_type(type_obj, type_name)
626
- logger.info(
627
- f"Registered type '{type_name}' from module '{module_path}'"
628
- )
629
- registered = True
630
- except ImportError:
631
- logger.debug(
632
- f"Could not import module {module_path} for type {type_name}"
633
- )
634
- except Exception as e:
635
- logger.warning(
636
- f"Error registering type {type_name} from module: {e}"
637
- )
638
-
639
- if registered:
640
- continue
641
-
642
- # Attempt dynamic creation if direct import failed or wasn't possible
643
- type_kind = type_def.get("type")
644
- if type_kind == "pydantic.BaseModel" and "schema" in type_def:
645
- FlockSerializer._create_pydantic_model(type_name, type_def)
646
- elif type_kind == "dataclass" and "fields" in type_def:
647
- FlockSerializer._create_dataclass(type_name, type_def)
648
- else:
649
- logger.warning(
650
- f"Cannot dynamically register type '{type_name}' with kind '{type_kind}'"
651
- )
652
-
653
- @staticmethod
654
- def _create_pydantic_model(
655
- type_name: str, type_def: dict[str, Any]
656
- ) -> None:
657
- """Dynamically create and register a Pydantic model from schema."""
658
- # (Logic remains the same, ensure it uses FlockRegistry.register_type)
659
- schema = type_def.get("schema", {})
660
- try:
661
- fields = {}
662
- properties = schema.get("properties", {})
663
- required = schema.get("required", [])
664
- for field_name, field_schema in properties.items():
665
- field_type = FlockSerializer._get_type_from_schema(field_schema)
666
- default = ... if field_name in required else None
667
- fields[field_name] = (field_type, default)
668
-
669
- DynamicModel = create_model(type_name, **fields)
670
- FlockRegistry.register_type(DynamicModel, type_name)
671
- logger.info(
672
- f"Dynamically created and registered Pydantic model: {type_name}"
673
- )
674
- except Exception as e:
675
- logger.error(f"Failed to create Pydantic model {type_name}: {e}")
676
-
677
- @staticmethod
678
- def _get_type_from_schema(field_schema: dict[str, Any]) -> Any:
679
- """Convert JSON schema type to Python type."""
680
- # (Logic remains the same)
681
- schema_type = field_schema.get("type")
682
- type_mapping = {
683
- "string": str,
684
- "integer": int,
685
- "number": float,
686
- "boolean": bool,
687
- "array": list,
688
- "object": dict,
689
- }
690
- if schema_type in type_mapping:
691
- return type_mapping[schema_type]
692
- if "enum" in field_schema:
693
- from typing import Literal
694
-
695
- return Literal[tuple(field_schema["enum"])] # type: ignore
696
- return Any
697
-
698
- @staticmethod
699
- def _create_dataclass(type_name: str, type_def: dict[str, Any]) -> None:
700
- """Dynamically create and register a dataclass."""
701
- # (Logic remains the same, ensure it uses FlockRegistry.register_type)
702
- from dataclasses import make_dataclass
703
-
704
- fields_def = type_def.get("fields", {})
705
- try:
706
- fields = []
707
- for field_name, field_props in fields_def.items():
708
- # Safely evaluate type string - requires care!
709
- field_type_str = field_props.get("type", "str")
710
- try:
711
- field_type = eval(
712
- field_type_str,
713
- {"__builtins__": builtins.__dict__},
714
- {"List": list, "Dict": dict},
715
- ) # Allow basic types
716
- except Exception:
717
- field_type = Any
718
- fields.append((field_name, field_type))
719
-
720
- DynamicDataclass = make_dataclass(type_name, fields)
721
- FlockRegistry.register_type(DynamicDataclass, type_name)
722
- logger.info(
723
- f"Dynamically created and registered dataclass: {type_name}"
724
- )
725
- except Exception as e:
726
- logger.error(f"Failed to create dataclass {type_name}: {e}")
727
-
728
- @staticmethod
729
- def _register_component_definitions(
730
- component_defs: dict[str, Any],
731
- path_type: Literal["absolute", "relative"],
732
- ) -> None:
733
- """Register component/callable definitions from serialized data."""
734
- # (Logic remains the same, ensure it uses FlockRegistry.register_component/register_callable)
735
- # Key change: Ensure file_path is handled correctly based on path_type from metadata
736
- for name, comp_def in component_defs.items():
737
- logger.debug(
738
- f"Registering component/callable definition for: {name}"
739
- )
740
- kind = comp_def.get("type")
741
- module_path = comp_def.get("module_path")
742
- file_path = comp_def.get("file_path")
743
- registered = False
744
-
745
- # Resolve file path if relative
746
- if (
747
- path_type == "relative"
748
- and file_path
749
- and not os.path.isabs(file_path)
750
- ):
751
- abs_file_path = os.path.abspath(file_path)
752
- logger.debug(
753
- f"Resolved relative path '{file_path}' to absolute '{abs_file_path}'"
754
- )
755
- file_path = abs_file_path # Use absolute path for loading
756
-
757
- # 1. Try importing from module_path
758
- if module_path and module_path != "unknown":
759
- try:
760
- module = importlib.import_module(module_path)
761
- if hasattr(module, name):
762
- obj = getattr(module, name)
763
- if kind == "flock_callable" and callable(obj):
764
- FlockRegistry.register_callable(
765
- obj, name
766
- ) # Register by simple name
767
- # Also register by full path if possible
768
- full_path = f"{module_path}.{name}"
769
- if full_path != name:
770
- FlockRegistry.register_callable(obj, full_path)
771
- logger.info(
772
- f"Registered callable '{name}' from module '{module_path}'"
773
- )
774
- registered = True
775
- elif kind == "flock_component" and isinstance(
776
- obj, type
777
- ):
778
- FlockRegistry.register_component(obj, name)
779
- logger.info(
780
- f"Registered component '{name}' from module '{module_path}'"
781
- )
782
- registered = True
783
- except (ImportError, AttributeError):
784
- logger.debug(
785
- f"Could not import '{name}' from module '{module_path}', trying file path."
786
- )
787
- except Exception as e:
788
- logger.warning(
789
- f"Error registering '{name}' from module '{module_path}': {e}"
790
- )
791
-
792
- if registered:
793
- continue
794
-
795
- # 2. Try importing from file_path if module import failed or wasn't possible
796
- if file_path and os.path.exists(file_path):
797
- logger.debug(
798
- f"Attempting to load '{name}' from file: {file_path}"
799
- )
800
- try:
801
- mod_name = f"flock_dynamic_{name}" # Unique module name
802
- spec = importlib.util.spec_from_file_location(
803
- mod_name, file_path
804
- )
805
- if spec and spec.loader:
806
- module = importlib.util.module_from_spec(spec)
807
- sys.modules[spec.name] = (
808
- module # Important for pickle/cloudpickle
809
- )
810
- spec.loader.exec_module(module)
811
- if hasattr(module, name):
812
- obj = getattr(module, name)
813
- if kind == "flock_callable" and callable(obj):
814
- FlockRegistry.register_callable(obj, name)
815
- logger.info(
816
- f"Registered callable '{name}' from file '{file_path}'"
817
- )
818
- elif kind == "flock_component" and isinstance(
819
- obj, type
820
- ):
821
- FlockRegistry.register_component(obj, name)
822
- logger.info(
823
- f"Registered component '{name}' from file '{file_path}'"
824
- )
825
- else:
826
- logger.warning(
827
- f"'{name}' not found in loaded file '{file_path}'"
828
- )
829
- else:
830
- logger.warning(
831
- f"Could not create import spec for file '{file_path}'"
832
- )
833
- except Exception as e:
834
- logger.error(
835
- f"Error loading '{name}' from file '{file_path}': {e}",
836
- exc_info=True,
837
- )
838
- elif not registered:
839
- logger.warning(
840
- f"Could not register '{name}'. No valid module or file path found."
841
- )
842
-
843
- @staticmethod
844
- def _check_dependencies(dependencies: list[str]) -> None:
845
- """Check if required dependencies are available (basic check)."""
846
- # (Logic remains the same)
847
- for dep in dependencies:
848
- match = re.match(r"([^>=<]+)", dep)
849
- if match:
850
- pkg_name = match.group(1).replace("-", "_")
851
- try:
852
- importlib.import_module(pkg_name)
853
- except ImportError:
854
- logger.warning(f"Dependency '{dep}' might be missing.")