flock-core 0.1.2__py3-none-any.whl → 0.2.1__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 (405) hide show
  1. flock/__init__.py +1 -4
  2. flock/agents/__init__.py +0 -3
  3. flock/agents/batch_agent.py +140 -175
  4. flock/agents/loop_agent.py +117 -178
  5. flock/agents/trigger_agent.py +113 -191
  6. flock/agents/user_agent.py +145 -230
  7. flock/core/__init__.py +1 -7
  8. flock/core/context/context.py +211 -0
  9. flock/core/context/context_manager.py +34 -0
  10. flock/core/{context_vars.py → context/context_vars.py} +8 -6
  11. flock/core/execution/local_executor.py +27 -0
  12. flock/core/execution/temporal_executor.py +40 -0
  13. flock/core/flock.py +199 -208
  14. flock/core/flock_agent.py +492 -0
  15. flock/core/logging/__init__.py +2 -18
  16. flock/core/logging/formatters/base_formatter.py +36 -0
  17. flock/core/logging/formatters/formatter_factory.py +38 -0
  18. flock/core/logging/formatters/pprint_formatter.py +18 -0
  19. flock/core/logging/formatters/rich_formatters.py +132 -0
  20. flock/core/logging/formatters/theme_builder.py +480 -0
  21. flock/core/logging/formatters/themed_formatter.py +442 -0
  22. flock/core/logging/logging.py +123 -0
  23. flock/core/mixin/dspy_integration.py +171 -0
  24. flock/core/mixin/prompt_parser.py +125 -0
  25. flock/core/registry/agent_registry.py +103 -0
  26. flock/core/tools/basic_tools.py +273 -98
  27. flock/core/tools/dev_tools/github.py +161 -0
  28. flock/core/util/cli_helper.py +21 -0
  29. flock/core/util/input_resolver.py +156 -0
  30. flock/core/util/serializable.py +93 -0
  31. flock/themes/3024-day.toml +39 -0
  32. flock/themes/3024-night.toml +77 -0
  33. flock/themes/aardvark-blue.toml +77 -0
  34. flock/themes/abernathy.toml +77 -0
  35. flock/themes/adventure.toml +77 -0
  36. flock/themes/adventuretime.toml +77 -0
  37. flock/themes/afterglow.toml +77 -0
  38. flock/themes/alabaster.toml +77 -0
  39. flock/themes/alienblood.toml +77 -0
  40. flock/themes/andromeda.toml +77 -0
  41. flock/themes/apple-classic.toml +77 -0
  42. flock/themes/apple-system-colors.toml +77 -0
  43. flock/themes/arcoiris.toml +77 -0
  44. flock/themes/argonaut copy.toml +77 -0
  45. flock/themes/argonaut.toml +39 -0
  46. flock/themes/arthur.toml +77 -0
  47. flock/themes/ateliersulphurpool.toml +77 -0
  48. flock/themes/atom.toml +38 -0
  49. flock/themes/atom_test.toml +65 -0
  50. flock/themes/atomonelight.toml +77 -0
  51. flock/themes/aurora.toml +77 -0
  52. flock/themes/ayu copy.toml +77 -0
  53. flock/themes/ayu-light.toml +77 -0
  54. flock/themes/ayu-mirage.toml +77 -0
  55. flock/themes/ayu.toml +39 -0
  56. flock/themes/banana-blueberry.toml +77 -0
  57. flock/themes/batman.toml +77 -0
  58. flock/themes/belafonte-day.toml +77 -0
  59. flock/themes/belafonte-night.toml +77 -0
  60. flock/themes/birdsofparadise.toml +77 -0
  61. flock/themes/blazer.toml +77 -0
  62. flock/themes/blue-matrix.toml +77 -0
  63. flock/themes/blueberrypie.toml +77 -0
  64. flock/themes/bluedolphin.toml +77 -0
  65. flock/themes/blulocodark.toml +77 -0
  66. flock/themes/blulocolight.toml +77 -0
  67. flock/themes/borland.toml +77 -0
  68. flock/themes/breeze.toml +77 -0
  69. flock/themes/bright-lights.toml +77 -0
  70. flock/themes/broadcast.toml +77 -0
  71. flock/themes/brogrammer.toml +77 -0
  72. flock/themes/builtin-dark.toml +77 -0
  73. flock/themes/builtin-light.toml +77 -0
  74. flock/themes/builtin-pastel-dark.toml +77 -0
  75. flock/themes/builtin-solarized-dark.toml +77 -0
  76. flock/themes/builtin-solarized-light.toml +77 -0
  77. flock/themes/builtin-tango-dark.toml +77 -0
  78. flock/themes/builtin-tango-light.toml +77 -0
  79. flock/themes/c64.toml +77 -0
  80. flock/themes/calamity.toml +77 -0
  81. flock/themes/catppuccin-frappe.toml +77 -0
  82. flock/themes/catppuccin-latte.toml +77 -0
  83. flock/themes/catppuccin-macchiato.toml +77 -0
  84. flock/themes/catppuccin-mocha.toml +77 -0
  85. flock/themes/cga.toml +77 -0
  86. flock/themes/chalk.toml +77 -0
  87. flock/themes/chalkboard.toml +77 -0
  88. flock/themes/challengerdeep.toml +77 -0
  89. flock/themes/chester.toml +77 -0
  90. flock/themes/ciapre.toml +77 -0
  91. flock/themes/clrs.toml +77 -0
  92. flock/themes/cobalt-neon.toml +77 -0
  93. flock/themes/cobalt2.toml +77 -0
  94. flock/themes/coffee-theme.toml +77 -0
  95. flock/themes/crayonponyfish.toml +77 -0
  96. flock/themes/cutiepro.toml +77 -0
  97. flock/themes/cyberdyne.toml +77 -0
  98. flock/themes/cyberpunk.toml +77 -0
  99. flock/themes/cyberpunkscarletprotocol.toml +77 -0
  100. flock/themes/dark+.toml +77 -0
  101. flock/themes/dark-pastel.toml +77 -0
  102. flock/themes/darkermatrix.toml +77 -0
  103. flock/themes/darkmatrix.toml +77 -0
  104. flock/themes/darkside.toml +77 -0
  105. flock/themes/dayfox.toml +77 -0
  106. flock/themes/deep.toml +77 -0
  107. flock/themes/desert.toml +77 -0
  108. flock/themes/dimidium.toml +77 -0
  109. flock/themes/dimmedmonokai.toml +77 -0
  110. flock/themes/django.toml +77 -0
  111. flock/themes/djangorebornagain.toml +77 -0
  112. flock/themes/djangosmooth.toml +77 -0
  113. flock/themes/doom-peacock.toml +77 -0
  114. flock/themes/doomone.toml +77 -0
  115. flock/themes/dotgov.toml +77 -0
  116. flock/themes/dracula+.toml +77 -0
  117. flock/themes/dracula.toml +77 -0
  118. flock/themes/duckbones.toml +77 -0
  119. flock/themes/duotone-dark.toml +77 -0
  120. flock/themes/earthsong.toml +77 -0
  121. flock/themes/elemental.toml +77 -0
  122. flock/themes/elementary.toml +77 -0
  123. flock/themes/encom.toml +77 -0
  124. flock/themes/espresso-libre.toml +77 -0
  125. flock/themes/espresso.toml +77 -0
  126. flock/themes/everblush.toml +77 -0
  127. flock/themes/fahrenheit.toml +77 -0
  128. flock/themes/fairyfloss.toml +77 -0
  129. flock/themes/farmhouse-dark.toml +77 -0
  130. flock/themes/farmhouse-light.toml +77 -0
  131. flock/themes/fideloper.toml +77 -0
  132. flock/themes/firefly-traditional.toml +77 -0
  133. flock/themes/firefoxdev.toml +77 -0
  134. flock/themes/firewatch.toml +77 -0
  135. flock/themes/fishtank.toml +77 -0
  136. flock/themes/flat.toml +77 -0
  137. flock/themes/flatland.toml +77 -0
  138. flock/themes/flexoki-dark.toml +77 -0
  139. flock/themes/flexoki-light.toml +77 -0
  140. flock/themes/floraverse.toml +77 -0
  141. flock/themes/forestblue.toml +77 -0
  142. flock/themes/framer.toml +77 -0
  143. flock/themes/frontenddelight.toml +77 -0
  144. flock/themes/funforrest.toml +77 -0
  145. flock/themes/galaxy.toml +77 -0
  146. flock/themes/galizur.toml +77 -0
  147. flock/themes/github-dark.toml +77 -0
  148. flock/themes/github.toml +77 -0
  149. flock/themes/glacier.toml +77 -0
  150. flock/themes/grape.toml +77 -0
  151. flock/themes/grass.toml +77 -0
  152. flock/themes/grey-green.toml +77 -0
  153. flock/themes/gruber-darker.toml +77 -0
  154. flock/themes/gruvboxdark.toml +77 -0
  155. flock/themes/gruvboxdarkhard.toml +77 -0
  156. flock/themes/gruvboxlight.toml +77 -0
  157. flock/themes/guezwhoz.toml +77 -0
  158. flock/themes/hacktober.toml +77 -0
  159. flock/themes/hardcore.toml +77 -0
  160. flock/themes/harper.toml +77 -0
  161. flock/themes/hax0r-blue.toml +77 -0
  162. flock/themes/hax0r-gr33n.toml +77 -0
  163. flock/themes/hax0r-r3d.toml +77 -0
  164. flock/themes/highway.toml +77 -0
  165. flock/themes/hipster-green.toml +77 -0
  166. flock/themes/hivacruz.toml +77 -0
  167. flock/themes/homebrew.toml +77 -0
  168. flock/themes/hopscotch.256.toml +77 -0
  169. flock/themes/hopscotch.toml +77 -0
  170. flock/themes/hurtado.toml +77 -0
  171. flock/themes/hybrid.toml +77 -0
  172. flock/themes/ic-green-ppl.toml +77 -0
  173. flock/themes/ic-orange-ppl.toml +77 -0
  174. flock/themes/iceberg-dark.toml +77 -0
  175. flock/themes/iceberg-light.toml +77 -0
  176. flock/themes/idea.toml +77 -0
  177. flock/themes/idletoes.toml +77 -0
  178. flock/themes/ir-black.toml +77 -0
  179. flock/themes/iterm2-dark-background.toml +77 -0
  180. flock/themes/iterm2-default.toml +77 -0
  181. flock/themes/iterm2-light-background.toml +77 -0
  182. flock/themes/iterm2-pastel-dark-background.toml +77 -0
  183. flock/themes/iterm2-smoooooth.toml +77 -0
  184. flock/themes/iterm2-solarized-dark.toml +77 -0
  185. flock/themes/iterm2-solarized-light.toml +77 -0
  186. flock/themes/iterm2-tango-dark.toml +77 -0
  187. flock/themes/iterm2-tango-light.toml +77 -0
  188. flock/themes/jackie-brown.toml +77 -0
  189. flock/themes/japanesque.toml +77 -0
  190. flock/themes/jellybeans.toml +77 -0
  191. flock/themes/jetbrains-darcula.toml +77 -0
  192. flock/themes/jubi.toml +77 -0
  193. flock/themes/kanagawabones.toml +77 -0
  194. flock/themes/kibble.toml +77 -0
  195. flock/themes/kolorit.toml +77 -0
  196. flock/themes/konsolas.toml +77 -0
  197. flock/themes/kurokula.toml +77 -0
  198. flock/themes/lab-fox.toml +77 -0
  199. flock/themes/laser.toml +77 -0
  200. flock/themes/later-this-evening.toml +77 -0
  201. flock/themes/lavandula.toml +77 -0
  202. flock/themes/liquidcarbon.toml +77 -0
  203. flock/themes/liquidcarbontransparent.toml +77 -0
  204. flock/themes/liquidcarbontransparentinverse.toml +77 -0
  205. flock/themes/lovelace.toml +77 -0
  206. flock/themes/man-page.toml +77 -0
  207. flock/themes/mariana.toml +77 -0
  208. flock/themes/material.toml +77 -0
  209. flock/themes/materialdark.toml +77 -0
  210. flock/themes/materialdarker.toml +77 -0
  211. flock/themes/materialdesigncolors.toml +77 -0
  212. flock/themes/materialocean.toml +77 -0
  213. flock/themes/mathias.toml +77 -0
  214. flock/themes/matrix.toml +77 -0
  215. flock/themes/medallion.toml +77 -0
  216. flock/themes/mellifluous.toml +77 -0
  217. flock/themes/midnight-in-mojave.toml +77 -0
  218. flock/themes/mirage.toml +77 -0
  219. flock/themes/misterioso.toml +77 -0
  220. flock/themes/molokai.toml +77 -0
  221. flock/themes/monalisa.toml +77 -0
  222. flock/themes/monokai-remastered.toml +77 -0
  223. flock/themes/monokai-soda.toml +77 -0
  224. flock/themes/monokai-vivid.toml +77 -0
  225. flock/themes/n0tch2k.toml +77 -0
  226. flock/themes/neobones-dark.toml +77 -0
  227. flock/themes/neobones-light.toml +77 -0
  228. flock/themes/neon.toml +77 -0
  229. flock/themes/neopolitan.toml +77 -0
  230. flock/themes/neutron.toml +77 -0
  231. flock/themes/night-owlish-light.toml +77 -0
  232. flock/themes/nightfox.toml +77 -0
  233. flock/themes/nightlion-v1.toml +77 -0
  234. flock/themes/nightlion-v2.toml +77 -0
  235. flock/themes/niji.toml +77 -0
  236. flock/themes/nocturnal-winter.toml +77 -0
  237. flock/themes/nord-light.toml +77 -0
  238. flock/themes/nord.toml +77 -0
  239. flock/themes/novel.toml +77 -0
  240. flock/themes/nvimdark.toml +77 -0
  241. flock/themes/nvimlight.toml +77 -0
  242. flock/themes/obsidian.toml +77 -0
  243. flock/themes/ocean.toml +77 -0
  244. flock/themes/oceanic-next.toml +77 -0
  245. flock/themes/oceanicmaterial.toml +77 -0
  246. flock/themes/ollie.toml +77 -0
  247. flock/themes/onehalfdark.toml +77 -0
  248. flock/themes/onehalflight.toml +77 -0
  249. flock/themes/operator-mono-dark.toml +77 -0
  250. flock/themes/overnight-slumber.toml +77 -0
  251. flock/themes/oxocarbon.toml +77 -0
  252. flock/themes/palenighthc.toml +77 -0
  253. flock/themes/pandora.toml +77 -0
  254. flock/themes/paraiso-dark.toml +77 -0
  255. flock/themes/paulmillr.toml +77 -0
  256. flock/themes/pencildark.toml +77 -0
  257. flock/themes/pencillight.toml +77 -0
  258. flock/themes/peppermint.toml +77 -0
  259. flock/themes/piatto-light.toml +77 -0
  260. flock/themes/pnevma.toml +77 -0
  261. flock/themes/popping-and-locking.toml +77 -0
  262. flock/themes/primary.toml +77 -0
  263. flock/themes/pro-light.toml +77 -0
  264. flock/themes/pro.toml +77 -0
  265. flock/themes/purple-rain.toml +77 -0
  266. flock/themes/purplepeter.toml +77 -0
  267. flock/themes/rapture.toml +77 -0
  268. flock/themes/raycast-dark.toml +77 -0
  269. flock/themes/raycast-light.toml +77 -0
  270. flock/themes/rebecca.toml +77 -0
  271. flock/themes/red-alert.toml +77 -0
  272. flock/themes/red-planet.toml +77 -0
  273. flock/themes/red-sands.toml +77 -0
  274. flock/themes/relaxed.toml +77 -0
  275. flock/themes/retro.toml +77 -0
  276. flock/themes/rippedcasts.toml +77 -0
  277. flock/themes/rose-pine-dawn.toml +77 -0
  278. flock/themes/rose-pine-moon.toml +77 -0
  279. flock/themes/rose-pine.toml +77 -0
  280. flock/themes/rouge-2.toml +77 -0
  281. flock/themes/royal.toml +77 -0
  282. flock/themes/ryuuko.toml +77 -0
  283. flock/themes/sakura.toml +77 -0
  284. flock/themes/scarlet-protocol.toml +77 -0
  285. flock/themes/seafoam-pastel.toml +77 -0
  286. flock/themes/seashells.toml +77 -0
  287. flock/themes/seoulbones-dark.toml +77 -0
  288. flock/themes/seoulbones-light.toml +77 -0
  289. flock/themes/seti.toml +77 -0
  290. flock/themes/shades-of-purple.toml +77 -0
  291. flock/themes/shaman.toml +77 -0
  292. flock/themes/slate.toml +77 -0
  293. flock/themes/sleepyhollow.toml +77 -0
  294. flock/themes/smyck.toml +77 -0
  295. flock/themes/snazzy.toml +77 -0
  296. flock/themes/softserver.toml +77 -0
  297. flock/themes/solarized-darcula.toml +77 -0
  298. flock/themes/solarized-dark---patched.toml +77 -0
  299. flock/themes/solarized-dark-higher-contrast.toml +77 -0
  300. flock/themes/spacedust.toml +77 -0
  301. flock/themes/spacegray-eighties-dull.toml +77 -0
  302. flock/themes/spacegray-eighties.toml +77 -0
  303. flock/themes/spacegray.toml +77 -0
  304. flock/themes/spiderman.toml +77 -0
  305. flock/themes/spring.toml +77 -0
  306. flock/themes/square.toml +77 -0
  307. flock/themes/sublette.toml +77 -0
  308. flock/themes/subliminal.toml +77 -0
  309. flock/themes/sugarplum.toml +77 -0
  310. flock/themes/sundried.toml +77 -0
  311. flock/themes/symfonic.toml +77 -0
  312. flock/themes/synthwave-everything.toml +77 -0
  313. flock/themes/synthwave.toml +77 -0
  314. flock/themes/synthwavealpha.toml +77 -0
  315. flock/themes/tango-adapted.toml +77 -0
  316. flock/themes/tango-half-adapted.toml +77 -0
  317. flock/themes/teerb.toml +77 -0
  318. flock/themes/terafox.toml +77 -0
  319. flock/themes/terminal-basic.toml +77 -0
  320. flock/themes/thayer-bright.toml +77 -0
  321. flock/themes/the-hulk.toml +77 -0
  322. flock/themes/tinacious-design-(dark).toml +77 -0
  323. flock/themes/tinacious-design-(light).toml +77 -0
  324. flock/themes/tokyonight-day.toml +77 -0
  325. flock/themes/tokyonight-storm.toml +77 -0
  326. flock/themes/tokyonight.toml +77 -0
  327. flock/themes/tomorrow-night-blue.toml +77 -0
  328. flock/themes/tomorrow-night-bright.toml +77 -0
  329. flock/themes/tomorrow-night-burns.toml +77 -0
  330. flock/themes/tomorrow-night-eighties.toml +77 -0
  331. flock/themes/tomorrow-night.toml +77 -0
  332. flock/themes/tomorrow.toml +77 -0
  333. flock/themes/toychest.toml +77 -0
  334. flock/themes/treehouse.toml +77 -0
  335. flock/themes/twilight.toml +77 -0
  336. flock/themes/ubuntu.toml +77 -0
  337. flock/themes/ultradark.toml +77 -0
  338. flock/themes/ultraviolent.toml +77 -0
  339. flock/themes/underthesea.toml +77 -0
  340. flock/themes/unikitty.toml +77 -0
  341. flock/themes/urple.toml +77 -0
  342. flock/themes/vaughn.toml +77 -0
  343. flock/themes/vesper.toml +77 -0
  344. flock/themes/vibrantink.toml +77 -0
  345. flock/themes/vimbones.toml +77 -0
  346. flock/themes/violet-dark.toml +77 -0
  347. flock/themes/violet-light.toml +77 -0
  348. flock/themes/warmneon.toml +77 -0
  349. flock/themes/wez.toml +77 -0
  350. flock/themes/whimsy.toml +77 -0
  351. flock/themes/wildcherry.toml +77 -0
  352. flock/themes/wilmersdorf.toml +77 -0
  353. flock/themes/wombat.toml +77 -0
  354. flock/themes/wryan.toml +77 -0
  355. flock/themes/xcodedark.toml +77 -0
  356. flock/themes/xcodedarkhc.toml +77 -0
  357. flock/themes/xcodelight.toml +77 -0
  358. flock/themes/xcodelighthc.toml +77 -0
  359. flock/themes/xcodewwdc.toml +77 -0
  360. flock/themes/zenbones-dark.toml +77 -0
  361. flock/themes/zenbones-light.toml +77 -0
  362. flock/themes/zenbones.toml +77 -0
  363. flock/themes/zenburn.toml +77 -0
  364. flock/themes/zenburned.toml +77 -0
  365. flock/themes/zenwritten-dark.toml +77 -0
  366. flock/themes/zenwritten-light.toml +77 -0
  367. flock/workflow/activities.py +117 -115
  368. flock/workflow/agent_activities.py +24 -26
  369. flock/workflow/temporal_setup.py +38 -37
  370. flock/workflow/workflow.py +58 -53
  371. flock_core-0.2.1.dist-info/METADATA +287 -0
  372. flock_core-0.2.1.dist-info/RECORD +375 -0
  373. {flock_core-0.1.2.dist-info → flock_core-0.2.1.dist-info}/licenses/LICENSE +21 -21
  374. flock/agents/declarative_agent.py +0 -166
  375. flock/app/components/__init__.py +0 -14
  376. flock/app/components/charts/agent_workflow.py +0 -14
  377. flock/app/components/charts/core_architecture.py +0 -14
  378. flock/app/components/charts/tool_system.py +0 -14
  379. flock/app/components/history_grid.py +0 -168
  380. flock/app/components/history_grid_alt.py +0 -189
  381. flock/app/components/sidebar.py +0 -19
  382. flock/app/components/theme.py +0 -9
  383. flock/app/components/util.py +0 -18
  384. flock/app/hive_app.py +0 -118
  385. flock/app/html/d3.html +0 -179
  386. flock/app/modules/__init__.py +0 -12
  387. flock/app/modules/about.py +0 -17
  388. flock/app/modules/agent_detail.py +0 -70
  389. flock/app/modules/agent_list.py +0 -59
  390. flock/app/modules/playground.py +0 -322
  391. flock/app/modules/settings.py +0 -96
  392. flock/core/agent.py +0 -150
  393. flock/core/agent_registry.py +0 -162
  394. flock/core/context.py +0 -279
  395. flock/core/handoff/handoff_base.py +0 -12
  396. flock/core/logging/error_handler.py +0 -84
  397. flock/core/logging/formatters.py +0 -122
  398. flock/core/logging/handlers.py +0 -117
  399. flock/core/logging/logger.py +0 -107
  400. flock/core/serializable.py +0 -206
  401. flock_core-0.1.2.dist-info/METADATA +0 -476
  402. flock_core-0.1.2.dist-info/RECORD +0 -48
  403. flock_core-0.1.2.dist-info/entry_points.txt +0 -2
  404. /flock/{core/config/declarative_agent_config.py → workflow/__init__.py} +0 -0
  405. {flock_core-0.1.2.dist-info → flock_core-0.2.1.dist-info}/WHEEL +0 -0
flock/__init__.py CHANGED
@@ -1,4 +1 @@
1
- # Initialize error handling through our custom handler
2
- from flock.core.logging import error_handler
3
-
4
- error_handler.install()
1
+ """Flock package initialization."""
flock/agents/__init__.py CHANGED
@@ -1,3 +0,0 @@
1
- from flock.agents.declarative_agent import DeclarativeAgent
2
-
3
- __all__ = ["DeclarativeAgent"]
@@ -1,175 +1,140 @@
1
- import asyncio
2
- import uuid
3
- from typing import Any
4
-
5
- from pydantic import Field
6
-
7
- from flock.core.context import FlockContext
8
- from flock.core.logging import flock_logger, live_update_handler, performance_handler
9
-
10
- from .declarative_agent import DeclarativeAgent
11
-
12
-
13
- class BatchAgent(DeclarativeAgent):
14
- """A DeclarativeAgent that processes an iterable input in batches.
15
-
16
- Additional Attributes:
17
- iter_input: The key in the FlockContext that holds the iterable (a list).
18
- batch_site: The number of items per batch.
19
-
20
- For each batch, the agent’s input dictionary is built from the FlockContext with the
21
- value for the iter_input key overridden by the current batch. The outputs across batches
22
- are then aggregated.
23
- """
24
-
25
- iter_input: str = Field(default="", description="Key of the iterable input (must be a list in the FlockContext)")
26
- batch_size: int = Field(default=1, description="Batch size (number of items per batch)")
27
-
28
- async def run(self, context: FlockContext) -> dict:
29
- """Run the BatchAgent locally by partitioning the iterable and aggregating the results."""
30
- try:
31
- with performance_handler.track_time("batch_preparation"):
32
- flock_logger.info(f"Starting batch processing for agent: {self.name}")
33
- iterable = context.get_variable(self.iter_input)
34
- if not isinstance(iterable, list):
35
- error_msg = f"Expected a list for key '{self.iter_input}' in context."
36
- flock_logger.error(error_msg)
37
- return {"error": error_msg}
38
-
39
- # Partition the iterable into batches
40
- batches: list[list[Any]] = [
41
- iterable[i : i + self.batch_size] for i in range(0, len(iterable), self.batch_size)
42
- ]
43
- num_batches = len(batches)
44
- flock_logger.info(
45
- "Prepared batches",
46
- total_items=len(iterable),
47
- batch_size=self.batch_size,
48
- num_batches=num_batches,
49
- )
50
-
51
- # Process batches with progress tracking
52
- with live_update_handler.progress_tracker(f"Processing {num_batches} batches") as update_progress:
53
- tasks = []
54
- for i, batch in enumerate(batches):
55
- flock_logger.debug(f"Creating task for batch {i + 1}/{num_batches}", batch_size=len(batch))
56
- tasks.append(self._evaluate(context, input_overrides={self.iter_input: batch}))
57
- update_progress((i + 1) * 100 / num_batches)
58
-
59
- with performance_handler.track_time("batch_processing"):
60
- batch_results = await asyncio.gather(*tasks)
61
- flock_logger.success(f"Completed processing {num_batches} batches")
62
-
63
- # Aggregate the outputs
64
- with performance_handler.track_time("result_aggregation"):
65
- flock_logger.info("Aggregating batch results")
66
- output_keys = self._parse_keys(self.output)
67
- aggregated = {key: [] for key in output_keys}
68
- for i, res in enumerate(batch_results):
69
- flock_logger.debug(f"Aggregating results from batch {i + 1}/{num_batches}")
70
- for key in output_keys:
71
- aggregated[key].append(res.get(key))
72
- aggregated["batch_results"] = batch_results
73
- flock_logger.success("Successfully aggregated all batch results")
74
- return aggregated
75
-
76
- except Exception as e:
77
- flock_logger.error(
78
- "Batch processing failed",
79
- error=str(e),
80
- agent=self.name,
81
- iter_input=self.iter_input,
82
- )
83
- raise
84
-
85
- async def run_temporal(self, context: FlockContext) -> dict:
86
- """Run the BatchAgent via Temporal.
87
-
88
- For each batch, the agent's evaluation is performed as a separate Temporal activity.
89
- The results are then aggregated.
90
- """
91
- try:
92
- with performance_handler.track_time("temporal_setup"):
93
- flock_logger.info(f"Starting temporal batch processing for agent: {self.name}")
94
-
95
- from temporalio.client import Client
96
-
97
- from flock.workflow.agent_activities import run_declarative_agent_activity
98
- from flock.workflow.temporal_setup import run_activity
99
-
100
- # Connect to Temporal
101
- flock_logger.info("Connecting to Temporal service...")
102
- client = await Client.connect("localhost:7233", namespace="default")
103
-
104
- # Validate and prepare input
105
- iterable = context.get_variable(self.iter_input)
106
- if not isinstance(iterable, list):
107
- error_msg = f"Expected a list for key '{self.iter_input}' in context."
108
- flock_logger.error(error_msg)
109
- return {"error": error_msg}
110
-
111
- # Partition into batches
112
- batches: list[list[Any]] = [
113
- iterable[i : i + self.batch_size] for i in range(0, len(iterable), self.batch_size)
114
- ]
115
- num_batches = len(batches)
116
- flock_logger.info(
117
- "Prepared batches for temporal processing",
118
- total_items=len(iterable),
119
- batch_size=self.batch_size,
120
- num_batches=num_batches,
121
- )
122
-
123
- # Process batches with status updates
124
- with live_update_handler.update_workflow_status(
125
- self.name, "Running", {"phase": "batch_processing", "total_batches": num_batches}
126
- ):
127
- tasks = []
128
- for i, batch in enumerate(batches):
129
- flock_logger.debug(f"Creating temporal task for batch {i + 1}/{num_batches}", batch_size=len(batch))
130
- # Prepare context for this batch
131
- new_state = context.state.copy()
132
- new_state[self.iter_input] = batch
133
- context_data = {
134
- "state": new_state,
135
- "history": [], # you might choose to pass along history if needed
136
- "agent_definitions": [],
137
- }
138
- agent_data = self.dict()
139
- task_id = f"{self.name}_{uuid.uuid4().hex[:4]}"
140
-
141
- # Create temporal activity task
142
- tasks.append(
143
- run_activity(
144
- client,
145
- task_id,
146
- run_declarative_agent_activity,
147
- {"agent_data": agent_data, "context_data": context_data},
148
- )
149
- )
150
-
151
- with performance_handler.track_time("temporal_batch_processing"):
152
- batch_results = await asyncio.gather(*tasks)
153
- flock_logger.success(f"Completed temporal processing of {num_batches} batches")
154
-
155
- # Aggregate the outputs
156
- with performance_handler.track_time("temporal_result_aggregation"):
157
- flock_logger.info("Aggregating temporal batch results")
158
- output_keys = self._parse_keys(self.output)
159
- aggregated = {key: [] for key in output_keys}
160
- for i, res in enumerate(batch_results):
161
- flock_logger.debug(f"Aggregating results from temporal batch {i + 1}/{num_batches}")
162
- for key in output_keys:
163
- aggregated[key].append(res.get(key))
164
- aggregated["batch_results"] = batch_results
165
- flock_logger.success("Successfully aggregated all temporal batch results")
166
- return aggregated
167
-
168
- except Exception as e:
169
- flock_logger.error(
170
- "Temporal batch processing failed",
171
- error=str(e),
172
- agent=self.name,
173
- iter_input=self.iter_input,
174
- )
175
- raise
1
+ import asyncio
2
+ import uuid
3
+ from typing import Any
4
+
5
+ from pydantic import Field
6
+
7
+ from flock.core.context.context import FlockContext
8
+ from flock.core.flock_agent import FlockAgent
9
+
10
+
11
+ class BatchAgent(FlockAgent):
12
+ """A DeclarativeAgent that processes an iterable input in batches.
13
+
14
+ Additional Attributes:
15
+ iter_input: The key in the FlockContext that holds the iterable (a list).
16
+ batch_site: The number of items per batch.
17
+
18
+ For each batch, the agent's input dictionary is built from the FlockContext with the
19
+ value for the iter_input key overridden by the current batch. The outputs across batches
20
+ are then aggregated.
21
+ """
22
+
23
+ iter_input: str = Field(
24
+ default="",
25
+ description="Key of the iterable input (must be a list in the FlockContext)",
26
+ )
27
+ batch_size: int = Field(
28
+ default=1, description="Batch size (number of items per batch)"
29
+ )
30
+
31
+ async def run(self, context: FlockContext) -> dict:
32
+ """Run the BatchAgent locally by partitioning the iterable and aggregating the results."""
33
+ try:
34
+ iterable = context.get_variable(self.iter_input)
35
+ if not isinstance(iterable, list):
36
+ error_msg = (
37
+ f"Expected a list for key '{self.iter_input}' in context."
38
+ )
39
+ return {"error": error_msg}
40
+
41
+ # Partition the iterable into batches
42
+ batches: list[list[Any]] = [
43
+ iterable[i : i + self.batch_size]
44
+ for i in range(0, len(iterable), self.batch_size)
45
+ ]
46
+
47
+ # Process batches
48
+ tasks = []
49
+ for batch in batches:
50
+ tasks.append(
51
+ self.evaluate(
52
+ context, input_overrides={self.iter_input: batch}
53
+ )
54
+ )
55
+
56
+ batch_results = await asyncio.gather(*tasks)
57
+
58
+ # Aggregate the outputs
59
+ output_keys = self._parse_keys(self.output)
60
+ aggregated = {key: [] for key in output_keys}
61
+ for res in batch_results:
62
+ for key in output_keys:
63
+ aggregated[key].append(res.get(key))
64
+ aggregated["batch_results"] = batch_results
65
+ return aggregated
66
+
67
+ except Exception:
68
+ raise
69
+
70
+ async def run_temporal(self, context: FlockContext) -> dict:
71
+ """Run the BatchAgent via Temporal.
72
+
73
+ For each batch, the agent's evaluation is performed as a separate Temporal activity.
74
+ The results are then aggregated.
75
+ """
76
+ try:
77
+ from temporalio.client import Client
78
+
79
+ from flock.workflow.agent_activities import (
80
+ run_declarative_agent_activity,
81
+ )
82
+ from flock.workflow.temporal_setup import run_activity
83
+
84
+ # Connect to Temporal
85
+ client = await Client.connect("localhost:7233", namespace="default")
86
+
87
+ # Validate and prepare input
88
+ iterable = context.get_variable(self.iter_input)
89
+ if not isinstance(iterable, list):
90
+ error_msg = (
91
+ f"Expected a list for key '{self.iter_input}' in context."
92
+ )
93
+ return {"error": error_msg}
94
+
95
+ # Partition into batches
96
+ batches: list[list[Any]] = [
97
+ iterable[i : i + self.batch_size]
98
+ for i in range(0, len(iterable), self.batch_size)
99
+ ]
100
+
101
+ # Process batches
102
+ tasks = []
103
+ for batch in batches:
104
+ # Prepare context for this batch
105
+ new_state = context.state.copy()
106
+ new_state[self.iter_input] = batch
107
+ context_data = {
108
+ "state": new_state,
109
+ "history": [], # you might choose to pass along history if needed
110
+ "agent_definitions": [],
111
+ }
112
+ agent_data = self.dict()
113
+ task_id = f"{self.name}_{uuid.uuid4().hex[:4]}"
114
+
115
+ # Create temporal activity task
116
+ tasks.append(
117
+ run_activity(
118
+ client,
119
+ task_id,
120
+ run_declarative_agent_activity,
121
+ {
122
+ "agent_data": agent_data,
123
+ "context_data": context_data,
124
+ },
125
+ )
126
+ )
127
+
128
+ batch_results = await asyncio.gather(*tasks)
129
+
130
+ # Aggregate the outputs
131
+ output_keys = self._parse_keys(self.output)
132
+ aggregated = {key: [] for key in output_keys}
133
+ for res in batch_results:
134
+ for key in output_keys:
135
+ aggregated[key].append(res.get(key))
136
+ aggregated["batch_results"] = batch_results
137
+ return aggregated
138
+
139
+ except Exception:
140
+ raise
@@ -1,178 +1,117 @@
1
- from collections.abc import Callable
2
- from typing import Any
3
-
4
- from pydantic import Field
5
-
6
- from flock.core.agent import Agent
7
- from flock.core.context import FlockContext
8
- from flock.core.logging import flock_logger, live_update_handler, performance_handler
9
-
10
-
11
- class LoopAgent(Agent):
12
- """An agent that executes its logic in a loop until a termination condition is met.
13
-
14
- Attributes:
15
- input: Input domain for the agent
16
- output: Output types for the agent
17
- tools: Tools the agent is allowed to use
18
- max_iterations: Maximum number of iterations before forced termination
19
- termination_condition: Optional callable that determines when to stop the loop
20
- """
21
-
22
- input: str = Field(default="", description="Input domain for the agent")
23
- output: str = Field(default="", description="Output types for the agent")
24
- tools: list[Callable] | None = Field(default=None, description="Tools the agent is allowed to use")
25
- max_iterations: int = Field(default=10, description="Maximum number of iterations")
26
- termination_condition: Callable[[dict[str, Any]], bool] | None = Field(
27
- default=None, description="Optional function to determine loop termination"
28
- )
29
-
30
- async def _process_iteration(self, context: FlockContext, iteration: int) -> dict[str, Any]:
31
- """Process a single iteration of the loop."""
32
- try:
33
- with performance_handler.track_time(f"iteration_{iteration}"):
34
- flock_logger.debug(f"Processing iteration {iteration}", agent=self.name)
35
- # Here you would implement the actual iteration logic
36
- # For now, we'll just return a simple result
37
- return {"iteration": iteration, "status": "completed"}
38
- except Exception as e:
39
- flock_logger.error(
40
- f"Error in iteration {iteration}",
41
- error=str(e),
42
- agent=self.name,
43
- )
44
- raise
45
-
46
- def _should_continue(self, result: dict[str, Any], iteration: int) -> bool:
47
- """Determine if the loop should continue."""
48
- if iteration >= self.max_iterations:
49
- flock_logger.warning(
50
- "Maximum iterations reached",
51
- max_iterations=self.max_iterations,
52
- agent=self.name,
53
- )
54
- return False
55
-
56
- if self.termination_condition:
57
- should_terminate = self.termination_condition(result)
58
- if should_terminate:
59
- flock_logger.info(
60
- "Termination condition met",
61
- iteration=iteration,
62
- agent=self.name,
63
- )
64
- return not should_terminate
65
-
66
- return True
67
-
68
- async def run(self, context: FlockContext) -> dict[str, Any]:
69
- """Run the agent in a loop until the termination condition is met or max iterations reached."""
70
- try:
71
- flock_logger.info(f"Starting loop agent: {self.name}")
72
- results = []
73
- iteration = 0
74
-
75
- with live_update_handler.progress_tracker("Loop Progress") as update_progress:
76
- while True:
77
- # Update progress based on iteration count
78
- progress = min((iteration + 1) * 100 / self.max_iterations, 100)
79
- update_progress(progress)
80
-
81
- # Process iteration with status tracking
82
- with live_update_handler.update_activity_status(
83
- f"{self.name}_iteration_{iteration}",
84
- f"Iteration {iteration + 1}",
85
- "Running",
86
- {"max_iterations": self.max_iterations},
87
- ):
88
- result = await self._process_iteration(context, iteration)
89
- results.append(result)
90
-
91
- # Check termination conditions
92
- if not self._should_continue(result, iteration):
93
- break
94
-
95
- iteration += 1
96
-
97
- flock_logger.success(
98
- f"Loop completed successfully",
99
- total_iterations=iteration + 1,
100
- agent=self.name,
101
- )
102
- return {
103
- "iterations": iteration + 1,
104
- "results": results,
105
- "final_result": results[-1] if results else None,
106
- }
107
-
108
- except Exception as e:
109
- flock_logger.error(
110
- "Loop execution failed",
111
- error=str(e),
112
- agent=self.name,
113
- iteration=iteration,
114
- )
115
- raise
116
-
117
- async def run_temporal(self, context: FlockContext) -> dict[str, Any]:
118
- """Run the loop agent via Temporal."""
119
- try:
120
- from temporalio.client import Client
121
-
122
- from flock.workflow.agent_activities import run_agent_activity
123
- from flock.workflow.temporal_setup import run_activity
124
-
125
- with performance_handler.track_time("temporal_setup"):
126
- flock_logger.info(f"Starting temporal loop agent: {self.name}")
127
- client = await Client.connect("localhost:7233", namespace="default")
128
-
129
- results = []
130
- iteration = 0
131
-
132
- with live_update_handler.update_workflow_status(
133
- self.name, "Running", {"phase": "loop_execution", "max_iterations": self.max_iterations}
134
- ):
135
- while True:
136
- # Process iteration as a temporal activity
137
- with performance_handler.track_time(f"temporal_iteration_{iteration}"):
138
- context_data = {
139
- "state": context.state,
140
- "history": [record.__dict__ for record in context.history],
141
- "agent_definitions": [definition.__dict__ for definition in context.agent_definitions],
142
- }
143
- agent_data = self.dict()
144
-
145
- flock_logger.info(f"Starting temporal iteration {iteration + 1}")
146
- result = await run_activity(
147
- client,
148
- f"{self.name}_iteration_{iteration}",
149
- run_agent_activity,
150
- {"agent_data": agent_data, "context_data": context_data},
151
- )
152
- results.append(result)
153
-
154
- # Check termination conditions
155
- if not self._should_continue(result, iteration):
156
- break
157
-
158
- iteration += 1
159
-
160
- flock_logger.success(
161
- "Temporal loop completed successfully",
162
- total_iterations=iteration + 1,
163
- agent=self.name,
164
- )
165
- return {
166
- "iterations": iteration + 1,
167
- "results": results,
168
- "final_result": results[-1] if results else None,
169
- }
170
-
171
- except Exception as e:
172
- flock_logger.error(
173
- "Temporal loop execution failed",
174
- error=str(e),
175
- agent=self.name,
176
- iteration=iteration,
177
- )
178
- raise
1
+ from collections.abc import Callable
2
+ from typing import Any
3
+
4
+ from pydantic import Field
5
+
6
+ from flock.core.context.context import FlockContext
7
+ from flock.core.flock_agent import FlockAgent
8
+
9
+
10
+ class LoopAgent(FlockAgent):
11
+ """An agent that executes its logic in a loop until a termination condition is met.
12
+
13
+ Attributes:
14
+ input: Input domain for the agent
15
+ output: Output types for the agent
16
+ tools: Tools the agent is allowed to use
17
+ max_iterations: Maximum number of iterations before forced termination
18
+ termination_condition: Optional callable that determines when to stop the loop
19
+ """
20
+
21
+ input: str = Field(default="", description="Input domain for the agent")
22
+ output: str = Field(default="", description="Output types for the agent")
23
+ tools: list[Callable] | None = Field(default=None, description="Tools the agent is allowed to use")
24
+ max_iterations: int = Field(default=10, description="Maximum number of iterations")
25
+ termination_condition: Callable[[dict[str, Any]], bool] | None = Field(
26
+ default=None, description="Optional function to determine loop termination"
27
+ )
28
+
29
+ async def _process_iteration(self, context: FlockContext, iteration: int) -> dict[str, Any]:
30
+ """Process a single iteration of the loop."""
31
+ try:
32
+ # Here you would implement the actual iteration logic
33
+ # For now, we'll just return a simple result
34
+ return {"iteration": iteration, "status": "completed"}
35
+ except Exception:
36
+ raise
37
+
38
+ def _should_continue(self, result: dict[str, Any], iteration: int) -> bool:
39
+ """Determine if the loop should continue."""
40
+ if iteration >= self.max_iterations:
41
+ return False
42
+
43
+ if self.termination_condition:
44
+ should_terminate = self.termination_condition(result)
45
+ return not should_terminate
46
+
47
+ return True
48
+
49
+ async def run(self, context: FlockContext) -> dict[str, Any]:
50
+ """Run the agent in a loop until the termination condition is met or max iterations reached."""
51
+ try:
52
+ results = []
53
+ iteration = 0
54
+
55
+ while True:
56
+ result = await self._process_iteration(context, iteration)
57
+ results.append(result)
58
+
59
+ # Check termination conditions
60
+ if not self._should_continue(result, iteration):
61
+ break
62
+
63
+ iteration += 1
64
+
65
+ return {
66
+ "iterations": iteration + 1,
67
+ "results": results,
68
+ "final_result": results[-1] if results else None,
69
+ }
70
+
71
+ except Exception:
72
+ raise
73
+
74
+ async def run_temporal(self, context: FlockContext) -> dict[str, Any]:
75
+ """Run the loop agent via Temporal."""
76
+ try:
77
+ from temporalio.client import Client
78
+
79
+ from flock.workflow.agent_activities import run_agent_activity
80
+ from flock.workflow.temporal_setup import run_activity
81
+
82
+ client = await Client.connect("localhost:7233", namespace="default")
83
+
84
+ results = []
85
+ iteration = 0
86
+
87
+ while True:
88
+ # Process iteration as a temporal activity
89
+ context_data = {
90
+ "state": context.state,
91
+ "history": [record.__dict__ for record in context.history],
92
+ "agent_definitions": [definition.__dict__ for definition in context.agent_definitions],
93
+ }
94
+ agent_data = self.dict()
95
+
96
+ result = await run_activity(
97
+ client,
98
+ f"{self.name}_iteration_{iteration}",
99
+ run_agent_activity,
100
+ {"agent_data": agent_data, "context_data": context_data},
101
+ )
102
+ results.append(result)
103
+
104
+ # Check termination conditions
105
+ if not self._should_continue(result, iteration):
106
+ break
107
+
108
+ iteration += 1
109
+
110
+ return {
111
+ "iterations": iteration + 1,
112
+ "results": results,
113
+ "final_result": results[-1] if results else None,
114
+ }
115
+
116
+ except Exception:
117
+ raise