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
flock/app/html/d3.html
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<title>D3.js Node Graph</title>
|
|
6
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
|
|
7
|
-
<style>
|
|
8
|
-
.node {
|
|
9
|
-
stroke: #fff;
|
|
10
|
-
stroke-width: 1.5px;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.link {
|
|
14
|
-
stroke: #999;
|
|
15
|
-
stroke-opacity: 0.6;
|
|
16
|
-
stroke-width: 1px;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.node text {
|
|
20
|
-
pointer-events: none;
|
|
21
|
-
font: 10px sans-serif;
|
|
22
|
-
}
|
|
23
|
-
</style>
|
|
24
|
-
</head>
|
|
25
|
-
|
|
26
|
-
<body>
|
|
27
|
-
<div>Double-click background to add node. Drag nodes to move them.</div>
|
|
28
|
-
<svg width="800" height="600"></svg>
|
|
29
|
-
<script>
|
|
30
|
-
// Initial data
|
|
31
|
-
let data = {
|
|
32
|
-
nodes: [
|
|
33
|
-
{ id: 1, name: "Node 1" },
|
|
34
|
-
{ id: 2, name: "Node 2" },
|
|
35
|
-
{ id: 3, name: "Node 3" }
|
|
36
|
-
],
|
|
37
|
-
links: [
|
|
38
|
-
{ source: 0, target: 1 },
|
|
39
|
-
{ source: 1, target: 2 }
|
|
40
|
-
]
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// Create SVG container
|
|
44
|
-
const svg = d3.select("svg");
|
|
45
|
-
const width = +svg.attr("width");
|
|
46
|
-
const height = +svg.attr("height");
|
|
47
|
-
|
|
48
|
-
// Create force simulation
|
|
49
|
-
const simulation = d3.forceSimulation(data.nodes)
|
|
50
|
-
.force("link", d3.forceLink(data.links).id(d => d.id))
|
|
51
|
-
.force("charge", d3.forceManyBody().strength(-300))
|
|
52
|
-
.force("center", d3.forceCenter(width / 2, height / 2));
|
|
53
|
-
|
|
54
|
-
// Create the links
|
|
55
|
-
const link = svg.append("g")
|
|
56
|
-
.selectAll("line")
|
|
57
|
-
.data(data.links)
|
|
58
|
-
.join("line")
|
|
59
|
-
.attr("class", "link");
|
|
60
|
-
|
|
61
|
-
// Create the nodes
|
|
62
|
-
const node = svg.append("g")
|
|
63
|
-
.selectAll("g")
|
|
64
|
-
.data(data.nodes)
|
|
65
|
-
.join("g")
|
|
66
|
-
.attr("class", "node");
|
|
67
|
-
|
|
68
|
-
// Add circles to nodes
|
|
69
|
-
node.append("circle")
|
|
70
|
-
.attr("r", 10)
|
|
71
|
-
.style("fill", (d, i) => d3.schemeCategory10[i % 10]);
|
|
72
|
-
|
|
73
|
-
// Add labels to nodes
|
|
74
|
-
node.append("text")
|
|
75
|
-
.attr("dx", 12)
|
|
76
|
-
.attr("dy", ".35em")
|
|
77
|
-
.text(d => d.name);
|
|
78
|
-
|
|
79
|
-
// Add drag behavior
|
|
80
|
-
node.call(d3.drag()
|
|
81
|
-
.on("start", dragstarted)
|
|
82
|
-
.on("drag", dragged)
|
|
83
|
-
.on("end", dragended));
|
|
84
|
-
|
|
85
|
-
// Double click on background to add node
|
|
86
|
-
svg.on("dblclick", function (event) {
|
|
87
|
-
const coords = d3.pointer(event);
|
|
88
|
-
const newNode = {
|
|
89
|
-
id: data.nodes.length + 1,
|
|
90
|
-
name: `Node ${data.nodes.length + 1}`,
|
|
91
|
-
x: coords[0],
|
|
92
|
-
y: coords[1]
|
|
93
|
-
};
|
|
94
|
-
data.nodes.push(newNode);
|
|
95
|
-
|
|
96
|
-
// Add link to nearest node
|
|
97
|
-
if (data.nodes.length > 1) {
|
|
98
|
-
const lastNode = data.nodes[data.nodes.length - 2];
|
|
99
|
-
data.links.push({
|
|
100
|
-
source: lastNode,
|
|
101
|
-
target: newNode
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
updateGraph();
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// Update function to refresh the graph
|
|
109
|
-
function updateGraph() {
|
|
110
|
-
// Update links
|
|
111
|
-
const link = svg.selectAll(".link")
|
|
112
|
-
.data(data.links)
|
|
113
|
-
.join("line")
|
|
114
|
-
.attr("class", "link");
|
|
115
|
-
|
|
116
|
-
// Update nodes
|
|
117
|
-
const node = svg.selectAll(".node")
|
|
118
|
-
.data(data.nodes)
|
|
119
|
-
.join(
|
|
120
|
-
enter => {
|
|
121
|
-
const nodeEnter = enter.append("g")
|
|
122
|
-
.attr("class", "node")
|
|
123
|
-
.call(d3.drag()
|
|
124
|
-
.on("start", dragstarted)
|
|
125
|
-
.on("drag", dragged)
|
|
126
|
-
.on("end", dragended));
|
|
127
|
-
|
|
128
|
-
nodeEnter.append("circle")
|
|
129
|
-
.attr("r", 10)
|
|
130
|
-
.style("fill", (d, i) => d3.schemeCategory10[i % 10]);
|
|
131
|
-
|
|
132
|
-
nodeEnter.append("text")
|
|
133
|
-
.attr("dx", 12)
|
|
134
|
-
.attr("dy", ".35em")
|
|
135
|
-
.text(d => d.name);
|
|
136
|
-
|
|
137
|
-
return nodeEnter;
|
|
138
|
-
}
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
// Update simulation
|
|
142
|
-
simulation.nodes(data.nodes);
|
|
143
|
-
simulation.force("link").links(data.links);
|
|
144
|
-
simulation.alpha(1).restart();
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Simulation tick function
|
|
148
|
-
simulation.on("tick", () => {
|
|
149
|
-
link
|
|
150
|
-
.attr("x1", d => d.source.x)
|
|
151
|
-
.attr("y1", d => d.source.y)
|
|
152
|
-
.attr("x2", d => d.target.x)
|
|
153
|
-
.attr("y2", d => d.target.y);
|
|
154
|
-
|
|
155
|
-
node
|
|
156
|
-
.attr("transform", d => `translate(${d.x},${d.y})`);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
// Drag functions
|
|
160
|
-
function dragstarted(event, d) {
|
|
161
|
-
if (!event.active) simulation.alphaTarget(0.3).restart();
|
|
162
|
-
d.fx = d.x;
|
|
163
|
-
d.fy = d.y;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function dragged(event, d) {
|
|
167
|
-
d.fx = event.x;
|
|
168
|
-
d.fy = event.y;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
function dragended(event, d) {
|
|
172
|
-
if (!event.active) simulation.alphaTarget(0);
|
|
173
|
-
d.fx = null;
|
|
174
|
-
d.fy = null;
|
|
175
|
-
}
|
|
176
|
-
</script>
|
|
177
|
-
</body>
|
|
178
|
-
|
|
179
|
-
</html>
|
flock/app/modules/__init__.py
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
from .agent_detail import AgentDetailView
|
|
2
|
-
from .agent_list import AgentContent, agent_data
|
|
3
|
-
from .playground import Playground
|
|
4
|
-
from .settings import Settings
|
|
5
|
-
|
|
6
|
-
__all__ = [
|
|
7
|
-
"AgentContent",
|
|
8
|
-
"AgentDetailView",
|
|
9
|
-
"Playground",
|
|
10
|
-
"Settings",
|
|
11
|
-
"agent_data",
|
|
12
|
-
]
|
flock/app/modules/about.py
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
from fasthtml.common import *
|
|
2
|
-
from fasthtml.svg import *
|
|
3
|
-
from monsterui.all import *
|
|
4
|
-
|
|
5
|
-
from flock.app.components import CoreArchitectureChart
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def AboutPage():
|
|
9
|
-
return Div(cls="flex flex-col", uk_filter="target: .js-filter")(
|
|
10
|
-
Div(cls="flex px-4 py-2 ")(
|
|
11
|
-
H3("About & Help"),
|
|
12
|
-
),
|
|
13
|
-
Div(
|
|
14
|
-
Div(cls="p-4")(CoreArchitectureChart()),
|
|
15
|
-
cls="w-[1200px]",
|
|
16
|
-
),
|
|
17
|
-
)
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
from fasthtml.common import *
|
|
2
|
-
from fasthtml.svg import *
|
|
3
|
-
from monsterui.all import *
|
|
4
|
-
|
|
5
|
-
from flock.app.components import HistoryGrid
|
|
6
|
-
from flock.app.components.util import IconNav, IconNavItem, format_date
|
|
7
|
-
|
|
8
|
-
##############################
|
|
9
|
-
# Agents
|
|
10
|
-
##############################
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def AgentDetailView(agent):
|
|
14
|
-
action_icons = [("copy", "Duplicate"), ("pencil", "Edit"), ("cloud-upload", "Deploy")]
|
|
15
|
-
status_items = ["Toggle Production", "Arcflock", "Add Label", "Monitor Usage"]
|
|
16
|
-
|
|
17
|
-
return Div(cls="flex flex-col")(
|
|
18
|
-
Div(cls="flex h-14 flex-none items-center border-b border-border p-2")(
|
|
19
|
-
DivFullySpaced(
|
|
20
|
-
DivLAligned(
|
|
21
|
-
IconNav(*IconNavItem(*action_icons)),
|
|
22
|
-
IconNav(Li(A(UkIcon("activity"), uk_tooltip="Metrics")), cls="pl-2"),
|
|
23
|
-
cls="gap-x-2 divide-x divide-border",
|
|
24
|
-
),
|
|
25
|
-
IconNav(
|
|
26
|
-
*IconNavItem(("trash", "Delete"), ("code", "View JSON")),
|
|
27
|
-
Li(A(UkIcon("ellipsis-vertical", button=True))),
|
|
28
|
-
DropDownNavContainer(*map(lambda x: Li(A(x)), status_items)),
|
|
29
|
-
),
|
|
30
|
-
)
|
|
31
|
-
),
|
|
32
|
-
Div(cls="flex-1")(
|
|
33
|
-
DivLAligned(
|
|
34
|
-
DivLAligned(
|
|
35
|
-
Span(UkIcon(agent["icon"]), cls="flex h-10 w-10 items-center justify-center rounded-full bg-muted"),
|
|
36
|
-
Div(cls="grid gap-1")(
|
|
37
|
-
Div(agent["title"], cls=TextT.bold),
|
|
38
|
-
Div(agent["name"], cls="text-xs"),
|
|
39
|
-
# DivLAligned("Type:", agent["type"], cls=TextT.sm),
|
|
40
|
-
),
|
|
41
|
-
cls="gap-4 text-sm",
|
|
42
|
-
),
|
|
43
|
-
Div(format_date(agent["created_at"]), cls=TextFont.muted_sm),
|
|
44
|
-
cls="p-4",
|
|
45
|
-
),
|
|
46
|
-
Div(cls="flex-1 space-y-4 border-t border-border p-4 text-sm")(
|
|
47
|
-
P(agent["description"]),
|
|
48
|
-
Dl(cls="grid grid-cols-2 gap-4")(
|
|
49
|
-
DivLAligned(
|
|
50
|
-
Dt("Production Ready", cls=TextT.muted), Dd("✅" if agent["production_ready"] else "❌")
|
|
51
|
-
),
|
|
52
|
-
DivLAligned(Dt("Last Updated", cls=TextT.muted), Dd(format_date(agent["last_updated"]))),
|
|
53
|
-
DivLAligned(Dt("Input Schema", cls=TextT.muted), Dd(agent["input"], cls="font-mono text-xs")),
|
|
54
|
-
DivLAligned(Dt("Output Schema", cls=TextT.muted), Dd(agent["output"], cls="font-mono text-xs")),
|
|
55
|
-
),
|
|
56
|
-
),
|
|
57
|
-
),
|
|
58
|
-
Div(cls="flex-none space-y-4 border-t border-border p-4")(
|
|
59
|
-
DivFullySpaced(
|
|
60
|
-
HistoryGrid(reduced=True),
|
|
61
|
-
),
|
|
62
|
-
),
|
|
63
|
-
Div(cls="flex-none space-y-4 border-t border-border p-4")(
|
|
64
|
-
DivFullySpaced(
|
|
65
|
-
LabelSwitch("Monitoring Enabled", id="monitoring"),
|
|
66
|
-
Button("Export Configuration", cls=ButtonT.secondary),
|
|
67
|
-
Button("Run Agent", cls=ButtonT.primary),
|
|
68
|
-
),
|
|
69
|
-
),
|
|
70
|
-
)
|
flock/app/modules/agent_list.py
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import pathlib
|
|
3
|
-
|
|
4
|
-
from fasthtml.common import *
|
|
5
|
-
from fasthtml.svg import *
|
|
6
|
-
from monsterui.all import *
|
|
7
|
-
|
|
8
|
-
from flock.app.components.util import format_date
|
|
9
|
-
|
|
10
|
-
agent_data = json.load(open(pathlib.Path("data/mock.json")))
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def AgentItem(agent):
|
|
14
|
-
cls_base = "space-y-4 relative rounded-lg border border-border p-3 text-sm hover:bg-primary"
|
|
15
|
-
cls = f"{cls_base} {'bg-muted' if agent == agent_data[0] else ''} {'tag-unread' if not agent['production_ready'] else 'tag-mail'}"
|
|
16
|
-
|
|
17
|
-
return Li(cls=cls)(
|
|
18
|
-
DivFullySpaced(
|
|
19
|
-
DivLAligned(
|
|
20
|
-
Span(UkIcon(agent["icon"]), cls="flex h-10 w-10 items-center justify-center"),
|
|
21
|
-
Div(agent["title"], cls="font-semibold"),
|
|
22
|
-
Span(cls="flex h-2 w-2 rounded-full bg-green-600") if agent["production_ready"] else "",
|
|
23
|
-
),
|
|
24
|
-
Div(format_date(agent["created_at"]), cls="text-xs"),
|
|
25
|
-
cls="mb-4",
|
|
26
|
-
),
|
|
27
|
-
A(agent["name"], cls=TextFont.bold_sm, href=f"#agent-{agent['id']}"),
|
|
28
|
-
Div(agent["description"][:100] + "...", cls=TextFont.muted_sm),
|
|
29
|
-
DivLAligned(*[
|
|
30
|
-
A(label, cls=f"uk-label relative z-10 {'uk-label-primary' if label == 'analysis' else ''}", href="#")
|
|
31
|
-
for label in agent["labels"]
|
|
32
|
-
]),
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def AgentList(agents):
|
|
37
|
-
return Ul(cls="js-filter space-y-4 p-4 pt-0")(*[AgentItem(agent) for agent in agents])
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def AgentContent():
|
|
41
|
-
return Div(cls="flex flex-col", uk_filter="target: .js-filter")(
|
|
42
|
-
Div(cls="flex px-4 py-2 ")(
|
|
43
|
-
H3("Agents"),
|
|
44
|
-
TabContainer(
|
|
45
|
-
Li(A("All Agents", href="#", role="button"), cls="uk-active", uk_filter_control="filter: .tag-mail"),
|
|
46
|
-
Li(A("Production Ready", href="#", role="button"), uk_filter_control="filter: .tag-unread"),
|
|
47
|
-
alt=True,
|
|
48
|
-
cls="ml-auto max-w-80",
|
|
49
|
-
),
|
|
50
|
-
),
|
|
51
|
-
Div(cls="flex flex-1 flex-col")(
|
|
52
|
-
Div(cls="p-4")(
|
|
53
|
-
Div(cls="uk-inline w-full")(
|
|
54
|
-
Span(cls="uk-form-icon text-muted-foreground")(UkIcon("search")), Input(placeholder="Search")
|
|
55
|
-
)
|
|
56
|
-
),
|
|
57
|
-
Div(cls="flex-1 overflow-y-auto max-h-[800px]")(AgentList(agent_data)),
|
|
58
|
-
),
|
|
59
|
-
)
|
flock/app/modules/playground.py
DELETED
|
@@ -1,322 +0,0 @@
|
|
|
1
|
-
from fasthtml.common import *
|
|
2
|
-
from fasthtml.svg import *
|
|
3
|
-
from monsterui.all import *
|
|
4
|
-
|
|
5
|
-
CODE = """
|
|
6
|
-
var pixelSize = 16
|
|
7
|
-
import 'https://cdn.interactjs.io/v1.9.20/auto-start/index.js'
|
|
8
|
-
import 'https://cdn.interactjs.io/v1.9.20/actions/drag/index.js'
|
|
9
|
-
import 'https://cdn.interactjs.io/v1.9.20/actions/resize/index.js'
|
|
10
|
-
import 'https://cdn.interactjs.io/v1.9.20/modifiers/index.js'
|
|
11
|
-
import 'https://cdn.interactjs.io/v1.9.20/dev-tools/index.js'
|
|
12
|
-
import interact from 'https://cdn.interactjs.io/v1.9.20/interactjs/index.js'
|
|
13
|
-
|
|
14
|
-
interact('.rainbow-pixel-canvas')
|
|
15
|
-
.draggable({
|
|
16
|
-
max: Infinity,
|
|
17
|
-
maxPerElement: Infinity,
|
|
18
|
-
origin: 'self',
|
|
19
|
-
modifiers: [
|
|
20
|
-
interact.modifiers.snap({
|
|
21
|
-
// snap to the corners of a grid
|
|
22
|
-
targets: [
|
|
23
|
-
interact.snappers.grid({ x: pixelSize, y: pixelSize })
|
|
24
|
-
]
|
|
25
|
-
})
|
|
26
|
-
],
|
|
27
|
-
listeners: {
|
|
28
|
-
// draw colored squares on move
|
|
29
|
-
move: function (event) {
|
|
30
|
-
var context = event.target.getContext('2d')
|
|
31
|
-
// calculate the angle of the drag direction
|
|
32
|
-
var dragAngle = 180 * Math.atan2(event.dx, event.dy) / Math.PI
|
|
33
|
-
|
|
34
|
-
// set color based on drag angle and speed
|
|
35
|
-
context.fillStyle =
|
|
36
|
-
'hsl(' +
|
|
37
|
-
dragAngle +
|
|
38
|
-
', 86%, ' +
|
|
39
|
-
(30 + Math.min(event.speed / 1000, 1) * 50) +
|
|
40
|
-
'%)'
|
|
41
|
-
|
|
42
|
-
// draw squares
|
|
43
|
-
context.fillRect(
|
|
44
|
-
event.pageX - pixelSize / 2,
|
|
45
|
-
event.pageY - pixelSize / 2,
|
|
46
|
-
pixelSize,
|
|
47
|
-
pixelSize
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
})
|
|
52
|
-
// clear the canvas on doubletap
|
|
53
|
-
.on('doubletap', function (event) {
|
|
54
|
-
var context = event.target.getContext('2d')
|
|
55
|
-
|
|
56
|
-
context.clearRect(0, 0, context.canvas.width, context.canvas.height)
|
|
57
|
-
resizeCanvases()
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
function resizeCanvases () {
|
|
61
|
-
[].forEach.call(document.querySelectorAll('.rainbow-pixel-canvas'), function (
|
|
62
|
-
canvas
|
|
63
|
-
) {
|
|
64
|
-
delete canvas.width
|
|
65
|
-
delete canvas.height
|
|
66
|
-
|
|
67
|
-
var rect = canvas.getBoundingClientRect()
|
|
68
|
-
|
|
69
|
-
canvas.width = rect.width
|
|
70
|
-
canvas.height = rect.height
|
|
71
|
-
})
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
resizeCanvases()
|
|
75
|
-
|
|
76
|
-
// interact.js can also add DOM event listeners
|
|
77
|
-
interact(window).on('resize', resizeCanvases)
|
|
78
|
-
"""
|
|
79
|
-
|
|
80
|
-
CODE2 = """
|
|
81
|
-
import 'https://cdn.interactjs.io/v1.9.20/auto-start/index.js'
|
|
82
|
-
import 'https://cdn.interactjs.io/v1.9.20/actions/drag/index.js'
|
|
83
|
-
import 'https://cdn.interactjs.io/v1.9.20/actions/resize/index.js'
|
|
84
|
-
import 'https://cdn.interactjs.io/v1.9.20/modifiers/index.js'
|
|
85
|
-
import 'https://cdn.interactjs.io/v1.9.20/dev-tools/index.js'
|
|
86
|
-
import interact from 'https://cdn.interactjs.io/v1.9.20/interactjs/index.js'
|
|
87
|
-
const svg = document.getElementById('connections');
|
|
88
|
-
|
|
89
|
-
// Function to draw an SVG line between two points
|
|
90
|
-
function createConnectionLine(x1, y1, x2, y2) {
|
|
91
|
-
const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
|
|
92
|
-
line.setAttribute("x1", x1);
|
|
93
|
-
line.setAttribute("y1", y1);
|
|
94
|
-
line.setAttribute("x2", x2);
|
|
95
|
-
line.setAttribute("y2", y2);
|
|
96
|
-
line.setAttribute("stroke", "red");
|
|
97
|
-
line.setAttribute("stroke-width", "1");
|
|
98
|
-
return line;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Function to update connection lines
|
|
102
|
-
function updateConnections() {
|
|
103
|
-
// Clear existing connections
|
|
104
|
-
svg.innerHTML = '';
|
|
105
|
-
|
|
106
|
-
// Get the positions of the nodes
|
|
107
|
-
const node1 = document.getElementById('node1');
|
|
108
|
-
const node2 = document.getElementById('node2');
|
|
109
|
-
const rect1 = node1.getBoundingClientRect();
|
|
110
|
-
const rect2 = node2.getBoundingClientRect();
|
|
111
|
-
|
|
112
|
-
// Calculate the centers of the nodes
|
|
113
|
-
const x1 = rect1.left + rect1.width / 2;
|
|
114
|
-
const y1 = rect1.top + rect1.height / 2;
|
|
115
|
-
const x2 = rect2.left + rect2.width / 2;
|
|
116
|
-
const y2 = rect2.top + rect2.height / 2;
|
|
117
|
-
|
|
118
|
-
// Create and append a connection line
|
|
119
|
-
const line = createConnectionLine(x1, y1, x2, y2);
|
|
120
|
-
svg.appendChild(line);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Initialize Interact.js
|
|
124
|
-
interact('.node').draggable({
|
|
125
|
-
listeners: {
|
|
126
|
-
move(event) {
|
|
127
|
-
// Move the dragged node
|
|
128
|
-
const target = event.target;
|
|
129
|
-
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
|
|
130
|
-
const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
|
|
131
|
-
|
|
132
|
-
target.style.transform = `translate(${x}px, ${y}px)`;
|
|
133
|
-
target.setAttribute('data-x', x);
|
|
134
|
-
target.setAttribute('data-y', y);
|
|
135
|
-
|
|
136
|
-
// Update the connections
|
|
137
|
-
updateConnections();
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
// Draw initial connections
|
|
143
|
-
updateConnections();
|
|
144
|
-
"""
|
|
145
|
-
|
|
146
|
-
CODE3 = """
|
|
147
|
-
// Initial data
|
|
148
|
-
let data = {
|
|
149
|
-
nodes: [
|
|
150
|
-
{id: 1, name: "Node 1"},
|
|
151
|
-
{id: 2, name: "Node 2"},
|
|
152
|
-
{id: 3, name: "Node 3"}
|
|
153
|
-
],
|
|
154
|
-
links: [
|
|
155
|
-
{source: 0, target: 1},
|
|
156
|
-
{source: 1, target: 2}
|
|
157
|
-
]
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
// Create SVG container
|
|
161
|
-
const svg = d3.select("svg");
|
|
162
|
-
const width = +svg.attr("width");
|
|
163
|
-
const height = +svg.attr("height");
|
|
164
|
-
|
|
165
|
-
// Create force simulation
|
|
166
|
-
const simulation = d3.forceSimulation(data.nodes)
|
|
167
|
-
.force("link", d3.forceLink(data.links).id(d => d.id))
|
|
168
|
-
.force("charge", d3.forceManyBody().strength(-300))
|
|
169
|
-
.force("center", d3.forceCenter(width / 2, height / 2));
|
|
170
|
-
|
|
171
|
-
// Create the links
|
|
172
|
-
const link = svg.append("g")
|
|
173
|
-
.selectAll("line")
|
|
174
|
-
.data(data.links)
|
|
175
|
-
.join("line")
|
|
176
|
-
.attr("class", "link");
|
|
177
|
-
|
|
178
|
-
// Create the nodes
|
|
179
|
-
const node = svg.append("g")
|
|
180
|
-
.selectAll("g")
|
|
181
|
-
.data(data.nodes)
|
|
182
|
-
.join("g")
|
|
183
|
-
.attr("class", "node");
|
|
184
|
-
|
|
185
|
-
// Add circles to nodes
|
|
186
|
-
node.append("circle")
|
|
187
|
-
.attr("r", 10)
|
|
188
|
-
.style("fill", (d, i) => d3.schemeCategory10[i % 10]);
|
|
189
|
-
|
|
190
|
-
// Add labels to nodes
|
|
191
|
-
node.append("text")
|
|
192
|
-
.attr("dx", 12)
|
|
193
|
-
.attr("dy", ".35em")
|
|
194
|
-
.text(d => d.name);
|
|
195
|
-
|
|
196
|
-
// Add drag behavior
|
|
197
|
-
node.call(d3.drag()
|
|
198
|
-
.on("start", dragstarted)
|
|
199
|
-
.on("drag", dragged)
|
|
200
|
-
.on("end", dragended));
|
|
201
|
-
|
|
202
|
-
// Double click on background to add node
|
|
203
|
-
svg.on("dblclick", function(event) {
|
|
204
|
-
const coords = d3.pointer(event);
|
|
205
|
-
const newNode = {
|
|
206
|
-
id: data.nodes.length + 1,
|
|
207
|
-
name: `Node ${data.nodes.length + 1}`,
|
|
208
|
-
x: coords[0],
|
|
209
|
-
y: coords[1]
|
|
210
|
-
};
|
|
211
|
-
data.nodes.push(newNode);
|
|
212
|
-
|
|
213
|
-
// Add link to nearest node
|
|
214
|
-
if (data.nodes.length > 1) {
|
|
215
|
-
const lastNode = data.nodes[data.nodes.length - 2];
|
|
216
|
-
data.links.push({
|
|
217
|
-
source: lastNode,
|
|
218
|
-
target: newNode
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
updateGraph();
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
// Update function to refresh the graph
|
|
226
|
-
function updateGraph() {
|
|
227
|
-
// Update links
|
|
228
|
-
const link = svg.selectAll(".link")
|
|
229
|
-
.data(data.links)
|
|
230
|
-
.join("line")
|
|
231
|
-
.attr("class", "link");
|
|
232
|
-
|
|
233
|
-
// Update nodes
|
|
234
|
-
const node = svg.selectAll(".node")
|
|
235
|
-
.data(data.nodes)
|
|
236
|
-
.join(
|
|
237
|
-
enter => {
|
|
238
|
-
const nodeEnter = enter.append("g")
|
|
239
|
-
.attr("class", "node")
|
|
240
|
-
.call(d3.drag()
|
|
241
|
-
.on("start", dragstarted)
|
|
242
|
-
.on("drag", dragged)
|
|
243
|
-
.on("end", dragended));
|
|
244
|
-
|
|
245
|
-
nodeEnter.append("circle")
|
|
246
|
-
.attr("r", 10)
|
|
247
|
-
.style("fill", (d, i) => d3.schemeCategory10[i % 10]);
|
|
248
|
-
|
|
249
|
-
nodeEnter.append("text")
|
|
250
|
-
.attr("dx", 12)
|
|
251
|
-
.attr("dy", ".35em")
|
|
252
|
-
.text(d => d.name);
|
|
253
|
-
|
|
254
|
-
return nodeEnter;
|
|
255
|
-
}
|
|
256
|
-
);
|
|
257
|
-
|
|
258
|
-
// Update simulation
|
|
259
|
-
simulation.nodes(data.nodes);
|
|
260
|
-
simulation.force("link").links(data.links);
|
|
261
|
-
simulation.alpha(1).restart();
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Simulation tick function
|
|
265
|
-
simulation.on("tick", () => {
|
|
266
|
-
link
|
|
267
|
-
.attr("x1", d => d.source.x)
|
|
268
|
-
.attr("y1", d => d.source.y)
|
|
269
|
-
.attr("x2", d => d.target.x)
|
|
270
|
-
.attr("y2", d => d.target.y);
|
|
271
|
-
|
|
272
|
-
node
|
|
273
|
-
.attr("transform", d => `translate(${d.x},${d.y})`);
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
// Drag functions
|
|
277
|
-
function dragstarted(event, d) {
|
|
278
|
-
if (!event.active) simulation.alphaTarget(0.3).restart();
|
|
279
|
-
d.fx = d.x;
|
|
280
|
-
d.fy = d.y;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
function dragged(event, d) {
|
|
284
|
-
d.fx = event.x;
|
|
285
|
-
d.fy = event.y;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
function dragended(event, d) {
|
|
289
|
-
if (!event.active) simulation.alphaTarget(0);
|
|
290
|
-
d.fx = null;
|
|
291
|
-
d.fy = null;
|
|
292
|
-
}
|
|
293
|
-
"""
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
def get_playground():
|
|
297
|
-
return Container(
|
|
298
|
-
Canvas(cls="rainbow-pixel-canvas w-full h-full"),
|
|
299
|
-
P("Drag to draw. Double tap to clear."),
|
|
300
|
-
Script(code=CODE, type="module"),
|
|
301
|
-
cls="w-full h-full",
|
|
302
|
-
)
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
def get_playground2():
|
|
306
|
-
return Container(
|
|
307
|
-
Svg(
|
|
308
|
-
width="800",
|
|
309
|
-
height="600",
|
|
310
|
-
),
|
|
311
|
-
Script(code=CODE3),
|
|
312
|
-
)
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
def Playground():
|
|
316
|
-
return Div(cls="flex flex-col w-full")(
|
|
317
|
-
Div(cls="px-4 py-2 ")(
|
|
318
|
-
H3("interact.js demo"),
|
|
319
|
-
P("Rainbows!", cls=TextFont.muted_sm),
|
|
320
|
-
),
|
|
321
|
-
get_playground2(),
|
|
322
|
-
)
|