flock-core 0.5.0b2__py3-none-any.whl → 0.5.0b5__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/cli/execute_flock.py +1 -1
- flock/cli/manage_agents.py +3 -3
- flock/components/evaluation/declarative_evaluation_component.py +10 -10
- flock/components/routing/conditional_routing_component.py +7 -6
- flock/components/routing/default_routing_component.py +3 -3
- flock/components/routing/llm_routing_component.py +24 -26
- flock/components/utility/memory_utility_component.py +3 -3
- flock/components/utility/metrics_utility_component.py +11 -11
- flock/components/utility/output_utility_component.py +11 -9
- flock/core/__init__.py +24 -10
- flock/core/agent/flock_agent_components.py +16 -16
- flock/core/agent/flock_agent_integration.py +88 -29
- flock/core/agent/flock_agent_serialization.py +23 -20
- flock/core/api/endpoints.py +2 -2
- flock/core/api/service.py +2 -2
- flock/core/component/__init__.py +7 -7
- flock/core/component/{evaluation_component_base.py → evaluation_component.py} +2 -2
- flock/core/component/{routing_component_base.py → routing_component.py} +3 -4
- flock/core/component/{utility_component_base.py → utility_component.py} +3 -3
- flock/core/evaluation/utils.py +2 -1
- flock/core/execution/batch_executor.py +1 -1
- flock/core/execution/evaluation_executor.py +1 -1
- flock/core/execution/opik_executor.py +1 -1
- flock/core/flock.py +12 -12
- flock/core/flock_agent.py +68 -38
- flock/core/flock_factory.py +21 -18
- flock/core/flock_scheduler.py +1 -1
- flock/core/flock_server_manager.py +8 -8
- flock/core/mcp/flock_mcp_server.py +11 -11
- flock/core/mcp/{flock_mcp_tool_base.py → flock_mcp_tool.py} +2 -2
- flock/core/mcp/mcp_client.py +9 -9
- flock/core/mcp/mcp_client_manager.py +9 -9
- flock/core/mcp/mcp_config.py +24 -24
- flock/core/orchestration/flock_execution.py +13 -13
- flock/core/orchestration/flock_initialization.py +6 -6
- flock/core/orchestration/flock_server_manager.py +8 -6
- flock/core/registry/__init__.py +16 -10
- flock/core/registry/registry_hub.py +7 -4
- flock/core/registry/server_registry.py +6 -6
- flock/core/serialization/flock_serializer.py +3 -2
- flock/core/util/hydrator.py +1 -1
- flock/mcp/servers/sse/flock_sse_server.py +10 -10
- flock/mcp/servers/stdio/flock_stdio_server.py +10 -10
- flock/mcp/servers/streamable_http/flock_streamable_http_server.py +10 -10
- flock/mcp/servers/websockets/flock_websocket_server.py +10 -10
- flock/webapp/app/chat.py +1 -1
- flock/webapp/app/services/flock_service.py +1 -1
- flock/workflow/activities.py +10 -10
- {flock_core-0.5.0b2.dist-info → flock_core-0.5.0b5.dist-info}/METADATA +1 -1
- {flock_core-0.5.0b2.dist-info → flock_core-0.5.0b5.dist-info}/RECORD +53 -55
- flock/core/flock_registry.py.backup +0 -688
- flock/workflow/activities_unified.py +0 -230
- {flock_core-0.5.0b2.dist-info → flock_core-0.5.0b5.dist-info}/WHEEL +0 -0
- {flock_core-0.5.0b2.dist-info → flock_core-0.5.0b5.dist-info}/entry_points.txt +0 -0
- {flock_core-0.5.0b2.dist-info → flock_core-0.5.0b5.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
"""Unified Temporal activities for running a chain of agents with the new component architecture."""
|
|
2
|
-
|
|
3
|
-
from datetime import datetime
|
|
4
|
-
|
|
5
|
-
from opentelemetry import trace
|
|
6
|
-
from temporalio import activity
|
|
7
|
-
|
|
8
|
-
from flock.core.context.context import FlockContext
|
|
9
|
-
from flock.core.context.context_vars import FLOCK_CURRENT_AGENT, FLOCK_MODEL
|
|
10
|
-
from flock.core.flock_agent_unified import FlockAgentUnified
|
|
11
|
-
from flock.core.registry import get_registry
|
|
12
|
-
# HandOffRequest removed - using agent.next_agent directly
|
|
13
|
-
from flock.core.logging.logging import get_logger
|
|
14
|
-
from flock.core.util.input_resolver import resolve_inputs
|
|
15
|
-
|
|
16
|
-
logger = get_logger("activities.unified")
|
|
17
|
-
tracer = trace.get_tracer(__name__)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@activity.defn
|
|
21
|
-
async def run_agent_unified(context: FlockContext) -> dict:
|
|
22
|
-
"""Runs a chain of agents using the unified component architecture.
|
|
23
|
-
|
|
24
|
-
Key changes from original:
|
|
25
|
-
- Uses FlockAgentUnified with components list
|
|
26
|
-
- Routing decisions come from agent.next_handoff (set during evaluation)
|
|
27
|
-
- Simplified workflow - no separate routing step
|
|
28
|
-
|
|
29
|
-
The context contains state, history, and agent definitions.
|
|
30
|
-
After each agent run, its output is merged into the context.
|
|
31
|
-
"""
|
|
32
|
-
# Start a top-level span for the entire run_agent activity.
|
|
33
|
-
with tracer.start_as_current_span("run_agent_unified") as span:
|
|
34
|
-
registry = get_registry()
|
|
35
|
-
|
|
36
|
-
previous_agent_name = ""
|
|
37
|
-
if isinstance(context, dict):
|
|
38
|
-
context = FlockContext.from_dict(context)
|
|
39
|
-
current_agent_name = context.get_variable(FLOCK_CURRENT_AGENT)
|
|
40
|
-
span.set_attribute("initial.agent", current_agent_name)
|
|
41
|
-
logger.info("Starting unified agent chain", initial_agent=current_agent_name)
|
|
42
|
-
|
|
43
|
-
agent = registry.get_agent(current_agent_name)
|
|
44
|
-
if not agent:
|
|
45
|
-
logger.error("Agent not found", agent=current_agent_name)
|
|
46
|
-
span.record_exception(
|
|
47
|
-
Exception(f"Agent '{current_agent_name}' not found")
|
|
48
|
-
)
|
|
49
|
-
return {"error": f"Agent '{current_agent_name}' not found."}
|
|
50
|
-
|
|
51
|
-
# Set model if not configured
|
|
52
|
-
if agent.model is None:
|
|
53
|
-
model = context.get_variable(FLOCK_MODEL)
|
|
54
|
-
if hasattr(agent, 'evaluator') and agent.evaluator and hasattr(agent.evaluator, 'config'):
|
|
55
|
-
agent.evaluator.config.model = model
|
|
56
|
-
agent.model = model
|
|
57
|
-
|
|
58
|
-
agent.resolve_callables(context=context)
|
|
59
|
-
|
|
60
|
-
# Loop over agents in the chain.
|
|
61
|
-
while agent:
|
|
62
|
-
# Create a nested span for this iteration.
|
|
63
|
-
with tracer.start_as_current_span("agent_iteration_unified") as iter_span:
|
|
64
|
-
iter_span.set_attribute("agent.name", agent.name)
|
|
65
|
-
agent.context = context
|
|
66
|
-
|
|
67
|
-
# Resolve inputs for the agent.
|
|
68
|
-
agent_inputs = resolve_inputs(
|
|
69
|
-
agent.input, context, previous_agent_name
|
|
70
|
-
)
|
|
71
|
-
iter_span.add_event(
|
|
72
|
-
"resolved inputs", attributes={"inputs": str(agent_inputs)}
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
# Execute the agent with its own span.
|
|
76
|
-
# NOTE: In unified architecture, routing happens DURING execution
|
|
77
|
-
with tracer.start_as_current_span("execute_agent_unified") as exec_span:
|
|
78
|
-
logger.info("Executing unified agent", agent=agent.name)
|
|
79
|
-
try:
|
|
80
|
-
# This will set agent.next_handoff during evaluation
|
|
81
|
-
result = await agent.run_async(agent_inputs)
|
|
82
|
-
exec_span.set_attribute("result", str(result))
|
|
83
|
-
logger.debug(
|
|
84
|
-
"Unified agent execution completed", agent=agent.name
|
|
85
|
-
)
|
|
86
|
-
except Exception as e:
|
|
87
|
-
logger.error(
|
|
88
|
-
"Unified agent execution failed",
|
|
89
|
-
agent=agent.name,
|
|
90
|
-
error=str(e),
|
|
91
|
-
)
|
|
92
|
-
exec_span.record_exception(e)
|
|
93
|
-
raise
|
|
94
|
-
|
|
95
|
-
# Get routing decision from agent.next_handoff (set during evaluation)
|
|
96
|
-
handoff_data = agent.next_handoff
|
|
97
|
-
|
|
98
|
-
if handoff_data is None:
|
|
99
|
-
# No routing component or router decided to end workflow
|
|
100
|
-
logger.info(
|
|
101
|
-
"No handoff data found, completing chain",
|
|
102
|
-
agent=agent.name,
|
|
103
|
-
)
|
|
104
|
-
context.record(
|
|
105
|
-
agent.name,
|
|
106
|
-
result,
|
|
107
|
-
timestamp=datetime.now().isoformat(),
|
|
108
|
-
hand_off=None,
|
|
109
|
-
called_from=previous_agent_name,
|
|
110
|
-
)
|
|
111
|
-
iter_span.add_event("chain completed - no handoff")
|
|
112
|
-
return result
|
|
113
|
-
|
|
114
|
-
# Process the handoff data
|
|
115
|
-
logger.info(
|
|
116
|
-
f"Processing handoff to: {handoff_data.next_agent}",
|
|
117
|
-
agent=agent.name,
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
# Handle callable handoff functions (if still needed for backward compatibility)
|
|
121
|
-
if callable(handoff_data):
|
|
122
|
-
logger.debug("Executing handoff function", agent=agent.name)
|
|
123
|
-
try:
|
|
124
|
-
handoff_data = handoff_data(context, result)
|
|
125
|
-
if isinstance(handoff_data.next_agent, FlockAgentUnified):
|
|
126
|
-
handoff_data.next_agent = handoff_data.next_agent.name
|
|
127
|
-
except Exception as e:
|
|
128
|
-
logger.error(
|
|
129
|
-
"Handoff function error",
|
|
130
|
-
agent=agent.name,
|
|
131
|
-
error=str(e),
|
|
132
|
-
)
|
|
133
|
-
iter_span.record_exception(e)
|
|
134
|
-
return {"error": f"Handoff function error: {e}"}
|
|
135
|
-
elif isinstance(handoff_data.next_agent, FlockAgentUnified):
|
|
136
|
-
handoff_data.next_agent = handoff_data.next_agent.name
|
|
137
|
-
|
|
138
|
-
# Check if we should end the workflow
|
|
139
|
-
if not handoff_data.next_agent:
|
|
140
|
-
logger.info(
|
|
141
|
-
"Router found no suitable next agent",
|
|
142
|
-
agent=agent.name,
|
|
143
|
-
)
|
|
144
|
-
context.record(
|
|
145
|
-
agent.name,
|
|
146
|
-
result,
|
|
147
|
-
timestamp=datetime.now().isoformat(),
|
|
148
|
-
hand_off=None,
|
|
149
|
-
called_from=previous_agent_name,
|
|
150
|
-
)
|
|
151
|
-
logger.info("Completing chain", agent=agent.name)
|
|
152
|
-
iter_span.add_event("chain completed - no next agent")
|
|
153
|
-
return result
|
|
154
|
-
|
|
155
|
-
# Record the agent run in the context.
|
|
156
|
-
context.record(
|
|
157
|
-
agent.name,
|
|
158
|
-
result,
|
|
159
|
-
timestamp=datetime.now().isoformat(),
|
|
160
|
-
hand_off=handoff_data.model_dump(),
|
|
161
|
-
called_from=previous_agent_name,
|
|
162
|
-
)
|
|
163
|
-
previous_agent_name = agent.name
|
|
164
|
-
previous_agent_output = agent.output
|
|
165
|
-
|
|
166
|
-
if handoff_data.override_context:
|
|
167
|
-
context.update(handoff_data.override_context)
|
|
168
|
-
|
|
169
|
-
# Prepare the next agent.
|
|
170
|
-
try:
|
|
171
|
-
agent = registry.get_agent(handoff_data.next_agent)
|
|
172
|
-
if not agent:
|
|
173
|
-
logger.error(
|
|
174
|
-
"Next agent not found",
|
|
175
|
-
agent=handoff_data.next_agent,
|
|
176
|
-
)
|
|
177
|
-
iter_span.record_exception(
|
|
178
|
-
Exception(
|
|
179
|
-
f"Next agent '{handoff_data.next_agent}' not found"
|
|
180
|
-
)
|
|
181
|
-
)
|
|
182
|
-
return {
|
|
183
|
-
"error": f"Next agent '{handoff_data.next_agent}' not found."
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
# Apply handoff modifications to the next agent
|
|
187
|
-
if handoff_data.output_to_input_merge_strategy == "add":
|
|
188
|
-
agent.input = previous_agent_output + ", " + agent.input
|
|
189
|
-
|
|
190
|
-
if handoff_data.add_input_fields:
|
|
191
|
-
for field in handoff_data.add_input_fields:
|
|
192
|
-
agent.input = field + ", " + agent.input
|
|
193
|
-
|
|
194
|
-
if handoff_data.add_output_fields:
|
|
195
|
-
for field in handoff_data.add_output_fields:
|
|
196
|
-
agent.output = field + ", " + agent.output
|
|
197
|
-
|
|
198
|
-
if handoff_data.add_description:
|
|
199
|
-
if agent.description:
|
|
200
|
-
agent.description = (
|
|
201
|
-
agent.description
|
|
202
|
-
+ "\n"
|
|
203
|
-
+ handoff_data.add_description
|
|
204
|
-
)
|
|
205
|
-
else:
|
|
206
|
-
agent.description = handoff_data.add_description
|
|
207
|
-
|
|
208
|
-
agent.resolve_callables(context=context)
|
|
209
|
-
context.set_variable(FLOCK_CURRENT_AGENT, agent.name)
|
|
210
|
-
|
|
211
|
-
logger.info("Handing off to next agent", next=agent.name)
|
|
212
|
-
iter_span.set_attribute("next.agent", agent.name)
|
|
213
|
-
|
|
214
|
-
except Exception as e:
|
|
215
|
-
logger.error("Error during handoff", error=str(e))
|
|
216
|
-
iter_span.record_exception(e)
|
|
217
|
-
return {"error": f"Error during handoff: {e}"}
|
|
218
|
-
|
|
219
|
-
# If the loop exits unexpectedly, return the initial input.
|
|
220
|
-
return context.get_variable("init_input")
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
# Backward compatibility wrapper
|
|
224
|
-
@activity.defn
|
|
225
|
-
async def run_agent(context: FlockContext) -> dict:
|
|
226
|
-
"""Backward compatibility wrapper for run_agent_unified."""
|
|
227
|
-
logger.warning(
|
|
228
|
-
"Using backward compatibility wrapper. Consider migrating to run_agent_unified."
|
|
229
|
-
)
|
|
230
|
-
return await run_agent_unified(context)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|