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,442 @@
|
|
|
1
|
+
"""A Rich-based formatter for agent results with theme support."""
|
|
2
|
+
|
|
3
|
+
import pathlib
|
|
4
|
+
import random
|
|
5
|
+
import re
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from devtools import pprint
|
|
9
|
+
from temporalio import workflow
|
|
10
|
+
|
|
11
|
+
from flock.core.logging.formatters.base_formatter import BaseFormatter
|
|
12
|
+
|
|
13
|
+
with workflow.unsafe.imports_passed_through():
|
|
14
|
+
from rich import box
|
|
15
|
+
from rich.console import Console, Group
|
|
16
|
+
from rich.panel import Panel
|
|
17
|
+
from rich.table import Table
|
|
18
|
+
|
|
19
|
+
import toml # install with: pip install toml
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def resolve_style_string(style_str: str, theme: dict) -> str:
|
|
23
|
+
"""Replace tokens in a style string of the form.
|
|
24
|
+
|
|
25
|
+
color.<section>.<key>
|
|
26
|
+
|
|
27
|
+
with the corresponding value from theme["colors"][<section>][<key>].
|
|
28
|
+
If the token cannot be resolved, it is left unchanged.
|
|
29
|
+
"""
|
|
30
|
+
pattern = r"color\.(\w+)\.(\w+)"
|
|
31
|
+
|
|
32
|
+
def repl(match):
|
|
33
|
+
section = match.group(1)
|
|
34
|
+
key = match.group(2)
|
|
35
|
+
try:
|
|
36
|
+
return theme["colors"][section][key]
|
|
37
|
+
except KeyError:
|
|
38
|
+
return match.group(0) # leave token unchanged if not found
|
|
39
|
+
|
|
40
|
+
return re.sub(pattern, repl, style_str)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def generate_default_rich_block(theme: dict | None = None) -> dict[str, Any]:
|
|
44
|
+
"""Generate a default [rich] block with *all* styling properties.
|
|
45
|
+
|
|
46
|
+
For the color mapping properties the defaults are computed from the
|
|
47
|
+
theme's [colors] blocks (if available). This includes colors from the
|
|
48
|
+
"bright", "normal", and "cursor" sections.
|
|
49
|
+
|
|
50
|
+
Non color properties (layout and table specific properties) are randomly
|
|
51
|
+
chosen from a set of sensible alternatives.
|
|
52
|
+
"""
|
|
53
|
+
if theme is not None:
|
|
54
|
+
# Retrieve colors from the theme.
|
|
55
|
+
bright_black = theme["colors"]["bright"].get("black", "#000000")
|
|
56
|
+
bright_blue = theme["colors"]["bright"].get("blue", "#96cbfe")
|
|
57
|
+
bright_cyan = theme["colors"]["bright"].get("cyan", "#85befd")
|
|
58
|
+
bright_green = theme["colors"]["bright"].get("green", "#94fa36")
|
|
59
|
+
bright_magenta = theme["colors"]["bright"].get("magenta", "#b9b6fc")
|
|
60
|
+
bright_red = theme["colors"]["bright"].get("red", "#fd5ff1")
|
|
61
|
+
bright_white = theme["colors"]["bright"].get("white", "#e0e0e0")
|
|
62
|
+
bright_yellow = theme["colors"]["bright"].get("yellow", "#f5ffa8")
|
|
63
|
+
|
|
64
|
+
normal_black = theme["colors"]["normal"].get("black", "#000000")
|
|
65
|
+
normal_blue = theme["colors"]["normal"].get("blue", "#85befd")
|
|
66
|
+
normal_cyan = theme["colors"]["normal"].get("cyan", "#85befd")
|
|
67
|
+
normal_green = theme["colors"]["normal"].get("green", "#87c38a")
|
|
68
|
+
normal_magenta = theme["colors"]["normal"].get("magenta", "#b9b6fc")
|
|
69
|
+
normal_red = theme["colors"]["normal"].get("red", "#fd5ff1")
|
|
70
|
+
normal_white = theme["colors"]["normal"].get("white", "#e0e0e0")
|
|
71
|
+
normal_yellow = theme["colors"]["normal"].get("yellow", "#ffd7b1")
|
|
72
|
+
|
|
73
|
+
cursor_cursor = theme["colors"]["cursor"].get("cursor", "#d0d0d0")
|
|
74
|
+
cursor_text = theme["colors"]["cursor"].get("text", "#151515")
|
|
75
|
+
|
|
76
|
+
primary_background = theme["colors"]["primary"].get(
|
|
77
|
+
"background", "#161719"
|
|
78
|
+
)
|
|
79
|
+
primary_foreground = theme["colors"]["primary"].get(
|
|
80
|
+
"foreground", "#c5c8c6"
|
|
81
|
+
)
|
|
82
|
+
selection_background = theme["colors"]["selection"].get(
|
|
83
|
+
"background", "#444444"
|
|
84
|
+
)
|
|
85
|
+
selection_text = theme["colors"]["selection"].get(
|
|
86
|
+
"text", primary_foreground
|
|
87
|
+
)
|
|
88
|
+
else:
|
|
89
|
+
bright_black = "black"
|
|
90
|
+
bright_blue = "blue"
|
|
91
|
+
bright_cyan = "cyan"
|
|
92
|
+
bright_green = "green"
|
|
93
|
+
bright_magenta = "magenta"
|
|
94
|
+
bright_red = "red"
|
|
95
|
+
bright_white = "white"
|
|
96
|
+
bright_yellow = "yellow"
|
|
97
|
+
|
|
98
|
+
normal_black = "black"
|
|
99
|
+
normal_blue = "blue"
|
|
100
|
+
normal_cyan = "cyan"
|
|
101
|
+
normal_green = "green"
|
|
102
|
+
normal_magenta = "magenta"
|
|
103
|
+
normal_red = "red"
|
|
104
|
+
normal_white = "white"
|
|
105
|
+
normal_yellow = "yellow"
|
|
106
|
+
|
|
107
|
+
cursor_cursor = "gray"
|
|
108
|
+
cursor_text = "white"
|
|
109
|
+
|
|
110
|
+
primary_background = "black"
|
|
111
|
+
primary_foreground = "white"
|
|
112
|
+
selection_background = "gray"
|
|
113
|
+
selection_text = "white"
|
|
114
|
+
|
|
115
|
+
# Color properties computed from the theme.
|
|
116
|
+
default_color_props = {
|
|
117
|
+
"panel_style": f"on {primary_background}",
|
|
118
|
+
"table_header_style": f"bold {selection_text} on {selection_background}",
|
|
119
|
+
"table_title_style": f"bold {primary_foreground}",
|
|
120
|
+
"table_border_style": bright_blue,
|
|
121
|
+
"panel_border_style": bright_blue,
|
|
122
|
+
"column_output": f"bold {primary_foreground}",
|
|
123
|
+
"column_value": primary_foreground,
|
|
124
|
+
}
|
|
125
|
+
# Extra color tokens so they can be used via tokens like color.bright.black, etc.
|
|
126
|
+
extra_color_props = {
|
|
127
|
+
"bright_black": bright_black,
|
|
128
|
+
"bright_blue": bright_blue,
|
|
129
|
+
"bright_cyan": bright_cyan,
|
|
130
|
+
"bright_green": bright_green,
|
|
131
|
+
"bright_magenta": bright_magenta,
|
|
132
|
+
"bright_red": bright_red,
|
|
133
|
+
"bright_white": bright_white,
|
|
134
|
+
"bright_yellow": bright_yellow,
|
|
135
|
+
"normal_black": normal_black,
|
|
136
|
+
"normal_blue": normal_blue,
|
|
137
|
+
"normal_cyan": normal_cyan,
|
|
138
|
+
"normal_green": normal_green,
|
|
139
|
+
"normal_magenta": normal_magenta,
|
|
140
|
+
"normal_red": normal_red,
|
|
141
|
+
"normal_white": normal_white,
|
|
142
|
+
"normal_yellow": normal_yellow,
|
|
143
|
+
"cursor_cursor": cursor_cursor,
|
|
144
|
+
"cursor_text": cursor_text,
|
|
145
|
+
}
|
|
146
|
+
# Randomly choose non color properties.
|
|
147
|
+
default_non_color_props = {
|
|
148
|
+
"table_show_lines": random.choice([True, False]),
|
|
149
|
+
"table_box": random.choice(
|
|
150
|
+
["ROUNDED", "SIMPLE", "SQUARE", "MINIMAL", "HEAVY", "DOUBLE_EDGE"]
|
|
151
|
+
),
|
|
152
|
+
"panel_padding": random.choice([[1, 2], [1, 1], [2, 2], [0, 2]]),
|
|
153
|
+
"panel_title_align": random.choice(["left", "center", "right"]),
|
|
154
|
+
# Add table_row_styles property.
|
|
155
|
+
"table_row_styles": random.choice(
|
|
156
|
+
[["", "dim"], ["", "italic"], ["", "underline"]]
|
|
157
|
+
),
|
|
158
|
+
}
|
|
159
|
+
# Extra table layout properties (non content properties).
|
|
160
|
+
default_extra_table_props = {
|
|
161
|
+
"table_safe_box": True,
|
|
162
|
+
"table_padding": [0, 1],
|
|
163
|
+
"table_collapse_padding": False,
|
|
164
|
+
"table_pad_edge": True,
|
|
165
|
+
"table_expand": False,
|
|
166
|
+
"table_show_footer": False,
|
|
167
|
+
"table_show_edge": True,
|
|
168
|
+
"table_leading": 0,
|
|
169
|
+
"table_style": "none",
|
|
170
|
+
"table_footer_style": "none",
|
|
171
|
+
"table_caption": None,
|
|
172
|
+
"table_caption_style": "none",
|
|
173
|
+
"table_title_justify": "center",
|
|
174
|
+
"table_caption_justify": "center",
|
|
175
|
+
"table_highlight": False,
|
|
176
|
+
}
|
|
177
|
+
# Combine all defaults.
|
|
178
|
+
defaults = {
|
|
179
|
+
**default_color_props,
|
|
180
|
+
**extra_color_props,
|
|
181
|
+
**default_non_color_props,
|
|
182
|
+
**default_extra_table_props,
|
|
183
|
+
}
|
|
184
|
+
return defaults
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def load_theme_from_file(filepath: str) -> dict:
|
|
188
|
+
"""Load a theme from a TOML file.
|
|
189
|
+
|
|
190
|
+
The theme is expected to contain color blocks like [colors.primary],
|
|
191
|
+
[colors.selection], [colors.normal], [colors.cursor], etc.
|
|
192
|
+
If the file does not contain a [rich] block for styling properties,
|
|
193
|
+
one is generated (with all properties including color mappings) and
|
|
194
|
+
written back into the file.
|
|
195
|
+
"""
|
|
196
|
+
with open(filepath) as f:
|
|
197
|
+
theme = toml.load(f)
|
|
198
|
+
|
|
199
|
+
if "rich" not in theme:
|
|
200
|
+
theme["rich"] = generate_default_rich_block(theme)
|
|
201
|
+
# Write the updated theme back into the file.
|
|
202
|
+
with open(filepath, "w") as f:
|
|
203
|
+
toml.dump(theme, f)
|
|
204
|
+
|
|
205
|
+
return theme
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def get_default_styles(theme: dict | None) -> dict[str, Any]:
|
|
209
|
+
"""Build a style mapping from the theme.
|
|
210
|
+
|
|
211
|
+
It first computes defaults from the [colors] block (via generate_default_rich_block)
|
|
212
|
+
and then overrides any property found in the [rich] block.
|
|
213
|
+
Finally, for every property that is a string, tokens of the form
|
|
214
|
+
"color.<section>.<key>" are resolved.
|
|
215
|
+
"""
|
|
216
|
+
if theme is None:
|
|
217
|
+
final_styles = generate_default_rich_block(None)
|
|
218
|
+
else:
|
|
219
|
+
defaults = generate_default_rich_block(theme)
|
|
220
|
+
rich_props = theme.get("rich", {})
|
|
221
|
+
final_styles = {
|
|
222
|
+
key: rich_props.get(key, defaults[key]) for key in defaults
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
# Ensure that panel_padding and table_padding are tuples.
|
|
226
|
+
final_styles["panel_padding"] = tuple(final_styles["panel_padding"])
|
|
227
|
+
if "table_padding" in final_styles:
|
|
228
|
+
final_styles["table_padding"] = tuple(final_styles["table_padding"])
|
|
229
|
+
|
|
230
|
+
# Resolve tokens in every string value.
|
|
231
|
+
if theme is not None:
|
|
232
|
+
for key, value in final_styles.items():
|
|
233
|
+
if isinstance(value, str):
|
|
234
|
+
final_styles[key] = resolve_style_string(value, theme)
|
|
235
|
+
|
|
236
|
+
return final_styles
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def create_rich_renderable(
|
|
240
|
+
value: Any,
|
|
241
|
+
level: int = 0,
|
|
242
|
+
theme: dict | None = None,
|
|
243
|
+
styles: dict[str, Any] | None = None,
|
|
244
|
+
max_length: int = -1,
|
|
245
|
+
) -> Any:
|
|
246
|
+
"""Recursively creates a Rich renderable for a given value.
|
|
247
|
+
|
|
248
|
+
- For dicts: creates a Table with headers styled via the computed properties.
|
|
249
|
+
- For lists/tuples: if every item is a dict, returns a Group of subtables;
|
|
250
|
+
otherwise, renders each item recursively.
|
|
251
|
+
- Other types: returns a string (adding extra newlines for multi-line strings).
|
|
252
|
+
"""
|
|
253
|
+
if styles is None:
|
|
254
|
+
styles = get_default_styles(theme)
|
|
255
|
+
|
|
256
|
+
# If the value is a dictionary, render it as a table.
|
|
257
|
+
if isinstance(value, dict):
|
|
258
|
+
# Convert table_box string into an actual box style.
|
|
259
|
+
box_style = (
|
|
260
|
+
getattr(box, styles["table_box"])
|
|
261
|
+
if isinstance(styles["table_box"], str)
|
|
262
|
+
else styles["table_box"]
|
|
263
|
+
)
|
|
264
|
+
# Gather all table-related keyword arguments.
|
|
265
|
+
table_kwargs = {
|
|
266
|
+
"show_header": True,
|
|
267
|
+
"header_style": styles["table_header_style"],
|
|
268
|
+
"title": f"Subtable (Level {level})" if level > 0 else None,
|
|
269
|
+
"title_style": styles["table_title_style"],
|
|
270
|
+
"border_style": styles["table_border_style"],
|
|
271
|
+
"show_lines": styles["table_show_lines"],
|
|
272
|
+
"box": box_style,
|
|
273
|
+
"row_styles": styles["table_row_styles"],
|
|
274
|
+
"safe_box": styles.get("table_safe_box"),
|
|
275
|
+
"padding": styles.get("table_padding"),
|
|
276
|
+
"collapse_padding": styles.get("table_collapse_padding"),
|
|
277
|
+
"pad_edge": styles.get("table_pad_edge"),
|
|
278
|
+
"expand": styles.get("table_expand"),
|
|
279
|
+
"show_footer": styles.get("table_show_footer"),
|
|
280
|
+
"show_edge": styles.get("table_show_edge"),
|
|
281
|
+
"leading": styles.get("table_leading"),
|
|
282
|
+
"style": styles.get("table_style"),
|
|
283
|
+
"footer_style": styles.get("table_footer_style"),
|
|
284
|
+
"caption": styles.get("table_caption"),
|
|
285
|
+
"caption_style": styles.get("table_caption_style"),
|
|
286
|
+
"title_justify": styles.get("table_title_justify"),
|
|
287
|
+
"caption_justify": styles.get("table_caption_justify"),
|
|
288
|
+
"highlight": styles.get("table_highlight"),
|
|
289
|
+
}
|
|
290
|
+
table = Table(**table_kwargs)
|
|
291
|
+
table.add_column("Key", style=styles["column_output"])
|
|
292
|
+
table.add_column("Value", style=styles["column_value"])
|
|
293
|
+
for k, v in value.items():
|
|
294
|
+
table.add_row(
|
|
295
|
+
str(k),
|
|
296
|
+
create_rich_renderable(v, level + 1, theme, styles, max_length),
|
|
297
|
+
)
|
|
298
|
+
return table
|
|
299
|
+
|
|
300
|
+
# If the value is a list or tuple, render each item.
|
|
301
|
+
elif isinstance(value, list | tuple):
|
|
302
|
+
if all(isinstance(item, dict) for item in value):
|
|
303
|
+
sub_tables = []
|
|
304
|
+
for i, item in enumerate(value):
|
|
305
|
+
sub_tables.append(f"[bold]Item {i + 1}[/bold]")
|
|
306
|
+
sub_tables.append(
|
|
307
|
+
create_rich_renderable(
|
|
308
|
+
item, level + 1, theme, styles, max_length=max_length
|
|
309
|
+
)
|
|
310
|
+
)
|
|
311
|
+
return Group(*sub_tables)
|
|
312
|
+
else:
|
|
313
|
+
rendered_items = [
|
|
314
|
+
create_rich_renderable(
|
|
315
|
+
item, level + 1, theme, styles, max_length=max_length
|
|
316
|
+
)
|
|
317
|
+
for item in value
|
|
318
|
+
]
|
|
319
|
+
if all(isinstance(item, str) for item in rendered_items):
|
|
320
|
+
return "\n".join(rendered_items)
|
|
321
|
+
else:
|
|
322
|
+
return Group(*rendered_items)
|
|
323
|
+
|
|
324
|
+
# Otherwise, return a string representation.
|
|
325
|
+
else:
|
|
326
|
+
s = str(value).strip()
|
|
327
|
+
if max_length > 0 and len(s) > max_length:
|
|
328
|
+
omitted = len(s) - max_length
|
|
329
|
+
s = (
|
|
330
|
+
s[:max_length]
|
|
331
|
+
+ f"[bold bright_yellow]...(+{omitted}chars)[/bold bright_yellow]"
|
|
332
|
+
)
|
|
333
|
+
if isinstance(value, str) and "\n" in value:
|
|
334
|
+
return f"\n{s}\n"
|
|
335
|
+
return s
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
class ThemedAgentResultFormatter(BaseFormatter):
|
|
339
|
+
"""Formats agent results in a Rich table with nested subtables and theme support."""
|
|
340
|
+
|
|
341
|
+
def __init__(self, theme: str = "atom", max_length: int = -1):
|
|
342
|
+
"""Initialize the formatter with a theme and optional max length."""
|
|
343
|
+
self.theme = theme
|
|
344
|
+
self.styles = None
|
|
345
|
+
self.max_length = max_length
|
|
346
|
+
|
|
347
|
+
def format_result(
|
|
348
|
+
self, result: dict[str, Any], agent_name: str, theme, styles
|
|
349
|
+
) -> Panel:
|
|
350
|
+
"""Format an agent's result as a Rich Panel containing a table."""
|
|
351
|
+
box_style = (
|
|
352
|
+
getattr(box, styles["table_box"])
|
|
353
|
+
if isinstance(styles["table_box"], str)
|
|
354
|
+
else styles["table_box"]
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
# Gather table properties for the main table.
|
|
358
|
+
table_kwargs = {
|
|
359
|
+
"show_header": True,
|
|
360
|
+
"header_style": styles["table_header_style"],
|
|
361
|
+
"title": f"Agent Results: {agent_name}",
|
|
362
|
+
"title_style": styles["table_title_style"],
|
|
363
|
+
"border_style": styles["table_border_style"],
|
|
364
|
+
"show_lines": styles["table_show_lines"],
|
|
365
|
+
"box": box_style,
|
|
366
|
+
"row_styles": styles["table_row_styles"],
|
|
367
|
+
"safe_box": styles.get("table_safe_box"),
|
|
368
|
+
"padding": styles.get("table_padding"),
|
|
369
|
+
"collapse_padding": styles.get("table_collapse_padding"),
|
|
370
|
+
"pad_edge": styles.get("table_pad_edge"),
|
|
371
|
+
"expand": styles.get("table_expand"),
|
|
372
|
+
"show_footer": styles.get("table_show_footer"),
|
|
373
|
+
"show_edge": styles.get("table_show_edge"),
|
|
374
|
+
"leading": styles.get("table_leading"),
|
|
375
|
+
"style": styles.get("table_style"),
|
|
376
|
+
"footer_style": styles.get("table_footer_style"),
|
|
377
|
+
"caption": styles.get("table_caption"),
|
|
378
|
+
"caption_style": styles.get("table_caption_style"),
|
|
379
|
+
"title_justify": styles.get("table_title_justify"),
|
|
380
|
+
"caption_justify": styles.get("table_caption_justify"),
|
|
381
|
+
"highlight": styles.get("table_highlight"),
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
table = Table(**table_kwargs)
|
|
385
|
+
table.add_column("Output", style=styles["column_output"])
|
|
386
|
+
table.add_column("Value", style=styles["column_value"])
|
|
387
|
+
for key, value in result.items():
|
|
388
|
+
rich_renderable = create_rich_renderable(
|
|
389
|
+
value,
|
|
390
|
+
level=0,
|
|
391
|
+
theme=theme,
|
|
392
|
+
styles=styles,
|
|
393
|
+
max_length=self.max_length,
|
|
394
|
+
)
|
|
395
|
+
table.add_row(key, rich_renderable)
|
|
396
|
+
|
|
397
|
+
return Panel(
|
|
398
|
+
table,
|
|
399
|
+
title="🐤🐧🐓🦆",
|
|
400
|
+
title_align=styles["panel_title_align"],
|
|
401
|
+
border_style=styles["panel_border_style"],
|
|
402
|
+
padding=styles["panel_padding"],
|
|
403
|
+
style=styles["panel_style"],
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
def display_result(self, result: dict[str, Any], agent_name: str) -> None:
|
|
407
|
+
"""Print an agent's result using Rich formatting."""
|
|
408
|
+
theme = self.theme
|
|
409
|
+
themes_dir = (
|
|
410
|
+
pathlib.Path(__file__).parent.parent.parent.parent / "themes"
|
|
411
|
+
)
|
|
412
|
+
all_themes = list(themes_dir.glob("*.toml"))
|
|
413
|
+
theme = theme + ".toml" if not theme.endswith(".toml") else theme
|
|
414
|
+
theme = (
|
|
415
|
+
pathlib.Path(__file__).parent.parent.parent.parent
|
|
416
|
+
/ "themes"
|
|
417
|
+
/ theme
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
if pathlib.Path(theme) not in all_themes:
|
|
421
|
+
raise ValueError(
|
|
422
|
+
f"Invalid theme: {theme}\nAvailable themes: {all_themes}"
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
theme_dict = load_theme_from_file(theme)
|
|
426
|
+
|
|
427
|
+
styles = get_default_styles(theme_dict)
|
|
428
|
+
self.styles = styles
|
|
429
|
+
|
|
430
|
+
console = Console()
|
|
431
|
+
panel = self.format_result(
|
|
432
|
+
result=result,
|
|
433
|
+
agent_name=agent_name,
|
|
434
|
+
theme=theme_dict,
|
|
435
|
+
styles=styles,
|
|
436
|
+
)
|
|
437
|
+
console.print(panel)
|
|
438
|
+
|
|
439
|
+
@staticmethod
|
|
440
|
+
def display_data(data: dict[str, Any]) -> None:
|
|
441
|
+
"""Print agent data using Rich formatting."""
|
|
442
|
+
pprint(data)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# File: src/flock/core/logging.py
|
|
2
|
+
"""A unified logging module for Flock that works both in local/worker contexts
|
|
3
|
+
and inside Temporal workflows.
|
|
4
|
+
|
|
5
|
+
Key points:
|
|
6
|
+
- We always have Temporal imported, so we cannot decide based on import.
|
|
7
|
+
- Instead, we dynamically check if we're in a workflow context by trying
|
|
8
|
+
to call `workflow.info()`.
|
|
9
|
+
- In a workflow, we use Temporal’s built-in logger and skip debug/info/warning
|
|
10
|
+
logs during replay.
|
|
11
|
+
- Outside workflows, we use Loguru with rich formatting.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
# Always import Temporal workflow (since it's part of the project)
|
|
17
|
+
from temporalio import workflow
|
|
18
|
+
|
|
19
|
+
with workflow.unsafe.imports_passed_through():
|
|
20
|
+
from loguru import logger as loguru_logger
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def in_workflow_context() -> bool:
|
|
24
|
+
"""Returns True if this code is running inside a Temporal workflow context.
|
|
25
|
+
It does this by attempting to call workflow.info() and returning True
|
|
26
|
+
if successful. Otherwise, it returns False.
|
|
27
|
+
"""
|
|
28
|
+
try:
|
|
29
|
+
workflow.logger.debug("Checking if in workflow context...")
|
|
30
|
+
# loguru_logger.debug("Checking if in workflow context...")
|
|
31
|
+
# This call will succeed only if we're in a workflow context.
|
|
32
|
+
if hasattr(workflow.info(), "is_replaying"):
|
|
33
|
+
return True
|
|
34
|
+
else:
|
|
35
|
+
return False
|
|
36
|
+
except Exception:
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# Configure Loguru for non-workflow (local/worker) contexts.
|
|
41
|
+
# Note that in workflow code, we will use Temporal's workflow.logger instead.
|
|
42
|
+
loguru_logger.remove()
|
|
43
|
+
loguru_logger.add(
|
|
44
|
+
sys.stderr,
|
|
45
|
+
level="DEBUG",
|
|
46
|
+
colorize=True,
|
|
47
|
+
format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{message}</cyan>",
|
|
48
|
+
)
|
|
49
|
+
# Optionally add a file handler, e.g.:
|
|
50
|
+
# loguru_logger.add("logs/flock.log", rotation="100 MB", retention="30 days", level="DEBUG")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Define a dummy logger that does nothing
|
|
54
|
+
class DummyLogger:
|
|
55
|
+
def debug(self, *args, **kwargs):
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
def info(self, *args, **kwargs):
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
def warning(self, *args, **kwargs):
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
def error(self, *args, **kwargs):
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
def exception(self, *args, **kwargs):
|
|
68
|
+
pass
|
|
69
|
+
|
|
70
|
+
def success(self, *args, **kwargs):
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
dummy_logger = DummyLogger()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class FlockLogger:
|
|
78
|
+
"""A unified logger that selects the appropriate logging mechanism based on context.
|
|
79
|
+
|
|
80
|
+
- If running in a workflow context, it uses Temporal's built‑in logger.
|
|
81
|
+
Additionally, if workflow.info().is_replaying is True, it suppresses debug/info/warning logs.
|
|
82
|
+
- Otherwise, it uses Loguru.
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
def __init__(self, name: str, enable_logging: bool = False):
|
|
86
|
+
self.name = name
|
|
87
|
+
self.enable_logging = enable_logging
|
|
88
|
+
|
|
89
|
+
def _get_logger(self):
|
|
90
|
+
if not self.enable_logging:
|
|
91
|
+
return dummy_logger
|
|
92
|
+
if in_workflow_context():
|
|
93
|
+
# Use Temporal's workflow.logger inside a workflow context.
|
|
94
|
+
return workflow.logger
|
|
95
|
+
else:
|
|
96
|
+
# Bind a new Loguru logger with the given name as context.
|
|
97
|
+
return loguru_logger.bind(name=self.name)
|
|
98
|
+
|
|
99
|
+
def debug(self, message: str, *args, **kwargs):
|
|
100
|
+
self._get_logger().debug(message, *args, **kwargs)
|
|
101
|
+
|
|
102
|
+
def info(self, message: str, *args, **kwargs):
|
|
103
|
+
self._get_logger().info(message, *args, **kwargs)
|
|
104
|
+
|
|
105
|
+
def warning(self, message: str, *args, **kwargs):
|
|
106
|
+
self._get_logger().warning(message, *args, **kwargs)
|
|
107
|
+
|
|
108
|
+
def error(self, message: str, *args, **kwargs):
|
|
109
|
+
self._get_logger().error(message, *args, **kwargs)
|
|
110
|
+
|
|
111
|
+
def exception(self, message: str, *args, **kwargs):
|
|
112
|
+
self._get_logger().exception(message, *args, **kwargs)
|
|
113
|
+
|
|
114
|
+
def success(self, message: str, *args, **kwargs):
|
|
115
|
+
self._get_logger().success(message, *args, **kwargs)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def get_logger(name: str = "flock") -> FlockLogger:
|
|
119
|
+
"""Returns a FlockLogger instance for the given name.
|
|
120
|
+
|
|
121
|
+
Import and use this function throughout your Flock code instead of importing Loguru directly.
|
|
122
|
+
"""
|
|
123
|
+
return FlockLogger(name)
|