@@ -8,9 +8,8 @@ import { getSession } from '@/lib/auth'
88import { buildConversationHistory } from '@/lib/copilot/chat-context'
99import { resolveOrCreateChat } from '@/lib/copilot/chat-lifecycle'
1010import { buildCopilotRequestPayload } from '@/lib/copilot/chat-payload'
11- import { generateChatTitle } from '@/lib/copilot/chat-title'
12- import { getCopilotModel } from '@/lib/copilot/config'
13- import { COPILOT_MODEL_IDS , COPILOT_REQUEST_MODES } from '@/lib/copilot/models'
11+ import { SIM_AGENT_API_URL } from '@/lib/copilot/constants'
12+ import { COPILOT_REQUEST_MODES } from '@/lib/copilot/models'
1413import { orchestrateCopilotStream } from '@/lib/copilot/orchestrator'
1514import {
1615 createStreamEventWriter ,
@@ -29,6 +28,49 @@ import { resolveWorkflowIdForUser } from '@/lib/workflows/utils'
2928
3029const logger = createLogger ( 'CopilotChatAPI' )
3130
31+ async function requestChatTitleFromCopilot ( params : {
32+ message : string
33+ model : string
34+ provider ?: string
35+ } ) : Promise < string | null > {
36+ const { message, model, provider } = params
37+ if ( ! message || ! model ) return null
38+
39+ const headers : Record < string , string > = {
40+ 'Content-Type' : 'application/json' ,
41+ }
42+ if ( env . COPILOT_API_KEY ) {
43+ headers [ 'x-api-key' ] = env . COPILOT_API_KEY
44+ }
45+
46+ try {
47+ const response = await fetch ( `${ SIM_AGENT_API_URL } /api/generate-chat-title` , {
48+ method : 'POST' ,
49+ headers,
50+ body : JSON . stringify ( {
51+ message,
52+ model,
53+ ...( provider ? { provider } : { } ) ,
54+ } ) ,
55+ } )
56+
57+ const payload = await response . json ( ) . catch ( ( ) => ( { } ) )
58+ if ( ! response . ok ) {
59+ logger . warn ( 'Failed to generate chat title via copilot backend' , {
60+ status : response . status ,
61+ error : payload ,
62+ } )
63+ return null
64+ }
65+
66+ const title = typeof payload ?. title === 'string' ? payload . title . trim ( ) : ''
67+ return title || null
68+ } catch ( error ) {
69+ logger . error ( 'Error generating chat title:' , error )
70+ return null
71+ }
72+ }
73+
3274const FileAttachmentSchema = z . object ( {
3375 id : z . string ( ) ,
3476 key : z . string ( ) ,
@@ -43,14 +85,14 @@ const ChatMessageSchema = z.object({
4385 chatId : z . string ( ) . optional ( ) ,
4486 workflowId : z . string ( ) . optional ( ) ,
4587 workflowName : z . string ( ) . optional ( ) ,
46- model : z . enum ( COPILOT_MODEL_IDS ) . optional ( ) . default ( 'claude-4.6-opus ' ) ,
88+ model : z . string ( ) . optional ( ) . default ( 'claude-opus-4-6 ' ) ,
4789 mode : z . enum ( COPILOT_REQUEST_MODES ) . optional ( ) . default ( 'agent' ) ,
4890 prefetch : z . boolean ( ) . optional ( ) ,
4991 createNewChat : z . boolean ( ) . optional ( ) . default ( false ) ,
5092 stream : z . boolean ( ) . optional ( ) . default ( true ) ,
5193 implicitFeedback : z . string ( ) . optional ( ) ,
5294 fileAttachments : z . array ( FileAttachmentSchema ) . optional ( ) ,
53- provider : z . string ( ) . optional ( ) . default ( 'openai' ) ,
95+ provider : z . string ( ) . optional ( ) ,
5496 conversationId : z . string ( ) . optional ( ) ,
5597 contexts : z
5698 . array (
@@ -173,14 +215,14 @@ export async function POST(req: NextRequest) {
173215 let currentChat : any = null
174216 let conversationHistory : any [ ] = [ ]
175217 let actualChatId = chatId
218+ const selectedModel = model || 'claude-opus-4-6'
176219
177220 if ( chatId || createNewChat ) {
178- const defaultsForChatRow = getCopilotModel ( 'chat' )
179221 const chatResult = await resolveOrCreateChat ( {
180222 chatId,
181223 userId : authenticatedUserId ,
182224 workflowId,
183- model : defaultsForChatRow . model ,
225+ model : selectedModel ,
184226 } )
185227 currentChat = chatResult . chat
186228 actualChatId = chatResult . chatId || chatId
@@ -191,8 +233,6 @@ export async function POST(req: NextRequest) {
191233 conversationHistory = history . history
192234 }
193235
194- const defaults = getCopilotModel ( 'chat' )
195- const selectedModel = model || defaults . model
196236 const effectiveMode = mode === 'agent' ? 'build' : mode
197237 const effectiveConversationId =
198238 ( currentChat ?. conversationId as string | undefined ) || conversationId
@@ -205,6 +245,7 @@ export async function POST(req: NextRequest) {
205245 userMessageId : userMessageIdToUse ,
206246 mode,
207247 model : selectedModel ,
248+ provider,
208249 conversationHistory,
209250 contexts : agentContexts ,
210251 fileAttachments,
@@ -283,7 +324,7 @@ export async function POST(req: NextRequest) {
283324 }
284325
285326 if ( actualChatId && ! currentChat ?. title && conversationHistory . length === 0 ) {
286- generateChatTitle ( message )
327+ requestChatTitleFromCopilot ( { message, model : selectedModel , provider } )
287328 . then ( async ( title ) => {
288329 if ( title ) {
289330 await db
@@ -372,10 +413,7 @@ export async function POST(req: NextRequest) {
372413 content : nonStreamingResult . content ,
373414 toolCalls : nonStreamingResult . toolCalls ,
374415 model : selectedModel ,
375- provider :
376- ( requestPayload ?. provider as Record < string , unknown > ) ?. provider ||
377- env . COPILOT_PROVIDER ||
378- 'openai' ,
416+ provider : typeof requestPayload ?. provider === 'string' ? requestPayload . provider : undefined ,
379417 }
380418
381419 logger . info ( `[${ tracker . requestId } ] Non-streaming response from orchestrator:` , {
@@ -413,7 +451,7 @@ export async function POST(req: NextRequest) {
413451 // Start title generation in parallel if this is first message (non-streaming)
414452 if ( actualChatId && ! currentChat . title && conversationHistory . length === 0 ) {
415453 logger . info ( `[${ tracker . requestId } ] Starting title generation for non-streaming response` )
416- generateChatTitle ( message )
454+ requestChatTitleFromCopilot ( { message, model : selectedModel , provider } )
417455 . then ( async ( title ) => {
418456 if ( title ) {
419457 await db
0 commit comments