flock-core 0.5.0b28__py3-none-any.whl → 0.5.56b0__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 +12 -217
- flock/agent.py +678 -0
- flock/api/themes.py +71 -0
- flock/artifacts.py +79 -0
- flock/cli.py +75 -0
- flock/components.py +173 -0
- flock/dashboard/__init__.py +28 -0
- flock/dashboard/collector.py +283 -0
- flock/dashboard/events.py +182 -0
- flock/dashboard/launcher.py +230 -0
- flock/dashboard/service.py +537 -0
- flock/dashboard/websocket.py +235 -0
- flock/engines/__init__.py +6 -0
- flock/engines/dspy_engine.py +856 -0
- flock/examples.py +128 -0
- flock/{core/util → helper}/cli_helper.py +4 -3
- flock/{core/logging → logging}/__init__.py +2 -3
- flock/{core/logging → logging}/formatters/enum_builder.py +3 -4
- flock/{core/logging → logging}/formatters/theme_builder.py +19 -44
- flock/{core/logging → logging}/formatters/themed_formatter.py +69 -115
- flock/{core/logging → logging}/logging.py +77 -61
- flock/{core/logging → logging}/telemetry.py +20 -26
- flock/{core/logging → logging}/telemetry_exporter/base_exporter.py +2 -2
- flock/{core/logging → logging}/telemetry_exporter/file_exporter.py +6 -9
- flock/{core/logging → logging}/telemetry_exporter/sqlite_exporter.py +2 -3
- flock/{core/logging → logging}/trace_and_logged.py +20 -24
- flock/mcp/__init__.py +91 -0
- flock/{core/mcp/mcp_client.py → mcp/client.py} +103 -154
- flock/{core/mcp/mcp_config.py → mcp/config.py} +62 -117
- flock/mcp/manager.py +255 -0
- flock/mcp/servers/sse/__init__.py +1 -1
- flock/mcp/servers/sse/flock_sse_server.py +11 -53
- flock/mcp/servers/stdio/__init__.py +1 -1
- flock/mcp/servers/stdio/flock_stdio_server.py +8 -48
- flock/mcp/servers/streamable_http/flock_streamable_http_server.py +17 -62
- flock/mcp/servers/websockets/flock_websocket_server.py +7 -40
- flock/{core/mcp/flock_mcp_tool.py → mcp/tool.py} +16 -26
- flock/mcp/types/__init__.py +42 -0
- flock/{core/mcp → mcp}/types/callbacks.py +9 -15
- flock/{core/mcp → mcp}/types/factories.py +7 -6
- flock/{core/mcp → mcp}/types/handlers.py +13 -18
- flock/{core/mcp → mcp}/types/types.py +70 -74
- flock/{core/mcp → mcp}/util/helpers.py +1 -1
- flock/orchestrator.py +645 -0
- flock/registry.py +148 -0
- flock/runtime.py +262 -0
- flock/service.py +140 -0
- flock/store.py +69 -0
- flock/subscription.py +111 -0
- flock/themes/andromeda.toml +1 -1
- flock/themes/apple-system-colors.toml +1 -1
- flock/themes/arcoiris.toml +1 -1
- flock/themes/atomonelight.toml +1 -1
- flock/themes/ayu copy.toml +1 -1
- flock/themes/ayu-light.toml +1 -1
- flock/themes/belafonte-day.toml +1 -1
- flock/themes/belafonte-night.toml +1 -1
- flock/themes/blulocodark.toml +1 -1
- flock/themes/breeze.toml +1 -1
- flock/themes/broadcast.toml +1 -1
- flock/themes/brogrammer.toml +1 -1
- flock/themes/builtin-dark.toml +1 -1
- flock/themes/builtin-pastel-dark.toml +1 -1
- flock/themes/catppuccin-latte.toml +1 -1
- flock/themes/catppuccin-macchiato.toml +1 -1
- flock/themes/catppuccin-mocha.toml +1 -1
- flock/themes/cga.toml +1 -1
- flock/themes/chalk.toml +1 -1
- flock/themes/ciapre.toml +1 -1
- flock/themes/coffee-theme.toml +1 -1
- flock/themes/cyberpunkscarletprotocol.toml +1 -1
- flock/themes/dark+.toml +1 -1
- flock/themes/darkermatrix.toml +1 -1
- flock/themes/darkside.toml +1 -1
- flock/themes/desert.toml +1 -1
- flock/themes/django.toml +1 -1
- flock/themes/djangosmooth.toml +1 -1
- flock/themes/doomone.toml +1 -1
- flock/themes/dotgov.toml +1 -1
- flock/themes/dracula+.toml +1 -1
- flock/themes/duckbones.toml +1 -1
- flock/themes/encom.toml +1 -1
- flock/themes/espresso.toml +1 -1
- flock/themes/everblush.toml +1 -1
- flock/themes/fairyfloss.toml +1 -1
- flock/themes/fideloper.toml +1 -1
- flock/themes/fishtank.toml +1 -1
- flock/themes/flexoki-light.toml +1 -1
- flock/themes/floraverse.toml +1 -1
- flock/themes/framer.toml +1 -1
- flock/themes/galizur.toml +1 -1
- flock/themes/github.toml +1 -1
- flock/themes/grass.toml +1 -1
- flock/themes/grey-green.toml +1 -1
- flock/themes/gruvboxlight.toml +1 -1
- flock/themes/guezwhoz.toml +1 -1
- flock/themes/harper.toml +1 -1
- flock/themes/hax0r-blue.toml +1 -1
- flock/themes/hopscotch.256.toml +1 -1
- flock/themes/ic-green-ppl.toml +1 -1
- flock/themes/iceberg-dark.toml +1 -1
- flock/themes/japanesque.toml +1 -1
- flock/themes/jubi.toml +1 -1
- flock/themes/kibble.toml +1 -1
- flock/themes/kolorit.toml +1 -1
- flock/themes/kurokula.toml +1 -1
- flock/themes/materialdesigncolors.toml +1 -1
- flock/themes/matrix.toml +1 -1
- flock/themes/mellifluous.toml +1 -1
- flock/themes/midnight-in-mojave.toml +1 -1
- flock/themes/monokai-remastered.toml +1 -1
- flock/themes/monokai-soda.toml +1 -1
- flock/themes/neon.toml +1 -1
- flock/themes/neopolitan.toml +1 -1
- flock/themes/nord-light.toml +1 -1
- flock/themes/ocean.toml +1 -1
- flock/themes/onehalfdark.toml +1 -1
- flock/themes/onehalflight.toml +1 -1
- flock/themes/palenighthc.toml +1 -1
- flock/themes/paulmillr.toml +1 -1
- flock/themes/pencildark.toml +1 -1
- flock/themes/pnevma.toml +1 -1
- flock/themes/purple-rain.toml +1 -1
- flock/themes/purplepeter.toml +1 -1
- flock/themes/raycast-dark.toml +1 -1
- flock/themes/red-sands.toml +1 -1
- flock/themes/relaxed.toml +1 -1
- flock/themes/retro.toml +1 -1
- flock/themes/rose-pine.toml +1 -1
- flock/themes/royal.toml +1 -1
- flock/themes/ryuuko.toml +1 -1
- flock/themes/sakura.toml +1 -1
- flock/themes/scarlet-protocol.toml +1 -1
- flock/themes/seoulbones-dark.toml +1 -1
- flock/themes/shades-of-purple.toml +1 -1
- flock/themes/smyck.toml +1 -1
- flock/themes/softserver.toml +1 -1
- flock/themes/solarized-darcula.toml +1 -1
- flock/themes/square.toml +1 -1
- flock/themes/sugarplum.toml +1 -1
- flock/themes/thayer-bright.toml +1 -1
- flock/themes/tokyonight.toml +1 -1
- flock/themes/tomorrow.toml +1 -1
- flock/themes/ubuntu.toml +1 -1
- flock/themes/ultradark.toml +1 -1
- flock/themes/ultraviolent.toml +1 -1
- flock/themes/unikitty.toml +1 -1
- flock/themes/urple.toml +1 -1
- flock/themes/vesper.toml +1 -1
- flock/themes/vimbones.toml +1 -1
- flock/themes/wildcherry.toml +1 -1
- flock/themes/wilmersdorf.toml +1 -1
- flock/themes/wryan.toml +1 -1
- flock/themes/xcodedarkhc.toml +1 -1
- flock/themes/xcodelight.toml +1 -1
- flock/themes/zenbones-light.toml +1 -1
- flock/themes/zenwritten-dark.toml +1 -1
- flock/utilities.py +301 -0
- flock/{components/utility → utility}/output_utility_component.py +68 -53
- flock/visibility.py +107 -0
- flock_core-0.5.56b0.dist-info/METADATA +747 -0
- flock_core-0.5.56b0.dist-info/RECORD +398 -0
- flock_core-0.5.56b0.dist-info/entry_points.txt +2 -0
- {flock_core-0.5.0b28.dist-info → flock_core-0.5.56b0.dist-info}/licenses/LICENSE +1 -1
- flock/adapter/__init__.py +0 -14
- flock/adapter/azure_adapter.py +0 -68
- flock/adapter/chroma_adapter.py +0 -73
- flock/adapter/faiss_adapter.py +0 -97
- flock/adapter/pinecone_adapter.py +0 -51
- flock/adapter/vector_base.py +0 -47
- flock/cli/assets/release_notes.md +0 -140
- flock/cli/config.py +0 -8
- flock/cli/constants.py +0 -36
- flock/cli/create_agent.py +0 -1
- flock/cli/create_flock.py +0 -280
- flock/cli/execute_flock.py +0 -620
- flock/cli/load_agent.py +0 -1
- flock/cli/load_examples.py +0 -1
- flock/cli/load_flock.py +0 -192
- flock/cli/load_release_notes.py +0 -20
- flock/cli/loaded_flock_cli.py +0 -254
- flock/cli/manage_agents.py +0 -459
- flock/cli/registry_management.py +0 -889
- flock/cli/runner.py +0 -41
- flock/cli/settings.py +0 -857
- flock/cli/utils.py +0 -135
- flock/cli/view_results.py +0 -29
- flock/cli/yaml_editor.py +0 -396
- flock/components/__init__.py +0 -30
- flock/components/evaluation/__init__.py +0 -9
- flock/components/evaluation/declarative_evaluation_component.py +0 -606
- flock/components/routing/__init__.py +0 -15
- flock/components/routing/conditional_routing_component.py +0 -494
- flock/components/routing/default_routing_component.py +0 -103
- flock/components/routing/llm_routing_component.py +0 -206
- flock/components/utility/__init__.py +0 -22
- flock/components/utility/example_utility_component.py +0 -250
- flock/components/utility/feedback_utility_component.py +0 -206
- flock/components/utility/memory_utility_component.py +0 -550
- flock/components/utility/metrics_utility_component.py +0 -700
- flock/config.py +0 -61
- flock/core/__init__.py +0 -110
- flock/core/agent/__init__.py +0 -16
- flock/core/agent/default_agent.py +0 -216
- flock/core/agent/flock_agent_components.py +0 -104
- flock/core/agent/flock_agent_execution.py +0 -101
- flock/core/agent/flock_agent_integration.py +0 -260
- flock/core/agent/flock_agent_lifecycle.py +0 -186
- flock/core/agent/flock_agent_serialization.py +0 -381
- flock/core/api/__init__.py +0 -10
- flock/core/api/custom_endpoint.py +0 -45
- flock/core/api/endpoints.py +0 -254
- flock/core/api/main.py +0 -162
- flock/core/api/models.py +0 -97
- flock/core/api/run_store.py +0 -224
- flock/core/api/runner.py +0 -44
- flock/core/api/service.py +0 -214
- flock/core/component/__init__.py +0 -15
- flock/core/component/agent_component_base.py +0 -309
- flock/core/component/evaluation_component.py +0 -62
- flock/core/component/routing_component.py +0 -74
- flock/core/component/utility_component.py +0 -69
- flock/core/config/flock_agent_config.py +0 -58
- flock/core/config/scheduled_agent_config.py +0 -40
- flock/core/context/context.py +0 -213
- flock/core/context/context_manager.py +0 -37
- flock/core/context/context_vars.py +0 -10
- flock/core/evaluation/utils.py +0 -396
- flock/core/execution/batch_executor.py +0 -369
- flock/core/execution/evaluation_executor.py +0 -438
- flock/core/execution/local_executor.py +0 -31
- flock/core/execution/opik_executor.py +0 -103
- flock/core/execution/temporal_executor.py +0 -164
- flock/core/flock.py +0 -634
- flock/core/flock_agent.py +0 -336
- flock/core/flock_factory.py +0 -613
- flock/core/flock_scheduler.py +0 -166
- flock/core/flock_server_manager.py +0 -136
- flock/core/interpreter/python_interpreter.py +0 -689
- flock/core/mcp/__init__.py +0 -1
- flock/core/mcp/flock_mcp_server.py +0 -680
- flock/core/mcp/mcp_client_manager.py +0 -201
- flock/core/mcp/types/__init__.py +0 -1
- flock/core/mixin/dspy_integration.py +0 -403
- flock/core/mixin/prompt_parser.py +0 -125
- flock/core/orchestration/__init__.py +0 -15
- flock/core/orchestration/flock_batch_processor.py +0 -94
- flock/core/orchestration/flock_evaluator.py +0 -113
- flock/core/orchestration/flock_execution.py +0 -295
- flock/core/orchestration/flock_initialization.py +0 -149
- flock/core/orchestration/flock_server_manager.py +0 -67
- flock/core/orchestration/flock_web_server.py +0 -117
- flock/core/registry/__init__.py +0 -45
- flock/core/registry/agent_registry.py +0 -69
- flock/core/registry/callable_registry.py +0 -139
- flock/core/registry/component_discovery.py +0 -142
- flock/core/registry/component_registry.py +0 -64
- flock/core/registry/config_mapping.py +0 -64
- flock/core/registry/decorators.py +0 -137
- flock/core/registry/registry_hub.py +0 -205
- flock/core/registry/server_registry.py +0 -57
- flock/core/registry/type_registry.py +0 -86
- flock/core/serialization/__init__.py +0 -13
- flock/core/serialization/callable_registry.py +0 -52
- flock/core/serialization/flock_serializer.py +0 -832
- flock/core/serialization/json_encoder.py +0 -41
- flock/core/serialization/secure_serializer.py +0 -175
- flock/core/serialization/serializable.py +0 -342
- flock/core/serialization/serialization_utils.py +0 -412
- flock/core/util/file_path_utils.py +0 -223
- flock/core/util/hydrator.py +0 -309
- flock/core/util/input_resolver.py +0 -164
- flock/core/util/loader.py +0 -59
- flock/core/util/splitter.py +0 -219
- flock/di.py +0 -27
- flock/platform/docker_tools.py +0 -49
- flock/platform/jaeger_install.py +0 -86
- flock/webapp/__init__.py +0 -1
- flock/webapp/app/__init__.py +0 -0
- flock/webapp/app/api/__init__.py +0 -0
- flock/webapp/app/api/agent_management.py +0 -241
- flock/webapp/app/api/execution.py +0 -709
- flock/webapp/app/api/flock_management.py +0 -129
- flock/webapp/app/api/registry_viewer.py +0 -30
- flock/webapp/app/chat.py +0 -665
- flock/webapp/app/config.py +0 -104
- flock/webapp/app/dependencies.py +0 -117
- flock/webapp/app/main.py +0 -1070
- flock/webapp/app/middleware.py +0 -113
- flock/webapp/app/models_ui.py +0 -7
- flock/webapp/app/services/__init__.py +0 -0
- flock/webapp/app/services/feedback_file_service.py +0 -363
- flock/webapp/app/services/flock_service.py +0 -337
- flock/webapp/app/services/sharing_models.py +0 -81
- flock/webapp/app/services/sharing_store.py +0 -762
- flock/webapp/app/templates/theme_mapper.html +0 -326
- flock/webapp/app/theme_mapper.py +0 -812
- flock/webapp/app/utils.py +0 -85
- flock/webapp/run.py +0 -215
- flock/webapp/static/css/chat.css +0 -301
- flock/webapp/static/css/components.css +0 -167
- flock/webapp/static/css/header.css +0 -39
- flock/webapp/static/css/layout.css +0 -46
- flock/webapp/static/css/sidebar.css +0 -127
- flock/webapp/static/css/two-pane.css +0 -48
- flock/webapp/templates/base.html +0 -200
- flock/webapp/templates/chat.html +0 -152
- flock/webapp/templates/chat_settings.html +0 -19
- flock/webapp/templates/flock_editor.html +0 -16
- flock/webapp/templates/index.html +0 -12
- flock/webapp/templates/partials/_agent_detail_form.html +0 -93
- flock/webapp/templates/partials/_agent_list.html +0 -18
- flock/webapp/templates/partials/_agent_manager_view.html +0 -51
- flock/webapp/templates/partials/_agent_tools_checklist.html +0 -14
- flock/webapp/templates/partials/_chat_container.html +0 -15
- flock/webapp/templates/partials/_chat_messages.html +0 -57
- flock/webapp/templates/partials/_chat_settings_form.html +0 -85
- flock/webapp/templates/partials/_create_flock_form.html +0 -50
- flock/webapp/templates/partials/_dashboard_flock_detail.html +0 -17
- flock/webapp/templates/partials/_dashboard_flock_file_list.html +0 -16
- flock/webapp/templates/partials/_dashboard_flock_properties_preview.html +0 -28
- flock/webapp/templates/partials/_dashboard_upload_flock_form.html +0 -16
- flock/webapp/templates/partials/_dynamic_input_form_content.html +0 -22
- flock/webapp/templates/partials/_env_vars_table.html +0 -23
- flock/webapp/templates/partials/_execution_form.html +0 -118
- flock/webapp/templates/partials/_execution_view_container.html +0 -28
- flock/webapp/templates/partials/_flock_file_list.html +0 -23
- flock/webapp/templates/partials/_flock_properties_form.html +0 -52
- flock/webapp/templates/partials/_flock_upload_form.html +0 -16
- flock/webapp/templates/partials/_header_flock_status.html +0 -5
- flock/webapp/templates/partials/_load_manager_view.html +0 -49
- flock/webapp/templates/partials/_registry_table.html +0 -25
- flock/webapp/templates/partials/_registry_viewer_content.html +0 -70
- flock/webapp/templates/partials/_results_display.html +0 -78
- flock/webapp/templates/partials/_settings_env_content.html +0 -9
- flock/webapp/templates/partials/_settings_theme_content.html +0 -14
- flock/webapp/templates/partials/_settings_view.html +0 -36
- flock/webapp/templates/partials/_share_chat_link_snippet.html +0 -11
- flock/webapp/templates/partials/_share_link_snippet.html +0 -35
- flock/webapp/templates/partials/_sidebar.html +0 -74
- flock/webapp/templates/partials/_streaming_results_container.html +0 -195
- flock/webapp/templates/partials/_structured_data_view.html +0 -40
- flock/webapp/templates/partials/_theme_preview.html +0 -36
- flock/webapp/templates/registry_viewer.html +0 -84
- flock/webapp/templates/shared_run_page.html +0 -140
- flock/workflow/__init__.py +0 -0
- flock/workflow/activities.py +0 -196
- flock/workflow/agent_activities.py +0 -24
- flock/workflow/agent_execution_activity.py +0 -202
- flock/workflow/flock_workflow.py +0 -214
- flock/workflow/temporal_config.py +0 -96
- flock/workflow/temporal_setup.py +0 -68
- flock_core-0.5.0b28.dist-info/METADATA +0 -274
- flock_core-0.5.0b28.dist-info/RECORD +0 -561
- flock_core-0.5.0b28.dist-info/entry_points.txt +0 -2
- /flock/{core/logging → logging}/formatters/themes.py +0 -0
- /flock/{core/logging → logging}/span_middleware/baggage_span_processor.py +0 -0
- /flock/{core/mcp → mcp}/util/__init__.py +0 -0
- {flock_core-0.5.0b28.dist-info → flock_core-0.5.56b0.dist-info}/WHEEL +0 -0
flock/examples.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Concrete demo wiring matching the design document."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
if __name__ == "__main__" and __package__ is None:
|
|
10
|
+
sys.path.append(str(Path(__file__).resolve().parents[2]))
|
|
11
|
+
|
|
12
|
+
from typing import TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
from pydantic import BaseModel, Field
|
|
15
|
+
|
|
16
|
+
from flock.artifacts import Artifact
|
|
17
|
+
from flock.components import EngineComponent
|
|
18
|
+
from flock.orchestrator import Flock
|
|
19
|
+
from flock.registry import flock_tool, flock_type, type_registry
|
|
20
|
+
from flock.runtime import EvalInputs, EvalResult
|
|
21
|
+
from flock.utilities import LoggingUtility, MetricsUtility
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from flock.agent import AgentBuilder
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@flock_type
|
|
29
|
+
class Idea(BaseModel):
|
|
30
|
+
topic: str
|
|
31
|
+
genre: str
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@flock_type
|
|
35
|
+
class Movie(BaseModel):
|
|
36
|
+
fun_title: str = Field(description="Fun title in CAPS")
|
|
37
|
+
runtime: int = Field(ge=60, le=400)
|
|
38
|
+
synopsis: str
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@flock_type
|
|
42
|
+
class Tagline(BaseModel):
|
|
43
|
+
line: str
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@flock_tool
|
|
47
|
+
def announce(tagline: Tagline) -> dict[str, str]:
|
|
48
|
+
return {"announced": tagline.line}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class MovieEngine(EngineComponent):
|
|
52
|
+
async def evaluate(self, agent, ctx, inputs: EvalInputs) -> EvalResult:
|
|
53
|
+
idea = Idea(**inputs.artifacts[0].payload)
|
|
54
|
+
synopsis = f"{idea.topic} told as a {idea.genre} adventure."
|
|
55
|
+
movie = Movie(fun_title=idea.topic.upper(), runtime=120, synopsis=synopsis)
|
|
56
|
+
artifact = Artifact(
|
|
57
|
+
type=type_registry.name_for(Movie),
|
|
58
|
+
payload=movie.model_dump(),
|
|
59
|
+
produced_by=agent.name,
|
|
60
|
+
)
|
|
61
|
+
return EvalResult(artifacts=[artifact])
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class TaglineEngine(EngineComponent):
|
|
65
|
+
async def evaluate(self, agent, ctx, inputs: EvalInputs) -> EvalResult:
|
|
66
|
+
movie = Movie(**inputs.artifacts[0].payload)
|
|
67
|
+
tagline = Tagline(line=f"Don't miss {movie.fun_title}!")
|
|
68
|
+
artifact = Artifact(
|
|
69
|
+
type=type_registry.name_for(Tagline),
|
|
70
|
+
payload=tagline.model_dump(),
|
|
71
|
+
produced_by=agent.name,
|
|
72
|
+
)
|
|
73
|
+
return EvalResult(artifacts=[artifact])
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def create_demo_orchestrator(
|
|
77
|
+
model: str | None = None,
|
|
78
|
+
) -> tuple[Flock, dict[str, AgentBuilder]]:
|
|
79
|
+
orchestrator = Flock(model)
|
|
80
|
+
|
|
81
|
+
movie = (
|
|
82
|
+
orchestrator.agent("movie")
|
|
83
|
+
.description("Generate a movie concept.")
|
|
84
|
+
.consumes(Idea)
|
|
85
|
+
.publishes(Movie)
|
|
86
|
+
.only_for("tagline", "presenter")
|
|
87
|
+
.with_utilities(MetricsUtility(), LoggingUtility())
|
|
88
|
+
.with_engines(MovieEngine())
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
tagline = (
|
|
92
|
+
orchestrator.agent("tagline")
|
|
93
|
+
.description("Generate a tagline.")
|
|
94
|
+
.consumes(Movie, where=lambda m: 60 <= m.runtime <= 200, from_agents={"movie"})
|
|
95
|
+
.publishes(Tagline)
|
|
96
|
+
.with_engines(TaglineEngine())
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
presenter = (
|
|
100
|
+
orchestrator.agent("presenter")
|
|
101
|
+
.description("Announce the winner.")
|
|
102
|
+
.consumes(Tagline, mode="both")
|
|
103
|
+
.calls(announce)
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
return orchestrator, {"movie": movie, "tagline": tagline, "presenter": presenter}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
__all__ = [
|
|
110
|
+
"Idea",
|
|
111
|
+
"Movie",
|
|
112
|
+
"Tagline",
|
|
113
|
+
"announce",
|
|
114
|
+
"create_demo_orchestrator",
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
import asyncio
|
|
119
|
+
|
|
120
|
+
async def _demo_run() -> None:
|
|
121
|
+
orchestrator, agents = create_demo_orchestrator()
|
|
122
|
+
idea = Idea(topic="AI agents collaborating", genre="comedy")
|
|
123
|
+
outputs = await orchestrator.arun(agents["movie"], idea)
|
|
124
|
+
await orchestrator.run_until_idle()
|
|
125
|
+
for artifact in outputs:
|
|
126
|
+
print(f"{artifact.type}: {artifact.payload}")
|
|
127
|
+
|
|
128
|
+
asyncio.run(_demo_run())
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from importlib.metadata import PackageNotFoundError, version
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
try:
|
|
4
|
-
__version__ = version("flock-
|
|
5
|
+
__version__ = version("flock-flow")
|
|
5
6
|
except PackageNotFoundError:
|
|
6
7
|
__version__ = "0.2.0"
|
|
7
8
|
|
|
@@ -51,7 +52,7 @@ def init_console(clear_screen: bool = True, show_banner: bool = True, model: str
|
|
|
51
52
|
│ ▒█▀▀▀ █░░ █▀▀█ █▀▀ █░█ │
|
|
52
53
|
│ ▒█▀▀▀ █░░ █░░█ █░░ █▀▄ │
|
|
53
54
|
│ ▒█░░░ ▀▀▀ ▀▀▀▀ ▀▀▀ ▀░▀ │
|
|
54
|
-
╰━━━━━━━━v{__version__}
|
|
55
|
+
╰━━━━━━━━v{__version__}━━━━━━━━━╯
|
|
55
56
|
🦆 🐤 🐧 🐓
|
|
56
57
|
""",
|
|
57
58
|
justify="center",
|
|
@@ -63,7 +64,7 @@ def init_console(clear_screen: bool = True, show_banner: bool = True, model: str
|
|
|
63
64
|
if show_banner:
|
|
64
65
|
console.print(banner_text)
|
|
65
66
|
console.print(
|
|
66
|
-
"[italic]'
|
|
67
|
+
"[italic]'Raven'[/] milestone - [bold]white duck GmbH[/] - [cyan]https://whiteduck.de[/]\n"
|
|
67
68
|
)
|
|
68
69
|
|
|
69
70
|
if model:
|
|
@@ -4,14 +4,13 @@ import os
|
|
|
4
4
|
import pathlib
|
|
5
5
|
import re
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
theme_folder = pathlib.Path(__file__).parent.parent.parent / "themes"
|
|
8
9
|
|
|
9
10
|
if not theme_folder.exists():
|
|
10
11
|
raise FileNotFoundError(f"Theme folder not found: {theme_folder}")
|
|
11
12
|
|
|
12
|
-
theme_files = [
|
|
13
|
-
pathlib.Path(f.path).stem for f in os.scandir(theme_folder) if f.is_file()
|
|
14
|
-
]
|
|
13
|
+
theme_files = [pathlib.Path(f.path).stem for f in os.scandir(theme_folder) if f.is_file()]
|
|
15
14
|
|
|
16
15
|
theme_enum_entries = {}
|
|
17
16
|
for theme in theme_files:
|
|
@@ -153,9 +153,7 @@ def generate_default_rich_block(theme: dict | None = None) -> dict[str, Any]:
|
|
|
153
153
|
),
|
|
154
154
|
"panel_padding": random.choice([[1, 2], [1, 1], [2, 2], [0, 2]]),
|
|
155
155
|
"panel_title_align": random.choice(["left", "center", "right"]),
|
|
156
|
-
"table_row_styles": random.choice(
|
|
157
|
-
[["", "dim"], ["", "italic"], ["", "underline"]]
|
|
158
|
-
),
|
|
156
|
+
"table_row_styles": random.choice([["", "dim"], ["", "italic"], ["", "underline"]]),
|
|
159
157
|
}
|
|
160
158
|
# Extra table layout properties (non-content).
|
|
161
159
|
default_extra_table_props = {
|
|
@@ -175,13 +173,12 @@ def generate_default_rich_block(theme: dict | None = None) -> dict[str, Any]:
|
|
|
175
173
|
"table_caption_justify": "center",
|
|
176
174
|
"table_highlight": False,
|
|
177
175
|
}
|
|
178
|
-
|
|
176
|
+
return {
|
|
179
177
|
**default_color_props,
|
|
180
178
|
**extra_color_props,
|
|
181
179
|
**default_non_color_props,
|
|
182
180
|
**default_extra_table_props,
|
|
183
181
|
}
|
|
184
|
-
return defaults
|
|
185
182
|
|
|
186
183
|
|
|
187
184
|
def load_theme_from_file(filepath: str) -> dict:
|
|
@@ -207,9 +204,7 @@ def get_default_styles(theme: dict | None) -> dict[str, Any]:
|
|
|
207
204
|
else:
|
|
208
205
|
defaults = generate_default_rich_block(theme)
|
|
209
206
|
rich_props = theme.get("rich", {})
|
|
210
|
-
final_styles = {
|
|
211
|
-
key: rich_props.get(key, defaults[key]) for key in defaults
|
|
212
|
-
}
|
|
207
|
+
final_styles = {key: rich_props.get(key, defaults[key]) for key in defaults}
|
|
213
208
|
# Ensure tuple for padding properties.
|
|
214
209
|
final_styles["panel_padding"] = tuple(final_styles["panel_padding"])
|
|
215
210
|
if "table_padding" in final_styles:
|
|
@@ -272,33 +267,23 @@ def create_rich_renderable(
|
|
|
272
267
|
table.add_column("Key", style=styles["column_output"])
|
|
273
268
|
table.add_column("Value", style=styles["column_value"])
|
|
274
269
|
for k, v in value.items():
|
|
275
|
-
table.add_row(
|
|
276
|
-
str(k), create_rich_renderable(v, level + 1, theme, styles)
|
|
277
|
-
)
|
|
270
|
+
table.add_row(str(k), create_rich_renderable(v, level + 1, theme, styles))
|
|
278
271
|
return table
|
|
279
272
|
|
|
280
|
-
|
|
273
|
+
if isinstance(value, (list, tuple)):
|
|
281
274
|
if all(isinstance(item, dict) for item in value):
|
|
282
275
|
sub_tables = []
|
|
283
276
|
for i, item in enumerate(value):
|
|
284
277
|
sub_tables.append(f"[bold]Item {i + 1}[/bold]")
|
|
285
|
-
sub_tables.append(
|
|
286
|
-
create_rich_renderable(item, level + 1, theme, styles)
|
|
287
|
-
)
|
|
278
|
+
sub_tables.append(create_rich_renderable(item, level + 1, theme, styles))
|
|
288
279
|
return Group(*sub_tables)
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
else:
|
|
297
|
-
return Group(*rendered_items)
|
|
298
|
-
else:
|
|
299
|
-
if isinstance(value, str) and "\n" in value:
|
|
300
|
-
return f"\n{value}\n"
|
|
301
|
-
return str(value)
|
|
280
|
+
rendered_items = [create_rich_renderable(item, level + 1, theme, styles) for item in value]
|
|
281
|
+
if all(isinstance(item, str) for item in rendered_items):
|
|
282
|
+
return "\n".join(rendered_items)
|
|
283
|
+
return Group(*rendered_items)
|
|
284
|
+
if isinstance(value, str) and "\n" in value:
|
|
285
|
+
return f"\n{value}\n"
|
|
286
|
+
return str(value)
|
|
302
287
|
|
|
303
288
|
|
|
304
289
|
# --- Theme Builder Functions --- #
|
|
@@ -312,9 +297,7 @@ def load_theme_files(theme_dir: pathlib.Path) -> list[pathlib.Path]:
|
|
|
312
297
|
def display_color_palette(theme: dict) -> None:
|
|
313
298
|
"""Display the color palette from a theme's [colors] sections with a color preview."""
|
|
314
299
|
console = Console()
|
|
315
|
-
palette_table = Table(
|
|
316
|
-
title="Color Palette", show_header=True, header_style="bold"
|
|
317
|
-
)
|
|
300
|
+
palette_table = Table(title="Color Palette", show_header=True, header_style="bold")
|
|
318
301
|
palette_table.add_column("Section", style="bold")
|
|
319
302
|
palette_table.add_column("Key", style="italic")
|
|
320
303
|
palette_table.add_column("Value", style="bold")
|
|
@@ -331,9 +314,7 @@ def display_color_palette(theme: dict) -> None:
|
|
|
331
314
|
console.print(palette_table)
|
|
332
315
|
|
|
333
316
|
|
|
334
|
-
def generate_sample_rich_blocks(
|
|
335
|
-
chosen_theme: dict, count: int
|
|
336
|
-
) -> list[dict[str, Any]]:
|
|
317
|
+
def generate_sample_rich_blocks(chosen_theme: dict, count: int) -> list[dict[str, Any]]:
|
|
337
318
|
"""Generate a list of sample rich blocks (randomized layout) using the chosen theme's colors."""
|
|
338
319
|
samples = []
|
|
339
320
|
for _ in range(count):
|
|
@@ -349,9 +330,7 @@ def generate_sample_table(sample_theme: dict, dummy_data: dict) -> Panel:
|
|
|
349
330
|
# For simplicity, we create our own panel.
|
|
350
331
|
styles = get_default_styles(sample_theme)
|
|
351
332
|
# Build a basic table (using our earlier functions)
|
|
352
|
-
table = create_rich_renderable(
|
|
353
|
-
dummy_data, theme=sample_theme, styles=styles
|
|
354
|
-
)
|
|
333
|
+
table = create_rich_renderable(dummy_data, theme=sample_theme, styles=styles)
|
|
355
334
|
return Panel(
|
|
356
335
|
table,
|
|
357
336
|
title="Sample Table",
|
|
@@ -373,7 +352,7 @@ def save_theme(theme: dict, filename: pathlib.Path) -> None:
|
|
|
373
352
|
|
|
374
353
|
def theme_builder():
|
|
375
354
|
console = Console(force_terminal=True, color_system="truecolor")
|
|
376
|
-
themes_dir = pathlib.Path(__file__).parent.parent.parent
|
|
355
|
+
themes_dir = pathlib.Path(__file__).parent.parent.parent / "themes"
|
|
377
356
|
theme_files = load_theme_files(themes_dir)
|
|
378
357
|
|
|
379
358
|
if not theme_files:
|
|
@@ -443,9 +422,7 @@ def theme_builder():
|
|
|
443
422
|
samples = []
|
|
444
423
|
for i, rich_block in enumerate(sample_rich_blocks):
|
|
445
424
|
# Build a sample theme: copy the chosen theme and override its [rich] block.
|
|
446
|
-
sample_theme = dict(
|
|
447
|
-
chosen_theme
|
|
448
|
-
) # shallow copy (good enough if colors remain unchanged)
|
|
425
|
+
sample_theme = dict(chosen_theme) # shallow copy (good enough if colors remain unchanged)
|
|
449
426
|
sample_theme["rich"] = rich_block
|
|
450
427
|
sample_table = generate_sample_table(sample_theme, dummy_data)
|
|
451
428
|
samples.append((sample_theme, sample_table))
|
|
@@ -468,9 +445,7 @@ def theme_builder():
|
|
|
468
445
|
return
|
|
469
446
|
|
|
470
447
|
# Ask for file name to save the chosen theme.
|
|
471
|
-
filename = console.input(
|
|
472
|
-
"\nEnter a filename to save the chosen theme (e.g. mytheme.toml): "
|
|
473
|
-
)
|
|
448
|
+
filename = console.input("\nEnter a filename to save the chosen theme (e.g. mytheme.toml): ")
|
|
474
449
|
save_path = themes_dir / filename
|
|
475
450
|
save_theme(chosen_sample_theme, save_path)
|
|
476
451
|
console.print(f"\n[green]Theme saved as {save_path}.[/green]")
|
|
@@ -5,21 +5,21 @@ import random
|
|
|
5
5
|
import re
|
|
6
6
|
from typing import Any
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
from flock.core.logging.formatters.themes import OutputTheme
|
|
8
|
+
import toml # install with: pip install toml
|
|
9
|
+
from pydantic import BaseModel
|
|
11
10
|
|
|
12
|
-
with workflow.unsafe.imports_passed_through():
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
# with workflow.unsafe.imports_passed_through():
|
|
12
|
+
from pygments.style import Style
|
|
13
|
+
from pygments.token import Token
|
|
14
|
+
from rich import box
|
|
15
|
+
from rich.console import Console, Group
|
|
16
|
+
from rich.panel import Panel
|
|
17
|
+
from rich.syntax import PygmentsSyntaxTheme, Syntax
|
|
18
|
+
from rich.table import Table
|
|
19
|
+
from rich.theme import Theme
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
# from temporalio import workflow
|
|
22
|
+
from flock.logging.formatters.themes import OutputTheme
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
def resolve_style_string(style_str: str, theme: dict) -> str:
|
|
@@ -76,18 +76,10 @@ def generate_default_rich_block(theme: dict | None = None) -> dict[str, Any]:
|
|
|
76
76
|
cursor_cursor = theme["colors"]["cursor"].get("cursor", "#d0d0d0")
|
|
77
77
|
cursor_text = theme["colors"]["cursor"].get("text", "#151515")
|
|
78
78
|
|
|
79
|
-
primary_background = theme["colors"]["primary"].get(
|
|
80
|
-
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
"foreground", "#c5c8c6"
|
|
84
|
-
)
|
|
85
|
-
selection_background = theme["colors"]["selection"].get(
|
|
86
|
-
"background", "#444444"
|
|
87
|
-
)
|
|
88
|
-
selection_text = theme["colors"]["selection"].get(
|
|
89
|
-
"text", primary_foreground
|
|
90
|
-
)
|
|
79
|
+
primary_background = theme["colors"]["primary"].get("background", "#161719")
|
|
80
|
+
primary_foreground = theme["colors"]["primary"].get("foreground", "#c5c8c6")
|
|
81
|
+
selection_background = theme["colors"]["selection"].get("background", "#444444")
|
|
82
|
+
selection_text = theme["colors"]["selection"].get("text", primary_foreground)
|
|
91
83
|
else:
|
|
92
84
|
bright_black = "black"
|
|
93
85
|
bright_blue = "blue"
|
|
@@ -155,9 +147,7 @@ def generate_default_rich_block(theme: dict | None = None) -> dict[str, Any]:
|
|
|
155
147
|
"panel_padding": random.choice([[1, 2], [1, 1], [2, 2], [0, 2]]),
|
|
156
148
|
"panel_title_align": random.choice(["left", "center", "right"]),
|
|
157
149
|
# Add table_row_styles property.
|
|
158
|
-
"table_row_styles": random.choice(
|
|
159
|
-
[["", "dim"], ["", "italic"], ["", "underline"]]
|
|
160
|
-
),
|
|
150
|
+
"table_row_styles": random.choice([["", "dim"], ["", "italic"], ["", "underline"]]),
|
|
161
151
|
}
|
|
162
152
|
# Extra table layout properties (non content properties).
|
|
163
153
|
default_extra_table_props = {
|
|
@@ -178,13 +168,12 @@ def generate_default_rich_block(theme: dict | None = None) -> dict[str, Any]:
|
|
|
178
168
|
"table_highlight": False,
|
|
179
169
|
}
|
|
180
170
|
# Combine all defaults.
|
|
181
|
-
|
|
171
|
+
return {
|
|
182
172
|
**default_color_props,
|
|
183
173
|
**extra_color_props,
|
|
184
174
|
**default_non_color_props,
|
|
185
175
|
**default_extra_table_props,
|
|
186
176
|
}
|
|
187
|
-
return defaults
|
|
188
177
|
|
|
189
178
|
|
|
190
179
|
def load_theme_from_file(filepath: str) -> dict:
|
|
@@ -221,9 +210,7 @@ def get_default_styles(theme: dict | None) -> dict[str, Any]:
|
|
|
221
210
|
else:
|
|
222
211
|
defaults = generate_default_rich_block(theme)
|
|
223
212
|
rich_props = theme.get("rich", {})
|
|
224
|
-
final_styles = {
|
|
225
|
-
key: rich_props.get(key, defaults[key]) for key in defaults
|
|
226
|
-
}
|
|
213
|
+
final_styles = {key: rich_props.get(key, defaults[key]) for key in defaults}
|
|
227
214
|
|
|
228
215
|
# Ensure that panel_padding and table_padding are tuples.
|
|
229
216
|
final_styles["panel_padding"] = tuple(final_styles["panel_padding"])
|
|
@@ -256,14 +243,6 @@ def create_rich_renderable(
|
|
|
256
243
|
if styles is None:
|
|
257
244
|
styles = get_default_styles(theme)
|
|
258
245
|
|
|
259
|
-
# Convert Pydantic BaseModel instances to dicts for rendering
|
|
260
|
-
try:
|
|
261
|
-
from pydantic import BaseModel
|
|
262
|
-
if isinstance(value, BaseModel):
|
|
263
|
-
value = value.model_dump()
|
|
264
|
-
except ImportError:
|
|
265
|
-
pass
|
|
266
|
-
|
|
267
246
|
# If the value is a dictionary, render it as a table.
|
|
268
247
|
if isinstance(value, dict):
|
|
269
248
|
# Convert table_box string into an actual box style.
|
|
@@ -309,41 +288,31 @@ def create_rich_renderable(
|
|
|
309
288
|
return table
|
|
310
289
|
|
|
311
290
|
# If the value is a list or tuple, render each item.
|
|
312
|
-
|
|
291
|
+
if isinstance(value, list | tuple):
|
|
313
292
|
if all(isinstance(item, dict) for item in value):
|
|
314
293
|
sub_tables = []
|
|
315
294
|
for i, item in enumerate(value):
|
|
316
295
|
sub_tables.append(f"[bold]Item {i + 1}[/bold]")
|
|
317
296
|
sub_tables.append(
|
|
318
|
-
create_rich_renderable(
|
|
319
|
-
item, level + 1, theme, styles, max_length=max_length
|
|
320
|
-
)
|
|
297
|
+
create_rich_renderable(item, level + 1, theme, styles, max_length=max_length)
|
|
321
298
|
)
|
|
322
299
|
return Group(*sub_tables)
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
if all(isinstance(item, str) for item in rendered_items):
|
|
331
|
-
return "\n".join(rendered_items)
|
|
332
|
-
else:
|
|
333
|
-
return Group(*rendered_items)
|
|
300
|
+
rendered_items = [
|
|
301
|
+
create_rich_renderable(item, level + 1, theme, styles, max_length=max_length)
|
|
302
|
+
for item in value
|
|
303
|
+
]
|
|
304
|
+
if all(isinstance(item, str) for item in rendered_items):
|
|
305
|
+
return "\n".join(rendered_items)
|
|
306
|
+
return Group(*rendered_items)
|
|
334
307
|
|
|
335
308
|
# Otherwise, return a string representation.
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
)
|
|
344
|
-
if isinstance(value, str) and "\n" in value:
|
|
345
|
-
return f"\n{s}\n"
|
|
346
|
-
return s
|
|
309
|
+
s = str(value).strip()
|
|
310
|
+
if max_length > 0 and len(s) > max_length:
|
|
311
|
+
omitted = len(s) - max_length
|
|
312
|
+
s = s[:max_length] + f"[bold bright_yellow]...(+{omitted}chars)[/bold bright_yellow]"
|
|
313
|
+
if isinstance(value, str) and "\n" in value:
|
|
314
|
+
return f"\n{s}\n"
|
|
315
|
+
return s
|
|
347
316
|
|
|
348
317
|
|
|
349
318
|
def load_syntax_theme_from_file(filepath: str) -> dict:
|
|
@@ -352,12 +321,10 @@ def load_syntax_theme_from_file(filepath: str) -> dict:
|
|
|
352
321
|
theme = toml.load(f)
|
|
353
322
|
|
|
354
323
|
if "colors" not in theme:
|
|
355
|
-
raise ValueError(
|
|
356
|
-
f"Theme file {filepath} does not contain a 'colors' section."
|
|
357
|
-
)
|
|
324
|
+
raise ValueError(f"Theme file {filepath} does not contain a 'colors' section.")
|
|
358
325
|
|
|
359
326
|
# Map theme colors to syntax categories
|
|
360
|
-
|
|
327
|
+
return {
|
|
361
328
|
"background": theme["colors"]["primary"].get("background", "#161719"),
|
|
362
329
|
"text": theme["colors"]["primary"].get("foreground", "#c5c8c6"),
|
|
363
330
|
"comment": theme["colors"]["normal"].get("black", "#666666"),
|
|
@@ -371,8 +338,6 @@ def load_syntax_theme_from_file(filepath: str) -> dict:
|
|
|
371
338
|
"error": theme["colors"]["bright"].get("red", "#ff5555"),
|
|
372
339
|
}
|
|
373
340
|
|
|
374
|
-
return syntax_theme
|
|
375
|
-
|
|
376
341
|
|
|
377
342
|
def create_rich_syntax_theme(syntax_theme: dict) -> Theme:
|
|
378
343
|
"""Convert a syntax theme dict to a Rich-compatible Theme."""
|
|
@@ -476,6 +441,7 @@ class ThemedAgentResultFormatter:
|
|
|
476
441
|
table = Table(**table_kwargs)
|
|
477
442
|
table.add_column("Output", style=styles["column_output"])
|
|
478
443
|
table.add_column("Value", style=styles["column_value"])
|
|
444
|
+
|
|
479
445
|
for key, value in result.items():
|
|
480
446
|
rich_renderable = create_rich_renderable(
|
|
481
447
|
value,
|
|
@@ -497,58 +463,46 @@ class ThemedAgentResultFormatter:
|
|
|
497
463
|
padding=styles["panel_padding"],
|
|
498
464
|
style=styles["panel_style"],
|
|
499
465
|
)
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
)
|
|
466
|
+
syntax = Syntax(
|
|
467
|
+
s, # The formatted string
|
|
468
|
+
"python", # Highlight as Python (change this for other formats)
|
|
469
|
+
theme=self.syntax_style, # Choose a Rich theme (matches your color setup)
|
|
470
|
+
line_numbers=False,
|
|
471
|
+
)
|
|
472
|
+
return Panel(
|
|
473
|
+
syntax,
|
|
474
|
+
title=agent_name,
|
|
475
|
+
title_align=styles["panel_title_align"],
|
|
476
|
+
border_style=styles["panel_border_style"],
|
|
477
|
+
padding=styles["panel_padding"],
|
|
478
|
+
style=styles["panel_style"],
|
|
479
|
+
)
|
|
515
480
|
|
|
516
|
-
def display_result(self, result:
|
|
481
|
+
def display_result(self, result: list[BaseModel], agent_name: str) -> None:
|
|
517
482
|
"""Print an agent's result using Rich formatting."""
|
|
518
483
|
theme = self.theme
|
|
519
|
-
themes_dir = (
|
|
520
|
-
pathlib.Path(__file__).parent.parent.parent.parent / "themes"
|
|
521
|
-
)
|
|
484
|
+
themes_dir = pathlib.Path(__file__).parent.parent.parent / "themes"
|
|
522
485
|
all_themes = list(themes_dir.glob("*.toml"))
|
|
523
|
-
theme = (
|
|
524
|
-
|
|
525
|
-
if not theme.value.endswith(".toml")
|
|
526
|
-
else theme.value
|
|
527
|
-
)
|
|
528
|
-
theme = (
|
|
529
|
-
pathlib.Path(__file__).parent.parent.parent.parent
|
|
530
|
-
/ "themes"
|
|
531
|
-
/ theme
|
|
532
|
-
)
|
|
486
|
+
theme = theme.value + ".toml" if not theme.value.endswith(".toml") else theme.value
|
|
487
|
+
theme = pathlib.Path(__file__).parent.parent.parent / "themes" / theme
|
|
533
488
|
|
|
534
489
|
if pathlib.Path(theme) not in all_themes:
|
|
535
|
-
raise ValueError(
|
|
536
|
-
f"Invalid theme: {theme}\nAvailable themes: {all_themes}"
|
|
537
|
-
)
|
|
490
|
+
raise ValueError(f"Invalid theme: {theme}\nAvailable themes: {all_themes}")
|
|
538
491
|
|
|
539
492
|
theme_dict = load_theme_from_file(theme)
|
|
540
493
|
|
|
541
494
|
styles = get_default_styles(theme_dict)
|
|
542
495
|
self.styles = styles
|
|
543
|
-
self.syntax_style = create_pygments_syntax_theme(
|
|
544
|
-
load_syntax_theme_from_file(theme)
|
|
545
|
-
)
|
|
496
|
+
self.syntax_style = create_pygments_syntax_theme(load_syntax_theme_from_file(theme))
|
|
546
497
|
|
|
547
498
|
console = Console()
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
499
|
+
for item in result:
|
|
500
|
+
# basemodel to dict
|
|
501
|
+
item = item.model_dump()
|
|
502
|
+
panel = self.format_result(
|
|
503
|
+
result=item,
|
|
504
|
+
agent_name=agent_name,
|
|
505
|
+
theme=theme_dict,
|
|
506
|
+
styles=styles,
|
|
507
|
+
)
|
|
508
|
+
console.print(panel)
|