Conversation
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
|
Caution Review failedThe pull request is closed. WalkthroughPreviously commented-out code for automatic draft generation in the thread workflow was restored. This includes re-enabling imports and reintegrating logic that analyzes the latest email's intent, determines if a draft should be generated, and creates the draft if appropriate. No new logic or error handling was introduced. Changes
Sequence Diagram(s)sequenceDiagram
participant ThreadWorkflow
participant ThreadWorkflowUtils
participant Agent
ThreadWorkflow->>ThreadWorkflowUtils: analyzeEmailIntent(latestMessage)
ThreadWorkflowUtils-->>ThreadWorkflow: intent
ThreadWorkflow->>ThreadWorkflowUtils: shouldGenerateDraft(intent)
ThreadWorkflowUtils-->>ThreadWorkflow: shouldGenerate
alt shouldGenerate
ThreadWorkflow->>ThreadWorkflowUtils: generateAutomaticDraft(thread, intent)
ThreadWorkflowUtils-->>ThreadWorkflow: draftContent
ThreadWorkflow->>Agent: createDraft(draftContent, metadata)
Agent-->>ThreadWorkflow: draftId or error
ThreadWorkflow->>ThreadWorkflow: log draftId or error
else do nothing
end
Possibly related PRs
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (3)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
This stack of pull requests is managed by Graphite. Learn more about stacking. |
There was a problem hiding this comment.
cubic analysis
1 issue found across 1 file • Review in cubic
React with 👍 or 👎 to teach cubic. You can also tag @cubic-dev-ai to give feedback, ask questions, or re-run the review.
|
|
||
| const replyTo = latestMessage.sender?.email || ''; | ||
| const cc = | ||
| latestMessage.cc |
There was a problem hiding this comment.
Calling .filter on the result of an optional chain can throw when latestMessage.cc is undefined, crashing the workflow
Prompt for AI agents
Address the following comment on apps/server/src/pipelines.effect.ts at line 497:
<comment>Calling .filter on the result of an optional chain can throw when latestMessage.cc is undefined, crashing the workflow</comment>
<file context>
@@ -17,11 +17,11 @@ import {
SummarizeThread,
ThreadLabels,
} from './lib/brain.fallback.prompts';
-// import {
-// generateAutomaticDraft,
-// shouldGenerateDraft,
-// analyzeEmailIntent,
-// } from './thread-workflow-utils';
+import {
+ generateAutomaticDraft,
+ shouldGenerateDraft,
+ analyzeEmailIntent,
+} from './thread-workflow-utils';
import { defaultLabels, EPrompts, EProviders, type ParsedMessage, type Sender } from './types';
import { getZeroAgent } from './lib/server-utils';
import { type gmail_v1 } from '@googleapis/gmail';
@@ -452,89 +452,91 @@ export const runThreadWorkflow = (
return 'Thread has no messages';
}
- // const autoDraftId = yield* Effect.tryPromise({
- // try: async () => {
- // if (!shouldGenerateDraft(thread, foundConnection)) {
- // console.log('[THREAD_WORKFLOW] Skipping draft generation for thread:', threadId);
- // return null;
- // }
-
- // const latestMessage = thread.messages[thread.messages.length - 1];
- // const emailIntent = analyzeEmailIntent(latestMessage);
-
- // console.log('[THREAD_WORKFLOW] Analyzed email intent:', {
- // threadId,
- // isQuestion: emailIntent.isQuestion,
- // isRequest: emailIntent.isRequest,
- // isMeeting: emailIntent.isMeeting,
- // isUrgent: emailIntent.isUrgent,
- // });
-
- // if (
- // !emailIntent.isQuestion &&
- // !emailIntent.isRequest &&
- // !emailIntent.isMeeting &&
- // !emailIntent.isUrgent
- // ) {
- // console.log(
- // '[THREAD_WORKFLOW] Email does not require a response, skipping draft generation',
- // );
- // return null;
- // }
-
- // console.log('[THREAD_WORKFLOW] Generating automatic draft for thread:', threadId);
- // const draftContent = await generateAutomaticDraft(
- // connectionId.toString(),
- // thread,
- // foundConnection,
- // );
-
- // if (draftContent) {
- // const latestMessage = thread.messages[thread.messages.length - 1];
-
- // const replyTo = latestMessage.sender?.email || '';
- // const cc =
- // latestMessage.cc
- // ?.map((r) => r.email)
- // .filter((email) => email && email !== foundConnection.email) || [];
-
- // const originalSubject = latestMessage.subject || '';
- // const replySubject = originalSubject.startsWith('Re: ')
- // ? originalSubject
- // : `Re: ${originalSubject}`;
-
- // const draftData = {
- // to: replyTo,
- // cc: cc.join(', '),
- // bcc: '',
- // subject: replySubject,
- // message: draftContent,
- // attachments: [],
- // id: null,
- // threadId: threadId.toString(),
- // fromEmail: foundConnection.email,
- // };
-
- // try {
- // const createdDraft = await agent.createDraft(draftData);
- // console.log('[THREAD_WORKFLOW] Created automatic draft:', {
- // threadId,
- // draftId: createdDraft?.id,
- // });
- // return createdDraft?.id || null;
- // } catch (error) {
- // console.log('[THREAD_WORKFLOW] Failed to create automatic draft:', {
- // threadId,
- // error: error instanceof Error ? error.message : String(error),
- // });
- // return null;
- // }
- // }
-
- // return null;
- // },
- // catch: (error) => ({ _tag: 'DatabaseError' as const, error }),
- // });
+ const autoDraftId = yield* Effect.tryPromise({
+ try: async () => {
+ if (!shouldGenerateDraft(thread, foundConnection)) {
+ console.log('[THREAD_WORKFLOW] Skipping draft generation for thread:', threadId);
+ return null;
+ }
+
+ const latestMessage = thread.messages[thread.messages.length - 1];
+ const emailIntent = analyzeEmailIntent(latestMessage);
+
+ console.log('[THREAD_WORKFLOW] Analyzed email intent:', {
+ threadId,
+ isQuestion: emailIntent.isQuestion,
+ isRequest: emailIntent.isRequest,
+ isMeeting: emailIntent.isMeeting,
+ isUrgent: emailIntent.isUrgent,
+ });
+
+ if (
+ !emailIntent.isQuestion &&
+ !emailIntent.isRequest &&
+ !emailIntent.isMeeting &&
+ !emailIntent.isUrgent
+ ) {
+ console.log(
+ '[THREAD_WORKFLOW] Email does not require a response, skipping draft generation',
+ );
+ return null;
+ }
+
+ console.log('[THREAD_WORKFLOW] Generating automatic draft for thread:', threadId);
+ const draftContent = await generateAutomaticDraft(
+ connectionId.toString(),
+ thread,
+ foundConnection,
+ );
+
+ if (draftContent) {
+ const latestMessage = thread.messages[thread.messages.length - 1];
+
+ const replyTo = latestMessage.sender?.email || '';
+ const cc =
+ latestMessage.cc
+ ?.map((r) => r.email)
+ .filter((email) => email && email !== foundConnection.email) || [];
+
+ const originalSubject = latestMessage.subject || '';
+ const replySubject = originalSubject.startsWith('Re: ')
+ ? originalSubject
+ : `Re: ${originalSubject}`;
+
+ const draftData = {
+ to: replyTo,
+ cc: cc.join(', '),
+ bcc: '',
+ subject: replySubject,
+ message: draftContent,
+ attachments: [],
+ id: null,
+ threadId: threadId.toString(),
+ fromEmail: foundConnection.email,
+ };
+
+ try {
+ const createdDraft = await agent.createDraft(draftData);
+ console.log('[THREAD_WORKFLOW] Created automatic draft:', {
+ threadId,
+ draftId: createdDraft?.id,
+ });
+ return createdDraft?.id || null;
+ } catch (error) {
+ console.log('[THREAD_WORKFLOW] Failed to create automatic draft:', {
+ threadId,
+ error: error instanceof Error ? error.message : String(error),
+ });
+ return null;
+ }
+ }
+
+ return null;
+ },
+ catch: (error) => ({ _tag: 'DatabaseError' as const, error }),
+ });
+
+ yield* Console.log('[THREAD_WORKFLOW] ' + autoDraftId);
yield* Console.log('[THREAD_WORKFLOW] Processing thread messages and vectorization');
</file context>
80e71aa to
2c8f729
Compare
There was a problem hiding this comment.
Bug: Bulk Selection UI Removal Causes Grid Layout Issues
The SelectAllCheckbox component has been removed from the UI (its import is commented out), eliminating the "select all" functionality for bulk email operations. This also causes a grid layout issue in the mail list header: when bulk selection is active, the search section is removed, and the remaining elements (SidebarToggle, refresh button, bulk selection UI) lack explicit column spans, leading to improper spacing and unpredictable layout.
apps/mail/components/mail/mail.tsx#L35-L580
Zero/apps/mail/components/mail/mail.tsx
Lines 35 to 580 in 2c8f729
BugBot free trial expires on July 31, 2025
Learn more in the Cursor dashboard.
Was this report helpful? Give feedback by reacting with 👍 or 👎

READ CAREFULLY THEN REMOVE
Remove bullet points that are not relevant.
PLEASE REFRAIN FROM USING AI TO WRITE YOUR CODE AND PR DESCRIPTION. IF YOU DO USE AI TO WRITE YOUR CODE PLEASE PROVIDE A DESCRIPTION AND REVIEW IT CAREFULLY. MAKE SURE YOU UNDERSTAND THE CODE YOU ARE SUBMITTING USING AI.
Description
Please provide a clear description of your changes.
Type of Change
Please delete options that are not relevant.
Areas Affected
Please check all that apply:
Testing Done
Describe the tests you've done:
Security Considerations
For changes involving data or authentication:
Checklist
Additional Notes
Add any other context about the pull request here.
Screenshots/Recordings
Add screenshots or recordings here if applicable.
By submitting this pull request, I confirm that my contribution is made under the terms of the project's license.
Summary by cubic
Enabled automatic draft generation in the thread workflow by uncommenting and activating related logic.
Summary by CodeRabbit
New Features
User Interface Updates
Bug Fixes