Skip to content

Instantly share code, notes, and snippets.

@mikegwhit
Created September 11, 2025 22:28
Show Gist options
  • Select an option

  • Save mikegwhit/c88437782e82c2fd3cb196da37d65ce9 to your computer and use it in GitHub Desktop.

Select an option

Save mikegwhit/c88437782e82c2fd3cb196da37d65ce9 to your computer and use it in GitHub Desktop.
const { GoogleGenerativeAI } = require('@google/generative-ai');
const dotenv = require('dotenv');
const { execSync } = require('child_process');
const fs = require('fs');
dotenv.config();
// Initialize the API with your key
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
// Define the function declarations for the API
const tools = [
{
functionDeclarations: [
{
name: 'run_npm_test',
description: 'Runs the \'npm test\' command and returns the test results, including success or failure status and the console output.',
parameters: {
type: 'object',
properties: {},
},
},
{
name: 'read_file',
description: 'Reads the content of a file.',
parameters: {
type: 'object',
properties: {
filePath: {
type: 'string',
description: 'The path to the file to read.',
},
},
required: ['filePath'],
},
},
{
name: 'apply_fix',
description: 'Applies a fix to a file.',
parameters: {
type: 'object',
properties: {
filePath: {
type: 'string',
description: 'The path to the file to fix.',
},
code: {
type: 'string',
description: 'The new code to write to the file.',
},
},
required: ['filePath', 'code'],
},
}
],
},
];
// The function to run npm test
function runNpmTest() {
try {
console.log('Running npm test...');
const output = execSync('npm test', { encoding: 'utf-8' });
return { status: 'passed', output: output };
} catch (error) {
// Return a detailed error object if tests fail
return { status: 'failed', output: error.stdout, error: error.stderr };
}
}
function readFile({ filePath }) {
console.log(`Reading file ${filePath}...`);
try {
const content = fs.readFileSync(filePath, 'utf-8');
return { status: 'success', content: content };
} catch (error) {
return { status: 'failed', error: error.message };
}
}
function applyFix({ filePath, code }) {
console.log(`Applying fix to ${filePath}...`);
try {
fs.writeFileSync(filePath, code);
return { status: 'success' };
} catch (error) {
return { status: 'failed', error: error.message };
}
}
async function orchestrateDebugging() {
const model = genAI.getGenerativeModel({ model: 'gemini-1.5-flash', tools });
const chat = model.startChat({
history: [
{
role: "user",
parts: [{ text: "You are an expert at debugging node.js applications." }],
},
{
role: "model",
parts: [{ text: "I am an expert at debugging node.js applications. I will help you fix the errors in your code." }],
}
]
});
let userPrompt = 'Please run `npm test`. If it fails, read the test.js file, suggest a fix, and apply it. Repeat the process until the test passes.';
let iteration = 0;
let hasReachedGoal = false;
while (!hasReachedGoal && iteration < 5) { // Add an iteration limit to prevent infinite loops
console.log(`--- Iteration ${iteration + 1} ---`);
const result = await chat.sendMessage(userPrompt);
const response = result.response;
if (response.functionCalls && response.functionCalls.length > 0) {
const functionCalls = response.functionCalls;
const functionResponses = [];
for (const call of functionCalls) {
console.log(`Model requested a function call: ${call.name}`);
let functionOutput;
// Handle the function call
if (call.name === 'run_npm_test') {
const testResults = runNpmTest();
functionOutput = testResults;
} else if (call.name === 'read_file') {
const fileContent = readFile(call.args);
functionOutput = fileContent;
} else if (call.name === 'apply_fix') {
const fixResult = applyFix(call.args);
functionOutput = fixResult;
}
console.log(`Function output:`, functionOutput);
functionResponses.push({
functionResponse: {
name: call.name,
response: functionOutput
}
});
}
const responseWithFunctionResult = await chat.sendMessage(functionResponses);
const nextResponse = responseWithFunctionResult.response;
if (nextResponse) {
const textResponse = nextResponse.text();
if (textResponse) {
console.log(`Model's response: ${textResponse}`);
if (textResponse.includes("Test passed!")) {
hasReachedGoal = true;
}
}
}
userPrompt = "The test failed again, please try again.";
} else if (response.text()) {
// If the model did not request a function call, it's a text response
const textResponse = response.text();
console.log(`Model's response: ${textResponse}`);
if (textResponse.includes("Test passed!")) {
hasReachedGoal = true;
}
} else {
hasReachedGoal = true;
}
iteration++;
}
}
orchestrateDebugging().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment