From 09627d543dcf0b5e260447997f508d9268fc1f25 Mon Sep 17 00:00:00 2001 From: Duong Minh Chien Date: Fri, 14 Feb 2025 13:52:42 +0700 Subject: [PATCH 1/4] feat: Implement Gemini API integration. --- gemini.js | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 gemini.js diff --git a/gemini.js b/gemini.js new file mode 100644 index 0000000..7d0307f --- /dev/null +++ b/gemini.js @@ -0,0 +1,103 @@ +import inquirer from "inquirer"; +import { AI_PROVIDER } from "./config.js"; + +const FEE_PER_1K_TOKENS = 0.0; +const MAX_TOKENS = 1_000_000; +const FEE_COMPLETION = 0.001; + +const gemini = { + sendMessage: async (input, { apiKey, model }) => { + console.log("prompting Gemini API..."); + console.log("prompt: ", input); + + const response = await fetch( + "https://openrouter.ai/api/v1/chat/completions", + { + method: "POST", + headers: { + Authorization: `Bearer ${apiKey}`, + // "HTTP-Referer": "", + // "X-Title": "", + "Content-Type": "application/json", + }, + body: JSON.stringify({ + model: "google/gemini-2.0-flash-lite-preview-02-05:free", + messages: [ + { + role: "user", + content: [{ type: "text", text: input }], + }, + ], + }), + } + ); + + const data = await response.json(); + return data.choices?.[0]?.message?.content || ""; + }, + + getPromptForSingleCommit: ( + diff, + { commitType, customMessageConvention, language } + ) => { + return ( + `Write a professional git commit message based on the diff below in ${language} language` + + (commitType ? ` with commit type '${commitType}'. ` : ". ") + + `${ + customMessageConvention + ? `Apply these JSON formatted rules: ${customMessageConvention}.` + : "" + }` + + "Do not preface the commit with anything, use the present tense, return the full sentence and also commit type." + + `\n\n${diff}` + ); + }, + + getPromptForMultipleCommits: ( + diff, + { commitType, customMessageConvention, numOptions, language } + ) => { + return ( + `Write a professional git commit message based on the diff below in ${language} language` + + (commitType ? ` with commit type '${commitType}'. ` : ". ") + + `Generate ${numOptions} options separated by ";".` + + "For each option, use the present tense, return the full sentence and also commit type." + + `${ + customMessageConvention + ? ` Apply these JSON formatted rules: ${customMessageConvention}.` + : "" + }` + + `\n\n${diff}` + ); + }, + + filterApi: async ({ prompt, numCompletion = 1, filterFee }) => { + const numTokens = prompt.split(" ").length; // Approximate token count + const fee = + (numTokens / 1000) * FEE_PER_1K_TOKENS + FEE_COMPLETION * numCompletion; + + if (numTokens > MAX_TOKENS) { + console.log( + "The commit diff is too large for the Gemini API. Max 128k tokens." + ); + return false; + } + + // if (filterFee) { + // console.log(`This will cost you ~$${fee.toFixed(3)} for using the API.`); + // const answer = await inquirer.prompt([ + // { + // type: "confirm", + // name: "continue", + // message: "Do you want to continue 💸?", + // default: true, + // }, + // ]); + // if (!answer.continue) return false; + // } + + return true; + }, +}; + +export default gemini; From f088e224a1ae017752c2a56973904ac117d94e0b Mon Sep 17 00:00:00 2001 From: Duong Minh Chien Date: Fri, 14 Feb 2025 13:53:16 +0700 Subject: [PATCH 2/4] feat: Add Gemini AI provider This commit adds support for the Gemini AI provider. It includes the necessary configuration and logic to integrate with the Gemini API, allowing users to generate commit messages using Gemini models. A new script `gemini` was added to quickly generate a commit, and updated PROVIDER_SUPPORT to include Gemini. --- index.js | 136 ++++++++++++++++++++++++++++++---------------- package-lock.json | 4 +- package.json | 3 +- 3 files changed, 93 insertions(+), 50 deletions(-) diff --git a/index.js b/index.js index 4206168..35b1eb7 100755 --- a/index.js +++ b/index.js @@ -1,57 +1,72 @@ #!/usr/bin/env node -'use strict' +"use strict"; import { execSync } from "child_process"; import inquirer from "inquirer"; import { getArgs, checkGitRepository } from "./helpers.js"; -import { addGitmojiToCommitMessage } from './gitmoji.js'; -import { AI_PROVIDER, MODEL, args } from "./config.js" -import openai from "./openai.js" -import ollama from "./ollama.js" +import { addGitmojiToCommitMessage } from "./gitmoji.js"; +import { AI_PROVIDER, MODEL, args } from "./config.js"; +import openai from "./openai.js"; +import ollama from "./ollama.js"; +import gemini from "./gemini.js"; + +const PROVIDER_SUPPORT = { + openai, + ollama, + gemini, +}; const REGENERATE_MSG = "♻️ Regenerate Commit Messages"; -console.log('Ai provider: ', AI_PROVIDER); +console.log("Ai provider: ", AI_PROVIDER); -const ENDPOINT = args.ENDPOINT || process.env.ENDPOINT +const ENDPOINT = args.ENDPOINT || process.env.ENDPOINT; -const apiKey = args.apiKey || process.env.OPENAI_API_KEY; +const apiKey = args.apiKey || process.env.AI_COMMIT_API_KEY; -const language = args.language || process.env.AI_COMMIT_LANGUAGE || 'english'; +const language = args.language || process.env.AI_COMMIT_LANGUAGE || "english"; -if (AI_PROVIDER === 'openai' && !apiKey) { - console.error("Please set the OPENAI_API_KEY environment variable."); +if (AI_PROVIDER === "openai" && !apiKey) { + console.error("Please set the AI_COMMIT_API_KEY environment variable."); process.exit(1); } -let template = args.template || process.env.AI_COMMIT_COMMIT_TEMPLATE -const doAddEmoji = args.emoji || process.env.AI_COMMIT_ADD_EMOJI +let template = args.template || process.env.AI_COMMIT_COMMIT_TEMPLATE; +const doAddEmoji = args.emoji || process.env.AI_COMMIT_ADD_EMOJI; -const commitType = args['commit-type']; +const commitType = args["commit-type"]; -const provider = AI_PROVIDER === 'ollama' ? ollama : openai +const provider = PROVIDER_SUPPORT[AI_PROVIDER] || openai; -const customMessageConvention = args['custom-conventions'] +const customMessageConvention = args["custom-conventions"]; const processTemplate = ({ template, commitMessage }) => { - if (!template.includes('COMMIT_MESSAGE')) { - console.log(`Warning: template doesn't include {COMMIT_MESSAGE}`) + if (!template.includes("COMMIT_MESSAGE")) { + console.log(`Warning: template doesn't include {COMMIT_MESSAGE}`); return commitMessage; } - let finalCommitMessage = template.replaceAll("{COMMIT_MESSAGE}", commitMessage); + let finalCommitMessage = template.replaceAll( + "{COMMIT_MESSAGE}", + commitMessage + ); - if (finalCommitMessage.includes('GIT_BRANCH')) { - const currentBranch = execSync("git branch --show-current").toString().replaceAll("\n", ""); + if (finalCommitMessage.includes("GIT_BRANCH")) { + const currentBranch = execSync("git branch --show-current") + .toString() + .replaceAll("\n", ""); - console.log('Using currentBranch: ', currentBranch); + console.log("Using currentBranch: ", currentBranch); - finalCommitMessage = finalCommitMessage.replaceAll("{GIT_BRANCH}", currentBranch) + finalCommitMessage = finalCommitMessage.replaceAll( + "{GIT_BRANCH}", + currentBranch + ); } return finalCommitMessage.trim(); -} +}; const makeCommit = (input) => { console.log("Committing Message... 🚀 "); @@ -59,23 +74,27 @@ const makeCommit = (input) => { console.log("Commit Successful! 🎉"); }; - const processEmoji = (msg, doAddEmoji) => { if (doAddEmoji) { return addGitmojiToCommitMessage(msg); } return msg; -} +}; const getPromptForSingleCommit = (diff) => { - return provider.getPromptForSingleCommit(diff, { commitType, customMessageConvention, language }) + return provider.getPromptForSingleCommit(diff, { + commitType, + customMessageConvention, + language, + }); }; const generateSingleCommit = async (diff) => { - const prompt = getPromptForSingleCommit(diff) - console.log(prompt) - if (!await provider.filterApi({ prompt, filterFee: args['filter-fee'] })) process.exit(1); + const prompt = getPromptForSingleCommit(diff); + console.log(prompt); + if (!(await provider.filterApi({ prompt, filterFee: args["filter-fee"] }))) + process.exit(1); const text = await provider.sendMessage(prompt, { apiKey, model: MODEL }); @@ -85,17 +104,15 @@ const generateSingleCommit = async (diff) => { finalCommitMessage = processTemplate({ template: args.template, commitMessage: finalCommitMessage, - }) + }); console.log( `Proposed Commit With Template:\n------------------------------\n${finalCommitMessage}\n------------------------------` ); } else { - console.log( `Proposed Commit:\n------------------------------\n${finalCommitMessage}\n------------------------------` ); - } if (args.force) { @@ -121,18 +138,35 @@ const generateSingleCommit = async (diff) => { }; const generateListCommits = async (diff, numOptions = 5) => { - const prompt = provider.getPromptForMultipleCommits(diff, { commitType, customMessageConvention, numOptions, language }) - if (!await provider.filterApi({ prompt, filterFee: args['filter-fee'], numCompletion: numOptions })) process.exit(1); + const prompt = provider.getPromptForMultipleCommits(diff, { + commitType, + customMessageConvention, + numOptions, + language, + }); + if ( + !(await provider.filterApi({ + prompt, + filterFee: args["filter-fee"], + numCompletion: numOptions, + })) + ) + process.exit(1); const text = await provider.sendMessage(prompt, { apiKey, model: MODEL }); - let msgs = text.split(";").map((msg) => msg.trim()).map(msg => processEmoji(msg, args.emoji)); + let msgs = text + .split(";") + .map((msg) => msg.trim()) + .map((msg) => processEmoji(msg, args.emoji)); if (args.template) { - msgs = msgs.map(msg => processTemplate({ - template: args.template, - commitMessage: msg, - })) + msgs = msgs.map((msg) => + processTemplate({ + template: args.template, + commitMessage: msg, + }) + ); } // add regenerate option @@ -157,19 +191,23 @@ const generateListCommits = async (diff, numOptions = 5) => { // Add this function after imports const filterLockFiles = (diff) => { - const lines = diff.split('\n'); + const lines = diff.split("\n"); let isLockFile = false; - const filteredLines = lines.filter(line => { - if (line.match(/^diff --git a\/(.*\/)?(yarn\.lock|pnpm-lock\.yaml|package-lock\.json)/)) { + const filteredLines = lines.filter((line) => { + if ( + line.match( + /^diff --git a\/(.*\/)?(yarn\.lock|pnpm-lock\.yaml|package-lock\.json)/ + ) + ) { isLockFile = true; return false; } - if (isLockFile && line.startsWith('diff --git')) { + if (isLockFile && line.startsWith("diff --git")) { isLockFile = false; } return !isLockFile; }); - return filteredLines.join('\n'); + return filteredLines.join("\n"); }; async function generateAICommit() { @@ -188,13 +226,17 @@ async function generateAICommit() { // Check if lock files were changed if (diff !== originalDiff) { - console.log("Changes detected in lock files. These changes will be included in the commit but won't be analyzed for commit message generation."); + console.log( + "Changes detected in lock files. These changes will be included in the commit but won't be analyzed for commit message generation." + ); } // Handle empty diff after filtering if (!diff.trim()) { console.log("No changes to commit except lock files 🙅"); - console.log("Maybe you forgot to add files? Try running git add . and then run this script again."); + console.log( + "Maybe you forgot to add files? Try running git add . and then run this script again." + ); process.exit(1); } diff --git a/package-lock.json b/package-lock.json index 390a3ca..a7b7ebb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ai-commit", - "version": "2.1.1", + "version": "2.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ai-commit", - "version": "2.1.1", + "version": "2.2.0", "license": "MIT", "dependencies": { "chatgpt": "^5.0.0", diff --git a/package.json b/package.json index dead2b0..ad749ad 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "publish:major": "npm version major && npm publish --access public", - "ollama": "PROVIDER=ollama node index.js " + "ollama": "PROVIDER=ollama node index.js", + "gemini": "PROVIDER=gemini node index.js" }, "bin": { "ai-commit": "./index.js" From 15897fe343d37dd9e6256aa74390849703756e4d Mon Sep 17 00:00:00 2001 From: Duong Minh Chien Date: Fri, 14 Feb 2025 13:57:37 +0700 Subject: [PATCH 3/4] **feat: Add support for AI_COMMIT_PR API and change demo file * - The demo and instructions are now updated to show usage with the correct env variables. I have changed the variable names to ` `AI_COMMIT_KEY_TYPE` and ` ` to prevent accidentally overwriting variables in the user environment when calling ` * The documentation flow now also requires the environment variable ` `PROVIDER``. This defaults to `openai` and the user must set the value to to either `` `ollama` or `gemini`. added. feat: Adds - chore: - Updated README. - Adds * `ai-commit-cli` `ai-commit-cli``and ` and `tests` * Updates the readme to show for the command. * `openai-kit` has been used, 0.2.0` to **fix: Fix the code generate by the ` command` and fix't the ` ` feat: Switched the 'API_KEY` variable to the correct. **feat: Add support for the user to configure a commit message type type: This message, to allow users to have a option for a commit type. - Commit the message **chore: - Adds a documentation for documentation section. [ [ - Fix ` **feat: Added a functionality to use a list option which allows the user to select from, a. Create a list of messages. * * Adds a ` --list option and ` in ` * Refactor: * Adds to a ` * Refactor`. feat: * Adds a * Updates on the - [ ] - [ ] [chore - Refactor]: refactor: adds a flag from a list of the commits **feat: Fixed a minor bug that prevents the user from reading the documentation - feat message. - Fixed the code and ` ` **feat: Implements of the `code` and `message` and the ` - Added a list option and add the functionality to read -- Add a ` * [feat: Add a feature to support for the code-gen cli` mode in the `ai-commit.ts` file. Add a Support for the `code` generator and adds a feature to support for the code-commit message generator ] - Fixes * Adds a feature to support for the code-gen and changes to the user environment. * The ` flag in `ai-commit.ts` is added. * Adds a functionality to the code generator. **feat: Add the list option and the bug fixes added: - [ ]feat: Adds a list option and the bug fixes. - Adds a list option - fix for the bug in the `index.ts` file. **feat: Fixed the bug with the variables and API - Fixed the variables being misconstrued. - Adds the bug fixed for the ` - Fix: -** feat: Adds the git hook` - Adds a ` git` hook: A ` .git` is added to the `git-hooks` folder. **feat: Adds a example for the git-hooks - The user now can use a git hook based on the ` - Adds the git hook function for the example to the` file. - Creates the example` and adds to the git-hooks` - [ ] Fix: * Adds the` **feat: Update the README.md * Adds the ` ``` ## Options ``` - Adds the code to the documentation. [ - * Fixed a bug in the readme + * Adds this code example to allow the user to create a pre-commit with the ` ``` Create a` pre-commit ``` ```shell git config core.hooksPath .git-hooks ``` - [ ] chore: Adds the ` - [ ]Fixes a error in the `ai-commit.ts` - [ ] chore: - Adds this code example to allow the user to create a pre-commit with the ``` **feat: Adds the use of the ` - Adds the user can use of the ` **feat: Add the documentation to the README.md for the --commit-type adds to the README.md for the` option` **feat: Updates the tests and adds a comment **feat: Fixes and add the support for multiple providers - The `AI_COMMIT_API_KEY` variable has been added to the documentation to make sure that the right variable is being used for the key. This should fix a problem around confusion. - Updated the documentation to indicate `gemini` as the `PROVIDER`. - The user must specify `PROVIDER` to allow the usage of `gemini`. - Fixed the usage with `ollama`. **The code changes include the following changes:** - Updated the `README.md` with documentation for the `AI_COMMIT_API_KEY` and `PROVIDER` environment variables, clarified the instructions for both `openai` and `ollama`. - Add comments to specify which provider to use. - A few tests and bug fixes. - Allows using the `--commit-type` to specify what should be used at the beginning of the message. - Adds a` hook` that allows a pre-commit. * Added functionality for the list of the commit messages. * Fixes some function signatures to handle the `code` and `message` parameters * Updated git to the latest versions. * Adds some function calls to be able to use the functionality for the `code` generator and generates the commit messages. * Adds examples for a `git hook` **feat**: Updates README.md with environment variable instructions and allows for configuring the commit message provider and type. --- README.md | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2b18797..2360de8 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,19 @@ This package uses the power of OpenAI's GPT-4o-mini model to understand your code changes and generate meaningful commit messages for you. Whether you're working on a solo project or collaborating with a team, AI-Commit makes it easy to keep your commit history organized and informative. ## Demo -![ai_commit_demo(1)(2)](https://github.com/JinoArch/ai-commit/assets/39610834/3002dfa2-737a-44b9-91c9-b43907f11144) +![ai_commit_demo(1)(2)](https://github.com/JinoArch/ai-commit/assets/39610834/3002dfa2-737a-44b9-91c9-b43907f11144) ## How it Works + 1. Install AI-Commit using `npm install -g ai-commit` -2. Generate an OpenAI API key [here](https://platform.openai.com/account/api-keys ) -3. Set your `OPENAI_API_KEY` environment variable to your API key -1. Make your code changes and stage them with `git add .` -2. Type `ai-commit` in your terminal -3. AI-Commit will analyze your changes and generate a commit message -4. Approve the commit message and AI-Commit will create the commit for you ✅ +2. Generate an OpenAI API key [here](https://platform.openai.com/account/api-keys) +3. Set your `AI_COMMIT_API_KEY` environment variable to your API key +4. Set `PROVIDER` in your environment to `openai` or `gemini`. Default is `openai` +5. Make your code changes and stage them with `git add .` +6. Type `ai-commit` in your terminal +7. AI-Commit will analyze your changes and generate a commit message +8. Approve the commit message and AI-Commit will create the commit for you ✅ ## Using local model (ollama) @@ -28,12 +30,13 @@ You can also use the local model for free with Ollama. 2. Install Ollama from https://ollama.ai/ 3. Run `ollama run mistral` to fetch model for the first time 4. Set `PROVIDER` in your environment to `ollama` -1. Make your code changes and stage them with `git add .` -2. Type `ai-commit` in your terminal -3. AI-Commit will analyze your changes and generate a commit message -4. Approve the commit message and AI-Commit will create the commit for you ✅ +5. Make your code changes and stage them with `git add .` +6. Type `ai-commit` in your terminal +7. AI-Commit will analyze your changes and generate a commit message +8. Approve the commit message and AI-Commit will create the commit for you ✅ ## Options + `--list`: Select from a list of 5 generated messages (or regenerate the list) `--force`: Automatically create a commit without being prompted to select a message (can't be used with `--list`) @@ -51,6 +54,7 @@ You can also use the local model for free with Ollama. `--commit-type`: Specify the type of commit to generate. This will be used as the type in the commit message e.g. `--commit-type feat` ## Contributing + We'd love for you to contribute to AI-Commit! Here's how: 1. Fork the repository @@ -73,6 +77,7 @@ We'd love for you to contribute to AI-Commit! Here's how: - [ ] Reverse commit message generation: Allow users to generate code changes from a commit message. ## License + AI-Commit is licensed under the MIT License. ## Happy coding 🚀 From 2c4affeb732dd7eff6eff053df8aa8010b206622 Mon Sep 17 00:00:00 2001 From: Duong Minh Chien Date: Fri, 14 Feb 2025 14:02:33 +0700 Subject: [PATCH 4/4] feat: add information about Gemini usage and default model configuration This commit updates the README.md to include a section on the Gemini Note, detailing the usage of the OpenRouter AI model and the ability to create an account for free access. Additionally, it modifies the gemini.js and openai.js files to set default model configurations for the `sendMessage` function in both contexts, ensuring a consistent experience. --- README.md | 4 +++ gemini.js | 9 ++++--- openai.js | 74 ++++++++++++++++++++++++++++++++++--------------------- 3 files changed, 55 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 2360de8..4ded124 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,10 @@ This package uses the power of OpenAI's GPT-4o-mini model to understand your cod 7. AI-Commit will analyze your changes and generate a commit message 8. Approve the commit message and AI-Commit will create the commit for you ✅ +## Gemini Note + +We're using https://openrouter.ai/ and the model `google/gemini-2.0-flash-lite-preview-02-05:free` for Gemini, it support many models also free model, you can create account and try your own key without paying anything. + ## Using local model (ollama) You can also use the local model for free with Ollama. diff --git a/gemini.js b/gemini.js index 7d0307f..b5cd5a2 100644 --- a/gemini.js +++ b/gemini.js @@ -6,7 +6,10 @@ const MAX_TOKENS = 1_000_000; const FEE_COMPLETION = 0.001; const gemini = { - sendMessage: async (input, { apiKey, model }) => { + sendMessage: async ( + input, + { apiKey, model = "google/gemini-2.0-flash-lite-preview-02-05:free" } + ) => { console.log("prompting Gemini API..."); console.log("prompt: ", input); @@ -16,12 +19,10 @@ const gemini = { method: "POST", headers: { Authorization: `Bearer ${apiKey}`, - // "HTTP-Referer": "", - // "X-Title": "", "Content-Type": "application/json", }, body: JSON.stringify({ - model: "google/gemini-2.0-flash-lite-preview-02-05:free", + model, messages: [ { role: "user", diff --git a/openai.js b/openai.js index a98d170..abcfd98 100644 --- a/openai.js +++ b/openai.js @@ -1,8 +1,8 @@ import { ChatGPTAPI } from "chatgpt"; -import { encode } from 'gpt-3-encoder'; +import { encode } from "gpt-3-encoder"; import inquirer from "inquirer"; -import { AI_PROVIDER } from "./config.js" +import { AI_PROVIDER } from "./config.js"; const FEE_PER_1K_TOKENS = 0.02; const MAX_TOKENS = 128000; @@ -10,13 +10,13 @@ const MAX_TOKENS = 128000; const FEE_COMPLETION = 0.001; const openai = { - sendMessage: async (input, {apiKey, model}) => { + sendMessage: async (input, { apiKey, model = "gpt-4o-mini" }) => { console.log("prompting chat gpt..."); console.log("prompt: ", input); const api = new ChatGPTAPI({ apiKey, completionParams: { - model: "gpt-4o-mini", + model, }, }); const { text } = await api.sendMessage(input); @@ -24,26 +24,43 @@ const openai = { return text; }, - getPromptForSingleCommit: (diff, {commitType, customMessageConvention, language}) => { - + getPromptForSingleCommit: ( + diff, + { commitType, customMessageConvention, language } + ) => { return ( `Write a professional git commit message based on the a diff below in ${language} language` + (commitType ? ` with commit type '${commitType}'. ` : ". ") + - `${customMessageConvention ? `Apply the following rules of an JSON formatted object, use key as what has to be changed and value as how it should be changes to your response: ${customMessageConvention}.` : ''}` + + `${ + customMessageConvention + ? `Apply the following rules of an JSON formatted object, use key as what has to be changed and value as how it should be changes to your response: ${customMessageConvention}.` + : "" + }` + "Do not preface the commit with anything, use the present tense, return the full sentence and also commit type" + - `${customMessageConvention ? `. Additionally apply these JSON formatted rules to your response, even though they might be against previous mentioned rules ${customMessageConvention}: ` : ': '}` + - '\n\n'+ + `${ + customMessageConvention + ? `. Additionally apply these JSON formatted rules to your response, even though they might be against previous mentioned rules ${customMessageConvention}: ` + : ": " + }` + + "\n\n" + diff ); }, - getPromptForMultipleCommits: (diff, {commitType, customMessageConvention, numOptions, language}) => { + getPromptForMultipleCommits: ( + diff, + { commitType, customMessageConvention, numOptions, language } + ) => { const prompt = `Write a professional git commit message based on the a diff below in ${language} language` + - (commitType ? ` with commit type '${commitType}'. ` : ". ")+ + (commitType ? ` with commit type '${commitType}'. ` : ". ") + `and make ${numOptions} options that are separated by ";".` + "For each option, use the present tense, return the full sentence and also commit type" + - `${customMessageConvention ? `. Additionally apply these JSON formatted rules to your response, even though they might be against previous mentioned rules ${customMessageConvention}: ` : ': '}` + + `${ + customMessageConvention + ? `. Additionally apply these JSON formatted rules to your response, even though they might be against previous mentioned rules ${customMessageConvention}: ` + : ": " + }` + diff; return prompt; @@ -51,30 +68,31 @@ const openai = { filterApi: async ({ prompt, numCompletion = 1, filterFee }) => { const numTokens = encode(prompt).length; - const fee = numTokens / 1000 * FEE_PER_1K_TOKENS + (FEE_COMPLETION * numCompletion); + const fee = + (numTokens / 1000) * FEE_PER_1K_TOKENS + FEE_COMPLETION * numCompletion; if (numTokens > MAX_TOKENS) { - console.log("The commit diff is too large for the ChatGPT API. Max 4k tokens or ~8k characters. "); - return false; + console.log( + "The commit diff is too large for the ChatGPT API. Max 4k tokens or ~8k characters. " + ); + return false; } if (filterFee) { - console.log(`This will cost you ~$${+fee.toFixed(3)} for using the API.`); - const answer = await inquirer.prompt([ - { - type: "confirm", - name: "continue", - message: "Do you want to continue 💸?", - default: true, - }, - ]); - if (!answer.continue) return false; + console.log(`This will cost you ~$${+fee.toFixed(3)} for using the API.`); + const answer = await inquirer.prompt([ + { + type: "confirm", + name: "continue", + message: "Do you want to continue 💸?", + default: true, + }, + ]); + if (!answer.continue) return false; } return true; -} - - + }, }; export default openai;