flock-core 0.4.527__py3-none-any.whl → 0.5.0b0__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.

Files changed (130) hide show
  1. flock/cli/execute_flock.py +1 -1
  2. flock/cli/manage_agents.py +6 -6
  3. flock/components/__init__.py +30 -0
  4. flock/components/evaluation/__init__.py +9 -0
  5. flock/components/evaluation/declarative_evaluation_component.py +222 -0
  6. flock/components/routing/__init__.py +15 -0
  7. flock/{routers/conditional/conditional_router.py → components/routing/conditional_routing_component.py} +61 -53
  8. flock/components/routing/default_routing_component.py +103 -0
  9. flock/components/routing/llm_routing_component.py +206 -0
  10. flock/components/utility/__init__.py +15 -0
  11. flock/{modules/enterprise_memory/enterprise_memory_module.py → components/utility/memory_utility_component.py} +195 -173
  12. flock/{modules/performance/metrics_module.py → components/utility/metrics_utility_component.py} +110 -95
  13. flock/{modules/output/output_module.py → components/utility/output_utility_component.py} +47 -45
  14. flock/core/__init__.py +26 -18
  15. flock/core/agent/__init__.py +16 -0
  16. flock/core/agent/flock_agent_components.py +104 -0
  17. flock/core/agent/flock_agent_execution.py +101 -0
  18. flock/core/agent/flock_agent_integration.py +206 -0
  19. flock/core/agent/flock_agent_lifecycle.py +177 -0
  20. flock/core/agent/flock_agent_serialization.py +381 -0
  21. flock/core/api/endpoints.py +2 -2
  22. flock/core/api/service.py +2 -2
  23. flock/core/component/__init__.py +15 -0
  24. flock/core/{flock_module.py → component/agent_component_base.py} +136 -34
  25. flock/core/component/evaluation_component.py +56 -0
  26. flock/core/component/routing_component.py +74 -0
  27. flock/core/component/utility_component.py +69 -0
  28. flock/core/config/flock_agent_config.py +49 -2
  29. flock/core/evaluation/utils.py +3 -2
  30. flock/core/execution/batch_executor.py +1 -1
  31. flock/core/execution/evaluation_executor.py +2 -2
  32. flock/core/execution/opik_executor.py +1 -1
  33. flock/core/flock.py +147 -493
  34. flock/core/flock_agent.py +195 -1032
  35. flock/core/flock_factory.py +114 -90
  36. flock/core/flock_scheduler.py +1 -1
  37. flock/core/flock_server_manager.py +8 -8
  38. flock/core/logging/logging.py +1 -0
  39. flock/core/mcp/flock_mcp_server.py +53 -48
  40. flock/core/mcp/{flock_mcp_tool_base.py → flock_mcp_tool.py} +2 -2
  41. flock/core/mcp/mcp_client.py +9 -9
  42. flock/core/mcp/mcp_client_manager.py +9 -9
  43. flock/core/mcp/mcp_config.py +24 -24
  44. flock/core/mixin/dspy_integration.py +5 -5
  45. flock/core/orchestration/__init__.py +18 -0
  46. flock/core/orchestration/flock_batch_processor.py +94 -0
  47. flock/core/orchestration/flock_evaluator.py +113 -0
  48. flock/core/orchestration/flock_execution.py +288 -0
  49. flock/core/orchestration/flock_initialization.py +125 -0
  50. flock/core/orchestration/flock_server_manager.py +67 -0
  51. flock/core/orchestration/flock_web_server.py +117 -0
  52. flock/core/registry/__init__.py +45 -0
  53. flock/core/registry/agent_registry.py +69 -0
  54. flock/core/registry/callable_registry.py +139 -0
  55. flock/core/registry/component_discovery.py +142 -0
  56. flock/core/registry/component_registry.py +64 -0
  57. flock/core/registry/config_mapping.py +64 -0
  58. flock/core/registry/decorators.py +137 -0
  59. flock/core/registry/registry_hub.py +205 -0
  60. flock/core/registry/server_registry.py +57 -0
  61. flock/core/registry/type_registry.py +86 -0
  62. flock/core/serialization/flock_serializer.py +36 -32
  63. flock/core/serialization/serialization_utils.py +28 -25
  64. flock/core/util/hydrator.py +1 -1
  65. flock/core/util/input_resolver.py +29 -2
  66. flock/mcp/servers/sse/flock_sse_server.py +10 -10
  67. flock/mcp/servers/stdio/flock_stdio_server.py +10 -10
  68. flock/mcp/servers/streamable_http/flock_streamable_http_server.py +10 -10
  69. flock/mcp/servers/websockets/flock_websocket_server.py +10 -10
  70. flock/platform/docker_tools.py +3 -3
  71. flock/webapp/app/chat.py +1 -1
  72. flock/webapp/app/main.py +9 -5
  73. flock/webapp/app/services/flock_service.py +1 -1
  74. flock/webapp/app/services/sharing_store.py +1 -0
  75. flock/workflow/activities.py +67 -92
  76. flock/workflow/agent_execution_activity.py +6 -6
  77. flock/workflow/flock_workflow.py +1 -1
  78. flock_core-0.5.0b0.dist-info/METADATA +272 -0
  79. {flock_core-0.4.527.dist-info → flock_core-0.5.0b0.dist-info}/RECORD +82 -95
  80. flock/core/flock_evaluator.py +0 -60
  81. flock/core/flock_registry.py +0 -702
  82. flock/core/flock_router.py +0 -83
  83. flock/evaluators/__init__.py +0 -1
  84. flock/evaluators/declarative/__init__.py +0 -1
  85. flock/evaluators/declarative/declarative_evaluator.py +0 -217
  86. flock/evaluators/memory/memory_evaluator.py +0 -90
  87. flock/evaluators/test/test_case_evaluator.py +0 -38
  88. flock/evaluators/zep/zep_evaluator.py +0 -59
  89. flock/modules/__init__.py +0 -1
  90. flock/modules/assertion/__init__.py +0 -1
  91. flock/modules/assertion/assertion_module.py +0 -286
  92. flock/modules/callback/__init__.py +0 -1
  93. flock/modules/callback/callback_module.py +0 -91
  94. flock/modules/enterprise_memory/README.md +0 -99
  95. flock/modules/mem0/__init__.py +0 -1
  96. flock/modules/mem0/mem0_module.py +0 -126
  97. flock/modules/mem0_async/__init__.py +0 -1
  98. flock/modules/mem0_async/async_mem0_module.py +0 -126
  99. flock/modules/memory/__init__.py +0 -1
  100. flock/modules/memory/memory_module.py +0 -429
  101. flock/modules/memory/memory_parser.py +0 -125
  102. flock/modules/memory/memory_storage.py +0 -736
  103. flock/modules/output/__init__.py +0 -1
  104. flock/modules/performance/__init__.py +0 -1
  105. flock/modules/zep/__init__.py +0 -1
  106. flock/modules/zep/zep_module.py +0 -192
  107. flock/routers/__init__.py +0 -1
  108. flock/routers/agent/__init__.py +0 -1
  109. flock/routers/agent/agent_router.py +0 -236
  110. flock/routers/agent/handoff_agent.py +0 -58
  111. flock/routers/default/__init__.py +0 -1
  112. flock/routers/default/default_router.py +0 -80
  113. flock/routers/feedback/feedback_router.py +0 -114
  114. flock/routers/list_generator/list_generator_router.py +0 -166
  115. flock/routers/llm/__init__.py +0 -1
  116. flock/routers/llm/llm_router.py +0 -365
  117. flock/tools/__init__.py +0 -0
  118. flock/tools/azure_tools.py +0 -781
  119. flock/tools/code_tools.py +0 -167
  120. flock/tools/file_tools.py +0 -149
  121. flock/tools/github_tools.py +0 -157
  122. flock/tools/markdown_tools.py +0 -205
  123. flock/tools/system_tools.py +0 -9
  124. flock/tools/text_tools.py +0 -810
  125. flock/tools/web_tools.py +0 -90
  126. flock/tools/zendesk_tools.py +0 -147
  127. flock_core-0.4.527.dist-info/METADATA +0 -674
  128. {flock_core-0.4.527.dist-info → flock_core-0.5.0b0.dist-info}/WHEEL +0 -0
  129. {flock_core-0.4.527.dist-info → flock_core-0.5.0b0.dist-info}/entry_points.txt +0 -0
  130. {flock_core-0.4.527.dist-info → flock_core-0.5.0b0.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,5 @@
1
+ import asyncio
1
2
  import subprocess
2
- import time
3
3
 
4
4
 
5
5
  def _check_docker_running():
@@ -16,7 +16,7 @@ def _check_docker_running():
16
16
  return False
17
17
 
18
18
 
19
- def _start_docker():
19
+ async def _start_docker():
20
20
  """Attempt to start Docker.
21
21
  This example first tries 'systemctl start docker' and then 'service docker start'.
22
22
  Adjust as needed for your environment.
@@ -37,7 +37,7 @@ def _start_docker():
37
37
  text=True,
38
38
  )
39
39
  # Give Docker a moment to start.
40
- time.sleep(3)
40
+ await asyncio.sleep(3)
41
41
  if _check_docker_running():
42
42
  print("Docker is now running.")
43
43
  return True
flock/webapp/app/chat.py CHANGED
@@ -473,7 +473,7 @@ async def chat_send_shared(
473
473
  if frozen_chat_cfg.history_key: run_input[frozen_chat_cfg.history_key] = [h["text"] for h in history if h.get("role") == "user" or h.get("role") == "bot"]
474
474
 
475
475
  try:
476
- result_dict = await flock_inst.run_async(start_agent=bot_agent, input=run_input, box_result=False)
476
+ result_dict = await flock_inst.run_async(agent=bot_agent, input=run_input, box_result=False)
477
477
  if frozen_chat_cfg.response_key:
478
478
  bot_text = str(result_dict.get(frozen_chat_cfg.response_key, result_dict))
479
479
  else:
flock/webapp/app/main.py CHANGED
@@ -124,6 +124,10 @@ def mask_sensitive_value_web(value: str) -> str:
124
124
  if len(value) <= 4: return "••••"
125
125
  return value[:2] + "•" * (len(value) - 4) + value[-2:]
126
126
 
127
+ def create_hx_trigger_header(triggers: dict[str, Any]) -> str:
128
+ """Helper function to create HX-Trigger header with JSON serialization."""
129
+ return json.dumps(triggers)
130
+
127
131
  def get_show_secrets_setting_web(env_vars: dict[str, str]) -> bool:
128
132
  return env_vars.get(SHOW_SECRETS_KEY, "false").lower() == "true"
129
133
 
@@ -843,12 +847,12 @@ async def ui_load_flock_by_name_action(request: Request, selected_flock_filename
843
847
  if loaded_flock:
844
848
  success_message_text = f"Flock '{loaded_flock.name}' loaded from '{selected_flock_filename}'."
845
849
  response_headers["HX-Push-Url"] = "/ui/editor/execute?ui_mode=" + ui_mode_query
846
- response_headers["HX-Trigger"] = json.dumps({"flockLoaded": None, "notify": {"type": "success", "message": success_message_text}})
850
+ response_headers["HX-Trigger"] = create_hx_trigger_header({"flockLoaded": None, "notify": {"type": "success", "message": success_message_text}})
847
851
  context = get_base_context_web(request, success=success_message_text, ui_mode=ui_mode_query)
848
852
  return templates.TemplateResponse("partials/_execution_view_container.html", context, headers=response_headers)
849
853
  else:
850
854
  error_message_text = f"Failed to load flock file '{selected_flock_filename}'."
851
- response_headers["HX-Trigger"] = json.dumps({"notify": {"type": "error", "message": error_message_text}})
855
+ response_headers["HX-Trigger"] = create_hx_trigger_header({"notify": {"type": "error", "message": error_message_text}})
852
856
  context = get_base_context_web(request, error=error_message_text, ui_mode=ui_mode_query)
853
857
  context["error_message_inline"] = error_message_text # For direct display in partial
854
858
  return templates.TemplateResponse("partials/_load_manager_view.html", context, headers=response_headers)
@@ -874,13 +878,13 @@ async def ui_load_flock_by_upload_action(request: Request, flock_file_upload: Up
874
878
  if loaded_flock:
875
879
  success_message_text = f"Flock '{loaded_flock.name}' loaded from '{filename_to_load}'."
876
880
  response_headers["HX-Push-Url"] = f"/ui/editor/execute?ui_mode={ui_mode_query}"
877
- response_headers["HX-Trigger"] = json.dumps({"flockLoaded": None, "flockFileListChanged": None, "notify": {"type": "success", "message": success_message_text}})
881
+ response_headers["HX-Trigger"] = create_hx_trigger_header({"flockLoaded": None, "flockFileListChanged": None, "notify": {"type": "success", "message": success_message_text}})
878
882
  context = get_base_context_web(request, success=success_message_text, ui_mode=ui_mode_query)
879
883
  return templates.TemplateResponse("partials/_execution_view_container.html", context, headers=response_headers)
880
884
  else: error_message_text = f"Failed to process uploaded '{filename_to_load}'."
881
885
 
882
886
  final_error_msg = error_message_text or "Upload failed."
883
- response_headers["HX-Trigger"] = json.dumps({"notify": {"type": "error", "message": final_error_msg}})
887
+ response_headers["HX-Trigger"] = create_hx_trigger_header({"notify": {"type": "error", "message": final_error_msg}})
884
888
  context = get_base_context_web(request, error=final_error_msg, ui_mode=ui_mode_query)
885
889
  return templates.TemplateResponse("partials/_create_flock_form.html", context, headers=response_headers)
886
890
 
@@ -893,7 +897,7 @@ async def ui_create_flock_action(request: Request, flock_name: str = Form(...),
893
897
 
894
898
  new_flock = create_new_flock_service(flock_name, default_model, description, request.app.state)
895
899
  success_msg_text = f"New flock '{new_flock.name}' created. Navigating to Execute page. Configure properties and agents as needed."
896
- response_headers = {"HX-Push-Url": f"/ui/editor/execute?ui_mode={ui_mode_query}", "HX-Trigger": json.dumps({"flockLoaded": None, "notify": {"type": "success", "message": success_msg_text}})}
900
+ response_headers = {"HX-Push-Url": f"/ui/editor/execute?ui_mode={ui_mode_query}", "HX-Trigger": create_hx_trigger_header({"flockLoaded": None, "notify": {"type": "success", "message": success_msg_text}})}
897
901
  context = get_base_context_web(request, success=success_msg_text, ui_mode=ui_mode_query)
898
902
  return templates.TemplateResponse("partials/_execution_view_container.html", context, headers=response_headers)
899
903
 
@@ -281,7 +281,7 @@ async def run_current_flock_service(
281
281
  logger.info(f"Executing agent '{start_agent_name}' from flock '{current_flock.name}' using app_state.")
282
282
  # Direct execution using the flock from app_state
283
283
  result = await current_flock.run_async(
284
- start_agent=start_agent_name, input=inputs, box_result=False
284
+ agent=start_agent_name, input=inputs, box_result=False
285
285
  )
286
286
  # Store run details using the run_store from app_state
287
287
  if hasattr(run_store, "add_run_details"): # Check if RunStore has this method
@@ -304,6 +304,7 @@ class SQLiteSharedLinkStore(SharedLinkStoreInterface):
304
304
  logger.error(f"SQLite error saving feedback {record.feedback_id}: {e}", exc_info=True)
305
305
  raise
306
306
 
307
+
307
308
  # ---------------------------------------------------------------------------
308
309
  # Azure Table + Blob implementation
309
310
  # ---------------------------------------------------------------------------
@@ -7,15 +7,28 @@ from temporalio import activity
7
7
 
8
8
  from flock.core.context.context import FlockContext
9
9
  from flock.core.context.context_vars import FLOCK_CURRENT_AGENT, FLOCK_MODEL
10
- from flock.core.flock_agent import FlockAgent
11
- from flock.core.flock_registry import get_registry
12
- from flock.core.flock_router import HandOffRequest
10
+
11
+ # HandOffRequest removed - using agent.next_agent directly
13
12
  from flock.core.logging.logging import get_logger
13
+ from flock.core.registry import get_registry
14
14
  from flock.core.util.input_resolver import resolve_inputs
15
15
 
16
16
  logger = get_logger("activities")
17
17
  tracer = trace.get_tracer(__name__)
18
18
 
19
+ def apply_handoff_strategy(previous_agent_output:str, next_agent_input:str, previous_agent_handoff_strategy:str, previous_agent_handoff_map:dict[str, str]) -> str:
20
+ if previous_agent_handoff_strategy == "append":
21
+ return next_agent_input + previous_agent_output
22
+ elif previous_agent_handoff_strategy == "override":
23
+ return previous_agent_output
24
+ elif previous_agent_handoff_strategy == "static":
25
+ return next_agent_input
26
+ elif previous_agent_handoff_strategy == "map":
27
+ for key, value in previous_agent_handoff_map.items():
28
+ next_agent_input = next_agent_input.replace(key, value)
29
+ return next_agent_input
30
+ raise NotImplementedError
31
+
19
32
 
20
33
  @activity.defn
21
34
  async def run_agent(context: FlockContext) -> dict:
@@ -29,6 +42,9 @@ async def run_agent(context: FlockContext) -> dict:
29
42
  registry = get_registry()
30
43
 
31
44
  previous_agent_name = ""
45
+ previous_agent_output = ""
46
+ previous_agent_handoff_strategy = ""
47
+ previous_agent_handoff_map = {}
32
48
  if isinstance(context, dict):
33
49
  context = FlockContext.from_dict(context)
34
50
  current_agent_name = context.get_variable(FLOCK_CURRENT_AGENT)
@@ -38,7 +54,7 @@ async def run_agent(context: FlockContext) -> dict:
38
54
  agent = registry.get_agent(current_agent_name)
39
55
  if agent.model is None or agent.evaluator.config.model is None:
40
56
  agent.set_model(context.get_variable(FLOCK_MODEL))
41
- agent.resolve_callables(context=context)
57
+
42
58
  if not agent:
43
59
  logger.error("Agent not found", agent=current_agent_name)
44
60
  span.record_exception(
@@ -53,8 +69,14 @@ async def run_agent(context: FlockContext) -> dict:
53
69
  iter_span.set_attribute("agent.name", agent.name)
54
70
  agent.context = context
55
71
  # Resolve inputs for the agent.
72
+ # Gets values from context, previous agent output, and handoff strategy.
56
73
  agent_inputs = resolve_inputs(
57
- agent.input, context, previous_agent_name
74
+ agent.input,
75
+ context,
76
+ previous_agent_name,
77
+ previous_agent_output,
78
+ previous_agent_handoff_strategy,
79
+ previous_agent_handoff_map
58
80
  )
59
81
  iter_span.add_event(
60
82
  "resolved inputs", attributes={"inputs": str(agent_inputs)}
@@ -69,6 +91,13 @@ async def run_agent(context: FlockContext) -> dict:
69
91
  logger.debug(
70
92
  "Agent execution completed", agent=agent.name
71
93
  )
94
+ context.record(
95
+ agent.name,
96
+ result,
97
+ timestamp=datetime.now().isoformat(),
98
+ hand_off=None,
99
+ called_from=previous_agent_name,
100
+ )
72
101
  except Exception as e:
73
102
  logger.error(
74
103
  "Agent execution failed",
@@ -78,81 +107,46 @@ async def run_agent(context: FlockContext) -> dict:
78
107
  exec_span.record_exception(e)
79
108
  raise
80
109
 
81
- # Determine the next agent using the handoff router if available
82
- handoff_data = HandOffRequest()
110
+ # Determine the next agent using routing component if available
111
+ next_agent_name = None
83
112
 
84
- if agent.handoff_router:
113
+ if agent.router:
85
114
  logger.info(
86
- f"Using handoff router: {agent.handoff_router.__class__.__name__}",
115
+ f"Using router: {agent.router.__class__.__name__}",
87
116
  agent=agent.name,
88
117
  )
89
118
  try:
90
- # Route to the next agent
91
- handoff_data = await agent.handoff_router.route(
119
+ # Route to the next agent using new routing component
120
+ next_agent_name = await agent.router.determine_next_step(
92
121
  agent, result, context
93
122
  )
94
123
 
95
- if callable(handoff_data):
96
- logger.debug(
97
- "Executing handoff function", agent=agent.name
98
- )
99
- try:
100
- handoff_data = handoff_data(context, result)
101
- if isinstance(
102
- handoff_data.next_agent, FlockAgent
103
- ):
104
- handoff_data.next_agent = (
105
- handoff_data.next_agent.name
106
- )
107
- except Exception as e:
108
- logger.error(
109
- "Handoff function error {} {}",
110
- agent=agent.name,
111
- error=str(e),
112
- )
113
- iter_span.record_exception(e)
114
- return {"error": f"Handoff function error: {e}"}
115
- elif isinstance(handoff_data.next_agent, FlockAgent):
116
- handoff_data.next_agent = (
117
- handoff_data.next_agent.name
118
- )
124
+ # Set next_agent on the agent instance
125
+ agent.next_agent = next_agent_name
119
126
 
120
- if not handoff_data.next_agent:
121
- logger.info(
122
- "Router found no suitable next agent",
123
- agent=agent.name,
124
- )
125
- context.record(
126
- agent.name,
127
- result,
128
- timestamp=datetime.now().isoformat(),
129
- hand_off=None,
130
- called_from=previous_agent_name,
131
- )
132
- logger.info("Completing chain", agent=agent.name)
133
- iter_span.add_event("chain completed")
134
- return result
135
127
  except Exception as e:
136
128
  logger.error(
137
- "Router error {} {}",
138
- agent.name,
139
- str(e),
129
+ f"Router error: {e}",
130
+ agent=agent.name,
131
+ error=str(e),
140
132
  )
141
133
  iter_span.record_exception(e)
142
134
  return {"error": f"Router error: {e}"}
143
135
  else:
144
- # No router, so no handoff
136
+ # Check if next_agent was set directly by user
137
+ next_agent_name = agent.next_agent
138
+ if callable(next_agent_name):
139
+ try:
140
+ next_agent_name = next_agent_name(context, result)
141
+ except Exception as e:
142
+ logger.error(f"next_agent callable error: {e}")
143
+ return {"error": f"next_agent callable error: {e}"}
144
+
145
+ if not next_agent_name:
145
146
  logger.info(
146
- "No handoff router defined, completing chain",
147
+ "No next agent found, completing chain",
147
148
  agent=agent.name,
148
149
  )
149
- context.record(
150
- agent.name,
151
- result,
152
- timestamp=datetime.now().isoformat(),
153
- hand_off=None,
154
- called_from=previous_agent_name,
155
- )
156
150
  iter_span.add_event("chain completed")
157
151
  return result
158
152
 
@@ -161,53 +155,34 @@ async def run_agent(context: FlockContext) -> dict:
161
155
  agent.name,
162
156
  result,
163
157
  timestamp=datetime.now().isoformat(),
164
- hand_off=handoff_data.model_dump(),
158
+ hand_off={"next_agent": next_agent_name} if next_agent_name else None,
165
159
  called_from=previous_agent_name,
166
160
  )
161
+ # Remember the current agent's details for the next iteration.
167
162
  previous_agent_name = agent.name
168
163
  previous_agent_output = agent.output
169
- if handoff_data.override_context:
170
- context.update(handoff_data.override_context)
164
+ previous_agent_handoff_strategy = agent.config.handoff_strategy
165
+ previous_agent_handoff_map = agent.config.handoff_map
171
166
 
172
- # Prepare the next agent.
167
+ # Activate the next agent.
173
168
  try:
174
- agent = registry.get_agent(handoff_data.next_agent)
175
- if handoff_data.output_to_input_merge_strategy == "add":
176
- agent.input = previous_agent_output + ", " + agent.input
177
-
178
- if handoff_data.add_input_fields:
179
- for field in handoff_data.add_input_fields:
180
- agent.input = field + ", " + agent.input
181
-
182
- if handoff_data.add_output_fields:
183
- for field in handoff_data.add_output_fields:
184
- agent.output = field + ", " + agent.output
185
-
186
- if handoff_data.add_description:
187
- if agent.description:
188
- agent.description = (
189
- agent.description
190
- + "\n"
191
- + handoff_data.add_description
192
- )
193
- else:
194
- agent.description = handoff_data.add_description
195
-
196
- agent.resolve_callables(context=context)
169
+ agent = registry.get_agent(next_agent_name)
197
170
  if not agent:
198
171
  logger.error(
199
172
  "Next agent not found",
200
- agent=handoff_data.next_agent,
173
+ agent=next_agent_name,
201
174
  )
202
175
  iter_span.record_exception(
203
176
  Exception(
204
- f"Next agent '{handoff_data.next_agent}' not found"
177
+ f"Next agent '{next_agent_name}' not found"
205
178
  )
206
179
  )
207
180
  return {
208
- "error": f"Next agent '{handoff_data.next_agent}' not found."
181
+ "error": f"Next agent '{next_agent_name}' not found."
209
182
  }
210
183
 
184
+
185
+
211
186
  context.set_variable(FLOCK_CURRENT_AGENT, agent.name)
212
187
 
213
188
  logger.info("Handing off to next agent", next=agent.name)
@@ -12,8 +12,8 @@ from temporalio import activity
12
12
  from flock.core.context.context import FlockContext
13
13
  from flock.core.context.context_vars import FLOCK_MODEL
14
14
  from flock.core.flock_agent import FlockAgent # Import concrete class if needed
15
- from flock.core.flock_registry import get_registry
16
- from flock.core.flock_router import HandOffRequest
15
+ from flock.core.registry import get_registry
16
+ # HandOffRequest removed - using agent.next_agent directly
17
17
  from flock.core.logging.logging import get_logger
18
18
  from flock.core.util.input_resolver import resolve_inputs
19
19
 
@@ -133,22 +133,22 @@ async def determine_next_agent(
133
133
  f"Agent '{current_agent_name}' not found for routing."
134
134
  )
135
135
 
136
- if not agent.handoff_router:
136
+ if not agent.router:
137
137
  logger.info(
138
- "No handoff router defined for agent", agent=current_agent_name
138
+ "No router defined for agent", agent=current_agent_name
139
139
  )
140
140
  span.add_event("no_router")
141
141
  return None # Indicate no handoff
142
142
 
143
143
  logger.debug(
144
- f"Using router {agent.handoff_router.__class__.__name__}",
144
+ f"Using router {agent.router.__class__.__name__}",
145
145
  agent=agent.name,
146
146
  )
147
147
  try:
148
148
  # Execute the routing logic
149
149
  handoff_data: (
150
150
  HandOffRequest | Callable
151
- ) = await agent.handoff_router.route(agent, result, context)
151
+ ) = await agent.router.route(agent, result, context)
152
152
 
153
153
  # Handle callable handoff functions - This is complex in distributed systems.
154
154
  # Consider if this pattern should be supported or if routing should always
@@ -7,7 +7,7 @@ from temporalio import workflow
7
7
  with workflow.unsafe.imports_passed_through():
8
8
  from flock.core.context.context import AgentDefinition, FlockContext
9
9
  from flock.core.context.context_vars import FLOCK_CURRENT_AGENT
10
- from flock.core.flock_router import HandOffRequest
10
+ # HandOffRequest removed - using agent.next_agent directly
11
11
  from flock.core.logging.logging import get_logger
12
12
  from flock.workflow.agent_execution_activity import (
13
13
  determine_next_agent,