feat(backend): improve gmail blocks (#10475)

<!-- Clearly explain the need for these changes: -->
I'm working with these blocks and found some much needed improvements

### Changes 🏗️
- Outputs labels from emails
- Types the outputs
- reorder the yielding of the smart decision blokc
<!-- Concisely describe all of the changes made in this pull request:
-->

### Checklist 📋

#### For code changes:
- [x] I have clearly listed my changes in the PR description
- [x] I have made a test plan
- [x] I have tested my changes according to the test plan:
  <!-- Put your test plan here: -->
- [x] Build a test agent with labels, sending, reading emails + smart
decision maker
This commit is contained in:
Nicholas Tindle
2025-07-28 23:04:34 -05:00
committed by GitHub
parent 4d05a27388
commit 95650ee346
2 changed files with 30 additions and 12 deletions

View File

@@ -32,6 +32,7 @@ class Attachment(BaseModel):
class Email(BaseModel):
threadId: str
labelIds: list[str]
id: str
subject: str
snippet: str
@@ -49,6 +50,16 @@ class Thread(BaseModel):
historyId: str
class GmailSendResult(BaseModel):
id: str
status: str
class GmailLabelResult(BaseModel):
label_id: str
status: str
class GmailReadBlock(Block):
class Input(BlockSchema):
credentials: GoogleCredentialsInput = GoogleCredentialsField(
@@ -93,6 +104,7 @@ class GmailReadBlock(Block):
"email",
{
"threadId": "t1",
"labelIds": ["INBOX"],
"id": "1",
"subject": "Test Email",
"snippet": "This is a test email",
@@ -109,6 +121,7 @@ class GmailReadBlock(Block):
[
{
"threadId": "t1",
"labelIds": ["INBOX"],
"id": "1",
"subject": "Test Email",
"snippet": "This is a test email",
@@ -126,6 +139,7 @@ class GmailReadBlock(Block):
"_read_emails": lambda *args, **kwargs: [
{
"threadId": "t1",
"labelIds": ["INBOX"],
"id": "1",
"subject": "Test Email",
"snippet": "This is a test email",
@@ -214,6 +228,7 @@ class GmailReadBlock(Block):
email = Email(
threadId=msg["threadId"],
labelIds=msg.get("labelIds", []),
id=msg["id"],
subject=headers.get("subject", "No Subject"),
snippet=msg["snippet"],
@@ -347,7 +362,7 @@ class GmailSendBlock(Block):
)
class Output(BlockSchema):
result: dict = SchemaField(
result: GmailSendResult = SchemaField(
description="Send confirmation",
)
error: str = SchemaField(
@@ -478,7 +493,7 @@ class GmailAddLabelBlock(Block):
)
class Output(BlockSchema):
result: dict = SchemaField(
result: GmailLabelResult = SchemaField(
description="Label addition result",
)
error: str = SchemaField(
@@ -563,7 +578,7 @@ class GmailRemoveLabelBlock(Block):
)
class Output(BlockSchema):
result: dict = SchemaField(
result: GmailLabelResult = SchemaField(
description="Label removal result",
)
error: str = SchemaField(
@@ -664,6 +679,7 @@ class GmailGetThreadBlock(Block):
"snippet": "have a funny looking car -- Bently, Community Administrator For AutoGPT",
"subject": "car",
"threadId": "188199feff9dc907",
"labelIds": ["INBOX"],
"attachments": [
{
"size": 5694,
@@ -692,6 +708,7 @@ class GmailGetThreadBlock(Block):
"snippet": "have a funny looking car -- Bently, Community Administrator For AutoGPT",
"subject": "car",
"threadId": "188199feff9dc907",
"labelIds": ["INBOX"],
"attachments": [
{
"size": 5694,
@@ -739,6 +756,7 @@ class GmailGetThreadBlock(Block):
attachments = self._get_attachments(service, msg)
email = Email(
threadId=msg.get("threadId", thread_id),
labelIds=msg.get("labelIds", []),
id=msg["id"],
subject=headers.get("subject", "No Subject"),
snippet=msg.get("snippet", ""),

View File

@@ -520,6 +520,15 @@ class SmartDecisionMakerBlock(Block):
parallel_tool_calls=input_data.multiple_tool_calls,
)
# Add reasoning to conversation history if available
if response.reasoning:
prompt.append(
{"role": "assistant", "content": f"[Reasoning]: {response.reasoning}"}
)
prompt.append(response.raw_response)
yield "conversations", prompt
if not response.tool_calls:
yield "finished", response.response
return
@@ -553,12 +562,3 @@ class SmartDecisionMakerBlock(Block):
yield f"tools_^_{tool_name}_~_{arg_name}", tool_args[arg_name]
else:
yield f"tools_^_{tool_name}_~_{arg_name}", None
# Add reasoning to conversation history if available
if response.reasoning:
prompt.append(
{"role": "assistant", "content": f"[Reasoning]: {response.reasoning}"}
)
prompt.append(response.raw_response)
yield "conversations", prompt