Skip to content

Commit 2b11d58

Browse files
committed
fix (tasks): fixed executor execution
1 parent 67914ad commit 2b11d58

1 file changed

Lines changed: 21 additions & 22 deletions

File tree

src/server/workers/executor/tasks.py

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ async def async_execute_task_plan(task_id: str, user_id: str, run_id: str):
224224

225225
user_profile = await db.user_profiles.find_one({"user_id": user_id})
226226
personal_info = user_profile.get("userData", {}).get("personalInfo", {}) if user_profile else {}
227-
preferences = user_profile.get("userData", {}).get("preferences", {}) if user_profile else {}
228227
user_name = personal_info.get("name", "User")
229228
user_location_raw = personal_info.get("location", "Not specified")
230229
if isinstance(user_location_raw, dict):
@@ -266,7 +265,6 @@ async def async_execute_task_plan(task_id: str, user_id: str, run_id: str):
266265

267266
plan_description = task.get("name", "Unnamed plan")
268267
original_context_str = json.dumps(original_context_data, indent=2, default=str) if original_context_data else "No original context provided."
269-
block_id_prompt = f"The block_id for this task is '{block_id}'. You MUST pass this ID to the 'update_progress' tool in the 'block_id' parameter." if block_id else "This task did not originate from a tasks block."
270268

271269
full_plan_prompt = (
272270
f"You are Sentient, a resourceful and autonomous executor agent. Your goal is to complete the user's request by intelligently following the provided plan.\n\n" # noqa
@@ -278,36 +276,34 @@ async def async_execute_task_plan(task_id: str, user_id: str, run_id: str):
278276
f"**The Plan to Execute:**\n" + "\n".join([f"- Step {i+1}: Use the '{step['tool']}' tool to '{step['description']}'" for i, step in enumerate(task.get("plan", []))]) + "\n\n" # noqa
279277
"**EXECUTION STRATEGY:**\n" # noqa
280278
"1. **Think Step-by-Step:** Before each action, you MUST explain your reasoning and what you are about to do. Your thought process MUST be wrapped in `<think>` tags.\n" # noqa
281-
"2. **Tool Calls:** When you call a tool, you MUST use the `<tool_code>` format. For example: `<tool_code name=\"gdrive_server-gdrive_search\">{{\"query\": \"Q3 Report\"}}</tool_code>`.\n" # noqa
282-
"3. **Execution Flow:** You MUST start by executing the first step of the plan. Do not summarize the plan or provide a final answer until you have executed all steps. Follow the plan sequentially.\n" # noqa
283-
"4. **Map Plan to Tools:** The plan provides a high-level tool name (e.g., 'gmail', 'gdrive'). You must map this to the specific functions available to you (e.g., `gmail_server-sendEmail`, `gdrive_server-gdrive_search`).\n" # noqa
284-
"5. **Be Resourceful & Fill Gaps:** The plan is a guideline. If a step is missing information (e.g., an email address for a manager, a document name), your first action for that step MUST be to use the `memory-search_memory` tool to find the missing information. Do not proceed with incomplete information.\n" # noqa
285-
"6. **Remember New Information:** If you discover a new, permanent fact about the user during your execution (e.g., you find their manager's email is 'boss@example.com'), you MUST use `memory-cud_memory` to save it.\n" # noqa
286-
"7. **Handle Failures:** If a tool fails, analyze the error, think about an alternative approach, and try again. Do not give up easily. Your thought process and the error will be logged automatically.\n" # noqa
287-
"8. **Provide a Final, Detailed Answer:** ONLY after all steps are successfully completed, you MUST provide a final, comprehensive answer to the user. This is not a tool call. Your final response MUST be wrapped in `<answer>` tags. For example: `<answer>I have successfully scheduled the meeting and sent an invitation to John Doe.</answer>`.\n" # noqa
288-
"9. **Contact Information:** To find contact details like phone numbers or emails, use the `gpeople` tool before attempting to send an email or make a call.\n" # noqa
279+
"2. **Execution Flow:** You MUST start by executing the first step of the plan. Do not summarize the plan or provide a final answer until you have executed all steps. Follow the plan sequentially. SEARCH FOR ANY RELEVANT CONTEXT THAT YOU NEED TO COMPLETE THE EXECUTION. \n" # noqa
280+
"3. **Map Plan to Tools:** The plan provides a high-level tool name (e.g., 'gmail', 'gdrive'). You must map this to the specific functions available to you (e.g., `gmail_server-sendEmail`, `gdrive_server-gdrive_search`).\n" # noqa
281+
"4. **Be Resourceful & Fill Gaps:** The plan is a guideline. If a step is missing information (e.g., an email address for a manager, a document name), your first action for that step MUST be to use the `memory-search_memory` tool to find the missing information. Do not proceed with incomplete information.\n" # noqa
282+
"5. **Remember New Information:** If you discover a new, permanent fact about the user during your execution (e.g., you find their manager's email is 'boss@example.com'), you MUST use `memory-cud_memory` to save it.\n" # noqa
283+
"6. **Handle Failures:** If a tool fails, analyze the error, think about an alternative approach, and try again. Do not give up easily. Your thought process and the error will be logged automatically.\n" # noqa
284+
"7. **Provide a Final, Detailed Answer:** ONLY after all steps are successfully completed, you MUST provide a final, comprehensive answer to the user. This is not a tool call. Your final response MUST be wrapped in `<answer>` tags. For example: `<answer>I have successfully scheduled the meeting and sent an invitation to John Doe.</answer>`.\n" # noqa
285+
"8. **Contact Information:** To find contact details like phone numbers or emails, use the `gpeople` tool before attempting to send an email or make a call.\n" # noqa
289286
"\nNow, begin your work. Think step-by-step and start executing the plan, beginning with Step 1."
290287
)
291288

292289
try:
293290
logger.info(f"Task {task_id}: Starting agent run.")
294291
initial_messages = [{'role': 'user', 'content': "Begin executing the plan. Follow your instructions meticulously."}]
295292

296-
# Step 1: Fully exhaust the generator to let the agent run to completion.
297-
# This prevents async UI updates from interfering with the agent's internal loop.
298-
agent_generator = run_main_agent(
293+
last_history_len = len(initial_messages)
294+
final_history = None
295+
296+
for current_history in run_main_agent(
299297
system_message=full_plan_prompt,
300298
function_list=tools_config,
301299
messages=initial_messages
302-
)
303-
all_history_steps = list(agent_generator)
300+
):
301+
final_history = current_history # Keep track of the latest state
304302

305-
if not all_history_steps:
306-
raise Exception("Agent run produced no history, indicating an immediate failure.")
303+
if not isinstance(current_history, list):
304+
continue
307305

308-
# Step 2: After completion, process all history steps to send UI updates.
309-
last_history_len = len(initial_messages)
310-
for current_history in all_history_steps:
306+
# Process new messages for UI updates
311307
new_messages = current_history[last_history_len:]
312308
for msg in new_messages:
313309
updates_to_push = []
@@ -336,11 +332,14 @@ async def async_execute_task_plan(task_id: str, user_id: str, run_id: str):
336332

337333
for update in updates_to_push:
338334
if update.get("type") != "thought":
335+
# Use asyncio.create_task to send updates without blocking the agent loop
339336
asyncio.create_task(add_progress_update(db, task_id, run_id, user_id, update, block_id))
337+
340338
last_history_len = len(current_history)
341339

342-
# Step 3: Check the final state for a valid answer.
343-
final_history = all_history_steps[-1]
340+
if not final_history:
341+
raise Exception("Agent run produced no history, indicating an immediate failure.")
342+
344343
final_assistant_message = next((msg for msg in reversed(final_history) if msg.get("role") == "assistant"), None)
345344

346345
has_final_answer = False

0 commit comments

Comments
 (0)