Skip to content

Commit

Permalink
Modularized code further - working on implementing different options
Browse files Browse the repository at this point in the history
  • Loading branch information
peterdanwan committed Sep 10, 2024
1 parent cb42b27 commit 4ea9d20
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 63 deletions.
80 changes: 18 additions & 62 deletions src/_gr.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,10 @@

// src/_gr.js

import fs from 'fs';
import path from 'path';
import dotenv from 'dotenv';

// Reference: https://ai.google.dev/gemini-api/docs/text-generation?lang=node
import { GoogleGenerativeAI } from '@google/generative-ai';

// Reference: https://www.npmjs.com/package/ora
// import ora from 'ora';

import program from './commanderProgram.js';
import getFileContent from './getFileContent.js';
import promptAI from './ai.js';

// Make values from .env available
dotenv.config();

// Initialize Google Generative AI client
const genAI = new GoogleGenerativeAI(process.env.GEMINI_KEY);
const model = genAI.getGenerativeModel({ model: 'gemini-1.5-flash' });

// Initialize a different AI client

// Main function
async function main() {
const args = process.argv;

Expand All @@ -42,59 +24,33 @@ async function main() {
let prompt =
'Take the following code and produce a README.md style response based on each file sent that explains the code (please have code snippets with comments):\n\n';

console.log(files);
for (let file of files) {
const modelFlag = options.model || null;
const outputFlag = options.output || null;

for (const file of files) {
console.log('Sending file: ');
console.log(file);
console.log('\n');

const content = getFileContent(file);
const content = getFileContent(file, modelFlag, outputFlag);

if (content) {
prompt += content + '\n\n';
}

// perhaps should throw an error if they can't read a file.
// if the error is thrown, then don't bother prompting AI at all and advise that a file could not be found.
}

await promptAI(prompt);
try {
await promptAI(prompt);

} catch (err) {

Check failure on line 48 in src/_gr.js

View workflow job for this annotation

GitHub Actions / ESLint

'err' is defined but never used
console.error("Throw");
}
}

process.exit(1);
}

// Run the main function
main();

function getFileContent(filePath) {
// Gets the absolute path of the file (this isn't sent to OpenAI)
const resolvedPath = path.resolve(filePath);

// Check if the file exists
if (!fs.existsSync(resolvedPath)) {
console.error(`Error: The file "${resolvedPath}" does not exist.`);
return null;
}

// Read file content
try {
let fileContent = resolvedPath + '\n';

fileContent += fs.readFileSync(resolvedPath, 'utf-8');

console.log(`Resolved path is: ${resolvedPath}`);
console.log(fileContent);
console.log('\n');

return fileContent;
} catch (error) {
console.error(`Error reading file "${resolvedPath}": ${error.message}`);
return null;
}
}

async function promptAI(prompt) {
try {
// Generate content using the AI model
const result = await model.generateContent(prompt);
console.log(result.response.text());
} catch (error) {
console.error('Error generating content:', error);
}
}
64 changes: 64 additions & 0 deletions src/ai.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// src/ai.js

import dotenv from 'dotenv';

/**************************** API imports ***********************************/
// Reference: https://ai.google.dev/gemini-api/docs/text-generation?lang=node
import { GoogleGenerativeAI } from '@google/generative-ai';

// Make values from .env available
dotenv.config();

// Initialize Google Generative AI client
const genAI = new GoogleGenerativeAI(process.env.GEMINI_KEY);
const model = genAI.getGenerativeModel({ model: 'gemini-1.5-flash' }); // can provide system instruction

// Publicly available function
export default async function promptAI(prompt, modelFlag = 'gemini', outputFlag = 'cmd') {
// Depending on which model is specified in modelFlag, call the right API's logic

switch (modelFlag) {
case 'gemini':
await promptGemini(prompt, outputFlag);
break;
case 'openai':
await promptOpenAi(prompt, outputFlag);
break;
case 'claude':
default:
break;
}
}

// Helpers
async function promptGemini(prompt, outputFlag) {

Check failure on line 34 in src/ai.js

View workflow job for this annotation

GitHub Actions / ESLint

'outputFlag' is defined but never used
// Depending on the outputFlag, output to stdout or paste the content into a file.

try {
// Generate content using the AI model
const result = await model.generateContent(prompt);
const responseText = result.response.text();

Check failure on line 40 in src/ai.js

View workflow job for this annotation

GitHub Actions / ESLint

'responseText' is assigned a value but never used


console.log(result.response.text());
} catch (error) {
// Error will propagate to _gr.js
throw Error(`Error prompting Gemini ${error}`);
}
}

async function promptOpenAi(prompt, outputFlag) {

Check failure on line 50 in src/ai.js

View workflow job for this annotation

GitHub Actions / ESLint

'prompt' is defined but never used

Check failure on line 50 in src/ai.js

View workflow job for this annotation

GitHub Actions / ESLint

'outputFlag' is defined but never used
try {

Check failure on line 51 in src/ai.js

View workflow job for this annotation

GitHub Actions / ESLint

Empty block statement

} catch (error) {

Check failure on line 53 in src/ai.js

View workflow job for this annotation

GitHub Actions / ESLint

'error' is defined but never used

Check failure on line 53 in src/ai.js

View workflow job for this annotation

GitHub Actions / ESLint

Empty block statement

}
}

// handleOutput
function handleOutput(outputFlag) {

Check failure on line 59 in src/ai.js

View workflow job for this annotation

GitHub Actions / ESLint

'handleOutput' is defined but never used
if (outputFlag == 'cmd') {

Check failure on line 60 in src/ai.js

View workflow job for this annotation

GitHub Actions / ESLint

Empty block statement
} else {
// output content into a README.md file
}
}
6 changes: 5 additions & 1 deletion src/commanderProgram.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ program.version(version, '-v, --version', 'output the current version');

// Options
program.option('-f, --file [files...]', 'specify files');
program.option('-o, --output <string>', 'output to file (fo) or command-line (c) ');
program.option('-o, --output <string>', 'output to file (f) or command-line (c) ');
program.option(
'-m, --model <string>',
"specify which free-tier model you'd want to use (e.g., gemini, openai, grok)"
);
program.option('-p, --prompt <string>', 'specify a custom prompt');

// Exports the configured program
Expand Down
31 changes: 31 additions & 0 deletions src/getFileContent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// src/getFileContent.js

import fs from 'fs';
import path from 'path';

export default function getFileContent(filePath) {
// Gets the absolute path of the file (this isn't sent to OpenAI)
const resolvedPath = path.resolve(filePath);

// Check if the file exists
if (!fs.existsSync(resolvedPath)) {
console.error(`Error: The file "${resolvedPath}" does not exist.`);
return null;
}

// Read file content
try {
let fileContent = resolvedPath + '\n';

fileContent += fs.readFileSync(resolvedPath, 'utf-8');

console.log(`Resolved path is: ${resolvedPath}`);
console.log(fileContent);
console.log('\n');

return fileContent;
} catch (error) {
console.error(`Error reading file "${resolvedPath}": ${error.message}`);
return null;
}
}

0 comments on commit 4ea9d20

Please sign in to comment.