flock-core 0.5.0b28__py3-none-any.whl → 0.5.56b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of flock-core might be problematic. Click here for more details.
- flock/__init__.py +12 -217
- flock/agent.py +678 -0
- flock/api/themes.py +71 -0
- flock/artifacts.py +79 -0
- flock/cli.py +75 -0
- flock/components.py +173 -0
- flock/dashboard/__init__.py +28 -0
- flock/dashboard/collector.py +283 -0
- flock/dashboard/events.py +182 -0
- flock/dashboard/launcher.py +230 -0
- flock/dashboard/service.py +537 -0
- flock/dashboard/websocket.py +235 -0
- flock/engines/__init__.py +6 -0
- flock/engines/dspy_engine.py +856 -0
- flock/examples.py +128 -0
- flock/{core/util → helper}/cli_helper.py +4 -3
- flock/{core/logging → logging}/__init__.py +2 -3
- flock/{core/logging → logging}/formatters/enum_builder.py +3 -4
- flock/{core/logging → logging}/formatters/theme_builder.py +19 -44
- flock/{core/logging → logging}/formatters/themed_formatter.py +69 -115
- flock/{core/logging → logging}/logging.py +77 -61
- flock/{core/logging → logging}/telemetry.py +20 -26
- flock/{core/logging → logging}/telemetry_exporter/base_exporter.py +2 -2
- flock/{core/logging → logging}/telemetry_exporter/file_exporter.py +6 -9
- flock/{core/logging → logging}/telemetry_exporter/sqlite_exporter.py +2 -3
- flock/{core/logging → logging}/trace_and_logged.py +20 -24
- flock/mcp/__init__.py +91 -0
- flock/{core/mcp/mcp_client.py → mcp/client.py} +103 -154
- flock/{core/mcp/mcp_config.py → mcp/config.py} +62 -117
- flock/mcp/manager.py +255 -0
- flock/mcp/servers/sse/__init__.py +1 -1
- flock/mcp/servers/sse/flock_sse_server.py +11 -53
- flock/mcp/servers/stdio/__init__.py +1 -1
- flock/mcp/servers/stdio/flock_stdio_server.py +8 -48
- flock/mcp/servers/streamable_http/flock_streamable_http_server.py +17 -62
- flock/mcp/servers/websockets/flock_websocket_server.py +7 -40
- flock/{core/mcp/flock_mcp_tool.py → mcp/tool.py} +16 -26
- flock/mcp/types/__init__.py +42 -0
- flock/{core/mcp → mcp}/types/callbacks.py +9 -15
- flock/{core/mcp → mcp}/types/factories.py +7 -6
- flock/{core/mcp → mcp}/types/handlers.py +13 -18
- flock/{core/mcp → mcp}/types/types.py +70 -74
- flock/{core/mcp → mcp}/util/helpers.py +1 -1
- flock/orchestrator.py +645 -0
- flock/registry.py +148 -0
- flock/runtime.py +262 -0
- flock/service.py +140 -0
- flock/store.py +69 -0
- flock/subscription.py +111 -0
- flock/themes/andromeda.toml +1 -1
- flock/themes/apple-system-colors.toml +1 -1
- flock/themes/arcoiris.toml +1 -1
- flock/themes/atomonelight.toml +1 -1
- flock/themes/ayu copy.toml +1 -1
- flock/themes/ayu-light.toml +1 -1
- flock/themes/belafonte-day.toml +1 -1
- flock/themes/belafonte-night.toml +1 -1
- flock/themes/blulocodark.toml +1 -1
- flock/themes/breeze.toml +1 -1
- flock/themes/broadcast.toml +1 -1
- flock/themes/brogrammer.toml +1 -1
- flock/themes/builtin-dark.toml +1 -1
- flock/themes/builtin-pastel-dark.toml +1 -1
- flock/themes/catppuccin-latte.toml +1 -1
- flock/themes/catppuccin-macchiato.toml +1 -1
- flock/themes/catppuccin-mocha.toml +1 -1
- flock/themes/cga.toml +1 -1
- flock/themes/chalk.toml +1 -1
- flock/themes/ciapre.toml +1 -1
- flock/themes/coffee-theme.toml +1 -1
- flock/themes/cyberpunkscarletprotocol.toml +1 -1
- flock/themes/dark+.toml +1 -1
- flock/themes/darkermatrix.toml +1 -1
- flock/themes/darkside.toml +1 -1
- flock/themes/desert.toml +1 -1
- flock/themes/django.toml +1 -1
- flock/themes/djangosmooth.toml +1 -1
- flock/themes/doomone.toml +1 -1
- flock/themes/dotgov.toml +1 -1
- flock/themes/dracula+.toml +1 -1
- flock/themes/duckbones.toml +1 -1
- flock/themes/encom.toml +1 -1
- flock/themes/espresso.toml +1 -1
- flock/themes/everblush.toml +1 -1
- flock/themes/fairyfloss.toml +1 -1
- flock/themes/fideloper.toml +1 -1
- flock/themes/fishtank.toml +1 -1
- flock/themes/flexoki-light.toml +1 -1
- flock/themes/floraverse.toml +1 -1
- flock/themes/framer.toml +1 -1
- flock/themes/galizur.toml +1 -1
- flock/themes/github.toml +1 -1
- flock/themes/grass.toml +1 -1
- flock/themes/grey-green.toml +1 -1
- flock/themes/gruvboxlight.toml +1 -1
- flock/themes/guezwhoz.toml +1 -1
- flock/themes/harper.toml +1 -1
- flock/themes/hax0r-blue.toml +1 -1
- flock/themes/hopscotch.256.toml +1 -1
- flock/themes/ic-green-ppl.toml +1 -1
- flock/themes/iceberg-dark.toml +1 -1
- flock/themes/japanesque.toml +1 -1
- flock/themes/jubi.toml +1 -1
- flock/themes/kibble.toml +1 -1
- flock/themes/kolorit.toml +1 -1
- flock/themes/kurokula.toml +1 -1
- flock/themes/materialdesigncolors.toml +1 -1
- flock/themes/matrix.toml +1 -1
- flock/themes/mellifluous.toml +1 -1
- flock/themes/midnight-in-mojave.toml +1 -1
- flock/themes/monokai-remastered.toml +1 -1
- flock/themes/monokai-soda.toml +1 -1
- flock/themes/neon.toml +1 -1
- flock/themes/neopolitan.toml +1 -1
- flock/themes/nord-light.toml +1 -1
- flock/themes/ocean.toml +1 -1
- flock/themes/onehalfdark.toml +1 -1
- flock/themes/onehalflight.toml +1 -1
- flock/themes/palenighthc.toml +1 -1
- flock/themes/paulmillr.toml +1 -1
- flock/themes/pencildark.toml +1 -1
- flock/themes/pnevma.toml +1 -1
- flock/themes/purple-rain.toml +1 -1
- flock/themes/purplepeter.toml +1 -1
- flock/themes/raycast-dark.toml +1 -1
- flock/themes/red-sands.toml +1 -1
- flock/themes/relaxed.toml +1 -1
- flock/themes/retro.toml +1 -1
- flock/themes/rose-pine.toml +1 -1
- flock/themes/royal.toml +1 -1
- flock/themes/ryuuko.toml +1 -1
- flock/themes/sakura.toml +1 -1
- flock/themes/scarlet-protocol.toml +1 -1
- flock/themes/seoulbones-dark.toml +1 -1
- flock/themes/shades-of-purple.toml +1 -1
- flock/themes/smyck.toml +1 -1
- flock/themes/softserver.toml +1 -1
- flock/themes/solarized-darcula.toml +1 -1
- flock/themes/square.toml +1 -1
- flock/themes/sugarplum.toml +1 -1
- flock/themes/thayer-bright.toml +1 -1
- flock/themes/tokyonight.toml +1 -1
- flock/themes/tomorrow.toml +1 -1
- flock/themes/ubuntu.toml +1 -1
- flock/themes/ultradark.toml +1 -1
- flock/themes/ultraviolent.toml +1 -1
- flock/themes/unikitty.toml +1 -1
- flock/themes/urple.toml +1 -1
- flock/themes/vesper.toml +1 -1
- flock/themes/vimbones.toml +1 -1
- flock/themes/wildcherry.toml +1 -1
- flock/themes/wilmersdorf.toml +1 -1
- flock/themes/wryan.toml +1 -1
- flock/themes/xcodedarkhc.toml +1 -1
- flock/themes/xcodelight.toml +1 -1
- flock/themes/zenbones-light.toml +1 -1
- flock/themes/zenwritten-dark.toml +1 -1
- flock/utilities.py +301 -0
- flock/{components/utility → utility}/output_utility_component.py +68 -53
- flock/visibility.py +107 -0
- flock_core-0.5.56b0.dist-info/METADATA +747 -0
- flock_core-0.5.56b0.dist-info/RECORD +398 -0
- flock_core-0.5.56b0.dist-info/entry_points.txt +2 -0
- {flock_core-0.5.0b28.dist-info → flock_core-0.5.56b0.dist-info}/licenses/LICENSE +1 -1
- flock/adapter/__init__.py +0 -14
- flock/adapter/azure_adapter.py +0 -68
- flock/adapter/chroma_adapter.py +0 -73
- flock/adapter/faiss_adapter.py +0 -97
- flock/adapter/pinecone_adapter.py +0 -51
- flock/adapter/vector_base.py +0 -47
- flock/cli/assets/release_notes.md +0 -140
- flock/cli/config.py +0 -8
- flock/cli/constants.py +0 -36
- flock/cli/create_agent.py +0 -1
- flock/cli/create_flock.py +0 -280
- flock/cli/execute_flock.py +0 -620
- flock/cli/load_agent.py +0 -1
- flock/cli/load_examples.py +0 -1
- flock/cli/load_flock.py +0 -192
- flock/cli/load_release_notes.py +0 -20
- flock/cli/loaded_flock_cli.py +0 -254
- flock/cli/manage_agents.py +0 -459
- flock/cli/registry_management.py +0 -889
- flock/cli/runner.py +0 -41
- flock/cli/settings.py +0 -857
- flock/cli/utils.py +0 -135
- flock/cli/view_results.py +0 -29
- flock/cli/yaml_editor.py +0 -396
- flock/components/__init__.py +0 -30
- flock/components/evaluation/__init__.py +0 -9
- flock/components/evaluation/declarative_evaluation_component.py +0 -606
- flock/components/routing/__init__.py +0 -15
- flock/components/routing/conditional_routing_component.py +0 -494
- flock/components/routing/default_routing_component.py +0 -103
- flock/components/routing/llm_routing_component.py +0 -206
- flock/components/utility/__init__.py +0 -22
- flock/components/utility/example_utility_component.py +0 -250
- flock/components/utility/feedback_utility_component.py +0 -206
- flock/components/utility/memory_utility_component.py +0 -550
- flock/components/utility/metrics_utility_component.py +0 -700
- flock/config.py +0 -61
- flock/core/__init__.py +0 -110
- flock/core/agent/__init__.py +0 -16
- flock/core/agent/default_agent.py +0 -216
- flock/core/agent/flock_agent_components.py +0 -104
- flock/core/agent/flock_agent_execution.py +0 -101
- flock/core/agent/flock_agent_integration.py +0 -260
- flock/core/agent/flock_agent_lifecycle.py +0 -186
- flock/core/agent/flock_agent_serialization.py +0 -381
- flock/core/api/__init__.py +0 -10
- flock/core/api/custom_endpoint.py +0 -45
- flock/core/api/endpoints.py +0 -254
- flock/core/api/main.py +0 -162
- flock/core/api/models.py +0 -97
- flock/core/api/run_store.py +0 -224
- flock/core/api/runner.py +0 -44
- flock/core/api/service.py +0 -214
- flock/core/component/__init__.py +0 -15
- flock/core/component/agent_component_base.py +0 -309
- flock/core/component/evaluation_component.py +0 -62
- flock/core/component/routing_component.py +0 -74
- flock/core/component/utility_component.py +0 -69
- flock/core/config/flock_agent_config.py +0 -58
- flock/core/config/scheduled_agent_config.py +0 -40
- flock/core/context/context.py +0 -213
- flock/core/context/context_manager.py +0 -37
- flock/core/context/context_vars.py +0 -10
- flock/core/evaluation/utils.py +0 -396
- flock/core/execution/batch_executor.py +0 -369
- flock/core/execution/evaluation_executor.py +0 -438
- flock/core/execution/local_executor.py +0 -31
- flock/core/execution/opik_executor.py +0 -103
- flock/core/execution/temporal_executor.py +0 -164
- flock/core/flock.py +0 -634
- flock/core/flock_agent.py +0 -336
- flock/core/flock_factory.py +0 -613
- flock/core/flock_scheduler.py +0 -166
- flock/core/flock_server_manager.py +0 -136
- flock/core/interpreter/python_interpreter.py +0 -689
- flock/core/mcp/__init__.py +0 -1
- flock/core/mcp/flock_mcp_server.py +0 -680
- flock/core/mcp/mcp_client_manager.py +0 -201
- flock/core/mcp/types/__init__.py +0 -1
- flock/core/mixin/dspy_integration.py +0 -403
- flock/core/mixin/prompt_parser.py +0 -125
- flock/core/orchestration/__init__.py +0 -15
- flock/core/orchestration/flock_batch_processor.py +0 -94
- flock/core/orchestration/flock_evaluator.py +0 -113
- flock/core/orchestration/flock_execution.py +0 -295
- flock/core/orchestration/flock_initialization.py +0 -149
- flock/core/orchestration/flock_server_manager.py +0 -67
- flock/core/orchestration/flock_web_server.py +0 -117
- flock/core/registry/__init__.py +0 -45
- flock/core/registry/agent_registry.py +0 -69
- flock/core/registry/callable_registry.py +0 -139
- flock/core/registry/component_discovery.py +0 -142
- flock/core/registry/component_registry.py +0 -64
- flock/core/registry/config_mapping.py +0 -64
- flock/core/registry/decorators.py +0 -137
- flock/core/registry/registry_hub.py +0 -205
- flock/core/registry/server_registry.py +0 -57
- flock/core/registry/type_registry.py +0 -86
- flock/core/serialization/__init__.py +0 -13
- flock/core/serialization/callable_registry.py +0 -52
- flock/core/serialization/flock_serializer.py +0 -832
- flock/core/serialization/json_encoder.py +0 -41
- flock/core/serialization/secure_serializer.py +0 -175
- flock/core/serialization/serializable.py +0 -342
- flock/core/serialization/serialization_utils.py +0 -412
- flock/core/util/file_path_utils.py +0 -223
- flock/core/util/hydrator.py +0 -309
- flock/core/util/input_resolver.py +0 -164
- flock/core/util/loader.py +0 -59
- flock/core/util/splitter.py +0 -219
- flock/di.py +0 -27
- flock/platform/docker_tools.py +0 -49
- flock/platform/jaeger_install.py +0 -86
- flock/webapp/__init__.py +0 -1
- flock/webapp/app/__init__.py +0 -0
- flock/webapp/app/api/__init__.py +0 -0
- flock/webapp/app/api/agent_management.py +0 -241
- flock/webapp/app/api/execution.py +0 -709
- flock/webapp/app/api/flock_management.py +0 -129
- flock/webapp/app/api/registry_viewer.py +0 -30
- flock/webapp/app/chat.py +0 -665
- flock/webapp/app/config.py +0 -104
- flock/webapp/app/dependencies.py +0 -117
- flock/webapp/app/main.py +0 -1070
- flock/webapp/app/middleware.py +0 -113
- flock/webapp/app/models_ui.py +0 -7
- flock/webapp/app/services/__init__.py +0 -0
- flock/webapp/app/services/feedback_file_service.py +0 -363
- flock/webapp/app/services/flock_service.py +0 -337
- flock/webapp/app/services/sharing_models.py +0 -81
- flock/webapp/app/services/sharing_store.py +0 -762
- flock/webapp/app/templates/theme_mapper.html +0 -326
- flock/webapp/app/theme_mapper.py +0 -812
- flock/webapp/app/utils.py +0 -85
- flock/webapp/run.py +0 -215
- flock/webapp/static/css/chat.css +0 -301
- flock/webapp/static/css/components.css +0 -167
- flock/webapp/static/css/header.css +0 -39
- flock/webapp/static/css/layout.css +0 -46
- flock/webapp/static/css/sidebar.css +0 -127
- flock/webapp/static/css/two-pane.css +0 -48
- flock/webapp/templates/base.html +0 -200
- flock/webapp/templates/chat.html +0 -152
- flock/webapp/templates/chat_settings.html +0 -19
- flock/webapp/templates/flock_editor.html +0 -16
- flock/webapp/templates/index.html +0 -12
- flock/webapp/templates/partials/_agent_detail_form.html +0 -93
- flock/webapp/templates/partials/_agent_list.html +0 -18
- flock/webapp/templates/partials/_agent_manager_view.html +0 -51
- flock/webapp/templates/partials/_agent_tools_checklist.html +0 -14
- flock/webapp/templates/partials/_chat_container.html +0 -15
- flock/webapp/templates/partials/_chat_messages.html +0 -57
- flock/webapp/templates/partials/_chat_settings_form.html +0 -85
- flock/webapp/templates/partials/_create_flock_form.html +0 -50
- flock/webapp/templates/partials/_dashboard_flock_detail.html +0 -17
- flock/webapp/templates/partials/_dashboard_flock_file_list.html +0 -16
- flock/webapp/templates/partials/_dashboard_flock_properties_preview.html +0 -28
- flock/webapp/templates/partials/_dashboard_upload_flock_form.html +0 -16
- flock/webapp/templates/partials/_dynamic_input_form_content.html +0 -22
- flock/webapp/templates/partials/_env_vars_table.html +0 -23
- flock/webapp/templates/partials/_execution_form.html +0 -118
- flock/webapp/templates/partials/_execution_view_container.html +0 -28
- flock/webapp/templates/partials/_flock_file_list.html +0 -23
- flock/webapp/templates/partials/_flock_properties_form.html +0 -52
- flock/webapp/templates/partials/_flock_upload_form.html +0 -16
- flock/webapp/templates/partials/_header_flock_status.html +0 -5
- flock/webapp/templates/partials/_load_manager_view.html +0 -49
- flock/webapp/templates/partials/_registry_table.html +0 -25
- flock/webapp/templates/partials/_registry_viewer_content.html +0 -70
- flock/webapp/templates/partials/_results_display.html +0 -78
- flock/webapp/templates/partials/_settings_env_content.html +0 -9
- flock/webapp/templates/partials/_settings_theme_content.html +0 -14
- flock/webapp/templates/partials/_settings_view.html +0 -36
- flock/webapp/templates/partials/_share_chat_link_snippet.html +0 -11
- flock/webapp/templates/partials/_share_link_snippet.html +0 -35
- flock/webapp/templates/partials/_sidebar.html +0 -74
- flock/webapp/templates/partials/_streaming_results_container.html +0 -195
- flock/webapp/templates/partials/_structured_data_view.html +0 -40
- flock/webapp/templates/partials/_theme_preview.html +0 -36
- flock/webapp/templates/registry_viewer.html +0 -84
- flock/webapp/templates/shared_run_page.html +0 -140
- flock/workflow/__init__.py +0 -0
- flock/workflow/activities.py +0 -196
- flock/workflow/agent_activities.py +0 -24
- flock/workflow/agent_execution_activity.py +0 -202
- flock/workflow/flock_workflow.py +0 -214
- flock/workflow/temporal_config.py +0 -96
- flock/workflow/temporal_setup.py +0 -68
- flock_core-0.5.0b28.dist-info/METADATA +0 -274
- flock_core-0.5.0b28.dist-info/RECORD +0 -561
- flock_core-0.5.0b28.dist-info/entry_points.txt +0 -2
- /flock/{core/logging → logging}/formatters/themes.py +0 -0
- /flock/{core/logging → logging}/span_middleware/baggage_span_processor.py +0 -0
- /flock/{core/mcp → mcp}/util/__init__.py +0 -0
- {flock_core-0.5.0b28.dist-info → flock_core-0.5.56b0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,747 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: flock-core
|
|
3
|
+
Version: 0.5.56b0
|
|
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: devtools>=0.12.2
|
|
9
|
+
Requires-Dist: dspy==3.0.0
|
|
10
|
+
Requires-Dist: fastapi>=0.117.1
|
|
11
|
+
Requires-Dist: httpx>=0.28.1
|
|
12
|
+
Requires-Dist: litellm==1.75.3
|
|
13
|
+
Requires-Dist: loguru>=0.7.3
|
|
14
|
+
Requires-Dist: mcp>=1.7.1
|
|
15
|
+
Requires-Dist: opentelemetry-api>=1.30.0
|
|
16
|
+
Requires-Dist: opentelemetry-exporter-jaeger-proto-grpc>=1.21.0
|
|
17
|
+
Requires-Dist: opentelemetry-exporter-jaeger>=1.21.0
|
|
18
|
+
Requires-Dist: opentelemetry-exporter-otlp>=1.30.0
|
|
19
|
+
Requires-Dist: opentelemetry-instrumentation-logging>=0.51b0
|
|
20
|
+
Requires-Dist: opentelemetry-sdk>=1.30.0
|
|
21
|
+
Requires-Dist: poethepoet>=0.30.0
|
|
22
|
+
Requires-Dist: pydantic[email]>=2.11.9
|
|
23
|
+
Requires-Dist: rich>=14.1.0
|
|
24
|
+
Requires-Dist: toml>=0.10.2
|
|
25
|
+
Requires-Dist: typer>=0.19.2
|
|
26
|
+
Requires-Dist: uvicorn>=0.37.0
|
|
27
|
+
Requires-Dist: websockets>=15.0.1
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
<p align="center">
|
|
31
|
+
<img alt="Flock Banner" src="https://raw.githubusercontent.com/whiteducksoftware/flock/master/docs/assets/images/flock.png" width="800">
|
|
32
|
+
</p>
|
|
33
|
+
<p align="center">
|
|
34
|
+
<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>
|
|
35
|
+
<img alt="Python Version" src="https://img.shields.io/badge/python-3.10%2B-blue?style=for-the-badge&logo=python">
|
|
36
|
+
<a href="https://github.com/whiteducksoftware/flock/blob/master/LICENSE" target="_blank"><img alt="License" src="https://img.shields.io/pypi/l/flock-core?style=for-the-badge"></a>
|
|
37
|
+
<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>
|
|
38
|
+
<a href="https://www.linkedin.com/company/whiteduck" target="_blank"><img alt="LinkedIn" src="https://img.shields.io/badge/linkedin-%230077B5.svg?style=for-the-badge&logo=linkedin&logoColor=white&label=whiteduck"></a>
|
|
39
|
+
<a href="https://bsky.app/profile/whiteduck-gmbh.bsky.social" target="_blank"><img alt="Bluesky" src="https://img.shields.io/badge/bluesky-Follow-blue?style=for-the-badge&logo=bluesky&logoColor=%23fff&color=%23333&labelColor=%230285FF&label=whiteduck-gmbh"></a>
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
# 🚀 Flock 0.5: Agent Systems Without the Graphs
|
|
45
|
+
|
|
46
|
+
> **What if agents collaborated like experts at a whiteboard—not like nodes in a rigid workflow?**
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## The Problem You Know Too Well
|
|
51
|
+
|
|
52
|
+
🤯 **Prompt Hell**: Brittle 500-line prompts that break with every model update
|
|
53
|
+
💥 **System Failures**: One bad LLM response crashes your entire workflow
|
|
54
|
+
🧪 **Testing Nightmares**: "How do I unit test a prompt?" (You don't.)
|
|
55
|
+
📏 **Measuring Quality**: "How do I know my prompts are optimal?" (You also don't.)
|
|
56
|
+
📄 **Output Chaos**: Parsing unstructured LLM responses into reliable data
|
|
57
|
+
⛓️ **Orchestration Limits**: Graph-based frameworks create rigid, tightly-coupled systems
|
|
58
|
+
🚀 **Production Gap**: Jupyter notebooks don't scale to enterprise systems
|
|
59
|
+
🔓 **No Security Model**: Every agent sees everything—no access controls
|
|
60
|
+
|
|
61
|
+
**The tooling is fundamentally broken. It's time for a better approach.**
|
|
62
|
+
|
|
63
|
+
Most issues are solvable, because decades of experience with micro services tought us hard lessons about decoupling, orchestration and reliability.
|
|
64
|
+
|
|
65
|
+
**Let's introduce these learnings to AI agents!**
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## The Flock Solution: Declarative + Blackboard Architecture
|
|
70
|
+
|
|
71
|
+
**What if you could skip the 'prompt engineering' step AND avoid rigid workflow graphs?**
|
|
72
|
+
|
|
73
|
+
Flock 0.5 combines **declarative AI workflows** with **blackboard architecture**—the pattern that powered groundbreaking AI systems since the 1970s (Hearsay-II speech recognition at CMU).
|
|
74
|
+
|
|
75
|
+
### ✅ Declarative at Heart
|
|
76
|
+
|
|
77
|
+
**No natural language prompts. No brittle instructions. Just type-safe contracts.**
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
@flock_type
|
|
81
|
+
class MyDreamPizza(BaseModel):
|
|
82
|
+
pizza_idea: str
|
|
83
|
+
|
|
84
|
+
@flock_type
|
|
85
|
+
class Pizza(BaseModel):
|
|
86
|
+
ingredients: list[str]
|
|
87
|
+
size: str
|
|
88
|
+
crust_type: str
|
|
89
|
+
step_by_step_instructions: list[str]
|
|
90
|
+
|
|
91
|
+
# Create orchestrator
|
|
92
|
+
flock = Flock("openai/gpt-4o")
|
|
93
|
+
|
|
94
|
+
# Define agent with ZERO natural language
|
|
95
|
+
pizza_master = (
|
|
96
|
+
flock.agent("pizza_master")
|
|
97
|
+
.consumes(MyDreamPizza)
|
|
98
|
+
.publishes(Pizza)
|
|
99
|
+
)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Hard-binding type contracts will even work with GPT-4729.**
|
|
103
|
+
|
|
104
|
+
<p align="center">
|
|
105
|
+
<img alt="Flock Blackboard" src="docs/img/pizza.png" width="1000">
|
|
106
|
+
</p>
|
|
107
|
+
|
|
108
|
+
### ✅ Key Advantages
|
|
109
|
+
|
|
110
|
+
✅ **Declarative Contracts**: Define inputs/outputs with Pydantic models. Flock handles the LLM complexity.
|
|
111
|
+
⚡ **Built-in Resilience**: Blackboard persists context—agents crash? They recover and resume.
|
|
112
|
+
🧪 **Actually Testable**: Clear contracts make agents unit-testable like any other code
|
|
113
|
+
🔐 **Zero-Trust Security**: 5 built-in visibility types (Public, Private, Tenant, Label-based, Time-delayed)
|
|
114
|
+
🚀 **Dynamic Workflows**: Self-correcting loops, conditional routing, intelligent decision-making
|
|
115
|
+
🔧 **Production-Ready**: Real-time dashboard, WebSocket streaming, 743 passing tests
|
|
116
|
+
📊 **True Observability**: Agent View + Blackboard View with full data lineage
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Why Graphs Fail (and Blackboards Win)
|
|
121
|
+
|
|
122
|
+
### The Problem with Graph-Based Frameworks
|
|
123
|
+
|
|
124
|
+
**LangGraph. CrewAI. AutoGen.** They all make the same fundamental mistake: **treating agent collaboration as a directed graph**.
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
# ❌ The Graph-Based Way (LangGraph, CrewAI, etc.)
|
|
128
|
+
workflow.add_edge("agent_a", "agent_b") # Tight coupling!
|
|
129
|
+
workflow.add_edge("agent_b", "agent_c") # Predefined flow!
|
|
130
|
+
|
|
131
|
+
# What happens when you need to:
|
|
132
|
+
# - Add agent_d that consumes data from agent_a?
|
|
133
|
+
# - Run agent_b and agent_c in parallel?
|
|
134
|
+
# - Route conditionally based on agent_a's output quality?
|
|
135
|
+
# Answer: Rewrite the graph. Again. And again.
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Why graphs fail at scale:**
|
|
139
|
+
|
|
140
|
+
- 🔗 **Tight coupling**: Agents hardcode their successors
|
|
141
|
+
- 📐 **Rigid topology**: Adding an agent means rewiring the graph
|
|
142
|
+
- 🐌 **Sequential thinking**: Even independent agents wait in line
|
|
143
|
+
- 🧪 **Testing nightmare**: Can't test agents in isolation
|
|
144
|
+
- 🔓 **No security model**: Every agent sees everything
|
|
145
|
+
- 📈 **Doesn't scale**: 20+ agents = spaghetti graph
|
|
146
|
+
- 💀 **Single point of failure**: Orchestrator dies? Everything dies.
|
|
147
|
+
- 🧠 **God object anti-pattern**: One orchestrator needs domain knowledge of 20+ agents to route correctly
|
|
148
|
+
- 📦 **No context resilience**: Agent crashes? Context disappears. No recovery.
|
|
149
|
+
|
|
150
|
+
**This is workflow orchestration dressed up as "agent systems."**
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
### The Blackboard Alternative: How Experts Actually Collaborate
|
|
155
|
+
|
|
156
|
+
<p align="center">
|
|
157
|
+
<img alt="Flock Blackboard" src="docs/img/flock_ui_blackboard_view.png" width="1000">
|
|
158
|
+
</p>
|
|
159
|
+
|
|
160
|
+
Watch a team of specialists solve a complex problem:
|
|
161
|
+
|
|
162
|
+
1. **Radiologist** posts X-ray analysis on the whiteboard
|
|
163
|
+
2. **Lab tech** sees it, adds blood work results
|
|
164
|
+
3. **Diagnostician** waits for BOTH, then posts diagnosis
|
|
165
|
+
4. **Pharmacist** reacts to diagnosis, suggests treatment
|
|
166
|
+
|
|
167
|
+
**No one manages the workflow.** No directed graph. Just specialists reacting to relevant information appearing on a shared workspace.
|
|
168
|
+
|
|
169
|
+
**This is the blackboard pattern—proven since the 1970s (Hearsay-II speech recognition system at CMU).**
|
|
170
|
+
|
|
171
|
+
**Why this matters:**
|
|
172
|
+
- **Context IS the blackboard**: All state lives in one place, not scattered across agents
|
|
173
|
+
- **Crash resilience**: Agent dies? Blackboard persists. Restart agent, it picks up where it left off.
|
|
174
|
+
- **100% decoupled**: Agents don't know about each other. They only know data types.
|
|
175
|
+
- **Microservices lessons applied**: We learned in the 2000s that tight coupling kills scalability. Blackboards apply that wisdom to AI agents.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 🎯 Flock 0.5: Blackboard-First Architecture
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from flock_flow.orchestrator import Flock
|
|
183
|
+
from flock_flow.registry import flock_type
|
|
184
|
+
from pydantic import BaseModel
|
|
185
|
+
|
|
186
|
+
# 1. Define typed artifacts (what goes on the blackboard)
|
|
187
|
+
@flock_type
|
|
188
|
+
class XRayAnalysis(BaseModel):
|
|
189
|
+
finding: str
|
|
190
|
+
confidence: float
|
|
191
|
+
|
|
192
|
+
@flock_type
|
|
193
|
+
class LabResults(BaseModel):
|
|
194
|
+
markers: dict[str, float]
|
|
195
|
+
|
|
196
|
+
@flock_type
|
|
197
|
+
class Diagnosis(BaseModel):
|
|
198
|
+
condition: str
|
|
199
|
+
reasoning: str
|
|
200
|
+
|
|
201
|
+
# 2. Create orchestrator (the blackboard)
|
|
202
|
+
orchestrator = Flock("openai/gpt-4o")
|
|
203
|
+
|
|
204
|
+
# 3. Agents subscribe to what they care about (NO explicit workflow!)
|
|
205
|
+
radiologist = (
|
|
206
|
+
orchestrator.agent("radiologist")
|
|
207
|
+
.consumes(PatientScan)
|
|
208
|
+
.publishes(XRayAnalysis)
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
lab_tech = (
|
|
212
|
+
orchestrator.agent("lab_tech")
|
|
213
|
+
.consumes(PatientScan)
|
|
214
|
+
.publishes(LabResults)
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
diagnostician = (
|
|
218
|
+
orchestrator.agent("diagnostician")
|
|
219
|
+
.consumes(XRayAnalysis, LabResults) # Waits for BOTH!
|
|
220
|
+
.publishes(Diagnosis)
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
# 4. Publish input, agents react opportunistically
|
|
224
|
+
await orchestrator.publish(PatientScan(patient_id="12345", ...))
|
|
225
|
+
await orchestrator.run_until_idle()
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**What just happened:**
|
|
229
|
+
- Radiologist and lab_tech ran **in parallel** (both consume PatientScan)
|
|
230
|
+
- Diagnostician **automatically waited** for both to finish
|
|
231
|
+
- **No workflow graph.** No `.add_edge()`. Just subscriptions.
|
|
232
|
+
- Add new agents? Just subscribe them. No rewiring.
|
|
233
|
+
|
|
234
|
+
**Resilience built-in:**
|
|
235
|
+
- Lab agent crashes? Blackboard still has XRayAnalysis. Restart lab agent, it processes the scan again.
|
|
236
|
+
- No "orchestrator god object" deciding which agent runs when—agents decide themselves based on what's on the blackboard.
|
|
237
|
+
- Context lives on the blackboard, not in memory. Agents are stateless and recoverable.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## 🔥 Why Blackboard Beats Graphs
|
|
242
|
+
|
|
243
|
+
| Dimension | Graph-Based (LangGraph, CrewAI) | Blackboard (Flock 0.5) |
|
|
244
|
+
|-----------|--------------------------------|------------------------|
|
|
245
|
+
| **Add new agent** | Rewrite graph, update edges | Just subscribe to types |
|
|
246
|
+
| **Parallel execution** | Manual (split nodes, join nodes) | Automatic (multiple consumers) |
|
|
247
|
+
| **Conditional routing** | Complex graph branches | `where=lambda x: x.score > 8` |
|
|
248
|
+
| **Testing** | Need full graph setup | Test agents in isolation |
|
|
249
|
+
| **Security** | Add-on (if exists) | Built-in (5 visibility types) |
|
|
250
|
+
| **Coupling** | Tight (agents know successors) | Loose (agents know types) |
|
|
251
|
+
| **Scalability** | O(n²) edges at 20+ agents | O(n) subscriptions |
|
|
252
|
+
| **Mental model** | "Draw the workflow" | "What data triggers this?" |
|
|
253
|
+
| **Context management** | Scattered across agents | **Blackboard IS the context** |
|
|
254
|
+
| **Resilience** | Agent crash = data loss | **Blackboard persists, agents recover** |
|
|
255
|
+
| **Orchestrator pattern** | **God object with domain knowledge** | **Agents decide autonomously** |
|
|
256
|
+
| **Single point of failure** | Orchestrator dies = everything dies | **Agents independent, blackboard survives** |
|
|
257
|
+
| **Architecture wisdom** | Ignores 20 years of microservices | **Applies decoupling lessons learned** |
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 💡 Core Concepts: Rethinking Agent Coordination
|
|
262
|
+
|
|
263
|
+
### 1. Typed Artifacts (Not Unstructured Messages)
|
|
264
|
+
|
|
265
|
+
**Graph frameworks:** Agents pass dictionaries or unstructured text.
|
|
266
|
+
|
|
267
|
+
```python
|
|
268
|
+
# ❌ LangGraph/CrewAI style
|
|
269
|
+
agent_a.output = {"result": "some text", "score": 8} # What's the schema?
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Flock 0.5:** Every artifact is a validated Pydantic model.
|
|
273
|
+
|
|
274
|
+
```python
|
|
275
|
+
# ✅ Flock 0.5 style
|
|
276
|
+
@flock_type
|
|
277
|
+
class Review(BaseModel):
|
|
278
|
+
text: str = Field(max_length=1000)
|
|
279
|
+
score: int = Field(ge=1, le=10)
|
|
280
|
+
confidence: float = Field(ge=0.0, le=1.0)
|
|
281
|
+
|
|
282
|
+
# Type errors caught at definition time, not runtime!
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**Benefits:**
|
|
286
|
+
- ✅ **Debuggable**: Strong typing catches errors at development time
|
|
287
|
+
- ✅ **Measurable**: Validate outputs against explicit schemas
|
|
288
|
+
- ✅ **Migratable**: Type contracts survive model upgrades (GPT-4 → GPT-6)
|
|
289
|
+
- ✅ **Testable**: Mock inputs/outputs with concrete types
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
### 2. Subscriptions (Not Edges)
|
|
294
|
+
|
|
295
|
+
**Graph frameworks:** Explicit edges define flow.
|
|
296
|
+
|
|
297
|
+
```python
|
|
298
|
+
# ❌ LangGraph style
|
|
299
|
+
graph.add_edge("review_agent", "high_quality_handler")
|
|
300
|
+
graph.add_edge("review_agent", "low_quality_handler") # How to route?
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Flock 0.5:** Declarative subscriptions define reactions.
|
|
304
|
+
|
|
305
|
+
```python
|
|
306
|
+
# ✅ Flock 0.5 style
|
|
307
|
+
high_quality = orchestrator.agent("high_quality").consumes(
|
|
308
|
+
Review,
|
|
309
|
+
where=lambda r: r.score > 8 # Conditional routing!
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
low_quality = orchestrator.agent("low_quality").consumes(
|
|
313
|
+
Review,
|
|
314
|
+
where=lambda r: r.score <= 8
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
# Both subscribe to Review, predicate determines who fires
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
### 3. Visibility Controls (Not Open Access)
|
|
323
|
+
|
|
324
|
+
**Graph frameworks:** Any agent can see any data.
|
|
325
|
+
|
|
326
|
+
**Flock 0.5:** Producer-controlled access to artifacts.
|
|
327
|
+
|
|
328
|
+
```python
|
|
329
|
+
# Multi-tenancy (customer data isolation)
|
|
330
|
+
agent.publishes(
|
|
331
|
+
CustomerData,
|
|
332
|
+
visibility=TenantVisibility(tenant_id="customer_123")
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
# Private (allowlist)
|
|
336
|
+
agent.publishes(
|
|
337
|
+
SensitiveData,
|
|
338
|
+
visibility=PrivateVisibility(agents={"compliance_agent"})
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
# Time-delayed (embargo periods)
|
|
342
|
+
artifact.visibility = AfterVisibility(
|
|
343
|
+
ttl=timedelta(hours=24),
|
|
344
|
+
then=PublicVisibility()
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
# Label-based RBAC
|
|
348
|
+
artifact.visibility = LabelledVisibility(
|
|
349
|
+
required_labels={"clearance:secret"}
|
|
350
|
+
)
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Why this matters:** Financial services, healthcare, SaaS platforms NEED this for compliance.
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
### 4. Opportunistic Execution (Not Sequential Workflows)
|
|
358
|
+
|
|
359
|
+
**Graph frameworks:** Define start node, execute path.
|
|
360
|
+
|
|
361
|
+
```python
|
|
362
|
+
# ❌ LangGraph style
|
|
363
|
+
result = graph.invoke({"input": "..."}, config={"start": "node_a"})
|
|
364
|
+
# Executes: node_a → node_b → node_c (even if b and c are independent!)
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
**Flock 0.5:** Publish data, all matching agents fire (in parallel if independent).
|
|
368
|
+
|
|
369
|
+
```python
|
|
370
|
+
# ✅ Flock 0.5 style
|
|
371
|
+
await orchestrator.publish(Review(text="Great product!", score=9))
|
|
372
|
+
|
|
373
|
+
# Three agents all consume Review, run concurrently:
|
|
374
|
+
# - sentiment_analyzer
|
|
375
|
+
# - rating_validator
|
|
376
|
+
# - summary_generator
|
|
377
|
+
|
|
378
|
+
await orchestrator.run_until_idle() # Waits for all agents
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## 🔥 What You Get With Flock 0.5
|
|
384
|
+
|
|
385
|
+
<p align="center">
|
|
386
|
+
<img alt="Flock Banner" src="docs/img/flock_ui_agent_view.png" width="1000">
|
|
387
|
+
</p>
|
|
388
|
+
|
|
389
|
+
### ✅ Production Safety Built-In
|
|
390
|
+
|
|
391
|
+
```python
|
|
392
|
+
# Prevent infinite feedback loops
|
|
393
|
+
agent = (
|
|
394
|
+
orchestrator.agent("processor")
|
|
395
|
+
.consumes(Document)
|
|
396
|
+
.publishes(Document) # Could trigger itself!
|
|
397
|
+
.prevent_self_trigger(True) # But won't! ✅
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
# Circuit breaker for runaway agents
|
|
401
|
+
orchestrator = Flock(max_agent_iterations=1000) # Automatic failsafe
|
|
402
|
+
|
|
403
|
+
# Configuration validation
|
|
404
|
+
agent.best_of(150, ...) # ⚠️ Warns: "best_of(150) is very high"
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**Graph frameworks:** No built-in loop prevention. No circuit breakers. Silent failures.
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
### ✅ Real-Time Observability
|
|
412
|
+
|
|
413
|
+
```python
|
|
414
|
+
# One line to activate dashboard
|
|
415
|
+
await orchestrator.serve(dashboard=True)
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
**What you get:**
|
|
419
|
+
- 🎯 **Agent View**: Live graph of agents and message flows
|
|
420
|
+
- 📋 **Blackboard View**: Transformation edges showing data lineage
|
|
421
|
+
- 🎛️ **Control Panel**: Publish artifacts and invoke agents from UI
|
|
422
|
+
- 📊 **EventLog Module**: Searchable, sortable event history
|
|
423
|
+
- ⌨️ **Keyboard Shortcuts**: Full accessibility (Ctrl+/ for help)
|
|
424
|
+
- 🔍 **Auto-Filter**: Correlation ID tracking
|
|
425
|
+
|
|
426
|
+
**Graph frameworks:** Basic logging at best. No real-time visualization.
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
### ✅ Advanced Execution Strategies
|
|
431
|
+
|
|
432
|
+
```python
|
|
433
|
+
# Best-of-N execution (run agent 5x, pick best)
|
|
434
|
+
agent.best_of(5, score=lambda r: r.metrics["confidence"])
|
|
435
|
+
|
|
436
|
+
# Exclusive delivery (lease-based, exactly-once)
|
|
437
|
+
agent.consumes(Task, delivery="exclusive")
|
|
438
|
+
|
|
439
|
+
# Batch processing (accumulate 10 items before triggering)
|
|
440
|
+
agent.consumes(Event, batch=BatchSpec(size=10, timeout=timedelta(seconds=30)))
|
|
441
|
+
|
|
442
|
+
# Join operations (wait for multiple artifact types)
|
|
443
|
+
agent.consumes(Review, Rating, join=JoinSpec(within=timedelta(minutes=5)))
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
**Graph frameworks:** None of these patterns exist.
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
## ⚡ Quick Start
|
|
451
|
+
|
|
452
|
+
```bash
|
|
453
|
+
# Install
|
|
454
|
+
pip install flock-flow
|
|
455
|
+
|
|
456
|
+
# Set API key
|
|
457
|
+
export OPENAI_API_KEY="sk-..."
|
|
458
|
+
export DEFAULT_MODEL="openai/gpt-4o"
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
**Your First Blackboard System (60 seconds):**
|
|
462
|
+
|
|
463
|
+
```python
|
|
464
|
+
import asyncio
|
|
465
|
+
from pydantic import BaseModel, Field
|
|
466
|
+
from flock_flow.orchestrator import Flock
|
|
467
|
+
from flock_flow.registry import flock_type
|
|
468
|
+
|
|
469
|
+
# 1. Define typed artifacts
|
|
470
|
+
@flock_type
|
|
471
|
+
class Idea(BaseModel):
|
|
472
|
+
topic: str
|
|
473
|
+
genre: str
|
|
474
|
+
|
|
475
|
+
@flock_type
|
|
476
|
+
class Movie(BaseModel):
|
|
477
|
+
title: str = Field(description="Title in CAPS")
|
|
478
|
+
runtime: int = Field(ge=60, le=400)
|
|
479
|
+
synopsis: str
|
|
480
|
+
|
|
481
|
+
@flock_type
|
|
482
|
+
class Tagline(BaseModel):
|
|
483
|
+
line: str
|
|
484
|
+
|
|
485
|
+
# 2. Create orchestrator (the blackboard)
|
|
486
|
+
orchestrator = Flock("openai/gpt-4o")
|
|
487
|
+
|
|
488
|
+
# 3. Agents subscribe to types (NO workflow graph!)
|
|
489
|
+
movie = (
|
|
490
|
+
orchestrator.agent("movie")
|
|
491
|
+
.description("Generate a compelling movie concept.")
|
|
492
|
+
.consumes(Idea)
|
|
493
|
+
.publishes(Movie)
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
tagline = (
|
|
497
|
+
orchestrator.agent("tagline")
|
|
498
|
+
.description("Write a one-sentence marketing tagline.")
|
|
499
|
+
.consumes(Movie) # Auto-chains after movie!
|
|
500
|
+
.publishes(Tagline)
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
# 4. Run with real-time dashboard
|
|
504
|
+
async def main():
|
|
505
|
+
await orchestrator.serve(dashboard=True)
|
|
506
|
+
|
|
507
|
+
asyncio.run(main())
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
**Publish an artifact:**
|
|
511
|
+
```bash
|
|
512
|
+
curl -X POST http://localhost:8000/api/control/publish \
|
|
513
|
+
-H "Content-Type: application/json" \
|
|
514
|
+
-d '{"type_name": "Idea", "payload": {"topic": "AI cats", "genre": "comedy"}}'
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
**Watch it execute:**
|
|
518
|
+
1. `movie` agent consumes `Idea`, publishes `Movie`
|
|
519
|
+
2. `tagline` agent automatically reacts (subscribed to `Movie`)
|
|
520
|
+
3. Dashboard shows live execution with full lineage
|
|
521
|
+
4. No graph wiring. Just subscriptions.
|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
## 🚀 Enterprise Use Cases
|
|
526
|
+
|
|
527
|
+
### Financial Services: Real-Time Risk Monitoring
|
|
528
|
+
|
|
529
|
+
```python
|
|
530
|
+
# 20+ agents monitoring different market signals
|
|
531
|
+
volatility = orchestrator.agent("volatility").consumes(
|
|
532
|
+
MarketData,
|
|
533
|
+
where=lambda m: m.volatility > 0.5
|
|
534
|
+
).publishes(VolatilityAlert)
|
|
535
|
+
|
|
536
|
+
sentiment = orchestrator.agent("sentiment").consumes(
|
|
537
|
+
NewsArticle,
|
|
538
|
+
text="market crash",
|
|
539
|
+
min_p=0.9
|
|
540
|
+
).publishes(SentimentAlert)
|
|
541
|
+
|
|
542
|
+
# Execution agent waits for BOTH signals
|
|
543
|
+
execute = orchestrator.agent("execute").consumes(
|
|
544
|
+
VolatilityAlert,
|
|
545
|
+
SentimentAlert,
|
|
546
|
+
join=JoinSpec(within=timedelta(minutes=5))
|
|
547
|
+
).publishes(TradeOrder)
|
|
548
|
+
|
|
549
|
+
# Complete audit trail for regulators ✅
|
|
550
|
+
# Multi-agent decision making ✅
|
|
551
|
+
# Real-time risk correlation ✅
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
### Healthcare: Multi-Modal Clinical Decision Support
|
|
557
|
+
|
|
558
|
+
```python
|
|
559
|
+
# Different specialists contribute to diagnosis
|
|
560
|
+
radiology.publishes(
|
|
561
|
+
XRayAnalysis,
|
|
562
|
+
visibility=PrivateVisibility(agents=["diagnosis_agent"]) # HIPAA!
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
lab.publishes(
|
|
566
|
+
LabResults,
|
|
567
|
+
visibility=TenantVisibility(tenant_id="patient_123") # Multi-tenancy!
|
|
568
|
+
)
|
|
569
|
+
|
|
570
|
+
# Diagnostician waits for both inputs
|
|
571
|
+
diagnosis.consumes(XRayAnalysis, LabResults).publishes(
|
|
572
|
+
Diagnosis,
|
|
573
|
+
visibility=PrivateVisibility(agents=["physician", "pharmacist"])
|
|
574
|
+
)
|
|
575
|
+
|
|
576
|
+
# Built-in access controls ✅
|
|
577
|
+
# Full data lineage ✅
|
|
578
|
+
# Compliance-ready ✅
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
---
|
|
582
|
+
|
|
583
|
+
### E-Commerce: 50-Agent Personalization Engine
|
|
584
|
+
|
|
585
|
+
```python
|
|
586
|
+
# Parallel signal analysis (all run concurrently!)
|
|
587
|
+
for signal in ["browsing", "purchase", "reviews", "social", "email", ...]:
|
|
588
|
+
orchestrator.agent(f"{signal}_analyzer").consumes(UserEvent).publishes(Signal)
|
|
589
|
+
|
|
590
|
+
# Recommendation engine consumes ALL signals (batched)
|
|
591
|
+
recommender = orchestrator.agent("recommender").consumes(
|
|
592
|
+
Signal,
|
|
593
|
+
batch=BatchSpec(size=50, timeout=timedelta(seconds=1))
|
|
594
|
+
).publishes(Recommendation)
|
|
595
|
+
|
|
596
|
+
# Add new signal? Just create agent, no graph rewiring ✅
|
|
597
|
+
# Scale to 100+ agents? Linear complexity ✅
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
## 🗺️ Roadmap
|
|
603
|
+
|
|
604
|
+
**✅ Phase 1: Core Framework (DONE - v0.5.00)**
|
|
605
|
+
- [x] Blackboard orchestrator with typed artifacts
|
|
606
|
+
- [x] Sequential + parallel execution
|
|
607
|
+
- [x] Visibility controls (5 types)
|
|
608
|
+
- [x] Real-time dashboard with WebSocket streaming
|
|
609
|
+
- [x] Safety features (circuit breaker, feedback prevention)
|
|
610
|
+
- [x] 743 tests, 77.65% coverage
|
|
611
|
+
|
|
612
|
+
**🚧 Phase 2: Roadmap to 1.0 (Q1 2026)**
|
|
613
|
+
- [ ] **YAML/JSON Serialization** - Export/import full orchestrators
|
|
614
|
+
- [ ] **LLM-Powered Routing** - AI agent selection based on context
|
|
615
|
+
- [ ] **Batch API** - Process DataFrames/CSV files
|
|
616
|
+
- [ ] **Advanced Predicates** - Complex subscription logic
|
|
617
|
+
- [ ] **CLI Tool** - Management console
|
|
618
|
+
- [ ] Persistent blackboard (Redis/Postgres)
|
|
619
|
+
- [ ] Event log replay (Kafka)
|
|
620
|
+
- [ ] Distributed orchestration (multi-region)
|
|
621
|
+
- [ ] OAuth/SSO for dashboard
|
|
622
|
+
- [ ] Audit trail export (compliance)
|
|
623
|
+
|
|
624
|
+
**📅 Phase 3: Post 1.0 ideas**
|
|
625
|
+
- [ ] Migration tool (auto-convert from LangGraph/CrewAI)
|
|
626
|
+
- [ ] Template marketplace
|
|
627
|
+
- [ ] VS Code extension
|
|
628
|
+
|
|
629
|
+
---
|
|
630
|
+
|
|
631
|
+
## 📚 What's Built-In
|
|
632
|
+
|
|
633
|
+
✅ **LLM Provider Support** - LiteLLM (OpenAI, Anthropic, Azure, Google, etc.)
|
|
634
|
+
✅ **DSPy Integration** - Prompt optimization and structured outputs
|
|
635
|
+
✅ **MCP Protocol** - Model Context Protocol servers
|
|
636
|
+
✅ **Tool System** - Function calling with any LLM
|
|
637
|
+
✅ **Pydantic Models** - Type validation with Field constraints
|
|
638
|
+
✅ **Rich Output** - Beautiful console themes
|
|
639
|
+
✅ **FastAPI Service** - Production-grade HTTP API
|
|
640
|
+
✅ **Streaming** - Real-time LLM output
|
|
641
|
+
✅ **Async-First** - True concurrent execution
|
|
642
|
+
|
|
643
|
+
---
|
|
644
|
+
|
|
645
|
+
## 🔬 Production Quality
|
|
646
|
+
|
|
647
|
+
| Metric | Graph Frameworks | Flock 0.5 |
|
|
648
|
+
|--------|------------------|-----------|
|
|
649
|
+
| Test Coverage | Varies | **77.65%** (743 tests) |
|
|
650
|
+
| Critical Path Coverage | Unknown | **86-100%** |
|
|
651
|
+
| E2E Tests | Few | 6 comprehensive scenarios |
|
|
652
|
+
| Safety Features | None/Manual | Circuit breaker, feedback prevention |
|
|
653
|
+
| Real-time Monitoring | None/Basic | WebSocket streaming dashboard |
|
|
654
|
+
| Security | Add-on | 5 built-in visibility types |
|
|
655
|
+
| Documentation | Good | Excellent (AGENTS.md + examples) |
|
|
656
|
+
|
|
657
|
+
---
|
|
658
|
+
|
|
659
|
+
## 🤝 Contributing
|
|
660
|
+
|
|
661
|
+
We're building Flock 0.5 in the open! See [`AGENTS.md`](AGENTS.md) for development setup.
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
git clone https://github.com/whiteducksoftware/flock-flow.git
|
|
665
|
+
cd flock-flow
|
|
666
|
+
uv sync
|
|
667
|
+
uv run pytest # 743 tests pass!
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
---
|
|
671
|
+
|
|
672
|
+
## 💬 Community & Support
|
|
673
|
+
|
|
674
|
+
- **GitHub Issues:** [Report bugs or request features](https://github.com/whiteducksoftware/flock-flow/issues)
|
|
675
|
+
- **Discussions:** [Ask questions or share ideas](https://github.com/whiteducksoftware/flock-flow/discussions)
|
|
676
|
+
- **Documentation:** [Full docs and examples](https://whiteducksoftware.github.io/flock/)
|
|
677
|
+
- **Email:** [support@whiteduck.de](mailto:support@whiteduck.de)
|
|
678
|
+
|
|
679
|
+
---
|
|
680
|
+
|
|
681
|
+
## 🌟 Why "0.5"?
|
|
682
|
+
|
|
683
|
+
We're calling this 0.5 to signal:
|
|
684
|
+
|
|
685
|
+
1. **It's production-ready** - 743 tests, enterprise features, dashboard
|
|
686
|
+
2. **It's still evolving** - Some advanced features coming in Q1/Q2 2026
|
|
687
|
+
3. **It's the future** - Blackboard architecture scales better than graphs
|
|
688
|
+
|
|
689
|
+
**1.0 will arrive** when we've added advanced routing, serialization, and enterprise persistence.
|
|
690
|
+
|
|
691
|
+
---
|
|
692
|
+
|
|
693
|
+
## 🔖 The Bottom Line
|
|
694
|
+
|
|
695
|
+
**Graph-based frameworks** treat agents like nodes in a workflow. Rigid. Sequential. Hard to scale.
|
|
696
|
+
|
|
697
|
+
**Flock 0.5** combines **declarative AI workflows** with **blackboard architecture**:
|
|
698
|
+
- ✅ No brittle prompts (type-safe contracts)
|
|
699
|
+
- ✅ No rigid graphs (opportunistic execution)
|
|
700
|
+
- ✅ No testing nightmares (unit-testable agents)
|
|
701
|
+
- ✅ No security gaps (5 visibility types)
|
|
702
|
+
- ✅ No production fears (743 tests, real-time monitoring)
|
|
703
|
+
|
|
704
|
+
**The future of AI agents isn't workflows—it's declarative blackboards.**
|
|
705
|
+
|
|
706
|
+
**Try it. You'll never go back to graphs.**
|
|
707
|
+
|
|
708
|
+
---
|
|
709
|
+
|
|
710
|
+
<div align="center">
|
|
711
|
+
|
|
712
|
+
**Built with ❤️ by white duck GmbH**
|
|
713
|
+
|
|
714
|
+
**"Agents are just microservices. Let's treat them that way."**
|
|
715
|
+
|
|
716
|
+
[⭐ Star us on GitHub](https://github.com/whiteducksoftware/flock-flow) | [📖 Read the Docs](https://whiteducksoftware.github.io/flock/) | [🚀 Try Examples](examples/)
|
|
717
|
+
|
|
718
|
+
</div>
|
|
719
|
+
|
|
720
|
+
---
|
|
721
|
+
|
|
722
|
+
## 📊 Framework Comparison
|
|
723
|
+
|
|
724
|
+
| | LangGraph | CrewAI | AutoGen | Flock 0.5 |
|
|
725
|
+
|-|-----------|---------|---------|-----------|
|
|
726
|
+
| **Pattern** | Directed Graph | Sequential Tasks | Chat-Based | Blackboard |
|
|
727
|
+
| **Coordination** | Explicit edges | Task context | Messages | Subscriptions |
|
|
728
|
+
| **Parallelism** | Manual (split/join) | None | None | Automatic |
|
|
729
|
+
| **Type Safety** | TypedDict | None | None | Pydantic |
|
|
730
|
+
| **Security** | None | None | None | 5 visibility types |
|
|
731
|
+
| **Conditional** | Route functions | Manual | Manual | `where=lambda` |
|
|
732
|
+
| **Testing** | Full graph | Full crew | Full group | Isolated agents |
|
|
733
|
+
| **Real-time UI** | None | None | None | WebSocket streaming |
|
|
734
|
+
| **Feedback Prevention** | Manual | Manual | Manual | Automatic |
|
|
735
|
+
| **Add Agent** | Rewrite graph | Rewrite tasks | Rewrite group | Just subscribe |
|
|
736
|
+
| **Learning Curve** | Medium | Easy | Easy | Medium |
|
|
737
|
+
| **Scalability** | 10-20 agents | 5-10 agents | 5-10 agents | 100+ agents |
|
|
738
|
+
|
|
739
|
+
---
|
|
740
|
+
|
|
741
|
+
**Last Updated:** October 6, 2025
|
|
742
|
+
**Version:** Flock 0.5.0 (Blackboard Edition) / flock-flow 0.1.20
|
|
743
|
+
**Status:** Production-Ready, Active Development
|
|
744
|
+
|
|
745
|
+
---
|
|
746
|
+
|
|
747
|
+
**"The blackboard pattern has been battle-tested for 50 years. Declarative contracts eliminate prompt hell. Together, they're the future of AI agents."**
|