1+ // app/api/chat/route.ts - Enhanced with better error handling and project analysis
12import type { Duration } from "@/lib/duration"
23import type { LLMModel , LLMModelConfig } from "@/lib/models"
34import { getModelClient } from "@/lib/models"
4- import { toPrompt } from "@/lib/prompt"
5+ import { toEnhancedPrompt } from "@/lib/enhanced- prompt"
56import ratelimit from "@/lib/ratelimit"
67import { fragmentSchema as schema } from "@/lib/schema"
78import type { TemplatesDataObject } from "@/lib/templates"
9+ import { ProjectAnalyzer , type ProjectStructure } from "@/lib/project-analyzer"
810import { streamObject , type LanguageModel , type CoreMessage } from "ai"
11+ import { logError , generateRequestId , validateRequestData } from "@/lib/debug"
912
1013export const maxDuration = 60
1114
@@ -15,18 +18,18 @@ const rateLimitMaxRequests = process.env.RATE_LIMIT_MAX_REQUESTS
1518const ratelimitWindow = process . env . RATE_LIMIT_WINDOW ? ( process . env . RATE_LIMIT_WINDOW as Duration ) : "1d"
1619
1720export async function POST ( req : Request ) {
18- const requestId = `req_ ${ Date . now ( ) } _ ${ Math . random ( ) . toString ( 36 ) . substr ( 2 , 9 ) } `
21+ const requestId = generateRequestId ( )
1922
2023 try {
21- console . log ( `[Chat API ${ requestId } ] Processing request` )
24+ console . log ( `[Enhanced Chat API ${ requestId } ] Processing request` )
2225
23- // Parse request body with error handling
26+ // Parse request body with enhanced error handling
2427 let body : any
2528 try {
2629 body = await req . json ( )
27- console . log ( `[Chat API ${ requestId } ] Request body parsed, keys:` , Object . keys ( body ) )
30+ console . log ( `[Enhanced Chat API ${ requestId } ] Request body parsed, keys:` , Object . keys ( body ) )
2831 } catch ( error ) {
29- console . error ( `[Chat API ${ requestId } ] Request body parsing failed:` , error )
32+ logError ( " Request body parsing" , error , { requestId } )
3033 return new Response (
3134 JSON . stringify ( {
3235 error : "Invalid JSON in request body" ,
@@ -47,84 +50,28 @@ export async function POST(req: Request) {
4750 template,
4851 model,
4952 config,
53+ uploadedFiles, // New: support for uploaded files
54+ analysisInstructions, // New: specific instructions for analysis
5055 } : {
5156 messages : CoreMessage [ ]
5257 userID : string
5358 teamID : string
5459 template : TemplatesDataObject
5560 model : LLMModel
5661 config : LLMModelConfig
62+ uploadedFiles ?: File [ ]
63+ analysisInstructions ?: string
5764 } = body
5865
59- // Enhanced validation with specific error messages
60- if ( ! userID || ! teamID ) {
61- console . error ( `[Chat API ${ requestId } ] Missing authentication:` , {
62- hasUserID : ! ! userID ,
63- hasTeamID : ! ! teamID ,
64- userID : userID ?. substring ( 0 , 8 ) + "..." ,
65- teamID : teamID ?. substring ( 0 , 8 ) + "..." ,
66- } )
67-
68- return new Response (
69- JSON . stringify ( {
70- error : "Authentication required. Please ensure you're signed in and have a valid team." ,
71- code : "MISSING_AUTH" ,
72- details : {
73- missingUserID : ! userID ,
74- missingTeamID : ! teamID ,
75- } ,
76- requestId,
77- } ) ,
78- {
79- status : 401 ,
80- headers : { "Content-Type" : "application/json" } ,
81- } ,
82- )
83- }
84-
85- if ( ! messages || ! Array . isArray ( messages ) || messages . length === 0 ) {
86- console . error ( `[Chat API ${ requestId } ] Invalid messages:` , {
87- hasMessages : ! ! messages ,
88- isArray : Array . isArray ( messages ) ,
89- length : messages ?. length ,
90- } )
91-
92- return new Response (
93- JSON . stringify ( {
94- error : "Messages are required and must be a non-empty array" ,
95- code : "INVALID_MESSAGES" ,
96- requestId,
97- } ) ,
98- {
99- status : 400 ,
100- headers : { "Content-Type" : "application/json" } ,
101- } ,
102- )
103- }
104-
105- if ( ! model || ! model . id || ! model . providerId ) {
106- console . error ( `[Chat API ${ requestId } ] Invalid model:` , model )
107-
108- return new Response (
109- JSON . stringify ( {
110- error : "Valid model configuration is required" ,
111- code : "INVALID_MODEL" ,
112- requestId,
113- } ) ,
114- {
115- status : 400 ,
116- headers : { "Content-Type" : "application/json" } ,
117- } ,
118- )
119- }
120-
121- if ( ! template ) {
122- console . error ( `[Chat API ${ requestId } ] Invalid template:` , template )
123-
66+ // Enhanced validation with better error messages
67+ const validation = validateRequestData ( body )
68+ if ( ! validation . valid ) {
69+ logError ( "Request validation failed" , new Error ( validation . errors . join ( ", " ) ) , { requestId, errors : validation . errors } )
12470 return new Response (
12571 JSON . stringify ( {
126- error : "Template configuration is required" ,
127- code : "INVALID_TEMPLATE" ,
72+ error : "Request validation failed" ,
73+ code : "VALIDATION_ERROR" ,
74+ details : validation . errors ,
12875 requestId,
12976 } ) ,
13077 {
@@ -134,22 +81,44 @@ export async function POST(req: Request) {
13481 )
13582 }
13683
137- console . log ( `[Chat API ${ requestId } ] Validation passed:` , {
84+ console . log ( `[Enhanced Chat API ${ requestId } ] Validation passed:` , {
13885 userID : userID . substring ( 0 , 8 ) + "..." ,
13986 teamID : teamID . substring ( 0 , 8 ) + "..." ,
14087 modelId : model . id ,
14188 provider : model . providerId ,
14289 messagesCount : messages . length ,
90+ hasUploadedFiles : ! ! ( uploadedFiles && uploadedFiles . length > 0 ) ,
14391 } )
14492
93+ // Analyze uploaded files if present
94+ let projectStructure : ProjectStructure | undefined
95+ if ( uploadedFiles && uploadedFiles . length > 0 ) {
96+ try {
97+ console . log ( `[Enhanced Chat API ${ requestId } ] Analyzing ${ uploadedFiles . length } uploaded files` )
98+ const analyzer = new ProjectAnalyzer ( )
99+ const analysis = await analyzer . analyzeProject ( uploadedFiles )
100+ projectStructure = analysis . structure
101+
102+ console . log ( `[Enhanced Chat API ${ requestId } ] Project analysis completed:` , {
103+ filesAnalyzed : uploadedFiles . length ,
104+ dependenciesFound : projectStructure . dependencies . size ,
105+ componentsFound : projectStructure . components . size ,
106+ architectureType : projectStructure . architecture . type ,
107+ } )
108+ } catch ( analysisError ) {
109+ logError ( "Project analysis failed" , analysisError , { requestId, filesCount : uploadedFiles . length } )
110+ console . warn ( `[Enhanced Chat API ${ requestId } ] Project analysis failed, continuing without analysis:` , analysisError )
111+ }
112+ }
113+
145114 // Rate limiting check
146115 try {
147116 const limit = ! config . apiKey
148117 ? await ratelimit ( req . headers . get ( "x-forwarded-for" ) , rateLimitMaxRequests , ratelimitWindow )
149118 : false
150119
151120 if ( limit ) {
152- console . log ( `[Chat API ${ requestId } ] Rate limit hit:` , limit )
121+ console . log ( `[Enhanced Chat API ${ requestId } ] Rate limit hit:` , limit )
153122 return new Response (
154123 JSON . stringify ( {
155124 error : "You have reached your request limit for the day." ,
@@ -168,24 +137,24 @@ export async function POST(req: Request) {
168137 } ,
169138 )
170139 }
171- console . log ( `[Chat API ${ requestId } ] Rate limit check passed` )
140+ console . log ( `[Enhanced Chat API ${ requestId } ] Rate limit check passed` )
172141 } catch ( error ) {
173- console . warn ( `[Chat API ${ requestId } ] Rate limiting check failed:` , error )
142+ logError ( " Rate limiting check failed" , error , { requestId } )
174143 // Continue without rate limiting if it fails
175144 }
176145
177146 // Create model client with enhanced error handling
178147 let modelClient : LanguageModel
179148 try {
180- console . log ( `[Chat API ${ requestId } ] Creating model client for:` , model . providerId , model . id )
149+ console . log ( `[Enhanced Chat API ${ requestId } ] Creating model client for:` , model . providerId , model . id )
181150 modelClient = getModelClient ( model , config ) as LanguageModel
182- console . log ( `[Chat API ${ requestId } ] Model client created successfully` )
151+ console . log ( `[Enhanced Chat API ${ requestId } ] Model client created successfully` )
183152 } catch ( error : any ) {
184- console . error ( `[Chat API ${ requestId } ] Model client creation failed:` , error )
153+ logError ( " Model client creation failed" , error , { requestId , provider : model . providerId , modelId : model . id } )
185154
186155 return new Response (
187156 JSON . stringify ( {
188- error : `Failed to initialize ${ model . providerId } model: ${ error . message } ` , // Use model.providerId for consistency
157+ error : `Failed to initialize ${ model . providerId } model. Please check your API key configuration.` ,
189158 code : "MODEL_INIT_ERROR" ,
190159 provider : model . providerId ,
191160 details : error . message ,
@@ -198,21 +167,30 @@ export async function POST(req: Request) {
198167 )
199168 }
200169
201- // Prepare model parameters from config, excluding model and apiKey used for client instantiation
202- const { model : _modelFromConfig , apiKey : _apiKeyFromConfig , ...providerSpecificConfig } = config
203-
204- // Clean up undefined values from provider-specific config
205- const cleanProviderSpecificConfig = Object . fromEntries (
206- Object . entries ( providerSpecificConfig ) . filter ( ( [ _ , value ] ) => value !== undefined ) ,
207- )
170+ // Extract user prompt from the last message
171+ const lastMessage = messages [ messages . length - 1 ]
172+ let userPrompt = ''
173+ if ( Array . isArray ( lastMessage ?. content ) ) {
174+ userPrompt = lastMessage . content
175+ . filter ( ( content : any ) => content . type === 'text' )
176+ . map ( ( content : any ) => content . text )
177+ . join ( ' ' )
178+ }
208179
209180 let systemPrompt : string
210181 try {
211- systemPrompt = toPrompt ( template )
212- // The check for empty systemPrompt with template content was removed due to type mismatch.
213- // toPrompt is responsible for handling the TemplatesDataObject.
182+ if ( projectStructure && userPrompt ) {
183+ console . log ( `[Enhanced Chat API ${ requestId } ] Generating enhanced prompt with project context` )
184+ systemPrompt = toEnhancedPrompt ( template , userPrompt , projectStructure )
185+ } else {
186+ console . log ( `[Enhanced Chat API ${ requestId } ] Using standard prompt generation` )
187+ // Fallback to existing prompt system
188+ systemPrompt = generateFallbackPrompt ( template )
189+ }
190+
191+ console . log ( `[Enhanced Chat API ${ requestId } ] System prompt generated, length:` , systemPrompt . length )
214192 } catch ( error : any ) {
215- console . error ( `[Chat API ${ requestId } ] System prompt generation failed:` , error )
193+ logError ( " System prompt generation failed" , error , { requestId } )
216194 return new Response (
217195 JSON . stringify ( {
218196 error : "Failed to generate system prompt from template." ,
@@ -227,32 +205,41 @@ export async function POST(req: Request) {
227205 )
228206 }
229207
230- console . log ( `[Chat API ${ requestId } ] Creating stream with params:` , {
208+ // Prepare model parameters from config
209+ const { model : _modelFromConfig , apiKey : _apiKeyFromConfig , ...providerSpecificConfig } = config
210+
211+ // Clean up undefined values from provider-specific config
212+ const cleanProviderSpecificConfig = Object . fromEntries (
213+ Object . entries ( providerSpecificConfig ) . filter ( ( [ _ , value ] ) => value !== undefined ) ,
214+ )
215+
216+ console . log ( `[Enhanced Chat API ${ requestId } ] Creating stream with params:` , {
231217 providerSpecificConfigKeys : Object . keys ( cleanProviderSpecificConfig ) ,
232218 systemPromptLength : systemPrompt . length ,
219+ hasProjectContext : ! ! projectStructure ,
233220 } )
234221
235222 try {
236223 const streamConfig = {
237224 model : modelClient ,
238225 schema,
239- system : systemPrompt , // Use the validated system prompt
226+ system : systemPrompt ,
240227 messages,
241- maxRetries : 1 , // Reduce retries to avoid timeout issues
242- ...cleanProviderSpecificConfig , // Pass cleaned provider-specific parameters
228+ maxRetries : 2 , // Increase retries for better reliability
229+ ...cleanProviderSpecificConfig ,
243230 }
244231
245- console . log ( `[Chat API ${ requestId } ] Starting stream object creation` )
232+ console . log ( `[Enhanced Chat API ${ requestId } ] Starting stream object creation` )
246233 const stream = await streamObject ( streamConfig )
247234
248- console . log ( `[Chat API ${ requestId } ] Stream created successfully` )
235+ console . log ( `[Enhanced Chat API ${ requestId } ] Stream created successfully` )
249236 return stream . toTextStreamResponse ( )
250237 } catch ( error : any ) {
251- console . error ( `[Chat API ${ requestId } ] Stream creation failed:` , {
252- error : error . message ,
253- stack : error . stack ,
254- status : error . status ,
255- code : error . code ,
238+ logError ( " Stream creation failed" , error , {
239+ requestId ,
240+ provider : model . providerId ,
241+ modelId : model . id ,
242+ hasProjectContext : ! ! projectStructure
256243 } )
257244
258245 // Enhanced error categorization
@@ -326,7 +313,7 @@ export async function POST(req: Request) {
326313 if ( errorMessage . includes ( "model" ) && errorMessage . includes ( "not found" ) ) {
327314 return new Response (
328315 JSON . stringify ( {
329- error : `Model ${ model . id } is not available for ${ model . providerId } .` , // Use model.providerId
316+ error : `Model ${ model . id } is not available for ${ model . providerId } .` ,
330317 code : "MODEL_NOT_FOUND" ,
331318 provider : model . providerId ,
332319 modelId : model . id ,
@@ -363,7 +350,7 @@ export async function POST(req: Request) {
363350 )
364351 }
365352 } catch ( error : any ) {
366- console . error ( `[Chat API ${ requestId } ] Request processing failed:` , error )
353+ logError ( " Request processing failed" , error , { requestId } )
367354
368355 return new Response (
369356 JSON . stringify ( {
@@ -379,3 +366,26 @@ export async function POST(req: Request) {
379366 )
380367 }
381368}
369+
370+ // Fallback prompt generation function
371+ function generateFallbackPrompt ( template : TemplatesDataObject ) : string {
372+ return `You are an expert software engineer with deep knowledge of modern web development, programming languages, frameworks, and best practices.
373+
374+ Generate production-ready code based on the user's requirements using the following templates:
375+
376+ ${ Object . entries ( template ) . map ( ( [ id , t ] , index ) =>
377+ `${ index + 1 } . ${ id } : "${ t . instructions } ". File: ${ t . file || 'none' } . Dependencies: ${ t . lib . join ( ', ' ) } . Port: ${ t . port || 'none' } .`
378+ ) . join ( '\n' ) }
379+
380+ IMPORTANT GUIDELINES:
381+ - Write clean, maintainable, and well-documented code
382+ - Follow modern best practices and patterns
383+ - Include proper error handling and validation
384+ - Ensure code is production-ready
385+ - Use TypeScript when applicable for type safety
386+ - Implement responsive design for web applications
387+ - Follow accessibility guidelines (WCAG 2.1)
388+ - Include proper security measures
389+
390+ Generate complete, functional code that fulfills the user's request.`
391+ }
0 commit comments