flock-core 0.1.2__py3-none-any.whl → 0.2.2__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 (407) hide show
  1. flock/__init__.py +1 -4
  2. flock/core/__init__.py +1 -7
  3. flock/core/context/context.py +182 -0
  4. flock/core/context/context_manager.py +34 -0
  5. flock/core/{context_vars.py → context/context_vars.py} +8 -6
  6. flock/core/execution/local_executor.py +27 -0
  7. flock/core/execution/temporal_executor.py +56 -0
  8. flock/core/flock.py +232 -208
  9. flock/core/flock_agent.py +574 -0
  10. flock/core/logging/__init__.py +2 -18
  11. flock/core/logging/formatters/base_formatter.py +36 -0
  12. flock/core/logging/formatters/formatter_factory.py +38 -0
  13. flock/core/logging/formatters/pprint_formatter.py +18 -0
  14. flock/core/logging/formatters/rich_formatters.py +132 -0
  15. flock/core/logging/formatters/theme_builder.py +480 -0
  16. flock/core/logging/formatters/themed_formatter.py +442 -0
  17. flock/core/logging/logging.py +141 -0
  18. flock/core/logging/telemetry.py +21 -0
  19. flock/core/logging/trace_and_logged.py +55 -0
  20. flock/core/mixin/dspy_integration.py +197 -0
  21. flock/core/mixin/prompt_parser.py +125 -0
  22. flock/core/registry/agent_registry.py +118 -0
  23. flock/core/tools/basic_tools.py +296 -98
  24. flock/core/tools/dev_tools/github.py +190 -0
  25. flock/core/util/cli_helper.py +25 -0
  26. flock/core/util/input_resolver.py +156 -0
  27. flock/core/util/serializable.py +93 -0
  28. flock/themes/3024-day.toml +39 -0
  29. flock/themes/3024-night.toml +77 -0
  30. flock/themes/aardvark-blue.toml +77 -0
  31. flock/themes/abernathy.toml +77 -0
  32. flock/themes/adventure.toml +77 -0
  33. flock/themes/adventuretime.toml +77 -0
  34. flock/themes/afterglow.toml +77 -0
  35. flock/themes/alabaster.toml +77 -0
  36. flock/themes/alienblood.toml +77 -0
  37. flock/themes/andromeda.toml +77 -0
  38. flock/themes/apple-classic.toml +77 -0
  39. flock/themes/apple-system-colors.toml +77 -0
  40. flock/themes/arcoiris.toml +77 -0
  41. flock/themes/argonaut copy.toml +77 -0
  42. flock/themes/argonaut.toml +39 -0
  43. flock/themes/arthur.toml +77 -0
  44. flock/themes/ateliersulphurpool.toml +77 -0
  45. flock/themes/atom.toml +38 -0
  46. flock/themes/atom_test.toml +65 -0
  47. flock/themes/atomonelight.toml +77 -0
  48. flock/themes/aurora.toml +77 -0
  49. flock/themes/ayu copy.toml +77 -0
  50. flock/themes/ayu-light.toml +77 -0
  51. flock/themes/ayu-mirage.toml +77 -0
  52. flock/themes/ayu.toml +39 -0
  53. flock/themes/banana-blueberry.toml +77 -0
  54. flock/themes/batman.toml +77 -0
  55. flock/themes/belafonte-day.toml +77 -0
  56. flock/themes/belafonte-night.toml +77 -0
  57. flock/themes/birdsofparadise.toml +77 -0
  58. flock/themes/blazer.toml +77 -0
  59. flock/themes/blue-matrix.toml +77 -0
  60. flock/themes/blueberrypie.toml +77 -0
  61. flock/themes/bluedolphin.toml +77 -0
  62. flock/themes/blulocodark.toml +77 -0
  63. flock/themes/blulocolight.toml +77 -0
  64. flock/themes/borland.toml +77 -0
  65. flock/themes/breeze.toml +77 -0
  66. flock/themes/bright-lights.toml +77 -0
  67. flock/themes/broadcast.toml +77 -0
  68. flock/themes/brogrammer.toml +77 -0
  69. flock/themes/builtin-dark.toml +77 -0
  70. flock/themes/builtin-light.toml +77 -0
  71. flock/themes/builtin-pastel-dark.toml +77 -0
  72. flock/themes/builtin-solarized-dark.toml +77 -0
  73. flock/themes/builtin-solarized-light.toml +77 -0
  74. flock/themes/builtin-tango-dark.toml +77 -0
  75. flock/themes/builtin-tango-light.toml +77 -0
  76. flock/themes/c64.toml +77 -0
  77. flock/themes/calamity.toml +77 -0
  78. flock/themes/catppuccin-frappe.toml +77 -0
  79. flock/themes/catppuccin-latte.toml +77 -0
  80. flock/themes/catppuccin-macchiato.toml +77 -0
  81. flock/themes/catppuccin-mocha.toml +77 -0
  82. flock/themes/cga.toml +77 -0
  83. flock/themes/chalk.toml +77 -0
  84. flock/themes/chalkboard.toml +77 -0
  85. flock/themes/challengerdeep.toml +77 -0
  86. flock/themes/chester.toml +77 -0
  87. flock/themes/ciapre.toml +77 -0
  88. flock/themes/clrs.toml +77 -0
  89. flock/themes/cobalt-neon.toml +77 -0
  90. flock/themes/cobalt2.toml +77 -0
  91. flock/themes/coffee-theme.toml +77 -0
  92. flock/themes/crayonponyfish.toml +77 -0
  93. flock/themes/cutiepro.toml +77 -0
  94. flock/themes/cyberdyne.toml +77 -0
  95. flock/themes/cyberpunk.toml +77 -0
  96. flock/themes/cyberpunkscarletprotocol.toml +77 -0
  97. flock/themes/dark+.toml +77 -0
  98. flock/themes/dark-pastel.toml +77 -0
  99. flock/themes/darkermatrix.toml +77 -0
  100. flock/themes/darkmatrix.toml +77 -0
  101. flock/themes/darkside.toml +77 -0
  102. flock/themes/dayfox.toml +77 -0
  103. flock/themes/deep.toml +77 -0
  104. flock/themes/desert.toml +77 -0
  105. flock/themes/dimidium.toml +77 -0
  106. flock/themes/dimmedmonokai.toml +77 -0
  107. flock/themes/django.toml +77 -0
  108. flock/themes/djangorebornagain.toml +77 -0
  109. flock/themes/djangosmooth.toml +77 -0
  110. flock/themes/doom-peacock.toml +77 -0
  111. flock/themes/doomone.toml +77 -0
  112. flock/themes/dotgov.toml +77 -0
  113. flock/themes/dracula+.toml +77 -0
  114. flock/themes/dracula.toml +77 -0
  115. flock/themes/duckbones.toml +77 -0
  116. flock/themes/duotone-dark.toml +77 -0
  117. flock/themes/earthsong.toml +77 -0
  118. flock/themes/elemental.toml +77 -0
  119. flock/themes/elementary.toml +77 -0
  120. flock/themes/encom.toml +77 -0
  121. flock/themes/espresso-libre.toml +77 -0
  122. flock/themes/espresso.toml +77 -0
  123. flock/themes/everblush.toml +77 -0
  124. flock/themes/fahrenheit.toml +77 -0
  125. flock/themes/fairyfloss.toml +77 -0
  126. flock/themes/farmhouse-dark.toml +77 -0
  127. flock/themes/farmhouse-light.toml +77 -0
  128. flock/themes/fideloper.toml +77 -0
  129. flock/themes/firefly-traditional.toml +77 -0
  130. flock/themes/firefoxdev.toml +77 -0
  131. flock/themes/firewatch.toml +77 -0
  132. flock/themes/fishtank.toml +77 -0
  133. flock/themes/flat.toml +77 -0
  134. flock/themes/flatland.toml +77 -0
  135. flock/themes/flexoki-dark.toml +77 -0
  136. flock/themes/flexoki-light.toml +77 -0
  137. flock/themes/floraverse.toml +77 -0
  138. flock/themes/forestblue.toml +77 -0
  139. flock/themes/framer.toml +77 -0
  140. flock/themes/frontenddelight.toml +77 -0
  141. flock/themes/funforrest.toml +77 -0
  142. flock/themes/galaxy.toml +77 -0
  143. flock/themes/galizur.toml +77 -0
  144. flock/themes/github-dark.toml +77 -0
  145. flock/themes/github.toml +77 -0
  146. flock/themes/glacier.toml +77 -0
  147. flock/themes/grape.toml +77 -0
  148. flock/themes/grass.toml +77 -0
  149. flock/themes/grey-green.toml +77 -0
  150. flock/themes/gruber-darker.toml +77 -0
  151. flock/themes/gruvboxdark.toml +77 -0
  152. flock/themes/gruvboxdarkhard.toml +77 -0
  153. flock/themes/gruvboxlight.toml +77 -0
  154. flock/themes/guezwhoz.toml +77 -0
  155. flock/themes/hacktober.toml +77 -0
  156. flock/themes/hardcore.toml +77 -0
  157. flock/themes/harper.toml +77 -0
  158. flock/themes/hax0r-blue.toml +77 -0
  159. flock/themes/hax0r-gr33n.toml +77 -0
  160. flock/themes/hax0r-r3d.toml +77 -0
  161. flock/themes/highway.toml +77 -0
  162. flock/themes/hipster-green.toml +77 -0
  163. flock/themes/hivacruz.toml +77 -0
  164. flock/themes/homebrew.toml +77 -0
  165. flock/themes/hopscotch.256.toml +77 -0
  166. flock/themes/hopscotch.toml +77 -0
  167. flock/themes/hurtado.toml +77 -0
  168. flock/themes/hybrid.toml +77 -0
  169. flock/themes/ic-green-ppl.toml +77 -0
  170. flock/themes/ic-orange-ppl.toml +77 -0
  171. flock/themes/iceberg-dark.toml +77 -0
  172. flock/themes/iceberg-light.toml +77 -0
  173. flock/themes/idea.toml +77 -0
  174. flock/themes/idletoes.toml +77 -0
  175. flock/themes/ir-black.toml +77 -0
  176. flock/themes/iterm2-dark-background.toml +77 -0
  177. flock/themes/iterm2-default.toml +77 -0
  178. flock/themes/iterm2-light-background.toml +77 -0
  179. flock/themes/iterm2-pastel-dark-background.toml +77 -0
  180. flock/themes/iterm2-smoooooth.toml +77 -0
  181. flock/themes/iterm2-solarized-dark.toml +77 -0
  182. flock/themes/iterm2-solarized-light.toml +77 -0
  183. flock/themes/iterm2-tango-dark.toml +77 -0
  184. flock/themes/iterm2-tango-light.toml +77 -0
  185. flock/themes/jackie-brown.toml +77 -0
  186. flock/themes/japanesque.toml +77 -0
  187. flock/themes/jellybeans.toml +77 -0
  188. flock/themes/jetbrains-darcula.toml +77 -0
  189. flock/themes/jubi.toml +77 -0
  190. flock/themes/kanagawabones.toml +77 -0
  191. flock/themes/kibble.toml +77 -0
  192. flock/themes/kolorit.toml +77 -0
  193. flock/themes/konsolas.toml +77 -0
  194. flock/themes/kurokula.toml +77 -0
  195. flock/themes/lab-fox.toml +77 -0
  196. flock/themes/laser.toml +77 -0
  197. flock/themes/later-this-evening.toml +77 -0
  198. flock/themes/lavandula.toml +77 -0
  199. flock/themes/liquidcarbon.toml +77 -0
  200. flock/themes/liquidcarbontransparent.toml +77 -0
  201. flock/themes/liquidcarbontransparentinverse.toml +77 -0
  202. flock/themes/lovelace.toml +77 -0
  203. flock/themes/man-page.toml +77 -0
  204. flock/themes/mariana.toml +77 -0
  205. flock/themes/material.toml +77 -0
  206. flock/themes/materialdark.toml +77 -0
  207. flock/themes/materialdarker.toml +77 -0
  208. flock/themes/materialdesigncolors.toml +77 -0
  209. flock/themes/materialocean.toml +77 -0
  210. flock/themes/mathias.toml +77 -0
  211. flock/themes/matrix.toml +77 -0
  212. flock/themes/medallion.toml +77 -0
  213. flock/themes/mellifluous.toml +77 -0
  214. flock/themes/midnight-in-mojave.toml +77 -0
  215. flock/themes/mirage.toml +77 -0
  216. flock/themes/misterioso.toml +77 -0
  217. flock/themes/molokai.toml +77 -0
  218. flock/themes/monalisa.toml +77 -0
  219. flock/themes/monokai-remastered.toml +77 -0
  220. flock/themes/monokai-soda.toml +77 -0
  221. flock/themes/monokai-vivid.toml +77 -0
  222. flock/themes/n0tch2k.toml +77 -0
  223. flock/themes/neobones-dark.toml +77 -0
  224. flock/themes/neobones-light.toml +77 -0
  225. flock/themes/neon.toml +77 -0
  226. flock/themes/neopolitan.toml +77 -0
  227. flock/themes/neutron.toml +77 -0
  228. flock/themes/night-owlish-light.toml +77 -0
  229. flock/themes/nightfox.toml +77 -0
  230. flock/themes/nightlion-v1.toml +77 -0
  231. flock/themes/nightlion-v2.toml +77 -0
  232. flock/themes/niji.toml +77 -0
  233. flock/themes/nocturnal-winter.toml +77 -0
  234. flock/themes/nord-light.toml +77 -0
  235. flock/themes/nord.toml +77 -0
  236. flock/themes/novel.toml +77 -0
  237. flock/themes/nvimdark.toml +77 -0
  238. flock/themes/nvimlight.toml +77 -0
  239. flock/themes/obsidian.toml +77 -0
  240. flock/themes/ocean.toml +77 -0
  241. flock/themes/oceanic-next.toml +77 -0
  242. flock/themes/oceanicmaterial.toml +77 -0
  243. flock/themes/ollie.toml +77 -0
  244. flock/themes/onehalfdark.toml +77 -0
  245. flock/themes/onehalflight.toml +77 -0
  246. flock/themes/operator-mono-dark.toml +77 -0
  247. flock/themes/overnight-slumber.toml +77 -0
  248. flock/themes/oxocarbon.toml +77 -0
  249. flock/themes/palenighthc.toml +77 -0
  250. flock/themes/pandora.toml +77 -0
  251. flock/themes/paraiso-dark.toml +77 -0
  252. flock/themes/paulmillr.toml +77 -0
  253. flock/themes/pencildark.toml +77 -0
  254. flock/themes/pencillight.toml +77 -0
  255. flock/themes/peppermint.toml +77 -0
  256. flock/themes/piatto-light.toml +77 -0
  257. flock/themes/pnevma.toml +77 -0
  258. flock/themes/popping-and-locking.toml +77 -0
  259. flock/themes/primary.toml +77 -0
  260. flock/themes/pro-light.toml +77 -0
  261. flock/themes/pro.toml +77 -0
  262. flock/themes/purple-rain.toml +77 -0
  263. flock/themes/purplepeter.toml +77 -0
  264. flock/themes/rapture.toml +77 -0
  265. flock/themes/raycast-dark.toml +77 -0
  266. flock/themes/raycast-light.toml +77 -0
  267. flock/themes/rebecca.toml +77 -0
  268. flock/themes/red-alert.toml +77 -0
  269. flock/themes/red-planet.toml +77 -0
  270. flock/themes/red-sands.toml +77 -0
  271. flock/themes/relaxed.toml +77 -0
  272. flock/themes/retro.toml +77 -0
  273. flock/themes/rippedcasts.toml +77 -0
  274. flock/themes/rose-pine-dawn.toml +77 -0
  275. flock/themes/rose-pine-moon.toml +77 -0
  276. flock/themes/rose-pine.toml +77 -0
  277. flock/themes/rouge-2.toml +77 -0
  278. flock/themes/royal.toml +77 -0
  279. flock/themes/ryuuko.toml +77 -0
  280. flock/themes/sakura.toml +77 -0
  281. flock/themes/scarlet-protocol.toml +77 -0
  282. flock/themes/seafoam-pastel.toml +77 -0
  283. flock/themes/seashells.toml +77 -0
  284. flock/themes/seoulbones-dark.toml +77 -0
  285. flock/themes/seoulbones-light.toml +77 -0
  286. flock/themes/seti.toml +77 -0
  287. flock/themes/shades-of-purple.toml +77 -0
  288. flock/themes/shaman.toml +77 -0
  289. flock/themes/slate.toml +77 -0
  290. flock/themes/sleepyhollow.toml +77 -0
  291. flock/themes/smyck.toml +77 -0
  292. flock/themes/snazzy.toml +77 -0
  293. flock/themes/softserver.toml +77 -0
  294. flock/themes/solarized-darcula.toml +77 -0
  295. flock/themes/solarized-dark---patched.toml +77 -0
  296. flock/themes/solarized-dark-higher-contrast.toml +77 -0
  297. flock/themes/spacedust.toml +77 -0
  298. flock/themes/spacegray-eighties-dull.toml +77 -0
  299. flock/themes/spacegray-eighties.toml +77 -0
  300. flock/themes/spacegray.toml +77 -0
  301. flock/themes/spiderman.toml +77 -0
  302. flock/themes/spring.toml +77 -0
  303. flock/themes/square.toml +77 -0
  304. flock/themes/sublette.toml +77 -0
  305. flock/themes/subliminal.toml +77 -0
  306. flock/themes/sugarplum.toml +77 -0
  307. flock/themes/sundried.toml +77 -0
  308. flock/themes/symfonic.toml +77 -0
  309. flock/themes/synthwave-everything.toml +77 -0
  310. flock/themes/synthwave.toml +77 -0
  311. flock/themes/synthwavealpha.toml +77 -0
  312. flock/themes/tango-adapted.toml +77 -0
  313. flock/themes/tango-half-adapted.toml +77 -0
  314. flock/themes/teerb.toml +77 -0
  315. flock/themes/terafox.toml +77 -0
  316. flock/themes/terminal-basic.toml +77 -0
  317. flock/themes/thayer-bright.toml +77 -0
  318. flock/themes/the-hulk.toml +77 -0
  319. flock/themes/tinacious-design-(dark).toml +77 -0
  320. flock/themes/tinacious-design-(light).toml +77 -0
  321. flock/themes/tokyonight-day.toml +77 -0
  322. flock/themes/tokyonight-storm.toml +77 -0
  323. flock/themes/tokyonight.toml +77 -0
  324. flock/themes/tomorrow-night-blue.toml +77 -0
  325. flock/themes/tomorrow-night-bright.toml +77 -0
  326. flock/themes/tomorrow-night-burns.toml +77 -0
  327. flock/themes/tomorrow-night-eighties.toml +77 -0
  328. flock/themes/tomorrow-night.toml +77 -0
  329. flock/themes/tomorrow.toml +77 -0
  330. flock/themes/toychest.toml +77 -0
  331. flock/themes/treehouse.toml +77 -0
  332. flock/themes/twilight.toml +77 -0
  333. flock/themes/ubuntu.toml +77 -0
  334. flock/themes/ultradark.toml +77 -0
  335. flock/themes/ultraviolent.toml +77 -0
  336. flock/themes/underthesea.toml +77 -0
  337. flock/themes/unikitty.toml +77 -0
  338. flock/themes/urple.toml +77 -0
  339. flock/themes/vaughn.toml +77 -0
  340. flock/themes/vesper.toml +77 -0
  341. flock/themes/vibrantink.toml +77 -0
  342. flock/themes/vimbones.toml +77 -0
  343. flock/themes/violet-dark.toml +77 -0
  344. flock/themes/violet-light.toml +77 -0
  345. flock/themes/warmneon.toml +77 -0
  346. flock/themes/wez.toml +77 -0
  347. flock/themes/whimsy.toml +77 -0
  348. flock/themes/wildcherry.toml +77 -0
  349. flock/themes/wilmersdorf.toml +77 -0
  350. flock/themes/wombat.toml +77 -0
  351. flock/themes/wryan.toml +77 -0
  352. flock/themes/xcodedark.toml +77 -0
  353. flock/themes/xcodedarkhc.toml +77 -0
  354. flock/themes/xcodelight.toml +77 -0
  355. flock/themes/xcodelighthc.toml +77 -0
  356. flock/themes/xcodewwdc.toml +77 -0
  357. flock/themes/zenbones-dark.toml +77 -0
  358. flock/themes/zenbones-light.toml +77 -0
  359. flock/themes/zenbones.toml +77 -0
  360. flock/themes/zenburn.toml +77 -0
  361. flock/themes/zenburned.toml +77 -0
  362. flock/themes/zenwritten-dark.toml +77 -0
  363. flock/themes/zenwritten-light.toml +77 -0
  364. flock/workflow/activities.py +175 -115
  365. flock/workflow/agent_activities.py +24 -26
  366. flock/workflow/temporal_setup.py +38 -37
  367. flock/workflow/workflow.py +58 -53
  368. flock_core-0.2.2.dist-info/METADATA +320 -0
  369. flock_core-0.2.2.dist-info/RECORD +372 -0
  370. {flock_core-0.1.2.dist-info → flock_core-0.2.2.dist-info}/licenses/LICENSE +21 -21
  371. flock/agents/__init__.py +0 -3
  372. flock/agents/batch_agent.py +0 -175
  373. flock/agents/declarative_agent.py +0 -166
  374. flock/agents/loop_agent.py +0 -178
  375. flock/agents/trigger_agent.py +0 -191
  376. flock/agents/user_agent.py +0 -230
  377. flock/app/components/__init__.py +0 -14
  378. flock/app/components/charts/agent_workflow.py +0 -14
  379. flock/app/components/charts/core_architecture.py +0 -14
  380. flock/app/components/charts/tool_system.py +0 -14
  381. flock/app/components/history_grid.py +0 -168
  382. flock/app/components/history_grid_alt.py +0 -189
  383. flock/app/components/sidebar.py +0 -19
  384. flock/app/components/theme.py +0 -9
  385. flock/app/components/util.py +0 -18
  386. flock/app/hive_app.py +0 -118
  387. flock/app/html/d3.html +0 -179
  388. flock/app/modules/__init__.py +0 -12
  389. flock/app/modules/about.py +0 -17
  390. flock/app/modules/agent_detail.py +0 -70
  391. flock/app/modules/agent_list.py +0 -59
  392. flock/app/modules/playground.py +0 -322
  393. flock/app/modules/settings.py +0 -96
  394. flock/core/agent.py +0 -150
  395. flock/core/agent_registry.py +0 -162
  396. flock/core/context.py +0 -279
  397. flock/core/handoff/handoff_base.py +0 -12
  398. flock/core/logging/error_handler.py +0 -84
  399. flock/core/logging/formatters.py +0 -122
  400. flock/core/logging/handlers.py +0 -117
  401. flock/core/logging/logger.py +0 -107
  402. flock/core/serializable.py +0 -206
  403. flock_core-0.1.2.dist-info/METADATA +0 -476
  404. flock_core-0.1.2.dist-info/RECORD +0 -48
  405. flock_core-0.1.2.dist-info/entry_points.txt +0 -2
  406. /flock/{core/config/declarative_agent_config.py → workflow/__init__.py} +0 -0
  407. {flock_core-0.1.2.dist-info → flock_core-0.2.2.dist-info}/WHEEL +0 -0
@@ -1,115 +1,175 @@
1
- """Defines Temporal activities for running a chain of agents."""
2
-
3
- from datetime import datetime
4
-
5
- from temporalio import activity
6
-
7
- from flock.core.agent import Agent
8
- from flock.core.agent_registry import Registry
9
- from flock.core.context import FlockContext
10
- from flock.core.context_vars import FLOCK_CURRENT_AGENT, FLOCK_INITIAL_INPUT
11
- from flock.core.handoff.handoff_base import HandoffBase
12
- from flock.core.logging import flock_logger
13
-
14
-
15
- @activity.defn
16
- async def run_agent(context: FlockContext) -> dict:
17
- """Runs a chain of agents using the provided context.
18
-
19
- The context contains:
20
- - A state (e.g., "init_input", "current_agent", etc.),
21
- - A history of agent runs.
22
-
23
- Each agent uses the current value of the variable specified in its `input` attribute.
24
- After each run, its output is merged into the context state.
25
- The default handoff behavior is to fetch the next agent's input automatically from the context.
26
- """
27
- registry = Registry()
28
- current_agent_name = context.get_variable(FLOCK_CURRENT_AGENT)
29
- flock_logger.info(f"Starting agent chain with initial agent", agent=current_agent_name)
30
-
31
- agent = registry.get_agent(current_agent_name)
32
- if not agent:
33
- flock_logger.error(f"Agent not found", agent=current_agent_name)
34
- return {"error": f"Agent '{current_agent_name}' not found."}
35
-
36
- while agent:
37
- # Determine the input for this agent.
38
- # (Preferably, the agent's input key is used; otherwise "init_input" is assumed.)
39
- agent_input = (
40
- context.get_variable(agent.input)
41
- if getattr(agent, "input", None)
42
- else context.get_variable(FLOCK_INITIAL_INPUT)
43
- )
44
- flock_logger.info(
45
- "Determined agent input", agent=agent.name, input_source=getattr(agent, "input", "FLOCK_INITIAL_INPUT")
46
- )
47
-
48
- # Prepare a deep copy of the state for the agent's run.
49
- local_context = FlockContext.from_dict(context.to_dict())
50
- local_context.set_variable(
51
- f"{agent.name}.{agent.input}", agent_input
52
- ) # ensure the agent's expected input is set
53
-
54
- # Execute the agent.
55
- flock_logger.info("Executing agent", agent=agent.name)
56
- result = await agent.run(local_context)
57
- flock_logger.info("Agent execution completed", agent=agent.name)
58
-
59
- # If no handoff is defined, return the result.
60
- if not agent.hand_off:
61
- # Record the agent's execution.
62
- context.record(agent.name, result, timestamp=datetime.now(), hand_off=None)
63
- flock_logger.info("No handoff defined, completing chain", agent=agent.name)
64
- return result
65
-
66
- # Determine the next agent.
67
- if callable(agent.hand_off):
68
- # The handoff function may override the default behavior:
69
- # it can explicitly return a dict with "next_agent" and optionally "input"
70
- flock_logger.info("Executing handoff function", agent=agent.name)
71
- handoff_data: HandoffBase = agent.hand_off(context, result)
72
- if isinstance(handoff_data.next_agent, Agent):
73
- next_agent_name = handoff_data.next_agent.name
74
- else:
75
- next_agent_name = handoff_data.next_agent
76
-
77
- # Use the provided new input if present, otherwise let the context update be automatic.
78
- if handoff_data.input:
79
- context.state["init_input"] = handoff_data["input"]
80
- flock_logger.debug("Using handoff-provided input", agent=agent.name)
81
- if handoff_data.context_params:
82
- context.state.update(handoff_data.context_params)
83
- flock_logger.debug("Updated context with handoff params", agent=agent.name)
84
- elif isinstance(agent.hand_off, str | Agent):
85
- next_agent_name = agent.hand_off if isinstance(agent.hand_off, str) else agent.hand_off.name
86
-
87
- else:
88
- return {"error": "Unsupported hand_off type."}
89
- context.record(agent.name, result, timestamp=datetime.now(), hand_off=next_agent_name)
90
- # Update the current agent and prepare the next input automatically.
91
- next_agent = registry.get_agent(next_agent_name)
92
- if not next_agent:
93
- flock_logger.error("Next agent not found", agent=next_agent_name)
94
- return {"error": f"Next agent '{next_agent_name}' not found."}
95
-
96
- context.state["current_agent"] = next_agent.name
97
- # By default, the next input is determined from the current state using next_input_for().
98
- context.state["init_input"] = context.next_input_for(next_agent)
99
- flock_logger.info("Handing off to next agent", current=agent.name, next=next_agent.name)
100
- agent = next_agent
101
-
102
- # If the loop ever terminates without a final result, return the latest state value.
103
- flock_logger.info("Chain completed, returning final state")
104
- return context.get_variable("init_input")
105
-
106
-
107
- @activity.defn
108
- async def get_next_agent(name: str) -> Agent | None:
109
- """Retrieves the agent with the given name from the registry."""
110
- flock_logger.debug("Looking up next agent", agent=name)
111
- registry = Registry()
112
- agent = registry.get_agent(name)
113
- if not agent:
114
- flock_logger.warning("Next agent not found", agent=name)
115
- return agent
1
+ """Defines Temporal activities for running a chain of agents with logging and tracing."""
2
+
3
+ from datetime import datetime
4
+
5
+ from opentelemetry import trace
6
+ from temporalio import activity
7
+
8
+ from flock.core.context.context import FlockContext
9
+ from flock.core.context.context_vars import FLOCK_CURRENT_AGENT
10
+ from flock.core.flock_agent import FlockAgent, HandOff
11
+ from flock.core.logging.formatters.base_formatter import FormatterOptions
12
+ from flock.core.logging.formatters.formatter_factory import FormatterFactory
13
+ from flock.core.logging.logging import get_logger
14
+ from flock.core.registry.agent_registry import Registry
15
+ from flock.core.util.input_resolver import resolve_inputs
16
+
17
+ logger = get_logger("activities")
18
+ tracer = trace.get_tracer(__name__)
19
+
20
+
21
+ @activity.defn
22
+ async def run_agent(
23
+ context: FlockContext, output_formatter: FormatterOptions = None
24
+ ) -> dict:
25
+ """Runs a chain of agents using the provided context.
26
+
27
+ The context contains state, history, and agent definitions.
28
+ After each agent run, its output is merged into the context.
29
+ """
30
+ # Start a top-level span for the entire run_agent activity.
31
+ with tracer.start_as_current_span("run_agent") as span:
32
+ registry = Registry()
33
+ previous_agent_name = ""
34
+ if isinstance(context, dict):
35
+ context = FlockContext.from_dict(context)
36
+ current_agent_name = context.get_variable(FLOCK_CURRENT_AGENT)
37
+ span.set_attribute("initial.agent", current_agent_name)
38
+ logger.info("Starting agent chain", initial_agent=current_agent_name)
39
+
40
+ agent = registry.get_agent(current_agent_name)
41
+ agent.resolve_callables(context=context)
42
+ if not agent:
43
+ logger.error("Agent not found", agent=current_agent_name)
44
+ span.record_exception(
45
+ Exception(f"Agent '{current_agent_name}' not found")
46
+ )
47
+ return {"error": f"Agent '{current_agent_name}' not found."}
48
+
49
+ # Loop over agents in the chain.
50
+ while agent:
51
+ # Create a nested span for this iteration.
52
+ with tracer.start_as_current_span("agent_iteration") as iter_span:
53
+ iter_span.set_attribute("agent.name", agent.name)
54
+
55
+ # Resolve inputs for the agent.
56
+ agent_inputs = resolve_inputs(
57
+ agent.input, context, previous_agent_name
58
+ )
59
+ iter_span.add_event(
60
+ "resolved inputs", attributes={"inputs": str(agent_inputs)}
61
+ )
62
+
63
+ # Execute the agent with its own span.
64
+ with tracer.start_as_current_span("execute_agent") as exec_span:
65
+ logger.info("Executing agent", agent=agent.name)
66
+ try:
67
+ result = await agent.run(agent_inputs)
68
+ exec_span.set_attribute("result", str(result))
69
+ logger.debug(
70
+ "Agent execution completed", agent=agent.name
71
+ )
72
+ except Exception as e:
73
+ logger.error(
74
+ "Agent execution failed",
75
+ agent=agent.name,
76
+ error=str(e),
77
+ )
78
+ exec_span.record_exception(e)
79
+ raise
80
+
81
+ # Optionally display formatted output.
82
+ display_output = True
83
+ if agent.config:
84
+ display_output = not agent.config.disable_output
85
+
86
+ if output_formatter and display_output:
87
+ formatter = FormatterFactory.create_formatter(
88
+ output_formatter
89
+ )
90
+ formatter.display(
91
+ result, agent.name, output_formatter.wait_for_input
92
+ )
93
+
94
+ # If there is no handoff, record the result and finish.
95
+ if not agent.hand_off:
96
+ context.record(
97
+ agent.name,
98
+ result,
99
+ timestamp=datetime.now(),
100
+ hand_off=None,
101
+ called_from=previous_agent_name,
102
+ )
103
+ logger.info(
104
+ "No handoff defined, completing chain", agent=agent.name
105
+ )
106
+ iter_span.add_event("chain completed")
107
+ return result
108
+
109
+ # Determine the next agent.
110
+ handoff_data = HandOff()
111
+ if callable(agent.hand_off):
112
+ logger.debug("Executing handoff function", agent=agent.name)
113
+ try:
114
+ handoff_data = agent.hand_off(context, result)
115
+ if isinstance(handoff_data.next_agent, FlockAgent):
116
+ handoff_data.next_agent = (
117
+ handoff_data.next_agent.name
118
+ )
119
+ except Exception as e:
120
+ logger.error(
121
+ "Handoff function error",
122
+ agent=agent.name,
123
+ error=str(e),
124
+ )
125
+ iter_span.record_exception(e)
126
+ return {"error": f"Handoff function error: {e}"}
127
+ elif isinstance(agent.hand_off, str | FlockAgent):
128
+ handoff_data.next_agent = (
129
+ agent.hand_off
130
+ if isinstance(agent.hand_off, str)
131
+ else agent.hand_off.name
132
+ )
133
+ else:
134
+ logger.error("Unsupported hand_off type", agent=agent.name)
135
+ iter_span.add_event("unsupported hand_off type")
136
+ return {"error": "Unsupported hand_off type."}
137
+
138
+ # Record the agent run in the context.
139
+ context.record(
140
+ agent.name,
141
+ result,
142
+ timestamp=datetime.now().isoformat(),
143
+ hand_off=handoff_data,
144
+ called_from=previous_agent_name,
145
+ )
146
+ previous_agent_name = agent.name
147
+
148
+ # Prepare the next agent.
149
+ try:
150
+ agent = registry.get_agent(handoff_data.next_agent)
151
+ agent.resolve_callables(context=context)
152
+ if not agent:
153
+ logger.error(
154
+ "Next agent not found",
155
+ agent=handoff_data.next_agent,
156
+ )
157
+ iter_span.record_exception(
158
+ Exception(
159
+ f"Next agent '{handoff_data.next_agent}' not found"
160
+ )
161
+ )
162
+ return {
163
+ "error": f"Next agent '{handoff_data.next_agent}' not found."
164
+ }
165
+
166
+ context.set_variable(FLOCK_CURRENT_AGENT, agent.name)
167
+ logger.info("Handing off to next agent", next=agent.name)
168
+ iter_span.set_attribute("next.agent", agent.name)
169
+ except Exception as e:
170
+ logger.error("Error during handoff", error=str(e))
171
+ iter_span.record_exception(e)
172
+ return {"error": f"Error during handoff: {e}"}
173
+
174
+ # If the loop exits unexpectedly, return the initial input.
175
+ return context.get_variable("init_input")
@@ -1,26 +1,24 @@
1
- from temporalio import activity
2
-
3
- from flock.agents.declarative_agent import DeclarativeAgent
4
- from flock.core.context import FlockContext
5
-
6
-
7
- @activity.defn
8
- async def run_declarative_agent_activity(params: dict) -> dict:
9
- """Temporal activity to run a declarative (or batch) agent.
10
-
11
- Expects a dictionary with:
12
- - "agent_data": a dict representation of the agent (as produced by .dict()),
13
- - "context_data": a dict containing the FlockContext state and optionally other fields.
14
-
15
- The activity reconstructs the agent and a FlockContext, then calls the agent’s _evaluate() method.
16
- """
17
- agent_data = params.get("agent_data")
18
- context_data = params.get("context_data", {})
19
- # Reconstruct the agent from its serialized representation.
20
- agent = DeclarativeAgent.parse_obj(agent_data)
21
- # Reconstruct the FlockContext from the state.
22
- state = context_data.get("state", {})
23
- # (For simplicity, we ignore history and agent_definitions here. You can extend this if needed.)
24
- context = FlockContext(state=state)
25
- result = await agent._evaluate(context)
26
- return result
1
+ from temporalio import activity
2
+
3
+ from flock.core.context.context import FlockContext
4
+ from flock.core.flock_agent import FlockAgent
5
+
6
+
7
+ @activity.defn
8
+ async def run_declarative_agent_activity(params: dict) -> dict:
9
+ """Temporal activity to run a declarative (or batch) agent.
10
+
11
+ Expects a dictionary with:
12
+ - "agent_data": a dict representation of the agent (as produced by .dict()),
13
+ - "context_data": a dict containing the FlockContext state and optionally other fields.
14
+
15
+ The activity reconstructs the agent and a FlockContext, then calls the agent’s _evaluate() method.
16
+ """
17
+ agent_data = params.get("agent_data")
18
+ context_data = params.get("context_data", {})
19
+ # Reconstruct the agent from its serialized representation.
20
+ agent = FlockAgent.from_dict(agent_data)
21
+ # Reconstruct the FlockContext from the state.
22
+ context = FlockContext.from_dict(context_data)
23
+ result = await agent.evaluate(context)
24
+ return result
@@ -1,37 +1,38 @@
1
- import asyncio
2
- import uuid
3
-
4
- from temporalio.client import Client
5
- from temporalio.worker import Worker
6
-
7
-
8
- async def create_temporal_client() -> Client:
9
- client = await Client.connect("localhost:7233")
10
- return client
11
-
12
- async def setup_worker(workflow,activity) -> Client:
13
- worker_client = await create_temporal_client()
14
- worker = Worker(worker_client, task_queue="flock-queue", workflows=[workflow], activities=[activity])
15
- asyncio.create_task(worker.run())
16
- await asyncio.sleep(1)
17
-
18
-
19
- async def run_worker(client: Client, task_queue: str, workflows, activities):
20
- worker = Worker(client, task_queue=task_queue, workflows=workflows, activities=activities)
21
- await worker.run()
22
-
23
-
24
- async def run_activity(client: Client, name: str, func, param):
25
- run_id = f"{name}_{uuid.uuid4().hex[:4]}"
26
-
27
- try:
28
- result = await client.execute_activity(
29
- func,
30
- param,
31
- id=run_id,
32
- task_queue="flock-queue",
33
- start_to_close_timeout=300, # e.g., 5 minutes
34
- )
35
- return result
36
- except Exception:
37
- raise
1
+ import asyncio
2
+ import uuid
3
+
4
+ from temporalio.client import Client
5
+ from temporalio.worker import Worker
6
+
7
+
8
+ async def create_temporal_client() -> Client:
9
+ client = await Client.connect("localhost:7233")
10
+ return client
11
+
12
+
13
+ async def setup_worker(workflow, activity) -> Client:
14
+ worker_client = await create_temporal_client()
15
+ worker = Worker(worker_client, task_queue="flock-queue", workflows=[workflow], activities=[activity])
16
+ asyncio.create_task(worker.run())
17
+ await asyncio.sleep(1)
18
+
19
+
20
+ async def run_worker(client: Client, task_queue: str, workflows, activities):
21
+ worker = Worker(client, task_queue=task_queue, workflows=workflows, activities=activities)
22
+ await worker.run()
23
+
24
+
25
+ async def run_activity(client: Client, name: str, func, param):
26
+ run_id = f"{name}_{uuid.uuid4().hex[:4]}"
27
+
28
+ try:
29
+ result = await client.execute_activity(
30
+ func,
31
+ param,
32
+ id=run_id,
33
+ task_queue="flock-queue",
34
+ start_to_close_timeout=300, # e.g., 5 minutes
35
+ )
36
+ return result
37
+ except Exception:
38
+ raise
@@ -1,53 +1,58 @@
1
- from datetime import timedelta
2
-
3
- from temporalio import workflow
4
-
5
- from flock.core.context import FlockContext
6
- from flock.core.logging import flock_logger
7
- from flock.workflow.activities import run_agent
8
-
9
- # Import activity, passing it through the sandbox without reloading the module
10
- with workflow.unsafe.imports_passed_through():
11
- from flock.workflow.activities import run_agent
12
-
13
-
14
- @workflow.defn
15
- class FlockWorkflow:
16
- def __init__(self) -> None:
17
- self.context = None
18
-
19
- @workflow.run
20
- async def run(self, context_dict: dict) -> dict:
21
- self.context = FlockContext.from_dict(context_dict)
22
- self.context.workflow_id = workflow.info().workflow_id
23
- self.context.workflow_timestamp = workflow.info().start_time.strftime("%Y-%m-%d %H:%M:%S")
24
-
25
- try:
26
- flock_logger.set_context(workflow_id=self.context.workflow_id)
27
- flock_logger.workflow_event(f"Starting workflow execution at {self.context.workflow_timestamp}")
28
-
29
- result = await workflow.execute_activity(
30
- run_agent, self.context, start_to_close_timeout=timedelta(minutes=5)
31
- )
32
-
33
- self.context.set_variable(
34
- "flock.result",
35
- {
36
- "result": result,
37
- "success": True,
38
- },
39
- )
40
-
41
- flock_logger.workflow_event("Workflow completed successfully")
42
- return result
43
-
44
- except Exception as e:
45
- flock_logger.error(f"Workflow execution failed: {e}")
46
- self.context.set_variable(
47
- "flock.result",
48
- {
49
- "result": f"Failed: {e}",
50
- "success": False,
51
- },
52
- )
53
- return self.context
1
+ from datetime import timedelta
2
+
3
+ from temporalio import workflow
4
+
5
+ from flock.core.context.context import FlockContext
6
+ from flock.core.logging.logging import get_logger
7
+ from flock.workflow.activities import run_agent
8
+
9
+ # Import activity, passing it through the sandbox without reloading the module
10
+
11
+
12
+ logger = get_logger("workflow")
13
+
14
+
15
+ @workflow.defn
16
+ class FlockWorkflow:
17
+ def __init__(self) -> None:
18
+ self.context = None
19
+
20
+ @workflow.run
21
+ async def run(self, context_dict: dict) -> dict:
22
+ self.context = FlockContext.from_dict(context_dict)
23
+ self.context.workflow_id = workflow.info().workflow_id
24
+ self.context.workflow_timestamp = workflow.info().start_time.strftime("%Y-%m-%d %H:%M:%S")
25
+
26
+ try:
27
+ logger.info(
28
+ "Starting workflow execution",
29
+ timestamp=self.context.workflow_timestamp,
30
+ )
31
+
32
+ result = await workflow.execute_activity(
33
+ run_agent,
34
+ self.context,
35
+ start_to_close_timeout=timedelta(minutes=5),
36
+ )
37
+
38
+ self.context.set_variable(
39
+ "flock.result",
40
+ {
41
+ "result": result,
42
+ "success": True,
43
+ },
44
+ )
45
+
46
+ logger.success("Workflow completed successfully")
47
+ return result
48
+
49
+ except Exception as e:
50
+ logger.exception("Workflow execution failed", error=str(e))
51
+ self.context.set_variable(
52
+ "flock.result",
53
+ {
54
+ "result": f"Failed: {e}",
55
+ "success": False,
56
+ },
57
+ )
58
+ return self.context