From 0417e33ab26183d0fcd416c37ae0ccc995b51f2d Mon Sep 17 00:00:00 2001 From: Timothy Date: Wed, 1 Apr 2026 17:23:57 -0700 Subject: [PATCH] fix: batch modify gmail tool --- .../email_inbox_management/nodes/__init__.py | 22 ++++++++++--------- .../aden_tools/tools/gmail_tool/gmail_tool.py | 12 ++++++++-- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/examples/templates/email_inbox_management/nodes/__init__.py b/examples/templates/email_inbox_management/nodes/__init__.py index 7cebedd5..239f7254 100644 --- a/examples/templates/email_inbox_management/nodes/__init__.py +++ b/examples/templates/email_inbox_management/nodes/__init__.py @@ -159,8 +159,8 @@ You are an inbox management assistant. Apply the user's rules to their emails an **YOUR TOOLS:** - load_data(filename, limit, offset) — Read emails from a local file. - append_data(filename, data) — Append a line to a file. Record actions taken. -- gmail_batch_modify_messages(message_ids, add_labels, remove_labels) — Modify labels in batch. ALWAYS prefer this. -- gmail_modify_message(message_id, add_labels, remove_labels) — Modify a single message's labels. +- gmail_batch_modify_messages(message_ids, add_labels, remove_labels) — Modify labels in batch. ONLY call when BOTH add_labels AND remove_labels are non-empty lists. If only one type is needed, use gmail_modify_message instead. +- gmail_modify_message(message_id, add_labels, remove_labels) — Modify a single message's labels. Use when you have only add_labels OR only remove_labels (not both). - gmail_trash_message(message_id) — Move a message to trash. - gmail_create_draft(to, subject, body) — Create a draft reply. NEVER sends automatically. - gmail_create_label(name) — Create a new Gmail label. Returns the label ID. @@ -195,19 +195,21 @@ Each turn, process exactly ONE chunk: load → classify → act → record. Then **CRITICAL:** Only call load_data ONCE per turn. Do NOT pre-load multiple chunks. You must see the emails before you can act on them. **GMAIL LABEL REFERENCE:** -- MARK AS UNREAD — add_labels=["UNREAD"] -- MARK AS READ — remove_labels=["UNREAD"] -- MARK IMPORTANT — add_labels=["IMPORTANT"] -- REMOVE IMPORTANT — remove_labels=["IMPORTANT"] -- STAR — add_labels=["STARRED"] -- UNSTAR — remove_labels=["STARRED"] -- ARCHIVE — remove_labels=["INBOX"] -- MARK AS SPAM — add_labels=["SPAM"], remove_labels=["INBOX"] +- MARK AS UNREAD — add_labels=["UNREAD"] via gmail_modify_message (single action) +- MARK AS READ — remove_labels=["UNREAD"] via gmail_modify_message +- MARK IMPORTANT — add_labels=["IMPORTANT"] via gmail_modify_message +- REMOVE IMPORTANT — remove_labels=["IMPORTANT"] via gmail_modify_message +- STAR — add_labels=["STARRED"] via gmail_modify_message +- UNSTAR — remove_labels=["STARRED"] via gmail_modify_message +- ARCHIVE — remove_labels=["INBOX"] via gmail_modify_message (single email) OR gmail_batch_modify_messages (multiple emails ALL need archive) +- MARK AS SPAM — add_labels=["SPAM"], remove_labels=["INBOX"] — must use gmail_modify_message for single emails or gmail_batch_modify_messages for multiple - TRASH — use gmail_trash_message(message_id) per email - DRAFT REPLY — use gmail_create_draft(to=, subject="Re: ", body=). Creates a draft only, never sends. - CREATE CUSTOM LABEL — use gmail_create_label(name=) to create, then apply via gmail_modify_message with add_labels=[] - APPLY CUSTOM LABEL — add_labels=[] using the ID from gmail_create_label or gmail_list_labels +**KEY RULE:** When you have BOTH add_labels AND remove_labels (like marking as spam), use gmail_modify_message for single emails or gmail_batch_modify_messages for multiple. When you have ONLY add_labels OR ONLY remove_labels (like just archiving), you MUST use gmail_modify_message because gmail_batch_modify_messages will fail. + **QUEEN RULE INJECTION:** If a new rule appears in the conversation mid-processing (injected by the queen), apply it to the remaining unprocessed emails alongside the existing rules. diff --git a/tools/src/aden_tools/tools/gmail_tool/gmail_tool.py b/tools/src/aden_tools/tools/gmail_tool/gmail_tool.py index 479b3a98..6fd91199 100644 --- a/tools/src/aden_tools/tools/gmail_tool/gmail_tool.py +++ b/tools/src/aden_tools/tools/gmail_tool/gmail_tool.py @@ -330,7 +330,11 @@ def register_tools( return token if not add_labels and not remove_labels: - return {"error": "At least one of add_labels or remove_labels is required"} + return { + "error": "At least one of add_labels or remove_labels is required. " + f"Received add_labels={add_labels!r}, remove_labels={remove_labels!r}. " + "Pass label IDs like add_labels=[\"STARRED\"] or remove_labels=[\"INBOX\"]." + } body: dict[str, list[str]] = {} if add_labels: @@ -387,7 +391,11 @@ def register_tools( return token if not add_labels and not remove_labels: - return {"error": "At least one of add_labels or remove_labels is required"} + return { + "error": "At least one of add_labels or remove_labels is required. " + f"Received add_labels={add_labels!r}, remove_labels={remove_labels!r}. " + "Pass label IDs like add_labels=[\"STARRED\"] or remove_labels=[\"INBOX\"]." + } body: dict = {"ids": message_ids} if add_labels: