Skip to content

Auto draft reply#361

Merged
elie222 merged 20 commits intomainfrom
auto-draft-reply
Feb 25, 2025
Merged

Auto draft reply#361
elie222 merged 20 commits intomainfrom
auto-draft-reply

Conversation

@elie222
Copy link
Owner

@elie222 elie222 commented Feb 25, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a new reply tracking settings interface accessible via an in-page dialog. Users can now configure reply tracking options, including enabling draft replies and updating tracking instructions.
    • Enhanced AI-generated reply responses for more professional, context-aware drafts.
    • Added functionality for tracking emails that require a response, including user-facing descriptions and actions.
    • Added a new component for managing reply tracking settings, including form handling and validation.
    • Implemented new test cases for email reply extraction functionality.
  • Bug Fixes

    • Improved error handling for user authentication and missing parameters in API responses.
  • Refactor

    • Streamlined integration and validation across email and rule management features for improved consistency.
    • Restructured validation logic for various actions to enhance organization and clarity.
  • Style

    • Made minor layout adjustments for improved alignment in interactive elements.

@vercel
Copy link

vercel bot commented Feb 25, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
inbox-zero ✅ Ready (Inspect) Visit Preview Feb 25, 2025 1:26pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2025

Warning

Rate limit exceeded

@elie222 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 38 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 58387ce and c28e9c1.

📒 Files selected for processing (2)
  • apps/web/app/(app)/automation/Rules.tsx (1 hunks)
  • apps/web/utils/actions/generate-reply.ts (3 hunks)

Walkthrough

This pull request refactors import paths and validation modules across various parts of the codebase, introduces several new Zod validation schemas, and adds reply tracking features. A new API route and custom hook are introduced, with accompanying database migration and schema updates for draft reply fields. Additional changes include UI enhancements such as a reply tracker dialog, minor CSS adjustments, and updates to AI and email utility functions including parameter renaming. Overall, the modifications standardize validation, improve rule management, and enhance reply tracking functionality.

Changes

File(s) Change Summary
apps/web/app/(app)/automation/{ReportMistake.tsx, RulesPrompt.tsx, TestCustomEmailForm.tsx, create/examples.tsx, group/ViewGroup.tsx, cold-email-blocker/TestRules.tsx, onboarding/OnboardingEmailAssistant.tsx, settings/ApiKeysCreateForm.tsx, smart-categories/CreateCategoryButton.tsx}
apps/web/utils/actions/{api-key.ts, categorize.ts, cold-email.ts, group.ts}
apps/web/utils/condition.ts
Updated import paths from legacy @/utils/actions/validation to specialized modules such as ai-rule.validation, rule.validation, group.validation, etc.
apps/web/utils/actions/{ai-rule.validation.ts, api-key.validation.ts, categorize.validation.ts, cold-email.validation.ts, group.validation.ts, rule.validation.ts} Introduced new Zod schemas and corresponding TypeScript types for AI rules, API key operations, categorization, and cold email handling; refined rule validation with a new updateRuleSettingsBody.
apps/web/__tests__/ai-choose-rule.test.ts
apps/web/app/(app)/automation/RuleForm.tsx
apps/web/app/(app)/reply-zero/{ReplyTrackerSettings.tsx, page.tsx}
apps/web/utils/actions/reply-tracking.ts
apps/web/utils/reply-tracker/{consts.ts, generate-reply.ts, inbound.ts, outbound.ts, check-previous-emails.ts}
Added and improved reply tracking functionality by using a default instruction constant, introducing new UI components and dialogs, updating tests, and refining user query/select logic for draft replies.
apps/web/hooks/useRule.tsx
apps/web/app/(app)/api/user/rules/[id]/route.ts
apps/web/prisma/{migrations/20250223190244_draft_replies/migration.sql, schema.prisma}
apps/web/scripts/encrypt-tokens.ts
Added a new API route for fetching user rules, created a custom hook for rule data fetching, executed a database migration and schema update to add draft reply fields, and modified query ordering.
apps/web/utils/ai/choose-rule/{execute.ts, run-rules.ts}
apps/web/utils/ai/reply/{check-if-needs-reply.ts, generate-reply.ts}
apps/web/utils/gmail/mail.ts
apps/web/utils/llms/types.ts
Renamed function parameters from email to message, added extra AI reply guidelines, updated type definitions to include additional fields, and modified the email drafting function to accept optional to and subject.
apps/web/components/Toggle.tsx Adjusted the CSS class by removing justify-center to change child element alignment.
apps/web/utils/actions/{ai-rule.ts, rule.ts} Renamed parameters (e.g. in approvePlanAction) and added a new updateRuleSettingsAction to update rule settings using the updated validation logic.
apps/web/utils/categorize/senders/categorize.ts Updated the categorizeSender function’s user parameter type by removing the requirement for the user’s id.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant B as Button (Dialog Trigger)
    participant D as Dialog
    participant RTS as ReplyTrackerSettings UI
    participant S as Server (API/Update Action)
    
    U->>B: Clicks on settings button
    B->>D: Opens dialog trigger
    D->>RTS: Renders ReplyTrackerSettings component
    RTS->>U: Displays form for reply tracking settings
    U->>RTS: Submits updated settings
    RTS->>S: Calls updateRuleSettingsAction API
    S-->>RTS: Returns update confirmation
    RTS-->>D: Closes dialog, updates UI
Loading
sequenceDiagram
    participant C as Client
    participant R as API Route
    participant A as Auth Check
    participant P as Prisma DB
    
    C->>R: Send GET /api/user/rules/[id]
    R->>A: Validate session/authentication
    A-->>R: Auth confirmed (or error)
    R->>P: Query rule with given ruleId and userId
    P-->>R: Return rule data
    R-->>C: Respond with JSON rule data
Loading

Possibly related PRs

  • Add UI for cursor rules style prompt #227: The changes in the main PR, specifically the modifications to the requiresResponse variable and the addition of a new test case in ai-choose-rule.test.ts, are related to the updates made to the getRule function in the retrieved PR, which also involves changes in the same test file. Both PRs focus on enhancing the functionality and clarity of rules management within the same testing context.
  • When enabling reply tracker check if any old emails need replies #323: The changes in the main PR, which involve modifying the requiresResponse variable and adding a test case for the aiChooseRule function, are related to the changes in the retrieved PR that enhance the enableReplyTrackerAction function to process previously sent emails, as both involve functionality related to reply tracking and the handling of email responses.

Poem

I’m a little rabbit, hopping through code,
New paths and hooks on this exciting road.
With imports aligned and validations in sight,
Reply tracking’s now a dazzling delight.
Bugs hop away as features emerge,
In our brisk code garden, we joyfully surge!
🥕🐇 Happy coding under the moon’s soft glow!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (12)
apps/web/utils/actions/categorize.validation.ts (1)

1-8: Well-structured Zod validation schema for category creation

The validation schema looks well-designed with appropriate constraints for each field. Using Zod for validation provides good type safety and runtime validation.

Consider a few minor enhancements that could make this validation more robust:

  1. Add .min(1) to the name field to prevent empty names
  2. Consider adding .trim() to string fields to handle whitespace consistently
  3. Add custom error messages for better user feedback

Example enhancement:

export const createCategoryBody = z.object({
  id: z.string().nullish(),
- name: z.string().max(30),
+ name: z.string().min(1, { message: "Name cannot be empty" }).max(30, { message: "Name cannot exceed 30 characters" }).trim(),
  description: z.string().max(300).nullish(),
});
apps/web/utils/actions/cold-email.validation.ts (1)

1-14: Good implementation of Zod schema validation for cold emails.

The schema properly defines the structure for validating cold email data with appropriate nullable and optional fields. The type export using z.infer is a good practice to maintain type safety throughout the application.

Consider enhancing the validation rules for specific fields:

  • Add email format validation for the from field
  • Add more specific validation for date instead of accepting both string and number
  • Consider adding min/max length constraints for text fields where appropriate
 export const coldEmailBlockerBody = z.object({
-  from: z.string(),
+  from: z.string().email("Invalid email format"),
   subject: z.string(),
   textHtml: z.string().nullable(),
   textPlain: z.string().nullable(),
   snippet: z.string().nullable(),
   // Hacky fix. Not sure why this happens. Is internalDate sometimes a string and sometimes a number?
-  date: z.string().or(z.number()).optional(),
+  date: z.coerce.date().optional(),
   threadId: z.string().nullable(),
   messageId: z.string().nullable(),
 });
apps/web/app/(app)/automation/RuleForm.tsx (1)

795-824: New component for explaining Reply Zero Tracker functionality.

The component provides clear information about what the Reply Zero Tracker does, including labeling emails that need replies and drafting responses. It also properly explains that these actions are automatically configured.

One suggestion: Consider adding more detailed information about how the AI determines when to draft replies.

apps/web/app/api/user/rules/[id]/route.ts (1)

1-28: New API endpoint for retrieving individual rules.

This endpoint provides a clean way to fetch rules by ID for authenticated users. The implementation includes proper authentication checks and error handling for missing parameters.

Some suggestions for improvement:

  1. Consider adding more detailed error responses with appropriate HTTP status codes
  2. The rule query could include related data that might be needed by clients (e.g., actions, conditions)
  3. Add validation for the rule ID format before querying the database
-  return NextResponse.json({ error: "Not authenticated" });
+  return NextResponse.json({ error: "Not authenticated" }, { status: 401 });
-  if (!params.id) return NextResponse.json({ error: "Missing rule id" });
+  if (!params.id) return NextResponse.json({ error: "Missing rule id" }, { status: 400 });
-  const rule = await prisma.rule.findUnique({ where: { id: ruleId, userId } });
+  const rule = await prisma.rule.findUnique({ 
+    where: { id: ruleId, userId },
+    include: { 
+      actions: true,
+      conditions: true
+    }
+  });
apps/web/app/(app)/reply-zero/page.tsx (1)

93-106: Add an accessible label for the settings button.

Since this button only uses an icon, including an aria-label (and/or title) helps screen readers and improves accessibility. For instance:

 <Button variant="ghost" size="icon"
+  aria-label="Settings"
+  title="Settings"
 >
   <SettingsIcon className="size-4" />
 </Button>
apps/web/utils/actions/rule.validation.ts (3)

9-19: Consider using z.nativeEnum(ActionType).

Using z.nativeEnum(ActionType) automatically stays in sync with the enum in Prisma when new actions are added or removed.


21-25: Use z.nativeEnum(RuleType) for better maintainability.

This approach makes the schema more resilient to future additions or removals of rule types in your Prisma enum.


45-51: Consider using a discriminated union for conditions.

Right now all fields from zodAiCondition, zodStaticCondition, and zodCategoryCondition are merged, potentially allowing irrelevant fields to pass. A discriminated union with z.discriminatedUnion("type", {...}) ensures strict field checks per condition type.

apps/web/utils/reply-tracker/generate-reply.ts (1)

13-40: Add error handling and possibly return the created draft’s ID.

Surrounding the draft creation logic with a try/catch or returning the draft’s ID could help debug and ensure the caller knows if the draft was successfully generated.

apps/web/app/(app)/reply-zero/ReplyTrackerSettings.tsx (1)

47-55: Add missing dependencies to useCallback

The useCallback hook is missing dependencies. Even though your function isn't using external values directly in its body, it's calling updateRuleSettingsAction which should be included in the dependency array.

  const onSubmit: SubmitHandler<UpdateRuleSettingsBody> = useCallback(
    async (data) => {
      const res = await updateRuleSettingsAction(data);
      if (isErrorMessage(res))
        toastError({ description: "There was an error updating the settings" });
      else toastSuccess({ description: "Settings updated" });
    },
-    [],
+    [updateRuleSettingsAction],
  );
apps/web/utils/actions/ai-rule.validation.ts (1)

16-33: Consider improving error message placement for related fields

The refinement for requiring either actualRuleId or expectedRuleId shows the error on the expectedRuleId field only. This might be confusing if a user is trying to provide only actualRuleId.

Consider using a custom path like ["_errors"] or showing the error on both fields for better user experience:

  .refine((data) => data.actualRuleId != null || data.expectedRuleId != null, {
    message: "Either the actual or the expected rule must be provided",
-   path: ["expectedRuleId"], // This will show the error on the expectedRuleId field
+   path: ["_errors"], // This will show as a form-level error
  });
apps/web/utils/reply-tracker/inbound.ts (1)

78-88: Improve error handling for draft generation

The draft generation is handled asynchronously outside the main Promise.allSettled group with a basic error log. Consider implementing a more robust error handling strategy such as retrying or providing more context in the error log.

  const draftPromise = generateDraft(email, gmail, message);

  const [dbResult, removeLabelResult, newLabelResult] =
    await Promise.allSettled([dbPromise, removeLabelPromise, newLabelPromise]);

  // Avoid hitting Gmail rate limit by doing too much at once
  try {
    await draftPromise;
  } catch (error) {
-   logger.error("Failed to create draft", { error });
+   logger.error("Failed to create draft", { 
+     error, 
+     messageId,
+     threadId,
+     reason: error instanceof Error ? error.message : 'Unknown error'
+   });
+   // Consider implementing retry logic or user notification here
  }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a123922 and d4a6e50.

📒 Files selected for processing (46)
  • apps/web/__tests__/ai-choose-rule.test.ts (3 hunks)
  • apps/web/app/(app)/automation/ReportMistake.tsx (1 hunks)
  • apps/web/app/(app)/automation/RuleForm.tsx (4 hunks)
  • apps/web/app/(app)/automation/RulesPrompt.tsx (1 hunks)
  • apps/web/app/(app)/automation/TestCustomEmailForm.tsx (1 hunks)
  • apps/web/app/(app)/automation/create/examples.tsx (1 hunks)
  • apps/web/app/(app)/automation/group/ViewGroup.tsx (1 hunks)
  • apps/web/app/(app)/cold-email-blocker/TestRules.tsx (1 hunks)
  • apps/web/app/(app)/onboarding/OnboardingEmailAssistant.tsx (1 hunks)
  • apps/web/app/(app)/reply-zero/ReplyTrackerSettings.tsx (1 hunks)
  • apps/web/app/(app)/reply-zero/page.tsx (2 hunks)
  • apps/web/app/(app)/settings/ApiKeysCreateForm.tsx (1 hunks)
  • apps/web/app/(app)/smart-categories/CreateCategoryButton.tsx (1 hunks)
  • apps/web/app/api/google/webhook/types.ts (1 hunks)
  • apps/web/app/api/user/rules/[id]/route.ts (1 hunks)
  • apps/web/components/Toggle.tsx (1 hunks)
  • apps/web/hooks/useRule.tsx (1 hunks)
  • apps/web/prisma/migrations/20250223190244_draft_replies/migration.sql (1 hunks)
  • apps/web/prisma/schema.prisma (1 hunks)
  • apps/web/scripts/encrypt-tokens.ts (1 hunks)
  • apps/web/utils/actions/ai-rule.ts (2 hunks)
  • apps/web/utils/actions/ai-rule.validation.ts (1 hunks)
  • apps/web/utils/actions/api-key.ts (1 hunks)
  • apps/web/utils/actions/api-key.validation.ts (1 hunks)
  • apps/web/utils/actions/categorize.ts (1 hunks)
  • apps/web/utils/actions/categorize.validation.ts (1 hunks)
  • apps/web/utils/actions/cold-email.ts (1 hunks)
  • apps/web/utils/actions/cold-email.validation.ts (1 hunks)
  • apps/web/utils/actions/group.ts (1 hunks)
  • apps/web/utils/actions/group.validation.ts (1 hunks)
  • apps/web/utils/actions/reply-tracking.ts (3 hunks)
  • apps/web/utils/actions/rule.ts (2 hunks)
  • apps/web/utils/actions/rule.validation.ts (3 hunks)
  • apps/web/utils/ai/choose-rule/execute.ts (4 hunks)
  • apps/web/utils/ai/choose-rule/run-rules.ts (1 hunks)
  • apps/web/utils/ai/reply/check-if-needs-reply.ts (1 hunks)
  • apps/web/utils/ai/reply/generate-reply.ts (1 hunks)
  • apps/web/utils/categorize/senders/categorize.ts (1 hunks)
  • apps/web/utils/condition.ts (1 hunks)
  • apps/web/utils/gmail/mail.ts (1 hunks)
  • apps/web/utils/llms/types.ts (1 hunks)
  • apps/web/utils/reply-tracker/check-previous-emails.ts (1 hunks)
  • apps/web/utils/reply-tracker/consts.ts (1 hunks)
  • apps/web/utils/reply-tracker/generate-reply.ts (1 hunks)
  • apps/web/utils/reply-tracker/inbound.ts (5 hunks)
  • apps/web/utils/reply-tracker/outbound.ts (1 hunks)
✅ Files skipped from review due to trivial changes (15)
  • apps/web/components/Toggle.tsx
  • apps/web/utils/actions/group.ts
  • apps/web/utils/condition.ts
  • apps/web/app/(app)/automation/RulesPrompt.tsx
  • apps/web/app/(app)/onboarding/OnboardingEmailAssistant.tsx
  • apps/web/app/(app)/smart-categories/CreateCategoryButton.tsx
  • apps/web/app/(app)/automation/create/examples.tsx
  • apps/web/utils/actions/categorize.ts
  • apps/web/utils/actions/cold-email.ts
  • apps/web/app/(app)/settings/ApiKeysCreateForm.tsx
  • apps/web/app/(app)/automation/TestCustomEmailForm.tsx
  • apps/web/app/(app)/automation/ReportMistake.tsx
  • apps/web/utils/ai/choose-rule/run-rules.ts
  • apps/web/app/(app)/automation/group/ViewGroup.tsx
  • apps/web/app/(app)/cold-email-blocker/TestRules.tsx
🔇 Additional comments (45)
apps/web/utils/actions/group.validation.ts (1)

1-9: Looks good - clean validation schema implementation.

This new file effectively establishes a dedicated validation schema for group items using Zod. The schema properly validates the required fields with appropriate types, and exports a type alias using Zod's inference capabilities for type safety throughout the application.

This change aligns with the PR's objective of refactoring validation modules across the codebase for better organization and standardization.

apps/web/utils/actions/api-key.validation.ts (1)

1-7: Well-structured validation schema implementation.

The Zod schema definitions are clean, focused, and properly typed with corresponding TypeScript type exports. This approach allows for both runtime validation and static type checking.

apps/web/utils/actions/api-key.ts (1)

5-10: Good import refactoring.

The import statement has been properly updated to use the new validation module. Using explicit type imports with the type keyword is a good TypeScript practice as it ensures these imports are removed during transpilation, leading to smaller bundle sizes.

apps/web/utils/actions/cold-email.validation.ts (1)

9-10: Investigate the type inconsistency for the date field.

The comment indicates uncertainty about why the date field sometimes has a string type and sometimes a number type. This inconsistency should be investigated at the source to determine if there's a more elegant solution than accepting multiple types.

You might want to trace how the date is being provided to this validation schema. Is it coming from different API sources or being transformed differently in various parts of the application?

apps/web/scripts/encrypt-tokens.ts (1)

23-25: Ordering by updatedAt is a good optimization.

Sorting accounts by most recently updated first ensures that active accounts are processed with priority. This is especially beneficial if the script encounters issues that prevent full completion.

apps/web/prisma/migrations/20250223190244_draft_replies/migration.sql (1)

1-3: Schema changes look appropriate for draft reply functionality.

The addition of draftReplies as a boolean flag and draftRepliesInstructions as a text field provides the necessary structure to support the auto draft reply feature mentioned in the PR title.

apps/web/hooks/useRule.tsx (1)

1-8:

Details

❓ Verification inconclusive

Clean implementation of the useRule hook.

The hook follows React best practices with conditional fetching (only when ruleId is provided) and proper TypeScript typing. One note: you're using the default fetcher for SWR - ensure this aligns with your API response handling needs.

Make sure your API endpoint returns data that matches the expected RuleResponse type:


🏁 Script executed:

#!/bin/bash
# Verify if there's a corresponding API route for this hook
fd --type file "route.ts" -p "api/user/rules/\[id\]"

Length of output: 161


Action: Verify API Endpoint Route

The implementation of the useRule hook looks clean and follows React best practices with conditional fetching and proper TypeScript typings. However, our initial attempt to verify the corresponding API route (i.e. the file implementing /api/user/rules/[id]) using the shell script encountered an issue due to an invalid search path.

Please ensure that your repository contains the API endpoint file (typically something like api/user/rules/[id]/route.ts) and that its response conforms to the expected RuleResponse type. You might want to re-run verification using a command similar to the one below:

#!/bin/bash
# Corrected verification: search for route.ts files in directories containing the expected API path segment
fd --type file "route.ts" | grep -E "api/user/rules/\\[id\\]"

Manually verify the location and content of the API route if the automated search does not produce the expected output.

apps/web/utils/reply-tracker/consts.ts (1)

3-12: Well-structured instructions for reply tracking.

The defaultReplyTrackerInstructions constant provides clear, comprehensive guidelines for identifying emails that need replies. Extracting this to a constant improves maintainability and consistency across the application.

apps/web/utils/llms/types.ts (1)

4-4: Type signature enhancement looks good.

The addition of the id field to the UserEmailWithAI type is a logical improvement that ensures consistent user identification across the application.

apps/web/prisma/schema.prisma (1)

192-193: Clean implementation of draft reply feature fields.

The new fields for draft replies functionality are well-placed within the reply tracking section of the Rule model and properly typed as optional.

apps/web/utils/ai/reply/generate-reply.ts (1)

27-31: Improved AI guidance for more professional replies.

The additional instructions enhance the quality of generated replies by providing clearer guidelines on brevity, placeholder usage, and avoiding invention of information.

apps/web/utils/ai/reply/check-if-needs-reply.ts (1)

20-20:

Details

❓ Verification inconclusive

Verify impact of removing id field from parameter type.

While simplifying the user parameter type by removing the id field seems intentional, this appears to contradict adding id to UserEmailWithAI in types.ts. Ensure this change doesn't break functionality in the chatCompletionObject function or other dependent code.


🏁 Script executed:

#!/bin/bash
# Check if chatCompletionObject uses the user.id field
rg -A 5 -B 5 "chatCompletionObject" | grep -A 10 "userAi"

# Check for other usages of user.id in reply-related functions
rg "user\.id" --type ts "utils/ai/reply"

Length of output: 9420


Action Required: Confirm Removal of id Field Does Not Break Functionality

After running the initial verification, no direct usage of user.id was found in the chatCompletionObject or in reply-related functions. However, note that the type definition in types.ts—where UserEmailWithAI includes an id—suggests that some code paths might expect this field. Please manually verify that the current composition

user: Pick<User, "about"> & UserEmailWithAI;

(which omits id from the Pick portion) does not remove the necessary id property at runtime or cause unexpected behavior in dependent functions.

  • Verify in detail:
    • Confirm that the chatCompletionObject and any reply-related logic do not rely on an id property directly from the combined type.
    • Ensure that the intersection effectively provides the id from UserEmailWithAI (if that is the intent) and that this change aligns with overall code expectations.

Please perform a careful manual review of these impacts.

apps/web/utils/gmail/mail.ts (1)

237-239: Appropriate update to parameter optionality.

Making to and subject parameters optional is a good improvement since the function already handles missing values by using fallbacks from the original email (lines 249-255).

apps/web/utils/actions/rule.ts (3)

13-15: LGTM! Good refactoring of validation imports.

The addition of updateRuleSettingsBody and UpdateRuleSettingsBody from the validation file shows good separation of concerns by moving validation logic to a dedicated file.


293-293: Good revalidation path addition for reply-zero.

This ensures that the UI is updated after rule settings change, providing a consistent user experience.


259-297:

Details

❓ Verification inconclusive

Well-structured new action function for updating rule settings.

The implementation follows the same pattern as other action functions in the file, making it consistent with the codebase. It properly validates input, performs error checking, and updates necessary related data.

However, there are commented-out fields in the data object (lines 278-279) that appear to be related to draft replies. Consider whether these should be implemented or removed if they're not needed.


🏁 Script executed:

#!/bin/bash
# Check if these fields exist in the schema and if they're used elsewhere
rg "autoDraftReply|draftReplyInstructions" -A 3 -B 3

Length of output: 611


Action Required: Verify Handling of Commented Fields in Rule Settings Update

The new action function is well-structured and consistent with the rest of the file. However, note that the fields autoDraftReply and draftReplyInstructions remain commented out. Our grep search confirms they only appear here and aren’t referenced elsewhere. Please verify whether these fields are intended to be part of the update logic (in which case, ensure their proper implementation along with any required schema adjustments) or if they should be removed to keep the code clean.

  • Confirm if the draft reply functionality is planned.
  • If not needed, remove the commented-out code to reduce clutter.
apps/web/__tests__/ai-choose-rule.test.ts (3)

4-4: Good refactoring to use constants for rule instructions.

Importing the defaultReplyTrackerInstructions constant improves maintainability by centralizing the rule definition.


103-103: Improved maintainability by using the imported constant.

Using defaultReplyTrackerInstructions instead of a hardcoded string ensures consistency across the application and makes future updates easier.


147-163: Well-structured test case for meeting request detection.

This test validates that the reply tracker correctly identifies emails requesting a meeting, which is an important use case. The test follows the same pattern as other test cases in the file.

apps/web/utils/categorize/senders/categorize.ts (1)

18-18:

Details

✅ Verification successful

Simplifying the user parameter type.

This change suggests that UserEmailWithAI now includes the id field, making the use of Pick<User, "id"> redundant. Ensure that all callers of this function provide an object with the id property.


🏁 Script executed:

#!/bin/bash
# Check if UserEmailWithAI type includes id field
rg -A 5 "type UserEmailWithAI" --glob="*.ts"

# Check if all callers provide id property
rg "categorizeSender\(" -A 5 -B 5

Length of output: 3858


Simplified Parameter for categorizeSender Verified

The update now directly uses UserEmailWithAI for the user parameter, which already includes the id field (see apps/web/utils/llms/types.ts). Verification of call sites—such as in apps/web/app/api/google/webhook/process-history-item.ts and apps/web/utils/actions/categorize.ts—confirms that all callers provide an object with an id.

apps/web/utils/ai/choose-rule/execute.ts (3)

9-9: Type import update for more appropriate message representation.

Changing from EmailForAction to ParsedMessage suggests a model refinement to better represent the data structure.


18-19: Consistent parameter renaming to match type change.

Renaming the parameter from email to message better reflects its purpose and aligns with the type update to ParsedMessage.

Also applies to: 23-24


51-52: Updated function calls to use the renamed parameter.

All occurrences of the renamed parameter have been consistently updated throughout the function, preventing potential errors.

Also applies to: 68-71

apps/web/app/(app)/automation/RuleForm.tsx (3)

33-33: Import path updated for better organization.

The import path has been changed from @/utils/actions/validation to @/utils/actions/rule.validation, which appears to be part of a broader restructuring of validation logic across files.


58-61: New constants imported for reply tracking feature.

These constants are used in the newly added ReplyTrackerActionSection component to display consistent label names for awaiting and needed replies.


518-520: Added new section for Reply Zero Tracker in the form.

This addition integrates the reply tracking feature into the rule form interface, providing users with information about how the feature works.

apps/web/utils/actions/ai-rule.ts (2)

26-30: Restructured imports for better organization.

The import for saveRulesPromptBody and its type has been moved from @/utils/actions/validation to @/utils/actions/rule.validation, which aligns with the refactoring of validation logic across the codebase.


273-273: Parameter name updated for clarity.

Changed parameter name from email to message in the executeAct function call, which more accurately reflects the data type being passed (ParsedMessage) and maintains consistency with other related functions.

apps/web/utils/actions/reply-tracking.ts (3)

12-15: Imported centralized reply tracker instructions constant.

The previously hardcoded instructions have been replaced with a constant imported from a dedicated module, improving maintainability and consistency.


43-43: Added user ID field to selection.

This ensures the user ID is available in the selected fields, which is necessary for subsequent operations.


104-104: Using standardized instructions from constant.

This change replaces hardcoded instructions with the imported constant, making the code more maintainable and ensuring consistency across the application.

apps/web/app/(app)/reply-zero/page.tsx (1)

22-28: Nice integration of Dialog components.

These imports align with common best practices for showing a dialog in place rather than navigating the user away.

apps/web/utils/actions/rule.validation.ts (5)

3-3: Import statements look good.

No issues encountered with these additional imports for ActionType and RuleType.

Also applies to: 6-6


27-29: This AI condition schema looks straightforward.


31-36: Static condition schema is clearly defined.


38-43: Category condition schema looks good.


142-148: Confirm which fields should be optional vs. required.

Currently, all properties (instructions, draftReplies, draftRepliesInstructions) are mandatory. If users or upstream code sometimes omit these fields, consider .optional() or .nullish().

apps/web/utils/reply-tracker/generate-reply.ts (2)

1-12: Import statements check out.

The dependencies for Gmail, AI generation, Redis, and user data retrieval are well-organized.


42-74: Logic for generating and caching replies is well-structured.

You cleanly avoid regenerating replies if they exist, minimizing redundant AI calls.

apps/web/app/(app)/reply-zero/ReplyTrackerSettings.tsx (2)

20-28: LGTM! Well-structured component with proper error handling

The component correctly uses the useRule hook to fetch data and handles loading and error states appropriately with the LoadingContent component.


30-97: Form implementation follows best practices

The form implementation is well-structured with:

  • Proper form state management using react-hook-form
  • Zod validation via zodResolver
  • Conditional rendering for draft replies instructions
  • Error handling and user feedback with toast messages

The code is clean, readable, and follows React best practices.

apps/web/utils/actions/ai-rule.validation.ts (2)

3-6: LGTM! Clear and concise validation schema

The validation schema for the test content is well-defined with a meaningful error message.


8-14:

Details

❓ Verification inconclusive

Consider clarifying the nullish rerun property

The rerun property is defined as z.boolean().nullish(), which accepts null or undefined values. Verify if this is intentional or if you meant to make it optional with z.boolean().optional() instead.


🏁 Script executed:

#!/bin/bash
# Search for usages of the runRulesBody schema to understand how rerun is used

echo "Searching for imports of runRulesBody..."
rg -A 2 "import.*runRulesBody" --type ts

echo "Searching for usages of runRulesBody..."
rg "runRulesBody" --type ts

echo "Searching for places where rerun parameter is used..."
rg "rerun.*\?.*:" --type ts

Length of output: 921


Review Feedback: Clarify the rerun Property Handling

  • In apps/web/utils/actions/ai-rule.validation.ts (lines 8–14), the rerun property is defined as z.boolean().nullish(), meaning it accepts true, false, as well as null or undefined.
  • Notably, in apps/web/app/(app)/automation/ProcessRules.tsx, the property is used as an optional boolean (rerun?: boolean), which suggests that only true, false, or undefined are expected.
  • Please confirm if allowing an explicit null value is intentional. If not, consider changing the schema to z.boolean().optional() for consistency with the expected usage.
apps/web/utils/reply-tracker/inbound.ts (2)

17-17: LGTM! Good addition of draft generation functionality

Adding the draft generation capability is a valuable enhancement to the reply tracking system.


110-112:

Details

✅ Verification successful

Verify impact of user parameter signature change

The signature of handleInboundReply has been modified to remove the id field from the user parameter. Ensure all calling code has been updated to match this new signature.


🏁 Script executed:

#!/bin/bash
# Search for places where handleInboundReply is called
echo "Searching for calls to handleInboundReply..."
rg "handleInboundReply\(" --type ts -A 3 -B 3

Length of output: 1282


User Parameter Update Verified

I verified that the update to handleInboundReply—removing the id field from the user parameter—is consistently reflected in the codebase. The only call site located in apps/web/utils/reply-tracker/check-previous-emails.ts correctly passes the updated parameters (user, latestMessage, and gmail). No further changes are needed at this time.


export async function handleOutboundReply(
user: Pick<User, "id" | "about"> & UserEmailWithAI,
user: Pick<User, "about"> & UserEmailWithAI,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential type inconsistency with parameter usage.

You've removed "id" from the Pick<User, "about"> type, but on line 23 there's still a reference to const userId = user.id;. This could cause TypeScript errors since the id property is no longer explicitly included in the type.

This inconsistency needs to be resolved by either:

  1. Restoring the "id" property in the parameter type, or
  2. Ensuring the id property is coming from the UserEmailWithAI type
  3. Modifying how userId is retrieved within the function
-  user: Pick<User, "about"> & UserEmailWithAI,
+  user: Pick<User, "id" | "about"> & UserEmailWithAI,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
user: Pick<User, "about"> & UserEmailWithAI,
user: Pick<User, "id" | "about"> & UserEmailWithAI,

export async function processPreviousSentEmails(
gmail: gmail_v1.Gmail,
user: Pick<User, "id" | "about"> & UserEmailWithAI,
user: Pick<User, "about"> & UserEmailWithAI,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Type consistency check needed.

The id property has been removed from the user parameter type. Although there are no direct references to user.id in this function, verify that the id property isn't required for downstream functions like handleOutboundReply and handleInboundReply that are called with this user object.


🏁 Script executed:

#!/bin/bash
# Search for references to user.id in handleOutboundReply and handleInboundReply
echo "Checking for user.id references in related functions:"
rg -n "user\.id" "apps/web/utils/reply-tracker/outbound.ts" "apps/web/utils/reply-tracker/inbound.ts"

Length of output: 519


Type consistency issue: Downstream functions require the user’s id

The removal of id from the user type in apps/web/utils/reply-tracker/check-previous-emails.ts is problematic. Our grep results show that both handleOutboundReply and handleInboundReply rely on user.id (see references in inbound.ts at lines 119 and 136, and in outbound.ts at lines 23 and 32). To resolve this, update the type signature to include the id property. For example:

-  user: Pick<User, "about"> & UserEmailWithAI,
+  user: Pick<User, "id" | "about"> & UserEmailWithAI,

Please update the type accordingly to ensure that all downstream calls receive the expected id property.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
user: Pick<User, "about"> & UserEmailWithAI,
user: Pick<User, "id" | "about"> & UserEmailWithAI,

Comment on lines 15 to 18
user: Pick<
User,
| "id"
| "about"
| "coldEmailPrompt"
| "coldEmailBlocker"
| "autoCategorizeSenders"
"about" | "coldEmailPrompt" | "coldEmailBlocker" | "autoCategorizeSenders"
> &
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify removal of "id" property across the codebase.

Removing the id property from the user type might be part of a broader refactoring. Check if any code using this type relies on accessing user.id.


🏁 Script executed:

#!/bin/bash
# Find files that import ProcessHistoryOptions and check for user.id usage
echo "Looking for files that import ProcessHistoryOptions:"
rg -l "ProcessHistoryOptions" "apps/web"

echo "\nChecking for user.id references in files that might be using ProcessHistoryOptions:"
rg -n "user\.id" $(rg -l "ProcessHistoryOptions" "apps/web")

Length of output: 1302


Action Required: Address Remaining References to user.id

We've verified that after the removal of the id property from the user type in apps/web/app/api/google/webhook/types.ts, there are still active code paths that reference user.id. In particular, multiple occurrences in the file apps/web/app/api/google/webhook/process-history-item.ts (lines 60, 89, 115, and 159) indicate that the removal may break functionality where user.id is expected.

Please consider updating these references by either:

  • Adding the id property back into the user type where it is still needed, or
  • Refactoring the code in the affected files to remove dependency on user.id.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/web/components/email-list/EmailMessage.tsx (1)

354-355: Remove debugging console.log statement

There's a console.log statement that appears to be left in for debugging purposes and should be removed before merging.

-  console.log("🚀 ~ splitHtml:", splitHtml);
-
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9fd4a4e and 58387ce.

📒 Files selected for processing (3)
  • apps/web/components/email-list/EmailMessage.tsx (5 hunks)
  • apps/web/utils/parse/extract-reply.client.test.ts (1 hunks)
  • apps/web/utils/parse/extract-reply.client.ts (1 hunks)
🔇 Additional comments (7)
apps/web/components/email-list/EmailMessage.tsx (5)

209-210: State variables renamed to better reflect functionality

The state variables have been renamed from "isGeneratingNudge" and "nudge" to "isGeneratingReply" and "reply" respectively, which better reflects the actual functionality of generating replies rather than nudges.


222-248: Function renamed with improved state management

The function has been renamed from "loadNudge" to "generateReply" with appropriate updates to its internal state management. The function maintains the same core functionality but with more accurate naming.


250-252: Improved condition for generating replies

The condition for when to generate a reply has been updated to be more explicit: only generate a reply if generateNudge is true and there's no draft message. This prevents unnecessary API calls.


259-270: Updated memoization logic for reply content

The memoization logic has been updated to use the new "reply" variable, maintaining the same functionality with more accurate naming that reflects the purpose of generating replies rather than nudges.


282-292: Loading state naming updated for consistency

The loading state display has been updated to reflect the renamed state variable isGeneratingReply, maintaining UI consistency with the backend functionality changes.

apps/web/utils/parse/extract-reply.client.ts (1)

24-43: Well-implemented special case handling for Gmail's formatting.

This addition neatly handles Gmail's specific format where replies are separated by <br> tags before the quoted content. The approach is clean - extracting content before the separator, parsing it for the reply div, and maintaining proper structure in the returned object. This will improve reply extraction reliability for Gmail users.

apps/web/utils/parse/extract-reply.client.test.ts (1)

95-113: Excellent test coverage for the new Gmail format handling.

These tests thoroughly validate the new special case handling with realistic Gmail HTML structures. Good job including both a simple case and a more complex case with formatted text. The assertions properly check both the extracted draft content and the presence of the quote container in the original HTML.

@elie222 elie222 merged commit 41182b0 into main Feb 25, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments