Skip to content

Commit 364e90b

Browse files
authored
Remove console logs and simplify AI chat prompt (#1769)
# Cleanup: Remove console logs and refactor AI chat prompt ## Description This PR removes unnecessary console logs from the codebase and refactors the AI chat prompt to be more concise and structured. The changes include: 1. Removing debug console.log statements from notification settings and hot key handling 2. Adding error handling to the AI sidebar component 3. Streamlining the AI chat prompt structure for better readability and maintenance 4. Improving the inboxRag function with better error handling and logging ## Type of Change - 🐛 Bug fix (non-breaking change which fixes an issue) - ⚡ Performance improvement ## Areas Affected - [x] User Interface/Experience - [x] API Endpoints ## Testing Done - [x] Manual testing performed ## Checklist - [x] I have performed a self-review of my code - [x] My changes generate no new warnings - [x] All tests pass locally ## Additional Notes The AI chat prompt refactoring significantly improves readability while maintaining the same functionality. The removal of console logs helps keep the browser console clean in production. --- _By submitting this pull request, I confirm that my contribution is made under the terms of the project's license._ <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Enhanced email search with improved AI-generated query refinement for more accurate results. * **Bug Fixes** * Improved error handling and fallback messaging during AI-powered searches to prevent disruptions. * **Refactor** * Streamlined and restructured the AI assistant’s internal prompt for clearer, more direct responses and safer actions. * Refined tool orchestration for chat streaming to improve reliability. * **Chores** * Removed unused tools and related features to simplify the system. * Eliminated unnecessary console logging for cleaner operation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent bf2c8f3 commit 364e90b

File tree

8 files changed

+216
-523
lines changed

8 files changed

+216
-523
lines changed

apps/mail/app/(routes)/settings/notifications/page.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import {
1515
} from '@/components/ui/select';
1616
import { SettingsCard } from '@/components/settings/settings-card';
1717
import { zodResolver } from '@hookform/resolvers/zod';
18-
import { Button } from '@/components/ui/button';
1918
import { Switch } from '@/components/ui/switch';
19+
import { Button } from '@/components/ui/button';
2020
import { useForm } from 'react-hook-form';
2121
import { Bell } from 'lucide-react';
2222
import { useState } from 'react';
@@ -41,7 +41,6 @@ export default function NotificationsPage() {
4141
function onSubmit(values: z.infer<typeof formSchema>) {
4242
setIsSaving(true);
4343
setTimeout(() => {
44-
console.log(values);
4544
setIsSaving(false);
4645
}, 1000);
4746
}

apps/mail/components/ui/ai-sidebar.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ function AISidebar({ className }: AISidebarProps) {
349349
agent: 'ZeroAgent',
350350
name: activeConnection?.id ? String(activeConnection.id) : 'general',
351351
host: `${import.meta.env.VITE_PUBLIC_BACKEND_URL}`,
352+
onError: (e) => console.log(e),
352353
});
353354

354355
const chatState = useAgentChat({

apps/mail/hooks/use-hot-key.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,49 +9,44 @@ function initKeyListeners() {
99
window.addEventListener('keydown', (e) => {
1010
// Store the key state
1111
keyStates.set(e.key, true);
12-
12+
1313
// Also store specific states for modifier keys
1414
if (e.altKey) {
1515
keyStates.set('Alt', true);
1616
keyStates.set('AltLeft', true);
1717
keyStates.set('AltRight', true);
1818
}
19-
19+
2020
if (e.shiftKey) {
2121
keyStates.set('Shift', true);
2222
keyStates.set('ShiftLeft', true);
2323
keyStates.set('ShiftRight', true);
2424
}
25-
26-
console.log('Key down:', e.key, 'Alt:', e.altKey, 'Shift:', e.shiftKey);
2725
});
2826

2927
window.addEventListener('keyup', (e) => {
3028
// Clear the key state
3129
keyStates.set(e.key, false);
32-
30+
3331
// Also clear specific states for modifier keys
3432
if (e.key === 'Alt' || e.key === 'AltLeft' || e.key === 'AltRight') {
3533
keyStates.set('Alt', false);
3634
keyStates.set('AltLeft', false);
3735
keyStates.set('AltRight', false);
3836
}
39-
37+
4038
if (e.key === 'Shift' || e.key === 'ShiftLeft' || e.key === 'ShiftRight') {
4139
keyStates.set('Shift', false);
4240
keyStates.set('ShiftLeft', false);
4341
keyStates.set('ShiftRight', false);
4442
}
45-
46-
console.log('Key up:', e.key);
4743
});
4844

4945
window.addEventListener('blur', () => {
5046
// Clear all key states when window loses focus
5147
keyStates.forEach((_, key) => {
5248
keyStates.set(key, false);
5349
});
54-
console.log('Window blur - all keys reset');
5550
});
5651

5752
listenersInit = true;

apps/server/src/lib/prompts.ts

Lines changed: 149 additions & 434 deletions
Large diffs are not rendered by default.

apps/server/src/routes/agent/index.ts

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
createDataStreamResponse,
2020
streamText,
2121
appendResponseMessages,
22+
generateText,
2223
} from 'ai';
2324
import {
2425
IncomingMessageType,
@@ -27,6 +28,7 @@ import {
2728
type OutgoingMessage,
2829
} from './types';
2930
import { DurableObjectOAuthClientProvider } from 'agents/mcp/do-oauth-client-provider';
31+
import { AiChatPrompt, GmailSearchAssistantSystemPrompt } from '../../lib/prompts';
3032
import { EPrompts, type IOutgoingMessage, type ParsedMessage } from '../../types';
3133
import type { MailManager, IGetThreadResponse } from '../../lib/driver/types';
3234
import { connectionToDriver } from '../../lib/server-utils';
@@ -35,7 +37,6 @@ import { withRetry } from '../../lib/gmail-rate-limit';
3537
import { getPrompt } from '../../pipelines.effect';
3638
import { AIChatAgent } from 'agents/ai-chat-agent';
3739
import { ToolOrchestrator } from './orchestrator';
38-
import { AiChatPrompt } from '../../lib/prompts';
3940
import { getPromptName } from '../../pipelines';
4041
import { anthropic } from '@ai-sdk/anthropic';
4142
import { connection } from '../../db/schema';
@@ -44,6 +45,7 @@ import { tools as authTools } from './tools';
4445
import { processToolCalls } from './utils';
4546
import { env } from 'cloudflare:workers';
4647
import type { Connection } from 'agents';
48+
import { openai } from '@ai-sdk/openai';
4749
import { createDb } from '../../db';
4850
import { DriverRpcDO } from './rpc';
4951
import { eq } from 'drizzle-orm';
@@ -493,22 +495,48 @@ export class ZeroDriver extends AIChatAgent<typeof env> {
493495
}
494496

495497
async inboxRag(query: string) {
496-
if (!env.AUTORAG_ID) return { result: 'Not enabled', data: [] };
497-
const answer = await env.AI.autorag(env.AUTORAG_ID).aiSearch({
498-
query: query,
499-
// rewrite_query: true,
500-
max_num_results: 3,
501-
ranking_options: {
498+
if (!env.AUTORAG_ID) {
499+
console.warn('[inboxRag] AUTORAG_ID not configured - RAG search disabled');
500+
return { result: 'Not enabled', data: [] };
501+
}
502+
503+
try {
504+
const startTime = Date.now();
505+
console.log(`[inboxRag] Executing AI search with parameters:`, {
506+
query,
507+
max_num_results: 3,
502508
score_threshold: 0.3,
503-
},
504-
// stream: true,
505-
filters: {
506-
type: 'eq',
507-
key: 'folder',
508-
value: `${this.name}/`,
509-
},
510-
});
511-
return { result: answer.response, data: answer.data };
509+
folder_filter: `${this.name}/`,
510+
});
511+
512+
const answer = await env.AI.autorag(env.AUTORAG_ID).aiSearch({
513+
query: query,
514+
// rewrite_query: true,
515+
max_num_results: 3,
516+
ranking_options: {
517+
score_threshold: 0.3,
518+
},
519+
// stream: true,
520+
filters: {
521+
type: 'eq',
522+
key: 'folder',
523+
value: `${this.name}/`,
524+
},
525+
});
526+
527+
const duration = Date.now() - startTime;
528+
529+
return { result: answer.response, data: answer.data };
530+
} catch (error) {
531+
console.error(`[inboxRag] Search failed for query: "${query}"`, {
532+
error: error instanceof Error ? error.message : 'Unknown error',
533+
stack: error instanceof Error ? error.stack : undefined,
534+
user: this.name,
535+
});
536+
537+
// Return empty result on error to prevent breaking the flow
538+
return { result: 'Search failed', data: [] };
539+
}
512540
}
513541

514542
async searchThreads(params: {
@@ -532,10 +560,20 @@ export class ZeroDriver extends AIChatAgent<typeof env> {
532560
}),
533561
).pipe(Effect.catchAll(() => Effect.succeed([])));
534562

563+
const genQueryEffect = Effect.tryPromise(() =>
564+
generateText({
565+
model: openai(env.OPENAI_MODEL || 'gpt-4o'),
566+
system: GmailSearchAssistantSystemPrompt(),
567+
prompt: params.query,
568+
}).then((response) => response.text),
569+
).pipe(Effect.catchAll(() => Effect.succeed(query)));
570+
571+
const genQueryResult = await Effect.runPromise(genQueryEffect);
572+
535573
const rawEffect = Effect.tryPromise(() =>
536574
this.driver!.list({
537575
folder,
538-
query,
576+
query: genQueryResult,
539577
labelIds,
540578
maxResults,
541579
pageToken,
@@ -847,7 +885,7 @@ export class ZeroAgent extends AIChatAgent<typeof env> {
847885
const rawTools = {
848886
...(await authTools(connectionId)),
849887
};
850-
const tools = orchestrator.processTools({});
888+
const tools = orchestrator.processTools(rawTools);
851889
const processedMessages = await processToolCalls(
852890
{
853891
messages: this.messages,
@@ -861,7 +899,7 @@ export class ZeroAgent extends AIChatAgent<typeof env> {
861899
model: anthropic(env.OPENAI_MODEL || 'claude-3-5-haiku-latest'),
862900
maxSteps: 10,
863901
messages: processedMessages,
864-
tools: rawTools,
902+
tools,
865903
onFinish,
866904
onError: (error) => {
867905
console.error('Error in streamText', error);

apps/server/src/routes/agent/mcp.ts

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@
1414
* Reuse or distribution of this file requires a license from Zero Email Inc.
1515
*/
1616

17-
import { GmailSearchAssistantSystemPrompt, getCurrentDateContext } from '../../lib/prompts';
1817
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
18+
import { getCurrentDateContext } from '../../lib/prompts';
1919
import { getZeroAgent } from '../../lib/server-utils';
20-
import { anthropic } from '@ai-sdk/anthropic';
2120
import { connection } from '../../db/schema';
2221
import { FOLDERS } from '../../lib/utils';
2322
import { env } from 'cloudflare:workers';
@@ -118,31 +117,6 @@ export class ZeroMCP extends McpAgent<typeof env, Record<string, unknown>, { use
118117
},
119118
);
120119

121-
this.server.registerTool(
122-
'buildGmailSearchQuery',
123-
{
124-
description: 'Build Gmail search query using AI assistance',
125-
inputSchema: {
126-
query: z.string(),
127-
},
128-
},
129-
async (s) => {
130-
const result = await generateText({
131-
model: anthropic(env.OPENAI_MODEL || 'claude-3-5-haiku-latest'),
132-
system: GmailSearchAssistantSystemPrompt(),
133-
prompt: s.query,
134-
});
135-
return {
136-
content: [
137-
{
138-
type: 'text',
139-
text: result.text,
140-
},
141-
],
142-
};
143-
},
144-
);
145-
146120
const agent = await getZeroAgent(_connection.id);
147121

148122
this.server.registerTool(

apps/server/src/routes/agent/tools.ts

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ import { composeEmail } from '../../trpc/routes/ai/compose';
22
import { perplexity } from '@ai-sdk/perplexity';
33
import { generateText, tool } from 'ai';
44

5-
import { colors, GmailSearchAssistantSystemPrompt } from '../../lib/prompts';
65
import { getZeroAgent } from '../../lib/server-utils';
7-
import { anthropic } from '@ai-sdk/anthropic';
6+
import { colors } from '../../lib/prompts';
87
import { env } from 'cloudflare:workers';
98
import { Tools } from '../../types';
109
import { z } from 'zod';
@@ -186,18 +185,6 @@ const markAsRead = (connectionId: string) =>
186185
},
187186
});
188187

189-
// const inboxRag = (connectionId: string, dataStream?: DataStreamWriter) =>
190-
// tool({
191-
// description: 'Search the inbox for emails',
192-
// parameters: z.object({
193-
// query: z.string().describe('The query to search the inbox for'),
194-
// }),
195-
// execute: async ({ query }) => {
196-
// console.log('inboxRag', query);
197-
// return await agent.inboxRag(query, dataStream);
198-
// },
199-
// });
200-
201188
const markAsUnread = (connectionId: string) =>
202189
tool({
203190
description: 'Mark emails as unread',
@@ -390,22 +377,6 @@ export const webSearch = () =>
390377
},
391378
});
392379

393-
const buildGmailSearchQuery = () =>
394-
tool({
395-
description: 'Build Gmail search query using AI assistance',
396-
parameters: z.object({
397-
query: z.string(),
398-
}),
399-
execute: async ({ query }) => {
400-
const result = await generateText({
401-
model: anthropic(env.OPENAI_MODEL || 'claude-3-5-haiku-latest'),
402-
system: GmailSearchAssistantSystemPrompt(),
403-
prompt: query,
404-
});
405-
return result.text;
406-
},
407-
});
408-
409380
export const tools = async (connectionId: string) => {
410381
return {
411382
[Tools.GetThread]: getEmail(),
@@ -425,7 +396,6 @@ export const tools = async (connectionId: string) => {
425396
query: z.string().describe('The query to search the web for'),
426397
}),
427398
}),
428-
[Tools.BuildGmailSearchQuery]: buildGmailSearchQuery(),
429399
[Tools.InboxRag]: tool({
430400
description:
431401
'Search the inbox for emails using natural language. Returns only an array of threadIds.',

apps/server/src/trpc/routes/ai/search.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import {
33
OutlookSearchAssistantSystemPrompt,
44
} from '../../../lib/prompts';
55
import { activeDriverProcedure } from '../../trpc';
6+
import { env } from 'cloudflare:workers';
67
import { openai } from '@ai-sdk/openai';
78
import { generateObject } from 'ai';
8-
import { env } from 'cloudflare:workers';
99
import { z } from 'zod';
1010

1111
export const generateSearchQuery = activeDriverProcedure
@@ -28,6 +28,7 @@ export const generateSearchQuery = activeDriverProcedure
2828
schema: z.object({
2929
query: z.string(),
3030
}),
31+
output: 'object',
3132
});
3233

3334
return result.object;

0 commit comments

Comments
 (0)