Open hatkyinc2 opened 1 year ago
🤖 This is my suggestion:
File: modules/db.js
To implement the desired new situation, we need to add a function in modules/db.js
that queries the database to get the list of dependent files. We can do this by adding a new function called getDependentFiles
that takes the codeBaseDirectory
and the filePath
as input parameters and returns a list of dependent files.
Here's the plan for this file:
getDependentFiles
that takes codeBaseDirectory
and filePath
as input parameters.getDB
function.filePath
in their dependenciesLibs
column.Here's the updated code for modules/db.js
:
// ... (existing code)
/**
* @description Gets the list of dependent files that have the given filePath in their dependenciesLibs column
* @param {string} codeBaseDirectory - The path to the codebase
* @param {string} filePath - The file path to search for in the dependenciesLibs column
* @returns {Array<string>} - An array of dependent file paths
* @throws {Error} If an error occurs during the database query.
*/
async function getDependentFiles(codeBaseDirectory, filePath) {
const db = getDB(codeBaseDirectory);
const sql = `
SELECT path
FROM files
WHERE dependenciesLibs LIKE ?
`;
const wildcardFilePath = `%${filePath}%`;
const dependentFiles = await new Promise((resolve, reject) => {
db.all(sql, [wildcardFilePath], (err, rows) => {
if (err) {
reject(err);
} else {
resolve(rows.map(row => row.path));
}
});
});
return dependentFiles;
}
// ... (existing code)
module.exports = {
createDB,
createFilesTable,
insertOrUpdateFile,
getDB,
getDBFiles,
deleteFile,
getDBFilePath,
getDependentFiles, // Export the new function
};
Now, you can use the getDependentFiles
function in the agents/coder.js
file to get the list of dependent files and call the coder agent with the necessary details.
File: agents/coder.js
To implement the desired new situation, we need to modify the suggestChanges
function in the agents/coder.js
file to accept a diff input and call the coder agent for each dependent file after a file update. Here's the plan for this file:
Update the suggestChanges
function signature to accept an additional parameter diff
which will be the diff input.
After receiving the parsedResponse, check if the updateDependentFiles
flag is set to true in the response. If it is, call a function (e.g., updateDependentFiles
) that will handle updating the dependent files.
Implement the updateDependentFiles
function that will:
modules/db.js
to get the list of dependent files (we will implement this function in the modules/db.js
file later).suggestChanges
function with the task, diff, and the new file context.Here's the updated agents/coder.js
file with the changes:
const { z } = require('zod');
const { PromptTemplate } = require('langchain/prompts');
const { StructuredOutputParser, OutputFixingParser } = require('langchain/output_parsers');
const { getModel } = require('../modules/model');
const { saveLog } = require('../modules/fsOutput');
const { getDependentFiles } = require('../modules/db'); // Import the function to get dependent files
const promptTemplate =
`
# USER INPUT
{task}
# YOUR TASK
As a senior software developer, make the requested changes from the USER INPUT.
Write out new code before deleting old code.
{format_instructions}
# SOURCE CODE
{code}
`
const parser = StructuredOutputParser.fromZodSchema(
z.object({
thoughts: z.object({
text: z.string().describe('your thoughts'),
reasoning: z.string().describe('your reasoning'),
criticism: z.string().describe('constructive self-criticism'),
}),
output: z.array(
z.object({
fileToUpdate: z.string().describe('File to write. (can be the current file or a new file)'),
content: z.string().describe('Full content for that file'),
}),
),
})
);
const formatInstructions = parser.getFormatInstructions();
const prompt = new PromptTemplate({
template: promptTemplate,
inputVariables: ['task', 'code'],
partialVariables: { format_instructions: formatInstructions },
});
async function suggestChanges(task, file, diff) {
const code = formatCode(file)
const model = getModel(process.env.INDEXER_MODEL);
const input = await prompt.format({ task, code });
const response = await model.call(input);
let parsedResponse
try {
parsedResponse = await parser.parse(response);
} catch (e){
const fixParser = OutputFixingParser.fromLLM(
model,
parser
);
parsedResponse = await fixParser.parse(response);
}
saveLog(`coder agent INPUT:\n${input}`)
saveLog(`coder agent OUTPUT:\n${response}`)
if (parsedResponse.updateDependentFiles) {
await updateDependentFiles(task, diff);
}
return parsedResponse.output;
}
async function updateDependentFiles(task, diff) {
const dependentFiles = await getDependentFiles();
for (const file of dependentFiles) {
await suggestChanges(task, file, diff);
}
}
function formatCode(file) {
// format code for prompt
let code = '';
code += `### ${file.path}`;
code += `\n`;
code += '```';
code += `\n`;
code += `${file.code}`;
code += `\n`;
code += '```';
code += `\n`;
return code
}
module.exports = { suggestChanges }
Now, you can implement the getDependentFiles
function in the modules/db.js
file to get the list of dependent files from the database.
Background story explaining the current situation: Due to token limits, we can't contain all the project context at once. That's why a code gets to see one or a few files at a time. After updating code in one file it is likely that other files counting on it would need to be updated.
Desired new situation: After a code is done, pull the list of files that have 'dependenciesList' in the DB including this file. For each of these files call a new coding agent with the task, diff produced so far and the new file context and ask it to update accordingly. A test case we want to see passing is a testing file updated after a code file update, for example asking the name of autopilot dir updated in
autopilotConfig.js
would update it's test fileautopilotConfig.test.js
to passImplementation details: Make up a new coder agent or adjust the current one to accept the possible diff input as well. Pull the dependent files after a file update. Call the agent with the details mentioned so far above.
re: https://github.com/fjrdomingues/autopilot/pull/158/files https://github.com/fjrdomingues/autopilot/pull/157