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,126 +0,0 @@
1
- from typing import Any
2
-
3
- # from mem0.client.main import AsyncMemoryClient, MemoryClient
4
- # from mem0.memory.main import AsyncMemory
5
- from mem0 import AsyncMemory, AsyncMemoryClient
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 AsyncMem0ModuleConfig(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=AsyncMem0ModuleConfig)
38
- class AsyncMem0Module(FlockModule):
39
-
40
- name: str = "mem0"
41
- config: AsyncMem0ModuleConfig = AsyncMem0ModuleConfig()
42
-
43
-
44
- def __init__(self, name, config: AsyncMem0ModuleConfig) -> 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 = AsyncMemoryClient(api_key=self.config.api_key)
66
- else:
67
- memory = await AsyncMemory.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 = await 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 = await 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 = AsyncMemoryClient(api_key=self.config.api_key)
95
- else:
96
- memory = await AsyncMemory.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 = await 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 = await 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
@@ -1,429 +0,0 @@
1
- import json
2
- import uuid
3
- from datetime import datetime
4
- from typing import Any, Literal
5
-
6
- from pydantic import Field
7
-
8
- from flock.core.context.context import FlockContext
9
-
10
- # if TYPE_CHECKING:
11
- # from flock.core import FlockAgent
12
- from flock.core.flock_agent import FlockAgent
13
- from flock.core.flock_module import FlockModule, FlockModuleConfig
14
- from flock.core.flock_registry import flock_component
15
- from flock.core.logging.logging import get_logger
16
- from flock.modules.memory.memory_parser import MemoryMappingParser
17
- from flock.modules.memory.memory_storage import FlockMemoryStore, MemoryEntry
18
-
19
- logger = get_logger("memory")
20
-
21
-
22
- class MemoryModuleConfig(FlockModuleConfig):
23
- """Configuration for the MemoryModule.
24
-
25
- This class defines the configuration for the MemoryModule.
26
- """
27
-
28
- folder_path: str = Field(
29
- default=".flock/memory/",
30
- description="Directory where memory file and concept graph will be saved",
31
- )
32
- concept_graph_file: str = Field(
33
- default="concept_graph.png",
34
- description="Base filename for the concept graph image",
35
- )
36
- file_path: str | None = Field(
37
- default="agent_memory.json", description="Path to save memory file"
38
- )
39
- memory_mapping: str | None = Field(
40
- default=None, description="Memory mapping configuration"
41
- )
42
- similarity_threshold: float = Field(
43
- default=0.5, description="Threshold for semantic similarity"
44
- )
45
- max_length: int = Field(
46
- default=1000, description="Max length of memory entry before splitting"
47
- )
48
- save_after_update: bool = Field(
49
- default=True, description="Whether to save memory after each update"
50
- )
51
- splitting_mode: Literal["summary", "semantic", "characters", "none"] = (
52
- Field(default="characters", description="Mode to split memory content")
53
- )
54
- enable_read_only_mode: bool = Field(
55
- default=False, description="Whether to enable read only mode"
56
- )
57
- enable_write_only_mode: bool = Field(
58
- default=False, description="Whether to enable write only mode"
59
- )
60
- number_of_concepts_to_extract: int = Field(
61
- default=3, description="Number of concepts to extract from the memory"
62
- )
63
- 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")
64
-
65
-
66
-
67
- @flock_component(config_class=MemoryModuleConfig)
68
- class MemoryModule(FlockModule):
69
- """Module that adds memory capabilities to a Flock agent."""
70
-
71
- name: str = "memory"
72
- config: MemoryModuleConfig = Field(
73
- default_factory=MemoryModuleConfig,
74
- description="Memory module configuration",
75
- )
76
- memory_store: FlockMemoryStore | None = None
77
- memory_ops: list[Any] = []
78
-
79
- def __init__(self, name: str, config: MemoryModuleConfig):
80
- super().__init__(name=name, config=config)
81
- self.memory_store = FlockMemoryStore.load_from_file(
82
- self.get_memory_filename(name)
83
- )
84
- self.memory_ops = (
85
- MemoryMappingParser().parse(self.config.memory_mapping)
86
- if self.config.memory_mapping
87
- else [{"type": "semantic"}]
88
- )
89
-
90
- async def on_initialize(
91
- self,
92
- agent: FlockAgent,
93
- inputs: dict[str, Any],
94
- context: FlockContext | None = None,
95
- ) -> None:
96
- """Initialize memory store if needed."""
97
- if not self.memory_store:
98
- self.memory_store = FlockMemoryStore.load_from_file(
99
- self.get_memory_filename(self.name)
100
- )
101
- self.memory_ops = (
102
- MemoryMappingParser().parse(self.config.memory_mapping)
103
- if self.config.memory_mapping
104
- else [{"type": "semantic"}]
105
- )
106
- logger.debug(f"Initialized memory module for agent {agent.name}")
107
-
108
- async def on_pre_evaluate(
109
- self,
110
- agent: FlockAgent,
111
- inputs: dict[str, Any],
112
- context: FlockContext | None = None,
113
- ) -> dict[str, Any]:
114
- """Check memory before evaluation."""
115
- if not self.memory_store:
116
- return inputs
117
-
118
- if self.config.enable_write_only_mode:
119
- return inputs
120
-
121
- inputs = await self.search_memory(agent, inputs)
122
-
123
- if "context" in inputs:
124
- agent.input = (
125
- agent.input + ", context: list | context with more information"
126
- )
127
-
128
- return inputs
129
-
130
- def get_memory_filename(self, module_name: str) -> str:
131
- """Generate the full file path for the memory file."""
132
- folder = self.config.folder_path
133
- if not folder.endswith(("/", "\\")):
134
- folder += "/"
135
- import os
136
-
137
- if not os.path.exists(folder):
138
- os.makedirs(folder, exist_ok=True)
139
- # Determine base filename and extension from file_path config
140
- if self.config.file_path:
141
- file_name = self.config.file_path.rsplit("/", 1)[-1].rsplit(
142
- "\\", 1
143
- )[-1]
144
- if "." in file_name:
145
- base, ext = file_name.rsplit(".", 1)
146
- ext = f".{ext}"
147
- else:
148
- base, ext = file_name, ""
149
- else:
150
- base, ext = "agent_memory", ".json"
151
- return f"{folder}{module_name}_{base}{ext}"
152
-
153
- def get_concept_graph_filename(self, module_name: str) -> str:
154
- """Generate the full file path for the concept graph image."""
155
- folder = self.config.folder_path
156
- if not folder.endswith(("/", "\\")):
157
- folder += "/"
158
- import os
159
-
160
- if not os.path.exists(folder):
161
- os.makedirs(folder, exist_ok=True)
162
- # Use timestamp to create a unique filename
163
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")[:-3]
164
- if self.config.concept_graph_file:
165
- file_name = self.config.concept_graph_file.rsplit("/", 1)[
166
- -1
167
- ].rsplit("\\", 1)[-1]
168
- if "." in file_name:
169
- base, ext = file_name.rsplit(".", 1)
170
- ext = f".{ext}"
171
- else:
172
- base, ext = file_name, ""
173
- else:
174
- base, ext = "concept_graph", ".png"
175
- return f"{folder}{module_name}_{base}_{timestamp}{ext}"
176
-
177
- async def search_memory(
178
- self, agent: FlockAgent, query: dict[str, Any]
179
- ) -> dict[str, Any]:
180
- """Search memory for the query."""
181
- if not self.memory_store:
182
- # No memory store loaded – just return the untouched input
183
- return query
184
-
185
- try:
186
- input_text = json.dumps(query)
187
- query_embedding = self.memory_store.compute_embedding(input_text)
188
- concepts = await self._extract_concepts(
189
- agent, input_text, self.config.number_of_concepts_to_extract
190
- )
191
-
192
- memory_results = []
193
- for op in self.memory_ops:
194
- if op["type"] == "semantic":
195
- semantic_results = self.memory_store.retrieve(
196
- query_embedding,
197
- concepts,
198
- similarity_threshold=self.config.similarity_threshold,
199
- )
200
- memory_results.extend(semantic_results)
201
- elif op["type"] == "exact":
202
- exact_results = self.memory_store.exact_match(query)
203
- memory_results.extend(exact_results)
204
-
205
- context: list[dict[str, Any]] = []
206
- if memory_results:
207
- for result in memory_results:
208
- context.append(
209
- {"content": result.content, "concepts": result.concepts}
210
- )
211
-
212
- logger.debug(
213
- f"Found {len(memory_results)} relevant memories",
214
- agent=agent.name,
215
- )
216
- query["context"] = context
217
-
218
- return query
219
-
220
- except Exception as e:
221
- logger.warning(f"Memory retrieval failed: {e}", agent=agent.name)
222
- return query
223
-
224
- async def add_to_memory(
225
- self, agent: FlockAgent, data: dict[str, Any]
226
- ) -> None:
227
- """Add data to memory."""
228
- if not self.memory_store:
229
- return
230
-
231
- try:
232
- chunks = await self._get_chunks(agent, data, None)
233
- await self._store_chunks(agent, chunks)
234
- except Exception as e:
235
- logger.warning(f"Memory storage failed: {e}", agent=agent.name)
236
-
237
- async def on_post_evaluate(
238
- self,
239
- agent: FlockAgent,
240
- inputs: dict[str, Any],
241
- context: FlockContext | None = None,
242
- result: dict[str, Any] | None = None,
243
- ) -> dict[str, Any]:
244
- """Store results in memory after evaluation."""
245
- if not self.memory_store:
246
- return result
247
-
248
- if self.config.enable_read_only_mode:
249
- return result
250
-
251
- try:
252
- chunks = await self._get_chunks(agent, inputs, result)
253
- await self._store_chunks(agent, chunks)
254
- except Exception as e:
255
- logger.warning(f"Memory storage failed: {e}", agent=agent.name)
256
-
257
- return result
258
-
259
- async def on_terminate(
260
- self,
261
- agent: Any,
262
- inputs: dict[str, Any],
263
- result: dict[str, Any],
264
- context: FlockContext | None = None,
265
- ) -> None:
266
- """Save memory store if configured."""
267
- if self.config.save_after_update and self.memory_store:
268
- self.save_memory()
269
-
270
- async def _extract_concepts(
271
- self, agent: FlockAgent, text: str, number_of_concepts: int = 3
272
- ) -> set[str]:
273
- """Extract concepts using the agent's LLM capabilities."""
274
- existing_concepts = set()
275
- if self.memory_store and self.memory_store.concept_graph:
276
- existing_concepts = set(
277
- self.memory_store.concept_graph.graph.nodes()
278
- )
279
-
280
- input_signature = "text: str | Text to analyze"
281
- if existing_concepts:
282
- input_signature += ", existing_concepts: list[str] | Already known concepts that might apply"
283
-
284
- concept_signature = agent.create_dspy_signature_class(
285
- f"{agent.name}_concept_extractor",
286
- "Extract key concepts from text",
287
- f"{input_signature} -> concepts: list[str] | Max {number_of_concepts} key concepts all lower case",
288
- )
289
-
290
- agent._configure_language_model(agent.model, True, 0.0, 8192)
291
- predictor = agent._select_task(concept_signature, "Completion")
292
- result_obj = predictor(
293
- text=text,
294
- existing_concepts=list(existing_concepts)
295
- if existing_concepts
296
- else None,
297
- )
298
- concept_list = getattr(result_obj, "concepts", [])
299
- return set(concept_list)
300
-
301
- async def _summarize_mode(
302
- self,
303
- agent: FlockAgent,
304
- inputs: dict[str, Any],
305
- result: dict[str, Any],
306
- ) -> str:
307
- """Extract information chunks using summary mode."""
308
- split_signature = agent.create_dspy_signature_class(
309
- f"{agent.name}_splitter",
310
- "Extract a list of potentially needed data and information for future reference",
311
- """
312
- content: str | The content to split
313
- -> chunks: list[str] | List of data and information for future reference
314
- """,
315
- )
316
- agent._configure_language_model(agent.model, True, 0.0, 8192)
317
- splitter = agent._select_task(split_signature, "Completion")
318
- full_text = json.dumps(inputs) + json.dumps(result)
319
- split_result = splitter(content=full_text)
320
- return "\n".join(split_result.chunks)
321
-
322
- async def _semantic_splitter_mode(
323
- self,
324
- agent: FlockAgent,
325
- inputs: dict[str, Any],
326
- result: dict[str, Any],
327
- ) -> list[str]:
328
- """Extract information chunks using semantic mode."""
329
- split_signature = agent.create_dspy_signature_class(
330
- f"{self.name}_splitter",
331
- "Split content into meaningful, self-contained chunks",
332
- """
333
- content: str | The content to split
334
- -> chunks: list[dict[str,str]] | List of chunks as key-value pairs - keys are a short title and values are the chunk content
335
- """,
336
- )
337
- agent._configure_language_model(agent.model, True, 0.0, 8192)
338
- splitter = agent._select_task(split_signature, "Completion")
339
- full_text = json.dumps(inputs) + (json.dumps(result) if result else "")
340
- split_result = splitter(content=full_text)
341
- # Flatten list[dict] into list[str] of "title: content" strings to
342
- # keep downstream storage logic simple and type-safe.
343
- flattened: list[str] = []
344
- for chunk in split_result.chunks:
345
- if isinstance(chunk, dict):
346
- flattened.extend([f"{k}: {v}" for k, v in chunk.items()])
347
- else:
348
- flattened.append(str(chunk))
349
- return flattened
350
-
351
- async def _character_splitter_mode(
352
- self,
353
- agent: FlockAgent,
354
- inputs: dict[str, Any],
355
- result: dict[str, Any],
356
- ) -> list[str]:
357
- """Extract information chunks by splitting text into fixed character lengths."""
358
- full_text = json.dumps(inputs) + (json.dumps(result) if result else "")
359
- return [
360
- full_text[i : i + self.config.max_length]
361
- for i in range(0, len(full_text), self.config.max_length)
362
- ]
363
-
364
- async def _get_chunks(
365
- self,
366
- agent: FlockAgent,
367
- inputs: dict[str, Any],
368
- result: dict[str, Any] | None,
369
- ) -> str | list[str]:
370
- """Get memory chunks based on the configured splitting mode."""
371
- mode = self.config.splitting_mode
372
- if mode == "semantic":
373
- return await self._semantic_splitter_mode(agent, inputs, result)
374
- elif mode == "summary":
375
- return await self._summarize_mode(agent, inputs, result)
376
- elif mode == "characters":
377
- return await self._character_splitter_mode(agent, inputs, result)
378
- elif mode == "none":
379
- return (
380
- json.dumps(inputs) + json.dumps(result)
381
- if result
382
- else json.dumps(inputs)
383
- )
384
- else:
385
- raise ValueError(f"Unknown splitting mode: {mode}")
386
-
387
- async def _store_chunk(self, agent: FlockAgent, chunk: str) -> None:
388
- """Store a single chunk in memory."""
389
- chunk_concepts = await self._extract_concepts(
390
- agent, chunk, self.config.number_of_concepts_to_extract
391
- )
392
- entry = MemoryEntry(
393
- id=str(uuid.uuid4()),
394
- content=chunk,
395
- embedding=self.memory_store.compute_embedding(chunk).tolist(),
396
- concepts=chunk_concepts,
397
- timestamp=datetime.now(),
398
- )
399
- self.memory_store.add_entry(entry)
400
- if self.config.save_after_update:
401
- self.save_memory()
402
- logger.debug(
403
- "Stored interaction in memory",
404
- agent=agent.name,
405
- entry_id=entry.id,
406
- concepts=chunk_concepts,
407
- )
408
-
409
- async def _store_chunks(
410
- self, agent: FlockAgent, chunks: str | list[str]
411
- ) -> None:
412
- """Store chunks (single or multiple) in memory."""
413
- if isinstance(chunks, str):
414
- await self._store_chunk(agent, chunks)
415
- elif isinstance(chunks, list):
416
- # Avoid tqdm in async context – simple for-loop is safer.
417
- for chunk in chunks:
418
- await self._store_chunk(agent, chunk)
419
-
420
- def save_memory(self) -> None:
421
- """Save memory store to file."""
422
- if self.memory_store and self.config.file_path:
423
- json_str = self.memory_store.model_dump_json()
424
- filename = self.get_memory_filename(self.name)
425
- with open(filename, "w") as file:
426
- file.write(json_str)
427
- self.memory_store.concept_graph.save_as_image(
428
- self.get_concept_graph_filename(self.name)
429
- )
@@ -1,125 +0,0 @@
1
- """Parser for memory mapping declarations into executable operations."""
2
-
3
- import re
4
- from typing import Any
5
-
6
- from flock.modules.memory.memory_storage import (
7
- CombineOperation,
8
- EnrichOperation,
9
- ExactOperation,
10
- FilterOperation,
11
- MemoryOperation,
12
- MemoryScope,
13
- SemanticOperation,
14
- SortOperation,
15
- )
16
-
17
-
18
- class MemoryMappingParser:
19
- """Parses memory mapping declarations into executable operations."""
20
-
21
- def parse(self, mapping: str) -> list[MemoryOperation]:
22
- """Parse a memory mapping string into operations.
23
-
24
- Example mappings:
25
- "topic -> memory.semantic(threshold=0.9) | memory.exact -> output"
26
- "query -> memory.semantic(scope='global') | memory.filter(recency='7d') | memory.sort(by='relevance')"
27
- """
28
- operations = []
29
- stages = [s.strip() for s in mapping.split("|")]
30
-
31
- for stage in stages:
32
- if "->" not in stage:
33
- continue
34
-
35
- inputs, op_spec = stage.split("->")
36
- inputs = [i.strip() for i in inputs.split(",")]
37
-
38
- if "memory." in op_spec:
39
- # Extract operation name and parameters
40
- match = re.match(r"memory\.(\w+)(?:\((.*)\))?", op_spec.strip())
41
- if not match:
42
- continue
43
-
44
- op_name, params_str = match.groups()
45
- params = self._parse_params(params_str or "")
46
-
47
- # Create appropriate operation object
48
- if op_name == "semantic":
49
- operation = SemanticOperation(
50
- threshold=params.get("threshold", 0.8),
51
- scope=params.get("scope", MemoryScope.BOTH),
52
- max_results=params.get("max_results", 10),
53
- )
54
- elif op_name == "exact":
55
- operation = ExactOperation(
56
- keys=inputs, scope=params.get("scope", MemoryScope.BOTH)
57
- )
58
- elif op_name == "enrich":
59
- operation = EnrichOperation(
60
- tools=params.get("tools", []),
61
- strategy=params.get("strategy", "comprehensive"),
62
- scope=params.get("scope", MemoryScope.BOTH),
63
- )
64
- elif op_name == "filter":
65
- operation = FilterOperation(
66
- recency=params.get("recency"),
67
- relevance=params.get("relevance"),
68
- metadata=params.get("metadata", {}),
69
- )
70
- elif op_name == "sort":
71
- operation = SortOperation(
72
- by=params.get("by", "relevance"),
73
- ascending=params.get("ascending", False),
74
- )
75
- elif op_name == "combine":
76
- operation = CombineOperation(
77
- weights=params.get(
78
- "weights", {"semantic": 0.7, "exact": 0.3}
79
- )
80
- )
81
-
82
- operations.append(operation)
83
-
84
- return operations
85
-
86
- def _parse_params(self, params_str: str) -> dict[str, Any]:
87
- """Parse parameters string into a dictionary.
88
-
89
- Handles:
90
- - Quoted strings: threshold='high'
91
- - Numbers: threshold=0.9
92
- - Lists: tools=['web_search', 'extract_numbers']
93
- - Dictionaries: weights={'semantic': 0.7, 'exact': 0.3}
94
- """
95
- if not params_str:
96
- return {}
97
-
98
- params = {}
99
- # Split on commas not inside brackets or quotes
100
- param_pairs = re.findall(
101
- r"""
102
- (?:[^,"]|"[^"]*"|'[^']*')+ # Match everything except comma, or quoted strings
103
- """,
104
- params_str,
105
- re.VERBOSE,
106
- )
107
-
108
- for pair in param_pairs:
109
- if "=" not in pair:
110
- continue
111
- key, value = pair.split("=", 1)
112
- key = key.strip()
113
- value = value.strip()
114
-
115
- # Try to evaluate the value (for lists, dicts, numbers)
116
- try:
117
- # Safely evaluate the value
118
- value = eval(value, {"__builtins__": {}}, {})
119
- except:
120
- # If evaluation fails, treat as string
121
- value = value.strip("'\"")
122
-
123
- params[key] = value
124
-
125
- return params