Skip to content

Commit e5edeea

Browse files
committed
merging fixes to triggered tasks
2 parents 52f839f + 8d840bc commit e5edeea

File tree

4 files changed

+34
-20
lines changed

4 files changed

+34
-20
lines changed

src/client/app/tasks/page.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ Description: ${event.description || "No description."}`
660660
// --- END NEW ---
661661

662662
return (
663-
<div className="flex-1 flex h-screen text-white overflow-hidden">
663+
<div className="flex-1 flex h-full text-white overflow-hidden">
664664
<Tooltip
665665
id="tasks-tooltip"
666666
place="right"
@@ -784,7 +784,7 @@ Description: ${event.description || "No description."}`
784784
initial={{ opacity: 0 }}
785785
animate={{ opacity: 1 }}
786786
exit={{ opacity: 0 }}
787-
className="fixed inset-0 bg-black/70 backdrop-blur-md z-[70] md:hidden"
787+
className="fixed inset-0 bg-black/70 z-[70] md:hidden"
788788
>
789789
<motion.div
790790
initial={{ y: "100%" }}
@@ -811,7 +811,7 @@ export default function TasksPage() {
811811
return (
812812
<Suspense
813813
fallback={
814-
<div className="flex-1 flex h-screen bg-black text-white overflow-hidden justify-center items-center">
814+
<div className="flex-1 flex h-full bg-black text-white overflow-hidden justify-center items-center">
815815
<IconLoader className="w-10 h-10 animate-spin text-[var(--color-accent-blue)]" />
816816
</div>
817817
}
@@ -820,3 +820,4 @@ export default function TasksPage() {
820820
</Suspense>
821821
)
822822
}
823+

src/server/main/integrations/routes.py

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -375,16 +375,21 @@ async def finalize_composio_connection(
375375
"gcalendar": "GOOGLECALENDAR_GOOGLE_CALENDAR_EVENT_SYNC_TRIGGER",
376376
"gmail": "GMAIL_NEW_GMAIL_MESSAGE"
377377
}
378-
trigger_config = {"calendarId": "primary"} if service_name == "gcalendar" else {}
378+
trigger_config = {}
379+
if service_name == "gcalendar":
380+
# Google Calendar trigger requires specifying which calendar to watch.
381+
trigger_config = {"calendarId": "primary"}
382+
elif service_name == "gmail":
383+
trigger_config = {"labelIds": "INBOX"}
379384
try:
380385
logger.info(f"Setting up Composio trigger for {service_name} for user {user_id}")
381386
trigger = await asyncio.to_thread(
382387
composio.triggers.create,
383388
slug=slug_map[service_name],
384-
user_id=user_id,
389+
connected_account_id=connected_account_id,
385390
trigger_config=trigger_config
386391
)
387-
trigger_id = trigger.id
392+
trigger_id = trigger.trigger_id
388393
logger.info(f"Successfully created Composio trigger {trigger_id} for {service_name} for user {user_id}")
389394
except Exception as e:
390395
logger.error(f"Failed to create Composio trigger for {service_name} for user {user_id}: {e}", exc_info=True)
@@ -415,27 +420,33 @@ async def composio_webhook(request: Request):
415420
"""
416421
try:
417422
payload = await request.json()
418-
user_id = payload.get("userId")
419-
trigger_slug = payload.get("triggerSlug")
420-
event_data = payload.get("payload")
423+
# Correctly parse the payload based on the provided sample structure
424+
event_data = payload.get("data")
425+
if not event_data:
426+
raise HTTPException(status_code=400, detail="Webhook payload missing 'data' object.")
421427

422-
if not all([user_id, trigger_slug, event_data]):
423-
raise HTTPException(status_code=400, detail="Missing required fields in webhook payload.")
428+
user_id = event_data.get("user_id")
429+
trigger_type = payload.get("type")
424430

431+
if not all([user_id, trigger_type, event_data]):
432+
raise HTTPException(status_code=400, detail="Missing required fields (user_id, type) in webhook payload.")
433+
434+
# Map from Composio's trigger type to our internal service_name and event_type
435+
# Using lowercase to match the sample payload
425436
service_name_map = {
426-
"GOOGLECALENDAR_GOOGLE_CALENDAR_EVENT_SYNC_TRIGGER": "gcalendar",
427-
"GMAIL_NEW_GMAIL_MESSAGE": "gmail"
437+
"googlecalendar_google_calendar_event_sync_trigger": "gcalendar",
438+
"gmail_new_gmail_message": "gmail"
428439
}
429440
event_type_map = {
430-
"GOOGLECALENDAR_GOOGLE_CALENDAR_EVENT_SYNC_TRIGGER": "new_event",
431-
"GMAIL_NEW_GMAIL_MESSAGE": "new_email"
441+
"googlecalendar_google_calendar_event_sync_trigger": "new_event",
442+
"gmail_new_gmail_message": "new_email"
432443
}
433444

434-
service_name = service_name_map.get(trigger_slug)
435-
event_type = event_type_map.get(trigger_slug)
445+
service_name = service_name_map.get(trigger_type)
446+
event_type = event_type_map.get(trigger_type)
436447

437448
if not service_name:
438-
logger.warning(f"Received webhook for unhandled trigger slug: {trigger_slug}")
449+
logger.warning(f"Received webhook for unhandled trigger type: {trigger_type}")
439450
return JSONResponse(content={"status": "ignored", "reason": "unhandled trigger"})
440451

441452
logger.info(f"Received Composio trigger for user '{user_id}' - Service: '{service_name}', Event: '{event_type}'")
@@ -456,7 +467,7 @@ async def composio_webhook(request: Request):
456467
logger.info(f"Event for user '{user_id}' was discarded by the pre-filter.")
457468
return JSONResponse(content={"status": "ignored", "reason": "pre-filter discard"})
458469

459-
# 3. Dispatch to Celery worker
470+
# 3. Dispatch to a Celery task that handles finding and running all matching triggered workflows.
460471
execute_triggered_task.delay(
461472
user_id=user_id,
462473
source=service_name,
@@ -468,4 +479,4 @@ async def composio_webhook(request: Request):
468479
except Exception as e:
469480
logger.error(f"Error processing Composio webhook: {e}", exc_info=True)
470481
# Return a 200 to Composio to prevent retries on our internal errors.
471-
return JSONResponse(content={"status": "error", "detail": str(e)}, status_code=200)
482+
return JSONResponse(content={"status": "error", "detail": str(e)}, status_code=200)

src/server/main/tasks/prompts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
- `source`: The service that triggers the workflow (e.g., "gmail", "gcalendar").
2828
- `event`: The specific event (e.g., "new_email", "new_event").
2929
- `filter`: A dictionary of conditions to match (e.g., `{{"from": "boss@example.com"}}`).
30+
The task will execute *after* the trigger occurs, using the event data (like the email content) as context.
3031
- CRUCIAL DISTINCTION: Differentiate between the *task's execution time* (`run_at`) and the *event's time* mentioned in the prompt. A task to arrange a future event (e.g., 'book a flight for next month', 'schedule a meeting for Friday') should be executed *now* to make the arrangement. Therefore, its `run_at` should be null, since setting run_at to null makes the task run immediately. The future date belongs in the task `description`.
3132
- Ambiguity: Phrases like "weekly hourly" are ambiguous. Interpret "weekly" as the frequency and ignore "hourly".
3233
- Use the current time and user's timezone to resolve relative dates like "tomorrow", "next Friday at 2pm", etc. correctly.

src/server/workers/planner/prompts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
6. Anticipate Information Gaps: If crucial information is still missing after checking context, the first step should be to use a tool to find it (e.g., `internet_search` for public information, `gpeople` for contacts, `memory` for personal information, `gcalendar` for upcoming events and so on).
1616
7. Output a Clear Plan: Your final output must be a single, valid JSON object containing a concise description of the overall goal and a list of specific, actionable steps for the executor.
1717
8. If the task is scheduled or recurring, only plan for an indivisual occurrence, not the entire series. The executor will handle scheduling. For example, if the user asks you to "Send a news summary every day at 8 AM", your plan should only include the steps for the indivisual run such as "Search for the news", "Summarize the news", "Send the news on WhatsApp". The executor will then handle the scheduling for future occurrences. Do NOT include any steps using the `gcalendar` tool to create a recurring or scheduled events.
18+
9. If the task is triggered by an event (like a new email or calendar event), your plan should focus on the immediate actions to take after that event has occured, such as "Search for the email", "Extract relevant information", "Send a summary to the user". The executor will handle the triggering mechanism. The executor is receiving the incoming email or calendar event as input, along with your plan so write each plan step as if the event has already occured and you are now processing it. For example, if the triggered task is to send a summary for each new email, your plan should be to directly read the email and summarize it, you do not need to search for the email as it is part of the input trigger.
1819
1920
Here is the complete list of services (tools) available to the executor agent, that you can use in your plan:
2021
{{

0 commit comments

Comments
 (0)