Skip to content

Commit ec52481

Browse files
author
Shaurya Singh
committed
fix: Use gpt-4o-mini & update email to light theme matching platform
1 parent f83892a commit ec52481

File tree

2 files changed

+49
-51
lines changed

2 files changed

+49
-51
lines changed

src/ai/client.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ export function getOpenAIClient(): OpenAI {
1515

1616
export interface AIGenerationOptions {
1717
model?: string;
18-
temperature?: number;
1918
maxTokens?: number;
2019
}
2120

@@ -29,16 +28,14 @@ export async function generateText(
2928
const client = getOpenAIClient();
3029

3130
const {
32-
model = 'gpt-4-turbo',
33-
temperature = 0.7,
31+
model = 'gpt-4o-mini',
3432
maxTokens = 4000,
3533
} = options;
3634

3735
const result = await withRetry(
3836
async () => {
3937
const completion = await client.chat.completions.create({
4038
model,
41-
temperature,
4239
max_tokens: maxTokens,
4340
messages: [
4441
{

src/notifications/templates/weekly-brief.ts

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ export interface WeeklyBriefData {
77
tldr: string[];
88
riskyChanges: string[];
99
suggestedActions: string[];
10-
schedule: 'weekly' | 'biweekly';
10+
schedule: 'weekly' | 'biweekly' | 'manual';
1111
}
1212

1313
/**
1414
* Builds the HTML email for weekly/biweekly maintainer brief
15+
* Light theme matching the RepoMind platform UI
1516
*/
1617
export function buildWeeklyBriefEmail(data: WeeklyBriefData): { subject: string; html: string } {
1718
const frontendUrl = config.FRONTEND_URL;
@@ -29,25 +30,30 @@ export function buildWeeklyBriefEmail(data: WeeklyBriefData): { subject: string;
2930
<meta name="viewport" content="width=device-width, initial-scale=1.0">
3031
<title>${subject}</title>
3132
</head>
32-
<body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #0a0a0a; color: #fafafa;">
33-
<table width="100%" cellpadding="0" cellspacing="0" style="background-color: #0a0a0a; padding: 40px 20px;">
33+
<body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #f8fafc; color: #1e293b;">
34+
<table width="100%" cellpadding="0" cellspacing="0" style="background-color: #f8fafc; padding: 40px 20px;">
3435
<tr>
3536
<td align="center">
36-
<table width="100%" cellpadding="0" cellspacing="0" style="max-width: 600px; background-color: #111111; border-radius: 16px; border: 1px solid #262626; overflow: hidden;">
37+
<table width="100%" cellpadding="0" cellspacing="0" style="max-width: 600px; background-color: #ffffff; border-radius: 16px; border: 1px solid #e2e8f0; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05); overflow: hidden;">
3738
3839
<!-- Header -->
3940
<tr>
40-
<td style="padding: 32px 32px 24px 32px; border-bottom: 1px solid #262626;">
41+
<td style="padding: 32px 32px 24px 32px; border-bottom: 1px solid #e2e8f0;">
4142
<table width="100%" cellpadding="0" cellspacing="0">
4243
<tr>
4344
<td>
44-
<div style="font-size: 24px; font-weight: 700; color: #fafafa; margin-bottom: 8px;">
45-
📋 ${frequency} Brief
45+
<div style="display: flex; align-items: center; gap: 12px; margin-bottom: 16px;">
46+
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); border-radius: 12px; display: inline-flex; align-items: center; justify-content: center;">
47+
<span style="font-size: 24px;">📋</span>
48+
</div>
4649
</div>
47-
<div style="font-size: 16px; color: #a1a1aa;">
50+
<div style="font-size: 24px; font-weight: 700; color: #1e293b; margin-bottom: 8px;">
51+
${frequency} Brief
52+
</div>
53+
<div style="font-size: 16px; color: #475569; font-weight: 500;">
4854
${data.repoFullName}
4955
</div>
50-
<div style="font-size: 14px; color: #71717a; margin-top: 4px;">
56+
<div style="font-size: 14px; color: #94a3b8; margin-top: 4px;">
5157
${data.date}
5258
</div>
5359
</td>
@@ -59,14 +65,14 @@ export function buildWeeklyBriefEmail(data: WeeklyBriefData): { subject: string;
5965
<!-- TL;DR Section -->
6066
<tr>
6167
<td style="padding: 24px 32px;">
62-
<div style="font-size: 14px; font-weight: 600; color: #a78bfa; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 16px;">
68+
<div style="font-size: 12px; font-weight: 700; color: #6366f1; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 16px;">
6369
TL;DR
6470
</div>
6571
<table width="100%" cellpadding="0" cellspacing="0">
6672
${data.tldr.map(item => `
6773
<tr>
68-
<td style="padding: 8px 0; color: #e4e4e7; font-size: 15px; line-height: 1.6;">
69-
<span style="color: #a78bfa; margin-right: 8px;">•</span>
74+
<td style="padding: 10px 0; color: #334155; font-size: 15px; line-height: 1.6;">
75+
<span style="color: #6366f1; margin-right: 10px; font-weight: 600;">•</span>
7076
${escapeHtml(item)}
7177
</td>
7278
</tr>
@@ -79,14 +85,14 @@ export function buildWeeklyBriefEmail(data: WeeklyBriefData): { subject: string;
7985
<!-- Risky Changes Section -->
8086
<tr>
8187
<td style="padding: 0 32px 24px 32px;">
82-
<div style="background-color: rgba(239, 68, 68, 0.1); border: 1px solid rgba(239, 68, 68, 0.2); border-radius: 12px; padding: 20px;">
83-
<div style="font-size: 14px; font-weight: 600; color: #ef4444; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px;">
88+
<div style="background-color: #fef2f2; border: 1px solid #fecaca; border-radius: 12px; padding: 20px;">
89+
<div style="font-size: 12px; font-weight: 700; color: #dc2626; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 12px;">
8490
⚠️ Risky Changes
8591
</div>
8692
<table width="100%" cellpadding="0" cellspacing="0">
8793
${data.riskyChanges.map(item => `
8894
<tr>
89-
<td style="padding: 6px 0; color: #fca5a5; font-size: 14px; line-height: 1.5;">
95+
<td style="padding: 8px 0; color: #991b1b; font-size: 14px; line-height: 1.5;">
9096
${escapeHtml(item)}
9197
</td>
9298
</tr>
@@ -101,14 +107,14 @@ export function buildWeeklyBriefEmail(data: WeeklyBriefData): { subject: string;
101107
<!-- Suggested Actions Section -->
102108
<tr>
103109
<td style="padding: 0 32px 24px 32px;">
104-
<div style="font-size: 14px; font-weight: 600; color: #22c55e; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px;">
110+
<div style="font-size: 12px; font-weight: 700; color: #16a34a; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 16px;">
105111
✅ Suggested Actions
106112
</div>
107113
<table width="100%" cellpadding="0" cellspacing="0">
108114
${data.suggestedActions.slice(0, 3).map((item, idx) => `
109115
<tr>
110-
<td style="padding: 8px 0; color: #e4e4e7; font-size: 14px; line-height: 1.5;">
111-
<span style="display: inline-block; width: 24px; height: 24px; background-color: #262626; border-radius: 50%; text-align: center; line-height: 24px; font-size: 12px; font-weight: 600; color: #a1a1aa; margin-right: 12px;">${idx + 1}</span>
116+
<td style="padding: 10px 0; color: #334155; font-size: 14px; line-height: 1.5;">
117+
<span style="display: inline-block; width: 26px; height: 26px; background-color: #f1f5f9; border-radius: 50%; text-align: center; line-height: 26px; font-size: 13px; font-weight: 600; color: #64748b; margin-right: 12px;">${idx + 1}</span>
112118
${escapeHtml(item)}
113119
</td>
114120
</tr>
@@ -123,13 +129,13 @@ export function buildWeeklyBriefEmail(data: WeeklyBriefData): { subject: string;
123129
<td style="padding: 8px 32px 32px 32px;">
124130
<table width="100%" cellpadding="0" cellspacing="0">
125131
<tr>
126-
<td style="padding-right: 8px;">
127-
<a href="${briefUrl}" style="display: block; text-align: center; padding: 14px 24px; background: linear-gradient(135deg, #a78bfa 0%, #8b5cf6 100%); color: #ffffff; text-decoration: none; border-radius: 10px; font-weight: 600; font-size: 14px;">
132+
<td style="padding-right: 8px; width: 50%;">
133+
<a href="${briefUrl}" style="display: block; text-align: center; padding: 14px 24px; background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); color: #ffffff; text-decoration: none; border-radius: 10px; font-weight: 600; font-size: 14px;">
128134
View Full Brief
129135
</a>
130136
</td>
131-
<td style="padding-left: 8px;">
132-
<a href="${briefUrl}?tab=issues" style="display: block; text-align: center; padding: 14px 24px; background-color: #262626; color: #fafafa; text-decoration: none; border-radius: 10px; font-weight: 600; font-size: 14px; border: 1px solid #3f3f46;">
137+
<td style="padding-left: 8px; width: 50%;">
138+
<a href="${briefUrl}?tab=issues" style="display: block; text-align: center; padding: 14px 24px; background-color: #f1f5f9; color: #334155; text-decoration: none; border-radius: 10px; font-weight: 600; font-size: 14px; border: 1px solid #e2e8f0;">
133139
Good First Issues
134140
</a>
135141
</td>
@@ -140,11 +146,11 @@ export function buildWeeklyBriefEmail(data: WeeklyBriefData): { subject: string;
140146
141147
<!-- Footer -->
142148
<tr>
143-
<td style="padding: 24px 32px; border-top: 1px solid #262626; background-color: #0a0a0a;">
144-
<div style="font-size: 13px; color: #71717a; line-height: 1.6;">
145-
You're receiving this because you enabled ${data.schedule} delivery for <strong style="color: #a1a1aa;">${data.repoFullName}</strong>.
149+
<td style="padding: 24px 32px; border-top: 1px solid #e2e8f0; background-color: #f8fafc;">
150+
<div style="font-size: 13px; color: #64748b; line-height: 1.6;">
151+
You're receiving this because you enabled ${data.schedule} delivery for <strong style="color: #475569;">${data.repoFullName}</strong>.
146152
<br>
147-
<a href="${settingsUrl}" style="color: #a78bfa; text-decoration: none;">Manage notification settings →</a>
153+
<a href="${settingsUrl}" style="color: #6366f1; text-decoration: none; font-weight: 500;">Manage notification settings →</a>
148154
</div>
149155
</td>
150156
</tr>
@@ -155,8 +161,8 @@ export function buildWeeklyBriefEmail(data: WeeklyBriefData): { subject: string;
155161
<table width="100%" cellpadding="0" cellspacing="0" style="max-width: 600px; margin-top: 24px;">
156162
<tr>
157163
<td align="center">
158-
<div style="font-size: 14px; color: #52525b;">
159-
Powered by <strong style="color: #a78bfa;">RepoMind</strong>
164+
<div style="font-size: 14px; color: #94a3b8;">
165+
Powered by <strong style="color: #6366f1;">RepoMind</strong>
160166
</div>
161167
</td>
162168
</tr>
@@ -187,34 +193,30 @@ function escapeHtml(text: string): string {
187193
* Extracts TL;DR bullets from maintainer brief markdown
188194
*/
189195
export function extractTldr(markdown: string): string[] {
190-
// Look for the Summary section
191-
const summaryMatch = markdown.match(/##\s*Summary\s*\n([\s\S]*?)(?=\n##|\n#|$)/i);
192-
if (!summaryMatch) {
193-
// Fallback: try to find any bullet points at the start
194-
const bullets = markdown.match(/^[\s]*[-*]\s*(.+)$/gm);
196+
// Look for TL;DR or Summary section
197+
const tldrMatch = markdown.match(/##\s*(?:TL;DR|Summary|Overview)\s*\n([\s\S]*?)(?=\n##|\n#|$)/i);
198+
if (tldrMatch) {
199+
const content = tldrMatch[1];
200+
const bullets = content.match(/[-*]\s*(.+)/g);
195201
if (bullets) {
196-
return bullets.slice(0, 5).map(b => b.replace(/^[\s]*[-*]\s*/, '').trim());
202+
return bullets.slice(0, 5).map(b => b.replace(/^[-*]\s*/, '').trim());
197203
}
198-
return ['Analysis complete. View the full brief for details.'];
199204
}
200-
201-
const summaryContent = summaryMatch[1];
202-
const bullets = summaryContent.match(/[-*]\s*(.+)/g);
203205

204-
if (!bullets) {
205-
// If no bullets, take first few sentences
206-
const sentences = summaryContent.split(/[.!?]+/).filter(s => s.trim());
207-
return sentences.slice(0, 5).map(s => s.trim());
206+
// Fallback: try to find any bullet points at the start
207+
const bullets = markdown.match(/^[\s]*[-*]\s*(.+)$/gm);
208+
if (bullets) {
209+
return bullets.slice(0, 5).map(b => b.replace(/^[\s]*[-*]\s*/, '').trim());
208210
}
209-
210-
return bullets.slice(0, 5).map(b => b.replace(/^[-*]\s*/, '').trim());
211+
212+
return ['Analysis complete. View the full brief for details.'];
211213
}
212214

213215
/**
214216
* Extracts risky changes from maintainer brief markdown
215217
*/
216218
export function extractRiskyChanges(markdown: string): string[] {
217-
const riskyMatch = markdown.match(/##\s*Risky Changes\s*\n([\s\S]*?)(?=\n##|\n#|$)/i);
219+
const riskyMatch = markdown.match(/##\s*(?:Risky Changes|Risk|Risks|Concerns)\s*\n([\s\S]*?)(?=\n##|\n#|$)/i);
218220
if (!riskyMatch) return [];
219221

220222
const content = riskyMatch[1];
@@ -229,7 +231,7 @@ export function extractRiskyChanges(markdown: string): string[] {
229231
* Extracts suggested actions from maintainer brief markdown
230232
*/
231233
export function extractSuggestedActions(markdown: string): string[] {
232-
const actionsMatch = markdown.match(/##\s*Suggested Actions\s*\n([\s\S]*?)(?=\n##|\n#|$)/i);
234+
const actionsMatch = markdown.match(/##\s*(?:Suggested Actions|Actions|Recommendations|Next Steps)\s*\n([\s\S]*?)(?=\n##|\n#|$)/i);
233235
if (!actionsMatch) return [];
234236

235237
const content = actionsMatch[1];
@@ -240,4 +242,3 @@ export function extractSuggestedActions(markdown: string): string[] {
240242

241243
return items.slice(0, 3).map(item => item.replace(/^(?:\d+\.\s*|[-*]\s*)/, '').trim());
242244
}
243-

0 commit comments

Comments
 (0)