flock-core 0.5.0b22__py3-none-any.whl → 0.5.0b23__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/components/evaluation/declarative_evaluation_component.py +61 -29
- {flock_core-0.5.0b22.dist-info → flock_core-0.5.0b23.dist-info}/METADATA +1 -1
- {flock_core-0.5.0b22.dist-info → flock_core-0.5.0b23.dist-info}/RECORD +6 -6
- {flock_core-0.5.0b22.dist-info → flock_core-0.5.0b23.dist-info}/WHEEL +0 -0
- {flock_core-0.5.0b22.dist-info → flock_core-0.5.0b23.dist-info}/entry_points.txt +0 -0
- {flock_core-0.5.0b22.dist-info → flock_core-0.5.0b23.dist-info}/licenses/LICENSE +0 -0
|
@@ -40,11 +40,13 @@ def _ensure_live_crop_above() -> None:
|
|
|
40
40
|
return
|
|
41
41
|
|
|
42
42
|
# Extend the accepted literal at runtime so type checks don't block the new option.
|
|
43
|
-
current_args = getattr(_lr.VerticalOverflowMethod,
|
|
44
|
-
if
|
|
45
|
-
_lr.VerticalOverflowMethod = _Literal[
|
|
43
|
+
current_args = getattr(_lr.VerticalOverflowMethod, "__args__", ())
|
|
44
|
+
if "crop_above" not in current_args:
|
|
45
|
+
_lr.VerticalOverflowMethod = _Literal[
|
|
46
|
+
"crop", "crop_above", "ellipsis", "visible"
|
|
47
|
+
] # type: ignore[assignment]
|
|
46
48
|
|
|
47
|
-
if getattr(_lr.LiveRender.__rich_console__,
|
|
49
|
+
if getattr(_lr.LiveRender.__rich_console__, "_flock_crop_above", False):
|
|
48
50
|
_live_patch_applied = True
|
|
49
51
|
return
|
|
50
52
|
|
|
@@ -55,26 +57,28 @@ def _ensure_live_crop_above() -> None:
|
|
|
55
57
|
def _patched_rich_console(self, console, options):
|
|
56
58
|
renderable = self.renderable
|
|
57
59
|
style = console.get_style(self.style)
|
|
58
|
-
lines = console.render_lines(
|
|
60
|
+
lines = console.render_lines(
|
|
61
|
+
renderable, options, style=style, pad=False
|
|
62
|
+
)
|
|
59
63
|
shape = Segment.get_shape(lines)
|
|
60
64
|
|
|
61
65
|
_, height = shape
|
|
62
66
|
max_height = options.size.height
|
|
63
67
|
if height > max_height:
|
|
64
|
-
if self.vertical_overflow ==
|
|
65
|
-
lines = lines[:
|
|
68
|
+
if self.vertical_overflow == "crop":
|
|
69
|
+
lines = lines[:max_height]
|
|
66
70
|
shape = Segment.get_shape(lines)
|
|
67
|
-
elif self.vertical_overflow ==
|
|
71
|
+
elif self.vertical_overflow == "crop_above":
|
|
68
72
|
lines = lines[-max_height:]
|
|
69
73
|
shape = Segment.get_shape(lines)
|
|
70
|
-
elif self.vertical_overflow ==
|
|
74
|
+
elif self.vertical_overflow == "ellipsis" and max_height > 0:
|
|
71
75
|
lines = lines[: (max_height - 1)]
|
|
72
76
|
overflow_text = Text(
|
|
73
|
-
|
|
74
|
-
overflow=
|
|
75
|
-
justify=
|
|
76
|
-
end=
|
|
77
|
-
style=
|
|
77
|
+
"...",
|
|
78
|
+
overflow="crop",
|
|
79
|
+
justify="center",
|
|
80
|
+
end="",
|
|
81
|
+
style="live.ellipsis",
|
|
78
82
|
)
|
|
79
83
|
lines.append(list(console.render(overflow_text)))
|
|
80
84
|
shape = Segment.get_shape(lines)
|
|
@@ -126,9 +130,13 @@ class DeclarativeEvaluationConfig(AgentComponentConfig):
|
|
|
126
130
|
description="Extraction LM for TwoStepAdapter when adapter='two_step'",
|
|
127
131
|
)
|
|
128
132
|
stream_callbacks: list[Callable[..., Any] | Any] | None = None
|
|
129
|
-
stream_vertical_overflow: Literal[
|
|
133
|
+
stream_vertical_overflow: Literal[
|
|
134
|
+
"crop", "ellipsis", "crop_above", "visible"
|
|
135
|
+
] = Field(
|
|
130
136
|
default="crop_above",
|
|
131
|
-
description=(
|
|
137
|
+
description=(
|
|
138
|
+
"Rich Live vertical overflow strategy; select how tall output is handled; 'crop_above' keeps the most recent rows visible."
|
|
139
|
+
),
|
|
132
140
|
)
|
|
133
141
|
kwargs: dict[str, Any] = Field(default_factory=dict)
|
|
134
142
|
|
|
@@ -138,7 +146,7 @@ class DeclarativeEvaluationComponent(
|
|
|
138
146
|
EvaluationComponent, DSPyIntegrationMixin, PromptParserMixin
|
|
139
147
|
):
|
|
140
148
|
"""Evaluation component that uses DSPy for generation.
|
|
141
|
-
|
|
149
|
+
|
|
142
150
|
This component provides the core intelligence for agents using DSPy's
|
|
143
151
|
declarative programming model. It handles LLM interactions, tool usage,
|
|
144
152
|
and prompt management through DSPy's framework.
|
|
@@ -156,7 +164,9 @@ class DeclarativeEvaluationComponent(
|
|
|
156
164
|
super().__init__(**data)
|
|
157
165
|
|
|
158
166
|
@override
|
|
159
|
-
def set_model(
|
|
167
|
+
def set_model(
|
|
168
|
+
self, model: str, temperature: float = 1.0, max_tokens: int = 32000
|
|
169
|
+
) -> None:
|
|
160
170
|
"""Set the model for the evaluation component."""
|
|
161
171
|
self.config.model = model
|
|
162
172
|
self.config.temperature = temperature
|
|
@@ -171,7 +181,9 @@ class DeclarativeEvaluationComponent(
|
|
|
171
181
|
mcp_tools: list[Any] | None = None,
|
|
172
182
|
) -> dict[str, Any]:
|
|
173
183
|
"""Core evaluation logic using DSPy - migrated from DeclarativeEvaluator."""
|
|
174
|
-
logger.debug(
|
|
184
|
+
logger.debug(
|
|
185
|
+
f"Starting declarative evaluation for component '{self.name}'"
|
|
186
|
+
)
|
|
175
187
|
|
|
176
188
|
# Prepare LM and optional adapter; keep settings changes scoped with dspy.context
|
|
177
189
|
lm = dspy.LM(
|
|
@@ -190,17 +202,22 @@ class DeclarativeEvaluationComponent(
|
|
|
190
202
|
elif self.config.adapter == "xml":
|
|
191
203
|
adapter = dspy.XMLAdapter()
|
|
192
204
|
elif self.config.adapter == "two_step":
|
|
193
|
-
extractor = dspy.LM(
|
|
205
|
+
extractor = dspy.LM(
|
|
206
|
+
self.config.extraction_model or "openai/gpt-4o-mini"
|
|
207
|
+
)
|
|
194
208
|
adapter = dspy.TwoStepAdapter(extraction_model=extractor)
|
|
195
209
|
else:
|
|
196
210
|
# chat is default; leave adapter=None
|
|
197
211
|
adapter = None
|
|
198
212
|
except Exception as e:
|
|
199
|
-
logger.warning(
|
|
213
|
+
logger.warning(
|
|
214
|
+
f"Failed to construct adapter '{self.config.adapter}': {e}. Proceeding without."
|
|
215
|
+
)
|
|
200
216
|
|
|
201
217
|
with dspy.context(lm=lm, adapter=adapter):
|
|
202
218
|
try:
|
|
203
219
|
from rich.console import Console
|
|
220
|
+
|
|
204
221
|
console = Console()
|
|
205
222
|
|
|
206
223
|
# Create DSPy signature from agent definition
|
|
@@ -238,17 +255,23 @@ class DeclarativeEvaluationComponent(
|
|
|
238
255
|
|
|
239
256
|
# Execute with streaming or non-streaming
|
|
240
257
|
if self.config.stream:
|
|
241
|
-
return await self._execute_streaming(
|
|
258
|
+
return await self._execute_streaming(
|
|
259
|
+
_dspy_signature, agent_task, inputs, agent, console
|
|
260
|
+
)
|
|
242
261
|
else:
|
|
243
262
|
return await self._execute_standard(agent_task, inputs, agent)
|
|
244
263
|
|
|
245
|
-
async def _execute_streaming(
|
|
264
|
+
async def _execute_streaming(
|
|
265
|
+
self, signature, agent_task, inputs: dict[str, Any], agent: Any, console
|
|
266
|
+
) -> dict[str, Any]:
|
|
246
267
|
"""Execute DSPy program in streaming mode with rich table updates."""
|
|
247
268
|
logger.info(f"Evaluating agent '{agent.name}' with async streaming.")
|
|
248
269
|
|
|
249
270
|
if not callable(agent_task):
|
|
250
271
|
logger.error("agent_task is not callable, cannot stream.")
|
|
251
|
-
raise TypeError(
|
|
272
|
+
raise TypeError(
|
|
273
|
+
"DSPy task could not be created or is not callable."
|
|
274
|
+
)
|
|
252
275
|
|
|
253
276
|
# Prepare stream listeners for any string output fields
|
|
254
277
|
listeners = []
|
|
@@ -306,7 +329,7 @@ class DeclarativeEvaluationComponent(
|
|
|
306
329
|
live_cm = Live(
|
|
307
330
|
initial_panel,
|
|
308
331
|
console=console,
|
|
309
|
-
refresh_per_second=
|
|
332
|
+
refresh_per_second=4,
|
|
310
333
|
transient=False,
|
|
311
334
|
vertical_overflow=overflow_mode,
|
|
312
335
|
)
|
|
@@ -314,6 +337,7 @@ class DeclarativeEvaluationComponent(
|
|
|
314
337
|
final_result: dict[str, Any] | None = None
|
|
315
338
|
|
|
316
339
|
with live_cm as live:
|
|
340
|
+
|
|
317
341
|
def _refresh_panel() -> None:
|
|
318
342
|
if formatter is None or live is None:
|
|
319
343
|
return
|
|
@@ -347,7 +371,9 @@ class DeclarativeEvaluationComponent(
|
|
|
347
371
|
except Exception as e:
|
|
348
372
|
logger.warning(f"Stream callback error: {e}")
|
|
349
373
|
token = getattr(value, "chunk", None)
|
|
350
|
-
signature_field = getattr(
|
|
374
|
+
signature_field = getattr(
|
|
375
|
+
value, "signature_field_name", None
|
|
376
|
+
)
|
|
351
377
|
if signature_field:
|
|
352
378
|
if signature_field not in display_data:
|
|
353
379
|
display_data[signature_field] = ""
|
|
@@ -385,7 +411,9 @@ class DeclarativeEvaluationComponent(
|
|
|
385
411
|
ordered_final[key] = final_result[key]
|
|
386
412
|
for field_name in signature_order:
|
|
387
413
|
if field_name in final_result:
|
|
388
|
-
ordered_final[field_name] = final_result[
|
|
414
|
+
ordered_final[field_name] = final_result[
|
|
415
|
+
field_name
|
|
416
|
+
]
|
|
389
417
|
for key, val in final_result.items():
|
|
390
418
|
if key not in ordered_final:
|
|
391
419
|
ordered_final[key] = val
|
|
@@ -410,14 +438,18 @@ class DeclarativeEvaluationComponent(
|
|
|
410
438
|
|
|
411
439
|
return filtered_result
|
|
412
440
|
|
|
413
|
-
async def _execute_standard(
|
|
441
|
+
async def _execute_standard(
|
|
442
|
+
self, agent_task, inputs: dict[str, Any], agent: Any
|
|
443
|
+
) -> dict[str, Any]:
|
|
414
444
|
"""Execute DSPy program in standard mode (from original implementation)."""
|
|
415
445
|
logger.info(f"Evaluating agent '{agent.name}' without streaming.")
|
|
416
446
|
|
|
417
447
|
try:
|
|
418
448
|
# Ensure the call is awaited if the underlying task is async
|
|
419
449
|
result_obj = await agent_task.acall(**inputs)
|
|
420
|
-
result_dict, cost, lm_history = self._process_result(
|
|
450
|
+
result_dict, cost, lm_history = self._process_result(
|
|
451
|
+
result_obj, inputs
|
|
452
|
+
)
|
|
421
453
|
self._cost = cost
|
|
422
454
|
self._lm_history = lm_history
|
|
423
455
|
result_dict = self.filter_reasoning(
|
|
@@ -27,7 +27,7 @@ flock/cli/yaml_editor.py,sha256=K3N0bh61G1TSDAZDnurqW9e_-hO6CtSQKXQqlDhCjVo,1252
|
|
|
27
27
|
flock/cli/assets/release_notes.md,sha256=bqnk50jxM3w5uY44Dc7MkdT8XmRREFxrVBAG9XCOSSU,4896
|
|
28
28
|
flock/components/__init__.py,sha256=qDcaP0O7_b5RlUEXluqwskpKCkhM73kSMeNXReze63M,963
|
|
29
29
|
flock/components/evaluation/__init__.py,sha256=_M3UlRFeNN90fEny6byt5VdLDE5o5khbd0EPT0o9S9k,303
|
|
30
|
-
flock/components/evaluation/declarative_evaluation_component.py,sha256=
|
|
30
|
+
flock/components/evaluation/declarative_evaluation_component.py,sha256=SiW6NddBsNNLte3sPiqkLe-sPCH1ACCyximhZoUsvpY,20706
|
|
31
31
|
flock/components/routing/__init__.py,sha256=BH_pFm9T6bUuf8HH4byDJ0dO0fzEVHv9m-ghUdDVdm0,542
|
|
32
32
|
flock/components/routing/conditional_routing_component.py,sha256=WqZLMz-0Dhfb97xvttNrJCIVe6FNMLEQ2m4KQTDpIbI,21374
|
|
33
33
|
flock/components/routing/default_routing_component.py,sha256=ZHt2Kjf-GHB5n7evU5NSGeQJ1Wuims5soeMswqaUb1E,3370
|
|
@@ -552,8 +552,8 @@ flock/workflow/agent_execution_activity.py,sha256=0exwmeWKYXXxdUqDf4YaUVpn0zl06S
|
|
|
552
552
|
flock/workflow/flock_workflow.py,sha256=sKFsRIL_bDGonXSNhK1zwu6UechghC_PihJJMidI-VI,9139
|
|
553
553
|
flock/workflow/temporal_config.py,sha256=3_8O7SDEjMsSMXsWJBfnb6XTp0TFaz39uyzSlMTSF_I,3988
|
|
554
554
|
flock/workflow/temporal_setup.py,sha256=KR6MlWOrpMtv8NyhaIPAsfl4tjobt81OBByQvg8Kw-Y,1948
|
|
555
|
-
flock_core-0.5.
|
|
556
|
-
flock_core-0.5.
|
|
557
|
-
flock_core-0.5.
|
|
558
|
-
flock_core-0.5.
|
|
559
|
-
flock_core-0.5.
|
|
555
|
+
flock_core-0.5.0b23.dist-info/METADATA,sha256=9lh5J5Bmb_61gf5EjRQKRWP7RwEEDOONsswFCMi8s04,9997
|
|
556
|
+
flock_core-0.5.0b23.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
557
|
+
flock_core-0.5.0b23.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
|
|
558
|
+
flock_core-0.5.0b23.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
|
|
559
|
+
flock_core-0.5.0b23.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|