flock-core 0.4.542__py3-none-any.whl ā 0.5.0__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 +1079 -0
- flock/api/themes.py +71 -0
- flock/artifacts.py +86 -0
- flock/cli.py +147 -0
- flock/components.py +189 -0
- flock/dashboard/__init__.py +30 -0
- flock/dashboard/collector.py +559 -0
- flock/dashboard/events.py +188 -0
- flock/dashboard/graph_builder.py +563 -0
- flock/dashboard/launcher.py +235 -0
- flock/dashboard/models/graph.py +156 -0
- flock/dashboard/service.py +991 -0
- flock/dashboard/static_v2/assets/index-DFRnI_mt.js +111 -0
- flock/dashboard/static_v2/assets/index-fPLNdmp1.css +1 -0
- flock/dashboard/static_v2/index.html +13 -0
- flock/dashboard/websocket.py +246 -0
- flock/engines/__init__.py +6 -0
- flock/engines/dspy_engine.py +932 -0
- flock/examples.py +131 -0
- flock/frontend/README.md +778 -0
- flock/frontend/docs/DESIGN_SYSTEM.md +1980 -0
- flock/frontend/index.html +12 -0
- flock/frontend/package-lock.json +4337 -0
- flock/frontend/package.json +48 -0
- flock/frontend/src/App.tsx +139 -0
- flock/frontend/src/__tests__/integration/graph-snapshot.test.tsx +647 -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 +58 -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/MessageDetailWindow.tsx +439 -0
- flock/frontend/src/components/details/MessageHistoryTab.tsx +374 -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 +348 -0
- flock/frontend/src/components/details/tabs.test.tsx +1015 -0
- flock/frontend/src/components/filters/ArtifactTypeFilter.tsx +21 -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/FilterFlyout.module.css +104 -0
- flock/frontend/src/components/filters/FilterFlyout.tsx +80 -0
- flock/frontend/src/components/filters/FilterPills.module.css +220 -0
- flock/frontend/src/components/filters/FilterPills.test.tsx +189 -0
- flock/frontend/src/components/filters/FilterPills.tsx +143 -0
- flock/frontend/src/components/filters/ProducerFilter.tsx +21 -0
- flock/frontend/src/components/filters/SavedFiltersControl.module.css +60 -0
- flock/frontend/src/components/filters/SavedFiltersControl.test.tsx +158 -0
- flock/frontend/src/components/filters/SavedFiltersControl.tsx +159 -0
- flock/frontend/src/components/filters/TagFilter.tsx +21 -0
- flock/frontend/src/components/filters/TimeRangeFilter.module.css +115 -0
- flock/frontend/src/components/filters/TimeRangeFilter.test.tsx +154 -0
- flock/frontend/src/components/filters/TimeRangeFilter.tsx +110 -0
- flock/frontend/src/components/filters/VisibilityFilter.tsx +21 -0
- flock/frontend/src/components/graph/AgentNode.test.tsx +77 -0
- flock/frontend/src/components/graph/AgentNode.tsx +324 -0
- flock/frontend/src/components/graph/GraphCanvas.tsx +613 -0
- flock/frontend/src/components/graph/MessageFlowEdge.tsx +128 -0
- flock/frontend/src/components/graph/MessageNode.test.tsx +64 -0
- flock/frontend/src/components/graph/MessageNode.tsx +129 -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 +420 -0
- flock/frontend/src/components/layout/DashboardLayout.tsx +287 -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/HistoricalArtifactsModule.module.css +288 -0
- flock/frontend/src/components/modules/HistoricalArtifactsModule.tsx +450 -0
- flock/frontend/src/components/modules/HistoricalArtifactsModuleWrapper.tsx +13 -0
- flock/frontend/src/components/modules/JsonAttributeRenderer.tsx +140 -0
- flock/frontend/src/components/modules/ModuleRegistry.test.ts +333 -0
- flock/frontend/src/components/modules/ModuleRegistry.ts +93 -0
- flock/frontend/src/components/modules/ModuleWindow.tsx +223 -0
- flock/frontend/src/components/modules/TraceModuleJaeger.tsx +1971 -0
- flock/frontend/src/components/modules/TraceModuleJaegerWrapper.tsx +13 -0
- flock/frontend/src/components/modules/registerModules.ts +29 -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/MultiSelect.tsx +235 -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/components/settings/TracingSettings.tsx +404 -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 +157 -0
- flock/frontend/src/hooks/usePersistence.ts +141 -0
- flock/frontend/src/main.tsx +13 -0
- flock/frontend/src/services/api.ts +337 -0
- flock/frontend/src/services/graphService.test.ts +330 -0
- flock/frontend/src/services/graphService.ts +75 -0
- flock/frontend/src/services/indexeddb.test.ts +793 -0
- flock/frontend/src/services/indexeddb.ts +848 -0
- flock/frontend/src/services/layout.test.ts +437 -0
- flock/frontend/src/services/layout.ts +357 -0
- flock/frontend/src/services/themeApplicator.ts +140 -0
- flock/frontend/src/services/themeService.ts +77 -0
- flock/frontend/src/services/websocket.ts +650 -0
- flock/frontend/src/store/filterStore.test.ts +250 -0
- flock/frontend/src/store/filterStore.ts +272 -0
- flock/frontend/src/store/graphStore.test.ts +570 -0
- flock/frontend/src/store/graphStore.ts +462 -0
- flock/frontend/src/store/moduleStore.test.ts +253 -0
- flock/frontend/src/store/moduleStore.ts +75 -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 +122 -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 +47 -0
- flock/frontend/src/types/graph.ts +95 -0
- flock/frontend/src/types/modules.ts +10 -0
- flock/frontend/src/types/theme.ts +55 -0
- flock/frontend/src/utils/artifacts.ts +24 -0
- flock/frontend/src/utils/mockData.ts +98 -0
- flock/frontend/src/utils/performance.ts +16 -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 +9 -5
- flock/{core/logging ā logging}/__init__.py +2 -3
- flock/logging/auto_trace.py +159 -0
- 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 -107
- flock/{core/logging ā logging}/logging.py +78 -61
- flock/{core/logging ā logging}/telemetry.py +66 -26
- flock/{core/logging ā logging}/telemetry_exporter/base_exporter.py +2 -2
- flock/logging/telemetry_exporter/duckdb_exporter.py +216 -0
- flock/{core/logging ā logging}/telemetry_exporter/file_exporter.py +13 -10
- flock/{core/logging ā logging}/telemetry_exporter/sqlite_exporter.py +2 -3
- flock/logging/trace_and_logged.py +304 -0
- flock/mcp/__init__.py +91 -0
- flock/{core/mcp/mcp_client.py ā mcp/client.py} +131 -158
- flock/{core/mcp/mcp_config.py ā mcp/config.py} +86 -132
- flock/mcp/manager.py +286 -0
- flock/mcp/servers/sse/__init__.py +1 -1
- flock/mcp/servers/sse/flock_sse_server.py +16 -58
- flock/mcp/servers/stdio/__init__.py +1 -1
- flock/mcp/servers/stdio/flock_stdio_server.py +13 -53
- flock/mcp/servers/streamable_http/flock_streamable_http_server.py +22 -67
- flock/mcp/servers/websockets/flock_websocket_server.py +12 -45
- flock/{core/mcp/flock_mcp_tool_base.py ā mcp/tool.py} +24 -78
- flock/mcp/types/__init__.py +42 -0
- flock/{core/mcp ā mcp}/types/callbacks.py +12 -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 +3 -3
- flock/orchestrator.py +970 -0
- flock/registry.py +148 -0
- flock/runtime.py +262 -0
- flock/service.py +277 -0
- flock/store.py +1214 -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/darkmatrix.toml +2 -2
- flock/themes/darkside.toml +1 -1
- flock/themes/deep.toml +2 -2
- 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 +5 -5
- 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/utility/output_utility_component.py +226 -0
- flock/visibility.py +107 -0
- flock_core-0.5.0.dist-info/METADATA +964 -0
- flock_core-0.5.0.dist-info/RECORD +525 -0
- flock_core-0.5.0.dist-info/entry_points.txt +2 -0
- {flock_core-0.4.542.dist-info ā flock_core-0.5.0.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/config.py +0 -56
- flock/core/__init__.py +0 -44
- flock/core/api/__init__.py +0 -10
- flock/core/api/custom_endpoint.py +0 -45
- flock/core/api/endpoints.py +0 -262
- flock/core/api/main.py +0 -162
- flock/core/api/models.py +0 -101
- flock/core/api/run_store.py +0 -224
- flock/core/api/runner.py +0 -44
- flock/core/api/service.py +0 -214
- flock/core/config/flock_agent_config.py +0 -11
- flock/core/config/scheduled_agent_config.py +0 -40
- flock/core/context/context.py +0 -214
- flock/core/context/context_manager.py +0 -40
- flock/core/context/context_vars.py +0 -11
- flock/core/evaluation/utils.py +0 -395
- 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 -166
- flock/core/flock.py +0 -1003
- flock/core/flock_agent.py +0 -1258
- flock/core/flock_evaluator.py +0 -60
- flock/core/flock_factory.py +0 -513
- flock/core/flock_module.py +0 -207
- flock/core/flock_registry.py +0 -702
- flock/core/flock_router.py +0 -83
- 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/logging/live_capture.py +0 -137
- flock/core/logging/trace_and_logged.py +0 -59
- flock/core/mcp/__init__.py +0 -1
- flock/core/mcp/flock_mcp_server.py +0 -640
- flock/core/mcp/mcp_client_manager.py +0 -201
- flock/core/mcp/types/__init__.py +0 -1
- flock/core/mixin/dspy_integration.py +0 -445
- flock/core/mixin/prompt_parser.py +0 -125
- flock/core/serialization/__init__.py +0 -13
- flock/core/serialization/callable_registry.py +0 -52
- flock/core/serialization/flock_serializer.py +0 -854
- 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 -409
- flock/core/util/file_path_utils.py +0 -223
- flock/core/util/hydrator.py +0 -309
- flock/core/util/input_resolver.py +0 -141
- flock/core/util/loader.py +0 -59
- flock/core/util/splitter.py +0 -219
- flock/di.py +0 -41
- flock/evaluators/__init__.py +0 -1
- flock/evaluators/declarative/__init__.py +0 -1
- flock/evaluators/declarative/declarative_evaluator.py +0 -217
- flock/evaluators/memory/memory_evaluator.py +0 -90
- flock/evaluators/test/test_case_evaluator.py +0 -38
- flock/evaluators/zep/zep_evaluator.py +0 -59
- flock/modules/__init__.py +0 -1
- flock/modules/assertion/__init__.py +0 -1
- flock/modules/assertion/assertion_module.py +0 -286
- flock/modules/callback/__init__.py +0 -1
- flock/modules/callback/callback_module.py +0 -91
- flock/modules/enterprise_memory/README.md +0 -99
- flock/modules/enterprise_memory/enterprise_memory_module.py +0 -526
- flock/modules/mem0/__init__.py +0 -1
- flock/modules/mem0/mem0_module.py +0 -126
- flock/modules/mem0_async/__init__.py +0 -1
- flock/modules/mem0_async/async_mem0_module.py +0 -126
- flock/modules/memory/__init__.py +0 -1
- flock/modules/memory/memory_module.py +0 -429
- flock/modules/memory/memory_parser.py +0 -125
- flock/modules/memory/memory_storage.py +0 -736
- flock/modules/output/__init__.py +0 -1
- flock/modules/output/output_module.py +0 -196
- flock/modules/performance/__init__.py +0 -1
- flock/modules/performance/metrics_module.py +0 -678
- flock/modules/zep/__init__.py +0 -1
- flock/modules/zep/zep_module.py +0 -192
- flock/platform/docker_tools.py +0 -49
- flock/platform/jaeger_install.py +0 -86
- flock/routers/__init__.py +0 -1
- flock/routers/agent/__init__.py +0 -1
- flock/routers/agent/agent_router.py +0 -236
- flock/routers/agent/handoff_agent.py +0 -58
- flock/routers/conditional/conditional_router.py +0 -486
- flock/routers/default/__init__.py +0 -1
- flock/routers/default/default_router.py +0 -80
- flock/routers/feedback/feedback_router.py +0 -114
- flock/routers/list_generator/list_generator_router.py +0 -166
- flock/routers/llm/__init__.py +0 -1
- flock/routers/llm/llm_router.py +0 -365
- flock/tools/__init__.py +0 -0
- flock/tools/azure_tools.py +0 -781
- flock/tools/code_tools.py +0 -167
- flock/tools/file_tools.py +0 -149
- flock/tools/github_tools.py +0 -157
- flock/tools/markdown_tools.py +0 -205
- flock/tools/system_tools.py +0 -9
- flock/tools/text_tools.py +0 -810
- flock/tools/web_tools.py +0 -92
- flock/tools/zendesk_tools.py +0 -501
- 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 -237
- flock/webapp/app/api/execution.py +0 -503
- flock/webapp/app/api/flock_management.py +0 -125
- flock/webapp/app/api/registry_viewer.py +0 -29
- flock/webapp/app/chat.py +0 -662
- flock/webapp/app/config.py +0 -104
- flock/webapp/app/dependencies.py +0 -117
- flock/webapp/app/main.py +0 -1086
- 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 -345
- flock/webapp/app/services/sharing_models.py +0 -81
- flock/webapp/app/services/sharing_store.py +0 -597
- flock/webapp/app/templates/theme_mapper.html +0 -326
- flock/webapp/app/theme_mapper.py +0 -811
- flock/webapp/app/utils.py +0 -85
- flock/webapp/run.py +0 -219
- 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 -281
- flock/webapp/static/css/sidebar.css +0 -127
- flock/webapp/static/css/two-pane.css +0 -48
- flock/webapp/templates/base.html +0 -389
- 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 -127
- 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/_live_logs.html +0 -13
- 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/_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 -237
- flock/workflow/agent_activities.py +0 -24
- flock/workflow/agent_execution_activity.py +0 -240
- flock/workflow/flock_workflow.py +0 -225
- flock/workflow/temporal_config.py +0 -96
- flock/workflow/temporal_setup.py +0 -60
- flock_core-0.4.542.dist-info/METADATA +0 -676
- flock_core-0.4.542.dist-info/RECORD +0 -572
- flock_core-0.4.542.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.4.542.dist-info ā flock_core-0.5.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,964 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: flock-core
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: Add your description here
|
|
5
|
+
Author-email: Andre Ratzenberger <andre.ratzenberger@whiteduck.de>
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Requires-Dist: aiosqlite>=0.20.0
|
|
9
|
+
Requires-Dist: devtools>=0.12.2
|
|
10
|
+
Requires-Dist: dspy==3.0.0
|
|
11
|
+
Requires-Dist: duckdb>=1.1.0
|
|
12
|
+
Requires-Dist: fastapi>=0.117.1
|
|
13
|
+
Requires-Dist: hanging-threads>=2.0.7
|
|
14
|
+
Requires-Dist: httpx>=0.28.1
|
|
15
|
+
Requires-Dist: litellm==1.75.3
|
|
16
|
+
Requires-Dist: loguru>=0.7.3
|
|
17
|
+
Requires-Dist: mcp>=1.7.1
|
|
18
|
+
Requires-Dist: opentelemetry-api>=1.30.0
|
|
19
|
+
Requires-Dist: opentelemetry-exporter-jaeger-proto-grpc>=1.21.0
|
|
20
|
+
Requires-Dist: opentelemetry-exporter-jaeger>=1.21.0
|
|
21
|
+
Requires-Dist: opentelemetry-exporter-otlp>=1.30.0
|
|
22
|
+
Requires-Dist: opentelemetry-instrumentation-logging>=0.51b0
|
|
23
|
+
Requires-Dist: opentelemetry-sdk>=1.30.0
|
|
24
|
+
Requires-Dist: poethepoet>=0.30.0
|
|
25
|
+
Requires-Dist: pydantic[email]>=2.11.9
|
|
26
|
+
Requires-Dist: rich>=14.1.0
|
|
27
|
+
Requires-Dist: toml>=0.10.2
|
|
28
|
+
Requires-Dist: typer>=0.19.2
|
|
29
|
+
Requires-Dist: uvicorn>=0.37.0
|
|
30
|
+
Requires-Dist: websockets>=15.0.1
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<img alt="Flock Banner" src="https://raw.githubusercontent.com/whiteducksoftware/flock/master/docs/assets/images/flock.png" width="800">
|
|
35
|
+
</p>
|
|
36
|
+
<p align="center">
|
|
37
|
+
<a href="https://docs.flock.whiteduck.de" target="_blank"><img alt="Documentation" src="https://img.shields.io/badge/docs-online-blue?style=for-the-badge&logo=readthedocs"></a>
|
|
38
|
+
<a href="https://pypi.org/project/flock-core/" target="_blank"><img alt="PyPI Version" src="https://img.shields.io/pypi/v/flock-core?style=for-the-badge&logo=pypi&label=pip%20version"></a>
|
|
39
|
+
<img alt="Python Version" src="https://img.shields.io/badge/python-3.10%2B-blue?style=for-the-badge&logo=python">
|
|
40
|
+
<a href="LICENSE" target="_blank"><img alt="License" src="https://img.shields.io/pypi/l/flock-core?style=for-the-badge"></a>
|
|
41
|
+
<a href="https://whiteduck.de" target="_blank"><img alt="Built by white duck" src="https://img.shields.io/badge/Built%20by-white%20duck%20GmbH-white?style=for-the-badge&labelColor=black"></a>
|
|
42
|
+
<img alt="Test Coverage" src="https://img.shields.io/badge/coverage-77%25-green?style=for-the-badge">
|
|
43
|
+
<img alt="Tests" src="https://img.shields.io/badge/tests-743%20passing-brightgreen?style=for-the-badge">
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
# Flock 0.5: Declarative Blackboard Multi-Agent Orchestration
|
|
49
|
+
|
|
50
|
+
> **Stop engineering prompts. Start declaring contracts.**
|
|
51
|
+
|
|
52
|
+
Flock is a production-focused framework for orchestrating AI agents through **declarative type contracts** and **blackboard architecture**āproven patterns from distributed systems, decades of experience with microservice architectures, and classical AIānow applied to modern LLMs.
|
|
53
|
+
|
|
54
|
+
**š [Read the full documentation ā](https://docs.flock.whiteduck.de)**
|
|
55
|
+
|
|
56
|
+
**Quick links:**
|
|
57
|
+
- **[Getting Started](https://docs.flock.whiteduck.de/getting-started/installation/)** - Installation and first steps
|
|
58
|
+
- **[Tutorials](https://docs.flock.whiteduck.de/tutorials/)** - Step-by-step learning path
|
|
59
|
+
- **[User Guides](https://docs.flock.whiteduck.de/guides/)** - In-depth feature documentation
|
|
60
|
+
- **[API Reference](https://docs.flock.whiteduck.de/reference/api/)** - Complete API documentation
|
|
61
|
+
- **[Roadmap](https://docs.flock.whiteduck.de/about/roadmap/)** - What's coming in v1.0
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## The Problem With Current Approaches
|
|
66
|
+
|
|
67
|
+
Building production multi-agent systems today means dealing with:
|
|
68
|
+
|
|
69
|
+
**š„ Prompt Engineering Hell**
|
|
70
|
+
```python
|
|
71
|
+
|
|
72
|
+
prompt = """You are an expert code reviewer. When you receive code, you should...
|
|
73
|
+
[498 more lines of instructions that the LLM ignores half the time]"""
|
|
74
|
+
|
|
75
|
+
# 500-line prompt that breaks when models update
|
|
76
|
+
|
|
77
|
+
# How do I know that there isn't an even better prompt? (you don't)
|
|
78
|
+
# -> proving 'best possible performance' is impossible
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**š§Ŗ Testing Nightmares**
|
|
82
|
+
```python
|
|
83
|
+
# How do you unit test this?
|
|
84
|
+
result = llm.invoke(prompt) # Hope for valid JSON
|
|
85
|
+
data = json.loads(result.content) # Crashes in production
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**š Rigid topology and tight coupling**
|
|
89
|
+
```python
|
|
90
|
+
# Want to add a new agent? Rewrite the entire graph.
|
|
91
|
+
workflow.add_edge("agent_a", "agent_b")
|
|
92
|
+
workflow.add_edge("agent_b", "agent_c")
|
|
93
|
+
# Add agent_d? Start rewiring...
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**š Single point of failure: Orchestrator dies? Everything dies.**
|
|
97
|
+
```python
|
|
98
|
+
# Orchestrator dies? Everything dies.
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**š§ God object anti-pattern:**
|
|
102
|
+
```python
|
|
103
|
+
# One orchestrator needs domain knowledge of 20+ agents to route correctly
|
|
104
|
+
# Orchestrator 'guesses' next agent based on a natural language description.
|
|
105
|
+
# Not suitable for critical systems.
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
These aren't framework limitations, they're **architectural choices** that don't scale.
|
|
109
|
+
|
|
110
|
+
These challenges are solvableādecades of experience with microservices have taught us hard lessons about decoupling, orchestration, and reliability. Let's apply those lessons!
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## The Flock Approach
|
|
115
|
+
|
|
116
|
+
Flock takes a different path, combining two proven patterns:
|
|
117
|
+
|
|
118
|
+
### 1. Declarative Type Contracts (Not Prompts)
|
|
119
|
+
|
|
120
|
+
**Traditional approach:**
|
|
121
|
+
```python
|
|
122
|
+
prompt = """You are an expert software engineer and bug analyst. Your task is to analyze bug reports and provide structured diagnostic information.
|
|
123
|
+
|
|
124
|
+
INSTRUCTIONS:
|
|
125
|
+
1. Read the bug report carefully
|
|
126
|
+
2. Determine the severity level (must be exactly one of: Critical, High, Medium, Low)
|
|
127
|
+
3. Classify the bug category (e.g., "performance", "security", "UI", "data corruption")
|
|
128
|
+
4. Formulate a root cause hypothesis (minimum 50 characters)
|
|
129
|
+
5. Assign a confidence score between 0.0 and 1.0
|
|
130
|
+
|
|
131
|
+
OUTPUT FORMAT:
|
|
132
|
+
You MUST return valid JSON with this exact structure:
|
|
133
|
+
{
|
|
134
|
+
"severity": "string (Critical|High|Medium|Low)",
|
|
135
|
+
"category": "string",
|
|
136
|
+
"root_cause_hypothesis": "string (minimum 50 characters)",
|
|
137
|
+
"confidence_score": "number (0.0 to 1.0)"
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
VALIDATION RULES:
|
|
141
|
+
- severity: Must be exactly one of: Critical, High, Medium, Low (case-sensitive)
|
|
142
|
+
- category: Must be a single word or short phrase describing the bug type
|
|
143
|
+
- root_cause_hypothesis: Must be at least 50 characters long and explain the likely cause
|
|
144
|
+
- confidence_score: Must be a decimal number between 0.0 and 1.0 inclusive
|
|
145
|
+
|
|
146
|
+
EXAMPLES:
|
|
147
|
+
Input: "App crashes when user clicks submit button"
|
|
148
|
+
Output: {"severity": "Critical", "category": "crash", "root_cause_hypothesis": "Null pointer exception in form validation logic when required fields are empty", "confidence_score": 0.85}
|
|
149
|
+
|
|
150
|
+
Input: "Login button has wrong color"
|
|
151
|
+
Output: {"severity": "Low", "category": "UI", "root_cause_hypothesis": "CSS class override not applied correctly in the theme configuration", "confidence_score": 0.9}
|
|
152
|
+
|
|
153
|
+
IMPORTANT:
|
|
154
|
+
- Do NOT include any explanatory text before or after the JSON
|
|
155
|
+
- Do NOT use markdown code blocks (no ```json```)
|
|
156
|
+
- Do NOT add comments in the JSON
|
|
157
|
+
- Ensure the JSON is valid and parseable
|
|
158
|
+
- If you cannot determine something, use your best judgment
|
|
159
|
+
- Never return null values
|
|
160
|
+
|
|
161
|
+
Now analyze this bug report:
|
|
162
|
+
{bug_report_text}"""
|
|
163
|
+
|
|
164
|
+
result = llm.invoke(prompt) # 500-line prompt that breaks when models update
|
|
165
|
+
# Then parse and hope it's valid JSON
|
|
166
|
+
data = json.loads(result.content) # Crashes in production š„
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**The Flock way:**
|
|
170
|
+
```python
|
|
171
|
+
@flock_type
|
|
172
|
+
class BugDiagnosis(BaseModel):
|
|
173
|
+
severity: str = Field(pattern="^(Critical|High|Medium|Low)$")
|
|
174
|
+
category: str = Field(description="Bug category")
|
|
175
|
+
root_cause_hypothesis: str = Field(min_length=50)
|
|
176
|
+
confidence_score: float = Field(ge=0.0, le=1.0)
|
|
177
|
+
|
|
178
|
+
# The schema IS the instruction. No 500-line prompt needed.
|
|
179
|
+
agent.consumes(BugReport).publishes(BugDiagnosis)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
<p align="center">
|
|
183
|
+
<img alt="Flock Banner" src="docs/assets/images/bug_diagnosis.png" width="1000">
|
|
184
|
+
</p>
|
|
185
|
+
|
|
186
|
+
**Why this matters:**
|
|
187
|
+
- ā
**Survives model upgrades** - GPT-6 will still understand Pydantic schemas
|
|
188
|
+
- ā
**Runtime validation** - Errors caught at parse time, not in production
|
|
189
|
+
- ā
**Testable** - Mock inputs/outputs with concrete types
|
|
190
|
+
- ā
**Self-documenting** - The code tells you what agents do
|
|
191
|
+
|
|
192
|
+
### 2. Blackboard Architecture (Not Directed Graphs)
|
|
193
|
+
|
|
194
|
+
**Graph-based approach:**
|
|
195
|
+
```python
|
|
196
|
+
# Explicit workflow with hardcoded edges
|
|
197
|
+
workflow.add_edge("radiologist", "diagnostician")
|
|
198
|
+
workflow.add_edge("lab_tech", "diagnostician")
|
|
199
|
+
# Add performance_analyzer? Rewrite the graph.
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**The Flock way (blackboard):**
|
|
203
|
+
```python
|
|
204
|
+
# Agents subscribe to types, workflows emerge
|
|
205
|
+
radiologist = flock.agent("radiologist").consumes(Scan).publishes(XRayAnalysis)
|
|
206
|
+
lab_tech = flock.agent("lab_tech").consumes(Scan).publishes(LabResults)
|
|
207
|
+
diagnostician = flock.agent("diagnostician").consumes(XRayAnalysis, LabResults).publishes(Diagnosis)
|
|
208
|
+
|
|
209
|
+
# Add performance_analyzer? Just subscribe it:
|
|
210
|
+
performance = flock.agent("perf").consumes(Scan).publishes(PerfAnalysis)
|
|
211
|
+
# Done. No graph rewiring. Diagnostician can optionally consume it.
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**What just happened:**
|
|
215
|
+
- ā
**Parallel execution** - Radiologist and lab_tech run concurrently (automatic)
|
|
216
|
+
- ā
**Dependency resolution** - Diagnostician waits for both inputs (automatic)
|
|
217
|
+
- ā
**Loose coupling** - Agents don't know about each other, just data types
|
|
218
|
+
- ā
**Scalable** - O(n) complexity, not O(n²) edges
|
|
219
|
+
|
|
220
|
+
**This is not a new idea.** Blackboard architecture has powered groundbreaking AI systems since the 1970s (Hearsay-II, HASP/SIAP, BB1). We're applying proven patterns to modern LLMs.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Quick Start (60 Seconds)
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
pip install flock-core
|
|
228
|
+
export OPENAI_API_KEY="sk-..."
|
|
229
|
+
# Optional: export DEFAULT_MODEL (falls back to hard-coded default if unset)
|
|
230
|
+
export DEFAULT_MODEL="openai/gpt-4.1"
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
import os
|
|
235
|
+
import asyncio
|
|
236
|
+
from pydantic import BaseModel, Field
|
|
237
|
+
from flock import Flock, flock_type
|
|
238
|
+
|
|
239
|
+
# 1. Define typed artifacts
|
|
240
|
+
@flock_type
|
|
241
|
+
class CodeSubmission(BaseModel):
|
|
242
|
+
code: str
|
|
243
|
+
language: str
|
|
244
|
+
|
|
245
|
+
@flock_type
|
|
246
|
+
class BugAnalysis(BaseModel):
|
|
247
|
+
bugs_found: list[str]
|
|
248
|
+
severity: str = Field(pattern="^(Critical|High|Medium|Low|None)$")
|
|
249
|
+
confidence: float = Field(ge=0.0, le=1.0)
|
|
250
|
+
|
|
251
|
+
@flock_type
|
|
252
|
+
class SecurityAnalysis(BaseModel):
|
|
253
|
+
vulnerabilities: list[str]
|
|
254
|
+
risk_level: str = Field(pattern="^(Critical|High|Medium|Low|None)$")
|
|
255
|
+
|
|
256
|
+
@flock_type
|
|
257
|
+
class FinalReview(BaseModel):
|
|
258
|
+
overall_assessment: str = Field(pattern="^(Approve|Approve with Changes|Reject)$")
|
|
259
|
+
action_items: list[str]
|
|
260
|
+
|
|
261
|
+
# 2. Create the blackboard
|
|
262
|
+
flock = Flock(os.getenv("DEFAULT_MODEL", "openai/gpt-4.1"))
|
|
263
|
+
|
|
264
|
+
# 3. Agents subscribe to types (NO graph wiring!)
|
|
265
|
+
bug_detector = flock.agent("bug_detector").consumes(CodeSubmission).publishes(BugAnalysis)
|
|
266
|
+
security_auditor = flock.agent("security_auditor").consumes(CodeSubmission).publishes(SecurityAnalysis)
|
|
267
|
+
|
|
268
|
+
# This agent AUTOMATICALLY waits for both analyses
|
|
269
|
+
final_reviewer = flock.agent("final_reviewer").consumes(BugAnalysis, SecurityAnalysis).publishes(FinalReview)
|
|
270
|
+
|
|
271
|
+
# 4. Run with real-time dashboard
|
|
272
|
+
async def main():
|
|
273
|
+
await flock.serve(dashboard=True)
|
|
274
|
+
|
|
275
|
+
asyncio.run(main())
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**What happened:**
|
|
279
|
+
- Bug detector and security auditor ran **in parallel** (both consume CodeSubmission)
|
|
280
|
+
- Final reviewer **automatically waited** for both
|
|
281
|
+
- **Zero prompts written** - types defined the behavior
|
|
282
|
+
- **Zero graph edges** - subscriptions created the workflow
|
|
283
|
+
- **Full type safety** - Pydantic validates all outputs
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Persistent Blackboard History
|
|
288
|
+
|
|
289
|
+
The in-memory store is still great for local tinkering, but production teams now have a durable option. Plugging in `SQLiteBlackboardStore` turns the blackboard into a persistent event log with first-class ergonomics:
|
|
290
|
+
|
|
291
|
+
- **Long-lived artifacts** ā every field (payload, tags, partition keys, visibility) is stored for replay, audits, and postmortems
|
|
292
|
+
- **Historical APIs** ā `/api/v1/artifacts`, `/summary`, and `/agents/{agent_id}/history-summary` expose pagination, filtering, and consumption counts
|
|
293
|
+
- **Dashboard module** ā the new **Historical Blackboard** experience preloads persisted history, enriches the graph with consumer metadata, and highlights retention windows
|
|
294
|
+
- **Operational tooling** ā CLI helpers (`init-sqlite-store`, `sqlite-maintenance --delete-before ... --vacuum`) make schema setup and retention policies scriptable
|
|
295
|
+
|
|
296
|
+
Quick start:
|
|
297
|
+
|
|
298
|
+
```python
|
|
299
|
+
from flock import Flock
|
|
300
|
+
from flock.store import SQLiteBlackboardStore
|
|
301
|
+
|
|
302
|
+
store = SQLiteBlackboardStore(".flock/blackboard.db")
|
|
303
|
+
await store.ensure_schema()
|
|
304
|
+
flock = Flock("openai/gpt-4.1", store=store)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Run `examples/02-the-blackboard/01_persistent_pizza.py` to generate history, then launch `examples/03-the-dashboard/04_persistent_pizza_dashboard.py` and explore previous runs, consumption trails, and retention banners inside the dashboard.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Core Concepts
|
|
312
|
+
|
|
313
|
+
### Typed Artifacts (The Vocabulary)
|
|
314
|
+
|
|
315
|
+
Every piece of data on the blackboard is a validated Pydantic model:
|
|
316
|
+
|
|
317
|
+
```python
|
|
318
|
+
@flock_type
|
|
319
|
+
class PatientDiagnosis(BaseModel):
|
|
320
|
+
condition: str = Field(min_length=10)
|
|
321
|
+
confidence: float = Field(ge=0.0, le=1.0)
|
|
322
|
+
recommended_treatment: list[str] = Field(min_length=1)
|
|
323
|
+
follow_up_required: bool
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Benefits:**
|
|
327
|
+
- Runtime validation ensures quality
|
|
328
|
+
- Field constraints prevent bad outputs
|
|
329
|
+
- Self-documenting data structures
|
|
330
|
+
- Version-safe (types survive model updates)
|
|
331
|
+
|
|
332
|
+
### Agent Subscriptions (The Rules)
|
|
333
|
+
|
|
334
|
+
Agents declare what they consume and produce:
|
|
335
|
+
|
|
336
|
+
```python
|
|
337
|
+
analyzer = (
|
|
338
|
+
flock.agent("analyzer")
|
|
339
|
+
.description("Analyzes patient scans") # Optional: improves multi-agent coordination
|
|
340
|
+
.consumes(PatientScan) # What triggers this agent
|
|
341
|
+
.publishes(PatientDiagnosis) # What it produces
|
|
342
|
+
)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**Advanced subscriptions:**
|
|
346
|
+
|
|
347
|
+
```python
|
|
348
|
+
# Conditional consumption - only high-severity cases
|
|
349
|
+
urgent_care = flock.agent("urgent").consumes(
|
|
350
|
+
Diagnosis,
|
|
351
|
+
where=lambda d: d.severity in ["Critical", "High"]
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
# Batch processing - wait for 10 items
|
|
355
|
+
batch_processor = flock.agent("batch").consumes(
|
|
356
|
+
Event,
|
|
357
|
+
batch=BatchSpec(size=10, timeout=timedelta(seconds=30))
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
# Join operations - wait for multiple types within time window
|
|
361
|
+
correlator = flock.agent("correlator").consumes(
|
|
362
|
+
SignalA,
|
|
363
|
+
SignalB,
|
|
364
|
+
join=JoinSpec(within=timedelta(minutes=5))
|
|
365
|
+
)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Visibility Controls (The Security)
|
|
369
|
+
|
|
370
|
+
**Unlike other frameworks, Flock has zero-trust security built-in:**
|
|
371
|
+
|
|
372
|
+
```python
|
|
373
|
+
# Multi-tenancy (SaaS isolation)
|
|
374
|
+
agent.publishes(CustomerData, visibility=TenantVisibility(tenant_id="customer_123"))
|
|
375
|
+
|
|
376
|
+
# Explicit allowlist (HIPAA compliance)
|
|
377
|
+
agent.publishes(MedicalRecord, visibility=PrivateVisibility(agents={"physician", "nurse"}))
|
|
378
|
+
|
|
379
|
+
# Role-based access control
|
|
380
|
+
agent.identity(AgentIdentity(name="analyst", labels={"clearance:secret"}))
|
|
381
|
+
agent.publishes(IntelReport, visibility=LabelledVisibility(required_labels={"clearance:secret"}))
|
|
382
|
+
|
|
383
|
+
# Time-delayed release (embargo periods)
|
|
384
|
+
artifact.visibility = AfterVisibility(ttl=timedelta(hours=24), then=PublicVisibility())
|
|
385
|
+
|
|
386
|
+
# Public (default)
|
|
387
|
+
agent.publishes(PublicReport, visibility=PublicVisibility())
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
**Why this matters:** Financial services, healthcare, defense, SaaS platforms all need this for compliance. Other frameworks make you build it yourself.
|
|
391
|
+
|
|
392
|
+
### Batching Pattern: Parallel Execution Control
|
|
393
|
+
|
|
394
|
+
**A key differentiator:** The separation of `publish()` and `run_until_idle()` enables parallel execution.
|
|
395
|
+
|
|
396
|
+
```python
|
|
397
|
+
# ā
EFFICIENT: Batch publish, then run in parallel
|
|
398
|
+
for review in customer_reviews:
|
|
399
|
+
await flock.publish(review) # Just scheduling work
|
|
400
|
+
|
|
401
|
+
await flock.run_until_idle() # All sentiment_analyzer agents run concurrently!
|
|
402
|
+
|
|
403
|
+
# Get all results
|
|
404
|
+
analyses = await flock.store.get_by_type(SentimentAnalysis)
|
|
405
|
+
# 100 analyses completed in ~1x single review processing time!
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
**Why this separation matters:**
|
|
409
|
+
- ā” **Parallel execution** - Process 100 customer reviews concurrently
|
|
410
|
+
- šÆ **Batch control** - Publish multiple artifacts, execute once
|
|
411
|
+
- š **Multi-type workflows** - Publish different types, trigger different agents in parallel
|
|
412
|
+
- š **Better performance** - Process 1000 items in the time it takes to process 1
|
|
413
|
+
|
|
414
|
+
**Comparison to other patterns:**
|
|
415
|
+
```python
|
|
416
|
+
# ā If run_until_idle() was automatic (like most frameworks):
|
|
417
|
+
for review in customer_reviews:
|
|
418
|
+
await flock.publish(review) # Would wait for completion each time!
|
|
419
|
+
# Total time: 100x single execution (sequential)
|
|
420
|
+
|
|
421
|
+
# ā
With explicit batching:
|
|
422
|
+
for review in customer_reviews:
|
|
423
|
+
await flock.publish(review) # Fast: just queuing
|
|
424
|
+
await flock.run_until_idle()
|
|
425
|
+
# Total time: ~1x single execution (parallel)
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
### Production Safety Features
|
|
429
|
+
|
|
430
|
+
**Built-in safeguards prevent common production failures:**
|
|
431
|
+
|
|
432
|
+
```python
|
|
433
|
+
# Circuit breakers prevent runaway costs
|
|
434
|
+
flock = Flock("openai/gpt-4.1", max_agent_iterations=1000)
|
|
435
|
+
|
|
436
|
+
# Feedback loop protection
|
|
437
|
+
critic = (
|
|
438
|
+
flock.agent("critic")
|
|
439
|
+
.consumes(Essay)
|
|
440
|
+
.publishes(Critique)
|
|
441
|
+
.prevent_self_trigger(True) # Won't trigger itself infinitely
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
# Best-of-N execution (run 5x, pick best)
|
|
445
|
+
agent.best_of(5, score=lambda result: result.metrics["confidence"])
|
|
446
|
+
|
|
447
|
+
# Configuration validation
|
|
448
|
+
agent.best_of(150, ...) # ā ļø Warns: "best_of(150) is very high - high LLM costs"
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
## Production-Ready Observability
|
|
454
|
+
|
|
455
|
+
### Real-Time Dashboard
|
|
456
|
+
|
|
457
|
+
**Start the dashboard with one line:**
|
|
458
|
+
|
|
459
|
+
```python
|
|
460
|
+
await flock.serve(dashboard=True)
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
The dashboard provides comprehensive real-time visibility into your agent system with professional UI/UX:
|
|
464
|
+
|
|
465
|
+
<p align="center">
|
|
466
|
+
<img alt="Flock Agent View" src="docs/assets/images/flock_ui_agent_view.png" width="1000">
|
|
467
|
+
<i>Agent View: See agent communication patterns and message flows in real-time</i>
|
|
468
|
+
</p>
|
|
469
|
+
|
|
470
|
+
**Key Features:**
|
|
471
|
+
|
|
472
|
+
- **Dual Visualization Modes:**
|
|
473
|
+
- **Agent View** - Agents as nodes with message flows as edges
|
|
474
|
+
- **Blackboard View** - Messages as nodes with data transformations as edges
|
|
475
|
+
|
|
476
|
+
<p align="center">
|
|
477
|
+
<img alt="Flock Blackboard View" src="docs/assets/images/flock_ui_blackboard_view.png" width="1000">
|
|
478
|
+
<i>Blackboard View: Track data lineage and transformations across the system</i>
|
|
479
|
+
</p>
|
|
480
|
+
|
|
481
|
+
- **Real-Time Updates:**
|
|
482
|
+
- WebSocket streaming with 2-minute heartbeat
|
|
483
|
+
- Live agent activation and message publication
|
|
484
|
+
- Auto-layout with Dagre algorithm
|
|
485
|
+
|
|
486
|
+
- **Interactive Graph:**
|
|
487
|
+
- Drag nodes, zoom, pan, and explore topology
|
|
488
|
+
- Double-click nodes to open detail windows
|
|
489
|
+
- Right-click for context menu with auto-layout options:
|
|
490
|
+
- **5 Layout Algorithms**: Hierarchical (Vertical/Horizontal), Circular, Grid, and Random
|
|
491
|
+
- **Smart Spacing**: Dynamic 200px minimum clearance based on node dimensions
|
|
492
|
+
- **Viewport Centering**: Layouts always center around current viewport
|
|
493
|
+
- Add modules dynamically from context menu
|
|
494
|
+
|
|
495
|
+
- **Advanced Filtering:**
|
|
496
|
+
- Correlation ID tracking for workflow tracing
|
|
497
|
+
- Time range filtering (last 5/10/60 minutes or custom)
|
|
498
|
+
- Active filter pills with one-click removal
|
|
499
|
+
- Autocomplete search with metadata preview
|
|
500
|
+
|
|
501
|
+
- **Control Panel:**
|
|
502
|
+
- Publish artifacts from the UI
|
|
503
|
+
- Invoke agents manually
|
|
504
|
+
- Monitor system health
|
|
505
|
+
|
|
506
|
+
- **Keyboard Shortcuts:**
|
|
507
|
+
- `Ctrl+M` - Toggle view mode
|
|
508
|
+
- `Ctrl+F` - Focus filter
|
|
509
|
+
- `Ctrl+/` - Show shortcuts help
|
|
510
|
+
- WCAG 2.1 AA compliant accessibility
|
|
511
|
+
|
|
512
|
+
### Production-Grade Trace Viewer
|
|
513
|
+
|
|
514
|
+
The dashboard includes a **Jaeger-style trace viewer** with 7 powerful visualization modes:
|
|
515
|
+
|
|
516
|
+
<p align="center">
|
|
517
|
+
<img alt="Trace Viewer" src="docs/assets/images/trace_1.png" width="1000">
|
|
518
|
+
<i>Trace Viewer: Timeline view showing span hierarchies and execution flow</i>
|
|
519
|
+
</p>
|
|
520
|
+
|
|
521
|
+
**7 Trace Viewer Modes:**
|
|
522
|
+
|
|
523
|
+
1. **Timeline** - Waterfall visualization with parent-child relationships
|
|
524
|
+
2. **Statistics** - Sortable table view with durations and error tracking
|
|
525
|
+
3. **RED Metrics** - Rate, Errors, Duration monitoring for service health
|
|
526
|
+
4. **Dependencies** - Service-to-service communication analysis
|
|
527
|
+
5. **DuckDB SQL** - Interactive SQL query editor with CSV export
|
|
528
|
+
6. **Configuration** - Real-time service/operation filtering
|
|
529
|
+
7. **Guide** - Built-in documentation and query examples
|
|
530
|
+
|
|
531
|
+
**Additional Features:**
|
|
532
|
+
|
|
533
|
+
- **Full I/O Capture** - Complete input/output data for every operation
|
|
534
|
+
- **JSON Viewer** - Collapsible tree structure with expand all/collapse all
|
|
535
|
+
- **Multi-Trace Support** - Open and compare multiple traces simultaneously
|
|
536
|
+
- **Smart Sorting** - Sort by date, span count, or duration
|
|
537
|
+
- **CSV Export** - Download query results for offline analysis
|
|
538
|
+
|
|
539
|
+
<p align="center">
|
|
540
|
+
<img alt="Trace Viewer" src="docs/assets/images/trace_2.png" width="1000">
|
|
541
|
+
<i>Trace Viewer: Dependency Analysis</i>
|
|
542
|
+
</p>
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
### OpenTelemetry + DuckDB Tracing
|
|
546
|
+
|
|
547
|
+
**One environment variable enables comprehensive tracing:**
|
|
548
|
+
|
|
549
|
+
```bash
|
|
550
|
+
export FLOCK_AUTO_TRACE=true
|
|
551
|
+
export FLOCK_TRACE_FILE=true
|
|
552
|
+
|
|
553
|
+
python your_app.py
|
|
554
|
+
# Traces stored in .flock/traces.duckdb
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
**AI-queryable debugging:**
|
|
558
|
+
|
|
559
|
+
```python
|
|
560
|
+
import duckdb
|
|
561
|
+
conn = duckdb.connect('.flock/traces.duckdb', read_only=True)
|
|
562
|
+
|
|
563
|
+
# Find bottlenecks
|
|
564
|
+
slow_ops = conn.execute("""
|
|
565
|
+
SELECT name, AVG(duration_ms) as avg_ms, COUNT(*) as count
|
|
566
|
+
FROM spans
|
|
567
|
+
WHERE duration_ms > 1000
|
|
568
|
+
GROUP BY name
|
|
569
|
+
ORDER BY avg_ms DESC
|
|
570
|
+
""").fetchall()
|
|
571
|
+
|
|
572
|
+
# Find errors with full context
|
|
573
|
+
errors = conn.execute("""
|
|
574
|
+
SELECT name, status_description,
|
|
575
|
+
json_extract(attributes, '$.input') as input,
|
|
576
|
+
json_extract(attributes, '$.output') as output
|
|
577
|
+
FROM spans
|
|
578
|
+
WHERE status_code = 'ERROR'
|
|
579
|
+
""").fetchall()
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
**Real debugging session:**
|
|
583
|
+
```
|
|
584
|
+
You: "My pizza agent is slow"
|
|
585
|
+
AI: [queries DuckDB]
|
|
586
|
+
"DSPyEngine.evaluate takes 23s on average.
|
|
587
|
+
Input size: 50KB of conversation history.
|
|
588
|
+
Recommendation: Limit context to last 5 messages."
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
**Why DuckDB?** 10-100x faster than SQLite for analytical queries. Zero configuration. AI agents can debug your AI agents.
|
|
592
|
+
|
|
593
|
+
<p align="center">
|
|
594
|
+
<img alt="Trace Viewer" src="docs/assets/images/trace_3.png" width="1000">
|
|
595
|
+
<i>Trace Viewer: DuckDB Query</i>
|
|
596
|
+
</p>
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
## Framework Comparison
|
|
601
|
+
|
|
602
|
+
### Architectural Differences
|
|
603
|
+
|
|
604
|
+
Flock uses a fundamentally different coordination pattern than most multi-agent frameworks:
|
|
605
|
+
|
|
606
|
+
| Dimension | Graph-Based Frameworks | Chat-Based Frameworks | Flock (Blackboard) |
|
|
607
|
+
|-----------|------------------------|----------------------|-------------------|
|
|
608
|
+
| **Core Pattern** | Directed graph with explicit edges | Round-robin conversation | Blackboard subscriptions |
|
|
609
|
+
| **Coordination** | Manual edge wiring | Message passing | Type-based subscriptions |
|
|
610
|
+
| **Parallelism** | Manual (split/join nodes) | Sequential turn-taking | Automatic (concurrent consumers) |
|
|
611
|
+
| **Type Safety** | Varies (often TypedDict) | Text-based messages | Pydantic + runtime validation |
|
|
612
|
+
| **Coupling** | Tight (hardcoded successors) | Medium (conversation context) | Loose (type subscriptions only) |
|
|
613
|
+
| **Adding Agents** | Rewrite graph topology | Update conversation flow | Just subscribe to types |
|
|
614
|
+
| **Testing** | Requires full graph | Requires full group | Individual agent isolation |
|
|
615
|
+
| **Security Model** | DIY implementation | DIY implementation | Built-in (5 visibility types) |
|
|
616
|
+
| **Scalability** | O(n²) edge complexity | Limited by turn-taking | O(n) subscription complexity |
|
|
617
|
+
|
|
618
|
+
### When Flock Wins
|
|
619
|
+
|
|
620
|
+
**ā
Use Flock when you need:**
|
|
621
|
+
|
|
622
|
+
- **Parallel agent execution** - Agents consuming the same type run concurrently automatically
|
|
623
|
+
- **Type-safe outputs** - Pydantic validation catches errors at runtime
|
|
624
|
+
- **Minimal prompt engineering** - Schemas define behavior, not natural language
|
|
625
|
+
- **Dynamic agent addition** - Subscribe new agents without rewiring existing workflows
|
|
626
|
+
- **Testing in isolation** - Unit test individual agents with mock inputs
|
|
627
|
+
- **Built-in security** - 5 visibility types for compliance (HIPAA, SOC2, multi-tenancy)
|
|
628
|
+
- **10+ agents** - Linear complexity stays manageable at scale
|
|
629
|
+
|
|
630
|
+
### When Alternatives Win
|
|
631
|
+
|
|
632
|
+
**ā ļø Consider graph-based frameworks when:**
|
|
633
|
+
- You need extensive ecosystem integration with existing tools
|
|
634
|
+
- Your workflow is inherently sequential (no parallelism needed)
|
|
635
|
+
- You want battle-tested maturity (larger communities, more documentation)
|
|
636
|
+
- Your team has existing expertise with those frameworks
|
|
637
|
+
|
|
638
|
+
**ā ļø Consider chat-based frameworks when:**
|
|
639
|
+
- You prefer conversation-based development patterns
|
|
640
|
+
- Your use case maps naturally to turn-taking dialogue
|
|
641
|
+
- You need features specific to those ecosystems
|
|
642
|
+
|
|
643
|
+
### Honest Trade-offs
|
|
644
|
+
|
|
645
|
+
**You trade:**
|
|
646
|
+
- Ecosystem maturity (established frameworks have larger communities)
|
|
647
|
+
- Extensive documentation (we're catching up)
|
|
648
|
+
- Battle-tested age (newer architecture means less production history)
|
|
649
|
+
|
|
650
|
+
**You gain:**
|
|
651
|
+
- Better scalability (O(n) vs O(n²) complexity)
|
|
652
|
+
- Type safety (runtime validation vs hope)
|
|
653
|
+
- Cleaner architecture (loose coupling vs tight graphs)
|
|
654
|
+
- Production safety (circuit breakers, feedback prevention built-in)
|
|
655
|
+
- Security model (5 visibility types vs DIY)
|
|
656
|
+
|
|
657
|
+
**Different frameworks for different priorities. Choose based on what matters to your team.**
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
## Production Readiness
|
|
662
|
+
|
|
663
|
+
### What Works Today (v0.5.0)
|
|
664
|
+
|
|
665
|
+
**ā
Production-ready core:**
|
|
666
|
+
- More than 700 tests, with >75% coverage (>90% on critical paths)
|
|
667
|
+
- Blackboard orchestrator with typed artifacts
|
|
668
|
+
- Parallel + sequential execution (automatic)
|
|
669
|
+
- Zero-trust security (5 visibility types)
|
|
670
|
+
- Circuit breakers and feedback loop prevention
|
|
671
|
+
- OpenTelemetry distributed tracing with DuckDB storage
|
|
672
|
+
- Real-time dashboard with 7-mode trace viewer
|
|
673
|
+
- MCP integration (Model Context Protocol)
|
|
674
|
+
- Best-of-N execution, batch processing, join operations
|
|
675
|
+
- Type-safe retrieval API (`get_by_type()`)
|
|
676
|
+
|
|
677
|
+
**ā ļø What's missing for large-scale production:**
|
|
678
|
+
- **Persistent blackboard** - Currently in-memory only
|
|
679
|
+
- **Advanced retry logic** - Basic only
|
|
680
|
+
- **Event replay** - No Kafka integration yet
|
|
681
|
+
- **Kubernetes-native deployment** - No Helm chart yet
|
|
682
|
+
- **OAuth/RBAC** - Dashboard has no auth
|
|
683
|
+
|
|
684
|
+
All planned for v1.0
|
|
685
|
+
|
|
686
|
+
### Recommended Use Cases Today
|
|
687
|
+
|
|
688
|
+
**ā
Good fit right now:**
|
|
689
|
+
- **Startups/MVPs** - Fast iteration, type safety, built-in observability
|
|
690
|
+
- **Internal tools** - Where in-memory blackboard is acceptable
|
|
691
|
+
- **Research/prototyping** - Rapid experimentation with clean architecture
|
|
692
|
+
- **Medium-scale systems** (10-50 agents, 1000s of artifacts)
|
|
693
|
+
|
|
694
|
+
**ā ļø Wait for 1.0 if you need:**
|
|
695
|
+
- **Enterprise persistence** (multi-region, high availability)
|
|
696
|
+
- **Compliance auditing** (immutable event logs)
|
|
697
|
+
- **Multi-tenancy SaaS** (with OAuth/SSO)
|
|
698
|
+
- **Mission-critical systems** with 99.99% uptime requirements
|
|
699
|
+
|
|
700
|
+
**Flock 0.5.0 is production-ready for the right use cases. Know your requirements.**
|
|
701
|
+
|
|
702
|
+
---
|
|
703
|
+
|
|
704
|
+
## Roadmap to 1.0
|
|
705
|
+
|
|
706
|
+
We're building enterprise infrastructure for AI agents and tracking the work publicly. Check [ROADMAP.md](ROADMAP.md) for deep dives and status updates.
|
|
707
|
+
|
|
708
|
+
### 0.5.0 Beta (In Flight)
|
|
709
|
+
- **Core data & governance:** [#271](https://github.com/whiteducksoftware/flock/issues/271), [#274](https://github.com/whiteducksoftware/flock/issues/274), [#273](https://github.com/whiteducksoftware/flock/issues/273), [#281](https://github.com/whiteducksoftware/flock/issues/281)
|
|
710
|
+
- **Execution patterns & scheduling:** [#282](https://github.com/whiteducksoftware/flock/issues/282), [#283](https://github.com/whiteducksoftware/flock/issues/283)
|
|
711
|
+
- **REST access & integrations:** [#286](https://github.com/whiteducksoftware/flock/issues/286), [#287](https://github.com/whiteducksoftware/flock/issues/287), [#288](https://github.com/whiteducksoftware/flock/issues/288), [#289](https://github.com/whiteducksoftware/flock/issues/289), [#290](https://github.com/whiteducksoftware/flock/issues/290), [#291](https://github.com/whiteducksoftware/flock/issues/291), [#292](https://github.com/whiteducksoftware/flock/issues/292), [#293](https://github.com/whiteducksoftware/flock/issues/293)
|
|
712
|
+
- **Docs & onboarding:** [#270](https://github.com/whiteducksoftware/flock/issues/270), [#269](https://github.com/whiteducksoftware/flock/issues/269)
|
|
713
|
+
|
|
714
|
+
### 1.0 Release Goals (Target Q4 2025)
|
|
715
|
+
- **Reliability & operations:** [#277](https://github.com/whiteducksoftware/flock/issues/277), [#278](https://github.com/whiteducksoftware/flock/issues/278), [#279](https://github.com/whiteducksoftware/flock/issues/279), [#294](https://github.com/whiteducksoftware/flock/issues/294)
|
|
716
|
+
- **Platform validation & quality:** [#275](https://github.com/whiteducksoftware/flock/issues/275), [#276](https://github.com/whiteducksoftware/flock/issues/276), [#284](https://github.com/whiteducksoftware/flock/issues/284), [#285](https://github.com/whiteducksoftware/flock/issues/285)
|
|
717
|
+
- **Security & access:** [#280](https://github.com/whiteducksoftware/flock/issues/280)
|
|
718
|
+
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
## Example: Multi-Modal Clinical Decision Support
|
|
722
|
+
|
|
723
|
+
```python
|
|
724
|
+
import os
|
|
725
|
+
from flock import Flock, flock_type
|
|
726
|
+
from flock.visibility import PrivateVisibility, TenantVisibility, LabelledVisibility
|
|
727
|
+
from flock.identity import AgentIdentity
|
|
728
|
+
from pydantic import BaseModel
|
|
729
|
+
|
|
730
|
+
@flock_type
|
|
731
|
+
class PatientScan(BaseModel):
|
|
732
|
+
patient_id: str
|
|
733
|
+
scan_type: str
|
|
734
|
+
image_data: bytes
|
|
735
|
+
|
|
736
|
+
@flock_type
|
|
737
|
+
class XRayAnalysis(BaseModel):
|
|
738
|
+
findings: list[str]
|
|
739
|
+
confidence: float
|
|
740
|
+
|
|
741
|
+
@flock_type
|
|
742
|
+
class LabResults(BaseModel):
|
|
743
|
+
markers: dict[str, float]
|
|
744
|
+
|
|
745
|
+
@flock_type
|
|
746
|
+
class Diagnosis(BaseModel):
|
|
747
|
+
condition: str
|
|
748
|
+
reasoning: str
|
|
749
|
+
confidence: float
|
|
750
|
+
|
|
751
|
+
# Create HIPAA-compliant blackboard
|
|
752
|
+
flock = Flock(os.getenv("DEFAULT_MODEL", "openai/gpt-4.1"))
|
|
753
|
+
|
|
754
|
+
# Radiologist with privacy controls
|
|
755
|
+
radiologist = (
|
|
756
|
+
flock.agent("radiologist")
|
|
757
|
+
.consumes(PatientScan)
|
|
758
|
+
.publishes(
|
|
759
|
+
XRayAnalysis,
|
|
760
|
+
visibility=PrivateVisibility(agents={"diagnostician"}) # HIPAA!
|
|
761
|
+
)
|
|
762
|
+
)
|
|
763
|
+
|
|
764
|
+
# Lab tech with multi-tenancy
|
|
765
|
+
lab_tech = (
|
|
766
|
+
flock.agent("lab_tech")
|
|
767
|
+
.consumes(PatientScan)
|
|
768
|
+
.publishes(
|
|
769
|
+
LabResults,
|
|
770
|
+
visibility=TenantVisibility(tenant_id="patient_123") # Isolation!
|
|
771
|
+
)
|
|
772
|
+
)
|
|
773
|
+
|
|
774
|
+
# Diagnostician with explicit access
|
|
775
|
+
diagnostician = (
|
|
776
|
+
flock.agent("diagnostician")
|
|
777
|
+
.identity(AgentIdentity(name="diagnostician", labels={"role:physician"}))
|
|
778
|
+
.consumes(XRayAnalysis, LabResults) # Waits for BOTH
|
|
779
|
+
.publishes(
|
|
780
|
+
Diagnosis,
|
|
781
|
+
visibility=LabelledVisibility(required_labels={"role:physician"})
|
|
782
|
+
)
|
|
783
|
+
)
|
|
784
|
+
|
|
785
|
+
# Run with tracing
|
|
786
|
+
async with flock.traced_run("patient_123_diagnosis"):
|
|
787
|
+
await flock.publish(PatientScan(patient_id="123", ...))
|
|
788
|
+
await flock.run_until_idle()
|
|
789
|
+
|
|
790
|
+
# Get diagnosis (type-safe retrieval)
|
|
791
|
+
diagnoses = await flock.store.get_by_type(Diagnosis)
|
|
792
|
+
# Returns list[Diagnosis] directly - no .data access, no casting
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
**What this demonstrates:**
|
|
796
|
+
- Multi-modal data fusion (images + labs + history)
|
|
797
|
+
- Built-in access controls (HIPAA compliance)
|
|
798
|
+
- Parallel agent execution (radiology + labs run concurrently)
|
|
799
|
+
- Automatic dependency resolution (diagnostician waits for both)
|
|
800
|
+
- Full audit trail (traced_run + DuckDB storage)
|
|
801
|
+
- Type-safe data retrieval (no Artifact wrappers)
|
|
802
|
+
|
|
803
|
+
---
|
|
804
|
+
|
|
805
|
+
## Production Use Cases
|
|
806
|
+
|
|
807
|
+
Flock's architecture shines in production scenarios requiring parallel execution, security, and observability. Here are common patterns:
|
|
808
|
+
|
|
809
|
+
### Financial Services: Multi-Signal Trading
|
|
810
|
+
|
|
811
|
+
**The Challenge:** Analyze multiple market signals in parallel, correlate them within time windows, maintain SEC-compliant audit trails.
|
|
812
|
+
|
|
813
|
+
**The Solution:** 20+ signal analyzers run concurrently, join operations correlate signals, DuckDB provides complete audit trails.
|
|
814
|
+
|
|
815
|
+
```python
|
|
816
|
+
# Parallel signal analyzers
|
|
817
|
+
volatility = flock.agent("volatility").consumes(MarketData).publishes(VolatilityAlert)
|
|
818
|
+
sentiment = flock.agent("sentiment").consumes(NewsArticle).publishes(SentimentAlert)
|
|
819
|
+
|
|
820
|
+
# Trade execution waits for CORRELATED signals (within 5min window)
|
|
821
|
+
trader = flock.agent("trader").consumes(
|
|
822
|
+
VolatilityAlert, SentimentAlert,
|
|
823
|
+
join=JoinSpec(within=timedelta(minutes=5))
|
|
824
|
+
).publishes(TradeOrder)
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
### Healthcare: HIPAA-Compliant Diagnostics
|
|
828
|
+
|
|
829
|
+
**The Challenge:** Multi-modal data fusion with strict access controls, complete audit trails, zero-trust security.
|
|
830
|
+
|
|
831
|
+
**The Solution:** Built-in visibility controls for HIPAA compliance, automatic parallel execution, full data lineage tracking.
|
|
832
|
+
|
|
833
|
+
```python
|
|
834
|
+
# Privacy controls built-in
|
|
835
|
+
radiology.publishes(XRayAnalysis, visibility=PrivateVisibility(agents={"diagnostician"}))
|
|
836
|
+
lab.publishes(LabResults, visibility=TenantVisibility(tenant_id="patient_123"))
|
|
837
|
+
|
|
838
|
+
# Diagnostician waits for BOTH inputs with role-based access
|
|
839
|
+
diagnostician = flock.agent("diagnostician").consumes(XRayAnalysis, LabResults).publishes(Diagnosis)
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
### E-Commerce: 50-Agent Personalization
|
|
843
|
+
|
|
844
|
+
**The Challenge:** Analyze dozens of independent signals, support dynamic signal addition, process millions of events daily.
|
|
845
|
+
|
|
846
|
+
**The Solution:** O(n) scaling to 50+ analyzers, batch processing for efficiency, zero graph rewiring when adding signals.
|
|
847
|
+
|
|
848
|
+
```python
|
|
849
|
+
# 50+ signal analyzers (all run in parallel!)
|
|
850
|
+
for signal in ["browsing", "purchase", "cart", "reviews", "email", "social"]:
|
|
851
|
+
flock.agent(f"{signal}_analyzer").consumes(UserEvent).publishes(Signal)
|
|
852
|
+
|
|
853
|
+
# Recommender batches signals for efficient LLM calls
|
|
854
|
+
recommender = flock.agent("recommender").consumes(Signal, batch=BatchSpec(size=50))
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
### Multi-Tenant SaaS: Content Moderation
|
|
858
|
+
|
|
859
|
+
**The Challenge:** Complete data isolation between tenants, multi-agent consensus, full audit trails.
|
|
860
|
+
|
|
861
|
+
**The Solution:** Tenant visibility ensures zero cross-tenant leakage, parallel checks provide diverse signals, traces show complete reasoning.
|
|
862
|
+
|
|
863
|
+
**See [USECASES.md](USECASES.md) for complete code examples and production metrics.**
|
|
864
|
+
|
|
865
|
+
---
|
|
866
|
+
|
|
867
|
+
## Getting Started
|
|
868
|
+
|
|
869
|
+
```bash
|
|
870
|
+
# Install
|
|
871
|
+
pip install flock-core
|
|
872
|
+
|
|
873
|
+
# Set API key
|
|
874
|
+
export OPENAI_API_KEY="sk-..."
|
|
875
|
+
|
|
876
|
+
# Try the workshop
|
|
877
|
+
git clone https://github.com/whiteducksoftware/flock-flow.git
|
|
878
|
+
cd flock-flow
|
|
879
|
+
uv run python examples/05-claudes-workshop/lesson_01_code_detective.py
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
**Learn by doing:**
|
|
883
|
+
- š [7-Lesson Workshop](examples/05-claudes-workshop/) - Progressive lessons from basics to advanced
|
|
884
|
+
- š [The Blackboard](examples/02-the-blackboard/) - See data-driven orchestration without graphs
|
|
885
|
+
- šÆ [Declarative Basics](examples/01-the-declarative-way/) - Understanding declarative programming
|
|
886
|
+
- š [Documentation](https://docs.flock.whiteduck.de) - Complete online documentation
|
|
887
|
+
- š [AGENTS.md](AGENTS.md) - Development guide
|
|
888
|
+
|
|
889
|
+
---
|
|
890
|
+
|
|
891
|
+
## Contributing
|
|
892
|
+
|
|
893
|
+
We're building Flock in the open. See **[Contributing Guide](https://docs.flock.whiteduck.de/about/contributing/)** for development setup, or check [CONTRIBUTING.md](CONTRIBUTING.md) and [AGENTS.md](AGENTS.md) locally.
|
|
894
|
+
|
|
895
|
+
**We welcome:**
|
|
896
|
+
- Bug reports and feature requests
|
|
897
|
+
- Documentation improvements
|
|
898
|
+
- Example contributions
|
|
899
|
+
- Architecture discussions
|
|
900
|
+
|
|
901
|
+
**Quality standards:**
|
|
902
|
+
- All tests must pass
|
|
903
|
+
- Coverage requirements met
|
|
904
|
+
- Code formatted with Ruff
|
|
905
|
+
|
|
906
|
+
---
|
|
907
|
+
|
|
908
|
+
## Why "0.5"?
|
|
909
|
+
|
|
910
|
+
We're calling this 0.5 to signal:
|
|
911
|
+
|
|
912
|
+
1. **Core is production-ready** - real-world client deployments, comprehensive features
|
|
913
|
+
2. **Ecosystem is evolving** - Documentation growing, community building, features maturing
|
|
914
|
+
3. **Architecture is proven** - Blackboard pattern is 50+ years old, declarative contracts are sound
|
|
915
|
+
4. **Enterprise features are coming** - Persistence, auth, Kubernetes deployment in roadmap
|
|
916
|
+
|
|
917
|
+
**1.0 will arrive** when we've delivered persistence, advanced error handling, and enterprise deployment patterns (targeting Q4 2025).
|
|
918
|
+
|
|
919
|
+
---
|
|
920
|
+
|
|
921
|
+
## The Bottom Line
|
|
922
|
+
|
|
923
|
+
**Flock is different because it makes different architectural choices:**
|
|
924
|
+
|
|
925
|
+
**Instead of:**
|
|
926
|
+
- ā Prompt engineering ā ā
Declarative type contracts
|
|
927
|
+
- ā Workflow graphs ā ā
Blackboard subscriptions
|
|
928
|
+
- ā Manual parallelization ā ā
Automatic concurrent execution
|
|
929
|
+
- ā Bolt-on security ā ā
Zero-trust visibility controls
|
|
930
|
+
- ā Hope-based debugging ā ā
AI-queryable distributed traces
|
|
931
|
+
|
|
932
|
+
**These aren't marketing slogans. They're architectural decisions with real tradeoffs.**
|
|
933
|
+
|
|
934
|
+
**You trade:**
|
|
935
|
+
- Ecosystem maturity (established frameworks have larger communities)
|
|
936
|
+
- Extensive documentation (we're catching up)
|
|
937
|
+
- Battle-tested age (newer architecture means less production history)
|
|
938
|
+
|
|
939
|
+
**You gain:**
|
|
940
|
+
- Better scalability (O(n) vs O(n²) complexity)
|
|
941
|
+
- Type safety (runtime validation vs hope)
|
|
942
|
+
- Cleaner architecture (loose coupling vs tight graphs)
|
|
943
|
+
- Production safety (circuit breakers, feedback prevention built-in)
|
|
944
|
+
- Security model (5 visibility types vs DIY)
|
|
945
|
+
|
|
946
|
+
**Different frameworks for different priorities. Choose based on what matters to your team.**
|
|
947
|
+
|
|
948
|
+
---
|
|
949
|
+
|
|
950
|
+
<div align="center">
|
|
951
|
+
|
|
952
|
+
**Built with ā¤ļø by white duck GmbH**
|
|
953
|
+
|
|
954
|
+
**"Declarative contracts eliminate prompt hell. Blackboard architecture eliminates graph spaghetti. Proven patterns applied to modern LLMs."**
|
|
955
|
+
|
|
956
|
+
[ā Star on GitHub](https://github.com/whiteducksoftware/flock-flow) | [š Documentation](https://docs.flock.whiteduck.de) | [š Try Examples](examples/) | [š¼ Enterprise Support](mailto:support@whiteduck.de)
|
|
957
|
+
|
|
958
|
+
</div>
|
|
959
|
+
|
|
960
|
+
---
|
|
961
|
+
|
|
962
|
+
**Last Updated:** October 8, 2025
|
|
963
|
+
**Version:** Flock 0.5.0 (Blackboard Edition)
|
|
964
|
+
**Status:** Production-Ready Core, Enterprise Features Roadmapped
|