flock-core 0.5.0b28__py3-none-any.whl → 0.5.0b51__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/frontend/README.md +678 -0
- flock/frontend/docs/DESIGN_SYSTEM.md +1980 -0
- flock/frontend/index.html +12 -0
- flock/frontend/package-lock.json +4347 -0
- flock/frontend/package.json +48 -0
- flock/frontend/src/App.tsx +79 -0
- flock/frontend/src/__tests__/e2e/critical-scenarios.test.tsx +587 -0
- flock/frontend/src/__tests__/integration/filtering-e2e.test.tsx +387 -0
- flock/frontend/src/__tests__/integration/graph-rendering.test.tsx +640 -0
- flock/frontend/src/__tests__/integration/indexeddb-persistence.test.tsx +699 -0
- flock/frontend/src/components/common/BuildInfo.tsx +39 -0
- flock/frontend/src/components/common/EmptyState.module.css +115 -0
- flock/frontend/src/components/common/EmptyState.tsx +128 -0
- flock/frontend/src/components/common/ErrorBoundary.module.css +169 -0
- flock/frontend/src/components/common/ErrorBoundary.tsx +118 -0
- flock/frontend/src/components/common/KeyboardShortcutsDialog.css +251 -0
- flock/frontend/src/components/common/KeyboardShortcutsDialog.tsx +151 -0
- flock/frontend/src/components/common/LoadingSpinner.module.css +97 -0
- flock/frontend/src/components/common/LoadingSpinner.tsx +29 -0
- flock/frontend/src/components/controls/PublishControl.css +547 -0
- flock/frontend/src/components/controls/PublishControl.test.tsx +543 -0
- flock/frontend/src/components/controls/PublishControl.tsx +432 -0
- flock/frontend/src/components/details/DetailWindowContainer.tsx +62 -0
- flock/frontend/src/components/details/LiveOutputTab.test.tsx +792 -0
- flock/frontend/src/components/details/LiveOutputTab.tsx +220 -0
- flock/frontend/src/components/details/MessageHistoryTab.tsx +299 -0
- flock/frontend/src/components/details/NodeDetailWindow.test.tsx +501 -0
- flock/frontend/src/components/details/NodeDetailWindow.tsx +218 -0
- flock/frontend/src/components/details/RunStatusTab.tsx +307 -0
- flock/frontend/src/components/details/tabs.test.tsx +1015 -0
- flock/frontend/src/components/filters/CorrelationIDFilter.module.css +102 -0
- flock/frontend/src/components/filters/CorrelationIDFilter.test.tsx +197 -0
- flock/frontend/src/components/filters/CorrelationIDFilter.tsx +121 -0
- flock/frontend/src/components/filters/FilterBar.module.css +29 -0
- flock/frontend/src/components/filters/FilterBar.test.tsx +133 -0
- flock/frontend/src/components/filters/FilterBar.tsx +33 -0
- flock/frontend/src/components/filters/FilterPills.module.css +79 -0
- flock/frontend/src/components/filters/FilterPills.test.tsx +173 -0
- flock/frontend/src/components/filters/FilterPills.tsx +67 -0
- flock/frontend/src/components/filters/TimeRangeFilter.module.css +91 -0
- flock/frontend/src/components/filters/TimeRangeFilter.test.tsx +154 -0
- flock/frontend/src/components/filters/TimeRangeFilter.tsx +105 -0
- flock/frontend/src/components/graph/AgentNode.test.tsx +75 -0
- flock/frontend/src/components/graph/AgentNode.tsx +322 -0
- flock/frontend/src/components/graph/GraphCanvas.tsx +406 -0
- flock/frontend/src/components/graph/MessageFlowEdge.tsx +128 -0
- flock/frontend/src/components/graph/MessageNode.test.tsx +62 -0
- flock/frontend/src/components/graph/MessageNode.tsx +116 -0
- flock/frontend/src/components/graph/MiniMap.tsx +47 -0
- flock/frontend/src/components/graph/TransformEdge.tsx +123 -0
- flock/frontend/src/components/layout/DashboardLayout.css +407 -0
- flock/frontend/src/components/layout/DashboardLayout.tsx +300 -0
- flock/frontend/src/components/layout/Header.module.css +88 -0
- flock/frontend/src/components/layout/Header.tsx +52 -0
- flock/frontend/src/components/modules/EventLogModule.test.tsx +401 -0
- flock/frontend/src/components/modules/EventLogModule.tsx +396 -0
- flock/frontend/src/components/modules/EventLogModuleWrapper.tsx +17 -0
- flock/frontend/src/components/modules/ModuleRegistry.test.ts +333 -0
- flock/frontend/src/components/modules/ModuleRegistry.ts +85 -0
- flock/frontend/src/components/modules/ModuleWindow.tsx +155 -0
- flock/frontend/src/components/modules/registerModules.ts +20 -0
- flock/frontend/src/components/settings/AdvancedSettings.tsx +175 -0
- flock/frontend/src/components/settings/AppearanceSettings.tsx +185 -0
- flock/frontend/src/components/settings/GraphSettings.tsx +110 -0
- flock/frontend/src/components/settings/SettingsPanel.css +327 -0
- flock/frontend/src/components/settings/SettingsPanel.tsx +131 -0
- flock/frontend/src/components/settings/ThemeSelector.tsx +298 -0
- flock/frontend/src/hooks/useKeyboardShortcuts.ts +148 -0
- flock/frontend/src/hooks/useModulePersistence.test.ts +442 -0
- flock/frontend/src/hooks/useModulePersistence.ts +154 -0
- flock/frontend/src/hooks/useModules.ts +139 -0
- flock/frontend/src/hooks/usePersistence.ts +139 -0
- flock/frontend/src/main.tsx +13 -0
- flock/frontend/src/services/api.ts +213 -0
- flock/frontend/src/services/indexeddb.test.ts +793 -0
- flock/frontend/src/services/indexeddb.ts +794 -0
- flock/frontend/src/services/layout.test.ts +437 -0
- flock/frontend/src/services/layout.ts +146 -0
- flock/frontend/src/services/themeApplicator.ts +140 -0
- flock/frontend/src/services/themeService.ts +77 -0
- flock/frontend/src/services/websocket.test.ts +595 -0
- flock/frontend/src/services/websocket.ts +685 -0
- flock/frontend/src/store/filterStore.test.ts +242 -0
- flock/frontend/src/store/filterStore.ts +103 -0
- flock/frontend/src/store/graphStore.test.ts +186 -0
- flock/frontend/src/store/graphStore.ts +414 -0
- flock/frontend/src/store/moduleStore.test.ts +253 -0
- flock/frontend/src/store/moduleStore.ts +57 -0
- flock/frontend/src/store/settingsStore.ts +188 -0
- flock/frontend/src/store/streamStore.ts +68 -0
- flock/frontend/src/store/uiStore.test.ts +54 -0
- flock/frontend/src/store/uiStore.ts +110 -0
- flock/frontend/src/store/wsStore.ts +34 -0
- flock/frontend/src/styles/index.css +15 -0
- flock/frontend/src/styles/scrollbar.css +47 -0
- flock/frontend/src/styles/variables.css +488 -0
- flock/frontend/src/test/setup.ts +1 -0
- flock/frontend/src/types/filters.ts +14 -0
- flock/frontend/src/types/graph.ts +55 -0
- flock/frontend/src/types/modules.ts +7 -0
- flock/frontend/src/types/theme.ts +55 -0
- flock/frontend/src/utils/mockData.ts +85 -0
- flock/frontend/src/utils/performance.ts +16 -0
- flock/frontend/src/utils/transforms.test.ts +860 -0
- flock/frontend/src/utils/transforms.ts +323 -0
- flock/frontend/src/vite-env.d.ts +17 -0
- flock/frontend/tsconfig.json +27 -0
- flock/frontend/tsconfig.node.json +11 -0
- flock/frontend/vite.config.ts +25 -0
- flock/frontend/vitest.config.ts +11 -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.0b51.dist-info/METADATA +747 -0
- flock_core-0.5.0b51.dist-info/RECORD +508 -0
- flock_core-0.5.0b51.dist-info/entry_points.txt +2 -0
- {flock_core-0.5.0b28.dist-info → flock_core-0.5.0b51.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.0b51.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { Edge } from '@xyflow/react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Phase 4: Graph Visualization & Dual Views - Edge Derivation Algorithms
|
|
5
|
+
*
|
|
6
|
+
* Implements edge derivation logic as specified in DATA_MODEL.md:
|
|
7
|
+
* - deriveAgentViewEdges: Creates message flow edges between agents (producer → consumer)
|
|
8
|
+
* - deriveBlackboardViewEdges: Creates transformation edges between artifacts (consumed → produced)
|
|
9
|
+
*
|
|
10
|
+
* SPECIFICATION: docs/specs/003-real-time-dashboard/DATA_MODEL.md lines 770-853
|
|
11
|
+
* REFERENCE: docs/specs/003-real-time-dashboard/PLAN.md Phase 4
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Type definitions matching DATA_MODEL.md specification
|
|
15
|
+
export interface Artifact {
|
|
16
|
+
artifact_id: string;
|
|
17
|
+
artifact_type: string;
|
|
18
|
+
produced_by: string;
|
|
19
|
+
consumed_by: string[];
|
|
20
|
+
published_at: string; // ISO timestamp
|
|
21
|
+
payload: any;
|
|
22
|
+
correlation_id: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface Run {
|
|
26
|
+
run_id: string;
|
|
27
|
+
agent_name: string;
|
|
28
|
+
correlation_id: string; // Groups multiple agent runs together
|
|
29
|
+
status: 'active' | 'completed' | 'error';
|
|
30
|
+
consumed_artifacts: string[];
|
|
31
|
+
produced_artifacts: string[];
|
|
32
|
+
duration_ms?: number;
|
|
33
|
+
started_at?: string;
|
|
34
|
+
completed_at?: string;
|
|
35
|
+
metrics?: {
|
|
36
|
+
tokensUsed?: number;
|
|
37
|
+
costUsd?: number;
|
|
38
|
+
artifactsProduced?: number;
|
|
39
|
+
};
|
|
40
|
+
error_message?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface DashboardState {
|
|
44
|
+
artifacts: Map<string, Artifact>;
|
|
45
|
+
runs: Map<string, Run>;
|
|
46
|
+
consumptions: Map<string, string[]>; // Phase 11: Track actual consumption (artifact_id -> consumer_ids[])
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Edge type definitions from DATA_MODEL.md
|
|
50
|
+
// Note: Using camelCase for TypeScript/JavaScript convention
|
|
51
|
+
export interface AgentViewEdge extends Edge {
|
|
52
|
+
type: 'message_flow';
|
|
53
|
+
label: string; // Format: "messageType (count)"
|
|
54
|
+
data: {
|
|
55
|
+
messageType: string;
|
|
56
|
+
messageCount: number;
|
|
57
|
+
artifactIds: string[];
|
|
58
|
+
latestTimestamp: string;
|
|
59
|
+
labelOffset?: number; // Phase 11: Vertical offset in pixels to prevent label overlap
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface BlackboardViewEdge extends Edge {
|
|
64
|
+
type: 'transformation';
|
|
65
|
+
label: string; // agentName
|
|
66
|
+
data: {
|
|
67
|
+
transformerAgent: string;
|
|
68
|
+
runId: string;
|
|
69
|
+
durationMs?: number;
|
|
70
|
+
labelOffset?: number; // Phase 11: Vertical offset in pixels to prevent label overlap
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Derive Agent View edges from dashboard state
|
|
76
|
+
*
|
|
77
|
+
* Algorithm (DATA_MODEL.md lines 770-821):
|
|
78
|
+
* 1. Group messages by (producer, consumer, message_type)
|
|
79
|
+
* 2. Create one edge per unique triple
|
|
80
|
+
* 3. Count artifacts in each group
|
|
81
|
+
* 4. Track latest timestamp
|
|
82
|
+
* 5. Add label offset for multiple edges between same nodes (Phase 11 bug fix)
|
|
83
|
+
*
|
|
84
|
+
* Edge format:
|
|
85
|
+
* - ID: `${producer}_${consumer}_${message_type}`
|
|
86
|
+
* - Type: 'message_flow'
|
|
87
|
+
* - Label: "Type (N)" where N is the count
|
|
88
|
+
* - Data: { message_type, message_count, artifact_ids[], latest_timestamp, labelOffset }
|
|
89
|
+
*
|
|
90
|
+
* @param state - Dashboard state with artifacts and runs
|
|
91
|
+
* @returns Array of message flow edges
|
|
92
|
+
*/
|
|
93
|
+
export function deriveAgentViewEdges(state: DashboardState): AgentViewEdge[] {
|
|
94
|
+
const edgeMap = new Map<
|
|
95
|
+
string,
|
|
96
|
+
{
|
|
97
|
+
source: string;
|
|
98
|
+
target: string;
|
|
99
|
+
message_type: string;
|
|
100
|
+
artifact_ids: string[];
|
|
101
|
+
latest_timestamp: string;
|
|
102
|
+
}
|
|
103
|
+
>();
|
|
104
|
+
|
|
105
|
+
// Iterate through all artifacts
|
|
106
|
+
state.artifacts.forEach((artifact) => {
|
|
107
|
+
const producer = artifact.produced_by;
|
|
108
|
+
const messageType = artifact.artifact_type;
|
|
109
|
+
|
|
110
|
+
// For each consumer, create or update edge
|
|
111
|
+
artifact.consumed_by.forEach((consumer) => {
|
|
112
|
+
const edgeKey = `${producer}_${consumer}_${messageType}`;
|
|
113
|
+
|
|
114
|
+
const existing = edgeMap.get(edgeKey);
|
|
115
|
+
|
|
116
|
+
if (existing) {
|
|
117
|
+
// Update existing edge
|
|
118
|
+
existing.artifact_ids.push(artifact.artifact_id);
|
|
119
|
+
|
|
120
|
+
// Update latest timestamp if this artifact is newer
|
|
121
|
+
if (artifact.published_at > existing.latest_timestamp) {
|
|
122
|
+
existing.latest_timestamp = artifact.published_at;
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
// Create new edge entry
|
|
126
|
+
edgeMap.set(edgeKey, {
|
|
127
|
+
source: producer,
|
|
128
|
+
target: consumer,
|
|
129
|
+
message_type: messageType,
|
|
130
|
+
artifact_ids: [artifact.artifact_id],
|
|
131
|
+
latest_timestamp: artifact.published_at,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Phase 11 Bug Fix: Calculate label offsets for edges between same node pairs
|
|
138
|
+
// Group edges by node pair to detect multiple edges
|
|
139
|
+
// Use canonical pair key (sorted) so A→B and B→A are treated as same pair
|
|
140
|
+
const nodePairEdges = new Map<string, string[]>();
|
|
141
|
+
edgeMap.forEach((data, edgeKey) => {
|
|
142
|
+
const nodes = [data.source, data.target].sort();
|
|
143
|
+
const pairKey = `${nodes[0]}_${nodes[1]}`;
|
|
144
|
+
const existing = nodePairEdges.get(pairKey) || [];
|
|
145
|
+
existing.push(edgeKey);
|
|
146
|
+
nodePairEdges.set(pairKey, existing);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Convert map to edges with label offsets
|
|
150
|
+
const edges: AgentViewEdge[] = [];
|
|
151
|
+
|
|
152
|
+
edgeMap.forEach((data, edgeKey) => {
|
|
153
|
+
const nodes = [data.source, data.target].sort();
|
|
154
|
+
const pairKey = `${nodes[0]}_${nodes[1]}`;
|
|
155
|
+
const edgesInPair = nodePairEdges.get(pairKey) || [];
|
|
156
|
+
const edgeIndex = edgesInPair.indexOf(edgeKey);
|
|
157
|
+
const totalEdgesInPair = edgesInPair.length;
|
|
158
|
+
|
|
159
|
+
// Calculate label offset (spread labels vertically if multiple edges)
|
|
160
|
+
// Offset range: -20 to +20 pixels for up to 3 edges, more if needed
|
|
161
|
+
let labelOffset = 0;
|
|
162
|
+
if (totalEdgesInPair > 1) {
|
|
163
|
+
const offsetRange = Math.min(40, totalEdgesInPair * 15);
|
|
164
|
+
const step = offsetRange / (totalEdgesInPair - 1);
|
|
165
|
+
labelOffset = edgeIndex * step - offsetRange / 2;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Phase 11 Bug Fix: Calculate filtered count from actual consumption data
|
|
169
|
+
// Count how many artifacts were actually consumed by the target agent
|
|
170
|
+
const totalCount = data.artifact_ids.length;
|
|
171
|
+
const consumedCount = data.artifact_ids.filter((artifactId) => {
|
|
172
|
+
const consumers = state.consumptions.get(artifactId) || [];
|
|
173
|
+
return consumers.includes(data.target);
|
|
174
|
+
}).length;
|
|
175
|
+
|
|
176
|
+
// Format label: "Type (total, filtered: consumed)" if filtering occurred
|
|
177
|
+
let label = `${data.message_type} (${totalCount})`;
|
|
178
|
+
if (consumedCount < totalCount && consumedCount > 0) {
|
|
179
|
+
label = `${data.message_type} (${totalCount}, filtered: ${consumedCount})`;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
edges.push({
|
|
183
|
+
id: edgeKey,
|
|
184
|
+
source: data.source,
|
|
185
|
+
target: data.target,
|
|
186
|
+
type: 'message_flow',
|
|
187
|
+
label,
|
|
188
|
+
markerEnd: {
|
|
189
|
+
type: 'arrowclosed',
|
|
190
|
+
width: 20,
|
|
191
|
+
height: 20,
|
|
192
|
+
},
|
|
193
|
+
data: {
|
|
194
|
+
messageType: data.message_type,
|
|
195
|
+
messageCount: data.artifact_ids.length,
|
|
196
|
+
artifactIds: data.artifact_ids,
|
|
197
|
+
latestTimestamp: data.latest_timestamp,
|
|
198
|
+
labelOffset, // Phase 11: Added for label positioning
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
return edges;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Derive Blackboard View edges from dashboard state
|
|
208
|
+
*
|
|
209
|
+
* Algorithm (DATA_MODEL.md lines 824-853):
|
|
210
|
+
* 1. For each completed run (status !== 'active')
|
|
211
|
+
* 2. Create edges from consumed artifacts to produced artifacts
|
|
212
|
+
* 3. Label with agent name
|
|
213
|
+
* 4. Include run metadata (run_id, duration_ms)
|
|
214
|
+
* 5. Add label offset for multiple edges between same artifacts (Phase 11 bug fix)
|
|
215
|
+
*
|
|
216
|
+
* Edge format:
|
|
217
|
+
* - ID: `${consumed_id}_${produced_id}_${run_id}` (Phase 11: Added run_id for uniqueness)
|
|
218
|
+
* - Type: 'transformation'
|
|
219
|
+
* - Label: agent_name
|
|
220
|
+
* - Data: { transformer_agent, run_id, duration_ms, labelOffset }
|
|
221
|
+
*
|
|
222
|
+
* @param state - Dashboard state with artifacts and runs
|
|
223
|
+
* @returns Array of transformation edges
|
|
224
|
+
*/
|
|
225
|
+
export function deriveBlackboardViewEdges(
|
|
226
|
+
state: DashboardState
|
|
227
|
+
): BlackboardViewEdge[] {
|
|
228
|
+
const tempEdges: Array<{
|
|
229
|
+
id: string;
|
|
230
|
+
source: string;
|
|
231
|
+
target: string;
|
|
232
|
+
label: string;
|
|
233
|
+
data: {
|
|
234
|
+
transformerAgent: string;
|
|
235
|
+
runId: string;
|
|
236
|
+
durationMs?: number;
|
|
237
|
+
};
|
|
238
|
+
}> = [];
|
|
239
|
+
|
|
240
|
+
// Iterate through all runs
|
|
241
|
+
state.runs.forEach((run) => {
|
|
242
|
+
// Skip active runs (only process completed or error runs)
|
|
243
|
+
if (run.status === 'active') {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Skip runs with no consumed or produced artifacts
|
|
248
|
+
if (
|
|
249
|
+
run.consumed_artifacts.length === 0 ||
|
|
250
|
+
run.produced_artifacts.length === 0
|
|
251
|
+
) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Create edges for each consumed × produced pair
|
|
256
|
+
run.consumed_artifacts.forEach((consumedId) => {
|
|
257
|
+
run.produced_artifacts.forEach((producedId) => {
|
|
258
|
+
// Phase 11: Include run_id in edge ID to make it unique per transformation
|
|
259
|
+
const edgeId = `${consumedId}_${producedId}_${run.run_id}`;
|
|
260
|
+
|
|
261
|
+
tempEdges.push({
|
|
262
|
+
id: edgeId,
|
|
263
|
+
source: consumedId,
|
|
264
|
+
target: producedId,
|
|
265
|
+
label: run.agent_name,
|
|
266
|
+
data: {
|
|
267
|
+
transformerAgent: run.agent_name,
|
|
268
|
+
runId: run.run_id,
|
|
269
|
+
durationMs: run.duration_ms,
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// Phase 11 Bug Fix: Calculate label offsets for edges between same artifact pairs
|
|
277
|
+
// Group edges by artifact pair to detect multiple transformations
|
|
278
|
+
// Use canonical pair key (sorted) so A→B and B→A are treated as same pair
|
|
279
|
+
const artifactPairEdges = new Map<string, string[]>();
|
|
280
|
+
tempEdges.forEach((edge) => {
|
|
281
|
+
const nodes = [edge.source, edge.target].sort();
|
|
282
|
+
const pairKey = `${nodes[0]}_${nodes[1]}`;
|
|
283
|
+
const existing = artifactPairEdges.get(pairKey) || [];
|
|
284
|
+
existing.push(edge.id);
|
|
285
|
+
artifactPairEdges.set(pairKey, existing);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// Convert to final edges with label offsets
|
|
289
|
+
const edges: BlackboardViewEdge[] = tempEdges.map((edge) => {
|
|
290
|
+
const nodes = [edge.source, edge.target].sort();
|
|
291
|
+
const pairKey = `${nodes[0]}_${nodes[1]}`;
|
|
292
|
+
const edgesInPair = artifactPairEdges.get(pairKey) || [];
|
|
293
|
+
const edgeIndex = edgesInPair.indexOf(edge.id);
|
|
294
|
+
const totalEdgesInPair = edgesInPair.length;
|
|
295
|
+
|
|
296
|
+
// Calculate label offset (spread labels vertically if multiple transformations)
|
|
297
|
+
let labelOffset = 0;
|
|
298
|
+
if (totalEdgesInPair > 1) {
|
|
299
|
+
const offsetRange = Math.min(40, totalEdgesInPair * 15);
|
|
300
|
+
const step = offsetRange / (totalEdgesInPair - 1);
|
|
301
|
+
labelOffset = edgeIndex * step - offsetRange / 2;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return {
|
|
305
|
+
id: edge.id,
|
|
306
|
+
source: edge.source,
|
|
307
|
+
target: edge.target,
|
|
308
|
+
type: 'transformation',
|
|
309
|
+
label: edge.label,
|
|
310
|
+
markerEnd: {
|
|
311
|
+
type: 'arrowclosed',
|
|
312
|
+
width: 20,
|
|
313
|
+
height: 20,
|
|
314
|
+
},
|
|
315
|
+
data: {
|
|
316
|
+
...edge.data,
|
|
317
|
+
labelOffset, // Phase 11: Added for label positioning
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
return edges;
|
|
323
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
|
+
|
|
3
|
+
interface ImportMetaEnv {
|
|
4
|
+
readonly VITE_WS_URL?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface ImportMeta {
|
|
8
|
+
readonly env: ImportMetaEnv;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare const __BUILD_TIMESTAMP__: string;
|
|
12
|
+
declare const __BUILD_HASH__: string;
|
|
13
|
+
|
|
14
|
+
declare module '*.module.css' {
|
|
15
|
+
const classes: { [key: string]: string };
|
|
16
|
+
export default classes;
|
|
17
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
"jsx": "react-jsx",
|
|
16
|
+
|
|
17
|
+
/* Linting */
|
|
18
|
+
"strict": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true,
|
|
22
|
+
"noUncheckedIndexedAccess": true,
|
|
23
|
+
"types": ["vitest/globals", "@testing-library/jest-dom"]
|
|
24
|
+
},
|
|
25
|
+
"include": ["src"],
|
|
26
|
+
"references": [{ "path": "./tsconfig.node.json" }]
|
|
27
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import react from '@vitejs/plugin-react';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
plugins: [react()],
|
|
6
|
+
define: {
|
|
7
|
+
__BUILD_TIMESTAMP__: JSON.stringify(new Date().toISOString()),
|
|
8
|
+
__BUILD_HASH__: JSON.stringify(
|
|
9
|
+
Date.now().toString(36) + Math.random().toString(36).substring(2, 9)
|
|
10
|
+
),
|
|
11
|
+
},
|
|
12
|
+
server: {
|
|
13
|
+
port: 5173,
|
|
14
|
+
proxy: {
|
|
15
|
+
'/api': {
|
|
16
|
+
target: 'http://localhost:8000',
|
|
17
|
+
changeOrigin: true,
|
|
18
|
+
},
|
|
19
|
+
'/ws': {
|
|
20
|
+
target: 'ws://localhost:8000',
|
|
21
|
+
ws: true,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
});
|
|
@@ -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]")
|