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.
- flock/__init__.py +1 -4
- flock/agents/__init__.py +0 -3
- flock/agents/batch_agent.py +140 -175
- flock/agents/loop_agent.py +117 -178
- flock/agents/trigger_agent.py +113 -191
- flock/agents/user_agent.py +145 -230
- flock/core/__init__.py +1 -7
- flock/core/context/context.py +211 -0
- flock/core/context/context_manager.py +34 -0
- flock/core/{context_vars.py → context/context_vars.py} +8 -6
- flock/core/execution/local_executor.py +27 -0
- flock/core/execution/temporal_executor.py +40 -0
- flock/core/flock.py +199 -208
- flock/core/flock_agent.py +492 -0
- flock/core/logging/__init__.py +2 -18
- flock/core/logging/formatters/base_formatter.py +36 -0
- flock/core/logging/formatters/formatter_factory.py +38 -0
- flock/core/logging/formatters/pprint_formatter.py +18 -0
- flock/core/logging/formatters/rich_formatters.py +132 -0
- flock/core/logging/formatters/theme_builder.py +480 -0
- flock/core/logging/formatters/themed_formatter.py +442 -0
- flock/core/logging/logging.py +123 -0
- flock/core/mixin/dspy_integration.py +171 -0
- flock/core/mixin/prompt_parser.py +125 -0
- flock/core/registry/agent_registry.py +103 -0
- flock/core/tools/basic_tools.py +273 -98
- flock/core/tools/dev_tools/github.py +161 -0
- flock/core/util/cli_helper.py +21 -0
- flock/core/util/input_resolver.py +156 -0
- flock/core/util/serializable.py +93 -0
- flock/themes/3024-day.toml +39 -0
- flock/themes/3024-night.toml +77 -0
- flock/themes/aardvark-blue.toml +77 -0
- flock/themes/abernathy.toml +77 -0
- flock/themes/adventure.toml +77 -0
- flock/themes/adventuretime.toml +77 -0
- flock/themes/afterglow.toml +77 -0
- flock/themes/alabaster.toml +77 -0
- flock/themes/alienblood.toml +77 -0
- flock/themes/andromeda.toml +77 -0
- flock/themes/apple-classic.toml +77 -0
- flock/themes/apple-system-colors.toml +77 -0
- flock/themes/arcoiris.toml +77 -0
- flock/themes/argonaut copy.toml +77 -0
- flock/themes/argonaut.toml +39 -0
- flock/themes/arthur.toml +77 -0
- flock/themes/ateliersulphurpool.toml +77 -0
- flock/themes/atom.toml +38 -0
- flock/themes/atom_test.toml +65 -0
- flock/themes/atomonelight.toml +77 -0
- flock/themes/aurora.toml +77 -0
- flock/themes/ayu copy.toml +77 -0
- flock/themes/ayu-light.toml +77 -0
- flock/themes/ayu-mirage.toml +77 -0
- flock/themes/ayu.toml +39 -0
- flock/themes/banana-blueberry.toml +77 -0
- flock/themes/batman.toml +77 -0
- flock/themes/belafonte-day.toml +77 -0
- flock/themes/belafonte-night.toml +77 -0
- flock/themes/birdsofparadise.toml +77 -0
- flock/themes/blazer.toml +77 -0
- flock/themes/blue-matrix.toml +77 -0
- flock/themes/blueberrypie.toml +77 -0
- flock/themes/bluedolphin.toml +77 -0
- flock/themes/blulocodark.toml +77 -0
- flock/themes/blulocolight.toml +77 -0
- flock/themes/borland.toml +77 -0
- flock/themes/breeze.toml +77 -0
- flock/themes/bright-lights.toml +77 -0
- flock/themes/broadcast.toml +77 -0
- flock/themes/brogrammer.toml +77 -0
- flock/themes/builtin-dark.toml +77 -0
- flock/themes/builtin-light.toml +77 -0
- flock/themes/builtin-pastel-dark.toml +77 -0
- flock/themes/builtin-solarized-dark.toml +77 -0
- flock/themes/builtin-solarized-light.toml +77 -0
- flock/themes/builtin-tango-dark.toml +77 -0
- flock/themes/builtin-tango-light.toml +77 -0
- flock/themes/c64.toml +77 -0
- flock/themes/calamity.toml +77 -0
- flock/themes/catppuccin-frappe.toml +77 -0
- flock/themes/catppuccin-latte.toml +77 -0
- flock/themes/catppuccin-macchiato.toml +77 -0
- flock/themes/catppuccin-mocha.toml +77 -0
- flock/themes/cga.toml +77 -0
- flock/themes/chalk.toml +77 -0
- flock/themes/chalkboard.toml +77 -0
- flock/themes/challengerdeep.toml +77 -0
- flock/themes/chester.toml +77 -0
- flock/themes/ciapre.toml +77 -0
- flock/themes/clrs.toml +77 -0
- flock/themes/cobalt-neon.toml +77 -0
- flock/themes/cobalt2.toml +77 -0
- flock/themes/coffee-theme.toml +77 -0
- flock/themes/crayonponyfish.toml +77 -0
- flock/themes/cutiepro.toml +77 -0
- flock/themes/cyberdyne.toml +77 -0
- flock/themes/cyberpunk.toml +77 -0
- flock/themes/cyberpunkscarletprotocol.toml +77 -0
- flock/themes/dark+.toml +77 -0
- flock/themes/dark-pastel.toml +77 -0
- flock/themes/darkermatrix.toml +77 -0
- flock/themes/darkmatrix.toml +77 -0
- flock/themes/darkside.toml +77 -0
- flock/themes/dayfox.toml +77 -0
- flock/themes/deep.toml +77 -0
- flock/themes/desert.toml +77 -0
- flock/themes/dimidium.toml +77 -0
- flock/themes/dimmedmonokai.toml +77 -0
- flock/themes/django.toml +77 -0
- flock/themes/djangorebornagain.toml +77 -0
- flock/themes/djangosmooth.toml +77 -0
- flock/themes/doom-peacock.toml +77 -0
- flock/themes/doomone.toml +77 -0
- flock/themes/dotgov.toml +77 -0
- flock/themes/dracula+.toml +77 -0
- flock/themes/dracula.toml +77 -0
- flock/themes/duckbones.toml +77 -0
- flock/themes/duotone-dark.toml +77 -0
- flock/themes/earthsong.toml +77 -0
- flock/themes/elemental.toml +77 -0
- flock/themes/elementary.toml +77 -0
- flock/themes/encom.toml +77 -0
- flock/themes/espresso-libre.toml +77 -0
- flock/themes/espresso.toml +77 -0
- flock/themes/everblush.toml +77 -0
- flock/themes/fahrenheit.toml +77 -0
- flock/themes/fairyfloss.toml +77 -0
- flock/themes/farmhouse-dark.toml +77 -0
- flock/themes/farmhouse-light.toml +77 -0
- flock/themes/fideloper.toml +77 -0
- flock/themes/firefly-traditional.toml +77 -0
- flock/themes/firefoxdev.toml +77 -0
- flock/themes/firewatch.toml +77 -0
- flock/themes/fishtank.toml +77 -0
- flock/themes/flat.toml +77 -0
- flock/themes/flatland.toml +77 -0
- flock/themes/flexoki-dark.toml +77 -0
- flock/themes/flexoki-light.toml +77 -0
- flock/themes/floraverse.toml +77 -0
- flock/themes/forestblue.toml +77 -0
- flock/themes/framer.toml +77 -0
- flock/themes/frontenddelight.toml +77 -0
- flock/themes/funforrest.toml +77 -0
- flock/themes/galaxy.toml +77 -0
- flock/themes/galizur.toml +77 -0
- flock/themes/github-dark.toml +77 -0
- flock/themes/github.toml +77 -0
- flock/themes/glacier.toml +77 -0
- flock/themes/grape.toml +77 -0
- flock/themes/grass.toml +77 -0
- flock/themes/grey-green.toml +77 -0
- flock/themes/gruber-darker.toml +77 -0
- flock/themes/gruvboxdark.toml +77 -0
- flock/themes/gruvboxdarkhard.toml +77 -0
- flock/themes/gruvboxlight.toml +77 -0
- flock/themes/guezwhoz.toml +77 -0
- flock/themes/hacktober.toml +77 -0
- flock/themes/hardcore.toml +77 -0
- flock/themes/harper.toml +77 -0
- flock/themes/hax0r-blue.toml +77 -0
- flock/themes/hax0r-gr33n.toml +77 -0
- flock/themes/hax0r-r3d.toml +77 -0
- flock/themes/highway.toml +77 -0
- flock/themes/hipster-green.toml +77 -0
- flock/themes/hivacruz.toml +77 -0
- flock/themes/homebrew.toml +77 -0
- flock/themes/hopscotch.256.toml +77 -0
- flock/themes/hopscotch.toml +77 -0
- flock/themes/hurtado.toml +77 -0
- flock/themes/hybrid.toml +77 -0
- flock/themes/ic-green-ppl.toml +77 -0
- flock/themes/ic-orange-ppl.toml +77 -0
- flock/themes/iceberg-dark.toml +77 -0
- flock/themes/iceberg-light.toml +77 -0
- flock/themes/idea.toml +77 -0
- flock/themes/idletoes.toml +77 -0
- flock/themes/ir-black.toml +77 -0
- flock/themes/iterm2-dark-background.toml +77 -0
- flock/themes/iterm2-default.toml +77 -0
- flock/themes/iterm2-light-background.toml +77 -0
- flock/themes/iterm2-pastel-dark-background.toml +77 -0
- flock/themes/iterm2-smoooooth.toml +77 -0
- flock/themes/iterm2-solarized-dark.toml +77 -0
- flock/themes/iterm2-solarized-light.toml +77 -0
- flock/themes/iterm2-tango-dark.toml +77 -0
- flock/themes/iterm2-tango-light.toml +77 -0
- flock/themes/jackie-brown.toml +77 -0
- flock/themes/japanesque.toml +77 -0
- flock/themes/jellybeans.toml +77 -0
- flock/themes/jetbrains-darcula.toml +77 -0
- flock/themes/jubi.toml +77 -0
- flock/themes/kanagawabones.toml +77 -0
- flock/themes/kibble.toml +77 -0
- flock/themes/kolorit.toml +77 -0
- flock/themes/konsolas.toml +77 -0
- flock/themes/kurokula.toml +77 -0
- flock/themes/lab-fox.toml +77 -0
- flock/themes/laser.toml +77 -0
- flock/themes/later-this-evening.toml +77 -0
- flock/themes/lavandula.toml +77 -0
- flock/themes/liquidcarbon.toml +77 -0
- flock/themes/liquidcarbontransparent.toml +77 -0
- flock/themes/liquidcarbontransparentinverse.toml +77 -0
- flock/themes/lovelace.toml +77 -0
- flock/themes/man-page.toml +77 -0
- flock/themes/mariana.toml +77 -0
- flock/themes/material.toml +77 -0
- flock/themes/materialdark.toml +77 -0
- flock/themes/materialdarker.toml +77 -0
- flock/themes/materialdesigncolors.toml +77 -0
- flock/themes/materialocean.toml +77 -0
- flock/themes/mathias.toml +77 -0
- flock/themes/matrix.toml +77 -0
- flock/themes/medallion.toml +77 -0
- flock/themes/mellifluous.toml +77 -0
- flock/themes/midnight-in-mojave.toml +77 -0
- flock/themes/mirage.toml +77 -0
- flock/themes/misterioso.toml +77 -0
- flock/themes/molokai.toml +77 -0
- flock/themes/monalisa.toml +77 -0
- flock/themes/monokai-remastered.toml +77 -0
- flock/themes/monokai-soda.toml +77 -0
- flock/themes/monokai-vivid.toml +77 -0
- flock/themes/n0tch2k.toml +77 -0
- flock/themes/neobones-dark.toml +77 -0
- flock/themes/neobones-light.toml +77 -0
- flock/themes/neon.toml +77 -0
- flock/themes/neopolitan.toml +77 -0
- flock/themes/neutron.toml +77 -0
- flock/themes/night-owlish-light.toml +77 -0
- flock/themes/nightfox.toml +77 -0
- flock/themes/nightlion-v1.toml +77 -0
- flock/themes/nightlion-v2.toml +77 -0
- flock/themes/niji.toml +77 -0
- flock/themes/nocturnal-winter.toml +77 -0
- flock/themes/nord-light.toml +77 -0
- flock/themes/nord.toml +77 -0
- flock/themes/novel.toml +77 -0
- flock/themes/nvimdark.toml +77 -0
- flock/themes/nvimlight.toml +77 -0
- flock/themes/obsidian.toml +77 -0
- flock/themes/ocean.toml +77 -0
- flock/themes/oceanic-next.toml +77 -0
- flock/themes/oceanicmaterial.toml +77 -0
- flock/themes/ollie.toml +77 -0
- flock/themes/onehalfdark.toml +77 -0
- flock/themes/onehalflight.toml +77 -0
- flock/themes/operator-mono-dark.toml +77 -0
- flock/themes/overnight-slumber.toml +77 -0
- flock/themes/oxocarbon.toml +77 -0
- flock/themes/palenighthc.toml +77 -0
- flock/themes/pandora.toml +77 -0
- flock/themes/paraiso-dark.toml +77 -0
- flock/themes/paulmillr.toml +77 -0
- flock/themes/pencildark.toml +77 -0
- flock/themes/pencillight.toml +77 -0
- flock/themes/peppermint.toml +77 -0
- flock/themes/piatto-light.toml +77 -0
- flock/themes/pnevma.toml +77 -0
- flock/themes/popping-and-locking.toml +77 -0
- flock/themes/primary.toml +77 -0
- flock/themes/pro-light.toml +77 -0
- flock/themes/pro.toml +77 -0
- flock/themes/purple-rain.toml +77 -0
- flock/themes/purplepeter.toml +77 -0
- flock/themes/rapture.toml +77 -0
- flock/themes/raycast-dark.toml +77 -0
- flock/themes/raycast-light.toml +77 -0
- flock/themes/rebecca.toml +77 -0
- flock/themes/red-alert.toml +77 -0
- flock/themes/red-planet.toml +77 -0
- flock/themes/red-sands.toml +77 -0
- flock/themes/relaxed.toml +77 -0
- flock/themes/retro.toml +77 -0
- flock/themes/rippedcasts.toml +77 -0
- flock/themes/rose-pine-dawn.toml +77 -0
- flock/themes/rose-pine-moon.toml +77 -0
- flock/themes/rose-pine.toml +77 -0
- flock/themes/rouge-2.toml +77 -0
- flock/themes/royal.toml +77 -0
- flock/themes/ryuuko.toml +77 -0
- flock/themes/sakura.toml +77 -0
- flock/themes/scarlet-protocol.toml +77 -0
- flock/themes/seafoam-pastel.toml +77 -0
- flock/themes/seashells.toml +77 -0
- flock/themes/seoulbones-dark.toml +77 -0
- flock/themes/seoulbones-light.toml +77 -0
- flock/themes/seti.toml +77 -0
- flock/themes/shades-of-purple.toml +77 -0
- flock/themes/shaman.toml +77 -0
- flock/themes/slate.toml +77 -0
- flock/themes/sleepyhollow.toml +77 -0
- flock/themes/smyck.toml +77 -0
- flock/themes/snazzy.toml +77 -0
- flock/themes/softserver.toml +77 -0
- flock/themes/solarized-darcula.toml +77 -0
- flock/themes/solarized-dark---patched.toml +77 -0
- flock/themes/solarized-dark-higher-contrast.toml +77 -0
- flock/themes/spacedust.toml +77 -0
- flock/themes/spacegray-eighties-dull.toml +77 -0
- flock/themes/spacegray-eighties.toml +77 -0
- flock/themes/spacegray.toml +77 -0
- flock/themes/spiderman.toml +77 -0
- flock/themes/spring.toml +77 -0
- flock/themes/square.toml +77 -0
- flock/themes/sublette.toml +77 -0
- flock/themes/subliminal.toml +77 -0
- flock/themes/sugarplum.toml +77 -0
- flock/themes/sundried.toml +77 -0
- flock/themes/symfonic.toml +77 -0
- flock/themes/synthwave-everything.toml +77 -0
- flock/themes/synthwave.toml +77 -0
- flock/themes/synthwavealpha.toml +77 -0
- flock/themes/tango-adapted.toml +77 -0
- flock/themes/tango-half-adapted.toml +77 -0
- flock/themes/teerb.toml +77 -0
- flock/themes/terafox.toml +77 -0
- flock/themes/terminal-basic.toml +77 -0
- flock/themes/thayer-bright.toml +77 -0
- flock/themes/the-hulk.toml +77 -0
- flock/themes/tinacious-design-(dark).toml +77 -0
- flock/themes/tinacious-design-(light).toml +77 -0
- flock/themes/tokyonight-day.toml +77 -0
- flock/themes/tokyonight-storm.toml +77 -0
- flock/themes/tokyonight.toml +77 -0
- flock/themes/tomorrow-night-blue.toml +77 -0
- flock/themes/tomorrow-night-bright.toml +77 -0
- flock/themes/tomorrow-night-burns.toml +77 -0
- flock/themes/tomorrow-night-eighties.toml +77 -0
- flock/themes/tomorrow-night.toml +77 -0
- flock/themes/tomorrow.toml +77 -0
- flock/themes/toychest.toml +77 -0
- flock/themes/treehouse.toml +77 -0
- flock/themes/twilight.toml +77 -0
- flock/themes/ubuntu.toml +77 -0
- flock/themes/ultradark.toml +77 -0
- flock/themes/ultraviolent.toml +77 -0
- flock/themes/underthesea.toml +77 -0
- flock/themes/unikitty.toml +77 -0
- flock/themes/urple.toml +77 -0
- flock/themes/vaughn.toml +77 -0
- flock/themes/vesper.toml +77 -0
- flock/themes/vibrantink.toml +77 -0
- flock/themes/vimbones.toml +77 -0
- flock/themes/violet-dark.toml +77 -0
- flock/themes/violet-light.toml +77 -0
- flock/themes/warmneon.toml +77 -0
- flock/themes/wez.toml +77 -0
- flock/themes/whimsy.toml +77 -0
- flock/themes/wildcherry.toml +77 -0
- flock/themes/wilmersdorf.toml +77 -0
- flock/themes/wombat.toml +77 -0
- flock/themes/wryan.toml +77 -0
- flock/themes/xcodedark.toml +77 -0
- flock/themes/xcodedarkhc.toml +77 -0
- flock/themes/xcodelight.toml +77 -0
- flock/themes/xcodelighthc.toml +77 -0
- flock/themes/xcodewwdc.toml +77 -0
- flock/themes/zenbones-dark.toml +77 -0
- flock/themes/zenbones-light.toml +77 -0
- flock/themes/zenbones.toml +77 -0
- flock/themes/zenburn.toml +77 -0
- flock/themes/zenburned.toml +77 -0
- flock/themes/zenwritten-dark.toml +77 -0
- flock/themes/zenwritten-light.toml +77 -0
- flock/workflow/activities.py +117 -115
- flock/workflow/agent_activities.py +24 -26
- flock/workflow/temporal_setup.py +38 -37
- flock/workflow/workflow.py +58 -53
- flock_core-0.2.1.dist-info/METADATA +287 -0
- flock_core-0.2.1.dist-info/RECORD +375 -0
- {flock_core-0.1.2.dist-info → flock_core-0.2.1.dist-info}/licenses/LICENSE +21 -21
- flock/agents/declarative_agent.py +0 -166
- flock/app/components/__init__.py +0 -14
- flock/app/components/charts/agent_workflow.py +0 -14
- flock/app/components/charts/core_architecture.py +0 -14
- flock/app/components/charts/tool_system.py +0 -14
- flock/app/components/history_grid.py +0 -168
- flock/app/components/history_grid_alt.py +0 -189
- flock/app/components/sidebar.py +0 -19
- flock/app/components/theme.py +0 -9
- flock/app/components/util.py +0 -18
- flock/app/hive_app.py +0 -118
- flock/app/html/d3.html +0 -179
- flock/app/modules/__init__.py +0 -12
- flock/app/modules/about.py +0 -17
- flock/app/modules/agent_detail.py +0 -70
- flock/app/modules/agent_list.py +0 -59
- flock/app/modules/playground.py +0 -322
- flock/app/modules/settings.py +0 -96
- flock/core/agent.py +0 -150
- flock/core/agent_registry.py +0 -162
- flock/core/context.py +0 -279
- flock/core/handoff/handoff_base.py +0 -12
- flock/core/logging/error_handler.py +0 -84
- flock/core/logging/formatters.py +0 -122
- flock/core/logging/handlers.py +0 -117
- flock/core/logging/logger.py +0 -107
- flock/core/serializable.py +0 -206
- flock_core-0.1.2.dist-info/METADATA +0 -476
- flock_core-0.1.2.dist-info/RECORD +0 -48
- flock_core-0.1.2.dist-info/entry_points.txt +0 -2
- /flock/{core/config/declarative_agent_config.py → workflow/__init__.py} +0 -0
- {flock_core-0.1.2.dist-info → flock_core-0.2.1.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""Mixin class for integrating with the dspy library."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import dspy
|
|
7
|
+
|
|
8
|
+
from flock.core.logging.logging import get_logger
|
|
9
|
+
from flock.core.util.input_resolver import split_top_level
|
|
10
|
+
|
|
11
|
+
logger = get_logger("flock")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class DSPyIntegrationMixin:
|
|
15
|
+
"""Mixin class for integrating with the dspy library."""
|
|
16
|
+
|
|
17
|
+
def create_dspy_signature_class(
|
|
18
|
+
self, agent_name, description_spec, fields_spec
|
|
19
|
+
) -> dspy.Signature:
|
|
20
|
+
"""Trying to create a dynamic class using dspy library."""
|
|
21
|
+
# ---------------------------
|
|
22
|
+
# 1. Parse the class specification.
|
|
23
|
+
# ---------------------------
|
|
24
|
+
base_class = dspy.Signature
|
|
25
|
+
|
|
26
|
+
# Start building the class dictionary with a docstring and annotations dict.
|
|
27
|
+
class_dict = {"__doc__": description_spec, "__annotations__": {}}
|
|
28
|
+
|
|
29
|
+
# ---------------------------
|
|
30
|
+
# 2. Split the fields specification into inputs and outputs.
|
|
31
|
+
# ---------------------------
|
|
32
|
+
if "->" in fields_spec:
|
|
33
|
+
inputs_spec, outputs_spec = fields_spec.split("->", 1)
|
|
34
|
+
else:
|
|
35
|
+
inputs_spec, outputs_spec = fields_spec, ""
|
|
36
|
+
|
|
37
|
+
# ---------------------------
|
|
38
|
+
# 3. Draw the rest of the owl.
|
|
39
|
+
# ---------------------------
|
|
40
|
+
def parse_field(field_str):
|
|
41
|
+
"""Parser.
|
|
42
|
+
|
|
43
|
+
Parse a field of the form:
|
|
44
|
+
<name> [ : <type> ] [ | <desc> ]
|
|
45
|
+
Returns a tuple: (name, field_type, desc)
|
|
46
|
+
"""
|
|
47
|
+
field_str = field_str.strip()
|
|
48
|
+
if not field_str:
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
parts = field_str.split("|", 1)
|
|
52
|
+
main_part = parts[0].strip() # contains name and (optionally) type
|
|
53
|
+
desc = parts[1].strip() if len(parts) > 1 else None
|
|
54
|
+
|
|
55
|
+
if ":" in main_part:
|
|
56
|
+
name, type_str = [s.strip() for s in main_part.split(":", 1)]
|
|
57
|
+
else:
|
|
58
|
+
name = main_part
|
|
59
|
+
type_str = "str" # default type
|
|
60
|
+
|
|
61
|
+
# Evaluate the type. Since type can be any valid expression (including custom types),
|
|
62
|
+
# we use eval. (Be cautious if using eval with untrusted input.)
|
|
63
|
+
try:
|
|
64
|
+
# TODO: We have to find a way to avoid using eval here.
|
|
65
|
+
# This is a security risk, as it allows arbitrary code execution.
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
field_type = eval(type_str, sys.modules[__name__].__dict__)
|
|
69
|
+
except Exception:
|
|
70
|
+
field_type = eval(
|
|
71
|
+
type_str, sys.modules["__main__"].__dict__
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
except Exception:
|
|
75
|
+
# If evaluation fails, default to str.
|
|
76
|
+
field_type = str
|
|
77
|
+
|
|
78
|
+
return name, field_type, desc
|
|
79
|
+
|
|
80
|
+
def process_fields(fields_string, field_kind):
|
|
81
|
+
"""Process a comma-separated list of field definitions.
|
|
82
|
+
|
|
83
|
+
field_kind: "input" or "output" determines which Field constructor to use.
|
|
84
|
+
"""
|
|
85
|
+
if not fields_string.strip():
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
# Split on commas.
|
|
89
|
+
for field in split_top_level(fields_string):
|
|
90
|
+
if field.strip():
|
|
91
|
+
parsed = parse_field(field)
|
|
92
|
+
if not parsed:
|
|
93
|
+
continue
|
|
94
|
+
name, field_type, desc = parsed
|
|
95
|
+
class_dict["__annotations__"][name] = field_type
|
|
96
|
+
|
|
97
|
+
# Use the proper Field constructor.
|
|
98
|
+
if field_kind == "input":
|
|
99
|
+
if desc is not None:
|
|
100
|
+
class_dict[name] = dspy.InputField(desc=desc)
|
|
101
|
+
else:
|
|
102
|
+
class_dict[name] = dspy.InputField()
|
|
103
|
+
elif field_kind == "output":
|
|
104
|
+
if desc is not None:
|
|
105
|
+
class_dict[name] = dspy.OutputField(desc=desc)
|
|
106
|
+
else:
|
|
107
|
+
class_dict[name] = dspy.OutputField()
|
|
108
|
+
else:
|
|
109
|
+
raise ValueError("Unknown field kind: " + field_kind)
|
|
110
|
+
|
|
111
|
+
# Process input fields (to be used with my.InputField)
|
|
112
|
+
process_fields(inputs_spec, "input")
|
|
113
|
+
# Process output fields (to be used with my.OutputField)
|
|
114
|
+
process_fields(outputs_spec, "output")
|
|
115
|
+
|
|
116
|
+
return type("dspy_" + agent_name, (base_class,), class_dict)
|
|
117
|
+
|
|
118
|
+
def _configure_language_model(self) -> None:
|
|
119
|
+
"""Initialize and configure the language model using dspy."""
|
|
120
|
+
lm = dspy.LM(self.model, cache=self.use_cache)
|
|
121
|
+
dspy.configure(lm=lm)
|
|
122
|
+
|
|
123
|
+
def _select_task(
|
|
124
|
+
self,
|
|
125
|
+
signature: dspy.Signature,
|
|
126
|
+
) -> Any:
|
|
127
|
+
"""Select and instantiate the appropriate task based on tool availability.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
prompt: The detailed prompt string.
|
|
131
|
+
input_desc: Dictionary of input key descriptions.
|
|
132
|
+
output_desc: Dictionary of output key descriptions.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
An instance of a dspy task (either ReAct or Predict).
|
|
136
|
+
"""
|
|
137
|
+
dspy_solver = None
|
|
138
|
+
if self.tools:
|
|
139
|
+
dspy_solver = dspy.ReAct(
|
|
140
|
+
signature,
|
|
141
|
+
tools=self.tools,
|
|
142
|
+
max_iters=10,
|
|
143
|
+
)
|
|
144
|
+
else:
|
|
145
|
+
dspy_solver = dspy.Predict(
|
|
146
|
+
signature,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
return dspy_solver
|
|
150
|
+
|
|
151
|
+
def _process_result(
|
|
152
|
+
self, result: Any, inputs: dict[str, Any]
|
|
153
|
+
) -> dict[str, Any]:
|
|
154
|
+
"""Convert the result to a dictionary and add the inputs for an unified result object.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
result: The raw result from the dspy task.
|
|
158
|
+
inputs: The original inputs provided to the agent.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
A dictionary containing the processed output.
|
|
162
|
+
"""
|
|
163
|
+
try:
|
|
164
|
+
result = result.toDict()
|
|
165
|
+
for key in inputs:
|
|
166
|
+
result.setdefault(key, inputs.get(key))
|
|
167
|
+
except Exception as conv_error:
|
|
168
|
+
logger.warning(
|
|
169
|
+
f"Warning: Failed to convert result to dict in agent '{self.name}': {conv_error}"
|
|
170
|
+
)
|
|
171
|
+
return result
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""A mixin class for parsing agent prompts and building clean signatures for DSPy."""
|
|
2
|
+
|
|
3
|
+
# DEPRECATED! This mixin is no longer used in the current version of Flock. It was used to parse agent prompts and build clean signatures for DSPy.
|
|
4
|
+
# TODO: DELETE THIS FILE!
|
|
5
|
+
|
|
6
|
+
from flock.core.util.input_resolver import split_top_level
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class PromptParserMixin:
|
|
10
|
+
"""A mixin class for parsing agent prompts and building clean signatures for DSPy."""
|
|
11
|
+
|
|
12
|
+
def _parse_key_descriptions(self, keys_str: str) -> list[tuple[str, str]]:
|
|
13
|
+
"""Parse a comma-separated string into a list of (key, description) tuples.
|
|
14
|
+
|
|
15
|
+
This function processes a configuration string that defines one or more keys, where each key may
|
|
16
|
+
include a type hint and an optional human-readable description. The expected format for each key is:
|
|
17
|
+
|
|
18
|
+
key: type_hint | description
|
|
19
|
+
|
|
20
|
+
If the pipe symbol ("|") is absent, the description is set to an empty string.
|
|
21
|
+
|
|
22
|
+
The splitting is performed using split_top_level() so that commas inside type hints are preserved.
|
|
23
|
+
|
|
24
|
+
For example, given:
|
|
25
|
+
"query: str | The search query, context: dict | The full conversation context"
|
|
26
|
+
it returns:
|
|
27
|
+
[("query", "The search query"), ("context", "The full conversation context")]
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
keys_str (str): A comma-separated string of key definitions.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
List[Tuple[str, str]]: A list of (key, description) tuples.
|
|
34
|
+
"""
|
|
35
|
+
key_descs = []
|
|
36
|
+
for part in split_top_level(keys_str):
|
|
37
|
+
if not part:
|
|
38
|
+
continue
|
|
39
|
+
if "|" in part:
|
|
40
|
+
key_type_part, desc = part.split("|", 1)
|
|
41
|
+
desc = desc.strip()
|
|
42
|
+
else:
|
|
43
|
+
key_type_part = part
|
|
44
|
+
desc = ""
|
|
45
|
+
key = key_type_part.split(":", 1)[0].strip()
|
|
46
|
+
key_descs.append((key, desc))
|
|
47
|
+
return key_descs
|
|
48
|
+
|
|
49
|
+
def _build_clean_signature(self, keys_str: str) -> str:
|
|
50
|
+
"""Build a clean signature string from the configuration string by removing the description parts.
|
|
51
|
+
|
|
52
|
+
Given a string like:
|
|
53
|
+
"query: str | The search query, context: dict | The full conversation context"
|
|
54
|
+
this method returns:
|
|
55
|
+
"query: str, context: dict"
|
|
56
|
+
|
|
57
|
+
This function uses split_top_level() to avoid splitting on commas that are inside type hints.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
keys_str (str): The configuration string containing keys, type hints, and optional descriptions.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
str: A clean signature string with only keys and type hints.
|
|
64
|
+
"""
|
|
65
|
+
parts = []
|
|
66
|
+
for part in split_top_level(keys_str):
|
|
67
|
+
if not part:
|
|
68
|
+
continue
|
|
69
|
+
if "|" in part:
|
|
70
|
+
clean_part = part.split("|", 1)[0].strip()
|
|
71
|
+
else:
|
|
72
|
+
clean_part = part.strip()
|
|
73
|
+
parts.append(clean_part)
|
|
74
|
+
return ", ".join(parts)
|
|
75
|
+
|
|
76
|
+
def _build_descriptions(self) -> tuple[dict[str, str], dict[str, str]]:
|
|
77
|
+
"""Build dictionaries of input and output descriptions from the agent's configuration.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
A tuple containing:
|
|
81
|
+
- input_desc: A dictionary mapping each input key (without type hints) to its description.
|
|
82
|
+
- output_desc: A dictionary mapping each output key (without type hints) to its description.
|
|
83
|
+
"""
|
|
84
|
+
input_desc: dict[str, str] = {}
|
|
85
|
+
if self.input:
|
|
86
|
+
for key, desc in self._parse_key_descriptions(self.input):
|
|
87
|
+
input_desc[key] = desc
|
|
88
|
+
|
|
89
|
+
output_desc: dict[str, str] = {}
|
|
90
|
+
if self.output:
|
|
91
|
+
for key, desc in self._parse_key_descriptions(self.output):
|
|
92
|
+
output_desc[key] = desc
|
|
93
|
+
|
|
94
|
+
return input_desc, output_desc
|
|
95
|
+
|
|
96
|
+
def _build_prompt(
|
|
97
|
+
self, input_desc: dict[str, str], output_desc: dict[str, str]
|
|
98
|
+
) -> str:
|
|
99
|
+
"""Build a clean signature prompt from the agent's configuration.
|
|
100
|
+
|
|
101
|
+
This method uses the original input and output strings (removing the description parts)
|
|
102
|
+
to create a signature string that is passed to DSPy. For example, if:
|
|
103
|
+
- self.input is "query: str | The search query, context: dict | The full conversation context"
|
|
104
|
+
- self.output is "result: str | The result"
|
|
105
|
+
then the prompt will be:
|
|
106
|
+
"query: str, context: dict -> result: str"
|
|
107
|
+
|
|
108
|
+
**Note:** The descriptive metadata is preserved in the dictionaries obtained from _build_descriptions,
|
|
109
|
+
which are passed separately to DSPy.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
input_desc: Dictionary of input key descriptions (for metadata only).
|
|
113
|
+
output_desc: Dictionary of output key descriptions (for metadata only).
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
A clean signature string for DSPy.
|
|
117
|
+
"""
|
|
118
|
+
clean_input = (
|
|
119
|
+
self._build_clean_signature(self.input) if self.input else ""
|
|
120
|
+
)
|
|
121
|
+
clean_output = (
|
|
122
|
+
self._build_clean_signature(self.output) if self.output else ""
|
|
123
|
+
)
|
|
124
|
+
# Combine the clean input and output signatures using "->"
|
|
125
|
+
return f"{clean_input} -> {clean_output}"
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Registry for storing and managing agents and tools."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
|
|
5
|
+
from flock.core.flock_agent import FlockAgent
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Registry:
|
|
9
|
+
"""Registry for storing and managing agents and tools.
|
|
10
|
+
|
|
11
|
+
This singleton class maintains a centralized registry of agents and tools,
|
|
12
|
+
which is particularly important for Temporal workflows where only basic Python
|
|
13
|
+
types can be passed between activities.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
_instance = None
|
|
17
|
+
|
|
18
|
+
def __new__(cls):
|
|
19
|
+
"""Singleton pattern implementation."""
|
|
20
|
+
if cls._instance is None:
|
|
21
|
+
cls._instance = super().__new__(cls)
|
|
22
|
+
cls._instance._initialize()
|
|
23
|
+
return cls._instance
|
|
24
|
+
|
|
25
|
+
def _initialize(self):
|
|
26
|
+
"""Initialize the registry's storage."""
|
|
27
|
+
self._agents: list[FlockAgent] = []
|
|
28
|
+
self._tools: list[tuple[str, Callable]] = []
|
|
29
|
+
|
|
30
|
+
def register_tool(self, tool_name: str, tool: Callable) -> None:
|
|
31
|
+
"""Register a tool with the registry.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
tool_name: The name to register the tool under
|
|
35
|
+
tool: The tool function to register
|
|
36
|
+
"""
|
|
37
|
+
try:
|
|
38
|
+
self._tools.append((tool_name, tool))
|
|
39
|
+
except Exception:
|
|
40
|
+
raise
|
|
41
|
+
|
|
42
|
+
def register_agent(self, agent: FlockAgent) -> None:
|
|
43
|
+
"""Register an agent with the registry.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
agent: The agent instance to register
|
|
47
|
+
"""
|
|
48
|
+
try:
|
|
49
|
+
self._agents.append(agent)
|
|
50
|
+
except Exception:
|
|
51
|
+
raise
|
|
52
|
+
|
|
53
|
+
def get_agent(self, name: str) -> FlockAgent | None:
|
|
54
|
+
"""Retrieve an agent by name.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
name: The name of the agent to retrieve
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
The agent instance if found, None otherwise
|
|
61
|
+
"""
|
|
62
|
+
try:
|
|
63
|
+
for agent in self._agents:
|
|
64
|
+
if agent.name == name:
|
|
65
|
+
return agent
|
|
66
|
+
return None
|
|
67
|
+
except Exception:
|
|
68
|
+
raise
|
|
69
|
+
|
|
70
|
+
def get_tool(self, name: str) -> Callable | None:
|
|
71
|
+
"""Retrieve a tool by name.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
name: The name of the tool to retrieve
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
The tool function if found, None otherwise
|
|
78
|
+
"""
|
|
79
|
+
try:
|
|
80
|
+
for tool_name, tool in self._tools:
|
|
81
|
+
if tool_name == name:
|
|
82
|
+
return tool
|
|
83
|
+
return None
|
|
84
|
+
except Exception:
|
|
85
|
+
raise
|
|
86
|
+
|
|
87
|
+
def get_tools(self, names: list[str] | None) -> list[Callable]:
|
|
88
|
+
"""Retrieve multiple tools by name.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
names: List of tool names to retrieve
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
List of found tool functions (may be empty if none found)
|
|
95
|
+
"""
|
|
96
|
+
try:
|
|
97
|
+
if not names:
|
|
98
|
+
return []
|
|
99
|
+
|
|
100
|
+
tools = [self.get_tool(name) for name in names]
|
|
101
|
+
return [tool for tool in tools if tool is not None]
|
|
102
|
+
except Exception:
|
|
103
|
+
raise
|