flock-core 0.4.0b22__py3-none-any.whl → 0.4.0b24__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.py +24 -7
- flock/core/flock_agent.py +219 -75
- flock/core/flock_factory.py +8 -6
- flock/core/flock_registry.py +140 -60
- flock/core/flock_router.py +19 -6
- flock/core/serialization/serialization_utils.py +85 -19
- flock/core/util/input_resolver.py +5 -0
- flock/evaluators/declarative/declarative_evaluator.py +18 -10
- flock/evaluators/memory/memory_evaluator.py +2 -0
- flock/evaluators/test/test_case_evaluator.py +2 -0
- flock/evaluators/zep/zep_evaluator.py +2 -0
- flock/modules/assertion/assertion_module.py +286 -0
- flock/modules/callback/callback_module.py +2 -0
- flock/modules/memory/memory_module.py +2 -0
- flock/modules/output/output_module.py +2 -0
- flock/modules/performance/metrics_module.py +2 -0
- flock/modules/zep/zep_module.py +2 -0
- flock/routers/agent/agent_router.py +7 -5
- flock/routers/conditional/conditional_router.py +482 -0
- flock/routers/default/default_router.py +5 -1
- flock/routers/feedback/feedback_router.py +114 -0
- flock/routers/list_generator/list_generator_router.py +166 -0
- flock/routers/llm/llm_router.py +3 -1
- flock/workflow/activities.py +20 -1
- {flock_core-0.4.0b22.dist-info → flock_core-0.4.0b24.dist-info}/METADATA +2 -1
- {flock_core-0.4.0b22.dist-info → flock_core-0.4.0b24.dist-info}/RECORD +29 -28
- flock/evaluators/memory/azure_search_evaluator.py +0 -0
- flock/evaluators/natural_language/natural_language_evaluator.py +0 -66
- flock/modules/azure-search/azure_search_module.py +0 -0
- {flock_core-0.4.0b22.dist-info → flock_core-0.4.0b24.dist-info}/WHEEL +0 -0
- {flock_core-0.4.0b22.dist-info → flock_core-0.4.0b24.dist-info}/entry_points.txt +0 -0
- {flock_core-0.4.0b22.dist-info → flock_core-0.4.0b24.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# src/flock/routers/list_generator/iterative_list_router.py (New File)
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from flock.core.context.context import FlockContext
|
|
8
|
+
from flock.core.flock_agent import FlockAgent
|
|
9
|
+
from flock.core.flock_registry import flock_component
|
|
10
|
+
from flock.core.flock_router import (
|
|
11
|
+
FlockRouter,
|
|
12
|
+
FlockRouterConfig,
|
|
13
|
+
HandOffRequest,
|
|
14
|
+
)
|
|
15
|
+
from flock.core.logging.logging import get_logger
|
|
16
|
+
|
|
17
|
+
# Need signature utils
|
|
18
|
+
|
|
19
|
+
logger = get_logger("router.list_generator")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class IterativeListGeneratorRouterConfig(FlockRouterConfig):
|
|
23
|
+
target_list_field: str = Field(
|
|
24
|
+
...,
|
|
25
|
+
description="Name of the final list output field (e.g., 'chapters').",
|
|
26
|
+
)
|
|
27
|
+
item_output_field: str = Field(
|
|
28
|
+
...,
|
|
29
|
+
description="Name of the single item output field for each iteration (e.g., 'chapter').",
|
|
30
|
+
)
|
|
31
|
+
context_input_field: str = Field(
|
|
32
|
+
default="previous_items",
|
|
33
|
+
description="Input field name for passing back generated items (e.g., 'existing_chapters').",
|
|
34
|
+
)
|
|
35
|
+
max_iterations: int = Field(
|
|
36
|
+
default=10, description="Maximum number of items to generate."
|
|
37
|
+
)
|
|
38
|
+
# More advanced: termination_condition: Optional[Callable] = None
|
|
39
|
+
# Store iteration state in context under this prefix
|
|
40
|
+
context_state_prefix: str = Field(
|
|
41
|
+
default="flock.iterator_state_",
|
|
42
|
+
description="Prefix for context keys storing iteration state.",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Field to extract item type from target_list_field signature
|
|
46
|
+
# This might require parsing the original agent's output signature
|
|
47
|
+
# item_type_str: Optional[str] = None # e.g., 'dict[str, str]' or 'MyChapterType'
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@flock_component(config_class=IterativeListGeneratorRouterConfig)
|
|
51
|
+
class IterativeListGeneratorRouter(FlockRouter):
|
|
52
|
+
name: str = "iterative_list_generator"
|
|
53
|
+
config: IterativeListGeneratorRouterConfig = Field(
|
|
54
|
+
default_factory=IterativeListGeneratorRouterConfig
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Helper to get state keys
|
|
58
|
+
def _get_state_keys(self, agent_name: str) -> tuple[str, str]:
|
|
59
|
+
prefix = self.config.context_state_prefix
|
|
60
|
+
list_key = f"{prefix}{agent_name}_{self.config.target_list_field}"
|
|
61
|
+
count_key = f"{prefix}{agent_name}_iteration_count"
|
|
62
|
+
return list_key, count_key
|
|
63
|
+
|
|
64
|
+
async def route(
|
|
65
|
+
self,
|
|
66
|
+
current_agent: FlockAgent,
|
|
67
|
+
result: dict[str, Any],
|
|
68
|
+
context: FlockContext,
|
|
69
|
+
) -> HandOffRequest:
|
|
70
|
+
list_key, count_key = self._get_state_keys(current_agent.name)
|
|
71
|
+
|
|
72
|
+
# --- State Initialization (First Run) ---
|
|
73
|
+
if count_key not in context.state:
|
|
74
|
+
logger.debug(
|
|
75
|
+
f"Initializing iterative list generation for '{self.config.target_list_field}' in agent '{current_agent.name}'."
|
|
76
|
+
)
|
|
77
|
+
context.set_variable(count_key, 0)
|
|
78
|
+
context.set_variable(list_key, [])
|
|
79
|
+
# Modify agent signature for the *first* iteration (remove context_input_field, use item_output_field)
|
|
80
|
+
# This requires modifying the agent's internal state or creating a temporary one.
|
|
81
|
+
# Let's try modifying the context passed to the *next* run instead.
|
|
82
|
+
context.set_variable(
|
|
83
|
+
f"{current_agent.name}.next_run_output_field",
|
|
84
|
+
self.config.item_output_field,
|
|
85
|
+
)
|
|
86
|
+
context.set_variable(
|
|
87
|
+
f"{current_agent.name}.next_run_input_fields_to_exclude",
|
|
88
|
+
{self.config.context_input_field},
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# --- Process Result of Previous Iteration ---
|
|
92
|
+
iteration_count = context.get_variable(count_key, 0)
|
|
93
|
+
generated_items = context.get_variable(list_key, [])
|
|
94
|
+
|
|
95
|
+
# Get the single item generated in the *last* run
|
|
96
|
+
# The result dict should contain the 'item_output_field' if it wasn't the very first run
|
|
97
|
+
new_item = result.get(self.config.item_output_field)
|
|
98
|
+
|
|
99
|
+
if (
|
|
100
|
+
new_item is not None and iteration_count > 0
|
|
101
|
+
): # Add item from previous run (not the init run)
|
|
102
|
+
generated_items.append(new_item)
|
|
103
|
+
context.set_variable(list_key, generated_items) # Update context
|
|
104
|
+
logger.info(
|
|
105
|
+
f"Added item #{iteration_count} to list '{self.config.target_list_field}' for agent '{current_agent.name}'."
|
|
106
|
+
)
|
|
107
|
+
elif iteration_count > 0:
|
|
108
|
+
logger.warning(
|
|
109
|
+
f"Iteration {iteration_count} for agent '{current_agent.name}' did not produce expected output field '{self.config.item_output_field}'."
|
|
110
|
+
)
|
|
111
|
+
# Decide how to handle: stop, retry, continue? Let's continue for now.
|
|
112
|
+
|
|
113
|
+
# Increment iteration count *after* processing the result of the previous one
|
|
114
|
+
current_iteration = iteration_count + 1
|
|
115
|
+
context.set_variable(count_key, current_iteration)
|
|
116
|
+
|
|
117
|
+
# --- Termination Check ---
|
|
118
|
+
if current_iteration > self.config.max_iterations:
|
|
119
|
+
logger.info(
|
|
120
|
+
f"Max iterations ({self.config.max_iterations}) reached for '{self.config.target_list_field}' in agent '{current_agent.name}'. Finalizing."
|
|
121
|
+
)
|
|
122
|
+
# Clean up state
|
|
123
|
+
del context.state[count_key]
|
|
124
|
+
# Final result should be the list itself under the target_list_field key
|
|
125
|
+
final_result = {self.config.target_list_field: generated_items}
|
|
126
|
+
# Handoff with empty next_agent to stop, but potentially override the *result*
|
|
127
|
+
# This is tricky. Routers usually decide the *next agent*, not the *final output*.
|
|
128
|
+
# Maybe the router should just signal termination, and the Flock run loop handles assembling the final output?
|
|
129
|
+
# Let's assume the router signals termination by returning next_agent=""
|
|
130
|
+
# The final list is already in the context under list_key.
|
|
131
|
+
# A final "AssemblerAgent" could read this context variable.
|
|
132
|
+
# OR we modify the HandOffRequest:
|
|
133
|
+
return HandOffRequest(
|
|
134
|
+
next_agent="", final_output_override=final_result
|
|
135
|
+
) # Needs HandOffRequest modification
|
|
136
|
+
|
|
137
|
+
# --- Prepare for Next Iteration ---
|
|
138
|
+
logger.info(
|
|
139
|
+
f"Routing back to agent '{current_agent.name}' for item #{current_iteration} of '{self.config.target_list_field}'."
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# The agent needs the context (previously generated items) and the original inputs again.
|
|
143
|
+
# We will pass the generated items via the context_input_field.
|
|
144
|
+
# The original inputs (like story_outline) should still be in the context.
|
|
145
|
+
next_input_override = {
|
|
146
|
+
self.config.context_input_field: generated_items # Pass the list back
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
# Modify agent signature for the *next* iteration (add context_input_field, use item_output_field)
|
|
150
|
+
# This is the trickiest part - how to modify the agent's perceived signature for the next run?
|
|
151
|
+
# Option 1: Pass overrides via HandOffRequest (cleanest)
|
|
152
|
+
next_signature_input = f"{current_agent.input}, {self.config.context_input_field}: list | Previously generated items" # Needs smarter joining
|
|
153
|
+
next_signature_output = (
|
|
154
|
+
self.config.item_output_field
|
|
155
|
+
) # Only ask for one item
|
|
156
|
+
|
|
157
|
+
# This requires HandOffRequest and Flock execution loop to support signature overrides
|
|
158
|
+
return HandOffRequest(
|
|
159
|
+
next_agent=current_agent.name,
|
|
160
|
+
output_to_input_merge_strategy="add", # Add the context_input_field to existing context
|
|
161
|
+
input_override=next_input_override, # Provide the actual list data
|
|
162
|
+
# --- Hypothetical Overrides ---
|
|
163
|
+
next_run_input_signature_override=next_signature_input,
|
|
164
|
+
next_run_output_signature_override=next_signature_output,
|
|
165
|
+
# -----------------------------
|
|
166
|
+
)
|
flock/routers/llm/llm_router.py
CHANGED
|
@@ -7,6 +7,7 @@ import litellm
|
|
|
7
7
|
|
|
8
8
|
from flock.core.context.context import FlockContext
|
|
9
9
|
from flock.core.flock_agent import FlockAgent
|
|
10
|
+
from flock.core.flock_registry import flock_component
|
|
10
11
|
from flock.core.flock_router import (
|
|
11
12
|
FlockRouter,
|
|
12
13
|
FlockRouterConfig,
|
|
@@ -29,6 +30,7 @@ class LLMRouterConfig(FlockRouterConfig):
|
|
|
29
30
|
prompt: str = ""
|
|
30
31
|
|
|
31
32
|
|
|
33
|
+
@flock_component(config_class=LLMRouterConfig)
|
|
32
34
|
class LLMRouter(FlockRouter):
|
|
33
35
|
"""Router that uses an LLM to determine the next agent in a workflow.
|
|
34
36
|
|
|
@@ -140,7 +142,7 @@ class LLMRouter(FlockRouter):
|
|
|
140
142
|
)
|
|
141
143
|
return HandOffRequest(
|
|
142
144
|
next_agent=next_agent_name,
|
|
143
|
-
|
|
145
|
+
output_to_input_merge_strategy="add",
|
|
144
146
|
override_next_agent=None,
|
|
145
147
|
override_context=None,
|
|
146
148
|
)
|
flock/workflow/activities.py
CHANGED
|
@@ -171,8 +171,27 @@ async def run_agent(context: FlockContext) -> dict:
|
|
|
171
171
|
# Prepare the next agent.
|
|
172
172
|
try:
|
|
173
173
|
agent = registry.get_agent(handoff_data.next_agent)
|
|
174
|
-
if handoff_data.
|
|
174
|
+
if handoff_data.output_to_input_merge_strategy == "add":
|
|
175
175
|
agent.input = previous_agent_output + ", " + agent.input
|
|
176
|
+
|
|
177
|
+
if handoff_data.add_input_fields:
|
|
178
|
+
for field in handoff_data.add_input_fields:
|
|
179
|
+
agent.input = field + ", " + agent.input
|
|
180
|
+
|
|
181
|
+
if handoff_data.add_output_fields:
|
|
182
|
+
for field in handoff_data.add_output_fields:
|
|
183
|
+
agent.output = field + ", " + agent.output
|
|
184
|
+
|
|
185
|
+
if handoff_data.add_description:
|
|
186
|
+
if agent.description:
|
|
187
|
+
agent.description = (
|
|
188
|
+
agent.description
|
|
189
|
+
+ "\n"
|
|
190
|
+
+ handoff_data.add_description
|
|
191
|
+
)
|
|
192
|
+
else:
|
|
193
|
+
agent.description = handoff_data.add_description
|
|
194
|
+
|
|
176
195
|
agent.resolve_callables(context=context)
|
|
177
196
|
if not agent:
|
|
178
197
|
logger.error(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flock-core
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.0b24
|
|
4
4
|
Summary: Declarative LLM Orchestration at Scale
|
|
5
5
|
Author-email: Andre Ratzenberger <andre.ratzenberger@whiteduck.de>
|
|
6
6
|
License-File: LICENSE
|
|
@@ -17,6 +17,7 @@ Requires-Dist: dspy==2.6.16
|
|
|
17
17
|
Requires-Dist: duckduckgo-search>=7.3.2
|
|
18
18
|
Requires-Dist: fastapi>=0.115.8
|
|
19
19
|
Requires-Dist: httpx>=0.28.1
|
|
20
|
+
Requires-Dist: inspect-ai>=0.3.88
|
|
20
21
|
Requires-Dist: litellm==1.63.7
|
|
21
22
|
Requires-Dist: loguru>=0.7.3
|
|
22
23
|
Requires-Dist: matplotlib>=3.10.0
|
|
@@ -19,13 +19,13 @@ flock/cli/view_results.py,sha256=dOzK0O1FHSIDERnx48y-2Xke9BkOHS7pcOhs64AyIg0,781
|
|
|
19
19
|
flock/cli/yaml_editor.py,sha256=K3N0bh61G1TSDAZDnurqW9e_-hO6CtSQKXQqlDhCjVo,12527
|
|
20
20
|
flock/cli/assets/release_notes.md,sha256=bqnk50jxM3w5uY44Dc7MkdT8XmRREFxrVBAG9XCOSSU,4896
|
|
21
21
|
flock/core/__init__.py,sha256=p7lmQULRu9ejIAELfanZiyMhW0CougIPvyFHW2nqBFQ,847
|
|
22
|
-
flock/core/flock.py,sha256=
|
|
23
|
-
flock/core/flock_agent.py,sha256=
|
|
22
|
+
flock/core/flock.py,sha256=2hQSDLd7vidqtR4M40dGqyUm1elD9wsSEFPK4L2Te5E,25483
|
|
23
|
+
flock/core/flock_agent.py,sha256=k2HDMG8yd8It9eZglLA4RDhTHrqq48bE7YEzIayqjq8,39054
|
|
24
24
|
flock/core/flock_evaluator.py,sha256=dOXZeDOGZcAmJ9ahqq_2bdGUU1VOXY4skmwTVpAjiVw,1685
|
|
25
|
-
flock/core/flock_factory.py,sha256=
|
|
25
|
+
flock/core/flock_factory.py,sha256=uRqcpu1fFbsDKp5YhGk47c6NjC36vAowQ3wzaQqmkBo,2972
|
|
26
26
|
flock/core/flock_module.py,sha256=96aFVYAgwpKN53xGbivQDUpikOYGFCxK5mqhclOcxY0,3003
|
|
27
|
-
flock/core/flock_registry.py,sha256=
|
|
28
|
-
flock/core/flock_router.py,sha256=
|
|
27
|
+
flock/core/flock_registry.py,sha256=Qcu9juUFNyDAOEsqVxauwVlWdfgKZrSzc8yT8JMiK-c,24246
|
|
28
|
+
flock/core/flock_router.py,sha256=1OAXDsdaIIFApEfo6SRfFEDoTuGt3Si7n2MXiySEfis,2644
|
|
29
29
|
flock/core/api/__init__.py,sha256=OKlhzDWZJfA6ddBwxQUmATY0TSzESsH032u00iVGvdA,228
|
|
30
30
|
flock/core/api/endpoints.py,sha256=qQnJmtcYGkjdKtLllVpyJVjc-iZrvu5EEeVIryyt4tc,12987
|
|
31
31
|
flock/core/api/main.py,sha256=glu9ThsYNTt35Ogjx732SGYJ9-aFftpvzLMQEJ7VuvQ,19189
|
|
@@ -64,7 +64,7 @@ flock/core/serialization/flock_serializer.py,sha256=TEePKaJqU-_XWHTMWyMHloDNwmkK
|
|
|
64
64
|
flock/core/serialization/json_encoder.py,sha256=gAKj2zU_8wQiNvdkby2hksSA4fbPNwTjup_yz1Le1Vw,1229
|
|
65
65
|
flock/core/serialization/secure_serializer.py,sha256=n5-zRvvXddgJv1FFHsaQ2wuYdL3WUSGPvG_LGaffEJo,6144
|
|
66
66
|
flock/core/serialization/serializable.py,sha256=qlv8TsTqRuklXiNuCMrvro5VKz764xC2i3FlgLJSkdk,12129
|
|
67
|
-
flock/core/serialization/serialization_utils.py,sha256=
|
|
67
|
+
flock/core/serialization/serialization_utils.py,sha256=AHRf90trgnj2Q6aaGaq5eja5PRcuJANUsp2wafGUeig,15257
|
|
68
68
|
flock/core/tools/azure_tools.py,sha256=hwLnI2gsEq6QzUoWj5eCGDKTdXY1XUf6K-H5Uwva2MY,17093
|
|
69
69
|
flock/core/tools/basic_tools.py,sha256=Ye7nlI4RRkqWRy8nH9CKuItBmh_ZXxUpouGnCOfx0s0,9050
|
|
70
70
|
flock/core/tools/llm_tools.py,sha256=Bdt4Dpur5dGpxd2KFEQyxjfZazvW1HCDKY6ydMj6UgQ,21811
|
|
@@ -74,32 +74,33 @@ flock/core/tools/dev_tools/github.py,sha256=a2OTPXS7kWOVA4zrZHynQDcsmEi4Pac5MfSj
|
|
|
74
74
|
flock/core/util/cli_helper.py,sha256=EnK4X-FgaO71JsSXLdy0R-cxE3UctlFZtzldursw-Bw,49845
|
|
75
75
|
flock/core/util/file_path_utils.py,sha256=Odf7uU32C-x1KNighbNERSiMtkzW4h8laABIoFK7A5M,6246
|
|
76
76
|
flock/core/util/hydrator.py,sha256=QJvCA8F4nkSP5akp3yg0cT6oaajOr1n7sldW5dCs6Lo,10733
|
|
77
|
-
flock/core/util/input_resolver.py,sha256=
|
|
77
|
+
flock/core/util/input_resolver.py,sha256=ttFiz5L_uzSvxEhWOPL09WfLF--RlLOikLP5hrgE7Mo,6138
|
|
78
78
|
flock/core/util/loader.py,sha256=j3q2qem5bFMP2SmMuYjb-ISxsNGNZd1baQmpvAnRUUk,2244
|
|
79
|
-
flock/evaluators/declarative/declarative_evaluator.py,sha256=
|
|
80
|
-
flock/evaluators/memory/
|
|
81
|
-
flock/evaluators/
|
|
82
|
-
flock/evaluators/
|
|
83
|
-
flock/
|
|
84
|
-
flock/
|
|
85
|
-
flock/modules/
|
|
86
|
-
flock/modules/callback/callback_module.py,sha256=volGGgHtY19qj1wHR6m5a_hmXSbV3Ca3uY6I76YmcfU,2833
|
|
87
|
-
flock/modules/memory/memory_module.py,sha256=bSkdFBW-Pp5ldHhXi8v4kfRM7zknfLR2fsOtbTosucI,14916
|
|
79
|
+
flock/evaluators/declarative/declarative_evaluator.py,sha256=mzg6Ch1JFGZb09goLC3dXxpuojIMR3AcFuoQaIUjEAk,6219
|
|
80
|
+
flock/evaluators/memory/memory_evaluator.py,sha256=ySwz7kcc8suXMJ7gKNSWThW8iOMlE8lUcUzEAHvv8rw,3559
|
|
81
|
+
flock/evaluators/test/test_case_evaluator.py,sha256=3Emcoty0LOLLBIuPGxSpKphuZC9Fu1DTr1vbGg-hd0Q,1233
|
|
82
|
+
flock/evaluators/zep/zep_evaluator.py,sha256=6_5vTdU0yJAH8I8w3-MPXiAZx6iUPhAVCsHjrHzkPLM,2058
|
|
83
|
+
flock/modules/assertion/assertion_module.py,sha256=vzv38E8mvVBQXON_YJ8GFF4kB-sWNychQrMVFmugEjU,12860
|
|
84
|
+
flock/modules/callback/callback_module.py,sha256=q2z-KX7QHlbfDncEP9c_W_DxhYyD6fe9MQfISO9OgrU,2939
|
|
85
|
+
flock/modules/memory/memory_module.py,sha256=MBsUCpnMWY184PlZUKw91b8Yf0jCg9ixsxiqx2tK8LM,15020
|
|
88
86
|
flock/modules/memory/memory_parser.py,sha256=FLH7GL8XThvHiCMfX3eQH7Sz-f62fzhAUmO6_gaDI7U,4372
|
|
89
87
|
flock/modules/memory/memory_storage.py,sha256=CNcLDMmvv0x7Z3YMKr6VveS_VCa7rKPw8l2d-XgqokA,27246
|
|
90
|
-
flock/modules/output/output_module.py,sha256=
|
|
91
|
-
flock/modules/performance/metrics_module.py,sha256=
|
|
92
|
-
flock/modules/zep/zep_module.py,sha256=
|
|
88
|
+
flock/modules/output/output_module.py,sha256=V2g7UF538dwCe4J2QsemADMOnorGfK5Z995Q2ZIV7K4,7385
|
|
89
|
+
flock/modules/performance/metrics_module.py,sha256=D7MHnkHcGe7BfKFV85LqGujZcXM7Mh95BkSmO7UbJEk,16895
|
|
90
|
+
flock/modules/zep/zep_module.py,sha256=uWhSXma4EIMt70L1_588FLnoLNmU8l7Vhhy1viRK1dk,6115
|
|
93
91
|
flock/platform/docker_tools.py,sha256=fpA7-6rJBjPOUBLdQP4ny2QPgJ_042nmqRn5GtKnoYw,1445
|
|
94
92
|
flock/platform/jaeger_install.py,sha256=MyOMJQx4TQSMYvdUJxfiGSo3YCtsfkbNXcAcQ9bjETA,2898
|
|
95
93
|
flock/routers/__init__.py,sha256=w9uL34Auuo26-q_EGlE8Z9iHsw6S8qutTAH_ZI7pn7M,39
|
|
96
94
|
flock/routers/agent/__init__.py,sha256=0ZOYpR8BMnR5iCGfcUiv99g7aT_g13xvm2Shl-XzybY,65
|
|
97
|
-
flock/routers/agent/agent_router.py,sha256=
|
|
95
|
+
flock/routers/agent/agent_router.py,sha256=d4rberqXguJFmDB_hLTaeaDP_rOvCnVQufPELA-pD6M,8327
|
|
98
96
|
flock/routers/agent/handoff_agent.py,sha256=p-0XEPXIyv1T3DGAhhXg2SYXmrwEaJ5pnuLgRSvbiZg,1903
|
|
97
|
+
flock/routers/conditional/conditional_router.py,sha256=_ETx3GhuS3uYqNz6AYWO0JIPov02l1WqxI7Xq-qyMTY,21261
|
|
99
98
|
flock/routers/default/__init__.py,sha256=DOatGX_aE2DWvf55a0Tv7qDK05QFD-hL3sm7g58hmLU,61
|
|
100
|
-
flock/routers/default/default_router.py,sha256=
|
|
99
|
+
flock/routers/default/default_router.py,sha256=RgJm6RcS8ah1S49mM9TccfJpenQ0SzzbPCX0K8ZtnHs,2384
|
|
100
|
+
flock/routers/feedback/feedback_router.py,sha256=RODEmPrrNZ-ODdZ0mGfmO8auEnH6KvHN3f5rmFGeq1M,4947
|
|
101
|
+
flock/routers/list_generator/list_generator_router.py,sha256=mofBBZFSfqek_uiYbiC-6avdfhTF8Q8tyEVka1xxALs,7741
|
|
101
102
|
flock/routers/llm/__init__.py,sha256=OV89ebq8RPWZwCJTS2_P46Q0yKD_03rwq_fBOsETd08,63
|
|
102
|
-
flock/routers/llm/llm_router.py,sha256=
|
|
103
|
+
flock/routers/llm/llm_router.py,sha256=F2GAKaiJxWCdtvI1G9vLkoLaY6kR_DgJYoRLenVN9FI,12335
|
|
103
104
|
flock/themes/3024-day.toml,sha256=uOVHqEzSyHx0WlUk3D0lne4RBsNBAPCTy3C58yU7kEY,667
|
|
104
105
|
flock/themes/3024-night.toml,sha256=qsXUwd6ZYz6J-R129_Ao2TKlvvK60svhZJJjB5c8Tfo,1667
|
|
105
106
|
flock/themes/aardvark-blue.toml,sha256=5ZgsxP3pWLPN3yJ2Wd9ErCo7fy_VJpIfje4kriDKlqo,1667
|
|
@@ -437,12 +438,12 @@ flock/themes/zenburned.toml,sha256=UEmquBbcAO3Zj652XKUwCsNoC2iQSlIh-q5c6DH-7Kc,1
|
|
|
437
438
|
flock/themes/zenwritten-dark.toml,sha256=To5l6520_3UqAGiEumpzGWsHhXxqu9ThrMildXKgIO0,1669
|
|
438
439
|
flock/themes/zenwritten-light.toml,sha256=G1iEheCPfBNsMTGaVpEVpDzYBHA_T-MV27rolUYolmE,1666
|
|
439
440
|
flock/workflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
440
|
-
flock/workflow/activities.py,sha256=
|
|
441
|
+
flock/workflow/activities.py,sha256=Rcgcepa-RzaEjKo2aNuI14O_sX8ij0RrqeyPa0oSw8M,9910
|
|
441
442
|
flock/workflow/agent_activities.py,sha256=NhBZscflEf2IMfSRa_pBM_TRP7uVEF_O0ROvWZ33eDc,963
|
|
442
443
|
flock/workflow/temporal_setup.py,sha256=VWBgmBgfTBjwM5ruS_dVpA5AVxx6EZ7oFPGw4j3m0l0,1091
|
|
443
444
|
flock/workflow/workflow.py,sha256=I9MryXW_bqYVTHx-nl2epbTqeRy27CAWHHA7ZZA0nAk,1696
|
|
444
|
-
flock_core-0.4.
|
|
445
|
-
flock_core-0.4.
|
|
446
|
-
flock_core-0.4.
|
|
447
|
-
flock_core-0.4.
|
|
448
|
-
flock_core-0.4.
|
|
445
|
+
flock_core-0.4.0b24.dist-info/METADATA,sha256=wANTOASj9rlk_xDBvSj2gY02R1lrqw0PIVWHSX5ulok,13004
|
|
446
|
+
flock_core-0.4.0b24.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
447
|
+
flock_core-0.4.0b24.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
|
|
448
|
+
flock_core-0.4.0b24.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
|
|
449
|
+
flock_core-0.4.0b24.dist-info/RECORD,,
|
|
File without changes
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
|
|
3
|
-
from flock.core.flock_evaluator import FlockEvaluator
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class NaturalLanguageEvaluator(FlockEvaluator):
|
|
7
|
-
"""Evaluator that uses natural language prompting."""
|
|
8
|
-
|
|
9
|
-
name: str = "natural_language"
|
|
10
|
-
prompt_template: str = ""
|
|
11
|
-
client: Any = None # OpenAI client
|
|
12
|
-
|
|
13
|
-
async def setup(self, input_schema: str, output_schema: str) -> None:
|
|
14
|
-
"""Set up prompt template and client."""
|
|
15
|
-
from openai import AsyncOpenAI
|
|
16
|
-
|
|
17
|
-
# Create prompt template
|
|
18
|
-
self.prompt_template = f"""
|
|
19
|
-
You are an AI assistant that processes inputs and generates outputs.
|
|
20
|
-
|
|
21
|
-
Input Format:
|
|
22
|
-
{input_schema}
|
|
23
|
-
|
|
24
|
-
Required Output Format:
|
|
25
|
-
{output_schema}
|
|
26
|
-
|
|
27
|
-
Please process the following input and provide output in the required format:
|
|
28
|
-
{{input}}
|
|
29
|
-
"""
|
|
30
|
-
|
|
31
|
-
# Set up client
|
|
32
|
-
self.client = AsyncOpenAI()
|
|
33
|
-
|
|
34
|
-
async def evaluate(self, inputs: dict[str, Any]) -> dict[str, Any]:
|
|
35
|
-
"""Evaluate using natural language."""
|
|
36
|
-
if not self.client:
|
|
37
|
-
raise RuntimeError("Evaluator not set up")
|
|
38
|
-
|
|
39
|
-
# Format input for prompt
|
|
40
|
-
input_str = "\n".join(f"{k}: {v}" for k, v in inputs.items())
|
|
41
|
-
|
|
42
|
-
# Get completion
|
|
43
|
-
response = await self.client.chat.completions.create(
|
|
44
|
-
model=self.config.model,
|
|
45
|
-
messages=[
|
|
46
|
-
{
|
|
47
|
-
"role": "user",
|
|
48
|
-
"content": self.prompt_template.format(input=input_str),
|
|
49
|
-
}
|
|
50
|
-
],
|
|
51
|
-
temperature=self.config.temperature,
|
|
52
|
-
max_tokens=self.config.max_tokens,
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
# Parse response into dictionary
|
|
56
|
-
try:
|
|
57
|
-
import json
|
|
58
|
-
|
|
59
|
-
return json.loads(response.choices[0].message.content)
|
|
60
|
-
except json.JSONDecodeError:
|
|
61
|
-
return {"result": response.choices[0].message.content}
|
|
62
|
-
|
|
63
|
-
async def cleanup(self) -> None:
|
|
64
|
-
"""Close client."""
|
|
65
|
-
if self.client:
|
|
66
|
-
await self.client.close()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|