flock-core 0.4.542__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.542.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.542.dist-info/METADATA +0 -676
  496. flock_core-0.4.542.dist-info/RECORD +0 -572
  497. flock_core-0.4.542.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.542.dist-info → flock_core-0.5.0.dist-info}/WHEEL +0 -0
@@ -1,526 +0,0 @@
1
- from __future__ import annotations
2
-
3
- """Enterprise-grade memory module for Flock.
4
-
5
- This module persists:
6
- • vector embeddings in a Chroma collection (or any collection that
7
- implements the same API)
8
- • a concept graph in Neo4j/Memgraph (Cypher-compatible)
9
-
10
- It follows the same life-cycle callbacks as the standard MemoryModule but
11
- is designed for large-scale, concurrent deployments.
12
- """
13
-
14
- import asyncio
15
- import json
16
- import time
17
- import uuid
18
- from pathlib import Path
19
- from typing import Any, Literal
20
-
21
- from neo4j import AsyncGraphDatabase
22
- from opentelemetry import trace
23
- from pydantic import Field
24
- from sentence_transformers import SentenceTransformer
25
-
26
- from flock.adapter.azure_adapter import AzureSearchAdapter
27
- from flock.adapter.chroma_adapter import ChromaAdapter
28
- from flock.adapter.faiss_adapter import FAISSAdapter
29
- from flock.adapter.pinecone_adapter import PineconeAdapter
30
-
31
- # Adapter imports
32
- from flock.adapter.vector_base import VectorAdapter
33
- from flock.core.context.context import FlockContext
34
- from flock.core.flock_agent import FlockAgent
35
- from flock.core.flock_module import FlockModule, FlockModuleConfig
36
- from flock.core.flock_registry import flock_component
37
- from flock.core.logging.logging import get_logger
38
- from flock.modules.performance.metrics_module import MetricsModule
39
-
40
- logger = get_logger("enterprise_memory")
41
- tracer = trace.get_tracer(__name__)
42
-
43
-
44
- # ---------------------------------------------------------------------------
45
- # Configuration
46
- # ---------------------------------------------------------------------------
47
- class EnterpriseMemoryModuleConfig(FlockModuleConfig):
48
- """Configuration for EnterpriseMemoryModule."""
49
-
50
- # ---------------------
51
- # Vector store settings
52
- # ---------------------
53
-
54
- vector_backend: Literal["chroma", "pinecone", "azure"] = Field(
55
- default="chroma",
56
- description="Which vector backend to use (chroma | pinecone | azure)",
57
- )
58
-
59
- # --- Chroma ---
60
- chroma_path: str | None = Field(
61
- default="./vector_store",
62
- description="Disk path for Chroma persistent storage (if running embedded).",
63
- )
64
- chroma_collection: str = Field(
65
- default="flock_memories", description="Chroma collection name"
66
- )
67
- chroma_host: str | None = Field(
68
- default=None,
69
- description="If provided, connect to a remote Chroma HTTP server at this host",
70
- )
71
- chroma_port: int = Field(default=8000, description="Remote Chroma HTTP port")
72
-
73
- # --- Pinecone ---
74
- pinecone_api_key: str | None = Field(default=None, description="Pinecone API key")
75
- pinecone_env: str | None = Field(default=None, description="Pinecone environment")
76
- pinecone_index: str | None = Field(default=None, description="Pinecone index name")
77
-
78
- # --- Azure Cognitive Search ---
79
- azure_search_endpoint: str | None = Field(default=None, description="Azure search endpoint (https://<service>.search.windows.net)")
80
- azure_search_key: str | None = Field(default=None, description="Azure search admin/key")
81
- azure_search_index_name: str | None = Field(default=None, description="Azure search index name")
82
-
83
- # Graph DB (Neo4j / Memgraph) settings
84
- cypher_uri: str = Field(
85
- default="bolt://localhost:7687", description="Bolt URI for the graph DB"
86
- )
87
- cypher_username: str = Field(default="neo4j", description="Username for DB")
88
- cypher_password: str = Field(default="password", description="Password for DB")
89
-
90
- similarity_threshold: float = Field(
91
- default=0.5, description="Cosine-similarity threshold for retrieval"
92
- )
93
- max_results: int = Field(default=10, description="Maximum retrieved memories")
94
- number_of_concepts_to_extract: int = Field(
95
- default=3, description="Number of concepts extracted per chunk"
96
- )
97
- save_interval: int = Field(
98
- default=10,
99
- description="Persist to disk after this many new chunks (0 disables auto-save)",
100
- )
101
-
102
- export_graph_image: bool = Field(
103
- default=False,
104
- description="If true, exports a PNG image of the concept graph each time it is updated.",
105
- )
106
- graph_image_dir: str = Field(
107
- default="./concept_graphs",
108
- description="Directory where graph images will be stored when export_graph_image is true.",
109
- )
110
-
111
-
112
- # ---------------------------------------------------------------------------
113
- # Storage Abstraction
114
- # ---------------------------------------------------------------------------
115
- class EnterpriseMemoryStore:
116
- """Persistence layer that wraps Chroma + Cypher graph."""
117
-
118
- def __init__(self, cfg: EnterpriseMemoryModuleConfig, metrics_module: MetricsModule | None = None):
119
- self.cfg = cfg
120
- # Metrics module (DI-resolved or fallback)
121
- self._metrics = metrics_module or MetricsModule # can be either instance or class exposing .record
122
- # Lazy initialise expensive resources
123
- self._embedding_model: SentenceTransformer | None = None
124
- self._adapter: VectorAdapter | None = None
125
- self._driver = None # Neo4j driver
126
- self._pending_writes: list[tuple[str, dict[str, Any]]] = []
127
- self._write_lock = asyncio.Lock()
128
- self._concept_cache: set[str] | None = None # names of known concepts
129
-
130
- # ---------------------------------------------------------------------
131
- # Connections
132
- # ---------------------------------------------------------------------
133
- def _ensure_embedding_model(self) -> SentenceTransformer:
134
- if self._embedding_model is None:
135
- logger.debug("Loading embedding model 'all-MiniLM-L6-v2'")
136
- with tracer.start_as_current_span("memory.load_embedding_model") as span:
137
- try:
138
- self._embedding_model = SentenceTransformer("all-MiniLM-L6-v2")
139
- span.set_attribute("model", "all-MiniLM-L6-v2")
140
- except Exception as e:
141
- span.record_exception(e)
142
- raise
143
- return self._embedding_model
144
-
145
- def _ensure_adapter(self) -> VectorAdapter:
146
- if self._adapter is not None:
147
- return self._adapter
148
-
149
- backend = self.cfg.vector_backend
150
-
151
- if backend == "chroma":
152
- self._adapter = ChromaAdapter(
153
- collection=self.cfg.chroma_collection,
154
- host=self.cfg.chroma_host,
155
- port=self.cfg.chroma_port,
156
- path=self.cfg.chroma_path,
157
- )
158
- elif backend == "pinecone":
159
- self._adapter = PineconeAdapter(
160
- api_key=self.cfg.pinecone_api_key,
161
- environment=self.cfg.pinecone_env,
162
- index=self.cfg.pinecone_index,
163
- )
164
- elif backend == "azure":
165
- self._adapter = AzureSearchAdapter(
166
- endpoint=self.cfg.azure_search_endpoint,
167
- key=self.cfg.azure_search_key,
168
- index_name=self.cfg.azure_search_index_name,
169
- )
170
- elif backend == "faiss":
171
- self._adapter = FAISSAdapter(index_path="./faiss.index")
172
- else:
173
- raise ValueError(f"Unsupported vector backend: {backend}")
174
-
175
- return self._adapter
176
-
177
- def _ensure_graph_driver(self):
178
- if self._driver is None:
179
- self._driver = AsyncGraphDatabase.driver(
180
- self.cfg.cypher_uri,
181
- auth=(self.cfg.cypher_username, self.cfg.cypher_password),
182
- encrypted=False,
183
- )
184
- return self._driver
185
-
186
- # ---------------------------------------------------------------------
187
- # Public API
188
- # ---------------------------------------------------------------------
189
- async def add_entry(
190
- self,
191
- content: str,
192
- concepts: set[str],
193
- metadata: dict[str, Any] | None = None,
194
- ) -> str:
195
- """Store a chunk in both vector store and graph DB and return its id."""
196
- with tracer.start_as_current_span("memory.add_entry") as span:
197
- span.set_attribute("entry_id", str(uuid.uuid4()))
198
-
199
- # Embed
200
- embedding = self._ensure_embedding_model().encode(content).tolist()
201
- span.set_attribute("embedding_length", len(embedding))
202
-
203
- # Vector store write
204
- adapter = self._ensure_adapter()
205
- span.set_attribute("vector_backend", self.cfg.vector_backend)
206
-
207
- start_t = time.perf_counter()
208
- try:
209
- adapter.add(
210
- id=span.get_attribute("entry_id"),
211
- content=content,
212
- embedding=embedding,
213
- metadata=metadata,
214
- )
215
- except Exception as e:
216
- span.record_exception(e)
217
- raise
218
- finally:
219
- elapsed = (time.perf_counter() - start_t) * 1000 # ms
220
- self._metrics.record(
221
- "memory_add_latency_ms",
222
- elapsed,
223
- {"backend": self.cfg.vector_backend},
224
- )
225
-
226
- # Schedule graph writes (batched)
227
- async with self._write_lock:
228
- self._pending_writes.append((span.get_attribute("entry_id"), {"concepts": concepts}))
229
- if self.cfg.save_interval and len(self._pending_writes) >= self.cfg.save_interval:
230
- await self._flush_pending_graph_writes()
231
- return span.get_attribute("entry_id")
232
-
233
- async def search(
234
- self, query_text: str, threshold: float, k: int
235
- ) -> list[dict[str, Any]]:
236
- """Vector similarity search followed by graph enrichment."""
237
- with tracer.start_as_current_span("memory.search") as span:
238
- span.set_attribute("vector_backend", self.cfg.vector_backend)
239
- embedding = (
240
- self._ensure_embedding_model().encode(query_text).tolist()
241
- )
242
- span.set_attribute("embedding_length", len(embedding))
243
- adapter = self._ensure_adapter()
244
- backend = self.cfg.vector_backend
245
- results: list[dict[str, Any]] = []
246
-
247
- search_start = time.perf_counter()
248
- vector_hits = adapter.query(embedding=embedding, k=k)
249
- search_elapsed = (time.perf_counter() - search_start) * 1000
250
- self._metrics.record(
251
- "memory_search_hits", len(vector_hits), {"backend": backend}
252
- )
253
- for hit in vector_hits:
254
- if hit.score < threshold:
255
- continue
256
- results.append(
257
- {
258
- "id": hit.id,
259
- "content": hit.content,
260
- "metadata": hit.metadata,
261
- "score": hit.score,
262
- }
263
- )
264
-
265
- span.set_attribute("results_count", len(results))
266
- self._metrics.record(
267
- "memory_search_latency_ms", search_elapsed, {"backend": backend}
268
- )
269
- return results
270
-
271
- # ------------------------------------------------------------------
272
- # Graph persistence helpers
273
- # ------------------------------------------------------------------
274
- async def _flush_pending_graph_writes(self):
275
- """Commit queued node/edge creations to the Cypher store."""
276
- if not self._pending_writes:
277
- return
278
- driver = self._ensure_graph_driver()
279
- async with driver.session() as session:
280
- tx_commands: list[str] = []
281
- params: dict[str, Any] = {}
282
- # Build Cypher in one transaction
283
- for idx, (entry_id, extra) in enumerate(self._pending_writes):
284
- concept_param = f"concepts_{idx}"
285
- tx_commands.append(
286
- f"MERGE (e:Memory {{id: '{entry_id}'}}) "
287
- f"SET e.created = datetime() "
288
- )
289
- if extra.get("concepts"):
290
- tx_commands.append(
291
- f"WITH e UNWIND ${concept_param} AS c "
292
- "MERGE (co:Concept {name: c}) "
293
- "MERGE (e)-[:MENTIONS]->(co)"
294
- )
295
- params[concept_param] = list(extra["concepts"])
296
- cypher = "\n".join(tx_commands)
297
- await session.run(cypher, params)
298
- # Export graph image if requested
299
- if self.cfg.export_graph_image:
300
- await self._export_graph_image(session)
301
- self._pending_writes.clear()
302
-
303
- async def _export_graph_image(self, session):
304
- """Generate and save a PNG of the concept graph."""
305
- try:
306
- import matplotlib
307
- matplotlib.use("Agg")
308
- import matplotlib.pyplot as plt
309
- import networkx as nx
310
-
311
- records = await session.run(
312
- "MATCH (c1:Concept)<-[:MENTIONS]-(:Memory)-[:MENTIONS]->(c2:Concept) "
313
- "RETURN DISTINCT c1.name AS source, c2.name AS target"
314
- )
315
- edges = [(r["source"], r["target"]) for r in await records.values("source", "target")]
316
- if not edges:
317
- return
318
-
319
- G = nx.Graph()
320
- G.add_edges_from(edges)
321
-
322
- pos = nx.spring_layout(G, k=0.4)
323
- plt.figure(figsize=(12, 9), dpi=100)
324
- nx.draw_networkx_nodes(G, pos, node_color="#8fa8d6", node_size=500, edgecolors="white")
325
- nx.draw_networkx_edges(G, pos, alpha=0.5, width=1.5)
326
- nx.draw_networkx_labels(G, pos, font_size=8)
327
- plt.axis("off")
328
-
329
- img_dir = Path(self.cfg.graph_image_dir)
330
- img_dir.mkdir(parents=True, exist_ok=True)
331
- filename = img_dir / f"concept_graph_{uuid.uuid4().hex[:8]}.png"
332
- plt.savefig(filename, bbox_inches="tight", facecolor="white")
333
- plt.close()
334
- logger.info("Concept graph image exported to %s", filename)
335
- except Exception as e:
336
- logger.warning("Failed to export concept graph image: %s", e)
337
-
338
- async def close(self):
339
- if self._pending_writes:
340
- await self._flush_pending_graph_writes()
341
- if self._driver:
342
- await self._driver.close()
343
- if self._adapter and hasattr(self._adapter, "close"):
344
- self._adapter.close()
345
-
346
-
347
- # ---------------------------------------------------------------------------
348
- # Module
349
- # ---------------------------------------------------------------------------
350
- @flock_component(config_class=EnterpriseMemoryModuleConfig)
351
- class EnterpriseMemoryModule(FlockModule):
352
- """Enterprise-ready memory module using real datastores."""
353
-
354
- name: str = "enterprise_memory"
355
- config: EnterpriseMemoryModuleConfig = Field(default_factory=EnterpriseMemoryModuleConfig)
356
-
357
- _store: EnterpriseMemoryStore | None = None
358
- _container: Any | None = None # DI container if supplied
359
- _metrics_module: MetricsModule | None = None
360
-
361
- # ----------------------------------------------------------
362
- # DI-enabled constructor
363
- # ----------------------------------------------------------
364
- def __init__(
365
- self,
366
- name: str = "enterprise_memory",
367
- config: EnterpriseMemoryModuleConfig | None = None,
368
- *,
369
- container: object | None = None,
370
- **kwargs,
371
- ):
372
- """Create a new EnterpriseMemoryModule instance.
373
-
374
- Parameters
375
- ----------
376
- container : ServiceProvider | None
377
- Optional DI container used to resolve shared services. When
378
- provided, the module will attempt to resolve
379
- :class:`flock.modules.performance.metrics_module.MetricsModule` from
380
- it. Falling back to the global singleton when not available keeps
381
- backward-compatibility.
382
- """
383
- from wd.di.container import (
384
- ServiceProvider, # Local import to avoid hard dependency if wd.di is absent
385
- )
386
-
387
- if config is None:
388
- config = EnterpriseMemoryModuleConfig()
389
-
390
- super().__init__(name=name, config=config, **kwargs)
391
-
392
- self._container = container if isinstance(container, ServiceProvider) else None
393
-
394
- # Attempt to resolve MetricsModule via DI, then via FlockModule registry
395
- resolved_metrics: MetricsModule | None = None
396
- if self._container is not None:
397
- try:
398
- resolved_metrics = self._container.get_service(MetricsModule)
399
- except Exception:
400
- resolved_metrics = None
401
-
402
- if resolved_metrics is None:
403
- resolved_metrics = MetricsModule._INSTANCE
404
-
405
- self._metrics_module = resolved_metrics
406
-
407
- # ----------------------------------------------------------
408
- # Life-cycle hooks
409
- # ----------------------------------------------------------
410
- async def on_initialize(
411
- self,
412
- agent: FlockAgent,
413
- inputs: dict[str, Any],
414
- context: FlockContext | None = None,
415
- ) -> None:
416
- self._store = EnterpriseMemoryStore(self.config, self._metrics_module)
417
- logger.info("EnterpriseMemoryModule initialised", agent=agent.name)
418
-
419
- async def on_pre_evaluate(
420
- self,
421
- agent: FlockAgent,
422
- inputs: dict[str, Any],
423
- context: FlockContext | None = None,
424
- ) -> dict[str, Any]:
425
- if not self._store:
426
- return inputs
427
- try:
428
- query_str = json.dumps(inputs)
429
- matches = await self._store.search(
430
- query_str,
431
- threshold=self.config.similarity_threshold,
432
- k=self.config.max_results,
433
- )
434
- if matches:
435
- inputs = {**inputs, "context": matches}
436
- # Advertise new input key to DSPy signature if needed
437
- if isinstance(agent.input, str) and "context:" not in agent.input:
438
- agent.input += ", context: list | retrieved memories"
439
- except Exception as e:
440
- logger.warning("Enterprise memory retrieval failed: %s", e, agent=agent.name)
441
- return inputs
442
-
443
- async def on_post_evaluate(
444
- self,
445
- agent: FlockAgent,
446
- inputs: dict[str, Any],
447
- context: FlockContext | None = None,
448
- result: dict[str, Any] | None = None,
449
- ) -> dict[str, Any] | None:
450
- if not self._store:
451
- return result
452
- try:
453
- full_text = json.dumps(inputs) + (json.dumps(result) if result else "")
454
- concepts = await self._extract_concepts(agent, full_text)
455
- if self._store:
456
- concepts = await self._store._deduplicate_concepts(concepts)
457
- await self._store.add_entry(full_text, concepts)
458
- except Exception as e:
459
- logger.warning("Enterprise memory store failed: %s", e, agent=agent.name)
460
- return result
461
-
462
- async def on_terminate(
463
- self,
464
- agent: FlockAgent,
465
- inputs: dict[str, Any],
466
- result: dict[str, Any],
467
- context: FlockContext | None = None,
468
- ) -> None:
469
- if self._store:
470
- await self._store.close()
471
-
472
- # ----------------------------------------------------------
473
- # Helpers (mostly copied from original module but simplified)
474
- # ----------------------------------------------------------
475
- async def _extract_concepts(self, agent: FlockAgent, text: str) -> set[str]:
476
- """Use the LLM to extract concept tokens."""
477
- concept_signature = agent.create_dspy_signature_class(
478
- f"{agent.name}_concept_extractor_enterprise",
479
- "Extract key concepts from text",
480
- "text: str | Input text -> concepts: list[str] | key concepts lower case",
481
- )
482
- agent._configure_language_model(agent.model, True, 0.0, 8192)
483
- predictor = agent._select_task(concept_signature, "Completion")
484
- res = predictor(text=text)
485
- return set(getattr(res, "concepts", []))
486
-
487
- # --------------------------------------------------------------
488
- # Concept helpers
489
- # --------------------------------------------------------------
490
- async def _ensure_concept_cache(self):
491
- if self._concept_cache is not None:
492
- return
493
- driver = self._ensure_graph_driver()
494
- async with driver.session() as session:
495
- records = await session.run("MATCH (c:Concept) RETURN c.name AS name")
496
- self._concept_cache = {r["name"] for r in await records.values("name")}
497
-
498
- async def _deduplicate_concepts(self, new_concepts: set[str]) -> set[str]:
499
- """Return a set of concept names that merges with existing ones to avoid duplicates.
500
-
501
- Strategy: case-insensitive equality first, then fuzzy match via difflib with cutoff 0.85.
502
- """
503
- await self._ensure_concept_cache()
504
- assert self._concept_cache is not None
505
-
506
- from difflib import get_close_matches
507
-
508
- unified: set[str] = set()
509
- for concept in new_concepts:
510
- # Exact (case-insensitive) match
511
- lower = concept.lower()
512
- exact = next((c for c in self._concept_cache if c.lower() == lower), None)
513
- if exact:
514
- unified.add(exact)
515
- continue
516
-
517
- # Fuzzy match (>=0.85 similarity)
518
- close = get_close_matches(concept, list(self._concept_cache), n=1, cutoff=0.85)
519
- if close:
520
- unified.add(close[0])
521
- continue
522
-
523
- # No match – treat as new
524
- unified.add(concept)
525
- self._concept_cache.add(concept)
526
- return unified
@@ -1 +0,0 @@
1
- # Package for modules
@@ -1,126 +0,0 @@
1
- from typing import Any
2
-
3
- # from mem0.client.main import MemoryClient
4
- # from mem0.memory.main import Memory
5
- from mem0 import Memory, MemoryClient
6
- from pydantic import Field
7
-
8
- from flock.core.context.context import FlockContext
9
- from flock.core.flock_agent import FlockAgent
10
- from flock.core.flock_module import FlockModule, FlockModuleConfig
11
- from flock.core.flock_registry import flock_component
12
- from flock.core.logging.logging import get_logger
13
-
14
- logger = get_logger("module.mem0")
15
-
16
-
17
- config = {
18
- "vector_store": {
19
- "provider": "chroma",
20
- "config": {
21
- "collection_name": "flock_memory",
22
- "path": ".flock/memory",
23
- }
24
- }
25
- }
26
-
27
-
28
- class Mem0ModuleConfig(FlockModuleConfig):
29
- top_k: int = Field(default=10, description="Number of memories to retrieve")
30
- user_id: str = Field(default="flock", description="User ID the memories will be associated with")
31
- agent_id: str = Field(default="flock", description="Agent ID the memories will be associated with")
32
- memory_input_key: str | None = Field(default=None, description="Input key to use for memory, if none the description of the agent will be used")
33
- api_key: str | None = Field(default=None, description="API key for mem0 Platform")
34
- config: dict[str, Any] = Field(default=config, description="Configuration for mem0")
35
-
36
-
37
- @flock_component(config_class=Mem0ModuleConfig)
38
- class Mem0Module(FlockModule):
39
-
40
- name: str = "mem0"
41
- config: Mem0ModuleConfig = Mem0ModuleConfig()
42
-
43
-
44
- def __init__(self, name, config: Mem0ModuleConfig) -> None:
45
- global memory
46
- """Initialize Mem0 module."""
47
- super().__init__(name=name, config=config)
48
- logger.debug("Initializing Mem0 module")
49
-
50
-
51
-
52
-
53
- def dict_to_str_repr(self,d: dict) -> str:
54
- return repr(d)
55
-
56
-
57
- async def on_post_evaluate(
58
- self,
59
- agent: FlockAgent,
60
- inputs: dict[str, Any],
61
- context: FlockContext | None = None,
62
- result: dict[str, Any] | None = None,
63
- ) -> dict[str, Any]:
64
- if self.config.api_key:
65
- memory = MemoryClient(api_key=self.config.api_key)
66
- else:
67
- memory = Memory.from_config(config_dict=self.config.config)
68
-
69
- agent_id = self.config.agent_id if self.config.agent_id else agent.name
70
-
71
- # get the result without the inputs
72
- filtered_result = {k: v for k, v in result.items() if k not in inputs}
73
- # get the inputs without memory
74
- filtered_inputs = {k: v for k, v in inputs.items() if k not in [self.config.memory_input_key]}
75
-
76
- # add memories about the user inputs
77
- added_user_memory = memory.add(self.dict_to_str_repr(filtered_inputs), user_id=self.config.user_id)
78
- logger.info(f"Added caller memory: {added_user_memory}")
79
-
80
- # add memories about the agent result
81
- added_agent_memory = memory.add(self.dict_to_str_repr(filtered_result), agent_id=agent_id)
82
- logger.info(f"Added agent memory: {added_agent_memory}")
83
-
84
-
85
- return result
86
-
87
- async def on_pre_evaluate(
88
- self,
89
- agent: FlockAgent,
90
- inputs: dict[str, Any],
91
- context: FlockContext | None = None,
92
- ) -> dict[str, Any]:
93
- if self.config.api_key:
94
- memory = MemoryClient(api_key=self.config.api_key)
95
- else:
96
- memory = Memory.from_config(config_dict=self.config.config)
97
-
98
- message = self.dict_to_str_repr(inputs)
99
- agent_id = self.config.agent_id if self.config.agent_id else agent.name
100
-
101
- relevant_agent_memories = memory.search(query=message, agent_id=agent_id, limit=self.config.top_k)
102
- logger.info(f"Relevant agent memories: {relevant_agent_memories}")
103
-
104
- relevant_user_memories = memory.search(query=message, user_id=self.config.user_id, limit=self.config.top_k)
105
- logger.info(f"Relevant user memories: {relevant_user_memories}")
106
-
107
- if relevant_agent_memories or relevant_user_memories:
108
- memories_str = ''
109
- if "results" in relevant_agent_memories:
110
- memories_str = "\n".join(f"- {entry['memory']}" for entry in relevant_agent_memories["results"])
111
- else:
112
- memories_str = "\n".join(f"- {entry}" for entry in relevant_agent_memories)
113
-
114
- if "results" in relevant_user_memories:
115
- memories_str = memories_str + "\n" + "\n".join(f"- {entry['memory']}" for entry in relevant_user_memories["results"])
116
- else:
117
- memories_str = memories_str + "\n" + "\n".join(f"- {entry}" for entry in relevant_user_memories)
118
-
119
- if memories_str:
120
- if self.config.memory_input_key:
121
- inputs[self.config.memory_input_key] = memories_str
122
- else:
123
- agent.description = agent.description + "\n\n Memories:" + memories_str
124
-
125
-
126
- return inputs
@@ -1 +0,0 @@
1
- # Package for modules