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
@@ -1,230 +1,145 @@
1
- from collections.abc import Callable
2
- from typing import Any
3
-
4
- from pydantic import Field
5
- from temporalio import activity
6
-
7
- from flock.core.agent import Agent
8
- from flock.core.context import FlockContext
9
- from flock.core.logging import flock_logger, live_update_handler, performance_handler
10
-
11
-
12
- @activity.defn
13
- async def run_user_agent_activity(context: dict[str, Any]) -> dict[str, Any]:
14
- """Temporal activity to process a user agent task.
15
-
16
- Expects context to contain:
17
- - "model": the model name
18
- - "agent_input": the key used for the input
19
- - "output": the agent output specification
20
- - "init_input": the initial input
21
- - "tools": (optional) list of tools
22
- """
23
- try:
24
- import dspy
25
-
26
- flock_logger.info("Starting user agent activity", context=context)
27
-
28
- with performance_handler.track_time("model_configuration"):
29
- model = context.get("model")
30
- agent_input = context.get("agent_input")
31
- output = context.get("output")
32
- init_input = context.get("init_input")
33
- tools = context.get("tools")
34
-
35
- flock_logger.debug(
36
- "Configuring model",
37
- model=model,
38
- input=agent_input,
39
- output=output,
40
- )
41
-
42
- lm = dspy.LM(model)
43
- dspy.configure(lm=lm)
44
-
45
- with performance_handler.track_time("task_execution"):
46
- if tools:
47
- flock_logger.info("Creating ReAct task with tools", num_tools=len(tools))
48
- agent_task = dspy.ReAct(f"{agent_input} -> {output}", tools=tools)
49
- else:
50
- flock_logger.info("Creating Predict task")
51
- agent_task = dspy.Predict(f"{agent_input} -> {output}")
52
-
53
- kwargs = {agent_input: init_input}
54
- flock_logger.info("Executing task", kwargs=kwargs)
55
- result = agent_task(**kwargs).toDict()
56
- result[agent_input] = init_input
57
-
58
- flock_logger.success("Task completed successfully")
59
- return result
60
-
61
- except Exception as e:
62
- flock_logger.error(
63
- "User agent activity failed",
64
- error=str(e),
65
- context=context,
66
- )
67
- raise
68
-
69
-
70
- class UserAgent(Agent):
71
- """An agent that evaluates declarative inputs with user interaction capabilities.
72
-
73
- This agent extends the base Agent class with the ability to interact with users
74
- during execution, while maintaining compatibility with both local and Temporal
75
- execution modes.
76
-
77
- Attributes:
78
- input: Input domain for the agent
79
- output: Output types for the agent
80
- tools: Tools the agent is allowed to use
81
- require_confirmation: Whether to require user confirmation before proceeding
82
- """
83
-
84
- input: str = Field(default="", description="Input domain for the agent")
85
- output: str = Field(default="", description="Output types for the agent")
86
- tools: list[Callable] | None = Field(default=None, description="Tools the agent is allowed to use")
87
- require_confirmation: bool = Field(default=False, description="Whether to require user confirmation")
88
-
89
- async def _configure_model(self) -> tuple[Any, Any]:
90
- """Configure the model and create the appropriate task."""
91
- try:
92
- with performance_handler.track_time("model_configuration"):
93
- import dspy
94
-
95
- flock_logger.debug(
96
- "Configuring model",
97
- model=self.model,
98
- input=self.input,
99
- output=self.output,
100
- )
101
-
102
- lm = dspy.LM(self.model)
103
- dspy.configure(lm=lm)
104
-
105
- if self.tools:
106
- flock_logger.info("Creating ReAct task with tools", num_tools=len(self.tools))
107
- agent_task = dspy.ReAct(f"{self.input} -> {self.output}", tools=self.tools)
108
- else:
109
- flock_logger.info("Creating Predict task")
110
- agent_task = dspy.Predict(f"{self.input} -> {self.output}")
111
-
112
- return lm, agent_task
113
-
114
- except Exception as e:
115
- flock_logger.error(
116
- "Model configuration failed",
117
- error=str(e),
118
- agent=self.name,
119
- )
120
- raise
121
-
122
- async def _execute_task(self, task: Any, context: FlockContext) -> dict[str, Any]:
123
- """Execute the configured task."""
124
- try:
125
- with performance_handler.track_time("task_execution"):
126
- kwargs = {self.input: context.get_variable("init_input")}
127
- flock_logger.info("Executing task", kwargs=kwargs)
128
-
129
- with live_update_handler.update_activity_status(
130
- self.name,
131
- "Executing Task",
132
- "Running",
133
- {"input": kwargs},
134
- ):
135
- result = task(**kwargs).toDict()
136
- result[self.input] = kwargs[self.input]
137
-
138
- flock_logger.success("Task executed successfully")
139
- return result
140
-
141
- except Exception as e:
142
- flock_logger.error(
143
- "Task execution failed",
144
- error=str(e),
145
- agent=self.name,
146
- kwargs=kwargs,
147
- )
148
- raise
149
-
150
- async def run(self, context: FlockContext) -> dict[str, Any]:
151
- """Run the agent on a task with optional user interaction."""
152
- try:
153
- flock_logger.info(f"Starting user agent: {self.name}")
154
-
155
- # Configure model and task
156
- _, task = await self._configure_model()
157
-
158
- # Execute with user confirmation if required
159
- if self.require_confirmation:
160
- with live_update_handler.update_activity_status(
161
- self.name,
162
- "Awaiting User Confirmation",
163
- "Paused",
164
- {"agent": self.name},
165
- ):
166
- flock_logger.info("Waiting for user confirmation")
167
- # Here you would implement user confirmation logic
168
- # For now, we'll just proceed
169
- pass
170
-
171
- # Execute the task
172
- result = await self._execute_task(task, context)
173
- return result
174
-
175
- except Exception as e:
176
- flock_logger.error(
177
- "User agent execution failed",
178
- error=str(e),
179
- agent=self.name,
180
- )
181
- raise
182
-
183
- async def run_temporal(self, context: FlockContext) -> dict[str, Any]:
184
- """Run the user agent via Temporal."""
185
- try:
186
- from temporalio.client import Client
187
-
188
- from flock.workflow.temporal_setup import run_activity
189
-
190
- with performance_handler.track_time("temporal_setup"):
191
- flock_logger.info(f"Starting temporal user agent: {self.name}")
192
- client = await Client.connect("localhost:7233", namespace="default")
193
-
194
- # Prepare context for temporal activity
195
- activity_context = {
196
- "model": self.model,
197
- "agent_input": self.input,
198
- "output": self.output,
199
- "init_input": context.get_variable("init_input"),
200
- "tools": self.tools,
201
- }
202
-
203
- with live_update_handler.update_workflow_status(
204
- self.name,
205
- "Running",
206
- {"phase": "user_agent_execution"},
207
- ):
208
- # Execute the activity
209
- with performance_handler.track_time("temporal_execution"):
210
- flock_logger.info("Starting user agent activity")
211
- result = await run_activity(
212
- client,
213
- self.name,
214
- run_user_agent_activity,
215
- activity_context,
216
- )
217
-
218
- flock_logger.success(
219
- "Temporal user agent completed successfully",
220
- agent=self.name,
221
- )
222
- return result
223
-
224
- except Exception as e:
225
- flock_logger.error(
226
- "Temporal user agent execution failed",
227
- error=str(e),
228
- agent=self.name,
229
- )
230
- raise
1
+ from collections.abc import Callable
2
+ from typing import Any
3
+
4
+ from pydantic import Field
5
+ from temporalio import activity
6
+
7
+ from flock.core.context.context import FlockContext
8
+ from flock.core.flock_agent import FlockAgent
9
+
10
+
11
+ @activity.defn
12
+ async def run_user_agent_activity(context: dict[str, Any]) -> dict[str, Any]:
13
+ """Temporal activity to process a user agent task.
14
+
15
+ Expects context to contain:
16
+ - "model": the model name
17
+ - "agent_input": the key used for the input
18
+ - "output": the agent output specification
19
+ - "init_input": the initial input
20
+ - "tools": (optional) list of tools
21
+ """
22
+ try:
23
+ import dspy
24
+
25
+ model = context.get("model")
26
+ agent_input = context.get("agent_input")
27
+ output = context.get("output")
28
+ init_input = context.get("init_input")
29
+ tools = context.get("tools")
30
+
31
+ lm = dspy.LM(model)
32
+ dspy.configure(lm=lm)
33
+
34
+ if tools:
35
+ agent_task = dspy.ReAct(f"{agent_input} -> {output}", tools=tools)
36
+ else:
37
+ agent_task = dspy.Predict(f"{agent_input} -> {output}")
38
+
39
+ kwargs = {agent_input: init_input}
40
+ result = agent_task(**kwargs).toDict()
41
+ result[agent_input] = init_input
42
+
43
+ return result
44
+
45
+ except Exception:
46
+ raise
47
+
48
+
49
+ class UserAgent(FlockAgent):
50
+ """An agent that evaluates declarative inputs with user interaction capabilities.
51
+
52
+ This agent extends the base Agent class with the ability to interact with users
53
+ during execution, while maintaining compatibility with both local and Temporal
54
+ execution modes.
55
+
56
+ Attributes:
57
+ input: Input domain for the agent
58
+ output: Output types for the agent
59
+ tools: Tools the agent is allowed to use
60
+ require_confirmation: Whether to require user confirmation before proceeding
61
+ """
62
+
63
+ input: str = Field(default="", description="Input domain for the agent")
64
+ output: str = Field(default="", description="Output types for the agent")
65
+ tools: list[Callable] | None = Field(default=None, description="Tools the agent is allowed to use")
66
+ require_confirmation: bool = Field(default=False, description="Whether to require user confirmation")
67
+
68
+ async def _configure_model(self) -> tuple[Any, Any]:
69
+ """Configure the model and create the appropriate task."""
70
+ try:
71
+ import dspy
72
+
73
+ lm = dspy.LM(self.model)
74
+ dspy.configure(lm=lm)
75
+
76
+ if self.tools:
77
+ agent_task = dspy.ReAct(f"{self.input} -> {self.output}", tools=self.tools)
78
+ else:
79
+ agent_task = dspy.Predict(f"{self.input} -> {self.output}")
80
+
81
+ return lm, agent_task
82
+
83
+ except Exception:
84
+ raise
85
+
86
+ async def _execute_task(self, task: Any, context: FlockContext) -> dict[str, Any]:
87
+ """Execute the configured task."""
88
+ try:
89
+ kwargs = {self.input: context.get_variable("init_input")}
90
+ result = task(**kwargs).toDict()
91
+ result[self.input] = kwargs[self.input]
92
+ return result
93
+
94
+ except Exception:
95
+ raise
96
+
97
+ async def run(self, context: FlockContext) -> dict[str, Any]:
98
+ """Run the agent on a task with optional user interaction."""
99
+ try:
100
+ # Configure model and task
101
+ _, task = await self._configure_model()
102
+
103
+ # Execute with user confirmation if required
104
+ if self.require_confirmation:
105
+ # Here you would implement user confirmation logic
106
+ # For now, we'll just proceed
107
+ pass
108
+
109
+ # Execute the task
110
+ result = await self._execute_task(task, context)
111
+ return result
112
+
113
+ except Exception:
114
+ raise
115
+
116
+ async def run_temporal(self, context: FlockContext) -> dict[str, Any]:
117
+ """Run the user agent via Temporal."""
118
+ try:
119
+ from temporalio.client import Client
120
+
121
+ from flock.workflow.temporal_setup import run_activity
122
+
123
+ client = await Client.connect("localhost:7233", namespace="default")
124
+
125
+ # Prepare context for temporal activity
126
+ activity_context = {
127
+ "model": self.model,
128
+ "agent_input": self.input,
129
+ "output": self.output,
130
+ "init_input": context.get_variable("init_input"),
131
+ "tools": self.tools,
132
+ }
133
+
134
+ # Execute the activity
135
+ result = await run_activity(
136
+ client,
137
+ self.name,
138
+ run_user_agent_activity,
139
+ activity_context,
140
+ )
141
+
142
+ return result
143
+
144
+ except Exception:
145
+ raise
flock/core/__init__.py CHANGED
@@ -1,7 +1 @@
1
- from flock.core.agent import Agent
2
- from flock.core.agent_registry import Registry
3
- from flock.core.context import FlockContext
4
- from flock.core.flock import Flock
5
- from flock.core.serializable import Serializable
6
-
7
- __all__ = ["Agent", "Flock", "FlockContext", "Registry", "Serializable"]
1
+
@@ -0,0 +1,211 @@
1
+ """A context object for storing state, history, and agent definitions."""
2
+
3
+ from dataclasses import asdict, dataclass, field
4
+ from datetime import datetime
5
+ from typing import Any, Literal
6
+
7
+ from flock.core.context.context_vars import FLOCK_LAST_AGENT, FLOCK_LAST_RESULT
8
+ from flock.core.util.serializable import Serializable
9
+
10
+
11
+ @dataclass
12
+ class AgentRunRecord:
13
+ """A record of an agent run, including the agent name, data, and timestamp."""
14
+
15
+ agent: str = field(default="") # Agent name
16
+ data: dict[str, Any] = field(default_factory=dict)
17
+ timestamp: str = field(default="")
18
+ hand_off: dict = field(default=dict) # Next agent name
19
+ called_from: str = field(default="") # Previous agent name
20
+
21
+
22
+ @dataclass
23
+ class AgentDefinition:
24
+ """A serializable definition for an agent, including the agent type, name, and data."""
25
+
26
+ agent_type: str = field(default="")
27
+ agent_name: str = field(default="")
28
+ agent_data: dict = field(default=dict)
29
+ serializer: Literal["json", "cloudpickle", "msgpack"] = field(
30
+ default="cloudpickle"
31
+ )
32
+
33
+
34
+ @dataclass
35
+ class FlockContext(Serializable):
36
+ """A context object for storing state, history, and agent definitions."""
37
+
38
+ state: dict[str, Any] = field(default_factory=dict)
39
+ history: list[AgentRunRecord] = field(default_factory=list)
40
+ agent_definitions: dict[str, AgentDefinition] = field(default_factory=dict)
41
+ run_id: str = field(default="")
42
+ workflow_id: str = field(default="")
43
+ workflow_timestamp: str = field(default="")
44
+
45
+ def record(
46
+ self,
47
+ agent_name: str,
48
+ data: dict[str, Any],
49
+ timestamp: str,
50
+ hand_off: str,
51
+ called_from: str,
52
+ ) -> None:
53
+ """Record an agent run and update the state with the agent's output."""
54
+ try:
55
+ record = AgentRunRecord(
56
+ agent=agent_name,
57
+ data=data.copy(),
58
+ timestamp=timestamp,
59
+ hand_off=hand_off,
60
+ called_from=called_from,
61
+ )
62
+ self.history.append(record)
63
+
64
+ for key, value in data.items():
65
+ self.set_variable(f"{agent_name}.{key}", value)
66
+ self.set_variable(FLOCK_LAST_RESULT, data)
67
+ self.set_variable(FLOCK_LAST_AGENT, agent_name)
68
+ except Exception:
69
+ raise
70
+
71
+ def get_variable(self, key: str) -> Any:
72
+ """Get the current value of a state variable."""
73
+ try:
74
+ return self.state.get(key)
75
+ except Exception:
76
+ raise
77
+
78
+ def set_variable(self, key: str, value: Any) -> None:
79
+ """Set the value of a state variable."""
80
+ try:
81
+ self.state[key] = value
82
+ except Exception:
83
+ raise
84
+
85
+ def deepcopy(self) -> "FlockContext":
86
+ """Create a deep copy of the context."""
87
+ try:
88
+ return FlockContext.from_dict(self.to_dict())
89
+ except Exception:
90
+ raise
91
+
92
+ def get_agent_history(self, agent_name: str) -> list[AgentRunRecord]:
93
+ """Return all agent run records for a given agent name."""
94
+ try:
95
+ return [
96
+ record for record in self.history if record.agent == agent_name
97
+ ]
98
+ except Exception:
99
+ raise
100
+
101
+ def next_input_for(self, agent) -> Any:
102
+ """By default, the next input for an agent is taken from the context state.
103
+
104
+ If the agent.input is a comma-separated list (e.g., "input1, input2"),
105
+ this method will return a dictionary with keys for each of the input names,
106
+ fetching the latest values from the state.
107
+
108
+ If only a single input is specified, the raw value is returned.
109
+ """
110
+ try:
111
+ if hasattr(agent, "input") and isinstance(agent.input, str):
112
+ keys = [k.strip() for k in agent.input.split(",") if k.strip()]
113
+
114
+ if len(keys) == 1:
115
+ return self.get_variable(keys[0])
116
+ else:
117
+ return {key: self.get_variable(key) for key in keys}
118
+ else:
119
+ # Fallback to "init_input"
120
+ return self.get_variable("init_input")
121
+ except Exception:
122
+ raise
123
+
124
+ def get_most_recent_value(self, variable_name: str) -> Any:
125
+ """Get the definition for a specific agent."""
126
+ try:
127
+ for history_record in reversed(self.history):
128
+ if variable_name in history_record.data:
129
+ return history_record.data[variable_name]
130
+ except Exception:
131
+ raise
132
+
133
+ def get_agent_definition(self, agent_name: str) -> AgentDefinition | None:
134
+ """Get the definition for a specific agent."""
135
+ try:
136
+ for definition in self.agent_definitions:
137
+ if definition.name == agent_name:
138
+ return definition
139
+ return None
140
+ except Exception:
141
+ raise
142
+
143
+ def add_agent_definition(
144
+ self, agent_type: type, agent_name: str, agent_data: Any
145
+ ) -> None:
146
+ """Add a new agent definition to the context."""
147
+ try:
148
+ definition = AgentDefinition(
149
+ agent_type=agent_type.__name__,
150
+ agent_name=agent_name,
151
+ agent_data=agent_data,
152
+ )
153
+ self.agent_definitions[agent_name] = definition
154
+ except Exception:
155
+ raise
156
+
157
+ # Allow dict-like access for convenience.
158
+ def __getitem__(self, key: str) -> Any:
159
+ """Get the current value of a state variable."""
160
+ value = self.state[key]
161
+ return value
162
+
163
+ def __setitem__(self, key: str, value: Any) -> None:
164
+ """Set the value of a state variable."""
165
+ self.state[key] = value
166
+
167
+ def to_dict(self) -> dict[str, Any]:
168
+ """Convert the context to a dictionary for serialization."""
169
+ try:
170
+
171
+ def convert(obj):
172
+ if isinstance(obj, datetime):
173
+ return obj.isoformat()
174
+ if hasattr(obj, "__dataclass_fields__"): # Is a dataclass
175
+ return asdict(
176
+ obj,
177
+ dict_factory=lambda x: {k: convert(v) for k, v in x},
178
+ )
179
+ return obj
180
+
181
+ return convert(asdict(self))
182
+ except Exception:
183
+ raise
184
+
185
+ @classmethod
186
+ def from_dict(cls, data: dict[str, Any]) -> "FlockContext":
187
+ """Create a context instance from a dictionary."""
188
+ try:
189
+
190
+ def convert(obj):
191
+ if isinstance(obj, dict):
192
+ if "timestamp" in obj: # AgentRunRecord
193
+ return AgentRunRecord(
194
+ **{
195
+ **obj,
196
+ "timestamp": datetime.fromisoformat(
197
+ obj["timestamp"]
198
+ ),
199
+ }
200
+ )
201
+ if "agent_type" in obj: # AgentDefinition
202
+ return AgentDefinition(**obj)
203
+ return {k: convert(v) for k, v in obj.items()}
204
+ if isinstance(obj, list):
205
+ return [convert(v) for v in obj]
206
+ return obj
207
+
208
+ converted = convert(data)
209
+ return cls(**converted)
210
+ except Exception:
211
+ raise
@@ -0,0 +1,34 @@
1
+ """Module for managing the FlockContext."""
2
+
3
+ from flock.core.context.context import FlockContext
4
+ from flock.core.context.context_vars import (
5
+ FLOCK_CURRENT_AGENT,
6
+ FLOCK_INITIAL_INPUT,
7
+ FLOCK_LOCAL_DEBUG,
8
+ FLOCK_RUN_ID,
9
+ )
10
+
11
+
12
+ def initialize_context(
13
+ context: FlockContext,
14
+ agent_name: str,
15
+ input_data: dict,
16
+ run_id: str,
17
+ local_debug: bool,
18
+ ) -> None:
19
+ """Initialize the FlockContext with standard variables before running an agent.
20
+
21
+ Args:
22
+ context: The FlockContext instance.
23
+ agent_name: The name of the current agent.
24
+ input_data: A dictionary of inputs for the agent.
25
+ run_id: A unique identifier for the run.
26
+ local_debug: Flag indicating whether local debugging is enabled.
27
+ """
28
+ context.set_variable(FLOCK_CURRENT_AGENT, agent_name)
29
+ for key, value in input_data.items():
30
+ context.set_variable("flock." + key, value)
31
+ context.set_variable(FLOCK_INITIAL_INPUT, input_data)
32
+ context.set_variable(FLOCK_LOCAL_DEBUG, local_debug)
33
+ context.run_id = run_id
34
+ context.set_variable(FLOCK_RUN_ID, run_id)
@@ -1,6 +1,8 @@
1
- FLOCK_CURRENT_AGENT = "flock.current_agent"
2
- FLOCK_INITIAL_INPUT = "flock.initial_input"
3
- FLOCK_LOCAL_DEBUG = "flock.local_debug"
4
- FLOCK_RUN_ID = "flock.run_id"
5
- FLOCK_LAST_AGENT = "flock.last_agent"
6
- FLOCK_LAST_RESULT = "flock.last_result"
1
+ """Context variables for Flock."""
2
+
3
+ FLOCK_CURRENT_AGENT = "flock.current_agent"
4
+ FLOCK_INITIAL_INPUT = "flock.initial_input"
5
+ FLOCK_LOCAL_DEBUG = "flock.local_debug"
6
+ FLOCK_RUN_ID = "flock.run_id"
7
+ FLOCK_LAST_AGENT = "flock.last_agent"
8
+ FLOCK_LAST_RESULT = "flock.last_result"