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
@@ -0,0 +1,437 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { Node, Edge } from '@xyflow/react';
3
+
4
+ /**
5
+ * Phase 4: Graph Visualization & Dual Views - Layout Tests
6
+ *
7
+ * Tests for Dagre-based hierarchical layout algorithm.
8
+ * These tests validate layout generation, node positioning, performance,
9
+ * and edge routing capabilities.
10
+ *
11
+ * SPECIFICATION: docs/specs/003-real-time-dashboard/PLAN.md Phase 4
12
+ * REQUIREMENT: Auto-layout completes <200ms for 10 nodes
13
+ */
14
+
15
+ // Type definitions for the layout service (to be implemented)
16
+ interface LayoutOptions {
17
+ direction?: 'TB' | 'LR' | 'BT' | 'RL';
18
+ nodeSpacing?: number;
19
+ rankSpacing?: number;
20
+ }
21
+
22
+ interface LayoutResult {
23
+ nodes: Node[];
24
+ edges: Edge[];
25
+ width: number;
26
+ height: number;
27
+ }
28
+
29
+ // Mock layout service interface (implementation will be in layout.ts)
30
+ interface LayoutService {
31
+ applyHierarchicalLayout(nodes: Node[], edges: Edge[], options?: LayoutOptions): LayoutResult;
32
+ }
33
+
34
+ describe('Layout Service', () => {
35
+ // This will be replaced with actual implementation
36
+ let layoutService: LayoutService;
37
+
38
+ beforeEach(() => {
39
+ // Mock implementation for testing
40
+ layoutService = {
41
+ applyHierarchicalLayout: (_nodes, _edges, _options) => {
42
+ // Placeholder that will fail until real implementation
43
+ throw new Error('Layout service not implemented');
44
+ },
45
+ };
46
+ });
47
+
48
+ describe('Hierarchical Layout Generation', () => {
49
+ it('should generate hierarchical layout in vertical direction (TB)', () => {
50
+ const nodes: Node[] = [
51
+ { id: 'agent-1', type: 'agent', position: { x: 0, y: 0 }, data: { name: 'Agent 1' } },
52
+ { id: 'agent-2', type: 'agent', position: { x: 0, y: 0 }, data: { name: 'Agent 2' } },
53
+ { id: 'agent-3', type: 'agent', position: { x: 0, y: 0 }, data: { name: 'Agent 3' } },
54
+ ];
55
+
56
+ const edges: Edge[] = [
57
+ { id: 'e1-2', source: 'agent-1', target: 'agent-2' },
58
+ { id: 'e2-3', source: 'agent-2', target: 'agent-3' },
59
+ ];
60
+
61
+ expect(() => {
62
+ layoutService.applyHierarchicalLayout(nodes, edges, { direction: 'TB' });
63
+ }).toThrow('Layout service not implemented');
64
+
65
+ // Expected behavior after implementation:
66
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges, { direction: 'TB' });
67
+ //
68
+ // expect(result.nodes).toHaveLength(3);
69
+ //
70
+ // // Verify vertical hierarchy: agent-1 should be above agent-2, agent-2 above agent-3
71
+ // const node1 = result.nodes.find(n => n.id === 'agent-1');
72
+ // const node2 = result.nodes.find(n => n.id === 'agent-2');
73
+ // const node3 = result.nodes.find(n => n.id === 'agent-3');
74
+ //
75
+ // expect(node1!.position.y).toBeLessThan(node2!.position.y);
76
+ // expect(node2!.position.y).toBeLessThan(node3!.position.y);
77
+ });
78
+
79
+ it('should generate hierarchical layout in horizontal direction (LR)', () => {
80
+ const nodes: Node[] = [
81
+ { id: 'agent-1', type: 'agent', position: { x: 0, y: 0 }, data: { name: 'Agent 1' } },
82
+ { id: 'agent-2', type: 'agent', position: { x: 0, y: 0 }, data: { name: 'Agent 2' } },
83
+ ];
84
+
85
+ const edges: Edge[] = [
86
+ { id: 'e1-2', source: 'agent-1', target: 'agent-2' },
87
+ ];
88
+
89
+ expect(() => {
90
+ layoutService.applyHierarchicalLayout(nodes, edges, { direction: 'LR' });
91
+ }).toThrow('Layout service not implemented');
92
+
93
+ // Expected behavior after implementation:
94
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges, { direction: 'LR' });
95
+ //
96
+ // const node1 = result.nodes.find(n => n.id === 'agent-1');
97
+ // const node2 = result.nodes.find(n => n.id === 'agent-2');
98
+ //
99
+ // // Verify horizontal hierarchy: agent-1 should be left of agent-2
100
+ // expect(node1!.position.x).toBeLessThan(node2!.position.x);
101
+ });
102
+
103
+ it('should handle cyclic graphs gracefully', () => {
104
+ const nodes: Node[] = [
105
+ { id: 'agent-1', type: 'agent', position: { x: 0, y: 0 }, data: {} },
106
+ { id: 'agent-2', type: 'agent', position: { x: 0, y: 0 }, data: {} },
107
+ { id: 'agent-3', type: 'agent', position: { x: 0, y: 0 }, data: {} },
108
+ ];
109
+
110
+ const edges: Edge[] = [
111
+ { id: 'e1-2', source: 'agent-1', target: 'agent-2' },
112
+ { id: 'e2-3', source: 'agent-2', target: 'agent-3' },
113
+ { id: 'e3-1', source: 'agent-3', target: 'agent-1' }, // Cycle
114
+ ];
115
+
116
+ expect(() => {
117
+ layoutService.applyHierarchicalLayout(nodes, edges);
118
+ }).toThrow('Layout service not implemented');
119
+
120
+ // Expected behavior: Should not throw, should produce valid layout
121
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges);
122
+ // expect(result.nodes).toHaveLength(3);
123
+ // result.nodes.forEach(node => {
124
+ // expect(node.position.x).toBeGreaterThanOrEqual(0);
125
+ // expect(node.position.y).toBeGreaterThanOrEqual(0);
126
+ // });
127
+ });
128
+ });
129
+
130
+ describe('Node Positioning', () => {
131
+ it('should assign x, y coordinates to all nodes', () => {
132
+ const nodes: Node[] = [
133
+ { id: 'node-1', type: 'agent', position: { x: 0, y: 0 }, data: {} },
134
+ { id: 'node-2', type: 'agent', position: { x: 0, y: 0 }, data: {} },
135
+ { id: 'node-3', type: 'agent', position: { x: 0, y: 0 }, data: {} },
136
+ ];
137
+
138
+ const edges: Edge[] = [
139
+ { id: 'e1-2', source: 'node-1', target: 'node-2' },
140
+ ];
141
+
142
+ expect(() => {
143
+ layoutService.applyHierarchicalLayout(nodes, edges);
144
+ }).toThrow('Layout service not implemented');
145
+
146
+ // Expected behavior:
147
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges);
148
+ //
149
+ // result.nodes.forEach(node => {
150
+ // expect(node.position).toHaveProperty('x');
151
+ // expect(node.position).toHaveProperty('y');
152
+ // expect(typeof node.position.x).toBe('number');
153
+ // expect(typeof node.position.y).toBe('number');
154
+ // expect(Number.isFinite(node.position.x)).toBe(true);
155
+ // expect(Number.isFinite(node.position.y)).toBe(true);
156
+ // });
157
+ });
158
+
159
+ it('should prevent node overlap with proper spacing', () => {
160
+ const nodes: Node[] = Array.from({ length: 5 }, (_, i) => ({
161
+ id: `node-${i}`,
162
+ type: 'agent',
163
+ position: { x: 0, y: 0 },
164
+ data: { name: `Agent ${i}` },
165
+ }));
166
+
167
+ const edges: Edge[] = Array.from({ length: 4 }, (_, i) => ({
168
+ id: `e${i}-${i + 1}`,
169
+ source: `node-${i}`,
170
+ target: `node-${i + 1}`,
171
+ }));
172
+
173
+ expect(() => {
174
+ layoutService.applyHierarchicalLayout(nodes, edges, { nodeSpacing: 50 });
175
+ }).toThrow('Layout service not implemented');
176
+
177
+ // Expected behavior:
178
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges, { nodeSpacing: 50 });
179
+ //
180
+ // // Check that no two nodes are too close
181
+ // const minDistance = 50; // Based on nodeSpacing
182
+ // for (let i = 0; i < result.nodes.length; i++) {
183
+ // for (let j = i + 1; j < result.nodes.length; j++) {
184
+ // const node1 = result.nodes[i];
185
+ // const node2 = result.nodes[j];
186
+ // const distance = Math.sqrt(
187
+ // Math.pow(node1.position.x - node2.position.x, 2) +
188
+ // Math.pow(node1.position.y - node2.position.y, 2)
189
+ // );
190
+ // expect(distance).toBeGreaterThanOrEqual(minDistance);
191
+ // }
192
+ // }
193
+ });
194
+
195
+ it('should respect custom node spacing', () => {
196
+ const nodes: Node[] = [
197
+ { id: 'node-1', type: 'agent', position: { x: 0, y: 0 }, data: {} },
198
+ { id: 'node-2', type: 'agent', position: { x: 0, y: 0 }, data: {} },
199
+ ];
200
+
201
+ const edges: Edge[] = [
202
+ { id: 'e1-2', source: 'node-1', target: 'node-2' },
203
+ ];
204
+
205
+ expect(() => {
206
+ const customSpacing = 100;
207
+ layoutService.applyHierarchicalLayout(nodes, edges, { nodeSpacing: customSpacing });
208
+ }).toThrow('Layout service not implemented');
209
+
210
+ // Expected behavior:
211
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges, { nodeSpacing: 100 });
212
+ //
213
+ // const node1 = result.nodes.find(n => n.id === 'node-1')!;
214
+ // const node2 = result.nodes.find(n => n.id === 'node-2')!;
215
+ //
216
+ // // Distance should be at least the custom spacing
217
+ // const distance = Math.abs(node2.position.y - node1.position.y);
218
+ // expect(distance).toBeGreaterThanOrEqual(100);
219
+ });
220
+ });
221
+
222
+ describe('Layout Performance', () => {
223
+ it('should complete layout in <200ms for 10 nodes (REQUIREMENT)', () => {
224
+ const nodes: Node[] = Array.from({ length: 10 }, (_, i) => ({
225
+ id: `node-${i}`,
226
+ type: 'agent',
227
+ position: { x: 0, y: 0 },
228
+ data: { name: `Agent ${i}` },
229
+ }));
230
+
231
+ // Create a connected graph
232
+ const edges: Edge[] = Array.from({ length: 9 }, (_, i) => ({
233
+ id: `e${i}-${i + 1}`,
234
+ source: `node-${i}`,
235
+ target: `node-${i + 1}`,
236
+ }));
237
+
238
+ expect(() => {
239
+ const startTime = performance.now();
240
+ layoutService.applyHierarchicalLayout(nodes, edges);
241
+ const endTime = performance.now();
242
+ const duration = endTime - startTime;
243
+
244
+ // This will fail until implementation
245
+ expect(duration).toBeLessThan(200);
246
+ }).toThrow('Layout service not implemented');
247
+
248
+ // Expected behavior:
249
+ // const startTime = performance.now();
250
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges);
251
+ // const endTime = performance.now();
252
+ // const duration = endTime - startTime;
253
+ //
254
+ // expect(duration).toBeLessThan(200); // REQUIREMENT: <200ms for 10 nodes
255
+ // expect(result.nodes).toHaveLength(10);
256
+ });
257
+
258
+ it('should handle large graphs efficiently (50 nodes)', () => {
259
+ const nodes: Node[] = Array.from({ length: 50 }, (_, i) => ({
260
+ id: `node-${i}`,
261
+ type: 'agent',
262
+ position: { x: 0, y: 0 },
263
+ data: { name: `Agent ${i}` },
264
+ }));
265
+
266
+ // Create edges with some complexity (not just linear)
267
+ const edges: Edge[] = [];
268
+ for (let i = 0; i < 49; i++) {
269
+ edges.push({
270
+ id: `e${i}-${i + 1}`,
271
+ source: `node-${i}`,
272
+ target: `node-${i + 1}`,
273
+ });
274
+ // Add some cross-edges for complexity
275
+ if (i % 5 === 0 && i + 2 < 50) {
276
+ edges.push({
277
+ id: `e${i}-${i + 2}`,
278
+ source: `node-${i}`,
279
+ target: `node-${i + 2}`,
280
+ });
281
+ }
282
+ }
283
+
284
+ expect(() => {
285
+ const startTime = performance.now();
286
+ layoutService.applyHierarchicalLayout(nodes, edges);
287
+ const endTime = performance.now();
288
+ const duration = endTime - startTime;
289
+
290
+ // Should still be reasonably fast (<1s)
291
+ expect(duration).toBeLessThan(1000);
292
+ }).toThrow('Layout service not implemented');
293
+ });
294
+ });
295
+
296
+ describe('Edge Routing', () => {
297
+ it('should preserve edge connections after layout', () => {
298
+ const nodes: Node[] = [
299
+ { id: 'a', type: 'agent', position: { x: 0, y: 0 }, data: {} },
300
+ { id: 'b', type: 'agent', position: { x: 0, y: 0 }, data: {} },
301
+ { id: 'c', type: 'agent', position: { x: 0, y: 0 }, data: {} },
302
+ ];
303
+
304
+ const edges: Edge[] = [
305
+ { id: 'e-a-b', source: 'a', target: 'b' },
306
+ { id: 'e-b-c', source: 'b', target: 'c' },
307
+ ];
308
+
309
+ expect(() => {
310
+ layoutService.applyHierarchicalLayout(nodes, edges);
311
+ }).toThrow('Layout service not implemented');
312
+
313
+ // Expected behavior:
314
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges);
315
+ //
316
+ // // Edges should remain unchanged in structure
317
+ // expect(result.edges).toHaveLength(2);
318
+ // expect(result.edges.find(e => e.id === 'e-a-b')).toBeDefined();
319
+ // expect(result.edges.find(e => e.id === 'e-b-c')).toBeDefined();
320
+ //
321
+ // // Source and target should still match
322
+ // const edgeAB = result.edges.find(e => e.id === 'e-a-b')!;
323
+ // expect(edgeAB.source).toBe('a');
324
+ // expect(edgeAB.target).toBe('b');
325
+ });
326
+
327
+ it('should return layout dimensions (width, height)', () => {
328
+ const nodes: Node[] = [
329
+ { id: 'node-1', type: 'agent', position: { x: 0, y: 0 }, data: {} },
330
+ { id: 'node-2', type: 'agent', position: { x: 0, y: 0 }, data: {} },
331
+ ];
332
+
333
+ const edges: Edge[] = [
334
+ { id: 'e1-2', source: 'node-1', target: 'node-2' },
335
+ ];
336
+
337
+ expect(() => {
338
+ layoutService.applyHierarchicalLayout(nodes, edges);
339
+ }).toThrow('Layout service not implemented');
340
+
341
+ // Expected behavior:
342
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges);
343
+ //
344
+ // expect(result).toHaveProperty('width');
345
+ // expect(result).toHaveProperty('height');
346
+ // expect(typeof result.width).toBe('number');
347
+ // expect(typeof result.height).toBe('number');
348
+ // expect(result.width).toBeGreaterThan(0);
349
+ // expect(result.height).toBeGreaterThan(0);
350
+ });
351
+
352
+ it('should handle disconnected components', () => {
353
+ const nodes: Node[] = [
354
+ { id: 'a1', type: 'agent', position: { x: 0, y: 0 }, data: {} },
355
+ { id: 'a2', type: 'agent', position: { x: 0, y: 0 }, data: {} },
356
+ { id: 'b1', type: 'agent', position: { x: 0, y: 0 }, data: {} },
357
+ { id: 'b2', type: 'agent', position: { x: 0, y: 0 }, data: {} },
358
+ ];
359
+
360
+ const edges: Edge[] = [
361
+ { id: 'e-a1-a2', source: 'a1', target: 'a2' },
362
+ { id: 'e-b1-b2', source: 'b1', target: 'b2' },
363
+ // No edges between a* and b* - two separate components
364
+ ];
365
+
366
+ expect(() => {
367
+ layoutService.applyHierarchicalLayout(nodes, edges);
368
+ }).toThrow('Layout service not implemented');
369
+
370
+ // Expected behavior:
371
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges);
372
+ //
373
+ // // All nodes should still get positions
374
+ // expect(result.nodes).toHaveLength(4);
375
+ // result.nodes.forEach(node => {
376
+ // expect(Number.isFinite(node.position.x)).toBe(true);
377
+ // expect(Number.isFinite(node.position.y)).toBe(true);
378
+ // });
379
+ });
380
+ });
381
+
382
+ describe('Empty and Edge Cases', () => {
383
+ it('should handle empty node list', () => {
384
+ const nodes: Node[] = [];
385
+ const edges: Edge[] = [];
386
+
387
+ expect(() => {
388
+ layoutService.applyHierarchicalLayout(nodes, edges);
389
+ }).toThrow('Layout service not implemented');
390
+
391
+ // Expected behavior:
392
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges);
393
+ // expect(result.nodes).toHaveLength(0);
394
+ // expect(result.edges).toHaveLength(0);
395
+ });
396
+
397
+ it('should handle single node with no edges', () => {
398
+ const nodes: Node[] = [
399
+ { id: 'lone-node', type: 'agent', position: { x: 0, y: 0 }, data: {} },
400
+ ];
401
+ const edges: Edge[] = [];
402
+
403
+ expect(() => {
404
+ layoutService.applyHierarchicalLayout(nodes, edges);
405
+ }).toThrow('Layout service not implemented');
406
+
407
+ // Expected behavior:
408
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges);
409
+ // expect(result.nodes).toHaveLength(1);
410
+ // expect(result.nodes[0].position.x).toBeGreaterThanOrEqual(0);
411
+ // expect(result.nodes[0].position.y).toBeGreaterThanOrEqual(0);
412
+ });
413
+
414
+ it('should handle nodes with no connecting edges', () => {
415
+ const nodes: Node[] = [
416
+ { id: 'node-1', type: 'agent', position: { x: 0, y: 0 }, data: {} },
417
+ { id: 'node-2', type: 'agent', position: { x: 0, y: 0 }, data: {} },
418
+ { id: 'node-3', type: 'agent', position: { x: 0, y: 0 }, data: {} },
419
+ ];
420
+ const edges: Edge[] = [];
421
+
422
+ expect(() => {
423
+ layoutService.applyHierarchicalLayout(nodes, edges);
424
+ }).toThrow('Layout service not implemented');
425
+
426
+ // Expected behavior:
427
+ // const result = layoutService.applyHierarchicalLayout(nodes, edges);
428
+ // expect(result.nodes).toHaveLength(3);
429
+ //
430
+ // // All nodes should get valid positions
431
+ // result.nodes.forEach(node => {
432
+ // expect(Number.isFinite(node.position.x)).toBe(true);
433
+ // expect(Number.isFinite(node.position.y)).toBe(true);
434
+ // });
435
+ });
436
+ });
437
+ });