Skip to content

Commit 8361931

Browse files
authored
fix(copilot): fix copilot bugs (#2855)
* Fix edit workflow returning bad state * Fix block id edit, slash commands at end, thinking tag resolution, add continue button * Clean up autosend and continue options and enable mention menu * Cleanup * Fix thinking tags * Fix thinking text * Fix get block options text * Fix bugs * Fix redeploy * Fix loading indicators * User input expansion * Normalize copilot subblock ids * Fix handlecancelcheckpoint
1 parent c863125 commit 8361931

File tree

26 files changed

+930
-612
lines changed

26 files changed

+930
-612
lines changed

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

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { getSession } from '@/lib/auth'
88
import { generateChatTitle } from '@/lib/copilot/chat-title'
99
import { getCopilotModel } from '@/lib/copilot/config'
1010
import { SIM_AGENT_API_URL_DEFAULT, SIM_AGENT_VERSION } from '@/lib/copilot/constants'
11+
import { COPILOT_MODEL_IDS, COPILOT_REQUEST_MODES } from '@/lib/copilot/models'
1112
import {
1213
authenticateCopilotRequestSessionOnly,
1314
createBadRequestResponse,
@@ -40,34 +41,8 @@ const ChatMessageSchema = z.object({
4041
userMessageId: z.string().optional(), // ID from frontend for the user message
4142
chatId: z.string().optional(),
4243
workflowId: z.string().min(1, 'Workflow ID is required'),
43-
model: z
44-
.enum([
45-
'gpt-5-fast',
46-
'gpt-5',
47-
'gpt-5-medium',
48-
'gpt-5-high',
49-
'gpt-5.1-fast',
50-
'gpt-5.1',
51-
'gpt-5.1-medium',
52-
'gpt-5.1-high',
53-
'gpt-5-codex',
54-
'gpt-5.1-codex',
55-
'gpt-5.2',
56-
'gpt-5.2-codex',
57-
'gpt-5.2-pro',
58-
'gpt-4o',
59-
'gpt-4.1',
60-
'o3',
61-
'claude-4-sonnet',
62-
'claude-4.5-haiku',
63-
'claude-4.5-sonnet',
64-
'claude-4.5-opus',
65-
'claude-4.1-opus',
66-
'gemini-3-pro',
67-
])
68-
.optional()
69-
.default('claude-4.5-opus'),
70-
mode: z.enum(['ask', 'agent', 'plan']).optional().default('agent'),
44+
model: z.enum(COPILOT_MODEL_IDS).optional().default('claude-4.5-opus'),
45+
mode: z.enum(COPILOT_REQUEST_MODES).optional().default('agent'),
7146
prefetch: z.boolean().optional(),
7247
createNewChat: z.boolean().optional().default(false),
7348
stream: z.boolean().optional().default(true),
@@ -295,7 +270,8 @@ export async function POST(req: NextRequest) {
295270
}
296271

297272
const defaults = getCopilotModel('chat')
298-
const modelToUse = env.COPILOT_MODEL || defaults.model
273+
const selectedModel = model || defaults.model
274+
const envModel = env.COPILOT_MODEL || defaults.model
299275

300276
let providerConfig: CopilotProviderConfig | undefined
301277
const providerEnv = env.COPILOT_PROVIDER as any
@@ -304,28 +280,31 @@ export async function POST(req: NextRequest) {
304280
if (providerEnv === 'azure-openai') {
305281
providerConfig = {
306282
provider: 'azure-openai',
307-
model: modelToUse,
283+
model: envModel,
308284
apiKey: env.AZURE_OPENAI_API_KEY,
309285
apiVersion: 'preview',
310286
endpoint: env.AZURE_OPENAI_ENDPOINT,
311287
}
312288
} else if (providerEnv === 'vertex') {
313289
providerConfig = {
314290
provider: 'vertex',
315-
model: modelToUse,
291+
model: envModel,
316292
apiKey: env.COPILOT_API_KEY,
317293
vertexProject: env.VERTEX_PROJECT,
318294
vertexLocation: env.VERTEX_LOCATION,
319295
}
320296
} else {
321297
providerConfig = {
322298
provider: providerEnv,
323-
model: modelToUse,
299+
model: selectedModel,
324300
apiKey: env.COPILOT_API_KEY,
325301
}
326302
}
327303
}
328304

305+
const effectiveMode = mode === 'agent' ? 'build' : mode
306+
const transportMode = effectiveMode === 'build' ? 'agent' : effectiveMode
307+
329308
// Determine conversationId to use for this request
330309
const effectiveConversationId =
331310
(currentChat?.conversationId as string | undefined) || conversationId
@@ -345,7 +324,7 @@ export async function POST(req: NextRequest) {
345324
}
346325
} | null = null
347326

348-
if (mode === 'agent') {
327+
if (effectiveMode === 'build') {
349328
// Build base tools (executed locally, not deferred)
350329
// Include function_execute for code execution capability
351330
baseTools = [
@@ -452,8 +431,8 @@ export async function POST(req: NextRequest) {
452431
userId: authenticatedUserId,
453432
stream: stream,
454433
streamToolCalls: true,
455-
model: model,
456-
mode: mode,
434+
model: selectedModel,
435+
mode: transportMode,
457436
messageId: userMessageIdToUse,
458437
version: SIM_AGENT_VERSION,
459438
...(providerConfig ? { provider: providerConfig } : {}),
@@ -477,7 +456,7 @@ export async function POST(req: NextRequest) {
477456
hasConversationId: !!effectiveConversationId,
478457
hasFileAttachments: processedFileContents.length > 0,
479458
messageLength: message.length,
480-
mode,
459+
mode: effectiveMode,
481460
hasTools: integrationTools.length > 0,
482461
toolCount: integrationTools.length,
483462
hasBaseTools: baseTools.length > 0,

apps/sim/app/api/copilot/chat/update-messages/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { createLogger } from '@sim/logger'
44
import { and, eq } from 'drizzle-orm'
55
import { type NextRequest, NextResponse } from 'next/server'
66
import { z } from 'zod'
7+
import { COPILOT_MODES } from '@/lib/copilot/models'
78
import {
89
authenticateCopilotRequestSessionOnly,
910
createInternalServerErrorResponse,
@@ -45,7 +46,7 @@ const UpdateMessagesSchema = z.object({
4546
planArtifact: z.string().nullable().optional(),
4647
config: z
4748
.object({
48-
mode: z.enum(['ask', 'build', 'plan']).optional(),
49+
mode: z.enum(COPILOT_MODES).optional(),
4950
model: z.string().optional(),
5051
})
5152
.nullable()

apps/sim/app/api/copilot/user-models/route.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import { createLogger } from '@sim/logger'
22
import { eq } from 'drizzle-orm'
33
import { type NextRequest, NextResponse } from 'next/server'
44
import { getSession } from '@/lib/auth'
5+
import type { CopilotModelId } from '@/lib/copilot/models'
56
import { db } from '@/../../packages/db'
67
import { settings } from '@/../../packages/db/schema'
78

89
const logger = createLogger('CopilotUserModelsAPI')
910

10-
const DEFAULT_ENABLED_MODELS: Record<string, boolean> = {
11+
const DEFAULT_ENABLED_MODELS: Record<CopilotModelId, boolean> = {
1112
'gpt-4o': false,
1213
'gpt-4.1': false,
1314
'gpt-5-fast': false,
@@ -28,7 +29,7 @@ const DEFAULT_ENABLED_MODELS: Record<string, boolean> = {
2829
'claude-4.5-haiku': true,
2930
'claude-4.5-sonnet': true,
3031
'claude-4.5-opus': true,
31-
// 'claude-4.1-opus': true,
32+
'claude-4.1-opus': false,
3233
'gemini-3-pro': true,
3334
}
3435

@@ -54,7 +55,9 @@ export async function GET(request: NextRequest) {
5455

5556
const mergedModels = { ...DEFAULT_ENABLED_MODELS }
5657
for (const [modelId, enabled] of Object.entries(userModelsMap)) {
57-
mergedModels[modelId] = enabled
58+
if (modelId in mergedModels) {
59+
mergedModels[modelId as CopilotModelId] = enabled
60+
}
5861
}
5962

6063
const hasNewModels = Object.keys(DEFAULT_ENABLED_MODELS).some(

apps/sim/app/api/workflows/[id]/chat/status/route.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ export async function GET(_request: Request, { params }: { params: Promise<{ id:
2222
.select({
2323
id: chat.id,
2424
identifier: chat.identifier,
25+
title: chat.title,
26+
description: chat.description,
27+
customizations: chat.customizations,
28+
authType: chat.authType,
29+
allowedEmails: chat.allowedEmails,
30+
outputConfigs: chat.outputConfigs,
31+
password: chat.password,
2532
isActive: chat.isActive,
2633
})
2734
.from(chat)
@@ -34,6 +41,13 @@ export async function GET(_request: Request, { params }: { params: Promise<{ id:
3441
? {
3542
id: deploymentResults[0].id,
3643
identifier: deploymentResults[0].identifier,
44+
title: deploymentResults[0].title,
45+
description: deploymentResults[0].description,
46+
customizations: deploymentResults[0].customizations,
47+
authType: deploymentResults[0].authType,
48+
allowedEmails: deploymentResults[0].allowedEmails,
49+
outputConfigs: deploymentResults[0].outputConfigs,
50+
hasPassword: Boolean(deploymentResults[0].password),
3751
}
3852
: null
3953

0 commit comments

Comments
 (0)