-
- Learned Patterns (Group)
+
+
+ Learned Patterns (previously known as Groups)
+
From c9ea2a9bfc0117178ca8f0af9d6bd45e70e0f822 Mon Sep 17 00:00:00 2001
From: Eliezer Steinbock <3090527+elie222@users.noreply.github.com>
Date: Wed, 29 Jan 2025 21:38:05 +0200
Subject: [PATCH 21/28] Adjust smart cat copy
---
apps/web/app/(app)/smart-categories/page.tsx | 4 ++--
.../app/(app)/smart-categories/setup/SetUpCategories.tsx | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/apps/web/app/(app)/smart-categories/page.tsx b/apps/web/app/(app)/smart-categories/page.tsx
index a1f4eb6113..8fa15869f6 100644
--- a/apps/web/app/(app)/smart-categories/page.tsx
+++ b/apps/web/app/(app)/smart-categories/page.tsx
@@ -100,10 +100,10 @@ export default async function CategoriesPage() {
{senders.length === 0 && (
- Categorize with AI
+ Categorize Senders
Now that you have some categories, our AI can categorize
- senders for you automatically.
+ senders.
diff --git a/apps/web/app/(app)/smart-categories/setup/SetUpCategories.tsx b/apps/web/app/(app)/smart-categories/setup/SetUpCategories.tsx
index cc716bfc86..a345025620 100644
--- a/apps/web/app/(app)/smart-categories/setup/SetUpCategories.tsx
+++ b/apps/web/app/(app)/smart-categories/setup/SetUpCategories.tsx
@@ -110,10 +110,10 @@ export function SetUpCategories({
<>
- Set up categories
+ Set up sender categories
- Automatically sort your emails by sender type to enable smart
- archiving and AI automation.
+ Automatically categorize senders for bulk archiving and AI
+ automation.
From 7d6befcac701d8bc11005ceb964defb4b4d84dee Mon Sep 17 00:00:00 2001
From: Eliezer Steinbock <3090527+elie222@users.noreply.github.com>
Date: Wed, 29 Jan 2025 21:43:59 +0200
Subject: [PATCH 22/28] Remove group from prompt to rules
---
apps/web/utils/ai/rule/prompt-to-rules.ts | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/apps/web/utils/ai/rule/prompt-to-rules.ts b/apps/web/utils/ai/rule/prompt-to-rules.ts
index 0b400afba5..19909114f5 100644
--- a/apps/web/utils/ai/rule/prompt-to-rules.ts
+++ b/apps/web/utils/ai/rule/prompt-to-rules.ts
@@ -63,7 +63,7 @@ ${promptFile}
`;
if (env.NODE_ENV === "development") {
- logger.trace("prompt-to-rules", {
+ logger.trace("Input", {
system,
prompt,
parameters: zodToJsonSchema(parameters),
@@ -88,7 +88,7 @@ ${promptFile}
rules: CreateOrUpdateRuleSchemaWithCategories[];
};
- logger.trace("Result", { rules });
+ logger.trace("Output", { rules });
return rules.map((rule) => ({
...rule,
@@ -127,7 +127,8 @@ If a rule can be handed without ai instructions, that's preferred, but often thi
"rules": [{
"name": "Label Newsletters",
"condition": {
- "group": "Newsletters"${
+ "aiInstructions": "Apply this rule to newsletters"
+ ${
hasSmartCategories
? `,
"categories": {
@@ -186,7 +187,7 @@ If a rule can be handed without ai instructions, that's preferred, but often thi
- Label all urgent emails from matt@company.com as "Urgent"
+ Label all urgent emails from company.com as "Urgent"
{
@@ -196,7 +197,7 @@ If a rule can be handed without ai instructions, that's preferred, but often thi
"conditionalOperator": "AND",
"aiInstructions": "Apply this rule to urgent emails",
"static": {
- "from": "matt@company.com"
+ "from": "@company.com"
}
},
"actions": [
From e14da21c56fc6801c17a3aaa9686b8f4cae2715d Mon Sep 17 00:00:00 2001
From: Eliezer Steinbock <3090527+elie222@users.noreply.github.com>
Date: Wed, 29 Jan 2025 21:53:37 +0200
Subject: [PATCH 23/28] adjust prompts
---
apps/web/utils/ai/assistant/process-user-request.ts | 7 +++----
apps/web/utils/ai/rule/prompt-to-rules.ts | 3 ++-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/apps/web/utils/ai/assistant/process-user-request.ts b/apps/web/utils/ai/assistant/process-user-request.ts
index 5f439b2ae4..c5647230d1 100644
--- a/apps/web/utils/ai/assistant/process-user-request.ts
+++ b/apps/web/utils/ai/assistant/process-user-request.ts
@@ -81,19 +81,18 @@ ${
When fixing rules:
- Make one precise change at a time
- Prefer minimal changes that solve the problem
-- Only add AI instructions if simpler conditions won't suffice
- Keep rules general and maintainable
Rule matching logic:
-- All static conditions (from, to, subject, body) use AND logic - meaning all conditions must match
+- All static conditions (from, to, subject, body) use AND logic - meaning all static conditions must match
- Top level conditions (AI instructions, static, category) can use either AND or OR logic, controlled by the conditionalOperator setting
Best practices:
- For static conditions, use email patterns (e.g., '@company.com') when matching multiple addresses
-- IMPORTANT: do not create new rules unless absolutely necessary and the user has asked for it.
+- IMPORTANT: do not create new rules unless absolutely necessary. Avoid duplicate rules, so make sure to check if the rule already exists.
Always end by using the reply tool to explain what changes were made.
-Include the updated rule in your reply so that the user understands what was changed.
+Include the updated rule in simple English in your reply so that the user understands what was changed.
Use simple language and avoid jargon in your reply.`;
const prompt = `${
diff --git a/apps/web/utils/ai/rule/prompt-to-rules.ts b/apps/web/utils/ai/rule/prompt-to-rules.ts
index 19909114f5..d10d0970c9 100644
--- a/apps/web/utils/ai/rule/prompt-to-rules.ts
+++ b/apps/web/utils/ai/rule/prompt-to-rules.ts
@@ -115,7 +115,8 @@ function getSystemPrompt({
IMPORTANT: If a user provides a snippet, use that full snippet in the rule. Don't include placeholders unless it's clear one is needed.
You can use multiple conditions in a rule, but aim for simplicity.
-If a rule can be handed without ai instructions, that's preferred, but often this won't be possible, so you can use the "aiInstructions" field.
+In most cases, you should use the "aiInstructions" and sometimes you will use other fields in addition.
+If a rule can be handled fully with static conditions, do so, but this is rarely possible.
From a86f1aca99b79afbb23d0b55e3611d20f353a240 Mon Sep 17 00:00:00 2001
From: Eliezer Steinbock <3090527+elie222@users.noreply.github.com>
Date: Wed, 29 Jan 2025 22:54:02 +0200
Subject: [PATCH 24/28] Add more to assistant prompt
---
apps/web/utils/ai/assistant/process-user-request.ts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/apps/web/utils/ai/assistant/process-user-request.ts b/apps/web/utils/ai/assistant/process-user-request.ts
index c5647230d1..92abc4a28d 100644
--- a/apps/web/utils/ai/assistant/process-user-request.ts
+++ b/apps/web/utils/ai/assistant/process-user-request.ts
@@ -90,6 +90,9 @@ Rule matching logic:
Best practices:
- For static conditions, use email patterns (e.g., '@company.com') when matching multiple addresses
- IMPORTANT: do not create new rules unless absolutely necessary. Avoid duplicate rules, so make sure to check if the rule already exists.
+- You can use multiple conditions in a rule, but aim for simplicity.
+- When creating rules, in most cases, you should use the "aiInstructions" and sometimes you will use other fields in addition.
+- If a rule can be handled fully with static conditions, do so, but this is rarely possible.
Always end by using the reply tool to explain what changes were made.
Include the updated rule in simple English in your reply so that the user understands what was changed.
From 45e3902787e366c9da9338219c3786118fa3c81c Mon Sep 17 00:00:00 2001
From: Eliezer Steinbock <3090527+elie222@users.noreply.github.com>
Date: Wed, 29 Jan 2025 23:12:46 +0200
Subject: [PATCH 25/28] Fix tests
---
apps/web/utils/ai/rule/create-prompt-from-rule.test.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/apps/web/utils/ai/rule/create-prompt-from-rule.test.ts b/apps/web/utils/ai/rule/create-prompt-from-rule.test.ts
index 5c7824372b..764197b73c 100644
--- a/apps/web/utils/ai/rule/create-prompt-from-rule.test.ts
+++ b/apps/web/utils/ai/rule/create-prompt-from-rule.test.ts
@@ -181,7 +181,7 @@ Alice`,
} as Rule & { actions: Action[]; group: Group };
expect(createPromptFromRule(rule)).toBe(
- 'For emails in group "Receipts", label as "Receipt" and archive',
+ 'For all emails, label as "Receipt" and archive',
);
});
@@ -193,7 +193,7 @@ Alice`,
} as Rule & { actions: Action[]; group: Group };
expect(createPromptFromRule(rule)).toBe(
- 'For emails with subject containing "order" and in group "Receipts", archive',
+ 'For emails with subject containing "order", archive',
);
});
@@ -206,7 +206,7 @@ Alice`,
} as Rule & { actions: Action[]; group: Group };
expect(createPromptFromRule(rule)).toBe(
- 'For emails with subject containing "order" or in group "Receipts", archive',
+ 'For emails with subject containing "order", archive',
);
});
});
From 0d3e1abc0e05a2de0ac512a46ba9f1e4f59ef2df Mon Sep 17 00:00:00 2001
From: Eliezer Steinbock <3090527+elie222@users.noreply.github.com>
Date: Wed, 29 Jan 2025 23:15:14 +0200
Subject: [PATCH 26/28] fix broken group logic
---
apps/web/utils/ai/choose-rule/match-rules.ts | 2 +-
apps/web/utils/ai/rule/create-prompt-from-rule.ts | 5 -----
2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/apps/web/utils/ai/choose-rule/match-rules.ts b/apps/web/utils/ai/choose-rule/match-rules.ts
index 4507a1c370..a60fc699fb 100644
--- a/apps/web/utils/ai/choose-rule/match-rules.ts
+++ b/apps/web/utils/ai/choose-rule/match-rules.ts
@@ -78,7 +78,7 @@ async function findPotentialMatchingRules({
// group - ignores conditional operator
// if a match is found, return it
- if (conditionTypes.GROUP) {
+ if (rule.groupId) {
const { matchingItem, group } = await matchesGroupRule(
rule,
await getGroups(rule.userId),
diff --git a/apps/web/utils/ai/rule/create-prompt-from-rule.ts b/apps/web/utils/ai/rule/create-prompt-from-rule.ts
index a13351c59e..39e0c17493 100644
--- a/apps/web/utils/ai/rule/create-prompt-from-rule.ts
+++ b/apps/web/utils/ai/rule/create-prompt-from-rule.ts
@@ -33,11 +33,6 @@ export function createPromptFromRule(rule: RuleWithRelations): string {
conditions.push(`with subject containing "${rule.subject}"`);
if (rule.body) conditions.push(`with body containing "${rule.body}"`);
- // // Add group if present
- // if (rule.group?.name) {
- // conditions.push(`in group "${rule.group.name}"`);
- // }
-
// Add category filters if present
if (rule.categoryFilters?.length) {
const categories = rule.categoryFilters.map((c) => c.name).join(", ");
From 580ba0bba4e9fabd9aa569de0c1ec390ac091c22 Mon Sep 17 00:00:00 2001
From: Eliezer Steinbock <3090527+elie222@users.noreply.github.com>
Date: Wed, 29 Jan 2025 23:16:31 +0200
Subject: [PATCH 27/28] Fix tests
---
apps/web/utils/ai/choose-rule/match-rules.test.ts | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/apps/web/utils/ai/choose-rule/match-rules.test.ts b/apps/web/utils/ai/choose-rule/match-rules.test.ts
index 7efd4c91b5..859b466d8f 100644
--- a/apps/web/utils/ai/choose-rule/match-rules.test.ts
+++ b/apps/web/utils/ai/choose-rule/match-rules.test.ts
@@ -169,9 +169,7 @@ describe("findMatchingRule", () => {
const result = await findMatchingRule(rules, message, user);
expect(result.rule?.id).toBe(rule.id);
- expect(result.reason).toBe(
- `Matched group item: "FROM: test@example.com", Matched category: "category"`,
- );
+ expect(result.reason).toBe(`Matched group item: "FROM: test@example.com"`);
});
it("matches a rule with multiple conditions AND (category and AI)", async () => {
@@ -236,7 +234,7 @@ describe("findMatchingRule", () => {
expect(aiChooseRule).toHaveBeenCalledOnce();
});
- it("doesn't match with only one of category or group", async () => {
+ it("should match with only one of category or group", async () => {
prisma.newsletter.findUnique.mockResolvedValue(
getNewsletter({ categoryId: "category1" }),
);
@@ -253,8 +251,8 @@ describe("findMatchingRule", () => {
const result = await findMatchingRule(rules, message, user);
- expect(result.rule?.id).toBeUndefined();
- expect(result.reason).toBeUndefined();
+ expect(result.rule?.id).toBe(rule.id);
+ expect(result.reason).toBe('Matched category: "category"');
});
it("matches with OR and one of category or group", async () => {
From 737128a6dda38077cc35e0267b9850c9c04c0e63 Mon Sep 17 00:00:00 2001
From: Eliezer Steinbock <3090527+elie222@users.noreply.github.com>
Date: Wed, 29 Jan 2025 23:18:40 +0200
Subject: [PATCH 28/28] fix turbo json
---
turbo.json | 3 +++
1 file changed, 3 insertions(+)
diff --git a/turbo.json b/turbo.json
index 22d95b074e..3f60a3c701 100644
--- a/turbo.json
+++ b/turbo.json
@@ -43,6 +43,9 @@
"ADMINS",
"WEBHOOK_URL",
"INTERNAL_API_KEY",
+ "USE_BACKUP_MODEL",
+ "WHITELIST_FROM",
+ "API_KEY_SALT",
"NEXT_PUBLIC_LEMON_STORE_ID",