flock-core 0.4.0b11__py3-none-any.whl → 0.4.0b13__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/core/flock_factory.py +2 -0
- flock/core/serialization/flock_serializer.py +60 -0
- flock/evaluators/declarative/declarative_evaluator.py +95 -21
- {flock_core-0.4.0b11.dist-info → flock_core-0.4.0b13.dist-info}/METADATA +1 -1
- {flock_core-0.4.0b11.dist-info → flock_core-0.4.0b13.dist-info}/RECORD +8 -8
- {flock_core-0.4.0b11.dist-info → flock_core-0.4.0b13.dist-info}/WHEEL +0 -0
- {flock_core-0.4.0b11.dist-info → flock_core-0.4.0b13.dist-info}/entry_points.txt +0 -0
- {flock_core-0.4.0b11.dist-info → flock_core-0.4.0b13.dist-info}/licenses/LICENSE +0 -0
flock/core/flock_factory.py
CHANGED
|
@@ -37,6 +37,7 @@ class FlockFactory:
|
|
|
37
37
|
no_output: bool = False,
|
|
38
38
|
print_context: bool = False,
|
|
39
39
|
write_to_file: bool = False,
|
|
40
|
+
stream: bool = False,
|
|
40
41
|
) -> FlockAgent:
|
|
41
42
|
"""Creates a default FlockAgent.
|
|
42
43
|
|
|
@@ -50,6 +51,7 @@ class FlockFactory:
|
|
|
50
51
|
use_cache=use_cache,
|
|
51
52
|
max_tokens=max_tokens,
|
|
52
53
|
temperature=temperature,
|
|
54
|
+
stream=stream,
|
|
53
55
|
)
|
|
54
56
|
|
|
55
57
|
evaluator = DeclarativeEvaluator(name="default", config=eval_config)
|
|
@@ -145,6 +145,66 @@ class FlockSerializer:
|
|
|
145
145
|
)
|
|
146
146
|
)
|
|
147
147
|
|
|
148
|
+
# Description (Callables)
|
|
149
|
+
if agent_data.get("description_callable"):
|
|
150
|
+
logger.debug(
|
|
151
|
+
f"Adding description callable '{agent_data['description_callable']}' from agent '{name}'"
|
|
152
|
+
)
|
|
153
|
+
description_callable_name = agent_data[
|
|
154
|
+
"description_callable"
|
|
155
|
+
]
|
|
156
|
+
description_callable = agent_instance.description
|
|
157
|
+
path_str = FlockRegistry.get_callable_path_string(
|
|
158
|
+
description_callable
|
|
159
|
+
)
|
|
160
|
+
if path_str:
|
|
161
|
+
logger.debug(
|
|
162
|
+
f"Adding description callable '{description_callable_name}' (from path '{path_str}') to components"
|
|
163
|
+
)
|
|
164
|
+
components[description_callable_name] = (
|
|
165
|
+
FlockSerializer._get_callable_definition(
|
|
166
|
+
path_str, description_callable_name, path_type
|
|
167
|
+
)
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
if agent_data.get("input_callable"):
|
|
171
|
+
logger.debug(
|
|
172
|
+
f"Adding input callable '{agent_data['input_callable']}' from agent '{name}'"
|
|
173
|
+
)
|
|
174
|
+
input_callable_name = agent_data["input_callable"]
|
|
175
|
+
input_callable = agent_instance.input
|
|
176
|
+
path_str = FlockRegistry.get_callable_path_string(
|
|
177
|
+
input_callable
|
|
178
|
+
)
|
|
179
|
+
if path_str:
|
|
180
|
+
logger.debug(
|
|
181
|
+
f"Adding input callable '{input_callable_name}' (from path '{path_str}') to components"
|
|
182
|
+
)
|
|
183
|
+
components[input_callable_name] = (
|
|
184
|
+
FlockSerializer._get_callable_definition(
|
|
185
|
+
path_str, input_callable_name, path_type
|
|
186
|
+
)
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
if agent_data.get("output_callable"):
|
|
190
|
+
logger.debug(
|
|
191
|
+
f"Adding output callable '{agent_data['output_callable']}' from agent '{name}'"
|
|
192
|
+
)
|
|
193
|
+
output_callable_name = agent_data["output_callable"]
|
|
194
|
+
output_callable = agent_instance.output
|
|
195
|
+
path_str = FlockRegistry.get_callable_path_string(
|
|
196
|
+
output_callable
|
|
197
|
+
)
|
|
198
|
+
if path_str:
|
|
199
|
+
logger.debug(
|
|
200
|
+
f"Adding output callable '{output_callable_name}' (from path '{path_str}') to components"
|
|
201
|
+
)
|
|
202
|
+
components[output_callable_name] = (
|
|
203
|
+
FlockSerializer._get_callable_definition(
|
|
204
|
+
path_str, output_callable_name, path_type
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
|
|
148
208
|
# Tools (Callables)
|
|
149
209
|
if agent_data.get("tools"):
|
|
150
210
|
logger.debug(
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
+
from collections.abc import Generator
|
|
1
2
|
from typing import Any
|
|
2
3
|
|
|
4
|
+
import dspy
|
|
3
5
|
from pydantic import Field
|
|
6
|
+
from rich.console import Console
|
|
4
7
|
|
|
5
8
|
from flock.core.flock_agent import FlockAgent
|
|
6
9
|
from flock.core.flock_evaluator import FlockEvaluator, FlockEvaluatorConfig
|
|
10
|
+
from flock.core.logging.logging import get_logger
|
|
7
11
|
from flock.core.mixin.dspy_integration import DSPyIntegrationMixin
|
|
8
12
|
from flock.core.mixin.prompt_parser import PromptParserMixin
|
|
9
13
|
|
|
14
|
+
console = Console()
|
|
15
|
+
|
|
16
|
+
logger = get_logger("evaluators.declarative")
|
|
17
|
+
|
|
10
18
|
|
|
11
19
|
class DeclarativeEvaluatorConfig(FlockEvaluatorConfig):
|
|
12
20
|
"""Configuration for the DeclarativeEvaluator."""
|
|
@@ -16,6 +24,10 @@ class DeclarativeEvaluatorConfig(FlockEvaluatorConfig):
|
|
|
16
24
|
use_cache: bool = True
|
|
17
25
|
temperature: float = 0.0
|
|
18
26
|
max_tokens: int = 4096
|
|
27
|
+
stream: bool = Field(
|
|
28
|
+
default=False,
|
|
29
|
+
description="Enable streaming output from the underlying DSPy program.",
|
|
30
|
+
)
|
|
19
31
|
|
|
20
32
|
|
|
21
33
|
class DeclarativeEvaluator(
|
|
@@ -31,24 +43,86 @@ class DeclarativeEvaluator(
|
|
|
31
43
|
async def evaluate(
|
|
32
44
|
self, agent: FlockAgent, inputs: dict[str, Any], tools: list[Any]
|
|
33
45
|
) -> dict[str, Any]:
|
|
34
|
-
"""Evaluate using DSPy."""
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
"""Evaluate using DSPy, with optional asynchronous streaming."""
|
|
47
|
+
# --- Setup Signature and LM ---
|
|
48
|
+
try:
|
|
49
|
+
_dspy_signature = self.create_dspy_signature_class(
|
|
50
|
+
agent.name,
|
|
51
|
+
agent.description,
|
|
52
|
+
f"{agent.input} -> {agent.output}",
|
|
53
|
+
)
|
|
54
|
+
# --- Get output field names ---
|
|
55
|
+
# dspy.Signature holds fields in .output_fields attribute
|
|
56
|
+
output_field_names = list(_dspy_signature.output_fields.keys())
|
|
57
|
+
if not output_field_names:
|
|
58
|
+
logger.warning(
|
|
59
|
+
f"DSPy signature for agent '{agent.name}' has no defined output fields. Streaming might not produce text."
|
|
60
|
+
)
|
|
61
|
+
# -----------------------------
|
|
62
|
+
|
|
63
|
+
self._configure_language_model(
|
|
64
|
+
model=self.config.model or agent.model,
|
|
65
|
+
use_cache=self.config.use_cache,
|
|
66
|
+
temperature=self.config.temperature,
|
|
67
|
+
max_tokens=self.config.max_tokens,
|
|
68
|
+
)
|
|
69
|
+
agent_task = self._select_task(
|
|
70
|
+
_dspy_signature,
|
|
71
|
+
agent_type_override=self.config.agent_type_override,
|
|
72
|
+
tools=tools,
|
|
73
|
+
)
|
|
74
|
+
except Exception as setup_error:
|
|
75
|
+
logger.error(
|
|
76
|
+
f"Error setting up DSPy task for agent '{agent.name}': {setup_error}",
|
|
77
|
+
exc_info=True,
|
|
78
|
+
)
|
|
79
|
+
raise RuntimeError(
|
|
80
|
+
f"DSPy task setup failed: {setup_error}"
|
|
81
|
+
) from setup_error
|
|
82
|
+
|
|
83
|
+
# --- Conditional Evaluation (Stream vs No Stream) ---
|
|
84
|
+
if self.config.stream:
|
|
85
|
+
logger.info(
|
|
86
|
+
f"Evaluating agent '{agent.name}' with async streaming."
|
|
87
|
+
)
|
|
88
|
+
if not callable(agent_task):
|
|
89
|
+
logger.error("agent_task is not callable, cannot stream.")
|
|
90
|
+
raise TypeError(
|
|
91
|
+
"DSPy task could not be created or is not callable."
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
streaming_task = dspy.streamify(agent_task)
|
|
95
|
+
stream_generator: Generator = streaming_task(**inputs)
|
|
96
|
+
|
|
97
|
+
console.print("\n")
|
|
98
|
+
async for chunk in stream_generator:
|
|
99
|
+
if (
|
|
100
|
+
hasattr(chunk, "choices")
|
|
101
|
+
and chunk.choices
|
|
102
|
+
and hasattr(chunk.choices[0], "delta")
|
|
103
|
+
and chunk.choices[0].delta
|
|
104
|
+
and hasattr(chunk.choices[0].delta, "content")
|
|
105
|
+
):
|
|
106
|
+
delta_content = chunk.choices[0].delta.content
|
|
107
|
+
|
|
108
|
+
if delta_content:
|
|
109
|
+
console.print(delta_content, end="")
|
|
110
|
+
|
|
111
|
+
result_dict = self._process_result(chunk, inputs)
|
|
112
|
+
|
|
113
|
+
console.print("\n")
|
|
114
|
+
return result_dict
|
|
115
|
+
|
|
116
|
+
else: # Non-streaming path
|
|
117
|
+
logger.info(f"Evaluating agent '{agent.name}' without streaming.")
|
|
118
|
+
try:
|
|
119
|
+
# Ensure the call is awaited if the underlying task is async
|
|
120
|
+
result_obj = await agent_task(**inputs)
|
|
121
|
+
result_dict = self._process_result(result_obj, inputs)
|
|
122
|
+
return result_dict
|
|
123
|
+
except Exception as e:
|
|
124
|
+
logger.error(
|
|
125
|
+
f"Error during non-streaming evaluation for agent '{agent.name}': {e}",
|
|
126
|
+
exc_info=True,
|
|
127
|
+
)
|
|
128
|
+
raise RuntimeError(f"Evaluation failed: {e}") from e
|
|
@@ -21,7 +21,7 @@ flock/core/__init__.py,sha256=p7lmQULRu9ejIAELfanZiyMhW0CougIPvyFHW2nqBFQ,847
|
|
|
21
21
|
flock/core/flock.py,sha256=zQUpITLx_CMhJRnft4AWQDfYj85FhUlT-Ank5c-fSko,25146
|
|
22
22
|
flock/core/flock_agent.py,sha256=uFVr8eVWZ4uowH659fdOvVuBD4fx695Zm9UB9pOQKDU,32223
|
|
23
23
|
flock/core/flock_evaluator.py,sha256=dOXZeDOGZcAmJ9ahqq_2bdGUU1VOXY4skmwTVpAjiVw,1685
|
|
24
|
-
flock/core/flock_factory.py,sha256=
|
|
24
|
+
flock/core/flock_factory.py,sha256=ym2ZIdDXzV_Ym5JdRUvFJRIkLIVCj017M6-AXQ7VkW8,2885
|
|
25
25
|
flock/core/flock_module.py,sha256=96aFVYAgwpKN53xGbivQDUpikOYGFCxK5mqhclOcxY0,3003
|
|
26
26
|
flock/core/flock_registry.py,sha256=ekYpQgSkZVnbyPbl8gA7nf54brt94rYZZBe2RwEGtUc,20828
|
|
27
27
|
flock/core/flock_router.py,sha256=A5GaxcGvtiFlRLHBTW7okh5RDm3BdKam2uXvRHRaj7k,2187
|
|
@@ -59,7 +59,7 @@ flock/core/mixin/dspy_integration.py,sha256=vlf6rJnR9EsfZi5KyFLEXIbUvhpBhodctn-m
|
|
|
59
59
|
flock/core/mixin/prompt_parser.py,sha256=eOqI-FK3y17gVqpc_y5GF-WmK1Jv8mFlkZxTcgweoxI,5121
|
|
60
60
|
flock/core/serialization/__init__.py,sha256=CML7fPgG6p4c0CDBlJ_uwV1aZZhJKK9uy3IoIHfO87w,431
|
|
61
61
|
flock/core/serialization/callable_registry.py,sha256=sUZECTZWsM3fJ8FDRQ-FgLNW9hF26nY17AD6fJKADMc,1419
|
|
62
|
-
flock/core/serialization/flock_serializer.py,sha256=
|
|
62
|
+
flock/core/serialization/flock_serializer.py,sha256=TEePKaJqU-_XWHTMWyMHloDNwmkKyOUSfXoJ7ZVki8k,33048
|
|
63
63
|
flock/core/serialization/json_encoder.py,sha256=gAKj2zU_8wQiNvdkby2hksSA4fbPNwTjup_yz1Le1Vw,1229
|
|
64
64
|
flock/core/serialization/secure_serializer.py,sha256=n5-zRvvXddgJv1FFHsaQ2wuYdL3WUSGPvG_LGaffEJo,6144
|
|
65
65
|
flock/core/serialization/serializable.py,sha256=qlv8TsTqRuklXiNuCMrvro5VKz764xC2i3FlgLJSkdk,12129
|
|
@@ -75,7 +75,7 @@ flock/core/util/file_path_utils.py,sha256=Odf7uU32C-x1KNighbNERSiMtkzW4h8laABIoF
|
|
|
75
75
|
flock/core/util/hydrator.py,sha256=6qNwOwCZB7r6y25BZ--0PGofrAlfMaXbDKFQeP5NLts,11196
|
|
76
76
|
flock/core/util/input_resolver.py,sha256=g9vDPdY4OH-G7qjas5ksGEHueokHGFPMoLOvC-ngeLo,5984
|
|
77
77
|
flock/core/util/loader.py,sha256=j3q2qem5bFMP2SmMuYjb-ISxsNGNZd1baQmpvAnRUUk,2244
|
|
78
|
-
flock/evaluators/declarative/declarative_evaluator.py,sha256=
|
|
78
|
+
flock/evaluators/declarative/declarative_evaluator.py,sha256=kGhxkFJx8T0JXsr27rdqmB4nwq28yMDCOwPRJ-C2DOA,4778
|
|
79
79
|
flock/evaluators/memory/azure_search_evaluator.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
80
|
flock/evaluators/memory/memory_evaluator.py,sha256=SmerXyNaqm8DTV0yw-WqWkn9DXIf6x-nPG1eyTV6NY8,3452
|
|
81
81
|
flock/evaluators/natural_language/natural_language_evaluator.py,sha256=6nVEeh8_uwv_h-d3FWlA0GbzDzRtdhvxCGKirHtyvOU,2012
|
|
@@ -439,8 +439,8 @@ flock/workflow/activities.py,sha256=eVZDnxGJl_quNO-UTV3YgvTV8LrRaHN3QDAA1ANKzac,
|
|
|
439
439
|
flock/workflow/agent_activities.py,sha256=NhBZscflEf2IMfSRa_pBM_TRP7uVEF_O0ROvWZ33eDc,963
|
|
440
440
|
flock/workflow/temporal_setup.py,sha256=VWBgmBgfTBjwM5ruS_dVpA5AVxx6EZ7oFPGw4j3m0l0,1091
|
|
441
441
|
flock/workflow/workflow.py,sha256=I9MryXW_bqYVTHx-nl2epbTqeRy27CAWHHA7ZZA0nAk,1696
|
|
442
|
-
flock_core-0.4.
|
|
443
|
-
flock_core-0.4.
|
|
444
|
-
flock_core-0.4.
|
|
445
|
-
flock_core-0.4.
|
|
446
|
-
flock_core-0.4.
|
|
442
|
+
flock_core-0.4.0b13.dist-info/METADATA,sha256=-oZxxLDqjStFoVTtT5Ss9sk-EFpgsyINBBBJYYq7i6I,21101
|
|
443
|
+
flock_core-0.4.0b13.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
444
|
+
flock_core-0.4.0b13.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
|
|
445
|
+
flock_core-0.4.0b13.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
|
|
446
|
+
flock_core-0.4.0b13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|