Sweetmantech/myc 3794 api email agentgenerate pass in full message history for the#79
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis PR introduces a comprehensive inbound email handling system with automated reply generation. It adds an email ingestion API route, email processing pipeline, chat room orchestration, message persistence, and agent-based reply composition. New utilities support UUID generation, system prompt construction, tool setup, memory tracking, and database schema extensions. The changes integrate Resend email service and MCP-based tool management. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as HTTP Client
participant APIRoute as API Route<br/>(POST /inbound)
participant Validator as validateInboundEmailEvent
participant EmailHandler as handleInboundEmail
participant Responder as respondToInboundEmail
participant Resend as Resend API
participant Agent as getGeneralAgent
participant Memory as Supabase Memories
Client->>APIRoute: POST with email event
APIRoute->>Validator: Validate event payload
alt Invalid Event
Validator->>APIRoute: 400 error response
APIRoute->>Client: Return error
else Valid Event
Validator->>APIRoute: Parsed event
APIRoute->>EmailHandler: handleInboundEmail(request)
rect rgb(200, 220, 240)
note over EmailHandler: Process email.received event
EmailHandler->>Responder: respondToInboundEmail(event)
Responder->>Resend: getEmailContent(emailId)
Resend-->>Responder: Email with headers
Responder->>Responder: Extract room_id from references
Responder->>Responder: Build chat request with message history
Responder->>Agent: getGeneralAgent(chatRequest)
Agent-->>Responder: Agent + tools + instructions
Responder->>Agent: Generate reply via ToolLoopAgent
Agent-->>Responder: Reply text
Responder->>Resend: sendEmailWithResend(reply payload)
Resend-->>Responder: Email sent confirmation
Responder->>Memory: insertMemoryEmail(linkage)
Memory-->>Responder: Saved reference
end
Responder-->>EmailHandler: Response
EmailHandler-->>APIRoute: Response
APIRoute-->>Client: 200 OK
end
sequenceDiagram
participant App as Application
participant Validator as validateChatRequest
participant Completion as handleChatCompletion
participant RoomSvc as Room Service
participant MsgSvc as Message Service
participant Memory as Supabase
App->>Validator: Validate chat request<br/>(messages or prompt)
alt Invalid
Validator->>App: Error
else Valid
Validator-->>Completion: Proceed
Completion->>MsgSvc: validateMessages(messages)
MsgSvc-->>Completion: lastMessage + validMessages
alt Room exists
Completion->>RoomSvc: selectRoom(roomId)
RoomSvc-->>Completion: Room data
else Room missing
Completion->>RoomSvc: createNewRoom(accountId, roomId)
RoomSvc->>Memory: insertRoom + notify
Memory-->>RoomSvc: Confirmed
end
Completion->>MsgSvc: saveNewMessages(roomId, messages)
MsgSvc->>Memory: insertMemories (user + assistant)
Memory-->>MsgSvc: Saved records
MsgSvc-->>Completion: Memory array
Completion-->>App: Memory records
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Areas requiring extra attention:
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Additional Suggestion:
If the AI agent's response text is empty or falsy, the code will crash when trying to save the assistant's message to the database.
View Details
📝 Patch Details
diff --git a/lib/chat/saveNewMessages.ts b/lib/chat/saveNewMessages.ts
index 8bd8262..46878ca 100644
--- a/lib/chat/saveNewMessages.ts
+++ b/lib/chat/saveNewMessages.ts
@@ -34,6 +34,11 @@ export async function saveNewMessages({
content: filterMessageContentForMemories(lastMessage),
});
+ // Only save assistant message if response messages exist (e.g., not empty from AI agent)
+ if (responseMessages.length === 0) {
+ return [userMemory].filter((m): m is Memory => m !== null);
+ }
+
const assistantMemory = await insertMemories({
id: responseMessages[responseMessages.length - 1].id,
room_id: roomId,
diff --git a/lib/emails/inbound/respondToInboundEmail.ts b/lib/emails/inbound/respondToInboundEmail.ts
index 7f831bf..95d8e05 100644
--- a/lib/emails/inbound/respondToInboundEmail.ts
+++ b/lib/emails/inbound/respondToInboundEmail.ts
@@ -52,6 +52,15 @@ export async function respondToInboundEmail(
const chatResponse = await agent.generate({
messages,
});
+
+ // Skip email and database save if the assistant response is empty
+ if (!chatResponse.text) {
+ return NextResponse.json(
+ { error: "No response generated from AI agent" },
+ { status: 400 },
+ );
+ }
+
const payload = {
from,
to: toArray,
Analysis
Crash when AI agent returns empty text in respondToInboundEmail
What fails: saveNewMessages() crashes with TypeError: Cannot read property 'id' of undefined when ToolLoopAgent.generate() returns an empty text string, which causes getMessages() to return an empty array and accessing responseMessages[-1] throws.
How to reproduce:
- Trigger inbound email processing via
respondToInboundEmail()endpoint - Configure the AI agent to invoke tools that produce only tool results without generating text (empty
textfield) - Per AI SDK GitHub issue #1831, this is a known scenario where tool-only responses return empty text
Result: The code crashes at lib/chat/saveNewMessages.ts:40 when trying to access responseMessages[responseMessages.length - 1].id on an empty array, resulting in a TypeError: Cannot read property 'id' of undefined
Expected: Should handle empty AI responses gracefully without crashing. Per Vercel AI SDK documentation, the text field is always a string but can be empty when models prioritize tool invocation over text generation.
Root cause: The code does not validate that chatResponse.text is non-empty before passing it to getMessages(), which returns an empty array for falsy input. The empty array is then passed to saveNewMessages() which attempts to access the last element without checking if the array is empty.
Fix: Added defensive checks at two levels:
- In
respondToInboundEmail.ts: Return error response ifchatResponse.textis falsy before sending empty email - In
saveNewMessages.ts: Check ifresponseMessagesarray is empty before accessing the last element
Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.