Skip to content

Commit c42d2a3

Browse files
icecrasher321Sg312waleedlatif1greptile-apps[bot]
authored
feat(copilot): fix context / json parsing edge cases (#1542)
* Add get ops examples * input format incorrectly created by copilot should not crash workflow * fix tool edits triggering overall delta * fix(db): add more options for SSL connection, add envvar for base64 db cert (#1533) * fix trigger additions * fix nested outputs for triggers * add condition subblock sanitization * fix custom tools json * Model selector * fix response format sanitization * remove dead code * fix export sanitization * Update migration * fix import race cond * Copilot settings * fix response format * stop loops/parallels copilot generation from breaking diff view * fix lint * Apply suggestion from @greptile-apps[bot] Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix tests * fix lint --------- Co-authored-by: Siddharth Ganesan <[email protected]> Co-authored-by: Waleed <[email protected]> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
1 parent 4da355d commit c42d2a3

File tree

23 files changed

+8301
-451
lines changed

23 files changed

+8301
-451
lines changed

apps/sim/app/api/copilot/chat/route.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ describe('Copilot Chat API Route', () => {
233233
model: 'claude-4.5-sonnet',
234234
mode: 'agent',
235235
messageId: 'mock-uuid-1234-5678',
236-
version: '1.0.0',
236+
version: '1.0.1',
237237
chatId: 'chat-123',
238238
}),
239239
})
@@ -303,7 +303,7 @@ describe('Copilot Chat API Route', () => {
303303
model: 'claude-4.5-sonnet',
304304
mode: 'agent',
305305
messageId: 'mock-uuid-1234-5678',
306-
version: '1.0.0',
306+
version: '1.0.1',
307307
chatId: 'chat-123',
308308
}),
309309
})
@@ -361,7 +361,7 @@ describe('Copilot Chat API Route', () => {
361361
model: 'claude-4.5-sonnet',
362362
mode: 'agent',
363363
messageId: 'mock-uuid-1234-5678',
364-
version: '1.0.0',
364+
version: '1.0.1',
365365
chatId: 'chat-123',
366366
}),
367367
})
@@ -453,7 +453,7 @@ describe('Copilot Chat API Route', () => {
453453
model: 'claude-4.5-sonnet',
454454
mode: 'ask',
455455
messageId: 'mock-uuid-1234-5678',
456-
version: '1.0.0',
456+
version: '1.0.1',
457457
chatId: 'chat-123',
458458
}),
459459
})
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import { eq } from 'drizzle-orm'
2+
import { type NextRequest, NextResponse } from 'next/server'
3+
import { auth } from '@/lib/auth'
4+
import { createLogger } from '@/lib/logs/console/logger'
5+
import { db } from '@/../../packages/db'
6+
import { settings } from '@/../../packages/db/schema'
7+
8+
const logger = createLogger('CopilotUserModelsAPI')
9+
10+
const DEFAULT_ENABLED_MODELS: Record<string, boolean> = {
11+
'gpt-4o': false,
12+
'gpt-4.1': false,
13+
'gpt-5-fast': false,
14+
'gpt-5': true,
15+
'gpt-5-medium': true,
16+
'gpt-5-high': false,
17+
o3: true,
18+
'claude-4-sonnet': true,
19+
'claude-4.5-sonnet': true,
20+
'claude-4.1-opus': true,
21+
}
22+
23+
// GET - Fetch user's enabled models
24+
export async function GET(request: NextRequest) {
25+
try {
26+
const session = await auth.api.getSession({ headers: request.headers })
27+
28+
if (!session?.user?.id) {
29+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
30+
}
31+
32+
const userId = session.user.id
33+
34+
// Try to fetch existing settings record
35+
const [userSettings] = await db
36+
.select()
37+
.from(settings)
38+
.where(eq(settings.userId, userId))
39+
.limit(1)
40+
41+
if (userSettings) {
42+
const userModelsMap = (userSettings.copilotEnabledModels as Record<string, boolean>) || {}
43+
44+
// Merge: start with defaults, then override with user's existing preferences
45+
const mergedModels = { ...DEFAULT_ENABLED_MODELS }
46+
for (const [modelId, enabled] of Object.entries(userModelsMap)) {
47+
mergedModels[modelId] = enabled
48+
}
49+
50+
// If we added any new models, update the database
51+
const hasNewModels = Object.keys(DEFAULT_ENABLED_MODELS).some(
52+
(key) => !(key in userModelsMap)
53+
)
54+
55+
if (hasNewModels) {
56+
await db
57+
.update(settings)
58+
.set({
59+
copilotEnabledModels: mergedModels,
60+
updatedAt: new Date(),
61+
})
62+
.where(eq(settings.userId, userId))
63+
}
64+
65+
return NextResponse.json({
66+
enabledModels: mergedModels,
67+
})
68+
}
69+
70+
// If no settings record exists, create one with empty object (client will use defaults)
71+
const [created] = await db
72+
.insert(settings)
73+
.values({
74+
id: userId,
75+
userId,
76+
copilotEnabledModels: {},
77+
})
78+
.returning()
79+
80+
return NextResponse.json({
81+
enabledModels: DEFAULT_ENABLED_MODELS,
82+
})
83+
} catch (error) {
84+
logger.error('Failed to fetch user models', { error })
85+
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
86+
}
87+
}
88+
89+
// PUT - Update user's enabled models
90+
export async function PUT(request: NextRequest) {
91+
try {
92+
const session = await auth.api.getSession({ headers: request.headers })
93+
94+
if (!session?.user?.id) {
95+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
96+
}
97+
98+
const userId = session.user.id
99+
const body = await request.json()
100+
101+
if (!body.enabledModels || typeof body.enabledModels !== 'object') {
102+
return NextResponse.json({ error: 'enabledModels must be an object' }, { status: 400 })
103+
}
104+
105+
// Check if settings record exists
106+
const [existing] = await db.select().from(settings).where(eq(settings.userId, userId)).limit(1)
107+
108+
if (existing) {
109+
// Update existing record
110+
await db
111+
.update(settings)
112+
.set({
113+
copilotEnabledModels: body.enabledModels,
114+
updatedAt: new Date(),
115+
})
116+
.where(eq(settings.userId, userId))
117+
} else {
118+
// Create new settings record
119+
await db.insert(settings).values({
120+
id: userId,
121+
userId,
122+
copilotEnabledModels: body.enabledModels,
123+
})
124+
}
125+
126+
return NextResponse.json({ success: true })
127+
} catch (error) {
128+
logger.error('Failed to update user models', { error })
129+
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
130+
}
131+
}

0 commit comments

Comments
 (0)