@@ -18,6 +18,7 @@ import path from 'path';
1818import { readFile } from 'fs-extra' ;
1919import { generateCSSPrompt , generateFrontEndCodePrompt } from './prompt' ;
2020import { parseGenerateTag } from 'src/build-system/utils/strings' ;
21+ import { ResponseParsingError } from 'src/build-system/errors' ;
2122
2223/**
2324 * FrontendCodeHandler is responsible for generating the frontend codebase
@@ -94,90 +95,102 @@ export class FrontendCodeHandler implements BuildHandler<string> {
9495
9596 // Gather direct dependencies
9697 const directDepsArray = fileInfos [ file ] ?. dependsOn || [ ] ;
97- let dependenciesContext = '' ;
98+ const dependenciesContext = '' ;
9899
99- //gather the contents of each dependency into a single string.
100+ // Read each dependency and append to dependenciesContext
101+ let dependenciesText = '' ;
100102 for ( const dep of directDepsArray ) {
101103 try {
102- // Resolve against frontendPath to get the absolute path
103104 const resolvedDepPath = normalizePath (
104105 path . resolve ( frontendPath , 'src' , dep ) ,
105106 ) ;
106-
107- // Read the file. (may want to guard so only read certain file types.)
108- const fileContent = await readFile ( resolvedDepPath , 'utf-8' ) ;
109-
110- //just append a code:
111- dependenciesContext += `\n\n[Dependency: ${ dep } ]\n\`\`\`\n${ fileContent } \n\`\`\`\n` ;
112- } catch ( readError ) {
113- // If the file doesn't exist or can't be read, log a warning.
107+ const depContent = await readFile ( resolvedDepPath , 'utf-8' ) ;
108+ dependenciesText += `\n\nprevious code **${ dep } ** is:\n\`\`\`typescript\n${ depContent } \n\`\`\`\n` ;
109+ } catch ( err ) {
114110 this . logger . warn (
115- `Failed to read dependency "${ dep } " for file "${ file } ": ${ readError } ` ,
111+ `Failed to read dependency "${ dep } " for file "${ file } ": ${ err } ` ,
112+ ) ;
113+ throw new ResponseParsingError (
114+ `Error generating code for ${ file } :` ,
116115 ) ;
117116 }
118117 }
119118
120- // Format for the prompt
121- const directDependencies = directDepsArray . join ( '\n' ) ;
122-
123- this . logger . log (
124- `Generating file in dependency order: ${ currentFullFilePath } ` ,
125- ) ;
126- this . logger . log (
127- `2 Generating file in dependency order directDependencies: ${ directDependencies } ` ,
128- ) ;
129-
119+ // 5. Build prompt text depending on file extension
120+ const fileExtension = path . extname ( file ) ;
130121 let frontendCodePrompt = '' ;
131-
132- if ( fileExtension === 'css' ) {
122+ if ( fileExtension === '.css' ) {
133123 frontendCodePrompt = generateCSSPrompt (
134- sitemapStruct ,
135- uxDataMapDoc ,
136124 file ,
137- directDependencies ,
138- dependenciesContext ,
125+ directDepsArray . join ( '\n' ) ,
139126 ) ;
140127 } else {
141- // Generate the prompt
128+ // default: treat as e.g. .ts, .js, .vue, .jsx, etc.
142129 frontendCodePrompt = generateFrontEndCodePrompt (
143- sitemapStruct ,
144- uxDataMapDoc ,
145- backendRequirementDoc . overview ,
146130 file ,
147- directDependencies ,
148- dependenciesContext ,
131+ directDepsArray . join ( '\n' ) ,
149132 ) ;
150133 }
151134 this . logger . log (
152- 'generate code prompt for frontendCodePrompt or css: ' +
153- frontendCodePrompt ,
135+ `Prompt for file "${ file } ":\n${ frontendCodePrompt } \n` ,
154136 ) ;
155137
156- this . logger . debug ( 'Generated frontend code prompt.' ) ;
157-
138+ const messages = [
139+ {
140+ role : 'system' as const ,
141+ content : frontendCodePrompt ,
142+ } ,
143+ {
144+ role : 'user' as const ,
145+ content : `This is the Sitemap Structure:
146+ ${ sitemapStruct }
147+
148+ Next will provide Sitemap Structure.` ,
149+ } ,
150+ {
151+ role : 'user' as const ,
152+ content : `This is the UX Datamap Documentation:
153+ ${ uxDataMapDoc }
154+
155+ Next will provide UX Datamap Documentation.` ,
156+ } ,
157+ {
158+ role : 'user' as const ,
159+ content : `This is the Backend Requirement Documentation:
160+ ${ backendRequirementDoc }
161+
162+ Next will provide Backend Requirement Documentation.` ,
163+ } ,
164+
165+ {
166+ role : 'user' as const ,
167+ content : `Dependencies for ${ file } :\n${ dependenciesText } \n
168+
169+ Now generate code for "${ file } ".` ,
170+ } ,
171+ ] ;
172+
173+ // 6. Call your Chat Model
158174 let generatedCode = '' ;
159175 try {
160- // Call the model
161- const modelResponse = await context . model . chatSync (
162- {
163- content : frontendCodePrompt ,
164- } ,
165- 'gpt-4o-mini' , // or whichever model you need
176+ const modelResponse = await batchChatSyncWithClock (
177+ context ,
178+ 'generate frontend code' ,
179+ FrontendCodeHandler . name ,
180+ [
181+ {
182+ model : 'gpt-4o' ,
183+ messages,
184+ } ,
185+ ] ,
166186 ) ;
167187
168- // Parse the output
169- generatedCode = parseGenerateTag ( modelResponse ) ;
170-
171- this . logger . debug (
172- 'Frontend code generated and parsed successfully.' ,
188+ generatedCode = parseGenerateTag ( modelResponse [ 0 ] ) ;
189+ } catch ( err ) {
190+ this . logger . error ( `Error generating code for ${ file } :` , err ) ;
191+ throw new ResponseParsingError (
192+ `Error generating code for ${ file } :` ,
173193 ) ;
174- } catch ( error ) {
175- // Return error
176- this . logger . error ( 'Error during frontend code generation:' , error ) ;
177- return {
178- success : false ,
179- error : new Error ( 'Failed to generate frontend code.' ) ,
180- } ;
181194 }
182195
183196 // 7. Write the file to the filesystem
0 commit comments