Skip to content

Commit 27f1b15

Browse files
committed
refactor: enhance dependency handling and error logging in frontend code generation
1 parent eb01b84 commit 27f1b15

File tree

1 file changed

+69
-56
lines changed
  • backend/src/build-system/handlers/frontend-code-generate

1 file changed

+69
-56
lines changed

backend/src/build-system/handlers/frontend-code-generate/index.ts

Lines changed: 69 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import path from 'path';
1818
import { readFile } from 'fs-extra';
1919
import { generateCSSPrompt, generateFrontEndCodePrompt } from './prompt';
2020
import { 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

Comments
 (0)