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
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
# src/flock/core/registry/component_discovery.py
|
|
2
|
-
"""Component discovery and auto-registration functionality."""
|
|
3
|
-
|
|
4
|
-
import importlib
|
|
5
|
-
import importlib.util
|
|
6
|
-
import inspect
|
|
7
|
-
import os
|
|
8
|
-
import pkgutil
|
|
9
|
-
import threading
|
|
10
|
-
from dataclasses import is_dataclass
|
|
11
|
-
from typing import TYPE_CHECKING, Any
|
|
12
|
-
|
|
13
|
-
from pydantic import BaseModel
|
|
14
|
-
from flock.core.logging.logging import get_logger
|
|
15
|
-
|
|
16
|
-
if TYPE_CHECKING:
|
|
17
|
-
from flock.core.registry.registry_hub import RegistryHub
|
|
18
|
-
from flock.core.component.agent_component_base import AgentComponent
|
|
19
|
-
|
|
20
|
-
logger = get_logger("registry.discovery")
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class ComponentDiscovery:
|
|
24
|
-
"""Handles automatic component discovery and registration."""
|
|
25
|
-
|
|
26
|
-
def __init__(self, registry_hub: "RegistryHub"):
|
|
27
|
-
self.registry_hub = registry_hub
|
|
28
|
-
self._packages_to_scan = [
|
|
29
|
-
"flock.tools",
|
|
30
|
-
"flock.components", # Updated to use unified components
|
|
31
|
-
]
|
|
32
|
-
|
|
33
|
-
def discover_and_register_components(self) -> None:
|
|
34
|
-
"""Auto-register components from known core packages."""
|
|
35
|
-
for package_name in self._packages_to_scan:
|
|
36
|
-
try:
|
|
37
|
-
package_spec = importlib.util.find_spec(package_name)
|
|
38
|
-
if package_spec and package_spec.origin:
|
|
39
|
-
package_path_list = [os.path.dirname(package_spec.origin)]
|
|
40
|
-
logger.info(f"Recursively scanning for modules in package: {package_name} (path: {package_path_list[0]})")
|
|
41
|
-
|
|
42
|
-
# Use walk_packages to recursively find all modules
|
|
43
|
-
for module_loader, module_name, is_pkg in pkgutil.walk_packages(
|
|
44
|
-
path=package_path_list,
|
|
45
|
-
prefix=package_name + ".", # Ensures module_name is fully qualified
|
|
46
|
-
onerror=lambda name: logger.warning(f"Error importing module {name} during scan.")
|
|
47
|
-
):
|
|
48
|
-
if not is_pkg and not module_name.split('.')[-1].startswith("_"):
|
|
49
|
-
# We are interested in actual modules, not sub-packages themselves for registration
|
|
50
|
-
# And also skip modules starting with underscore (e.g. __main__.py)
|
|
51
|
-
try:
|
|
52
|
-
logger.debug(f"Attempting to auto-register components from module: {module_name}")
|
|
53
|
-
self.register_module_components(module_name)
|
|
54
|
-
except ImportError as e:
|
|
55
|
-
logger.warning(
|
|
56
|
-
f"Could not auto-register from {module_name}: Module not found or import error: {e}"
|
|
57
|
-
)
|
|
58
|
-
except Exception as e: # Catch other potential errors during registration
|
|
59
|
-
logger.error(
|
|
60
|
-
f"Unexpected error during auto-registration of {module_name}: {e}",
|
|
61
|
-
exc_info=True
|
|
62
|
-
)
|
|
63
|
-
else:
|
|
64
|
-
logger.warning(f"Could not find package spec for '{package_name}' to auto-register components/tools.")
|
|
65
|
-
except Exception as e:
|
|
66
|
-
logger.error(f"Error while trying to dynamically register from '{package_name}': {e}", exc_info=True)
|
|
67
|
-
|
|
68
|
-
def register_module_components(self, module_or_path: Any) -> None:
|
|
69
|
-
"""Scan a module (object or path string) and automatically register.
|
|
70
|
-
|
|
71
|
-
- Functions as callables.
|
|
72
|
-
- Pydantic Models and Dataclasses as types.
|
|
73
|
-
- Subclasses of AgentComponent as components.
|
|
74
|
-
"""
|
|
75
|
-
try:
|
|
76
|
-
if isinstance(module_or_path, str):
|
|
77
|
-
module = importlib.import_module(module_or_path)
|
|
78
|
-
elif inspect.ismodule(module_or_path):
|
|
79
|
-
module = module_or_path
|
|
80
|
-
else:
|
|
81
|
-
logger.error(
|
|
82
|
-
f"Invalid input for auto-registration: {module_or_path}. Must be module object or path string."
|
|
83
|
-
)
|
|
84
|
-
return
|
|
85
|
-
|
|
86
|
-
logger.info(f"Auto-registering components from module: {module.__name__}")
|
|
87
|
-
registered_count = {"callable": 0, "type": 0, "component": 0}
|
|
88
|
-
|
|
89
|
-
for name, obj in inspect.getmembers(module):
|
|
90
|
-
if name.startswith("_"):
|
|
91
|
-
continue # Skip private/internal
|
|
92
|
-
|
|
93
|
-
# Register Functions as Callables
|
|
94
|
-
if (
|
|
95
|
-
inspect.isfunction(obj)
|
|
96
|
-
and obj.__module__ == module.__name__
|
|
97
|
-
):
|
|
98
|
-
if self.registry_hub.callables.register_callable(obj):
|
|
99
|
-
registered_count["callable"] += 1
|
|
100
|
-
|
|
101
|
-
# Register Classes (Types and Components)
|
|
102
|
-
elif inspect.isclass(obj) and obj.__module__ == module.__name__:
|
|
103
|
-
is_component = False
|
|
104
|
-
|
|
105
|
-
# Register as Component if subclass of AgentComponent
|
|
106
|
-
try:
|
|
107
|
-
from flock.core.component.agent_component_base import AgentComponent
|
|
108
|
-
if (
|
|
109
|
-
issubclass(obj, AgentComponent)
|
|
110
|
-
and self.registry_hub.components.register_component(obj)
|
|
111
|
-
):
|
|
112
|
-
registered_count["component"] += 1
|
|
113
|
-
is_component = True # Mark as component
|
|
114
|
-
except ImportError:
|
|
115
|
-
# AgentComponent not available during setup
|
|
116
|
-
pass
|
|
117
|
-
|
|
118
|
-
# Register as Type if Pydantic Model or Dataclass
|
|
119
|
-
# A component can also be a type used in signatures
|
|
120
|
-
base_model_or_dataclass = isinstance(obj, type) and (
|
|
121
|
-
issubclass(obj, BaseModel) or is_dataclass(obj)
|
|
122
|
-
)
|
|
123
|
-
if (
|
|
124
|
-
base_model_or_dataclass
|
|
125
|
-
and self.registry_hub.types.register_type(obj)
|
|
126
|
-
and not is_component
|
|
127
|
-
):
|
|
128
|
-
# Only increment type count if it wasn't already counted as component
|
|
129
|
-
registered_count["type"] += 1
|
|
130
|
-
|
|
131
|
-
logger.info(
|
|
132
|
-
f"Auto-registration summary for {module.__name__}: "
|
|
133
|
-
f"{registered_count['callable']} callables, "
|
|
134
|
-
f"{registered_count['type']} types, "
|
|
135
|
-
f"{registered_count['component']} components."
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
except Exception as e:
|
|
139
|
-
logger.error(
|
|
140
|
-
f"Error during auto-registration for {module_or_path}: {e}",
|
|
141
|
-
exc_info=True,
|
|
142
|
-
)
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# src/flock/core/registry/component_registry.py
|
|
2
|
-
"""Component class registration and lookup functionality."""
|
|
3
|
-
|
|
4
|
-
import threading
|
|
5
|
-
from typing import TYPE_CHECKING, Any
|
|
6
|
-
|
|
7
|
-
from flock.core.logging.logging import get_logger
|
|
8
|
-
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from flock.core.component.agent_component_base import AgentComponent
|
|
11
|
-
|
|
12
|
-
logger = get_logger("registry.components")
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ComponentRegistry:
|
|
16
|
-
"""Manages component class registration and lookup with thread safety."""
|
|
17
|
-
|
|
18
|
-
def __init__(self, lock: threading.RLock):
|
|
19
|
-
self._lock = lock
|
|
20
|
-
self._components: dict[str, type] = {}
|
|
21
|
-
|
|
22
|
-
def register_component(self, component_class: type, name: str | None = None) -> str | None:
|
|
23
|
-
"""Register a component class (evaluation, routing, utility components)."""
|
|
24
|
-
type_name = name or component_class.__name__
|
|
25
|
-
if not type_name:
|
|
26
|
-
logger.error(f"Could not determine name for component class: {component_class}")
|
|
27
|
-
return None
|
|
28
|
-
|
|
29
|
-
with self._lock:
|
|
30
|
-
if type_name in self._components and self._components[type_name] != component_class:
|
|
31
|
-
logger.warning(f"Component class '{type_name}' already registered. Overwriting.")
|
|
32
|
-
|
|
33
|
-
self._components[type_name] = component_class
|
|
34
|
-
logger.debug(f"Registered component class: {type_name}")
|
|
35
|
-
return type_name
|
|
36
|
-
|
|
37
|
-
def get_component(self, type_name: str) -> type:
|
|
38
|
-
"""Retrieve a component class by its type name."""
|
|
39
|
-
with self._lock:
|
|
40
|
-
if type_name in self._components:
|
|
41
|
-
return self._components[type_name]
|
|
42
|
-
|
|
43
|
-
logger.error(f"Component class '{type_name}' not found in registry.")
|
|
44
|
-
raise KeyError(f"Component class '{type_name}' not found. Ensure it is registered.")
|
|
45
|
-
|
|
46
|
-
def get_component_type_name(self, component_class: type) -> str | None:
|
|
47
|
-
"""Get the type name for a component class, registering it if necessary."""
|
|
48
|
-
with self._lock:
|
|
49
|
-
for type_name, registered_class in self._components.items():
|
|
50
|
-
if component_class == registered_class:
|
|
51
|
-
return type_name
|
|
52
|
-
# If not found, register using class name and return
|
|
53
|
-
return self.register_component(component_class)
|
|
54
|
-
|
|
55
|
-
def get_all_components(self) -> dict[str, type]:
|
|
56
|
-
"""Get all registered components."""
|
|
57
|
-
with self._lock:
|
|
58
|
-
return self._components.copy()
|
|
59
|
-
|
|
60
|
-
def clear(self) -> None:
|
|
61
|
-
"""Clear all registered components."""
|
|
62
|
-
with self._lock:
|
|
63
|
-
self._components.clear()
|
|
64
|
-
logger.debug("Cleared all registered components")
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# src/flock/core/registry/config_mapping.py
|
|
2
|
-
"""Config-to-component mapping functionality."""
|
|
3
|
-
|
|
4
|
-
import threading
|
|
5
|
-
from typing import TypeVar
|
|
6
|
-
|
|
7
|
-
from pydantic import BaseModel
|
|
8
|
-
from flock.core.logging.logging import get_logger
|
|
9
|
-
|
|
10
|
-
logger = get_logger("registry.config_mapping")
|
|
11
|
-
|
|
12
|
-
ConfigType = TypeVar("ConfigType", bound=BaseModel)
|
|
13
|
-
ClassType = TypeVar("ClassType", bound=type)
|
|
14
|
-
|
|
15
|
-
# Global config mapping with thread safety
|
|
16
|
-
_component_config_map: dict[type[BaseModel], type] = {}
|
|
17
|
-
_config_map_lock = threading.RLock()
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class ConfigMapping:
|
|
21
|
-
"""Manages config-to-component mappings with thread safety."""
|
|
22
|
-
|
|
23
|
-
def __init__(self, lock: threading.RLock):
|
|
24
|
-
self._lock = lock
|
|
25
|
-
|
|
26
|
-
def register_config_component_pair(
|
|
27
|
-
self, config_cls: type[ConfigType], component_cls: type[ClassType]
|
|
28
|
-
) -> None:
|
|
29
|
-
"""Explicitly register the mapping between a config and component class."""
|
|
30
|
-
# Component config validation can be added here if needed
|
|
31
|
-
# Add more checks if needed (e.g., component_cls inherits from Module/Router/Evaluator)
|
|
32
|
-
|
|
33
|
-
with _config_map_lock:
|
|
34
|
-
if (
|
|
35
|
-
config_cls in _component_config_map
|
|
36
|
-
and _component_config_map[config_cls] != component_cls
|
|
37
|
-
):
|
|
38
|
-
logger.warning(
|
|
39
|
-
f"Config class {config_cls.__name__} already mapped to {_component_config_map[config_cls].__name__}. "
|
|
40
|
-
f"Overwriting with {component_cls.__name__}."
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
_component_config_map[config_cls] = component_cls
|
|
44
|
-
logger.debug(
|
|
45
|
-
f"Registered config mapping: {config_cls.__name__} -> {component_cls.__name__}"
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
def get_component_class_for_config(
|
|
49
|
-
self, config_cls: type[ConfigType]
|
|
50
|
-
) -> type[ClassType] | None:
|
|
51
|
-
"""Look up the Component Class associated with a Config Class."""
|
|
52
|
-
with _config_map_lock:
|
|
53
|
-
return _component_config_map.get(config_cls)
|
|
54
|
-
|
|
55
|
-
def get_all_config_mappings(self) -> dict[type[BaseModel], type]:
|
|
56
|
-
"""Get all config-to-component mappings."""
|
|
57
|
-
with _config_map_lock:
|
|
58
|
-
return _component_config_map.copy()
|
|
59
|
-
|
|
60
|
-
def clear_config_mappings(self) -> None:
|
|
61
|
-
"""Clear all config-to-component mappings."""
|
|
62
|
-
with _config_map_lock:
|
|
63
|
-
_component_config_map.clear()
|
|
64
|
-
logger.debug("Cleared all config-to-component mappings")
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
# src/flock/core/registry/decorators.py
|
|
2
|
-
"""Registry decorators for component, tool, and type registration."""
|
|
3
|
-
|
|
4
|
-
import inspect
|
|
5
|
-
from collections.abc import Callable
|
|
6
|
-
from typing import Any, TypeVar, overload
|
|
7
|
-
|
|
8
|
-
from flock.core.registry.registry_hub import get_registry
|
|
9
|
-
|
|
10
|
-
ClassType = TypeVar("ClassType", bound=type)
|
|
11
|
-
FuncType = TypeVar("FuncType", bound=Callable)
|
|
12
|
-
ConfigType = TypeVar("ConfigType")
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
# --- Component Registration Decorator ---
|
|
16
|
-
|
|
17
|
-
@overload
|
|
18
|
-
def flock_component(cls: ClassType) -> ClassType: ... # Basic registration
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@overload
|
|
22
|
-
def flock_component(
|
|
23
|
-
*, name: str | None = None, config_class: type[ConfigType] | None = None
|
|
24
|
-
) -> Callable[[ClassType], ClassType]: ... # With options
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def flock_component(
|
|
28
|
-
cls: ClassType | None = None,
|
|
29
|
-
*,
|
|
30
|
-
name: str | None = None,
|
|
31
|
-
config_class: type[ConfigType] | None = None,
|
|
32
|
-
) -> Any:
|
|
33
|
-
"""Decorator to register a Flock Component class and optionally link its config class."""
|
|
34
|
-
registry = get_registry()
|
|
35
|
-
|
|
36
|
-
def decorator(inner_cls: ClassType) -> ClassType:
|
|
37
|
-
if not inspect.isclass(inner_cls):
|
|
38
|
-
raise TypeError("@flock_component can only decorate classes.")
|
|
39
|
-
|
|
40
|
-
component_name = name or inner_cls.__name__
|
|
41
|
-
registry.register_component(inner_cls, name=component_name)
|
|
42
|
-
|
|
43
|
-
# If config_class is provided, register the mapping
|
|
44
|
-
if config_class:
|
|
45
|
-
registry.register_config_component_pair(config_class, inner_cls)
|
|
46
|
-
|
|
47
|
-
return inner_cls
|
|
48
|
-
|
|
49
|
-
if cls is None:
|
|
50
|
-
# Called as @flock_component(name="...", config_class=...)
|
|
51
|
-
return decorator
|
|
52
|
-
else:
|
|
53
|
-
# Called as @flock_component
|
|
54
|
-
return decorator(cls)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
# --- Tool/Callable Registration Decorator ---
|
|
58
|
-
|
|
59
|
-
@overload
|
|
60
|
-
def flock_tool(func: FuncType) -> FuncType: ...
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
@overload
|
|
64
|
-
def flock_tool(
|
|
65
|
-
*, name: str | None = None
|
|
66
|
-
) -> Callable[[FuncType], FuncType]: ...
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def flock_tool(func: FuncType | None = None, *, name: str | None = None) -> Any:
|
|
70
|
-
"""Decorator to register a callable function/method as a Tool (or general callable).
|
|
71
|
-
|
|
72
|
-
Usage:
|
|
73
|
-
@flock_tool
|
|
74
|
-
def my_web_search(query: str): ...
|
|
75
|
-
|
|
76
|
-
@flock_tool(name="utils.calculate_pi")
|
|
77
|
-
def compute_pi(): ...
|
|
78
|
-
"""
|
|
79
|
-
registry = get_registry()
|
|
80
|
-
|
|
81
|
-
def decorator(inner_func: FuncType) -> FuncType:
|
|
82
|
-
if not callable(inner_func):
|
|
83
|
-
raise TypeError("@flock_tool can only decorate callables.")
|
|
84
|
-
# Let registry handle default name generation if None
|
|
85
|
-
registry.register_callable(inner_func, name=name)
|
|
86
|
-
return inner_func
|
|
87
|
-
|
|
88
|
-
if func is None:
|
|
89
|
-
# Called as @flock_tool(name="...")
|
|
90
|
-
return decorator
|
|
91
|
-
else:
|
|
92
|
-
# Called as @flock_tool
|
|
93
|
-
return decorator(func)
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
# Alias for clarity
|
|
97
|
-
flock_callable = flock_tool
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
# --- Type Registration Decorator ---
|
|
101
|
-
|
|
102
|
-
@overload
|
|
103
|
-
def flock_type(cls: ClassType) -> ClassType: ...
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
@overload
|
|
107
|
-
def flock_type(
|
|
108
|
-
*, name: str | None = None
|
|
109
|
-
) -> Callable[[ClassType], ClassType]: ...
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
def flock_type(cls: ClassType | None = None, *, name: str | None = None) -> Any:
|
|
113
|
-
"""Decorator to register a Type (Pydantic Model, Dataclass) used in signatures.
|
|
114
|
-
|
|
115
|
-
Usage:
|
|
116
|
-
@flock_type
|
|
117
|
-
class MyDataModel(BaseModel): ...
|
|
118
|
-
|
|
119
|
-
@flock_type(name="UserInput")
|
|
120
|
-
@dataclass
|
|
121
|
-
class UserQuery: ...
|
|
122
|
-
"""
|
|
123
|
-
registry = get_registry()
|
|
124
|
-
|
|
125
|
-
def decorator(inner_cls: ClassType) -> ClassType:
|
|
126
|
-
if not inspect.isclass(inner_cls):
|
|
127
|
-
raise TypeError("@flock_type can only decorate classes.")
|
|
128
|
-
type_name = name or inner_cls.__name__
|
|
129
|
-
registry.register_type(inner_cls, name=type_name)
|
|
130
|
-
return inner_cls
|
|
131
|
-
|
|
132
|
-
if cls is None:
|
|
133
|
-
# Called as @flock_type(name="...")
|
|
134
|
-
return decorator
|
|
135
|
-
else:
|
|
136
|
-
# Called as @flock_type
|
|
137
|
-
return decorator(cls)
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
# src/flock/core/registry/registry_hub.py
|
|
2
|
-
"""Main registry hub using composition pattern with thread safety."""
|
|
3
|
-
|
|
4
|
-
import threading
|
|
5
|
-
from typing import TYPE_CHECKING, Any, TypeVar
|
|
6
|
-
|
|
7
|
-
from flock.core.logging.logging import get_logger
|
|
8
|
-
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from collections.abc import Callable
|
|
11
|
-
|
|
12
|
-
from flock.core.flock_agent import FlockAgent
|
|
13
|
-
from flock.core.mcp.flock_mcp_server import FlockMCPServer
|
|
14
|
-
|
|
15
|
-
logger = get_logger("registry.hub")
|
|
16
|
-
|
|
17
|
-
T = TypeVar("T")
|
|
18
|
-
ConfigType = TypeVar("ConfigType")
|
|
19
|
-
ClassType = TypeVar("ClassType")
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class RegistryHub:
|
|
23
|
-
"""Thread-safe registry hub using composition pattern.
|
|
24
|
-
|
|
25
|
-
Main coordinator for all registry types following the successful
|
|
26
|
-
pattern from Flock and FlockAgent refactoring.
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
def __init__(self):
|
|
30
|
-
self._lock = threading.RLock()
|
|
31
|
-
logger.debug("RegistryHub initialized with thread safety")
|
|
32
|
-
|
|
33
|
-
# --- Lazy-loaded composition helpers (following Flock pattern) ---
|
|
34
|
-
|
|
35
|
-
@property
|
|
36
|
-
def components(self):
|
|
37
|
-
"""Component class registry helper."""
|
|
38
|
-
if not hasattr(self, '_components_helper'):
|
|
39
|
-
from flock.core.registry.component_registry import ComponentRegistry
|
|
40
|
-
self._components_helper = ComponentRegistry(self._lock)
|
|
41
|
-
return self._components_helper
|
|
42
|
-
|
|
43
|
-
@property
|
|
44
|
-
def callables(self):
|
|
45
|
-
"""Callable registry helper."""
|
|
46
|
-
if not hasattr(self, '_callables_helper'):
|
|
47
|
-
from flock.core.registry.callable_registry import CallableRegistry
|
|
48
|
-
self._callables_helper = CallableRegistry(self._lock)
|
|
49
|
-
return self._callables_helper
|
|
50
|
-
|
|
51
|
-
@property
|
|
52
|
-
def agents(self):
|
|
53
|
-
"""Agent registry helper."""
|
|
54
|
-
if not hasattr(self, '_agents_helper'):
|
|
55
|
-
from flock.core.registry.agent_registry import AgentRegistry
|
|
56
|
-
self._agents_helper = AgentRegistry(self._lock)
|
|
57
|
-
return self._agents_helper
|
|
58
|
-
|
|
59
|
-
@property
|
|
60
|
-
def servers(self):
|
|
61
|
-
"""Server registry helper."""
|
|
62
|
-
if not hasattr(self, '_servers_helper'):
|
|
63
|
-
from flock.core.registry.server_registry import ServerRegistry
|
|
64
|
-
self._servers_helper = ServerRegistry(self._lock)
|
|
65
|
-
return self._servers_helper
|
|
66
|
-
|
|
67
|
-
@property
|
|
68
|
-
def types(self):
|
|
69
|
-
"""Type registry helper."""
|
|
70
|
-
if not hasattr(self, '_types_helper'):
|
|
71
|
-
from flock.core.registry.type_registry import TypeRegistry
|
|
72
|
-
self._types_helper = TypeRegistry(self._lock)
|
|
73
|
-
return self._types_helper
|
|
74
|
-
|
|
75
|
-
@property
|
|
76
|
-
def config_mapping(self):
|
|
77
|
-
"""Config mapping helper."""
|
|
78
|
-
if not hasattr(self, '_config_mapping_helper'):
|
|
79
|
-
from flock.core.registry.config_mapping import ConfigMapping
|
|
80
|
-
self._config_mapping_helper = ConfigMapping(self._lock)
|
|
81
|
-
return self._config_mapping_helper
|
|
82
|
-
|
|
83
|
-
@property
|
|
84
|
-
def discovery(self):
|
|
85
|
-
"""Component discovery helper."""
|
|
86
|
-
if not hasattr(self, '_discovery_helper'):
|
|
87
|
-
from flock.core.registry.component_discovery import (
|
|
88
|
-
ComponentDiscovery,
|
|
89
|
-
)
|
|
90
|
-
self._discovery_helper = ComponentDiscovery(self)
|
|
91
|
-
return self._discovery_helper
|
|
92
|
-
|
|
93
|
-
# --- High-level registry operations (delegate to helpers) ---
|
|
94
|
-
|
|
95
|
-
def register_agent(self, agent: "FlockAgent", *, force: bool = False) -> None:
|
|
96
|
-
"""Register a FlockAgent instance."""
|
|
97
|
-
self.agents.register_agent(agent, force=force)
|
|
98
|
-
|
|
99
|
-
def get_agent(self, name: str) -> "FlockAgent | None":
|
|
100
|
-
"""Get a registered FlockAgent instance by name."""
|
|
101
|
-
return self.agents.get_agent(name)
|
|
102
|
-
|
|
103
|
-
def get_all_agent_names(self) -> list[str]:
|
|
104
|
-
"""Get all registered agent names."""
|
|
105
|
-
return self.agents.get_all_agent_names()
|
|
106
|
-
|
|
107
|
-
def register_server(self, server: "FlockMCPServer") -> None:
|
|
108
|
-
"""Register a FlockMCPServer instance."""
|
|
109
|
-
self.servers.register_server(server)
|
|
110
|
-
|
|
111
|
-
def get_server(self, name: str) -> "FlockMCPServer | None":
|
|
112
|
-
"""Get a registered FlockMCPServer instance by name."""
|
|
113
|
-
return self.servers.get_server(name)
|
|
114
|
-
|
|
115
|
-
def get_all_server_names(self) -> list[str]:
|
|
116
|
-
"""Get all registered server names."""
|
|
117
|
-
return self.servers.get_all_server_names()
|
|
118
|
-
|
|
119
|
-
def register_callable(self, func: "Callable", name: str | None = None) -> str | None:
|
|
120
|
-
"""Register a callable function/method."""
|
|
121
|
-
return self.callables.register_callable(func, name)
|
|
122
|
-
|
|
123
|
-
def get_callable(self, name_or_path: str) -> "Callable":
|
|
124
|
-
"""Get a registered callable by name or path."""
|
|
125
|
-
return self.callables.get_callable(name_or_path)
|
|
126
|
-
|
|
127
|
-
def get_callable_path_string(self, func: "Callable") -> str | None:
|
|
128
|
-
"""Get the path string for a callable."""
|
|
129
|
-
return self.callables.get_callable_path_string(func)
|
|
130
|
-
|
|
131
|
-
def register_type(self, type_obj: type, name: str | None = None) -> str | None:
|
|
132
|
-
"""Register a type (Pydantic Model, Dataclass, etc.)."""
|
|
133
|
-
return self.types.register_type(type_obj, name)
|
|
134
|
-
|
|
135
|
-
def get_type(self, type_name: str) -> type:
|
|
136
|
-
"""Get a registered type by name."""
|
|
137
|
-
return self.types.get_type(type_name)
|
|
138
|
-
|
|
139
|
-
def register_component(self, component_class: type, name: str | None = None) -> str | None:
|
|
140
|
-
"""Register a component class."""
|
|
141
|
-
return self.components.register_component(component_class, name)
|
|
142
|
-
|
|
143
|
-
def get_component(self, type_name: str) -> type:
|
|
144
|
-
"""Get a registered component class by name."""
|
|
145
|
-
return self.components.get_component(type_name)
|
|
146
|
-
|
|
147
|
-
def get_component_type_name(self, component_class: type) -> str | None:
|
|
148
|
-
"""Get the type name for a component class."""
|
|
149
|
-
return self.components.get_component_type_name(component_class)
|
|
150
|
-
|
|
151
|
-
def register_config_component_pair(self, config_cls: type[ConfigType], component_cls: type[ClassType]) -> None:
|
|
152
|
-
"""Register a config-to-component mapping."""
|
|
153
|
-
self.config_mapping.register_config_component_pair(config_cls, component_cls)
|
|
154
|
-
|
|
155
|
-
def get_component_class_for_config(self, config_cls: type[ConfigType]) -> type[ClassType] | None:
|
|
156
|
-
"""Get the component class for a config class."""
|
|
157
|
-
return self.config_mapping.get_component_class_for_config(config_cls)
|
|
158
|
-
|
|
159
|
-
def discover_and_register_components(self) -> None:
|
|
160
|
-
"""Auto-discover and register components from known packages."""
|
|
161
|
-
self.discovery.discover_and_register_components()
|
|
162
|
-
|
|
163
|
-
def register_module_components(self, module_or_path: Any) -> None:
|
|
164
|
-
"""Register components from a specific module."""
|
|
165
|
-
self.discovery.register_module_components(module_or_path)
|
|
166
|
-
|
|
167
|
-
# --- Utility methods ---
|
|
168
|
-
|
|
169
|
-
def clear_all(self) -> None:
|
|
170
|
-
"""Clear all registries (useful for testing)."""
|
|
171
|
-
with self._lock:
|
|
172
|
-
if hasattr(self, '_agents_helper'):
|
|
173
|
-
self.agents.clear()
|
|
174
|
-
if hasattr(self, '_servers_helper'):
|
|
175
|
-
self.servers.clear()
|
|
176
|
-
if hasattr(self, '_callables_helper'):
|
|
177
|
-
self.callables.clear()
|
|
178
|
-
if hasattr(self, '_types_helper'):
|
|
179
|
-
self.types.clear()
|
|
180
|
-
if hasattr(self, '_components_helper'):
|
|
181
|
-
self.components.clear()
|
|
182
|
-
if hasattr(self, '_config_mapping_helper'):
|
|
183
|
-
self.config_mapping.clear_config_mappings()
|
|
184
|
-
logger.debug("Cleared all registries")
|
|
185
|
-
|
|
186
|
-
def get_registry_summary(self) -> dict[str, int]:
|
|
187
|
-
"""Get a summary of all registries."""
|
|
188
|
-
with self._lock:
|
|
189
|
-
return {
|
|
190
|
-
"agents": len(self.agents.get_all_agents()),
|
|
191
|
-
"servers": len(self.servers.get_all_servers()),
|
|
192
|
-
"callables": len(self.callables.get_all_callables()),
|
|
193
|
-
"types": len(self.types.get_all_types()),
|
|
194
|
-
"components": len(self.components.get_all_components()),
|
|
195
|
-
"config_mappings": len(self.config_mapping.get_all_config_mappings()),
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
# --- Global singleton instance ---
|
|
200
|
-
_default_registry_hub = RegistryHub()
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
def get_registry() -> RegistryHub:
|
|
204
|
-
"""Get the default thread-safe registry hub instance."""
|
|
205
|
-
return _default_registry_hub
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# src/flock/core/registry/server_registry.py
|
|
2
|
-
"""MCP Server registration and lookup functionality."""
|
|
3
|
-
|
|
4
|
-
import threading
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
6
|
-
|
|
7
|
-
from flock.core.logging.logging import get_logger
|
|
8
|
-
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from flock.core.mcp.flock_mcp_server import FlockMCPServer
|
|
11
|
-
|
|
12
|
-
logger = get_logger("registry.servers")
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ServerRegistry:
|
|
16
|
-
"""Manages FlockMCPServerBase registration and lookup with thread safety."""
|
|
17
|
-
|
|
18
|
-
def __init__(self, lock: threading.RLock):
|
|
19
|
-
self._lock = lock
|
|
20
|
-
self._servers: dict[str, FlockMCPServer] = {}
|
|
21
|
-
|
|
22
|
-
def register_server(self, server: "FlockMCPServer") -> None:
|
|
23
|
-
"""Register a flock mcp server by its name."""
|
|
24
|
-
if not hasattr(server.config, "name") or not server.config.name:
|
|
25
|
-
logger.error("Attempted to register a server without a valid 'name' attribute.")
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
with self._lock:
|
|
29
|
-
if server.config.name in self._servers and self._servers[server.config.name] != server:
|
|
30
|
-
logger.warning(f"Server '{server.config.name}' already registered. Overwriting.")
|
|
31
|
-
|
|
32
|
-
self._servers[server.config.name] = server
|
|
33
|
-
logger.debug(f"Registered server: {server.config.name}")
|
|
34
|
-
|
|
35
|
-
def get_server(self, name: str) -> "FlockMCPServer | None":
|
|
36
|
-
"""Retrieve a registered FlockMCPServer instance by name."""
|
|
37
|
-
with self._lock:
|
|
38
|
-
server = self._servers.get(name)
|
|
39
|
-
if not server:
|
|
40
|
-
logger.warning(f"Server '{name}' not found in registry.")
|
|
41
|
-
return server
|
|
42
|
-
|
|
43
|
-
def get_all_server_names(self) -> list[str]:
|
|
44
|
-
"""Return a list of names for all registered servers."""
|
|
45
|
-
with self._lock:
|
|
46
|
-
return list(self._servers.keys())
|
|
47
|
-
|
|
48
|
-
def get_all_servers(self) -> dict[str, "FlockMCPServer"]:
|
|
49
|
-
"""Get all registered servers."""
|
|
50
|
-
with self._lock:
|
|
51
|
-
return self._servers.copy()
|
|
52
|
-
|
|
53
|
-
def clear(self) -> None:
|
|
54
|
-
"""Clear all registered servers."""
|
|
55
|
-
with self._lock:
|
|
56
|
-
self._servers.clear()
|
|
57
|
-
logger.debug("Cleared all registered servers")
|