feat: outlook ai search prompt (#1277)

# Add Outlook Search Assistant Support

## Description

Added support for Outlook search queries by implementing a new `OutlookSearchAssistantSystemPrompt` function that follows the Outlook search syntax. Modified the `generateSearchQuery` mutation to dynamically select the appropriate system prompt based on the provider ID (Google or Microsoft).

## Type of Change

- [x]  New feature

## Areas Affected

- [x] Email Integration
- [x] User Interface/Experience

## Testing Done

- [x] Manual testing performed

## Checklist

- [x] I have performed a self-review of my code
- [x] My changes generate no new warnings

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Added support for generating Outlook-compatible search queries based on user requests.
	- The search assistant now adapts queries for either Gmail or Outlook, depending on the connected provider.

- **Improvements**
	- Enhanced search functionality to better interpret informal, vague, or multilingual email search requests for both Gmail and Outlook users.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Ahmet Kilinc
2025-06-10 21:40:24 +01:00
committed by GitHub
parent 985f04f14b
commit 656bd46ce0
2 changed files with 53 additions and 3 deletions

View File

@@ -267,6 +267,43 @@ export const GmailSearchAssistantSystemPrompt = () =>
`;
export const OutlookSearchAssistantSystemPrompt = () =>
dedent`
<SystemPrompt>
<Role>You are a Outlook Search Query Builder AI.</Role>
<Task>Convert any informal, vague, or multilingual email search request into an accurate Outlook search bar query.</Task>
<current_date>${getCurrentDateContext()}</current_date>
<Guidelines>
<Guideline id="1">
Understand Intent: Infer the user's meaning from casual, ambiguous, or non-standard phrasing and extract people, topics, dates, attachments, labels.
</Guideline>
<Guideline id="2">
Multilingual Support: Recognize queries in any language, map foreign terms (e.g. adjunto, 附件, pièce jointe) to English operators, and translate date expressions across languages.
</Guideline>
<Guideline id="3">
Use Outlook Syntax: Employ operators like <code>from:</code>, <code>to:</code>, <code>cc:</code>, <code>bcc:</code>, <code>subject:</code>, <code>category:</code>, <code>hasattachment:yes</code>, <code>hasattachment:no</code>, <code>attachments:</code>, <code>received:</code>, <code>sent:</code>, <code>messagesize:</code>, <code>hasflag:true</code>, <code>read:no</code>, and body text searches. Combine fields with implicit AND and group alternatives with <code>OR</code> in parentheses. Use <code>NOT</code> for exclusions. Date formats should use MM/DD/YYYY or relative terms like "yesterday", "last week", "this month".
</Guideline>
<Guideline id="4">
Maximize Recall: For vague terms, expand with synonyms and related keywords joined by <code>OR</code> (e.g. <code>(report OR summary)</code>, <code>(picture OR photo OR image OR filename:jpg)</code>) to cover edge cases.
</Guideline>
<Guideline id="5">
Date Interpretation: Translate relative dates ("yesterday," "last week," "mañana") into precise <code>after:</code>/<code>before:</code> or <code>newer_than:</code>/<code>older_than:</code> filters using YYYY/MM/DD or relative units.
</Guideline>
<Guideline id="6">
Body and Content Search: By default, unqualified terms or the <code>intext:</code> operator search email bodies and snippets. Use <code>intext:</code> for explicit body-only searches when the user's keywords refer to message content rather than headers.
</Guideline>
<Guideline id="7">
When asked to search for plural of a word, use the <code>OR</code> operator to search for the singular form of the word, example: "referrals" should also be searched as "referral", example: "rewards" should also be searched as "reward", example: "comissions" should also be searched as "commission".
</Guideline>
<Guideline id="8">
When asked to search always use the <code>OR</code> operator to search for related terms, example: "emails from canva" should also be searched as "from:canva.com OR from:canva OR canva".
</Guideline>
</Guidelines>
<OutputFormat>Return only the final Outlook search query string, with no additional text, explanations, or formatting.</OutputFormat>
</SystemPrompt>
`;
export const AiChatPrompt = (threadId: string, currentFolder: string, currentFilter: string) =>
dedent`
<system>

View File

@@ -1,4 +1,7 @@
import { GmailSearchAssistantSystemPrompt } from '../../../lib/prompts';
import {
GmailSearchAssistantSystemPrompt,
OutlookSearchAssistantSystemPrompt,
} from '../../../lib/prompts';
import { activeDriverProcedure } from '../../trpc';
import { openai } from '@ai-sdk/openai';
import { generateObject } from 'ai';
@@ -6,10 +9,20 @@ import { z } from 'zod';
export const generateSearchQuery = activeDriverProcedure
.input(z.object({ query: z.string() }))
.mutation(async ({ input }) => {
.mutation(async ({ input, ctx }) => {
const {
activeConnection: { providerId },
} = ctx;
const systemPrompt =
providerId === 'google'
? GmailSearchAssistantSystemPrompt()
: providerId === 'microsoft'
? OutlookSearchAssistantSystemPrompt()
: '';
const result = await generateObject({
model: openai('gpt-4o'),
system: GmailSearchAssistantSystemPrompt(),
system: systemPrompt,
prompt: input.query,
schema: z.object({
query: z.string(),