flock-core 0.4.520__py3-none-any.whl → 0.5.0b2__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/cli/manage_agents.py +3 -3
- flock/components/__init__.py +28 -0
- flock/components/evaluation/__init__.py +9 -0
- flock/components/evaluation/declarative_evaluation_component.py +198 -0
- flock/components/routing/__init__.py +15 -0
- flock/{routers/conditional/conditional_router.py → components/routing/conditional_routing_component.py} +60 -49
- flock/components/routing/default_routing_component.py +103 -0
- flock/components/routing/llm_routing_component.py +208 -0
- flock/components/utility/__init__.py +15 -0
- flock/{modules/enterprise_memory/enterprise_memory_module.py → components/utility/memory_utility_component.py} +195 -173
- flock/{modules/performance/metrics_module.py → components/utility/metrics_utility_component.py} +101 -86
- flock/{modules/output/output_module.py → components/utility/output_utility_component.py} +49 -49
- flock/core/__init__.py +2 -8
- flock/core/agent/__init__.py +16 -0
- flock/core/agent/flock_agent_components.py +104 -0
- flock/core/agent/flock_agent_execution.py +101 -0
- flock/core/agent/flock_agent_integration.py +147 -0
- flock/core/agent/flock_agent_lifecycle.py +177 -0
- flock/core/agent/flock_agent_serialization.py +378 -0
- flock/core/component/__init__.py +15 -0
- flock/core/{flock_module.py → component/agent_component_base.py} +136 -35
- flock/core/component/evaluation_component_base.py +56 -0
- flock/core/component/routing_component_base.py +75 -0
- flock/core/component/utility_component_base.py +69 -0
- flock/core/config/flock_agent_config.py +49 -2
- flock/core/evaluation/utils.py +1 -1
- flock/core/execution/evaluation_executor.py +1 -1
- flock/core/flock.py +137 -483
- flock/core/flock_agent.py +151 -1018
- flock/core/flock_factory.py +94 -73
- flock/core/{flock_registry.py → flock_registry.py.backup} +3 -17
- flock/core/logging/logging.py +1 -0
- flock/core/mcp/flock_mcp_server.py +42 -37
- flock/core/mixin/dspy_integration.py +5 -5
- flock/core/orchestration/__init__.py +18 -0
- flock/core/orchestration/flock_batch_processor.py +94 -0
- flock/core/orchestration/flock_evaluator.py +113 -0
- flock/core/orchestration/flock_execution.py +288 -0
- flock/core/orchestration/flock_initialization.py +125 -0
- flock/core/orchestration/flock_server_manager.py +65 -0
- flock/core/orchestration/flock_web_server.py +117 -0
- flock/core/registry/__init__.py +39 -0
- flock/core/registry/agent_registry.py +69 -0
- flock/core/registry/callable_registry.py +139 -0
- flock/core/registry/component_discovery.py +142 -0
- flock/core/registry/component_registry.py +64 -0
- flock/core/registry/config_mapping.py +64 -0
- flock/core/registry/decorators.py +137 -0
- flock/core/registry/registry_hub.py +202 -0
- flock/core/registry/server_registry.py +57 -0
- flock/core/registry/type_registry.py +86 -0
- flock/core/serialization/flock_serializer.py +33 -30
- flock/core/serialization/serialization_utils.py +28 -25
- flock/core/util/input_resolver.py +29 -2
- flock/platform/docker_tools.py +3 -3
- flock/tools/markdown_tools.py +1 -2
- flock/tools/text_tools.py +1 -2
- flock/webapp/app/main.py +9 -5
- flock/workflow/activities.py +59 -84
- flock/workflow/activities_unified.py +230 -0
- flock/workflow/agent_execution_activity.py +6 -6
- flock/workflow/flock_workflow.py +1 -1
- {flock_core-0.4.520.dist-info → flock_core-0.5.0b2.dist-info}/METADATA +2 -2
- {flock_core-0.4.520.dist-info → flock_core-0.5.0b2.dist-info}/RECORD +67 -68
- flock/core/flock_evaluator.py +0 -60
- flock/core/flock_router.py +0 -83
- flock/evaluators/__init__.py +0 -1
- flock/evaluators/declarative/__init__.py +0 -1
- flock/evaluators/declarative/declarative_evaluator.py +0 -194
- flock/evaluators/memory/memory_evaluator.py +0 -90
- flock/evaluators/test/test_case_evaluator.py +0 -38
- flock/evaluators/zep/zep_evaluator.py +0 -59
- flock/modules/__init__.py +0 -1
- flock/modules/assertion/__init__.py +0 -1
- flock/modules/assertion/assertion_module.py +0 -286
- flock/modules/callback/__init__.py +0 -1
- flock/modules/callback/callback_module.py +0 -91
- flock/modules/enterprise_memory/README.md +0 -99
- flock/modules/mem0/__init__.py +0 -1
- flock/modules/mem0/mem0_module.py +0 -126
- flock/modules/mem0_async/__init__.py +0 -1
- flock/modules/mem0_async/async_mem0_module.py +0 -126
- flock/modules/memory/__init__.py +0 -1
- flock/modules/memory/memory_module.py +0 -429
- flock/modules/memory/memory_parser.py +0 -125
- flock/modules/memory/memory_storage.py +0 -736
- flock/modules/output/__init__.py +0 -1
- flock/modules/performance/__init__.py +0 -1
- flock/modules/zep/__init__.py +0 -1
- flock/modules/zep/zep_module.py +0 -192
- flock/routers/__init__.py +0 -1
- flock/routers/agent/__init__.py +0 -1
- flock/routers/agent/agent_router.py +0 -236
- flock/routers/agent/handoff_agent.py +0 -58
- flock/routers/default/__init__.py +0 -1
- flock/routers/default/default_router.py +0 -80
- flock/routers/feedback/feedback_router.py +0 -114
- flock/routers/list_generator/list_generator_router.py +0 -166
- flock/routers/llm/__init__.py +0 -1
- flock/routers/llm/llm_router.py +0 -365
- {flock_core-0.4.520.dist-info → flock_core-0.5.0b2.dist-info}/WHEEL +0 -0
- {flock_core-0.4.520.dist-info → flock_core-0.5.0b2.dist-info}/entry_points.txt +0 -0
- {flock_core-0.4.520.dist-info → flock_core-0.5.0b2.dist-info}/licenses/LICENSE +0 -0
flock/core/flock_factory.py
CHANGED
|
@@ -8,6 +8,13 @@ from typing import Any, Literal
|
|
|
8
8
|
import httpx
|
|
9
9
|
from pydantic import AnyUrl, BaseModel, ConfigDict, Field, FileUrl
|
|
10
10
|
|
|
11
|
+
from flock.components.utility.metrics_utility_component import (
|
|
12
|
+
MetricsUtilityComponent,
|
|
13
|
+
MetricsUtilityConfig,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
# New unified components imported locally to avoid circular imports
|
|
17
|
+
from flock.core.config.flock_agent_config import FlockAgentConfig
|
|
11
18
|
from flock.core.config.scheduled_agent_config import ScheduledAgentConfig
|
|
12
19
|
from flock.core.flock_agent import FlockAgent, SignatureType
|
|
13
20
|
from flock.core.logging.formatters.themes import OutputTheme
|
|
@@ -28,10 +35,6 @@ from flock.core.mcp.types.types import (
|
|
|
28
35
|
StreamableHttpServerParameters,
|
|
29
36
|
WebsocketServerParameters,
|
|
30
37
|
)
|
|
31
|
-
from flock.evaluators.declarative.declarative_evaluator import (
|
|
32
|
-
DeclarativeEvaluator,
|
|
33
|
-
DeclarativeEvaluatorConfig,
|
|
34
|
-
)
|
|
35
38
|
from flock.mcp.servers.sse.flock_sse_server import (
|
|
36
39
|
FlockSSEConfig,
|
|
37
40
|
FlockSSEConnectionConfig,
|
|
@@ -52,11 +55,6 @@ from flock.mcp.servers.websockets.flock_websocket_server import (
|
|
|
52
55
|
FlockWSConnectionConfig,
|
|
53
56
|
FlockWSServer,
|
|
54
57
|
)
|
|
55
|
-
from flock.modules.output.output_module import OutputModule, OutputModuleConfig
|
|
56
|
-
from flock.modules.performance.metrics_module import (
|
|
57
|
-
MetricsModule,
|
|
58
|
-
MetricsModuleConfig,
|
|
59
|
-
)
|
|
60
58
|
from flock.workflow.temporal_config import TemporalActivityConfig
|
|
61
59
|
|
|
62
60
|
LoggingLevel = Literal[
|
|
@@ -111,34 +109,29 @@ class FlockFactory:
|
|
|
111
109
|
class StreamableHttpParams(BaseModel):
|
|
112
110
|
"""Factory-Params for Streamable Http Servers."""
|
|
113
111
|
|
|
114
|
-
url: str | AnyUrl = Field(
|
|
115
|
-
...,
|
|
116
|
-
description="Url the server listens at."
|
|
117
|
-
)
|
|
112
|
+
url: str | AnyUrl = Field(..., description="Url the server listens at.")
|
|
118
113
|
|
|
119
114
|
headers: dict[str, Any] | None = Field(
|
|
120
115
|
default=None,
|
|
121
|
-
description="Additional Headers to pass to the client."
|
|
116
|
+
description="Additional Headers to pass to the client.",
|
|
122
117
|
)
|
|
123
118
|
|
|
124
119
|
auth: httpx.Auth | None = Field(
|
|
125
|
-
default=None,
|
|
126
|
-
description="Httpx Auth Schema."
|
|
120
|
+
default=None, description="Httpx Auth Schema."
|
|
127
121
|
)
|
|
128
122
|
|
|
129
123
|
timeout_seconds: float | int = Field(
|
|
130
|
-
default=5,
|
|
131
|
-
description="Http Timeout in Seconds"
|
|
124
|
+
default=5, description="Http Timeout in Seconds"
|
|
132
125
|
)
|
|
133
126
|
|
|
134
127
|
sse_read_timeout_seconds: float | int = Field(
|
|
135
|
-
default=60*5,
|
|
136
|
-
description="How many seconds to wait for server-sent events until closing the connection."
|
|
128
|
+
default=60 * 5,
|
|
129
|
+
description="How many seconds to wait for server-sent events until closing the connection.",
|
|
137
130
|
)
|
|
138
131
|
|
|
139
132
|
terminate_on_close: bool = Field(
|
|
140
133
|
default=True,
|
|
141
|
-
description="Whether or not to terminate the underlying connection on close."
|
|
134
|
+
description="Whether or not to terminate the underlying connection on close.",
|
|
142
135
|
)
|
|
143
136
|
|
|
144
137
|
model_config = ConfigDict(
|
|
@@ -169,8 +162,7 @@ class FlockFactory:
|
|
|
169
162
|
)
|
|
170
163
|
|
|
171
164
|
auth: httpx.Auth | None = Field(
|
|
172
|
-
default=None,
|
|
173
|
-
description="Httpx Auth Scheme."
|
|
165
|
+
default=None, description="Httpx Auth Scheme."
|
|
174
166
|
)
|
|
175
167
|
|
|
176
168
|
model_config = ConfigDict(
|
|
@@ -189,7 +181,10 @@ class FlockFactory:
|
|
|
189
181
|
@staticmethod
|
|
190
182
|
def create_mcp_server(
|
|
191
183
|
name: str,
|
|
192
|
-
connection_params: StreamableHttpParams
|
|
184
|
+
connection_params: StreamableHttpParams
|
|
185
|
+
| SSEParams
|
|
186
|
+
| StdioParams
|
|
187
|
+
| WebsocketParams,
|
|
193
188
|
max_retries: int = 3,
|
|
194
189
|
mount_points: list[str | MCPRoot] | None = None,
|
|
195
190
|
timeout_seconds: int | float = 10,
|
|
@@ -380,13 +375,13 @@ class FlockFactory:
|
|
|
380
375
|
|
|
381
376
|
server = concrete_server_cls(config=server_config)
|
|
382
377
|
|
|
383
|
-
|
|
378
|
+
metrics_component_config = MetricsUtilityConfig(
|
|
384
379
|
latency_threshold_ms=alert_latency_threshold_ms
|
|
385
380
|
)
|
|
386
381
|
|
|
387
|
-
|
|
382
|
+
metrics_component = MetricsUtilityComponent("metrics", config=metrics_component_config)
|
|
388
383
|
|
|
389
|
-
server.
|
|
384
|
+
server.add_component(metrics_component)
|
|
390
385
|
|
|
391
386
|
return server
|
|
392
387
|
|
|
@@ -415,16 +410,31 @@ class FlockFactory:
|
|
|
415
410
|
include_thought_process: bool = False,
|
|
416
411
|
temporal_activity_config: TemporalActivityConfig | None = None,
|
|
417
412
|
) -> FlockAgent:
|
|
418
|
-
"""Creates a default FlockAgent.
|
|
413
|
+
"""Creates a default FlockAgent using unified component architecture.
|
|
419
414
|
|
|
420
|
-
The default agent includes the following
|
|
421
|
-
-
|
|
422
|
-
-
|
|
423
|
-
-
|
|
415
|
+
The default agent includes the following unified components:
|
|
416
|
+
- DeclarativeEvaluationComponent (core LLM evaluation)
|
|
417
|
+
- OutputUtilityComponent (result formatting and display)
|
|
418
|
+
- MetricsUtilityComponent (performance tracking)
|
|
424
419
|
|
|
425
|
-
|
|
420
|
+
This provides a complete, production-ready agent with sensible defaults.
|
|
426
421
|
"""
|
|
427
|
-
|
|
422
|
+
# Import unified components locally to avoid circular imports
|
|
423
|
+
from flock.components.evaluation.declarative_evaluation_component import (
|
|
424
|
+
DeclarativeEvaluationComponent,
|
|
425
|
+
DeclarativeEvaluationConfig,
|
|
426
|
+
)
|
|
427
|
+
from flock.components.utility.metrics_utility_component import (
|
|
428
|
+
MetricsUtilityComponent,
|
|
429
|
+
MetricsUtilityConfig,
|
|
430
|
+
)
|
|
431
|
+
from flock.components.utility.output_utility_component import (
|
|
432
|
+
OutputUtilityComponent,
|
|
433
|
+
OutputUtilityConfig,
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
# Create evaluation component
|
|
437
|
+
eval_config = DeclarativeEvaluationConfig(
|
|
428
438
|
model=model,
|
|
429
439
|
use_cache=use_cache,
|
|
430
440
|
max_tokens=max_tokens,
|
|
@@ -434,8 +444,30 @@ class FlockFactory:
|
|
|
434
444
|
stream=stream,
|
|
435
445
|
include_thought_process=include_thought_process,
|
|
436
446
|
)
|
|
447
|
+
evaluator = DeclarativeEvaluationComponent(
|
|
448
|
+
name="default_evaluator", config=eval_config
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
# Create output utility component
|
|
452
|
+
output_config = OutputUtilityConfig(
|
|
453
|
+
render_table=enable_rich_tables,
|
|
454
|
+
theme=output_theme,
|
|
455
|
+
no_output=no_output,
|
|
456
|
+
print_context=print_context,
|
|
457
|
+
)
|
|
458
|
+
output_component = OutputUtilityComponent(
|
|
459
|
+
name="output_formatter", config=output_config
|
|
460
|
+
)
|
|
437
461
|
|
|
438
|
-
|
|
462
|
+
# Create metrics utility component
|
|
463
|
+
metrics_config = MetricsUtilityConfig(
|
|
464
|
+
latency_threshold_ms=alert_latency_threshold_ms
|
|
465
|
+
)
|
|
466
|
+
metrics_component = MetricsUtilityComponent(
|
|
467
|
+
name="metrics_tracker", config=metrics_config
|
|
468
|
+
)
|
|
469
|
+
|
|
470
|
+
# Create agent with unified components
|
|
439
471
|
agent = FlockAgent(
|
|
440
472
|
name=name,
|
|
441
473
|
input=input,
|
|
@@ -444,65 +476,54 @@ class FlockFactory:
|
|
|
444
476
|
servers=servers,
|
|
445
477
|
model=model,
|
|
446
478
|
description=description,
|
|
447
|
-
|
|
448
|
-
write_to_file=write_to_file,
|
|
449
|
-
|
|
479
|
+
components=[evaluator, output_component, metrics_component],
|
|
480
|
+
config=FlockAgentConfig(write_to_file=write_to_file,
|
|
481
|
+
wait_for_input=wait_for_input),
|
|
482
|
+
next_agent=None, # No next agent by default
|
|
450
483
|
temporal_activity_config=temporal_activity_config,
|
|
451
484
|
)
|
|
452
|
-
output_config = OutputModuleConfig(
|
|
453
|
-
render_table=enable_rich_tables,
|
|
454
|
-
theme=output_theme,
|
|
455
|
-
no_output=no_output,
|
|
456
|
-
print_context=print_context,
|
|
457
|
-
)
|
|
458
|
-
output_module = OutputModule("output", config=output_config)
|
|
459
|
-
|
|
460
|
-
metrics_config = MetricsModuleConfig(
|
|
461
|
-
latency_threshold_ms=alert_latency_threshold_ms
|
|
462
|
-
)
|
|
463
|
-
metrics_module = MetricsModule("metrics", config=metrics_config)
|
|
464
485
|
|
|
465
|
-
agent.add_module(output_module)
|
|
466
|
-
agent.add_module(metrics_module)
|
|
467
486
|
return agent
|
|
468
487
|
|
|
469
488
|
@staticmethod
|
|
470
489
|
def create_scheduled_agent(
|
|
471
490
|
name: str,
|
|
472
|
-
schedule_expression: str,
|
|
491
|
+
schedule_expression: str, # e.g., "every 1h", "0 0 * * *"
|
|
473
492
|
description: str | Callable[..., str] | None = None,
|
|
474
493
|
model: str | Callable[..., str] | None = None,
|
|
475
|
-
output: SignatureType = None,
|
|
494
|
+
output: SignatureType = None, # Input might be implicit or none
|
|
476
495
|
tools: list[Callable[..., Any] | Any] | None = None,
|
|
477
496
|
servers: list[str | FlockMCPServerBase] | None = None,
|
|
478
|
-
use_cache: bool = False,
|
|
479
|
-
temperature: float = 0.7,
|
|
497
|
+
use_cache: bool = False, # Whether to cache results
|
|
498
|
+
temperature: float = 0.7, # Temperature for model responses
|
|
480
499
|
# ... other common agent params from create_default_agent ...
|
|
481
|
-
temporal_activity_config: TemporalActivityConfig
|
|
482
|
-
|
|
500
|
+
temporal_activity_config: TemporalActivityConfig
|
|
501
|
+
| None = None, # If you want scheduled tasks to be Temporal activities
|
|
502
|
+
**kwargs, # Forward other standard agent params
|
|
483
503
|
) -> FlockAgent:
|
|
484
504
|
"""Creates a FlockAgent configured to run on a schedule."""
|
|
485
|
-
agent_config = ScheduledAgentConfig(
|
|
505
|
+
agent_config = ScheduledAgentConfig( # Use the new config type
|
|
486
506
|
schedule_expression=schedule_expression,
|
|
487
507
|
enabled=True,
|
|
488
508
|
initial_run=True,
|
|
489
509
|
max_runs=0,
|
|
490
|
-
**kwargs
|
|
510
|
+
**kwargs,
|
|
491
511
|
)
|
|
492
512
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
513
|
+
agent = (
|
|
514
|
+
FlockFactory.create_default_agent( # Reuse your existing factory
|
|
515
|
+
name=name,
|
|
516
|
+
description=description,
|
|
517
|
+
model=model,
|
|
518
|
+
input="trigger_time: str | Time of scheduled execution",
|
|
519
|
+
output=output,
|
|
520
|
+
tools=tools,
|
|
521
|
+
servers=servers,
|
|
522
|
+
temporal_activity_config=temporal_activity_config,
|
|
523
|
+
use_cache=use_cache,
|
|
524
|
+
temperature=temperature,
|
|
525
|
+
**kwargs,
|
|
526
|
+
)
|
|
506
527
|
)
|
|
507
528
|
agent.config = agent_config # Assign the scheduled agent config
|
|
508
529
|
|
|
@@ -29,12 +29,10 @@ if TYPE_CHECKING:
|
|
|
29
29
|
from flock.core.flock_agent import (
|
|
30
30
|
FlockAgent, # Import only for type checking
|
|
31
31
|
)
|
|
32
|
-
from flock.core.flock_evaluator import FlockEvaluator
|
|
33
|
-
from flock.core.flock_module import FlockModule
|
|
34
|
-
from flock.core.flock_router import FlockRouter
|
|
35
32
|
from flock.core.mcp.flock_mcp_server import FlockMCPServerBase
|
|
33
|
+
from flock.core.component.agent_component_base import AgentComponent
|
|
36
34
|
|
|
37
|
-
COMPONENT_BASE_TYPES = (
|
|
35
|
+
COMPONENT_BASE_TYPES = (AgentComponent,)
|
|
38
36
|
|
|
39
37
|
IS_COMPONENT_CHECK_ENABLED = True
|
|
40
38
|
else:
|
|
@@ -44,7 +42,6 @@ else:
|
|
|
44
42
|
IS_COMPONENT_CHECK_ENABLED = False
|
|
45
43
|
|
|
46
44
|
# Fallback if core types aren't available during setup
|
|
47
|
-
from flock.core.flock_module import FlockModuleConfig
|
|
48
45
|
from flock.core.logging.logging import get_logger
|
|
49
46
|
|
|
50
47
|
logger = get_logger("registry")
|
|
@@ -118,18 +115,7 @@ class FlockRegistry:
|
|
|
118
115
|
config_cls: type[ConfigType], component_cls: type[ClassType]
|
|
119
116
|
):
|
|
120
117
|
"""Explicitly registers the mapping between a config and component class."""
|
|
121
|
-
|
|
122
|
-
FlockEvaluatorConfig,
|
|
123
|
-
)
|
|
124
|
-
from flock.core.flock_router import FlockRouterConfig
|
|
125
|
-
|
|
126
|
-
if not issubclass(
|
|
127
|
-
config_cls,
|
|
128
|
-
FlockModuleConfig | FlockRouterConfig | FlockEvaluatorConfig,
|
|
129
|
-
):
|
|
130
|
-
logger.warning(
|
|
131
|
-
f"Config class {config_cls.__name__} does not inherit from a standard Flock config base."
|
|
132
|
-
)
|
|
118
|
+
# Component config validation can be added here if needed
|
|
133
119
|
# Add more checks if needed (e.g., component_cls inherits from Module/Router/Evaluator)
|
|
134
120
|
|
|
135
121
|
if (
|
flock/core/logging/logging.py
CHANGED
|
@@ -154,6 +154,7 @@ def color_for_category(category: str) -> str:
|
|
|
154
154
|
if category in COLOR_MAP:
|
|
155
155
|
return COLOR_MAP[category]
|
|
156
156
|
parts = category.split(".")
|
|
157
|
+
# Try progressively shorter parent categories
|
|
157
158
|
for i in range(len(parts) - 1, 0, -1):
|
|
158
159
|
parent_category = ".".join(parts[:i])
|
|
159
160
|
if parent_category in COLOR_MAP:
|
|
@@ -15,7 +15,7 @@ from pydantic import (
|
|
|
15
15
|
Field,
|
|
16
16
|
)
|
|
17
17
|
|
|
18
|
-
from flock.core.
|
|
18
|
+
from flock.core.component.agent_component_base import AgentComponent
|
|
19
19
|
from flock.core.logging.logging import get_logger
|
|
20
20
|
from flock.core.mcp.flock_mcp_tool_base import FlockMCPToolBase
|
|
21
21
|
from flock.core.mcp.mcp_client_manager import FlockMCPClientManagerBase
|
|
@@ -74,9 +74,9 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
74
74
|
description="Whether or not this Server has already initialized.",
|
|
75
75
|
)
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
components: dict[str, AgentComponent] = Field(
|
|
78
78
|
default={},
|
|
79
|
-
description="Dictionary of
|
|
79
|
+
description="Dictionary of unified agent components attached to this Server.",
|
|
80
80
|
)
|
|
81
81
|
|
|
82
82
|
# --- Underlying ConnectionManager ---
|
|
@@ -98,40 +98,40 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
98
98
|
arbitrary_types_allowed=True,
|
|
99
99
|
)
|
|
100
100
|
|
|
101
|
-
def
|
|
102
|
-
"""Add a
|
|
103
|
-
if not
|
|
104
|
-
logger.error("
|
|
101
|
+
def add_component(self, component: AgentComponent) -> None:
|
|
102
|
+
"""Add a unified component to this server."""
|
|
103
|
+
if not component.name:
|
|
104
|
+
logger.error("Component must have a name to be added.")
|
|
105
105
|
return
|
|
106
|
-
if self.
|
|
107
|
-
logger.warning(f"Overwriting existing
|
|
106
|
+
if self.components and component.name in self.components:
|
|
107
|
+
logger.warning(f"Overwriting existing component: {component.name}")
|
|
108
108
|
|
|
109
|
-
self.
|
|
109
|
+
self.components[component.name] = component
|
|
110
110
|
logger.debug(
|
|
111
|
-
f"Added
|
|
111
|
+
f"Added component '{component.name}' to server {self.config.name}"
|
|
112
112
|
)
|
|
113
113
|
return
|
|
114
114
|
|
|
115
|
-
def
|
|
116
|
-
"""Remove a
|
|
117
|
-
if
|
|
118
|
-
del self.
|
|
115
|
+
def remove_component(self, component_name: str) -> None:
|
|
116
|
+
"""Remove a component from this server."""
|
|
117
|
+
if component_name in self.components:
|
|
118
|
+
del self.components[component_name]
|
|
119
119
|
logger.debug(
|
|
120
|
-
f"Removed
|
|
120
|
+
f"Removed component '{component_name}' from server '{self.config.name}'"
|
|
121
121
|
)
|
|
122
122
|
else:
|
|
123
123
|
logger.warning(
|
|
124
|
-
f"
|
|
124
|
+
f"Component '{component_name}' not found on server '{self.config.name}'"
|
|
125
125
|
)
|
|
126
126
|
return
|
|
127
127
|
|
|
128
|
-
def
|
|
129
|
-
"""Get a
|
|
130
|
-
return self.
|
|
128
|
+
def get_component(self, component_name: str) -> AgentComponent | None:
|
|
129
|
+
"""Get a component by name."""
|
|
130
|
+
return self.components.get(component_name)
|
|
131
131
|
|
|
132
|
-
def
|
|
133
|
-
"""Get a list of currently enabled
|
|
134
|
-
return [
|
|
132
|
+
def get_enabled_components(self) -> list[AgentComponent]:
|
|
133
|
+
"""Get a list of currently enabled components attached to this server."""
|
|
134
|
+
return [c for c in self.components.values() if c.config.enabled]
|
|
135
135
|
|
|
136
136
|
@abstractmethod
|
|
137
137
|
async def initialize(self) -> FlockMCPClientManagerBase:
|
|
@@ -244,7 +244,7 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
244
244
|
try:
|
|
245
245
|
if not additional_params:
|
|
246
246
|
additional_params = {}
|
|
247
|
-
for module in self.
|
|
247
|
+
for module in self.get_enabled_components():
|
|
248
248
|
additional_params = await module.on_connect(
|
|
249
249
|
server=self, additional_params=additional_params
|
|
250
250
|
)
|
|
@@ -264,7 +264,7 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
264
264
|
with tracer.start_as_current_span("server.pre_init") as span:
|
|
265
265
|
span.set_attribute("server.name", self.config.name)
|
|
266
266
|
try:
|
|
267
|
-
for module in self.
|
|
267
|
+
for module in self.get_enabled_components():
|
|
268
268
|
await module.on_pre_server_init(self)
|
|
269
269
|
except Exception as module_error:
|
|
270
270
|
logger.error(
|
|
@@ -282,7 +282,7 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
282
282
|
with tracer.start_as_current_span("server.post_init") as span:
|
|
283
283
|
span.set_attribute("server.name", self.config.name)
|
|
284
284
|
try:
|
|
285
|
-
for module in self.
|
|
285
|
+
for module in self.get_enabled_components():
|
|
286
286
|
await module.on_post_server_init(self)
|
|
287
287
|
except Exception as module_error:
|
|
288
288
|
logger.error(
|
|
@@ -300,7 +300,7 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
300
300
|
with tracer.start_as_current_span("server.pre_terminate") as span:
|
|
301
301
|
span.set_attribute("server.name", self.config.name)
|
|
302
302
|
try:
|
|
303
|
-
for module in self.
|
|
303
|
+
for module in self.get_enabled_components():
|
|
304
304
|
await module.on_pre_server_terminate(self)
|
|
305
305
|
except Exception as module_error:
|
|
306
306
|
logger.error(
|
|
@@ -318,7 +318,7 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
318
318
|
with tracer.start_as_current_span("server.post_terminate") as span:
|
|
319
319
|
span.set_attribute("server.name", self.config.name)
|
|
320
320
|
try:
|
|
321
|
-
for module in self.
|
|
321
|
+
for module in self.get_enabled_components():
|
|
322
322
|
await module.on_post_server_terminate(server=self)
|
|
323
323
|
except Exception as module_error:
|
|
324
324
|
logger.error(
|
|
@@ -336,7 +336,7 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
336
336
|
with tracer.start_as_current_span("server.on_error") as span:
|
|
337
337
|
span.set_attribute("server.name", self.config.name)
|
|
338
338
|
try:
|
|
339
|
-
for module in self.
|
|
339
|
+
for module in self.get_enabled_components():
|
|
340
340
|
await module.on_server_error(server=self, error=error)
|
|
341
341
|
except Exception as module_error:
|
|
342
342
|
logger.error(
|
|
@@ -354,7 +354,7 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
354
354
|
with tracer.start_as_current_span("server.pre_mcp_call") as span:
|
|
355
355
|
span.set_attribute("server.name", self.config.name)
|
|
356
356
|
try:
|
|
357
|
-
for module in self.
|
|
357
|
+
for module in self.get_enabled_components():
|
|
358
358
|
await module.on_pre_mcp_call(
|
|
359
359
|
server=self, arguments=arguments
|
|
360
360
|
)
|
|
@@ -374,7 +374,7 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
374
374
|
with tracer.start_as_current_span("server.post_mcp_call") as span:
|
|
375
375
|
span.set_attribute("server.name", self.config.name)
|
|
376
376
|
try:
|
|
377
|
-
for module in self.
|
|
377
|
+
for module in self.get_enabled_components():
|
|
378
378
|
await module.on_post_mcp_call(server=self, result=result)
|
|
379
379
|
except Exception as module_error:
|
|
380
380
|
logger.error(
|
|
@@ -432,9 +432,9 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
432
432
|
# --- Serialization Implementation ---
|
|
433
433
|
def to_dict(self, path_type: str = "relative") -> dict[str, Any]:
|
|
434
434
|
"""Convert instance to dictionary representation suitable for serialization."""
|
|
435
|
-
from flock.core.
|
|
435
|
+
from flock.core.registry import get_registry
|
|
436
436
|
|
|
437
|
-
|
|
437
|
+
registry = get_registry()
|
|
438
438
|
|
|
439
439
|
exclude = ["modules", "config"]
|
|
440
440
|
|
|
@@ -498,7 +498,7 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
498
498
|
def add_serialized_component(component: Any, field_name: str):
|
|
499
499
|
if component:
|
|
500
500
|
comp_type = type(component)
|
|
501
|
-
type_name =
|
|
501
|
+
type_name = registry.get_component_type_name(
|
|
502
502
|
comp_type
|
|
503
503
|
) # Get registered name
|
|
504
504
|
|
|
@@ -619,11 +619,16 @@ class FlockMCPServerBase(BaseModel, Serializable, ABC):
|
|
|
619
619
|
data["config"] = config_object
|
|
620
620
|
|
|
621
621
|
# now construct
|
|
622
|
-
server = real_cls(**{k: v for k, v in data.items() if k
|
|
622
|
+
server = real_cls(**{k: v for k, v in data.items() if k not in ["modules", "components"]})
|
|
623
623
|
|
|
624
|
-
# re-hydrate modules
|
|
624
|
+
# re-hydrate components (both legacy modules and new components)
|
|
625
|
+
for cname, cdata in data.get("components", {}).items():
|
|
626
|
+
server.add_component(deserialize_component(cdata, AgentComponent))
|
|
627
|
+
|
|
628
|
+
# Handle legacy modules for backward compatibility during transition
|
|
625
629
|
for mname, mdata in data.get("modules", {}).items():
|
|
626
|
-
|
|
630
|
+
logger.warning(f"Legacy module '{mname}' found during deserialization - consider migrating to unified components")
|
|
631
|
+
# Skip legacy modules during migration
|
|
627
632
|
|
|
628
633
|
# --- Separate Data ---
|
|
629
634
|
component_configs = {}
|
|
@@ -30,9 +30,9 @@ def _resolve_type_string(type_str: str) -> type:
|
|
|
30
30
|
List, Dict, Optional, Union, Literal.
|
|
31
31
|
"""
|
|
32
32
|
# Import registry here to avoid circular imports
|
|
33
|
-
from flock.core.
|
|
33
|
+
from flock.core.registry import get_registry
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
registry = get_registry()
|
|
36
36
|
|
|
37
37
|
type_str = type_str.strip()
|
|
38
38
|
logger.debug(f"Attempting to resolve type string: '{type_str}'")
|
|
@@ -40,7 +40,7 @@ def _resolve_type_string(type_str: str) -> type:
|
|
|
40
40
|
# 1. Check built-ins and registered types directly
|
|
41
41
|
try:
|
|
42
42
|
# This covers str, int, bool, Any, and types registered by name
|
|
43
|
-
resolved_type =
|
|
43
|
+
resolved_type = registry.get_type(type_str)
|
|
44
44
|
logger.debug(f"Resolved '{type_str}' via registry to: {resolved_type}")
|
|
45
45
|
return resolved_type
|
|
46
46
|
except KeyError:
|
|
@@ -61,7 +61,7 @@ def _resolve_type_string(type_str: str) -> type:
|
|
|
61
61
|
|
|
62
62
|
try:
|
|
63
63
|
# Get the base generic type (e.g., list, dict, Optional) from registry/builtins
|
|
64
|
-
BaseType =
|
|
64
|
+
BaseType = registry.get_type(
|
|
65
65
|
base_name
|
|
66
66
|
) # Expects List, Dict etc. to be registered
|
|
67
67
|
logger.debug(
|
|
@@ -149,7 +149,7 @@ class DSPyIntegrationMixin:
|
|
|
149
149
|
self, agent_name, description_spec, fields_spec
|
|
150
150
|
) -> Any:
|
|
151
151
|
"""Creates a dynamic DSPy Signature class from string specifications,
|
|
152
|
-
resolving types using the
|
|
152
|
+
resolving types using the registry.
|
|
153
153
|
"""
|
|
154
154
|
try:
|
|
155
155
|
import dspy
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# src/flock/core/orchestration/__init__.py
|
|
2
|
+
"""Orchestration components for Flock."""
|
|
3
|
+
|
|
4
|
+
from .flock_batch_processor import FlockBatchProcessor
|
|
5
|
+
from .flock_evaluator import FlockEvaluator
|
|
6
|
+
from .flock_execution import FlockExecution
|
|
7
|
+
from .flock_initialization import FlockInitialization
|
|
8
|
+
from .flock_server_manager import FlockServerManager
|
|
9
|
+
from .flock_web_server import FlockWebServer
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"FlockExecution",
|
|
13
|
+
"FlockServerManager",
|
|
14
|
+
"FlockBatchProcessor",
|
|
15
|
+
"FlockEvaluator",
|
|
16
|
+
"FlockWebServer",
|
|
17
|
+
"FlockInitialization",
|
|
18
|
+
]
|