flock-core 0.4.528__py3-none-any.whl → 0.5.0b0__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.

Files changed (130) hide show
  1. flock/cli/execute_flock.py +1 -1
  2. flock/cli/manage_agents.py +6 -6
  3. flock/components/__init__.py +30 -0
  4. flock/components/evaluation/__init__.py +9 -0
  5. flock/components/evaluation/declarative_evaluation_component.py +222 -0
  6. flock/components/routing/__init__.py +15 -0
  7. flock/{routers/conditional/conditional_router.py → components/routing/conditional_routing_component.py} +61 -53
  8. flock/components/routing/default_routing_component.py +103 -0
  9. flock/components/routing/llm_routing_component.py +206 -0
  10. flock/components/utility/__init__.py +15 -0
  11. flock/{modules/enterprise_memory/enterprise_memory_module.py → components/utility/memory_utility_component.py} +195 -173
  12. flock/{modules/performance/metrics_module.py → components/utility/metrics_utility_component.py} +110 -95
  13. flock/{modules/output/output_module.py → components/utility/output_utility_component.py} +47 -45
  14. flock/core/__init__.py +26 -18
  15. flock/core/agent/__init__.py +16 -0
  16. flock/core/agent/flock_agent_components.py +104 -0
  17. flock/core/agent/flock_agent_execution.py +101 -0
  18. flock/core/agent/flock_agent_integration.py +206 -0
  19. flock/core/agent/flock_agent_lifecycle.py +177 -0
  20. flock/core/agent/flock_agent_serialization.py +381 -0
  21. flock/core/api/endpoints.py +2 -2
  22. flock/core/api/service.py +2 -2
  23. flock/core/component/__init__.py +15 -0
  24. flock/core/{flock_module.py → component/agent_component_base.py} +136 -34
  25. flock/core/component/evaluation_component.py +56 -0
  26. flock/core/component/routing_component.py +74 -0
  27. flock/core/component/utility_component.py +69 -0
  28. flock/core/config/flock_agent_config.py +49 -2
  29. flock/core/evaluation/utils.py +3 -2
  30. flock/core/execution/batch_executor.py +1 -1
  31. flock/core/execution/evaluation_executor.py +2 -2
  32. flock/core/execution/opik_executor.py +1 -1
  33. flock/core/flock.py +147 -493
  34. flock/core/flock_agent.py +195 -1032
  35. flock/core/flock_factory.py +114 -90
  36. flock/core/flock_scheduler.py +1 -1
  37. flock/core/flock_server_manager.py +8 -8
  38. flock/core/logging/logging.py +1 -0
  39. flock/core/mcp/flock_mcp_server.py +53 -48
  40. flock/core/mcp/{flock_mcp_tool_base.py → flock_mcp_tool.py} +2 -2
  41. flock/core/mcp/mcp_client.py +9 -9
  42. flock/core/mcp/mcp_client_manager.py +9 -9
  43. flock/core/mcp/mcp_config.py +24 -24
  44. flock/core/mixin/dspy_integration.py +5 -5
  45. flock/core/orchestration/__init__.py +18 -0
  46. flock/core/orchestration/flock_batch_processor.py +94 -0
  47. flock/core/orchestration/flock_evaluator.py +113 -0
  48. flock/core/orchestration/flock_execution.py +288 -0
  49. flock/core/orchestration/flock_initialization.py +125 -0
  50. flock/core/orchestration/flock_server_manager.py +67 -0
  51. flock/core/orchestration/flock_web_server.py +117 -0
  52. flock/core/registry/__init__.py +45 -0
  53. flock/core/registry/agent_registry.py +69 -0
  54. flock/core/registry/callable_registry.py +139 -0
  55. flock/core/registry/component_discovery.py +142 -0
  56. flock/core/registry/component_registry.py +64 -0
  57. flock/core/registry/config_mapping.py +64 -0
  58. flock/core/registry/decorators.py +137 -0
  59. flock/core/registry/registry_hub.py +205 -0
  60. flock/core/registry/server_registry.py +57 -0
  61. flock/core/registry/type_registry.py +86 -0
  62. flock/core/serialization/flock_serializer.py +36 -32
  63. flock/core/serialization/serialization_utils.py +28 -25
  64. flock/core/util/hydrator.py +1 -1
  65. flock/core/util/input_resolver.py +29 -2
  66. flock/mcp/servers/sse/flock_sse_server.py +10 -10
  67. flock/mcp/servers/stdio/flock_stdio_server.py +10 -10
  68. flock/mcp/servers/streamable_http/flock_streamable_http_server.py +10 -10
  69. flock/mcp/servers/websockets/flock_websocket_server.py +10 -10
  70. flock/platform/docker_tools.py +3 -3
  71. flock/webapp/app/chat.py +1 -1
  72. flock/webapp/app/main.py +9 -5
  73. flock/webapp/app/services/flock_service.py +1 -1
  74. flock/webapp/app/services/sharing_store.py +1 -0
  75. flock/workflow/activities.py +67 -92
  76. flock/workflow/agent_execution_activity.py +6 -6
  77. flock/workflow/flock_workflow.py +1 -1
  78. flock_core-0.5.0b0.dist-info/METADATA +272 -0
  79. {flock_core-0.4.528.dist-info → flock_core-0.5.0b0.dist-info}/RECORD +82 -95
  80. flock/core/flock_evaluator.py +0 -60
  81. flock/core/flock_registry.py +0 -702
  82. flock/core/flock_router.py +0 -83
  83. flock/evaluators/__init__.py +0 -1
  84. flock/evaluators/declarative/__init__.py +0 -1
  85. flock/evaluators/declarative/declarative_evaluator.py +0 -217
  86. flock/evaluators/memory/memory_evaluator.py +0 -90
  87. flock/evaluators/test/test_case_evaluator.py +0 -38
  88. flock/evaluators/zep/zep_evaluator.py +0 -59
  89. flock/modules/__init__.py +0 -1
  90. flock/modules/assertion/__init__.py +0 -1
  91. flock/modules/assertion/assertion_module.py +0 -286
  92. flock/modules/callback/__init__.py +0 -1
  93. flock/modules/callback/callback_module.py +0 -91
  94. flock/modules/enterprise_memory/README.md +0 -99
  95. flock/modules/mem0/__init__.py +0 -1
  96. flock/modules/mem0/mem0_module.py +0 -126
  97. flock/modules/mem0_async/__init__.py +0 -1
  98. flock/modules/mem0_async/async_mem0_module.py +0 -126
  99. flock/modules/memory/__init__.py +0 -1
  100. flock/modules/memory/memory_module.py +0 -429
  101. flock/modules/memory/memory_parser.py +0 -125
  102. flock/modules/memory/memory_storage.py +0 -736
  103. flock/modules/output/__init__.py +0 -1
  104. flock/modules/performance/__init__.py +0 -1
  105. flock/modules/zep/__init__.py +0 -1
  106. flock/modules/zep/zep_module.py +0 -192
  107. flock/routers/__init__.py +0 -1
  108. flock/routers/agent/__init__.py +0 -1
  109. flock/routers/agent/agent_router.py +0 -236
  110. flock/routers/agent/handoff_agent.py +0 -58
  111. flock/routers/default/__init__.py +0 -1
  112. flock/routers/default/default_router.py +0 -80
  113. flock/routers/feedback/feedback_router.py +0 -114
  114. flock/routers/list_generator/list_generator_router.py +0 -166
  115. flock/routers/llm/__init__.py +0 -1
  116. flock/routers/llm/llm_router.py +0 -365
  117. flock/tools/__init__.py +0 -0
  118. flock/tools/azure_tools.py +0 -781
  119. flock/tools/code_tools.py +0 -167
  120. flock/tools/file_tools.py +0 -149
  121. flock/tools/github_tools.py +0 -157
  122. flock/tools/markdown_tools.py +0 -205
  123. flock/tools/system_tools.py +0 -9
  124. flock/tools/text_tools.py +0 -810
  125. flock/tools/web_tools.py +0 -90
  126. flock/tools/zendesk_tools.py +0 -147
  127. flock_core-0.4.528.dist-info/METADATA +0 -675
  128. {flock_core-0.4.528.dist-info → flock_core-0.5.0b0.dist-info}/WHEEL +0 -0
  129. {flock_core-0.4.528.dist-info → flock_core-0.5.0b0.dist-info}/entry_points.txt +0 -0
  130. {flock_core-0.4.528.dist-info → flock_core-0.5.0b0.dist-info}/licenses/LICENSE +0 -0
@@ -1,7 +1,6 @@
1
1
  # src/flock/core/serialization/flock_serializer.py
2
2
  """Handles serialization and deserialization logic for Flock instances."""
3
3
 
4
- import builtins
5
4
  import importlib
6
5
  import importlib.util
7
6
  import inspect
@@ -13,9 +12,10 @@ from typing import TYPE_CHECKING, Any, Literal
13
12
 
14
13
  from pydantic import BaseModel, create_model
15
14
 
16
- # Need registry access
17
- from flock.core.flock_registry import get_registry
18
15
  from flock.core.logging.logging import get_logger
16
+
17
+ # Need registry access
18
+ from flock.core.registry import get_registry
19
19
  from flock.core.serialization.serialization_utils import (
20
20
  # Assuming this handles basic serialization needs
21
21
  extract_pydantic_models_from_type_string,
@@ -26,7 +26,7 @@ if TYPE_CHECKING:
26
26
 
27
27
 
28
28
  logger = get_logger("serialization.flock")
29
- FlockRegistry = get_registry()
29
+ registry = get_registry()
30
30
 
31
31
 
32
32
  class FlockSerializer:
@@ -186,7 +186,7 @@ class FlockSerializer:
186
186
  "description_callable"
187
187
  ]
188
188
  description_callable = agent_instance.description
189
- path_str = FlockRegistry.get_callable_path_string(
189
+ path_str = registry.get_callable_path_string(
190
190
  description_callable
191
191
  )
192
192
  if path_str:
@@ -205,7 +205,7 @@ class FlockSerializer:
205
205
  )
206
206
  input_callable_name = agent_data["input_callable"]
207
207
  input_callable = agent_instance.input
208
- path_str = FlockRegistry.get_callable_path_string(
208
+ path_str = registry.get_callable_path_string(
209
209
  input_callable
210
210
  )
211
211
  if path_str:
@@ -224,7 +224,7 @@ class FlockSerializer:
224
224
  )
225
225
  output_callable_name = agent_data["output_callable"]
226
226
  output_callable = agent_instance.output
227
- path_str = FlockRegistry.get_callable_path_string(
227
+ path_str = registry.get_callable_path_string(
228
228
  output_callable
229
229
  )
230
230
  if path_str:
@@ -250,7 +250,7 @@ class FlockSerializer:
250
250
  tool = tool_objs[i]
251
251
  if callable(tool) and not isinstance(tool, type):
252
252
  path_str = (
253
- FlockRegistry.get_callable_path_string(tool)
253
+ registry.get_callable_path_string(tool)
254
254
  )
255
255
  if path_str:
256
256
  logger.debug(
@@ -293,7 +293,7 @@ class FlockSerializer:
293
293
  from flock.core.flock import Flock # Import the actual class
294
294
  from flock.core.flock_agent import FlockAgent as ConcreteFlockAgent
295
295
  from flock.core.mcp.flock_mcp_server import (
296
- FlockMCPServerBase as ConcreteFlockMCPServer,
296
+ FlockMCPServer as ConcreteFlockMCPServer,
297
297
  )
298
298
 
299
299
  logger.debug(
@@ -415,7 +415,7 @@ class FlockSerializer:
415
415
  type_definitions = {}
416
416
  for type_name in type_names:
417
417
  try:
418
- type_obj = FlockRegistry.get_type(
418
+ type_obj = registry.get_type(
419
419
  type_name
420
420
  ) # Throws KeyError if not found
421
421
  type_def = FlockSerializer._extract_type_definition(
@@ -490,7 +490,7 @@ class FlockSerializer:
490
490
  "file_path": None,
491
491
  }
492
492
  try:
493
- component_class = FlockRegistry.get_component(
493
+ component_class = registry.get_component(
494
494
  component_type_name
495
495
  ) # Raises KeyError if not found
496
496
  component_def["module_path"] = getattr(
@@ -540,7 +540,7 @@ class FlockSerializer:
540
540
  "file_path": None,
541
541
  }
542
542
  try:
543
- func = FlockRegistry.get_callable(
543
+ func = registry.get_callable(
544
544
  callable_path
545
545
  ) # Raises KeyError if not found
546
546
  callable_def["module_path"] = getattr(func, "__module__", "unknown")
@@ -596,7 +596,7 @@ class FlockSerializer:
596
596
  module = importlib.import_module(module_path)
597
597
  if hasattr(module, type_name):
598
598
  type_obj = getattr(module, type_name)
599
- FlockRegistry.register_type(type_obj, type_name)
599
+ registry.register_type(type_obj, type_name)
600
600
  logger.info(
601
601
  f"Registered type '{type_name}' from module '{module_path}'"
602
602
  )
@@ -629,7 +629,7 @@ class FlockSerializer:
629
629
  type_name: str, type_def: dict[str, Any]
630
630
  ) -> None:
631
631
  """Dynamically create and register a Pydantic model from schema."""
632
- # (Logic remains the same, ensure it uses FlockRegistry.register_type)
632
+ # (Logic remains the same, ensure it uses registry.register_type)
633
633
  schema = type_def.get("schema", {})
634
634
  try:
635
635
  fields = {}
@@ -641,7 +641,7 @@ class FlockSerializer:
641
641
  fields[field_name] = (field_type, default)
642
642
 
643
643
  DynamicModel = create_model(type_name, **fields)
644
- FlockRegistry.register_type(DynamicModel, type_name)
644
+ registry.register_type(DynamicModel, type_name)
645
645
  logger.info(
646
646
  f"Dynamically created and registered Pydantic model: {type_name}"
647
647
  )
@@ -672,27 +672,31 @@ class FlockSerializer:
672
672
  @staticmethod
673
673
  def _create_dataclass(type_name: str, type_def: dict[str, Any]) -> None:
674
674
  """Dynamically create and register a dataclass."""
675
- # (Logic remains the same, ensure it uses FlockRegistry.register_type)
675
+ # (Logic remains the same, ensure it uses registry.register_type)
676
676
  from dataclasses import make_dataclass
677
677
 
678
678
  fields_def = type_def.get("fields", {})
679
679
  try:
680
680
  fields = []
681
681
  for field_name, field_props in fields_def.items():
682
- # Safely evaluate type string - requires care!
682
+ # Safely map type strings to actual types
683
683
  field_type_str = field_props.get("type", "str")
684
- try:
685
- field_type = eval(
686
- field_type_str,
687
- {"__builtins__": builtins.__dict__},
688
- {"List": list, "Dict": dict},
689
- ) # Allow basic types
690
- except Exception:
691
- field_type = Any
684
+ type_mapping = {
685
+ "str": str,
686
+ "int": int,
687
+ "float": float,
688
+ "bool": bool,
689
+ "list": list,
690
+ "dict": dict,
691
+ "List": list,
692
+ "Dict": dict,
693
+ "Any": Any,
694
+ }
695
+ field_type = type_mapping.get(field_type_str, Any)
692
696
  fields.append((field_name, field_type))
693
697
 
694
698
  DynamicDataclass = make_dataclass(type_name, fields)
695
- FlockRegistry.register_type(DynamicDataclass, type_name)
699
+ registry.register_type(DynamicDataclass, type_name)
696
700
  logger.info(
697
701
  f"Dynamically created and registered dataclass: {type_name}"
698
702
  )
@@ -705,7 +709,7 @@ class FlockSerializer:
705
709
  path_type: Literal["absolute", "relative"],
706
710
  ) -> None:
707
711
  """Register component/callable definitions from serialized data."""
708
- # (Logic remains the same, ensure it uses FlockRegistry.register_component/register_callable)
712
+ # (Logic remains the same, ensure it uses registry.register_component/register_callable)
709
713
  # Key change: Ensure file_path is handled correctly based on path_type from metadata
710
714
  for name, comp_def in component_defs.items():
711
715
  logger.debug(
@@ -735,13 +739,13 @@ class FlockSerializer:
735
739
  if hasattr(module, name):
736
740
  obj = getattr(module, name)
737
741
  if kind == "flock_callable" and callable(obj):
738
- FlockRegistry.register_callable(
742
+ registry.register_callable(
739
743
  obj, name
740
744
  ) # Register by simple name
741
745
  # Also register by full path if possible
742
746
  full_path = f"{module_path}.{name}"
743
747
  if full_path != name:
744
- FlockRegistry.register_callable(obj, full_path)
748
+ registry.register_callable(obj, full_path)
745
749
  logger.info(
746
750
  f"Registered callable '{name}' from module '{module_path}'"
747
751
  )
@@ -749,7 +753,7 @@ class FlockSerializer:
749
753
  elif kind == "flock_component" and isinstance(
750
754
  obj, type
751
755
  ):
752
- FlockRegistry.register_component(obj, name)
756
+ registry.register_component(obj, name)
753
757
  logger.info(
754
758
  f"Registered component '{name}' from module '{module_path}'"
755
759
  )
@@ -785,14 +789,14 @@ class FlockSerializer:
785
789
  if hasattr(module, name):
786
790
  obj = getattr(module, name)
787
791
  if kind == "flock_callable" and callable(obj):
788
- FlockRegistry.register_callable(obj, name)
792
+ registry.register_callable(obj, name)
789
793
  logger.info(
790
794
  f"Registered callable '{name}' from file '{file_path}'"
791
795
  )
792
796
  elif kind == "flock_component" and isinstance(
793
797
  obj, type
794
798
  ):
795
- FlockRegistry.register_component(obj, name)
799
+ registry.register_component(obj, name)
796
800
  logger.info(
797
801
  f"Registered component '{name}' from file '{file_path}'"
798
802
  )
@@ -24,13 +24,13 @@ from pydantic import BaseModel
24
24
  if TYPE_CHECKING:
25
25
  pass
26
26
 
27
- from flock.core.flock_registry import get_registry
27
+ from flock.core.registry import get_registry
28
28
  from flock.core.logging.logging import get_logger
29
29
 
30
30
  logger = get_logger("serialization.utils")
31
31
 
32
32
  # Remove this line to avoid circular import at module level
33
- # FlockRegistry = get_registry() # Get singleton instance
33
+ # registry = get_registry() # Get singleton instance
34
34
 
35
35
  # --- Serialization Helper ---
36
36
 
@@ -188,16 +188,16 @@ def collect_pydantic_models(
188
188
 
189
189
  def serialize_item(item: Any) -> Any:
190
190
  """Recursively prepares an item for serialization (e.g., to dict for YAML/JSON).
191
- Converts known callables to their path strings using FlockRegistry.
191
+ Converts known callables to their path strings using registry.
192
192
  Converts Pydantic models using model_dump.
193
193
  """
194
194
  # Import the registry lazily when needed
195
- from flock.core.flock_registry import get_registry
195
+ from flock.core.registry import get_registry
196
196
 
197
- FlockRegistry = get_registry()
197
+ registry = get_registry()
198
198
 
199
199
  if callable(item) and not isinstance(item, type):
200
- path_str = FlockRegistry.get_callable_path_string(
200
+ path_str = registry.get_callable_path_string(
201
201
  item
202
202
  ) # Use registry helper
203
203
  if path_str:
@@ -248,12 +248,12 @@ def serialize_item(item: Any) -> Any:
248
248
  elif isinstance(
249
249
  item, type
250
250
  ): # Handle type objects themselves (e.g. if stored directly)
251
- type_name = FlockRegistry.get_component_type_name(
251
+ type_name = registry.get_component_type_name(
252
252
  item
253
253
  ) # Check components first
254
254
  if type_name:
255
255
  return {"__component_ref__": type_name}
256
- type_name = FlockRegistry._get_path_string(
256
+ type_name = registry._get_path_string(
257
257
  item
258
258
  ) # Check regular types/classes by path
259
259
  if type_name:
@@ -274,13 +274,13 @@ def serialize_item(item: Any) -> Any:
274
274
 
275
275
  def deserialize_item(item: Any) -> Any:
276
276
  """Recursively processes a deserialized item (e.g., from YAML/JSON dict).
277
- Converts reference dicts back to actual callables or types using FlockRegistry.
277
+ Converts reference dicts back to actual callables or types using registry.
278
278
  Handles nested lists and dicts.
279
279
  """
280
280
  # Import the registry lazily when needed
281
- from flock.core.flock_registry import get_registry
281
+ from flock.core.registry import get_registry
282
282
 
283
- FlockRegistry = get_registry()
283
+ registry = get_registry()
284
284
 
285
285
  if isinstance(item, Mapping):
286
286
  if "__callable_ref__" in item and len(item) == 1:
@@ -288,7 +288,7 @@ def deserialize_item(item: Any) -> Any:
288
288
  try:
289
289
  # The registry's get_callable needs to handle lookup by simple name OR full path
290
290
  # Or we assume get_callable handles finding the right function from the simple name
291
- resolved_callable = FlockRegistry.get_callable(ref_name)
291
+ resolved_callable = registry.get_callable(ref_name)
292
292
  logger.debug(
293
293
  f"Deserialized callable reference '{ref_name}' to {resolved_callable}"
294
294
  )
@@ -307,7 +307,7 @@ def deserialize_item(item: Any) -> Any:
307
307
  elif "__component_ref__" in item and len(item) == 1:
308
308
  type_name = item["__component_ref__"]
309
309
  try:
310
- return FlockRegistry.get_component(type_name)
310
+ return registry.get_component(type_name)
311
311
  except KeyError:
312
312
  logger.error(
313
313
  f"Component reference '{type_name}' not found during deserialization."
@@ -318,7 +318,7 @@ def deserialize_item(item: Any) -> Any:
318
318
  try:
319
319
  # For general types, use get_type or fallback to dynamic import like get_callable
320
320
  # Using get_type for now, assuming it needs registration
321
- return FlockRegistry.get_type(type_name)
321
+ return registry.get_type(type_name)
322
322
  except KeyError:
323
323
  # Attempt dynamic import as fallback if get_type fails (similar to get_callable)
324
324
  try:
@@ -329,7 +329,7 @@ def deserialize_item(item: Any) -> Any:
329
329
  mod = importlib.import_module(module_name)
330
330
  type_obj = getattr(mod, class_name)
331
331
  if isinstance(type_obj, type):
332
- FlockRegistry.register_type(
332
+ registry.register_type(
333
333
  type_obj, type_name
334
334
  ) # Cache it
335
335
  return type_obj
@@ -356,12 +356,12 @@ def deserialize_component(
356
356
  data: dict | None, expected_base_type: type
357
357
  ) -> Any | None:
358
358
  """Deserializes a component (Module, Evaluator, Router) from its dict representation.
359
- Uses the 'type' field to find the correct class via FlockRegistry.
359
+ Uses the 'type' field to find the correct class via registry.
360
360
  """
361
361
  # Import the registry and COMPONENT_BASE_TYPES lazily when needed
362
- from flock.core.flock_registry import COMPONENT_BASE_TYPES, get_registry
362
+ from flock.core.registry import get_registry
363
363
 
364
- FlockRegistry = get_registry()
364
+ registry = get_registry()
365
365
 
366
366
  if data is None:
367
367
  return None
@@ -379,14 +379,17 @@ def deserialize_component(
379
379
  return None
380
380
 
381
381
  try:
382
- ComponentClass = FlockRegistry.get_component(type_name) # Use registry
382
+ ComponentClass = registry.get_component(type_name) # Use registry
383
383
  # Optional: Keep the base type check
384
- if COMPONENT_BASE_TYPES and not issubclass(
385
- ComponentClass, expected_base_type
386
- ):
387
- raise TypeError(
388
- f"Deserialized class {type_name} is not a subclass of {expected_base_type.__name__}"
389
- )
384
+ try:
385
+ from flock.core.component.agent_component_base import AgentComponent
386
+ if not issubclass(ComponentClass, AgentComponent):
387
+ logger.warning(
388
+ f"Deserialized class '{type_name}' is not a subclass of AgentComponent."
389
+ )
390
+ except ImportError:
391
+ # AgentComponent not available during setup
392
+ pass
390
393
 
391
394
  # Recursively deserialize the data *before* passing to Pydantic constructor
392
395
  # This handles nested callables/types within the component's config/data
@@ -259,7 +259,7 @@ async def _run_hydration_agent(
259
259
 
260
260
  # Run agent
261
261
  result = await temp_flock.run_async(
262
- start_agent=agent_name,
262
+ agent=agent_name,
263
263
  input=agent_input_data,
264
264
  box_result=False,
265
265
  )
@@ -45,7 +45,12 @@ def top_level_to_keys(s: str) -> list[str]:
45
45
 
46
46
 
47
47
  def resolve_inputs(
48
- input_spec: str, context: FlockContext, previous_agent_name: str
48
+ input_spec: str,
49
+ context: FlockContext,
50
+ previous_agent_name: str,
51
+ previous_agent_output:str,
52
+ previous_agent_handoff_strategy:str,
53
+ previous_agent_handoff_map:dict[str, str]
49
54
  ) -> dict:
50
55
  """Build a dictionary of inputs based on the input specification string and the provided context.
51
56
 
@@ -63,6 +68,28 @@ def resolve_inputs(
63
68
  eg. agent name: "idea_agent", variable: "ia_idea" (ia = idea agent)
64
69
  - or set hand off mode to strict to avoid conflicts.
65
70
  with strict mode, the agent will only accept inputs from the previous agent.
71
+
72
+
73
+ Strategy for passing data to the next agent.
74
+
75
+ Example:
76
+ ReviewAgent.next_agent = SummaryAgent
77
+ ReviewAgent(output = "text:str, keywords:list[str], rating:int")
78
+ SummaryAgent(input = "text:str, title:str")
79
+
80
+ 'append' means the difference in signature is appended to the next agent's input signature.
81
+ SummaryAgent(input = "text:str, title:str, keywords:list[str], rating:int")
82
+
83
+ 'override' means the target agent's signature is getting overriden.
84
+ SummaryAgent(input = "text:str, keywords:list[str], rating:int")
85
+
86
+ 'static' means the the target agent's signature is not changed at all.
87
+ If source agent has no output fields that match the target agent's input,
88
+ there will be no data passed to the next agent.
89
+ SummaryAgent(input = "text:str, title:str")
90
+
91
+ 'map' means the source agent's output is mapped to the target agent's input
92
+ based on 'handoff_map' configuration.
66
93
 
67
94
  Args:
68
95
  input_spec: Comma-separated input keys (e.g., "query" or "agent_name.property").
@@ -120,7 +147,7 @@ def resolve_inputs(
120
147
  inputs[key] = context.get_agent_definition(property_name)
121
148
  continue
122
149
 
123
- # Otherwise, attempt to look up a state variable with the key "agent_name.property"
150
+ # Otherwise, attempt to look up a state variable with the key "entity_name.property_name"
124
151
  inputs[key] = context.get_variable(f"{entity_name}.{property_name}")
125
152
  continue
126
153
 
@@ -15,12 +15,12 @@ from opentelemetry import trace
15
15
  from pydantic import Field
16
16
 
17
17
  from flock.core.logging.logging import get_logger
18
- from flock.core.mcp.flock_mcp_server import FlockMCPServerBase
19
- from flock.core.mcp.mcp_client import FlockMCPClientBase
20
- from flock.core.mcp.mcp_client_manager import FlockMCPClientManagerBase
18
+ from flock.core.mcp.flock_mcp_server import FlockMCPServer
19
+ from flock.core.mcp.mcp_client import FlockMCPClient
20
+ from flock.core.mcp.mcp_client_manager import FlockMCPClientManager
21
21
  from flock.core.mcp.mcp_config import (
22
- FlockMCPConfigurationBase,
23
- FlockMCPConnectionConfigurationBase,
22
+ FlockMCPConfiguration,
23
+ FlockMCPConnectionConfiguration,
24
24
  )
25
25
  from flock.core.mcp.types.types import SseServerParameters
26
26
 
@@ -28,7 +28,7 @@ logger = get_logger("mcp.sse.server")
28
28
  tracer = trace.get_tracer(__name__)
29
29
 
30
30
 
31
- class FlockSSEConnectionConfig(FlockMCPConnectionConfigurationBase):
31
+ class FlockSSEConnectionConfig(FlockMCPConnectionConfiguration):
32
32
  """Concrete ConnectionConfig for an SSEClient."""
33
33
 
34
34
  # Only thing we need to override here is the concrete transport_type
@@ -42,7 +42,7 @@ class FlockSSEConnectionConfig(FlockMCPConnectionConfigurationBase):
42
42
  )
43
43
 
44
44
 
45
- class FlockSSEConfig(FlockMCPConfigurationBase):
45
+ class FlockSSEConfig(FlockMCPConfiguration):
46
46
  """Configuration for SSE Clients."""
47
47
 
48
48
  # The only thing we need to override here is the concrete
@@ -53,7 +53,7 @@ class FlockSSEConfig(FlockMCPConfigurationBase):
53
53
  )
54
54
 
55
55
 
56
- class FlockSSEClient(FlockMCPClientBase):
56
+ class FlockSSEClient(FlockMCPClient):
57
57
  """Client for SSE Servers."""
58
58
 
59
59
  config: FlockSSEConfig = Field(..., description="Client configuration.")
@@ -115,7 +115,7 @@ class FlockSSEClient(FlockMCPClientBase):
115
115
  )
116
116
 
117
117
 
118
- class FlockSSEClientManager(FlockMCPClientManagerBase):
118
+ class FlockSSEClientManager(FlockMCPClientManager):
119
119
  """Manager for handling SSE Clients."""
120
120
 
121
121
  client_config: FlockSSEConfig = Field(
@@ -132,7 +132,7 @@ class FlockSSEClientManager(FlockMCPClientManagerBase):
132
132
  return new_client
133
133
 
134
134
 
135
- class FlockSSEServer(FlockMCPServerBase):
135
+ class FlockSSEServer(FlockMCPServer):
136
136
  """Class which represents a MCP Server using the SSE Transport type."""
137
137
 
138
138
  config: FlockSSEConfig = Field(..., description="Config for the server.")
@@ -14,12 +14,12 @@ from opentelemetry import trace
14
14
  from pydantic import Field
15
15
 
16
16
  from flock.core.logging.logging import get_logger
17
- from flock.core.mcp.flock_mcp_server import FlockMCPServerBase
18
- from flock.core.mcp.mcp_client import FlockMCPClientBase
19
- from flock.core.mcp.mcp_client_manager import FlockMCPClientManagerBase
17
+ from flock.core.mcp.flock_mcp_server import FlockMCPServer
18
+ from flock.core.mcp.mcp_client import FlockMCPClient
19
+ from flock.core.mcp.mcp_client_manager import FlockMCPClientManager
20
20
  from flock.core.mcp.mcp_config import (
21
- FlockMCPConfigurationBase,
22
- FlockMCPConnectionConfigurationBase,
21
+ FlockMCPConfiguration,
22
+ FlockMCPConnectionConfiguration,
23
23
  )
24
24
  from flock.core.mcp.types.types import StdioServerParameters
25
25
 
@@ -27,7 +27,7 @@ logger = get_logger("mcp.stdio.server")
27
27
  tracer = trace.get_tracer(__name__)
28
28
 
29
29
 
30
- class FlockStdioConnectionConfig(FlockMCPConnectionConfigurationBase):
30
+ class FlockStdioConnectionConfig(FlockMCPConnectionConfiguration):
31
31
  """Concrete ConnectionConfig for an StdioClient."""
32
32
 
33
33
  # Only thing we need to override here is the concrete transport_type
@@ -42,7 +42,7 @@ class FlockStdioConnectionConfig(FlockMCPConnectionConfigurationBase):
42
42
  )
43
43
 
44
44
 
45
- class FlockStdioConfig(FlockMCPConfigurationBase):
45
+ class FlockStdioConfig(FlockMCPConfiguration):
46
46
  """Configuration for Stdio Clients."""
47
47
 
48
48
  # The only thing we need to override here is the
@@ -53,7 +53,7 @@ class FlockStdioConfig(FlockMCPConfigurationBase):
53
53
  )
54
54
 
55
55
 
56
- class FlockStdioClient(FlockMCPClientBase):
56
+ class FlockStdioClient(FlockMCPClient):
57
57
  """Client for Stdio Servers."""
58
58
 
59
59
  config: FlockStdioConfig = Field(..., description="Client Configuration.")
@@ -104,7 +104,7 @@ class FlockStdioClient(FlockMCPClientBase):
104
104
 
105
105
 
106
106
  # Not really needed but kept here as an example.
107
- class FlockStdioClientManager(FlockMCPClientManagerBase):
107
+ class FlockStdioClientManager(FlockMCPClientManager):
108
108
  """Manager for handling Stdio Clients."""
109
109
 
110
110
  client_config: FlockStdioConfig = Field(
@@ -122,7 +122,7 @@ class FlockStdioClientManager(FlockMCPClientManagerBase):
122
122
  return new_client
123
123
 
124
124
 
125
- class FlockMCPStdioServer(FlockMCPServerBase):
125
+ class FlockMCPStdioServer(FlockMCPServer):
126
126
  """Class which represents a MCP Server using the Stdio Transport type.
127
127
 
128
128
  This means (most likely) that the server is a locally
@@ -17,12 +17,12 @@ from opentelemetry import trace
17
17
  from pydantic import Field
18
18
 
19
19
  from flock.core.logging.logging import get_logger
20
- from flock.core.mcp.flock_mcp_server import FlockMCPServerBase
21
- from flock.core.mcp.mcp_client import FlockMCPClientBase
22
- from flock.core.mcp.mcp_client_manager import FlockMCPClientManagerBase
20
+ from flock.core.mcp.flock_mcp_server import FlockMCPServer
21
+ from flock.core.mcp.mcp_client import FlockMCPClient
22
+ from flock.core.mcp.mcp_client_manager import FlockMCPClientManager
23
23
  from flock.core.mcp.mcp_config import (
24
- FlockMCPConfigurationBase,
25
- FlockMCPConnectionConfigurationBase,
24
+ FlockMCPConfiguration,
25
+ FlockMCPConnectionConfiguration,
26
26
  )
27
27
  from flock.core.mcp.types.types import (
28
28
  StreamableHttpServerParameters,
@@ -34,7 +34,7 @@ tracer = trace.get_tracer(__name__)
34
34
  GetSessionIdCallback = Callable[[], str | None]
35
35
 
36
36
 
37
- class FlockStreamableHttpConnectionConfig(FlockMCPConnectionConfigurationBase):
37
+ class FlockStreamableHttpConnectionConfig(FlockMCPConnectionConfiguration):
38
38
  """Concrete ConnectionConfig for a StreamableHttpClient."""
39
39
 
40
40
  # Only thing we need to override here is the concrete transport_type
@@ -49,7 +49,7 @@ class FlockStreamableHttpConnectionConfig(FlockMCPConnectionConfigurationBase):
49
49
  )
50
50
 
51
51
 
52
- class FlockStreamableHttpConfig(FlockMCPConfigurationBase):
52
+ class FlockStreamableHttpConfig(FlockMCPConfiguration):
53
53
  """Configuration for Streamable HTTP Clients."""
54
54
 
55
55
  # The only thing we need to override here is the
@@ -60,7 +60,7 @@ class FlockStreamableHttpConfig(FlockMCPConfigurationBase):
60
60
  )
61
61
 
62
62
 
63
- class FlockStreamableHttpClient(FlockMCPClientBase):
63
+ class FlockStreamableHttpClient(FlockMCPClient):
64
64
  """Client for StreamableHttpServers."""
65
65
 
66
66
  config: FlockStreamableHttpConfig = Field(
@@ -135,7 +135,7 @@ class FlockStreamableHttpClient(FlockMCPClientBase):
135
135
  )
136
136
 
137
137
 
138
- class FlockStreamableHttpClientManager(FlockMCPClientManagerBase):
138
+ class FlockStreamableHttpClientManager(FlockMCPClientManager):
139
139
  """Manager for handling StreamableHttpClients."""
140
140
 
141
141
  client_config: FlockStreamableHttpConfig = Field(
@@ -153,7 +153,7 @@ class FlockStreamableHttpClientManager(FlockMCPClientManagerBase):
153
153
  return new_client
154
154
 
155
155
 
156
- class FlockStreamableHttpServer(FlockMCPServerBase):
156
+ class FlockStreamableHttpServer(FlockMCPServer):
157
157
  """Class which represents a MCP Server using the streamable Http Transport type."""
158
158
 
159
159
  config: FlockStreamableHttpConfig = Field(
@@ -14,12 +14,12 @@ from opentelemetry import trace
14
14
  from pydantic import Field
15
15
 
16
16
  from flock.core.logging.logging import get_logger
17
- from flock.core.mcp.flock_mcp_server import FlockMCPServerBase
18
- from flock.core.mcp.mcp_client import FlockMCPClientBase
19
- from flock.core.mcp.mcp_client_manager import FlockMCPClientManagerBase
17
+ from flock.core.mcp.flock_mcp_server import FlockMCPServer
18
+ from flock.core.mcp.mcp_client import FlockMCPClient
19
+ from flock.core.mcp.mcp_client_manager import FlockMCPClientManager
20
20
  from flock.core.mcp.mcp_config import (
21
- FlockMCPConfigurationBase,
22
- FlockMCPConnectionConfigurationBase,
21
+ FlockMCPConfiguration,
22
+ FlockMCPConnectionConfiguration,
23
23
  )
24
24
  from flock.core.mcp.types.types import WebsocketServerParameters
25
25
 
@@ -28,7 +28,7 @@ tracer = trace.get_tracer(__name__)
28
28
 
29
29
 
30
30
  # Optional to provide type hints.
31
- class FlockWSConnectionConfig(FlockMCPConnectionConfigurationBase):
31
+ class FlockWSConnectionConfig(FlockMCPConnectionConfiguration):
32
32
  """Concrete ConnectionConfig for a WS Client."""
33
33
 
34
34
  # Only thing we need to override here is the concrete transport_type
@@ -44,7 +44,7 @@ class FlockWSConnectionConfig(FlockMCPConnectionConfigurationBase):
44
44
 
45
45
 
46
46
  # Optional to provide type hints.
47
- class FlockWSConfig(FlockMCPConfigurationBase):
47
+ class FlockWSConfig(FlockMCPConfiguration):
48
48
  """Configuration for Websocket clients."""
49
49
 
50
50
  # The only thing we need to override here is the concrete
@@ -56,7 +56,7 @@ class FlockWSConfig(FlockMCPConfigurationBase):
56
56
  )
57
57
 
58
58
 
59
- class FlockWSClient(FlockMCPClientBase):
59
+ class FlockWSClient(FlockMCPClient):
60
60
  """Client for Websocket servers."""
61
61
 
62
62
  config: FlockWSConfig = Field(..., description="Client Configuration")
@@ -90,7 +90,7 @@ class FlockWSClient(FlockMCPClientBase):
90
90
 
91
91
 
92
92
  # not really needed, but kept for type hints and as an example.
93
- class FlockWSClientManager(FlockMCPClientManagerBase):
93
+ class FlockWSClientManager(FlockMCPClientManager):
94
94
  """Manager for handling websocket clients."""
95
95
 
96
96
  client_config: FlockWSConfig = Field(
@@ -106,7 +106,7 @@ class FlockWSClientManager(FlockMCPClientManagerBase):
106
106
  return new_client
107
107
 
108
108
 
109
- class FlockWSServer(FlockMCPServerBase):
109
+ class FlockWSServer(FlockMCPServer):
110
110
  """Class which represents an MCP Server using the websocket transport type."""
111
111
 
112
112
  config: FlockWSConfig = Field(..., description="Config for the server.")