flock-core 0.4.0b25__py3-none-any.whl → 0.4.0b27__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 +10 -14
- flock/cli/load_release_notes.py +1 -4
- flock/core/context/context.py +10 -1
- flock/core/execution/temporal_executor.py +142 -25
- flock/core/flock.py +56 -6
- flock/core/flock_agent.py +146 -147
- flock/core/flock_factory.py +3 -0
- flock/core/util/cli_helper.py +8 -5
- flock/evaluators/declarative/declarative_evaluator.py +8 -4
- flock/modules/performance/metrics_module.py +3 -0
- flock/workflow/agent_execution_activity.py +228 -0
- flock/workflow/flock_workflow.py +225 -0
- flock/workflow/temporal_config.py +96 -0
- flock/workflow/temporal_setup.py +29 -7
- {flock_core-0.4.0b25.dist-info → flock_core-0.4.0b27.dist-info}/METADATA +31 -5
- {flock_core-0.4.0b25.dist-info → flock_core-0.4.0b27.dist-info}/RECORD +19 -17
- flock/workflow/workflow.py +0 -58
- {flock_core-0.4.0b25.dist-info → flock_core-0.4.0b27.dist-info}/WHEEL +0 -0
- {flock_core-0.4.0b25.dist-info → flock_core-0.4.0b27.dist-info}/entry_points.txt +0 -0
- {flock_core-0.4.0b25.dist-info → flock_core-0.4.0b27.dist-info}/licenses/LICENSE +0 -0
flock/core/flock_agent.py
CHANGED
|
@@ -10,6 +10,7 @@ from datetime import datetime
|
|
|
10
10
|
from typing import TYPE_CHECKING, Any, TypeVar
|
|
11
11
|
|
|
12
12
|
from flock.core.serialization.json_encoder import FlockJSONEncoder
|
|
13
|
+
from flock.workflow.temporal_config import TemporalActivityConfig
|
|
13
14
|
|
|
14
15
|
if TYPE_CHECKING:
|
|
15
16
|
from flock.core.context.context import FlockContext
|
|
@@ -19,7 +20,6 @@ if TYPE_CHECKING:
|
|
|
19
20
|
|
|
20
21
|
from opentelemetry import trace
|
|
21
22
|
from pydantic import BaseModel, Field
|
|
22
|
-
from rich.console import Console
|
|
23
23
|
|
|
24
24
|
# Core Flock components (ensure these are importable)
|
|
25
25
|
from flock.core.context.context import FlockContext
|
|
@@ -38,8 +38,6 @@ from flock.core.serialization.serialization_utils import (
|
|
|
38
38
|
serialize_item,
|
|
39
39
|
)
|
|
40
40
|
|
|
41
|
-
console = Console()
|
|
42
|
-
|
|
43
41
|
logger = get_logger("agent")
|
|
44
42
|
tracer = trace.get_tracer(__name__)
|
|
45
43
|
T = TypeVar("T", bound="FlockAgent")
|
|
@@ -113,6 +111,12 @@ class FlockAgent(BaseModel, Serializable, DSPyIntegrationMixin, ABC):
|
|
|
113
111
|
description="Dictionary of FlockModules attached to this agent.",
|
|
114
112
|
)
|
|
115
113
|
|
|
114
|
+
# --- Temporal Configuration (Optional) ---
|
|
115
|
+
temporal_activity_config: TemporalActivityConfig | None = Field(
|
|
116
|
+
default=None,
|
|
117
|
+
description="Optional Temporal settings specific to this agent's activity execution.",
|
|
118
|
+
)
|
|
119
|
+
|
|
116
120
|
# --- Runtime State (Excluded from Serialization) ---
|
|
117
121
|
context: FlockContext | None = Field(
|
|
118
122
|
default=None,
|
|
@@ -133,6 +137,7 @@ class FlockAgent(BaseModel, Serializable, DSPyIntegrationMixin, ABC):
|
|
|
133
137
|
modules: dict[str, "FlockModule"] | None = None, # Use dict for modules
|
|
134
138
|
write_to_file: bool = False,
|
|
135
139
|
wait_for_input: bool = False,
|
|
140
|
+
temporal_activity_config: TemporalActivityConfig | None = None,
|
|
136
141
|
**kwargs,
|
|
137
142
|
):
|
|
138
143
|
super().__init__(
|
|
@@ -149,6 +154,7 @@ class FlockAgent(BaseModel, Serializable, DSPyIntegrationMixin, ABC):
|
|
|
149
154
|
modules=modules
|
|
150
155
|
if modules is not None
|
|
151
156
|
else {}, # Ensure modules is a dict
|
|
157
|
+
temporal_activity_config=temporal_activity_config,
|
|
152
158
|
**kwargs,
|
|
153
159
|
)
|
|
154
160
|
|
|
@@ -230,8 +236,7 @@ class FlockAgent(BaseModel, Serializable, DSPyIntegrationMixin, ABC):
|
|
|
230
236
|
|
|
231
237
|
if self.write_to_file:
|
|
232
238
|
self._save_output(self.name, result)
|
|
233
|
-
|
|
234
|
-
console.input(prompt="Press Enter to continue...")
|
|
239
|
+
|
|
235
240
|
except Exception as module_error:
|
|
236
241
|
logger.error(
|
|
237
242
|
"Error during terminate",
|
|
@@ -727,202 +732,196 @@ class FlockAgent(BaseModel, Serializable, DSPyIntegrationMixin, ABC):
|
|
|
727
732
|
|
|
728
733
|
@classmethod
|
|
729
734
|
def from_dict(cls: type[T], data: dict[str, Any]) -> T:
|
|
730
|
-
"""
|
|
731
|
-
from flock.core.flock_registry import
|
|
732
|
-
|
|
733
|
-
logger.debug(
|
|
734
|
-
f"Deserializing agent from dict. Provided keys: {list(data.keys())}"
|
|
735
|
+
"""Deserialize the agent from a dictionary, including components, tools, and callables."""
|
|
736
|
+
from flock.core.flock_registry import (
|
|
737
|
+
get_registry, # Import registry locally
|
|
735
738
|
)
|
|
736
|
-
if "name" not in data:
|
|
737
|
-
raise ValueError("Agent data must include a 'name' field.")
|
|
738
|
-
FlockRegistry = get_registry()
|
|
739
|
-
agent_name = data["name"] # For logging context
|
|
740
|
-
logger.info(f"Deserializing agent '{agent_name}'")
|
|
741
|
-
|
|
742
|
-
# Pop complex components to handle them after basic agent instantiation
|
|
743
|
-
evaluator_data = data.pop("evaluator", None)
|
|
744
|
-
router_data = data.pop("handoff_router", None)
|
|
745
|
-
modules_data = data.pop("modules", {})
|
|
746
|
-
tools_data = data.pop("tools", [])
|
|
747
|
-
description_callable = data.pop("description_callable", None)
|
|
748
|
-
input_callable = data.pop("input_callable", None)
|
|
749
|
-
output_callable = data.pop("output_callable", None)
|
|
750
739
|
|
|
740
|
+
registry = get_registry()
|
|
751
741
|
logger.debug(
|
|
752
|
-
f"
|
|
742
|
+
f"Deserializing agent from dict. Keys: {list(data.keys())}"
|
|
753
743
|
)
|
|
754
744
|
|
|
755
|
-
#
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
745
|
+
# --- Separate Data ---
|
|
746
|
+
component_configs = {}
|
|
747
|
+
callable_configs = {}
|
|
748
|
+
tool_config = []
|
|
749
|
+
agent_data = {}
|
|
750
|
+
|
|
751
|
+
component_keys = [
|
|
752
|
+
"evaluator",
|
|
753
|
+
"handoff_router",
|
|
754
|
+
"modules",
|
|
755
|
+
"temporal_activity_config",
|
|
756
|
+
]
|
|
757
|
+
callable_keys = [
|
|
758
|
+
"description_callable",
|
|
759
|
+
"input_callable",
|
|
760
|
+
"output_callable",
|
|
761
|
+
]
|
|
762
|
+
tool_key = "tools"
|
|
763
|
+
|
|
764
|
+
for key, value in data.items():
|
|
765
|
+
if key in component_keys and value is not None:
|
|
766
|
+
component_configs[key] = value
|
|
767
|
+
elif key in callable_keys and value is not None:
|
|
768
|
+
callable_configs[key] = value
|
|
769
|
+
elif key == tool_key and value is not None:
|
|
770
|
+
tool_config = value # Expecting a list of names
|
|
771
|
+
elif key not in component_keys + callable_keys + [
|
|
772
|
+
tool_key
|
|
773
|
+
]: # Avoid double adding
|
|
774
|
+
agent_data[key] = value
|
|
775
|
+
# else: ignore keys that are None or already handled
|
|
776
|
+
|
|
777
|
+
# --- Deserialize Base Agent ---
|
|
778
|
+
# Ensure required fields like 'name' are present if needed by __init__
|
|
779
|
+
if "name" not in agent_data:
|
|
772
780
|
raise ValueError(
|
|
773
|
-
|
|
774
|
-
)
|
|
781
|
+
"Agent data must include a 'name' field for deserialization."
|
|
782
|
+
)
|
|
783
|
+
agent_name_log = agent_data["name"] # For logging
|
|
784
|
+
logger.info(f"Deserializing base agent data for '{agent_name_log}'")
|
|
785
|
+
|
|
786
|
+
# Pydantic should handle base fields based on type hints in __init__
|
|
787
|
+
agent = cls(**agent_data)
|
|
788
|
+
logger.debug(f"Base agent '{agent.name}' instantiated.")
|
|
775
789
|
|
|
776
|
-
# --- Deserialize
|
|
790
|
+
# --- Deserialize Components ---
|
|
791
|
+
logger.debug(f"Deserializing components for '{agent.name}'")
|
|
777
792
|
# Evaluator
|
|
778
|
-
if
|
|
793
|
+
if "evaluator" in component_configs:
|
|
779
794
|
try:
|
|
780
|
-
logger.debug(
|
|
781
|
-
f"Deserializing evaluator for agent '{agent_name}'"
|
|
782
|
-
)
|
|
783
795
|
agent.evaluator = deserialize_component(
|
|
784
|
-
|
|
785
|
-
)
|
|
786
|
-
if agent.evaluator is None:
|
|
787
|
-
raise ValueError("deserialize_component returned None")
|
|
788
|
-
logger.debug(
|
|
789
|
-
f"Deserialized evaluator '{agent.evaluator.name}' of type '{evaluator_data.get('type')}' for agent '{agent_name}'"
|
|
796
|
+
component_configs["evaluator"], FlockEvaluator
|
|
790
797
|
)
|
|
798
|
+
logger.debug(f"Deserialized evaluator for '{agent.name}'")
|
|
791
799
|
except Exception as e:
|
|
792
800
|
logger.error(
|
|
793
|
-
f"Failed to deserialize evaluator for
|
|
801
|
+
f"Failed to deserialize evaluator for '{agent.name}': {e}",
|
|
794
802
|
exc_info=True,
|
|
795
803
|
)
|
|
796
|
-
# Decide: raise error or continue without evaluator?
|
|
797
|
-
# raise ValueError(f"Failed to deserialize evaluator for agent '{agent_name}': {e}") from e
|
|
798
804
|
|
|
799
|
-
# Router
|
|
800
|
-
if
|
|
805
|
+
# Handoff Router
|
|
806
|
+
if "handoff_router" in component_configs:
|
|
801
807
|
try:
|
|
802
|
-
logger.debug(f"Deserializing router for agent '{agent_name}'")
|
|
803
808
|
agent.handoff_router = deserialize_component(
|
|
804
|
-
|
|
805
|
-
)
|
|
806
|
-
if agent.handoff_router is None:
|
|
807
|
-
raise ValueError("deserialize_component returned None")
|
|
808
|
-
logger.debug(
|
|
809
|
-
f"Deserialized router '{agent.handoff_router.name}' of type '{router_data.get('type')}' for agent '{agent_name}'"
|
|
809
|
+
component_configs["handoff_router"], FlockRouter
|
|
810
810
|
)
|
|
811
|
+
logger.debug(f"Deserialized handoff_router for '{agent.name}'")
|
|
811
812
|
except Exception as e:
|
|
812
813
|
logger.error(
|
|
813
|
-
f"Failed to deserialize
|
|
814
|
+
f"Failed to deserialize handoff_router for '{agent.name}': {e}",
|
|
814
815
|
exc_info=True,
|
|
815
816
|
)
|
|
816
|
-
# Decide: raise error or continue without router?
|
|
817
817
|
|
|
818
818
|
# Modules
|
|
819
|
-
if
|
|
820
|
-
agent.modules = {} #
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
)
|
|
824
|
-
for name, module_data in modules_data.items():
|
|
819
|
+
if "modules" in component_configs:
|
|
820
|
+
agent.modules = {} # Initialize
|
|
821
|
+
for module_name, module_data in component_configs[
|
|
822
|
+
"modules"
|
|
823
|
+
].items():
|
|
825
824
|
try:
|
|
826
|
-
logger.debug(
|
|
827
|
-
f"Deserializing module '{name}' of type '{module_data.get('type')}' for agent '{agent_name}'"
|
|
828
|
-
)
|
|
829
825
|
module_instance = deserialize_component(
|
|
830
826
|
module_data, FlockModule
|
|
831
827
|
)
|
|
832
828
|
if module_instance:
|
|
833
|
-
#
|
|
834
|
-
|
|
835
|
-
agent.add_module(
|
|
836
|
-
module_instance
|
|
837
|
-
) # Use add_module for consistency
|
|
829
|
+
# Use add_module for potential logic within it
|
|
830
|
+
agent.add_module(module_instance)
|
|
838
831
|
logger.debug(
|
|
839
|
-
f"
|
|
832
|
+
f"Deserialized and added module '{module_name}' for '{agent.name}'"
|
|
840
833
|
)
|
|
841
|
-
else:
|
|
842
|
-
raise ValueError("deserialize_component returned None")
|
|
843
834
|
except Exception as e:
|
|
844
835
|
logger.error(
|
|
845
|
-
f"Failed to deserialize module '{
|
|
836
|
+
f"Failed to deserialize module '{module_name}' for '{agent.name}': {e}",
|
|
846
837
|
exc_info=True,
|
|
847
838
|
)
|
|
848
|
-
|
|
839
|
+
|
|
840
|
+
# Temporal Activity Config
|
|
841
|
+
if "temporal_activity_config" in component_configs:
|
|
842
|
+
try:
|
|
843
|
+
agent.temporal_activity_config = TemporalActivityConfig(
|
|
844
|
+
**component_configs["temporal_activity_config"]
|
|
845
|
+
)
|
|
846
|
+
logger.debug(
|
|
847
|
+
f"Deserialized temporal_activity_config for '{agent.name}'"
|
|
848
|
+
)
|
|
849
|
+
except Exception as e:
|
|
850
|
+
logger.error(
|
|
851
|
+
f"Failed to deserialize temporal_activity_config for '{agent.name}': {e}",
|
|
852
|
+
exc_info=True,
|
|
853
|
+
)
|
|
854
|
+
agent.temporal_activity_config = None
|
|
849
855
|
|
|
850
856
|
# --- Deserialize Tools ---
|
|
851
857
|
agent.tools = [] # Initialize tools list
|
|
852
|
-
if
|
|
853
|
-
# Get component registry to look up function imports
|
|
854
|
-
registry = get_registry()
|
|
855
|
-
components = getattr(registry, "_callables", {})
|
|
858
|
+
if tool_config:
|
|
856
859
|
logger.debug(
|
|
857
|
-
f"Deserializing {len(
|
|
860
|
+
f"Deserializing {len(tool_config)} tools for '{agent.name}'"
|
|
858
861
|
)
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
)
|
|
862
|
-
|
|
863
|
-
for tool_name in tools_data:
|
|
862
|
+
# Use get_callable to find each tool
|
|
863
|
+
for tool_name_or_path in tool_config:
|
|
864
864
|
try:
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
for path_str, func in components.items():
|
|
869
|
-
if (
|
|
870
|
-
path_str.endswith("." + tool_name)
|
|
871
|
-
or path_str == tool_name
|
|
872
|
-
):
|
|
873
|
-
agent.tools.append(func)
|
|
874
|
-
found = True
|
|
875
|
-
logger.info(
|
|
876
|
-
f"Found tool '{tool_name}' via path '{path_str}' for agent '{agent_name}'"
|
|
877
|
-
)
|
|
878
|
-
break
|
|
879
|
-
|
|
880
|
-
# If not found by simple name, try manual import
|
|
881
|
-
if not found:
|
|
865
|
+
found_tool = registry.get_callable(tool_name_or_path)
|
|
866
|
+
if found_tool and callable(found_tool):
|
|
867
|
+
agent.tools.append(found_tool)
|
|
882
868
|
logger.debug(
|
|
883
|
-
f"
|
|
869
|
+
f"Resolved and added tool '{tool_name_or_path}' for agent '{agent.name}'"
|
|
884
870
|
)
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
if hasattr(__main__, tool_name):
|
|
889
|
-
agent.tools.append(getattr(__main__, tool_name))
|
|
890
|
-
found = True
|
|
891
|
-
logger.info(
|
|
892
|
-
f"Found tool '{tool_name}' in __main__ module for agent '{agent_name}'"
|
|
893
|
-
)
|
|
894
|
-
|
|
895
|
-
if not found:
|
|
871
|
+
else:
|
|
872
|
+
# Should not happen if get_callable returns successfully but just in case
|
|
896
873
|
logger.warning(
|
|
897
|
-
f"
|
|
874
|
+
f"Registry returned non-callable for tool '{tool_name_or_path}' for agent '{agent.name}'. Skipping."
|
|
898
875
|
)
|
|
876
|
+
except (
|
|
877
|
+
ValueError
|
|
878
|
+
) as e: # get_callable raises ValueError if not found/ambiguous
|
|
879
|
+
logger.warning(
|
|
880
|
+
f"Could not resolve tool '{tool_name_or_path}' for agent '{agent.name}': {e}. Skipping."
|
|
881
|
+
)
|
|
899
882
|
except Exception as e:
|
|
900
883
|
logger.error(
|
|
901
|
-
f"
|
|
884
|
+
f"Unexpected error resolving tool '{tool_name_or_path}' for agent '{agent.name}': {e}. Skipping.",
|
|
902
885
|
exc_info=True,
|
|
903
886
|
)
|
|
904
887
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
)
|
|
909
|
-
agent.description = components[description_callable]
|
|
888
|
+
# --- Deserialize Callables ---
|
|
889
|
+
logger.debug(f"Deserializing callable fields for '{agent.name}'")
|
|
890
|
+
# available_callables = registry.get_all_callables() # Incorrect
|
|
910
891
|
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
892
|
+
def resolve_and_assign(field_name: str, callable_key: str):
|
|
893
|
+
if callable_key in callable_configs:
|
|
894
|
+
callable_name = callable_configs[callable_key]
|
|
895
|
+
try:
|
|
896
|
+
# Use get_callable to find the signature function
|
|
897
|
+
found_callable = registry.get_callable(callable_name)
|
|
898
|
+
if found_callable and callable(found_callable):
|
|
899
|
+
setattr(agent, field_name, found_callable)
|
|
900
|
+
logger.debug(
|
|
901
|
+
f"Resolved callable '{callable_name}' for field '{field_name}' on agent '{agent.name}'"
|
|
902
|
+
)
|
|
903
|
+
else:
|
|
904
|
+
logger.warning(
|
|
905
|
+
f"Registry returned non-callable for name '{callable_name}' for field '{field_name}' on agent '{agent.name}'. Field remains default."
|
|
906
|
+
)
|
|
907
|
+
except (
|
|
908
|
+
ValueError
|
|
909
|
+
) as e: # get_callable raises ValueError if not found/ambiguous
|
|
910
|
+
logger.warning(
|
|
911
|
+
f"Could not resolve callable '{callable_name}' in registry for field '{field_name}' on agent '{agent.name}': {e}. Field remains default."
|
|
912
|
+
)
|
|
913
|
+
except Exception as e:
|
|
914
|
+
logger.error(
|
|
915
|
+
f"Unexpected error resolving callable '{callable_name}' for field '{field_name}' on agent '{agent.name}': {e}. Field remains default.",
|
|
916
|
+
exc_info=True,
|
|
917
|
+
)
|
|
918
|
+
# Else: key not present, field retains its default value from __init__
|
|
916
919
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
)
|
|
921
|
-
agent.output = components[output_callable]
|
|
920
|
+
resolve_and_assign("description", "description_callable")
|
|
921
|
+
resolve_and_assign("input", "input_callable")
|
|
922
|
+
resolve_and_assign("output", "output_callable")
|
|
922
923
|
|
|
923
|
-
logger.info(
|
|
924
|
-
f"Successfully deserialized agent '{agent_name}' with {len(agent.modules)} modules and {len(agent.tools)} tools"
|
|
925
|
-
)
|
|
924
|
+
logger.info(f"Successfully deserialized agent '{agent.name}'.")
|
|
926
925
|
return agent
|
|
927
926
|
|
|
928
927
|
# --- Pydantic v2 Configuration ---
|
flock/core/flock_factory.py
CHANGED
|
@@ -14,6 +14,7 @@ from flock.modules.performance.metrics_module import (
|
|
|
14
14
|
MetricsModule,
|
|
15
15
|
MetricsModuleConfig,
|
|
16
16
|
)
|
|
17
|
+
from flock.workflow.temporal_config import TemporalActivityConfig
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class FlockFactory:
|
|
@@ -39,6 +40,7 @@ class FlockFactory:
|
|
|
39
40
|
write_to_file: bool = False,
|
|
40
41
|
stream: bool = False,
|
|
41
42
|
include_thought_process: bool = False,
|
|
43
|
+
temporal_activity_config: TemporalActivityConfig | None = None,
|
|
42
44
|
) -> FlockAgent:
|
|
43
45
|
"""Creates a default FlockAgent.
|
|
44
46
|
|
|
@@ -69,6 +71,7 @@ class FlockFactory:
|
|
|
69
71
|
evaluator=evaluator,
|
|
70
72
|
write_to_file=write_to_file,
|
|
71
73
|
wait_for_input=wait_for_input,
|
|
74
|
+
temporal_activity_config=temporal_activity_config,
|
|
72
75
|
)
|
|
73
76
|
output_config = OutputModuleConfig(
|
|
74
77
|
render_table=enable_rich_tables,
|
flock/core/util/cli_helper.py
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
from importlib.metadata import PackageNotFoundError, version
|
|
2
2
|
|
|
3
|
-
from rich.console import Console
|
|
4
|
-
from rich.syntax import Text
|
|
5
|
-
|
|
6
3
|
try:
|
|
7
4
|
__version__ = version("flock-core")
|
|
8
5
|
except PackageNotFoundError:
|
|
9
6
|
__version__ = "0.2.0"
|
|
10
7
|
|
|
11
|
-
console = Console()
|
|
12
|
-
|
|
13
8
|
|
|
14
9
|
def display_hummingbird():
|
|
15
10
|
"""Display the hummingbird."""
|
|
@@ -45,6 +40,10 @@ def display_hummingbird():
|
|
|
45
40
|
|
|
46
41
|
def init_console(clear_screen: bool = True, show_banner: bool = True):
|
|
47
42
|
"""Display the Flock banner."""
|
|
43
|
+
from rich.console import Console
|
|
44
|
+
from rich.syntax import Text
|
|
45
|
+
|
|
46
|
+
console = Console()
|
|
48
47
|
banner_text = Text(
|
|
49
48
|
f"""
|
|
50
49
|
🦆 🐓 🐤 🐧
|
|
@@ -70,6 +69,10 @@ def init_console(clear_screen: bool = True, show_banner: bool = True):
|
|
|
70
69
|
|
|
71
70
|
def display_banner_no_version():
|
|
72
71
|
"""Display the Flock banner."""
|
|
72
|
+
from rich.console import Console
|
|
73
|
+
from rich.syntax import Text
|
|
74
|
+
|
|
75
|
+
console = Console()
|
|
73
76
|
banner_text = Text(
|
|
74
77
|
"""
|
|
75
78
|
🦆 🐓 🐤 🐧
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
from collections.abc import Generator
|
|
2
2
|
from typing import Any
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
from temporalio import workflow
|
|
5
|
+
|
|
6
|
+
with workflow.unsafe.imports_passed_through():
|
|
7
|
+
import dspy
|
|
8
|
+
|
|
5
9
|
from pydantic import Field, PrivateAttr
|
|
6
|
-
from rich.console import Console
|
|
7
10
|
|
|
8
11
|
from flock.core.flock_agent import FlockAgent
|
|
9
12
|
from flock.core.flock_evaluator import FlockEvaluator, FlockEvaluatorConfig
|
|
@@ -12,8 +15,6 @@ from flock.core.logging.logging import get_logger
|
|
|
12
15
|
from flock.core.mixin.dspy_integration import DSPyIntegrationMixin
|
|
13
16
|
from flock.core.mixin.prompt_parser import PromptParserMixin
|
|
14
17
|
|
|
15
|
-
console = Console()
|
|
16
|
-
|
|
17
18
|
logger = get_logger("evaluators.declarative")
|
|
18
19
|
|
|
19
20
|
|
|
@@ -56,6 +57,9 @@ class DeclarativeEvaluator(
|
|
|
56
57
|
"""Evaluate using DSPy, with optional asynchronous streaming."""
|
|
57
58
|
# --- Setup Signature and LM ---
|
|
58
59
|
try:
|
|
60
|
+
from rich.console import Console
|
|
61
|
+
|
|
62
|
+
console = Console()
|
|
59
63
|
_dspy_signature = self.create_dspy_signature_class(
|
|
60
64
|
agent.name,
|
|
61
65
|
agent.description,
|