The generateCode
function is an asynchronous function that generates code based on a given prompt and project repository, and handles various steps such as resolving the Github path and cloning the repository. If no codeFile
is provided, the function uses the llmCode
function to ask the user for a file to edit based on the prompt, and logs the prompt and potential file name(s) generated by the AI model.
npm run import -- "generate code"
const fs = require('fs')
const path = require('path')
const PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE || '';
const {spawnSync} = require('child_process')
const {safeurl} = importer.import("domain cache tools")
async function generateCode(prompt, codeFile, github) {
const llmCode = await importer.import("llm code")
if(!github) {
console.error('Project not specified.')
return
}
// TODO: local pull
if(!fs.existsSync(github)
&& fs.existsSync(path.join(PROFILE_PATH, github))) {
github = path.join(PROFILE_PATH, github)
}
if(github.includes('://')
&& fs.existsSync(path.basename(github).replace('.git', ''))
) {
github = path.join(PROFILE_PATH, path.basename(github).replace('.git', ''))
}
if(!fs.existsSync(github)) {
console.error('Project not found.')
return
}
let baseName = path.basename(github)
await spawnSync('git', ['pull'], {
cwd: github,
timeout: 3000,
stdio: ['pipe', 'pipe', 'pipe']
})
if(!codeFile) {
let project = fs.readdirSync(github)
let projectDirs = project.filter(dir => fs.statSync(path.join(github, dir)).isDirectory())
let projectFiles = project.filter(dir => !fs.statSync(path.join(github, dir)).isDirectory())
for(let i = 0; i < projectDirs.length; i++) {
projectFiles = projectFiles.concat(fs.readdirSync(github).filter(file => !fs.statSync(path.join(github, projectDirs[i], file)).isDirectory()))
}
let q0 = 'Out of these project files:\n' + projectFiles
+ '\nWhich one needs to be edited for the given prompt:\n'
+ prompt + '\nReturn only the potential file name and nothing else.'
console.log('User: ' + q0)
let a0 = await llmCode(q0)
console.log('AI: ' + a0)
codeFile = projectFiles.filter(file => a0.match(file))
}
//if(fs.existsSync(path.join(github, codeFile))) {
// codeFile = path.join(github, codeFile)
//}
//if(!fs.existsSync(codeFile)) { // edit passwords?
if(!fs.existsSync(path.join(github, codeFile))) {
console.error('Code file not found.')
return
}
// TODO: compare existing project files
let q1 = 'Given the project files:\n' + fs.readdirSync(github).join('\n')
+ 'And the existing code for the file ' + codeFile + ':\n'
+ fs.readFileSync(path.join(github, codeFile))
+ '\nFulfill the following instructions on the code file, only return the block of new code.'
+ '\n' + prompt
+ '\n' + 'Response with only the block of code and no summary or reasoning.'
// TODO: create new files
console.log('User: ' + q1)
let a1 = await llmCode(q1)
console.log('AI: ' + a1)
// try to extract code blocks
let code = a1.matchAll(/```(bash|javascript|code)*\n[\s\S]*?\n```/gi)
// extract code blocks from response
let codeBlocks = ''
for(let match of code) {
codeBlocks += match[0].replace(/^```(bash|javascript|code)*\n|\n```$/gi, '') + '\n'
}
if(!codeBlocks) {
console.log('Error, couldn\'t find code in:' + a1)
return
}
// TODO: populate code files with goals
fs.writeFileSync(path.join(github, codeFile), codeBlocks)
// TODO: populate goals with actual code
}
module.exports = generateCode
const fs = require('fs');
const path = require('path');
const { spawnSync } = require('child_process');
const { safeUrl } = require('domain-cache-tools');
class CodeGenerator {
constructor(llmCode) {
this.llmCode = llmCode;
}
async generateCode(prompt, codeFile, github) {
if (!github) {
throw new Error('Project not specified.');
}
if (!fs.existsSync(github) && fs.existsSync(path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, github))) {
github = path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, github);
}
if (github.includes('://') && fs.existsSync(path.basename(github).replace('.git', ''))) {
github = path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, path.basename(github).replace('.git', ''));
}
if (!fs.existsSync(github)) {
throw new Error('Project not found.');
}
let baseName = path.basename(github);
try {
await this.pullRepo(github);
} catch (error) {
throw new Error('Failed to pull repository.');
}
if (!codeFile) {
try {
codeFile = await this.autocompleteCode(prompt, github);
} catch (error) {
throw new Error('Failed to autocomplete code.');
}
}
if (!fs.existsSync(path.join(github, codeFile))) {
throw new Error('Code file not found.');
}
try {
const existingCode = fs.readFileSync(path.join(github, codeFile));
const newCode = await this.generateNewCode(prompt, existingCode, github);
fs.writeFileSync(path.join(github, codeFile), newCode);
} catch (error) {
throw new Error('Failed to generate new code.');
}
}
async pullRepo(github) {
return spawnSync('git', ['pull'], {
cwd: github,
timeout: 3000,
stdio: ['pipe', 'pipe', 'pipe']
});
}
async autocompleteCode(prompt, github) {
const projectFiles = fs.readdirSync(github).filter(file =>!fs.statSync(path.join(github, file)).isDirectory());
const q0 = `Out of these project files:\n${projectFiles.join('\n')}\nWhich one needs to be edited for the given prompt:\n${prompt}\nReturn only the potential file name and nothing else.`;
const a0 = await this.llmCode(q0);
const codeFile = projectFiles.filter(file => a0.match(file))[0];
return codeFile;
}
async generateNewCode(prompt, existingCode, github) {
const q1 = `Given the project files:\n${fs.readdirSync(github).join('\n')}\nAnd the existing code for the file ${path.basename(github)}:\n${existingCode}\nFulfill the following instructions on the code file, only return the block of new code.\n${prompt}\nResponse with only the block of code and no summary or reasoning.`;
const a1 = await this.llmCode(q1);
const code = a1.matchAll(/```(bash|javascript|code)*\n[\s\S]*?\n```/gi);
let codeBlocks = '';
for (let match of code) {
codeBlocks += match[0].replace(/^```(bash|javascript|code)*\n|\n```$/gi, '') + '\n';
}
return codeBlocks;
}
}
module.exports = (llmCode) => new CodeGenerator(llmCode);
Function Overview
This is an asynchronous function generateCode
that takes three parameters: prompt
, codeFile
, and github
. The function appears to be designed to generate code based on a given prompt and project repository.
Key Steps
github
parameter is provided. If not, it logs an error and returns.github
path, considering various environment variables and the local file system.github
path is not found, it logs an error and returns.spawnSync
function to perform a git pull
operation.codeFile
is provided, the function uses the llmCode
function to ask the user for a file to edit based on the prompt. It logs the prompt and the potential file name(s) generated by the AI model.codeFile
is not found in the project repository, it logs an error (commented out code is related to checking if the file exists in the repository).Functions Used
fs.existsSync
: checks if a file or directory existspath.basename
: gets the base name of a file or directorypath.join
: joins paths togetherspawnSync
: executes a command in the shell and waits for its completionllmCode
: a function that uses a language model to generate code (not implemented in this code snippet)importer.import
: imports a module or function (not implemented in this code snippet)Notes
process.env
object to access environment variables.github
parameter is expected to be a repository path, which may include a Git URL (e.g., https://github.com/user/repo.git
).codeFile
parameter is expected to be a file name within the project repository.